xref: /wlan-dirver/qcacld-3.0/core/mac/src/pe/sch/sch_beacon_process.c (revision 5f87c0b118df8e541f3051a13b7414c1dd79020b)
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  * This file sch_beacon_process.cc contains beacon processing related
22  * functions
23  *
24  * Author:      Sandesh Goel
25  * Date:        02/25/02
26  * History:-
27  * Date            Modified by    Modification Information
28  * --------------------------------------------------------------------
29  *
30  */
31 
32 #include "cds_api.h"
33 #include "wni_cfg.h"
34 
35 #include "cfg_ucfg_api.h"
36 #include "lim_api.h"
37 #include "utils_api.h"
38 #include "sch_api.h"
39 
40 #include "lim_utils.h"
41 #include "lim_send_messages.h"
42 #include "rrm_api.h"
43 #include "lim_mlo.h"
44 
45 #ifdef FEATURE_WLAN_DIAG_SUPPORT
46 #include "host_diag_core_log.h"
47 #endif /* FEATURE_WLAN_DIAG_SUPPORT */
48 
49 #include "wma.h"
50 
51 #include "wlan_lmac_if_def.h"
52 #include "wlan_reg_services_api.h"
53 #include "wlan_mlo_mgr_sta.h"
54 #include "wlan_mlme_main.h"
55 #include <wlan_mlo_mgr_link_switch.h>
56 
57 static void
58 ap_beacon_process_5_ghz(struct mac_context *mac_ctx, uint8_t *rx_pkt_info,
59 			tpSchBeaconStruct bcn_struct,
60 			tpUpdateBeaconParams bcn_prm, struct pe_session *session,
61 			uint32_t phy_mode)
62 {
63 	tpSirMacMgmtHdr mac_hdr = WMA_GET_RX_MAC_HEADER(rx_pkt_info);
64 
65 	if (!session->htCapability)
66 		return;
67 
68 	if (bcn_struct->chan_freq != session->curr_op_freq)
69 		return;
70 
71 	/* 11a (non HT) AP  overlaps or */
72 	/* HT AP with HT op mode as mixed overlaps. */
73 	/* HT AP with HT op mode as overlap legacy overlaps. */
74 	if (!bcn_struct->HTInfo.present
75 	    || (eSIR_HT_OP_MODE_MIXED == bcn_struct->HTInfo.opMode)
76 	    || (eSIR_HT_OP_MODE_OVERLAP_LEGACY == bcn_struct->HTInfo.opMode)) {
77 		lim_update_overlap_sta_param(mac_ctx, mac_hdr->bssId,
78 					&(session->gLimOverlap11aParams));
79 
80 		if (session->gLimOverlap11aParams.numSta
81 		    && !session->gLimOverlap11aParams.protectionEnabled) {
82 			lim_update_11a_protection(mac_ctx, true, true,
83 						 bcn_prm, session);
84 		}
85 		return;
86 	}
87 	/* HT AP with HT20 op mode overlaps. */
88 	if (eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT != bcn_struct->HTInfo.opMode)
89 		return;
90 
91 	lim_update_overlap_sta_param(mac_ctx, mac_hdr->bssId,
92 				     &(session->gLimOverlapHt20Params));
93 
94 	if (session->gLimOverlapHt20Params.numSta
95 	    && !session->gLimOverlapHt20Params.protectionEnabled)
96 		lim_enable_ht20_protection(mac_ctx, true, true,
97 					   bcn_prm, session);
98 }
99 
100 static void
101 ap_beacon_process_24_ghz(struct mac_context *mac_ctx, uint8_t *rx_pkt_info,
102 			 tpSchBeaconStruct bcn_struct,
103 			 tpUpdateBeaconParams bcn_prm, struct pe_session *session,
104 			 uint32_t phy_mode)
105 {
106 	tpSirMacMgmtHdr mac_hdr = WMA_GET_RX_MAC_HEADER(rx_pkt_info);
107 	bool tmp_exp = false;
108 	/* We are 11G AP. */
109 	if ((phy_mode == WNI_CFG_PHY_MODE_11G) &&
110 	    (false == session->htCapability)) {
111 		if (bcn_struct->chan_freq != session->curr_op_freq)
112 			return;
113 
114 		tmp_exp = (!bcn_struct->erpPresent &&
115 			   !bcn_struct->HTInfo.present) ||
116 			    /* if erp not present then  11B AP overlapping */
117 			  (!mac_ctx->mlme_cfg->sta.ignore_peer_erp_info &&
118 			   bcn_struct->erpPresent &&
119 			   (bcn_struct->erpIEInfo.useProtection ||
120 			    bcn_struct->erpIEInfo.nonErpPresent));
121 		if (!tmp_exp)
122 			return;
123 #ifdef FEATURE_WLAN_ESE
124 		if (wlan_cm_get_ese_assoc(mac_ctx->pdev, session->vdev_id))
125 			pe_info("[INFOLOG]ESE 11g erpPresent=%d useProtection=%d nonErpPresent=%d",
126 				bcn_struct->erpPresent,
127 				bcn_struct->erpIEInfo.useProtection,
128 				bcn_struct->erpIEInfo.nonErpPresent);
129 #endif
130 		lim_enable_overlap11g_protection(mac_ctx, bcn_prm,
131 						 mac_hdr, session);
132 		return;
133 	}
134 	/* handling the case when HT AP has overlapping legacy BSS. */
135 	if (!session->htCapability)
136 		return;
137 
138 	if (bcn_struct->chan_freq != session->curr_op_freq)
139 		return;
140 
141 	tmp_exp = (!bcn_struct->erpPresent && !bcn_struct->HTInfo.present) ||
142 		    /* if erp not present then  11B AP overlapping */
143 		   (!mac_ctx->mlme_cfg->sta.ignore_peer_erp_info &&
144 		    bcn_struct->erpPresent &&
145 		    (bcn_struct->erpIEInfo.useProtection ||
146 		     bcn_struct->erpIEInfo.nonErpPresent));
147 	if (tmp_exp) {
148 #ifdef FEATURE_WLAN_ESE
149 		if (wlan_cm_get_ese_assoc(mac_ctx->pdev, session->vdev_id)) {
150 			pe_info("[INFOLOG]ESE 11g erpPresent=%d useProtection=%d nonErpPresent=%d",
151 				bcn_struct->erpPresent,
152 				bcn_struct->erpIEInfo.useProtection,
153 				bcn_struct->erpIEInfo.nonErpPresent);
154 		}
155 #endif
156 		lim_enable_overlap11g_protection(mac_ctx, bcn_prm,
157 						 mac_hdr, session);
158 	}
159 	/* 11g device overlaps */
160 	tmp_exp = bcn_struct->erpPresent
161 		&& !(bcn_struct->erpIEInfo.useProtection
162 		     || bcn_struct->erpIEInfo.nonErpPresent)
163 		&& !(bcn_struct->HTInfo.present);
164 	if (tmp_exp) {
165 		lim_update_overlap_sta_param(mac_ctx, mac_hdr->bssId,
166 					     &(session->gLimOverlap11gParams));
167 
168 		if (session->gLimOverlap11gParams.numSta
169 		    && !session->gLimOverlap11gParams.protectionEnabled)
170 			lim_enable_ht_protection_from11g(mac_ctx, true, true,
171 							 bcn_prm, session);
172 	}
173 	/* ht device overlaps.
174 	 * here we will check for HT related devices only which might need
175 	 * protection. check for 11b and 11g is already done in the previous
176 	 * blocks. so we will not check for HT operating mode as MIXED.
177 	 */
178 	if (!bcn_struct->HTInfo.present)
179 		return;
180 
181 	/*
182 	 * if we are not already in mixed mode or legacy mode as HT operating
183 	 * mode and received beacon has HT operating mode as legacy then we need
184 	 * to enable protection from 11g station. we don't need protection from
185 	 * 11b because if that's needed then our operating mode would have
186 	 * already been set to legacy in the previous blocks.
187 	 */
188 	if ((eSIR_HT_OP_MODE_OVERLAP_LEGACY == bcn_struct->HTInfo.opMode) &&
189 		!mac_ctx->mlme_cfg->sap_protection_cfg.ignore_peer_ht_opmode) {
190 		if (eSIR_HT_OP_MODE_OVERLAP_LEGACY == mac_ctx->lim.gHTOperMode
191 		    || eSIR_HT_OP_MODE_MIXED == mac_ctx->lim.gHTOperMode)
192 			return;
193 		lim_update_overlap_sta_param(mac_ctx, mac_hdr->bssId,
194 					     &(session->gLimOverlap11gParams));
195 		if (session->gLimOverlap11gParams.numSta
196 		    && !session->gLimOverlap11gParams.protectionEnabled)
197 			lim_enable_ht_protection_from11g(mac_ctx, true, true,
198 							 bcn_prm, session);
199 		return;
200 	}
201 
202 	if (eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT == bcn_struct->HTInfo.opMode) {
203 		lim_update_overlap_sta_param(mac_ctx, mac_hdr->bssId,
204 					     &(session->gLimOverlapHt20Params));
205 		if (session->gLimOverlapHt20Params.numSta
206 		    && !session->gLimOverlapHt20Params.protectionEnabled)
207 			lim_enable_ht20_protection(mac_ctx, true, true,
208 						   bcn_prm, session);
209 	}
210 }
211 
212 /**
213  * ap_beacon_process() - processes incoming beacons
214  *
215  * @mac_ctx:         mac global context
216  * @rx_pkt_info:     incoming beacon packet
217  * @bcn_struct:      beacon struct
218  * @bcn_prm:         beacon params
219  * @session:         pe session entry
220  *
221  * Return: void
222  */
223 static void
224 ap_beacon_process(struct mac_context *mac_ctx, uint8_t *rx_pkt_info,
225 		  tpSchBeaconStruct bcn_struct,
226 		  tpUpdateBeaconParams bcn_prm, struct pe_session *session)
227 {
228 	uint32_t phy_mode;
229 	enum reg_wifi_band rf_band = REG_BAND_UNKNOWN;
230 	/* Get RF band from session */
231 	rf_band = session->limRFBand;
232 
233 	lim_get_phy_mode(mac_ctx, &phy_mode, session);
234 
235 	if (REG_BAND_5G == rf_band)
236 		ap_beacon_process_5_ghz(mac_ctx, rx_pkt_info, bcn_struct,
237 					bcn_prm, session, phy_mode);
238 	else if (REG_BAND_2G == rf_band)
239 		ap_beacon_process_24_ghz(mac_ctx, rx_pkt_info, bcn_struct,
240 					 bcn_prm, session, phy_mode);
241 }
242 
243 /* -------------------------------------------------------------------- */
244 
245 /*
246  * sch_bcn_process_sta() - Process the received beacon frame for sta
247  * @mac_ctx:        mac_ctx
248  * @bcn:            beacon struct
249  * @rx_pkt_info:    received packet info
250  * @session:        pe session pointer
251  * @beaconParams:   update beacon params
252  * @sendProbeReq:   out flag to indicate if probe rsp is to be sent
253  * @pMh:            mac header
254  *
255  * Process the received beacon frame for sta
256  *
257  * Return: success of failure of operation
258  */
259 static bool
260 sch_bcn_process_sta(struct mac_context *mac_ctx,
261 			       tpSchBeaconStruct bcn,
262 			       uint8_t *rx_pkt_info,
263 			       struct pe_session *session,
264 			       tUpdateBeaconParams *beaconParams,
265 			       uint8_t *sendProbeReq, tpSirMacMgmtHdr pMh)
266 {
267 	uint32_t bi;
268 	tpDphHashNode sta = NULL;
269 	QDF_STATUS status;
270 
271 	/*
272 	 *  This handles two cases:
273 	 *  -- Infra STA receiving beacons from AP
274 	 */
275 
276 	/**
277 	 * This is the Beacon received from the AP  we're currently associated
278 	 * with. Check if there are any changes in AP's capabilities
279 	 */
280 	if (bcn->chan_freq != session->curr_op_freq) {
281 		pe_err("Channel Change freq from %d --> %d - Ignoring beacon!",
282 		       session->curr_op_freq, bcn->chan_freq);
283 		return false;
284 	}
285 
286 	/*
287 	 * Ignore bcn as channel switch IE present and csa offload is enabled,
288 	 * as in CSA offload enabled case FW will send Event to switch channel
289 	 */
290 	if (bcn->channelSwitchPresent && wma_is_csa_offload_enabled()) {
291 		pe_err_rl("Ignore bcn as channel switch IE present and csa offload is enabled");
292 		return false;
293 	}
294 
295 	lim_detect_change_in_ap_capabilities(mac_ctx, bcn, session, true);
296 	beaconParams->bss_idx = session->vdev_id;
297 	qdf_mem_copy((uint8_t *) &session->lastBeaconTimeStamp,
298 			(uint8_t *) bcn->timeStamp, sizeof(uint64_t));
299 	session->currentBssBeaconCnt++;
300 	if (session->bcon_dtim_period != bcn->tim.dtimPeriod) {
301 		session->bcon_dtim_period = bcn->tim.dtimPeriod;
302 		lim_send_set_dtim_period(mac_ctx, bcn->tim.dtimPeriod,
303 				session);
304 	}
305 	MTRACE(mac_trace(mac_ctx, TRACE_CODE_RX_MGMT_TSF,
306 	       session->peSessionId, bcn->timeStamp[0]));
307 	MTRACE(mac_trace(mac_ctx, TRACE_CODE_RX_MGMT_TSF,
308 	       session->peSessionId, bcn->timeStamp[1]));
309 
310 	/* Read beacon interval session Entry */
311 	bi = session->beaconParams.beaconInterval;
312 	if (bi != bcn->beaconInterval) {
313 		pe_debug("Beacon interval changed from %d to %d",
314 		       bcn->beaconInterval, bi);
315 
316 		bi = bcn->beaconInterval;
317 		session->beaconParams.beaconInterval = (uint16_t) bi;
318 		beaconParams->paramChangeBitmap |= PARAM_BCN_INTERVAL_CHANGED;
319 		beaconParams->beaconInterval = (uint16_t) bi;
320 	}
321 
322 	if (bcn->cfPresent) {
323 		if (!cfg_in_range(CFG_CFP_PERIOD, bcn->cfParamSet.cfpPeriod)) {
324 			pe_err("Error in setting CFG item CFP Period");
325 			return false;
326 		}
327 		mac_ctx->mlme_cfg->rates.cfp_period = bcn->cfParamSet.cfpPeriod;
328 	}
329 
330 	/* No need to send DTIM Period and Count to HAL/SMAC */
331 	/* SMAC already parses TIM bit. */
332 	if (bcn->timPresent) {
333 		if (cfg_in_range(CFG_DTIM_PERIOD, bcn->tim.dtimPeriod))
334 			mac_ctx->mlme_cfg->sap_cfg.dtim_interval =
335 						bcn->tim.dtimPeriod;
336 	}
337 
338 	if (mac_ctx->lim.gLimProtectionControl !=
339 	    MLME_FORCE_POLICY_PROTECTION_DISABLE)
340 		lim_decide_sta_protection(mac_ctx, bcn, beaconParams, session);
341 
342 	if (bcn->erpPresent) {
343 		if (bcn->erpIEInfo.barkerPreambleMode)
344 			lim_enable_short_preamble(mac_ctx, false,
345 						  beaconParams, session);
346 		else
347 			lim_enable_short_preamble(mac_ctx, true,
348 						  beaconParams, session);
349 	}
350 	lim_update_short_slot(mac_ctx, bcn, beaconParams, session);
351 
352 	sta = dph_get_hash_entry(mac_ctx, DPH_STA_HASH_INDEX_PEER,
353 				    &session->dph.dphHashTable);
354 	if ((bcn->wmeEdcaPresent && session->limWmeEnabled) ||
355 	    (bcn->edcaPresent && session->limQosEnabled)) {
356 		if (bcn->edcaParams.qosInfo.count !=
357 		    session->gLimEdcaParamSetCount) {
358 			qdf_mem_copy(&sta->qos.peer_edca_params,
359 				     &bcn->edcaParams,
360 				     sizeof(bcn->edcaParams));
361 			status = sch_beacon_edca_process(mac_ctx,
362 							 &bcn->edcaParams,
363 							 session);
364 			if (QDF_IS_STATUS_ERROR(status)) {
365 				pe_err("EDCA parameter processing error");
366 			} else if (sta) {
367 				/* If needed, downgrade the EDCA parameters */
368 				lim_set_active_edca_params(mac_ctx,
369 					session->gLimEdcaParams, session);
370 				lim_send_edca_params(mac_ctx,
371 					session->gLimEdcaParamsActive,
372 					session->vdev_id, false);
373 				sch_qos_concurrency_update();
374 			} else {
375 				pe_err("Self Entry missing in Hash Table");
376 			}
377 		}
378 		return true;
379 	}
380 
381 	if ((bcn->qosCapabilityPresent && session->limQosEnabled)
382 	    && (bcn->qosCapability.qosInfo.count !=
383 		session->gLimEdcaParamSetCount))
384 		*sendProbeReq = true;
385 
386 	return true;
387 }
388 
389 #ifdef WLAN_FEATURE_11AX_BSS_COLOR
390 static void
391 sch_bcn_update_he_ies(struct mac_context *mac_ctx, tpDphHashNode sta_ds,
392 				struct pe_session *session, tpSchBeaconStruct bcn,
393 				tpSirMacMgmtHdr mac_hdr)
394 {
395 	uint8_t session_bss_col_disabled_flag;
396 	bool anything_changed = false;
397 
398 	if (session->is_session_obss_color_collision_det_enabled)
399 		return;
400 
401 	if (session->he_op.present && bcn->he_op.present) {
402 		if (bcn->vendor_he_bss_color_change.present &&
403 				(session->he_op.bss_color !=
404 				 bcn->vendor_he_bss_color_change.new_color)) {
405 			pe_debug("bss color changed from [%d] to [%d]",
406 				session->he_op.bss_color,
407 				bcn->vendor_he_bss_color_change.new_color);
408 			session->he_op.bss_color =
409 				bcn->vendor_he_bss_color_change.new_color;
410 			anything_changed = true;
411 		}
412 		session_bss_col_disabled_flag = session->he_op.bss_col_disabled;
413 		if (session_bss_col_disabled_flag !=
414 				bcn->he_op.bss_col_disabled) {
415 			pe_debug("color disable flag changed from [%d] to [%d]",
416 				session->he_op.bss_col_disabled,
417 				bcn->he_op.bss_col_disabled);
418 			session->he_op.bss_col_disabled =
419 				bcn->he_op.bss_col_disabled;
420 			anything_changed = true;
421 		}
422 	}
423 	if (anything_changed)
424 		lim_send_he_ie_update(mac_ctx, session);
425 }
426 #else
427 static void
428 sch_bcn_update_he_ies(struct mac_context *mac_ctx, tpDphHashNode sta_ds,
429 				struct pe_session *session, tpSchBeaconStruct bcn,
430 				tpSirMacMgmtHdr mac_hdr)
431 {
432 	return;
433 }
434 #endif
435 
436 static void
437 sch_bcn_update_opmode_change(struct mac_context *mac_ctx, tpDphHashNode sta_ds,
438 			     struct pe_session *session, tpSchBeaconStruct bcn,
439 			     tpSirMacMgmtHdr mac_hdr)
440 {
441 	enum phy_ch_width ch_bw;
442 	enum phy_ch_width ch_width = CH_WIDTH_20MHZ;
443 	tDot11fIEVHTCaps *vht_caps = NULL;
444 	tDot11fIEVHTOperation *vht_op = NULL;
445 	uint8_t bcn_vht_chwidth = 0;
446 	bool is_40 = false;
447 
448 	/*
449 	 * Ignore opmode change during channel change The opmode will be updated
450 	 * with the beacons on new channel once the AP move to new channel.
451 	 */
452 	if (session->ch_switch_in_progress) {
453 		pe_debug("Ignore opmode change as channel switch is in progress");
454 		return;
455 	}
456 	if (bcn->eht_op.eht_op_information_present) {
457 		pe_debug("Ignore opmode change as there is EHT operation information");
458 		return;
459 	}
460 
461 	if (bcn->VHTCaps.present) {
462 		vht_caps = &bcn->VHTCaps;
463 		vht_op = &bcn->VHTOperation;
464 	} else if (bcn->vendor_vht_ie.VHTCaps.present) {
465 		vht_caps = &bcn->vendor_vht_ie.VHTCaps;
466 		vht_op = &bcn->vendor_vht_ie.VHTOperation;
467 	}
468 	if (!session->vhtCapability ||
469 	    !(bcn->OperatingMode.present ||
470 	      (vht_op && vht_op->present && vht_caps)))
471 		return;
472 
473 	is_40 = bcn->HTInfo.present ?
474 			bcn->HTInfo.recommendedTxWidthSet : false;
475 
476 	if (bcn->OperatingMode.present) {
477 		pe_debug("OMN IE is present in the beacon, update NSS/Ch width");
478 		lim_update_nss(mac_ctx, sta_ds, bcn->OperatingMode.rxNSS,
479 			       session);
480 		ch_width = bcn->OperatingMode.chanWidth;
481 	} else {
482 		bcn_vht_chwidth = lim_get_vht_ch_width(vht_caps, vht_op,
483 						       &bcn->HTInfo);
484 		ch_width =
485 			lim_convert_vht_chwidth_to_phy_chwidth(bcn_vht_chwidth,
486 							       is_40);
487 	}
488 	lim_update_channel_width(mac_ctx, sta_ds, session, ch_width, &ch_bw);
489 }
490 
491 #ifdef WLAN_FEATURE_SR
492 /**
493  * lim_detect_change_in_srp() - Detect change in SRP IE
494  * of the beacon
495  *
496  * @mac_ctx: global mac context
497  * @sta: pointer to sta node
498  * @session: pointer to LIM session
499  * @bcn: beacon from associated AP
500  *
501  * Detect change in SRP IE of the beacon and update the params
502  * accordingly.
503  *
504  * Return: None
505  */
506 static void lim_detect_change_in_srp(struct mac_context *mac_ctx,
507 				     tpDphHashNode sta,
508 				     struct pe_session *session,
509 				     tpSchBeaconStruct bcn)
510 {
511 	tDot11fIEspatial_reuse sr_ie;
512 	int32_t ret = 0;
513 
514 	sr_ie = sta->parsed_ies.srp_ie;
515 	if (sr_ie.present || bcn->srp_ie.present) {
516 		ret = qdf_mem_cmp(&sr_ie, &bcn->srp_ie,
517 				  sizeof(tDot11fIEspatial_reuse));
518 
519 		if (ret) {
520 			/*
521 			 * If SRP IE has changes, update the new params.
522 			 */
523 			sta->parsed_ies.srp_ie = bcn->srp_ie;
524 			lim_update_vdev_sr_elements(session, sta);
525 
526 			lim_handle_sr_cap(session->vdev,
527 					  SR_REASON_CODE_BCN_IE_CHANGE);
528 		}
529 	}
530 }
531 #else
532 static void lim_detect_change_in_srp(struct mac_context *mac_ctx,
533 				     tpDphHashNode sta,
534 				     struct pe_session *session,
535 				     tpSchBeaconStruct bcn)
536 {
537 }
538 #endif
539 
540 static void
541 sch_bcn_process_sta_opmode(struct mac_context *mac_ctx,
542 			    tpSchBeaconStruct bcn,
543 			    uint8_t *rx_pkt_info,
544 			    struct pe_session *session,
545 			    tUpdateBeaconParams *beaconParams,
546 			    uint8_t *sendProbeReq, tpSirMacMgmtHdr pMh)
547 {
548 	tpDphHashNode sta = NULL;
549 	uint16_t aid;
550 
551 	/* check for VHT capability */
552 	sta = dph_lookup_hash_entry(mac_ctx, pMh->sa, &aid,
553 			&session->dph.dphHashTable);
554 	if (!sta)
555 		return;
556 	sch_bcn_update_opmode_change(mac_ctx, sta, session, bcn, pMh);
557 	sch_bcn_update_he_ies(mac_ctx, sta, session, bcn, pMh);
558 	lim_detect_change_in_srp(mac_ctx, sta, session, bcn);
559 	return;
560 }
561 
562 /**
563  * get_local_power_constraint_beacon() - extracts local constraint
564  * from beacon
565  * @bcn: beacon structure
566  * @local_constraint: local constraint pointer
567  * @is_power_constraint_abs: is power constraint absolute
568  *
569  * Return: None
570  */
571 #ifdef FEATURE_WLAN_ESE
572 static void get_local_power_constraint_beacon(
573 		tpSchBeaconStruct bcn,
574 		int8_t *local_constraint,
575 		bool *is_power_constraint_abs)
576 {
577 	if (bcn->eseTxPwr.present) {
578 		*local_constraint = bcn->eseTxPwr.power_limit;
579 		*is_power_constraint_abs = true;
580 	}
581 }
582 #else
583 static void get_local_power_constraint_beacon(
584 		tpSchBeaconStruct bcn,
585 		int8_t *local_constraint,
586 		bool *is_power_constraint_abs)
587 {
588 
589 }
590 #endif
591 
592 static void __sch_beacon_process_for_session(struct mac_context *mac_ctx,
593 					     tpSchBeaconStruct bcn,
594 					     uint8_t *rx_pkt_info,
595 					     struct pe_session *session)
596 {
597 	tUpdateBeaconParams beaconParams;
598 	uint8_t sendProbeReq = false;
599 	tpSirMacMgmtHdr pMh = WMA_GET_RX_MAC_HEADER(rx_pkt_info);
600 	int8_t local_constraint = 0;
601 	uint32_t chan_freq = 0;
602 	struct vdev_mlme_obj *mlme_obj;
603 	struct wlan_lmac_if_reg_tx_ops *tx_ops;
604 	bool ap_constraint_change = false, tpe_change = false;
605 	bool allow_tpc = false;
606 	int8_t regMax = 0, maxTxPower = 0;
607 	QDF_STATUS status;
608 	bool skip_tpe = false, is_sap_go_switched_ch;
609 	enum reg_6g_ap_type pwr_type_6g;
610 	uint8_t bpcc;
611 	bool cu_flag = true;
612 	bool is_power_constraint_abs = false;
613 
614 	if (mlo_is_mld_sta(session->vdev)) {
615 		cu_flag = false;
616 		status = lim_get_bpcc_from_mlo_ie(bcn, &bpcc);
617 		if (QDF_IS_STATUS_SUCCESS(status))
618 			cu_flag = lim_check_cu_happens(session->vdev, bpcc);
619 		lim_process_ml_reconfig(mac_ctx, session, rx_pkt_info);
620 	}
621 
622 	if (!cu_flag)
623 		return;
624 
625 	qdf_mem_zero(&beaconParams, sizeof(tUpdateBeaconParams));
626 	beaconParams.paramChangeBitmap = 0;
627 
628 	if (LIM_IS_STA_ROLE(session)) {
629 		is_sap_go_switched_ch =
630 			wlan_vdev_mlme_is_sap_go_move_before_sta(session->vdev);
631 		if (is_sap_go_switched_ch)
632 			policy_mgr_sta_sap_dfs_enforce_scc(mac_ctx->psoc,
633 							   session->vdev_id);
634 		if (false == sch_bcn_process_sta(mac_ctx, bcn, rx_pkt_info,
635 						 session, &beaconParams,
636 						 &sendProbeReq, pMh))
637 			return;
638 	}
639 
640 	/*
641 	 * For vht session, if opermode ie or vht oper IE is present
642 	 * bandwidth change will be taken care using these vht IEs.
643 	 */
644 	if (!(session->vhtCapability && (bcn->OperatingMode.present ||
645 	   bcn->VHTOperation.present)) && session->htCapability &&
646 	   bcn->HTInfo.present)
647 		lim_update_sta_run_time_ht_switch_chnl_params(mac_ctx,
648 						&bcn->HTInfo, session);
649 
650 	if (LIM_IS_STA_ROLE(session))
651 		sch_bcn_process_sta_opmode(mac_ctx, bcn, rx_pkt_info, session,
652 					    &beaconParams, &sendProbeReq, pMh);
653 
654 	mlme_obj = wlan_vdev_mlme_get_cmpt_obj(session->vdev);
655 	if (!mlme_obj) {
656 		pe_err("vdev component object is NULL");
657 		return;
658 	}
659 
660 	if (!wlan_reg_is_6ghz_chan_freq(bcn->chan_freq)) {
661 		skip_tpe = wlan_mlme_skip_tpe(mac_ctx->psoc);
662 	} else {
663 		if (!bcn->countryInfoParam.countryString[0]) {
664 			pe_err("Channel is 6G but country IE not present");
665 			return;
666 		}
667 		if (bcn->he_op.oper_info_6g_present) {
668 			session->ap_defined_power_type_6g =
669 					bcn->he_op.oper_info_6g.info.reg_info;
670 			if (session->ap_defined_power_type_6g < REG_INDOOR_AP ||
671 			    session->ap_defined_power_type_6g >
672 			    REG_MAX_SUPP_AP_TYPE) {
673 				session->ap_defined_power_type_6g =
674 						REG_CURRENT_MAX_AP_TYPE;
675 				pe_debug("AP power type is invalid, defaulting to MAX_AP_TYPE");
676 			}
677 		} else {
678 			pe_debug("AP power type is null, defaulting to MAX_AP_TYPE");
679 			session->ap_defined_power_type_6g =
680 						REG_CURRENT_MAX_AP_TYPE;
681 		}
682 
683 		status = wlan_reg_get_best_6g_power_type(
684 				mac_ctx->psoc, mac_ctx->pdev, &pwr_type_6g,
685 				session->ap_defined_power_type_6g,
686 				bcn->chan_freq);
687 		if (QDF_IS_STATUS_ERROR(status))
688 			return;
689 
690 		session->best_6g_power_type = pwr_type_6g;
691 		mlme_set_best_6g_power_type(session->vdev, pwr_type_6g);
692 	}
693 
694 	/*
695 	 * STA LPI + SAP VLP is supported. For this STA should operate in VLP
696 	 * power level of the SAP.
697 	 * If STA is operating in VLP power of SAP, do not update STA power.
698 	 */
699 	if (wlan_reg_is_ext_tpc_supported(mac_ctx->psoc) &&
700 	    !session->sta_follows_sap_power) {
701 		tx_ops = wlan_reg_get_tx_ops(mac_ctx->psoc);
702 
703 		lim_parse_tpe_ie(mac_ctx, session, bcn->transmit_power_env,
704 				 bcn->num_transmit_power_env, &bcn->he_op,
705 				 &tpe_change);
706 
707 		if (mac_ctx->mlme_cfg->sta.allow_tpc_from_ap) {
708 			get_local_power_constraint_beacon(
709 						bcn, &local_constraint,
710 						&is_power_constraint_abs);
711 
712 			if (mac_ctx->rrm.rrmPEContext.rrmEnable &&
713 			    bcn->powerConstraintPresent) {
714 				local_constraint =
715 				bcn->localPowerConstraint.localPowerConstraints;
716 				is_power_constraint_abs = false;
717 			}
718 			allow_tpc = true;
719 		}
720 
721 		if (allow_tpc && local_constraint !=
722 		    mlme_obj->reg_tpc_obj.ap_constraint_power) {
723 			mlme_obj->reg_tpc_obj.ap_constraint_power =
724 							local_constraint;
725 			mlme_obj->reg_tpc_obj.is_power_constraint_abs =
726 							is_power_constraint_abs;
727 			ap_constraint_change = true;
728 		}
729 
730 		if (ap_constraint_change || (tpe_change && !skip_tpe)) {
731 			lim_calculate_tpc(mac_ctx, session);
732 
733 			if (tx_ops->set_tpc_power)
734 				tx_ops->set_tpc_power(mac_ctx->psoc,
735 						      session->vdev_id,
736 						      &mlme_obj->reg_tpc_obj);
737 		}
738 	} else if (!session->sta_follows_sap_power) {
739 		/* Obtain the Max Tx power for the current regulatory  */
740 		regMax = wlan_reg_get_channel_reg_power_for_freq(
741 					mac_ctx->pdev, session->curr_op_freq);
742 		local_constraint = regMax;
743 
744 		if (mac_ctx->mlme_cfg->sta.allow_tpc_from_ap) {
745 			get_local_power_constraint_beacon(
746 						bcn, &local_constraint,
747 						&is_power_constraint_abs);
748 
749 			if (mac_ctx->rrm.rrmPEContext.rrmEnable &&
750 			    bcn->powerConstraintPresent) {
751 				local_constraint = regMax;
752 				local_constraint -=
753 				bcn->localPowerConstraint.localPowerConstraints;
754 				is_power_constraint_abs = false;
755 
756 			}
757 		}
758 		mlme_obj->reg_tpc_obj.is_power_constraint_abs =
759 						is_power_constraint_abs;
760 		mlme_obj->reg_tpc_obj.reg_max[0] = regMax;
761 		mlme_obj->reg_tpc_obj.ap_constraint_power = local_constraint;
762 		mlme_obj->reg_tpc_obj.frequency[0] = session->curr_op_freq;
763 
764 		maxTxPower = lim_get_max_tx_power(mac_ctx, mlme_obj);
765 
766 		/* If maxTxPower is increased or decreased */
767 		if (maxTxPower != session->maxTxPower) {
768 			pe_debug("New maxTx power %d, old pwr %d",
769 				 maxTxPower, session->maxTxPower);
770 			pe_debug("regMax %d, local %d", regMax,
771 				 local_constraint);
772 			status = lim_send_set_max_tx_power_req(mac_ctx,
773 							       maxTxPower,
774 							       session);
775 			if (status == QDF_STATUS_SUCCESS)
776 				session->maxTxPower = maxTxPower;
777 		}
778 	}
779 	/* Indicate to LIM that Beacon is received */
780 	if (bcn->HTInfo.present) {
781 		chan_freq = wlan_reg_legacy_chan_to_freq(mac_ctx->pdev,
782 							 bcn->HTInfo.primaryChannel);
783 		lim_received_hb_handler(mac_ctx, chan_freq, session);
784 	} else
785 		lim_received_hb_handler(mac_ctx, bcn->chan_freq, session);
786 
787 	/*
788 	 * I don't know if any additional IE is required here. Currently, not
789 	 * include addIE.
790 	 */
791 	if (sendProbeReq)
792 		lim_send_probe_req_mgmt_frame(mac_ctx, &session->ssId,
793 			session->bssId, session->curr_op_freq,
794 			session->self_mac_addr, session->dot11mode, NULL, NULL);
795 
796 	if ((false == mac_ctx->sap.SapDfsInfo.is_dfs_cac_timer_running)
797 	    && beaconParams.paramChangeBitmap) {
798 		pe_debug("Beacon for session[%d] got changed param change bitmap: 0x%x",
799 			 session->peSessionId, beaconParams.paramChangeBitmap);
800 		lim_send_beacon_params(mac_ctx, &beaconParams, session);
801 	}
802 
803 	if ((session->opmode == QDF_P2P_CLIENT_MODE) &&
804 	    session->send_p2p_conf_frame) {
805 		lim_p2p_oper_chan_change_confirm_action_frame(mac_ctx,
806 							      session->bssId,
807 							      session);
808 		session->send_p2p_conf_frame = false;
809 	}
810 
811 	lim_process_beacon_eht(mac_ctx, session, bcn);
812 	lim_process_bcn_prb_rsp_t2lm(mac_ctx, session, bcn);
813 }
814 
815 #ifdef WLAN_FEATURE_11AX_BSS_COLOR
816 static void ap_update_bss_color_info(struct mac_context *mac_ctx,
817 						struct pe_session *session,
818 						uint8_t bss_color)
819 {
820 	if (!session)
821 		return;
822 
823 	if (bss_color < 1 || bss_color > 63) {
824 		pe_warn("Invalid BSS color");
825 		return;
826 	}
827 
828 	session->bss_color_info[bss_color - 1].seen_count++;
829 	session->bss_color_info[bss_color - 1].timestamp =
830 					qdf_get_system_timestamp();
831 }
832 
833 static uint8_t ap_get_new_bss_color(struct mac_context *mac_ctx, struct pe_session *session)
834 {
835 	int i;
836 	uint8_t new_bss_color;
837 	struct bss_color_info color_info;
838 	qdf_time_t cur_timestamp;
839 
840 	if (!session)
841 		return 0;
842 
843 	color_info = session->bss_color_info[0];
844 	new_bss_color = 0;
845 	cur_timestamp = qdf_get_system_timestamp();
846 	for (i = 1; i < MAX_BSS_COLOR_VALUE; i++) {
847 		if (session->bss_color_info[i].seen_count == 0) {
848 			new_bss_color = i + 1;
849 			return new_bss_color;
850 		}
851 
852 		if (color_info.seen_count >
853 				session->bss_color_info[i].seen_count &&
854 				(cur_timestamp - session->bss_color_info[i].
855 					timestamp) > TIME_BEACON_NOT_UPDATED) {
856 			color_info = session->bss_color_info[i];
857 			new_bss_color = i + 1;
858 		}
859 	}
860 	pe_debug("new bss color: %d", new_bss_color);
861 	return new_bss_color;
862 }
863 
864 static void sch_check_bss_color_ie(struct mac_context *mac_ctx,
865 					struct pe_session *ap_session,
866 					tSchBeaconStruct *bcn,
867 					tUpdateBeaconParams *bcn_prm)
868 {
869 	/* check bss color in the beacon */
870 	if (ap_session->he_op.present && !ap_session->he_op.bss_color) {
871 		if (bcn->he_op.present &&
872 			(bcn->he_op.bss_color ==
873 					ap_session->he_op.bss_color)) {
874 			ap_session->he_op.bss_col_disabled = 1;
875 			bcn_prm->paramChangeBitmap |=
876 						PARAM_BSS_COLOR_CHANGED;
877 			ap_session->he_bss_color_change.countdown =
878 						BSS_COLOR_SWITCH_COUNTDOWN;
879 			ap_session->he_bss_color_change.new_color =
880 					ap_get_new_bss_color(mac_ctx,
881 								ap_session);
882 			ap_session->he_op.bss_color = ap_session->
883 						he_bss_color_change.new_color;
884 			bcn_prm->bss_color = ap_session->he_op.bss_color;
885 			bcn_prm->bss_color_disabled =
886 					ap_session->he_op.bss_col_disabled;
887 			ap_session->bss_color_changing = 1;
888 		} else {
889 			/* update info for the bss color */
890 			if (bcn->he_op.present)
891 				ap_update_bss_color_info(mac_ctx,
892 						ap_session,
893 						bcn->he_op.bss_color);
894 		}
895 	}
896 }
897 
898 #else
899 static void  sch_check_bss_color_ie(struct mac_context *mac_ctx,
900 					struct pe_session *ap_session,
901 					tSchBeaconStruct *bcn,
902 					tUpdateBeaconParams *bcn_prm)
903 {
904 }
905 #endif
906 
907 void sch_beacon_process_for_ap(struct mac_context *mac_ctx,
908 				uint8_t session_id,
909 				uint8_t *rx_pkt_info,
910 				tSchBeaconStruct *bcn)
911 {
912 	struct pe_session *ap_session;
913 	tUpdateBeaconParams bcn_prm;
914 
915 	if (!bcn || !rx_pkt_info) {
916 		pe_debug("bcn %pK or rx_pkt_info %pKis NULL",
917 			 bcn, rx_pkt_info);
918 		return;
919 	}
920 
921 	ap_session = pe_find_session_by_session_id(mac_ctx, session_id);
922 	if (!ap_session)
923 		return;
924 
925 	if (!LIM_IS_AP_ROLE(ap_session))
926 		return;
927 
928 	qdf_mem_zero(&bcn_prm, sizeof(tUpdateBeaconParams));
929 	bcn_prm.paramChangeBitmap = 0;
930 
931 	bcn_prm.bss_idx = ap_session->vdev_id;
932 
933 	if (!ap_session->is_session_obss_color_collision_det_enabled)
934 		sch_check_bss_color_ie(mac_ctx, ap_session,
935 					bcn, &bcn_prm);
936 
937 	if ((ap_session->gLimProtectionControl !=
938 	     MLME_FORCE_POLICY_PROTECTION_DISABLE) &&
939 	    !ap_session->is_session_obss_offload_enabled)
940 		ap_beacon_process(mac_ctx, rx_pkt_info,
941 					bcn, &bcn_prm, ap_session);
942 
943 	if ((false == mac_ctx->sap.SapDfsInfo.is_dfs_cac_timer_running)
944 	    && bcn_prm.paramChangeBitmap) {
945 		/* Update the bcn and apply the new settings to HAL */
946 		sch_set_fixed_beacon_fields(mac_ctx, ap_session);
947 		pe_debug("Beacon for PE session[%d] got changed",
948 		       ap_session->peSessionId);
949 		pe_debug("sending beacon param change bitmap: 0x%x",
950 		       bcn_prm.paramChangeBitmap);
951 		lim_send_beacon_params(mac_ctx, &bcn_prm, ap_session);
952 	}
953 }
954 
955 #ifdef WLAN_BCN_RECV_FEATURE
956 /*
957  * sch_send_beacon_report() - To Fill beacon report for
958  * each beacon coming from connected peer and sends it
959  * to upper layer
960  * @mac_ctx: Mac context
961  * @beacon_struct: Pointing to beacon structure
962  * @session: pointer to the PE session
963  *
964  * Return: None
965  */
966 static
967 void sch_send_beacon_report(struct mac_context *mac_ctx,
968 			    struct sSirProbeRespBeacon *beacon_struct,
969 			    struct pe_session *session)
970 {
971 	struct wlan_beacon_report beacon_report;
972 	beacon_report_cb sme_bcn_cb;
973 
974 	sme_bcn_cb = mac_ctx->lim.sme_bcn_rcv_callback;
975 	if (!sme_bcn_cb)
976 		return;
977 
978 	if (!LIM_IS_STA_ROLE(session))
979 		return;
980 
981 	if (sir_compare_mac_addr(session->bssId, beacon_struct->bssid)) {
982 		/* Prepare beacon report from incoming beacon */
983 		qdf_mem_copy(beacon_report.bssid.bytes, beacon_struct->bssid,
984 			     sizeof(tSirMacAddr));
985 
986 		qdf_mem_copy(&beacon_report.time_stamp,
987 			     &beacon_struct->timeStamp, sizeof(qdf_time_t));
988 		beacon_report.beacon_interval = beacon_struct->beaconInterval;
989 		beacon_report.frequency = beacon_struct->chan_freq;
990 
991 		beacon_report.ssid.length = beacon_struct->ssId.length;
992 		qdf_mem_copy(&beacon_report.ssid.ssid,
993 			     &beacon_struct->ssId.ssId,
994 			     beacon_report.ssid.length);
995 
996 		beacon_report.boot_time =
997 				qdf_do_div(qdf_get_monotonic_boottime(),
998 					   QDF_MC_TIMER_TO_MS_UNIT);
999 
1000 		beacon_report.vdev_id = session->vdev_id;
1001 
1002 		/* Send report to upper layer */
1003 		sme_bcn_cb(mac_ctx->hdd_handle, &beacon_report);
1004 	}
1005 }
1006 
1007 #else
1008 static inline
1009 void sch_send_beacon_report(struct mac_context *mac_ctx,
1010 			    struct sSirProbeRespBeacon *beacon_struct,
1011 			    struct pe_session *session)
1012 {
1013 }
1014 #endif
1015 
1016 /**
1017  * sch_beacon_process() - process the beacon frame
1018  * @mac_ctx: mac global context
1019  * @rx_pkt_info: pointer to buffer descriptor
1020  * @session: pointer to the PE session
1021  *
1022  * Return: None
1023  */
1024 void
1025 sch_beacon_process(struct mac_context *mac_ctx, uint8_t *rx_pkt_info,
1026 		   struct pe_session *session)
1027 {
1028 	static tSchBeaconStruct bcn;
1029 
1030 	if (!session)
1031 		return;
1032 
1033 	/*
1034 	 * Drop the beacon/probe response from current connected AP in
1035 	 * below cases to avoid responding to the changes in beacon(e.g. doing
1036 	 * VDEV_RESTART to update to the latest capabilities),
1037 	 * 1. vdev is not in connected state: vdev might be transitioning
1038 	 * 2. Link switch is in progress: Current link or one of the partner
1039 	 *                                links are getting replaced.
1040 	 *
1041 	 * New beacons/probe rsps can be considered once post these operations.
1042 	 */
1043 	if (LIM_IS_STA_ROLE(session) &&
1044 	    (!wlan_cm_is_vdev_connected(session->vdev) ||
1045 	     mlo_mgr_is_link_switch_in_progress(session->vdev))) {
1046 		pe_debug_rl("vdev %d, drop beacon", session->vdev_id);
1047 		return;
1048 	}
1049 
1050 	/* Convert the beacon frame into a structure */
1051 	if (sir_convert_beacon_frame2_struct(mac_ctx, (uint8_t *) rx_pkt_info,
1052 		&bcn) != QDF_STATUS_SUCCESS) {
1053 		pe_err_rl("beacon parsing failed");
1054 		return;
1055 	}
1056 
1057 	session->dtimPeriod = bcn.tim.dtimPeriod;
1058 
1059 	sch_send_beacon_report(mac_ctx, &bcn, session);
1060 	__sch_beacon_process_for_session(mac_ctx, &bcn, rx_pkt_info, session);
1061 }
1062 
1063 /**
1064  * sch_beacon_edca_process(): Process the EDCA parameter set in the received
1065  * beacon frame
1066  *
1067  * @mac_ctx:    mac global context
1068  * @edca:       reference to edca parameters in beacon struct
1069  * @session :   pesession entry
1070  *
1071  * @return status of operation
1072  */
1073 QDF_STATUS
1074 sch_beacon_edca_process(struct mac_context *mac, tSirMacEdcaParamSetIE *edca,
1075 			struct pe_session *session)
1076 {
1077 	bool follow_ap_edca;
1078 #ifdef FEATURE_WLAN_DIAG_SUPPORT
1079 	host_log_qos_edca_pkt_type *log_ptr = NULL;
1080 #endif /* FEATURE_WLAN_DIAG_SUPPORT */
1081 
1082 	if (!(mac->mlme_cfg)) {
1083 		pe_err("invalid mlme cfg");
1084 		return QDF_STATUS_E_FAILURE;
1085 	}
1086 
1087 	follow_ap_edca = mlme_get_follow_ap_edca_flag(session->vdev);
1088 
1089 	session->gLimEdcaParamSetCount = edca->qosInfo.count;
1090 	session->gLimEdcaParams[QCA_WLAN_AC_BE] = edca->acbe;
1091 	session->gLimEdcaParams[QCA_WLAN_AC_BK] = edca->acbk;
1092 	session->gLimEdcaParams[QCA_WLAN_AC_VI] = edca->acvi;
1093 	session->gLimEdcaParams[QCA_WLAN_AC_VO] = edca->acvo;
1094 
1095 	if (mac->mlme_cfg->edca_params.enable_edca_params && !follow_ap_edca) {
1096 		session->gLimEdcaParams[QCA_WLAN_AC_VO].aci.aifsn =
1097 			mac->mlme_cfg->edca_params.edca_ac_vo.vo_aifs;
1098 		session->gLimEdcaParams[QCA_WLAN_AC_VI].aci.aifsn =
1099 			mac->mlme_cfg->edca_params.edca_ac_vi.vi_aifs;
1100 		session->gLimEdcaParams[QCA_WLAN_AC_BK].aci.aifsn =
1101 			mac->mlme_cfg->edca_params.edca_ac_bk.bk_aifs;
1102 		session->gLimEdcaParams[QCA_WLAN_AC_BE].aci.aifsn =
1103 			mac->mlme_cfg->edca_params.edca_ac_be.be_aifs;
1104 
1105 		session->gLimEdcaParams[QCA_WLAN_AC_VO].cw.min =
1106 			mac->mlme_cfg->edca_params.edca_ac_vo.vo_cwmin;
1107 		session->gLimEdcaParams[QCA_WLAN_AC_VI].cw.min =
1108 			mac->mlme_cfg->edca_params.edca_ac_vi.vi_cwmin;
1109 		session->gLimEdcaParams[QCA_WLAN_AC_BK].cw.min =
1110 			mac->mlme_cfg->edca_params.edca_ac_bk.bk_cwmin;
1111 		session->gLimEdcaParams[QCA_WLAN_AC_BE].cw.min =
1112 			mac->mlme_cfg->edca_params.edca_ac_be.be_cwmin;
1113 
1114 		session->gLimEdcaParams[QCA_WLAN_AC_VO].cw.max =
1115 			mac->mlme_cfg->edca_params.edca_ac_vo.vo_cwmax;
1116 		session->gLimEdcaParams[QCA_WLAN_AC_VI].cw.max =
1117 			mac->mlme_cfg->edca_params.edca_ac_vi.vi_cwmax;
1118 		session->gLimEdcaParams[QCA_WLAN_AC_BK].cw.max =
1119 			mac->mlme_cfg->edca_params.edca_ac_bk.bk_cwmax;
1120 		session->gLimEdcaParams[QCA_WLAN_AC_BE].cw.max =
1121 			mac->mlme_cfg->edca_params.edca_ac_be.be_cwmax;
1122 	}
1123 #ifdef FEATURE_WLAN_DIAG_SUPPORT
1124 	WLAN_HOST_DIAG_LOG_ALLOC(log_ptr, host_log_qos_edca_pkt_type,
1125 				 LOG_WLAN_QOS_EDCA_C);
1126 	if (log_ptr) {
1127 		log_ptr->aci_be = session->gLimEdcaParams[QCA_WLAN_AC_BE].aci.aci;
1128 		log_ptr->cw_be =
1129 			session->gLimEdcaParams[QCA_WLAN_AC_BE].cw.max << 4
1130 				| session->gLimEdcaParams[QCA_WLAN_AC_BE].cw.min;
1131 		log_ptr->txoplimit_be =
1132 			session->gLimEdcaParams[QCA_WLAN_AC_BE].txoplimit;
1133 		log_ptr->aci_bk =
1134 			session->gLimEdcaParams[QCA_WLAN_AC_BK].aci.aci;
1135 		log_ptr->cw_bk =
1136 			session->gLimEdcaParams[QCA_WLAN_AC_BK].cw.max << 4
1137 				| session->gLimEdcaParams[QCA_WLAN_AC_BK].cw.min;
1138 		log_ptr->txoplimit_bk =
1139 			session->gLimEdcaParams[QCA_WLAN_AC_BK].txoplimit;
1140 		log_ptr->aci_vi =
1141 			session->gLimEdcaParams[QCA_WLAN_AC_VI].aci.aci;
1142 		log_ptr->cw_vi =
1143 			session->gLimEdcaParams[QCA_WLAN_AC_VI].cw.max << 4
1144 				| session->gLimEdcaParams[QCA_WLAN_AC_VI].cw.min;
1145 		log_ptr->txoplimit_vi =
1146 			session->gLimEdcaParams[QCA_WLAN_AC_VI].txoplimit;
1147 		log_ptr->aci_vo =
1148 			session->gLimEdcaParams[QCA_WLAN_AC_VO].aci.aci;
1149 		log_ptr->cw_vo =
1150 			session->gLimEdcaParams[QCA_WLAN_AC_VO].cw.max << 4
1151 				| session->gLimEdcaParams[QCA_WLAN_AC_VO].cw.min;
1152 		log_ptr->txoplimit_vo =
1153 			session->gLimEdcaParams[QCA_WLAN_AC_VO].txoplimit;
1154 	}
1155 	WLAN_HOST_DIAG_LOG_REPORT(log_ptr);
1156 #endif /* FEATURE_WLAN_DIAG_SUPPORT */
1157 	pe_debug("Edca param enabled %d. Updating Local Params to: AC_BE: AIFSN: %d, ACM %d, CWmin %d, CWmax %d, TxOp %d  AC_BK: AIFSN: %d, ACM %d, CWmin %d, CWmax %d, TxOp %d  AC_VI: AIFSN: %d, ACM %d, CWmin %d, CWmax %d, TxOp %d  AC_VO: AIFSN: %d, ACM %d, CWmin %d, CWmax %d, TxOp %d",
1158 		 mac->mlme_cfg->edca_params.enable_edca_params,
1159 		 session->gLimEdcaParams[0].aci.aifsn,
1160 		 session->gLimEdcaParams[0].aci.acm,
1161 		 session->gLimEdcaParams[0].cw.min,
1162 		 session->gLimEdcaParams[0].cw.max,
1163 		 session->gLimEdcaParams[0].txoplimit,
1164 		 session->gLimEdcaParams[1].aci.aifsn,
1165 		 session->gLimEdcaParams[1].aci.acm,
1166 		 session->gLimEdcaParams[1].cw.min,
1167 		 session->gLimEdcaParams[1].cw.max,
1168 		 session->gLimEdcaParams[1].txoplimit,
1169 		 session->gLimEdcaParams[2].aci.aifsn,
1170 		 session->gLimEdcaParams[2].aci.acm,
1171 		 session->gLimEdcaParams[2].cw.min,
1172 		 session->gLimEdcaParams[2].cw.max,
1173 		 session->gLimEdcaParams[2].txoplimit,
1174 		 session->gLimEdcaParams[3].aci.aifsn,
1175 		 session->gLimEdcaParams[3].aci.acm,
1176 		 session->gLimEdcaParams[3].cw.min,
1177 		 session->gLimEdcaParams[3].cw.max,
1178 		 session->gLimEdcaParams[3].txoplimit);
1179 
1180 	return QDF_STATUS_SUCCESS;
1181 }
1182 
1183 void lim_enable_obss_detection_config(struct mac_context *mac_ctx,
1184 				      struct pe_session *session)
1185 {
1186 	QDF_STATUS status = QDF_STATUS_SUCCESS;
1187 
1188 	if (!session) {
1189 		pe_err("Invalid session, protection not enabled");
1190 		return;
1191 	}
1192 
1193 	if (session->gLimProtectionControl ==
1194 	    MLME_FORCE_POLICY_PROTECTION_DISABLE) {
1195 		pe_err("protectiond disabled, force policy, session %d",
1196 		       session->smeSessionId);
1197 		return;
1198 	}
1199 
1200 	if (mac_ctx->mlme_cfg->obss_ht40.obss_detection_offload_enabled) {
1201 		status = lim_obss_send_detection_cfg(mac_ctx, session, true);
1202 		if (QDF_IS_STATUS_ERROR(status)) {
1203 			pe_err("vdev %d: offload enable failed, trying legacy",
1204 			       session->smeSessionId);
1205 			session->is_session_obss_offload_enabled = false;
1206 		} else {
1207 			pe_debug("vdev %d: offload detection enabled",
1208 				 session->smeSessionId);
1209 			session->is_session_obss_offload_enabled = true;
1210 			lim_obss_send_detection_cfg(mac_ctx, session, true);
1211 		}
1212 	}
1213 
1214 	if (!mac_ctx->mlme_cfg->obss_ht40.obss_detection_offload_enabled ||
1215 	    QDF_IS_STATUS_ERROR(status)) {
1216 		status = qdf_mc_timer_start(&session->
1217 					    protection_fields_reset_timer,
1218 					    SCH_PROTECTION_RESET_TIME);
1219 		if (QDF_IS_STATUS_ERROR(status))
1220 			pe_err("vdev %d: start timer failed",
1221 			       session->smeSessionId);
1222 		else
1223 			pe_debug("vdev %d: legacy detection enabled",
1224 				 session->smeSessionId);
1225 	}
1226 }
1227 
1228 QDF_STATUS lim_obss_generate_detection_config(struct mac_context *mac_ctx,
1229 					      struct pe_session *session,
1230 					      struct obss_detection_cfg *cfg)
1231 {
1232 	uint32_t phy_mode;
1233 	enum reg_wifi_band rf_band = REG_BAND_UNKNOWN;
1234 	struct obss_detection_cfg *cur_detect;
1235 
1236 	if (!mac_ctx || !session || !cfg) {
1237 		pe_err("Invalid params mac_ctx %pK, session %pK, cfg %pK",
1238 			mac_ctx, session, cfg);
1239 		return QDF_STATUS_E_INVAL;
1240 	}
1241 
1242 	lim_get_phy_mode(mac_ctx, &phy_mode, session);
1243 	rf_band = session->limRFBand;
1244 	qdf_mem_zero(cfg, sizeof(*cfg));
1245 	cur_detect = &session->current_obss_detection;
1246 
1247 	pe_debug("band:%d, phy_mode:%d, ht_cap:%d, ht_oper_mode:%d",
1248 		 rf_band, phy_mode, session->htCapability,
1249 		 mac_ctx->lim.gHTOperMode);
1250 	pe_debug("assoc_sta: 11b:%d, 11g:%d, 11a:%d, ht20:%d",
1251 		 session->gLim11bParams.protectionEnabled,
1252 		 session->gLim11gParams.protectionEnabled,
1253 		 session->gLim11aParams.protectionEnabled,
1254 		 session->gLimHt20Params.protectionEnabled);
1255 	pe_debug("obss: 11b:%d, 11g:%d, 11a:%d, ht20:%d",
1256 		 session->gLimOlbcParams.protectionEnabled,
1257 		 session->gLimOverlap11gParams.protectionEnabled,
1258 		 session->gLimOverlap11aParams.protectionEnabled,
1259 		 session->gLimOverlapHt20Params.protectionEnabled);
1260 	pe_debug("detect: b_ap:%d, b_s:%d, g:%d, a:%d, htl:%d, htm:%d, ht20:%d",
1261 		 cur_detect->obss_11b_ap_detect_mode,
1262 		 cur_detect->obss_11b_sta_detect_mode,
1263 		 cur_detect->obss_11g_ap_detect_mode,
1264 		 cur_detect->obss_11a_detect_mode,
1265 		 cur_detect->obss_ht_legacy_detect_mode,
1266 		 cur_detect->obss_ht_mixed_detect_mode,
1267 		 cur_detect->obss_ht_20mhz_detect_mode);
1268 
1269 	if (rf_band == REG_BAND_2G) {
1270 		if ((phy_mode == WNI_CFG_PHY_MODE_11G ||
1271 		    session->htCapability) &&
1272 		    !session->gLim11bParams.protectionEnabled) {
1273 			if (!session->gLimOlbcParams.protectionEnabled &&
1274 			    !session->gLimOverlap11gParams.protectionEnabled) {
1275 				cfg->obss_11b_ap_detect_mode =
1276 					OBSS_OFFLOAD_DETECTION_PRESENT;
1277 				cfg->obss_11b_sta_detect_mode =
1278 					OBSS_OFFLOAD_DETECTION_PRESENT;
1279 			} else {
1280 				if (cur_detect->obss_11b_ap_detect_mode ==
1281 				    OBSS_OFFLOAD_DETECTION_PRESENT)
1282 					cfg->obss_11b_ap_detect_mode =
1283 						OBSS_OFFLOAD_DETECTION_ABSENT;
1284 				if (cur_detect->obss_11b_sta_detect_mode ==
1285 				    OBSS_OFFLOAD_DETECTION_PRESENT)
1286 					cfg->obss_11b_sta_detect_mode =
1287 						OBSS_OFFLOAD_DETECTION_ABSENT;
1288 			}
1289 		} else if (session->gLim11bParams.protectionEnabled) {
1290 			session->gLimOlbcParams.protectionEnabled = false;
1291 		}
1292 
1293 		if (session->htCapability &&
1294 		    session->cfgProtection.overlapFromllg &&
1295 		    !session->gLim11gParams.protectionEnabled) {
1296 			if (!session->gLimOverlap11gParams.protectionEnabled) {
1297 				cfg->obss_11g_ap_detect_mode =
1298 					OBSS_OFFLOAD_DETECTION_PRESENT;
1299 				cfg->obss_ht_legacy_detect_mode =
1300 					OBSS_OFFLOAD_DETECTION_PRESENT;
1301 				cfg->obss_ht_mixed_detect_mode =
1302 					OBSS_OFFLOAD_DETECTION_PRESENT;
1303 			} else {
1304 				if (cur_detect->obss_11g_ap_detect_mode ==
1305 				    OBSS_OFFLOAD_DETECTION_PRESENT)
1306 					cfg->obss_11g_ap_detect_mode =
1307 						OBSS_OFFLOAD_DETECTION_ABSENT;
1308 				if (cur_detect->obss_ht_legacy_detect_mode ==
1309 				    OBSS_OFFLOAD_DETECTION_PRESENT)
1310 					cfg->obss_ht_legacy_detect_mode =
1311 						OBSS_OFFLOAD_DETECTION_ABSENT;
1312 				if (cur_detect->obss_ht_mixed_detect_mode ==
1313 				    OBSS_OFFLOAD_DETECTION_PRESENT)
1314 					cfg->obss_ht_mixed_detect_mode =
1315 						OBSS_OFFLOAD_DETECTION_ABSENT;
1316 			}
1317 		} else if (session->gLim11gParams.protectionEnabled) {
1318 			session->gLimOverlap11gParams.protectionEnabled = false;
1319 		}
1320 
1321 		/* INI related settings */
1322 		if (mac_ctx->mlme_cfg->sta.ignore_peer_erp_info)
1323 			cfg->obss_11b_sta_detect_mode =
1324 				OBSS_OFFLOAD_DETECTION_DISABLED;
1325 
1326 		if (mac_ctx->mlme_cfg->sap_protection_cfg.ignore_peer_ht_opmode)
1327 			cfg->obss_ht_legacy_detect_mode =
1328 				OBSS_OFFLOAD_DETECTION_DISABLED;
1329 	}
1330 
1331 	if ((rf_band == REG_BAND_5G) && session->htCapability) {
1332 		if (!session->gLim11aParams.protectionEnabled) {
1333 			if (!session->gLimOverlap11aParams.protectionEnabled)
1334 				cfg->obss_11a_detect_mode =
1335 					OBSS_OFFLOAD_DETECTION_PRESENT;
1336 			else if (cur_detect->obss_11a_detect_mode ==
1337 				 OBSS_OFFLOAD_DETECTION_PRESENT)
1338 					cfg->obss_11a_detect_mode =
1339 						OBSS_OFFLOAD_DETECTION_ABSENT;
1340 		} else {
1341 			session->gLimOverlap11aParams.protectionEnabled = false;
1342 		}
1343 	}
1344 
1345 	if (((rf_band == REG_BAND_2G) || (rf_band == REG_BAND_5G)) &&
1346 	    session->htCapability) {
1347 
1348 		if (!session->gLimHt20Params.protectionEnabled) {
1349 			if (!session->gLimOverlapHt20Params.protectionEnabled) {
1350 				cfg->obss_ht_20mhz_detect_mode =
1351 					OBSS_OFFLOAD_DETECTION_PRESENT;
1352 			} else if (cur_detect->obss_ht_20mhz_detect_mode ==
1353 				   OBSS_OFFLOAD_DETECTION_PRESENT) {
1354 					cfg->obss_ht_20mhz_detect_mode =
1355 					OBSS_OFFLOAD_DETECTION_ABSENT;
1356 			}
1357 		} else {
1358 			session->gLimOverlapHt20Params.protectionEnabled =
1359 				false;
1360 		}
1361 	}
1362 
1363 	pe_debug("b_ap:%d, b_s:%d, g:%d, a:%d, ht_le:%d, ht_m:%d, ht_20:%d",
1364 		 cfg->obss_11b_ap_detect_mode,
1365 		 cfg->obss_11b_sta_detect_mode,
1366 		 cfg->obss_11g_ap_detect_mode,
1367 		 cfg->obss_11a_detect_mode,
1368 		 cfg->obss_ht_legacy_detect_mode,
1369 		 cfg->obss_ht_mixed_detect_mode,
1370 		 cfg->obss_ht_20mhz_detect_mode);
1371 
1372 	return QDF_STATUS_SUCCESS;
1373 }
1374 
1375 QDF_STATUS lim_obss_send_detection_cfg(struct mac_context *mac_ctx,
1376 				       struct pe_session *session, bool force)
1377 {
1378 	QDF_STATUS status;
1379 	struct obss_detection_cfg obss_cfg;
1380 	struct wmi_obss_detection_cfg_param *req_param;
1381 
1382 	if (!session) {
1383 		pe_err("Invalid session");
1384 		return QDF_STATUS_E_INVAL;
1385 	}
1386 
1387 	if (!session->is_session_obss_offload_enabled) {
1388 		pe_debug("obss offload protectiond disabled, session %d",
1389 		       session->smeSessionId);
1390 		/* Send success */
1391 		return QDF_STATUS_SUCCESS;
1392 	}
1393 
1394 	if (session->gLimProtectionControl ==
1395 	    MLME_FORCE_POLICY_PROTECTION_DISABLE) {
1396 		pe_debug("protectiond disabled, force from policy, session %d",
1397 		       session->smeSessionId);
1398 		/* Send success */
1399 		return QDF_STATUS_SUCCESS;
1400 	}
1401 
1402 	status = lim_obss_generate_detection_config(mac_ctx,
1403 						    session,
1404 						    &obss_cfg);
1405 	if (QDF_IS_STATUS_ERROR(status)) {
1406 		pe_err("Failed to generate obss detection cfg, session %d",
1407 		       session->smeSessionId);
1408 		return status;
1409 	}
1410 
1411 	if (qdf_mem_cmp(&session->obss_offload_cfg, &obss_cfg, sizeof(obss_cfg))
1412 	    || force) {
1413 		struct scheduler_msg msg = {0};
1414 		req_param = qdf_mem_malloc(sizeof(*req_param));
1415 		if (!req_param)
1416 			return QDF_STATUS_E_NOMEM;
1417 		qdf_mem_copy(&session->obss_offload_cfg, &obss_cfg,
1418 				sizeof(obss_cfg));
1419 		req_param->vdev_id = session->smeSessionId;
1420 		req_param->obss_detect_period_ms = OBSS_DETECTION_PERIOD_MS;
1421 		req_param->obss_11b_ap_detect_mode =
1422 			obss_cfg.obss_11b_ap_detect_mode;
1423 		req_param->obss_11b_sta_detect_mode =
1424 			obss_cfg.obss_11b_sta_detect_mode;
1425 		req_param->obss_11g_ap_detect_mode =
1426 			obss_cfg.obss_11g_ap_detect_mode;
1427 		req_param->obss_11a_detect_mode =
1428 			obss_cfg.obss_11a_detect_mode;
1429 		req_param->obss_ht_legacy_detect_mode =
1430 			obss_cfg.obss_ht_legacy_detect_mode;
1431 		req_param->obss_ht_20mhz_detect_mode =
1432 			obss_cfg.obss_ht_20mhz_detect_mode;
1433 		req_param->obss_ht_mixed_detect_mode =
1434 			obss_cfg.obss_ht_mixed_detect_mode;
1435 
1436 		msg.type = WMA_OBSS_DETECTION_REQ;
1437 		msg.bodyptr = req_param;
1438 		msg.reserved = 0;
1439 		status = scheduler_post_message(QDF_MODULE_ID_PE,
1440 						QDF_MODULE_ID_WMA,
1441 						QDF_MODULE_ID_WMA, &msg);
1442 		if (QDF_IS_STATUS_ERROR(status)) {
1443 			qdf_mem_free(req_param);
1444 			return status;
1445 		}
1446 	} else {
1447 		pe_debug("Skipping WMA_OBSS_DETECTION_REQ, force = %d", force);
1448 	}
1449 
1450 	return status;
1451 }
1452 
1453 QDF_STATUS lim_process_obss_detection_ind(struct mac_context *mac_ctx,
1454 					  struct wmi_obss_detect_info
1455 					  *obss_detection)
1456 {
1457 	QDF_STATUS status;
1458 	uint32_t detect_masks;
1459 	uint32_t reason;
1460 	struct obss_detection_cfg *obss_cfg;
1461 	bool enable;
1462 	struct pe_session *session;
1463 	tUpdateBeaconParams bcn_prm;
1464 	enum reg_wifi_band rf_band = REG_BAND_UNKNOWN;
1465 	struct obss_detection_cfg *cur_detect;
1466 
1467 	pe_debug("obss detect ind id %d, reason %d, msk 0x%x, " QDF_MAC_ADDR_FMT,
1468 		 obss_detection->vdev_id, obss_detection->reason,
1469 		 obss_detection->matched_detection_masks,
1470 		 QDF_MAC_ADDR_REF(obss_detection->matched_bssid_addr));
1471 
1472 	session = pe_find_session_by_vdev_id(mac_ctx, obss_detection->vdev_id);
1473 	if (!session) {
1474 		pe_err("Failed to get session for id %d",
1475 		       obss_detection->vdev_id);
1476 		return QDF_STATUS_E_INVAL;
1477 	}
1478 
1479 	if (!LIM_IS_AP_ROLE(session)) {
1480 		pe_err("session %d is not AP", obss_detection->vdev_id);
1481 		return QDF_STATUS_E_INVAL;
1482 	}
1483 
1484 	if (!session->is_session_obss_offload_enabled) {
1485 		pe_err("Offload already disabled for session %d",
1486 		       obss_detection->vdev_id);
1487 		return QDF_STATUS_SUCCESS;
1488 	}
1489 
1490 	reason = obss_detection->reason;
1491 	detect_masks = obss_detection->matched_detection_masks;
1492 
1493 	if (reason == OBSS_OFFLOAD_DETECTION_PRESENT) {
1494 		enable = true;
1495 	} else if (reason == OBSS_OFFLOAD_DETECTION_ABSENT) {
1496 		enable = false;
1497 	} else if (reason == OBSS_OFFLOAD_DETECTION_DISABLED) {
1498 		/*
1499 		 * Most common reason for this event-type from firmware
1500 		 * is insufficient memory.
1501 		 * Disable offload OBSS detection and enable legacy-way
1502 		 * of detecting OBSS by parsing beacons.
1503 		 **/
1504 		session->is_session_obss_offload_enabled = false;
1505 		pe_err("FW indicated obss offload disabled");
1506 		pe_err("Enabling host based detection, session %d",
1507 		       obss_detection->vdev_id);
1508 
1509 		status = qdf_mc_timer_start(&session->
1510 					    protection_fields_reset_timer,
1511 					    SCH_PROTECTION_RESET_TIME);
1512 		if (QDF_IS_STATUS_ERROR(status))
1513 			pe_err("cannot start protection reset timer");
1514 
1515 		return QDF_STATUS_SUCCESS;
1516 	} else {
1517 		pe_err("Invalid reason %d, session %d",
1518 		       obss_detection->reason,
1519 		       obss_detection->vdev_id);
1520 		return QDF_STATUS_E_INVAL;
1521 	}
1522 
1523 	rf_band = session->limRFBand;
1524 	qdf_mem_zero(&bcn_prm, sizeof(bcn_prm));
1525 	obss_cfg = &session->obss_offload_cfg;
1526 	cur_detect = &session->current_obss_detection;
1527 
1528 	if (OBSS_DETECTION_IS_11B_AP(detect_masks)) {
1529 		if (reason != obss_cfg->obss_11b_ap_detect_mode ||
1530 		    rf_band != REG_BAND_2G)
1531 			goto wrong_detection;
1532 
1533 		lim_enable11g_protection(mac_ctx, enable, true,
1534 					 &bcn_prm, session);
1535 		cur_detect->obss_11b_ap_detect_mode = reason;
1536 	}
1537 	if (OBSS_DETECTION_IS_11B_STA(detect_masks)) {
1538 		if (reason != obss_cfg->obss_11b_sta_detect_mode ||
1539 		    rf_band != REG_BAND_2G)
1540 			goto wrong_detection;
1541 
1542 		lim_enable11g_protection(mac_ctx, enable, true,
1543 					 &bcn_prm, session);
1544 		cur_detect->obss_11b_sta_detect_mode = reason;
1545 	}
1546 	if (OBSS_DETECTION_IS_11G_AP(detect_masks)) {
1547 		if (reason != obss_cfg->obss_11g_ap_detect_mode ||
1548 		    rf_band != REG_BAND_2G)
1549 			goto wrong_detection;
1550 
1551 		lim_enable_ht_protection_from11g(mac_ctx, enable, true,
1552 						 &bcn_prm, session);
1553 		cur_detect->obss_11g_ap_detect_mode = reason;
1554 	}
1555 	if (OBSS_DETECTION_IS_11A(detect_masks)) {
1556 		if (reason != obss_cfg->obss_11a_detect_mode ||
1557 		    rf_band != REG_BAND_5G)
1558 			goto wrong_detection;
1559 
1560 		lim_update_11a_protection(mac_ctx, enable, true,
1561 					  &bcn_prm, session);
1562 		cur_detect->obss_11a_detect_mode = reason;
1563 	}
1564 	if (OBSS_DETECTION_IS_HT_LEGACY(detect_masks)) {
1565 		/* for 5GHz, we have only 11a detection, which covers legacy */
1566 		if (reason != obss_cfg->obss_ht_legacy_detect_mode ||
1567 		    rf_band != REG_BAND_2G)
1568 			goto wrong_detection;
1569 
1570 		lim_enable_ht_protection_from11g(mac_ctx, enable, true,
1571 						 &bcn_prm, session);
1572 		cur_detect->obss_ht_legacy_detect_mode = reason;
1573 	}
1574 	if (OBSS_DETECTION_IS_HT_MIXED(detect_masks)) {
1575 		/* for 5GHz, we have only 11a detection, which covers ht mix */
1576 		if (reason != obss_cfg->obss_ht_mixed_detect_mode ||
1577 		    rf_band != REG_BAND_2G)
1578 			goto wrong_detection;
1579 
1580 		lim_enable_ht_protection_from11g(mac_ctx, enable, true,
1581 						 &bcn_prm, session);
1582 		cur_detect->obss_ht_mixed_detect_mode = reason;
1583 	}
1584 	if (OBSS_DETECTION_IS_HT_20MHZ(detect_masks)) {
1585 		if (reason != obss_cfg->obss_ht_20mhz_detect_mode)
1586 			goto wrong_detection;
1587 
1588 		lim_enable_ht20_protection(mac_ctx, enable, true,
1589 					   &bcn_prm, session);
1590 		cur_detect->obss_ht_20mhz_detect_mode = reason;
1591 	}
1592 
1593 	if ((false == mac_ctx->sap.SapDfsInfo.is_dfs_cac_timer_running) &&
1594 	    bcn_prm.paramChangeBitmap) {
1595 		/* Update the bcn and apply the new settings to HAL */
1596 		sch_set_fixed_beacon_fields(mac_ctx, session);
1597 		pe_debug("Beacon for PE session: %d got changed: 0x%x",
1598 			 session->smeSessionId, bcn_prm.paramChangeBitmap);
1599 		if (!QDF_IS_STATUS_SUCCESS(lim_send_beacon_params(
1600 		     mac_ctx, &bcn_prm, session))) {
1601 			pe_err("Failed to send beacon param, session %d",
1602 				obss_detection->vdev_id);
1603 			return QDF_STATUS_E_FAULT;
1604 		}
1605 	}
1606 
1607 	status = lim_obss_send_detection_cfg(mac_ctx, session, true);
1608 	if (QDF_IS_STATUS_ERROR(status)) {
1609 		pe_err("Failed to send obss detection cfg, session %d",
1610 			obss_detection->vdev_id);
1611 		return status;
1612 	}
1613 
1614 	return QDF_STATUS_SUCCESS;
1615 
1616 wrong_detection:
1617 	/*
1618 	 * We may get this wrong detection before FW can update latest cfg,
1619 	 * So keeping log level debug
1620 	 **/
1621 	pe_debug("Wrong detection, session %d", obss_detection->vdev_id);
1622 
1623 	return QDF_STATUS_E_INVAL;
1624 }
1625