1 /*
2 * Copyright (c) 2011-2021 The Linux Foundation. All rights reserved.
3 * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
4 *
5 * Permission to use, copy, modify, and/or distribute this software for
6 * any purpose with or without fee is hereby granted, provided that the
7 * above copyright notice and this permission notice appear in all
8 * copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
11 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
12 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
13 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
16 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17 * PERFORMANCE OF THIS SOFTWARE.
18 */
19
20 /*
21 *
22 * This file lim_process_beacon_frame.cc contains the code
23 * for processing Received Beacon Frame.
24 * Author: Chandra Modumudi
25 * Date: 03/01/02
26 * History:-
27 * Date Modified by Modification Information
28 * --------------------------------------------------------------------
29 *
30 */
31
32 #include "wni_cfg.h"
33 #include "ani_global.h"
34 #include "sch_api.h"
35 #include "utils_api.h"
36 #include "lim_types.h"
37 #include "lim_utils.h"
38 #include "lim_assoc_utils.h"
39 #include "lim_prop_exts_utils.h"
40 #include "lim_ser_des_utils.h"
41 #include "wlan_mlo_t2lm.h"
42 #include "wlan_mlo_mgr_roam.h"
43 #include "lim_mlo.h"
44 #include "wlan_mlo_mgr_sta.h"
45 #include "wlan_cm_api.h"
46 #include "wlan_mlme_api.h"
47 #include "wlan_objmgr_vdev_obj.h"
48 #include "wlan_reg_services_api.h"
49 #ifdef WLAN_FEATURE_11BE_MLO
50 #include <cds_ieee80211_common.h>
51 #endif
52 #include "wlan_t2lm_api.h"
53
54 /*Invalid Recommended Max Simultaneous Links value */
55 #define RESERVED_REC_LINK_VALUE 1
56
57 #ifdef WLAN_FEATURE_11BE_MLO
58
lim_process_bcn_prb_rsp_t2lm(struct mac_context * mac_ctx,struct pe_session * session,tpSirProbeRespBeacon bcn_ptr)59 void lim_process_bcn_prb_rsp_t2lm(struct mac_context *mac_ctx,
60 struct pe_session *session,
61 tpSirProbeRespBeacon bcn_ptr)
62 {
63 struct wlan_objmgr_vdev *vdev;
64 struct wlan_t2lm_context *t2lm_ctx;
65
66 if (!session || !bcn_ptr || !mac_ctx) {
67 pe_err("invalid input parameters");
68 return;
69 }
70
71 if (!wlan_mlme_get_t2lm_negotiation_supported(mac_ctx->psoc)) {
72 pe_err_rl("T2LM negotiation not supported");
73 return;
74 }
75
76 vdev = session->vdev;
77 if (!vdev || !wlan_vdev_mlme_is_mlo_vdev(vdev))
78 return;
79
80 if (!wlan_cm_is_vdev_connected(vdev))
81 return;
82
83 if (!mlo_check_if_all_links_up(vdev))
84 return;
85
86 t2lm_ctx = &vdev->mlo_dev_ctx->t2lm_ctx;
87
88 qdf_mem_copy((uint8_t *)&t2lm_ctx->tsf, (uint8_t *)bcn_ptr->timeStamp,
89 sizeof(uint64_t));
90 wlan_update_t2lm_mapping(vdev, &bcn_ptr->t2lm_ctx, t2lm_ctx->tsf);
91 }
92
valid_max_rec_links(uint8_t value)93 static uint8_t valid_max_rec_links(uint8_t value)
94 {
95 if (value > RESERVED_REC_LINK_VALUE &&
96 value <= WLAN_DEFAULT_REC_LINK_VALUE)
97 return value;
98 return WLAN_DEFAULT_REC_LINK_VALUE;
99 }
100
lim_process_beacon_mlo(struct mac_context * mac_ctx,struct pe_session * session,tSchBeaconStruct * bcn_ptr)101 void lim_process_beacon_mlo(struct mac_context *mac_ctx,
102 struct pe_session *session,
103 tSchBeaconStruct *bcn_ptr)
104 {
105 struct csa_offload_params csa_param;
106 int i;
107 uint8_t link_id;
108 uint8_t *per_sta_pro;
109 uint32_t per_sta_pro_len;
110 uint8_t *sta_pro;
111 uint32_t sta_pro_len;
112 uint16_t stacontrol;
113 struct ieee80211_channelswitch_ie *csa_ie;
114 struct ieee80211_extendedchannelswitch_ie *xcsa_ie;
115 struct wlan_objmgr_vdev *vdev;
116 struct wlan_objmgr_pdev *pdev;
117 struct wlan_mlo_dev_context *mlo_ctx;
118 uint8_t is_sta_csa_synced;
119 struct mlo_link_info *link_info;
120 uint8_t sta_info_len = 0;
121 uint8_t tmp_rec_value;
122
123 if (!session || !bcn_ptr || !mac_ctx) {
124 pe_err("invalid input parameters");
125 return;
126 }
127 vdev = session->vdev;
128 if (!vdev || !wlan_vdev_mlme_is_mlo_vdev(vdev))
129 return;
130
131 pdev = wlan_vdev_get_pdev(vdev);
132 if (!pdev) {
133 pe_err("null pdev");
134 return;
135 }
136 mlo_ctx = vdev->mlo_dev_ctx;
137 if (!mlo_ctx) {
138 pe_err("null mlo_dev_ctx");
139 return;
140 }
141
142 if (bcn_ptr->mlo_ie.mlo_ie.medium_sync_delay_info_present) {
143 wlan_vdev_mlme_cap_clear(vdev, WLAN_VDEV_C_EMLSR_CAP);
144 pe_debug("EMLSR not supported with D2.0 AP");
145 }
146
147 /** max num of active links recommended by AP */
148 tmp_rec_value =
149 bcn_ptr->mlo_ie.mlo_ie.ext_mld_capab_and_op_info.rec_max_simultaneous_links;
150 mlo_ctx->mlo_max_recom_simult_links =
151 valid_max_rec_links(tmp_rec_value);
152
153 for (i = 0; i < bcn_ptr->mlo_ie.mlo_ie.num_sta_profile; i++) {
154 csa_ie = NULL;
155 xcsa_ie = NULL;
156 qdf_mem_zero(&csa_param, sizeof(csa_param));
157 per_sta_pro = bcn_ptr->mlo_ie.mlo_ie.sta_profile[i].data;
158 /* Append one byte to get the element length */
159 per_sta_pro_len = bcn_ptr->mlo_ie.mlo_ie.sta_profile[i].num_data;
160 stacontrol = *(uint16_t *)(per_sta_pro + sizeof(struct subelem_header));
161 sta_info_len = *(uint8_t *)(per_sta_pro +
162 sizeof(struct subelem_header) + WLAN_ML_BV_LINFO_PERSTAPROF_STACTRL_SIZE);
163 /* IE ID + LEN + STA control STA info len*/
164 sta_pro = per_sta_pro + sizeof(struct subelem_header) +
165 WLAN_ML_BV_LINFO_PERSTAPROF_STACTRL_SIZE + sta_info_len;
166 sta_pro_len = per_sta_pro_len - sizeof(struct subelem_header) -
167 WLAN_ML_BV_LINFO_PERSTAPROF_STACTRL_SIZE - sta_info_len;
168 link_id = QDF_GET_BITS(
169 stacontrol,
170 WLAN_ML_BV_LINFO_PERSTAPROF_STACTRL_LINKID_IDX,
171 WLAN_ML_BV_LINFO_PERSTAPROF_STACTRL_LINKID_BITS);
172
173 csa_ie = (struct ieee80211_channelswitch_ie *)
174 wlan_get_ie_ptr_from_eid(
175 DOT11F_EID_CHANSWITCHANN,
176 sta_pro, sta_pro_len);
177 xcsa_ie = (struct ieee80211_extendedchannelswitch_ie *)
178 wlan_get_ie_ptr_from_eid(
179 DOT11F_EID_EXT_CHAN_SWITCH_ANN,
180 sta_pro, sta_pro_len);
181 is_sta_csa_synced = mlo_is_sta_csa_synced(mlo_ctx, link_id);
182 link_info = mlo_mgr_get_ap_link_by_link_id(mlo_ctx, link_id);
183 if (!link_info) {
184 mlo_err("link info null");
185 return;
186 }
187
188 if (csa_ie) {
189 csa_param.channel = csa_ie->newchannel;
190 csa_param.csa_chan_freq = wlan_reg_legacy_chan_to_freq(
191 pdev, csa_ie->newchannel);
192 csa_param.switch_mode = csa_ie->switchmode;
193 csa_param.ies_present_flag |= MLME_CSA_IE_PRESENT;
194 mlo_sta_handle_csa_standby_link(mlo_ctx, link_id,
195 &csa_param, vdev);
196
197 if (!is_sta_csa_synced)
198 mlo_sta_csa_save_params(mlo_ctx, link_id,
199 &csa_param);
200 } else if (xcsa_ie) {
201 csa_param.channel = xcsa_ie->newchannel;
202 csa_param.switch_mode = xcsa_ie->switchmode;
203 csa_param.new_op_class = xcsa_ie->newClass;
204 if (wlan_reg_is_6ghz_op_class(pdev, xcsa_ie->newClass))
205 csa_param.csa_chan_freq =
206 wlan_reg_chan_band_to_freq(
207 pdev, xcsa_ie->newchannel,
208 BIT(REG_BAND_6G));
209 else
210 csa_param.csa_chan_freq =
211 wlan_reg_legacy_chan_to_freq(
212 pdev, xcsa_ie->newchannel);
213 csa_param.ies_present_flag |= MLME_XCSA_IE_PRESENT;
214 mlo_sta_handle_csa_standby_link(mlo_ctx, link_id,
215 &csa_param, vdev);
216 if (!is_sta_csa_synced)
217 mlo_sta_csa_save_params(mlo_ctx, link_id,
218 &csa_param);
219 }
220 }
221 }
222 #endif
223
224 static QDF_STATUS
lim_validate_rsn_ie(const uint8_t * ie_ptr,uint16_t ie_len)225 lim_validate_rsn_ie(const uint8_t *ie_ptr, uint16_t ie_len)
226 {
227 QDF_STATUS status;
228 const uint8_t *rsn_ie;
229 struct wlan_crypto_params crypto_params;
230
231 rsn_ie = wlan_get_ie_ptr_from_eid(WLAN_ELEMID_RSN, ie_ptr, ie_len);
232 if (!rsn_ie)
233 return QDF_STATUS_SUCCESS;
234
235 qdf_mem_zero(&crypto_params, sizeof(struct wlan_crypto_params));
236 status = wlan_crypto_rsnie_check(&crypto_params, rsn_ie);
237 if (status != QDF_STATUS_SUCCESS) {
238 pe_debug_rl("RSN IE check failed %d", status);
239 return QDF_STATUS_E_INVAL;
240 }
241
242 return QDF_STATUS_SUCCESS;
243 }
244
245 #ifdef WLAN_FEATURE_11BE
246 /**
247 * lim_get_update_eht_bw_puncture_allow() - whether bw and puncture can be
248 * sent to target directly
249 * @session: pe session
250 * @ori_bw: bandwdith from beacon
251 * @new_bw: bandwidth intersection between reference AP and STA
252 * @update_allow: return true if bw and puncture can be updated directly
253 *
254 * Return: QDF_STATUS
255 */
256 static QDF_STATUS
lim_get_update_eht_bw_puncture_allow(struct pe_session * session,enum phy_ch_width ori_bw,enum phy_ch_width * new_bw,bool * update_allow)257 lim_get_update_eht_bw_puncture_allow(struct pe_session *session,
258 enum phy_ch_width ori_bw,
259 enum phy_ch_width *new_bw,
260 bool *update_allow)
261 {
262 enum phy_ch_width ch_width;
263 struct wlan_objmgr_psoc *psoc;
264 enum wlan_phymode phy_mode;
265 QDF_STATUS status = QDF_STATUS_SUCCESS;
266
267 *update_allow = false;
268
269 psoc = wlan_vdev_get_psoc(session->vdev);
270 if (!psoc) {
271 pe_err("psoc object invalid");
272 return QDF_STATUS_E_INVAL;
273 }
274 status = mlme_get_peer_phymode(psoc, session->bssId, &phy_mode);
275 if (QDF_IS_STATUS_ERROR(status)) {
276 pe_err("failed to get phy_mode %d mac: " QDF_MAC_ADDR_FMT,
277 status, QDF_MAC_ADDR_REF(session->bssId));
278 return QDF_STATUS_E_INVAL;
279 }
280 ch_width = wlan_mlme_get_ch_width_from_phymode(phy_mode);
281
282 if (ori_bw <= ch_width) {
283 *new_bw = ori_bw;
284 *update_allow = true;
285 return QDF_STATUS_SUCCESS;
286 }
287
288 if ((ori_bw == CH_WIDTH_320MHZ) &&
289 !session->eht_config.support_320mhz_6ghz) {
290 if (ch_width == CH_WIDTH_160MHZ) {
291 *new_bw = CH_WIDTH_160MHZ;
292 *update_allow = true;
293 return QDF_STATUS_SUCCESS;
294 }
295 }
296
297 return QDF_STATUS_SUCCESS;
298 }
299
lim_process_beacon_eht_op(struct pe_session * session,struct sSirProbeRespBeacon * bcn_ptr)300 void lim_process_beacon_eht_op(struct pe_session *session,
301 struct sSirProbeRespBeacon *bcn_ptr)
302 {
303 uint16_t ori_punc = 0;
304 enum phy_ch_width ori_bw = CH_WIDTH_INVALID;
305 enum phy_ch_width ori_bw_no_punct = CH_WIDTH_INVALID;
306 uint8_t cb_mode;
307 enum phy_ch_width new_bw;
308 bool update_allow;
309 QDF_STATUS status;
310 struct mac_context *mac_ctx;
311 struct wlan_objmgr_vdev *vdev;
312 struct wlan_channel *des_chan;
313 struct csa_offload_params *csa_param;
314 uint8_t ccfs0;
315 uint8_t ccfs1;
316 tDot11fIEeht_op *eht_op;
317 tDot11fIEhe_op *he_op;
318 uint8_t ch_width;
319 uint8_t chan_id;
320 struct wlan_channel bss_chan = {0};
321 struct wlan_channel *current_chan = NULL;
322 uint8_t band_mask;
323 uint32_t ch_cfreq2 = 0;
324
325 if (!bcn_ptr || !session || !session->mac_ctx || !session->vdev) {
326 pe_err("invalid input parameters");
327 return;
328 }
329
330 eht_op = &bcn_ptr->eht_op;
331 he_op = &bcn_ptr->he_op;
332 mac_ctx = session->mac_ctx;
333 vdev = session->vdev;
334
335 chan_id = wlan_reg_freq_to_chan(wlan_vdev_get_pdev(vdev),
336 bcn_ptr->chan_freq);
337
338 cb_mode = lim_get_cb_mode_for_freq(mac_ctx, session,
339 session->curr_op_freq);
340 if (cb_mode == WNI_CFG_CHANNEL_BONDING_MODE_DISABLE) {
341 /*
342 * if channel bonding is disabled from INI do not
343 * update the chan width
344 */
345 pe_debug_rl("chan banding is disabled skip bw update");
346
347 return;
348 }
349 /* handle beacon IE for 11be non-mlo case */
350 if (eht_op->eht_op_information_present) {
351 ori_bw = wlan_mlme_convert_eht_op_bw_to_phy_ch_width(
352 eht_op->channel_width);
353 ccfs0 = eht_op->ccfs0;
354 ccfs1 = eht_op->ccfs1;
355 if (eht_op->disabled_sub_chan_bitmap_present) {
356 ori_punc = QDF_GET_BITS(eht_op->disabled_sub_chan_bitmap[0][0], 0, 8);
357 ori_punc |= QDF_GET_BITS(eht_op->disabled_sub_chan_bitmap[0][1], 0, 8) << 8;
358
359 if (!wlan_mlme_get_eht_disable_punct_in_us_lpi(mac_ctx->psoc))
360 goto update_bw;
361
362 bss_chan.ch_freq = bcn_ptr->chan_freq;
363 bss_chan.puncture_bitmap = ori_punc;
364 bss_chan.ch_width = ori_bw;
365 bss_chan.ch_phymode = WLAN_PHYMODE_11BEA_EHT160;
366
367 if (ori_bw == CH_WIDTH_320MHZ &&
368 WLAN_REG_IS_6GHZ_CHAN_FREQ(bcn_ptr->chan_freq)) {
369 band_mask = BIT(REG_BAND_6G);
370 ch_cfreq2 = wlan_reg_chan_band_to_freq(mac_ctx->pdev,
371 ccfs1,
372 band_mask);
373 bss_chan.ch_cfreq2 = ch_cfreq2;
374 }
375
376 status = wlan_mlme_get_bw_no_punct(mac_ctx->psoc,
377 vdev,
378 &bss_chan,
379 &ori_bw_no_punct);
380 current_chan = wlan_vdev_mlme_get_bss_chan(vdev);
381 if (QDF_IS_STATUS_SUCCESS(status)) {
382 if (ori_bw_no_punct != current_chan->ch_width) {
383 status = wlan_mlme_send_ch_width_update_with_notify(mac_ctx->psoc,
384 vdev,
385 session->vdev_id,
386 ori_bw_no_punct);
387 }
388 return;
389 }
390 }
391 } else if (he_op->oper_info_6g_present) {
392 ch_width = he_op->oper_info_6g.info.ch_width;
393 ccfs0 = he_op->oper_info_6g.info.center_freq_seg0;
394 ccfs1 = he_op->oper_info_6g.info.center_freq_seg1;
395 ori_bw = wlan_mlme_convert_he_6ghz_op_bw_to_phy_ch_width(ch_width,
396 chan_id,
397 ccfs0,
398 ccfs1);
399 } else {
400 return;
401 }
402
403 update_bw:
404 status = lim_get_update_eht_bw_puncture_allow(session, ori_bw,
405 &new_bw,
406 &update_allow);
407 if (QDF_IS_STATUS_ERROR(status))
408 return;
409
410 if (update_allow) {
411 wlan_cm_sta_update_bw_puncture(vdev, session->bssId,
412 ori_punc, ori_bw,
413 ccfs0,
414 ccfs1,
415 new_bw);
416 } else {
417 csa_param = qdf_mem_malloc(sizeof(*csa_param));
418 if (!csa_param) {
419 pe_err("csa_param allocation fails");
420 return;
421 }
422 des_chan = wlan_vdev_mlme_get_des_chan(vdev);
423 csa_param->channel = des_chan->ch_ieee;
424 csa_param->csa_chan_freq = des_chan->ch_freq;
425 csa_param->new_ch_width = ori_bw;
426 csa_param->new_punct_bitmap = ori_punc;
427 csa_param->new_ch_freq_seg1 = ccfs0;
428 csa_param->new_ch_freq_seg2 = ccfs1;
429 qdf_copy_macaddr(&csa_param->bssid,
430 (struct qdf_mac_addr *)session->bssId);
431 lim_handle_sta_csa_param(session->mac_ctx, csa_param, false);
432 }
433 }
434
lim_process_beacon_eht(struct mac_context * mac_ctx,struct pe_session * session,tSchBeaconStruct * bcn_ptr)435 void lim_process_beacon_eht(struct mac_context *mac_ctx,
436 struct pe_session *session,
437 tSchBeaconStruct *bcn_ptr)
438 {
439 struct wlan_objmgr_vdev *vdev;
440 struct wlan_channel *des_chan;
441
442 if (!session || !bcn_ptr || !mac_ctx) {
443 pe_err("invalid input parameters");
444 return;
445 }
446 vdev = session->vdev;
447 if (!vdev || wlan_vdev_mlme_get_opmode(vdev) != QDF_STA_MODE ||
448 !qdf_is_macaddr_equal((struct qdf_mac_addr *)session->bssId,
449 (struct qdf_mac_addr *)bcn_ptr->bssid))
450 return;
451 des_chan = wlan_vdev_mlme_get_des_chan(vdev);
452 if (!des_chan || !IS_WLAN_PHYMODE_EHT(des_chan->ch_phymode))
453 return;
454
455 if (wlan_cm_is_vdev_connected(vdev))
456 lim_process_beacon_eht_op(session, bcn_ptr);
457
458 if (mlo_is_mld_sta(vdev))
459 /* handle beacon IE for 802.11be mlo case */
460 lim_process_beacon_mlo(mac_ctx, session, bcn_ptr);
461 }
462
463 void
lim_process_ml_reconfig(struct mac_context * mac_ctx,struct pe_session * session,uint8_t * rx_pkt_info)464 lim_process_ml_reconfig(struct mac_context *mac_ctx,
465 struct pe_session *session,
466 uint8_t *rx_pkt_info)
467 {
468 uint8_t *frame;
469 uint16_t frame_len;
470
471 if (!session->vdev)
472 return;
473
474 frame = WMA_GET_RX_MPDU_DATA(rx_pkt_info);
475 frame_len = WMA_GET_RX_PAYLOAD_LEN(rx_pkt_info);
476 if (frame_len < SIR_MAC_B_PR_SSID_OFFSET)
477 return;
478
479 mlo_process_ml_reconfig_ie(session->vdev, NULL,
480 frame + SIR_MAC_B_PR_SSID_OFFSET,
481 frame_len - SIR_MAC_B_PR_SSID_OFFSET, NULL);
482 }
483 #endif
484
485 /**
486 * lim_process_beacon_frame() - to process beacon frames
487 * @mac_ctx: Pointer to Global MAC structure
488 * @rx_pkt_info: A pointer to RX packet info structure
489 * @session: A pointer to session
490 *
491 * This function is called by limProcessMessageQueue() upon Beacon
492 * frame reception.
493 * Note:
494 * 1. Beacons received in 'normal' state in IBSS are handled by
495 * Beacon Processing module.
496 *
497 * Return: none
498 */
499
500 void
lim_process_beacon_frame(struct mac_context * mac_ctx,uint8_t * rx_pkt_info,struct pe_session * session)501 lim_process_beacon_frame(struct mac_context *mac_ctx, uint8_t *rx_pkt_info,
502 struct pe_session *session)
503 {
504 tpSirMacMgmtHdr mac_hdr;
505 tSchBeaconStruct *bcn_ptr;
506 uint8_t *frame;
507 const uint8_t *owe_transition_ie;
508 uint16_t frame_len;
509 uint8_t bpcc;
510 bool cu_flag = true;
511 QDF_STATUS status;
512
513 /*
514 * here is it required to increment session specific heartBeat
515 * beacon counter
516 */
517 mac_hdr = WMA_GET_RX_MAC_HEADER(rx_pkt_info);
518 frame = WMA_GET_RX_MPDU_DATA(rx_pkt_info);
519 frame_len = WMA_GET_RX_PAYLOAD_LEN(rx_pkt_info);
520
521 if (frame_len < SIR_MAC_B_PR_SSID_OFFSET) {
522 pe_debug_rl("payload invalid len %d", frame_len);
523 return;
524 }
525 if (lim_validate_rsn_ie(frame + SIR_MAC_B_PR_SSID_OFFSET,
526 frame_len - SIR_MAC_B_PR_SSID_OFFSET) !=
527 QDF_STATUS_SUCCESS)
528 return;
529 /* Expect Beacon in any state as Scan is independent of LIM state */
530 bcn_ptr = qdf_mem_malloc(sizeof(*bcn_ptr));
531 if (!bcn_ptr)
532 return;
533
534 /* Parse received Beacon */
535 if (sir_convert_beacon_frame2_struct(mac_ctx,
536 rx_pkt_info, bcn_ptr) !=
537 QDF_STATUS_SUCCESS) {
538 /*
539 * Received wrongly formatted/invalid Beacon.
540 * Ignore it and move on.
541 */
542 pe_warn("Received invalid Beacon in state: %X",
543 session->limMlmState);
544 lim_print_mlm_state(mac_ctx, LOGW,
545 session->limMlmState);
546 qdf_mem_free(bcn_ptr);
547 return;
548 }
549
550 if (mlo_is_mld_sta(session->vdev)) {
551 cu_flag = false;
552 status = lim_get_bpcc_from_mlo_ie(bcn_ptr, &bpcc);
553 if (QDF_IS_STATUS_SUCCESS(status))
554 cu_flag = lim_check_cu_happens(session->vdev, bpcc);
555 lim_process_ml_reconfig(mac_ctx, session, rx_pkt_info);
556 }
557
558 lim_process_bcn_prb_rsp_t2lm(mac_ctx, session, bcn_ptr);
559 if (QDF_IS_STATUS_SUCCESS(lim_check_for_ml_probe_req(session)))
560 goto end;
561
562 /*
563 * during scanning, when any session is active, and
564 * beacon/Pr belongs to one of the session, fill up the
565 * following, TBD - HB counter
566 */
567 if (sir_compare_mac_addr(session->bssId,
568 bcn_ptr->bssid)) {
569 qdf_mem_copy((uint8_t *)&session->lastBeaconTimeStamp,
570 (uint8_t *) bcn_ptr->timeStamp,
571 sizeof(uint64_t));
572 session->currentBssBeaconCnt++;
573 }
574 MTRACE(mac_trace(mac_ctx,
575 TRACE_CODE_RX_MGMT_TSF, 0, bcn_ptr->timeStamp[0]));
576 MTRACE(mac_trace(mac_ctx, TRACE_CODE_RX_MGMT_TSF, 0,
577 bcn_ptr->timeStamp[1]));
578
579 if (session->limMlmState ==
580 eLIM_MLM_WT_JOIN_BEACON_STATE) {
581 owe_transition_ie = wlan_get_vendor_ie_ptr_from_oui(
582 OWE_TRANSITION_OUI_TYPE,
583 OWE_TRANSITION_OUI_SIZE,
584 frame + SIR_MAC_B_PR_SSID_OFFSET,
585 frame_len - SIR_MAC_B_PR_SSID_OFFSET);
586 if (session->connected_akm == ANI_AKM_TYPE_OWE &&
587 owe_transition_ie) {
588 pe_debug("vdev:%d Drop OWE rx beacon. Wait for probe for join success",
589 session->vdev_id);
590 qdf_mem_free(bcn_ptr);
591 return;
592 }
593
594 if (session->beacon) {
595 qdf_mem_free(session->beacon);
596 session->beacon = NULL;
597 session->bcnLen = 0;
598 }
599
600 mac_ctx->lim.bss_rssi =
601 (int8_t)WMA_GET_RX_RSSI_NORMALIZED(rx_pkt_info);
602 session->bcnLen = WMA_GET_RX_MPDU_LEN(rx_pkt_info);
603 session->beacon = qdf_mem_malloc(session->bcnLen);
604 if (session->beacon)
605 /*
606 * Store the whole Beacon frame. This is sent to
607 * csr/hdd in join cnf response.
608 */
609 qdf_mem_copy(session->beacon,
610 WMA_GET_RX_MAC_HEADER(rx_pkt_info),
611 session->bcnLen);
612 mgmt_txrx_frame_hex_dump((uint8_t *)mac_hdr,
613 WMA_GET_RX_MPDU_LEN(rx_pkt_info),
614 false);
615 lim_check_and_announce_join_success(mac_ctx, bcn_ptr,
616 mac_hdr, session);
617 }
618
619 if (cu_flag)
620 lim_process_beacon_eht(mac_ctx, session, bcn_ptr);
621 end:
622 qdf_mem_free(bcn_ptr);
623 return;
624 }
625