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