1 /*
2 * Copyright (c) 2012-2021 The Linux Foundation. All rights reserved.
3 * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
4 *
5 * Permission to use, copy, modify, and/or distribute this software for
6 * any purpose with or without fee is hereby granted, provided that the
7 * above copyright notice and this permission notice appear in all
8 * copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
11 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
12 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
13 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
16 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17 * PERFORMANCE OF THIS SOFTWARE.
18 */
19
20 /**=========================================================================
21
22 \brief implementation for PE 11r VoWiFi FT Protocol
23
24 ========================================================================*/
25
26 /* $Header$ */
27
28 /*--------------------------------------------------------------------------
29 Include Files
30 ------------------------------------------------------------------------*/
31 #include <lim_send_messages.h>
32 #include <lim_types.h>
33 #include <lim_ft.h>
34 #include <lim_ft_defs.h>
35 #include <lim_utils.h>
36 #include <lim_prop_exts_utils.h>
37 #include <lim_assoc_utils.h>
38 #include <lim_session.h>
39 #include <lim_admit_control.h>
40 #include <lim_security_utils.h>
41 #include "wmm_apsd.h"
42 #include "wma.h"
43 #include "wlan_cmn.h"
44
45 /*--------------------------------------------------------------------------
46 Initialize the FT variables.
47 ------------------------------------------------------------------------*/
lim_ft_open(struct mac_context * mac,struct pe_session * pe_session)48 void lim_ft_open(struct mac_context *mac, struct pe_session *pe_session)
49 {
50 if (pe_session)
51 qdf_mem_zero(&pe_session->ftPEContext, sizeof(tftPEContext));
52 }
53
lim_ft_cleanup_all_ft_sessions(struct mac_context * mac)54 void lim_ft_cleanup_all_ft_sessions(struct mac_context *mac)
55 {
56 /* Wrapper function to cleanup all FT sessions */
57 int i;
58
59 for (i = 0; i < mac->lim.maxBssId; i++) {
60 if (true == mac->lim.gpSession[i].valid) {
61 /* The session is valid, may have FT data */
62 lim_ft_cleanup(mac, &mac->lim.gpSession[i]);
63 }
64 }
65 }
66
lim_ft_cleanup(struct mac_context * mac,struct pe_session * pe_session)67 void lim_ft_cleanup(struct mac_context *mac, struct pe_session *pe_session)
68 {
69 if (!pe_session) {
70 pe_err("pe_session is NULL");
71 return;
72 }
73
74 /* Nothing to be done if the session is not in STA mode */
75 if (!LIM_IS_STA_ROLE(pe_session)) {
76 pe_debug("pe_session is not in STA mode");
77 return;
78 }
79
80 if (pe_session->ftPEContext.pFTPreAuthReq) {
81 pe_debug("Freeing pFTPreAuthReq: %pK",
82 pe_session->ftPEContext.pFTPreAuthReq);
83 if (NULL !=
84 pe_session->ftPEContext.pFTPreAuthReq->
85 pbssDescription) {
86 qdf_mem_free(pe_session->ftPEContext.pFTPreAuthReq->
87 pbssDescription);
88 pe_session->ftPEContext.pFTPreAuthReq->
89 pbssDescription = NULL;
90 }
91 qdf_mem_free(pe_session->ftPEContext.pFTPreAuthReq);
92 pe_session->ftPEContext.pFTPreAuthReq = NULL;
93 }
94
95 if (pe_session->ftPEContext.pAddBssReq) {
96 qdf_mem_free(pe_session->ftPEContext.pAddBssReq);
97 pe_session->ftPEContext.pAddBssReq = NULL;
98 }
99
100 if (pe_session->ftPEContext.pAddStaReq) {
101 qdf_mem_free(pe_session->ftPEContext.pAddStaReq);
102 pe_session->ftPEContext.pAddStaReq = NULL;
103 }
104
105 /* The session is being deleted, cleanup the contents */
106 qdf_mem_zero(&pe_session->ftPEContext, sizeof(tftPEContext));
107 }
108
109 #if defined(WLAN_FEATURE_HOST_ROAM) || defined(WLAN_FEATURE_ROAM_OFFLOAD)
110 /*------------------------------------------------------------------
111 *
112 * Create the new Add Bss Req to the new AP.
113 * This will be used when we are ready to FT to the new AP.
114 * The newly created ft Session entry is passed to this function
115 *
116 *------------------------------------------------------------------*/
lim_ft_prepare_add_bss_req(struct mac_context * mac,struct pe_session * ft_session,struct bss_description * bssDescription)117 void lim_ft_prepare_add_bss_req(struct mac_context *mac,
118 struct pe_session *ft_session,
119 struct bss_description *bssDescription)
120 {
121 struct bss_params *pAddBssParams = NULL;
122 tAddStaParams *sta_ctx;
123 bool chan_width_support = false;
124 tSchBeaconStruct *pBeaconStruct;
125 tDot11fIEVHTCaps *vht_caps = NULL;
126
127 /* Nothing to be done if the session is not in STA mode */
128 if (!LIM_IS_STA_ROLE(ft_session)) {
129 pe_err("pe_session is not in STA mode");
130 return;
131 }
132
133 pBeaconStruct = qdf_mem_malloc(sizeof(tSchBeaconStruct));
134 if (!pBeaconStruct)
135 return;
136
137 /* Package SIR_HAL_ADD_BSS_REQ message parameters */
138 pAddBssParams = qdf_mem_malloc(sizeof(struct bss_params));
139 if (!pAddBssParams) {
140 qdf_mem_free(pBeaconStruct);
141 return;
142 }
143
144 lim_extract_ap_capabilities(mac, (uint8_t *) bssDescription->ieFields,
145 lim_get_ielen_from_bss_description(bssDescription),
146 pBeaconStruct);
147
148 if (mac->lim.gLimProtectionControl !=
149 MLME_FORCE_POLICY_PROTECTION_DISABLE)
150 lim_decide_sta_protection_on_assoc(mac, pBeaconStruct,
151 ft_session);
152
153 qdf_mem_copy(pAddBssParams->bssId, bssDescription->bssId,
154 sizeof(tSirMacAddr));
155 pAddBssParams->beaconInterval = bssDescription->beaconInterval;
156
157 pAddBssParams->dtimPeriod = pBeaconStruct->tim.dtimPeriod;
158 pAddBssParams->updateBss = false;
159
160 pAddBssParams->nwType = bssDescription->nwType;
161
162 pAddBssParams->shortSlotTimeSupported =
163 (uint8_t) pBeaconStruct->capabilityInfo.shortSlotTime;
164 pAddBssParams->llbCoexist =
165 (uint8_t) ft_session->beaconParams.llbCoexist;
166 pAddBssParams->rmfEnabled = ft_session->limRmfEnabled;
167
168 /* Use the advertised capabilities from the received beacon/PR */
169 if (IS_DOT11_MODE_HT(ft_session->dot11mode) &&
170 (pBeaconStruct->HTCaps.present)) {
171 chan_width_support =
172 lim_get_ht_capability(mac,
173 eHT_SUPPORTED_CHANNEL_WIDTH_SET,
174 ft_session);
175 lim_sta_add_bss_update_ht_parameter(bssDescription->chan_freq,
176 &pBeaconStruct->HTCaps,
177 &pBeaconStruct->HTInfo,
178 chan_width_support,
179 pAddBssParams);
180 qdf_mem_copy(&pAddBssParams->staContext.capab_info,
181 &pBeaconStruct->capabilityInfo,
182 sizeof(pAddBssParams->staContext.capab_info));
183 qdf_mem_copy(&pAddBssParams->staContext.ht_caps,
184 (uint8_t *) &pBeaconStruct->HTCaps +
185 sizeof(uint8_t),
186 sizeof(pAddBssParams->staContext.ht_caps));
187 }
188
189 ft_session->htSecondaryChannelOffset =
190 pBeaconStruct->HTInfo.secondaryChannelOffset;
191 sta_ctx = &pAddBssParams->staContext;
192 /*
193 * in lim_extract_ap_capability function intersection of FW
194 * advertised channel width and AP advertised channel
195 * width has been taken into account for calculating
196 * pe_session->ch_width
197 */
198 pAddBssParams->ch_width = ft_session->ch_width;
199 sta_ctx->ch_width = ft_session->ch_width;
200
201 if (ft_session->vhtCapability &&
202 ft_session->vhtCapabilityPresentInBeacon) {
203 pAddBssParams->vhtCapable = pBeaconStruct->VHTCaps.present;
204 vht_caps = &pBeaconStruct->VHTCaps;
205 lim_update_vhtcaps_assoc_resp(mac, pAddBssParams,
206 vht_caps, ft_session);
207 } else if (ft_session->vhtCapability &&
208 pBeaconStruct->vendor_vht_ie.VHTCaps.present) {
209 pe_debug("VHT caps are present in vendor specific IE");
210 pAddBssParams->vhtCapable =
211 pBeaconStruct->vendor_vht_ie.VHTCaps.present;
212 vht_caps = &pBeaconStruct->vendor_vht_ie.VHTCaps;
213 lim_update_vhtcaps_assoc_resp(mac, pAddBssParams,
214 vht_caps, ft_session);
215 } else {
216 pAddBssParams->vhtCapable = 0;
217 }
218
219 if (lim_is_session_he_capable(ft_session) &&
220 pBeaconStruct->he_cap.present) {
221 lim_update_bss_he_capable(mac, pAddBssParams);
222 lim_add_bss_he_cfg(pAddBssParams, ft_session);
223 }
224
225 if (lim_is_session_eht_capable(ft_session) &&
226 pBeaconStruct->eht_cap.present) {
227 lim_update_bss_eht_capable(mac, pAddBssParams);
228 lim_add_bss_eht_cfg(pAddBssParams, ft_session);
229 }
230
231 pe_debug("SIR_HAL_ADD_BSS_REQ with frequency: %d, width: %d",
232 bssDescription->chan_freq, pAddBssParams->ch_width);
233
234 /* Populate the STA-related parameters here */
235 /* Note that the STA here refers to the AP */
236 {
237 pAddBssParams->staContext.staType = STA_ENTRY_OTHER;
238
239 qdf_mem_copy(pAddBssParams->staContext.bssId,
240 bssDescription->bssId, sizeof(tSirMacAddr));
241 pAddBssParams->staContext.listenInterval =
242 bssDescription->beaconInterval;
243
244 pAddBssParams->staContext.assocId = 0;
245 pAddBssParams->staContext.uAPSD = 0;
246 pAddBssParams->staContext.maxSPLen = 0;
247 pAddBssParams->staContext.updateSta = false;
248 pAddBssParams->staContext.encryptType =
249 ft_session->encryptType;
250 pAddBssParams->staContext.rmfEnabled =
251 ft_session->limRmfEnabled;
252
253 if (IS_DOT11_MODE_HT(ft_session->dot11mode) &&
254 (pBeaconStruct->HTCaps.present)) {
255 pAddBssParams->staContext.htCapable = 1;
256 if (ft_session->vhtCapability &&
257 IS_BSS_VHT_CAPABLE(pBeaconStruct->VHTCaps)) {
258 pAddBssParams->staContext.vhtCapable = 1;
259 if ((pBeaconStruct->VHTCaps.suBeamFormerCap ||
260 pBeaconStruct->VHTCaps.muBeamformerCap) &&
261 ft_session->vht_config.su_beam_formee)
262 sta_ctx->vhtTxBFCapable
263 = 1;
264 if (pBeaconStruct->VHTCaps.suBeamformeeCap &&
265 ft_session->vht_config.su_beam_former)
266 sta_ctx->enable_su_tx_bformer = 1;
267 }
268 if (lim_is_session_he_capable(ft_session) &&
269 pBeaconStruct->he_cap.present)
270 lim_intersect_ap_he_caps(ft_session,
271 pAddBssParams,
272 pBeaconStruct, NULL,
273 bssDescription);
274
275 if (lim_is_session_eht_capable(ft_session) &&
276 pBeaconStruct->eht_cap.present)
277 lim_intersect_ap_eht_caps(ft_session,
278 pAddBssParams,
279 pBeaconStruct, NULL);
280
281 pAddBssParams->staContext.mimoPS =
282 (tSirMacHTMIMOPowerSaveState) pBeaconStruct->HTCaps.
283 mimoPowerSave;
284 pAddBssParams->staContext.maxAmpduDensity =
285 pBeaconStruct->HTCaps.mpduDensity;
286 pAddBssParams->staContext.fShortGI20Mhz =
287 (uint8_t) pBeaconStruct->HTCaps.shortGI20MHz;
288 pAddBssParams->staContext.fShortGI40Mhz =
289 (uint8_t) pBeaconStruct->HTCaps.shortGI40MHz;
290 pAddBssParams->staContext.maxAmpduSize =
291 pBeaconStruct->HTCaps.maxRxAMPDUFactor;
292 }
293
294 if ((ft_session->limWmeEnabled
295 && pBeaconStruct->wmeEdcaPresent)
296 || (ft_session->limQosEnabled
297 && pBeaconStruct->edcaPresent))
298 pAddBssParams->staContext.wmmEnabled = 1;
299 else
300 pAddBssParams->staContext.wmmEnabled = 0;
301
302 pAddBssParams->staContext.wpa_rsn = pBeaconStruct->rsnPresent;
303 /* For OSEN Connection AP does not advertise RSN or WPA IE
304 * so from the IEs we get from supplicant we get this info
305 * so for FW to transmit EAPOL message 4 we shall set
306 * wpa_rsn
307 */
308 pAddBssParams->staContext.wpa_rsn |=
309 (pBeaconStruct->wpaPresent << 1);
310 if ((!pAddBssParams->staContext.wpa_rsn)
311 && (ft_session->isOSENConnection))
312 pAddBssParams->staContext.wpa_rsn = 1;
313 /* Update the rates */
314 lim_populate_peer_rate_set(mac,
315 &pAddBssParams->staContext.
316 supportedRates,
317 pBeaconStruct->HTCaps.supportedMCSSet,
318 false, ft_session,
319 &pBeaconStruct->VHTCaps,
320 &pBeaconStruct->he_cap,
321 &pBeaconStruct->eht_cap, NULL,
322 bssDescription);
323 }
324
325 pAddBssParams->maxTxPower = ft_session->maxTxPower;
326
327 if (ft_session->limRmfEnabled) {
328 pAddBssParams->rmfEnabled = 1;
329 pAddBssParams->staContext.rmfEnabled = 1;
330 }
331 pAddBssParams->staContext.sessionId = ft_session->peSessionId;
332 pAddBssParams->staContext.smesessionId = ft_session->smeSessionId;
333
334 /* Set a new state for MLME */
335 if (!lim_is_roam_synch_in_progress(mac->psoc, ft_session)) {
336 ft_session->limMlmState =
337 eLIM_MLM_WT_ADD_BSS_RSP_FT_REASSOC_STATE;
338 MTRACE(mac_trace
339 (mac, TRACE_CODE_MLM_STATE,
340 ft_session->peSessionId,
341 eLIM_MLM_WT_ADD_BSS_RSP_FT_REASSOC_STATE));
342 }
343 ft_session->ftPEContext.pAddBssReq = pAddBssParams;
344
345 pe_debug("Saving SIR_HAL_ADD_BSS_REQ for pre-auth ap");
346
347 qdf_mem_free(pBeaconStruct);
348 return;
349 }
350 #endif
351
352 #if defined(WLAN_FEATURE_ROAM_OFFLOAD)
353
354 /**
355 * lim_convert_phymode_to_dot11mode() - get dot11 mode from phymode
356 * @phymode: phymode
357 *
358 * The function is to convert the phymode to corresponding dot11 mode
359 *
360 * Return: dot11mode.
361 */
lim_convert_phymode_to_dot11mode(enum wlan_phymode phymode)362 static uint8_t lim_convert_phymode_to_dot11mode(enum wlan_phymode phymode)
363 {
364
365 if (IS_WLAN_PHYMODE_HE(phymode))
366 return MLME_DOT11_MODE_11AX;
367
368 if (IS_WLAN_PHYMODE_VHT(phymode))
369 return MLME_DOT11_MODE_11AC;
370
371 if (IS_WLAN_PHYMODE_HT(phymode))
372 return MLME_DOT11_MODE_11N;
373
374 #ifdef WLAN_FEATURE_11BE
375 if (IS_WLAN_PHYMODE_EHT(phymode))
376 return MLME_DOT11_MODE_11BE;
377 #endif
378
379 if (phymode == WLAN_PHYMODE_11G)
380 return MLME_DOT11_MODE_11G;
381
382 if (phymode == WLAN_PHYMODE_11G_ONLY)
383 return MLME_DOT11_MODE_11G_ONLY;
384
385 if (phymode == WLAN_PHYMODE_11A)
386 return MLME_DOT11_MODE_11A;
387
388 if (phymode == WLAN_PHYMODE_11B)
389 return MLME_DOT11_MODE_11B;
390
391 return MLME_DOT11_MODE_ALL;
392 }
393
394 /**
395 * lim_calculate_dot11_mode() - calculate dot11 mode.
396 * @mac_ctx: mac context
397 * @bcn: beacon structure
398 * @band: reg_wifi_band
399 *
400 * The function is to calculate dot11 mode in case fw doesn't send phy mode.
401 *
402 * Return: dot11mode.
403 */
lim_calculate_dot11_mode(struct mac_context * mac_ctx,tSchBeaconStruct * bcn,enum reg_wifi_band band)404 static uint8_t lim_calculate_dot11_mode(struct mac_context *mac_ctx,
405 tSchBeaconStruct *bcn,
406 enum reg_wifi_band band)
407 {
408 enum mlme_dot11_mode self_dot11_mode;
409 enum mlme_dot11_mode new_dot11_mode;
410
411 self_dot11_mode = mac_ctx->mlme_cfg->dot11_mode.dot11_mode;
412
413 if (band == REG_BAND_2G)
414 new_dot11_mode = MLME_DOT11_MODE_11G;
415 else
416 new_dot11_mode = MLME_DOT11_MODE_11A;
417
418 switch (self_dot11_mode) {
419 case MLME_DOT11_MODE_11AX:
420 case MLME_DOT11_MODE_11AX_ONLY:
421 case MLME_DOT11_MODE_ALL:
422 if (bcn->he_cap.present)
423 return MLME_DOT11_MODE_11AX;
424 else if ((bcn->VHTCaps.present ||
425 bcn->vendor_vht_ie.present) &&
426 (!(band == REG_BAND_2G &&
427 !mac_ctx->mlme_cfg->vht_caps.vht_cap_info.b24ghz_band)
428 ))
429
430 return MLME_DOT11_MODE_11AC;
431 else if (bcn->HTCaps.present)
432 return MLME_DOT11_MODE_11N;
433 fallthrough;
434 case MLME_DOT11_MODE_11AC:
435 case MLME_DOT11_MODE_11AC_ONLY:
436 if ((bcn->VHTCaps.present ||
437 bcn->vendor_vht_ie.present) &&
438 (!(band == REG_BAND_2G &&
439 !mac_ctx->mlme_cfg->vht_caps.vht_cap_info.b24ghz_band)
440 ))
441 return MLME_DOT11_MODE_11AC;
442 else if (bcn->HTCaps.present)
443 return MLME_DOT11_MODE_11N;
444 fallthrough;
445 case MLME_DOT11_MODE_11N:
446 case MLME_DOT11_MODE_11N_ONLY:
447 if (bcn->HTCaps.present)
448 return MLME_DOT11_MODE_11N;
449 fallthrough;
450 default:
451 return new_dot11_mode;
452 }
453
454 }
455
456 /**
457 * lim_fill_dot11mode() - to fill 802.11 mode in FT session
458 * @mac_ctx: pointer to mac ctx
459 * @ft_session: FT session
460 * @pe_session: PE session
461 * @bcn: AP beacon pointer
462 * @bss_phymode: bss phy mode
463 *
464 * This API fills FT session's dot11mode either from pe session or
465 * from CFG depending on the condition.
466 *
467 * Return: none
468 */
lim_fill_dot11mode(struct mac_context * mac_ctx,struct pe_session * ft_session,struct pe_session * pe_session,tSchBeaconStruct * bcn,enum wlan_phymode bss_phymode)469 static void lim_fill_dot11mode(struct mac_context *mac_ctx,
470 struct pe_session *ft_session,
471 struct pe_session *pe_session,
472 tSchBeaconStruct *bcn,
473 enum wlan_phymode bss_phymode)
474 {
475 if (pe_session->ftPEContext.pFTPreAuthReq &&
476 !wlan_is_roam_offload_enabled(mac_ctx->mlme_cfg->lfr)) {
477 ft_session->dot11mode =
478 pe_session->ftPEContext.pFTPreAuthReq->dot11mode;
479 return;
480 }
481
482 if (bss_phymode == WLAN_PHYMODE_AUTO)
483 ft_session->dot11mode = lim_calculate_dot11_mode(
484 mac_ctx, bcn,
485 ft_session->limRFBand);
486
487 else
488 ft_session->dot11mode =
489 lim_convert_phymode_to_dot11mode(bss_phymode);
490 }
491 #elif defined(WLAN_FEATURE_HOST_ROAM)
492 /**
493 * lim_fill_dot11mode() - to fill 802.11 mode in FT session
494 * @mac_ctx: pointer to mac ctx
495 * @ft_session: FT session
496 * @pe_session: PE session
497 * @bcn: AP beacon pointer
498 * @bss_phymode: bss phy mode
499 *
500 * This API fills FT session's dot11mode either from pe session.
501 *
502 * Return: none
503 */
lim_fill_dot11mode(struct mac_context * mac_ctx,struct pe_session * ft_session,struct pe_session * pe_session,tSchBeaconStruct * bcn,enum wlan_phymode bss_phymode)504 static void lim_fill_dot11mode(struct mac_context *mac_ctx,
505 struct pe_session *ft_session,
506 struct pe_session *pe_session,
507 tSchBeaconStruct *bcn,
508 enum wlan_phymode bss_phymode)
509 {
510 ft_session->dot11mode =
511 pe_session->ftPEContext.pFTPreAuthReq->dot11mode;
512 }
513 #endif
514
515 #if defined(WLAN_FEATURE_HOST_ROAM) || defined(WLAN_FEATURE_ROAM_OFFLOAD)
516 /**
517 * lim_fill_session_power_info() - to fill power info in session
518 * @mac: pointer to mac ctx
519 * @pbssDescription: Pointer to pbssDescription
520 * @ft_session: Pointer to FT session
521 * @pe_session: Pointer to PE session
522 *
523 * Return: QDF_STATUS
524 */
lim_fill_session_power_info(struct mac_context * mac,struct bss_description * pbssDescription,struct pe_session * ft_session,struct pe_session * pe_session)525 static QDF_STATUS lim_fill_session_power_info(
526 struct mac_context *mac,
527 struct bss_description *pbssDescription,
528 struct pe_session *ft_session,
529 struct pe_session *pe_session)
530 {
531 uint8_t currentBssUapsd;
532 int8_t localPowerConstraint = 0;
533 int8_t regMax = 0;
534 bool is_pwr_constraint = false;
535 struct vdev_mlme_obj *mlme_obj;
536 enum reg_6g_ap_type power_type_6g;
537 QDF_STATUS status;
538
539 mlme_obj = wlan_vdev_mlme_get_cmpt_obj(pe_session->vdev);
540 if (!mlme_obj) {
541 pe_err("vdev component object is NULL");
542 return QDF_STATUS_E_FAILURE;
543 }
544
545 lim_extract_ap_capability(mac, (uint8_t *)pbssDescription->ieFields,
546 lim_get_ielen_from_bss_description(pbssDescription),
547 &ft_session->limCurrentBssQosCaps,
548 ¤tBssUapsd,
549 &localPowerConstraint, ft_session, &is_pwr_constraint);
550
551 mlme_obj->reg_tpc_obj.is_power_constraint_abs = !is_pwr_constraint;
552
553 if (wlan_reg_is_6ghz_chan_freq(pbssDescription->chan_freq)) {
554 status = wlan_reg_get_best_6g_power_type(
555 mac->psoc, mac->pdev,
556 &power_type_6g,
557 ft_session->ap_defined_power_type_6g,
558 pbssDescription->chan_freq);
559 if (QDF_IS_STATUS_ERROR(status))
560 return status;
561
562 ft_session->best_6g_power_type = power_type_6g;
563 mlme_set_best_6g_power_type(ft_session->vdev, power_type_6g);
564 }
565
566 if (wlan_reg_is_ext_tpc_supported(mac->psoc)) {
567 mlme_obj->reg_tpc_obj.ap_constraint_power =
568 localPowerConstraint;
569 } else {
570 regMax = wlan_reg_get_channel_reg_power_for_freq(
571 mac->pdev, ft_session->curr_op_freq);
572 if (is_pwr_constraint)
573 localPowerConstraint = regMax - localPowerConstraint;
574 if (!localPowerConstraint)
575 localPowerConstraint = regMax;
576
577 mlme_obj->reg_tpc_obj.reg_max[0] = regMax;
578 mlme_obj->reg_tpc_obj.ap_constraint_power =
579 localPowerConstraint;
580 mlme_obj->reg_tpc_obj.frequency[0] = ft_session->curr_op_freq;
581
582 #ifdef FEATURE_WLAN_ESE
583 ft_session->maxTxPower = lim_get_max_tx_power(mac, mlme_obj);
584 #else
585 ft_session->maxTxPower = QDF_MIN(regMax, localPowerConstraint);
586 #endif
587 ft_session->def_max_tx_pwr = ft_session->maxTxPower;
588 }
589
590 /*
591 * for mdm platform which QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET
592 * will not call from android framework every 3 seconds, and tx
593 * power will never update. So we use iw dev get tx power need
594 * set maxTxPower non-zero value, that firmware can calc a non-zero
595 * tx power, and update to host driver.
596 */
597 if (ft_session->maxTxPower == 0)
598 ft_session->maxTxPower =
599 wlan_reg_get_channel_reg_power_for_freq(mac->pdev,
600 ft_session->curr_op_freq);
601
602 pe_debug("Reg max: %d local pwr: %d, max tx pwr: %d", regMax,
603 localPowerConstraint, ft_session->maxTxPower);
604
605 return QDF_STATUS_SUCCESS;
606 }
607
608 /*------------------------------------------------------------------
609 *
610 * Setup the new session for the pre-auth AP.
611 * Return the newly created session entry.
612 *
613 *------------------------------------------------------------------*/
614 QDF_STATUS
lim_fill_ft_session(struct mac_context * mac,struct bss_description * pbssDescription,struct pe_session * ft_session,struct pe_session * pe_session,enum wlan_phymode bss_phymode)615 lim_fill_ft_session(struct mac_context *mac,
616 struct bss_description *pbssDescription,
617 struct pe_session *ft_session,
618 struct pe_session *pe_session,
619 enum wlan_phymode bss_phymode)
620 {
621 uint8_t bss_chan_id;
622 tSchBeaconStruct *pBeaconStruct;
623 uint8_t cb_mode;
624 QDF_STATUS status = QDF_STATUS_SUCCESS;
625
626 pBeaconStruct = qdf_mem_malloc(sizeof(tSchBeaconStruct));
627 if (!pBeaconStruct)
628 return QDF_STATUS_E_NOMEM;
629
630 /* Retrieve the session that was already created and update the entry */
631 ft_session->limWmeEnabled = pe_session->limWmeEnabled;
632 ft_session->limQosEnabled = pe_session->limQosEnabled;
633 ft_session->limWsmEnabled = pe_session->limWsmEnabled;
634 ft_session->lim11hEnable = pe_session->lim11hEnable;
635 ft_session->isOSENConnection = pe_session->isOSENConnection;
636 ft_session->connected_akm = pe_session->connected_akm;
637
638 /* Fields to be filled later */
639 ft_session->lim_join_req = NULL;
640 ft_session->smeSessionId = pe_session->smeSessionId;
641
642 lim_extract_ap_capabilities(mac, (uint8_t *) pbssDescription->ieFields,
643 lim_get_ielen_from_bss_description(pbssDescription),
644 pBeaconStruct);
645
646 qdf_mem_zero(&ft_session->wmm_params, sizeof(tDot11fIEWMMParams));
647 if (pBeaconStruct->wmm_params.present)
648 qdf_mem_copy(&ft_session->wmm_params,
649 &pBeaconStruct->wmm_params,
650 sizeof(tDot11fIEWMMParams));
651
652 ft_session->rateSet.numRates =
653 pBeaconStruct->supportedRates.numRates;
654 qdf_mem_copy(ft_session->rateSet.rate,
655 pBeaconStruct->supportedRates.rate,
656 pBeaconStruct->supportedRates.numRates);
657
658 ft_session->extRateSet.numRates =
659 pBeaconStruct->extendedRates.numRates;
660 qdf_mem_copy(ft_session->extRateSet.rate,
661 pBeaconStruct->extendedRates.rate,
662 ft_session->extRateSet.numRates);
663
664 ft_session->ssId.length = pBeaconStruct->ssId.length;
665 qdf_mem_copy(ft_session->ssId.ssId, pBeaconStruct->ssId.ssId,
666 ft_session->ssId.length);
667 /* Copy The channel Id to the session Table */
668 bss_chan_id =
669 wlan_reg_freq_to_chan(mac->pdev, pbssDescription->chan_freq);
670 ft_session->lim_reassoc_chan_freq = pbssDescription->chan_freq;
671 ft_session->curr_op_freq = pbssDescription->chan_freq;
672 ft_session->limRFBand = lim_get_rf_band(ft_session->curr_op_freq);
673
674 lim_fill_dot11mode(mac, ft_session, pe_session, pBeaconStruct,
675 bss_phymode);
676 pe_debug("dot11mode: %d bss_phymode %d", ft_session->dot11mode,
677 bss_phymode);
678
679 ft_session->vhtCapability =
680 (IS_DOT11_MODE_VHT(ft_session->dot11mode) &&
681 (IS_BSS_VHT_CAPABLE(pBeaconStruct->VHTCaps) ||
682 IS_BSS_VHT_CAPABLE(pBeaconStruct->vendor_vht_ie.VHTCaps)));
683 ft_session->htCapability =
684 (IS_DOT11_MODE_HT(ft_session->dot11mode)
685 && pBeaconStruct->HTCaps.present);
686
687 if (IS_DOT11_MODE_HE(ft_session->dot11mode) &&
688 pBeaconStruct->he_cap.present) {
689 lim_update_session_he_capable(mac, ft_session);
690 lim_copy_join_req_he_cap(ft_session);
691 }
692 if (IS_DOT11_MODE_EHT(ft_session->dot11mode) &&
693 pBeaconStruct->eht_cap.present) {
694 lim_update_session_eht_capable(mac, ft_session);
695 lim_copy_join_req_eht_cap(ft_session);
696 }
697 /* Assign default configured nss value in the new session */
698 if (!wlan_reg_is_24ghz_ch_freq(ft_session->curr_op_freq))
699 ft_session->vdev_nss = mac->vdev_type_nss_5g.sta;
700 else
701 ft_session->vdev_nss = mac->vdev_type_nss_2g.sta;
702
703 ft_session->nss = ft_session ->vdev_nss;
704
705 cb_mode = lim_get_cb_mode_for_freq(mac, ft_session,
706 ft_session->curr_op_freq);
707
708 ft_session->htSupportedChannelWidthSet =
709 (pBeaconStruct->HTInfo.present) ?
710 (cb_mode && pBeaconStruct->HTInfo.recommendedTxWidthSet &&
711 pBeaconStruct->HTCaps.supportedChannelWidthSet) : 0;
712 ft_session->htRecommendedTxWidthSet =
713 ft_session->htSupportedChannelWidthSet;
714
715 if (IS_BSS_VHT_CAPABLE(pBeaconStruct->VHTCaps) &&
716 pBeaconStruct->VHTOperation.present &&
717 ft_session->vhtCapability) {
718 ft_session->vhtCapabilityPresentInBeacon = 1;
719 } else if (IS_BSS_VHT_CAPABLE(pBeaconStruct->vendor_vht_ie.VHTCaps) &&
720 pBeaconStruct->vendor_vht_ie.VHTOperation.present &&
721 ft_session->vhtCapability){
722 ft_session->vhtCapabilityPresentInBeacon = 1;
723 } else {
724 ft_session->vhtCapabilityPresentInBeacon = 0;
725 }
726
727 if (ft_session->htRecommendedTxWidthSet) {
728 ft_session->ch_width = CH_WIDTH_40MHZ;
729 if (ft_session->vhtCapabilityPresentInBeacon &&
730 pBeaconStruct->VHTOperation.chanWidth) {
731 ft_session->ch_width =
732 pBeaconStruct->VHTOperation.chanWidth + 1;
733 ft_session->ch_center_freq_seg0 =
734 pBeaconStruct->VHTOperation.chan_center_freq_seg0;
735 ft_session->ch_center_freq_seg1 =
736 pBeaconStruct->VHTOperation.chan_center_freq_seg1;
737 } else if (ft_session->vhtCapabilityPresentInBeacon &&
738 pBeaconStruct->vendor_vht_ie.VHTOperation.chanWidth) {
739 ft_session->ch_width =
740 pBeaconStruct->vendor_vht_ie.VHTOperation.chanWidth + 1;
741 ft_session->ch_center_freq_seg0 =
742 pBeaconStruct->vendor_vht_ie.VHTOperation.chan_center_freq_seg0;
743 ft_session->ch_center_freq_seg1 =
744 pBeaconStruct->vendor_vht_ie.VHTOperation.chan_center_freq_seg1;
745
746 } else {
747 if (pBeaconStruct->HTInfo.secondaryChannelOffset ==
748 PHY_DOUBLE_CHANNEL_LOW_PRIMARY)
749 ft_session->ch_center_freq_seg0 =
750 bss_chan_id + 2;
751 else if (pBeaconStruct->HTInfo.secondaryChannelOffset ==
752 PHY_DOUBLE_CHANNEL_HIGH_PRIMARY)
753 ft_session->ch_center_freq_seg0 =
754 bss_chan_id - 2;
755 else {
756 pe_warn("Invalid sec ch offset");
757 ft_session->ch_width = CH_WIDTH_20MHZ;
758 ft_session->ch_center_freq_seg0 = 0;
759 ft_session->ch_center_freq_seg1 = 0;
760 }
761 }
762 } else {
763 ft_session->ch_width = CH_WIDTH_20MHZ;
764 ft_session->ch_center_freq_seg0 = 0;
765 ft_session->ch_center_freq_seg1 = 0;
766 }
767
768 sir_copy_mac_addr(ft_session->self_mac_addr,
769 wlan_vdev_mlme_get_macaddr(pe_session->vdev));
770 sir_copy_mac_addr(ft_session->limReAssocbssId,
771 pbssDescription->bssId);
772 sir_copy_mac_addr(ft_session->prev_ap_bssid, pe_session->bssId);
773
774 /* Store beaconInterval */
775 ft_session->beaconParams.beaconInterval =
776 pbssDescription->beaconInterval;
777 ft_session->bssType = pe_session->bssType;
778
779 ft_session->statypeForBss = STA_ENTRY_PEER;
780 ft_session->nwType = pbssDescription->nwType;
781
782
783 if (ft_session->bssType == eSIR_INFRASTRUCTURE_MODE) {
784 ft_session->limSystemRole = eLIM_STA_ROLE;
785 } else {
786 /* Throw an error & return & make sure to delete the session */
787 pe_warn("Invalid bss type");
788 }
789
790 ft_session->limCurrentBssCaps = pbssDescription->capabilityInfo;
791 ft_session->limReassocBssCaps = pbssDescription->capabilityInfo;
792 if (mac->mlme_cfg->ht_caps.short_slot_time_enabled &&
793 SIR_MAC_GET_SHORT_SLOT_TIME(ft_session->limReassocBssCaps)) {
794 ft_session->shortSlotTimeSupported = true;
795 }
796
797 status = lim_fill_session_power_info(mac, pbssDescription, ft_session,
798 pe_session);
799 if (QDF_IS_STATUS_ERROR(status)) {
800 pe_err("Failed to fill power info in ft session");
801 goto exit;
802 }
803
804 ft_session->limReassocBssQosCaps =
805 ft_session->limCurrentBssQosCaps;
806
807 ft_session->is11Rconnection = pe_session->is11Rconnection;
808
809 #ifdef FEATURE_WLAN_ESE
810 ft_session->is_ese_version_ie_present =
811 pBeaconStruct->is_ese_ver_ie_present;
812 #endif
813
814 if (!lim_is_roam_synch_in_progress(mac->psoc, pe_session)) {
815 ft_session->limPrevSmeState = ft_session->limSmeState;
816 ft_session->limSmeState = eLIM_SME_WT_REASSOC_STATE;
817 MTRACE(mac_trace(mac,
818 TRACE_CODE_SME_STATE,
819 ft_session->peSessionId,
820 ft_session->limSmeState));
821 }
822 ft_session->encryptType = pe_session->encryptType;
823 ft_session->limRmfEnabled = pe_session->limRmfEnabled;
824 /* Load default OBSS parameters to session entry */
825 lim_init_obss_params(mac, ft_session);
826
827 /*
828 * By default supported NSS 1x1 is set to true
829 * and later on updated while determining session
830 * supported rates which is the intersection of
831 * self and peer rates
832 */
833 ft_session->supported_nss_1x1 = true;
834 pe_debug("FT enable smps: %d mode: %d supported nss 1x1: %d",
835 mac->mlme_cfg->ht_caps.enable_smps,
836 mac->mlme_cfg->ht_caps.smps,
837 ft_session->supported_nss_1x1);
838
839 exit:
840 qdf_mem_free(pBeaconStruct);
841 return status;
842 }
843 #endif
844
845 static void
lim_ft_send_aggr_qos_rsp(struct mac_context * mac,uint8_t rspReqd,struct aggr_add_ts_param * aggrQosRsp,uint8_t smesessionId)846 lim_ft_send_aggr_qos_rsp(struct mac_context *mac, uint8_t rspReqd,
847 struct aggr_add_ts_param *aggrQosRsp,
848 uint8_t smesessionId)
849 {
850 tpSirAggrQosRsp rsp;
851 int i = 0;
852
853 if (!rspReqd) {
854 return;
855 }
856 rsp = qdf_mem_malloc(sizeof(tSirAggrQosRsp));
857 if (!rsp)
858 return;
859
860 rsp->messageType = eWNI_SME_FT_AGGR_QOS_RSP;
861 rsp->sessionId = smesessionId;
862 rsp->length = sizeof(*rsp);
863 rsp->aggrInfo.tspecIdx = aggrQosRsp->tspecIdx;
864 for (i = 0; i < QCA_WLAN_AC_ALL; i++) {
865 if ((1 << i) & aggrQosRsp->tspecIdx) {
866 if (QDF_IS_STATUS_SUCCESS(aggrQosRsp->status[i]))
867 rsp->aggrInfo.aggrRsp[i].status =
868 STATUS_SUCCESS;
869 else
870 rsp->aggrInfo.aggrRsp[i].status =
871 STATUS_UNSPECIFIED_FAILURE;
872 rsp->aggrInfo.aggrRsp[i].tspec = aggrQosRsp->tspec[i];
873 }
874 }
875 lim_send_sme_aggr_qos_rsp(mac, rsp, smesessionId);
876 return;
877 }
878
lim_process_ft_aggr_qos_rsp(struct mac_context * mac,struct scheduler_msg * limMsg)879 void lim_process_ft_aggr_qos_rsp(struct mac_context *mac,
880 struct scheduler_msg *limMsg)
881 {
882 struct aggr_add_ts_param *pAggrQosRspMsg;
883 struct add_ts_param addTsParam = { 0 };
884 tpDphHashNode pSta = NULL;
885 uint16_t assocId = 0;
886 tSirMacAddr peerMacAddr;
887 uint8_t rspReqd = 1;
888 struct pe_session *pe_session = NULL;
889 int i = 0;
890
891 pe_debug(" Received AGGR_QOS_RSP from HAL");
892 SET_LIM_PROCESS_DEFD_MESGS(mac, true);
893 pAggrQosRspMsg = limMsg->bodyptr;
894 if (!pAggrQosRspMsg) {
895 pe_err("NULL pAggrQosRspMsg");
896 return;
897 }
898 pe_session =
899 pe_find_session_by_session_id(mac, pAggrQosRspMsg->sessionId);
900 if (!pe_session) {
901 pe_err("Cant find session entry");
902 if (pAggrQosRspMsg) {
903 qdf_mem_free(pAggrQosRspMsg);
904 }
905 return;
906 }
907 if (!LIM_IS_STA_ROLE(pe_session)) {
908 pe_err("pe_session is not in STA mode");
909 return;
910 }
911 for (i = 0; i < QCA_WLAN_AC_ALL; i++) {
912 if ((((1 << i) & pAggrQosRspMsg->tspecIdx)) &&
913 (pAggrQosRspMsg->status[i] != QDF_STATUS_SUCCESS)) {
914 sir_copy_mac_addr(peerMacAddr, pe_session->bssId);
915 addTsParam.pe_session_id = pAggrQosRspMsg->sessionId;
916 addTsParam.tspec = pAggrQosRspMsg->tspec[i];
917 addTsParam.tspec_idx = pAggrQosRspMsg->tspecIdx;
918 lim_send_delts_req_action_frame(mac, peerMacAddr,
919 rspReqd,
920 &addTsParam.tspec.tsinfo,
921 &addTsParam.tspec,
922 pe_session);
923 pSta =
924 dph_lookup_hash_entry(mac, peerMacAddr,
925 &assocId,
926 &pe_session->
927 dph.dphHashTable);
928
929 if (pSta) {
930 lim_admit_control_delete_ts(mac, assocId,
931 &addTsParam.tspec.
932 tsinfo, NULL,
933 (uint8_t *) &
934 addTsParam.tspec_idx);
935 }
936 }
937 }
938 lim_ft_send_aggr_qos_rsp(mac, rspReqd, pAggrQosRspMsg,
939 pe_session->smeSessionId);
940 if (pAggrQosRspMsg) {
941 qdf_mem_free(pAggrQosRspMsg);
942 }
943 return;
944 }
945
lim_process_ft_aggr_qos_req(struct mac_context * mac,uint32_t * msg_buf)946 QDF_STATUS lim_process_ft_aggr_qos_req(struct mac_context *mac,
947 uint32_t *msg_buf)
948 {
949 struct scheduler_msg msg = {0};
950 tSirAggrQosReq *aggrQosReq = (tSirAggrQosReq *) msg_buf;
951 struct aggr_add_ts_param *pAggrAddTsParam;
952 struct pe_session *pe_session = NULL;
953 tpLimTspecInfo tspecInfo;
954 uint8_t ac;
955 tpDphHashNode pSta;
956 uint16_t aid;
957 uint8_t sessionId;
958 int i;
959
960 pAggrAddTsParam = qdf_mem_malloc(sizeof(*pAggrAddTsParam));
961 if (!pAggrAddTsParam)
962 return QDF_STATUS_E_NOMEM;
963
964 pe_session = pe_find_session_by_bssid(mac, aggrQosReq->bssid.bytes,
965 &sessionId);
966
967 if (!pe_session) {
968 pe_err("psession Entry Null for sessionId: %d",
969 aggrQosReq->sessionId);
970 qdf_mem_free(pAggrAddTsParam);
971 return QDF_STATUS_E_FAILURE;
972 }
973
974 /* Nothing to be done if the session is not in STA mode */
975 if (!LIM_IS_STA_ROLE(pe_session)) {
976 pe_err("pe_session is not in STA mode");
977 qdf_mem_free(pAggrAddTsParam);
978 return QDF_STATUS_E_FAILURE;
979 }
980
981 pSta = dph_lookup_hash_entry(mac, aggrQosReq->bssid.bytes, &aid,
982 &pe_session->dph.dphHashTable);
983 if (!pSta) {
984 pe_err("Station context not found - ignoring AddTsRsp");
985 qdf_mem_free(pAggrAddTsParam);
986 return QDF_STATUS_E_FAILURE;
987 }
988
989 /* Fill in the sessionId specific to PE */
990 pAggrAddTsParam->sessionId = sessionId;
991 pAggrAddTsParam->tspecIdx = aggrQosReq->aggrInfo.tspecIdx;
992 pAggrAddTsParam->vdev_id = pe_session->smeSessionId;
993
994 for (i = 0; i < QCA_WLAN_AC_ALL; i++) {
995 if (aggrQosReq->aggrInfo.tspecIdx & (1 << i)) {
996 struct mac_tspec_ie *pTspec =
997 &aggrQosReq->aggrInfo.aggrAddTsInfo[i].tspec;
998 /* Since AddTS response was successful, check for the PSB flag
999 * and directional flag inside the TS Info field.
1000 * An AC is trigger enabled AC if the PSB subfield is set to 1
1001 * in the uplink direction.
1002 * An AC is delivery enabled AC if the PSB subfield is set to 1
1003 * in the downlink direction.
1004 * An AC is trigger and delivery enabled AC if the PSB subfield
1005 * is set to 1 in the bi-direction field.
1006 */
1007 if (pTspec->tsinfo.traffic.psb == 1) {
1008 lim_set_tspec_uapsd_mask_per_session(mac,
1009 pe_session,
1010 &pTspec->
1011 tsinfo,
1012 SET_UAPSD_MASK);
1013 } else {
1014 lim_set_tspec_uapsd_mask_per_session(mac,
1015 pe_session,
1016 &pTspec->
1017 tsinfo,
1018 CLEAR_UAPSD_MASK);
1019 }
1020 /*
1021 * ADDTS success, so AC is now admitted.
1022 * We shall now use the default
1023 * EDCA parameters as advertised by AP and
1024 * send the updated EDCA params
1025 * to HAL.
1026 */
1027 ac = upToAc(pTspec->tsinfo.traffic.userPrio);
1028 if (pTspec->tsinfo.traffic.direction ==
1029 SIR_MAC_DIRECTION_UPLINK) {
1030 pe_session->
1031 gAcAdmitMask
1032 [SIR_MAC_DIRECTION_UPLINK] |=
1033 (1 << ac);
1034 } else if (pTspec->tsinfo.traffic.direction ==
1035 SIR_MAC_DIRECTION_DNLINK) {
1036 pe_session->
1037 gAcAdmitMask
1038 [SIR_MAC_DIRECTION_DNLINK] |=
1039 (1 << ac);
1040 } else if (pTspec->tsinfo.traffic.direction ==
1041 SIR_MAC_DIRECTION_BIDIR) {
1042 pe_session->
1043 gAcAdmitMask
1044 [SIR_MAC_DIRECTION_UPLINK] |=
1045 (1 << ac);
1046 pe_session->
1047 gAcAdmitMask
1048 [SIR_MAC_DIRECTION_DNLINK] |=
1049 (1 << ac);
1050 }
1051 lim_set_active_edca_params(mac,
1052 pe_session->gLimEdcaParams,
1053 pe_session);
1054
1055 lim_send_edca_params(mac,
1056 pe_session->gLimEdcaParamsActive,
1057 pe_session->vdev_id, false);
1058
1059 if (QDF_STATUS_SUCCESS !=
1060 lim_tspec_add(mac, pSta->staAddr, pSta->assocId,
1061 pTspec, 0, &tspecInfo)) {
1062 pe_err("Adding entry in lim Tspec Table failed");
1063 mac->lim.gLimAddtsSent = false;
1064 qdf_mem_free(pAggrAddTsParam);
1065 return QDF_STATUS_E_FAILURE;
1066 }
1067
1068 pAggrAddTsParam->tspec[i] =
1069 aggrQosReq->aggrInfo.aggrAddTsInfo[i].tspec;
1070 }
1071 }
1072
1073 #ifdef WLAN_FEATURE_ROAM_OFFLOAD
1074 if (!mac->mlme_cfg->lfr.lfr3_roaming_offload ||
1075 (mac->mlme_cfg->lfr.lfr3_roaming_offload &&
1076 !pe_session->is11Rconnection))
1077 #endif
1078 {
1079 msg.type = WMA_AGGR_QOS_REQ;
1080 msg.bodyptr = pAggrAddTsParam;
1081 msg.bodyval = 0;
1082
1083 /* We need to defer any incoming messages until we get a
1084 * WMA_AGGR_QOS_RSP from HAL.
1085 */
1086 SET_LIM_PROCESS_DEFD_MESGS(mac, false);
1087 MTRACE(mac_trace_msg_tx(mac, pe_session->peSessionId, msg.type));
1088
1089 if (QDF_STATUS_SUCCESS != wma_post_ctrl_msg(mac, &msg)) {
1090 pe_warn("wma_post_ctrl_msg() failed");
1091 SET_LIM_PROCESS_DEFD_MESGS(mac, true);
1092 qdf_mem_free(pAggrAddTsParam);
1093 return QDF_STATUS_E_FAILURE;
1094 }
1095 }
1096 #ifdef WLAN_FEATURE_ROAM_OFFLOAD
1097 else {
1098 /* Implies it is a LFR3.0 based 11r connection
1099 * so donot send add ts request to firmware since it
1100 * already has the RIC IEs */
1101
1102 /* Send the Aggr QoS response to SME */
1103 lim_ft_send_aggr_qos_rsp(mac, true, pAggrAddTsParam,
1104 pe_session->smeSessionId);
1105 if (pAggrAddTsParam) {
1106 qdf_mem_free(pAggrAddTsParam);
1107 }
1108 }
1109 #endif
1110
1111 return QDF_STATUS_SUCCESS;
1112 }
1113