xref: /wlan-dirver/qcacld-3.0/core/mac/src/pe/lim/lim_ft.c (revision be9a0ab9410bb65f899b9fceac3229cd023a706e)
1 /*
2  * Copyright (c) 2012-2021 The Linux Foundation. All rights reserved.
3  * Copyright (c) 2021-2023 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    ------------------------------------------------------------------------*/
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 
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 
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  *------------------------------------------------------------------*/
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  */
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_context: 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  */
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  */
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  */
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_ctx: 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  */
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 		&currentBssUapsd,
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
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 	ePhyChanBondState cbEnabledMode;
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 	if (ft_session->limRFBand == REG_BAND_2G) {
706 		cbEnabledMode = mac->roam.configParam.channelBondingMode24GHz;
707 	} else {
708 		cbEnabledMode = mac->roam.configParam.channelBondingMode5GHz;
709 	}
710 	ft_session->htSupportedChannelWidthSet =
711 	    (pBeaconStruct->HTInfo.present) ?
712 	    (cbEnabledMode && pBeaconStruct->HTInfo.recommendedTxWidthSet &&
713 	     pBeaconStruct->HTCaps.supportedChannelWidthSet) : 0;
714 	ft_session->htRecommendedTxWidthSet =
715 		ft_session->htSupportedChannelWidthSet;
716 
717 	if (IS_BSS_VHT_CAPABLE(pBeaconStruct->VHTCaps) &&
718 		pBeaconStruct->VHTOperation.present &&
719 		ft_session->vhtCapability) {
720 		ft_session->vhtCapabilityPresentInBeacon = 1;
721 	} else if (IS_BSS_VHT_CAPABLE(pBeaconStruct->vendor_vht_ie.VHTCaps) &&
722 		    pBeaconStruct->vendor_vht_ie.VHTOperation.present &&
723 		    ft_session->vhtCapability){
724 		ft_session->vhtCapabilityPresentInBeacon = 1;
725 	} else {
726 		ft_session->vhtCapabilityPresentInBeacon = 0;
727 	}
728 
729 	if (ft_session->htRecommendedTxWidthSet) {
730 		ft_session->ch_width = CH_WIDTH_40MHZ;
731 		if (ft_session->vhtCapabilityPresentInBeacon &&
732 				pBeaconStruct->VHTOperation.chanWidth) {
733 			ft_session->ch_width =
734 				pBeaconStruct->VHTOperation.chanWidth + 1;
735 			ft_session->ch_center_freq_seg0 =
736 			pBeaconStruct->VHTOperation.chan_center_freq_seg0;
737 			ft_session->ch_center_freq_seg1 =
738 			pBeaconStruct->VHTOperation.chan_center_freq_seg1;
739 		} else if (ft_session->vhtCapabilityPresentInBeacon &&
740 			   pBeaconStruct->vendor_vht_ie.VHTOperation.chanWidth){
741 			ft_session->ch_width =
742 			pBeaconStruct->vendor_vht_ie.VHTOperation.chanWidth + 1;
743 			ft_session->ch_center_freq_seg0 =
744 		pBeaconStruct->vendor_vht_ie.VHTOperation.chan_center_freq_seg0;
745 			ft_session->ch_center_freq_seg1 =
746 		pBeaconStruct->vendor_vht_ie.VHTOperation.chan_center_freq_seg1;
747 
748 		} else {
749 			if (pBeaconStruct->HTInfo.secondaryChannelOffset ==
750 					PHY_DOUBLE_CHANNEL_LOW_PRIMARY)
751 				ft_session->ch_center_freq_seg0 =
752 					bss_chan_id + 2;
753 			else if (pBeaconStruct->HTInfo.secondaryChannelOffset ==
754 					PHY_DOUBLE_CHANNEL_HIGH_PRIMARY)
755 				ft_session->ch_center_freq_seg0 =
756 					bss_chan_id - 2;
757 			else {
758 				pe_warn("Invalid sec ch offset");
759 				ft_session->ch_width = CH_WIDTH_20MHZ;
760 				ft_session->ch_center_freq_seg0 = 0;
761 				ft_session->ch_center_freq_seg1 = 0;
762 			}
763 		}
764 	} else {
765 		ft_session->ch_width = CH_WIDTH_20MHZ;
766 		ft_session->ch_center_freq_seg0 = 0;
767 		ft_session->ch_center_freq_seg1 = 0;
768 	}
769 
770 	sir_copy_mac_addr(ft_session->self_mac_addr,
771 			  wlan_vdev_mlme_get_macaddr(pe_session->vdev));
772 	sir_copy_mac_addr(ft_session->limReAssocbssId,
773 			  pbssDescription->bssId);
774 	sir_copy_mac_addr(ft_session->prev_ap_bssid, pe_session->bssId);
775 
776 	/* Store beaconInterval */
777 	ft_session->beaconParams.beaconInterval =
778 		pbssDescription->beaconInterval;
779 	ft_session->bssType = pe_session->bssType;
780 
781 	ft_session->statypeForBss = STA_ENTRY_PEER;
782 	ft_session->nwType = pbssDescription->nwType;
783 
784 
785 	if (ft_session->bssType == eSIR_INFRASTRUCTURE_MODE) {
786 		ft_session->limSystemRole = eLIM_STA_ROLE;
787 	} else {
788 		/* Throw an error & return & make sure to delete the session */
789 		pe_warn("Invalid bss type");
790 	}
791 
792 	ft_session->limCurrentBssCaps = pbssDescription->capabilityInfo;
793 	ft_session->limReassocBssCaps = pbssDescription->capabilityInfo;
794 	if (mac->mlme_cfg->ht_caps.short_slot_time_enabled &&
795 	    SIR_MAC_GET_SHORT_SLOT_TIME(ft_session->limReassocBssCaps)) {
796 		ft_session->shortSlotTimeSupported = true;
797 	}
798 
799 	status = lim_fill_session_power_info(mac, pbssDescription, ft_session,
800 					     pe_session);
801 	if (QDF_IS_STATUS_ERROR(status)) {
802 		pe_err("Failed to fill power info in ft session");
803 		goto exit;
804 	}
805 
806 	ft_session->limReassocBssQosCaps =
807 		ft_session->limCurrentBssQosCaps;
808 
809 	ft_session->is11Rconnection = pe_session->is11Rconnection;
810 
811 #ifdef FEATURE_WLAN_ESE
812 	ft_session->is_ese_version_ie_present =
813 		pBeaconStruct->is_ese_ver_ie_present;
814 #endif
815 
816 	if (!lim_is_roam_synch_in_progress(mac->psoc, pe_session)) {
817 		ft_session->limPrevSmeState = ft_session->limSmeState;
818 		ft_session->limSmeState = eLIM_SME_WT_REASSOC_STATE;
819 		MTRACE(mac_trace(mac,
820 				TRACE_CODE_SME_STATE,
821 				ft_session->peSessionId,
822 				ft_session->limSmeState));
823 	}
824 	ft_session->encryptType = pe_session->encryptType;
825 	ft_session->limRmfEnabled = pe_session->limRmfEnabled;
826 	/* Load default OBSS parameters to session entry */
827 	lim_init_obss_params(mac, ft_session);
828 
829 	/*
830 	 * By default supported NSS 1x1 is set to true
831 	 * and later on updated while determining session
832 	 * supported rates which is the intersection of
833 	 * self and peer rates
834 	 */
835 	ft_session->supported_nss_1x1 = true;
836 	pe_debug("FT enable smps: %d mode: %d supported nss 1x1: %d",
837 		mac->mlme_cfg->ht_caps.enable_smps,
838 		mac->mlme_cfg->ht_caps.smps,
839 		ft_session->supported_nss_1x1);
840 
841 exit:
842 	qdf_mem_free(pBeaconStruct);
843 	return status;
844 }
845 #endif
846 
847 static void
848 lim_ft_send_aggr_qos_rsp(struct mac_context *mac, uint8_t rspReqd,
849 			 struct aggr_add_ts_param *aggrQosRsp,
850 			 uint8_t smesessionId)
851 {
852 	tpSirAggrQosRsp rsp;
853 	int i = 0;
854 
855 	if (!rspReqd) {
856 		return;
857 	}
858 	rsp = qdf_mem_malloc(sizeof(tSirAggrQosRsp));
859 	if (!rsp)
860 		return;
861 
862 	rsp->messageType = eWNI_SME_FT_AGGR_QOS_RSP;
863 	rsp->sessionId = smesessionId;
864 	rsp->length = sizeof(*rsp);
865 	rsp->aggrInfo.tspecIdx = aggrQosRsp->tspecIdx;
866 	for (i = 0; i < QCA_WLAN_AC_ALL; i++) {
867 		if ((1 << i) & aggrQosRsp->tspecIdx) {
868 			if (QDF_IS_STATUS_SUCCESS(aggrQosRsp->status[i]))
869 				rsp->aggrInfo.aggrRsp[i].status =
870 					STATUS_SUCCESS;
871 			else
872 				rsp->aggrInfo.aggrRsp[i].status =
873 					STATUS_UNSPECIFIED_FAILURE;
874 			rsp->aggrInfo.aggrRsp[i].tspec = aggrQosRsp->tspec[i];
875 		}
876 	}
877 	lim_send_sme_aggr_qos_rsp(mac, rsp, smesessionId);
878 	return;
879 }
880 
881 void lim_process_ft_aggr_qos_rsp(struct mac_context *mac,
882 				 struct scheduler_msg *limMsg)
883 {
884 	struct aggr_add_ts_param *pAggrQosRspMsg;
885 	struct add_ts_param addTsParam = { 0 };
886 	tpDphHashNode pSta = NULL;
887 	uint16_t assocId = 0;
888 	tSirMacAddr peerMacAddr;
889 	uint8_t rspReqd = 1;
890 	struct pe_session *pe_session = NULL;
891 	int i = 0;
892 
893 	pe_debug(" Received AGGR_QOS_RSP from HAL");
894 	SET_LIM_PROCESS_DEFD_MESGS(mac, true);
895 	pAggrQosRspMsg = limMsg->bodyptr;
896 	if (!pAggrQosRspMsg) {
897 		pe_err("NULL pAggrQosRspMsg");
898 		return;
899 	}
900 	pe_session =
901 		pe_find_session_by_session_id(mac, pAggrQosRspMsg->sessionId);
902 	if (!pe_session) {
903 		pe_err("Cant find session entry");
904 		if (pAggrQosRspMsg) {
905 			qdf_mem_free(pAggrQosRspMsg);
906 		}
907 		return;
908 	}
909 	if (!LIM_IS_STA_ROLE(pe_session)) {
910 		pe_err("pe_session is not in STA mode");
911 		return;
912 	}
913 	for (i = 0; i < QCA_WLAN_AC_ALL; i++) {
914 		if ((((1 << i) & pAggrQosRspMsg->tspecIdx)) &&
915 		    (pAggrQosRspMsg->status[i] != QDF_STATUS_SUCCESS)) {
916 			sir_copy_mac_addr(peerMacAddr, pe_session->bssId);
917 			addTsParam.pe_session_id = pAggrQosRspMsg->sessionId;
918 			addTsParam.tspec = pAggrQosRspMsg->tspec[i];
919 			addTsParam.tspec_idx = pAggrQosRspMsg->tspecIdx;
920 			lim_send_delts_req_action_frame(mac, peerMacAddr,
921 							rspReqd,
922 							&addTsParam.tspec.tsinfo,
923 							&addTsParam.tspec,
924 							pe_session);
925 			pSta =
926 				dph_lookup_hash_entry(mac, peerMacAddr,
927 						      &assocId,
928 						      &pe_session->
929 						      dph.dphHashTable);
930 
931 			if (pSta) {
932 				lim_admit_control_delete_ts(mac, assocId,
933 							    &addTsParam.tspec.
934 							    tsinfo, NULL,
935 							    (uint8_t *) &
936 							    addTsParam.tspec_idx);
937 			}
938 		}
939 	}
940 	lim_ft_send_aggr_qos_rsp(mac, rspReqd, pAggrQosRspMsg,
941 				 pe_session->smeSessionId);
942 	if (pAggrQosRspMsg) {
943 		qdf_mem_free(pAggrQosRspMsg);
944 	}
945 	return;
946 }
947 
948 QDF_STATUS lim_process_ft_aggr_qos_req(struct mac_context *mac,
949 				       uint32_t *msg_buf)
950 {
951 	struct scheduler_msg msg = {0};
952 	tSirAggrQosReq *aggrQosReq = (tSirAggrQosReq *) msg_buf;
953 	struct aggr_add_ts_param *pAggrAddTsParam;
954 	struct pe_session *pe_session = NULL;
955 	tpLimTspecInfo tspecInfo;
956 	uint8_t ac;
957 	tpDphHashNode pSta;
958 	uint16_t aid;
959 	uint8_t sessionId;
960 	int i;
961 
962 	pAggrAddTsParam = qdf_mem_malloc(sizeof(*pAggrAddTsParam));
963 	if (!pAggrAddTsParam)
964 		return QDF_STATUS_E_NOMEM;
965 
966 	pe_session = pe_find_session_by_bssid(mac, aggrQosReq->bssid.bytes,
967 					      &sessionId);
968 
969 	if (!pe_session) {
970 		pe_err("psession Entry Null for sessionId: %d",
971 			       aggrQosReq->sessionId);
972 		qdf_mem_free(pAggrAddTsParam);
973 		return QDF_STATUS_E_FAILURE;
974 	}
975 
976 	/* Nothing to be done if the session is not in STA mode */
977 	if (!LIM_IS_STA_ROLE(pe_session)) {
978 		pe_err("pe_session is not in STA mode");
979 		qdf_mem_free(pAggrAddTsParam);
980 		return QDF_STATUS_E_FAILURE;
981 	}
982 
983 	pSta = dph_lookup_hash_entry(mac, aggrQosReq->bssid.bytes, &aid,
984 				     &pe_session->dph.dphHashTable);
985 	if (!pSta) {
986 		pe_err("Station context not found - ignoring AddTsRsp");
987 		qdf_mem_free(pAggrAddTsParam);
988 		return QDF_STATUS_E_FAILURE;
989 	}
990 
991 	/* Fill in the sessionId specific to PE */
992 	pAggrAddTsParam->sessionId = sessionId;
993 	pAggrAddTsParam->tspecIdx = aggrQosReq->aggrInfo.tspecIdx;
994 	pAggrAddTsParam->vdev_id = pe_session->smeSessionId;
995 
996 	for (i = 0; i < QCA_WLAN_AC_ALL; i++) {
997 		if (aggrQosReq->aggrInfo.tspecIdx & (1 << i)) {
998 			struct mac_tspec_ie *pTspec =
999 				&aggrQosReq->aggrInfo.aggrAddTsInfo[i].tspec;
1000 			/* Since AddTS response was successful, check for the PSB flag
1001 			 * and directional flag inside the TS Info field.
1002 			 * An AC is trigger enabled AC if the PSB subfield is set to 1
1003 			 * in the uplink direction.
1004 			 * An AC is delivery enabled AC if the PSB subfield is set to 1
1005 			 * in the downlink direction.
1006 			 * An AC is trigger and delivery enabled AC if the PSB subfield
1007 			 * is set to 1 in the bi-direction field.
1008 			 */
1009 			if (pTspec->tsinfo.traffic.psb == 1) {
1010 				lim_set_tspec_uapsd_mask_per_session(mac,
1011 								     pe_session,
1012 								     &pTspec->
1013 								     tsinfo,
1014 								     SET_UAPSD_MASK);
1015 			} else {
1016 				lim_set_tspec_uapsd_mask_per_session(mac,
1017 								     pe_session,
1018 								     &pTspec->
1019 								     tsinfo,
1020 								     CLEAR_UAPSD_MASK);
1021 			}
1022 			/*
1023 			 * ADDTS success, so AC is now admitted.
1024 			 * We shall now use the default
1025 			 * EDCA parameters as advertised by AP and
1026 			 * send the updated EDCA params
1027 			 * to HAL.
1028 			 */
1029 			ac = upToAc(pTspec->tsinfo.traffic.userPrio);
1030 			if (pTspec->tsinfo.traffic.direction ==
1031 			    SIR_MAC_DIRECTION_UPLINK) {
1032 				pe_session->
1033 				gAcAdmitMask
1034 				[SIR_MAC_DIRECTION_UPLINK] |=
1035 					(1 << ac);
1036 			} else if (pTspec->tsinfo.traffic.direction ==
1037 				   SIR_MAC_DIRECTION_DNLINK) {
1038 				pe_session->
1039 				gAcAdmitMask
1040 				[SIR_MAC_DIRECTION_DNLINK] |=
1041 					(1 << ac);
1042 			} else if (pTspec->tsinfo.traffic.direction ==
1043 				   SIR_MAC_DIRECTION_BIDIR) {
1044 				pe_session->
1045 				gAcAdmitMask
1046 				[SIR_MAC_DIRECTION_UPLINK] |=
1047 					(1 << ac);
1048 				pe_session->
1049 					gAcAdmitMask
1050 					[SIR_MAC_DIRECTION_DNLINK] |=
1051 					(1 << ac);
1052 			}
1053 			lim_set_active_edca_params(mac,
1054 						   pe_session->gLimEdcaParams,
1055 						   pe_session);
1056 
1057 				lim_send_edca_params(mac,
1058 					     pe_session->gLimEdcaParamsActive,
1059 					     pe_session->vdev_id, false);
1060 
1061 			if (QDF_STATUS_SUCCESS !=
1062 			    lim_tspec_add(mac, pSta->staAddr, pSta->assocId,
1063 					  pTspec, 0, &tspecInfo)) {
1064 				pe_err("Adding entry in lim Tspec Table failed");
1065 				mac->lim.gLimAddtsSent = false;
1066 				qdf_mem_free(pAggrAddTsParam);
1067 				return QDF_STATUS_E_FAILURE;
1068 			}
1069 
1070 			pAggrAddTsParam->tspec[i] =
1071 				aggrQosReq->aggrInfo.aggrAddTsInfo[i].tspec;
1072 		}
1073 	}
1074 
1075 #ifdef WLAN_FEATURE_ROAM_OFFLOAD
1076 	if (!mac->mlme_cfg->lfr.lfr3_roaming_offload ||
1077 	    (mac->mlme_cfg->lfr.lfr3_roaming_offload &&
1078 	     !pe_session->is11Rconnection))
1079 #endif
1080 	{
1081 	msg.type = WMA_AGGR_QOS_REQ;
1082 	msg.bodyptr = pAggrAddTsParam;
1083 	msg.bodyval = 0;
1084 
1085 	/* We need to defer any incoming messages until we get a
1086 	 * WMA_AGGR_QOS_RSP from HAL.
1087 	 */
1088 	SET_LIM_PROCESS_DEFD_MESGS(mac, false);
1089 	MTRACE(mac_trace_msg_tx(mac, pe_session->peSessionId, msg.type));
1090 
1091 	if (QDF_STATUS_SUCCESS != wma_post_ctrl_msg(mac, &msg)) {
1092 			pe_warn("wma_post_ctrl_msg() failed");
1093 			SET_LIM_PROCESS_DEFD_MESGS(mac, true);
1094 			qdf_mem_free(pAggrAddTsParam);
1095 			return QDF_STATUS_E_FAILURE;
1096 		}
1097 	}
1098 #ifdef WLAN_FEATURE_ROAM_OFFLOAD
1099 	else {
1100 		/* Implies it is a LFR3.0 based 11r connection
1101 		 * so donot send add ts request to firmware since it
1102 		 * already has the RIC IEs */
1103 
1104 		/* Send the Aggr QoS response to SME */
1105 		lim_ft_send_aggr_qos_rsp(mac, true, pAggrAddTsParam,
1106 					 pe_session->smeSessionId);
1107 		if (pAggrAddTsParam) {
1108 			qdf_mem_free(pAggrAddTsParam);
1109 		}
1110 	}
1111 #endif
1112 
1113 	return QDF_STATUS_SUCCESS;
1114 }
1115