1 /*
2 * Copyright (c) 2011-2021 The Linux Foundation. All rights reserved.
3 * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
4 *
5 * Permission to use, copy, modify, and/or distribute this software for
6 * any purpose with or without fee is hereby granted, provided that the
7 * above copyright notice and this permission notice appear in all
8 * copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
11 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
12 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
13 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
16 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17 * PERFORMANCE OF THIS SOFTWARE.
18 */
19
20 /**=========================================================================
21
22 \file lim_session.c
23
24 \brief implementation for lim Session related APIs
25
26 \author Sunit Bhatia
27
28 ========================================================================*/
29
30 /*--------------------------------------------------------------------------
31 Include Files
32 ------------------------------------------------------------------------*/
33 #include "ani_global.h"
34 #include "lim_ft_defs.h"
35 #include "lim_ft.h"
36 #include "lim_session.h"
37 #include "lim_utils.h"
38
39 #include "sch_api.h"
40 #include "lim_send_messages.h"
41 #include "cfg_ucfg_api.h"
42 #include <lim_assoc_utils.h>
43 #include <lim_process_fils.h>
44
45 #ifdef WLAN_ALLOCATE_GLOBAL_BUFFERS_DYNAMICALLY
46 static struct sDphHashNode *g_dph_node_array;
47
pe_allocate_dph_node_array_buffer(void)48 QDF_STATUS pe_allocate_dph_node_array_buffer(void)
49 {
50 uint32_t buf_size;
51
52 buf_size = WLAN_MAX_VDEVS * (SIR_SAP_MAX_NUM_PEERS + 1) *
53 sizeof(struct sDphHashNode);
54 g_dph_node_array = qdf_mem_malloc(buf_size);
55 if (!g_dph_node_array)
56 return QDF_STATUS_E_NOMEM;
57
58 return QDF_STATUS_SUCCESS;
59 }
60
pe_free_dph_node_array_buffer(void)61 void pe_free_dph_node_array_buffer(void)
62 {
63 qdf_mem_free(g_dph_node_array);
64 g_dph_node_array = NULL;
65 }
66
67 static inline
pe_get_session_dph_node_array(uint8_t session_id)68 struct sDphHashNode *pe_get_session_dph_node_array(uint8_t session_id)
69 {
70 return &g_dph_node_array[session_id * (SIR_SAP_MAX_NUM_PEERS + 1)];
71 }
72
73 #else /* WLAN_ALLOCATE_GLOBAL_BUFFERS_DYNAMICALLY */
74 static struct sDphHashNode
75 g_dph_node_array[WLAN_MAX_VDEVS][SIR_SAP_MAX_NUM_PEERS + 1];
76
77 static inline
pe_get_session_dph_node_array(uint8_t session_id)78 struct sDphHashNode *pe_get_session_dph_node_array(uint8_t session_id)
79 {
80 return g_dph_node_array[session_id];
81 }
82 #endif /* WLAN_ALLOCATE_GLOBAL_BUFFERS_DYNAMICALLY */
83
84 /*--------------------------------------------------------------------------
85
86 \brief pe_init_beacon_params() - Initialize the beaconParams structure
87
88 \param struct pe_session * - pointer to the session context or NULL if session can not be created.
89 \return void
90 \sa
91
92 --------------------------------------------------------------------------*/
93
pe_init_beacon_params(struct mac_context * mac,struct pe_session * pe_session)94 static void pe_init_beacon_params(struct mac_context *mac,
95 struct pe_session *pe_session)
96 {
97 pe_session->beaconParams.beaconInterval = 0;
98 pe_session->beaconParams.fShortPreamble = 0;
99 pe_session->beaconParams.llaCoexist = 0;
100 pe_session->beaconParams.llbCoexist = 0;
101 pe_session->beaconParams.llgCoexist = 0;
102 pe_session->beaconParams.ht20Coexist = 0;
103 pe_session->beaconParams.llnNonGFCoexist = 0;
104 pe_session->beaconParams.fRIFSMode = 0;
105 pe_session->beaconParams.fLsigTXOPProtectionFullSupport = 0;
106 pe_session->beaconParams.gHTObssMode = 0;
107
108 /* Number of legacy STAs associated */
109 qdf_mem_zero((void *)&pe_session->gLim11bParams,
110 sizeof(tLimProtStaParams));
111 qdf_mem_zero((void *)&pe_session->gLim11aParams,
112 sizeof(tLimProtStaParams));
113 qdf_mem_zero((void *)&pe_session->gLim11gParams,
114 sizeof(tLimProtStaParams));
115 qdf_mem_zero((void *)&pe_session->gLimNonGfParams,
116 sizeof(tLimProtStaParams));
117 qdf_mem_zero((void *)&pe_session->gLimHt20Params,
118 sizeof(tLimProtStaParams));
119 qdf_mem_zero((void *)&pe_session->gLimLsigTxopParams,
120 sizeof(tLimProtStaParams));
121 qdf_mem_zero((void *)&pe_session->gLimOlbcParams,
122 sizeof(tLimProtStaParams));
123 }
124
125 /*
126 * pe_reset_protection_callback() - resets protection structs so that when an AP
127 * causing use of protection goes away, corresponding protection bit can be
128 * reset
129 * @ptr: pointer to pe_session
130 *
131 * This function resets protection structs so that when an AP causing use of
132 * protection goes away, corresponding protection bit can be reset. This allowes
133 * protection bits to be reset once legacy overlapping APs are gone.
134 *
135 * Return: void
136 */
pe_reset_protection_callback(void * ptr)137 static void pe_reset_protection_callback(void *ptr)
138 {
139 struct pe_session *pe_session_entry = (struct pe_session *)ptr;
140 struct mac_context *mac_ctx = pe_session_entry->mac_ctx;
141 int8_t i = 0;
142 tUpdateBeaconParams beacon_params;
143 uint16_t current_protection_state = 0;
144 tpDphHashNode station_hash_node = NULL;
145 tSirMacHTOperatingMode old_op_mode;
146 bool bcn_prms_changed = false;
147
148 if (pe_session_entry->valid == false) {
149 pe_err("session already deleted. exiting timer callback");
150 return;
151 }
152
153 /*
154 * During CAC period, if the callback is triggered, the beacon
155 * template may get updated. Subsequently if the vdev is not up, the
156 * vdev would be made up -- which should not happen during the CAC
157 * period. To avoid this, ignore the protection callback if the session
158 * is not yet up.
159 */
160 if (!wma_is_vdev_up(pe_session_entry->smeSessionId)) {
161 pe_err("session is not up yet. exiting timer callback");
162 return;
163 }
164
165 /*
166 * If dfsIncludeChanSwIe is set restrat timer as we are going to change
167 * channel and no point in checking protection mode for this channel.
168 */
169 if (pe_session_entry->dfsIncludeChanSwIe) {
170 pe_err("CSA going on restart timer");
171 goto restart_timer;
172 }
173 current_protection_state |=
174 pe_session_entry->gLimOverlap11gParams.protectionEnabled |
175 pe_session_entry->gLimOverlap11aParams.protectionEnabled << 1 |
176 pe_session_entry->gLimOverlapHt20Params.protectionEnabled << 2 |
177 pe_session_entry->gLimOverlapNonGfParams.protectionEnabled << 3 |
178 pe_session_entry->gLimOlbcParams.protectionEnabled << 4;
179
180 pe_debug("old protection state: 0x%04X, new protection state: 0x%04X",
181 pe_session_entry->old_protection_state,
182 current_protection_state);
183
184 qdf_mem_zero(&pe_session_entry->gLimOverlap11gParams,
185 sizeof(pe_session_entry->gLimOverlap11gParams));
186 qdf_mem_zero(&pe_session_entry->gLimOverlap11aParams,
187 sizeof(pe_session_entry->gLimOverlap11aParams));
188 qdf_mem_zero(&pe_session_entry->gLimOverlapHt20Params,
189 sizeof(pe_session_entry->gLimOverlapHt20Params));
190 qdf_mem_zero(&pe_session_entry->gLimOverlapNonGfParams,
191 sizeof(pe_session_entry->gLimOverlapNonGfParams));
192
193 qdf_mem_zero(&pe_session_entry->gLimOlbcParams,
194 sizeof(pe_session_entry->gLimOlbcParams));
195
196 /*
197 * Do not reset fShortPreamble and beaconInterval, as they
198 * are not updated.
199 */
200 pe_session_entry->beaconParams.llaCoexist = 0;
201 pe_session_entry->beaconParams.llbCoexist = 0;
202 pe_session_entry->beaconParams.llgCoexist = 0;
203 pe_session_entry->beaconParams.ht20Coexist = 0;
204 pe_session_entry->beaconParams.llnNonGFCoexist = 0;
205 pe_session_entry->beaconParams.fRIFSMode = 0;
206 pe_session_entry->beaconParams.fLsigTXOPProtectionFullSupport = 0;
207 pe_session_entry->beaconParams.gHTObssMode = 0;
208
209
210 old_op_mode = pe_session_entry->htOperMode;
211 pe_session_entry->htOperMode = eSIR_HT_OP_MODE_PURE;
212 mac_ctx->lim.gHTOperMode = eSIR_HT_OP_MODE_PURE;
213
214 qdf_mem_zero(&beacon_params, sizeof(tUpdateBeaconParams));
215 /* index 0, is self node, peers start from 1 */
216 for (i = 1 ; i <= mac_ctx->lim.max_sta_of_pe_session; i++) {
217 station_hash_node = dph_get_hash_entry(mac_ctx, i,
218 &pe_session_entry->dph.dphHashTable);
219 if (!station_hash_node)
220 continue;
221 lim_decide_ap_protection(mac_ctx, station_hash_node->staAddr,
222 &beacon_params, pe_session_entry);
223 }
224
225 if (pe_session_entry->htOperMode != old_op_mode)
226 bcn_prms_changed = true;
227
228 if ((current_protection_state !=
229 pe_session_entry->old_protection_state) &&
230 (false == mac_ctx->sap.SapDfsInfo.is_dfs_cac_timer_running)) {
231 pe_debug("protection changed, update beacon template");
232 /* update beacon fix params and send update to FW */
233 qdf_mem_zero(&beacon_params, sizeof(tUpdateBeaconParams));
234 beacon_params.bss_idx = pe_session_entry->vdev_id;
235 beacon_params.fShortPreamble =
236 pe_session_entry->beaconParams.fShortPreamble;
237 beacon_params.beaconInterval =
238 pe_session_entry->beaconParams.beaconInterval;
239 beacon_params.llaCoexist =
240 pe_session_entry->beaconParams.llaCoexist;
241 beacon_params.llbCoexist =
242 pe_session_entry->beaconParams.llbCoexist;
243 beacon_params.llgCoexist =
244 pe_session_entry->beaconParams.llgCoexist;
245 beacon_params.ht20MhzCoexist =
246 pe_session_entry->beaconParams.ht20Coexist;
247 beacon_params.llnNonGFCoexist =
248 pe_session_entry->beaconParams.llnNonGFCoexist;
249 beacon_params.fLsigTXOPProtectionFullSupport =
250 pe_session_entry->beaconParams.
251 fLsigTXOPProtectionFullSupport;
252 beacon_params.fRIFSMode =
253 pe_session_entry->beaconParams.fRIFSMode;
254 beacon_params.vdev_id =
255 pe_session_entry->vdev_id;
256 beacon_params.paramChangeBitmap |= PARAM_llBCOEXIST_CHANGED;
257 bcn_prms_changed = true;
258 }
259
260 if (bcn_prms_changed) {
261 sch_set_fixed_beacon_fields(mac_ctx, pe_session_entry);
262 lim_send_beacon_params(mac_ctx, &beacon_params, pe_session_entry);
263 }
264
265 pe_session_entry->old_protection_state = current_protection_state;
266 restart_timer:
267 if (qdf_mc_timer_start(&pe_session_entry->
268 protection_fields_reset_timer,
269 SCH_PROTECTION_RESET_TIME)
270 != QDF_STATUS_SUCCESS) {
271 pe_err("cannot create or start protectionFieldsResetTimer");
272 }
273 }
274
275 /**
276 * pe_init_pmf_comeback_timer: init PMF comeback timer
277 * @mac_ctx: pointer to global adapter context
278 * @session: pe session
279 *
280 * Return: void
281 */
282 static void
pe_init_pmf_comeback_timer(tpAniSirGlobal mac_ctx,struct pe_session * session)283 pe_init_pmf_comeback_timer(tpAniSirGlobal mac_ctx, struct pe_session *session)
284 {
285 QDF_STATUS status;
286
287 if (session->opmode != QDF_STA_MODE)
288 return;
289
290 session->pmf_retry_timer_info.mac = mac_ctx;
291 session->pmf_retry_timer_info.vdev_id = session->vdev_id;
292 session->pmf_retry_timer_info.retried = false;
293 status = qdf_mc_timer_init(
294 &session->pmf_retry_timer, QDF_TIMER_TYPE_SW,
295 lim_pmf_comeback_timer_callback,
296 (void *)&session->pmf_retry_timer_info);
297 if (!QDF_IS_STATUS_SUCCESS(status))
298 pe_err("cannot init pmf comeback timer");
299 }
300
301 #ifdef WLAN_FEATURE_FILS_SK
302 /**
303 * pe_delete_fils_info: API to delete fils session info
304 * @session: pe session
305 *
306 * Return: void
307 */
pe_delete_fils_info(struct pe_session * session)308 void pe_delete_fils_info(struct pe_session *session)
309 {
310 struct pe_fils_session *fils_info;
311
312 if (!session || (session && !session->valid)) {
313 pe_debug("session is not valid");
314 return;
315 }
316 fils_info = session->fils_info;
317 if (!fils_info) {
318 pe_debug("fils info not found");
319 return;
320 }
321 if (fils_info->keyname_nai_data)
322 qdf_mem_free(fils_info->keyname_nai_data);
323 if (fils_info->fils_erp_reauth_pkt)
324 qdf_mem_free(fils_info->fils_erp_reauth_pkt);
325 if (fils_info->fils_rrk)
326 qdf_mem_free(fils_info->fils_rrk);
327 if (fils_info->fils_rik)
328 qdf_mem_free(fils_info->fils_rik);
329 if (fils_info->fils_eap_finish_pkt)
330 qdf_mem_free(fils_info->fils_eap_finish_pkt);
331 if (fils_info->fils_rmsk)
332 qdf_mem_free(fils_info->fils_rmsk);
333 if (fils_info->fils_pmk)
334 qdf_mem_free(fils_info->fils_pmk);
335 if (fils_info->auth_info.keyname)
336 qdf_mem_free(fils_info->auth_info.keyname);
337 if (fils_info->auth_info.domain_name)
338 qdf_mem_free(fils_info->auth_info.domain_name);
339 if (fils_info->hlp_data)
340 qdf_mem_free(fils_info->hlp_data);
341 qdf_mem_free(fils_info);
342 session->fils_info = NULL;
343 }
344 /**
345 * pe_init_fils_info: API to initialize fils session info elements to null
346 * @session: pe session
347 *
348 * Return: void
349 */
pe_init_fils_info(struct pe_session * session)350 static void pe_init_fils_info(struct pe_session *session)
351 {
352 struct pe_fils_session *fils_info;
353
354 if (!session || (session && !session->valid)) {
355 pe_debug("session is not valid");
356 return;
357 }
358 session->fils_info = qdf_mem_malloc(sizeof(struct pe_fils_session));
359 fils_info = session->fils_info;
360 if (!fils_info)
361 return;
362 fils_info->keyname_nai_data = NULL;
363 fils_info->fils_erp_reauth_pkt = NULL;
364 fils_info->fils_rrk = NULL;
365 fils_info->fils_rik = NULL;
366 fils_info->fils_eap_finish_pkt = NULL;
367 fils_info->fils_rmsk = NULL;
368 fils_info->fils_pmk = NULL;
369 fils_info->auth_info.keyname = NULL;
370 fils_info->auth_info.domain_name = NULL;
371 }
372 #else
pe_delete_fils_info(struct pe_session * session)373 static void pe_delete_fils_info(struct pe_session *session) { }
pe_init_fils_info(struct pe_session * session)374 static void pe_init_fils_info(struct pe_session *session) { }
375 #endif
376
377 /**
378 * lim_get_peer_idxpool_size: get number of peer idx pool size
379 * @num_sta: Max number of STA
380 * @bss_type: BSS type
381 *
382 * The peer index start from 1 and thus index 0 is not used, so
383 * add 1 to the max sta. For STA if TDLS is enabled add 2 as
384 * index 1 is reserved for peer BSS.
385 *
386 * Return: number of peer idx pool size
387 */
388 #ifdef FEATURE_WLAN_TDLS
389 static inline uint8_t
lim_get_peer_idxpool_size(uint16_t num_sta,enum bss_type bss_type)390 lim_get_peer_idxpool_size(uint16_t num_sta, enum bss_type bss_type)
391 {
392 /*
393 * In station role, index 1 is reserved for peer
394 * corresponding to AP. For TDLS the index should
395 * start from 2
396 */
397 if (bss_type == eSIR_INFRASTRUCTURE_MODE)
398 return num_sta + 2;
399 else
400 return num_sta + 1;
401
402 }
403 #else
404 static inline uint8_t
lim_get_peer_idxpool_size(uint16_t num_sta,enum bss_type bss_type)405 lim_get_peer_idxpool_size(uint16_t num_sta, enum bss_type bss_type)
406 {
407 return num_sta + 1;
408 }
409 #endif
410
lim_set_bcn_probe_filter(struct mac_context * mac_ctx,struct pe_session * session,uint8_t sap_channel)411 void lim_set_bcn_probe_filter(struct mac_context *mac_ctx,
412 struct pe_session *session,
413 uint8_t sap_channel)
414 {
415 struct mgmt_beacon_probe_filter *filter;
416 enum bss_type bss_type;
417 uint8_t session_id;
418 tSirMacAddr *bssid;
419
420 if (!session) {
421 pe_err("Invalid session pointer");
422 return;
423 }
424
425 bss_type = session->bssType;
426 session_id = session->peSessionId;
427 bssid = &session->bssId;
428
429 if (session_id >= WLAN_MAX_VDEVS) {
430 pe_err("vdev %d Invalid session_id %d of type %d",
431 session->vdev_id, session_id, bss_type);
432 return;
433 }
434
435 filter = &mac_ctx->bcn_filter;
436
437 if (eSIR_INFRASTRUCTURE_MODE == bss_type) {
438 filter->num_sta_sessions++;
439 sir_copy_mac_addr(filter->sta_bssid[session_id], *bssid);
440 } else if (eSIR_INFRA_AP_MODE == bss_type) {
441 if (!sap_channel) {
442 pe_err("vdev %d with invalid chan", session->vdev_id);
443 return;
444 }
445 filter->num_sap_sessions++;
446 filter->sap_channel[session_id] = sap_channel;
447 }
448 }
449
lim_reset_bcn_probe_filter(struct mac_context * mac_ctx,struct pe_session * session)450 void lim_reset_bcn_probe_filter(struct mac_context *mac_ctx,
451 struct pe_session *session)
452 {
453 struct mgmt_beacon_probe_filter *filter;
454 enum bss_type bss_type;
455 uint8_t session_id;
456
457 if (!session) {
458 pe_err("Invalid session pointer");
459 return;
460 }
461
462 bss_type = session->bssType;
463 session_id = session->peSessionId;
464
465 if (session_id >= WLAN_MAX_VDEVS) {
466 pe_err("Invalid session_id %d of type %d",
467 session_id, bss_type);
468 return;
469 }
470
471 filter = &mac_ctx->bcn_filter;
472
473 if (eSIR_INFRASTRUCTURE_MODE == bss_type) {
474 if (filter->num_sta_sessions)
475 filter->num_sta_sessions--;
476 qdf_mem_zero(&filter->sta_bssid[session_id],
477 sizeof(tSirMacAddr));
478 pe_debug("Cleared STA Filter for session %d", session_id);
479 } else if (eSIR_INFRA_AP_MODE == bss_type) {
480 if (filter->num_sap_sessions)
481 filter->num_sap_sessions--;
482 filter->sap_channel[session_id] = 0;
483 pe_debug("Cleared SAP Filter for session %d", session_id);
484 }
485
486 pe_debug("sta %d sap %d", filter->num_sta_sessions,
487 filter->num_sap_sessions);
488 }
489
lim_update_bcn_probe_filter(struct mac_context * mac_ctx,struct pe_session * session)490 void lim_update_bcn_probe_filter(struct mac_context *mac_ctx,
491 struct pe_session *session)
492 {
493 struct mgmt_beacon_probe_filter *filter;
494 enum bss_type bss_type;
495 uint8_t session_id;
496
497 if (!session) {
498 pe_err("Invalid session pointer");
499 return;
500 }
501
502 bss_type = session->bssType;
503 session_id = session->peSessionId;
504
505 if (session_id >= WLAN_MAX_VDEVS) {
506 pe_err("Invalid session_id %d of type %d",
507 session_id, bss_type);
508 return;
509 }
510
511 filter = &mac_ctx->bcn_filter;
512
513 if (eSIR_INFRA_AP_MODE == bss_type) {
514 filter->sap_channel[session_id] = wlan_reg_freq_to_chan(
515 mac_ctx->pdev, session->curr_op_freq);
516 pe_debug("Updated SAP Filter for session %d channel %d",
517 session_id, filter->sap_channel[session_id]);
518 } else {
519 pe_debug("Invalid session type %d session id %d",
520 bss_type, session_id);
521 }
522
523 pe_debug("sta %d sap %d", filter->num_sta_sessions,
524 filter->num_sap_sessions);
525 }
526
pe_create_session(struct mac_context * mac,uint8_t * bssid,uint8_t * sessionId,uint16_t numSta,enum bss_type bssType,uint8_t vdev_id)527 struct pe_session *pe_create_session(struct mac_context *mac,
528 uint8_t *bssid, uint8_t *sessionId,
529 uint16_t numSta, enum bss_type bssType,
530 uint8_t vdev_id)
531 {
532 QDF_STATUS status;
533 uint8_t i;
534 struct pe_session *session_ptr;
535 struct wlan_objmgr_vdev *vdev;
536
537 for (i = 0; i < mac->lim.maxBssId; i++) {
538 /* Find first free room in session table */
539 if (mac->lim.gpSession[i].valid == true)
540 continue;
541 break;
542 }
543
544 if (i == mac->lim.maxBssId) {
545 pe_err("Session can't be created. Reached max sessions");
546 return NULL;
547 }
548
549 session_ptr = &mac->lim.gpSession[i];
550 qdf_mem_zero((void *)session_ptr, sizeof(struct pe_session));
551 /* Allocate space for Station Table for this session. */
552 session_ptr->dph.dphHashTable.pHashTable =
553 qdf_mem_malloc(sizeof(tpDphHashNode) * (numSta + 1));
554 if (!session_ptr->dph.dphHashTable.pHashTable)
555 return NULL;
556
557 session_ptr->dph.dphHashTable.pDphNodeArray =
558 pe_get_session_dph_node_array(i);
559 session_ptr->dph.dphHashTable.size = numSta + 1;
560 dph_hash_table_init(mac, &session_ptr->dph.dphHashTable);
561
562 /* Copy the BSSID to the session table */
563 sir_copy_mac_addr(session_ptr->bssId, bssid);
564 if (bssType == eSIR_MONITOR_MODE)
565 sir_copy_mac_addr(mac->lim.gpSession[i].self_mac_addr, bssid);
566 session_ptr->valid = true;
567 /* Initialize the SME and MLM states to IDLE */
568 session_ptr->limMlmState = eLIM_MLM_IDLE_STATE;
569 session_ptr->limSmeState = eLIM_SME_IDLE_STATE;
570 session_ptr->limCurrentAuthType = eSIR_OPEN_SYSTEM;
571 pe_init_beacon_params(mac, &mac->lim.gpSession[i]);
572 session_ptr->is11Rconnection = false;
573 *sessionId = i;
574 session_ptr->peSessionId = i;
575 session_ptr->bssType = bssType;
576 session_ptr->gLimPhyMode = WNI_CFG_PHY_MODE_11G;
577 /* Initialize CB mode variables when session is created */
578 session_ptr->htSupportedChannelWidthSet = 0;
579 session_ptr->htRecommendedTxWidthSet = 0;
580 session_ptr->htSecondaryChannelOffset = 0;
581 #ifdef FEATURE_WLAN_TDLS
582 qdf_mem_zero(session_ptr->peerAIDBitmap,
583 sizeof(session_ptr->peerAIDBitmap));
584 #endif
585 lim_update_tdls_set_state_for_fw(session_ptr, true);
586 session_ptr->fWaitForProbeRsp = 0;
587 session_ptr->fIgnoreCapsChange = 0;
588 session_ptr->is_session_obss_color_collision_det_enabled =
589 mac->mlme_cfg->obss_ht40.obss_color_collision_offload_enabled;
590
591 if (bssType == eSIR_INFRA_AP_MODE) {
592 session_ptr->pSchProbeRspTemplate =
593 qdf_mem_malloc(SIR_MAX_PROBE_RESP_SIZE);
594 session_ptr->pSchBeaconFrameBegin =
595 qdf_mem_malloc(SIR_MAX_BEACON_SIZE);
596 session_ptr->pSchBeaconFrameEnd =
597 qdf_mem_malloc(SIR_MAX_BEACON_SIZE);
598 if ((!session_ptr->pSchProbeRspTemplate)
599 || (!session_ptr->pSchBeaconFrameBegin)
600 || (!session_ptr->pSchBeaconFrameEnd)) {
601 goto free_session_attrs;
602 }
603 }
604
605 /*
606 * Get vdev object from soc which automatically increments
607 * reference count.
608 */
609 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac->psoc,
610 vdev_id,
611 WLAN_LEGACY_MAC_ID);
612 if (!vdev) {
613 pe_err("vdev is NULL for vdev_id: %u", vdev_id);
614 goto free_session_attrs;
615 }
616 session_ptr->vdev = vdev;
617 session_ptr->vdev_id = vdev_id;
618 session_ptr->mac_ctx = mac;
619 session_ptr->opmode = wlan_vdev_mlme_get_opmode(vdev);
620 mlme_set_tdls_chan_switch_prohibited(vdev, false);
621 mlme_set_tdls_prohibited(vdev, false);
622 pe_debug("Create PE session: %d opmode %d vdev_id %d BSSID: "QDF_MAC_ADDR_FMT" Max No of STA: %d",
623 *sessionId, session_ptr->opmode, vdev_id,
624 QDF_MAC_ADDR_REF(bssid), numSta);
625
626 if (!lim_create_peer_idxpool(
627 session_ptr,
628 lim_get_peer_idxpool_size(numSta, bssType)))
629 goto free_session_attrs;
630
631 if (eSIR_INFRASTRUCTURE_MODE == bssType)
632 lim_ft_open(mac, &mac->lim.gpSession[i]);
633
634 if (eSIR_MONITOR_MODE == bssType)
635 lim_ft_open(mac, &mac->lim.gpSession[i]);
636
637 if (eSIR_INFRA_AP_MODE == bssType) {
638 session_ptr->old_protection_state = 0;
639 session_ptr->is_session_obss_offload_enabled = false;
640 session_ptr->is_obss_reset_timer_initialized = false;
641
642 status = qdf_mc_timer_init(&session_ptr->
643 protection_fields_reset_timer,
644 QDF_TIMER_TYPE_SW,
645 pe_reset_protection_callback,
646 (void *)&mac->lim.gpSession[i]);
647
648 if (QDF_IS_STATUS_ERROR(status))
649 pe_err("cannot create protection fields reset timer");
650 else
651 session_ptr->is_obss_reset_timer_initialized = true;
652
653 qdf_wake_lock_create(&session_ptr->ap_ecsa_wakelock,
654 "ap_ecsa_wakelock");
655 qdf_runtime_lock_init(&session_ptr->ap_ecsa_runtime_lock);
656 status = qdf_mc_timer_init(&session_ptr->ap_ecsa_timer,
657 QDF_TIMER_TYPE_WAKE_APPS,
658 lim_process_ap_ecsa_timeout,
659 (void *)&mac->lim.gpSession[i]);
660 if (status != QDF_STATUS_SUCCESS)
661 pe_err("cannot create ap_ecsa_timer");
662 }
663 if (session_ptr->opmode == QDF_STA_MODE)
664 session_ptr->is_session_obss_color_collision_det_enabled =
665 mac->mlme_cfg->obss_ht40.bss_color_collision_det_sta;
666 pe_init_fils_info(session_ptr);
667 pe_init_pmf_comeback_timer(mac, session_ptr);
668 session_ptr->ht_client_cnt = 0;
669 /* following is invalid value since seq number is 12 bit */
670 session_ptr->prev_auth_seq_num = 0xFFFF;
671
672 session_ptr->user_edca_set = 0;
673 session_ptr->join_probe_cnt = 0;
674
675 return &mac->lim.gpSession[i];
676
677 free_session_attrs:
678 lim_free_peer_idxpool(session_ptr);
679 qdf_mem_free(session_ptr->pSchProbeRspTemplate);
680 qdf_mem_free(session_ptr->pSchBeaconFrameBegin);
681 qdf_mem_free(session_ptr->pSchBeaconFrameEnd);
682
683 session_ptr->pSchProbeRspTemplate = NULL;
684 session_ptr->pSchBeaconFrameBegin = NULL;
685 session_ptr->pSchBeaconFrameEnd = NULL;
686
687 qdf_mem_free(session_ptr->dph.dphHashTable.pHashTable);
688 qdf_mem_zero(session_ptr->dph.dphHashTable.pDphNodeArray,
689 sizeof(struct sDphHashNode) * (SIR_SAP_MAX_NUM_PEERS + 1));
690
691 session_ptr->dph.dphHashTable.pHashTable = NULL;
692 session_ptr->dph.dphHashTable.pDphNodeArray = NULL;
693 session_ptr->valid = false;
694
695 return NULL;
696 }
697
698 /*--------------------------------------------------------------------------
699 \brief pe_find_session_by_bssid() - looks up the PE session given the BSSID.
700
701 This function returns the session context and the session ID if the session
702 corresponding to the given BSSID is found in the PE session table.
703
704 \param mac - pointer to global adapter context
705 \param bssid - BSSID of the session
706 \param sessionId -session ID is returned here, if session is found.
707
708 \return struct pe_session * - pointer to the session context or NULL if session is not found.
709
710 \sa
711 --------------------------------------------------------------------------*/
pe_find_session_by_bssid(struct mac_context * mac,uint8_t * bssid,uint8_t * sessionId)712 struct pe_session *pe_find_session_by_bssid(struct mac_context *mac, uint8_t *bssid,
713 uint8_t *sessionId)
714 {
715 uint8_t i;
716
717 for (i = 0; i < mac->lim.maxBssId; i++) {
718 /* If BSSID matches return corresponding tables address */
719 if ((mac->lim.gpSession[i].valid)
720 && (sir_compare_mac_addr(mac->lim.gpSession[i].bssId,
721 bssid))) {
722 *sessionId = i;
723 return &mac->lim.gpSession[i];
724 }
725 }
726
727 return NULL;
728
729 }
730
pe_find_session_by_vdev_id(struct mac_context * mac,uint8_t vdev_id)731 struct pe_session *pe_find_session_by_vdev_id(struct mac_context *mac,
732 uint8_t vdev_id)
733 {
734 uint8_t i;
735
736 for (i = 0; i < mac->lim.maxBssId; i++) {
737 /* If BSSID matches return corresponding tables address */
738 if ((mac->lim.gpSession[i].valid) &&
739 (mac->lim.gpSession[i].vdev_id == vdev_id))
740 return &mac->lim.gpSession[i];
741 }
742 pe_debug("Session lookup fails for vdev_id: %d", vdev_id);
743
744 return NULL;
745 }
746
747 struct pe_session
pe_find_session_by_vdev_id_and_state(struct mac_context * mac,uint8_t vdev_id,enum eLimMlmStates lim_state)748 *pe_find_session_by_vdev_id_and_state(struct mac_context *mac,
749 uint8_t vdev_id,
750 enum eLimMlmStates lim_state)
751 {
752 uint8_t i;
753
754 for (i = 0; i < mac->lim.maxBssId; i++) {
755 if (mac->lim.gpSession[i].valid &&
756 mac->lim.gpSession[i].vdev_id == vdev_id &&
757 mac->lim.gpSession[i].limMlmState == lim_state)
758 return &mac->lim.gpSession[i];
759 }
760 pe_debug("Session lookup fails for vdev_id: %d, mlm state: %d",
761 vdev_id, lim_state);
762
763 return NULL;
764 }
765
766 struct pe_session *
pe_find_session_by_bssid_and_vdev_id(struct mac_context * mac,uint8_t * bssid,uint8_t vdev_id,uint8_t * sessionId)767 pe_find_session_by_bssid_and_vdev_id(struct mac_context *mac,
768 uint8_t *bssid,
769 uint8_t vdev_id,
770 uint8_t *sessionId)
771 {
772 uint8_t i;
773
774 for (i = 0; i < mac->lim.maxBssId; i++) {
775 /* If BSSID matches return corresponding tables address */
776 if ((mac->lim.gpSession[i].valid) &&
777 (mac->lim.gpSession[i].vdev_id == vdev_id) &&
778 (sir_compare_mac_addr(mac->lim.gpSession[i].bssId,
779 bssid))) {
780 *sessionId = i;
781 return &mac->lim.gpSession[i];
782 }
783 }
784
785 return NULL;
786 }
787
788 /*--------------------------------------------------------------------------
789 \brief pe_find_session_by_session_id() - looks up the PE session given the session ID.
790
791 This function returns the session context if the session
792 corresponding to the given session ID is found in the PE session table.
793
794 \param mac - pointer to global adapter context
795 \param sessionId -session ID for which session context needs to be looked up.
796
797 \return struct pe_session * - pointer to the session context or NULL if session is not found.
798
799 \sa
800 --------------------------------------------------------------------------*/
pe_find_session_by_session_id(struct mac_context * mac,uint8_t sessionId)801 struct pe_session *pe_find_session_by_session_id(struct mac_context *mac,
802 uint8_t sessionId)
803 {
804 if (sessionId >= mac->lim.maxBssId) {
805 pe_err("Invalid sessionId: %d", sessionId);
806 return NULL;
807 }
808
809 if (mac->lim.gpSession[sessionId].valid)
810 return &mac->lim.gpSession[sessionId];
811
812 return NULL;
813 }
814
lim_clear_pmfcomeback_timer(struct pe_session * session)815 static void lim_clear_pmfcomeback_timer(struct pe_session *session)
816 {
817 if (session->opmode != QDF_STA_MODE)
818 return;
819
820 pe_debug("deinit pmf comeback timer for vdev %d", session->vdev_id);
821 if (QDF_TIMER_STATE_RUNNING ==
822 qdf_mc_timer_get_current_state(&session->pmf_retry_timer))
823 qdf_mc_timer_stop(&session->pmf_retry_timer);
824 qdf_mc_timer_destroy(&session->pmf_retry_timer);
825 session->pmf_retry_timer_info.retried = false;
826 }
827
lim_clear_mbssid_info(struct wlan_objmgr_vdev * vdev)828 static void lim_clear_mbssid_info(struct wlan_objmgr_vdev *vdev)
829 {
830 struct scan_mbssid_info mbssid_info = {0};
831
832 mlme_set_mbssid_info(vdev, &mbssid_info, INVALID_CHANNEL_NUM);
833 }
834
835 /**
836 * pe_delete_session() - deletes the PE session given the session ID.
837 * @mac_ctx: pointer to global adapter context
838 * @session: session to be deleted.
839 *
840 * Deletes the given PE session
841 *
842 * Return: void
843 */
pe_delete_session(struct mac_context * mac_ctx,struct pe_session * session)844 void pe_delete_session(struct mac_context *mac_ctx, struct pe_session *session)
845 {
846 uint16_t i = 0;
847 uint16_t n;
848 TX_TIMER *timer_ptr;
849 struct wlan_objmgr_vdev *vdev;
850 tpSirAssocRsp assoc_rsp;
851
852 if (!session || (session && !session->valid)) {
853 pe_debug("session already deleted or not valid");
854 return;
855 }
856
857 pe_debug("Delete PE session: %d opmode: %d vdev_id: %d BSSID: "QDF_MAC_ADDR_FMT,
858 session->peSessionId, session->opmode, session->vdev_id,
859 QDF_MAC_ADDR_REF(session->bssId));
860
861 lim_reset_bcn_probe_filter(mac_ctx, session);
862 lim_sae_auth_cleanup_retry(mac_ctx, session->vdev_id);
863 lim_cleanup_power_change(mac_ctx, session);
864 lim_clear_mbssid_info(session->vdev);
865
866 /* Restore default failure timeout */
867 if (session->defaultAuthFailureTimeout) {
868 pe_debug("Restore default failure timeout");
869 if (cfg_in_range(CFG_AUTH_FAILURE_TIMEOUT,
870 session->defaultAuthFailureTimeout))
871 mac_ctx->mlme_cfg->timeouts.auth_failure_timeout =
872 session->defaultAuthFailureTimeout;
873 else
874 mac_ctx->mlme_cfg->timeouts.auth_failure_timeout =
875 cfg_default(CFG_AUTH_FAILURE_TIMEOUT);
876 }
877
878 for (n = 0; n < (mac_ctx->lim.maxStation + 1); n++) {
879 timer_ptr = &mac_ctx->lim.lim_timers.gpLimCnfWaitTimer[n];
880 if (session->peSessionId == timer_ptr->sessionId)
881 if (true == tx_timer_running(timer_ptr))
882 tx_timer_deactivate(timer_ptr);
883 }
884
885 if (LIM_IS_AP_ROLE(session)) {
886 qdf_runtime_lock_deinit(&session->ap_ecsa_runtime_lock);
887 qdf_wake_lock_destroy(&session->ap_ecsa_wakelock);
888 qdf_mc_timer_stop(&session->protection_fields_reset_timer);
889 qdf_mc_timer_destroy(&session->protection_fields_reset_timer);
890 session->dfsIncludeChanSwIe = 0;
891 qdf_mc_timer_stop(&session->ap_ecsa_timer);
892 qdf_mc_timer_destroy(&session->ap_ecsa_timer);
893 lim_del_pmf_sa_query_timer(mac_ctx, session);
894 }
895
896 /* Delete FT related information */
897 lim_ft_cleanup(mac_ctx, session);
898 if (session->pLimStartBssReq) {
899 qdf_mem_free(session->pLimStartBssReq);
900 session->pLimStartBssReq = NULL;
901 }
902
903 if (session->lim_join_req) {
904 qdf_mem_free(session->lim_join_req);
905 session->lim_join_req = NULL;
906 }
907
908 if (session->pLimReAssocReq) {
909 qdf_mem_free(session->pLimReAssocReq);
910 session->pLimReAssocReq = NULL;
911 }
912
913 if (session->pLimMlmJoinReq) {
914 qdf_mem_free(session->pLimMlmJoinReq);
915 session->pLimMlmJoinReq = NULL;
916 }
917
918 if (session->dph.dphHashTable.pHashTable) {
919 qdf_mem_free(session->dph.dphHashTable.pHashTable);
920 session->dph.dphHashTable.pHashTable = NULL;
921 }
922
923 if (session->dph.dphHashTable.pDphNodeArray) {
924 qdf_mem_zero(session->dph.dphHashTable.pDphNodeArray,
925 sizeof(struct sDphHashNode) *
926 (SIR_SAP_MAX_NUM_PEERS + 1));
927 session->dph.dphHashTable.pDphNodeArray = NULL;
928 }
929
930 lim_free_peer_idxpool(session);
931
932 if (session->beacon) {
933 qdf_mem_free(session->beacon);
934 session->beacon = NULL;
935 session->bcnLen = 0;
936 }
937
938 if (session->assoc_req) {
939 qdf_mem_free(session->assoc_req);
940 session->assoc_req = NULL;
941 session->assocReqLen = 0;
942 }
943
944 if (session->assocRsp) {
945 qdf_mem_free(session->assocRsp);
946 session->assocRsp = NULL;
947 session->assocRspLen = 0;
948 }
949
950 if (session->parsedAssocReq) {
951 tpSirAssocReq tmp_ptr = NULL;
952 /* Cleanup the individual allocation first */
953 for (i = 0; i < session->dph.dphHashTable.size; i++) {
954 if (!session->parsedAssocReq[i])
955 continue;
956 tmp_ptr = ((tpSirAssocReq)
957 (session->parsedAssocReq[i]));
958 lim_free_assoc_req_frm_buf(tmp_ptr);
959 qdf_mem_free(session->parsedAssocReq[i]);
960 session->parsedAssocReq[i] = NULL;
961 }
962 /* Cleanup the whole block */
963 qdf_mem_free(session->parsedAssocReq);
964 session->parsedAssocReq = NULL;
965 }
966 if (session->limAssocResponseData) {
967 assoc_rsp = (tpSirAssocRsp) session->limAssocResponseData;
968 qdf_mem_free(assoc_rsp->sha384_ft_subelem.gtk);
969 qdf_mem_free(assoc_rsp->sha384_ft_subelem.igtk);
970 qdf_mem_free(session->limAssocResponseData);
971 session->limAssocResponseData = NULL;
972 }
973 if (session->pLimMlmReassocRetryReq) {
974 qdf_mem_free(session->pLimMlmReassocRetryReq);
975 session->pLimMlmReassocRetryReq = NULL;
976 }
977 if (session->pLimMlmReassocReq) {
978 qdf_mem_free(session->pLimMlmReassocReq);
979 session->pLimMlmReassocReq = NULL;
980 }
981
982 if (session->pSchProbeRspTemplate) {
983 qdf_mem_free(session->pSchProbeRspTemplate);
984 session->pSchProbeRspTemplate = NULL;
985 }
986
987 if (session->pSchBeaconFrameBegin) {
988 qdf_mem_free(session->pSchBeaconFrameBegin);
989 session->pSchBeaconFrameBegin = NULL;
990 }
991
992 if (session->pSchBeaconFrameEnd) {
993 qdf_mem_free(session->pSchBeaconFrameEnd);
994 session->pSchBeaconFrameEnd = NULL;
995 }
996
997 /* Must free the buffer before peSession invalid */
998 if (session->add_ie_params.probeRespData_buff) {
999 qdf_mem_free(session->add_ie_params.probeRespData_buff);
1000 session->add_ie_params.probeRespData_buff = NULL;
1001 session->add_ie_params.probeRespDataLen = 0;
1002 }
1003 if (session->add_ie_params.assocRespData_buff) {
1004 qdf_mem_free(session->add_ie_params.assocRespData_buff);
1005 session->add_ie_params.assocRespData_buff = NULL;
1006 session->add_ie_params.assocRespDataLen = 0;
1007 }
1008 if (session->add_ie_params.probeRespBCNData_buff) {
1009 qdf_mem_free(session->add_ie_params.probeRespBCNData_buff);
1010 session->add_ie_params.probeRespBCNData_buff = NULL;
1011 session->add_ie_params.probeRespBCNDataLen = 0;
1012 }
1013 pe_delete_fils_info(session);
1014 lim_clear_pmfcomeback_timer(session);
1015 session->valid = false;
1016
1017 session->mac_ctx = NULL;
1018
1019 if (session->access_policy_vendor_ie)
1020 qdf_mem_free(session->access_policy_vendor_ie);
1021
1022 session->access_policy_vendor_ie = NULL;
1023
1024 if (LIM_IS_AP_ROLE(session)) {
1025 lim_check_and_reset_protection_params(mac_ctx);
1026 wlan_set_sap_user_config_freq(session->vdev, 0);
1027 }
1028
1029 session->user_edca_set = 0;
1030
1031 vdev = session->vdev;
1032 session->vdev = NULL;
1033 if (vdev)
1034 wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_MAC_ID);
1035 }
1036
1037 /*--------------------------------------------------------------------------
1038 \brief pe_find_session_by_peer_sta() - looks up the PE session given the Station Address.
1039
1040 This function returns the session context and the session ID if the session
1041 corresponding to the given station address is found in the PE session table.
1042
1043 \param mac - pointer to global adapter context
1044 \param sa - Peer STA Address of the session
1045 \param sessionId -session ID is returned here, if session is found.
1046
1047 \return struct pe_session * - pointer to the session context or NULL if session is not found.
1048
1049 \sa
1050 --------------------------------------------------------------------------*/
1051
pe_find_session_by_peer_sta(struct mac_context * mac,uint8_t * sa,uint8_t * sessionId)1052 struct pe_session *pe_find_session_by_peer_sta(struct mac_context *mac, uint8_t *sa,
1053 uint8_t *sessionId)
1054 {
1055 uint8_t i;
1056 tpDphHashNode pSta;
1057 uint16_t aid;
1058
1059 for (i = 0; i < mac->lim.maxBssId; i++) {
1060 if ((mac->lim.gpSession[i].valid)) {
1061 pSta =
1062 dph_lookup_hash_entry(mac, sa, &aid,
1063 &mac->lim.gpSession[i].dph.
1064 dphHashTable);
1065 if (pSta) {
1066 *sessionId = i;
1067 return &mac->lim.gpSession[i];
1068 }
1069 }
1070 }
1071
1072 pe_debug("Session lookup fails for Peer: "QDF_MAC_ADDR_FMT,
1073 QDF_MAC_ADDR_REF(sa));
1074 return NULL;
1075 }
1076
1077 /**
1078 * pe_find_session_by_scan_id() - looks up the PE session for given scan id
1079 * @mac_ctx: pointer to global adapter context
1080 * @scan_id: scan id
1081 *
1082 * looks up the PE session for given scan id
1083 *
1084 * Return: pe session entry for given scan id if found else NULL
1085 */
pe_find_session_by_scan_id(struct mac_context * mac_ctx,uint32_t scan_id)1086 struct pe_session *pe_find_session_by_scan_id(struct mac_context *mac_ctx,
1087 uint32_t scan_id)
1088 {
1089 uint8_t i;
1090
1091 for (i = 0; i < mac_ctx->lim.maxBssId; i++) {
1092 if ((mac_ctx->lim.gpSession[i].valid) &&
1093 (mac_ctx->lim.gpSession[i].ftPEContext.pFTPreAuthReq) &&
1094 (mac_ctx->lim.gpSession[i].ftPEContext.pFTPreAuthReq
1095 ->scan_id == scan_id)) {
1096 return &mac_ctx->lim.gpSession[i];
1097 }
1098 }
1099 return NULL;
1100 }
1101
lim_dump_session_info(struct mac_context * mac_ctx,struct pe_session * pe_session)1102 void lim_dump_session_info(struct mac_context *mac_ctx,
1103 struct pe_session *pe_session)
1104 {
1105 if (!mac_ctx || !pe_session)
1106 return;
1107
1108 pe_nofl_debug("vdev_id %d freq %d ch_bw %d freq0 %d freq1 %d, smps %d mode %d action %d, nss_1x1 %d vdev_nss %d nss %d, cbMode %d, dot11Mode %d, subfer %d subfee %d csn %d, is_cisco %d, WPS %d OSEN %d FILS %d AKM %d",
1109 pe_session->vdev_id, pe_session->curr_op_freq,
1110 pe_session->ch_width, pe_session->ch_center_freq_seg0,
1111 pe_session->ch_center_freq_seg1,
1112 mac_ctx->mlme_cfg->ht_caps.enable_smps,
1113 mac_ctx->mlme_cfg->ht_caps.smps,
1114 pe_session->send_smps_action,
1115 pe_session->supported_nss_1x1, pe_session->vdev_nss,
1116 pe_session->nss, pe_session->htSupportedChannelWidthSet,
1117 pe_session->dot11mode,
1118 pe_session->vht_config.su_beam_former,
1119 pe_session->vht_config.su_beam_formee,
1120 pe_session->vht_config.csnof_beamformer_antSup,
1121 pe_session->isCiscoVendorAP, pe_session->wps_registration,
1122 pe_session->isOSENConnection,
1123 lim_is_fils_connection(pe_session),
1124 pe_session->connected_akm);
1125
1126 pe_nofl_debug(" MaxTxPwr %d RMF %d force_20_24 %d UAPSD flag 0x%2x auth type %d privacy %d",
1127 pe_session->maxTxPower, pe_session->limRmfEnabled,
1128 wlan_cm_get_force_20mhz_in_24ghz(pe_session->vdev),
1129 pe_session->gUapsdPerAcBitmask,
1130 mac_ctx->mlme_cfg->wep_params.auth_type,
1131 mac_ctx->mlme_cfg->wep_params.is_privacy_enabled);
1132 }
1133
1134 #ifdef WLAN_FEATURE_11AX
lim_dump_he_info(struct mac_context * mac,struct pe_session * session)1135 void lim_dump_he_info(struct mac_context *mac, struct pe_session *session)
1136 {
1137 struct mlme_legacy_priv *mlme_priv;
1138
1139 if (!session->he_capable)
1140 return;
1141
1142 mlme_priv = wlan_vdev_mlme_get_ext_hdl(session->vdev);
1143 if (!mlme_priv)
1144 return;
1145
1146 pe_nofl_debug(" HE info: bss_color %d default_pe %d ul mu %d, rx_pream_puncturing %d MCS LT_80: tx: 0x%x, rx: 0x%x, 160: tx: 0x%x, rx: 0x%x",
1147 session->he_op.bss_color, session->he_op.default_pe,
1148 session->he_config.ul_mu,
1149 mac->he_cap_5g.rx_pream_puncturing,
1150 mlme_priv->he_config.tx_he_mcs_map_lt_80,
1151 mlme_priv->he_config.rx_he_mcs_map_lt_80,
1152 *(uint16_t *)mlme_priv->he_config.tx_he_mcs_map_160,
1153 *(uint16_t *)mlme_priv->he_config.rx_he_mcs_map_160);
1154 }
1155 #endif
1156
1157 #ifdef WLAN_FEATURE_11BE_MLO
lim_dump_eht_info(struct pe_session * session)1158 void lim_dump_eht_info(struct pe_session *session)
1159 {
1160 bool is_emlsr;
1161 struct mlo_partner_info *partner_info;
1162 struct qdf_mac_addr mld_addr = {0};
1163 uint8_t buffer[100] = {0};
1164 uint8_t idx, len = 0, buf_len = QDF_ARRAY_SIZE(buffer);
1165
1166 if (!session->eht_capable)
1167 return;
1168
1169 wlan_vdev_obj_lock(session->vdev);
1170 is_emlsr = wlan_vdev_mlme_cap_get(session->vdev, WLAN_VDEV_C_EMLSR_CAP);
1171 wlan_vdev_obj_unlock(session->vdev);
1172
1173 wlan_vdev_get_bss_peer_mld_mac(session->vdev, &mld_addr);
1174
1175 if (!session->lim_join_req)
1176 return;
1177
1178 partner_info = &session->lim_join_req->partner_info;
1179 for (idx = 0; idx < partner_info->num_partner_links; idx++) {
1180 if (len >= buf_len)
1181 break;
1182
1183 len += qdf_scnprintf(buffer + len, buf_len - len, "Link %d: " QDF_MAC_ADDR_FMT,
1184 partner_info->partner_link_info[idx].link_id,
1185 QDF_MAC_ADDR_REF(partner_info->partner_link_info[idx].link_addr.bytes));
1186 }
1187
1188 pe_nofl_debug(" 802.11be D-3.0, MLD: " QDF_MAC_ADDR_FMT " 320MHz %d num_sounding_dim_320 %d, eMLSR %d, partner_links %d, %s",
1189 QDF_MAC_ADDR_REF(mld_addr.bytes),
1190 session->eht_config.support_320mhz_6ghz,
1191 session->eht_config.num_sounding_dim_320mhz, is_emlsr,
1192 partner_info->num_partner_links,
1193 len ? buffer : '\0');
1194 }
1195 #endif
1196
1197 /**
1198 * pe_get_active_session_count() - function to return active pe session count
1199 *
1200 * @mac_ctx: pointer to global mac structure
1201 *
1202 * returns number of active pe session count
1203 *
1204 * Return: 0 if there are no active sessions else return number of active
1205 * sessions
1206 */
pe_get_active_session_count(struct mac_context * mac_ctx)1207 uint8_t pe_get_active_session_count(struct mac_context *mac_ctx)
1208 {
1209 uint8_t i, active_session_count = 0;
1210
1211 for (i = 0; i < mac_ctx->lim.maxBssId; i++)
1212 if (mac_ctx->lim.gpSession[i].valid)
1213 active_session_count++;
1214
1215 return active_session_count;
1216 }
1217