xref: /wlan-dirver/qcacld-3.0/core/sme/src/csr/csr_api_roam.c (revision 1fee2fd0aade1d97f7426d6ff7ab16571e512484)
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  * DOC: csr_api_roam.c
22  *
23  * Implementation for the Common Roaming interfaces.
24  */
25 #include "ani_global.h"          /* for struct mac_context **/
26 #include "wma_types.h"
27 #include "wma_if.h"          /* for STA_INVALID_IDX. */
28 #include "csr_inside_api.h"
29 #include <include/wlan_psoc_mlme.h>
30 #include "sme_trace.h"
31 #include "sme_qos_internal.h"
32 #include "sme_inside.h"
33 #include "host_diag_core_event.h"
34 #include "host_diag_core_log.h"
35 #include "csr_api.h"
36 #include "csr_internal.h"
37 #include "cds_reg_service.h"
38 #include "mac_trace.h"
39 #include "cds_regdomain.h"
40 #include "cds_utils.h"
41 #include "sir_types.h"
42 #include "cfg_ucfg_api.h"
43 #include "sme_power_save_api.h"
44 #include "wma.h"
45 #include "wlan_policy_mgr_api.h"
46 #include "sme_nan_datapath.h"
47 #include "pld_common.h"
48 #include "wlan_reg_services_api.h"
49 #include "qdf_crypto.h"
50 #include <wlan_logging_sock_svc.h>
51 #include "wlan_objmgr_psoc_obj.h"
52 #include <wlan_scan_ucfg_api.h>
53 #include <wlan_cp_stats_mc_ucfg_api.h>
54 #include <wlan_tdls_tgt_api.h>
55 #include <wlan_cfg80211_scan.h>
56 #include <wlan_scan_public_structs.h>
57 #include <wlan_action_oui_public_struct.h>
58 #include <wlan_action_oui_ucfg_api.h>
59 #include "wlan_mlme_api.h"
60 #include "wlan_mlme_ucfg_api.h"
61 #include <wlan_utility.h>
62 #include "cfg_mlme.h"
63 #include "wlan_mlme_public_struct.h"
64 #include <wlan_crypto_global_api.h>
65 #include "wlan_qct_sys.h"
66 #include "wlan_dlm_api.h"
67 #include "wlan_policy_mgr_i.h"
68 #include "wlan_scan_utils_api.h"
69 #include "wlan_p2p_cfg_api.h"
70 #include "cfg_nan_api.h"
71 #include "nan_ucfg_api.h"
72 #include <../../core/src/wlan_cm_vdev_api.h>
73 #include "wlan_reg_ucfg_api.h"
74 
75 #include <ol_defines.h>
76 #include "wlan_pkt_capture_ucfg_api.h"
77 #include "wlan_psoc_mlme_api.h"
78 #include "wlan_cm_roam_api.h"
79 #include "wlan_if_mgr_public_struct.h"
80 #include "wlan_if_mgr_ucfg_api.h"
81 #include "wlan_if_mgr_roam.h"
82 #include "wlan_roam_debug.h"
83 #include "wlan_cm_roam_public_struct.h"
84 #include "wlan_mlme_twt_api.h"
85 #include <wlan_serialization_api.h>
86 #include <wlan_vdev_mlme_ser_if.h>
87 #include "wlan_mlo_mgr_sta.h"
88 #include "wlan_mlo_mgr_roam.h"
89 
90 #define MAX_PWR_FCC_CHAN_12 8
91 #define MAX_PWR_FCC_CHAN_13 2
92 #define MAX_CB_VALUE_IN_INI (2)
93 
94 #define MAX_SOCIAL_CHANNELS  3
95 
96 /* packet dump timer duration of 60 secs */
97 #define PKT_DUMP_TIMER_DURATION 60
98 
99 #ifdef WLAN_FEATURE_SAE
100 /**
101  * csr_sae_callback - Update SAE info to CSR roam session
102  * @mac_ctx: MAC context
103  * @msg_ptr: pointer to SAE message
104  *
105  * API to update SAE info to roam csr session
106  *
107  * Return: QDF_STATUS
108  */
109 static QDF_STATUS csr_sae_callback(struct mac_context *mac_ctx,
110 		tSirSmeRsp *msg_ptr)
111 {
112 	struct csr_roam_info *roam_info;
113 	uint32_t session_id;
114 	struct sir_sae_info *sae_info;
115 
116 	sae_info = (struct sir_sae_info *) msg_ptr;
117 	if (!sae_info) {
118 		sme_err("SAE info is NULL");
119 		return QDF_STATUS_E_FAILURE;
120 	}
121 
122 	sme_debug("vdev_id %d "QDF_MAC_ADDR_FMT,
123 		sae_info->vdev_id,
124 		QDF_MAC_ADDR_REF(sae_info->peer_mac_addr.bytes));
125 
126 	session_id = sae_info->vdev_id;
127 	if (session_id == WLAN_UMAC_VDEV_ID_MAX)
128 		return QDF_STATUS_E_INVAL;
129 
130 	roam_info = qdf_mem_malloc(sizeof(*roam_info));
131 	if (!roam_info)
132 		return QDF_STATUS_E_FAILURE;
133 
134 	roam_info->sae_info = sae_info;
135 
136 	csr_roam_call_callback(mac_ctx, session_id, roam_info,
137 			       eCSR_ROAM_SAE_COMPUTE, eCSR_ROAM_RESULT_NONE);
138 	qdf_mem_free(roam_info);
139 
140 	return QDF_STATUS_SUCCESS;
141 }
142 #else
143 static inline QDF_STATUS csr_sae_callback(struct mac_context *mac_ctx,
144 		tSirSmeRsp *msg_ptr)
145 {
146 	return QDF_STATUS_SUCCESS;
147 }
148 #endif
149 
150 static const uint32_t
151 social_channel_freq[MAX_SOCIAL_CHANNELS] = { 2412, 2437, 2462 };
152 
153 static void init_config_param(struct mac_context *mac);
154 static QDF_STATUS csr_roam_open(struct mac_context *mac);
155 static QDF_STATUS csr_roam_close(struct mac_context *mac);
156 static QDF_STATUS csr_init11d_info(struct mac_context *mac, tCsr11dinfo *ps11dinfo);
157 static QDF_STATUS csr_init_channel_power_list(struct mac_context *mac,
158 					      tCsr11dinfo *ps11dinfo);
159 static QDF_STATUS csr_roam_free_connected_info(struct mac_context *mac,
160 					       struct csr_roam_connectedinfo *
161 					       pConnectedInfo);
162 static void csr_init_session(struct mac_context *mac, uint32_t sessionId);
163 
164 static void csr_init_operating_classes(struct mac_context *mac);
165 
166 static void csr_add_len_of_social_channels(struct mac_context *mac,
167 		uint8_t *num_chan);
168 static void csr_add_social_channels(struct mac_context *mac,
169 		tSirUpdateChanList *chan_list, struct csr_scanstruct *pScan,
170 		uint8_t *num_chan);
171 
172 #ifdef WLAN_ALLOCATE_GLOBAL_BUFFERS_DYNAMICALLY
173 static struct csr_roam_session *csr_roam_roam_session;
174 
175 /* Allocate and initialize global variables */
176 static QDF_STATUS csr_roam_init_globals(struct mac_context *mac)
177 {
178 	uint32_t buf_size;
179 	QDF_STATUS status;
180 
181 	buf_size = WLAN_MAX_VDEVS * sizeof(struct csr_roam_session);
182 
183 	csr_roam_roam_session = qdf_mem_malloc(buf_size);
184 	if (csr_roam_roam_session) {
185 		mac->roam.roamSession = csr_roam_roam_session;
186 		status = QDF_STATUS_SUCCESS;
187 	} else {
188 		status = QDF_STATUS_E_NOMEM;
189 	}
190 
191 	return status;
192 }
193 
194 /* Free memory allocated dynamically */
195 static inline void csr_roam_free_globals(void)
196 {
197 	qdf_mem_free(csr_roam_roam_session);
198 	csr_roam_roam_session = NULL;
199 }
200 
201 #else /* WLAN_ALLOCATE_GLOBAL_BUFFERS_DYNAMICALLY */
202 static struct csr_roam_session csr_roam_roam_session[WLAN_MAX_VDEVS];
203 
204 /* Initialize global variables */
205 static QDF_STATUS csr_roam_init_globals(struct mac_context *mac)
206 {
207 	qdf_mem_zero(&csr_roam_roam_session,
208 		     sizeof(csr_roam_roam_session));
209 	mac->roam.roamSession = csr_roam_roam_session;
210 
211 	return QDF_STATUS_SUCCESS;
212 }
213 
214 static inline void csr_roam_free_globals(void)
215 {
216 }
217 #endif /* WLAN_ALLOCATE_GLOBAL_BUFFERS_DYNAMICALLY */
218 
219 static void csr_roam_de_init_globals(struct mac_context *mac)
220 {
221 	csr_roam_free_globals();
222 	mac->roam.roamSession = NULL;
223 }
224 
225 /**
226  * csr_roam_lost_link - Process lost link indication
227  * @mac: MAC context
228  * @session_id: Session id of the current session
229  * @type: Type of the indication
230  * @sir_msg: sme response message
231  *
232  * Return: QDF_STATUS
233  */
234 static
235 QDF_STATUS csr_roam_lost_link(struct mac_context *mac, uint32_t session_id,
236 			      uint32_t type, tSirSmeRsp *sir_msg)
237 {
238 	QDF_STATUS status = QDF_STATUS_SUCCESS;
239 	struct deauth_ind *deauth_ind_msg = NULL;
240 	struct disassoc_ind *disassoc_ind_msg = NULL;
241 
242 	sme_debug("vdev_id %d type %d ", session_id, type);
243 
244 	if (type == eWNI_SME_DISASSOC_IND) {
245 		disassoc_ind_msg = (struct disassoc_ind *)sir_msg;
246 		status = csr_send_mb_disassoc_cnf_msg(mac, disassoc_ind_msg);
247 	} else if (type == eWNI_SME_DEAUTH_IND) {
248 		deauth_ind_msg = (struct deauth_ind *)sir_msg;
249 		status = csr_send_mb_deauth_cnf_msg(mac, deauth_ind_msg);
250 	}
251 
252 	return status;
253 }
254 
255 /**
256  * csr_process_deauth_disassoc_cmd - Process deauth/disassoc command
257  * @mac: MAC context
258  * @sme_cmd: sme command which needs to be processed
259  *
260  * This function processes deauth or disassoc command
261  *
262  * Return: None
263  */
264 static void csr_process_deauth_disassoc_cmd(struct mac_context *mac,
265 					    tSmeCmd *sme_cmd)
266 {
267 	if (sme_cmd->u.roamCmd.roamReason == eCsrForcedDisassocSta) {
268 		sme_debug("Disassoc vdev_id %d with reason: %d peer "
269 			  QDF_MAC_ADDR_FMT, sme_cmd->vdev_id,
270 			  sme_cmd->u.roamCmd.reason,
271 			  QDF_MAC_ADDR_REF(sme_cmd->u.roamCmd.peerMac));
272 		csr_send_mb_disassoc_req_msg(mac, sme_cmd->vdev_id,
273 					     sme_cmd->u.roamCmd.peerMac,
274 					     sme_cmd->u.roamCmd.reason);
275 	} else if (sme_cmd->u.roamCmd.roamReason == eCsrForcedDeauthSta) {
276 		sme_debug("Deauth vdev_id %d with reason: %d peer "
277 			  QDF_MAC_ADDR_FMT, sme_cmd->vdev_id,
278 			  sme_cmd->u.roamCmd.reason,
279 			  QDF_MAC_ADDR_REF(sme_cmd->u.roamCmd.peerMac));
280 		csr_send_mb_deauth_req_msg(mac, sme_cmd->vdev_id,
281 					   sme_cmd->u.roamCmd.peerMac,
282 					   sme_cmd->u.roamCmd.reason);
283 	} else {
284 		sme_info("Invalid command, vdev_id %d reason: %d peer "
285 			  QDF_MAC_ADDR_FMT, sme_cmd->vdev_id,
286 			  sme_cmd->u.roamCmd.reason,
287 			  QDF_MAC_ADDR_REF(sme_cmd->u.roamCmd.peerMac));
288 	}
289 }
290 
291 /**
292  * csr_process_wmm_status_change_cmd - Process wmm status change command
293  * @mac: MAC context
294  * @sme_cmd: sme command which needs to be processed
295  *
296  * Return: None
297  */
298 static void csr_process_wmm_status_change_cmd(struct mac_context *mac,
299 					      tSmeCmd *sme_cmd)
300 {
301 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
302 	tSirSmeRsp *sir_msg;
303 
304 	if (sme_cmd->u.wmStatusChangeCmd.Type == eCsrDisassociated) {
305 		sir_msg =
306 			(tSirSmeRsp *)&sme_cmd->u.wmStatusChangeCmd.u.
307 			DisassocIndMsg;
308 		status = csr_roam_lost_link(mac, sme_cmd->vdev_id,
309 					    eWNI_SME_DISASSOC_IND,
310 					    sir_msg);
311 	} else if (sme_cmd->u.wmStatusChangeCmd.Type == eCsrDeauthenticated) {
312 		sir_msg = (tSirSmeRsp *)&sme_cmd->u.wmStatusChangeCmd.u.
313 								DeauthIndMsg;
314 		status = csr_roam_lost_link(mac, sme_cmd->vdev_id,
315 					    eWNI_SME_DEAUTH_IND,
316 					    sir_msg);
317 	}
318 	if (QDF_IS_STATUS_ERROR(status)) {
319 		sme_info("Failed to issue lost link command, status %d",
320 			 status);
321 		/*
322 		 * As status returned is not success, there is nothing else
323 		 * left to do so release WM status change command here.
324 		 */
325 		csr_roam_wm_status_change_complete(mac, sme_cmd->vdev_id);
326 	}
327 }
328 
329 /**
330  * csr_get_active_peer_disconnect_command - Get active peer disconnect command
331  * from serialization.
332  * @mac: MAC context
333  * @vdev_id: Vdev id for which active command needs to be return
334  *
335  * Return: None
336  */
337 static tSmeCmd *csr_get_active_peer_disconnect_command(struct mac_context *mac,
338 						       uint8_t vdev_id)
339 {
340 	tSmeCmd *sme_cmd;
341 
342 	sme_cmd = wlan_serialization_get_active_cmd(
343 						mac->psoc, vdev_id,
344 						WLAN_SER_CMD_FORCE_DEAUTH_STA);
345 	if (sme_cmd)
346 		return sme_cmd;
347 
348 	sme_cmd = wlan_serialization_get_active_cmd(
349 					mac->psoc, vdev_id,
350 					WLAN_SER_CMD_FORCE_DISASSOC_STA);
351 	if (sme_cmd)
352 		return sme_cmd;
353 
354 	return wlan_serialization_get_active_cmd(mac->psoc, vdev_id,
355 						 WLAN_SER_CMD_WM_STATUS_CHANGE);
356 }
357 
358 /**
359  * csr_continue_peer_disconnect_after_get_stats - Continue peer disconnect after
360  * getting peer disconnect stats
361  * @mac: MAC context
362  *
363  * Process the active serialization command after getting disconnect peer
364  * stats or after peer stats request gets timed out
365  *
366  * Return: None
367  */
368 static void
369 csr_continue_peer_disconnect_after_get_stats(struct mac_context *mac)
370 {
371 	tSmeCmd *sme_cmd;
372 	QDF_STATUS status;
373 	struct wlan_mlme_psoc_ext_obj *mlme_obj;
374 
375 	mlme_obj = mlme_get_psoc_ext_obj(mac->psoc);
376 	if (!mlme_obj) {
377 		sme_err("NULL mlme psoc object");
378 		return;
379 	}
380 
381 	status = sme_acquire_global_lock(&mac->sme);
382 	if (QDF_IS_STATUS_ERROR(status)) {
383 		sme_err("can't acquire sme global lock");
384 		return;
385 	}
386 
387 	sme_cmd = csr_get_active_peer_disconnect_command(
388 				mac,
389 				mlme_obj->disconnect_stats_param.vdev_id);
390 	if (!sme_cmd) {
391 		sme_err("sme_cmd is NULL");
392 		goto release_lock;
393 	}
394 
395 	if (qdf_atomic_inc_return(
396 		&mlme_obj->disconnect_stats_param.is_disconn_stats_completed) >
397 		1) {
398 		sme_info("Command %d already in process", sme_cmd->command);
399 		goto release_lock;
400 	}
401 
402 	switch (sme_cmd->command) {
403 	case eSmeCommandRoam:
404 		csr_process_deauth_disassoc_cmd(mac, sme_cmd);
405 		break;
406 
407 	case eSmeCommandWmStatusChange:
408 		csr_process_wmm_status_change_cmd(mac, sme_cmd);
409 		break;
410 	default:
411 		sme_info("Invalid command %d vdev_id %d", sme_cmd->command,
412 			 mlme_obj->disconnect_stats_param.vdev_id);
413 	}
414 release_lock:
415 	sme_release_global_lock(&mac->sme);
416 }
417 
418 /**
419  * csr_disconnect_stats_timer_cb - Disconnect stats timer callback
420  * @user_data: Void pointer to mac context
421  *
422  * Return: None
423  */
424 static void csr_disconnect_stats_timer_cb(void *user_data)
425 {
426 	struct mac_context *mac = (struct mac_context *)user_data;
427 
428 	if (!mac) {
429 		sme_err("Invalid mac ctx");
430 		return;
431 	}
432 
433 	sme_debug("Disconnect peer stats timed out");
434 	csr_continue_peer_disconnect_after_get_stats(mac);
435 }
436 
437 /**
438  * csr_init_disconnect_stats_timer - Init Disconnect stats timer
439  * @mac: MAC context
440  *
441  * Return: None
442  */
443 static void csr_init_disconnect_stats_timer(struct mac_context *mac)
444 {
445 	struct wlan_mlme_psoc_ext_obj *mlme_obj;
446 
447 	mlme_obj = mlme_get_psoc_ext_obj(mac->psoc);
448 	if (!mlme_obj) {
449 		sme_err("NULL mlme psoc object");
450 		return;
451 	}
452 
453 	qdf_mc_timer_init(&mlme_obj->disconnect_stats_param.disconn_stats_timer,
454 			  QDF_TIMER_TYPE_SW,
455 			  csr_disconnect_stats_timer_cb, mac);
456 
457 	qdf_atomic_init(
458 		&mlme_obj->disconnect_stats_param.is_disconn_stats_completed);
459 }
460 
461 /**
462  * csr_deinit_disconnect_stats_timer - Deinit Disconnect stats timer
463  * @mac: MAC context
464  *
465  * Return: None
466  */
467 static void csr_deinit_disconnect_stats_timer(struct mac_context *mac)
468 {
469 	struct wlan_mlme_psoc_ext_obj *mlme_obj;
470 
471 	mlme_obj = mlme_get_psoc_ext_obj(mac->psoc);
472 	if (!mlme_obj) {
473 		sme_err("NULL mlme psoc object");
474 		return;
475 	}
476 
477 	if (QDF_TIMER_STATE_RUNNING ==
478 		qdf_mc_timer_get_current_state(
479 			&mlme_obj->disconnect_stats_param.disconn_stats_timer))
480 		qdf_mc_timer_stop(
481 			&mlme_obj->disconnect_stats_param.disconn_stats_timer);
482 
483 	qdf_mc_timer_destroy(
484 			&mlme_obj->disconnect_stats_param.disconn_stats_timer);
485 }
486 
487 QDF_STATUS csr_open(struct mac_context *mac)
488 {
489 	QDF_STATUS status = QDF_STATUS_SUCCESS;
490 	uint32_t i;
491 
492 	do {
493 		/* Initialize CSR Roam Globals */
494 		status = csr_roam_init_globals(mac);
495 		if (!QDF_IS_STATUS_SUCCESS(status))
496 			break;
497 
498 		for (i = 0; i < WLAN_MAX_VDEVS; i++)
499 			csr_roam_state_change(mac, eCSR_ROAMING_STATE_STOP, i);
500 
501 		init_config_param(mac);
502 		status = csr_scan_open(mac);
503 		if (!QDF_IS_STATUS_SUCCESS(status)) {
504 			csr_roam_free_globals();
505 			break;
506 		}
507 		status = csr_roam_open(mac);
508 		if (!QDF_IS_STATUS_SUCCESS(status)) {
509 			csr_roam_free_globals();
510 			break;
511 		}
512 		csr_init_disconnect_stats_timer(mac);
513 	} while (0);
514 
515 	return status;
516 }
517 
518 QDF_STATUS csr_init_chan_list(struct mac_context *mac)
519 {
520 	QDF_STATUS status;
521 	uint8_t reg_cc[REG_ALPHA2_LEN + 1];
522 
523 	wlan_reg_read_current_country(mac->psoc, reg_cc);
524 	sme_debug("init time country code %.2s", reg_cc);
525 
526 	status = csr_get_channel_and_power_list(mac);
527 
528 	return status;
529 }
530 
531 QDF_STATUS csr_set_channels(struct mac_context *mac,
532 			    struct csr_config_params *pParam)
533 {
534 	QDF_STATUS status = QDF_STATUS_SUCCESS;
535 	uint8_t index = 0;
536 
537 	for (index = 0; index < mac->scan.base_channels.numChannels;
538 	     index++) {
539 		pParam->Csr11dinfo.Channels.channel_freq_list[index] =
540 			mac->scan.base_channels.channel_freq_list[index];
541 		pParam->Csr11dinfo.ChnPower[index].first_chan_freq =
542 			mac->scan.base_channels.channel_freq_list[index];
543 		pParam->Csr11dinfo.ChnPower[index].numChannels = 1;
544 		pParam->Csr11dinfo.ChnPower[index].maxtxPower =
545 			mac->scan.defaultPowerTable[index].tx_power;
546 	}
547 	pParam->Csr11dinfo.Channels.numChannels =
548 		mac->scan.base_channels.numChannels;
549 
550 	return status;
551 }
552 
553 QDF_STATUS csr_close(struct mac_context *mac)
554 {
555 	QDF_STATUS status = QDF_STATUS_SUCCESS;
556 
557 	csr_deinit_disconnect_stats_timer(mac);
558 
559 	csr_roam_close(mac);
560 	csr_scan_close(mac);
561 	/* DeInit Globals */
562 	csr_roam_de_init_globals(mac);
563 	return status;
564 }
565 
566 static int8_t
567 csr_find_channel_pwr(struct channel_power *pdefaultPowerTable,
568 		     uint32_t chan_freq)
569 {
570 	uint8_t i;
571 	/* TODO: if defaultPowerTable is guaranteed to be in ascending */
572 	/* order of channel numbers, we can employ binary search */
573 	for (i = 0; i < CFG_VALID_CHANNEL_LIST_LEN; i++) {
574 		if (pdefaultPowerTable[i].center_freq == chan_freq)
575 			return pdefaultPowerTable[i].tx_power;
576 	}
577 	/* could not find the channel list in default list */
578 	/* this should not have occurred */
579 	QDF_ASSERT(0);
580 	return 0;
581 }
582 
583 /**
584  * csr_roam_arrange_ch_list() - Updates the channel list modified with greedy
585  * order for 5 Ghz preference and DFS channels.
586  * @mac_ctx: pointer to mac context.
587  * @chan_list:    channel list updated with greedy channel order.
588  * @num_channel:  Number of channels in list
589  *
590  * To allow Early Stop Roaming Scan feature to co-exist with 5G preference,
591  * this function moves 5G channels ahead of 2G channels. This function can
592  * also move 2G channels, ahead of DFS channel or vice versa. Order is
593  * maintained among same category channels
594  *
595  * Return: None
596  */
597 static void csr_roam_arrange_ch_list(struct mac_context *mac_ctx,
598 			tSirUpdateChanParam *chan_list, uint8_t num_channel)
599 {
600 	bool prefer_5g = CSR_IS_ROAM_PREFER_5GHZ(mac_ctx);
601 	bool prefer_dfs = CSR_IS_DFS_CH_ROAM_ALLOWED(mac_ctx);
602 	int i, j = 0;
603 	tSirUpdateChanParam *tmp_list = NULL;
604 
605 	if (!prefer_5g)
606 		return;
607 
608 	tmp_list = qdf_mem_malloc(sizeof(tSirUpdateChanParam) * num_channel);
609 	if (!tmp_list)
610 		return;
611 
612 	/* Fist copy Non-DFS 5g channels */
613 	for (i = 0; i < num_channel; i++) {
614 		if (WLAN_REG_IS_5GHZ_CH_FREQ(chan_list[i].freq) &&
615 			!wlan_reg_is_dfs_for_freq(mac_ctx->pdev,
616 						  chan_list[i].freq)) {
617 			qdf_mem_copy(&tmp_list[j++],
618 				&chan_list[i], sizeof(tSirUpdateChanParam));
619 			chan_list[i].freq = 0;
620 		}
621 	}
622 	if (prefer_dfs) {
623 		/* next copy DFS channels (remaining channels in 5G) */
624 		for (i = 0; i < num_channel; i++) {
625 			if (WLAN_REG_IS_5GHZ_CH_FREQ(chan_list[i].freq)) {
626 				qdf_mem_copy(&tmp_list[j++], &chan_list[i],
627 					sizeof(tSirUpdateChanParam));
628 				chan_list[i].freq = 0;
629 			}
630 		}
631 	} else {
632 		/* next copy 2G channels */
633 		for (i = 0; i < num_channel; i++) {
634 			if (WLAN_REG_IS_24GHZ_CH_FREQ(chan_list[i].freq)) {
635 				qdf_mem_copy(&tmp_list[j++], &chan_list[i],
636 					sizeof(tSirUpdateChanParam));
637 				chan_list[i].freq = 0;
638 			}
639 		}
640 	}
641 	/* copy rest of the channels in same order to tmp list */
642 	for (i = 0; i < num_channel; i++) {
643 		if (chan_list[i].freq) {
644 			qdf_mem_copy(&tmp_list[j++], &chan_list[i],
645 				sizeof(tSirUpdateChanParam));
646 			chan_list[i].freq = 0;
647 		}
648 	}
649 	/* copy tmp list to original channel list buffer */
650 	qdf_mem_copy(chan_list, tmp_list,
651 				 sizeof(tSirUpdateChanParam) * num_channel);
652 	qdf_mem_free(tmp_list);
653 }
654 
655 /**
656  * csr_roam_sort_channel_for_early_stop() - Sort the channels
657  * @mac_ctx:        mac global context
658  * @chan_list:      Original channel list from the upper layers
659  * @num_channel:    Number of original channels
660  *
661  * For Early stop scan feature, the channel list should be in an order,
662  * where-in there is a maximum chance to detect an AP in the initial
663  * channels in the list so that the scanning can be stopped early as the
664  * feature demands.
665  * Below fixed greedy channel list has been provided
666  * based on most of the enterprise wifi installations across the globe.
667  *
668  * Identify all the greedy channels within the channel list from user space.
669  * Identify all the non-greedy channels in the user space channel list.
670  * Merge greedy channels followed by non-greedy channels back into the
671  * chan_list.
672  *
673  * Return: None
674  */
675 static void csr_roam_sort_channel_for_early_stop(struct mac_context *mac_ctx,
676 			tSirUpdateChanList *chan_list, uint8_t num_channel)
677 {
678 	tSirUpdateChanList *chan_list_greedy, *chan_list_non_greedy;
679 	uint8_t i, j;
680 	static const uint32_t fixed_greedy_freq_list[] = {2412, 2437, 2462,
681 		5180, 5240, 5200, 5220, 2457, 2417, 2452, 5745, 5785, 5805,
682 		2422, 2427, 2447, 5765, 5825, 2442, 2432, 5680, 5700, 5260,
683 		5580, 5280, 5520, 5320, 5300, 5500, 5600, 2472, 2484, 5560,
684 		5660, 5755, 5775};
685 	uint8_t num_fixed_greedy_chan;
686 	uint8_t num_greedy_chan = 0;
687 	uint8_t num_non_greedy_chan = 0;
688 	uint8_t match_found = false;
689 	uint32_t buf_size;
690 
691 	buf_size = sizeof(tSirUpdateChanList) +
692 		(sizeof(tSirUpdateChanParam) * num_channel);
693 	chan_list_greedy = qdf_mem_malloc(buf_size);
694 	chan_list_non_greedy = qdf_mem_malloc(buf_size);
695 	if (!chan_list_greedy || !chan_list_non_greedy)
696 		goto scan_list_sort_error;
697 	/*
698 	 * fixed_greedy_freq_list is an evaluated freq list based on most of
699 	 * the enterprise wifi deployments and the order of the channels
700 	 * determines the highest possibility of finding an AP.
701 	 * chan_list is the channel list provided by upper layers based on the
702 	 * regulatory domain.
703 	 */
704 	num_fixed_greedy_chan = sizeof(fixed_greedy_freq_list) /
705 							sizeof(uint32_t);
706 	/*
707 	 * Browse through the chan_list and put all the non-greedy channels
708 	 * into a separate list by name chan_list_non_greedy
709 	 */
710 	for (i = 0; i < num_channel; i++) {
711 		for (j = 0; j < num_fixed_greedy_chan; j++) {
712 			if (chan_list->chanParam[i].freq ==
713 					 fixed_greedy_freq_list[j]) {
714 				match_found = true;
715 				break;
716 			}
717 		}
718 		if (!match_found) {
719 			qdf_mem_copy(
720 			  &chan_list_non_greedy->chanParam[num_non_greedy_chan],
721 			  &chan_list->chanParam[i],
722 			  sizeof(tSirUpdateChanParam));
723 			num_non_greedy_chan++;
724 		} else {
725 			match_found = false;
726 		}
727 	}
728 	/*
729 	 * Browse through the fixed_greedy_chan_list and put all the greedy
730 	 * channels in the chan_list into a separate list by name
731 	 * chan_list_greedy
732 	 */
733 	for (i = 0; i < num_fixed_greedy_chan; i++) {
734 		for (j = 0; j < num_channel; j++) {
735 			if (fixed_greedy_freq_list[i] ==
736 				chan_list->chanParam[j].freq) {
737 				qdf_mem_copy(
738 				  &chan_list_greedy->chanParam[num_greedy_chan],
739 				  &chan_list->chanParam[j],
740 				  sizeof(tSirUpdateChanParam));
741 				num_greedy_chan++;
742 				break;
743 			}
744 		}
745 	}
746 	sme_debug("greedy=%d, non-greedy=%d, tot=%d", num_greedy_chan,
747 		  num_non_greedy_chan, num_channel);
748 	if ((num_greedy_chan + num_non_greedy_chan) != num_channel) {
749 		sme_err("incorrect sorting of channels");
750 		goto scan_list_sort_error;
751 	}
752 	/* Copy the Greedy channels first */
753 	i = 0;
754 	qdf_mem_copy(&chan_list->chanParam[i],
755 		&chan_list_greedy->chanParam[i],
756 		num_greedy_chan * sizeof(tSirUpdateChanParam));
757 	/* Copy the remaining Non Greedy channels */
758 	i = num_greedy_chan;
759 	j = 0;
760 	qdf_mem_copy(&chan_list->chanParam[i],
761 		&chan_list_non_greedy->chanParam[j],
762 		num_non_greedy_chan * sizeof(tSirUpdateChanParam));
763 
764 	/* Update channel list for 5g preference and allow DFS roam */
765 	csr_roam_arrange_ch_list(mac_ctx, chan_list->chanParam, num_channel);
766 scan_list_sort_error:
767 	qdf_mem_free(chan_list_greedy);
768 	qdf_mem_free(chan_list_non_greedy);
769 }
770 
771 /**
772  * csr_emu_chan_req() - update the required channel list for emulation
773  * @channel: channel number to check
774  *
775  * To reduce scan time during emulation platforms, this function
776  * restricts the scanning to be done on selected channels
777  *
778  * Return: QDF_STATUS enumeration
779  */
780 #ifdef QCA_WIFI_EMULATION
781 #define SCAN_CHAN_LIST_5G_LEN 6
782 #define SCAN_CHAN_LIST_2G_LEN 3
783 #define SCAN_CHAN_LIST_6G_LEN 3
784 static const uint16_t
785 csr_scan_chan_list_5g[SCAN_CHAN_LIST_5G_LEN] = { 5180, 5220, 5260, 5280, 5700, 5745 };
786 static const uint16_t
787 csr_scan_chan_list_2g[SCAN_CHAN_LIST_2G_LEN] = { 2412, 2437, 2462 };
788 static const uint16_t
789 csr_scan_chan_list_6g[SCAN_CHAN_LIST_6G_LEN] = { 6055, 6135, 6215 };
790 
791 static QDF_STATUS csr_emu_chan_req(uint32_t channel)
792 {
793 	int i;
794 
795 	if (WLAN_REG_IS_24GHZ_CH_FREQ(channel)) {
796 		for (i = 0; i < QDF_ARRAY_SIZE(csr_scan_chan_list_2g); i++) {
797 			if (csr_scan_chan_list_2g[i] == channel)
798 				return QDF_STATUS_SUCCESS;
799 		}
800 	} else if (WLAN_REG_IS_5GHZ_CH_FREQ(channel)) {
801 		for (i = 0; i < QDF_ARRAY_SIZE(csr_scan_chan_list_5g); i++) {
802 			if (csr_scan_chan_list_5g[i] == channel)
803 				return QDF_STATUS_SUCCESS;
804 		}
805 	} else if (WLAN_REG_IS_6GHZ_CHAN_FREQ(channel)) {
806 		for (i = 0; i < QDF_ARRAY_SIZE(csr_scan_chan_list_6g); i++) {
807 			if (csr_scan_chan_list_6g[i] == channel)
808 				return QDF_STATUS_SUCCESS;
809 		}
810 	}
811 	return QDF_STATUS_E_FAILURE;
812 }
813 #else
814 static QDF_STATUS csr_emu_chan_req(uint32_t channel_num)
815 {
816 	return QDF_STATUS_SUCCESS;
817 }
818 #endif
819 
820 #ifdef WLAN_ENABLE_SOCIAL_CHANNELS_5G_ONLY
821 static void csr_add_len_of_social_channels(struct mac_context *mac,
822 		uint8_t *num_chan)
823 {
824 	uint8_t i;
825 	uint8_t no_chan = *num_chan;
826 
827 	sme_debug("add len of social channels, before adding - num_chan:%hu",
828 			*num_chan);
829 	if (CSR_IS_5G_BAND_ONLY(mac)) {
830 		for (i = 0; i < MAX_SOCIAL_CHANNELS; i++) {
831 			if (wlan_reg_get_channel_state_for_pwrmode(
832 				mac->pdev, social_channel_freq[i],
833 				REG_CURRENT_PWR_MODE) ==
834 					CHANNEL_STATE_ENABLE)
835 				no_chan++;
836 		}
837 	}
838 	*num_chan = no_chan;
839 	sme_debug("after adding - num_chan:%hu", *num_chan);
840 }
841 
842 static void csr_add_social_channels(struct mac_context *mac,
843 		tSirUpdateChanList *chan_list, struct csr_scanstruct *pScan,
844 		uint8_t *num_chan)
845 {
846 	uint8_t i;
847 	uint8_t no_chan = *num_chan;
848 
849 	sme_debug("add social channels chan_list %pK, num_chan %hu", chan_list,
850 			*num_chan);
851 	if (CSR_IS_5G_BAND_ONLY(mac)) {
852 		for (i = 0; i < MAX_SOCIAL_CHANNELS; i++) {
853 			if (wlan_reg_get_channel_state_for_pwrmode(
854 					mac->pdev, social_channel_freq[i],
855 					REG_CURRENT_PWR_MODE) !=
856 					CHANNEL_STATE_ENABLE)
857 				continue;
858 			chan_list->chanParam[no_chan].freq =
859 				social_channel_freq[i];
860 			chan_list->chanParam[no_chan].pwr =
861 				csr_find_channel_pwr(pScan->defaultPowerTable,
862 						social_channel_freq[i]);
863 			chan_list->chanParam[no_chan].dfsSet = false;
864 			if (cds_is_5_mhz_enabled())
865 				chan_list->chanParam[no_chan].quarter_rate
866 					= 1;
867 			else if (cds_is_10_mhz_enabled())
868 				chan_list->chanParam[no_chan].half_rate = 1;
869 			no_chan++;
870 		}
871 		sme_debug("after adding -num_chan %hu", no_chan);
872 	}
873 	*num_chan = no_chan;
874 }
875 #else
876 static void csr_add_len_of_social_channels(struct mac_context *mac,
877 		uint8_t *num_chan)
878 {
879 	sme_debug("skip adding len of social channels");
880 }
881 static void csr_add_social_channels(struct mac_context *mac,
882 		tSirUpdateChanList *chan_list, struct csr_scanstruct *pScan,
883 		uint8_t *num_chan)
884 {
885 	sme_debug("skip social channels");
886 }
887 #endif
888 
889 /**
890  * csr_scan_event_handler() - callback for scan event
891  * @vdev: wlan objmgr vdev pointer
892  * @event: scan event
893  * @arg: global mac context pointer
894  *
895  * Return: void
896  */
897 static void csr_scan_event_handler(struct wlan_objmgr_vdev *vdev,
898 					    struct scan_event *event,
899 					    void *arg)
900 {
901 	bool success = false;
902 	QDF_STATUS lock_status;
903 	struct mac_context *mac = arg;
904 
905 	if (!mac)
906 		return;
907 
908 	if (!util_is_scan_completed(event, &success))
909 		return;
910 
911 	lock_status = sme_acquire_global_lock(&mac->sme);
912 	if (QDF_IS_STATUS_ERROR(lock_status))
913 		return;
914 
915 	if (mac->scan.pending_channel_list_req)
916 		csr_update_channel_list(mac);
917 	sme_release_global_lock(&mac->sme);
918 }
919 
920 /**
921  * csr_update_roam_pcl_per_connected_sta_vdev() - Update roam pcl per connected
922  *                                                STA
923  * @psoc: pointer to psoc object
924  *
925  * Return: None
926  */
927 static void csr_update_roam_pcl_per_connected_sta_vdev(
928 						struct wlan_objmgr_psoc *psoc)
929 {
930 	struct wlan_objmgr_vdev *vdev;
931 	uint32_t vdev_id;
932 
933 	for (vdev_id = 0; vdev_id < WLAN_UMAC_PSOC_MAX_VDEVS; vdev_id++) {
934 		vdev =
935 		wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
936 						     WLAN_LEGACY_SME_ID);
937 
938 		if (!vdev)
939 			continue;
940 
941 		if (vdev->vdev_mlme.vdev_opmode != QDF_STA_MODE)
942 			goto next;
943 
944 		if (!wlan_cm_is_vdev_connected(vdev))
945 			goto next;
946 
947 		policy_mgr_set_pcl_for_existing_combo(psoc, PM_STA_MODE,
948 						      vdev_id);
949 next:
950 		wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID);
951 	}
952 }
953 
954 QDF_STATUS csr_update_channel_list(struct mac_context *mac)
955 {
956 	tSirUpdateChanList *pChanList;
957 	struct csr_scanstruct *pScan = &mac->scan;
958 	uint8_t numChan = pScan->base_channels.numChannels;
959 	uint8_t num_channel = 0;
960 	uint32_t bufLen;
961 	struct scheduler_msg msg = {0};
962 	uint8_t i;
963 	uint8_t channel_state;
964 	uint16_t unsafe_chan[NUM_CHANNELS];
965 	uint16_t unsafe_chan_cnt = 0;
966 	uint16_t cnt = 0;
967 	uint32_t  channel_freq;
968 	bool is_unsafe_chan;
969 	bool is_same_band;
970 	bool is_5mhz_enabled;
971 	bool is_10mhz_enabled;
972 	enum scm_scan_status scan_status;
973 	QDF_STATUS lock_status;
974 	struct rso_roam_policy_params *roam_policy;
975 	struct wlan_mlme_psoc_ext_obj *mlme_obj;
976 
977 	qdf_device_t qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
978 
979 	if (!qdf_ctx)
980 		return QDF_STATUS_E_FAILURE;
981 
982 	mlme_obj = mlme_get_psoc_ext_obj(mac->psoc);
983 	if (!mlme_obj)
984 		return QDF_STATUS_E_FAILURE;
985 	roam_policy = &mlme_obj->cfg.lfr.rso_user_config.policy_params;
986 	lock_status = sme_acquire_global_lock(&mac->sme);
987 	if (QDF_IS_STATUS_ERROR(lock_status))
988 		return lock_status;
989 
990 	if (mac->mlme_cfg->reg.enable_pending_chan_list_req) {
991 		scan_status = wlan_get_pdev_status(mac->pdev);
992 		if (scan_status == SCAN_IS_ACTIVE ||
993 		    scan_status == SCAN_IS_ACTIVE_AND_PENDING) {
994 			mac->scan.pending_channel_list_req = true;
995 			sme_release_global_lock(&mac->sme);
996 			sme_debug("scan in progress postpone channel list req ");
997 			return QDF_STATUS_SUCCESS;
998 		}
999 		mac->scan.pending_channel_list_req = false;
1000 	}
1001 	sme_release_global_lock(&mac->sme);
1002 
1003 	pld_get_wlan_unsafe_channel(qdf_ctx->dev, unsafe_chan,
1004 		    &unsafe_chan_cnt,
1005 		    sizeof(unsafe_chan));
1006 
1007 	csr_add_len_of_social_channels(mac, &numChan);
1008 
1009 	bufLen = sizeof(tSirUpdateChanList) +
1010 		 (sizeof(tSirUpdateChanParam) * (numChan));
1011 
1012 	csr_init_operating_classes(mac);
1013 	pChanList = qdf_mem_malloc(bufLen);
1014 	if (!pChanList)
1015 		return QDF_STATUS_E_NOMEM;
1016 
1017 	is_5mhz_enabled = cds_is_5_mhz_enabled();
1018 	if (is_5mhz_enabled)
1019 		sme_nofl_debug("quarter_rate enabled");
1020 	is_10mhz_enabled = cds_is_10_mhz_enabled();
1021 	if (is_10mhz_enabled)
1022 		sme_nofl_debug("half_rate enabled");
1023 
1024 	for (i = 0; i < pScan->base_channels.numChannels; i++) {
1025 		if (QDF_STATUS_SUCCESS !=
1026 			csr_emu_chan_req(pScan->base_channels.channel_freq_list[i]))
1027 			continue;
1028 
1029 		channel_freq = pScan->base_channels.channel_freq_list[i];
1030 		/* Scan is not performed on DSRC channels*/
1031 		if (wlan_reg_is_dsrc_freq(channel_freq))
1032 			continue;
1033 
1034 		channel_state =
1035 			wlan_reg_get_channel_state_for_pwrmode(
1036 				mac->pdev, channel_freq,
1037 				REG_CURRENT_PWR_MODE);
1038 		if ((CHANNEL_STATE_ENABLE == channel_state) ||
1039 		    mac->scan.fEnableDFSChnlScan) {
1040 			if (wlan_reg_is_6ghz_chan_freq(channel_freq) &&
1041 			    !wlan_reg_is_6ghz_band_set(mac->pdev)) {
1042 				sme_debug("skip 6ghz frequency %d",
1043 					  channel_freq);
1044 				continue;
1045 			}
1046 			if ((roam_policy->dfs_mode ==
1047 				STA_ROAM_POLICY_DFS_DISABLED) &&
1048 				(channel_state == CHANNEL_STATE_DFS)) {
1049 				sme_debug("skip dfs channel frequency %d",
1050 					  channel_freq);
1051 				continue;
1052 			}
1053 			if (roam_policy->skip_unsafe_channels &&
1054 			    unsafe_chan_cnt) {
1055 				is_unsafe_chan = false;
1056 				for (cnt = 0; cnt < unsafe_chan_cnt; cnt++) {
1057 					if (unsafe_chan[cnt] == channel_freq) {
1058 						is_unsafe_chan = true;
1059 						break;
1060 					}
1061 				}
1062 				is_same_band =
1063 					(WLAN_REG_IS_24GHZ_CH_FREQ(
1064 							channel_freq) &&
1065 					roam_policy->sap_operating_band ==
1066 							BAND_2G) ||
1067 					(WLAN_REG_IS_5GHZ_CH_FREQ(
1068 							channel_freq) &&
1069 					roam_policy->sap_operating_band ==
1070 							BAND_5G);
1071 				if (is_unsafe_chan && is_same_band) {
1072 					sme_debug("ignoring unsafe channel freq %d",
1073 						  channel_freq);
1074 					continue;
1075 				}
1076 			}
1077 			pChanList->chanParam[num_channel].freq =
1078 				pScan->base_channels.channel_freq_list[i];
1079 			pChanList->chanParam[num_channel].pwr =
1080 				csr_find_channel_pwr(
1081 				pScan->defaultPowerTable,
1082 				pScan->base_channels.channel_freq_list[i]);
1083 
1084 			if (pScan->fcc_constraint) {
1085 				if (2467 ==
1086 					pScan->base_channels.channel_freq_list[i]) {
1087 					pChanList->chanParam[num_channel].pwr =
1088 						MAX_PWR_FCC_CHAN_12;
1089 					sme_debug("txpow for channel 12 is %d",
1090 						  MAX_PWR_FCC_CHAN_12);
1091 				}
1092 				if (2472 ==
1093 					pScan->base_channels.channel_freq_list[i]) {
1094 					pChanList->chanParam[num_channel].pwr =
1095 						MAX_PWR_FCC_CHAN_13;
1096 					sme_debug("txpow for channel 13 is %d",
1097 						  MAX_PWR_FCC_CHAN_13);
1098 				}
1099 			}
1100 
1101 			if (!ucfg_is_nan_allowed_on_freq(mac->pdev,
1102 				pChanList->chanParam[num_channel].freq))
1103 				pChanList->chanParam[num_channel].nan_disabled =
1104 					true;
1105 
1106 			if (CHANNEL_STATE_DFS == channel_state)
1107 				pChanList->chanParam[num_channel].dfsSet =
1108 					true;
1109 
1110 			pChanList->chanParam[num_channel].quarter_rate =
1111 							is_5mhz_enabled;
1112 
1113 			pChanList->chanParam[num_channel].half_rate =
1114 							is_10mhz_enabled;
1115 
1116 			num_channel++;
1117 		}
1118 	}
1119 
1120 	csr_add_social_channels(mac, pChanList, pScan, &num_channel);
1121 
1122 	if (mac->mlme_cfg->lfr.early_stop_scan_enable)
1123 		csr_roam_sort_channel_for_early_stop(mac, pChanList,
1124 						     num_channel);
1125 	else
1126 		sme_debug("Early Stop Scan Feature not supported");
1127 
1128 	if ((mac->roam.configParam.uCfgDot11Mode ==
1129 				eCSR_CFG_DOT11_MODE_AUTO) ||
1130 			(mac->roam.configParam.uCfgDot11Mode ==
1131 			 eCSR_CFG_DOT11_MODE_11AC) ||
1132 			(mac->roam.configParam.uCfgDot11Mode ==
1133 			 eCSR_CFG_DOT11_MODE_11AC_ONLY)) {
1134 		pChanList->vht_en = true;
1135 		if (mac->mlme_cfg->vht_caps.vht_cap_info.b24ghz_band)
1136 			pChanList->vht_24_en = true;
1137 	}
1138 	if ((mac->roam.configParam.uCfgDot11Mode ==
1139 				eCSR_CFG_DOT11_MODE_AUTO) ||
1140 			(mac->roam.configParam.uCfgDot11Mode ==
1141 			 eCSR_CFG_DOT11_MODE_11N) ||
1142 			(mac->roam.configParam.uCfgDot11Mode ==
1143 			 eCSR_CFG_DOT11_MODE_11N_ONLY)) {
1144 		pChanList->ht_en = true;
1145 	}
1146 	if ((mac->roam.configParam.uCfgDot11Mode == eCSR_CFG_DOT11_MODE_AUTO) ||
1147 	    (mac->roam.configParam.uCfgDot11Mode == eCSR_CFG_DOT11_MODE_11AX) ||
1148 	    (mac->roam.configParam.uCfgDot11Mode ==
1149 	     eCSR_CFG_DOT11_MODE_11AX_ONLY))
1150 		pChanList->he_en = true;
1151 #ifdef WLAN_FEATURE_11BE
1152 	if ((mac->roam.configParam.uCfgDot11Mode == eCSR_CFG_DOT11_MODE_AUTO) ||
1153 	    CSR_IS_CFG_DOT11_PHY_MODE_11BE(
1154 		mac->roam.configParam.uCfgDot11Mode) ||
1155 	    CSR_IS_CFG_DOT11_PHY_MODE_11BE_ONLY(
1156 		mac->roam.configParam.uCfgDot11Mode))
1157 		pChanList->eht_en = true;
1158 #endif
1159 
1160 	pChanList->numChan = num_channel;
1161 	mlme_store_fw_scan_channels(mac->psoc, pChanList);
1162 
1163 	msg.type = WMA_UPDATE_CHAN_LIST_REQ;
1164 	msg.reserved = 0;
1165 	msg.bodyptr = pChanList;
1166 	MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG,
1167 			 NO_SESSION, msg.type));
1168 	if (QDF_STATUS_SUCCESS != scheduler_post_message(QDF_MODULE_ID_SME,
1169 							 QDF_MODULE_ID_WMA,
1170 							 QDF_MODULE_ID_WMA,
1171 							 &msg)) {
1172 		qdf_mem_free(pChanList);
1173 		return QDF_STATUS_E_FAILURE;
1174 	}
1175 
1176 	csr_update_roam_pcl_per_connected_sta_vdev(mac->psoc);
1177 	return QDF_STATUS_SUCCESS;
1178 }
1179 
1180 QDF_STATUS csr_start(struct mac_context *mac)
1181 {
1182 	QDF_STATUS status = QDF_STATUS_SUCCESS;
1183 	uint32_t i;
1184 
1185 	do {
1186 		for (i = 0; i < WLAN_MAX_VDEVS; i++)
1187 			csr_roam_state_change(mac, eCSR_ROAMING_STATE_IDLE, i);
1188 
1189 		mac->roam.sPendingCommands = 0;
1190 
1191 		if (mac->mlme_cfg->reg.enable_pending_chan_list_req) {
1192 			status = ucfg_scan_register_event_handler(mac->pdev,
1193 					csr_scan_event_handler, mac);
1194 
1195 			if (QDF_IS_STATUS_ERROR(status))
1196 				sme_err("scan event registration failed ");
1197 		}
1198 	} while (0);
1199 	return status;
1200 }
1201 
1202 QDF_STATUS csr_stop(struct mac_context *mac)
1203 {
1204 	uint32_t sessionId;
1205 
1206 	if (mac->mlme_cfg->reg.enable_pending_chan_list_req)
1207 		ucfg_scan_unregister_event_handler(mac->pdev,
1208 						   csr_scan_event_handler,
1209 						   mac);
1210 	wlan_scan_psoc_set_disable(mac->psoc, REASON_SYSTEM_DOWN);
1211 
1212 	/*
1213 	 * purge all serialization command if there are any pending to make
1214 	 * sure memory and vdev ref are freed.
1215 	 */
1216 	csr_purge_pdev_all_ser_cmd_list(mac);
1217 	for (sessionId = 0; sessionId < WLAN_MAX_VDEVS; sessionId++)
1218 		csr_cleanup_vdev_session(mac, sessionId);
1219 
1220 	for (sessionId = 0; sessionId < WLAN_MAX_VDEVS; sessionId++)
1221 		if (CSR_IS_SESSION_VALID(mac, sessionId))
1222 			ucfg_scan_flush_results(mac->pdev, NULL);
1223 
1224 	for (sessionId = 0; sessionId < WLAN_MAX_VDEVS; sessionId++) {
1225 		csr_roam_state_change(mac, eCSR_ROAMING_STATE_STOP, sessionId);
1226 		csr_roam_substate_change(mac, eCSR_ROAM_SUBSTATE_NONE,
1227 					 sessionId);
1228 	}
1229 
1230 	return QDF_STATUS_SUCCESS;
1231 }
1232 
1233 QDF_STATUS csr_ready(struct mac_context *mac)
1234 {
1235 	QDF_STATUS status = QDF_STATUS_SUCCESS;
1236 	/* If the gScanAgingTime is set to '0' then scan results aging timeout
1237 	 * based  on timer feature is not enabled
1238 	 */
1239 	status = csr_apply_channel_and_power_list(mac);
1240 	if (!QDF_IS_STATUS_SUCCESS(status))
1241 		sme_err("csr_apply_channel_and_power_list failed status: %d",
1242 			status);
1243 
1244 	return status;
1245 }
1246 
1247 void csr_set_default_dot11_mode(struct mac_context *mac)
1248 {
1249 	mac->mlme_cfg->dot11_mode.dot11_mode =
1250 			csr_translate_to_wni_cfg_dot11_mode(mac,
1251 					  mac->roam.configParam.uCfgDot11Mode);
1252 }
1253 
1254 void csr_set_global_cfgs(struct mac_context *mac)
1255 {
1256 	wlan_mlme_set_frag_threshold(mac->psoc, csr_get_frag_thresh(mac));
1257 	wlan_mlme_set_rts_threshold(mac->psoc, csr_get_rts_thresh(mac));
1258 	/* For now we will just use the 5GHz CB mode ini parameter to decide
1259 	 * whether CB supported or not in Probes when there is no session
1260 	 * Once session is established we will use the session related params
1261 	 * stored in PE session for CB mode
1262 	 */
1263 	if (cfg_in_range(CFG_CHANNEL_BONDING_MODE_5GHZ,
1264 			 mac->roam.configParam.channelBondingMode5GHz))
1265 		ucfg_mlme_set_channel_bonding_5ghz(mac->psoc,
1266 						   mac->roam.configParam.
1267 						   channelBondingMode5GHz);
1268 	if (cfg_in_range(CFG_CHANNEL_BONDING_MODE_24GHZ,
1269 			 mac->roam.configParam.channelBondingMode24GHz))
1270 		ucfg_mlme_set_channel_bonding_24ghz(mac->psoc,
1271 						    mac->roam.configParam.
1272 						    channelBondingMode24GHz);
1273 
1274 	mac->mlme_cfg->timeouts.heart_beat_threshold =
1275 			cfg_default(CFG_HEART_BEAT_THRESHOLD);
1276 
1277 	/* Update the operating mode to configured value during
1278 	 *  initialization, So that client can advertise full
1279 	 *  capabilities in Probe request frame.
1280 	 */
1281 	csr_set_default_dot11_mode(mac);
1282 }
1283 
1284 #if defined(WLAN_LOGGING_SOCK_SVC_ENABLE) && \
1285 	defined(CONNECTIVITY_PKTLOG)
1286 /**
1287  * csr_packetdump_timer_handler() - packet dump timer
1288  * handler
1289  * @pv: user data
1290  *
1291  * This function is used to handle packet dump timer
1292  *
1293  * Return: None
1294  *
1295  */
1296 static void csr_packetdump_timer_handler(void *pv)
1297 {
1298 	sme_debug("Invoking packetdump deregistration API");
1299 	wlan_deregister_txrx_packetdump(OL_TXRX_PDEV_ID);
1300 }
1301 
1302 void csr_packetdump_timer_start(void)
1303 {
1304 	QDF_STATUS status;
1305 	mac_handle_t mac_handle;
1306 	struct mac_context *mac;
1307 	QDF_TIMER_STATE cur_state;
1308 
1309 	mac_handle = cds_get_context(QDF_MODULE_ID_SME);
1310 	mac = MAC_CONTEXT(mac_handle);
1311 	if (!mac) {
1312 		QDF_ASSERT(0);
1313 		return;
1314 	}
1315 	cur_state = qdf_mc_timer_get_current_state(&mac->roam.packetdump_timer);
1316 	if (cur_state == QDF_TIMER_STATE_STARTING ||
1317 	    cur_state == QDF_TIMER_STATE_STARTING) {
1318 		sme_debug("packetdump_timer is already started: %d", cur_state);
1319 		return;
1320 	}
1321 
1322 	status = qdf_mc_timer_start(&mac->roam.packetdump_timer,
1323 				    (PKT_DUMP_TIMER_DURATION *
1324 				     QDF_MC_TIMER_TO_SEC_UNIT) /
1325 				    QDF_MC_TIMER_TO_MS_UNIT);
1326 	if (!QDF_IS_STATUS_SUCCESS(status))
1327 		sme_debug("cannot start packetdump timer status: %d", status);
1328 }
1329 
1330 void csr_packetdump_timer_stop(void)
1331 {
1332 	QDF_STATUS status;
1333 	mac_handle_t mac_handle;
1334 	struct mac_context *mac;
1335 
1336 	mac_handle = cds_get_context(QDF_MODULE_ID_SME);
1337 	mac = MAC_CONTEXT(mac_handle);
1338 	if (!mac) {
1339 		QDF_ASSERT(0);
1340 		return;
1341 	}
1342 
1343 	status = qdf_mc_timer_stop(&mac->roam.packetdump_timer);
1344 	if (!QDF_IS_STATUS_SUCCESS(status))
1345 		sme_err("cannot stop packetdump timer");
1346 }
1347 
1348 static QDF_STATUS csr_packetdump_timer_init(struct mac_context *mac)
1349 {
1350 	QDF_STATUS status = QDF_STATUS_SUCCESS;
1351 
1352 	if (!mac) {
1353 		QDF_ASSERT(0);
1354 		return -EINVAL;
1355 	}
1356 
1357 	status = qdf_mc_timer_init(&mac->roam.packetdump_timer,
1358 				   QDF_TIMER_TYPE_SW,
1359 				   csr_packetdump_timer_handler,
1360 				   mac);
1361 	if (!QDF_IS_STATUS_SUCCESS(status)) {
1362 		sme_err("cannot allocate memory for packetdump timer");
1363 		return status;
1364 	}
1365 
1366 	return status;
1367 }
1368 
1369 static void csr_packetdump_timer_deinit(struct mac_context *mac)
1370 {
1371 	if (!mac) {
1372 		QDF_ASSERT(0);
1373 		return;
1374 	}
1375 
1376 	qdf_mc_timer_stop(&mac->roam.packetdump_timer);
1377 	qdf_mc_timer_destroy(&mac->roam.packetdump_timer);
1378 }
1379 #else
1380 static inline QDF_STATUS csr_packetdump_timer_init(struct mac_context *mac)
1381 {
1382 	return QDF_STATUS_SUCCESS;
1383 }
1384 
1385 static inline void csr_packetdump_timer_deinit(struct mac_context *mac) {}
1386 #endif
1387 
1388 static QDF_STATUS csr_roam_open(struct mac_context *mac)
1389 {
1390 	QDF_STATUS status = QDF_STATUS_SUCCESS;
1391 
1392 	status = csr_packetdump_timer_init(mac);
1393 	if (QDF_IS_STATUS_ERROR(status))
1394 		return status;
1395 
1396 	spin_lock_init(&mac->roam.roam_state_lock);
1397 
1398 	return status;
1399 }
1400 
1401 static QDF_STATUS csr_roam_close(struct mac_context *mac)
1402 {
1403 	uint32_t sessionId;
1404 	struct csr_roam_session *session;
1405 
1406 	/*
1407 	 * purge all serialization command if there are any pending to make
1408 	 * sure memory and vdev ref are freed.
1409 	 */
1410 	csr_purge_pdev_all_ser_cmd_list(mac);
1411 	for (sessionId = 0; sessionId < WLAN_MAX_VDEVS; sessionId++) {
1412 		session = CSR_GET_SESSION(mac, sessionId);
1413 		if (!session)
1414 			continue;
1415 		csr_cleanup_vdev_session(mac, sessionId);
1416 	}
1417 
1418 	csr_packetdump_timer_deinit(mac);
1419 	return QDF_STATUS_SUCCESS;
1420 }
1421 
1422 static QDF_STATUS csr_roam_free_connected_info(struct mac_context *mac,
1423 					       struct csr_roam_connectedinfo *
1424 					       pConnectedInfo)
1425 {
1426 	QDF_STATUS status = QDF_STATUS_SUCCESS;
1427 
1428 	if (pConnectedInfo->pbFrames) {
1429 		qdf_mem_free(pConnectedInfo->pbFrames);
1430 		pConnectedInfo->pbFrames = NULL;
1431 	}
1432 	pConnectedInfo->nBeaconLength = 0;
1433 	pConnectedInfo->nAssocReqLength = 0;
1434 	pConnectedInfo->nAssocRspLength = 0;
1435 	pConnectedInfo->nRICRspLength = 0;
1436 #ifdef FEATURE_WLAN_ESE
1437 	pConnectedInfo->nTspecIeLength = 0;
1438 #endif
1439 	return status;
1440 }
1441 
1442 void csr_release_command_roam(struct mac_context *mac, tSmeCmd *pCommand)
1443 {
1444 	csr_reinit_roam_cmd(mac, pCommand);
1445 }
1446 
1447 void csr_release_command_wm_status_change(struct mac_context *mac,
1448 					  tSmeCmd *pCommand)
1449 {
1450 	csr_reinit_wm_status_change_cmd(mac, pCommand);
1451 }
1452 
1453 void csr_roam_substate_change(struct mac_context *mac,
1454 		enum csr_roam_substate NewSubstate, uint32_t sessionId)
1455 {
1456 	if (sessionId >= WLAN_MAX_VDEVS) {
1457 		sme_err("Invalid no of concurrent sessions %d",
1458 			  sessionId);
1459 		return;
1460 	}
1461 	if (mac->roam.curSubState[sessionId] == NewSubstate)
1462 		return;
1463 	sme_nofl_debug("CSR RoamSubstate: [ %s <== %s ]",
1464 		       mac_trace_getcsr_roam_sub_state(NewSubstate),
1465 		       mac_trace_getcsr_roam_sub_state(mac->roam.
1466 		       curSubState[sessionId]));
1467 	spin_lock(&mac->roam.roam_state_lock);
1468 	mac->roam.curSubState[sessionId] = NewSubstate;
1469 	spin_unlock(&mac->roam.roam_state_lock);
1470 }
1471 
1472 enum csr_roam_state csr_roam_state_change(struct mac_context *mac,
1473 				    enum csr_roam_state NewRoamState,
1474 				uint8_t sessionId)
1475 {
1476 	enum csr_roam_state PreviousState;
1477 
1478 	PreviousState = mac->roam.curState[sessionId];
1479 
1480 	if (NewRoamState == mac->roam.curState[sessionId])
1481 		return PreviousState;
1482 
1483 	sme_nofl_debug("CSR RoamState[%d]: [ %s <== %s ]", sessionId,
1484 		       mac_trace_getcsr_roam_state(NewRoamState),
1485 		       mac_trace_getcsr_roam_state(
1486 		       mac->roam.curState[sessionId]));
1487 	/*
1488 	 * Whenever we transition OUT of the Roaming state,
1489 	 * clear the Roaming substate.
1490 	 */
1491 	if (CSR_IS_ROAM_JOINING(mac, sessionId)) {
1492 		csr_roam_substate_change(mac, eCSR_ROAM_SUBSTATE_NONE,
1493 					 sessionId);
1494 	}
1495 
1496 	mac->roam.curState[sessionId] = NewRoamState;
1497 
1498 	return PreviousState;
1499 }
1500 
1501 static void init_config_param(struct mac_context *mac)
1502 {
1503 	mac->roam.configParam.channelBondingMode24GHz =
1504 		WNI_CFG_CHANNEL_BONDING_MODE_DISABLE;
1505 	mac->roam.configParam.channelBondingMode5GHz =
1506 		WNI_CFG_CHANNEL_BONDING_MODE_ENABLE;
1507 
1508 	mac->roam.configParam.phyMode = eCSR_DOT11_MODE_AUTO;
1509 	mac->roam.configParam.uCfgDot11Mode = eCSR_CFG_DOT11_MODE_AUTO;
1510 	mac->roam.configParam.HeartbeatThresh50 = 40;
1511 	mac->roam.configParam.Is11eSupportEnabled = true;
1512 	mac->roam.configParam.WMMSupportMode = WMM_USER_MODE_AUTO;
1513 	mac->roam.configParam.ProprietaryRatesEnabled = true;
1514 
1515 	mac->roam.configParam.nVhtChannelWidth =
1516 		WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ + 1;
1517 }
1518 
1519 /**
1520  * csr_flush_roam_scan_chan_lists() - Flush the roam channel lists
1521  * @mac: Global MAC context
1522  * @vdev_id: vdev id
1523  *
1524  * Flush the roam channel lists pref_chan_info and specific_chan_info.
1525  *
1526  * Return: None
1527  */
1528 static void
1529 csr_flush_roam_scan_chan_lists(struct mac_context *mac, uint8_t vdev_id)
1530 {
1531 	struct wlan_objmgr_vdev *vdev;
1532 	struct rso_config *rso_cfg;
1533 	struct rso_cfg_params *cfg_params;
1534 
1535 	vdev = wlan_objmgr_get_vdev_by_id_from_pdev(mac->pdev, vdev_id,
1536 						    WLAN_LEGACY_SME_ID);
1537 	if (!vdev)
1538 		return;
1539 
1540 	rso_cfg = wlan_cm_get_rso_config(vdev);
1541 	if (!rso_cfg) {
1542 		wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID);
1543 		return;
1544 	}
1545 	cfg_params = &rso_cfg->cfg_param;
1546 	wlan_cm_flush_roam_channel_list(&cfg_params->pref_chan_info);
1547 	wlan_cm_flush_roam_channel_list(&cfg_params->specific_chan_info);
1548 	wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID);
1549 }
1550 
1551 #ifdef FEATURE_WLAN_ESE
1552 /**
1553  * csr_roam_is_ese_assoc() - is this ese association
1554  * @mac_ctx: Global MAC context
1555  * @session_id: session identifier
1556  *
1557  * Returns whether the current association is a ESE assoc or not.
1558  *
1559  * Return: true if ese association; false otherwise
1560  */
1561 bool csr_roam_is_ese_assoc(struct mac_context *mac_ctx, uint32_t session_id)
1562 {
1563 	return wlan_cm_get_ese_assoc(mac_ctx->pdev, session_id);
1564 }
1565 
1566 
1567 /**
1568  * csr_tsm_stats_rsp_processor() - tsm stats response processor
1569  * @mac: Global MAC context
1570  * @pMsg: Message pointer
1571  *
1572  * Return: None
1573  */
1574 static void csr_tsm_stats_rsp_processor(struct mac_context *mac, void *pMsg)
1575 {
1576 	tAniGetTsmStatsRsp *pTsmStatsRsp = (tAniGetTsmStatsRsp *) pMsg;
1577 
1578 	if (pTsmStatsRsp) {
1579 		/*
1580 		 * Get roam Rssi request is backed up and passed back
1581 		 * to the response, Extract the request message
1582 		 * to fetch callback.
1583 		 */
1584 		tpAniGetTsmStatsReq reqBkp
1585 			= (tAniGetTsmStatsReq *) pTsmStatsRsp->tsmStatsReq;
1586 
1587 		if (reqBkp) {
1588 			if (reqBkp->tsmStatsCallback) {
1589 				((tCsrTsmStatsCallback)
1590 				 (reqBkp->tsmStatsCallback))(pTsmStatsRsp->
1591 							     tsmMetrics,
1592 							     reqBkp->
1593 							     pDevContext);
1594 				reqBkp->tsmStatsCallback = NULL;
1595 			}
1596 			qdf_mem_free(reqBkp);
1597 			pTsmStatsRsp->tsmStatsReq = NULL;
1598 		} else {
1599 			if (reqBkp) {
1600 				qdf_mem_free(reqBkp);
1601 				pTsmStatsRsp->tsmStatsReq = NULL;
1602 			}
1603 		}
1604 	} else {
1605 		sme_err("pTsmStatsRsp is NULL");
1606 	}
1607 }
1608 
1609 /**
1610  * csr_send_ese_adjacent_ap_rep_ind() - ese send adjacent ap report
1611  * @mac: Global MAC context
1612  * @pSession: Session pointer
1613  *
1614  * Return: None
1615  */
1616 static void csr_send_ese_adjacent_ap_rep_ind(struct mac_context *mac,
1617 					struct csr_roam_session *pSession)
1618 {
1619 	uint32_t roamTS2 = 0;
1620 	struct csr_roam_info *roam_info;
1621 	struct pe_session *pe_session = NULL;
1622 	uint8_t sessionId = WLAN_UMAC_VDEV_ID_MAX;
1623 	struct qdf_mac_addr connected_bssid;
1624 
1625 	if (!pSession) {
1626 		sme_err("pSession is NULL");
1627 		return;
1628 	}
1629 
1630 	roam_info = qdf_mem_malloc(sizeof(*roam_info));
1631 	if (!roam_info)
1632 		return;
1633 	roamTS2 = qdf_mc_timer_get_system_time();
1634 	roam_info->tsmRoamDelay = roamTS2 - pSession->roamTS1;
1635 	wlan_mlme_get_bssid_vdev_id(mac->pdev, pSession->vdev_id,
1636 				    &connected_bssid);
1637 	sme_debug("Bssid(" QDF_MAC_ADDR_FMT ") Roaming Delay(%u ms)",
1638 		QDF_MAC_ADDR_REF(connected_bssid.bytes),
1639 		roam_info->tsmRoamDelay);
1640 
1641 	pe_session = pe_find_session_by_bssid(mac, connected_bssid.bytes,
1642 					      &sessionId);
1643 	if (!pe_session) {
1644 		sme_err("session %d not found", sessionId);
1645 		qdf_mem_free(roam_info);
1646 		return;
1647 	}
1648 
1649 	pe_session->eseContext.tsm.tsmMetrics.RoamingDly
1650 		= roam_info->tsmRoamDelay;
1651 
1652 	csr_roam_call_callback(mac, pSession->vdev_id, roam_info,
1653 			       eCSR_ROAM_ESE_ADJ_AP_REPORT_IND, 0);
1654 	qdf_mem_free(roam_info);
1655 }
1656 
1657 /**
1658  * csr_get_tsm_stats() - get tsm stats
1659  * @mac: Global MAC context
1660  * @callback: TSM stats callback
1661  * @staId: Station id
1662  * @bssId: bssid
1663  * @pContext: pointer to context
1664  * @tid: traffic id
1665  *
1666  * Return: QDF_STATUS enumeration
1667  */
1668 QDF_STATUS csr_get_tsm_stats(struct mac_context *mac,
1669 			     tCsrTsmStatsCallback callback,
1670 			     struct qdf_mac_addr bssId,
1671 			     void *pContext, uint8_t tid)
1672 {
1673 	QDF_STATUS status = QDF_STATUS_SUCCESS;
1674 	tAniGetTsmStatsReq *pMsg = NULL;
1675 
1676 	pMsg = qdf_mem_malloc(sizeof(tAniGetTsmStatsReq));
1677 	if (!pMsg) {
1678 		return QDF_STATUS_E_NOMEM;
1679 	}
1680 	/* need to initiate a stats request to PE */
1681 	pMsg->msgType = eWNI_SME_GET_TSM_STATS_REQ;
1682 	pMsg->msgLen = (uint16_t) sizeof(tAniGetTsmStatsReq);
1683 	pMsg->tid = tid;
1684 	qdf_copy_macaddr(&pMsg->bssId, &bssId);
1685 	pMsg->tsmStatsCallback = callback;
1686 	pMsg->pDevContext = pContext;
1687 	status = umac_send_mb_message_to_mac(pMsg);
1688 	if (!QDF_IS_STATUS_SUCCESS(status)) {
1689 		sme_debug("Failed to send down the TSM req (status=%d)", status);
1690 		/* pMsg is freed by cds_send_mb_message_to_mac */
1691 		status = QDF_STATUS_E_FAILURE;
1692 	}
1693 	return status;
1694 }
1695 #endif /* FEATURE_WLAN_ESE */
1696 
1697 /* The funcns csr_convert_cb_ini_value_to_phy_cb_state and
1698  * csr_convert_phy_cb_state_to_ini_value have been introduced
1699  * to convert the ini value to the ENUM used in csr and MAC for CB state
1700  * Ideally we should have kept the ini value and enum value same and
1701  * representing the same cb values as in 11n standard i.e.
1702  * Set to 1 (SCA) if the secondary channel is above the primary channel
1703  * Set to 3 (SCB) if the secondary channel is below the primary channel
1704  * Set to 0 (SCN) if no secondary channel is present
1705  * However, since our driver is already distributed we will keep the ini
1706  * definition as it is which is:
1707  * 0 - secondary none
1708  * 1 - secondary LOW
1709  * 2 - secondary HIGH
1710  * and convert to enum value used within the driver in
1711  * csr_change_default_config_param using this funcn
1712  * The enum values are as follows:
1713  * PHY_SINGLE_CHANNEL_CENTERED          = 0
1714  * PHY_DOUBLE_CHANNEL_LOW_PRIMARY   = 1
1715  * PHY_DOUBLE_CHANNEL_HIGH_PRIMARY  = 3
1716  */
1717 ePhyChanBondState csr_convert_cb_ini_value_to_phy_cb_state(uint32_t cbIniValue)
1718 {
1719 
1720 	ePhyChanBondState phyCbState;
1721 
1722 	switch (cbIniValue) {
1723 	/* secondary none */
1724 	case eCSR_INI_SINGLE_CHANNEL_CENTERED:
1725 		phyCbState = PHY_SINGLE_CHANNEL_CENTERED;
1726 		break;
1727 	/* secondary LOW */
1728 	case eCSR_INI_DOUBLE_CHANNEL_HIGH_PRIMARY:
1729 		phyCbState = PHY_DOUBLE_CHANNEL_HIGH_PRIMARY;
1730 		break;
1731 	/* secondary HIGH */
1732 	case eCSR_INI_DOUBLE_CHANNEL_LOW_PRIMARY:
1733 		phyCbState = PHY_DOUBLE_CHANNEL_LOW_PRIMARY;
1734 		break;
1735 	case eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_CENTERED:
1736 		phyCbState = PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_CENTERED;
1737 		break;
1738 	case eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_CENTERED_40MHZ_CENTERED:
1739 		phyCbState =
1740 			PHY_QUADRUPLE_CHANNEL_20MHZ_CENTERED_40MHZ_CENTERED;
1741 		break;
1742 	case eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_CENTERED:
1743 		phyCbState = PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_CENTERED;
1744 		break;
1745 	case eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW:
1746 		phyCbState = PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW;
1747 		break;
1748 	case eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW:
1749 		phyCbState = PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW;
1750 		break;
1751 	case eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH:
1752 		phyCbState = PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH;
1753 		break;
1754 	case eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH:
1755 		phyCbState = PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH;
1756 		break;
1757 	default:
1758 		/* If an invalid value is passed, disable CHANNEL BONDING */
1759 		phyCbState = PHY_SINGLE_CHANNEL_CENTERED;
1760 		break;
1761 	}
1762 	return phyCbState;
1763 }
1764 
1765 static
1766 uint32_t csr_convert_phy_cb_state_to_ini_value(ePhyChanBondState phyCbState)
1767 {
1768 	uint32_t cbIniValue;
1769 
1770 	switch (phyCbState) {
1771 	/* secondary none */
1772 	case PHY_SINGLE_CHANNEL_CENTERED:
1773 		cbIniValue = eCSR_INI_SINGLE_CHANNEL_CENTERED;
1774 		break;
1775 	/* secondary LOW */
1776 	case PHY_DOUBLE_CHANNEL_HIGH_PRIMARY:
1777 		cbIniValue = eCSR_INI_DOUBLE_CHANNEL_HIGH_PRIMARY;
1778 		break;
1779 	/* secondary HIGH */
1780 	case PHY_DOUBLE_CHANNEL_LOW_PRIMARY:
1781 		cbIniValue = eCSR_INI_DOUBLE_CHANNEL_LOW_PRIMARY;
1782 		break;
1783 	case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_CENTERED:
1784 		cbIniValue =
1785 			eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_CENTERED;
1786 		break;
1787 	case PHY_QUADRUPLE_CHANNEL_20MHZ_CENTERED_40MHZ_CENTERED:
1788 		cbIniValue =
1789 		eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_CENTERED_40MHZ_CENTERED;
1790 		break;
1791 	case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_CENTERED:
1792 		cbIniValue =
1793 			eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_CENTERED;
1794 		break;
1795 	case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW:
1796 		cbIniValue = eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW;
1797 		break;
1798 	case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW:
1799 		cbIniValue = eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW;
1800 		break;
1801 	case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH:
1802 		cbIniValue = eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH;
1803 		break;
1804 	case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH:
1805 		cbIniValue = eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH;
1806 		break;
1807 	default:
1808 		/* return some invalid value */
1809 		cbIniValue = eCSR_INI_CHANNEL_BONDING_STATE_MAX;
1810 		break;
1811 	}
1812 	return cbIniValue;
1813 }
1814 
1815 #ifdef WLAN_FEATURE_11BE
1816 void csr_update_session_eht_cap(struct mac_context *mac_ctx,
1817 				struct csr_roam_session *session)
1818 {
1819 	tDot11fIEeht_cap *eht_cap;
1820 	struct wlan_objmgr_vdev *vdev;
1821 	struct mlme_legacy_priv *mlme_priv;
1822 
1823 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac_ctx->psoc,
1824 						    session->vdev_id,
1825 						    WLAN_LEGACY_SME_ID);
1826 	if (!vdev)
1827 		return;
1828 	mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev);
1829 	if (!mlme_priv) {
1830 		wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID);
1831 		return;
1832 	}
1833 	qdf_mem_copy(&mlme_priv->eht_config,
1834 		     &mac_ctx->mlme_cfg->eht_caps.dot11_eht_cap,
1835 		     sizeof(mlme_priv->eht_config));
1836 	eht_cap = &mlme_priv->eht_config;
1837 	eht_cap->present = true;
1838 	wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID);
1839 }
1840 #endif
1841 
1842 #ifdef WLAN_FEATURE_11AX
1843 void csr_update_session_he_cap(struct mac_context *mac_ctx,
1844 			       struct csr_roam_session *session)
1845 {
1846 	enum QDF_OPMODE persona;
1847 	tDot11fIEhe_cap *he_cap;
1848 	struct wlan_objmgr_vdev *vdev;
1849 	struct mlme_legacy_priv *mlme_priv;
1850 
1851 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac_ctx->psoc,
1852 						    session->vdev_id,
1853 						    WLAN_LEGACY_SME_ID);
1854 	if (!vdev)
1855 		return;
1856 	mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev);
1857 	if (!mlme_priv) {
1858 		wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID);
1859 		return;
1860 	}
1861 	qdf_mem_copy(&mlme_priv->he_config,
1862 		     &mac_ctx->mlme_cfg->he_caps.dot11_he_cap,
1863 		     sizeof(mlme_priv->he_config));
1864 	he_cap = &mlme_priv->he_config;
1865 	he_cap->present = true;
1866 	/*
1867 	 * Do not advertise requester role for SAP & responder role
1868 	 * for STA
1869 	 */
1870 	persona = wlan_vdev_mlme_get_opmode(vdev);
1871 	if (persona == QDF_SAP_MODE || persona == QDF_P2P_GO_MODE) {
1872 		he_cap->twt_request = false;
1873 		if (!he_cap->twt_responder)
1874 			he_cap->flex_twt_sched = false;
1875 
1876 	} else if (persona == QDF_STA_MODE || persona == QDF_P2P_CLIENT_MODE) {
1877 		he_cap->twt_responder = false;
1878 		if (!he_cap->twt_request)
1879 			he_cap->flex_twt_sched = false;
1880 	}
1881 
1882 	if (he_cap->ppet_present) {
1883 		/* till now operating channel is not decided yet, use 5g cap */
1884 		qdf_mem_copy(he_cap->ppet.ppe_threshold.ppe_th,
1885 			     mac_ctx->mlme_cfg->he_caps.he_ppet_5g,
1886 			     WNI_CFG_HE_PPET_LEN);
1887 		he_cap->ppet.ppe_threshold.num_ppe_th =
1888 			lim_truncate_ppet(he_cap->ppet.ppe_threshold.ppe_th,
1889 					  WNI_CFG_HE_PPET_LEN);
1890 	} else {
1891 		he_cap->ppet.ppe_threshold.num_ppe_th = 0;
1892 	}
1893 	mlme_priv->he_sta_obsspd = mac_ctx->mlme_cfg->he_caps.he_sta_obsspd;
1894 	wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID);
1895 }
1896 #endif
1897 
1898 QDF_STATUS csr_change_default_config_param(struct mac_context *mac,
1899 					   struct csr_config_params *pParam)
1900 {
1901 	QDF_STATUS status = QDF_STATUS_SUCCESS;
1902 
1903 	if (pParam) {
1904 		mac->roam.configParam.is_force_1x1 =
1905 			pParam->is_force_1x1;
1906 		mac->roam.configParam.WMMSupportMode = pParam->WMMSupportMode;
1907 		mac->mlme_cfg->wmm_params.wme_enabled =
1908 			(pParam->WMMSupportMode == WMM_USER_MODE_NO_QOS) ? 0 : 1;
1909 		mac->roam.configParam.Is11eSupportEnabled =
1910 			pParam->Is11eSupportEnabled;
1911 
1912 		mac->roam.configParam.fenableMCCMode = pParam->fEnableMCCMode;
1913 		mac->roam.configParam.mcc_rts_cts_prot_enable =
1914 						pParam->mcc_rts_cts_prot_enable;
1915 		mac->roam.configParam.mcc_bcast_prob_resp_enable =
1916 					pParam->mcc_bcast_prob_resp_enable;
1917 		mac->roam.configParam.fAllowMCCGODiffBI =
1918 			pParam->fAllowMCCGODiffBI;
1919 
1920 		/* channelBondingMode5GHz plays a dual role right now
1921 		 * INFRA STA will use this non zero value as CB enabled
1922 		 * and SOFTAP will use this non-zero value to determine
1923 		 * the secondary channel offset. This is how
1924 		 * channelBondingMode5GHz works now and this is kept intact
1925 		 * to avoid any cfg.ini change.
1926 		 */
1927 		if (pParam->channelBondingMode24GHz > MAX_CB_VALUE_IN_INI)
1928 			sme_warn("Invalid CB value from ini in 2.4GHz band %d, CB DISABLED",
1929 				pParam->channelBondingMode24GHz);
1930 		mac->roam.configParam.channelBondingMode24GHz =
1931 			csr_convert_cb_ini_value_to_phy_cb_state(pParam->
1932 						channelBondingMode24GHz);
1933 		if (pParam->channelBondingMode5GHz > MAX_CB_VALUE_IN_INI)
1934 			sme_warn("Invalid CB value from ini in 5GHz band %d, CB DISABLED",
1935 				pParam->channelBondingMode5GHz);
1936 		mac->roam.configParam.channelBondingMode5GHz =
1937 			csr_convert_cb_ini_value_to_phy_cb_state(pParam->
1938 							channelBondingMode5GHz);
1939 		sme_debug("cb mode 2g %d 5g %d",
1940 			  mac->roam.configParam.channelBondingMode24GHz,
1941 			  mac->roam.configParam.channelBondingMode5GHz);
1942 		mac->roam.configParam.phyMode = pParam->phyMode;
1943 		mac->roam.configParam.HeartbeatThresh50 =
1944 			pParam->HeartbeatThresh50;
1945 		mac->roam.configParam.ProprietaryRatesEnabled =
1946 			pParam->ProprietaryRatesEnabled;
1947 
1948 		mac->roam.configParam.wep_tkip_in_he = pParam->wep_tkip_in_he;
1949 
1950 		mac->roam.configParam.uCfgDot11Mode =
1951 			csr_get_cfg_dot11_mode_from_csr_phy_mode(false,
1952 							mac->roam.configParam.
1953 							phyMode);
1954 
1955 		/* Assign this before calling csr_init11d_info */
1956 		if (wlan_reg_11d_enabled_on_host(mac->psoc))
1957 			status = csr_init11d_info(mac, &pParam->Csr11dinfo);
1958 
1959 		/* Initialize the power + channel information if 11h is
1960 		 * enabled. If 11d is enabled this information has already
1961 		 * been initialized
1962 		 */
1963 		if (csr_is11h_supported(mac) &&
1964 				!wlan_reg_11d_enabled_on_host(mac->psoc))
1965 			csr_init_channel_power_list(mac, &pParam->Csr11dinfo);
1966 
1967 		mac->scan.fEnableDFSChnlScan = pParam->fEnableDFSChnlScan;
1968 		mac->roam.configParam.send_smps_action =
1969 			pParam->send_smps_action;
1970 #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
1971 		mac->roam.configParam.cc_switch_mode = pParam->cc_switch_mode;
1972 #endif
1973 		mac->roam.configParam.obssEnabled = pParam->obssEnabled;
1974 		mac->roam.configParam.conc_custom_rule1 =
1975 			pParam->conc_custom_rule1;
1976 		mac->roam.configParam.conc_custom_rule2 =
1977 			pParam->conc_custom_rule2;
1978 		mac->roam.configParam.is_sta_connection_in_5gz_enabled =
1979 			pParam->is_sta_connection_in_5gz_enabled;
1980 
1981 		/* update interface configuration */
1982 		mac->sme.max_intf_count = pParam->max_intf_count;
1983 
1984 		mac->f_sta_miracast_mcc_rest_time_val =
1985 			pParam->f_sta_miracast_mcc_rest_time_val;
1986 #ifdef FEATURE_AP_MCC_CH_AVOIDANCE
1987 		mac->sap.sap_channel_avoidance =
1988 			pParam->sap_channel_avoidance;
1989 #endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
1990 	}
1991 	return status;
1992 }
1993 
1994 QDF_STATUS csr_get_config_param(struct mac_context *mac,
1995 				struct csr_config_params *pParam)
1996 {
1997 	struct csr_config *cfg_params = &mac->roam.configParam;
1998 
1999 	if (!pParam)
2000 		return QDF_STATUS_E_INVAL;
2001 
2002 	pParam->is_force_1x1 = cfg_params->is_force_1x1;
2003 	pParam->WMMSupportMode = cfg_params->WMMSupportMode;
2004 	pParam->Is11eSupportEnabled = cfg_params->Is11eSupportEnabled;
2005 	pParam->channelBondingMode24GHz = csr_convert_phy_cb_state_to_ini_value(
2006 					cfg_params->channelBondingMode24GHz);
2007 	pParam->channelBondingMode5GHz = csr_convert_phy_cb_state_to_ini_value(
2008 					cfg_params->channelBondingMode5GHz);
2009 	pParam->phyMode = cfg_params->phyMode;
2010 	pParam->HeartbeatThresh50 = cfg_params->HeartbeatThresh50;
2011 	pParam->ProprietaryRatesEnabled = cfg_params->ProprietaryRatesEnabled;
2012 	pParam->fEnableDFSChnlScan = mac->scan.fEnableDFSChnlScan;
2013 	pParam->fEnableMCCMode = cfg_params->fenableMCCMode;
2014 	pParam->fAllowMCCGODiffBI = cfg_params->fAllowMCCGODiffBI;
2015 
2016 #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
2017 	pParam->cc_switch_mode = cfg_params->cc_switch_mode;
2018 #endif
2019 	pParam->wep_tkip_in_he = cfg_params->wep_tkip_in_he;
2020 	csr_set_channels(mac, pParam);
2021 	pParam->obssEnabled = cfg_params->obssEnabled;
2022 	pParam->conc_custom_rule1 = cfg_params->conc_custom_rule1;
2023 	pParam->conc_custom_rule2 = cfg_params->conc_custom_rule2;
2024 	pParam->is_sta_connection_in_5gz_enabled =
2025 		cfg_params->is_sta_connection_in_5gz_enabled;
2026 #ifdef FEATURE_AP_MCC_CH_AVOIDANCE
2027 	pParam->sap_channel_avoidance = mac->sap.sap_channel_avoidance;
2028 #endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
2029 	pParam->max_intf_count = mac->sme.max_intf_count;
2030 	pParam->f_sta_miracast_mcc_rest_time_val =
2031 		mac->f_sta_miracast_mcc_rest_time_val;
2032 	pParam->send_smps_action = mac->roam.configParam.send_smps_action;
2033 
2034 	return QDF_STATUS_SUCCESS;
2035 }
2036 
2037 /**
2038  * csr_prune_ch_list() - prunes the channel list to keep only a type of channels
2039  * @ch_lst:        existing channel list
2040  * @is_24_GHz:     indicates if 2.5 GHz or 5 GHz channels are required
2041  *
2042  * Return: void
2043  */
2044 static void csr_prune_ch_list(struct csr_channel *ch_lst, bool is_24_GHz)
2045 {
2046 	uint8_t idx = 0, num_channels = 0;
2047 
2048 	for ( ; idx < ch_lst->numChannels; idx++) {
2049 		if (is_24_GHz) {
2050 			if (WLAN_REG_IS_24GHZ_CH_FREQ(ch_lst->channel_freq_list[idx])) {
2051 				ch_lst->channel_freq_list[num_channels] =
2052 					ch_lst->channel_freq_list[idx];
2053 				num_channels++;
2054 			}
2055 		} else {
2056 			if (WLAN_REG_IS_5GHZ_CH_FREQ(ch_lst->channel_freq_list[idx])) {
2057 				ch_lst->channel_freq_list[num_channels] =
2058 					ch_lst->channel_freq_list[idx];
2059 				num_channels++;
2060 			}
2061 		}
2062 	}
2063 	/*
2064 	 * Cleanup the rest of channels. Note we only need to clean up the
2065 	 * channels if we had to trim the list. Calling qdf_mem_set() with a 0
2066 	 * size is going to throw asserts on the debug builds so let's be a bit
2067 	 * smarter about that. Zero out the reset of the channels only if we
2068 	 * need to. The amount of memory to clear is the number of channesl that
2069 	 * we trimmed (ch_lst->numChannels - num_channels) times the size of a
2070 	 * channel in the structure.
2071 	 */
2072 	if (ch_lst->numChannels > num_channels) {
2073 		qdf_mem_zero(&ch_lst->channel_freq_list[num_channels],
2074 			     sizeof(ch_lst->channel_freq_list[0]) *
2075 			     (ch_lst->numChannels - num_channels));
2076 	}
2077 	ch_lst->numChannels = num_channels;
2078 }
2079 
2080 /**
2081  * csr_prune_channel_list_for_mode() - prunes the channel list
2082  * @mac_ctx:       global mac context
2083  * @ch_lst:        existing channel list
2084  *
2085  * Prunes the channel list according to band stored in mac_ctx
2086  *
2087  * Return: void
2088  */
2089 void csr_prune_channel_list_for_mode(struct mac_context *mac_ctx,
2090 				     struct csr_channel *ch_lst)
2091 {
2092 	/* for dual band NICs, don't need to trim the channel list.... */
2093 	if (CSR_IS_OPEARTING_DUAL_BAND(mac_ctx))
2094 		return;
2095 	/*
2096 	 * 2.4 GHz band operation requires the channel list to be trimmed to
2097 	 * the 2.4 GHz channels only
2098 	 */
2099 	if (CSR_IS_24_BAND_ONLY(mac_ctx))
2100 		csr_prune_ch_list(ch_lst, true);
2101 	else if (CSR_IS_5G_BAND_ONLY(mac_ctx))
2102 		csr_prune_ch_list(ch_lst, false);
2103 }
2104 
2105 #define INFRA_AP_DEFAULT_CHAN_FREQ 2437
2106 
2107 QDF_STATUS csr_get_channel_and_power_list(struct mac_context *mac)
2108 {
2109 	QDF_STATUS status = QDF_STATUS_SUCCESS;
2110 	uint8_t num20MHzChannelsFound = 0;
2111 	QDF_STATUS qdf_status;
2112 	uint8_t Index = 0;
2113 
2114 	qdf_status = wlan_reg_get_channel_list_with_power_for_freq(
2115 				mac->pdev,
2116 				mac->scan.defaultPowerTable,
2117 				&num20MHzChannelsFound);
2118 
2119 	if ((QDF_STATUS_SUCCESS != qdf_status) ||
2120 	    (num20MHzChannelsFound == 0)) {
2121 		sme_err("failed to get channels");
2122 		status = QDF_STATUS_E_FAILURE;
2123 	} else {
2124 		if (num20MHzChannelsFound > CFG_VALID_CHANNEL_LIST_LEN)
2125 			num20MHzChannelsFound = CFG_VALID_CHANNEL_LIST_LEN;
2126 		/* Move the channel list to the global data */
2127 		/* structure -- this will be used as the scan list */
2128 		for (Index = 0; Index < num20MHzChannelsFound; Index++)
2129 			mac->scan.base_channels.channel_freq_list[Index] =
2130 				mac->scan.defaultPowerTable[Index].center_freq;
2131 		mac->scan.base_channels.numChannels =
2132 			num20MHzChannelsFound;
2133 	}
2134 	return status;
2135 }
2136 
2137 QDF_STATUS csr_apply_channel_and_power_list(struct mac_context *mac)
2138 {
2139 	QDF_STATUS status = QDF_STATUS_SUCCESS;
2140 
2141 	csr_prune_channel_list_for_mode(mac, &mac->scan.base_channels);
2142 	csr_save_channel_power_for_band(mac, false);
2143 	csr_save_channel_power_for_band(mac, true);
2144 	csr_apply_channel_power_info_to_fw(mac,
2145 					   &mac->scan.base_channels);
2146 
2147 	csr_init_operating_classes(mac);
2148 	return status;
2149 }
2150 
2151 static QDF_STATUS csr_init11d_info(struct mac_context *mac, tCsr11dinfo *ps11dinfo)
2152 {
2153 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
2154 	uint8_t index;
2155 	uint32_t count = 0;
2156 	struct pwr_channel_info *pChanInfo;
2157 	struct pwr_channel_info *pChanInfoStart;
2158 	bool applyConfig = true;
2159 
2160 	if (!ps11dinfo)
2161 		return status;
2162 
2163 	if (ps11dinfo->Channels.numChannels
2164 	    && (CFG_VALID_CHANNEL_LIST_LEN >=
2165 		ps11dinfo->Channels.numChannels)) {
2166 		mac->scan.base_channels.numChannels =
2167 			ps11dinfo->Channels.numChannels;
2168 		qdf_mem_copy(mac->scan.base_channels.channel_freq_list,
2169 			     ps11dinfo->Channels.channel_freq_list,
2170 			     ps11dinfo->Channels.numChannels);
2171 	} else {
2172 		/* No change */
2173 		return QDF_STATUS_SUCCESS;
2174 	}
2175 	/* legacy maintenance */
2176 
2177 	/* need to add the max power channel list */
2178 	pChanInfo =
2179 		qdf_mem_malloc(sizeof(struct pwr_channel_info) *
2180 			       CFG_VALID_CHANNEL_LIST_LEN);
2181 	if (pChanInfo) {
2182 		pChanInfoStart = pChanInfo;
2183 		for (index = 0; index < ps11dinfo->Channels.numChannels;
2184 		     index++) {
2185 			pChanInfo->first_freq = ps11dinfo->ChnPower[index].first_chan_freq;
2186 			pChanInfo->num_chan =
2187 				ps11dinfo->ChnPower[index].numChannels;
2188 			pChanInfo->max_tx_pwr =
2189 				ps11dinfo->ChnPower[index].maxtxPower;
2190 			pChanInfo++;
2191 			count++;
2192 		}
2193 		if (count) {
2194 			status = csr_save_to_channel_power2_g_5_g(mac,
2195 						count *
2196 						sizeof(struct pwr_channel_info),
2197 						pChanInfoStart);
2198 		}
2199 		qdf_mem_free(pChanInfoStart);
2200 	}
2201 	/* Only apply them to CFG when not in STOP state.
2202 	 * Otherwise they will be applied later
2203 	 */
2204 	if (QDF_IS_STATUS_SUCCESS(status)) {
2205 		for (index = 0; index < WLAN_MAX_VDEVS; index++) {
2206 			if ((CSR_IS_SESSION_VALID(mac, index))
2207 			    && CSR_IS_ROAM_STOP(mac, index)) {
2208 				applyConfig = false;
2209 			}
2210 		}
2211 
2212 		if (true == applyConfig) {
2213 			/* Apply the base channel list, power info,
2214 			 * and set the Country code.
2215 			 */
2216 			csr_apply_channel_power_info_to_fw(mac,
2217 							   &mac->scan.
2218 							   base_channels);
2219 		}
2220 	}
2221 	return status;
2222 }
2223 
2224 /* Initialize the Channel + Power List in the local cache and in the CFG */
2225 QDF_STATUS csr_init_channel_power_list(struct mac_context *mac,
2226 					tCsr11dinfo *ps11dinfo)
2227 {
2228 	uint8_t index;
2229 	uint32_t count = 0;
2230 	struct pwr_channel_info *pChanInfo;
2231 	struct pwr_channel_info *pChanInfoStart;
2232 
2233 	if (!ps11dinfo || !mac)
2234 		return QDF_STATUS_E_FAILURE;
2235 
2236 	pChanInfo =
2237 		qdf_mem_malloc(sizeof(struct pwr_channel_info) *
2238 			       CFG_VALID_CHANNEL_LIST_LEN);
2239 	if (pChanInfo) {
2240 		pChanInfoStart = pChanInfo;
2241 
2242 		for (index = 0; index < ps11dinfo->Channels.numChannels;
2243 		     index++) {
2244 			pChanInfo->first_freq = ps11dinfo->ChnPower[index].first_chan_freq;
2245 			pChanInfo->num_chan =
2246 				ps11dinfo->ChnPower[index].numChannels;
2247 			pChanInfo->max_tx_pwr =
2248 				ps11dinfo->ChnPower[index].maxtxPower;
2249 			pChanInfo++;
2250 			count++;
2251 		}
2252 		if (count) {
2253 			csr_save_to_channel_power2_g_5_g(mac,
2254 						count *
2255 						sizeof(struct pwr_channel_info),
2256 						pChanInfoStart);
2257 		}
2258 		qdf_mem_free(pChanInfoStart);
2259 	}
2260 
2261 	return QDF_STATUS_SUCCESS;
2262 }
2263 
2264 #ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
2265 #ifdef WLAN_UNIT_TEST
2266 void csr_cm_get_sta_cxn_info(struct mac_context *mac_ctx, uint8_t vdev_id,
2267 			     char *buf, uint32_t buf_sz)
2268 {
2269 	struct wlan_objmgr_vdev *vdev;
2270 
2271 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac_ctx->psoc, vdev_id,
2272 						    WLAN_LEGACY_MAC_ID);
2273 	if (!vdev) {
2274 		sme_err("vdev object is NULL for vdev %d", vdev_id);
2275 		return;
2276 	}
2277 
2278 	cm_get_sta_cxn_info(vdev, buf, buf_sz);
2279 	wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_MAC_ID);
2280 
2281 }
2282 #endif
2283 #endif
2284 
2285 QDF_STATUS csr_roam_call_callback(struct mac_context *mac, uint32_t sessionId,
2286 				  struct csr_roam_info *roam_info,
2287 				  eRoamCmdStatus u1, eCsrRoamResult u2)
2288 {
2289 	QDF_STATUS status = QDF_STATUS_SUCCESS;
2290 	struct csr_roam_session *pSession;
2291 	qdf_freq_t chan_freq;
2292 
2293 	if (!CSR_IS_SESSION_VALID(mac, sessionId)) {
2294 		sme_err("Session ID: %d is not valid", sessionId);
2295 		QDF_ASSERT(0);
2296 		return QDF_STATUS_E_FAILURE;
2297 	}
2298 	pSession = CSR_GET_SESSION(mac, sessionId);
2299 
2300 	if (false == pSession->sessionActive) {
2301 		sme_debug("Session is not Active");
2302 		return QDF_STATUS_E_FAILURE;
2303 	}
2304 	chan_freq = wlan_get_operation_chan_freq_vdev_id(mac->pdev, sessionId);
2305 
2306 	if (mac->session_roam_complete_cb)
2307 		status = mac->session_roam_complete_cb(mac->psoc, sessionId,
2308 						       roam_info, u1, u2);
2309 
2310 	return status;
2311 }
2312 
2313 static bool csr_peer_mac_match_cmd(tSmeCmd *sme_cmd,
2314 				   struct qdf_mac_addr peer_macaddr,
2315 				   uint8_t vdev_id)
2316 {
2317 	if (sme_cmd->command == eSmeCommandRoam &&
2318 	    (sme_cmd->u.roamCmd.roamReason == eCsrForcedDisassocSta ||
2319 	     sme_cmd->u.roamCmd.roamReason == eCsrForcedDeauthSta) &&
2320 	    !qdf_mem_cmp(peer_macaddr.bytes, sme_cmd->u.roamCmd.peerMac,
2321 			 QDF_MAC_ADDR_SIZE))
2322 		return true;
2323 
2324 	if (sme_cmd->command == eSmeCommandWmStatusChange) {
2325 		struct wmstatus_changecmd *wms_cmd;
2326 
2327 		wms_cmd = &sme_cmd->u.wmStatusChangeCmd;
2328 		if (wms_cmd->Type == eCsrDisassociated &&
2329 		    !qdf_mem_cmp(peer_macaddr.bytes,
2330 				 wms_cmd->u.DisassocIndMsg.peer_macaddr.bytes,
2331 				 QDF_MAC_ADDR_SIZE))
2332 			return true;
2333 
2334 		if (wms_cmd->Type == eCsrDeauthenticated &&
2335 		    !qdf_mem_cmp(peer_macaddr.bytes,
2336 				 wms_cmd->u.DeauthIndMsg.peer_macaddr.bytes,
2337 				 QDF_MAC_ADDR_SIZE))
2338 			return true;
2339 	}
2340 
2341 	return false;
2342 }
2343 
2344 static bool
2345 csr_is_deauth_disassoc_in_pending_q(struct mac_context *mac_ctx,
2346 				    uint8_t vdev_id,
2347 				    struct qdf_mac_addr peer_macaddr)
2348 {
2349 	tListElem *entry = NULL;
2350 	tSmeCmd *sme_cmd;
2351 
2352 	entry = csr_nonscan_pending_ll_peek_head(mac_ctx, LL_ACCESS_NOLOCK);
2353 	while (entry) {
2354 		sme_cmd = GET_BASE_ADDR(entry, tSmeCmd, Link);
2355 		if ((sme_cmd->vdev_id == vdev_id) &&
2356 		    csr_peer_mac_match_cmd(sme_cmd, peer_macaddr, vdev_id))
2357 			return true;
2358 		entry = csr_nonscan_pending_ll_next(mac_ctx, entry,
2359 						    LL_ACCESS_NOLOCK);
2360 	}
2361 
2362 	return false;
2363 }
2364 
2365 static bool
2366 csr_is_deauth_disassoc_in_active_q(struct mac_context *mac_ctx,
2367 				   uint8_t vdev_id,
2368 				   struct qdf_mac_addr peer_macaddr)
2369 {
2370 	tSmeCmd *sme_cmd;
2371 
2372 	sme_cmd = wlan_serialization_get_active_cmd(mac_ctx->psoc, vdev_id,
2373 						WLAN_SER_CMD_FORCE_DEAUTH_STA);
2374 
2375 	if (sme_cmd && csr_peer_mac_match_cmd(sme_cmd, peer_macaddr, vdev_id))
2376 		return true;
2377 
2378 	sme_cmd = wlan_serialization_get_active_cmd(mac_ctx->psoc, vdev_id,
2379 					WLAN_SER_CMD_FORCE_DISASSOC_STA);
2380 
2381 	if (sme_cmd && csr_peer_mac_match_cmd(sme_cmd, peer_macaddr, vdev_id))
2382 		return true;
2383 
2384 	/*
2385 	 * WLAN_SER_CMD_WM_STATUS_CHANGE is of two type, the handling
2386 	 * should take care of both the types.
2387 	 */
2388 	sme_cmd = wlan_serialization_get_active_cmd(mac_ctx->psoc, vdev_id,
2389 						WLAN_SER_CMD_WM_STATUS_CHANGE);
2390 	if (sme_cmd && csr_peer_mac_match_cmd(sme_cmd, peer_macaddr, vdev_id))
2391 		return true;
2392 
2393 	return false;
2394 }
2395 
2396 /*
2397  * csr_is_deauth_disassoc_already_active() - Function to check if deauth or
2398  *  disassoc is already in progress.
2399  * @mac_ctx: Global MAC context
2400  * @vdev_id: vdev id
2401  * @peer_macaddr: Peer MAC address
2402  *
2403  * Return: True if deauth/disassoc indication can be dropped
2404  *  else false
2405  */
2406 static bool
2407 csr_is_deauth_disassoc_already_active(struct mac_context *mac_ctx,
2408 				      uint8_t vdev_id,
2409 				      struct qdf_mac_addr peer_macaddr)
2410 {
2411 	bool ret = csr_is_deauth_disassoc_in_pending_q(mac_ctx,
2412 						      vdev_id,
2413 						      peer_macaddr);
2414 	if (!ret)
2415 		/**
2416 		 * commands are not found in pending queue, check in active
2417 		 * queue as well
2418 		 */
2419 		ret = csr_is_deauth_disassoc_in_active_q(mac_ctx,
2420 							  vdev_id,
2421 							  peer_macaddr);
2422 
2423 	if (ret)
2424 		sme_debug("Deauth/Disassoc already in progress for "QDF_MAC_ADDR_FMT,
2425 			  QDF_MAC_ADDR_REF(peer_macaddr.bytes));
2426 
2427 	return ret;
2428 }
2429 
2430 /**
2431  * csr_roam_issue_disassociate_sta_cmd() - disassociate a associated station
2432  * @sessionId:     Session Id for Soft AP
2433  * @p_del_sta_params: Pointer to parameters of the station to disassoc
2434  *
2435  * CSR function that HDD calls to delete a associated station
2436  *
2437  * Return: QDF_STATUS_SUCCESS on success or another QDF_STATUS_* on error
2438  */
2439 QDF_STATUS csr_roam_issue_disassociate_sta_cmd(struct mac_context *mac,
2440 					       uint32_t sessionId,
2441 					       struct csr_del_sta_params
2442 					       *p_del_sta_params)
2443 
2444 {
2445 	QDF_STATUS status = QDF_STATUS_SUCCESS;
2446 	tSmeCmd *pCommand;
2447 
2448 	do {
2449 		if (csr_is_deauth_disassoc_already_active(mac, sessionId,
2450 					      p_del_sta_params->peerMacAddr))
2451 			break;
2452 		pCommand = csr_get_command_buffer(mac);
2453 		if (!pCommand) {
2454 			sme_err("fail to get command buffer");
2455 			status = QDF_STATUS_E_RESOURCES;
2456 			break;
2457 		}
2458 		pCommand->command = eSmeCommandRoam;
2459 		pCommand->vdev_id = (uint8_t) sessionId;
2460 		pCommand->u.roamCmd.roamReason = eCsrForcedDisassocSta;
2461 		qdf_mem_copy(pCommand->u.roamCmd.peerMac,
2462 				p_del_sta_params->peerMacAddr.bytes,
2463 				sizeof(pCommand->u.roamCmd.peerMac));
2464 		pCommand->u.roamCmd.reason = p_del_sta_params->reason_code;
2465 
2466 		status = csr_queue_sme_command(mac, pCommand, false);
2467 		if (!QDF_IS_STATUS_SUCCESS(status))
2468 			sme_err("fail to send message status: %d", status);
2469 	} while (0);
2470 
2471 	return status;
2472 }
2473 
2474 /**
2475  * csr_roam_issue_deauthSta() - delete a associated station
2476  * @sessionId:     Session Id for Soft AP
2477  * @pDelStaParams: Pointer to parameters of the station to deauthenticate
2478  *
2479  * CSR function that HDD calls to delete a associated station
2480  *
2481  * Return: QDF_STATUS_SUCCESS on success or another QDF_STATUS_** on error
2482  */
2483 QDF_STATUS csr_roam_issue_deauth_sta_cmd(struct mac_context *mac,
2484 		uint32_t sessionId,
2485 		struct csr_del_sta_params *pDelStaParams)
2486 {
2487 	QDF_STATUS status = QDF_STATUS_SUCCESS;
2488 	tSmeCmd *pCommand;
2489 
2490 	do {
2491 		if (csr_is_deauth_disassoc_already_active(mac, sessionId,
2492 					      pDelStaParams->peerMacAddr))
2493 			break;
2494 		pCommand = csr_get_command_buffer(mac);
2495 		if (!pCommand) {
2496 			sme_err("fail to get command buffer");
2497 			status = QDF_STATUS_E_RESOURCES;
2498 			break;
2499 		}
2500 		pCommand->command = eSmeCommandRoam;
2501 		pCommand->vdev_id = (uint8_t) sessionId;
2502 		pCommand->u.roamCmd.roamReason = eCsrForcedDeauthSta;
2503 		qdf_mem_copy(pCommand->u.roamCmd.peerMac,
2504 			     pDelStaParams->peerMacAddr.bytes,
2505 			     sizeof(tSirMacAddr));
2506 		pCommand->u.roamCmd.reason = pDelStaParams->reason_code;
2507 
2508 		status = csr_queue_sme_command(mac, pCommand, false);
2509 		if (!QDF_IS_STATUS_SUCCESS(status))
2510 			sme_err("fail to send message status: %d", status);
2511 	} while (0);
2512 
2513 	return status;
2514 }
2515 
2516 /**
2517  * csr_get_peer_stats_cb - Peer stats callback
2518  * @ev: stats event
2519  * @cookie: Void pointer to mac contaxt
2520  *
2521  * Return: None
2522  */
2523 static void csr_get_peer_stats_cb(struct stats_event *ev, void *cookie)
2524 {
2525 	struct mac_context *mac = (struct mac_context *)cookie;
2526 	struct wlan_mlme_psoc_ext_obj *mlme_obj;
2527 
2528 	if (!mac) {
2529 		sme_err("Invalid mac ctx");
2530 		return;
2531 	}
2532 
2533 	mlme_obj = mlme_get_psoc_ext_obj(mac->psoc);
2534 	if (!mlme_obj) {
2535 		sme_err("NULL mlme psoc object");
2536 		return;
2537 	}
2538 
2539 	qdf_mc_timer_stop(
2540 		&mlme_obj->disconnect_stats_param.disconn_stats_timer);
2541 
2542 	if (!ev->peer_stats) {
2543 		sme_debug("no peer stats");
2544 		goto disconnect_stats_complete;
2545 	}
2546 
2547 	mac->peer_rssi = ev->peer_stats->peer_rssi;
2548 	mac->peer_txrate = ev->peer_stats->tx_rate;
2549 	mac->peer_rxrate = ev->peer_stats->rx_rate;
2550 	if (!ev->peer_extended_stats) {
2551 		sme_debug("no peer extended stats");
2552 		goto disconnect_stats_complete;
2553 	}
2554 	mac->rx_mc_bc_cnt = ev->peer_extended_stats->rx_mc_bc_cnt;
2555 
2556 disconnect_stats_complete:
2557 	sme_debug("peer rssi %d tx_rate %d rx_rate %d rx_mc_bc_cnt %d",
2558 		  mac->peer_rssi, mac->peer_txrate, mac->peer_rxrate,
2559 		  mac->rx_mc_bc_cnt);
2560 	csr_continue_peer_disconnect_after_get_stats(mac);
2561 }
2562 
2563 /**
2564  * csr_get_peer_stats - Get Peer stats
2565  * @mac: MAC contaxt
2566  * @session_id: Current session id
2567  * @peer_mac: Peer mac address
2568  *
2569  * Return: None
2570  */
2571 static void csr_get_peer_stats(struct mac_context *mac, uint32_t session_id,
2572 			       struct qdf_mac_addr peer_mac)
2573 {
2574 	struct wlan_objmgr_vdev *vdev;
2575 	struct request_info info = {0};
2576 	QDF_STATUS status;
2577 	struct wlan_mlme_psoc_ext_obj *mlme_obj;
2578 
2579 	mlme_obj = mlme_get_psoc_ext_obj(mac->psoc);
2580 	if (!mlme_obj) {
2581 		sme_err("NULL mlme psoc object");
2582 		return;
2583 	}
2584 	/* Reset is_disconn_stats_completed before error handing. */
2585 	qdf_atomic_set(
2586 		&mlme_obj->disconnect_stats_param.is_disconn_stats_completed,
2587 		0);
2588 
2589 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac->psoc, session_id,
2590 						    WLAN_LEGACY_SME_ID);
2591 
2592 	if (!vdev) {
2593 		csr_continue_peer_disconnect_after_get_stats(mac);
2594 		return;
2595 	}
2596 
2597 	info.cookie = mac;
2598 	info.u.get_peer_rssi_cb = csr_get_peer_stats_cb;
2599 	info.vdev_id = wlan_vdev_get_id(vdev);
2600 	info.pdev_id = wlan_objmgr_pdev_get_pdev_id(wlan_vdev_get_pdev(vdev));
2601 	qdf_mem_copy(info.peer_mac_addr, &peer_mac, QDF_MAC_ADDR_SIZE);
2602 	sme_debug("peer_mac" QDF_MAC_ADDR_FMT,
2603 		  QDF_MAC_ADDR_REF(peer_mac.bytes));
2604 	mlme_obj->disconnect_stats_param.vdev_id = info.vdev_id;
2605 	status = ucfg_mc_cp_stats_send_stats_request(vdev, TYPE_PEER_STATS,
2606 						     &info);
2607 	if (QDF_IS_STATUS_ERROR(status)) {
2608 		sme_err("stats req failed: %d", status);
2609 		wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID);
2610 		csr_continue_peer_disconnect_after_get_stats(mac);
2611 		return;
2612 	}
2613 
2614 	qdf_mc_timer_start(
2615 		&mlme_obj->disconnect_stats_param.disconn_stats_timer,
2616 		SME_CMD_GET_DISCONNECT_STATS_TIMEOUT);
2617 
2618 	wma_get_rx_retry_cnt(mac, session_id, info.peer_mac_addr);
2619 	wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID);
2620 }
2621 
2622 QDF_STATUS csr_roam_process_command(struct mac_context *mac, tSmeCmd *pCommand)
2623 {
2624 	QDF_STATUS status = QDF_STATUS_SUCCESS;
2625 	uint32_t sessionId = pCommand->vdev_id;
2626 	struct csr_roam_session *pSession = CSR_GET_SESSION(mac, sessionId);
2627 	struct qdf_mac_addr peer_mac;
2628 
2629 	if (!pSession) {
2630 		sme_err("session %d not found", sessionId);
2631 		return QDF_STATUS_E_FAILURE;
2632 	}
2633 	sme_debug("Roam Reason: %d sessionId: %d",
2634 		pCommand->u.roamCmd.roamReason, sessionId);
2635 
2636 	switch (pCommand->u.roamCmd.roamReason) {
2637 	case eCsrForcedDisassocSta:
2638 	case eCsrForcedDeauthSta:
2639 		csr_roam_state_change(mac, eCSR_ROAMING_STATE_JOINING,
2640 				      sessionId);
2641 		if (pCommand->u.roamCmd.roamReason == eCsrForcedDeauthSta)
2642 			csr_roam_substate_change(mac,
2643 						 eCSR_ROAM_SUBSTATE_DEAUTH_REQ,
2644 						 sessionId);
2645 		else
2646 			csr_roam_substate_change(
2647 						mac,
2648 						eCSR_ROAM_SUBSTATE_DISASSOC_REQ,
2649 						sessionId);
2650 
2651 		qdf_mem_copy(&peer_mac, &pCommand->u.roamCmd.peerMac,
2652 			     QDF_MAC_ADDR_SIZE);
2653 		/*
2654 		 * Get peer stats before peer gets deleted so that these stats
2655 		 * can be given to user space when big data stats are queried.
2656 		 * Once peer stats are retrieved deauth sta will continue
2657 		 */
2658 		csr_get_peer_stats(mac, sessionId, peer_mac);
2659 		break;
2660 	}
2661 	return status;
2662 }
2663 
2664 void csr_reinit_roam_cmd(struct mac_context *mac, tSmeCmd *pCommand)
2665 {
2666 	/* Because u.roamCmd is union and share with scanCmd and StatusChange */
2667 	qdf_mem_zero(&pCommand->u.roamCmd, sizeof(struct roam_cmd));
2668 }
2669 
2670 void csr_reinit_wm_status_change_cmd(struct mac_context *mac,
2671 			tSmeCmd *pCommand)
2672 {
2673 	qdf_mem_zero(&pCommand->u.wmStatusChangeCmd,
2674 			sizeof(struct wmstatus_changecmd));
2675 }
2676 
2677 void csr_roam_complete(struct mac_context *mac_ctx, uint8_t session_id)
2678 {
2679 	tSmeCmd *sme_cmd;
2680 	struct wlan_serialization_command *cmd;
2681 
2682 	cmd = wlan_serialization_peek_head_active_cmd_using_psoc(
2683 				mac_ctx->psoc, false);
2684 	if (!cmd) {
2685 		sme_err("Roam completion called but cmd is not active");
2686 		return;
2687 	}
2688 	sme_cmd = cmd->umac_cmd;
2689 	if (!sme_cmd) {
2690 		sme_err("sme_cmd is NULL");
2691 		return;
2692 	}
2693 	if (eSmeCommandRoam == sme_cmd->command) {
2694 		csr_roam_process_results_default(mac_ctx, sme_cmd);
2695 		csr_release_command(mac_ctx, sme_cmd);
2696 	}
2697 }
2698 
2699 /* Returns whether the current association is a 11r assoc or not */
2700 bool csr_roam_is11r_assoc(struct mac_context *mac, uint8_t sessionId)
2701 {
2702 	struct cm_roam_values_copy config;
2703 
2704 	wlan_cm_roam_cfg_get_value(mac->psoc, sessionId, IS_11R_CONNECTION,
2705 				   &config);
2706 
2707 	return config.bool_value;
2708 }
2709 
2710 void csr_roam_process_results_default(struct mac_context *mac_ctx,
2711 				      tSmeCmd *cmd)
2712 {
2713 	uint32_t session_id = cmd->vdev_id;
2714 	struct csr_roam_session *session;
2715 	struct csr_roam_info *roam_info;
2716 	QDF_STATUS status;
2717 	enum QDF_OPMODE opmode;
2718 
2719 	if (!CSR_IS_SESSION_VALID(mac_ctx, session_id)) {
2720 		sme_err("Invalid session id %d", session_id);
2721 		return;
2722 	}
2723 	opmode = wlan_get_opmode_from_vdev_id(mac_ctx->pdev, session_id);
2724 	roam_info = qdf_mem_malloc(sizeof(*roam_info));
2725 	if (!roam_info)
2726 		return;
2727 	session = CSR_GET_SESSION(mac_ctx, session_id);
2728 	if (CSR_IS_ROAM_SUBSTATE_STOP_BSS_REQ(mac_ctx, session_id)) {
2729 		/*
2730 		 * do not free for the other profiles as we need
2731 		 * to send down stop BSS later
2732 		 */
2733 		csr_roam_free_connected_info(mac_ctx, &session->connectedInfo);
2734 		csr_set_default_dot11_mode(mac_ctx);
2735 	}
2736 
2737 	switch (cmd->u.roamCmd.roamReason) {
2738 	case eCsrForcedDisassocSta:
2739 	case eCsrForcedDeauthSta:
2740 		roam_info->rssi = mac_ctx->peer_rssi;
2741 		roam_info->tx_rate = mac_ctx->peer_txrate;
2742 		roam_info->rx_rate = mac_ctx->peer_rxrate;
2743 		roam_info->rx_mc_bc_cnt = mac_ctx->rx_mc_bc_cnt;
2744 		roam_info->rx_retry_cnt = mac_ctx->rx_retry_cnt;
2745 
2746 		csr_roam_state_change(mac_ctx, eCSR_ROAMING_STATE_JOINED,
2747 				      session_id);
2748 		if (opmode == QDF_SAP_MODE || opmode == QDF_P2P_GO_MODE) {
2749 			qdf_mem_copy(roam_info->peerMac.bytes,
2750 				     cmd->u.roamCmd.peerMac,
2751 				     sizeof(tSirMacAddr));
2752 			roam_info->reasonCode = eCSR_ROAM_RESULT_FORCED;
2753 			/* Update the MAC reason code */
2754 			roam_info->disassoc_reason = cmd->u.roamCmd.reason;
2755 			roam_info->status_code = eSIR_SME_SUCCESS;
2756 			status = csr_roam_call_callback(mac_ctx, session_id,
2757 							roam_info,
2758 							eCSR_ROAM_LOSTLINK,
2759 							eCSR_ROAM_RESULT_FORCED);
2760 		}
2761 		break;
2762 	default:
2763 		csr_roam_state_change(mac_ctx,
2764 			eCSR_ROAMING_STATE_IDLE, session_id);
2765 		break;
2766 	}
2767 	qdf_mem_free(roam_info);
2768 }
2769 
2770 /**
2771  * csr_roam_process_start_bss_success() - Process the result for start bss
2772  * @mac_ctx:   Global MAC Context
2773  * @context:   Additional data in context of the cmd
2774  * @vdev_id:   vdev id
2775  *
2776  * Return: None
2777  */
2778 static void csr_roam_process_start_bss_success(struct mac_context *mac_ctx,
2779 					       struct csr_roam_info *roam_info,
2780 					       void *context, uint8_t vdev_id)
2781 {
2782 	struct csr_roam_session *session;
2783 	struct start_bss_rsp *start_bss_rsp = NULL;
2784 	eRoamCmdStatus roam_status = eCSR_ROAM_INFRA_IND;
2785 	eCsrRoamResult roam_result = eCSR_ROAM_RESULT_INFRA_STARTED;
2786 	tSirMacAddr bcast_mac = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
2787 	QDF_STATUS status;
2788 	enum QDF_OPMODE opmode;
2789 	uint8_t wmm_mode = 0, value = 0;
2790 
2791 	if (!CSR_IS_SESSION_VALID(mac_ctx, vdev_id)) {
2792 		sme_err("Invalid session id %d", vdev_id);
2793 		return;
2794 	}
2795 	session = CSR_GET_SESSION(mac_ctx, vdev_id);
2796 
2797 	sme_debug("Start BSS success");
2798 	start_bss_rsp = (struct start_bss_rsp *)context;
2799 
2800 	opmode = wlan_get_opmode_from_vdev_id(mac_ctx->pdev, vdev_id);
2801 	if (opmode == QDF_SAP_MODE || opmode == QDF_P2P_GO_MODE)
2802 		session->connectState =
2803 				eCSR_ASSOC_STATE_TYPE_INFRA_DISCONNECTED;
2804 	else if (opmode == QDF_NDI_MODE)
2805 		session->connectState = eCSR_CONNECT_STATE_TYPE_NDI_STARTED;
2806 	else
2807 		session->connectState = eCSR_ASSOC_STATE_TYPE_WDS_DISCONNECTED;
2808 
2809 	if (opmode == QDF_NDI_MODE) {
2810 		status = ucfg_mlme_get_wmm_mode(mac_ctx->psoc, &wmm_mode);
2811 		if (!QDF_IS_STATUS_SUCCESS(status))
2812 			return;
2813 		if (wmm_mode == WMM_USER_MODE_NO_QOS) {
2814 			session->modifyProfileFields.uapsd_mask = 0;
2815 		} else {
2816 			status =
2817 			   ucfg_mlme_get_wmm_uapsd_mask(mac_ctx->psoc, &value);
2818 			if (!QDF_IS_STATUS_SUCCESS(status))
2819 				return;
2820 			session->modifyProfileFields.uapsd_mask = value;
2821 		}
2822 	}
2823 	csr_roam_state_change(mac_ctx, eCSR_ROAMING_STATE_JOINED, vdev_id);
2824 	csr_roam_free_connected_info(mac_ctx, &session->connectedInfo);
2825 	wlan_mlme_get_mac_vdev_id(mac_ctx->pdev, vdev_id, &roam_info->bssid);
2826 
2827 	/* We are done with the IEs so free it */
2828 	/*
2829 	 * Only set context for non-WDS_STA. We don't even need it for
2830 	 * WDS_AP. But since the encryption.
2831 	 * is WPA2-PSK so it won't matter.
2832 	 */
2833 	if (opmode == QDF_SAP_MODE || opmode == QDF_P2P_GO_MODE) {
2834 		if (wlan_is_open_wep_cipher(mac_ctx->pdev, vdev_id)) {
2835 			csr_issue_set_context_req_helper(mac_ctx, vdev_id,
2836 							 &bcast_mac, false,
2837 							 false, 0);
2838 		}
2839 	}
2840 
2841 	/*
2842 	 * Only tell upper layer is we start the BSS because Vista doesn't like
2843 	 * multiple connection indications. If we don't start the BSS ourself,
2844 	 * handler of eSIR_SME_JOINED_NEW_BSS will trigger the connection start
2845 	 * indication in Vista
2846 	 */
2847 	roam_info->staId = (uint8_t)start_bss_rsp->staId;
2848 	if (opmode == QDF_NDI_MODE) {
2849 		csr_roam_update_ndp_return_params(mac_ctx,
2850 						  CSR_SAP_START_BSS_SUCCESS,
2851 						   &roam_status,
2852 						   &roam_result,
2853 						    roam_info);
2854 	}
2855 	/*
2856 	 * Only tell upper layer is we start the BSS because Vista
2857 	 * doesn't like multiple connection indications. If we don't
2858 	 * start the BSS ourself, handler of eSIR_SME_JOINED_NEW_BSS
2859 	 * will trigger the connection start indication in Vista
2860 	 */
2861 	roam_info->status_code = eSIR_SME_SUCCESS;
2862 	csr_roam_call_callback(mac_ctx, vdev_id, roam_info,
2863 			       roam_status, roam_result);
2864 }
2865 
2866 static void csr_flush_pending_start_bss_cmd(struct mac_context *mac_ctx,
2867 					     uint8_t vdev_id)
2868 {
2869 	struct wlan_serialization_queued_cmd_info cmd = {0};
2870 	struct wlan_objmgr_vdev *vdev;
2871 
2872 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac_ctx->psoc, vdev_id,
2873 						    WLAN_LEGACY_SME_ID);
2874 	if (!vdev) {
2875 		sme_err("vdev not found for id %d", vdev_id);
2876 		return;
2877 	}
2878 
2879 	/* Flush any pending vdev start command */
2880 	cmd.vdev = vdev;
2881 	cmd.cmd_type = WLAN_SER_CMD_VDEV_START_BSS;
2882 	cmd.req_type = WLAN_SER_CANCEL_VDEV_NON_SCAN_CMD_TYPE;
2883 	cmd.requestor = WLAN_UMAC_COMP_MLME;
2884 	cmd.queue_type = WLAN_SERIALIZATION_PENDING_QUEUE;
2885 
2886 	wlan_serialization_cancel_request(&cmd);
2887 
2888 	wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID);
2889 }
2890 
2891 bool cm_csr_is_ss_wait_for_key(uint8_t vdev_id)
2892 {
2893 	struct mac_context *mac;
2894 	bool is_wait_for_key = false;
2895 
2896 	mac = sme_get_mac_context();
2897 	if (!mac) {
2898 		sme_err("mac_ctx is NULL");
2899 		return is_wait_for_key;
2900 	}
2901 
2902 	spin_lock(&mac->roam.roam_state_lock);
2903 	if (CSR_IS_WAIT_FOR_KEY(mac, vdev_id))
2904 		is_wait_for_key = true;
2905 	spin_unlock(&mac->roam.roam_state_lock);
2906 
2907 	return is_wait_for_key;
2908 }
2909 
2910 void cm_csr_set_ss_wait_for_key(uint8_t vdev_id)
2911 {
2912 	struct mac_context *mac;
2913 
2914 	mac = sme_get_mac_context();
2915 	if (!mac) {
2916 		sme_err("mac_ctx is NULL");
2917 		return;
2918 	}
2919 
2920 	csr_roam_substate_change(mac, eCSR_ROAM_SUBSTATE_WAIT_FOR_KEY,
2921 				 vdev_id);
2922 }
2923 
2924 void cm_csr_set_joining(uint8_t vdev_id)
2925 {
2926 	struct mac_context *mac;
2927 
2928 	mac = sme_get_mac_context();
2929 	if (!mac) {
2930 		sme_err("mac_ctx is NULL");
2931 		return;
2932 	}
2933 
2934 	csr_roam_state_change(mac, eCSR_ROAMING_STATE_JOINING, vdev_id);
2935 }
2936 
2937 void cm_csr_set_joined(uint8_t vdev_id)
2938 {
2939 	struct mac_context *mac;
2940 
2941 	mac = sme_get_mac_context();
2942 	if (!mac) {
2943 		sme_err("mac_ctx is NULL");
2944 		return;
2945 	}
2946 
2947 	csr_roam_state_change(mac, eCSR_ROAMING_STATE_JOINED, vdev_id);
2948 }
2949 
2950 void cm_csr_set_idle(uint8_t vdev_id)
2951 {
2952 	struct mac_context *mac;
2953 
2954 	mac = sme_get_mac_context();
2955 	if (!mac) {
2956 		sme_err("mac_ctx is NULL");
2957 		return;
2958 	}
2959 
2960 	csr_roam_state_change(mac, eCSR_ROAMING_STATE_IDLE, vdev_id);
2961 }
2962 
2963 void cm_csr_set_ss_none(uint8_t vdev_id)
2964 {
2965 	struct mac_context *mac;
2966 
2967 	mac = sme_get_mac_context();
2968 	if (!mac) {
2969 		sme_err("mac_ctx is NULL");
2970 		return;
2971 	}
2972 
2973 	csr_roam_substate_change(mac, eCSR_ROAM_SUBSTATE_NONE,
2974 				 vdev_id);
2975 }
2976 
2977 QDF_STATUS csr_roam_ndi_stop(struct mac_context *mac_ctx, uint8_t vdev_id)
2978 {
2979 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
2980 	bool is_vdev_up;
2981 	bool is_start_bss_in_active_q = false;
2982 
2983 	csr_flush_pending_start_bss_cmd(mac_ctx, vdev_id);
2984 
2985 	is_vdev_up = wlan_is_vdev_id_up(mac_ctx->pdev, vdev_id);
2986 	if (wlan_serialization_get_active_cmd(mac_ctx->psoc, vdev_id,
2987 					      WLAN_SER_CMD_VDEV_START_BSS))
2988 		is_start_bss_in_active_q = true;
2989 
2990 	sme_debug("vdev_id: %d is_vdev_up %d is_start_bss_in_active_q %d",
2991 		  vdev_id, is_vdev_up, is_start_bss_in_active_q);
2992 
2993 	if (is_vdev_up || is_start_bss_in_active_q)
2994 		status = csr_roam_issue_stop_bss_cmd(mac_ctx, vdev_id,
2995 						     eCSR_BSS_TYPE_NDI);
2996 	return status;
2997 }
2998 
2999 #if defined(WLAN_SAE_SINGLE_PMK) && defined(WLAN_FEATURE_ROAM_OFFLOAD)
3000 static void csr_fill_single_pmk(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id,
3001 				struct bss_description *bss_desc)
3002 {
3003 	struct cm_roam_values_copy src_cfg = {};
3004 
3005 	src_cfg.bool_value = bss_desc->is_single_pmk;
3006 	wlan_cm_roam_cfg_set_value(psoc, vdev_id,
3007 				   IS_SINGLE_PMK, &src_cfg);
3008 }
3009 #else
3010 static inline void
3011 csr_fill_single_pmk(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id,
3012 		    struct bss_description *bss_desc)
3013 {}
3014 #endif
3015 
3016 void csr_roam_roaming_state_stop_bss_rsp_processor(struct mac_context *mac,
3017 						   void *msg)
3018 {
3019 	struct stop_bss_rsp *stop_bss_rsp = (struct stop_bss_rsp *)msg;
3020 	uint8_t vdev_id = stop_bss_rsp->vdev_id;
3021 	enum csr_sap_response_type result_code = CSR_SAP_STOP_BSS_SUCCESS;
3022 
3023 	sme_debug("Received stop bss rsp on vdev: %d", vdev_id);
3024 	mac->roam.roamSession[vdev_id].connectState =
3025 					eCSR_ASSOC_STATE_TYPE_NOT_CONNECTED;
3026 	if (CSR_IS_ROAM_SUBSTATE_STOP_BSS_REQ(mac, vdev_id)) {
3027 		if (stop_bss_rsp->status_code != eSIR_SME_SUCCESS)
3028 			result_code = CSR_SAP_STOP_BSS_FAILURE;
3029 		csr_process_sap_response(mac, result_code, NULL, vdev_id);
3030 	}
3031 }
3032 
3033 static
3034 void csr_roam_roaming_state_disassoc_rsp_processor(struct mac_context *mac,
3035 						   struct disassoc_rsp *rsp)
3036 {
3037 	struct csr_roam_session *pSession;
3038 
3039 	sme_debug("Received disassoc response for vdev : %d status : %d",
3040 		  rsp->sessionId, rsp->status_code);
3041 
3042 	pSession = CSR_GET_SESSION(mac, rsp->sessionId);
3043 	if (!pSession) {
3044 		sme_err("session not found");
3045 		return;
3046 	}
3047 
3048 	csr_roam_complete(mac, rsp->sessionId);
3049 }
3050 
3051 static void csr_roam_roaming_state_deauth_rsp_processor(struct mac_context *mac,
3052 						struct deauth_rsp *rsp)
3053 {
3054 	csr_roam_complete(mac, rsp->sessionId);
3055 }
3056 
3057 void
3058 csr_roam_roaming_state_start_bss_rsp_processor(struct mac_context *mac,
3059 					       void *msg)
3060 {
3061 	enum csr_sap_response_type result;
3062 	struct start_bss_rsp *start_bss_rsp = (struct start_bss_rsp *)msg;
3063 
3064 	if (!CSR_IS_ROAM_SUBSTATE_START_BSS_REQ(mac, start_bss_rsp->vdev_id)) {
3065 		sme_err(" Start bss received in invalid state");
3066 		return;
3067 	}
3068 
3069 	sme_debug("Start Bss response status : %d",
3070 		  start_bss_rsp->status_code);
3071 	if (start_bss_rsp->status_code == eSIR_SME_SUCCESS)
3072 		result = CSR_SAP_START_BSS_SUCCESS;
3073 	else
3074 		result = CSR_SAP_START_BSS_FAILURE;
3075 
3076 	csr_process_sap_response(mac, result, start_bss_rsp,
3077 				 start_bss_rsp->vdev_id);
3078 }
3079 
3080 
3081 /**
3082  * csr_roam_send_disconnect_done_indication() - Send disconnect ind to HDD.
3083  *
3084  * @mac_ctx: mac global context
3085  * @msg_ptr: incoming message
3086  *
3087  * This function gives final disconnect event to HDD after all cleanup in
3088  * lower layers is done.
3089  *
3090  * Return: None
3091  */
3092 static void
3093 csr_roam_send_disconnect_done_indication(struct mac_context *mac_ctx,
3094 					 tSirSmeRsp *msg_ptr)
3095 {
3096 	struct sir_sme_discon_done_ind *discon_ind =
3097 				(struct sir_sme_discon_done_ind *)(msg_ptr);
3098 	struct csr_roam_info *roam_info;
3099 	uint8_t vdev_id;
3100 
3101 	vdev_id = discon_ind->session_id;
3102 	roam_info = qdf_mem_malloc(sizeof(*roam_info));
3103 	if (!roam_info)
3104 		return;
3105 
3106 	sme_debug("DISCONNECT_DONE_IND RC:%d", discon_ind->reason_code);
3107 
3108 	if (CSR_IS_SESSION_VALID(mac_ctx, vdev_id)) {
3109 		roam_info->reasonCode = discon_ind->reason_code;
3110 		roam_info->status_code = eSIR_SME_STA_NOT_ASSOCIATED;
3111 		qdf_mem_copy(roam_info->peerMac.bytes, discon_ind->peer_mac,
3112 			     ETH_ALEN);
3113 
3114 		roam_info->rssi = mac_ctx->peer_rssi;
3115 		roam_info->tx_rate = mac_ctx->peer_txrate;
3116 		roam_info->rx_rate = mac_ctx->peer_rxrate;
3117 		roam_info->disassoc_reason = discon_ind->reason_code;
3118 		roam_info->rx_mc_bc_cnt = mac_ctx->rx_mc_bc_cnt;
3119 		roam_info->rx_retry_cnt = mac_ctx->rx_retry_cnt;
3120 		csr_roam_call_callback(mac_ctx, vdev_id,
3121 				       roam_info, eCSR_ROAM_LOSTLINK,
3122 				       eCSR_ROAM_RESULT_DISASSOC_IND);
3123 	} else {
3124 		sme_err("Inactive vdev_id %d", vdev_id);
3125 	}
3126 
3127 	/*
3128 	 * Release WM status change command as eWNI_SME_DISCONNECT_DONE_IND
3129 	 * has been sent to HDD and there is nothing else left to do.
3130 	 */
3131 	csr_roam_wm_status_change_complete(mac_ctx, vdev_id);
3132 	qdf_mem_free(roam_info);
3133 }
3134 
3135 /**
3136  * csr_roaming_state_msg_processor() - process roaming messages
3137  * @mac:       mac global context
3138  * @msg_buf:    message buffer
3139  *
3140  * We need to be careful on whether to cast msg_buf (pSmeRsp) to other type of
3141  * structures. It depends on how the message is constructed. If the message is
3142  * sent by lim_send_sme_rsp, the msg_buf is only a generic response and can only
3143  * be used as pointer to tSirSmeRsp. For the messages where sender allocates
3144  * memory for specific structures, then it can be cast accordingly.
3145  *
3146  * Return: status of operation
3147  */
3148 void csr_roaming_state_msg_processor(struct mac_context *mac, void *msg_buf)
3149 {
3150 	tSirSmeRsp *pSmeRsp;
3151 
3152 	pSmeRsp = (tSirSmeRsp *)msg_buf;
3153 
3154 	switch (pSmeRsp->messageType) {
3155 	case eWNI_SME_DISASSOC_RSP:
3156 		/* or the Disassociate response message... */
3157 		if (CSR_IS_ROAM_SUBSTATE_DISASSOC_REQ(mac, pSmeRsp->vdev_id)) {
3158 			sme_debug("eWNI_SME_DISASSOC_RSP subState = %s",
3159 				  mac_trace_getcsr_roam_sub_state(
3160 				  mac->roam.curSubState[pSmeRsp->vdev_id]));
3161 			csr_roam_roaming_state_disassoc_rsp_processor(mac,
3162 						(struct disassoc_rsp *) pSmeRsp);
3163 		}
3164 		break;
3165 	case eWNI_SME_DEAUTH_RSP:
3166 		/* or the Deauthentication response message... */
3167 		if (CSR_IS_ROAM_SUBSTATE_DEAUTH_REQ(mac, pSmeRsp->vdev_id))
3168 			csr_roam_roaming_state_deauth_rsp_processor(mac,
3169 						(struct deauth_rsp *) pSmeRsp);
3170 		break;
3171 	/* In case CSR issues STOP_BSS, we need to tell HDD about peer departed
3172 	 * because PE is removing them
3173 	 */
3174 	case eWNI_SME_TRIGGER_SAE:
3175 		sme_debug("Invoke SAE callback");
3176 		csr_sae_callback(mac, pSmeRsp);
3177 		break;
3178 
3179 	case eWNI_SME_SETCONTEXT_RSP:
3180 		csr_roam_check_for_link_status_change(mac, pSmeRsp);
3181 		break;
3182 
3183 	case eWNI_SME_DISCONNECT_DONE_IND:
3184 		csr_roam_send_disconnect_done_indication(mac, pSmeRsp);
3185 		break;
3186 
3187 	case eWNI_SME_UPPER_LAYER_ASSOC_CNF:
3188 		csr_roam_joined_state_msg_processor(mac, pSmeRsp);
3189 		break;
3190 	default:
3191 		sme_debug("Unexpected message type: %d[0x%X] received in substate %s",
3192 			pSmeRsp->messageType, pSmeRsp->messageType,
3193 			mac_trace_getcsr_roam_sub_state(
3194 				mac->roam.curSubState[pSmeRsp->vdev_id]));
3195 		/* If we are connected, check the link status change */
3196 		if (!csr_is_conn_state_disconnected(mac, pSmeRsp->vdev_id))
3197 			csr_roam_check_for_link_status_change(mac, pSmeRsp);
3198 		break;
3199 	}
3200 }
3201 
3202 #ifdef WLAN_FEATURE_11BE_MLO
3203 static void
3204 csr_roam_assoc_cnf_mld_copy(struct csr_roam_info *roam_info,
3205 			    tSirSmeAssocIndToUpperLayerCnf *pUpperLayerAssocCnf,
3206 			    uint32_t num_bytes)
3207 {
3208 	qdf_mem_copy(roam_info->peer_mld.bytes,
3209 		     pUpperLayerAssocCnf->peer_mld_addr,
3210 		     num_bytes);
3211 }
3212 #else /* WLAN_FEATURE_11BE_MLO */
3213 static inline void
3214 csr_roam_assoc_cnf_mld_copy(struct csr_roam_info *roam_info,
3215 			    tSirSmeAssocIndToUpperLayerCnf *pUpperLayerAssocCnf,
3216 			    uint32_t num_bytes)
3217 {
3218 }
3219 #endif /* WLAN_FEATURE_11BE_MLO */
3220 
3221 void csr_roam_joined_state_msg_processor(struct mac_context *mac, void *msg_buf)
3222 {
3223 	tSirSmeRsp *pSirMsg = (tSirSmeRsp *)msg_buf;
3224 
3225 	switch (pSirMsg->messageType) {
3226 	case eWNI_SME_UPPER_LAYER_ASSOC_CNF:
3227 	{
3228 		struct csr_roam_session *pSession;
3229 		tSirSmeAssocIndToUpperLayerCnf *pUpperLayerAssocCnf;
3230 		struct csr_roam_info *roam_info;
3231 		uint32_t sessionId;
3232 		QDF_STATUS status;
3233 		enum QDF_OPMODE opmode;
3234 
3235 		sme_debug("ASSOCIATION confirmation can be given to upper layer ");
3236 		pUpperLayerAssocCnf =
3237 			(tSirSmeAssocIndToUpperLayerCnf *)msg_buf;
3238 		status = csr_roam_get_session_id_from_bssid(mac,
3239 							(struct qdf_mac_addr *)
3240 							   pUpperLayerAssocCnf->
3241 							   bssId, &sessionId);
3242 		pSession = CSR_GET_SESSION(mac, sessionId);
3243 
3244 		if (!pSession) {
3245 			sme_err("session %d not found", sessionId);
3246 			if (pUpperLayerAssocCnf->ies)
3247 				qdf_mem_free(pUpperLayerAssocCnf->ies);
3248 			return;
3249 		}
3250 
3251 		roam_info = qdf_mem_malloc(sizeof(*roam_info));
3252 		if (!roam_info) {
3253 			if (pUpperLayerAssocCnf->ies)
3254 				qdf_mem_free(pUpperLayerAssocCnf->ies);
3255 			return;
3256 		}
3257 		opmode = wlan_get_opmode_from_vdev_id(mac->pdev, sessionId);
3258 		/* send the status code as Success */
3259 		roam_info->status_code = eSIR_SME_SUCCESS;
3260 		roam_info->staId = (uint8_t) pUpperLayerAssocCnf->aid;
3261 		roam_info->rsnIELen =
3262 			(uint8_t) pUpperLayerAssocCnf->rsnIE.length;
3263 		roam_info->prsnIE =
3264 			pUpperLayerAssocCnf->rsnIE.rsnIEdata;
3265 #ifdef FEATURE_WLAN_WAPI
3266 		roam_info->wapiIELen =
3267 			(uint8_t) pUpperLayerAssocCnf->wapiIE.length;
3268 		roam_info->pwapiIE =
3269 			pUpperLayerAssocCnf->wapiIE.wapiIEdata;
3270 #endif
3271 		roam_info->addIELen =
3272 			(uint8_t) pUpperLayerAssocCnf->addIE.length;
3273 		roam_info->paddIE =
3274 			pUpperLayerAssocCnf->addIE.addIEdata;
3275 		qdf_mem_copy(roam_info->peerMac.bytes,
3276 			     pUpperLayerAssocCnf->peerMacAddr,
3277 			     sizeof(tSirMacAddr));
3278 		csr_roam_assoc_cnf_mld_copy(roam_info,
3279 					    pUpperLayerAssocCnf,
3280 					    sizeof(tSirMacAddr));
3281 		qdf_mem_copy(&roam_info->bssid,
3282 			     pUpperLayerAssocCnf->bssId,
3283 			     sizeof(struct qdf_mac_addr));
3284 		roam_info->wmmEnabledSta =
3285 			pUpperLayerAssocCnf->wmmEnabledSta;
3286 		roam_info->timingMeasCap =
3287 			pUpperLayerAssocCnf->timingMeasCap;
3288 		qdf_mem_copy(&roam_info->chan_info,
3289 			     &pUpperLayerAssocCnf->chan_info,
3290 			     sizeof(struct oem_channel_info));
3291 
3292 		roam_info->ampdu = pUpperLayerAssocCnf->ampdu;
3293 		roam_info->sgi_enable = pUpperLayerAssocCnf->sgi_enable;
3294 		roam_info->tx_stbc = pUpperLayerAssocCnf->tx_stbc;
3295 		roam_info->rx_stbc = pUpperLayerAssocCnf->rx_stbc;
3296 		roam_info->ch_width = pUpperLayerAssocCnf->ch_width;
3297 		roam_info->mode = pUpperLayerAssocCnf->mode;
3298 		roam_info->max_supp_idx = pUpperLayerAssocCnf->max_supp_idx;
3299 		roam_info->max_ext_idx = pUpperLayerAssocCnf->max_ext_idx;
3300 		roam_info->max_mcs_idx = pUpperLayerAssocCnf->max_mcs_idx;
3301 		roam_info->max_real_mcs_idx =
3302 					pUpperLayerAssocCnf->max_real_mcs_idx;
3303 		roam_info->rx_mcs_map = pUpperLayerAssocCnf->rx_mcs_map;
3304 		roam_info->tx_mcs_map = pUpperLayerAssocCnf->tx_mcs_map;
3305 		roam_info->ecsa_capable = pUpperLayerAssocCnf->ecsa_capable;
3306 		roam_info->ext_cap = pUpperLayerAssocCnf->ext_cap;
3307 		roam_info->supported_band =
3308 					pUpperLayerAssocCnf->supported_band;
3309 		if (pUpperLayerAssocCnf->ht_caps.present)
3310 			roam_info->ht_caps = pUpperLayerAssocCnf->ht_caps;
3311 		if (pUpperLayerAssocCnf->vht_caps.present)
3312 			roam_info->vht_caps = pUpperLayerAssocCnf->vht_caps;
3313 		roam_info->capability_info =
3314 					pUpperLayerAssocCnf->capability_info;
3315 		roam_info->he_caps_present =
3316 					pUpperLayerAssocCnf->he_caps_present;
3317 		roam_info->eht_caps_present =
3318 			pUpperLayerAssocCnf->eht_caps_present;
3319 		if (opmode == QDF_SAP_MODE || opmode == QDF_P2P_GO_MODE) {
3320 			if (pUpperLayerAssocCnf->ies_len > 0) {
3321 				roam_info->assocReqLength =
3322 						pUpperLayerAssocCnf->ies_len;
3323 				roam_info->assocReqPtr =
3324 						pUpperLayerAssocCnf->ies;
3325 			}
3326 
3327 			mac->roam.roamSession[sessionId].connectState =
3328 				eCSR_ASSOC_STATE_TYPE_INFRA_CONNECTED;
3329 			roam_info->fReassocReq =
3330 				pUpperLayerAssocCnf->reassocReq;
3331 			status = csr_roam_call_callback(mac, sessionId,
3332 						       roam_info,
3333 						       eCSR_ROAM_INFRA_IND,
3334 					eCSR_ROAM_RESULT_INFRA_ASSOCIATION_CNF);
3335 		}
3336 		if (pUpperLayerAssocCnf->ies)
3337 			qdf_mem_free(pUpperLayerAssocCnf->ies);
3338 		qdf_mem_free(roam_info);
3339 	}
3340 	break;
3341 	default:
3342 		csr_roam_check_for_link_status_change(mac, pSirMsg);
3343 		break;
3344 	}
3345 }
3346 
3347 /**
3348  * csr_update_wep_key_peer_macaddr() - Update wep key peer mac addr
3349  * @vdev: vdev object
3350  * @crypto_key: crypto key info
3351  * @unicast: uncast or broadcast
3352  * @mac_addr: peer mac address
3353  *
3354  * Update peer mac address to key context before set wep key to target.
3355  *
3356  * Return void
3357  */
3358 static void
3359 csr_update_wep_key_peer_macaddr(struct wlan_objmgr_vdev *vdev,
3360 				struct wlan_crypto_key *crypto_key,
3361 				bool unicast,
3362 				struct qdf_mac_addr *mac_addr)
3363 {
3364 	if (!crypto_key || !vdev) {
3365 		sme_err("vdev or crytpo_key null");
3366 		return;
3367 	}
3368 
3369 	if (unicast) {
3370 		qdf_mem_copy(&crypto_key->macaddr, mac_addr,
3371 			     QDF_MAC_ADDR_SIZE);
3372 	} else {
3373 		if (vdev->vdev_mlme.vdev_opmode == QDF_STA_MODE ||
3374 		    vdev->vdev_mlme.vdev_opmode == QDF_P2P_CLIENT_MODE)
3375 			qdf_mem_copy(&crypto_key->macaddr, mac_addr,
3376 				     QDF_MAC_ADDR_SIZE);
3377 		else
3378 			qdf_mem_copy(&crypto_key->macaddr,
3379 				     vdev->vdev_mlme.macaddr,
3380 				     QDF_MAC_ADDR_SIZE);
3381 	}
3382 }
3383 
3384 #ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
3385 static void
3386 csr_roam_diag_set_ctx_rsp(struct mac_context *mac_ctx,
3387 			  struct csr_roam_session *session,
3388 			  struct set_context_rsp *pRsp)
3389 {
3390 	WLAN_HOST_DIAG_EVENT_DEF(setKeyEvent,
3391 				 host_event_wlan_security_payload_type);
3392 	struct wlan_objmgr_vdev *vdev;
3393 
3394 	vdev = wlan_objmgr_get_vdev_by_id_from_pdev(mac_ctx->pdev,
3395 						    session->vdev_id,
3396 						    WLAN_LEGACY_SME_ID);
3397 	if (!vdev)
3398 		return;
3399 	if (cm_is_open_mode(vdev)) {
3400 		wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID);
3401 		return;
3402 	}
3403 	wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID);
3404 
3405 	qdf_mem_zero(&setKeyEvent,
3406 		     sizeof(host_event_wlan_security_payload_type));
3407 	if (qdf_is_macaddr_group(&pRsp->peer_macaddr))
3408 		setKeyEvent.eventId =
3409 			WLAN_SECURITY_EVENT_SET_BCAST_RSP;
3410 	else
3411 		setKeyEvent.eventId =
3412 			WLAN_SECURITY_EVENT_SET_UNICAST_RSP;
3413 	cm_diag_get_auth_enc_type_vdev_id(mac_ctx->psoc,
3414 					  &setKeyEvent.authMode,
3415 					  &setKeyEvent.encryptionModeUnicast,
3416 					  &setKeyEvent.encryptionModeMulticast,
3417 					  session->vdev_id);
3418 	wlan_mlme_get_bssid_vdev_id(mac_ctx->pdev, session->vdev_id,
3419 				    (struct qdf_mac_addr *)&setKeyEvent.bssid);
3420 	if (eSIR_SME_SUCCESS != pRsp->status_code)
3421 		setKeyEvent.status = WLAN_SECURITY_STATUS_FAILURE;
3422 	WLAN_HOST_DIAG_EVENT_REPORT(&setKeyEvent, EVENT_WLAN_SECURITY);
3423 }
3424 #else /* FEATURE_WLAN_DIAG_SUPPORT_CSR */
3425 static void
3426 csr_roam_diag_set_ctx_rsp(struct mac_context *mac_ctx,
3427 			  struct csr_roam_session *session,
3428 			  struct set_context_rsp *pRsp)
3429 {
3430 }
3431 #endif /* FEATURE_WLAN_DIAG_SUPPORT_CSR */
3432 
3433 #ifdef WLAN_FEATURE_11BE_MLO
3434 static QDF_STATUS
3435 csr_roam_send_rso_enable(struct mac_context *mac_ctx, uint8_t vdev_id)
3436 {
3437 	struct wlan_objmgr_vdev *vdev = NULL;
3438 	struct wlan_objmgr_vdev *assoc_vdev = NULL;
3439 
3440 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac_ctx->psoc,
3441 						    vdev_id,
3442 						    WLAN_MLME_OBJMGR_ID);
3443 	if (!vdev) {
3444 		sme_err("vdev object is NULL for vdev %d", vdev_id);
3445 		return QDF_STATUS_E_FAILURE;
3446 	}
3447 
3448 	if (wlan_vdev_mlme_is_mlo_vdev(vdev) &&
3449 	    mlo_check_if_all_links_up(vdev)) {
3450 		assoc_vdev = wlan_mlo_get_assoc_link_vdev(vdev);
3451 		if (!assoc_vdev) {
3452 			sme_err("Assoc vdev is null");
3453 			wlan_objmgr_vdev_release_ref(vdev,
3454 						     WLAN_MLME_OBJMGR_ID);
3455 			return QDF_STATUS_E_FAILURE;
3456 		}
3457 		cm_roam_start_init_on_connect(mac_ctx->pdev,
3458 					      wlan_vdev_get_id(assoc_vdev));
3459 	} else if (!wlan_vdev_mlme_is_mlo_vdev(vdev)) {
3460 		cm_roam_start_init_on_connect(mac_ctx->pdev, vdev_id);
3461 	}
3462 	wlan_objmgr_vdev_release_ref(vdev,
3463 				     WLAN_MLME_OBJMGR_ID);
3464 	return QDF_STATUS_SUCCESS;
3465 }
3466 #else
3467 static QDF_STATUS
3468 csr_roam_send_rso_enable(struct mac_context *mac_ctx, uint8_t vdev_id)
3469 {
3470 	cm_roam_start_init_on_connect(mac_ctx->pdev, vdev_id);
3471 	return QDF_STATUS_SUCCESS;
3472 }
3473 #endif
3474 
3475 static void
3476 csr_roam_chk_lnk_set_ctx_rsp(struct mac_context *mac_ctx, tSirSmeRsp *msg_ptr)
3477 {
3478 	struct csr_roam_session *session;
3479 	uint32_t sessionId = WLAN_UMAC_VDEV_ID_MAX;
3480 	QDF_STATUS status;
3481 	qdf_freq_t chan_freq;
3482 	struct csr_roam_info *roam_info;
3483 	eCsrRoamResult result = eCSR_ROAM_RESULT_NONE;
3484 	struct set_context_rsp *pRsp = (struct set_context_rsp *)msg_ptr;
3485 	struct qdf_mac_addr connected_bssid;
3486 
3487 	if (!pRsp) {
3488 		sme_err("set key response is NULL");
3489 		return;
3490 	}
3491 
3492 	roam_info = qdf_mem_malloc(sizeof(*roam_info));
3493 	if (!roam_info)
3494 		return;
3495 	sessionId = pRsp->sessionId;
3496 	session = CSR_GET_SESSION(mac_ctx, sessionId);
3497 	if (!session) {
3498 		sme_err("session %d not found", sessionId);
3499 		qdf_mem_free(roam_info);
3500 		return;
3501 	}
3502 
3503 	csr_roam_diag_set_ctx_rsp(mac_ctx, session, pRsp);
3504 	chan_freq = wlan_get_operation_chan_freq_vdev_id(mac_ctx->pdev,
3505 							 sessionId);
3506 	wlan_mlme_get_bssid_vdev_id(mac_ctx->pdev, sessionId,
3507 				    &connected_bssid);
3508 	sme_debug("vdev %d, Status %d, peer_macaddr "QDF_MAC_ADDR_FMT " obss offload %d freq %d opmode %d",
3509 		  pRsp->sessionId, pRsp->status_code,
3510 		  QDF_MAC_ADDR_REF(pRsp->peer_macaddr.bytes),
3511 		  mac_ctx->obss_scan_offload, chan_freq,
3512 		  wlan_get_opmode_from_vdev_id(mac_ctx->pdev, sessionId));
3513 
3514 	if (CSR_IS_WAIT_FOR_KEY(mac_ctx, sessionId)) {
3515 		/* We are done with authentication, whethere succeed or not */
3516 		csr_roam_substate_change(mac_ctx, eCSR_ROAM_SUBSTATE_NONE,
3517 					 sessionId);
3518 		cm_stop_wait_for_key_timer(mac_ctx->psoc, sessionId);
3519 		if (QDF_IS_STATUS_ERROR(csr_roam_send_rso_enable(mac_ctx,
3520 								 sessionId))) {
3521 			qdf_mem_free(roam_info);
3522 			return;
3523 		}
3524 	}
3525 	if (eSIR_SME_SUCCESS == pRsp->status_code) {
3526 		qdf_copy_macaddr(&roam_info->peerMac, &pRsp->peer_macaddr);
3527 		/* Make sure we install the GTK before indicating to HDD as
3528 		 * authenticated. This is to prevent broadcast packets go out
3529 		 * after PTK and before GTK.
3530 		 */
3531 		if (qdf_is_macaddr_broadcast(&pRsp->peer_macaddr)) {
3532 			/*
3533 			 * OBSS SCAN Indication will be sent to Firmware
3534 			 * to start OBSS Scan
3535 			 */
3536 			if (mac_ctx->obss_scan_offload &&
3537 			    wlan_reg_is_24ghz_ch_freq(chan_freq) &&
3538 			    cm_is_vdevid_connected(mac_ctx->pdev, sessionId)) {
3539 				struct sme_obss_ht40_scanind_msg *msg;
3540 
3541 				msg = qdf_mem_malloc(sizeof(
3542 					struct sme_obss_ht40_scanind_msg));
3543 				if (!msg) {
3544 					qdf_mem_free(roam_info);
3545 					return;
3546 				}
3547 
3548 				msg->msg_type = eWNI_SME_HT40_OBSS_SCAN_IND;
3549 				msg->length =
3550 				      sizeof(struct sme_obss_ht40_scanind_msg);
3551 				qdf_copy_macaddr(&msg->mac_addr,
3552 					&connected_bssid);
3553 				status = umac_send_mb_message_to_mac(msg);
3554 			}
3555 			result = eCSR_ROAM_RESULT_AUTHENTICATED;
3556 		} else {
3557 			result = eCSR_ROAM_RESULT_NONE;
3558 		}
3559 	} else {
3560 		result = eCSR_ROAM_RESULT_FAILURE;
3561 		sme_err(
3562 			"CSR: setkey command failed(err=%d) PeerMac "
3563 			QDF_MAC_ADDR_FMT,
3564 			pRsp->status_code,
3565 			QDF_MAC_ADDR_REF(pRsp->peer_macaddr.bytes));
3566 	}
3567 	csr_roam_call_callback(mac_ctx, sessionId, roam_info,
3568 			       eCSR_ROAM_SET_KEY_COMPLETE, result);
3569 	/* Indicate SME_QOS that the SET_KEY is completed, so that SME_QOS
3570 	 * can go ahead and initiate the TSPEC if any are pending
3571 	 */
3572 	sme_qos_csr_event_ind(mac_ctx, (uint8_t)sessionId,
3573 			      SME_QOS_CSR_SET_KEY_SUCCESS_IND, NULL);
3574 #ifdef FEATURE_WLAN_ESE
3575 	/* Send Adjacent AP repot to new AP. */
3576 	if (result == eCSR_ROAM_RESULT_AUTHENTICATED &&
3577 	    session->isPrevApInfoValid &&
3578 	    wlan_cm_get_ese_assoc(mac_ctx->pdev, sessionId)) {
3579 		csr_send_ese_adjacent_ap_rep_ind(mac_ctx, session);
3580 		session->isPrevApInfoValid = false;
3581 	}
3582 #endif
3583 	qdf_mem_free(roam_info);
3584 }
3585 
3586 static QDF_STATUS csr_roam_issue_set_context_req(struct mac_context *mac_ctx,
3587 						 uint32_t session_id,
3588 						 bool add_key, bool unicast,
3589 						 uint8_t key_idx,
3590 						 struct qdf_mac_addr *mac_addr)
3591 {
3592 	enum wlan_crypto_cipher_type cipher;
3593 	struct wlan_crypto_key *crypto_key;
3594 	uint8_t wep_key_idx = 0;
3595 	struct wlan_objmgr_vdev *vdev;
3596 
3597 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac_ctx->psoc, session_id,
3598 						    WLAN_LEGACY_MAC_ID);
3599 	if (!vdev) {
3600 		sme_err("VDEV object not found for session_id %d", session_id);
3601 		return QDF_STATUS_E_INVAL;
3602 	}
3603 	cipher = wlan_crypto_get_cipher(vdev, unicast, key_idx);
3604 	if (IS_WEP_CIPHER(cipher)) {
3605 		wep_key_idx = wlan_crypto_get_default_key_idx(vdev, !unicast);
3606 		crypto_key = wlan_crypto_get_key(vdev, wep_key_idx);
3607 		csr_update_wep_key_peer_macaddr(vdev, crypto_key, unicast,
3608 						mac_addr);
3609 	} else {
3610 		crypto_key = wlan_crypto_get_key(vdev, key_idx);
3611 	}
3612 
3613 	wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_MAC_ID);
3614 
3615 	sme_debug("session:%d, cipher:%d, ucast:%d, idx:%d, wep:%d, add:%d",
3616 		  session_id, cipher, unicast, key_idx, wep_key_idx, add_key);
3617 	if (!IS_WEP_CIPHER(cipher) && !add_key)
3618 		return QDF_STATUS_E_INVAL;
3619 
3620 	return ucfg_crypto_set_key_req(vdev, crypto_key, (unicast ?
3621 				       WLAN_CRYPTO_KEY_TYPE_UNICAST :
3622 				       WLAN_CRYPTO_KEY_TYPE_GROUP));
3623 }
3624 
3625 QDF_STATUS
3626 csr_issue_set_context_req_helper(struct mac_context *mac_ctx,
3627 				 uint32_t vdev_id, tSirMacAddr *bssid,
3628 				 bool addkey, bool unicast, uint8_t key_id)
3629 {
3630 	return csr_roam_issue_set_context_req(mac_ctx, vdev_id, addkey,
3631 					      unicast, key_id,
3632 					      (struct qdf_mac_addr *)bssid);
3633 }
3634 
3635 static
3636 bool csr_roam_issue_wm_status_change(struct mac_context *mac, uint32_t sessionId,
3637 				     enum csr_roam_wmstatus_changetypes Type,
3638 				     tSirSmeRsp *pSmeRsp)
3639 {
3640 	bool fCommandQueued = false;
3641 	tSmeCmd *pCommand;
3642 
3643 	do {
3644 		/* Validate the type is ok... */
3645 		if ((eCsrDisassociated != Type)
3646 		    && (eCsrDeauthenticated != Type))
3647 			break;
3648 		pCommand = csr_get_command_buffer(mac);
3649 		if (!pCommand) {
3650 			sme_err(" fail to get command buffer");
3651 			break;
3652 		}
3653 
3654 		pCommand->command = eSmeCommandWmStatusChange;
3655 		pCommand->vdev_id = (uint8_t) sessionId;
3656 		pCommand->u.wmStatusChangeCmd.Type = Type;
3657 		if (eCsrDisassociated == Type) {
3658 			qdf_mem_copy(&pCommand->u.wmStatusChangeCmd.u.
3659 				     DisassocIndMsg, pSmeRsp,
3660 				     sizeof(pCommand->u.wmStatusChangeCmd.u.
3661 					    DisassocIndMsg));
3662 		} else {
3663 			qdf_mem_copy(&pCommand->u.wmStatusChangeCmd.u.
3664 				     DeauthIndMsg, pSmeRsp,
3665 				     sizeof(pCommand->u.wmStatusChangeCmd.u.
3666 					    DeauthIndMsg));
3667 		}
3668 		if (QDF_IS_STATUS_SUCCESS
3669 			    (csr_queue_sme_command(mac, pCommand, false)))
3670 			fCommandQueued = true;
3671 		else
3672 			sme_err("fail to send message");
3673 	} while (0);
3674 	return fCommandQueued;
3675 }
3676 
3677 static void csr_update_snr(struct mac_context *mac, void *pMsg)
3678 {
3679 	tAniGetSnrReq *pGetSnrReq = (tAniGetSnrReq *) pMsg;
3680 
3681 	if (pGetSnrReq) {
3682 		if (QDF_STATUS_SUCCESS != wma_get_snr(pGetSnrReq)) {
3683 			sme_err("Error in wma_get_snr");
3684 			return;
3685 		}
3686 
3687 	} else
3688 		sme_err("pGetSnrReq is NULL");
3689 }
3690 
3691 /**
3692  * csr_translate_akm_type() - Convert ani_akm_type value to equivalent
3693  * enum csr_akm_type
3694  * @akm_type: value of type ani_akm_type
3695  *
3696  * Return: enum csr_akm_type value
3697  */
3698 static enum csr_akm_type csr_translate_akm_type(enum ani_akm_type akm_type)
3699 {
3700 	enum csr_akm_type csr_akm_type;
3701 
3702 	switch (akm_type)
3703 	{
3704 	case ANI_AKM_TYPE_NONE:
3705 		csr_akm_type = eCSR_AUTH_TYPE_NONE;
3706 		break;
3707 #ifdef WLAN_FEATURE_SAE
3708 	case ANI_AKM_TYPE_SAE:
3709 		csr_akm_type = eCSR_AUTH_TYPE_SAE;
3710 		break;
3711 #endif
3712 	case ANI_AKM_TYPE_WPA:
3713 		csr_akm_type = eCSR_AUTH_TYPE_WPA;
3714 		break;
3715 	case ANI_AKM_TYPE_WPA_PSK:
3716 		csr_akm_type = eCSR_AUTH_TYPE_WPA_PSK;
3717 		break;
3718 	case ANI_AKM_TYPE_RSN:
3719 		csr_akm_type = eCSR_AUTH_TYPE_RSN;
3720 		break;
3721 	case ANI_AKM_TYPE_RSN_PSK:
3722 		csr_akm_type = eCSR_AUTH_TYPE_RSN_PSK;
3723 		break;
3724 	case ANI_AKM_TYPE_FT_RSN:
3725 		csr_akm_type = eCSR_AUTH_TYPE_FT_RSN;
3726 		break;
3727 	case ANI_AKM_TYPE_FT_RSN_PSK:
3728 		csr_akm_type = eCSR_AUTH_TYPE_FT_RSN_PSK;
3729 		break;
3730 #ifdef FEATURE_WLAN_ESE
3731 	case ANI_AKM_TYPE_CCKM:
3732 		csr_akm_type = eCSR_AUTH_TYPE_CCKM_RSN;
3733 		break;
3734 #endif
3735 	case ANI_AKM_TYPE_RSN_PSK_SHA256:
3736 		csr_akm_type = eCSR_AUTH_TYPE_RSN_PSK_SHA256;
3737 		break;
3738 	case ANI_AKM_TYPE_RSN_8021X_SHA256:
3739 		csr_akm_type = eCSR_AUTH_TYPE_RSN_8021X_SHA256;
3740 		break;
3741 	case ANI_AKM_TYPE_FILS_SHA256:
3742 		csr_akm_type = eCSR_AUTH_TYPE_FILS_SHA256;
3743 		break;
3744 	case ANI_AKM_TYPE_FILS_SHA384:
3745 		csr_akm_type = eCSR_AUTH_TYPE_FILS_SHA384;
3746 		break;
3747 	case ANI_AKM_TYPE_FT_FILS_SHA256:
3748 		csr_akm_type = eCSR_AUTH_TYPE_FT_FILS_SHA256;
3749 		break;
3750 	case ANI_AKM_TYPE_FT_FILS_SHA384:
3751 		csr_akm_type = eCSR_AUTH_TYPE_FT_FILS_SHA384;
3752 		break;
3753 	case ANI_AKM_TYPE_DPP_RSN:
3754 		csr_akm_type = eCSR_AUTH_TYPE_DPP_RSN;
3755 		break;
3756 	case ANI_AKM_TYPE_OWE:
3757 		csr_akm_type = eCSR_AUTH_TYPE_OWE;
3758 		break;
3759 	case ANI_AKM_TYPE_SUITEB_EAP_SHA256:
3760 		csr_akm_type = eCSR_AUTH_TYPE_SUITEB_EAP_SHA256;
3761 		break;
3762 	case ANI_AKM_TYPE_SUITEB_EAP_SHA384:
3763 		csr_akm_type = eCSR_AUTH_TYPE_SUITEB_EAP_SHA384;
3764 		break;
3765 	case ANI_AKM_TYPE_OSEN:
3766 		csr_akm_type = eCSR_AUTH_TYPE_OSEN;
3767 		break;
3768 	default:
3769 		csr_akm_type = eCSR_AUTH_TYPE_UNKNOWN;
3770 	}
3771 
3772 	return csr_akm_type;
3773 }
3774 
3775 #ifdef WLAN_FEATURE_11BE_MLO
3776 static void
3777 csr_send_assoc_ind_to_upper_layer_mac_copy(tSirSmeAssocIndToUpperLayerCnf *cnf,
3778 					   struct assoc_ind *ind)
3779 {
3780 	qdf_mem_copy(&cnf->peer_mld_addr, &ind->peer_mld_addr,
3781 		     sizeof(cnf->peer_mld_addr));
3782 }
3783 #else /* WLAN_FEATURE_11BE_MLO */
3784 static inline void
3785 csr_send_assoc_ind_to_upper_layer_mac_copy(tSirSmeAssocIndToUpperLayerCnf *cnf,
3786 					   struct assoc_ind *ind)
3787 {
3788 }
3789 #endif /* WLAN_FEATURE_11BE_MLO */
3790 
3791 static QDF_STATUS
3792 csr_send_assoc_ind_to_upper_layer_cnf_msg(struct mac_context *mac,
3793 					  struct assoc_ind *ind,
3794 					  QDF_STATUS status,
3795 					  uint8_t vdev_id)
3796 {
3797 	struct scheduler_msg msg = {0};
3798 	tSirSmeAssocIndToUpperLayerCnf *cnf;
3799 
3800 	cnf = qdf_mem_malloc(sizeof(*cnf));
3801 	if (!cnf)
3802 		return QDF_STATUS_E_NOMEM;
3803 
3804 	cnf->messageType = eWNI_SME_UPPER_LAYER_ASSOC_CNF;
3805 	cnf->length = sizeof(*cnf);
3806 	cnf->sessionId = vdev_id;
3807 
3808 	if (QDF_IS_STATUS_SUCCESS(status))
3809 		cnf->status_code = eSIR_SME_SUCCESS;
3810 	else
3811 		cnf->status_code = eSIR_SME_ASSOC_REFUSED;
3812 	qdf_mem_copy(&cnf->bssId, &ind->bssId, sizeof(cnf->bssId));
3813 	qdf_mem_copy(&cnf->peerMacAddr, &ind->peerMacAddr,
3814 		     sizeof(cnf->peerMacAddr));
3815 	csr_send_assoc_ind_to_upper_layer_mac_copy(cnf, ind);
3816 	cnf->aid = ind->staId;
3817 	cnf->wmmEnabledSta = ind->wmmEnabledSta;
3818 	cnf->rsnIE = ind->rsnIE;
3819 #ifdef FEATURE_WLAN_WAPI
3820 	cnf->wapiIE = ind->wapiIE;
3821 #endif
3822 	cnf->addIE = ind->addIE;
3823 	cnf->reassocReq = ind->reassocReq;
3824 	cnf->timingMeasCap = ind->timingMeasCap;
3825 	cnf->chan_info = ind->chan_info;
3826 	cnf->ampdu = ind->ampdu;
3827 	cnf->sgi_enable = ind->sgi_enable;
3828 	cnf->tx_stbc = ind->tx_stbc;
3829 	cnf->ch_width = ind->ch_width;
3830 	cnf->mode = ind->mode;
3831 	cnf->rx_stbc = ind->rx_stbc;
3832 	cnf->max_supp_idx = ind->max_supp_idx;
3833 	cnf->max_ext_idx = ind->max_ext_idx;
3834 	cnf->max_mcs_idx = ind->max_mcs_idx;
3835 	cnf->max_real_mcs_idx = ind->max_real_mcs_idx;
3836 	cnf->rx_mcs_map = ind->rx_mcs_map;
3837 	cnf->tx_mcs_map = ind->tx_mcs_map;
3838 	cnf->ecsa_capable = ind->ecsa_capable;
3839 	cnf->ext_cap = ind->ext_cap;
3840 	cnf->supported_band = ind->supported_band;
3841 	if (ind->HTCaps.present)
3842 		cnf->ht_caps = ind->HTCaps;
3843 	if (ind->VHTCaps.present)
3844 		cnf->vht_caps = ind->VHTCaps;
3845 	cnf->capability_info = ind->capability_info;
3846 	cnf->he_caps_present = ind->he_caps_present;
3847 	cnf->eht_caps_present = ind->eht_caps_present;
3848 	if (ind->assocReqPtr) {
3849 		if (ind->assocReqLength < MAX_ASSOC_REQ_IE_LEN) {
3850 			cnf->ies = qdf_mem_malloc(ind->assocReqLength);
3851 			if (!cnf->ies) {
3852 				qdf_mem_free(cnf);
3853 				return QDF_STATUS_E_NOMEM;
3854 			}
3855 			cnf->ies_len = ind->assocReqLength;
3856 			qdf_mem_copy(cnf->ies, ind->assocReqPtr,
3857 				     cnf->ies_len);
3858 		} else {
3859 			sme_err("Assoc Ie length is too long");
3860 		}
3861 	}
3862 
3863 	msg.type = eWNI_SME_UPPER_LAYER_ASSOC_CNF;
3864 	msg.bodyptr = cnf;
3865 	sys_process_mmh_msg(mac, &msg);
3866 
3867 	return QDF_STATUS_SUCCESS;
3868 }
3869 
3870 static void
3871 csr_roam_chk_lnk_assoc_ind_upper_layer(
3872 		struct mac_context *mac_ctx, tSirSmeRsp *msg_ptr)
3873 {
3874 	uint32_t session_id = WLAN_UMAC_VDEV_ID_MAX;
3875 	struct assoc_ind *assoc_ind;
3876 	QDF_STATUS status;
3877 
3878 	assoc_ind = (struct assoc_ind *)msg_ptr;
3879 	status = csr_roam_get_session_id_from_bssid(
3880 			mac_ctx, (struct qdf_mac_addr *)assoc_ind->bssId,
3881 			&session_id);
3882 	if (!QDF_IS_STATUS_SUCCESS(status)) {
3883 		sme_debug("Couldn't find session_id for given BSSID");
3884 		goto free_mem;
3885 	}
3886 	csr_send_assoc_ind_to_upper_layer_cnf_msg(
3887 					mac_ctx, assoc_ind, status, session_id);
3888 	/*in the association response tx compete case,
3889 	 *memory for assoc_ind->assocReqPtr will be malloced
3890 	 *in the lim_assoc_rsp_tx_complete -> lim_fill_sme_assoc_ind_params
3891 	 *and then assoc_ind will pass here, so after using it
3892 	 *in the csr_send_assoc_ind_to_upper_layer_cnf_msg and
3893 	 *then free the memory here.
3894 	 */
3895 free_mem:
3896 	if (assoc_ind->assocReqLength != 0 && assoc_ind->assocReqPtr)
3897 		qdf_mem_free(assoc_ind->assocReqPtr);
3898 }
3899 
3900 static void
3901 csr_roam_chk_lnk_assoc_ind(struct mac_context *mac_ctx, tSirSmeRsp *msg_ptr)
3902 {
3903 	struct csr_roam_session *session;
3904 	uint32_t sessionId = WLAN_UMAC_VDEV_ID_MAX;
3905 	QDF_STATUS status;
3906 	struct csr_roam_info *roam_info;
3907 	struct assoc_ind *pAssocInd;
3908 	enum wlan_status_code mac_status_code = STATUS_SUCCESS;
3909 	enum csr_akm_type csr_akm_type;
3910 	enum QDF_OPMODE opmode;
3911 
3912 	sme_debug("Receive WNI_SME_ASSOC_IND from SME");
3913 	pAssocInd = (struct assoc_ind *) msg_ptr;
3914 	sme_debug("Receive WNI_SME_ASSOC_IND from SME vdev id %d",
3915 		  pAssocInd->sessionId);
3916 	status = csr_roam_get_session_id_from_bssid(mac_ctx,
3917 				(struct qdf_mac_addr *) pAssocInd->bssId,
3918 				&sessionId);
3919 	if (!QDF_IS_STATUS_SUCCESS(status)) {
3920 		sme_debug("Couldn't find session_id for given BSSID" QDF_MAC_ADDR_FMT,
3921 			  QDF_MAC_ADDR_REF(pAssocInd->bssId));
3922 		return;
3923 	}
3924 	session = CSR_GET_SESSION(mac_ctx, sessionId);
3925 	if (!session) {
3926 		sme_err("session %d not found", sessionId);
3927 		return;
3928 	}
3929 	csr_akm_type = csr_translate_akm_type(pAssocInd->akm_type);
3930 
3931 	roam_info = qdf_mem_malloc(sizeof(*roam_info));
3932 	if (!roam_info)
3933 		return;
3934 	opmode = wlan_get_opmode_from_vdev_id(mac_ctx->pdev, sessionId);
3935 	/* Required for indicating the frames to upper layer */
3936 	roam_info->assocReqLength = pAssocInd->assocReqLength;
3937 	roam_info->assocReqPtr = pAssocInd->assocReqPtr;
3938 	roam_info->status_code = eSIR_SME_SUCCESS;
3939 	roam_info->staId = (uint8_t)pAssocInd->staId;
3940 	roam_info->rsnIELen = (uint8_t)pAssocInd->rsnIE.length;
3941 	roam_info->prsnIE = pAssocInd->rsnIE.rsnIEdata;
3942 #ifdef FEATURE_WLAN_WAPI
3943 	roam_info->wapiIELen = (uint8_t)pAssocInd->wapiIE.length;
3944 	roam_info->pwapiIE = pAssocInd->wapiIE.wapiIEdata;
3945 #endif
3946 	roam_info->addIELen = (uint8_t)pAssocInd->addIE.length;
3947 	roam_info->paddIE = pAssocInd->addIE.addIEdata;
3948 	roam_info->fReassocReq = pAssocInd->reassocReq;
3949 	qdf_mem_copy(roam_info->peerMac.bytes,
3950 		     pAssocInd->peerMacAddr,
3951 		     sizeof(tSirMacAddr));
3952 	qdf_mem_copy(roam_info->bssid.bytes,
3953 		     pAssocInd->bssId,
3954 		     sizeof(struct qdf_mac_addr));
3955 	roam_info->wmmEnabledSta = pAssocInd->wmmEnabledSta;
3956 	roam_info->timingMeasCap = pAssocInd->timingMeasCap;
3957 	roam_info->ecsa_capable = pAssocInd->ecsa_capable;
3958 	qdf_mem_copy(&roam_info->chan_info,
3959 		     &pAssocInd->chan_info,
3960 		     sizeof(struct oem_channel_info));
3961 
3962 	if (pAssocInd->HTCaps.present)
3963 		qdf_mem_copy(&roam_info->ht_caps,
3964 			     &pAssocInd->HTCaps,
3965 			     sizeof(tDot11fIEHTCaps));
3966 	if (pAssocInd->VHTCaps.present)
3967 		qdf_mem_copy(&roam_info->vht_caps,
3968 			     &pAssocInd->VHTCaps,
3969 			     sizeof(tDot11fIEVHTCaps));
3970 	roam_info->capability_info = pAssocInd->capability_info;
3971 	roam_info->he_caps_present = pAssocInd->he_caps_present;
3972 	roam_info->eht_caps_present = pAssocInd->eht_caps_present;
3973 	if (opmode == QDF_SAP_MODE || opmode == QDF_P2P_GO_MODE) {
3974 		if (wlan_is_open_wep_cipher(mac_ctx->pdev, sessionId)) {
3975 			csr_issue_set_context_req_helper(mac_ctx, sessionId,
3976 					&roam_info->peerMac.bytes, false, true,
3977 					0);
3978 			roam_info->fAuthRequired = false;
3979 		} else {
3980 			roam_info->fAuthRequired = true;
3981 		}
3982 		sme_debug("Receive AUTH_TYPE of %d", csr_akm_type);
3983 		if (csr_akm_type == eCSR_AUTH_TYPE_OWE) {
3984 			roam_info->owe_pending_assoc_ind = qdf_mem_malloc(
3985 							    sizeof(*pAssocInd));
3986 			if (roam_info->owe_pending_assoc_ind)
3987 				qdf_mem_copy(roam_info->owe_pending_assoc_ind,
3988 					     pAssocInd, sizeof(*pAssocInd));
3989 		} else if (csr_akm_type == eCSR_AUTH_TYPE_FT_RSN_PSK) {
3990 			roam_info->ft_pending_assoc_ind = qdf_mem_malloc(
3991 			    sizeof(*pAssocInd));
3992 			if (roam_info->ft_pending_assoc_ind)
3993 				qdf_mem_copy(roam_info->ft_pending_assoc_ind,
3994 					     pAssocInd, sizeof(*pAssocInd));
3995 		}
3996 		status = csr_roam_call_callback(mac_ctx, sessionId,
3997 					roam_info, eCSR_ROAM_INFRA_IND,
3998 					eCSR_ROAM_RESULT_INFRA_ASSOCIATION_IND);
3999 		if (!QDF_IS_STATUS_SUCCESS(status)) {
4000 			/* Refused due to Mac filtering */
4001 			if (roam_info->owe_pending_assoc_ind) {
4002 				qdf_mem_free(roam_info->owe_pending_assoc_ind);
4003 				roam_info->owe_pending_assoc_ind = NULL;
4004 			} else if (roam_info->ft_pending_assoc_ind) {
4005 				qdf_mem_free(roam_info->ft_pending_assoc_ind);
4006 				roam_info->ft_pending_assoc_ind = NULL;
4007 			}
4008 			roam_info->status_code = eSIR_SME_ASSOC_REFUSED;
4009 		}
4010 	}
4011 	sme_debug("csr_akm_type: %d", csr_akm_type);
4012 
4013 	if (csr_akm_type != eCSR_AUTH_TYPE_OWE &&
4014 	    csr_akm_type != eCSR_AUTH_TYPE_FT_RSN_PSK) {
4015 		if ((opmode == QDF_SAP_MODE || opmode == QDF_P2P_GO_MODE) &&
4016 		    roam_info->status_code != eSIR_SME_ASSOC_REFUSED)
4017 			pAssocInd->need_assoc_rsp_tx_cb = true;
4018 		/* Send Association completion message to PE */
4019 		status = csr_send_assoc_cnf_msg(mac_ctx, pAssocInd, status,
4020 						mac_status_code);
4021 	}
4022 
4023 	qdf_mem_free(roam_info);
4024 }
4025 
4026 /* csr_if_peer_present() - Check whether peer is present or not
4027  * @mac_ctx: Pointer to mac context
4028  * @bssid: Pointer to bssid address
4029  * @peer_macaddr: Pointer to peer mac address
4030  *
4031  * Consider a case
4032  * 1. SAP received south bound disconnect command
4033  * 2. At same time, SAP CSA to DFS channel happened and thus peers are deleted.
4034  * 3. Later same peer got re-added and south bound disconnect command becomes
4035  *    active for same peer.
4036  *
4037  * When SAP receives south bound disconnect command req, driver will post to
4038  * schedular thread and it will wait in SME message queue. When SAP CSA to DFS
4039  * channel happens, driver will post to schedular thread and it will wait in PE
4040  * message queue. Since PE has higher priority than SME message queue, so it
4041  * will process first. As part of CSA, it will delete all peer including sta
4042  * hash entry.
4043  * After CSA, south bound disconnect command got queue to serialization and
4044  * same peer got re-added again. When south bound disconnect command becomes
4045  * active, the states will not be proper because for old peer, disassocTrigger
4046  * is eLIM_PEER_ENTITY_DISASSOC/eLIM_PEER_ENTITY_DEAUTH and when new peer gets
4047  * re-added, disassocTrigger will be eLIM_HOST_DISASSOC/eLIM_HOST_DEAUTH and
4048  * thus response to CSR will not be proper. Due to this south bound disconnect
4049  * command will not remove from active queue which leads to active command
4050  * timeout.
4051  * Validate the peer before sending to serialization to avoid queuing command
4052  * if peer is already deleted.
4053  *
4054  * Return: True if peer is present otherwise return false
4055  */
4056 static bool csr_if_peer_present(struct mac_context *mac_ctx,
4057 				uint8_t *bssid,
4058 				uint8_t *peer_macaddr)
4059 {
4060 	struct wlan_objmgr_peer *peer;
4061 	uint8_t pdev_id;
4062 
4063 	pdev_id = wlan_objmgr_pdev_get_pdev_id(mac_ctx->pdev);
4064 
4065 	peer = wlan_objmgr_get_peer_by_mac_n_vdev(mac_ctx->psoc, pdev_id,
4066 						  bssid, peer_macaddr,
4067 						  WLAN_LEGACY_SME_ID);
4068 
4069 	if (!peer) {
4070 		sme_info("peer not found for mac: " QDF_MAC_ADDR_FMT "and bssid: "
4071 			  QDF_MAC_ADDR_FMT, QDF_MAC_ADDR_REF(peer_macaddr),
4072 			  QDF_MAC_ADDR_REF(bssid));
4073 		return false;
4074 	}
4075 
4076 	wlan_objmgr_peer_release_ref(peer, WLAN_LEGACY_SME_ID);
4077 	return true;
4078 }
4079 
4080 static void
4081 csr_roam_chk_lnk_disassoc_ind(struct mac_context *mac_ctx, tSirSmeRsp *msg_ptr)
4082 {
4083 	struct csr_roam_session *session;
4084 	uint32_t sessionId = WLAN_UMAC_VDEV_ID_MAX;
4085 	struct disassoc_ind *pDisassocInd;
4086 
4087 	/*
4088 	 * Check if AP dis-associated us because of MIC failure. If so,
4089 	 * then we need to take action immediately and not wait till the
4090 	 * the WmStatusChange requests is pushed and processed
4091 	 */
4092 	pDisassocInd = (struct disassoc_ind *)msg_ptr;
4093 	sessionId = pDisassocInd->vdev_id;
4094 	sme_debug("Disassoc Indication from MAC for vdev_id %d bssid " QDF_MAC_ADDR_FMT,
4095 		  pDisassocInd->vdev_id,
4096 		  QDF_MAC_ADDR_REF(pDisassocInd->bssid.bytes));
4097 
4098 	if (!CSR_IS_SESSION_VALID(mac_ctx, sessionId)) {
4099 		sme_err("vdev:%d Invalid session. BSSID: " QDF_MAC_ADDR_FMT,
4100 			sessionId, QDF_MAC_ADDR_REF(pDisassocInd->bssid.bytes));
4101 
4102 		return;
4103 	}
4104 
4105 	if (!csr_if_peer_present(mac_ctx, &pDisassocInd->bssid.bytes[0],
4106 				 &pDisassocInd->peer_macaddr.bytes[0]))
4107 		return;
4108 
4109 	if (csr_is_deauth_disassoc_already_active(mac_ctx, sessionId,
4110 	    pDisassocInd->peer_macaddr))
4111 		return;
4112 
4113 	sme_nofl_info("disassoc from peer " QDF_MAC_ADDR_FMT
4114 		      "reason: %d status: %d vid %d",
4115 		      QDF_MAC_ADDR_REF(pDisassocInd->peer_macaddr.bytes),
4116 		      pDisassocInd->reasonCode,
4117 		      pDisassocInd->status_code, sessionId);
4118 	session = CSR_GET_SESSION(mac_ctx, sessionId);
4119 	if (!session) {
4120 		sme_err("session: %d not found", sessionId);
4121 		return;
4122 	}
4123 	/* Update the disconnect stats */
4124 	session->disconnect_stats.disconnection_cnt++;
4125 	session->disconnect_stats.disassoc_by_peer++;
4126 
4127 	csr_roam_issue_wm_status_change(mac_ctx, sessionId,
4128 					eCsrDisassociated, msg_ptr);
4129 }
4130 
4131 static void
4132 csr_roam_chk_lnk_deauth_ind(struct mac_context *mac_ctx, tSirSmeRsp *msg_ptr)
4133 {
4134 	struct csr_roam_session *session;
4135 	uint32_t sessionId = WLAN_UMAC_VDEV_ID_MAX;
4136 	struct deauth_ind *pDeauthInd;
4137 
4138 	pDeauthInd = (struct deauth_ind *)msg_ptr;
4139 	sme_debug("DEAUTH Indication from MAC for vdev_id %d bssid "QDF_MAC_ADDR_FMT,
4140 		  pDeauthInd->vdev_id,
4141 		  QDF_MAC_ADDR_REF(pDeauthInd->bssid.bytes));
4142 
4143 	sessionId = pDeauthInd->vdev_id;
4144 	if (!CSR_IS_SESSION_VALID(mac_ctx, sessionId)) {
4145 		sme_err("vdev %d: Invalid session BSSID: " QDF_MAC_ADDR_FMT,
4146 			pDeauthInd->vdev_id,
4147 			QDF_MAC_ADDR_REF(pDeauthInd->bssid.bytes));
4148 		return;
4149 	}
4150 
4151 	if (!csr_if_peer_present(mac_ctx, &pDeauthInd->bssid.bytes[0],
4152 				 &pDeauthInd->peer_macaddr.bytes[0]))
4153 		return;
4154 
4155 	if (csr_is_deauth_disassoc_already_active(mac_ctx, sessionId,
4156 	    pDeauthInd->peer_macaddr))
4157 		return;
4158 	session = CSR_GET_SESSION(mac_ctx, sessionId);
4159 	if (!session) {
4160 		sme_err("session %d not found", sessionId);
4161 		return;
4162 	}
4163 	/* Update the disconnect stats */
4164 	switch (pDeauthInd->reasonCode) {
4165 	case REASON_DISASSOC_DUE_TO_INACTIVITY:
4166 		session->disconnect_stats.disconnection_cnt++;
4167 		session->disconnect_stats.peer_kickout++;
4168 		break;
4169 	case REASON_UNSPEC_FAILURE:
4170 	case REASON_PREV_AUTH_NOT_VALID:
4171 	case REASON_DEAUTH_NETWORK_LEAVING:
4172 	case REASON_CLASS2_FRAME_FROM_NON_AUTH_STA:
4173 	case REASON_CLASS3_FRAME_FROM_NON_ASSOC_STA:
4174 	case REASON_STA_NOT_AUTHENTICATED:
4175 		session->disconnect_stats.disconnection_cnt++;
4176 		session->disconnect_stats.deauth_by_peer++;
4177 		break;
4178 	case REASON_BEACON_MISSED:
4179 		session->disconnect_stats.disconnection_cnt++;
4180 		session->disconnect_stats.bmiss++;
4181 		break;
4182 	default:
4183 		/* Unknown reason code */
4184 		break;
4185 	}
4186 
4187 	csr_roam_issue_wm_status_change(mac_ctx, sessionId,
4188 					eCsrDeauthenticated,
4189 					msg_ptr);
4190 }
4191 
4192 static void
4193 csr_roam_chk_lnk_swt_ch_ind(struct mac_context *mac_ctx, tSirSmeRsp *msg_ptr)
4194 {
4195 	struct csr_roam_session *session;
4196 	uint32_t sessionId = WLAN_UMAC_VDEV_ID_MAX;
4197 	QDF_STATUS status;
4198 	struct switch_channel_ind *pSwitchChnInd;
4199 	struct csr_roam_info *roam_info;
4200 
4201 	/* in case of STA, the SWITCH_CHANNEL originates from its AP */
4202 	sme_debug("eWNI_SME_SWITCH_CHL_IND from SME");
4203 	pSwitchChnInd = (struct switch_channel_ind *)msg_ptr;
4204 	/* Update with the new channel id. The channel id is hidden in the
4205 	 * status_code.
4206 	 */
4207 	status = csr_roam_get_session_id_from_bssid(mac_ctx,
4208 			&pSwitchChnInd->bssid, &sessionId);
4209 	if (QDF_IS_STATUS_ERROR(status))
4210 		return;
4211 
4212 	session = CSR_GET_SESSION(mac_ctx, sessionId);
4213 	if (!session) {
4214 		sme_err("session %d not found", sessionId);
4215 		return;
4216 	}
4217 
4218 	if (QDF_IS_STATUS_ERROR(pSwitchChnInd->status)) {
4219 		sme_err("Channel switch failed");
4220 		return;
4221 	}
4222 	/* Update the occupied channel list with the new switched channel */
4223 	wlan_cm_init_occupied_ch_freq_list(mac_ctx->pdev, mac_ctx->psoc,
4224 					   sessionId);
4225 	roam_info = qdf_mem_malloc(sizeof(*roam_info));
4226 	if (!roam_info)
4227 		return;
4228 	roam_info->chan_info.mhz = pSwitchChnInd->freq;
4229 	roam_info->chan_info.ch_width = pSwitchChnInd->chan_params.ch_width;
4230 	roam_info->chan_info.sec_ch_offset =
4231 				pSwitchChnInd->chan_params.sec_ch_offset;
4232 	roam_info->chan_info.band_center_freq1 =
4233 				pSwitchChnInd->chan_params.mhz_freq_seg0;
4234 	roam_info->chan_info.band_center_freq2 =
4235 				pSwitchChnInd->chan_params.mhz_freq_seg1;
4236 
4237 	if (IS_WLAN_PHYMODE_HT(pSwitchChnInd->ch_phymode))
4238 		roam_info->mode = SIR_SME_PHY_MODE_HT;
4239 	else if (IS_WLAN_PHYMODE_VHT(pSwitchChnInd->ch_phymode) ||
4240 		 IS_WLAN_PHYMODE_HE(pSwitchChnInd->ch_phymode))
4241 		roam_info->mode = SIR_SME_PHY_MODE_VHT;
4242 #ifdef WLAN_FEATURE_11BE
4243 	else if (IS_WLAN_PHYMODE_EHT(pSwitchChnInd->ch_phymode))
4244 		roam_info->mode = SIR_SME_PHY_MODE_VHT;
4245 #endif
4246 	else
4247 		roam_info->mode = SIR_SME_PHY_MODE_LEGACY;
4248 
4249 	status = csr_roam_call_callback(mac_ctx, sessionId, roam_info,
4250 					eCSR_ROAM_STA_CHANNEL_SWITCH,
4251 					eCSR_ROAM_RESULT_NONE);
4252 	qdf_mem_free(roam_info);
4253 }
4254 
4255 static void
4256 csr_roam_chk_lnk_deauth_rsp(struct mac_context *mac_ctx, tSirSmeRsp *msg_ptr)
4257 {
4258 	uint32_t sessionId = WLAN_UMAC_VDEV_ID_MAX;
4259 	QDF_STATUS status;
4260 	struct csr_roam_info *roam_info;
4261 	struct deauth_rsp *pDeauthRsp = (struct deauth_rsp *) msg_ptr;
4262 	enum QDF_OPMODE opmode;
4263 
4264 	roam_info = qdf_mem_malloc(sizeof(*roam_info));
4265 	if (!roam_info)
4266 		return;
4267 	sme_debug("eWNI_SME_DEAUTH_RSP from SME");
4268 	sessionId = pDeauthRsp->sessionId;
4269 	if (!CSR_IS_SESSION_VALID(mac_ctx, sessionId)) {
4270 		qdf_mem_free(roam_info);
4271 		return;
4272 	}
4273 	opmode = wlan_get_opmode_from_vdev_id(mac_ctx->pdev, sessionId);
4274 	if (opmode == QDF_SAP_MODE || opmode == QDF_P2P_GO_MODE) {
4275 		qdf_copy_macaddr(&roam_info->peerMac,
4276 				 &pDeauthRsp->peer_macaddr);
4277 		roam_info->reasonCode = eCSR_ROAM_RESULT_FORCED;
4278 		roam_info->status_code = pDeauthRsp->status_code;
4279 		status = csr_roam_call_callback(mac_ctx, sessionId,
4280 						roam_info, eCSR_ROAM_LOSTLINK,
4281 						eCSR_ROAM_RESULT_FORCED);
4282 	}
4283 	qdf_mem_free(roam_info);
4284 }
4285 
4286 static void
4287 csr_roam_chk_lnk_disassoc_rsp(struct mac_context *mac_ctx, tSirSmeRsp *msg_ptr)
4288 {
4289 	uint32_t sessionId = WLAN_UMAC_VDEV_ID_MAX;
4290 	QDF_STATUS status;
4291 	struct csr_roam_info *roam_info;
4292 	enum QDF_OPMODE opmode;
4293 	/*
4294 	 * session id is invalid here so cant use it to access the array
4295 	 * curSubstate as index
4296 	 */
4297 	struct disassoc_rsp *pDisassocRsp = (struct disassoc_rsp *) msg_ptr;
4298 
4299 	roam_info = qdf_mem_malloc(sizeof(*roam_info));
4300 	if (!roam_info)
4301 		return;
4302 	sme_debug("eWNI_SME_DISASSOC_RSP from SME ");
4303 	sessionId = pDisassocRsp->sessionId;
4304 	if (!CSR_IS_SESSION_VALID(mac_ctx, sessionId)) {
4305 		qdf_mem_free(roam_info);
4306 		return;
4307 	}
4308 	opmode = wlan_get_opmode_from_vdev_id(mac_ctx->pdev, sessionId);
4309 	if (opmode == QDF_SAP_MODE || opmode == QDF_P2P_GO_MODE) {
4310 		qdf_copy_macaddr(&roam_info->peerMac,
4311 				 &pDisassocRsp->peer_macaddr);
4312 		roam_info->reasonCode = eCSR_ROAM_RESULT_FORCED;
4313 		roam_info->status_code = pDisassocRsp->status_code;
4314 		status = csr_roam_call_callback(mac_ctx, sessionId,
4315 						roam_info,
4316 						eCSR_ROAM_LOSTLINK,
4317 						eCSR_ROAM_RESULT_FORCED);
4318 	}
4319 	qdf_mem_free(roam_info);
4320 }
4321 
4322 #ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
4323 static void
4324 csr_roam_diag_mic_fail(struct mac_context *mac_ctx, uint32_t sessionId)
4325 {
4326 	WLAN_HOST_DIAG_EVENT_DEF(secEvent,
4327 				 host_event_wlan_security_payload_type);
4328 	struct csr_roam_session *session = CSR_GET_SESSION(mac_ctx, sessionId);
4329 
4330 	if (!session) {
4331 		sme_err("session %d not found", sessionId);
4332 		return;
4333 	}
4334 	qdf_mem_zero(&secEvent, sizeof(host_event_wlan_security_payload_type));
4335 	secEvent.eventId = WLAN_SECURITY_EVENT_MIC_ERROR;
4336 	cm_diag_get_auth_enc_type_vdev_id(mac_ctx->psoc,
4337 					  &secEvent.authMode,
4338 					  &secEvent.encryptionModeUnicast,
4339 					  &secEvent.encryptionModeMulticast,
4340 					  sessionId);
4341 	wlan_mlme_get_bssid_vdev_id(mac_ctx->pdev, sessionId,
4342 				    (struct qdf_mac_addr *)&secEvent.bssid);
4343 	WLAN_HOST_DIAG_EVENT_REPORT(&secEvent, EVENT_WLAN_SECURITY);
4344 }
4345 #endif /* FEATURE_WLAN_DIAG_SUPPORT_CSR */
4346 
4347 static void
4348 csr_roam_chk_lnk_mic_fail_ind(struct mac_context *mac_ctx, tSirSmeRsp *msg_ptr)
4349 {
4350 	uint32_t sessionId = WLAN_UMAC_VDEV_ID_MAX;
4351 	QDF_STATUS status;
4352 	struct csr_roam_info *roam_info;
4353 	struct mic_failure_ind *mic_ind = (struct mic_failure_ind *)msg_ptr;
4354 	eCsrRoamResult result = eCSR_ROAM_RESULT_MIC_ERROR_UNICAST;
4355 
4356 	roam_info = qdf_mem_malloc(sizeof(*roam_info));
4357 	if (!roam_info)
4358 		return;
4359 	status = csr_roam_get_session_id_from_bssid(mac_ctx,
4360 				&mic_ind->bssId, &sessionId);
4361 	if (QDF_IS_STATUS_SUCCESS(status)) {
4362 		roam_info->u.pMICFailureInfo = &mic_ind->info;
4363 		if (mic_ind->info.multicast)
4364 			result = eCSR_ROAM_RESULT_MIC_ERROR_GROUP;
4365 		else
4366 			result = eCSR_ROAM_RESULT_MIC_ERROR_UNICAST;
4367 		csr_roam_call_callback(mac_ctx, sessionId, roam_info,
4368 				       eCSR_ROAM_MIC_ERROR_IND, result);
4369 	}
4370 #ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
4371 	csr_roam_diag_mic_fail(mac_ctx, sessionId);
4372 #endif /* FEATURE_WLAN_DIAG_SUPPORT_CSR */
4373 	qdf_mem_free(roam_info);
4374 }
4375 
4376 static void
4377 csr_roam_chk_lnk_pbs_probe_req_ind(struct mac_context *mac_ctx, tSirSmeRsp *msg_ptr)
4378 {
4379 	uint32_t sessionId = WLAN_UMAC_VDEV_ID_MAX;
4380 	QDF_STATUS status;
4381 	struct csr_roam_info *roam_info;
4382 	tpSirSmeProbeReqInd pProbeReqInd = (tpSirSmeProbeReqInd) msg_ptr;
4383 
4384 	roam_info = qdf_mem_malloc(sizeof(*roam_info));
4385 	if (!roam_info)
4386 		return;
4387 	sme_debug("WPS PBC Probe request Indication from SME");
4388 
4389 	status = csr_roam_get_session_id_from_bssid(mac_ctx,
4390 			&pProbeReqInd->bssid, &sessionId);
4391 	if (QDF_IS_STATUS_SUCCESS(status)) {
4392 		roam_info->u.pWPSPBCProbeReq = &pProbeReqInd->WPSPBCProbeReq;
4393 		csr_roam_call_callback(mac_ctx, sessionId, roam_info,
4394 				       eCSR_ROAM_WPS_PBC_PROBE_REQ_IND,
4395 				       eCSR_ROAM_RESULT_WPS_PBC_PROBE_REQ_IND);
4396 	}
4397 	qdf_mem_free(roam_info);
4398 }
4399 
4400 static void
4401 csr_roam_chk_lnk_max_assoc_exceeded(struct mac_context *mac_ctx, tSirSmeRsp *msg_ptr)
4402 {
4403 	uint32_t sessionId = WLAN_UMAC_VDEV_ID_MAX;
4404 	tSmeMaxAssocInd *pSmeMaxAssocInd;
4405 	struct csr_roam_info *roam_info;
4406 
4407 	roam_info = qdf_mem_malloc(sizeof(*roam_info));
4408 	if (!roam_info)
4409 		return;
4410 	pSmeMaxAssocInd = (tSmeMaxAssocInd *) msg_ptr;
4411 	sme_debug(
4412 		"max assoc have been reached, new peer cannot be accepted");
4413 	sessionId = pSmeMaxAssocInd->sessionId;
4414 	qdf_copy_macaddr(&roam_info->peerMac, &pSmeMaxAssocInd->peer_mac);
4415 	csr_roam_call_callback(mac_ctx, sessionId, roam_info,
4416 			       eCSR_ROAM_INFRA_IND,
4417 			       eCSR_ROAM_RESULT_MAX_ASSOC_EXCEEDED);
4418 	qdf_mem_free(roam_info);
4419 }
4420 
4421 void csr_roam_check_for_link_status_change(struct mac_context *mac,
4422 						tSirSmeRsp *pSirMsg)
4423 {
4424 	if (!pSirMsg) {
4425 		sme_err("pSirMsg is NULL");
4426 		return;
4427 	}
4428 	switch (pSirMsg->messageType) {
4429 	case eWNI_SME_ASSOC_IND:
4430 		csr_roam_chk_lnk_assoc_ind(mac, pSirMsg);
4431 		break;
4432 	case eWNI_SME_ASSOC_IND_UPPER_LAYER:
4433 		csr_roam_chk_lnk_assoc_ind_upper_layer(mac, pSirMsg);
4434 		break;
4435 	case eWNI_SME_DISASSOC_IND:
4436 		csr_roam_chk_lnk_disassoc_ind(mac, pSirMsg);
4437 		break;
4438 	case eWNI_SME_DISCONNECT_DONE_IND:
4439 		csr_roam_send_disconnect_done_indication(mac, pSirMsg);
4440 		break;
4441 	case eWNI_SME_DEAUTH_IND:
4442 		csr_roam_chk_lnk_deauth_ind(mac, pSirMsg);
4443 		break;
4444 	case eWNI_SME_SWITCH_CHL_IND:
4445 		csr_roam_chk_lnk_swt_ch_ind(mac, pSirMsg);
4446 		break;
4447 	case eWNI_SME_DEAUTH_RSP:
4448 		csr_roam_chk_lnk_deauth_rsp(mac, pSirMsg);
4449 		break;
4450 	case eWNI_SME_DISASSOC_RSP:
4451 		csr_roam_chk_lnk_disassoc_rsp(mac, pSirMsg);
4452 		break;
4453 	case eWNI_SME_MIC_FAILURE_IND:
4454 		csr_roam_chk_lnk_mic_fail_ind(mac, pSirMsg);
4455 		break;
4456 	case eWNI_SME_WPS_PBC_PROBE_REQ_IND:
4457 		csr_roam_chk_lnk_pbs_probe_req_ind(mac, pSirMsg);
4458 		break;
4459 	case eWNI_SME_SETCONTEXT_RSP:
4460 		csr_roam_chk_lnk_set_ctx_rsp(mac, pSirMsg);
4461 		break;
4462 #ifdef FEATURE_WLAN_ESE
4463 	case eWNI_SME_GET_TSM_STATS_RSP:
4464 		sme_debug("TSM Stats rsp from PE");
4465 		csr_tsm_stats_rsp_processor(mac, pSirMsg);
4466 		break;
4467 #endif /* FEATURE_WLAN_ESE */
4468 	case eWNI_SME_GET_SNR_REQ:
4469 		sme_debug("GetSnrReq from self");
4470 		csr_update_snr(mac, pSirMsg);
4471 		break;
4472 	case eWNI_SME_MAX_ASSOC_EXCEEDED:
4473 		csr_roam_chk_lnk_max_assoc_exceeded(mac, pSirMsg);
4474 		break;
4475 	default:
4476 		break;
4477 	} /* end switch on message type */
4478 }
4479 
4480 void csr_roam_wm_status_change_complete(struct mac_context *mac,
4481 					uint8_t session_id)
4482 {
4483 	tListElem *pEntry;
4484 	tSmeCmd *pCommand;
4485 
4486 	pEntry = csr_nonscan_active_ll_peek_head(mac, LL_ACCESS_LOCK);
4487 	if (pEntry) {
4488 		pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link);
4489 		if (eSmeCommandWmStatusChange == pCommand->command) {
4490 			/* Nothing to process in a Lost Link completion....  It just kicks off a */
4491 			/* roaming sequence. */
4492 			if (csr_nonscan_active_ll_remove_entry(mac, pEntry,
4493 				    LL_ACCESS_LOCK)) {
4494 				csr_release_command(mac, pCommand);
4495 			} else {
4496 				sme_err("Failed to release command");
4497 			}
4498 		} else {
4499 			sme_warn("CSR: LOST LINK command is not ACTIVE ...");
4500 		}
4501 	} else {
4502 		sme_warn("CSR: NO commands are ACTIVE ...");
4503 	}
4504 }
4505 
4506 void csr_roam_process_wm_status_change_command(
4507 		struct mac_context *mac, tSmeCmd *pCommand)
4508 {
4509 	struct csr_roam_session *pSession = CSR_GET_SESSION(mac,
4510 						pCommand->vdev_id);
4511 	struct qdf_mac_addr peer_mac;
4512 
4513 	if (!pSession) {
4514 		sme_err("session %d not found", pCommand->vdev_id);
4515 		csr_roam_wm_status_change_complete(mac, pCommand->vdev_id);
4516 	}
4517 	sme_debug("session:%d, CmdType : %d",
4518 		pCommand->vdev_id, pCommand->u.wmStatusChangeCmd.Type);
4519 
4520 	switch (pCommand->u.wmStatusChangeCmd.Type) {
4521 	case eCsrDisassociated:
4522 		qdf_mem_copy(&peer_mac, &pCommand->u.wmStatusChangeCmd.
4523 					u.DisassocIndMsg.peer_macaddr,
4524 			     QDF_MAC_ADDR_SIZE);
4525 		/*
4526 		 * Get peer stats before peer gets deleted so that these stats
4527 		 * can be given to user space when big data stats are queried.
4528 		 * Once peer stats are retrieved disassoc sta will continue
4529 		 */
4530 		csr_get_peer_stats(mac, pCommand->vdev_id, peer_mac);
4531 		break;
4532 	case eCsrDeauthenticated:
4533 		qdf_mem_copy(&peer_mac, &pCommand->u.wmStatusChangeCmd.
4534 					u.DeauthIndMsg.peer_macaddr,
4535 			     QDF_MAC_ADDR_SIZE);
4536 		/*
4537 		 * Get peer stats before peer gets deleted so that these stats
4538 		 * can be given to user space when big data stats are queried.
4539 		 * Once peer stats are retrieved deauth sta will continue
4540 		 */
4541 		csr_get_peer_stats(mac, pCommand->vdev_id, peer_mac);
4542 		break;
4543 	default:
4544 		sme_warn("gets an unknown command %d",
4545 			pCommand->u.wmStatusChangeCmd.Type);
4546 		csr_roam_wm_status_change_complete(mac, pCommand->vdev_id);
4547 		break;
4548 	}
4549 }
4550 
4551 /**
4552  * csr_compute_mode_and_band() - computes dot11mode
4553  * @mac: mac global context
4554  * @dot11_mode: out param, do11 mode calculated
4555  * @band: out param, band caclculated
4556  * @opr_ch_freq: operating channel freq in MHz
4557  *
4558  * This function finds dot11 mode based on current mode, operating channel and
4559  * fw supported modes.
4560  *
4561  * Return: void
4562  */
4563 static void
4564 csr_compute_mode_and_band(struct mac_context *mac_ctx,
4565 			  enum csr_cfgdot11mode *dot11_mode,
4566 			  enum reg_wifi_band *band,
4567 			  uint32_t opr_ch_freq)
4568 {
4569 	bool vht_24_ghz = mac_ctx->mlme_cfg->vht_caps.vht_cap_info.b24ghz_band;
4570 
4571 	switch (mac_ctx->roam.configParam.uCfgDot11Mode) {
4572 	case eCSR_CFG_DOT11_MODE_11A:
4573 		*dot11_mode = eCSR_CFG_DOT11_MODE_11A;
4574 		*band = REG_BAND_5G;
4575 		break;
4576 	case eCSR_CFG_DOT11_MODE_11B:
4577 		*dot11_mode = eCSR_CFG_DOT11_MODE_11B;
4578 		*band = REG_BAND_2G;
4579 		break;
4580 	case eCSR_CFG_DOT11_MODE_11G:
4581 		*dot11_mode = eCSR_CFG_DOT11_MODE_11G;
4582 		*band = REG_BAND_2G;
4583 		break;
4584 	case eCSR_CFG_DOT11_MODE_11N:
4585 		*dot11_mode = eCSR_CFG_DOT11_MODE_11N;
4586 		*band = wlan_reg_freq_to_band(opr_ch_freq);
4587 		break;
4588 	case eCSR_CFG_DOT11_MODE_11AC:
4589 		if (IS_FEATURE_SUPPORTED_BY_FW(DOT11AC)) {
4590 			/*
4591 			 * If the operating channel is in 2.4 GHz band, check
4592 			 * for INI item to disable VHT operation in 2.4 GHz band
4593 			 */
4594 			if (WLAN_REG_IS_24GHZ_CH_FREQ(opr_ch_freq) &&
4595 			    !vht_24_ghz)
4596 				/* Disable 11AC operation */
4597 				*dot11_mode = eCSR_CFG_DOT11_MODE_11N;
4598 			else
4599 				*dot11_mode = eCSR_CFG_DOT11_MODE_11AC;
4600 		} else {
4601 			*dot11_mode = eCSR_CFG_DOT11_MODE_11N;
4602 		}
4603 		*band = wlan_reg_freq_to_band(opr_ch_freq);
4604 		break;
4605 	case eCSR_CFG_DOT11_MODE_11AC_ONLY:
4606 		if (IS_FEATURE_SUPPORTED_BY_FW(DOT11AC)) {
4607 			/*
4608 			 * If the operating channel is in 2.4 GHz band, check
4609 			 * for INI item to disable VHT operation in 2.4 GHz band
4610 			 */
4611 			if (WLAN_REG_IS_24GHZ_CH_FREQ(opr_ch_freq) &&
4612 			    !vht_24_ghz)
4613 				/* Disable 11AC operation */
4614 				*dot11_mode = eCSR_CFG_DOT11_MODE_11N;
4615 			else
4616 				*dot11_mode = eCSR_CFG_DOT11_MODE_11AC_ONLY;
4617 		} else {
4618 			*dot11_mode = eCSR_CFG_DOT11_MODE_11N;
4619 		}
4620 		*band = wlan_reg_freq_to_band(opr_ch_freq);
4621 		break;
4622 	case eCSR_CFG_DOT11_MODE_11AX:
4623 	case eCSR_CFG_DOT11_MODE_11AX_ONLY:
4624 		if (IS_FEATURE_SUPPORTED_BY_FW(DOT11AX)) {
4625 			*dot11_mode = mac_ctx->roam.configParam.uCfgDot11Mode;
4626 		} else if (IS_FEATURE_SUPPORTED_BY_FW(DOT11AC)) {
4627 			/*
4628 			 * If the operating channel is in 2.4 GHz band, check
4629 			 * for INI item to disable VHT operation in 2.4 GHz band
4630 			 */
4631 			if (WLAN_REG_IS_24GHZ_CH_FREQ(opr_ch_freq) &&
4632 			    !vht_24_ghz)
4633 				/* Disable 11AC operation */
4634 				*dot11_mode = eCSR_CFG_DOT11_MODE_11N;
4635 			else
4636 				*dot11_mode = eCSR_CFG_DOT11_MODE_11AC;
4637 		} else {
4638 			*dot11_mode = eCSR_CFG_DOT11_MODE_11N;
4639 		}
4640 		*band = wlan_reg_freq_to_band(opr_ch_freq);
4641 		break;
4642 #ifdef WLAN_FEATURE_11BE
4643 	case eCSR_CFG_DOT11_MODE_11BE:
4644 	case eCSR_CFG_DOT11_MODE_11BE_ONLY:
4645 		if (IS_FEATURE_11BE_SUPPORTED_BY_FW) {
4646 			*dot11_mode = mac_ctx->roam.configParam.uCfgDot11Mode;
4647 		} else if (IS_FEATURE_SUPPORTED_BY_FW(DOT11AX)) {
4648 			*dot11_mode = eCSR_CFG_DOT11_MODE_11AX;
4649 		} else if (IS_FEATURE_SUPPORTED_BY_FW(DOT11AC)) {
4650 			/*
4651 			 * If the operating channel is in 2.4 GHz band, check
4652 			 * for INI item to disable VHT operation in 2.4 GHz band
4653 			 */
4654 			if (WLAN_REG_IS_24GHZ_CH_FREQ(opr_ch_freq) &&
4655 			    !vht_24_ghz)
4656 				/* Disable 11AC operation */
4657 				*dot11_mode = eCSR_CFG_DOT11_MODE_11N;
4658 			else
4659 				*dot11_mode = eCSR_CFG_DOT11_MODE_11AC;
4660 		} else {
4661 			*dot11_mode = eCSR_CFG_DOT11_MODE_11N;
4662 		}
4663 		*band = wlan_reg_freq_to_band(opr_ch_freq);
4664 		break;
4665 #endif
4666 	case eCSR_CFG_DOT11_MODE_AUTO:
4667 #ifdef WLAN_FEATURE_11BE
4668 		if (IS_FEATURE_11BE_SUPPORTED_BY_FW) {
4669 			*dot11_mode = eCSR_CFG_DOT11_MODE_11BE;
4670 		} else
4671 #endif
4672 		if (IS_FEATURE_SUPPORTED_BY_FW(DOT11AX)) {
4673 			*dot11_mode = eCSR_CFG_DOT11_MODE_11AX;
4674 		} else if (IS_FEATURE_SUPPORTED_BY_FW(DOT11AC)) {
4675 			/*
4676 			 * If the operating channel is in 2.4 GHz band,
4677 			 * check for INI item to disable VHT operation
4678 			 * in 2.4 GHz band
4679 			 */
4680 			if (WLAN_REG_IS_24GHZ_CH_FREQ(opr_ch_freq) &&
4681 			    !vht_24_ghz)
4682 				/* Disable 11AC operation */
4683 				*dot11_mode = eCSR_CFG_DOT11_MODE_11N;
4684 			else
4685 				*dot11_mode = eCSR_CFG_DOT11_MODE_11AC;
4686 		} else {
4687 			*dot11_mode = eCSR_CFG_DOT11_MODE_11N;
4688 		}
4689 		*band = wlan_reg_freq_to_band(opr_ch_freq);
4690 		break;
4691 	default:
4692 		/*
4693 		 * Global dot11 Mode setting is 11a/b/g. use the channel number
4694 		 * to determine the Mode setting.
4695 		 */
4696 		if (eCSR_OPERATING_CHANNEL_AUTO == opr_ch_freq) {
4697 			*band = (mac_ctx->mlme_cfg->gen.band == BAND_2G ?
4698 				REG_BAND_2G : REG_BAND_5G);
4699 			if (REG_BAND_2G == *band) {
4700 				*dot11_mode = eCSR_CFG_DOT11_MODE_11B;
4701 			} else {
4702 				/* prefer 5GHz */
4703 				*band = REG_BAND_5G;
4704 				*dot11_mode = eCSR_CFG_DOT11_MODE_11A;
4705 			}
4706 		} else if (WLAN_REG_IS_24GHZ_CH_FREQ(opr_ch_freq)) {
4707 			*dot11_mode = eCSR_CFG_DOT11_MODE_11B;
4708 			*band = REG_BAND_2G;
4709 		} else {
4710 			/* else, it's a 5.0GHz channel.  Set mode to 11a. */
4711 			*dot11_mode = eCSR_CFG_DOT11_MODE_11A;
4712 			*band = REG_BAND_5G;
4713 		}
4714 		break;
4715 	} /* switch */
4716 }
4717 
4718 /**
4719  * csr_roam_get_phy_mode_band_for_bss() - This function returns band and mode
4720  * information.
4721  * @mac_ctx:  mac global context
4722  * dot11_cfg: pointer to dot11 config
4723  *
4724  * This function finds dot11 mode based on current mode, operating channel and
4725  * fw supported modes. The only tricky part is that if phyMode is set to 11abg,
4726  * this function may return eCSR_CFG_DOT11_MODE_11B instead of
4727  * eCSR_CFG_DOT11_MODE_11G if everything is set to auto-pick.
4728  *
4729  * Return: dot11mode
4730  */
4731 enum csr_cfgdot11mode
4732 csr_roam_get_phy_mode_band_for_bss(struct mac_context *mac_ctx,
4733 				   struct bss_dot11_config *dot11_cfg)
4734 {
4735 	enum reg_wifi_band band = REG_BAND_2G;
4736 	qdf_freq_t opr_freq = 0;
4737 	bool is_11n_allowed;
4738 	enum csr_cfgdot11mode curr_mode =
4739 		mac_ctx->roam.configParam.uCfgDot11Mode;
4740 	enum csr_cfgdot11mode cfg_dot11_mode;
4741 	enum QDF_OPMODE opmode;
4742 	bool is_ap = false;
4743 	uint8_t privacy;
4744 	uint8_t vdev_id = dot11_cfg->vdev_id;
4745 
4746 	if (dot11_cfg->bss_op_ch_freq)
4747 		opr_freq = dot11_cfg->bss_op_ch_freq;
4748 
4749 	opmode = wlan_get_opmode_from_vdev_id(mac_ctx->pdev, vdev_id);
4750 	is_ap = (opmode == QDF_SAP_MODE || opmode == QDF_P2P_GO_MODE);
4751 	cfg_dot11_mode =
4752 		csr_get_cfg_dot11_mode_from_csr_phy_mode(is_ap,
4753 							 dot11_cfg->phy_mode);
4754 	privacy = dot11_cfg->privacy;
4755 
4756 	/*
4757 	 * If the global setting for dot11Mode is set to auto/abg, we overwrite
4758 	 * the setting in the profile.
4759 	 */
4760 	if ((!is_ap && ((eCSR_CFG_DOT11_MODE_AUTO == curr_mode) ||
4761 	     (eCSR_CFG_DOT11_MODE_ABG == curr_mode))) ||
4762 	     (eCSR_CFG_DOT11_MODE_AUTO == cfg_dot11_mode) ||
4763 	     (eCSR_CFG_DOT11_MODE_ABG == cfg_dot11_mode)) {
4764 		csr_compute_mode_and_band(mac_ctx, &cfg_dot11_mode,
4765 					  &band, opr_freq);
4766 	} /* if( eCSR_CFG_DOT11_MODE_ABG == cfg_dot11_mode ) */
4767 	else {
4768 		/* dot11 mode is set, lets pick the band */
4769 		if (0 == opr_freq) {
4770 			/* channel is Auto also. */
4771 			if (mac_ctx->mlme_cfg->gen.band == BAND_ALL) {
4772 				/* prefer 5GHz */
4773 				band = REG_BAND_5G;
4774 			}
4775 		} else{
4776 			band = wlan_reg_freq_to_band(opr_freq);
4777 		}
4778 	}
4779 
4780 	dot11_cfg->p_band = band;
4781 	if (opr_freq == 2484 && wlan_reg_is_24ghz_ch_freq(opr_freq)) {
4782 		sme_err("Switching to Dot11B mode");
4783 		cfg_dot11_mode = eCSR_CFG_DOT11_MODE_11B;
4784 	}
4785 
4786 	if (wlan_reg_is_24ghz_ch_freq(opr_freq) &&
4787 	    !mac_ctx->mlme_cfg->vht_caps.vht_cap_info.b24ghz_band &&
4788 	    (eCSR_CFG_DOT11_MODE_11AC == cfg_dot11_mode ||
4789 	    eCSR_CFG_DOT11_MODE_11AC_ONLY == cfg_dot11_mode))
4790 		cfg_dot11_mode = eCSR_CFG_DOT11_MODE_11N;
4791 	/*
4792 	 * Incase of WEP Security encryption type is coming as part of add key.
4793 	 * So while STart BSS dont have information
4794 	 */
4795 	is_11n_allowed = wlan_vdev_id_is_11n_allowed(mac_ctx->pdev, vdev_id);
4796 	if ((!is_11n_allowed || (privacy &&
4797 	    wlan_vdev_id_is_open_cipher(mac_ctx->pdev, vdev_id))) &&
4798 	    ((eCSR_CFG_DOT11_MODE_11N == cfg_dot11_mode) ||
4799 	    (eCSR_CFG_DOT11_MODE_11AC == cfg_dot11_mode) ||
4800 	    (eCSR_CFG_DOT11_MODE_11AX == cfg_dot11_mode) ||
4801 	    CSR_IS_CFG_DOT11_PHY_MODE_11BE(cfg_dot11_mode))) {
4802 		/* We cannot do 11n here */
4803 		if (wlan_reg_is_24ghz_ch_freq(opr_freq))
4804 			cfg_dot11_mode = eCSR_CFG_DOT11_MODE_11G;
4805 		else
4806 			cfg_dot11_mode = eCSR_CFG_DOT11_MODE_11A;
4807 	}
4808 	sme_debug("dot11mode: %d phyMode %d is_11n_allowed %d privacy %d chan freq %d fw sup AX %d",
4809 		  cfg_dot11_mode, dot11_cfg->phy_mode, is_11n_allowed,
4810 		  privacy, opr_freq,
4811 		  IS_FEATURE_SUPPORTED_BY_FW(DOT11AX));
4812 
4813 #ifdef WLAN_FEATURE_11BE
4814 	sme_debug("BE :%d", IS_FEATURE_SUPPORTED_BY_FW(DOT11BE));
4815 #endif
4816 	return cfg_dot11_mode;
4817 }
4818 
4819 QDF_STATUS csr_get_cfg_valid_channels(struct mac_context *mac,
4820 				      qdf_freq_t *ch_freq_list,
4821 				      uint32_t *num_ch_freq)
4822 {
4823 	uint8_t num_chan_temp = 0;
4824 	int i;
4825 	uint32_t *valid_ch_freq_list =
4826 				mac->mlme_cfg->reg.valid_channel_freq_list;
4827 
4828 	*num_ch_freq = mac->mlme_cfg->reg.valid_channel_list_num;
4829 
4830 	for (i = 0; i < *num_ch_freq; i++) {
4831 		if (!wlan_reg_is_dsrc_freq(valid_ch_freq_list[i])) {
4832 			ch_freq_list[num_chan_temp] = valid_ch_freq_list[i];
4833 			num_chan_temp++;
4834 		}
4835 	}
4836 
4837 	*num_ch_freq = num_chan_temp;
4838 	return QDF_STATUS_SUCCESS;
4839 }
4840 
4841 /**
4842  * csr_convert_mode_to_nw_type() - convert mode into network type
4843  * @dot11_mode:    dot11_mode
4844  * @band:          2.4 or 5 GHz
4845  *
4846  * Return: tSirNwType
4847  */
4848 tSirNwType
4849 csr_convert_mode_to_nw_type(enum csr_cfgdot11mode dot11_mode,
4850 			    enum reg_wifi_band band)
4851 {
4852 	switch (dot11_mode) {
4853 	case eCSR_CFG_DOT11_MODE_11G:
4854 		return eSIR_11G_NW_TYPE;
4855 	case eCSR_CFG_DOT11_MODE_11B:
4856 		return eSIR_11B_NW_TYPE;
4857 	case eCSR_CFG_DOT11_MODE_11A:
4858 		return eSIR_11A_NW_TYPE;
4859 	case eCSR_CFG_DOT11_MODE_11N:
4860 	default:
4861 		/*
4862 		 * Because LIM only verifies it against 11a, 11b or 11g, set
4863 		 * only 11g or 11a here
4864 		 */
4865 		if (REG_BAND_2G == band)
4866 			return eSIR_11G_NW_TYPE;
4867 		else
4868 			return eSIR_11A_NW_TYPE;
4869 	}
4870 	return eSIR_DONOT_USE_NW_TYPE;
4871 }
4872 
4873 #ifdef WLAN_FEATURE_ROAM_OFFLOAD
4874 #ifdef WLAN_FEATURE_11BE_MLO
4875 static bool csr_pmk_match_mlo_address(struct wlan_objmgr_vdev *vdev,
4876 				      struct wlan_crypto_pmksa *pmksa)
4877 {
4878 	struct qdf_mac_addr bss_peer_mld_mac = {0};
4879 
4880 	wlan_vdev_get_bss_peer_mld_mac(vdev, &bss_peer_mld_mac);
4881 
4882 	return qdf_is_macaddr_equal(&bss_peer_mld_mac, &pmksa->bssid);
4883 }
4884 #else
4885 static inline bool csr_pmk_match_mlo_address(struct wlan_objmgr_vdev *vdev,
4886 					     struct wlan_crypto_pmksa *pmksa)
4887 {
4888 	return false;
4889 }
4890 #endif
4891 
4892 void csr_get_pmk_info(struct mac_context *mac_ctx, uint8_t session_id,
4893 		      struct wlan_crypto_pmksa *pmk_cache)
4894 {
4895 	if (!mac_ctx) {
4896 		sme_err("Mac_ctx is NULL");
4897 		return;
4898 	}
4899 	wlan_cm_get_psk_pmk(mac_ctx->pdev, session_id, pmk_cache->pmk,
4900 			    &pmk_cache->pmk_len);
4901 }
4902 
4903 QDF_STATUS csr_roam_set_psk_pmk(struct mac_context *mac,
4904 				struct wlan_crypto_pmksa *pmksa,
4905 				uint8_t vdev_id, bool update_to_fw)
4906 {
4907 	struct wlan_objmgr_vdev *vdev;
4908 	struct qdf_mac_addr connected_bssid = {0};
4909 	QDF_STATUS status;
4910 
4911 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac->psoc, vdev_id,
4912 						    WLAN_LEGACY_SME_ID);
4913 	if (!vdev) {
4914 		sme_err("vdev is NULL");
4915 		return QDF_STATUS_E_FAILURE;
4916 	}
4917 
4918 	wlan_mlme_get_bssid_vdev_id(mac->pdev, vdev_id, &connected_bssid);
4919 
4920 	/*
4921 	 * If the set_pmksa is received from the userspace in
4922 	 * connected state and if the connected BSSID is not
4923 	 * same as the PMKSA entry bssid, then reject this
4924 	 * global cache updation.
4925 	 *
4926 	 * Also for FILS connection, the set_pmksa will not have
4927 	 * the BSSID. So avoid this check for FILS connection.
4928 	 */
4929 	if (wlan_vdev_mlme_get_state(vdev) == WLAN_VDEV_S_UP &&
4930 	    !pmksa->ssid_len &&
4931 	    !qdf_is_macaddr_equal(&connected_bssid, &pmksa->bssid) &&
4932 	    !csr_pmk_match_mlo_address(vdev, pmksa)) {
4933 		wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID);
4934 		sme_debug("Set pmksa received for non-connected bss");
4935 		return QDF_STATUS_E_INVAL;
4936 	}
4937 
4938 	wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID);
4939 
4940 	wlan_cm_set_psk_pmk(mac->pdev, vdev_id, pmksa->pmk, pmksa->pmk_len);
4941 	if (update_to_fw) {
4942 		status = wlan_roam_update_cfg(mac->psoc, vdev_id,
4943 					      REASON_ROAM_PSK_PMK_CHANGED);
4944 		if (status == QDF_STATUS_E_INVAL)
4945 			wlan_mlme_defer_pmk_set_in_roaming(mac->psoc, vdev_id,
4946 							   true);
4947 	}
4948 
4949 	return QDF_STATUS_SUCCESS;
4950 }
4951 
4952 QDF_STATUS csr_set_pmk_cache_ft(struct mac_context *mac, uint8_t vdev_id,
4953 				struct wlan_crypto_pmksa *pmk_cache)
4954 {
4955 	struct wlan_objmgr_vdev *vdev;
4956 	int32_t akm;
4957 
4958 	if (!CSR_IS_SESSION_VALID(mac, vdev_id)) {
4959 		sme_err("session %d not found", vdev_id);
4960 		return QDF_STATUS_E_INVAL;
4961 	}
4962 
4963 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac->psoc, vdev_id,
4964 						    WLAN_LEGACY_SME_ID);
4965 	if (!vdev) {
4966 		sme_err("vdev is NULL");
4967 		return QDF_STATUS_E_FAILURE;
4968 	}
4969 
4970 	akm = wlan_crypto_get_param(vdev, WLAN_CRYPTO_PARAM_KEY_MGMT);
4971 
4972 	wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID);
4973 
4974 	if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_CCKM)) {
4975 		sme_debug("PMK update is not required for ESE");
4976 		return QDF_STATUS_SUCCESS;
4977 	}
4978 
4979 	if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_FT_IEEE8021X) ||
4980 	    QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_FT_FILS_SHA256) ||
4981 	    QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_FILS_SHA384) ||
4982 	    QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_FT_IEEE8021X_SHA384)) {
4983 		sme_debug("Auth type: %x update the MDID in cache", akm);
4984 		cm_update_pmk_cache_ft(mac->psoc, vdev_id, pmk_cache);
4985 	} else {
4986 		struct cm_roam_values_copy src_cfg = {};
4987 		struct scan_filter *scan_filter;
4988 		qdf_list_t *list = NULL;
4989 		struct scan_cache_node *first_node = NULL;
4990 		struct rsn_mdie *mdie = NULL;
4991 		qdf_list_node_t *cur_node = NULL;
4992 
4993 		scan_filter = qdf_mem_malloc(sizeof(*scan_filter));
4994 		if (!scan_filter)
4995 			return QDF_STATUS_E_NOMEM;
4996 		scan_filter->num_of_bssid = 1;
4997 		qdf_mem_copy(scan_filter->bssid_list[0].bytes,
4998 			     &pmk_cache->bssid, sizeof(struct qdf_mac_addr));
4999 		list = wlan_scan_get_result(mac->pdev, scan_filter);
5000 		qdf_mem_free(scan_filter);
5001 		if (!list || (list && !qdf_list_size(list))) {
5002 			sme_debug("Scan list is empty");
5003 			goto err;
5004 		}
5005 		qdf_list_peek_front(list, &cur_node);
5006 		first_node = qdf_container_of(cur_node,
5007 					      struct scan_cache_node,
5008 					      node);
5009 		if (first_node && first_node->entry)
5010 			mdie = (struct rsn_mdie *)
5011 					util_scan_entry_mdie(first_node->entry);
5012 		if (mdie) {
5013 			sme_debug("Update MDID in cache from scan_res");
5014 			src_cfg.bool_value = true;
5015 			src_cfg.uint_value =
5016 				(mdie->mobility_domain[0] |
5017 				 (mdie->mobility_domain[1] << 8));
5018 			wlan_cm_roam_cfg_set_value(mac->psoc, vdev_id,
5019 						   MOBILITY_DOMAIN, &src_cfg);
5020 			cm_update_pmk_cache_ft(mac->psoc, vdev_id, pmk_cache);
5021 		}
5022 err:
5023 		if (list)
5024 			wlan_scan_purge_results(list);
5025 	}
5026 	return QDF_STATUS_SUCCESS;
5027 }
5028 #endif /* WLAN_FEATURE_ROAM_OFFLOAD */
5029 
5030 #if defined(WLAN_SAE_SINGLE_PMK) && defined(WLAN_FEATURE_ROAM_OFFLOAD)
5031 void csr_clear_sae_single_pmk(struct wlan_objmgr_psoc *psoc,
5032 			      uint8_t vdev_id,
5033 			      struct wlan_crypto_pmksa *pmk_cache)
5034 {
5035 	struct wlan_objmgr_vdev *vdev;
5036 	int32_t keymgmt;
5037 	struct mlme_pmk_info pmk_info;
5038 
5039 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
5040 						    WLAN_LEGACY_SME_ID);
5041 	if (!vdev) {
5042 		sme_err("vdev is NULL");
5043 		return;
5044 	}
5045 
5046 	keymgmt = wlan_crypto_get_param(vdev, WLAN_CRYPTO_PARAM_KEY_MGMT);
5047 	if (keymgmt < 0) {
5048 		sme_err("Invalid mgmt cipher");
5049 		wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID);
5050 		return;
5051 	}
5052 
5053 	if (!(QDF_HAS_PARAM(keymgmt, WLAN_CRYPTO_KEY_MGMT_SAE) ||
5054 	      QDF_HAS_PARAM(keymgmt, WLAN_CRYPTO_KEY_MGMT_SAE_EXT_KEY))) {
5055 		wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID);
5056 		return;
5057 	}
5058 	if (pmk_cache) {
5059 		qdf_mem_copy(&pmk_info.pmk, pmk_cache->pmk, pmk_cache->pmk_len);
5060 		pmk_info.pmk_len = pmk_cache->pmk_len;
5061 		wlan_mlme_clear_sae_single_pmk_info(vdev, &pmk_info);
5062 	} else {
5063 		wlan_mlme_clear_sae_single_pmk_info(vdev, NULL);
5064 	}
5065 	wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID);
5066 }
5067 #endif
5068 
5069 #ifdef FEATURE_WLAN_ESE
5070 void csr_update_prev_ap_info(struct csr_roam_session *session,
5071 			     struct wlan_objmgr_vdev *vdev)
5072 {
5073 	struct wlan_ssid ssid;
5074 	QDF_STATUS status;
5075 	enum QDF_OPMODE opmode;
5076 	struct rso_config *rso_cfg;
5077 
5078 	opmode = wlan_vdev_mlme_get_opmode(vdev);
5079 	rso_cfg = wlan_cm_get_rso_config(vdev);
5080 	if (!rso_cfg)
5081 		return;
5082 
5083 	if (!rso_cfg->is_ese_assoc || opmode != QDF_STA_MODE)
5084 		return;
5085 	status = wlan_vdev_mlme_get_ssid(vdev, ssid.ssid, &ssid.length);
5086 	if (QDF_IS_STATUS_ERROR(status)) {
5087 		sme_err(" failed to find SSID for vdev %d", session->vdev_id);
5088 		return;
5089 	}
5090 	session->isPrevApInfoValid = true;
5091 	session->roamTS1 = qdf_mc_timer_get_system_time();
5092 }
5093 #endif
5094 
5095 #ifdef WLAN_FEATURE_FILS_SK
5096 static QDF_STATUS csr_cm_update_fils_info(struct wlan_objmgr_vdev *vdev,
5097 					  struct bss_description *bss_desc,
5098 					  struct wlan_cm_vdev_connect_req *req)
5099 {
5100 	uint8_t cache_id[CACHE_ID_LEN] = {0};
5101 	struct scan_cache_entry *entry;
5102 	struct wlan_crypto_pmksa *fils_ssid_pmksa, *bssid_lookup_pmksa;
5103 
5104 	if (!req->fils_info || !req->fils_info->is_fils_connection) {
5105 		wlan_cm_update_mlme_fils_info(vdev, NULL);
5106 		return QDF_STATUS_SUCCESS;
5107 	}
5108 
5109 	if (bss_desc->fils_info_element.is_cache_id_present) {
5110 		qdf_mem_copy(cache_id, bss_desc->fils_info_element.cache_id,
5111 			     CACHE_ID_LEN);
5112 		sme_debug("FILS_PMKSA: cache_id[0]:%d, cache_id[1]:%d",
5113 			  cache_id[0], cache_id[1]);
5114 	}
5115 	entry = req->bss->entry;
5116 	bssid_lookup_pmksa = wlan_crypto_get_pmksa(vdev, &entry->bssid);
5117 	fils_ssid_pmksa =
5118 			wlan_crypto_get_fils_pmksa(vdev, cache_id,
5119 						   entry->ssid.ssid,
5120 						   entry->ssid.length);
5121 
5122 	if ((!req->fils_info->rrk_len ||
5123 	     !req->fils_info->username_len) &&
5124 	     !bss_desc->fils_info_element.is_cache_id_present &&
5125 	     !bssid_lookup_pmksa && !fils_ssid_pmksa)
5126 		return QDF_STATUS_E_FAILURE;
5127 
5128 	return wlan_cm_update_mlme_fils_info(vdev, req->fils_info);
5129 }
5130 #else
5131 static inline
5132 QDF_STATUS csr_cm_update_fils_info(struct wlan_objmgr_vdev *vdev,
5133 				   struct bss_description *bss_desc,
5134 				   struct wlan_cm_vdev_connect_req *req)
5135 {
5136 }
5137 #endif
5138 
5139 #if defined(WLAN_FEATURE_HOST_ROAM) && defined(FEATURE_WLAN_ESE)
5140 static void csr_update_tspec_info(struct mac_context *mac_ctx,
5141 				  struct wlan_objmgr_vdev *vdev,
5142 				  tDot11fBeaconIEs *ie_struct)
5143 {
5144 	struct mlme_legacy_priv *mlme_priv;
5145 	tESETspecInfo *ese_tspec;
5146 
5147 	mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev);
5148 	if (!mlme_priv)
5149 		return;
5150 	if (!cm_is_ese_connection(vdev, ie_struct->ESEVersion.present))
5151 		return;
5152 
5153 	ese_tspec = &mlme_priv->connect_info.ese_tspec_info;
5154 	qdf_mem_zero(ese_tspec, sizeof(tESETspecInfo));
5155 	ese_tspec->numTspecs = sme_qos_ese_retrieve_tspec_info(mac_ctx,
5156 					wlan_vdev_get_id(vdev),
5157 					ese_tspec->tspec);
5158 }
5159 #else
5160 static inline void csr_update_tspec_info(struct mac_context *mac_ctx,
5161 					 struct wlan_objmgr_vdev *vdev,
5162 					 tDot11fBeaconIEs *ie_struct) {}
5163 #endif
5164 
5165 void cm_csr_send_set_ie(struct wlan_objmgr_vdev *vdev)
5166 {
5167 	struct vdev_mlme_obj *vdev_mlme;
5168 
5169 	vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev);
5170 	if (!vdev_mlme) {
5171 		sme_err("Failed to get vdev mlme obj!");
5172 		QDF_BUG(0);
5173 		return;
5174 	}
5175 
5176 	csr_send_set_ie(vdev_mlme->mgmt.generic.type,
5177 			vdev_mlme->mgmt.generic.subtype,
5178 			wlan_vdev_get_id(vdev));
5179 }
5180 
5181 QDF_STATUS cm_csr_handle_join_req(struct wlan_objmgr_vdev *vdev,
5182 				  struct wlan_cm_vdev_connect_req *req,
5183 				  struct cm_vdev_join_req *join_req,
5184 				  bool reassoc)
5185 {
5186 	struct mac_context *mac_ctx;
5187 	uint8_t vdev_id = wlan_vdev_get_id(vdev);
5188 	QDF_STATUS status;
5189 	tDot11fBeaconIEs *ie_struct;
5190 	struct bss_description *bss_desc;
5191 	uint32_t ie_len, bss_len;
5192 
5193 	/*
5194 	 * This API is to update legacy struct and should be removed once
5195 	 * CSR is cleaned up fully. No new params should be added to CSR, use
5196 	 * vdev/pdev/psoc instead
5197 	 */
5198 	mac_ctx = cds_get_context(QDF_MODULE_ID_SME);
5199 	if (!mac_ctx)
5200 		return QDF_STATUS_E_INVAL;
5201 
5202 	ie_len = util_scan_entry_ie_len(join_req->entry);
5203 	bss_len = (uint16_t)(offsetof(struct bss_description,
5204 			   ieFields[0]) + ie_len);
5205 
5206 	bss_desc = qdf_mem_malloc(sizeof(*bss_desc) + bss_len);
5207 	if (!bss_desc)
5208 		return QDF_STATUS_E_NOMEM;
5209 
5210 	status = wlan_fill_bss_desc_from_scan_entry(mac_ctx, bss_desc,
5211 						    join_req->entry);
5212 	if (QDF_IS_STATUS_ERROR(status)) {
5213 		qdf_mem_free(bss_desc);
5214 		return QDF_STATUS_E_FAILURE;
5215 	}
5216 
5217 	status = wlan_get_parsed_bss_description_ies(mac_ctx, bss_desc,
5218 						     &ie_struct);
5219 	if (QDF_IS_STATUS_ERROR(status)) {
5220 		sme_err("IE parsing failed vdev id %d", vdev_id);
5221 		qdf_mem_free(bss_desc);
5222 		return QDF_STATUS_E_FAILURE;
5223 	}
5224 
5225 	if (reassoc) {
5226 		csr_update_tspec_info(mac_ctx, vdev, ie_struct);
5227 	} else {
5228 		status = csr_cm_update_fils_info(vdev, bss_desc, req);
5229 		if (QDF_IS_STATUS_ERROR(status)) {
5230 			sme_err("failed to update fils info vdev id %d",
5231 				vdev_id);
5232 			qdf_mem_free(ie_struct);
5233 			qdf_mem_free(bss_desc);
5234 			return QDF_STATUS_E_FAILURE;
5235 		}
5236 		sme_qos_csr_event_ind(mac_ctx, vdev_id,
5237 				      SME_QOS_CSR_JOIN_REQ, NULL);
5238 	}
5239 
5240 	if ((wlan_reg_11d_enabled_on_host(mac_ctx->psoc)) &&
5241 	     !ie_struct->Country.present)
5242 		csr_apply_channel_power_info_wrapper(mac_ctx);
5243 
5244 	qdf_mem_free(ie_struct);
5245 	qdf_mem_free(bss_desc);
5246 
5247 	cm_csr_set_joining(vdev_id);
5248 
5249 	return QDF_STATUS_SUCCESS;
5250 }
5251 
5252 #ifdef FEATURE_WLAN_ESE
5253 static uint32_t csr_get_tspec_ie_len(struct cm_vdev_join_rsp *rsp)
5254 {
5255 	return rsp->tspec_ie.len;
5256 }
5257 static inline void csr_copy_tspec_ie_len(struct csr_roam_session *session,
5258 					 uint8_t *frame_ptr,
5259 					 struct cm_vdev_join_rsp *rsp)
5260 {
5261 	session->connectedInfo.nTspecIeLength = rsp->tspec_ie.len;
5262 	if (rsp->tspec_ie.len)
5263 		qdf_mem_copy(frame_ptr, rsp->tspec_ie.ptr,
5264 			     rsp->tspec_ie.len);
5265 }
5266 
5267 #else
5268 static inline uint32_t csr_get_tspec_ie_len(struct cm_vdev_join_rsp *rsp)
5269 {
5270 	return 0;
5271 }
5272 static inline void csr_copy_tspec_ie_len(struct csr_roam_session *session,
5273 					 uint8_t *frame_ptr,
5274 					 struct cm_vdev_join_rsp *rsp)
5275 {}
5276 #endif
5277 
5278 static void csr_fill_connected_info(struct mac_context *mac_ctx,
5279 				    struct csr_roam_session *session,
5280 				    struct cm_vdev_join_rsp *rsp)
5281 {
5282 	uint32_t len;
5283 	struct wlan_connect_rsp_ies *connect_ies;
5284 	uint8_t *frame_ptr;
5285 	uint32_t beacon_data_len = 0;
5286 
5287 	connect_ies = &rsp->connect_rsp.connect_ies;
5288 	csr_roam_free_connected_info(mac_ctx, &session->connectedInfo);
5289 	if (connect_ies->bcn_probe_rsp.len > sizeof(struct wlan_frame_hdr))
5290 		beacon_data_len = connect_ies->bcn_probe_rsp.len -
5291 						sizeof(struct wlan_frame_hdr);
5292 	len = beacon_data_len + connect_ies->assoc_req.len +
5293 		connect_ies->assoc_rsp.len + rsp->ric_resp_ie.len +
5294 		csr_get_tspec_ie_len(rsp);
5295 	if (!len)
5296 		return;
5297 
5298 	session->connectedInfo.pbFrames = qdf_mem_malloc(len);
5299 	if (!session->connectedInfo.pbFrames)
5300 		return;
5301 
5302 	frame_ptr = session->connectedInfo.pbFrames;
5303 	session->connectedInfo.nBeaconLength = beacon_data_len;
5304 	if (beacon_data_len)
5305 		qdf_mem_copy(frame_ptr,
5306 			     connect_ies->bcn_probe_rsp.ptr +
5307 			     sizeof(struct wlan_frame_hdr),
5308 			     beacon_data_len);
5309 	frame_ptr += beacon_data_len;
5310 
5311 	session->connectedInfo.nAssocReqLength = connect_ies->assoc_req.len;
5312 	if (connect_ies->assoc_req.len)
5313 		qdf_mem_copy(frame_ptr,
5314 			     connect_ies->assoc_req.ptr,
5315 			     connect_ies->assoc_req.len);
5316 	frame_ptr += connect_ies->assoc_req.len;
5317 
5318 	session->connectedInfo.nAssocRspLength = connect_ies->assoc_rsp.len;
5319 	if (connect_ies->assoc_rsp.len)
5320 		qdf_mem_copy(frame_ptr,
5321 			     connect_ies->assoc_rsp.ptr,
5322 			     connect_ies->assoc_rsp.len);
5323 	frame_ptr += connect_ies->assoc_rsp.len;
5324 
5325 	session->connectedInfo.nRICRspLength = rsp->ric_resp_ie.len;
5326 	if (rsp->ric_resp_ie.len)
5327 		qdf_mem_copy(frame_ptr, rsp->ric_resp_ie.ptr,
5328 			     rsp->ric_resp_ie.len);
5329 	frame_ptr += rsp->ric_resp_ie.len;
5330 
5331 	csr_copy_tspec_ie_len(session, frame_ptr, rsp);
5332 }
5333 
5334 #ifndef WLAN_MDM_CODE_REDUCTION_OPT
5335 static inline void csr_qos_send_disconnect_ind(struct mac_context *mac_ctx,
5336 					       uint8_t vdev_id)
5337 {
5338 	sme_qos_csr_event_ind(mac_ctx, vdev_id, SME_QOS_CSR_DISCONNECT_IND,
5339 			      NULL);
5340 }
5341 
5342 static inline void csr_qos_send_assoc_ind(struct mac_context *mac_ctx,
5343 					  uint8_t vdev_id,
5344 					  sme_QosAssocInfo *assoc_info)
5345 {
5346 	sme_qos_csr_event_ind(mac_ctx, vdev_id, SME_QOS_CSR_ASSOC_COMPLETE,
5347 			      assoc_info);
5348 }
5349 
5350 #ifdef WLAN_FEATURE_ROAM_OFFLOAD
5351 static void
5352 csr_qso_disconnect_complete_ind(struct mac_context *mac_ctx,
5353 				struct wlan_cm_connect_resp *connect_rsp)
5354 {
5355 	if (IS_ROAM_REASON_DISCONNECTION(
5356 		connect_rsp->roaming_info->roam_reason))
5357 		sme_qos_csr_event_ind(mac_ctx, connect_rsp->vdev_id,
5358 				      SME_QOS_CSR_DISCONNECT_ROAM_COMPLETE,
5359 				      NULL);
5360 }
5361 #else
5362 static inline void
5363 csr_qso_disconnect_complete_ind(struct mac_context *mac_ctx,
5364 				struct wlan_cm_connect_resp *connect_rsp) {}
5365 #endif
5366 
5367 static void
5368 csr_qos_send_reassoc_ind(struct mac_context *mac_ctx,
5369 			 uint8_t vdev_id,
5370 			 sme_QosAssocInfo *assoc_info,
5371 			 struct wlan_cm_connect_resp *connect_rsp)
5372 {
5373 	sme_qos_csr_event_ind(mac_ctx, vdev_id, SME_QOS_CSR_HANDOFF_ASSOC_REQ,
5374 			      NULL);
5375 	sme_qos_csr_event_ind(mac_ctx, vdev_id, SME_QOS_CSR_REASSOC_REQ,
5376 			      NULL);
5377 	sme_qos_csr_event_ind(mac_ctx, vdev_id, SME_QOS_CSR_HANDOFF_COMPLETE,
5378 			      NULL);
5379 	sme_qos_csr_event_ind(mac_ctx, vdev_id, SME_QOS_CSR_REASSOC_COMPLETE,
5380 			      assoc_info);
5381 
5382 	csr_qso_disconnect_complete_ind(mac_ctx, connect_rsp);
5383 }
5384 #else
5385 static inline void csr_qos_send_disconnect_ind(struct mac_context *mac_ctx,
5386 					       uint8_t vdev_id)
5387 {}
5388 
5389 static inline void csr_qos_send_assoc_ind(struct mac_context *mac_ctx,
5390 					  uint8_t vdev_id,
5391 					  sme_QosAssocInfo *assoc_info)
5392 {}
5393 static inline void
5394 csr_qos_send_reassoc_ind(struct mac_context *mac_ctx,
5395 			 uint8_t vdev_id,
5396 			 sme_QosAssocInfo *assoc_info,
5397 			 struct wlan_cm_connect_resp *connect_rsp)
5398 {}
5399 #endif
5400 
5401 static void
5402 csr_update_beacon_in_connect_rsp(struct scan_cache_entry *entry,
5403 				 struct wlan_connect_rsp_ies *connect_ies)
5404 {
5405 	if (!entry)
5406 		return;
5407 
5408 	/* no need to update if already present */
5409 	if (connect_ies->bcn_probe_rsp.ptr)
5410 		return;
5411 
5412 	/*
5413 	 * In case connection to MBSSID: Non Tx BSS OR host reassoc,
5414 	 * vdev/peer manager doesn't send unicast probe req so fill the
5415 	 * beacon in connect resp IEs here.
5416 	 */
5417 	connect_ies->bcn_probe_rsp.len =
5418 				util_scan_entry_frame_len(entry);
5419 	connect_ies->bcn_probe_rsp.ptr =
5420 		qdf_mem_malloc(connect_ies->bcn_probe_rsp.len);
5421 	if (!connect_ies->bcn_probe_rsp.ptr)
5422 		return;
5423 
5424 	qdf_mem_copy(connect_ies->bcn_probe_rsp.ptr,
5425 		     util_scan_entry_frame_ptr(entry),
5426 		     connect_ies->bcn_probe_rsp.len);
5427 }
5428 
5429 #ifdef WLAN_FEATURE_11BE_MLO_ADV_FEATURE
5430 static bool csr_is_link_switch_in_progress(struct wlan_objmgr_vdev *vdev)
5431 {
5432 	return mlo_mgr_is_link_switch_in_progress(vdev);
5433 }
5434 #else
5435 static bool csr_is_link_switch_in_progress(struct wlan_objmgr_vdev *vdev)
5436 {
5437 	return false;
5438 }
5439 #endif
5440 
5441 static void csr_fill_connected_profile(struct mac_context *mac_ctx,
5442 				       struct csr_roam_session *session,
5443 				       struct wlan_objmgr_vdev *vdev,
5444 				       struct cm_vdev_join_rsp *rsp)
5445 {
5446 	struct scan_filter *filter;
5447 	uint8_t vdev_id = wlan_vdev_get_id(vdev);
5448 	QDF_STATUS status;
5449 	qdf_list_t *list = NULL;
5450 	qdf_list_node_t *cur_lst = NULL;
5451 	struct scan_cache_node *cur_node = NULL;
5452 	uint32_t bss_len, ie_len;
5453 	struct bss_description *bss_desc = NULL;
5454 	tDot11fBeaconIEs *bcn_ies;
5455 	sme_QosAssocInfo assoc_info;
5456 	struct cm_roam_values_copy src_cfg = {};
5457 	bool is_ese = false;
5458 	uint8_t country_code[REG_ALPHA2_LEN + 1];
5459 
5460 	session->modifyProfileFields.uapsd_mask = rsp->uapsd_mask;
5461 	filter = qdf_mem_malloc(sizeof(*filter));
5462 	if (!filter)
5463 		return;
5464 
5465 	filter->num_of_bssid = 1;
5466 	qdf_copy_macaddr(&filter->bssid_list[0], &rsp->connect_rsp.bssid);
5467 	filter->ignore_auth_enc_type = true;
5468 
5469 	status = wlan_vdev_mlme_get_ssid(vdev, filter->ssid_list[0].ssid,
5470 					 &filter->ssid_list[0].length);
5471 	if (QDF_IS_STATUS_SUCCESS(status))
5472 		filter->num_of_ssid = 1;
5473 
5474 	list = wlan_scan_get_result(mac_ctx->pdev, filter);
5475 	qdf_mem_free(filter);
5476 	if (!list || (list && !qdf_list_size(list)))
5477 		goto purge_list;
5478 
5479 
5480 	qdf_list_peek_front(list, &cur_lst);
5481 	if (!cur_lst)
5482 		goto purge_list;
5483 
5484 	cur_node = qdf_container_of(cur_lst, struct scan_cache_node, node);
5485 	ie_len = util_scan_entry_ie_len(cur_node->entry);
5486 	bss_len = (uint16_t)(offsetof(struct bss_description,
5487 				      ieFields[0]) + ie_len);
5488 	bss_desc = qdf_mem_malloc(bss_len);
5489 	if (!bss_desc)
5490 		goto purge_list;
5491 
5492 	wlan_fill_bss_desc_from_scan_entry(mac_ctx, bss_desc, cur_node->entry);
5493 	pe_debug("Dump scan entry frm:");
5494 	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_DEBUG,
5495 			   cur_node->entry->raw_frame.ptr,
5496 			   cur_node->entry->raw_frame.len);
5497 
5498 	src_cfg.uint_value = bss_desc->mbo_oce_enabled_ap;
5499 	wlan_cm_roam_cfg_set_value(mac_ctx->psoc, vdev_id, MBO_OCE_ENABLED_AP,
5500 				   &src_cfg);
5501 	csr_fill_single_pmk(mac_ctx->psoc, vdev_id, bss_desc);
5502 	status = wlan_get_parsed_bss_description_ies(mac_ctx, bss_desc,
5503 						     &bcn_ies);
5504 	if (QDF_IS_STATUS_ERROR(status))
5505 		goto purge_list;
5506 
5507 	if (!bss_desc->beaconInterval)
5508 		sme_err("ERROR: Beacon interval is ZERO");
5509 
5510 	csr_update_beacon_in_connect_rsp(cur_node->entry,
5511 					 &rsp->connect_rsp.connect_ies);
5512 
5513 	assoc_info.bss_desc = bss_desc;
5514 	if (rsp->connect_rsp.is_reassoc) {
5515 		if (cm_is_ese_connection(vdev, bcn_ies->ESEVersion.present))
5516 			is_ese = true;
5517 		wlan_cm_set_ese_assoc(mac_ctx->pdev, vdev_id, is_ese);
5518 		wlan_cm_roam_cfg_get_value(mac_ctx->psoc, vdev_id, UAPSD_MASK,
5519 					   &src_cfg);
5520 		assoc_info.uapsd_mask = src_cfg.uint_value;
5521 		csr_qos_send_reassoc_ind(mac_ctx, vdev_id, &assoc_info,
5522 					 &rsp->connect_rsp);
5523 		if (src_cfg.uint_value)
5524 			sme_ps_start_uapsd(MAC_HANDLE(mac_ctx), vdev_id);
5525 	} else {
5526 		assoc_info.uapsd_mask = rsp->uapsd_mask;
5527 		csr_qos_send_assoc_ind(mac_ctx, vdev_id, &assoc_info);
5528 	}
5529 
5530 	if (rsp->connect_rsp.is_reassoc ||
5531 	    csr_is_link_switch_in_progress(vdev))
5532 		mlme_set_mbssid_info(vdev, &cur_node->entry->mbssid_info,
5533 				     bss_desc->chan_freq);
5534 
5535 	if (bcn_ies->Country.present)
5536 		qdf_mem_copy(country_code, bcn_ies->Country.country,
5537 			     REG_ALPHA2_LEN + 1);
5538 	else
5539 		qdf_mem_zero(country_code, REG_ALPHA2_LEN + 1);
5540 	wlan_cm_set_country_code(mac_ctx->pdev, vdev_id, country_code);
5541 
5542 	qdf_mem_free(bcn_ies);
5543 
5544 purge_list:
5545 	if (bss_desc)
5546 		qdf_mem_free(bss_desc);
5547 	if (list)
5548 		wlan_scan_purge_results(list);
5549 
5550 }
5551 
5552 QDF_STATUS cm_csr_connect_rsp(struct wlan_objmgr_vdev *vdev,
5553 			      struct cm_vdev_join_rsp *rsp)
5554 {
5555 	struct mac_context *mac_ctx;
5556 	uint8_t vdev_id = wlan_vdev_get_id(vdev);
5557 	struct csr_roam_session *session;
5558 	struct cm_roam_values_copy src_config = {};
5559 
5560 	/*
5561 	 * This API is to update legacy struct and should be removed once
5562 	 * CSR is cleaned up fully. No new params should be added to CSR, use
5563 	 * vdev/pdev/psoc instead
5564 	 */
5565 	if (QDF_IS_STATUS_ERROR(rsp->connect_rsp.connect_status))
5566 		return QDF_STATUS_SUCCESS;
5567 
5568 	/* handle below only in case of success */
5569 	mac_ctx = cds_get_context(QDF_MODULE_ID_SME);
5570 	if (!mac_ctx)
5571 		return QDF_STATUS_E_INVAL;
5572 
5573 	session = CSR_GET_SESSION(mac_ctx, vdev_id);
5574 	if (!session || !CSR_IS_SESSION_VALID(mac_ctx, vdev_id)) {
5575 		sme_err("session not found for vdev_id %d", vdev_id);
5576 		return QDF_STATUS_E_INVAL;
5577 	}
5578 
5579 	if (!rsp->connect_rsp.is_reassoc) {
5580 		if (rsp->uapsd_mask)
5581 			sme_ps_start_uapsd(MAC_HANDLE(mac_ctx), vdev_id);
5582 		src_config.uint_value = rsp->uapsd_mask;
5583 		wlan_cm_roam_cfg_set_value(mac_ctx->psoc, vdev_id, UAPSD_MASK,
5584 					   &src_config);
5585 	}
5586 	session->nss = rsp->nss;
5587 	csr_fill_connected_info(mac_ctx, session, rsp);
5588 	csr_fill_connected_profile(mac_ctx, session, vdev, rsp);
5589 
5590 	return QDF_STATUS_SUCCESS;
5591 }
5592 
5593 static void
5594 cm_update_rsn_ocv_cap(int32_t *rsn_cap,
5595 		      struct wlan_cm_connect_resp *rsp)
5596 {
5597 	struct wlan_crypto_params crypto_params;
5598 	uint8_t *ie_ptr;
5599 	uint32_t ie_len;
5600 	QDF_STATUS status;
5601 
5602 	/* no need to do anything if OCV is not set */
5603 	if (!(*rsn_cap & WLAN_CRYPTO_RSN_CAP_OCV_SUPPORTED))
5604 		return;
5605 
5606 	if (!rsp->connect_ies.bcn_probe_rsp.ptr ||
5607 	    !rsp->connect_ies.bcn_probe_rsp.len ||
5608 	    (rsp->connect_ies.bcn_probe_rsp.len <
5609 		(sizeof(struct wlan_frame_hdr) +
5610 		offsetof(struct wlan_bcn_frame, ie)))) {
5611 		sme_err("invalid beacon probe rsp len %d",
5612 			rsp->connect_ies.bcn_probe_rsp.len);
5613 		return;
5614 	}
5615 
5616 	ie_len = (rsp->connect_ies.bcn_probe_rsp.len -
5617 			sizeof(struct wlan_frame_hdr) -
5618 			offsetof(struct wlan_bcn_frame, ie));
5619 	ie_ptr = (uint8_t *)(rsp->connect_ies.bcn_probe_rsp.ptr +
5620 			     sizeof(struct wlan_frame_hdr) +
5621 			     offsetof(struct wlan_bcn_frame, ie));
5622 
5623 	status = wlan_get_crypto_params_from_rsn_ie(&crypto_params, ie_ptr,
5624 						    ie_len);
5625 	if (QDF_IS_STATUS_ERROR(status))
5626 		return;
5627 
5628 	if (!(crypto_params.rsn_caps & WLAN_CRYPTO_RSN_CAP_OCV_SUPPORTED))
5629 		*rsn_cap &= ~WLAN_CRYPTO_RSN_CAP_OCV_SUPPORTED;
5630 }
5631 
5632 QDF_STATUS
5633 cm_csr_connect_done_ind(struct wlan_objmgr_vdev *vdev,
5634 			struct wlan_cm_connect_resp *rsp)
5635 {
5636 	mac_handle_t mac_handle;
5637 	struct mac_context *mac_ctx;
5638 	uint8_t vdev_id = wlan_vdev_get_id(vdev);
5639 	int32_t count;
5640 	struct set_context_rsp install_key_rsp;
5641 	int32_t rsn_cap, set_value;
5642 	struct wlan_mlme_psoc_ext_obj *mlme_obj;
5643 	struct dual_sta_policy *dual_sta_policy;
5644 	bool enable_mcc_adaptive_sch = false;
5645 	struct qdf_mac_addr bc_mac = QDF_MAC_ADDR_BCAST_INIT;
5646 
5647 	/*
5648 	 * This API is to update legacy struct and should be removed once
5649 	 * CSR is cleaned up fully. No new params should be added to CSR, use
5650 	 * vdev/pdev/psoc instead
5651 	 */
5652 	mac_handle = cds_get_context(QDF_MODULE_ID_SME);
5653 
5654 	mac_ctx = MAC_CONTEXT(mac_handle);
5655 	if (!mac_ctx)
5656 		return QDF_STATUS_E_INVAL;
5657 
5658 	mlme_obj = mlme_get_psoc_ext_obj(mac_ctx->psoc);
5659 	if (!mlme_obj)
5660 		return QDF_STATUS_E_INVAL;
5661 
5662 	if (QDF_IS_STATUS_ERROR(rsp->connect_status)) {
5663 		cm_csr_set_idle(vdev_id);
5664 		sme_qos_update_hand_off(vdev_id, false);
5665 		sme_qos_csr_event_ind(mac_ctx, vdev_id,
5666 				      SME_QOS_CSR_DISCONNECT_IND, NULL);
5667 		/* Fill legacy structures from resp for failure */
5668 
5669 		return QDF_STATUS_SUCCESS;
5670 	}
5671 
5672 	dual_sta_policy = &mlme_obj->cfg.gen.dual_sta_policy;
5673 	count = policy_mgr_mode_specific_connection_count(mac_ctx->psoc,
5674 							  PM_STA_MODE, NULL);
5675 	/*
5676 	 * send duty cycle percentage to FW only if STA + STA
5677 	 * concurrency is in MCC.
5678 	 */
5679 	sme_debug("Current iface vdev_id:%d, Primary vdev_id:%d, Dual sta policy:%d, count:%d",
5680 		  vdev_id, dual_sta_policy->primary_vdev_id,
5681 		  dual_sta_policy->concurrent_sta_policy, count);
5682 
5683 	if (dual_sta_policy->primary_vdev_id != WLAN_UMAC_VDEV_ID_MAX &&
5684 	    dual_sta_policy->concurrent_sta_policy ==
5685 	    QCA_WLAN_CONCURRENT_STA_POLICY_PREFER_PRIMARY && count == 2 &&
5686 	    policy_mgr_current_concurrency_is_mcc(mac_ctx->psoc)) {
5687 		policy_mgr_get_mcc_adaptive_sch(mac_ctx->psoc,
5688 						&enable_mcc_adaptive_sch);
5689 		if (enable_mcc_adaptive_sch) {
5690 			sme_debug("Disable mcc_adaptive_scheduler");
5691 			policy_mgr_set_dynamic_mcc_adaptive_sch(
5692 							mac_ctx->psoc, false);
5693 			if (QDF_STATUS_SUCCESS != sme_set_mas(false)) {
5694 				sme_err("Failed to disable mcc_adaptive_sched");
5695 				return -EAGAIN;
5696 			}
5697 		}
5698 		set_value =
5699 			wlan_mlme_get_mcc_duty_cycle_percentage(mac_ctx->pdev);
5700 		sme_cli_set_command(vdev_id, WMA_VDEV_MCC_SET_TIME_QUOTA,
5701 				    set_value, VDEV_CMD);
5702 	  } else if (dual_sta_policy->concurrent_sta_policy ==
5703 		     QCA_WLAN_CONCURRENT_STA_POLICY_UNBIASED && count == 2 &&
5704 		     policy_mgr_current_concurrency_is_mcc(mac_ctx->psoc)) {
5705 		policy_mgr_get_mcc_adaptive_sch(mac_ctx->psoc,
5706 						&enable_mcc_adaptive_sch);
5707 		if (enable_mcc_adaptive_sch) {
5708 			sme_debug("Enable mcc_adaptive_scheduler");
5709 			policy_mgr_set_dynamic_mcc_adaptive_sch(
5710 						  mac_ctx->psoc, true);
5711 			if (QDF_STATUS_SUCCESS != sme_set_mas(true)) {
5712 				sme_err("Failed to enable mcc_adaptive_sched");
5713 				return -EAGAIN;
5714 			}
5715 		}
5716 	} else {
5717 		QDF_STATUS status = QDF_STATUS_SUCCESS;
5718 		uint32_t quota_val;
5719 
5720 		quota_val =
5721 			ucfg_mlme_get_user_mcc_quota_percentage(mac_ctx->psoc);
5722 
5723 		if (quota_val) {
5724 			if (enable_mcc_adaptive_sch) {
5725 				policy_mgr_set_dynamic_mcc_adaptive_sch(
5726 							mac_ctx->psoc, false);
5727 				status = sme_set_mas(false);
5728 			}
5729 			if (status == QDF_STATUS_SUCCESS)
5730 				sme_cli_set_command(wlan_vdev_get_id(vdev),
5731 						    WMA_VDEV_MCC_SET_TIME_QUOTA,
5732 						    quota_val, VDEV_CMD);
5733 		} else {
5734 			sme_debug("no applicable user mcc/quota");
5735 		}
5736 	}
5737 
5738 	/*
5739 	 * For open mode authentication, send dummy install key response to
5740 	 * send OBSS scan and QOS event.
5741 	 */
5742 	if (!rsp->is_wps_connection && cm_is_open_mode(vdev)) {
5743 		install_key_rsp.length = sizeof(install_key_rsp);
5744 		install_key_rsp.status_code = eSIR_SME_SUCCESS;
5745 		install_key_rsp.sessionId = vdev_id;
5746 		/* use BC mac to enable OBSS scan */
5747 		qdf_copy_macaddr(&install_key_rsp.peer_macaddr, &bc_mac);
5748 		csr_roam_chk_lnk_set_ctx_rsp(mac_ctx,
5749 					     (tSirSmeRsp *)&install_key_rsp);
5750 	}
5751 
5752 	rsn_cap = wlan_crypto_get_param(vdev, WLAN_CRYPTO_PARAM_RSN_CAP);
5753 	if (rsn_cap >= 0) {
5754 		cm_update_rsn_ocv_cap(&rsn_cap, rsp);
5755 		if (wma_cli_set2_command(vdev_id, wmi_vdev_param_rsn_capability,
5756 					 rsn_cap, 0, VDEV_CMD))
5757 			sme_err("Failed to update wmi_vdev_param_rsn_capability for vdev id %d",
5758 				vdev_id);
5759 	}
5760 
5761 	/*
5762 	 * Update the IEs after connection to reconfigure
5763 	 * any capability that changed during connection.
5764 	 */
5765 	if (mlme_obj->cfg.obss_ht40.is_override_ht20_40_24g)
5766 		sme_set_vdev_ies_per_band(mac_handle, vdev_id,
5767 					  wlan_vdev_mlme_get_opmode(vdev));
5768 
5769 	return QDF_STATUS_SUCCESS;
5770 }
5771 
5772 QDF_STATUS cm_csr_handle_diconnect_req(struct wlan_objmgr_vdev *vdev,
5773 				       struct wlan_cm_vdev_discon_req *req)
5774 {
5775 	struct mac_context *mac_ctx;
5776 	uint8_t vdev_id = wlan_vdev_get_id(vdev);
5777 	struct csr_roam_session *session;
5778 
5779 	/*
5780 	 * This API is to update legacy struct and should be removed once
5781 	 * CSR is cleaned up fully. No new params should be added to CSR, use
5782 	 * vdev/pdev/psoc instead
5783 	 */
5784 	mac_ctx = cds_get_context(QDF_MODULE_ID_SME);
5785 	if (!mac_ctx)
5786 		return QDF_STATUS_E_INVAL;
5787 
5788 	session = CSR_GET_SESSION(mac_ctx, vdev_id);
5789 	if (!session || !CSR_IS_SESSION_VALID(mac_ctx, vdev_id)) {
5790 		sme_err("session not found for vdev_id %d", vdev_id);
5791 		return QDF_STATUS_E_INVAL;
5792 	}
5793 
5794 	cm_csr_set_joining(vdev_id);
5795 
5796 	/* Update the disconnect stats */
5797 	session->disconnect_stats.disconnection_cnt++;
5798 	if (req->req.source == CM_PEER_DISCONNECT) {
5799 		session->disconnect_stats.disassoc_by_peer++;
5800 	} else if (req->req.source == CM_SB_DISCONNECT) {
5801 		switch (req->req.reason_code) {
5802 		case REASON_DISASSOC_DUE_TO_INACTIVITY:
5803 			session->disconnect_stats.peer_kickout++;
5804 			break;
5805 		case REASON_BEACON_MISSED:
5806 			session->disconnect_stats.bmiss++;
5807 			break;
5808 		default:
5809 			/* Unknown reason code */
5810 			break;
5811 		}
5812 	} else if (req->req.source == CM_MLO_LINK_SWITCH_DISCONNECT) {
5813 		/* Do not update any stats as session is going to be deleted*/
5814 	} else {
5815 		session->disconnect_stats.disconnection_by_app++;
5816 	}
5817 
5818 	csr_update_prev_ap_info(session, vdev);
5819 	csr_qos_send_disconnect_ind(mac_ctx, vdev_id);
5820 
5821 	return QDF_STATUS_SUCCESS;
5822 }
5823 
5824 QDF_STATUS
5825 cm_csr_disconnect_done_ind(struct wlan_objmgr_vdev *vdev,
5826 			   struct wlan_cm_discon_rsp *rsp)
5827 {
5828 	mac_handle_t mac_handle;
5829 	struct mac_context *mac_ctx;
5830 	uint8_t vdev_id = wlan_vdev_get_id(vdev);
5831 	struct wlan_mlme_psoc_ext_obj *mlme_obj;
5832 
5833 	/*
5834 	 * This API is to update legacy struct and should be removed once
5835 	 * CSR is cleaned up fully. No new params should be added to CSR, use
5836 	 * vdev/pdev/psoc instead
5837 	 */
5838 	mac_handle = cds_get_context(QDF_MODULE_ID_SME);
5839 
5840 	mac_ctx = MAC_CONTEXT(mac_handle);
5841 	if (!mac_ctx)
5842 		return QDF_STATUS_E_INVAL;
5843 
5844 	mlme_obj = mlme_get_psoc_ext_obj(mac_ctx->psoc);
5845 	if (!mlme_obj)
5846 		return QDF_STATUS_E_INVAL;
5847 
5848 	cm_csr_set_idle(vdev_id);
5849 	if (cm_is_vdev_roaming(vdev))
5850 		sme_qos_update_hand_off(vdev_id, false);
5851 	csr_set_default_dot11_mode(mac_ctx);
5852 
5853 	/*
5854 	 * Update the IEs after disconnection to remove
5855 	 * any connection specific capability change and
5856 	 * to reset back to self cap
5857 	 */
5858 	if (mlme_obj->cfg.obss_ht40.is_override_ht20_40_24g) {
5859 		wlan_cm_set_force_20mhz_in_24ghz(vdev, true);
5860 		sme_set_vdev_ies_per_band(mac_handle, vdev_id,
5861 					  wlan_vdev_mlme_get_opmode(vdev));
5862 	}
5863 
5864 	return QDF_STATUS_SUCCESS;
5865 }
5866 
5867 #ifdef WLAN_FEATURE_HOST_ROAM
5868 void cm_csr_preauth_done(struct wlan_objmgr_vdev *vdev)
5869 {
5870 	struct mac_context *mac_ctx;
5871 	uint8_t vdev_id = wlan_vdev_get_id(vdev);
5872 	struct cm_roam_values_copy config;
5873 	bool is_11r;
5874 
5875 	/*
5876 	 * This API is to update legacy struct and should be removed once
5877 	 * CSR is cleaned up fully. No new params should be added to CSR, use
5878 	 * vdev/pdev/psoc instead
5879 	 */
5880 	mac_ctx = cds_get_context(QDF_MODULE_ID_SME);
5881 	if (!mac_ctx) {
5882 		sme_err("mac_ctx is NULL");
5883 		return;
5884 	}
5885 
5886 	wlan_cm_roam_cfg_get_value(mac_ctx->psoc, vdev_id, IS_11R_CONNECTION,
5887 				   &config);
5888 	is_11r = config.bool_value;
5889 	if (is_11r || wlan_cm_get_ese_assoc(mac_ctx->pdev, vdev_id))
5890 		sme_qos_csr_event_ind(mac_ctx, vdev_id,
5891 				      SME_QOS_CSR_PREAUTH_SUCCESS_IND, NULL);
5892 }
5893 #endif
5894 
5895 /* */
5896 QDF_STATUS csr_send_mb_disassoc_req_msg(struct mac_context *mac,
5897 					uint32_t sessionId,
5898 					tSirMacAddr bssId, uint16_t reasonCode)
5899 {
5900 	struct disassoc_req *pMsg;
5901 	struct csr_roam_session *pSession = CSR_GET_SESSION(mac, sessionId);
5902 
5903 	if (!CSR_IS_SESSION_VALID(mac, sessionId))
5904 		return QDF_STATUS_E_FAILURE;
5905 
5906 	pMsg = qdf_mem_malloc(sizeof(*pMsg));
5907 	if (!pMsg)
5908 		return QDF_STATUS_E_NOMEM;
5909 
5910 	pMsg->messageType = eWNI_SME_DISASSOC_REQ;
5911 	pMsg->length = sizeof(*pMsg);
5912 	pMsg->sessionId = sessionId;
5913 
5914 	wlan_mlme_get_mac_vdev_id(mac->pdev, sessionId, &pMsg->bssid);
5915 	qdf_mem_copy(&pMsg->peer_macaddr.bytes, bssId, QDF_MAC_ADDR_SIZE);
5916 	pMsg->reasonCode = reasonCode;
5917 
5918 	/* Update the disconnect stats */
5919 	pSession->disconnect_stats.disconnection_cnt++;
5920 	pSession->disconnect_stats.disconnection_by_app++;
5921 
5922 	return umac_send_mb_message_to_mac(pMsg);
5923 }
5924 
5925 QDF_STATUS csr_send_chng_mcc_beacon_interval(struct mac_context *mac,
5926 						uint32_t sessionId)
5927 {
5928 	struct wlan_change_bi *pMsg;
5929 	uint16_t len = 0;
5930 	QDF_STATUS status = QDF_STATUS_SUCCESS;
5931 	struct csr_roam_session *pSession = CSR_GET_SESSION(mac, sessionId);
5932 
5933 	if (!pSession) {
5934 		sme_err("session %d not found", sessionId);
5935 		return QDF_STATUS_E_FAILURE;
5936 	}
5937 	/* NO need to update the Beacon Params if update beacon parameter flag
5938 	 * is not set
5939 	 */
5940 	if (!mac->roam.roamSession[sessionId].update_bcn_int)
5941 		return QDF_STATUS_SUCCESS;
5942 
5943 	mac->roam.roamSession[sessionId].update_bcn_int =
5944 		false;
5945 
5946 	/* Create the message and send to lim */
5947 	len = sizeof(*pMsg);
5948 	pMsg = qdf_mem_malloc(len);
5949 	if (!pMsg)
5950 		status = QDF_STATUS_E_NOMEM;
5951 	else
5952 		status = QDF_STATUS_SUCCESS;
5953 	if (QDF_IS_STATUS_SUCCESS(status)) {
5954 		pMsg->message_type = eWNI_SME_CHNG_MCC_BEACON_INTERVAL;
5955 		pMsg->length = len;
5956 
5957 		wlan_mlme_get_mac_vdev_id(mac->pdev, sessionId,
5958 					  &pMsg->bssid);
5959 		sme_debug("CSR Attempting to change BI for Bssid= "
5960 			  QDF_MAC_ADDR_FMT,
5961 			  QDF_MAC_ADDR_REF(pMsg->bssid.bytes));
5962 		pMsg->session_id = sessionId;
5963 		sme_debug("session %d BeaconInterval %d",
5964 			sessionId,
5965 			mac->roam.roamSession[sessionId].bcn_int);
5966 		pMsg->beacon_interval =
5967 			mac->roam.roamSession[sessionId].bcn_int;
5968 		status = umac_send_mb_message_to_mac(pMsg);
5969 	}
5970 	return status;
5971 }
5972 
5973 #ifdef QCA_HT_2040_COEX
5974 QDF_STATUS csr_set_ht2040_mode(struct mac_context *mac, uint32_t sessionId,
5975 			       ePhyChanBondState cbMode, bool obssEnabled)
5976 {
5977 	struct set_ht2040_mode *pMsg;
5978 	uint16_t len = 0;
5979 	QDF_STATUS status = QDF_STATUS_SUCCESS;
5980 	struct csr_roam_session *pSession = CSR_GET_SESSION(mac, sessionId);
5981 
5982 	if (!pSession) {
5983 		sme_err("session %d not found", sessionId);
5984 		return QDF_STATUS_E_FAILURE;
5985 	}
5986 
5987 	/* Create the message and send to lim */
5988 	len = sizeof(struct set_ht2040_mode);
5989 	pMsg = qdf_mem_malloc(len);
5990 	if (!pMsg)
5991 		status = QDF_STATUS_E_NOMEM;
5992 	else
5993 		status = QDF_STATUS_SUCCESS;
5994 	if (QDF_IS_STATUS_SUCCESS(status)) {
5995 		qdf_mem_zero(pMsg, sizeof(struct set_ht2040_mode));
5996 		pMsg->messageType = eWNI_SME_SET_HT_2040_MODE;
5997 		pMsg->length = len;
5998 
5999 		wlan_mlme_get_mac_vdev_id(mac->pdev, sessionId, &pMsg->bssid);
6000 		sme_debug(
6001 			"CSR Attempting to set HT20/40 mode for Bssid= "
6002 			 QDF_MAC_ADDR_FMT,
6003 			 QDF_MAC_ADDR_REF(pMsg->bssid.bytes));
6004 		pMsg->sessionId = sessionId;
6005 		sme_debug("  session %d HT20/40 mode %d",
6006 			sessionId, cbMode);
6007 		pMsg->cbMode = cbMode;
6008 		pMsg->obssEnabled = obssEnabled;
6009 		status = umac_send_mb_message_to_mac(pMsg);
6010 	}
6011 	return status;
6012 }
6013 #endif
6014 
6015 QDF_STATUS csr_send_mb_deauth_req_msg(struct mac_context *mac,
6016 				      uint32_t vdev_id,
6017 				      tSirMacAddr bssId, uint16_t reasonCode)
6018 {
6019 	struct deauth_req *pMsg;
6020 	struct csr_roam_session *pSession = CSR_GET_SESSION(mac, vdev_id);
6021 
6022 	if (!CSR_IS_SESSION_VALID(mac, vdev_id))
6023 		return QDF_STATUS_E_FAILURE;
6024 
6025 	pMsg = qdf_mem_malloc(sizeof(*pMsg));
6026 	if (!pMsg)
6027 		return QDF_STATUS_E_NOMEM;
6028 
6029 	pMsg->messageType = eWNI_SME_DEAUTH_REQ;
6030 	pMsg->length = sizeof(*pMsg);
6031 	pMsg->vdev_id = vdev_id;
6032 
6033 	wlan_mlme_get_mac_vdev_id(mac->pdev, vdev_id, &pMsg->bssid);
6034 	/* Set the peer MAC address before sending the message to LIM */
6035 	qdf_mem_copy(&pMsg->peer_macaddr.bytes, bssId, QDF_MAC_ADDR_SIZE);
6036 	pMsg->reasonCode = reasonCode;
6037 
6038 	/* Update the disconnect stats */
6039 	pSession->disconnect_stats.disconnection_cnt++;
6040 	pSession->disconnect_stats.disconnection_by_app++;
6041 
6042 	return umac_send_mb_message_to_mac(pMsg);
6043 }
6044 
6045 QDF_STATUS csr_send_mb_disassoc_cnf_msg(struct mac_context *mac,
6046 					struct disassoc_ind *pDisassocInd)
6047 {
6048 	QDF_STATUS status = QDF_STATUS_SUCCESS;
6049 	struct disassoc_cnf *pMsg;
6050 
6051 	do {
6052 		pMsg = qdf_mem_malloc(sizeof(*pMsg));
6053 		if (!pMsg)
6054 			status = QDF_STATUS_E_NOMEM;
6055 		else
6056 			status = QDF_STATUS_SUCCESS;
6057 		if (!QDF_IS_STATUS_SUCCESS(status))
6058 			break;
6059 		pMsg->messageType = eWNI_SME_DISASSOC_CNF;
6060 		pMsg->status_code = eSIR_SME_SUCCESS;
6061 		pMsg->length = sizeof(*pMsg);
6062 		pMsg->vdev_id = pDisassocInd->vdev_id;
6063 		qdf_copy_macaddr(&pMsg->peer_macaddr,
6064 				 &pDisassocInd->peer_macaddr);
6065 		status = QDF_STATUS_SUCCESS;
6066 		if (!QDF_IS_STATUS_SUCCESS(status)) {
6067 			qdf_mem_free(pMsg);
6068 			break;
6069 		}
6070 
6071 		qdf_copy_macaddr(&pMsg->bssid, &pDisassocInd->bssid);
6072 		status = QDF_STATUS_SUCCESS;
6073 		if (!QDF_IS_STATUS_SUCCESS(status)) {
6074 			qdf_mem_free(pMsg);
6075 			break;
6076 		}
6077 
6078 		status = umac_send_mb_message_to_mac(pMsg);
6079 	} while (0);
6080 	return status;
6081 }
6082 
6083 QDF_STATUS csr_send_mb_deauth_cnf_msg(struct mac_context *mac,
6084 				      struct deauth_ind *pDeauthInd)
6085 {
6086 	QDF_STATUS status = QDF_STATUS_SUCCESS;
6087 	struct deauth_cnf *pMsg;
6088 
6089 	do {
6090 		pMsg = qdf_mem_malloc(sizeof(*pMsg));
6091 		if (!pMsg)
6092 			status = QDF_STATUS_E_NOMEM;
6093 		else
6094 			status = QDF_STATUS_SUCCESS;
6095 		if (!QDF_IS_STATUS_SUCCESS(status))
6096 			break;
6097 		pMsg->messageType = eWNI_SME_DEAUTH_CNF;
6098 		pMsg->status_code = eSIR_SME_SUCCESS;
6099 		pMsg->length = sizeof(*pMsg);
6100 		pMsg->vdev_id = pDeauthInd->vdev_id;
6101 		qdf_copy_macaddr(&pMsg->bssid, &pDeauthInd->bssid);
6102 		status = QDF_STATUS_SUCCESS;
6103 		if (!QDF_IS_STATUS_SUCCESS(status)) {
6104 			qdf_mem_free(pMsg);
6105 			break;
6106 		}
6107 		qdf_copy_macaddr(&pMsg->peer_macaddr,
6108 				 &pDeauthInd->peer_macaddr);
6109 		status = QDF_STATUS_SUCCESS;
6110 		if (!QDF_IS_STATUS_SUCCESS(status)) {
6111 			qdf_mem_free(pMsg);
6112 			break;
6113 		}
6114 		status = umac_send_mb_message_to_mac(pMsg);
6115 	} while (0);
6116 	return status;
6117 }
6118 
6119 QDF_STATUS csr_send_assoc_cnf_msg(struct mac_context *mac,
6120 				  struct assoc_ind *pAssocInd,
6121 				  QDF_STATUS Halstatus,
6122 				  enum wlan_status_code mac_status_code)
6123 {
6124 	QDF_STATUS status = QDF_STATUS_SUCCESS;
6125 	struct assoc_cnf *pMsg;
6126 	struct scheduler_msg msg = { 0 };
6127 
6128 	sme_debug("HalStatus: %d, mac_status_code %d",
6129 		  Halstatus, mac_status_code);
6130 	do {
6131 		pMsg = qdf_mem_malloc(sizeof(*pMsg));
6132 		if (!pMsg)
6133 			return QDF_STATUS_E_NOMEM;
6134 		pMsg->messageType = eWNI_SME_ASSOC_CNF;
6135 		pMsg->length = sizeof(*pMsg);
6136 		if (QDF_IS_STATUS_SUCCESS(Halstatus)) {
6137 			pMsg->status_code = eSIR_SME_SUCCESS;
6138 		} else {
6139 			pMsg->status_code = eSIR_SME_ASSOC_REFUSED;
6140 			pMsg->mac_status_code = mac_status_code;
6141 		}
6142 		/* bssId */
6143 		qdf_mem_copy(pMsg->bssid.bytes, pAssocInd->bssId,
6144 			     QDF_MAC_ADDR_SIZE);
6145 		/* peerMacAddr */
6146 		qdf_mem_copy(pMsg->peer_macaddr.bytes, pAssocInd->peerMacAddr,
6147 			     QDF_MAC_ADDR_SIZE);
6148 		/* aid */
6149 		pMsg->aid = pAssocInd->aid;
6150 		/* OWE IE */
6151 		if (pAssocInd->owe_ie_len) {
6152 			pMsg->owe_ie = qdf_mem_malloc(pAssocInd->owe_ie_len);
6153 			if (!pMsg->owe_ie)
6154 				return QDF_STATUS_E_NOMEM;
6155 			qdf_mem_copy(pMsg->owe_ie, pAssocInd->owe_ie,
6156 				     pAssocInd->owe_ie_len);
6157 			pMsg->owe_ie_len = pAssocInd->owe_ie_len;
6158 		}
6159 
6160 		if (pAssocInd->ft_ie_len) {
6161 			pMsg->ft_ie = qdf_mem_malloc(pAssocInd->ft_ie_len);
6162 			if (!pMsg->ft_ie)
6163 				return QDF_STATUS_E_NOMEM;
6164 			qdf_mem_copy(pMsg->ft_ie, pAssocInd->ft_ie,
6165 				     pAssocInd->ft_ie_len);
6166 			pMsg->ft_ie_len = pAssocInd->ft_ie_len;
6167 		}
6168 		pMsg->need_assoc_rsp_tx_cb = pAssocInd->need_assoc_rsp_tx_cb;
6169 
6170 		msg.type = pMsg->messageType;
6171 		msg.bodyval = 0;
6172 		msg.bodyptr = pMsg;
6173 		/* pMsg is freed by umac_send_mb_message_to_mac in anycase*/
6174 		status = scheduler_post_msg_by_priority(QDF_MODULE_ID_PE, &msg,
6175 							true);
6176 	} while (0);
6177 	return status;
6178 }
6179 
6180 /**
6181  * csr_store_oce_cfg_flags_in_vdev() - fill OCE flags from ini
6182  * @mac: mac_context.
6183  * @vdev: Pointer to pdev obj
6184  * @vdev_id: vdev_id
6185  *
6186  * This API will store the oce flags in vdev mlme priv object
6187  *
6188  * Return: none
6189  */
6190 static void csr_store_oce_cfg_flags_in_vdev(struct mac_context *mac,
6191 					    struct wlan_objmgr_pdev *pdev,
6192 					    uint8_t vdev_id)
6193 {
6194 	uint8_t *vdev_dynamic_oce;
6195 	struct wlan_objmgr_vdev *vdev =
6196 	wlan_objmgr_get_vdev_by_id_from_pdev(pdev, vdev_id, WLAN_LEGACY_MAC_ID);
6197 
6198 	if (!vdev)
6199 		return;
6200 
6201 	vdev_dynamic_oce = mlme_get_dynamic_oce_flags(vdev);
6202 	if (vdev_dynamic_oce)
6203 		*vdev_dynamic_oce = mac->mlme_cfg->oce.feature_bitmap;
6204 	wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_MAC_ID);
6205 }
6206 
6207 void csr_send_set_ie(uint8_t type, uint8_t sub_type,
6208 		     uint8_t vdev_id)
6209 {
6210 	struct send_extcap_ie *msg;
6211 	QDF_STATUS status;
6212 
6213 	sme_debug("send SET IE msg to PE");
6214 
6215 	if (!(type == WLAN_VDEV_MLME_TYPE_STA ||
6216 	      (type == WLAN_VDEV_MLME_TYPE_AP &&
6217 	      sub_type == WLAN_VDEV_MLME_SUBTYPE_P2P_DEVICE))) {
6218 		sme_debug("Failed to send set IE req for vdev_%d", vdev_id);
6219 		return;
6220 	}
6221 
6222 	msg = qdf_mem_malloc(sizeof(*msg));
6223 	if (!msg)
6224 		return;
6225 
6226 	msg->msg_type = eWNI_SME_SET_IE_REQ;
6227 	msg->session_id = vdev_id;
6228 	msg->length = sizeof(*msg);
6229 	status = umac_send_mb_message_to_mac(msg);
6230 	if (!QDF_IS_STATUS_SUCCESS(status))
6231 		sme_debug("Failed to send set IE req for vdev_%d", vdev_id);
6232 }
6233 
6234 void csr_get_vdev_type_nss(enum QDF_OPMODE dev_mode, uint8_t *nss_2g,
6235 			   uint8_t *nss_5g)
6236 {
6237 	struct mac_context *mac_ctx = sme_get_mac_context();
6238 
6239 	if (!mac_ctx) {
6240 		sme_err("Invalid MAC context");
6241 		return;
6242 	}
6243 
6244 	switch (dev_mode) {
6245 	case QDF_STA_MODE:
6246 		*nss_2g = mac_ctx->vdev_type_nss_2g.sta;
6247 		*nss_5g = mac_ctx->vdev_type_nss_5g.sta;
6248 		break;
6249 	case QDF_SAP_MODE:
6250 		*nss_2g = mac_ctx->vdev_type_nss_2g.sap;
6251 		*nss_5g = mac_ctx->vdev_type_nss_5g.sap;
6252 		break;
6253 	case QDF_P2P_CLIENT_MODE:
6254 		*nss_2g = mac_ctx->vdev_type_nss_2g.p2p_cli;
6255 		*nss_5g = mac_ctx->vdev_type_nss_5g.p2p_cli;
6256 		break;
6257 	case QDF_P2P_GO_MODE:
6258 		*nss_2g = mac_ctx->vdev_type_nss_2g.p2p_go;
6259 		*nss_5g = mac_ctx->vdev_type_nss_5g.p2p_go;
6260 		break;
6261 	case QDF_P2P_DEVICE_MODE:
6262 		*nss_2g = mac_ctx->vdev_type_nss_2g.p2p_dev;
6263 		*nss_5g = mac_ctx->vdev_type_nss_5g.p2p_dev;
6264 		break;
6265 	case QDF_IBSS_MODE:
6266 		*nss_2g = mac_ctx->vdev_type_nss_2g.ibss;
6267 		*nss_5g = mac_ctx->vdev_type_nss_5g.ibss;
6268 		break;
6269 	case QDF_OCB_MODE:
6270 		*nss_2g = mac_ctx->vdev_type_nss_2g.ocb;
6271 		*nss_5g = mac_ctx->vdev_type_nss_5g.ocb;
6272 		break;
6273 	case QDF_NAN_DISC_MODE:
6274 		*nss_2g = mac_ctx->vdev_type_nss_2g.nan;
6275 		*nss_5g = mac_ctx->vdev_type_nss_5g.nan;
6276 		break;
6277 	case QDF_NDI_MODE:
6278 		*nss_2g = mac_ctx->vdev_type_nss_2g.ndi;
6279 		*nss_5g = mac_ctx->vdev_type_nss_5g.ndi;
6280 		break;
6281 	default:
6282 		*nss_2g = 1;
6283 		*nss_5g = 1;
6284 		sme_err("Unknown device mode: %d", dev_mode);
6285 		break;
6286 	}
6287 	sme_debug("mode - %d: nss_2g - %d, 5g - %d",
6288 		  dev_mode, *nss_2g, *nss_5g);
6289 }
6290 
6291 QDF_STATUS csr_setup_vdev_session(struct vdev_mlme_obj *vdev_mlme)
6292 {
6293 	QDF_STATUS status;
6294 	uint32_t existing_session_id;
6295 	struct csr_roam_session *session;
6296 	struct mlme_vht_capabilities_info *vht_cap_info;
6297 	u8 vdev_id;
6298 	struct qdf_mac_addr *mac_addr;
6299 	mac_handle_t mac_handle;
6300 	struct mac_context *mac_ctx;
6301 	struct wlan_objmgr_vdev *vdev;
6302 	struct wlan_vht_config vht_config;
6303 	struct wlan_ht_config ht_cap;
6304 
6305 	mac_handle = cds_get_context(QDF_MODULE_ID_SME);
6306 	mac_ctx = MAC_CONTEXT(mac_handle);
6307 	if (!mac_ctx) {
6308 		QDF_ASSERT(0);
6309 		return QDF_STATUS_E_INVAL;
6310 	}
6311 
6312 	if (!(mac_ctx->mlme_cfg)) {
6313 		sme_err("invalid mlme cfg");
6314 		return QDF_STATUS_E_FAILURE;
6315 	}
6316 	vht_cap_info = &mac_ctx->mlme_cfg->vht_caps.vht_cap_info;
6317 
6318 	vdev = vdev_mlme->vdev;
6319 
6320 	vdev_id = wlan_vdev_get_id(vdev);
6321 	mac_addr = (struct qdf_mac_addr *)wlan_vdev_mlme_get_macaddr(vdev);
6322 	/* check to see if the mac address already belongs to a session */
6323 	status = csr_roam_get_session_id_from_bssid(mac_ctx, mac_addr,
6324 						    &existing_session_id);
6325 	if (QDF_IS_STATUS_SUCCESS(status)) {
6326 		sme_err("Session %d exists with mac address "QDF_MAC_ADDR_FMT,
6327 			existing_session_id,
6328 			QDF_MAC_ADDR_REF(mac_addr->bytes));
6329 		return QDF_STATUS_E_FAILURE;
6330 	}
6331 
6332 	/* attempt to retrieve session for Id */
6333 	session = CSR_GET_SESSION(mac_ctx, vdev_id);
6334 	if (!session) {
6335 		sme_err("Session does not exist for interface %d", vdev_id);
6336 		return QDF_STATUS_E_FAILURE;
6337 	}
6338 
6339 	/* check to see if the session is already active */
6340 	if (session->sessionActive) {
6341 		sme_err("Cannot re-open active session with Id %d", vdev_id);
6342 		return QDF_STATUS_E_FAILURE;
6343 	}
6344 
6345 	session->sessionActive = true;
6346 	session->vdev_id = vdev_id;
6347 
6348 	ht_cap.caps = 0;
6349 	vht_config.caps = 0;
6350 	ht_cap.ht_caps = mac_ctx->mlme_cfg->ht_caps.ht_cap_info;
6351 	vdev_mlme->proto.ht_info.ht_caps = ht_cap.caps;
6352 
6353 	vht_config.max_mpdu_len = vht_cap_info->ampdu_len;
6354 	vht_config.supported_channel_widthset =
6355 			vht_cap_info->supp_chan_width;
6356 	vht_config.ldpc_coding = vht_cap_info->ldpc_coding_cap;
6357 	vht_config.shortgi80 = vht_cap_info->short_gi_80mhz;
6358 	vht_config.shortgi160and80plus80 =
6359 			vht_cap_info->short_gi_160mhz;
6360 	vht_config.tx_stbc = vht_cap_info->tx_stbc;
6361 	vht_config.rx_stbc = vht_cap_info->rx_stbc;
6362 	vht_config.su_beam_former = vht_cap_info->su_bformer;
6363 	vht_config.su_beam_formee = vht_cap_info->su_bformee;
6364 	vht_config.csnof_beamformer_antSup =
6365 			vht_cap_info->tx_bfee_ant_supp;
6366 	vht_config.num_soundingdim = vht_cap_info->num_soundingdim;
6367 	vht_config.mu_beam_former = vht_cap_info->mu_bformer;
6368 	vht_config.mu_beam_formee = vht_cap_info->enable_mu_bformee;
6369 	vht_config.vht_txops = vht_cap_info->txop_ps;
6370 	vht_config.htc_vhtcap = vht_cap_info->htc_vhtc;
6371 	vht_config.rx_antpattern = vht_cap_info->rx_antpattern;
6372 	vht_config.tx_antpattern = vht_cap_info->tx_antpattern;
6373 
6374 	vht_config.max_ampdu_lenexp =
6375 			vht_cap_info->ampdu_len_exponent;
6376 	vdev_mlme->proto.vht_info.caps = vht_config.caps;
6377 	csr_update_session_he_cap(mac_ctx, session);
6378 	csr_update_session_eht_cap(mac_ctx, session);
6379 
6380 	csr_send_set_ie(vdev_mlme->mgmt.generic.type,
6381 			vdev_mlme->mgmt.generic.subtype,
6382 			wlan_vdev_get_id(vdev));
6383 
6384 	if (vdev_mlme->mgmt.generic.type == WLAN_VDEV_MLME_TYPE_STA) {
6385 		csr_store_oce_cfg_flags_in_vdev(mac_ctx, mac_ctx->pdev,
6386 						wlan_vdev_get_id(vdev));
6387 		wlan_mlme_update_oce_flags(mac_ctx->pdev);
6388 	}
6389 
6390 	return QDF_STATUS_SUCCESS;
6391 }
6392 
6393 void csr_cleanup_vdev_session(struct mac_context *mac, uint8_t vdev_id)
6394 {
6395 	if (CSR_IS_SESSION_VALID(mac, vdev_id)) {
6396 		struct csr_roam_session *pSession = CSR_GET_SESSION(mac,
6397 								vdev_id);
6398 
6399 		csr_flush_roam_scan_chan_lists(mac, vdev_id);
6400 		csr_roam_free_connected_info(mac, &pSession->connectedInfo);
6401 		csr_init_session(mac, vdev_id);
6402 	}
6403 }
6404 
6405 QDF_STATUS csr_prepare_vdev_delete(struct mac_context *mac_ctx,
6406 				   struct wlan_objmgr_vdev *vdev)
6407 {
6408 	QDF_STATUS status = QDF_STATUS_SUCCESS;
6409 	struct csr_roam_session *session;
6410 	uint8_t vdev_id = wlan_vdev_get_id(vdev);
6411 
6412 	session = CSR_GET_SESSION(mac_ctx, vdev_id);
6413 	if (!session)
6414 		return QDF_STATUS_E_INVAL;
6415 
6416 	if (!CSR_IS_SESSION_VALID(mac_ctx, vdev_id))
6417 		return QDF_STATUS_E_INVAL;
6418 
6419 	if (CSR_IS_WAIT_FOR_KEY(mac_ctx, vdev_id)) {
6420 		sme_debug("Stop Wait for key timer and change substate to eCSR_ROAM_SUBSTATE_NONE");
6421 		cm_stop_wait_for_key_timer(mac_ctx->psoc, vdev_id);
6422 		csr_roam_substate_change(mac_ctx, eCSR_ROAM_SUBSTATE_NONE,
6423 					 vdev_id);
6424 	}
6425 
6426 	wlan_ser_vdev_queue_disable(vdev);
6427 	/* Flush all the commands for vdev */
6428 	wlan_serialization_purge_all_cmd_by_vdev_id(mac_ctx->pdev, vdev_id);
6429 	if (!mac_ctx->session_close_cb) {
6430 		sme_err("no close session callback registered");
6431 		return QDF_STATUS_E_FAILURE;
6432 	}
6433 
6434 	return status;
6435 }
6436 
6437 static void csr_init_session(struct mac_context *mac, uint32_t sessionId)
6438 {
6439 	struct csr_roam_session *pSession = CSR_GET_SESSION(mac, sessionId);
6440 
6441 	if (!pSession)
6442 		return;
6443 
6444 	pSession->sessionActive = false;
6445 	pSession->vdev_id = WLAN_UMAC_VDEV_ID_MAX;
6446 	pSession->connectState = eCSR_ASSOC_STATE_TYPE_NOT_CONNECTED;
6447 	csr_roam_free_connected_info(mac, &pSession->connectedInfo);
6448 }
6449 
6450 static void csr_get_vdev_id_from_bssid(struct wlan_objmgr_pdev *pdev,
6451 				       void *object, void *arg)
6452 {
6453 	struct bssid_search_arg *bssid_arg = arg;
6454 	struct wlan_objmgr_vdev *vdev = (struct wlan_objmgr_vdev *)object;
6455 	struct wlan_objmgr_peer *peer;
6456 
6457 	if (wlan_vdev_is_up(vdev) != QDF_STATUS_SUCCESS)
6458 		return;
6459 
6460 	peer = wlan_objmgr_vdev_try_get_bsspeer(vdev, WLAN_LEGACY_SME_ID);
6461 	if (!peer)
6462 		return;
6463 
6464 	if (WLAN_ADDR_EQ(bssid_arg->peer_addr.bytes,
6465 			 wlan_peer_get_macaddr(peer)) == QDF_STATUS_SUCCESS)
6466 		bssid_arg->vdev_id = wlan_vdev_get_id(vdev);
6467 
6468 	wlan_objmgr_peer_release_ref(peer, WLAN_LEGACY_SME_ID);
6469 }
6470 
6471 QDF_STATUS csr_roam_get_session_id_from_bssid(struct mac_context *mac,
6472 					      struct qdf_mac_addr *bssid,
6473 					      uint32_t *pSessionId)
6474 {
6475 	struct bssid_search_arg bssid_arg;
6476 
6477 	qdf_copy_macaddr(&bssid_arg.peer_addr, bssid);
6478 	bssid_arg.vdev_id = WLAN_MAX_VDEVS;
6479 	wlan_objmgr_pdev_iterate_obj_list(mac->pdev, WLAN_VDEV_OP,
6480 					  csr_get_vdev_id_from_bssid,
6481 					  &bssid_arg, 0,
6482 					  WLAN_LEGACY_SME_ID);
6483 	if (bssid_arg.vdev_id >= WLAN_MAX_VDEVS) {
6484 		*pSessionId = 0;
6485 		return QDF_STATUS_E_FAILURE;
6486 	}
6487 
6488 	*pSessionId = bssid_arg.vdev_id;
6489 
6490 	return QDF_STATUS_SUCCESS;
6491 }
6492 
6493 QDF_STATUS csr_get_snr(struct mac_context *mac,
6494 		       tCsrSnrCallback callback,
6495 		       struct qdf_mac_addr bssId, void *pContext)
6496 {
6497 	QDF_STATUS status = QDF_STATUS_SUCCESS;
6498 	struct scheduler_msg msg = {0};
6499 	uint32_t sessionId = WLAN_UMAC_VDEV_ID_MAX;
6500 	tAniGetSnrReq *pMsg;
6501 
6502 	pMsg = qdf_mem_malloc(sizeof(tAniGetSnrReq));
6503 	if (!pMsg)
6504 		return QDF_STATUS_E_NOMEM;
6505 
6506 	status = csr_roam_get_session_id_from_bssid(mac, &bssId, &sessionId);
6507 	if (!QDF_IS_STATUS_SUCCESS(status)) {
6508 		qdf_mem_free(pMsg);
6509 		sme_err("Couldn't find session_id for given BSSID");
6510 		return status;
6511 	}
6512 
6513 	pMsg->msgType = eWNI_SME_GET_SNR_REQ;
6514 	pMsg->msgLen = (uint16_t) sizeof(tAniGetSnrReq);
6515 	pMsg->sessionId = sessionId;
6516 	pMsg->snrCallback = callback;
6517 	pMsg->pDevContext = pContext;
6518 	msg.type = eWNI_SME_GET_SNR_REQ;
6519 	msg.bodyptr = pMsg;
6520 	msg.reserved = 0;
6521 
6522 	if (QDF_STATUS_SUCCESS != scheduler_post_message(QDF_MODULE_ID_SME,
6523 							 QDF_MODULE_ID_SME,
6524 							 QDF_MODULE_ID_SME,
6525 							 &msg)) {
6526 		qdf_mem_free((void *)pMsg);
6527 		status = QDF_STATUS_E_FAILURE;
6528 	}
6529 
6530 	return status;
6531 }
6532 
6533 #if defined(WLAN_FEATURE_HOST_ROAM) || defined(WLAN_FEATURE_ROAM_OFFLOAD)
6534 QDF_STATUS csr_invoke_neighbor_report_request(
6535 				uint8_t session_id,
6536 				struct sRrmNeighborReq *neighbor_report_req,
6537 				bool send_resp_to_host)
6538 {
6539 	struct wmi_invoke_neighbor_report_params *invoke_params;
6540 	struct scheduler_msg msg = {0};
6541 
6542 	if (!neighbor_report_req) {
6543 		sme_err("Invalid params");
6544 		return QDF_STATUS_E_INVAL;
6545 	}
6546 
6547 	invoke_params = qdf_mem_malloc(sizeof(*invoke_params));
6548 	if (!invoke_params)
6549 		return QDF_STATUS_E_NOMEM;
6550 
6551 	invoke_params->vdev_id = session_id;
6552 	invoke_params->send_resp_to_host = send_resp_to_host;
6553 
6554 	if (!neighbor_report_req->no_ssid) {
6555 		invoke_params->ssid.length = neighbor_report_req->ssid.length;
6556 		qdf_mem_copy(invoke_params->ssid.ssid,
6557 			     neighbor_report_req->ssid.ssId,
6558 			     neighbor_report_req->ssid.length);
6559 	} else {
6560 		invoke_params->ssid.length = 0;
6561 	}
6562 
6563 	sme_debug("Sending SIR_HAL_INVOKE_NEIGHBOR_REPORT");
6564 
6565 	msg.type = SIR_HAL_INVOKE_NEIGHBOR_REPORT;
6566 	msg.reserved = 0;
6567 	msg.bodyptr = invoke_params;
6568 
6569 	if (QDF_STATUS_SUCCESS != scheduler_post_message(QDF_MODULE_ID_SME,
6570 							 QDF_MODULE_ID_WMA,
6571 							 QDF_MODULE_ID_WMA,
6572 							 &msg)) {
6573 		sme_err("Not able to post message to WMA");
6574 		qdf_mem_free(invoke_params);
6575 		return QDF_STATUS_E_FAILURE;
6576 	}
6577 
6578 	return QDF_STATUS_SUCCESS;
6579 }
6580 
6581 #ifdef FEATURE_WLAN_ESE
6582 void wlan_cm_ese_populate_additional_ies(struct wlan_objmgr_pdev *pdev,
6583 			struct wlan_mlme_psoc_ext_obj *mlme_obj,
6584 			uint8_t vdev_id,
6585 			struct wlan_roam_scan_offload_params *rso_mode_cfg)
6586 {
6587 	uint8_t tspec_ie_hdr[SIR_MAC_OUI_WME_HDR_MIN]
6588 			= { 0x00, 0x50, 0xf2, 0x02, 0x02, 0x01 };
6589 	uint8_t tspec_ie_buf[DOT11F_IE_WMMTSPEC_MAX_LEN], j;
6590 	ese_wmm_tspec_ie *tspec_ie;
6591 	tESETspecInfo ese_tspec;
6592 	struct mac_context *mac_ctx;
6593 	struct csr_roam_session *session;
6594 
6595 	mac_ctx = sme_get_mac_context();
6596 	if (!mac_ctx) {
6597 		sme_err("mac_ctx is NULL");
6598 		return;
6599 	}
6600 
6601 	session = CSR_GET_SESSION(mac_ctx, vdev_id);
6602 	if (!session) {
6603 		sme_err("session is null %d", vdev_id);
6604 		return;
6605 	}
6606 
6607 	tspec_ie = (ese_wmm_tspec_ie *)(tspec_ie_buf + SIR_MAC_OUI_WME_HDR_MIN);
6608 	if (csr_is_wmm_supported(mac_ctx) &&
6609 	    mlme_obj->cfg.lfr.ese_enabled &&
6610 	    wlan_cm_get_ese_assoc(pdev, session->vdev_id)) {
6611 		ese_tspec.numTspecs = sme_qos_ese_retrieve_tspec_info(
6612 					mac_ctx, session->vdev_id,
6613 					(tTspecInfo *)&ese_tspec.tspec[0]);
6614 		qdf_mem_copy(tspec_ie_buf, tspec_ie_hdr,
6615 			     SIR_MAC_OUI_WME_HDR_MIN);
6616 		for (j = 0; j < ese_tspec.numTspecs; j++) {
6617 			/* Populate the tspec_ie */
6618 			ese_populate_wmm_tspec(&ese_tspec.tspec[j].tspec,
6619 					       tspec_ie);
6620 			wlan_cm_append_assoc_ies(rso_mode_cfg,
6621 						 WLAN_ELEMID_VENDOR,
6622 						  DOT11F_IE_WMMTSPEC_MAX_LEN,
6623 						 tspec_ie_buf);
6624 		}
6625 	}
6626 }
6627 #endif
6628 
6629 uint8_t *wlan_cm_get_rrm_cap_ie_data(void)
6630 {
6631 	struct mac_context *mac_ctx;
6632 
6633 	mac_ctx = sme_get_mac_context();
6634 	if (!mac_ctx) {
6635 		sme_err("mac_ctx is NULL");
6636 		return NULL;
6637 	}
6638 
6639 	return (uint8_t *)&mac_ctx->rrm.rrmPEContext.rrmEnabledCaps;
6640 }
6641 #endif
6642 
6643 tSmeCmd *csr_get_command_buffer(struct mac_context *mac)
6644 {
6645 	tSmeCmd *pCmd = sme_get_command_buffer(mac);
6646 
6647 	if (pCmd)
6648 		mac->roam.sPendingCommands++;
6649 
6650 	return pCmd;
6651 }
6652 
6653 static void csr_free_cmd_memory(struct mac_context *mac, tSmeCmd *pCommand)
6654 {
6655 	if (!pCommand) {
6656 		sme_err("pCommand is NULL");
6657 		return;
6658 	}
6659 	switch (pCommand->command) {
6660 	case eSmeCommandRoam:
6661 		csr_release_command_roam(mac, pCommand);
6662 		break;
6663 	case eSmeCommandWmStatusChange:
6664 		csr_release_command_wm_status_change(mac, pCommand);
6665 		break;
6666 	default:
6667 		break;
6668 	}
6669 }
6670 
6671 void csr_release_command_buffer(struct mac_context *mac, tSmeCmd *pCommand)
6672 {
6673 	if (mac->roam.sPendingCommands > 0) {
6674 		/*
6675 		 * All command allocated through csr_get_command_buffer
6676 		 * need to decrement the pending count when releasing
6677 		 */
6678 		mac->roam.sPendingCommands--;
6679 		csr_free_cmd_memory(mac, pCommand);
6680 		sme_release_command(mac, pCommand);
6681 	} else {
6682 		sme_err("no pending commands");
6683 		QDF_ASSERT(0);
6684 	}
6685 }
6686 
6687 void csr_release_command(struct mac_context *mac_ctx, tSmeCmd *sme_cmd)
6688 {
6689 	struct wlan_serialization_queued_cmd_info cmd_info;
6690 	struct wlan_serialization_command cmd;
6691 	struct wlan_objmgr_vdev *vdev;
6692 
6693 	if (!sme_cmd) {
6694 		sme_err("sme_cmd is NULL");
6695 		return;
6696 	}
6697 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac_ctx->psoc,
6698 			sme_cmd->vdev_id, WLAN_LEGACY_SME_ID);
6699 	if (!vdev) {
6700 		sme_err("Invalid vdev");
6701 		return;
6702 	}
6703 	qdf_mem_zero(&cmd_info,
6704 			sizeof(struct wlan_serialization_queued_cmd_info));
6705 	cmd_info.cmd_id = sme_cmd->cmd_id;
6706 	cmd_info.req_type = WLAN_SER_CANCEL_NON_SCAN_CMD;
6707 	cmd_info.cmd_type = csr_get_cmd_type(sme_cmd);
6708 	cmd_info.vdev = vdev;
6709 	qdf_mem_zero(&cmd, sizeof(struct wlan_serialization_command));
6710 	cmd.cmd_id = cmd_info.cmd_id;
6711 	cmd.cmd_type = cmd_info.cmd_type;
6712 	cmd.vdev = cmd_info.vdev;
6713 	if (wlan_serialization_is_cmd_present_in_active_queue(
6714 				mac_ctx->psoc, &cmd)) {
6715 		cmd_info.queue_type = WLAN_SERIALIZATION_ACTIVE_QUEUE;
6716 		wlan_serialization_remove_cmd(&cmd_info);
6717 	} else if (wlan_serialization_is_cmd_present_in_pending_queue(
6718 				mac_ctx->psoc, &cmd)) {
6719 		cmd_info.queue_type = WLAN_SERIALIZATION_PENDING_QUEUE;
6720 		wlan_serialization_cancel_request(&cmd_info);
6721 	} else {
6722 		sme_debug("can't find cmd_id %d cmd_type %d", cmd_info.cmd_id,
6723 			  cmd_info.cmd_type);
6724 	}
6725 	if (cmd_info.vdev)
6726 		wlan_objmgr_vdev_release_ref(cmd_info.vdev, WLAN_LEGACY_SME_ID);
6727 }
6728 
6729 
6730 static enum wlan_serialization_cmd_type csr_get_roam_cmd_type(
6731 		tSmeCmd *sme_cmd)
6732 {
6733 	enum wlan_serialization_cmd_type cmd_type = WLAN_SER_CMD_MAX;
6734 
6735 	switch (sme_cmd->u.roamCmd.roamReason) {
6736 	case eCsrForcedDisassocSta:
6737 		cmd_type = WLAN_SER_CMD_FORCE_DISASSOC_STA;
6738 		break;
6739 	case eCsrForcedDeauthSta:
6740 		cmd_type = WLAN_SER_CMD_FORCE_DEAUTH_STA;
6741 		break;
6742 	default:
6743 		break;
6744 	}
6745 
6746 	return cmd_type;
6747 }
6748 
6749 enum wlan_serialization_cmd_type csr_get_cmd_type(tSmeCmd *sme_cmd)
6750 {
6751 	enum wlan_serialization_cmd_type cmd_type = WLAN_SER_CMD_MAX;
6752 
6753 	switch (sme_cmd->command) {
6754 	case eSmeCommandRoam:
6755 		cmd_type = csr_get_roam_cmd_type(sme_cmd);
6756 		break;
6757 	case eSmeCommandWmStatusChange:
6758 		cmd_type = WLAN_SER_CMD_WM_STATUS_CHANGE;
6759 		break;
6760 	case eSmeCommandAddTs:
6761 		cmd_type = WLAN_SER_CMD_ADDTS;
6762 		break;
6763 	case eSmeCommandDelTs:
6764 		cmd_type = WLAN_SER_CMD_DELTS;
6765 		break;
6766 	case e_sme_command_set_hw_mode:
6767 		cmd_type = WLAN_SER_CMD_SET_HW_MODE;
6768 		break;
6769 	case e_sme_command_nss_update:
6770 		cmd_type = WLAN_SER_CMD_NSS_UPDATE;
6771 		break;
6772 	case e_sme_command_set_dual_mac_config:
6773 		cmd_type = WLAN_SER_CMD_SET_DUAL_MAC_CONFIG;
6774 		break;
6775 	case e_sme_command_set_antenna_mode:
6776 		cmd_type = WLAN_SER_CMD_SET_ANTENNA_MODE;
6777 		break;
6778 	case e_sme_command_sap_ch_width_update:
6779 		cmd_type = WLAN_SER_CMD_SAP_BW_UPDATE;
6780 		break;
6781 	default:
6782 		break;
6783 	}
6784 
6785 	return cmd_type;
6786 }
6787 
6788 static uint32_t csr_get_monotonous_number(struct mac_context *mac_ctx)
6789 {
6790 	uint32_t cmd_id;
6791 	uint32_t mask = 0x00FFFFFF, prefix = 0x0D000000;
6792 
6793 	cmd_id = qdf_atomic_inc_return(&mac_ctx->global_cmd_id);
6794 	cmd_id = (cmd_id & mask);
6795 	cmd_id = (cmd_id | prefix);
6796 
6797 	return cmd_id;
6798 }
6799 
6800 static void csr_fill_cmd_timeout(struct wlan_serialization_command *cmd)
6801 {
6802 	switch (cmd->cmd_type) {
6803 	case WLAN_SER_CMD_WM_STATUS_CHANGE:
6804 		cmd->cmd_timeout_duration = SME_CMD_PEER_DISCONNECT_TIMEOUT;
6805 		break;
6806 	case WLAN_SER_CMD_VDEV_START_BSS:
6807 		cmd->cmd_timeout_duration = SME_CMD_VDEV_START_BSS_TIMEOUT;
6808 		break;
6809 	case WLAN_SER_CMD_VDEV_STOP_BSS:
6810 		cmd->cmd_timeout_duration = SME_CMD_STOP_BSS_CMD_TIMEOUT;
6811 		break;
6812 	case WLAN_SER_CMD_FORCE_DISASSOC_STA:
6813 	case WLAN_SER_CMD_FORCE_DEAUTH_STA:
6814 		cmd->cmd_timeout_duration = SME_CMD_PEER_DISCONNECT_TIMEOUT;
6815 		break;
6816 
6817 	case WLAN_SER_CMD_ADDTS:
6818 	case WLAN_SER_CMD_DELTS:
6819 		cmd->cmd_timeout_duration = SME_CMD_ADD_DEL_TS_TIMEOUT;
6820 		break;
6821 	case WLAN_SER_CMD_SET_HW_MODE:
6822 	case WLAN_SER_CMD_NSS_UPDATE:
6823 	case WLAN_SER_CMD_SET_DUAL_MAC_CONFIG:
6824 	case WLAN_SER_CMD_SET_ANTENNA_MODE:
6825 	case WLAN_SER_CMD_SAP_BW_UPDATE:
6826 		cmd->cmd_timeout_duration = SME_CMD_POLICY_MGR_CMD_TIMEOUT;
6827 		break;
6828 	default:
6829 		cmd->cmd_timeout_duration = SME_ACTIVE_LIST_CMD_TIMEOUT_VALUE;
6830 		break;
6831 	}
6832 }
6833 
6834 QDF_STATUS csr_set_serialization_params_to_cmd(struct mac_context *mac_ctx,
6835 		tSmeCmd *sme_cmd, struct wlan_serialization_command *cmd,
6836 		uint8_t high_priority)
6837 {
6838 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
6839 
6840 	if (!sme_cmd) {
6841 		sme_err("Invalid sme_cmd");
6842 		return status;
6843 	}
6844 	if (!cmd) {
6845 		sme_err("Invalid serialization_cmd");
6846 		return status;
6847 	}
6848 
6849 	/*
6850 	 * no need to fill command id for non-scan as they will be
6851 	 * zero always
6852 	 */
6853 	sme_cmd->cmd_id = csr_get_monotonous_number(mac_ctx);
6854 	cmd->cmd_id = sme_cmd->cmd_id;
6855 
6856 	cmd->cmd_type = csr_get_cmd_type(sme_cmd);
6857 	if (cmd->cmd_type == WLAN_SER_CMD_MAX) {
6858 		sme_err("serialization enum not found for sme_cmd type %d",
6859 			sme_cmd->command);
6860 		return status;
6861 	}
6862 	cmd->vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac_ctx->psoc,
6863 				sme_cmd->vdev_id, WLAN_LEGACY_SME_ID);
6864 	if (!cmd->vdev) {
6865 		sme_err("vdev is NULL for vdev_id:%d", sme_cmd->vdev_id);
6866 		return status;
6867 	}
6868 	cmd->umac_cmd = sme_cmd;
6869 
6870 	csr_fill_cmd_timeout(cmd);
6871 
6872 	cmd->source = WLAN_UMAC_COMP_MLME;
6873 	cmd->cmd_cb = sme_ser_cmd_callback;
6874 	cmd->is_high_priority = high_priority;
6875 	cmd->is_blocking = true;
6876 
6877 	return QDF_STATUS_SUCCESS;
6878 }
6879 
6880 QDF_STATUS csr_queue_sme_command(struct mac_context *mac_ctx, tSmeCmd *sme_cmd,
6881 				 bool high_priority)
6882 {
6883 	struct wlan_serialization_command cmd;
6884 	struct wlan_objmgr_vdev *vdev = NULL;
6885 	enum wlan_serialization_status ser_cmd_status;
6886 	QDF_STATUS status;
6887 
6888 	if (!SME_IS_START(mac_ctx)) {
6889 		sme_err("Sme in stop state");
6890 		QDF_ASSERT(0);
6891 		goto error;
6892 	}
6893 
6894 	qdf_mem_zero(&cmd, sizeof(struct wlan_serialization_command));
6895 	status = csr_set_serialization_params_to_cmd(mac_ctx, sme_cmd,
6896 					&cmd, high_priority);
6897 	if (QDF_IS_STATUS_ERROR(status)) {
6898 		sme_err("failed to set ser params");
6899 		goto error;
6900 	}
6901 
6902 	vdev = cmd.vdev;
6903 	ser_cmd_status = wlan_serialization_request(&cmd);
6904 
6905 	switch (ser_cmd_status) {
6906 	case WLAN_SER_CMD_PENDING:
6907 	case WLAN_SER_CMD_ACTIVE:
6908 		/* Command posted to active/pending list */
6909 		status = QDF_STATUS_SUCCESS;
6910 		break;
6911 	default:
6912 		sme_err("Failed to queue command %d with status:%d",
6913 			  sme_cmd->command, ser_cmd_status);
6914 		status = QDF_STATUS_E_FAILURE;
6915 		goto error;
6916 	}
6917 
6918 	return status;
6919 
6920 error:
6921 	if (vdev)
6922 		wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID);
6923 
6924 	csr_release_command_buffer(mac_ctx, sme_cmd);
6925 
6926 	return QDF_STATUS_E_FAILURE;
6927 }
6928 
6929 QDF_STATUS csr_roam_update_config(struct mac_context *mac_ctx, uint8_t session_id,
6930 				  uint16_t capab, uint32_t value)
6931 {
6932 	struct update_config *msg;
6933 	QDF_STATUS status = QDF_STATUS_SUCCESS;
6934 	struct csr_roam_session *session = CSR_GET_SESSION(mac_ctx, session_id);
6935 
6936 	sme_debug("update HT config requested");
6937 	if (!session) {
6938 		sme_err("Session does not exist for session id %d", session_id);
6939 		return QDF_STATUS_E_FAILURE;
6940 	}
6941 
6942 	msg = qdf_mem_malloc(sizeof(*msg));
6943 	if (!msg)
6944 		return QDF_STATUS_E_NOMEM;
6945 
6946 	msg->messageType = eWNI_SME_UPDATE_CONFIG;
6947 	msg->vdev_id = session_id;
6948 	msg->capab = capab;
6949 	msg->value = value;
6950 	msg->length = sizeof(*msg);
6951 	status = umac_send_mb_message_to_mac(msg);
6952 
6953 	return status;
6954 }
6955 
6956 QDF_STATUS csr_send_channel_change_req(struct mac_context *mac,
6957 				      struct channel_change_req *req)
6958 {
6959 	struct scheduler_msg msg = {0};
6960 	struct channel_change_req *ch_change_req;
6961 	QDF_STATUS status;
6962 
6963 	ch_change_req = qdf_mem_malloc(sizeof(*ch_change_req));
6964 	if (!ch_change_req)
6965 		return QDF_STATUS_E_NOMEM;
6966 
6967 	qdf_mem_copy(ch_change_req, req, sizeof(*ch_change_req));
6968 	msg.type = eWNI_SME_CHANNEL_CHANGE_REQ;
6969 	msg.bodyptr = ch_change_req;
6970 	msg.reserved = 0;
6971 
6972 	status = scheduler_post_message(QDF_MODULE_ID_SME,
6973 					QDF_MODULE_ID_PE,
6974 					QDF_MODULE_ID_PE,
6975 					&msg);
6976 	if (QDF_IS_STATUS_ERROR(status)) {
6977 		sme_err("Failed to send channel change request with status : %d",
6978 			status);
6979 		qdf_mem_free(ch_change_req);
6980 	}
6981 
6982 	return status;
6983 }
6984 /*
6985  * Post Beacon Tx Start request to LIM
6986  * immediately after SAP CAC WAIT is
6987  * completed without any RADAR indications.
6988  */
6989 QDF_STATUS csr_roam_start_beacon_req(struct mac_context *mac,
6990 				     struct qdf_mac_addr bssid,
6991 				     uint8_t dfsCacWaitStatus)
6992 {
6993 	QDF_STATUS status = QDF_STATUS_SUCCESS;
6994 	tSirStartBeaconIndication *pMsg;
6995 
6996 	pMsg = qdf_mem_malloc(sizeof(tSirStartBeaconIndication));
6997 	if (!pMsg)
6998 		return QDF_STATUS_E_NOMEM;
6999 
7000 	pMsg->messageType = eWNI_SME_START_BEACON_REQ;
7001 	pMsg->messageLen = sizeof(tSirStartBeaconIndication);
7002 	pMsg->beaconStartStatus = dfsCacWaitStatus;
7003 	qdf_mem_copy(pMsg->bssid, bssid.bytes, QDF_MAC_ADDR_SIZE);
7004 
7005 	status = umac_send_mb_message_to_mac(pMsg);
7006 
7007 	return status;
7008 }
7009 
7010 /*
7011  * csr_roam_modify_add_ies -
7012  * This function sends msg to modify the additional IE buffers in PE
7013  *
7014  * @mac: mac global structure
7015  * @pModifyIE: pointer to tSirModifyIE structure
7016  * @updateType: Type of buffer
7017  *
7018  *
7019  * Return: QDF_STATUS -  Success or failure
7020  */
7021 QDF_STATUS
7022 csr_roam_modify_add_ies(struct mac_context *mac,
7023 			 tSirModifyIE *pModifyIE, eUpdateIEsType updateType)
7024 {
7025 	tpSirModifyIEsInd pModifyAddIEInd = NULL;
7026 	uint8_t *pLocalBuffer = NULL;
7027 	QDF_STATUS status;
7028 
7029 	/* following buffer will be freed by consumer (PE) */
7030 	pLocalBuffer = qdf_mem_malloc(pModifyIE->ieBufferlength);
7031 	if (!pLocalBuffer)
7032 		return QDF_STATUS_E_NOMEM;
7033 
7034 	pModifyAddIEInd = qdf_mem_malloc(sizeof(tSirModifyIEsInd));
7035 	if (!pModifyAddIEInd) {
7036 		qdf_mem_free(pLocalBuffer);
7037 		return QDF_STATUS_E_NOMEM;
7038 	}
7039 
7040 	/*copy the IE buffer */
7041 	qdf_mem_copy(pLocalBuffer, pModifyIE->pIEBuffer,
7042 		     pModifyIE->ieBufferlength);
7043 	qdf_mem_zero(pModifyAddIEInd, sizeof(tSirModifyIEsInd));
7044 
7045 	pModifyAddIEInd->msgType = eWNI_SME_MODIFY_ADDITIONAL_IES;
7046 	pModifyAddIEInd->msgLen = sizeof(tSirModifyIEsInd);
7047 
7048 	qdf_copy_macaddr(&pModifyAddIEInd->modifyIE.bssid, &pModifyIE->bssid);
7049 
7050 	pModifyAddIEInd->modifyIE.vdev_id = pModifyIE->vdev_id;
7051 	pModifyAddIEInd->modifyIE.notify = pModifyIE->notify;
7052 	pModifyAddIEInd->modifyIE.ieID = pModifyIE->ieID;
7053 	pModifyAddIEInd->modifyIE.ieIDLen = pModifyIE->ieIDLen;
7054 	pModifyAddIEInd->modifyIE.pIEBuffer = pLocalBuffer;
7055 	pModifyAddIEInd->modifyIE.ieBufferlength = pModifyIE->ieBufferlength;
7056 	pModifyAddIEInd->modifyIE.oui_length = pModifyIE->oui_length;
7057 
7058 	pModifyAddIEInd->updateType = updateType;
7059 
7060 	status = umac_send_mb_message_to_mac(pModifyAddIEInd);
7061 	if (!QDF_IS_STATUS_SUCCESS(status)) {
7062 		sme_err("Failed to send eWNI_SME_UPDATE_ADDTIONAL_IES msg status %d",
7063 			status);
7064 		qdf_mem_free(pLocalBuffer);
7065 	}
7066 	return status;
7067 }
7068 
7069 /*
7070  * csr_roam_update_add_ies -
7071  * This function sends msg to updates the additional IE buffers in PE
7072  *
7073  * @mac: mac global structure
7074  * @sessionId: SME session id
7075  * @bssid: BSSID
7076  * @additionIEBuffer: buffer containing addition IE from hostapd
7077  * @length: length of buffer
7078  * @updateType: Type of buffer
7079  * @append: append or replace completely
7080  *
7081  *
7082  * Return: QDF_STATUS -  Success or failure
7083  */
7084 QDF_STATUS
7085 csr_roam_update_add_ies(struct mac_context *mac,
7086 			 tSirUpdateIE *pUpdateIE, eUpdateIEsType updateType)
7087 {
7088 	tpSirUpdateIEsInd pUpdateAddIEs = NULL;
7089 	uint8_t *pLocalBuffer = NULL;
7090 	QDF_STATUS status;
7091 
7092 	if (pUpdateIE->ieBufferlength != 0) {
7093 		/* Following buffer will be freed by consumer (PE) */
7094 		pLocalBuffer = qdf_mem_malloc(pUpdateIE->ieBufferlength);
7095 		if (!pLocalBuffer) {
7096 			return QDF_STATUS_E_NOMEM;
7097 		}
7098 		qdf_mem_copy(pLocalBuffer, pUpdateIE->pAdditionIEBuffer,
7099 			     pUpdateIE->ieBufferlength);
7100 	}
7101 
7102 	pUpdateAddIEs = qdf_mem_malloc(sizeof(tSirUpdateIEsInd));
7103 	if (!pUpdateAddIEs) {
7104 		qdf_mem_free(pLocalBuffer);
7105 		return QDF_STATUS_E_NOMEM;
7106 	}
7107 
7108 	pUpdateAddIEs->msgType = eWNI_SME_UPDATE_ADDITIONAL_IES;
7109 	pUpdateAddIEs->msgLen = sizeof(tSirUpdateIEsInd);
7110 
7111 	qdf_copy_macaddr(&pUpdateAddIEs->updateIE.bssid, &pUpdateIE->bssid);
7112 
7113 	pUpdateAddIEs->updateIE.vdev_id = pUpdateIE->vdev_id;
7114 	pUpdateAddIEs->updateIE.append = pUpdateIE->append;
7115 	pUpdateAddIEs->updateIE.notify = pUpdateIE->notify;
7116 	pUpdateAddIEs->updateIE.ieBufferlength = pUpdateIE->ieBufferlength;
7117 	pUpdateAddIEs->updateIE.pAdditionIEBuffer = pLocalBuffer;
7118 
7119 	pUpdateAddIEs->updateType = updateType;
7120 
7121 	status = umac_send_mb_message_to_mac(pUpdateAddIEs);
7122 	if (!QDF_IS_STATUS_SUCCESS(status)) {
7123 		sme_err("Failed to send eWNI_SME_UPDATE_ADDTIONAL_IES msg status %d",
7124 			status);
7125 		qdf_mem_free(pLocalBuffer);
7126 	}
7127 	return status;
7128 }
7129 
7130 /**
7131  * csr_send_ext_change_freq()- function to post send ECSA
7132  * action frame to lim.
7133  * @mac_ctx: pointer to global mac structure
7134  * @ch_freq: new channel freq to switch
7135  * @session_id: senssion it should be sent on.
7136  *
7137  * This function is called to post ECSA frame to lim.
7138  *
7139  * Return: success if msg posted to LIM else return failure
7140  */
7141 QDF_STATUS csr_send_ext_change_freq(struct mac_context *mac_ctx,
7142 				    qdf_freq_t ch_freq, uint8_t session_id)
7143 {
7144 	QDF_STATUS status = QDF_STATUS_SUCCESS;
7145 	struct sir_sme_ext_cng_chan_req *msg;
7146 
7147 	msg = qdf_mem_malloc(sizeof(*msg));
7148 	if (!msg)
7149 		return QDF_STATUS_E_NOMEM;
7150 
7151 	msg->message_type = eWNI_SME_EXT_CHANGE_CHANNEL;
7152 	msg->length = sizeof(*msg);
7153 	msg->new_ch_freq = ch_freq;
7154 	msg->vdev_id = session_id;
7155 	status = umac_send_mb_message_to_mac(msg);
7156 	return status;
7157 }
7158 
7159 QDF_STATUS csr_csa_restart(struct mac_context *mac_ctx, uint8_t vdev_id)
7160 {
7161 	QDF_STATUS status;
7162 	struct wlan_objmgr_vdev *vdev;
7163 	struct scheduler_msg message = {0};
7164 
7165 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac_ctx->psoc, vdev_id,
7166 						    WLAN_LEGACY_MAC_ID);
7167 	if (!vdev) {
7168 		sme_err("VDEV not found for vdev id: %d", vdev_id);
7169 		return QDF_STATUS_E_FAILURE;
7170 	}
7171 
7172 	if_mgr_deliver_event(vdev, WLAN_IF_MGR_EV_AP_CSA_START, NULL);
7173 	wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_MAC_ID);
7174 
7175 	/* Serialize the req through MC thread */
7176 	message.bodyval = vdev_id;
7177 	message.type    = eWNI_SME_CSA_RESTART_REQ;
7178 	status = scheduler_post_message(QDF_MODULE_ID_SME, QDF_MODULE_ID_PE,
7179 					QDF_MODULE_ID_PE, &message);
7180 	if (!QDF_IS_STATUS_SUCCESS(status)) {
7181 		sme_err("scheduler_post_msg failed!(err=%d)", status);
7182 		status = QDF_STATUS_E_FAILURE;
7183 	}
7184 
7185 	return status;
7186 }
7187 
7188 QDF_STATUS csr_roam_send_chan_sw_ie_request(struct mac_context *mac_ctx,
7189 					    struct qdf_mac_addr bssid,
7190 					    uint32_t target_chan_freq,
7191 					    uint8_t csa_ie_reqd,
7192 					    struct ch_params *ch_params,
7193 					    uint32_t new_cac_ms)
7194 {
7195 	QDF_STATUS status = QDF_STATUS_SUCCESS;
7196 	tSirDfsCsaIeRequest *msg;
7197 
7198 	msg = qdf_mem_malloc(sizeof(tSirDfsCsaIeRequest));
7199 	if (!msg)
7200 		return QDF_STATUS_E_NOMEM;
7201 
7202 	msg->msgType = eWNI_SME_DFS_BEACON_CHAN_SW_IE_REQ;
7203 	msg->msgLen = sizeof(tSirDfsCsaIeRequest);
7204 
7205 	msg->target_chan_freq = target_chan_freq;
7206 	msg->csaIeRequired = csa_ie_reqd;
7207 	msg->ch_switch_beacon_cnt =
7208 		 mac_ctx->sap.SapDfsInfo.sap_ch_switch_beacon_cnt;
7209 	if (mac_ctx->sap.one_time_csa_count) {
7210 		msg->ch_switch_beacon_cnt = mac_ctx->sap.one_time_csa_count;
7211 		mac_ctx->sap.one_time_csa_count = 0;
7212 	}
7213 	msg->ch_switch_mode = mac_ctx->sap.SapDfsInfo.sap_ch_switch_mode;
7214 	msg->dfs_ch_switch_disable =
7215 		mac_ctx->sap.SapDfsInfo.disable_dfs_ch_switch;
7216 	msg->new_chan_cac_ms = new_cac_ms;
7217 	qdf_mem_copy(msg->bssid, bssid.bytes, QDF_MAC_ADDR_SIZE);
7218 	qdf_mem_copy(&msg->ch_params, ch_params, sizeof(struct ch_params));
7219 
7220 	status = umac_send_mb_message_to_mac(msg);
7221 
7222 	return status;
7223 }
7224 
7225 QDF_STATUS csr_sta_continue_csa(struct mac_context *mac_ctx, uint8_t vdev_id)
7226 {
7227 	QDF_STATUS status;
7228 	struct scheduler_msg message = {0};
7229 
7230 	/* Serialize the req through MC thread */
7231 	message.bodyval = vdev_id;
7232 	message.type    = eWNI_SME_STA_CSA_CONTINUE_REQ;
7233 	status = scheduler_post_message(QDF_MODULE_ID_SME, QDF_MODULE_ID_PE,
7234 					QDF_MODULE_ID_PE, &message);
7235 	if (!QDF_IS_STATUS_SUCCESS(status)) {
7236 		sme_err("eWNI_SME_STA_CSA_CONTINUE_REQ failed!(err=%d)",
7237 			status);
7238 		status = QDF_STATUS_E_FAILURE;
7239 	}
7240 
7241 	return status;
7242 }
7243 
7244 /**
7245  * csr_update_op_class_array() - update op class for each band
7246  * @mac_ctx:          mac global context
7247  * @op_classes:       out param, operating class array to update
7248  * @channel_info:     channel info
7249  * @ch_name:          channel band name to display in debug messages
7250  * @i:                out param, stores number of operating classes
7251  *
7252  * Return: void
7253  */
7254 static void
7255 csr_update_op_class_array(struct mac_context *mac_ctx,
7256 			  uint8_t *op_classes,
7257 			  struct csr_channel *channel_info,
7258 			  char *ch_name,
7259 			  uint8_t *i)
7260 {
7261 	uint8_t j = 0, idx = 0, class = 0;
7262 	bool found = false;
7263 	uint8_t num_channels = channel_info->numChannels;
7264 	uint8_t ch_num;
7265 
7266 	sme_debug("Num %s channels,  %d", ch_name, num_channels);
7267 
7268 	for (idx = 0; idx < num_channels &&
7269 		*i < (REG_MAX_SUPP_OPER_CLASSES - 1); idx++) {
7270 		wlan_reg_freq_to_chan_op_class(
7271 			mac_ctx->pdev, channel_info->channel_freq_list[idx],
7272 			true, BIT(BEHAV_NONE), &class, &ch_num);
7273 
7274 		found = false;
7275 		for (j = 0; j < REG_MAX_SUPP_OPER_CLASSES - 1; j++) {
7276 			if (op_classes[j] == class) {
7277 				found = true;
7278 				break;
7279 			}
7280 		}
7281 
7282 		if (!found) {
7283 			op_classes[*i] = class;
7284 			*i = *i + 1;
7285 		}
7286 	}
7287 }
7288 
7289 /**
7290  * csr_init_operating_classes() - update op class for all bands
7291  * @mac: pointer to mac context.
7292  *
7293  * Return: void
7294  */
7295 static void csr_init_operating_classes(struct mac_context *mac)
7296 {
7297 	uint8_t i = 0;
7298 	uint8_t j = 0;
7299 	uint8_t swap = 0;
7300 	uint8_t numClasses = 0;
7301 	uint8_t opClasses[REG_MAX_SUPP_OPER_CLASSES] = {0,};
7302 	uint8_t reg_cc[REG_ALPHA2_LEN + 1];
7303 
7304 	wlan_reg_read_current_country(mac->psoc, reg_cc);
7305 	sme_debug("Current Country = %s", reg_cc);
7306 
7307 	csr_update_op_class_array(mac, opClasses,
7308 				  &mac->scan.base_channels, "20MHz", &i);
7309 	numClasses = i;
7310 
7311 	/* As per spec the operating classes should be in ascending order.
7312 	 * Bubble sort is fine since we don't have many classes
7313 	 */
7314 	for (i = 0; i < (numClasses - 1); i++) {
7315 		for (j = 0; j < (numClasses - i - 1); j++) {
7316 			/* For decreasing order use < */
7317 			if (opClasses[j] > opClasses[j + 1]) {
7318 				swap = opClasses[j];
7319 				opClasses[j] = opClasses[j + 1];
7320 				opClasses[j + 1] = swap;
7321 			}
7322 		}
7323 	}
7324 
7325 	/* Set the ordered list of op classes in regdomain
7326 	 * for use by other modules
7327 	 */
7328 	wlan_reg_dmn_set_curr_opclasses(numClasses, &opClasses[0]);
7329 }
7330 
7331 /**
7332  * csr_process_set_hw_mode() - Set HW mode command to PE
7333  * @mac: Globacl MAC pointer
7334  * @command: Command received from SME
7335  *
7336  * Posts the set HW mode command to PE. This message passing
7337  * through PE is required for PE's internal management
7338  *
7339  * Return: None
7340  */
7341 void csr_process_set_hw_mode(struct mac_context *mac, tSmeCmd *command)
7342 {
7343 	uint32_t len;
7344 	struct s_sir_set_hw_mode *cmd = NULL;
7345 	QDF_STATUS status;
7346 	struct scheduler_msg msg = {0};
7347 	struct sir_set_hw_mode_resp *param;
7348 	enum policy_mgr_hw_mode_change hw_mode;
7349 	enum policy_mgr_conc_next_action action;
7350 	enum set_hw_mode_status hw_mode_change_status =
7351 						SET_HW_MODE_STATUS_ECANCELED;
7352 
7353 	/* Setting HW mode is for the entire system.
7354 	 * So, no need to check session
7355 	 */
7356 
7357 	if (!command) {
7358 		sme_err("Set HW mode param is NULL");
7359 		goto fail;
7360 	}
7361 
7362 	len = sizeof(*cmd);
7363 	cmd = qdf_mem_malloc(len);
7364 	if (!cmd)
7365 		/* Probably the fail response will also fail during malloc.
7366 		 * Still proceeding to send response!
7367 		 */
7368 		goto fail;
7369 
7370 	action = command->u.set_hw_mode_cmd.action;
7371 
7372 	status = policy_mgr_validate_dbs_switch(mac->psoc, action);
7373 
7374 	if (QDF_IS_STATUS_ERROR(status)) {
7375 		sme_debug("Hw mode change not sent to FW status = %d", status);
7376 		if (status == QDF_STATUS_E_ALREADY)
7377 			hw_mode_change_status = SET_HW_MODE_STATUS_ALREADY;
7378 		goto fail;
7379 	}
7380 
7381 	hw_mode = policy_mgr_get_hw_mode_change_from_hw_mode_index(
7382 			mac->psoc, command->u.set_hw_mode_cmd.hw_mode_index);
7383 
7384 	if (POLICY_MGR_HW_MODE_NOT_IN_PROGRESS == hw_mode) {
7385 		sme_err("hw_mode %d, failing", hw_mode);
7386 		goto fail;
7387 	}
7388 
7389 	policy_mgr_set_hw_mode_change_in_progress(mac->psoc, hw_mode);
7390 	policy_mgr_reset_connection_update(mac->psoc);
7391 
7392 	if ((POLICY_MGR_UPDATE_REASON_OPPORTUNISTIC ==
7393 	     command->u.set_hw_mode_cmd.reason) &&
7394 	    (true == mac->sme.get_connection_info_cb(NULL, NULL))) {
7395 		sme_err("Set HW mode refused: conn in progress");
7396 		policy_mgr_restart_opportunistic_timer(mac->psoc, false);
7397 		goto reset_state;
7398 	}
7399 
7400 	if ((POLICY_MGR_UPDATE_REASON_OPPORTUNISTIC ==
7401 	     command->u.set_hw_mode_cmd.reason) &&
7402 	    (!command->u.set_hw_mode_cmd.hw_mode_index &&
7403 	     !policy_mgr_need_opportunistic_upgrade(mac->psoc, NULL))) {
7404 		sme_err("Set HW mode to SMM not needed anymore");
7405 		goto reset_state;
7406 	}
7407 
7408 	cmd->messageType = eWNI_SME_SET_HW_MODE_REQ;
7409 	cmd->length = len;
7410 	cmd->set_hw.hw_mode_index = command->u.set_hw_mode_cmd.hw_mode_index;
7411 	cmd->set_hw.reason = command->u.set_hw_mode_cmd.reason;
7412 	/*
7413 	 * Below callback and context info are not needed for PE as of now.
7414 	 * Storing the passed value in the same s_sir_set_hw_mode format.
7415 	 */
7416 	cmd->set_hw.set_hw_mode_cb = command->u.set_hw_mode_cmd.set_hw_mode_cb;
7417 
7418 	sme_debug(
7419 		"Posting set hw mode req to PE session:%d reason:%d",
7420 		command->u.set_hw_mode_cmd.session_id,
7421 		command->u.set_hw_mode_cmd.reason);
7422 
7423 	status = umac_send_mb_message_to_mac(cmd);
7424 	if (QDF_STATUS_SUCCESS != status) {
7425 		sme_err("Posting to PE failed");
7426 		cmd = NULL;
7427 		goto reset_state;
7428 	}
7429 	return;
7430 
7431 reset_state:
7432 	policy_mgr_set_hw_mode_change_in_progress(mac->psoc,
7433 			POLICY_MGR_HW_MODE_NOT_IN_PROGRESS);
7434 fail:
7435 	if (cmd)
7436 		qdf_mem_free(cmd);
7437 	param = qdf_mem_malloc(sizeof(*param));
7438 	if (!param)
7439 		return;
7440 
7441 	sme_debug("Sending set HW fail response to SME");
7442 	param->status = hw_mode_change_status;
7443 	param->cfgd_hw_mode_index = 0;
7444 	param->num_vdev_mac_entries = 0;
7445 	msg.type = eWNI_SME_SET_HW_MODE_RESP;
7446 	msg.bodyptr = param;
7447 	msg.bodyval = 0;
7448 	sys_process_mmh_msg(mac, &msg);
7449 }
7450 
7451 /**
7452  * csr_process_set_dual_mac_config() - Set HW mode command to PE
7453  * @mac: Global MAC pointer
7454  * @command: Command received from SME
7455  *
7456  * Posts the set dual mac config command to PE.
7457  *
7458  * Return: None
7459  */
7460 void csr_process_set_dual_mac_config(struct mac_context *mac, tSmeCmd *command)
7461 {
7462 	uint32_t len;
7463 	struct sir_set_dual_mac_cfg *cmd;
7464 	QDF_STATUS status;
7465 	struct scheduler_msg msg = {0};
7466 	struct sir_dual_mac_config_resp *param;
7467 
7468 	/* Setting MAC configuration is for the entire system.
7469 	 * So, no need to check session
7470 	 */
7471 
7472 	if (!command) {
7473 		sme_err("Set HW mode param is NULL");
7474 		goto fail;
7475 	}
7476 
7477 	len = sizeof(*cmd);
7478 	cmd = qdf_mem_malloc(len);
7479 	if (!cmd)
7480 		/* Probably the fail response will also fail during malloc.
7481 		 * Still proceeding to send response!
7482 		 */
7483 		goto fail;
7484 
7485 	cmd->message_type = eWNI_SME_SET_DUAL_MAC_CFG_REQ;
7486 	cmd->length = len;
7487 	cmd->set_dual_mac.scan_config = command->u.set_dual_mac_cmd.scan_config;
7488 	cmd->set_dual_mac.fw_mode_config =
7489 		command->u.set_dual_mac_cmd.fw_mode_config;
7490 	/*
7491 	 * Below callback and context info are not needed for PE as of now.
7492 	 * Storing the passed value in the same sir_set_dual_mac_cfg format.
7493 	 */
7494 	cmd->set_dual_mac.set_dual_mac_cb =
7495 		command->u.set_dual_mac_cmd.set_dual_mac_cb;
7496 
7497 	sme_debug("Posting eWNI_SME_SET_DUAL_MAC_CFG_REQ to PE: %x %x",
7498 		  cmd->set_dual_mac.scan_config,
7499 		  cmd->set_dual_mac.fw_mode_config);
7500 
7501 	status = umac_send_mb_message_to_mac(cmd);
7502 	if (QDF_IS_STATUS_ERROR(status)) {
7503 		sme_err("Posting to PE failed");
7504 		goto fail;
7505 	}
7506 	return;
7507 fail:
7508 	param = qdf_mem_malloc(sizeof(*param));
7509 	if (!param)
7510 		return;
7511 
7512 	sme_err("Sending set dual mac fail response to SME");
7513 	param->status = SET_HW_MODE_STATUS_ECANCELED;
7514 	msg.type = eWNI_SME_SET_DUAL_MAC_CFG_RESP;
7515 	msg.bodyptr = param;
7516 	msg.bodyval = 0;
7517 	sys_process_mmh_msg(mac, &msg);
7518 }
7519 
7520 /**
7521  * csr_process_set_antenna_mode() - Set antenna mode command to
7522  * PE
7523  * @mac: Global MAC pointer
7524  * @command: Command received from SME
7525  *
7526  * Posts the set dual mac config command to PE.
7527  *
7528  * Return: None
7529  */
7530 void csr_process_set_antenna_mode(struct mac_context *mac, tSmeCmd *command)
7531 {
7532 	uint32_t len;
7533 	struct sir_set_antenna_mode *cmd;
7534 	QDF_STATUS status;
7535 	struct scheduler_msg msg = {0};
7536 	struct sir_antenna_mode_resp *param;
7537 
7538 	/* Setting MAC configuration is for the entire system.
7539 	 * So, no need to check session
7540 	 */
7541 
7542 	if (!command) {
7543 		sme_err("Set antenna mode param is NULL");
7544 		goto fail;
7545 	}
7546 
7547 	len = sizeof(*cmd);
7548 	cmd = qdf_mem_malloc(len);
7549 	if (!cmd)
7550 		goto fail;
7551 
7552 	cmd->message_type = eWNI_SME_SET_ANTENNA_MODE_REQ;
7553 	cmd->length = len;
7554 	cmd->set_antenna_mode = command->u.set_antenna_mode_cmd;
7555 
7556 	sme_debug(
7557 		"Posting eWNI_SME_SET_ANTENNA_MODE_REQ to PE: %d %d",
7558 		cmd->set_antenna_mode.num_rx_chains,
7559 		cmd->set_antenna_mode.num_tx_chains);
7560 
7561 	status = umac_send_mb_message_to_mac(cmd);
7562 	if (QDF_STATUS_SUCCESS != status) {
7563 		sme_err("Posting to PE failed");
7564 		/*
7565 		 * umac_send_mb_message_to_mac would've released the mem
7566 		 * allocated by cmd.
7567 		 */
7568 		goto fail;
7569 	}
7570 
7571 	return;
7572 fail:
7573 	param = qdf_mem_malloc(sizeof(*param));
7574 	if (!param)
7575 		return;
7576 
7577 	sme_err("Sending set dual mac fail response to SME");
7578 	param->status = SET_ANTENNA_MODE_STATUS_ECANCELED;
7579 	msg.type = eWNI_SME_SET_ANTENNA_MODE_RESP;
7580 	msg.bodyptr = param;
7581 	msg.bodyval = 0;
7582 	sys_process_mmh_msg(mac, &msg);
7583 }
7584 
7585 /**
7586  * csr_process_nss_update_req() - Update nss command to PE
7587  * @mac: Globacl MAC pointer
7588  * @command: Command received from SME
7589  *
7590  * Posts the nss update command to PE. This message passing
7591  * through PE is required for PE's internal management
7592  *
7593  * Return: None
7594  */
7595 void csr_process_nss_update_req(struct mac_context *mac, tSmeCmd *command)
7596 {
7597 	uint32_t len;
7598 	struct sir_nss_update_request *msg;
7599 	QDF_STATUS status;
7600 	struct scheduler_msg msg_return = {0};
7601 	struct sir_bcn_update_rsp *param;
7602 	struct csr_roam_session *session;
7603 
7604 
7605 	if (!CSR_IS_SESSION_VALID(mac, command->vdev_id)) {
7606 		sme_err("Invalid session id %d", command->vdev_id);
7607 		goto fail;
7608 	}
7609 	session = CSR_GET_SESSION(mac, command->vdev_id);
7610 
7611 	len = sizeof(*msg);
7612 	msg = qdf_mem_malloc(len);
7613 	if (!msg)
7614 		/* Probably the fail response is also fail during malloc.
7615 		 * Still proceeding to send response!
7616 		 */
7617 		goto fail;
7618 
7619 	msg->msgType = eWNI_SME_NSS_UPDATE_REQ;
7620 	msg->msgLen = sizeof(*msg);
7621 
7622 	msg->new_nss = command->u.nss_update_cmd.new_nss;
7623 	msg->ch_width = command->u.nss_update_cmd.ch_width;
7624 	msg->vdev_id = command->u.nss_update_cmd.session_id;
7625 
7626 	sme_debug("Posting eWNI_SME_NSS_UPDATE_REQ to PE");
7627 
7628 	status = umac_send_mb_message_to_mac(msg);
7629 	if (QDF_IS_STATUS_SUCCESS(status))
7630 		return;
7631 
7632 	sme_err("Posting to PE failed");
7633 fail:
7634 	param = qdf_mem_malloc(sizeof(*param));
7635 	if (!param)
7636 		return;
7637 
7638 	sme_err("Sending nss update fail response to SME");
7639 	param->status = QDF_STATUS_E_FAILURE;
7640 	param->vdev_id = command->u.nss_update_cmd.session_id;
7641 	param->reason = REASON_NSS_UPDATE;
7642 	msg_return.type = eWNI_SME_NSS_UPDATE_RSP;
7643 	msg_return.bodyptr = param;
7644 	msg_return.bodyval = 0;
7645 	sys_process_mmh_msg(mac, &msg_return);
7646 }
7647 
7648 /**
7649  * csr_process_sap_ch_width_update() - Update ch_width command to PE
7650  * @mac: Globacl MAC pointer
7651  * @command: Command received from SME
7652  *
7653  * Posts the ch_width update command to PE. This message passing
7654  * through PE is required for PE's internal management
7655  *
7656  * Return: None
7657  */
7658 void csr_process_sap_ch_width_update(struct mac_context *mac, tSmeCmd *command)
7659 {
7660 	uint32_t len;
7661 	struct sir_sap_ch_width_update *msg;
7662 	QDF_STATUS status;
7663 	struct scheduler_msg msg_return = {0};
7664 	struct sir_bcn_update_rsp *param;
7665 	enum policy_mgr_conn_update_reason reason =
7666 				command->u.bw_update_cmd.reason;
7667 
7668 	if (!CSR_IS_SESSION_VALID(mac, command->vdev_id)) {
7669 		sme_err("Invalid session id %d", command->vdev_id);
7670 		goto fail;
7671 	}
7672 
7673 	if ((reason == POLICY_MGR_UPDATE_REASON_OPPORTUNISTIC) &&
7674 	    (mac->sme.get_connection_info_cb(NULL, NULL))) {
7675 		policy_mgr_restart_opportunistic_timer(mac->psoc, false);
7676 		sme_info("Vdev %d : Avoid set BW as conn in progress",
7677 			 command->vdev_id);
7678 		goto fail;
7679 	}
7680 
7681 	if ((reason == POLICY_MGR_UPDATE_REASON_OPPORTUNISTIC) &&
7682 	    (!policy_mgr_need_opportunistic_upgrade(mac->psoc, &reason))) {
7683 		sme_info("Vdev %d: BW update not needed anymore",
7684 			 command->vdev_id);
7685 		goto fail;
7686 	}
7687 
7688 	len = sizeof(*msg);
7689 	msg = qdf_mem_malloc(len);
7690 	if (!msg)
7691 		/* Probably the fail response is also fail during malloc.
7692 		 * Still proceeding to send response!
7693 		 */
7694 		goto fail;
7695 
7696 	msg->msgType = eWNI_SME_SAP_CH_WIDTH_UPDATE_REQ;
7697 	msg->msgLen = sizeof(*msg);
7698 
7699 	msg->ch_width = command->u.bw_update_cmd.ch_width;
7700 	msg->vdev_id = command->u.bw_update_cmd.vdev_id;
7701 
7702 	sme_debug("Posting eWNI_SME_SAP_CH_WIDTH_UPDATE_REQ to PE");
7703 
7704 	status = umac_send_mb_message_to_mac(msg);
7705 	if (QDF_IS_STATUS_SUCCESS(status))
7706 		return;
7707 
7708 	sme_err("Posting to PE failed");
7709 fail:
7710 	param = qdf_mem_malloc(sizeof(*param));
7711 	if (param) {
7712 		param->status = QDF_STATUS_E_FAILURE;
7713 		param->vdev_id = command->u.bw_update_cmd.vdev_id;
7714 		param->reason = REASON_CH_WIDTH_UPDATE;
7715 	}
7716 	msg_return.type = eWNI_SME_SAP_CH_WIDTH_UPDATE_RSP;
7717 	msg_return.bodyptr = param;
7718 	msg_return.bodyval = 0;
7719 	sys_process_mmh_msg(mac, &msg_return);
7720 }
7721 
7722 #ifdef WLAN_FEATURE_ROAM_OFFLOAD
7723 #ifdef WLAN_FEATURE_SAE
7724 /**
7725  * csr_process_roam_auth_sae_callback() - API to trigger the
7726  * WPA3 pre-auth event for candidate AP received from firmware.
7727  * @mac_ctx: Global mac context pointer
7728  * @vdev_id: vdev id
7729  * @roam_bssid: Candidate BSSID to roam
7730  * @akm: Candidate AKM
7731  *
7732  * This function calls the hdd_sme_roam_callback with reason
7733  * eCSR_ROAM_SAE_COMPUTE to trigger SAE auth to supplicant.
7734  */
7735 static QDF_STATUS
7736 csr_process_roam_auth_sae_callback(struct mac_context *mac_ctx,
7737 				   uint8_t vdev_id,
7738 				   struct qdf_mac_addr roam_bssid,
7739 				   uint32_t akm)
7740 {
7741 	struct csr_roam_info *roam_info;
7742 	struct sir_sae_info sae_info;
7743 	struct csr_roam_session *session = CSR_GET_SESSION(mac_ctx, vdev_id);
7744 
7745 	if (!session) {
7746 		sme_err("WPA3 Preauth event with invalid session id:%d",
7747 			vdev_id);
7748 		return QDF_STATUS_E_FAILURE;
7749 	}
7750 
7751 	roam_info = qdf_mem_malloc(sizeof(*roam_info));
7752 	if (!roam_info)
7753 		return QDF_STATUS_E_FAILURE;
7754 
7755 	sae_info.msg_len = sizeof(sae_info);
7756 	sae_info.vdev_id = vdev_id;
7757 	sae_info.akm = akm;
7758 	wlan_cm_get_roam_offload_ssid(mac_ctx->psoc, vdev_id,
7759 				      sae_info.ssid.ssId,
7760 				      &sae_info.ssid.length);
7761 	qdf_mem_copy(sae_info.peer_mac_addr.bytes,
7762 		     roam_bssid.bytes, QDF_MAC_ADDR_SIZE);
7763 
7764 	roam_info->sae_info = &sae_info;
7765 
7766 	csr_roam_call_callback(mac_ctx, vdev_id, roam_info,
7767 			       eCSR_ROAM_SAE_COMPUTE, eCSR_ROAM_RESULT_NONE);
7768 
7769 	qdf_mem_free(roam_info);
7770 
7771 	return QDF_STATUS_SUCCESS;
7772 }
7773 #else
7774 static inline QDF_STATUS
7775 csr_process_roam_auth_sae_callback(struct mac_context *mac_ctx,
7776 				   uint8_t vdev_id,
7777 				   struct qdf_mac_addr roam_bssid,
7778 				   uint32_t akm)
7779 {
7780 	return QDF_STATUS_E_NOSUPPORT;
7781 }
7782 #endif
7783 
7784 QDF_STATUS
7785 csr_roam_auth_offload_callback(struct mac_context *mac_ctx, uint8_t vdev_id,
7786 			       struct qdf_mac_addr bssid, uint32_t akm)
7787 {
7788 	QDF_STATUS status;
7789 
7790 	status = sme_acquire_global_lock(&mac_ctx->sme);
7791 	if (!QDF_IS_STATUS_SUCCESS(status))
7792 		return status;
7793 
7794 	status = csr_process_roam_auth_sae_callback(mac_ctx, vdev_id,
7795 						    bssid, akm);
7796 
7797 	sme_release_global_lock(&mac_ctx->sme);
7798 
7799 	return status;
7800 
7801 }
7802 #endif
7803 
7804 QDF_STATUS csr_update_owe_info(struct mac_context *mac,
7805 			       struct assoc_ind *assoc_ind)
7806 {
7807 	uint32_t session_id = WLAN_UMAC_VDEV_ID_MAX;
7808 	QDF_STATUS status;
7809 
7810 	status = csr_roam_get_session_id_from_bssid(mac,
7811 					(struct qdf_mac_addr *)assoc_ind->bssId,
7812 					&session_id);
7813 	if (!QDF_IS_STATUS_SUCCESS(status)) {
7814 		sme_debug("Couldn't find session_id for given BSSID");
7815 		return QDF_STATUS_E_FAILURE;
7816 	}
7817 
7818 	/* Send Association completion message to PE */
7819 	if (assoc_ind->owe_status)
7820 		status = QDF_STATUS_E_INVAL;
7821 	status = csr_send_assoc_cnf_msg(mac, assoc_ind, status,
7822 					assoc_ind->owe_status);
7823 	/*
7824 	 * send a message to CSR itself just to avoid the EAPOL frames
7825 	 * going OTA before association response
7826 	 */
7827 	if (assoc_ind->owe_status == 0)
7828 		status = csr_send_assoc_ind_to_upper_layer_cnf_msg(mac,
7829 								   assoc_ind,
7830 								   status,
7831 								   session_id);
7832 
7833 	return status;
7834 }
7835 
7836 QDF_STATUS csr_update_ft_info(struct mac_context *mac,
7837 			      struct assoc_ind *assoc_ind)
7838 {
7839 	QDF_STATUS status;
7840 
7841 	/* Send Association completion message to PE */
7842 	status = assoc_ind->ft_status ? QDF_STATUS_E_INVAL : QDF_STATUS_SUCCESS;
7843 	assoc_ind->need_assoc_rsp_tx_cb = true;
7844 	status = csr_send_assoc_cnf_msg(mac, assoc_ind, status,
7845 					assoc_ind->ft_status);
7846 	return status;
7847 }
7848 
7849 /**
7850  * csr_set_sap_ser_params() - API to fill serialization parameters for
7851  * SAP requests
7852  * @cmd : Serialization command
7853  * @cmd_type: Type of serialization command
7854  *
7855  * Return: Void
7856  */
7857 static void csr_set_sap_ser_params(struct wlan_serialization_command *cmd,
7858 				   enum wlan_serialization_cmd_type cmd_type)
7859 {
7860 	cmd->cmd_type = cmd_type;
7861 	cmd->source = WLAN_UMAC_COMP_MLME;
7862 	cmd->cmd_cb = sme_sap_ser_callback;
7863 	cmd->is_high_priority =  false;
7864 	cmd->is_blocking = true;
7865 	return;
7866 }
7867 
7868 QDF_STATUS csr_bss_start(struct mac_context *mac, uint32_t vdev_id,
7869 			 struct start_bss_config *bss_config)
7870 {
7871 	struct wlan_serialization_command cmd = {0};
7872 	struct wlan_objmgr_vdev *vdev;
7873 	struct start_bss_config *start_bss_cfg = NULL;
7874 	enum QDF_OPMODE persona;
7875 	enum wlan_serialization_status status;
7876 	struct csr_roam_session *session;
7877 	struct validate_bss_data candidate;
7878 
7879 	session = CSR_GET_SESSION(mac, vdev_id);
7880 	if (!session)
7881 		return QDF_STATUS_E_FAILURE;
7882 
7883 	vdev = wlan_objmgr_get_vdev_by_id_from_pdev(mac->pdev, vdev_id,
7884 						    WLAN_LEGACY_MAC_ID);
7885 	if (!vdev) {
7886 		sme_err("VDEV not found for vdev id : %d", vdev_id);
7887 		return QDF_STATUS_E_FAILURE;
7888 	}
7889 
7890 	persona = wlan_vdev_mlme_get_opmode(vdev);
7891 	if (persona != QDF_SAP_MODE && persona != QDF_NDI_MODE &&
7892 	    persona != QDF_P2P_GO_MODE) {
7893 		sme_err("Start BSS request for invalid mode %d", persona);
7894 		goto error;
7895 	}
7896 
7897 	start_bss_cfg = qdf_mem_malloc(sizeof(struct start_bss_config));
7898 	if (!start_bss_cfg) {
7899 		sme_err("SAP BSS config allocation failed");
7900 		goto error;
7901 	}
7902 
7903 	qdf_mem_copy(start_bss_cfg, bss_config,
7904 		     sizeof(struct start_bss_config));
7905 	start_bss_cfg->cmd_id = csr_get_monotonous_number(mac);
7906 
7907 	session->cb_mode = start_bss_cfg->sec_ch_offset;
7908 	session->bcn_int = bss_config->beaconInterval;
7909 	candidate.beacon_interval = session->bcn_int;
7910 	candidate.chan_freq = bss_config->oper_ch_freq;
7911 	if_mgr_is_beacon_interval_valid(mac->pdev, vdev_id,
7912 					&candidate);
7913 	bss_config->beaconInterval = candidate.beacon_interval;
7914 	session->bcn_int = candidate.beacon_interval;
7915 
7916 	cmd.cmd_id = start_bss_cfg->cmd_id;
7917 	csr_set_sap_ser_params(&cmd, WLAN_SER_CMD_VDEV_START_BSS);
7918 	cmd.umac_cmd = start_bss_cfg;
7919 	cmd.vdev = vdev;
7920 	csr_fill_cmd_timeout(&cmd);
7921 
7922 	status = wlan_vdev_mlme_ser_start_bss(&cmd);
7923 	switch (status) {
7924 	case WLAN_SER_CMD_PENDING:
7925 	case WLAN_SER_CMD_ACTIVE:
7926 		break;
7927 	default:
7928 		sme_err("ser cmd status %d", status);
7929 		goto error;
7930 	}
7931 
7932 	return QDF_STATUS_SUCCESS;
7933 error:
7934 	wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_MAC_ID);
7935 	if (start_bss_cfg)
7936 		qdf_mem_free(start_bss_cfg);
7937 
7938 	return QDF_STATUS_E_FAILURE;
7939 }
7940 
7941 QDF_STATUS csr_roam_issue_stop_bss_cmd(struct mac_context *mac,
7942 				       uint8_t vdev_id,
7943 				       eCsrRoamBssType bss_type)
7944 {
7945 	struct wlan_objmgr_vdev *vdev;
7946 	struct wlan_serialization_command cmd = {0};
7947 	enum wlan_serialization_status status;
7948 	struct stop_bss_req *stop_bss_req;
7949 
7950 	vdev = wlan_objmgr_get_vdev_by_id_from_pdev(mac->pdev, vdev_id,
7951 						    WLAN_LEGACY_MAC_ID);
7952 	if (!vdev) {
7953 		sme_err("VDEV not found for vdev id : %d", vdev_id);
7954 		return QDF_STATUS_E_FAILURE;
7955 	}
7956 
7957 	/* Change the substate in case it is wait-for-key */
7958 	if (CSR_IS_WAIT_FOR_KEY(mac, vdev_id)) {
7959 		cm_stop_wait_for_key_timer(mac->psoc, vdev_id);
7960 		csr_roam_substate_change(mac, eCSR_ROAM_SUBSTATE_NONE,
7961 					 vdev_id);
7962 	}
7963 
7964 	sme_debug("Stop BSS vdev_id: %d bss_type %d", vdev_id, bss_type);
7965 	stop_bss_req = qdf_mem_malloc(sizeof(*stop_bss_req));
7966 	if (!stop_bss_req)
7967 		goto error;
7968 
7969 	stop_bss_req->vdev_id = vdev_id;
7970 	stop_bss_req->cmd_id = csr_get_monotonous_number(mac);
7971 
7972 	cmd.cmd_id = stop_bss_req->cmd_id;
7973 	csr_set_sap_ser_params(&cmd, WLAN_SER_CMD_VDEV_STOP_BSS);
7974 	cmd.umac_cmd = stop_bss_req;
7975 	cmd.vdev = vdev;
7976 	csr_fill_cmd_timeout(&cmd);
7977 
7978 	status = wlan_vdev_mlme_ser_stop_bss(&cmd);
7979 	switch (status) {
7980 	case WLAN_SER_CMD_PENDING:
7981 	case WLAN_SER_CMD_ACTIVE:
7982 		break;
7983 	default:
7984 		sme_err("ser cmd status %d", status);
7985 		goto error;
7986 	}
7987 	return QDF_STATUS_SUCCESS;
7988 
7989 error:
7990 	wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_MAC_ID);
7991 	qdf_mem_free(stop_bss_req);
7992 	return QDF_STATUS_E_FAILURE;
7993 }
7994 
7995 static void csr_process_stop_bss_response(struct mac_context *mac_ctx,
7996 					  uint32_t vdev_id)
7997 {
7998 	struct csr_roam_session *session = CSR_GET_SESSION(mac_ctx, vdev_id);
7999 
8000 	if (CSR_IS_ROAM_SUBSTATE_STOP_BSS_REQ(mac_ctx, vdev_id)) {
8001 		csr_roam_free_connected_info(mac_ctx, &session->connectedInfo);
8002 		csr_set_default_dot11_mode(mac_ctx);
8003 	}
8004 
8005 	csr_roam_call_callback(mac_ctx, vdev_id, NULL, eCSR_ROAM_INFRA_IND,
8006 			       eCSR_ROAM_RESULT_INFRA_STOPPED);
8007 	return;
8008 }
8009 
8010 /**
8011  * csr_process_sap_results() - API to process the LIM response for
8012  * the messages posted by SAP module
8013  * @mac_ctx: mac context
8014  * @req: Serialization command posted by SAP
8015  * @rsp: Response from LIM
8016  * @result: Result from LIM
8017  * @vdev_id : vdev id
8018  *
8019  * Return: void
8020  */
8021 static bool csr_process_sap_results(struct mac_context *mac_ctx,
8022 				    void *rsp,
8023 				    enum csr_sap_response_type result,
8024 				    uint8_t vdev_id)
8025 {
8026 	struct csr_roam_info *roam_info;
8027 	struct csr_roam_session *session = CSR_GET_SESSION(mac_ctx, vdev_id);
8028 	eRoamCmdStatus roam_status = eCSR_ROAM_INFRA_IND;
8029 	eCsrRoamResult roam_result = eCSR_ROAM_RESULT_INFRA_START_FAILED;
8030 	enum QDF_OPMODE opmode;
8031 
8032 	if (!session) {
8033 		sme_err("session %d not found ", vdev_id);
8034 		return false;
8035 	}
8036 
8037 	roam_info = qdf_mem_malloc(sizeof(*roam_info));
8038 	if (!roam_info)
8039 		return false;
8040 
8041 	opmode = wlan_get_opmode_from_vdev_id(mac_ctx->pdev, vdev_id);
8042 	sme_debug("SAP result : %d", result);
8043 
8044 	switch (result) {
8045 	case CSR_SAP_START_BSS_SUCCESS:
8046 		csr_roam_process_start_bss_success(mac_ctx, roam_info,
8047 						   rsp, vdev_id);
8048 		break;
8049 	case CSR_SAP_START_BSS_FAILURE:
8050 		if (opmode == QDF_NDI_MODE) {
8051 			csr_roam_update_ndp_return_params(mac_ctx,
8052 							  CSR_SAP_START_BSS_FAILURE,
8053 							  &roam_status,
8054 							  &roam_result,
8055 							  roam_info);
8056 		}
8057 		csr_roam_call_callback(mac_ctx, vdev_id, roam_info,
8058 				       roam_status, roam_result);
8059 		csr_set_default_dot11_mode(mac_ctx);
8060 		break;
8061 	case CSR_SAP_STOP_BSS_SUCCESS:
8062 	case CSR_SAP_STOP_BSS_FAILURE:
8063 		if (opmode == QDF_NDI_MODE) {
8064 			qdf_mem_zero(roam_info, sizeof(*roam_info));
8065 			csr_roam_update_ndp_return_params(mac_ctx, result,
8066 							  &roam_status,
8067 							  &roam_result,
8068 							  roam_info);
8069 			csr_roam_call_callback(mac_ctx, vdev_id, roam_info,
8070 					       roam_status, roam_result);
8071 		} else {
8072 			csr_process_stop_bss_response(mac_ctx, vdev_id);
8073 		}
8074 		break;
8075 	default:
8076 		sme_err("Invalid response");
8077 		break;
8078 	}
8079 	qdf_mem_free(roam_info);
8080 	return true;
8081 }
8082 
8083 static enum wlan_serialization_cmd_type
8084 get_cmd_type_from_result(enum csr_sap_response_type result)
8085 {
8086 	switch (result) {
8087 	case CSR_SAP_START_BSS_SUCCESS:
8088 	case CSR_SAP_START_BSS_FAILURE:
8089 		return WLAN_SER_CMD_VDEV_START_BSS;
8090 	case CSR_SAP_STOP_BSS_SUCCESS:
8091 	case CSR_SAP_STOP_BSS_FAILURE:
8092 		return WLAN_SER_CMD_VDEV_STOP_BSS;
8093 	default:
8094 		return WLAN_SER_CMD_MAX;
8095 	}
8096 }
8097 
8098 static inline
8099 uint32_t get_cmd_id_from_cmd_type(void *cmd,
8100 				  enum wlan_serialization_cmd_type cmd_type)
8101 {
8102 	switch (cmd_type) {
8103 	case WLAN_SER_CMD_VDEV_START_BSS:
8104 		return ((struct start_bss_config *)cmd)->cmd_id;
8105 	case WLAN_SER_CMD_VDEV_STOP_BSS:
8106 		return ((struct stop_bss_req *)cmd)->cmd_id;
8107 	default:
8108 		sme_err("Invalid cmd_type %d to be dequeued", cmd_type);
8109 		return 0;
8110 	}
8111 }
8112 
8113 void csr_process_sap_response(struct mac_context *mac_ctx,
8114 			      enum csr_sap_response_type result,
8115 			      void *rsp, uint8_t vdev_id)
8116 {
8117 	struct wlan_objmgr_vdev *vdev;
8118 	void *req;
8119 	uint32_t cmd_id;
8120 	enum wlan_serialization_cmd_type cmd_type =
8121 				get_cmd_type_from_result(result);
8122 
8123 	if (cmd_type >= WLAN_SER_CMD_MAX) {
8124 		sme_err("Invalid command to be dequeued %d", cmd_type);
8125 		return;
8126 	}
8127 
8128 	req = wlan_serialization_get_active_cmd(mac_ctx->psoc,
8129 						vdev_id, cmd_type);
8130 	if (!req) {
8131 		sme_err("No active command for response from LIM for cmd: %d vdev: %d",
8132 			cmd_type, vdev_id);
8133 		csr_process_sap_results(mac_ctx, rsp, result, vdev_id);
8134 		return;
8135 	}
8136 
8137 	csr_process_sap_results(mac_ctx, rsp, result, vdev_id);
8138 
8139 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac_ctx->psoc, vdev_id,
8140 						    WLAN_LEGACY_MAC_ID);
8141 	if (!vdev) {
8142 		sme_err("vdev not found for vdev id: %d", vdev_id);
8143 		return;
8144 	}
8145 
8146 	cmd_id = get_cmd_id_from_cmd_type(req, cmd_type);
8147 	sme_debug("Dequeue cmd id : %d type : %d", cmd_id, cmd_type);
8148 
8149 	wlan_vdev_mlme_ser_remove_request(vdev, cmd_id, cmd_type);
8150 	wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_MAC_ID);
8151 }
8152 
8153 void csr_set_vdev_ies_per_band(mac_handle_t mac_handle, uint8_t vdev_id,
8154 			       enum QDF_OPMODE device_mode)
8155 {
8156 	struct sir_set_vdev_ies_per_band *p_msg;
8157 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
8158 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
8159 	enum csr_cfgdot11mode curr_dot11_mode =
8160 			mac_ctx->roam.configParam.uCfgDot11Mode;
8161 
8162 	p_msg = qdf_mem_malloc(sizeof(*p_msg));
8163 	if (!p_msg)
8164 		return;
8165 
8166 	p_msg->vdev_id = vdev_id;
8167 	p_msg->device_mode = device_mode;
8168 	p_msg->dot11_mode = csr_get_vdev_dot11_mode(mac_ctx, vdev_id,
8169 						    curr_dot11_mode);
8170 	p_msg->msg_type = eWNI_SME_SET_VDEV_IES_PER_BAND;
8171 	p_msg->len = sizeof(*p_msg);
8172 	sme_debug("SET_VDEV_IES_PER_BAND: vdev_id %d dot11mode %d dev_mode %d",
8173 		  vdev_id, p_msg->dot11_mode, device_mode);
8174 	status = umac_send_mb_message_to_mac(p_msg);
8175 	if (QDF_STATUS_SUCCESS != status)
8176 		sme_err("Send eWNI_SME_SET_VDEV_IES_PER_BAND fail");
8177 }
8178