xref: /wlan-dirver/qcacld-3.0/core/mac/src/pe/sch/sch_beacon_process.c (revision 1ed9249cd9445fcc8a5eabed8f545e03248cddb1)
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 	int8_t regMax = 0, maxTxPower = 0;
606 	QDF_STATUS status;
607 	bool skip_tpe = false, is_sap_go_switched_ch;
608 	enum reg_6g_ap_type pwr_type_6g;
609 	uint8_t bpcc;
610 	bool cu_flag = true;
611 	bool is_power_constraint_abs = false;
612 
613 	if (mlo_is_mld_sta(session->vdev)) {
614 		cu_flag = false;
615 		status = lim_get_bpcc_from_mlo_ie(bcn, &bpcc);
616 		if (QDF_IS_STATUS_SUCCESS(status))
617 			cu_flag = lim_check_cu_happens(session->vdev, bpcc);
618 		lim_process_ml_reconfig(mac_ctx, session, rx_pkt_info);
619 	}
620 
621 	if (!cu_flag)
622 		return;
623 
624 	qdf_mem_zero(&beaconParams, sizeof(tUpdateBeaconParams));
625 	beaconParams.paramChangeBitmap = 0;
626 
627 	if (LIM_IS_STA_ROLE(session)) {
628 		is_sap_go_switched_ch =
629 			wlan_vdev_mlme_is_sap_go_move_before_sta(session->vdev);
630 		if (is_sap_go_switched_ch)
631 			policy_mgr_sta_sap_dfs_enforce_scc(mac_ctx->psoc,
632 							   session->vdev_id);
633 		if (false == sch_bcn_process_sta(mac_ctx, bcn, rx_pkt_info,
634 						 session, &beaconParams,
635 						 &sendProbeReq, pMh))
636 			return;
637 	}
638 
639 	/*
640 	 * For vht session, if opermode ie or vht oper IE is present
641 	 * bandwidth change will be taken care using these vht IEs.
642 	 */
643 	if (!(session->vhtCapability && (bcn->OperatingMode.present ||
644 	   bcn->VHTOperation.present)) && session->htCapability &&
645 	   bcn->HTInfo.present)
646 		lim_update_sta_run_time_ht_switch_chnl_params(mac_ctx,
647 						&bcn->HTInfo, session);
648 
649 	if (LIM_IS_STA_ROLE(session))
650 		sch_bcn_process_sta_opmode(mac_ctx, bcn, rx_pkt_info, session,
651 					    &beaconParams, &sendProbeReq, pMh);
652 
653 	mlme_obj = wlan_vdev_mlme_get_cmpt_obj(session->vdev);
654 	if (!mlme_obj) {
655 		pe_err("vdev component object is NULL");
656 		return;
657 	}
658 
659 	if (!wlan_reg_is_6ghz_chan_freq(bcn->chan_freq)) {
660 		skip_tpe = wlan_mlme_skip_tpe(mac_ctx->psoc);
661 	} else {
662 		if (!bcn->countryInfoParam.countryString[0]) {
663 			pe_err("Channel is 6G but country IE not present");
664 			return;
665 		}
666 		if (bcn->he_op.oper_info_6g_present) {
667 			session->ap_defined_power_type_6g =
668 					bcn->he_op.oper_info_6g.info.reg_info;
669 			if (session->ap_defined_power_type_6g < REG_INDOOR_AP ||
670 			    session->ap_defined_power_type_6g >
671 			    REG_MAX_SUPP_AP_TYPE) {
672 				session->ap_defined_power_type_6g =
673 						REG_CURRENT_MAX_AP_TYPE;
674 				pe_debug("AP power type is invalid, defaulting to MAX_AP_TYPE");
675 			}
676 		} else {
677 			pe_debug("AP power type is null, defaulting to MAX_AP_TYPE");
678 			session->ap_defined_power_type_6g =
679 						REG_CURRENT_MAX_AP_TYPE;
680 		}
681 
682 		status = wlan_reg_get_best_6g_power_type(
683 				mac_ctx->psoc, mac_ctx->pdev, &pwr_type_6g,
684 				session->ap_defined_power_type_6g,
685 				bcn->chan_freq);
686 		if (QDF_IS_STATUS_ERROR(status))
687 			return;
688 
689 		session->best_6g_power_type = pwr_type_6g;
690 		mlme_set_best_6g_power_type(session->vdev, pwr_type_6g);
691 	}
692 
693 	/*
694 	 * STA LPI + SAP VLP is supported. For this STA should operate in VLP
695 	 * power level of the SAP.
696 	 * If STA is operating in VLP power of SAP, do not update STA power.
697 	 */
698 	if (wlan_reg_is_ext_tpc_supported(mac_ctx->psoc) &&
699 	    !session->sta_follows_sap_power) {
700 		tx_ops = wlan_reg_get_tx_ops(mac_ctx->psoc);
701 
702 		lim_parse_tpe_ie(mac_ctx, session, bcn->transmit_power_env,
703 				 bcn->num_transmit_power_env, &bcn->he_op,
704 				 &tpe_change);
705 
706 		if (mac_ctx->mlme_cfg->sta.allow_tpc_from_ap) {
707 			get_local_power_constraint_beacon(
708 						bcn, &local_constraint,
709 						&is_power_constraint_abs);
710 
711 			if (mac_ctx->rrm.rrmPEContext.rrmEnable &&
712 			    bcn->powerConstraintPresent) {
713 				local_constraint =
714 				bcn->localPowerConstraint.localPowerConstraints;
715 				is_power_constraint_abs = false;
716 			}
717 		}
718 
719 		if (local_constraint !=
720 				mlme_obj->reg_tpc_obj.ap_constraint_power) {
721 			mlme_obj->reg_tpc_obj.ap_constraint_power =
722 							local_constraint;
723 			mlme_obj->reg_tpc_obj.is_power_constraint_abs =
724 							is_power_constraint_abs;
725 			ap_constraint_change = true;
726 		}
727 
728 		if ((ap_constraint_change && local_constraint) ||
729 		    (tpe_change && !skip_tpe)) {
730 			lim_calculate_tpc(mac_ctx, session);
731 
732 			if (tx_ops->set_tpc_power)
733 				tx_ops->set_tpc_power(mac_ctx->psoc,
734 						      session->vdev_id,
735 						      &mlme_obj->reg_tpc_obj);
736 			}
737 	} else if (!session->sta_follows_sap_power) {
738 		/* Obtain the Max Tx power for the current regulatory  */
739 		regMax = wlan_reg_get_channel_reg_power_for_freq(
740 					mac_ctx->pdev, session->curr_op_freq);
741 		local_constraint = regMax;
742 
743 		if (mac_ctx->mlme_cfg->sta.allow_tpc_from_ap) {
744 			get_local_power_constraint_beacon(
745 						bcn, &local_constraint,
746 						&is_power_constraint_abs);
747 
748 			if (mac_ctx->rrm.rrmPEContext.rrmEnable &&
749 			    bcn->powerConstraintPresent) {
750 				local_constraint = regMax;
751 				local_constraint -=
752 				bcn->localPowerConstraint.localPowerConstraints;
753 				is_power_constraint_abs = false;
754 
755 			}
756 		}
757 		mlme_obj->reg_tpc_obj.is_power_constraint_abs =
758 						is_power_constraint_abs;
759 		mlme_obj->reg_tpc_obj.reg_max[0] = regMax;
760 		mlme_obj->reg_tpc_obj.ap_constraint_power = local_constraint;
761 		mlme_obj->reg_tpc_obj.frequency[0] = session->curr_op_freq;
762 
763 		maxTxPower = lim_get_max_tx_power(mac_ctx, mlme_obj);
764 
765 		/* If maxTxPower is increased or decreased */
766 		if (maxTxPower != session->maxTxPower) {
767 			pe_debug("New maxTx power %d, old pwr %d",
768 				 maxTxPower, session->maxTxPower);
769 			pe_debug("regMax %d, local %d", regMax,
770 				 local_constraint);
771 			status = lim_send_set_max_tx_power_req(mac_ctx,
772 							       maxTxPower,
773 							       session);
774 			if (status == QDF_STATUS_SUCCESS)
775 				session->maxTxPower = maxTxPower;
776 		}
777 	}
778 	/* Indicate to LIM that Beacon is received */
779 	if (bcn->HTInfo.present) {
780 		chan_freq = wlan_reg_legacy_chan_to_freq(mac_ctx->pdev,
781 							 bcn->HTInfo.primaryChannel);
782 		lim_received_hb_handler(mac_ctx, chan_freq, session);
783 	} else
784 		lim_received_hb_handler(mac_ctx, bcn->chan_freq, session);
785 
786 	/*
787 	 * I don't know if any additional IE is required here. Currently, not
788 	 * include addIE.
789 	 */
790 	if (sendProbeReq)
791 		lim_send_probe_req_mgmt_frame(mac_ctx, &session->ssId,
792 			session->bssId, session->curr_op_freq,
793 			session->self_mac_addr, session->dot11mode, NULL, NULL);
794 
795 	if ((false == mac_ctx->sap.SapDfsInfo.is_dfs_cac_timer_running)
796 	    && beaconParams.paramChangeBitmap) {
797 		pe_debug("Beacon for session[%d] got changed param change bitmap: 0x%x",
798 			 session->peSessionId, beaconParams.paramChangeBitmap);
799 		lim_send_beacon_params(mac_ctx, &beaconParams, session);
800 	}
801 
802 	if ((session->opmode == QDF_P2P_CLIENT_MODE) &&
803 	    session->send_p2p_conf_frame) {
804 		lim_p2p_oper_chan_change_confirm_action_frame(mac_ctx,
805 							      session->bssId,
806 							      session);
807 		session->send_p2p_conf_frame = false;
808 	}
809 
810 	lim_process_beacon_eht(mac_ctx, session, bcn);
811 	lim_process_bcn_prb_rsp_t2lm(mac_ctx, session, bcn);
812 }
813 
814 #ifdef WLAN_FEATURE_11AX_BSS_COLOR
815 static void ap_update_bss_color_info(struct mac_context *mac_ctx,
816 						struct pe_session *session,
817 						uint8_t bss_color)
818 {
819 	if (!session)
820 		return;
821 
822 	if (bss_color < 1 || bss_color > 63) {
823 		pe_warn("Invalid BSS color");
824 		return;
825 	}
826 
827 	session->bss_color_info[bss_color - 1].seen_count++;
828 	session->bss_color_info[bss_color - 1].timestamp =
829 					qdf_get_system_timestamp();
830 }
831 
832 static uint8_t ap_get_new_bss_color(struct mac_context *mac_ctx, struct pe_session *session)
833 {
834 	int i;
835 	uint8_t new_bss_color;
836 	struct bss_color_info color_info;
837 	qdf_time_t cur_timestamp;
838 
839 	if (!session)
840 		return 0;
841 
842 	color_info = session->bss_color_info[0];
843 	new_bss_color = 0;
844 	cur_timestamp = qdf_get_system_timestamp();
845 	for (i = 1; i < MAX_BSS_COLOR_VALUE; i++) {
846 		if (session->bss_color_info[i].seen_count == 0) {
847 			new_bss_color = i + 1;
848 			return new_bss_color;
849 		}
850 
851 		if (color_info.seen_count >
852 				session->bss_color_info[i].seen_count &&
853 				(cur_timestamp - session->bss_color_info[i].
854 					timestamp) > TIME_BEACON_NOT_UPDATED) {
855 			color_info = session->bss_color_info[i];
856 			new_bss_color = i + 1;
857 		}
858 	}
859 	pe_debug("new bss color: %d", new_bss_color);
860 	return new_bss_color;
861 }
862 
863 static void sch_check_bss_color_ie(struct mac_context *mac_ctx,
864 					struct pe_session *ap_session,
865 					tSchBeaconStruct *bcn,
866 					tUpdateBeaconParams *bcn_prm)
867 {
868 	/* check bss color in the beacon */
869 	if (ap_session->he_op.present && !ap_session->he_op.bss_color) {
870 		if (bcn->he_op.present &&
871 			(bcn->he_op.bss_color ==
872 					ap_session->he_op.bss_color)) {
873 			ap_session->he_op.bss_col_disabled = 1;
874 			bcn_prm->paramChangeBitmap |=
875 						PARAM_BSS_COLOR_CHANGED;
876 			ap_session->he_bss_color_change.countdown =
877 						BSS_COLOR_SWITCH_COUNTDOWN;
878 			ap_session->he_bss_color_change.new_color =
879 					ap_get_new_bss_color(mac_ctx,
880 								ap_session);
881 			ap_session->he_op.bss_color = ap_session->
882 						he_bss_color_change.new_color;
883 			bcn_prm->bss_color = ap_session->he_op.bss_color;
884 			bcn_prm->bss_color_disabled =
885 					ap_session->he_op.bss_col_disabled;
886 			ap_session->bss_color_changing = 1;
887 		} else {
888 			/* update info for the bss color */
889 			if (bcn->he_op.present)
890 				ap_update_bss_color_info(mac_ctx,
891 						ap_session,
892 						bcn->he_op.bss_color);
893 		}
894 	}
895 }
896 
897 #else
898 static void  sch_check_bss_color_ie(struct mac_context *mac_ctx,
899 					struct pe_session *ap_session,
900 					tSchBeaconStruct *bcn,
901 					tUpdateBeaconParams *bcn_prm)
902 {
903 }
904 #endif
905 
906 void sch_beacon_process_for_ap(struct mac_context *mac_ctx,
907 				uint8_t session_id,
908 				uint8_t *rx_pkt_info,
909 				tSchBeaconStruct *bcn)
910 {
911 	struct pe_session *ap_session;
912 	tUpdateBeaconParams bcn_prm;
913 
914 	if (!bcn || !rx_pkt_info) {
915 		pe_debug("bcn %pK or rx_pkt_info %pKis NULL",
916 			 bcn, rx_pkt_info);
917 		return;
918 	}
919 
920 	ap_session = pe_find_session_by_session_id(mac_ctx, session_id);
921 	if (!ap_session)
922 		return;
923 
924 	if (!LIM_IS_AP_ROLE(ap_session))
925 		return;
926 
927 	qdf_mem_zero(&bcn_prm, sizeof(tUpdateBeaconParams));
928 	bcn_prm.paramChangeBitmap = 0;
929 
930 	bcn_prm.bss_idx = ap_session->vdev_id;
931 
932 	if (!ap_session->is_session_obss_color_collision_det_enabled)
933 		sch_check_bss_color_ie(mac_ctx, ap_session,
934 					bcn, &bcn_prm);
935 
936 	if ((ap_session->gLimProtectionControl !=
937 	     MLME_FORCE_POLICY_PROTECTION_DISABLE) &&
938 	    !ap_session->is_session_obss_offload_enabled)
939 		ap_beacon_process(mac_ctx, rx_pkt_info,
940 					bcn, &bcn_prm, ap_session);
941 
942 	if ((false == mac_ctx->sap.SapDfsInfo.is_dfs_cac_timer_running)
943 	    && bcn_prm.paramChangeBitmap) {
944 		/* Update the bcn and apply the new settings to HAL */
945 		sch_set_fixed_beacon_fields(mac_ctx, ap_session);
946 		pe_debug("Beacon for PE session[%d] got changed",
947 		       ap_session->peSessionId);
948 		pe_debug("sending beacon param change bitmap: 0x%x",
949 		       bcn_prm.paramChangeBitmap);
950 		lim_send_beacon_params(mac_ctx, &bcn_prm, ap_session);
951 	}
952 }
953 
954 #ifdef WLAN_BCN_RECV_FEATURE
955 /*
956  * sch_send_beacon_report() - To Fill beacon report for
957  * each beacon coming from connected peer and sends it
958  * to upper layer
959  * @mac_ctx: Mac context
960  * @beacon_struct: Pointing to beacon structure
961  * @session: pointer to the PE session
962  *
963  * Return: None
964  */
965 static
966 void sch_send_beacon_report(struct mac_context *mac_ctx,
967 			    struct sSirProbeRespBeacon *beacon_struct,
968 			    struct pe_session *session)
969 {
970 	struct wlan_beacon_report beacon_report;
971 	beacon_report_cb sme_bcn_cb;
972 
973 	sme_bcn_cb = mac_ctx->lim.sme_bcn_rcv_callback;
974 	if (!sme_bcn_cb)
975 		return;
976 
977 	if (!LIM_IS_STA_ROLE(session))
978 		return;
979 
980 	if (sir_compare_mac_addr(session->bssId, beacon_struct->bssid)) {
981 		/* Prepare beacon report from incoming beacon */
982 		qdf_mem_copy(beacon_report.bssid.bytes, beacon_struct->bssid,
983 			     sizeof(tSirMacAddr));
984 
985 		qdf_mem_copy(&beacon_report.time_stamp,
986 			     &beacon_struct->timeStamp, sizeof(qdf_time_t));
987 		beacon_report.beacon_interval = beacon_struct->beaconInterval;
988 		beacon_report.frequency = beacon_struct->chan_freq;
989 
990 		beacon_report.ssid.length = beacon_struct->ssId.length;
991 		qdf_mem_copy(&beacon_report.ssid.ssid,
992 			     &beacon_struct->ssId.ssId,
993 			     beacon_report.ssid.length);
994 
995 		beacon_report.boot_time =
996 				qdf_do_div(qdf_get_monotonic_boottime(),
997 					   QDF_MC_TIMER_TO_MS_UNIT);
998 
999 		beacon_report.vdev_id = session->vdev_id;
1000 
1001 		/* Send report to upper layer */
1002 		sme_bcn_cb(mac_ctx->hdd_handle, &beacon_report);
1003 	}
1004 }
1005 
1006 #else
1007 static inline
1008 void sch_send_beacon_report(struct mac_context *mac_ctx,
1009 			    struct sSirProbeRespBeacon *beacon_struct,
1010 			    struct pe_session *session)
1011 {
1012 }
1013 #endif
1014 
1015 /**
1016  * sch_beacon_process() - process the beacon frame
1017  * @mac_ctx: mac global context
1018  * @rx_pkt_info: pointer to buffer descriptor
1019  * @session: pointer to the PE session
1020  *
1021  * Return: None
1022  */
1023 void
1024 sch_beacon_process(struct mac_context *mac_ctx, uint8_t *rx_pkt_info,
1025 		   struct pe_session *session)
1026 {
1027 	static tSchBeaconStruct bcn;
1028 
1029 	if (!session)
1030 		return;
1031 
1032 	/*
1033 	 * Drop the beacon/probe response from current connected AP in
1034 	 * below cases to avoid responding to the changes in beacon(e.g. doing
1035 	 * VDEV_RESTART to update to the latest capabilities),
1036 	 * 1. vdev is not in connected state: vdev might be transitioning
1037 	 * 2. Link switch is in progress: Current link or one of the partner
1038 	 *                                links are getting replaced.
1039 	 *
1040 	 * New beacons/probe rsps can be considered once post these operations.
1041 	 */
1042 	if (LIM_IS_STA_ROLE(session) &&
1043 	    (!wlan_cm_is_vdev_connected(session->vdev) ||
1044 	     mlo_mgr_is_link_switch_in_progress(session->vdev))) {
1045 		pe_debug_rl("vdev %d, drop beacon", session->vdev_id);
1046 		return;
1047 	}
1048 
1049 	/* Convert the beacon frame into a structure */
1050 	if (sir_convert_beacon_frame2_struct(mac_ctx, (uint8_t *) rx_pkt_info,
1051 		&bcn) != QDF_STATUS_SUCCESS) {
1052 		pe_err_rl("beacon parsing failed");
1053 		return;
1054 	}
1055 
1056 	session->dtimPeriod = bcn.tim.dtimPeriod;
1057 
1058 	sch_send_beacon_report(mac_ctx, &bcn, session);
1059 	__sch_beacon_process_for_session(mac_ctx, &bcn, rx_pkt_info, session);
1060 }
1061 
1062 /**
1063  * sch_beacon_edca_process(): Process the EDCA parameter set in the received
1064  * beacon frame
1065  *
1066  * @mac_ctx:    mac global context
1067  * @edca:       reference to edca parameters in beacon struct
1068  * @session :   pesession entry
1069  *
1070  * @return status of operation
1071  */
1072 QDF_STATUS
1073 sch_beacon_edca_process(struct mac_context *mac, tSirMacEdcaParamSetIE *edca,
1074 			struct pe_session *session)
1075 {
1076 	bool follow_ap_edca;
1077 #ifdef FEATURE_WLAN_DIAG_SUPPORT
1078 	host_log_qos_edca_pkt_type *log_ptr = NULL;
1079 #endif /* FEATURE_WLAN_DIAG_SUPPORT */
1080 
1081 	if (!(mac->mlme_cfg)) {
1082 		pe_err("invalid mlme cfg");
1083 		return QDF_STATUS_E_FAILURE;
1084 	}
1085 
1086 	follow_ap_edca = mlme_get_follow_ap_edca_flag(session->vdev);
1087 
1088 	session->gLimEdcaParamSetCount = edca->qosInfo.count;
1089 	session->gLimEdcaParams[QCA_WLAN_AC_BE] = edca->acbe;
1090 	session->gLimEdcaParams[QCA_WLAN_AC_BK] = edca->acbk;
1091 	session->gLimEdcaParams[QCA_WLAN_AC_VI] = edca->acvi;
1092 	session->gLimEdcaParams[QCA_WLAN_AC_VO] = edca->acvo;
1093 
1094 	if (mac->mlme_cfg->edca_params.enable_edca_params && !follow_ap_edca) {
1095 		session->gLimEdcaParams[QCA_WLAN_AC_VO].aci.aifsn =
1096 			mac->mlme_cfg->edca_params.edca_ac_vo.vo_aifs;
1097 		session->gLimEdcaParams[QCA_WLAN_AC_VI].aci.aifsn =
1098 			mac->mlme_cfg->edca_params.edca_ac_vi.vi_aifs;
1099 		session->gLimEdcaParams[QCA_WLAN_AC_BK].aci.aifsn =
1100 			mac->mlme_cfg->edca_params.edca_ac_bk.bk_aifs;
1101 		session->gLimEdcaParams[QCA_WLAN_AC_BE].aci.aifsn =
1102 			mac->mlme_cfg->edca_params.edca_ac_be.be_aifs;
1103 
1104 		session->gLimEdcaParams[QCA_WLAN_AC_VO].cw.min =
1105 			mac->mlme_cfg->edca_params.edca_ac_vo.vo_cwmin;
1106 		session->gLimEdcaParams[QCA_WLAN_AC_VI].cw.min =
1107 			mac->mlme_cfg->edca_params.edca_ac_vi.vi_cwmin;
1108 		session->gLimEdcaParams[QCA_WLAN_AC_BK].cw.min =
1109 			mac->mlme_cfg->edca_params.edca_ac_bk.bk_cwmin;
1110 		session->gLimEdcaParams[QCA_WLAN_AC_BE].cw.min =
1111 			mac->mlme_cfg->edca_params.edca_ac_be.be_cwmin;
1112 
1113 		session->gLimEdcaParams[QCA_WLAN_AC_VO].cw.max =
1114 			mac->mlme_cfg->edca_params.edca_ac_vo.vo_cwmax;
1115 		session->gLimEdcaParams[QCA_WLAN_AC_VI].cw.max =
1116 			mac->mlme_cfg->edca_params.edca_ac_vi.vi_cwmax;
1117 		session->gLimEdcaParams[QCA_WLAN_AC_BK].cw.max =
1118 			mac->mlme_cfg->edca_params.edca_ac_bk.bk_cwmax;
1119 		session->gLimEdcaParams[QCA_WLAN_AC_BE].cw.max =
1120 			mac->mlme_cfg->edca_params.edca_ac_be.be_cwmax;
1121 	}
1122 #ifdef FEATURE_WLAN_DIAG_SUPPORT
1123 	WLAN_HOST_DIAG_LOG_ALLOC(log_ptr, host_log_qos_edca_pkt_type,
1124 				 LOG_WLAN_QOS_EDCA_C);
1125 	if (log_ptr) {
1126 		log_ptr->aci_be = session->gLimEdcaParams[QCA_WLAN_AC_BE].aci.aci;
1127 		log_ptr->cw_be =
1128 			session->gLimEdcaParams[QCA_WLAN_AC_BE].cw.max << 4
1129 				| session->gLimEdcaParams[QCA_WLAN_AC_BE].cw.min;
1130 		log_ptr->txoplimit_be =
1131 			session->gLimEdcaParams[QCA_WLAN_AC_BE].txoplimit;
1132 		log_ptr->aci_bk =
1133 			session->gLimEdcaParams[QCA_WLAN_AC_BK].aci.aci;
1134 		log_ptr->cw_bk =
1135 			session->gLimEdcaParams[QCA_WLAN_AC_BK].cw.max << 4
1136 				| session->gLimEdcaParams[QCA_WLAN_AC_BK].cw.min;
1137 		log_ptr->txoplimit_bk =
1138 			session->gLimEdcaParams[QCA_WLAN_AC_BK].txoplimit;
1139 		log_ptr->aci_vi =
1140 			session->gLimEdcaParams[QCA_WLAN_AC_VI].aci.aci;
1141 		log_ptr->cw_vi =
1142 			session->gLimEdcaParams[QCA_WLAN_AC_VI].cw.max << 4
1143 				| session->gLimEdcaParams[QCA_WLAN_AC_VI].cw.min;
1144 		log_ptr->txoplimit_vi =
1145 			session->gLimEdcaParams[QCA_WLAN_AC_VI].txoplimit;
1146 		log_ptr->aci_vo =
1147 			session->gLimEdcaParams[QCA_WLAN_AC_VO].aci.aci;
1148 		log_ptr->cw_vo =
1149 			session->gLimEdcaParams[QCA_WLAN_AC_VO].cw.max << 4
1150 				| session->gLimEdcaParams[QCA_WLAN_AC_VO].cw.min;
1151 		log_ptr->txoplimit_vo =
1152 			session->gLimEdcaParams[QCA_WLAN_AC_VO].txoplimit;
1153 	}
1154 	WLAN_HOST_DIAG_LOG_REPORT(log_ptr);
1155 #endif /* FEATURE_WLAN_DIAG_SUPPORT */
1156 	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",
1157 		 mac->mlme_cfg->edca_params.enable_edca_params,
1158 		 session->gLimEdcaParams[0].aci.aifsn,
1159 		 session->gLimEdcaParams[0].aci.acm,
1160 		 session->gLimEdcaParams[0].cw.min,
1161 		 session->gLimEdcaParams[0].cw.max,
1162 		 session->gLimEdcaParams[0].txoplimit,
1163 		 session->gLimEdcaParams[1].aci.aifsn,
1164 		 session->gLimEdcaParams[1].aci.acm,
1165 		 session->gLimEdcaParams[1].cw.min,
1166 		 session->gLimEdcaParams[1].cw.max,
1167 		 session->gLimEdcaParams[1].txoplimit,
1168 		 session->gLimEdcaParams[2].aci.aifsn,
1169 		 session->gLimEdcaParams[2].aci.acm,
1170 		 session->gLimEdcaParams[2].cw.min,
1171 		 session->gLimEdcaParams[2].cw.max,
1172 		 session->gLimEdcaParams[2].txoplimit,
1173 		 session->gLimEdcaParams[3].aci.aifsn,
1174 		 session->gLimEdcaParams[3].aci.acm,
1175 		 session->gLimEdcaParams[3].cw.min,
1176 		 session->gLimEdcaParams[3].cw.max,
1177 		 session->gLimEdcaParams[3].txoplimit);
1178 
1179 	return QDF_STATUS_SUCCESS;
1180 }
1181 
1182 void lim_enable_obss_detection_config(struct mac_context *mac_ctx,
1183 				      struct pe_session *session)
1184 {
1185 	QDF_STATUS status = QDF_STATUS_SUCCESS;
1186 
1187 	if (!session) {
1188 		pe_err("Invalid session, protection not enabled");
1189 		return;
1190 	}
1191 
1192 	if (session->gLimProtectionControl ==
1193 	    MLME_FORCE_POLICY_PROTECTION_DISABLE) {
1194 		pe_err("protectiond disabled, force policy, session %d",
1195 		       session->smeSessionId);
1196 		return;
1197 	}
1198 
1199 	if (mac_ctx->mlme_cfg->obss_ht40.obss_detection_offload_enabled) {
1200 		status = lim_obss_send_detection_cfg(mac_ctx, session, true);
1201 		if (QDF_IS_STATUS_ERROR(status)) {
1202 			pe_err("vdev %d: offload enable failed, trying legacy",
1203 			       session->smeSessionId);
1204 			session->is_session_obss_offload_enabled = false;
1205 		} else {
1206 			pe_debug("vdev %d: offload detection enabled",
1207 				 session->smeSessionId);
1208 			session->is_session_obss_offload_enabled = true;
1209 			lim_obss_send_detection_cfg(mac_ctx, session, true);
1210 		}
1211 	}
1212 
1213 	if (!mac_ctx->mlme_cfg->obss_ht40.obss_detection_offload_enabled ||
1214 	    QDF_IS_STATUS_ERROR(status)) {
1215 		status = qdf_mc_timer_start(&session->
1216 					    protection_fields_reset_timer,
1217 					    SCH_PROTECTION_RESET_TIME);
1218 		if (QDF_IS_STATUS_ERROR(status))
1219 			pe_err("vdev %d: start timer failed",
1220 			       session->smeSessionId);
1221 		else
1222 			pe_debug("vdev %d: legacy detection enabled",
1223 				 session->smeSessionId);
1224 	}
1225 }
1226 
1227 QDF_STATUS lim_obss_generate_detection_config(struct mac_context *mac_ctx,
1228 					      struct pe_session *session,
1229 					      struct obss_detection_cfg *cfg)
1230 {
1231 	uint32_t phy_mode;
1232 	enum reg_wifi_band rf_band = REG_BAND_UNKNOWN;
1233 	struct obss_detection_cfg *cur_detect;
1234 
1235 	if (!mac_ctx || !session || !cfg) {
1236 		pe_err("Invalid params mac_ctx %pK, session %pK, cfg %pK",
1237 			mac_ctx, session, cfg);
1238 		return QDF_STATUS_E_INVAL;
1239 	}
1240 
1241 	lim_get_phy_mode(mac_ctx, &phy_mode, session);
1242 	rf_band = session->limRFBand;
1243 	qdf_mem_zero(cfg, sizeof(*cfg));
1244 	cur_detect = &session->current_obss_detection;
1245 
1246 	pe_debug("band:%d, phy_mode:%d, ht_cap:%d, ht_oper_mode:%d",
1247 		 rf_band, phy_mode, session->htCapability,
1248 		 mac_ctx->lim.gHTOperMode);
1249 	pe_debug("assoc_sta: 11b:%d, 11g:%d, 11a:%d, ht20:%d",
1250 		 session->gLim11bParams.protectionEnabled,
1251 		 session->gLim11gParams.protectionEnabled,
1252 		 session->gLim11aParams.protectionEnabled,
1253 		 session->gLimHt20Params.protectionEnabled);
1254 	pe_debug("obss: 11b:%d, 11g:%d, 11a:%d, ht20:%d",
1255 		 session->gLimOlbcParams.protectionEnabled,
1256 		 session->gLimOverlap11gParams.protectionEnabled,
1257 		 session->gLimOverlap11aParams.protectionEnabled,
1258 		 session->gLimOverlapHt20Params.protectionEnabled);
1259 	pe_debug("detect: b_ap:%d, b_s:%d, g:%d, a:%d, htl:%d, htm:%d, ht20:%d",
1260 		 cur_detect->obss_11b_ap_detect_mode,
1261 		 cur_detect->obss_11b_sta_detect_mode,
1262 		 cur_detect->obss_11g_ap_detect_mode,
1263 		 cur_detect->obss_11a_detect_mode,
1264 		 cur_detect->obss_ht_legacy_detect_mode,
1265 		 cur_detect->obss_ht_mixed_detect_mode,
1266 		 cur_detect->obss_ht_20mhz_detect_mode);
1267 
1268 	if (rf_band == REG_BAND_2G) {
1269 		if ((phy_mode == WNI_CFG_PHY_MODE_11G ||
1270 		    session->htCapability) &&
1271 		    !session->gLim11bParams.protectionEnabled) {
1272 			if (!session->gLimOlbcParams.protectionEnabled &&
1273 			    !session->gLimOverlap11gParams.protectionEnabled) {
1274 				cfg->obss_11b_ap_detect_mode =
1275 					OBSS_OFFLOAD_DETECTION_PRESENT;
1276 				cfg->obss_11b_sta_detect_mode =
1277 					OBSS_OFFLOAD_DETECTION_PRESENT;
1278 			} else {
1279 				if (cur_detect->obss_11b_ap_detect_mode ==
1280 				    OBSS_OFFLOAD_DETECTION_PRESENT)
1281 					cfg->obss_11b_ap_detect_mode =
1282 						OBSS_OFFLOAD_DETECTION_ABSENT;
1283 				if (cur_detect->obss_11b_sta_detect_mode ==
1284 				    OBSS_OFFLOAD_DETECTION_PRESENT)
1285 					cfg->obss_11b_sta_detect_mode =
1286 						OBSS_OFFLOAD_DETECTION_ABSENT;
1287 			}
1288 		} else if (session->gLim11bParams.protectionEnabled) {
1289 			session->gLimOlbcParams.protectionEnabled = false;
1290 		}
1291 
1292 		if (session->htCapability &&
1293 		    session->cfgProtection.overlapFromllg &&
1294 		    !session->gLim11gParams.protectionEnabled) {
1295 			if (!session->gLimOverlap11gParams.protectionEnabled) {
1296 				cfg->obss_11g_ap_detect_mode =
1297 					OBSS_OFFLOAD_DETECTION_PRESENT;
1298 				cfg->obss_ht_legacy_detect_mode =
1299 					OBSS_OFFLOAD_DETECTION_PRESENT;
1300 				cfg->obss_ht_mixed_detect_mode =
1301 					OBSS_OFFLOAD_DETECTION_PRESENT;
1302 			} else {
1303 				if (cur_detect->obss_11g_ap_detect_mode ==
1304 				    OBSS_OFFLOAD_DETECTION_PRESENT)
1305 					cfg->obss_11g_ap_detect_mode =
1306 						OBSS_OFFLOAD_DETECTION_ABSENT;
1307 				if (cur_detect->obss_ht_legacy_detect_mode ==
1308 				    OBSS_OFFLOAD_DETECTION_PRESENT)
1309 					cfg->obss_ht_legacy_detect_mode =
1310 						OBSS_OFFLOAD_DETECTION_ABSENT;
1311 				if (cur_detect->obss_ht_mixed_detect_mode ==
1312 				    OBSS_OFFLOAD_DETECTION_PRESENT)
1313 					cfg->obss_ht_mixed_detect_mode =
1314 						OBSS_OFFLOAD_DETECTION_ABSENT;
1315 			}
1316 		} else if (session->gLim11gParams.protectionEnabled) {
1317 			session->gLimOverlap11gParams.protectionEnabled = false;
1318 		}
1319 
1320 		/* INI related settings */
1321 		if (mac_ctx->mlme_cfg->sta.ignore_peer_erp_info)
1322 			cfg->obss_11b_sta_detect_mode =
1323 				OBSS_OFFLOAD_DETECTION_DISABLED;
1324 
1325 		if (mac_ctx->mlme_cfg->sap_protection_cfg.ignore_peer_ht_opmode)
1326 			cfg->obss_ht_legacy_detect_mode =
1327 				OBSS_OFFLOAD_DETECTION_DISABLED;
1328 	}
1329 
1330 	if ((rf_band == REG_BAND_5G) && session->htCapability) {
1331 		if (!session->gLim11aParams.protectionEnabled) {
1332 			if (!session->gLimOverlap11aParams.protectionEnabled)
1333 				cfg->obss_11a_detect_mode =
1334 					OBSS_OFFLOAD_DETECTION_PRESENT;
1335 			else if (cur_detect->obss_11a_detect_mode ==
1336 				 OBSS_OFFLOAD_DETECTION_PRESENT)
1337 					cfg->obss_11a_detect_mode =
1338 						OBSS_OFFLOAD_DETECTION_ABSENT;
1339 		} else {
1340 			session->gLimOverlap11aParams.protectionEnabled = false;
1341 		}
1342 	}
1343 
1344 	if (((rf_band == REG_BAND_2G) || (rf_band == REG_BAND_5G)) &&
1345 	    session->htCapability) {
1346 
1347 		if (!session->gLimHt20Params.protectionEnabled) {
1348 			if (!session->gLimOverlapHt20Params.protectionEnabled) {
1349 				cfg->obss_ht_20mhz_detect_mode =
1350 					OBSS_OFFLOAD_DETECTION_PRESENT;
1351 			} else if (cur_detect->obss_ht_20mhz_detect_mode ==
1352 				   OBSS_OFFLOAD_DETECTION_PRESENT) {
1353 					cfg->obss_ht_20mhz_detect_mode =
1354 					OBSS_OFFLOAD_DETECTION_ABSENT;
1355 			}
1356 		} else {
1357 			session->gLimOverlapHt20Params.protectionEnabled =
1358 				false;
1359 		}
1360 	}
1361 
1362 	pe_debug("b_ap:%d, b_s:%d, g:%d, a:%d, ht_le:%d, ht_m:%d, ht_20:%d",
1363 		 cfg->obss_11b_ap_detect_mode,
1364 		 cfg->obss_11b_sta_detect_mode,
1365 		 cfg->obss_11g_ap_detect_mode,
1366 		 cfg->obss_11a_detect_mode,
1367 		 cfg->obss_ht_legacy_detect_mode,
1368 		 cfg->obss_ht_mixed_detect_mode,
1369 		 cfg->obss_ht_20mhz_detect_mode);
1370 
1371 	return QDF_STATUS_SUCCESS;
1372 }
1373 
1374 QDF_STATUS lim_obss_send_detection_cfg(struct mac_context *mac_ctx,
1375 				       struct pe_session *session, bool force)
1376 {
1377 	QDF_STATUS status;
1378 	struct obss_detection_cfg obss_cfg;
1379 	struct wmi_obss_detection_cfg_param *req_param;
1380 
1381 	if (!session) {
1382 		pe_err("Invalid session");
1383 		return QDF_STATUS_E_INVAL;
1384 	}
1385 
1386 	if (!session->is_session_obss_offload_enabled) {
1387 		pe_debug("obss offload protectiond disabled, session %d",
1388 		       session->smeSessionId);
1389 		/* Send success */
1390 		return QDF_STATUS_SUCCESS;
1391 	}
1392 
1393 	if (session->gLimProtectionControl ==
1394 	    MLME_FORCE_POLICY_PROTECTION_DISABLE) {
1395 		pe_debug("protectiond disabled, force from policy, session %d",
1396 		       session->smeSessionId);
1397 		/* Send success */
1398 		return QDF_STATUS_SUCCESS;
1399 	}
1400 
1401 	status = lim_obss_generate_detection_config(mac_ctx,
1402 						    session,
1403 						    &obss_cfg);
1404 	if (QDF_IS_STATUS_ERROR(status)) {
1405 		pe_err("Failed to generate obss detection cfg, session %d",
1406 		       session->smeSessionId);
1407 		return status;
1408 	}
1409 
1410 	if (qdf_mem_cmp(&session->obss_offload_cfg, &obss_cfg, sizeof(obss_cfg))
1411 	    || force) {
1412 		struct scheduler_msg msg = {0};
1413 		req_param = qdf_mem_malloc(sizeof(*req_param));
1414 		if (!req_param)
1415 			return QDF_STATUS_E_NOMEM;
1416 		qdf_mem_copy(&session->obss_offload_cfg, &obss_cfg,
1417 				sizeof(obss_cfg));
1418 		req_param->vdev_id = session->smeSessionId;
1419 		req_param->obss_detect_period_ms = OBSS_DETECTION_PERIOD_MS;
1420 		req_param->obss_11b_ap_detect_mode =
1421 			obss_cfg.obss_11b_ap_detect_mode;
1422 		req_param->obss_11b_sta_detect_mode =
1423 			obss_cfg.obss_11b_sta_detect_mode;
1424 		req_param->obss_11g_ap_detect_mode =
1425 			obss_cfg.obss_11g_ap_detect_mode;
1426 		req_param->obss_11a_detect_mode =
1427 			obss_cfg.obss_11a_detect_mode;
1428 		req_param->obss_ht_legacy_detect_mode =
1429 			obss_cfg.obss_ht_legacy_detect_mode;
1430 		req_param->obss_ht_20mhz_detect_mode =
1431 			obss_cfg.obss_ht_20mhz_detect_mode;
1432 		req_param->obss_ht_mixed_detect_mode =
1433 			obss_cfg.obss_ht_mixed_detect_mode;
1434 
1435 		msg.type = WMA_OBSS_DETECTION_REQ;
1436 		msg.bodyptr = req_param;
1437 		msg.reserved = 0;
1438 		status = scheduler_post_message(QDF_MODULE_ID_PE,
1439 						QDF_MODULE_ID_WMA,
1440 						QDF_MODULE_ID_WMA, &msg);
1441 		if (QDF_IS_STATUS_ERROR(status)) {
1442 			qdf_mem_free(req_param);
1443 			return status;
1444 		}
1445 	} else {
1446 		pe_debug("Skipping WMA_OBSS_DETECTION_REQ, force = %d", force);
1447 	}
1448 
1449 	return status;
1450 }
1451 
1452 QDF_STATUS lim_process_obss_detection_ind(struct mac_context *mac_ctx,
1453 					  struct wmi_obss_detect_info
1454 					  *obss_detection)
1455 {
1456 	QDF_STATUS status;
1457 	uint32_t detect_masks;
1458 	uint32_t reason;
1459 	struct obss_detection_cfg *obss_cfg;
1460 	bool enable;
1461 	struct pe_session *session;
1462 	tUpdateBeaconParams bcn_prm;
1463 	enum reg_wifi_band rf_band = REG_BAND_UNKNOWN;
1464 	struct obss_detection_cfg *cur_detect;
1465 
1466 	pe_debug("obss detect ind id %d, reason %d, msk 0x%x, " QDF_MAC_ADDR_FMT,
1467 		 obss_detection->vdev_id, obss_detection->reason,
1468 		 obss_detection->matched_detection_masks,
1469 		 QDF_MAC_ADDR_REF(obss_detection->matched_bssid_addr));
1470 
1471 	session = pe_find_session_by_vdev_id(mac_ctx, obss_detection->vdev_id);
1472 	if (!session) {
1473 		pe_err("Failed to get session for id %d",
1474 		       obss_detection->vdev_id);
1475 		return QDF_STATUS_E_INVAL;
1476 	}
1477 
1478 	if (!LIM_IS_AP_ROLE(session)) {
1479 		pe_err("session %d is not AP", obss_detection->vdev_id);
1480 		return QDF_STATUS_E_INVAL;
1481 	}
1482 
1483 	if (!session->is_session_obss_offload_enabled) {
1484 		pe_err("Offload already disabled for session %d",
1485 		       obss_detection->vdev_id);
1486 		return QDF_STATUS_SUCCESS;
1487 	}
1488 
1489 	reason = obss_detection->reason;
1490 	detect_masks = obss_detection->matched_detection_masks;
1491 
1492 	if (reason == OBSS_OFFLOAD_DETECTION_PRESENT) {
1493 		enable = true;
1494 	} else if (reason == OBSS_OFFLOAD_DETECTION_ABSENT) {
1495 		enable = false;
1496 	} else if (reason == OBSS_OFFLOAD_DETECTION_DISABLED) {
1497 		/*
1498 		 * Most common reason for this event-type from firmware
1499 		 * is insufficient memory.
1500 		 * Disable offload OBSS detection and enable legacy-way
1501 		 * of detecting OBSS by parsing beacons.
1502 		 **/
1503 		session->is_session_obss_offload_enabled = false;
1504 		pe_err("FW indicated obss offload disabled");
1505 		pe_err("Enabling host based detection, session %d",
1506 		       obss_detection->vdev_id);
1507 
1508 		status = qdf_mc_timer_start(&session->
1509 					    protection_fields_reset_timer,
1510 					    SCH_PROTECTION_RESET_TIME);
1511 		if (QDF_IS_STATUS_ERROR(status))
1512 			pe_err("cannot start protection reset timer");
1513 
1514 		return QDF_STATUS_SUCCESS;
1515 	} else {
1516 		pe_err("Invalid reason %d, session %d",
1517 		       obss_detection->reason,
1518 		       obss_detection->vdev_id);
1519 		return QDF_STATUS_E_INVAL;
1520 	}
1521 
1522 	rf_band = session->limRFBand;
1523 	qdf_mem_zero(&bcn_prm, sizeof(bcn_prm));
1524 	obss_cfg = &session->obss_offload_cfg;
1525 	cur_detect = &session->current_obss_detection;
1526 
1527 	if (OBSS_DETECTION_IS_11B_AP(detect_masks)) {
1528 		if (reason != obss_cfg->obss_11b_ap_detect_mode ||
1529 		    rf_band != REG_BAND_2G)
1530 			goto wrong_detection;
1531 
1532 		lim_enable11g_protection(mac_ctx, enable, true,
1533 					 &bcn_prm, session);
1534 		cur_detect->obss_11b_ap_detect_mode = reason;
1535 	}
1536 	if (OBSS_DETECTION_IS_11B_STA(detect_masks)) {
1537 		if (reason != obss_cfg->obss_11b_sta_detect_mode ||
1538 		    rf_band != REG_BAND_2G)
1539 			goto wrong_detection;
1540 
1541 		lim_enable11g_protection(mac_ctx, enable, true,
1542 					 &bcn_prm, session);
1543 		cur_detect->obss_11b_sta_detect_mode = reason;
1544 	}
1545 	if (OBSS_DETECTION_IS_11G_AP(detect_masks)) {
1546 		if (reason != obss_cfg->obss_11g_ap_detect_mode ||
1547 		    rf_band != REG_BAND_2G)
1548 			goto wrong_detection;
1549 
1550 		lim_enable_ht_protection_from11g(mac_ctx, enable, true,
1551 						 &bcn_prm, session);
1552 		cur_detect->obss_11g_ap_detect_mode = reason;
1553 	}
1554 	if (OBSS_DETECTION_IS_11A(detect_masks)) {
1555 		if (reason != obss_cfg->obss_11a_detect_mode ||
1556 		    rf_band != REG_BAND_5G)
1557 			goto wrong_detection;
1558 
1559 		lim_update_11a_protection(mac_ctx, enable, true,
1560 					  &bcn_prm, session);
1561 		cur_detect->obss_11a_detect_mode = reason;
1562 	}
1563 	if (OBSS_DETECTION_IS_HT_LEGACY(detect_masks)) {
1564 		/* for 5GHz, we have only 11a detection, which covers legacy */
1565 		if (reason != obss_cfg->obss_ht_legacy_detect_mode ||
1566 		    rf_band != REG_BAND_2G)
1567 			goto wrong_detection;
1568 
1569 		lim_enable_ht_protection_from11g(mac_ctx, enable, true,
1570 						 &bcn_prm, session);
1571 		cur_detect->obss_ht_legacy_detect_mode = reason;
1572 	}
1573 	if (OBSS_DETECTION_IS_HT_MIXED(detect_masks)) {
1574 		/* for 5GHz, we have only 11a detection, which covers ht mix */
1575 		if (reason != obss_cfg->obss_ht_mixed_detect_mode ||
1576 		    rf_band != REG_BAND_2G)
1577 			goto wrong_detection;
1578 
1579 		lim_enable_ht_protection_from11g(mac_ctx, enable, true,
1580 						 &bcn_prm, session);
1581 		cur_detect->obss_ht_mixed_detect_mode = reason;
1582 	}
1583 	if (OBSS_DETECTION_IS_HT_20MHZ(detect_masks)) {
1584 		if (reason != obss_cfg->obss_ht_20mhz_detect_mode)
1585 			goto wrong_detection;
1586 
1587 		lim_enable_ht20_protection(mac_ctx, enable, true,
1588 					   &bcn_prm, session);
1589 		cur_detect->obss_ht_20mhz_detect_mode = reason;
1590 	}
1591 
1592 	if ((false == mac_ctx->sap.SapDfsInfo.is_dfs_cac_timer_running) &&
1593 	    bcn_prm.paramChangeBitmap) {
1594 		/* Update the bcn and apply the new settings to HAL */
1595 		sch_set_fixed_beacon_fields(mac_ctx, session);
1596 		pe_debug("Beacon for PE session: %d got changed: 0x%x",
1597 			 session->smeSessionId, bcn_prm.paramChangeBitmap);
1598 		if (!QDF_IS_STATUS_SUCCESS(lim_send_beacon_params(
1599 		     mac_ctx, &bcn_prm, session))) {
1600 			pe_err("Failed to send beacon param, session %d",
1601 				obss_detection->vdev_id);
1602 			return QDF_STATUS_E_FAULT;
1603 		}
1604 	}
1605 
1606 	status = lim_obss_send_detection_cfg(mac_ctx, session, true);
1607 	if (QDF_IS_STATUS_ERROR(status)) {
1608 		pe_err("Failed to send obss detection cfg, session %d",
1609 			obss_detection->vdev_id);
1610 		return status;
1611 	}
1612 
1613 	return QDF_STATUS_SUCCESS;
1614 
1615 wrong_detection:
1616 	/*
1617 	 * We may get this wrong detection before FW can update latest cfg,
1618 	 * So keeping log level debug
1619 	 **/
1620 	pe_debug("Wrong detection, session %d", obss_detection->vdev_id);
1621 
1622 	return QDF_STATUS_E_INVAL;
1623 }
1624