1 /*
2 * Copyright (c) 2012-2021 The Linux Foundation. All rights reserved.
3 * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
4 *
5 * Permission to use, copy, modify, and/or distribute this software for
6 * any purpose with or without fee is hereby granted, provided that the
7 * above copyright notice and this permission notice appear in all
8 * copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
11 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
12 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
13 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
16 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17 * PERFORMANCE OF THIS SOFTWARE.
18 */
19
20 /*
21 * This file parser_api.cc contains the code for parsing
22 * 802.11 messages.
23 * Author: Pierre Vandwalle
24 * Date: 03/18/02
25 * History:-
26 * Date Modified by Modification Information
27 * --------------------------------------------------------------------
28 *
29 */
30
31 #include "sir_api.h"
32 #include "ani_global.h"
33 #include "parser_api.h"
34 #include "lim_utils.h"
35 #include "utils_parser.h"
36 #include "lim_ser_des_utils.h"
37 #include "sch_api.h"
38 #include "wmm_apsd.h"
39 #include "rrm_api.h"
40
41 #include "cds_regdomain.h"
42 #include "qdf_crypto.h"
43 #include "lim_process_fils.h"
44 #include "wlan_utility.h"
45 #include "wifi_pos_api.h"
46 #include "wlan_mlme_public_struct.h"
47 #include "wlan_mlme_ucfg_api.h"
48 #include "wlan_mlme_api.h"
49 #include "wlan_reg_services_api.h"
50 #include "wlan_cm_roam_api.h"
51 #include "wlan_mlo_mgr_sta.h"
52 #include "wlan_twt_cfg_ext_api.h"
53 #include <wlan_cmn_ieee80211.h>
54 #ifdef WLAN_FEATURE_11BE_MLO
55 #include <lim_mlo.h>
56 #include <utils_mlo.h>
57 #endif
58 #ifdef WLAN_FEATURE_11BE
59 #include "wlan_epcs_api.h"
60 #include <wlan_mlo_t2lm.h>
61 #endif
62 #include "wlan_mlo_mgr_link_switch.h"
63
64 #define RSN_OUI_SIZE 4
65 /* ////////////////////////////////////////////////////////////////////// */
swap_bit_field16(uint16_t in,uint16_t * out)66 void swap_bit_field16(uint16_t in, uint16_t *out)
67 {
68 #ifdef ANI_LITTLE_BIT_ENDIAN
69 *out = in;
70 #else /* Big-Endian... */
71 *out = ((in & 0x8000) >> 15) |
72 ((in & 0x4000) >> 13) |
73 ((in & 0x2000) >> 11) |
74 ((in & 0x1000) >> 9) |
75 ((in & 0x0800) >> 7) |
76 ((in & 0x0400) >> 5) |
77 ((in & 0x0200) >> 3) |
78 ((in & 0x0100) >> 1) |
79 ((in & 0x0080) << 1) |
80 ((in & 0x0040) << 3) |
81 ((in & 0x0020) << 5) |
82 ((in & 0x0010) << 7) |
83 ((in & 0x0008) << 9) |
84 ((in & 0x0004) << 11) |
85 ((in & 0x0002) << 13) | ((in & 0x0001) << 15);
86 #endif /* ANI_LITTLE_BIT_ENDIAN */
87 }
88
__print_wmm_params(struct mac_context * mac,tDot11fIEWMMParams * pWmm)89 static inline void __print_wmm_params(struct mac_context *mac,
90 tDot11fIEWMMParams *pWmm)
91 {
92 pe_nofl_debug("WMM: BE: aifsn %d, acm %d, aci %d, cwmin %d, cwmax %d, txop %d, "
93 "BK: aifsn %d, acm %d, aci %d, cwmin %d, cwmax %d, txop %d, "
94 "VI: aifsn %d, acm %d, aci %d, cwmin %d, cwmax %d, txop %d, "
95 "VO: aifsn %d, acm %d, aci %d, cwmin %d, cwmax %d, txop %d",
96 pWmm->acbe_aifsn, pWmm->acbe_acm, pWmm->acbe_aci,
97 pWmm->acbe_acwmin, pWmm->acbe_acwmax,
98 pWmm->acbe_txoplimit,
99 pWmm->acbk_aifsn, pWmm->acbk_acm, pWmm->acbk_aci,
100 pWmm->acbk_acwmin, pWmm->acbk_acwmax,
101 pWmm->acbk_txoplimit,
102 pWmm->acvi_aifsn, pWmm->acvi_acm, pWmm->acvi_aci,
103 pWmm->acvi_acwmin, pWmm->acvi_acwmax,
104 pWmm->acvi_txoplimit,
105 pWmm->acvo_aifsn, pWmm->acvo_acm, pWmm->acvo_aci,
106 pWmm->acvo_acwmin, pWmm->acvo_acwmax,
107 pWmm->acvo_txoplimit);
108 }
109
110 /* ////////////////////////////////////////////////////////////////////// */
111 /* Functions for populating "dot11f" style IEs */
112
113 /* return: >= 0, the starting location of the IE in rsnIEdata inside tSirRSNie */
114 /* < 0, cannot find */
find_ie_location(struct mac_context * mac,tpSirRSNie pRsnIe,uint8_t EID)115 int find_ie_location(struct mac_context *mac, tpSirRSNie pRsnIe, uint8_t EID)
116 {
117 int idx, ieLen, bytesLeft;
118 int ret_val = -1;
119
120 /* Here's what's going on: 'rsnIe' looks like this: */
121
122 /* typedef struct sSirRSNie */
123 /* { */
124 /* uint16_t length; */
125 /* uint8_t rsnIEdata[WLAN_MAX_IE_LEN+2]; */
126 /* } tSirRSNie, *tpSirRSNie; */
127
128 /* other code records both the WPA & RSN IEs (including their EIDs & */
129 /* lengths) into the array 'rsnIEdata'. We may have: */
130
131 /* With WAPI support, there may be 3 IEs here */
132 /* It can be only WPA IE, or only RSN IE or only WAPI IE */
133 /* Or two or all three of them with no particular ordering */
134
135 /* The if/then/else statements that follow are here to figure out */
136 /* whether we have the WPA IE, and where it is if we *do* have it. */
137
138 /* Save the first IE length */
139 ieLen = pRsnIe->rsnIEdata[1] + 2;
140 idx = 0;
141 bytesLeft = pRsnIe->length;
142
143 while (1) {
144 if (EID == pRsnIe->rsnIEdata[idx])
145 /* Found it */
146 return idx;
147 if (EID != pRsnIe->rsnIEdata[idx] &&
148 /* & if no more IE, */
149 bytesLeft <= (uint16_t)(ieLen))
150 return ret_val;
151
152 bytesLeft -= ieLen;
153 ieLen = pRsnIe->rsnIEdata[idx + 1] + 2;
154 idx += ieLen;
155 }
156
157 return ret_val;
158 }
159
160 QDF_STATUS
populate_dot11f_capabilities(struct mac_context * mac,tDot11fFfCapabilities * pDot11f,struct pe_session * pe_session)161 populate_dot11f_capabilities(struct mac_context *mac,
162 tDot11fFfCapabilities *pDot11f,
163 struct pe_session *pe_session)
164 {
165 uint16_t cfg;
166 QDF_STATUS nSirStatus;
167
168 nSirStatus = lim_get_capability_info(mac, &cfg, pe_session);
169 if (QDF_STATUS_SUCCESS != nSirStatus) {
170 pe_err("Failed to retrieve the Capabilities bitfield from CFG status: %d",
171 nSirStatus);
172 return nSirStatus;
173 }
174
175 swap_bit_field16(cfg, (uint16_t *) pDot11f);
176
177 return QDF_STATUS_SUCCESS;
178 } /* End populate_dot11f_capabilities. */
179
180 /**
181 * populate_dot_11_f_ext_chann_switch_ann() - Function to populate ECS
182 * @mac_ptr: Pointer to PMAC structure
183 * @dot_11_ptr: ECS element
184 * @session_entry: PE session entry
185 *
186 * This function is used to populate the extended channel switch element
187 *
188 * Return: None
189 */
populate_dot_11_f_ext_chann_switch_ann(struct mac_context * mac_ptr,tDot11fIEext_chan_switch_ann * dot_11_ptr,struct pe_session * session_entry)190 void populate_dot_11_f_ext_chann_switch_ann(struct mac_context *mac_ptr,
191 tDot11fIEext_chan_switch_ann *dot_11_ptr,
192 struct pe_session *session_entry)
193 {
194 uint8_t ch_offset;
195 uint32_t sw_target_freq;
196 uint8_t primary_channel;
197 enum phy_ch_width ch_width;
198
199 ch_width = session_entry->gLimChannelSwitch.ch_width;
200 ch_offset = session_entry->gLimChannelSwitch.sec_ch_offset;
201
202 dot_11_ptr->switch_mode = session_entry->gLimChannelSwitch.switchMode;
203 sw_target_freq = session_entry->gLimChannelSwitch.sw_target_freq;
204 primary_channel = session_entry->gLimChannelSwitch.primaryChannel;
205 dot_11_ptr->new_reg_class =
206 lim_op_class_from_bandwidth(mac_ptr, sw_target_freq, ch_width,
207 ch_offset);
208 dot_11_ptr->new_channel =
209 session_entry->gLimChannelSwitch.primaryChannel;
210 dot_11_ptr->switch_count =
211 session_entry->gLimChannelSwitch.switchCount;
212 dot_11_ptr->present = 1;
213 }
214
215 #define TIME_UNIT 1024 //time unit (TU): A measurement of time equal to 1024 us
216 void
populate_dot11f_max_chan_switch_time(struct mac_context * mac,tDot11fIEmax_chan_switch_time * pDot11f,struct pe_session * pe_session)217 populate_dot11f_max_chan_switch_time(struct mac_context *mac,
218 tDot11fIEmax_chan_switch_time *pDot11f,
219 struct pe_session *pe_session)
220 {
221 uint32_t switch_time = pe_session->cac_duration_ms;
222
223 if (!switch_time) {
224 pDot11f->present = 0;
225 return;
226 }
227
228 switch_time = qdf_do_div(switch_time * 1000, TIME_UNIT);
229
230 pDot11f->switch_time[0] = switch_time & 0xff;
231 pDot11f->switch_time[1] = (switch_time >> 8) & 0xff;
232 pDot11f->switch_time[2] = (switch_time >> 16) & 0xff;
233
234 pDot11f->present = 1;
235 }
236
populate_dot11f_non_inheritance(struct mac_context * mac_ctx,tDot11fIEnon_inheritance * non_inheritance,uint8_t * non_inher_ie_lists,uint8_t * non_inher_ext_ie_lists,uint8_t non_inher_len,uint8_t non_inher_ext_len)237 void populate_dot11f_non_inheritance(
238 struct mac_context *mac_ctx,
239 tDot11fIEnon_inheritance *non_inheritance,
240 uint8_t *non_inher_ie_lists,
241 uint8_t *non_inher_ext_ie_lists,
242 uint8_t non_inher_len, uint8_t non_inher_ext_len)
243 {
244 uint8_t *non_inher_data;
245
246 non_inher_data = non_inheritance->data;
247 non_inheritance->num_data = 0;
248 non_inheritance->present = 1;
249 *non_inher_data++ = non_inher_len;
250 non_inheritance->num_data++;
251 qdf_mem_copy(non_inher_data,
252 non_inher_ie_lists,
253 non_inher_len);
254 non_inher_data += non_inher_len;
255 non_inheritance->num_data += non_inher_len;
256 *non_inher_data++ = non_inher_ext_len;
257 non_inheritance->num_data++;
258 qdf_mem_copy(non_inher_data,
259 non_inher_ext_ie_lists,
260 non_inher_ext_len);
261 non_inheritance->num_data += non_inher_ext_len;
262 }
263
264 void
populate_dot11f_chan_switch_ann(struct mac_context * mac,tDot11fIEChanSwitchAnn * pDot11f,struct pe_session * pe_session)265 populate_dot11f_chan_switch_ann(struct mac_context *mac,
266 tDot11fIEChanSwitchAnn *pDot11f,
267 struct pe_session *pe_session)
268 {
269 pDot11f->switchMode = pe_session->gLimChannelSwitch.switchMode;
270 pDot11f->newChannel = pe_session->gLimChannelSwitch.primaryChannel;
271 pDot11f->switchCount =
272 (uint8_t) pe_session->gLimChannelSwitch.switchCount;
273
274 pDot11f->present = 1;
275 }
276
277 /**
278 * populate_dot11_supp_operating_classes() - Function to populate supported
279 * operating class IE
280 * @mac_ptr: Pointer to PMAC structure
281 * @dot_11_ptr: Operating class element
282 * @session_entry: PE session entry
283 *
284 * Return: None
285 */
286 void
populate_dot11_supp_operating_classes(struct mac_context * mac_ptr,tDot11fIESuppOperatingClasses * dot_11_ptr,struct pe_session * session_entry)287 populate_dot11_supp_operating_classes(struct mac_context *mac_ptr,
288 tDot11fIESuppOperatingClasses *dot_11_ptr,
289 struct pe_session *session_entry)
290 {
291 uint8_t ch_offset;
292
293 if (session_entry->ch_width == CH_WIDTH_80MHZ) {
294 ch_offset = BW80;
295 } else {
296 switch (session_entry->htSecondaryChannelOffset) {
297 case PHY_DOUBLE_CHANNEL_HIGH_PRIMARY:
298 ch_offset = BW40_HIGH_PRIMARY;
299 break;
300 case PHY_DOUBLE_CHANNEL_LOW_PRIMARY:
301 ch_offset = BW40_LOW_PRIMARY;
302 break;
303 default:
304 ch_offset = BW20;
305 break;
306 }
307 }
308
309 wlan_reg_dmn_get_curr_opclasses(&dot_11_ptr->num_classes,
310 &dot_11_ptr->classes[1]);
311 dot_11_ptr->classes[0] =
312 lim_op_class_from_bandwidth(mac_ptr,
313 session_entry->curr_op_freq,
314 session_entry->ch_width,
315 ch_offset);
316 dot_11_ptr->num_classes++;
317 dot_11_ptr->present = 1;
318 }
319
320 void
populate_dot11f_tx_power_env(struct mac_context * mac,tDot11fIEtransmit_power_env * tpe_ptr,enum phy_ch_width chan_width,uint32_t chan_freq,uint16_t * num_tpe,bool is_chan_switch)321 populate_dot11f_tx_power_env(struct mac_context *mac,
322 tDot11fIEtransmit_power_env *tpe_ptr,
323 enum phy_ch_width chan_width, uint32_t chan_freq,
324 uint16_t *num_tpe, bool is_chan_switch)
325 {
326 uint8_t count;
327 uint16_t eirp_power, reg_power;
328 int power_for_bss;
329 bool add_eirp_power = false;
330 struct ch_params chan_params;
331 bool psd_tpe = false;
332 uint32_t bw_threshold, bw_val;
333 int num_tpe_ies = 0;
334 uint32_t num_tx_power, num_tx_power_psd;
335 uint32_t max_tx_pwr_count, max_tx_pwr_count_psd;
336 qdf_freq_t psd_start_freq;
337
338 if (!wlan_reg_is_6ghz_chan_freq(chan_freq)) {
339 psd_tpe = false;
340 } else {
341 wlan_reg_get_client_power_for_6ghz_ap(mac->pdev,
342 REG_DEFAULT_CLIENT,
343 chan_freq,
344 &psd_tpe,
345 ®_power, &eirp_power);
346 pe_debug("chan_freq %d, reg_power %d, psd_power %d",
347 chan_freq, reg_power, eirp_power);
348 }
349
350 switch (chan_width) {
351 case CH_WIDTH_20MHZ:
352 max_tx_pwr_count = 0;
353 max_tx_pwr_count_psd = 1;
354 num_tx_power = 1;
355 num_tx_power_psd = 1;
356 break;
357
358 case CH_WIDTH_40MHZ:
359 max_tx_pwr_count = 1;
360 max_tx_pwr_count_psd = 2;
361 num_tx_power = 2;
362 num_tx_power_psd = 2;
363 break;
364
365 case CH_WIDTH_80MHZ:
366 max_tx_pwr_count = 2;
367 max_tx_pwr_count_psd = 3;
368 num_tx_power = 3;
369 num_tx_power_psd = 4;
370 break;
371
372 case CH_WIDTH_160MHZ:
373 case CH_WIDTH_80P80MHZ:
374 max_tx_pwr_count = 3;
375 max_tx_pwr_count_psd = 4;
376 num_tx_power = 4;
377 num_tx_power_psd = 8;
378 break;
379 default:
380 return;
381 }
382
383 if (!psd_tpe) {
384 reg_power = wlan_reg_get_channel_reg_power_for_freq(
385 mac->pdev, chan_freq);
386
387 tpe_ptr->present = 1;
388 tpe_ptr->max_tx_pwr_count = max_tx_pwr_count;
389 tpe_ptr->max_tx_pwr_interpret = 0;
390 tpe_ptr->max_tx_pwr_category = 0;
391 tpe_ptr->num_tx_power = num_tx_power;
392 for (count = 0; count < num_tx_power; count++)
393 tpe_ptr->tx_power[count] = reg_power;
394
395 num_tpe_ies++;
396 tpe_ptr++;
397 } else {
398
399 bw_val = wlan_reg_get_bw_value(chan_width);
400 bw_threshold = 20;
401 power_for_bss = eirp_power + 13;
402
403 while ((reg_power > power_for_bss) &&
404 (bw_threshold < bw_val)) {
405 bw_threshold = 2 * bw_threshold;
406 power_for_bss += 3;
407 }
408 if (bw_threshold < bw_val)
409 add_eirp_power = true;
410
411 pe_debug("bw_threshold %d", bw_threshold);
412
413 if (add_eirp_power) {
414 tpe_ptr->present = 1;
415 tpe_ptr->max_tx_pwr_count = max_tx_pwr_count;
416 tpe_ptr->max_tx_pwr_interpret = 2;
417 tpe_ptr->max_tx_pwr_category = 0;
418 tpe_ptr->num_tx_power = num_tx_power;
419 for (count = 0; count < num_tx_power; count++) {
420 tpe_ptr->tx_power[count] = reg_power * 2;
421 pe_debug("non-psd default TPE %d %d",
422 count, tpe_ptr->tx_power[count]);
423 }
424 num_tpe_ies++;
425 tpe_ptr++;
426 }
427
428 wlan_reg_get_client_power_for_6ghz_ap(mac->pdev,
429 REG_SUBORDINATE_CLIENT,
430 chan_freq,
431 &psd_tpe,
432 ®_power,
433 &eirp_power);
434
435 if (reg_power) {
436 bw_val = wlan_reg_get_bw_value(chan_width);
437 bw_threshold = 20;
438 power_for_bss = eirp_power + 13;
439
440 while ((reg_power > power_for_bss) &&
441 (bw_threshold < bw_val)) {
442 bw_threshold = 2 * bw_threshold;
443 power_for_bss += 3;
444 }
445 if (bw_threshold < bw_val)
446 add_eirp_power = true;
447
448 if (add_eirp_power) {
449 tpe_ptr->present = 1;
450 tpe_ptr->max_tx_pwr_count = max_tx_pwr_count;
451 tpe_ptr->max_tx_pwr_interpret = 2;
452 tpe_ptr->max_tx_pwr_category = 1;
453 tpe_ptr->num_tx_power = num_tx_power;
454 for (count = 0; count < num_tx_power; count++) {
455 tpe_ptr->tx_power[count] =
456 reg_power * 2;
457 pe_debug("non-psd subord TPE %d %d",
458 count,
459 tpe_ptr->tx_power[count]);
460 }
461 num_tpe_ies++;
462 tpe_ptr++;
463 }
464 }
465
466 tpe_ptr->present = 1;
467 tpe_ptr->max_tx_pwr_count = max_tx_pwr_count_psd;
468 tpe_ptr->max_tx_pwr_interpret = 3;
469 tpe_ptr->max_tx_pwr_category = 0;
470 tpe_ptr->num_tx_power = num_tx_power_psd;
471
472 chan_params.ch_width = chan_width;
473 bw_val = wlan_reg_get_bw_value(chan_width);
474 wlan_reg_set_channel_params_for_pwrmode(mac->pdev, chan_freq,
475 chan_freq, &chan_params,
476 REG_CURRENT_PWR_MODE);
477
478 if (chan_params.mhz_freq_seg1)
479 psd_start_freq =
480 chan_params.mhz_freq_seg1 - bw_val / 2 + 10;
481 else
482 psd_start_freq =
483 chan_params.mhz_freq_seg0 - bw_val / 2 + 10;
484
485 for (count = 0; count < num_tx_power_psd; count++) {
486 wlan_reg_get_client_power_for_6ghz_ap(
487 mac->pdev,
488 REG_DEFAULT_CLIENT,
489 psd_start_freq +
490 20 * count,
491 &psd_tpe,
492 ®_power,
493 &eirp_power);
494 tpe_ptr->tx_power[count] = eirp_power * 2;
495 pe_debug("psd default TPE %d %d",
496 count, tpe_ptr->tx_power[count]);
497 }
498 num_tpe_ies++;
499 tpe_ptr++;
500
501 wlan_reg_get_client_power_for_6ghz_ap(mac->pdev,
502 REG_SUBORDINATE_CLIENT,
503 chan_freq,
504 &psd_tpe,
505 ®_power,
506 &eirp_power);
507
508 if (eirp_power) {
509 tpe_ptr->present = 1;
510 tpe_ptr->max_tx_pwr_count = max_tx_pwr_count_psd;
511 tpe_ptr->max_tx_pwr_interpret = 3;
512 tpe_ptr->max_tx_pwr_category = 1;
513 tpe_ptr->num_tx_power = num_tx_power_psd;
514
515 for (count = 0; count < num_tx_power_psd; count++) {
516 wlan_reg_get_client_power_for_6ghz_ap(
517 mac->pdev,
518 REG_SUBORDINATE_CLIENT,
519 psd_start_freq +
520 20 * count,
521 &psd_tpe,
522 ®_power,
523 &eirp_power);
524 tpe_ptr->tx_power[count] = eirp_power * 2;
525 pe_debug("psd subord TPE %d %d",
526 count, tpe_ptr->tx_power[count]);
527 }
528 num_tpe_ies++;
529 tpe_ptr++;
530 }
531 }
532 *num_tpe = num_tpe_ies;
533 }
534
535 void
populate_dot11f_chan_switch_wrapper(struct mac_context * mac,tDot11fIEChannelSwitchWrapper * pDot11f,struct pe_session * pe_session)536 populate_dot11f_chan_switch_wrapper(struct mac_context *mac,
537 tDot11fIEChannelSwitchWrapper *pDot11f,
538 struct pe_session *pe_session)
539 {
540 uint16_t num_tpe;
541 /*
542 * The new country subelement is present only when
543 * 1. AP performs Extended Channel switching to new country.
544 * 2. New Operating Class table or a changed set of operating
545 * classes relative to the contents of the country element sent
546 * in the beacons.
547 *
548 * In the current scenario Channel Switch wrapper IE is included
549 * when we a radar is found and the AP does a channel change in
550 * the same regulatory domain(No country change or Operating class
551 * table). So, we do not need to include the New Country IE.
552 *
553 * Transmit Power Envlope Subelement is optional
554 * in Channel Switch Wrapper IE. So, not setting
555 * the TPE subelement. We include only WiderBWChanSwitchAnn.
556 */
557 pDot11f->present = 1;
558
559 /*
560 * Add the Wide Channel Bandwidth Sublement.
561 */
562 pDot11f->WiderBWChanSwitchAnn.newChanWidth =
563 pe_session->gLimWiderBWChannelSwitch.newChanWidth;
564 pDot11f->WiderBWChanSwitchAnn.newCenterChanFreq0 =
565 pe_session->gLimWiderBWChannelSwitch.newCenterChanFreq0;
566 pDot11f->WiderBWChanSwitchAnn.newCenterChanFreq1 =
567 pe_session->gLimWiderBWChannelSwitch.newCenterChanFreq1;
568 pDot11f->WiderBWChanSwitchAnn.present = 1;
569
570 /*
571 * Add the Transmit power Envelope Sublement.
572 */
573 if (pe_session->vhtCapability) {
574 populate_dot11f_tx_power_env(mac,
575 &pDot11f->transmit_power_env,
576 pe_session->gLimChannelSwitch.ch_width,
577 pe_session->gLimChannelSwitch.sw_target_freq,
578 &num_tpe, true);
579 }
580 }
581
582 #ifdef FEATURE_AP_MCC_CH_AVOIDANCE
583 void
populate_dot11f_avoid_channel_ie(struct mac_context * mac_ctx,tDot11fIEQComVendorIE * dot11f,struct pe_session * pe_session)584 populate_dot11f_avoid_channel_ie(struct mac_context *mac_ctx,
585 tDot11fIEQComVendorIE *dot11f,
586 struct pe_session *pe_session)
587 {
588 if (!pe_session->sap_advertise_avoid_ch_ie)
589 return;
590
591 dot11f->present = true;
592 dot11f->type = QCOM_VENDOR_IE_MCC_AVOID_CH;
593 dot11f->channel = wlan_reg_freq_to_chan(
594 mac_ctx->pdev, pe_session->curr_op_freq);
595 }
596 #endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
597
598 QDF_STATUS
populate_dot11f_country(struct mac_context * mac,tDot11fIECountry * ctry_ie,struct pe_session * pe_session)599 populate_dot11f_country(struct mac_context *mac,
600 tDot11fIECountry *ctry_ie, struct pe_session *pe_session)
601 {
602 uint8_t code[REG_ALPHA2_LEN + 1];
603 uint8_t cur_triplet_num_chans = 0;
604 int chan_enum, chan_num;
605 struct regulatory_channel *sec_cur_chan_list;
606 struct regulatory_channel *cur_chan, *start, *prev;
607 uint8_t buffer_triplets[81][3];
608 uint8_t i, j, num_triplets = 0;
609 QDF_STATUS status = QDF_STATUS_SUCCESS;
610 bool six_gig_started = false;
611 uint8_t band_bitmap;
612 uint32_t band_capability;
613 uint8_t chan_spacing_for_2ghz = 1;
614 uint8_t chan_spacing_for_5ghz_6ghz = 4;
615 struct mlme_legacy_priv *mlme_priv = NULL;
616
617 sec_cur_chan_list = qdf_mem_malloc(NUM_CHANNELS *
618 sizeof(*sec_cur_chan_list));
619 if (!sec_cur_chan_list)
620 return QDF_STATUS_E_NOMEM;
621
622 if (pe_session) {
623 mlme_priv = wlan_vdev_mlme_get_ext_hdl(pe_session->vdev);
624 if (!mlme_priv) {
625 pe_err("Invalid mlme priv object");
626 status = QDF_STATUS_E_FAILURE;
627 goto out;
628 }
629 }
630
631 if (!pe_session ||
632 (mlme_priv && mlme_priv->country_ie_for_all_band)) {
633 status = wlan_mlme_get_band_capability(mac->psoc,
634 &band_capability);
635 if (QDF_IS_STATUS_ERROR(status)) {
636 pe_err("Failed to get MLME Band Capability");
637 goto out;
638 }
639 band_bitmap = (uint8_t)band_capability;
640 } else {
641 if (pe_session->limRFBand == REG_BAND_UNKNOWN) {
642 pe_err("Wrong reg band for country info");
643 status = QDF_STATUS_E_FAILURE;
644 goto out;
645 }
646 band_bitmap = BIT(pe_session->limRFBand);
647 }
648
649 chan_num = wlan_reg_get_secondary_band_channel_list(
650 mac->pdev,
651 band_bitmap,
652 sec_cur_chan_list);
653 if (!chan_num) {
654 pe_err("failed to get cur_chan list");
655 status = QDF_STATUS_E_FAILURE;
656 goto out;
657 }
658
659 wlan_reg_read_current_country(mac->psoc, code);
660 qdf_mem_copy(ctry_ie->country, code, REG_ALPHA2_LEN);
661
662 /* advertise global operating class */
663 ctry_ie->country[REG_ALPHA2_LEN] = 0x04;
664
665 start = NULL;
666 prev = NULL;
667 for (chan_enum = 0; chan_enum < chan_num; chan_enum++) {
668 cur_chan = &sec_cur_chan_list[chan_enum];
669
670 if (cur_chan->chan_flags & REGULATORY_CHAN_DISABLED)
671 continue;
672
673 if (wlan_reg_is_6ghz_chan_freq(cur_chan->center_freq) &&
674 !six_gig_started) {
675 buffer_triplets[num_triplets][0] = OP_CLASS_ID_201;
676 buffer_triplets[num_triplets][1] = OP_CLASS_131;
677 num_triplets++;
678 six_gig_started = true;
679 }
680
681 if (start && prev &&
682 ((prev->chan_num + chan_spacing_for_2ghz ==
683 cur_chan->chan_num) ||
684 (prev->chan_num + chan_spacing_for_5ghz_6ghz ==
685 cur_chan->chan_num)) &&
686 start->tx_power == cur_chan->tx_power) {
687 /* Can use same entry */
688 prev = cur_chan;
689 cur_triplet_num_chans++;
690 continue;
691 }
692
693 if (start && prev) {
694 /* Save as entry */
695 buffer_triplets[num_triplets][0] = start->chan_num;
696 buffer_triplets[num_triplets][1] =
697 cur_triplet_num_chans + 1;
698 buffer_triplets[num_triplets][2] = start->tx_power;
699 start = NULL;
700 cur_triplet_num_chans = 0;
701
702 num_triplets++;
703 if (num_triplets > 80) {
704 pe_err("Triplets number exceed max size");
705 status = QDF_STATUS_E_FAILURE;
706 goto out;
707 }
708 }
709
710 if ((chan_enum == NUM_CHANNELS - 1) && (six_gig_started)) {
711 buffer_triplets[num_triplets][0] = OP_CLASS_ID_201;
712 buffer_triplets[num_triplets][1] = OP_CLASS_132;
713 num_triplets++;
714
715 buffer_triplets[num_triplets][0] = OP_CLASS_ID_201;
716 buffer_triplets[num_triplets][1] = OP_CLASS_133;
717 num_triplets++;
718
719 buffer_triplets[num_triplets][0] = OP_CLASS_ID_201;
720 buffer_triplets[num_triplets][1] = OP_CLASS_134;
721 num_triplets++;
722 }
723
724 /* Start new group */
725 start = cur_chan;
726 prev = cur_chan;
727 }
728
729 if (start) {
730 buffer_triplets[num_triplets][0] = start->chan_num;
731 buffer_triplets[num_triplets][1] = cur_triplet_num_chans + 1;
732 buffer_triplets[num_triplets][2] = start->tx_power;
733 num_triplets++;
734 }
735
736 if (!num_triplets) {
737 /* at-least one triplet should be present */
738 pe_err("No triplet present");
739 status = QDF_STATUS_E_FAILURE;
740 goto out;
741 }
742
743 ctry_ie->num_more_triplets = num_triplets - 1;
744 ctry_ie->first_triplet[0] = buffer_triplets[0][0];
745 ctry_ie->first_triplet[1] = buffer_triplets[0][1];
746 ctry_ie->first_triplet[2] = buffer_triplets[0][2];
747
748 for (i = 0; i < ctry_ie->num_more_triplets; i++) {
749 for (j = 0; j < 3; j++) {
750 ctry_ie->more_triplets[i][j] = buffer_triplets[i+1][j];
751 }
752 }
753 ctry_ie->present = 1;
754
755 out:
756 qdf_mem_free(sec_cur_chan_list);
757 return status;
758 } /* End populate_dot11f_country. */
759
760 /**
761 * populate_dot11f_ds_params() - To populate DS IE params
762 * @mac_ctx: Pointer to global mac context
763 * @dot11f_param: pointer to DS params IE
764 * @freq: freq
765 *
766 * This routine will populate DS param in management frame like
767 * beacon, probe response, and etc.
768 *
769 * Return: Overall success
770 */
771 QDF_STATUS
populate_dot11f_ds_params(struct mac_context * mac_ctx,tDot11fIEDSParams * dot11f_param,qdf_freq_t freq)772 populate_dot11f_ds_params(struct mac_context *mac_ctx,
773 tDot11fIEDSParams *dot11f_param, qdf_freq_t freq)
774 {
775 if (WLAN_REG_IS_24GHZ_CH_FREQ(freq)) {
776 /* .11b/g mode PHY => Include the DS Parameter Set IE: */
777 dot11f_param->curr_channel = wlan_reg_freq_to_chan(
778 mac_ctx->pdev,
779 freq);
780 dot11f_param->present = 1;
781 }
782
783 return QDF_STATUS_SUCCESS;
784 }
785
786 #define SET_AIFSN(aifsn) (((aifsn) < 2) ? 2 : (aifsn))
787
788 void
populate_dot11f_edca_param_set(struct mac_context * mac,tDot11fIEEDCAParamSet * pDot11f,struct pe_session * pe_session)789 populate_dot11f_edca_param_set(struct mac_context *mac,
790 tDot11fIEEDCAParamSet *pDot11f,
791 struct pe_session *pe_session)
792 {
793
794 if (pe_session->limQosEnabled) {
795 /* change to bitwise operation, after this is fixed in frames. */
796 pDot11f->qos =
797 (uint8_t) (0xf0 &
798 (pe_session->gLimEdcaParamSetCount << 4));
799
800 /* Fill each EDCA parameter set in order: be, bk, vi, vo */
801 pDot11f->acbe_aifsn =
802 (0xf &
803 SET_AIFSN(pe_session->gLimEdcaParamsBC[0].aci.aifsn));
804 pDot11f->acbe_acm =
805 (0x1 & pe_session->gLimEdcaParamsBC[0].aci.acm);
806 pDot11f->acbe_aci = (0x3 & QCA_WLAN_AC_BE);
807 pDot11f->acbe_acwmin =
808 (0xf & pe_session->gLimEdcaParamsBC[0].cw.min);
809 pDot11f->acbe_acwmax =
810 (0xf & pe_session->gLimEdcaParamsBC[0].cw.max);
811 pDot11f->acbe_txoplimit =
812 pe_session->gLimEdcaParamsBC[0].txoplimit;
813
814 pDot11f->acbk_aifsn =
815 (0xf &
816 SET_AIFSN(pe_session->gLimEdcaParamsBC[1].aci.aifsn));
817 pDot11f->acbk_acm =
818 (0x1 & pe_session->gLimEdcaParamsBC[1].aci.acm);
819 pDot11f->acbk_aci = (0x3 & QCA_WLAN_AC_BK);
820 pDot11f->acbk_acwmin =
821 (0xf & pe_session->gLimEdcaParamsBC[1].cw.min);
822 pDot11f->acbk_acwmax =
823 (0xf & pe_session->gLimEdcaParamsBC[1].cw.max);
824 pDot11f->acbk_txoplimit =
825 pe_session->gLimEdcaParamsBC[1].txoplimit;
826
827 pDot11f->acvi_aifsn =
828 (0xf &
829 SET_AIFSN(pe_session->gLimEdcaParamsBC[2].aci.aifsn));
830 pDot11f->acvi_acm =
831 (0x1 & pe_session->gLimEdcaParamsBC[2].aci.acm);
832 pDot11f->acvi_aci = (0x3 & QCA_WLAN_AC_VI);
833 pDot11f->acvi_acwmin =
834 (0xf & pe_session->gLimEdcaParamsBC[2].cw.min);
835 pDot11f->acvi_acwmax =
836 (0xf & pe_session->gLimEdcaParamsBC[2].cw.max);
837 pDot11f->acvi_txoplimit =
838 pe_session->gLimEdcaParamsBC[2].txoplimit;
839
840 pDot11f->acvo_aifsn =
841 (0xf &
842 SET_AIFSN(pe_session->gLimEdcaParamsBC[3].aci.aifsn));
843 pDot11f->acvo_acm =
844 (0x1 & pe_session->gLimEdcaParamsBC[3].aci.acm);
845 pDot11f->acvo_aci = (0x3 & QCA_WLAN_AC_VO);
846 pDot11f->acvo_acwmin =
847 (0xf & pe_session->gLimEdcaParamsBC[3].cw.min);
848 pDot11f->acvo_acwmax =
849 (0xf & pe_session->gLimEdcaParamsBC[3].cw.max);
850 pDot11f->acvo_txoplimit =
851 pe_session->gLimEdcaParamsBC[3].txoplimit;
852
853 pDot11f->present = 1;
854 }
855
856 } /* End PopluateDot11fEDCAParamSet. */
857
858 QDF_STATUS
populate_dot11f_erp_info(struct mac_context * mac,tDot11fIEERPInfo * pDot11f,struct pe_session * pe_session)859 populate_dot11f_erp_info(struct mac_context *mac,
860 tDot11fIEERPInfo *pDot11f, struct pe_session *pe_session)
861 {
862 uint32_t val;
863 enum reg_wifi_band rfBand = REG_BAND_UNKNOWN;
864
865 lim_get_rf_band_new(mac, &rfBand, pe_session);
866 if (REG_BAND_2G == rfBand) {
867 pDot11f->present = 1;
868
869 val = pe_session->cfgProtection.fromllb;
870 if (!val) {
871 pe_err("11B protection not enabled. Not populating ERP IE %d",
872 val);
873 return QDF_STATUS_SUCCESS;
874 }
875
876 if (pe_session->gLim11bParams.protectionEnabled) {
877 pDot11f->non_erp_present = 1;
878 pDot11f->use_prot = 1;
879 }
880
881 if (pe_session->gLimOlbcParams.protectionEnabled) {
882 /* FIXME_PROTECTION: we should be setting non_erp present also. */
883 /* check the test plan first. */
884 pDot11f->use_prot = 1;
885 }
886
887 if ((pe_session->gLimNoShortParams.numNonShortPreambleSta)
888 || !pe_session->beaconParams.fShortPreamble) {
889 pDot11f->barker_preamble = 1;
890
891 }
892 }
893
894 return QDF_STATUS_SUCCESS;
895 } /* End populate_dot11f_erp_info. */
896
897 QDF_STATUS
populate_dot11f_ext_supp_rates(struct mac_context * mac,uint8_t nChannelNum,tDot11fIEExtSuppRates * pDot11f,struct pe_session * pe_session)898 populate_dot11f_ext_supp_rates(struct mac_context *mac, uint8_t nChannelNum,
899 tDot11fIEExtSuppRates *pDot11f,
900 struct pe_session *pe_session)
901 {
902 qdf_size_t n_rates = 0;
903 uint8_t rates[SIR_MAC_MAX_NUMBER_OF_RATES];
904
905 /* Use the ext rates present in session entry whenever nChannelNum is set to OPERATIONAL
906 else use the ext supported rate set from CFG, which is fixed and does not change dynamically and is used for
907 sending mgmt frames (lile probe req) which need to go out before any session is present.
908 */
909 if (POPULATE_DOT11F_RATES_OPERATIONAL == nChannelNum) {
910 if (pe_session) {
911 n_rates = pe_session->extRateSet.numRates;
912 qdf_mem_copy(rates, pe_session->extRateSet.rate,
913 n_rates);
914 } else {
915 pe_err("no session context exists while populating Operational Rate Set");
916 }
917 } else if (HIGHEST_24GHZ_CHANNEL_NUM >= nChannelNum) {
918 if (!pe_session) {
919 pe_err("null pe_session");
920 return QDF_STATUS_E_INVAL;
921 }
922
923 n_rates = mlme_get_ext_opr_rate(pe_session->vdev, rates,
924 sizeof(rates));
925 }
926
927 if (0 != n_rates) {
928 pe_debug("ext supp rates present, num %d", (uint8_t)n_rates);
929 pDot11f->num_rates = (uint8_t)n_rates;
930 qdf_mem_copy(pDot11f->rates, rates, n_rates);
931 pDot11f->present = 1;
932 }
933
934 return QDF_STATUS_SUCCESS;
935
936 } /* End populate_dot11f_ext_supp_rates. */
937
938 QDF_STATUS
populate_dot11f_ext_supp_rates1(struct mac_context * mac,uint8_t nChannelNum,tDot11fIEExtSuppRates * pDot11f)939 populate_dot11f_ext_supp_rates1(struct mac_context *mac,
940 uint8_t nChannelNum,
941 tDot11fIEExtSuppRates *pDot11f)
942 {
943 qdf_size_t nRates;
944 QDF_STATUS nsir_status;
945 uint8_t rates[SIR_MAC_MAX_NUMBER_OF_RATES];
946
947 if (14 < nChannelNum) {
948 pDot11f->present = 0;
949 return QDF_STATUS_SUCCESS;
950 }
951 /* N.B. I have *no* idea why we're calling 'wlan_cfg_get_str' with an argument */
952 /* of WNI_CFG_SUPPORTED_RATES_11A here, but that's what was done */
953 /* previously & I'm afraid to change it! */
954 nRates = SIR_MAC_MAX_NUMBER_OF_RATES;
955 nsir_status = wlan_mlme_get_cfg_str(
956 rates,
957 &mac->mlme_cfg->rates.supported_11a,
958 &nRates);
959 if (QDF_IS_STATUS_ERROR(nsir_status)) {
960 pe_err("Failed to retrieve nItem from CFG status: %d",
961 (nsir_status));
962 return nsir_status;
963 }
964
965 if (0 != nRates) {
966 pDot11f->num_rates = (uint8_t) nRates;
967 qdf_mem_copy(pDot11f->rates, rates, nRates);
968 pDot11f->present = 1;
969 }
970
971 return QDF_STATUS_SUCCESS;
972 } /* populate_dot11f_ext_supp_rates1. */
973
974 QDF_STATUS
populate_dot11f_ht_caps(struct mac_context * mac,struct pe_session * pe_session,tDot11fIEHTCaps * pDot11f)975 populate_dot11f_ht_caps(struct mac_context *mac,
976 struct pe_session *pe_session, tDot11fIEHTCaps *pDot11f)
977 {
978 qdf_size_t ncfglen;
979 QDF_STATUS nSirStatus;
980 uint8_t disable_high_ht_mcs_2x2 = 0;
981 struct ch_params ch_params = {0};
982 uint8_t cb_mode;
983
984 tSirMacTxBFCapabilityInfo *pTxBFCapabilityInfo;
985 tSirMacASCapabilityInfo *pASCapabilityInfo;
986 struct mlme_ht_capabilities_info *ht_cap_info;
987 struct mlme_vht_capabilities_info *vht_cap_info;
988
989 ht_cap_info = &mac->mlme_cfg->ht_caps.ht_cap_info;
990 vht_cap_info = &mac->mlme_cfg->vht_caps.vht_cap_info;
991
992 pDot11f->mimoPowerSave = ht_cap_info->mimo_power_save;
993 pDot11f->greenField = ht_cap_info->green_field;
994 pDot11f->delayedBA = ht_cap_info->delayed_ba;
995 pDot11f->maximalAMSDUsize = ht_cap_info->maximal_amsdu_size;
996 pDot11f->dsssCckMode40MHz = ht_cap_info->dsss_cck_mode_40_mhz;
997 pDot11f->psmp = ht_cap_info->psmp;
998 pDot11f->stbcControlFrame = ht_cap_info->stbc_control_frame;
999 pDot11f->lsigTXOPProtection = ht_cap_info->l_sig_tx_op_protection;
1000
1001 /* All sessionized entries will need the check below */
1002 if (!pe_session) { /* Only in case of NO session */
1003 pDot11f->supportedChannelWidthSet =
1004 ht_cap_info->supported_channel_width_set;
1005 pDot11f->advCodingCap = ht_cap_info->adv_coding_cap;
1006 pDot11f->txSTBC = ht_cap_info->tx_stbc;
1007 pDot11f->rxSTBC = ht_cap_info->rx_stbc;
1008 pDot11f->shortGI20MHz = ht_cap_info->short_gi_20_mhz;
1009 pDot11f->shortGI40MHz = ht_cap_info->short_gi_40_mhz;
1010 } else {
1011 cb_mode = lim_get_cb_mode_for_freq(mac, pe_session,
1012 pe_session->curr_op_freq);
1013 if (WLAN_REG_IS_24GHZ_CH_FREQ(pe_session->curr_op_freq) &&
1014 LIM_IS_STA_ROLE(pe_session) &&
1015 cb_mode != WNI_CFG_CHANNEL_BONDING_MODE_DISABLE) {
1016 pDot11f->supportedChannelWidthSet = 1;
1017 ch_params.ch_width = CH_WIDTH_40MHZ;
1018 wlan_reg_set_channel_params_for_pwrmode(
1019 mac->pdev, pe_session->curr_op_freq, 0,
1020 &ch_params, REG_CURRENT_PWR_MODE);
1021 if (ch_params.ch_width != CH_WIDTH_40MHZ)
1022 pDot11f->supportedChannelWidthSet = 0;
1023 } else if (LIM_IS_STA_ROLE(pe_session)) {
1024 if (pe_session->ch_width == CH_WIDTH_20MHZ)
1025 pDot11f->supportedChannelWidthSet = 0;
1026 else
1027 pDot11f->supportedChannelWidthSet = 1;
1028 } else {
1029 pDot11f->supportedChannelWidthSet =
1030 pe_session->htSupportedChannelWidthSet;
1031 }
1032
1033 pDot11f->advCodingCap = pe_session->ht_config.adv_coding_cap;
1034 pDot11f->txSTBC = pe_session->ht_config.tx_stbc;
1035 pDot11f->rxSTBC = pe_session->ht_config.rx_stbc;
1036 pDot11f->shortGI20MHz = pe_session->ht_config.short_gi_20_mhz;
1037 pDot11f->shortGI40MHz = pe_session->ht_config.short_gi_40_mhz;
1038 }
1039
1040 /* Ensure that shortGI40MHz is Disabled if supportedChannelWidthSet is
1041 eHT_CHANNEL_WIDTH_20MHZ */
1042 if (pDot11f->supportedChannelWidthSet == eHT_CHANNEL_WIDTH_20MHZ) {
1043 pDot11f->shortGI40MHz = 0;
1044 }
1045
1046 pDot11f->maxRxAMPDUFactor =
1047 mac->mlme_cfg->ht_caps.ampdu_params.max_rx_ampdu_factor;
1048 pDot11f->mpduDensity =
1049 mac->mlme_cfg->ht_caps.ampdu_params.mpdu_density;
1050 pDot11f->reserved1 = mac->mlme_cfg->ht_caps.ampdu_params.reserved;
1051
1052 ncfglen = SIZE_OF_SUPPORTED_MCS_SET;
1053 nSirStatus = wlan_mlme_get_cfg_str(
1054 pDot11f->supportedMCSSet,
1055 &mac->mlme_cfg->rates.supported_mcs_set,
1056 &ncfglen);
1057 if (QDF_IS_STATUS_ERROR(nSirStatus)) {
1058 pe_err("Failed to retrieve nItem from CFG status: %d",
1059 (nSirStatus));
1060 return nSirStatus;
1061 }
1062
1063 if (pe_session) {
1064 disable_high_ht_mcs_2x2 =
1065 mac->mlme_cfg->rates.disable_high_ht_mcs_2x2;
1066 if (pe_session->nss == NSS_1x1_MODE) {
1067 pDot11f->supportedMCSSet[1] = 0;
1068 pDot11f->txSTBC = 0;
1069 } else if (wlan_reg_is_24ghz_ch_freq(
1070 pe_session->curr_op_freq) &&
1071 disable_high_ht_mcs_2x2 &&
1072 (pe_session->opmode == QDF_STA_MODE)) {
1073 pe_debug("Disabling high HT MCS [%d]",
1074 disable_high_ht_mcs_2x2);
1075 pDot11f->supportedMCSSet[1] =
1076 (pDot11f->supportedMCSSet[1] >>
1077 disable_high_ht_mcs_2x2);
1078 }
1079 }
1080
1081 /* If STA mode, session supported NSS > 1 and
1082 * SMPS enabled publish HT SMPS IE
1083 */
1084 if (pe_session &&
1085 LIM_IS_STA_ROLE(pe_session) &&
1086 (mac->mlme_cfg->ht_caps.enable_smps) &&
1087 (!pe_session->supported_nss_1x1)) {
1088 pe_debug("Add SM power save IE: %d",
1089 mac->mlme_cfg->ht_caps.smps);
1090 pDot11f->mimoPowerSave = mac->mlme_cfg->ht_caps.smps;
1091 }
1092
1093 pDot11f->pco = mac->mlme_cfg->ht_caps.ext_cap_info.pco;
1094 pDot11f->transitionTime =
1095 mac->mlme_cfg->ht_caps.ext_cap_info.transition_time;
1096 pDot11f->mcsFeedback =
1097 mac->mlme_cfg->ht_caps.ext_cap_info.mcs_feedback;
1098
1099 pTxBFCapabilityInfo =
1100 (tSirMacTxBFCapabilityInfo *)&vht_cap_info->tx_bf_cap;
1101 pDot11f->txBF = pTxBFCapabilityInfo->txBF;
1102 pDot11f->rxStaggeredSounding = pTxBFCapabilityInfo->rxStaggeredSounding;
1103 pDot11f->txStaggeredSounding = pTxBFCapabilityInfo->txStaggeredSounding;
1104 pDot11f->rxZLF = pTxBFCapabilityInfo->rxZLF;
1105 pDot11f->txZLF = pTxBFCapabilityInfo->txZLF;
1106 pDot11f->implicitTxBF = pTxBFCapabilityInfo->implicitTxBF;
1107 pDot11f->calibration = pTxBFCapabilityInfo->calibration;
1108 pDot11f->explicitCSITxBF = pTxBFCapabilityInfo->explicitCSITxBF;
1109 pDot11f->explicitUncompressedSteeringMatrix =
1110 pTxBFCapabilityInfo->explicitUncompressedSteeringMatrix;
1111 pDot11f->explicitBFCSIFeedback =
1112 pTxBFCapabilityInfo->explicitBFCSIFeedback;
1113 pDot11f->explicitUncompressedSteeringMatrixFeedback =
1114 pTxBFCapabilityInfo->explicitUncompressedSteeringMatrixFeedback;
1115 pDot11f->explicitCompressedSteeringMatrixFeedback =
1116 pTxBFCapabilityInfo->explicitCompressedSteeringMatrixFeedback;
1117 pDot11f->csiNumBFAntennae = pTxBFCapabilityInfo->csiNumBFAntennae;
1118 pDot11f->uncompressedSteeringMatrixBFAntennae =
1119 pTxBFCapabilityInfo->uncompressedSteeringMatrixBFAntennae;
1120 pDot11f->compressedSteeringMatrixBFAntennae =
1121 pTxBFCapabilityInfo->compressedSteeringMatrixBFAntennae;
1122
1123 pASCapabilityInfo = (tSirMacASCapabilityInfo *)&vht_cap_info->as_cap;
1124 pDot11f->antennaSelection = pASCapabilityInfo->antennaSelection;
1125 pDot11f->explicitCSIFeedbackTx =
1126 pASCapabilityInfo->explicitCSIFeedbackTx;
1127 pDot11f->antennaIndicesFeedbackTx =
1128 pASCapabilityInfo->antennaIndicesFeedbackTx;
1129 pDot11f->explicitCSIFeedback = pASCapabilityInfo->explicitCSIFeedback;
1130 pDot11f->antennaIndicesFeedback =
1131 pASCapabilityInfo->antennaIndicesFeedback;
1132 pDot11f->rxAS = pASCapabilityInfo->rxAS;
1133 pDot11f->txSoundingPPDUs = pASCapabilityInfo->txSoundingPPDUs;
1134
1135 pDot11f->present = 1;
1136
1137 return QDF_STATUS_SUCCESS;
1138
1139 } /* End populate_dot11f_ht_caps. */
1140
1141 #define SEC_CHANNEL_OFFSET 20
1142
wlan_get_cb_mode(struct mac_context * mac,qdf_freq_t ch_freq,tDot11fBeaconIEs * ie_struct,struct pe_session * pe_session)1143 ePhyChanBondState wlan_get_cb_mode(struct mac_context *mac,
1144 qdf_freq_t ch_freq,
1145 tDot11fBeaconIEs *ie_struct,
1146 struct pe_session *pe_session)
1147 {
1148 ePhyChanBondState cb_mode = PHY_SINGLE_CHANNEL_CENTERED;
1149 uint32_t sec_ch_freq = 0;
1150 uint32_t self_cb_mode;
1151 struct ch_params ch_params = {0};
1152
1153 self_cb_mode = lim_get_cb_mode_for_freq(mac, pe_session, ch_freq);
1154 if (self_cb_mode == WNI_CFG_CHANNEL_BONDING_MODE_DISABLE)
1155 return PHY_SINGLE_CHANNEL_CENTERED;
1156
1157 if (pe_session->dot11mode == MLME_DOT11_MODE_11A ||
1158 pe_session->dot11mode == MLME_DOT11_MODE_11G ||
1159 pe_session->dot11mode == MLME_DOT11_MODE_11B)
1160 return PHY_SINGLE_CHANNEL_CENTERED;
1161
1162 if (!(ie_struct->HTCaps.present && (eHT_CHANNEL_WIDTH_40MHZ ==
1163 ie_struct->HTCaps.supportedChannelWidthSet))) {
1164 return PHY_SINGLE_CHANNEL_CENTERED;
1165 }
1166
1167 /* In Case WPA2 and TKIP is the only one cipher suite in Pairwise */
1168 if ((ie_struct->RSN.present &&
1169 (ie_struct->RSN.pwise_cipher_suite_count == 1) &&
1170 !qdf_mem_cmp(&(ie_struct->RSN.pwise_cipher_suites[0][0]),
1171 "\x00\x0f\xac\x02", 4)) ||
1172 /* In Case only WPA1 is supported and TKIP is
1173 * the only one cipher suite in Unicast.
1174 */
1175 (!ie_struct->RSN.present && (ie_struct->WPA.present &&
1176 (ie_struct->WPA.unicast_cipher_count == 1) &&
1177 !qdf_mem_cmp(&(ie_struct->WPA.unicast_ciphers[0][0]),
1178 "\x00\x50\xf2\x02", 4)))) {
1179 pe_debug("No channel bonding in TKIP mode");
1180 return PHY_SINGLE_CHANNEL_CENTERED;
1181 }
1182
1183 if (!ie_struct->HTInfo.present)
1184 return PHY_SINGLE_CHANNEL_CENTERED;
1185
1186 pe_debug("ch freq %d scws %u rtws %u sco %u", ch_freq,
1187 ie_struct->HTCaps.supportedChannelWidthSet,
1188 ie_struct->HTInfo.recommendedTxWidthSet,
1189 ie_struct->HTInfo.secondaryChannelOffset);
1190
1191 if (ie_struct->HTInfo.recommendedTxWidthSet == eHT_CHANNEL_WIDTH_40MHZ)
1192 cb_mode = ie_struct->HTInfo.secondaryChannelOffset;
1193 else
1194 cb_mode = PHY_SINGLE_CHANNEL_CENTERED;
1195
1196 switch (cb_mode) {
1197 case PHY_DOUBLE_CHANNEL_LOW_PRIMARY:
1198 sec_ch_freq = ch_freq + SEC_CHANNEL_OFFSET;
1199 break;
1200 case PHY_DOUBLE_CHANNEL_HIGH_PRIMARY:
1201 sec_ch_freq = ch_freq - SEC_CHANNEL_OFFSET;
1202 break;
1203 default:
1204 break;
1205 }
1206
1207 if (cb_mode != PHY_SINGLE_CHANNEL_CENTERED) {
1208 ch_params.ch_width = CH_WIDTH_40MHZ;
1209 wlan_reg_set_channel_params_for_pwrmode(mac->pdev, ch_freq,
1210 sec_ch_freq, &ch_params,
1211 REG_CURRENT_PWR_MODE);
1212 if (ch_params.ch_width == CH_WIDTH_20MHZ ||
1213 ch_params.sec_ch_offset != cb_mode) {
1214 pe_err("ch freq %d :: Supported HT BW %d and cbmode %d, APs HT BW %d and cbmode %d, so switch to 20Mhz",
1215 ch_freq, ch_params.ch_width,
1216 ch_params.sec_ch_offset,
1217 ie_struct->HTInfo.recommendedTxWidthSet,
1218 cb_mode);
1219 cb_mode = PHY_SINGLE_CHANNEL_CENTERED;
1220 }
1221 }
1222
1223 return cb_mode;
1224 }
1225
lim_log_vht_cap(struct mac_context * mac,tDot11fIEVHTCaps * pDot11f)1226 void lim_log_vht_cap(struct mac_context *mac, tDot11fIEVHTCaps *pDot11f)
1227 {
1228 #ifdef DUMP_MGMT_CNTNTS
1229 pe_debug("maxMPDULen (2): %d", pDot11f->maxMPDULen);
1230 pe_debug("supportedChannelWidthSet (2): %d",
1231 pDot11f->supportedChannelWidthSet);
1232 pe_debug("ldpcCodingCap (1): %d",
1233 pDot11f->ldpcCodingCap);
1234 pe_debug("shortGI80MHz (1): %d", pDot11f->shortGI80MHz);
1235 pe_debug("shortGI160and80plus80MHz (1): %d",
1236 pDot11f->shortGI160and80plus80MHz);
1237 pe_debug("txSTBC (1): %d", pDot11f->txSTBC);
1238 pe_debug("rxSTBC (3): %d", pDot11f->rxSTBC);
1239 pe_debug("suBeamFormerCap (1): %d",
1240 pDot11f->suBeamFormerCap);
1241 pe_debug("suBeamformeeCap (1): %d",
1242 pDot11f->suBeamformeeCap);
1243 pe_debug("csnofBeamformerAntSup (3): %d",
1244 pDot11f->csnofBeamformerAntSup);
1245 pe_debug("numSoundingDim (3): %d",
1246 pDot11f->numSoundingDim);
1247 pe_debug("muBeamformerCap (1): %d",
1248 pDot11f->muBeamformerCap);
1249 pe_debug("muBeamformeeCap (1): %d",
1250 pDot11f->muBeamformeeCap);
1251 pe_debug("vhtTXOPPS (1): %d", pDot11f->vhtTXOPPS);
1252 pe_debug("htcVHTCap (1): %d", pDot11f->htcVHTCap);
1253 pe_debug("maxAMPDULenExp (3): %d",
1254 pDot11f->maxAMPDULenExp);
1255 pe_debug("vhtLinkAdaptCap (2): %d",
1256 pDot11f->vhtLinkAdaptCap);
1257 pe_debug("rxAntPattern (1): %d",
1258 pDot11f->rxAntPattern;
1259 pe_debug("txAntPattern (1): %d",
1260 pDot11f->txAntPattern);
1261 pe_debug("reserved1 (2): %d", pDot11f->reserved1);
1262 pe_debug("rxMCSMap (16): %d", pDot11f->rxMCSMap);
1263 pe_debug("rxHighSupDataRate (13): %d",
1264 pDot11f->rxHighSupDataRate);
1265 pe_debug("reserved2(3): %d", pDot11f->reserved2);
1266 pe_debug("txMCSMap (16): %d", pDot11f->txMCSMap);
1267 pe_debug("txSupDataRate (13): %d"),
1268 pDot11f->txSupDataRate;
1269 pe_debug("reserved3 (3): %d", pDot11f->reserved3);
1270 #endif /* DUMP_MGMT_CNTNTS */
1271 }
1272
1273 static void lim_log_vht_operation(struct mac_context *mac,
1274 tDot11fIEVHTOperation *pDot11f)
1275 {
1276 #ifdef DUMP_MGMT_CNTNTS
1277 pe_debug("chanWidth: %d", pDot11f->chanWidth);
1278 pe_debug("chan_center_freq_seg0: %d",
1279 pDot11f->chan_center_freq_seg0);
1280 pe_debug("chan_center_freq_seg1: %d",
1281 pDot11f->chan_center_freq_seg1);
1282 pe_debug("basicMCSSet: %d", pDot11f->basicMCSSet);
1283 #endif /* DUMP_MGMT_CNTNTS */
1284 }
1285
1286 static void lim_log_operating_mode(struct mac_context *mac,
1287 tDot11fIEOperatingMode *pDot11f)
1288 {
1289 #ifdef DUMP_MGMT_CNTNTS
1290 pe_debug("ChanWidth: %d", pDot11f->chanWidth);
1291 pe_debug("reserved: %d", pDot11f->reserved);
1292 pe_debug("rxNSS: %d", pDot11f->rxNSS);
1293 pe_debug("rxNSS Type: %d", pDot11f->rxNSSType);
1294 #endif /* DUMP_MGMT_CNTNTS */
1295 }
1296
1297 static void lim_log_qos_map_set(struct mac_context *mac,
1298 struct qos_map_set *pQosMapSet)
1299 {
1300 if (pQosMapSet->num_dscp_exceptions > QOS_MAP_MAX_EX)
1301 pQosMapSet->num_dscp_exceptions = QOS_MAP_MAX_EX;
1302
1303 pe_debug("num of dscp exceptions: %d", pQosMapSet->num_dscp_exceptions);
1304 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_DEBUG,
1305 pQosMapSet->dscp_exceptions,
1306 sizeof(pQosMapSet->dscp_exceptions));
1307 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_DEBUG,
1308 pQosMapSet->dscp_range,
1309 sizeof(pQosMapSet->dscp_range));
1310 }
1311
1312 QDF_STATUS
1313 populate_dot11f_vht_caps(struct mac_context *mac,
1314 struct pe_session *pe_session, tDot11fIEVHTCaps *pDot11f)
1315 {
1316 uint32_t nCfgValue = 0;
1317 struct mlme_vht_capabilities_info *vht_cap_info;
1318
1319 if (!(mac->mlme_cfg)) {
1320 pe_err("invalid mlme cfg");
1321 return QDF_STATUS_E_FAILURE;
1322 }
1323 vht_cap_info = &mac->mlme_cfg->vht_caps.vht_cap_info;
1324
1325 pDot11f->present = 1;
1326
1327 nCfgValue = vht_cap_info->ampdu_len;
1328 pDot11f->maxMPDULen = (nCfgValue & 0x0003);
1329
1330 nCfgValue = vht_cap_info->supp_chan_width;
1331 pDot11f->supportedChannelWidthSet = (nCfgValue & 0x0003);
1332
1333 nCfgValue = 0;
1334 /* With VHT it suffices if we just examine HT */
1335 if (pe_session) {
1336 if (lim_is_he_6ghz_band(pe_session)) {
1337 pDot11f->present = 0;
1338 return QDF_STATUS_SUCCESS;
1339 }
1340
1341 if (wlan_reg_is_24ghz_ch_freq(pe_session->curr_op_freq)) {
1342 pDot11f->supportedChannelWidthSet = 0;
1343 } else {
1344 if (pe_session->ch_width <= CH_WIDTH_80MHZ)
1345 pDot11f->supportedChannelWidthSet = 0;
1346 }
1347
1348 if (pe_session->ht_config.adv_coding_cap)
1349 pDot11f->ldpcCodingCap =
1350 pe_session->vht_config.ldpc_coding;
1351
1352 pDot11f->shortGI80MHz =
1353 pe_session->vht_config.shortgi80;
1354
1355 if (pDot11f->supportedChannelWidthSet)
1356 pDot11f->shortGI160and80plus80MHz =
1357 pe_session->vht_config.shortgi160and80plus80;
1358
1359 if (pe_session->ht_config.tx_stbc)
1360 pDot11f->txSTBC = pe_session->vht_config.tx_stbc;
1361
1362 if (pe_session->ht_config.rx_stbc)
1363 pDot11f->rxSTBC = pe_session->vht_config.rx_stbc;
1364
1365 pDot11f->suBeamformeeCap =
1366 pe_session->vht_config.su_beam_formee;
1367 if (pe_session->vht_config.su_beam_formee) {
1368 pDot11f->muBeamformeeCap =
1369 pe_session->vht_config.mu_beam_formee;
1370 pDot11f->csnofBeamformerAntSup =
1371 pe_session->vht_config.csnof_beamformer_antSup;
1372 } else {
1373 pDot11f->muBeamformeeCap = 0;
1374 }
1375 pDot11f->suBeamFormerCap =
1376 pe_session->vht_config.su_beam_former;
1377
1378 pDot11f->vhtTXOPPS = pe_session->vht_config.vht_txops;
1379
1380 pDot11f->numSoundingDim =
1381 pe_session->vht_config.num_soundingdim;
1382
1383 pDot11f->htcVHTCap = pe_session->vht_config.htc_vhtcap;
1384
1385 pDot11f->rxAntPattern = pe_session->vht_config.rx_antpattern;
1386
1387 pDot11f->txAntPattern = pe_session->vht_config.tx_antpattern;
1388 pDot11f->extended_nss_bw_supp =
1389 pe_session->vht_config.extended_nss_bw_supp;
1390
1391 pDot11f->maxAMPDULenExp =
1392 pe_session->vht_config.max_ampdu_lenexp;
1393
1394 pDot11f->vhtLinkAdaptCap =
1395 pe_session->vht_config.vht_link_adapt;
1396 } else {
1397 nCfgValue = vht_cap_info->ldpc_coding_cap;
1398 pDot11f->ldpcCodingCap = (nCfgValue & 0x0001);
1399
1400 nCfgValue = vht_cap_info->short_gi_80mhz;
1401 pDot11f->shortGI80MHz = (nCfgValue & 0x0001);
1402
1403 if (pDot11f->supportedChannelWidthSet) {
1404 nCfgValue = vht_cap_info->short_gi_160mhz;
1405 pDot11f->shortGI160and80plus80MHz = (nCfgValue & 0x0001);
1406 }
1407
1408 nCfgValue = vht_cap_info->tx_stbc;
1409 pDot11f->txSTBC = (nCfgValue & 0x0001);
1410
1411 nCfgValue = vht_cap_info->rx_stbc;
1412 pDot11f->rxSTBC = (nCfgValue & 0x0007);
1413
1414 nCfgValue = vht_cap_info->su_bformee;
1415 pDot11f->suBeamformeeCap = (nCfgValue & 0x0001);
1416
1417 nCfgValue = vht_cap_info->enable_mu_bformee;
1418 pDot11f->muBeamformeeCap = (nCfgValue & 0x0001);
1419
1420 nCfgValue = vht_cap_info->su_bformer;
1421 pDot11f->suBeamFormerCap = (nCfgValue & 0x0001);
1422
1423 nCfgValue = vht_cap_info->tx_bfee_ant_supp;
1424 pDot11f->csnofBeamformerAntSup = (nCfgValue & 0x0007);
1425
1426 nCfgValue = vht_cap_info->txop_ps;
1427 pDot11f->vhtTXOPPS = (nCfgValue & 0x0001);
1428
1429 nCfgValue = vht_cap_info->num_soundingdim;
1430 pDot11f->numSoundingDim = (nCfgValue & 0x0007);
1431
1432 nCfgValue = vht_cap_info->htc_vhtc;
1433 pDot11f->htcVHTCap = (nCfgValue & 0x0001);
1434
1435 pDot11f->rxAntPattern = vht_cap_info->rx_antpattern;
1436
1437 pDot11f->txAntPattern = vht_cap_info->tx_antpattern;
1438
1439 nCfgValue = vht_cap_info->ampdu_len_exponent;
1440 pDot11f->maxAMPDULenExp = (nCfgValue & 0x0007);
1441
1442 nCfgValue = vht_cap_info->link_adap_cap;
1443 pDot11f->vhtLinkAdaptCap = (nCfgValue & 0x0003);
1444
1445 pDot11f->extended_nss_bw_supp =
1446 vht_cap_info->extended_nss_bw_supp;
1447 }
1448
1449 pDot11f->max_nsts_total = vht_cap_info->max_nsts_total;
1450 pDot11f->vht_extended_nss_bw_cap =
1451 vht_cap_info->vht_extended_nss_bw_cap;
1452
1453 nCfgValue = vht_cap_info->mu_bformer;
1454 pDot11f->muBeamformerCap = (nCfgValue & 0x0001);
1455
1456
1457 nCfgValue = vht_cap_info->rx_mcs_map;
1458 pDot11f->rxMCSMap = (nCfgValue & 0x0000FFFF);
1459
1460 nCfgValue = vht_cap_info->rx_supp_data_rate;
1461 pDot11f->rxHighSupDataRate = (nCfgValue & 0x00001FFF);
1462
1463 nCfgValue = vht_cap_info->tx_mcs_map;
1464 pDot11f->txMCSMap = (nCfgValue & 0x0000FFFF);
1465
1466 nCfgValue = vht_cap_info->tx_supp_data_rate;
1467 pDot11f->txSupDataRate = (nCfgValue & 0x00001FFF);
1468
1469 if (pe_session) {
1470 if (pe_session->nss == NSS_1x1_MODE) {
1471 pDot11f->txMCSMap |= DISABLE_NSS2_MCS;
1472 pDot11f->rxMCSMap |= DISABLE_NSS2_MCS;
1473 pDot11f->txSupDataRate =
1474 VHT_TX_HIGHEST_SUPPORTED_DATA_RATE_1_1;
1475 pDot11f->rxHighSupDataRate =
1476 VHT_RX_HIGHEST_SUPPORTED_DATA_RATE_1_1;
1477 if (!pe_session->ch_width &&
1478 !vht_cap_info->enable_vht20_mcs9 &&
1479 ((pDot11f->txMCSMap & VHT_1x1_MCS_MASK) ==
1480 VHT_1x1_MCS9_MAP)) {
1481 DISABLE_VHT_MCS_9(pDot11f->txMCSMap,
1482 NSS_1x1_MODE);
1483 DISABLE_VHT_MCS_9(pDot11f->rxMCSMap,
1484 NSS_1x1_MODE);
1485 }
1486 pDot11f->txSTBC = 0;
1487 } else {
1488 if (!pe_session->ch_width &&
1489 !vht_cap_info->enable_vht20_mcs9 &&
1490 ((pDot11f->txMCSMap & VHT_2x2_MCS_MASK) ==
1491 VHT_2x2_MCS9_MAP)) {
1492 DISABLE_VHT_MCS_9(pDot11f->txMCSMap,
1493 NSS_2x2_MODE);
1494 DISABLE_VHT_MCS_9(pDot11f->rxMCSMap,
1495 NSS_2x2_MODE);
1496 }
1497 }
1498 }
1499
1500 lim_log_vht_cap(mac, pDot11f);
1501 return QDF_STATUS_SUCCESS;
1502 }
1503
1504 QDF_STATUS
1505 populate_dot11f_vht_operation(struct mac_context *mac,
1506 struct pe_session *pe_session,
1507 tDot11fIEVHTOperation *pDot11f)
1508 {
1509 uint32_t mcs_set;
1510 struct mlme_vht_capabilities_info *vht_cap_info;
1511 enum reg_wifi_band band;
1512 uint8_t band_mask;
1513 struct ch_params ch_params = {0};
1514 qdf_freq_t sec_chan_freq = 0;
1515
1516 if (!pe_session || !pe_session->vhtCapability)
1517 return QDF_STATUS_SUCCESS;
1518
1519 band = wlan_reg_freq_to_band(pe_session->curr_op_freq);
1520 band_mask = 1 << band;
1521
1522 ch_params.ch_width = pe_session->ch_width;
1523 ch_params.mhz_freq_seg0 =
1524 wlan_reg_chan_band_to_freq(mac->pdev,
1525 pe_session->ch_center_freq_seg0,
1526 band_mask);
1527
1528 if (pe_session->ch_center_freq_seg1)
1529 ch_params.mhz_freq_seg1 =
1530 wlan_reg_chan_band_to_freq(mac->pdev,
1531 pe_session->ch_center_freq_seg1,
1532 band_mask);
1533
1534 if (band == (REG_BAND_2G) && ch_params.ch_width == CH_WIDTH_40MHZ) {
1535 if (ch_params.mhz_freq_seg0 == pe_session->curr_op_freq + 10)
1536 sec_chan_freq = pe_session->curr_op_freq + 20;
1537 if (ch_params.mhz_freq_seg0 == pe_session->curr_op_freq - 10)
1538 sec_chan_freq = pe_session->curr_op_freq - 20;
1539 }
1540
1541 wlan_reg_set_channel_params_for_pwrmode(mac->pdev,
1542 pe_session->curr_op_freq,
1543 sec_chan_freq, &ch_params,
1544 REG_CURRENT_PWR_MODE);
1545
1546 pDot11f->present = 1;
1547
1548 if (pe_session->ch_width > CH_WIDTH_40MHZ) {
1549 pDot11f->chanWidth = 1;
1550 pDot11f->chan_center_freq_seg0 =
1551 ch_params.center_freq_seg0;
1552 if (pe_session->ch_width == CH_WIDTH_80P80MHZ ||
1553 pe_session->ch_width == CH_WIDTH_160MHZ)
1554 pDot11f->chan_center_freq_seg1 =
1555 ch_params.center_freq_seg1;
1556 else
1557 pDot11f->chan_center_freq_seg1 = 0;
1558 } else {
1559 pDot11f->chanWidth = 0;
1560 pDot11f->chan_center_freq_seg0 = 0;
1561 pDot11f->chan_center_freq_seg1 = 0;
1562 }
1563
1564 vht_cap_info = &mac->mlme_cfg->vht_caps.vht_cap_info;
1565 mcs_set = vht_cap_info->basic_mcs_set;
1566 mcs_set = (mcs_set & 0xFFFC) | vht_cap_info->rx_mcs;
1567
1568 if (pe_session->nss == NSS_1x1_MODE)
1569 mcs_set |= 0x000C;
1570 else
1571 mcs_set = (mcs_set & 0xFFF3) | (vht_cap_info->rx_mcs2x2 << 2);
1572
1573 pDot11f->basicMCSSet = (uint16_t)mcs_set;
1574 lim_log_vht_operation(mac, pDot11f);
1575
1576 return QDF_STATUS_SUCCESS;
1577
1578 }
1579
1580 QDF_STATUS
1581 populate_dot11f_ext_cap(struct mac_context *mac,
1582 bool isVHTEnabled, tDot11fIEExtCap *pDot11f,
1583 struct pe_session *pe_session)
1584 {
1585 struct s_ext_cap *p_ext_cap;
1586
1587 pDot11f->present = 1;
1588
1589 if (!pe_session) {
1590 pe_debug("11MC - enabled for non-SAP cases");
1591 pDot11f->num_bytes = DOT11F_IE_EXTCAP_MAX_LEN;
1592 } else if (pe_session->sap_dot11mc) {
1593 pe_debug("11MC support enabled");
1594 pDot11f->num_bytes = DOT11F_IE_EXTCAP_MAX_LEN;
1595 } else {
1596 if (eLIM_AP_ROLE != pe_session->limSystemRole)
1597 pDot11f->num_bytes = DOT11F_IE_EXTCAP_MAX_LEN;
1598 else
1599 pDot11f->num_bytes = DOT11F_IE_EXTCAP_MIN_LEN;
1600 }
1601
1602 p_ext_cap = (struct s_ext_cap *)pDot11f->bytes;
1603 if (isVHTEnabled == true)
1604 p_ext_cap->oper_mode_notification = 1;
1605
1606 if (mac->mlme_cfg->gen.rtt3_enabled) {
1607 uint32_t ftm = ucfg_wifi_pos_get_ftm_cap(mac->psoc);
1608 if (!pe_session || LIM_IS_STA_ROLE(pe_session)) {
1609 p_ext_cap->fine_time_meas_initiator =
1610 (ftm & WMI_FW_STA_RTT_INITR) ? 1 : 0;
1611 p_ext_cap->fine_time_meas_responder =
1612 (ftm & WMI_FW_STA_RTT_RESPR) ? 1 : 0;
1613 } else if (LIM_IS_AP_ROLE(pe_session)) {
1614 p_ext_cap->fine_time_meas_initiator =
1615 (ftm & WMI_FW_AP_RTT_INITR) ? 1 : 0;
1616 p_ext_cap->fine_time_meas_responder =
1617 (ftm & WMI_FW_AP_RTT_RESPR) ? 1 : 0;
1618 }
1619 }
1620 #ifdef QCA_HT_2040_COEX
1621 if (mac->roam.configParam.obssEnabled)
1622 p_ext_cap->bss_coexist_mgmt_support = 1;
1623 #endif
1624 p_ext_cap->ext_chan_switch = 1;
1625
1626 if (pe_session && pe_session->enable_bcast_probe_rsp)
1627 p_ext_cap->fils_capability = 1;
1628
1629 if (pe_session && pe_session->is_mbssid_enabled)
1630 p_ext_cap->multi_bssid = 1;
1631
1632 /* Beacon Protection Enabled : This field is reserved for STA */
1633 if (pe_session && (pe_session->opmode == QDF_SAP_MODE ||
1634 pe_session->opmode == QDF_P2P_GO_MODE)) {
1635 p_ext_cap->beacon_protection_enable = pe_session ?
1636 mlme_get_bigtk_support(pe_session->vdev) : false;
1637 }
1638 if (pe_session)
1639 populate_dot11f_twt_extended_caps(mac, pe_session, pDot11f);
1640
1641 /* Need to calculate the num_bytes based on bits set */
1642 if (pDot11f->present)
1643 pDot11f->num_bytes = lim_compute_ext_cap_ie_length(pDot11f);
1644
1645 return QDF_STATUS_SUCCESS;
1646 }
1647
1648 #ifdef WLAN_FEATURE_11AX
1649 static void populate_dot11f_qcn_ie_he_params(struct mac_context *mac,
1650 struct pe_session *pe_session,
1651 tDot11fIEqcn_ie *qcn_ie,
1652 uint8_t attr_id)
1653 {
1654 uint16_t mcs_12_13_supp = 0;
1655
1656 if (!lim_is_session_he_capable(pe_session))
1657 return;
1658
1659 /* To fix WAPI IoT issue.*/
1660 if (pe_session->encryptType == eSIR_ED_WPI)
1661 return;
1662
1663 if (wlan_reg_is_24ghz_ch_freq(pe_session->curr_op_freq)) {
1664 if (!(LIM_IS_AP_ROLE(pe_session) &&
1665 pe_session->ch_width == CH_WIDTH_40MHZ &&
1666 (mac->mlme_cfg->he_caps.disable_sap_mcs_12_13 &
1667 BIT(DISABLE_MCS_12_13_2G_40M))))
1668 mcs_12_13_supp = mac->mlme_cfg->he_caps.he_mcs_12_13_supp_2g;
1669 } else {
1670 mcs_12_13_supp = mac->mlme_cfg->he_caps.he_mcs_12_13_supp_5g;
1671 }
1672
1673 if (!mcs_12_13_supp)
1674 return;
1675
1676 qcn_ie->present = 1;
1677 qcn_ie->he_mcs13_attr.present = 1;
1678 qcn_ie->he_mcs13_attr.he_mcs_12_13_supp_80 = mcs_12_13_supp & 0xFF;
1679 qcn_ie->he_mcs13_attr.he_mcs_12_13_supp_160 = mcs_12_13_supp >> 8;
1680 }
1681 #else /* WLAN_FEATURE_11AX */
1682 static void populate_dot11f_qcn_ie_he_params(struct mac_context *mac,
1683 struct pe_session *pe_session,
1684 tDot11fIEqcn_ie *qcn_ie,
1685 uint8_t attr_id)
1686 {}
1687 #endif /* WLAN_FEATURE_11AX */
1688
1689 void populate_dot11f_bss_max_idle(struct mac_context *mac,
1690 struct pe_session *session,
1691 tDot11fIEbss_max_idle_period *max_idle_ie)
1692 {
1693 max_idle_ie->present = 0;
1694 if (lim_is_session_he_capable(session) &&
1695 mac->mlme_cfg->sta.bss_max_idle_period) {
1696 max_idle_ie->present = 1;
1697 max_idle_ie->max_idle_period =
1698 mac->mlme_cfg->sta.bss_max_idle_period;
1699 max_idle_ie->prot_keep_alive_reqd = session->limRmfEnabled;
1700 }
1701 }
1702
1703 void populate_dot11f_edca_pifs_param_set(struct mac_context *mac,
1704 tDot11fIEqcn_ie *qcn_ie)
1705 {
1706 struct wlan_edca_pifs_param_ie param = {0};
1707 struct edca_param *eparam;
1708 struct pifs_param *pparam;
1709 uint8_t edca_param_type;
1710
1711 qcn_ie->present = 1;
1712 qcn_ie->edca_pifs_param_attr.present = 1;
1713
1714 edca_param_type = mac->mlme_cfg->edca_params.edca_param_type;
1715 wlan_mlme_set_edca_pifs_param(¶m, edca_param_type);
1716 qcn_ie->edca_pifs_param_attr.edca_param_type = edca_param_type;
1717
1718 if (edca_param_type == HOST_EDCA_PARAM_TYPE_AGGRESSIVE) {
1719 qcn_ie->edca_pifs_param_attr.num_data = sizeof(*eparam);
1720 eparam = (struct edca_param *)qcn_ie->edca_pifs_param_attr.data;
1721 qdf_mem_copy(eparam, ¶m.edca_pifs_param.eparam,
1722 sizeof(*eparam));
1723 } else if (edca_param_type == HOST_EDCA_PARAM_TYPE_PIFS) {
1724 qcn_ie->edca_pifs_param_attr.num_data = sizeof(*pparam);
1725 pparam = (struct pifs_param *)qcn_ie->edca_pifs_param_attr.data;
1726 qdf_mem_copy(pparam, ¶m.edca_pifs_param.pparam,
1727 sizeof(*pparam));
1728 }
1729 }
1730
1731 void populate_dot11f_qcn_ie(struct mac_context *mac,
1732 struct pe_session *pe_session,
1733 tDot11fIEqcn_ie *qcn_ie,
1734 uint8_t attr_id)
1735 {
1736 qcn_ie->present = 0;
1737 if (mac->mlme_cfg->sta.qcn_ie_support &&
1738 ((attr_id == QCN_IE_ATTR_ID_ALL) ||
1739 (attr_id == QCN_IE_ATTR_ID_VERSION))) {
1740 qcn_ie->present = 1;
1741 qcn_ie->qcn_version.present = 1;
1742 qcn_ie->qcn_version.version = QCN_IE_VERSION_SUPPORTED;
1743 qcn_ie->qcn_version.sub_version = QCN_IE_SUBVERSION_SUPPORTED;
1744 }
1745 if (pe_session->vhtCapability &&
1746 mac->mlme_cfg->vht_caps.vht_cap_info.vht_mcs_10_11_supp) {
1747 qcn_ie->present = 1;
1748 qcn_ie->vht_mcs11_attr.present = 1;
1749 qcn_ie->vht_mcs11_attr.vht_mcs_10_11_supp = 1;
1750 }
1751
1752 populate_dot11f_qcn_ie_he_params(mac, pe_session, qcn_ie, attr_id);
1753 if (policy_mgr_is_vdev_ll_lt_sap(mac->psoc, pe_session->vdev_id)) {
1754 pe_debug("Populate edca/pifs param ie for ll sap");
1755 populate_dot11f_edca_pifs_param_set(mac, qcn_ie);
1756 }
1757 }
1758
1759 QDF_STATUS
1760 populate_dot11f_operating_mode(struct mac_context *mac,
1761 tDot11fIEOperatingMode *pDot11f,
1762 struct pe_session *pe_session)
1763 {
1764 pDot11f->present = 1;
1765
1766 pDot11f->chanWidth = pe_session->gLimOperatingMode.chanWidth;
1767 pDot11f->rxNSS = pe_session->gLimOperatingMode.rxNSS;
1768 pDot11f->rxNSSType = pe_session->gLimOperatingMode.rxNSSType;
1769
1770 return QDF_STATUS_SUCCESS;
1771 }
1772
1773 QDF_STATUS
1774 populate_dot11f_ht_info(struct mac_context *mac,
1775 tDot11fIEHTInfo *pDot11f, struct pe_session *pe_session)
1776 {
1777 qdf_size_t ncfglen;
1778 QDF_STATUS nSirStatus;
1779
1780 if (!pe_session) {
1781 pe_err("Invalid session entry");
1782 return QDF_STATUS_E_FAILURE;
1783 }
1784
1785 pDot11f->primaryChannel = wlan_reg_freq_to_chan(
1786 mac->pdev, pe_session->curr_op_freq);
1787
1788 pDot11f->secondaryChannelOffset =
1789 pe_session->htSecondaryChannelOffset;
1790 pDot11f->recommendedTxWidthSet =
1791 pe_session->htRecommendedTxWidthSet;
1792 pDot11f->rifsMode = pe_session->beaconParams.fRIFSMode;
1793 pDot11f->controlledAccessOnly =
1794 mac->mlme_cfg->ht_caps.info_field_1.controlled_access_only;
1795 pDot11f->serviceIntervalGranularity =
1796 mac->lim.gHTServiceIntervalGranularity;
1797
1798 if (LIM_IS_AP_ROLE(pe_session)) {
1799 pDot11f->opMode = pe_session->htOperMode;
1800 pDot11f->nonGFDevicesPresent =
1801 pe_session->beaconParams.llnNonGFCoexist;
1802 pDot11f->obssNonHTStaPresent =
1803 pe_session->beaconParams.gHTObssMode;
1804 pDot11f->reserved = 0;
1805 } else {
1806 pDot11f->opMode = 0;
1807 pDot11f->nonGFDevicesPresent = 0;
1808 pDot11f->obssNonHTStaPresent = 0;
1809 pDot11f->reserved = 0;
1810 }
1811
1812 pDot11f->basicSTBCMCS = mac->lim.gHTSTBCBasicMCS;
1813 pDot11f->dualCTSProtection = mac->lim.gHTDualCTSProtection;
1814 pDot11f->secondaryBeacon = mac->lim.gHTSecondaryBeacon;
1815 pDot11f->lsigTXOPProtectionFullSupport =
1816 pe_session->beaconParams.fLsigTXOPProtectionFullSupport;
1817 pDot11f->pcoActive = mac->lim.gHTPCOActive;
1818 pDot11f->pcoPhase = mac->lim.gHTPCOPhase;
1819 pDot11f->reserved2 = 0;
1820
1821 ncfglen = SIZE_OF_BASIC_MCS_SET;
1822 nSirStatus = wlan_mlme_get_cfg_str(pDot11f->basicMCSSet,
1823 &mac->mlme_cfg->rates.basic_mcs_set,
1824 &ncfglen);
1825 if (QDF_IS_STATUS_ERROR(nSirStatus)) {
1826 pe_err("Failed to retrieve nItem from CFG status: %d",
1827 (nSirStatus));
1828 return nSirStatus;
1829 }
1830
1831 pDot11f->present = 1;
1832
1833 return QDF_STATUS_SUCCESS;
1834
1835 } /* End populate_dot11f_ht_info. */
1836
1837 #ifdef ANI_SUPPORT_11H
1838 QDF_STATUS
1839 populate_dot11f_measurement_report0(struct mac_context *mac,
1840 tpSirMacMeasReqActionFrame pReq,
1841 tDot11fIEMeasurementReport *pDot11f)
1842 {
1843 pDot11f->token = pReq->measReqIE.measToken;
1844 pDot11f->late = 0;
1845 pDot11f->incapable = 0;
1846 pDot11f->refused = 1;
1847 pDot11f->type = SIR_MAC_BASIC_MEASUREMENT_TYPE;
1848
1849 pDot11f->present = 1;
1850
1851 return QDF_STATUS_SUCCESS;
1852
1853 } /* End PopulatedDot11fMeasurementReport0. */
1854 QDF_STATUS
1855 populate_dot11f_measurement_report1(struct mac_context *mac,
1856 tpSirMacMeasReqActionFrame pReq,
1857 tDot11fIEMeasurementReport *pDot11f)
1858 {
1859 pDot11f->token = pReq->measReqIE.measToken;
1860 pDot11f->late = 0;
1861 pDot11f->incapable = 0;
1862 pDot11f->refused = 1;
1863 pDot11f->type = SIR_MAC_CCA_MEASUREMENT_TYPE;
1864 pDot11f->present = 1;
1865 return QDF_STATUS_SUCCESS;
1866 } /* End PopulatedDot11fMeasurementReport1. */
1867 QDF_STATUS
1868 populate_dot11f_measurement_report2(struct mac_context *mac,
1869 tpSirMacMeasReqActionFrame pReq,
1870 tDot11fIEMeasurementReport *pDot11f)
1871 {
1872 pDot11f->token = pReq->measReqIE.measToken;
1873 pDot11f->late = 0;
1874 pDot11f->incapable = 0;
1875 pDot11f->refused = 1;
1876 pDot11f->type = SIR_MAC_RPI_MEASUREMENT_TYPE;
1877 pDot11f->present = 1;
1878 return QDF_STATUS_SUCCESS;
1879 } /* End PopulatedDot11fMeasurementReport2. */
1880 #endif
1881
1882 void
1883 populate_dot11f_power_caps(struct mac_context *mac,
1884 tDot11fIEPowerCaps *pCaps,
1885 uint8_t nAssocType, struct pe_session *pe_session)
1886 {
1887 struct vdev_mlme_obj *mlme_obj;
1888
1889 pCaps->minTxPower = pe_session->min_11h_pwr;
1890 pCaps->maxTxPower = pe_session->maxTxPower;
1891
1892 /* Use firmware updated max tx power if non zero */
1893 mlme_obj = wlan_vdev_mlme_get_cmpt_obj(pe_session->vdev);
1894 if (mlme_obj && mlme_obj->mgmt.generic.tx_pwrlimit)
1895 pCaps->maxTxPower = mlme_obj->mgmt.generic.tx_pwrlimit;
1896
1897 pCaps->present = 1;
1898 } /* End populate_dot11f_power_caps. */
1899
1900 QDF_STATUS
1901 populate_dot11f_power_constraints(struct mac_context *mac,
1902 tDot11fIEPowerConstraints *pDot11f)
1903 {
1904 pDot11f->localPowerConstraints =
1905 mac->mlme_cfg->power.local_power_constraint;
1906
1907 pDot11f->present = 1;
1908
1909 return QDF_STATUS_SUCCESS;
1910 } /* End populate_dot11f_power_constraints. */
1911
1912 void
1913 populate_dot11f_qos_caps_station(struct mac_context *mac, struct pe_session *pe_session,
1914 tDot11fIEQOSCapsStation *pDot11f)
1915 {
1916 uint8_t max_sp_length = 0;
1917
1918 max_sp_length = mac->mlme_cfg->wmm_params.max_sp_length;
1919
1920 pDot11f->more_data_ack = 0;
1921 pDot11f->max_sp_length = max_sp_length;
1922 pDot11f->qack = 0;
1923
1924 if (mac->lim.gUapsdEnable) {
1925 pDot11f->acbe_uapsd =
1926 LIM_UAPSD_GET(ACBE, pe_session->gUapsdPerAcBitmask);
1927 pDot11f->acbk_uapsd =
1928 LIM_UAPSD_GET(ACBK, pe_session->gUapsdPerAcBitmask);
1929 pDot11f->acvi_uapsd =
1930 LIM_UAPSD_GET(ACVI, pe_session->gUapsdPerAcBitmask);
1931 pDot11f->acvo_uapsd =
1932 LIM_UAPSD_GET(ACVO, pe_session->gUapsdPerAcBitmask);
1933 }
1934 pDot11f->present = 1;
1935 } /* End PopulatedDot11fQOSCaps. */
1936
1937 QDF_STATUS
1938 populate_dot11f_rsn(struct mac_context *mac,
1939 tpSirRSNie pRsnIe, tDot11fIERSN *pDot11f)
1940 {
1941 uint32_t status;
1942 int idx;
1943
1944 if (pRsnIe->length) {
1945 idx = find_ie_location(mac, pRsnIe, DOT11F_EID_RSN);
1946 if (0 <= idx) {
1947 status = dot11f_unpack_ie_rsn(mac, pRsnIe->rsnIEdata + idx + 2, /* EID, length */
1948 pRsnIe->rsnIEdata[idx + 1],
1949 pDot11f, false);
1950 if (DOT11F_FAILED(status)) {
1951 pe_err("Parse failure in Populate Dot11fRSN (0x%08x)",
1952 status);
1953 return QDF_STATUS_E_FAILURE;
1954 }
1955 pe_debug("status 0x%08x", status);
1956 }
1957
1958 }
1959
1960 return QDF_STATUS_SUCCESS;
1961 } /* End populate_dot11f_rsn. */
1962
1963 QDF_STATUS populate_dot11f_rsn_opaque(struct mac_context *mac,
1964 tpSirRSNie pRsnIe,
1965 tDot11fIERSNOpaque *pDot11f)
1966 {
1967 int idx;
1968
1969 if (pRsnIe->length) {
1970 idx = find_ie_location(mac, pRsnIe, DOT11F_EID_RSN);
1971 if (0 <= idx) {
1972 pDot11f->present = 1;
1973 pDot11f->num_data = pRsnIe->rsnIEdata[idx + 1];
1974 qdf_mem_copy(pDot11f->data, pRsnIe->rsnIEdata + idx + 2, /* EID, len */
1975 pRsnIe->rsnIEdata[idx + 1]);
1976 }
1977 }
1978
1979 return QDF_STATUS_SUCCESS;
1980
1981 } /* End populate_dot11f_rsn_opaque. */
1982
1983 #if defined(FEATURE_WLAN_WAPI)
1984
1985 QDF_STATUS
1986 populate_dot11f_wapi(struct mac_context *mac,
1987 tpSirRSNie pRsnIe, tDot11fIEWAPI *pDot11f)
1988 {
1989 uint32_t status;
1990 int idx;
1991
1992 if (pRsnIe->length) {
1993 idx = find_ie_location(mac, pRsnIe, DOT11F_EID_WAPI);
1994 if (0 <= idx) {
1995 status = dot11f_unpack_ie_wapi(mac, pRsnIe->rsnIEdata + idx + 2, /* EID, length */
1996 pRsnIe->rsnIEdata[idx + 1],
1997 pDot11f, false);
1998 if (DOT11F_FAILED(status)) {
1999 pe_err("Parse failure (0x%08x)", status);
2000 return QDF_STATUS_E_FAILURE;
2001 }
2002 pe_debug("status 0x%08x", status);
2003 }
2004 }
2005
2006 return QDF_STATUS_SUCCESS;
2007 } /* End populate_dot11f_wapi. */
2008
2009 QDF_STATUS populate_dot11f_wapi_opaque(struct mac_context *mac,
2010 tpSirRSNie pRsnIe,
2011 tDot11fIEWAPIOpaque *pDot11f)
2012 {
2013 int idx;
2014
2015 if (pRsnIe->length) {
2016 idx = find_ie_location(mac, pRsnIe, DOT11F_EID_WAPI);
2017 if (0 <= idx) {
2018 pDot11f->present = 1;
2019 pDot11f->num_data = pRsnIe->rsnIEdata[idx + 1];
2020 qdf_mem_copy(pDot11f->data, pRsnIe->rsnIEdata + idx + 2, /* EID, len */
2021 pRsnIe->rsnIEdata[idx + 1]);
2022 }
2023 }
2024
2025 return QDF_STATUS_SUCCESS;
2026
2027 } /* End populate_dot11f_wapi_opaque. */
2028
2029 #endif /* defined(FEATURE_WLAN_WAPI) */
2030
2031 void
2032 populate_dot11f_ssid(struct mac_context *mac,
2033 tSirMacSSid *pInternal, tDot11fIESSID *pDot11f)
2034 {
2035 pDot11f->present = 1;
2036 pDot11f->num_ssid = pInternal->length;
2037 if (pInternal->length) {
2038 qdf_mem_copy((uint8_t *) pDot11f->ssid,
2039 (uint8_t *) &pInternal->ssId, pInternal->length);
2040 }
2041 } /* End populate_dot11f_ssid. */
2042
2043 QDF_STATUS populate_dot11f_ssid2(struct pe_session *pe_session,
2044 tDot11fIESSID *pDot11f)
2045 {
2046 qdf_mem_copy(pDot11f->ssid, pe_session->ssId.ssId,
2047 pe_session->ssId.length);
2048 pDot11f->num_ssid = pe_session->ssId.length;
2049 pDot11f->present = 1;
2050
2051 return QDF_STATUS_SUCCESS;
2052 } /* End populate_dot11f_ssid2. */
2053
2054 void
2055 populate_dot11f_schedule(tSirMacScheduleIE *pSchedule,
2056 tDot11fIESchedule *pDot11f)
2057 {
2058 pDot11f->aggregation = pSchedule->info.aggregation;
2059 pDot11f->tsid = pSchedule->info.tsid;
2060 pDot11f->direction = pSchedule->info.direction;
2061 pDot11f->reserved = pSchedule->info.rsvd;
2062 pDot11f->service_start_time = pSchedule->svcStartTime;
2063 pDot11f->service_interval = pSchedule->svcInterval;
2064 pDot11f->max_service_dur = pSchedule->maxSvcDuration;
2065 pDot11f->spec_interval = pSchedule->specInterval;
2066
2067 pDot11f->present = 1;
2068 } /* End populate_dot11f_schedule. */
2069
2070 void
2071 populate_dot11f_supp_channels(struct mac_context *mac,
2072 tDot11fIESuppChannels *pDot11f,
2073 uint8_t nAssocType, struct pe_session *pe_session)
2074 {
2075 uint8_t i, j = 0;
2076 uint8_t *p;
2077 struct supported_channels supportedChannels;
2078 uint8_t channel, opclass, base_opclass;
2079 uint8_t reg_cc[REG_ALPHA2_LEN + 1];
2080
2081 wlan_add_supported_5Ghz_channels(mac->psoc, mac->pdev,
2082 supportedChannels.channelList,
2083 &supportedChannels.numChnl,
2084 false);
2085
2086 p = supportedChannels.channelList;
2087 pDot11f->num_bands = supportedChannels.numChnl;
2088
2089 wlan_reg_read_current_country(mac->psoc, reg_cc);
2090 for (i = 0U; i < pDot11f->num_bands; i++) {
2091 base_opclass = wlan_reg_dmn_get_opclass_from_channel(
2092 reg_cc,
2093 p[i], BW20);
2094 pDot11f->bands[j][0] = p[i];
2095 pDot11f->bands[j][1] = 1;
2096 channel = p[i];
2097 while (i + 1 < pDot11f->num_bands && (p[i + 1] == channel + 4)) {
2098 opclass = wlan_reg_dmn_get_opclass_from_channel(
2099 reg_cc,
2100 p[i + 1], BW20);
2101 if (base_opclass != opclass)
2102 goto skip;
2103 pDot11f->bands[j][1]++;
2104 channel = p[++i];
2105 }
2106 skip:
2107 j++;
2108 }
2109
2110 pDot11f->num_bands = j;
2111 pDot11f->present = 1;
2112
2113 } /* End populate_dot11f_supp_channels. */
2114
2115 QDF_STATUS
2116 populate_dot11f_supp_rates(struct mac_context *mac,
2117 uint8_t nChannelNum,
2118 tDot11fIESuppRates *pDot11f,
2119 struct pe_session *pe_session)
2120 {
2121 QDF_STATUS nsir_status;
2122 qdf_size_t nRates;
2123 uint8_t rates[SIR_MAC_MAX_NUMBER_OF_RATES];
2124
2125 /* Use the operational rates present in session entry whenever
2126 * nChannelNum is set to OPERATIONAL else use the supported
2127 * rate set from CFG, which is fixed and does not change
2128 * dynamically and is used for sending mgmt frames (lile probe
2129 * req) which need to go out before any session is present.
2130 */
2131 if (POPULATE_DOT11F_RATES_OPERATIONAL == nChannelNum) {
2132 if (pe_session) {
2133 nRates = pe_session->rateSet.numRates;
2134 qdf_mem_copy(rates, pe_session->rateSet.rate,
2135 nRates);
2136 } else {
2137 pe_err("no session context exists while populating Operational Rate Set");
2138 nRates = 0;
2139 }
2140 } else if (14 >= nChannelNum) {
2141 nRates = SIR_MAC_MAX_NUMBER_OF_RATES;
2142 nsir_status = wlan_mlme_get_cfg_str(
2143 rates,
2144 &mac->mlme_cfg->rates.supported_11b,
2145 &nRates);
2146 if (QDF_IS_STATUS_ERROR(nsir_status)) {
2147 pe_err("Failed to retrieve nItem from CFG status: %d",
2148 (nsir_status));
2149 return nsir_status;
2150 }
2151 } else {
2152 nRates = SIR_MAC_MAX_NUMBER_OF_RATES;
2153 nsir_status = wlan_mlme_get_cfg_str(
2154 rates,
2155 &mac->mlme_cfg->rates.supported_11a,
2156 &nRates);
2157 if (QDF_IS_STATUS_ERROR(nsir_status)) {
2158 pe_err("Failed to retrieve nItem from CFG status: %d",
2159 (nsir_status));
2160 return nsir_status;
2161 }
2162 }
2163
2164 if (0 != nRates) {
2165 pDot11f->num_rates = (uint8_t) nRates;
2166 qdf_mem_copy(pDot11f->rates, rates, nRates);
2167 pDot11f->present = 1;
2168 }
2169
2170 return QDF_STATUS_SUCCESS;
2171
2172 } /* End populate_dot11f_supp_rates. */
2173
2174 /**
2175 * populate_dot11f_rates_tdls() - populate supported rates and
2176 * extended supported rates IE.
2177 * @p_mac: Pointer to global mac context
2178 * @p_supp_rates: pointer to supported rates IE
2179 * @p_ext_supp_rates: pointer to extended supported rates IE
2180 * @curr_oper_channel: current operating channel
2181 *
2182 * This function populates the supported rates and extended supported
2183 * rates IE based in the STA capability. If the number of rates
2184 * supported is less than MAX_NUM_SUPPORTED_RATES, only supported rates
2185 * IE is populated.
2186 *
2187 * Return: QDF_STATUS QDF_STATUS_SUCCESS on Success and QDF_STATUS_E_FAILURE
2188 * on failure.
2189 */
2190
2191 QDF_STATUS
2192 populate_dot11f_rates_tdls(struct mac_context *p_mac,
2193 tDot11fIESuppRates *p_supp_rates,
2194 tDot11fIEExtSuppRates *p_ext_supp_rates,
2195 uint8_t curr_oper_channel)
2196 {
2197 tSirMacRateSet temp_rateset;
2198 tSirMacRateSet temp_rateset2;
2199 uint32_t i;
2200 uint32_t self_dot11mode = 0;
2201 qdf_size_t num_rates;
2202
2203 self_dot11mode = p_mac->mlme_cfg->dot11_mode.dot11_mode;
2204
2205 /**
2206 * Include 11b rates only when the device configured in
2207 * auto, 11a/b/g or 11b_only and also if current base
2208 * channel is 5 GHz then no need to advertise the 11b rates.
2209 * If devices move to 2.4GHz off-channel then they can communicate
2210 * in 11g rates i.e. (6, 9, 12, 18, 24, 36 and 54).
2211 */
2212 pe_debug("Current operating channel %d self_dot11mode = %d",
2213 curr_oper_channel, self_dot11mode);
2214
2215 if ((curr_oper_channel <= SIR_11B_CHANNEL_END) &&
2216 ((self_dot11mode == MLME_DOT11_MODE_ALL) ||
2217 (self_dot11mode == MLME_DOT11_MODE_11A) ||
2218 (self_dot11mode == MLME_DOT11_MODE_11AC) ||
2219 (self_dot11mode == MLME_DOT11_MODE_11N) ||
2220 (self_dot11mode == MLME_DOT11_MODE_11G) ||
2221 (self_dot11mode == MLME_DOT11_MODE_11B))) {
2222 num_rates = p_mac->mlme_cfg->rates.supported_11b.len;
2223 wlan_mlme_get_cfg_str((uint8_t *)&temp_rateset.rate,
2224 &p_mac->mlme_cfg->rates.supported_11b,
2225 &num_rates);
2226 temp_rateset.numRates = (uint8_t)num_rates;
2227 } else {
2228 temp_rateset.numRates = 0;
2229 }
2230
2231 /* Include 11a rates when the device configured in non-11b mode */
2232 if (!IS_DOT11_MODE_11B(self_dot11mode)) {
2233 num_rates = p_mac->mlme_cfg->rates.supported_11a.len;
2234 wlan_mlme_get_cfg_str((uint8_t *)&temp_rateset2.rate,
2235 &p_mac->mlme_cfg->rates.supported_11a,
2236 &num_rates);
2237 temp_rateset2.numRates = (uint8_t)num_rates;
2238 } else {
2239 temp_rateset2.numRates = 0;
2240 }
2241
2242 if ((temp_rateset.numRates + temp_rateset2.numRates) >
2243 SIR_MAC_MAX_NUMBER_OF_RATES) {
2244 pe_err("more than %d rates in CFG",
2245 SIR_MAC_MAX_NUMBER_OF_RATES);
2246 return QDF_STATUS_E_FAILURE;
2247 }
2248
2249 /**
2250 * copy all rates in temp_rateset,
2251 * there are SIR_MAC_MAX_NUMBER_OF_RATES rates max
2252 */
2253 for (i = 0; i < temp_rateset2.numRates; i++)
2254 temp_rateset.rate[i + temp_rateset.numRates] =
2255 temp_rateset2.rate[i];
2256
2257 temp_rateset.numRates += temp_rateset2.numRates;
2258
2259 if (temp_rateset.numRates <= MAX_NUM_SUPPORTED_RATES) {
2260 p_supp_rates->num_rates = temp_rateset.numRates;
2261 qdf_mem_copy(p_supp_rates->rates, temp_rateset.rate,
2262 p_supp_rates->num_rates);
2263 p_supp_rates->present = 1;
2264 } else { /* Populate extended capability as well */
2265 p_supp_rates->num_rates = MAX_NUM_SUPPORTED_RATES;
2266 qdf_mem_copy(p_supp_rates->rates, temp_rateset.rate,
2267 p_supp_rates->num_rates);
2268 p_supp_rates->present = 1;
2269
2270 p_ext_supp_rates->num_rates = temp_rateset.numRates -
2271 MAX_NUM_SUPPORTED_RATES;
2272 qdf_mem_copy(p_ext_supp_rates->rates,
2273 (uint8_t *)temp_rateset.rate +
2274 MAX_NUM_SUPPORTED_RATES,
2275 p_ext_supp_rates->num_rates);
2276 p_ext_supp_rates->present = 1;
2277 }
2278
2279 return QDF_STATUS_SUCCESS;
2280
2281 } /* End populate_dot11f_rates_tdls */
2282
2283
2284 QDF_STATUS
2285 populate_dot11f_tpc_report(struct mac_context *mac,
2286 tDot11fIETPCReport *pDot11f, struct pe_session *pe_session)
2287 {
2288 uint16_t staid;
2289 uint8_t tx_power;
2290 QDF_STATUS nSirStatus;
2291
2292 nSirStatus = lim_get_mgmt_staid(mac, &staid, pe_session);
2293 if (QDF_STATUS_SUCCESS != nSirStatus) {
2294 pe_err("Failed to get the STAID in Populate Dot11fTPCReport; lim_get_mgmt_staid returned status %d",
2295 nSirStatus);
2296 return QDF_STATUS_E_FAILURE;
2297 }
2298 tx_power = wlan_reg_get_channel_reg_power_for_freq(
2299 mac->pdev, pe_session->curr_op_freq);
2300 pDot11f->tx_power = tx_power;
2301 pDot11f->link_margin = 0;
2302 pDot11f->present = 1;
2303
2304 return QDF_STATUS_SUCCESS;
2305 } /* End populate_dot11f_tpc_report. */
2306
2307 void populate_dot11f_ts_info(struct mac_ts_info *pInfo,
2308 tDot11fFfTSInfo *pDot11f)
2309 {
2310 pDot11f->traffic_type = pInfo->traffic.trafficType;
2311 pDot11f->tsid = pInfo->traffic.tsid;
2312 pDot11f->direction = pInfo->traffic.direction;
2313 pDot11f->access_policy = pInfo->traffic.accessPolicy;
2314 pDot11f->aggregation = pInfo->traffic.aggregation;
2315 pDot11f->psb = pInfo->traffic.psb;
2316 pDot11f->user_priority = pInfo->traffic.userPrio;
2317 pDot11f->tsinfo_ack_pol = pInfo->traffic.ackPolicy;
2318 pDot11f->schedule = pInfo->schedule.schedule;
2319 } /* End PopulatedDot11fTSInfo. */
2320
2321 void populate_dot11f_wmm(struct mac_context *mac,
2322 tDot11fIEWMMInfoAp *pInfo,
2323 tDot11fIEWMMParams *pParams,
2324 tDot11fIEWMMCaps *pCaps, struct pe_session *pe_session)
2325 {
2326 if (pe_session->limWmeEnabled) {
2327 populate_dot11f_wmm_params(mac, pParams,
2328 pe_session);
2329 if (pe_session->limWsmEnabled)
2330 populate_dot11f_wmm_caps(pCaps);
2331 }
2332 } /* End populate_dot11f_wmm. */
2333
2334 void populate_dot11f_wmm_caps(tDot11fIEWMMCaps *pCaps)
2335 {
2336 pCaps->version = SIR_MAC_OUI_VERSION_1;
2337 pCaps->qack = 0;
2338 pCaps->queue_request = 1;
2339 pCaps->txop_request = 0;
2340 pCaps->more_ack = 0;
2341 pCaps->present = 1;
2342 } /* End PopulateDot11fWmmCaps. */
2343
2344 #ifdef FEATURE_WLAN_ESE
2345 #ifdef WLAN_FEATURE_HOST_ROAM
2346 void populate_dot11f_re_assoc_tspec(struct mac_context *mac,
2347 tDot11fReAssocRequest *pReassoc,
2348 struct pe_session *pe_session)
2349 {
2350 uint8_t numTspecs = 0, idx;
2351 tTspecInfo *pTspec = NULL;
2352 struct mlme_legacy_priv *mlme_priv;
2353
2354 mlme_priv = wlan_vdev_mlme_get_ext_hdl(pe_session->vdev);
2355 if (!mlme_priv)
2356 return;
2357
2358 numTspecs = mlme_priv->connect_info.ese_tspec_info.numTspecs;
2359 pTspec = &mlme_priv->connect_info.ese_tspec_info.tspec[0];
2360 pReassoc->num_WMMTSPEC = numTspecs;
2361 if (numTspecs) {
2362 for (idx = 0; idx < numTspecs; idx++) {
2363 populate_dot11f_wmmtspec(&pTspec->tspec,
2364 &pReassoc->WMMTSPEC[idx]);
2365 pTspec->tspec.mediumTime = 0;
2366 pTspec++;
2367 }
2368 }
2369 }
2370 #endif
2371 void ese_populate_wmm_tspec(struct mac_tspec_ie *source,
2372 ese_wmm_tspec_ie *dest)
2373 {
2374 dest->traffic_type = source->tsinfo.traffic.trafficType;
2375 dest->tsid = source->tsinfo.traffic.tsid;
2376 dest->direction = source->tsinfo.traffic.direction;
2377 dest->access_policy = source->tsinfo.traffic.accessPolicy;
2378 dest->aggregation = source->tsinfo.traffic.aggregation;
2379 dest->psb = source->tsinfo.traffic.psb;
2380 dest->user_priority = source->tsinfo.traffic.userPrio;
2381 dest->tsinfo_ack_pol = source->tsinfo.traffic.ackPolicy;
2382 dest->burst_size_defn = source->tsinfo.traffic.burstSizeDefn;
2383 /* As defined in IEEE 802.11-2007, section 7.3.2.30
2384 * Nominal MSDU size: Bit[0:14]=Size, Bit[15]=Fixed
2385 */
2386 dest->size = (source->nomMsduSz & SIZE_MASK);
2387 dest->fixed = (source->nomMsduSz & FIXED_MASK) ? 1 : 0;
2388 dest->max_msdu_size = source->maxMsduSz;
2389 dest->min_service_int = source->minSvcInterval;
2390 dest->max_service_int = source->maxSvcInterval;
2391 dest->inactivity_int = source->inactInterval;
2392 dest->suspension_int = source->suspendInterval;
2393 dest->service_start_time = source->svcStartTime;
2394 dest->min_data_rate = source->minDataRate;
2395 dest->mean_data_rate = source->meanDataRate;
2396 dest->peak_data_rate = source->peakDataRate;
2397 dest->burst_size = source->maxBurstSz;
2398 dest->delay_bound = source->delayBound;
2399 dest->min_phy_rate = source->minPhyRate;
2400 dest->surplus_bw_allowance = source->surplusBw;
2401 dest->medium_time = source->mediumTime;
2402 }
2403
2404 #endif
2405
2406 void populate_dot11f_wmm_info_ap(struct mac_context *mac, tDot11fIEWMMInfoAp *pInfo,
2407 struct pe_session *pe_session)
2408 {
2409 pInfo->version = SIR_MAC_OUI_VERSION_1;
2410
2411 /* WMM Specification 3.1.3, 3.2.3 */
2412 pInfo->param_set_count = (0xf & pe_session->gLimEdcaParamSetCount);
2413 if (LIM_IS_AP_ROLE(pe_session))
2414 pInfo->uapsd = (0x1 & pe_session->apUapsdEnable);
2415 else
2416 pInfo->uapsd = (0x1 & mac->lim.gUapsdEnable);
2417
2418 pInfo->present = 1;
2419 }
2420
2421 void populate_dot11f_wmm_info_station_per_session(struct mac_context *mac,
2422 struct pe_session *pe_session,
2423 tDot11fIEWMMInfoStation *pInfo)
2424 {
2425 uint8_t max_sp_length = 0;
2426
2427 max_sp_length = mac->mlme_cfg->wmm_params.max_sp_length;
2428 pInfo->version = SIR_MAC_OUI_VERSION_1;
2429 pInfo->acvo_uapsd =
2430 LIM_UAPSD_GET(ACVO, pe_session->gUapsdPerAcBitmask);
2431 pInfo->acvi_uapsd =
2432 LIM_UAPSD_GET(ACVI, pe_session->gUapsdPerAcBitmask);
2433 pInfo->acbk_uapsd =
2434 LIM_UAPSD_GET(ACBK, pe_session->gUapsdPerAcBitmask);
2435 pInfo->acbe_uapsd =
2436 LIM_UAPSD_GET(ACBE, pe_session->gUapsdPerAcBitmask);
2437
2438 pInfo->max_sp_length = max_sp_length;
2439 pInfo->present = 1;
2440 }
2441
2442 void populate_dot11f_wmm_params(struct mac_context *mac,
2443 tDot11fIEWMMParams *pParams,
2444 struct pe_session *pe_session)
2445 {
2446 pParams->version = SIR_MAC_OUI_VERSION_1;
2447
2448 if (LIM_IS_AP_ROLE(pe_session))
2449 pParams->qosInfo =
2450 (pe_session->
2451 apUapsdEnable << 7) | ((uint8_t) (0x0f & pe_session->
2452 gLimEdcaParamSetCount));
2453 else
2454 pParams->qosInfo =
2455 (mac->lim.
2456 gUapsdEnable << 7) | ((uint8_t) (0x0f & pe_session->
2457 gLimEdcaParamSetCount));
2458
2459 /* Fill each EDCA parameter set in order: be, bk, vi, vo */
2460 pParams->acbe_aifsn =
2461 (0xf & SET_AIFSN(pe_session->gLimEdcaParamsBC[0].aci.aifsn));
2462 pParams->acbe_acm = (0x1 & pe_session->gLimEdcaParamsBC[0].aci.acm);
2463 pParams->acbe_aci = (0x3 & QCA_WLAN_AC_BE);
2464 pParams->acbe_acwmin =
2465 (0xf & pe_session->gLimEdcaParamsBC[0].cw.min);
2466 pParams->acbe_acwmax =
2467 (0xf & pe_session->gLimEdcaParamsBC[0].cw.max);
2468 pParams->acbe_txoplimit = pe_session->gLimEdcaParamsBC[0].txoplimit;
2469
2470 pParams->acbk_aifsn =
2471 (0xf & SET_AIFSN(pe_session->gLimEdcaParamsBC[1].aci.aifsn));
2472 pParams->acbk_acm = (0x1 & pe_session->gLimEdcaParamsBC[1].aci.acm);
2473 pParams->acbk_aci = (0x3 & QCA_WLAN_AC_BK);
2474 pParams->acbk_acwmin =
2475 (0xf & pe_session->gLimEdcaParamsBC[1].cw.min);
2476 pParams->acbk_acwmax =
2477 (0xf & pe_session->gLimEdcaParamsBC[1].cw.max);
2478 pParams->acbk_txoplimit = pe_session->gLimEdcaParamsBC[1].txoplimit;
2479
2480 if (LIM_IS_AP_ROLE(pe_session))
2481 pParams->acvi_aifsn =
2482 (0xf & pe_session->gLimEdcaParamsBC[2].aci.aifsn);
2483 else
2484 pParams->acvi_aifsn =
2485 (0xf &
2486 SET_AIFSN(pe_session->gLimEdcaParamsBC[2].aci.aifsn));
2487
2488 pParams->acvi_acm = (0x1 & pe_session->gLimEdcaParamsBC[2].aci.acm);
2489 pParams->acvi_aci = (0x3 & QCA_WLAN_AC_VI);
2490 pParams->acvi_acwmin =
2491 (0xf & pe_session->gLimEdcaParamsBC[2].cw.min);
2492 pParams->acvi_acwmax =
2493 (0xf & pe_session->gLimEdcaParamsBC[2].cw.max);
2494 pParams->acvi_txoplimit = pe_session->gLimEdcaParamsBC[2].txoplimit;
2495
2496 if (LIM_IS_AP_ROLE(pe_session))
2497 pParams->acvo_aifsn =
2498 (0xf & pe_session->gLimEdcaParamsBC[3].aci.aifsn);
2499 else
2500 pParams->acvo_aifsn =
2501 (0xf &
2502 SET_AIFSN(pe_session->gLimEdcaParamsBC[3].aci.aifsn));
2503
2504 pParams->acvo_acm = (0x1 & pe_session->gLimEdcaParamsBC[3].aci.acm);
2505 pParams->acvo_aci = (0x3 & QCA_WLAN_AC_VO);
2506 pParams->acvo_acwmin =
2507 (0xf & pe_session->gLimEdcaParamsBC[3].cw.min);
2508 pParams->acvo_acwmax =
2509 (0xf & pe_session->gLimEdcaParamsBC[3].cw.max);
2510 pParams->acvo_txoplimit = pe_session->gLimEdcaParamsBC[3].txoplimit;
2511
2512 pParams->present = 1;
2513
2514 } /* End populate_dot11f_wmm_params. */
2515
2516 QDF_STATUS
2517 populate_dot11f_wpa(struct mac_context *mac,
2518 tpSirRSNie pRsnIe, tDot11fIEWPA *pDot11f)
2519 {
2520 uint32_t status;
2521 int idx;
2522
2523 if (pRsnIe->length) {
2524 idx = find_ie_location(mac, pRsnIe, DOT11F_EID_WPA);
2525 if (0 <= idx) {
2526 status = dot11f_unpack_ie_wpa(mac, pRsnIe->rsnIEdata + idx + 2 + 4, /* EID, length, OUI */
2527 pRsnIe->rsnIEdata[idx + 1] - 4, /* OUI */
2528 pDot11f, false);
2529 if (DOT11F_FAILED(status)) {
2530 pe_err("Parse failure in Populate Dot11fWPA (0x%08x)",
2531 status);
2532 return QDF_STATUS_E_FAILURE;
2533 }
2534 }
2535 }
2536
2537 return QDF_STATUS_SUCCESS;
2538 } /* End populate_dot11f_wpa. */
2539
2540 QDF_STATUS populate_dot11f_wpa_opaque(struct mac_context *mac,
2541 tpSirRSNie pRsnIe,
2542 tDot11fIEWPAOpaque *pDot11f)
2543 {
2544 int idx;
2545
2546 if (pRsnIe->length) {
2547 idx = find_ie_location(mac, pRsnIe, DOT11F_EID_WPA);
2548 if (0 <= idx) {
2549 pDot11f->present = 1;
2550 pDot11f->num_data = pRsnIe->rsnIEdata[idx + 1] - 4;
2551 qdf_mem_copy(pDot11f->data, pRsnIe->rsnIEdata + idx + 2 + 4, /* EID, len, OUI */
2552 pRsnIe->rsnIEdata[idx + 1] - 4); /* OUI */
2553 }
2554 }
2555
2556 return QDF_STATUS_SUCCESS;
2557
2558 } /* End populate_dot11f_wpa_opaque. */
2559
2560 /* ////////////////////////////////////////////////////////////////////// */
2561
2562 QDF_STATUS
2563 sir_convert_probe_req_frame2_struct(struct mac_context *mac,
2564 uint8_t *pFrame,
2565 uint32_t nFrame, tpSirProbeReq pProbeReq)
2566 {
2567 uint32_t status;
2568 tDot11fProbeRequest *pr;
2569
2570 pr = qdf_mem_malloc(sizeof(*pr));
2571 if (!pr) {
2572 pe_err("malloc failed for probe request");
2573 return QDF_STATUS_E_FAILURE;
2574 }
2575
2576 /* Ok, zero-init our [out] parameter, */
2577 qdf_mem_zero((uint8_t *) pProbeReq, sizeof(tSirProbeReq));
2578
2579 /* delegate to the framesc-generated code, */
2580 status = dot11f_unpack_probe_request(mac, pFrame, nFrame, pr, false);
2581 if (DOT11F_FAILED(status)) {
2582 pe_err("Failed to parse a Probe Request (0x%08x, %d bytes):",
2583 status, nFrame);
2584 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_ERROR,
2585 pFrame, nFrame);
2586 qdf_mem_free(pr);
2587 return QDF_STATUS_E_FAILURE;
2588 } else if (DOT11F_WARNED(status)) {
2589 pe_debug("There were warnings while unpacking a Probe Request (0x%08x, %d bytes):",
2590 status, nFrame);
2591 }
2592 /* & "transliterate" from a 'tDot11fProbeRequestto' a 'tSirProbeReq'... */
2593 if (!pr->SSID.present) {
2594 pe_debug("Mandatory IE SSID not present!");
2595 } else {
2596 pProbeReq->ssidPresent = 1;
2597 convert_ssid(mac, &pProbeReq->ssId, &pr->SSID);
2598 }
2599
2600 if (!pr->SuppRates.present) {
2601 pe_debug_rl("Mandatory IE Supported Rates not present!");
2602 qdf_mem_free(pr);
2603 return QDF_STATUS_E_FAILURE;
2604 } else {
2605 pProbeReq->suppRatesPresent = 1;
2606 convert_supp_rates(mac, &pProbeReq->supportedRates,
2607 &pr->SuppRates);
2608 }
2609
2610 if (pr->ExtSuppRates.present) {
2611 pProbeReq->extendedRatesPresent = 1;
2612 convert_ext_supp_rates(mac, &pProbeReq->extendedRates,
2613 &pr->ExtSuppRates);
2614 }
2615
2616 if (pr->HTCaps.present)
2617 qdf_mem_copy(&pProbeReq->HTCaps, &pr->HTCaps,
2618 sizeof(tDot11fIEHTCaps));
2619
2620 if (pr->WscProbeReq.present) {
2621 pProbeReq->wscIePresent = 1;
2622 memcpy(&pProbeReq->probeReqWscIeInfo, &pr->WscProbeReq,
2623 sizeof(tDot11fIEWscProbeReq));
2624 }
2625 if (pr->VHTCaps.present)
2626 qdf_mem_copy(&pProbeReq->VHTCaps, &pr->VHTCaps,
2627 sizeof(tDot11fIEVHTCaps));
2628
2629 if (pr->P2PProbeReq.present)
2630 pProbeReq->p2pIePresent = 1;
2631
2632 if (pr->he_cap.present)
2633 qdf_mem_copy(&pProbeReq->he_cap, &pr->he_cap,
2634 sizeof(tDot11fIEhe_cap));
2635
2636 qdf_mem_free(pr);
2637
2638 return QDF_STATUS_SUCCESS;
2639 } /* End sir_convert_probe_req_frame2_struct. */
2640
2641
2642 /**
2643 * sir_validate_and_rectify_ies() - API to check malformed frame
2644 * @mac_ctx: mac context
2645 * @mgmt_frame: pointer to management frame
2646 * @frame_bytes: no of bytes in frame
2647 * @missing_rsn_bytes: missing rsn bytes
2648 *
2649 * The frame would contain fixed IEs of 12 bytes followed by variable IEs
2650 * (Tagged elements). Every Tagged IE has tag number, tag length and data.
2651 * Tag length indicates the size of data in bytes.
2652 * This function checks for size of Frame received with the sum of all IEs.
2653 * And also rectifies missing optional fields in IE.
2654 *
2655 * NOTE : Presently this function rectifies RSN capability in RSN IE, can
2656 * be extended to rectify other optional fields in other IEs.
2657 *
2658 * Return: 0 on success, error number otherwise.
2659 */
2660 QDF_STATUS
2661 sir_validate_and_rectify_ies(struct mac_context *mac_ctx,
2662 uint8_t *mgmt_frame,
2663 uint32_t frame_bytes,
2664 uint32_t *missing_rsn_bytes)
2665 {
2666 uint32_t length = SIZE_OF_FIXED_PARAM;
2667 uint8_t *ref_frame = NULL;
2668
2669 /* Frame contains atleast one IE */
2670 if (frame_bytes > (SIZE_OF_FIXED_PARAM +
2671 SIZE_OF_TAG_PARAM_NUM + SIZE_OF_TAG_PARAM_LEN)) {
2672 while (length < frame_bytes) {
2673 /* ref frame points to next IE */
2674 ref_frame = mgmt_frame + length;
2675 length += (uint32_t)(SIZE_OF_TAG_PARAM_NUM +
2676 SIZE_OF_TAG_PARAM_LEN +
2677 (*(ref_frame + SIZE_OF_TAG_PARAM_NUM)));
2678 }
2679 if (length != frame_bytes) {
2680 /*
2681 * Workaround : Some APs may not include RSN
2682 * Capability but the length of which is included in
2683 * RSN IE length. This may cause in updating RSN
2684 * Capability with junk value. To avoid this, add RSN
2685 * Capability value with default value.
2686 */
2687 if (ref_frame && (*ref_frame == RSNIEID) &&
2688 (length == (frame_bytes +
2689 RSNIE_CAPABILITY_LEN))) {
2690 /* Assume RSN Capability as 00 */
2691 qdf_mem_set((uint8_t *)(mgmt_frame +
2692 (frame_bytes)),
2693 RSNIE_CAPABILITY_LEN,
2694 DEFAULT_RSNIE_CAP_VAL);
2695 *missing_rsn_bytes = RSNIE_CAPABILITY_LEN;
2696 pe_debug("Added RSN Capability to RSNIE as 0x00 0x00");
2697 return QDF_STATUS_SUCCESS;
2698 }
2699 return QDF_STATUS_E_FAILURE;
2700 }
2701 }
2702 return QDF_STATUS_SUCCESS;
2703 }
2704
2705 void sir_copy_caps_info(struct mac_context *mac_ctx, tDot11fFfCapabilities caps,
2706 tpSirProbeRespBeacon pProbeResp)
2707 {
2708 pProbeResp->capabilityInfo.ess = caps.ess;
2709 pProbeResp->capabilityInfo.ibss = caps.ibss;
2710 pProbeResp->capabilityInfo.cfPollable = caps.cfPollable;
2711 pProbeResp->capabilityInfo.cfPollReq = caps.cfPollReq;
2712 pProbeResp->capabilityInfo.privacy = caps.privacy;
2713 pProbeResp->capabilityInfo.shortPreamble = caps.shortPreamble;
2714 pProbeResp->capabilityInfo.criticalUpdateFlag = caps.criticalUpdateFlag;
2715 pProbeResp->capabilityInfo.channelAgility = caps.channelAgility;
2716 pProbeResp->capabilityInfo.spectrumMgt = caps.spectrumMgt;
2717 pProbeResp->capabilityInfo.qos = caps.qos;
2718 pProbeResp->capabilityInfo.shortSlotTime = caps.shortSlotTime;
2719 pProbeResp->capabilityInfo.apsd = caps.apsd;
2720 pProbeResp->capabilityInfo.rrm = caps.rrm;
2721 pProbeResp->capabilityInfo.dsssOfdm = caps.dsssOfdm;
2722 pProbeResp->capabilityInfo.delayedBA = caps.delayedBA;
2723 pProbeResp->capabilityInfo.immediateBA = caps.immediateBA;
2724 }
2725
2726 #ifdef WLAN_FEATURE_FILS_SK
2727 static void populate_dot11f_fils_rsn(struct mac_context *mac_ctx,
2728 tDot11fIERSNOpaque *p_dot11f,
2729 uint8_t *rsn_ie)
2730 {
2731 pe_debug("FILS RSN IE length %d", rsn_ie[1]);
2732 if (rsn_ie[1]) {
2733 p_dot11f->present = 1;
2734 p_dot11f->num_data = rsn_ie[1];
2735 qdf_mem_copy(p_dot11f->data, &rsn_ie[2], rsn_ie[1]);
2736 }
2737 }
2738
2739 void populate_dot11f_fils_params(struct mac_context *mac_ctx,
2740 tDot11fAssocRequest *frm,
2741 struct pe_session *pe_session)
2742 {
2743 struct pe_fils_session *fils_info = pe_session->fils_info;
2744
2745 /* Populate RSN IE with FILS AKM */
2746 populate_dot11f_fils_rsn(mac_ctx, &frm->RSNOpaque,
2747 fils_info->rsn_ie);
2748
2749 /* Populate FILS session IE */
2750 frm->fils_session.present = true;
2751 qdf_mem_copy(frm->fils_session.session,
2752 fils_info->fils_session, FILS_SESSION_LENGTH);
2753
2754 /* Populate FILS Key confirmation IE */
2755 if (fils_info->key_auth_len) {
2756 frm->fils_key_confirmation.present = true;
2757 frm->fils_key_confirmation.num_key_auth =
2758 fils_info->key_auth_len;
2759
2760 qdf_mem_copy(frm->fils_key_confirmation.key_auth,
2761 fils_info->key_auth, fils_info->key_auth_len);
2762 }
2763 }
2764
2765 /**
2766 * update_fils_data: update fils params from beacon/probe response
2767 * @fils_ind: pointer to sir_fils_indication
2768 * @fils_indication: pointer to tDot11fIEfils_indication
2769 *
2770 * Return: None
2771 */
2772 void update_fils_data(struct sir_fils_indication *fils_ind,
2773 tDot11fIEfils_indication *fils_indication)
2774 {
2775 uint8_t *data;
2776 uint8_t remaining_data = fils_indication->num_variable_data;
2777
2778 data = fils_indication->variable_data;
2779 fils_ind->is_present = true;
2780 fils_ind->is_ip_config_supported =
2781 fils_indication->is_ip_config_supported;
2782 fils_ind->is_fils_sk_auth_supported =
2783 fils_indication->is_fils_sk_auth_supported;
2784 fils_ind->is_fils_sk_auth_pfs_supported =
2785 fils_indication->is_fils_sk_auth_pfs_supported;
2786 fils_ind->is_pk_auth_supported =
2787 fils_indication->is_pk_auth_supported;
2788 if (fils_indication->is_cache_id_present) {
2789 if (remaining_data < SIR_CACHE_IDENTIFIER_LEN) {
2790 pe_err("Failed to copy Cache Identifier, Invalid remaining data %d",
2791 remaining_data);
2792 return;
2793 }
2794 fils_ind->cache_identifier.is_present = true;
2795 qdf_mem_copy(fils_ind->cache_identifier.identifier,
2796 data, SIR_CACHE_IDENTIFIER_LEN);
2797 data = data + SIR_CACHE_IDENTIFIER_LEN;
2798 remaining_data = remaining_data - SIR_CACHE_IDENTIFIER_LEN;
2799 }
2800 if (fils_indication->is_hessid_present) {
2801 if (remaining_data < SIR_HESSID_LEN) {
2802 pe_err("Failed to copy HESSID, Invalid remaining data %d",
2803 remaining_data);
2804 return;
2805 }
2806 fils_ind->hessid.is_present = true;
2807 qdf_mem_copy(fils_ind->hessid.hessid,
2808 data, SIR_HESSID_LEN);
2809 data = data + SIR_HESSID_LEN;
2810 remaining_data = remaining_data - SIR_HESSID_LEN;
2811 }
2812 if (fils_indication->realm_identifiers_cnt) {
2813 if (remaining_data < (fils_indication->realm_identifiers_cnt *
2814 SIR_REALM_LEN)) {
2815 pe_err("Failed to copy Realm Identifier, Invalid remaining data %d realm_cnt %d",
2816 remaining_data,
2817 fils_indication->realm_identifiers_cnt);
2818 return;
2819 }
2820 fils_ind->realm_identifier.is_present = true;
2821 fils_ind->realm_identifier.realm_cnt =
2822 fils_indication->realm_identifiers_cnt;
2823 qdf_mem_copy(fils_ind->realm_identifier.realm,
2824 data, fils_ind->realm_identifier.realm_cnt *
2825 SIR_REALM_LEN);
2826 }
2827 }
2828 #endif
2829
2830 #ifdef WLAN_FEATURE_11AX_BSS_COLOR
2831 static void update_bss_color_change_ie_from_probe_rsp(
2832 tDot11fProbeResponse *prb_frm,
2833 tpSirProbeRespBeacon prb_rsp_struct)
2834 {
2835 if (prb_frm->bss_color_change.present) {
2836 pe_debug("11AX: HE BSS color change present");
2837 qdf_mem_copy(&prb_rsp_struct->vendor_he_bss_color_change,
2838 &prb_frm->bss_color_change,
2839 sizeof(tDot11fIEbss_color_change));
2840 }
2841 }
2842 #else
2843 static inline void update_bss_color_change_ie_from_probe_rsp(
2844 tDot11fProbeResponse *prb_frm,
2845 tpSirProbeRespBeacon prb_rsp_struct)
2846 {}
2847 #endif
2848
2849 #ifdef WLAN_FEATURE_11BE
2850 static void
2851 sir_convert_probe_frame2_eht_struct(tDot11fProbeResponse *pr,
2852 tpSirProbeRespBeacon p_probe_resp)
2853 {
2854 if (pr->eht_cap.present) {
2855 qdf_mem_copy(&p_probe_resp->eht_cap, &pr->eht_cap,
2856 sizeof(tDot11fIEeht_cap));
2857 }
2858 }
2859 #else
2860 static inline void
2861 sir_convert_probe_frame2_eht_struct(tDot11fProbeResponse *pr,
2862 tpSirProbeRespBeacon p_probe_resp)
2863 {
2864 }
2865 #endif
2866
2867 #ifdef WLAN_FEATURE_11BE_MLO
2868 static QDF_STATUS
2869 sir_convert_probe_frame2_mlo_struct(uint8_t *pframe,
2870 uint32_t nframe,
2871 tDot11fProbeResponse *pr,
2872 tpSirProbeRespBeacon p_probe_resp)
2873 {
2874 uint32_t status;
2875 uint8_t *ml_ie;
2876 qdf_size_t ml_ie_total_len;
2877
2878 if (pr->mlo_ie.present) {
2879 status = util_find_mlie(pframe + WLAN_PROBE_RESP_IES_OFFSET,
2880 nframe - WLAN_PROBE_RESP_IES_OFFSET,
2881 &ml_ie, &ml_ie_total_len);
2882 if (QDF_IS_STATUS_SUCCESS(status)) {
2883 sir_convert_mlo_probe_rsp_frame2_struct(ml_ie,
2884 ml_ie_total_len,
2885 &p_probe_resp->mlo_ie);
2886 }
2887 }
2888
2889 return QDF_STATUS_SUCCESS;
2890 }
2891 #else
2892 static inline QDF_STATUS
2893 sir_convert_probe_frame2_mlo_struct(uint8_t *pframe,
2894 uint32_t nframe,
2895 tDot11fProbeResponse *pr,
2896 tpSirProbeRespBeacon p_probe_resp)
2897 {
2898 return QDF_STATUS_SUCCESS;
2899 }
2900 #endif
2901
2902 #ifdef WLAN_FEATURE_11BE_MLO
2903 static QDF_STATUS
2904 sir_convert_probe_frame2_t2lm_struct(tDot11fProbeResponse *pr,
2905 tpSirProbeRespBeacon bcn_struct)
2906 {
2907 QDF_STATUS status = QDF_STATUS_SUCCESS;
2908 struct wlan_t2lm_context *t2lm_ctx;
2909 /* add 3 bytes for extn_ie_header */
2910 uint8_t ie[DOT11F_IE_T2LM_IE_MAX_LEN + 3];
2911 struct wlan_t2lm_info t2lm;
2912 uint8_t i;
2913
2914 t2lm_ctx = &bcn_struct->t2lm_ctx;
2915 qdf_mem_zero(&t2lm_ctx->established_t2lm.t2lm,
2916 sizeof(struct wlan_t2lm_info));
2917 t2lm_ctx->established_t2lm.t2lm.direction = WLAN_T2LM_INVALID_DIRECTION;
2918
2919 qdf_mem_zero(&t2lm_ctx->upcoming_t2lm.t2lm,
2920 sizeof(struct wlan_t2lm_info));
2921 t2lm_ctx->upcoming_t2lm.t2lm.direction = WLAN_T2LM_INVALID_DIRECTION;
2922
2923 if (!pr->num_t2lm_ie)
2924 return status;
2925
2926 pe_debug("Number of T2LM IEs in probe rsp %d", pr->num_t2lm_ie);
2927 for (i = 0; i < pr->num_t2lm_ie; i++) {
2928 qdf_mem_zero(&ie[0], DOT11F_IE_T2LM_IE_MAX_LEN + 3);
2929 qdf_mem_zero(&t2lm, sizeof(struct wlan_t2lm_info));
2930 ie[ID_POS] = WLAN_ELEMID_EXTN_ELEM;
2931 ie[TAG_LEN_POS] = pr->t2lm_ie[i].num_data + 1;
2932 ie[IDEXT_POS] = WLAN_EXTN_ELEMID_T2LM;
2933 qdf_mem_copy(&ie[3], &pr->t2lm_ie[i].data[0],
2934 pr->t2lm_ie[i].num_data);
2935
2936 qdf_trace_hex_dump(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_DEBUG,
2937 &ie[0], pr->t2lm_ie[i].num_data + 3);
2938
2939 if (ie[TAG_LEN_POS] + 2 > DOT11F_IE_T2LM_IE_MAX_LEN + 3) {
2940 pe_debug("Invalid T2LM IE length");
2941 return QDF_STATUS_E_PROTO;
2942 }
2943
2944 status = wlan_mlo_parse_t2lm_info(&ie[0], &t2lm);
2945 if (QDF_IS_STATUS_ERROR(status)) {
2946 pe_debug("Parse T2LM IE fail");
2947 return status;
2948 }
2949
2950 if (!t2lm.mapping_switch_time_present &&
2951 t2lm.expected_duration_present) {
2952 qdf_mem_copy(&t2lm_ctx->established_t2lm.t2lm, &t2lm,
2953 sizeof(struct wlan_t2lm_info));
2954 pe_debug("Parse established T2LM IE success");
2955 } else if (t2lm.mapping_switch_time_present) {
2956 qdf_mem_copy(&t2lm_ctx->upcoming_t2lm.t2lm, &t2lm,
2957 sizeof(struct wlan_t2lm_info));
2958 pe_debug("Parse upcoming T2LM IE success");
2959 }
2960 pe_debug("Parse T2LM IE success");
2961 }
2962 return status;
2963 }
2964 #else
2965 static inline QDF_STATUS
2966 sir_convert_probe_frame2_t2lm_struct(tDot11fProbeResponse *pr,
2967 tpSirProbeRespBeacon bcn_struct)
2968 {
2969 return QDF_STATUS_SUCCESS;
2970 }
2971 #endif
2972
2973 QDF_STATUS sir_convert_probe_frame2_struct(struct mac_context *mac,
2974 uint8_t *pFrame,
2975 uint32_t nFrame,
2976 tpSirProbeRespBeacon pProbeResp)
2977 {
2978 uint32_t status;
2979 tDot11fProbeResponse *pr;
2980
2981 /* Ok, zero-init our [out] parameter, */
2982 qdf_mem_zero((uint8_t *) pProbeResp, sizeof(tSirProbeRespBeacon));
2983
2984 pr = qdf_mem_malloc(sizeof(tDot11fProbeResponse));
2985 if (!pr)
2986 return QDF_STATUS_E_NOMEM;
2987
2988 /* delegate to the framesc-generated code, */
2989 status = dot11f_unpack_probe_response(mac, pFrame, nFrame, pr, false);
2990 if (DOT11F_FAILED(status)) {
2991 pe_err("Failed to parse a Probe Response (0x%08x, %d bytes):",
2992 status, nFrame);
2993 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_DEBUG,
2994 pFrame, nFrame);
2995 qdf_mem_free(pr);
2996 return QDF_STATUS_E_FAILURE;
2997 }
2998 /* & "transliterate" from a 'tDot11fProbeResponse' to a 'tSirProbeRespBeacon'... */
2999
3000 /* Timestamp */
3001 qdf_mem_copy((uint8_t *) pProbeResp->timeStamp,
3002 (uint8_t *) &pr->TimeStamp, sizeof(tSirMacTimeStamp));
3003
3004 /* Beacon Interval */
3005 pProbeResp->beaconInterval = pr->BeaconInterval.interval;
3006
3007 sir_copy_caps_info(mac, pr->Capabilities, pProbeResp);
3008
3009 if (!pr->SSID.present) {
3010 pe_debug("Mandatory IE SSID not present!");
3011 } else {
3012 pProbeResp->ssidPresent = 1;
3013 convert_ssid(mac, &pProbeResp->ssId, &pr->SSID);
3014 }
3015
3016 if (!pr->SuppRates.present) {
3017 pe_debug_rl("Mandatory IE Supported Rates not present!");
3018 } else {
3019 pProbeResp->suppRatesPresent = 1;
3020 convert_supp_rates(mac, &pProbeResp->supportedRates,
3021 &pr->SuppRates);
3022 }
3023
3024 if (pr->ExtSuppRates.present) {
3025 pProbeResp->extendedRatesPresent = 1;
3026 convert_ext_supp_rates(mac, &pProbeResp->extendedRates,
3027 &pr->ExtSuppRates);
3028 }
3029
3030 if (pr->CFParams.present) {
3031 pProbeResp->cfPresent = 1;
3032 convert_cf_params(mac, &pProbeResp->cfParamSet, &pr->CFParams);
3033 }
3034
3035 if (pr->Country.present) {
3036 pProbeResp->countryInfoPresent = 1;
3037 convert_country(mac, &pProbeResp->countryInfoParam,
3038 &pr->Country);
3039 }
3040
3041 if (pr->EDCAParamSet.present) {
3042 pProbeResp->edcaPresent = 1;
3043 convert_edca_param(mac, &pProbeResp->edcaParams,
3044 &pr->EDCAParamSet);
3045 }
3046
3047 if (pr->ChanSwitchAnn.present) {
3048 pProbeResp->channelSwitchPresent = 1;
3049 qdf_mem_copy(&pProbeResp->channelSwitchIE, &pr->ChanSwitchAnn,
3050 sizeof(pProbeResp->channelSwitchIE));
3051 }
3052
3053 if (pr->ext_chan_switch_ann.present) {
3054 pProbeResp->ext_chan_switch_present = 1;
3055 qdf_mem_copy(&pProbeResp->ext_chan_switch,
3056 &pr->ext_chan_switch_ann,
3057 sizeof(tDot11fIEext_chan_switch_ann));
3058 }
3059
3060 if (pr->SuppOperatingClasses.present) {
3061 pProbeResp->supp_operating_class_present = 1;
3062 qdf_mem_copy(&pProbeResp->supp_operating_classes,
3063 &pr->SuppOperatingClasses,
3064 sizeof(tDot11fIESuppOperatingClasses));
3065 }
3066
3067 if (pr->sec_chan_offset_ele.present) {
3068 pProbeResp->sec_chan_offset_present = 1;
3069 qdf_mem_copy(&pProbeResp->sec_chan_offset,
3070 &pr->sec_chan_offset_ele,
3071 sizeof(pProbeResp->sec_chan_offset));
3072 }
3073
3074 if (pr->TPCReport.present) {
3075 pProbeResp->tpcReportPresent = 1;
3076 qdf_mem_copy(&pProbeResp->tpcReport, &pr->TPCReport,
3077 sizeof(tDot11fIETPCReport));
3078 }
3079
3080 if (pr->PowerConstraints.present) {
3081 pProbeResp->powerConstraintPresent = 1;
3082 qdf_mem_copy(&pProbeResp->localPowerConstraint,
3083 &pr->PowerConstraints,
3084 sizeof(tDot11fIEPowerConstraints));
3085 }
3086
3087 if (pr->Quiet.present) {
3088 pProbeResp->quietIEPresent = 1;
3089 qdf_mem_copy(&pProbeResp->quietIE, &pr->Quiet,
3090 sizeof(tDot11fIEQuiet));
3091 }
3092
3093 if (pr->HTCaps.present) {
3094 qdf_mem_copy(&pProbeResp->HTCaps, &pr->HTCaps,
3095 sizeof(tDot11fIEHTCaps));
3096 }
3097
3098 if (pr->HTInfo.present) {
3099 qdf_mem_copy(&pProbeResp->HTInfo, &pr->HTInfo,
3100 sizeof(tDot11fIEHTInfo));
3101 }
3102
3103 if (pr->he_op.oper_info_6g_present) {
3104 pProbeResp->chan_freq = wlan_reg_chan_band_to_freq(mac->pdev,
3105 pr->he_op.oper_info_6g.info.primary_ch,
3106 BIT(REG_BAND_6G));
3107 } else if (pr->DSParams.present) {
3108 pProbeResp->dsParamsPresent = 1;
3109 pProbeResp->chan_freq =
3110 wlan_reg_legacy_chan_to_freq(mac->pdev, pr->DSParams.curr_channel);
3111 } else if (pr->HTInfo.present) {
3112 pProbeResp->chan_freq =
3113 wlan_reg_legacy_chan_to_freq(mac->pdev, pr->HTInfo.primaryChannel);
3114 }
3115
3116 if (pr->RSNOpaque.present) {
3117 pProbeResp->rsnPresent = 1;
3118 convert_rsn_opaque(mac, &pProbeResp->rsn, &pr->RSNOpaque);
3119 }
3120
3121 if (pr->WPA.present) {
3122 pProbeResp->wpaPresent = 1;
3123 convert_wpa(mac, &pProbeResp->wpa, &pr->WPA);
3124 }
3125
3126 if (pr->WMMParams.present) {
3127 pProbeResp->wmeEdcaPresent = 1;
3128 convert_wmm_params(mac, &pProbeResp->edcaParams, &pr->WMMParams);
3129 }
3130
3131 if (pr->WMMInfoAp.present) {
3132 pProbeResp->wmeInfoPresent = 1;
3133 pe_debug("WMM Information Element present in Probe Response Frame!");
3134 }
3135
3136 if (pr->WMMCaps.present) {
3137 pProbeResp->wsmCapablePresent = 1;
3138 }
3139
3140 if (pr->ERPInfo.present) {
3141 pProbeResp->erpPresent = 1;
3142 convert_erp_info(mac, &pProbeResp->erpIEInfo, &pr->ERPInfo);
3143 }
3144 if (pr->MobilityDomain.present) {
3145 /* MobilityDomain */
3146 pProbeResp->mdiePresent = 1;
3147 qdf_mem_copy((uint8_t *) &(pProbeResp->mdie[0]),
3148 (uint8_t *) &(pr->MobilityDomain.MDID),
3149 sizeof(uint16_t));
3150 pProbeResp->mdie[2] =
3151 ((pr->MobilityDomain.overDSCap << 0) | (pr->MobilityDomain.
3152 resourceReqCap <<
3153 1));
3154 pe_debug("mdie=%02x%02x%02x",
3155 (unsigned int)pProbeResp->mdie[0],
3156 (unsigned int)pProbeResp->mdie[1],
3157 (unsigned int)pProbeResp->mdie[2]);
3158 }
3159
3160 #if defined FEATURE_WLAN_ESE
3161 if (pr->ESEVersion.present)
3162 pProbeResp->is_ese_ver_ie_present = 1;
3163 if (pr->QBSSLoad.present) {
3164 qdf_mem_copy(&pProbeResp->QBSSLoad, &pr->QBSSLoad,
3165 sizeof(tDot11fIEQBSSLoad));
3166 }
3167 #endif
3168 if (pr->P2PProbeRes.present) {
3169 qdf_mem_copy(&pProbeResp->P2PProbeRes, &pr->P2PProbeRes,
3170 sizeof(tDot11fIEP2PProbeRes));
3171 }
3172 if (pr->VHTCaps.present) {
3173 qdf_mem_copy(&pProbeResp->VHTCaps, &pr->VHTCaps,
3174 sizeof(tDot11fIEVHTCaps));
3175 }
3176 if (pr->VHTOperation.present) {
3177 qdf_mem_copy(&pProbeResp->VHTOperation, &pr->VHTOperation,
3178 sizeof(tDot11fIEVHTOperation));
3179 }
3180 if (pr->VHTExtBssLoad.present) {
3181 qdf_mem_copy(&pProbeResp->VHTExtBssLoad, &pr->VHTExtBssLoad,
3182 sizeof(tDot11fIEVHTExtBssLoad));
3183 }
3184 pProbeResp->Vendor1IEPresent = pr->Vendor1IE.present;
3185 pProbeResp->Vendor3IEPresent = pr->Vendor3IE.present;
3186
3187 pProbeResp->vendor_vht_ie.present = pr->vendor_vht_ie.present;
3188 if (pr->vendor_vht_ie.present)
3189 pProbeResp->vendor_vht_ie.sub_type = pr->vendor_vht_ie.sub_type;
3190 if (pr->vendor_vht_ie.VHTCaps.present) {
3191 qdf_mem_copy(&pProbeResp->vendor_vht_ie.VHTCaps,
3192 &pr->vendor_vht_ie.VHTCaps,
3193 sizeof(tDot11fIEVHTCaps));
3194 }
3195 if (pr->vendor_vht_ie.VHTOperation.present) {
3196 qdf_mem_copy(&pProbeResp->vendor_vht_ie.VHTOperation,
3197 &pr->vendor_vht_ie.VHTOperation,
3198 sizeof(tDot11fIEVHTOperation));
3199 }
3200 /* Update HS 2.0 Information Element */
3201 if (pr->hs20vendor_ie.present) {
3202 pe_debug("HS20 Indication Element Present, rel#:%u, id:%u",
3203 pr->hs20vendor_ie.release_num,
3204 pr->hs20vendor_ie.hs_id_present);
3205 qdf_mem_copy(&pProbeResp->hs20vendor_ie,
3206 &pr->hs20vendor_ie,
3207 sizeof(tDot11fIEhs20vendor_ie) -
3208 sizeof(pr->hs20vendor_ie.hs_id));
3209 if (pr->hs20vendor_ie.hs_id_present)
3210 qdf_mem_copy(&pProbeResp->hs20vendor_ie.hs_id,
3211 &pr->hs20vendor_ie.hs_id,
3212 sizeof(pr->hs20vendor_ie.hs_id));
3213 }
3214 if (pr->MBO_IE.present) {
3215 pProbeResp->MBO_IE_present = true;
3216 if (pr->MBO_IE.cellular_data_cap.present)
3217 pProbeResp->MBO_capability =
3218 pr->MBO_IE.cellular_data_cap.cellular_connectivity;
3219
3220 if (pr->MBO_IE.assoc_disallowed.present) {
3221 pProbeResp->assoc_disallowed = true;
3222 pProbeResp->assoc_disallowed_reason =
3223 pr->MBO_IE.assoc_disallowed.reason_code;
3224 }
3225 }
3226
3227 if (pr->qcn_ie.present)
3228 qdf_mem_copy(&pProbeResp->qcn_ie, &pr->qcn_ie,
3229 sizeof(tDot11fIEqcn_ie));
3230
3231 if (pr->he_cap.present) {
3232 qdf_mem_copy(&pProbeResp->he_cap, &pr->he_cap,
3233 sizeof(tDot11fIEhe_cap));
3234 }
3235 if (pr->he_op.present) {
3236 qdf_mem_copy(&pProbeResp->he_op, &pr->he_op,
3237 sizeof(tDot11fIEhe_op));
3238 }
3239
3240 sir_convert_probe_frame2_eht_struct(pr, pProbeResp);
3241 update_bss_color_change_ie_from_probe_rsp(pr, pProbeResp);
3242 sir_convert_probe_frame2_mlo_struct(pFrame, nFrame, pr, pProbeResp);
3243 sir_convert_probe_frame2_t2lm_struct(pr, pProbeResp);
3244
3245 qdf_mem_free(pr);
3246 return QDF_STATUS_SUCCESS;
3247
3248 } /* End sir_convert_probe_frame2_struct. */
3249
3250 #ifdef WLAN_FEATURE_11BE
3251 static void
3252 sir_convert_assoc_req_frame2_eht_struct(tDot11fAssocRequest *ar,
3253 tpSirAssocReq p_assoc_req)
3254 {
3255 if (ar->eht_cap.present)
3256 qdf_mem_copy(&p_assoc_req->eht_cap, &ar->eht_cap,
3257 sizeof(tDot11fIEeht_cap));
3258 }
3259 #else
3260 static inline void
3261 sir_convert_assoc_req_frame2_eht_struct(tDot11fAssocRequest *ar,
3262 tpSirAssocReq p_assoc_req)
3263 {
3264 }
3265 #endif
3266
3267 #ifdef WLAN_FEATURE_11BE_MLO
3268 static QDF_STATUS
3269 sir_convert_assoc_req_frame2_mlo_struct(uint8_t *pframe,
3270 uint32_t nframe,
3271 tDot11fAssocRequest *ar,
3272 tpSirAssocReq p_assoc_req)
3273 {
3274 uint8_t *ml_ie;
3275 qdf_size_t ml_ie_total_len;
3276 struct qdf_mac_addr mld_mac_addr;
3277 uint32_t status;
3278
3279 if (ar->mlo_ie.present) {
3280 status = util_find_mlie(pframe + WLAN_ASSOC_REQ_IES_OFFSET,
3281 nframe - WLAN_ASSOC_REQ_IES_OFFSET,
3282 &ml_ie, &ml_ie_total_len);
3283
3284 if (QDF_IS_STATUS_SUCCESS(status)) {
3285 util_get_bvmlie_persta_partner_info(ml_ie,
3286 ml_ie_total_len,
3287 &p_assoc_req->mlo_info);
3288 util_get_bvmlie_mldmacaddr(ml_ie, ml_ie_total_len,
3289 &mld_mac_addr);
3290 qdf_mem_copy(p_assoc_req->mld_mac, mld_mac_addr.bytes,
3291 QDF_MAC_ADDR_SIZE);
3292 pe_debug("Partner link count: %d, MLD mac addr: " QDF_MAC_ADDR_FMT,
3293 p_assoc_req->mlo_info.num_partner_links,
3294 QDF_MAC_ADDR_REF(p_assoc_req->mld_mac));
3295 } else {
3296 pe_debug("Do not find mlie");
3297 }
3298 }
3299
3300 return QDF_STATUS_SUCCESS;
3301 }
3302 #else
3303 static inline QDF_STATUS
3304 sir_convert_assoc_req_frame2_mlo_struct(uint8_t *pFrame,
3305 uint32_t nFrame,
3306 tDot11fAssocRequest *ar,
3307 tpSirAssocReq p_assoc_req)
3308 {
3309 return QDF_STATUS_SUCCESS;
3310 }
3311 #endif
3312
3313 enum wlan_status_code
3314 sir_convert_assoc_req_frame2_struct(struct mac_context *mac,
3315 uint8_t *pFrame,
3316 uint32_t nFrame, tpSirAssocReq pAssocReq)
3317 {
3318 tDot11fAssocRequest *ar;
3319 uint32_t status;
3320
3321 ar = qdf_mem_malloc(sizeof(tDot11fAssocRequest));
3322 if (!ar)
3323 return STATUS_UNSPECIFIED_FAILURE;
3324
3325 /* delegate to the framesc-generated code, */
3326 status = dot11f_unpack_assoc_request(mac, pFrame, nFrame, ar, false);
3327 if (DOT11F_FAILED(status)) {
3328 pe_err("Failed to parse an Association Request (0x%08x, %d bytes):",
3329 status, nFrame);
3330 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_ERROR,
3331 pFrame, nFrame);
3332 qdf_mem_free(ar);
3333 return STATUS_UNSPECIFIED_FAILURE;
3334 } else if (DOT11F_WARNED(status)) {
3335 pe_debug("There were warnings while unpacking an Association Request (0x%08x, %d bytes):",
3336 status, nFrame);
3337 }
3338 /* & "transliterate" from a 'tDot11fAssocRequest' to a 'tSirAssocReq'... */
3339
3340 /* make sure this is seen as an assoc request */
3341 pAssocReq->reassocRequest = 0;
3342
3343 /* Capabilities */
3344 pAssocReq->capabilityInfo.ess = ar->Capabilities.ess;
3345 pAssocReq->capabilityInfo.ibss = ar->Capabilities.ibss;
3346 pAssocReq->capabilityInfo.cfPollable = ar->Capabilities.cfPollable;
3347 pAssocReq->capabilityInfo.cfPollReq = ar->Capabilities.cfPollReq;
3348 pAssocReq->capabilityInfo.privacy = ar->Capabilities.privacy;
3349 pAssocReq->capabilityInfo.shortPreamble =
3350 ar->Capabilities.shortPreamble;
3351 pAssocReq->capabilityInfo.criticalUpdateFlag =
3352 ar->Capabilities.criticalUpdateFlag;
3353 pAssocReq->capabilityInfo.channelAgility =
3354 ar->Capabilities.channelAgility;
3355 pAssocReq->capabilityInfo.spectrumMgt = ar->Capabilities.spectrumMgt;
3356 pAssocReq->capabilityInfo.qos = ar->Capabilities.qos;
3357 pAssocReq->capabilityInfo.shortSlotTime =
3358 ar->Capabilities.shortSlotTime;
3359 pAssocReq->capabilityInfo.apsd = ar->Capabilities.apsd;
3360 pAssocReq->capabilityInfo.rrm = ar->Capabilities.rrm;
3361 pAssocReq->capabilityInfo.dsssOfdm = ar->Capabilities.dsssOfdm;
3362 pAssocReq->capabilityInfo.delayedBA = ar->Capabilities.delayedBA;
3363 pAssocReq->capabilityInfo.immediateBA = ar->Capabilities.immediateBA;
3364
3365 /* Listen Interval */
3366 pAssocReq->listenInterval = ar->ListenInterval.interval;
3367
3368 /* SSID */
3369 if (ar->SSID.present) {
3370 pAssocReq->ssidPresent = 1;
3371 convert_ssid(mac, &pAssocReq->ssId, &ar->SSID);
3372 }
3373 /* Supported Rates */
3374 if (ar->SuppRates.present) {
3375 pAssocReq->suppRatesPresent = 1;
3376 convert_supp_rates(mac, &pAssocReq->supportedRates,
3377 &ar->SuppRates);
3378 }
3379 /* Extended Supported Rates */
3380 if (ar->ExtSuppRates.present) {
3381 pAssocReq->extendedRatesPresent = 1;
3382 convert_ext_supp_rates(mac, &pAssocReq->extendedRates,
3383 &ar->ExtSuppRates);
3384 }
3385 /* QOS Capabilities: */
3386 if (ar->QOSCapsStation.present) {
3387 pAssocReq->qosCapabilityPresent = 1;
3388 convert_qos_caps_station(mac, &pAssocReq->qosCapability,
3389 &ar->QOSCapsStation);
3390 }
3391 /* WPA */
3392 if (ar->WPAOpaque.present) {
3393 pAssocReq->wpaPresent = 1;
3394 convert_wpa_opaque(mac, &pAssocReq->wpa, &ar->WPAOpaque);
3395 }
3396 #ifdef FEATURE_WLAN_WAPI
3397 if (ar->WAPIOpaque.present) {
3398 pAssocReq->wapiPresent = 1;
3399 convert_wapi_opaque(mac, &pAssocReq->wapi, &ar->WAPIOpaque);
3400 }
3401 #endif
3402 /* RSN */
3403 if (ar->RSNOpaque.present) {
3404 pAssocReq->rsnPresent = 1;
3405 convert_rsn_opaque(mac, &pAssocReq->rsn, &ar->RSNOpaque);
3406 }
3407 /* WSC IE */
3408 if (ar->WscIEOpaque.present) {
3409 pAssocReq->addIEPresent = 1;
3410 convert_wsc_opaque(mac, &pAssocReq->addIE, &ar->WscIEOpaque);
3411 }
3412
3413 if (ar->P2PIEOpaque.present) {
3414 pAssocReq->addIEPresent = 1;
3415 convert_p2p_opaque(mac, &pAssocReq->addIE, &ar->P2PIEOpaque);
3416 }
3417 #ifdef WLAN_FEATURE_WFD
3418 if (ar->WFDIEOpaque.present) {
3419 pAssocReq->addIEPresent = 1;
3420 convert_wfd_opaque(mac, &pAssocReq->addIE, &ar->WFDIEOpaque);
3421 }
3422 #endif
3423
3424 /* Power Capabilities */
3425 if (ar->PowerCaps.present) {
3426 pAssocReq->powerCapabilityPresent = 1;
3427 convert_power_caps(mac, &pAssocReq->powerCapability,
3428 &ar->PowerCaps);
3429 }
3430 /* Supported Channels */
3431 if (ar->SuppChannels.present) {
3432 pAssocReq->supportedChannelsPresent = 1;
3433 convert_supp_channels(mac, &pAssocReq->supportedChannels,
3434 &ar->SuppChannels);
3435 }
3436
3437 if (ar->HTCaps.present) {
3438 qdf_mem_copy(&pAssocReq->HTCaps, &ar->HTCaps,
3439 sizeof(tDot11fIEHTCaps));
3440 }
3441
3442 if (ar->WMMInfoStation.present) {
3443 pAssocReq->wmeInfoPresent = 1;
3444 qdf_mem_copy(&pAssocReq->WMMInfoStation, &ar->WMMInfoStation,
3445 sizeof(tDot11fIEWMMInfoStation));
3446
3447 }
3448
3449 if (ar->WMMCaps.present)
3450 pAssocReq->wsmCapablePresent = 1;
3451
3452 if (!pAssocReq->ssidPresent) {
3453 pe_debug("Received Assoc without SSID IE");
3454 qdf_mem_free(ar);
3455 return STATUS_UNSPECIFIED_FAILURE;
3456 }
3457
3458 if (!pAssocReq->suppRatesPresent && !pAssocReq->extendedRatesPresent) {
3459 pe_debug("Received Assoc without supp rate IE");
3460 qdf_mem_free(ar);
3461 return STATUS_ASSOC_DENIED_RATES;
3462 }
3463 if (ar->VHTCaps.present) {
3464 qdf_mem_copy(&pAssocReq->VHTCaps, &ar->VHTCaps,
3465 sizeof(tDot11fIEVHTCaps));
3466 lim_log_vht_cap(mac, &pAssocReq->VHTCaps);
3467 }
3468 if (ar->OperatingMode.present) {
3469 qdf_mem_copy(&pAssocReq->operMode, &ar->OperatingMode,
3470 sizeof(tDot11fIEOperatingMode));
3471 lim_log_operating_mode(mac, &pAssocReq->operMode);
3472 }
3473 if (ar->ExtCap.present) {
3474 struct s_ext_cap *ext_cap;
3475
3476 qdf_mem_copy(&pAssocReq->ExtCap, &ar->ExtCap,
3477 sizeof(tDot11fIEExtCap));
3478 ext_cap = (struct s_ext_cap *)&pAssocReq->ExtCap.bytes;
3479 pe_debug("timingMeas: %d, finetimingMeas Init: %d, Resp: %d",
3480 ext_cap->timing_meas, ext_cap->fine_time_meas_initiator,
3481 ext_cap->fine_time_meas_responder);
3482 }
3483 if (ar->SuppOperatingClasses.present) {
3484 uint8_t num_classes = ar->SuppOperatingClasses.num_classes;
3485
3486 if (num_classes > sizeof(ar->SuppOperatingClasses.classes))
3487 num_classes =
3488 sizeof(ar->SuppOperatingClasses.classes);
3489 qdf_mem_copy(&pAssocReq->supp_operating_classes,
3490 &ar->SuppOperatingClasses,
3491 sizeof(tDot11fIESuppOperatingClasses));
3492 }
3493
3494 pAssocReq->vendor_vht_ie.present = ar->vendor_vht_ie.present;
3495 if (ar->vendor_vht_ie.present) {
3496 pAssocReq->vendor_vht_ie.sub_type = ar->vendor_vht_ie.sub_type;
3497 if (ar->vendor_vht_ie.VHTCaps.present) {
3498 qdf_mem_copy(&pAssocReq->vendor_vht_ie.VHTCaps,
3499 &ar->vendor_vht_ie.VHTCaps,
3500 sizeof(tDot11fIEVHTCaps));
3501 lim_log_vht_cap(mac, &pAssocReq->VHTCaps);
3502 }
3503 }
3504 if (ar->qcn_ie.present)
3505 qdf_mem_copy(&pAssocReq->qcn_ie, &ar->qcn_ie,
3506 sizeof(tDot11fIEqcn_ie));
3507 if (ar->bss_max_idle_period.present) {
3508 qdf_mem_copy(&pAssocReq->bss_max_idle_period,
3509 &ar->bss_max_idle_period,
3510 sizeof(tDot11fIEbss_max_idle_period));
3511 }
3512 if (ar->he_cap.present)
3513 qdf_mem_copy(&pAssocReq->he_cap, &ar->he_cap,
3514 sizeof(tDot11fIEhe_cap));
3515
3516 if (ar->he_6ghz_band_cap.present)
3517 qdf_mem_copy(&pAssocReq->he_6ghz_band_cap,
3518 &ar->he_6ghz_band_cap,
3519 sizeof(tDot11fIEhe_6ghz_band_cap));
3520
3521 sir_convert_assoc_req_frame2_eht_struct(ar, pAssocReq);
3522 sir_convert_assoc_req_frame2_mlo_struct(pFrame, nFrame, ar, pAssocReq);
3523
3524 pe_debug("ht %d vht %d opmode %d vendor vht %d he %d he 6ghband %d eht %d",
3525 ar->HTCaps.present, ar->VHTCaps.present,
3526 ar->OperatingMode.present, ar->vendor_vht_ie.VHTCaps.present,
3527 ar->he_cap.present, ar->he_6ghz_band_cap.present,
3528 ar->eht_cap.present);
3529
3530 qdf_mem_free(ar);
3531 return STATUS_SUCCESS;
3532
3533 } /* End sir_convert_assoc_req_frame2_struct. */
3534
3535 QDF_STATUS dot11f_parse_assoc_response(struct mac_context *mac_ctx,
3536 uint8_t *p_buf, uint32_t n_buf,
3537 tDot11fAssocResponse *p_frm,
3538 bool append_ie)
3539 {
3540 uint32_t status;
3541
3542 status = dot11f_unpack_assoc_response(mac_ctx, p_buf,
3543 n_buf, p_frm, append_ie);
3544 if (DOT11F_FAILED(status)) {
3545 pe_err("Failed to parse an Association Response (0x%08x, %d bytes):",
3546 status, n_buf);
3547 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_ERROR,
3548 p_buf, n_buf);
3549 return QDF_STATUS_E_FAILURE;
3550 }
3551 return QDF_STATUS_SUCCESS;
3552 }
3553
3554 #ifdef WLAN_FEATURE_FILS_SK
3555 /**
3556 * fils_convert_assoc_rsp_frame2_struct() - Copy FILS IE's to Assoc rsp struct
3557 * @ar: frame parser Assoc response struct
3558 * @pAssocRsp: LIM Assoc response
3559 *
3560 * Return: None
3561 */
3562 static void fils_convert_assoc_rsp_frame2_struct(tDot11fAssocResponse *ar,
3563 tpSirAssocRsp pAssocRsp)
3564 {
3565 if (ar->fils_session.present) {
3566 pe_debug("fils session IE present");
3567 pAssocRsp->fils_session.present = true;
3568 qdf_mem_copy(pAssocRsp->fils_session.session,
3569 ar->fils_session.session,
3570 DOT11F_IE_FILS_SESSION_MAX_LEN);
3571 }
3572
3573 if (ar->fils_key_confirmation.present) {
3574 pe_debug("fils key conf IE present");
3575 pAssocRsp->fils_key_auth.num_key_auth =
3576 ar->fils_key_confirmation.num_key_auth;
3577 qdf_mem_copy(pAssocRsp->fils_key_auth.key_auth,
3578 ar->fils_key_confirmation.key_auth,
3579 pAssocRsp->fils_key_auth.num_key_auth);
3580 }
3581
3582 if (ar->fils_kde.present) {
3583 pe_debug("fils kde IE present %d",
3584 ar->fils_kde.num_kde_list);
3585 pAssocRsp->fils_kde.num_kde_list =
3586 ar->fils_kde.num_kde_list;
3587 qdf_mem_copy(pAssocRsp->fils_kde.key_rsc,
3588 ar->fils_kde.key_rsc, KEY_RSC_LEN);
3589 qdf_mem_copy(&pAssocRsp->fils_kde.kde_list,
3590 &ar->fils_kde.kde_list,
3591 pAssocRsp->fils_kde.num_kde_list);
3592 }
3593
3594 if (ar->fils_hlp_container.present) {
3595 pe_debug("FILS HLP container IE present");
3596 sir_copy_mac_addr(pAssocRsp->dst_mac.bytes,
3597 ar->fils_hlp_container.dest_mac);
3598 sir_copy_mac_addr(pAssocRsp->src_mac.bytes,
3599 ar->fils_hlp_container.src_mac);
3600 pAssocRsp->hlp_data_len = ar->fils_hlp_container.num_hlp_packet;
3601 qdf_mem_copy(pAssocRsp->hlp_data,
3602 ar->fils_hlp_container.hlp_packet,
3603 pAssocRsp->hlp_data_len);
3604
3605 if (ar->fragment_ie.present) {
3606 pe_debug("FILS fragment ie present");
3607 qdf_mem_copy(pAssocRsp->hlp_data +
3608 pAssocRsp->hlp_data_len,
3609 ar->fragment_ie.data,
3610 ar->fragment_ie.num_data);
3611 pAssocRsp->hlp_data_len += ar->fragment_ie.num_data;
3612 }
3613 }
3614 }
3615 #else
3616 static inline void fils_convert_assoc_rsp_frame2_struct(tDot11fAssocResponse
3617 *ar, tpSirAssocRsp
3618 pAssocRsp)
3619 { }
3620 #endif
3621
3622 QDF_STATUS wlan_parse_ftie_sha384(uint8_t *frame, uint32_t frame_len,
3623 struct sSirAssocRsp *assoc_rsp)
3624 {
3625 const uint8_t *ie, *ie_end, *pos;
3626 uint8_t ie_len, remaining_ie_len;
3627 struct wlan_sha384_ftinfo_subelem *ft_subelem;
3628
3629 ie = wlan_get_ie_ptr_from_eid(DOT11F_EID_FTINFO, frame, frame_len);
3630 if (!ie) {
3631 pe_err("FT IE not present");
3632 return QDF_STATUS_E_FAILURE;
3633 }
3634
3635 if (!ie[1]) {
3636 pe_err("FT IE length is zero");
3637 return QDF_STATUS_E_FAILURE;
3638 }
3639
3640 ie_len = ie[1];
3641 if (ie_len < sizeof(struct wlan_sha384_ftinfo)) {
3642 pe_err("Invalid FTIE len:%d", ie_len);
3643 return QDF_STATUS_E_FAILURE;
3644 }
3645 remaining_ie_len = ie_len;
3646 pos = ie + 2;
3647 qdf_mem_copy(&assoc_rsp->sha384_ft_info, pos,
3648 sizeof(struct wlan_sha384_ftinfo));
3649 ie_end = ie + ie_len;
3650 pos += sizeof(struct wlan_sha384_ftinfo);
3651 remaining_ie_len -= sizeof(struct wlan_sha384_ftinfo);
3652 ft_subelem = &assoc_rsp->sha384_ft_subelem;
3653 qdf_mem_zero(ft_subelem, sizeof(*ft_subelem));
3654 while (ie_end - pos >= 2) {
3655 uint8_t id, len;
3656
3657 id = *pos++;
3658 len = *pos++;
3659 /* Subtract data length(len) + 1 bytes for
3660 * Subelement ID + 1 bytes for length from
3661 * remaining FTIE buffer len (ie_len).
3662 * Subelement Parameter(s) field :
3663 * Subelement ID Length Data
3664 * Octets: 1 1 variable
3665 */
3666 if (len < 1 || remaining_ie_len < (len + 2)) {
3667 pe_err("Invalid FT subelem length");
3668 return QDF_STATUS_E_FAILURE;
3669 }
3670
3671 remaining_ie_len -= (len + 2);
3672
3673 switch (id) {
3674 case FTIE_SUBELEM_R1KH_ID:
3675 if (len != FTIE_R1KH_LEN) {
3676 pe_err("Invalid R1KH-ID length: %d",
3677 len);
3678 return QDF_STATUS_E_FAILURE;
3679 }
3680 ft_subelem->r1kh_id.present = 1;
3681 qdf_mem_copy(ft_subelem->r1kh_id.PMK_R1_ID,
3682 pos, FTIE_R1KH_LEN);
3683 break;
3684 case FTIE_SUBELEM_GTK:
3685 if (ft_subelem->gtk) {
3686 qdf_mem_zero(ft_subelem->gtk,
3687 ft_subelem->gtk_len);
3688 ft_subelem->gtk_len = 0;
3689 qdf_mem_free(ft_subelem->gtk);
3690 }
3691 ft_subelem->gtk = qdf_mem_malloc(len);
3692 if (!ft_subelem->gtk)
3693 return QDF_STATUS_E_NOMEM;
3694
3695 qdf_mem_copy(ft_subelem->gtk, pos, len);
3696 ft_subelem->gtk_len = len;
3697 break;
3698 case FTIE_SUBELEM_R0KH_ID:
3699 if (len < 1 || len > FTIE_R0KH_MAX_LEN) {
3700 pe_err("Invalid R0KH-ID length: %d",
3701 len);
3702 return QDF_STATUS_E_FAILURE;
3703 }
3704 ft_subelem->r0kh_id.present = 1;
3705 ft_subelem->r0kh_id.num_PMK_R0_ID = len;
3706 qdf_mem_copy(ft_subelem->r0kh_id.PMK_R0_ID,
3707 pos, len);
3708 break;
3709 case FTIE_SUBELEM_IGTK:
3710 if (ft_subelem->igtk) {
3711 qdf_mem_zero(ft_subelem->igtk,
3712 ft_subelem->igtk_len);
3713 ft_subelem->igtk_len = 0;
3714 qdf_mem_free(ft_subelem->igtk);
3715 }
3716 ft_subelem->igtk = qdf_mem_malloc(len);
3717 if (!ft_subelem->igtk)
3718 return QDF_STATUS_E_NOMEM;
3719
3720 qdf_mem_copy(ft_subelem->igtk, pos, len);
3721 ft_subelem->igtk_len = len;
3722
3723 break;
3724 default:
3725 pe_debug("Unknown subelem id %d len:%d",
3726 id, len);
3727 break;
3728 }
3729 pos += len;
3730 }
3731 return QDF_STATUS_SUCCESS;
3732 }
3733
3734 #ifdef WLAN_FEATURE_11BE
3735 static void
3736 sir_convert_assoc_resp_frame2_eht_struct(tDot11fAssocResponse *ar,
3737 tpSirAssocRsp p_assoc_rsp)
3738 {
3739 if (ar->eht_cap.present)
3740 qdf_mem_copy(&p_assoc_rsp->eht_cap, &ar->eht_cap,
3741 sizeof(tDot11fIEeht_cap));
3742
3743 if (ar->eht_op.present)
3744 qdf_mem_copy(&p_assoc_rsp->eht_op, &ar->eht_op,
3745 sizeof(tDot11fIEeht_op));
3746 }
3747 #else
3748 static inline void
3749 sir_convert_assoc_resp_frame2_eht_struct(tDot11fAssocResponse *ar,
3750 tpSirAssocRsp p_assoc_rsp)
3751 {
3752 }
3753 #endif
3754
3755 #ifdef WLAN_FEATURE_11BE_MLO
3756 static QDF_STATUS
3757 sir_copy_assoc_rsp_partner_info_to_session(struct pe_session *session_entry,
3758 struct mlo_partner_info *partner_info)
3759 {
3760 uint16_t i, partner_idx = 0, j, link_id;
3761 struct mlo_link_info *link_info;
3762 struct mlo_partner_info *ml_partner_info =
3763 &session_entry->ml_partner_info;
3764
3765 link_info = mlo_mgr_get_ap_link(session_entry->vdev);
3766 if (!link_info)
3767 return QDF_STATUS_E_FAILURE;
3768
3769 /* Clear the Partner info already filled from the join request */
3770 qdf_mem_zero(ml_partner_info, sizeof(*ml_partner_info));
3771 for (i = 1; i < WLAN_MAX_ML_BSS_LINKS; i++) {
3772 link_id = link_info[i].link_id;
3773 for (j = 0; j < partner_info->num_partner_links; j++) {
3774 if (partner_info->partner_link_info[j].link_id !=
3775 link_id)
3776 continue;
3777
3778 ml_partner_info->partner_link_info[partner_idx++] =
3779 partner_info->partner_link_info[j];
3780 break;
3781 }
3782 }
3783 ml_partner_info->num_partner_links = partner_idx;
3784
3785 return QDF_STATUS_SUCCESS;
3786 }
3787
3788 static QDF_STATUS
3789 sir_convert_assoc_resp_frame2_mlo_struct(struct mac_context *mac,
3790 uint8_t *frame,
3791 uint32_t frame_len,
3792 struct pe_session *session_entry,
3793 tDot11fAssocResponse *ar,
3794 tpSirAssocRsp p_assoc_rsp)
3795 {
3796 uint8_t *ml_ie;
3797 qdf_size_t ml_ie_total_len;
3798 struct wlan_mlo_ie *ml_ie_info;
3799 bool link_id_found;
3800 uint8_t link_id;
3801 bool eml_cap_found, msd_cap_found;
3802 uint16_t eml_cap;
3803 uint16_t msd_cap;
3804 struct qdf_mac_addr mld_mac_addr;
3805 QDF_STATUS status = QDF_STATUS_SUCCESS;
3806 struct mlo_partner_info partner_info;
3807
3808 if (!ar->mlo_ie.present)
3809 return status;
3810
3811 status = util_find_mlie(frame + WLAN_ASSOC_RSP_IES_OFFSET,
3812 frame_len - WLAN_ASSOC_RSP_IES_OFFSET,
3813 &ml_ie, &ml_ie_total_len);
3814 if (QDF_IS_STATUS_ERROR(status))
3815 return status;
3816
3817 ml_ie_info = &p_assoc_rsp->mlo_ie.mlo_ie;
3818 util_get_bvmlie_persta_partner_info(ml_ie, ml_ie_total_len,
3819 &partner_info);
3820
3821 sir_copy_assoc_rsp_partner_info_to_session(session_entry,
3822 &partner_info);
3823
3824 if (!wlan_cm_is_roam_sync_in_progress(mac->psoc,
3825 session_entry->vdev_id)) {
3826 session_entry->ml_partner_info.num_partner_links =
3827 QDF_MIN(
3828 session_entry->ml_partner_info.num_partner_links,
3829 session_entry->lim_join_req->partner_info.num_partner_links);
3830 }
3831 util_get_bvmlie_mldmacaddr(ml_ie, ml_ie_total_len,
3832 &mld_mac_addr);
3833 qdf_mem_copy(ml_ie_info->mld_mac_addr,
3834 mld_mac_addr.bytes, QDF_MAC_ADDR_SIZE);
3835
3836 util_get_mlie_common_info_len(ml_ie, ml_ie_total_len,
3837 &ml_ie_info->common_info_length);
3838
3839 util_get_bvmlie_primary_linkid(ml_ie, ml_ie_total_len,
3840 &link_id_found, &link_id);
3841 util_get_bvmlie_msd_cap(ml_ie, ml_ie_total_len,
3842 &msd_cap_found, &msd_cap);
3843 if (msd_cap_found) {
3844 ml_ie_info->medium_sync_delay_info_present =
3845 msd_cap_found;
3846 ml_ie_info->medium_sync_delay_info.medium_sync_duration =
3847 QDF_GET_BITS(
3848 msd_cap,
3849 WLAN_ML_BV_CINFO_MEDMSYNCDELAYINFO_DURATION_IDX,
3850 WLAN_ML_BV_CINFO_MEDMSYNCDELAYINFO_DURATION_BITS);
3851 ml_ie_info->medium_sync_delay_info.medium_sync_ofdm_ed_thresh =
3852 QDF_GET_BITS(
3853 msd_cap,
3854 WLAN_ML_BV_CINFO_MEDMSYNCDELAYINFO_OFDMEDTHRESH_IDX,
3855 WLAN_ML_BV_CINFO_MEDMSYNCDELAYINFO_OFDMEDTHRESH_BITS);
3856 ml_ie_info->medium_sync_delay_info.medium_sync_max_txop_num =
3857 QDF_GET_BITS(
3858 msd_cap,
3859 WLAN_ML_BV_CINFO_MEDMSYNCDELAYINFO_MAXTXOPS_IDX,
3860 WLAN_ML_BV_CINFO_MEDMSYNCDELAYINFO_MAXTXOPS_BITS);
3861 }
3862 util_get_bvmlie_eml_cap(ml_ie, ml_ie_total_len,
3863 &eml_cap_found, &eml_cap);
3864 if (eml_cap_found) {
3865 ml_ie_info->eml_capab_present = eml_cap_found;
3866 ml_ie_info->eml_capabilities_info.emlsr_support =
3867 QDF_GET_BITS(eml_cap,
3868 WLAN_ML_BV_CINFO_EMLCAP_EMLSRSUPPORT_IDX,
3869 WLAN_ML_BV_CINFO_EMLCAP_EMLSRSUPPORT_BITS);
3870
3871 ml_ie_info->eml_capabilities_info.transition_timeout =
3872 QDF_GET_BITS(eml_cap,
3873 WLAN_ML_BV_CINFO_EMLCAP_TRANSTIMEOUT_IDX,
3874 WLAN_ML_BV_CINFO_EMLCAP_TRANSTIMEOUT_BITS);
3875 }
3876
3877 ml_ie_info->num_sta_profile =
3878 session_entry->ml_partner_info.num_partner_links;
3879 ml_ie_info->link_id_info_present = link_id_found;
3880 ml_ie_info->link_id = link_id;
3881
3882 pe_debug("vdev:%d Partner link count: %d, Link id: %d, MLD mac addr: " QDF_MAC_ADDR_FMT,
3883 session_entry->vdev_id,
3884 ml_ie_info->num_sta_profile, ml_ie_info->link_id,
3885 QDF_MAC_ADDR_REF(ml_ie_info->mld_mac_addr));
3886
3887 return status;
3888 }
3889
3890 static QDF_STATUS
3891 sir_convert_assoc_resp_frame2_t2lm_struct(struct mac_context *mac,
3892 uint8_t *frame,
3893 uint32_t frame_len,
3894 struct pe_session *session_entry,
3895 tDot11fAssocResponse *ar,
3896 tpSirAssocRsp p_assoc_rsp)
3897 {
3898 QDF_STATUS status = QDF_STATUS_SUCCESS;
3899 struct wlan_t2lm_context *t2lm_ctx;
3900 /* add 3 bytes for extn_ie_header */
3901 uint8_t ie[DOT11F_IE_T2LM_IE_MAX_LEN + 3];
3902 struct wlan_t2lm_info t2lm;
3903 uint8_t i;
3904
3905 t2lm_ctx = &p_assoc_rsp->t2lm_ctx;
3906 qdf_mem_zero(&t2lm_ctx->established_t2lm.t2lm,
3907 sizeof(struct wlan_t2lm_info));
3908 t2lm_ctx->established_t2lm.t2lm.direction = WLAN_T2LM_INVALID_DIRECTION;
3909
3910 qdf_mem_zero(&t2lm_ctx->upcoming_t2lm.t2lm,
3911 sizeof(struct wlan_t2lm_info));
3912 t2lm_ctx->upcoming_t2lm.t2lm.direction = WLAN_T2LM_INVALID_DIRECTION;
3913
3914 if (!ar->num_t2lm_ie) {
3915 pe_debug("T2LM IEs not present");
3916 return status;
3917 }
3918
3919 pe_debug("Number of T2LM IEs in assoc resp %d", ar->num_t2lm_ie);
3920 for (i = 0; i < ar->num_t2lm_ie; i++) {
3921 qdf_mem_zero(&ie[0], DOT11F_IE_T2LM_IE_MAX_LEN + 3);
3922 qdf_mem_zero(&t2lm, sizeof(struct wlan_t2lm_info));
3923 ie[ID_POS] = WLAN_ELEMID_EXTN_ELEM;
3924 ie[TAG_LEN_POS] = ar->t2lm_ie[i].num_data + 1;
3925 ie[IDEXT_POS] = WLAN_EXTN_ELEMID_T2LM;
3926 qdf_mem_copy(&ie[3], &ar->t2lm_ie[i].data[0],
3927 ar->t2lm_ie[i].num_data);
3928 qdf_trace_hex_dump(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_DEBUG,
3929 &ie[0], ar->t2lm_ie[i].num_data + 3);
3930
3931 if (ie[TAG_LEN_POS] + 2 > DOT11F_IE_T2LM_IE_MAX_LEN + 3) {
3932 pe_debug("Invalid T2LM IE length");
3933 return QDF_STATUS_E_PROTO;
3934 }
3935
3936 status = wlan_mlo_parse_t2lm_info(&ie[0], &t2lm);
3937 if (QDF_IS_STATUS_ERROR(status)) {
3938 pe_debug("Parse T2LM IE fail");
3939 return status;
3940 }
3941
3942 if (!t2lm.mapping_switch_time_present &&
3943 t2lm.expected_duration_present) {
3944 qdf_mem_copy(&t2lm_ctx->established_t2lm.t2lm, &t2lm,
3945 sizeof(struct wlan_t2lm_info));
3946 pe_debug("Parse established T2LM IE success");
3947 } else if (t2lm.mapping_switch_time_present) {
3948 qdf_mem_copy(&t2lm_ctx->upcoming_t2lm.t2lm, &t2lm,
3949 sizeof(struct wlan_t2lm_info));
3950 pe_debug("Parse upcoming T2LM IE success");
3951 }
3952 pe_debug("Parse T2LM IE success");
3953 }
3954 return status;
3955 }
3956
3957 #else
3958 static inline QDF_STATUS
3959 sir_convert_assoc_resp_frame2_mlo_struct(struct mac_context *mac,
3960 uint8_t *frame,
3961 uint32_t frame_len,
3962 struct pe_session *session_entry,
3963 tDot11fAssocResponse *ar,
3964 tpSirAssocRsp p_assoc_rsp)
3965 {
3966 return QDF_STATUS_SUCCESS;
3967 }
3968
3969 static inline QDF_STATUS
3970 sir_convert_assoc_resp_frame2_t2lm_struct(struct mac_context *mac,
3971 uint8_t *frame,
3972 uint32_t frame_len,
3973 struct pe_session *session_entry,
3974 tDot11fAssocResponse *ar,
3975 tpSirAssocRsp p_assoc_rsp)
3976 {
3977 return QDF_STATUS_SUCCESS;
3978 }
3979 #endif
3980 #ifdef WLAN_FEATURE_SR
3981 static void sir_convert_assoc_resp_frame2_sr(tpSirAssocRsp pAssocRsp,
3982 tDot11fAssocResponse *ar)
3983 {
3984 if (ar->spatial_reuse.present)
3985 qdf_mem_copy(&pAssocRsp->srp_ie, &ar->spatial_reuse,
3986 sizeof(tDot11fIEspatial_reuse));
3987 }
3988 #else
3989 static inline void sir_convert_assoc_resp_frame2_sr(tpSirAssocRsp pAssocRsp,
3990 tDot11fAssocResponse *ar)
3991 {
3992 }
3993 #endif
3994
3995 QDF_STATUS
3996 sir_convert_assoc_resp_frame2_struct(struct mac_context *mac,
3997 struct pe_session *session_entry,
3998 uint8_t *frame, uint32_t frame_len,
3999 tpSirAssocRsp pAssocRsp)
4000 {
4001 tDot11fAssocResponse *ar;
4002 enum ani_akm_type auth_type;
4003 uint32_t status, ie_len;
4004 QDF_STATUS qdf_status;
4005 uint8_t cnt = 0;
4006 bool sha384_akm;
4007 uint8_t *ie_ptr;
4008 uint16_t status_code;
4009
4010 ar = qdf_mem_malloc(sizeof(*ar));
4011 if (!ar)
4012 return QDF_STATUS_E_FAILURE;
4013
4014 status_code = sir_read_u16(frame +
4015 SIR_MAC_ASSOC_RSP_STATUS_CODE_OFFSET);
4016 if (lim_is_fils_connection(session_entry) && status_code)
4017 pe_debug("FILS: assoc reject Status code:%d", status_code);
4018
4019 /*
4020 * decrypt the cipher text using AEAD decryption, if association
4021 * response status code is successful, else the don't do AEAD decryption
4022 * since AP doesn't include FILS session IE when association reject is
4023 * sent
4024 */
4025 if (lim_is_fils_connection(session_entry) && !status_code) {
4026 status = aead_decrypt_assoc_rsp(mac, session_entry,
4027 ar, frame, &frame_len);
4028 if (!QDF_IS_STATUS_SUCCESS(status)) {
4029 pe_err("FILS assoc rsp AEAD decrypt fails");
4030 qdf_mem_free(ar);
4031 return QDF_STATUS_E_FAILURE;
4032 }
4033 }
4034
4035 status = dot11f_parse_assoc_response(mac, frame, frame_len, ar, false);
4036 if (QDF_STATUS_SUCCESS != status) {
4037 qdf_mem_free(ar);
4038 return status;
4039 }
4040
4041 /* Capabilities */
4042 pAssocRsp->capabilityInfo.ess = ar->Capabilities.ess;
4043 pAssocRsp->capabilityInfo.ibss = ar->Capabilities.ibss;
4044 pAssocRsp->capabilityInfo.cfPollable = ar->Capabilities.cfPollable;
4045 pAssocRsp->capabilityInfo.cfPollReq = ar->Capabilities.cfPollReq;
4046 pAssocRsp->capabilityInfo.privacy = ar->Capabilities.privacy;
4047 pAssocRsp->capabilityInfo.shortPreamble =
4048 ar->Capabilities.shortPreamble;
4049 pAssocRsp->capabilityInfo.criticalUpdateFlag =
4050 ar->Capabilities.criticalUpdateFlag;
4051 pAssocRsp->capabilityInfo.channelAgility =
4052 ar->Capabilities.channelAgility;
4053 pAssocRsp->capabilityInfo.spectrumMgt = ar->Capabilities.spectrumMgt;
4054 pAssocRsp->capabilityInfo.qos = ar->Capabilities.qos;
4055 pAssocRsp->capabilityInfo.shortSlotTime =
4056 ar->Capabilities.shortSlotTime;
4057 pAssocRsp->capabilityInfo.apsd = ar->Capabilities.apsd;
4058 pAssocRsp->capabilityInfo.rrm = ar->Capabilities.rrm;
4059 pAssocRsp->capabilityInfo.dsssOfdm = ar->Capabilities.dsssOfdm;
4060 pAssocRsp->capabilityInfo.delayedBA = ar->Capabilities.delayedBA;
4061 pAssocRsp->capabilityInfo.immediateBA = ar->Capabilities.immediateBA;
4062
4063 pAssocRsp->status_code = ar->Status.status;
4064 pAssocRsp->aid = ar->AID.associd;
4065
4066 if (ar->TimeoutInterval.present) {
4067 pAssocRsp->TimeoutInterval.present = 1;
4068 pAssocRsp->TimeoutInterval.timeoutType =
4069 ar->TimeoutInterval.timeoutType;
4070 pAssocRsp->TimeoutInterval.timeoutValue =
4071 ar->TimeoutInterval.timeoutValue;
4072 }
4073
4074 if (!ar->SuppRates.present) {
4075 pAssocRsp->suppRatesPresent = 0;
4076 pe_debug_rl("Mandatory IE Supported Rates not present!");
4077 } else {
4078 pAssocRsp->suppRatesPresent = 1;
4079 convert_supp_rates(mac, &pAssocRsp->supportedRates,
4080 &ar->SuppRates);
4081 }
4082
4083 if (ar->ExtSuppRates.present) {
4084 pAssocRsp->extendedRatesPresent = 1;
4085 convert_ext_supp_rates(mac, &pAssocRsp->extendedRates,
4086 &ar->ExtSuppRates);
4087 }
4088
4089 if (ar->EDCAParamSet.present) {
4090 pAssocRsp->edcaPresent = 1;
4091 convert_edca_param(mac, &pAssocRsp->edca, &ar->EDCAParamSet);
4092 }
4093 if (ar->WMMParams.present) {
4094 pAssocRsp->wmeEdcaPresent = 1;
4095 convert_wmm_params(mac, &pAssocRsp->edca, &ar->WMMParams);
4096 }
4097
4098 if (ar->HTCaps.present)
4099 qdf_mem_copy(&pAssocRsp->HTCaps, &ar->HTCaps,
4100 sizeof(tDot11fIEHTCaps));
4101
4102 if (ar->HTInfo.present)
4103 qdf_mem_copy(&pAssocRsp->HTInfo, &ar->HTInfo,
4104 sizeof(tDot11fIEHTInfo));
4105
4106 if (ar->RRMEnabledCap.present) {
4107 qdf_mem_copy(&pAssocRsp->rrm_caps, &ar->RRMEnabledCap,
4108 sizeof(tDot11fIERRMEnabledCap));
4109 }
4110 if (ar->MobilityDomain.present) {
4111 /* MobilityDomain */
4112 pAssocRsp->mdiePresent = 1;
4113 qdf_mem_copy((uint8_t *) &(pAssocRsp->mdie[0]),
4114 (uint8_t *) &(ar->MobilityDomain.MDID),
4115 sizeof(uint16_t));
4116 pAssocRsp->mdie[2] = ((ar->MobilityDomain.overDSCap << 0) |
4117 (ar->MobilityDomain.resourceReqCap << 1));
4118 pe_debug("new mdie=%02x%02x%02x",
4119 (unsigned int)pAssocRsp->mdie[0],
4120 (unsigned int)pAssocRsp->mdie[1],
4121 (unsigned int)pAssocRsp->mdie[2]);
4122 }
4123
4124 /*
4125 * If the connection is based on SHA384 AKM suite,
4126 * then the length of MIC is 24 bytes, but frame parser
4127 * has FTIE MIC of 16 bytes only. This results in parsing FTIE
4128 * failure and R0KH and R1KH are not sent to firmware over RSO
4129 * command. Frame parser doesn't have
4130 * info on the connected AKM. So parse the FTIE again if
4131 * AKM is sha384 based and extract the R0KH and R1KH using the new
4132 * parsing logic.
4133 */
4134 auth_type = session_entry->connected_akm;
4135 sha384_akm = lim_is_sha384_akm(auth_type);
4136 ie_ptr = frame + FIXED_PARAM_OFFSET_ASSOC_RSP;
4137 ie_len = frame_len - FIXED_PARAM_OFFSET_ASSOC_RSP;
4138 if (sha384_akm) {
4139 qdf_status = wlan_parse_ftie_sha384(ie_ptr, ie_len, pAssocRsp);
4140 if (QDF_IS_STATUS_ERROR(qdf_status)) {
4141 pe_err("FT IE parsing failed status:%d", status);
4142 } else {
4143 pe_debug("FT: R0KH present:%d len:%d R1KH present%d",
4144 pAssocRsp->sha384_ft_subelem.r0kh_id.present,
4145 pAssocRsp->sha384_ft_subelem.r0kh_id.num_PMK_R0_ID,
4146 pAssocRsp->sha384_ft_subelem.r1kh_id.present);
4147 ar->FTInfo.present = false;
4148 }
4149 } else if (ar->FTInfo.present) {
4150 pe_debug("FT: R0KH present:%d, len:%d R1KH present:%d",
4151 ar->FTInfo.R0KH_ID.present,
4152 ar->FTInfo.R0KH_ID.num_PMK_R0_ID,
4153 ar->FTInfo.R1KH_ID.present);
4154 pAssocRsp->ftinfoPresent = 1;
4155 qdf_mem_copy(&pAssocRsp->FTInfo, &ar->FTInfo,
4156 sizeof(tDot11fIEFTInfo));
4157 }
4158
4159 if (ar->num_RICDataDesc && ar->num_RICDataDesc <= 2) {
4160 for (cnt = 0; cnt < ar->num_RICDataDesc; cnt++) {
4161 if (ar->RICDataDesc[cnt].present) {
4162 qdf_mem_copy(&pAssocRsp->RICData[cnt],
4163 &ar->RICDataDesc[cnt],
4164 sizeof(tDot11fIERICDataDesc));
4165 }
4166 }
4167 pAssocRsp->num_RICData = ar->num_RICDataDesc;
4168 pAssocRsp->ricPresent = true;
4169 }
4170
4171 #ifdef FEATURE_WLAN_ESE
4172 if (ar->num_WMMTSPEC) {
4173 pAssocRsp->num_tspecs = ar->num_WMMTSPEC;
4174 for (cnt = 0; cnt < ar->num_WMMTSPEC; cnt++) {
4175 qdf_mem_copy(&pAssocRsp->TSPECInfo[cnt],
4176 &ar->WMMTSPEC[cnt],
4177 sizeof(tDot11fIEWMMTSPEC));
4178 }
4179 pAssocRsp->tspecPresent = true;
4180 }
4181
4182 if (ar->ESETrafStrmMet.present) {
4183 pAssocRsp->tsmPresent = 1;
4184 qdf_mem_copy(&pAssocRsp->tsmIE.tsid,
4185 &ar->ESETrafStrmMet.tsid,
4186 sizeof(struct ese_tsm_ie));
4187 }
4188 #endif
4189 if (ar->bss_max_idle_period.present)
4190 qdf_mem_copy(&pAssocRsp->bss_max_idle_period,
4191 &ar->bss_max_idle_period,
4192 sizeof(tDot11fIEbss_max_idle_period));
4193
4194 if (ar->VHTCaps.present) {
4195 qdf_mem_copy(&pAssocRsp->VHTCaps, &ar->VHTCaps,
4196 sizeof(tDot11fIEVHTCaps));
4197 lim_log_vht_cap(mac, &pAssocRsp->VHTCaps);
4198 }
4199 if (ar->VHTOperation.present) {
4200 qdf_mem_copy(&pAssocRsp->VHTOperation, &ar->VHTOperation,
4201 sizeof(tDot11fIEVHTOperation));
4202 lim_log_vht_operation(mac, &pAssocRsp->VHTOperation);
4203 }
4204
4205 if (ar->ExtCap.present) {
4206 struct s_ext_cap *ext_cap;
4207
4208 qdf_mem_copy(&pAssocRsp->ExtCap, &ar->ExtCap,
4209 sizeof(tDot11fIEExtCap));
4210 ext_cap = (struct s_ext_cap *)&pAssocRsp->ExtCap.bytes;
4211 pe_debug("timingMeas: %d, finetimingMeas Init: %d, Resp: %d",
4212 ext_cap->timing_meas, ext_cap->fine_time_meas_initiator,
4213 ext_cap->fine_time_meas_responder);
4214 }
4215
4216 if (ar->OperatingMode.present) {
4217 qdf_mem_copy(&pAssocRsp->oper_mode_ntf, &ar->OperatingMode,
4218 sizeof(tDot11fIEOperatingMode));
4219 }
4220
4221 if (ar->QosMapSet.present) {
4222 pAssocRsp->QosMapSet.present = 1;
4223 convert_qos_mapset_frame(mac, &pAssocRsp->QosMapSet,
4224 &ar->QosMapSet);
4225 lim_log_qos_map_set(mac, &pAssocRsp->QosMapSet);
4226 }
4227
4228 pAssocRsp->vendor_vht_ie.present = ar->vendor_vht_ie.present;
4229 if (ar->vendor_vht_ie.present)
4230 pAssocRsp->vendor_vht_ie.sub_type = ar->vendor_vht_ie.sub_type;
4231 if (ar->OBSSScanParameters.present) {
4232 qdf_mem_copy(&pAssocRsp->obss_scanparams,
4233 &ar->OBSSScanParameters,
4234 sizeof(struct sDot11fIEOBSSScanParameters));
4235 }
4236 if (ar->vendor_vht_ie.VHTCaps.present) {
4237 qdf_mem_copy(&pAssocRsp->vendor_vht_ie.VHTCaps,
4238 &ar->vendor_vht_ie.VHTCaps,
4239 sizeof(tDot11fIEVHTCaps));
4240 lim_log_vht_cap(mac, &pAssocRsp->VHTCaps);
4241 }
4242 if (ar->vendor_vht_ie.VHTOperation.present) {
4243 qdf_mem_copy(&pAssocRsp->vendor_vht_ie.VHTOperation,
4244 &ar->vendor_vht_ie.VHTOperation,
4245 sizeof(tDot11fIEVHTOperation));
4246 lim_log_vht_operation(mac, &pAssocRsp->VHTOperation);
4247 }
4248
4249 if (ar->qcn_ie.present)
4250 qdf_mem_copy(&pAssocRsp->qcn_ie, &ar->qcn_ie,
4251 sizeof(tDot11fIEqcn_ie));
4252 if (ar->he_cap.present) {
4253 qdf_mem_copy(&pAssocRsp->he_cap, &ar->he_cap,
4254 sizeof(tDot11fIEhe_cap));
4255 }
4256 if (ar->he_op.present)
4257 qdf_mem_copy(&pAssocRsp->he_op, &ar->he_op,
4258 sizeof(tDot11fIEhe_op));
4259
4260 sir_convert_assoc_resp_frame2_sr(pAssocRsp, ar);
4261
4262 if (ar->he_6ghz_band_cap.present)
4263 qdf_mem_copy(&pAssocRsp->he_6ghz_band_cap,
4264 &ar->he_6ghz_band_cap,
4265 sizeof(tDot11fIEhe_6ghz_band_cap));
4266
4267 if (ar->mu_edca_param_set.present) {
4268 pAssocRsp->mu_edca_present = true;
4269 convert_mu_edca_param(mac, &pAssocRsp->mu_edca,
4270 &ar->mu_edca_param_set);
4271 }
4272
4273 if (ar->MBO_IE.present && ar->MBO_IE.rssi_assoc_rej.present)
4274 qdf_mem_copy(&pAssocRsp->rssi_assoc_rej,
4275 &ar->MBO_IE.rssi_assoc_rej,
4276 sizeof(tDot11fTLVrssi_assoc_rej));
4277
4278 sir_convert_assoc_resp_frame2_eht_struct(ar, pAssocRsp);
4279 fils_convert_assoc_rsp_frame2_struct(ar, pAssocRsp);
4280 sir_convert_assoc_resp_frame2_mlo_struct(mac, frame, frame_len,
4281 session_entry, ar, pAssocRsp);
4282 sir_convert_assoc_resp_frame2_t2lm_struct(mac, frame, frame_len,
4283 session_entry, ar, pAssocRsp);
4284 pe_debug("ht %d vht %d vendor vht: cap %d op %d, he %d he 6ghband %d eht %d eht320 %d, max idle: present %d val %d, he mu edca %d wmm %d qos %d mlo %d",
4285 ar->HTCaps.present, ar->VHTCaps.present,
4286 ar->vendor_vht_ie.VHTCaps.present,
4287 ar->vendor_vht_ie.VHTOperation.present, ar->he_cap.present,
4288 ar->he_6ghz_band_cap.present, ar->eht_cap.present,
4289 pAssocRsp->eht_cap.support_320mhz_6ghz,
4290 ar->bss_max_idle_period.present,
4291 pAssocRsp->bss_max_idle_period.max_idle_period,
4292 ar->mu_edca_param_set.present, ar->WMMParams.present,
4293 ar->QosMapSet.present,
4294 ar->mlo_ie.present);
4295
4296 if (ar->WMMParams.present)
4297 __print_wmm_params(mac, &ar->WMMParams);
4298
4299 qdf_mem_free(ar);
4300 return QDF_STATUS_SUCCESS;
4301 } /* End sir_convert_assoc_resp_frame2_struct. */
4302
4303 #ifdef WLAN_FEATURE_11BE
4304 static void
4305 sir_convert_reassoc_req_frame2_eht_struct(tDot11fReAssocRequest *ar,
4306 tpSirAssocReq p_assoc_req)
4307 {
4308 if (ar->eht_cap.present) {
4309 qdf_mem_copy(&p_assoc_req->eht_cap, &ar->eht_cap,
4310 sizeof(tDot11fIEeht_cap));
4311 pe_debug("Received Assoc Req with EHT Capability IE");
4312 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_DEBUG,
4313 &p_assoc_req->eht_cap,
4314 sizeof(tDot11fIEeht_cap));
4315 }
4316 }
4317 #else
4318 static inline void
4319 sir_convert_reassoc_req_frame2_eht_struct(tDot11fReAssocRequest *ar,
4320 tpSirAssocReq p_assoc_req)
4321 {
4322 }
4323 #endif
4324
4325 #ifdef WLAN_FEATURE_11BE_MLO
4326 static QDF_STATUS
4327 sir_convert_reassoc_req_frame2_mlo_struct(uint8_t *pframe, uint32_t nframe,
4328 tDot11fReAssocRequest *ar,
4329 tpSirAssocReq p_assoc_req)
4330 {
4331 uint8_t *ml_ie;
4332 qdf_size_t ml_ie_total_len;
4333 struct qdf_mac_addr mld_mac_addr;
4334 uint32_t status = QDF_STATUS_SUCCESS;
4335
4336 if (ar->mlo_ie.present) {
4337 status = util_find_mlie(pframe + WLAN_REASSOC_REQ_IES_OFFSET,
4338 nframe - WLAN_ASSOC_REQ_IES_OFFSET,
4339 &ml_ie, &ml_ie_total_len);
4340 if (QDF_IS_STATUS_SUCCESS(status)) {
4341 util_get_bvmlie_persta_partner_info(ml_ie,
4342 ml_ie_total_len,
4343 &p_assoc_req->mlo_info);
4344
4345 util_get_bvmlie_mldmacaddr(ml_ie, ml_ie_total_len,
4346 &mld_mac_addr);
4347 qdf_mem_copy(p_assoc_req->mld_mac, mld_mac_addr.bytes,
4348 QDF_MAC_ADDR_SIZE);
4349 } else {
4350 pe_debug("Do not find ml ie");
4351 }
4352 }
4353 return status;
4354 }
4355 #else
4356 static QDF_STATUS
4357 sir_convert_reassoc_req_frame2_mlo_struct(uint8_t *pframe, uint32_t nframe,
4358 tDot11fReAssocRequest *ar,
4359 tpSirAssocReq p_assoc_req)
4360 {
4361 return QDF_STATUS_SUCCESS;
4362 }
4363 #endif
4364 enum wlan_status_code
4365 sir_convert_reassoc_req_frame2_struct(struct mac_context *mac,
4366 uint8_t *pFrame,
4367 uint32_t nFrame, tpSirAssocReq pAssocReq)
4368 {
4369 tDot11fReAssocRequest *ar;
4370 uint32_t status;
4371
4372 ar = qdf_mem_malloc(sizeof(*ar));
4373 if (!ar)
4374 return STATUS_UNSPECIFIED_FAILURE;
4375
4376 /* delegate to the framesc-generated code, */
4377 status = dot11f_unpack_re_assoc_request(mac, pFrame, nFrame,
4378 ar, false);
4379 if (DOT11F_FAILED(status)) {
4380 pe_err("Failed to parse a Re-association Request (0x%08x, %d bytes):",
4381 status, nFrame);
4382 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_ERROR,
4383 pFrame, nFrame);
4384 qdf_mem_free(ar);
4385 return STATUS_UNSPECIFIED_FAILURE;
4386 } else if (DOT11F_WARNED(status)) {
4387 pe_debug("There were warnings while unpacking a Re-association Request (0x%08x, %d bytes):",
4388 status, nFrame);
4389 }
4390 /* & "transliterate" from a 'tDot11fReAssocRequest' to a 'tSirAssocReq'... */
4391
4392 /* make sure this is seen as a re-assoc request */
4393 pAssocReq->reassocRequest = 1;
4394
4395 /* Capabilities */
4396 pAssocReq->capabilityInfo.ess = ar->Capabilities.ess;
4397 pAssocReq->capabilityInfo.ibss = ar->Capabilities.ibss;
4398 pAssocReq->capabilityInfo.cfPollable = ar->Capabilities.cfPollable;
4399 pAssocReq->capabilityInfo.cfPollReq = ar->Capabilities.cfPollReq;
4400 pAssocReq->capabilityInfo.privacy = ar->Capabilities.privacy;
4401 pAssocReq->capabilityInfo.shortPreamble = ar->Capabilities.shortPreamble;
4402 pAssocReq->capabilityInfo.criticalUpdateFlag =
4403 ar->Capabilities.criticalUpdateFlag;
4404 pAssocReq->capabilityInfo.channelAgility =
4405 ar->Capabilities.channelAgility;
4406 pAssocReq->capabilityInfo.spectrumMgt = ar->Capabilities.spectrumMgt;
4407 pAssocReq->capabilityInfo.qos = ar->Capabilities.qos;
4408 pAssocReq->capabilityInfo.shortSlotTime = ar->Capabilities.shortSlotTime;
4409 pAssocReq->capabilityInfo.apsd = ar->Capabilities.apsd;
4410 pAssocReq->capabilityInfo.rrm = ar->Capabilities.rrm;
4411 pAssocReq->capabilityInfo.dsssOfdm = ar->Capabilities.dsssOfdm;
4412 pAssocReq->capabilityInfo.delayedBA = ar->Capabilities.delayedBA;
4413 pAssocReq->capabilityInfo.immediateBA = ar->Capabilities.immediateBA;
4414
4415 /* Listen Interval */
4416 pAssocReq->listenInterval = ar->ListenInterval.interval;
4417
4418 /* SSID */
4419 if (ar->SSID.present) {
4420 pAssocReq->ssidPresent = 1;
4421 convert_ssid(mac, &pAssocReq->ssId, &ar->SSID);
4422 }
4423 /* Supported Rates */
4424 if (ar->SuppRates.present) {
4425 pAssocReq->suppRatesPresent = 1;
4426 convert_supp_rates(mac, &pAssocReq->supportedRates,
4427 &ar->SuppRates);
4428 }
4429 /* Extended Supported Rates */
4430 if (ar->ExtSuppRates.present) {
4431 pAssocReq->extendedRatesPresent = 1;
4432 convert_ext_supp_rates(mac, &pAssocReq->extendedRates,
4433 &ar->ExtSuppRates);
4434 }
4435 /* QOS Capabilities: */
4436 if (ar->QOSCapsStation.present) {
4437 pAssocReq->qosCapabilityPresent = 1;
4438 convert_qos_caps_station(mac, &pAssocReq->qosCapability,
4439 &ar->QOSCapsStation);
4440 }
4441 /* WPA */
4442 if (ar->WPAOpaque.present) {
4443 pAssocReq->wpaPresent = 1;
4444 convert_wpa_opaque(mac, &pAssocReq->wpa, &ar->WPAOpaque);
4445 }
4446 /* RSN */
4447 if (ar->RSNOpaque.present) {
4448 pAssocReq->rsnPresent = 1;
4449 convert_rsn_opaque(mac, &pAssocReq->rsn, &ar->RSNOpaque);
4450 }
4451
4452 /* Power Capabilities */
4453 if (ar->PowerCaps.present) {
4454 pAssocReq->powerCapabilityPresent = 1;
4455 convert_power_caps(mac, &pAssocReq->powerCapability,
4456 &ar->PowerCaps);
4457 }
4458 /* Supported Channels */
4459 if (ar->SuppChannels.present) {
4460 pAssocReq->supportedChannelsPresent = 1;
4461 convert_supp_channels(mac, &pAssocReq->supportedChannels,
4462 &ar->SuppChannels);
4463 }
4464
4465 if (ar->HTCaps.present) {
4466 qdf_mem_copy(&pAssocReq->HTCaps, &ar->HTCaps,
4467 sizeof(tDot11fIEHTCaps));
4468 }
4469
4470 if (ar->WMMInfoStation.present) {
4471 pAssocReq->wmeInfoPresent = 1;
4472 qdf_mem_copy(&pAssocReq->WMMInfoStation, &ar->WMMInfoStation,
4473 sizeof(tDot11fIEWMMInfoStation));
4474
4475 }
4476
4477 if (ar->WMMCaps.present)
4478 pAssocReq->wsmCapablePresent = 1;
4479
4480 if (!pAssocReq->ssidPresent) {
4481 pe_debug("Received Assoc without SSID IE");
4482 qdf_mem_free(ar);
4483 return STATUS_UNSPECIFIED_FAILURE;
4484 }
4485
4486 if (!pAssocReq->suppRatesPresent && !pAssocReq->extendedRatesPresent) {
4487 pe_debug("Received Assoc without supp rate IE");
4488 qdf_mem_free(ar);
4489 return STATUS_ASSOC_DENIED_RATES;
4490 }
4491 /* Why no call to 'updateAssocReqFromPropCapability' here, like */
4492 /* there is in 'sir_convert_assoc_req_frame2_struct'? */
4493
4494 /* WSC IE */
4495 if (ar->WscIEOpaque.present) {
4496 pAssocReq->addIEPresent = 1;
4497 convert_wsc_opaque(mac, &pAssocReq->addIE, &ar->WscIEOpaque);
4498 }
4499
4500 if (ar->P2PIEOpaque.present) {
4501 pAssocReq->addIEPresent = 1;
4502 convert_p2p_opaque(mac, &pAssocReq->addIE, &ar->P2PIEOpaque);
4503 }
4504 #ifdef WLAN_FEATURE_WFD
4505 if (ar->WFDIEOpaque.present) {
4506 pAssocReq->addIEPresent = 1;
4507 convert_wfd_opaque(mac, &pAssocReq->addIE, &ar->WFDIEOpaque);
4508 }
4509 #endif
4510 if (ar->SuppOperatingClasses.present) {
4511 uint8_t num_classes = ar->SuppOperatingClasses.num_classes;
4512
4513 if (num_classes > sizeof(ar->SuppOperatingClasses.classes))
4514 num_classes =
4515 sizeof(ar->SuppOperatingClasses.classes);
4516 qdf_mem_copy(&pAssocReq->supp_operating_classes,
4517 &ar->SuppOperatingClasses,
4518 sizeof(tDot11fIESuppOperatingClasses));
4519 QDF_TRACE_HEX_DUMP(
4520 QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_DEBUG,
4521 ar->SuppOperatingClasses.classes, num_classes);
4522 }
4523 if (ar->VHTCaps.present) {
4524 qdf_mem_copy(&pAssocReq->VHTCaps, &ar->VHTCaps,
4525 sizeof(tDot11fIEVHTCaps));
4526 }
4527 if (ar->OperatingMode.present) {
4528 qdf_mem_copy(&pAssocReq->operMode, &ar->OperatingMode,
4529 sizeof(tDot11fIEOperatingMode));
4530 pe_warn("Received Assoc Req with Operating Mode IE");
4531 lim_log_operating_mode(mac, &pAssocReq->operMode);
4532 }
4533 if (ar->ExtCap.present) {
4534 struct s_ext_cap *ext_cap;
4535
4536 qdf_mem_copy(&pAssocReq->ExtCap, &ar->ExtCap,
4537 sizeof(tDot11fIEExtCap));
4538 ext_cap = (struct s_ext_cap *)&pAssocReq->ExtCap.bytes;
4539 pe_debug("timingMeas: %d, finetimingMeas Init: %d, Resp: %d",
4540 ext_cap->timing_meas, ext_cap->fine_time_meas_initiator,
4541 ext_cap->fine_time_meas_responder);
4542 }
4543 if (ar->he_cap.present) {
4544 qdf_mem_copy(&pAssocReq->he_cap, &ar->he_cap,
4545 sizeof(tDot11fIEhe_cap));
4546 }
4547 if (ar->he_6ghz_band_cap.present) {
4548 qdf_mem_copy(&pAssocReq->he_6ghz_band_cap,
4549 &ar->he_6ghz_band_cap,
4550 sizeof(tDot11fIEhe_6ghz_band_cap));
4551 }
4552
4553 sir_convert_reassoc_req_frame2_eht_struct(ar, pAssocReq);
4554 sir_convert_reassoc_req_frame2_mlo_struct(pFrame, nFrame,
4555 ar, pAssocReq);
4556 pe_debug("ht %d vht %d opmode %d vendor vht %d he %d he 6ghband %d eht %d",
4557 ar->HTCaps.present, ar->VHTCaps.present,
4558 ar->OperatingMode.present, ar->vendor_vht_ie.VHTCaps.present,
4559 ar->he_cap.present, ar->he_6ghz_band_cap.present,
4560 ar->eht_cap.present);
4561 qdf_mem_free(ar);
4562
4563 return STATUS_SUCCESS;
4564
4565 } /* End sir_convert_reassoc_req_frame2_struct. */
4566
4567 #ifdef FEATURE_WLAN_ESE
4568 QDF_STATUS
4569 sir_beacon_ie_ese_bcn_report(struct mac_context *mac,
4570 uint8_t *pPayload, const uint32_t nPayload,
4571 uint8_t **outIeBuf, uint32_t *pOutIeLen)
4572 {
4573 tDot11fBeaconIEs *pBies = NULL;
4574 uint32_t status = QDF_STATUS_SUCCESS;
4575 QDF_STATUS retStatus = QDF_STATUS_SUCCESS;
4576 tSirEseBcnReportMandatoryIe eseBcnReportMandatoryIe;
4577
4578 /* To store how many bytes are required to be allocated
4579 for Bcn report mandatory Ies */
4580 uint16_t numBytes = 0, freeBytes = 0;
4581 uint8_t *pos = NULL;
4582 uint32_t freq;
4583
4584 freq = WMA_GET_RX_FREQ(pPayload);
4585 /* Zero-init our [out] parameter, */
4586 qdf_mem_zero((uint8_t *) &eseBcnReportMandatoryIe,
4587 sizeof(eseBcnReportMandatoryIe));
4588 pBies = qdf_mem_malloc(sizeof(tDot11fBeaconIEs));
4589 if (!pBies)
4590 return QDF_STATUS_E_NOMEM;
4591 qdf_mem_zero(pBies, sizeof(tDot11fBeaconIEs));
4592 /* delegate to the framesc-generated code, */
4593 status = dot11f_unpack_beacon_i_es(mac, pPayload, nPayload,
4594 pBies, false);
4595
4596 if (DOT11F_FAILED(status)) {
4597 pe_err("Failed to parse Beacon IEs (0x%08x, %d bytes):",
4598 status, nPayload);
4599 qdf_mem_free(pBies);
4600 return QDF_STATUS_E_FAILURE;
4601 } else if (DOT11F_WARNED(status)) {
4602 pe_debug("There were warnings while unpacking Beacon IEs (0x%08x, %d bytes):",
4603 status, nPayload);
4604 }
4605
4606 status = lim_strip_and_decode_eht_op(pPayload + WLAN_BEACON_IES_OFFSET,
4607 nPayload - WLAN_BEACON_IES_OFFSET,
4608 &pBies->eht_op,
4609 pBies->VHTOperation,
4610 pBies->he_op,
4611 pBies->HTInfo);
4612 if (status != QDF_STATUS_SUCCESS) {
4613 pe_err("Failed to extract eht op");
4614 qdf_mem_free(pBies);
4615 return status;
4616 }
4617
4618 status = lim_strip_and_decode_eht_cap(pPayload + WLAN_BEACON_IES_OFFSET,
4619 nPayload - WLAN_BEACON_IES_OFFSET,
4620 &pBies->eht_cap,
4621 pBies->he_cap,
4622 freq);
4623 if (status != QDF_STATUS_SUCCESS) {
4624 pe_err("Failed to extract eht cap");
4625 qdf_mem_free(pBies);
4626 return status;
4627 }
4628
4629 /* & "transliterate" from a 'tDot11fBeaconIEs' to a 'eseBcnReportMandatoryIe'... */
4630 if (!pBies->SSID.present) {
4631 pe_debug("Mandatory IE SSID not present!");
4632 } else {
4633 eseBcnReportMandatoryIe.ssidPresent = 1;
4634 convert_ssid(mac, &eseBcnReportMandatoryIe.ssId, &pBies->SSID);
4635 /* 1 for EID, 1 for length and length bytes */
4636 numBytes += 1 + 1 + eseBcnReportMandatoryIe.ssId.length;
4637 }
4638
4639 if (!pBies->SuppRates.present) {
4640 pe_debug_rl("Mandatory IE Supported Rates not present!");
4641 } else {
4642 eseBcnReportMandatoryIe.suppRatesPresent = 1;
4643 convert_supp_rates(mac, &eseBcnReportMandatoryIe.supportedRates,
4644 &pBies->SuppRates);
4645 numBytes +=
4646 1 + 1 + eseBcnReportMandatoryIe.supportedRates.numRates;
4647 }
4648
4649 if (pBies->FHParamSet.present) {
4650 eseBcnReportMandatoryIe.fhParamPresent = 1;
4651 convert_fh_params(mac, &eseBcnReportMandatoryIe.fhParamSet,
4652 &pBies->FHParamSet);
4653 numBytes += 1 + 1 + WLAN_FH_PARAM_IE_MAX_LEN;
4654 }
4655
4656 if (pBies->DSParams.present) {
4657 eseBcnReportMandatoryIe.dsParamsPresent = 1;
4658 eseBcnReportMandatoryIe.dsParamSet.channelNumber =
4659 pBies->DSParams.curr_channel;
4660 numBytes += 1 + 1 + WLAN_DS_PARAM_IE_MAX_LEN;
4661 }
4662
4663 if (pBies->CFParams.present) {
4664 eseBcnReportMandatoryIe.cfPresent = 1;
4665 convert_cf_params(mac, &eseBcnReportMandatoryIe.cfParamSet,
4666 &pBies->CFParams);
4667 numBytes += 1 + 1 + WLAN_CF_PARAM_IE_MAX_LEN;
4668 }
4669
4670 if (pBies->TIM.present) {
4671 eseBcnReportMandatoryIe.timPresent = 1;
4672 eseBcnReportMandatoryIe.tim.dtimCount = pBies->TIM.dtim_count;
4673 eseBcnReportMandatoryIe.tim.dtimPeriod = pBies->TIM.dtim_period;
4674 eseBcnReportMandatoryIe.tim.bitmapControl = pBies->TIM.bmpctl;
4675 /* As per the ESE spec, May truncate and report first 4 octets only */
4676 numBytes += 1 + 1 + SIR_MAC_TIM_EID_MIN;
4677 }
4678
4679 if (pBies->RRMEnabledCap.present) {
4680 eseBcnReportMandatoryIe.rrmPresent = 1;
4681 qdf_mem_copy(&eseBcnReportMandatoryIe.rmEnabledCapabilities,
4682 &pBies->RRMEnabledCap,
4683 sizeof(tDot11fIERRMEnabledCap));
4684 numBytes += 1 + 1 + WLAN_RM_CAPABILITY_IE_MAX_LEN;
4685 }
4686
4687 *outIeBuf = qdf_mem_malloc(numBytes);
4688 if (!*outIeBuf) {
4689 qdf_mem_free(pBies);
4690 return QDF_STATUS_E_NOMEM;
4691 }
4692 pos = *outIeBuf;
4693 *pOutIeLen = numBytes;
4694 freeBytes = numBytes;
4695
4696 /* Start filling the output Ie with Mandatory IE information */
4697 /* Fill SSID IE */
4698 if (eseBcnReportMandatoryIe.ssidPresent) {
4699 if (freeBytes < (1 + 1 + eseBcnReportMandatoryIe.ssId.length)) {
4700 pe_err("Insufficient memory to copy SSID");
4701 retStatus = QDF_STATUS_E_FAILURE;
4702 goto err_bcnrep;
4703 }
4704 *pos = WLAN_ELEMID_SSID;
4705 pos++;
4706 *pos = eseBcnReportMandatoryIe.ssId.length;
4707 pos++;
4708 qdf_mem_copy(pos,
4709 (uint8_t *) eseBcnReportMandatoryIe.ssId.ssId,
4710 eseBcnReportMandatoryIe.ssId.length);
4711 pos += eseBcnReportMandatoryIe.ssId.length;
4712 freeBytes -= (1 + 1 + eseBcnReportMandatoryIe.ssId.length);
4713 }
4714
4715 /* Fill Supported Rates IE */
4716 if (eseBcnReportMandatoryIe.suppRatesPresent) {
4717 if (freeBytes <
4718 (1 + 1 + eseBcnReportMandatoryIe.supportedRates.numRates)) {
4719 pe_err("Insufficient memory to copy Rates IE");
4720 retStatus = QDF_STATUS_E_FAILURE;
4721 goto err_bcnrep;
4722 }
4723 if (eseBcnReportMandatoryIe.supportedRates.numRates <=
4724 WLAN_SUPPORTED_RATES_IE_MAX_LEN) {
4725 *pos = WLAN_ELEMID_RATES;
4726 pos++;
4727 *pos = eseBcnReportMandatoryIe.supportedRates.numRates;
4728 pos++;
4729 qdf_mem_copy(pos,
4730 (uint8_t *) eseBcnReportMandatoryIe.supportedRates.
4731 rate,
4732 eseBcnReportMandatoryIe.supportedRates.numRates);
4733 pos += eseBcnReportMandatoryIe.supportedRates.numRates;
4734 freeBytes -=
4735 (1 + 1 +
4736 eseBcnReportMandatoryIe.supportedRates.numRates);
4737 }
4738 }
4739
4740 /* Fill FH Parameter set IE */
4741 if (eseBcnReportMandatoryIe.fhParamPresent) {
4742 if (freeBytes < (1 + 1 + WLAN_FH_PARAM_IE_MAX_LEN)) {
4743 pe_err("Insufficient memory to copy FHIE");
4744 retStatus = QDF_STATUS_E_FAILURE;
4745 goto err_bcnrep;
4746 }
4747 *pos = WLAN_ELEMID_FHPARMS;
4748 pos++;
4749 *pos = WLAN_FH_PARAM_IE_MAX_LEN;
4750 pos++;
4751 qdf_mem_copy(pos,
4752 (uint8_t *) &eseBcnReportMandatoryIe.fhParamSet,
4753 WLAN_FH_PARAM_IE_MAX_LEN);
4754 pos += WLAN_FH_PARAM_IE_MAX_LEN;
4755 freeBytes -= (1 + 1 + WLAN_FH_PARAM_IE_MAX_LEN);
4756 }
4757
4758 /* Fill DS Parameter set IE */
4759 if (eseBcnReportMandatoryIe.dsParamsPresent) {
4760 if (freeBytes < (1 + 1 + WLAN_DS_PARAM_IE_MAX_LEN)) {
4761 pe_err("Insufficient memory to copy DS IE");
4762 retStatus = QDF_STATUS_E_FAILURE;
4763 goto err_bcnrep;
4764 }
4765 *pos = WLAN_ELEMID_DSPARMS;
4766 pos++;
4767 *pos = WLAN_DS_PARAM_IE_MAX_LEN;
4768 pos++;
4769 *pos = eseBcnReportMandatoryIe.dsParamSet.channelNumber;
4770 pos += WLAN_DS_PARAM_IE_MAX_LEN;
4771 freeBytes -= (1 + 1 + WLAN_DS_PARAM_IE_MAX_LEN);
4772 }
4773
4774 /* Fill CF Parameter set */
4775 if (eseBcnReportMandatoryIe.cfPresent) {
4776 if (freeBytes < (1 + 1 + WLAN_CF_PARAM_IE_MAX_LEN)) {
4777 pe_err("Insufficient memory to copy CF IE");
4778 retStatus = QDF_STATUS_E_FAILURE;
4779 goto err_bcnrep;
4780 }
4781 *pos = WLAN_ELEMID_CFPARMS;
4782 pos++;
4783 *pos = WLAN_CF_PARAM_IE_MAX_LEN;
4784 pos++;
4785 qdf_mem_copy(pos,
4786 (uint8_t *) &eseBcnReportMandatoryIe.cfParamSet,
4787 WLAN_CF_PARAM_IE_MAX_LEN);
4788 pos += WLAN_CF_PARAM_IE_MAX_LEN;
4789 freeBytes -= (1 + 1 + WLAN_CF_PARAM_IE_MAX_LEN);
4790 }
4791
4792 /* Fill TIM IE */
4793 if (eseBcnReportMandatoryIe.timPresent) {
4794 if (freeBytes < (1 + 1 + SIR_MAC_TIM_EID_MIN)) {
4795 pe_err("Insufficient memory to copy TIM IE");
4796 retStatus = QDF_STATUS_E_FAILURE;
4797 goto err_bcnrep;
4798 }
4799 *pos = WLAN_ELEMID_TIM;
4800 pos++;
4801 *pos = SIR_MAC_TIM_EID_MIN;
4802 pos++;
4803 qdf_mem_copy(pos,
4804 (uint8_t *) &eseBcnReportMandatoryIe.tim,
4805 SIR_MAC_TIM_EID_MIN);
4806 pos += SIR_MAC_TIM_EID_MIN;
4807 freeBytes -= (1 + 1 + SIR_MAC_TIM_EID_MIN);
4808 }
4809
4810 /* Fill RM Capability IE */
4811 if (eseBcnReportMandatoryIe.rrmPresent) {
4812 if (freeBytes < (1 + 1 + WLAN_RM_CAPABILITY_IE_MAX_LEN)) {
4813 pe_err("Insufficient memory to copy RRM IE");
4814 retStatus = QDF_STATUS_E_FAILURE;
4815 goto err_bcnrep;
4816 }
4817 *pos = WLAN_ELEMID_RRM;
4818 pos++;
4819 *pos = WLAN_RM_CAPABILITY_IE_MAX_LEN;
4820 pos++;
4821 qdf_mem_copy(pos,
4822 (uint8_t *) &eseBcnReportMandatoryIe.
4823 rmEnabledCapabilities,
4824 WLAN_RM_CAPABILITY_IE_MAX_LEN);
4825 freeBytes -= (1 + 1 + WLAN_RM_CAPABILITY_IE_MAX_LEN);
4826 }
4827
4828 if (freeBytes != 0) {
4829 pe_err("Mismatch in allocation and copying of IE in Bcn Rep");
4830 retStatus = QDF_STATUS_E_FAILURE;
4831 }
4832
4833 err_bcnrep:
4834 /* The message counter would not be incremented in case of
4835 * returning failure and hence next time, this function gets
4836 * called, it would be using the same msg ctr for a different
4837 * BSS.So, it is good to clear the memory allocated for a BSS
4838 * that is returning failure.On success, the caller would take
4839 * care of freeing up the memory*/
4840 if (retStatus == QDF_STATUS_E_FAILURE) {
4841 qdf_mem_free(*outIeBuf);
4842 *outIeBuf = NULL;
4843 }
4844
4845 qdf_mem_free(pBies);
4846 return retStatus;
4847 }
4848
4849 #endif /* FEATURE_WLAN_ESE */
4850
4851 #ifdef WLAN_FEATURE_11AX_BSS_COLOR
4852 static void update_bss_color_change_from_beacon_ies(tDot11fBeaconIEs *bcn_ies,
4853 tpSirProbeRespBeacon bcn_struct)
4854 {
4855 if (bcn_ies->bss_color_change.present) {
4856 qdf_mem_copy(&bcn_struct->vendor_he_bss_color_change,
4857 &bcn_ies->bss_color_change,
4858 sizeof(tDot11fIEbss_color_change));
4859 }
4860 }
4861 #else
4862 static inline void update_bss_color_change_from_beacon_ies(
4863 tDot11fBeaconIEs *bcn_ies,
4864 tpSirProbeRespBeacon bcn_struct)
4865 {}
4866 #endif
4867
4868 QDF_STATUS
4869 sir_parse_beacon_ie(struct mac_context *mac,
4870 tpSirProbeRespBeacon pBeaconStruct,
4871 uint8_t *pPayload, uint32_t nPayload)
4872 {
4873 tDot11fBeaconIEs *pBies;
4874 uint32_t status;
4875 uint32_t freq;
4876
4877 freq = WMA_GET_RX_FREQ(pPayload);
4878 /* Zero-init our [out] parameter, */
4879 qdf_mem_zero((uint8_t *) pBeaconStruct, sizeof(tSirProbeRespBeacon));
4880
4881 pBies = qdf_mem_malloc(sizeof(tDot11fBeaconIEs));
4882 if (!pBies)
4883 return QDF_STATUS_E_NOMEM;
4884 qdf_mem_zero(pBies, sizeof(tDot11fBeaconIEs));
4885 /* delegate to the framesc-generated code, */
4886 status = dot11f_unpack_beacon_i_es(mac, pPayload, nPayload,
4887 pBies, false);
4888
4889 if (DOT11F_FAILED(status)) {
4890 pe_err("Failed to parse Beacon IEs (0x%08x, %d bytes):",
4891 status, nPayload);
4892 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_ERROR,
4893 pPayload, nPayload);
4894 qdf_mem_free(pBies);
4895 return QDF_STATUS_E_FAILURE;
4896 } else if (DOT11F_WARNED(status)) {
4897 pe_debug("warnings (0x%08x, %d bytes):", status, nPayload);
4898 }
4899
4900 status = lim_strip_and_decode_eht_op(pPayload,
4901 nPayload,
4902 &pBies->eht_op,
4903 pBies->VHTOperation,
4904 pBies->he_op,
4905 pBies->HTInfo);
4906 if (status != QDF_STATUS_SUCCESS) {
4907 pe_err("Failed to extract eht op");
4908 qdf_mem_free(pBies);
4909 return QDF_STATUS_E_FAILURE;
4910 }
4911
4912 status = lim_strip_and_decode_eht_cap(pPayload,
4913 nPayload,
4914 &pBies->eht_cap,
4915 pBies->he_cap,
4916 freq);
4917 if (status != QDF_STATUS_SUCCESS) {
4918 pe_err("Failed to extract eht cap");
4919 qdf_mem_free(pBies);
4920 return QDF_STATUS_E_FAILURE;
4921 }
4922
4923 /* & "transliterate" from a 'tDot11fBeaconIEs' to a 'tSirProbeRespBeacon'... */
4924 if (!pBies->SSID.present) {
4925 pe_debug("Mandatory IE SSID not present!");
4926 } else {
4927 pBeaconStruct->ssidPresent = 1;
4928 convert_ssid(mac, &pBeaconStruct->ssId, &pBies->SSID);
4929 }
4930
4931 if (!pBies->SuppRates.present) {
4932 pe_debug_rl("Mandatory IE Supported Rates not present!");
4933 } else {
4934 pBeaconStruct->suppRatesPresent = 1;
4935 convert_supp_rates(mac, &pBeaconStruct->supportedRates,
4936 &pBies->SuppRates);
4937 }
4938
4939 if (pBies->ExtSuppRates.present) {
4940 pBeaconStruct->extendedRatesPresent = 1;
4941 convert_ext_supp_rates(mac, &pBeaconStruct->extendedRates,
4942 &pBies->ExtSuppRates);
4943 }
4944
4945 if (pBies->CFParams.present) {
4946 pBeaconStruct->cfPresent = 1;
4947 convert_cf_params(mac, &pBeaconStruct->cfParamSet,
4948 &pBies->CFParams);
4949 }
4950
4951 if (pBies->TIM.present) {
4952 pBeaconStruct->timPresent = 1;
4953 convert_tim(mac, &pBeaconStruct->tim, &pBies->TIM);
4954 }
4955
4956 if (pBies->Country.present) {
4957 pBeaconStruct->countryInfoPresent = 1;
4958 convert_country(mac, &pBeaconStruct->countryInfoParam,
4959 &pBies->Country);
4960 }
4961 /* 11h IEs */
4962 if (pBies->TPCReport.present) {
4963 pBeaconStruct->tpcReportPresent = 1;
4964 qdf_mem_copy(&pBeaconStruct->tpcReport,
4965 &pBies->TPCReport, sizeof(tDot11fIETPCReport));
4966 }
4967
4968 if (pBies->PowerConstraints.present) {
4969 pBeaconStruct->powerConstraintPresent = 1;
4970 qdf_mem_copy(&pBeaconStruct->localPowerConstraint,
4971 &pBies->PowerConstraints,
4972 sizeof(tDot11fIEPowerConstraints));
4973 }
4974 #ifdef FEATURE_WLAN_ESE
4975 if (pBies->ESEVersion.present)
4976 pBeaconStruct->is_ese_ver_ie_present = 1;
4977 if (pBies->ESETxmitPower.present) {
4978 pBeaconStruct->eseTxPwr.present = 1;
4979 pBeaconStruct->eseTxPwr.power_limit =
4980 pBies->ESETxmitPower.power_limit;
4981 }
4982 if (pBies->QBSSLoad.present) {
4983 qdf_mem_copy(&pBeaconStruct->QBSSLoad, &pBies->QBSSLoad,
4984 sizeof(tDot11fIEQBSSLoad));
4985 }
4986 #endif
4987
4988 if (pBies->EDCAParamSet.present) {
4989 pBeaconStruct->edcaPresent = 1;
4990 convert_edca_param(mac, &pBeaconStruct->edcaParams,
4991 &pBies->EDCAParamSet);
4992 }
4993 /* QOS Capabilities: */
4994 if (pBies->QOSCapsAp.present) {
4995 pBeaconStruct->qosCapabilityPresent = 1;
4996 convert_qos_caps(mac, &pBeaconStruct->qosCapability,
4997 &pBies->QOSCapsAp);
4998 }
4999
5000 if (pBies->ChanSwitchAnn.present) {
5001 pBeaconStruct->channelSwitchPresent = 1;
5002 qdf_mem_copy(&pBeaconStruct->channelSwitchIE,
5003 &pBies->ChanSwitchAnn,
5004 sizeof(pBeaconStruct->channelSwitchIE));
5005 }
5006
5007 if (pBies->SuppOperatingClasses.present) {
5008 pBeaconStruct->supp_operating_class_present = 1;
5009 qdf_mem_copy(&pBeaconStruct->supp_operating_classes,
5010 &pBies->SuppOperatingClasses,
5011 sizeof(tDot11fIESuppOperatingClasses));
5012 }
5013
5014 if (pBies->ext_chan_switch_ann.present) {
5015 pBeaconStruct->ext_chan_switch_present = 1;
5016 qdf_mem_copy(&pBeaconStruct->ext_chan_switch,
5017 &pBies->ext_chan_switch_ann,
5018 sizeof(tDot11fIEext_chan_switch_ann));
5019 }
5020
5021 if (pBies->sec_chan_offset_ele.present) {
5022 pBeaconStruct->sec_chan_offset_present = 1;
5023 qdf_mem_copy(&pBeaconStruct->sec_chan_offset,
5024 &pBies->sec_chan_offset_ele,
5025 sizeof(pBeaconStruct->sec_chan_offset));
5026 }
5027
5028 if (pBies->Quiet.present) {
5029 pBeaconStruct->quietIEPresent = 1;
5030 qdf_mem_copy(&pBeaconStruct->quietIE, &pBies->Quiet,
5031 sizeof(tDot11fIEQuiet));
5032 }
5033
5034 if (pBies->HTCaps.present) {
5035 qdf_mem_copy(&pBeaconStruct->HTCaps, &pBies->HTCaps,
5036 sizeof(tDot11fIEHTCaps));
5037 }
5038
5039 if (pBies->HTInfo.present) {
5040 qdf_mem_copy(&pBeaconStruct->HTInfo, &pBies->HTInfo,
5041 sizeof(tDot11fIEHTInfo));
5042 }
5043
5044 if (pBies->he_op.oper_info_6g_present) {
5045 pBeaconStruct->chan_freq = wlan_reg_chan_band_to_freq(mac->pdev,
5046 pBies->he_op.oper_info_6g.info.primary_ch,
5047 BIT(REG_BAND_6G));
5048 } else if (pBies->DSParams.present) {
5049 pBeaconStruct->dsParamsPresent = 1;
5050 pBeaconStruct->chan_freq =
5051 wlan_reg_legacy_chan_to_freq(mac->pdev,
5052 pBies->DSParams.curr_channel);
5053 } else if (pBies->HTInfo.present) {
5054 pBeaconStruct->chan_freq =
5055 wlan_reg_legacy_chan_to_freq(mac->pdev,
5056 pBies->HTInfo.primaryChannel);
5057 }
5058
5059 if (pBies->RSN.present) {
5060 pBeaconStruct->rsnPresent = 1;
5061 convert_rsn(mac, &pBeaconStruct->rsn, &pBies->RSN);
5062 }
5063
5064 if (pBies->WPA.present) {
5065 pBeaconStruct->wpaPresent = 1;
5066 convert_wpa(mac, &pBeaconStruct->wpa, &pBies->WPA);
5067 }
5068
5069 if (pBies->WMMParams.present) {
5070 pBeaconStruct->wmeEdcaPresent = 1;
5071 convert_wmm_params(mac, &pBeaconStruct->edcaParams,
5072 &pBies->WMMParams);
5073 qdf_mem_copy(&pBeaconStruct->wmm_params, &pBies->WMMParams,
5074 sizeof(tDot11fIEWMMParams));
5075 }
5076
5077 if (pBies->WMMInfoAp.present) {
5078 pBeaconStruct->wmeInfoPresent = 1;
5079 }
5080
5081 if (pBies->WMMCaps.present) {
5082 pBeaconStruct->wsmCapablePresent = 1;
5083 }
5084
5085 if (pBies->ERPInfo.present) {
5086 pBeaconStruct->erpPresent = 1;
5087 convert_erp_info(mac, &pBeaconStruct->erpIEInfo,
5088 &pBies->ERPInfo);
5089 }
5090 if (pBies->VHTCaps.present) {
5091 pBeaconStruct->VHTCaps.present = 1;
5092 qdf_mem_copy(&pBeaconStruct->VHTCaps, &pBies->VHTCaps,
5093 sizeof(tDot11fIEVHTCaps));
5094 }
5095 if (pBies->VHTOperation.present) {
5096 pBeaconStruct->VHTOperation.present = 1;
5097 qdf_mem_copy(&pBeaconStruct->VHTOperation, &pBies->VHTOperation,
5098 sizeof(tDot11fIEVHTOperation));
5099 }
5100 if (pBies->VHTExtBssLoad.present) {
5101 pBeaconStruct->VHTExtBssLoad.present = 1;
5102 qdf_mem_copy(&pBeaconStruct->VHTExtBssLoad,
5103 &pBies->VHTExtBssLoad,
5104 sizeof(tDot11fIEVHTExtBssLoad));
5105 }
5106 if (pBies->OperatingMode.present) {
5107 pBeaconStruct->OperatingMode.present = 1;
5108 qdf_mem_copy(&pBeaconStruct->OperatingMode,
5109 &pBies->OperatingMode,
5110 sizeof(tDot11fIEOperatingMode));
5111 }
5112 if (pBies->MobilityDomain.present) {
5113 pBeaconStruct->mdiePresent = 1;
5114 qdf_mem_copy(pBeaconStruct->mdie, &pBies->MobilityDomain.MDID,
5115 SIR_MDIE_SIZE);
5116 }
5117
5118 pBeaconStruct->Vendor1IEPresent = pBies->Vendor1IE.present;
5119 pBeaconStruct->Vendor3IEPresent = pBies->Vendor3IE.present;
5120 pBeaconStruct->vendor_vht_ie.present = pBies->vendor_vht_ie.present;
5121 if (pBies->vendor_vht_ie.present)
5122 pBeaconStruct->vendor_vht_ie.sub_type =
5123 pBies->vendor_vht_ie.sub_type;
5124
5125 if (pBies->vendor_vht_ie.VHTCaps.present) {
5126 pBeaconStruct->vendor_vht_ie.VHTCaps.present = 1;
5127 qdf_mem_copy(&pBeaconStruct->vendor_vht_ie.VHTCaps,
5128 &pBies->vendor_vht_ie.VHTCaps,
5129 sizeof(tDot11fIEVHTCaps));
5130 }
5131 if (pBies->vendor_vht_ie.VHTOperation.present) {
5132 pBeaconStruct->vendor_vht_ie.VHTOperation.present = 1;
5133 qdf_mem_copy(&pBeaconStruct->vendor_vht_ie.VHTOperation,
5134 &pBies->vendor_vht_ie.VHTOperation,
5135 sizeof(tDot11fIEVHTOperation));
5136 }
5137 if (pBies->ExtCap.present) {
5138 qdf_mem_copy(&pBeaconStruct->ext_cap, &pBies->ExtCap,
5139 sizeof(tDot11fIEExtCap));
5140 }
5141 /* Update HS 2.0 Information Element */
5142 if (pBies->hs20vendor_ie.present) {
5143 pe_debug("HS20 Indication Element Present, rel#:%u, id:%u",
5144 pBies->hs20vendor_ie.release_num,
5145 pBies->hs20vendor_ie.hs_id_present);
5146 qdf_mem_copy(&pBeaconStruct->hs20vendor_ie,
5147 &pBies->hs20vendor_ie,
5148 sizeof(tDot11fIEhs20vendor_ie) -
5149 sizeof(pBies->hs20vendor_ie.hs_id));
5150 if (pBies->hs20vendor_ie.hs_id_present)
5151 qdf_mem_copy(&pBeaconStruct->hs20vendor_ie.hs_id,
5152 &pBies->hs20vendor_ie.hs_id,
5153 sizeof(pBies->hs20vendor_ie.hs_id));
5154 }
5155
5156 if (pBies->MBO_IE.present) {
5157 pBeaconStruct->MBO_IE_present = true;
5158 if (pBies->MBO_IE.cellular_data_cap.present)
5159 pBeaconStruct->MBO_capability =
5160 pBies->MBO_IE.cellular_data_cap.cellular_connectivity;
5161
5162 if (pBies->MBO_IE.assoc_disallowed.present) {
5163 pBeaconStruct->assoc_disallowed = true;
5164 pBeaconStruct->assoc_disallowed_reason =
5165 pBies->MBO_IE.assoc_disallowed.reason_code;
5166 }
5167 }
5168
5169 if (pBies->qcn_ie.present)
5170 qdf_mem_copy(&pBeaconStruct->qcn_ie, &pBies->qcn_ie,
5171 sizeof(tDot11fIEqcn_ie));
5172
5173 if (pBies->he_cap.present) {
5174 qdf_mem_copy(&pBeaconStruct->he_cap, &pBies->he_cap,
5175 sizeof(tDot11fIEhe_cap));
5176 }
5177 if (pBies->he_op.present) {
5178 qdf_mem_copy(&pBeaconStruct->he_op, &pBies->he_op,
5179 sizeof(tDot11fIEhe_op));
5180 }
5181
5182 if (pBies->eht_cap.present) {
5183 qdf_mem_copy(&pBeaconStruct->eht_cap, &pBies->eht_cap,
5184 sizeof(tDot11fIEeht_cap));
5185 }
5186 if (pBies->eht_op.present) {
5187 qdf_mem_copy(&pBeaconStruct->eht_op, &pBies->eht_op,
5188 sizeof(tDot11fIEeht_op));
5189 }
5190
5191 update_bss_color_change_from_beacon_ies(pBies, pBeaconStruct);
5192
5193 qdf_mem_free(pBies);
5194 return QDF_STATUS_SUCCESS;
5195 } /* End sir_parse_beacon_ie. */
5196
5197 #ifdef WLAN_FEATURE_11AX_BSS_COLOR
5198 static void convert_bcon_bss_color_change_ie(tDot11fBeacon *bcn_frm,
5199 tpSirProbeRespBeacon bcn_struct)
5200 {
5201 if (bcn_frm->bss_color_change.present) {
5202 pe_debug("11AX: HE BSS color change present");
5203 qdf_mem_copy(&bcn_struct->vendor_he_bss_color_change,
5204 &bcn_frm->bss_color_change,
5205 sizeof(tDot11fIEbss_color_change));
5206 }
5207 }
5208 #else
5209 static inline void convert_bcon_bss_color_change_ie(tDot11fBeacon *bcn_frm,
5210 tpSirProbeRespBeacon bcn_struct)
5211 {}
5212 #endif
5213
5214 #ifdef WLAN_FEATURE_SR
5215 static void sir_convert_beacon_frame2_sr_struct(tDot11fBeacon *bcn_frm,
5216 tpSirProbeRespBeacon bcn_struct)
5217 {
5218 if (bcn_frm->spatial_reuse.present)
5219 qdf_mem_copy(&bcn_struct->srp_ie, &bcn_frm->spatial_reuse,
5220 sizeof(tDot11fIEspatial_reuse));
5221 }
5222 #else
5223 static inline void
5224 sir_convert_beacon_frame2_sr_struct(tDot11fBeacon *bcn_frm,
5225 tpSirProbeRespBeacon bcn_struct)
5226 {
5227 }
5228 #endif
5229
5230 #ifdef WLAN_FEATURE_11BE_MLO
5231 static QDF_STATUS
5232 sir_convert_beacon_frame2_t2lm_struct(tDot11fBeacon *bcn_frm,
5233 tpSirProbeRespBeacon bcn_struct)
5234 {
5235 QDF_STATUS status = QDF_STATUS_SUCCESS;
5236 struct wlan_t2lm_context *t2lm_ctx;
5237 /* add 3 bytes for extn_ie_header */
5238 uint8_t ie[DOT11F_IE_T2LM_IE_MAX_LEN + 3];
5239 struct wlan_t2lm_info t2lm;
5240 uint8_t i;
5241
5242 t2lm_ctx = &bcn_struct->t2lm_ctx;
5243 qdf_mem_zero(&t2lm_ctx->established_t2lm.t2lm,
5244 sizeof(struct wlan_t2lm_info));
5245 t2lm_ctx->established_t2lm.t2lm.direction = WLAN_T2LM_INVALID_DIRECTION;
5246
5247 qdf_mem_zero(&t2lm_ctx->upcoming_t2lm.t2lm,
5248 sizeof(struct wlan_t2lm_info));
5249 t2lm_ctx->upcoming_t2lm.t2lm.direction = WLAN_T2LM_INVALID_DIRECTION;
5250
5251 if (!bcn_frm->num_t2lm_ie)
5252 return status;
5253
5254 pe_debug("Number of T2LM IEs in beacon %d", bcn_frm->num_t2lm_ie);
5255 for (i = 0; i < bcn_frm->num_t2lm_ie; i++) {
5256 qdf_mem_zero(&ie[0], DOT11F_IE_T2LM_IE_MAX_LEN + 3);
5257 qdf_mem_zero(&t2lm, sizeof(struct wlan_t2lm_info));
5258 ie[ID_POS] = WLAN_ELEMID_EXTN_ELEM;
5259 ie[TAG_LEN_POS] = bcn_frm->t2lm_ie[i].num_data + 1;
5260 ie[IDEXT_POS] = WLAN_EXTN_ELEMID_T2LM;
5261 qdf_mem_copy(&ie[3], &bcn_frm->t2lm_ie[i].data[0],
5262 bcn_frm->t2lm_ie[i].num_data);
5263 qdf_trace_hex_dump(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_DEBUG,
5264 &ie[0], bcn_frm->t2lm_ie[i].num_data + 3);
5265
5266 if (ie[TAG_LEN_POS] + 2 > DOT11F_IE_T2LM_IE_MAX_LEN + 3) {
5267 pe_debug("Invalid T2LM IE length");
5268 return QDF_STATUS_E_PROTO;
5269 }
5270
5271 status = wlan_mlo_parse_t2lm_info(&ie[0], &t2lm);
5272 if (QDF_IS_STATUS_ERROR(status)) {
5273 pe_debug("Parse T2LM IE fail");
5274 return status;
5275 }
5276
5277 if (!t2lm.mapping_switch_time_present &&
5278 t2lm.expected_duration_present) {
5279 qdf_mem_copy(&t2lm_ctx->established_t2lm.t2lm, &t2lm,
5280 sizeof(struct wlan_t2lm_info));
5281 pe_debug("Parse established T2LM IE success");
5282 } else if (t2lm.mapping_switch_time_present) {
5283 qdf_mem_copy(&t2lm_ctx->upcoming_t2lm.t2lm, &t2lm,
5284 sizeof(struct wlan_t2lm_info));
5285 pe_debug("Parse upcoming T2LM IE success");
5286 }
5287 pe_debug("Parse T2LM IE success");
5288 }
5289 return status;
5290 }
5291 #else
5292 static inline QDF_STATUS
5293 sir_convert_beacon_frame2_t2lm_struct(tDot11fBeacon *bcn_frm,
5294 tpSirProbeRespBeacon bcn_struct)
5295 {
5296 return QDF_STATUS_SUCCESS;
5297 }
5298 #endif
5299
5300 #ifdef WLAN_FEATURE_11BE_MLO
5301 static QDF_STATUS
5302 sir_convert_beacon_frame2_mlo_struct(uint8_t *pframe, uint32_t nframe,
5303 tDot11fBeacon *bcn_frm,
5304 tpSirProbeRespBeacon bcn_struct)
5305 {
5306 uint8_t *ml_ie, *sta_prof;
5307 qdf_size_t ml_ie_total_len;
5308 uint8_t common_info_len = 0;
5309 struct mlo_partner_info partner_info;
5310 QDF_STATUS status = QDF_STATUS_SUCCESS;
5311 uint8_t bpcc;
5312 bool bpcc_found;
5313 bool ext_mld_cap_found = false;
5314 uint16_t ext_mld_cap = 0;
5315
5316 if (bcn_frm->mlo_ie.present) {
5317 status = util_find_mlie(pframe + WLAN_BEACON_IES_OFFSET,
5318 nframe - WLAN_BEACON_IES_OFFSET,
5319 &ml_ie, &ml_ie_total_len);
5320 if (QDF_IS_STATUS_SUCCESS(status)) {
5321 status = util_get_bvmlie_persta_partner_info(
5322 ml_ie,
5323 ml_ie_total_len,
5324 &partner_info);
5325 if (QDF_IS_STATUS_ERROR(status))
5326 return status;
5327 bcn_struct->mlo_ie.mlo_ie.num_sta_profile =
5328 partner_info.num_partner_links;
5329 util_get_mlie_common_info_len(ml_ie, ml_ie_total_len,
5330 &common_info_len);
5331 sta_prof = ml_ie + sizeof(struct wlan_ie_multilink) +
5332 common_info_len;
5333
5334 lim_store_mlo_ie_raw_info(ml_ie, sta_prof,
5335 ml_ie_total_len,
5336 &bcn_struct->mlo_ie.mlo_ie);
5337
5338 util_get_bvmlie_ext_mld_cap_op_info(ml_ie,
5339 ml_ie_total_len,
5340 &ext_mld_cap_found,
5341 &ext_mld_cap);
5342 if (ext_mld_cap_found) {
5343 bcn_struct->mlo_ie.mlo_ie.ext_mld_capab_and_op_info.rec_max_simultaneous_links =
5344 QDF_GET_BITS(
5345 ext_mld_cap,
5346 WLAN_ML_BV_CINFO_EXTMLDCAPINFO_RECOM_MAX_SIMULT_LINKS_IDX,
5347 WLAN_ML_BV_CINFO_EXTMLDCAPINFO_RECOM_MAX_SIMULT_LINKS_BITS);
5348 }
5349 util_get_bvmlie_bssparamchangecnt(ml_ie,
5350 ml_ie_total_len,
5351 &bpcc_found, &bpcc);
5352 bcn_struct->mlo_ie.mlo_ie.bss_param_change_cnt_present =
5353 bpcc_found;
5354 bcn_struct->mlo_ie.mlo_ie.bss_param_change_count = bpcc;
5355 bcn_struct->mlo_ie.mlo_ie_present = true;
5356 }
5357 }
5358
5359 return status;
5360 }
5361 #else
5362 static inline QDF_STATUS
5363 sir_convert_beacon_frame2_mlo_struct(uint8_t *pframe, uint32_t nframe,
5364 tDot11fBeacon *bcn_frm,
5365 tpSirProbeRespBeacon bcn_struct)
5366 {
5367 return QDF_STATUS_SUCCESS;
5368 }
5369 #endif
5370
5371 QDF_STATUS
5372 sir_convert_beacon_frame2_struct(struct mac_context *mac,
5373 uint8_t *pFrame,
5374 tpSirProbeRespBeacon pBeaconStruct)
5375 {
5376 tDot11fBeacon *pBeacon;
5377 uint32_t status, nPayload;
5378 uint8_t *pPayload;
5379 tpSirMacMgmtHdr pHdr;
5380 uint32_t freq;
5381
5382 pPayload = WMA_GET_RX_MPDU_DATA(pFrame);
5383 nPayload = WMA_GET_RX_PAYLOAD_LEN(pFrame);
5384 pHdr = WMA_GET_RX_MAC_HEADER(pFrame);
5385 freq = WMA_GET_RX_FREQ(pFrame);
5386
5387 /* Zero-init our [out] parameter, */
5388 qdf_mem_zero((uint8_t *) pBeaconStruct, sizeof(tSirProbeRespBeacon));
5389
5390 pBeacon = qdf_mem_malloc_atomic(sizeof(tDot11fBeacon));
5391 if (!pBeacon)
5392 return QDF_STATUS_E_NOMEM;
5393
5394 /* get the MAC address out of the BD, */
5395 qdf_mem_copy(pBeaconStruct->bssid, pHdr->sa, 6);
5396
5397 /* delegate to the framesc-generated code, */
5398 status = dot11f_unpack_beacon(mac, pPayload, nPayload, pBeacon, false);
5399 if (DOT11F_FAILED(status)) {
5400 pe_err("Failed to parse Beacon IEs (0x%08x, %d bytes):",
5401 status, nPayload);
5402 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_DEBUG,
5403 pPayload, nPayload);
5404 qdf_mem_free(pBeacon);
5405 return QDF_STATUS_E_FAILURE;
5406 }
5407
5408 status = lim_strip_and_decode_eht_op(pPayload + WLAN_BEACON_IES_OFFSET,
5409 nPayload - WLAN_BEACON_IES_OFFSET,
5410 &pBeacon->eht_op,
5411 pBeacon->VHTOperation,
5412 pBeacon->he_op,
5413 pBeacon->HTInfo);
5414 if (status != QDF_STATUS_SUCCESS) {
5415 pe_err("Failed to extract eht op");
5416 qdf_mem_free(pBeacon);
5417 return QDF_STATUS_E_FAILURE;
5418 }
5419
5420 status = lim_strip_and_decode_eht_cap(pPayload + WLAN_BEACON_IES_OFFSET,
5421 nPayload - WLAN_BEACON_IES_OFFSET,
5422 &pBeacon->eht_cap,
5423 pBeacon->he_cap,
5424 freq);
5425 if (status != QDF_STATUS_SUCCESS) {
5426 pe_err("Failed to extract eht cap");
5427 qdf_mem_free(pBeacon);
5428 return QDF_STATUS_E_FAILURE;
5429 }
5430
5431 /* & "transliterate" from a 'tDot11fBeacon' to a 'tSirProbeRespBeacon'... */
5432 /* Timestamp */
5433 qdf_mem_copy((uint8_t *) pBeaconStruct->timeStamp,
5434 (uint8_t *) &pBeacon->TimeStamp,
5435 sizeof(tSirMacTimeStamp));
5436
5437 /* Beacon Interval */
5438 pBeaconStruct->beaconInterval = pBeacon->BeaconInterval.interval;
5439
5440 /* Capabilities */
5441 pBeaconStruct->capabilityInfo.ess = pBeacon->Capabilities.ess;
5442 pBeaconStruct->capabilityInfo.ibss = pBeacon->Capabilities.ibss;
5443 pBeaconStruct->capabilityInfo.cfPollable =
5444 pBeacon->Capabilities.cfPollable;
5445 pBeaconStruct->capabilityInfo.cfPollReq =
5446 pBeacon->Capabilities.cfPollReq;
5447 pBeaconStruct->capabilityInfo.privacy = pBeacon->Capabilities.privacy;
5448 pBeaconStruct->capabilityInfo.shortPreamble =
5449 pBeacon->Capabilities.shortPreamble;
5450 pBeaconStruct->capabilityInfo.criticalUpdateFlag =
5451 pBeacon->Capabilities.criticalUpdateFlag;
5452 pBeaconStruct->capabilityInfo.channelAgility =
5453 pBeacon->Capabilities.channelAgility;
5454 pBeaconStruct->capabilityInfo.spectrumMgt =
5455 pBeacon->Capabilities.spectrumMgt;
5456 pBeaconStruct->capabilityInfo.qos = pBeacon->Capabilities.qos;
5457 pBeaconStruct->capabilityInfo.shortSlotTime =
5458 pBeacon->Capabilities.shortSlotTime;
5459 pBeaconStruct->capabilityInfo.apsd = pBeacon->Capabilities.apsd;
5460 pBeaconStruct->capabilityInfo.rrm = pBeacon->Capabilities.rrm;
5461 pBeaconStruct->capabilityInfo.dsssOfdm = pBeacon->Capabilities.dsssOfdm;
5462 pBeaconStruct->capabilityInfo.delayedBA =
5463 pBeacon->Capabilities.delayedBA;
5464 pBeaconStruct->capabilityInfo.immediateBA =
5465 pBeacon->Capabilities.immediateBA;
5466
5467 if (!pBeacon->SSID.present) {
5468 pe_debug("Mandatory IE SSID not present!");
5469 } else {
5470 pBeaconStruct->ssidPresent = 1;
5471 convert_ssid(mac, &pBeaconStruct->ssId, &pBeacon->SSID);
5472 }
5473
5474 if (!pBeacon->SuppRates.present) {
5475 pe_debug_rl("Mandatory IE Supported Rates not present!");
5476 } else {
5477 pBeaconStruct->suppRatesPresent = 1;
5478 convert_supp_rates(mac, &pBeaconStruct->supportedRates,
5479 &pBeacon->SuppRates);
5480 }
5481
5482 if (pBeacon->ExtSuppRates.present) {
5483 pBeaconStruct->extendedRatesPresent = 1;
5484 convert_ext_supp_rates(mac, &pBeaconStruct->extendedRates,
5485 &pBeacon->ExtSuppRates);
5486 }
5487
5488 if (pBeacon->CFParams.present) {
5489 pBeaconStruct->cfPresent = 1;
5490 convert_cf_params(mac, &pBeaconStruct->cfParamSet,
5491 &pBeacon->CFParams);
5492 }
5493
5494 if (pBeacon->TIM.present) {
5495 pBeaconStruct->timPresent = 1;
5496 convert_tim(mac, &pBeaconStruct->tim, &pBeacon->TIM);
5497 }
5498
5499 if (pBeacon->Country.present) {
5500 pBeaconStruct->countryInfoPresent = 1;
5501 convert_country(mac, &pBeaconStruct->countryInfoParam,
5502 &pBeacon->Country);
5503 }
5504 /* QOS Capabilities: */
5505 if (pBeacon->QOSCapsAp.present) {
5506 pBeaconStruct->qosCapabilityPresent = 1;
5507 convert_qos_caps(mac, &pBeaconStruct->qosCapability,
5508 &pBeacon->QOSCapsAp);
5509 }
5510
5511 if (pBeacon->EDCAParamSet.present) {
5512 pBeaconStruct->edcaPresent = 1;
5513 convert_edca_param(mac, &pBeaconStruct->edcaParams,
5514 &pBeacon->EDCAParamSet);
5515 }
5516
5517 if (pBeacon->ChanSwitchAnn.present) {
5518 pBeaconStruct->channelSwitchPresent = 1;
5519 qdf_mem_copy(&pBeaconStruct->channelSwitchIE,
5520 &pBeacon->ChanSwitchAnn,
5521 sizeof(pBeaconStruct->channelSwitchIE));
5522 }
5523
5524 if (pBeacon->ext_chan_switch_ann.present) {
5525 pBeaconStruct->ext_chan_switch_present = 1;
5526 qdf_mem_copy(&pBeaconStruct->ext_chan_switch,
5527 &pBeacon->ext_chan_switch_ann,
5528 sizeof(tDot11fIEext_chan_switch_ann));
5529 }
5530
5531 if (pBeacon->sec_chan_offset_ele.present) {
5532 pBeaconStruct->sec_chan_offset_present = 1;
5533 qdf_mem_copy(&pBeaconStruct->sec_chan_offset,
5534 &pBeacon->sec_chan_offset_ele,
5535 sizeof(pBeaconStruct->sec_chan_offset));
5536 }
5537
5538 if (pBeacon->TPCReport.present) {
5539 pBeaconStruct->tpcReportPresent = 1;
5540 qdf_mem_copy(&pBeaconStruct->tpcReport, &pBeacon->TPCReport,
5541 sizeof(tDot11fIETPCReport));
5542 }
5543
5544 if (pBeacon->PowerConstraints.present) {
5545 pBeaconStruct->powerConstraintPresent = 1;
5546 qdf_mem_copy(&pBeaconStruct->localPowerConstraint,
5547 &pBeacon->PowerConstraints,
5548 sizeof(tDot11fIEPowerConstraints));
5549 }
5550
5551 if (pBeacon->Quiet.present) {
5552 pBeaconStruct->quietIEPresent = 1;
5553 qdf_mem_copy(&pBeaconStruct->quietIE, &pBeacon->Quiet,
5554 sizeof(tDot11fIEQuiet));
5555 }
5556
5557 if (pBeacon->HTCaps.present) {
5558 qdf_mem_copy(&pBeaconStruct->HTCaps, &pBeacon->HTCaps,
5559 sizeof(tDot11fIEHTCaps));
5560 }
5561
5562 if (pBeacon->HTInfo.present) {
5563 qdf_mem_copy(&pBeaconStruct->HTInfo, &pBeacon->HTInfo,
5564 sizeof(tDot11fIEHTInfo));
5565
5566 }
5567
5568 if (pBeacon->he_op.oper_info_6g_present) {
5569 pBeaconStruct->chan_freq = wlan_reg_chan_band_to_freq(mac->pdev,
5570 pBeacon->he_op.oper_info_6g.info.primary_ch,
5571 BIT(REG_BAND_6G));
5572 pBeaconStruct->ap_power_type =
5573 pBeacon->he_op.oper_info_6g.info.reg_info;
5574 } else if (pBeacon->DSParams.present) {
5575 pBeaconStruct->dsParamsPresent = 1;
5576 pBeaconStruct->chan_freq =
5577 wlan_reg_legacy_chan_to_freq(mac->pdev,
5578 pBeacon->DSParams.curr_channel);
5579 } else if (pBeacon->HTInfo.present) {
5580 pBeaconStruct->chan_freq =
5581 wlan_reg_legacy_chan_to_freq(mac->pdev,
5582 pBeacon->HTInfo.primaryChannel);
5583 } else {
5584 pBeaconStruct->chan_freq = WMA_GET_RX_FREQ(pFrame);
5585 pe_debug_rl("In Beacon No Channel info");
5586 }
5587
5588 if (pBeacon->RSN.present) {
5589 pBeaconStruct->rsnPresent = 1;
5590 convert_rsn(mac, &pBeaconStruct->rsn, &pBeacon->RSN);
5591 }
5592
5593 if (pBeacon->WPA.present) {
5594 pBeaconStruct->wpaPresent = 1;
5595 convert_wpa(mac, &pBeaconStruct->wpa, &pBeacon->WPA);
5596 }
5597
5598 if (pBeacon->WMMParams.present) {
5599 pBeaconStruct->wmeEdcaPresent = 1;
5600 convert_wmm_params(mac, &pBeaconStruct->edcaParams,
5601 &pBeacon->WMMParams);
5602 }
5603
5604 if (pBeacon->WMMInfoAp.present) {
5605 pBeaconStruct->wmeInfoPresent = 1;
5606 pe_debug("WMM Info present in Beacon Frame!");
5607 }
5608
5609 if (pBeacon->WMMCaps.present) {
5610 pBeaconStruct->wsmCapablePresent = 1;
5611 }
5612
5613 if (pBeacon->ERPInfo.present) {
5614 pBeaconStruct->erpPresent = 1;
5615 convert_erp_info(mac, &pBeaconStruct->erpIEInfo,
5616 &pBeacon->ERPInfo);
5617 }
5618 if (pBeacon->MobilityDomain.present) {
5619 /* MobilityDomain */
5620 pBeaconStruct->mdiePresent = 1;
5621 qdf_mem_copy((uint8_t *) &(pBeaconStruct->mdie[0]),
5622 (uint8_t *) &(pBeacon->MobilityDomain.MDID),
5623 sizeof(uint16_t));
5624 pBeaconStruct->mdie[2] =
5625 ((pBeacon->MobilityDomain.overDSCap << 0) | (pBeacon->
5626 MobilityDomain.
5627 resourceReqCap
5628 << 1));
5629 }
5630
5631 #ifdef FEATURE_WLAN_ESE
5632 if (pBeacon->ESEVersion.present)
5633 pBeaconStruct->is_ese_ver_ie_present = 1;
5634 if (pBeacon->ESETxmitPower.present) {
5635 /* copy ESE TPC info element */
5636 pBeaconStruct->eseTxPwr.present = 1;
5637 qdf_mem_copy(&pBeaconStruct->eseTxPwr,
5638 &pBeacon->ESETxmitPower,
5639 sizeof(tDot11fIEESETxmitPower));
5640 }
5641 if (pBeacon->QBSSLoad.present) {
5642 qdf_mem_copy(&pBeaconStruct->QBSSLoad,
5643 &pBeacon->QBSSLoad, sizeof(tDot11fIEQBSSLoad));
5644 }
5645 #endif
5646 if (pBeacon->VHTCaps.present) {
5647 qdf_mem_copy(&pBeaconStruct->VHTCaps, &pBeacon->VHTCaps,
5648 sizeof(tDot11fIEVHTCaps));
5649 }
5650 if (pBeacon->VHTOperation.present) {
5651 qdf_mem_copy(&pBeaconStruct->VHTOperation,
5652 &pBeacon->VHTOperation,
5653 sizeof(tDot11fIEVHTOperation));
5654 }
5655 if (pBeacon->VHTExtBssLoad.present) {
5656 qdf_mem_copy(&pBeaconStruct->VHTExtBssLoad,
5657 &pBeacon->VHTExtBssLoad,
5658 sizeof(tDot11fIEVHTExtBssLoad));
5659 }
5660 if (pBeacon->OperatingMode.present) {
5661 qdf_mem_copy(&pBeaconStruct->OperatingMode,
5662 &pBeacon->OperatingMode,
5663 sizeof(tDot11fIEOperatingMode));
5664 }
5665 if (pBeacon->WiderBWChanSwitchAnn.present) {
5666 pBeaconStruct->WiderBWChanSwitchAnnPresent = 1;
5667 qdf_mem_copy(&pBeaconStruct->WiderBWChanSwitchAnn,
5668 &pBeacon->WiderBWChanSwitchAnn,
5669 sizeof(tDot11fIEWiderBWChanSwitchAnn));
5670 }
5671
5672 pBeaconStruct->Vendor1IEPresent = pBeacon->Vendor1IE.present;
5673 pBeaconStruct->Vendor3IEPresent = pBeacon->Vendor3IE.present;
5674
5675 pBeaconStruct->vendor_vht_ie.present = pBeacon->vendor_vht_ie.present;
5676 if (pBeacon->vendor_vht_ie.present) {
5677 pBeaconStruct->vendor_vht_ie.sub_type =
5678 pBeacon->vendor_vht_ie.sub_type;
5679 }
5680
5681 if (pBeacon->vendor_vht_ie.VHTCaps.present) {
5682 qdf_mem_copy(&pBeaconStruct->vendor_vht_ie.VHTCaps,
5683 &pBeacon->vendor_vht_ie.VHTCaps,
5684 sizeof(tDot11fIEVHTCaps));
5685 }
5686 if (pBeacon->vendor_vht_ie.VHTOperation.present) {
5687 qdf_mem_copy(&pBeaconStruct->vendor_vht_ie.VHTOperation,
5688 &pBeacon->VHTOperation,
5689 sizeof(tDot11fIEVHTOperation));
5690 }
5691 /* Update HS 2.0 Information Element */
5692 if (pBeacon->hs20vendor_ie.present) {
5693 qdf_mem_copy(&pBeaconStruct->hs20vendor_ie,
5694 &pBeacon->hs20vendor_ie,
5695 sizeof(tDot11fIEhs20vendor_ie) -
5696 sizeof(pBeacon->hs20vendor_ie.hs_id));
5697 if (pBeacon->hs20vendor_ie.hs_id_present)
5698 qdf_mem_copy(&pBeaconStruct->hs20vendor_ie.hs_id,
5699 &pBeacon->hs20vendor_ie.hs_id,
5700 sizeof(pBeacon->hs20vendor_ie.hs_id));
5701 }
5702 #ifdef FEATURE_AP_MCC_CH_AVOIDANCE
5703 if (pBeacon->QComVendorIE.present) {
5704 pBeaconStruct->AvoidChannelIE.present =
5705 pBeacon->QComVendorIE.present;
5706 pBeaconStruct->AvoidChannelIE.type =
5707 pBeacon->QComVendorIE.type;
5708 pBeaconStruct->AvoidChannelIE.channel =
5709 pBeacon->QComVendorIE.channel;
5710 }
5711 #endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
5712 if (pBeacon->OBSSScanParameters.present) {
5713 qdf_mem_copy(&pBeaconStruct->obss_scanparams,
5714 &pBeacon->OBSSScanParameters,
5715 sizeof(struct sDot11fIEOBSSScanParameters));
5716 }
5717 if (pBeacon->MBO_IE.present) {
5718 pBeaconStruct->MBO_IE_present = true;
5719 if (pBeacon->MBO_IE.cellular_data_cap.present)
5720 pBeaconStruct->MBO_capability =
5721 pBeacon->MBO_IE.cellular_data_cap.cellular_connectivity;
5722
5723 if (pBeacon->MBO_IE.assoc_disallowed.present) {
5724 pBeaconStruct->assoc_disallowed = true;
5725 pBeaconStruct->assoc_disallowed_reason =
5726 pBeacon->MBO_IE.assoc_disallowed.reason_code;
5727 }
5728 }
5729
5730 if (pBeacon->qcn_ie.present)
5731 qdf_mem_copy(&pBeaconStruct->qcn_ie, &pBeacon->qcn_ie,
5732 sizeof(tDot11fIEqcn_ie));
5733
5734 if (pBeacon->he_cap.present) {
5735 qdf_mem_copy(&pBeaconStruct->he_cap,
5736 &pBeacon->he_cap,
5737 sizeof(tDot11fIEhe_cap));
5738 }
5739 if (pBeacon->he_op.present) {
5740 qdf_mem_copy(&pBeaconStruct->he_op,
5741 &pBeacon->he_op,
5742 sizeof(tDot11fIEhe_op));
5743 }
5744
5745 if (pBeacon->eht_cap.present)
5746 qdf_mem_copy(&pBeaconStruct->eht_cap, &pBeacon->eht_cap,
5747 sizeof(tDot11fIEeht_cap));
5748 if (pBeacon->eht_op.present)
5749 qdf_mem_copy(&pBeaconStruct->eht_op, &pBeacon->eht_op,
5750 sizeof(tDot11fIEeht_op));
5751
5752 pBeaconStruct->num_transmit_power_env = pBeacon->num_transmit_power_env;
5753 if (pBeacon->num_transmit_power_env) {
5754 qdf_mem_copy(pBeaconStruct->transmit_power_env,
5755 pBeacon->transmit_power_env,
5756 pBeacon->num_transmit_power_env *
5757 sizeof(tDot11fIEtransmit_power_env));
5758 }
5759
5760 convert_bcon_bss_color_change_ie(pBeacon, pBeaconStruct);
5761 sir_convert_beacon_frame2_mlo_struct(pPayload, nPayload, pBeacon,
5762 pBeaconStruct);
5763 sir_convert_beacon_frame2_t2lm_struct(pBeacon, pBeaconStruct);
5764 sir_convert_beacon_frame2_sr_struct(pBeacon, pBeaconStruct);
5765
5766 qdf_mem_free(pBeacon);
5767 return QDF_STATUS_SUCCESS;
5768
5769 } /* End sir_convert_beacon_frame2_struct. */
5770
5771 #ifdef WLAN_FEATURE_FILS_SK
5772
5773 /* update_ftie_in_fils_conf() - API to update fils info from auth
5774 * response packet from AP
5775 * @auth: auth packet pointer received from AP
5776 * @auth_frame: data structure needs to be updated
5777 *
5778 * Return: None
5779 */
5780 static void
5781 update_ftie_in_fils_conf(tDot11fAuthentication *auth,
5782 tpSirMacAuthFrameBody auth_frame)
5783 {
5784 /**
5785 * Copy the FTIE sent by the AP in the auth request frame.
5786 * This is required for FT-FILS connection.
5787 * This FTIE will be sent in Assoc request frame without
5788 * any modification.
5789 */
5790 if (auth->FTInfo.present) {
5791 pe_debug("FT-FILS: r0kh_len:%d r1kh_present:%d",
5792 auth->FTInfo.R0KH_ID.num_PMK_R0_ID,
5793 auth->FTInfo.R1KH_ID.present);
5794
5795 auth_frame->ft_ie.present = 1;
5796 if (auth->FTInfo.R1KH_ID.present) {
5797 qdf_mem_copy(auth_frame->ft_ie.r1kh_id,
5798 auth->FTInfo.R1KH_ID.PMK_R1_ID,
5799 FT_R1KH_ID_LEN);
5800 }
5801
5802 if (auth->FTInfo.R0KH_ID.present) {
5803 qdf_mem_copy(auth_frame->ft_ie.r0kh_id,
5804 auth->FTInfo.R0KH_ID.PMK_R0_ID,
5805 auth->FTInfo.R0KH_ID.num_PMK_R0_ID);
5806 auth_frame->ft_ie.r0kh_id_len =
5807 auth->FTInfo.R0KH_ID.num_PMK_R0_ID;
5808 }
5809
5810 if (auth_frame->ft_ie.gtk_ie.present) {
5811 pe_debug("FT-FILS: GTK present");
5812 qdf_mem_copy(&auth_frame->ft_ie.gtk_ie,
5813 &auth->FTInfo.GTK,
5814 sizeof(struct mac_ft_gtk_ie));
5815 }
5816
5817 if (auth_frame->ft_ie.igtk_ie.present) {
5818 pe_debug("FT-FILS: IGTK present");
5819 qdf_mem_copy(&auth_frame->ft_ie.igtk_ie,
5820 &auth->FTInfo.IGTK,
5821 sizeof(struct mac_ft_igtk_ie));
5822 }
5823
5824 qdf_mem_copy(auth_frame->ft_ie.anonce, auth->FTInfo.Anonce,
5825 FT_NONCE_LEN);
5826 qdf_mem_copy(auth_frame->ft_ie.snonce, auth->FTInfo.Snonce,
5827 FT_NONCE_LEN);
5828
5829 qdf_mem_copy(auth_frame->ft_ie.mic, auth->FTInfo.MIC,
5830 FT_MIC_LEN);
5831 auth_frame->ft_ie.element_count = auth->FTInfo.IECount;
5832 }
5833 }
5834
5835 /* sir_update_auth_frame2_struct_fils_conf: API to update fils info from auth
5836 * packet type 2
5837 * @auth: auth packet pointer received from AP
5838 * @auth_frame: data structure needs to be updated
5839 *
5840 * Return: None
5841 */
5842 static void
5843 sir_update_auth_frame2_struct_fils_conf(tDot11fAuthentication *auth,
5844 tpSirMacAuthFrameBody auth_frame)
5845 {
5846 if (auth->AuthAlgo.algo != SIR_FILS_SK_WITHOUT_PFS)
5847 return;
5848
5849 if (auth->fils_assoc_delay_info.present)
5850 auth_frame->assoc_delay_info =
5851 auth->fils_assoc_delay_info.assoc_delay_info;
5852
5853 if (auth->fils_session.present)
5854 qdf_mem_copy(auth_frame->session, auth->fils_session.session,
5855 SIR_FILS_SESSION_LENGTH);
5856
5857 if (auth->fils_nonce.present)
5858 qdf_mem_copy(auth_frame->nonce, auth->fils_nonce.nonce,
5859 SIR_FILS_NONCE_LENGTH);
5860
5861 if (auth->fils_wrapped_data.present) {
5862 qdf_mem_copy(auth_frame->wrapped_data,
5863 auth->fils_wrapped_data.wrapped_data,
5864 auth->fils_wrapped_data.num_wrapped_data);
5865 auth_frame->wrapped_data_len =
5866 auth->fils_wrapped_data.num_wrapped_data;
5867 }
5868 if (auth->RSNOpaque.present) {
5869 qdf_mem_copy(auth_frame->rsn_ie.info, auth->RSNOpaque.data,
5870 auth->RSNOpaque.num_data);
5871 auth_frame->rsn_ie.length = auth->RSNOpaque.num_data;
5872 }
5873
5874 update_ftie_in_fils_conf(auth, auth_frame);
5875
5876 }
5877 #else
5878 static void sir_update_auth_frame2_struct_fils_conf(tDot11fAuthentication *auth,
5879 tpSirMacAuthFrameBody auth_frame)
5880 { }
5881 #endif
5882
5883 QDF_STATUS
5884 sir_convert_auth_frame2_struct(struct mac_context *mac,
5885 uint8_t *pFrame,
5886 uint32_t nFrame, tpSirMacAuthFrameBody pAuth)
5887 {
5888 static tDot11fAuthentication auth;
5889 uint32_t status;
5890
5891 /* Zero-init our [out] parameter, */
5892 qdf_mem_zero((uint8_t *) pAuth, sizeof(tSirMacAuthFrameBody));
5893
5894 /* delegate to the framesc-generated code, */
5895 status = dot11f_unpack_authentication(mac, pFrame, nFrame,
5896 &auth, false);
5897 if (DOT11F_FAILED(status)) {
5898 pe_err("Failed to parse an Authentication frame (0x%08x, %d bytes):",
5899 status, nFrame);
5900 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_ERROR,
5901 pFrame, nFrame);
5902 return QDF_STATUS_E_FAILURE;
5903 } else if (DOT11F_WARNED(status)) {
5904 pe_debug("There were warnings while unpacking an Authentication frame (0x%08x, %d bytes):",
5905 status, nFrame);
5906 }
5907 /* & "transliterate" from a 'tDot11fAuthentication' to a 'tSirMacAuthFrameBody'... */
5908 pAuth->authAlgoNumber = auth.AuthAlgo.algo;
5909 pAuth->authTransactionSeqNumber = auth.AuthSeqNo.no;
5910 pAuth->authStatusCode = auth.Status.status;
5911
5912 if (auth.ChallengeText.present) {
5913 pAuth->type = WLAN_ELEMID_CHALLENGE;
5914 pAuth->length = auth.ChallengeText.num_text;
5915 qdf_mem_copy(pAuth->challengeText, auth.ChallengeText.text,
5916 auth.ChallengeText.num_text);
5917 }
5918
5919 /* Copy MLO IE presence flag to pAuth in case of ML connection */
5920 pAuth->is_mlo_ie_present = auth.mlo_ie.present;
5921 /* The minimum length is set to 9 based on below calculation
5922 * Multi-Link Control Field => 2 Bytes
5923 * Minimum CInfo Field => CInfo Length (1 Byte) + MLD Addr (6 Bytes)
5924 * min_len = 2 + 1 + 6
5925 * MLD Offset = min_len - (2 + 1)
5926 */
5927 if (pAuth->is_mlo_ie_present && auth.mlo_ie.num_data >= 9) {
5928 qdf_copy_macaddr(&pAuth->peer_mld,
5929 (struct qdf_mac_addr *)(auth.mlo_ie.data + 3));
5930 }
5931
5932 sir_update_auth_frame2_struct_fils_conf(&auth, pAuth);
5933
5934 return QDF_STATUS_SUCCESS;
5935
5936 } /* End sir_convert_auth_frame2_struct. */
5937
5938 QDF_STATUS
5939 sir_convert_addts_rsp2_struct(struct mac_context *mac,
5940 uint8_t *pFrame,
5941 uint32_t nFrame, tSirAddtsRspInfo *pAddTs)
5942 {
5943 tDot11fAddTSResponse addts = { {0} };
5944 tDot11fWMMAddTSResponse wmmaddts = { {0} };
5945 uint8_t j;
5946 uint16_t i;
5947 uint32_t status;
5948
5949 if (QOS_ADD_TS_RSP != *(pFrame + 1)) {
5950 pe_err("Action of %d; this is not supported & is probably an error",
5951 *(pFrame + 1));
5952 return QDF_STATUS_E_FAILURE;
5953 }
5954 /* Zero-init our [out] parameter, */
5955 qdf_mem_zero((uint8_t *) pAddTs, sizeof(tSirAddtsRspInfo));
5956 qdf_mem_zero((uint8_t *) &addts, sizeof(tDot11fAddTSResponse));
5957 qdf_mem_zero((uint8_t *) &wmmaddts, sizeof(tDot11fWMMAddTSResponse));
5958
5959 /* delegate to the framesc-generated code, */
5960 switch (*pFrame) {
5961 case ACTION_CATEGORY_QOS:
5962 status =
5963 dot11f_unpack_add_ts_response(mac, pFrame, nFrame,
5964 &addts, false);
5965 break;
5966 case ACTION_CATEGORY_WMM:
5967 status =
5968 dot11f_unpack_wmm_add_ts_response(mac, pFrame, nFrame,
5969 &wmmaddts, false);
5970 break;
5971 default:
5972 pe_err("Category of %d; this is not supported & is probably an error",
5973 *pFrame);
5974 return QDF_STATUS_E_FAILURE;
5975 }
5976
5977 if (DOT11F_FAILED(status)) {
5978 pe_err("Failed to parse an Add TS Response frame (0x%08x, %d bytes):",
5979 status, nFrame);
5980 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_ERROR,
5981 pFrame, nFrame);
5982 return QDF_STATUS_E_FAILURE;
5983 } else if (DOT11F_WARNED(status)) {
5984 pe_debug("There were warnings while unpacking an Add TS Response frame (0x%08x,%d bytes):",
5985 status, nFrame);
5986 }
5987 /* & "transliterate" from a 'tDot11fAddTSResponse' or a */
5988 /* 'tDot11WMMAddTSResponse' to a 'tSirMacAddtsRspInfo'... */
5989 if (ACTION_CATEGORY_QOS == *pFrame) {
5990 pAddTs->dialogToken = addts.DialogToken.token;
5991 pAddTs->status = (enum wlan_status_code)addts.Status.status;
5992
5993 if (addts.TSDelay.present) {
5994 convert_ts_delay(mac, &pAddTs->delay, &addts.TSDelay);
5995 }
5996 /* TS Delay is present iff status indicates its presence */
5997 if (pAddTs->status == STATUS_TS_NOT_CREATED &&
5998 !addts.TSDelay.present) {
5999 pe_warn("Missing TSDelay IE");
6000 }
6001
6002 if (addts.TSPEC.present) {
6003 convert_tspec(mac, &pAddTs->tspec, &addts.TSPEC);
6004 } else {
6005 pe_err("Mandatory TSPEC element missing in Add TS Response");
6006 return QDF_STATUS_E_FAILURE;
6007 }
6008
6009 if (addts.num_TCLAS) {
6010 pAddTs->numTclas = (uint8_t) addts.num_TCLAS;
6011
6012 for (i = 0U; i < addts.num_TCLAS; ++i) {
6013 if (QDF_STATUS_SUCCESS !=
6014 convert_tclas(mac, &(pAddTs->tclasInfo[i]),
6015 &(addts.TCLAS[i]))) {
6016 pe_err("Failed to convert a TCLAS IE");
6017 return QDF_STATUS_E_FAILURE;
6018 }
6019 }
6020 }
6021
6022 if (addts.TCLASSPROC.present) {
6023 pAddTs->tclasProcPresent = 1;
6024 pAddTs->tclasProc = addts.TCLASSPROC.processing;
6025 }
6026 #ifdef FEATURE_WLAN_ESE
6027 if (addts.ESETrafStrmMet.present) {
6028 pAddTs->tsmPresent = 1;
6029 qdf_mem_copy(&pAddTs->tsmIE.tsid,
6030 &addts.ESETrafStrmMet.tsid,
6031 sizeof(struct ese_tsm_ie));
6032 }
6033 #endif
6034 if (addts.Schedule.present) {
6035 pAddTs->schedulePresent = 1;
6036 convert_schedule(mac, &pAddTs->schedule,
6037 &addts.Schedule);
6038 }
6039
6040 if (addts.WMMSchedule.present) {
6041 pAddTs->schedulePresent = 1;
6042 convert_wmm_schedule(mac, &pAddTs->schedule,
6043 &addts.WMMSchedule);
6044 }
6045
6046 if (addts.WMMTSPEC.present) {
6047 pAddTs->wsmTspecPresent = 1;
6048 convert_wmmtspec(mac, &pAddTs->tspec, &addts.WMMTSPEC);
6049 }
6050
6051 if (addts.num_WMMTCLAS) {
6052 j = (uint8_t) (pAddTs->numTclas + addts.num_WMMTCLAS);
6053 if (SIR_MAC_TCLASIE_MAXNUM < j)
6054 j = SIR_MAC_TCLASIE_MAXNUM;
6055
6056 for (i = pAddTs->numTclas; i < j; ++i) {
6057 if (QDF_STATUS_SUCCESS !=
6058 convert_wmmtclas(mac,
6059 &(pAddTs->tclasInfo[i]),
6060 &(addts.WMMTCLAS[i]))) {
6061 pe_err("Failed to convert a TCLAS IE");
6062 return QDF_STATUS_E_FAILURE;
6063 }
6064 }
6065 }
6066
6067 if (addts.WMMTCLASPROC.present) {
6068 pAddTs->tclasProcPresent = 1;
6069 pAddTs->tclasProc = addts.WMMTCLASPROC.processing;
6070 }
6071
6072 if (1 < pAddTs->numTclas && (!pAddTs->tclasProcPresent)) {
6073 pe_err("%d TCLAS IE but not TCLASPROC IE",
6074 pAddTs->numTclas);
6075 return QDF_STATUS_E_FAILURE;
6076 }
6077 } else {
6078 pAddTs->dialogToken = wmmaddts.DialogToken.token;
6079 pAddTs->status =
6080 (enum wlan_status_code)wmmaddts.StatusCode.statusCode;
6081
6082 if (wmmaddts.WMMTSPEC.present) {
6083 pAddTs->wmeTspecPresent = 1;
6084 convert_wmmtspec(mac, &pAddTs->tspec,
6085 &wmmaddts.WMMTSPEC);
6086 } else {
6087 pe_err("Mandatory WME TSPEC element missing!");
6088 return QDF_STATUS_E_FAILURE;
6089 }
6090
6091 #ifdef FEATURE_WLAN_ESE
6092 if (wmmaddts.ESETrafStrmMet.present) {
6093 pAddTs->tsmPresent = 1;
6094 qdf_mem_copy(&pAddTs->tsmIE.tsid,
6095 &wmmaddts.ESETrafStrmMet.tsid,
6096 sizeof(struct ese_tsm_ie));
6097 }
6098 #endif
6099
6100 }
6101
6102 return QDF_STATUS_SUCCESS;
6103
6104 } /* End sir_convert_addts_rsp2_struct. */
6105
6106 QDF_STATUS
6107 sir_convert_delts_req2_struct(struct mac_context *mac,
6108 uint8_t *pFrame,
6109 uint32_t nFrame, struct delts_req_info *pDelTs)
6110 {
6111 tDot11fDelTS delts = { {0} };
6112 tDot11fWMMDelTS wmmdelts = { {0} };
6113 uint32_t status;
6114
6115 if (QOS_DEL_TS_REQ != *(pFrame + 1)) {
6116 pe_err("sirConvertDeltsRsp2Struct invoked "
6117 "with an Action of %d; this is not "
6118 "supported & is probably an error",
6119 *(pFrame + 1));
6120 return QDF_STATUS_E_FAILURE;
6121 }
6122 /* Zero-init our [out] parameter, */
6123 qdf_mem_zero(pDelTs, sizeof(*pDelTs));
6124
6125 /* delegate to the framesc-generated code, */
6126 switch (*pFrame) {
6127 case ACTION_CATEGORY_QOS:
6128 status = dot11f_unpack_del_ts(mac, pFrame, nFrame,
6129 &delts, false);
6130 break;
6131 case ACTION_CATEGORY_WMM:
6132 status = dot11f_unpack_wmm_del_ts(mac, pFrame, nFrame,
6133 &wmmdelts, false);
6134 break;
6135 default:
6136 pe_err("sirConvertDeltsRsp2Struct invoked "
6137 "with a Category of %d; this is not"
6138 " supported & is probably an error",
6139 *pFrame);
6140 return QDF_STATUS_E_FAILURE;
6141 }
6142
6143 if (DOT11F_FAILED(status)) {
6144 pe_err("Failed to parse an Del TS Request frame (0x%08x, %d bytes):",
6145 status, nFrame);
6146 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_ERROR,
6147 pFrame, nFrame);
6148 return QDF_STATUS_E_FAILURE;
6149 } else if (DOT11F_WARNED(status)) {
6150 pe_debug("There were warnings while unpacking an Del TS Request frame (0x%08x,%d bytes):",
6151 status, nFrame);
6152 }
6153 /* & "transliterate" from a 'tDot11fDelTSResponse' or a */
6154 /* 'tDot11WMMDelTSResponse' to a 'tSirMacDeltsReqInfo'... */
6155 if (ACTION_CATEGORY_QOS == *pFrame) {
6156 pDelTs->tsinfo.traffic.trafficType =
6157 (uint16_t) delts.TSInfo.traffic_type;
6158 pDelTs->tsinfo.traffic.tsid = (uint16_t) delts.TSInfo.tsid;
6159 pDelTs->tsinfo.traffic.direction =
6160 (uint16_t) delts.TSInfo.direction;
6161 pDelTs->tsinfo.traffic.accessPolicy =
6162 (uint16_t) delts.TSInfo.access_policy;
6163 pDelTs->tsinfo.traffic.aggregation =
6164 (uint16_t) delts.TSInfo.aggregation;
6165 pDelTs->tsinfo.traffic.psb = (uint16_t) delts.TSInfo.psb;
6166 pDelTs->tsinfo.traffic.userPrio =
6167 (uint16_t) delts.TSInfo.user_priority;
6168 pDelTs->tsinfo.traffic.ackPolicy =
6169 (uint16_t) delts.TSInfo.tsinfo_ack_pol;
6170
6171 pDelTs->tsinfo.schedule.schedule =
6172 (uint8_t) delts.TSInfo.schedule;
6173 } else {
6174 if (wmmdelts.WMMTSPEC.present) {
6175 pDelTs->wmeTspecPresent = 1;
6176 convert_wmmtspec(mac, &pDelTs->tspec,
6177 &wmmdelts.WMMTSPEC);
6178 } else {
6179 pe_err("Mandatory WME TSPEC element missing!");
6180 return QDF_STATUS_E_FAILURE;
6181 }
6182 }
6183
6184 return QDF_STATUS_SUCCESS;
6185
6186 } /* End sir_convert_delts_req2_struct. */
6187
6188 QDF_STATUS
6189 sir_convert_qos_map_configure_frame2_struct(struct mac_context *mac,
6190 uint8_t *pFrame,
6191 uint32_t nFrame,
6192 struct qos_map_set *pQosMapSet)
6193 {
6194 tDot11fQosMapConfigure mapConfigure;
6195 uint32_t status;
6196
6197 status =
6198 dot11f_unpack_qos_map_configure(mac, pFrame, nFrame,
6199 &mapConfigure, false);
6200 if (DOT11F_FAILED(status) || !mapConfigure.QosMapSet.present) {
6201 pe_err("Failed to parse Qos Map Configure frame (0x%08x, %d bytes):",
6202 status, nFrame);
6203 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_ERROR,
6204 pFrame, nFrame);
6205 return QDF_STATUS_E_FAILURE;
6206 } else if (DOT11F_WARNED(status)) {
6207 pe_debug("There were warnings while unpacking Qos Map Configure frame (0x%08x, %d bytes):",
6208 status, nFrame);
6209 }
6210 pQosMapSet->present = mapConfigure.QosMapSet.present;
6211 convert_qos_mapset_frame(mac, pQosMapSet, &mapConfigure.QosMapSet);
6212 lim_log_qos_map_set(mac, pQosMapSet);
6213 return QDF_STATUS_SUCCESS;
6214 }
6215
6216 #ifdef ANI_SUPPORT_11H
6217 QDF_STATUS
6218 sir_convert_tpc_req_frame2_struct(struct mac_context *mac,
6219 uint8_t *pFrame,
6220 tpSirMacTpcReqActionFrame pTpcReqFrame,
6221 uint32_t nFrame)
6222 {
6223 tDot11fTPCRequest req;
6224 uint32_t status;
6225
6226 qdf_mem_zero((uint8_t *) pTpcReqFrame,
6227 sizeof(tSirMacTpcReqActionFrame));
6228 status = dot11f_unpack_tpc_request(mac, pFrame, nFrame, &req, false);
6229 if (DOT11F_FAILED(status)) {
6230 pe_err("Failed to parse a TPC Request frame (0x%08x, %d bytes):",
6231 status, nFrame);
6232 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_ERROR,
6233 pFrame, nFrame);
6234 return QDF_STATUS_E_FAILURE;
6235 } else if (DOT11F_WARNED(status)) {
6236 pe_debug("There were warnings while unpacking a TPC Request frame (0x%08x, %d bytes):",
6237 status, nFrame);
6238 }
6239 /* & "transliterate" from a 'tDot11fTPCRequest' to a */
6240 /* 'tSirMacTpcReqActionFrame'... */
6241 pTpcReqFrame->actionHeader.category = req.Category.category;
6242 pTpcReqFrame->actionHeader.actionID = req.Action.action;
6243 pTpcReqFrame->actionHeader.dialogToken = req.DialogToken.token;
6244 if (req.TPCRequest.present) {
6245 pTpcReqFrame->type = DOT11F_EID_TPCREQUEST;
6246 pTpcReqFrame->length = 0;
6247 } else {
6248 pe_warn("!!!Rcv TPC Req of invalid type!");
6249 return QDF_STATUS_E_FAILURE;
6250 }
6251 return QDF_STATUS_SUCCESS;
6252 } /* End sir_convert_tpc_req_frame2_struct. */
6253 QDF_STATUS
6254 sir_convert_meas_req_frame2_struct(struct mac_context *mac,
6255 uint8_t *pFrame,
6256 tpSirMacMeasReqActionFrame pMeasReqFrame,
6257 uint32_t nFrame)
6258 {
6259 tDot11fMeasurementRequest mr;
6260 uint32_t status;
6261
6262 /* Zero-init our [out] parameter, */
6263 qdf_mem_zero((uint8_t *) pMeasReqFrame,
6264 sizeof(tpSirMacMeasReqActionFrame));
6265
6266 /* delegate to the framesc-generated code, */
6267 status = dot11f_unpack_measurement_request(mac, pFrame,
6268 nFrame, &mr, false);
6269 if (DOT11F_FAILED(status)) {
6270 pe_err("Failed to parse a Measurement Request frame (0x%08x, %d bytes):",
6271 status, nFrame);
6272 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_ERROR,
6273 pFrame, nFrame);
6274 return QDF_STATUS_E_FAILURE;
6275 } else if (DOT11F_WARNED(status)) {
6276 pe_debug("There were warnings while unpacking a Measurement Request frame (0x%08x, %d bytes):",
6277 status, nFrame);
6278 }
6279 /* & "transliterate" from a 'tDot11fMeasurementRequest' to a */
6280 /* 'tpSirMacMeasReqActionFrame'... */
6281 pMeasReqFrame->actionHeader.category = mr.Category.category;
6282 pMeasReqFrame->actionHeader.actionID = mr.Action.action;
6283 pMeasReqFrame->actionHeader.dialogToken = mr.DialogToken.token;
6284
6285 if (0 == mr.num_MeasurementRequest) {
6286 pe_err("Missing mandatory IE in Measurement Request Frame");
6287 return QDF_STATUS_E_FAILURE;
6288 } else if (1 < mr.num_MeasurementRequest) {
6289 pe_warn(
6290 FL("Warning: dropping extra Measurement Request IEs!"));
6291 }
6292
6293 pMeasReqFrame->measReqIE.type = DOT11F_EID_MEASUREMENTREQUEST;
6294 pMeasReqFrame->measReqIE.length = DOT11F_IE_MEASUREMENTREQUEST_MIN_LEN;
6295 pMeasReqFrame->measReqIE.measToken =
6296 mr.MeasurementRequest[0].measurement_token;
6297 pMeasReqFrame->measReqIE.measReqMode =
6298 (mr.MeasurementRequest[0].reserved << 3) | (mr.
6299 MeasurementRequest[0].
6300 enable << 2) | (mr.
6301 MeasurementRequest
6302 [0].
6303 request
6304 << 1) |
6305 (mr.MeasurementRequest[0].report /*<< 0 */);
6306 pMeasReqFrame->measReqIE.measType =
6307 mr.MeasurementRequest[0].measurement_type;
6308
6309 pMeasReqFrame->measReqIE.measReqField.channelNumber =
6310 mr.MeasurementRequest[0].channel_no;
6311
6312 qdf_mem_copy(pMeasReqFrame->measReqIE.measReqField.measStartTime,
6313 mr.MeasurementRequest[0].meas_start_time, 8);
6314
6315 pMeasReqFrame->measReqIE.measReqField.measDuration =
6316 mr.MeasurementRequest[0].meas_duration;
6317
6318 return QDF_STATUS_SUCCESS;
6319
6320 } /* End sir_convert_meas_req_frame2_struct. */
6321 #endif
6322
6323 void populate_dot11f_tspec(struct mac_tspec_ie *pOld, tDot11fIETSPEC *pDot11f)
6324 {
6325 pDot11f->traffic_type = pOld->tsinfo.traffic.trafficType;
6326 pDot11f->tsid = pOld->tsinfo.traffic.tsid;
6327 pDot11f->direction = pOld->tsinfo.traffic.direction;
6328 pDot11f->access_policy = pOld->tsinfo.traffic.accessPolicy;
6329 pDot11f->aggregation = pOld->tsinfo.traffic.aggregation;
6330 pDot11f->psb = pOld->tsinfo.traffic.psb;
6331 pDot11f->user_priority = pOld->tsinfo.traffic.userPrio;
6332 pDot11f->tsinfo_ack_pol = pOld->tsinfo.traffic.ackPolicy;
6333 pDot11f->schedule = pOld->tsinfo.schedule.schedule;
6334 /* As defined in IEEE 802.11-2007, section 7.3.2.30
6335 * Nominal MSDU size: Bit[0:14]=Size, Bit[15]=Fixed
6336 */
6337 pDot11f->size = (pOld->nomMsduSz & 0x7fff);
6338 pDot11f->fixed = (pOld->nomMsduSz & 0x8000) ? 1 : 0;
6339 pDot11f->max_msdu_size = pOld->maxMsduSz;
6340 pDot11f->min_service_int = pOld->minSvcInterval;
6341 pDot11f->max_service_int = pOld->maxSvcInterval;
6342 pDot11f->inactivity_int = pOld->inactInterval;
6343 pDot11f->suspension_int = pOld->suspendInterval;
6344 pDot11f->service_start_time = pOld->svcStartTime;
6345 pDot11f->min_data_rate = pOld->minDataRate;
6346 pDot11f->mean_data_rate = pOld->meanDataRate;
6347 pDot11f->peak_data_rate = pOld->peakDataRate;
6348 pDot11f->burst_size = pOld->maxBurstSz;
6349 pDot11f->delay_bound = pOld->delayBound;
6350 pDot11f->min_phy_rate = pOld->minPhyRate;
6351 pDot11f->surplus_bw_allowance = pOld->surplusBw;
6352 pDot11f->medium_time = pOld->mediumTime;
6353
6354 pDot11f->present = 1;
6355
6356 } /* End populate_dot11f_tspec. */
6357
6358 #ifdef WLAN_FEATURE_MSCS
6359 void
6360 populate_dot11f_mscs_dec_element(struct mscs_req_info *mscs_req,
6361 tDot11fmscs_request_action_frame *dot11f)
6362 {
6363 dot11f->descriptor_element.request_type =
6364 mscs_req->dec.request_type;
6365 dot11f->descriptor_element.user_priority_control =
6366 mscs_req->dec.user_priority_control;
6367 dot11f->descriptor_element.stream_timeout =
6368 mscs_req->dec.stream_timeout;
6369 dot11f->descriptor_element.tclas_mask.classifier_type =
6370 mscs_req->dec.tclas_mask.classifier_type;
6371 dot11f->descriptor_element.tclas_mask.classifier_mask =
6372 mscs_req->dec.tclas_mask.classifier_mask;
6373
6374 dot11f->descriptor_element.present = 1;
6375 dot11f->descriptor_element.tclas_mask.present = 1;
6376
6377 } /* End populate_dot11f_descriptor_element */
6378 #endif
6379
6380 void populate_dot11f_wmmtspec(struct mac_tspec_ie *pOld,
6381 tDot11fIEWMMTSPEC *pDot11f)
6382 {
6383 pDot11f->traffic_type = pOld->tsinfo.traffic.trafficType;
6384 pDot11f->tsid = pOld->tsinfo.traffic.tsid;
6385 pDot11f->direction = pOld->tsinfo.traffic.direction;
6386 pDot11f->access_policy = pOld->tsinfo.traffic.accessPolicy;
6387 pDot11f->aggregation = pOld->tsinfo.traffic.aggregation;
6388 pDot11f->psb = pOld->tsinfo.traffic.psb;
6389 pDot11f->user_priority = pOld->tsinfo.traffic.userPrio;
6390 pDot11f->tsinfo_ack_pol = pOld->tsinfo.traffic.ackPolicy;
6391 pDot11f->burst_size_defn = pOld->tsinfo.traffic.burstSizeDefn;
6392 /* As defined in IEEE 802.11-2007, section 7.3.2.30
6393 * Nominal MSDU size: Bit[0:14]=Size, Bit[15]=Fixed
6394 */
6395 pDot11f->size = (pOld->nomMsduSz & 0x7fff);
6396 pDot11f->fixed = (pOld->nomMsduSz & 0x8000) ? 1 : 0;
6397 pDot11f->max_msdu_size = pOld->maxMsduSz;
6398 pDot11f->min_service_int = pOld->minSvcInterval;
6399 pDot11f->max_service_int = pOld->maxSvcInterval;
6400 pDot11f->inactivity_int = pOld->inactInterval;
6401 pDot11f->suspension_int = pOld->suspendInterval;
6402 pDot11f->service_start_time = pOld->svcStartTime;
6403 pDot11f->min_data_rate = pOld->minDataRate;
6404 pDot11f->mean_data_rate = pOld->meanDataRate;
6405 pDot11f->peak_data_rate = pOld->peakDataRate;
6406 pDot11f->burst_size = pOld->maxBurstSz;
6407 pDot11f->delay_bound = pOld->delayBound;
6408 pDot11f->min_phy_rate = pOld->minPhyRate;
6409 pDot11f->surplus_bw_allowance = pOld->surplusBw;
6410 pDot11f->medium_time = pOld->mediumTime;
6411
6412 pDot11f->version = 1;
6413 pDot11f->present = 1;
6414
6415 } /* End populate_dot11f_wmmtspec. */
6416
6417 #if defined(FEATURE_WLAN_ESE)
6418 /* Fill the ESE version currently supported */
6419 void populate_dot11f_ese_version(tDot11fIEESEVersion *pESEVersion)
6420 {
6421 pESEVersion->present = 1;
6422 pESEVersion->version = ESE_VERSION_SUPPORTED;
6423 }
6424
6425 /* Fill the ESE ie for the station. */
6426 /* The State is Normal (1) */
6427 /* The MBSSID for station is set to 0. */
6428 void populate_dot11f_ese_rad_mgmt_cap(tDot11fIEESERadMgmtCap *pESERadMgmtCap)
6429 {
6430 pESERadMgmtCap->present = 1;
6431 pESERadMgmtCap->mgmt_state = RM_STATE_NORMAL;
6432 pESERadMgmtCap->mbssid_mask = 0;
6433 pESERadMgmtCap->reserved = 0;
6434 }
6435
6436 QDF_STATUS
6437 populate_dot11f_ese_cckm_opaque(struct mac_context *mac,
6438 struct mlme_connect_info *connect_info,
6439 tDot11fIEESECckmOpaque *pDot11f)
6440 {
6441 int idx;
6442 tSirRSNie ie;
6443
6444 if (connect_info->cckm_ie_len &&
6445 connect_info->cckm_ie_len < DOT11F_IE_RSN_MAX_LEN) {
6446 qdf_mem_copy(ie.rsnIEdata, connect_info->cckm_ie,
6447 connect_info->cckm_ie_len);
6448 ie.length = connect_info->cckm_ie_len;
6449 idx = find_ie_location(mac, &ie, DOT11F_EID_ESECCKMOPAQUE);
6450 if (idx >= 0) {
6451 pDot11f->present = 1;
6452 /* Dont include OUI */
6453 pDot11f->num_data = ie.rsnIEdata[idx + 1] - 4;
6454 qdf_mem_copy(pDot11f->data, ie.rsnIEdata + idx + 2 + 4, /* EID,len,OUI */
6455 ie.rsnIEdata[idx + 1] - 4); /* Skip OUI */
6456 }
6457 }
6458 return QDF_STATUS_SUCCESS;
6459 } /* End populate_dot11f_ese_cckm_opaque. */
6460
6461 void populate_dot11_tsrsie(struct mac_context *mac,
6462 struct ese_tsrs_ie *pOld,
6463 tDot11fIEESETrafStrmRateSet *pDot11f,
6464 uint8_t rate_length)
6465 {
6466 pDot11f->tsid = pOld->tsid;
6467 qdf_mem_copy(pDot11f->tsrates, pOld->rates, rate_length);
6468 pDot11f->num_tsrates = rate_length;
6469 pDot11f->present = 1;
6470 }
6471 #endif
6472
6473 QDF_STATUS
6474 populate_dot11f_tclas(struct mac_context *mac,
6475 tSirTclasInfo *pOld, tDot11fIETCLAS *pDot11f)
6476 {
6477 pDot11f->user_priority = pOld->tclas.userPrio;
6478 pDot11f->classifier_type = pOld->tclas.classifierType;
6479 pDot11f->classifier_mask = pOld->tclas.classifierMask;
6480
6481 switch (pDot11f->classifier_type) {
6482 case SIR_MAC_TCLASTYPE_ETHERNET:
6483 qdf_mem_copy((uint8_t *) &pDot11f->info.EthParams.source,
6484 (uint8_t *) &pOld->tclasParams.eth.srcAddr, 6);
6485 qdf_mem_copy((uint8_t *) &pDot11f->info.EthParams.dest,
6486 (uint8_t *) &pOld->tclasParams.eth.dstAddr, 6);
6487 pDot11f->info.EthParams.type = pOld->tclasParams.eth.type;
6488 break;
6489 case SIR_MAC_TCLASTYPE_TCPUDPIP:
6490 pDot11f->info.IpParams.version = pOld->version;
6491 if (SIR_MAC_TCLAS_IPV4 == pDot11f->info.IpParams.version) {
6492 qdf_mem_copy(pDot11f->info.IpParams.params.IpV4Params.
6493 source, pOld->tclasParams.ipv4.srcIpAddr,
6494 4);
6495 qdf_mem_copy(pDot11f->info.IpParams.params.IpV4Params.
6496 dest, pOld->tclasParams.ipv4.dstIpAddr, 4);
6497 pDot11f->info.IpParams.params.IpV4Params.src_port =
6498 pOld->tclasParams.ipv4.srcPort;
6499 pDot11f->info.IpParams.params.IpV4Params.dest_port =
6500 pOld->tclasParams.ipv4.dstPort;
6501 pDot11f->info.IpParams.params.IpV4Params.DSCP =
6502 pOld->tclasParams.ipv4.dscp;
6503 pDot11f->info.IpParams.params.IpV4Params.proto =
6504 pOld->tclasParams.ipv4.protocol;
6505 pDot11f->info.IpParams.params.IpV4Params.reserved =
6506 pOld->tclasParams.ipv4.rsvd;
6507 } else {
6508 qdf_mem_copy((uint8_t *) &pDot11f->info.IpParams.
6509 params.IpV6Params.source,
6510 (uint8_t *) pOld->tclasParams.ipv6.
6511 srcIpAddr, 16);
6512 qdf_mem_copy((uint8_t *) &pDot11f->info.IpParams.
6513 params.IpV6Params.dest,
6514 (uint8_t *) pOld->tclasParams.ipv6.
6515 dstIpAddr, 16);
6516 pDot11f->info.IpParams.params.IpV6Params.src_port =
6517 pOld->tclasParams.ipv6.srcPort;
6518 pDot11f->info.IpParams.params.IpV6Params.dest_port =
6519 pOld->tclasParams.ipv6.dstPort;
6520 qdf_mem_copy((uint8_t *) &pDot11f->info.IpParams.
6521 params.IpV6Params.flow_label,
6522 (uint8_t *) pOld->tclasParams.ipv6.
6523 flowLabel, 3);
6524 }
6525 break;
6526 case SIR_MAC_TCLASTYPE_8021DQ:
6527 pDot11f->info.Params8021dq.tag_type =
6528 pOld->tclasParams.t8021dq.tag;
6529 break;
6530 default:
6531 pe_err("Bad TCLAS type %d", pDot11f->classifier_type);
6532 return QDF_STATUS_E_FAILURE;
6533 }
6534
6535 pDot11f->present = 1;
6536
6537 return QDF_STATUS_SUCCESS;
6538
6539 } /* End populate_dot11f_tclas. */
6540
6541 QDF_STATUS
6542 populate_dot11f_wmmtclas(struct mac_context *mac,
6543 tSirTclasInfo *pOld, tDot11fIEWMMTCLAS *pDot11f)
6544 {
6545 pDot11f->version = 1;
6546 pDot11f->user_priority = pOld->tclas.userPrio;
6547 pDot11f->classifier_type = pOld->tclas.classifierType;
6548 pDot11f->classifier_mask = pOld->tclas.classifierMask;
6549
6550 switch (pDot11f->classifier_type) {
6551 case SIR_MAC_TCLASTYPE_ETHERNET:
6552 qdf_mem_copy((uint8_t *) &pDot11f->info.EthParams.source,
6553 (uint8_t *) &pOld->tclasParams.eth.srcAddr, 6);
6554 qdf_mem_copy((uint8_t *) &pDot11f->info.EthParams.dest,
6555 (uint8_t *) &pOld->tclasParams.eth.dstAddr, 6);
6556 pDot11f->info.EthParams.type = pOld->tclasParams.eth.type;
6557 break;
6558 case SIR_MAC_TCLASTYPE_TCPUDPIP:
6559 pDot11f->info.IpParams.version = pOld->version;
6560 if (SIR_MAC_TCLAS_IPV4 == pDot11f->info.IpParams.version) {
6561 qdf_mem_copy((uint8_t *) &pDot11f->info.IpParams.
6562 params.IpV4Params.source,
6563 (uint8_t *) pOld->tclasParams.ipv4.
6564 srcIpAddr, 4);
6565 qdf_mem_copy((uint8_t *) &pDot11f->info.IpParams.
6566 params.IpV4Params.dest,
6567 (uint8_t *) pOld->tclasParams.ipv4.
6568 dstIpAddr, 4);
6569 pDot11f->info.IpParams.params.IpV4Params.src_port =
6570 pOld->tclasParams.ipv4.srcPort;
6571 pDot11f->info.IpParams.params.IpV4Params.dest_port =
6572 pOld->tclasParams.ipv4.dstPort;
6573 pDot11f->info.IpParams.params.IpV4Params.DSCP =
6574 pOld->tclasParams.ipv4.dscp;
6575 pDot11f->info.IpParams.params.IpV4Params.proto =
6576 pOld->tclasParams.ipv4.protocol;
6577 pDot11f->info.IpParams.params.IpV4Params.reserved =
6578 pOld->tclasParams.ipv4.rsvd;
6579 } else {
6580 qdf_mem_copy((uint8_t *) &pDot11f->info.IpParams.
6581 params.IpV6Params.source,
6582 (uint8_t *) pOld->tclasParams.ipv6.
6583 srcIpAddr, 16);
6584 qdf_mem_copy((uint8_t *) &pDot11f->info.IpParams.
6585 params.IpV6Params.dest,
6586 (uint8_t *) pOld->tclasParams.ipv6.
6587 dstIpAddr, 16);
6588 pDot11f->info.IpParams.params.IpV6Params.src_port =
6589 pOld->tclasParams.ipv6.srcPort;
6590 pDot11f->info.IpParams.params.IpV6Params.dest_port =
6591 pOld->tclasParams.ipv6.dstPort;
6592 qdf_mem_copy((uint8_t *) &pDot11f->info.IpParams.
6593 params.IpV6Params.flow_label,
6594 (uint8_t *) pOld->tclasParams.ipv6.
6595 flowLabel, 3);
6596 }
6597 break;
6598 case SIR_MAC_TCLASTYPE_8021DQ:
6599 pDot11f->info.Params8021dq.tag_type =
6600 pOld->tclasParams.t8021dq.tag;
6601 break;
6602 default:
6603 pe_err("Bad TCLAS type %d in populate_dot11f_tclas",
6604 pDot11f->classifier_type);
6605 return QDF_STATUS_E_FAILURE;
6606 }
6607
6608 pDot11f->present = 1;
6609
6610 return QDF_STATUS_SUCCESS;
6611
6612 } /* End populate_dot11f_wmmtclas. */
6613
6614 QDF_STATUS populate_dot11f_wsc(struct mac_context *mac,
6615 tDot11fIEWscBeacon *pDot11f)
6616 {
6617
6618 uint32_t wpsState;
6619
6620 pDot11f->Version.present = 1;
6621 pDot11f->Version.major = 0x01;
6622 pDot11f->Version.minor = 0x00;
6623
6624 wpsState = mac->mlme_cfg->wps_params.wps_state;
6625
6626 pDot11f->WPSState.present = 1;
6627 pDot11f->WPSState.state = (uint8_t) wpsState;
6628
6629 pDot11f->APSetupLocked.present = 0;
6630
6631 pDot11f->SelectedRegistrar.present = 0;
6632
6633 pDot11f->DevicePasswordID.present = 0;
6634
6635 pDot11f->SelectedRegistrarConfigMethods.present = 0;
6636
6637 pDot11f->UUID_E.present = 0;
6638
6639 pDot11f->RFBands.present = 0;
6640
6641 pDot11f->present = 1;
6642 return QDF_STATUS_SUCCESS;
6643 }
6644
6645 QDF_STATUS populate_dot11f_wsc_registrar_info(struct mac_context *mac,
6646 tDot11fIEWscBeacon *pDot11f)
6647 {
6648 const struct sLimWscIeInfo *const pWscIeInfo = &(mac->lim.wscIeInfo);
6649
6650 pDot11f->APSetupLocked.present = 1;
6651 pDot11f->APSetupLocked.fLocked = pWscIeInfo->apSetupLocked;
6652
6653 pDot11f->SelectedRegistrar.present = 1;
6654 pDot11f->SelectedRegistrar.selected = pWscIeInfo->selectedRegistrar;
6655
6656 pDot11f->DevicePasswordID.present = 1;
6657 pDot11f->DevicePasswordID.id =
6658 (uint16_t)mac->mlme_cfg->wps_params.wps_device_password_id;
6659
6660 pDot11f->SelectedRegistrarConfigMethods.present = 1;
6661 pDot11f->SelectedRegistrarConfigMethods.methods =
6662 pWscIeInfo->selectedRegistrarConfigMethods;
6663
6664 /* UUID_E and RF Bands are applicable only for dual band AP */
6665
6666 return QDF_STATUS_SUCCESS;
6667 }
6668
6669 QDF_STATUS de_populate_dot11f_wsc_registrar_info(struct mac_context *mac,
6670 tDot11fIEWscBeacon *pDot11f)
6671 {
6672 pDot11f->APSetupLocked.present = 0;
6673 pDot11f->SelectedRegistrar.present = 0;
6674 pDot11f->DevicePasswordID.present = 0;
6675 pDot11f->SelectedRegistrarConfigMethods.present = 0;
6676
6677 return QDF_STATUS_SUCCESS;
6678 }
6679
6680 QDF_STATUS populate_dot11f_probe_res_wpsi_es(struct mac_context *mac,
6681 tDot11fIEWscProbeRes *pDot11f,
6682 struct pe_session *pe_session)
6683 {
6684
6685 tSirWPSProbeRspIE *pSirWPSProbeRspIE;
6686
6687 pSirWPSProbeRspIE = &pe_session->APWPSIEs.SirWPSProbeRspIE;
6688
6689 if (pSirWPSProbeRspIE->FieldPresent & SIR_WPS_PROBRSP_VER_PRESENT) {
6690 pDot11f->present = 1;
6691 pDot11f->Version.present = 1;
6692 pDot11f->Version.major =
6693 (uint8_t) ((pSirWPSProbeRspIE->Version & 0xF0) >> 4);
6694 pDot11f->Version.minor =
6695 (uint8_t) (pSirWPSProbeRspIE->Version & 0x0F);
6696 } else {
6697 pDot11f->present = 0;
6698 pDot11f->Version.present = 0;
6699 }
6700
6701 if (pSirWPSProbeRspIE->FieldPresent & SIR_WPS_PROBRSP_STATE_PRESENT) {
6702
6703 pDot11f->WPSState.present = 1;
6704 pDot11f->WPSState.state = (uint8_t) pSirWPSProbeRspIE->wpsState;
6705 } else
6706 pDot11f->WPSState.present = 0;
6707
6708 if (pSirWPSProbeRspIE->
6709 FieldPresent & SIR_WPS_PROBRSP_APSETUPLOCK_PRESENT) {
6710 pDot11f->APSetupLocked.present = 1;
6711 pDot11f->APSetupLocked.fLocked =
6712 pSirWPSProbeRspIE->APSetupLocked;
6713 } else
6714 pDot11f->APSetupLocked.present = 0;
6715
6716 if (pSirWPSProbeRspIE->
6717 FieldPresent & SIR_WPS_PROBRSP_SELECTEDREGISTRA_PRESENT) {
6718 pDot11f->SelectedRegistrar.present = 1;
6719 pDot11f->SelectedRegistrar.selected =
6720 pSirWPSProbeRspIE->SelectedRegistra;
6721 } else
6722 pDot11f->SelectedRegistrar.present = 0;
6723
6724 if (pSirWPSProbeRspIE->
6725 FieldPresent & SIR_WPS_PROBRSP_DEVICEPASSWORDID_PRESENT) {
6726 pDot11f->DevicePasswordID.present = 1;
6727 pDot11f->DevicePasswordID.id =
6728 pSirWPSProbeRspIE->DevicePasswordID;
6729 } else
6730 pDot11f->DevicePasswordID.present = 0;
6731
6732 if (pSirWPSProbeRspIE->
6733 FieldPresent & SIR_WPS_PROBRSP_SELECTEDREGISTRACFGMETHOD_PRESENT) {
6734 pDot11f->SelectedRegistrarConfigMethods.present = 1;
6735 pDot11f->SelectedRegistrarConfigMethods.methods =
6736 pSirWPSProbeRspIE->SelectedRegistraCfgMethod;
6737 } else
6738 pDot11f->SelectedRegistrarConfigMethods.present = 0;
6739
6740 if (pSirWPSProbeRspIE->
6741 FieldPresent & SIR_WPS_PROBRSP_RESPONSETYPE_PRESENT) {
6742 pDot11f->ResponseType.present = 1;
6743 pDot11f->ResponseType.resType = pSirWPSProbeRspIE->ResponseType;
6744 } else
6745 pDot11f->ResponseType.present = 0;
6746
6747 if (pSirWPSProbeRspIE->FieldPresent & SIR_WPS_PROBRSP_UUIDE_PRESENT) {
6748 pDot11f->UUID_E.present = 1;
6749 qdf_mem_copy(pDot11f->UUID_E.uuid, pSirWPSProbeRspIE->UUID_E,
6750 WNI_CFG_WPS_UUID_LEN);
6751 } else
6752 pDot11f->UUID_E.present = 0;
6753
6754 if (pSirWPSProbeRspIE->
6755 FieldPresent & SIR_WPS_PROBRSP_MANUFACTURE_PRESENT) {
6756 pDot11f->Manufacturer.present = 1;
6757 pDot11f->Manufacturer.num_name =
6758 pSirWPSProbeRspIE->Manufacture.num_name;
6759 qdf_mem_copy(pDot11f->Manufacturer.name,
6760 pSirWPSProbeRspIE->Manufacture.name,
6761 pSirWPSProbeRspIE->Manufacture.num_name);
6762 } else
6763 pDot11f->Manufacturer.present = 0;
6764
6765 if (pSirWPSProbeRspIE->
6766 FieldPresent & SIR_WPS_PROBRSP_MODELNUMBER_PRESENT) {
6767 pDot11f->ModelName.present = 1;
6768 pDot11f->ModelName.num_text =
6769 pSirWPSProbeRspIE->ModelName.num_text;
6770 qdf_mem_copy(pDot11f->ModelName.text,
6771 pSirWPSProbeRspIE->ModelName.text,
6772 pDot11f->ModelName.num_text);
6773 } else
6774 pDot11f->ModelName.present = 0;
6775
6776 if (pSirWPSProbeRspIE->
6777 FieldPresent & SIR_WPS_PROBRSP_MODELNUMBER_PRESENT) {
6778 pDot11f->ModelNumber.present = 1;
6779 pDot11f->ModelNumber.num_text =
6780 pSirWPSProbeRspIE->ModelNumber.num_text;
6781 qdf_mem_copy(pDot11f->ModelNumber.text,
6782 pSirWPSProbeRspIE->ModelNumber.text,
6783 pDot11f->ModelNumber.num_text);
6784 } else
6785 pDot11f->ModelNumber.present = 0;
6786
6787 if (pSirWPSProbeRspIE->
6788 FieldPresent & SIR_WPS_PROBRSP_SERIALNUMBER_PRESENT) {
6789 pDot11f->SerialNumber.present = 1;
6790 pDot11f->SerialNumber.num_text =
6791 pSirWPSProbeRspIE->SerialNumber.num_text;
6792 qdf_mem_copy(pDot11f->SerialNumber.text,
6793 pSirWPSProbeRspIE->SerialNumber.text,
6794 pDot11f->SerialNumber.num_text);
6795 } else
6796 pDot11f->SerialNumber.present = 0;
6797
6798 if (pSirWPSProbeRspIE->
6799 FieldPresent & SIR_WPS_PROBRSP_PRIMARYDEVICETYPE_PRESENT) {
6800 pDot11f->PrimaryDeviceType.present = 1;
6801 qdf_mem_copy(pDot11f->PrimaryDeviceType.oui,
6802 pSirWPSProbeRspIE->PrimaryDeviceOUI,
6803 sizeof(pSirWPSProbeRspIE->PrimaryDeviceOUI));
6804 pDot11f->PrimaryDeviceType.primary_category =
6805 (uint16_t) pSirWPSProbeRspIE->PrimaryDeviceCategory;
6806 pDot11f->PrimaryDeviceType.sub_category =
6807 (uint16_t) pSirWPSProbeRspIE->DeviceSubCategory;
6808 } else
6809 pDot11f->PrimaryDeviceType.present = 0;
6810
6811 if (pSirWPSProbeRspIE->
6812 FieldPresent & SIR_WPS_PROBRSP_DEVICENAME_PRESENT) {
6813 pDot11f->DeviceName.present = 1;
6814 pDot11f->DeviceName.num_text =
6815 pSirWPSProbeRspIE->DeviceName.num_text;
6816 qdf_mem_copy(pDot11f->DeviceName.text,
6817 pSirWPSProbeRspIE->DeviceName.text,
6818 pDot11f->DeviceName.num_text);
6819 } else
6820 pDot11f->DeviceName.present = 0;
6821
6822 if (pSirWPSProbeRspIE->
6823 FieldPresent & SIR_WPS_PROBRSP_CONFIGMETHODS_PRESENT) {
6824 pDot11f->ConfigMethods.present = 1;
6825 pDot11f->ConfigMethods.methods =
6826 pSirWPSProbeRspIE->ConfigMethod;
6827 } else
6828 pDot11f->ConfigMethods.present = 0;
6829
6830 if (pSirWPSProbeRspIE->FieldPresent & SIR_WPS_PROBRSP_RF_BANDS_PRESENT) {
6831 pDot11f->RFBands.present = 1;
6832 pDot11f->RFBands.bands = pSirWPSProbeRspIE->RFBand;
6833 } else
6834 pDot11f->RFBands.present = 0;
6835
6836 return QDF_STATUS_SUCCESS;
6837 }
6838
6839 QDF_STATUS populate_dot11f_beacon_wpsi_es(struct mac_context *mac,
6840 tDot11fIEWscBeacon *pDot11f,
6841 struct pe_session *pe_session)
6842 {
6843
6844 tSirWPSBeaconIE *pSirWPSBeaconIE;
6845
6846 pSirWPSBeaconIE = &pe_session->APWPSIEs.SirWPSBeaconIE;
6847
6848 if (pSirWPSBeaconIE->FieldPresent & SIR_WPS_PROBRSP_VER_PRESENT) {
6849 pDot11f->present = 1;
6850 pDot11f->Version.present = 1;
6851 pDot11f->Version.major =
6852 (uint8_t) ((pSirWPSBeaconIE->Version & 0xF0) >> 4);
6853 pDot11f->Version.minor =
6854 (uint8_t) (pSirWPSBeaconIE->Version & 0x0F);
6855 } else {
6856 pDot11f->present = 0;
6857 pDot11f->Version.present = 0;
6858 }
6859
6860 if (pSirWPSBeaconIE->FieldPresent & SIR_WPS_BEACON_STATE_PRESENT) {
6861
6862 pDot11f->WPSState.present = 1;
6863 pDot11f->WPSState.state = (uint8_t) pSirWPSBeaconIE->wpsState;
6864 } else
6865 pDot11f->WPSState.present = 0;
6866
6867 if (pSirWPSBeaconIE->FieldPresent & SIR_WPS_BEACON_APSETUPLOCK_PRESENT) {
6868 pDot11f->APSetupLocked.present = 1;
6869 pDot11f->APSetupLocked.fLocked = pSirWPSBeaconIE->APSetupLocked;
6870 } else
6871 pDot11f->APSetupLocked.present = 0;
6872
6873 if (pSirWPSBeaconIE->
6874 FieldPresent & SIR_WPS_BEACON_SELECTEDREGISTRA_PRESENT) {
6875 pDot11f->SelectedRegistrar.present = 1;
6876 pDot11f->SelectedRegistrar.selected =
6877 pSirWPSBeaconIE->SelectedRegistra;
6878 } else
6879 pDot11f->SelectedRegistrar.present = 0;
6880
6881 if (pSirWPSBeaconIE->
6882 FieldPresent & SIR_WPS_BEACON_DEVICEPASSWORDID_PRESENT) {
6883 pDot11f->DevicePasswordID.present = 1;
6884 pDot11f->DevicePasswordID.id =
6885 pSirWPSBeaconIE->DevicePasswordID;
6886 } else
6887 pDot11f->DevicePasswordID.present = 0;
6888
6889 if (pSirWPSBeaconIE->
6890 FieldPresent & SIR_WPS_BEACON_SELECTEDREGISTRACFGMETHOD_PRESENT) {
6891 pDot11f->SelectedRegistrarConfigMethods.present = 1;
6892 pDot11f->SelectedRegistrarConfigMethods.methods =
6893 pSirWPSBeaconIE->SelectedRegistraCfgMethod;
6894 } else
6895 pDot11f->SelectedRegistrarConfigMethods.present = 0;
6896
6897 if (pSirWPSBeaconIE->FieldPresent & SIR_WPS_BEACON_UUIDE_PRESENT) {
6898 pDot11f->UUID_E.present = 1;
6899 qdf_mem_copy(pDot11f->UUID_E.uuid, pSirWPSBeaconIE->UUID_E,
6900 WNI_CFG_WPS_UUID_LEN);
6901 } else
6902 pDot11f->UUID_E.present = 0;
6903
6904 if (pSirWPSBeaconIE->FieldPresent & SIR_WPS_BEACON_RF_BANDS_PRESENT) {
6905 pDot11f->RFBands.present = 1;
6906 pDot11f->RFBands.bands = pSirWPSBeaconIE->RFBand;
6907 } else
6908 pDot11f->RFBands.present = 0;
6909
6910 return QDF_STATUS_SUCCESS;
6911 }
6912
6913 QDF_STATUS populate_dot11f_wsc_in_probe_res(struct mac_context *mac,
6914 tDot11fIEWscProbeRes *pDot11f)
6915 {
6916 uint32_t cfgStrLen;
6917 uint32_t val;
6918 uint32_t wpsVersion, wpsState;
6919
6920 wpsVersion = mac->mlme_cfg->wps_params.wps_version;
6921
6922 pDot11f->Version.present = 1;
6923 pDot11f->Version.major = (uint8_t) ((wpsVersion & 0xF0) >> 4);
6924 pDot11f->Version.minor = (uint8_t) (wpsVersion & 0x0F);
6925
6926 wpsState = mac->mlme_cfg->wps_params.wps_state;
6927 pDot11f->WPSState.present = 1;
6928 pDot11f->WPSState.state = (uint8_t) wpsState;
6929
6930 pDot11f->APSetupLocked.present = 0;
6931
6932 pDot11f->SelectedRegistrar.present = 0;
6933
6934 pDot11f->DevicePasswordID.present = 0;
6935
6936 pDot11f->SelectedRegistrarConfigMethods.present = 0;
6937
6938 pDot11f->ResponseType.present = 1;
6939 if ((mac->lim.wscIeInfo.reqType == REQ_TYPE_REGISTRAR) ||
6940 (mac->lim.wscIeInfo.reqType == REQ_TYPE_WLAN_MANAGER_REGISTRAR)) {
6941 pDot11f->ResponseType.resType = RESP_TYPE_ENROLLEE_OPEN_8021X;
6942 } else {
6943 pDot11f->ResponseType.resType = RESP_TYPE_AP;
6944 }
6945
6946 /* UUID is a 16 byte long binary*/
6947 pDot11f->UUID_E.present = 1;
6948 *pDot11f->UUID_E.uuid = '\0';
6949
6950 wlan_mlme_get_wps_uuid(&mac->mlme_cfg->wps_params,
6951 pDot11f->UUID_E.uuid);
6952
6953 pDot11f->Manufacturer.present = 1;
6954 cfgStrLen = sizeof(pDot11f->Manufacturer.name);
6955 if (wlan_mlme_get_manufacturer_name(mac->psoc,
6956 pDot11f->Manufacturer.name,
6957 &cfgStrLen) != QDF_STATUS_SUCCESS) {
6958 pDot11f->Manufacturer.num_name = 0;
6959 } else {
6960 pDot11f->Manufacturer.num_name =
6961 (uint8_t) (cfgStrLen & 0x000000FF);
6962 }
6963
6964 pDot11f->ModelName.present = 1;
6965 cfgStrLen = sizeof(pDot11f->ModelName.text);
6966 if (wlan_mlme_get_model_name(mac->psoc,
6967 pDot11f->ModelName.text,
6968 &cfgStrLen) != QDF_STATUS_SUCCESS) {
6969 pDot11f->ModelName.num_text = 0;
6970 } else {
6971 pDot11f->ModelName.num_text =
6972 (uint8_t) (cfgStrLen & 0x000000FF);
6973 }
6974
6975 pDot11f->ModelNumber.present = 1;
6976 cfgStrLen = sizeof(pDot11f->ModelNumber.text);
6977 if (wlan_mlme_get_model_number(mac->psoc,
6978 pDot11f->ModelNumber.text,
6979 &cfgStrLen) != QDF_STATUS_SUCCESS) {
6980 pDot11f->ModelNumber.num_text = 0;
6981 } else {
6982 pDot11f->ModelNumber.num_text =
6983 (uint8_t) (cfgStrLen & 0x000000FF);
6984 }
6985
6986 pDot11f->SerialNumber.present = 1;
6987 cfgStrLen = sizeof(pDot11f->SerialNumber.text);
6988 if (wlan_mlme_get_manufacture_product_version
6989 (mac->psoc,
6990 pDot11f->SerialNumber.text,
6991 &cfgStrLen) != QDF_STATUS_SUCCESS) {
6992 pDot11f->SerialNumber.num_text = 0;
6993 } else {
6994 pDot11f->SerialNumber.num_text =
6995 (uint8_t) (cfgStrLen & 0x000000FF);
6996 }
6997
6998 pDot11f->PrimaryDeviceType.present = 1;
6999
7000 pDot11f->PrimaryDeviceType.primary_category =
7001 (uint16_t)mac->mlme_cfg->wps_params.wps_primary_device_category;
7002
7003 val = mac->mlme_cfg->wps_params.wps_primary_device_oui;
7004 *(pDot11f->PrimaryDeviceType.oui) =
7005 (uint8_t) ((val >> 24) & 0xff);
7006 *(pDot11f->PrimaryDeviceType.oui + 1) =
7007 (uint8_t) ((val >> 16) & 0xff);
7008 *(pDot11f->PrimaryDeviceType.oui + 2) =
7009 (uint8_t) ((val >> 8) & 0xff);
7010 *(pDot11f->PrimaryDeviceType.oui + 3) =
7011 (uint8_t) ((val & 0xff));
7012
7013 pDot11f->PrimaryDeviceType.sub_category =
7014 (uint16_t)mac->mlme_cfg->wps_params.wps_device_sub_category;
7015
7016
7017 pDot11f->DeviceName.present = 1;
7018 cfgStrLen = sizeof(pDot11f->DeviceName.text);
7019 if (wlan_mlme_get_manufacture_product_name(mac->psoc,
7020 pDot11f->DeviceName.text,
7021 &cfgStrLen) !=
7022 QDF_STATUS_SUCCESS) {
7023 pDot11f->DeviceName.num_text = 0;
7024 } else {
7025 pDot11f->DeviceName.num_text =
7026 (uint8_t) (cfgStrLen & 0x000000FF);
7027 }
7028
7029 pDot11f->ConfigMethods.present = 1;
7030 pDot11f->ConfigMethods.methods =
7031 (uint16_t)(mac->mlme_cfg->wps_params.wps_cfg_method &
7032 0x0000FFFF);
7033
7034 pDot11f->RFBands.present = 0;
7035
7036 pDot11f->present = 1;
7037 return QDF_STATUS_SUCCESS;
7038 }
7039
7040 QDF_STATUS
7041 populate_dot11f_wsc_registrar_info_in_probe_res(struct mac_context *mac,
7042 tDot11fIEWscProbeRes *pDot11f)
7043 {
7044 const struct sLimWscIeInfo *const pWscIeInfo = &(mac->lim.wscIeInfo);
7045
7046 pDot11f->APSetupLocked.present = 1;
7047 pDot11f->APSetupLocked.fLocked = pWscIeInfo->apSetupLocked;
7048
7049 pDot11f->SelectedRegistrar.present = 1;
7050 pDot11f->SelectedRegistrar.selected = pWscIeInfo->selectedRegistrar;
7051
7052 pDot11f->DevicePasswordID.present = 1;
7053 pDot11f->DevicePasswordID.id =
7054 (uint16_t)mac->mlme_cfg->wps_params.wps_device_password_id;
7055
7056 pDot11f->SelectedRegistrarConfigMethods.present = 1;
7057 pDot11f->SelectedRegistrarConfigMethods.methods =
7058 pWscIeInfo->selectedRegistrarConfigMethods;
7059
7060 /* UUID_E and RF Bands are applicable only for dual band AP */
7061
7062 return QDF_STATUS_SUCCESS;
7063 }
7064
7065 QDF_STATUS
7066 de_populate_dot11f_wsc_registrar_info_in_probe_res(struct mac_context *mac,
7067 tDot11fIEWscProbeRes *
7068 pDot11f)
7069 {
7070 pDot11f->APSetupLocked.present = 0;
7071 pDot11f->SelectedRegistrar.present = 0;
7072 pDot11f->DevicePasswordID.present = 0;
7073 pDot11f->SelectedRegistrarConfigMethods.present = 0;
7074
7075 return QDF_STATUS_SUCCESS;
7076 }
7077
7078 QDF_STATUS populate_dot11_assoc_res_p2p_ie(struct mac_context *mac,
7079 tDot11fIEP2PAssocRes *pDot11f,
7080 tpSirAssocReq pRcvdAssocReq)
7081 {
7082 const uint8_t *p2pIe;
7083
7084 p2pIe = limGetP2pIEPtr(mac, pRcvdAssocReq->addIE.addIEdata,
7085 pRcvdAssocReq->addIE.length);
7086 if (p2pIe) {
7087 pDot11f->present = 1;
7088 pDot11f->P2PStatus.present = 1;
7089 pDot11f->P2PStatus.status = QDF_STATUS_SUCCESS;
7090 pDot11f->ExtendedListenTiming.present = 0;
7091 }
7092 return QDF_STATUS_SUCCESS;
7093 }
7094
7095
7096 QDF_STATUS populate_dot11f_wfatpc(struct mac_context *mac,
7097 tDot11fIEWFATPC *pDot11f, uint8_t txPower,
7098 uint8_t linkMargin)
7099 {
7100 pDot11f->txPower = txPower;
7101 pDot11f->linkMargin = linkMargin;
7102 pDot11f->present = 1;
7103
7104 return QDF_STATUS_SUCCESS;
7105 }
7106
7107 void
7108 populate_dot11f_chan_load_report(struct mac_context *mac,
7109 tDot11fIEMeasurementReport *dot11f,
7110 struct chan_load_report *channel_load_report)
7111 {
7112 dot11f->report.channel_load_report.op_class =
7113 channel_load_report->op_class;
7114 dot11f->report.channel_load_report.channel =
7115 channel_load_report->channel;
7116 qdf_mem_copy(dot11f->report.channel_load_report.meas_start_time,
7117 &channel_load_report->rrm_scan_tsf,
7118 sizeof(dot11f->report.channel_load_report.meas_start_time));
7119 dot11f->report.channel_load_report.meas_duration =
7120 channel_load_report->meas_duration;
7121 dot11f->report.channel_load_report.chan_load =
7122 channel_load_report->chan_load;
7123
7124 if (channel_load_report->wide_bw.is_wide_bw_chan_switch) {
7125 dot11f->report.channel_load_report.wide_bw_chan_switch.present = 1;
7126 dot11f->report.channel_load_report.wide_bw_chan_switch.new_chan_width = channel_load_report->wide_bw.channel_width;
7127 dot11f->report.channel_load_report.wide_bw_chan_switch.new_center_chan_freq0 = channel_load_report->wide_bw.center_chan_freq0;
7128 dot11f->report.channel_load_report.wide_bw_chan_switch.new_center_chan_freq1 = channel_load_report->wide_bw.center_chan_freq1;
7129 }
7130
7131 if (channel_load_report->bw_ind.is_bw_ind_element) {
7132 dot11f->report.channel_load_report.bw_indication.present = 1;
7133 dot11f->report.channel_load_report.bw_indication.channel_width = channel_load_report->bw_ind.channel_width;
7134 dot11f->report.channel_load_report.bw_indication.ccfs0 = channel_load_report->bw_ind.center_freq_seg0;
7135 dot11f->report.channel_load_report.bw_indication.ccfs1 = channel_load_report->bw_ind.center_freq_seg1;
7136 }
7137
7138 pe_debug("regClass %d chan %d meas_time %lu meas_dur %d, chan_load %d",
7139 dot11f->report.channel_load_report.op_class,
7140 dot11f->report.channel_load_report.channel,
7141 channel_load_report->rrm_scan_tsf,
7142 dot11f->report.channel_load_report.meas_duration,
7143 dot11f->report.channel_load_report.chan_load);
7144 }
7145
7146 static void
7147 populate_dot11f_rrm_counter_stats(tDot11fIEMeasurementReport *pdot11f,
7148 struct counter_stats *counter_stats,
7149 bool *reporting_reason_present)
7150 {
7151 tDot11fIEreporting_reason *reporting_reason;
7152
7153 reporting_reason = &pdot11f->report.sta_stats.reporting_reason;
7154 pdot11f->report.sta_stats.statsgroupdata.dot11_counter_stats.transmitted_fragment_count =
7155 counter_stats->transmitted_fragment_count;
7156
7157 pdot11f->report.sta_stats.statsgroupdata.dot11_counter_stats.group_transmitted_frame_count =
7158 counter_stats->group_transmitted_frame_count;
7159
7160 if (counter_stats->failed_count) {
7161 reporting_reason->failed_count = 1;
7162 *reporting_reason_present = true;
7163 }
7164 pdot11f->report.sta_stats.statsgroupdata.dot11_counter_stats.failed_count =
7165 counter_stats->failed_count;
7166
7167 pdot11f->report.sta_stats.statsgroupdata.dot11_counter_stats.received_fragment_count =
7168 counter_stats->received_fragment_count;
7169
7170 pdot11f->report.sta_stats.statsgroupdata.dot11_counter_stats.group_received_frame_count =
7171 counter_stats->group_received_frame_count;
7172
7173 if (counter_stats->fcs_error_count) {
7174 reporting_reason->fcs_error = 1;
7175 *reporting_reason_present = true;
7176 }
7177 pdot11f->report.sta_stats.statsgroupdata.dot11_counter_stats.fcs_error_count =
7178 counter_stats->fcs_error_count;
7179
7180 pdot11f->report.sta_stats.statsgroupdata.dot11_counter_stats.transmitted_frame_count =
7181 counter_stats->transmitted_frame_count;
7182 }
7183
7184 static void
7185 populate_dot11f_rrm_mac_stats(tDot11fIEMeasurementReport *pdot11f,
7186 struct mac_stats *mac_stats,
7187 bool *reporting_reason_present)
7188 {
7189 tDot11fIEreporting_reason *reporting_reason;
7190
7191 reporting_reason = &pdot11f->report.sta_stats.reporting_reason;
7192 if (mac_stats->retry_count) {
7193 reporting_reason->retry = 1;
7194 *reporting_reason_present = true;
7195 }
7196 pdot11f->report.sta_stats.statsgroupdata.dot11_mac_stats.retry_count =
7197 mac_stats->retry_count;
7198
7199 if (mac_stats->multiple_retry_count) {
7200 reporting_reason->multiple_retry = 1;
7201 *reporting_reason_present = true;
7202 }
7203 pdot11f->report.sta_stats.statsgroupdata.dot11_mac_stats.multiple_retry_count =
7204 mac_stats->multiple_retry_count;
7205
7206 if (mac_stats->frame_duplicate_count) {
7207 reporting_reason->frame_duplicate = 1;
7208 *reporting_reason_present = true;
7209 }
7210 pdot11f->report.sta_stats.statsgroupdata.dot11_mac_stats.frame_duplicate_count =
7211 mac_stats->frame_duplicate_count;
7212
7213 pdot11f->report.sta_stats.statsgroupdata.dot11_mac_stats.rts_success_count =
7214 mac_stats->rts_success_count;
7215
7216 if (mac_stats->rts_failure_count) {
7217 reporting_reason->rts_failure = 1;
7218 *reporting_reason_present = true;
7219 }
7220 pdot11f->report.sta_stats.statsgroupdata.dot11_mac_stats.rts_failure_count =
7221 mac_stats->rts_failure_count;
7222
7223 if (mac_stats->ack_failure_count) {
7224 reporting_reason->ack_failure = 1;
7225 *reporting_reason_present = true;
7226 }
7227 pdot11f->report.sta_stats.statsgroupdata.dot11_mac_stats.ack_failure_count =
7228 mac_stats->ack_failure_count;
7229 }
7230
7231 static void
7232 populate_dot11f_rrm_access_delay_stats(
7233 tDot11fIEMeasurementReport *pdot11f,
7234 struct access_delay_stats *access_delay_stats)
7235 {
7236 pdot11f->report.sta_stats.statsgroupdata.dot11_bss_average_access_delay.ap_average_access_delay =
7237 access_delay_stats->ap_average_access_delay;
7238
7239 pdot11f->report.sta_stats.statsgroupdata.dot11_bss_average_access_delay.average_access_delay_besteffort =
7240 access_delay_stats->average_access_delay_besteffort;
7241
7242 pdot11f->report.sta_stats.statsgroupdata.dot11_bss_average_access_delay.average_access_delay_background =
7243 access_delay_stats->average_access_delay_background;
7244
7245 pdot11f->report.sta_stats.statsgroupdata.dot11_bss_average_access_delay.average_access_delay_video =
7246 access_delay_stats->average_access_delay_video;
7247
7248 pdot11f->report.sta_stats.statsgroupdata.dot11_bss_average_access_delay.average_access_delay_voice =
7249 access_delay_stats->average_access_delay_voice;
7250
7251 pdot11f->report.sta_stats.statsgroupdata.dot11_bss_average_access_delay.station_count =
7252 access_delay_stats->station_count;
7253
7254 pdot11f->report.sta_stats.statsgroupdata.dot11_bss_average_access_delay.channel_utilization =
7255 access_delay_stats->channel_utilization;
7256 }
7257
7258 QDF_STATUS
7259 populate_dot11f_rrm_sta_stats_report(
7260 struct mac_context *mac, tDot11fIEMeasurementReport *pdot11f,
7261 struct statistics_report *statistics_report)
7262 {
7263 struct counter_stats counter_stats;
7264 struct mac_stats mac_stats;
7265 struct access_delay_stats access_delay_stats;
7266 bool reporting_reason_present = false;
7267
7268 counter_stats = statistics_report->group_stats.counter_stats;
7269 mac_stats = statistics_report->group_stats.mac_stats;
7270 access_delay_stats = statistics_report->group_stats.access_delay_stats;
7271
7272 pdot11f->report.sta_stats.meas_duration =
7273 statistics_report->meas_duration;
7274 pdot11f->report.sta_stats.group_id = statistics_report->group_id;
7275 pdot11f->report.sta_stats.reporting_reason.present = 0;
7276
7277 switch (statistics_report->group_id) {
7278 case STA_STAT_GROUP_ID_COUNTER_STATS:
7279 populate_dot11f_rrm_counter_stats(pdot11f, &counter_stats,
7280 &reporting_reason_present);
7281 break;
7282 case STA_STAT_GROUP_ID_MAC_STATS:
7283 populate_dot11f_rrm_mac_stats(pdot11f, &mac_stats,
7284 &reporting_reason_present);
7285 break;
7286 case STA_STAT_GROUP_ID_DELAY_STATS:
7287 populate_dot11f_rrm_access_delay_stats(pdot11f,
7288 &access_delay_stats);
7289 break;
7290 default:
7291 pe_err("group id not supported %d",
7292 statistics_report->group_id);
7293 return QDF_STATUS_SUCCESS;
7294 }
7295 if (reporting_reason_present)
7296 pdot11f->report.sta_stats.reporting_reason.present = 1;
7297
7298 return QDF_STATUS_SUCCESS;
7299 }
7300
7301 QDF_STATUS
7302 populate_dot11f_beacon_report(struct mac_context *mac,
7303 tDot11fIEMeasurementReport *pDot11f,
7304 tSirMacBeaconReport *pBeaconReport,
7305 bool is_last_frame)
7306 {
7307 tDot11fIEbeacon_report_frm_body_fragment_id *frm_body_frag_id;
7308
7309 pDot11f->report.Beacon.regClass = pBeaconReport->regClass;
7310 pDot11f->report.Beacon.channel = pBeaconReport->channel;
7311 qdf_mem_copy(pDot11f->report.Beacon.meas_start_time,
7312 pBeaconReport->measStartTime,
7313 sizeof(pDot11f->report.Beacon.meas_start_time));
7314 pDot11f->report.Beacon.meas_duration = pBeaconReport->measDuration;
7315 pDot11f->report.Beacon.condensed_PHY = pBeaconReport->phyType;
7316 pDot11f->report.Beacon.reported_frame_type =
7317 !pBeaconReport->bcnProbeRsp;
7318 pDot11f->report.Beacon.RCPI = pBeaconReport->rcpi;
7319 pDot11f->report.Beacon.RSNI = pBeaconReport->rsni;
7320 qdf_mem_copy(pDot11f->report.Beacon.BSSID, pBeaconReport->bssid,
7321 sizeof(tSirMacAddr));
7322 pDot11f->report.Beacon.antenna_id = pBeaconReport->antennaId;
7323 pDot11f->report.Beacon.parent_TSF = pBeaconReport->parentTSF;
7324
7325 if (pBeaconReport->numIes) {
7326 pDot11f->report.Beacon.BeaconReportFrmBody.present = 1;
7327 qdf_mem_copy(pDot11f->report.Beacon.BeaconReportFrmBody.
7328 reportedFields, pBeaconReport->Ies,
7329 pBeaconReport->numIes);
7330 pDot11f->report.Beacon.BeaconReportFrmBody.num_reportedFields =
7331 pBeaconReport->numIes;
7332 }
7333
7334 if (pBeaconReport->last_bcn_report_ind_support) {
7335 pe_debug("Including Last Beacon Report in RRM Frame");
7336 frm_body_frag_id = &pDot11f->report.Beacon.
7337 beacon_report_frm_body_fragment_id;
7338
7339 frm_body_frag_id->present = 1;
7340 frm_body_frag_id->beacon_report_id =
7341 pBeaconReport->frame_body_frag_id.id;
7342 frm_body_frag_id->fragment_id_number =
7343 pBeaconReport->frame_body_frag_id.frag_id;
7344 frm_body_frag_id->more_fragments =
7345 pBeaconReport->frame_body_frag_id.more_frags;
7346
7347 pDot11f->report.Beacon.last_beacon_report_indication.present =
7348 1;
7349
7350 pDot11f->report.Beacon.last_beacon_report_indication.
7351 last_fragment = is_last_frame;
7352 pe_debug("id %d frag_id %d more_frags %d is_last_frame %d",
7353 frm_body_frag_id->beacon_report_id,
7354 frm_body_frag_id->fragment_id_number,
7355 frm_body_frag_id->more_fragments,
7356 is_last_frame);
7357 }
7358 return QDF_STATUS_SUCCESS;
7359
7360 }
7361
7362 QDF_STATUS populate_dot11f_rrm_ie(struct mac_context *mac,
7363 tDot11fIERRMEnabledCap *pDot11f,
7364 struct pe_session *pe_session)
7365 {
7366 tpRRMCaps pRrmCaps;
7367 uint8_t *bytes;
7368
7369 pRrmCaps = rrm_get_capabilities(mac, pe_session);
7370
7371 pDot11f->LinkMeasurement = pRrmCaps->LinkMeasurement;
7372 pDot11f->NeighborRpt = pRrmCaps->NeighborRpt;
7373 pDot11f->parallel = pRrmCaps->parallel;
7374 pDot11f->repeated = pRrmCaps->repeated;
7375 pDot11f->BeaconPassive = pRrmCaps->BeaconPassive;
7376 pDot11f->BeaconActive = pRrmCaps->BeaconActive;
7377 pDot11f->BeaconTable = pRrmCaps->BeaconTable;
7378 pDot11f->BeaconRepCond = pRrmCaps->BeaconRepCond;
7379 pDot11f->FrameMeasurement = pRrmCaps->FrameMeasurement;
7380 pDot11f->ChannelLoad = pRrmCaps->ChannelLoad;
7381 pDot11f->NoiseHistogram = pRrmCaps->NoiseHistogram;
7382 pDot11f->statistics = pRrmCaps->statistics;
7383 pDot11f->LCIMeasurement = pRrmCaps->LCIMeasurement;
7384 pDot11f->LCIAzimuth = pRrmCaps->LCIAzimuth;
7385 pDot11f->TCMCapability = pRrmCaps->TCMCapability;
7386 pDot11f->triggeredTCM = pRrmCaps->triggeredTCM;
7387 pDot11f->APChanReport = pRrmCaps->APChanReport;
7388 pDot11f->RRMMIBEnabled = pRrmCaps->RRMMIBEnabled;
7389 pDot11f->operatingChanMax = pRrmCaps->operatingChanMax;
7390 pDot11f->nonOperatinChanMax = pRrmCaps->nonOperatingChanMax;
7391 pDot11f->MeasurementPilot = pRrmCaps->MeasurementPilot;
7392 pDot11f->MeasurementPilotEnabled = pRrmCaps->MeasurementPilotEnabled;
7393 pDot11f->NeighborTSFOffset = pRrmCaps->NeighborTSFOffset;
7394 pDot11f->RCPIMeasurement = pRrmCaps->RCPIMeasurement;
7395 pDot11f->RSNIMeasurement = pRrmCaps->RSNIMeasurement;
7396 pDot11f->BssAvgAccessDelay = pRrmCaps->BssAvgAccessDelay;
7397 pDot11f->BSSAvailAdmission = pRrmCaps->BSSAvailAdmission;
7398 pDot11f->AntennaInformation = pRrmCaps->AntennaInformation;
7399 pDot11f->fine_time_meas_rpt = pRrmCaps->fine_time_meas_rpt;
7400 pDot11f->lci_capability = pRrmCaps->lci_capability;
7401 pDot11f->reserved = pRrmCaps->reserved;
7402
7403 bytes = (uint8_t *) pDot11f + 1; /* ignore present field */
7404 pe_debug("RRM Enabled Cap IE: %02x %02x %02x %02x %02x",
7405 bytes[0], bytes[1], bytes[2], bytes[3], bytes[4]);
7406
7407 pDot11f->present = 1;
7408 return QDF_STATUS_SUCCESS;
7409 }
7410
7411 void populate_mdie(struct mac_context *mac,
7412 tDot11fIEMobilityDomain *pDot11f,
7413 uint8_t mdie[])
7414 {
7415 pDot11f->present = 1;
7416 pDot11f->MDID = (uint16_t) ((mdie[1] << 8) | (mdie[0]));
7417
7418 /* Plugfest fix */
7419 pDot11f->overDSCap = (mdie[2] & 0x01);
7420 pDot11f->resourceReqCap = ((mdie[2] >> 1) & 0x01);
7421
7422 }
7423
7424 #ifdef WLAN_FEATURE_FILS_SK
7425 void populate_fils_ft_info(struct mac_context *mac, tDot11fIEFTInfo *ft_info,
7426 struct pe_session *pe_session)
7427 {
7428 struct pe_fils_session *ft_fils_info = pe_session->fils_info;
7429
7430 if (!ft_fils_info)
7431 return;
7432
7433 if (!ft_fils_info->ft_ie.present) {
7434 ft_info->present = 0;
7435 pe_err("FT IE doesn't exist");
7436 return;
7437 }
7438
7439 ft_info->IECount = ft_fils_info->ft_ie.element_count;
7440
7441 qdf_mem_copy(ft_info->MIC, ft_fils_info->ft_ie.mic,
7442 FT_MIC_LEN);
7443
7444 qdf_mem_copy(ft_info->Anonce, ft_fils_info->ft_ie.anonce,
7445 FT_NONCE_LEN);
7446
7447 qdf_mem_copy(ft_info->Snonce, ft_fils_info->ft_ie.snonce,
7448 FT_NONCE_LEN);
7449
7450 if (ft_fils_info->ft_ie.r0kh_id_len > 0) {
7451 ft_info->R0KH_ID.present = 1;
7452 qdf_mem_copy(ft_info->R0KH_ID.PMK_R0_ID,
7453 ft_fils_info->ft_ie.r0kh_id,
7454 ft_fils_info->ft_ie.r0kh_id_len);
7455 ft_info->R0KH_ID.num_PMK_R0_ID =
7456 ft_fils_info->ft_ie.r0kh_id_len;
7457 }
7458
7459 ft_info->R1KH_ID.present = 1;
7460 qdf_mem_copy(ft_info->R1KH_ID.PMK_R1_ID,
7461 ft_fils_info->ft_ie.r1kh_id,
7462 FT_R1KH_ID_LEN);
7463
7464 qdf_mem_copy(&ft_info->GTK, &ft_fils_info->ft_ie.gtk_ie,
7465 sizeof(struct mac_ft_gtk_ie));
7466 qdf_mem_copy(&ft_info->IGTK, &ft_fils_info->ft_ie.igtk_ie,
7467 sizeof(struct mac_ft_igtk_ie));
7468
7469 ft_info->present = 1;
7470 }
7471 #endif
7472
7473 void populate_dot11f_assoc_rsp_rates(struct mac_context *mac,
7474 tDot11fIESuppRates *pSupp,
7475 tDot11fIEExtSuppRates *pExt,
7476 uint16_t *_11bRates, uint16_t *_11aRates)
7477 {
7478 uint8_t num_supp = 0, num_ext = 0;
7479 uint8_t i, j;
7480
7481 for (i = 0; (i < SIR_NUM_11B_RATES && _11bRates[i]); i++, num_supp++) {
7482 pSupp->rates[num_supp] = (uint8_t) _11bRates[i];
7483 }
7484 for (j = 0; (j < SIR_NUM_11A_RATES && _11aRates[j]); j++) {
7485 if (num_supp < 8)
7486 pSupp->rates[num_supp++] = (uint8_t) _11aRates[j];
7487 else
7488 pExt->rates[num_ext++] = (uint8_t) _11aRates[j];
7489 }
7490
7491 if (num_supp) {
7492 pSupp->num_rates = num_supp;
7493 pSupp->present = 1;
7494 }
7495 if (num_ext) {
7496 pExt->num_rates = num_ext;
7497 pExt->present = 1;
7498 }
7499 }
7500
7501 void populate_dot11f_timeout_interval(struct mac_context *mac,
7502 tDot11fIETimeoutInterval *pDot11f,
7503 uint8_t type, uint32_t value)
7504 {
7505 pDot11f->present = 1;
7506 pDot11f->timeoutType = type;
7507 pDot11f->timeoutValue = value;
7508 }
7509
7510 /**
7511 * populate_dot11f_timing_advert_frame() - Populate the TA mgmt frame fields
7512 * @mac_ctx: the MAC context
7513 * @frame: pointer to the TA frame
7514 *
7515 * Return: The SIR status.
7516 */
7517 QDF_STATUS
7518 populate_dot11f_timing_advert_frame(struct mac_context *mac_ctx,
7519 tDot11fTimingAdvertisementFrame *frame)
7520 {
7521 uint32_t val = 0;
7522
7523 /* Capabilities */
7524 val = mac_ctx->mlme_cfg->wep_params.is_privacy_enabled;
7525 if (val)
7526 frame->Capabilities.privacy = 1;
7527
7528 if (mac_ctx->mlme_cfg->ht_caps.short_preamble)
7529 frame->Capabilities.shortPreamble = 1;
7530
7531 if (mac_ctx->mlme_cfg->gen.enabled_11h)
7532 frame->Capabilities.spectrumMgt = 1;
7533
7534 if (mac_ctx->mlme_cfg->wmm_params.qos_enabled)
7535 frame->Capabilities.qos = 1;
7536
7537 if (mac_ctx->mlme_cfg->roam_scoring.apsd_enabled)
7538 frame->Capabilities.apsd = 1;
7539
7540 val = mac_ctx->mlme_cfg->feature_flags.enable_block_ack;
7541 frame->Capabilities.delayedBA =
7542 (uint16_t)((val >> WNI_CFG_BLOCK_ACK_ENABLED_DELAYED) & 1);
7543 frame->Capabilities.immediateBA =
7544 (uint16_t)((val >> WNI_CFG_BLOCK_ACK_ENABLED_IMMEDIATE) & 1);
7545
7546 /* Country */
7547 populate_dot11f_country(mac_ctx, &frame->Country, NULL);
7548
7549 /* PowerConstraints */
7550 frame->PowerConstraints.localPowerConstraints =
7551 mac_ctx->mlme_cfg->power.local_power_constraint;
7552
7553 frame->PowerConstraints.present = 1;
7554
7555 /* TimeAdvertisement */
7556 frame->TimeAdvertisement.present = 1;
7557 frame->TimeAdvertisement.timing_capabilities = 1;
7558
7559 return QDF_STATUS_SUCCESS;
7560 }
7561
7562 #if defined(WLAN_SUPPORT_TWT) && defined(WLAN_FEATURE_11AX)
7563 #ifdef WLAN_TWT_CONV_SUPPORTED
7564 static bool
7565 twt_get_requestor_flag(struct mac_context *mac)
7566 {
7567 bool req_flag = false;
7568
7569 wlan_twt_cfg_get_req_flag(mac->psoc, &req_flag);
7570 return req_flag;
7571 }
7572
7573 static bool
7574 twt_get_responder_flag(struct mac_context *mac)
7575 {
7576 bool res_flag = false;
7577
7578 wlan_twt_cfg_get_res_flag(mac->psoc, &res_flag);
7579 return res_flag;
7580 }
7581 #else
7582 static bool
7583 twt_get_requestor_flag(struct mac_context *mac)
7584 {
7585 return mac->mlme_cfg->twt_cfg.req_flag;
7586 }
7587
7588 static bool
7589 twt_get_responder_flag(struct mac_context *mac)
7590 {
7591 return mac->mlme_cfg->twt_cfg.res_flag;
7592 }
7593 #endif
7594 #endif
7595
7596 #ifdef WLAN_FEATURE_11AX
7597 #ifdef WLAN_SUPPORT_TWT
7598 static void
7599 populate_dot11f_twt_he_cap(struct mac_context *mac,
7600 struct pe_session *session,
7601 tDot11fIEhe_cap *he_cap)
7602 {
7603 bool twt_requestor = false;
7604 bool twt_responder = false;
7605 bool bcast_requestor = false;
7606 bool bcast_responder = false;
7607
7608 wlan_twt_get_bcast_requestor_cfg(mac->psoc, &bcast_requestor);
7609 bcast_requestor = bcast_requestor &&
7610 !mac->mlme_cfg->twt_cfg.disable_btwt_usr_cfg;
7611 wlan_twt_get_bcast_responder_cfg(mac->psoc, &bcast_responder);
7612 wlan_twt_get_requestor_cfg(mac->psoc, &twt_requestor);
7613 wlan_twt_get_responder_cfg(mac->psoc, &twt_responder);
7614
7615 he_cap->broadcast_twt = 0;
7616 if (session->opmode == QDF_STA_MODE ||
7617 session->opmode == QDF_SAP_MODE) {
7618 he_cap->twt_request =
7619 twt_requestor && twt_get_requestor_flag(mac);
7620 he_cap->twt_responder =
7621 twt_responder && twt_get_responder_flag(mac);
7622 }
7623
7624 if (session->opmode == QDF_STA_MODE) {
7625 he_cap->broadcast_twt = bcast_requestor;
7626 } else if (session->opmode == QDF_SAP_MODE) {
7627 he_cap->broadcast_twt = bcast_responder;
7628 }
7629 }
7630 #else
7631 static inline void
7632 populate_dot11f_twt_he_cap(struct mac_context *mac_ctx,
7633 struct pe_session *session,
7634 tDot11fIEhe_cap *he_cap)
7635 {
7636 he_cap->broadcast_twt = 0;
7637 }
7638 #endif
7639
7640 /**
7641 * populate_dot11f_he_caps() - pouldate HE Capability IE
7642 * @mac_ctx: Global MAC context
7643 * @session: PE session
7644 * @he_cap: pointer to HE capability IE
7645 *
7646 * Populdate the HE capability IE based on the session.
7647 */
7648 QDF_STATUS populate_dot11f_he_caps(struct mac_context *mac_ctx, struct pe_session *session,
7649 tDot11fIEhe_cap *he_cap)
7650 {
7651 uint8_t *ppet;
7652 uint32_t value = 0;
7653
7654 he_cap->present = 1;
7655
7656 if (!session) {
7657 qdf_mem_copy(he_cap, &mac_ctx->mlme_cfg->he_caps.dot11_he_cap,
7658 sizeof(tDot11fIEhe_cap));
7659 return QDF_STATUS_SUCCESS;
7660 }
7661
7662 /** TODO: String items needs attention. **/
7663 qdf_mem_copy(he_cap, &session->he_config, sizeof(*he_cap));
7664 if (he_cap->ppet_present) {
7665 value = WNI_CFG_HE_PPET_LEN;
7666 /* if session is present, populate PPET based on band */
7667 if (!wlan_reg_is_24ghz_ch_freq(session->curr_op_freq))
7668 qdf_mem_copy(he_cap->ppet.ppe_threshold.ppe_th,
7669 mac_ctx->mlme_cfg->he_caps.he_ppet_5g,
7670 value);
7671 else
7672 qdf_mem_copy(he_cap->ppet.ppe_threshold.ppe_th,
7673 mac_ctx->mlme_cfg->he_caps.he_ppet_2g,
7674 value);
7675
7676 ppet = he_cap->ppet.ppe_threshold.ppe_th;
7677 he_cap->ppet.ppe_threshold.num_ppe_th =
7678 lim_truncate_ppet(ppet, value);
7679 } else {
7680 he_cap->ppet.ppe_threshold.num_ppe_th = 0;
7681 }
7682 populate_dot11f_twt_he_cap(mac_ctx, session, he_cap);
7683
7684 if (wlan_reg_is_5ghz_ch_freq(session->curr_op_freq) ||
7685 wlan_reg_is_6ghz_chan_freq(session->curr_op_freq)) {
7686 if (session->ch_width <= CH_WIDTH_80MHZ) {
7687 he_cap->chan_width_2 = 0;
7688 he_cap->chan_width_3 = 0;
7689 } else if (session->ch_width == CH_WIDTH_160MHZ) {
7690 he_cap->chan_width_3 = 0;
7691 }
7692 }
7693
7694 return QDF_STATUS_SUCCESS;
7695 }
7696
7697 QDF_STATUS
7698 populate_dot11f_he_caps_by_band(struct mac_context *mac_ctx,
7699 bool is_2g,
7700 tDot11fIEhe_cap *he_cap,
7701 struct pe_session *session)
7702 {
7703 if (is_2g)
7704 qdf_mem_copy(he_cap, &mac_ctx->he_cap_2g, sizeof(*he_cap));
7705 else
7706 qdf_mem_copy(he_cap, &mac_ctx->he_cap_5g, sizeof(*he_cap));
7707
7708 if (session)
7709 populate_dot11f_twt_he_cap(mac_ctx, session, he_cap);
7710
7711 return QDF_STATUS_SUCCESS;
7712 }
7713
7714 /**
7715 * populate_dot11f_he_operation() - pouldate HE Operation IE
7716 * @mac_ctx: Global MAC context
7717 * @session: PE session
7718 * @he_op: pointer to HE Operation IE
7719 *
7720 * Populdate the HE Operation IE based on the session.
7721 */
7722 QDF_STATUS
7723 populate_dot11f_he_operation(struct mac_context *mac_ctx,
7724 struct pe_session *session, tDot11fIEhe_op *he_op)
7725 {
7726 enum reg_6g_ap_type ap_pwr_type;
7727 qdf_mem_copy(he_op, &session->he_op, sizeof(*he_op));
7728
7729 he_op->present = 1;
7730 he_op->vht_oper_present = 0;
7731 if (session->he_6ghz_band) {
7732 he_op->oper_info_6g_present = 1;
7733 if (session->bssType != eSIR_INFRA_AP_MODE) {
7734 he_op->oper_info_6g.info.ch_width = session->ch_width;
7735 he_op->oper_info_6g.info.center_freq_seg0 =
7736 session->ch_center_freq_seg0;
7737 if (session->ch_width == CH_WIDTH_80P80MHZ ||
7738 session->ch_width == CH_WIDTH_160MHZ) {
7739 he_op->oper_info_6g.info.center_freq_seg1 =
7740 session->ch_center_freq_seg1;
7741 he_op->oper_info_6g.info.ch_width =
7742 CH_WIDTH_160MHZ;
7743 } else {
7744 he_op->oper_info_6g.info.center_freq_seg1 = 0;
7745 }
7746 }
7747 he_op->oper_info_6g.info.primary_ch =
7748 wlan_reg_freq_to_chan(mac_ctx->pdev,
7749 session->curr_op_freq);
7750 he_op->oper_info_6g.info.dup_bcon = 0;
7751 he_op->oper_info_6g.info.min_rate = 0;
7752 wlan_reg_get_cur_6g_ap_pwr_type(mac_ctx->pdev, &ap_pwr_type);
7753 he_op->oper_info_6g.info.reg_info = ap_pwr_type;
7754 }
7755
7756 return QDF_STATUS_SUCCESS;
7757 }
7758
7759 QDF_STATUS
7760 populate_dot11f_sr_info(struct mac_context *mac_ctx,
7761 struct pe_session *session,
7762 tDot11fIEspatial_reuse *sr_info)
7763 {
7764 uint8_t non_srg_pd_offset;
7765 uint8_t sr_ctrl = wlan_vdev_mlme_get_sr_ctrl(session->vdev);
7766 bool sr_enabled = wlan_vdev_mlme_get_he_spr_enabled(session->vdev);
7767
7768 if (!sr_enabled)
7769 return QDF_STATUS_SUCCESS;
7770
7771 sr_info->present = 1;
7772 sr_info->psr_disallow = 1;
7773 sr_info->srg_info_present = 0;
7774 sr_info->non_srg_offset_present = 0;
7775 sr_info->non_srg_pd_sr_disallow = !!(sr_ctrl &
7776 WLAN_HE_NON_SRG_PD_SR_DISALLOWED);
7777
7778 if ((!sr_info->non_srg_pd_sr_disallow) &&
7779 (sr_ctrl & WLAN_HE_NON_SRG_OFFSET_PRESENT)) {
7780 non_srg_pd_offset =
7781 wlan_vdev_mlme_get_non_srg_pd_offset(session->vdev);
7782 sr_info->non_srg_offset_present = 1;
7783 sr_info->non_srg_offset.info.non_srg_pd_max_offset =
7784 non_srg_pd_offset;
7785 }
7786
7787 if (sr_ctrl & WLAN_HE_SIGA_SR_VAL15_ALLOWED)
7788 sr_info->sr_value15_allow = 1;
7789
7790 return QDF_STATUS_SUCCESS;
7791 }
7792
7793 QDF_STATUS
7794 populate_dot11f_he_6ghz_cap(struct mac_context *mac_ctx,
7795 struct pe_session *session,
7796 tDot11fIEhe_6ghz_band_cap *he_6g_cap)
7797 {
7798 struct mlme_ht_capabilities_info *ht_cap_info;
7799 struct mlme_vht_capabilities_info *vht_cap_info;
7800
7801 if (session && !session->he_6ghz_band)
7802 return QDF_STATUS_SUCCESS;
7803
7804 ht_cap_info = &mac_ctx->mlme_cfg->ht_caps.ht_cap_info;
7805 vht_cap_info = &mac_ctx->mlme_cfg->vht_caps.vht_cap_info;
7806
7807 he_6g_cap->present = 1;
7808 he_6g_cap->min_mpdu_start_spacing =
7809 mac_ctx->mlme_cfg->ht_caps.ampdu_params.mpdu_density;
7810 if (session)
7811 he_6g_cap->max_ampdu_len_exp =
7812 session->vht_config.max_ampdu_lenexp;
7813 else
7814 he_6g_cap->max_ampdu_len_exp =
7815 vht_cap_info->ampdu_len_exponent & 0x7;
7816 he_6g_cap->max_mpdu_len = vht_cap_info->ampdu_len;
7817 he_6g_cap->sm_pow_save = ht_cap_info->mimo_power_save;
7818 he_6g_cap->rd_responder = 0;
7819 he_6g_cap->rx_ant_pattern_consistency = 0;
7820 he_6g_cap->tx_ant_pattern_consistency = 0;
7821
7822 lim_log_he_6g_cap(mac_ctx, he_6g_cap);
7823
7824 return QDF_STATUS_SUCCESS;
7825 }
7826
7827 #ifdef WLAN_FEATURE_11AX_BSS_COLOR
7828 /**
7829 * populate_dot11f_he_bss_color_change() - pouldate HE BSS color change IE
7830 * @mac_ctx: Global MAC context
7831 * @session: PE session
7832 * @he_bss_color: pointer to HE BSS color change IE
7833 *
7834 * Populdate the HE BSS color change IE based on the session.
7835 */
7836 QDF_STATUS
7837 populate_dot11f_he_bss_color_change(struct mac_context *mac_ctx,
7838 struct pe_session *session,
7839 tDot11fIEbss_color_change *he_bss_color)
7840 {
7841 if (!session->bss_color_changing) {
7842 he_bss_color->present = 0;
7843 return QDF_STATUS_SUCCESS;
7844 }
7845
7846 he_bss_color->present = 1;
7847 he_bss_color->countdown = session->he_bss_color_change.countdown;
7848 he_bss_color->new_color = session->he_bss_color_change.new_color;
7849
7850 lim_log_he_bss_color(mac_ctx, he_bss_color);
7851
7852 return QDF_STATUS_SUCCESS;
7853 }
7854 #endif /* WLAN_FEATURE_11AX_BSS_COLOR */
7855 #endif /* WLAN_FEATURE_11AX */
7856
7857 #ifdef WLAN_FEATURE_11BE
7858
7859 /**
7860 * lim_get_ext_ie_ptr_from_ext_id() - Find out ext ie
7861 * @ie: source ie address
7862 * @ie_len: source ie length
7863 * @oui: oui buffer
7864 * @oui_size: oui size
7865 *
7866 * This API is used to find out ext ie from ext id
7867 *
7868 * Return: vendor ie address - success
7869 * NULL - failure
7870 */
7871 static
7872 const uint8_t *lim_get_ext_ie_ptr_from_ext_id(const uint8_t *ie,
7873 uint16_t ie_len,
7874 const uint8_t *oui,
7875 uint8_t oui_size)
7876 {
7877 return wlan_get_ext_ie_ptr_from_ext_id(oui, oui_size,
7878 ie, ie_len);
7879 }
7880
7881 /* EHT Operation */
7882 /* 1 byte ext id, 1 byte eht op params, 4 bytes basic EHT MCS and NSS set*/
7883 #define EHTOP_FIXED_LEN 6
7884
7885 #define EHTOP_PARAMS_INFOP_IDX 0
7886 #define EHTOP_PARAMS_INFOP_BITS 1
7887
7888 #define EHTOP_PARAMS_DISABLEDSUBCHANBITMAPP_IDX 1
7889 #define EHTOP_PARAMS_DISABLEDSUBCHANBITMAPP_BITS 1
7890
7891 #define EHTOP_INFO_CHANWIDTH_IDX 0
7892 #define EHTOP_INFO_CHANWIDTH_BITS 3
7893
7894 #define WLAN_MAX_DISABLED_SUB_CHAN_BITMAP 2
7895
7896 #define ehtop_ie_set(eht_op, index, num_bits, val) \
7897 QDF_SET_BITS((*eht_op), qdf_do_div_rem(index, 8),\
7898 (num_bits), (val))
7899 #define ehtop_ie_get(eht_op, index, num_bits) \
7900 QDF_GET_BITS((eht_op), qdf_do_div_rem(index, 8), \
7901 (num_bits))
7902
7903 /* byte 0 */
7904 #define EHTOP_PARAMS_INFOP_GET_FROM_IE(__eht_op_params) \
7905 ehtop_ie_get(__eht_op_params, \
7906 EHTOP_PARAMS_INFOP_IDX, \
7907 EHTOP_PARAMS_INFOP_BITS)
7908 #define EHTOP_PARAMS_INFOP_SET_TO_IE(__eht_op_params, __value) \
7909 ehtop_ie_set(&__eht_op_params, \
7910 EHTOP_PARAMS_INFOP_IDX, \
7911 EHTOP_PARAMS_INFOP_BITS, __value)
7912
7913 #define EHTOP_PARAMS_DISABLEDSUBCHANBITMAPP_GET_FROM_IE(__eht_op_params) \
7914 ehtop_ie_get(__eht_op_params, \
7915 EHTOP_PARAMS_DISABLEDSUBCHANBITMAPP_IDX, \
7916 EHTOP_PARAMS_DISABLEDSUBCHANBITMAPP_BITS)
7917 #define EHTOP_PARAMS_DISABLEDSUBCHANBITMAPP_SET_TO_IE(__eht_op_params, __value) \
7918 ehtop_ie_set(&__eht_op_params, \
7919 EHTOP_PARAMS_DISABLEDSUBCHANBITMAPP_IDX, \
7920 EHTOP_PARAMS_DISABLEDSUBCHANBITMAPP_BITS, \
7921 __value)
7922
7923 #define EHTOP_PARAMS_EHT_DEF_PE_DURATION_GET_FROM_IE(__eht_op_params) \
7924 ehtop_ie_get(__eht_op_params, \
7925 EHTOP_DEFAULT_PE_DURATION_IDX, \
7926 EHTOP_DEFAULT_PE_DURATION_BITS)
7927 #define EHTOP_PARAMS_EHT_DEF_PE_DURATION_SET_TO_IE(__eht_op_params, __value) \
7928 ehtop_ie_set(&__eht_op_params, \
7929 EHTOP_DEFAULT_PE_DURATION_IDX, \
7930 EHTOP_DEFAULT_PE_DURATION_BITS, __value)
7931
7932 #define EHTOP_PARAMS_GROUP_ADDR_BU_IND_LIMIT_GET_FROM_IE(__eht_op_params) \
7933 ehtop_ie_get(__eht_op_params, \
7934 EHTOP_GRP_ADDRESSED_BU_IND_LIMIT_IDX, \
7935 EHTOP_GRP_ADDRESSED_BU_IND_LIMIT_BITS)
7936 #define EHTOP_PARAMS_GROUP_ADDR_BU_IND_LIMIT_SET_TO_IE(__eht_op_params, __value) \
7937 ehtop_ie_set(&__eht_op_params, \
7938 EHTOP_GRP_ADDRESSED_BU_IND_LIMIT_IDX, \
7939 EHTOP_GRP_ADDRESSED_BU_IND_LIMIT_BITS, \
7940 __value)
7941
7942 #define EHTOP_PARAMS_GROUP_ADDR_BU_IND_EXPONENT_GET_FROM_IE(__eht_op_params) \
7943 ehtop_ie_get(__eht_op_params, \
7944 EHTOP_GRP_ADDRESSED_BU_IND_EXPONENT_IDX, \
7945 EHTOP_GRP_ADDRESSED_BU_IND_EXPONENT_BITS)
7946 #define EHTOP_PARAMS_GROUP_ADDR_BU_IND_EXPONENT_SET_TO_IE(__eht_op_params, __value) \
7947 ehtop_ie_set(&__eht_op_params, \
7948 EHTOP_GRP_ADDRESSED_BU_IND_EXPONENT_IDX, \
7949 EHTOP_GRP_ADDRESSED_BU_IND_EXPONENT_BITS, \
7950 __value)
7951
7952 #define EHTOP_INFO_CHANWIDTH_GET_FROM_IE(__eht_op_control) \
7953 ehtop_ie_get(__eht_op_control, \
7954 EHTOP_INFO_CHANWIDTH_IDX, \
7955 EHTOP_INFO_CHANWIDTH_BITS)
7956 #define EHTOP_INFO_CHANWIDTH_SET_TO_IE(__eht_op_control, __value) \
7957 ehtop_ie_set(&__eht_op_control, \
7958 EHTOP_INFO_CHANWIDTH_IDX, \
7959 EHTOP_INFO_CHANWIDTH_BITS, __value)
7960
7961 /* 1 byte ext id, 2 bytes mac cap, 9 bytes phy cap */
7962 #define EHTCAP_FIXED_LEN 12
7963 #define EHTCAP_MACBYTE_IDX0 0
7964 #define EHTCAP_MACBYTE_IDX1 1
7965
7966 #define EHTCAP_PHYBYTE_IDX0 0
7967 #define EHTCAP_PHYBYTE_IDX1 1
7968 #define EHTCAP_PHYBYTE_IDX2 2
7969 #define EHTCAP_PHYBYTE_IDX3 3
7970 #define EHTCAP_PHYBYTE_IDX4 4
7971 #define EHTCAP_PHYBYTE_IDX5 5
7972 #define EHTCAP_PHYBYTE_IDX6 6
7973 #define EHTCAP_PHYBYTE_IDX7 7
7974 #define EHTCAP_PHYBYTE_IDX8 8
7975
7976 #define WLAN_IE_HDR_LEN 2
7977
7978 enum EHT_TXRX_MCS_NSS_IDX {
7979 EHTCAP_TXRX_MCS_NSS_IDX0,
7980 EHTCAP_TXRX_MCS_NSS_IDX1,
7981 EHTCAP_TXRX_MCS_NSS_IDX2,
7982 EHTCAP_TXRX_MCS_NSS_IDXMAX,
7983 };
7984
7985 enum EHT_PER_BW_TXRX_MCS_NSS_MAP_IDX {
7986 EHTCAP_TXRX_MCS_NSS_IDX_ONLY20,
7987 EHTCAP_TXRX_MCS_NSS_IDX_80,
7988 EHTCAP_TXRX_MCS_NSS_IDX_160,
7989 EHTCAP_TXRX_MCS_NSS_IDX_320,
7990 EHTCAP_TXRX_MCS_NSS_IDX_MAX,
7991 };
7992
7993 #define EHT_MCS_MAP_RX_MCS_0_9_IDX 0
7994 #define EHT_MCS_MAP_RX_MCS_0_9_BITS 4
7995 #define EHT_MCS_MAP_TX_MCS_0_9_IDX 4
7996 #define EHT_MCS_MAP_TX_MCS_0_9_BITS 4
7997 #define EHT_MCS_MAP_RX_MCS_10_11_IDX 8
7998 #define EHT_MCS_MAP_RX_MCS_10_11_BITS 4
7999 #define EHT_MCS_MAP_TX_MCS_10_11_IDX 12
8000 #define EHT_MCS_MAP_TX_MCS_10_11_BITS 4
8001 #define EHT_MCS_MAP_RX_MCS_12_13_IDX 16
8002 #define EHT_MCS_MAP_RX_MCS_12_13_BITS 4
8003 #define EHT_MCS_MAP_TX_MCS_12_13_IDX 20
8004 #define EHT_MCS_MAP_TX_MCS_12_13_BITS 4
8005
8006 #define EHT_MCS_MAP_20_ONLY_RX_MCS_0_7_IDX 0
8007 #define EHT_MCS_MAP_20_ONLY_RX_MCS_0_7_BITS 4
8008 #define EHT_MCS_MAP_20_ONLY_TX_MCS_0_7_IDX 4
8009 #define EHT_MCS_MAP_20_ONLY_TX_MCS_0_7_BITS 4
8010 #define EHT_MCS_MAP_20_ONLY_RX_MCS_8_9_IDX 8
8011 #define EHT_MCS_MAP_20_ONLY_RX_MCS_8_9_BITS 4
8012 #define EHT_MCS_MAP_20_ONLY_TX_MCS_8_9_IDX 12
8013 #define EHT_MCS_MAP_20_ONLY_TX_MCS_8_9_BITS 4
8014 #define EHT_MCS_MAP_20_ONLY_RX_MCS_10_11_IDX 16
8015 #define EHT_MCS_MAP_20_ONLY_RX_MCS_10_11_BITS 4
8016 #define EHT_MCS_MAP_20_ONLY_TX_MCS_10_11_IDX 20
8017 #define EHT_MCS_MAP_20_ONLY_TX_MCS_10_11_BITS 4
8018 #define EHT_MCS_MAP_20_ONLY_RX_MCS_12_13_IDX 24
8019 #define EHT_MCS_MAP_20_ONLY_RX_MCS_12_13_BITS 4
8020 #define EHT_MCS_MAP_20_ONLY_TX_MCS_12_13_IDX 28
8021 #define EHT_MCS_MAP_20_ONLY_TX_MCS_12_13_BITS 4
8022
8023 #define EHT_TXMCS_MAP_MCS_0_7_IDX 0
8024 #define EHT_TXMCS_MAP_MCS_0_7_BITS 4
8025 #define EHT_TXMCS_MAP_MCS_8_9_IDX 4
8026 #define EHT_TXMCS_MAP_MCS_8_9_BITS 4
8027 #define EHT_TXMCS_MAP_MCS_10_11_IDX 8
8028 #define EHT_TXMCS_MAP_MCS_10_11_BITS 4
8029 #define EHT_TXMCS_MAP_MCS_12_13_IDX 12
8030 #define EHT_TXMCS_MAP_MCS_12_13_BITS 4
8031
8032 #define EHT_RXMCS_MAP_MCS_0_7_IDX 0
8033 #define EHT_RXMCS_MAP_MCS_0_7_BITS 4
8034 #define EHT_RXMCS_MAP_MCS_8_9_IDX 4
8035 #define EHT_RXMCS_MAP_MCS_8_9_BITS 4
8036 #define EHT_RXMCS_MAP_MCS_10_11_IDX 8
8037 #define EHT_RXMCS_MAP_MCS_10_11_BITS 4
8038 #define EHT_RXMCS_MAP_MCS_12_13_IDX 12
8039 #define EHT_RXMCS_MAP_MCS_12_13_BITS 4
8040
8041 #define EHT_MCS_MAP_LEN 3
8042 #define EHT_MCS_MAP_BW20_ONLY_LEN 4
8043
8044 #define ehtcap_ie_set(eht_cap, index, num_bits, val) \
8045 QDF_SET_BITS((*eht_cap), qdf_do_div_rem(index, 8),\
8046 (num_bits), (val))
8047 #define ehtcap_ie_get(eht_cap, index, num_bits) \
8048 QDF_GET_BITS((eht_cap), qdf_do_div_rem(index, 8), \
8049 (num_bits))
8050
8051 /* byte 0 */
8052 #define EHTCAP_MAC_EPCSPRIACCESS_GET_FROM_IE(__eht_cap_mac) \
8053 ehtcap_ie_get(__eht_cap_mac[EHTCAP_MACBYTE_IDX0], \
8054 EHTCAP_MAC_EPCSPRIACCESS_IDX, \
8055 EHTCAP_MAC_EPCSPRIACCESS_BITS)
8056 #define EHTCAP_MAC_EPCSPRIACCESS_SET_TO_IE(__eht_cap_mac, __value) \
8057 ehtcap_ie_set(&__eht_cap_mac[EHTCAP_MACBYTE_IDX0], \
8058 EHTCAP_MAC_EPCSPRIACCESS_IDX, \
8059 EHTCAP_MAC_EPCSPRIACCESS_BITS, __value)
8060
8061 #define EHTCAP_MAC_EHTOMCTRL_GET_FROM_IE(__eht_cap_mac) \
8062 ehtcap_ie_get(__eht_cap_mac[EHTCAP_MACBYTE_IDX0], \
8063 EHTCAP_MAC_EHTOMCTRL_IDX, \
8064 EHTCAP_MAC_EHTOMCTRL_BITS)
8065 #define EHTCAP_MAC_EHTOMCTRL_SET_TO_IE(__eht_cap_mac, value) \
8066 ehtcap_ie_set(&__eht_cap_mac[EHTCAP_MACBYTE_IDX0], \
8067 EHTCAP_MAC_EHTOMCTRL_IDX, \
8068 EHTCAP_MAC_EHTOMCTRL_BITS, value)
8069
8070 #define EHTCAP_MAC_TRIGTXOP_MODE1_GET_FROM_IE(__eht_cap_mac) \
8071 ehtcap_ie_get(__eht_cap_mac[EHTCAP_MACBYTE_IDX0], \
8072 EHTCAP_MAC_TRIGGERED_TXOP_MODE1_IDX, \
8073 EHTCAP_MAC_TRIGGERED_TXOP_MODE1_BITS)
8074 #define EHTCAP_MAC_TRIGTXOP_MODE1_SET_TO_IE(__eht_cap_mac, value) \
8075 ehtcap_ie_set(&__eht_cap_mac[EHTCAP_MACBYTE_IDX0], \
8076 EHTCAP_MAC_TRIGGERED_TXOP_MODE1_IDX, \
8077 EHTCAP_MAC_TRIGGERED_TXOP_MODE1_BITS, \
8078 value)
8079
8080 #define EHTCAP_MAC_TRIGTXOP_MODE2_GET_FROM_IE(__eht_cap_mac) \
8081 ehtcap_ie_get(__eht_cap_mac[EHTCAP_MACBYTE_IDX0], \
8082 EHTCAP_MAC_TRIGGERED_TXOP_MODE2_IDX, \
8083 EHTCAP_MAC_TRIGGERED_TXOP_MODE2_BITS)
8084 #define EHTCAP_MAC_TRIGTXOP_MODE2_SET_TO_IE(__eht_cap_mac, value) \
8085 ehtcap_ie_set(&__eht_cap_mac[EHTCAP_MACBYTE_IDX0], \
8086 EHTCAP_MAC_TRIGGERED_TXOP_MODE2_IDX, \
8087 EHTCAP_MAC_TRIGGERED_TXOP_MODE2_BITS, \
8088 value)
8089
8090 #define EHTCAP_MAC_RESTRICTED_TWT_GET_FROM_IE(__eht_cap_mac) \
8091 ehtcap_ie_get(__eht_cap_mac[EHTCAP_MACBYTE_IDX0], \
8092 EHTCAP_MAC_RESTRICTED_TWT_IDX, \
8093 EHTCAP_MAC_RESTRICTED_TWT_BITS)
8094 #define EHTCAP_MAC_RESTRICTED_TWT_SET_TO_IE(__eht_cap_mac, value) \
8095 ehtcap_ie_set(&__eht_cap_mac[EHTCAP_MACBYTE_IDX0], \
8096 EHTCAP_MAC_RESTRICTED_TWT_IDX, \
8097 EHTCAP_MAC_RESTRICTED_TWT_BITS, value)
8098
8099 #define EHTCAP_MAC_SCS_TRAFFIC_DESC_GET_FROM_IE(__eht_cap_mac) \
8100 ehtcap_ie_get(__eht_cap_mac[EHTCAP_MACBYTE_IDX0], \
8101 EHTCAP_MAC_SCS_TRAFFIC_DESC_IDX, \
8102 EHTCAP_MAC_SCS_TRAFFIC_DESC_BITS)
8103 #define EHTCAP_MAC_SCS_TRAFFIC_DESC_SET_TO_IE(__eht_cap_mac, value) \
8104 ehtcap_ie_set(&__eht_cap_mac[EHTCAP_MACBYTE_IDX0], \
8105 EHTCAP_MAC_SCS_TRAFFIC_DESC_IDX, \
8106 EHTCAP_MAC_SCS_TRAFFIC_DESC_BITS, value)
8107
8108 #define EHTCAP_MAC_MAX_MPDU_LEN_GET_FROM_IE(__eht_cap_mac) \
8109 ehtcap_ie_get(__eht_cap_mac[EHTCAP_MACBYTE_IDX0], \
8110 EHTCAP_MAC_MAX_MPDU_LEN_IDX, \
8111 EHTCAP_MAC_MAX_MPDU_LEN_BITS)
8112 #define EHTCAP_MAC_MAX_MPDU_LEN_SET_TO_IE(__eht_cap_mac, value) \
8113 ehtcap_ie_set(&__eht_cap_mac[EHTCAP_MACBYTE_IDX0], \
8114 EHTCAP_MAC_MAX_MPDU_LEN_IDX, \
8115 EHTCAP_MAC_MAX_MPDU_LEN_BITS, value)
8116
8117 #define EHTCAP_MAC_MAX_A_MPDU_LEN_EXPONENT_EXT_GET_FROM_IE(__eht_cap_mac) \
8118 ehtcap_ie_get(__eht_cap_mac[EHTCAP_MACBYTE_IDX1], \
8119 EHTCAP_MAC_MAX_A_MPDU_LEN_IDX, \
8120 EHTCAP_MAC_MAX_A_MPDU_LEN_BITS)
8121 #define EHTCAP_MAC_MAX_A_MPDU_LEN_EXPONENT_EXT_SET_TO_IE(__eht_cap_mac, value) \
8122 ehtcap_ie_set(&__eht_cap_mac[EHTCAP_MACBYTE_IDX1], \
8123 EHTCAP_MAC_MAX_A_MPDU_LEN_IDX, \
8124 EHTCAP_MAC_MAX_A_MPDU_LEN_BITS, value)
8125
8126 #define EHTCAP_MAC_EHT_TRS_SUPPORT_GET_FROM_IE(__eht_cap_mac) \
8127 ehtcap_ie_get(__eht_cap_mac[EHTCAP_MACBYTE_IDX1], \
8128 EHTCAP_MAC_TRS_SUPPORT_IDX, \
8129 EHTCAP_MAC_TRS_SUPPORT_BITS)
8130 #define EHTCAP_MAC_EHT_TRS_SUPPORT_SET_TO_IE(__eht_cap_mac, value) \
8131 ehtcap_ie_set(&__eht_cap_mac[EHTCAP_MACBYTE_IDX1], \
8132 EHTCAP_MAC_TRS_SUPPORT_IDX, \
8133 EHTCAP_MAC_TRS_SUPPORT_BITS, value)
8134
8135 #define EHTCAP_MAC_TXOP_RETURN_SUPPORT_SHARE_M2_GET_FROM_IE(__eht_cap_mac) \
8136 ehtcap_ie_get(__eht_cap_mac[EHTCAP_MACBYTE_IDX1], \
8137 EHTCAP_MAC_TXOP_RET_SUPPP_IN_SHARING_MODE2_IDX, \
8138 EHTCAP_MAC_TXOP_RET_SUPPP_IN_SHARING_MODE2_BITS)
8139 #define EHTCAP_MAC_TXOP_RETURN_SUPPORT_SHARE_M2_SET_FROM_IE(__eht_cap_mac, value) \
8140 ehtcap_ie_set(&__eht_cap_mac[EHTCAP_MACBYTE_IDX1], \
8141 EHTCAP_MAC_TXOP_RET_SUPPP_IN_SHARING_MODE2_IDX, \
8142 EHTCAP_MAC_TXOP_RET_SUPPP_IN_SHARING_MODE2_BITS, \
8143 value)
8144
8145 #define EHTCAP_MAC_TWO_BQRS_SUPP_GET_FROM_IE(__eht_cap_mac) \
8146 ehtcap_ie_get(__eht_cap_mac[EHTCAP_MACBYTE_IDX1], \
8147 EHTCAP_MAC_TWO_BQRS_SUPP_IDX, \
8148 EHTCAP_MAC_TWO_BQRS_SUPP_BITS)
8149 #define EHTCAP_MAC_TWO_BQRS_SUPP_SET_FROM_IE(__eht_cap_mac, value) \
8150 ehtcap_ie_set(&__eht_cap_mac[EHTCAP_MACBYTE_IDX1], \
8151 EHTCAP_MAC_TWO_BQRS_SUPP_IDX, \
8152 EHTCAP_MAC_TWO_BQRS_SUPP_BITS, \
8153 value)
8154
8155 #define EHTCAP_MAC_EHT_LINK_ADAPTATION_SUPP_GET_FROM_IE(__eht_cap_mac) \
8156 ehtcap_ie_get(__eht_cap_mac[EHTCAP_MACBYTE_IDX1], \
8157 EHTCAP_MAC_EHT_LINK_ADAPTATION_SUPP_IDX, \
8158 EHTCAP_MAC_EHT_LINK_ADAPTATION_SUPP_BITS)
8159 #define EHTCAP_MAC_EHT_LINK_ADAPTATION_SUPP_SET_FROM_IE(__eht_cap_mac, value) \
8160 ehtcap_ie_set(&__eht_cap_mac[EHTCAP_MACBYTE_IDX1], \
8161 EHTCAP_MAC_EHT_LINK_ADAPTATION_SUPP_IDX, \
8162 EHTCAP_MAC_EHT_LINK_ADAPTATION_SUPP_BITS, \
8163 value)
8164
8165 /* byte 0 */
8166 #define EHTCAP_PHY_320MHZIN6GHZ_GET_FROM_IE(__eht_cap_phy) \
8167 ehtcap_ie_get(__eht_cap_phy[EHTCAP_PHYBYTE_IDX0], \
8168 EHTCAP_PHY_320MHZIN6GHZ_IDX, \
8169 EHTCAP_PHY_320MHZIN6GHZ_BITS)
8170 #define EHTCAP_PHY_320MHZIN6GHZ_SET_TO_IE(__eht_cap_phy, value) \
8171 ehtcap_ie_set(&__eht_cap_phy[EHTCAP_PHYBYTE_IDX0], \
8172 EHTCAP_PHY_320MHZIN6GHZ_IDX, \
8173 EHTCAP_PHY_320MHZIN6GHZ_BITS, value)
8174
8175 #define EHTCAP_PHY_242TONERUBWGT20MHZ_GET_FROM_IE(__eht_cap_phy) \
8176 ehtcap_ie_get(__eht_cap_phy[EHTCAP_PHYBYTE_IDX0], \
8177 EHTCAP_PHY_242TONERUBWLT20MHZ_IDX, \
8178 EHTCAP_PHY_242TONERUBWLT20MHZ_BITS)
8179 #define EHTCAP_PHY_242TONERUBWGT20MHZ_SET_TO_IE(__eht_cap_phy, value) \
8180 ehtcap_ie_set(&__eht_cap_phy[EHTCAP_PHYBYTE_IDX0], \
8181 EHTCAP_PHY_242TONERUBWLT20MHZ_IDX, \
8182 EHTCAP_PHY_242TONERUBWLT20MHZ_BITS, value)
8183
8184 #define EHTCAP_PHY_NDP4XEHTLTFAND320NSGI_GET_FROM_IE(__eht_cap_phy) \
8185 ehtcap_ie_get(__eht_cap_phy[EHTCAP_PHYBYTE_IDX0], \
8186 EHTCAP_PHY_NDP4XEHTLTFAND320NSGI_IDX, \
8187 EHTCAP_PHY_NDP4XEHTLTFAND320NSGI_BITS)
8188 #define EHTCAP_PHY_NDP4XEHTLTFAND320NSGI_SET_TO_IE(__eht_cap_phy, value) \
8189 ehtcap_ie_set(&__eht_cap_phy[EHTCAP_PHYBYTE_IDX0], \
8190 EHTCAP_PHY_NDP4XEHTLTFAND320NSGI_IDX, \
8191 EHTCAP_PHY_NDP4XEHTLTFAND320NSGI_BITS, \
8192 value)
8193
8194 #define EHTCAP_PHY_PARTIALBWULMU_GET_FROM_IE(__eht_cap_phy) \
8195 ehtcap_ie_get(__eht_cap_phy[EHTCAP_PHYBYTE_IDX0], \
8196 EHTCAP_PHY_PARTIALBWULMU_IDX, \
8197 EHTCAP_PHY_PARTIALBWULMU_BITS)
8198 #define EHTCAP_PHY_PARTIALBWULMU_SET_TO_IE(__eht_cap_phy, value) \
8199 ehtcap_ie_set(&__eht_cap_phy[EHTCAP_PHYBYTE_IDX0], \
8200 EHTCAP_PHY_PARTIALBWULMU_IDX, \
8201 EHTCAP_PHY_PARTIALBWULMU_BITS, value)
8202
8203 #define EHTCAP_PHY_SUBFMR_GET_FROM_IE(__eht_cap_phy) \
8204 ehtcap_ie_get(__eht_cap_phy[EHTCAP_PHYBYTE_IDX0], \
8205 EHTCAP_PHY_SUBFMR_IDX, \
8206 EHTCAP_PHY_SUBFMR_BITS)
8207 #define EHTCAP_PHY_SUBFMR_SET_TO_IE(__eht_cap_phy, value) \
8208 ehtcap_ie_set(&__eht_cap_phy[EHTCAP_PHYBYTE_IDX0], \
8209 EHTCAP_PHY_SUBFMR_IDX, \
8210 EHTCAP_PHY_SUBFMR_BITS, value)
8211
8212 #define EHTCAP_PHY_SUBFME_GET_FROM_IE(__eht_cap_phy) \
8213 ehtcap_ie_get(__eht_cap_phy[EHTCAP_PHYBYTE_IDX0], \
8214 EHTCAP_PHY_SUBFME_IDX, \
8215 EHTCAP_PHY_SUBFME_BITS)
8216 #define EHTCAP_PHY_SUBFME_SET_TO_IE(__eht_cap_phy, value) \
8217 ehtcap_ie_set(&__eht_cap_phy[EHTCAP_PHYBYTE_IDX0], \
8218 EHTCAP_PHY_SUBFME_IDX, \
8219 EHTCAP_PHY_SUBFME_BITS, value)
8220
8221 #define EHTCAP_PHY_BFMESSLT80MHZ_GET_FROM_IE_BYTE0(__eht_cap_phy) \
8222 ehtcap_ie_get(__eht_cap_phy[EHTCAP_PHYBYTE_IDX0], \
8223 EHTCAP_PHY_BFMESSLT80MHZ_IDX, \
8224 1)
8225 #define EHTCAP_PHY_BFMESSLT80MHZ_SET_TO_IE_BYTE0(__eht_cap_phy, __value) \
8226 ehtcap_ie_set(&__eht_cap_phy[EHTCAP_PHYBYTE_IDX0], \
8227 EHTCAP_PHY_BFMESSLT80MHZ_IDX, \
8228 1, __value)
8229
8230 /* byte 1 */
8231 #define EHTCAP_PHY_BFMESSLT80MHZ_GET_FROM_IE_BYTE1(__eht_cap_phy) \
8232 ehtcap_ie_get(__eht_cap_phy[EHTCAP_PHYBYTE_IDX1], \
8233 8, \
8234 2)
8235 #define EHTCAP_PHY_BFMESSLT80MHZ_SET_TO_IE_BYTE1(__eht_cap_phy, __value) \
8236 ehtcap_ie_set(&__eht_cap_phy[EHTCAP_PHYBYTE_IDX1], \
8237 8, \
8238 2, __value)
8239 #define EHTCAP_PHY_BFMESS160MHZ_GET_FROM_IE(__eht_cap_phy) \
8240 ehtcap_ie_get(__eht_cap_phy[EHTCAP_PHYBYTE_IDX1], \
8241 EHTCAP_PHY_BFMESS160MHZ_IDX, \
8242 EHTCAP_PHY_BFMESS160MHZ_BITS)
8243 #define EHTCAP_PHY_BFMESS160MHZ_SET_TO_IE(__eht_cap_phy, value) \
8244 ehtcap_ie_set(&__eht_cap_phy[EHTCAP_PHYBYTE_IDX1], \
8245 EHTCAP_PHY_BFMESS160MHZ_IDX, \
8246 EHTCAP_PHY_BFMESS160MHZ_BITS, value)
8247
8248 #define EHTCAP_PHY_BFMESS320MHZ_GET_FROM_IE(__eht_cap_phy) \
8249 ehtcap_ie_get(__eht_cap_phy[EHTCAP_PHYBYTE_IDX1], \
8250 EHTCAP_PHY_BFMESS320MHZ_IDX, \
8251 EHTCAP_PHY_BFMESS320MHZ_BITS)
8252 #define EHTCAP_PHY_BFMESS320MHZ_SET_TO_IE(__eht_cap_phy, value) \
8253 ehtcap_ie_set(&__eht_cap_phy[EHTCAP_PHYBYTE_IDX1], \
8254 EHTCAP_PHY_BFMESS320MHZ_IDX, \
8255 EHTCAP_PHY_BFMESS320MHZ_BITS, value)
8256
8257 /* byte 2 */
8258 #define EHTCAP_PHY_NUMSOUNDLT80MHZ_GET_FROM_IE(__eht_cap_phy) \
8259 ehtcap_ie_get(__eht_cap_phy[EHTCAP_PHYBYTE_IDX2], \
8260 EHTCAP_PHY_NUMSOUNDLT80MHZ_IDX, \
8261 EHTCAP_PHY_NUMSOUNDLT80MHZ_BITS)
8262 #define EHTCAP_PHY_NUMSOUNDLT80MHZ_SET_TO_IE(__eht_cap_phy, value) \
8263 ehtcap_ie_set(&__eht_cap_phy[EHTCAP_PHYBYTE_IDX2], \
8264 EHTCAP_PHY_NUMSOUNDLT80MHZ_IDX, \
8265 EHTCAP_PHY_NUMSOUNDLT80MHZ_BITS, value)
8266
8267 #define EHTCAP_PHY_NUMSOUND160MHZ_GET_FROM_IE(__eht_cap_phy) \
8268 ehtcap_ie_get(__eht_cap_phy[EHTCAP_PHYBYTE_IDX2], \
8269 EHTCAP_PHY_NUMSOUND160MHZ_IDX, \
8270 EHTCAP_PHY_NUMSOUND160MHZ_BITS)
8271 #define EHTCAP_PHY_NUMSOUND160MHZ_SET_TO_IE(__eht_cap_phy, value) \
8272 ehtcap_ie_set(&__eht_cap_phy[EHTCAP_PHYBYTE_IDX2], \
8273 EHTCAP_PHY_NUMSOUND160MHZ_IDX, \
8274 EHTCAP_PHY_NUMSOUND160MHZ_BITS, value)
8275
8276 #define EHTCAP_PHY_NUMSOUND320MHZ_GET_FROM_IE(__eht_cap_phy) \
8277 ehtcap_ie_get(__eht_cap_phy[EHTCAP_PHYBYTE_IDX2], \
8278 EHTCAP_PHY_NUMSOUND320MHZ_IDX, \
8279 EHTCAP_PHY_NUMSOUND320MHZ_BITS)
8280 #define EHTCAP_PHY_NUMSOUND320MHZ_SET_TO_IE(__eht_cap_phy, value) \
8281 ehtcap_ie_set(&__eht_cap_phy[EHTCAP_PHYBYTE_IDX2], \
8282 EHTCAP_PHY_NUMSOUND320MHZ_IDX, \
8283 EHTCAP_PHY_NUMSOUND320MHZ_BITS, value)
8284
8285 /* byte 3 */
8286 #define EHTCAP_PHY_NG16SUFB_GET_FROM_IE(__eht_cap_phy) \
8287 ehtcap_ie_get(__eht_cap_phy[EHTCAP_PHYBYTE_IDX3], \
8288 EHTCAP_PHY_NG16SUFB_IDX, \
8289 EHTCAP_PHY_NG16SUFB_BITS)
8290 #define EHTCAP_PHY_NG16SUFB_SET_TO_IE(__eht_cap_phy, value) \
8291 ehtcap_ie_set(&__eht_cap_phy[EHTCAP_PHYBYTE_IDX3], \
8292 EHTCAP_PHY_NG16SUFB_IDX, \
8293 EHTCAP_PHY_NG16SUFB_BITS, value)
8294
8295 #define EHTCAP_PHY_NG16MUFB_GET_FROM_IE(__eht_cap_phy) \
8296 ehtcap_ie_get(__eht_cap_phy[EHTCAP_PHYBYTE_IDX3], \
8297 EHTCAP_PHY_NG16MUFB_IDX, \
8298 EHTCAP_PHY_NG16MUFB_BITS)
8299 #define EHTCAP_PHY_NG16MUFB_SET_TO_IE(__eht_cap_phy, value) \
8300 ehtcap_ie_set(&__eht_cap_phy[EHTCAP_PHYBYTE_IDX3], \
8301 EHTCAP_PHY_NG16MUFB_IDX, \
8302 EHTCAP_PHY_NG16MUFB_BITS, value)
8303
8304 #define EHTCAP_PHY_CODBK42SUFB_GET_FROM_IE(__eht_cap_phy) \
8305 ehtcap_ie_get(__eht_cap_phy[EHTCAP_PHYBYTE_IDX3], \
8306 EHTCAP_PHY_CODBK42SUFB_IDX, \
8307 EHTCAP_PHY_CODBK42SUFB_BITS)
8308 #define EHTCAP_PHY_CODBK42SUFB_SET_TO_IE(__eht_cap_phy, value) \
8309 ehtcap_ie_set(&__eht_cap_phy[EHTCAP_PHYBYTE_IDX3], \
8310 EHTCAP_PHY_CODBK42SUFB_IDX, \
8311 EHTCAP_PHY_CODBK42SUFB_BITS, value)
8312
8313 #define EHTCAP_PHY_CODBK75MUFB_GET_FROM_IE(__eht_cap_phy) \
8314 ehtcap_ie_get(__eht_cap_phy[EHTCAP_PHYBYTE_IDX3], \
8315 EHTCAP_PHY_CODBK75MUFB_IDX, \
8316 EHTCAP_PHY_CODBK75MUFB_BITS)
8317 #define EHTCAP_PHY_CODBK75MUFB_SET_TO_IE(__eht_cap_phy, value) \
8318 ehtcap_ie_set(&__eht_cap_phy[EHTCAP_PHYBYTE_IDX3], \
8319 EHTCAP_PHY_CODBK75MUFB_IDX, \
8320 EHTCAP_PHY_CODBK75MUFB_BITS, value)
8321
8322 #define EHTCAP_PHY_TRIGSUBFFB_GET_FROM_IE(__eht_cap_phy) \
8323 ehtcap_ie_get(__eht_cap_phy[EHTCAP_PHYBYTE_IDX3], \
8324 EHTCAP_PHY_TRIGSUBFFB_IDX, \
8325 EHTCAP_PHY_TRIGSUBFFB_BITS)
8326 #define EHTCAP_PHY_TRIGSUBFFB_SET_TO_IE(__eht_cap_phy, value) \
8327 ehtcap_ie_set(&__eht_cap_phy[EHTCAP_PHYBYTE_IDX3], \
8328 EHTCAP_PHY_TRIGSUBFFB_IDX, \
8329 EHTCAP_PHY_TRIGSUBFFB_BITS, value)
8330
8331 #define EHTCAP_PHY_TRIGMUBFPARTBWFB_GET_FROM_IE(__eht_cap_phy) \
8332 ehtcap_ie_get(__eht_cap_phy[EHTCAP_PHYBYTE_IDX3], \
8333 EHTCAP_PHY_TRIGMUBFPARTBWFB_IDX, \
8334 EHTCAP_PHY_TRIGMUBFPARTBWFB_BITS)
8335 #define EHTCAP_PHY_TRIGMUBFPARTBWFB_SET_TO_IE(__eht_cap_phy, value) \
8336 ehtcap_ie_set(&__eht_cap_phy[EHTCAP_PHYBYTE_IDX3], \
8337 EHTCAP_PHY_TRIGMUBFPARTBWFB_IDX, \
8338 EHTCAP_PHY_TRIGMUBFPARTBWFB_BITS, value)
8339
8340 #define EHTCAP_PHY_TRIGCQIFB_GET_FROM_IE(__eht_cap_phy) \
8341 ehtcap_ie_get(__eht_cap_phy[EHTCAP_PHYBYTE_IDX3], \
8342 EHTCAP_PHY_TRIGCQIFB_IDX, \
8343 EHTCAP_PHY_TRIGCQIFB_BITS)
8344 #define EHTCAP_PHY_TRIGCQIFB_SET_TO_IE(__eht_cap_phy, value) \
8345 ehtcap_ie_set(&__eht_cap_phy[EHTCAP_PHYBYTE_IDX3], \
8346 EHTCAP_PHY_TRIGCQIFB_IDX, \
8347 EHTCAP_PHY_TRIGCQIFB_BITS, value)
8348
8349 /* byte 4 */
8350 #define EHTCAP_PHY_PARTBWDLMUMIMO_GET_FROM_IE(__eht_cap_phy) \
8351 ehtcap_ie_get(__eht_cap_phy[EHTCAP_PHYBYTE_IDX4], \
8352 EHTCAP_PHY_PARTBWDLMUMIMO_IDX, \
8353 EHTCAP_PHY_PARTBWDLMUMIMO_BITS)
8354 #define EHTCAP_PHY_PARTBWDLMUMIMO_SET_TO_IE(__eht_cap_phy, value) \
8355 ehtcap_ie_set(&__eht_cap_phy[EHTCAP_PHYBYTE_IDX4], \
8356 EHTCAP_PHY_PARTBWDLMUMIMO_IDX, \
8357 EHTCAP_PHY_PARTBWDLMUMIMO_BITS, value)
8358
8359 #define EHTCAP_PHY_PSRSR_GET_FROM_IE(__eht_cap_phy) \
8360 ehtcap_ie_get(__eht_cap_phy[EHTCAP_PHYBYTE_IDX4], \
8361 EHTCAP_PHY_PSRSR_IDX, \
8362 EHTCAP_PHY_PSRSR_BITS)
8363 #define EHTCAP_PHY_PSRSR_SET_TO_IE(__eht_cap_phy, value) \
8364 ehtcap_ie_set(&__eht_cap_phy[EHTCAP_PHYBYTE_IDX4], \
8365 EHTCAP_PHY_PSRSR_IDX, \
8366 EHTCAP_PHY_PSRSR_BITS, value)
8367
8368 #define EHTCAP_PHY_PWRBSTFACTOR_GET_FROM_IE(__eht_cap_phy) \
8369 ehtcap_ie_get(__eht_cap_phy[EHTCAP_PHYBYTE_IDX4], \
8370 EHTCAP_PHY_PWRBSTFACTOR_IDX, \
8371 EHTCAP_PHY_PWRBSTFACTOR_BITS)
8372 #define EHTCAP_PHY_PWRBSTFACTOR_SET_TO_IE(__eht_cap_phy, value) \
8373 ehtcap_ie_set(&__eht_cap_phy[EHTCAP_PHYBYTE_IDX4], \
8374 EHTCAP_PHY_PWRBSTFACTOR_IDX, \
8375 EHTCAP_PHY_PWRBSTFACTOR_BITS, value)
8376
8377 #define EHTCAP_PHY_4XEHTMULTFAND800NSGI_GET_FROM_IE(__eht_cap_phy) \
8378 ehtcap_ie_get(__eht_cap_phy[EHTCAP_PHYBYTE_IDX4], \
8379 EHTCAP_PHY_4XEHTLTFAND800NSGI_IDX, \
8380 EHTCAP_PHY_4XEHTLTFAND800NSGI_BITS)
8381 #define EHTCAP_PHY_4XEHTMULTFAND800NSGI_SET_TO_IE(__eht_cap_phy, value) \
8382 ehtcap_ie_set(&__eht_cap_phy[EHTCAP_PHYBYTE_IDX4], \
8383 EHTCAP_PHY_4XEHTLTFAND800NSGI_IDX, \
8384 EHTCAP_PHY_4XEHTLTFAND800NSGI_BITS, value)
8385
8386 #define EHTCAP_PHY_MAXNC_GET_FROM_IE(__eht_cap_phy) \
8387 ehtcap_ie_get(__eht_cap_phy[EHTCAP_PHYBYTE_IDX4], \
8388 EHTCAP_PHY_MAXNC_IDX, \
8389 EHTCAP_PHY_MAXNC_BITS)
8390 #define EHTCAP_PHY_MAXNC_SET_TO_IE(__eht_cap_phy, value) \
8391 ehtcap_ie_set(&__eht_cap_phy[EHTCAP_PHYBYTE_IDX4], \
8392 EHTCAP_PHY_MAXNC_IDX, \
8393 EHTCAP_PHY_MAXNC_BITS, value)
8394
8395 /* byte 5 */
8396 #define EHTCAP_PHY_NONTRIGCQIFB_GET_FROM_IE(__eht_cap_phy) \
8397 ehtcap_ie_get(__eht_cap_phy[EHTCAP_PHYBYTE_IDX5], \
8398 EHTCAP_PHY_NONTRIGCQIFB_IDX, \
8399 EHTCAP_PHY_NONTRIGCQIFB_BITS)
8400 #define EHTCAP_PHY_NONTRIGCQIFB_SET_TO_IE(__eht_cap_phy, value) \
8401 ehtcap_ie_set(&__eht_cap_phy[EHTCAP_PHYBYTE_IDX5], \
8402 EHTCAP_PHY_NONTRIGCQIFB_IDX, \
8403 EHTCAP_PHY_NONTRIGCQIFB_BITS, value)
8404
8405 #define EHTCAP_PHY_TX1024AND4096QAMLT242TONERU_GET_FROM_IE(__eht_cap_phy) \
8406 ehtcap_ie_get(__eht_cap_phy[EHTCAP_PHYBYTE_IDX5], \
8407 EHTCAP_PHY_TX1024AND4096QAMLS242TONERU_IDX, \
8408 EHTCAP_PHY_TX1024AND4096QAMLS242TONERU_BITS)
8409 #define EHTCAP_PHY_TX1024AND4096QAMLT242TONERU_SET_TO_IE(__eht_cap_phy, value) \
8410 ehtcap_ie_set(&__eht_cap_phy[EHTCAP_PHYBYTE_IDX5], \
8411 EHTCAP_PHY_TX1024AND4096QAMLS242TONERU_IDX, \
8412 EHTCAP_PHY_TX1024AND4096QAMLS242TONERU_BITS, \
8413 value)
8414
8415 #define EHTCAP_PHY_RX1024AND4096QAMLT242TONERU_GET_FROM_IE(__eht_cap_phy) \
8416 ehtcap_ie_get(__eht_cap_phy[EHTCAP_PHYBYTE_IDX5], \
8417 EHTCAP_PHY_RX1024AND4096QAMLS242TONERU_IDX, \
8418 EHTCAP_PHY_RX1024AND4096QAMLS242TONERU_BITS)
8419 #define EHTCAP_PHY_RX1024AND4096QAMLT242TONERU_SET_TO_IE(__eht_cap_phy, value) \
8420 ehtcap_ie_set(&__eht_cap_phy[EHTCAP_PHYBYTE_IDX5], \
8421 EHTCAP_PHY_RX1024AND4096QAMLS242TONERU_IDX, \
8422 EHTCAP_PHY_RX1024AND4096QAMLS242TONERU_BITS, \
8423 value)
8424
8425 #define EHTCAP_PHY_PPETHRESPRESENT_GET_FROM_IE(__eht_cap_phy) \
8426 ehtcap_ie_get(__eht_cap_phy[EHTCAP_PHYBYTE_IDX5], \
8427 EHTCAP_PHY_PPETHRESPRESENT_IDX, \
8428 EHTCAP_PHY_PPETHRESPRESENT_BITS)
8429 #define EHTCAP_PHY_PPETHRESPRESENT_SET_TO_IE(__eht_cap_phy, value) \
8430 ehtcap_ie_set(&__eht_cap_phy[EHTCAP_PHYBYTE_IDX5], \
8431 EHTCAP_PHY_PPETHRESPRESENT_IDX, \
8432 EHTCAP_PHY_PPETHRESPRESENT_BITS, value)
8433
8434 #define EHTCAP_PHY_CMNNOMPKTPAD_GET_FROM_IE(__eht_cap_phy) \
8435 ehtcap_ie_get(__eht_cap_phy[EHTCAP_PHYBYTE_IDX5], \
8436 EHTCAP_PHY_CMNNOMPKTPAD_IDX, \
8437 EHTCAP_PHY_CMNNOMPKTPAD_BITS)
8438 #define EHTCAP_PHY_CMNNOMPKTPAD_SET_TO_IE(__eht_cap_phy, value) \
8439 ehtcap_ie_set(&__eht_cap_phy[EHTCAP_PHYBYTE_IDX5], \
8440 EHTCAP_PHY_CMNNOMPKTPAD_IDX, \
8441 EHTCAP_PHY_CMNNOMPKTPAD_BITS, value)
8442
8443 #define EHTCAP_PHY_MAXNUMEHTLTF_GET_FROM_IE(__eht_cap_phy) \
8444 ehtcap_ie_get(__eht_cap_phy[EHTCAP_PHYBYTE_IDX5], \
8445 EHTCAP_PHY_MAXNUMEHTLTF_IDX, \
8446 EHTCAP_PHY_MAXNUMEHTLTF_BITS)
8447 #define EHTCAP_PHY_MAXNUMEHTLTF_SET_TO_IE(__eht_cap_phy, value) \
8448 ehtcap_ie_set(&__eht_cap_phy[EHTCAP_PHYBYTE_IDX5], \
8449 EHTCAP_PHY_MAXNUMEHTLTF_IDX, \
8450 EHTCAP_PHY_MAXNUMEHTLTF_BITS, value)
8451
8452 /* byte 6 */
8453 #define EHTCAP_PHY_SUPMCS15_GET_FROM_IE(__eht_cap_phy) \
8454 ehtcap_ie_get(__eht_cap_phy[EHTCAP_PHYBYTE_IDX6], \
8455 EHTCAP_PHY_SUPMCS15_IDX, \
8456 EHTCAP_PHY_SUPMCS15_BITS)
8457 #define EHTCAP_PHY_SUPMCS15_SET_TO_IE(__eht_cap_phy, value) \
8458 ehtcap_ie_set(&__eht_cap_phy[EHTCAP_PHYBYTE_IDX6], \
8459 EHTCAP_PHY_SUPMCS15_IDX, \
8460 EHTCAP_PHY_SUPMCS15_BITS, value)
8461
8462 #define EHTCAP_PHY_EHTDUPIN6GHZ_GET_FROM_IE(__eht_cap_phy) \
8463 ehtcap_ie_get(__eht_cap_phy[EHTCAP_PHYBYTE_IDX6], \
8464 EHTCAP_PHY_EHTDUPIN6GHZ_IDX, \
8465 EHTCAP_PHY_EHTDUPIN6GHZ_BITS)
8466 #define EHTCAP_PHY_EHTDUPIN6GHZ_SET_TO_IE(__eht_cap_phy, value) \
8467 ehtcap_ie_set(&__eht_cap_phy[EHTCAP_PHYBYTE_IDX6], \
8468 EHTCAP_PHY_EHTDUPIN6GHZ_IDX, \
8469 EHTCAP_PHY_EHTDUPIN6GHZ_BITS, value)
8470
8471 /* byte 7 */
8472 #define EHTCAP_PHY_20MHZOPSTARXNDPWIDERBW_GET_FROM_IE(__eht_cap_phy) \
8473 ehtcap_ie_get(__eht_cap_phy[EHTCAP_PHYBYTE_IDX7], \
8474 EHTCAP_PHY_20MHZOPSTARXNDPWIDERBW_IDX, \
8475 EHTCAP_PHY_20MHZOPSTARXNDPWIDERBW_BITS)
8476 #define EHTCAP_PHY_20MHZOPSTARXNDPWIDERBW_SET_TO_IE(__eht_cap_phy, value) \
8477 ehtcap_ie_set(&__eht_cap_phy[EHTCAP_PHYBYTE_IDX7], \
8478 EHTCAP_PHY_20MHZOPSTARXNDPWIDERBW_IDX, \
8479 EHTCAP_PHY_20MHZOPSTARXNDPWIDERBW_BITS, \
8480 value)
8481
8482 #define EHTCAP_PHY_NONOFDMAULMUMIMOLT80MHZ_GET_FROM_IE(__eht_cap_phy) \
8483 ehtcap_ie_get(__eht_cap_phy[EHTCAP_PHYBYTE_IDX7], \
8484 EHTCAP_PHY_NONOFDMAULMUMIMOLT80MHZ_IDX, \
8485 EHTCAP_PHY_NONOFDMAULMUMIMOLT80MHZ_BITS)
8486 #define EHTCAP_PHY_NONOFDMAULMUMIMOLT80MHZ_SET_TO_IE(__eht_cap_phy, value) \
8487 ehtcap_ie_set(&__eht_cap_phy[EHTCAP_PHYBYTE_IDX7], \
8488 EHTCAP_PHY_NONOFDMAULMUMIMOLT80MHZ_IDX, \
8489 EHTCAP_PHY_NONOFDMAULMUMIMOLT80MHZ_BITS, \
8490 value)
8491
8492 #define EHTCAP_PHY_NONOFDMAULMUMIMO160MHZ_GET_FROM_IE(__eht_cap_phy) \
8493 ehtcap_ie_get(__eht_cap_phy[EHTCAP_PHYBYTE_IDX7], \
8494 EHTCAP_PHY_NONOFDMAULMUMIMO160MHZ_IDX, \
8495 EHTCAP_PHY_NONOFDMAULMUMIMO160MHZ_BITS)
8496 #define EHTCAP_PHY_NONOFDMAULMUMIMO160MHZ_SET_TO_IE(__eht_cap_phy, value) \
8497 ehtcap_ie_set(&__eht_cap_phy[EHTCAP_PHYBYTE_IDX7], \
8498 EHTCAP_PHY_NONOFDMAULMUMIMO160MHZ_IDX, \
8499 EHTCAP_PHY_NONOFDMAULMUMIMO160MHZ_BITS, \
8500 value)
8501
8502 #define EHTCAP_PHY_NONOFDMAULMUMIMO320MHZ_GET_FROM_IE(__eht_cap_phy) \
8503 ehtcap_ie_get(__eht_cap_phy[EHTCAP_PHYBYTE_IDX7], \
8504 EHTCAP_PHY_NONOFDMAULMUMIMO320MHZ_IDX, \
8505 EHTCAP_PHY_NONOFDMAULMUMIMO320MHZ_BITS)
8506 #define EHTCAP_PHY_NONOFDMAULMUMIMO320MHZ_SET_TO_IE(__eht_cap_phy, value) \
8507 ehtcap_ie_set(&__eht_cap_phy[EHTCAP_PHYBYTE_IDX7], \
8508 EHTCAP_PHY_NONOFDMAULMUMIMO320MHZ_IDX, \
8509 EHTCAP_PHY_NONOFDMAULMUMIMO320MHZ_BITS, \
8510 value)
8511
8512 #define EHTCAP_PHY_MUBFMRLT80MHZ_GET_FROM_IE(__eht_cap_phy) \
8513 ehtcap_ie_get(__eht_cap_phy[EHTCAP_PHYBYTE_IDX7], \
8514 EHTCAP_PHY_MUBFMRLT80MHZ_IDX, \
8515 EHTCAP_PHY_MUBFMRLT80MHZ_BITS)
8516 #define EHTCAP_PHY_MUBFMRLT80MHZ_SET_TO_IE(__eht_cap_phy, value) \
8517 ehtcap_ie_set(&__eht_cap_phy[EHTCAP_PHYBYTE_IDX7], \
8518 EHTCAP_PHY_MUBFMRLT80MHZ_IDX, \
8519 EHTCAP_PHY_MUBFMRLT80MHZ_BITS, value)
8520
8521 #define EHTCAP_PHY_MUBFMR160MHZ_GET_FROM_IE(__eht_cap_phy) \
8522 ehtcap_ie_get(__eht_cap_phy[EHTCAP_PHYBYTE_IDX7], \
8523 EHTCAP_PHY_MUBFMR160MHZ_IDX, \
8524 EHTCAP_PHY_MUBFMR160MHZ_BITS)
8525 #define EHTCAP_PHY_MUBFMR160MHZ_SET_TO_IE(__eht_cap_phy, value) \
8526 ehtcap_ie_set(&__eht_cap_phy[EHTCAP_PHYBYTE_IDX7], \
8527 EHTCAP_PHY_MUBFMR160MHZ_IDX, \
8528 EHTCAP_PHY_MUBFMR160MHZ_BITS, value)
8529
8530 #define EHTCAP_PHY_MUBFMR320MHZ_GET_FROM_IE(__eht_cap_phy) \
8531 ehtcap_ie_get(__eht_cap_phy[EHTCAP_PHYBYTE_IDX7], \
8532 EHTCAP_PHY_MUBFMR320MHZ_IDX, \
8533 EHTCAP_PHY_MUBFMR320MHZ_BITS)
8534 #define EHTCAP_PHY_MUBFMR320MHZ_SET_TO_IE(__eht_cap_phy, value) \
8535 ehtcap_ie_set(&__eht_cap_phy[EHTCAP_PHYBYTE_IDX7], \
8536 EHTCAP_PHY_MUBFMR320MHZ_IDX, \
8537 EHTCAP_PHY_MUBFMR320MHZ_BITS, value)
8538
8539 #define EHTCAP_PHY_TB_SOUNDING_FB_RL_GET_FROM_IE(__eht_cap_phy) \
8540 ehtcap_ie_get(__eht_cap_phy[EHTCAP_PHYBYTE_IDX7], \
8541 EHTCAP_PHY_TB_SOUNDING_FEEDBACK_RL_IDX, \
8542 EHTCAP_PHY_TB_SOUNDING_FEEDBACK_RL_BITS)
8543 #define EHTCAP_PHY_TB_SOUNDING_FB_RL_SET_TO_IE(__eht_cap_phy, value) \
8544 ehtcap_ie_set(&__eht_cap_phy[EHTCAP_PHYBYTE_IDX7], \
8545 EHTCAP_PHY_TB_SOUNDING_FEEDBACK_RL_IDX, \
8546 EHTCAP_PHY_TB_SOUNDING_FEEDBACK_RL_BITS, \
8547 value)
8548 #define EHTCAP_PHY_RX_1K_QAM_IN_WIDER_BW_DL_OFDMA_GET_FROM_IE(__eht_cap_phy) \
8549 ehtcap_ie_get(__eht_cap_phy[EHTCAP_PHYBYTE_IDX8], \
8550 EHTCAP_PHY_RX_1K_QAM_IN_WIDER_BW_DL_OFDMA_IDX, \
8551 EHTCAP_PHY_RX_1K_QAM_IN_WIDER_BW_DL_OFDMA_BITS)
8552 #define EHTCAP_PHY_RX_1K_QAM_IN_WIDER_BW_DL_OFDMA_SET_TO_IE(__eht_cap_phy, value) \
8553 ehtcap_ie_set(&__eht_cap_phy[EHTCAP_PHYBYTE_IDX8], \
8554 EHTCAP_PHY_RX_1K_QAM_IN_WIDER_BW_DL_OFDMA_IDX, \
8555 EHTCAP_PHY_RX_1K_QAM_IN_WIDER_BW_DL_OFDMA_BITS, \
8556 value)
8557
8558 #define EHTCAP_PHY_RX_4K_QAM_IN_WIDER_BW_DL_OFDMA_GET_FROM_IE(__eht_cap_phy) \
8559 ehtcap_ie_get(__eht_cap_phy[EHTCAP_PHYBYTE_IDX8], \
8560 EHTCAP_PHY_RX_4K_QAM_IN_WIDER_BW_DL_OFDMA_IDX, \
8561 EHTCAP_PHY_RX_4K_QAM_IN_WIDER_BW_DL_OFDMA_BITS)
8562 #define EHTCAP_PHY_RX_4K_QAM_IN_WIDER_BW_DL_OFDMA_SET_TO_IE(__eht_cap_phy, value) \
8563 ehtcap_ie_set(&__eht_cap_phy[EHTCAP_PHYBYTE_IDX8], \
8564 EHTCAP_PHY_RX_4K_QAM_IN_WIDER_BW_DL_OFDMA_IDX, \
8565 EHTCAP_PHY_RX_4K_QAM_IN_WIDER_BW_DL_OFDMA_BITS, \
8566 value)
8567
8568 #define EHTCAP_PHY_20MHZ_ONLY_CAPS_GET_FROM_IE(__eht_cap_phy) \
8569 ehtcap_ie_get(__eht_cap_phy[EHTCAP_PHYBYTE_IDX8], \
8570 EHTCAP_PHY_20MHZ_ONLY_CAPS_IDX, \
8571 EHTCAP_PHY_20MHZ_ONLY_CAPS_BITS)
8572 #define EHTCAP_PHY_20MHZ_ONLY_CAPS_SET_TO_IE(__eht_cap_phy, value) \
8573 ehtcap_ie_set(&__eht_cap_phy[EHTCAP_PHYBYTE_IDX8], \
8574 EHTCAP_PHY_20MHZ_ONLY_CAPS_IDX, \
8575 EHTCAP_PHY_20MHZ_ONLY_CAPS_BITS, \
8576 value)
8577
8578 #define EHTCAP_PHY_20MHZ_ONLY_TRIGGER_MUBF_FULL_BW_FB_AND_DLMUMIMO_GET_FROM_IE(__eht_cap_phy) \
8579 ehtcap_ie_get(__eht_cap_phy[EHTCAP_PHYBYTE_IDX8], \
8580 EHTCAP_PHY_20MHZ_ONLY_TRIGGER_MUBF_FL_BW_FB_DLMUMIMO_IDX, \
8581 EHTCAP_PHY_20MHZ_ONLY_TRIGGER_MUBF_FL_BW_FB_DLMUMIMO_BITS)
8582
8583 #define EHTCAP_PHY_20MHZ_ONLY_TRIGGER_MUBF_FULL_BW_FB_AND_DLMUMIMO_SET_TO_IE(__eht_cap_phy, value) \
8584 ehtcap_ie_set(&__eht_cap_phy[EHTCAP_PHYBYTE_IDX8], \
8585 EHTCAP_PHY_20MHZ_ONLY_TRIGGER_MUBF_FL_BW_FB_DLMUMIMO_IDX, \
8586 EHTCAP_PHY_20MHZ_ONLY_TRIGGER_MUBF_FL_BW_FB_DLMUMIMO_BITS, \
8587 value)
8588
8589 #define EHTCAP_PHY_20MHZ_ONLY_MRU_SUPP_GET_FROM_IE(__eht_cap_phy) \
8590 ehtcap_ie_get(__eht_cap_phy[EHTCAP_PHYBYTE_IDX8], \
8591 EHTCAP_PHY_20MHZ_ONLY_MRU_SUPP_IDX, \
8592 EHTCAP_PHY_20MHZ_ONLY_MRU_SUPP_BITS)
8593 #define EHTCAP_PHY_20MHZ_ONLY_MRU_SUPP_SET_TO_IE(__eht_cap_phy, value) \
8594 ehtcap_ie_set(&__eht_cap_phy[EHTCAP_PHYBYTE_IDX8], \
8595 EHTCAP_PHY_20MHZ_ONLY_MRU_SUPP_IDX, \
8596 EHTCAP_PHY_20MHZ_ONLY_MRU_SUPP_BITS, \
8597 value)
8598 static
8599 QDF_STATUS lim_ieee80211_unpack_ehtop(const uint8_t *eht_op_ie,
8600 tDot11fIEeht_op *dot11f_eht_op,
8601 tDot11fIEVHTOperation dot11f_vht_op,
8602 tDot11fIEhe_op dot11f_he_op,
8603 tDot11fIEHTInfo dot11f_ht_info)
8604 {
8605 struct wlan_ie_ehtops *ehtop = (struct wlan_ie_ehtops *)eht_op_ie;
8606 uint8_t i;
8607
8608 if (!eht_op_ie || !(ehtop->elem_id == DOT11F_EID_EHT_OP &&
8609 ehtop->elem_id_extn == 0x6a)) {
8610 pe_err("Invalid EHT op IE");
8611 return QDF_STATUS_E_INVAL;
8612 }
8613
8614 qdf_mem_zero(dot11f_eht_op, (sizeof(tDot11fIEeht_op)));
8615
8616 dot11f_eht_op->present = 1;
8617 dot11f_eht_op->eht_op_information_present =
8618 EHTOP_PARAMS_INFOP_GET_FROM_IE(ehtop->ehtop_param);
8619
8620 dot11f_eht_op->disabled_sub_chan_bitmap_present =
8621 EHTOP_PARAMS_DISABLEDSUBCHANBITMAPP_GET_FROM_IE(
8622 ehtop->ehtop_param);
8623
8624 dot11f_eht_op->eht_default_pe_duration =
8625 EHTOP_PARAMS_EHT_DEF_PE_DURATION_GET_FROM_IE(
8626 ehtop->ehtop_param);
8627
8628 dot11f_eht_op->group_addr_bu_indication_limit =
8629 EHTOP_PARAMS_GROUP_ADDR_BU_IND_LIMIT_GET_FROM_IE(
8630 ehtop->ehtop_param);
8631
8632 dot11f_eht_op->group_addr_bu_indication_exponent =
8633 EHTOP_PARAMS_GROUP_ADDR_BU_IND_EXPONENT_GET_FROM_IE(
8634 ehtop->ehtop_param);
8635
8636 dot11f_eht_op->basic_rx_max_nss_for_mcs_0_to_7 =
8637 ehtop_ie_get(ehtop->basic_mcs_nss_set.max_nss_mcs_0_7,
8638 EHTOP_RX_MCS_NSS_MAP_IDX,
8639 EHTOP_RX_MCS_NSS_MAP_BITS);
8640 dot11f_eht_op->basic_tx_max_nss_for_mcs_0_to_7 =
8641 ehtop_ie_get(ehtop->basic_mcs_nss_set.max_nss_mcs_0_7,
8642 EHTOP_TX_MCS_NSS_MAP_IDX,
8643 EHTOP_TX_MCS_NSS_MAP_BITS);
8644 dot11f_eht_op->basic_rx_max_nss_for_mcs_8_and_9 =
8645 ehtop_ie_get(ehtop->basic_mcs_nss_set.max_nss_mcs_8_9,
8646 EHTOP_RX_MCS_NSS_MAP_IDX,
8647 EHTOP_RX_MCS_NSS_MAP_BITS);
8648 dot11f_eht_op->basic_tx_max_nss_for_mcs_8_and_9 =
8649 ehtop_ie_get(ehtop->basic_mcs_nss_set.max_nss_mcs_8_9,
8650 EHTOP_TX_MCS_NSS_MAP_IDX,
8651 EHTOP_TX_MCS_NSS_MAP_BITS);
8652 dot11f_eht_op->basic_rx_max_nss_for_mcs_10_and_11 =
8653 ehtop_ie_get(ehtop->basic_mcs_nss_set.max_nss_mcs_10_11,
8654 EHTOP_RX_MCS_NSS_MAP_IDX,
8655 EHTOP_RX_MCS_NSS_MAP_BITS);
8656 dot11f_eht_op->basic_tx_max_nss_for_mcs_10_and_11 =
8657 ehtop_ie_get(ehtop->basic_mcs_nss_set.max_nss_mcs_10_11,
8658 EHTOP_TX_MCS_NSS_MAP_IDX,
8659 EHTOP_TX_MCS_NSS_MAP_BITS);
8660 dot11f_eht_op->basic_rx_max_nss_for_mcs_12_and_13 =
8661 ehtop_ie_get(ehtop->basic_mcs_nss_set.max_nss_mcs_12_13,
8662 EHTOP_RX_MCS_NSS_MAP_IDX,
8663 EHTOP_RX_MCS_NSS_MAP_BITS);
8664 dot11f_eht_op->basic_tx_max_nss_for_mcs_12_and_13 =
8665 ehtop_ie_get(ehtop->basic_mcs_nss_set.max_nss_mcs_12_13,
8666 EHTOP_TX_MCS_NSS_MAP_IDX,
8667 EHTOP_TX_MCS_NSS_MAP_BITS);
8668
8669 if (dot11f_eht_op->eht_op_information_present) {
8670 dot11f_eht_op->channel_width =
8671 EHTOP_INFO_CHANWIDTH_GET_FROM_IE(ehtop->control);
8672
8673 dot11f_eht_op->ccfs0 = ehtop->ccfs0;
8674
8675 dot11f_eht_op->ccfs1 = ehtop->ccfs1;
8676
8677 if (dot11f_eht_op->disabled_sub_chan_bitmap_present) {
8678 for (i = 0; i < WLAN_MAX_DISABLED_SUB_CHAN_BITMAP;
8679 i++) {
8680 dot11f_eht_op->disabled_sub_chan_bitmap[0][i] =
8681 ehtop->disabled_sub_chan_bitmap[i];
8682 }
8683 }
8684 }
8685
8686 return QDF_STATUS_SUCCESS;
8687 }
8688
8689 static
8690 QDF_STATUS lim_ieee80211_unpack_ehtcap(const uint8_t *eht_cap_ie,
8691 tDot11fIEeht_cap *dot11f_eht_cap,
8692 tDot11fIEhe_cap dot11f_he_cap,
8693 bool is_band_2g)
8694 {
8695 struct wlan_ie_ehtcaps *ehtcap = (struct wlan_ie_ehtcaps *)eht_cap_ie;
8696 uint32_t idx = 0;
8697 uint32_t mcs_map_len;
8698
8699 if (!eht_cap_ie || !(ehtcap->elem_id == DOT11F_EID_EHT_CAP &&
8700 ehtcap->elem_id_extn == 0x6c)) {
8701 pe_err("Invalid EHT cap IE");
8702 return QDF_STATUS_E_INVAL;
8703 }
8704
8705 qdf_mem_zero(dot11f_eht_cap, (sizeof(tDot11fIEeht_cap)));
8706
8707 dot11f_eht_cap->present = 1;
8708 dot11f_eht_cap->epcs_pri_access =
8709 EHTCAP_MAC_EPCSPRIACCESS_GET_FROM_IE(ehtcap->eht_mac_cap);
8710
8711 dot11f_eht_cap->eht_om_ctl =
8712 EHTCAP_MAC_EHTOMCTRL_GET_FROM_IE(ehtcap->eht_mac_cap);
8713
8714 dot11f_eht_cap->triggered_txop_sharing_mode1 =
8715 EHTCAP_MAC_TRIGTXOP_MODE1_GET_FROM_IE(ehtcap->eht_mac_cap);
8716
8717 dot11f_eht_cap->triggered_txop_sharing_mode2 =
8718 EHTCAP_MAC_TRIGTXOP_MODE2_GET_FROM_IE(ehtcap->eht_mac_cap);
8719
8720 dot11f_eht_cap->restricted_twt =
8721 EHTCAP_MAC_RESTRICTED_TWT_GET_FROM_IE(ehtcap->eht_mac_cap);
8722
8723 dot11f_eht_cap->scs_traffic_desc =
8724 EHTCAP_MAC_SCS_TRAFFIC_DESC_GET_FROM_IE(ehtcap->eht_mac_cap);
8725
8726 dot11f_eht_cap->max_mpdu_len =
8727 EHTCAP_MAC_MAX_MPDU_LEN_GET_FROM_IE(ehtcap->eht_mac_cap);
8728
8729 dot11f_eht_cap->max_a_mpdu_len_exponent_ext =
8730 EHTCAP_MAC_MAX_A_MPDU_LEN_EXPONENT_EXT_GET_FROM_IE(
8731 ehtcap->eht_mac_cap);
8732
8733 dot11f_eht_cap->eht_trs_support =
8734 EHTCAP_MAC_EHT_TRS_SUPPORT_GET_FROM_IE(ehtcap->eht_mac_cap);
8735
8736 dot11f_eht_cap->txop_return_support_txop_share_m2 =
8737 EHTCAP_MAC_TXOP_RETURN_SUPPORT_SHARE_M2_GET_FROM_IE(
8738 ehtcap->eht_mac_cap);
8739 dot11f_eht_cap->two_bqrs_support =
8740 EHTCAP_MAC_TWO_BQRS_SUPP_GET_FROM_IE(
8741 ehtcap->eht_mac_cap);
8742
8743 dot11f_eht_cap->eht_link_adaptation_support =
8744 EHTCAP_MAC_EHT_LINK_ADAPTATION_SUPP_GET_FROM_IE(
8745 ehtcap->eht_mac_cap);
8746
8747 dot11f_eht_cap->support_320mhz_6ghz =
8748 EHTCAP_PHY_320MHZIN6GHZ_GET_FROM_IE(
8749 ehtcap->eht_phy_cap.phy_cap_bytes);
8750
8751 dot11f_eht_cap->ru_242tone_wt_20mhz =
8752 EHTCAP_PHY_242TONERUBWGT20MHZ_GET_FROM_IE(
8753 ehtcap->eht_phy_cap.phy_cap_bytes);
8754
8755 dot11f_eht_cap->ndp_4x_eht_ltf_3dot2_us_gi =
8756 EHTCAP_PHY_NDP4XEHTLTFAND320NSGI_GET_FROM_IE(
8757 ehtcap->eht_phy_cap.phy_cap_bytes);
8758
8759 dot11f_eht_cap->partial_bw_mu_mimo =
8760 EHTCAP_PHY_PARTIALBWULMU_GET_FROM_IE(
8761 ehtcap->eht_phy_cap.phy_cap_bytes);
8762
8763 dot11f_eht_cap->su_beamformer =
8764 EHTCAP_PHY_SUBFMR_GET_FROM_IE(ehtcap->eht_phy_cap.phy_cap_bytes);
8765
8766 dot11f_eht_cap->su_beamformee =
8767 EHTCAP_PHY_SUBFME_GET_FROM_IE(ehtcap->eht_phy_cap.phy_cap_bytes);
8768
8769 dot11f_eht_cap->bfee_ss_le_80mhz =
8770 EHTCAP_PHY_BFMESSLT80MHZ_GET_FROM_IE_BYTE0(
8771 ehtcap->eht_phy_cap.phy_cap_bytes);
8772
8773 dot11f_eht_cap->bfee_ss_le_80mhz |=
8774 (EHTCAP_PHY_BFMESSLT80MHZ_GET_FROM_IE_BYTE1(
8775 ehtcap->eht_phy_cap.phy_cap_bytes) << 1);
8776 dot11f_eht_cap->bfee_ss_160mhz =
8777 EHTCAP_PHY_BFMESS160MHZ_GET_FROM_IE(
8778 ehtcap->eht_phy_cap.phy_cap_bytes);
8779
8780 dot11f_eht_cap->bfee_ss_320mhz =
8781 EHTCAP_PHY_BFMESS320MHZ_GET_FROM_IE(
8782 ehtcap->eht_phy_cap.phy_cap_bytes);
8783
8784 dot11f_eht_cap->num_sounding_dim_le_80mhz =
8785 EHTCAP_PHY_NUMSOUNDLT80MHZ_GET_FROM_IE(
8786 ehtcap->eht_phy_cap.phy_cap_bytes);
8787
8788 dot11f_eht_cap->num_sounding_dim_160mhz =
8789 EHTCAP_PHY_NUMSOUND160MHZ_GET_FROM_IE(
8790 ehtcap->eht_phy_cap.phy_cap_bytes);
8791
8792 dot11f_eht_cap->num_sounding_dim_320mhz =
8793 EHTCAP_PHY_NUMSOUND320MHZ_GET_FROM_IE(
8794 ehtcap->eht_phy_cap.phy_cap_bytes);
8795
8796 dot11f_eht_cap->ng_16_su_feedback =
8797 EHTCAP_PHY_NG16SUFB_GET_FROM_IE(
8798 ehtcap->eht_phy_cap.phy_cap_bytes);
8799
8800 dot11f_eht_cap->ng_16_mu_feedback =
8801 EHTCAP_PHY_NG16MUFB_GET_FROM_IE(
8802 ehtcap->eht_phy_cap.phy_cap_bytes);
8803
8804 dot11f_eht_cap->cb_sz_4_2_su_feedback =
8805 EHTCAP_PHY_CODBK42SUFB_GET_FROM_IE(
8806 ehtcap->eht_phy_cap.phy_cap_bytes);
8807
8808 dot11f_eht_cap->cb_sz_7_5_su_feedback =
8809 EHTCAP_PHY_CODBK75MUFB_GET_FROM_IE(
8810 ehtcap->eht_phy_cap.phy_cap_bytes);
8811
8812 dot11f_eht_cap->trig_su_bforming_feedback =
8813 EHTCAP_PHY_TRIGSUBFFB_GET_FROM_IE(
8814 ehtcap->eht_phy_cap.phy_cap_bytes);
8815
8816 dot11f_eht_cap->trig_mu_bforming_partial_bw_feedback =
8817 EHTCAP_PHY_TRIGMUBFPARTBWFB_GET_FROM_IE(
8818 ehtcap->eht_phy_cap.phy_cap_bytes);
8819
8820 dot11f_eht_cap->triggered_cqi_feedback =
8821 EHTCAP_PHY_TRIGCQIFB_GET_FROM_IE(
8822 ehtcap->eht_phy_cap.phy_cap_bytes);
8823
8824 dot11f_eht_cap->partial_bw_dl_mu_mimo =
8825 EHTCAP_PHY_PARTBWDLMUMIMO_GET_FROM_IE(
8826 ehtcap->eht_phy_cap.phy_cap_bytes);
8827
8828 dot11f_eht_cap->psr_based_sr =
8829 EHTCAP_PHY_PSRSR_GET_FROM_IE(
8830 ehtcap->eht_phy_cap.phy_cap_bytes);
8831
8832 dot11f_eht_cap->power_boost_factor =
8833 EHTCAP_PHY_PWRBSTFACTOR_GET_FROM_IE(
8834 ehtcap->eht_phy_cap.phy_cap_bytes);
8835
8836 dot11f_eht_cap->eht_mu_ppdu_4x_ltf_0_8_us_gi =
8837 EHTCAP_PHY_4XEHTMULTFAND800NSGI_GET_FROM_IE(
8838 ehtcap->eht_phy_cap.phy_cap_bytes);
8839
8840 dot11f_eht_cap->max_nc =
8841 EHTCAP_PHY_MAXNC_GET_FROM_IE(
8842 ehtcap->eht_phy_cap.phy_cap_bytes);
8843
8844 dot11f_eht_cap->non_trig_cqi_feedback =
8845 EHTCAP_PHY_NONTRIGCQIFB_GET_FROM_IE(
8846 ehtcap->eht_phy_cap.phy_cap_bytes);
8847
8848 dot11f_eht_cap->tx_1024_4096_qam_lt_242_tone_ru =
8849 EHTCAP_PHY_TX1024AND4096QAMLT242TONERU_GET_FROM_IE(
8850 ehtcap->eht_phy_cap.phy_cap_bytes);
8851
8852 dot11f_eht_cap->rx_1024_4096_qam_lt_242_tone_ru =
8853 EHTCAP_PHY_RX1024AND4096QAMLT242TONERU_GET_FROM_IE(
8854 ehtcap->eht_phy_cap.phy_cap_bytes);
8855
8856 dot11f_eht_cap->ppet_present =
8857 EHTCAP_PHY_PPETHRESPRESENT_GET_FROM_IE(
8858 ehtcap->eht_phy_cap.phy_cap_bytes);
8859
8860 dot11f_eht_cap->common_nominal_pkt_padding =
8861 EHTCAP_PHY_CMNNOMPKTPAD_GET_FROM_IE(
8862 ehtcap->eht_phy_cap.phy_cap_bytes);
8863
8864 dot11f_eht_cap->max_num_eht_ltf =
8865 EHTCAP_PHY_MAXNUMEHTLTF_GET_FROM_IE(
8866 ehtcap->eht_phy_cap.phy_cap_bytes);
8867
8868 dot11f_eht_cap->mcs_15 =
8869 EHTCAP_PHY_SUPMCS15_GET_FROM_IE(
8870 ehtcap->eht_phy_cap.phy_cap_bytes);
8871
8872 dot11f_eht_cap->eht_dup_6ghz =
8873 EHTCAP_PHY_EHTDUPIN6GHZ_GET_FROM_IE(
8874 ehtcap->eht_phy_cap.phy_cap_bytes);
8875
8876 dot11f_eht_cap->op_sta_rx_ndp_wider_bw_20mhz =
8877 EHTCAP_PHY_20MHZOPSTARXNDPWIDERBW_GET_FROM_IE(
8878 ehtcap->eht_phy_cap.phy_cap_bytes);
8879
8880 dot11f_eht_cap->non_ofdma_ul_mu_mimo_le_80mhz =
8881 EHTCAP_PHY_NONOFDMAULMUMIMOLT80MHZ_GET_FROM_IE(
8882 ehtcap->eht_phy_cap.phy_cap_bytes);
8883
8884 dot11f_eht_cap->non_ofdma_ul_mu_mimo_160mhz =
8885 EHTCAP_PHY_NONOFDMAULMUMIMO160MHZ_GET_FROM_IE(
8886 ehtcap->eht_phy_cap.phy_cap_bytes);
8887
8888 dot11f_eht_cap->non_ofdma_ul_mu_mimo_320mhz =
8889 EHTCAP_PHY_NONOFDMAULMUMIMO320MHZ_GET_FROM_IE(
8890 ehtcap->eht_phy_cap.phy_cap_bytes);
8891
8892 dot11f_eht_cap->mu_bformer_le_80mhz =
8893 EHTCAP_PHY_MUBFMRLT80MHZ_GET_FROM_IE(
8894 ehtcap->eht_phy_cap.phy_cap_bytes);
8895
8896 dot11f_eht_cap->mu_bformer_160mhz =
8897 EHTCAP_PHY_MUBFMR160MHZ_GET_FROM_IE(
8898 ehtcap->eht_phy_cap.phy_cap_bytes);
8899
8900 dot11f_eht_cap->mu_bformer_320mhz =
8901 EHTCAP_PHY_MUBFMR320MHZ_GET_FROM_IE(
8902 ehtcap->eht_phy_cap.phy_cap_bytes);
8903
8904 dot11f_eht_cap->tb_sounding_feedback_rl =
8905 EHTCAP_PHY_TB_SOUNDING_FB_RL_GET_FROM_IE(
8906 ehtcap->eht_phy_cap.phy_cap_bytes);
8907
8908 dot11f_eht_cap->rx_1k_qam_in_wider_bw_dl_ofdma =
8909 EHTCAP_PHY_RX_1K_QAM_IN_WIDER_BW_DL_OFDMA_GET_FROM_IE(
8910 ehtcap->eht_phy_cap.phy_cap_bytes);
8911
8912 dot11f_eht_cap->rx_4k_qam_in_wider_bw_dl_ofdma =
8913 EHTCAP_PHY_RX_4K_QAM_IN_WIDER_BW_DL_OFDMA_GET_FROM_IE(
8914 ehtcap->eht_phy_cap.phy_cap_bytes);
8915
8916 dot11f_eht_cap->limited_cap_support_20mhz =
8917 EHTCAP_PHY_20MHZ_ONLY_CAPS_GET_FROM_IE(
8918 ehtcap->eht_phy_cap.phy_cap_bytes);
8919
8920 dot11f_eht_cap->triggered_mu_bf_full_bw_fb_and_dl_mumimo =
8921 EHTCAP_PHY_20MHZ_ONLY_TRIGGER_MUBF_FULL_BW_FB_AND_DLMUMIMO_GET_FROM_IE(
8922 ehtcap->eht_phy_cap.phy_cap_bytes);
8923
8924 dot11f_eht_cap->mru_support_20mhz =
8925 EHTCAP_PHY_20MHZ_ONLY_MRU_SUPP_GET_FROM_IE(
8926 ehtcap->eht_phy_cap.phy_cap_bytes);
8927
8928 /* Fill EHT MCS and NSS set field */
8929 if ((is_band_2g && !dot11f_he_cap.chan_width_0) ||
8930 (!is_band_2g && !dot11f_he_cap.chan_width_1 &&
8931 !dot11f_he_cap.chan_width_2 && !dot11f_he_cap.chan_width_3)) {
8932 dot11f_eht_cap->bw_20_rx_max_nss_for_mcs_0_to_7 =
8933 ehtcap_ie_get(ehtcap->mcs_nss_map_bytes[idx],
8934 EHTCAP_RX_MCS_NSS_MAP_IDX,
8935 EHTCAP_RX_MCS_NSS_MAP_BITS);
8936
8937 dot11f_eht_cap->bw_20_tx_max_nss_for_mcs_0_to_7 =
8938 ehtcap_ie_get(ehtcap->mcs_nss_map_bytes[idx],
8939 EHTCAP_TX_MCS_NSS_MAP_IDX,
8940 EHTCAP_TX_MCS_NSS_MAP_BITS);
8941 idx++;
8942
8943 dot11f_eht_cap->bw_20_rx_max_nss_for_mcs_8_and_9 =
8944 ehtcap_ie_get(ehtcap->mcs_nss_map_bytes[idx],
8945 EHTCAP_RX_MCS_NSS_MAP_IDX,
8946 EHTCAP_RX_MCS_NSS_MAP_BITS);
8947
8948 dot11f_eht_cap->bw_20_tx_max_nss_for_mcs_8_and_9 =
8949 ehtcap_ie_get(ehtcap->mcs_nss_map_bytes[idx],
8950 EHTCAP_TX_MCS_NSS_MAP_IDX,
8951 EHTCAP_TX_MCS_NSS_MAP_BITS);
8952 idx++;
8953
8954 dot11f_eht_cap->bw_20_rx_max_nss_for_mcs_10_and_11 =
8955 ehtcap_ie_get(ehtcap->mcs_nss_map_bytes[idx],
8956 EHTCAP_RX_MCS_NSS_MAP_IDX,
8957 EHTCAP_RX_MCS_NSS_MAP_BITS);
8958
8959 dot11f_eht_cap->bw_20_tx_max_nss_for_mcs_10_and_11 =
8960 ehtcap_ie_get(ehtcap->mcs_nss_map_bytes[idx],
8961 EHTCAP_TX_MCS_NSS_MAP_IDX,
8962 EHTCAP_TX_MCS_NSS_MAP_BITS);
8963 idx++;
8964
8965 dot11f_eht_cap->bw_20_rx_max_nss_for_mcs_12_and_13 =
8966 ehtcap_ie_get(ehtcap->mcs_nss_map_bytes[idx],
8967 EHTCAP_RX_MCS_NSS_MAP_IDX,
8968 EHTCAP_RX_MCS_NSS_MAP_BITS);
8969
8970 dot11f_eht_cap->bw_20_tx_max_nss_for_mcs_12_and_13 =
8971 ehtcap_ie_get(ehtcap->mcs_nss_map_bytes[idx],
8972 EHTCAP_TX_MCS_NSS_MAP_IDX,
8973 EHTCAP_TX_MCS_NSS_MAP_BITS);
8974 idx++;
8975 } else {
8976 if ((is_band_2g && dot11f_he_cap.chan_width_0) ||
8977 (!is_band_2g && dot11f_he_cap.chan_width_1)) {
8978 dot11f_eht_cap->bw_le_80_rx_max_nss_for_mcs_0_to_9 =
8979 ehtcap_ie_get(ehtcap->mcs_nss_map_bytes[idx],
8980 EHTCAP_RX_MCS_NSS_MAP_IDX,
8981 EHTCAP_RX_MCS_NSS_MAP_BITS);
8982 dot11f_eht_cap->bw_20_rx_max_nss_for_mcs_0_to_7 =
8983 dot11f_eht_cap->bw_le_80_rx_max_nss_for_mcs_0_to_9;
8984 dot11f_eht_cap->bw_20_rx_max_nss_for_mcs_8_and_9 =
8985 dot11f_eht_cap->bw_le_80_rx_max_nss_for_mcs_0_to_9;
8986
8987 dot11f_eht_cap->bw_le_80_tx_max_nss_for_mcs_0_to_9 =
8988 ehtcap_ie_get(ehtcap->mcs_nss_map_bytes[idx],
8989 EHTCAP_TX_MCS_NSS_MAP_IDX,
8990 EHTCAP_TX_MCS_NSS_MAP_BITS);
8991 dot11f_eht_cap->bw_20_tx_max_nss_for_mcs_0_to_7 =
8992 dot11f_eht_cap->bw_le_80_tx_max_nss_for_mcs_0_to_9;
8993 dot11f_eht_cap->bw_20_tx_max_nss_for_mcs_8_and_9 =
8994 dot11f_eht_cap->bw_le_80_tx_max_nss_for_mcs_0_to_9;
8995 idx++;
8996
8997 dot11f_eht_cap->bw_le_80_rx_max_nss_for_mcs_10_and_11 =
8998 ehtcap_ie_get(ehtcap->mcs_nss_map_bytes[idx],
8999 EHTCAP_RX_MCS_NSS_MAP_IDX,
9000 EHTCAP_RX_MCS_NSS_MAP_BITS);
9001 dot11f_eht_cap->bw_20_rx_max_nss_for_mcs_10_and_11 =
9002 dot11f_eht_cap->bw_le_80_rx_max_nss_for_mcs_10_and_11;
9003
9004 dot11f_eht_cap->bw_le_80_tx_max_nss_for_mcs_10_and_11 =
9005 ehtcap_ie_get(ehtcap->mcs_nss_map_bytes[idx],
9006 EHTCAP_TX_MCS_NSS_MAP_IDX,
9007 EHTCAP_TX_MCS_NSS_MAP_BITS);
9008 dot11f_eht_cap->bw_20_tx_max_nss_for_mcs_10_and_11 =
9009 dot11f_eht_cap->bw_le_80_tx_max_nss_for_mcs_10_and_11;
9010 idx++;
9011
9012 dot11f_eht_cap->bw_le_80_rx_max_nss_for_mcs_12_and_13 =
9013 ehtcap_ie_get(ehtcap->mcs_nss_map_bytes[idx],
9014 EHTCAP_RX_MCS_NSS_MAP_IDX,
9015 EHTCAP_RX_MCS_NSS_MAP_BITS);
9016 dot11f_eht_cap->bw_20_rx_max_nss_for_mcs_12_and_13 =
9017 dot11f_eht_cap->bw_le_80_rx_max_nss_for_mcs_12_and_13;
9018
9019 dot11f_eht_cap->bw_le_80_tx_max_nss_for_mcs_12_and_13 =
9020 ehtcap_ie_get(ehtcap->mcs_nss_map_bytes[idx],
9021 EHTCAP_TX_MCS_NSS_MAP_IDX,
9022 EHTCAP_TX_MCS_NSS_MAP_BITS);
9023 dot11f_eht_cap->bw_20_tx_max_nss_for_mcs_12_and_13 =
9024 dot11f_eht_cap->bw_le_80_tx_max_nss_for_mcs_12_and_13;
9025 idx++;
9026 }
9027
9028 if (dot11f_he_cap.chan_width_2 == 1) {
9029 dot11f_eht_cap->bw_160_rx_max_nss_for_mcs_0_to_9 =
9030 ehtcap_ie_get(ehtcap->mcs_nss_map_bytes[idx],
9031 EHTCAP_RX_MCS_NSS_MAP_IDX,
9032 EHTCAP_RX_MCS_NSS_MAP_BITS);
9033
9034 dot11f_eht_cap->bw_160_tx_max_nss_for_mcs_0_to_9 =
9035 ehtcap_ie_get(ehtcap->mcs_nss_map_bytes[idx],
9036 EHTCAP_TX_MCS_NSS_MAP_IDX,
9037 EHTCAP_TX_MCS_NSS_MAP_BITS);
9038 idx++;
9039
9040 dot11f_eht_cap->bw_160_rx_max_nss_for_mcs_10_and_11 =
9041 ehtcap_ie_get(ehtcap->mcs_nss_map_bytes[idx],
9042 EHTCAP_RX_MCS_NSS_MAP_IDX,
9043 EHTCAP_RX_MCS_NSS_MAP_BITS);
9044
9045 dot11f_eht_cap->bw_160_tx_max_nss_for_mcs_10_and_11 =
9046 ehtcap_ie_get(ehtcap->mcs_nss_map_bytes[idx],
9047 EHTCAP_TX_MCS_NSS_MAP_IDX,
9048 EHTCAP_TX_MCS_NSS_MAP_BITS);
9049 idx++;
9050
9051 dot11f_eht_cap->bw_160_rx_max_nss_for_mcs_12_and_13 =
9052 ehtcap_ie_get(ehtcap->mcs_nss_map_bytes[idx],
9053 EHTCAP_RX_MCS_NSS_MAP_IDX,
9054 EHTCAP_RX_MCS_NSS_MAP_BITS);
9055
9056 dot11f_eht_cap->bw_160_tx_max_nss_for_mcs_12_and_13 =
9057 ehtcap_ie_get(ehtcap->mcs_nss_map_bytes[idx],
9058 EHTCAP_TX_MCS_NSS_MAP_IDX,
9059 EHTCAP_TX_MCS_NSS_MAP_BITS);
9060 idx++;
9061 }
9062
9063 if (dot11f_eht_cap->support_320mhz_6ghz) {
9064 dot11f_eht_cap->bw_320_rx_max_nss_for_mcs_0_to_9 =
9065 ehtcap_ie_get(ehtcap->mcs_nss_map_bytes[idx],
9066 EHTCAP_RX_MCS_NSS_MAP_IDX,
9067 EHTCAP_RX_MCS_NSS_MAP_BITS);
9068
9069 dot11f_eht_cap->bw_320_tx_max_nss_for_mcs_0_to_9 =
9070 ehtcap_ie_get(ehtcap->mcs_nss_map_bytes[idx],
9071 EHTCAP_TX_MCS_NSS_MAP_IDX,
9072 EHTCAP_TX_MCS_NSS_MAP_BITS);
9073 idx++;
9074
9075 dot11f_eht_cap->bw_320_rx_max_nss_for_mcs_10_and_11 =
9076 ehtcap_ie_get(ehtcap->mcs_nss_map_bytes[idx],
9077 EHTCAP_RX_MCS_NSS_MAP_IDX,
9078 EHTCAP_RX_MCS_NSS_MAP_BITS);
9079
9080 dot11f_eht_cap->bw_320_tx_max_nss_for_mcs_10_and_11 =
9081 ehtcap_ie_get(ehtcap->mcs_nss_map_bytes[idx],
9082 EHTCAP_TX_MCS_NSS_MAP_IDX,
9083 EHTCAP_TX_MCS_NSS_MAP_BITS);
9084 idx++;
9085
9086 dot11f_eht_cap->bw_320_rx_max_nss_for_mcs_12_and_13 =
9087 ehtcap_ie_get(ehtcap->mcs_nss_map_bytes[idx],
9088 EHTCAP_RX_MCS_NSS_MAP_IDX,
9089 EHTCAP_RX_MCS_NSS_MAP_BITS);
9090
9091 dot11f_eht_cap->bw_320_tx_max_nss_for_mcs_12_and_13 =
9092 ehtcap_ie_get(ehtcap->mcs_nss_map_bytes[idx],
9093 EHTCAP_TX_MCS_NSS_MAP_IDX,
9094 EHTCAP_TX_MCS_NSS_MAP_BITS);
9095 idx++;
9096 }
9097 }
9098
9099 /* Fill in TxRx EHT NSS & MCS support */
9100 mcs_map_len = idx;
9101 //ehtcap->elem_len = EHTCAP_FIXED_LEN + mcs_map_len;
9102 //ehtcaplen = ehtcap->elem_len + WLAN_IE_HDR_LEN;
9103
9104 return QDF_STATUS_SUCCESS;
9105 }
9106
9107 QDF_STATUS lim_strip_and_decode_eht_cap(uint8_t *ie, uint16_t ie_len,
9108 tDot11fIEeht_cap *dot11f_eht_cap,
9109 tDot11fIEhe_cap dot11f_he_cap,
9110 uint16_t freq)
9111 {
9112 const uint8_t *eht_cap_ie;
9113 bool is_band_2g;
9114 QDF_STATUS status;
9115
9116 eht_cap_ie = lim_get_ext_ie_ptr_from_ext_id(ie, ie_len,
9117 EHT_CAP_OUI_TYPE,
9118 EHT_CAP_OUI_SIZE);
9119
9120 if (!eht_cap_ie)
9121 return QDF_STATUS_SUCCESS;
9122
9123 is_band_2g = WLAN_REG_IS_24GHZ_CH_FREQ(freq);
9124
9125 status = lim_ieee80211_unpack_ehtcap(eht_cap_ie, dot11f_eht_cap,
9126 dot11f_he_cap,
9127 is_band_2g);
9128
9129 if (status != QDF_STATUS_SUCCESS) {
9130 pe_err("Failed to extract eht cap");
9131 return QDF_STATUS_E_FAILURE;
9132 }
9133
9134 return QDF_STATUS_SUCCESS;
9135 }
9136
9137 void lim_ieee80211_pack_ehtcap(uint8_t *ie, tDot11fIEeht_cap dot11f_eht_cap,
9138 tDot11fIEhe_cap dot11f_he_cap, bool is_band_2g)
9139 {
9140 struct wlan_ie_ehtcaps *ehtcap = (struct wlan_ie_ehtcaps *)ie;
9141 uint32_t ehtcaplen;
9142 uint32_t val, idx = 0;
9143 bool chwidth_320;
9144 uint32_t mcs_map_len;
9145
9146 if (!ie) {
9147 pe_err("ie is null");
9148 return;
9149 }
9150
9151 /* deduct the variable size fields before
9152 * memsetting hecap to 0
9153 */
9154 qdf_mem_zero(ehtcap,
9155 (sizeof(struct wlan_ie_ehtcaps)));
9156
9157 ehtcap->elem_id = DOT11F_EID_EHT_CAP;
9158 /* elem id + len = 2 bytes readjust based on
9159 * mcs-nss and ppet fields
9160 */
9161 qdf_mem_copy(&ehtcap->elem_id_extn, EHT_CAP_OUI_TYPE, EHT_CAP_OUI_SIZE);
9162
9163 val = dot11f_eht_cap.epcs_pri_access;
9164 EHTCAP_MAC_EPCSPRIACCESS_SET_TO_IE(ehtcap->eht_mac_cap, val);
9165
9166 val = dot11f_eht_cap.eht_om_ctl;
9167 EHTCAP_MAC_EHTOMCTRL_SET_TO_IE(ehtcap->eht_mac_cap, val);
9168
9169 val = dot11f_eht_cap.triggered_txop_sharing_mode1;
9170 EHTCAP_MAC_TRIGTXOP_MODE1_SET_TO_IE(ehtcap->eht_mac_cap, val);
9171
9172 val = dot11f_eht_cap.triggered_txop_sharing_mode2;
9173 EHTCAP_MAC_TRIGTXOP_MODE2_SET_TO_IE(ehtcap->eht_mac_cap, val);
9174
9175 val = dot11f_eht_cap.restricted_twt;
9176 EHTCAP_MAC_RESTRICTED_TWT_SET_TO_IE(ehtcap->eht_mac_cap, val);
9177
9178 val = dot11f_eht_cap.scs_traffic_desc;
9179 EHTCAP_MAC_SCS_TRAFFIC_DESC_SET_TO_IE(ehtcap->eht_mac_cap, val);
9180
9181 val = dot11f_eht_cap.max_mpdu_len;
9182 EHTCAP_MAC_MAX_MPDU_LEN_SET_TO_IE(ehtcap->eht_mac_cap, val);
9183
9184 val = dot11f_eht_cap.max_a_mpdu_len_exponent_ext;
9185 EHTCAP_MAC_MAX_A_MPDU_LEN_EXPONENT_EXT_SET_TO_IE(ehtcap->eht_mac_cap,
9186 val);
9187
9188 val = dot11f_eht_cap.eht_trs_support;
9189 EHTCAP_MAC_EHT_TRS_SUPPORT_SET_TO_IE(ehtcap->eht_mac_cap, val);
9190
9191 val = dot11f_eht_cap.txop_return_support_txop_share_m2;
9192 EHTCAP_MAC_TXOP_RETURN_SUPPORT_SHARE_M2_SET_FROM_IE(ehtcap->eht_mac_cap,
9193 val);
9194 val = dot11f_eht_cap.two_bqrs_support;
9195 EHTCAP_MAC_TWO_BQRS_SUPP_SET_FROM_IE(ehtcap->eht_mac_cap,
9196 val);
9197
9198 val = dot11f_eht_cap.eht_link_adaptation_support;
9199 EHTCAP_MAC_EHT_LINK_ADAPTATION_SUPP_SET_FROM_IE(ehtcap->eht_mac_cap,
9200 val);
9201
9202 chwidth_320 = dot11f_eht_cap.support_320mhz_6ghz;
9203 EHTCAP_PHY_320MHZIN6GHZ_SET_TO_IE(ehtcap->eht_phy_cap.phy_cap_bytes,
9204 chwidth_320);
9205
9206 val = dot11f_eht_cap.ru_242tone_wt_20mhz;
9207 EHTCAP_PHY_242TONERUBWGT20MHZ_SET_TO_IE(
9208 ehtcap->eht_phy_cap.phy_cap_bytes, val);
9209
9210 val = dot11f_eht_cap.ndp_4x_eht_ltf_3dot2_us_gi;
9211 EHTCAP_PHY_NDP4XEHTLTFAND320NSGI_SET_TO_IE(
9212 ehtcap->eht_phy_cap.phy_cap_bytes, val);
9213
9214 val = dot11f_eht_cap.partial_bw_mu_mimo;
9215 EHTCAP_PHY_PARTIALBWULMU_SET_TO_IE(
9216 ehtcap->eht_phy_cap.phy_cap_bytes, val);
9217
9218 val = dot11f_eht_cap.su_beamformer;
9219 EHTCAP_PHY_SUBFMR_SET_TO_IE(ehtcap->eht_phy_cap.phy_cap_bytes, val);
9220
9221 val = dot11f_eht_cap.su_beamformee;
9222 EHTCAP_PHY_SUBFME_SET_TO_IE(ehtcap->eht_phy_cap.phy_cap_bytes, val);
9223
9224 val = dot11f_eht_cap.bfee_ss_le_80mhz;
9225 EHTCAP_PHY_BFMESSLT80MHZ_SET_TO_IE_BYTE0(
9226 ehtcap->eht_phy_cap.phy_cap_bytes,
9227 val & 1);
9228
9229 EHTCAP_PHY_BFMESSLT80MHZ_SET_TO_IE_BYTE1(
9230 ehtcap->eht_phy_cap.phy_cap_bytes,
9231 (val >> 1));
9232 val = dot11f_eht_cap.bfee_ss_160mhz;
9233 EHTCAP_PHY_BFMESS160MHZ_SET_TO_IE(
9234 ehtcap->eht_phy_cap.phy_cap_bytes, val);
9235
9236 val = dot11f_eht_cap.bfee_ss_320mhz;
9237 EHTCAP_PHY_BFMESS320MHZ_SET_TO_IE(
9238 ehtcap->eht_phy_cap.phy_cap_bytes, val);
9239
9240 val = dot11f_eht_cap.num_sounding_dim_le_80mhz;
9241 EHTCAP_PHY_NUMSOUNDLT80MHZ_SET_TO_IE(
9242 ehtcap->eht_phy_cap.phy_cap_bytes, val);
9243
9244 val = dot11f_eht_cap.num_sounding_dim_160mhz;
9245 EHTCAP_PHY_NUMSOUND160MHZ_SET_TO_IE(
9246 ehtcap->eht_phy_cap.phy_cap_bytes, val);
9247
9248 val = dot11f_eht_cap.num_sounding_dim_320mhz;
9249 EHTCAP_PHY_NUMSOUND320MHZ_SET_TO_IE(
9250 ehtcap->eht_phy_cap.phy_cap_bytes, val);
9251
9252 val = dot11f_eht_cap.ng_16_su_feedback;
9253 EHTCAP_PHY_NG16SUFB_SET_TO_IE(ehtcap->eht_phy_cap.phy_cap_bytes, val);
9254
9255 val = dot11f_eht_cap.ng_16_mu_feedback;
9256 EHTCAP_PHY_NG16MUFB_SET_TO_IE(ehtcap->eht_phy_cap.phy_cap_bytes, val);
9257
9258 val = dot11f_eht_cap.cb_sz_4_2_su_feedback;
9259 EHTCAP_PHY_CODBK42SUFB_SET_TO_IE(
9260 ehtcap->eht_phy_cap.phy_cap_bytes, val);
9261
9262 val = dot11f_eht_cap.cb_sz_7_5_su_feedback;
9263 EHTCAP_PHY_CODBK75MUFB_SET_TO_IE(
9264 ehtcap->eht_phy_cap.phy_cap_bytes, val);
9265
9266 val = dot11f_eht_cap.trig_su_bforming_feedback;
9267 EHTCAP_PHY_TRIGSUBFFB_SET_TO_IE(
9268 ehtcap->eht_phy_cap.phy_cap_bytes, val);
9269
9270 val = dot11f_eht_cap.trig_mu_bforming_partial_bw_feedback;
9271 EHTCAP_PHY_TRIGMUBFPARTBWFB_SET_TO_IE(
9272 ehtcap->eht_phy_cap.phy_cap_bytes, val);
9273
9274 val = dot11f_eht_cap.triggered_cqi_feedback;
9275 EHTCAP_PHY_TRIGCQIFB_SET_TO_IE(ehtcap->eht_phy_cap.phy_cap_bytes, val);
9276
9277 val = dot11f_eht_cap.partial_bw_dl_mu_mimo;
9278 EHTCAP_PHY_PARTBWDLMUMIMO_SET_TO_IE(
9279 ehtcap->eht_phy_cap.phy_cap_bytes, val);
9280
9281 val = dot11f_eht_cap.psr_based_sr;
9282 EHTCAP_PHY_PSRSR_SET_TO_IE(ehtcap->eht_phy_cap.phy_cap_bytes, val);
9283
9284 val = dot11f_eht_cap.power_boost_factor;
9285 EHTCAP_PHY_PWRBSTFACTOR_SET_TO_IE(
9286 ehtcap->eht_phy_cap.phy_cap_bytes, val);
9287
9288 val = dot11f_eht_cap.eht_mu_ppdu_4x_ltf_0_8_us_gi;
9289 EHTCAP_PHY_4XEHTMULTFAND800NSGI_SET_TO_IE(
9290 ehtcap->eht_phy_cap.phy_cap_bytes, val);
9291
9292 val = dot11f_eht_cap.max_nc;
9293 EHTCAP_PHY_MAXNC_SET_TO_IE(ehtcap->eht_phy_cap.phy_cap_bytes, val);
9294
9295 val = dot11f_eht_cap.non_trig_cqi_feedback;
9296 EHTCAP_PHY_NONTRIGCQIFB_SET_TO_IE(
9297 ehtcap->eht_phy_cap.phy_cap_bytes, val);
9298
9299 val = dot11f_eht_cap.tx_1024_4096_qam_lt_242_tone_ru;
9300 EHTCAP_PHY_TX1024AND4096QAMLT242TONERU_SET_TO_IE(
9301 ehtcap->eht_phy_cap.phy_cap_bytes, val);
9302
9303 val = dot11f_eht_cap.rx_1024_4096_qam_lt_242_tone_ru;
9304 EHTCAP_PHY_RX1024AND4096QAMLT242TONERU_SET_TO_IE(
9305 ehtcap->eht_phy_cap.phy_cap_bytes, val);
9306
9307 val = dot11f_eht_cap.ppet_present;
9308 EHTCAP_PHY_PPETHRESPRESENT_SET_TO_IE(
9309 ehtcap->eht_phy_cap.phy_cap_bytes, val);
9310
9311 val = dot11f_eht_cap.common_nominal_pkt_padding;
9312 EHTCAP_PHY_CMNNOMPKTPAD_SET_TO_IE(
9313 ehtcap->eht_phy_cap.phy_cap_bytes, val);
9314
9315 val = dot11f_eht_cap.max_num_eht_ltf;
9316 EHTCAP_PHY_MAXNUMEHTLTF_SET_TO_IE(
9317 ehtcap->eht_phy_cap.phy_cap_bytes, val);
9318
9319 val = dot11f_eht_cap.mcs_15;
9320 EHTCAP_PHY_SUPMCS15_SET_TO_IE(ehtcap->eht_phy_cap.phy_cap_bytes, val);
9321
9322 val = dot11f_eht_cap.eht_dup_6ghz;
9323 EHTCAP_PHY_EHTDUPIN6GHZ_SET_TO_IE(
9324 ehtcap->eht_phy_cap.phy_cap_bytes, val);
9325
9326 val = dot11f_eht_cap.op_sta_rx_ndp_wider_bw_20mhz;
9327 EHTCAP_PHY_20MHZOPSTARXNDPWIDERBW_SET_TO_IE(
9328 ehtcap->eht_phy_cap.phy_cap_bytes, val);
9329
9330 val = dot11f_eht_cap.non_ofdma_ul_mu_mimo_le_80mhz;
9331 EHTCAP_PHY_NONOFDMAULMUMIMOLT80MHZ_SET_TO_IE(
9332 ehtcap->eht_phy_cap.phy_cap_bytes, val);
9333
9334 val = dot11f_eht_cap.non_ofdma_ul_mu_mimo_160mhz;
9335 EHTCAP_PHY_NONOFDMAULMUMIMO160MHZ_SET_TO_IE(
9336 ehtcap->eht_phy_cap.phy_cap_bytes, val);
9337
9338 val = dot11f_eht_cap.non_ofdma_ul_mu_mimo_320mhz;
9339 EHTCAP_PHY_NONOFDMAULMUMIMO320MHZ_SET_TO_IE(
9340 ehtcap->eht_phy_cap.phy_cap_bytes, val);
9341
9342 val = dot11f_eht_cap.mu_bformer_le_80mhz;
9343 EHTCAP_PHY_MUBFMRLT80MHZ_SET_TO_IE(
9344 ehtcap->eht_phy_cap.phy_cap_bytes, val);
9345
9346 val = dot11f_eht_cap.mu_bformer_160mhz;
9347 EHTCAP_PHY_MUBFMR160MHZ_SET_TO_IE(
9348 ehtcap->eht_phy_cap.phy_cap_bytes, val);
9349
9350 val = dot11f_eht_cap.mu_bformer_320mhz;
9351 EHTCAP_PHY_MUBFMR320MHZ_SET_TO_IE(
9352 ehtcap->eht_phy_cap.phy_cap_bytes, val);
9353
9354 val = dot11f_eht_cap.tb_sounding_feedback_rl;
9355 EHTCAP_PHY_TB_SOUNDING_FB_RL_SET_TO_IE(
9356 ehtcap->eht_phy_cap.phy_cap_bytes, val);
9357
9358 val = dot11f_eht_cap.rx_1k_qam_in_wider_bw_dl_ofdma;
9359 EHTCAP_PHY_RX_1K_QAM_IN_WIDER_BW_DL_OFDMA_SET_TO_IE(
9360 ehtcap->eht_phy_cap.phy_cap_bytes, val);
9361
9362 val = dot11f_eht_cap.rx_4k_qam_in_wider_bw_dl_ofdma;
9363 EHTCAP_PHY_RX_4K_QAM_IN_WIDER_BW_DL_OFDMA_SET_TO_IE(
9364 ehtcap->eht_phy_cap.phy_cap_bytes, val);
9365
9366 val = dot11f_eht_cap.limited_cap_support_20mhz;
9367 EHTCAP_PHY_20MHZ_ONLY_CAPS_SET_TO_IE(
9368 ehtcap->eht_phy_cap.phy_cap_bytes, val);
9369
9370 val = dot11f_eht_cap.triggered_mu_bf_full_bw_fb_and_dl_mumimo;
9371 EHTCAP_PHY_20MHZ_ONLY_TRIGGER_MUBF_FULL_BW_FB_AND_DLMUMIMO_SET_TO_IE(
9372 ehtcap->eht_phy_cap.phy_cap_bytes, val);
9373
9374 val = dot11f_eht_cap.mru_support_20mhz;
9375 EHTCAP_PHY_20MHZ_ONLY_MRU_SUPP_SET_TO_IE(
9376 ehtcap->eht_phy_cap.phy_cap_bytes, val);
9377
9378 /* Fill EHT MCS and NSS set field */
9379 if ((is_band_2g && !dot11f_he_cap.chan_width_0) ||
9380 (!is_band_2g && !dot11f_he_cap.chan_width_1 &&
9381 !dot11f_he_cap.chan_width_2 && !dot11f_he_cap.chan_width_3)) {
9382 val = dot11f_eht_cap.bw_20_rx_max_nss_for_mcs_0_to_7;
9383 ehtcap_ie_set(&ehtcap->mcs_nss_map_bytes[idx],
9384 EHTCAP_RX_MCS_NSS_MAP_IDX,
9385 EHTCAP_RX_MCS_NSS_MAP_BITS, val);
9386
9387 val = dot11f_eht_cap.bw_20_tx_max_nss_for_mcs_0_to_7;
9388 ehtcap_ie_set(&ehtcap->mcs_nss_map_bytes[idx],
9389 EHTCAP_TX_MCS_NSS_MAP_IDX,
9390 EHTCAP_TX_MCS_NSS_MAP_BITS, val);
9391 idx++;
9392
9393 val = dot11f_eht_cap.bw_20_rx_max_nss_for_mcs_8_and_9;
9394 ehtcap_ie_set(&ehtcap->mcs_nss_map_bytes[idx],
9395 EHTCAP_RX_MCS_NSS_MAP_IDX,
9396 EHTCAP_RX_MCS_NSS_MAP_BITS, val);
9397
9398 val = dot11f_eht_cap.bw_20_tx_max_nss_for_mcs_8_and_9;
9399 ehtcap_ie_set(&ehtcap->mcs_nss_map_bytes[idx],
9400 EHTCAP_TX_MCS_NSS_MAP_IDX,
9401 EHTCAP_TX_MCS_NSS_MAP_BITS, val);
9402 idx++;
9403
9404 val = dot11f_eht_cap.bw_20_rx_max_nss_for_mcs_10_and_11;
9405 ehtcap_ie_set(&ehtcap->mcs_nss_map_bytes[idx],
9406 EHTCAP_RX_MCS_NSS_MAP_IDX,
9407 EHTCAP_RX_MCS_NSS_MAP_BITS, val);
9408
9409 val = dot11f_eht_cap.bw_20_tx_max_nss_for_mcs_10_and_11;
9410 ehtcap_ie_set(&ehtcap->mcs_nss_map_bytes[idx],
9411 EHTCAP_TX_MCS_NSS_MAP_IDX,
9412 EHTCAP_TX_MCS_NSS_MAP_BITS, val);
9413 idx++;
9414
9415 val = dot11f_eht_cap.bw_20_rx_max_nss_for_mcs_12_and_13;
9416 ehtcap_ie_set(&ehtcap->mcs_nss_map_bytes[idx],
9417 EHTCAP_RX_MCS_NSS_MAP_IDX,
9418 EHTCAP_RX_MCS_NSS_MAP_BITS, val);
9419
9420 val = dot11f_eht_cap.bw_20_tx_max_nss_for_mcs_12_and_13;
9421 ehtcap_ie_set(&ehtcap->mcs_nss_map_bytes[idx],
9422 EHTCAP_TX_MCS_NSS_MAP_IDX,
9423 EHTCAP_TX_MCS_NSS_MAP_BITS, val);
9424 idx++;
9425 } else {
9426 if ((is_band_2g && dot11f_he_cap.chan_width_0) ||
9427 (!is_band_2g && dot11f_he_cap.chan_width_1)) {
9428 val = dot11f_eht_cap.bw_le_80_rx_max_nss_for_mcs_0_to_9;
9429 ehtcap_ie_set(&ehtcap->mcs_nss_map_bytes[idx],
9430 EHTCAP_RX_MCS_NSS_MAP_IDX,
9431 EHTCAP_RX_MCS_NSS_MAP_BITS, val);
9432
9433 val = dot11f_eht_cap.bw_le_80_tx_max_nss_for_mcs_0_to_9;
9434 ehtcap_ie_set(&ehtcap->mcs_nss_map_bytes[idx],
9435 EHTCAP_TX_MCS_NSS_MAP_IDX,
9436 EHTCAP_TX_MCS_NSS_MAP_BITS, val);
9437 idx++;
9438
9439 val = dot11f_eht_cap.bw_le_80_rx_max_nss_for_mcs_10_and_11;
9440 ehtcap_ie_set(&ehtcap->mcs_nss_map_bytes[idx],
9441 EHTCAP_RX_MCS_NSS_MAP_IDX,
9442 EHTCAP_RX_MCS_NSS_MAP_BITS, val);
9443
9444 val = dot11f_eht_cap.bw_le_80_tx_max_nss_for_mcs_10_and_11;
9445 ehtcap_ie_set(&ehtcap->mcs_nss_map_bytes[idx],
9446 EHTCAP_TX_MCS_NSS_MAP_IDX,
9447 EHTCAP_TX_MCS_NSS_MAP_BITS, val);
9448 idx++;
9449
9450 val = dot11f_eht_cap.bw_le_80_rx_max_nss_for_mcs_12_and_13;
9451 ehtcap_ie_set(&ehtcap->mcs_nss_map_bytes[idx],
9452 EHTCAP_RX_MCS_NSS_MAP_IDX,
9453 EHTCAP_RX_MCS_NSS_MAP_BITS, val);
9454
9455 val = dot11f_eht_cap.bw_le_80_tx_max_nss_for_mcs_12_and_13;
9456 ehtcap_ie_set(&ehtcap->mcs_nss_map_bytes[idx],
9457 EHTCAP_TX_MCS_NSS_MAP_IDX,
9458 EHTCAP_TX_MCS_NSS_MAP_BITS, val);
9459 idx++;
9460 }
9461
9462 if (dot11f_he_cap.chan_width_2 == 1) {
9463 val = dot11f_eht_cap.bw_160_rx_max_nss_for_mcs_0_to_9;
9464 ehtcap_ie_set(&ehtcap->mcs_nss_map_bytes[idx],
9465 EHTCAP_RX_MCS_NSS_MAP_IDX,
9466 EHTCAP_RX_MCS_NSS_MAP_BITS, val);
9467
9468 val = dot11f_eht_cap.bw_160_tx_max_nss_for_mcs_0_to_9;
9469 ehtcap_ie_set(&ehtcap->mcs_nss_map_bytes[idx],
9470 EHTCAP_TX_MCS_NSS_MAP_IDX,
9471 EHTCAP_TX_MCS_NSS_MAP_BITS, val);
9472 idx++;
9473
9474 val = dot11f_eht_cap.bw_160_rx_max_nss_for_mcs_10_and_11;
9475 ehtcap_ie_set(&ehtcap->mcs_nss_map_bytes[idx],
9476 EHTCAP_RX_MCS_NSS_MAP_IDX,
9477 EHTCAP_RX_MCS_NSS_MAP_BITS, val);
9478
9479 val = dot11f_eht_cap.bw_160_tx_max_nss_for_mcs_10_and_11;
9480 ehtcap_ie_set(&ehtcap->mcs_nss_map_bytes[idx],
9481 EHTCAP_TX_MCS_NSS_MAP_IDX,
9482 EHTCAP_TX_MCS_NSS_MAP_BITS, val);
9483 idx++;
9484
9485 val = dot11f_eht_cap.bw_160_rx_max_nss_for_mcs_12_and_13;
9486 ehtcap_ie_set(&ehtcap->mcs_nss_map_bytes[idx],
9487 EHTCAP_RX_MCS_NSS_MAP_IDX,
9488 EHTCAP_RX_MCS_NSS_MAP_BITS, val);
9489
9490 val = dot11f_eht_cap.bw_160_tx_max_nss_for_mcs_12_and_13;
9491 ehtcap_ie_set(&ehtcap->mcs_nss_map_bytes[idx],
9492 EHTCAP_TX_MCS_NSS_MAP_IDX,
9493 EHTCAP_TX_MCS_NSS_MAP_BITS, val);
9494 idx++;
9495 }
9496
9497 if (chwidth_320) {
9498 val = dot11f_eht_cap.bw_320_rx_max_nss_for_mcs_0_to_9;
9499 ehtcap_ie_set(&ehtcap->mcs_nss_map_bytes[idx],
9500 EHTCAP_RX_MCS_NSS_MAP_IDX,
9501 EHTCAP_RX_MCS_NSS_MAP_BITS, val);
9502
9503 val = dot11f_eht_cap.bw_320_tx_max_nss_for_mcs_0_to_9;
9504 ehtcap_ie_set(&ehtcap->mcs_nss_map_bytes[idx],
9505 EHTCAP_TX_MCS_NSS_MAP_IDX,
9506 EHTCAP_TX_MCS_NSS_MAP_BITS, val);
9507 idx++;
9508
9509 val = dot11f_eht_cap.bw_320_rx_max_nss_for_mcs_10_and_11;
9510 ehtcap_ie_set(&ehtcap->mcs_nss_map_bytes[idx],
9511 EHTCAP_RX_MCS_NSS_MAP_IDX,
9512 EHTCAP_RX_MCS_NSS_MAP_BITS, val);
9513
9514 val = dot11f_eht_cap.bw_320_tx_max_nss_for_mcs_10_and_11;
9515 ehtcap_ie_set(&ehtcap->mcs_nss_map_bytes[idx],
9516 EHTCAP_TX_MCS_NSS_MAP_IDX,
9517 EHTCAP_TX_MCS_NSS_MAP_BITS, val);
9518 idx++;
9519
9520 val = dot11f_eht_cap.bw_320_rx_max_nss_for_mcs_12_and_13;
9521 ehtcap_ie_set(&ehtcap->mcs_nss_map_bytes[idx],
9522 EHTCAP_RX_MCS_NSS_MAP_IDX,
9523 EHTCAP_RX_MCS_NSS_MAP_BITS, val);
9524
9525 val = dot11f_eht_cap.bw_320_tx_max_nss_for_mcs_12_and_13;
9526 ehtcap_ie_set(&ehtcap->mcs_nss_map_bytes[idx],
9527 EHTCAP_TX_MCS_NSS_MAP_IDX,
9528 EHTCAP_TX_MCS_NSS_MAP_BITS, val);
9529 idx++;
9530 }
9531 }
9532
9533 /* Fill in TxRx EHT NSS & MCS support */
9534 mcs_map_len = idx;
9535 ehtcap->elem_len = EHTCAP_FIXED_LEN + mcs_map_len;
9536 ehtcaplen = ehtcap->elem_len + WLAN_IE_HDR_LEN;
9537 }
9538
9539 #ifdef WLAN_SUPPORT_TWT
9540 static void
9541 populate_dot11f_rtwt_eht_cap(struct mac_context *mac,
9542 tDot11fIEeht_cap *eht_cap)
9543 {
9544 bool restricted_support = false;
9545
9546 wlan_twt_get_rtwt_support(mac->psoc, &restricted_support);
9547
9548 pe_debug("rTWT support: %d", restricted_support);
9549
9550 eht_cap->restricted_twt = restricted_support;
9551 }
9552 #else
9553 static inline void
9554 populate_dot11f_rtwt_eht_cap(struct mac_context *mac,
9555 tDot11fIEeht_cap *eht_cap)
9556 {
9557 eht_cap->restricted_twt = false;
9558 }
9559 #endif
9560 static void
9561 populate_dot11f_revise_eht_caps(struct pe_session *session,
9562 tDot11fIEeht_cap *eht_cap)
9563 {
9564 if (session->ch_width != CH_WIDTH_320MHZ)
9565 eht_cap->support_320mhz_6ghz = 0;
9566
9567 if (wlan_epcs_get_config(session->vdev))
9568 eht_cap->epcs_pri_access = 1;
9569 else
9570 eht_cap->epcs_pri_access = 0;
9571 }
9572
9573 QDF_STATUS populate_dot11f_eht_caps(struct mac_context *mac_ctx,
9574 struct pe_session *session,
9575 tDot11fIEeht_cap *eht_cap)
9576 {
9577 eht_cap->present = 1;
9578
9579 if (!session) {
9580 qdf_mem_copy(eht_cap,
9581 &mac_ctx->mlme_cfg->eht_caps.dot11_eht_cap,
9582 sizeof(tDot11fIEeht_cap));
9583 return QDF_STATUS_SUCCESS;
9584 }
9585
9586 /** TODO: String items needs attention. **/
9587 qdf_mem_copy(eht_cap, &session->eht_config, sizeof(*eht_cap));
9588 populate_dot11f_revise_eht_caps(session, eht_cap);
9589
9590 populate_dot11f_rtwt_eht_cap(mac_ctx, eht_cap);
9591 return QDF_STATUS_SUCCESS;
9592 }
9593
9594 QDF_STATUS
9595 populate_dot11f_eht_caps_by_band(struct mac_context *mac_ctx,
9596 bool is_2g, tDot11fIEeht_cap *eht_cap,
9597 struct pe_session *session)
9598 {
9599 pe_debug("is_2g %d", is_2g);
9600 if (is_2g)
9601 qdf_mem_copy(eht_cap,
9602 &mac_ctx->eht_cap_2g,
9603 sizeof(tDot11fIEeht_cap));
9604 else
9605 qdf_mem_copy(eht_cap,
9606 &mac_ctx->eht_cap_5g,
9607 sizeof(tDot11fIEeht_cap));
9608 if (session)
9609 populate_dot11f_revise_eht_caps(session, eht_cap);
9610
9611 populate_dot11f_rtwt_eht_cap(mac_ctx, eht_cap);
9612 return QDF_STATUS_SUCCESS;
9613 }
9614
9615 QDF_STATUS lim_strip_and_decode_eht_op(uint8_t *ie, uint16_t ie_len,
9616 tDot11fIEeht_op *dot11f_eht_op,
9617 tDot11fIEVHTOperation dot11f_vht_op,
9618 tDot11fIEhe_op dot11f_he_op,
9619 tDot11fIEHTInfo dot11f_ht_info)
9620 {
9621 const uint8_t *eht_op_ie;
9622 QDF_STATUS status;
9623
9624 eht_op_ie = lim_get_ext_ie_ptr_from_ext_id(ie, ie_len,
9625 EHT_OP_OUI_TYPE,
9626 EHT_OP_OUI_SIZE);
9627
9628 if (!eht_op_ie)
9629 return QDF_STATUS_SUCCESS;
9630
9631 status = lim_ieee80211_unpack_ehtop(eht_op_ie, dot11f_eht_op,
9632 dot11f_vht_op, dot11f_he_op,
9633 dot11f_ht_info);
9634
9635 if (status != QDF_STATUS_SUCCESS) {
9636 pe_err("Failed to extract eht op");
9637 return QDF_STATUS_E_FAILURE;
9638 }
9639
9640 return QDF_STATUS_SUCCESS;
9641 }
9642
9643 void lim_ieee80211_pack_ehtop(uint8_t *ie, tDot11fIEeht_op dot11f_eht_op,
9644 tDot11fIEVHTOperation dot11f_vht_op,
9645 tDot11fIEhe_op dot11f_he_op,
9646 tDot11fIEHTInfo dot11f_ht_info)
9647 {
9648 struct wlan_ie_ehtops *ehtop = (struct wlan_ie_ehtops *)ie;
9649 uint32_t val;
9650 uint32_t i;
9651 uint32_t eht_op_info_len = 0;
9652 uint32_t ehtoplen;
9653 bool diff_chan_width = false;
9654
9655 if (!ie) {
9656 pe_err("ie is null");
9657 return;
9658 }
9659
9660 qdf_mem_zero(ehtop, (sizeof(struct wlan_ie_ehtops)));
9661
9662 ehtop->elem_id = DOT11F_EID_EHT_OP;
9663
9664 qdf_mem_copy(&ehtop->elem_id_extn, EHT_OP_OUI_TYPE, EHT_OP_OUI_SIZE);
9665
9666 if (dot11f_he_op.present && dot11f_he_op.oper_info_6g_present &&
9667 (dot11f_he_op.oper_info_6g.info.ch_width !=
9668 dot11f_eht_op.channel_width)) {
9669 diff_chan_width = true;
9670 } else if (dot11f_vht_op.present &&
9671 (dot11f_vht_op.chanWidth != dot11f_eht_op.channel_width)) {
9672 diff_chan_width = true;
9673 } else if (dot11f_ht_info.present &&
9674 (dot11f_ht_info.recommendedTxWidthSet !=
9675 dot11f_eht_op.channel_width)) {
9676 diff_chan_width = true;
9677 }
9678
9679 if (diff_chan_width) {
9680 val = dot11f_eht_op.eht_op_information_present;
9681 EHTOP_PARAMS_INFOP_SET_TO_IE(ehtop->ehtop_param, val);
9682 }
9683
9684 val = dot11f_eht_op.eht_default_pe_duration;
9685 EHTOP_PARAMS_EHT_DEF_PE_DURATION_SET_TO_IE(ehtop->ehtop_param, val);
9686
9687 val = dot11f_eht_op.group_addr_bu_indication_limit;
9688 EHTOP_PARAMS_GROUP_ADDR_BU_IND_LIMIT_SET_TO_IE(ehtop->ehtop_param, val);
9689
9690 val = dot11f_eht_op.group_addr_bu_indication_exponent;
9691 EHTOP_PARAMS_GROUP_ADDR_BU_IND_EXPONENT_SET_TO_IE(ehtop->ehtop_param,
9692 val);
9693
9694 val = dot11f_eht_op.basic_rx_max_nss_for_mcs_0_to_7;
9695 ehtop_ie_set(&ehtop->basic_mcs_nss_set.max_nss_mcs_0_7,
9696 EHTOP_RX_MCS_NSS_MAP_IDX,
9697 EHTOP_RX_MCS_NSS_MAP_BITS, val);
9698 val = dot11f_eht_op.basic_tx_max_nss_for_mcs_0_to_7;
9699 ehtop_ie_set(&ehtop->basic_mcs_nss_set.max_nss_mcs_0_7,
9700 EHTOP_TX_MCS_NSS_MAP_IDX,
9701 EHTOP_TX_MCS_NSS_MAP_BITS, val);
9702
9703 val = dot11f_eht_op.basic_rx_max_nss_for_mcs_8_and_9;
9704 ehtop_ie_set(&ehtop->basic_mcs_nss_set.max_nss_mcs_8_9,
9705 EHTOP_RX_MCS_NSS_MAP_IDX,
9706 EHTOP_RX_MCS_NSS_MAP_BITS, val);
9707 val = dot11f_eht_op.basic_tx_max_nss_for_mcs_8_and_9;
9708 ehtop_ie_set(&ehtop->basic_mcs_nss_set.max_nss_mcs_8_9,
9709 EHTOP_TX_MCS_NSS_MAP_IDX,
9710 EHTOP_TX_MCS_NSS_MAP_BITS, val);
9711
9712 val = dot11f_eht_op.basic_rx_max_nss_for_mcs_10_and_11;
9713 ehtop_ie_set(&ehtop->basic_mcs_nss_set.max_nss_mcs_10_11,
9714 EHTOP_RX_MCS_NSS_MAP_IDX,
9715 EHTOP_RX_MCS_NSS_MAP_BITS, val);
9716 val = dot11f_eht_op.basic_tx_max_nss_for_mcs_10_and_11;
9717 ehtop_ie_set(&ehtop->basic_mcs_nss_set.max_nss_mcs_10_11,
9718 EHTOP_TX_MCS_NSS_MAP_IDX,
9719 EHTOP_TX_MCS_NSS_MAP_BITS, val);
9720
9721 val = dot11f_eht_op.basic_rx_max_nss_for_mcs_12_and_13;
9722 ehtop_ie_set(&ehtop->basic_mcs_nss_set.max_nss_mcs_12_13,
9723 EHTOP_RX_MCS_NSS_MAP_IDX,
9724 EHTOP_RX_MCS_NSS_MAP_BITS, val);
9725 val = dot11f_eht_op.basic_tx_max_nss_for_mcs_12_and_13;
9726 ehtop_ie_set(&ehtop->basic_mcs_nss_set.max_nss_mcs_12_13,
9727 EHTOP_TX_MCS_NSS_MAP_IDX,
9728 EHTOP_TX_MCS_NSS_MAP_BITS, val);
9729
9730 if (EHTOP_PARAMS_INFOP_GET_FROM_IE(ehtop->ehtop_param)) {
9731 val = dot11f_eht_op.channel_width;
9732 EHTOP_INFO_CHANWIDTH_SET_TO_IE(ehtop->control, val);
9733
9734 ehtop->ccfs0 = dot11f_eht_op.ccfs0;
9735
9736 ehtop->ccfs1 = dot11f_eht_op.ccfs1;
9737 /*1 byte for Control, 1 byte for CCFS0, 1 bytes for CCFS1*/
9738 eht_op_info_len += 3;
9739
9740 if (dot11f_eht_op.disabled_sub_chan_bitmap_present) {
9741 val = dot11f_eht_op.disabled_sub_chan_bitmap_present;
9742 EHTOP_PARAMS_DISABLEDSUBCHANBITMAPP_SET_TO_IE(ehtop->ehtop_param, val);
9743
9744 eht_op_info_len += WLAN_MAX_DISABLED_SUB_CHAN_BITMAP;
9745
9746 for (i = 0; i < WLAN_MAX_DISABLED_SUB_CHAN_BITMAP; i++)
9747 ehtop->disabled_sub_chan_bitmap[i] =
9748 dot11f_eht_op.disabled_sub_chan_bitmap[0][i];
9749 }
9750 }
9751
9752 ehtop->elem_len = EHTOP_FIXED_LEN + eht_op_info_len;
9753 ehtoplen = ehtop->elem_len + WLAN_IE_HDR_LEN;
9754 }
9755
9756 QDF_STATUS populate_dot11f_eht_operation(struct mac_context *mac_ctx,
9757 struct pe_session *session,
9758 tDot11fIEeht_op *eht_op)
9759 {
9760 enum phy_ch_width oper_ch_width;
9761
9762 qdf_mem_copy(eht_op, &session->eht_op, sizeof(*eht_op));
9763
9764 eht_op->present = 1;
9765
9766 eht_op->eht_op_information_present = 1;
9767
9768 oper_ch_width = wlan_mlme_get_ap_oper_ch_width(session->vdev);
9769 if (oper_ch_width == CH_WIDTH_320MHZ) {
9770 eht_op->channel_width = WLAN_EHT_CHWIDTH_320;
9771 eht_op->ccfs0 = session->ch_center_freq_seg0;
9772 eht_op->ccfs1 = session->ch_center_freq_seg1;
9773 } else if (oper_ch_width == CH_WIDTH_160MHZ ||
9774 oper_ch_width == CH_WIDTH_80P80MHZ) {
9775 eht_op->channel_width = WLAN_EHT_CHWIDTH_160;
9776 eht_op->ccfs0 = session->ch_center_freq_seg0;
9777 eht_op->ccfs1 = session->ch_center_freq_seg1;
9778 } else if (oper_ch_width == CH_WIDTH_80MHZ) {
9779 eht_op->channel_width = WLAN_EHT_CHWIDTH_80;
9780 eht_op->ccfs0 = session->ch_center_freq_seg0;
9781 eht_op->ccfs1 = 0;
9782 } else if (oper_ch_width == CH_WIDTH_40MHZ) {
9783 eht_op->channel_width = WLAN_EHT_CHWIDTH_40;
9784 eht_op->ccfs0 = session->ch_center_freq_seg0;
9785 eht_op->ccfs1 = 0;
9786 } else if (oper_ch_width == CH_WIDTH_20MHZ) {
9787 eht_op->channel_width = WLAN_EHT_CHWIDTH_20;
9788 eht_op->ccfs0 = session->ch_center_freq_seg0;
9789 eht_op->ccfs1 = 0;
9790 }
9791
9792 lim_log_eht_op(mac_ctx, eht_op, session);
9793
9794 return QDF_STATUS_SUCCESS;
9795 }
9796
9797
9798 QDF_STATUS populate_dot11f_bw_ind_element(struct mac_context *mac_ctx,
9799 struct pe_session *session,
9800 tDot11fIEbw_ind_element *bw_ind)
9801 {
9802 tLimChannelSwitchInfo *ch_switch;
9803
9804 ch_switch = &session->gLimChannelSwitch;
9805 bw_ind->present = true;
9806 bw_ind->channel_width = wlan_mlme_convert_phy_ch_width_to_eht_op_bw(
9807 ch_switch->ch_width);
9808 if (ch_switch->puncture_bitmap) {
9809 bw_ind->disabled_sub_chan_bitmap_present = 1;
9810 bw_ind->disabled_sub_chan_bitmap[0][0] =
9811 QDF_GET_BITS(ch_switch->puncture_bitmap, 0, 8);
9812 bw_ind->disabled_sub_chan_bitmap[0][1] =
9813 QDF_GET_BITS(ch_switch->puncture_bitmap, 8, 8);
9814 }
9815 bw_ind->ccfs0 = ch_switch->ch_center_freq_seg0;
9816 bw_ind->ccfs1 = ch_switch->ch_center_freq_seg1;
9817
9818 return QDF_STATUS_SUCCESS;
9819 }
9820
9821 #endif /* WLAN_FEATURE_11BE */
9822
9823 #ifdef WLAN_FEATURE_11BE_MLO
9824 QDF_STATUS
9825 populate_dot11f_probe_req_mlo_ie(struct mac_context *mac,
9826 struct pe_session *session)
9827 {
9828 struct wlan_mlo_ie *mlo_ie;
9829 uint8_t *p_ml_ie, *sta_data;
9830 uint16_t len_remaining, sta_len_left;
9831 struct wlan_mlo_sta_profile *sta_pro;
9832 int num_sta_pro = 0;
9833 struct mlo_partner_info partner_info;
9834 uint8_t link;
9835
9836 if (!session || !session->vdev || !session->vdev->mlo_dev_ctx) {
9837 pe_err("Null value");
9838 return QDF_STATUS_E_NULL_VALUE;
9839 }
9840
9841 mlo_ie = &session->mlo_ie;
9842 p_ml_ie = mlo_ie->data;
9843 len_remaining = sizeof(mlo_ie->data);
9844
9845 *p_ml_ie++ = WLAN_ELEMID_EXTN_ELEM;
9846 len_remaining--;
9847
9848 /* set length later */
9849 *p_ml_ie++ = 0;
9850 len_remaining--;
9851
9852 *p_ml_ie++ = WLAN_EXTN_ELEMID_MULTI_LINK;
9853 len_remaining--;
9854
9855 /* Set ML IE multi link control bitmap:
9856 * ML probe variant type = 1
9857 * In presence bitmap, set MLD ID presence bit = 1
9858 */
9859 mlo_ie->type = WLAN_ML_VARIANT_PROBEREQ;
9860 QDF_SET_BITS(*(uint16_t *)p_ml_ie, WLAN_ML_CTRL_TYPE_IDX,
9861 WLAN_ML_CTRL_TYPE_BITS, mlo_ie->type);
9862 QDF_SET_BITS(*(uint16_t *)p_ml_ie, WLAN_ML_CTRL_PBM_IDX,
9863 WLAN_ML_CTRL_PBM_BITS, 1);
9864
9865 p_ml_ie += WLAN_ML_CTRL_SIZE;
9866 len_remaining -= WLAN_ML_CTRL_SIZE;
9867
9868 /* common info length is 2 */
9869 *p_ml_ie++ = 2;
9870 len_remaining--;
9871
9872 /* mld id is always 0 for tx link for SAP or AP */
9873 *p_ml_ie++ = 0;
9874 len_remaining--;
9875
9876 mlo_ie->num_data = p_ml_ie - mlo_ie->data;
9877
9878 if (wlan_vdev_mlme_cap_get(session->vdev,
9879 WLAN_VDEV_C_EXCL_STA_PROF_PRB_REQ)) {
9880 pe_debug("Do not populate sta profile in MLO IE");
9881 goto no_sta_prof;
9882 }
9883
9884 partner_info = session->lim_join_req->partner_info;
9885 for (link = 0; link < partner_info.num_partner_links; link++) {
9886 sta_pro = &mlo_ie->sta_profile[num_sta_pro];
9887 sta_data = sta_pro->data;
9888 sta_len_left = sizeof(sta_pro->data);
9889
9890 *sta_data++ = WLAN_ML_LINFO_SUBELEMID_PERSTAPROFILE;
9891 sta_len_left--;
9892 /* length of subelement, filled at last */
9893 *sta_data++ = 0;
9894 sta_len_left--;
9895
9896 QDF_SET_BITS(*(uint16_t *)sta_data,
9897 WLAN_ML_BV_LINFO_PERSTAPROF_STACTRL_LINKID_IDX,
9898 WLAN_ML_BV_LINFO_PERSTAPROF_STACTRL_LINKID_BITS,
9899 partner_info.partner_link_info[link].link_id);
9900
9901 QDF_SET_BITS(*(uint16_t *)sta_data,
9902 WLAN_ML_BV_LINFO_PERSTAPROF_STACTRL_CMPLTPROF_IDX,
9903 WLAN_ML_BV_LINFO_PERSTAPROF_STACTRL_CMPLTPROF_BITS,
9904 1);
9905 sta_data += WLAN_ML_BV_LINFO_PERSTAPROF_STACTRL_SIZE;
9906 sta_len_left -= WLAN_ML_BV_LINFO_PERSTAPROF_STACTRL_SIZE;
9907
9908 sta_pro->num_data = sta_data - sta_pro->data;
9909 sta_pro->data[TAG_LEN_POS] = sta_pro->num_data - MIN_IE_LEN;
9910
9911 num_sta_pro++;
9912 }
9913
9914 no_sta_prof:
9915 mlo_ie->num_sta_profile = num_sta_pro;
9916 session->lim_join_req->is_ml_probe_req_sent = true;
9917
9918 return QDF_STATUS_SUCCESS;
9919 }
9920
9921 #if defined(SAP_MULTI_LINK_EMULATION)
9922 QDF_STATUS populate_dot11f_assoc_rsp_mlo_ie(struct mac_context *mac_ctx,
9923 struct pe_session *session,
9924 tpDphHashNode sta,
9925 tDot11fAssocResponse *frm)
9926 {
9927 struct wlan_mlo_ie *mlo_ie;
9928 struct wlan_mlo_sta_profile *sta_pro;
9929 tpSirAssocReq assoc_req;
9930 uint8_t *sta_data;
9931 uint32_t sta_len_left;
9932 uint8_t common_info_len = 0;
9933 uint8_t *p_ml_ie;
9934 uint16_t len_remaining;
9935 uint16_t presence_bitmap = 0;
9936 uint16_t sta_prof_len;
9937 uint8_t sta_prof_[] = {0x00, 0xff, 0xf1, 0x01, 0x13, 0x02, 0x03, 0x7f, 0x95, 0xaf, 0x62, 0x64, 0x00, 0x54, 0x00, 0x00,
9938 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x31, 0x04, 0x00, 0x00, 0x01, 0x08, 0x8c, 0x12, 0x98, 0x24, 0xb0,
9939 0x48, 0x60, 0x6c, 0x07, 0x0a, 0x55, 0x53, 0x04, 0xc9, 0x83, 0x00, 0x01, 0x3b, 0x00, 0x00, 0x20,
9940 0x01, 0x00, 0x23, 0x02, 0x0a, 0x00, 0x32, 0x01, 0xfb, 0x7f, 0x0b, 0x04, 0x00, 0x4f, 0x02, 0x00,
9941 0x00, 0x00, 0x40, 0x00, 0x40, 0x19, 0xc3, 0x02, 0x58, 0x0a, 0xc3, 0x02, 0x18, 0xfe, 0xff, 0x23,
9942 0x23, 0x0d, 0x01, 0x08, 0x1a, 0x40, 0x10, 0x00, 0x63, 0x40, 0x88, 0x1f, 0x43, 0x81, 0x1c, 0x11,
9943 0x08, 0x00, 0xaa, 0xff, 0xaa, 0xff, 0x7b, 0x1c, 0xc7, 0x71, 0x1c, 0xc7, 0x71, 0x1c, 0xc7, 0x71,
9944 0x1c, 0xc7, 0x71, 0xff, 0x0c, 0x24, 0xf4, 0x3f, 0x02, 0x28, 0xfc, 0xff, 0x25, 0x00, 0x25, 0x00,
9945 0x01, 0xff, 0x0e, 0x26, 0x00, 0x03, 0xa4, 0xff, 0x27, 0xa4, 0xff, 0x42, 0x43, 0xff, 0x62, 0x32,
9946 0xff, 0xff, 0x03, 0x3b, 0xb8, 0x36, 0xff, 0x0f, 0x6c, 0x17, 0x00, 0xe0, 0x03, 0x03, 0x00, 0x18,
9947 0x76, 0xd8, 0x12, 0x00, 0x44, 0x44, 0x44, 0xff, 0x06, 0x6a, 0x04, 0x11, 0x00, 0x00, 0x00};
9948 QDF_STATUS status;
9949
9950 if (!mac_ctx || !session || !frm)
9951 return QDF_STATUS_E_NULL_VALUE;
9952
9953 mlo_ie = &session->mlo_ie;
9954
9955 p_ml_ie = mlo_ie->data;
9956 len_remaining = sizeof(mlo_ie->data);
9957
9958 *p_ml_ie++ = WLAN_ELEMID_EXTN_ELEM;
9959 len_remaining--;
9960 /* set length later */
9961 *p_ml_ie++ = 0;
9962 len_remaining--;
9963 *p_ml_ie++ = WLAN_EXTN_ELEMID_MULTI_LINK;
9964 len_remaining--;
9965
9966 mlo_ie->type = 0;
9967 /* Common Info Length*/
9968 common_info_len += WLAN_ML_BV_CINFO_LENGTH_SIZE;
9969 qdf_mem_copy(mlo_ie->mld_mac_addr,
9970 session->vdev->mlo_dev_ctx->mld_addr.bytes,
9971 sizeof(mlo_ie->mld_mac_addr));
9972 common_info_len += QDF_MAC_ADDR_SIZE;
9973
9974 mlo_ie->link_id_info_present = 1;
9975 presence_bitmap |= WLAN_ML_BV_CTRL_PBM_LINKIDINFO_P;
9976 mlo_ie->link_id = wlan_vdev_get_link_id(session->vdev);
9977 common_info_len += WLAN_ML_BV_CINFO_LINKIDINFO_SIZE;
9978
9979 mlo_ie->bss_param_change_cnt_present = 1;
9980 presence_bitmap |= WLAN_ML_BV_CTRL_PBM_BSSPARAMCHANGECNT_P;
9981 mlo_ie->bss_param_change_count =
9982 session->mlo_link_info.link_ie.bss_param_change_cnt;
9983 common_info_len += WLAN_ML_BSSPARAMCHNGCNT_SIZE;
9984
9985 mlo_ie->mld_capab_and_op_present = 1;
9986 mlo_ie->mld_id_present = 1;
9987 mlo_ie->ext_mld_capab_and_op_present = 1;
9988 common_info_len += WLAN_ML_BV_CINFO_MLDCAPANDOP_SIZE;
9989 presence_bitmap |= WLAN_ML_BV_CTRL_PBM_MLDCAPANDOP_P;
9990
9991 common_info_len += WLAN_ML_BV_CINFO_EMLCAP_SIZE;
9992 presence_bitmap |= WLAN_ML_BV_CTRL_PBM_EMLCAP_P;
9993
9994 common_info_len += WLAN_ML_BV_CINFO_MLDCAPANDOP_SIZE;
9995 presence_bitmap |= WLAN_ML_BV_CTRL_PBM_MEDIUMSYNCDELAYINFO_P;
9996
9997 mlo_ie->common_info_length = common_info_len;
9998
9999 QDF_SET_BITS(*(uint16_t *)p_ml_ie, WLAN_ML_CTRL_TYPE_IDX,
10000 WLAN_ML_CTRL_TYPE_BITS, mlo_ie->type);
10001 QDF_SET_BITS(*(uint16_t *)p_ml_ie, WLAN_ML_CTRL_PBM_IDX,
10002 WLAN_ML_CTRL_PBM_BITS, presence_bitmap);
10003 p_ml_ie += WLAN_ML_CTRL_SIZE;
10004 len_remaining -= WLAN_ML_CTRL_SIZE;
10005
10006 *p_ml_ie++ = common_info_len;
10007 len_remaining--;
10008
10009 qdf_mem_copy(p_ml_ie, mlo_ie->mld_mac_addr, QDF_MAC_ADDR_SIZE);
10010 p_ml_ie += QDF_MAC_ADDR_SIZE;
10011 len_remaining -= QDF_MAC_ADDR_SIZE;
10012
10013 QDF_SET_BITS(*p_ml_ie, WLAN_ML_BV_CINFO_LINKIDINFO_LINKID_IDX,
10014 WLAN_ML_BV_CINFO_LINKIDINFO_LINKID_BITS, mlo_ie->link_id);
10015 p_ml_ie++;
10016 len_remaining--;
10017
10018 *p_ml_ie++ = mlo_ie->bss_param_change_count;
10019 len_remaining--;
10020
10021 p_ml_ie += WLAN_ML_BV_CINFO_MLDCAPANDOP_SIZE;
10022 p_ml_ie += WLAN_ML_BV_CINFO_MLDCAPANDOP_SIZE;
10023 len_remaining -= WLAN_ML_BV_CINFO_MLDCAPANDOP_SIZE;
10024 len_remaining -= WLAN_ML_BV_CINFO_MLDCAPANDOP_SIZE;
10025
10026 if (mlo_ie->mld_capab_and_op_present) {
10027 QDF_SET_BITS(*(uint16_t *)p_ml_ie,
10028 WLAN_ML_BV_CINFO_MLDCAPANDOP_MAXSIMULLINKS_IDX,
10029 WLAN_ML_BV_CINFO_MLDCAPANDOP_MAXSIMULLINKS_BITS,
10030 mlo_ie->mld_capab_and_op_info.max_simultaneous_link_num);
10031 QDF_SET_BITS(*(uint16_t *)p_ml_ie,
10032 WLAN_ML_BV_CINFO_MLDCAPANDOP_TIDTOLINKMAPNEGSUPPORT_IDX,
10033 WLAN_ML_BV_CINFO_MLDCAPANDOP_TIDTOLINKMAPNEGSUPPORT_BITS,
10034 mlo_ie->mld_capab_and_op_info.tid_link_map_supported);
10035 p_ml_ie += WLAN_ML_BV_CINFO_MLDCAPANDOP_SIZE;
10036 len_remaining -= WLAN_ML_BV_CINFO_MLDCAPANDOP_SIZE;
10037 }
10038
10039 mlo_ie->num_data = p_ml_ie - mlo_ie->data;
10040
10041 sta_prof_[5] = session->self_mac_addr[0];
10042 sta_prof_[6] = session->self_mac_addr[1];
10043 sta_prof_[7] = session->self_mac_addr[2];
10044 sta_prof_[8] = session->self_mac_addr[3];
10045
10046 sta_prof_[9] = 0xaf;
10047 sta_prof_[10] = 0x62;
10048
10049 sta_pro = &mlo_ie->sta_profile[0];
10050 sta_data = sta_pro->data;
10051 sta_len_left = sizeof(sta_pro->data);
10052
10053 sta_prof_len = ARRAY_SIZE(sta_prof_);
10054 qdf_mem_copy(sta_data, sta_prof_, sta_prof_len);
10055 sta_data += sta_prof_len;
10056 sta_len_left -= sta_prof_len;
10057
10058 sta_pro->num_data = sta_data - sta_pro->data;
10059 pe_debug("num data: %d, sta_prof_len: %d, sta_data len: %d",
10060 sta_pro->num_data, sta_prof_len, sizeof(sta_pro->data));
10061 sta_pro->data[TAG_LEN_POS] = sta_pro->num_data - MIN_IE_LEN;
10062
10063 mlo_ie->num_sta_profile = 1;
10064 mlo_ie->mld_capab_and_op_info.max_simultaneous_link_num = 1;
10065
10066 if (sta_pro->num_data > WLAN_MAX_IE_LEN + MIN_IE_LEN) {
10067 sta_pro->data[TAG_LEN_POS] = WLAN_MAX_IE_LEN;
10068 status =
10069 lim_add_frag_ie_for_sta_profile(sta_pro->data,
10070 &sta_pro->num_data);
10071 if (status != QDF_STATUS_SUCCESS) {
10072 pe_debug("add frg ie for sta profile error.");
10073 sta_pro->num_data =
10074 WLAN_MAX_IE_LEN + MIN_IE_LEN;
10075 }
10076 } else {
10077 sta_pro->data[TAG_LEN_POS] =
10078 sta_pro->num_data - MIN_IE_LEN;
10079 }
10080 assoc_req = session->parsedAssocReq[sta->assocId];
10081
10082 pe_debug("num partner links: %d", assoc_req->mlo_info.num_partner_links);
10083 return QDF_STATUS_SUCCESS;
10084 }
10085
10086 QDF_STATUS populate_dot11f_bcn_mlo_ie(struct mac_context *mac_ctx,
10087 struct pe_session *session)
10088 {
10089 struct wlan_mlo_ie *mlo_ie;
10090 struct wlan_mlo_sta_profile *sta_pro;
10091 uint16_t vdev_count;
10092 struct wlan_objmgr_vdev *wlan_vdev_list[WLAN_UMAC_MLO_MAX_VDEVS];
10093 uint16_t tmp_offset = 0;
10094 struct ml_sch_partner_info *tmp_info;
10095 struct mlo_sch_partner_links *sch_info;
10096 uint8_t *sta_data;
10097 uint8_t common_info_length = 0;
10098 uint8_t *p_ml_ie;
10099 uint16_t len_remaining;
10100 uint16_t presence_bitmap = 0;
10101 uint32_t sta_len_left;
10102 QDF_STATUS status;
10103 uint16_t sta_prof_len;
10104 uint8_t sta_prof_[] = {0x00, 0xff, 0xf1, 0x01, 0x13, 0x02, 0x03, 0x7f, 0x95, 0xaf, 0x62, 0x64, 0x00, 0x54, 0x00, 0x00,
10105 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x11, 0x05, 0x01, 0x08, 0x8c, 0x12, 0x98, 0x24, 0xb0,
10106 0x48, 0x60, 0x6c, 0x07, 0x0a, 0x55, 0x53, 0x04, 0xc9, 0x83, 0x00, 0x01, 0x3b, 0x00, 0x00, 0x20,
10107 0x01, 0x00, 0x23, 0x02, 0x0a, 0x00, 0x32, 0x01, 0xfb, 0x7f, 0x0b, 0x04, 0x00, 0x4f, 0x02, 0x00,
10108 0x00, 0x00, 0x40, 0x00, 0x40, 0x19, 0xc3, 0x02, 0x58, 0x0a, 0xc3, 0x02, 0x18, 0xfe, 0xff, 0x23,
10109 0x23, 0x0d, 0x01, 0x08, 0x1a, 0x40, 0x10, 0x00, 0x63, 0x40, 0x88, 0x1f, 0x43, 0x81, 0x1c, 0x11,
10110 0x08, 0x00, 0xaa, 0xff, 0xaa, 0xff, 0x7b, 0x1c, 0xc7, 0x71, 0x1c, 0xc7, 0x71, 0x1c, 0xc7, 0x71,
10111 0x1c, 0xc7, 0x71, 0xff, 0x0c, 0x24, 0xf4, 0x3f, 0x02, 0x28, 0xfc, 0xff, 0x25, 0x00, 0x25, 0x00,
10112 0x01, 0xff, 0x0e, 0x26, 0x00, 0x03, 0xa4, 0xff, 0x27, 0xa4, 0xff, 0x42, 0x43, 0xff, 0x62, 0x32,
10113 0xff, 0xff, 0x03, 0x3b, 0xb8, 0x36, 0xff, 0x0f, 0x6c, 0x17, 0x00, 0xe0, 0x03, 0x03, 0x00, 0x18,
10114 0x76, 0xd8, 0x12, 0x00, 0x44, 0x44, 0x44, 0xff, 0x06, 0x6a, 0x04, 0x11, 0x00, 0x00, 0x00};
10115 if (!mac_ctx || !session)
10116 return QDF_STATUS_E_NULL_VALUE;
10117
10118 mlo_ie = &session->mlo_ie;
10119
10120 /* Common Info Length */
10121 common_info_length += WLAN_ML_BV_CINFO_LENGTH_SIZE;
10122 qdf_mem_zero(&mac_ctx->sch.sch_mlo_partner,
10123 sizeof(mac_ctx->sch.sch_mlo_partner));
10124 sch_info = &mac_ctx->sch.sch_mlo_partner;
10125 mlo_ie->type = 0;
10126 tmp_offset += 1; /* Element ID */
10127 tmp_offset += 1; /* length */
10128 tmp_offset += 1; /* Element ID extension */
10129 tmp_offset += 2; /* Multi-link control */
10130 qdf_mem_copy(mlo_ie->mld_mac_addr,
10131 session->vdev->mlo_dev_ctx->mld_addr.bytes,
10132 sizeof(mlo_ie->mld_mac_addr));
10133 tmp_offset += 1; /* Common Info Length */
10134 tmp_offset += 6; /* mld mac addr */
10135 common_info_length += QDF_MAC_ADDR_SIZE;
10136 mlo_ie->link_id_info_present = 1;
10137 presence_bitmap |= WLAN_ML_BV_CTRL_PBM_LINKIDINFO_P;
10138 mlo_ie->link_id = wlan_vdev_get_link_id(session->vdev);
10139 tmp_offset += 1; /* link id */
10140 common_info_length += WLAN_ML_BV_CINFO_LINKIDINFO_SIZE;
10141 mlo_ie->bss_param_change_cnt_present = 1;
10142 presence_bitmap |= WLAN_ML_BV_CTRL_PBM_BSSPARAMCHANGECNT_P;
10143 mlo_ie->bss_param_change_count =
10144 session->mlo_link_info.link_ie.bss_param_change_cnt;
10145 tmp_offset += 1; /* bss parameters change count */
10146 common_info_length += WLAN_ML_BSSPARAMCHNGCNT_SIZE;
10147
10148 tmp_offset += 2;/* MLD Parameters */
10149 mlo_ie->mld_capab_and_op_present = 1;
10150 mlo_ie->mld_id_present = 1;
10151 mlo_ie->ext_mld_capab_and_op_present = 1;
10152 sch_info->num_links = 1;
10153 common_info_length += WLAN_ML_BV_CINFO_MLDCAPANDOP_SIZE;
10154 presence_bitmap |= WLAN_ML_BV_CTRL_PBM_MLDCAPANDOP_P;
10155
10156 tmp_offset += 2;
10157 common_info_length += WLAN_ML_BV_CINFO_EMLCAP_SIZE;
10158 presence_bitmap |= WLAN_ML_BV_CTRL_PBM_EMLCAP_P;
10159
10160 tmp_offset += 2;
10161 common_info_length += WLAN_ML_BV_CINFO_MLDCAPANDOP_SIZE;
10162 presence_bitmap |= WLAN_ML_BV_CTRL_PBM_MEDIUMSYNCDELAYINFO_P;
10163
10164 lim_get_mlo_vdev_list(session, &vdev_count, wlan_vdev_list);
10165 mlo_ie->mld_capab_and_op_info.max_simultaneous_link_num =
10166 vdev_count;
10167
10168 mlo_ie->mld_capab_and_op_info.tid_link_map_supported = 1;
10169
10170 mlo_ie->common_info_length = common_info_length;
10171 sch_info->mlo_ie_link_info_ofst = tmp_offset;
10172
10173 p_ml_ie = mlo_ie->data;
10174 len_remaining = sizeof(mlo_ie->data);
10175
10176 *p_ml_ie++ = WLAN_ELEMID_EXTN_ELEM;
10177 len_remaining--;
10178 *p_ml_ie++ = 0;
10179 len_remaining--;
10180 *p_ml_ie++ = WLAN_EXTN_ELEMID_MULTI_LINK;
10181 len_remaining--;
10182
10183 QDF_SET_BITS(*(uint16_t *)p_ml_ie, WLAN_ML_CTRL_TYPE_IDX,
10184 WLAN_ML_CTRL_TYPE_BITS, mlo_ie->type);
10185 QDF_SET_BITS(*(uint16_t *)p_ml_ie, WLAN_ML_CTRL_PBM_IDX,
10186 WLAN_ML_CTRL_PBM_BITS, presence_bitmap);
10187 p_ml_ie += WLAN_ML_CTRL_SIZE;
10188 len_remaining -= WLAN_ML_CTRL_SIZE;
10189
10190 *p_ml_ie++ = common_info_length;
10191 len_remaining--;
10192
10193 qdf_mem_copy(p_ml_ie, mlo_ie->mld_mac_addr, QDF_MAC_ADDR_SIZE);
10194 p_ml_ie += QDF_MAC_ADDR_SIZE;
10195 len_remaining -= QDF_MAC_ADDR_SIZE;
10196
10197 QDF_SET_BITS(*p_ml_ie, WLAN_ML_BV_CINFO_LINKIDINFO_LINKID_IDX,
10198 WLAN_ML_BV_CINFO_LINKIDINFO_LINKID_BITS,
10199 mlo_ie->link_id);
10200 p_ml_ie++;
10201 len_remaining--;
10202
10203 *p_ml_ie++ = mlo_ie->bss_param_change_count;
10204 len_remaining--;
10205
10206 p_ml_ie += WLAN_ML_BV_CINFO_MLDCAPANDOP_SIZE;
10207 p_ml_ie += WLAN_ML_BV_CINFO_MLDCAPANDOP_SIZE;
10208 len_remaining -= WLAN_ML_BV_CINFO_MLDCAPANDOP_SIZE;
10209 len_remaining -= WLAN_ML_BV_CINFO_MLDCAPANDOP_SIZE;
10210
10211 if (mlo_ie->mld_capab_and_op_present) {
10212 QDF_SET_BITS(*(uint16_t *)p_ml_ie,
10213 WLAN_ML_BV_CINFO_MLDCAPANDOP_MAXSIMULLINKS_IDX,
10214 WLAN_ML_BV_CINFO_MLDCAPANDOP_MAXSIMULLINKS_BITS,
10215 mlo_ie->mld_capab_and_op_info.max_simultaneous_link_num);
10216 QDF_SET_BITS(*(uint16_t *)p_ml_ie,
10217 WLAN_ML_BV_CINFO_MLDCAPANDOP_TIDTOLINKMAPNEGSUPPORT_IDX,
10218 WLAN_ML_BV_CINFO_MLDCAPANDOP_TIDTOLINKMAPNEGSUPPORT_BITS,
10219 mlo_ie->mld_capab_and_op_info.tid_link_map_supported);
10220 p_ml_ie += WLAN_ML_BV_CINFO_MLDCAPANDOP_SIZE;
10221 len_remaining -= WLAN_ML_BV_CINFO_MLDCAPANDOP_SIZE;
10222 }
10223
10224 mlo_ie->num_data = p_ml_ie - mlo_ie->data;
10225
10226 sta_prof_[5] = session->self_mac_addr[0];
10227 sta_prof_[6] = session->self_mac_addr[1];
10228 sta_prof_[7] = session->self_mac_addr[2];
10229 sta_prof_[8] = session->self_mac_addr[3];
10230
10231 sta_prof_[9] = 0xaf;
10232 sta_prof_[10] = 0x62;
10233
10234 sta_pro = &mlo_ie->sta_profile[0];
10235 sta_data = sta_pro->data;
10236 sta_len_left = sizeof(sta_pro->data);
10237
10238 sta_prof_len = ARRAY_SIZE(sta_prof_);
10239 qdf_mem_copy(sta_data, sta_prof_, sta_prof_len);
10240 sta_data += sta_prof_len;
10241 sta_len_left -= sta_prof_len;
10242 sch_info->num_links = 1;
10243 mlo_ie->num_sta_profile = 1;
10244
10245 sta_pro->num_data = sta_data - sta_pro->data;
10246 pe_debug("num data: %d, sta_prof_len: %d, sta_data len: %d",
10247 sta_pro->num_data, sta_prof_len, sizeof(sta_pro->data));
10248 sta_pro->data[TAG_LEN_POS] = sta_pro->num_data - MIN_IE_LEN;
10249 tmp_info = &sch_info->partner_info[0];
10250 tmp_info->link_info_sta_prof_ofst = sta_prof_len;
10251
10252 mlo_ie->num_sta_profile = 1;
10253 status = QDF_STATUS_SUCCESS;
10254
10255 return status;
10256 }
10257 #else
10258 QDF_STATUS populate_dot11f_assoc_rsp_mlo_ie(struct mac_context *mac_ctx,
10259 struct pe_session *session,
10260 tpDphHashNode sta,
10261 tDot11fAssocResponse *frm)
10262 {
10263 int link;
10264 int num_sta_pro = 0;
10265 struct wlan_mlo_ie *mlo_ie;
10266 struct wlan_mlo_sta_profile *sta_pro;
10267 struct mlo_link_ie_info *link_info;
10268 struct mlo_link_ie *link_ie;
10269 tpSirAssocReq assoc_req;
10270 tpSirAssocReq link_assoc_req;
10271 const uint8_t *reported_p2p_ie;
10272 uint8_t non_inher_ie_lists[255];
10273 uint8_t non_inher_len;
10274 uint8_t non_inher_ext_len;
10275 uint8_t non_inher_ext_ie_lists[255];
10276 bool same_ie, reported_vendor_vht_ie_pres;
10277 bool reported_wmm_caps_pres, reported_wmm_param_pres;
10278 tDot11fIEvendor_vht_ie vendor_vht_ie;
10279 tpDphHashNode link_sta;
10280 tDot11fIESuppRates supp_rates;
10281 tDot11fIEExtSuppRates ext_supp_rates;
10282 uint8_t lle_mode;
10283 struct pe_session *link_session;
10284 uint16_t assoc_id = 0;
10285 uint8_t link_id;
10286 uint8_t *sta_addr;
10287 uint8_t *sta_data;
10288 uint32_t sta_len_left;
10289 uint32_t sta_len_consumed;
10290 tDot11fFfStatus sta_status;
10291 tDot11fIEP2PAssocRes sta_p2p_assoc_res;
10292 tDot11fIEnon_inheritance sta_non_inheritance;
10293 uint8_t common_info_len = 0, len = 0;
10294 uint8_t *p_ml_ie;
10295 uint16_t len_remaining;
10296 uint16_t presence_bitmap = 0;
10297 QDF_STATUS status;
10298
10299 if (!mac_ctx || !session || !frm)
10300 return QDF_STATUS_E_NULL_VALUE;
10301
10302 mlo_ie = &session->mlo_ie;
10303
10304 p_ml_ie = mlo_ie->data;
10305 len_remaining = sizeof(mlo_ie->data);
10306
10307 *p_ml_ie++ = WLAN_ELEMID_EXTN_ELEM;
10308 len_remaining--;
10309 /* set length later */
10310 *p_ml_ie++ = 0;
10311 len_remaining--;
10312 *p_ml_ie++ = WLAN_EXTN_ELEMID_MULTI_LINK;
10313 len_remaining--;
10314
10315 mlo_ie->type = 0;
10316 /* Common Info Length*/
10317 common_info_len += WLAN_ML_BV_CINFO_LENGTH_SIZE;
10318 qdf_mem_copy(mlo_ie->mld_mac_addr,
10319 session->vdev->mlo_dev_ctx->mld_addr.bytes,
10320 sizeof(mlo_ie->mld_mac_addr));
10321 common_info_len += QDF_MAC_ADDR_SIZE;
10322
10323 mlo_ie->link_id_info_present = 1;
10324 presence_bitmap |= WLAN_ML_BV_CTRL_PBM_LINKIDINFO_P;
10325 mlo_ie->link_id = wlan_vdev_get_link_id(session->vdev);
10326 common_info_len += WLAN_ML_BV_CINFO_LINKIDINFO_SIZE;
10327
10328 mlo_ie->bss_param_change_cnt_present = 1;
10329 presence_bitmap |= WLAN_ML_BV_CTRL_PBM_BSSPARAMCHANGECNT_P;
10330 mlo_ie->bss_param_change_count =
10331 session->mlo_link_info.link_ie.bss_param_change_cnt;
10332 common_info_len += WLAN_ML_BSSPARAMCHNGCNT_SIZE;
10333
10334 mlo_ie->mld_capab_and_op_present = 0;
10335 mlo_ie->mld_id_present = 0;
10336 mlo_ie->ext_mld_capab_and_op_present = 0;
10337
10338 mlo_ie->common_info_length = common_info_len;
10339
10340 QDF_SET_BITS(*(uint16_t *)p_ml_ie, WLAN_ML_CTRL_TYPE_IDX,
10341 WLAN_ML_CTRL_TYPE_BITS, mlo_ie->type);
10342 QDF_SET_BITS(*(uint16_t *)p_ml_ie, WLAN_ML_CTRL_PBM_IDX,
10343 WLAN_ML_CTRL_PBM_BITS, presence_bitmap);
10344 p_ml_ie += WLAN_ML_CTRL_SIZE;
10345 len_remaining -= WLAN_ML_CTRL_SIZE;
10346
10347 *p_ml_ie++ = common_info_len;
10348 len_remaining--;
10349
10350 qdf_mem_copy(p_ml_ie, mlo_ie->mld_mac_addr, QDF_MAC_ADDR_SIZE);
10351 p_ml_ie += QDF_MAC_ADDR_SIZE;
10352 len_remaining -= QDF_MAC_ADDR_SIZE;
10353
10354 QDF_SET_BITS(*p_ml_ie, WLAN_ML_BV_CINFO_LINKIDINFO_LINKID_IDX,
10355 WLAN_ML_BV_CINFO_LINKIDINFO_LINKID_BITS, mlo_ie->link_id);
10356 p_ml_ie++;
10357 len_remaining--;
10358
10359 *p_ml_ie++ = mlo_ie->bss_param_change_count;
10360 len_remaining--;
10361
10362 mlo_ie->num_data = p_ml_ie - mlo_ie->data;
10363
10364 assoc_req = session->parsedAssocReq[sta->assocId];
10365 if (!assoc_req)
10366 goto no_partner;
10367
10368 for (link = 0; link < assoc_req->mlo_info.num_partner_links; link++) {
10369 lle_mode = 0;
10370 sta_pro = &mlo_ie->sta_profile[num_sta_pro];
10371 link_id = assoc_req->mlo_info.partner_link_info[link].link_id;
10372 link_session = pe_find_partner_session_by_link_id(session,
10373 link_id);
10374 if (!link_session)
10375 continue;
10376 link_info = &link_session->mlo_link_info;
10377 link_ie = &link_info->link_ie;
10378 sta_addr =
10379 assoc_req->mlo_info.partner_link_info[link].link_addr.bytes;
10380 link_sta = dph_lookup_hash_entry(
10381 mac_ctx,
10382 sta_addr,
10383 &assoc_id,
10384 &link_session->dph.dphHashTable);
10385 if (!link_sta) {
10386 lim_mlo_release_vdev_ref(link_session->vdev);
10387 continue;
10388 }
10389 link_assoc_req =
10390 link_session->parsedAssocReq[link_sta->assocId];
10391 sta_data = sta_pro->data;
10392 sta_len_left = sizeof(sta_pro->data);
10393
10394 *sta_data++ = WLAN_ML_LINFO_SUBELEMID_PERSTAPROFILE;
10395 /* set length later */
10396 *sta_data++ = 0;
10397 sta_len_left -= 2;
10398
10399 QDF_SET_BITS(
10400 *(uint16_t *)sta_data,
10401 WLAN_ML_BV_LINFO_PERSTAPROF_STACTRL_LINKID_IDX,
10402 WLAN_ML_BV_LINFO_PERSTAPROF_STACTRL_LINKID_BITS,
10403 link_id);
10404 QDF_SET_BITS(
10405 *(uint16_t *)sta_data,
10406 WLAN_ML_BV_LINFO_PERSTAPROF_STACTRL_CMPLTPROF_IDX,
10407 WLAN_ML_BV_LINFO_PERSTAPROF_STACTRL_CMPLTPROF_BITS,
10408 1);
10409 QDF_SET_BITS(
10410 *(uint16_t *)sta_data,
10411 WLAN_ML_BV_LINFO_PERSTAPROF_STACTRL_MACADDRP_IDX,
10412 WLAN_ML_BV_LINFO_PERSTAPROF_STACTRL_MACADDRP_BITS,
10413 1);
10414 QDF_SET_BITS(
10415 *(uint16_t *)sta_data,
10416 WLAN_ML_BV_LINFO_PERSTAPROF_STACTRL_BCNINTP_IDX,
10417 WLAN_ML_BV_LINFO_PERSTAPROF_STACTRL_BCNINTP_BITS,
10418 1);
10419 QDF_SET_BITS(
10420 *(uint16_t *)sta_data,
10421 WLAN_ML_BV_LINFO_PERSTAPROF_STACTRL_DTIMINFOP_IDX,
10422 WLAN_ML_BV_LINFO_PERSTAPROF_STACTRL_DTIMINFOP_BITS,
10423 1);
10424 /* sta control */
10425 sta_data += 2;
10426 sta_len_left -= 2;
10427
10428 /*
10429 * 1 Bytes for STA Info Length + 6 bytes for STA MAC Address +
10430 * 2 Bytes for Becon Interval + 2 Bytes for DTIM Info
10431 */
10432 len = WLAN_ML_BV_LINFO_PERSTAPROF_STAINFO_LENGTH_SIZE +
10433 QDF_MAC_ADDR_SIZE + WLAN_BEACONINTERVAL_LEN +
10434 sizeof(struct wlan_ml_bv_linfo_perstaprof_stainfo_dtiminfo);
10435 *sta_data = len;
10436
10437 /* STA Info Length */
10438 sta_data += WLAN_ML_BV_LINFO_PERSTAPROF_STAINFO_LENGTH_SIZE;
10439 sta_len_left -= WLAN_ML_BV_LINFO_PERSTAPROF_STAINFO_LENGTH_SIZE;
10440
10441 /*mac addr*/
10442 qdf_mem_copy(sta_data, link_session->self_mac_addr,
10443 QDF_MAC_ADDR_SIZE);
10444 sta_data += QDF_MAC_ADDR_SIZE;
10445 sta_len_left -= QDF_MAC_ADDR_SIZE;
10446 /* Beacon interval */
10447 *(uint16_t *)sta_data =
10448 link_session->beaconParams.beaconInterval;
10449 sta_data += WLAN_BEACONINTERVAL_LEN;
10450 sta_len_left -= WLAN_BEACONINTERVAL_LEN;
10451 /* DTIM populated by FW */
10452 sta_data += sizeof(
10453 struct wlan_ml_bv_linfo_perstaprof_stainfo_dtiminfo);
10454 sta_len_left -= sizeof(
10455 struct wlan_ml_bv_linfo_perstaprof_stainfo_dtiminfo);
10456 /* Capabilities */
10457 dot11f_pack_ff_capabilities(mac_ctx, &link_ie->link_cap,
10458 sta_data);
10459 sta_data += WLAN_CAPABILITYINFO_LEN;
10460 sta_len_left -= WLAN_CAPABILITYINFO_LEN;
10461 /* status */
10462 sta_status.status = 0;
10463 dot11f_pack_ff_status(mac_ctx, &sta_status, sta_data);
10464 sta_data += WLAN_STATUSCODE_LEN;
10465 sta_len_left -= WLAN_STATUSCODE_LEN;
10466
10467 qdf_mem_zero(non_inher_ie_lists, sizeof(non_inher_ie_lists));
10468 qdf_mem_zero(non_inher_ext_ie_lists,
10469 sizeof(non_inher_ext_ie_lists));
10470 qdf_mem_zero(&supp_rates, sizeof(tDot11fIESuppRates));
10471 qdf_mem_zero(&ext_supp_rates, sizeof(tDot11fIEExtSuppRates));
10472 qdf_mem_zero(&sta_p2p_assoc_res, sizeof(tDot11fIEP2PAssocRes));
10473 qdf_mem_zero(&sta_non_inheritance,
10474 sizeof(tDot11fIEnon_inheritance));
10475 non_inher_len = 0;
10476 non_inher_ext_len = 0;
10477
10478 populate_dot11f_assoc_rsp_rates(
10479 mac_ctx, &supp_rates,
10480 &ext_supp_rates,
10481 link_sta->supportedRates.llbRates,
10482 link_sta->supportedRates.llaRates);
10483 if ((supp_rates.present && frm->SuppRates.present &&
10484 qdf_mem_cmp(&supp_rates, &frm->SuppRates,
10485 sizeof(supp_rates))) ||
10486 (supp_rates.present && !frm->SuppRates.present)) {
10487 sta_len_consumed = 0;
10488 dot11f_pack_ie_supp_rates(mac_ctx, &supp_rates,
10489 sta_data,
10490 sta_len_left,
10491 &sta_len_consumed);
10492 sta_data += sta_len_consumed;
10493 sta_len_left -= sta_len_consumed;
10494 } else if (frm->SuppRates.present && !supp_rates.present) {
10495 non_inher_ie_lists[non_inher_len++] =
10496 DOT11F_EID_SUPPRATES;
10497 }
10498
10499 if (link_session->limQosEnabled && link_sta->lleEnabled) {
10500 lle_mode = 1;
10501 if ((link_ie->link_edca.present &&
10502 frm->EDCAParamSet.present &&
10503 qdf_mem_cmp(&link_ie->link_edca,
10504 &frm->EDCAParamSet,
10505 sizeof(link_ie->link_edca))) ||
10506 (link_ie->link_edca.present &&
10507 !frm->EDCAParamSet.present)) {
10508 sta_len_consumed = 0;
10509 dot11f_pack_ie_edca_param_set(
10510 mac_ctx, &link_ie->link_edca,
10511 sta_data, sta_len_left,
10512 &sta_len_consumed);
10513 sta_data += sta_len_consumed;
10514 sta_len_left -= sta_len_consumed;
10515 } else if (frm->EDCAParamSet.present &&
10516 !link_ie->link_edca.present) {
10517 non_inher_ie_lists[non_inher_len++] =
10518 DOT11F_EID_EDCAPARAMSET;
10519 }
10520 }
10521
10522 if ((link_ie->link_ht_cap.present && frm->HTCaps.present &&
10523 qdf_mem_cmp(&link_ie->link_ht_cap, &frm->HTCaps,
10524 sizeof(tDot11fIEHTCaps))) ||
10525 (link_ie->link_ht_cap.present && !frm->HTCaps.present)) {
10526 sta_len_consumed = 0;
10527 dot11f_pack_ie_ht_caps(
10528 mac_ctx, &link_ie->link_ht_cap,
10529 sta_data, sta_len_left, &sta_len_consumed);
10530 sta_data += sta_len_consumed;
10531 sta_len_left -= sta_len_consumed;
10532 } else if (frm->HTCaps.present &&
10533 !link_ie->link_ht_cap.present) {
10534 non_inher_ie_lists[non_inher_len++] = DOT11F_EID_HTCAPS;
10535 }
10536
10537 if ((ext_supp_rates.present && frm->ExtSuppRates.present &&
10538 qdf_mem_cmp(&ext_supp_rates, &frm->ExtSuppRates,
10539 sizeof(ext_supp_rates))) ||
10540 (ext_supp_rates.present && !frm->ExtSuppRates.present)) {
10541 sta_len_consumed = 0;
10542 dot11f_pack_ie_ext_supp_rates(
10543 mac_ctx, &ext_supp_rates, sta_data,
10544 sta_len_left,
10545 &sta_len_consumed);
10546 sta_data += sta_len_consumed;
10547 sta_len_left -= sta_len_consumed;
10548 } else if (frm->SuppRates.present && !ext_supp_rates.present) {
10549 non_inher_ie_lists[non_inher_len++] =
10550 DOT11F_EID_EXTSUPPRATES;
10551 }
10552
10553 if ((link_ie->link_ht_info.present && frm->HTInfo.present &&
10554 qdf_mem_cmp(&link_ie->link_ht_info, &frm->HTInfo,
10555 sizeof(tDot11fIEHTInfo))) ||
10556 (link_ie->link_ht_info.present && !frm->HTInfo.present)) {
10557 sta_len_consumed = 0;
10558 dot11f_pack_ie_ht_info(
10559 mac_ctx, &link_ie->link_ht_info,
10560 sta_data, sta_len_left,
10561 &sta_len_consumed);
10562 sta_data += sta_len_consumed;
10563 sta_len_left -= sta_len_consumed;
10564 } else if (frm->HTInfo.present &&
10565 !link_ie->link_ht_info.present) {
10566 non_inher_ie_lists[non_inher_len++] = DOT11F_EID_HTINFO;
10567 }
10568
10569 if ((link_ie->link_ext_cap.present && frm->ExtCap.present &&
10570 qdf_mem_cmp(&link_ie->link_ext_cap, &frm->ExtCap,
10571 sizeof(tDot11fIEExtCap))) ||
10572 (link_ie->link_ext_cap.present && !frm->ExtCap.present)) {
10573 sta_len_consumed = 0;
10574 dot11f_pack_ie_ext_cap(
10575 mac_ctx, &link_ie->link_ext_cap,
10576 sta_data, sta_len_left,
10577 &sta_len_consumed);
10578 sta_data += sta_len_consumed;
10579 sta_len_left -= sta_len_consumed;
10580 } else if (frm->ExtCap.present &&
10581 !link_ie->link_ext_cap.present) {
10582 non_inher_ie_lists[non_inher_len++] = DOT11F_EID_EXTCAP;
10583 }
10584
10585 if ((link_ie->link_vht_cap.present && frm->VHTCaps.present &&
10586 qdf_mem_cmp(&link_ie->link_vht_cap, &frm->VHTCaps,
10587 sizeof(frm->VHTCaps))) ||
10588 (link_ie->link_vht_cap.present && !frm->VHTCaps.present)) {
10589 sta_len_consumed = 0;
10590 dot11f_pack_ie_vht_caps(
10591 mac_ctx, &link_ie->link_vht_cap,
10592 sta_data, sta_len_left,
10593 &sta_len_consumed);
10594 sta_data += sta_len_consumed;
10595 sta_len_left -= sta_len_consumed;
10596 } else if (frm->VHTCaps.present &&
10597 !link_ie->link_vht_cap.present) {
10598 non_inher_ie_lists[non_inher_len++] =
10599 DOT11F_EID_VHTCAPS;
10600 }
10601
10602 if ((link_ie->link_vht_op.present &&
10603 frm->VHTOperation.present &&
10604 qdf_mem_cmp(&link_ie->link_vht_op, &frm->VHTOperation,
10605 sizeof(tDot11fIEVHTOperation))) ||
10606 (link_ie->link_vht_op.present &&
10607 !frm->VHTOperation.present)) {
10608 sta_len_consumed = 0;
10609 dot11f_pack_ie_vht_operation(
10610 mac_ctx, &link_ie->link_vht_op,
10611 sta_data, sta_len_left,
10612 &sta_len_consumed);
10613 sta_data += sta_len_consumed;
10614 sta_len_left -= sta_len_consumed;
10615 } else if (frm->VHTOperation.present &&
10616 !link_ie->link_vht_op.present) {
10617 non_inher_ie_lists[non_inher_len++] =
10618 DOT11F_EID_VHTOPERATION;
10619 }
10620 /* Check every 221 EID whether it's the same with assoc link */
10621 same_ie = false;
10622 // P2PAssocRes is different or not
10623 if (link_assoc_req)
10624 reported_p2p_ie = limGetP2pIEPtr(
10625 mac_ctx,
10626 link_assoc_req->addIE.addIEdata,
10627 link_assoc_req->addIE.length);
10628 else
10629 reported_p2p_ie = NULL;
10630 if ((reported_p2p_ie && frm->P2PAssocRes.present) ||
10631 (!reported_p2p_ie && !frm->P2PAssocRes.present))
10632 same_ie = true;
10633 // vendor_vht_ie is different or not
10634 reported_vendor_vht_ie_pres =
10635 link_session->vhtCapability &&
10636 link_session->vendor_vht_sap &&
10637 link_assoc_req &&
10638 link_assoc_req->vendor_vht_ie.VHTCaps.present;
10639 if (same_ie && frm->vendor_vht_ie.VHTCaps.present &&
10640 reported_vendor_vht_ie_pres) {
10641 if (qdf_mem_cmp(&link_ie->link_vht_cap,
10642 &frm->vendor_vht_ie.VHTCaps,
10643 sizeof(tDot11fIEVHTCaps)) ||
10644 qdf_mem_cmp(&link_ie->link_vht_op,
10645 &frm->vendor_vht_ie.VHTOperation,
10646 sizeof(tDot11fIEVHTOperation)))
10647 same_ie = false;
10648
10649 } else if (same_ie && ((frm->vendor_vht_ie.VHTCaps.present &&
10650 !reported_vendor_vht_ie_pres) ||
10651 (!frm->vendor_vht_ie.VHTCaps.present &&
10652 reported_vendor_vht_ie_pres))) {
10653 same_ie = false;
10654 }
10655 // qcn ie is different or not
10656 if (same_ie && link_ie->link_qcn_ie.present &&
10657 frm->qcn_ie.present) {
10658 if (qdf_mem_cmp(&link_ie->link_qcn_ie, &frm->qcn_ie,
10659 sizeof(tDot11fIEqcn_ie)))
10660 same_ie = false;
10661 } else if (same_ie && ((link_ie->link_qcn_ie.present &&
10662 !frm->qcn_ie.present) ||
10663 (!link_ie->link_qcn_ie.present &&
10664 frm->qcn_ie.present))) {
10665 same_ie = false;
10666 }
10667 /* wmm param and wmm caps are different or not*/
10668 reported_wmm_caps_pres = false;
10669 reported_wmm_param_pres = false;
10670 if (!lle_mode && link_session->limWmeEnabled &&
10671 link_sta->wmeEnabled) {
10672 if (link_ie->link_wmm_params.present)
10673 reported_wmm_param_pres = true;
10674
10675 if (link_sta->wsmEnabled &&
10676 link_ie->link_wmm_caps.present)
10677 reported_wmm_caps_pres = true;
10678 }
10679 if (same_ie && reported_wmm_param_pres &&
10680 frm->WMMParams.present) {
10681 if (qdf_mem_cmp(&link_ie->link_wmm_params,
10682 &frm->WMMParams,
10683 sizeof(link_ie->link_wmm_params)))
10684 same_ie = false;
10685 } else if (same_ie && ((reported_wmm_param_pres &&
10686 !frm->WMMParams.present) ||
10687 (!reported_wmm_param_pres &&
10688 frm->WMMParams.present))) {
10689 same_ie = false;
10690 }
10691 if (same_ie && reported_wmm_caps_pres &&
10692 frm->WMMCaps.present) {
10693 if (qdf_mem_cmp(&link_ie->link_wmm_caps,
10694 &frm->WMMCaps,
10695 sizeof(link_ie->link_wmm_caps)))
10696 same_ie = false;
10697 } else if (same_ie && ((reported_wmm_caps_pres &&
10698 !frm->WMMCaps.present) ||
10699 (!reported_wmm_caps_pres &&
10700 frm->WMMCaps.present))) {
10701 same_ie = false;
10702 }
10703 /*
10704 * Nothing need to do if all 221 ie in the reported assoc resp
10705 * are the same with reporting assoc resp.
10706 */
10707 if (!same_ie) {
10708 if (reported_p2p_ie && link_assoc_req) {
10709 populate_dot11_assoc_res_p2p_ie(
10710 mac_ctx,
10711 &sta_p2p_assoc_res,
10712 link_assoc_req);
10713 sta_len_consumed = 0;
10714 dot11f_pack_ie_p2_p_assoc_res(
10715 mac_ctx, &sta_p2p_assoc_res,
10716 sta_data, sta_len_left,
10717 &sta_len_consumed);
10718 sta_data += sta_len_consumed;
10719 sta_len_left -= sta_len_consumed;
10720 }
10721 if (reported_vendor_vht_ie_pres) {
10722 qdf_mem_zero(&vendor_vht_ie,
10723 sizeof(vendor_vht_ie));
10724 vendor_vht_ie.present = 1;
10725 vendor_vht_ie.sub_type =
10726 link_session->vendor_specific_vht_ie_sub_type;
10727 populate_dot11f_vht_caps(
10728 mac_ctx, link_session,
10729 &vendor_vht_ie.VHTCaps);
10730 populate_dot11f_vht_operation(
10731 mac_ctx, link_session,
10732 &vendor_vht_ie.VHTOperation);
10733
10734 sta_len_consumed = 0;
10735 dot11f_pack_ie_vendor_vht_ie(
10736 mac_ctx, &vendor_vht_ie,
10737 sta_data, sta_len_left,
10738 &sta_len_consumed);
10739 sta_data += sta_len_consumed;
10740 sta_len_left -= sta_len_consumed;
10741 }
10742 sta_len_consumed = 0;
10743 dot11f_pack_ie_qcn_ie(
10744 mac_ctx, &link_ie->link_qcn_ie,
10745 sta_data, sta_len_left,
10746 &sta_len_consumed);
10747 sta_data += sta_len_consumed;
10748 sta_len_left -= sta_len_consumed;
10749 if (reported_wmm_param_pres) {
10750 sta_len_consumed = 0;
10751 dot11f_pack_ie_wmm_params(
10752 mac_ctx,
10753 &link_ie->link_wmm_params,
10754 sta_data, sta_len_left,
10755 &sta_len_consumed);
10756 sta_data += sta_len_consumed;
10757 sta_len_left -= sta_len_consumed;
10758 }
10759 if (reported_wmm_caps_pres) {
10760 sta_len_consumed = 0;
10761 dot11f_pack_ie_wmm_caps(
10762 mac_ctx,
10763 &link_ie->link_wmm_caps,
10764 sta_data, sta_len_left,
10765 &sta_len_consumed);
10766 sta_data += sta_len_consumed;
10767 sta_len_left -= sta_len_consumed;
10768 }
10769 /*
10770 * if there is no 221 IE in partner link
10771 * while there is such IE in current link
10772 * include 221 in the non inheritance IE lists
10773 */
10774 if (!reported_p2p_ie &&
10775 !link_ie->link_qcn_ie.present &&
10776 !reported_vendor_vht_ie_pres &&
10777 !reported_wmm_caps_pres && !reported_wmm_param_pres)
10778 non_inher_ie_lists[non_inher_len++] =
10779 DOT11F_EID_QCN_IE;
10780 }
10781
10782 if ((link_ie->link_he_cap.present && frm->he_cap.present &&
10783 qdf_mem_cmp(&link_ie->link_he_cap, &frm->he_cap,
10784 sizeof(frm->he_cap))) ||
10785 (link_ie->link_he_cap.present && !frm->he_cap.present)) {
10786 sta_len_consumed = 0;
10787 dot11f_pack_ie_he_cap(
10788 mac_ctx, &link_ie->link_he_cap,
10789 sta_data, sta_len_left,
10790 &sta_len_consumed);
10791 sta_data += sta_len_consumed;
10792 sta_len_left -= sta_len_consumed;
10793 } else if (frm->he_cap.present &&
10794 !link_ie->link_he_cap.present) {
10795 non_inher_ext_ie_lists[non_inher_ext_len++] =
10796 WLAN_EXTN_ELEMID_HECAP;
10797 }
10798
10799 if ((link_ie->link_he_op.present && frm->he_op.present &&
10800 qdf_mem_cmp(&link_ie->link_he_op, &frm->he_op,
10801 sizeof(tDot11fIEhe_op))) ||
10802 (link_ie->link_he_op.present && !frm->he_op.present)) {
10803 sta_len_consumed = 0;
10804 dot11f_pack_ie_he_op(
10805 mac_ctx, &link_ie->link_he_op,
10806 sta_data, sta_len_left,
10807 &sta_len_consumed);
10808 sta_data += sta_len_consumed;
10809 sta_len_left -= sta_len_consumed;
10810 } else if (frm->he_op.present && !link_ie->link_he_op.present) {
10811 non_inher_ext_ie_lists[non_inher_ext_len++] =
10812 WLAN_EXTN_ELEMID_HEOP;
10813 }
10814 if ((link_ie->link_he_6ghz_band_cap.present &&
10815 frm->he_6ghz_band_cap.present &&
10816 qdf_mem_cmp(&link_ie->link_he_6ghz_band_cap,
10817 &frm->he_6ghz_band_cap,
10818 sizeof(tDot11fIEhe_6ghz_band_cap))) ||
10819 (link_ie->link_he_6ghz_band_cap.present &&
10820 !frm->he_6ghz_band_cap.present)) {
10821 sta_len_consumed = 0;
10822 dot11f_pack_ie_he_6ghz_band_cap(
10823 mac_ctx, &link_ie->link_he_6ghz_band_cap,
10824 sta_data, sta_len_left,
10825 &sta_len_consumed);
10826 sta_data += sta_len_consumed;
10827 sta_len_left -= sta_len_consumed;
10828 } else if (frm->he_6ghz_band_cap.present &&
10829 !link_ie->link_he_6ghz_band_cap.present) {
10830 non_inher_ext_ie_lists[non_inher_ext_len++] =
10831 WLAN_EXTN_ELEMID_HE_6G_CAP;
10832 }
10833 if ((link_ie->link_eht_op.present && frm->eht_op.present &&
10834 qdf_mem_cmp(&link_ie->link_eht_op, &frm->eht_op,
10835 sizeof(tDot11fIEeht_op))) ||
10836 (link_ie->link_eht_op.present && !frm->eht_op.present)) {
10837 sta_len_consumed = 0;
10838 dot11f_pack_ie_eht_op(
10839 mac_ctx, &link_ie->link_eht_op,
10840 sta_data, sta_len_left,
10841 &sta_len_consumed);
10842 sta_data += sta_len_consumed;
10843 sta_len_left -= sta_len_consumed;
10844 } else if (frm->eht_op.present &&
10845 !link_ie->link_eht_op.present) {
10846 non_inher_ext_ie_lists[non_inher_ext_len++] =
10847 WLAN_EXTN_ELEMID_EHTOP;
10848 }
10849 if ((link_ie->link_eht_cap.present && frm->eht_cap.present &&
10850 qdf_mem_cmp(&link_ie->link_eht_cap, &frm->eht_cap,
10851 sizeof(frm->eht_cap))) ||
10852 (link_ie->link_eht_cap.present && !frm->eht_cap.present)) {
10853 sta_len_consumed = 0;
10854 dot11f_pack_ie_eht_cap(
10855 mac_ctx, &link_ie->link_eht_cap,
10856 sta_data, sta_len_left,
10857 &sta_len_consumed);
10858 sta_data += sta_len_consumed;
10859 sta_len_left -= sta_len_consumed;
10860 } else if (frm->eht_cap.present &&
10861 !link_ie->link_eht_cap.present) {
10862 non_inher_ext_ie_lists[non_inher_ext_len++] =
10863 WLAN_EXTN_ELEMID_EHTCAP;
10864 }
10865 populate_dot11f_non_inheritance(mac_ctx, &sta_non_inheritance,
10866 non_inher_ie_lists,
10867 non_inher_ext_ie_lists,
10868 non_inher_len,
10869 non_inher_ext_len);
10870 if (sta_non_inheritance.present) {
10871 sta_len_consumed = 0;
10872 dot11f_pack_ie_non_inheritance(
10873 mac_ctx, &sta_non_inheritance,
10874 sta_data, sta_len_left,
10875 &sta_len_consumed);
10876 sta_data += sta_len_consumed;
10877 sta_len_left -= sta_len_consumed;
10878 }
10879 sta_pro->num_data = sta_data - sta_pro->data;
10880 if (sta_pro->num_data > WLAN_MAX_IE_LEN + MIN_IE_LEN) {
10881 sta_pro->data[TAG_LEN_POS] = WLAN_MAX_IE_LEN;
10882 status =
10883 lim_add_frag_ie_for_sta_profile(sta_pro->data,
10884 &sta_pro->num_data);
10885 if (status != QDF_STATUS_SUCCESS) {
10886 pe_debug("add frg ie for sta profile error.");
10887 sta_pro->num_data =
10888 WLAN_MAX_IE_LEN + MIN_IE_LEN;
10889 }
10890 } else {
10891 sta_pro->data[TAG_LEN_POS] =
10892 sta_pro->num_data - MIN_IE_LEN;
10893 }
10894 lim_mlo_release_vdev_ref(link_session->vdev);
10895 num_sta_pro++;
10896 }
10897
10898 no_partner:
10899 mlo_ie->num_sta_profile = num_sta_pro;
10900 mlo_ie->mld_capab_and_op_info.max_simultaneous_link_num = num_sta_pro;
10901 return QDF_STATUS_SUCCESS;
10902 }
10903
10904 QDF_STATUS populate_dot11f_bcn_mlo_ie(struct mac_context *mac_ctx,
10905 struct pe_session *session)
10906 {
10907 int link;
10908 int num_sta_pro = 0;
10909 struct wlan_mlo_ie *mlo_ie;
10910 struct wlan_mlo_sta_profile *sta_pro;
10911 struct mlo_link_ie *link_ie;
10912 uint16_t vdev_count;
10913 struct wlan_objmgr_vdev *wlan_vdev_list[WLAN_UMAC_MLO_MAX_VDEVS];
10914 struct pe_session *link_session;
10915 uint16_t tmp_offset = 0;
10916 struct ml_sch_partner_info *tmp_info;
10917 struct mlo_sch_partner_links *sch_info;
10918 uint8_t *sta_data;
10919 uint32_t sta_len_left;
10920 uint32_t sta_len_consumed;
10921 uint8_t common_info_length = 0;
10922 uint8_t *p_ml_ie;
10923 uint16_t len_remaining;
10924 uint16_t presence_bitmap = 0;
10925 bool sta_pro_present;
10926 QDF_STATUS status;
10927
10928 if (!mac_ctx || !session)
10929 return QDF_STATUS_E_NULL_VALUE;
10930
10931 mlo_ie = &session->mlo_ie;
10932
10933 /* Common Info Length */
10934 common_info_length += WLAN_ML_BV_CINFO_LENGTH_SIZE;
10935 qdf_mem_zero(&mac_ctx->sch.sch_mlo_partner,
10936 sizeof(mac_ctx->sch.sch_mlo_partner));
10937 sch_info = &mac_ctx->sch.sch_mlo_partner;
10938 mlo_ie->type = 0;
10939 tmp_offset += 1; /* Element ID */
10940 tmp_offset += 1; /* length */
10941 tmp_offset += 1; /* Element ID extension */
10942 tmp_offset += 2; /* Multi-link control */
10943 qdf_mem_copy(mlo_ie->mld_mac_addr,
10944 session->vdev->mlo_dev_ctx->mld_addr.bytes,
10945 sizeof(mlo_ie->mld_mac_addr));
10946 tmp_offset += 1; /* Common Info Length */
10947 tmp_offset += 6; /* mld mac addr */
10948 common_info_length += QDF_MAC_ADDR_SIZE;
10949 mlo_ie->link_id_info_present = 1;
10950 presence_bitmap |= WLAN_ML_BV_CTRL_PBM_LINKIDINFO_P;
10951 mlo_ie->link_id = wlan_vdev_get_link_id(session->vdev);
10952 tmp_offset += 1; /* link id */
10953 common_info_length += WLAN_ML_BV_CINFO_LINKIDINFO_SIZE;
10954 mlo_ie->bss_param_change_cnt_present = 1;
10955 presence_bitmap |= WLAN_ML_BV_CTRL_PBM_BSSPARAMCHANGECNT_P;
10956 mlo_ie->bss_param_change_count =
10957 session->mlo_link_info.link_ie.bss_param_change_cnt;
10958 tmp_offset += 1; /* bss parameters change count */
10959 common_info_length += WLAN_ML_BSSPARAMCHNGCNT_SIZE;
10960 mlo_ie->mld_capab_and_op_present = 0;
10961 mlo_ie->mld_id_present = 0;
10962 mlo_ie->ext_mld_capab_and_op_present = 0;
10963 sch_info->num_links = 0;
10964
10965 lim_get_mlo_vdev_list(session, &vdev_count, wlan_vdev_list);
10966 mlo_ie->mld_capab_and_op_info.max_simultaneous_link_num =
10967 vdev_count - 1;
10968
10969 mlo_ie->common_info_length = common_info_length;
10970 sch_info->mlo_ie_link_info_ofst = tmp_offset;
10971
10972 p_ml_ie = mlo_ie->data;
10973 len_remaining = sizeof(mlo_ie->data);
10974
10975 *p_ml_ie++ = WLAN_ELEMID_EXTN_ELEM;
10976 len_remaining--;
10977 *p_ml_ie++ = 0;
10978 len_remaining--;
10979 *p_ml_ie++ = WLAN_EXTN_ELEMID_MULTI_LINK;
10980 len_remaining--;
10981
10982 QDF_SET_BITS(*(uint16_t *)p_ml_ie, WLAN_ML_CTRL_TYPE_IDX,
10983 WLAN_ML_CTRL_TYPE_BITS, mlo_ie->type);
10984 QDF_SET_BITS(*(uint16_t *)p_ml_ie, WLAN_ML_CTRL_PBM_IDX,
10985 WLAN_ML_CTRL_PBM_BITS, presence_bitmap);
10986 p_ml_ie += WLAN_ML_CTRL_SIZE;
10987 len_remaining -= WLAN_ML_CTRL_SIZE;
10988
10989 *p_ml_ie++ = common_info_length;
10990 len_remaining--;
10991
10992 qdf_mem_copy(p_ml_ie, mlo_ie->mld_mac_addr, QDF_MAC_ADDR_SIZE);
10993 p_ml_ie += QDF_MAC_ADDR_SIZE;
10994 len_remaining -= QDF_MAC_ADDR_SIZE;
10995
10996 QDF_SET_BITS(*p_ml_ie, WLAN_ML_BV_CINFO_LINKIDINFO_LINKID_IDX,
10997 WLAN_ML_BV_CINFO_LINKIDINFO_LINKID_BITS,
10998 mlo_ie->link_id);
10999 p_ml_ie++;
11000 len_remaining--;
11001
11002 *p_ml_ie++ = mlo_ie->bss_param_change_count;
11003 len_remaining--;
11004
11005 mlo_ie->num_data = p_ml_ie - mlo_ie->data;
11006
11007 for (link = 0; link < vdev_count; link++) {
11008 if (!wlan_vdev_list[link])
11009 continue;
11010 if (wlan_vdev_list[link] == session->vdev) {
11011 lim_mlo_release_vdev_ref(wlan_vdev_list[link]);
11012 continue;
11013 }
11014 if (!wlan_vdev_mlme_is_mlo_ap(wlan_vdev_list[link])) {
11015 lim_mlo_release_vdev_ref(wlan_vdev_list[link]);
11016 continue;
11017 }
11018 link_session = pe_find_session_by_vdev_id(
11019 mac_ctx, wlan_vdev_list[link]->vdev_objmgr.vdev_id);
11020 if (!link_session) {
11021 lim_mlo_release_vdev_ref(wlan_vdev_list[link]);
11022 continue;
11023 }
11024 sta_pro = &mlo_ie->sta_profile[num_sta_pro];
11025 link_ie = &link_session->mlo_link_info.link_ie;
11026 tmp_info = &sch_info->partner_info[sch_info->num_links++];
11027 tmp_info->vdev_id = wlan_vdev_get_id(wlan_vdev_list[link]);
11028 tmp_info->beacon_interval =
11029 link_session->beaconParams.beaconInterval;
11030 sta_pro_present = false;
11031 sta_data = sta_pro->data;
11032 sta_len_left = sizeof(sta_pro->data);
11033 *sta_data++ = WLAN_ML_LINFO_SUBELEMID_PERSTAPROFILE;
11034 *sta_data++ = 0;
11035 sta_data += 2; /* sta control */
11036 sta_len_left -= 4;
11037 tmp_offset = 1; /* sub element id */
11038 tmp_offset += 1; /* length */
11039 if (link_ie->link_csa.present) {
11040 sta_len_consumed = 0;
11041 dot11f_pack_ie_chan_switch_ann(mac_ctx,
11042 &link_ie->link_csa,
11043 sta_data, sta_len_left,
11044 &sta_len_consumed);
11045 sta_data += sta_len_consumed;
11046 sta_len_left -= sta_len_consumed;
11047 sta_pro_present = true;
11048 tmp_info->csa_ext_csa_exist = true;
11049 }
11050 if (link_ie->link_ecsa.present) {
11051 sta_len_consumed = 0;
11052 dot11f_pack_ie_ext_chan_switch_ann(mac_ctx,
11053 &link_ie->link_ecsa,
11054 sta_data,
11055 sta_len_left,
11056 &sta_len_consumed);
11057 sta_data += sta_len_consumed;
11058 sta_len_left -= sta_len_consumed;
11059 sta_pro_present = true;
11060 tmp_info->csa_ext_csa_exist = true;
11061 }
11062 if (link_ie->link_quiet.present) {
11063 sta_len_consumed = 0;
11064 dot11f_pack_ie_quiet(mac_ctx, &link_ie->link_quiet,
11065 sta_data, sta_len_left,
11066 &sta_len_consumed);
11067 sta_data += sta_len_consumed;
11068 sta_len_left -= sta_len_consumed;
11069 sta_pro_present = true;
11070 }
11071 if (link_ie->link_swt_time.present) {
11072 sta_len_consumed = 0;
11073 dot11f_pack_ie_max_chan_switch_time(
11074 mac_ctx, &link_ie->link_swt_time, sta_data,
11075 sta_len_left, &sta_len_consumed);
11076 sta_data += sta_len_consumed;
11077 sta_len_left -= sta_len_consumed;
11078 sta_pro_present = true;
11079 }
11080 if (sta_pro_present) {
11081 sta_pro->num_data = sta_data - sta_pro->data;
11082 if (sta_pro->num_data > WLAN_MAX_IE_LEN + MIN_IE_LEN) {
11083 sta_pro->data[TAG_LEN_POS] = WLAN_MAX_IE_LEN;
11084 status =
11085 lim_add_frag_ie_for_sta_profile(sta_pro->data,
11086 &sta_pro->num_data);
11087 if (status != QDF_STATUS_SUCCESS) {
11088 pe_debug("STA profile flag error");
11089 sta_pro->num_data =
11090 WLAN_MAX_IE_LEN + MIN_IE_LEN;
11091 }
11092 } else {
11093 sta_pro->data[TAG_LEN_POS] =
11094 sta_pro->num_data - MIN_IE_LEN;
11095 }
11096 QDF_SET_BITS(
11097 *(uint16_t *)(sta_pro->data + MIN_IE_LEN),
11098 WLAN_ML_BV_LINFO_PERSTAPROF_STACTRL_LINKID_IDX,
11099 WLAN_ML_BV_LINFO_PERSTAPROF_STACTRL_LINKID_BITS,
11100 wlan_vdev_get_link_id(link_session->vdev));
11101
11102 num_sta_pro++;
11103 tmp_offset += 2; /* sta control */
11104 tmp_info->link_info_sta_prof_ofst = tmp_offset;
11105 }
11106 lim_mlo_release_vdev_ref(wlan_vdev_list[link]);
11107 }
11108 mlo_ie->num_sta_profile = num_sta_pro;
11109
11110 return QDF_STATUS_SUCCESS;
11111 }
11112 #endif
11113
11114 QDF_STATUS populate_dot11f_tdls_mgmt_mlo_ie(struct mac_context *mac_ctx,
11115 struct pe_session *session)
11116 {
11117 struct wlan_mlo_ie *mlo_ie;
11118 uint8_t *p_ml_ie;
11119 uint16_t len_remaining;
11120 uint16_t presence_bitmap = 0;
11121 uint8_t common_info_length = 0;
11122
11123 if (!mac_ctx || !session)
11124 return QDF_STATUS_E_NULL_VALUE;
11125
11126 mlo_ie = &session->mlo_ie;
11127
11128 p_ml_ie = mlo_ie->data;
11129 len_remaining = sizeof(mlo_ie->data);
11130
11131 *p_ml_ie++ = WLAN_ELEMID_EXTN_ELEM;
11132 len_remaining--;
11133 *p_ml_ie++ = 0;
11134 len_remaining--;
11135
11136 *p_ml_ie++ = WLAN_EXTN_ELEMID_MULTI_LINK;
11137 len_remaining--;
11138
11139 common_info_length += WLAN_ML_BV_CINFO_LENGTH_SIZE;
11140 presence_bitmap |= WLAN_ML_BV_CTRL_PBM_BSSPARAMCHANGECNT_P;
11141 common_info_length += WLAN_ML_BSSPARAMCHNGCNT_SIZE;
11142
11143 QDF_SET_BITS(*(uint16_t *)p_ml_ie, WLAN_ML_CTRL_TYPE_IDX,
11144 WLAN_ML_CTRL_TYPE_BITS, WLAN_ML_VARIANT_TDLS);
11145 QDF_SET_BITS(*(uint16_t *)p_ml_ie, WLAN_ML_CTRL_PBM_IDX,
11146 WLAN_ML_CTRL_PBM_BITS, presence_bitmap);
11147
11148 p_ml_ie += WLAN_ML_CTRL_SIZE;
11149 len_remaining -= WLAN_ML_CTRL_SIZE;
11150
11151 *p_ml_ie++ = common_info_length;
11152 len_remaining--;
11153
11154 qdf_mem_copy(p_ml_ie, session->vdev->mlo_dev_ctx->mld_addr.bytes,
11155 QDF_MAC_ADDR_SIZE);
11156
11157 p_ml_ie += QDF_MAC_ADDR_SIZE;
11158 len_remaining -= QDF_MAC_ADDR_SIZE;
11159
11160 mlo_ie->num_data = p_ml_ie - mlo_ie->data;
11161
11162 return QDF_STATUS_SUCCESS;
11163 }
11164
11165 #if defined (SAP_MULTI_LINK_EMULATION)
11166 static void populate_2link_rnr_info(struct pe_session *session,
11167 tDot11fIEreduced_neighbor_report *dot11f)
11168 {
11169 tSirMacAddr fake_mac_addr;
11170
11171 qdf_mem_copy(fake_mac_addr, session->self_mac_addr, sizeof(tSirMacAddr));
11172
11173 pe_debug(QDF_MAC_ADDR_FMT, QDF_MAC_ADDR_REF(fake_mac_addr));
11174
11175 dot11f->present = 1;
11176 dot11f->op_class = 131;
11177 dot11f->channel_num = 37;
11178
11179 dot11f->tbtt_info_count = 0;
11180 dot11f->tbtt_info_len = 16;
11181
11182 fake_mac_addr[4] = 0xaf;
11183 fake_mac_addr[5] = 0x62;
11184 qdf_mem_copy(dot11f->tbtt_info.tbtt_info_16.bssid,
11185 fake_mac_addr, sizeof(tSirMacAddr));
11186 dot11f->tbtt_info.tbtt_info_16.mld_id = 0;
11187 dot11f->tbtt_info.tbtt_info_16.link_id = 1;
11188
11189 dot11f->tbtt_info.tbtt_info_16.bss_params = 0x4e;
11190 dot11f->tbtt_info.tbtt_info_16.short_ssid = 0x558df58e;
11191 dot11f->tbtt_info.tbtt_info_16.psd_20mhz = 0xfe;
11192
11193 dot11f->tbtt_info.tbtt_info_16.bss_param_change_cnt =
11194 session->mlo_link_info.link_ie.bss_param_change_cnt;
11195
11196 pe_debug("Populated rnr IE...");
11197 }
11198 #else
11199 static inline void populate_2link_rnr_info(struct pe_session *session,
11200 tDot11fIEreduced_neighbor_report *dot11f)
11201 {
11202 }
11203 #endif
11204
11205 void populate_dot11f_mlo_rnr(struct mac_context *mac_ctx,
11206 struct pe_session *session,
11207 tDot11fIEreduced_neighbor_report *dot11f)
11208 {
11209 int link;
11210 uint16_t vdev_count;
11211 struct wlan_objmgr_vdev *wlan_vdev_list[WLAN_UMAC_MLO_MAX_VDEVS];
11212 struct pe_session *link_session;
11213 bool rnr_populated = false;
11214
11215 lim_get_mlo_vdev_list(session, &vdev_count, wlan_vdev_list);
11216 for (link = 0; link < vdev_count; link++) {
11217 if (!wlan_vdev_list[link])
11218 continue;
11219 if (wlan_vdev_list[link] == session->vdev) {
11220 lim_mlo_release_vdev_ref(wlan_vdev_list[link]);
11221 continue;
11222 }
11223 if (!wlan_vdev_mlme_is_mlo_ap(wlan_vdev_list[link])) {
11224 lim_mlo_release_vdev_ref(wlan_vdev_list[link]);
11225 continue;
11226 }
11227 link_session = pe_find_session_by_vdev_id(
11228 mac_ctx, wlan_vdev_get_id(wlan_vdev_list[link]));
11229 if (!link_session) {
11230 pe_debug("vdev id %d pe session is not created",
11231 wlan_vdev_get_id(wlan_vdev_list[link]));
11232 lim_mlo_release_vdev_ref(wlan_vdev_list[link]);
11233 continue;
11234 }
11235 if (!rnr_populated) {
11236 populate_dot11f_rnr_tbtt_info_16(mac_ctx, session,
11237 link_session, dot11f);
11238 pe_debug("mlo vdev id %d populate vdev id %d link id %d op class %d chan num %d in RNR IE",
11239 wlan_vdev_get_id(session->vdev),
11240 wlan_vdev_get_id(wlan_vdev_list[link]),
11241 dot11f->tbtt_info.tbtt_info_16.link_id,
11242 dot11f->op_class, dot11f->channel_num);
11243 rnr_populated = true;
11244 }
11245 lim_mlo_release_vdev_ref(wlan_vdev_list[link]);
11246 }
11247
11248 populate_2link_rnr_info(session, dot11f);
11249
11250 }
11251
11252 void populate_dot11f_rnr_tbtt_info_16(struct mac_context *mac_ctx,
11253 struct pe_session *pe_session,
11254 struct pe_session *rnr_session,
11255 tDot11fIEreduced_neighbor_report *dot11f)
11256 {
11257 uint8_t reg_class;
11258 uint8_t ch_offset;
11259
11260 dot11f->present = 1;
11261 dot11f->tbtt_type = 0;
11262 if (rnr_session->ch_width == CH_WIDTH_80MHZ) {
11263 ch_offset = BW80;
11264 } else {
11265 switch (rnr_session->htSecondaryChannelOffset) {
11266 case PHY_DOUBLE_CHANNEL_HIGH_PRIMARY:
11267 ch_offset = BW40_HIGH_PRIMARY;
11268 break;
11269 case PHY_DOUBLE_CHANNEL_LOW_PRIMARY:
11270 ch_offset = BW40_LOW_PRIMARY;
11271 break;
11272 default:
11273 ch_offset = BW20;
11274 break;
11275 }
11276 }
11277
11278 reg_class = lim_op_class_from_bandwidth(mac_ctx,
11279 rnr_session->curr_op_freq,
11280 rnr_session->ch_width,
11281 ch_offset);
11282
11283 dot11f->op_class = reg_class;
11284 dot11f->channel_num = wlan_reg_freq_to_chan(mac_ctx->pdev,
11285 rnr_session->curr_op_freq);
11286 dot11f->tbtt_info_count = 0;
11287 dot11f->tbtt_info_len = 16;
11288 qdf_mem_copy(dot11f->tbtt_info.tbtt_info_16.bssid,
11289 rnr_session->self_mac_addr, sizeof(tSirMacAddr));
11290 dot11f->tbtt_info.tbtt_info_16.mld_id = 0;
11291 dot11f->tbtt_info.tbtt_info_16.link_id = wlan_vdev_get_link_id(
11292 rnr_session->vdev);
11293 dot11f->tbtt_info.tbtt_info_16.bss_param_change_cnt =
11294 rnr_session->mlo_link_info.link_ie.bss_param_change_cnt;
11295 }
11296
11297 QDF_STATUS
11298 populate_dot11f_mlo_caps(struct mac_context *mac_ctx,
11299 struct pe_session *session,
11300 struct wlan_mlo_ie *mlo_ie)
11301 {
11302 uint8_t *mld_addr;
11303 uint8_t common_info_len = 0;
11304
11305 mlo_ie->type = 0;
11306 /* Common Info Length */
11307 common_info_len += WLAN_ML_BV_CINFO_LENGTH_SIZE;
11308 mld_addr = wlan_vdev_mlme_get_mldaddr(session->vdev);
11309 qdf_mem_copy(&mlo_ie->mld_mac_addr, mld_addr,
11310 sizeof(mlo_ie->mld_mac_addr));
11311 common_info_len += QDF_MAC_ADDR_SIZE;
11312 mlo_ie->link_id_info_present = 0;
11313
11314 mlo_ie->bss_param_change_cnt_present = 0;
11315 mlo_ie->medium_sync_delay_info_present = 0;
11316
11317 if (wlan_vdev_mlme_cap_get(session->vdev, WLAN_VDEV_C_EMLSR_CAP)) {
11318 mlo_ie->eml_capab_present = 1;
11319 mlo_ie->eml_capabilities_info.emlmr_support = 0;
11320 mlo_ie->eml_capabilities_info.emlsr_support = 1;
11321 common_info_len += WLAN_ML_BV_CINFO_EMLCAP_SIZE;
11322 } else {
11323 mlo_ie->eml_capab_present = 0;
11324 }
11325
11326 common_info_len += WLAN_ML_BV_CINFO_MLDCAPANDOP_SIZE;
11327 mlo_ie->ext_mld_capab_and_op_present = 0;
11328 mlo_ie->mld_id_present = 0;
11329 mlo_ie->mld_capab_and_op_present = 1;
11330 mlo_ie->mld_capab_and_op_info.tid_link_map_supported =
11331 wlan_mlme_get_t2lm_negotiation_supported(mac_ctx->psoc);
11332 mlo_ie->reserved = 0;
11333 mlo_ie->reserved_1 = 0;
11334 mlo_ie->common_info_length = common_info_len;
11335
11336 return QDF_STATUS_SUCCESS;
11337 }
11338
11339 QDF_STATUS
11340 sir_convert_mlo_probe_rsp_frame2_struct(uint8_t *ml_ie,
11341 uint32_t ml_ie_total_len,
11342 struct sir_multi_link_ie *mlo_ie_ptr)
11343 {
11344 bool link_id_found;
11345 uint8_t link_id;
11346 bool bss_param_change_cnt_found;
11347 uint8_t bss_param_change_cnt;
11348 struct qdf_mac_addr mld_mac_addr;
11349 uint8_t *sta_prof;
11350
11351 if (!ml_ie)
11352 return QDF_STATUS_E_NULL_VALUE;
11353
11354 if (!ml_ie_total_len)
11355 return QDF_STATUS_E_NULL_VALUE;
11356
11357 qdf_mem_zero((uint8_t *)mlo_ie_ptr, sizeof(*mlo_ie_ptr));
11358
11359 util_get_mlie_common_info_len(ml_ie, ml_ie_total_len,
11360 &mlo_ie_ptr->mlo_ie.common_info_length);
11361
11362 sta_prof = ml_ie + sizeof(struct wlan_ie_multilink) +
11363 mlo_ie_ptr->mlo_ie.common_info_length;
11364 lim_store_mlo_ie_raw_info(ml_ie, sta_prof,
11365 ml_ie_total_len, &mlo_ie_ptr->mlo_ie);
11366
11367 util_get_bvmlie_mldmacaddr(ml_ie, ml_ie_total_len, &mld_mac_addr);
11368 qdf_mem_copy(mlo_ie_ptr->mlo_ie.mld_mac_addr, mld_mac_addr.bytes,
11369 QDF_MAC_ADDR_SIZE);
11370
11371 util_get_bvmlie_primary_linkid(ml_ie, ml_ie_total_len,
11372 &link_id_found, &link_id);
11373 mlo_ie_ptr->mlo_ie.link_id_info_present = link_id_found;
11374 mlo_ie_ptr->mlo_ie.link_id = link_id;
11375
11376 util_get_bvmlie_bssparamchangecnt(ml_ie, ml_ie_total_len,
11377 &bss_param_change_cnt_found,
11378 &bss_param_change_cnt);
11379 mlo_ie_ptr->mlo_ie.bss_param_change_cnt_present =
11380 bss_param_change_cnt_found;
11381 mlo_ie_ptr->mlo_ie.bss_param_change_count = bss_param_change_cnt;
11382 mlo_ie_ptr->mlo_ie_present = true;
11383
11384 return QDF_STATUS_SUCCESS;
11385 }
11386 #endif
11387
11388 #if defined(WLAN_FEATURE_11AX) && defined(WLAN_SUPPORT_TWT)
11389 QDF_STATUS populate_dot11f_twt_extended_caps(struct mac_context *mac_ctx,
11390 struct pe_session *pe_session,
11391 tDot11fIEExtCap *dot11f)
11392 {
11393 struct s_ext_cap *p_ext_cap;
11394 bool twt_responder = false;
11395 bool twt_requestor = false;
11396
11397 if (pe_session->opmode == QDF_STA_MODE &&
11398 !pe_session->enable_session_twt_support) {
11399 return QDF_STATUS_SUCCESS;
11400 }
11401
11402 dot11f->num_bytes = DOT11F_IE_EXTCAP_MAX_LEN;
11403 p_ext_cap = (struct s_ext_cap *)dot11f->bytes;
11404 dot11f->present = 1;
11405
11406 if (pe_session->opmode == QDF_STA_MODE) {
11407 wlan_twt_get_requestor_cfg(mac_ctx->psoc, &twt_requestor);
11408 p_ext_cap->twt_requestor_support =
11409 twt_requestor && twt_get_requestor_flag(mac_ctx);
11410 }
11411
11412 if (pe_session->opmode == QDF_SAP_MODE) {
11413 wlan_twt_get_responder_cfg(mac_ctx->psoc, &twt_responder);
11414 p_ext_cap->twt_responder_support =
11415 twt_responder && twt_get_responder_flag(mac_ctx);
11416 }
11417
11418 dot11f->num_bytes = lim_compute_ext_cap_ie_length(dot11f);
11419 if (!dot11f->num_bytes) {
11420 dot11f->present = 0;
11421 pe_debug("ext ie length become 0, disable the ext caps");
11422 }
11423
11424 return QDF_STATUS_SUCCESS;
11425 }
11426 #endif
11427
11428 #if defined(WLAN_SAE_SINGLE_PMK) && defined(WLAN_FEATURE_ROAM_OFFLOAD)
11429 /**
11430 * wlan_fill_single_pmk_ap_cap_from_scan_entry() - WAP3_SPMK VSIE from scan
11431 * entry
11432 * @mac_ctx: pointer to mac_context
11433 * @bss_desc: BSS Descriptor
11434 * @scan_entry: scan entry
11435 *
11436 * Return: None
11437 */
11438 static void
11439 wlan_fill_single_pmk_ap_cap_from_scan_entry(struct mac_context *mac_ctx,
11440 struct bss_description *bss_desc,
11441 struct scan_cache_entry *scan_entry)
11442 {
11443 bss_desc->is_single_pmk =
11444 util_scan_entry_single_pmk(mac_ctx->psoc, scan_entry) &&
11445 mac_ctx->mlme_cfg->lfr.sae_single_pmk_feature_enabled;
11446 }
11447 #else
11448 static inline void
11449 wlan_fill_single_pmk_ap_cap_from_scan_entry(struct mac_context *mac_ctx,
11450 struct bss_description *bss_desc,
11451 struct scan_cache_entry *scan_entry)
11452 {
11453 }
11454 #endif
11455
11456 QDF_STATUS wlan_parse_bss_description_ies(struct mac_context *mac_ctx,
11457 struct bss_description *bss_desc,
11458 tDot11fBeaconIEs *ie_struct)
11459 {
11460 int ie_len = wlan_get_ielen_from_bss_description(bss_desc);
11461 QDF_STATUS status;
11462
11463 if (ie_len <= 0 || !ie_struct) {
11464 pe_err("BSS description has invalid IE : %d", ie_len);
11465 return QDF_STATUS_E_FAILURE;
11466 }
11467 if (DOT11F_FAILED(dot11f_unpack_beacon_i_es
11468 (mac_ctx, (uint8_t *)bss_desc->ieFields,
11469 ie_len, ie_struct, false))) {
11470 pe_err("Beacon IE parsing failed");
11471 return QDF_STATUS_E_FAILURE;
11472 }
11473
11474 status = lim_strip_and_decode_eht_op((uint8_t *)bss_desc->ieFields,
11475 ie_len, &ie_struct->eht_op,
11476 ie_struct->VHTOperation,
11477 ie_struct->he_op,
11478 ie_struct->HTInfo);
11479 if (status != QDF_STATUS_SUCCESS) {
11480 pe_err("Failed to extract eht op");
11481 return QDF_STATUS_E_FAILURE;
11482 }
11483
11484 status = lim_strip_and_decode_eht_cap((uint8_t *)bss_desc->ieFields,
11485 ie_len, &ie_struct->eht_cap,
11486 ie_struct->he_cap,
11487 bss_desc->chan_freq);
11488 if (status != QDF_STATUS_SUCCESS) {
11489 pe_err("Failed to extract eht cap");
11490 return QDF_STATUS_E_FAILURE;
11491 }
11492
11493 return QDF_STATUS_SUCCESS;
11494 }
11495
11496 QDF_STATUS
11497 wlan_get_parsed_bss_description_ies(struct mac_context *mac_ctx,
11498 struct bss_description *bss_desc,
11499 tDot11fBeaconIEs **ie_struct)
11500 {
11501 QDF_STATUS status;
11502
11503 if (!bss_desc || !ie_struct)
11504 return QDF_STATUS_E_INVAL;
11505
11506 *ie_struct = qdf_mem_malloc(sizeof(tDot11fBeaconIEs));
11507 if (!*ie_struct)
11508 return QDF_STATUS_E_NOMEM;
11509
11510 status = wlan_parse_bss_description_ies(mac_ctx, bss_desc,
11511 *ie_struct);
11512 if (QDF_IS_STATUS_ERROR(status)) {
11513 qdf_mem_free(*ie_struct);
11514 *ie_struct = NULL;
11515 }
11516
11517 return status;
11518 }
11519
11520 void
11521 wlan_populate_basic_rates(tSirMacRateSet *rate_set, bool is_ofdm_rates,
11522 bool is_basic_rates)
11523 {
11524 uint8_t ofdm_rates[8] = {
11525 SIR_MAC_RATE_6,
11526 SIR_MAC_RATE_9,
11527 SIR_MAC_RATE_12,
11528 SIR_MAC_RATE_18,
11529 SIR_MAC_RATE_24,
11530 SIR_MAC_RATE_36,
11531 SIR_MAC_RATE_48,
11532 SIR_MAC_RATE_54
11533 };
11534 uint8_t cck_rates[4] = {
11535 SIR_MAC_RATE_1,
11536 SIR_MAC_RATE_2,
11537 SIR_MAC_RATE_5_5,
11538 SIR_MAC_RATE_11
11539 };
11540
11541 if (is_ofdm_rates == true) {
11542 rate_set->numRates = 8;
11543 qdf_mem_copy(rate_set->rate, ofdm_rates, sizeof(ofdm_rates));
11544 if (is_basic_rates) {
11545 rate_set->rate[0] |= WLAN_DOT11_BASIC_RATE_MASK;
11546 rate_set->rate[2] |= WLAN_DOT11_BASIC_RATE_MASK;
11547 rate_set->rate[4] |= WLAN_DOT11_BASIC_RATE_MASK;
11548 }
11549 pe_debug("Default OFDM Rates");
11550 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_DEBUG,
11551 rate_set->rate, rate_set->numRates);
11552 } else {
11553 rate_set->numRates = 4;
11554 qdf_mem_copy(rate_set->rate, cck_rates, sizeof(cck_rates));
11555 if (is_basic_rates) {
11556 rate_set->rate[0] |= WLAN_DOT11_BASIC_RATE_MASK;
11557 rate_set->rate[1] |= WLAN_DOT11_BASIC_RATE_MASK;
11558 rate_set->rate[2] |= WLAN_DOT11_BASIC_RATE_MASK;
11559 rate_set->rate[3] |= WLAN_DOT11_BASIC_RATE_MASK;
11560 }
11561 pe_debug("Default CCK Rates");
11562 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_DEBUG,
11563 rate_set->rate, rate_set->numRates);
11564 }
11565 }
11566
11567 /**
11568 * wlan_is_aggregate_rate_supported() - to check if aggregate rate is supported
11569 * @mac_ctx: pointer to mac context
11570 * @rate: A rate in units of 500kbps
11571 *
11572 *
11573 * The rate encoding is just as in 802.11 Information Elements, except
11574 * that the high bit is \em not interpreted as indicating a Basic Rate,
11575 * and proprietary rates are allowed, too.
11576 *
11577 * Note that if the adapter's dot11Mode is g, we don't restrict the
11578 * rates. According to hwReadEepromParameters, this will happen when:
11579 * ... the card is configured for ALL bands through the property
11580 * page. If this occurs, and the card is not an ABG card ,then this
11581 * code is setting the dot11Mode to assume the mode that the
11582 * hardware can support. For example, if the card is an 11BG card
11583 * and we are configured to support ALL bands, then we change the
11584 * dot11Mode to 11g because ALL in this case is only what the
11585 * hardware can support.
11586 *
11587 * Return: true if the adapter is currently capable of supporting this rate
11588 */
11589
11590 static bool wlan_is_aggregate_rate_supported(struct mac_context *mac_ctx,
11591 uint16_t rate)
11592 {
11593 bool supported = false;
11594 uint16_t idx, new_rate;
11595 enum mlme_dot11_mode self_dot11_mode =
11596 mac_ctx->mlme_cfg->dot11_mode.dot11_mode;
11597
11598 /* In case basic rate flag is set */
11599 new_rate = BITS_OFF(rate, WLAN_DOT11_BASIC_RATE_MASK);
11600 if (self_dot11_mode == MLME_DOT11_MODE_11A) {
11601 switch (new_rate) {
11602 case SUPP_RATE_6_MBPS:
11603 case SUPP_RATE_9_MBPS:
11604 case SUPP_RATE_12_MBPS:
11605 case SUPP_RATE_18_MBPS:
11606 case SUPP_RATE_24_MBPS:
11607 case SUPP_RATE_36_MBPS:
11608 case SUPP_RATE_48_MBPS:
11609 case SUPP_RATE_54_MBPS:
11610 supported = true;
11611 break;
11612 default:
11613 supported = false;
11614 break;
11615 }
11616 } else if (self_dot11_mode == MLME_DOT11_MODE_11B) {
11617 switch (new_rate) {
11618 case SUPP_RATE_1_MBPS:
11619 case SUPP_RATE_2_MBPS:
11620 case SUPP_RATE_5_MBPS:
11621 case SUPP_RATE_11_MBPS:
11622 supported = true;
11623 break;
11624 default:
11625 supported = false;
11626 break;
11627 }
11628 } else if (!mac_ctx->roam.configParam.ProprietaryRatesEnabled) {
11629 switch (new_rate) {
11630 case SUPP_RATE_1_MBPS:
11631 case SUPP_RATE_2_MBPS:
11632 case SUPP_RATE_5_MBPS:
11633 case SUPP_RATE_6_MBPS:
11634 case SUPP_RATE_9_MBPS:
11635 case SUPP_RATE_11_MBPS:
11636 case SUPP_RATE_12_MBPS:
11637 case SUPP_RATE_18_MBPS:
11638 case SUPP_RATE_24_MBPS:
11639 case SUPP_RATE_36_MBPS:
11640 case SUPP_RATE_48_MBPS:
11641 case SUPP_RATE_54_MBPS:
11642 supported = true;
11643 break;
11644 default:
11645 supported = false;
11646 break;
11647 }
11648 } else if (new_rate == SUPP_RATE_1_MBPS ||
11649 new_rate == SUPP_RATE_2_MBPS ||
11650 new_rate == SUPP_RATE_5_MBPS ||
11651 new_rate == SUPP_RATE_11_MBPS)
11652 supported = true;
11653 else {
11654 idx = 0x1;
11655
11656 switch (new_rate) {
11657 case SUPP_RATE_6_MBPS:
11658 supported = g_phy_rates_suppt[0][idx];
11659 break;
11660 case SUPP_RATE_9_MBPS:
11661 supported = g_phy_rates_suppt[1][idx];
11662 break;
11663 case SUPP_RATE_12_MBPS:
11664 supported = g_phy_rates_suppt[2][idx];
11665 break;
11666 case SUPP_RATE_18_MBPS:
11667 supported = g_phy_rates_suppt[3][idx];
11668 break;
11669 case SUPP_RATE_20_MBPS:
11670 supported = g_phy_rates_suppt[4][idx];
11671 break;
11672 case SUPP_RATE_24_MBPS:
11673 supported = g_phy_rates_suppt[5][idx];
11674 break;
11675 case SUPP_RATE_36_MBPS:
11676 supported = g_phy_rates_suppt[6][idx];
11677 break;
11678 case SUPP_RATE_40_MBPS:
11679 supported = g_phy_rates_suppt[7][idx];
11680 break;
11681 case SUPP_RATE_42_MBPS:
11682 supported = g_phy_rates_suppt[8][idx];
11683 break;
11684 case SUPP_RATE_48_MBPS:
11685 supported = g_phy_rates_suppt[9][idx];
11686 break;
11687 case SUPP_RATE_54_MBPS:
11688 supported = g_phy_rates_suppt[10][idx];
11689 break;
11690 case SUPP_RATE_72_MBPS:
11691 supported = g_phy_rates_suppt[11][idx];
11692 break;
11693 case SUPP_RATE_80_MBPS:
11694 supported = g_phy_rates_suppt[12][idx];
11695 break;
11696 case SUPP_RATE_84_MBPS:
11697 supported = g_phy_rates_suppt[13][idx];
11698 break;
11699 case SUPP_RATE_96_MBPS:
11700 supported = g_phy_rates_suppt[14][idx];
11701 break;
11702 case SUPP_RATE_108_MBPS:
11703 supported = g_phy_rates_suppt[15][idx];
11704 break;
11705 case SUPP_RATE_120_MBPS:
11706 supported = g_phy_rates_suppt[16][idx];
11707 break;
11708 case SUPP_RATE_126_MBPS:
11709 supported = g_phy_rates_suppt[17][idx];
11710 break;
11711 case SUPP_RATE_144_MBPS:
11712 supported = g_phy_rates_suppt[18][idx];
11713 break;
11714 case SUPP_RATE_160_MBPS:
11715 supported = g_phy_rates_suppt[19][idx];
11716 break;
11717 case SUPP_RATE_168_MBPS:
11718 supported = g_phy_rates_suppt[20][idx];
11719 break;
11720 case SUPP_RATE_192_MBPS:
11721 supported = g_phy_rates_suppt[21][idx];
11722 break;
11723 case SUPP_RATE_216_MBPS:
11724 supported = g_phy_rates_suppt[22][idx];
11725 break;
11726 case SUPP_RATE_240_MBPS:
11727 supported = g_phy_rates_suppt[23][idx];
11728 break;
11729 default:
11730 supported = false;
11731 break;
11732 }
11733 }
11734
11735 return supported;
11736 }
11737
11738 bool wlan_rates_is_dot11_rate_supported(struct mac_context *mac_ctx,
11739 uint8_t rate)
11740 {
11741 uint16_t n = BITS_OFF(rate, WLAN_DOT11_BASIC_RATE_MASK);
11742
11743 return wlan_is_aggregate_rate_supported(mac_ctx, n);
11744 }
11745
11746 bool wlan_check_rate_bitmap(uint8_t rate, uint16_t rate_bitmap)
11747 {
11748 uint16_t n = BITS_OFF(rate, WLAN_DOT11_BASIC_RATE_MASK);
11749
11750 switch (n) {
11751 case SIR_MAC_RATE_1:
11752 rate_bitmap &= SIR_MAC_RATE_1_BITMAP;
11753 break;
11754 case SIR_MAC_RATE_2:
11755 rate_bitmap &= SIR_MAC_RATE_2_BITMAP;
11756 break;
11757 case SIR_MAC_RATE_5_5:
11758 rate_bitmap &= SIR_MAC_RATE_5_5_BITMAP;
11759 break;
11760 case SIR_MAC_RATE_11:
11761 rate_bitmap &= SIR_MAC_RATE_11_BITMAP;
11762 break;
11763 case SIR_MAC_RATE_6:
11764 rate_bitmap &= SIR_MAC_RATE_6_BITMAP;
11765 break;
11766 case SIR_MAC_RATE_9:
11767 rate_bitmap &= SIR_MAC_RATE_9_BITMAP;
11768 break;
11769 case SIR_MAC_RATE_12:
11770 rate_bitmap &= SIR_MAC_RATE_12_BITMAP;
11771 break;
11772 case SIR_MAC_RATE_18:
11773 rate_bitmap &= SIR_MAC_RATE_18_BITMAP;
11774 break;
11775 case SIR_MAC_RATE_24:
11776 rate_bitmap &= SIR_MAC_RATE_24_BITMAP;
11777 break;
11778 case SIR_MAC_RATE_36:
11779 rate_bitmap &= SIR_MAC_RATE_36_BITMAP;
11780 break;
11781 case SIR_MAC_RATE_48:
11782 rate_bitmap &= SIR_MAC_RATE_48_BITMAP;
11783 break;
11784 case SIR_MAC_RATE_54:
11785 rate_bitmap &= SIR_MAC_RATE_54_BITMAP;
11786 break;
11787 }
11788 return !!rate_bitmap;
11789 }
11790
11791 void wlan_add_rate_bitmap(uint8_t rate, uint16_t *rate_bitmap)
11792 {
11793 uint16_t n = BITS_OFF(rate, CSR_DOT11_BASIC_RATE_MASK);
11794
11795 switch (n) {
11796 case SIR_MAC_RATE_1:
11797 *rate_bitmap |= SIR_MAC_RATE_1_BITMAP;
11798 break;
11799 case SIR_MAC_RATE_2:
11800 *rate_bitmap |= SIR_MAC_RATE_2_BITMAP;
11801 break;
11802 case SIR_MAC_RATE_5_5:
11803 *rate_bitmap |= SIR_MAC_RATE_5_5_BITMAP;
11804 break;
11805 case SIR_MAC_RATE_11:
11806 *rate_bitmap |= SIR_MAC_RATE_11_BITMAP;
11807 break;
11808 case SIR_MAC_RATE_6:
11809 *rate_bitmap |= SIR_MAC_RATE_6_BITMAP;
11810 break;
11811 case SIR_MAC_RATE_9:
11812 *rate_bitmap |= SIR_MAC_RATE_9_BITMAP;
11813 break;
11814 case SIR_MAC_RATE_12:
11815 *rate_bitmap |= SIR_MAC_RATE_12_BITMAP;
11816 break;
11817 case SIR_MAC_RATE_18:
11818 *rate_bitmap |= SIR_MAC_RATE_18_BITMAP;
11819 break;
11820 case SIR_MAC_RATE_24:
11821 *rate_bitmap |= SIR_MAC_RATE_24_BITMAP;
11822 break;
11823 case SIR_MAC_RATE_36:
11824 *rate_bitmap |= SIR_MAC_RATE_36_BITMAP;
11825 break;
11826 case SIR_MAC_RATE_48:
11827 *rate_bitmap |= SIR_MAC_RATE_48_BITMAP;
11828 break;
11829 case SIR_MAC_RATE_54:
11830 *rate_bitmap |= SIR_MAC_RATE_54_BITMAP;
11831 break;
11832 }
11833 }
11834
11835 static bool is_ofdm_rates(uint16_t rate)
11836 {
11837 uint16_t n = BITS_OFF(rate, WLAN_DOT11_BASIC_RATE_MASK);
11838
11839 switch (n) {
11840 case SIR_MAC_RATE_6:
11841 case SIR_MAC_RATE_9:
11842 case SIR_MAC_RATE_12:
11843 case SIR_MAC_RATE_18:
11844 case SIR_MAC_RATE_24:
11845 case SIR_MAC_RATE_36:
11846 case SIR_MAC_RATE_48:
11847 case SIR_MAC_RATE_54:
11848 return true;
11849 default:
11850 break;
11851 }
11852
11853 return false;
11854 }
11855
11856 QDF_STATUS wlan_get_rate_set(struct mac_context *mac,
11857 tDot11fBeaconIEs *ie_struct,
11858 struct pe_session *pe_session)
11859 {
11860 QDF_STATUS status = QDF_STATUS_E_FAILURE;
11861 int i;
11862 uint8_t *dst_rate;
11863 uint16_t rateBitmap = 0;
11864 bool is_24ghz_freq;
11865 tSirMacRateSet *op_rate;
11866 tSirMacRateSet *ext_rate;
11867 tSirMacRateSet rate_set;
11868
11869
11870 if (!pe_session) {
11871 pe_err("pe session is NULL");
11872 return QDF_STATUS_E_INVAL;
11873 }
11874 op_rate = &pe_session->rateSet;
11875 ext_rate = &pe_session->extRateSet;
11876 is_24ghz_freq = wlan_reg_is_24ghz_ch_freq(pe_session->curr_op_freq);
11877
11878 qdf_mem_zero(op_rate, sizeof(tSirMacRateSet));
11879 qdf_mem_zero(ext_rate, sizeof(tSirMacRateSet));
11880 qdf_mem_zero(&rate_set, sizeof(tSirMacRateSet));
11881 QDF_ASSERT(ie_struct);
11882
11883 /*
11884 * Originally, we thought that for 11a networks, the 11a rates
11885 * are always in the Operational Rate set & for 11b and 11g
11886 * networks, the 11b rates appear in the Operational Rate set.
11887 * Consequently, in either case, we would blindly put the rates
11888 * we support into our Operational Rate set.
11889 * (including the basic rates, which we've already verified are
11890 * supported earlier in the roaming decision).
11891 * However, it turns out that this is not always the case.
11892 * Some AP's (e.g. D-Link DI-784) ram 11g rates into the
11893 * Operational Rate set too. Now, we're a little more careful.
11894 */
11895 dst_rate = op_rate->rate;
11896 if (ie_struct->SuppRates.present) {
11897 for (i = 0; i < ie_struct->SuppRates.num_rates; i++) {
11898 if (!is_24ghz_freq &&
11899 !is_ofdm_rates(ie_struct->SuppRates.rates[i]))
11900 continue;
11901
11902 if (wlan_rates_is_dot11_rate_supported(mac,
11903 ie_struct->SuppRates.rates[i]) &&
11904 !wlan_check_rate_bitmap(
11905 ie_struct->SuppRates.rates[i],
11906 rateBitmap)) {
11907 wlan_add_rate_bitmap(ie_struct->SuppRates.
11908 rates[i], &rateBitmap);
11909 *dst_rate++ = ie_struct->SuppRates.rates[i];
11910 op_rate->numRates++;
11911 }
11912 }
11913 }
11914 /*
11915 * If there are Extended Rates in the beacon, we will reflect the
11916 * extended rates that we support in our Extended Operational Rate
11917 * set.
11918 */
11919 if (ie_struct->ExtSuppRates.present) {
11920 dst_rate = ext_rate->rate;
11921 for (i = 0; i < ie_struct->ExtSuppRates.num_rates; i++) {
11922 if (wlan_rates_is_dot11_rate_supported(mac,
11923 ie_struct->ExtSuppRates.rates[i]) &&
11924 !wlan_check_rate_bitmap(
11925 ie_struct->ExtSuppRates.rates[i],
11926 rateBitmap)) {
11927 *dst_rate++ = ie_struct->ExtSuppRates.rates[i];
11928 ext_rate->numRates++;
11929 }
11930 }
11931 }
11932 if (!op_rate->numRates) {
11933 dst_rate = op_rate->rate;
11934 wlan_populate_basic_rates(&rate_set, !is_24ghz_freq, true);
11935 for (i = 0; i < rate_set.numRates; i++) {
11936 if (!wlan_check_rate_bitmap(rate_set.rate[i],
11937 rateBitmap)) {
11938 wlan_add_rate_bitmap(rate_set.rate[i],
11939 &rateBitmap);
11940 *dst_rate++ = rate_set.rate[i];
11941 op_rate->numRates++;
11942 }
11943 }
11944 if (!is_24ghz_freq)
11945 return QDF_STATUS_SUCCESS;
11946
11947 wlan_populate_basic_rates(&rate_set, true, false);
11948 for (i = op_rate->numRates;
11949 i < WLAN_SUPPORTED_RATES_IE_MAX_LEN; i++) {
11950 if (!wlan_check_rate_bitmap(rate_set.rate[i],
11951 rateBitmap)) {
11952 wlan_add_rate_bitmap(rate_set.rate[i],
11953 &rateBitmap);
11954 *dst_rate++ = rate_set.rate[i];
11955 op_rate->numRates++;
11956 }
11957 }
11958 }
11959 if (op_rate->numRates > 0 || ext_rate->numRates > 0)
11960 status = QDF_STATUS_SUCCESS;
11961
11962 return status;
11963 }
11964
11965 uint32_t wlan_get_11h_power_constraint(struct mac_context *mac_ctx,
11966 tDot11fIEPowerConstraints *constraints)
11967 {
11968 uint32_t local_power_constraint = 0;
11969
11970 /*
11971 * check if .11h support is enabled, if not,
11972 * the power constraint is 0.
11973 */
11974 if (mac_ctx->mlme_cfg->gen.enabled_11h && constraints->present)
11975 local_power_constraint = constraints->localPowerConstraints;
11976
11977 return local_power_constraint;
11978 }
11979
11980 #ifdef FEATURE_WLAN_ESE
11981 static void wlan_fill_qbss_load_param(tDot11fBeaconIEs *bcn_ies,
11982 struct bss_description *bss_desc)
11983 {
11984 if (!bcn_ies->QBSSLoad.present)
11985 return;
11986
11987 bss_desc->QBSSLoad_present = true;
11988 bss_desc->QBSSLoad_avail = bcn_ies->QBSSLoad.avail;
11989 }
11990 #else
11991 static void wlan_fill_qbss_load_param(tDot11fBeaconIEs *bcn_ies,
11992 struct bss_description *bss_desc)
11993 {
11994 }
11995 #endif
11996
11997 #ifdef WLAN_FEATURE_FILS_SK
11998 static void wlan_update_bss_with_fils_data(struct mac_context *mac_ctx,
11999 struct scan_cache_entry *scan_entry,
12000 struct bss_description *bss_descr)
12001 {
12002 int ret;
12003 tDot11fIEfils_indication *fils_indication;
12004 struct sir_fils_indication *fils_ind;
12005
12006 if (!scan_entry->ie_list.fils_indication)
12007 return;
12008
12009 fils_indication = qdf_mem_malloc(sizeof(*fils_indication));
12010 if (!fils_indication) {
12011 pe_err("malloc failed for fils_indication");
12012 return;
12013 }
12014
12015 ret = dot11f_unpack_ie_fils_indication(mac_ctx,
12016 scan_entry->ie_list.fils_indication +
12017 SIR_FILS_IND_ELEM_OFFSET,
12018 *(scan_entry->ie_list.fils_indication + 1),
12019 fils_indication, false);
12020 if (DOT11F_FAILED(ret)) {
12021 pe_err("unpack failed ret: 0x%x", ret);
12022 qdf_mem_free(fils_indication);
12023 return;
12024 }
12025
12026 fils_ind = qdf_mem_malloc(sizeof(*fils_ind));
12027 if (!fils_ind) {
12028 pe_err("malloc failed for fils_ind");
12029 qdf_mem_free(fils_indication);
12030 return;
12031 }
12032
12033 update_fils_data(fils_ind, fils_indication);
12034 if (fils_ind->realm_identifier.realm_cnt > SIR_MAX_REALM_COUNT)
12035 fils_ind->realm_identifier.realm_cnt = SIR_MAX_REALM_COUNT;
12036
12037 bss_descr->fils_info_element.realm_cnt =
12038 fils_ind->realm_identifier.realm_cnt;
12039 qdf_mem_copy(bss_descr->fils_info_element.realm,
12040 fils_ind->realm_identifier.realm,
12041 bss_descr->fils_info_element.realm_cnt * SIR_REALM_LEN);
12042 pe_debug("FILS: bssid:" QDF_MAC_ADDR_FMT "is_present:%d cache_id[0x%x%x]",
12043 QDF_MAC_ADDR_REF(bss_descr->bssId),
12044 fils_ind->cache_identifier.is_present,
12045 fils_ind->cache_identifier.identifier[0],
12046 fils_ind->cache_identifier.identifier[1]);
12047 if (fils_ind->cache_identifier.is_present) {
12048 bss_descr->fils_info_element.is_cache_id_present = true;
12049 qdf_mem_copy(bss_descr->fils_info_element.cache_id,
12050 fils_ind->cache_identifier.identifier, CACHE_ID_LEN);
12051 }
12052 if (fils_ind->is_fils_sk_auth_supported)
12053 bss_descr->fils_info_element.is_fils_sk_supported = true;
12054
12055 qdf_mem_free(fils_ind);
12056 qdf_mem_free(fils_indication);
12057 }
12058 #else
12059 static void wlan_update_bss_with_fils_data(struct mac_context *mac_ctx,
12060 struct scan_cache_entry *scan_entry,
12061 struct bss_description *bss_descr)
12062 { }
12063 #endif
12064
12065 QDF_STATUS
12066 wlan_fill_bss_desc_from_scan_entry(struct mac_context *mac_ctx,
12067 struct bss_description *bss_desc,
12068 struct scan_cache_entry *scan_entry)
12069 {
12070 uint8_t *ie_ptr;
12071 uint32_t ie_len;
12072 tpSirMacMgmtHdr hdr;
12073 tDot11fBeaconIEs *bcn_ies;
12074 QDF_STATUS status;
12075
12076 hdr = (tpSirMacMgmtHdr)scan_entry->raw_frame.ptr;
12077
12078 ie_len = util_scan_entry_ie_len(scan_entry);
12079 ie_ptr = util_scan_entry_ie_data(scan_entry);
12080
12081 bss_desc->length = (uint16_t) (offsetof(struct bss_description,
12082 ieFields[0]) - sizeof(bss_desc->length) + ie_len);
12083
12084 qdf_mem_copy(bss_desc->bssId, scan_entry->bssid.bytes,
12085 QDF_MAC_ADDR_SIZE);
12086 bss_desc->scansystimensec = scan_entry->boottime_ns;
12087 qdf_mem_copy(bss_desc->timeStamp,
12088 scan_entry->tsf_info.data, 8);
12089
12090 bss_desc->beaconInterval = scan_entry->bcn_int;
12091 bss_desc->capabilityInfo = scan_entry->cap_info.value;
12092
12093 if (WLAN_REG_IS_5GHZ_CH_FREQ(scan_entry->channel.chan_freq) ||
12094 WLAN_REG_IS_6GHZ_CHAN_FREQ(scan_entry->channel.chan_freq))
12095 bss_desc->nwType = eSIR_11A_NW_TYPE;
12096 else if (scan_entry->phy_mode == WLAN_PHYMODE_11B)
12097 bss_desc->nwType = eSIR_11B_NW_TYPE;
12098 else
12099 bss_desc->nwType = eSIR_11G_NW_TYPE;
12100
12101 bss_desc->rssi = scan_entry->rssi_raw;
12102 bss_desc->rssi_raw = scan_entry->rssi_raw;
12103
12104 /* channel frequency what peer sent in beacon/probersp. */
12105 bss_desc->chan_freq = scan_entry->channel.chan_freq;
12106 bss_desc->received_time =
12107 scan_entry->scan_entry_time;
12108 bss_desc->startTSF[0] =
12109 mac_ctx->rrm.rrmPEContext.startTSF[0];
12110 bss_desc->startTSF[1] =
12111 mac_ctx->rrm.rrmPEContext.startTSF[1];
12112 bss_desc->parentTSF =
12113 scan_entry->rrm_parent_tsf;
12114 bss_desc->fProbeRsp = (scan_entry->frm_subtype ==
12115 MGMT_SUBTYPE_PROBE_RESP);
12116 bss_desc->seq_ctrl = hdr->seqControl;
12117 bss_desc->tsf_delta = scan_entry->tsf_delta;
12118 bss_desc->adaptive_11r_ap = scan_entry->adaptive_11r_ap;
12119
12120 bss_desc->mbo_oce_enabled_ap =
12121 util_scan_entry_mbo_oce(scan_entry) ? true : false;
12122
12123 wlan_fill_single_pmk_ap_cap_from_scan_entry(mac_ctx, bss_desc,
12124 scan_entry);
12125
12126 qdf_mem_copy(&bss_desc->mbssid_info, &scan_entry->mbssid_info,
12127 sizeof(struct scan_mbssid_info));
12128
12129 qdf_mem_copy((uint8_t *) &bss_desc->ieFields, ie_ptr, ie_len);
12130
12131 status = wlan_get_parsed_bss_description_ies(mac_ctx, bss_desc,
12132 &bcn_ies);
12133 if (QDF_IS_STATUS_ERROR(status))
12134 return status;
12135
12136 if (bcn_ies->MobilityDomain.present) {
12137 bss_desc->mdiePresent = true;
12138 qdf_mem_copy((uint8_t *)&(bss_desc->mdie[0]),
12139 (uint8_t *)&(bcn_ies->MobilityDomain.MDID),
12140 sizeof(uint16_t));
12141 bss_desc->mdie[2] =
12142 ((bcn_ies->MobilityDomain.overDSCap << 0) |
12143 (bcn_ies->MobilityDomain.resourceReqCap << 1));
12144 }
12145
12146 wlan_fill_qbss_load_param(bcn_ies, bss_desc);
12147 wlan_update_bss_with_fils_data(mac_ctx, scan_entry, bss_desc);
12148
12149 qdf_mem_free(bcn_ies);
12150
12151 return QDF_STATUS_SUCCESS;
12152 }
12153
12154 uint16_t
12155 wlan_get_ielen_from_bss_description(struct bss_description *bss_desc)
12156 {
12157 uint16_t ielen, ieFields_offset;
12158
12159 ieFields_offset = GET_FIELD_OFFSET(struct bss_description, ieFields);
12160
12161 if (!bss_desc) {
12162 pe_err_rl("Bss_desc is NULL");
12163 return 0;
12164 }
12165
12166 if (bss_desc->length <= (ieFields_offset - sizeof(bss_desc->length))) {
12167 pe_err_rl("Invalid bss_desc len:%d ie_fields_offset:%d",
12168 bss_desc->length, ieFields_offset);
12169 return 0;
12170 }
12171
12172 /*
12173 * Length of BSS description is without length of
12174 * length itself and length of pointer
12175 * that holds ieFields
12176 *
12177 * <------------sizeof(struct bss_description)-------------------->
12178 * +--------+---------------------------------+---------------+
12179 * | length | other fields | pointer to IEs|
12180 * +--------+---------------------------------+---------------+
12181 * ^
12182 * ieFields
12183 */
12184
12185 ielen = (uint16_t)(bss_desc->length + sizeof(bss_desc->length) -
12186 ieFields_offset);
12187
12188 return ielen;
12189 }
12190
12191 QDF_STATUS populate_dot11f_btm_extended_caps(struct mac_context *mac_ctx,
12192 struct pe_session *pe_session,
12193 struct sDot11fIEExtCap *dot11f)
12194 {
12195 struct s_ext_cap *p_ext_cap;
12196 QDF_STATUS status;
12197 bool is_disable_btm;
12198 struct cm_roam_values_copy temp;
12199
12200 dot11f->num_bytes = DOT11F_IE_EXTCAP_MAX_LEN;
12201 p_ext_cap = (struct s_ext_cap *)dot11f->bytes;
12202 dot11f->present = 1;
12203
12204 status = cm_akm_roam_allowed(mac_ctx->psoc, pe_session->vdev);
12205 if (QDF_IS_STATUS_ERROR(status)) {
12206 p_ext_cap->bss_transition = 0;
12207 pe_debug("vdev:%d, Disable btm for roaming not suppprted",
12208 pe_session->vdev_id);
12209 }
12210
12211 wlan_cm_roam_cfg_get_value(mac_ctx->psoc, pe_session->vdev_id,
12212 IS_DISABLE_BTM, &temp);
12213 is_disable_btm = temp.bool_value;
12214 if (is_disable_btm) {
12215 pe_debug("vdev:%d, Disable BTM as BTM roam disabled by user",
12216 pe_session->vdev_id);
12217 p_ext_cap->bss_transition = 0;
12218 }
12219
12220 if (!pe_session->lim_join_req)
12221 goto compute_len;
12222
12223 if (p_ext_cap->bss_transition && !cm_is_open_mode(pe_session->vdev) &&
12224 pe_session->lim_join_req->bssDescription.mbo_oce_enabled_ap &&
12225 !pe_session->limRmfEnabled) {
12226 pe_debug("vdev:%d, Disable BTM as MBO AP doesn't support PMF",
12227 pe_session->vdev_id);
12228 p_ext_cap->bss_transition = 0;
12229 }
12230
12231 compute_len:
12232 dot11f->num_bytes = lim_compute_ext_cap_ie_length(dot11f);
12233 if (!dot11f->num_bytes) {
12234 dot11f->present = 0;
12235 pe_debug("ext ie length become 0, disable the ext caps");
12236 }
12237
12238 wlan_cm_set_assoc_btm_cap(pe_session->vdev, p_ext_cap->bss_transition);
12239 return QDF_STATUS_SUCCESS;
12240 }
12241
12242 #ifdef WLAN_FEATURE_11BE_MLO
12243 /**
12244 * populate_dot11f_mlo_partner_sta_cap() - populate mlo sta partner capability
12245 * @mac: mac
12246 * @pDot11f: tDot11fFfCapabilities
12247 *
12248 * Return: QDF_STATUS
12249 */
12250 static QDF_STATUS
12251 populate_dot11f_mlo_partner_sta_cap(struct mac_context *mac,
12252 tDot11fFfCapabilities *pDot11f)
12253 {
12254 uint16_t cap = 0;
12255 uint32_t val = 0;
12256 tpSirMacCapabilityInfo pcap_info;
12257
12258 pcap_info = (tpSirMacCapabilityInfo)∩
12259
12260 pcap_info->ess = 1; /* ESS bit */
12261
12262 if (mac->mlme_cfg->wep_params.is_privacy_enabled)
12263 pcap_info->privacy = 1;
12264
12265 /* Short preamble bit */
12266 if (mac->mlme_cfg->ht_caps.short_preamble)
12267 pcap_info->shortPreamble =
12268 mac->mlme_cfg->ht_caps.short_preamble;
12269
12270 /* criticalUpdateFlag bit */
12271 pcap_info->criticalUpdateFlag = 0;
12272
12273 /* Channel agility bit */
12274 pcap_info->channelAgility = 0;
12275
12276 /* Short slot time bit */
12277 if (mac->mlme_cfg->feature_flags.enable_short_slot_time_11g)
12278 pcap_info->shortSlotTime = 1;
12279
12280 /* Spectrum Management bit */
12281 if (mac->mlme_cfg->gen.enabled_11h)
12282 pcap_info->spectrumMgt = 1;
12283 /* QoS bit */
12284 if (mac->mlme_cfg->wmm_params.qos_enabled)
12285 pcap_info->qos = 1;
12286
12287 /* APSD bit */
12288 if (mac->mlme_cfg->roam_scoring.apsd_enabled)
12289 pcap_info->apsd = 1;
12290
12291 pcap_info->rrm = mac->rrm.rrmConfig.rrm_enabled;
12292 /* DSSS-OFDM */
12293 /* FIXME : no config defined yet. */
12294
12295 /* Block ack bit */
12296 val = mac->mlme_cfg->feature_flags.enable_block_ack;
12297 pcap_info->delayedBA =
12298 (uint16_t)((val >> WNI_CFG_BLOCK_ACK_ENABLED_DELAYED) & 1);
12299 pcap_info->immediateBA =
12300 (uint16_t)((val >> WNI_CFG_BLOCK_ACK_ENABLED_IMMEDIATE) & 1);
12301
12302 swap_bit_field16(cap, (uint16_t *)pDot11f);
12303
12304 return QDF_STATUS_SUCCESS;
12305 }
12306
12307 QDF_STATUS populate_dot11f_auth_mlo_ie(struct mac_context *mac_ctx,
12308 struct pe_session *pe_session,
12309 struct wlan_mlo_ie *mlo_ie)
12310 {
12311 struct qdf_mac_addr *mld_addr;
12312 uint8_t *p_ml_ie;
12313 uint16_t len_remaining;
12314
12315 pe_debug("Populate Auth MLO IEs");
12316
12317 mlo_ie->type = 0;
12318
12319 mlo_ie->common_info_length = WLAN_ML_BV_CINFO_LENGTH_SIZE;
12320 mld_addr = (struct qdf_mac_addr *)wlan_vdev_mlme_get_mldaddr(
12321 pe_session->vdev);
12322 qdf_mem_copy(&mlo_ie->mld_mac_addr, mld_addr, QDF_MAC_ADDR_SIZE);
12323 mlo_ie->common_info_length += QDF_MAC_ADDR_SIZE;
12324
12325 pe_debug("MLD mac addr: " QDF_MAC_ADDR_FMT,
12326 QDF_MAC_ADDR_REF(mld_addr->bytes));
12327
12328 mlo_ie->link_id_info_present = 0;
12329 mlo_ie->bss_param_change_cnt_present = 0;
12330 mlo_ie->medium_sync_delay_info_present = 0;
12331 mlo_ie->eml_capab_present = 0;
12332 mlo_ie->mld_capab_and_op_present = 0;
12333 mlo_ie->mld_id_present = 0;
12334 mlo_ie->ext_mld_capab_and_op_present = 0;
12335
12336 p_ml_ie = mlo_ie->data;
12337 len_remaining = sizeof(mlo_ie->data);
12338
12339 *p_ml_ie++ = WLAN_ELEMID_EXTN_ELEM;
12340 len_remaining--;
12341 *p_ml_ie++ = 0;
12342 len_remaining--;
12343 *p_ml_ie++ = WLAN_EXTN_ELEMID_MULTI_LINK;
12344 len_remaining--;
12345
12346 QDF_SET_BITS(*(uint16_t *)p_ml_ie, WLAN_ML_CTRL_TYPE_IDX,
12347 WLAN_ML_CTRL_TYPE_BITS, mlo_ie->type);
12348 p_ml_ie += WLAN_ML_CTRL_SIZE;
12349 len_remaining -= WLAN_ML_CTRL_SIZE;
12350
12351 *p_ml_ie++ = mlo_ie->common_info_length;
12352 len_remaining--;
12353
12354 qdf_mem_copy(p_ml_ie, mlo_ie->mld_mac_addr, QDF_MAC_ADDR_SIZE);
12355 p_ml_ie += QDF_MAC_ADDR_SIZE;
12356 len_remaining -= QDF_MAC_ADDR_SIZE;
12357
12358 mlo_ie->num_data = p_ml_ie - mlo_ie->data;
12359
12360 return QDF_STATUS_SUCCESS;
12361 }
12362
12363 QDF_STATUS populate_dot11f_assoc_req_mlo_ie(struct mac_context *mac_ctx,
12364 struct pe_session *pe_session,
12365 tDot11fAssocRequest *frm)
12366 {
12367 uint8_t link;
12368 uint8_t num_sta_prof = 0, total_sta_prof;
12369 struct wlan_mlo_ie *mlo_ie;
12370 struct wlan_mlo_sta_profile *sta_prof;
12371 struct mlo_link_info *link_info = NULL;
12372 struct mlo_partner_info *partner_info;
12373 struct qdf_mac_addr *mld_addr;
12374 struct wlan_mlo_dev_context *mlo_dev_ctx;
12375 tSirMacRateSet b_rates;
12376 tSirMacRateSet e_rates;
12377 uint8_t non_inher_len;
12378 uint8_t non_inher_ie_lists[255];
12379 uint8_t non_inher_ext_len;
12380 uint8_t non_inher_ext_ie_lists[255];
12381 qdf_freq_t chan_freq = 0;
12382 uint8_t chan;
12383 uint8_t op_class;
12384 uint8_t *p_sta_prof;
12385 uint8_t *p_ml_ie;
12386 uint32_t len_consumed;
12387 uint16_t len_remaining, len;
12388 QDF_STATUS status;
12389 struct wlan_objmgr_psoc *psoc;
12390 tDot11fIEnon_inheritance sta_prof_non_inherit;
12391 tDot11fFfCapabilities mlo_cap;
12392 tDot11fIEHTCaps ht_caps;
12393 tDot11fIEVHTCaps vht_caps;
12394 tDot11fIEExtCap ext_cap;
12395 tDot11fIEhe_cap he_caps;
12396 tDot11fIEhe_6ghz_band_cap he_6ghz_band_cap;
12397 tDot11fIEeht_cap eht_caps;
12398 tDot11fIESuppRates supp_rates;
12399 tDot11fIEExtSuppRates ext_supp_rates;
12400 struct wlan_mlo_eml_cap eml_cap = {0};
12401 uint16_t presence_bitmap = 0;
12402 bool is_2g;
12403 uint32_t value = 0;
12404 uint8_t *ppet, cb_mode;
12405 uint8_t *eht_cap_ie = NULL;
12406 bool sta_prof_he_ie = false;
12407
12408 if (!mac_ctx || !pe_session || !frm)
12409 return QDF_STATUS_E_NULL_VALUE;
12410
12411 psoc = wlan_vdev_get_psoc(pe_session->vdev);
12412 if (!psoc) {
12413 pe_err("Invalid psoc");
12414 return QDF_STATUS_E_FAILURE;
12415 }
12416
12417 pe_debug("Populate Assoc req MLO IEs");
12418
12419 mlo_ie = &pe_session->mlo_ie;
12420
12421 mlo_ie->type = 0;
12422 mlo_ie->common_info_length = WLAN_ML_BV_CINFO_LENGTH_SIZE;
12423 mld_addr =
12424 (struct qdf_mac_addr *)wlan_vdev_mlme_get_mldaddr(pe_session->vdev);
12425 qdf_mem_copy(&mlo_ie->mld_mac_addr, mld_addr, QDF_MAC_ADDR_SIZE);
12426 mlo_ie->common_info_length += QDF_MAC_ADDR_SIZE;
12427
12428 mlo_ie->link_id_info_present = 0;
12429 mlo_ie->bss_param_change_cnt_present = 0;
12430 mlo_ie->medium_sync_delay_info_present = 0;
12431 mlo_ie->eml_capab_present = 0;
12432 mlo_ie->mld_capab_and_op_present = 1;
12433 mlo_ie->mld_id_present = 0;
12434 mlo_ie->ext_mld_capab_and_op_present = 0;
12435
12436 if (!pe_session->lim_join_req)
12437 return QDF_STATUS_E_FAILURE;
12438
12439 partner_info = &pe_session->lim_join_req->partner_info;
12440
12441 if (mlo_ie->mld_capab_and_op_present) {
12442 presence_bitmap |= WLAN_ML_BV_CTRL_PBM_MLDCAPANDOP_P;
12443 mlo_ie->common_info_length += WLAN_ML_BV_CINFO_MLDCAPANDOP_SIZE;
12444 mlo_ie->mld_capab_and_op_info.max_simultaneous_link_num =
12445 QDF_MIN(partner_info->num_partner_links,
12446 wlan_mlme_get_sta_mlo_simultaneous_links(psoc));
12447 pe_debug("max_simultaneous_link_num %d",
12448 mlo_ie->mld_capab_and_op_info.max_simultaneous_link_num);
12449 mlo_ie->mld_capab_and_op_info.srs_support = 0;
12450 mlo_ie->mld_capab_and_op_info.tid_link_map_supported =
12451 wlan_mlme_get_t2lm_negotiation_supported(mac_ctx->psoc);
12452 mlo_ie->mld_capab_and_op_info.str_freq_separation = 0;
12453 mlo_ie->mld_capab_and_op_info.aar_support = 0;
12454 }
12455
12456 /* Check if STA supports EMLSR and vendor command prefers EMLSR mode */
12457 if (wlan_vdev_mlme_cap_get(pe_session->vdev, WLAN_VDEV_C_EMLSR_CAP)) {
12458 wlan_mlme_get_eml_params(psoc, &eml_cap);
12459 mlo_ie->eml_capab_present = 1;
12460 presence_bitmap |= WLAN_ML_BV_CTRL_PBM_EMLCAP_P;
12461 mlo_ie->common_info_length += WLAN_ML_BV_CINFO_EMLCAP_SIZE;
12462 mlo_ie->eml_capabilities_info.emlsr_support =
12463 eml_cap.emlsr_supp;
12464 mlo_ie->eml_capabilities_info.emlmr_support =
12465 eml_cap.emlmr_supp;
12466 mlo_ie->eml_capabilities_info.transition_timeout = 0;
12467 mlo_ie->eml_capabilities_info.emlsr_padding_delay =
12468 eml_cap.emlsr_pad_delay;
12469 mlo_ie->eml_capabilities_info.emlsr_transition_delay =
12470 eml_cap.emlsr_trans_delay;
12471 }
12472
12473 p_ml_ie = mlo_ie->data;
12474 len_remaining = sizeof(mlo_ie->data);
12475
12476 /* element ID, length and extension element ID */
12477 *p_ml_ie++ = WLAN_ELEMID_EXTN_ELEM;
12478 len_remaining--;
12479 /* length will set later */
12480 *p_ml_ie++ = 0;
12481 len_remaining--;
12482 *p_ml_ie++ = WLAN_EXTN_ELEMID_MULTI_LINK;
12483 len_remaining--;
12484
12485 QDF_SET_BITS(*(uint16_t *)p_ml_ie, WLAN_ML_CTRL_TYPE_IDX,
12486 WLAN_ML_CTRL_TYPE_BITS, mlo_ie->type);
12487 QDF_SET_BITS(*(uint16_t *)p_ml_ie, WLAN_ML_CTRL_PBM_IDX,
12488 WLAN_ML_CTRL_PBM_BITS, presence_bitmap);
12489 p_ml_ie += WLAN_ML_CTRL_SIZE;
12490 len_remaining -= WLAN_ML_CTRL_SIZE;
12491
12492 *p_ml_ie++ = mlo_ie->common_info_length;
12493 len_remaining--;
12494
12495 qdf_mem_copy(p_ml_ie, mld_addr, QDF_MAC_ADDR_SIZE);
12496 p_ml_ie += QDF_MAC_ADDR_SIZE;
12497 len_remaining -= QDF_MAC_ADDR_SIZE;
12498
12499 if (mlo_ie->eml_capab_present) {
12500 QDF_SET_BITS(*(uint16_t *)p_ml_ie,
12501 WLAN_ML_BV_CINFO_EMLCAP_EMLSRSUPPORT_IDX,
12502 WLAN_ML_BV_CINFO_EMLCAP_EMLSRSUPPORT_BITS,
12503 mlo_ie->eml_capabilities_info.emlsr_support);
12504 QDF_SET_BITS(*(uint16_t *)p_ml_ie,
12505 WLAN_ML_BV_CINFO_EMLCAP_EMLSR_PADDINGDELAY_IDX,
12506 WLAN_ML_BV_CINFO_EMLCAP_EMLSR_PADDINGDELAY_BITS,
12507 mlo_ie->eml_capabilities_info.emlsr_padding_delay);
12508 QDF_SET_BITS(*(uint16_t *)p_ml_ie,
12509 WLAN_ML_BV_CINFO_EMLCAP_EMLSRTRANSDELAY_IDX,
12510 WLAN_ML_BV_CINFO_EMLCAP_EMLSRTRANSDELAY_BITS,
12511 mlo_ie->eml_capabilities_info.emlsr_transition_delay);
12512 QDF_SET_BITS(*(uint16_t *)p_ml_ie,
12513 WLAN_ML_BV_CINFO_EMLCAP_EMLMRSUPPORT_IDX,
12514 WLAN_ML_BV_CINFO_EMLCAP_EMLMRSUPPORT_BITS,
12515 mlo_ie->eml_capabilities_info.emlmr_support);
12516 QDF_SET_BITS(*(uint16_t *)p_ml_ie,
12517 WLAN_ML_BV_CINFO_EMLCAP_EMLMRDELAY_IDX,
12518 WLAN_ML_BV_CINFO_EMLCAP_EMLMRDELAY_BITS,
12519 mlo_ie->eml_capabilities_info.emlmr_delay);
12520 QDF_SET_BITS(*(uint16_t *)p_ml_ie,
12521 WLAN_ML_BV_CINFO_EMLCAP_TRANSTIMEOUT_IDX,
12522 WLAN_ML_BV_CINFO_EMLCAP_TRANSTIMEOUT_BITS,
12523 mlo_ie->eml_capabilities_info.transition_timeout);
12524
12525 p_ml_ie += WLAN_ML_BV_CINFO_EMLCAP_SIZE;
12526 len_remaining -= WLAN_ML_BV_CINFO_EMLCAP_SIZE;
12527 }
12528
12529 pe_debug("EMLSR support: %d, padding delay: %d, transition delay: %d",
12530 mlo_ie->eml_capabilities_info.emlsr_support,
12531 mlo_ie->eml_capabilities_info.emlsr_padding_delay,
12532 mlo_ie->eml_capabilities_info.emlsr_transition_delay);
12533
12534 if (mlo_ie->mld_capab_and_op_present) {
12535 QDF_SET_BITS(*(uint16_t *)p_ml_ie,
12536 WLAN_ML_BV_CINFO_MLDCAPANDOP_MAXSIMULLINKS_IDX,
12537 WLAN_ML_BV_CINFO_MLDCAPANDOP_MAXSIMULLINKS_BITS,
12538 mlo_ie->mld_capab_and_op_info.max_simultaneous_link_num);
12539 QDF_SET_BITS(*(uint16_t *)p_ml_ie,
12540 WLAN_ML_BV_CINFO_MLDCAPANDOP_TIDTOLINKMAPNEGSUPPORT_IDX,
12541 WLAN_ML_BV_CINFO_MLDCAPANDOP_TIDTOLINKMAPNEGSUPPORT_BITS,
12542 mlo_ie->mld_capab_and_op_info.tid_link_map_supported);
12543 p_ml_ie += WLAN_ML_BV_CINFO_MLDCAPANDOP_SIZE;
12544 len_remaining -= WLAN_ML_BV_CINFO_MLDCAPANDOP_SIZE;
12545 }
12546
12547 mlo_ie->num_data = p_ml_ie - mlo_ie->data;
12548
12549 /* find out number of links from bcn or prb rsp */
12550 total_sta_prof = partner_info->num_partner_links;
12551
12552 mlo_dev_ctx = pe_session->vdev->mlo_dev_ctx;
12553 if (!mlo_dev_ctx) {
12554 pe_err("mlo_dev_ctx is null");
12555 return QDF_STATUS_E_NULL_VALUE;
12556 }
12557
12558 for (link = 0;
12559 link < total_sta_prof && total_sta_prof != num_sta_prof;
12560 link++) {
12561 struct mlo_link_info *ml_link_info;
12562
12563 if (!partner_info->num_partner_links)
12564 continue;
12565
12566 sta_prof = &mlo_ie->sta_profile[num_sta_prof];
12567 link_info = &partner_info->partner_link_info[link];
12568 p_sta_prof = sta_prof->data;
12569 len_remaining = sizeof(sta_prof->data);
12570 ml_link_info =
12571 mlo_mgr_get_ap_link_by_link_id(
12572 pe_session->vdev->mlo_dev_ctx,
12573 link_info->link_id);
12574 if (!ml_link_info)
12575 continue;
12576
12577 /* subelement ID 0, length(sta_prof->num_data - 2) */
12578 *p_sta_prof++ = WLAN_ML_LINFO_SUBELEMID_PERSTAPROFILE;
12579 *p_sta_prof++ = 0;
12580 len_remaining -= 2;
12581
12582 qdf_mem_zero(non_inher_ie_lists, sizeof(non_inher_ie_lists));
12583 qdf_mem_zero(non_inher_ext_ie_lists,
12584 sizeof(non_inher_ext_ie_lists));
12585 non_inher_len = 0;
12586 non_inher_ext_len = 0;
12587
12588 QDF_SET_BITS(*(uint16_t *)(sta_prof->data + MIN_IE_LEN),
12589 WLAN_ML_BV_LINFO_PERSTAPROF_STACTRL_LINKID_IDX,
12590 WLAN_ML_BV_LINFO_PERSTAPROF_STACTRL_LINKID_BITS,
12591 link_info->link_id);
12592 QDF_SET_BITS(*(uint16_t *)(sta_prof->data + MIN_IE_LEN),
12593 WLAN_ML_BV_LINFO_PERSTAPROF_STACTRL_CMPLTPROF_IDX,
12594 WLAN_ML_BV_LINFO_PERSTAPROF_STACTRL_CMPLTPROF_BITS,
12595 1);
12596 QDF_SET_BITS(*(uint16_t *)(sta_prof->data + MIN_IE_LEN),
12597 WLAN_ML_BV_LINFO_PERSTAPROF_STACTRL_MACADDRP_IDX,
12598 WLAN_ML_BV_LINFO_PERSTAPROF_STACTRL_MACADDRP_BITS,
12599 1);
12600 /* 2 Bytes for sta control field*/
12601 p_sta_prof += 2;
12602 len_remaining -= 2;
12603
12604 /* 1 Bytes for STA Info Length + 6 bytes for STA MAC Address*/
12605 len = WLAN_ML_BV_LINFO_PERSTAPROF_STAINFO_LENGTH_SIZE +
12606 QDF_MAC_ADDR_SIZE;
12607 *p_sta_prof = len;
12608
12609 /* 1 Byte for STA Info Length */
12610 p_sta_prof += WLAN_ML_BV_LINFO_PERSTAPROF_STAINFO_LENGTH_SIZE;
12611 len_remaining -=
12612 WLAN_ML_BV_LINFO_PERSTAPROF_STAINFO_LENGTH_SIZE;
12613
12614 /* Copying sta mac address in sta info field */
12615 qdf_mem_copy(p_sta_prof, ml_link_info->link_addr.bytes,
12616 QDF_MAC_ADDR_SIZE);
12617 p_sta_prof += QDF_MAC_ADDR_SIZE;
12618 len_remaining -= QDF_MAC_ADDR_SIZE;
12619
12620 pe_debug("Sta profile mac: " QDF_MAC_ADDR_FMT,
12621 QDF_MAC_ADDR_REF(ml_link_info->link_addr.bytes));
12622
12623 /* TBD : populate beacon_interval, dtim_info
12624 * nstr_link_pair_present, nstr_bitmap_size
12625 */
12626 QDF_SET_BITS(*(uint16_t *)(sta_prof->data + MIN_IE_LEN),
12627 WLAN_ML_BV_LINFO_PERSTAPROF_STACTRL_BCNINTP_IDX,
12628 WLAN_ML_BV_LINFO_PERSTAPROF_STACTRL_BCNINTP_BITS,
12629 0);
12630 QDF_SET_BITS(*(uint16_t *)(sta_prof->data + MIN_IE_LEN),
12631 WLAN_ML_BV_LINFO_PERSTAPROF_STACTRL_DTIMINFOP_IDX,
12632 WLAN_ML_BV_LINFO_PERSTAPROF_STACTRL_DTIMINFOP_BITS,
12633 0);
12634 QDF_SET_BITS(
12635 *(uint16_t *)(sta_prof->data + MIN_IE_LEN),
12636 WLAN_ML_BV_LINFO_PERSTAPROF_STACTRL_NSTRLINKPRP_IDX,
12637 WLAN_ML_BV_LINFO_PERSTAPROF_STACTRL_NSTRLINKPRP_BITS,
12638 0);
12639 QDF_SET_BITS(*(uint16_t *)(sta_prof->data + MIN_IE_LEN),
12640 WLAN_ML_BV_LINFO_PERSTAPROF_STACTRL_NSTRBMSZ_IDX,
12641 WLAN_ML_BV_LINFO_PERSTAPROF_STACTRL_NSTRBMSZ_BITS,
12642 0);
12643
12644 qdf_mem_zero(&mlo_cap, sizeof(tDot11fFfCapabilities));
12645 qdf_mem_zero(&b_rates, sizeof(b_rates));
12646 qdf_mem_zero(&e_rates, sizeof(e_rates));
12647 qdf_mem_zero(&supp_rates, sizeof(supp_rates));
12648 qdf_mem_zero(&ext_supp_rates, sizeof(ext_supp_rates));
12649 qdf_mem_zero(&sta_prof_non_inherit,
12650 sizeof(tDot11fIEnon_inheritance));
12651 qdf_mem_zero(&ht_caps, sizeof(tDot11fIEHTCaps));
12652 qdf_mem_zero(&ext_cap, sizeof(tDot11fIEExtCap));
12653 qdf_mem_zero(&vht_caps, sizeof(tDot11fIEVHTCaps));
12654 qdf_mem_zero(&he_caps, sizeof(tDot11fIEhe_cap));
12655 qdf_mem_zero(&he_6ghz_band_cap,
12656 sizeof(tDot11fIEhe_6ghz_band_cap));
12657 qdf_mem_zero(&eht_caps, sizeof(tDot11fIEeht_cap));
12658
12659 // TBD: mlo_capab, supported oper classes
12660 populate_dot11f_mlo_partner_sta_cap(mac_ctx, &mlo_cap);
12661 dot11f_pack_ff_capabilities(mac_ctx, &mlo_cap, p_sta_prof);
12662 p_sta_prof += WLAN_CAPABILITYINFO_LEN;
12663 len_remaining -= WLAN_CAPABILITYINFO_LEN;
12664
12665 wlan_get_chan_by_bssid_from_rnr(pe_session->vdev,
12666 pe_session->cm_id,
12667 &link_info->link_addr,
12668 &chan, &op_class);
12669 if (!chan)
12670 wlan_get_chan_by_link_id_from_rnr(pe_session->vdev,
12671 pe_session->cm_id,
12672 link_info->link_id,
12673 &chan, &op_class);
12674 if (!chan) {
12675 pe_err("Invalid parter link id %d link mac: " QDF_MAC_ADDR_FMT,
12676 link_info->link_id,
12677 QDF_MAC_ADDR_REF(link_info->link_addr.bytes));
12678 continue;
12679 }
12680 chan_freq = wlan_reg_chan_opclass_to_freq_auto(chan, op_class,
12681 false);
12682 is_2g = WLAN_REG_IS_24GHZ_CH_FREQ(chan_freq);
12683 if (is_2g) {
12684 wlan_populate_basic_rates(&b_rates, false, true);
12685 wlan_populate_basic_rates(&e_rates, true, false);
12686 } else {
12687 wlan_populate_basic_rates(&b_rates, true, true);
12688 }
12689
12690 if ((b_rates.numRates && frm->SuppRates.present &&
12691 (qdf_mem_cmp(frm->SuppRates.rates, b_rates.rate,
12692 b_rates.numRates))) || (b_rates.numRates &&
12693 !frm->SuppRates.present)) {
12694 supp_rates.num_rates = b_rates.numRates;
12695 qdf_mem_copy(supp_rates.rates, b_rates.rate,
12696 b_rates.numRates);
12697 supp_rates.present = 1;
12698 len_consumed = 0;
12699 dot11f_pack_ie_supp_rates(mac_ctx, &supp_rates,
12700 p_sta_prof, len_remaining,
12701 &len_consumed);
12702 p_sta_prof += len_consumed;
12703 len_remaining -= len_consumed;
12704 } else if (frm->SuppRates.present && !b_rates.numRates) {
12705 non_inher_ie_lists[non_inher_len++] =
12706 DOT11F_EID_SUPPRATES;
12707 }
12708
12709 if (!WLAN_REG_IS_6GHZ_CHAN_FREQ(chan_freq)) {
12710 cb_mode = lim_get_cb_mode_for_freq(mac_ctx, pe_session,
12711 chan_freq);
12712 populate_dot11f_ht_caps(mac_ctx, NULL, &ht_caps);
12713 if (!cb_mode) {
12714 ht_caps.supportedChannelWidthSet = 0;
12715 ht_caps.shortGI40MHz = 0;
12716 } else {
12717 ht_caps.supportedChannelWidthSet = 1;
12718 ht_caps.shortGI40MHz = 1;
12719 }
12720 }
12721
12722 if ((ht_caps.present && frm->HTCaps.present &&
12723 qdf_mem_cmp(&ht_caps, &frm->HTCaps, sizeof(ht_caps))) ||
12724 (ht_caps.present && !frm->HTCaps.present)) {
12725 len_consumed = 0;
12726 dot11f_pack_ie_ht_caps(mac_ctx, &ht_caps, p_sta_prof,
12727 len_remaining, &len_consumed);
12728 p_sta_prof += len_consumed;
12729 len_remaining -= len_consumed;
12730 } else if (frm->HTCaps.present && !ht_caps.present) {
12731 non_inher_ie_lists[non_inher_len++] = DOT11F_EID_HTCAPS;
12732 }
12733
12734 if ((e_rates.numRates && frm->ExtSuppRates.present &&
12735 (qdf_mem_cmp(frm->ExtSuppRates.rates, e_rates.rate,
12736 e_rates.numRates))) || (e_rates.numRates &&
12737 !frm->ExtSuppRates.present)) {
12738 ext_supp_rates.num_rates = e_rates.numRates;
12739 qdf_mem_copy(ext_supp_rates.rates, e_rates.rate,
12740 e_rates.numRates);
12741 ext_supp_rates.present = 1;
12742 len_consumed = 0;
12743 dot11f_pack_ie_ext_supp_rates(mac_ctx, &ext_supp_rates,
12744 p_sta_prof,
12745 len_remaining,
12746 &len_consumed);
12747 p_sta_prof += len_consumed;
12748 len_remaining -= len_consumed;
12749 } else if (frm->ExtSuppRates.present) {
12750 non_inher_ie_lists[non_inher_len++] =
12751 DOT11F_EID_EXTSUPPRATES;
12752 }
12753
12754 populate_dot11f_ext_cap(mac_ctx, true, &ext_cap, NULL);
12755 populate_dot11f_btm_extended_caps(mac_ctx, pe_session,
12756 &ext_cap);
12757 if ((ext_cap.present && frm->ExtCap.present &&
12758 qdf_mem_cmp(&ext_cap, &frm->ExtCap, sizeof(ext_cap))) ||
12759 (ext_cap.present && !frm->ExtCap.present)) {
12760 len_consumed = 0;
12761 dot11f_pack_ie_ext_cap(mac_ctx, &ext_cap, p_sta_prof,
12762 len_remaining, &len_consumed);
12763 p_sta_prof += len_consumed;
12764 len_remaining -= len_consumed;
12765 } else if (ext_cap.present && !frm->ExtCap.present) {
12766 non_inher_ie_lists[non_inher_len++] = DOT11F_EID_EXTCAP;
12767 }
12768
12769 if (!WLAN_REG_IS_6GHZ_CHAN_FREQ(chan_freq))
12770 populate_dot11f_vht_caps(mac_ctx, NULL, &vht_caps);
12771 if ((vht_caps.present && frm->VHTCaps.present &&
12772 qdf_mem_cmp(&vht_caps, &frm->VHTCaps, sizeof(vht_caps))) ||
12773 (vht_caps.present && !frm->VHTCaps.present)) {
12774 len_consumed = 0;
12775 dot11f_pack_ie_vht_caps(mac_ctx, &vht_caps, p_sta_prof,
12776 len_remaining, &len_consumed);
12777 p_sta_prof += len_consumed;
12778 len_remaining -= len_consumed;
12779 } else if (frm->VHTCaps.present && !vht_caps.present) {
12780 non_inher_ie_lists[non_inher_len++] =
12781 DOT11F_EID_VHTCAPS;
12782 }
12783
12784 populate_dot11f_he_caps_by_band(mac_ctx, is_2g, &he_caps,
12785 pe_session);
12786 if (he_caps.ppet_present) {
12787 value = WNI_CFG_HE_PPET_LEN;
12788 if (!is_2g)
12789 qdf_mem_copy(he_caps.ppet.ppe_threshold.ppe_th,
12790 mac_ctx->mlme_cfg->he_caps.he_ppet_5g,
12791 value);
12792 else
12793 qdf_mem_copy(he_caps.ppet.ppe_threshold.ppe_th,
12794 mac_ctx->mlme_cfg->he_caps.he_ppet_2g,
12795 value);
12796
12797 ppet = he_caps.ppet.ppe_threshold.ppe_th;
12798 he_caps.ppet.ppe_threshold.num_ppe_th =
12799 lim_truncate_ppet(ppet, value);
12800 } else {
12801 he_caps.ppet.ppe_threshold.num_ppe_th = 0;
12802 }
12803 if ((he_caps.present && frm->he_cap.present &&
12804 qdf_mem_cmp(&he_caps, &frm->he_cap, sizeof(he_caps))) ||
12805 (he_caps.present && !frm->he_cap.present)) {
12806 len_consumed = 0;
12807 dot11f_pack_ie_he_cap(mac_ctx, &he_caps, p_sta_prof,
12808 len_remaining, &len_consumed);
12809 p_sta_prof += len_consumed;
12810 len_remaining -= len_consumed;
12811 sta_prof_he_ie = true;
12812 } else if (frm->he_cap.present && !he_caps.present) {
12813 non_inher_ext_ie_lists[non_inher_ext_len++] =
12814 WLAN_EXTN_ELEMID_HECAP;
12815 }
12816
12817 if (WLAN_REG_IS_6GHZ_CHAN_FREQ(chan_freq))
12818 populate_dot11f_he_6ghz_cap(mac_ctx, NULL,
12819 &he_6ghz_band_cap);
12820 if ((he_6ghz_band_cap.present &&
12821 frm->he_6ghz_band_cap.present &&
12822 qdf_mem_cmp(&he_6ghz_band_cap, &frm->he_6ghz_band_cap,
12823 sizeof(he_6ghz_band_cap))) ||
12824 (he_6ghz_band_cap.present &&
12825 !frm->he_6ghz_band_cap.present)) {
12826 len_consumed = 0;
12827 dot11f_pack_ie_he_6ghz_band_cap(
12828 mac_ctx, &he_6ghz_band_cap, p_sta_prof,
12829 len_remaining, &len_consumed);
12830 p_sta_prof += len_consumed;
12831 len_remaining -= len_consumed;
12832 } else if (frm->he_6ghz_band_cap.present &&
12833 !he_6ghz_band_cap.present) {
12834 non_inher_ext_ie_lists[non_inher_ext_len++] =
12835 WLAN_EXTN_ELEMID_HE_6G_CAP;
12836 }
12837 populate_dot11f_eht_caps_by_band(mac_ctx, is_2g, &eht_caps,
12838 NULL);
12839 if (!WLAN_REG_IS_6GHZ_CHAN_FREQ(chan_freq))
12840 eht_caps.support_320mhz_6ghz = 0;
12841
12842 if ((eht_caps.present && frm->eht_cap.present &&
12843 qdf_mem_cmp(&eht_caps, &frm->eht_cap, sizeof(eht_caps))) ||
12844 (eht_caps.present && !frm->eht_cap.present) ||
12845 sta_prof_he_ie) {
12846 eht_cap_ie = qdf_mem_malloc(WLAN_MAX_IE_LEN + 2);
12847 if (eht_cap_ie) {
12848 len_consumed = 0;
12849 lim_ieee80211_pack_ehtcap(eht_cap_ie, eht_caps,
12850 he_caps, is_2g);
12851 len_consumed = eht_cap_ie[1] + 2;
12852
12853 qdf_mem_copy(p_sta_prof, eht_cap_ie,
12854 len_consumed);
12855 qdf_mem_free(eht_cap_ie);
12856 p_sta_prof += len_consumed;
12857 len_remaining -= len_consumed;
12858 } else {
12859 pe_err("malloc failed for eht_cap_ie");
12860 }
12861 } else if (frm->eht_cap.present && !eht_caps.present) {
12862 pe_debug("eht non inher");
12863 non_inher_ext_ie_lists[non_inher_ext_len++] =
12864 WLAN_EXTN_ELEMID_EHTCAP;
12865 } else {
12866 pe_debug("eht ie not included");
12867 }
12868 if (frm->OperatingMode.present) {
12869 pe_info("opmode in assoc req, add to non inher list");
12870 non_inher_ie_lists[non_inher_len++] =
12871 DOT11F_EID_OPERATINGMODE;
12872 }
12873
12874 populate_dot11f_non_inheritance(
12875 mac_ctx, &sta_prof_non_inherit,
12876 non_inher_ie_lists, non_inher_ext_ie_lists,
12877 non_inher_len, non_inher_ext_len);
12878 if (sta_prof_non_inherit.present) {
12879 len_consumed = 0;
12880 dot11f_pack_ie_non_inheritance(
12881 mac_ctx, &sta_prof_non_inherit,
12882 p_sta_prof, len_remaining, &len_consumed);
12883 p_sta_prof += len_consumed;
12884 len_remaining -= len_consumed;
12885 }
12886 sta_prof->num_data = p_sta_prof - sta_prof->data;
12887 if (sta_prof->num_data > WLAN_MAX_IE_LEN + MIN_IE_LEN) {
12888 sta_prof->data[TAG_LEN_POS] = WLAN_MAX_IE_LEN;
12889 status =
12890 lim_add_frag_ie_for_sta_profile(sta_prof->data,
12891 &sta_prof->num_data);
12892 if (status != QDF_STATUS_SUCCESS) {
12893 pe_debug("STA profile frag error");
12894 sta_prof->num_data =
12895 WLAN_MAX_IE_LEN + MIN_IE_LEN;
12896 }
12897 } else {
12898 sta_prof->data[TAG_LEN_POS] =
12899 sta_prof->num_data - MIN_IE_LEN;
12900 }
12901 num_sta_prof++;
12902 }
12903 mlo_ie->num_sta_profile = num_sta_prof;
12904
12905 return QDF_STATUS_SUCCESS;
12906 }
12907
12908 QDF_STATUS populate_dot11f_mlo_ie(struct mac_context *mac_ctx,
12909 struct wlan_objmgr_vdev *vdev,
12910 struct wlan_mlo_ie *mlo_ie)
12911 {
12912 struct qdf_mac_addr *mld_addr;
12913 uint8_t *p_ml_ie;
12914 uint16_t len_remaining;
12915 struct wlan_objmgr_psoc *psoc;
12916 struct wlan_mlo_eml_cap eml_cap = {0};
12917 uint16_t presence_bitmap = 0;
12918 bool emlsr_cap, emlsr_enabled = false;
12919
12920 if (!mac_ctx || !mlo_ie)
12921 return QDF_STATUS_E_NULL_VALUE;
12922
12923 psoc = wlan_vdev_get_psoc(vdev);
12924 if (!psoc) {
12925 pe_err("Invalid psoc");
12926 return QDF_STATUS_E_FAILURE;
12927 }
12928
12929 mlo_ie->type = 0;
12930 mlo_ie->common_info_length = WLAN_ML_BV_CINFO_LENGTH_SIZE;
12931 mld_addr =
12932 (struct qdf_mac_addr *)wlan_vdev_mlme_get_mldaddr(vdev);
12933 qdf_mem_copy(&mlo_ie->mld_mac_addr, mld_addr, QDF_MAC_ADDR_SIZE);
12934 mlo_ie->common_info_length += QDF_MAC_ADDR_SIZE;
12935
12936 mlo_ie->link_id_info_present = 0;
12937 mlo_ie->bss_param_change_cnt_present = 0;
12938 mlo_ie->medium_sync_delay_info_present = 0;
12939 mlo_ie->eml_capab_present = 0;
12940 mlo_ie->mld_capab_and_op_present = 1;
12941 mlo_ie->mld_id_present = 0;
12942 mlo_ie->ext_mld_capab_and_op_present = 0;
12943
12944 if (mlo_ie->mld_capab_and_op_present) {
12945 presence_bitmap |= WLAN_ML_BV_CTRL_PBM_MLDCAPANDOP_P;
12946 mlo_ie->common_info_length += WLAN_ML_BV_CINFO_MLDCAPANDOP_SIZE;
12947 mlo_ie->mld_capab_and_op_info.max_simultaneous_link_num =
12948 wlan_mlme_get_sta_mlo_simultaneous_links(psoc);
12949 mlo_ie->mld_capab_and_op_info.srs_support = 0;
12950 mlo_ie->mld_capab_and_op_info.tid_link_map_supported =
12951 wlan_mlme_get_t2lm_negotiation_supported(mac_ctx->psoc);
12952 mlo_ie->mld_capab_and_op_info.str_freq_separation = 0;
12953 mlo_ie->mld_capab_and_op_info.aar_support = 0;
12954 }
12955
12956 /* Check if HW supports eMLSR mode */
12957 emlsr_cap = policy_mgr_is_hw_emlsr_capable(mac_ctx->psoc);
12958
12959 /* Check if vendor command chooses eMLSR mode */
12960 wlan_mlme_get_emlsr_mode_enabled(mac_ctx->psoc, &emlsr_enabled);
12961
12962 /* Check if STA supports EMLSR and vendor command prefers EMLSR mode */
12963 if (emlsr_cap && emlsr_enabled) {
12964 wlan_mlme_get_eml_params(psoc, &eml_cap);
12965 mlo_ie->eml_capab_present = 1;
12966 presence_bitmap |= WLAN_ML_BV_CTRL_PBM_EMLCAP_P;
12967 mlo_ie->common_info_length += WLAN_ML_BV_CINFO_EMLCAP_SIZE;
12968 mlo_ie->eml_capabilities_info.emlsr_support =
12969 eml_cap.emlsr_supp;
12970 mlo_ie->eml_capabilities_info.emlmr_support =
12971 eml_cap.emlmr_supp;
12972 mlo_ie->eml_capabilities_info.transition_timeout = 0;
12973 mlo_ie->eml_capabilities_info.emlsr_padding_delay =
12974 eml_cap.emlsr_pad_delay;
12975 mlo_ie->eml_capabilities_info.emlsr_transition_delay =
12976 eml_cap.emlsr_trans_delay;
12977 }
12978
12979 p_ml_ie = mlo_ie->data;
12980 len_remaining = sizeof(mlo_ie->data);
12981
12982 /* element ID, length and extension element ID */
12983 *p_ml_ie++ = WLAN_ELEMID_EXTN_ELEM;
12984 len_remaining--;
12985 /* length will set later */
12986 *p_ml_ie++ = 0;
12987 len_remaining--;
12988 *p_ml_ie++ = WLAN_EXTN_ELEMID_MULTI_LINK;
12989 len_remaining--;
12990
12991 QDF_SET_BITS(*(uint16_t *)p_ml_ie, WLAN_ML_CTRL_TYPE_IDX,
12992 WLAN_ML_CTRL_TYPE_BITS, mlo_ie->type);
12993 QDF_SET_BITS(*(uint16_t *)p_ml_ie, WLAN_ML_CTRL_PBM_IDX,
12994 WLAN_ML_CTRL_PBM_BITS, presence_bitmap);
12995 p_ml_ie += WLAN_ML_CTRL_SIZE;
12996 len_remaining -= WLAN_ML_CTRL_SIZE;
12997
12998 *p_ml_ie++ = mlo_ie->common_info_length;
12999 len_remaining--;
13000
13001 qdf_mem_copy(p_ml_ie, mld_addr, QDF_MAC_ADDR_SIZE);
13002 p_ml_ie += QDF_MAC_ADDR_SIZE;
13003 len_remaining -= QDF_MAC_ADDR_SIZE;
13004
13005 if (mlo_ie->eml_capab_present) {
13006 QDF_SET_BITS(*(uint16_t *)p_ml_ie,
13007 WLAN_ML_BV_CINFO_EMLCAP_EMLSRSUPPORT_IDX,
13008 WLAN_ML_BV_CINFO_EMLCAP_EMLSRSUPPORT_BITS,
13009 mlo_ie->eml_capabilities_info.emlsr_support);
13010 QDF_SET_BITS(*(uint16_t *)p_ml_ie,
13011 WLAN_ML_BV_CINFO_EMLCAP_EMLSR_PADDINGDELAY_IDX,
13012 WLAN_ML_BV_CINFO_EMLCAP_EMLSR_PADDINGDELAY_BITS,
13013 mlo_ie->eml_capabilities_info.emlsr_padding_delay);
13014 QDF_SET_BITS(*(uint16_t *)p_ml_ie,
13015 WLAN_ML_BV_CINFO_EMLCAP_EMLSRTRANSDELAY_IDX,
13016 WLAN_ML_BV_CINFO_EMLCAP_EMLSRTRANSDELAY_BITS,
13017 mlo_ie->eml_capabilities_info.emlsr_transition_delay);
13018 QDF_SET_BITS(*(uint16_t *)p_ml_ie,
13019 WLAN_ML_BV_CINFO_EMLCAP_EMLMRSUPPORT_IDX,
13020 WLAN_ML_BV_CINFO_EMLCAP_EMLMRSUPPORT_BITS,
13021 mlo_ie->eml_capabilities_info.emlmr_support);
13022 QDF_SET_BITS(*(uint16_t *)p_ml_ie,
13023 WLAN_ML_BV_CINFO_EMLCAP_EMLMRDELAY_IDX,
13024 WLAN_ML_BV_CINFO_EMLCAP_EMLMRDELAY_BITS,
13025 mlo_ie->eml_capabilities_info.emlmr_delay);
13026 QDF_SET_BITS(*(uint16_t *)p_ml_ie,
13027 WLAN_ML_BV_CINFO_EMLCAP_TRANSTIMEOUT_IDX,
13028 WLAN_ML_BV_CINFO_EMLCAP_TRANSTIMEOUT_BITS,
13029 mlo_ie->eml_capabilities_info.transition_timeout);
13030
13031 p_ml_ie += WLAN_ML_BV_CINFO_EMLCAP_SIZE;
13032 len_remaining -= WLAN_ML_BV_CINFO_EMLCAP_SIZE;
13033 }
13034
13035 if (mlo_ie->mld_capab_and_op_present) {
13036 QDF_SET_BITS(*(uint16_t *)p_ml_ie,
13037 WLAN_ML_BV_CINFO_MLDCAPANDOP_MAXSIMULLINKS_IDX,
13038 WLAN_ML_BV_CINFO_MLDCAPANDOP_MAXSIMULLINKS_BITS,
13039 mlo_ie->mld_capab_and_op_info.max_simultaneous_link_num);
13040 QDF_SET_BITS(*(uint16_t *)p_ml_ie,
13041 WLAN_ML_BV_CINFO_MLDCAPANDOP_TIDTOLINKMAPNEGSUPPORT_IDX,
13042 WLAN_ML_BV_CINFO_MLDCAPANDOP_TIDTOLINKMAPNEGSUPPORT_BITS,
13043 mlo_ie->mld_capab_and_op_info.tid_link_map_supported);
13044 p_ml_ie += WLAN_ML_BV_CINFO_MLDCAPANDOP_SIZE;
13045 len_remaining -= WLAN_ML_BV_CINFO_MLDCAPANDOP_SIZE;
13046 }
13047
13048 mlo_ie->num_data = p_ml_ie - mlo_ie->data;
13049 pe_debug("VDEV %d ML-IE common info len %d eMLSR support %d pad_delay %d, trans_delay %d",
13050 wlan_vdev_get_id(vdev), mlo_ie->num_data,
13051 mlo_ie->eml_capabilities_info.emlsr_support,
13052 mlo_ie->eml_capabilities_info.emlsr_padding_delay,
13053 mlo_ie->eml_capabilities_info.emlsr_transition_delay);
13054
13055 return QDF_STATUS_SUCCESS;
13056 }
13057 #endif
13058
13059 QDF_STATUS
13060 populate_dot11f_rnr_tbtt_info(struct mac_context *mac_ctx,
13061 struct pe_session *pe_session,
13062 struct pe_session *rnr_session,
13063 tDot11fIEreduced_neighbor_report *dot11f,
13064 uint8_t tbtt_len)
13065 {
13066 uint8_t reg_class;
13067 uint8_t ch_offset;
13068 uint8_t psd_power;
13069
13070 dot11f->present = 1;
13071 dot11f->tbtt_type = 0;
13072 if (rnr_session->ch_width == CH_WIDTH_80MHZ) {
13073 ch_offset = BW80;
13074 } else {
13075 switch (rnr_session->htSecondaryChannelOffset) {
13076 case PHY_DOUBLE_CHANNEL_HIGH_PRIMARY:
13077 ch_offset = BW40_HIGH_PRIMARY;
13078 break;
13079 case PHY_DOUBLE_CHANNEL_LOW_PRIMARY:
13080 ch_offset = BW40_LOW_PRIMARY;
13081 break;
13082 default:
13083 ch_offset = BW20;
13084 break;
13085 }
13086 }
13087
13088 reg_class = lim_op_class_from_bandwidth(mac_ctx,
13089 rnr_session->curr_op_freq,
13090 rnr_session->ch_width,
13091 ch_offset);
13092
13093 psd_power = wlan_mlme_get_sap_psd_for_20mhz(rnr_session->vdev);
13094
13095 dot11f->op_class = reg_class;
13096 dot11f->channel_num = wlan_reg_freq_to_chan(mac_ctx->pdev,
13097 rnr_session->curr_op_freq);
13098 dot11f->tbtt_info_count = 0;
13099 dot11f->tbtt_info_len = tbtt_len;
13100
13101 switch (tbtt_len) {
13102 case 7:
13103 dot11f->tbtt_info.tbtt_info_7.tbtt_offset =
13104 WLAN_RNR_TBTT_OFFSET_INVALID;
13105 qdf_mem_copy(dot11f->tbtt_info.tbtt_info_7.bssid,
13106 rnr_session->self_mac_addr, sizeof(tSirMacAddr));
13107 break;
13108 case 9:
13109 dot11f->tbtt_info.tbtt_info_9.tbtt_offset =
13110 WLAN_RNR_TBTT_OFFSET_INVALID;
13111 qdf_mem_copy(dot11f->tbtt_info.tbtt_info_9.bssid,
13112 rnr_session->self_mac_addr, sizeof(tSirMacAddr));
13113 dot11f->tbtt_info.tbtt_info_9.bss_params =
13114 WLAN_RNR_BSS_PARAM_COLOCATED_AP;
13115 if (!lim_cmp_ssid(&rnr_session->ssId, pe_session))
13116 dot11f->tbtt_info.tbtt_info_9.bss_params |=
13117 WLAN_RNR_BSS_PARAM_SAME_SSID;
13118 if (psd_power)
13119 dot11f->tbtt_info.tbtt_info_9.psd_20mhz = psd_power;
13120 else
13121 dot11f->tbtt_info.tbtt_info_9.psd_20mhz = 127;
13122 break;
13123 case 13:
13124 dot11f->tbtt_info.tbtt_info_13.tbtt_offset =
13125 WLAN_RNR_TBTT_OFFSET_INVALID;
13126 qdf_mem_copy(dot11f->tbtt_info.tbtt_info_13.bssid,
13127 rnr_session->self_mac_addr, sizeof(tSirMacAddr));
13128
13129 dot11f->tbtt_info.tbtt_info_13.short_ssid =
13130 wlan_construct_shortssid(rnr_session->ssId.ssId,
13131 rnr_session->ssId.length);
13132
13133 dot11f->tbtt_info.tbtt_info_13.bss_params =
13134 WLAN_RNR_BSS_PARAM_COLOCATED_AP;
13135 if (!lim_cmp_ssid(&rnr_session->ssId, pe_session))
13136 dot11f->tbtt_info.tbtt_info_13.bss_params |=
13137 WLAN_RNR_BSS_PARAM_SAME_SSID;
13138
13139 if (psd_power)
13140 dot11f->tbtt_info.tbtt_info_13.psd_20mhz = psd_power;
13141 else
13142 dot11f->tbtt_info.tbtt_info_13.psd_20mhz = 127;
13143 break;
13144 default:
13145 dot11f->tbtt_info_len = 0;
13146 return QDF_STATUS_E_FAILURE;
13147 }
13148
13149 return QDF_STATUS_SUCCESS;
13150 }
13151
13152 /**
13153 * lim_is_6g_vdev() - loop every vdev to populate 6g vdev id
13154 * @psoc: pointer to psoc
13155 * @obj: vdev
13156 * @args: vdev list to record 6G vdev id
13157 *
13158 * Return: void
13159 */
13160 static void lim_is_6g_vdev(struct wlan_objmgr_psoc *psoc, void *obj, void *args)
13161 {
13162 struct wlan_objmgr_vdev *vdev = (struct wlan_objmgr_vdev *)obj;
13163 uint8_t *vdev_id_list = (uint8_t *)args;
13164 int i;
13165
13166 if (!vdev || (wlan_vdev_mlme_get_opmode(vdev) != QDF_SAP_MODE))
13167 return;
13168 if (QDF_IS_STATUS_ERROR(wlan_vdev_chan_config_valid(vdev)))
13169 return;
13170 if (!wlan_reg_is_6ghz_chan_freq(wlan_get_operation_chan_freq(vdev)))
13171 return;
13172
13173 for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) {
13174 if (vdev_id_list[i] == INVALID_VDEV_ID) {
13175 vdev_id_list[i] = wlan_vdev_get_id(vdev);
13176 break;
13177 }
13178 }
13179 }
13180
13181 void populate_dot11f_6g_rnr(struct mac_context *mac_ctx,
13182 struct pe_session *session,
13183 tDot11fIEreduced_neighbor_report *dot11f)
13184 {
13185 struct pe_session *co_session;
13186 struct wlan_objmgr_psoc *psoc;
13187 int vdev_id;
13188 uint8_t vdev_id_list[MAX_NUMBER_OF_CONC_CONNECTIONS];
13189
13190 if (!session || !mac_ctx || !dot11f || !session->vdev) {
13191 pe_err("Invalid params");
13192 return;
13193 }
13194
13195 psoc = wlan_vdev_get_psoc(session->vdev);
13196 if (!psoc) {
13197 pe_err("Invalid psoc");
13198 return;
13199 }
13200
13201 for (vdev_id = 0; vdev_id < MAX_NUMBER_OF_CONC_CONNECTIONS; vdev_id++)
13202 vdev_id_list[vdev_id] = INVALID_VDEV_ID;
13203
13204 wlan_objmgr_iterate_obj_list(psoc, WLAN_VDEV_OP,
13205 lim_is_6g_vdev,
13206 vdev_id_list, 1,
13207 WLAN_LEGACY_MAC_ID);
13208
13209 if (vdev_id_list[0] == INVALID_VDEV_ID)
13210 return;
13211
13212 co_session = pe_find_session_by_vdev_id(mac_ctx,
13213 vdev_id_list[0]);
13214 if (!co_session) {
13215 pe_err("Invalid co located session");
13216 return;
13217 }
13218 populate_dot11f_rnr_tbtt_info(mac_ctx, session, co_session, dot11f,
13219 CURRENT_RNR_TBTT_INFO_LEN);
13220 pe_debug("vdev id %d populate RNR IE with 6G vdev id %d op class %d chan num %d",
13221 wlan_vdev_get_id(session->vdev),
13222 wlan_vdev_get_id(co_session->vdev),
13223 dot11f->op_class, dot11f->channel_num);
13224 }
13225
13226 QDF_STATUS populate_dot11f_bcn_prot_extcaps(struct mac_context *mac_ctx,
13227 struct pe_session *pe_session,
13228 tDot11fIEExtCap *dot11f)
13229 {
13230 struct s_ext_cap *p_ext_cap;
13231
13232 /*
13233 * Some legacy STA might not connect with SAP broadcasting
13234 * EXTCAP with size greater than 8bytes.
13235 * In such cases, disable the beacon protection only if
13236 * a) disable_sap_bcn_prot ini is set
13237 * b) The SAP is not operating in 6 GHz or 11be profile
13238 * where BP is mandatory.
13239 */
13240 if (pe_session->opmode != QDF_SAP_MODE ||
13241 !wlan_mlme_is_bcn_prot_disabled_for_sap(mac_ctx->psoc) ||
13242 WLAN_REG_IS_6GHZ_CHAN_FREQ(pe_session->curr_op_freq) ||
13243 pe_session->dot11mode > MLME_DOT11_MODE_11AX_ONLY)
13244 return QDF_STATUS_SUCCESS;
13245
13246 p_ext_cap = (struct s_ext_cap *)dot11f->bytes;
13247 if (!dot11f->present || !p_ext_cap->beacon_protection_enable)
13248 return QDF_STATUS_SUCCESS;
13249
13250 p_ext_cap->beacon_protection_enable = 0;
13251 dot11f->num_bytes = lim_compute_ext_cap_ie_length(dot11f);
13252
13253 return QDF_STATUS_SUCCESS;
13254 }
13255 /* parser_api.c ends here. */
13256