xref: /wlan-driver/qcacld-3.0/core/sme/src/common/sme_api.c (revision 5113495b16420b49004c444715d2daae2066e7dc)
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: sme_api.c
22  *
23  * Definitions for SME APIs
24  */
25 
26 /* Include Files */
27 #include <sir_common.h>
28 #include <ani_global.h>
29 #include "sme_api.h"
30 #include "csr_inside_api.h"
31 #include "sme_inside.h"
32 #include "csr_internal.h"
33 #include "wma_types.h"
34 #include "wma_if.h"
35 #include "wma.h"
36 #include "wma_fips_api.h"
37 #include "wma_fw_state.h"
38 #include "qdf_trace.h"
39 #include "sme_trace.h"
40 #include "qdf_types.h"
41 #include "qdf_util.h"
42 #include "qdf_trace.h"
43 #include "cds_utils.h"
44 #include "sap_api.h"
45 #include "mac_trace.h"
46 #include "cds_regdomain.h"
47 #include "sme_power_save_api.h"
48 #include "wma.h"
49 #include "wma_twt.h"
50 #include "sch_api.h"
51 #include "sme_nan_datapath.h"
52 #include "csr_api.h"
53 #include "wlan_reg_services_api.h"
54 #include <wlan_scan_ucfg_api.h>
55 #include "wlan_reg_ucfg_api.h"
56 #include "ol_txrx.h"
57 #include "wifi_pos_api.h"
58 #include "net/cfg80211.h"
59 #include "wifi_pos_pasn_api.h"
60 #include <wlan_spectral_utils_api.h>
61 #include "wlan_mlme_public_struct.h"
62 #include "wlan_mlme_main.h"
63 #include "cfg_ucfg_api.h"
64 #include "wlan_fwol_ucfg_api.h"
65 #include <wlan_coex_ucfg_api.h>
66 #include "wlan_crypto_global_api.h"
67 #include "wlan_mlme_ucfg_api.h"
68 #include "wlan_psoc_mlme_api.h"
69 #include "mac_init_api.h"
70 #include "wlan_cm_roam_api.h"
71 #include "wlan_cm_tgt_if_tx_api.h"
72 #include "wlan_cm_api.h"
73 #include "wlan_mlme_twt_public_struct.h"
74 #include "wlan_mlme_twt_api.h"
75 #include "wlan_mlme_twt_ucfg_api.h"
76 #include "parser_api.h"
77 #include <../../core/src/wlan_cm_vdev_api.h>
78 #include <wlan_mlme_twt_api.h>
79 #include "wlan_cm_roam_ucfg_api.h"
80 #include <cm_utf.h>
81 #include <wlan_mlo_mgr_sta.h>
82 #include <wlan_mlo_mgr_main.h>
83 #include "wlan_policy_mgr_ucfg.h"
84 #include "wlan_wifi_pos_interface.h"
85 #include "wlan_cp_stats_mc_ucfg_api.h"
86 #include "wlan_psoc_mlme_ucfg_api.h"
87 #include <wlan_mlo_link_force.h>
88 #include "wma_eht.h"
89 #include "wlan_policy_mgr_ll_sap.h"
90 #include "wlan_vdev_mgr_ucfg_api.h"
91 #include "wlan_vdev_mlme_main.h"
92 #include "wlan_tdls_api.h"
93 
94 static QDF_STATUS init_sme_cmd_list(struct mac_context *mac);
95 
96 static void sme_disconnect_connected_sessions(struct mac_context *mac,
97 					      enum wlan_reason_code reason);
98 
99 static QDF_STATUS sme_handle_generic_change_country_code(struct mac_context *mac,
100 						  void *msg_buf);
101 
102 static QDF_STATUS sme_process_nss_update_resp(struct mac_context *mac, uint8_t *msg);
103 
104 /* Channel Change Response Indication Handler */
105 static QDF_STATUS sme_process_channel_change_resp(struct mac_context *mac,
106 					   uint16_t msg_type, void *msg_buf);
107 
108 static QDF_STATUS sme_stats_ext_event(struct mac_context *mac,
109 				      struct stats_ext_event *msg);
110 
111 static QDF_STATUS sme_fw_state_resp(struct mac_context *mac);
112 
113 /* Internal SME APIs */
sme_acquire_global_lock(struct sme_context * sme)114 QDF_STATUS sme_acquire_global_lock(struct sme_context *sme)
115 {
116 	if (!sme)
117 		return QDF_STATUS_E_INVAL;
118 
119 	return qdf_mutex_acquire(&sme->sme_global_lock);
120 }
121 
sme_release_global_lock(struct sme_context * sme)122 QDF_STATUS sme_release_global_lock(struct sme_context *sme)
123 {
124 	if (!sme)
125 		return QDF_STATUS_E_INVAL;
126 
127 	return qdf_mutex_release(&sme->sme_global_lock);
128 }
129 
sme_get_mac_context(void)130 struct mac_context *sme_get_mac_context(void)
131 {
132 	struct mac_context *mac_ctx;
133 	mac_handle_t mac_handle;
134 
135 	mac_handle = cds_get_context(QDF_MODULE_ID_SME);
136 	if (!mac_handle)
137 		return NULL;
138 
139 	mac_ctx = MAC_CONTEXT(mac_handle);
140 
141 	return mac_ctx;
142 }
143 
144 /**
145  * sme_process_set_hw_mode_resp() - Process set HW mode response
146  * @mac: Global MAC pointer
147  * @msg: HW mode response
148  *
149  * Processes the HW mode response and invokes the HDD callback
150  * to process further
151  */
sme_process_set_hw_mode_resp(struct mac_context * mac,uint8_t * msg)152 static QDF_STATUS sme_process_set_hw_mode_resp(struct mac_context *mac, uint8_t *msg)
153 {
154 	tListElem *entry;
155 	tSmeCmd *command = NULL;
156 	bool found;
157 	policy_mgr_pdev_set_hw_mode_cback callback = NULL;
158 	struct sir_set_hw_mode_resp *param;
159 	enum policy_mgr_conn_update_reason reason;
160 
161 	uint32_t session_id;
162 	uint32_t request_id;
163 
164 	param = (struct sir_set_hw_mode_resp *)msg;
165 	if (!param) {
166 		sme_err("HW mode resp param is NULL");
167 		/* Not returning. Need to check if active command list
168 		 * needs to be freed
169 		 */
170 	}
171 
172 	entry = csr_nonscan_active_ll_peek_head(mac, LL_ACCESS_LOCK);
173 	if (!entry) {
174 		sme_err("No cmd found in active list");
175 		return QDF_STATUS_E_FAILURE;
176 	}
177 
178 	command = GET_BASE_ADDR(entry, tSmeCmd, Link);
179 	if (!command) {
180 		sme_err("Base address is NULL");
181 		return QDF_STATUS_E_FAILURE;
182 	}
183 
184 	if (e_sme_command_set_hw_mode != command->command) {
185 		sme_err("Command mismatch!");
186 		return QDF_STATUS_E_FAILURE;
187 	}
188 
189 	callback = command->u.set_hw_mode_cmd.set_hw_mode_cb;
190 	reason = command->u.set_hw_mode_cmd.reason;
191 	session_id = command->u.set_hw_mode_cmd.session_id;
192 	request_id = command->u.set_hw_mode_cmd.request_id;
193 
194 	sme_debug("reason: %d session: %d",
195 		command->u.set_hw_mode_cmd.reason,
196 		command->u.set_hw_mode_cmd.session_id);
197 
198 	if (!callback) {
199 		sme_err("Callback does not exist");
200 		goto end;
201 	}
202 
203 	if (!param) {
204 		sme_err("Callback failed since HW mode params is NULL");
205 		goto end;
206 	}
207 
208 	/* Irrespective of the reason for which the hw mode change request
209 	 * was issued, the policy manager connection table needs to be updated
210 	 * with the new vdev-mac id mapping, tx/rx spatial streams etc., if the
211 	 * set hw mode was successful.
212 	 */
213 	callback(param->status,
214 			param->cfgd_hw_mode_index,
215 			param->num_vdev_mac_entries,
216 			param->vdev_mac_map,
217 			command->u.set_hw_mode_cmd.next_action,
218 			command->u.set_hw_mode_cmd.reason,
219 			command->u.set_hw_mode_cmd.session_id,
220 			command->u.set_hw_mode_cmd.context,
221 			command->u.set_hw_mode_cmd.request_id);
222 	if (!CSR_IS_SESSION_VALID(mac, session_id)) {
223 		sme_err("session %d is invalid", session_id);
224 		goto end;
225 	}
226 
227 	if (reason == POLICY_MGR_UPDATE_REASON_CHANNEL_SWITCH_STA) {
228 		sme_debug("Continue channel switch for STA on vdev %d",
229 			  session_id);
230 		csr_sta_continue_csa(mac, session_id);
231 	}
232 
233 	if (reason == POLICY_MGR_UPDATE_REASON_CHANNEL_SWITCH_SAP) {
234 		sme_debug("Continue channel switch for SAP on vdev %d",
235 			  session_id);
236 		csr_csa_restart(mac, session_id);
237 	}
238 
239 	if (reason == POLICY_MGR_UPDATE_REASON_STA_CONNECT ||
240 	    reason == POLICY_MGR_UPDATE_REASON_LFR2_ROAM) {
241 		QDF_STATUS status = QDF_STATUS_E_FAILURE;
242 
243 		sme_debug("Continue connect/reassoc on vdev %d reason %d status %d cm_id 0x%x",
244 			  session_id, reason, param->status, request_id);
245 		if (param->status == SET_HW_MODE_STATUS_OK ||
246 		    param->status == SET_HW_MODE_STATUS_ALREADY)
247 			status = QDF_STATUS_SUCCESS;
248 
249 		wlan_cm_handle_hw_mode_change_resp(mac->pdev, session_id,
250 						   request_id,
251 						   status);
252 	}
253 
254 end:
255 	found = csr_nonscan_active_ll_remove_entry(mac, entry,
256 			LL_ACCESS_LOCK);
257 	if (found)
258 		/* Now put this command back on the available command list */
259 		csr_release_command(mac, command);
260 
261 	return QDF_STATUS_SUCCESS;
262 }
263 
264 /**
265  * sme_process_hw_mode_trans_ind() - Process HW mode transition indication
266  * @mac: Global MAC pointer
267  * @msg: HW mode transition response
268  *
269  * Processes the HW mode transition indication and invoke the HDD callback
270  * to process further
271  */
sme_process_hw_mode_trans_ind(struct mac_context * mac,uint8_t * msg)272 static QDF_STATUS sme_process_hw_mode_trans_ind(struct mac_context *mac,
273 						uint8_t *msg)
274 {
275 	struct cm_hw_mode_trans_ind *param;
276 
277 	param = (struct cm_hw_mode_trans_ind *)msg;
278 	if (!param) {
279 		sme_err("HW mode trans ind param is NULL");
280 		return QDF_STATUS_E_FAILURE;
281 	}
282 
283 	policy_mgr_hw_mode_transition_cb(param->old_hw_mode_index,
284 		param->new_hw_mode_index,
285 		param->num_vdev_mac_entries,
286 		param->vdev_mac_map, param->num_freq_map, param->mac_freq_map,
287 		mac->psoc);
288 
289 	return QDF_STATUS_SUCCESS;
290 }
291 
292 /**
293  * free_sme_cmds() - This function frees memory allocated for SME commands
294  * @mac_ctx:      Pointer to Global MAC structure
295  *
296  * This function frees memory allocated for SME commands
297  *
298  * @Return: void
299  */
free_sme_cmds(struct mac_context * mac_ctx)300 static void free_sme_cmds(struct mac_context *mac_ctx)
301 {
302 	uint32_t idx;
303 
304 	if (!mac_ctx->sme.sme_cmd_buf_addr)
305 		return;
306 
307 	for (idx = 0; idx < mac_ctx->sme.sme_cmd_count; idx++)
308 		qdf_mem_free(mac_ctx->sme.sme_cmd_buf_addr[idx]);
309 
310 	qdf_mem_free(mac_ctx->sme.sme_cmd_buf_addr);
311 	mac_ctx->sme.sme_cmd_buf_addr = NULL;
312 }
313 
init_sme_cmd_list(struct mac_context * mac)314 static QDF_STATUS init_sme_cmd_list(struct mac_context *mac)
315 {
316 	QDF_STATUS status;
317 	tSmeCmd *cmd;
318 	uint32_t cmd_idx;
319 	uint32_t sme_cmd_ptr_ary_sz;
320 
321 	mac->sme.sme_cmd_count = SME_TOTAL_COMMAND;
322 
323 	status = csr_ll_open(&mac->sme.sme_cmd_freelist);
324 	if (!QDF_IS_STATUS_SUCCESS(status))
325 		goto end;
326 
327 	/* following pointer contains array of pointers for tSmeCmd* */
328 	sme_cmd_ptr_ary_sz = sizeof(void *) * mac->sme.sme_cmd_count;
329 	mac->sme.sme_cmd_buf_addr = qdf_mem_malloc(sme_cmd_ptr_ary_sz);
330 	if (!mac->sme.sme_cmd_buf_addr) {
331 		status = QDF_STATUS_E_NOMEM;
332 		goto end;
333 	}
334 
335 	status = QDF_STATUS_SUCCESS;
336 	for (cmd_idx = 0; cmd_idx < mac->sme.sme_cmd_count; cmd_idx++) {
337 		/*
338 		 * Since total size of all commands together can be huge chunk
339 		 * of memory, allocate SME cmd individually. These SME CMDs are
340 		 * moved between pending and active queues. And these freeing of
341 		 * these queues just manipulates the list but does not actually
342 		 * frees SME CMD pointers. Hence store each SME CMD address in
343 		 * the array, sme.sme_cmd_buf_addr. This will later facilitate
344 		 * freeing up of all SME CMDs with just a for loop.
345 		 */
346 		cmd = qdf_mem_malloc(sizeof(*cmd));
347 		if (!cmd) {
348 			status = QDF_STATUS_E_NOMEM;
349 			free_sme_cmds(mac);
350 			goto end;
351 		}
352 		mac->sme.sme_cmd_buf_addr[cmd_idx] = cmd;
353 		csr_ll_insert_tail(&mac->sme.sme_cmd_freelist,
354 				   &cmd->Link, LL_ACCESS_LOCK);
355 	}
356 
357 end:
358 	if (!QDF_IS_STATUS_SUCCESS(status))
359 		sme_err("Failed to initialize sme command list: %d", status);
360 
361 	return status;
362 }
363 
sme_release_command(struct mac_context * mac_ctx,tSmeCmd * sme_cmd)364 void sme_release_command(struct mac_context *mac_ctx, tSmeCmd *sme_cmd)
365 {
366 	sme_cmd->command = eSmeNoCommand;
367 	csr_ll_insert_tail(&mac_ctx->sme.sme_cmd_freelist, &sme_cmd->Link,
368 			   LL_ACCESS_LOCK);
369 }
370 
free_sme_cmd_list(struct mac_context * mac)371 static QDF_STATUS free_sme_cmd_list(struct mac_context *mac)
372 {
373 	QDF_STATUS status = QDF_STATUS_SUCCESS;
374 
375 	csr_ll_close(&mac->sme.sme_cmd_freelist);
376 
377 	status = sme_acquire_global_lock(&mac->sme);
378 	if (status != QDF_STATUS_SUCCESS)
379 		goto done;
380 
381 	free_sme_cmds(mac);
382 
383 	status = sme_release_global_lock(&mac->sme);
384 	if (status != QDF_STATUS_SUCCESS)
385 		sme_err("Failed to release the lock status: %d", status);
386 done:
387 	return status;
388 }
389 
dump_csr_command_info(struct mac_context * mac,tSmeCmd * pCmd)390 static void dump_csr_command_info(struct mac_context *mac, tSmeCmd *pCmd)
391 {
392 	switch (pCmd->command) {
393 	case eSmeCommandRoam:
394 		sme_debug("roam command reason is %d",
395 			pCmd->u.roamCmd.roamReason);
396 		break;
397 
398 	case eSmeCommandWmStatusChange:
399 		sme_debug("WMStatusChange command type is %d",
400 			pCmd->u.wmStatusChangeCmd.Type);
401 		break;
402 
403 	default:
404 		sme_debug("default: Unhandled command %d",
405 			pCmd->command);
406 		break;
407 	}
408 }
409 
sme_get_command_buffer(struct mac_context * mac)410 tSmeCmd *sme_get_command_buffer(struct mac_context *mac)
411 {
412 	tSmeCmd *pRetCmd = NULL, *pTempCmd = NULL;
413 	tListElem *pEntry;
414 	static int sme_command_queue_full;
415 
416 	pEntry = csr_ll_remove_head(&mac->sme.sme_cmd_freelist, LL_ACCESS_LOCK);
417 
418 	/* If we can get another MS Msg buffer, then we are ok.  Just
419 	 * link the entry onto the linked list.  (We are using the
420 	 * linked list to keep track of the message buffers).
421 	 */
422 	if (pEntry) {
423 		pRetCmd = GET_BASE_ADDR(pEntry, tSmeCmd, Link);
424 		/* reset when free list is available */
425 		sme_command_queue_full = 0;
426 	} else {
427 		int idx = 1;
428 
429 		/* Cannot change pRetCmd here since it needs to return later. */
430 		pEntry = csr_nonscan_active_ll_peek_head(mac, LL_ACCESS_LOCK);
431 		if (pEntry)
432 			pTempCmd = GET_BASE_ADDR(pEntry, tSmeCmd, Link);
433 
434 		sme_err("Out of command buffer.... command (0x%X) stuck",
435 			(pTempCmd) ? pTempCmd->command : eSmeNoCommand);
436 		if (pTempCmd) {
437 			if (eSmeCsrCommandMask & pTempCmd->command)
438 				/* CSR command is stuck. See what the reason
439 				 * code is for that command
440 				 */
441 				dump_csr_command_info(mac, pTempCmd);
442 		} /* if(pTempCmd) */
443 
444 		/* dump what is in the pending queue */
445 		pEntry =
446 			csr_nonscan_pending_ll_peek_head(mac,
447 					 LL_ACCESS_NOLOCK);
448 		while (pEntry && !sme_command_queue_full) {
449 			pTempCmd = GET_BASE_ADDR(pEntry, tSmeCmd, Link);
450 			/* Print only 1st five commands from pending queue. */
451 			if (idx <= 5)
452 				sme_err("Out of command buffer.... SME pending command #%d (0x%X)",
453 					idx, pTempCmd->command);
454 			idx++;
455 			if (eSmeCsrCommandMask & pTempCmd->command)
456 				/* CSR command is stuck. See what the reason
457 				 * code is for that command
458 				 */
459 				dump_csr_command_info(mac, pTempCmd);
460 			pEntry = csr_nonscan_pending_ll_next(mac, pEntry,
461 					    LL_ACCESS_NOLOCK);
462 		}
463 
464 		if (mac->mlme_cfg->gen.fatal_event_trigger)
465 			cds_flush_logs(WLAN_LOG_TYPE_FATAL,
466 				WLAN_LOG_INDICATOR_HOST_DRIVER,
467 				WLAN_LOG_REASON_SME_OUT_OF_CMD_BUF,
468 				false,
469 				mac->mlme_cfg->gen.self_recovery);
470 		else
471 			cds_trigger_recovery(QDF_GET_MSG_BUFF_FAILURE);
472 	}
473 
474 	/* memset to zero */
475 	if (pRetCmd) {
476 		qdf_mem_zero((uint8_t *)&pRetCmd->command,
477 			    sizeof(pRetCmd->command));
478 		qdf_mem_zero((uint8_t *)&pRetCmd->vdev_id,
479 			    sizeof(pRetCmd->vdev_id));
480 		qdf_mem_zero((uint8_t *)&pRetCmd->u, sizeof(pRetCmd->u));
481 	}
482 
483 	return pRetCmd;
484 }
485 
486 /**
487  * sme_ser_handle_active_cmd() - handle command activation callback from
488  *					new serialization module
489  * @cmd: pointer to new serialization command
490  *
491  * This API is to handle command activation callback from new serialization
492  * callback
493  *
494  * Return: QDF_STATUS_SUCCESS
495  */
496 static
sme_ser_handle_active_cmd(struct wlan_serialization_command * cmd)497 QDF_STATUS sme_ser_handle_active_cmd(struct wlan_serialization_command *cmd)
498 {
499 	tSmeCmd *sme_cmd;
500 	mac_handle_t mac_handle;
501 	struct mac_context *mac_ctx;
502 	QDF_STATUS status = QDF_STATUS_SUCCESS;
503 	bool do_continue;
504 
505 	if (!cmd) {
506 		sme_err("No serialization command found");
507 		return QDF_STATUS_E_FAILURE;
508 	}
509 
510 	mac_handle = cds_get_context(QDF_MODULE_ID_SME);
511 	if (mac_handle)
512 		mac_ctx = MAC_CONTEXT(mac_handle);
513 	else
514 		return QDF_STATUS_E_FAILURE;
515 
516 	sme_cmd = cmd->umac_cmd;
517 	if (!sme_cmd) {
518 		sme_err("No SME command found");
519 		return QDF_STATUS_E_FAILURE;
520 	}
521 
522 	switch (sme_cmd->command) {
523 	case eSmeCommandRoam:
524 		status = csr_roam_process_command(mac_ctx, sme_cmd);
525 		break;
526 	case eSmeCommandWmStatusChange:
527 		csr_roam_process_wm_status_change_command(mac_ctx,
528 					sme_cmd);
529 		break;
530 
531 	case eSmeCommandAddTs:
532 	case eSmeCommandDelTs:
533 #ifndef WLAN_MDM_CODE_REDUCTION_OPT
534 		do_continue = qos_process_command(mac_ctx, sme_cmd);
535 		if (do_continue)
536 			status = QDF_STATUS_E_FAILURE;
537 #endif
538 		break;
539 	case e_sme_command_set_hw_mode:
540 		csr_process_set_hw_mode(mac_ctx, sme_cmd);
541 		break;
542 	case e_sme_command_nss_update:
543 		csr_process_nss_update_req(mac_ctx, sme_cmd);
544 		break;
545 	case e_sme_command_set_dual_mac_config:
546 		csr_process_set_dual_mac_config(mac_ctx, sme_cmd);
547 		break;
548 	case e_sme_command_set_antenna_mode:
549 		csr_process_set_antenna_mode(mac_ctx, sme_cmd);
550 		break;
551 	case e_sme_command_sap_ch_width_update:
552 		csr_process_sap_ch_width_update(mac_ctx, sme_cmd);
553 		break;
554 	default:
555 		/* something is wrong */
556 		sme_err("unknown command %d", sme_cmd->command);
557 		status = QDF_STATUS_E_FAILURE;
558 		break;
559 	}
560 	return status;
561 }
562 
sme_dump_peer_disconnect_timeout_info(tSmeCmd * sme_cmd)563 static void sme_dump_peer_disconnect_timeout_info(tSmeCmd *sme_cmd)
564 {
565 	struct wmstatus_changecmd *wms_cmd;
566 	struct qdf_mac_addr peer_macaddr = QDF_MAC_ADDR_ZERO_INIT;
567 	struct qdf_mac_addr peer_mld_addr = QDF_MAC_ADDR_ZERO_INIT;
568 	char mld_log_str[MAC_ADDR_DUMP_LEN] = {0};
569 
570 	if (sme_cmd->command == eSmeCommandRoam &&
571 	    (sme_cmd->u.roamCmd.roamReason == eCsrForcedDisassocSta ||
572 	    sme_cmd->u.roamCmd.roamReason == eCsrForcedDeauthSta)) {
573 		qdf_mem_copy(peer_macaddr.bytes, sme_cmd->u.roamCmd.peerMac,
574 			     QDF_MAC_ADDR_SIZE);
575 		if (!qdf_is_macaddr_zero(&sme_cmd->u.roamCmd.peer_mld_addr))
576 			qdf_copy_macaddr(&peer_mld_addr,
577 					 &sme_cmd->u.roamCmd.peer_mld_addr);
578 	} else if (sme_cmd->command == eSmeCommandWmStatusChange) {
579 		wms_cmd = &sme_cmd->u.wmStatusChangeCmd;
580 		if (wms_cmd->Type == eCsrDisassociated) {
581 			qdf_copy_macaddr(
582 				&peer_macaddr,
583 				&wms_cmd->u.DisassocIndMsg.peer_macaddr);
584 			if (!qdf_is_macaddr_zero(
585 				&wms_cmd->u.DisassocIndMsg.peer_mld_addr))
586 				qdf_copy_macaddr(
587 					&peer_mld_addr,
588 					&wms_cmd->u.DisassocIndMsg.peer_mld_addr);
589 		} else if (wms_cmd->Type == eCsrDeauthenticated) {
590 			qdf_copy_macaddr(
591 				&peer_macaddr,
592 				&wms_cmd->u.DeauthIndMsg.peer_macaddr);
593 			if (!qdf_is_macaddr_zero(
594 				&wms_cmd->u.DeauthIndMsg.peer_mld_addr))
595 				qdf_copy_macaddr(
596 					&peer_mld_addr,
597 					&wms_cmd->u.DeauthIndMsg.peer_mld_addr);
598 		}
599 	}
600 
601 	if (!qdf_is_macaddr_zero(&peer_mld_addr))
602 		qdf_scnprintf(mld_log_str, MAC_ADDR_DUMP_LEN,
603 			      " mld: " QDF_MAC_ADDR_FMT,
604 			      QDF_MAC_ADDR_REF(peer_mld_addr.bytes));
605 
606 	if (!qdf_is_macaddr_zero(&peer_macaddr))
607 		sme_err("vdev %d cmd %d timeout for peer " QDF_MAC_ADDR_FMT "%s",
608 			sme_cmd->vdev_id, sme_cmd->command,
609 			QDF_MAC_ADDR_REF(peer_macaddr.bytes), mld_log_str);
610 
611 }
612 
sme_ser_cmd_callback(struct wlan_serialization_command * cmd,enum wlan_serialization_cb_reason reason)613 QDF_STATUS sme_ser_cmd_callback(struct wlan_serialization_command *cmd,
614 				enum wlan_serialization_cb_reason reason)
615 {
616 	mac_handle_t mac_handle;
617 	struct mac_context *mac_ctx;
618 	QDF_STATUS status = QDF_STATUS_SUCCESS;
619 	tSmeCmd *sme_cmd;
620 
621 	mac_handle = cds_get_context(QDF_MODULE_ID_SME);
622 	if (mac_handle)
623 		mac_ctx = MAC_CONTEXT(mac_handle);
624 	else
625 		return QDF_STATUS_E_FAILURE;
626 
627 	/*
628 	 * Do not acquire lock here as sme global lock is already acquired in
629 	 * caller or MC thread context
630 	 */
631 	if (!cmd) {
632 		sme_err("serialization command is null");
633 		return QDF_STATUS_E_FAILURE;
634 	}
635 
636 	switch (reason) {
637 	case WLAN_SER_CB_ACTIVATE_CMD:
638 		status = sme_ser_handle_active_cmd(cmd);
639 		break;
640 	case WLAN_SER_CB_CANCEL_CMD:
641 		if (cmd->cmd_type == WLAN_SER_CMD_SET_HW_MODE)
642 			policy_mgr_reset_hw_mode_change(mac_ctx->psoc);
643 		break;
644 	case WLAN_SER_CB_RELEASE_MEM_CMD:
645 		if (cmd->vdev)
646 			wlan_objmgr_vdev_release_ref(cmd->vdev,
647 						     WLAN_LEGACY_SME_ID);
648 		sme_cmd = cmd->umac_cmd;
649 		csr_release_command_buffer(mac_ctx, sme_cmd);
650 		break;
651 	case WLAN_SER_CB_ACTIVE_CMD_TIMEOUT:
652 		sme_cmd = cmd->umac_cmd;
653 		if (sme_cmd && (sme_cmd->command == eSmeCommandRoam ||
654 		    sme_cmd->command == eSmeCommandWmStatusChange)) {
655 			sme_dump_peer_disconnect_timeout_info(sme_cmd);
656 			qdf_trigger_self_recovery(mac_ctx->psoc,
657 						  QDF_ACTIVE_LIST_TIMEOUT);
658 		}
659 
660 		if (cmd->cmd_type == WLAN_SER_CMD_SET_HW_MODE)
661 			policy_mgr_reset_hw_mode_change(mac_ctx->psoc);
662 		break;
663 	default:
664 		sme_debug("unknown reason code");
665 		return QDF_STATUS_E_FAILURE;
666 	}
667 	return status;
668 }
669 
670 #ifdef WLAN_FEATURE_MEMDUMP_ENABLE
671 /**
672  * sme_get_sessionid_from_activelist() - gets vdev_id
673  * @mac: mac context
674  *
675  * This function is used to get session id from sme command
676  * active list
677  *
678  * Return: returns vdev_id
679  */
sme_get_sessionid_from_activelist(struct mac_context * mac)680 static uint32_t sme_get_sessionid_from_activelist(struct mac_context *mac)
681 {
682 	tListElem *entry;
683 	tSmeCmd *command;
684 	uint32_t vdev_id = WLAN_UMAC_VDEV_ID_MAX;
685 
686 	entry = csr_nonscan_active_ll_peek_head(mac, LL_ACCESS_LOCK);
687 	if (entry) {
688 		command = GET_BASE_ADDR(entry, tSmeCmd, Link);
689 		vdev_id = command->vdev_id;
690 	}
691 
692 	return vdev_id;
693 }
694 
695 /**
696  * sme_state_info_dump() - prints state information of sme layer
697  * @buf: buffer pointer
698  * @size: size of buffer to be filled
699  *
700  * This function is used to dump state information of sme layer
701  *
702  * Return: None
703  */
sme_state_info_dump(char ** buf_ptr,uint16_t * size)704 static void sme_state_info_dump(char **buf_ptr, uint16_t *size)
705 {
706 	uint8_t vdev_id, active_session_id;
707 	mac_handle_t mac_handle;
708 	struct mac_context *mac;
709 	uint16_t len = 0;
710 	char *buf = *buf_ptr;
711 	enum QDF_OPMODE op_mode;
712 
713 	mac_handle = cds_get_context(QDF_MODULE_ID_SME);
714 	if (!mac_handle) {
715 		return;
716 	}
717 
718 	mac = MAC_CONTEXT(mac_handle);
719 
720 	active_session_id = sme_get_sessionid_from_activelist(mac);
721 	if (active_session_id != WLAN_UMAC_VDEV_ID_MAX) {
722 		len += qdf_scnprintf(buf + len, *size - len,
723 			"\n active command sessionid %d", active_session_id);
724 	}
725 
726 	for (vdev_id = 0; vdev_id < WLAN_MAX_VDEVS; vdev_id++) {
727 		if (CSR_IS_SESSION_VALID(mac, vdev_id)) {
728 			op_mode = wlan_get_opmode_from_vdev_id(mac->pdev,
729 							       vdev_id);
730 			if (op_mode != QDF_STA_MODE &&
731 			    op_mode != QDF_P2P_CLIENT_MODE)
732 				continue;
733 			if (cm_is_vdevid_connected(mac->pdev, vdev_id)) {
734 				len += qdf_scnprintf(buf + len, *size - len,
735 					"\n RoamState: %d", mac->roam.curState[vdev_id]);
736 				len += qdf_scnprintf(buf + len, *size - len,
737 					"\n RoamSubState: %d", mac->roam.curSubState[vdev_id]);
738 			}
739 		}
740 	}
741 
742 	*size -= len;
743 	*buf_ptr += len;
744 }
745 
746 /**
747  * sme_register_debug_callback() - registration function sme layer
748  * to print sme state information
749  *
750  * Return: None
751  */
sme_register_debug_callback(void)752 static void sme_register_debug_callback(void)
753 {
754 	qdf_register_debug_callback(QDF_MODULE_ID_SME, &sme_state_info_dump);
755 }
756 #else /* WLAN_FEATURE_MEMDUMP_ENABLE */
sme_register_debug_callback(void)757 static void sme_register_debug_callback(void)
758 {
759 }
760 #endif /* WLAN_FEATURE_MEMDUMP_ENABLE */
761 
762 #ifdef WLAN_POWER_DEBUG
sme_power_debug_stats_cb(struct mac_context * mac,struct power_stats_response * response)763 static void sme_power_debug_stats_cb(struct mac_context *mac,
764 				     struct power_stats_response *response)
765 {
766 	QDF_STATUS status = QDF_STATUS_SUCCESS;
767 
768 	status = sme_acquire_global_lock(&mac->sme);
769 	if (QDF_IS_STATUS_SUCCESS(status)) {
770 		if (mac->sme.power_stats_resp_callback)
771 			mac->sme.power_stats_resp_callback(
772 					response,
773 					mac->sme.power_debug_stats_context);
774 		else
775 			sme_err("Null hdd cb");
776 		mac->sme.power_stats_resp_callback = NULL;
777 		mac->sme.power_debug_stats_context = NULL;
778 		sme_release_global_lock(&mac->sme);
779 	}
780 }
781 
sme_register_power_debug_stats_cb(struct mac_context * mac)782 static void sme_register_power_debug_stats_cb(struct mac_context *mac)
783 {
784 	QDF_STATUS status = QDF_STATUS_SUCCESS;
785 
786 	status = sme_acquire_global_lock(&mac->sme);
787 
788 	if (QDF_IS_STATUS_SUCCESS(status)) {
789 		mac->sme.sme_power_debug_stats_callback =
790 						sme_power_debug_stats_cb;
791 		sme_release_global_lock(&mac->sme);
792 	}
793 }
794 
sme_unregister_power_debug_stats_cb(struct mac_context * mac)795 static void sme_unregister_power_debug_stats_cb(struct mac_context *mac)
796 {
797 	QDF_STATUS status = QDF_STATUS_SUCCESS;
798 
799 	status = sme_acquire_global_lock(&mac->sme);
800 	if (QDF_IS_STATUS_SUCCESS(status)) {
801 		mac->sme.sme_power_debug_stats_callback = NULL;
802 		sme_release_global_lock(&mac->sme);
803 	}
804 }
805 #else
sme_register_power_debug_stats_cb(struct mac_context * mac)806 static inline void sme_register_power_debug_stats_cb(struct mac_context *mac)
807 {
808 }
809 
sme_unregister_power_debug_stats_cb(struct mac_context * mac)810 static inline void sme_unregister_power_debug_stats_cb(struct mac_context *mac)
811 {
812 }
813 #endif
814 
815 static void
sme_register_vdev_delete_callback(struct mac_context * mac)816 sme_register_vdev_delete_callback(struct mac_context *mac)
817 {
818 	mac->sme.sme_vdev_del_cb = sme_vdev_delete;
819 }
820 
821 /* Global APIs */
822 
823 /**
824  * sme_open() - Initialize all SME modules and put them at idle state
825  * @mac_handle:       The handle returned by mac_open
826  *
827  * The function initializes each module inside SME, PMC, CSR, etc. Upon
828  * successfully return, all modules are at idle state ready to start.
829  * smeOpen must be called before any other SME APIs can be involved.
830  * smeOpen must be called after mac_open.
831  *
832  * Return: QDF_STATUS_SUCCESS - SME is successfully initialized.
833  *         Other status means SME is failed to be initialized
834  */
sme_open(mac_handle_t mac_handle)835 QDF_STATUS sme_open(mac_handle_t mac_handle)
836 {
837 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
838 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
839 
840 	mac->sme.state = SME_STATE_STOP;
841 	if (!QDF_IS_STATUS_SUCCESS(qdf_mutex_create(
842 					&mac->sme.sme_global_lock))) {
843 		sme_err("Init lock failed");
844 		return  QDF_STATUS_E_FAILURE;
845 	}
846 	status = csr_open(mac);
847 	if (!QDF_IS_STATUS_SUCCESS(status)) {
848 		sme_err("csr_open failed, status: %d", status);
849 		return status;
850 	}
851 
852 	status = sme_ps_open(mac_handle);
853 	if (!QDF_IS_STATUS_SUCCESS(status)) {
854 		sme_err("sme_ps_open failed with status: %d", status);
855 		return status;
856 	}
857 
858 #ifndef WLAN_MDM_CODE_REDUCTION_OPT
859 	status = sme_qos_open(mac);
860 	if (!QDF_IS_STATUS_SUCCESS(status)) {
861 		sme_err("Qos open, status: %d", status);
862 		return status;
863 	}
864 #endif
865 	status = init_sme_cmd_list(mac);
866 	if (!QDF_IS_STATUS_SUCCESS(status))
867 		return status;
868 
869 	status = rrm_open(mac);
870 	if (!QDF_IS_STATUS_SUCCESS(status)) {
871 		sme_err("rrm_open failed, status: %d", status);
872 		return status;
873 	}
874 	sme_trace_init(mac);
875 	sme_register_debug_callback();
876 	sme_register_power_debug_stats_cb(mac);
877 	sme_register_vdev_delete_callback(mac);
878 
879 	return status;
880 }
881 
882 /*
883  * sme_init_chan_list, triggers channel setup based on country code.
884  */
sme_init_chan_list(mac_handle_t mac_handle,enum country_src cc_src)885 QDF_STATUS sme_init_chan_list(mac_handle_t mac_handle, enum country_src cc_src)
886 {
887 	struct mac_context *pmac = MAC_CONTEXT(mac_handle);
888 
889 	if ((cc_src == SOURCE_USERSPACE) &&
890 	    (pmac->mlme_cfg->sap_cfg.country_code_priority)) {
891 		pmac->mlme_cfg->gen.enabled_11d = false;
892 	}
893 
894 	return csr_init_chan_list(pmac);
895 }
896 
897 /*
898  * sme_set11dinfo() - Set the 11d information about valid channels
899  *  and there power using information from nvRAM
900  *  This function is called only for AP.
901  *
902  *  This is a synchronous call
903  *
904  * mac_handle - The handle returned by mac_open.
905  * pSmeConfigParams - a pointer to a caller allocated object of
906  *  struct sme_config_params.
907  *
908  * Return QDF_STATUS_SUCCESS - SME update the config parameters successfully.
909  *
910  *  Other status means SME is failed to update the config parameters.
911  */
912 
sme_set11dinfo(mac_handle_t mac_handle,struct sme_config_params * pSmeConfigParams)913 QDF_STATUS sme_set11dinfo(mac_handle_t mac_handle,
914 			  struct sme_config_params *pSmeConfigParams)
915 {
916 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
917 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
918 
919 	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
920 			 TRACE_CODE_SME_RX_HDD_MSG_SET_11DINFO, NO_SESSION, 0));
921 	if (!pSmeConfigParams) {
922 		sme_err("SME config params empty");
923 		return status;
924 	}
925 
926 	status = csr_set_channels(mac_ctx, &pSmeConfigParams->csr_config);
927 	if (!QDF_IS_STATUS_SUCCESS(status))
928 		sme_err("csr_set_channels failed with status: %d", status);
929 
930 	return status;
931 }
932 
933 /**
934  * sme_update_fine_time_measurement_capab() - Update the FTM capabitlies from
935  * incoming val
936  * @mac_handle: Opaque handle to the global MAC context
937  * @val: New FTM capability value
938  *
939  * Return: None
940  */
sme_update_fine_time_measurement_capab(mac_handle_t mac_handle,uint8_t session_id,uint32_t val)941 void sme_update_fine_time_measurement_capab(mac_handle_t mac_handle,
942 					    uint8_t session_id,
943 					    uint32_t val)
944 {
945 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
946 	QDF_STATUS status;
947 
948 	ucfg_wifi_pos_set_ftm_cap(mac_ctx->psoc, val);
949 
950 	if (!val) {
951 		mac_ctx->rrm.rrmPEContext.rrmEnabledCaps.fine_time_meas_rpt = 0;
952 		((tpRRMCaps)mac_ctx->rrm.rrmConfig.
953 			rm_capability)->fine_time_meas_rpt = 0;
954 	} else {
955 		mac_ctx->rrm.rrmPEContext.rrmEnabledCaps.fine_time_meas_rpt = 1;
956 		((tpRRMCaps)mac_ctx->rrm.rrmConfig.
957 			rm_capability)->fine_time_meas_rpt = 1;
958 	}
959 
960 	/* Inform this RRM IE change to FW */
961 	status = sme_acquire_global_lock(&mac_ctx->sme);
962 	if (QDF_IS_STATUS_SUCCESS(status)) {
963 		wlan_roam_update_cfg(mac_ctx->psoc, session_id,
964 				     REASON_CONNECT_IES_CHANGED);
965 		sme_release_global_lock(&mac_ctx->sme);
966 	}
967 }
968 
969 /*
970  * sme_update_config() - Change configurations for all SME modules
971  * The function updates some configuration for modules in SME, CSR, etc
972  *  during SMEs close open sequence.
973  * Modules inside SME apply the new configuration at the next transaction.
974  * This is a synchronous call
975  *
976  * mac_handle - The handle returned by mac_open.
977  * pSmeConfigParams - a pointer to a caller allocated object of
978  *  struct sme_config_params.
979  * Return QDF_STATUS_SUCCESS - SME update the config parameters successfully.
980  *  Other status means SME is failed to update the config parameters.
981  */
sme_update_config(mac_handle_t mac_handle,struct sme_config_params * pSmeConfigParams)982 QDF_STATUS sme_update_config(mac_handle_t mac_handle,
983 			     struct sme_config_params *pSmeConfigParams)
984 {
985 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
986 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
987 
988 	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
989 			 TRACE_CODE_SME_RX_HDD_MSG_UPDATE_CONFIG, NO_SESSION,
990 			 0));
991 	if (!pSmeConfigParams) {
992 		sme_err("SME config params empty");
993 		return status;
994 	}
995 	status = sme_acquire_global_lock(&mac->sme);
996 	if (QDF_IS_STATUS_ERROR(status)) {
997 		sme_err("SME lock error %d", status);
998 		return status;
999 	}
1000 
1001 	status = csr_change_default_config_param(mac, &pSmeConfigParams->
1002 						csr_config);
1003 	if (!QDF_IS_STATUS_SUCCESS(status))
1004 		sme_err("csr_change_default_config_param failed status: %d",
1005 			status);
1006 
1007 	/* For SOC, CFG is set before start We don't want to apply global CFG
1008 	 * in connect state because that may cause some side affect
1009 	 */
1010 	if (csr_is_all_session_disconnected(mac))
1011 		csr_set_global_cfgs(mac);
1012 
1013 	sme_release_global_lock(&mac->sme);
1014 
1015 	return QDF_STATUS_SUCCESS;
1016 }
1017 
sme_update_roam_params(mac_handle_t mac_handle,uint8_t vdev_id,struct rso_config_params * src_rso_config,struct rso_user_config * src_rso_usr_cfg,int update_param)1018 QDF_STATUS sme_update_roam_params(mac_handle_t mac_handle,
1019 				  uint8_t vdev_id,
1020 				  struct rso_config_params *src_rso_config,
1021 				  struct rso_user_config *src_rso_usr_cfg,
1022 				  int update_param)
1023 {
1024 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
1025 	QDF_STATUS status;
1026 	uint8_t i;
1027 	struct wlan_mlme_psoc_ext_obj *mlme_obj;
1028 	struct rso_config_params *dst_rso_usr_cfg;
1029 	struct rso_user_config *rso_usr_cfg;
1030 	struct wlan_objmgr_vdev *vdev;
1031 
1032 	mlme_obj = mlme_get_psoc_ext_obj(mac_ctx->psoc);
1033 	if (!mlme_obj)
1034 		return QDF_STATUS_E_FAILURE;
1035 
1036 	dst_rso_usr_cfg = &mlme_obj->cfg.lfr.rso_user_config;
1037 
1038 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac_ctx->psoc, vdev_id,
1039 						    WLAN_LEGACY_SME_ID);
1040 	if (!vdev)
1041 		return QDF_STATUS_E_FAILURE;
1042 
1043 	rso_usr_cfg = wlan_cm_get_rso_user_config(vdev);
1044 
1045 	if (!rso_usr_cfg) {
1046 		wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID);
1047 		return QDF_STATUS_E_FAILURE;
1048 	}
1049 
1050 	switch (update_param) {
1051 	case REASON_ROAM_EXT_SCAN_PARAMS_CHANGED:
1052 		mac_ctx->mlme_cfg->lfr.rssi_boost_threshold_5g =
1053 			src_rso_config->raise_rssi_thresh_5g;
1054 		mac_ctx->mlme_cfg->lfr.rssi_penalize_threshold_5g =
1055 			src_rso_config->drop_rssi_thresh_5g;
1056 		mac_ctx->mlme_cfg->lfr.rssi_boost_factor_5g =
1057 			src_rso_config->raise_factor_5g;
1058 		mac_ctx->mlme_cfg->lfr.rssi_penalize_factor_5g =
1059 			src_rso_config->drop_factor_5g;
1060 		mac_ctx->mlme_cfg->lfr.max_rssi_boost_5g =
1061 			src_rso_config->max_raise_rssi_5g;
1062 		dst_rso_usr_cfg->alert_rssi_threshold =
1063 			src_rso_config->alert_rssi_threshold;
1064 		dst_rso_usr_cfg->rssi_diff = src_rso_config->rssi_diff;
1065 		mac_ctx->mlme_cfg->lfr.enable_5g_band_pref = true;
1066 		break;
1067 	case REASON_ROAM_SET_SSID_ALLOWED:
1068 		qdf_mem_zero(&rso_usr_cfg->ssid_allowed_list,
1069 			     sizeof(struct wlan_ssid) * MAX_SSID_ALLOWED_LIST);
1070 		rso_usr_cfg->num_ssid_allowed_list =
1071 			src_rso_usr_cfg->num_ssid_allowed_list;
1072 		for (i = 0; i < rso_usr_cfg->num_ssid_allowed_list; i++) {
1073 			rso_usr_cfg->ssid_allowed_list[i].length =
1074 				src_rso_usr_cfg->ssid_allowed_list[i].length;
1075 			qdf_mem_copy(rso_usr_cfg->ssid_allowed_list[i].ssid,
1076 				     src_rso_usr_cfg->ssid_allowed_list[i].ssid,
1077 				     rso_usr_cfg->ssid_allowed_list[i].length);
1078 		}
1079 		break;
1080 	case REASON_ROAM_SET_FAVORED_BSSID:
1081 		qdf_mem_zero(&dst_rso_usr_cfg->bssid_favored,
1082 			sizeof(struct qdf_mac_addr) * MAX_BSSID_FAVORED);
1083 		dst_rso_usr_cfg->num_bssid_favored =
1084 			src_rso_config->num_bssid_favored;
1085 		for (i = 0; i < dst_rso_usr_cfg->num_bssid_favored; i++) {
1086 			qdf_copy_macaddr(&dst_rso_usr_cfg->bssid_favored[i],
1087 					 &src_rso_config->bssid_favored[i]);
1088 			dst_rso_usr_cfg->bssid_favored_factor[i] =
1089 				src_rso_config->bssid_favored_factor[i];
1090 		}
1091 		break;
1092 	case REASON_ROAM_GOOD_RSSI_CHANGED:
1093 		dst_rso_usr_cfg->good_rssi_roam =
1094 					src_rso_config->good_rssi_roam;
1095 		break;
1096 	default:
1097 		break;
1098 	}
1099 
1100 	status = sme_acquire_global_lock(&mac_ctx->sme);
1101 	if (QDF_IS_STATUS_SUCCESS(status)) {
1102 		wlan_roam_update_cfg(mac_ctx->psoc, vdev_id, update_param);
1103 		sme_release_global_lock(&mac_ctx->sme);
1104 	}
1105 
1106 	wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID);
1107 	return 0;
1108 }
1109 
1110 #ifdef WLAN_FEATURE_EXTWOW_SUPPORT
1111 
1112 /**
1113  * sme_process_ready_to_ext_wow() - inform ready to ExtWoW indication.
1114  * @mac: Global MAC context
1115  * @indication: ready to Ext WoW indication from lower layer
1116  *
1117  * On getting ready to Ext WoW indication, this function calls callback
1118  * registered (HDD callback) with SME to inform ready to ExtWoW indication.
1119  *
1120  * Return: None
1121  */
sme_process_ready_to_ext_wow(struct mac_context * mac,tpSirReadyToExtWoWInd indication)1122 static void sme_process_ready_to_ext_wow(struct mac_context *mac,
1123 					 tpSirReadyToExtWoWInd indication)
1124 {
1125 	if (!mac) {
1126 		sme_err("mac is null");
1127 		return;
1128 	}
1129 
1130 	if (mac->readyToExtWoWCallback) {
1131 		mac->readyToExtWoWCallback(mac->readyToExtWoWContext,
1132 					   indication->status);
1133 		mac->readyToExtWoWCallback = NULL;
1134 		mac->readyToExtWoWContext = NULL;
1135 	}
1136 
1137 }
1138 #endif
1139 
1140 /*
1141  * sme_hdd_ready_ind() - SME sends eWNI_SME_SYS_READY_IND to PE to inform
1142  *  that the NIC is ready tio run.
1143  * The function is called by HDD at the end of initialization stage so PE/HAL
1144  * can enable the NIC to running state.
1145  * This is a synchronous call
1146  *
1147  * @mac_handle - The handle returned by mac_open.
1148  * Return QDF_STATUS_SUCCESS - eWNI_SME_SYS_READY_IND is sent to PE
1149  *				successfully.
1150  * Other status means SME failed to send the message to PE.
1151  */
sme_hdd_ready_ind(mac_handle_t mac_handle)1152 QDF_STATUS sme_hdd_ready_ind(mac_handle_t mac_handle)
1153 {
1154 	struct sme_ready_req *msg;
1155 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
1156 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
1157 
1158 	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
1159 			 TRACE_CODE_SME_RX_HDD_MSG_HDDREADYIND, NO_SESSION, 0));
1160 	do {
1161 
1162 		msg = qdf_mem_malloc(sizeof(*msg));
1163 		if (!msg)
1164 			return QDF_STATUS_E_NOMEM;
1165 
1166 		msg->messageType = eWNI_SME_SYS_READY_IND;
1167 		msg->length = sizeof(*msg);
1168 		msg->sme_msg_cb = sme_process_msg_callback;
1169 		msg->stop_roaming_cb = sme_stop_roaming;
1170 		msg->csr_roam_auth_event_handle_cb =
1171 				csr_roam_auth_offload_callback;
1172 		status = u_mac_post_ctrl_msg(mac_handle, (tSirMbMsg *)msg);
1173 		if (QDF_IS_STATUS_ERROR(status)) {
1174 			sme_err("u_mac_post_ctrl_msg failed to send eWNI_SME_SYS_READY_IND");
1175 			break;
1176 		}
1177 
1178 		status = csr_ready(mac);
1179 		if (QDF_IS_STATUS_ERROR(status)) {
1180 			sme_err("csr_ready failed with status: %d", status);
1181 			break;
1182 		}
1183 
1184 		mac->sme.state = SME_STATE_READY;
1185 	} while (0);
1186 
1187 	return status;
1188 }
1189 
1190 #ifdef WLAN_BCN_RECV_FEATURE
1191 QDF_STATUS
sme_register_bcn_report_pe_cb(mac_handle_t mac_handle,beacon_report_cb cb)1192 sme_register_bcn_report_pe_cb(mac_handle_t mac_handle, beacon_report_cb cb)
1193 {
1194 	QDF_STATUS status;
1195 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
1196 
1197 	if (!mac) {
1198 		sme_err("Invalid mac context");
1199 		return QDF_STATUS_E_INVAL;
1200 	}
1201 
1202 	status = sme_acquire_global_lock(&mac->sme);
1203 	if (QDF_IS_STATUS_SUCCESS(status)) {
1204 		mac_register_bcn_report_send_cb(mac, cb);
1205 		sme_release_global_lock(&mac->sme);
1206 	}
1207 
1208 	return status;
1209 }
1210 #endif
1211 
1212 #ifdef WLAN_CONV_SPECTRAL_ENABLE
sme_register_spectral_cb(struct mac_context * mac_ctx)1213 static QDF_STATUS sme_register_spectral_cb(struct mac_context *mac_ctx)
1214 {
1215 	struct spectral_legacy_cbacks spectral_cb = {0};
1216 	QDF_STATUS status;
1217 
1218 	spectral_cb.vdev_get_chan_freq = sme_get_oper_chan_freq;
1219 	spectral_cb.vdev_get_ch_width = sme_get_oper_ch_width;
1220 	spectral_cb.vdev_get_sec20chan_freq_mhz = sme_get_sec20chan_freq_mhz;
1221 	status = spectral_register_legacy_cb(mac_ctx->psoc, &spectral_cb);
1222 
1223 	return status;
1224 }
1225 #else
sme_register_spectral_cb(struct mac_context * mac_ctx)1226 static QDF_STATUS sme_register_spectral_cb(struct mac_context *mac_ctx)
1227 {
1228 	return QDF_STATUS_SUCCESS;
1229 }
1230 #endif
1231 /*
1232  * sme_start() - Put all SME modules at ready state.
1233  *  The function starts each module in SME, PMC, CSR, etc. . Upon
1234  *  successfully return, all modules are ready to run.
1235  *  This is a synchronous call
1236  *
1237  * mac_handle - The handle returned by mac_open.
1238  * Return QDF_STATUS_SUCCESS - SME is ready.
1239  * Other status means SME is failed to start
1240  */
sme_start(mac_handle_t mac_handle)1241 QDF_STATUS sme_start(mac_handle_t mac_handle)
1242 {
1243 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
1244 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
1245 	struct policy_mgr_sme_cbacks sme_cbacks;
1246 
1247 	do {
1248 		status = csr_start(mac);
1249 		if (!QDF_IS_STATUS_SUCCESS(status)) {
1250 			sme_err("csr_start failed status: %d", status);
1251 			break;
1252 		}
1253 		sme_cbacks.sme_get_nss_for_vdev = sme_get_vdev_type_nss;
1254 		sme_cbacks.sme_nss_update_request = sme_nss_update_request;
1255 		sme_cbacks.sme_pdev_set_hw_mode = sme_pdev_set_hw_mode;
1256 		sme_cbacks.sme_soc_set_dual_mac_config =
1257 			sme_soc_set_dual_mac_config;
1258 		sme_cbacks.sme_change_mcc_beacon_interval =
1259 			sme_change_mcc_beacon_interval;
1260 		sme_cbacks.sme_rso_start_cb = sme_start_roaming;
1261 		sme_cbacks.sme_rso_stop_cb = sme_stop_roaming;
1262 		sme_cbacks.sme_change_sap_csa_count = sme_change_sap_csa_count;
1263 		sme_cbacks.sme_sap_update_ch_width = sme_sap_update_ch_width;
1264 		status = policy_mgr_register_sme_cb(mac->psoc, &sme_cbacks);
1265 		if (!QDF_IS_STATUS_SUCCESS(status)) {
1266 			sme_err("Failed to register sme cb with Policy Manager: %d",
1267 				status);
1268 			break;
1269 		}
1270 		sme_register_spectral_cb(mac);
1271 		mac->sme.state = SME_STATE_START;
1272 
1273 		/* START RRM */
1274 		status = rrm_start(mac);
1275 		if (!QDF_IS_STATUS_SUCCESS(status)) {
1276 			sme_err("Failed to start RRM");
1277 			break;
1278 		}
1279 	} while (0);
1280 	return status;
1281 }
1282 
dfs_msg_processor(struct mac_context * mac,struct scheduler_msg * msg)1283 static QDF_STATUS dfs_msg_processor(struct mac_context *mac,
1284 		struct scheduler_msg *msg)
1285 {
1286 	QDF_STATUS status = QDF_STATUS_SUCCESS;
1287 	struct csr_roam_info *roam_info;
1288 	tSirSmeCSAIeTxCompleteRsp *csa_ie_tx_complete_rsp;
1289 	uint32_t session_id = 0;
1290 	eRoamCmdStatus roam_status;
1291 	eCsrRoamResult roam_result;
1292 
1293 	roam_info = qdf_mem_malloc(sizeof(*roam_info));
1294 	if (!roam_info)
1295 		return QDF_STATUS_E_NOMEM;
1296 
1297 	switch (msg->type) {
1298 	case eWNI_SME_DFS_RADAR_FOUND:
1299 	{
1300 		session_id = policy_mgr_get_dfs_beaconing_session_id(mac->psoc);
1301 		if (!CSR_IS_SESSION_VALID(mac, session_id)) {
1302 			sme_err("Invalid vdev %d", session_id);
1303 			qdf_mem_free(roam_info);
1304 			return QDF_STATUS_E_FAILURE;
1305 		}
1306 		roam_status = eCSR_ROAM_DFS_RADAR_IND;
1307 		roam_result = eCSR_ROAM_RESULT_DFS_RADAR_FOUND_IND;
1308 		sme_debug("sapdfs: Radar indication event occurred");
1309 		break;
1310 	}
1311 	case eWNI_SME_DFS_CSAIE_TX_COMPLETE_IND:
1312 	{
1313 		csa_ie_tx_complete_rsp =
1314 			(tSirSmeCSAIeTxCompleteRsp *) msg->bodyptr;
1315 		if (!csa_ie_tx_complete_rsp) {
1316 			sme_err("eWNI_SME_DFS_CSAIE_TX_COMPLETE_IND null msg");
1317 			qdf_mem_free(roam_info);
1318 			return QDF_STATUS_E_FAILURE;
1319 		}
1320 		session_id = csa_ie_tx_complete_rsp->sessionId;
1321 		roam_status = eCSR_ROAM_DFS_CHAN_SW_NOTIFY;
1322 		roam_result = eCSR_ROAM_RESULT_DFS_CHANSW_UPDATE_SUCCESS;
1323 		break;
1324 	}
1325 	case eWNI_SME_DFS_CAC_COMPLETE:
1326 	{
1327 		session_id = msg->bodyval;
1328 		roam_status = eCSR_ROAM_CAC_COMPLETE_IND;
1329 		roam_result = eCSR_ROAM_RESULT_CAC_END_IND;
1330 		sme_debug("sapdfs: Received eWNI_SME_DFS_CAC_COMPLETE vdev %d",
1331 			  session_id);
1332 		break;
1333 	}
1334 	case eWNI_SME_CSA_RESTART_RSP:
1335 	{
1336 		session_id = msg->bodyval;
1337 		roam_status = 0;
1338 		roam_result = eCSR_ROAM_RESULT_CSA_RESTART_RSP;
1339 		sme_debug("sapdfs: Received eCSR_ROAM_RESULT_DFS_CHANSW_UPDATE_REQ vdev %d",
1340 			  session_id);
1341 		break;
1342 	}
1343 	default:
1344 	{
1345 		sme_err("Invalid DFS message: 0x%x", msg->type);
1346 		qdf_mem_free(roam_info);
1347 		status = QDF_STATUS_E_FAILURE;
1348 		return status;
1349 	}
1350 	}
1351 
1352 	/* Indicate Radar Event to SAP */
1353 	csr_roam_call_callback(mac, session_id, roam_info,
1354 			       roam_status, roam_result);
1355 	qdf_mem_free(roam_info);
1356 	return status;
1357 }
1358 
1359 /*
1360  * Handle the unprotected management frame indication from LIM and
1361  * forward it to HDD.
1362  */
1363 static QDF_STATUS
sme_unprotected_mgmt_frm_ind(struct mac_context * mac,tpSirSmeUnprotMgmtFrameInd pSmeMgmtFrm)1364 sme_unprotected_mgmt_frm_ind(struct mac_context *mac,
1365 			     tpSirSmeUnprotMgmtFrameInd pSmeMgmtFrm)
1366 {
1367 	QDF_STATUS status = QDF_STATUS_SUCCESS;
1368 	struct csr_roam_info *roam_info;
1369 	uint32_t SessionId = pSmeMgmtFrm->sessionId;
1370 
1371 	roam_info = qdf_mem_malloc(sizeof(*roam_info));
1372 	if (!roam_info)
1373 		return QDF_STATUS_E_NOMEM;
1374 
1375 	roam_info->nFrameLength = pSmeMgmtFrm->frameLen;
1376 	roam_info->pbFrames = pSmeMgmtFrm->frameBuf;
1377 	roam_info->frameType = pSmeMgmtFrm->frameType;
1378 
1379 	/* forward the mgmt frame to HDD */
1380 	csr_roam_call_callback(mac, SessionId, roam_info,
1381 			       eCSR_ROAM_UNPROT_MGMT_FRAME_IND, 0);
1382 
1383 	qdf_mem_free(roam_info);
1384 
1385 	return status;
1386 }
1387 
sme_update_new_channel_event(mac_handle_t mac_handle,uint8_t session_id)1388 QDF_STATUS sme_update_new_channel_event(mac_handle_t mac_handle,
1389 					uint8_t session_id)
1390 {
1391 	QDF_STATUS status = QDF_STATUS_SUCCESS;
1392 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
1393 	struct csr_roam_info *roamInfo;
1394 	eRoamCmdStatus roamStatus;
1395 	eCsrRoamResult roamResult;
1396 
1397 	roamInfo = qdf_mem_malloc(sizeof(*roamInfo));
1398 	if (!roamInfo)
1399 		return QDF_STATUS_E_FAILURE;
1400 
1401 	roamStatus = eCSR_ROAM_CHANNEL_COMPLETE_IND;
1402 	roamResult = eCSR_ROAM_RESULT_DFS_RADAR_FOUND_IND;
1403 	sme_debug("sapdfs: Updated new channel event");
1404 
1405 	/* Indicate channel Event to SAP */
1406 	csr_roam_call_callback(mac, session_id, roamInfo,
1407 			       roamStatus, roamResult);
1408 
1409 	qdf_mem_free(roamInfo);
1410 	return status;
1411 }
1412 
1413 
1414 /**
1415  * sme_extended_change_channel_ind()- function to indicate ECSA
1416  * action frame is received in lim to SAP
1417  * @mac_ctx:  pointer to global mac structure
1418  * @msg_buf: contain new channel and session id.
1419  *
1420  * This function is called to post ECSA action frame
1421  * receive event to SAP.
1422  *
1423  * Return: success if msg indicated to SAP else return failure
1424  */
sme_extended_change_channel_ind(struct mac_context * mac_ctx,void * msg_buf)1425 static QDF_STATUS sme_extended_change_channel_ind(struct mac_context *mac_ctx,
1426 						void *msg_buf)
1427 {
1428 	struct sir_sme_ext_cng_chan_ind *ext_chan_ind;
1429 	QDF_STATUS status = QDF_STATUS_SUCCESS;
1430 	uint32_t session_id = 0;
1431 	struct csr_roam_info *roam_info;
1432 	eRoamCmdStatus roam_status;
1433 	eCsrRoamResult roam_result;
1434 
1435 	ext_chan_ind = msg_buf;
1436 	if (!ext_chan_ind) {
1437 		sme_err("ext_chan_ind is NULL");
1438 		return QDF_STATUS_E_FAILURE;
1439 	}
1440 	roam_info = qdf_mem_malloc(sizeof(*roam_info));
1441 	if (!roam_info)
1442 		return QDF_STATUS_E_NOMEM;
1443 
1444 	session_id = ext_chan_ind->session_id;
1445 	roam_info->target_chan_freq = ext_chan_ind->new_chan_freq;
1446 	roam_status = eCSR_ROAM_EXT_CHG_CHNL_IND;
1447 	roam_result = eCSR_ROAM_EXT_CHG_CHNL_UPDATE_IND;
1448 	sme_debug("sapdfs: Received eWNI_SME_EXT_CHANGE_CHANNEL_IND for session id [%d]",
1449 		 session_id);
1450 
1451 	/* Indicate Ext Channel Change event to SAP */
1452 	csr_roam_call_callback(mac_ctx, session_id, roam_info,
1453 			       roam_status, roam_result);
1454 	qdf_mem_free(roam_info);
1455 	return status;
1456 }
1457 
1458 #ifdef FEATURE_WLAN_ESE
1459 /**
1460  * sme_update_is_ese_feature_enabled() - enable/disable ESE support at runtime
1461  * @mac_handle: Opaque handle to the global MAC context
1462  * @sessionId: session id
1463  * @isEseIniFeatureEnabled: ese ini enabled
1464  *
1465  * It is used at in the REG_DYNAMIC_VARIABLE macro definition of
1466  * isEseIniFeatureEnabled. This is a synchronous call
1467  *
1468  * Return: QDF_STATUS enumeration
1469  */
sme_update_is_ese_feature_enabled(mac_handle_t mac_handle,uint8_t sessionId,const bool isEseIniFeatureEnabled)1470 QDF_STATUS sme_update_is_ese_feature_enabled(mac_handle_t mac_handle,
1471 			uint8_t sessionId, const bool isEseIniFeatureEnabled)
1472 {
1473 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
1474 	QDF_STATUS status;
1475 
1476 	if (mac->mlme_cfg->lfr.ese_enabled ==
1477 	    isEseIniFeatureEnabled) {
1478 		sme_debug("ESE Mode is already enabled or disabled, nothing to do (returning) old(%d) new(%d)",
1479 			  mac->mlme_cfg->lfr.ese_enabled, isEseIniFeatureEnabled);
1480 		return QDF_STATUS_SUCCESS;
1481 	}
1482 
1483 	sme_debug("vdev %d EseEnabled is changed from %d to %d", sessionId,
1484 		  mac->mlme_cfg->lfr.ese_enabled, isEseIniFeatureEnabled);
1485 	mac->mlme_cfg->lfr.ese_enabled = isEseIniFeatureEnabled;
1486 	mlme_set_supplicant_disabled_roaming(mac->psoc, sessionId,
1487 					     !isEseIniFeatureEnabled);
1488 	if (isEseIniFeatureEnabled)
1489 		wlan_cm_roam_state_change(mac->pdev, sessionId,
1490 					  WLAN_ROAM_RSO_ENABLED,
1491 					  REASON_CONNECT);
1492 	else
1493 		wlan_cm_roam_state_change(mac->pdev, sessionId,
1494 				WLAN_ROAM_RSO_STOPPED,
1495 				REASON_SUPPLICANT_DISABLED_ROAMING);
1496 
1497 	if (true == isEseIniFeatureEnabled)
1498 		mac->mlme_cfg->lfr.fast_transition_enabled = true;
1499 
1500 	if (mac->mlme_cfg->lfr.roam_scan_offload_enabled) {
1501 		status = sme_acquire_global_lock(&mac->sme);
1502 		if (QDF_IS_STATUS_SUCCESS(status)) {
1503 			wlan_roam_update_cfg(mac->psoc, sessionId,
1504 					    REASON_ESE_INI_CFG_CHANGED);
1505 			sme_release_global_lock(&mac->sme);
1506 		} else {
1507 			return status;
1508 		}
1509 	}
1510 	return QDF_STATUS_SUCCESS;
1511 }
1512 
sme_set_plm_request(mac_handle_t mac_handle,struct plm_req_params * req)1513 QDF_STATUS sme_set_plm_request(mac_handle_t mac_handle,
1514 			       struct plm_req_params *req)
1515 {
1516 	QDF_STATUS status;
1517 	bool ret = false;
1518 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
1519 	uint32_t ch_freq_list[CFG_VALID_CHANNEL_LIST_LEN] = { 0 };
1520 	uint8_t count, valid_count = 0;
1521 	struct scheduler_msg msg = {0};
1522 	struct csr_roam_session *session;
1523 	struct plm_req_params *body;
1524 	uint32_t ch_freq;
1525 
1526 	if (!req)
1527 		return QDF_STATUS_E_FAILURE;
1528 
1529 	status = sme_acquire_global_lock(&mac->sme);
1530 	if (!QDF_IS_STATUS_SUCCESS(status))
1531 		return status;
1532 
1533 	session = CSR_GET_SESSION(mac, req->vdev_id);
1534 	if (!session) {
1535 		sme_err("session for vdev %d not found", req->vdev_id);
1536 		sme_release_global_lock(&mac->sme);
1537 		return QDF_STATUS_E_FAILURE;
1538 	}
1539 
1540 	if (!session->sessionActive) {
1541 		sme_err("Invalid vdev %d", req->vdev_id);
1542 		sme_release_global_lock(&mac->sme);
1543 		return QDF_STATUS_E_FAILURE;
1544 	}
1545 
1546 	/* per contract must make a copy of the params when messaging */
1547 	body = qdf_mem_malloc(sizeof(*body));
1548 
1549 	if (!body) {
1550 		sme_release_global_lock(&mac->sme);
1551 		return QDF_STATUS_E_NOMEM;
1552 	}
1553 
1554 	*body = *req;
1555 
1556 	if (!body->enable)
1557 		goto send_plm_start;
1558 	/* validating channel numbers */
1559 	for (count = 0; count < body->plm_num_ch; count++) {
1560 		ch_freq = body->plm_ch_freq_list[count];
1561 		ret = csr_is_supported_channel(mac, ch_freq);
1562 		if (!ret) {
1563 			/* Not supported, ignore the channel */
1564 			sme_debug("Unsupported freq %d ignored for PLM",
1565 				  ch_freq);
1566 			continue;
1567 		}
1568 
1569 		if (ch_freq > 2477) {
1570 			enum channel_state state =
1571 				wlan_reg_get_channel_state_for_pwrmode(
1572 					mac->pdev, ch_freq,
1573 					REG_CURRENT_PWR_MODE);
1574 
1575 			if (state == CHANNEL_STATE_DFS) {
1576 				/* DFS channel is provided, no PLM bursts can be
1577 				 * transmitted. Ignoring these channels.
1578 				 */
1579 				sme_debug("DFS channel %d ignored for PLM",
1580 					  ch_freq);
1581 				continue;
1582 			}
1583 		}
1584 		ch_freq_list[valid_count++] = ch_freq;
1585 	} /* End of for () */
1586 
1587 	/* Copying back the valid channel list to plm struct */
1588 	qdf_mem_zero(body->plm_ch_freq_list, body->plm_num_ch);
1589 	if (valid_count)
1590 		qdf_mem_copy(body->plm_ch_freq_list, ch_freq_list, valid_count);
1591 	/* All are invalid channels, FW need to send the PLM
1592 	 *  report with "incapable" bit set.
1593 	 */
1594 	body->plm_num_ch = valid_count;
1595 
1596 send_plm_start:
1597 	/* PLM START */
1598 	msg.type = WMA_SET_PLM_REQ;
1599 	msg.reserved = 0;
1600 	msg.bodyptr = body;
1601 
1602 	if (!QDF_IS_STATUS_SUCCESS(scheduler_post_message(QDF_MODULE_ID_SME,
1603 							  QDF_MODULE_ID_WMA,
1604 							  QDF_MODULE_ID_WMA,
1605 							  &msg))) {
1606 		sme_err("Not able to post WMA_SET_PLM_REQ to WMA");
1607 		sme_release_global_lock(&mac->sme);
1608 		qdf_mem_free(body);
1609 		return QDF_STATUS_E_FAILURE;
1610 	}
1611 
1612 	sme_release_global_lock(&mac->sme);
1613 	return QDF_STATUS_SUCCESS;
1614 }
1615 
1616 /**
1617  * sme_tsm_ie_ind() - sme tsm ie indication
1618  * @mac: Global mac context
1619  * @pSmeTsmIeInd: Pointer to tsm ie indication
1620  *
1621  * Handle the tsm ie indication from  LIM and forward it to HDD.
1622  *
1623  * Return: QDF_STATUS enumeration
1624  */
sme_tsm_ie_ind(struct mac_context * mac,struct tsm_ie_ind * pSmeTsmIeInd)1625 static QDF_STATUS sme_tsm_ie_ind(struct mac_context *mac,
1626 				 struct tsm_ie_ind *pSmeTsmIeInd)
1627 {
1628 	QDF_STATUS status = QDF_STATUS_SUCCESS;
1629 	struct csr_roam_info *roam_info;
1630 	uint32_t SessionId = pSmeTsmIeInd->sessionId;
1631 
1632 	roam_info = qdf_mem_malloc(sizeof(*roam_info));
1633 	if (!roam_info)
1634 		return QDF_STATUS_E_NOMEM;
1635 
1636 	roam_info->tsm_ie.tsid = pSmeTsmIeInd->tsm_ie.tsid;
1637 	roam_info->tsm_ie.state = pSmeTsmIeInd->tsm_ie.state;
1638 	roam_info->tsm_ie.msmt_interval = pSmeTsmIeInd->tsm_ie.msmt_interval;
1639 	/* forward the tsm ie information to HDD */
1640 	csr_roam_call_callback(mac, SessionId, roam_info,
1641 			       eCSR_ROAM_TSM_IE_IND, 0);
1642 	qdf_mem_free(roam_info);
1643 	return status;
1644 }
1645 
1646 /**
1647  * sme_set_ese_beacon_request() - set ese beacon request
1648  * @mac_handle: Opaque handle to the global MAC context
1649  * @sessionId: session id
1650  * @in_req: Ese beacon report request
1651  *
1652  * function to set ESE beacon request parameters
1653  *
1654  * Return: QDF_STATUS enumeration
1655  */
sme_set_ese_beacon_request(mac_handle_t mac_handle,const uint8_t sessionId,const tCsrEseBeaconReq * in_req)1656 QDF_STATUS sme_set_ese_beacon_request(mac_handle_t mac_handle,
1657 				      const uint8_t sessionId,
1658 				      const tCsrEseBeaconReq *in_req)
1659 {
1660 	QDF_STATUS status;
1661 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
1662 	tpSirBeaconReportReqInd sme_bcn_rpt_req = NULL;
1663 	const tCsrEseBeaconReqParams *bcn_req = NULL;
1664 	uint8_t counter = 0;
1665 	tpRrmSMEContext sme_rrm_ctx = &mac->rrm.rrmSmeContext[0];
1666 
1667 	if (sme_rrm_ctx->eseBcnReqInProgress == true) {
1668 		sme_err("A Beacon Report Req is already in progress");
1669 		return QDF_STATUS_E_RESOURCES;
1670 	}
1671 
1672 	/* Store the info in RRM context */
1673 	qdf_mem_copy(&sme_rrm_ctx->eseBcnReqInfo, in_req,
1674 		     sizeof(tCsrEseBeaconReq));
1675 
1676 	/* Prepare the request to send to SME. */
1677 	sme_bcn_rpt_req = qdf_mem_malloc(sizeof(tSirBeaconReportReqInd));
1678 	if (!sme_bcn_rpt_req)
1679 		return QDF_STATUS_E_NOMEM;
1680 
1681 	sme_rrm_ctx->eseBcnReqInProgress = true;
1682 
1683 	sme_debug("Sending Beacon Report Req to SME");
1684 
1685 	sme_bcn_rpt_req->messageType = eWNI_SME_BEACON_REPORT_REQ_IND;
1686 	sme_bcn_rpt_req->length = sizeof(tSirBeaconReportReqInd);
1687 	wlan_mlme_get_bssid_vdev_id(mac->pdev, sessionId,
1688 				    (struct qdf_mac_addr *)&sme_bcn_rpt_req->bssId);
1689 	sme_bcn_rpt_req->channel_info.chan_num = 255;
1690 	sme_bcn_rpt_req->channel_list.num_channels = in_req->numBcnReqIe;
1691 	sme_bcn_rpt_req->msgSource = eRRM_MSG_SOURCE_ESE_UPLOAD;
1692 	sme_bcn_rpt_req->measurement_idx = 0;
1693 
1694 	for (counter = 0; counter < in_req->numBcnReqIe; counter++) {
1695 		bcn_req = &in_req->bcnReq[counter];
1696 		sme_bcn_rpt_req->fMeasurementtype[counter] =
1697 			bcn_req->scanMode;
1698 		sme_bcn_rpt_req->measurementDuration[counter] =
1699 			SYS_TU_TO_MS(bcn_req->measurementDuration);
1700 		sme_bcn_rpt_req->channel_list.chan_freq_lst[counter] =
1701 			bcn_req->ch_freq;
1702 	}
1703 
1704 	status = sme_rrm_process_beacon_report_req_ind(mac, sme_bcn_rpt_req);
1705 
1706 	if (status != QDF_STATUS_SUCCESS)
1707 		sme_rrm_ctx->eseBcnReqInProgress = false;
1708 
1709 	qdf_mem_free(sme_bcn_rpt_req);
1710 
1711 	return status;
1712 }
1713 
1714 /**
1715  * sme_get_tsm_stats() - SME get tsm stats
1716  * @mac_handle: Opaque handle to the global MAC context
1717  * @callback: SME sends back the requested stats using the callback
1718  * @staId: The station ID for which the stats is requested for
1719  * @bssId: bssid
1720  * @pContext: user context to be passed back along with the callback
1721  * @tid: Traffic id
1722  *
1723  * API register a callback to get TSM Stats.
1724  *
1725  * Return: QDF_STATUS enumeration
1726  */
sme_get_tsm_stats(mac_handle_t mac_handle,tCsrTsmStatsCallback callback,struct qdf_mac_addr bssId,void * pContext,uint8_t tid)1727 QDF_STATUS sme_get_tsm_stats(mac_handle_t mac_handle,
1728 			     tCsrTsmStatsCallback callback,
1729 			     struct qdf_mac_addr bssId,
1730 			     void *pContext, uint8_t tid)
1731 {
1732 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
1733 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
1734 
1735 	status = sme_acquire_global_lock(&mac->sme);
1736 	if (QDF_IS_STATUS_SUCCESS(status)) {
1737 		status = csr_get_tsm_stats(mac, callback,
1738 					   bssId, pContext,
1739 					   tid);
1740 		sme_release_global_lock(&mac->sme);
1741 	}
1742 	return status;
1743 }
1744 #endif /* FEATURE_WLAN_ESE */
1745 
1746 #ifdef WLAN_FEATURE_ROAM_OFFLOAD
sme_get_roam_scan_ch(mac_handle_t mac_handle,uint8_t vdev_id,void * pcontext)1747 QDF_STATUS sme_get_roam_scan_ch(mac_handle_t mac_handle,
1748 				uint8_t vdev_id, void *pcontext)
1749 {
1750 	struct scheduler_msg msg = {0};
1751 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
1752 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
1753 
1754 	status = sme_acquire_global_lock(&mac->sme);
1755 	if (QDF_IS_STATUS_ERROR(status))
1756 		return QDF_STATUS_E_FAILURE;
1757 
1758 	msg.type = WMA_ROAM_SCAN_CH_REQ;
1759 	msg.bodyval = vdev_id;
1760 	mac->sme.roam_scan_ch_get_context = pcontext;
1761 
1762 	if (scheduler_post_message(QDF_MODULE_ID_SME,
1763 				   QDF_MODULE_ID_WMA,
1764 				   QDF_MODULE_ID_WMA,
1765 				   &msg)) {
1766 		sme_err("Posting message %d failed",
1767 			WMA_ROAM_SCAN_CH_REQ);
1768 		mac->sme.roam_scan_ch_get_context = NULL;
1769 		sme_release_global_lock(&mac->sme);
1770 		return QDF_STATUS_E_FAILURE;
1771 	}
1772 
1773 	sme_release_global_lock(&mac->sme);
1774 	return QDF_STATUS_SUCCESS;
1775 }
1776 #endif
1777 
1778 /**
1779  * sme_process_dual_mac_config_resp() - Process set Dual mac config response
1780  * @mac: Global MAC pointer
1781  * @msg: Dual mac config response
1782  *
1783  * Processes the dual mac configuration response and invokes the HDD callback
1784  * to process further
1785  */
sme_process_dual_mac_config_resp(struct mac_context * mac,uint8_t * msg)1786 static QDF_STATUS sme_process_dual_mac_config_resp(struct mac_context *mac,
1787 		uint8_t *msg)
1788 {
1789 	tListElem *entry = NULL;
1790 	tSmeCmd *command = NULL;
1791 	bool found;
1792 	dual_mac_cb callback = NULL;
1793 	struct sir_dual_mac_config_resp *param;
1794 
1795 	param = (struct sir_dual_mac_config_resp *)msg;
1796 	if (!param) {
1797 		sme_err("Dual mac config resp param is NULL");
1798 		/* Not returning. Need to check if active command list
1799 		 * needs to be freed
1800 		 */
1801 	}
1802 
1803 	entry = csr_nonscan_active_ll_peek_head(mac, LL_ACCESS_LOCK);
1804 	if (!entry) {
1805 		sme_err("No cmd found in active list");
1806 		return QDF_STATUS_E_FAILURE;
1807 	}
1808 
1809 	command = GET_BASE_ADDR(entry, tSmeCmd, Link);
1810 	if (!command) {
1811 		sme_err("Base address is NULL");
1812 		return QDF_STATUS_E_FAILURE;
1813 	}
1814 
1815 	if (e_sme_command_set_dual_mac_config != command->command) {
1816 		sme_err("Command mismatch!");
1817 		return QDF_STATUS_E_FAILURE;
1818 	}
1819 
1820 	callback = command->u.set_dual_mac_cmd.set_dual_mac_cb;
1821 	if (callback) {
1822 		if (!param) {
1823 			sme_err("Callback failed-Dual mac config is NULL");
1824 		} else {
1825 			sme_debug("Calling HDD callback for Dual mac config");
1826 			callback(param->status,
1827 				command->u.set_dual_mac_cmd.scan_config,
1828 				command->u.set_dual_mac_cmd.fw_mode_config);
1829 		}
1830 	} else {
1831 		sme_err("Callback does not exist");
1832 	}
1833 
1834 	found = csr_nonscan_active_ll_remove_entry(mac, entry, LL_ACCESS_LOCK);
1835 	if (found)
1836 		/* Now put this command back on the available command list */
1837 		csr_release_command(mac, command);
1838 
1839 	return QDF_STATUS_SUCCESS;
1840 }
1841 
1842 #ifdef WLAN_FEATURE_ROAM_OFFLOAD
sme_set_roam_scan_ch_event_cb(mac_handle_t mac_handle,sme_get_raom_scan_ch_callback cb)1843 QDF_STATUS sme_set_roam_scan_ch_event_cb(mac_handle_t mac_handle,
1844 					 sme_get_raom_scan_ch_callback cb)
1845 {
1846 	QDF_STATUS qdf_status;
1847 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
1848 
1849 	qdf_status = sme_acquire_global_lock(&mac->sme);
1850 	if (QDF_IS_STATUS_ERROR(qdf_status))
1851 		return qdf_status;
1852 
1853 	mac->sme.roam_scan_ch_callback = cb;
1854 	sme_release_global_lock(&mac->sme);
1855 
1856 	return qdf_status;
1857 }
1858 
1859 /**
1860  * sme_process_roam_scan_ch_list_resp() - Process get roam scan ch list
1861  * response
1862  * @mac: Global MAC pointer
1863  * @msgbuf: pointer to roam scan ch list response
1864  *
1865  * This function checks the roam scan chan list message is for command
1866  * response or a async event and accordingly data is given to user space.
1867  * callback to process further
1868  */
1869 static void
sme_process_roam_scan_ch_list_resp(struct mac_context * mac,struct roam_scan_ch_resp * roam_ch)1870 sme_process_roam_scan_ch_list_resp(struct mac_context *mac,
1871 				   struct roam_scan_ch_resp *roam_ch)
1872 {
1873 	sme_get_raom_scan_ch_callback callback =
1874 				mac->sme.roam_scan_ch_callback;
1875 
1876 	if (!roam_ch)
1877 		return;
1878 
1879 	if (callback)
1880 		callback(mac->hdd_handle, roam_ch,
1881 			 mac->sme.roam_scan_ch_get_context);
1882 }
1883 #else
1884 static void
sme_process_roam_scan_ch_list_resp(tpAniSirGlobal mac,struct roam_scan_ch_resp * roam_ch)1885 sme_process_roam_scan_ch_list_resp(tpAniSirGlobal mac,
1886 				   struct roam_scan_ch_resp *roam_ch)
1887 {
1888 }
1889 #endif
1890 
1891 /**
1892  * sme_process_antenna_mode_resp() - Process set antenna mode
1893  * response
1894  * @mac: Global MAC pointer
1895  * @msg: antenna mode response
1896  *
1897  * Processes the antenna mode response and invokes the HDD
1898  * callback to process further
1899  */
sme_process_antenna_mode_resp(struct mac_context * mac,uint8_t * msg)1900 static QDF_STATUS sme_process_antenna_mode_resp(struct mac_context *mac,
1901 		uint8_t *msg)
1902 {
1903 	tListElem *entry;
1904 	tSmeCmd *command;
1905 	bool found;
1906 	void *context = NULL;
1907 	antenna_mode_cb callback;
1908 	struct sir_antenna_mode_resp *param;
1909 
1910 	param = (struct sir_antenna_mode_resp *)msg;
1911 	if (!param)
1912 		sme_err("set antenna mode resp is NULL");
1913 		/* Not returning. Need to check if active command list
1914 		 * needs to be freed
1915 		 */
1916 
1917 	entry = csr_nonscan_active_ll_peek_head(mac, LL_ACCESS_LOCK);
1918 	if (!entry) {
1919 		sme_err("No cmd found in active list");
1920 		return QDF_STATUS_E_FAILURE;
1921 	}
1922 
1923 	command = GET_BASE_ADDR(entry, tSmeCmd, Link);
1924 	if (!command) {
1925 		sme_err("Base address is NULL");
1926 		return QDF_STATUS_E_FAILURE;
1927 	}
1928 
1929 	if (e_sme_command_set_antenna_mode != command->command) {
1930 		sme_err("Command mismatch!");
1931 		return QDF_STATUS_E_FAILURE;
1932 	}
1933 
1934 	context = command->u.set_antenna_mode_cmd.set_antenna_mode_ctx;
1935 	callback = command->u.set_antenna_mode_cmd.set_antenna_mode_resp;
1936 	if (callback) {
1937 		if (!param)
1938 			sme_err("Set antenna mode call back is NULL");
1939 		else
1940 			callback(param->status, context);
1941 	} else {
1942 		sme_err("Callback does not exist");
1943 	}
1944 
1945 	found = csr_nonscan_active_ll_remove_entry(mac, entry, LL_ACCESS_LOCK);
1946 	if (found)
1947 		/* Now put this command back on the available command list */
1948 		csr_release_command(mac, command);
1949 
1950 	return QDF_STATUS_SUCCESS;
1951 }
1952 
1953 #ifdef WLAN_SUPPORT_TWT
1954 /**
1955  * sme_sap_twt_is_command_in_progress() - Based on the input peer mac address
1956  * invoke the appropriate function to check if the given command is in progress
1957  * @psoc: Pointer to psoc object
1958  * @vdev_id: Vdev id
1959  * @peer_mac: Peer MAC address
1960  * @dialog_id: Dialog id
1961  * @cmd: command
1962  *
1963  * If the input @peer_mac is a broadcast MAC address then the expectation is
1964  * to iterate through the list of all peers and check for any given @dialog_id
1965  * if the command @cmd is in progress.
1966  * Note: If @peer_mac is broadcast MAC address then @dialog_id shall always
1967  * be TWT_ALL_SESSIONS_DIALOG_ID.
1968  * For ex: If TWT teardown command is issued on a particular @dialog_id and
1969  * non-broadcast peer mac and FW response is not yet received then for that
1970  * particular @dialog_id and @peer_mac, TWT teardown is the active command,
1971  * then if the driver receives another TWT teardown request with broadcast
1972  * peer mac, then API mlme_twt_any_peer_cmd_in_progress() shall iterate
1973  * through the list of all peers and returns command in progress as true.
1974  *
1975  * If the input @peer_mac is a non-broadcast MAC address then
1976  * mlme_sap_twt_peer_is_cmd_in_progress() shall check only for that
1977  * particular @peer_mac and @dialog_id.
1978  *
1979  * Return: true if command is in progress, false otherwise
1980  */
1981 static bool
sme_sap_twt_is_command_in_progress(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id,struct qdf_mac_addr * peer_mac,uint8_t dialog_id,enum wlan_twt_commands cmd)1982 sme_sap_twt_is_command_in_progress(struct wlan_objmgr_psoc *psoc,
1983 				   uint8_t vdev_id,
1984 				   struct qdf_mac_addr *peer_mac,
1985 				   uint8_t dialog_id,
1986 				   enum wlan_twt_commands cmd)
1987 {
1988 	if (qdf_is_macaddr_broadcast(peer_mac)) {
1989 		return mlme_twt_any_peer_cmd_in_progress(psoc, vdev_id,
1990 							 dialog_id, cmd);
1991 	} else {
1992 		return mlme_sap_twt_peer_is_cmd_in_progress(psoc, peer_mac,
1993 							    dialog_id, cmd);
1994 	}
1995 }
1996 
1997 /**
1998  * sme_sap_add_twt_session() - Based on the input peer mac address
1999  * invoke the appropriate function to add dialog_id to the TWT session context
2000  * @psoc: Pointer to psoc object
2001  * @vdev_id: Vdev id
2002  * @peer_mac: Peer MAC address
2003  * @dialog_id: Dialog id
2004  *
2005  * If the input @peer_mac is a broadcast MAC address then there is nothing
2006  * to do, because the initialized structure is already in the expected format
2007  * Note: If @peer_mac is broadcast MAC address then @dialog_id shall always
2008  * be TWT_ALL_SESSIONS_DIALOG_ID.
2009  *
2010  * If the input @peer_mac is a non-broadcast MAC address then
2011  * mlme_add_twt_session() shall add the @dialog_id to the @peer_mac
2012  * TWT session context.
2013  *
2014  * Return: None
2015  */
2016 static void
sme_sap_add_twt_session(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id,struct qdf_mac_addr * peer_mac,uint8_t dialog_id)2017 sme_sap_add_twt_session(struct wlan_objmgr_psoc *psoc,
2018 			uint8_t vdev_id,
2019 			struct qdf_mac_addr *peer_mac,
2020 			uint8_t dialog_id)
2021 {
2022 	if (!qdf_is_macaddr_broadcast(peer_mac))
2023 		mlme_add_twt_session(psoc, peer_mac, dialog_id);
2024 }
2025 
2026 /**
2027  * sme_sap_set_twt_command_in_progress() - Based on the input peer mac address
2028  * invoke the appropriate function to set the command is in progress
2029  * @psoc: Pointer to psoc object
2030  * @vdev_id: Vdev id
2031  * @peer_mac: Peer MAC address
2032  * @dialog_id: Dialog id
2033  * @cmd: command
2034  *
2035  * If the input @peer_mac is a broadcast MAC address then the expectation is
2036  * to iterate through the list of all peers and set the active command to @cmd
2037  * for the given @dialog_id
2038  * Note: If @peer_mac is broadcast MAC address then @dialog_id shall always
2039  * be TWT_ALL_SESSIONS_DIALOG_ID.
2040  * For ex: If TWT teardown command is issued on broadcast @peer_mac, then
2041  * it is same as issuing TWT teardown for all the peers (all TWT sessions).
2042  * Invoking mlme_sap_set_twt_all_peers_cmd_in_progress() shall iterate through
2043  * all the peers and set the active command to @cmd.
2044  *
2045  * If the input @peer_mac is a non-broadcast MAC address then
2046  * mlme_set_twt_command_in_progress() shall set the active command to @cmd
2047  * only for that particular @peer_mac and @dialog_id.
2048  *
2049  * Return: QDF_STATUS
2050  */
2051 static QDF_STATUS
sme_sap_set_twt_command_in_progress(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id,struct qdf_mac_addr * peer_mac,uint8_t dialog_id,enum wlan_twt_commands cmd)2052 sme_sap_set_twt_command_in_progress(struct wlan_objmgr_psoc *psoc,
2053 				    uint8_t vdev_id,
2054 				    struct qdf_mac_addr *peer_mac,
2055 				    uint8_t dialog_id,
2056 				    enum wlan_twt_commands cmd)
2057 {
2058 	if (qdf_is_macaddr_broadcast(peer_mac)) {
2059 		return mlme_sap_set_twt_all_peers_cmd_in_progress(psoc,
2060 								  vdev_id,
2061 								  dialog_id,
2062 								  cmd);
2063 	} else {
2064 		return mlme_set_twt_command_in_progress(psoc, peer_mac,
2065 							dialog_id, cmd);
2066 	}
2067 }
2068 
2069 /**
2070  * sme_sap_init_twt_context() - Based on the input peer mac address
2071  * invoke the appropriate function to initialize the TWT session context
2072  * @psoc: Pointer to psoc object
2073  * @vdev_id: Vdev id
2074  * @peer_mac: Peer MAC address
2075  * @dialog_id: Dialog id
2076  *
2077  * If the input @peer_mac is a broadcast MAC address then the expectation is
2078  * to iterate through the list of all peers and initialize the TWT session
2079  * context
2080  * Note: If @peer_mac is broadcast MAC address then @dialog_id shall always
2081  * be TWT_ALL_SESSIONS_DIALOG_ID.
2082  * For ex: If TWT teardown command is issued on broadcast @peer_mac, then
2083  * it is same as issuing TWT teardown for all the peers (all TWT sessions).
2084  * Then active command for all the peers is set to @WLAN_TWT_TERMINATE.
2085  * Upon receiving the TWT teardown WMI event, mlme_init_all_peers_twt_context()
2086  * shall iterate through the list of all peers and initializes the TWT session
2087  * context back to its initial state.
2088  *
2089  * If the input @peer_mac is a non-broadcast MAC address then
2090  * mlme_init_twt_context() shall initialize the TWT session context
2091  * only for that particular @peer_mac and @dialog_id.
2092  *
2093  * Return: QDF_STATUS
2094  */
2095 static QDF_STATUS
sme_sap_init_twt_context(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id,struct qdf_mac_addr * peer_mac,uint8_t dialog_id)2096 sme_sap_init_twt_context(struct wlan_objmgr_psoc *psoc,
2097 			 uint8_t vdev_id,
2098 			 struct qdf_mac_addr *peer_mac,
2099 			 uint8_t dialog_id)
2100 {
2101 	if (qdf_is_macaddr_broadcast(peer_mac)) {
2102 		return mlme_init_all_peers_twt_context(psoc, vdev_id,
2103 						       dialog_id);
2104 	} else {
2105 		return mlme_init_twt_context(psoc, peer_mac, dialog_id);
2106 	}
2107 }
2108 
2109 /**
2110  * sme_process_twt_add_renego_failure() - Process TWT re-negotiation failure
2111  *
2112  * @mac: Global MAC pointer
2113  * @add_dialog_event: pointer to event buf containing twt response parameters
2114  *
2115  * Return: None
2116  */
2117 static void
sme_process_twt_add_renego_failure(struct mac_context * mac,struct wma_twt_add_dialog_complete_event * add_dialog_event)2118 sme_process_twt_add_renego_failure(struct mac_context *mac,
2119 				 struct wma_twt_add_dialog_complete_event *add_dialog_event)
2120 {
2121 	twt_add_dialog_cb callback;
2122 
2123 	/* Reset the active TWT command to none */
2124 	mlme_set_twt_command_in_progress(
2125 		mac->psoc,
2126 		(struct qdf_mac_addr *)add_dialog_event->params.peer_macaddr,
2127 		add_dialog_event->params.dialog_id, WLAN_TWT_NONE);
2128 
2129 	callback = mac->sme.twt_add_dialog_cb;
2130 	if (callback)
2131 		callback(mac->psoc, add_dialog_event, true);
2132 }
2133 
2134 /**
2135  * sme_process_twt_add_initial_nego() - Process initial TWT setup or
2136  * re-negotiation successful setup
2137  * @mac: Global MAC pointer
2138  * @add_dialog_event: pointer to event buf containing twt response parameters
2139  *
2140  * Return: None
2141  */
2142 static void
sme_process_twt_add_initial_nego(struct mac_context * mac,struct wma_twt_add_dialog_complete_event * add_dialog_event)2143 sme_process_twt_add_initial_nego(struct mac_context *mac,
2144 				 struct wma_twt_add_dialog_complete_event *add_dialog_event)
2145 {
2146 	twt_add_dialog_cb callback;
2147 
2148 	callback = mac->sme.twt_add_dialog_cb;
2149 	if (callback)
2150 		callback(mac->psoc, add_dialog_event, false);
2151 
2152 	/* Reset the active TWT command to none */
2153 	mlme_set_twt_command_in_progress(
2154 		mac->psoc,
2155 		(struct qdf_mac_addr *)add_dialog_event->params.peer_macaddr,
2156 		add_dialog_event->params.dialog_id, WLAN_TWT_NONE);
2157 
2158 	if (add_dialog_event->params.status) {
2159 		/* Clear the stored TWT dialog ID as TWT setup failed */
2160 		ucfg_mlme_init_twt_context(mac->psoc, (struct qdf_mac_addr *)
2161 					   add_dialog_event->params.peer_macaddr,
2162 					   add_dialog_event->params.dialog_id);
2163 		return;
2164 	}
2165 
2166 	ucfg_mlme_set_twt_setup_done(mac->psoc, (struct qdf_mac_addr *)
2167 				     add_dialog_event->params.peer_macaddr,
2168 				     add_dialog_event->params.dialog_id, true);
2169 
2170 	ucfg_mlme_set_twt_session_state(
2171 		mac->psoc,
2172 		(struct qdf_mac_addr *)add_dialog_event->params.peer_macaddr,
2173 		add_dialog_event->params.dialog_id,
2174 		WLAN_TWT_SETUP_STATE_ACTIVE);
2175 }
2176 
2177 /**
2178  * sme_process_twt_add_dialog_event() - Process twt add dialog event
2179  * response from firmware
2180  * @mac: Global MAC pointer
2181  * @add_dialog_event: pointer to event buf containing twt response parameters
2182  *
2183  * Return: None
2184  */
2185 static void
sme_process_twt_add_dialog_event(struct mac_context * mac,struct wma_twt_add_dialog_complete_event * add_dialog_event)2186 sme_process_twt_add_dialog_event(struct mac_context *mac,
2187 				 struct wma_twt_add_dialog_complete_event
2188 				 *add_dialog_event)
2189 {
2190 	bool is_evt_allowed;
2191 	bool setup_done;
2192 	enum WMI_HOST_ADD_TWT_STATUS status = add_dialog_event->params.status;
2193 	enum wlan_twt_commands active_cmd = WLAN_TWT_NONE;
2194 	enum QDF_OPMODE opmode;
2195 	QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
2196 	twt_add_dialog_cb callback;
2197 
2198 	opmode = wlan_get_opmode_from_vdev_id(mac->pdev,
2199 					      add_dialog_event->params.vdev_id);
2200 
2201 	qdf_status = sme_acquire_global_lock(&mac->sme);
2202 	if (QDF_IS_STATUS_ERROR(qdf_status))
2203 		return;
2204 
2205 	switch (opmode) {
2206 	case QDF_SAP_MODE:
2207 		callback = mac->sme.twt_add_dialog_cb;
2208 		if (callback)
2209 			callback(mac->psoc, add_dialog_event, false);
2210 		break;
2211 	case QDF_STA_MODE:
2212 		is_evt_allowed = mlme_twt_is_command_in_progress(
2213 					mac->psoc, (struct qdf_mac_addr *)
2214 					add_dialog_event->params.peer_macaddr,
2215 					add_dialog_event->params.dialog_id,
2216 					WLAN_TWT_SETUP,	&active_cmd);
2217 
2218 		if (!is_evt_allowed) {
2219 			sme_debug("Drop TWT add dialog event for dialog_id:%d status:%d active_cmd:%d",
2220 				  add_dialog_event->params.dialog_id, status,
2221 				  active_cmd);
2222 			sme_release_global_lock(&mac->sme);
2223 			return;
2224 		}
2225 
2226 		setup_done = ucfg_mlme_is_twt_setup_done(
2227 					mac->psoc, (struct qdf_mac_addr *)
2228 					add_dialog_event->params.peer_macaddr,
2229 					add_dialog_event->params.dialog_id);
2230 		sme_debug("setup_done:%d status:%d", setup_done, status);
2231 
2232 		if (setup_done && status) {
2233 			/*This is re-negotiation failure case */
2234 			sme_process_twt_add_renego_failure(mac,
2235 							   add_dialog_event);
2236 		} else {
2237 			sme_process_twt_add_initial_nego(mac,
2238 							 add_dialog_event);
2239 		}
2240 		break;
2241 	default:
2242 		sme_debug("TWT Setup is not supported on %s",
2243 			  qdf_opmode_str(opmode));
2244 	}
2245 
2246 	sme_release_global_lock(&mac->sme);
2247 	return;
2248 }
2249 
2250 static bool
sme_is_twt_teardown_failed(enum WMI_HOST_DEL_TWT_STATUS teardown_status)2251 sme_is_twt_teardown_failed(enum WMI_HOST_DEL_TWT_STATUS teardown_status)
2252 {
2253 	switch (teardown_status) {
2254 	case WMI_HOST_DEL_TWT_STATUS_DIALOG_ID_NOT_EXIST:
2255 	case WMI_HOST_DEL_TWT_STATUS_INVALID_PARAM:
2256 	case WMI_HOST_DEL_TWT_STATUS_DIALOG_ID_BUSY:
2257 	case WMI_HOST_DEL_TWT_STATUS_NO_RESOURCE:
2258 	case WMI_HOST_DEL_TWT_STATUS_NO_ACK:
2259 	case WMI_HOST_DEL_TWT_STATUS_UNKNOWN_ERROR:
2260 		return true;
2261 	default:
2262 		return false;
2263 	}
2264 
2265 	return false;
2266 }
2267 
2268 static void
sme_process_sta_twt_del_dialog_event(struct mac_context * mac,struct wmi_twt_del_dialog_complete_event_param * param)2269 sme_process_sta_twt_del_dialog_event(
2270 		struct mac_context *mac,
2271 		struct wmi_twt_del_dialog_complete_event_param *param)
2272 {
2273 	twt_del_dialog_cb callback;
2274 	bool is_evt_allowed, usr_cfg_ps_enable;
2275 	enum wlan_twt_commands active_cmd = WLAN_TWT_NONE;
2276 
2277 	is_evt_allowed = mlme_twt_is_command_in_progress(
2278 					mac->psoc, (struct qdf_mac_addr *)
2279 					param->peer_macaddr, param->dialog_id,
2280 					WLAN_TWT_TERMINATE, &active_cmd);
2281 
2282 	if (!is_evt_allowed &&
2283 	    param->dialog_id != TWT_ALL_SESSIONS_DIALOG_ID &&
2284 	    param->status != WMI_HOST_DEL_TWT_STATUS_ROAMING &&
2285 	    param->status != WMI_HOST_DEL_TWT_STATUS_PEER_INIT_TEARDOWN &&
2286 	    param->status != WMI_HOST_DEL_TWT_STATUS_CONCURRENCY) {
2287 		sme_debug("Drop TWT Del dialog event for dialog_id:%d status:%d active_cmd:%d",
2288 			  param->dialog_id, param->status, active_cmd);
2289 
2290 		return;
2291 	}
2292 
2293 	usr_cfg_ps_enable = mlme_get_user_ps(mac->psoc, param->vdev_id);
2294 	if (!usr_cfg_ps_enable &&
2295 	    param->status == WMI_HOST_DEL_TWT_STATUS_OK)
2296 		param->status = WMI_HOST_DEL_TWT_STATUS_PS_DISABLE_TEARDOWN;
2297 
2298 	callback = mac->sme.twt_del_dialog_cb;
2299 	if (callback)
2300 		callback(mac->psoc, param);
2301 
2302 	if (param->status == WMI_HOST_DEL_TWT_STATUS_ROAMING ||
2303 	    param->status == WMI_HOST_DEL_TWT_STATUS_CONCURRENCY)
2304 		mlme_twt_set_wait_for_notify(mac->psoc, param->vdev_id, true);
2305 
2306 	/* Reset the active TWT command to none */
2307 	mlme_set_twt_command_in_progress(mac->psoc, (struct qdf_mac_addr *)
2308 					 param->peer_macaddr, param->dialog_id,
2309 					 WLAN_TWT_NONE);
2310 
2311 	if (sme_is_twt_teardown_failed(param->status))
2312 		return;
2313 
2314 	ucfg_mlme_set_twt_setup_done(mac->psoc, (struct qdf_mac_addr *)
2315 				     param->peer_macaddr, param->dialog_id,
2316 				     false);
2317 
2318 	ucfg_mlme_set_twt_session_state(mac->psoc, (struct qdf_mac_addr *)
2319 					param->peer_macaddr, param->dialog_id,
2320 					WLAN_TWT_SETUP_STATE_NOT_ESTABLISHED);
2321 
2322 	mlme_init_twt_context(mac->psoc, (struct qdf_mac_addr *)
2323 			      param->peer_macaddr, param->dialog_id);
2324 }
2325 
2326 /**
2327  * sme_process_twt_del_dialog_event() - Process twt del dialog event
2328  * response from firmware
2329  * @mac: Global MAC pointer
2330  * @param: pointer to wmi_twt_del_dialog_complete_event_param buffer
2331  *
2332  * Return: None
2333  */
2334 static void
sme_process_twt_del_dialog_event(struct mac_context * mac,struct wmi_twt_del_dialog_complete_event_param * param)2335 sme_process_twt_del_dialog_event(
2336 	struct mac_context *mac,
2337 	struct wmi_twt_del_dialog_complete_event_param *param)
2338 {
2339 	twt_del_dialog_cb callback;
2340 	enum QDF_OPMODE opmode;
2341 	QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
2342 
2343 	opmode = wlan_get_opmode_from_vdev_id(mac->pdev, param->vdev_id);
2344 
2345 	qdf_status = sme_acquire_global_lock(&mac->sme);
2346 	if (QDF_IS_STATUS_ERROR(qdf_status))
2347 		return;
2348 
2349 	switch (opmode) {
2350 	case QDF_SAP_MODE:
2351 		callback = mac->sme.twt_del_dialog_cb;
2352 		if (callback)
2353 			callback(mac->psoc, param);
2354 
2355 		/*
2356 		 * If this is an unsolicited TWT del event initiated from the
2357 		 * peer, then no need to clear the active command in progress
2358 		 */
2359 		if (param->status !=
2360 		    WMI_HOST_DEL_TWT_STATUS_PEER_INIT_TEARDOWN) {
2361 			/* Reset the active TWT command to none */
2362 			sme_sap_set_twt_command_in_progress(mac->psoc,
2363 				param->vdev_id,
2364 				(struct qdf_mac_addr *)param->peer_macaddr,
2365 				param->dialog_id, WLAN_TWT_NONE);
2366 			sme_sap_init_twt_context(mac->psoc, param->vdev_id,
2367 				      (struct qdf_mac_addr *)
2368 				      param->peer_macaddr, param->dialog_id);
2369 		}
2370 		break;
2371 	case QDF_STA_MODE:
2372 		sme_process_sta_twt_del_dialog_event(mac, param);
2373 		break;
2374 	default:
2375 		sme_debug("TWT Teardown is not supported on %s",
2376 			  qdf_opmode_str(opmode));
2377 	}
2378 
2379 	sme_release_global_lock(&mac->sme);
2380 	return;
2381 }
2382 
2383 /**
2384  * sme_process_twt_pause_dialog_event() - Process twt pause dialog event
2385  * response from firmware
2386  * @mac: Global MAC pointer
2387  * @param: pointer to wmi_twt_pause_dialog_complete_event_param buffer
2388  *
2389  * Return: None
2390  */
2391 static void
sme_process_twt_pause_dialog_event(struct mac_context * mac,struct wmi_twt_pause_dialog_complete_event_param * param)2392 sme_process_twt_pause_dialog_event(
2393 		struct mac_context *mac,
2394 		struct wmi_twt_pause_dialog_complete_event_param *param)
2395 {
2396 	twt_pause_dialog_cb callback;
2397 	enum QDF_OPMODE opmode;
2398 	QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
2399 
2400 	opmode = wlan_get_opmode_from_vdev_id(mac->pdev, param->vdev_id);
2401 
2402 	qdf_status = sme_acquire_global_lock(&mac->sme);
2403 	if (QDF_IS_STATUS_ERROR(qdf_status))
2404 		return;
2405 
2406 	switch (opmode) {
2407 	case QDF_SAP_MODE:
2408 		callback = mac->sme.twt_pause_dialog_cb;
2409 		if (callback)
2410 			callback(mac->psoc, param);
2411 		break;
2412 	case QDF_STA_MODE:
2413 		callback = mac->sme.twt_pause_dialog_cb;
2414 		if (callback)
2415 			callback(mac->psoc, param);
2416 
2417 		ucfg_mlme_set_twt_session_state(
2418 					mac->psoc, (struct qdf_mac_addr *)
2419 					param->peer_macaddr, param->dialog_id,
2420 					WLAN_TWT_SETUP_STATE_SUSPEND);
2421 
2422 		/*Reset the active TWT command to none */
2423 		mlme_set_twt_command_in_progress(
2424 					mac->psoc, (struct qdf_mac_addr *)
2425 					param->peer_macaddr, param->dialog_id,
2426 					WLAN_TWT_NONE);
2427 		break;
2428 	default:
2429 		sme_debug("TWT Pause is not supported on %s",
2430 			  qdf_opmode_str(opmode));
2431 	}
2432 
2433 	sme_release_global_lock(&mac->sme);
2434 	return;
2435 }
2436 
2437 /**
2438  * sme_process_twt_nudge_dialog_event() - Process twt nudge dialog event
2439  * response from firmware
2440  * @mac: Global MAC pointer
2441  * @param: pointer to wmi_twt_nudge_dialog_complete_event_param buffer
2442  *
2443  * Return: None
2444  */
2445 static void
sme_process_twt_nudge_dialog_event(struct mac_context * mac,struct wmi_twt_nudge_dialog_complete_event_param * param)2446 sme_process_twt_nudge_dialog_event(struct mac_context *mac,
2447 			struct wmi_twt_nudge_dialog_complete_event_param *param)
2448 {
2449 	twt_nudge_dialog_cb callback;
2450 	bool is_evt_allowed;
2451 	enum wlan_twt_commands active_cmd = WLAN_TWT_NONE;
2452 	enum QDF_OPMODE opmode;
2453 	QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
2454 
2455 	opmode = wlan_get_opmode_from_vdev_id(mac->pdev, param->vdev_id);
2456 
2457 	qdf_status = sme_acquire_global_lock(&mac->sme);
2458 	if (QDF_IS_STATUS_ERROR(qdf_status))
2459 		return;
2460 
2461 	switch (opmode) {
2462 	case QDF_SAP_MODE:
2463 		callback = mac->sme.twt_nudge_dialog_cb;
2464 		if (callback)
2465 			callback(mac->psoc, param);
2466 		break;
2467 	case QDF_STA_MODE:
2468 		is_evt_allowed = mlme_twt_is_command_in_progress(
2469 					mac->psoc, (struct qdf_mac_addr *)
2470 					param->peer_macaddr, param->dialog_id,
2471 					WLAN_TWT_NUDGE, &active_cmd);
2472 		if (!is_evt_allowed &&
2473 		    param->dialog_id != TWT_ALL_SESSIONS_DIALOG_ID) {
2474 			sme_debug("Nudge event dropped active_cmd:%d",
2475 				  active_cmd);
2476 			goto fail;
2477 		}
2478 
2479 		callback = mac->sme.twt_nudge_dialog_cb;
2480 		if (callback)
2481 			callback(mac->psoc, param);
2482 		/* Reset the active TWT command to none */
2483 		mlme_set_twt_command_in_progress(
2484 					mac->psoc, (struct qdf_mac_addr *)
2485 					param->peer_macaddr, param->dialog_id,
2486 					WLAN_TWT_NONE);
2487 		break;
2488 	default:
2489 		sme_debug("TWT Nudge is not supported on %s",
2490 			  qdf_opmode_str(opmode));
2491 	}
2492 
2493 fail:
2494 	sme_release_global_lock(&mac->sme);
2495 	return;
2496 }
2497 
2498 /**
2499  * sme_process_twt_resume_dialog_event() - Process twt resume dialog event
2500  * response from firmware
2501  * @mac: Global MAC pointer
2502  * @param: pointer to wmi_twt_resume_dialog_complete_event_param buffer
2503  *
2504  * Return: None
2505  */
2506 static void
sme_process_twt_resume_dialog_event(struct mac_context * mac,struct wmi_twt_resume_dialog_complete_event_param * param)2507 sme_process_twt_resume_dialog_event(
2508 		struct mac_context *mac,
2509 		struct wmi_twt_resume_dialog_complete_event_param *param)
2510 {
2511 	twt_resume_dialog_cb callback;
2512 	QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
2513 	enum QDF_OPMODE opmode;
2514 
2515 	opmode = wlan_get_opmode_from_vdev_id(mac->pdev, param->vdev_id);
2516 
2517 	qdf_status = sme_acquire_global_lock(&mac->sme);
2518 	if (QDF_IS_STATUS_ERROR(qdf_status))
2519 		return;
2520 
2521 	switch (opmode) {
2522 	case QDF_SAP_MODE:
2523 		callback = mac->sme.twt_resume_dialog_cb;
2524 		if (callback)
2525 			callback(mac->psoc, param);
2526 		break;
2527 	case QDF_STA_MODE:
2528 		callback = mac->sme.twt_resume_dialog_cb;
2529 		if (callback)
2530 			callback(mac->psoc, param);
2531 
2532 		ucfg_mlme_set_twt_session_state(
2533 					mac->psoc, (struct qdf_mac_addr *)
2534 					param->peer_macaddr, param->dialog_id,
2535 					WLAN_TWT_SETUP_STATE_ACTIVE);
2536 
2537 		/* Reset the active TWT command to none */
2538 		mlme_set_twt_command_in_progress(
2539 					mac->psoc, (struct qdf_mac_addr *)
2540 					param->peer_macaddr, param->dialog_id,
2541 					WLAN_TWT_NONE);
2542 		break;
2543 	default:
2544 		sme_debug("TWT Resume is not supported on %s",
2545 			  qdf_opmode_str(opmode));
2546 	}
2547 
2548 	sme_release_global_lock(&mac->sme);
2549 	return;
2550 }
2551 
2552 /**
2553  * sme_process_twt_notify_event() - Process twt ready for setup notification
2554  * event from firmware
2555  * @mac: Global MAC pointer
2556  * @twt_notify_event: pointer to event buf containing twt notify parameters
2557  *
2558  * Return: None
2559  */
2560 static void
sme_process_twt_notify_event(struct mac_context * mac,struct wmi_twt_notify_event_param * notify_event)2561 sme_process_twt_notify_event(struct mac_context *mac,
2562 			     struct wmi_twt_notify_event_param *notify_event)
2563 {
2564 	twt_notify_cb callback;
2565 
2566 	mlme_twt_set_wait_for_notify(mac->psoc, notify_event->vdev_id, false);
2567 	callback = mac->sme.twt_notify_cb;
2568 	if (callback)
2569 		callback(mac->psoc, notify_event);
2570 }
2571 
2572 /**
2573  * sme_twt_update_beacon_template() - API to send beacon update to fw
2574  * @mac: Global MAC pointer
2575  *
2576  * Return: None
2577  */
sme_twt_update_beacon_template(mac_handle_t mac_handle)2578 void sme_twt_update_beacon_template(mac_handle_t mac_handle)
2579 {
2580 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
2581 
2582 	csr_update_beacon(mac);
2583 }
2584 
2585 #else
2586 static void
sme_process_twt_add_dialog_event(struct mac_context * mac,struct wma_twt_add_dialog_complete_event * add_dialog_event)2587 sme_process_twt_add_dialog_event(struct mac_context *mac,
2588 				 struct wma_twt_add_dialog_complete_event *add_dialog_event)
2589 {
2590 }
2591 
2592 static void
sme_process_twt_del_dialog_event(struct mac_context * mac,struct wmi_twt_del_dialog_complete_event_param * param)2593 sme_process_twt_del_dialog_event(
2594 		struct mac_context *mac,
2595 		struct wmi_twt_del_dialog_complete_event_param *param)
2596 {
2597 }
2598 
2599 static void
sme_process_twt_pause_dialog_event(struct mac_context * mac,struct wmi_twt_pause_dialog_complete_event_param * param)2600 sme_process_twt_pause_dialog_event(struct mac_context *mac,
2601 				   struct wmi_twt_pause_dialog_complete_event_param *param)
2602 {
2603 }
2604 
2605 static void
sme_process_twt_resume_dialog_event(struct mac_context * mac,struct wmi_twt_resume_dialog_complete_event_param * param)2606 sme_process_twt_resume_dialog_event(struct mac_context *mac,
2607 				    struct wmi_twt_resume_dialog_complete_event_param *param)
2608 {
2609 }
2610 
2611 static void
sme_process_twt_nudge_dialog_event(struct mac_context * mac,struct wmi_twt_nudge_dialog_complete_event_param * param)2612 sme_process_twt_nudge_dialog_event(struct mac_context *mac,
2613 				   struct wmi_twt_nudge_dialog_complete_event_param *param)
2614 {
2615 }
2616 
2617 static void
sme_process_twt_notify_event(struct mac_context * mac,struct wmi_twt_notify_event_param * notify_event)2618 sme_process_twt_notify_event(struct mac_context *mac,
2619 			     struct wmi_twt_notify_event_param *notify_event)
2620 {
2621 }
2622 #endif
2623 
sme_link_lost_ind(struct mac_context * mac,struct sir_lost_link_info * ind)2624 static void sme_link_lost_ind(struct mac_context *mac,
2625 				    struct sir_lost_link_info *ind)
2626 {
2627 	struct cm_roam_values_copy src_cfg = {};
2628 
2629 	if (ind) {
2630 		src_cfg.int_value = ind->rssi;
2631 		wlan_cm_roam_cfg_set_value(mac->psoc, ind->vdev_id,
2632 					   LOST_LINK_RSSI, &src_cfg);
2633 	}
2634 	if (mac->sme.lost_link_info_cb)
2635 		mac->sme.lost_link_info_cb(mac->hdd_handle, ind);
2636 }
2637 
2638 #ifdef WLAN_FEATURE_SAP_ACS_OPTIMIZE
sme_indicate_chan_info_event(struct mac_context * mac,struct channel_status * chan_stats,uint8_t vdev_id)2639 static void sme_indicate_chan_info_event(struct mac_context *mac,
2640 					 struct channel_status *chan_stats,
2641 					 uint8_t vdev_id)
2642 {
2643 	struct csr_roam_info *roam_info;
2644 	struct wlan_objmgr_vdev *vdev;
2645 	eRoamCmdStatus roam_status;
2646 	eCsrRoamResult roam_result;
2647 	enum QDF_OPMODE mode;
2648 
2649 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac->psoc, vdev_id,
2650 						    WLAN_LEGACY_SME_ID);
2651 	if (!vdev) {
2652 		sme_err("vdev not found for vdev %d", vdev_id);
2653 		return;
2654 	}
2655 
2656 	mode = wlan_vdev_mlme_get_opmode(vdev);
2657 	wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID);
2658 
2659 	if (mode != QDF_SAP_MODE)
2660 		return;
2661 
2662 	roam_info = qdf_mem_malloc(sizeof(*roam_info));
2663 	if (!roam_info)
2664 		return;
2665 
2666 	roam_info->chan_info_freq = chan_stats->channel_freq;
2667 	roam_status = eCSR_ROAM_CHANNEL_INFO_EVENT_IND;
2668 	roam_result = eCSR_ROAM_RESULT_NONE;
2669 
2670 	/* Indicate channel info event to SAP */
2671 	csr_roam_call_callback(mac, vdev_id, roam_info,
2672 			       roam_status, roam_result);
2673 
2674 	qdf_mem_free(roam_info);
2675 }
2676 #else
sme_indicate_chan_info_event(struct mac_context * mac,struct channel_status * chan_stats,uint8_t vdev_id)2677 static void sme_indicate_chan_info_event(struct mac_context *mac,
2678 					 struct channel_status *chan_stats,
2679 					 uint8_t vdev_id)
2680 {
2681 }
2682 #endif
2683 
sme_process_chan_info_event(struct mac_context * mac,struct channel_status * chan_stats,uint8_t vdev_id)2684 static void sme_process_chan_info_event(struct mac_context *mac,
2685 					struct channel_status *chan_stats,
2686 					uint8_t vdev_id)
2687 {
2688 	if (!chan_stats) {
2689 		sme_err("Chan info report is NULL\n");
2690 		return;
2691 	}
2692 
2693 	wlan_cp_stats_update_chan_info(mac->psoc, chan_stats, vdev_id);
2694 
2695 	sme_indicate_chan_info_event(mac, chan_stats, vdev_id);
2696 }
2697 
2698 /**
2699  * sme_process_sap_ch_width_update_rsp() - Process ch_width update response
2700  * @mac: Global MAC pointer
2701  * @msg: ch_width update response
2702  *
2703  * Processes the ch_width update response and invokes the HDD
2704  * callback to process further
2705  */
2706 static QDF_STATUS
sme_process_sap_ch_width_update_rsp(struct mac_context * mac,uint8_t * msg)2707 sme_process_sap_ch_width_update_rsp(struct mac_context *mac, uint8_t *msg)
2708 {
2709 	tListElem *entry = NULL;
2710 	tSmeCmd *command = NULL;
2711 	bool found;
2712 	struct sir_bcn_update_rsp *param;
2713 	enum policy_mgr_conn_update_reason reason;
2714 	uint32_t request_id;
2715 	uint8_t vdev_id;
2716 	QDF_STATUS status = QDF_STATUS_E_NOMEM;
2717 
2718 	param = (struct sir_bcn_update_rsp *)msg;
2719 	if (!param)
2720 		sme_err("ch_width update resp param is NULL");
2721 		/* Not returning. Need to check if active command list
2722 		 * needs to be freed
2723 		 */
2724 
2725 	if (param && param->reason != REASON_CH_WIDTH_UPDATE) {
2726 		sme_err("reason not ch_width update");
2727 		return QDF_STATUS_E_INVAL;
2728 	}
2729 	entry = csr_nonscan_active_ll_peek_head(mac, LL_ACCESS_LOCK);
2730 	if (!entry) {
2731 		sme_err("No cmd found in active list");
2732 		return QDF_STATUS_E_FAILURE;
2733 	}
2734 
2735 	command = GET_BASE_ADDR(entry, tSmeCmd, Link);
2736 	if (!command) {
2737 		sme_err("Base address is NULL");
2738 		return QDF_STATUS_E_FAILURE;
2739 	}
2740 
2741 	if (e_sme_command_sap_ch_width_update != command->command) {
2742 		sme_err("Command mismatch!");
2743 		return QDF_STATUS_E_FAILURE;
2744 	}
2745 	reason = command->u.bw_update_cmd.reason;
2746 	request_id = command->u.bw_update_cmd.request_id;
2747 	vdev_id = command->u.bw_update_cmd.conc_vdev_id;
2748 	if (param)
2749 		status = param->status;
2750 	sme_debug("vdev %d reason %d status %d cm_id 0x%x",
2751 		  vdev_id, reason, status, request_id);
2752 
2753 	if (reason == POLICY_MGR_UPDATE_REASON_CHANNEL_SWITCH_STA) {
2754 		sme_debug("Continue channel switch for STA on vdev %d",
2755 			  vdev_id);
2756 		csr_sta_continue_csa(mac, vdev_id);
2757 	} else if (reason == POLICY_MGR_UPDATE_REASON_STA_CONNECT) {
2758 		sme_debug("Continue connect/reassoc on vdev %d reason %d status %d cm_id 0x%x",
2759 			  vdev_id, reason, status, request_id);
2760 		wlan_cm_handle_hw_mode_change_resp(mac->pdev, vdev_id,
2761 						   request_id, status);
2762 	}
2763 
2764 	policy_mgr_set_connection_update(mac->psoc);
2765 
2766 	found = csr_nonscan_active_ll_remove_entry(mac, entry, LL_ACCESS_LOCK);
2767 	if (found) {
2768 		/* Now put this command back on the available command list */
2769 		csr_release_command(mac, command);
2770 	}
2771 
2772 	return QDF_STATUS_SUCCESS;
2773 }
2774 
sme_process_msg(struct mac_context * mac,struct scheduler_msg * pMsg)2775 QDF_STATUS sme_process_msg(struct mac_context *mac, struct scheduler_msg *pMsg)
2776 {
2777 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
2778 
2779 	if (!pMsg) {
2780 		sme_err("Empty message for SME");
2781 		return status;
2782 	}
2783 	status = sme_acquire_global_lock(&mac->sme);
2784 	if (!QDF_IS_STATUS_SUCCESS(status)) {
2785 		if (pMsg->bodyptr)
2786 			qdf_mem_free(pMsg->bodyptr);
2787 		return status;
2788 	}
2789 	if (!SME_IS_START(mac)) {
2790 		sme_debug("message type %d in stop state ignored", pMsg->type);
2791 		if (pMsg->bodyptr)
2792 			qdf_mem_free(pMsg->bodyptr);
2793 		goto release_lock;
2794 	}
2795 	switch (pMsg->type) {
2796 	case eWNI_SME_ADDTS_RSP:
2797 	case eWNI_SME_DELTS_RSP:
2798 	case eWNI_SME_DELTS_IND:
2799 	case eWNI_SME_FT_AGGR_QOS_RSP:
2800 		/* QoS */
2801 		if (pMsg->bodyptr) {
2802 #ifndef WLAN_MDM_CODE_REDUCTION_OPT
2803 			status = sme_qos_msg_processor(mac, pMsg->type,
2804 						       pMsg->bodyptr);
2805 			qdf_mem_free(pMsg->bodyptr);
2806 #endif
2807 		} else {
2808 			sme_err("Empty message for: %d", pMsg->type);
2809 		}
2810 		break;
2811 	case eWNI_SME_NEIGHBOR_REPORT_IND:
2812 	case eWNI_SME_BEACON_REPORT_REQ_IND:
2813 	case eWNI_SME_CHAN_LOAD_REQ_IND:
2814 		if (pMsg->bodyptr) {
2815 			status = sme_rrm_msg_processor(mac, pMsg->type,
2816 						       pMsg->bodyptr);
2817 			qdf_mem_free(pMsg->bodyptr);
2818 		} else {
2819 			sme_err("Empty message for: %d", pMsg->type);
2820 		}
2821 		break;
2822 	case eWNI_SME_VDEV_DELETE_RSP:
2823 		if (pMsg->bodyptr)
2824 			sme_vdev_self_peer_delete_resp(pMsg->bodyptr);
2825 		else
2826 			sme_err("Empty message for: %d", pMsg->type);
2827 		break;
2828 	case eWNI_SME_GENERIC_CHANGE_COUNTRY_CODE:
2829 		if (pMsg->bodyptr) {
2830 			status = sme_handle_generic_change_country_code(
2831 						(void *)mac, pMsg->bodyptr);
2832 			qdf_mem_free(pMsg->bodyptr);
2833 		} else {
2834 			sme_err("Empty message for: %d", pMsg->type);
2835 		}
2836 		break;
2837 	case eWNI_SME_UNPROT_MGMT_FRM_IND:
2838 		if (pMsg->bodyptr) {
2839 			sme_unprotected_mgmt_frm_ind(mac, pMsg->bodyptr);
2840 			qdf_mem_free(pMsg->bodyptr);
2841 		} else {
2842 			sme_err("Empty message for: %d", pMsg->type);
2843 		}
2844 		break;
2845 #ifdef FEATURE_WLAN_ESE
2846 	case eWNI_SME_TSM_IE_IND:
2847 		if (pMsg->bodyptr) {
2848 			sme_tsm_ie_ind(mac, pMsg->bodyptr);
2849 			qdf_mem_free(pMsg->bodyptr);
2850 		} else {
2851 			sme_err("Empty message for: %d", pMsg->type);
2852 		}
2853 		break;
2854 #endif /* FEATURE_WLAN_ESE */
2855 #ifdef WLAN_FEATURE_EXTWOW_SUPPORT
2856 	case eWNI_SME_READY_TO_EXTWOW_IND:
2857 		if (pMsg->bodyptr) {
2858 			sme_process_ready_to_ext_wow(mac, pMsg->bodyptr);
2859 			qdf_mem_free(pMsg->bodyptr);
2860 		} else {
2861 			sme_err("Empty message for: %d", pMsg->type);
2862 		}
2863 		break;
2864 #endif
2865 #ifdef FEATURE_WLAN_AUTO_SHUTDOWN
2866 	case eWNI_SME_AUTO_SHUTDOWN_IND:
2867 		if (mac->sme.auto_shutdown_cb) {
2868 			sme_debug("Auto shutdown notification");
2869 			mac->sme.auto_shutdown_cb();
2870 		}
2871 		break;
2872 #endif
2873 	case eWNI_SME_DFS_RADAR_FOUND:
2874 	case eWNI_SME_DFS_CAC_COMPLETE:
2875 	case eWNI_SME_DFS_CSAIE_TX_COMPLETE_IND:
2876 	case eWNI_SME_CSA_RESTART_RSP:
2877 		status = dfs_msg_processor(mac, pMsg);
2878 		qdf_mem_free(pMsg->bodyptr);
2879 		break;
2880 	case eWNI_SME_CHANNEL_CHANGE_RSP:
2881 		if (pMsg->bodyptr) {
2882 			status = sme_process_channel_change_resp(mac,
2883 								 pMsg->type,
2884 								 pMsg->bodyptr);
2885 			qdf_mem_free(pMsg->bodyptr);
2886 		} else {
2887 			sme_err("Empty message for: %d", pMsg->type);
2888 		}
2889 		break;
2890 	case eWNI_SME_STATS_EXT_EVENT:
2891 		status = sme_stats_ext_event(mac, pMsg->bodyptr);
2892 		qdf_mem_free(pMsg->bodyptr);
2893 		break;
2894 	case eWNI_SME_FW_STATUS_IND:
2895 		status = sme_fw_state_resp(mac);
2896 		break;
2897 	case eWNI_SME_TSF_EVENT:
2898 		if (mac->sme.get_tsf_cb) {
2899 			mac->sme.get_tsf_cb(mac->sme.get_tsf_cxt,
2900 					(struct stsf *)pMsg->bodyptr);
2901 		}
2902 		if (pMsg->bodyptr)
2903 			qdf_mem_free(pMsg->bodyptr);
2904 		break;
2905 	case eWNI_SME_LINK_STATUS_IND:
2906 	{
2907 		tAniGetLinkStatus *pLinkStatus =
2908 			(tAniGetLinkStatus *) pMsg->bodyptr;
2909 		if (pLinkStatus) {
2910 			if (mac->sme.link_status_callback)
2911 				mac->sme.link_status_callback(
2912 					pLinkStatus->linkStatus,
2913 					mac->sme.link_status_context);
2914 
2915 			mac->sme.link_status_callback = NULL;
2916 			mac->sme.link_status_context = NULL;
2917 			qdf_mem_free(pLinkStatus);
2918 		}
2919 		break;
2920 	}
2921 	case eWNI_SME_MSG_GET_TEMPERATURE_IND:
2922 		if (mac->sme.temperature_cb)
2923 			mac->sme.temperature_cb(pMsg->bodyval,
2924 					mac->sme.temperature_cb_context);
2925 		break;
2926 	case eWNI_SME_SNR_IND:
2927 	{
2928 		tAniGetSnrReq *pSnrReq = (tAniGetSnrReq *) pMsg->bodyptr;
2929 
2930 		if (pSnrReq) {
2931 			if (pSnrReq->snrCallback) {
2932 				((tCsrSnrCallback)
2933 				 (pSnrReq->snrCallback))(pSnrReq->snr,
2934 							 pSnrReq->pDevContext);
2935 			}
2936 			qdf_mem_free(pSnrReq);
2937 		}
2938 		break;
2939 	}
2940 #ifdef FEATURE_WLAN_EXTSCAN
2941 	case eWNI_SME_EXTSCAN_FULL_SCAN_RESULT_IND:
2942 		if (mac->sme.ext_scan_ind_cb)
2943 			mac->sme.ext_scan_ind_cb(mac->hdd_handle,
2944 					eSIR_EXTSCAN_FULL_SCAN_RESULT_IND,
2945 					pMsg->bodyptr);
2946 		else
2947 			sme_err("callback not registered to process: %d",
2948 				pMsg->type);
2949 
2950 		qdf_mem_free(pMsg->bodyptr);
2951 		break;
2952 	case eWNI_SME_EPNO_NETWORK_FOUND_IND:
2953 		if (mac->sme.ext_scan_ind_cb)
2954 			mac->sme.ext_scan_ind_cb(mac->hdd_handle,
2955 					eSIR_EPNO_NETWORK_FOUND_IND,
2956 					pMsg->bodyptr);
2957 		else
2958 			sme_err("callback not registered to process: %d",
2959 				pMsg->type);
2960 
2961 		qdf_mem_free(pMsg->bodyptr);
2962 		break;
2963 #endif
2964 	case eWNI_SME_SET_HW_MODE_RESP:
2965 		if (pMsg->bodyptr) {
2966 			status = sme_process_set_hw_mode_resp(mac,
2967 								pMsg->bodyptr);
2968 			qdf_mem_free(pMsg->bodyptr);
2969 		} else {
2970 			sme_err("Empty message for: %d", pMsg->type);
2971 		}
2972 		break;
2973 	case eWNI_SME_HW_MODE_TRANS_IND:
2974 		if (pMsg->bodyptr) {
2975 			status = sme_process_hw_mode_trans_ind(mac,
2976 								pMsg->bodyptr);
2977 			qdf_mem_free(pMsg->bodyptr);
2978 		} else {
2979 			sme_err("Empty message for: %d", pMsg->type);
2980 		}
2981 		break;
2982 	case eWNI_SME_NSS_UPDATE_RSP:
2983 		if (pMsg->bodyptr) {
2984 			status = sme_process_nss_update_resp(mac,
2985 								pMsg->bodyptr);
2986 			qdf_mem_free(pMsg->bodyptr);
2987 		} else {
2988 			sme_err("Empty message for: %d", pMsg->type);
2989 		}
2990 		break;
2991 	case eWNI_SME_SET_DUAL_MAC_CFG_RESP:
2992 		if (pMsg->bodyptr) {
2993 			status = sme_process_dual_mac_config_resp(mac,
2994 					pMsg->bodyptr);
2995 			qdf_mem_free(pMsg->bodyptr);
2996 		} else {
2997 			sme_err("Empty message for: %d", pMsg->type);
2998 		}
2999 		break;
3000 	case eWNI_SME_SET_THERMAL_LEVEL_IND:
3001 		if (mac->sme.set_thermal_level_cb)
3002 			mac->sme.set_thermal_level_cb(mac->hdd_handle,
3003 						       pMsg->bodyval);
3004 		break;
3005 	case eWNI_SME_EXT_CHANGE_CHANNEL_IND:
3006 		 status = sme_extended_change_channel_ind(mac, pMsg->bodyptr);
3007 		 qdf_mem_free(pMsg->bodyptr);
3008 		break;
3009 	case eWNI_SME_SET_ANTENNA_MODE_RESP:
3010 		if (pMsg->bodyptr) {
3011 			status = sme_process_antenna_mode_resp(mac,
3012 					pMsg->bodyptr);
3013 			qdf_mem_free(pMsg->bodyptr);
3014 		} else {
3015 			sme_err("Empty message for: %d", pMsg->type);
3016 		}
3017 		break;
3018 	case eWNI_SME_LOST_LINK_INFO_IND:
3019 		sme_link_lost_ind(mac, pMsg->bodyptr);
3020 		qdf_mem_free(pMsg->bodyptr);
3021 		break;
3022 	case eWNI_SME_RSO_CMD_STATUS_IND:
3023 		if (mac->sme.rso_cmd_status_cb)
3024 			mac->sme.rso_cmd_status_cb(mac->hdd_handle,
3025 						    pMsg->bodyptr);
3026 		qdf_mem_free(pMsg->bodyptr);
3027 		break;
3028 	case eWMI_SME_LL_STATS_IND:
3029 		if (mac->sme.link_layer_stats_ext_cb)
3030 			mac->sme.link_layer_stats_ext_cb(mac->hdd_handle,
3031 							  pMsg->bodyptr);
3032 		qdf_mem_free(pMsg->bodyptr);
3033 		break;
3034 	case eWNI_SME_BT_ACTIVITY_INFO_IND:
3035 		if (mac->sme.bt_activity_info_cb)
3036 			mac->sme.bt_activity_info_cb(mac->hdd_handle,
3037 						      pMsg->bodyval);
3038 		break;
3039 	case eWNI_SME_HIDDEN_SSID_RESTART_RSP:
3040 		if (mac->sme.hidden_ssid_cb)
3041 			mac->sme.hidden_ssid_cb(mac->hdd_handle, pMsg->bodyval);
3042 		else
3043 			sme_err("callback is NULL");
3044 		break;
3045 	case eWNI_SME_ANTENNA_ISOLATION_RSP:
3046 		if (pMsg->bodyptr) {
3047 			if (mac->sme.get_isolation_cb)
3048 				mac->sme.get_isolation_cb(
3049 				  (struct sir_isolation_resp *)pMsg->bodyptr,
3050 				  mac->sme.get_isolation_cb_context);
3051 			qdf_mem_free(pMsg->bodyptr);
3052 		} else {
3053 			sme_err("Empty message for: %d", pMsg->type);
3054 		}
3055 		break;
3056 	case eWNI_SME_GET_ROAM_SCAN_CH_LIST_EVENT:
3057 		sme_process_roam_scan_ch_list_resp(mac, pMsg->bodyptr);
3058 		qdf_mem_free(pMsg->bodyptr);
3059 		break;
3060 	case eWNI_SME_MONITOR_MODE_VDEV_UP:
3061 		status = sme_process_monitor_mode_vdev_up_evt(pMsg->bodyval);
3062 		break;
3063 	case eWNI_SME_TWT_ADD_DIALOG_EVENT:
3064 		sme_process_twt_add_dialog_event(mac, pMsg->bodyptr);
3065 		qdf_mem_free(pMsg->bodyptr);
3066 		break;
3067 	case eWNI_SME_TWT_DEL_DIALOG_EVENT:
3068 		sme_process_twt_del_dialog_event(mac, pMsg->bodyptr);
3069 		qdf_mem_free(pMsg->bodyptr);
3070 		break;
3071 	case eWNI_SME_TWT_PAUSE_DIALOG_EVENT:
3072 		sme_process_twt_pause_dialog_event(mac, pMsg->bodyptr);
3073 		qdf_mem_free(pMsg->bodyptr);
3074 		break;
3075 	case eWNI_SME_TWT_RESUME_DIALOG_EVENT:
3076 		sme_process_twt_resume_dialog_event(mac, pMsg->bodyptr);
3077 		qdf_mem_free(pMsg->bodyptr);
3078 		break;
3079 	case eWNI_SME_TWT_NUDGE_DIALOG_EVENT:
3080 		sme_process_twt_nudge_dialog_event(mac, pMsg->bodyptr);
3081 		qdf_mem_free(pMsg->bodyptr);
3082 		break;
3083 	case eWNI_SME_TWT_NOTIFY_EVENT:
3084 		sme_process_twt_notify_event(mac, pMsg->bodyptr);
3085 		qdf_mem_free(pMsg->bodyptr);
3086 		break;
3087 	case eWNI_SME_START_BSS_RSP:
3088 		csr_roam_roaming_state_start_bss_rsp_processor(mac,
3089 							       pMsg->bodyptr);
3090 		qdf_mem_free(pMsg->bodyptr);
3091 		break;
3092 	case eWNI_SME_STOP_BSS_RSP:
3093 		csr_roam_roaming_state_stop_bss_rsp_processor(mac,
3094 							      pMsg->bodyptr);
3095 		qdf_mem_free(pMsg->bodyptr);
3096 		break;
3097 	case eWNI_SME_CHAN_INFO_EVENT:
3098 		sme_process_chan_info_event(mac, pMsg->bodyptr, pMsg->bodyval);
3099 		qdf_mem_free(pMsg->bodyptr);
3100 		break;
3101 	case eWNI_SME_SAP_CH_WIDTH_UPDATE_RSP:
3102 		status = sme_process_sap_ch_width_update_rsp(mac,
3103 							     pMsg->bodyptr);
3104 		qdf_mem_free(pMsg->bodyptr);
3105 		break;
3106 	default:
3107 
3108 		if ((pMsg->type >= eWNI_SME_MSG_TYPES_BEGIN)
3109 		    && (pMsg->type <= eWNI_SME_MSG_TYPES_END)) {
3110 			/* CSR */
3111 			if (pMsg->bodyptr) {
3112 				status = csr_msg_processor(mac, pMsg->bodyptr);
3113 				qdf_mem_free(pMsg->bodyptr);
3114 			} else
3115 				sme_err("Empty message for: %d", pMsg->type);
3116 		} else {
3117 			sme_warn("Unknown message type: %d", pMsg->type);
3118 			if (pMsg->bodyptr)
3119 				qdf_mem_free(pMsg->bodyptr);
3120 		}
3121 	} /* switch */
3122 release_lock:
3123 	sme_release_global_lock(&mac->sme);
3124 	return status;
3125 }
3126 
sme_mc_process_handler(struct scheduler_msg * msg)3127 QDF_STATUS sme_mc_process_handler(struct scheduler_msg *msg)
3128 {
3129 	struct mac_context *mac_ctx = cds_get_context(QDF_MODULE_ID_SME);
3130 
3131 	if (!mac_ctx) {
3132 		QDF_ASSERT(0);
3133 		return QDF_STATUS_E_FAILURE;
3134 	}
3135 
3136 	return sme_process_msg(mac_ctx, msg);
3137 }
3138 
3139 /**
3140  * sme_process_nss_update_resp() - Process nss update response
3141  * @mac: Global MAC pointer
3142  * @msg: nss update response
3143  *
3144  * Processes the nss update response and invokes the HDD
3145  * callback to process further
3146  */
sme_process_nss_update_resp(struct mac_context * mac,uint8_t * msg)3147 static QDF_STATUS sme_process_nss_update_resp(struct mac_context *mac, uint8_t *msg)
3148 {
3149 	tListElem *entry = NULL;
3150 	tSmeCmd *command = NULL;
3151 	bool found;
3152 	policy_mgr_nss_update_cback callback = NULL;
3153 	struct sir_bcn_update_rsp *param;
3154 
3155 	param = (struct sir_bcn_update_rsp *)msg;
3156 	if (!param)
3157 		sme_err("nss update resp param is NULL");
3158 		/* Not returning. Need to check if active command list
3159 		 * needs to be freed
3160 		 */
3161 
3162 	if (param && param->reason != REASON_NSS_UPDATE) {
3163 		sme_err("reason not NSS update");
3164 		return QDF_STATUS_E_INVAL;
3165 	}
3166 	entry = csr_nonscan_active_ll_peek_head(mac, LL_ACCESS_LOCK);
3167 	if (!entry) {
3168 		sme_err("No cmd found in active list");
3169 		return QDF_STATUS_E_FAILURE;
3170 	}
3171 
3172 	command = GET_BASE_ADDR(entry, tSmeCmd, Link);
3173 	if (!command) {
3174 		sme_err("Base address is NULL");
3175 		return QDF_STATUS_E_FAILURE;
3176 	}
3177 
3178 	if (e_sme_command_nss_update != command->command) {
3179 		sme_err("Command mismatch!");
3180 		return QDF_STATUS_E_FAILURE;
3181 	}
3182 
3183 	callback = command->u.nss_update_cmd.nss_update_cb;
3184 	if (callback) {
3185 		if (!param)
3186 			sme_err("Callback failed since nss update params is NULL");
3187 		else
3188 			callback(command->u.nss_update_cmd.context,
3189 				param->status,
3190 				param->vdev_id,
3191 				command->u.nss_update_cmd.next_action,
3192 				command->u.nss_update_cmd.reason,
3193 				command->u.nss_update_cmd.original_vdev_id,
3194 				command->u.nss_update_cmd.request_id);
3195 	} else {
3196 		sme_err("Callback does not exist");
3197 	}
3198 
3199 	found = csr_nonscan_active_ll_remove_entry(mac, entry, LL_ACCESS_LOCK);
3200 	if (found) {
3201 		/* Now put this command back on the available command list */
3202 		csr_release_command(mac, command);
3203 	}
3204 
3205 	return QDF_STATUS_SUCCESS;
3206 }
3207 
sme_stop(mac_handle_t mac_handle)3208 QDF_STATUS sme_stop(mac_handle_t mac_handle)
3209 {
3210 	QDF_STATUS status;
3211 	QDF_STATUS ret_status = QDF_STATUS_SUCCESS;
3212 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
3213 
3214 	status = rrm_stop(mac);
3215 	if (QDF_IS_STATUS_ERROR(status)) {
3216 		ret_status = status;
3217 		sme_err("rrm_stop failed with status: %d", status);
3218 	}
3219 
3220 	status = csr_stop(mac);
3221 	if (QDF_IS_STATUS_ERROR(status)) {
3222 		ret_status = status;
3223 		sme_err("csr_stop failed with status: %d", status);
3224 	}
3225 
3226 	mac->sme.state = SME_STATE_STOP;
3227 
3228 	return ret_status;
3229 }
3230 
3231 /*
3232  * sme_close() - Release all SME modules and their resources.
3233  * The function release each module in SME, PMC, CSR, etc. . Upon
3234  *  return, all modules are at closed state.
3235  *
3236  *  No SME APIs can be involved after smeClose except smeOpen.
3237  *  smeClose must be called before mac_close.
3238  *  This is a synchronous call
3239  *
3240  * mac_handle - The handle returned by mac_open
3241  * Return QDF_STATUS_SUCCESS - SME is successfully close.
3242  *
3243  *  Other status means SME is failed to be closed but caller still cannot
3244  *  call any other SME functions except smeOpen.
3245  */
sme_close(mac_handle_t mac_handle)3246 QDF_STATUS sme_close(mac_handle_t mac_handle)
3247 {
3248 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
3249 	QDF_STATUS fail_status = QDF_STATUS_SUCCESS;
3250 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
3251 
3252 	if (!mac)
3253 		return QDF_STATUS_E_FAILURE;
3254 
3255 	sme_unregister_power_debug_stats_cb(mac);
3256 
3257 	status = csr_close(mac);
3258 	if (!QDF_IS_STATUS_SUCCESS(status)) {
3259 		sme_err("csr_close failed with status: %d", status);
3260 		fail_status = status;
3261 	}
3262 #ifndef WLAN_MDM_CODE_REDUCTION_OPT
3263 	status = sme_qos_close(mac);
3264 	if (!QDF_IS_STATUS_SUCCESS(status)) {
3265 		sme_err("Qos close failed with status: %d", status);
3266 		fail_status = status;
3267 	}
3268 #endif
3269 	status = sme_ps_close(mac_handle);
3270 	if (!QDF_IS_STATUS_SUCCESS(status)) {
3271 		sme_err("sme_ps_close failed status: %d", status);
3272 		fail_status = status;
3273 	}
3274 
3275 	status = rrm_close(mac);
3276 	if (!QDF_IS_STATUS_SUCCESS(status)) {
3277 		sme_err("RRM close failed with status: %d", status);
3278 		fail_status = status;
3279 	}
3280 
3281 	free_sme_cmd_list(mac);
3282 
3283 	status = qdf_mutex_destroy(&mac->sme.sme_global_lock);
3284 	if (!QDF_IS_STATUS_SUCCESS(status))
3285 		fail_status = QDF_STATUS_E_FAILURE;
3286 
3287 	mac->sme.state = SME_STATE_STOP;
3288 
3289 	return fail_status;
3290 }
3291 
sme_get_phy_mode(mac_handle_t mac_handle)3292 eCsrPhyMode sme_get_phy_mode(mac_handle_t mac_handle)
3293 {
3294 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
3295 
3296 	return mac->roam.configParam.phyMode;
3297 }
3298 
sme_get_network_params(struct mac_context * mac,struct bss_dot11_config * dot11_cfg)3299 QDF_STATUS sme_get_network_params(struct mac_context *mac,
3300 				  struct bss_dot11_config *dot11_cfg)
3301 {
3302 	enum csr_cfgdot11mode dot11_mode;
3303 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
3304 	bool chan_switch_hostapd_rate_enabled = true;
3305 	uint8_t mcc_to_scc_switch = 0;
3306 	enum QDF_OPMODE opmode;
3307 
3308 	if (!mac)
3309 		return status;
3310 
3311 	status = sme_acquire_global_lock(&mac->sme);
3312 	if (QDF_IS_STATUS_ERROR(status))
3313 		return status;
3314 
3315 	ucfg_mlme_get_sap_chan_switch_rate_enabled(mac->psoc,
3316 				&chan_switch_hostapd_rate_enabled);
3317 	ucfg_policy_mgr_get_mcc_scc_switch(mac->psoc,
3318 					   &mcc_to_scc_switch);
3319 
3320 	if (mcc_to_scc_switch != QDF_MCC_TO_SCC_SWITCH_DISABLE)
3321 		chan_switch_hostapd_rate_enabled = false;
3322 
3323 	opmode = wlan_get_opmode_from_vdev_id(mac->pdev,
3324 					      dot11_cfg->vdev_id);
3325 	dot11_mode =
3326 		csr_roam_get_phy_mode_band_for_bss(mac, dot11_cfg);
3327 
3328 	dot11_cfg->dot11_mode =
3329 		csr_translate_to_wni_cfg_dot11_mode(mac, dot11_mode);
3330 
3331 	dot11_cfg->nw_type =
3332 		csr_convert_mode_to_nw_type(dot11_mode, dot11_cfg->p_band);
3333 
3334 	/* If INI is enabled, use the rates from hostapd */
3335 	if (!cds_is_sub_20_mhz_enabled() && chan_switch_hostapd_rate_enabled &&
3336 	    (dot11_cfg->opr_rates.numRates || dot11_cfg->ext_rates.numRates)) {
3337 		sme_err("Use the rates from the hostapd");
3338 	} else { /* Populate new rates */
3339 		dot11_cfg->ext_rates.numRates = 0;
3340 		dot11_cfg->opr_rates.numRates = 0;
3341 
3342 		switch (dot11_cfg->nw_type) {
3343 		case eSIR_11A_NW_TYPE:
3344 			wlan_populate_basic_rates(&dot11_cfg->opr_rates,
3345 						  true, true);
3346 			break;
3347 		case eSIR_11B_NW_TYPE:
3348 			wlan_populate_basic_rates(&dot11_cfg->opr_rates,
3349 						  false, true);
3350 			break;
3351 		case eSIR_11G_NW_TYPE:
3352 			if ((opmode == QDF_P2P_CLIENT_MODE) ||
3353 			    (opmode == QDF_P2P_GO_MODE) ||
3354 			    (dot11_mode == eCSR_CFG_DOT11_MODE_11G_ONLY)) {
3355 				wlan_populate_basic_rates(&dot11_cfg->opr_rates,
3356 							  true, true);
3357 			} else {
3358 				wlan_populate_basic_rates(&dot11_cfg->opr_rates,
3359 							  false, true);
3360 				wlan_populate_basic_rates(&dot11_cfg->ext_rates,
3361 							  true, false);
3362 			}
3363 			break;
3364 		default:
3365 			sme_release_global_lock(&mac->sme);
3366 			sme_err("Unknown network type %d", dot11_cfg->nw_type);
3367 			return QDF_STATUS_E_FAILURE;
3368 		}
3369 	}
3370 
3371 	sme_release_global_lock(&mac->sme);
3372 	return QDF_STATUS_SUCCESS;
3373 }
3374 
sme_start_bss(mac_handle_t mac_handle,uint8_t vdev_id,struct start_bss_config * bss_config)3375 QDF_STATUS sme_start_bss(mac_handle_t mac_handle, uint8_t vdev_id,
3376 			 struct start_bss_config *bss_config)
3377 {
3378 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
3379 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
3380 
3381 	if (!mac)
3382 		return QDF_STATUS_E_FAILURE;
3383 
3384 	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
3385 			 TRACE_CODE_SME_RX_HDD_MSG_CONNECT, vdev_id, 0));
3386 
3387 	if (!CSR_IS_SESSION_VALID(mac, vdev_id)) {
3388 		sme_err("Invalid sessionID: %d", vdev_id);
3389 		return QDF_STATUS_E_INVAL;
3390 	}
3391 
3392 	status = sme_acquire_global_lock(&mac->sme);
3393 	if (QDF_IS_STATUS_ERROR(status))
3394 		return status;
3395 
3396 	status = csr_bss_start(mac, vdev_id, bss_config);
3397 	sme_release_global_lock(&mac->sme);
3398 
3399 	return status;
3400 }
3401 
3402 /*
3403  * sme_set_phy_mode() -
3404  * Changes the PhyMode.
3405  *
3406  * mac_handle - The handle returned by mac_open.
3407  * phyMode new phyMode which is to set
3408  * Return QDF_STATUS  SUCCESS.
3409  */
sme_set_phy_mode(mac_handle_t mac_handle,eCsrPhyMode phyMode)3410 QDF_STATUS sme_set_phy_mode(mac_handle_t mac_handle, eCsrPhyMode phyMode)
3411 {
3412 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
3413 
3414 	mac->roam.configParam.phyMode = phyMode;
3415 	mac->roam.configParam.uCfgDot11Mode =
3416 		csr_get_cfg_dot11_mode_from_csr_phy_mode(false,
3417 						mac->roam.configParam.phyMode);
3418 
3419 	return QDF_STATUS_SUCCESS;
3420 }
3421 
3422 /*
3423  * sme_get_11b_data_duration() -
3424  * returns 11b data duration via channel freq.
3425  *
3426  * mac_handle - The handle returned by mac_open.
3427  * chan_freq - channel frequency
3428  *
3429  * Return - 11b data duration on success else 0
3430  */
sme_get_11b_data_duration(mac_handle_t mac_handle,uint32_t chan_freq)3431 uint32_t sme_get_11b_data_duration(mac_handle_t mac_handle, uint32_t chan_freq)
3432 {
3433 	uint32_t rx_11b_data_duration = 0;
3434 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
3435 	struct channel_status *chan_status =
3436 		ucfg_mc_cp_stats_get_channel_status(mac->pdev, chan_freq);
3437 
3438 	if (chan_status)
3439 		rx_11b_data_duration = chan_status->rx_11b_mode_data_duration;
3440 
3441 	return rx_11b_data_duration;
3442 }
3443 
sme_roam_ndi_stop(mac_handle_t mac_handle,uint8_t vdev_id)3444 QDF_STATUS sme_roam_ndi_stop(mac_handle_t mac_handle, uint8_t vdev_id)
3445 {
3446 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
3447 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
3448 
3449 	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
3450 			 TRACE_CODE_SME_RX_HDD_ROAM_DISCONNECT, vdev_id,
3451 			 0));
3452 
3453 	if (!CSR_IS_SESSION_VALID(mac_ctx, vdev_id)) {
3454 		sme_debug("Invalid sessionID: %d", vdev_id);
3455 		return QDF_STATUS_E_INVAL;
3456 	}
3457 
3458 	status = sme_acquire_global_lock(&mac_ctx->sme);
3459 	if (QDF_IS_STATUS_ERROR(status))
3460 		return status;
3461 
3462 	status = csr_roam_ndi_stop(mac_ctx, vdev_id);
3463 	sme_release_global_lock(&mac_ctx->sme);
3464 
3465 	return status;
3466 }
3467 
3468 /* sme_dhcp_done_ind() - send dhcp done ind
3469  * @mac_handle: Opaque handle to the global MAC context
3470  * @session_id: session id
3471  *
3472  * Return: void.
3473  */
sme_dhcp_done_ind(mac_handle_t mac_handle,uint8_t session_id)3474 void sme_dhcp_done_ind(mac_handle_t mac_handle, uint8_t session_id)
3475 {
3476 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
3477 	struct csr_roam_session *session;
3478 
3479 	if (!mac_ctx)
3480 		return;
3481 
3482 	session = CSR_GET_SESSION(mac_ctx, session_id);
3483 	if (!session) {
3484 		sme_err("Session: %d not found", session_id);
3485 		return;
3486 	}
3487 	session->dhcp_done = true;
3488 }
3489 
sme_roam_stop_bss(mac_handle_t mac_handle,uint8_t vdev_id)3490 QDF_STATUS sme_roam_stop_bss(mac_handle_t mac_handle, uint8_t vdev_id)
3491 {
3492 	QDF_STATUS status;
3493 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
3494 
3495 	status = sme_acquire_global_lock(&mac->sme);
3496 	if (QDF_IS_STATUS_ERROR(status))
3497 		return status;
3498 
3499 	status = csr_roam_issue_stop_bss_cmd(mac, vdev_id,
3500 					     eCSR_BSS_TYPE_INFRA_AP);
3501 	sme_release_global_lock(&mac->sme);
3502 
3503 	return status;
3504 }
3505 
3506 /**
3507  * sme_roam_disconnect_sta() - disassociate a station
3508  * @mac_handle:          Global structure
3509  * @sessionId:     SessionId of SoftAP
3510  * @p_del_sta_params: Pointer to parameters of the station to disassoc
3511  *
3512  * To disassociate a station. This is an asynchronous API.
3513  *
3514  * Return: QDF_STATUS_SUCCESS on success.Roam callback will
3515  *         be called to indicate actual result.
3516  */
sme_roam_disconnect_sta(mac_handle_t mac_handle,uint8_t sessionId,struct csr_del_sta_params * p_del_sta_params)3517 QDF_STATUS sme_roam_disconnect_sta(mac_handle_t mac_handle, uint8_t sessionId,
3518 				   struct csr_del_sta_params *p_del_sta_params)
3519 {
3520 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
3521 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
3522 
3523 	if (!mac) {
3524 		QDF_ASSERT(0);
3525 		return status;
3526 	}
3527 
3528 	status = sme_acquire_global_lock(&mac->sme);
3529 	if (QDF_IS_STATUS_SUCCESS(status)) {
3530 		if (CSR_IS_SESSION_VALID(mac, sessionId))
3531 			status = csr_roam_issue_disassociate_sta_cmd(mac,
3532 					sessionId, p_del_sta_params);
3533 		else
3534 			status = QDF_STATUS_E_INVAL;
3535 		sme_release_global_lock(&mac->sme);
3536 	}
3537 
3538 	return status;
3539 }
3540 
3541 /**
3542  * sme_roam_deauth_sta() - deauthenticate a station
3543  * @mac_handle:          Global structure
3544  * @sessionId:     SessionId of SoftAP
3545  * @pDelStaParams: Pointer to parameters of the station to deauthenticate
3546  *
3547  * To disassociate a station. This is an asynchronous API.
3548  *
3549  * Return: QDF_STATUS_SUCCESS on success or another QDF_STATUS error
3550  *         code on error. Roam callback will be called to indicate actual
3551  *         result
3552  */
sme_roam_deauth_sta(mac_handle_t mac_handle,uint8_t sessionId,struct csr_del_sta_params * pDelStaParams)3553 QDF_STATUS sme_roam_deauth_sta(mac_handle_t mac_handle, uint8_t sessionId,
3554 			       struct csr_del_sta_params *pDelStaParams)
3555 {
3556 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
3557 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
3558 
3559 	if (!mac) {
3560 		QDF_ASSERT(0);
3561 		return status;
3562 	}
3563 
3564 	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
3565 			 TRACE_CODE_SME_RX_HDD_MSG_DEAUTH_STA,
3566 			 sessionId, pDelStaParams->reason_code));
3567 	status = sme_acquire_global_lock(&mac->sme);
3568 	if (QDF_IS_STATUS_SUCCESS(status)) {
3569 		if (CSR_IS_SESSION_VALID(mac, sessionId))
3570 			status =
3571 				csr_roam_issue_deauth_sta_cmd(mac, sessionId,
3572 							      pDelStaParams);
3573 		else
3574 			status = QDF_STATUS_E_INVAL;
3575 		sme_release_global_lock(&mac->sme);
3576 	}
3577 
3578 	return status;
3579 }
3580 
3581 #ifdef WLAN_FEATURE_ROAM_OFFLOAD
sme_get_pmk_info(mac_handle_t mac_handle,uint8_t session_id,struct wlan_crypto_pmksa * pmk_cache)3582 void sme_get_pmk_info(mac_handle_t mac_handle, uint8_t session_id,
3583 		      struct wlan_crypto_pmksa *pmk_cache)
3584 {
3585 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
3586 	QDF_STATUS status = sme_acquire_global_lock(&mac_ctx->sme);
3587 
3588 	if (QDF_IS_STATUS_SUCCESS(status)) {
3589 		if (CSR_IS_SESSION_VALID(mac_ctx, session_id))
3590 			csr_get_pmk_info(mac_ctx, session_id, pmk_cache);
3591 		sme_release_global_lock(&mac_ctx->sme);
3592 	}
3593 }
3594 #endif
3595 
3596 #ifdef WLAN_FEATURE_ROAM_OFFLOAD
3597 /*
3598  * sme_roam_set_psk_pmk() - a wrapper function to request CSR to save PSK/PMK
3599  * This is a synchronous call.
3600  * @mac_handle:  Global structure
3601  * @vdev_id:  vdev id
3602  * @pmksa : PMK entry
3603  * @update_to_fw: True - send RSO update to firmware after updating
3604  *                       session->psk_pmk.
3605  *                False - Copy the pmk to session->psk_pmk and return
3606  *
3607  * Return: QDF_STATUS - status whether PSK/PMK is set or not
3608  */
sme_roam_set_psk_pmk(mac_handle_t mac_handle,struct wlan_crypto_pmksa * pmksa,uint8_t vdev_id,bool update_to_fw)3609 QDF_STATUS sme_roam_set_psk_pmk(mac_handle_t mac_handle,
3610 				struct wlan_crypto_pmksa *pmksa,
3611 				uint8_t vdev_id, bool update_to_fw)
3612 {
3613 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
3614 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
3615 
3616 	status = sme_acquire_global_lock(&mac->sme);
3617 	if (QDF_IS_STATUS_SUCCESS(status)) {
3618 		if (CSR_IS_SESSION_VALID(mac, vdev_id))
3619 			status = csr_roam_set_psk_pmk(mac, pmksa, vdev_id,
3620 						      update_to_fw);
3621 		else
3622 			status = QDF_STATUS_E_INVAL;
3623 		sme_release_global_lock(&mac->sme);
3624 	}
3625 	return status;
3626 }
3627 
sme_set_pmk_cache_ft(mac_handle_t mac_handle,uint8_t vdev_id,struct wlan_crypto_pmksa * pmk_cache)3628 QDF_STATUS sme_set_pmk_cache_ft(mac_handle_t mac_handle, uint8_t vdev_id,
3629 				struct wlan_crypto_pmksa *pmk_cache)
3630 {
3631 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
3632 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
3633 
3634 	status = sme_acquire_global_lock(&mac->sme);
3635 	if (QDF_IS_STATUS_SUCCESS(status)) {
3636 		status = csr_set_pmk_cache_ft(mac, vdev_id, pmk_cache);
3637 		sme_release_global_lock(&mac->sme);
3638 	}
3639 	return status;
3640 }
3641 #endif
3642 
3643 /*
3644  * sme_get_config_param() -
3645  * A wrapper function that HDD calls to get the global settings
3646  *	currently maintained by CSR.
3647  * This is a synchronous call.
3648  *
3649  * pParam - caller allocated memory
3650  * Return QDF_STATUS
3651  */
sme_get_config_param(mac_handle_t mac_handle,struct sme_config_params * pParam)3652 QDF_STATUS sme_get_config_param(mac_handle_t mac_handle,
3653 				struct sme_config_params *pParam)
3654 {
3655 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
3656 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
3657 
3658 	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
3659 			 TRACE_CODE_SME_RX_HDD_GET_CONFIGPARAM, NO_SESSION, 0));
3660 	status = sme_acquire_global_lock(&mac->sme);
3661 	if (QDF_IS_STATUS_SUCCESS(status)) {
3662 		status = csr_get_config_param(mac, &pParam->csr_config);
3663 		if (status != QDF_STATUS_SUCCESS) {
3664 			sme_err("csr_get_config_param failed");
3665 			sme_release_global_lock(&mac->sme);
3666 			return status;
3667 		}
3668 		sme_release_global_lock(&mac->sme);
3669 	}
3670 
3671 	return status;
3672 }
3673 
sme_get_vht_ch_width(void)3674 uint32_t sme_get_vht_ch_width(void)
3675 {
3676 	return wma_get_vht_ch_width();
3677 }
3678 
3679 #ifdef WLAN_FEATURE_11BE
sme_get_eht_ch_width(void)3680 uint32_t sme_get_eht_ch_width(void)
3681 {
3682 	return wma_get_eht_ch_width();
3683 }
3684 #endif
3685 
3686 #ifdef FEATURE_OEM_DATA_SUPPORT
3687 /**
3688  * sme_register_oem_data_rsp_callback() - Register a routine of
3689  *                                        type send_oem_data_rsp_msg
3690  * @mac_handle:                                Handle returned by mac_open.
3691  * @callback:                             Callback to send response
3692  *                                        to oem application.
3693  *
3694  * sme_oem_data_rsp_callback is used to register sme_send_oem_data_rsp_msg
3695  * callback function.
3696  *
3697  * Return: QDF_STATUS.
3698  */
sme_register_oem_data_rsp_callback(mac_handle_t mac_handle,sme_send_oem_data_rsp_msg callback)3699 QDF_STATUS sme_register_oem_data_rsp_callback(mac_handle_t mac_handle,
3700 				sme_send_oem_data_rsp_msg callback)
3701 {
3702 	QDF_STATUS status = QDF_STATUS_SUCCESS;
3703 	struct mac_context *pmac = MAC_CONTEXT(mac_handle);
3704 
3705 	pmac->sme.oem_data_rsp_callback = callback;
3706 
3707 	return status;
3708 
3709 }
3710 
3711 /**
3712  * sme_deregister_oem_data_rsp_callback() - De-register OEM datarsp callback
3713  * @mac_handle: Handler return by mac_open
3714  * This function De-registers the OEM data response callback  to SME
3715  *
3716  * Return: None
3717  */
sme_deregister_oem_data_rsp_callback(mac_handle_t mac_handle)3718 void  sme_deregister_oem_data_rsp_callback(mac_handle_t mac_handle)
3719 {
3720 	struct mac_context *pmac;
3721 
3722 	if (!mac_handle) {
3723 		sme_err("mac_handle is not valid");
3724 		return;
3725 	}
3726 	pmac = MAC_CONTEXT(mac_handle);
3727 
3728 	pmac->sme.oem_data_rsp_callback = NULL;
3729 }
3730 
3731 /**
3732  * sme_oem_update_capability() - update UMAC's oem related capability.
3733  * @mac_handle: Handle returned by mac_open
3734  * @oem_cap: pointer to oem_capability
3735  *
3736  * This function updates OEM capability to UMAC. Currently RTT
3737  * related capabilities are updated. More capabilities can be
3738  * added in future.
3739  *
3740  * Return: QDF_STATUS
3741  */
sme_oem_update_capability(mac_handle_t mac_handle,struct sme_oem_capability * cap)3742 QDF_STATUS sme_oem_update_capability(mac_handle_t mac_handle,
3743 				     struct sme_oem_capability *cap)
3744 {
3745 	QDF_STATUS status = QDF_STATUS_SUCCESS;
3746 	struct mac_context *pmac = MAC_CONTEXT(mac_handle);
3747 	uint8_t *bytes;
3748 
3749 	bytes = pmac->rrm.rrmConfig.rm_capability;
3750 
3751 	if (cap->ftm_rr)
3752 		bytes[4] |= RM_CAP_FTM_RANGE_REPORT;
3753 	if (cap->lci_capability)
3754 		bytes[4] |= RM_CAP_CIVIC_LOC_MEASUREMENT;
3755 
3756 	return status;
3757 }
3758 
3759 /**
3760  * sme_oem_get_capability() - get oem capability
3761  * @mac_handle: Handle returned by mac_open
3762  * @oem_cap: pointer to oem_capability
3763  *
3764  * This function is used to get the OEM capability from UMAC.
3765  * Currently RTT related capabilities are received. More
3766  * capabilities can be added in future.
3767  *
3768  * Return: QDF_STATUS
3769  */
sme_oem_get_capability(mac_handle_t mac_handle,struct sme_oem_capability * cap)3770 QDF_STATUS sme_oem_get_capability(mac_handle_t mac_handle,
3771 				  struct sme_oem_capability *cap)
3772 {
3773 	QDF_STATUS status = QDF_STATUS_SUCCESS;
3774 	struct mac_context *pmac = MAC_CONTEXT(mac_handle);
3775 	uint8_t *bytes;
3776 
3777 	bytes = pmac->rrm.rrmConfig.rm_capability;
3778 
3779 	cap->ftm_rr = bytes[4] & RM_CAP_FTM_RANGE_REPORT;
3780 	cap->lci_capability = bytes[4] & RM_CAP_CIVIC_LOC_MEASUREMENT;
3781 
3782 	return status;
3783 }
3784 #endif
3785 
3786 /*
3787  * sme_get_snr() -
3788  * A wrapper function that client calls to register a callback to get SNR
3789  *
3790  * callback - SME sends back the requested stats using the callback
3791  * staId - The station ID for which the stats is requested for
3792  * pContext - user context to be passed back along with the callback
3793  * p_cds_context - cds context
3794  *   \return QDF_STATUS
3795  */
sme_get_snr(mac_handle_t mac_handle,tCsrSnrCallback callback,struct qdf_mac_addr bssId,void * pContext)3796 QDF_STATUS sme_get_snr(mac_handle_t mac_handle,
3797 		       tCsrSnrCallback callback,
3798 		       struct qdf_mac_addr bssId, void *pContext)
3799 {
3800 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
3801 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
3802 
3803 	status = sme_acquire_global_lock(&mac->sme);
3804 	if (QDF_IS_STATUS_SUCCESS(status)) {
3805 		status = csr_get_snr(mac, callback, bssId, pContext);
3806 		sme_release_global_lock(&mac->sme);
3807 	}
3808 	return status;
3809 }
3810 
sme_get_link_status(mac_handle_t mac_handle,csr_link_status_callback callback,void * context,uint8_t session_id)3811 QDF_STATUS sme_get_link_status(mac_handle_t mac_handle,
3812 			       csr_link_status_callback callback,
3813 			       void *context, uint8_t session_id)
3814 {
3815 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
3816 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
3817 	tAniGetLinkStatus *msg;
3818 	struct scheduler_msg message = {0};
3819 
3820 	status = sme_acquire_global_lock(&mac->sme);
3821 	if (QDF_IS_STATUS_SUCCESS(status)) {
3822 		msg = qdf_mem_malloc(sizeof(*msg));
3823 		if (!msg) {
3824 			sme_release_global_lock(&mac->sme);
3825 			return QDF_STATUS_E_NOMEM;
3826 		}
3827 
3828 		msg->msgType = WMA_LINK_STATUS_GET_REQ;
3829 		msg->msgLen = sizeof(*msg);
3830 		msg->sessionId = session_id;
3831 		mac->sme.link_status_context = context;
3832 		mac->sme.link_status_callback = callback;
3833 
3834 		message.type = WMA_LINK_STATUS_GET_REQ;
3835 		message.bodyptr = msg;
3836 		message.reserved = 0;
3837 
3838 		status = scheduler_post_message(QDF_MODULE_ID_SME,
3839 						QDF_MODULE_ID_WMA,
3840 						QDF_MODULE_ID_WMA, &message);
3841 		if (QDF_IS_STATUS_ERROR(status)) {
3842 			sme_err("post msg failed, %d", status);
3843 			qdf_mem_free(msg);
3844 			mac->sme.link_status_context = NULL;
3845 			mac->sme.link_status_callback = NULL;
3846 		}
3847 
3848 		sme_release_global_lock(&mac->sme);
3849 	}
3850 
3851 	return status;
3852 }
3853 
3854 /*
3855  * sme_generic_change_country_code() -
3856  * Change Country code from upperlayer during WLAN driver operation.
3857  * This is a synchronous API.
3858  *
3859  * mac_handle - The handle returned by mac_open.
3860  * pCountry New Country Code String
3861  * reg_domain regulatory domain
3862  * Return QDF_STATUS  SUCCESS.
3863  * FAILURE or RESOURCES  The API finished and failed.
3864  */
sme_generic_change_country_code(mac_handle_t mac_handle,uint8_t * pCountry)3865 QDF_STATUS sme_generic_change_country_code(mac_handle_t mac_handle,
3866 					   uint8_t *pCountry)
3867 {
3868 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
3869 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
3870 	struct scheduler_msg msg = {0};
3871 	tAniGenericChangeCountryCodeReq *pMsg;
3872 
3873 	if (!mac) {
3874 		sme_err("mac is null");
3875 		return status;
3876 	}
3877 
3878 	status = sme_acquire_global_lock(&mac->sme);
3879 	if (QDF_IS_STATUS_SUCCESS(status)) {
3880 		pMsg = qdf_mem_malloc(sizeof(tAniGenericChangeCountryCodeReq));
3881 		if (!pMsg) {
3882 			sme_release_global_lock(&mac->sme);
3883 			return QDF_STATUS_E_NOMEM;
3884 		}
3885 
3886 		pMsg->msgType = eWNI_SME_GENERIC_CHANGE_COUNTRY_CODE;
3887 		pMsg->msgLen =
3888 			(uint16_t) sizeof(tAniGenericChangeCountryCodeReq);
3889 		qdf_mem_copy(pMsg->countryCode, pCountry, 2);
3890 		pMsg->countryCode[2] = ' ';
3891 
3892 		msg.type = eWNI_SME_GENERIC_CHANGE_COUNTRY_CODE;
3893 		msg.bodyptr = pMsg;
3894 		msg.reserved = 0;
3895 
3896 		if (QDF_STATUS_SUCCESS !=
3897 		    scheduler_post_message(QDF_MODULE_ID_SME,
3898 					   QDF_MODULE_ID_SME,
3899 					   QDF_MODULE_ID_SME, &msg)) {
3900 			qdf_mem_free(pMsg);
3901 			status = QDF_STATUS_E_FAILURE;
3902 		}
3903 		sme_release_global_lock(&mac->sme);
3904 	}
3905 
3906 	return status;
3907 }
3908 
3909 /*
3910  * sme_dhcp_start_ind() -
3911  * API to signal the FW about the DHCP Start event.
3912  *
3913  * mac_handle: Opaque handle to the global MAC context.
3914  * device_mode - mode(AP,SAP etc) of the device.
3915  * macAddr - MAC address of the adapter.
3916  * sessionId - session ID.
3917  * Return QDF_STATUS  SUCCESS.
3918  * FAILURE or RESOURCES  The API finished and failed.
3919  */
sme_dhcp_start_ind(mac_handle_t mac_handle,uint8_t device_mode,uint8_t * macAddr,uint8_t sessionId)3920 QDF_STATUS sme_dhcp_start_ind(mac_handle_t mac_handle,
3921 			      uint8_t device_mode,
3922 			      uint8_t *macAddr, uint8_t sessionId)
3923 {
3924 	QDF_STATUS status;
3925 	QDF_STATUS qdf_status;
3926 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
3927 	struct scheduler_msg message = {0};
3928 	tAniDHCPInd *pMsg;
3929 	struct csr_roam_session *pSession;
3930 
3931 	status = sme_acquire_global_lock(&mac->sme);
3932 	if (QDF_STATUS_SUCCESS == status) {
3933 		pSession = CSR_GET_SESSION(mac, sessionId);
3934 
3935 		if (!pSession) {
3936 			sme_err("Session: %d not found", sessionId);
3937 			sme_release_global_lock(&mac->sme);
3938 			return QDF_STATUS_E_FAILURE;
3939 		}
3940 		pSession->dhcp_done = false;
3941 
3942 		pMsg = qdf_mem_malloc(sizeof(tAniDHCPInd));
3943 		if (!pMsg) {
3944 			sme_release_global_lock(&mac->sme);
3945 			return QDF_STATUS_E_NOMEM;
3946 		}
3947 		pMsg->msgType = WMA_DHCP_START_IND;
3948 		pMsg->msgLen = (uint16_t) sizeof(tAniDHCPInd);
3949 		pMsg->device_mode = device_mode;
3950 		qdf_mem_copy(pMsg->adapterMacAddr.bytes, macAddr,
3951 			     QDF_MAC_ADDR_SIZE);
3952 		wlan_mlme_get_bssid_vdev_id(mac->pdev, sessionId,
3953 					    &pMsg->peerMacAddr);
3954 
3955 		message.type = WMA_DHCP_START_IND;
3956 		message.bodyptr = pMsg;
3957 		message.reserved = 0;
3958 		MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG,
3959 				 sessionId, message.type));
3960 		qdf_status = scheduler_post_message(QDF_MODULE_ID_SME,
3961 						    QDF_MODULE_ID_WMA,
3962 						    QDF_MODULE_ID_WMA,
3963 						    &message);
3964 		if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
3965 			sme_err("Post DHCP Start MSG fail");
3966 			qdf_mem_free(pMsg);
3967 			status = QDF_STATUS_E_FAILURE;
3968 		}
3969 		sme_release_global_lock(&mac->sme);
3970 	}
3971 	return status;
3972 }
3973 
3974 /*
3975  * sme_dhcp_stop_ind() -
3976  * API to signal the FW about the DHCP complete event.
3977  *
3978  * mac_handle: Opaque handle to the global MAC context.
3979  * device_mode - mode(AP, SAP etc) of the device.
3980  * macAddr - MAC address of the adapter.
3981  * sessionId - session ID.
3982  * Return QDF_STATUS  SUCCESS.
3983  *			FAILURE or RESOURCES  The API finished and failed.
3984  */
sme_dhcp_stop_ind(mac_handle_t mac_handle,uint8_t device_mode,uint8_t * macAddr,uint8_t sessionId)3985 QDF_STATUS sme_dhcp_stop_ind(mac_handle_t mac_handle,
3986 			     uint8_t device_mode,
3987 			     uint8_t *macAddr, uint8_t sessionId)
3988 {
3989 	QDF_STATUS status;
3990 	QDF_STATUS qdf_status;
3991 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
3992 	struct scheduler_msg message = {0};
3993 	tAniDHCPInd *pMsg;
3994 	struct csr_roam_session *pSession;
3995 
3996 	status = sme_acquire_global_lock(&mac->sme);
3997 	if (QDF_STATUS_SUCCESS == status) {
3998 		pSession = CSR_GET_SESSION(mac, sessionId);
3999 
4000 		if (!pSession) {
4001 			sme_err("Session: %d not found", sessionId);
4002 			sme_release_global_lock(&mac->sme);
4003 			return QDF_STATUS_E_FAILURE;
4004 		}
4005 		pSession->dhcp_done = true;
4006 
4007 		pMsg = qdf_mem_malloc(sizeof(tAniDHCPInd));
4008 		if (!pMsg) {
4009 			sme_release_global_lock(&mac->sme);
4010 			return QDF_STATUS_E_NOMEM;
4011 		}
4012 
4013 		pMsg->msgType = WMA_DHCP_STOP_IND;
4014 		pMsg->msgLen = (uint16_t) sizeof(tAniDHCPInd);
4015 		pMsg->device_mode = device_mode;
4016 		qdf_mem_copy(pMsg->adapterMacAddr.bytes, macAddr,
4017 			     QDF_MAC_ADDR_SIZE);
4018 
4019 		wlan_mlme_get_bssid_vdev_id(mac->pdev, sessionId,
4020 					    &pMsg->peerMacAddr);
4021 
4022 		message.type = WMA_DHCP_STOP_IND;
4023 		message.bodyptr = pMsg;
4024 		message.reserved = 0;
4025 		MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG,
4026 				 sessionId, message.type));
4027 		qdf_status = scheduler_post_message(QDF_MODULE_ID_SME,
4028 						    QDF_MODULE_ID_WMA,
4029 						    QDF_MODULE_ID_WMA,
4030 						    &message);
4031 		if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
4032 			sme_err("Post DHCP Stop MSG fail");
4033 			qdf_mem_free(pMsg);
4034 			status = QDF_STATUS_E_FAILURE;
4035 		}
4036 
4037 		sme_release_global_lock(&mac->sme);
4038 	}
4039 	return status;
4040 }
4041 
4042 /*
4043  * sme_neighbor_report_request() -
4044  * API to request neighbor report.
4045  *
4046  * mac_handle - The handle returned by mac_open.
4047  * pRrmNeighborReq - Pointer to a caller allocated object of type
4048  *			      tRrmNeighborReq. Caller owns the memory and is
4049  *			      responsible for freeing it.
4050  * Return QDF_STATUS
4051  *	    QDF_STATUS_E_FAILURE - failure
4052  *	    QDF_STATUS_SUCCESS  success
4053  */
sme_neighbor_report_request(mac_handle_t mac_handle,uint8_t sessionId,tpRrmNeighborReq pRrmNeighborReq,tpRrmNeighborRspCallbackInfo callbackInfo)4054 QDF_STATUS sme_neighbor_report_request(
4055 				mac_handle_t mac_handle,
4056 				uint8_t sessionId,
4057 				tpRrmNeighborReq pRrmNeighborReq,
4058 				tpRrmNeighborRspCallbackInfo callbackInfo)
4059 {
4060 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
4061 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
4062 
4063 	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
4064 			 TRACE_CODE_SME_RX_HDD_NEIGHBOR_REPORTREQ, NO_SESSION,
4065 			 0));
4066 
4067 	if (pRrmNeighborReq->neighbor_report_offload) {
4068 		status = csr_invoke_neighbor_report_request(sessionId,
4069 							    pRrmNeighborReq,
4070 							    false);
4071 		return status;
4072 	}
4073 
4074 	if (QDF_STATUS_SUCCESS == sme_acquire_global_lock(&mac->sme)) {
4075 		status =
4076 			sme_rrm_neighbor_report_request(mac, sessionId,
4077 						pRrmNeighborReq, callbackInfo);
4078 		sme_release_global_lock(&mac->sme);
4079 	}
4080 
4081 	return status;
4082 }
4083 
4084 void
sme_register_pagefault_cb(mac_handle_t mac_handle,QDF_STATUS (* hdd_pagefault_action_cb)(void * buf,uint32_t data))4085 sme_register_pagefault_cb(mac_handle_t mac_handle,
4086 			  QDF_STATUS (*hdd_pagefault_action_cb)(void *buf,
4087 								uint32_t data))
4088 {
4089 	QDF_STATUS status;
4090 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
4091 
4092 	SME_ENTER();
4093 
4094 	status = sme_acquire_global_lock(&mac->sme);
4095 	if (QDF_IS_STATUS_SUCCESS(status)) {
4096 		mac->sme.pagefault_action_cb = hdd_pagefault_action_cb;
4097 		sme_release_global_lock(&mac->sme);
4098 	}
4099 
4100 	SME_EXIT();
4101 }
4102 
sme_deregister_ssr_on_pagefault_cb(mac_handle_t mac_handle)4103 void sme_deregister_ssr_on_pagefault_cb(mac_handle_t mac_handle)
4104 {
4105 	QDF_STATUS status;
4106 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
4107 
4108 	SME_ENTER();
4109 
4110 	status = sme_acquire_global_lock(&mac->sme);
4111 	if (QDF_IS_STATUS_SUCCESS(status)) {
4112 		mac->sme.pagefault_action_cb = NULL;
4113 		sme_release_global_lock(&mac->sme);
4114 	}
4115 
4116 	SME_EXIT();
4117 }
4118 
4119 #ifdef FEATURE_OEM_DATA_SUPPORT
sme_oem_req_cmd(mac_handle_t mac_handle,struct oem_data_req * oem_req)4120 QDF_STATUS sme_oem_req_cmd(mac_handle_t mac_handle,
4121 			   struct oem_data_req *oem_req)
4122 {
4123 	QDF_STATUS status = QDF_STATUS_SUCCESS;
4124 	struct oem_data_req *oem_data_req;
4125 	void *wma_handle;
4126 
4127 	SME_ENTER();
4128 	wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
4129 	if (!wma_handle)
4130 		return QDF_STATUS_E_FAILURE;
4131 
4132 	oem_data_req = qdf_mem_malloc(sizeof(*oem_data_req));
4133 	if (!oem_data_req)
4134 		return QDF_STATUS_E_NOMEM;
4135 
4136 	oem_data_req->data_len = oem_req->data_len;
4137 	oem_data_req->data = qdf_mem_malloc(oem_data_req->data_len);
4138 	if (!oem_data_req->data) {
4139 		qdf_mem_free(oem_data_req);
4140 		return QDF_STATUS_E_NOMEM;
4141 	}
4142 
4143 	qdf_mem_copy(oem_data_req->data, oem_req->data,
4144 		     oem_data_req->data_len);
4145 
4146 	status = wma_start_oem_req_cmd(wma_handle, oem_data_req);
4147 
4148 	if (!QDF_IS_STATUS_SUCCESS(status))
4149 		sme_err("Post oem data request msg fail");
4150 	else
4151 		sme_debug("OEM request(length: %d) sent to WMA",
4152 			  oem_data_req->data_len);
4153 
4154 	if (oem_data_req->data_len)
4155 		qdf_mem_free(oem_data_req->data);
4156 	qdf_mem_free(oem_data_req);
4157 
4158 	SME_EXIT();
4159 	return status;
4160 }
4161 #endif /*FEATURE_OEM_DATA_SUPPORT */
4162 
4163 #ifdef FEATURE_OEM_DATA
sme_oem_data_cmd(mac_handle_t mac_handle,void (* oem_data_event_handler_cb)(const struct oem_data * oem_event_data,uint8_t vdev_id),struct oem_data * oem_data,uint8_t vdev_id)4164 QDF_STATUS sme_oem_data_cmd(mac_handle_t mac_handle,
4165 			    void (*oem_data_event_handler_cb)
4166 			    (const struct oem_data *oem_event_data,
4167 			     uint8_t vdev_id),
4168 			     struct oem_data *oem_data,
4169 			     uint8_t vdev_id)
4170 {
4171 	QDF_STATUS status;
4172 	void *wma_handle;
4173 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
4174 
4175 	SME_ENTER();
4176 	wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
4177 	if (!wma_handle)
4178 		return QDF_STATUS_E_FAILURE;
4179 
4180 	status = sme_acquire_global_lock(&mac->sme);
4181 	if (QDF_IS_STATUS_SUCCESS(status)) {
4182 		mac->sme.oem_data_event_handler_cb = oem_data_event_handler_cb;
4183 		mac->sme.oem_data_vdev_id = vdev_id;
4184 		sme_release_global_lock(&mac->sme);
4185 	}
4186 	status = wma_start_oem_data_cmd(wma_handle, oem_data);
4187 	if (!QDF_IS_STATUS_SUCCESS(status))
4188 		sme_err("fail to call wma_start_oem_data_cmd.");
4189 
4190 	SME_EXIT();
4191 	return status;
4192 }
4193 
sme_oem_event_deinit(mac_handle_t mac_handle)4194 void sme_oem_event_deinit(mac_handle_t mac_handle)
4195 {
4196 	QDF_STATUS status;
4197 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
4198 
4199 	SME_ENTER();
4200 
4201 	status = sme_acquire_global_lock(&mac->sme);
4202 	if (QDF_IS_STATUS_SUCCESS(status)) {
4203 		mac->sme.oem_data_event_handler_cb = NULL;
4204 		mac->sme.oem_data_vdev_id = WMA_INVALID_VDEV_ID;
4205 		sme_release_global_lock(&mac->sme);
4206 	}
4207 
4208 	SME_EXIT();
4209 }
4210 
sme_async_oem_event_init(mac_handle_t mac_handle,void (* oem_data_async_event_handler_cb)(const struct oem_data * oem_event_data))4211 void sme_async_oem_event_init(mac_handle_t mac_handle,
4212 			      void (*oem_data_async_event_handler_cb)
4213 			      (const struct oem_data *oem_event_data))
4214 {
4215 	QDF_STATUS status;
4216 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
4217 
4218 	SME_ENTER();
4219 
4220 	status = sme_acquire_global_lock(&mac->sme);
4221 	if (QDF_IS_STATUS_SUCCESS(status)) {
4222 		mac->sme.oem_data_async_event_handler_cb =
4223 		oem_data_async_event_handler_cb;
4224 		sme_release_global_lock(&mac->sme);
4225 	}
4226 
4227 	SME_EXIT();
4228 }
4229 
sme_async_oem_event_deinit(mac_handle_t mac_handle)4230 void sme_async_oem_event_deinit(mac_handle_t mac_handle)
4231 {
4232 	QDF_STATUS status;
4233 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
4234 
4235 	SME_ENTER();
4236 
4237 	status = sme_acquire_global_lock(&mac->sme);
4238 	if (QDF_IS_STATUS_SUCCESS(status)) {
4239 		mac->sme.oem_data_async_event_handler_cb = NULL;
4240 		sme_release_global_lock(&mac->sme);
4241 	}
4242 
4243 	SME_EXIT();
4244 }
4245 #endif
4246 
4247 #define STA_NSS_CHAINS_SHIFT               0
4248 #define SAP_NSS_CHAINS_SHIFT               3
4249 #define P2P_GO_NSS_CHAINS_SHIFT            6
4250 #define P2P_CLI_CHAINS_SHIFT               9
4251 #define TDLS_NSS_CHAINS_SHIFT              12
4252 #define IBSS_NSS_CHAINS_SHIFT              15
4253 #define P2P_DEV_NSS_CHAINS_SHIFT           18
4254 #define OCB_NSS_CHAINS_SHIFT               21
4255 #define NAN_NSS_CHAIN_SHIFT                24
4256 #define NSS_CHAIN_MASK                     0x7
4257 #define GET_VDEV_NSS_CHAIN(x, y)         (((x) >> (y)) & NSS_CHAIN_MASK)
4258 
sme_get_nss_chain_shift(enum QDF_OPMODE device_mode)4259 static uint8_t sme_get_nss_chain_shift(enum QDF_OPMODE device_mode)
4260 {
4261 	switch (device_mode) {
4262 	case QDF_STA_MODE:
4263 		return STA_NSS_CHAINS_SHIFT;
4264 	case QDF_SAP_MODE:
4265 		return SAP_NSS_CHAINS_SHIFT;
4266 	case QDF_P2P_GO_MODE:
4267 		return P2P_GO_NSS_CHAINS_SHIFT;
4268 	case QDF_P2P_CLIENT_MODE:
4269 		return P2P_CLI_CHAINS_SHIFT;
4270 	case QDF_IBSS_MODE:
4271 		return IBSS_NSS_CHAINS_SHIFT;
4272 	case QDF_P2P_DEVICE_MODE:
4273 		return P2P_DEV_NSS_CHAINS_SHIFT;
4274 	case QDF_OCB_MODE:
4275 		return OCB_NSS_CHAINS_SHIFT;
4276 	case QDF_TDLS_MODE:
4277 		return TDLS_NSS_CHAINS_SHIFT;
4278 
4279 	default:
4280 		sme_err("Device mode %d invalid", device_mode);
4281 		return STA_NSS_CHAINS_SHIFT;
4282 	}
4283 }
4284 
4285 static void
sme_check_nss_chain_ini_param(struct wlan_mlme_nss_chains * vdev_ini_cfg,uint8_t rf_chains_supported,enum nss_chains_band_info band)4286 sme_check_nss_chain_ini_param(struct wlan_mlme_nss_chains *vdev_ini_cfg,
4287 			      uint8_t rf_chains_supported,
4288 			      enum nss_chains_band_info band)
4289 {
4290 	vdev_ini_cfg->rx_nss[band] = QDF_MIN(vdev_ini_cfg->rx_nss[band],
4291 					     rf_chains_supported);
4292 	vdev_ini_cfg->tx_nss[band] = QDF_MIN(vdev_ini_cfg->tx_nss[band],
4293 					     rf_chains_supported);
4294 }
4295 
4296 static void
sme_fill_nss_chain_params(struct mac_context * mac_ctx,struct wlan_mlme_nss_chains * vdev_ini_cfg,enum QDF_OPMODE device_mode,enum nss_chains_band_info band,uint8_t rf_chains_supported)4297 sme_fill_nss_chain_params(struct mac_context *mac_ctx,
4298 			  struct wlan_mlme_nss_chains *vdev_ini_cfg,
4299 			  enum QDF_OPMODE device_mode,
4300 			  enum nss_chains_band_info band,
4301 			  uint8_t rf_chains_supported)
4302 {
4303 	uint8_t nss_chain_shift;
4304 	uint8_t max_supported_nss;
4305 	enum coex_btc_chain_mode btc_chain_mode;
4306 	struct wlan_mlme_nss_chains *nss_chains_ini_cfg =
4307 					&mac_ctx->mlme_cfg->nss_chains_ini_cfg;
4308 	QDF_STATUS status;
4309 
4310 	nss_chain_shift = sme_get_nss_chain_shift(device_mode);
4311 	max_supported_nss = mac_ctx->mlme_cfg->vht_caps.vht_cap_info.enable2x2 ?
4312 			    MAX_VDEV_NSS : 1;
4313 
4314 	/*
4315 	 * If target supports Antenna sharing, set NSS to 1 for 2.4GHz band for
4316 	 * NDI vdev.
4317 	 */
4318 	if (device_mode == QDF_NDI_MODE && mac_ctx->mlme_cfg->gen.as_enabled &&
4319 	    band == NSS_CHAINS_BAND_2GHZ)
4320 		max_supported_nss = NSS_1x1_MODE;
4321 
4322 	status = ucfg_coex_psoc_get_btc_chain_mode(mac_ctx->psoc,
4323 						   &btc_chain_mode);
4324 	if (QDF_IS_STATUS_ERROR(status)) {
4325 		sme_err("Failed to get BT coex chain mode");
4326 		btc_chain_mode = WLAN_COEX_BTC_CHAIN_MODE_UNSETTLED;
4327 	}
4328 
4329 	if (band == NSS_CHAINS_BAND_2GHZ &&
4330 	    (btc_chain_mode == WLAN_COEX_BTC_CHAIN_MODE_FDD ||
4331 	     btc_chain_mode == WLAN_COEX_BTC_CHAIN_MODE_HYBRID))
4332 		max_supported_nss = NSS_1x1_MODE;
4333 
4334 	/* If the fw doesn't support two chains, num rf chains can max be 1 */
4335 	vdev_ini_cfg->num_rx_chains[band] =
4336 		QDF_MIN(GET_VDEV_NSS_CHAIN(
4337 				nss_chains_ini_cfg->num_rx_chains[band],
4338 				nss_chain_shift), rf_chains_supported);
4339 
4340 	vdev_ini_cfg->num_tx_chains[band] =
4341 		QDF_MIN(GET_VDEV_NSS_CHAIN(
4342 				nss_chains_ini_cfg->num_tx_chains[band],
4343 				nss_chain_shift), rf_chains_supported);
4344 
4345 	/* If 2x2 mode is disabled, then max rx, tx nss can be 1 */
4346 	vdev_ini_cfg->rx_nss[band] =
4347 		QDF_MIN(GET_VDEV_NSS_CHAIN(
4348 				nss_chains_ini_cfg->rx_nss[band],
4349 				nss_chain_shift), max_supported_nss);
4350 
4351 	vdev_ini_cfg->tx_nss[band] =
4352 		QDF_MIN(GET_VDEV_NSS_CHAIN(
4353 				nss_chains_ini_cfg->tx_nss[band],
4354 				nss_chain_shift), max_supported_nss);
4355 
4356 	vdev_ini_cfg->num_tx_chains_11a =
4357 		QDF_MIN(GET_VDEV_NSS_CHAIN(
4358 				nss_chains_ini_cfg->num_tx_chains_11a,
4359 				nss_chain_shift), rf_chains_supported);
4360 
4361 	/* If the fw doesn't support two chains, num rf chains can max be 1 */
4362 	vdev_ini_cfg->num_tx_chains_11b =
4363 		QDF_MIN(GET_VDEV_NSS_CHAIN(
4364 				nss_chains_ini_cfg->num_tx_chains_11b,
4365 				nss_chain_shift), rf_chains_supported);
4366 
4367 	vdev_ini_cfg->num_tx_chains_11g =
4368 		QDF_MIN(GET_VDEV_NSS_CHAIN(
4369 				nss_chains_ini_cfg->num_tx_chains_11g,
4370 				nss_chain_shift), rf_chains_supported);
4371 
4372 	vdev_ini_cfg->disable_rx_mrc[band] =
4373 				nss_chains_ini_cfg->disable_rx_mrc[band];
4374 
4375 	vdev_ini_cfg->disable_tx_mrc[band] =
4376 				nss_chains_ini_cfg->disable_tx_mrc[band];
4377 	/*
4378 	 * Check whether the rx/tx nss is greater than the number of rf chains
4379 	 * supported by FW, if so downgrade the nss to the number of chains
4380 	 * supported, as higher nss cannot be supported with less chains.
4381 	 */
4382 	sme_check_nss_chain_ini_param(vdev_ini_cfg, rf_chains_supported,
4383 				      band);
4384 
4385 }
4386 
sme_populate_nss_chain_params(mac_handle_t mac_handle,struct wlan_mlme_nss_chains * vdev_ini_cfg,enum QDF_OPMODE device_mode,uint8_t rf_chains_supported)4387 void sme_populate_nss_chain_params(mac_handle_t mac_handle,
4388 				   struct wlan_mlme_nss_chains *vdev_ini_cfg,
4389 				   enum QDF_OPMODE device_mode,
4390 				   uint8_t rf_chains_supported)
4391 {
4392 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
4393 	enum nss_chains_band_info band;
4394 
4395 	for (band = NSS_CHAINS_BAND_2GHZ; band < NSS_CHAINS_BAND_MAX; band++)
4396 		sme_fill_nss_chain_params(mac_ctx, vdev_ini_cfg,
4397 					  device_mode, band,
4398 					  rf_chains_supported);
4399 }
4400 
4401 void
sme_store_nss_chains_cfg_in_vdev(struct wlan_objmgr_vdev * vdev,struct wlan_mlme_nss_chains * vdev_ini_cfg)4402 sme_store_nss_chains_cfg_in_vdev(struct wlan_objmgr_vdev *vdev,
4403 				 struct wlan_mlme_nss_chains *vdev_ini_cfg)
4404 {
4405 	struct wlan_mlme_nss_chains *ini_cfg;
4406 	struct wlan_mlme_nss_chains *dynamic_cfg;
4407 
4408 	if (!vdev) {
4409 		sme_err("Invalid vdev");
4410 		return;
4411 	}
4412 
4413 	ini_cfg = mlme_get_ini_vdev_config(vdev);
4414 	dynamic_cfg = mlme_get_dynamic_vdev_config(vdev);
4415 
4416 	if (!ini_cfg || !dynamic_cfg) {
4417 		sme_err("Nss chains ini/dynamic config NULL vdev_id %d",
4418 					     vdev->vdev_objmgr.vdev_id);
4419 		return;
4420 	}
4421 
4422 	*ini_cfg = *vdev_ini_cfg;
4423 	*dynamic_cfg = *vdev_ini_cfg;
4424 }
4425 
4426 static void
sme_populate_user_config(struct wlan_mlme_nss_chains * dynamic_cfg,struct wlan_mlme_nss_chains * user_cfg,struct wlan_mlme_nss_chains * ini_cfg,enum nss_chains_band_info band)4427 sme_populate_user_config(struct wlan_mlme_nss_chains *dynamic_cfg,
4428 			 struct wlan_mlme_nss_chains *user_cfg,
4429 			 struct wlan_mlme_nss_chains *ini_cfg,
4430 			 enum nss_chains_band_info band)
4431 {
4432 	if (!user_cfg->num_rx_chains[band])
4433 		user_cfg->num_rx_chains[band] =
4434 			dynamic_cfg->num_rx_chains[band];
4435 
4436 	if (!user_cfg->num_tx_chains[band])
4437 		user_cfg->num_tx_chains[band] =
4438 			dynamic_cfg->num_tx_chains[band];
4439 
4440 	if (!user_cfg->rx_nss[band])
4441 		user_cfg->rx_nss[band] =
4442 			dynamic_cfg->rx_nss[band];
4443 
4444 	if (!user_cfg->tx_nss[band])
4445 		user_cfg->tx_nss[band] =
4446 			dynamic_cfg->tx_nss[band];
4447 
4448 	if (!user_cfg->num_tx_chains_11a) {
4449 		user_cfg->num_tx_chains_11a =
4450 			QDF_MIN(user_cfg->num_tx_chains[NSS_CHAINS_BAND_5GHZ],
4451 				ini_cfg->num_tx_chains_11a);
4452 	}
4453 
4454 	if (!user_cfg->num_tx_chains_11b) {
4455 		user_cfg->num_tx_chains_11b =
4456 			QDF_MIN(user_cfg->num_tx_chains[NSS_CHAINS_BAND_2GHZ],
4457 				ini_cfg->num_tx_chains_11b);
4458 	}
4459 
4460 	if (!user_cfg->num_tx_chains_11g) {
4461 		user_cfg->num_tx_chains_11g =
4462 			QDF_MIN(user_cfg->num_tx_chains[NSS_CHAINS_BAND_2GHZ],
4463 				ini_cfg->num_tx_chains_11g);
4464 	}
4465 
4466 	if (!user_cfg->disable_rx_mrc[band])
4467 		user_cfg->disable_rx_mrc[band] =
4468 			dynamic_cfg->disable_rx_mrc[band];
4469 
4470 	if (!user_cfg->disable_tx_mrc[band])
4471 		user_cfg->disable_tx_mrc[band] =
4472 			dynamic_cfg->disable_tx_mrc[band];
4473 }
4474 
4475 static QDF_STATUS
sme_validate_from_ini_config(struct wlan_mlme_nss_chains * user_cfg,struct wlan_mlme_nss_chains * ini_cfg,enum nss_chains_band_info band)4476 sme_validate_from_ini_config(struct wlan_mlme_nss_chains *user_cfg,
4477 			     struct wlan_mlme_nss_chains *ini_cfg,
4478 			     enum nss_chains_band_info band)
4479 {
4480 	if (user_cfg->num_rx_chains[band] >
4481 	    ini_cfg->num_rx_chains[band])
4482 		return QDF_STATUS_E_FAILURE;
4483 
4484 	if (user_cfg->num_tx_chains[band] >
4485 	    ini_cfg->num_tx_chains[band])
4486 		return QDF_STATUS_E_FAILURE;
4487 
4488 	if (user_cfg->rx_nss[band] >
4489 	    ini_cfg->rx_nss[band])
4490 		return QDF_STATUS_E_FAILURE;
4491 
4492 	if (user_cfg->tx_nss[band] >
4493 	    ini_cfg->tx_nss[band])
4494 		return QDF_STATUS_E_FAILURE;
4495 
4496 	if (user_cfg->num_tx_chains_11a >
4497 	    ini_cfg->num_tx_chains_11a)
4498 		return QDF_STATUS_E_FAILURE;
4499 
4500 	if (user_cfg->num_tx_chains_11b >
4501 	    ini_cfg->num_tx_chains_11b)
4502 		return QDF_STATUS_E_FAILURE;
4503 
4504 	if (user_cfg->num_tx_chains_11g >
4505 	    ini_cfg->num_tx_chains_11g)
4506 		return QDF_STATUS_E_FAILURE;
4507 
4508 	return QDF_STATUS_SUCCESS;
4509 }
4510 
4511 static QDF_STATUS
sme_validate_user_nss_chain_params(struct wlan_mlme_nss_chains * user_cfg,enum nss_chains_band_info band)4512 sme_validate_user_nss_chain_params(
4513 				    struct wlan_mlme_nss_chains *user_cfg,
4514 				    enum nss_chains_band_info band)
4515 {
4516 	/* Reject as 2x1 modes are not supported in chains yet */
4517 
4518 	if (user_cfg->num_tx_chains[band] >
4519 	    user_cfg->num_rx_chains[band])
4520 		return QDF_STATUS_E_FAILURE;
4521 
4522 	/* Also if mode is 2x2, we cant have chains as 1x1, or 1x2, or 2x1 */
4523 
4524 	if (user_cfg->tx_nss[band] >
4525 	    user_cfg->num_tx_chains[band])
4526 		user_cfg->num_tx_chains[band] =
4527 			user_cfg->tx_nss[band];
4528 
4529 	if (user_cfg->rx_nss[band] >
4530 	    user_cfg->num_rx_chains[band])
4531 		user_cfg->num_rx_chains[band] =
4532 			user_cfg->rx_nss[band];
4533 
4534 	/*
4535 	 * It may happen that already chains are in 1x1 mode and nss too
4536 	 * is in 1x1 mode, but the tx 11a/b/g chains in user config comes
4537 	 * as 2x1, or 1x2 which cannot support respective mode, as tx chains
4538 	 * for respective band have max of 1x1 only, so these cannot exceed
4539 	 * respective band num tx chains.
4540 	 */
4541 
4542 	if (user_cfg->num_tx_chains_11a >
4543 	    user_cfg->num_tx_chains[NSS_CHAINS_BAND_5GHZ])
4544 		user_cfg->num_tx_chains_11a =
4545 			user_cfg->num_tx_chains[NSS_CHAINS_BAND_5GHZ];
4546 
4547 	if (user_cfg->num_tx_chains_11b >
4548 	    user_cfg->num_tx_chains[NSS_CHAINS_BAND_2GHZ])
4549 		user_cfg->num_tx_chains_11b =
4550 			user_cfg->num_tx_chains[NSS_CHAINS_BAND_2GHZ];
4551 
4552 	if (user_cfg->num_tx_chains_11g >
4553 	    user_cfg->num_tx_chains[NSS_CHAINS_BAND_2GHZ])
4554 		user_cfg->num_tx_chains_11g =
4555 			user_cfg->num_tx_chains[NSS_CHAINS_BAND_2GHZ];
4556 
4557 	return QDF_STATUS_SUCCESS;
4558 }
4559 
4560 static QDF_STATUS
sme_validate_nss_chains_config(struct wlan_objmgr_vdev * vdev,struct wlan_mlme_nss_chains * user_cfg,struct wlan_mlme_nss_chains * dynamic_cfg)4561 sme_validate_nss_chains_config(struct wlan_objmgr_vdev *vdev,
4562 			       struct wlan_mlme_nss_chains *user_cfg,
4563 			       struct wlan_mlme_nss_chains *dynamic_cfg)
4564 {
4565 	enum nss_chains_band_info band;
4566 	struct wlan_mlme_nss_chains *ini_cfg;
4567 	QDF_STATUS status;
4568 
4569 	ini_cfg = mlme_get_ini_vdev_config(vdev);
4570 	if (!ini_cfg) {
4571 		sme_err("nss chain ini config NULL");
4572 		return QDF_STATUS_E_FAILURE;
4573 	}
4574 
4575 	for (band = NSS_CHAINS_BAND_2GHZ; band < NSS_CHAINS_BAND_MAX; band++) {
4576 		sme_populate_user_config(dynamic_cfg,
4577 					 user_cfg, ini_cfg, band);
4578 		status = sme_validate_from_ini_config(user_cfg,
4579 						      ini_cfg,
4580 						      band);
4581 		if (QDF_IS_STATUS_ERROR(status)) {
4582 			sme_err("Validation from ini config failed");
4583 			return QDF_STATUS_E_FAILURE;
4584 		}
4585 		status = sme_validate_user_nss_chain_params(user_cfg,
4586 							    band);
4587 		if (QDF_IS_STATUS_ERROR(status)) {
4588 			sme_err("User cfg validation failed");
4589 			return QDF_STATUS_E_FAILURE;
4590 		}
4591 	}
4592 
4593 	return QDF_STATUS_SUCCESS;
4594 }
4595 
4596 static bool
sme_is_nss_update_allowed(struct wlan_mlme_chain_cfg chain_cfg,uint8_t rx_nss,uint8_t tx_nss,enum nss_chains_band_info band)4597 sme_is_nss_update_allowed(struct wlan_mlme_chain_cfg chain_cfg,
4598 			  uint8_t rx_nss, uint8_t tx_nss,
4599 			  enum nss_chains_band_info band)
4600 {
4601 	switch (band) {
4602 	case NSS_CHAINS_BAND_2GHZ:
4603 		if (rx_nss > chain_cfg.max_rx_chains_2g)
4604 			return false;
4605 		if (tx_nss > chain_cfg.max_tx_chains_2g)
4606 			return false;
4607 		break;
4608 	case NSS_CHAINS_BAND_5GHZ:
4609 		if (rx_nss > chain_cfg.max_rx_chains_5g)
4610 			return false;
4611 		if (tx_nss > chain_cfg.max_tx_chains_5g)
4612 			return false;
4613 		break;
4614 	default:
4615 		sme_err("Unknown Band nss change not allowed");
4616 		return false;
4617 	}
4618 	return true;
4619 }
4620 
sme_modify_chains_in_mlme_cfg(mac_handle_t mac_handle,uint8_t rx_chains,uint8_t tx_chains,enum QDF_OPMODE vdev_op_mode,enum nss_chains_band_info band)4621 static void sme_modify_chains_in_mlme_cfg(mac_handle_t mac_handle,
4622 					  uint8_t rx_chains,
4623 					  uint8_t tx_chains,
4624 					  enum QDF_OPMODE vdev_op_mode,
4625 					  enum nss_chains_band_info band)
4626 {
4627 	uint8_t nss_shift;
4628 	uint32_t nss_mask = 0x7;
4629 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
4630 
4631 	nss_shift = sme_get_nss_chain_shift(vdev_op_mode);
4632 
4633 	mac_ctx->mlme_cfg->nss_chains_ini_cfg.num_rx_chains[band] &=
4634 						~(nss_mask << nss_shift);
4635 	mac_ctx->mlme_cfg->nss_chains_ini_cfg.num_rx_chains[band] |=
4636 						 (rx_chains << nss_shift);
4637 	mac_ctx->mlme_cfg->nss_chains_ini_cfg.num_tx_chains[band] &=
4638 						~(nss_mask << nss_shift);
4639 	mac_ctx->mlme_cfg->nss_chains_ini_cfg.num_tx_chains[band] |=
4640 						 (tx_chains << nss_shift);
4641 	sme_debug("rx chains %d tx chains %d changed for vdev mode %d for band %d",
4642 		  rx_chains, tx_chains, vdev_op_mode, band);
4643 }
4644 
4645 static void
sme_modify_nss_in_mlme_cfg(mac_handle_t mac_handle,uint8_t rx_nss,uint8_t tx_nss,enum QDF_OPMODE vdev_op_mode,enum nss_chains_band_info band)4646 sme_modify_nss_in_mlme_cfg(mac_handle_t mac_handle,
4647 			   uint8_t rx_nss, uint8_t tx_nss,
4648 			   enum QDF_OPMODE vdev_op_mode,
4649 			   enum nss_chains_band_info band)
4650 {
4651 	uint8_t nss_shift;
4652 	uint32_t nss_mask = 0x7;
4653 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
4654 
4655 	if (!sme_is_nss_update_allowed(mac_ctx->fw_chain_cfg, rx_nss, tx_nss,
4656 				       band)) {
4657 		sme_debug("Nss modification failed, fw doesn't support this nss %d",
4658 			  rx_nss);
4659 		return;
4660 	}
4661 
4662 	nss_shift = sme_get_nss_chain_shift(vdev_op_mode);
4663 
4664 	mac_ctx->mlme_cfg->nss_chains_ini_cfg.rx_nss[band] &=
4665 						~(nss_mask << nss_shift);
4666 	mac_ctx->mlme_cfg->nss_chains_ini_cfg.rx_nss[band] |=
4667 						 (rx_nss << nss_shift);
4668 	mac_ctx->mlme_cfg->nss_chains_ini_cfg.tx_nss[band] &=
4669 						~(nss_mask << nss_shift);
4670 	mac_ctx->mlme_cfg->nss_chains_ini_cfg.tx_nss[band] |=
4671 						 (tx_nss << nss_shift);
4672 	sme_debug("rx nss %d tx nss %d changed for vdev mode %d for band %d",
4673 		  rx_nss, tx_nss, vdev_op_mode, band);
4674 }
4675 
4676 void
sme_modify_nss_chains_tgt_cfg(mac_handle_t mac_handle,enum QDF_OPMODE vdev_op_mode,enum nss_chains_band_info band)4677 sme_modify_nss_chains_tgt_cfg(mac_handle_t mac_handle,
4678 			      enum QDF_OPMODE vdev_op_mode,
4679 			      enum nss_chains_band_info band)
4680 {
4681 	uint8_t ini_rx_nss;
4682 	uint8_t ini_tx_nss;
4683 	uint8_t max_supported_rx_nss = MAX_VDEV_NSS;
4684 	uint8_t max_supported_tx_nss = MAX_VDEV_NSS;
4685 	uint8_t ini_rx_chains;
4686 	uint8_t ini_tx_chains;
4687 	uint8_t max_supported_rx_chains = MAX_VDEV_CHAINS;
4688 	uint8_t max_supported_tx_chains = MAX_VDEV_CHAINS;
4689 
4690 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
4691 	struct wlan_mlme_nss_chains *nss_chains_ini_cfg =
4692 					&mac_ctx->mlme_cfg->nss_chains_ini_cfg;
4693 	uint8_t nss_shift = sme_get_nss_chain_shift(vdev_op_mode);
4694 	struct wlan_mlme_chain_cfg chain_cfg = mac_ctx->fw_chain_cfg;
4695 
4696 	ini_rx_nss = GET_VDEV_NSS_CHAIN(nss_chains_ini_cfg->rx_nss[band],
4697 					nss_shift);
4698 	ini_tx_nss = GET_VDEV_NSS_CHAIN(nss_chains_ini_cfg->tx_nss[band],
4699 					nss_shift);
4700 
4701 	if (band == NSS_CHAINS_BAND_2GHZ) {
4702 		max_supported_rx_nss = chain_cfg.max_rx_chains_2g;
4703 		max_supported_tx_nss = chain_cfg.max_tx_chains_2g;
4704 	} else if (band == NSS_CHAINS_BAND_5GHZ) {
4705 		max_supported_rx_nss = chain_cfg.max_rx_chains_5g;
4706 		max_supported_tx_nss = chain_cfg.max_tx_chains_5g;
4707 	}
4708 
4709 	max_supported_rx_nss = QDF_MIN(ini_rx_nss, max_supported_rx_nss);
4710 	if (!max_supported_rx_nss)
4711 		return;
4712 
4713 	max_supported_tx_nss = QDF_MIN(ini_tx_nss, max_supported_tx_nss);
4714 	if (!max_supported_tx_nss)
4715 		return;
4716 
4717 	ini_rx_chains = GET_VDEV_NSS_CHAIN(nss_chains_ini_cfg->
4718 						num_rx_chains[band],
4719 					   nss_shift);
4720 	ini_tx_chains = GET_VDEV_NSS_CHAIN(nss_chains_ini_cfg->
4721 						num_tx_chains[band],
4722 					   nss_shift);
4723 
4724 	if (band == NSS_CHAINS_BAND_2GHZ) {
4725 		max_supported_rx_chains = chain_cfg.max_rx_chains_2g;
4726 		max_supported_tx_chains = chain_cfg.max_tx_chains_2g;
4727 	} else if (band == NSS_CHAINS_BAND_5GHZ) {
4728 		max_supported_rx_chains = chain_cfg.max_rx_chains_5g;
4729 		max_supported_tx_chains = chain_cfg.max_tx_chains_5g;
4730 	}
4731 
4732 	max_supported_rx_chains = QDF_MIN(ini_rx_chains,
4733 					  max_supported_rx_chains);
4734 	if (!max_supported_rx_chains)
4735 		return;
4736 
4737 	max_supported_tx_chains = QDF_MIN(ini_tx_chains,
4738 					  max_supported_tx_chains);
4739 	if (!max_supported_tx_chains)
4740 		return;
4741 
4742 	sme_modify_chains_in_mlme_cfg(mac_handle, max_supported_rx_chains,
4743 				      max_supported_tx_chains, vdev_op_mode,
4744 				      band);
4745 	sme_modify_nss_in_mlme_cfg(mac_handle, max_supported_rx_nss,
4746 				   max_supported_tx_nss, vdev_op_mode, band);
4747 }
4748 
4749 void
sme_update_nss_in_mlme_cfg(mac_handle_t mac_handle,uint8_t rx_nss,uint8_t tx_nss,enum QDF_OPMODE vdev_op_mode,enum nss_chains_band_info band)4750 sme_update_nss_in_mlme_cfg(mac_handle_t mac_handle,
4751 			   uint8_t rx_nss, uint8_t tx_nss,
4752 			   enum QDF_OPMODE vdev_op_mode,
4753 			   enum nss_chains_band_info band)
4754 {
4755 	/*
4756 	 * If device mode is P2P-DEVICE, then we want P2P to come in that
4757 	 * particular nss, then we should change the nss of P@P-CLI, and GO
4758 	 * and we are unaware that for what will be the device mode after
4759 	 * negotiation yet.
4760 	 */
4761 
4762 	if (vdev_op_mode == QDF_P2P_DEVICE_MODE ||
4763 	    vdev_op_mode == QDF_P2P_CLIENT_MODE ||
4764 	    vdev_op_mode == QDF_P2P_GO_MODE) {
4765 		sme_modify_nss_in_mlme_cfg(mac_handle, rx_nss, tx_nss,
4766 					   QDF_P2P_CLIENT_MODE, band);
4767 		sme_modify_nss_in_mlme_cfg(mac_handle, rx_nss, tx_nss,
4768 					   QDF_P2P_GO_MODE, band);
4769 		sme_modify_nss_in_mlme_cfg(mac_handle, rx_nss, tx_nss,
4770 					   QDF_P2P_DEVICE_MODE, band);
4771 	} else
4772 		sme_modify_nss_in_mlme_cfg(mac_handle, rx_nss, tx_nss,
4773 					   vdev_op_mode, band);
4774 }
4775 
sme_dump_nss_cfg(struct wlan_mlme_nss_chains * user_cfg)4776 static void sme_dump_nss_cfg(struct wlan_mlme_nss_chains *user_cfg)
4777 {
4778 	sme_debug("num_tx_chains 2g %d 5g %d",
4779 		  user_cfg->num_tx_chains[NSS_CHAINS_BAND_2GHZ],
4780 		  user_cfg->num_tx_chains[NSS_CHAINS_BAND_5GHZ]);
4781 
4782 	sme_debug("num_rx_chains 2g %d 5g %d",
4783 		  user_cfg->num_rx_chains[NSS_CHAINS_BAND_2GHZ],
4784 		  user_cfg->num_rx_chains[NSS_CHAINS_BAND_5GHZ]);
4785 
4786 	sme_debug("tx_nss 2g %d 5g %d",
4787 		  user_cfg->tx_nss[NSS_CHAINS_BAND_2GHZ],
4788 		  user_cfg->tx_nss[NSS_CHAINS_BAND_5GHZ]);
4789 	sme_debug("rx_nss 2g %d 5g %d",
4790 		  user_cfg->rx_nss[NSS_CHAINS_BAND_2GHZ],
4791 		  user_cfg->rx_nss[NSS_CHAINS_BAND_5GHZ]);
4792 	sme_debug("num_tx_chains_11b %d",
4793 		  user_cfg->num_tx_chains_11b);
4794 	sme_debug("num_tx_chains_11g %d",
4795 		  user_cfg->num_tx_chains_11g);
4796 	sme_debug("num_tx_chains_11a %d",
4797 		  user_cfg->num_tx_chains_11a);
4798 }
4799 
4800 QDF_STATUS
sme_nss_chains_update(mac_handle_t mac_handle,struct wlan_mlme_nss_chains * user_cfg,uint8_t vdev_id)4801 sme_nss_chains_update(mac_handle_t mac_handle,
4802 		      struct wlan_mlme_nss_chains *user_cfg,
4803 		      uint8_t vdev_id)
4804 {
4805 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
4806 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
4807 	struct wlan_mlme_nss_chains *dynamic_cfg;
4808 	struct wlan_objmgr_vdev *vdev =
4809 		       wlan_objmgr_get_vdev_by_id_from_psoc(mac_ctx->psoc,
4810 							    vdev_id,
4811 							    WLAN_LEGACY_SME_ID);
4812 	uint8_t ll_lt_sap_vdev_id;
4813 
4814 	if (!vdev) {
4815 		sme_err("Got NULL vdev obj, returning");
4816 		return QDF_STATUS_E_FAILURE;
4817 	}
4818 
4819 	ll_lt_sap_vdev_id =
4820 			wlan_policy_mgr_get_ll_lt_sap_vdev_id(mac_ctx->psoc);
4821 	if (ll_lt_sap_vdev_id != WLAN_INVALID_VDEV_ID) {
4822 		sme_info_rl("LL_LT_SAP vdev %d present, chainmask config not allowed",
4823 			    ll_lt_sap_vdev_id);
4824 		goto release_ref;
4825 	}
4826 
4827 	if (QDF_STATUS_SUCCESS == wlan_is_tdls_session_present(vdev)) {
4828 		sme_debug("TDLS session exists");
4829 		status = QDF_STATUS_E_FAILURE;
4830 		goto release_ref;
4831 	}
4832 
4833 	status = sme_acquire_global_lock(&mac_ctx->sme);
4834 	if (QDF_IS_STATUS_ERROR(status))
4835 		goto release_ref;
4836 
4837 	dynamic_cfg = mlme_get_dynamic_vdev_config(vdev);
4838 	if (!dynamic_cfg) {
4839 		sme_err("nss chain dynamic config NULL");
4840 		status = QDF_STATUS_E_FAILURE;
4841 		goto release_lock;
4842 	}
4843 
4844 	status = sme_validate_nss_chains_config(vdev, user_cfg,
4845 						dynamic_cfg);
4846 	sme_debug("dynamic_cfg");
4847 	sme_dump_nss_cfg(dynamic_cfg);
4848 	sme_debug("user_cfg");
4849 	sme_dump_nss_cfg(user_cfg);
4850 
4851 	if (QDF_IS_STATUS_ERROR(status))
4852 		goto release_lock;
4853 
4854 	if (!qdf_mem_cmp(dynamic_cfg, user_cfg,
4855 			 sizeof(struct wlan_mlme_nss_chains))) {
4856 		sme_debug("current config same as user config");
4857 		status = QDF_STATUS_SUCCESS;
4858 		goto release_lock;
4859 	}
4860 	sme_debug("User params verified, sending to fw vdev id %d", vdev_id);
4861 
4862 	status = wma_vdev_nss_chain_params_send(vdev->vdev_objmgr.vdev_id,
4863 						user_cfg);
4864 	if (QDF_IS_STATUS_ERROR(status)) {
4865 		sme_err("params sent failed to fw vdev id %d", vdev_id);
4866 		goto release_lock;
4867 	}
4868 
4869 	*dynamic_cfg = *user_cfg;
4870 
4871 release_lock:
4872 	sme_release_global_lock(&mac_ctx->sme);
4873 
4874 release_ref:
4875 	wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID);
4876 	return status;
4877 }
4878 
4879 #ifdef WLAN_FEATURE_11AX
sme_update_bfer_he_cap(struct wma_tgt_cfg * cfg)4880 static void sme_update_bfer_he_cap(struct wma_tgt_cfg *cfg)
4881 {
4882 	cfg->he_cap_5g.su_beamformer = 0;
4883 }
4884 #else
sme_update_bfer_he_cap(struct wma_tgt_cfg * cfg)4885 static void sme_update_bfer_he_cap(struct wma_tgt_cfg *cfg)
4886 {
4887 }
4888 #endif
4889 
4890 #ifdef WLAN_FEATURE_11BE
sme_update_bfer_eht_cap(struct wma_tgt_cfg * cfg)4891 static void sme_update_bfer_eht_cap(struct wma_tgt_cfg *cfg)
4892 {
4893 	cfg->eht_cap_5g.su_beamformer = 0;
4894 }
4895 #else
sme_update_bfer_eht_cap(struct wma_tgt_cfg * cfg)4896 static void sme_update_bfer_eht_cap(struct wma_tgt_cfg *cfg)
4897 {
4898 }
4899 #endif
4900 
sme_update_bfer_caps_as_per_nss_chains(mac_handle_t mac_handle,struct wma_tgt_cfg * cfg)4901 void sme_update_bfer_caps_as_per_nss_chains(mac_handle_t mac_handle,
4902 					    struct wma_tgt_cfg *cfg)
4903 {
4904 	uint8_t max_supported_tx_chains = MAX_VDEV_CHAINS;
4905 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
4906 	struct wlan_mlme_nss_chains *nss_chains_ini_cfg =
4907 					&mac_ctx->mlme_cfg->nss_chains_ini_cfg;
4908 	uint8_t ini_tx_chains;
4909 
4910 	ini_tx_chains = GET_VDEV_NSS_CHAIN(
4911 			nss_chains_ini_cfg->num_tx_chains[NSS_CHAINS_BAND_5GHZ],
4912 			SAP_NSS_CHAINS_SHIFT);
4913 
4914 	max_supported_tx_chains =
4915 			mac_ctx->fw_chain_cfg.max_tx_chains_5g;
4916 
4917 	max_supported_tx_chains = QDF_MIN(ini_tx_chains,
4918 					  max_supported_tx_chains);
4919 	if (!max_supported_tx_chains)
4920 		return;
4921 
4922 	if (max_supported_tx_chains == 1) {
4923 		sme_debug("ini support %d and firmware support %d",
4924 			  ini_tx_chains,
4925 			  mac_ctx->fw_chain_cfg.max_tx_chains_5g);
4926 		if (mac_ctx->fw_chain_cfg.max_tx_chains_5g == 1) {
4927 			cfg->vht_cap.vht_su_bformer = 0;
4928 			sme_update_bfer_he_cap(cfg);
4929 			sme_update_bfer_eht_cap(cfg);
4930 		}
4931 		mac_ctx->mlme_cfg->vht_caps.vht_cap_info.su_bformer = 0;
4932 		mac_ctx->mlme_cfg->vht_caps.vht_cap_info.num_soundingdim = 0;
4933 		mac_ctx->mlme_cfg->vht_caps.vht_cap_info.mu_bformer = 0;
4934 	}
4935 }
4936 
sme_vdev_post_vdev_create_setup(mac_handle_t mac_handle,struct wlan_objmgr_vdev * vdev)4937 QDF_STATUS sme_vdev_post_vdev_create_setup(mac_handle_t mac_handle,
4938 					   struct wlan_objmgr_vdev *vdev)
4939 {
4940 	struct vdev_mlme_obj *vdev_mlme;
4941 	QDF_STATUS status = QDF_STATUS_E_INVAL;
4942 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
4943 	uint8_t vdev_id;
4944 
4945 	vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev);
4946 	if (!vdev_mlme) {
4947 		sme_err("Failed to get vdev mlme obj!");
4948 		QDF_BUG(0);
4949 		return status;
4950 	}
4951 
4952 	vdev_id = wlan_vdev_get_id(vdev);
4953 	status = wma_post_vdev_create_setup(vdev);
4954 	if (QDF_IS_STATUS_ERROR(status)) {
4955 		sme_err("Failed to setup wma for vdev: %d", vdev_id);
4956 		return status;
4957 	}
4958 
4959 	status = csr_setup_vdev_session(vdev_mlme);
4960 	if (QDF_IS_STATUS_ERROR(status)) {
4961 		sme_err("Failed to setup CSR layer for vdev: %d", vdev_id);
4962 		goto cleanup_wma;
4963 	}
4964 
4965 	wlan_vdev_set_dot11mode(mac_ctx->mlme_cfg, vdev->vdev_mlme.vdev_opmode,
4966 				vdev_mlme);
4967 
4968 	status = mlme_vdev_self_peer_create(vdev);
4969 	if (QDF_IS_STATUS_ERROR(status)) {
4970 		sme_err("Failed to create vdev selfpeer for vdev:%d", vdev_id);
4971 		goto csr_cleanup_vdev_session;
4972 	}
4973 
4974 	return status;
4975 
4976 csr_cleanup_vdev_session:
4977 	csr_cleanup_vdev_session(mac_ctx, vdev_id);
4978 cleanup_wma:
4979 	wma_cleanup_vdev(vdev);
4980 	return status;
4981 }
4982 
sme_vdev_set_data_tx_callback(struct wlan_objmgr_vdev * vdev)4983 QDF_STATUS sme_vdev_set_data_tx_callback(struct wlan_objmgr_vdev *vdev)
4984 {
4985 	return wma_vdev_set_data_tx_callback(vdev);
4986 }
4987 
4988 struct wlan_objmgr_vdev
sme_vdev_create(mac_handle_t mac_handle,struct wlan_vdev_create_params * vdev_params)4989 *sme_vdev_create(mac_handle_t mac_handle,
4990 		 struct wlan_vdev_create_params *vdev_params)
4991 {
4992 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
4993 	struct wlan_objmgr_vdev *vdev;
4994 
4995 	sme_debug("addr:"QDF_MAC_ADDR_FMT" opmode:%d",
4996 		  QDF_MAC_ADDR_REF(vdev_params->macaddr),
4997 		  vdev_params->opmode);
4998 
4999 	vdev = wlan_objmgr_vdev_obj_create(mac_ctx->pdev, vdev_params);
5000 	if (!vdev) {
5001 		sme_err("Failed to create vdev object");
5002 		return NULL;
5003 	}
5004 
5005 	if (wlan_objmgr_vdev_try_get_ref(vdev, WLAN_LEGACY_SME_ID) !=
5006 	    QDF_STATUS_SUCCESS) {
5007 		wlan_objmgr_vdev_obj_delete(vdev);
5008 		return NULL;
5009 	}
5010 
5011 	cm_utf_attach(vdev);
5012 	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
5013 			 TRACE_CODE_SME_RX_HDD_OPEN_SESSION,
5014 			 wlan_vdev_get_id(vdev), 0));
5015 
5016 	return vdev;
5017 }
5018 
sme_vdev_del_resp(uint8_t vdev_id)5019 void sme_vdev_del_resp(uint8_t vdev_id)
5020 {
5021 	mac_handle_t mac_handle;
5022 	struct mac_context *mac;
5023 
5024 	mac_handle = cds_get_context(QDF_MODULE_ID_SME);
5025 	if (!mac_handle) {
5026 		QDF_ASSERT(0);
5027 		return;
5028 	}
5029 
5030 	mac = MAC_CONTEXT(mac_handle);
5031 	csr_cleanup_vdev_session(mac, vdev_id);
5032 
5033 	if (mac->session_close_cb)
5034 		mac->session_close_cb(vdev_id);
5035 }
5036 
sme_vdev_self_peer_delete_resp(struct del_vdev_params * del_vdev_req)5037 QDF_STATUS sme_vdev_self_peer_delete_resp(struct del_vdev_params *del_vdev_req)
5038 {
5039 	struct wlan_objmgr_vdev *vdev;
5040 	QDF_STATUS status;
5041 
5042 	vdev = del_vdev_req->vdev;
5043 	if (!vdev) {
5044 		qdf_mem_free(del_vdev_req);
5045 		return QDF_STATUS_E_INVAL;
5046 	}
5047 
5048 	if (vdev->obj_state == WLAN_OBJ_STATE_LOGICALLY_DELETED) {
5049 		wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID);
5050 		wma_debug("vdev delete");
5051 	} else {
5052 		wlan_vdev_mlme_notify_set_mac_addr_response(vdev,
5053 							    del_vdev_req->status);
5054 		wma_debug("mac update");
5055 	}
5056 
5057 	status = del_vdev_req->status;
5058 	qdf_mem_free(del_vdev_req);
5059 	return status;
5060 }
5061 
sme_vdev_delete(mac_handle_t mac_handle,struct wlan_objmgr_vdev * vdev)5062 QDF_STATUS sme_vdev_delete(mac_handle_t mac_handle,
5063 			   struct wlan_objmgr_vdev *vdev)
5064 {
5065 	QDF_STATUS status;
5066 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
5067 	uint8_t *self_peer_macaddr, vdev_id = wlan_vdev_get_id(vdev);
5068 	struct scheduler_msg self_peer_delete_msg = {0};
5069 	struct del_vdev_params *del_self_peer;
5070 	bool is_pasn_peer_delete_all_required;
5071 
5072 	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
5073 			 TRACE_CODE_SME_RX_HDD_CLOSE_SESSION, vdev_id, 0));
5074 
5075 	is_pasn_peer_delete_all_required =
5076 		wlan_wifi_pos_pasn_peer_delete_all(mac->psoc, vdev_id);
5077 	if (is_pasn_peer_delete_all_required) {
5078 		sme_info("Resume vdev delete after pasn peers deletion");
5079 		return QDF_STATUS_SUCCESS;
5080 	}
5081 
5082 	status = sme_acquire_global_lock(&mac->sme);
5083 
5084 	if (QDF_IS_STATUS_SUCCESS(status)) {
5085 		status = csr_prepare_vdev_delete(mac, vdev);
5086 		sme_release_global_lock(&mac->sme);
5087 	}
5088 
5089 	/*
5090 	 * While this vdev delete is invoked we will still have following
5091 	 * references held:
5092 	 * WLAN_LEGACY_WMA_ID -- 1
5093 	 * WLAN_LEGACY_SME_ID -- 1
5094 	 * WLAN_OBJMGR_ID -- 2
5095 	 * Following message will release the self and delete the self peer
5096 	 * and release the wma references so the objmgr and wma_legacy will be
5097 	 * released because of this.
5098 	 *
5099 	 * In the message callback the legacy_sme reference will be released
5100 	 * resulting in the last reference of vdev object and sending the
5101 	 * vdev_delete to firmware.
5102 	 */
5103 	status = wlan_objmgr_vdev_obj_delete(vdev);
5104 	if (QDF_IS_STATUS_ERROR(status)) {
5105 		sme_nofl_err("Failed to mark vdev as logical delete %d",
5106 			     status);
5107 		return status;
5108 	}
5109 
5110 	cm_utf_detach(vdev);
5111 
5112 	del_self_peer = qdf_mem_malloc(sizeof(*del_self_peer));
5113 	if (!del_self_peer)
5114 		return QDF_STATUS_E_NOMEM;
5115 
5116 	self_peer_macaddr = wlan_vdev_mlme_get_mldaddr(vdev);
5117 	if (qdf_is_macaddr_zero((struct qdf_mac_addr *)self_peer_macaddr))
5118 		self_peer_macaddr = wlan_vdev_mlme_get_macaddr(vdev);
5119 
5120 	del_self_peer->vdev = vdev;
5121 	del_self_peer->vdev_id = wlan_vdev_get_id(vdev);
5122 	qdf_mem_copy(del_self_peer->self_mac_addr, self_peer_macaddr,
5123 		     sizeof(tSirMacAddr));
5124 
5125 	self_peer_delete_msg.bodyptr = del_self_peer;
5126 	self_peer_delete_msg.callback = mlme_vdev_self_peer_delete;
5127 	status = scheduler_post_message(QDF_MODULE_ID_SME,
5128 					QDF_MODULE_ID_MLME,
5129 					QDF_MODULE_ID_TARGET_IF,
5130 					&self_peer_delete_msg);
5131 
5132 	if (QDF_IS_STATUS_ERROR(status)) {
5133 		sme_err("Failed to post vdev selfpeer for vdev:%d", vdev_id);
5134 		wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID);
5135 		qdf_mem_free(del_self_peer);
5136 	}
5137 
5138 	return status;
5139 }
5140 
sme_cleanup_session(mac_handle_t mac_handle,uint8_t vdev_id)5141 void sme_cleanup_session(mac_handle_t mac_handle, uint8_t vdev_id)
5142 {
5143 	QDF_STATUS status;
5144 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
5145 
5146 	status = sme_acquire_global_lock(&mac->sme);
5147 	if (QDF_IS_STATUS_ERROR(status))
5148 		return;
5149 	csr_cleanup_vdev_session(mac, vdev_id);
5150 	sme_release_global_lock(&mac->sme);
5151 }
5152 
5153 /*
5154  * sme_change_mcc_beacon_interval() -
5155  * To update P2P-GO beaconInterval. This function should be called after
5156  *    disassociating all the station is done
5157  *   This is an asynchronous API.
5158  *
5159  * @sessionId: Session Identifier
5160  * Return QDF_STATUS  SUCCESS
5161  *			FAILURE or RESOURCES
5162  *			The API finished and failed.
5163  */
sme_change_mcc_beacon_interval(uint8_t sessionId)5164 QDF_STATUS sme_change_mcc_beacon_interval(uint8_t sessionId)
5165 {
5166 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
5167 	struct mac_context *mac_ctx = sme_get_mac_context();
5168 
5169 	if (!mac_ctx) {
5170 		sme_err("mac_ctx is NULL");
5171 		return status;
5172 	}
5173 	status = sme_acquire_global_lock(&mac_ctx->sme);
5174 	if (QDF_IS_STATUS_SUCCESS(status)) {
5175 		status = csr_send_chng_mcc_beacon_interval(mac_ctx,
5176 							   sessionId);
5177 		sme_release_global_lock(&mac_ctx->sme);
5178 	}
5179 	return status;
5180 }
5181 
sme_change_sap_csa_count(uint8_t count)5182 QDF_STATUS sme_change_sap_csa_count(uint8_t count)
5183 {
5184 	struct mac_context *mac_ctx = sme_get_mac_context();
5185 
5186 	if (!mac_ctx) {
5187 		sme_err("mac_ctx is NULL");
5188 		return QDF_STATUS_E_FAILURE;
5189 	}
5190 	mac_ctx->sap.one_time_csa_count = count;
5191 
5192 	return QDF_STATUS_SUCCESS;
5193 }
5194 
5195 /**
5196  * sme_set_host_offload(): API to set the host offload feature.
5197  * @mac_handle: The handle returned by mac_open.
5198  * @sessionId: Session Identifier
5199  * @request: Pointer to the offload request.
5200  *
5201  * Return QDF_STATUS
5202  */
sme_set_host_offload(mac_handle_t mac_handle,uint8_t sessionId,struct sir_host_offload_req * request)5203 QDF_STATUS sme_set_host_offload(mac_handle_t mac_handle, uint8_t sessionId,
5204 				struct sir_host_offload_req *request)
5205 {
5206 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
5207 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
5208 
5209 	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
5210 			 TRACE_CODE_SME_RX_HDD_SET_HOSTOFFLOAD, sessionId, 0));
5211 	status = sme_acquire_global_lock(&mac->sme);
5212 	if (QDF_IS_STATUS_SUCCESS(status)) {
5213 #ifdef WLAN_NS_OFFLOAD
5214 		if (SIR_IPV6_NS_OFFLOAD == request->offloadType) {
5215 			status = sme_set_ps_ns_offload(mac_handle, request,
5216 					sessionId);
5217 		} else
5218 #endif /* WLAN_NS_OFFLOAD */
5219 		{
5220 			status = sme_set_ps_host_offload(mac_handle, request,
5221 					sessionId);
5222 		}
5223 		sme_release_global_lock(&mac->sme);
5224 	}
5225 
5226 	return status;
5227 }
5228 
5229 /*
5230  * sme_set_keep_alive() -
5231  * API to set the Keep Alive feature.
5232  *
5233  * mac_handle - The handle returned by mac_open.
5234  * request -  Pointer to the Keep Alive request.
5235  * Return QDF_STATUS
5236  */
sme_set_keep_alive(mac_handle_t mac_handle,uint8_t session_id,struct keep_alive_req * request)5237 QDF_STATUS sme_set_keep_alive(mac_handle_t mac_handle, uint8_t session_id,
5238 			      struct keep_alive_req *request)
5239 {
5240 	struct keep_alive_req *request_buf;
5241 	struct scheduler_msg msg = {0};
5242 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
5243 
5244 	if (!CSR_IS_SESSION_VALID(mac, session_id)) {
5245 		sme_err("invalid vdev %d", session_id);
5246 		return QDF_STATUS_E_INVAL;
5247 	}
5248 
5249 	request_buf = qdf_mem_malloc(sizeof(*request_buf));
5250 	if (!request_buf)
5251 		return QDF_STATUS_E_NOMEM;
5252 
5253 	wlan_mlme_get_bssid_vdev_id(mac->pdev, session_id,
5254 				    &request->bssid);
5255 	qdf_mem_copy(request_buf, request, sizeof(*request_buf));
5256 
5257 	sme_debug("vdev %d buff TP %d input TP %d ", session_id,
5258 		  request_buf->timePeriod, request->timePeriod);
5259 	request_buf->sessionId = session_id;
5260 
5261 	msg.type = WMA_SET_KEEP_ALIVE;
5262 	msg.reserved = 0;
5263 	msg.bodyptr = request_buf;
5264 	MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG,
5265 			 session_id, msg.type));
5266 	if (QDF_STATUS_SUCCESS !=
5267 			scheduler_post_message(QDF_MODULE_ID_SME,
5268 					       QDF_MODULE_ID_WMA,
5269 					       QDF_MODULE_ID_WMA, &msg)) {
5270 		sme_err("Not able to post WMA_SET_KEEP_ALIVE message to WMA");
5271 		qdf_mem_free(request_buf);
5272 		return QDF_STATUS_E_FAILURE;
5273 	}
5274 
5275 	return QDF_STATUS_SUCCESS;
5276 }
5277 
5278 /*
5279  * sme_get_operation_channel() -
5280  * API to get current channel on which STA is parked his function gives
5281  * channel information only of infra station
5282  *
5283  * mac_handle, pointer to memory location and sessionId
5284  * Returns QDF_STATUS_SUCCESS
5285  *	     QDF_STATUS_E_FAILURE
5286  */
sme_get_operation_channel(mac_handle_t mac_handle,uint32_t * chan_freq,uint8_t sessionId)5287 QDF_STATUS sme_get_operation_channel(mac_handle_t mac_handle,
5288 				     uint32_t *chan_freq,
5289 				     uint8_t sessionId)
5290 {
5291 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
5292 
5293 	if (CSR_IS_SESSION_VALID(mac, sessionId)) {
5294 		*chan_freq = wlan_get_operation_chan_freq_vdev_id(mac->pdev,
5295 								  sessionId);
5296 		return QDF_STATUS_SUCCESS;
5297 	}
5298 
5299 	return QDF_STATUS_E_FAILURE;
5300 } /* sme_get_operation_channel ends here */
5301 
5302 /**
5303  * sme_register_mgmt_frame_ind_callback() - Register a callback for
5304  * management frame indication to PE.
5305  *
5306  * @mac_handle: Opaque handle to the global MAC context
5307  * @callback: callback pointer to be registered
5308  *
5309  * This function is used to register a callback for management
5310  * frame indication to PE.
5311  *
5312  * Return: Success if msg is posted to PE else Failure.
5313  */
sme_register_mgmt_frame_ind_callback(mac_handle_t mac_handle,sir_mgmt_frame_ind_callback callback)5314 QDF_STATUS sme_register_mgmt_frame_ind_callback(mac_handle_t mac_handle,
5315 				sir_mgmt_frame_ind_callback callback)
5316 {
5317 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
5318 	struct sir_sme_mgmt_frame_cb_req *msg;
5319 	QDF_STATUS status = QDF_STATUS_SUCCESS;
5320 
5321 	if (QDF_STATUS_SUCCESS ==
5322 			sme_acquire_global_lock(&mac_ctx->sme)) {
5323 		msg = qdf_mem_malloc(sizeof(*msg));
5324 		if (!msg) {
5325 			sme_release_global_lock(&mac_ctx->sme);
5326 			return QDF_STATUS_E_NOMEM;
5327 		}
5328 		msg->message_type = eWNI_SME_REGISTER_MGMT_FRAME_CB;
5329 		msg->length          = sizeof(*msg);
5330 
5331 		msg->callback = callback;
5332 		status = umac_send_mb_message_to_mac(msg);
5333 		sme_release_global_lock(&mac_ctx->sme);
5334 		return status;
5335 	}
5336 	return QDF_STATUS_E_FAILURE;
5337 }
5338 
5339 /*
5340  * sme_RegisterMgtFrame() -
5341  * To register management frame of specified type and subtype.
5342  *
5343  * frameType - type of the frame that needs to be passed to HDD.
5344  * matchData - data which needs to be matched before passing frame
5345  *		       to HDD.
5346  * matchDataLen - Length of matched data.
5347  * Return QDF_STATUS
5348  */
sme_register_mgmt_frame(mac_handle_t mac_handle,uint8_t sessionId,uint16_t frameType,uint8_t * matchData,uint16_t matchLen)5349 QDF_STATUS sme_register_mgmt_frame(mac_handle_t mac_handle, uint8_t sessionId,
5350 				   uint16_t frameType, uint8_t *matchData,
5351 				   uint16_t matchLen)
5352 {
5353 	QDF_STATUS status = QDF_STATUS_SUCCESS;
5354 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
5355 
5356 	status = sme_acquire_global_lock(&mac->sme);
5357 	if (QDF_IS_STATUS_SUCCESS(status)) {
5358 		struct register_mgmt_frame *pMsg;
5359 		uint16_t len;
5360 		struct csr_roam_session *pSession = CSR_GET_SESSION(mac,
5361 							sessionId);
5362 
5363 		if (!CSR_IS_SESSION_ANY(sessionId) && !pSession) {
5364 			sme_err("Session %d not found",	sessionId);
5365 			sme_release_global_lock(&mac->sme);
5366 			return QDF_STATUS_E_FAILURE;
5367 		}
5368 
5369 		if (!CSR_IS_SESSION_ANY(sessionId) &&
5370 						!pSession->sessionActive) {
5371 			sme_err("Invalid Sessionid");
5372 			sme_release_global_lock(&mac->sme);
5373 			return QDF_STATUS_E_FAILURE;
5374 		}
5375 
5376 		len = sizeof(*pMsg) + matchLen;
5377 
5378 		pMsg = qdf_mem_malloc(len);
5379 		if (!pMsg)
5380 			status = QDF_STATUS_E_NOMEM;
5381 		else {
5382 			pMsg->messageType = eWNI_SME_REGISTER_MGMT_FRAME_REQ;
5383 			pMsg->length = len;
5384 			pMsg->sessionId = sessionId;
5385 			pMsg->registerFrame = true;
5386 			pMsg->frameType = frameType;
5387 			pMsg->matchLen = matchLen;
5388 			qdf_mem_copy(pMsg->matchData, matchData, matchLen);
5389 			status = umac_send_mb_message_to_mac(pMsg);
5390 		}
5391 		sme_release_global_lock(&mac->sme);
5392 	}
5393 	return status;
5394 }
5395 
5396 /*
5397  * sme_DeregisterMgtFrame() -
5398  * To De-register management frame of specified type and subtype.
5399  *
5400  * frameType - type of the frame that needs to be passed to HDD.
5401  * matchData - data which needs to be matched before passing frame
5402  *		       to HDD.
5403  * matchDataLen - Length of matched data.
5404  * Return QDF_STATUS
5405  */
sme_deregister_mgmt_frame(mac_handle_t mac_handle,uint8_t sessionId,uint16_t frameType,uint8_t * matchData,uint16_t matchLen)5406 QDF_STATUS sme_deregister_mgmt_frame(mac_handle_t mac_handle, uint8_t sessionId,
5407 				     uint16_t frameType, uint8_t *matchData,
5408 				     uint16_t matchLen)
5409 {
5410 	QDF_STATUS status = QDF_STATUS_SUCCESS;
5411 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
5412 
5413 	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
5414 			 TRACE_CODE_SME_RX_HDD_DEREGISTER_MGMTFR, sessionId,
5415 			 0));
5416 	status = sme_acquire_global_lock(&mac->sme);
5417 	if (QDF_IS_STATUS_SUCCESS(status)) {
5418 		struct register_mgmt_frame *pMsg;
5419 		uint16_t len;
5420 		struct csr_roam_session *pSession = CSR_GET_SESSION(mac,
5421 							sessionId);
5422 
5423 		if (!CSR_IS_SESSION_ANY(sessionId) && !pSession) {
5424 			sme_err("Session %d not found",	sessionId);
5425 			sme_release_global_lock(&mac->sme);
5426 			return QDF_STATUS_E_FAILURE;
5427 		}
5428 
5429 		if (!CSR_IS_SESSION_ANY(sessionId) &&
5430 						!pSession->sessionActive) {
5431 			sme_err("Invalid Sessionid");
5432 			sme_release_global_lock(&mac->sme);
5433 			return QDF_STATUS_E_FAILURE;
5434 		}
5435 
5436 		len = sizeof(*pMsg) + matchLen;
5437 
5438 		pMsg = qdf_mem_malloc(len);
5439 		if (!pMsg)
5440 			status = QDF_STATUS_E_NOMEM;
5441 		else {
5442 			pMsg->messageType = eWNI_SME_REGISTER_MGMT_FRAME_REQ;
5443 			pMsg->length = len;
5444 			pMsg->registerFrame = false;
5445 			pMsg->frameType = frameType;
5446 			pMsg->matchLen = matchLen;
5447 			qdf_mem_copy(pMsg->matchData, matchData, matchLen);
5448 			status = umac_send_mb_message_to_mac(pMsg);
5449 		}
5450 		sme_release_global_lock(&mac->sme);
5451 	}
5452 	return status;
5453 }
5454 
5455 /**
5456  * sme_prepare_mgmt_tx() - Prepares mgmt frame
5457  * @mac_handle: The handle returned by mac_open
5458  * @vdev_id: vdev id
5459  * @buf: pointer to frame
5460  * @len: frame length
5461  *
5462  * Return: QDF_STATUS
5463  */
sme_prepare_mgmt_tx(mac_handle_t mac_handle,uint8_t vdev_id,const uint8_t * buf,uint32_t len)5464 static QDF_STATUS sme_prepare_mgmt_tx(mac_handle_t mac_handle,
5465 				      uint8_t vdev_id,
5466 				      const uint8_t *buf, uint32_t len)
5467 {
5468 	QDF_STATUS status = QDF_STATUS_SUCCESS;
5469 	struct sir_mgmt_msg *msg;
5470 	uint16_t msg_len;
5471 	struct scheduler_msg sch_msg = {0};
5472 
5473 	sme_debug("prepares auth frame");
5474 
5475 	msg_len = sizeof(*msg) + len;
5476 	msg = qdf_mem_malloc(msg_len);
5477 	if (!msg) {
5478 		status = QDF_STATUS_E_NOMEM;
5479 	} else {
5480 		msg->type = eWNI_SME_SEND_MGMT_FRAME_TX;
5481 		msg->msg_len = msg_len;
5482 		msg->vdev_id = vdev_id;
5483 		msg->data = (uint8_t *)msg + sizeof(*msg);
5484 		qdf_mem_copy(msg->data, buf, len);
5485 
5486 		sch_msg.type = eWNI_SME_SEND_MGMT_FRAME_TX;
5487 		sch_msg.bodyptr = msg;
5488 		status = scheduler_post_message(QDF_MODULE_ID_SME,
5489 						QDF_MODULE_ID_PE,
5490 						QDF_MODULE_ID_PE, &sch_msg);
5491 	}
5492 	return status;
5493 }
5494 
sme_send_mgmt_tx(mac_handle_t mac_handle,uint8_t session_id,const uint8_t * buf,uint32_t len)5495 QDF_STATUS sme_send_mgmt_tx(mac_handle_t mac_handle, uint8_t session_id,
5496 			    const uint8_t *buf, uint32_t len)
5497 {
5498 	QDF_STATUS status = QDF_STATUS_SUCCESS;
5499 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
5500 
5501 	status = sme_acquire_global_lock(&mac->sme);
5502 	if (QDF_IS_STATUS_SUCCESS(status)) {
5503 		status = sme_prepare_mgmt_tx(mac_handle, session_id, buf, len);
5504 		sme_release_global_lock(&mac->sme);
5505 	}
5506 
5507 	return status;
5508 }
5509 
5510 #ifdef WLAN_FEATURE_EXTWOW_SUPPORT
5511 /**
5512  * sme_configure_ext_wow() - configure Extr WoW
5513  * @mac_handle - The handle returned by mac_open.
5514  * @wlanExtParams - Depicts the wlan Ext params.
5515  * @callback - ext_wow callback to be registered.
5516  * @callback_context - ext_wow callback context
5517  *
5518  * SME will pass this request to lower mac to configure Extr WoW
5519  * Return: QDF_STATUS
5520  */
sme_configure_ext_wow(mac_handle_t mac_handle,tpSirExtWoWParams wlanExtParams,csr_readyToExtWoWCallback callback,void * callback_context)5521 QDF_STATUS sme_configure_ext_wow(mac_handle_t mac_handle,
5522 				 tpSirExtWoWParams wlanExtParams,
5523 				 csr_readyToExtWoWCallback callback,
5524 				 void *callback_context)
5525 {
5526 	QDF_STATUS status = QDF_STATUS_SUCCESS;
5527 	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
5528 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
5529 	struct scheduler_msg message = {0};
5530 	tpSirExtWoWParams MsgPtr = qdf_mem_malloc(sizeof(*MsgPtr));
5531 
5532 	if (!MsgPtr)
5533 		return QDF_STATUS_E_NOMEM;
5534 
5535 	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
5536 			 TRACE_CODE_SME_RX_HDD_CONFIG_EXTWOW, NO_SESSION, 0));
5537 
5538 	mac->readyToExtWoWCallback = callback;
5539 	mac->readyToExtWoWContext = callback_context;
5540 
5541 	status = sme_acquire_global_lock(&mac->sme);
5542 	if (QDF_IS_STATUS_SUCCESS(status)) {
5543 
5544 		/* serialize the req through MC thread */
5545 		qdf_mem_copy(MsgPtr, wlanExtParams, sizeof(*MsgPtr));
5546 		message.bodyptr = MsgPtr;
5547 		message.type = WMA_WLAN_EXT_WOW;
5548 		qdf_status = scheduler_post_message(QDF_MODULE_ID_SME,
5549 						    QDF_MODULE_ID_WMA,
5550 						    QDF_MODULE_ID_WMA,
5551 						    &message);
5552 		if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
5553 			mac->readyToExtWoWCallback = NULL;
5554 			mac->readyToExtWoWContext = NULL;
5555 			qdf_mem_free(MsgPtr);
5556 			status = QDF_STATUS_E_FAILURE;
5557 		}
5558 		sme_release_global_lock(&mac->sme);
5559 	} else {
5560 		mac->readyToExtWoWCallback = NULL;
5561 		mac->readyToExtWoWContext = NULL;
5562 		qdf_mem_free(MsgPtr);
5563 	}
5564 
5565 	return status;
5566 }
5567 
5568 /*
5569  * sme_configure_app_type1_params() -
5570  * SME will pass this request to lower mac to configure Indoor WoW parameters.
5571  *
5572  * mac_handle - The handle returned by mac_open.
5573  * wlanAppType1Params- Depicts the wlan App Type 1(Indoor) params
5574  * Return QDF_STATUS
5575  */
sme_configure_app_type1_params(mac_handle_t mac_handle,tpSirAppType1Params wlanAppType1Params)5576 QDF_STATUS sme_configure_app_type1_params(mac_handle_t mac_handle,
5577 					  tpSirAppType1Params wlanAppType1Params)
5578 {
5579 	QDF_STATUS status = QDF_STATUS_SUCCESS;
5580 	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
5581 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
5582 	struct scheduler_msg message = {0};
5583 	tpSirAppType1Params MsgPtr = qdf_mem_malloc(sizeof(*MsgPtr));
5584 
5585 	if (!MsgPtr)
5586 		return QDF_STATUS_E_NOMEM;
5587 
5588 	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
5589 			 TRACE_CODE_SME_RX_HDD_CONFIG_APP_TYPE1, NO_SESSION,
5590 			 0));
5591 
5592 	status = sme_acquire_global_lock(&mac->sme);
5593 	if (QDF_IS_STATUS_SUCCESS(status)) {
5594 		/* serialize the req through MC thread */
5595 		qdf_mem_copy(MsgPtr, wlanAppType1Params, sizeof(*MsgPtr));
5596 		message.bodyptr = MsgPtr;
5597 		message.type = WMA_WLAN_SET_APP_TYPE1_PARAMS;
5598 		qdf_status = scheduler_post_message(QDF_MODULE_ID_SME,
5599 						    QDF_MODULE_ID_WMA,
5600 						    QDF_MODULE_ID_WMA,
5601 						    &message);
5602 		if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
5603 			qdf_mem_free(MsgPtr);
5604 			status = QDF_STATUS_E_FAILURE;
5605 		}
5606 		sme_release_global_lock(&mac->sme);
5607 	} else {
5608 		qdf_mem_free(MsgPtr);
5609 	}
5610 
5611 	return status;
5612 }
5613 
5614 /*
5615  * sme_configure_app_type2_params() -
5616  * SME will pass this request to lower mac to configure Indoor WoW parameters.
5617  *
5618  * mac_handle - The handle returned by mac_open.
5619  * wlanAppType2Params- Depicts the wlan App Type 2 (Outdoor) params
5620  * Return QDF_STATUS
5621  */
sme_configure_app_type2_params(mac_handle_t mac_handle,tpSirAppType2Params wlanAppType2Params)5622 QDF_STATUS sme_configure_app_type2_params(mac_handle_t mac_handle,
5623 					 tpSirAppType2Params wlanAppType2Params)
5624 {
5625 	QDF_STATUS status = QDF_STATUS_SUCCESS;
5626 	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
5627 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
5628 	struct scheduler_msg message = {0};
5629 	tpSirAppType2Params MsgPtr = qdf_mem_malloc(sizeof(*MsgPtr));
5630 
5631 	if (!MsgPtr)
5632 		return QDF_STATUS_E_NOMEM;
5633 
5634 	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
5635 			 TRACE_CODE_SME_RX_HDD_CONFIG_APP_TYPE2, NO_SESSION,
5636 			 0));
5637 
5638 	status = sme_acquire_global_lock(&mac->sme);
5639 	if (QDF_IS_STATUS_SUCCESS(status)) {
5640 		/* serialize the req through MC thread */
5641 		qdf_mem_copy(MsgPtr, wlanAppType2Params, sizeof(*MsgPtr));
5642 		message.bodyptr = MsgPtr;
5643 		message.type = WMA_WLAN_SET_APP_TYPE2_PARAMS;
5644 		qdf_status = scheduler_post_message(QDF_MODULE_ID_SME,
5645 						    QDF_MODULE_ID_WMA,
5646 						    QDF_MODULE_ID_WMA,
5647 						    &message);
5648 		if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
5649 			qdf_mem_free(MsgPtr);
5650 			status = QDF_STATUS_E_FAILURE;
5651 		}
5652 		sme_release_global_lock(&mac->sme);
5653 	} else {
5654 		qdf_mem_free(MsgPtr);
5655 	}
5656 
5657 	return status;
5658 }
5659 #endif
5660 
sme_get_beaconing_concurrent_operation_channel(mac_handle_t mac_handle,uint8_t vdev_id_to_skip)5661 uint32_t sme_get_beaconing_concurrent_operation_channel(mac_handle_t mac_handle,
5662 							uint8_t vdev_id_to_skip)
5663 {
5664 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
5665 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
5666 	uint32_t chan_freq = 0;
5667 
5668 	status = sme_acquire_global_lock(&mac->sme);
5669 	if (QDF_IS_STATUS_SUCCESS(status)) {
5670 
5671 		chan_freq = csr_get_beaconing_concurrent_channel(mac,
5672 							       vdev_id_to_skip);
5673 		sme_debug("Other Concurrent Chan_freq: %d skipped vdev_id %d",
5674 			  chan_freq, vdev_id_to_skip);
5675 		sme_release_global_lock(&mac->sme);
5676 	}
5677 
5678 	return chan_freq;
5679 }
5680 
5681 #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
sme_check_concurrent_channel_overlap(mac_handle_t mac_handle,uint16_t sap_ch_freq,eCsrPhyMode sapPhyMode,uint8_t cc_switch_mode,uint8_t vdev_id)5682 uint16_t sme_check_concurrent_channel_overlap(mac_handle_t mac_handle,
5683 					      uint16_t sap_ch_freq,
5684 					      eCsrPhyMode sapPhyMode,
5685 					      uint8_t cc_switch_mode,
5686 					      uint8_t vdev_id)
5687 {
5688 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
5689 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
5690 	uint16_t intf_ch_freq = 0;
5691 
5692 	status = sme_acquire_global_lock(&mac->sme);
5693 	if (QDF_IS_STATUS_SUCCESS(status)) {
5694 		intf_ch_freq = csr_check_concurrent_channel_overlap(
5695 			mac, sap_ch_freq, sapPhyMode, cc_switch_mode, vdev_id);
5696 		sme_release_global_lock(&mac->sme);
5697 	}
5698 
5699 	return intf_ch_freq;
5700 }
5701 #endif
5702 
5703 /**
5704  * sme_set_tsfcb() - Set callback for TSF capture
5705  * @mac_handle: Handler return by mac_open
5706  * @cb_fn: Callback function pointer
5707  * @db_ctx: Callback data
5708  *
5709  * Return: QDF_STATUS
5710  */
sme_set_tsfcb(mac_handle_t mac_handle,int (* cb_fn)(void * cb_ctx,struct stsf * ptsf),void * cb_ctx)5711 QDF_STATUS sme_set_tsfcb(mac_handle_t mac_handle,
5712 	int (*cb_fn)(void *cb_ctx, struct stsf *ptsf), void *cb_ctx)
5713 {
5714 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
5715 	QDF_STATUS status;
5716 
5717 	status = sme_acquire_global_lock(&mac->sme);
5718 	if (QDF_IS_STATUS_SUCCESS(status)) {
5719 		mac->sme.get_tsf_cb = cb_fn;
5720 		mac->sme.get_tsf_cxt = cb_ctx;
5721 		sme_release_global_lock(&mac->sme);
5722 	}
5723 	return status;
5724 }
5725 
5726 /**
5727  * sme_reset_tsfcb() - Reset callback for TSF capture
5728  * @mac_handle: Handler return by mac_open
5729  *
5730  * This function reset the tsf capture callback to SME
5731  *
5732  * Return: QDF_STATUS
5733  */
sme_reset_tsfcb(mac_handle_t mac_handle)5734 QDF_STATUS sme_reset_tsfcb(mac_handle_t mac_handle)
5735 {
5736 	struct mac_context *mac;
5737 	QDF_STATUS status;
5738 
5739 	if (!mac_handle) {
5740 		sme_err("mac_handle is not valid");
5741 		return QDF_STATUS_E_INVAL;
5742 	}
5743 	mac = MAC_CONTEXT(mac_handle);
5744 
5745 	status = sme_acquire_global_lock(&mac->sme);
5746 	if (QDF_IS_STATUS_SUCCESS(status)) {
5747 		mac->sme.get_tsf_cb = NULL;
5748 		mac->sme.get_tsf_cxt = NULL;
5749 		sme_release_global_lock(&mac->sme);
5750 	}
5751 	return status;
5752 }
5753 
5754 #if defined(WLAN_FEATURE_TSF) && !defined(WLAN_FEATURE_TSF_PLUS_NOIRQ)
5755 /*
5756  * sme_set_tsf_gpio() - set gpio pin that be toggled when capture tsf
5757  * @mac_handle: Handler return by mac_open
5758  * @pinvalue: gpio pin id
5759  *
5760  * Return: QDF_STATUS
5761  */
sme_set_tsf_gpio(mac_handle_t mac_handle,uint32_t pinvalue)5762 QDF_STATUS sme_set_tsf_gpio(mac_handle_t mac_handle, uint32_t pinvalue)
5763 {
5764 	QDF_STATUS status;
5765 	struct scheduler_msg tsf_msg = {0};
5766 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
5767 
5768 	status = sme_acquire_global_lock(&mac->sme);
5769 	if (QDF_IS_STATUS_SUCCESS(status)) {
5770 		tsf_msg.type = WMA_TSF_GPIO_PIN;
5771 		tsf_msg.reserved = 0;
5772 		tsf_msg.bodyval = pinvalue;
5773 
5774 		status = scheduler_post_message(QDF_MODULE_ID_SME,
5775 						QDF_MODULE_ID_WMA,
5776 						QDF_MODULE_ID_WMA, &tsf_msg);
5777 		if (!QDF_IS_STATUS_SUCCESS(status)) {
5778 			sme_err("Unable to post WMA_TSF_GPIO_PIN");
5779 			status = QDF_STATUS_E_FAILURE;
5780 		}
5781 		sme_release_global_lock(&mac->sme);
5782 	}
5783 	return status;
5784 }
5785 #endif
5786 
sme_get_cfg_valid_channels(uint32_t * valid_ch_freq,uint32_t * len)5787 QDF_STATUS sme_get_cfg_valid_channels(uint32_t *valid_ch_freq, uint32_t *len)
5788 {
5789 	QDF_STATUS status;
5790 	struct mac_context *mac_ctx = sme_get_mac_context();
5791 	uint32_t *valid_ch_freq_list;
5792 	uint32_t i;
5793 
5794 	if (!mac_ctx) {
5795 		sme_err("Invalid MAC context");
5796 		return QDF_STATUS_E_FAILURE;
5797 	}
5798 
5799 	valid_ch_freq_list = qdf_mem_malloc(CFG_VALID_CHANNEL_LIST_LEN *
5800 					    sizeof(uint32_t));
5801 	if (!valid_ch_freq_list)
5802 		return QDF_STATUS_E_NOMEM;
5803 
5804 	status = csr_get_cfg_valid_channels(mac_ctx, valid_ch_freq_list, len);
5805 
5806 	for (i = 0; i < *len; i++)
5807 		valid_ch_freq[i] = valid_ch_freq_list[i];
5808 
5809 	qdf_mem_free(valid_ch_freq_list);
5810 
5811 	return status;
5812 }
5813 
5814 /**
5815  * sme_handle_generic_change_country_code() - handles country ch req
5816  * @mac_ctx:    mac global context
5817  * @msg:        request msg packet
5818  *
5819  * If Supplicant country code is priority than 11d is disabled.
5820  * If 11D is enabled, we update the country code after every scan.
5821  * Hence when Supplicant country code is priority, we don't need 11D info.
5822  * Country code from Supplicant is set as current country code.
5823  *
5824  * Return: status of operation
5825  */
5826 static QDF_STATUS
sme_handle_generic_change_country_code(struct mac_context * mac_ctx,void * msg_buf)5827 sme_handle_generic_change_country_code(struct mac_context *mac_ctx,
5828 				       void *msg_buf)
5829 {
5830 	QDF_STATUS status = QDF_STATUS_SUCCESS;
5831 
5832 	/* get the channels based on new cc */
5833 	status = csr_get_channel_and_power_list(mac_ctx);
5834 
5835 	if (status != QDF_STATUS_SUCCESS) {
5836 		sme_err("fail to get Channels");
5837 		return status;
5838 	}
5839 
5840 	/* reset info based on new cc, and we are done */
5841 	csr_apply_channel_power_info_wrapper(mac_ctx);
5842 	csr_update_beacon(mac_ctx);
5843 
5844 	csr_scan_filter_results(mac_ctx);
5845 
5846 	return QDF_STATUS_SUCCESS;
5847 }
5848 
sme_update_channel_list(mac_handle_t mac_handle)5849 QDF_STATUS sme_update_channel_list(mac_handle_t mac_handle)
5850 {
5851 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
5852 	QDF_STATUS status;
5853 
5854 	status = sme_acquire_global_lock(&mac_ctx->sme);
5855 	if (QDF_IS_STATUS_SUCCESS(status)) {
5856 		/* Update umac channel (enable/disable) from cds channels */
5857 		status = csr_get_channel_and_power_list(mac_ctx);
5858 		if (status != QDF_STATUS_SUCCESS) {
5859 			sme_err("fail to get Channels");
5860 			sme_release_global_lock(&mac_ctx->sme);
5861 			return status;
5862 		}
5863 
5864 		csr_apply_channel_power_info_wrapper(mac_ctx);
5865 		csr_scan_filter_results(mac_ctx);
5866 		sme_release_global_lock(&mac_ctx->sme);
5867 		/* release the sme lock before we call cm disconnect */
5868 		sme_disconnect_connected_sessions(mac_ctx,
5869 					REASON_OPER_CHANNEL_USER_DISABLED);
5870 	}
5871 
5872 	return status;
5873 }
5874 
5875 /**
5876  * sme_search_in_base_ch_freq_lst() - is given ch_freq in base ch freq
5877  * @mac_ctx: mac global context
5878  * @chan_freq: current channel freq
5879  *
5880  * Return: true if given ch_freq is in base ch freq
5881  */
sme_search_in_base_ch_freq_lst(struct mac_context * mac_ctx,uint32_t chan_freq)5882 static bool sme_search_in_base_ch_freq_lst(
5883 	struct mac_context *mac_ctx, uint32_t chan_freq)
5884 {
5885 	uint8_t i;
5886 	struct csr_channel *ch_lst_info;
5887 
5888 	ch_lst_info = &mac_ctx->scan.base_channels;
5889 	for (i = 0; i < ch_lst_info->numChannels; i++) {
5890 		if (ch_lst_info->channel_freq_list[i] == chan_freq)
5891 			return true;
5892 	}
5893 
5894 	return false;
5895 }
5896 
5897 /**
5898  * sme_disconnect_connected_sessions() - Disconnect STA and P2P client session
5899  * if channel is not supported
5900  * @mac_ctx: mac global context
5901  * @reason: Mac Disconnect reason code as per @enum wlan_reason_code
5902  *
5903  * If new country code does not support the channel on which STA/P2P client
5904  * is connected, it sends the disconnect to the AP/P2P GO
5905  *
5906  * Return: void
5907  */
sme_disconnect_connected_sessions(struct mac_context * mac_ctx,enum wlan_reason_code reason)5908 static void sme_disconnect_connected_sessions(struct mac_context *mac_ctx,
5909 					      enum wlan_reason_code reason)
5910 {
5911 	uint8_t vdev_id, found = false;
5912 	qdf_freq_t chan_freq;
5913 	enum QDF_OPMODE op_mode;
5914 	struct wlan_objmgr_vdev *vdev;
5915 
5916 	for (vdev_id = 0; vdev_id < WLAN_MAX_VDEVS; vdev_id++) {
5917 		op_mode = wlan_get_opmode_from_vdev_id(mac_ctx->pdev, vdev_id);
5918 		/* check only for STA and CLI */
5919 		if (op_mode != QDF_STA_MODE && op_mode != QDF_P2P_CLIENT_MODE)
5920 			continue;
5921 
5922 		chan_freq =
5923 			wlan_get_operation_chan_freq_vdev_id(mac_ctx->pdev,
5924 							     vdev_id);
5925 		if (!chan_freq)
5926 			continue;
5927 		found = false;
5928 		sme_debug("Current Operating channel : %d, vdev_id :%d",
5929 			  chan_freq, vdev_id);
5930 		found = sme_search_in_base_ch_freq_lst(mac_ctx, chan_freq);
5931 		if (!found) {
5932 			sme_debug("Disconnect Session: %d", vdev_id);
5933 			/* do not call cm disconnect while holding Sme lock */
5934 			vdev = wlan_objmgr_get_vdev_by_id_from_psoc(
5935 							mac_ctx->psoc,
5936 							vdev_id,
5937 							WLAN_LEGACY_SME_ID);
5938 			if (!vdev) {
5939 				sme_err("vdev object is NULL for vdev_id %d",
5940 					vdev_id);
5941 				return;
5942 			}
5943 			mlo_disconnect(vdev, CM_MLME_DISCONNECT, reason, NULL);
5944 			wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID);
5945 		}
5946 	}
5947 }
5948 
5949 #ifdef WLAN_FEATURE_PACKET_FILTERING
sme_8023_multicast_list(mac_handle_t mac_handle,uint8_t sessionId,tpSirRcvFltMcAddrList pMulticastAddrs)5950 QDF_STATUS sme_8023_multicast_list(mac_handle_t mac_handle, uint8_t sessionId,
5951 				   tpSirRcvFltMcAddrList pMulticastAddrs)
5952 {
5953 	tpSirRcvFltMcAddrList request_buf;
5954 	struct scheduler_msg msg = {0};
5955 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
5956 	struct csr_roam_session *pSession = NULL;
5957 
5958 	sme_debug("ulMulticastAddrCnt: %d, multicastAddr[0]: %pK",
5959 		  pMulticastAddrs->ulMulticastAddrCnt,
5960 		  pMulticastAddrs->multicastAddr[0].bytes);
5961 
5962 	/* Find the connected Infra / P2P_client connected session */
5963 	pSession = CSR_GET_SESSION(mac, sessionId);
5964 	if (!CSR_IS_SESSION_VALID(mac, sessionId) ||
5965 	    (!cm_is_vdevid_connected(mac->pdev, sessionId) &&
5966 	     !csr_is_ndi_started(mac, sessionId))) {
5967 		sme_err("Unable to find the vdev %d", sessionId);
5968 		return QDF_STATUS_E_FAILURE;
5969 	}
5970 
5971 	request_buf = qdf_mem_malloc(sizeof(tSirRcvFltMcAddrList));
5972 	if (!request_buf)
5973 		return QDF_STATUS_E_NOMEM;
5974 
5975 	if (!cm_is_vdevid_connected(mac->pdev, sessionId) &&
5976 	    !csr_is_ndi_started(mac, sessionId)) {
5977 		sme_err("Request ignored, session %d is not connected or started",
5978 			sessionId);
5979 		qdf_mem_free(request_buf);
5980 		return QDF_STATUS_E_FAILURE;
5981 	}
5982 
5983 	qdf_mem_copy(request_buf, pMulticastAddrs,
5984 		     sizeof(tSirRcvFltMcAddrList));
5985 
5986 	wlan_mlme_get_mac_vdev_id(mac->pdev, sessionId,
5987 				  &request_buf->self_macaddr);
5988 	wlan_mlme_get_bssid_vdev_id(mac->pdev, sessionId, &request_buf->bssid);
5989 
5990 	msg.type = WMA_8023_MULTICAST_LIST_REQ;
5991 	msg.reserved = 0;
5992 	msg.bodyptr = request_buf;
5993 	MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG,
5994 			 sessionId, msg.type));
5995 	if (QDF_STATUS_SUCCESS != scheduler_post_message(QDF_MODULE_ID_SME,
5996 							 QDF_MODULE_ID_WMA,
5997 							 QDF_MODULE_ID_WMA,
5998 							 &msg)) {
5999 		sme_err("Not able to post WMA_8023_MULTICAST_LIST message to WMA");
6000 		qdf_mem_free(request_buf);
6001 		return QDF_STATUS_E_FAILURE;
6002 	}
6003 
6004 	return QDF_STATUS_SUCCESS;
6005 }
6006 #endif /* WLAN_FEATURE_PACKET_FILTERING */
6007 
sme_is_channel_valid(mac_handle_t mac_handle,uint32_t chan_freq)6008 bool sme_is_channel_valid(mac_handle_t mac_handle, uint32_t chan_freq)
6009 {
6010 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
6011 	bool valid = false;
6012 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
6013 
6014 	status = sme_acquire_global_lock(&mac->sme);
6015 	if (QDF_IS_STATUS_SUCCESS(status)) {
6016 
6017 		valid = wlan_roam_is_channel_valid(&mac->mlme_cfg->reg,
6018 						   chan_freq);
6019 
6020 		sme_release_global_lock(&mac->sme);
6021 	}
6022 
6023 	return valid;
6024 }
6025 
6026 /*
6027  * sme_set_max_tx_power_per_band() -
6028  * Set the Maximum Transmit Power specific to band dynamically.
6029  *   Note: this setting will not persist over reboots.
6030  *
6031  * band
6032  * power to set in dB
6033  * Return QDF_STATUS
6034  */
sme_set_max_tx_power_per_band(enum band_info band,int8_t dB)6035 QDF_STATUS sme_set_max_tx_power_per_band(enum band_info band, int8_t dB)
6036 {
6037 	struct scheduler_msg msg = {0};
6038 	tpMaxTxPowerPerBandParams pMaxTxPowerPerBandParams = NULL;
6039 
6040 	pMaxTxPowerPerBandParams =
6041 		qdf_mem_malloc(sizeof(tMaxTxPowerPerBandParams));
6042 	if (!pMaxTxPowerPerBandParams)
6043 		return QDF_STATUS_E_NOMEM;
6044 
6045 	pMaxTxPowerPerBandParams->power = dB;
6046 	pMaxTxPowerPerBandParams->bandInfo = band;
6047 
6048 	msg.type = WMA_SET_MAX_TX_POWER_PER_BAND_REQ;
6049 	msg.reserved = 0;
6050 	msg.bodyptr = pMaxTxPowerPerBandParams;
6051 	MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG,
6052 			 NO_SESSION, msg.type));
6053 	if (QDF_STATUS_SUCCESS != scheduler_post_message(QDF_MODULE_ID_SME,
6054 							 QDF_MODULE_ID_WMA,
6055 							 QDF_MODULE_ID_WMA,
6056 							 &msg)) {
6057 		sme_err("Not able to post WMA_SET_MAX_TX_POWER_PER_BAND_REQ");
6058 		qdf_mem_free(pMaxTxPowerPerBandParams);
6059 		return QDF_STATUS_E_FAILURE;
6060 	}
6061 
6062 	return QDF_STATUS_SUCCESS;
6063 }
6064 
6065 /*
6066  * sme_set_max_tx_power() -
6067  * Set the Maximum Transmit Power dynamically. Note: this setting will
6068  *   not persist over reboots.
6069  *
6070  * mac_handle
6071  * pBssid  BSSID to set the power cap for
6072  * pBssid  pSelfMacAddress self MAC Address
6073  * pBssid  power to set in dB
6074  * Return QDF_STATUS
6075  */
sme_set_max_tx_power(mac_handle_t mac_handle,struct qdf_mac_addr pBssid,struct qdf_mac_addr pSelfMacAddress,int8_t dB)6076 QDF_STATUS sme_set_max_tx_power(mac_handle_t mac_handle,
6077 				struct qdf_mac_addr pBssid,
6078 				struct qdf_mac_addr pSelfMacAddress, int8_t dB)
6079 {
6080 	struct scheduler_msg msg = {0};
6081 	tpMaxTxPowerParams pMaxTxParams = NULL;
6082 
6083 	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
6084 			 TRACE_CODE_SME_RX_HDD_SET_MAXTXPOW, NO_SESSION, 0));
6085 	pMaxTxParams = qdf_mem_malloc(sizeof(tMaxTxPowerParams));
6086 	if (!pMaxTxParams)
6087 		return QDF_STATUS_E_NOMEM;
6088 
6089 	qdf_copy_macaddr(&pMaxTxParams->bssId, &pBssid);
6090 	qdf_copy_macaddr(&pMaxTxParams->selfStaMacAddr, &pSelfMacAddress);
6091 	pMaxTxParams->power = dB;
6092 
6093 	msg.type = WMA_SET_MAX_TX_POWER_REQ;
6094 	msg.reserved = 0;
6095 	msg.bodyptr = pMaxTxParams;
6096 
6097 	if (QDF_STATUS_SUCCESS != scheduler_post_message(QDF_MODULE_ID_SME,
6098 							 QDF_MODULE_ID_WMA,
6099 							 QDF_MODULE_ID_WMA,
6100 							 &msg)) {
6101 		sme_err("Not able to post WMA_SET_MAX_TX_POWER_REQ message to WMA");
6102 		qdf_mem_free(pMaxTxParams);
6103 		return QDF_STATUS_E_FAILURE;
6104 	}
6105 
6106 	return QDF_STATUS_SUCCESS;
6107 }
6108 
sme_set_listen_interval(mac_handle_t mac_handle,uint8_t vdev_id)6109 void sme_set_listen_interval(mac_handle_t mac_handle, uint8_t vdev_id)
6110 {
6111 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
6112 	struct pe_session *session = NULL;
6113 	uint8_t val = 0;
6114 
6115 	session = pe_find_session_by_vdev_id(mac, vdev_id);
6116 	if (!session) {
6117 		sme_err("Session lookup fails for vdev %d", vdev_id);
6118 		return;
6119 	}
6120 
6121 	val = session->dtimPeriod;
6122 	pe_debug("Listen interval: %d vdev id: %d", val, vdev_id);
6123 	wma_vdev_set_listen_interval(vdev_id, val);
6124 }
6125 
6126 /*
6127  * sme_set_custom_mac_addr() -
6128  * Set the customer Mac Address.
6129  *
6130  * customMacAddr  customer MAC Address
6131  * Return QDF_STATUS
6132  */
sme_set_custom_mac_addr(tSirMacAddr customMacAddr)6133 QDF_STATUS sme_set_custom_mac_addr(tSirMacAddr customMacAddr)
6134 {
6135 	struct scheduler_msg msg = {0};
6136 	tSirMacAddr *pBaseMacAddr;
6137 
6138 	pBaseMacAddr = qdf_mem_malloc(sizeof(tSirMacAddr));
6139 	if (!pBaseMacAddr)
6140 		return QDF_STATUS_E_NOMEM;
6141 
6142 	qdf_mem_copy(*pBaseMacAddr, customMacAddr, sizeof(tSirMacAddr));
6143 
6144 	msg.type = SIR_HAL_SET_BASE_MACADDR_IND;
6145 	msg.reserved = 0;
6146 	msg.bodyptr = pBaseMacAddr;
6147 
6148 	if (QDF_STATUS_SUCCESS != scheduler_post_message(QDF_MODULE_ID_SME,
6149 							 QDF_MODULE_ID_WMA,
6150 							 QDF_MODULE_ID_WMA,
6151 							 &msg)) {
6152 		sme_err("Not able to post SIR_HAL_SET_BASE_MACADDR_IND message to WMA");
6153 		qdf_mem_free(pBaseMacAddr);
6154 		return QDF_STATUS_E_FAILURE;
6155 	}
6156 
6157 	return QDF_STATUS_SUCCESS;
6158 }
6159 
6160 /*
6161  * sme_set_tx_power() -
6162  * Set Transmit Power dynamically.
6163  *
6164  * mac_handle
6165  * sessionId  Target Session ID
6166  * BSSID
6167  * dev_mode dev_mode such as station, P2PGO, SAP
6168  * dBm  power to set
6169  * Return QDF_STATUS
6170  */
sme_set_tx_power(mac_handle_t mac_handle,uint8_t sessionId,struct qdf_mac_addr pBSSId,enum QDF_OPMODE dev_mode,int dBm)6171 QDF_STATUS sme_set_tx_power(mac_handle_t mac_handle, uint8_t sessionId,
6172 			   struct qdf_mac_addr pBSSId,
6173 			   enum QDF_OPMODE dev_mode, int dBm)
6174 {
6175 	struct scheduler_msg msg = {0};
6176 	tpMaxTxPowerParams pTxParams = NULL;
6177 	int8_t power = (int8_t) dBm;
6178 
6179 	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
6180 			 TRACE_CODE_SME_RX_HDD_SET_TXPOW, sessionId, 0));
6181 
6182 	/* make sure there is no overflow */
6183 	if ((int)power != dBm) {
6184 		sme_err("error, invalid power = %d", dBm);
6185 		return QDF_STATUS_E_FAILURE;
6186 	}
6187 
6188 	pTxParams = qdf_mem_malloc(sizeof(tMaxTxPowerParams));
6189 	if (!pTxParams)
6190 		return QDF_STATUS_E_NOMEM;
6191 
6192 	qdf_copy_macaddr(&pTxParams->bssId, &pBSSId);
6193 	pTxParams->power = power;       /* unit is dBm */
6194 	pTxParams->dev_mode = dev_mode;
6195 	msg.type = WMA_SET_TX_POWER_REQ;
6196 	msg.reserved = 0;
6197 	msg.bodyptr = pTxParams;
6198 
6199 	if (QDF_STATUS_SUCCESS != scheduler_post_message(QDF_MODULE_ID_SME,
6200 							 QDF_MODULE_ID_WMA,
6201 							 QDF_MODULE_ID_WMA,
6202 							 &msg)) {
6203 		qdf_mem_free(pTxParams);
6204 		return QDF_STATUS_E_FAILURE;
6205 	}
6206 
6207 	return QDF_STATUS_SUCCESS;
6208 }
6209 
sme_set_check_assoc_disallowed(mac_handle_t mac_handle,bool check_assoc_disallowed)6210 QDF_STATUS sme_set_check_assoc_disallowed(mac_handle_t mac_handle,
6211 					  bool check_assoc_disallowed)
6212 {
6213 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
6214 	QDF_STATUS status;
6215 
6216 	status = sme_acquire_global_lock(&mac->sme);
6217 	if (QDF_IS_STATUS_ERROR(status)) {
6218 		sme_err("Failed to acquire sme lock; status: %d", status);
6219 		return status;
6220 	}
6221 	wlan_cm_set_check_assoc_disallowed(mac->psoc, check_assoc_disallowed);
6222 	sme_release_global_lock(&mac->sme);
6223 
6224 	return QDF_STATUS_SUCCESS;
6225 }
6226 
sme_update_session_param(mac_handle_t mac_handle,uint8_t session_id,uint32_t param_type,uint32_t param_val)6227 QDF_STATUS sme_update_session_param(mac_handle_t mac_handle, uint8_t session_id,
6228 				    uint32_t param_type, uint32_t param_val)
6229 {
6230 	QDF_STATUS status = QDF_STATUS_SUCCESS;
6231 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
6232 	uint16_t len;
6233 
6234 	status = sme_acquire_global_lock(&mac_ctx->sme);
6235 	if (QDF_IS_STATUS_SUCCESS(status)) {
6236 		struct sir_update_session_param *msg;
6237 		struct csr_roam_session *session = CSR_GET_SESSION(mac_ctx,
6238 							session_id);
6239 
6240 		if (!session) {
6241 			sme_err("Session: %d not found", session_id);
6242 			sme_release_global_lock(&mac_ctx->sme);
6243 			return status;
6244 		}
6245 
6246 		if (!session->sessionActive)
6247 			QDF_ASSERT(0);
6248 
6249 		len = sizeof(*msg);
6250 		msg = qdf_mem_malloc(len);
6251 		if (!msg)
6252 			status = QDF_STATUS_E_NOMEM;
6253 		else {
6254 			msg->message_type = eWNI_SME_SESSION_UPDATE_PARAM;
6255 			msg->length = len;
6256 			msg->vdev_id = session_id;
6257 			msg->param_type = param_type;
6258 			msg->param_val = param_val;
6259 			status = umac_send_mb_message_to_mac(msg);
6260 		}
6261 		sme_release_global_lock(&mac_ctx->sme);
6262 	}
6263 	return status;
6264 }
6265 
sme_update_roam_scan_n_probes(mac_handle_t mac_handle,uint8_t vdev_id,const uint8_t probes)6266 QDF_STATUS sme_update_roam_scan_n_probes(mac_handle_t mac_handle,
6267 					 uint8_t vdev_id,
6268 					 const uint8_t probes)
6269 {
6270 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
6271 	struct cm_roam_values_copy src_config = {};
6272 
6273 	src_config.uint_value = probes;
6274 	return wlan_cm_roam_cfg_set_value(mac->psoc, vdev_id,
6275 					  SCAN_N_PROBE,
6276 					  &src_config);
6277 }
6278 
6279 QDF_STATUS
sme_update_roam_scan_home_away_time(mac_handle_t mac_handle,uint8_t vdev_id,const uint16_t roam_scan_home_away_time,const bool send_offload_cmd)6280 sme_update_roam_scan_home_away_time(mac_handle_t mac_handle, uint8_t vdev_id,
6281 				    const uint16_t roam_scan_home_away_time,
6282 				    const bool send_offload_cmd)
6283 {
6284 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
6285 	struct cm_roam_values_copy src_config = {};
6286 
6287 	src_config.bool_value = send_offload_cmd;
6288 	src_config.uint_value = roam_scan_home_away_time;
6289 	return wlan_cm_roam_cfg_set_value(mac->psoc, vdev_id,
6290 					  SCAN_HOME_AWAY, &src_config);
6291 }
6292 
6293 /**
6294  * sme_ext_change_freq()- function to post send ECSA
6295  * action frame to csr.
6296  * @mac_handle: Opaque handle to the global MAC context
6297  * @channel freq: new channel freq to switch
6298  * @session_id: senssion it should be sent on.
6299  *
6300  * This function is called to post ECSA frame to csr.
6301  *
6302  * Return: success if msg is sent else return failure
6303  */
sme_ext_change_freq(mac_handle_t mac_handle,qdf_freq_t ch_freq,uint8_t session_id)6304 QDF_STATUS sme_ext_change_freq(mac_handle_t mac_handle, qdf_freq_t ch_freq,
6305 			       uint8_t session_id)
6306 {
6307 	QDF_STATUS status = QDF_STATUS_SUCCESS;
6308 	struct mac_context *mac_ctx  = MAC_CONTEXT(mac_handle);
6309 	uint8_t channel_state;
6310 
6311 	sme_err("Set Channel freq: %d", ch_freq);
6312 
6313 	channel_state = wlan_reg_get_channel_state_for_pwrmode(
6314 							mac_ctx->pdev,
6315 							ch_freq,
6316 							REG_CURRENT_PWR_MODE);
6317 
6318 	if (CHANNEL_STATE_DISABLE == channel_state) {
6319 		sme_err("Invalid channel freq: %d", ch_freq);
6320 		return QDF_STATUS_E_INVAL;
6321 	}
6322 
6323 	status = sme_acquire_global_lock(&mac_ctx->sme);
6324 
6325 	if (QDF_STATUS_SUCCESS == status) {
6326 		/* update the channel list to the firmware */
6327 		status = csr_send_ext_change_freq(mac_ctx,
6328 						  ch_freq, session_id);
6329 		sme_release_global_lock(&mac_ctx->sme);
6330 	}
6331 
6332 	return status;
6333 }
6334 
sme_get_roam_scan_n_probes(mac_handle_t mac_handle,uint8_t vdev_id,uint8_t * roam_scan_n_probes)6335 QDF_STATUS sme_get_roam_scan_n_probes(mac_handle_t mac_handle, uint8_t vdev_id,
6336 				      uint8_t *roam_scan_n_probes)
6337 {
6338 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
6339 	struct cm_roam_values_copy temp;
6340 
6341 	wlan_cm_roam_cfg_get_value(mac->psoc, vdev_id, SCAN_N_PROBE, &temp);
6342 	*roam_scan_n_probes = temp.uint_value;
6343 
6344 	return QDF_STATUS_SUCCESS;
6345 }
6346 
sme_update_roam_rssi_diff(mac_handle_t mac_handle,uint8_t vdev_id,uint8_t roam_rssi_diff)6347 QDF_STATUS sme_update_roam_rssi_diff(mac_handle_t mac_handle, uint8_t vdev_id,
6348 				     uint8_t roam_rssi_diff)
6349 {
6350 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
6351 	struct cm_roam_values_copy src_config = {};
6352 
6353 	src_config.uint_value = roam_rssi_diff;
6354 	return wlan_cm_roam_cfg_set_value(mac->psoc, vdev_id,
6355 					  ROAM_RSSI_DIFF, &src_config);
6356 }
6357 
sme_send_rso_connect_params(mac_handle_t mac_handle,uint8_t vdev_id)6358 QDF_STATUS sme_send_rso_connect_params(mac_handle_t mac_handle,
6359 				       uint8_t vdev_id)
6360 {
6361 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
6362 	QDF_STATUS status = QDF_STATUS_SUCCESS;
6363 
6364 	if (vdev_id >= WLAN_MAX_VDEVS) {
6365 		sme_err("Invalid sme vdev id: %d", vdev_id);
6366 		return QDF_STATUS_E_INVAL;
6367 	}
6368 
6369 	if (!mac->mlme_cfg->lfr.lfr_enabled) {
6370 		sme_debug("lfr enabled %d", mac->mlme_cfg->lfr.lfr_enabled);
6371 		return QDF_STATUS_E_PERM;
6372 	}
6373 
6374 	if (wlan_is_roam_offload_enabled(mac->mlme_cfg->lfr)) {
6375 		status = sme_acquire_global_lock(&mac->sme);
6376 		if (QDF_IS_STATUS_SUCCESS(status)) {
6377 			sme_debug("Updating fils config to fw");
6378 			wlan_roam_update_cfg(mac->psoc, vdev_id,
6379 					    REASON_FILS_PARAMS_CHANGED);
6380 			sme_release_global_lock(&mac->sme);
6381 		} else {
6382 			sme_err("Failed to acquire SME lock");
6383 		}
6384 	} else {
6385 		sme_debug("LFR3 not enabled");
6386 		return QDF_STATUS_E_INVAL;
6387 	}
6388 
6389 	return status;
6390 }
6391 
6392 #ifdef WLAN_FEATURE_FILS_SK
sme_send_hlp_ie_info(mac_handle_t mac_handle,uint8_t vdev_id,uint32_t if_addr)6393 void sme_send_hlp_ie_info(mac_handle_t mac_handle, uint8_t vdev_id,
6394 			  uint32_t if_addr)
6395 {
6396 	int i;
6397 	struct scheduler_msg msg;
6398 	QDF_STATUS status;
6399 	struct hlp_params *params;
6400 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
6401 	struct csr_roam_session *session = CSR_GET_SESSION(mac, vdev_id);
6402 	struct mlme_legacy_priv *mlme_priv;
6403 	struct wlan_objmgr_vdev *vdev;
6404 
6405 	if (!session) {
6406 		sme_err("session NULL");
6407 		return;
6408 	}
6409 
6410 	if (!mac->mlme_cfg->lfr.lfr_enabled) {
6411 		sme_debug("Fast roam is disabled");
6412 		return;
6413 	}
6414 	if (!csr_is_conn_state_connected(mac, vdev_id)) {
6415 		sme_debug("vdev not connected");
6416 		return;
6417 	}
6418 
6419 	params = qdf_mem_malloc(sizeof(*params));
6420 	if (!params)
6421 		return;
6422 
6423 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac->psoc, vdev_id,
6424 						    WLAN_MLME_NB_ID);
6425 	if (!vdev) {
6426 		mlme_err("vdev object is NULL for vdev_id %d", vdev_id);
6427 		qdf_mem_free(params);
6428 		return;
6429 	}
6430 	mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev);
6431 	if (!mlme_priv) {
6432 		wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_NB_ID);
6433 		qdf_mem_free(params);
6434 		return;
6435 	}
6436 	if ((mlme_priv->connect_info.hlp_ie_len +
6437 	     QDF_IPV4_ADDR_SIZE) > FILS_MAX_HLP_DATA_LEN) {
6438 		sme_err("HLP IE len exceeds %d",
6439 			mlme_priv->connect_info.hlp_ie_len);
6440 		wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_NB_ID);
6441 		qdf_mem_free(params);
6442 		return;
6443 	}
6444 
6445 	params->vdev_id = vdev_id;
6446 	params->hlp_ie_len =
6447 		mlme_priv->connect_info.hlp_ie_len + QDF_IPV4_ADDR_SIZE;
6448 
6449 	for (i = 0; i < QDF_IPV4_ADDR_SIZE; i++)
6450 		params->hlp_ie[i] = (if_addr >> (i * 8)) & 0xFF;
6451 
6452 	qdf_mem_copy(params->hlp_ie + QDF_IPV4_ADDR_SIZE,
6453 		     mlme_priv->connect_info.hlp_ie,
6454 		     mlme_priv->connect_info.hlp_ie_len);
6455 	wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_NB_ID);
6456 
6457 	msg.type = SIR_HAL_HLP_IE_INFO;
6458 	msg.reserved = 0;
6459 	msg.bodyptr = params;
6460 	status = sme_acquire_global_lock(&mac->sme);
6461 	if (status != QDF_STATUS_SUCCESS) {
6462 		sme_err("sme lock acquire fails");
6463 		qdf_mem_free(params);
6464 		return;
6465 	}
6466 
6467 	if (!QDF_IS_STATUS_SUCCESS
6468 			(scheduler_post_message(QDF_MODULE_ID_SME,
6469 						QDF_MODULE_ID_WMA,
6470 						QDF_MODULE_ID_WMA, &msg))) {
6471 		sme_err("Not able to post WMA_HLP_IE_INFO message to HAL");
6472 		sme_release_global_lock(&mac->sme);
6473 		qdf_mem_free(params);
6474 		return;
6475 	}
6476 
6477 	sme_release_global_lock(&mac->sme);
6478 }
6479 
6480 #else
sme_send_hlp_ie_info(mac_handle_t mac_handle,uint8_t vdev_id,struct csr_roam_profile * profile,uint32_t if_addr)6481 inline void sme_send_hlp_ie_info(mac_handle_t mac_handle, uint8_t vdev_id,
6482 			  struct csr_roam_profile *profile, uint32_t if_addr)
6483 {}
6484 #endif
6485 
6486 /*
6487  * sme_update_wes_mode() -
6488  * Update WES Mode
6489  *	    This function is called through dynamic setConfig callback function
6490  *	    to configure isWESModeEnabled
6491  *
6492  * mac_handle: Opaque handle to the global MAC context
6493  * isWESModeEnabled - WES mode
6494  * sessionId - Session Identifier
6495  * Return QDF_STATUS_SUCCESS - SME update isWESModeEnabled config successfully.
6496  *	    Other status means SME is failed to update isWESModeEnabled.
6497  */
6498 
sme_update_wes_mode(mac_handle_t mac_handle,bool isWESModeEnabled,uint8_t sessionId)6499 QDF_STATUS sme_update_wes_mode(mac_handle_t mac_handle, bool isWESModeEnabled,
6500 			       uint8_t sessionId)
6501 {
6502 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
6503 	QDF_STATUS status = QDF_STATUS_SUCCESS;
6504 
6505 	if (sessionId >= WLAN_MAX_VDEVS) {
6506 		sme_err("Invalid vdev %d", sessionId);
6507 		return QDF_STATUS_E_INVAL;
6508 	}
6509 
6510 	status = sme_acquire_global_lock(&mac->sme);
6511 	if (QDF_IS_STATUS_SUCCESS(status)) {
6512 		sme_debug("LFR runtime successfully set WES Mode to %d - old value is %d",
6513 			  isWESModeEnabled,
6514 			  mac->mlme_cfg->lfr.wes_mode_enabled);
6515 		mac->mlme_cfg->lfr.wes_mode_enabled = isWESModeEnabled;
6516 		sme_release_global_lock(&mac->sme);
6517 	}
6518 
6519 	return status;
6520 }
6521 
6522 /*
6523  * sme_update_is_fast_roam_ini_feature_enabled() - enable/disable LFR
6524  *	support at runtime
6525  * It is used at in the REG_DYNAMIC_VARIABLE macro definition of
6526  * isFastRoamIniFeatureEnabled.
6527  * This is a synchronous call
6528  *
6529  * mac_handle - The handle returned by mac_open.
6530  * sessionId - Session Identifier
6531  * Return QDF_STATUS_SUCCESS - SME update isFastRoamIniFeatureEnabled config
6532  *	successfully.
6533  * Other status means SME is failed to update isFastRoamIniFeatureEnabled.
6534  */
sme_update_is_fast_roam_ini_feature_enabled(mac_handle_t mac_handle,uint8_t sessionId,const bool isFastRoamIniFeatureEnabled)6535 QDF_STATUS sme_update_is_fast_roam_ini_feature_enabled(mac_handle_t mac_handle,
6536 		uint8_t sessionId, const bool isFastRoamIniFeatureEnabled)
6537 {
6538 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
6539 
6540 	if (mac->mlme_cfg->lfr.lfr_enabled ==
6541 	    isFastRoamIniFeatureEnabled) {
6542 		sme_debug("FastRoam is already enabled or disabled, nothing to do (returning) old(%d) new(%d)",
6543 			  mac->mlme_cfg->lfr.lfr_enabled,
6544 			  isFastRoamIniFeatureEnabled);
6545 		return QDF_STATUS_SUCCESS;
6546 	}
6547 
6548 	sme_debug("FastRoamEnabled is changed from %d to %d",
6549 		  mac->mlme_cfg->lfr.lfr_enabled,
6550 		  isFastRoamIniFeatureEnabled);
6551 	mac->mlme_cfg->lfr.lfr_enabled = isFastRoamIniFeatureEnabled;
6552 	mlme_set_supplicant_disabled_roaming(mac->psoc, sessionId,
6553 					     !isFastRoamIniFeatureEnabled);
6554 	if (isFastRoamIniFeatureEnabled)
6555 		wlan_cm_roam_state_change(mac->pdev, sessionId,
6556 					  WLAN_ROAM_RSO_ENABLED,
6557 					  REASON_CONNECT);
6558 	else
6559 		wlan_cm_roam_state_change(mac->pdev, sessionId,
6560 				WLAN_ROAM_RSO_STOPPED,
6561 				REASON_SUPPLICANT_DISABLED_ROAMING);
6562 
6563 	return QDF_STATUS_SUCCESS;
6564 }
6565 
6566 #ifdef FEATURE_WLAN_ESE
sme_add_key_krk(mac_handle_t mac_handle,uint8_t session_id,const uint8_t * key,const int key_len)6567 int sme_add_key_krk(mac_handle_t mac_handle, uint8_t session_id,
6568 		    const uint8_t *key, const int key_len)
6569 {
6570 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
6571 	struct wlan_objmgr_vdev *vdev;
6572 	struct rso_config *rso_cfg;
6573 
6574 	if (key_len < WMI_KRK_KEY_LEN) {
6575 		sme_warn("Invalid KRK keylength [= %d]", key_len);
6576 		return -EINVAL;
6577 	}
6578 
6579 	if (!CSR_IS_SESSION_VALID(mac_ctx, session_id)) {
6580 		sme_err("incorrect session/vdev ID");
6581 		return -EINVAL;
6582 	}
6583 
6584 	vdev = wlan_objmgr_get_vdev_by_id_from_pdev(mac_ctx->pdev, session_id,
6585 						    WLAN_LEGACY_SME_ID);
6586 	if (!vdev) {
6587 		sme_err("vdev object is NULL for vdev %d", session_id);
6588 		return QDF_STATUS_E_INVAL;
6589 	}
6590 	rso_cfg = wlan_cm_get_rso_config(vdev);
6591 	if (!rso_cfg) {
6592 		wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID);
6593 		return QDF_STATUS_E_INVAL;
6594 	}
6595 
6596 	qdf_mem_copy(rso_cfg->krk, key, WMI_KRK_KEY_LEN);
6597 	wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID);
6598 
6599 	return 0;
6600 }
6601 #endif
6602 
6603 #if defined(FEATURE_WLAN_ESE) && defined(WLAN_FEATURE_ROAM_OFFLOAD)
sme_add_key_btk(mac_handle_t mac_handle,uint8_t session_id,const uint8_t * key,const int key_len)6604 int sme_add_key_btk(mac_handle_t mac_handle, uint8_t session_id,
6605 		    const uint8_t *key, const int key_len)
6606 {
6607 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
6608 	struct wlan_objmgr_vdev *vdev;
6609 	struct rso_config *rso_cfg;
6610 
6611 	if (key_len < WMI_BTK_KEY_LEN) {
6612 		sme_warn("Invalid BTK keylength [= %d]", key_len);
6613 		return -EINVAL;
6614 	}
6615 
6616 	if (!CSR_IS_SESSION_VALID(mac_ctx, session_id)) {
6617 		sme_err("incorrect session/vdev ID");
6618 		return -EINVAL;
6619 	}
6620 
6621 	vdev = wlan_objmgr_get_vdev_by_id_from_pdev(mac_ctx->pdev, session_id,
6622 						    WLAN_LEGACY_SME_ID);
6623 	if (!vdev) {
6624 		sme_err("vdev object is NULL for vdev %d", session_id);
6625 		return QDF_STATUS_E_INVAL;
6626 	}
6627 	rso_cfg = wlan_cm_get_rso_config(vdev);
6628 	if (!rso_cfg) {
6629 		wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID);
6630 		return QDF_STATUS_E_INVAL;
6631 	}
6632 
6633 	qdf_mem_copy(rso_cfg->btk, key, WMI_BTK_KEY_LEN);
6634 	wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID);
6635 	/*
6636 	 * KRK and BTK are updated by upper layer back to back. Send
6637 	 * updated KRK and BTK together to FW here.
6638 	 */
6639 	wlan_roam_update_cfg(mac_ctx->psoc, session_id,
6640 			     REASON_ROAM_PSK_PMK_CHANGED);
6641 
6642 	return 0;
6643 }
6644 #endif
6645 
sme_stop_roaming(mac_handle_t mac_handle,uint8_t vdev_id,uint8_t reason,enum wlan_cm_rso_control_requestor requestor)6646 QDF_STATUS sme_stop_roaming(mac_handle_t mac_handle, uint8_t vdev_id,
6647 			    uint8_t reason,
6648 			    enum wlan_cm_rso_control_requestor requestor)
6649 {
6650 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
6651 	struct csr_roam_session *session;
6652 
6653 	session = CSR_GET_SESSION(mac, vdev_id);
6654 	if (!session) {
6655 		sme_err("ROAM: incorrect vdev ID %d", vdev_id);
6656 		return QDF_STATUS_E_FAILURE;
6657 	}
6658 
6659 	return wlan_cm_disable_rso(mac->pdev, vdev_id, requestor, reason);
6660 }
6661 
sme_start_roaming(mac_handle_t mac_handle,uint8_t vdev_id,uint8_t reason,enum wlan_cm_rso_control_requestor requestor)6662 QDF_STATUS sme_start_roaming(mac_handle_t mac_handle, uint8_t vdev_id,
6663 			     uint8_t reason,
6664 			     enum wlan_cm_rso_control_requestor requestor)
6665 {
6666 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
6667 
6668 	return wlan_cm_enable_rso(mac->pdev, vdev_id, requestor, reason);
6669 }
6670 
sme_roaming_in_progress(mac_handle_t mac_handle,uint8_t vdev_id)6671 bool sme_roaming_in_progress(mac_handle_t mac_handle, uint8_t vdev_id)
6672 {
6673 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
6674 	struct csr_roam_session *session;
6675 
6676 	session = CSR_GET_SESSION(mac, vdev_id);
6677 	if (!session) {
6678 		sme_err("ROAM: incorrect vdev ID %d", vdev_id);
6679 		return false;
6680 	}
6681 
6682 	return wlan_cm_roaming_in_progress(mac->pdev, vdev_id);
6683 }
6684 
6685 /*
6686  * sme_set_roam_opportunistic_scan_threshold_diff() -
6687  * Update Opportunistic Scan threshold diff
6688  *	This function is called through dynamic setConfig callback function
6689  *	to configure  nOpportunisticThresholdDiff
6690  *
6691  * mac_handle: Opaque handle to the global MAC context
6692  * sessionId - Session Identifier
6693  * nOpportunisticThresholdDiff - Opportunistic Scan threshold diff
6694  * Return QDF_STATUS_SUCCESS - SME update nOpportunisticThresholdDiff config
6695  *	    successfully.
6696  *	    else SME is failed to update nOpportunisticThresholdDiff.
6697  */
sme_set_roam_opportunistic_scan_threshold_diff(mac_handle_t mac_handle,uint8_t sessionId,const uint8_t nOpportunisticThresholdDiff)6698 QDF_STATUS sme_set_roam_opportunistic_scan_threshold_diff(
6699 				mac_handle_t mac_handle,
6700 				uint8_t sessionId,
6701 				const uint8_t nOpportunisticThresholdDiff)
6702 {
6703 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
6704 	QDF_STATUS status = QDF_STATUS_SUCCESS;
6705 
6706 	status = sme_acquire_global_lock(&mac->sme);
6707 	if (QDF_IS_STATUS_SUCCESS(status)) {
6708 		status = cm_neighbor_roam_update_config(mac->pdev, sessionId,
6709 				nOpportunisticThresholdDiff,
6710 				REASON_OPPORTUNISTIC_THRESH_DIFF_CHANGED);
6711 		if (QDF_IS_STATUS_SUCCESS(status)) {
6712 			mac->mlme_cfg->lfr.opportunistic_scan_threshold_diff =
6713 				nOpportunisticThresholdDiff;
6714 		}
6715 		sme_release_global_lock(&mac->sme);
6716 	}
6717 	return status;
6718 }
6719 
6720 /*
6721  * sme_set_roam_rescan_rssi_diff() - Update roam rescan rssi diff
6722  * This function is called through dynamic setConfig callback function
6723  * to configure  nRoamRescanRssiDiff
6724  *
6725  * mac_handle: Opaque handle to the global MAC context
6726  * sessionId - Session Identifier
6727  * nRoamRescanRssiDiff - roam rescan rssi diff
6728  * Return QDF_STATUS_SUCCESS - SME update nRoamRescanRssiDiff config
6729  *	    successfully.
6730  * else SME is failed to update nRoamRescanRssiDiff.
6731  */
sme_set_roam_rescan_rssi_diff(mac_handle_t mac_handle,uint8_t sessionId,const uint8_t nRoamRescanRssiDiff)6732 QDF_STATUS sme_set_roam_rescan_rssi_diff(mac_handle_t mac_handle,
6733 					 uint8_t sessionId,
6734 					 const uint8_t nRoamRescanRssiDiff)
6735 {
6736 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
6737 	QDF_STATUS status = QDF_STATUS_SUCCESS;
6738 
6739 	status = sme_acquire_global_lock(&mac->sme);
6740 	if (QDF_IS_STATUS_SUCCESS(status)) {
6741 		status = cm_neighbor_roam_update_config(mac->pdev, sessionId,
6742 				nRoamRescanRssiDiff,
6743 				REASON_ROAM_RESCAN_RSSI_DIFF_CHANGED);
6744 		if (QDF_IS_STATUS_SUCCESS(status))
6745 			mac->mlme_cfg->lfr.roam_rescan_rssi_diff =
6746 				nRoamRescanRssiDiff;
6747 
6748 		sme_release_global_lock(&mac->sme);
6749 	}
6750 	return status;
6751 }
6752 
6753 /*
6754  * sme_set_roam_bmiss_first_bcnt() -
6755  * Update Roam count for first beacon miss
6756  *	    This function is called through dynamic setConfig callback function
6757  *	    to configure nRoamBmissFirstBcnt
6758  * mac_handle: Opaque handle to the global MAC context
6759  * sessionId - Session Identifier
6760  * nRoamBmissFirstBcnt - Roam first bmiss count
6761  * Return QDF_STATUS_SUCCESS - SME update nRoamBmissFirstBcnt
6762  *	    successfully.
6763  * else SME is failed to update nRoamBmissFirstBcnt
6764  */
sme_set_roam_bmiss_first_bcnt(mac_handle_t mac_handle,uint8_t sessionId,const uint8_t nRoamBmissFirstBcnt)6765 QDF_STATUS sme_set_roam_bmiss_first_bcnt(mac_handle_t mac_handle,
6766 					 uint8_t sessionId,
6767 					 const uint8_t nRoamBmissFirstBcnt)
6768 {
6769 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
6770 	QDF_STATUS status = QDF_STATUS_SUCCESS;
6771 
6772 	status = sme_acquire_global_lock(&mac->sme);
6773 	if (QDF_IS_STATUS_SUCCESS(status)) {
6774 		status = cm_neighbor_roam_update_config(mac->pdev, sessionId,
6775 				nRoamBmissFirstBcnt,
6776 				REASON_ROAM_BMISS_FIRST_BCNT_CHANGED);
6777 		if (QDF_IS_STATUS_SUCCESS(status)) {
6778 			mac->mlme_cfg->lfr.roam_bmiss_first_bcnt =
6779 							nRoamBmissFirstBcnt;
6780 		}
6781 		sme_release_global_lock(&mac->sme);
6782 	}
6783 	return status;
6784 }
6785 
6786 /*
6787  * sme_set_roam_bmiss_final_bcnt() -
6788  * Update Roam count for final beacon miss
6789  *	    This function is called through dynamic setConfig callback function
6790  *	    to configure nRoamBmissFinalBcnt
6791  * mac_handle: Opaque handle to the global MAC context
6792  * sessionId - Session Identifier
6793  * nRoamBmissFinalBcnt - Roam final bmiss count
6794  * Return QDF_STATUS_SUCCESS - SME update nRoamBmissFinalBcnt
6795  *	    successfully.
6796  * else SME is failed to update nRoamBmissFinalBcnt
6797  */
sme_set_roam_bmiss_final_bcnt(mac_handle_t mac_handle,uint8_t sessionId,const uint8_t nRoamBmissFinalBcnt)6798 QDF_STATUS sme_set_roam_bmiss_final_bcnt(mac_handle_t mac_handle,
6799 					 uint8_t sessionId,
6800 					 const uint8_t nRoamBmissFinalBcnt)
6801 {
6802 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
6803 	QDF_STATUS status = QDF_STATUS_SUCCESS;
6804 
6805 	status = sme_acquire_global_lock(&mac->sme);
6806 	if (QDF_IS_STATUS_SUCCESS(status)) {
6807 		status = cm_neighbor_roam_update_config(mac->pdev, sessionId,
6808 				nRoamBmissFinalBcnt,
6809 				REASON_ROAM_BMISS_FINAL_BCNT_CHANGED);
6810 		if (QDF_IS_STATUS_SUCCESS(status)) {
6811 			mac->mlme_cfg->lfr.roam_bmiss_final_bcnt =
6812 							nRoamBmissFinalBcnt;
6813 		}
6814 		sme_release_global_lock(&mac->sme);
6815 	}
6816 	return status;
6817 }
6818 
6819 QDF_STATUS
sme_set_neighbor_lookup_rssi_threshold(mac_handle_t mac_handle,uint8_t vdev_id,uint8_t neighbor_lookup_rssi_threshold)6820 sme_set_neighbor_lookup_rssi_threshold(mac_handle_t mac_handle,
6821 				       uint8_t vdev_id,
6822 				       uint8_t neighbor_lookup_rssi_threshold)
6823 {
6824 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
6825 	QDF_STATUS status;
6826 
6827 	if (vdev_id >= WLAN_MAX_VDEVS) {
6828 		sme_err("Invalid vdev_id: %u", vdev_id);
6829 		return QDF_STATUS_E_INVAL;
6830 	}
6831 
6832 	status = sme_acquire_global_lock(&mac->sme);
6833 	if (QDF_IS_STATUS_ERROR(status))
6834 		return status;
6835 	cm_neighbor_roam_update_config(mac->pdev, vdev_id,
6836 					neighbor_lookup_rssi_threshold,
6837 					REASON_LOOKUP_THRESH_CHANGED);
6838 	sme_release_global_lock(&mac->sme);
6839 	return status;
6840 }
6841 
6842 /*
6843  * sme_set_neighbor_scan_refresh_period() - set neighbor scan results
6844  *	refresh period
6845  *  This is a synchronous call
6846  *
6847  * mac_handle - The handle returned by mac_open.
6848  * sessionId - Session Identifier
6849  * Return QDF_STATUS_SUCCESS - SME update config successful.
6850  *	   Other status means SME is failed to update
6851  */
sme_set_neighbor_scan_refresh_period(mac_handle_t mac_handle,uint8_t sessionId,uint16_t neighborScanResultsRefreshPeriod)6852 QDF_STATUS sme_set_neighbor_scan_refresh_period(mac_handle_t mac_handle,
6853 		uint8_t sessionId, uint16_t neighborScanResultsRefreshPeriod)
6854 {
6855 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
6856 	struct cm_roam_values_copy src_config = {};
6857 
6858 	src_config.uint_value = neighborScanResultsRefreshPeriod;
6859 	return wlan_cm_roam_cfg_set_value(mac->psoc, sessionId,
6860 					  NEIGHBOUR_SCAN_REFRESH_PERIOD,
6861 					  &src_config);
6862 }
6863 
6864 /*
6865  * sme_update_empty_scan_refresh_period
6866  * Update empty_scan_refresh_period
6867  *	    This function is called through dynamic setConfig callback function
6868  *	    to configure empty_scan_refresh_period
6869  *	    Usage: adb shell iwpriv wlan0 setConfig
6870  *			empty_scan_refresh_period=[0 .. 60]
6871  *
6872  * mac_handle: Opaque handle to the global MAC context
6873  * sessionId - Session Identifier
6874  * empty_scan_refresh_period - scan period following empty scan results.
6875  * Return Success or failure
6876  */
6877 
sme_update_empty_scan_refresh_period(mac_handle_t mac_handle,uint8_t sessionId,uint16_t empty_scan_refresh_period)6878 QDF_STATUS sme_update_empty_scan_refresh_period(mac_handle_t mac_handle,
6879 						uint8_t sessionId, uint16_t
6880 						empty_scan_refresh_period)
6881 {
6882 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
6883 	struct cm_roam_values_copy src_config = {};
6884 
6885 	src_config.uint_value = empty_scan_refresh_period;
6886 	return wlan_cm_roam_cfg_set_value(mac->psoc, sessionId,
6887 					  EMPTY_SCAN_REFRESH_PERIOD,
6888 					  &src_config);
6889 }
6890 
sme_update_full_roam_scan_period(mac_handle_t mac_handle,uint8_t vdev_id,uint32_t full_roam_scan_period)6891 QDF_STATUS sme_update_full_roam_scan_period(mac_handle_t mac_handle,
6892 					    uint8_t vdev_id,
6893 					    uint32_t full_roam_scan_period)
6894 {
6895 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
6896 	struct cm_roam_values_copy src_config = {};
6897 
6898 	src_config.uint_value = full_roam_scan_period;
6899 	return wlan_cm_roam_cfg_set_value(mac->psoc, vdev_id,
6900 					  FULL_ROAM_SCAN_PERIOD, &src_config);
6901 }
6902 
6903 QDF_STATUS
sme_modify_roam_cand_sel_criteria(mac_handle_t mac_handle,uint8_t vdev_id,bool enable_scoring_for_roam)6904 sme_modify_roam_cand_sel_criteria(mac_handle_t mac_handle,
6905 				  uint8_t vdev_id,
6906 				  bool enable_scoring_for_roam)
6907 {
6908 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
6909 	struct cm_roam_values_copy src_config = {};
6910 
6911 	src_config.bool_value = enable_scoring_for_roam;
6912 	return wlan_cm_roam_cfg_set_value(mac->psoc, vdev_id,
6913 					  ENABLE_SCORING_FOR_ROAM, &src_config);
6914 }
6915 
sme_roam_control_restore_default_config(mac_handle_t mac_handle,uint8_t vdev_id)6916 QDF_STATUS sme_roam_control_restore_default_config(mac_handle_t mac_handle,
6917 						   uint8_t vdev_id)
6918 {
6919 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
6920 
6921 	if (vdev_id >= WLAN_MAX_VDEVS) {
6922 		sme_err("Invalid vdev_id: %d", vdev_id);
6923 		return QDF_STATUS_E_INVAL;
6924 	}
6925 
6926 	return cm_roam_control_restore_default_config(mac->pdev, vdev_id);
6927 }
6928 
6929 /*
6930  * sme_set_neighbor_scan_min_chan_time() -
6931  * Update nNeighborScanMinChanTime
6932  *	    This function is called through dynamic setConfig callback function
6933  *	    to configure gNeighborScanChannelMinTime
6934  *	    Usage: adb shell iwpriv wlan0 setConfig
6935  *			gNeighborScanChannelMinTime=[0 .. 60]
6936  *
6937  * mac_handle: Opaque handle to the global MAC context
6938  * nNeighborScanMinChanTime - Channel minimum dwell time
6939  * sessionId - Session Identifier
6940  * Return Success or failure
6941  */
sme_set_neighbor_scan_min_chan_time(mac_handle_t mac_handle,const uint16_t nNeighborScanMinChanTime,uint8_t sessionId)6942 QDF_STATUS sme_set_neighbor_scan_min_chan_time(mac_handle_t mac_handle,
6943 					       const uint16_t
6944 					       nNeighborScanMinChanTime,
6945 					       uint8_t sessionId)
6946 {
6947 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
6948 	struct cm_roam_values_copy src_config = {};
6949 
6950 	src_config.uint_value = nNeighborScanMinChanTime;
6951 	return wlan_cm_roam_cfg_set_value(mac->psoc, sessionId,
6952 					  SCAN_MIN_CHAN_TIME, &src_config);
6953 }
6954 
6955 /*
6956  * sme_set_neighbor_scan_max_chan_time() -
6957  * Update nNeighborScanMaxChanTime
6958  *	    This function is called through dynamic setConfig callback function
6959  *	    to configure gNeighborScanChannelMaxTime
6960  *	    Usage: adb shell iwpriv wlan0 setConfig
6961  *			gNeighborScanChannelMaxTime=[0 .. 60]
6962  *
6963  * mac_handle: Opaque handle to the global MAC context
6964  * sessionId - Session Identifier
6965  * nNeighborScanMinChanTime - Channel maximum dwell time
6966  * Return Success or failure
6967  */
sme_set_neighbor_scan_max_chan_time(mac_handle_t mac_handle,uint8_t sessionId,const uint16_t nNeighborScanMaxChanTime)6968 QDF_STATUS sme_set_neighbor_scan_max_chan_time(mac_handle_t mac_handle,
6969 					       uint8_t sessionId,
6970 					       const uint16_t
6971 					       nNeighborScanMaxChanTime)
6972 {
6973 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
6974 	struct cm_roam_values_copy src_config = {};
6975 
6976 	src_config.uint_value = nNeighborScanMaxChanTime;
6977 	return wlan_cm_roam_cfg_set_value(mac->psoc, sessionId,
6978 					  SCAN_MAX_CHAN_TIME, &src_config);
6979 }
6980 
6981 /*
6982  * sme_get_current_roam_state() -
6983  * get current roam state
6984  *
6985  * mac_handle - The handle returned by mac_open.
6986  * sessionId - Session Identifier
6987  * Return uint32_t - current roam state
6988  */
sme_get_current_roam_state(mac_handle_t mac_handle,uint8_t sessionId)6989 uint32_t sme_get_current_roam_state(mac_handle_t mac_handle, uint8_t sessionId)
6990 {
6991 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
6992 
6993 	return mac->roam.curState[sessionId];
6994 }
6995 
6996 /*
6997  * sme_get_current_roam_sub_state() -
6998  *   \brief  get neighbor roam sub state
6999  *
7000  * mac_handle - The handle returned by mac_open.
7001  * sessionId - Session Identifier
7002  * Return uint32_t - current roam sub state
7003  */
sme_get_current_roam_sub_state(mac_handle_t mac_handle,uint8_t sessionId)7004 uint32_t sme_get_current_roam_sub_state(mac_handle_t mac_handle,
7005 					uint8_t sessionId)
7006 {
7007 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
7008 
7009 	return mac->roam.curSubState[sessionId];
7010 }
7011 
7012 /*
7013  * sme_get_lim_sme_state() -
7014  *   get Lim Sme state
7015  *
7016  * mac_handle - The handle returned by mac_open.
7017  * Return uint32_t - Lim Sme state
7018  */
sme_get_lim_sme_state(mac_handle_t mac_handle)7019 uint32_t sme_get_lim_sme_state(mac_handle_t mac_handle)
7020 {
7021 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
7022 
7023 	return mac->lim.gLimSmeState;
7024 }
7025 
7026 /*
7027  * sme_get_lim_mlm_state() -
7028  *   get Lim Mlm state
7029  *
7030  * mac_handle - The handle returned by mac_open.
7031  * Return uint32_t - Lim Mlm state
7032  */
sme_get_lim_mlm_state(mac_handle_t mac_handle)7033 uint32_t sme_get_lim_mlm_state(mac_handle_t mac_handle)
7034 {
7035 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
7036 
7037 	return mac->lim.gLimMlmState;
7038 }
7039 
7040 /*
7041  * sme_is_lim_session_valid() -
7042  *  is Lim session valid
7043  *
7044  * mac_handle - The handle returned by mac_open.
7045  * sessionId - Session Identifier
7046  * Return bool - true or false
7047  */
sme_is_lim_session_valid(mac_handle_t mac_handle,uint8_t sessionId)7048 bool sme_is_lim_session_valid(mac_handle_t mac_handle, uint8_t sessionId)
7049 {
7050 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
7051 
7052 	if (sessionId > mac->lim.maxBssId)
7053 		return false;
7054 
7055 	return mac->lim.gpSession[sessionId].valid;
7056 }
7057 
7058 /*
7059  * sme_get_lim_sme_session_state() -
7060  *   get Lim Sme session state
7061  *
7062  * mac_handle - The handle returned by mac_open.
7063  * sessionId - Session Identifier
7064  * Return uint32_t - Lim Sme session state
7065  */
sme_get_lim_sme_session_state(mac_handle_t mac_handle,uint8_t sessionId)7066 uint32_t sme_get_lim_sme_session_state(mac_handle_t mac_handle,
7067 				       uint8_t sessionId)
7068 {
7069 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
7070 
7071 	return mac->lim.gpSession[sessionId].limSmeState;
7072 }
7073 
7074 /*
7075  * sme_get_lim_mlm_session_state() -
7076  *   \brief  get Lim Mlm session state
7077  *
7078  * mac_handle - The handle returned by mac_open.
7079  * sessionId - Session Identifier
7080  * Return uint32_t - Lim Mlm session state
7081  */
sme_get_lim_mlm_session_state(mac_handle_t mac_handle,uint8_t sessionId)7082 uint32_t sme_get_lim_mlm_session_state(mac_handle_t mac_handle,
7083 				       uint8_t sessionId)
7084 {
7085 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
7086 
7087 	return mac->lim.gpSession[sessionId].limMlmState;
7088 }
7089 
7090 /*
7091  * sme_set_neighbor_scan_period() -
7092  *  Update nNeighborScanPeriod
7093  *	    This function is called through dynamic setConfig callback function
7094  *	    to configure nNeighborScanPeriod
7095  *	    Usage: adb shell iwpriv wlan0 setConfig
7096  *			nNeighborScanPeriod=[0 .. 1000]
7097  *
7098  * mac_handle: Opaque handle to the global MAC context
7099  * sessionId - Session Identifier
7100  * nNeighborScanPeriod - neighbor scan period
7101  * Return Success or failure
7102  */
sme_set_neighbor_scan_period(mac_handle_t mac_handle,uint8_t sessionId,const uint16_t nNeighborScanPeriod)7103 QDF_STATUS sme_set_neighbor_scan_period(mac_handle_t mac_handle,
7104 					uint8_t sessionId,
7105 					const uint16_t nNeighborScanPeriod)
7106 {
7107 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
7108 	struct cm_roam_values_copy src_config = {};
7109 
7110 	src_config.uint_value = nNeighborScanPeriod;
7111 	return wlan_cm_roam_cfg_set_value(mac->psoc, sessionId,
7112 					  NEIGHBOR_SCAN_PERIOD,
7113 					  &src_config);
7114 }
7115 
sme_validate_freq_list(mac_handle_t mac_handle,uint32_t * freq_list,uint8_t num_channels)7116 static bool sme_validate_freq_list(mac_handle_t mac_handle,
7117 				   uint32_t *freq_list,
7118 				   uint8_t num_channels)
7119 {
7120 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
7121 	uint8_t i = 0, j;
7122 	bool found;
7123 	struct csr_channel *ch_lst_info = &mac_ctx->scan.base_channels;
7124 
7125 	if (!freq_list || !num_channels) {
7126 		sme_err("Freq list empty %pK or num_channels is 0", freq_list);
7127 		return false;
7128 	}
7129 
7130 	while (i < num_channels) {
7131 		found = false;
7132 		for (j = 0; j < ch_lst_info->numChannels; j++) {
7133 			if (ch_lst_info->channel_freq_list[j] == freq_list[i]) {
7134 				found = true;
7135 				break;
7136 			}
7137 		}
7138 
7139 		if (!found) {
7140 			sme_debug("Invalid frequency %u", freq_list[i]);
7141 			return false;
7142 		}
7143 
7144 		i++;
7145 	}
7146 
7147 	return true;
7148 }
7149 
7150 QDF_STATUS
sme_update_roam_scan_freq_list(mac_handle_t mac_handle,uint8_t vdev_id,uint32_t * freq_list,uint8_t num_chan,uint32_t freq_list_type)7151 sme_update_roam_scan_freq_list(mac_handle_t mac_handle, uint8_t vdev_id,
7152 			       uint32_t *freq_list, uint8_t num_chan,
7153 			       uint32_t freq_list_type)
7154 {
7155 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
7156 	struct cm_roam_values_copy src_config = {};
7157 
7158 	if (!sme_validate_freq_list(mac_handle, freq_list, num_chan)) {
7159 		sme_err("List contains invalid channel(s)");
7160 		return QDF_STATUS_E_INVAL;
7161 	}
7162 
7163 	/*
7164 	 * NCHO Frequency configurations:
7165 	 * If ADDROAMSCANFREQUENCIES command is given, then freq_list_type is
7166 	 * QCA_PREFERRED_SCAN_FREQ_LIST.
7167 	 * If SETROAMSCANFREQUENCIES command is given, then freq_list_type is
7168 	 * QCA_SPECIFIC_SCAN_FREQ_LIST.
7169 	 *
7170 	 * If new channels are configured with type as STATIC(specific freq
7171 	 * list):
7172 	 * - FW clears both static & dynamic list.
7173 	 * - FW adds new channels to static & dynamic lists(both list contains
7174 	 *   only new channels)
7175 	 *
7176 	 * If Host configures new channels with type as DYNAMIC(preferred freq
7177 	 * list):
7178 	 * - FW clears the static list and adds new channels(Static list
7179 	 *   contains only new channels)
7180 	 * - FW will not clear dynamic list. New channels will be
7181 	 *   appended(Dynamic list contains old+new channels)
7182 	 */
7183 
7184 	src_config.chan_info.freq_list = freq_list;
7185 	src_config.chan_info.num_chan = num_chan;
7186 	if (freq_list_type == QCA_PREFERRED_SCAN_FREQ_LIST)
7187 		return wlan_cm_roam_cfg_set_value(mac->psoc, vdev_id,
7188 						  ROAM_PREFERRED_CHAN,
7189 						  &src_config);
7190 	else
7191 		return wlan_cm_roam_cfg_set_value(mac->psoc, vdev_id,
7192 						  ROAM_SPECIFIC_CHAN,
7193 						  &src_config);
7194 }
7195 
7196 /**
7197  * sme_get_roam_scan_channel_list() - To get roam scan channel list
7198  * @mac_handle: Opaque handle to the global MAC context
7199  * @freq_list: Output channel freq list
7200  * @pNumChannels: Output number of channels
7201  * @sessionId: Session Identifier
7202  *
7203  * To get roam scan channel list This is a synchronous call
7204  *
7205  * Return: QDF_STATUS
7206  */
sme_get_roam_scan_channel_list(mac_handle_t mac_handle,uint32_t * freq_list,uint8_t * pNumChannels,uint8_t sessionId)7207 QDF_STATUS sme_get_roam_scan_channel_list(mac_handle_t mac_handle,
7208 			uint32_t *freq_list, uint8_t *pNumChannels,
7209 			uint8_t sessionId)
7210 {
7211 	int i = 0, chan_cnt = 0;
7212 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
7213 	QDF_STATUS status = QDF_STATUS_SUCCESS;
7214 	struct rso_chan_info *chan_info;
7215 	struct wlan_objmgr_vdev *vdev;
7216 	struct rso_config *rso_cfg;
7217 	struct rso_cfg_params *cfg_params;
7218 
7219 	if (sessionId >= WLAN_MAX_VDEVS) {
7220 		sme_err("Invalid sme vdev %d", sessionId);
7221 		return QDF_STATUS_E_INVAL;
7222 	}
7223 
7224 	status = sme_acquire_global_lock(&mac->sme);
7225 	if (!QDF_IS_STATUS_SUCCESS(status))
7226 		return status;
7227 
7228 	vdev = wlan_objmgr_get_vdev_by_id_from_pdev(mac->pdev, sessionId,
7229 						    WLAN_LEGACY_SME_ID);
7230 	if (!vdev) {
7231 		sme_err("vdev object is NULL for vdev %d", sessionId);
7232 		sme_release_global_lock(&mac->sme);
7233 		return QDF_STATUS_E_INVAL;
7234 	}
7235 	rso_cfg = wlan_cm_get_rso_config(vdev);
7236 	if (!rso_cfg) {
7237 		sme_release_global_lock(&mac->sme);
7238 		wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID);
7239 		return QDF_STATUS_E_INVAL;
7240 	}
7241 	cfg_params = &rso_cfg->cfg_param;
7242 	chan_info = &cfg_params->specific_chan_info;
7243 	if (chan_info->num_chan) {
7244 		*pNumChannels = chan_info->num_chan;
7245 		for (i = 0; i < (*pNumChannels) &&
7246 		     i < WNI_CFG_VALID_CHANNEL_LIST_LEN; i++)
7247 			freq_list[i] = chan_info->freq_list[i];
7248 
7249 		*pNumChannels = i;
7250 	} else {
7251 		chan_info = &cfg_params->pref_chan_info;
7252 		*pNumChannels = chan_info->num_chan;
7253 		if (chan_info->num_chan) {
7254 			for (chan_cnt = 0; chan_cnt < (*pNumChannels) &&
7255 			     chan_cnt < WNI_CFG_VALID_CHANNEL_LIST_LEN;
7256 			     chan_cnt++)
7257 				freq_list[chan_cnt] =
7258 					chan_info->freq_list[chan_cnt];
7259 		}
7260 
7261 		if (rso_cfg->occupied_chan_lst.num_chan) {
7262 			for (i = 0; i < rso_cfg->occupied_chan_lst.num_chan &&
7263 			     chan_cnt < CFG_VALID_CHANNEL_LIST_LEN; i++)
7264 				freq_list[chan_cnt++] =
7265 				     rso_cfg->occupied_chan_lst.freq_list[i];
7266 		}
7267 
7268 		*pNumChannels = chan_cnt;
7269 		if (!(chan_info->num_chan ||
7270 		      rso_cfg->occupied_chan_lst.num_chan)) {
7271 			sme_info("Roam Scan channel list is NOT yet initialized");
7272 			*pNumChannels = 0;
7273 			status = QDF_STATUS_E_INVAL;
7274 		}
7275 	}
7276 
7277 	wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID);
7278 	sme_release_global_lock(&mac->sme);
7279 	return status;
7280 }
7281 
7282 /**
7283  * sme_is_feature_supported_by_fw() - check if feature is supported by FW
7284  * @feature: enum value of requested feature.
7285  *
7286  * Return: 1 if supported; 0 otherwise
7287  */
sme_is_feature_supported_by_fw(enum cap_bitmap feature)7288 bool sme_is_feature_supported_by_fw(enum cap_bitmap feature)
7289 {
7290 	return IS_FEATURE_SUPPORTED_BY_FW(feature);
7291 }
7292 
sme_get_link_speed(mac_handle_t mac_handle,struct link_speed_info * req,void * context,sme_link_speed_cb cb)7293 QDF_STATUS sme_get_link_speed(mac_handle_t mac_handle,
7294 			      struct link_speed_info *req,
7295 			      void *context,
7296 			      sme_link_speed_cb cb)
7297 {
7298 	QDF_STATUS status;
7299 	struct mac_context *mac;
7300 	void *wma_handle;
7301 
7302 	if (!mac_handle || !cb || !req) {
7303 		sme_err("Invalid parameter");
7304 		return QDF_STATUS_E_FAILURE;
7305 	}
7306 
7307 	wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
7308 	if (!wma_handle)
7309 		return QDF_STATUS_E_FAILURE;
7310 
7311 	mac = MAC_CONTEXT(mac_handle);
7312 	status = sme_acquire_global_lock(&mac->sme);
7313 	if (QDF_STATUS_SUCCESS != status) {
7314 		sme_err("Failed to acquire global lock");
7315 		return QDF_STATUS_E_FAILURE;
7316 	}
7317 
7318 	mac->sme.link_speed_context = context;
7319 	mac->sme.link_speed_cb = cb;
7320 	status = wma_get_link_speed(wma_handle, req);
7321 	sme_release_global_lock(&mac->sme);
7322 	return status;
7323 }
7324 
sme_get_isolation(mac_handle_t mac_handle,void * context,sme_get_isolation_cb callbackfn)7325 QDF_STATUS sme_get_isolation(mac_handle_t mac_handle, void *context,
7326 			     sme_get_isolation_cb callbackfn)
7327 {
7328 	QDF_STATUS status;
7329 	struct mac_context  *mac = MAC_CONTEXT(mac_handle);
7330 	struct scheduler_msg message = {0};
7331 
7332 	if (!callbackfn) {
7333 		sme_err("Indication Call back is NULL");
7334 		return QDF_STATUS_E_FAILURE;
7335 	}
7336 	status = sme_acquire_global_lock(&mac->sme);
7337 	if (QDF_IS_STATUS_ERROR(status))
7338 		return status;
7339 	mac->sme.get_isolation_cb = callbackfn;
7340 	mac->sme.get_isolation_cb_context = context;
7341 	message.bodyptr = NULL;
7342 	message.type    = WMA_GET_ISOLATION;
7343 	status = scheduler_post_message(QDF_MODULE_ID_SME,
7344 					QDF_MODULE_ID_WMA,
7345 					QDF_MODULE_ID_WMA,
7346 					&message);
7347 	if (!QDF_IS_STATUS_SUCCESS(status)) {
7348 		sme_err("failed to post WMA_GET_ISOLATION");
7349 		status = QDF_STATUS_E_FAILURE;
7350 	}
7351 	sme_release_global_lock(&mac->sme);
7352 	return status;
7353 }
7354 
7355 /*convert the ini value to the ENUM used in csr and MAC for CB state*/
sme_get_cb_phy_state_from_cb_ini_value(uint32_t cb_ini_value)7356 ePhyChanBondState sme_get_cb_phy_state_from_cb_ini_value(uint32_t cb_ini_value)
7357 {
7358 	return csr_convert_cb_ini_value_to_phy_cb_state(cb_ini_value);
7359 }
7360 
7361 /**
7362  * sme_add_periodic_tx_ptrn() - Add Periodic TX Pattern
7363  * @mac_handle: Opaque handle to the global MAC context
7364  * @addPeriodicTxPtrnParams: request message
7365  *
7366  * Return: QDF_STATUS enumeration
7367  */
7368 QDF_STATUS
sme_add_periodic_tx_ptrn(mac_handle_t mac_handle,struct sSirAddPeriodicTxPtrn * addPeriodicTxPtrnParams)7369 sme_add_periodic_tx_ptrn(mac_handle_t mac_handle,
7370 			 struct sSirAddPeriodicTxPtrn *addPeriodicTxPtrnParams)
7371 {
7372 	QDF_STATUS status   = QDF_STATUS_SUCCESS;
7373 	struct mac_context *mac  = MAC_CONTEXT(mac_handle);
7374 	struct sSirAddPeriodicTxPtrn *req_msg;
7375 	struct scheduler_msg msg = {0};
7376 
7377 	SME_ENTER();
7378 
7379 	req_msg = qdf_mem_malloc(sizeof(*req_msg));
7380 	if (!req_msg)
7381 		return QDF_STATUS_E_NOMEM;
7382 
7383 	*req_msg = *addPeriodicTxPtrnParams;
7384 
7385 	status = sme_acquire_global_lock(&mac->sme);
7386 	if (!QDF_IS_STATUS_SUCCESS(status)) {
7387 		sme_err("sme_acquire_global_lock failed!(status=%d)",
7388 			status);
7389 		qdf_mem_free(req_msg);
7390 		return status;
7391 	}
7392 
7393 	/* Serialize the req through MC thread */
7394 	msg.bodyptr = req_msg;
7395 	msg.type    = WMA_ADD_PERIODIC_TX_PTRN_IND;
7396 	MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG,
7397 			 NO_SESSION, msg.type));
7398 	status = scheduler_post_message(QDF_MODULE_ID_SME,
7399 					QDF_MODULE_ID_WMA,
7400 					QDF_MODULE_ID_WMA, &msg);
7401 	if (!QDF_IS_STATUS_SUCCESS(status)) {
7402 		sme_err("scheduler_post_msg failed!(err=%d)",
7403 			status);
7404 		qdf_mem_free(req_msg);
7405 	}
7406 	sme_release_global_lock(&mac->sme);
7407 	return status;
7408 }
7409 
7410 /**
7411  * sme_del_periodic_tx_ptrn() - Delete Periodic TX Pattern
7412  * @mac_handle: Opaque handle to the global MAC context
7413  * @delPeriodicTxPtrnParams: request message
7414  *
7415  * Return: QDF_STATUS enumeration
7416  */
7417 QDF_STATUS
sme_del_periodic_tx_ptrn(mac_handle_t mac_handle,struct sSirDelPeriodicTxPtrn * delPeriodicTxPtrnParams)7418 sme_del_periodic_tx_ptrn(mac_handle_t mac_handle,
7419 			 struct sSirDelPeriodicTxPtrn *delPeriodicTxPtrnParams)
7420 {
7421 	QDF_STATUS status    = QDF_STATUS_SUCCESS;
7422 	struct mac_context *mac   = MAC_CONTEXT(mac_handle);
7423 	struct sSirDelPeriodicTxPtrn *req_msg;
7424 	struct scheduler_msg msg = {0};
7425 
7426 	SME_ENTER();
7427 
7428 	req_msg = qdf_mem_malloc(sizeof(*req_msg));
7429 	if (!req_msg)
7430 		return QDF_STATUS_E_NOMEM;
7431 
7432 	*req_msg = *delPeriodicTxPtrnParams;
7433 
7434 	status = sme_acquire_global_lock(&mac->sme);
7435 	if (!QDF_IS_STATUS_SUCCESS(status)) {
7436 		sme_err("sme_acquire_global_lock failed!(status=%d)",
7437 			status);
7438 		qdf_mem_free(req_msg);
7439 		return status;
7440 	}
7441 
7442 	/* Serialize the req through MC thread */
7443 	msg.bodyptr = req_msg;
7444 	msg.type    = WMA_DEL_PERIODIC_TX_PTRN_IND;
7445 	MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG,
7446 			 NO_SESSION, msg.type));
7447 	status = scheduler_post_message(QDF_MODULE_ID_SME,
7448 					QDF_MODULE_ID_WMA,
7449 					QDF_MODULE_ID_WMA, &msg);
7450 	if (!QDF_IS_STATUS_SUCCESS(status)) {
7451 		sme_err("scheduler_post_msg failed!(err=%d)",
7452 			status);
7453 		qdf_mem_free(req_msg);
7454 	}
7455 	sme_release_global_lock(&mac->sme);
7456 	return status;
7457 }
7458 
7459 #ifdef MULTI_CLIENT_LL_SUPPORT
sme_multi_client_ll_rsp_register_callback(mac_handle_t mac_handle,void (* latency_level_event_handler_cb)(const struct latency_level_data * event_data,uint8_t vdev_id))7460 QDF_STATUS sme_multi_client_ll_rsp_register_callback(mac_handle_t mac_handle,
7461 				void (*latency_level_event_handler_cb)
7462 				(const struct latency_level_data *event_data,
7463 				 uint8_t vdev_id))
7464 {
7465 	QDF_STATUS status = QDF_STATUS_SUCCESS;
7466 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
7467 
7468 	status = sme_acquire_global_lock(&mac->sme);
7469 	if (QDF_IS_STATUS_SUCCESS(status)) {
7470 		mac->sme.latency_level_event_handler_cb =
7471 				latency_level_event_handler_cb;
7472 		sme_release_global_lock(&mac->sme);
7473 	}
7474 
7475 	return status;
7476 }
7477 
sme_multi_client_ll_rsp_deregister_callback(mac_handle_t mac_handle)7478 void sme_multi_client_ll_rsp_deregister_callback(mac_handle_t mac_handle)
7479 {
7480 	sme_multi_client_ll_rsp_register_callback(mac_handle, NULL);
7481 }
7482 
7483 /**
7484  * sme_fill_multi_client_info() - Fill multi client info
7485  * @param:latency leevel param
7486  * @client_id_bitmap: bitmap for host clients
7487  * @force_reset: force reset bit to clear latency level for all clients
7488  *
7489  * Return: none
7490  */
7491 static void
sme_fill_multi_client_info(struct wlm_latency_level_param * params,uint32_t client_id_bitmap,bool force_reset)7492 sme_fill_multi_client_info(struct wlm_latency_level_param *params,
7493 			   uint32_t client_id_bitmap, bool force_reset)
7494 {
7495 	params->client_id_bitmask = client_id_bitmap;
7496 	params->force_reset = force_reset;
7497 }
7498 #else
7499 static inline void
sme_fill_multi_client_info(struct wlm_latency_level_param * params,uint32_t client_id_bitmap,bool force_reset)7500 sme_fill_multi_client_info(struct wlm_latency_level_param *params,
7501 			   uint32_t client_id_bitmap, bool force_reset)
7502 {
7503 }
7504 #endif
7505 
sme_set_wlm_latency_level(mac_handle_t mac_handle,uint16_t session_id,uint16_t latency_level,uint32_t client_id_bitmap,bool force_reset)7506 QDF_STATUS sme_set_wlm_latency_level(mac_handle_t mac_handle,
7507 				uint16_t session_id, uint16_t latency_level,
7508 				uint32_t client_id_bitmap,
7509 				bool force_reset)
7510 {
7511 	QDF_STATUS status;
7512 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
7513 	struct wlm_latency_level_param params;
7514 	void *wma = cds_get_context(QDF_MODULE_ID_WMA);
7515 
7516 	SME_ENTER();
7517 
7518 	if (!wma)
7519 		return QDF_STATUS_E_FAILURE;
7520 
7521 	if (!mac_ctx->mlme_cfg->wlm_config.latency_enable) {
7522 		sme_err("WLM latency level setting is disabled");
7523 		return QDF_STATUS_E_FAILURE;
7524 	}
7525 	if (!wma) {
7526 		sme_err("wma is NULL");
7527 		return QDF_STATUS_E_FAILURE;
7528 	}
7529 
7530 	if (session_id == WLAN_INVALID_LINK_ID) {
7531 		sme_err("Invalid vdev_id[%u]", session_id);
7532 		return QDF_STATUS_E_FAILURE;
7533 	}
7534 
7535 	params.wlm_latency_level = latency_level;
7536 	params.wlm_latency_flags =
7537 		mac_ctx->mlme_cfg->wlm_config.latency_flags[latency_level];
7538 	params.vdev_id = session_id;
7539 	sme_fill_multi_client_info(&params, client_id_bitmap, force_reset);
7540 
7541 	status = wma_set_wlm_latency_level(wma, &params);
7542 
7543 	return status;
7544 }
7545 
sme_get_command_q_status(mac_handle_t mac_handle)7546 void sme_get_command_q_status(mac_handle_t mac_handle)
7547 {
7548 	tSmeCmd *pTempCmd = NULL;
7549 	struct mac_context *mac;
7550 	struct wlan_serialization_command *cmd;
7551 
7552 	if (!mac_handle)
7553 		return;
7554 
7555 	mac = MAC_CONTEXT(mac_handle);
7556 
7557 	sme_debug("smeCmdPendingList has %d commands",
7558 		  wlan_serialization_get_pending_list_count(mac->psoc, false));
7559 	cmd = wlan_serialization_peek_head_active_cmd_using_psoc(mac->psoc,
7560 								 false);
7561 	if (cmd)
7562 		sme_debug("Active commaned is %d cmd id %d source %d",
7563 			  cmd->cmd_type, cmd->cmd_id, cmd->source);
7564 	if (!cmd || cmd->source != WLAN_UMAC_COMP_MLME)
7565 		return;
7566 
7567 	pTempCmd = cmd->umac_cmd;
7568 	if (pTempCmd) {
7569 		if (eSmeCsrCommandMask & pTempCmd->command)
7570 			/* CSR command is stuck. See what the reason code is
7571 			 * for that command
7572 			 */
7573 			dump_csr_command_info(mac, pTempCmd);
7574 	}
7575 }
7576 
7577 #ifdef WLAN_FEATURE_DSRC
7578 /**
7579  * sme_ocb_gen_timing_advert_frame() - generate TA frame and populate the buffer
7580  * @mac_handle: Opaque handle to the global MAC context
7581  * @self_addr: the self MAC address
7582  * @buf: the buffer that will contain the frame
7583  * @timestamp_offset: return for the offset of the timestamp field
7584  * @time_value_offset: return for the time_value field in the TA IE
7585  *
7586  * Return: the length of the buffer on success and error code on failure.
7587  */
sme_ocb_gen_timing_advert_frame(mac_handle_t mac_handle,tSirMacAddr self_addr,uint8_t ** buf,uint32_t * timestamp_offset,uint32_t * time_value_offset)7588 int sme_ocb_gen_timing_advert_frame(mac_handle_t mac_handle,
7589 				    tSirMacAddr self_addr, uint8_t **buf,
7590 				    uint32_t *timestamp_offset,
7591 				    uint32_t *time_value_offset)
7592 {
7593 	int template_length;
7594 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
7595 
7596 	template_length = sch_gen_timing_advert_frame(mac_ctx, self_addr, buf,
7597 						  timestamp_offset,
7598 						  time_value_offset);
7599 	return template_length;
7600 }
7601 #endif
7602 
sme_notify_modem_power_state(mac_handle_t mac_handle,uint32_t value)7603 QDF_STATUS sme_notify_modem_power_state(mac_handle_t mac_handle, uint32_t value)
7604 {
7605 	struct scheduler_msg msg = {0};
7606 	tpSirModemPowerStateInd request_buf;
7607 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
7608 
7609 	if (!mac)
7610 		return QDF_STATUS_E_FAILURE;
7611 
7612 	request_buf = qdf_mem_malloc(sizeof(tSirModemPowerStateInd));
7613 	if (!request_buf)
7614 		return QDF_STATUS_E_NOMEM;
7615 
7616 	request_buf->param = value;
7617 
7618 	msg.type = WMA_MODEM_POWER_STATE_IND;
7619 	msg.reserved = 0;
7620 	msg.bodyptr = request_buf;
7621 	if (!QDF_IS_STATUS_SUCCESS
7622 		    (scheduler_post_message(QDF_MODULE_ID_SME,
7623 					    QDF_MODULE_ID_WMA,
7624 					    QDF_MODULE_ID_WMA, &msg))) {
7625 		sme_err("Not able to post WMA_MODEM_POWER_STATE_IND message to WMA");
7626 		qdf_mem_free(request_buf);
7627 		return QDF_STATUS_E_FAILURE;
7628 	}
7629 
7630 	return QDF_STATUS_SUCCESS;
7631 }
7632 
7633 #ifdef QCA_HT_2040_COEX
sme_notify_ht2040_mode(mac_handle_t mac_handle,struct qdf_mac_addr macAddrSTA,uint8_t sessionId,uint8_t channel_type)7634 QDF_STATUS sme_notify_ht2040_mode(mac_handle_t mac_handle,
7635 				  struct qdf_mac_addr macAddrSTA,
7636 				  uint8_t sessionId,
7637 				  uint8_t channel_type)
7638 {
7639 	struct scheduler_msg msg = {0};
7640 	tUpdateVHTOpMode *pHtOpMode = NULL;
7641 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
7642 
7643 	if (!mac)
7644 		return QDF_STATUS_E_FAILURE;
7645 
7646 	pHtOpMode = qdf_mem_malloc(sizeof(tUpdateVHTOpMode));
7647 	if (!pHtOpMode)
7648 		return QDF_STATUS_E_NOMEM;
7649 
7650 	switch (channel_type) {
7651 	case eHT_CHAN_HT20:
7652 		pHtOpMode->opMode = eHT_CHANNEL_WIDTH_20MHZ;
7653 		break;
7654 
7655 	case eHT_CHAN_HT40MINUS:
7656 	case eHT_CHAN_HT40PLUS:
7657 		pHtOpMode->opMode = eHT_CHANNEL_WIDTH_40MHZ;
7658 		break;
7659 
7660 	default:
7661 		sme_err("Invalid OP mode %d", channel_type);
7662 		qdf_mem_free(pHtOpMode);
7663 		return QDF_STATUS_E_FAILURE;
7664 	}
7665 
7666 	qdf_mem_copy(pHtOpMode->peer_mac, macAddrSTA.bytes,
7667 		     sizeof(tSirMacAddr));
7668 	pHtOpMode->smesessionId = sessionId;
7669 
7670 	msg.type = WMA_UPDATE_OP_MODE;
7671 	msg.reserved = 0;
7672 	msg.bodyptr = pHtOpMode;
7673 	if (QDF_IS_STATUS_ERROR
7674 		    (scheduler_post_message(QDF_MODULE_ID_SME,
7675 					    QDF_MODULE_ID_WMA,
7676 					    QDF_MODULE_ID_WMA, &msg))) {
7677 		sme_err("Not able to post WMA_UPDATE_OP_MODE message to WMA");
7678 		qdf_mem_free(pHtOpMode);
7679 		return QDF_STATUS_E_FAILURE;
7680 	}
7681 
7682 	sme_debug("vdev %d OP mode: %d", sessionId, pHtOpMode->opMode);
7683 
7684 	return QDF_STATUS_SUCCESS;
7685 }
7686 
7687 /*
7688  * sme_set_ht2040_mode() -
7689  *  To update HT Operation beacon IE.
7690  *
7691  * Return QDF_STATUS  SUCCESS
7692  *			FAILURE or RESOURCES
7693  *			The API finished and failed.
7694  */
sme_set_ht2040_mode(mac_handle_t mac_handle,uint8_t sessionId,uint8_t channel_type,bool obssEnabled)7695 QDF_STATUS sme_set_ht2040_mode(mac_handle_t mac_handle, uint8_t sessionId,
7696 			       uint8_t channel_type, bool obssEnabled)
7697 {
7698 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
7699 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
7700 	ePhyChanBondState cb_mode;
7701 	struct csr_roam_session *session = CSR_GET_SESSION(mac, sessionId);
7702 
7703 	if (!CSR_IS_SESSION_VALID(mac, sessionId)) {
7704 		sme_err("Session not valid for session id %d", sessionId);
7705 		return QDF_STATUS_E_INVAL;
7706 	}
7707 	session = CSR_GET_SESSION(mac, sessionId);
7708 	sme_debug("Update HT operation beacon IE, channel_type=%d cur cbmode %d",
7709 		channel_type, session->cb_mode);
7710 
7711 	switch (channel_type) {
7712 	case eHT_CHAN_HT20:
7713 		if (!session->cb_mode)
7714 			return QDF_STATUS_SUCCESS;
7715 		cb_mode = PHY_SINGLE_CHANNEL_CENTERED;
7716 		break;
7717 	case eHT_CHAN_HT40MINUS:
7718 		if (session->cb_mode)
7719 			return QDF_STATUS_SUCCESS;
7720 		cb_mode = PHY_DOUBLE_CHANNEL_HIGH_PRIMARY;
7721 		break;
7722 	case eHT_CHAN_HT40PLUS:
7723 		if (session->cb_mode)
7724 			return QDF_STATUS_SUCCESS;
7725 		cb_mode = PHY_DOUBLE_CHANNEL_LOW_PRIMARY;
7726 		break;
7727 	default:
7728 		sme_err("Error!!! Invalid HT20/40 mode !");
7729 		return QDF_STATUS_E_FAILURE;
7730 	}
7731 	session->cb_mode = cb_mode;
7732 	status = sme_acquire_global_lock(&mac->sme);
7733 	if (QDF_IS_STATUS_SUCCESS(status)) {
7734 		status = csr_set_ht2040_mode(mac, sessionId,
7735 					     cb_mode, obssEnabled);
7736 		sme_release_global_lock(&mac->sme);
7737 	}
7738 	return status;
7739 }
7740 
sme_get_ht2040_mode(mac_handle_t mac_handle,uint8_t vdev_id,enum eSirMacHTChannelType * channel_type)7741 QDF_STATUS sme_get_ht2040_mode(mac_handle_t mac_handle, uint8_t vdev_id,
7742 			       enum eSirMacHTChannelType *channel_type)
7743 {
7744 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
7745 	struct csr_roam_session *session;
7746 
7747 	if (!CSR_IS_SESSION_VALID(mac, vdev_id)) {
7748 		sme_err("Session not valid for session id %d", vdev_id);
7749 		return QDF_STATUS_E_INVAL;
7750 	}
7751 	session = CSR_GET_SESSION(mac, vdev_id);
7752 	sme_debug("Get HT operation beacon IE, channel_type=%d cur cbmode %d",
7753 		  *channel_type, session->cb_mode);
7754 
7755 	switch (session->cb_mode) {
7756 	case PHY_SINGLE_CHANNEL_CENTERED:
7757 		*channel_type = eHT_CHAN_HT20;
7758 		break;
7759 	case PHY_DOUBLE_CHANNEL_HIGH_PRIMARY:
7760 		*channel_type = eHT_CHAN_HT40MINUS;
7761 		break;
7762 	case PHY_DOUBLE_CHANNEL_LOW_PRIMARY:
7763 		*channel_type = eHT_CHAN_HT40PLUS;
7764 		break;
7765 	default:
7766 		sme_err("Error!!! Invalid HT20/40 mode !");
7767 		return QDF_STATUS_E_FAILURE;
7768 	}
7769 
7770 	return QDF_STATUS_SUCCESS;
7771 }
7772 
7773 #endif
7774 
7775 /*
7776  * SME API to enable/disable idle mode powersave
7777  * This should be called only if powersave offload
7778  * is enabled
7779  */
sme_set_idle_powersave_config(bool value)7780 QDF_STATUS sme_set_idle_powersave_config(bool value)
7781 {
7782 	void *wmaContext = cds_get_context(QDF_MODULE_ID_WMA);
7783 
7784 	if (!wmaContext)
7785 		return QDF_STATUS_E_FAILURE;
7786 
7787 	if (QDF_STATUS_SUCCESS != wma_set_idle_ps_config(wmaContext, value))
7788 		return QDF_STATUS_E_FAILURE;
7789 
7790 	return QDF_STATUS_SUCCESS;
7791 }
7792 
sme_get_ht_config(mac_handle_t mac_handle,uint8_t vdev_id,uint16_t ht_capab)7793 int16_t sme_get_ht_config(mac_handle_t mac_handle, uint8_t vdev_id,
7794 			  uint16_t ht_capab)
7795 {
7796 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
7797 	struct csr_roam_session *pSession = CSR_GET_SESSION(mac, vdev_id);
7798 	struct wlan_objmgr_vdev *vdev;
7799 	struct vdev_mlme_obj *vdev_mlme;
7800 	struct wlan_ht_config ht_cap_info;
7801 
7802 	if (!pSession) {
7803 		sme_err("pSession is NULL");
7804 		return -EIO;
7805 	}
7806 
7807 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac->psoc, vdev_id,
7808 						    WLAN_LEGACY_SME_ID);
7809 	if (!vdev)
7810 		return -EIO;
7811 	vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev);
7812 	if (!vdev_mlme) {
7813 		wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID);
7814 		return -EIO;
7815 	}
7816 	ht_cap_info.caps = vdev_mlme->proto.ht_info.ht_caps;
7817 	wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID);
7818 	switch (ht_capab) {
7819 	case WNI_CFG_HT_CAP_INFO_ADVANCE_CODING:
7820 		return ht_cap_info.ht_caps.adv_coding_cap;
7821 	case WNI_CFG_HT_CAP_INFO_TX_STBC:
7822 		return ht_cap_info.ht_caps.tx_stbc;
7823 	case WNI_CFG_HT_CAP_INFO_RX_STBC:
7824 		return ht_cap_info.ht_caps.rx_stbc;
7825 	case WNI_CFG_HT_CAP_INFO_SHORT_GI_20MHZ:
7826 		return ht_cap_info.ht_caps.short_gi_20_mhz;
7827 	case WNI_CFG_HT_CAP_INFO_SHORT_GI_40MHZ:
7828 		return ht_cap_info.ht_caps.short_gi_40_mhz;
7829 	default:
7830 		sme_err("invalid ht capability");
7831 		return -EIO;
7832 	}
7833 }
7834 
7835 /**
7836  * sme_validate_peer_ampdu_cfg() - Function to validate peer A-MPDU configure
7837  * @peer: peer object
7838  * @cfg: peer A-MPDU configure value
7839  *
7840  * Return: true if success, otherwise false
7841  */
sme_validate_peer_ampdu_cfg(struct wlan_objmgr_peer * peer,uint16_t cfg)7842 static bool sme_validate_peer_ampdu_cfg(struct wlan_objmgr_peer *peer,
7843 					uint16_t cfg)
7844 {
7845 	if (!cfg) {
7846 		sme_debug("peer ampdu count 0");
7847 		return false;
7848 	}
7849 
7850 	if (wlan_peer_get_peer_type(peer) == WLAN_PEER_SELF) {
7851 		sme_debug("self peer");
7852 		return false;
7853 	}
7854 
7855 	return true;
7856 }
7857 
sme_set_peer_ampdu(mac_handle_t mac_handle,uint8_t vdev_id,struct qdf_mac_addr * peer_mac,uint16_t cfg)7858 int sme_set_peer_ampdu(mac_handle_t mac_handle, uint8_t vdev_id,
7859 		       struct qdf_mac_addr *peer_mac, uint16_t cfg)
7860 {
7861 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
7862 	struct wlan_objmgr_vdev *vdev;
7863 	QDF_STATUS status;
7864 	struct wlan_objmgr_peer *peer_obj;
7865 
7866 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac_ctx->psoc,
7867 						    vdev_id,
7868 						    WLAN_LEGACY_SME_ID);
7869 	if (!vdev) {
7870 		sme_err("vdev null");
7871 		return -EINVAL;
7872 	}
7873 
7874 	status = wlan_vdev_is_up(vdev);
7875 	if (QDF_IS_STATUS_ERROR(status)) {
7876 		sme_debug("vdev id %d not up", vdev_id);
7877 		goto release_vdev_ref;
7878 	}
7879 	peer_obj = wlan_objmgr_vdev_find_peer_by_mac(vdev,
7880 						     peer_mac->bytes,
7881 						     WLAN_LEGACY_SME_ID);
7882 	if (!peer_obj) {
7883 		sme_debug("vdev id %d peer not found "QDF_MAC_ADDR_FMT,
7884 			  vdev_id,
7885 			  QDF_MAC_ADDR_REF(peer_mac->bytes));
7886 		status = QDF_STATUS_E_FAILURE;
7887 		goto release_vdev_ref;
7888 	}
7889 
7890 	if (!sme_validate_peer_ampdu_cfg(peer_obj, cfg)) {
7891 		status = QDF_STATUS_E_INVAL;
7892 		goto release_peer_ref;
7893 	}
7894 	status = sme_set_peer_param(peer_mac->bytes,
7895 				    WMI_HOST_PEER_AMPDU,
7896 				    cfg,
7897 				    vdev_id);
7898 release_peer_ref:
7899 	wlan_objmgr_peer_release_ref(peer_obj, WLAN_LEGACY_SME_ID);
7900 release_vdev_ref:
7901 	wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID);
7902 	return qdf_status_to_os_return(status);
7903 }
7904 
sme_update_ht_config(mac_handle_t mac_handle,uint8_t vdev_id,uint16_t htCapab,int value)7905 int sme_update_ht_config(mac_handle_t mac_handle, uint8_t vdev_id,
7906 			 uint16_t htCapab, int value)
7907 {
7908 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
7909 	struct csr_roam_session *pSession = CSR_GET_SESSION(mac, vdev_id);
7910 	struct wlan_ht_config ht_cap_info;
7911 	struct wlan_objmgr_vdev *vdev;
7912 	struct vdev_mlme_obj *vdev_mlme;
7913 
7914 	if (!pSession) {
7915 		sme_err("pSession is NULL");
7916 		return -EIO;
7917 	}
7918 
7919 	if (QDF_STATUS_SUCCESS != wma_set_htconfig(vdev_id, htCapab, value)) {
7920 		sme_err("Failed to set ht capability in target");
7921 		return -EIO;
7922 	}
7923 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac->psoc, vdev_id,
7924 						    WLAN_LEGACY_SME_ID);
7925 	if (!vdev)
7926 		return -EIO;
7927 	vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev);
7928 	if (!vdev_mlme) {
7929 		wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID);
7930 		return -EIO;
7931 	}
7932 	ht_cap_info.caps = vdev_mlme->proto.ht_info.ht_caps;
7933 
7934 	switch (htCapab) {
7935 	case WNI_CFG_HT_CAP_INFO_ADVANCE_CODING:
7936 		ht_cap_info.ht_caps.adv_coding_cap = value;
7937 		break;
7938 	case WNI_CFG_HT_CAP_INFO_TX_STBC:
7939 		ht_cap_info.ht_caps.tx_stbc = value;
7940 		break;
7941 	case WNI_CFG_HT_CAP_INFO_RX_STBC:
7942 		ht_cap_info.ht_caps.rx_stbc = value;
7943 		break;
7944 	case WNI_CFG_HT_CAP_INFO_SHORT_GI_20MHZ:
7945 		value = value ? 1 : 0; /* HT SGI can be only 1 or 0 */
7946 		ht_cap_info.ht_caps.short_gi_20_mhz = value;
7947 		break;
7948 	case WNI_CFG_HT_CAP_INFO_SHORT_GI_40MHZ:
7949 		value = value ? 1 : 0; /* HT SGI can be only 1 or 0 */
7950 		ht_cap_info.ht_caps.short_gi_40_mhz = value;
7951 		break;
7952 	}
7953 	vdev_mlme->proto.ht_info.ht_caps = ht_cap_info.caps;
7954 	wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID);
7955 
7956 	csr_roam_update_config(mac, vdev_id, htCapab, value);
7957 	return 0;
7958 }
7959 
sme_set_addba_accept(mac_handle_t mac_handle,uint8_t session_id,int value)7960 int sme_set_addba_accept(mac_handle_t mac_handle, uint8_t session_id, int value)
7961 {
7962 	struct sme_addba_accept *addba_accept;
7963 	struct scheduler_msg msg = {0};
7964 	QDF_STATUS status;
7965 
7966 	addba_accept = qdf_mem_malloc(sizeof(*addba_accept));
7967 	if (!addba_accept)
7968 		return -EIO;
7969 
7970 	addba_accept->session_id = session_id;
7971 	addba_accept->addba_accept = value;
7972 	qdf_mem_zero(&msg, sizeof(msg));
7973 	msg.type = eWNI_SME_SET_ADDBA_ACCEPT;
7974 	msg.reserved = 0;
7975 	msg.bodyptr = addba_accept;
7976 	status = scheduler_post_message(QDF_MODULE_ID_SME,
7977 					QDF_MODULE_ID_PE,
7978 					QDF_MODULE_ID_PE, &msg);
7979 	if (status != QDF_STATUS_SUCCESS) {
7980 		sme_err("Not able to post addba reject");
7981 		qdf_mem_free(addba_accept);
7982 		return -EIO;
7983 	}
7984 	return 0;
7985 }
7986 
sme_set_ba_buff_size(mac_handle_t mac_handle,uint8_t session_id,uint16_t buff_size)7987 int sme_set_ba_buff_size(mac_handle_t mac_handle, uint8_t session_id,
7988 			 uint16_t buff_size)
7989 {
7990 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
7991 	if (!buff_size) {
7992 		sme_err("invalid buff size %d", buff_size);
7993 		return -EINVAL;
7994 	}
7995 	mac_ctx->usr_cfg_ba_buff_size = buff_size;
7996 	sme_debug("addba buff size is set to %d",
7997 			mac_ctx->usr_cfg_ba_buff_size);
7998 
7999 	return 0;
8000 }
8001 
8002 #define DEFAULT_BA_BUFF_SIZE 64
sme_send_addba_req(mac_handle_t mac_handle,uint8_t session_id,uint8_t tid,uint16_t buff_size)8003 int sme_send_addba_req(mac_handle_t mac_handle, uint8_t session_id, uint8_t tid,
8004 		       uint16_t buff_size)
8005 {
8006 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
8007 	uint16_t ba_buff = 0;
8008 	QDF_STATUS status;
8009 	struct scheduler_msg msg = {0};
8010 	struct send_add_ba_req *send_ba_req;
8011 
8012 	if (!cm_is_vdevid_connected(mac_ctx->pdev, session_id)) {
8013 		sme_err("STA not infra/connected state session_id: %d",
8014 			session_id);
8015 		return -EINVAL;
8016 	}
8017 
8018 	if (!CSR_IS_SESSION_VALID(mac_ctx, session_id)) {
8019 		sme_err("CSR session is invalid");
8020 		return -EINVAL;
8021 	}
8022 	send_ba_req = qdf_mem_malloc(sizeof(*send_ba_req));
8023 	if (!send_ba_req)
8024 		return -EIO;
8025 
8026 	wlan_mlme_get_bssid_vdev_id(mac_ctx->pdev, session_id,
8027 				    (struct qdf_mac_addr *)&send_ba_req->mac_addr);
8028 	ba_buff = buff_size;
8029 	if (!buff_size) {
8030 		if (mac_ctx->usr_cfg_ba_buff_size)
8031 			ba_buff = mac_ctx->usr_cfg_ba_buff_size;
8032 		else
8033 			ba_buff = DEFAULT_BA_BUFF_SIZE;
8034 	}
8035 	send_ba_req->param.vdev_id = session_id;
8036 	send_ba_req->param.tidno = tid;
8037 	send_ba_req->param.buffersize = ba_buff;
8038 	msg.type = WMA_SEND_ADDBA_REQ;
8039 	msg.bodyptr = send_ba_req;
8040 	status = scheduler_post_message(QDF_MODULE_ID_SME,
8041 					QDF_MODULE_ID_WMA,
8042 					QDF_MODULE_ID_WMA, &msg);
8043 	if (QDF_STATUS_SUCCESS != status) {
8044 		qdf_mem_free(send_ba_req);
8045 		return -EIO;
8046 	}
8047 	sme_debug("ADDBA_REQ sent to FW: tid %d buff_size %d", tid, ba_buff);
8048 
8049 	return 0;
8050 }
8051 
sme_set_no_ack_policy(mac_handle_t mac_handle,uint8_t session_id,uint8_t val,uint8_t ac)8052 int sme_set_no_ack_policy(mac_handle_t mac_handle, uint8_t session_id,
8053 			  uint8_t val, uint8_t ac)
8054 {
8055 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
8056 	uint8_t i, set_val;
8057 	struct scheduler_msg msg = {0};
8058 	QDF_STATUS status;
8059 
8060 	if (ac > QCA_WLAN_AC_ALL) {
8061 		sme_err("invalid ac val %d", ac);
8062 		return -EINVAL;
8063 	}
8064 	if (val)
8065 		set_val = 1;
8066 	else
8067 		set_val = 0;
8068 	if (ac == QCA_WLAN_AC_ALL) {
8069 		for (i = 0; i < ac; i++)
8070 			mac_ctx->no_ack_policy_cfg[i] = set_val;
8071 	} else {
8072 		mac_ctx->no_ack_policy_cfg[ac] = set_val;
8073 	}
8074 	sme_debug("no ack is set to %d for ac %d", set_val, ac);
8075 	qdf_mem_zero(&msg, sizeof(msg));
8076 	msg.type = eWNI_SME_UPDATE_EDCA_PROFILE;
8077 	msg.reserved = 0;
8078 	msg.bodyval = session_id;
8079 	status = scheduler_post_message(QDF_MODULE_ID_SME,
8080 					QDF_MODULE_ID_PE,
8081 					QDF_MODULE_ID_PE, &msg);
8082 	if (status != QDF_STATUS_SUCCESS) {
8083 		sme_err("Not able to post update edca profile");
8084 		return -EIO;
8085 	}
8086 
8087 	return 0;
8088 }
8089 
sme_set_auto_rate_he_ltf(mac_handle_t mac_handle,uint8_t session_id,uint8_t cfg_val)8090 int sme_set_auto_rate_he_ltf(mac_handle_t mac_handle, uint8_t session_id,
8091 			     uint8_t cfg_val)
8092 {
8093 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
8094 	uint32_t set_val;
8095 	uint32_t bit_mask = 0;
8096 	int status;
8097 
8098 	if (cfg_val > QCA_WLAN_HE_LTF_4X) {
8099 		sme_err("invalid HE LTF cfg %d", cfg_val);
8100 		return -EINVAL;
8101 	}
8102 
8103 	/*set the corresponding HE LTF cfg BIT*/
8104 	if (cfg_val == QCA_WLAN_HE_LTF_AUTO)
8105 		bit_mask = HE_LTF_ALL;
8106 	else
8107 		bit_mask = (1 << (cfg_val - 1));
8108 
8109 	set_val = mac_ctx->he_sgi_ltf_cfg_bit_mask;
8110 
8111 	SET_AUTO_RATE_HE_LTF_VAL(set_val, bit_mask);
8112 
8113 	mac_ctx->he_sgi_ltf_cfg_bit_mask = set_val;
8114 	status = wma_cli_set_command(session_id,
8115 			wmi_vdev_param_autorate_misc_cfg,
8116 			set_val, VDEV_CMD);
8117 	if (status) {
8118 		sme_err("failed to set he_ltf_sgi");
8119 		return status;
8120 	}
8121 
8122 	sme_debug("HE SGI_LTF is set to 0x%08X",
8123 			mac_ctx->he_sgi_ltf_cfg_bit_mask);
8124 
8125 	return 0;
8126 }
8127 
sme_set_auto_rate_he_sgi(mac_handle_t mac_handle,uint8_t session_id,uint8_t cfg_val)8128 int sme_set_auto_rate_he_sgi(mac_handle_t mac_handle, uint8_t session_id,
8129 			     uint8_t cfg_val)
8130 {
8131 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
8132 	uint32_t set_val;
8133 	uint32_t sgi_bit_mask = 0;
8134 	int status;
8135 
8136 	if ((cfg_val > AUTO_RATE_GI_3200NS) ||
8137 			(cfg_val < AUTO_RATE_GI_400NS)) {
8138 		sme_err("invalid auto rate GI cfg %d", cfg_val);
8139 		return -EINVAL;
8140 	}
8141 
8142 	sgi_bit_mask = (1 << cfg_val);
8143 
8144 	set_val = mac_ctx->he_sgi_ltf_cfg_bit_mask;
8145 	SET_AUTO_RATE_SGI_VAL(set_val, sgi_bit_mask);
8146 
8147 	mac_ctx->he_sgi_ltf_cfg_bit_mask = set_val;
8148 	status = wma_cli_set_command(session_id,
8149 				     wmi_vdev_param_autorate_misc_cfg,
8150 				     set_val, VDEV_CMD);
8151 	if (status) {
8152 		sme_err("failed to set he_ltf_sgi");
8153 		return status;
8154 	}
8155 
8156 	sme_debug("auto rate HE SGI_LTF is set to 0x%08X",
8157 			mac_ctx->he_sgi_ltf_cfg_bit_mask);
8158 
8159 	return 0;
8160 }
8161 
sme_set_auto_rate_ldpc(mac_handle_t mac_handle,uint8_t session_id,uint8_t ldpc_disable)8162 int sme_set_auto_rate_ldpc(mac_handle_t mac_handle, uint8_t session_id,
8163 			   uint8_t ldpc_disable)
8164 {
8165 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
8166 	uint32_t set_val;
8167 	int status;
8168 
8169 	set_val = mac_ctx->he_sgi_ltf_cfg_bit_mask;
8170 
8171 	set_val |= (ldpc_disable << AUTO_RATE_LDPC_DIS_BIT);
8172 
8173 	status = wma_cli_set_command(session_id,
8174 				     wmi_vdev_param_autorate_misc_cfg,
8175 				     set_val, VDEV_CMD);
8176 	if (status) {
8177 		sme_err("failed to set auto rate LDPC cfg");
8178 		return status;
8179 	}
8180 
8181 	sme_debug("auto rate misc cfg set to 0x%08X", set_val);
8182 
8183 	return 0;
8184 }
8185 
8186 #define HT20_SHORT_GI_MCS7_RATE 722
8187 /*
8188  * sme_send_rate_update_ind() -
8189  *  API to Update rate
8190  *
8191  * mac_handle - The handle returned by mac_open
8192  * rateUpdateParams - Pointer to rate update params
8193  * Return QDF_STATUS
8194  */
sme_send_rate_update_ind(mac_handle_t mac_handle,tSirRateUpdateInd * rateUpdateParams)8195 QDF_STATUS sme_send_rate_update_ind(mac_handle_t mac_handle,
8196 				    tSirRateUpdateInd *rateUpdateParams)
8197 {
8198 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
8199 	QDF_STATUS status;
8200 	struct scheduler_msg msg = {0};
8201 	tSirRateUpdateInd *rate_upd = qdf_mem_malloc(sizeof(tSirRateUpdateInd));
8202 
8203 	if (!rate_upd)
8204 		return QDF_STATUS_E_FAILURE;
8205 
8206 	*rate_upd = *rateUpdateParams;
8207 
8208 	if (rate_upd->mcastDataRate24GHz == HT20_SHORT_GI_MCS7_RATE)
8209 		rate_upd->mcastDataRate24GHzTxFlag =
8210 			TX_RATE_HT20 | TX_RATE_SGI;
8211 	else if (rate_upd->reliableMcastDataRate ==
8212 		 HT20_SHORT_GI_MCS7_RATE)
8213 		rate_upd->reliableMcastDataRateTxFlag =
8214 			TX_RATE_HT20 | TX_RATE_SGI;
8215 
8216 	status = sme_acquire_global_lock(&mac->sme);
8217 	if (QDF_IS_STATUS_ERROR(status)) {
8218 		qdf_mem_free(rate_upd);
8219 		return status;
8220 	}
8221 
8222 	msg.type = WMA_RATE_UPDATE_IND;
8223 	msg.bodyptr = rate_upd;
8224 	MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG,
8225 			 NO_SESSION, msg.type));
8226 
8227 	status = scheduler_post_message(QDF_MODULE_ID_SME, QDF_MODULE_ID_WMA,
8228 					QDF_MODULE_ID_WMA, &msg);
8229 	if (QDF_IS_STATUS_ERROR(status)) {
8230 		sme_err("Not able to post WMA_RATE_UPDATE_IND to WMA!");
8231 		qdf_mem_free(rate_upd);
8232 		status = QDF_STATUS_E_FAILURE;
8233 	}
8234 
8235 	sme_release_global_lock(&mac->sme);
8236 
8237 	return status;
8238 }
8239 
8240 /**
8241  * sme_update_access_policy_vendor_ie() - update vendor ie and access policy.
8242  * @mac_handle: Pointer to the mac context
8243  * @vdev_id: vdev_id
8244  * @vendor_ie: vendor ie
8245  * @access_policy: vendor ie access policy
8246  *
8247  * This function updates the vendor ie and access policy to lim.
8248  *
8249  * Return: success or failure.
8250  */
sme_update_access_policy_vendor_ie(mac_handle_t mac_handle,uint8_t vdev_id,uint8_t * vendor_ie,int access_policy)8251 QDF_STATUS sme_update_access_policy_vendor_ie(mac_handle_t mac_handle,
8252 					      uint8_t vdev_id,
8253 					      uint8_t *vendor_ie,
8254 					      int access_policy)
8255 {
8256 	struct sme_update_access_policy_vendor_ie *msg;
8257 	uint16_t msg_len;
8258 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
8259 
8260 	msg_len  = sizeof(*msg);
8261 
8262 	msg = qdf_mem_malloc(msg_len);
8263 	if (!msg) {
8264 		return QDF_STATUS_E_NOMEM;
8265 	}
8266 
8267 	msg->msg_type = (uint16_t)eWNI_SME_UPDATE_ACCESS_POLICY_VENDOR_IE;
8268 	msg->length = (uint16_t)msg_len;
8269 
8270 	qdf_mem_copy(&msg->ie[0], vendor_ie, sizeof(msg->ie));
8271 
8272 	msg->vdev_id = vdev_id;
8273 	msg->access_policy = access_policy;
8274 
8275 	sme_debug("vdev_id: %hu, access_policy: %d", vdev_id, access_policy);
8276 	status = umac_send_mb_message_to_mac(msg);
8277 
8278 	return status;
8279 }
8280 
8281 /**
8282  * sme_update_sta_inactivity_timeout(): Update sta_inactivity_timeout to FW
8283  * @mac_handle: Handle returned by mac_open
8284  * @session_id: Session ID on which sta_inactivity_timeout needs
8285  * to be updated to FW
8286  * @sta_inactivity_timeout: sta inactivity timeout.
8287  *
8288  * If a station does not send anything in sta_inactivity_timeout seconds, an
8289  * empty data frame is sent to it in order to verify whether it is
8290  * still in range. If this frame is not ACKed, the station will be
8291  * disassociated and then deauthenticated.
8292  *
8293  * Return: QDF_STATUS_SUCCESS or non-zero on failure.
8294  */
sme_update_sta_inactivity_timeout(mac_handle_t mac_handle,struct sme_sta_inactivity_timeout * sta_inactivity_timer)8295 QDF_STATUS sme_update_sta_inactivity_timeout(mac_handle_t mac_handle,
8296 		 struct sme_sta_inactivity_timeout  *sta_inactivity_timer)
8297 {
8298 	struct sme_sta_inactivity_timeout *inactivity_time;
8299 	void *wma_handle;
8300 
8301 	wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
8302 	inactivity_time = qdf_mem_malloc(sizeof(*inactivity_time));
8303 	if (!inactivity_time)
8304 		return QDF_STATUS_E_FAILURE;
8305 
8306 	sme_debug("sta_inactivity_timeout: %d",
8307 		  sta_inactivity_timer->sta_inactivity_timeout);
8308 	inactivity_time->session_id = sta_inactivity_timer->session_id;
8309 	inactivity_time->sta_inactivity_timeout =
8310 		sta_inactivity_timer->sta_inactivity_timeout;
8311 
8312 	wma_update_sta_inactivity_timeout(wma_handle, inactivity_time);
8313 	qdf_mem_free(inactivity_time);
8314 	return QDF_STATUS_SUCCESS;
8315 }
8316 
sme_get_reg_info(mac_handle_t mac_handle,uint32_t chan_freq,uint32_t * regInfo1,uint32_t * regInfo2)8317 QDF_STATUS sme_get_reg_info(mac_handle_t mac_handle, uint32_t chan_freq,
8318 			    uint32_t *regInfo1, uint32_t *regInfo2)
8319 {
8320 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
8321 	QDF_STATUS status = QDF_STATUS_SUCCESS;
8322 	uint8_t i;
8323 	bool found = false;
8324 
8325 	*regInfo1 = 0;
8326 	*regInfo2 = 0;
8327 
8328 	for (i = 0; i < CFG_VALID_CHANNEL_LIST_LEN; i++) {
8329 		if (mac->scan.defaultPowerTable[i].center_freq == chan_freq) {
8330 			SME_SET_CHANNEL_REG_POWER(*regInfo1,
8331 				mac->scan.defaultPowerTable[i].tx_power);
8332 
8333 			SME_SET_CHANNEL_MAX_TX_POWER(*regInfo2,
8334 				mac->scan.defaultPowerTable[i].tx_power);
8335 			found = true;
8336 			break;
8337 		}
8338 	}
8339 	if (!found)
8340 		status = QDF_STATUS_E_FAILURE;
8341 
8342 	return status;
8343 }
8344 
8345 #ifdef FEATURE_WLAN_AUTO_SHUTDOWN
sme_set_auto_shutdown_cb(mac_handle_t mac_handle,void (* callback_fn)(void))8346 QDF_STATUS sme_set_auto_shutdown_cb(mac_handle_t mac_handle,
8347 				    void (*callback_fn)(void))
8348 {
8349 	QDF_STATUS status;
8350 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
8351 
8352 	sme_info("Plug in Auto shutdown event callback");
8353 
8354 	status = sme_acquire_global_lock(&mac->sme);
8355 	if (QDF_STATUS_SUCCESS == status) {
8356 		if (callback_fn)
8357 			mac->sme.auto_shutdown_cb = callback_fn;
8358 		sme_release_global_lock(&mac->sme);
8359 	}
8360 
8361 	return status;
8362 }
8363 
8364 /*
8365  * sme_set_auto_shutdown_timer() -
8366  *  API to set auto shutdown timer value in FW.
8367  *
8368  * mac_handle - The handle returned by mac_open
8369  * timer_val - The auto shutdown timer value to be set
8370  * Return Configuration message posting status, SUCCESS or Fail
8371  */
sme_set_auto_shutdown_timer(mac_handle_t mac_handle,uint32_t timer_val)8372 QDF_STATUS sme_set_auto_shutdown_timer(mac_handle_t mac_handle,
8373 				       uint32_t timer_val)
8374 {
8375 	QDF_STATUS status = QDF_STATUS_SUCCESS;
8376 	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
8377 	struct auto_shutdown_cmd *auto_sh_cmd;
8378 	struct scheduler_msg message = {0};
8379 
8380 	auto_sh_cmd = qdf_mem_malloc(sizeof(*auto_sh_cmd));
8381 	if (!auto_sh_cmd)
8382 		return QDF_STATUS_E_NOMEM;
8383 
8384 
8385 	auto_sh_cmd->timer_val = timer_val;
8386 
8387 	/* serialize the req through MC thread */
8388 	message.bodyptr = auto_sh_cmd;
8389 	message.type = WMA_SET_AUTO_SHUTDOWN_TIMER_REQ;
8390 	qdf_status = scheduler_post_message(QDF_MODULE_ID_SME,
8391 					    QDF_MODULE_ID_WMA,
8392 					    QDF_MODULE_ID_WMA,
8393 					    &message);
8394 	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
8395 		sme_err("Post Auto shutdown MSG fail");
8396 		qdf_mem_free(auto_sh_cmd);
8397 		return QDF_STATUS_E_FAILURE;
8398 	}
8399 
8400 	return status;
8401 }
8402 #endif
8403 
8404 #ifdef FEATURE_WLAN_CH_AVOID
8405 /*
8406  * sme_ch_avoid_update_req() -
8407  *   API to request channel avoidance update from FW.
8408  *
8409  * mac_handle - The handle returned by mac_open
8410  * update_type - The update_type parameter of this request call
8411  * Return Configuration message posting status, SUCCESS or Fail
8412  */
sme_ch_avoid_update_req(mac_handle_t mac_handle)8413 QDF_STATUS sme_ch_avoid_update_req(mac_handle_t mac_handle)
8414 {
8415 	QDF_STATUS status = QDF_STATUS_SUCCESS;
8416 	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
8417 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
8418 	tSirChAvoidUpdateReq *cauReq;
8419 	struct scheduler_msg message = {0};
8420 
8421 	status = sme_acquire_global_lock(&mac->sme);
8422 	if (QDF_STATUS_SUCCESS == status) {
8423 		cauReq = qdf_mem_malloc(sizeof(tSirChAvoidUpdateReq));
8424 		if (!cauReq) {
8425 			sme_release_global_lock(&mac->sme);
8426 			return QDF_STATUS_E_NOMEM;
8427 		}
8428 
8429 		cauReq->reserved_param = 0;
8430 
8431 		/* serialize the req through MC thread */
8432 		message.bodyptr = cauReq;
8433 		message.type = WMA_CH_AVOID_UPDATE_REQ;
8434 		qdf_status = scheduler_post_message(QDF_MODULE_ID_SME,
8435 						    QDF_MODULE_ID_WMA,
8436 						    QDF_MODULE_ID_WMA,
8437 						    &message);
8438 		if (QDF_IS_STATUS_ERROR(qdf_status)) {
8439 			sme_err("Post Ch Avoid Update MSG fail");
8440 			qdf_mem_free(cauReq);
8441 			sme_release_global_lock(&mac->sme);
8442 			return QDF_STATUS_E_FAILURE;
8443 		}
8444 		sme_debug("Posted Ch Avoid Update MSG");
8445 		sme_release_global_lock(&mac->sme);
8446 	}
8447 
8448 	return status;
8449 }
8450 #endif
8451 
8452 /**
8453  * sme_set_miracast() - Function to set miracast value to UMAC
8454  * @mac_handle:                Handle returned by macOpen
8455  * @filter_type:        0-Disabled, 1-Source, 2-sink
8456  *
8457  * This function passes down the value of miracast set by
8458  * framework to UMAC
8459  *
8460  * Return: Configuration message posting status, SUCCESS or Fail
8461  *
8462  */
sme_set_miracast(mac_handle_t mac_handle,uint8_t filter_type)8463 QDF_STATUS sme_set_miracast(mac_handle_t mac_handle, uint8_t filter_type)
8464 {
8465 	struct scheduler_msg msg = {0};
8466 	uint32_t *val;
8467 	struct mac_context *mac_ptr = MAC_CONTEXT(mac_handle);
8468 
8469 	if (!mac_ptr) {
8470 		sme_err("Invalid pointer");
8471 		return QDF_STATUS_E_INVAL;
8472 	}
8473 
8474 	val = qdf_mem_malloc(sizeof(*val));
8475 	if (!val)
8476 		return QDF_STATUS_E_NOMEM;
8477 
8478 	*val = filter_type;
8479 
8480 	msg.type = SIR_HAL_SET_MIRACAST;
8481 	msg.reserved = 0;
8482 	msg.bodyptr = val;
8483 
8484 	if (!QDF_IS_STATUS_SUCCESS(
8485 				scheduler_post_message(QDF_MODULE_ID_SME,
8486 						       QDF_MODULE_ID_WMA,
8487 						       QDF_MODULE_ID_WMA,
8488 						       &msg))) {
8489 		sme_err("Not able to post WDA_SET_MAS_ENABLE_DISABLE to WMA!");
8490 		qdf_mem_free(val);
8491 		return QDF_STATUS_E_FAILURE;
8492 	}
8493 
8494 	mac_ptr->sme.miracast_value = filter_type;
8495 	return QDF_STATUS_SUCCESS;
8496 }
8497 
8498 /**
8499  * sme_set_mas() - Function to set MAS value to UMAC
8500  * @val:	1-Enable, 0-Disable
8501  *
8502  * This function passes down the value of MAS to the UMAC. A
8503  * value of 1 will enable MAS and a value of 0 will disable MAS
8504  *
8505  * Return: Configuration message posting status, SUCCESS or Fail
8506  *
8507  */
sme_set_mas(uint32_t val)8508 QDF_STATUS sme_set_mas(uint32_t val)
8509 {
8510 	struct scheduler_msg msg = {0};
8511 	uint32_t *ptr_val;
8512 
8513 	ptr_val = qdf_mem_malloc(sizeof(*ptr_val));
8514 	if (!ptr_val)
8515 		return QDF_STATUS_E_NOMEM;
8516 
8517 	*ptr_val = val;
8518 
8519 	msg.type = SIR_HAL_SET_MAS;
8520 	msg.reserved = 0;
8521 	msg.bodyptr = ptr_val;
8522 
8523 	if (!QDF_IS_STATUS_SUCCESS(
8524 				scheduler_post_message(QDF_MODULE_ID_SME,
8525 						       QDF_MODULE_ID_WMA,
8526 						       QDF_MODULE_ID_WMA,
8527 						       &msg))) {
8528 		sme_err("Not able to post WDA_SET_MAS_ENABLE_DISABLE to WMA!");
8529 		qdf_mem_free(ptr_val);
8530 		return QDF_STATUS_E_FAILURE;
8531 	}
8532 	return QDF_STATUS_SUCCESS;
8533 }
8534 
sme_send_channel_change_req(mac_handle_t mac_handle,struct channel_change_req * req)8535 QDF_STATUS sme_send_channel_change_req(mac_handle_t mac_handle,
8536 				      struct channel_change_req *req)
8537 {
8538 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
8539 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
8540 
8541 	status = sme_acquire_global_lock(&mac->sme);
8542 	if (QDF_IS_STATUS_SUCCESS(status)) {
8543 		status = csr_send_channel_change_req(mac, req);
8544 		sme_release_global_lock(&mac->sme);
8545 	}
8546 	return status;
8547 }
8548 
8549 /*
8550  * sme_process_channel_change_resp() -
8551  * API to Indicate Channel change response message to SAP.
8552  *
8553  * Return QDF_STATUS
8554  */
sme_process_channel_change_resp(struct mac_context * mac,uint16_t msg_type,void * msg_buf)8555 static QDF_STATUS sme_process_channel_change_resp(struct mac_context *mac,
8556 					   uint16_t msg_type, void *msg_buf)
8557 {
8558 	QDF_STATUS status = QDF_STATUS_SUCCESS;
8559 	struct csr_roam_info *roam_info;
8560 	eCsrRoamResult roamResult;
8561 	uint8_t session_id;
8562 
8563 	roam_info = qdf_mem_malloc(sizeof(*roam_info));
8564 	if (!roam_info)
8565 		return QDF_STATUS_E_NOMEM;
8566 
8567 	roam_info->channelChangeRespEvent =
8568 		(struct sSirChanChangeResponse *)msg_buf;
8569 
8570 	session_id = roam_info->channelChangeRespEvent->sessionId;
8571 
8572 	if (roam_info->channelChangeRespEvent->channelChangeStatus ==
8573 	    QDF_STATUS_SUCCESS) {
8574 		sme_debug("sapdfs: Received success for vdev %d", session_id);
8575 		roamResult = eCSR_ROAM_RESULT_CHANNEL_CHANGE_SUCCESS;
8576 	} else {
8577 		sme_debug("sapdfs: Received failure for vdev %d", session_id);
8578 		roamResult = eCSR_ROAM_RESULT_CHANNEL_CHANGE_FAILURE;
8579 	}
8580 
8581 	csr_roam_call_callback(mac, session_id, roam_info,
8582 			       eCSR_ROAM_SET_CHANNEL_RSP, roamResult);
8583 
8584 	qdf_mem_free(roam_info);
8585 
8586 	return status;
8587 }
8588 
8589 /*
8590  * sme_roam_start_beacon_req() -
8591  * API to Indicate LIM to start Beacon Tx after SAP CAC Wait is completed.
8592  *
8593  * mac_handle - The handle returned by mac_open
8594  * sessionId - session ID
8595  * dfsCacWaitStatus - CAC WAIT status flag
8596  * Return QDF_STATUS
8597  */
sme_roam_start_beacon_req(mac_handle_t mac_handle,struct qdf_mac_addr bssid,uint8_t dfsCacWaitStatus)8598 QDF_STATUS sme_roam_start_beacon_req(mac_handle_t mac_handle,
8599 				     struct qdf_mac_addr bssid,
8600 				     uint8_t dfsCacWaitStatus)
8601 {
8602 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
8603 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
8604 
8605 	status = sme_acquire_global_lock(&mac->sme);
8606 
8607 	if (QDF_IS_STATUS_SUCCESS(status)) {
8608 		status = csr_roam_start_beacon_req(mac, bssid,
8609 						dfsCacWaitStatus);
8610 		sme_release_global_lock(&mac->sme);
8611 	}
8612 	return status;
8613 }
8614 
sme_csa_restart(struct mac_context * mac_ctx,uint8_t session_id)8615 QDF_STATUS sme_csa_restart(struct mac_context *mac_ctx, uint8_t session_id)
8616 {
8617 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
8618 
8619 	status = sme_acquire_global_lock(&mac_ctx->sme);
8620 	if (QDF_IS_STATUS_SUCCESS(status)) {
8621 		status = csr_csa_restart(mac_ctx, session_id);
8622 		sme_release_global_lock(&mac_ctx->sme);
8623 	}
8624 
8625 	return status;
8626 }
8627 
sme_roam_csa_ie_request(mac_handle_t mac_handle,struct qdf_mac_addr bssid,uint32_t target_chan_freq,uint8_t csaIeReqd,struct ch_params * ch_params,uint32_t new_cac_ms)8628 QDF_STATUS sme_roam_csa_ie_request(mac_handle_t mac_handle,
8629 				   struct qdf_mac_addr bssid,
8630 				   uint32_t target_chan_freq, uint8_t csaIeReqd,
8631 				   struct ch_params *ch_params,
8632 				   uint32_t new_cac_ms)
8633 {
8634 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
8635 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
8636 
8637 	status = sme_acquire_global_lock(&mac->sme);
8638 	if (QDF_IS_STATUS_SUCCESS(status)) {
8639 		status = csr_roam_send_chan_sw_ie_request(mac, bssid,
8640 							  target_chan_freq,
8641 							  csaIeReqd, ch_params,
8642 							  new_cac_ms);
8643 		sme_release_global_lock(&mac->sme);
8644 	}
8645 	return status;
8646 }
8647 
8648 /*
8649  * sme_init_thermal_info() -
8650  * SME API to initialize the thermal mitigation parameters
8651  *
8652  * mac_handle
8653  * thermalParam : thermal mitigation parameters
8654  * Return QDF_STATUS
8655  */
sme_init_thermal_info(mac_handle_t mac_handle)8656 QDF_STATUS sme_init_thermal_info(mac_handle_t mac_handle)
8657 {
8658 	t_thermal_mgmt *pWmaParam;
8659 	struct scheduler_msg msg = {0};
8660 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
8661 	struct wlan_fwol_thermal_temp thermal_temp = {0};
8662 	QDF_STATUS status;
8663 
8664 	pWmaParam = qdf_mem_malloc(sizeof(t_thermal_mgmt));
8665 	if (!pWmaParam)
8666 		return QDF_STATUS_E_NOMEM;
8667 
8668 	status = ucfg_fwol_get_thermal_temp(mac->psoc, &thermal_temp);
8669 	if (QDF_IS_STATUS_ERROR(status))
8670 		return qdf_status_to_os_return(status);
8671 
8672 	pWmaParam->thermalMgmtEnabled = thermal_temp.thermal_mitigation_enable;
8673 	pWmaParam->throttlePeriod = thermal_temp.throttle_period;
8674 
8675 	pWmaParam->throttle_duty_cycle_tbl[0] =
8676 				thermal_temp.throttle_dutycycle_level[0];
8677 	pWmaParam->throttle_duty_cycle_tbl[1] =
8678 				thermal_temp.throttle_dutycycle_level[1];
8679 	pWmaParam->throttle_duty_cycle_tbl[2] =
8680 				thermal_temp.throttle_dutycycle_level[2];
8681 	pWmaParam->throttle_duty_cycle_tbl[3] =
8682 				thermal_temp.throttle_dutycycle_level[3];
8683 	pWmaParam->throttle_duty_cycle_tbl[4] =
8684 				thermal_temp.throttle_dutycycle_level[4];
8685 	pWmaParam->throttle_duty_cycle_tbl[5] =
8686 				thermal_temp.throttle_dutycycle_level[5];
8687 
8688 	pWmaParam->thermalLevels[0].minTempThreshold =
8689 				thermal_temp.thermal_temp_min_level[0];
8690 	pWmaParam->thermalLevels[0].maxTempThreshold =
8691 				thermal_temp.thermal_temp_max_level[0];
8692 	pWmaParam->thermalLevels[1].minTempThreshold =
8693 				thermal_temp.thermal_temp_min_level[1];
8694 	pWmaParam->thermalLevels[1].maxTempThreshold =
8695 				thermal_temp.thermal_temp_max_level[1];
8696 	pWmaParam->thermalLevels[2].minTempThreshold =
8697 				thermal_temp.thermal_temp_min_level[2];
8698 	pWmaParam->thermalLevels[2].maxTempThreshold =
8699 				thermal_temp.thermal_temp_max_level[2];
8700 	pWmaParam->thermalLevels[3].minTempThreshold =
8701 				thermal_temp.thermal_temp_min_level[3];
8702 	pWmaParam->thermalLevels[3].maxTempThreshold =
8703 				thermal_temp.thermal_temp_max_level[3];
8704 	pWmaParam->thermalLevels[4].minTempThreshold =
8705 				thermal_temp.thermal_temp_min_level[4];
8706 	pWmaParam->thermalLevels[4].maxTempThreshold =
8707 				thermal_temp.thermal_temp_max_level[4];
8708 	pWmaParam->thermalLevels[5].minTempThreshold =
8709 				thermal_temp.thermal_temp_min_level[5];
8710 	pWmaParam->thermalLevels[5].maxTempThreshold =
8711 				thermal_temp.thermal_temp_max_level[5];
8712 	pWmaParam->thermal_action = thermal_temp.thermal_action;
8713 	if (QDF_STATUS_SUCCESS == sme_acquire_global_lock(&mac->sme)) {
8714 		msg.type = WMA_INIT_THERMAL_INFO_CMD;
8715 		msg.bodyptr = pWmaParam;
8716 
8717 		if (!QDF_IS_STATUS_SUCCESS
8718 			    (scheduler_post_message(QDF_MODULE_ID_SME,
8719 						    QDF_MODULE_ID_WMA,
8720 						    QDF_MODULE_ID_WMA,
8721 						    &msg))) {
8722 			sme_err("Not able to post WMA_SET_THERMAL_INFO_CMD to WMA!");
8723 			qdf_mem_free(pWmaParam);
8724 			sme_release_global_lock(&mac->sme);
8725 			return QDF_STATUS_E_FAILURE;
8726 		}
8727 		sme_release_global_lock(&mac->sme);
8728 		return QDF_STATUS_SUCCESS;
8729 	}
8730 	qdf_mem_free(pWmaParam);
8731 	return QDF_STATUS_E_FAILURE;
8732 }
8733 
8734 /**
8735  * sme_add_set_thermal_level_callback() - Plug in set thermal level callback
8736  * @mac_handle:	Handle returned by macOpen
8737  * @callback:	sme_set_thermal_level_callback
8738  *
8739  * Plug in set thermal level callback
8740  *
8741  * Return: none
8742  */
sme_add_set_thermal_level_callback(mac_handle_t mac_handle,sme_set_thermal_level_callback callback)8743 void sme_add_set_thermal_level_callback(mac_handle_t mac_handle,
8744 		sme_set_thermal_level_callback callback)
8745 {
8746 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
8747 
8748 	mac->sme.set_thermal_level_cb = callback;
8749 }
8750 
8751 /**
8752  * sme_set_thermal_level() - SME API to set the thermal mitigation level
8753  * @mac_handle: Opaque handle to the global MAC context
8754  * @level:       Thermal mitigation level
8755  *
8756  * Return: QDF_STATUS
8757  */
sme_set_thermal_level(mac_handle_t mac_handle,uint8_t level)8758 QDF_STATUS sme_set_thermal_level(mac_handle_t mac_handle, uint8_t level)
8759 {
8760 	struct scheduler_msg msg = {0};
8761 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
8762 	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
8763 
8764 	if (QDF_STATUS_SUCCESS == sme_acquire_global_lock(&mac->sme)) {
8765 		qdf_mem_zero(&msg, sizeof(msg));
8766 		msg.type = WMA_SET_THERMAL_LEVEL;
8767 		msg.bodyval = level;
8768 
8769 		qdf_status =  scheduler_post_message(QDF_MODULE_ID_SME,
8770 						     QDF_MODULE_ID_WMA,
8771 						     QDF_MODULE_ID_WMA, &msg);
8772 		if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
8773 			sme_err("Not able to post WMA_SET_THERMAL_LEVEL to WMA!");
8774 			sme_release_global_lock(&mac->sme);
8775 			return QDF_STATUS_E_FAILURE;
8776 		}
8777 		sme_release_global_lock(&mac->sme);
8778 		return QDF_STATUS_SUCCESS;
8779 	}
8780 	return QDF_STATUS_E_FAILURE;
8781 }
8782 
8783 /*
8784  * sme_txpower_limit() -
8785  * SME API to set txpower limits
8786  *
8787  * mac_handle
8788  * psmetx : power limits for 2g/5g
8789  * Return QDF_STATUS
8790  */
sme_txpower_limit(mac_handle_t mac_handle,struct tx_power_limit * psmetx)8791 QDF_STATUS sme_txpower_limit(mac_handle_t mac_handle,
8792 			     struct tx_power_limit *psmetx)
8793 {
8794 	QDF_STATUS status;
8795 	struct scheduler_msg message = {0};
8796 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
8797 	struct tx_power_limit *tx_power_limit;
8798 
8799 	tx_power_limit = qdf_mem_malloc(sizeof(*tx_power_limit));
8800 	if (!tx_power_limit)
8801 		return QDF_STATUS_E_FAILURE;
8802 
8803 	*tx_power_limit = *psmetx;
8804 
8805 	status = sme_acquire_global_lock(&mac->sme);
8806 	if (QDF_IS_STATUS_ERROR(status)) {
8807 		qdf_mem_free(tx_power_limit);
8808 		return status;
8809 	}
8810 
8811 	message.type = WMA_TX_POWER_LIMIT;
8812 	message.bodyptr = tx_power_limit;
8813 	status = scheduler_post_message(QDF_MODULE_ID_SME, QDF_MODULE_ID_WMA,
8814 					QDF_MODULE_ID_WMA, &message);
8815 	if (QDF_IS_STATUS_ERROR(status)) {
8816 		sme_err("not able to post WMA_TX_POWER_LIMIT");
8817 		status = QDF_STATUS_E_FAILURE;
8818 		qdf_mem_free(tx_power_limit);
8819 	}
8820 
8821 	sme_release_global_lock(&mac->sme);
8822 
8823 	return status;
8824 }
8825 
sme_update_connect_debug(mac_handle_t mac_handle,uint32_t set_value)8826 QDF_STATUS sme_update_connect_debug(mac_handle_t mac_handle, uint32_t set_value)
8827 {
8828 	QDF_STATUS status = QDF_STATUS_SUCCESS;
8829 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
8830 
8831 	mac->mlme_cfg->gen.debug_packet_log = set_value;
8832 	return status;
8833 }
8834 
8835 /*
8836  * sme_ap_disable_intra_bss_fwd() -
8837  * SME will send message to WMA to set Intra BSS in txrx
8838  *
8839  * mac_handle - The handle returned by mac_open
8840  * sessionId - session id ( vdev id)
8841  * disablefwd - bool value that indicate disable intrabss fwd disable
8842  * Return QDF_STATUS
8843  */
sme_ap_disable_intra_bss_fwd(mac_handle_t mac_handle,uint8_t sessionId,bool disablefwd)8844 QDF_STATUS sme_ap_disable_intra_bss_fwd(mac_handle_t mac_handle,
8845 					uint8_t sessionId,
8846 					bool disablefwd)
8847 {
8848 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
8849 	int status = QDF_STATUS_SUCCESS;
8850 	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
8851 	struct scheduler_msg message = {0};
8852 	tpDisableIntraBssFwd pSapDisableIntraFwd = NULL;
8853 
8854 	/* Prepare the request to send to SME. */
8855 	pSapDisableIntraFwd = qdf_mem_malloc(sizeof(tDisableIntraBssFwd));
8856 	if (!pSapDisableIntraFwd)
8857 		return QDF_STATUS_E_NOMEM;
8858 
8859 	pSapDisableIntraFwd->sessionId = sessionId;
8860 	pSapDisableIntraFwd->disableintrabssfwd = disablefwd;
8861 
8862 	status = sme_acquire_global_lock(&mac->sme);
8863 
8864 	if (QDF_IS_STATUS_ERROR(status)) {
8865 		qdf_mem_free(pSapDisableIntraFwd);
8866 		return QDF_STATUS_E_FAILURE;
8867 	}
8868 	/* serialize the req through MC thread */
8869 	message.bodyptr = pSapDisableIntraFwd;
8870 	message.type = WMA_SET_SAP_INTRABSS_DIS;
8871 	qdf_status = scheduler_post_message(QDF_MODULE_ID_SME,
8872 					    QDF_MODULE_ID_WMA,
8873 					    QDF_MODULE_ID_WMA,
8874 					    &message);
8875 	if (QDF_IS_STATUS_ERROR(status)) {
8876 		status = QDF_STATUS_E_FAILURE;
8877 		qdf_mem_free(pSapDisableIntraFwd);
8878 	}
8879 	sme_release_global_lock(&mac->sme);
8880 
8881 	return status;
8882 }
8883 
8884 #ifdef WLAN_FEATURE_STATS_EXT
8885 
sme_stats_ext_register_callback(mac_handle_t mac_handle,stats_ext_cb callback)8886 void sme_stats_ext_register_callback(mac_handle_t mac_handle,
8887 				     stats_ext_cb callback)
8888 {
8889 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
8890 
8891 	if (!mac) {
8892 		sme_err("Invalid mac context");
8893 		return;
8894 	}
8895 
8896 	mac->sme.stats_ext_cb = callback;
8897 }
8898 
sme_stats_ext_deregister_callback(mac_handle_t mac_handle)8899 void sme_stats_ext_deregister_callback(mac_handle_t mac_handle)
8900 {
8901 	sme_stats_ext_register_callback(mac_handle, NULL);
8902 }
8903 
sme_stats_ext2_register_callback(mac_handle_t mac_handle,stats_ext2_cb callback)8904 void sme_stats_ext2_register_callback(mac_handle_t mac_handle,
8905 				      stats_ext2_cb callback)
8906 {
8907 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
8908 
8909 	if (!mac) {
8910 		sme_err("Invalid mac context");
8911 		return;
8912 	}
8913 
8914 	mac->sme.stats_ext2_cb = callback;
8915 }
8916 
8917 /*
8918  * sme_stats_ext_request() -
8919  * Function called when HDD receives STATS EXT vendor command from userspace
8920  *
8921  * sessionID - vdevID for the stats ext request
8922  * input - Stats Ext Request structure ptr
8923  * Return QDF_STATUS
8924  */
sme_stats_ext_request(uint8_t session_id,tpStatsExtRequestReq input)8925 QDF_STATUS sme_stats_ext_request(uint8_t session_id, tpStatsExtRequestReq input)
8926 {
8927 	struct scheduler_msg msg = {0};
8928 	tpStatsExtRequest data;
8929 	size_t data_len;
8930 
8931 	data_len = sizeof(tStatsExtRequest) + input->request_data_len;
8932 	data = qdf_mem_malloc(data_len);
8933 	if (!data)
8934 		return QDF_STATUS_E_NOMEM;
8935 
8936 	data->vdev_id = session_id;
8937 	data->request_data_len = input->request_data_len;
8938 	if (input->request_data_len)
8939 		qdf_mem_copy(data->request_data,
8940 			     input->request_data, input->request_data_len);
8941 
8942 	msg.type = WMA_STATS_EXT_REQUEST;
8943 	msg.reserved = 0;
8944 	msg.bodyptr = data;
8945 
8946 	if (QDF_STATUS_SUCCESS != scheduler_post_message(QDF_MODULE_ID_SME,
8947 							 QDF_MODULE_ID_WMA,
8948 							 QDF_MODULE_ID_WMA,
8949 							 &msg)) {
8950 		sme_err("Not able to post WMA_STATS_EXT_REQUEST message to WMA");
8951 		qdf_mem_free(data);
8952 		return QDF_STATUS_E_FAILURE;
8953 	}
8954 
8955 	return QDF_STATUS_SUCCESS;
8956 }
8957 
8958 /**
8959  * sme_stats_ext_event() - eWNI_SME_STATS_EXT_EVENT processor
8960  * @mac: Global MAC context
8961  * @msg: "stats ext" message
8962 
8963  * This callback function called when SME received eWNI_SME_STATS_EXT_EVENT
8964  * response from WMA
8965  *
8966  * Return: QDF_STATUS
8967  */
sme_stats_ext_event(struct mac_context * mac,struct stats_ext_event * msg)8968 static QDF_STATUS sme_stats_ext_event(struct mac_context *mac,
8969 				      struct stats_ext_event *msg)
8970 {
8971 	if (!msg) {
8972 		sme_err("Null msg");
8973 		return QDF_STATUS_E_FAILURE;
8974 	}
8975 
8976 	if (mac->sme.stats_ext_cb)
8977 		mac->sme.stats_ext_cb(mac->hdd_handle, msg);
8978 
8979 	return QDF_STATUS_SUCCESS;
8980 }
8981 
8982 #else
8983 
sme_stats_ext_event(struct mac_context * mac,struct stats_ext_event * msg)8984 static QDF_STATUS sme_stats_ext_event(struct mac_context *mac,
8985 				      struct stats_ext_event *msg)
8986 {
8987 	return QDF_STATUS_SUCCESS;
8988 }
8989 
8990 #endif
8991 
8992 #ifdef FEATURE_FW_STATE
sme_get_fw_state(mac_handle_t mac_handle,fw_state_callback callback,void * context)8993 QDF_STATUS sme_get_fw_state(mac_handle_t mac_handle,
8994 			    fw_state_callback callback,
8995 			    void *context)
8996 {
8997 	QDF_STATUS status;
8998 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
8999 	tp_wma_handle wma_handle;
9000 
9001 	SME_ENTER();
9002 
9003 	mac_ctx->sme.fw_state_cb = callback;
9004 	mac_ctx->sme.fw_state_context = context;
9005 	wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
9006 	status = wma_get_fw_state(wma_handle);
9007 
9008 	SME_EXIT();
9009 	return status;
9010 }
9011 
9012 /**
9013  * sme_fw_state_resp() - eWNI_SME_FW_STATUS_IND processor
9014  * @mac: Global MAC context
9015 
9016  * This callback function called when SME received eWNI_SME_FW_STATUS_IND
9017  * response from WMA
9018  *
9019  * Return: QDF_STATUS
9020  */
sme_fw_state_resp(struct mac_context * mac)9021 static QDF_STATUS sme_fw_state_resp(struct mac_context *mac)
9022 {
9023 	if (mac->sme.fw_state_cb)
9024 		mac->sme.fw_state_cb(mac->sme.fw_state_context);
9025 	mac->sme.fw_state_cb = NULL;
9026 	mac->sme.fw_state_context = NULL;
9027 
9028 	return QDF_STATUS_SUCCESS;
9029 }
9030 
9031 #else /* FEATURE_FW_STATE */
sme_fw_state_resp(struct mac_context * mac)9032 static QDF_STATUS sme_fw_state_resp(struct mac_context *mac)
9033 {
9034 	return QDF_STATUS_SUCCESS;
9035 }
9036 
9037 #endif /* FEATURE_FW_STATE */
9038 
9039 /*
9040  * sme_update_dfs_scan_mode() -
9041  * Update DFS roam scan mode
9042  *	    This function is called through dynamic setConfig callback function
9043  *	    to configure allowDFSChannelRoam.
9044  * mac_handle: Opaque handle to the global MAC context
9045  * sessionId - Session Identifier
9046  * allowDFSChannelRoam - DFS roaming scan mode 0 (disable),
9047  *	    1 (passive), 2 (active)
9048  * Return QDF_STATUS_SUCCESS - SME update DFS roaming scan config
9049  *	    successfully.
9050  *	  Other status means SME failed to update DFS roaming scan config.
9051  */
sme_update_dfs_scan_mode(mac_handle_t mac_handle,uint8_t sessionId,uint8_t allowDFSChannelRoam)9052 QDF_STATUS sme_update_dfs_scan_mode(mac_handle_t mac_handle, uint8_t sessionId,
9053 				    uint8_t allowDFSChannelRoam)
9054 {
9055 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
9056 	QDF_STATUS status = QDF_STATUS_SUCCESS;
9057 
9058 	if (sessionId >= WLAN_MAX_VDEVS) {
9059 		sme_err("Invalid vdev %d", sessionId);
9060 		return QDF_STATUS_E_INVAL;
9061 	}
9062 
9063 	status = sme_acquire_global_lock(&mac->sme);
9064 	if (QDF_IS_STATUS_SUCCESS(status)) {
9065 		sme_debug("LFR runtime successfully set AllowDFSChannelRoam Mode to %d - old value is %d",
9066 			  allowDFSChannelRoam,
9067 			  mac->mlme_cfg->lfr.roaming_dfs_channel);
9068 		mac->mlme_cfg->lfr.roaming_dfs_channel =
9069 			allowDFSChannelRoam;
9070 		if (mac->mlme_cfg->lfr.roam_scan_offload_enabled)
9071 			wlan_roam_update_cfg(mac->psoc, sessionId,
9072 					    REASON_ROAM_DFS_SCAN_MODE_CHANGED);
9073 
9074 		sme_release_global_lock(&mac->sme);
9075 	}
9076 
9077 
9078 	return status;
9079 }
9080 
9081 /*
9082  * sme_get_dfs_scan_mode() - get DFS roam scan mode
9083  *	  This is a synchronous call
9084  *
9085  * mac_handle - The handle returned by mac_open.
9086  * Return DFS roaming scan mode 0 (disable), 1 (passive), 2 (active)
9087  */
sme_get_dfs_scan_mode(mac_handle_t mac_handle)9088 uint8_t sme_get_dfs_scan_mode(mac_handle_t mac_handle)
9089 {
9090 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
9091 
9092 	return mac->mlme_cfg->lfr.roaming_dfs_channel;
9093 }
9094 
9095 /*
9096  * sme_modify_add_ie() -
9097  * This function sends msg to updates the additional IE buffers in PE
9098  *
9099  * mac_handle - global structure
9100  * pModifyIE - pointer to tModifyIE structure
9101  * updateType - type of buffer
9102  * Return Success or failure
9103  */
sme_modify_add_ie(mac_handle_t mac_handle,tSirModifyIE * pModifyIE,eUpdateIEsType updateType)9104 QDF_STATUS sme_modify_add_ie(mac_handle_t mac_handle,
9105 			     tSirModifyIE *pModifyIE, eUpdateIEsType updateType)
9106 {
9107 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
9108 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
9109 
9110 	status = sme_acquire_global_lock(&mac->sme);
9111 
9112 	if (QDF_IS_STATUS_SUCCESS(status)) {
9113 		status = csr_roam_modify_add_ies(mac, pModifyIE, updateType);
9114 		sme_release_global_lock(&mac->sme);
9115 	}
9116 	return status;
9117 }
9118 
9119 /*
9120  * sme_update_add_ie() -
9121  * This function sends msg to updates the additional IE buffers in PE
9122  *
9123  * mac_handle - global structure
9124  * pUpdateIE - pointer to structure tUpdateIE
9125  * updateType - type of buffer
9126  * Return Success or failure
9127  */
sme_update_add_ie(mac_handle_t mac_handle,tSirUpdateIE * pUpdateIE,eUpdateIEsType updateType)9128 QDF_STATUS sme_update_add_ie(mac_handle_t mac_handle,
9129 			     tSirUpdateIE *pUpdateIE, eUpdateIEsType updateType)
9130 {
9131 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
9132 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
9133 
9134 	status = sme_acquire_global_lock(&mac->sme);
9135 
9136 	if (QDF_IS_STATUS_SUCCESS(status)) {
9137 		status = csr_roam_update_add_ies(mac, pUpdateIE, updateType);
9138 		sme_release_global_lock(&mac->sme);
9139 	}
9140 	return status;
9141 }
9142 
9143 /**
9144  * sme_update_dsc_pto_up_mapping()
9145  * @mac_handle: Opaque handle to the global MAC context
9146  * @dscpmapping: pointer to DSCP mapping structure
9147  * @sessionId: SME session id
9148  *
9149  * This routine is called to update dscp mapping
9150  *
9151  * Return: QDF_STATUS
9152  */
sme_update_dsc_pto_up_mapping(mac_handle_t mac_handle,enum sme_qos_wmmuptype * dscpmapping,uint8_t sessionId)9153 QDF_STATUS sme_update_dsc_pto_up_mapping(mac_handle_t mac_handle,
9154 					 enum sme_qos_wmmuptype *dscpmapping,
9155 					 uint8_t sessionId)
9156 {
9157 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
9158 	QDF_STATUS status = QDF_STATUS_SUCCESS;
9159 	uint8_t i, j;
9160 	struct csr_roam_session *pCsrSession = NULL;
9161 	struct pe_session *pSession = NULL;
9162 	struct qos_map_set *pqosmapset;
9163 
9164 	pCsrSession = CSR_GET_SESSION(mac, sessionId);
9165 	if (!pCsrSession) {
9166 		sme_err("Session lookup fails for dvev %d", sessionId);
9167 		return QDF_STATUS_E_FAILURE;
9168 	}
9169 	if (!CSR_IS_SESSION_VALID(mac, sessionId)) {
9170 		sme_err("Invalid session Id %u", sessionId);
9171 		return QDF_STATUS_E_FAILURE;
9172 	}
9173 
9174 	pSession = pe_find_session_by_vdev_id(mac, sessionId);
9175 
9176 	if (!pSession)
9177 		return QDF_STATUS_E_FAILURE;
9178 
9179 	pqosmapset = &pSession->QosMapSet;
9180 	if (!pqosmapset->present)
9181 		return QDF_STATUS_E_FAILURE;
9182 
9183 	for (i = 0; i < SME_QOS_WMM_UP_MAX; i++) {
9184 		for (j = pqosmapset->dscp_range[i][0];
9185 		     j <= pqosmapset->dscp_range[i][1] && j <= WLAN_MAX_DSCP;
9186 		     j++)
9187 			dscpmapping[j] = i;
9188 	}
9189 	for (i = 0; i < pqosmapset->num_dscp_exceptions; i++)
9190 		if (pqosmapset->dscp_exceptions[i][0] <= WLAN_MAX_DSCP &&
9191 		    pqosmapset->dscp_exceptions[i][1] < SME_QOS_WMM_UP_MAX)
9192 			dscpmapping[pqosmapset->dscp_exceptions[i][0]] =
9193 					pqosmapset->dscp_exceptions[i][1];
9194 
9195 	return status;
9196 }
9197 
sme_get_valid_channels_by_band(mac_handle_t mac_handle,uint8_t wifi_band,uint32_t * valid_chan_list,uint8_t * valid_chan_len)9198 QDF_STATUS sme_get_valid_channels_by_band(mac_handle_t mac_handle,
9199 					  uint8_t wifi_band,
9200 					  uint32_t *valid_chan_list,
9201 					  uint8_t *valid_chan_len)
9202 {
9203 	QDF_STATUS status = QDF_STATUS_SUCCESS;
9204 	uint32_t chan_freq_list[CFG_VALID_CHANNEL_LIST_LEN] = { 0 };
9205 	uint8_t num_channels = 0;
9206 	uint8_t i = 0;
9207 	uint32_t valid_channels = CFG_VALID_CHANNEL_LIST_LEN;
9208 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
9209 
9210 	if (!valid_chan_list || !valid_chan_len) {
9211 		sme_err("Output channel list/NumChannels is NULL");
9212 		return QDF_STATUS_E_INVAL;
9213 	}
9214 
9215 	if (wifi_band >= WIFI_BAND_MAX) {
9216 		sme_err("Invalid wifi Band: %d", wifi_band);
9217 		return QDF_STATUS_E_INVAL;
9218 	}
9219 
9220 	status = sme_get_cfg_valid_channels(&chan_freq_list[0],
9221 					    &valid_channels);
9222 	if (!QDF_IS_STATUS_SUCCESS(status)) {
9223 		sme_err("Fail to get valid channel list (err=%d)", status);
9224 		return status;
9225 	}
9226 
9227 	switch (wifi_band) {
9228 	case WIFI_BAND_UNSPECIFIED:
9229 		sme_debug("Unspec Band, return all %d valid channels",
9230 			  valid_channels);
9231 		num_channels = valid_channels;
9232 		for (i = 0; i < valid_channels; i++)
9233 			valid_chan_list[i] = chan_freq_list[i];
9234 		break;
9235 
9236 	case WIFI_BAND_BG:
9237 		sme_debug("WIFI_BAND_BG (2.4 GHz)");
9238 		for (i = 0; i < valid_channels; i++) {
9239 			if (WLAN_REG_IS_24GHZ_CH_FREQ(chan_freq_list[i]))
9240 				valid_chan_list[num_channels++] =
9241 					chan_freq_list[i];
9242 		}
9243 		break;
9244 
9245 	case WIFI_BAND_A:
9246 		sme_debug("WIFI_BAND_A (5 GHz without DFS)");
9247 		for (i = 0; i < valid_channels; i++) {
9248 			if (WLAN_REG_IS_5GHZ_CH_FREQ(chan_freq_list[i]) &&
9249 			    !wlan_reg_is_dfs_for_freq(mac_ctx->pdev,
9250 						      chan_freq_list[i]))
9251 				valid_chan_list[num_channels++] =
9252 					chan_freq_list[i];
9253 		}
9254 		break;
9255 
9256 	case WIFI_BAND_ABG:
9257 		sme_debug("WIFI_BAND_ABG (2.4 GHz + 5 GHz; no DFS)");
9258 		for (i = 0; i < valid_channels; i++) {
9259 			if ((WLAN_REG_IS_24GHZ_CH_FREQ(chan_freq_list[i]) ||
9260 			     WLAN_REG_IS_5GHZ_CH_FREQ(chan_freq_list[i])) &&
9261 			    !wlan_reg_is_dfs_for_freq(mac_ctx->pdev,
9262 						      chan_freq_list[i]))
9263 				valid_chan_list[num_channels++] =
9264 					chan_freq_list[i];
9265 		}
9266 		break;
9267 
9268 	case WIFI_BAND_A_DFS_ONLY:
9269 		sme_debug("WIFI_BAND_A_DFS (5 GHz DFS only)");
9270 		for (i = 0; i < valid_channels; i++) {
9271 			if (WLAN_REG_IS_5GHZ_CH_FREQ(chan_freq_list[i]) &&
9272 			    wlan_reg_is_dfs_for_freq(mac_ctx->pdev,
9273 						     chan_freq_list[i]))
9274 				valid_chan_list[num_channels++] =
9275 					chan_freq_list[i];
9276 		}
9277 		break;
9278 
9279 	case WIFI_BAND_A_WITH_DFS:
9280 		sme_debug("WIFI_BAND_A_WITH_DFS (5 GHz with DFS)");
9281 		for (i = 0; i < valid_channels; i++) {
9282 			if (WLAN_REG_IS_5GHZ_CH_FREQ(chan_freq_list[i]))
9283 				valid_chan_list[num_channels++] =
9284 					chan_freq_list[i];
9285 		}
9286 		break;
9287 
9288 	case WIFI_BAND_ABG_WITH_DFS:
9289 		sme_debug("WIFI_BAND_ABG_WITH_DFS (2.4 GHz+5 GHz with DFS)");
9290 		for (i = 0; i < valid_channels; i++) {
9291 			if (WLAN_REG_IS_24GHZ_CH_FREQ(chan_freq_list[i]) ||
9292 			    WLAN_REG_IS_5GHZ_CH_FREQ(chan_freq_list[i]))
9293 				valid_chan_list[num_channels++] =
9294 					chan_freq_list[i];
9295 		}
9296 		break;
9297 
9298 	default:
9299 		sme_err("Unknown wifi Band: %d", wifi_band);
9300 		return QDF_STATUS_E_INVAL;
9301 	}
9302 	*valid_chan_len = num_channels;
9303 
9304 	return status;
9305 }
9306 
9307 #ifdef FEATURE_WLAN_EXTSCAN
9308 
9309 QDF_STATUS
sme_ext_scan_get_capabilities(mac_handle_t mac_handle,struct extscan_capabilities_params * params)9310 sme_ext_scan_get_capabilities(mac_handle_t mac_handle,
9311 			      struct extscan_capabilities_params *params)
9312 {
9313 	QDF_STATUS status;
9314 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
9315 	struct scheduler_msg message = {0};
9316 	struct extscan_capabilities_params *bodyptr;
9317 
9318 	/* per contract must make a copy of the params when messaging */
9319 	bodyptr = qdf_mem_malloc(sizeof(*bodyptr));
9320 	if (!bodyptr)
9321 		return QDF_STATUS_E_NOMEM;
9322 
9323 	*bodyptr = *params;
9324 
9325 	status = sme_acquire_global_lock(&mac->sme);
9326 	if (QDF_IS_STATUS_SUCCESS(status)) {
9327 		/* Serialize the req through MC thread */
9328 		message.bodyptr = bodyptr;
9329 		message.type = WMA_EXTSCAN_GET_CAPABILITIES_REQ;
9330 		qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG,
9331 			  NO_SESSION, message.type);
9332 		status = scheduler_post_message(QDF_MODULE_ID_SME,
9333 						QDF_MODULE_ID_WMA,
9334 						QDF_MODULE_ID_WMA,
9335 						&message);
9336 		sme_release_global_lock(&mac->sme);
9337 	}
9338 
9339 	if (QDF_IS_STATUS_ERROR(status)) {
9340 		sme_err("failure: %d", status);
9341 		qdf_mem_free(bodyptr);
9342 	}
9343 	return status;
9344 }
9345 
9346 QDF_STATUS
sme_ext_scan_start(mac_handle_t mac_handle,struct wifi_scan_cmd_req_params * params)9347 sme_ext_scan_start(mac_handle_t mac_handle,
9348 		   struct wifi_scan_cmd_req_params *params)
9349 {
9350 	QDF_STATUS status;
9351 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
9352 	struct scheduler_msg message = {0};
9353 	struct wifi_scan_cmd_req_params *bodyptr;
9354 
9355 	/* per contract must make a copy of the params when messaging */
9356 	bodyptr = qdf_mem_malloc(sizeof(*bodyptr));
9357 	if (!bodyptr)
9358 		return QDF_STATUS_E_NOMEM;
9359 
9360 	*bodyptr = *params;
9361 
9362 	status = sme_acquire_global_lock(&mac->sme);
9363 	if (QDF_IS_STATUS_SUCCESS(status)) {
9364 		/* Serialize the req through MC thread */
9365 		message.bodyptr = bodyptr;
9366 		message.type = WMA_EXTSCAN_START_REQ;
9367 		qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG,
9368 			  NO_SESSION, message.type);
9369 		status = scheduler_post_message(QDF_MODULE_ID_SME,
9370 						QDF_MODULE_ID_WMA,
9371 						QDF_MODULE_ID_WMA,
9372 						&message);
9373 		sme_release_global_lock(&mac->sme);
9374 	}
9375 
9376 	if (QDF_IS_STATUS_ERROR(status)) {
9377 		sme_err("failure: %d", status);
9378 		qdf_mem_free(bodyptr);
9379 	}
9380 	return status;
9381 }
9382 
sme_ext_scan_stop(mac_handle_t mac_handle,struct extscan_stop_req_params * params)9383 QDF_STATUS sme_ext_scan_stop(mac_handle_t mac_handle,
9384 			     struct extscan_stop_req_params *params)
9385 {
9386 	QDF_STATUS status;
9387 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
9388 	struct scheduler_msg message = {0};
9389 	struct extscan_stop_req_params *bodyptr;
9390 
9391 	/* per contract must make a copy of the params when messaging */
9392 	bodyptr = qdf_mem_malloc(sizeof(*bodyptr));
9393 	if (!bodyptr)
9394 		return QDF_STATUS_E_NOMEM;
9395 
9396 	*bodyptr = *params;
9397 
9398 	status = sme_acquire_global_lock(&mac->sme);
9399 	if (QDF_IS_STATUS_SUCCESS(status)) {
9400 		/* Serialize the req through MC thread */
9401 		message.bodyptr = bodyptr;
9402 		message.type = WMA_EXTSCAN_STOP_REQ;
9403 		qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG,
9404 			  NO_SESSION, message.type);
9405 		status = scheduler_post_message(QDF_MODULE_ID_SME,
9406 						QDF_MODULE_ID_WMA,
9407 						QDF_MODULE_ID_WMA,
9408 						&message);
9409 		sme_release_global_lock(&mac->sme);
9410 	}
9411 
9412 	if (QDF_IS_STATUS_ERROR(status)) {
9413 		sme_err("failure: %d", status);
9414 		qdf_mem_free(bodyptr);
9415 	}
9416 	return status;
9417 }
9418 
9419 QDF_STATUS
sme_set_bss_hotlist(mac_handle_t mac_handle,struct extscan_bssid_hotlist_set_params * params)9420 sme_set_bss_hotlist(mac_handle_t mac_handle,
9421 		    struct extscan_bssid_hotlist_set_params *params)
9422 {
9423 	QDF_STATUS status;
9424 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
9425 	struct scheduler_msg message = {0};
9426 	struct extscan_bssid_hotlist_set_params *bodyptr;
9427 
9428 	/* per contract must make a copy of the params when messaging */
9429 	bodyptr = qdf_mem_malloc(sizeof(*bodyptr));
9430 	if (!bodyptr)
9431 		return QDF_STATUS_E_NOMEM;
9432 
9433 	*bodyptr = *params;
9434 
9435 	status = sme_acquire_global_lock(&mac->sme);
9436 	if (QDF_IS_STATUS_SUCCESS(status)) {
9437 		/* Serialize the req through MC thread */
9438 		message.bodyptr = bodyptr;
9439 		message.type = WMA_EXTSCAN_SET_BSSID_HOTLIST_REQ;
9440 		qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG,
9441 			  NO_SESSION, message.type);
9442 		status = scheduler_post_message(QDF_MODULE_ID_SME,
9443 						QDF_MODULE_ID_WMA,
9444 						QDF_MODULE_ID_WMA, &message);
9445 		sme_release_global_lock(&mac->sme);
9446 	}
9447 
9448 	if (QDF_IS_STATUS_ERROR(status)) {
9449 		sme_err("failure: %d", status);
9450 		qdf_mem_free(bodyptr);
9451 	}
9452 	return status;
9453 }
9454 
9455 QDF_STATUS
sme_reset_bss_hotlist(mac_handle_t mac_handle,struct extscan_bssid_hotlist_reset_params * params)9456 sme_reset_bss_hotlist(mac_handle_t mac_handle,
9457 		      struct extscan_bssid_hotlist_reset_params *params)
9458 {
9459 	QDF_STATUS status;
9460 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
9461 	struct scheduler_msg message = {0};
9462 	struct extscan_bssid_hotlist_reset_params *bodyptr;
9463 
9464 	/* per contract must make a copy of the params when messaging */
9465 	bodyptr = qdf_mem_malloc(sizeof(*bodyptr));
9466 	if (!bodyptr)
9467 		return QDF_STATUS_E_NOMEM;
9468 
9469 	*bodyptr = *params;
9470 
9471 	status = sme_acquire_global_lock(&mac->sme);
9472 	if (QDF_IS_STATUS_SUCCESS(status)) {
9473 		/* Serialize the req through MC thread */
9474 		message.bodyptr = bodyptr;
9475 		message.type = WMA_EXTSCAN_RESET_BSSID_HOTLIST_REQ;
9476 		MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG,
9477 				 NO_SESSION, message.type));
9478 		status = scheduler_post_message(QDF_MODULE_ID_SME,
9479 						QDF_MODULE_ID_WMA,
9480 						QDF_MODULE_ID_WMA, &message);
9481 		sme_release_global_lock(&mac->sme);
9482 	}
9483 
9484 	if (QDF_IS_STATUS_ERROR(status)) {
9485 		sme_err("failure: %d", status);
9486 		qdf_mem_free(bodyptr);
9487 	}
9488 	return status;
9489 }
9490 
9491 QDF_STATUS
sme_set_significant_change(mac_handle_t mac_handle,struct extscan_set_sig_changereq_params * params)9492 sme_set_significant_change(mac_handle_t mac_handle,
9493 			   struct extscan_set_sig_changereq_params *params)
9494 {
9495 	QDF_STATUS status;
9496 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
9497 	struct scheduler_msg message = {0};
9498 	struct extscan_set_sig_changereq_params *bodyptr;
9499 
9500 	/* per contract must make a copy of the params when messaging */
9501 	bodyptr = qdf_mem_malloc(sizeof(*bodyptr));
9502 	if (!bodyptr)
9503 		return QDF_STATUS_E_NOMEM;
9504 
9505 	*bodyptr = *params;
9506 
9507 	status = sme_acquire_global_lock(&mac->sme);
9508 	if (QDF_IS_STATUS_SUCCESS(status)) {
9509 		/* Serialize the req through MC thread */
9510 		message.bodyptr = bodyptr;
9511 		message.type = WMA_EXTSCAN_SET_SIGNF_CHANGE_REQ;
9512 		status = scheduler_post_message(QDF_MODULE_ID_SME,
9513 						QDF_MODULE_ID_WMA,
9514 						QDF_MODULE_ID_WMA,
9515 						&message);
9516 		sme_release_global_lock(&mac->sme);
9517 	}
9518 	if (QDF_IS_STATUS_ERROR(status)) {
9519 		sme_err("failure: %d", status);
9520 		qdf_mem_free(bodyptr);
9521 	}
9522 	return status;
9523 }
9524 
9525 QDF_STATUS
sme_reset_significant_change(mac_handle_t mac_handle,struct extscan_capabilities_reset_params * params)9526 sme_reset_significant_change(mac_handle_t mac_handle,
9527 			     struct extscan_capabilities_reset_params *params)
9528 {
9529 	QDF_STATUS status;
9530 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
9531 	struct scheduler_msg message = {0};
9532 	struct extscan_capabilities_reset_params *bodyptr;
9533 
9534 	/* per contract must make a copy of the params when messaging */
9535 	bodyptr = qdf_mem_malloc(sizeof(*bodyptr));
9536 	if (!bodyptr)
9537 		return QDF_STATUS_E_NOMEM;
9538 
9539 	*bodyptr = *params;
9540 
9541 	status = sme_acquire_global_lock(&mac->sme);
9542 	if (QDF_IS_STATUS_SUCCESS(status)) {
9543 		/* Serialize the req through MC thread */
9544 		message.bodyptr = bodyptr;
9545 		message.type = WMA_EXTSCAN_RESET_SIGNF_CHANGE_REQ;
9546 		MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG,
9547 				 NO_SESSION, message.type));
9548 		status = scheduler_post_message(QDF_MODULE_ID_SME,
9549 						QDF_MODULE_ID_WMA,
9550 						QDF_MODULE_ID_WMA,
9551 						&message);
9552 		sme_release_global_lock(&mac->sme);
9553 	}
9554 	if (QDF_IS_STATUS_ERROR(status)) {
9555 		sme_err("failure: %d", status);
9556 		qdf_mem_free(bodyptr);
9557 	}
9558 
9559 	return status;
9560 }
9561 
9562 QDF_STATUS
sme_get_cached_results(mac_handle_t mac_handle,struct extscan_cached_result_params * params)9563 sme_get_cached_results(mac_handle_t mac_handle,
9564 		       struct extscan_cached_result_params *params)
9565 {
9566 	QDF_STATUS status;
9567 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
9568 	struct scheduler_msg message = {0};
9569 	struct extscan_cached_result_params *bodyptr;
9570 
9571 	/* per contract must make a copy of the params when messaging */
9572 	bodyptr = qdf_mem_malloc(sizeof(*bodyptr));
9573 	if (!bodyptr)
9574 		return QDF_STATUS_E_NOMEM;
9575 
9576 	*bodyptr = *params;
9577 
9578 	status = sme_acquire_global_lock(&mac->sme);
9579 	if (QDF_IS_STATUS_SUCCESS(status)) {
9580 		/* Serialize the req through MC thread */
9581 		message.bodyptr = bodyptr;
9582 		message.type = WMA_EXTSCAN_GET_CACHED_RESULTS_REQ;
9583 		qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG,
9584 			  NO_SESSION, message.type);
9585 		status = scheduler_post_message(QDF_MODULE_ID_SME,
9586 						QDF_MODULE_ID_WMA,
9587 						QDF_MODULE_ID_WMA,
9588 						&message);
9589 		sme_release_global_lock(&mac->sme);
9590 	}
9591 
9592 	if (QDF_IS_STATUS_ERROR(status)) {
9593 		sme_err("failure: %d", status);
9594 		qdf_mem_free(bodyptr);
9595 	}
9596 	return status;
9597 }
9598 
sme_set_epno_list(mac_handle_t mac_handle,struct wifi_enhanced_pno_params * params)9599 QDF_STATUS sme_set_epno_list(mac_handle_t mac_handle,
9600 			     struct wifi_enhanced_pno_params *params)
9601 {
9602 	QDF_STATUS status;
9603 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
9604 	struct scheduler_msg message = {0};
9605 	struct wifi_enhanced_pno_params *req_msg;
9606 	int len;
9607 
9608 	SME_ENTER();
9609 
9610 	/* per contract must make a copy of the params when messaging */
9611 	len = sizeof(*req_msg) +
9612 		(params->num_networks * sizeof(req_msg->networks[0]));
9613 
9614 	req_msg = qdf_mem_malloc(len);
9615 	if (!req_msg)
9616 		return QDF_STATUS_E_NOMEM;
9617 
9618 	qdf_mem_copy(req_msg, params, len);
9619 
9620 	status = sme_acquire_global_lock(&mac->sme);
9621 	if (!QDF_IS_STATUS_SUCCESS(status)) {
9622 		sme_err("sme_acquire_global_lock failed!(status=%d)",
9623 			status);
9624 		qdf_mem_free(req_msg);
9625 		return status;
9626 	}
9627 
9628 	/* Serialize the req through MC thread */
9629 	message.bodyptr = req_msg;
9630 	message.type    = WMA_SET_EPNO_LIST_REQ;
9631 	status = scheduler_post_message(QDF_MODULE_ID_SME,
9632 					QDF_MODULE_ID_WMA,
9633 					QDF_MODULE_ID_WMA, &message);
9634 	if (!QDF_IS_STATUS_SUCCESS(status)) {
9635 		sme_err("scheduler_post_msg failed!(err=%d)", status);
9636 		qdf_mem_free(req_msg);
9637 	}
9638 	sme_release_global_lock(&mac->sme);
9639 
9640 	return status;
9641 }
9642 
sme_set_passpoint_list(mac_handle_t mac_handle,struct wifi_passpoint_req_param * params)9643 QDF_STATUS sme_set_passpoint_list(mac_handle_t mac_handle,
9644 				  struct wifi_passpoint_req_param *params)
9645 {
9646 	QDF_STATUS status;
9647 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
9648 	struct scheduler_msg message = {0};
9649 	struct wifi_passpoint_req_param *req_msg;
9650 	int len;
9651 
9652 	SME_ENTER();
9653 
9654 	len = sizeof(*req_msg) +
9655 		(params->num_networks * sizeof(params->networks[0]));
9656 	req_msg = qdf_mem_malloc(len);
9657 	if (!req_msg)
9658 		return QDF_STATUS_E_NOMEM;
9659 
9660 	qdf_mem_copy(req_msg, params, len);
9661 
9662 	status = sme_acquire_global_lock(&mac->sme);
9663 	if (!QDF_IS_STATUS_SUCCESS(status)) {
9664 		sme_err("sme_acquire_global_lock failed!(status=%d)",
9665 			status);
9666 		qdf_mem_free(req_msg);
9667 		return status;
9668 	}
9669 
9670 	/* Serialize the req through MC thread */
9671 	message.bodyptr = req_msg;
9672 	message.type    = WMA_SET_PASSPOINT_LIST_REQ;
9673 	status = scheduler_post_message(QDF_MODULE_ID_SME,
9674 					QDF_MODULE_ID_WMA,
9675 					QDF_MODULE_ID_WMA, &message);
9676 	if (!QDF_IS_STATUS_SUCCESS(status)) {
9677 		sme_err("scheduler_post_msg failed!(err=%d)",
9678 			status);
9679 		qdf_mem_free(req_msg);
9680 	}
9681 	sme_release_global_lock(&mac->sme);
9682 	return status;
9683 }
9684 
sme_reset_passpoint_list(mac_handle_t mac_handle,struct wifi_passpoint_req_param * params)9685 QDF_STATUS sme_reset_passpoint_list(mac_handle_t mac_handle,
9686 				    struct wifi_passpoint_req_param *params)
9687 {
9688 	QDF_STATUS status;
9689 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
9690 	struct scheduler_msg message = {0};
9691 	struct wifi_passpoint_req_param *req_msg;
9692 
9693 	SME_ENTER();
9694 
9695 	req_msg = qdf_mem_malloc(sizeof(*req_msg));
9696 	if (!req_msg)
9697 		return QDF_STATUS_E_NOMEM;
9698 
9699 	*req_msg = *params;
9700 
9701 	status = sme_acquire_global_lock(&mac->sme);
9702 	if (!QDF_IS_STATUS_SUCCESS(status)) {
9703 		sme_err("sme_acquire_global_lock failed!(status=%d)",
9704 			status);
9705 		qdf_mem_free(req_msg);
9706 		return status;
9707 	}
9708 
9709 	/* Serialize the req through MC thread */
9710 	message.bodyptr = req_msg;
9711 	message.type    = WMA_RESET_PASSPOINT_LIST_REQ;
9712 	status = scheduler_post_message(QDF_MODULE_ID_SME,
9713 					QDF_MODULE_ID_WMA,
9714 					QDF_MODULE_ID_WMA, &message);
9715 	if (!QDF_IS_STATUS_SUCCESS(status)) {
9716 		sme_err("scheduler_post_msg failed!(err=%d)",
9717 			status);
9718 		qdf_mem_free(req_msg);
9719 	}
9720 	sme_release_global_lock(&mac->sme);
9721 	return status;
9722 }
9723 
sme_ext_scan_register_callback(mac_handle_t mac_handle,ext_scan_ind_cb ext_scan_ind_cb)9724 QDF_STATUS sme_ext_scan_register_callback(mac_handle_t mac_handle,
9725 					  ext_scan_ind_cb ext_scan_ind_cb)
9726 {
9727 	QDF_STATUS status;
9728 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
9729 
9730 	status = sme_acquire_global_lock(&mac->sme);
9731 	if (QDF_IS_STATUS_SUCCESS(status)) {
9732 		mac->sme.ext_scan_ind_cb = ext_scan_ind_cb;
9733 		sme_release_global_lock(&mac->sme);
9734 	}
9735 	return status;
9736 }
9737 #endif /* FEATURE_WLAN_EXTSCAN */
9738 
9739 /**
9740  * sme_send_wisa_params(): Pass WISA mode to WMA
9741  * @mac_handle: Opaque handle to the global MAC context
9742  * @wisa_params: pointer to WISA params struct
9743  * @sessionId: SME session id
9744  *
9745  * Pass WISA params to WMA
9746  *
9747  * Return: QDF_STATUS
9748  */
sme_set_wisa_params(mac_handle_t mac_handle,struct sir_wisa_params * wisa_params)9749 QDF_STATUS sme_set_wisa_params(mac_handle_t mac_handle,
9750 			       struct sir_wisa_params *wisa_params)
9751 {
9752 	QDF_STATUS status = QDF_STATUS_SUCCESS;
9753 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
9754 	struct scheduler_msg message = {0};
9755 	struct sir_wisa_params *cds_msg_wisa_params;
9756 
9757 	cds_msg_wisa_params = qdf_mem_malloc(sizeof(struct sir_wisa_params));
9758 	if (!cds_msg_wisa_params)
9759 		return QDF_STATUS_E_NOMEM;
9760 
9761 	*cds_msg_wisa_params = *wisa_params;
9762 	status = sme_acquire_global_lock(&mac->sme);
9763 
9764 	if (QDF_IS_STATUS_ERROR(status)) {
9765 		qdf_mem_free(cds_msg_wisa_params);
9766 		return QDF_STATUS_E_FAILURE;
9767 	}
9768 	message.bodyptr = cds_msg_wisa_params;
9769 	message.type = WMA_SET_WISA_PARAMS;
9770 	status = scheduler_post_message(QDF_MODULE_ID_SME,
9771 					QDF_MODULE_ID_WMA,
9772 					QDF_MODULE_ID_WMA, &message);
9773 	if (QDF_IS_STATUS_ERROR(status))
9774 		qdf_mem_free(cds_msg_wisa_params);
9775 	sme_release_global_lock(&mac->sme);
9776 	return status;
9777 }
9778 
9779 #ifdef WLAN_FEATURE_LINK_LAYER_STATS
9780 
sme_radio_tx_mem_free(void)9781 void sme_radio_tx_mem_free(void)
9782 {
9783 	tp_wma_handle wma_handle;
9784 
9785 	wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
9786 
9787 	if (!wma_handle) {
9788 		sme_err("Invalid wma handle");
9789 		return;
9790 	}
9791 	wma_unified_radio_tx_mem_free(wma_handle);
9792 }
9793 
9794 /*
9795  * sme_ll_stats_clear_req() -
9796  * SME API to clear Link Layer Statistics
9797  *
9798  * mac_handle
9799  * pclearStatsReq: Link Layer clear stats request params structure
9800  * Return QDF_STATUS
9801  */
sme_ll_stats_clear_req(mac_handle_t mac_handle,tSirLLStatsClearReq * pclearStatsReq)9802 QDF_STATUS sme_ll_stats_clear_req(mac_handle_t mac_handle,
9803 				  tSirLLStatsClearReq *pclearStatsReq)
9804 {
9805 	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
9806 	struct scheduler_msg message = {0};
9807 	tSirLLStatsClearReq *clear_stats_req;
9808 
9809 	sme_debug("staId = %u statsClearReqMask = 0x%X stopReq = %u",
9810 		  pclearStatsReq->staId, pclearStatsReq->statsClearReqMask,
9811 		  pclearStatsReq->stopReq);
9812 	if (!sme_is_session_id_valid(mac_handle, pclearStatsReq->staId)) {
9813 		sme_err("invalid staId %d", pclearStatsReq->staId);
9814 		return QDF_STATUS_E_INVAL;
9815 	}
9816 
9817 	clear_stats_req = qdf_mem_malloc(sizeof(*clear_stats_req));
9818 	if (!clear_stats_req)
9819 		return QDF_STATUS_E_NOMEM;
9820 
9821 	*clear_stats_req = *pclearStatsReq;
9822 
9823 	/* Serialize the req through MC thread */
9824 	message.bodyptr = clear_stats_req;
9825 	message.type = WMA_LINK_LAYER_STATS_CLEAR_REQ;
9826 	MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG,
9827 			 NO_SESSION, message.type));
9828 	qdf_status = scheduler_post_message(QDF_MODULE_ID_SME,
9829 					    QDF_MODULE_ID_WMA,
9830 					    QDF_MODULE_ID_WMA,
9831 					    &message);
9832 	if (QDF_IS_STATUS_ERROR(qdf_status)) {
9833 		sme_err("not able to post WMA_LL_STATS_CLEAR_REQ");
9834 		qdf_mem_free(clear_stats_req);
9835 	}
9836 
9837 	return qdf_status;
9838 }
9839 
9840 /*
9841  * sme_ll_stats_set_req() -
9842  * SME API to set the Link Layer Statistics
9843  *
9844  * mac_handle
9845  * psetStatsReq: Link Layer set stats request params structure
9846  * Return QDF_STATUS
9847  */
sme_ll_stats_set_req(mac_handle_t mac_handle,tSirLLStatsSetReq * psetStatsReq)9848 QDF_STATUS sme_ll_stats_set_req(mac_handle_t mac_handle, tSirLLStatsSetReq
9849 				*psetStatsReq)
9850 {
9851 	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
9852 	struct scheduler_msg message = {0};
9853 	tSirLLStatsSetReq *set_stats_req;
9854 
9855 	sme_debug("MPDU Size = %u Aggressive Stats Collections = %u",
9856 		  psetStatsReq->mpduSizeThreshold,
9857 		  psetStatsReq->aggressiveStatisticsGathering);
9858 
9859 	set_stats_req = qdf_mem_malloc(sizeof(*set_stats_req));
9860 	if (!set_stats_req)
9861 		return QDF_STATUS_E_NOMEM;
9862 
9863 	*set_stats_req = *psetStatsReq;
9864 
9865 	/* Serialize the req through MC thread */
9866 	message.bodyptr = set_stats_req;
9867 	message.type = WMA_LINK_LAYER_STATS_SET_REQ;
9868 	MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG,
9869 			 NO_SESSION, message.type));
9870 	qdf_status = scheduler_post_message(QDF_MODULE_ID_SME,
9871 					    QDF_MODULE_ID_WMA,
9872 					    QDF_MODULE_ID_WMA,
9873 					    &message);
9874 	if (QDF_IS_STATUS_ERROR(qdf_status)) {
9875 		sme_err("not able to post WMA_LL_STATS_SET_REQ");
9876 		qdf_mem_free(set_stats_req);
9877 	}
9878 
9879 	return qdf_status;
9880 }
9881 
sme_ll_stats_get_req(mac_handle_t mac_handle,tSirLLStatsGetReq * get_stats_req,void * context)9882 QDF_STATUS sme_ll_stats_get_req(mac_handle_t mac_handle,
9883 				tSirLLStatsGetReq *get_stats_req,
9884 				void *context)
9885 {
9886 	QDF_STATUS status;
9887 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
9888 	struct scheduler_msg message = {0};
9889 	tSirLLStatsGetReq *ll_stats_get_req;
9890 
9891 	ll_stats_get_req = qdf_mem_malloc(sizeof(*ll_stats_get_req));
9892 	if (!ll_stats_get_req)
9893 		return QDF_STATUS_E_NOMEM;
9894 
9895 	*ll_stats_get_req = *get_stats_req;
9896 
9897 	mac->sme.ll_stats_context = context;
9898 	/* Serialize the req through MC thread */
9899 	message.bodyptr = ll_stats_get_req;
9900 	message.type = WMA_LINK_LAYER_STATS_GET_REQ;
9901 	qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG,
9902 		  NO_SESSION, message.type);
9903 	status = scheduler_post_message(QDF_MODULE_ID_SME,
9904 					QDF_MODULE_ID_WMA,
9905 					QDF_MODULE_ID_WMA, &message);
9906 	if (QDF_IS_STATUS_ERROR(status)) {
9907 		sme_err("Not able to post WMA_LL_STATS_GET_REQ");
9908 		qdf_mem_free(ll_stats_get_req);
9909 	}
9910 
9911 	return status;
9912 }
9913 
sme_set_link_layer_stats_ind_cb(mac_handle_t mac_handle,link_layer_stats_cb callback)9914 QDF_STATUS sme_set_link_layer_stats_ind_cb(mac_handle_t mac_handle,
9915 					   link_layer_stats_cb callback)
9916 {
9917 	QDF_STATUS status;
9918 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
9919 
9920 	status = sme_acquire_global_lock(&mac->sme);
9921 	if (QDF_IS_STATUS_SUCCESS(status)) {
9922 		mac->sme.link_layer_stats_cb = callback;
9923 		sme_release_global_lock(&mac->sme);
9924 	} else {
9925 		sme_err("sme_acquire_global_lock error");
9926 	}
9927 
9928 	return status;
9929 }
9930 
9931 /**
9932  * sme_set_link_layer_ext_cb() - Register callback for link layer statistics
9933  * @mac_handle: Mac global handle
9934  * @ll_stats_ext_cb: HDD callback which needs to be invoked after getting
9935  *                   status notification from FW
9936  *
9937  * Return: QDF_STATUS
9938  */
9939 QDF_STATUS
sme_set_link_layer_ext_cb(mac_handle_t mac_handle,void (* ll_stats_ext_cb)(hdd_handle_t callback_ctx,tSirLLStatsResults * rsp))9940 sme_set_link_layer_ext_cb(mac_handle_t mac_handle,
9941 			  void (*ll_stats_ext_cb)(hdd_handle_t callback_ctx,
9942 						  tSirLLStatsResults *rsp))
9943 {
9944 	QDF_STATUS status;
9945 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
9946 
9947 	status = sme_acquire_global_lock(&mac->sme);
9948 	if (status == QDF_STATUS_SUCCESS) {
9949 		mac->sme.link_layer_stats_ext_cb = ll_stats_ext_cb;
9950 		sme_release_global_lock(&mac->sme);
9951 	} else
9952 		sme_err("sme_qcquire_global_lock error");
9953 	return status;
9954 }
9955 
9956 /**
9957  * sme_reset_link_layer_stats_ind_cb() - SME API to reset link layer stats
9958  *					 indication
9959  * @mac_handle: Opaque handle to the global MAC context
9960  *
9961  * This function reset's the link layer stats indication
9962  *
9963  * Return: QDF_STATUS Enumeration
9964  */
9965 
sme_reset_link_layer_stats_ind_cb(mac_handle_t mac_handle)9966 QDF_STATUS sme_reset_link_layer_stats_ind_cb(mac_handle_t mac_handle)
9967 {
9968 	QDF_STATUS status;
9969 	struct mac_context *pmac;
9970 
9971 	if (!mac_handle) {
9972 		sme_err("mac_handle is not valid");
9973 		return QDF_STATUS_E_INVAL;
9974 	}
9975 	pmac = MAC_CONTEXT(mac_handle);
9976 
9977 	status = sme_acquire_global_lock(&pmac->sme);
9978 	if (QDF_IS_STATUS_SUCCESS(status)) {
9979 		pmac->sme.link_layer_stats_cb = NULL;
9980 		sme_release_global_lock(&pmac->sme);
9981 	} else
9982 		sme_err("sme_acquire_global_lock error");
9983 
9984 	return status;
9985 }
9986 
9987 /**
9988  * sme_ll_stats_set_thresh - set threshold for mac counters
9989  * @mac_handle: Opaque handle to the global MAC context
9990  * @threshold, threshold for mac counters
9991  *
9992  * Return: QDF_STATUS Enumeration
9993  */
sme_ll_stats_set_thresh(mac_handle_t mac_handle,struct sir_ll_ext_stats_threshold * threshold)9994 QDF_STATUS sme_ll_stats_set_thresh(mac_handle_t mac_handle,
9995 				   struct sir_ll_ext_stats_threshold *threshold)
9996 {
9997 	QDF_STATUS status;
9998 	struct scheduler_msg message = {0};
9999 	struct sir_ll_ext_stats_threshold *thresh;
10000 
10001 	if (!threshold) {
10002 		sme_err("threshold is not valid");
10003 		return QDF_STATUS_E_INVAL;
10004 	}
10005 
10006 	if (!mac_handle) {
10007 		sme_err("mac_handle is not valid");
10008 		return QDF_STATUS_E_INVAL;
10009 	}
10010 
10011 	thresh = qdf_mem_malloc(sizeof(*thresh));
10012 	if (!thresh)
10013 		return QDF_STATUS_E_NOMEM;
10014 
10015 	*thresh = *threshold;
10016 
10017 	/* Serialize the req through MC thread */
10018 	message.bodyptr = thresh;
10019 	message.type    = WDA_LINK_LAYER_STATS_SET_THRESHOLD;
10020 	MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG,
10021 			 NO_SESSION, message.type));
10022 	status = scheduler_post_message(QDF_MODULE_ID_SME,
10023 					QDF_MODULE_ID_WMA,
10024 					QDF_MODULE_ID_WMA, &message);
10025 	if (QDF_IS_STATUS_ERROR(status)) {
10026 		sme_err("not able to post WDA_LL_STATS_GET_REQ");
10027 		qdf_mem_free(thresh);
10028 	}
10029 
10030 	return status;
10031 }
10032 
10033 #endif /* WLAN_FEATURE_LINK_LAYER_STATS */
10034 
10035 #ifdef WLAN_POWER_DEBUG
sme_reset_power_debug_stats_cb(mac_handle_t mac_handle)10036 void sme_reset_power_debug_stats_cb(mac_handle_t mac_handle)
10037 {
10038 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
10039 	QDF_STATUS status = QDF_STATUS_SUCCESS;
10040 
10041 	status = sme_acquire_global_lock(&mac_ctx->sme);
10042 	if (QDF_IS_STATUS_SUCCESS(status)) {
10043 		mac_ctx->sme.power_debug_stats_context = NULL;
10044 		mac_ctx->sme.power_stats_resp_callback = NULL;
10045 		sme_release_global_lock(&mac_ctx->sme);
10046 	}
10047 }
10048 
sme_power_debug_stats_req(mac_handle_t mac_handle,void (* callback_fn)(struct power_stats_response * response,void * context),void * power_stats_context)10049 QDF_STATUS sme_power_debug_stats_req(
10050 		mac_handle_t mac_handle,
10051 		void (*callback_fn)(struct power_stats_response *response,
10052 				    void *context),
10053 		void *power_stats_context)
10054 {
10055 	QDF_STATUS status = QDF_STATUS_SUCCESS;
10056 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
10057 	struct scheduler_msg msg = {0};
10058 
10059 	status = sme_acquire_global_lock(&mac_ctx->sme);
10060 	if (QDF_IS_STATUS_SUCCESS(status)) {
10061 		if (!callback_fn) {
10062 			sme_err("Indication callback did not registered");
10063 			sme_release_global_lock(&mac_ctx->sme);
10064 			return QDF_STATUS_E_FAILURE;
10065 		}
10066 
10067 		if (mac_ctx->sme.power_debug_stats_context ||
10068 		    mac_ctx->sme.power_stats_resp_callback) {
10069 			sme_err("Already one power stats req in progress");
10070 			sme_release_global_lock(&mac_ctx->sme);
10071 			return QDF_STATUS_E_ALREADY;
10072 		}
10073 		mac_ctx->sme.power_debug_stats_context = power_stats_context;
10074 		mac_ctx->sme.power_stats_resp_callback = callback_fn;
10075 		msg.bodyptr = NULL;
10076 		msg.type = WMA_POWER_DEBUG_STATS_REQ;
10077 		status = scheduler_post_message(QDF_MODULE_ID_SME,
10078 						QDF_MODULE_ID_WMA,
10079 						QDF_MODULE_ID_WMA, &msg);
10080 		if (!QDF_IS_STATUS_SUCCESS(status))
10081 			sme_err("not able to post WDA_POWER_DEBUG_STATS_REQ");
10082 		sme_release_global_lock(&mac_ctx->sme);
10083 	}
10084 	return status;
10085 }
10086 #endif
10087 
10088 #ifdef WLAN_FEATURE_BEACON_RECEPTION_STATS
sme_beacon_debug_stats_req(mac_handle_t mac_handle,uint32_t vdev_id,void (* callback_fn)(struct bcn_reception_stats_rsp * response,void * context),void * beacon_stats_context)10089 QDF_STATUS sme_beacon_debug_stats_req(
10090 		mac_handle_t mac_handle, uint32_t vdev_id,
10091 		void (*callback_fn)(struct bcn_reception_stats_rsp
10092 				    *response, void *context),
10093 		void *beacon_stats_context)
10094 {
10095 	QDF_STATUS status;
10096 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
10097 	uint32_t *val;
10098 	struct scheduler_msg msg = {0};
10099 
10100 	status = sme_acquire_global_lock(&mac_ctx->sme);
10101 	if (QDF_IS_STATUS_SUCCESS(status)) {
10102 		if (!callback_fn) {
10103 			sme_err("Indication callback did not registered");
10104 			sme_release_global_lock(&mac_ctx->sme);
10105 			return QDF_STATUS_E_FAILURE;
10106 		}
10107 
10108 		if (!mac_ctx->bcn_reception_stats &&
10109 		    !mac_ctx->mlme_cfg->gen.enable_beacon_reception_stats) {
10110 			sme_err("Beacon Reception stats not supported");
10111 			sme_release_global_lock(&mac_ctx->sme);
10112 			return QDF_STATUS_E_NOSUPPORT;
10113 		}
10114 
10115 		val = qdf_mem_malloc(sizeof(*val));
10116 		if (!val) {
10117 			sme_release_global_lock(&mac_ctx->sme);
10118 			return QDF_STATUS_E_NOMEM;
10119 		}
10120 
10121 		*val = vdev_id;
10122 		mac_ctx->sme.beacon_stats_context = beacon_stats_context;
10123 		mac_ctx->sme.beacon_stats_resp_callback = callback_fn;
10124 		msg.bodyptr = val;
10125 		msg.type = WMA_BEACON_DEBUG_STATS_REQ;
10126 		status = scheduler_post_message(QDF_MODULE_ID_SME,
10127 						QDF_MODULE_ID_WMA,
10128 						QDF_MODULE_ID_WMA, &msg);
10129 		if (!QDF_IS_STATUS_SUCCESS(status)) {
10130 			sme_err("not able to post WMA_BEACON_DEBUG_STATS_REQ");
10131 			qdf_mem_free(val);
10132 		}
10133 		sme_release_global_lock(&mac_ctx->sme);
10134 	}
10135 	return status;
10136 }
10137 #endif
10138 
10139 /**
10140  * sme_get_temperature() - SME API to get the pdev temperature
10141  * @mac_handle: Handle to global MAC context
10142  * @cb_context: temperature callback context
10143  * @cb: callback function with response (temperature)
10144  * Return: QDF_STATUS
10145  */
sme_get_temperature(mac_handle_t mac_handle,void * cb_context,void (* cb)(int temperature,void * context))10146 QDF_STATUS sme_get_temperature(mac_handle_t mac_handle,
10147 			       void *cb_context,
10148 			       void (*cb)(int temperature,
10149 					  void *context))
10150 {
10151 	QDF_STATUS status = QDF_STATUS_SUCCESS;
10152 	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
10153 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
10154 	struct scheduler_msg message = {0};
10155 
10156 	status = sme_acquire_global_lock(&mac->sme);
10157 	if (QDF_STATUS_SUCCESS == status) {
10158 		if ((!cb) &&
10159 		    (!mac->sme.temperature_cb)) {
10160 			sme_err("Indication Call back did not registered");
10161 			sme_release_global_lock(&mac->sme);
10162 			return QDF_STATUS_E_FAILURE;
10163 		} else if (cb) {
10164 			mac->sme.temperature_cb_context = cb_context;
10165 			mac->sme.temperature_cb = cb;
10166 		}
10167 		/* serialize the req through MC thread */
10168 		message.bodyptr = NULL;
10169 		message.type = WMA_GET_TEMPERATURE_REQ;
10170 		qdf_status = scheduler_post_message(QDF_MODULE_ID_SME,
10171 						    QDF_MODULE_ID_WMA,
10172 						    QDF_MODULE_ID_WMA,
10173 						    &message);
10174 		if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
10175 			sme_err("Post Get Temperature msg fail");
10176 			status = QDF_STATUS_E_FAILURE;
10177 		}
10178 		sme_release_global_lock(&mac->sme);
10179 	}
10180 	return status;
10181 }
10182 
sme_set_scanning_mac_oui(mac_handle_t mac_handle,struct scan_mac_oui * scan_mac_oui)10183 QDF_STATUS sme_set_scanning_mac_oui(mac_handle_t mac_handle,
10184 				    struct scan_mac_oui *scan_mac_oui)
10185 {
10186 	QDF_STATUS status = QDF_STATUS_SUCCESS;
10187 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
10188 	struct scheduler_msg message = {0};
10189 	struct scan_mac_oui *bodyptr;
10190 
10191 	/* per contract must make a copy of the params when messaging */
10192 	bodyptr = qdf_mem_malloc(sizeof(*bodyptr));
10193 	if (!bodyptr)
10194 		return QDF_STATUS_E_NOMEM;
10195 	*bodyptr = *scan_mac_oui;
10196 
10197 	status = sme_acquire_global_lock(&mac->sme);
10198 	if (QDF_STATUS_SUCCESS == status) {
10199 		/* Serialize the req through MC thread */
10200 		message.bodyptr = bodyptr;
10201 		message.type = WMA_SET_SCAN_MAC_OUI_REQ;
10202 		status = scheduler_post_message(QDF_MODULE_ID_SME,
10203 						QDF_MODULE_ID_WMA,
10204 						QDF_MODULE_ID_WMA,
10205 						&message);
10206 		sme_release_global_lock(&mac->sme);
10207 	}
10208 
10209 	if (QDF_IS_STATUS_ERROR(status)) {
10210 		sme_err("failure: %d", status);
10211 		qdf_mem_free(bodyptr);
10212 	}
10213 
10214 	return status;
10215 }
10216 
10217 #ifdef DHCP_SERVER_OFFLOAD
10218 QDF_STATUS
sme_set_dhcp_srv_offload(mac_handle_t mac_handle,struct dhcp_offload_info_params * dhcp_srv_info)10219 sme_set_dhcp_srv_offload(mac_handle_t mac_handle,
10220 			 struct dhcp_offload_info_params *dhcp_srv_info)
10221 {
10222 	struct scheduler_msg message = {0};
10223 	struct dhcp_offload_info_params *payload;
10224 	QDF_STATUS status = QDF_STATUS_SUCCESS;
10225 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
10226 
10227 	payload = qdf_mem_malloc(sizeof(*payload));
10228 	if (!payload)
10229 		return QDF_STATUS_E_NOMEM;
10230 
10231 	*payload = *dhcp_srv_info;
10232 
10233 	status = sme_acquire_global_lock(&mac->sme);
10234 	if (QDF_STATUS_SUCCESS == status) {
10235 		/* serialize the req through MC thread */
10236 		message.type = WMA_SET_DHCP_SERVER_OFFLOAD_CMD;
10237 		message.bodyptr = payload;
10238 
10239 		if (!QDF_IS_STATUS_SUCCESS
10240 			    (scheduler_post_message(QDF_MODULE_ID_SME,
10241 						    QDF_MODULE_ID_WMA,
10242 						    QDF_MODULE_ID_WMA,
10243 						    &message))) {
10244 			sme_err("WMA_SET_DHCP_SERVER_OFFLOAD_CMD failed");
10245 			qdf_mem_free(payload);
10246 			status = QDF_STATUS_E_FAILURE;
10247 		}
10248 		sme_release_global_lock(&mac->sme);
10249 	} else {
10250 		sme_err("sme_acquire_global_lock error!");
10251 		qdf_mem_free(payload);
10252 	}
10253 
10254 	return status;
10255 }
10256 #endif /* DHCP_SERVER_OFFLOAD */
10257 
sme_send_unit_test_cmd(uint32_t vdev_id,uint32_t module_id,uint32_t arg_count,uint32_t * arg)10258 QDF_STATUS sme_send_unit_test_cmd(uint32_t vdev_id, uint32_t module_id,
10259 				  uint32_t arg_count, uint32_t *arg)
10260 {
10261 	return wma_form_unit_test_cmd_and_send(vdev_id, module_id,
10262 					       arg_count, arg);
10263 }
10264 
10265 #ifdef WLAN_FEATURE_GPIO_LED_FLASHING
10266 /*
10267  * sme_set_led_flashing() -
10268  * API to set the Led flashing parameters.
10269  *
10270  * mac_handle - The handle returned by mac_open.
10271  * x0, x1 -  led flashing parameters
10272  * Return QDF_STATUS
10273  */
sme_set_led_flashing(mac_handle_t mac_handle,uint8_t type,uint32_t x0,uint32_t x1)10274 QDF_STATUS sme_set_led_flashing(mac_handle_t mac_handle, uint8_t type,
10275 				uint32_t x0, uint32_t x1)
10276 {
10277 	QDF_STATUS status;
10278 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
10279 	struct scheduler_msg message = {0};
10280 	struct flashing_req_params *ledflashing;
10281 
10282 	ledflashing = qdf_mem_malloc(sizeof(*ledflashing));
10283 	if (!ledflashing)
10284 		return QDF_STATUS_E_NOMEM;
10285 
10286 	ledflashing->req_id = 0;
10287 	ledflashing->pattern_id = type;
10288 	ledflashing->led_x0 = x0;
10289 	ledflashing->led_x1 = x1;
10290 
10291 	status = sme_acquire_global_lock(&mac->sme);
10292 	if (QDF_IS_STATUS_SUCCESS(status)) {
10293 		/* Serialize the req through MC thread */
10294 		message.bodyptr = ledflashing;
10295 		message.type = WMA_LED_FLASHING_REQ;
10296 		status = scheduler_post_message(QDF_MODULE_ID_SME,
10297 						QDF_MODULE_ID_WMA,
10298 						QDF_MODULE_ID_WMA, &message);
10299 		sme_release_global_lock(&mac->sme);
10300 	}
10301 	if (!QDF_IS_STATUS_SUCCESS(status))
10302 		qdf_mem_free(ledflashing);
10303 
10304 	return status;
10305 }
10306 #endif
10307 
10308 /**
10309  *  sme_enable_dfS_chan_scan() - set DFS channel scan enable/disable
10310  *  @mac_handle:         corestack handler
10311  *  @dfs_flag:      flag indicating dfs channel enable/disable
10312  *  Return:         QDF_STATUS
10313  */
sme_enable_dfs_chan_scan(mac_handle_t mac_handle,uint8_t dfs_flag)10314 QDF_STATUS sme_enable_dfs_chan_scan(mac_handle_t mac_handle, uint8_t dfs_flag)
10315 {
10316 	QDF_STATUS status = QDF_STATUS_SUCCESS;
10317 	struct mac_context *mac;
10318 
10319 	if (!mac_handle) {
10320 		sme_err("mac_handle is NULL");
10321 		return QDF_STATUS_E_INVAL;
10322 	}
10323 
10324 	mac = MAC_CONTEXT(mac_handle);
10325 
10326 	mac->scan.fEnableDFSChnlScan = dfs_flag;
10327 
10328 	return status;
10329 }
10330 
10331 #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
10332 /**
10333  * sme_validate_sap_channel_switch() - validate target channel switch w.r.t
10334  *      concurreny rules set to avoid channel interference.
10335  * @mac_handle: Opaque handle to the global MAC context
10336  * @sap_ch - channel to switch
10337  * @sap_phy_mode - phy mode of SAP
10338  * @cc_switch_mode - concurreny switch mode
10339  * @vdev_id - vdev id.
10340  *
10341  * Return: true if there is no channel interference else return false
10342  */
sme_validate_sap_channel_switch(mac_handle_t mac_handle,uint32_t sap_ch_freq,eCsrPhyMode sap_phy_mode,uint8_t cc_switch_mode,uint8_t vdev_id)10343 bool sme_validate_sap_channel_switch(mac_handle_t mac_handle,
10344 				     uint32_t sap_ch_freq,
10345 				     eCsrPhyMode sap_phy_mode,
10346 				     uint8_t cc_switch_mode,
10347 				     uint8_t vdev_id)
10348 {
10349 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
10350 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
10351 	struct csr_roam_session *session = CSR_GET_SESSION(mac, vdev_id);
10352 	uint16_t intf_channel_freq = 0;
10353 
10354 	if (!session)
10355 		return false;
10356 
10357 	session->ch_switch_in_progress = true;
10358 	status = sme_acquire_global_lock(&mac->sme);
10359 	if (QDF_IS_STATUS_SUCCESS(status)) {
10360 		intf_channel_freq = csr_check_concurrent_channel_overlap(
10361 			mac, sap_ch_freq, sap_phy_mode, cc_switch_mode,
10362 			vdev_id);
10363 		sme_release_global_lock(&mac->sme);
10364 	} else {
10365 		sme_err("sme_acquire_global_lock error!");
10366 		session->ch_switch_in_progress = false;
10367 		return false;
10368 	}
10369 
10370 	session->ch_switch_in_progress = false;
10371 	return (intf_channel_freq == 0) ? true : false;
10372 }
10373 #endif
10374 
10375 /**
10376  * sme_configure_stats_avg_factor() - function to config avg. stats factor
10377  * @mac_handle: Opaque handle to the global MAC context
10378  * @session_id: session ID
10379  * @stats_avg_factor: average stats factor
10380  *
10381  * This function configures the stats avg factor in firmware
10382  *
10383  * Return: QDF_STATUS
10384  */
sme_configure_stats_avg_factor(mac_handle_t mac_handle,uint8_t session_id,uint16_t stats_avg_factor)10385 QDF_STATUS sme_configure_stats_avg_factor(mac_handle_t mac_handle,
10386 					  uint8_t session_id,
10387 					  uint16_t stats_avg_factor)
10388 {
10389 	struct scheduler_msg msg = {0};
10390 	QDF_STATUS status = QDF_STATUS_SUCCESS;
10391 	struct mac_context *mac  = MAC_CONTEXT(mac_handle);
10392 	struct sir_stats_avg_factor *stats_factor;
10393 
10394 	stats_factor = qdf_mem_malloc(sizeof(*stats_factor));
10395 	if (!stats_factor)
10396 		return QDF_STATUS_E_NOMEM;
10397 
10398 	status = sme_acquire_global_lock(&mac->sme);
10399 
10400 	if (QDF_STATUS_SUCCESS == status) {
10401 
10402 		stats_factor->vdev_id = session_id;
10403 		stats_factor->stats_avg_factor = stats_avg_factor;
10404 
10405 		/* serialize the req through MC thread */
10406 		msg.type     = SIR_HAL_CONFIG_STATS_FACTOR;
10407 		msg.bodyptr  = stats_factor;
10408 
10409 		if (!QDF_IS_STATUS_SUCCESS(
10410 			    scheduler_post_message(QDF_MODULE_ID_SME,
10411 						   QDF_MODULE_ID_WMA,
10412 						   QDF_MODULE_ID_WMA, &msg))) {
10413 			sme_err("Not able to post SIR_HAL_CONFIG_STATS_FACTOR to WMA!");
10414 			qdf_mem_free(stats_factor);
10415 			status = QDF_STATUS_E_FAILURE;
10416 		}
10417 		sme_release_global_lock(&mac->sme);
10418 	} else {
10419 		sme_err("sme_acquire_global_lock error!");
10420 		qdf_mem_free(stats_factor);
10421 	}
10422 
10423 	return status;
10424 }
10425 
10426 /**
10427  * sme_configure_guard_time() - function to configure guard time
10428  * @mac_handle: Opaque handle to the global MAC context
10429  * @session_id: session id
10430  * @guard_time: guard time
10431  *
10432  * This function configures the guard time in firmware
10433  *
10434  * Return: QDF_STATUS
10435  */
sme_configure_guard_time(mac_handle_t mac_handle,uint8_t session_id,uint32_t guard_time)10436 QDF_STATUS sme_configure_guard_time(mac_handle_t mac_handle, uint8_t session_id,
10437 				    uint32_t guard_time)
10438 {
10439 	struct scheduler_msg msg = {0};
10440 	QDF_STATUS status = QDF_STATUS_SUCCESS;
10441 	struct mac_context *mac  = MAC_CONTEXT(mac_handle);
10442 	struct sir_guard_time_request *g_time;
10443 
10444 	g_time = qdf_mem_malloc(sizeof(*g_time));
10445 	if (!g_time)
10446 		return QDF_STATUS_E_NOMEM;
10447 
10448 	status = sme_acquire_global_lock(&mac->sme);
10449 
10450 	if (QDF_STATUS_SUCCESS == status) {
10451 
10452 		g_time->vdev_id = session_id;
10453 		g_time->guard_time = guard_time;
10454 
10455 		/* serialize the req through MC thread */
10456 		msg.type     = SIR_HAL_CONFIG_GUARD_TIME;
10457 		msg.bodyptr  = g_time;
10458 
10459 		if (!QDF_IS_STATUS_SUCCESS(
10460 			    scheduler_post_message(QDF_MODULE_ID_SME,
10461 						   QDF_MODULE_ID_WMA,
10462 						   QDF_MODULE_ID_WMA, &msg))) {
10463 			sme_err("Not able to post SIR_HAL_CONFIG_GUARD_TIME to WMA!");
10464 			qdf_mem_free(g_time);
10465 			status = QDF_STATUS_E_FAILURE;
10466 		}
10467 		sme_release_global_lock(&mac->sme);
10468 	} else {
10469 		sme_err("sme_acquire_global_lock error!");
10470 		qdf_mem_free(g_time);
10471 	}
10472 
10473 	return status;
10474 }
10475 
10476 /*
10477  * sme_wifi_start_logger() - Send the start/stop logging command to WMA
10478  * to either start/stop logging
10479  * @mac_handle: Opaque handle to the global MAC context
10480  * @start_log: Structure containing the wifi start logger params
10481  *
10482  * This function sends the start/stop logging command to WMA
10483  *
10484  * Return: QDF_STATUS_SUCCESS on successful posting
10485  */
sme_wifi_start_logger(mac_handle_t mac_handle,struct sir_wifi_start_log start_log)10486 QDF_STATUS sme_wifi_start_logger(mac_handle_t mac_handle,
10487 				 struct sir_wifi_start_log start_log)
10488 {
10489 	QDF_STATUS status = QDF_STATUS_SUCCESS;
10490 	struct scheduler_msg message = {0};
10491 	struct sir_wifi_start_log *req_msg;
10492 	uint32_t len;
10493 
10494 	len = sizeof(*req_msg);
10495 	req_msg = qdf_mem_malloc(len);
10496 	if (!req_msg)
10497 		return QDF_STATUS_E_NOMEM;
10498 
10499 	req_msg->verbose_level = start_log.verbose_level;
10500 	req_msg->is_iwpriv_command = start_log.is_iwpriv_command;
10501 	req_msg->ring_id = start_log.ring_id;
10502 	req_msg->ini_triggered = start_log.ini_triggered;
10503 	req_msg->user_triggered = start_log.user_triggered;
10504 	req_msg->size = start_log.size;
10505 	req_msg->is_pktlog_buff_clear = start_log.is_pktlog_buff_clear;
10506 
10507 	message.bodyptr = req_msg;
10508 	message.type    = SIR_HAL_START_STOP_LOGGING;
10509 	status = scheduler_post_message(QDF_MODULE_ID_SME,
10510 					QDF_MODULE_ID_WMA,
10511 					QDF_MODULE_ID_WMA, &message);
10512 	if (!QDF_IS_STATUS_SUCCESS(status)) {
10513 		sme_err("scheduler_post_msg failed!(err=%d)", status);
10514 		qdf_mem_free(req_msg);
10515 		status = QDF_STATUS_E_FAILURE;
10516 	}
10517 
10518 	return status;
10519 }
10520 
sme_is_any_session_in_middle_of_roaming(mac_handle_t mac_handle)10521 bool sme_is_any_session_in_middle_of_roaming(mac_handle_t mac_handle)
10522 {
10523 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
10524 	uint8_t session_id;
10525 
10526 	for (session_id = 0; session_id < WLAN_MAX_VDEVS; session_id++) {
10527 		if (CSR_IS_SESSION_VALID(mac_ctx, session_id) &&
10528 		    wlan_cm_host_roam_in_progress(mac_ctx->psoc, session_id))
10529 			return true;
10530 	}
10531 
10532 	return false;
10533 }
10534 
10535 /*
10536  * sme_send_flush_logs_cmd_to_fw() - Flush FW logs
10537  *
10538  * This function is used to send the command that will
10539  * be used to flush the logs in the firmware
10540  *
10541  * Return: QDF_STATUS
10542  */
sme_send_flush_logs_cmd_to_fw(void)10543 QDF_STATUS sme_send_flush_logs_cmd_to_fw(void)
10544 {
10545 	QDF_STATUS status;
10546 	struct scheduler_msg message = {0};
10547 
10548 	/* Serialize the req through MC thread */
10549 	message.bodyptr = NULL;
10550 	message.type    = SIR_HAL_FLUSH_LOG_TO_FW;
10551 	status = scheduler_post_message(QDF_MODULE_ID_SME,
10552 					QDF_MODULE_ID_WMA,
10553 					QDF_MODULE_ID_WMA, &message);
10554 	if (!QDF_IS_STATUS_SUCCESS(status)) {
10555 		sme_err("scheduler_post_msg failed!(err=%d)", status);
10556 		status = QDF_STATUS_E_FAILURE;
10557 	}
10558 	return status;
10559 }
10560 
sme_enable_uapsd_for_ac(sme_ac_enum_type ac,uint8_t tid,uint8_t pri,uint32_t srvc_int,uint32_t sus_int,enum sme_qos_wmm_dir_type dir,uint8_t psb,uint32_t sessionId,uint32_t delay_interval)10561 QDF_STATUS sme_enable_uapsd_for_ac(sme_ac_enum_type ac, uint8_t tid,
10562 				   uint8_t pri, uint32_t srvc_int,
10563 				   uint32_t sus_int,
10564 				   enum sme_qos_wmm_dir_type dir,
10565 				   uint8_t psb, uint32_t sessionId,
10566 				   uint32_t delay_interval)
10567 {
10568 	void *wma_handle;
10569 	t_wma_trigger_uapsd_params uapsd_params;
10570 	enum uapsd_ac access_category;
10571 
10572 	if (!psb) {
10573 		sme_debug("No need to configure auto trigger:psb is 0");
10574 		return QDF_STATUS_SUCCESS;
10575 	}
10576 
10577 	wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
10578 	if (!wma_handle)
10579 		return QDF_STATUS_E_FAILURE;
10580 
10581 	switch (ac) {
10582 	case SME_AC_BK:
10583 		access_category = UAPSD_BK;
10584 		break;
10585 	case SME_AC_BE:
10586 		access_category = UAPSD_BE;
10587 		break;
10588 	case SME_AC_VI:
10589 		access_category = UAPSD_VI;
10590 		break;
10591 	case SME_AC_VO:
10592 		access_category = UAPSD_VO;
10593 		break;
10594 	default:
10595 		return QDF_STATUS_E_FAILURE;
10596 	}
10597 
10598 	uapsd_params.wmm_ac = access_category;
10599 	uapsd_params.user_priority = pri;
10600 	uapsd_params.service_interval = srvc_int;
10601 	uapsd_params.delay_interval = delay_interval;
10602 	uapsd_params.suspend_interval = sus_int;
10603 
10604 	if (QDF_STATUS_SUCCESS !=
10605 	    wma_trigger_uapsd_params(wma_handle, sessionId, &uapsd_params)) {
10606 		sme_err("Failed to Trigger Uapsd params for vdev %d",
10607 			sessionId);
10608 		return QDF_STATUS_E_FAILURE;
10609 	}
10610 	return QDF_STATUS_SUCCESS;
10611 }
10612 
sme_disable_uapsd_for_ac(sme_ac_enum_type ac,uint32_t sessionId)10613 QDF_STATUS sme_disable_uapsd_for_ac(sme_ac_enum_type ac, uint32_t sessionId)
10614 {
10615 	void *wma_handle;
10616 	enum uapsd_ac access_category;
10617 
10618 	switch (ac) {
10619 	case SME_AC_BK:
10620 		access_category = UAPSD_BK;
10621 		break;
10622 	case SME_AC_BE:
10623 		access_category = UAPSD_BE;
10624 		break;
10625 	case SME_AC_VI:
10626 		access_category = UAPSD_VI;
10627 		break;
10628 	case SME_AC_VO:
10629 		access_category = UAPSD_VO;
10630 		break;
10631 	default:
10632 		return QDF_STATUS_E_FAILURE;
10633 	}
10634 
10635 	wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
10636 	if (!wma_handle)
10637 		return QDF_STATUS_E_FAILURE;
10638 
10639 	if (QDF_STATUS_SUCCESS !=
10640 	    wma_disable_uapsd_per_ac(wma_handle, sessionId, access_category)) {
10641 		sme_err("Failed to disable uapsd for ac %d for vdev %d",
10642 			ac, sessionId);
10643 		return QDF_STATUS_E_FAILURE;
10644 	}
10645 	return QDF_STATUS_SUCCESS;
10646 }
10647 
sme_vdev_ht_tx_stbc(struct mac_context * mac_ctx,bool ht_tx_stbc,uint8_t vdev_id)10648 static void sme_vdev_ht_tx_stbc(struct mac_context *mac_ctx,
10649 				bool ht_tx_stbc, uint8_t vdev_id)
10650 {
10651 	struct wlan_objmgr_vdev *vdev;
10652 	struct vdev_mlme_obj *vdev_mlme;
10653 	struct wlan_ht_config ht_cap_info;
10654 
10655 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac_ctx->psoc, vdev_id,
10656 						    WLAN_LEGACY_SME_ID);
10657 	if (!vdev)
10658 		return;
10659 	vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev);
10660 	if (!vdev_mlme) {
10661 		wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID);
10662 		return;
10663 	}
10664 	ht_cap_info.caps = vdev_mlme->proto.ht_info.ht_caps;
10665 
10666 	ht_cap_info.ht_caps.tx_stbc = ht_tx_stbc;
10667 	vdev_mlme->proto.ht_info.ht_caps = ht_cap_info.caps;
10668 	wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID);
10669 }
10670 
10671 /**
10672  * sme_update_nss() - SME API to change the number for spatial streams
10673  * (1 or 2)
10674  * @mac_handle: Handle returned by mac open
10675  * @nss: Number of spatial streams
10676  *
10677  * This function is used to update the number of spatial streams supported.
10678  *
10679  * Return: Success upon successfully changing nss else failure
10680  *
10681  */
sme_update_nss(mac_handle_t mac_handle,uint8_t nss)10682 QDF_STATUS sme_update_nss(mac_handle_t mac_handle, uint8_t nss)
10683 {
10684 	QDF_STATUS status;
10685 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
10686 	uint32_t i;
10687 	struct mlme_ht_capabilities_info *ht_cap_info;
10688 	struct mlme_vht_capabilities_info *vht_cap_info;
10689 
10690 	vht_cap_info = &mac_ctx->mlme_cfg->vht_caps.vht_cap_info;
10691 
10692 	status = sme_acquire_global_lock(&mac_ctx->sme);
10693 
10694 	if (QDF_STATUS_SUCCESS == status) {
10695 		vht_cap_info->enable2x2 = (nss == 1) ? 0 : 1;
10696 
10697 		/* get the HT capability info*/
10698 		ht_cap_info = &mac_ctx->mlme_cfg->ht_caps.ht_cap_info;
10699 
10700 		for (i = 0; i < WLAN_MAX_VDEVS; i++) {
10701 			if (CSR_IS_SESSION_VALID(mac_ctx, i)) {
10702 				sme_vdev_ht_tx_stbc(mac_ctx,
10703 						    ht_cap_info->tx_stbc, i);
10704 			}
10705 		}
10706 
10707 		sme_release_global_lock(&mac_ctx->sme);
10708 	}
10709 	return status;
10710 }
10711 
10712 /**
10713  * sme_update_user_configured_nss() - sets the nss based on user request
10714  * @mac_handle: Opaque handle to the global MAC context
10715  * @nss: number of streams
10716  *
10717  * Return: None
10718  */
sme_update_user_configured_nss(mac_handle_t mac_handle,uint8_t nss)10719 void sme_update_user_configured_nss(mac_handle_t mac_handle, uint8_t nss)
10720 {
10721 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
10722 
10723 	mac_ctx->user_configured_nss = nss;
10724 }
10725 
sme_update_tx_bfee_supp(mac_handle_t mac_handle,uint8_t session_id,uint8_t cfg_val)10726 int sme_update_tx_bfee_supp(mac_handle_t mac_handle, uint8_t session_id,
10727 			    uint8_t cfg_val)
10728 {
10729 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
10730 
10731 	mac_ctx->mlme_cfg->vht_caps.vht_cap_info.su_bformee = cfg_val;
10732 
10733 	return sme_update_he_tx_bfee_supp(mac_handle, session_id, cfg_val);
10734 }
10735 
sme_update_tx_bfee_nsts(mac_handle_t mac_handle,uint8_t session_id,uint8_t usr_cfg_val,uint8_t nsts_val)10736 int sme_update_tx_bfee_nsts(mac_handle_t mac_handle, uint8_t session_id,
10737 			    uint8_t usr_cfg_val, uint8_t nsts_val)
10738 {
10739 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
10740 	uint8_t nsts_set_val;
10741 	struct mlme_vht_capabilities_info *vht_cap_info;
10742 
10743 	vht_cap_info = &mac_ctx->mlme_cfg->vht_caps.vht_cap_info;
10744 	mac_ctx->usr_cfg_tx_bfee_nsts = usr_cfg_val;
10745 	if (usr_cfg_val)
10746 		nsts_set_val = usr_cfg_val;
10747 	else
10748 		nsts_set_val = nsts_val;
10749 
10750 	vht_cap_info->tx_bfee_ant_supp = nsts_set_val;
10751 
10752 	if (usr_cfg_val)
10753 		sme_set_he_tx_bf_cbf_rates(session_id);
10754 
10755 	return sme_update_he_tx_bfee_nsts(mac_handle, session_id, nsts_set_val);
10756 }
10757 
10758 #ifdef WLAN_FEATURE_11BE
sme_update_tgt_eht_cap(mac_handle_t mac_handle,struct wma_tgt_cfg * cfg,tDot11fIEeht_cap * eht_cap_ini)10759 void sme_update_tgt_eht_cap(mac_handle_t mac_handle,
10760 			    struct wma_tgt_cfg *cfg,
10761 			    tDot11fIEeht_cap *eht_cap_ini)
10762 {
10763 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
10764 
10765 	qdf_mem_copy(&mac_ctx->eht_cap_2g,
10766 		     &cfg->eht_cap_2g,
10767 		     sizeof(tDot11fIEeht_cap));
10768 
10769 	qdf_mem_copy(&mac_ctx->eht_cap_5g,
10770 		     &cfg->eht_cap_5g,
10771 		     sizeof(tDot11fIEeht_cap));
10772 
10773 	qdf_mem_copy(&mac_ctx->eht_cap_2g_orig,
10774 		     &mac_ctx->eht_cap_2g,
10775 		     sizeof(tDot11fIEeht_cap));
10776 
10777 	qdf_mem_copy(&mac_ctx->eht_cap_5g_orig,
10778 		     &mac_ctx->eht_cap_5g,
10779 		     sizeof(tDot11fIEeht_cap));
10780 }
10781 
sme_set_eht_bw_cap(mac_handle_t mac_handle,uint8_t vdev_id,enum eSirMacHTChannelWidth chwidth)10782 void sme_set_eht_bw_cap(mac_handle_t mac_handle, uint8_t vdev_id,
10783 			enum eSirMacHTChannelWidth chwidth)
10784 {
10785 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
10786 	struct csr_roam_session *session;
10787 
10788 	session = CSR_GET_SESSION(mac_ctx, vdev_id);
10789 	if (!session) {
10790 		sme_debug("No session for id %d", vdev_id);
10791 		return;
10792 	}
10793 	sme_debug("Config EHT caps for BW %d", chwidth);
10794 	mac_ctx->mlme_cfg->eht_caps.dot11_eht_cap.support_320mhz_6ghz = 0;
10795 
10796 	if (chwidth < eHT_CHANNEL_WIDTH_320MHZ) {
10797 		sme_debug("EHT caps config not required for bw: %d", chwidth);
10798 		return;
10799 	}
10800 
10801 	mac_ctx->mlme_cfg->eht_caps.dot11_eht_cap.support_320mhz_6ghz = 1;
10802 	qdf_mem_copy(&mac_ctx->eht_cap_5g,
10803 		     &mac_ctx->mlme_cfg->eht_caps.dot11_eht_cap,
10804 		     sizeof(tDot11fIEeht_cap));
10805 
10806 	csr_update_session_eht_cap(mac_ctx, session);
10807 }
10808 
sme_update_eht_om_ctrl_supp(mac_handle_t mac_handle,uint8_t session_id,uint8_t cfg_val)10809 int sme_update_eht_om_ctrl_supp(mac_handle_t mac_handle, uint8_t session_id,
10810 				uint8_t cfg_val)
10811 {
10812 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
10813 	struct csr_roam_session *session;
10814 
10815 	session = CSR_GET_SESSION(mac_ctx, session_id);
10816 
10817 	if (!session) {
10818 		sme_err("No session for id %d", session_id);
10819 		return -EINVAL;
10820 	}
10821 	mac_ctx->mlme_cfg->eht_caps.dot11_eht_cap.eht_om_ctl = cfg_val;
10822 	mac_ctx->eht_cap_2g.eht_om_ctl = cfg_val;
10823 	mac_ctx->eht_cap_5g.eht_om_ctl = cfg_val;
10824 
10825 	csr_update_session_eht_cap(mac_ctx, session);
10826 
10827 	return 0;
10828 }
10829 #endif
10830 
10831 #ifdef WLAN_FEATURE_11AX
sme_update_tgt_he_cap(mac_handle_t mac_handle,struct wma_tgt_cfg * cfg,tDot11fIEhe_cap * he_cap_ini)10832 void sme_update_tgt_he_cap(mac_handle_t mac_handle,
10833 			   struct wma_tgt_cfg *cfg,
10834 			   tDot11fIEhe_cap *he_cap_ini)
10835 {
10836 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
10837 
10838 	qdf_mem_copy(&mac_ctx->he_cap_2g,
10839 		     &cfg->he_cap_2g,
10840 		     sizeof(tDot11fIEhe_cap));
10841 
10842 	qdf_mem_copy(&mac_ctx->he_cap_5g,
10843 		     &cfg->he_cap_5g,
10844 		     sizeof(tDot11fIEhe_cap));
10845 
10846 	if (!mac_ctx->mlme_cfg->he_caps.dot11_he_cap.rx_pream_puncturing) {
10847 		sme_debug("feature is disabled via INI, FW caps 2G:%d, 5G:%d",
10848 			  mac_ctx->he_cap_2g.rx_pream_puncturing,
10849 			  mac_ctx->he_cap_5g.rx_pream_puncturing);
10850 
10851 		mac_ctx->he_cap_2g.rx_pream_puncturing = 0;
10852 		mac_ctx->he_cap_5g.rx_pream_puncturing = 0;
10853 	}
10854 
10855 	if (!mac_ctx->mlme_cfg->he_caps.enable_ul_mimo) {
10856 		sme_debug("feature is disabled via INI, FW caps 2G:%d, 5G:%d",
10857 			  mac_ctx->he_cap_2g.ul_mu, mac_ctx->he_cap_5g.ul_mu);
10858 		mac_ctx->he_cap_2g.ul_mu = 0;
10859 		mac_ctx->he_cap_5g.ul_mu = 0;
10860 	}
10861 
10862 	/* modify HE Caps field according to INI setting */
10863 	mac_ctx->he_cap_2g.bfee_sts_lt_80 =
10864 			QDF_MIN(cfg->he_cap_2g.bfee_sts_lt_80,
10865 				he_cap_ini->bfee_sts_lt_80);
10866 
10867 	mac_ctx->he_cap_5g.bfee_sts_lt_80 =
10868 			QDF_MIN(cfg->he_cap_5g.bfee_sts_lt_80,
10869 				he_cap_ini->bfee_sts_lt_80);
10870 
10871 	if (!mac_ctx->mlme_cfg->vht_caps.vht_cap_info.enable2x2) {
10872 		mac_ctx->he_cap_2g.rx_he_mcs_map_lt_80 = HE_SET_MCS_4_NSS(
10873 				mac_ctx->he_cap_2g.rx_he_mcs_map_lt_80,
10874 				HE_MCS_DISABLE, 2);
10875 		mac_ctx->he_cap_2g.tx_he_mcs_map_lt_80 = HE_SET_MCS_4_NSS(
10876 				mac_ctx->he_cap_2g.tx_he_mcs_map_lt_80,
10877 				HE_MCS_DISABLE, 2);
10878 		mac_ctx->he_cap_5g.rx_he_mcs_map_lt_80 = HE_SET_MCS_4_NSS(
10879 				mac_ctx->he_cap_5g.rx_he_mcs_map_lt_80,
10880 				HE_MCS_DISABLE, 2);
10881 		mac_ctx->he_cap_5g.tx_he_mcs_map_lt_80 = HE_SET_MCS_4_NSS(
10882 				mac_ctx->he_cap_5g.tx_he_mcs_map_lt_80,
10883 				HE_MCS_DISABLE, 2);
10884 	}
10885 	mac_ctx->he_cap_2g.rx_he_mcs_map_lt_80 = HE_INTERSECT_MCS(
10886 		mac_ctx->he_cap_2g.rx_he_mcs_map_lt_80,
10887 		mac_ctx->mlme_cfg->he_caps.dot11_he_cap.rx_he_mcs_map_lt_80);
10888 	mac_ctx->he_cap_2g.tx_he_mcs_map_lt_80 = HE_INTERSECT_MCS(
10889 		mac_ctx->he_cap_2g.tx_he_mcs_map_lt_80,
10890 		mac_ctx->mlme_cfg->he_caps.dot11_he_cap.tx_he_mcs_map_lt_80);
10891 	mac_ctx->he_cap_5g.rx_he_mcs_map_lt_80 = HE_INTERSECT_MCS(
10892 		mac_ctx->he_cap_5g.rx_he_mcs_map_lt_80,
10893 		mac_ctx->mlme_cfg->he_caps.dot11_he_cap.rx_he_mcs_map_lt_80);
10894 	mac_ctx->he_cap_5g.tx_he_mcs_map_lt_80 = HE_INTERSECT_MCS(
10895 		mac_ctx->he_cap_5g.tx_he_mcs_map_lt_80,
10896 		mac_ctx->mlme_cfg->he_caps.dot11_he_cap.tx_he_mcs_map_lt_80);
10897 
10898 	qdf_mem_copy(&mac_ctx->he_cap_2g_orig,
10899 		     &mac_ctx->he_cap_2g,
10900 		     sizeof(tDot11fIEhe_cap));
10901 
10902 	qdf_mem_copy(&mac_ctx->he_cap_5g_orig,
10903 		     &mac_ctx->he_cap_5g,
10904 		     sizeof(tDot11fIEhe_cap));
10905 
10906 }
10907 
sme_update_he_cap_nss(mac_handle_t mac_handle,uint8_t session_id,uint8_t nss)10908 void sme_update_he_cap_nss(mac_handle_t mac_handle, uint8_t session_id,
10909 			   uint8_t nss)
10910 {
10911 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
10912 	struct csr_roam_session *csr_session;
10913 	uint32_t tx_mcs_map = 0;
10914 	uint32_t rx_mcs_map = 0;
10915 	uint32_t mcs_map = 0;
10916 
10917 	if (!nss || (nss > 2)) {
10918 		sme_err("invalid Nss value nss %d", nss);
10919 		return;
10920 	}
10921 	csr_session = CSR_GET_SESSION(mac_ctx, session_id);
10922 	if (!csr_session) {
10923 		sme_err("No session for id %d", session_id);
10924 		return;
10925 	}
10926 	rx_mcs_map =
10927 	mac_ctx->mlme_cfg->he_caps.dot11_he_cap.rx_he_mcs_map_lt_80;
10928 	tx_mcs_map =
10929 	mac_ctx->mlme_cfg->he_caps.dot11_he_cap.tx_he_mcs_map_lt_80;
10930 	mcs_map = rx_mcs_map & 0x3;
10931 
10932 	if (nss == 1) {
10933 		tx_mcs_map = HE_SET_MCS_4_NSS(tx_mcs_map, HE_MCS_DISABLE, 2);
10934 		rx_mcs_map = HE_SET_MCS_4_NSS(rx_mcs_map, HE_MCS_DISABLE, 2);
10935 	} else {
10936 		tx_mcs_map = HE_SET_MCS_4_NSS(tx_mcs_map, mcs_map, 2);
10937 		rx_mcs_map = HE_SET_MCS_4_NSS(rx_mcs_map, mcs_map, 2);
10938 	}
10939 	sme_debug("new HE Nss MCS MAP: Rx 0x%0X, Tx: 0x%0X",
10940 		  rx_mcs_map, tx_mcs_map);
10941 	if (cfg_in_range(CFG_HE_RX_MCS_MAP_LT_80, rx_mcs_map))
10942 		mac_ctx->mlme_cfg->he_caps.dot11_he_cap.rx_he_mcs_map_lt_80 =
10943 		rx_mcs_map;
10944 	if (cfg_in_range(CFG_HE_TX_MCS_MAP_LT_80, tx_mcs_map))
10945 		mac_ctx->mlme_cfg->he_caps.dot11_he_cap.tx_he_mcs_map_lt_80 =
10946 		tx_mcs_map;
10947 	if (cfg_in_range(CFG_HE_RX_MCS_MAP_160, rx_mcs_map))
10948 		qdf_mem_copy(mac_ctx->mlme_cfg->he_caps.dot11_he_cap.
10949 			     rx_he_mcs_map_160,
10950 			     &rx_mcs_map, sizeof(uint16_t));
10951 	if (cfg_in_range(CFG_HE_TX_MCS_MAP_160, tx_mcs_map))
10952 		qdf_mem_copy(mac_ctx->mlme_cfg->he_caps.dot11_he_cap.
10953 			     tx_he_mcs_map_160,
10954 			     &tx_mcs_map, sizeof(uint16_t));
10955 
10956 	mac_ctx->he_cap_2g.rx_he_mcs_map_lt_80 = rx_mcs_map;
10957 	mac_ctx->he_cap_2g.tx_he_mcs_map_lt_80 = tx_mcs_map;
10958 	mac_ctx->he_cap_5g.rx_he_mcs_map_lt_80 = rx_mcs_map;
10959 	mac_ctx->he_cap_5g.tx_he_mcs_map_lt_80 = tx_mcs_map;
10960 	qdf_mem_copy(mac_ctx->he_cap_5g.rx_he_mcs_map_160,
10961 		     mac_ctx->mlme_cfg->he_caps.dot11_he_cap.rx_he_mcs_map_160,
10962 		     sizeof(uint16_t));
10963 	qdf_mem_copy(mac_ctx->he_cap_5g.tx_he_mcs_map_160,
10964 		     mac_ctx->mlme_cfg->he_caps.dot11_he_cap.tx_he_mcs_map_160,
10965 		     sizeof(uint16_t));
10966 	csr_update_session_he_cap(mac_ctx, csr_session);
10967 
10968 }
10969 
sme_update_he_mcs(mac_handle_t mac_handle,uint8_t session_id,uint16_t he_mcs)10970 int sme_update_he_mcs(mac_handle_t mac_handle, uint8_t session_id,
10971 		      uint16_t he_mcs)
10972 {
10973 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
10974 	struct csr_roam_session *csr_session;
10975 	uint16_t mcs_val = 0;
10976 	uint16_t mcs_map = HE_MCS_ALL_DISABLED;
10977 	uint16_t mcs_map_cfg;
10978 	uint8_t nss = 0, i;
10979 	uint16_t mcs_mask = 0x3;
10980 
10981 	csr_session = CSR_GET_SESSION(mac_ctx, session_id);
10982 	if (!csr_session) {
10983 		sme_err("No session for id %d", session_id);
10984 		return -EINVAL;
10985 	}
10986 
10987 	mcs_map_cfg =
10988 		mac_ctx->mlme_cfg->he_caps.dot11_he_cap.rx_he_mcs_map_lt_80;
10989 	for (nss = 0; nss < VHT_MAX_NSS; nss++) {
10990 		if ((mcs_map_cfg & mcs_mask) ==  mcs_mask)
10991 			break;
10992 		mcs_mask = (mcs_mask << 2);
10993 	}
10994 	if (nss > 2)
10995 		nss = 2;
10996 
10997 	if ((he_mcs & 0x3) == HE_MCS_DISABLE) {
10998 		sme_err("Invalid HE MCS 0x%0x, can't disable 0-7 for 1ss",
10999 			he_mcs);
11000 		return -EINVAL;
11001 	}
11002 	mcs_val = he_mcs & 0x3;
11003 	switch (he_mcs) {
11004 	case HE_80_MCS0_7:
11005 	case HE_80_MCS0_9:
11006 	case HE_80_MCS0_11:
11007 		for (i = 1; i <= nss; i++)
11008 			mcs_map = HE_SET_MCS_4_NSS(mcs_map, mcs_val, i);
11009 
11010 		sme_debug("HE 80 nss: %d, mcs: 0x%0X", nss, mcs_map);
11011 		if (cfg_in_range(CFG_HE_TX_MCS_MAP_LT_80, mcs_map))
11012 			mac_ctx->mlme_cfg->he_caps.dot11_he_cap.
11013 			tx_he_mcs_map_lt_80 = mcs_map;
11014 		if (cfg_in_range(CFG_HE_RX_MCS_MAP_LT_80, mcs_map))
11015 			mac_ctx->mlme_cfg->he_caps.dot11_he_cap.
11016 			rx_he_mcs_map_lt_80 = mcs_map;
11017 		mac_ctx->he_cap_2g.tx_he_mcs_map_lt_80 = mcs_map;
11018 		mac_ctx->he_cap_2g.rx_he_mcs_map_lt_80 = mcs_map;
11019 		mac_ctx->he_cap_5g.tx_he_mcs_map_lt_80 = mcs_map;
11020 		mac_ctx->he_cap_5g.rx_he_mcs_map_lt_80 = mcs_map;
11021 		break;
11022 
11023 	case HE_160_MCS0_7:
11024 	case HE_160_MCS0_9:
11025 	case HE_160_MCS0_11:
11026 		for (i = 1; i <= nss; i++)
11027 			mcs_map = HE_SET_MCS_4_NSS(mcs_map, mcs_val, i);
11028 
11029 		sme_debug("HE 160 nss: %d, mcs: 0x%0X", nss, mcs_map);
11030 		if (cfg_in_range(CFG_HE_TX_MCS_MAP_160, mcs_map))
11031 			qdf_mem_copy(mac_ctx->mlme_cfg->he_caps.dot11_he_cap.
11032 				     tx_he_mcs_map_160, &mcs_map,
11033 				     sizeof(uint16_t));
11034 		if (cfg_in_range(CFG_HE_RX_MCS_MAP_160, mcs_map))
11035 			qdf_mem_copy(mac_ctx->mlme_cfg->he_caps.dot11_he_cap.
11036 				     rx_he_mcs_map_160, &mcs_map,
11037 				     sizeof(uint16_t));
11038 		qdf_mem_copy(mac_ctx->he_cap_5g.tx_he_mcs_map_160,
11039 			     mac_ctx->mlme_cfg->he_caps.dot11_he_cap.
11040 			     tx_he_mcs_map_160,
11041 			     sizeof(uint16_t));
11042 		qdf_mem_copy(mac_ctx->he_cap_5g.rx_he_mcs_map_160,
11043 			     mac_ctx->mlme_cfg->he_caps.dot11_he_cap.
11044 			     rx_he_mcs_map_160,
11045 			     sizeof(uint16_t));
11046 		break;
11047 
11048 	case HE_80p80_MCS0_7:
11049 	case HE_80p80_MCS0_9:
11050 	case HE_80p80_MCS0_11:
11051 		mcs_map = HE_SET_MCS_4_NSS(mcs_map, mcs_val, 1);
11052 		if (cfg_in_range(CFG_HE_TX_MCS_MAP_80_80, mcs_map))
11053 			qdf_mem_copy(mac_ctx->mlme_cfg->he_caps.dot11_he_cap.
11054 				     tx_he_mcs_map_80_80, &mcs_map,
11055 				     sizeof(uint16_t));
11056 		if (cfg_in_range(CFG_HE_RX_MCS_MAP_80_80, mcs_map))
11057 			qdf_mem_copy(mac_ctx->mlme_cfg->he_caps.dot11_he_cap.
11058 				     rx_he_mcs_map_80_80, &mcs_map,
11059 				     sizeof(uint16_t));
11060 		break;
11061 
11062 	default:
11063 		sme_err("Invalid HE MCS 0x%0x", he_mcs);
11064 		return -EINVAL;
11065 	}
11066 	sme_debug("new HE MCS 0x%0x", mcs_map);
11067 	sme_set_vdev_ies_per_band(mac_handle, session_id, QDF_STA_MODE);
11068 	csr_update_session_he_cap(mac_ctx, csr_session);
11069 
11070 	return 0;
11071 }
11072 
sme_set_usr_cfg_mu_edca(mac_handle_t mac_handle,bool val)11073 void sme_set_usr_cfg_mu_edca(mac_handle_t mac_handle, bool val)
11074 {
11075 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
11076 
11077 	mac_ctx->usr_cfg_mu_edca_params = val;
11078 }
11079 
sme_update_mu_edca_params(mac_handle_t mac_handle,uint8_t session_id)11080 int sme_update_mu_edca_params(mac_handle_t mac_handle, uint8_t session_id)
11081 {
11082 	struct scheduler_msg msg = {0};
11083 	QDF_STATUS status;
11084 
11085 	qdf_mem_zero(&msg, sizeof(msg));
11086 	msg.type = WNI_SME_UPDATE_MU_EDCA_PARAMS;
11087 	msg.reserved = 0;
11088 	msg.bodyval = session_id;
11089 	status = scheduler_post_message(QDF_MODULE_ID_SME,
11090 					QDF_MODULE_ID_PE,
11091 					QDF_MODULE_ID_PE, &msg);
11092 	if (status != QDF_STATUS_SUCCESS) {
11093 		sme_err("Not able to post update edca profile");
11094 		return -EIO;
11095 	}
11096 
11097 	return 0;
11098 }
11099 
sme_set_he_mu_edca_def_cfg(mac_handle_t mac_handle)11100 void sme_set_he_mu_edca_def_cfg(mac_handle_t mac_handle)
11101 {
11102 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
11103 	uint8_t i;
11104 
11105 	sme_debug("Set MU EDCA params to default");
11106 	for (i = 0; i < QCA_WLAN_AC_ALL; i++) {
11107 		mac_ctx->usr_mu_edca_params[i].aci.aifsn = MU_EDCA_DEF_AIFSN;
11108 		mac_ctx->usr_mu_edca_params[i].aci.aci = i;
11109 		mac_ctx->usr_mu_edca_params[i].cw.max = MU_EDCA_DEF_CW_MAX;
11110 		mac_ctx->usr_mu_edca_params[i].cw.min = MU_EDCA_DEF_CW_MIN;
11111 		mac_ctx->usr_mu_edca_params[i].mu_edca_timer =
11112 							MU_EDCA_DEF_TIMER;
11113 	}
11114 }
11115 
sme_update_he_capabilities(mac_handle_t mac_handle,uint8_t session_id,uint8_t cfg_val,uint8_t cfg_id)11116 int sme_update_he_capabilities(mac_handle_t mac_handle, uint8_t session_id,
11117 			       uint8_t cfg_val, uint8_t cfg_id)
11118 {
11119 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
11120 	struct csr_roam_session *session;
11121 	tDot11fIEhe_cap *cfg_he_cap;
11122 	tDot11fIEhe_cap *he_cap_orig;
11123 
11124 	session = CSR_GET_SESSION(mac_ctx, session_id);
11125 
11126 	if (!session) {
11127 		sme_err("No session for id %d", session_id);
11128 		return -EINVAL;
11129 	}
11130 	cfg_he_cap = &mac_ctx->mlme_cfg->he_caps.dot11_he_cap;
11131 	he_cap_orig = &mac_ctx->mlme_cfg->he_caps.he_cap_orig;
11132 
11133 	switch (cfg_id) {
11134 	case QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_BCAST_TWT_SUPPORT:
11135 		if (cfg_val) {
11136 			mac_ctx->mlme_cfg->twt_cfg.disable_btwt_usr_cfg = false;
11137 			cfg_he_cap->broadcast_twt = he_cap_orig->broadcast_twt;
11138 		} else {
11139 			cfg_he_cap->broadcast_twt = 0;
11140 			mac_ctx->mlme_cfg->twt_cfg.disable_btwt_usr_cfg = true;
11141 		}
11142 		break;
11143 	case QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_RX_CTRL_FRAME_TO_MBSS:
11144 		if (cfg_val)
11145 			cfg_he_cap->rx_ctrl_frame = he_cap_orig->rx_ctrl_frame;
11146 		else
11147 			cfg_he_cap->rx_ctrl_frame = 0;
11148 		break;
11149 	case QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_PUNCTURED_PREAMBLE_RX:
11150 		if (cfg_val)
11151 			cfg_he_cap->rx_pream_puncturing =
11152 				he_cap_orig->rx_pream_puncturing;
11153 		else
11154 			cfg_he_cap->rx_pream_puncturing = 0;
11155 		break;
11156 	default:
11157 		sme_debug("default: Unhandled cfg %d", cfg_id);
11158 		return -EINVAL;
11159 	}
11160 
11161 	sme_debug("HE cap: cfg id %d, cfg val %d", cfg_id, cfg_val);
11162 	csr_update_session_he_cap(mac_ctx, session);
11163 	return 0;
11164 }
11165 
sme_update_he_tx_bfee_supp(mac_handle_t mac_handle,uint8_t session_id,uint8_t cfg_val)11166 int sme_update_he_tx_bfee_supp(mac_handle_t mac_handle, uint8_t session_id,
11167 			       uint8_t cfg_val)
11168 {
11169 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
11170 	struct csr_roam_session *session;
11171 
11172 	session = CSR_GET_SESSION(mac_ctx, session_id);
11173 
11174 	if (!session) {
11175 		sme_err("No session for id %d", session_id);
11176 		return -EINVAL;
11177 	}
11178 	if (cfg_val <= 1)
11179 		mac_ctx->mlme_cfg->he_caps.dot11_he_cap.su_beamformee = cfg_val;
11180 	else
11181 		return -EINVAL;
11182 
11183 	csr_update_session_he_cap(mac_ctx, session);
11184 	return 0;
11185 }
11186 
sme_update_he_trigger_frm_mac_pad(mac_handle_t mac_handle,uint8_t session_id,uint8_t cfg_val)11187 int sme_update_he_trigger_frm_mac_pad(mac_handle_t mac_handle,
11188 				      uint8_t session_id,
11189 				      uint8_t cfg_val)
11190 {
11191 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
11192 	struct csr_roam_session *session;
11193 
11194 	session = CSR_GET_SESSION(mac_ctx, session_id);
11195 
11196 	if (!session) {
11197 		sme_err("No session for id %d", session_id);
11198 		return -EINVAL;
11199 	}
11200 	if (cfg_in_range(CFG_HE_TRIG_PAD, cfg_val))
11201 		mac_ctx->mlme_cfg->he_caps.dot11_he_cap.trigger_frm_mac_pad =
11202 		cfg_val;
11203 	else
11204 		return -EINVAL;
11205 
11206 	csr_update_session_he_cap(mac_ctx, session);
11207 	return 0;
11208 
11209 }
11210 
sme_update_he_om_ctrl_supp(mac_handle_t mac_handle,uint8_t session_id,uint8_t cfg_val)11211 int sme_update_he_om_ctrl_supp(mac_handle_t mac_handle, uint8_t session_id,
11212 			       uint8_t cfg_val)
11213 {
11214 
11215 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
11216 	struct csr_roam_session *session;
11217 
11218 	session = CSR_GET_SESSION(mac_ctx, session_id);
11219 
11220 	if (!session) {
11221 		sme_err("No session for id %d", session_id);
11222 		return -EINVAL;
11223 	}
11224 	mac_ctx->mlme_cfg->he_caps.dot11_he_cap.omi_a_ctrl = cfg_val;
11225 	mac_ctx->he_cap_2g.omi_a_ctrl = cfg_val;
11226 	mac_ctx->he_cap_5g.omi_a_ctrl = cfg_val;
11227 
11228 	csr_update_session_he_cap(mac_ctx, session);
11229 	return 0;
11230 }
11231 
sme_update_he_htc_he_supp(mac_handle_t mac_handle,uint8_t session_id,bool cfg_val)11232 int sme_update_he_htc_he_supp(mac_handle_t mac_handle, uint8_t session_id,
11233 			      bool cfg_val)
11234 {
11235 
11236 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
11237 	struct csr_roam_session *session;
11238 
11239 	session = CSR_GET_SESSION(mac_ctx, session_id);
11240 
11241 	if (!session) {
11242 		sme_err("No session for id %d", session_id);
11243 		return -EINVAL;
11244 	}
11245 
11246 	mac_ctx->mlme_cfg->he_caps.dot11_he_cap.htc_he = cfg_val;
11247 	csr_update_session_he_cap(mac_ctx, session);
11248 
11249 	return 0;
11250 }
11251 
11252 static QDF_STATUS
sme_validate_session_for_cap_update(struct mac_context * mac_ctx,uint8_t session_id,struct csr_roam_session * session)11253 sme_validate_session_for_cap_update(struct mac_context *mac_ctx,
11254 				    uint8_t session_id,
11255 				    struct csr_roam_session *session)
11256 {
11257 	if (!session) {
11258 		sme_err("Session does not exist, Session_id: %d", session_id);
11259 		return QDF_STATUS_E_INVAL;
11260 	}
11261 
11262 	if (!cm_is_vdevid_connected(mac_ctx->pdev, session_id)) {
11263 		sme_debug("STA is not connected, Session_id: %d", session_id);
11264 		return QDF_STATUS_E_INVAL;
11265 	}
11266 
11267 	return QDF_STATUS_SUCCESS;
11268 }
11269 
sme_send_he_om_ctrl_update(mac_handle_t mac_handle,uint8_t session_id,struct omi_ctrl_tx * omi_data)11270 int sme_send_he_om_ctrl_update(mac_handle_t mac_handle, uint8_t session_id,
11271 			       struct omi_ctrl_tx *omi_data)
11272 {
11273 	QDF_STATUS status = QDF_STATUS_SUCCESS;
11274 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
11275 	void *wma_handle;
11276 	struct csr_roam_session *session = CSR_GET_SESSION(mac_ctx, session_id);
11277 	uint32_t param_val = 0;
11278 	qdf_freq_t op_chan_freq;
11279 	qdf_freq_t freq_seg_0;
11280 	enum phy_ch_width ch_width;
11281 	struct qdf_mac_addr connected_bssid;
11282 
11283 	wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
11284 	if (!wma_handle)
11285 		return -EIO;
11286 
11287 	status = sme_validate_session_for_cap_update(mac_ctx, session_id,
11288 						     session);
11289 	if (QDF_IS_STATUS_ERROR(status))
11290 		return -EINVAL;
11291 
11292 	wlan_get_op_chan_freq_info_vdev_id(mac_ctx->pdev, session_id,
11293 					   &op_chan_freq, &freq_seg_0,
11294 					   &ch_width);
11295 
11296 	if (!omi_data) {
11297 		sme_err("OMI data is NULL");
11298 		return -EIO;
11299 	}
11300 
11301 	omi_data->a_ctrl_id = A_CTRL_ID_OMI;
11302 
11303 	if (mac_ctx->he_om_ctrl_cfg_nss_set)
11304 		omi_data->rx_nss = mac_ctx->he_om_ctrl_cfg_nss;
11305 	else
11306 		omi_data->rx_nss = session->nss - 1;
11307 
11308 	if (mac_ctx->he_om_ctrl_cfg_tx_nsts_set)
11309 		omi_data->tx_nsts = mac_ctx->he_om_ctrl_cfg_tx_nsts;
11310 	else
11311 		omi_data->tx_nsts = session->nss - 1;
11312 
11313 	if (mac_ctx->he_om_ctrl_cfg_bw_set)
11314 		omi_data->ch_bw = mac_ctx->he_om_ctrl_cfg_bw;
11315 	else
11316 		omi_data->ch_bw = ch_width;
11317 
11318 	omi_data->ul_mu_dis = mac_ctx->he_om_ctrl_cfg_ul_mu_dis;
11319 	omi_data->ul_mu_data_dis = mac_ctx->he_om_ctrl_ul_mu_data_dis;
11320 	omi_data->omi_in_vht = 0x1;
11321 	omi_data->omi_in_he = 0x1;
11322 
11323 	sme_debug("OMI: BW %d TxNSTS %d RxNSS %d ULMU %d, OMI_VHT %d, OMI_HE %d",
11324 		  omi_data->ch_bw, omi_data->tx_nsts, omi_data->rx_nss,
11325 		  omi_data->ul_mu_dis, omi_data->omi_in_vht,
11326 		  omi_data->omi_in_he);
11327 	sme_debug("EHT OMI: BW %d rx nss %d tx nss %d", omi_data->eht_ch_bw_ext,
11328 		  omi_data->eht_rx_nss_ext, omi_data->eht_tx_nss_ext);
11329 
11330 	qdf_mem_copy(&param_val, omi_data, sizeof(param_val));
11331 	wlan_mlme_get_bssid_vdev_id(mac_ctx->pdev, session_id,
11332 				    &connected_bssid);
11333 	sme_debug("param val %08X, bssid:"QDF_MAC_ADDR_FMT, param_val,
11334 		  QDF_MAC_ADDR_REF(connected_bssid.bytes));
11335 	status = wma_set_peer_param(wma_handle,
11336 				    connected_bssid.bytes,
11337 				    WMI_PEER_PARAM_XMIT_OMI,
11338 				    param_val, session_id);
11339 	if (QDF_STATUS_SUCCESS != status) {
11340 		sme_err("set_peer_param_cmd returned %d", status);
11341 		return -EIO;
11342 	}
11343 
11344 	return 0;
11345 }
11346 
sme_set_he_om_ctrl_param(mac_handle_t mac_handle,uint8_t session_id,enum qca_wlan_vendor_attr_he_omi_tx param,uint8_t cfg_val)11347 int sme_set_he_om_ctrl_param(mac_handle_t mac_handle, uint8_t session_id,
11348 			     enum qca_wlan_vendor_attr_he_omi_tx param,
11349 			     uint8_t cfg_val)
11350 {
11351 	QDF_STATUS status;
11352 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
11353 	struct csr_roam_session *session = CSR_GET_SESSION(mac_ctx, session_id);
11354 	qdf_freq_t op_chan_freq;
11355 	qdf_freq_t freq_seg_0;
11356 	enum phy_ch_width ch_width;
11357 
11358 	status = sme_validate_session_for_cap_update(mac_ctx, session_id,
11359 						     session);
11360 	if (QDF_IS_STATUS_ERROR(status))
11361 		return -EINVAL;
11362 
11363 	wlan_get_op_chan_freq_info_vdev_id(mac_ctx->pdev, session_id,
11364 					    &op_chan_freq, &freq_seg_0,
11365 					    &ch_width);
11366 
11367 	switch(param) {
11368 		case QCA_WLAN_VENDOR_ATTR_HE_OMI_ULMU_DISABLE:
11369 			sme_debug("Set OM ctrl UL MU dis to %d", cfg_val);
11370 			mac_ctx->he_om_ctrl_cfg_ul_mu_dis = cfg_val;
11371 			break;
11372 		case QCA_WLAN_VENDOR_ATTR_HE_OMI_RX_NSS:
11373 			if ((cfg_val + 1)  > session->nss) {
11374 				sme_debug("OMI Nss %d is > connected Nss %d",
11375 					  cfg_val, session->nss);
11376 				mac_ctx->he_om_ctrl_cfg_nss_set = false;
11377 				return 0;
11378 			}
11379 			sme_debug("Set OM ctrl Rx Nss cfg to %d", cfg_val);
11380 			mac_ctx->he_om_ctrl_cfg_nss_set = true;
11381 			mac_ctx->he_om_ctrl_cfg_nss = cfg_val;
11382 			break;
11383 		case QCA_WLAN_VENDOR_ATTR_HE_OMI_CH_BW:
11384 			if (cfg_val > ch_width) {
11385 				sme_debug("OMI BW %d is > connected BW %d",
11386 					  cfg_val, ch_width);
11387 				mac_ctx->he_om_ctrl_cfg_bw_set = false;
11388 				return 0;
11389 			}
11390 			sme_debug("Set OM ctrl BW cfg to %d", cfg_val);
11391 			mac_ctx->he_om_ctrl_cfg_bw_set = true;
11392 			mac_ctx->he_om_ctrl_cfg_bw = cfg_val;
11393 			break;
11394 		case QCA_WLAN_VENDOR_ATTR_HE_OMI_TX_NSTS:
11395 			if ((cfg_val + 1) > session->nss) {
11396 				sme_debug("OMI NSTS %d is > connected Nss %d",
11397 					  cfg_val, session->nss);
11398 				mac_ctx->he_om_ctrl_cfg_tx_nsts_set = false;
11399 				return 0;
11400 			}
11401 			sme_debug("Set OM ctrl tx nsts cfg to %d", cfg_val);
11402 			mac_ctx->he_om_ctrl_cfg_tx_nsts_set = true;
11403 			mac_ctx->he_om_ctrl_cfg_tx_nsts = cfg_val;
11404 			break;
11405 		case QCA_WLAN_VENDOR_ATTR_HE_OMI_ULMU_DATA_DISABLE:
11406 			sme_debug("Set OM ctrl UL MU data dis to %d", cfg_val);
11407 			mac_ctx->he_om_ctrl_ul_mu_data_dis = cfg_val;
11408 			break;
11409 		default:
11410 			sme_debug("Invalid OMI param %d", param);
11411 			return -EINVAL;
11412 	}
11413 
11414 	return 0;
11415 }
11416 
sme_reset_he_om_ctrl(mac_handle_t mac_handle)11417 void sme_reset_he_om_ctrl(mac_handle_t mac_handle)
11418 {
11419 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
11420 
11421 	mac_ctx->he_om_ctrl_cfg_bw_set = false;
11422 	mac_ctx->he_om_ctrl_cfg_nss_set = false;
11423 	mac_ctx->he_om_ctrl_cfg_bw = 0;
11424 	mac_ctx->he_om_ctrl_cfg_nss = 0;
11425 	mac_ctx->he_om_ctrl_cfg_ul_mu_dis = false;
11426 	mac_ctx->he_om_ctrl_cfg_tx_nsts_set = false;
11427 	mac_ctx->he_om_ctrl_cfg_tx_nsts = 0;
11428 	mac_ctx->he_om_ctrl_ul_mu_data_dis = false;
11429 }
11430 
sme_config_action_tx_in_tb_ppdu(mac_handle_t mac_handle,uint8_t session_id,uint8_t cfg_val)11431 int sme_config_action_tx_in_tb_ppdu(mac_handle_t mac_handle, uint8_t session_id,
11432 				    uint8_t cfg_val)
11433 {
11434 	QDF_STATUS status;
11435 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
11436 	struct scheduler_msg msg = {0};
11437 	struct sir_cfg_action_frm_tb_ppdu *cfg_msg;
11438 
11439 	if (!cm_is_vdevid_connected(mac_ctx->pdev, session_id)) {
11440 		sme_debug("STA is not connected, Session_id: %d", session_id);
11441 		return -EINVAL;
11442 	}
11443 
11444 	cfg_msg = qdf_mem_malloc(sizeof(*cfg_msg));
11445 	if (!cfg_msg)
11446 		return -EIO;
11447 
11448 	cfg_msg->type = WNI_SME_CFG_ACTION_FRM_HE_TB_PPDU;
11449 	cfg_msg->vdev_id = session_id;
11450 	cfg_msg->cfg = cfg_val;
11451 
11452 	msg.bodyptr = cfg_msg;
11453 	msg.type = WNI_SME_CFG_ACTION_FRM_HE_TB_PPDU;
11454 	status = scheduler_post_message(QDF_MODULE_ID_SME, QDF_MODULE_ID_PE,
11455 					QDF_MODULE_ID_PE, &msg);
11456 	if (QDF_STATUS_SUCCESS != status) {
11457 		sme_err("Failed to send CFG_ACTION_FRAME_IN_TB_PPDU to PE %d",
11458 			status);
11459 		qdf_mem_free(cfg_msg);
11460 		return -EIO;
11461 	}
11462 
11463 	return 0;
11464 }
11465 
sme_update_he_tx_bfee_nsts(mac_handle_t mac_handle,uint8_t session_id,uint8_t cfg_val)11466 int sme_update_he_tx_bfee_nsts(mac_handle_t mac_handle, uint8_t session_id,
11467 			       uint8_t cfg_val)
11468 {
11469 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
11470 	struct csr_roam_session *session;
11471 
11472 	session = CSR_GET_SESSION(mac_ctx, session_id);
11473 
11474 	if (!session) {
11475 		sme_err("No session for id %d", session_id);
11476 		return -EINVAL;
11477 	}
11478 	if (cfg_in_range(CFG_HE_BFEE_STS_LT80, cfg_val)) {
11479 		mac_ctx->mlme_cfg->he_caps.dot11_he_cap.bfee_sts_lt_80 =
11480 		cfg_val;
11481 		mac_ctx->mlme_cfg->he_caps.dot11_he_cap.bfee_sts_gt_80 =
11482 		cfg_val;
11483 	} else {
11484 		return -EINVAL;
11485 	}
11486 
11487 
11488 	csr_update_session_he_cap(mac_ctx, session);
11489 	return 0;
11490 }
11491 
sme_set_he_tx_bf_cbf_rates(uint8_t session_id)11492 void sme_set_he_tx_bf_cbf_rates(uint8_t session_id)
11493 {
11494 	uint32_t tx_bf_cbf_rates_5g[] = {91, 1, 0, 3, 2, 4, 0};
11495 	uint32_t tx_bf_cbf_rates_2g[] = {91, 1, 1, 3, 1, 3, 0};
11496 	QDF_STATUS status;
11497 
11498 	status = wma_form_unit_test_cmd_and_send(session_id, 0x48, 7,
11499 						 tx_bf_cbf_rates_5g);
11500 	if (QDF_STATUS_SUCCESS != status)
11501 		sme_err("send_unit_test_cmd returned %d", status);
11502 
11503 	status = wma_form_unit_test_cmd_and_send(session_id, 0x48, 7,
11504 						 tx_bf_cbf_rates_2g);
11505 	if (QDF_STATUS_SUCCESS != status)
11506 		sme_err("send_unit_test_cmd returned %d", status);
11507 }
11508 
sme_config_su_ppdu_queue(uint8_t session_id,bool enable)11509 void sme_config_su_ppdu_queue(uint8_t session_id, bool enable)
11510 {
11511 	uint32_t su_ppdu_enable[] = {69, 1, 1, 1};
11512 	uint32_t su_ppdu_disable[] = {69, 1, 1, 0};
11513 	QDF_STATUS status;
11514 
11515 	if (enable) {
11516 		sme_debug("Send Tx SU PPDU queue ENABLE cmd to FW");
11517 		status = wma_form_unit_test_cmd_and_send(session_id, 0x48, 4,
11518 							 su_ppdu_enable);
11519 	} else {
11520 		sme_debug("Send Tx SU PPDU queue DISABLE cmd to FW");
11521 		status = wma_form_unit_test_cmd_and_send(session_id, 0x48, 4,
11522 							 su_ppdu_disable);
11523 	}
11524 	if (QDF_STATUS_SUCCESS != status)
11525 		sme_err("send_unit_test_cmd returned %d", status);
11526 }
11527 
sme_update_he_tx_stbc_cap(mac_handle_t mac_handle,uint8_t session_id,int value)11528 int sme_update_he_tx_stbc_cap(mac_handle_t mac_handle, uint8_t session_id,
11529 			      int value)
11530 {
11531 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
11532 	struct csr_roam_session *session;
11533 	uint32_t he_cap_val = 0;
11534 
11535 	he_cap_val = value ? 1 : 0;
11536 	session = CSR_GET_SESSION(mac_ctx, session_id);
11537 
11538 	if (!session) {
11539 		sme_err("No session for id %d", session_id);
11540 		return -EINVAL;
11541 	}
11542 	if (he_cap_val <= 1)
11543 		mac_ctx->mlme_cfg->he_caps.dot11_he_cap.tb_ppdu_tx_stbc_lt_80mhz
11544 			= he_cap_val;
11545 	else
11546 		return -EINVAL;
11547 	if (he_cap_val <= 1)
11548 		mac_ctx->mlme_cfg->he_caps.dot11_he_cap.tb_ppdu_tx_stbc_gt_80mhz
11549 			= he_cap_val;
11550 	else
11551 		return -EINVAL;
11552 	csr_update_session_he_cap(mac_ctx, session);
11553 	return 0;
11554 }
11555 
sme_update_he_rx_stbc_cap(mac_handle_t mac_handle,uint8_t session_id,int value)11556 int sme_update_he_rx_stbc_cap(mac_handle_t mac_handle, uint8_t session_id,
11557 			      int value)
11558 {
11559 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
11560 	struct csr_roam_session *session;
11561 	uint32_t he_cap_val = 0;
11562 
11563 	he_cap_val = value ? 1 : 0;
11564 	session = CSR_GET_SESSION(mac_ctx, session_id);
11565 
11566 	if (!session) {
11567 		sme_err("No session for id %d", session_id);
11568 		return -EINVAL;
11569 	}
11570 	if (he_cap_val <= 1)
11571 		mac_ctx->mlme_cfg->he_caps.dot11_he_cap.rx_stbc_lt_80mhz =
11572 		he_cap_val;
11573 	else
11574 		return -EINVAL;
11575 	if (he_cap_val <= 1)
11576 		mac_ctx->mlme_cfg->he_caps.dot11_he_cap.rx_stbc_gt_80mhz =
11577 		he_cap_val;
11578 	else
11579 		return -EINVAL;
11580 	csr_update_session_he_cap(mac_ctx, session);
11581 	return 0;
11582 }
11583 
sme_update_he_frag_supp(mac_handle_t mac_handle,uint8_t session_id,uint16_t he_frag)11584 int sme_update_he_frag_supp(mac_handle_t mac_handle, uint8_t session_id,
11585 			    uint16_t he_frag)
11586 {
11587 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
11588 	struct csr_roam_session *session;
11589 
11590 	session = CSR_GET_SESSION(mac_ctx, session_id);
11591 
11592 	if (!session) {
11593 		sme_err("No session for id %d", session_id);
11594 		return -EINVAL;
11595 	}
11596 	if (cfg_in_range(CFG_HE_FRAGMENTATION, he_frag))
11597 		mac_ctx->mlme_cfg->he_caps.dot11_he_cap.fragmentation = he_frag;
11598 	else
11599 		return -EINVAL;
11600 
11601 	csr_update_session_he_cap(mac_ctx, session);
11602 	return 0;
11603 
11604 }
11605 
sme_update_he_ldpc_supp(mac_handle_t mac_handle,uint8_t session_id,uint16_t he_ldpc)11606 int sme_update_he_ldpc_supp(mac_handle_t mac_handle, uint8_t session_id,
11607 			    uint16_t he_ldpc)
11608 {
11609 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
11610 	struct csr_roam_session *session;
11611 
11612 	session = CSR_GET_SESSION(mac_ctx, session_id);
11613 
11614 	if (!session) {
11615 		sme_err("No session for id %d", session_id);
11616 		return -EINVAL;
11617 	}
11618 	if (he_ldpc <= 1)
11619 		mac_ctx->mlme_cfg->he_caps.dot11_he_cap.ldpc_coding = he_ldpc;
11620 	else
11621 		return -EINVAL;
11622 
11623 	csr_update_session_he_cap(mac_ctx, session);
11624 	return 0;
11625 
11626 }
11627 
sme_update_he_twt_req_support(mac_handle_t mac_handle,uint8_t session_id,uint8_t cfg_val)11628 int sme_update_he_twt_req_support(mac_handle_t mac_handle, uint8_t session_id,
11629 				  uint8_t cfg_val)
11630 {
11631 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
11632 	struct csr_roam_session *session;
11633 
11634 	session = CSR_GET_SESSION(mac_ctx, session_id);
11635 
11636 	if (!session) {
11637 		sme_err("No session for id %d", session_id);
11638 		return -EINVAL;
11639 	}
11640 	mac_ctx->mlme_cfg->he_caps.dot11_he_cap.twt_request = cfg_val;
11641 
11642 	csr_update_session_he_cap(mac_ctx, session);
11643 
11644 	return 0;
11645 }
11646 
sme_update_he_full_ul_mumimo(mac_handle_t mac_handle,uint8_t session_id,uint8_t cfg_val)11647 int sme_update_he_full_ul_mumimo(mac_handle_t mac_handle, uint8_t session_id,
11648 				 uint8_t cfg_val)
11649 {
11650 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
11651 	struct csr_roam_session *session;
11652 
11653 	session = CSR_GET_SESSION(mac_ctx, session_id);
11654 
11655 	if (!session) {
11656 		sme_err("No session for id %d", session_id);
11657 		return -EINVAL;
11658 	}
11659 	mac_ctx->mlme_cfg->he_caps.dot11_he_cap.ul_mu = cfg_val;
11660 
11661 	csr_update_session_he_cap(mac_ctx, session);
11662 
11663 	return 0;
11664 }
11665 #endif
11666 
11667 QDF_STATUS
sme_update_session_txq_edca_params(mac_handle_t mac_handle,uint8_t session_id,tSirMacEdcaParamRecord * txq_edca_params)11668 sme_update_session_txq_edca_params(mac_handle_t mac_handle,
11669 				   uint8_t session_id,
11670 				   tSirMacEdcaParamRecord *txq_edca_params)
11671 {
11672 	QDF_STATUS status;
11673 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
11674 	struct sir_update_session_txq_edca_param *msg;
11675 	struct pe_session *pe_session;
11676 
11677 	pe_session = pe_find_session_by_vdev_id(mac_ctx, session_id);
11678 	if (!pe_session) {
11679 		pe_warn("Session does not exist for given session_id %d",
11680 			session_id);
11681 		return QDF_STATUS_E_INVAL;
11682 	}
11683 
11684 	status = sme_acquire_global_lock(&mac_ctx->sme);
11685 	if (QDF_IS_STATUS_ERROR(status))
11686 		return QDF_STATUS_E_AGAIN;
11687 
11688 	msg = qdf_mem_malloc(sizeof(*msg));
11689 	if (!msg) {
11690 		sme_release_global_lock(&mac_ctx->sme);
11691 		return QDF_STATUS_E_NOMEM;
11692 	}
11693 
11694 	msg->message_type = eWNI_SME_UPDATE_SESSION_EDCA_TXQ_PARAMS;
11695 	msg->vdev_id = session_id;
11696 	qdf_mem_copy(&msg->txq_edca_params, txq_edca_params,
11697 		     sizeof(tSirMacEdcaParamRecord));
11698 	msg->length = sizeof(*msg);
11699 
11700 	status = umac_send_mb_message_to_mac(msg);
11701 
11702 	sme_release_global_lock(&mac_ctx->sme);
11703 	if (status != QDF_STATUS_SUCCESS)
11704 		return QDF_STATUS_E_IO;
11705 
11706 	pe_session->user_edca_set = 1;
11707 
11708 	return QDF_STATUS_SUCCESS;
11709 }
11710 
11711 /**
11712  * sme_set_nud_debug_stats_cb() - set nud debug stats callback
11713  * @mac_handle: Opaque handle to the global MAC context
11714  * @cb: callback function pointer
11715  * @context: callback context
11716  *
11717  * This function stores nud debug stats callback function.
11718  *
11719  * Return: QDF_STATUS enumeration.
11720  */
sme_set_nud_debug_stats_cb(mac_handle_t mac_handle,void (* cb)(void *,struct rsp_stats *,void *),void * context)11721 QDF_STATUS sme_set_nud_debug_stats_cb(mac_handle_t mac_handle,
11722 				void (*cb)(void *, struct rsp_stats *, void *),
11723 				void *context)
11724 {
11725 	QDF_STATUS status  = QDF_STATUS_SUCCESS;
11726 	struct mac_context *mac;
11727 
11728 	if (!mac_handle) {
11729 		sme_err("mac_handle is not valid");
11730 		return QDF_STATUS_E_INVAL;
11731 	}
11732 	mac = MAC_CONTEXT(mac_handle);
11733 
11734 	status = sme_acquire_global_lock(&mac->sme);
11735 	if (!QDF_IS_STATUS_SUCCESS(status)) {
11736 		sme_err("sme_acquire_global_lock failed!(status=%d)",
11737 			status);
11738 		return status;
11739 	}
11740 
11741 	mac->sme.get_arp_stats_cb = cb;
11742 	mac->sme.get_arp_stats_context = context;
11743 	sme_release_global_lock(&mac->sme);
11744 	return status;
11745 }
11746 
11747 /**
11748  * sme_is_any_session_in_connected_state() - SME wrapper API to
11749  * check if any session is in connected state or not.
11750  *
11751  * @mac_handle: Handle returned by mac open
11752  *
11753  * This function is used to check if any valid sme session is in
11754  * connected state or not.
11755  *
11756  * Return: true if any session is connected, else false.
11757  *
11758  */
sme_is_any_session_in_connected_state(mac_handle_t mac_handle)11759 bool sme_is_any_session_in_connected_state(mac_handle_t mac_handle)
11760 {
11761 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
11762 	QDF_STATUS status;
11763 	bool ret = false;
11764 
11765 	status = sme_acquire_global_lock(&mac_ctx->sme);
11766 	if (QDF_STATUS_SUCCESS == status) {
11767 		ret = csr_is_any_session_in_connect_state(mac_ctx);
11768 		sme_release_global_lock(&mac_ctx->sme);
11769 	}
11770 	return ret;
11771 }
11772 
sme_set_chip_pwr_save_fail_cb(mac_handle_t mac_handle,pwr_save_fail_cb cb)11773 QDF_STATUS sme_set_chip_pwr_save_fail_cb(mac_handle_t mac_handle,
11774 					 pwr_save_fail_cb cb)
11775 {
11776 	QDF_STATUS status;
11777 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
11778 
11779 	status = sme_acquire_global_lock(&mac->sme);
11780 	if (status != QDF_STATUS_SUCCESS) {
11781 		sme_err("sme_AcquireGlobalLock failed!(status=%d)", status);
11782 		return status;
11783 	}
11784 	mac->sme.chip_power_save_fail_cb = cb;
11785 	sme_release_global_lock(&mac->sme);
11786 	return status;
11787 }
11788 
11789 #ifdef FEATURE_RSSI_MONITOR
11790 /**
11791  * sme_set_rssi_monitoring() - set rssi monitoring
11792  * @mac_handle: Opaque handle to the global MAC context
11793  * @input: request message
11794  *
11795  * This function constructs the vos message and fill in message type,
11796  * bodyptr with @input and posts it to WDA queue.
11797  *
11798  * Return: QDF_STATUS enumeration
11799  */
sme_set_rssi_monitoring(mac_handle_t mac_handle,struct rssi_monitor_param * input)11800 QDF_STATUS sme_set_rssi_monitoring(mac_handle_t mac_handle,
11801 				   struct rssi_monitor_param *input)
11802 {
11803 	QDF_STATUS status     = QDF_STATUS_SUCCESS;
11804 	struct mac_context *mac    = MAC_CONTEXT(mac_handle);
11805 	struct scheduler_msg message = {0};
11806 	struct rssi_monitor_param *req_msg;
11807 
11808 	SME_ENTER();
11809 	req_msg = qdf_mem_malloc(sizeof(*req_msg));
11810 	if (!req_msg)
11811 		return QDF_STATUS_E_NOMEM;
11812 
11813 	*req_msg = *input;
11814 
11815 	status = sme_acquire_global_lock(&mac->sme);
11816 	if (!QDF_IS_STATUS_SUCCESS(status)) {
11817 		sme_err("sme_acquire_global_lock failed!(status=%d)", status);
11818 		qdf_mem_free(req_msg);
11819 		return status;
11820 	}
11821 
11822 	/* Serialize the req through MC thread */
11823 	message.bodyptr = req_msg;
11824 	message.type    = WMA_SET_RSSI_MONITOR_REQ;
11825 	status = scheduler_post_message(QDF_MODULE_ID_SME,
11826 					QDF_MODULE_ID_WMA,
11827 					QDF_MODULE_ID_WMA, &message);
11828 	if (!QDF_IS_STATUS_SUCCESS(status)) {
11829 		sme_err("scheduler_post_msg failed!(err=%d)", status);
11830 		qdf_mem_free(req_msg);
11831 	}
11832 	sme_release_global_lock(&mac->sme);
11833 
11834 	return status;
11835 }
11836 
sme_set_rssi_threshold_breached_cb(mac_handle_t mac_handle,rssi_threshold_breached_cb cb)11837 QDF_STATUS sme_set_rssi_threshold_breached_cb(mac_handle_t mac_handle,
11838 					      rssi_threshold_breached_cb cb)
11839 {
11840 	QDF_STATUS status;
11841 	struct mac_context *mac;
11842 
11843 	mac = MAC_CONTEXT(mac_handle);
11844 	if (!mac) {
11845 		sme_err("Invalid mac context");
11846 		return QDF_STATUS_E_INVAL;
11847 	}
11848 
11849 	status = sme_acquire_global_lock(&mac->sme);
11850 	if (!QDF_IS_STATUS_SUCCESS(status)) {
11851 		sme_err("sme_acquire_global_lock failed!(status=%d)",
11852 			status);
11853 		return status;
11854 	}
11855 
11856 	mac->sme.rssi_threshold_breached_cb = cb;
11857 	sme_release_global_lock(&mac->sme);
11858 	return status;
11859 }
11860 #endif /* FEATURE_RSSI_MONITOR */
11861 
sme_reset_rssi_threshold_breached_cb(mac_handle_t mac_handle)11862 QDF_STATUS sme_reset_rssi_threshold_breached_cb(mac_handle_t mac_handle)
11863 {
11864 	return sme_set_rssi_threshold_breached_cb(mac_handle, NULL);
11865 }
11866 
11867 /*
11868  * sme_pdev_set_hw_mode() - Send WMI_PDEV_SET_HW_MODE_CMDID to the WMA
11869  * @mac_handle: Handle returned by macOpen
11870  * @msg: HW mode structure containing hw mode and callback details
11871  *
11872  * Sends the command to CSR to send WMI_PDEV_SET_HW_MODE_CMDID to FW
11873  * Return: QDF_STATUS_SUCCESS on successful posting
11874  */
sme_pdev_set_hw_mode(struct policy_mgr_hw_mode msg)11875 QDF_STATUS sme_pdev_set_hw_mode(struct policy_mgr_hw_mode msg)
11876 {
11877 	QDF_STATUS status = QDF_STATUS_SUCCESS;
11878 	struct mac_context *mac = sme_get_mac_context();
11879 	tSmeCmd *cmd = NULL;
11880 
11881 	if (!mac) {
11882 		sme_err("mac is NULL");
11883 		return QDF_STATUS_E_FAILURE;
11884 	}
11885 	status = sme_acquire_global_lock(&mac->sme);
11886 	if (!QDF_IS_STATUS_SUCCESS(status)) {
11887 		sme_err("Failed to acquire lock");
11888 		return QDF_STATUS_E_RESOURCES;
11889 	}
11890 
11891 	cmd = csr_get_command_buffer(mac);
11892 	if (!cmd) {
11893 		sme_err("Get command buffer failed");
11894 		sme_release_global_lock(&mac->sme);
11895 		return QDF_STATUS_E_NULL_VALUE;
11896 	}
11897 
11898 	cmd->command = e_sme_command_set_hw_mode;
11899 	cmd->vdev_id = msg.session_id;
11900 	cmd->u.set_hw_mode_cmd.hw_mode_index = msg.hw_mode_index;
11901 	cmd->u.set_hw_mode_cmd.set_hw_mode_cb = msg.set_hw_mode_cb;
11902 	cmd->u.set_hw_mode_cmd.reason = msg.reason;
11903 	cmd->u.set_hw_mode_cmd.session_id = msg.session_id;
11904 	cmd->u.set_hw_mode_cmd.next_action = msg.next_action;
11905 	cmd->u.set_hw_mode_cmd.action = msg.action;
11906 	cmd->u.set_hw_mode_cmd.context = msg.context;
11907 	cmd->u.set_hw_mode_cmd.request_id = msg.request_id;
11908 
11909 	sme_debug("Queuing set hw mode to CSR, session: %d reason: %d request_id: %x",
11910 		  cmd->u.set_hw_mode_cmd.session_id,
11911 		  cmd->u.set_hw_mode_cmd.reason,
11912 		  cmd->u.set_hw_mode_cmd.request_id);
11913 	csr_queue_sme_command(mac, cmd, false);
11914 
11915 	sme_release_global_lock(&mac->sme);
11916 	return QDF_STATUS_SUCCESS;
11917 }
11918 
sme_nss_update_request(uint32_t vdev_id,uint8_t new_nss,uint8_t ch_width,policy_mgr_nss_update_cback cback,uint8_t next_action,struct wlan_objmgr_psoc * psoc,enum policy_mgr_conn_update_reason reason,uint32_t original_vdev_id,uint32_t request_id)11919 QDF_STATUS sme_nss_update_request(uint32_t vdev_id,
11920 				uint8_t  new_nss, uint8_t ch_width,
11921 				policy_mgr_nss_update_cback cback,
11922 				uint8_t next_action, struct wlan_objmgr_psoc *psoc,
11923 				enum policy_mgr_conn_update_reason reason,
11924 				uint32_t original_vdev_id, uint32_t request_id)
11925 {
11926 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
11927 	struct mac_context *mac = sme_get_mac_context();
11928 	tSmeCmd *cmd = NULL;
11929 
11930 	if (!mac) {
11931 		sme_err("mac is null");
11932 		return status;
11933 	}
11934 	status = sme_acquire_global_lock(&mac->sme);
11935 	if (QDF_IS_STATUS_SUCCESS(status)) {
11936 		cmd = csr_get_command_buffer(mac);
11937 		if (!cmd) {
11938 			sme_err("Get command buffer failed");
11939 			sme_release_global_lock(&mac->sme);
11940 			return QDF_STATUS_E_NULL_VALUE;
11941 		}
11942 		cmd->command = e_sme_command_nss_update;
11943 		/* Sessionized modules may require this info */
11944 		cmd->vdev_id = vdev_id;
11945 		cmd->u.nss_update_cmd.new_nss = new_nss;
11946 		cmd->u.nss_update_cmd.ch_width = ch_width;
11947 		cmd->u.nss_update_cmd.session_id = vdev_id;
11948 		cmd->u.nss_update_cmd.nss_update_cb = cback;
11949 		cmd->u.nss_update_cmd.context = psoc;
11950 		cmd->u.nss_update_cmd.next_action = next_action;
11951 		cmd->u.nss_update_cmd.reason = reason;
11952 		cmd->u.nss_update_cmd.original_vdev_id = original_vdev_id;
11953 		cmd->u.nss_update_cmd.request_id = request_id;
11954 
11955 		sme_debug("Queuing e_sme_command_nss_update to CSR:vdev (%d %d) ss %d r %d req id %x",
11956 			  vdev_id, original_vdev_id, new_nss, reason, request_id);
11957 		csr_queue_sme_command(mac, cmd, false);
11958 		sme_release_global_lock(&mac->sme);
11959 	}
11960 	return status;
11961 }
11962 
11963 QDF_STATUS
sme_sap_update_ch_width(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id,enum phy_ch_width ch_width,enum policy_mgr_conn_update_reason reason,uint8_t conc_vdev_id,uint32_t request_id)11964 sme_sap_update_ch_width(struct wlan_objmgr_psoc *psoc,
11965 			uint8_t vdev_id,
11966 			enum phy_ch_width ch_width,
11967 			enum policy_mgr_conn_update_reason reason,
11968 			uint8_t conc_vdev_id, uint32_t request_id)
11969 {
11970 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
11971 	struct mac_context *mac = sme_get_mac_context();
11972 	tSmeCmd *cmd = NULL;
11973 
11974 	if (!mac) {
11975 		sme_err("mac is null");
11976 		return status;
11977 	}
11978 	status = sme_acquire_global_lock(&mac->sme);
11979 	if (QDF_IS_STATUS_ERROR(status))
11980 		return status;
11981 
11982 	cmd = csr_get_command_buffer(mac);
11983 	if (!cmd) {
11984 		sme_err("Get command buffer failed");
11985 		sme_release_global_lock(&mac->sme);
11986 		return QDF_STATUS_E_NULL_VALUE;
11987 	}
11988 	cmd->command = e_sme_command_sap_ch_width_update;
11989 	/* Sessionized modules may require this info */
11990 	cmd->vdev_id = vdev_id;
11991 	cmd->u.bw_update_cmd.ch_width = ch_width;
11992 	cmd->u.bw_update_cmd.vdev_id = vdev_id;
11993 	cmd->u.bw_update_cmd.reason = reason;
11994 	cmd->u.bw_update_cmd.request_id = request_id;
11995 	cmd->u.bw_update_cmd.conc_vdev_id = conc_vdev_id;
11996 
11997 	sme_debug("vdev %d ch_width: %d reason: %d", vdev_id, ch_width, reason);
11998 	csr_queue_sme_command(mac, cmd, false);
11999 	sme_release_global_lock(&mac->sme);
12000 
12001 	return status;
12002 }
12003 
12004 /**
12005  * sme_soc_set_dual_mac_config() - Set dual mac configurations
12006  * @mac_handle: Handle returned by macOpen
12007  * @msg: Structure containing the dual mac config parameters
12008  *
12009  * Queues configuration information to CSR to configure
12010  * WLAN firmware for the dual MAC features
12011  *
12012  * Return: QDF_STATUS
12013  */
sme_soc_set_dual_mac_config(struct policy_mgr_dual_mac_config msg)12014 QDF_STATUS sme_soc_set_dual_mac_config(struct policy_mgr_dual_mac_config msg)
12015 {
12016 	QDF_STATUS status = QDF_STATUS_SUCCESS;
12017 	struct mac_context *mac = sme_get_mac_context();
12018 	tSmeCmd *cmd;
12019 
12020 	if (!mac) {
12021 		sme_err("mac is null");
12022 		return QDF_STATUS_E_FAILURE;
12023 	}
12024 	status = sme_acquire_global_lock(&mac->sme);
12025 	if (!QDF_IS_STATUS_SUCCESS(status)) {
12026 		sme_err("Failed to acquire lock");
12027 		return QDF_STATUS_E_RESOURCES;
12028 	}
12029 
12030 	cmd = csr_get_command_buffer(mac);
12031 	if (!cmd) {
12032 		sme_err("Get command buffer failed");
12033 		sme_release_global_lock(&mac->sme);
12034 		return QDF_STATUS_E_NULL_VALUE;
12035 	}
12036 
12037 	cmd->command = e_sme_command_set_dual_mac_config;
12038 	cmd->u.set_dual_mac_cmd.scan_config = msg.scan_config;
12039 	cmd->u.set_dual_mac_cmd.fw_mode_config = msg.fw_mode_config;
12040 	cmd->u.set_dual_mac_cmd.set_dual_mac_cb = msg.set_dual_mac_cb;
12041 
12042 	sme_debug("set_dual_mac_config scan_config: %x fw_mode_config: %x",
12043 		cmd->u.set_dual_mac_cmd.scan_config,
12044 		cmd->u.set_dual_mac_cmd.fw_mode_config);
12045 	status = csr_queue_sme_command(mac, cmd, false);
12046 
12047 	sme_release_global_lock(&mac->sme);
12048 	return status;
12049 }
12050 
12051 #ifdef FEATURE_LFR_SUBNET_DETECTION
12052 /**
12053  * sme_gateway_param_update() - to update gateway parameters with WMA
12054  * @mac_handle: Opaque handle to the global MAC context
12055  * @gw_params: request parameters from HDD
12056  *
12057  * Return: QDF_STATUS
12058  *
12059  * This routine will update gateway parameters to WMA
12060  */
sme_gateway_param_update(mac_handle_t mac_handle,struct gateway_update_req_param * gw_params)12061 QDF_STATUS sme_gateway_param_update(mac_handle_t mac_handle,
12062 				    struct gateway_update_req_param *gw_params)
12063 {
12064 	QDF_STATUS qdf_status;
12065 	struct scheduler_msg message = {0};
12066 	struct gateway_update_req_param *request_buf;
12067 
12068 	request_buf = qdf_mem_malloc(sizeof(*request_buf));
12069 	if (!request_buf)
12070 		return QDF_STATUS_E_NOMEM;
12071 
12072 	*request_buf = *gw_params;
12073 
12074 	message.type = WMA_GW_PARAM_UPDATE_REQ;
12075 	message.reserved = 0;
12076 	message.bodyptr = request_buf;
12077 	qdf_status = scheduler_post_message(QDF_MODULE_ID_SME,
12078 					    QDF_MODULE_ID_WMA,
12079 					    QDF_MODULE_ID_WMA, &message);
12080 	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
12081 		sme_err("Not able to post WMA_GW_PARAM_UPDATE_REQ message to HAL");
12082 		qdf_mem_free(request_buf);
12083 		return QDF_STATUS_E_FAILURE;
12084 	}
12085 
12086 	return QDF_STATUS_SUCCESS;
12087 }
12088 #endif /* FEATURE_LFR_SUBNET_DETECTION */
12089 
12090 /**
12091  * sme_soc_set_antenna_mode() - set antenna mode
12092  * @mac_handle: Handle returned by macOpen
12093  * @msg: Structure containing the antenna mode parameters
12094  *
12095  * Send the command to CSR to send
12096  * WMI_SOC_SET_ANTENNA_MODE_CMDID to FW
12097  *
12098  * Return: QDF_STATUS
12099  */
sme_soc_set_antenna_mode(mac_handle_t mac_handle,struct sir_antenna_mode_param * msg)12100 QDF_STATUS sme_soc_set_antenna_mode(mac_handle_t mac_handle,
12101 				    struct sir_antenna_mode_param *msg)
12102 {
12103 	QDF_STATUS status = QDF_STATUS_SUCCESS;
12104 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
12105 	tSmeCmd *cmd;
12106 
12107 	if (!msg) {
12108 		sme_err("antenna mode mesg is NULL");
12109 		return QDF_STATUS_E_FAILURE;
12110 	}
12111 
12112 	status = sme_acquire_global_lock(&mac->sme);
12113 	if (!QDF_IS_STATUS_SUCCESS(status)) {
12114 		sme_err("Failed to acquire lock");
12115 		return QDF_STATUS_E_RESOURCES;
12116 	}
12117 
12118 	cmd = csr_get_command_buffer(mac);
12119 	if (!cmd) {
12120 		sme_release_global_lock(&mac->sme);
12121 		sme_err("Get command buffer failed");
12122 		return QDF_STATUS_E_NULL_VALUE;
12123 	}
12124 
12125 	cmd->command = e_sme_command_set_antenna_mode;
12126 	cmd->u.set_antenna_mode_cmd = *msg;
12127 
12128 	sme_debug("Antenna mode rx_chains: %d tx_chains: %d",
12129 		cmd->u.set_antenna_mode_cmd.num_rx_chains,
12130 		cmd->u.set_antenna_mode_cmd.num_tx_chains);
12131 
12132 	csr_queue_sme_command(mac, cmd, false);
12133 	sme_release_global_lock(&mac->sme);
12134 
12135 	return QDF_STATUS_SUCCESS;
12136 }
12137 
12138 /**
12139  * sme_set_peer_authorized() - call peer authorized callback
12140  * @peer_addr: peer mac address
12141  * @vdev_id: vdev id
12142  *
12143  * Return: QDF Status
12144  */
sme_set_peer_authorized(uint8_t * peer_addr,uint32_t vdev_id)12145 QDF_STATUS sme_set_peer_authorized(uint8_t *peer_addr,
12146 				   uint32_t vdev_id)
12147 {
12148 	void *wma_handle;
12149 
12150 	wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
12151 	if (!wma_handle)
12152 		return QDF_STATUS_E_FAILURE;
12153 
12154 	return wma_set_peer_param(wma_handle, peer_addr,
12155 				  WMI_HOST_PEER_AUTHORIZE, 1, vdev_id);
12156 }
12157 
12158 /**
12159  * sme_setdef_dot11mode() - Updates mac with default dot11mode
12160  * @mac_handle: Global MAC pointer
12161  *
12162  * Return: NULL.
12163  */
sme_setdef_dot11mode(mac_handle_t mac_handle)12164 void sme_setdef_dot11mode(mac_handle_t mac_handle)
12165 {
12166 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
12167 
12168 	csr_set_default_dot11_mode(mac_ctx);
12169 }
12170 
12171 /**
12172  * sme_update_tgt_services() - update the target services config.
12173  * @mac_handle: Opaque handle to the global MAC context.
12174  * @cfg: wma_tgt_services parameters.
12175  *
12176  * update the target services config.
12177  *
12178  * Return: None.
12179  */
sme_update_tgt_services(mac_handle_t mac_handle,struct wma_tgt_services * cfg)12180 void sme_update_tgt_services(mac_handle_t mac_handle,
12181 			     struct wma_tgt_services *cfg)
12182 {
12183 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
12184 	struct wlan_mlme_psoc_ext_obj *mlme_obj;
12185 
12186 	mlme_obj = mlme_get_psoc_ext_obj(mac_ctx->psoc);
12187 	if (!mlme_obj)
12188 		return;
12189 
12190 	mac_ctx->obss_scan_offload = cfg->obss_scan_offload;
12191 	mac_ctx->mlme_cfg->gen.as_enabled = cfg->lte_coex_ant_share;
12192 	mac_ctx->beacon_offload = cfg->beacon_offload;
12193 	mac_ctx->pmf_offload = cfg->pmf_offload;
12194 	mlme_obj->cfg.lfr.rso_user_config.is_fils_roaming_supported =
12195 				cfg->is_fils_roaming_supported;
12196 	mac_ctx->is_11k_offload_supported =
12197 				cfg->is_11k_offload_supported;
12198 	sme_debug("obss_scan_offload: %d pmf_offload: %d fils_roam support %d 11k_offload %d",
12199 		  mac_ctx->obss_scan_offload, mac_ctx->pmf_offload,
12200 		  mlme_obj->cfg.lfr.rso_user_config.is_fils_roaming_supported,
12201 		  mac_ctx->is_11k_offload_supported);
12202 	mac_ctx->bcn_reception_stats = cfg->bcn_reception_stats;
12203 }
12204 
12205 /**
12206  * sme_is_session_id_valid() - Check if the session id is valid
12207  * @mac_handle: Opaque handle to the global MAC context
12208  * @session_id: Session id
12209  *
12210  * Checks if the session id is valid or not
12211  *
12212  * Return: True is the session id is valid, false otherwise
12213  */
sme_is_session_id_valid(mac_handle_t mac_handle,uint32_t session_id)12214 bool sme_is_session_id_valid(mac_handle_t mac_handle, uint32_t session_id)
12215 {
12216 	struct mac_context *mac;
12217 
12218 	if (mac_handle) {
12219 		mac = MAC_CONTEXT(mac_handle);
12220 	} else {
12221 		sme_err("null mac pointer");
12222 		return false;
12223 	}
12224 
12225 	if (CSR_IS_SESSION_VALID(mac, session_id))
12226 		return true;
12227 
12228 	return false;
12229 }
12230 
12231 #ifdef FEATURE_WLAN_TDLS
12232 
12233 /**
12234  * sme_get_opclass() - determine operating class
12235  * @mac_handle: Opaque handle to the global MAC context
12236  * @channel: channel id
12237  * @bw_offset: bandwidth offset
12238  * @opclass: pointer to operating class
12239  *
12240  * Function will determine operating class from regdm_get_opclass_from_channel
12241  *
12242  * Return: none
12243  */
sme_get_opclass(mac_handle_t mac_handle,uint8_t channel,uint8_t bw_offset,uint8_t * opclass)12244 void sme_get_opclass(mac_handle_t mac_handle, uint8_t channel,
12245 		     uint8_t bw_offset, uint8_t *opclass)
12246 {
12247 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
12248 	uint8_t reg_cc[REG_ALPHA2_LEN + 1];
12249 
12250 	wlan_reg_read_current_country(mac_ctx->psoc, reg_cc);
12251 	/* redgm opclass table contains opclass for 40MHz low primary,
12252 	 * 40MHz high primary and 20MHz. No support for 80MHz yet. So
12253 	 * first we will check if bit for 40MHz is set and if so find
12254 	 * matching opclass either with low primary or high primary
12255 	 * (a channel would never be in both) and then search for opclass
12256 	 * matching 20MHz, else for any BW.
12257 	 */
12258 	if (bw_offset & (1 << BW_40_OFFSET_BIT)) {
12259 		*opclass = wlan_reg_dmn_get_opclass_from_channel(
12260 				reg_cc, channel, BW40_LOW_PRIMARY);
12261 		if (!(*opclass)) {
12262 			*opclass = wlan_reg_dmn_get_opclass_from_channel(
12263 					reg_cc, channel, BW40_HIGH_PRIMARY);
12264 		}
12265 	} else if (bw_offset & (1 << BW_20_OFFSET_BIT)) {
12266 		*opclass = wlan_reg_dmn_get_opclass_from_channel(
12267 				reg_cc, channel, BW20);
12268 	} else {
12269 		*opclass = wlan_reg_dmn_get_opclass_from_channel(
12270 				reg_cc, channel, BWALL);
12271 	}
12272 }
12273 #endif
12274 
12275 /**
12276  * sme_set_fw_test() - set fw test
12277  * @fw_test: fw test param
12278  *
12279  * Return: Return QDF_STATUS, otherwise appropriate failure code
12280  */
sme_set_fw_test(struct set_fwtest_params * fw_test)12281 QDF_STATUS sme_set_fw_test(struct set_fwtest_params *fw_test)
12282 {
12283 	void *wma_handle;
12284 
12285 	wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
12286 	if (!wma_handle)
12287 		return QDF_STATUS_E_FAILURE;
12288 
12289 	return wma_process_fw_test_cmd(wma_handle, fw_test);
12290 }
12291 
12292 /**
12293  * sme_ht40_stop_obss_scan() - ht40 obss stop scan
12294  * @mac_handle: mac handle
12295  * @vdev_id: vdev identifier
12296  *
12297  * Return: Return QDF_STATUS, otherwise appropriate failure code
12298  */
sme_ht40_stop_obss_scan(mac_handle_t mac_handle,uint32_t vdev_id)12299 QDF_STATUS sme_ht40_stop_obss_scan(mac_handle_t mac_handle, uint32_t vdev_id)
12300 {
12301 	void *wma_handle;
12302 
12303 	wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
12304 	if (!wma_handle)
12305 		return QDF_STATUS_E_FAILURE;
12306 
12307 	wma_ht40_stop_obss_scan(wma_handle, vdev_id);
12308 	return QDF_STATUS_SUCCESS;
12309 }
12310 
12311 #ifdef WLAN_BCN_RECV_FEATURE
sme_handle_bcn_recv_start(mac_handle_t mac_handle,uint32_t vdev_id,uint32_t nth_value,bool do_not_resume)12312 QDF_STATUS sme_handle_bcn_recv_start(mac_handle_t mac_handle,
12313 				     uint32_t vdev_id, uint32_t nth_value,
12314 				     bool do_not_resume)
12315 {
12316 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
12317 	struct csr_roam_session *session;
12318 	QDF_STATUS status;
12319 	int ret;
12320 
12321 	session = CSR_GET_SESSION(mac_ctx, vdev_id);
12322 	if (!session) {
12323 		sme_err("vdev_id %d not found", vdev_id);
12324 		return QDF_STATUS_E_FAILURE;
12325 	}
12326 
12327 	if (!CSR_IS_SESSION_VALID(mac_ctx, vdev_id)) {
12328 		sme_err("CSR session not valid: %d", vdev_id);
12329 		return QDF_STATUS_E_FAILURE;
12330 	}
12331 
12332 	status = sme_acquire_global_lock(&mac_ctx->sme);
12333 	if (QDF_IS_STATUS_SUCCESS(status)) {
12334 		if (session->is_bcn_recv_start) {
12335 			sme_release_global_lock(&mac_ctx->sme);
12336 			sme_err("Beacon receive already started");
12337 			return QDF_STATUS_SUCCESS;
12338 		}
12339 		session->is_bcn_recv_start = true;
12340 		session->beacon_report_do_not_resume = do_not_resume;
12341 		sme_release_global_lock(&mac_ctx->sme);
12342 	}
12343 
12344 	/*
12345 	 * Allows fw to send beacons of connected AP to driver.
12346 	 * MSB set : means fw do not wakeup host in wow mode
12347 	 * LSB set: Value of beacon report period (say n), Means fw sends nth
12348 	 * beacons of connected AP to HOST
12349 	 */
12350 	ret = sme_cli_set_command(vdev_id,
12351 				  wmi_vdev_param_nth_beacon_to_host,
12352 				  nth_value, VDEV_CMD);
12353 	if (ret) {
12354 		status = sme_acquire_global_lock(&mac_ctx->sme);
12355 		if (QDF_IS_STATUS_SUCCESS(status)) {
12356 			session->is_bcn_recv_start = false;
12357 			session->beacon_report_do_not_resume = false;
12358 			sme_release_global_lock(&mac_ctx->sme);
12359 		}
12360 		sme_err("wmi_vdev_param_nth_beacon_to_host %d", ret);
12361 		status = qdf_status_from_os_return(ret);
12362 	}
12363 
12364 	return status;
12365 }
12366 
sme_stop_beacon_report(mac_handle_t mac_handle,uint32_t session_id)12367 void sme_stop_beacon_report(mac_handle_t mac_handle, uint32_t session_id)
12368 {
12369 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
12370 	struct csr_roam_session *session;
12371 	QDF_STATUS status;
12372 	int ret;
12373 
12374 	session = CSR_GET_SESSION(mac_ctx, session_id);
12375 	if (!session) {
12376 		sme_err("vdev_id %d not found", session_id);
12377 		return;
12378 	}
12379 
12380 	ret = sme_cli_set_command(session_id,
12381 				  wmi_vdev_param_nth_beacon_to_host, 0,
12382 				  VDEV_CMD);
12383 	if (ret)
12384 		sme_err("wmi_vdev_param_nth_beacon_to_host command failed to FW");
12385 	status = sme_acquire_global_lock(&mac_ctx->sme);
12386 	if (QDF_IS_STATUS_SUCCESS(status)) {
12387 		session->is_bcn_recv_start = false;
12388 		session->beacon_report_do_not_resume = false;
12389 		sme_release_global_lock(&mac_ctx->sme);
12390 	}
12391 }
12392 
sme_is_beacon_report_started(mac_handle_t mac_handle,uint32_t session_id)12393 bool sme_is_beacon_report_started(mac_handle_t mac_handle, uint32_t session_id)
12394 {
12395 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
12396 	struct csr_roam_session *session;
12397 
12398 	session = CSR_GET_SESSION(mac_ctx, session_id);
12399 	if (!session) {
12400 		sme_err("vdev_id %d not found", session_id);
12401 		return false;
12402 	}
12403 
12404 	if (!CSR_IS_SESSION_VALID(mac_ctx, session_id)) {
12405 		sme_err("CSR session not valid: %d", session_id);
12406 		return false;
12407 	}
12408 
12409 	return session->is_bcn_recv_start;
12410 }
12411 
sme_is_beacon_reporting_do_not_resume(mac_handle_t mac_handle,uint32_t session_id)12412 bool sme_is_beacon_reporting_do_not_resume(mac_handle_t mac_handle,
12413 					   uint32_t session_id)
12414 {
12415 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
12416 	struct csr_roam_session *session;
12417 
12418 	session = CSR_GET_SESSION(mac_ctx, session_id);
12419 	if (!session) {
12420 		sme_err("vdev_id %d not found", session_id);
12421 		return false;
12422 	}
12423 
12424 	if (!CSR_IS_SESSION_VALID(mac_ctx, session_id)) {
12425 		sme_err("CSR session not valid: %d", session_id);
12426 		return false;
12427 	}
12428 
12429 	return session->beacon_report_do_not_resume;
12430 }
12431 #endif
12432 
12433 /**
12434  * sme_add_beacon_filter() - set the beacon filter configuration
12435  * @mac_handle: The handle returned by macOpen
12436  * @session_id: session id
12437  * @ie_map: bitwise array of IEs
12438  *
12439  * Return: Return QDF_STATUS, otherwise appropriate failure code
12440  */
sme_add_beacon_filter(mac_handle_t mac_handle,uint32_t session_id,uint32_t * ie_map)12441 QDF_STATUS sme_add_beacon_filter(mac_handle_t mac_handle,
12442 				 uint32_t session_id,
12443 				 uint32_t *ie_map)
12444 {
12445 	struct scheduler_msg message = {0};
12446 	QDF_STATUS qdf_status;
12447 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
12448 	struct beacon_filter_param *filter_param;
12449 
12450 	if (!CSR_IS_SESSION_VALID(mac_ctx, session_id)) {
12451 		sme_err("CSR session not valid: %d", session_id);
12452 		return QDF_STATUS_E_FAILURE;
12453 	}
12454 
12455 	filter_param = qdf_mem_malloc(sizeof(*filter_param));
12456 	if (!filter_param)
12457 		return QDF_STATUS_E_FAILURE;
12458 
12459 	filter_param->vdev_id = session_id;
12460 
12461 	qdf_mem_copy(filter_param->ie_map, ie_map,
12462 			SIR_BCN_FLT_MAX_ELEMS_IE_LIST * sizeof(uint32_t));
12463 
12464 	message.type = WMA_ADD_BCN_FILTER_CMDID;
12465 	message.bodyptr = filter_param;
12466 	qdf_status = scheduler_post_message(QDF_MODULE_ID_SME,
12467 					    QDF_MODULE_ID_WMA,
12468 					    QDF_MODULE_ID_WMA,
12469 					    &message);
12470 	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
12471 		sme_err("Not able to post msg to WDA!");
12472 
12473 		qdf_mem_free(filter_param);
12474 	}
12475 	return qdf_status;
12476 }
12477 
12478 /**
12479  * sme_remove_beacon_filter() - set the beacon filter configuration
12480  * @mac_handle: The handle returned by macOpen
12481  * @session_id: session id
12482  *
12483  * Return: Return QDF_STATUS, otherwise appropriate failure code
12484  */
sme_remove_beacon_filter(mac_handle_t mac_handle,uint32_t session_id)12485 QDF_STATUS sme_remove_beacon_filter(mac_handle_t mac_handle,
12486 				    uint32_t session_id)
12487 {
12488 	struct scheduler_msg message = {0};
12489 	QDF_STATUS qdf_status;
12490 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
12491 	struct beacon_filter_param *filter_param;
12492 
12493 	if (!CSR_IS_SESSION_VALID(mac_ctx, session_id)) {
12494 		sme_err("CSR session not valid: %d", session_id);
12495 		return QDF_STATUS_E_FAILURE;
12496 	}
12497 
12498 	filter_param = qdf_mem_malloc(sizeof(*filter_param));
12499 	if (!filter_param)
12500 		return QDF_STATUS_E_FAILURE;
12501 
12502 	filter_param->vdev_id = session_id;
12503 
12504 	message.type = WMA_REMOVE_BCN_FILTER_CMDID;
12505 	message.bodyptr = filter_param;
12506 	qdf_status = scheduler_post_message(QDF_MODULE_ID_SME,
12507 					    QDF_MODULE_ID_WMA,
12508 					    QDF_MODULE_ID_WMA,
12509 					    &message);
12510 	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
12511 		sme_err("Not able to post msg to WDA!");
12512 
12513 		qdf_mem_free(filter_param);
12514 	}
12515 	return qdf_status;
12516 }
12517 
12518 /**
12519  * sme_send_disassoc_req_frame - send disassoc req
12520  * @mac_handle: Opaque handle to the global MAC context
12521  * @session_id: session id
12522  * @peer_mac: peer mac address
12523  * @reason: reason for disassociation
12524  * wait_for_ack: wait for acknowledgment
12525  *
12526  * function to send disassoc request to lim
12527  *
12528  * return: none
12529  */
sme_send_disassoc_req_frame(mac_handle_t mac_handle,uint8_t session_id,uint8_t * peer_mac,uint16_t reason,uint8_t wait_for_ack)12530 void sme_send_disassoc_req_frame(mac_handle_t mac_handle, uint8_t session_id,
12531 				 uint8_t *peer_mac, uint16_t reason,
12532 				 uint8_t wait_for_ack)
12533 {
12534 	struct sme_send_disassoc_frm_req *msg;
12535 	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
12536 
12537 	msg = qdf_mem_malloc(sizeof(*msg));
12538 	if (!msg)
12539 		return;
12540 
12541 	msg->msg_type = eWNI_SME_SEND_DISASSOC_FRAME;
12542 	msg->length = sizeof(*msg);
12543 	msg->vdev_id = session_id;
12544 	qdf_mem_copy(msg->peer_mac, peer_mac, QDF_MAC_ADDR_SIZE);
12545 	msg->reason = reason;
12546 	msg->wait_for_ack = wait_for_ack;
12547 
12548 	qdf_status = umac_send_mb_message_to_mac(msg);
12549 	if (QDF_IS_STATUS_ERROR(qdf_status))
12550 		sme_err("umac_send_mb_message_to_mac failed, %d",
12551 			qdf_status);
12552 }
12553 
12554 #ifdef FEATURE_WLAN_APF
sme_get_apf_capabilities(mac_handle_t mac_handle,apf_get_offload_cb callback,void * context)12555 QDF_STATUS sme_get_apf_capabilities(mac_handle_t mac_handle,
12556 				    apf_get_offload_cb callback,
12557 				    void *context)
12558 {
12559 	QDF_STATUS          status     = QDF_STATUS_SUCCESS;
12560 	struct mac_context *     mac_ctx      = MAC_CONTEXT(mac_handle);
12561 	struct scheduler_msg           cds_msg = {0};
12562 
12563 	SME_ENTER();
12564 
12565 	status = sme_acquire_global_lock(&mac_ctx->sme);
12566 	if (QDF_STATUS_SUCCESS == status) {
12567 		/* Serialize the req through MC thread */
12568 		mac_ctx->sme.apf_get_offload_cb = callback;
12569 		mac_ctx->sme.apf_get_offload_context = context;
12570 		cds_msg.bodyptr = NULL;
12571 		cds_msg.type = WDA_APF_GET_CAPABILITIES_REQ;
12572 		status = scheduler_post_message(QDF_MODULE_ID_SME,
12573 						QDF_MODULE_ID_WMA,
12574 						QDF_MODULE_ID_WMA, &cds_msg);
12575 		if (!QDF_IS_STATUS_SUCCESS(status)) {
12576 			sme_err("Post apf get offload msg fail");
12577 			status = QDF_STATUS_E_FAILURE;
12578 		}
12579 		sme_release_global_lock(&mac_ctx->sme);
12580 	}
12581 
12582 	SME_EXIT();
12583 	return status;
12584 }
12585 
sme_set_apf_instructions(mac_handle_t mac_handle,struct sir_apf_set_offload * req)12586 QDF_STATUS sme_set_apf_instructions(mac_handle_t mac_handle,
12587 				    struct sir_apf_set_offload *req)
12588 {
12589 	void *wma_handle;
12590 
12591 	wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
12592 	if (!wma_handle)
12593 		return QDF_STATUS_E_FAILURE;
12594 
12595 	return wma_set_apf_instructions(wma_handle, req);
12596 }
12597 
sme_set_apf_enable_disable(mac_handle_t mac_handle,uint8_t vdev_id,bool apf_enable)12598 QDF_STATUS sme_set_apf_enable_disable(mac_handle_t mac_handle, uint8_t vdev_id,
12599 				      bool apf_enable)
12600 {
12601 	void *wma_handle;
12602 
12603 	wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
12604 	if (!wma_handle)
12605 		return QDF_STATUS_E_FAILURE;
12606 
12607 	return wma_send_apf_enable_cmd(wma_handle, vdev_id, apf_enable);
12608 }
12609 
12610 QDF_STATUS
sme_apf_write_work_memory(mac_handle_t mac_handle,struct wmi_apf_write_memory_params * write_params)12611 sme_apf_write_work_memory(mac_handle_t mac_handle,
12612 			struct wmi_apf_write_memory_params *write_params)
12613 {
12614 	void *wma_handle;
12615 
12616 	wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
12617 	if (!wma_handle)
12618 		return QDF_STATUS_E_FAILURE;
12619 
12620 	return wma_send_apf_write_work_memory_cmd(wma_handle, write_params);
12621 }
12622 
12623 QDF_STATUS
sme_apf_read_work_memory(mac_handle_t mac_handle,struct wmi_apf_read_memory_params * read_params,apf_read_mem_cb callback)12624 sme_apf_read_work_memory(mac_handle_t mac_handle,
12625 			 struct wmi_apf_read_memory_params *read_params,
12626 			 apf_read_mem_cb callback)
12627 {
12628 	QDF_STATUS status   = QDF_STATUS_SUCCESS;
12629 	struct mac_context *mac  = MAC_CONTEXT(mac_handle);
12630 	void *wma_handle;
12631 
12632 	status = sme_acquire_global_lock(&mac->sme);
12633 	if (QDF_IS_STATUS_SUCCESS(status)) {
12634 		mac->sme.apf_read_mem_cb = callback;
12635 		sme_release_global_lock(&mac->sme);
12636 	} else {
12637 		sme_err("sme_acquire_global_lock failed");
12638 	}
12639 
12640 	wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
12641 	if (!wma_handle)
12642 		return QDF_STATUS_E_FAILURE;
12643 
12644 	return wma_send_apf_read_work_memory_cmd(wma_handle, read_params);
12645 }
12646 #endif /* FEATURE_WLAN_APF */
12647 
12648 /**
12649  * sme_get_wni_dot11_mode() - return configured wni dot11mode
12650  * @mac_handle: Opaque handle to the global MAC context
12651  *
12652  * Return: wni dot11 mode.
12653  */
sme_get_wni_dot11_mode(mac_handle_t mac_handle)12654 uint32_t sme_get_wni_dot11_mode(mac_handle_t mac_handle)
12655 {
12656 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
12657 
12658 	return csr_translate_to_wni_cfg_dot11_mode(mac_ctx,
12659 		mac_ctx->roam.configParam.uCfgDot11Mode);
12660 }
12661 
12662 /**
12663  * sme_create_mon_session() - post message to create PE session for monitormode
12664  * operation
12665  * @mac_handle: Opaque handle to the global MAC context
12666  * @bssid: pointer to bssid
12667  * @vdev_id: sme session id
12668  *
12669  * Return: QDF_STATUS_SUCCESS on success, non-zero error code on failure.
12670  */
sme_create_mon_session(mac_handle_t mac_handle,uint8_t * bss_id,uint8_t vdev_id)12671 QDF_STATUS sme_create_mon_session(mac_handle_t mac_handle, uint8_t *bss_id,
12672 				  uint8_t vdev_id)
12673 {
12674 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
12675 	struct sir_create_session *msg;
12676 
12677 	msg = qdf_mem_malloc(sizeof(*msg));
12678 	if (msg) {
12679 		msg->type = eWNI_SME_MON_INIT_SESSION;
12680 		msg->vdev_id = vdev_id;
12681 		msg->msg_len = sizeof(*msg);
12682 		qdf_mem_copy(msg->bss_id.bytes, bss_id, QDF_MAC_ADDR_SIZE);
12683 		status = umac_send_mb_message_to_mac(msg);
12684 	}
12685 	return status;
12686 }
12687 
sme_delete_mon_session(mac_handle_t mac_handle,uint8_t vdev_id)12688 QDF_STATUS sme_delete_mon_session(mac_handle_t mac_handle, uint8_t vdev_id)
12689 {
12690 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
12691 	struct sir_delete_session *msg;
12692 
12693 	msg = qdf_mem_malloc(sizeof(*msg));
12694 	if (msg) {
12695 		msg->type = eWNI_SME_MON_DEINIT_SESSION;
12696 		msg->vdev_id = vdev_id;
12697 		msg->msg_len = sizeof(*msg);
12698 		status = umac_send_mb_message_to_mac(msg);
12699 	}
12700 
12701 	return status;
12702 }
12703 
12704 void
sme_set_del_peers_ind_callback(mac_handle_t mac_handle,void (* callback)(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id))12705 sme_set_del_peers_ind_callback(mac_handle_t mac_handle,
12706 			       void (*callback)(struct wlan_objmgr_psoc *psoc,
12707 						uint8_t vdev_id))
12708 {
12709 	struct mac_context *mac;
12710 
12711 	if (!mac_handle) {
12712 		QDF_ASSERT(0);
12713 		return;
12714 	}
12715 	mac = MAC_CONTEXT(mac_handle);
12716 	mac->del_peers_ind_cb = callback;
12717 }
12718 
sme_set_chan_info_callback(mac_handle_t mac_handle,void (* callback)(struct scan_chan_info * chan_info))12719 void sme_set_chan_info_callback(mac_handle_t mac_handle,
12720 			void (*callback)(struct scan_chan_info *chan_info))
12721 {
12722 	struct mac_context *mac;
12723 
12724 	if (!mac_handle) {
12725 		QDF_ASSERT(0);
12726 		return;
12727 	}
12728 	mac = MAC_CONTEXT(mac_handle);
12729 	mac->chan_info_cb = callback;
12730 }
12731 
12732 #ifdef WLAN_FEATURE_CAL_FAILURE_TRIGGER
sme_set_cal_failure_event_cb(mac_handle_t mac_handle,void (* callback)(uint8_t cal_type,uint8_t reason))12733 void sme_set_cal_failure_event_cb(
12734 			mac_handle_t mac_handle,
12735 			void (*callback)(uint8_t cal_type, uint8_t reason))
12736 {
12737 	struct mac_context *mac;
12738 	QDF_STATUS status   = QDF_STATUS_SUCCESS;
12739 
12740 	if (!mac_handle) {
12741 		QDF_ASSERT(0);
12742 		return;
12743 	}
12744 	mac = MAC_CONTEXT(mac_handle);
12745 
12746 	status = sme_acquire_global_lock(&mac->sme);
12747 	if (QDF_IS_STATUS_SUCCESS(status)) {
12748 		mac->cal_failure_event_cb = callback;
12749 		sme_release_global_lock(&mac->sme);
12750 	} else {
12751 		sme_err("sme_acquire_global_lock failed");
12752 	}
12753 }
12754 #endif
12755 
sme_set_vdev_ies_per_band(mac_handle_t mac_handle,uint8_t vdev_id,enum QDF_OPMODE device_mode)12756 void sme_set_vdev_ies_per_band(mac_handle_t mac_handle, uint8_t vdev_id,
12757 			       enum QDF_OPMODE device_mode)
12758 {
12759 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
12760 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
12761 
12762 	status = sme_acquire_global_lock(&mac_ctx->sme);
12763 	if (QDF_IS_STATUS_SUCCESS(status)) {
12764 		csr_set_vdev_ies_per_band(mac_handle, vdev_id,
12765 					  device_mode);
12766 		sme_release_global_lock(&mac_ctx->sme);
12767 	}
12768 }
12769 
12770 /**
12771  * sme_set_pdev_ht_vht_ies() - sends the set pdev IE req
12772  * @mac_handle: Opaque handle to the global MAC context
12773  * @enable2x2: 1x1 or 2x2 mode.
12774  *
12775  * Sends the set pdev IE req with Nss value.
12776  *
12777  * Return: None
12778  */
sme_set_pdev_ht_vht_ies(mac_handle_t mac_handle,bool enable2x2)12779 void sme_set_pdev_ht_vht_ies(mac_handle_t mac_handle, bool enable2x2)
12780 {
12781 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
12782 	struct sir_set_ht_vht_cfg *ht_vht_cfg;
12783 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
12784 
12785 	if (!((mac_ctx->roam.configParam.uCfgDot11Mode ==
12786 					eCSR_CFG_DOT11_MODE_AUTO) ||
12787 				(mac_ctx->roam.configParam.uCfgDot11Mode ==
12788 				 eCSR_CFG_DOT11_MODE_11N) ||
12789 				(mac_ctx->roam.configParam.uCfgDot11Mode ==
12790 				 eCSR_CFG_DOT11_MODE_11N_ONLY) ||
12791 				(mac_ctx->roam.configParam.uCfgDot11Mode ==
12792 				 eCSR_CFG_DOT11_MODE_11AC) ||
12793 				(mac_ctx->roam.configParam.uCfgDot11Mode ==
12794 				 eCSR_CFG_DOT11_MODE_11AC_ONLY)))
12795 		return;
12796 
12797 	status = sme_acquire_global_lock(&mac_ctx->sme);
12798 	if (QDF_STATUS_SUCCESS == status) {
12799 		ht_vht_cfg = qdf_mem_malloc(sizeof(*ht_vht_cfg));
12800 		if (!ht_vht_cfg) {
12801 			sme_release_global_lock(&mac_ctx->sme);
12802 			return;
12803 		}
12804 
12805 		ht_vht_cfg->pdev_id = 0;
12806 		if (enable2x2)
12807 			ht_vht_cfg->nss = 2;
12808 		else
12809 			ht_vht_cfg->nss = 1;
12810 		ht_vht_cfg->dot11mode =
12811 			(uint8_t)csr_translate_to_wni_cfg_dot11_mode(mac_ctx,
12812 				mac_ctx->roam.configParam.uCfgDot11Mode);
12813 
12814 		ht_vht_cfg->msg_type = eWNI_SME_PDEV_SET_HT_VHT_IE;
12815 		ht_vht_cfg->len = sizeof(*ht_vht_cfg);
12816 		sme_debug("SET_HT_VHT_IE with nss: %d, dot11mode: %d",
12817 			  ht_vht_cfg->nss,
12818 			  ht_vht_cfg->dot11mode);
12819 		status = umac_send_mb_message_to_mac(ht_vht_cfg);
12820 		if (QDF_STATUS_SUCCESS != status)
12821 			sme_err("Send SME_PDEV_SET_HT_VHT_IE fail");
12822 
12823 		sme_release_global_lock(&mac_ctx->sme);
12824 	}
12825 }
12826 
sme_get_sap_vdev_type_nss(mac_handle_t mac_handle,uint8_t * vdev_nss,enum band_info band)12827 void sme_get_sap_vdev_type_nss(mac_handle_t mac_handle, uint8_t *vdev_nss,
12828 			       enum band_info band)
12829 {
12830 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
12831 
12832 	if (band == BAND_5G)
12833 		*vdev_nss = mac_ctx->vdev_type_nss_5g.sap;
12834 	else
12835 		*vdev_nss = mac_ctx->vdev_type_nss_2g.sap;
12836 }
12837 
sme_update_vdev_type_nss(mac_handle_t mac_handle,uint8_t max_supp_nss,enum nss_chains_band_info band)12838 void sme_update_vdev_type_nss(mac_handle_t mac_handle, uint8_t max_supp_nss,
12839 			      enum nss_chains_band_info band)
12840 {
12841 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
12842 	struct vdev_type_nss *vdev_nss;
12843 
12844 	struct wlan_mlme_nss_chains *nss_chains_ini_cfg =
12845 					&mac_ctx->mlme_cfg->nss_chains_ini_cfg;
12846 
12847 	if (band == NSS_CHAINS_BAND_5GHZ)
12848 		vdev_nss = &mac_ctx->vdev_type_nss_5g;
12849 	else
12850 		vdev_nss = &mac_ctx->vdev_type_nss_2g;
12851 
12852 	vdev_nss->sta = QDF_MIN(max_supp_nss, GET_VDEV_NSS_CHAIN(
12853 						nss_chains_ini_cfg->
12854 							rx_nss[band],
12855 						STA_NSS_CHAINS_SHIFT));
12856 	vdev_nss->sap = QDF_MIN(max_supp_nss, GET_VDEV_NSS_CHAIN(
12857 						nss_chains_ini_cfg->
12858 							rx_nss[band],
12859 						SAP_NSS_CHAINS_SHIFT));
12860 	vdev_nss->p2p_go = QDF_MIN(max_supp_nss, GET_VDEV_NSS_CHAIN(
12861 						nss_chains_ini_cfg->
12862 							rx_nss[band],
12863 						P2P_GO_NSS_CHAINS_SHIFT));
12864 	vdev_nss->p2p_cli = QDF_MIN(max_supp_nss, GET_VDEV_NSS_CHAIN(
12865 						nss_chains_ini_cfg->
12866 							rx_nss[band],
12867 						P2P_CLI_CHAINS_SHIFT));
12868 	vdev_nss->p2p_dev = QDF_MIN(max_supp_nss, GET_VDEV_NSS_CHAIN(
12869 						nss_chains_ini_cfg->
12870 							rx_nss[band],
12871 						P2P_DEV_NSS_CHAINS_SHIFT));
12872 	vdev_nss->ibss = QDF_MIN(max_supp_nss, GET_VDEV_NSS_CHAIN(
12873 						nss_chains_ini_cfg->
12874 							rx_nss[band],
12875 						IBSS_NSS_CHAINS_SHIFT));
12876 	vdev_nss->tdls = QDF_MIN(max_supp_nss, GET_VDEV_NSS_CHAIN(
12877 						nss_chains_ini_cfg->
12878 							rx_nss[band],
12879 						TDLS_NSS_CHAINS_SHIFT));
12880 	vdev_nss->ocb = QDF_MIN(max_supp_nss, GET_VDEV_NSS_CHAIN(
12881 						nss_chains_ini_cfg->
12882 							rx_nss[band],
12883 						OCB_NSS_CHAINS_SHIFT));
12884 	vdev_nss->nan = QDF_MIN(max_supp_nss, GET_VDEV_NSS_CHAIN(
12885 						nss_chains_ini_cfg->
12886 							rx_nss[band],
12887 						NAN_NSS_CHAIN_SHIFT));
12888 	vdev_nss->ndi = QDF_MIN(max_supp_nss, GET_VDEV_NSS_CHAIN(
12889 						nss_chains_ini_cfg->
12890 							rx_nss[band],
12891 						NAN_NSS_CHAIN_SHIFT));
12892 
12893 	sme_debug("band %d NSS:sta %d sap %d cli %d go %d dev %d ibss %d tdls %d ocb %d nan %d",
12894 		  band, vdev_nss->sta, vdev_nss->sap, vdev_nss->p2p_cli,
12895 		  vdev_nss->p2p_go, vdev_nss->p2p_dev, vdev_nss->ibss,
12896 		  vdev_nss->tdls, vdev_nss->ocb, vdev_nss->nan);
12897 }
12898 
12899 #ifdef WLAN_FEATURE_11AX_BSS_COLOR
12900 #define MAX_BSS_COLOR_VAL 63
12901 #define MIN_BSS_COLOR_VAL 1
12902 
sme_set_he_bss_color(mac_handle_t mac_handle,uint8_t session_id,uint8_t bss_color)12903 QDF_STATUS sme_set_he_bss_color(mac_handle_t mac_handle, uint8_t session_id,
12904 				uint8_t bss_color)
12905 
12906 {
12907 	struct sir_set_he_bss_color *bss_color_msg;
12908 	uint8_t len;
12909 
12910 	if (!mac_handle) {
12911 		sme_err("Invalid mac_handle pointer");
12912 		return QDF_STATUS_E_FAULT;
12913 	}
12914 
12915 	sme_debug("Set HE bss_color  %d", bss_color);
12916 
12917 	if (bss_color < MIN_BSS_COLOR_VAL || bss_color > MAX_BSS_COLOR_VAL) {
12918 		sme_debug("Invalid HE bss_color  %d", bss_color);
12919 		return QDF_STATUS_E_INVAL;
12920 	}
12921 	len = sizeof(*bss_color_msg);
12922 	bss_color_msg = qdf_mem_malloc(len);
12923 	if (!bss_color_msg)
12924 		return QDF_STATUS_E_NOMEM;
12925 
12926 	bss_color_msg->message_type = eWNI_SME_SET_HE_BSS_COLOR;
12927 	bss_color_msg->length = len;
12928 	bss_color_msg->vdev_id = session_id;
12929 	bss_color_msg->bss_color = bss_color;
12930 	return umac_send_mb_message_to_mac(bss_color_msg);
12931 }
12932 
sme_reconfig_obss_scan_param(mac_handle_t mac_handle,uint8_t session_id,bool is_scan_reconfig)12933 QDF_STATUS sme_reconfig_obss_scan_param(mac_handle_t mac_handle,
12934 					uint8_t session_id,
12935 					bool is_scan_reconfig)
12936 {
12937 	struct sir_cfg_obss_scan *obss_scan_msg;
12938 	uint8_t len;
12939 
12940 	if (!mac_handle) {
12941 		sme_err("Invalid mac_handle pointer");
12942 		return QDF_STATUS_E_FAULT;
12943 	}
12944 
12945 	len = sizeof(*obss_scan_msg);
12946 	obss_scan_msg = qdf_mem_malloc(len);
12947 	if (!obss_scan_msg)
12948 		return QDF_STATUS_E_NOMEM;
12949 
12950 	obss_scan_msg->message_type = eWNI_SME_RECONFIG_OBSS_SCAN_PARAM;
12951 	obss_scan_msg->length = len;
12952 	obss_scan_msg->vdev_id = session_id;
12953 	obss_scan_msg->is_scan_reconfig = is_scan_reconfig;
12954 	return umac_send_mb_message_to_mac(obss_scan_msg);
12955 }
12956 #endif
12957 
12958 #ifdef FEATURE_P2P_LISTEN_OFFLOAD
12959 /**
12960  * sme_register_p2p_lo_event() - Register for the p2p lo event
12961  * @mac_handle: Opaque handle to the global MAC context
12962  * @context: the context of the call
12963  * @callback: the callback to hdd
12964  *
12965  * This function registers the callback function for P2P listen
12966  * offload stop event.
12967  *
12968  * Return: none
12969  */
sme_register_p2p_lo_event(mac_handle_t mac_handle,void * context,p2p_lo_callback callback)12970 void sme_register_p2p_lo_event(mac_handle_t mac_handle, void *context,
12971 			       p2p_lo_callback callback)
12972 {
12973 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
12974 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
12975 
12976 	status = sme_acquire_global_lock(&mac->sme);
12977 	mac->sme.p2p_lo_event_callback = callback;
12978 	mac->sme.p2p_lo_event_context = context;
12979 	sme_release_global_lock(&mac->sme);
12980 }
12981 #endif
12982 
12983 /**
12984  * sme_process_mac_pwr_dbg_cmd() - enable mac pwr debugging
12985  * @mac_handle: The handle returned by macOpen
12986  * @session_id: session id
12987  * @dbg_args: args for mac pwr debug command
12988  * Return: Return QDF_STATUS, otherwise appropriate failure code
12989  */
sme_process_mac_pwr_dbg_cmd(mac_handle_t mac_handle,uint32_t session_id,struct sir_mac_pwr_dbg_cmd * dbg_args)12990 QDF_STATUS sme_process_mac_pwr_dbg_cmd(mac_handle_t mac_handle,
12991 				       uint32_t session_id,
12992 				       struct sir_mac_pwr_dbg_cmd *dbg_args)
12993 {
12994 	struct scheduler_msg message = {0};
12995 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
12996 	struct sir_mac_pwr_dbg_cmd *req;
12997 	int i;
12998 
12999 	if (!CSR_IS_SESSION_VALID(mac_ctx, session_id)) {
13000 		sme_err("CSR session not valid: %d", session_id);
13001 		return QDF_STATUS_E_FAILURE;
13002 	}
13003 
13004 	req = qdf_mem_malloc(sizeof(*req));
13005 	if (!req)
13006 		return QDF_STATUS_E_FAILURE;
13007 
13008 	req->module_id = dbg_args->module_id;
13009 	req->pdev_id = dbg_args->pdev_id;
13010 	req->num_args = dbg_args->num_args;
13011 	for (i = 0; i < req->num_args; i++)
13012 		req->args[i] = dbg_args->args[i];
13013 
13014 	message.type = SIR_HAL_POWER_DBG_CMD;
13015 	message.bodyptr = req;
13016 
13017 	if (!QDF_IS_STATUS_SUCCESS(scheduler_post_message(QDF_MODULE_ID_SME,
13018 							  QDF_MODULE_ID_WMA,
13019 							  QDF_MODULE_ID_WMA,
13020 							  &message))) {
13021 		sme_err("Not able to post msg to WDA!");
13022 		qdf_mem_free(req);
13023 	}
13024 	return QDF_STATUS_SUCCESS;
13025 }
13026 /**
13027  * sme_get_vdev_type_nss() - gets the nss per vdev type
13028  * @dev_mode: connection type.
13029  * @nss2g: Pointer to the 2G Nss parameter.
13030  * @nss5g: Pointer to the 5G Nss parameter.
13031  *
13032  * Fills the 2G and 5G Nss values based on connection type.
13033  *
13034  * Return: None
13035  */
sme_get_vdev_type_nss(enum QDF_OPMODE dev_mode,uint8_t * nss_2g,uint8_t * nss_5g)13036 void sme_get_vdev_type_nss(enum QDF_OPMODE dev_mode,
13037 			   uint8_t *nss_2g, uint8_t *nss_5g)
13038 {
13039 	csr_get_vdev_type_nss(dev_mode, nss_2g, nss_5g);
13040 }
13041 
13042 /**
13043  * sme_update_sta_roam_policy() - update sta roam policy for
13044  * unsafe and DFS channels.
13045  * @mac_handle: Opaque handle to the global MAC context
13046  * @dfs_mode: dfs mode which tell if dfs channel needs to be
13047  * skipped or not
13048  * @skip_unsafe_channels: Param to tell if driver needs to
13049  * skip unsafe channels or not.
13050  * @vdev_id: vdev_id
13051  * @sap_operating_band: Band on which SAP is operating
13052  *
13053  * sme_update_sta_roam_policy update sta rome policies to csr
13054  * this function will call csrUpdateChannelList as well
13055  * to include/exclude DFS channels and unsafe channels.
13056  *
13057  * Return: eHAL_STATUS_SUCCESS or non-zero on failure.
13058  */
sme_update_sta_roam_policy(mac_handle_t mac_handle,enum sta_roam_policy_dfs_mode dfs_mode,bool skip_unsafe_channels,uint8_t vdev_id,uint8_t sap_operating_band)13059 QDF_STATUS sme_update_sta_roam_policy(mac_handle_t mac_handle,
13060 				      enum sta_roam_policy_dfs_mode dfs_mode,
13061 				      bool skip_unsafe_channels,
13062 				      uint8_t vdev_id,
13063 				      uint8_t sap_operating_band)
13064 {
13065 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
13066 	QDF_STATUS status = QDF_STATUS_SUCCESS;
13067 	struct wlan_mlme_psoc_ext_obj *mlme_obj;
13068 
13069 	if (!mac_ctx) {
13070 		sme_err("mac_ctx is null");
13071 		return QDF_STATUS_E_FAILURE;
13072 	}
13073 
13074 	mlme_obj = mlme_get_psoc_ext_obj(mac_ctx->psoc);
13075 	if (!mlme_obj)
13076 		return QDF_STATUS_E_FAILURE;
13077 
13078 	mlme_obj->cfg.lfr.rso_user_config.policy_params.dfs_mode =
13079 		dfs_mode;
13080 	mlme_obj->cfg.lfr.rso_user_config.policy_params.skip_unsafe_channels =
13081 		skip_unsafe_channels;
13082 	mlme_obj->cfg.lfr.rso_user_config.policy_params.sap_operating_band =
13083 		sap_operating_band;
13084 
13085 	status = csr_update_channel_list(mac_ctx);
13086 	if (QDF_STATUS_SUCCESS != status) {
13087 		sme_err("failed to update the supported channel list");
13088 	}
13089 
13090 	if (mac_ctx->mlme_cfg->lfr.roam_scan_offload_enabled) {
13091 		status = sme_acquire_global_lock(&mac_ctx->sme);
13092 		if (QDF_IS_STATUS_SUCCESS(status)) {
13093 			wlan_roam_update_cfg(mac_ctx->psoc, vdev_id,
13094 				      REASON_ROAM_SCAN_STA_ROAM_POLICY_CHANGED);
13095 			sme_release_global_lock(&mac_ctx->sme);
13096 		}
13097 	}
13098 
13099 	return status;
13100 }
13101 
13102 /**
13103  * sme_enable_disable_chanavoidind_event - configure ca event ind
13104  * @mac_handle: Opaque handle to the global MAC context
13105  * @set_value: enable/disable
13106  *
13107  * function to enable/disable chan avoidance indication
13108  *
13109  * Return: QDF_STATUS
13110  */
sme_enable_disable_chanavoidind_event(mac_handle_t mac_handle,uint8_t set_value)13111 QDF_STATUS sme_enable_disable_chanavoidind_event(mac_handle_t mac_handle,
13112 						 uint8_t set_value)
13113 {
13114 	QDF_STATUS status;
13115 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
13116 	struct scheduler_msg msg = {0};
13117 
13118 	if (!mac_ctx->mlme_cfg->gen.optimize_ca_event) {
13119 		sme_debug("optimize_ca_event not enabled in ini");
13120 		return QDF_STATUS_E_NOSUPPORT;
13121 	}
13122 
13123 	sme_debug("set_value: %d", set_value);
13124 	status = sme_acquire_global_lock(&mac_ctx->sme);
13125 	if (QDF_STATUS_SUCCESS == status) {
13126 		qdf_mem_zero(&msg, sizeof(struct scheduler_msg));
13127 		msg.type = WMA_SEND_FREQ_RANGE_CONTROL_IND;
13128 		msg.bodyval = set_value;
13129 		status = scheduler_post_message(QDF_MODULE_ID_SME,
13130 						QDF_MODULE_ID_WMA,
13131 						QDF_MODULE_ID_WMA, &msg);
13132 		sme_release_global_lock(&mac_ctx->sme);
13133 		return status;
13134 	}
13135 	return status;
13136 }
13137 
13138 /*
13139  * sme_set_default_scan_ie() - API to send default scan IE to LIM
13140  * @mac_handle: Opaque handle to the global MAC context
13141  * @session_id: current session ID
13142  * @ie_data: Pointer to Scan IE data
13143  * @ie_len: Length of @ie_data
13144  *
13145  * Return: QDF_STATUS
13146  */
sme_set_default_scan_ie(mac_handle_t mac_handle,uint16_t session_id,uint8_t * ie_data,uint16_t ie_len)13147 QDF_STATUS sme_set_default_scan_ie(mac_handle_t mac_handle, uint16_t session_id,
13148 				   uint8_t *ie_data, uint16_t ie_len)
13149 {
13150 	QDF_STATUS status;
13151 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
13152 	struct hdd_default_scan_ie *set_ie_params;
13153 
13154 	if (!ie_data)
13155 		return QDF_STATUS_E_INVAL;
13156 
13157 	status = sme_acquire_global_lock(&mac_ctx->sme);
13158 	if (QDF_IS_STATUS_SUCCESS(status)) {
13159 		set_ie_params = qdf_mem_malloc(sizeof(*set_ie_params));
13160 		if (!set_ie_params)
13161 			status = QDF_STATUS_E_NOMEM;
13162 		else {
13163 			set_ie_params->message_type = eWNI_SME_DEFAULT_SCAN_IE;
13164 			set_ie_params->length = sizeof(*set_ie_params);
13165 			set_ie_params->vdev_id = session_id;
13166 			set_ie_params->ie_len = ie_len;
13167 			qdf_mem_copy(set_ie_params->ie_data, ie_data, ie_len);
13168 			status = umac_send_mb_message_to_mac(set_ie_params);
13169 		}
13170 		sme_release_global_lock(&mac_ctx->sme);
13171 	}
13172 	return status;
13173 }
13174 
sme_get_sar_power_limits(mac_handle_t mac_handle,wma_sar_cb callback,void * context)13175 QDF_STATUS sme_get_sar_power_limits(mac_handle_t mac_handle,
13176 				    wma_sar_cb callback, void *context)
13177 {
13178 	void *wma_handle;
13179 
13180 	wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
13181 	if (!wma_handle)
13182 		return QDF_STATUS_E_FAILURE;
13183 
13184 	return wma_get_sar_limit(wma_handle, callback, context);
13185 }
13186 
sme_set_sar_power_limits(mac_handle_t mac_handle,struct sar_limit_cmd_params * sar_limit_cmd)13187 QDF_STATUS sme_set_sar_power_limits(mac_handle_t mac_handle,
13188 				    struct sar_limit_cmd_params *sar_limit_cmd)
13189 {
13190 	void *wma_handle;
13191 
13192 	wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
13193 	if (!wma_handle)
13194 		return QDF_STATUS_E_FAILURE;
13195 
13196 	return wma_set_sar_limit(wma_handle, sar_limit_cmd);
13197 }
13198 
sme_send_coex_config_cmd(struct coex_config_params * coex_cfg_params)13199 QDF_STATUS sme_send_coex_config_cmd(struct coex_config_params *coex_cfg_params)
13200 {
13201 	void *wma_handle;
13202 
13203 	wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
13204 	if (!wma_handle)
13205 		return QDF_STATUS_E_FAILURE;
13206 
13207 	return wma_send_coex_config_cmd(wma_handle, coex_cfg_params);
13208 }
13209 
13210 #ifdef WLAN_FEATURE_FIPS
sme_fips_request(mac_handle_t mac_handle,struct fips_params * param,wma_fips_cb callback,void * context)13211 QDF_STATUS sme_fips_request(mac_handle_t mac_handle, struct fips_params *param,
13212 			    wma_fips_cb callback, void *context)
13213 {
13214 	void *wma_handle;
13215 
13216 	wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
13217 	if (!wma_handle)
13218 		return QDF_STATUS_E_FAILURE;
13219 
13220 	return wma_fips_request(wma_handle, param, callback, context);
13221 }
13222 #endif
13223 
sme_set_cts2self_for_p2p_go(mac_handle_t mac_handle)13224 QDF_STATUS sme_set_cts2self_for_p2p_go(mac_handle_t mac_handle)
13225 {
13226 	void *wma_handle;
13227 
13228 	wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
13229 	if (!wma_handle)
13230 		return QDF_STATUS_E_FAILURE;
13231 
13232 	if (QDF_STATUS_SUCCESS !=
13233 		wma_set_cts2self_for_p2p_go(wma_handle, true)) {
13234 		sme_err("Failed to set cts2self for p2p GO to firmware");
13235 		return QDF_STATUS_E_FAILURE;
13236 	}
13237 	return QDF_STATUS_SUCCESS;
13238 }
13239 
13240 /**
13241  * sme_update_tx_fail_cnt_threshold() - update tx fail count Threshold
13242  * @mac_handle: Handle returned by mac_open
13243  * @session_id: Session ID on which tx fail count needs to be updated to FW
13244  * @tx_fail_count: Count for tx fail threshold after which FW will disconnect
13245  *
13246  * This function is used to set tx fail count threshold to firmware.
13247  * firmware will issue disocnnect with peer device once this threshold is
13248  * reached.
13249  *
13250  * Return: Return QDF_STATUS, otherwise appropriate failure code
13251  */
sme_update_tx_fail_cnt_threshold(mac_handle_t mac_handle,uint8_t session_id,uint32_t tx_fail_count)13252 QDF_STATUS sme_update_tx_fail_cnt_threshold(mac_handle_t mac_handle,
13253 					    uint8_t session_id,
13254 					    uint32_t tx_fail_count)
13255 {
13256 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
13257 	struct sme_tx_fail_cnt_threshold *tx_fail_cnt;
13258 	struct scheduler_msg msg = {0};
13259 
13260 	tx_fail_cnt = qdf_mem_malloc(sizeof(*tx_fail_cnt));
13261 	if (!tx_fail_cnt)
13262 		return QDF_STATUS_E_FAILURE;
13263 
13264 	sme_debug("session_id: %d tx_fail_count: %d",
13265 		  session_id, tx_fail_count);
13266 	tx_fail_cnt->session_id = session_id;
13267 	tx_fail_cnt->tx_fail_cnt_threshold = tx_fail_count;
13268 
13269 	qdf_mem_zero(&msg, sizeof(struct scheduler_msg));
13270 	msg.type = SIR_HAL_UPDATE_TX_FAIL_CNT_TH;
13271 	msg.reserved = 0;
13272 	msg.bodyptr = tx_fail_cnt;
13273 	status = scheduler_post_message(QDF_MODULE_ID_SME,
13274 					QDF_MODULE_ID_WMA,
13275 					QDF_MODULE_ID_WMA, &msg);
13276 
13277 	if (!QDF_IS_STATUS_SUCCESS(status)) {
13278 		sme_err("Not able to post Tx fail count message to WDA");
13279 		qdf_mem_free(tx_fail_cnt);
13280 	}
13281 	return status;
13282 }
13283 
sme_set_lost_link_info_cb(mac_handle_t mac_handle,lost_link_info_cb cb)13284 QDF_STATUS sme_set_lost_link_info_cb(mac_handle_t mac_handle,
13285 				     lost_link_info_cb cb)
13286 {
13287 	QDF_STATUS status;
13288 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
13289 
13290 	status = sme_acquire_global_lock(&mac->sme);
13291 	if (QDF_IS_STATUS_SUCCESS(status)) {
13292 		mac->sme.lost_link_info_cb = cb;
13293 		sme_release_global_lock(&mac->sme);
13294 	}
13295 
13296 	return status;
13297 }
13298 
sme_neighbor_roam_is11r_assoc(mac_handle_t mac_handle,uint8_t session_id)13299 bool sme_neighbor_roam_is11r_assoc(mac_handle_t mac_handle, uint8_t session_id)
13300 {
13301 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
13302 	struct cm_roam_values_copy config;
13303 
13304 	wlan_cm_roam_cfg_get_value(mac_ctx->psoc, session_id, IS_11R_CONNECTION,
13305 				   &config);
13306 
13307 	return config.bool_value;
13308 }
13309 
13310 #ifdef WLAN_FEATURE_WOW_PULSE
13311 /**
13312  * sme_set_wow_pulse() - set wow pulse info
13313  * @wow_pulse_set_info: wow_pulse_mode structure pointer
13314  *
13315  * Return: QDF_STATUS
13316  */
sme_set_wow_pulse(struct wow_pulse_mode * wow_pulse_set_info)13317 QDF_STATUS sme_set_wow_pulse(struct wow_pulse_mode *wow_pulse_set_info)
13318 {
13319 	struct scheduler_msg message = {0};
13320 	QDF_STATUS status;
13321 	struct wow_pulse_mode *wow_pulse_set_cmd;
13322 
13323 	if (!wow_pulse_set_info) {
13324 		sme_err("invalid wow_pulse_set_info pointer");
13325 		return QDF_STATUS_E_FAILURE;
13326 	}
13327 
13328 	wow_pulse_set_cmd = qdf_mem_malloc(sizeof(*wow_pulse_set_cmd));
13329 	if (!wow_pulse_set_cmd)
13330 		return QDF_STATUS_E_NOMEM;
13331 
13332 	*wow_pulse_set_cmd = *wow_pulse_set_info;
13333 
13334 	message.type = WMA_SET_WOW_PULSE_CMD;
13335 	message.bodyptr = wow_pulse_set_cmd;
13336 	status = scheduler_post_message(QDF_MODULE_ID_SME,
13337 					QDF_MODULE_ID_WMA,
13338 					QDF_MODULE_ID_WMA,
13339 					&message);
13340 	if (!QDF_IS_STATUS_SUCCESS(status)) {
13341 		sme_err("Not able to post msg to WDA!");
13342 		qdf_mem_free(wow_pulse_set_cmd);
13343 		status = QDF_STATUS_E_FAILURE;
13344 	}
13345 
13346 	return status;
13347 }
13348 #endif
13349 
sme_get_rssi_snr_by_bssid(mac_handle_t mac_handle,const uint8_t * bssid,int8_t * rssi,int8_t * snr)13350 QDF_STATUS sme_get_rssi_snr_by_bssid(mac_handle_t mac_handle,
13351 				     const uint8_t *bssid,
13352 				     int8_t *rssi, int8_t *snr)
13353 {
13354 	QDF_STATUS status = QDF_STATUS_SUCCESS;
13355 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
13356 	struct qdf_mac_addr mac_addr;
13357 
13358 	qdf_mem_copy(mac_addr.bytes,
13359 		     bssid, sizeof(struct qdf_mac_addr));
13360 	status = cm_get_rssi_snr_by_bssid(mac_ctx->pdev, &mac_addr, rssi, snr);
13361 
13362 	sme_debug("status %d snr: %d, rssi: %d", status,
13363 		  snr ? *snr : 0, rssi ? *rssi: 0);
13364 
13365 	return status;
13366 }
13367 
sme_clear_sae_single_pmk_info(struct wlan_objmgr_psoc * psoc,uint8_t session_id,struct wlan_crypto_pmksa * pmk_cache_info)13368 void sme_clear_sae_single_pmk_info(struct wlan_objmgr_psoc *psoc,
13369 				   uint8_t session_id,
13370 				   struct wlan_crypto_pmksa *pmk_cache_info)
13371 {
13372 	struct wlan_crypto_pmksa *pmksa;
13373 	struct wlan_objmgr_vdev *vdev;
13374 	struct wlan_crypto_pmksa pmk_to_del;
13375 
13376 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, session_id,
13377 						    WLAN_LEGACY_SME_ID);
13378 	if (!vdev) {
13379 		sme_err("Invalid vdev");
13380 		return;
13381 	}
13382 	pmksa = wlan_crypto_get_pmksa(vdev, &pmk_cache_info->bssid);
13383 	if (!pmksa) {
13384 		wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID);
13385 		return;
13386 	}
13387 	qdf_mem_copy(&pmk_to_del.pmk, pmksa->pmk, pmksa->pmk_len);
13388 	pmk_to_del.pmk_len = pmksa->pmk_len;
13389 	csr_clear_sae_single_pmk(psoc, session_id, &pmk_to_del);
13390 	wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID);
13391 }
13392 
sme_set_del_pmkid_cache(struct wlan_objmgr_psoc * psoc,uint8_t session_id,struct wlan_crypto_pmksa * pmk_cache_info,bool is_add)13393 QDF_STATUS sme_set_del_pmkid_cache(struct wlan_objmgr_psoc *psoc,
13394 				   uint8_t session_id,
13395 				   struct wlan_crypto_pmksa *pmk_cache_info,
13396 				   bool is_add)
13397 {
13398 	struct wmi_unified_pmk_cache *pmk_cache;
13399 	struct scheduler_msg msg;
13400 
13401 	pmk_cache = qdf_mem_malloc(sizeof(*pmk_cache));
13402 	if (!pmk_cache)
13403 		return QDF_STATUS_E_NOMEM;
13404 
13405 	qdf_mem_zero(pmk_cache, sizeof(*pmk_cache));
13406 
13407 	pmk_cache->vdev_id = session_id;
13408 
13409 	if (!pmk_cache_info) {
13410 		pmk_cache->is_flush_all = true;
13411 		csr_clear_sae_single_pmk(psoc, session_id, NULL);
13412 		goto send_flush_cmd;
13413 	}
13414 
13415 	if (!pmk_cache_info->ssid_len) {
13416 		pmk_cache->cat_flag = WMI_PMK_CACHE_CAT_FLAG_BSSID;
13417 		WMI_CHAR_ARRAY_TO_MAC_ADDR(pmk_cache_info->bssid.bytes,
13418 				&pmk_cache->bssid);
13419 	} else {
13420 		pmk_cache->cat_flag = WMI_PMK_CACHE_CAT_FLAG_SSID_CACHE_ID;
13421 		pmk_cache->ssid.length = pmk_cache_info->ssid_len;
13422 		qdf_mem_copy(pmk_cache->ssid.ssid,
13423 			     pmk_cache_info->ssid,
13424 			     pmk_cache->ssid.length);
13425 	}
13426 	pmk_cache->cache_id = (uint32_t) (pmk_cache_info->cache_id[0] << 8 |
13427 					pmk_cache_info->cache_id[1]);
13428 
13429 	if (is_add)
13430 		pmk_cache->action_flag = WMI_PMK_CACHE_ACTION_FLAG_ADD_ENTRY;
13431 	else
13432 		pmk_cache->action_flag = WMI_PMK_CACHE_ACTION_FLAG_DEL_ENTRY;
13433 
13434 	pmk_cache->pmkid_len = PMKID_LEN;
13435 	qdf_mem_copy(pmk_cache->pmkid, pmk_cache_info->pmkid,
13436 		     PMKID_LEN);
13437 
13438 	pmk_cache->pmk_len = pmk_cache_info->pmk_len;
13439 	qdf_mem_copy(pmk_cache->pmk, pmk_cache_info->pmk,
13440 		     pmk_cache->pmk_len);
13441 
13442 send_flush_cmd:
13443 	msg.type = SIR_HAL_SET_DEL_PMKID_CACHE;
13444 	msg.reserved = 0;
13445 	msg.bodyptr = pmk_cache;
13446 	if (QDF_STATUS_SUCCESS !=
13447 	    scheduler_post_message(QDF_MODULE_ID_SME,
13448 				   QDF_MODULE_ID_WMA,
13449 				   QDF_MODULE_ID_WMA, &msg)) {
13450 		sme_err("Not able to post message to WDA");
13451 		if (pmk_cache) {
13452 			qdf_mem_zero(pmk_cache, sizeof(*pmk_cache));
13453 			qdf_mem_free(pmk_cache);
13454 		}
13455 		return QDF_STATUS_E_FAILURE;
13456 	}
13457 
13458 	return QDF_STATUS_SUCCESS;
13459 }
13460 
13461 /* ARP DEBUG STATS */
13462 
13463 /**
13464  * sme_set_nud_debug_stats() - sme api to set nud debug stats
13465  * @mac_handle: Opaque handle to the global MAC context
13466  * @set_stats_param: pointer to set stats param
13467  *
13468  * Return: Return QDF_STATUS.
13469  */
sme_set_nud_debug_stats(mac_handle_t mac_handle,struct set_arp_stats_params * set_stats_param)13470 QDF_STATUS sme_set_nud_debug_stats(mac_handle_t mac_handle,
13471 				   struct set_arp_stats_params
13472 				   *set_stats_param)
13473 {
13474 	struct set_arp_stats_params *arp_set_param;
13475 	struct scheduler_msg msg;
13476 
13477 	arp_set_param = qdf_mem_malloc(sizeof(*arp_set_param));
13478 	if (!arp_set_param)
13479 		return QDF_STATUS_E_NOMEM;
13480 
13481 	qdf_mem_copy(arp_set_param, set_stats_param, sizeof(*arp_set_param));
13482 
13483 	msg.type = WMA_SET_ARP_STATS_REQ;
13484 	msg.reserved = 0;
13485 	msg.bodyptr = arp_set_param;
13486 
13487 	if (QDF_STATUS_SUCCESS !=
13488 	    scheduler_post_message(QDF_MODULE_ID_SME,
13489 				   QDF_MODULE_ID_WMA,
13490 				   QDF_MODULE_ID_WMA, &msg)) {
13491 		sme_err("Not able to post message to WDA");
13492 		qdf_mem_free(arp_set_param);
13493 		return QDF_STATUS_E_FAILURE;
13494 	}
13495 
13496 	return QDF_STATUS_SUCCESS;
13497 }
13498 
13499 /**
13500  * sme_get_nud_debug_stats() - sme api to get nud debug stats
13501  * @mac_handle: Opaque handle to the global MAC context
13502  * @get_stats_param: pointer to set stats param
13503  *
13504  * Return: Return QDF_STATUS.
13505  */
sme_get_nud_debug_stats(mac_handle_t mac_handle,struct get_arp_stats_params * get_stats_param)13506 QDF_STATUS sme_get_nud_debug_stats(mac_handle_t mac_handle,
13507 				   struct get_arp_stats_params
13508 				   *get_stats_param)
13509 {
13510 	struct get_arp_stats_params *arp_get_param;
13511 	struct scheduler_msg msg;
13512 
13513 	arp_get_param = qdf_mem_malloc(sizeof(*arp_get_param));
13514 	if (!arp_get_param)
13515 		return QDF_STATUS_E_NOMEM;
13516 
13517 	qdf_mem_copy(arp_get_param, get_stats_param, sizeof(*arp_get_param));
13518 
13519 	msg.type = WMA_GET_ARP_STATS_REQ;
13520 	msg.reserved = 0;
13521 	msg.bodyptr = arp_get_param;
13522 
13523 	if (QDF_STATUS_SUCCESS !=
13524 	    scheduler_post_message(QDF_MODULE_ID_SME,
13525 				   QDF_MODULE_ID_WMA,
13526 				   QDF_MODULE_ID_WMA, &msg)) {
13527 		sme_err("Not able to post message to WDA");
13528 		qdf_mem_free(arp_get_param);
13529 		return QDF_STATUS_E_FAILURE;
13530 	}
13531 
13532 	return QDF_STATUS_SUCCESS;
13533 }
13534 
sme_set_peer_param(uint8_t * peer_addr,uint32_t param_id,uint32_t param_value,uint32_t vdev_id)13535 QDF_STATUS sme_set_peer_param(uint8_t *peer_addr, uint32_t param_id,
13536 			      uint32_t param_value, uint32_t vdev_id)
13537 {
13538 	void *wma_handle;
13539 
13540 	wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
13541 	if (!wma_handle)
13542 		return QDF_STATUS_E_FAILURE;
13543 
13544 	return wma_set_peer_param(wma_handle, peer_addr, param_id,
13545 				  param_value, vdev_id);
13546 }
13547 
sme_register_set_connection_info_cb(mac_handle_t mac_handle,bool (* set_connection_info_cb)(bool),bool (* get_connection_info_cb)(uint8_t * session_id,enum scan_reject_states * reason))13548 QDF_STATUS sme_register_set_connection_info_cb(mac_handle_t mac_handle,
13549 				bool (*set_connection_info_cb)(bool),
13550 				bool (*get_connection_info_cb)(uint8_t *session_id,
13551 				enum scan_reject_states *reason))
13552 {
13553 	QDF_STATUS status = QDF_STATUS_SUCCESS;
13554 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
13555 
13556 	status = sme_acquire_global_lock(&mac->sme);
13557 	if (QDF_IS_STATUS_SUCCESS(status)) {
13558 		mac->sme.set_connection_info_cb = set_connection_info_cb;
13559 		mac->sme.get_connection_info_cb = get_connection_info_cb;
13560 		sme_release_global_lock(&mac->sme);
13561 	}
13562 	return status;
13563 }
13564 
sme_rso_cmd_status_cb(mac_handle_t mac_handle,rso_cmd_status_cb cb)13565 QDF_STATUS sme_rso_cmd_status_cb(mac_handle_t mac_handle,
13566 				 rso_cmd_status_cb cb)
13567 {
13568 	QDF_STATUS status = QDF_STATUS_SUCCESS;
13569 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
13570 
13571 	mac->sme.rso_cmd_status_cb = cb;
13572 	sme_debug("Registered RSO command status callback");
13573 	return status;
13574 }
13575 
sme_set_dbs_scan_selection_config(mac_handle_t mac_handle,struct wmi_dbs_scan_sel_params * params)13576 QDF_STATUS sme_set_dbs_scan_selection_config(mac_handle_t mac_handle,
13577 		struct wmi_dbs_scan_sel_params *params)
13578 {
13579 	struct scheduler_msg message = {0};
13580 	QDF_STATUS status;
13581 	struct wmi_dbs_scan_sel_params *dbs_scan_params;
13582 	uint32_t i;
13583 
13584 	if (0 == params->num_clients) {
13585 		sme_err("Num of clients is 0");
13586 		return QDF_STATUS_E_FAILURE;
13587 	}
13588 
13589 	dbs_scan_params = qdf_mem_malloc(sizeof(*dbs_scan_params));
13590 	if (!dbs_scan_params)
13591 		return QDF_STATUS_E_NOMEM;
13592 
13593 	dbs_scan_params->num_clients = params->num_clients;
13594 	dbs_scan_params->pdev_id = params->pdev_id;
13595 	for (i = 0; i < params->num_clients; i++) {
13596 		dbs_scan_params->module_id[i] = params->module_id[i];
13597 		dbs_scan_params->num_dbs_scans[i] = params->num_dbs_scans[i];
13598 		dbs_scan_params->num_non_dbs_scans[i] =
13599 			params->num_non_dbs_scans[i];
13600 	}
13601 	message.type = WMA_SET_DBS_SCAN_SEL_CONF_PARAMS;
13602 	message.bodyptr = dbs_scan_params;
13603 	status = scheduler_post_message(QDF_MODULE_ID_SME,
13604 					QDF_MODULE_ID_WMA,
13605 					QDF_MODULE_ID_WMA, &message);
13606 	if (!QDF_IS_STATUS_SUCCESS(status)) {
13607 		sme_err("Not able to post msg to WMA!");
13608 		qdf_mem_free(dbs_scan_params);
13609 	}
13610 
13611 	return status;
13612 }
13613 
sme_get_rcpi(mac_handle_t mac_handle,struct sme_rcpi_req * rcpi)13614 QDF_STATUS sme_get_rcpi(mac_handle_t mac_handle, struct sme_rcpi_req *rcpi)
13615 {
13616 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
13617 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
13618 	struct scheduler_msg msg = {0};
13619 	struct sme_rcpi_req *rcpi_req;
13620 
13621 	rcpi_req = qdf_mem_malloc(sizeof(*rcpi_req));
13622 	if (!rcpi_req)
13623 		return QDF_STATUS_E_NOMEM;
13624 
13625 	qdf_mem_copy(rcpi_req, rcpi, sizeof(*rcpi_req));
13626 
13627 	status = sme_acquire_global_lock(&mac->sme);
13628 	if (QDF_IS_STATUS_SUCCESS(status)) {
13629 		msg.bodyptr = rcpi_req;
13630 		msg.type = WMA_GET_RCPI_REQ;
13631 		status = scheduler_post_message(QDF_MODULE_ID_SME,
13632 						QDF_MODULE_ID_WMA,
13633 						QDF_MODULE_ID_WMA, &msg);
13634 		sme_release_global_lock(&mac->sme);
13635 		if (!QDF_IS_STATUS_SUCCESS(status)) {
13636 			sme_err("post get rcpi req failed");
13637 			status = QDF_STATUS_E_FAILURE;
13638 			qdf_mem_free(rcpi_req);
13639 		}
13640 	} else {
13641 		qdf_mem_free(rcpi_req);
13642 	}
13643 
13644 	return status;
13645 }
13646 
sme_store_pdev(mac_handle_t mac_handle,struct wlan_objmgr_pdev * pdev)13647 void sme_store_pdev(mac_handle_t mac_handle, struct wlan_objmgr_pdev *pdev)
13648 {
13649 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
13650 	void *wma_handle;
13651 	QDF_STATUS status;
13652 
13653 	status = wlan_objmgr_pdev_try_get_ref(pdev, WLAN_LEGACY_MAC_ID);
13654 	if (QDF_STATUS_SUCCESS != status) {
13655 		mac_ctx->pdev = NULL;
13656 		return;
13657 	}
13658 	mac_ctx->pdev = pdev;
13659 	wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
13660 	if (!wma_handle)
13661 		return;
13662 
13663 	wma_store_pdev(wma_handle, pdev);
13664 	pdev->pdev_nif.pdev_fw_caps |= SUPPORTED_CRYPTO_CAPS;
13665 }
13666 
sme_register_tx_queue_cb(mac_handle_t mac_handle,tx_queue_cb tx_queue_cb)13667 QDF_STATUS sme_register_tx_queue_cb(mac_handle_t mac_handle,
13668 				    tx_queue_cb tx_queue_cb)
13669 {
13670 	QDF_STATUS status;
13671 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
13672 
13673 	status = sme_acquire_global_lock(&mac->sme);
13674 	if (QDF_IS_STATUS_SUCCESS(status)) {
13675 		mac->sme.tx_queue_cb = tx_queue_cb;
13676 		sme_release_global_lock(&mac->sme);
13677 		sme_debug("Tx queue callback set");
13678 	}
13679 
13680 	return status;
13681 }
13682 
sme_deregister_tx_queue_cb(mac_handle_t mac_handle)13683 QDF_STATUS sme_deregister_tx_queue_cb(mac_handle_t mac_handle)
13684 {
13685 	return sme_register_tx_queue_cb(mac_handle, NULL);
13686 }
13687 
13688 #ifdef WLAN_SUPPORT_TWT
13689 
sme_test_config_twt_setup(struct wmi_twt_add_dialog_param * params)13690 QDF_STATUS sme_test_config_twt_setup(struct wmi_twt_add_dialog_param *params)
13691 {
13692 	t_wma_handle *wma_handle;
13693 
13694 	wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
13695 	if (!wma_handle)
13696 		return QDF_STATUS_E_FAILURE;
13697 
13698 	return wma_twt_process_add_dialog(wma_handle, params);
13699 }
13700 
13701 QDF_STATUS
sme_test_config_twt_terminate(struct wmi_twt_del_dialog_param * params)13702 sme_test_config_twt_terminate(struct wmi_twt_del_dialog_param *params)
13703 {
13704 	t_wma_handle *wma_handle;
13705 
13706 	wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
13707 	if (!wma_handle)
13708 		return QDF_STATUS_E_FAILURE;
13709 
13710 	return wma_twt_process_del_dialog(wma_handle, params);
13711 }
13712 
sme_clear_twt_complete_cb(mac_handle_t mac_handle)13713 QDF_STATUS sme_clear_twt_complete_cb(mac_handle_t mac_handle)
13714 {
13715 	QDF_STATUS status;
13716 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
13717 
13718 	status = sme_acquire_global_lock(&mac->sme);
13719 	if (QDF_IS_STATUS_SUCCESS(status)) {
13720 		mac->sme.twt_add_dialog_cb = NULL;
13721 		mac->sme.twt_del_dialog_cb = NULL;
13722 		mac->sme.twt_pause_dialog_cb = NULL;
13723 		mac->sme.twt_resume_dialog_cb = NULL;
13724 		mac->sme.twt_notify_cb = NULL;
13725 		mac->sme.twt_nudge_dialog_cb = NULL;
13726 		mac->sme.twt_ack_comp_cb = NULL;
13727 		sme_release_global_lock(&mac->sme);
13728 
13729 		sme_debug("TWT: callbacks Initialized");
13730 	}
13731 
13732 	return status;
13733 }
13734 
sme_register_twt_callbacks(mac_handle_t mac_handle,struct twt_callbacks * twt_cb)13735 QDF_STATUS sme_register_twt_callbacks(mac_handle_t mac_handle,
13736 				      struct twt_callbacks *twt_cb)
13737 {
13738 	QDF_STATUS status;
13739 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
13740 
13741 	status = sme_acquire_global_lock(&mac->sme);
13742 	if (QDF_IS_STATUS_SUCCESS(status)) {
13743 		mac->sme.twt_enable_cb = twt_cb->twt_enable_cb;
13744 		mac->sme.twt_add_dialog_cb = twt_cb->twt_add_dialog_cb;
13745 		mac->sme.twt_del_dialog_cb = twt_cb->twt_del_dialog_cb;
13746 		mac->sme.twt_pause_dialog_cb = twt_cb->twt_pause_dialog_cb;
13747 		mac->sme.twt_resume_dialog_cb = twt_cb->twt_resume_dialog_cb;
13748 		mac->sme.twt_disable_cb = twt_cb->twt_disable_cb;
13749 		mac->sme.twt_notify_cb = twt_cb->twt_notify_cb;
13750 		mac->sme.twt_nudge_dialog_cb = twt_cb->twt_nudge_dialog_cb;
13751 		mac->sme.twt_ack_comp_cb = twt_cb->twt_ack_comp_cb;
13752 		sme_release_global_lock(&mac->sme);
13753 		sme_debug("TWT: callbacks registered");
13754 	}
13755 
13756 	return status;
13757 }
13758 
sme_add_dialog_cmd(mac_handle_t mac_handle,twt_add_dialog_cb twt_add_dialog_cb,struct wmi_twt_add_dialog_param * twt_params,void * context)13759 QDF_STATUS sme_add_dialog_cmd(mac_handle_t mac_handle,
13760 			      twt_add_dialog_cb twt_add_dialog_cb,
13761 			      struct wmi_twt_add_dialog_param *twt_params,
13762 			      void *context)
13763 {
13764 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
13765 	struct scheduler_msg twt_msg = {0};
13766 	bool is_twt_cmd_in_progress, is_twt_notify_in_progress;
13767 	bool usr_cfg_ps_enable;
13768 	QDF_STATUS status;
13769 	void *wma_handle;
13770 	struct wmi_twt_add_dialog_param *cmd_params;
13771 	enum wlan_twt_commands active_cmd = WLAN_TWT_NONE;
13772 
13773 	SME_ENTER();
13774 
13775 	usr_cfg_ps_enable = mlme_get_user_ps(mac->psoc, twt_params->vdev_id);
13776 	if (!usr_cfg_ps_enable) {
13777 		sme_debug("Power save mode disable");
13778 		return QDF_STATUS_E_AGAIN;
13779 	}
13780 
13781 	is_twt_notify_in_progress = mlme_is_twt_notify_in_progress(
13782 			mac->psoc, twt_params->vdev_id);
13783 
13784 	if (is_twt_notify_in_progress) {
13785 		sme_debug("Waiting for TWT Notify");
13786 		return QDF_STATUS_E_BUSY;
13787 	}
13788 
13789 	is_twt_cmd_in_progress = mlme_twt_is_command_in_progress(
13790 			mac->psoc,
13791 			(struct qdf_mac_addr *)twt_params->peer_macaddr,
13792 			twt_params->dialog_id, WLAN_TWT_ANY, &active_cmd);
13793 	if (is_twt_cmd_in_progress) {
13794 		sme_debug("Already TWT command:%d is in progress", active_cmd);
13795 		return QDF_STATUS_E_PENDING;
13796 	}
13797 
13798 	wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
13799 	if (!wma_handle)
13800 		return QDF_STATUS_E_FAILURE;
13801 
13802 	/*bodyptr should be freeable*/
13803 	cmd_params = qdf_mem_malloc(sizeof(*cmd_params));
13804 	if (!cmd_params)
13805 		return QDF_STATUS_E_NOMEM;
13806 
13807 	qdf_mem_copy(cmd_params, twt_params, sizeof(*cmd_params));
13808 
13809 	status = sme_acquire_global_lock(&mac->sme);
13810 	if (QDF_IS_STATUS_ERROR(status)) {
13811 		sme_err("failed to register add dialog callback");
13812 		qdf_mem_free(cmd_params);
13813 		return status;
13814 	}
13815 
13816 	/*
13817 	 * Add the dialog id to TWT context to drop back to back
13818 	 * commands
13819 	 */
13820 	mlme_add_twt_session(mac->psoc,
13821 			     (struct qdf_mac_addr *)twt_params->peer_macaddr,
13822 			     twt_params->dialog_id);
13823 
13824 	mlme_set_twt_command_in_progress(mac->psoc,
13825 				(struct qdf_mac_addr *)twt_params->peer_macaddr,
13826 				twt_params->dialog_id, WLAN_TWT_SETUP);
13827 
13828 	/* Serialize the req through MC thread */
13829 	mac->sme.twt_add_dialog_cb = twt_add_dialog_cb;
13830 	mac->sme.twt_ack_context_cb = context;
13831 	twt_msg.bodyptr = cmd_params;
13832 	twt_msg.type = WMA_TWT_ADD_DIALOG_REQUEST;
13833 	sme_release_global_lock(&mac->sme);
13834 
13835 	status = scheduler_post_message(QDF_MODULE_ID_SME,
13836 					QDF_MODULE_ID_WMA,
13837 					QDF_MODULE_ID_WMA, &twt_msg);
13838 
13839 	if (QDF_IS_STATUS_ERROR(status)) {
13840 		sme_err("Post twt add dialog msg fail");
13841 		mlme_set_twt_command_in_progress(mac->psoc,
13842 				(struct qdf_mac_addr *)twt_params->peer_macaddr,
13843 				twt_params->dialog_id, WLAN_TWT_NONE);
13844 		mlme_init_twt_context(mac->psoc,
13845 				(struct qdf_mac_addr *)twt_params->peer_macaddr,
13846 				twt_params->dialog_id);
13847 		qdf_mem_free(cmd_params);
13848 	}
13849 
13850 	SME_EXIT();
13851 	return status;
13852 }
13853 
sme_del_dialog_cmd(mac_handle_t mac_handle,twt_del_dialog_cb del_dialog_cb,struct wmi_twt_del_dialog_param * twt_params,void * context)13854 QDF_STATUS sme_del_dialog_cmd(mac_handle_t mac_handle,
13855 			      twt_del_dialog_cb del_dialog_cb,
13856 			      struct wmi_twt_del_dialog_param *twt_params,
13857 			      void *context)
13858 {
13859 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
13860 	struct scheduler_msg twt_msg = {0};
13861 	bool is_twt_cmd_in_progress;
13862 	QDF_STATUS status;
13863 	void *wma_handle;
13864 	struct wmi_twt_del_dialog_param *cmd_params;
13865 	enum wlan_twt_commands active_cmd = WLAN_TWT_NONE;
13866 
13867 	SME_ENTER();
13868 
13869 	is_twt_cmd_in_progress =
13870 		mlme_twt_is_command_in_progress(
13871 			mac->psoc,
13872 			(struct qdf_mac_addr *)twt_params->peer_macaddr,
13873 			twt_params->dialog_id, WLAN_TWT_SETUP, &active_cmd) ||
13874 		mlme_twt_is_command_in_progress(
13875 			mac->psoc,
13876 			(struct qdf_mac_addr *)twt_params->peer_macaddr,
13877 			twt_params->dialog_id, WLAN_TWT_TERMINATE,
13878 			&active_cmd);
13879 	if (is_twt_cmd_in_progress) {
13880 		sme_debug("Already TWT command:%d is in progress", active_cmd);
13881 		return QDF_STATUS_E_PENDING;
13882 	}
13883 
13884 	wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
13885 	if (!wma_handle)
13886 		return QDF_STATUS_E_FAILURE;
13887 
13888 	/*bodyptr should be freeable*/
13889 	cmd_params = qdf_mem_malloc(sizeof(*cmd_params));
13890 	if (!cmd_params)
13891 		return QDF_STATUS_E_NOMEM;
13892 
13893 	qdf_mem_copy(cmd_params, twt_params, sizeof(*cmd_params));
13894 
13895 	status = sme_acquire_global_lock(&mac->sme);
13896 	if (QDF_IS_STATUS_ERROR(status)) {
13897 		sme_err("Failed to acquire SME global lock");
13898 		qdf_mem_free(cmd_params);
13899 		return status;
13900 	}
13901 
13902 	mlme_set_twt_command_in_progress(mac->psoc,
13903 				(struct qdf_mac_addr *)twt_params->peer_macaddr,
13904 				twt_params->dialog_id, WLAN_TWT_TERMINATE);
13905 
13906 	/* Serialize the req through MC thread */
13907 	mac->sme.twt_del_dialog_cb = del_dialog_cb;
13908 	mac->sme.twt_ack_context_cb = context;
13909 	twt_msg.bodyptr = cmd_params;
13910 	twt_msg.type = WMA_TWT_DEL_DIALOG_REQUEST;
13911 	sme_release_global_lock(&mac->sme);
13912 
13913 	status = scheduler_post_message(QDF_MODULE_ID_SME,
13914 					QDF_MODULE_ID_WMA,
13915 					QDF_MODULE_ID_WMA, &twt_msg);
13916 
13917 	if (QDF_IS_STATUS_ERROR(status)) {
13918 		sme_err("Post twt del dialog msg fail");
13919 		mlme_set_twt_command_in_progress(
13920 				mac->psoc,
13921 				(struct qdf_mac_addr *)twt_params->peer_macaddr,
13922 				twt_params->dialog_id, WLAN_TWT_NONE);
13923 		qdf_mem_free(cmd_params);
13924 	}
13925 
13926 	SME_EXIT();
13927 	return status;
13928 }
13929 
sme_sap_del_dialog_cmd(mac_handle_t mac_handle,twt_del_dialog_cb del_dialog_cb,struct wmi_twt_del_dialog_param * twt_params)13930 QDF_STATUS sme_sap_del_dialog_cmd(mac_handle_t mac_handle,
13931 				  twt_del_dialog_cb del_dialog_cb,
13932 				  struct wmi_twt_del_dialog_param *twt_params)
13933 {
13934 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
13935 	struct scheduler_msg twt_msg = {0};
13936 	bool is_twt_cmd_in_progress;
13937 	QDF_STATUS status;
13938 	void *wma_handle;
13939 	struct wmi_twt_del_dialog_param *cmd_params;
13940 
13941 	SME_ENTER();
13942 
13943 	is_twt_cmd_in_progress =
13944 		sme_sap_twt_is_command_in_progress(mac->psoc,
13945 			twt_params->vdev_id,
13946 			(struct qdf_mac_addr *)twt_params->peer_macaddr,
13947 			twt_params->dialog_id, WLAN_TWT_TERMINATE);
13948 
13949 	if (is_twt_cmd_in_progress) {
13950 		sme_debug("Already TWT teardown command is in progress");
13951 		return QDF_STATUS_E_PENDING;
13952 	}
13953 
13954 	wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
13955 	if (!wma_handle)
13956 		return QDF_STATUS_E_FAILURE;
13957 
13958 	/* bodyptr should be freeable */
13959 	cmd_params = qdf_mem_malloc(sizeof(*cmd_params));
13960 	if (!cmd_params)
13961 		return QDF_STATUS_E_NOMEM;
13962 
13963 	qdf_mem_copy(cmd_params, twt_params, sizeof(*cmd_params));
13964 
13965 	status = sme_acquire_global_lock(&mac->sme);
13966 	if (QDF_IS_STATUS_ERROR(status)) {
13967 		qdf_mem_free(cmd_params);
13968 		sme_err("Failed to acquire SME global lock");
13969 		return status;
13970 	}
13971 
13972 	/*
13973 	 * Add the dialog id to TWT context to drop back to back
13974 	 * commands
13975 	 */
13976 	sme_sap_add_twt_session(mac->psoc, twt_params->vdev_id,
13977 			       (struct qdf_mac_addr *)twt_params->peer_macaddr,
13978 			       twt_params->dialog_id);
13979 
13980 	sme_sap_set_twt_command_in_progress(mac->psoc, twt_params->vdev_id,
13981 				(struct qdf_mac_addr *)twt_params->peer_macaddr,
13982 				twt_params->dialog_id, WLAN_TWT_TERMINATE);
13983 
13984 	/* Serialize the req through MC thread */
13985 	mac->sme.twt_del_dialog_cb = del_dialog_cb;
13986 	twt_msg.bodyptr = cmd_params;
13987 	twt_msg.type = WMA_TWT_DEL_DIALOG_REQUEST;
13988 	sme_release_global_lock(&mac->sme);
13989 
13990 	status = scheduler_post_message(QDF_MODULE_ID_SME,
13991 					QDF_MODULE_ID_WMA,
13992 					QDF_MODULE_ID_WMA, &twt_msg);
13993 
13994 	if (QDF_IS_STATUS_ERROR(status)) {
13995 		sme_err("Post twt del dialog msg fail");
13996 		sme_sap_set_twt_command_in_progress(mac->psoc,
13997 				twt_params->vdev_id,
13998 				(struct qdf_mac_addr *)twt_params->peer_macaddr,
13999 				twt_params->dialog_id, WLAN_TWT_NONE);
14000 		sme_sap_init_twt_context(mac->psoc,
14001 				twt_params->vdev_id,
14002 				(struct qdf_mac_addr *)twt_params->peer_macaddr,
14003 				twt_params->dialog_id);
14004 		qdf_mem_free(cmd_params);
14005 	}
14006 
14007 	SME_EXIT();
14008 	return status;
14009 }
14010 
14011 QDF_STATUS
sme_pause_dialog_cmd(mac_handle_t mac_handle,struct wmi_twt_pause_dialog_cmd_param * twt_params,void * context)14012 sme_pause_dialog_cmd(mac_handle_t mac_handle,
14013 		     struct wmi_twt_pause_dialog_cmd_param *twt_params,
14014 		     void *context)
14015 {
14016 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
14017 	struct wmi_twt_pause_dialog_cmd_param *cmd_params;
14018 	struct scheduler_msg twt_msg = {0};
14019 	bool is_twt_cmd_in_progress;
14020 	QDF_STATUS status;
14021 	void *wma_handle;
14022 	enum wlan_twt_commands active_cmd = WLAN_TWT_NONE;
14023 
14024 	SME_ENTER();
14025 
14026 	is_twt_cmd_in_progress = mlme_twt_is_command_in_progress(
14027 			mac->psoc,
14028 			(struct qdf_mac_addr *)twt_params->peer_macaddr,
14029 			twt_params->dialog_id, WLAN_TWT_ANY, &active_cmd);
14030 	if (is_twt_cmd_in_progress) {
14031 		sme_debug("Already TWT command:%d is in progress", active_cmd);
14032 		return QDF_STATUS_E_PENDING;
14033 	}
14034 
14035 	wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
14036 	if (!wma_handle)
14037 		return QDF_STATUS_E_FAILURE;
14038 
14039 	/*bodyptr should be freeable*/
14040 	cmd_params = qdf_mem_malloc(sizeof(*cmd_params));
14041 	if (!cmd_params)
14042 		return QDF_STATUS_E_NOMEM;
14043 
14044 	qdf_mem_copy(cmd_params, twt_params, sizeof(*cmd_params));
14045 
14046 	status = sme_acquire_global_lock(&mac->sme);
14047 	if (QDF_IS_STATUS_ERROR(status)) {
14048 		sme_err("failed to register pause dialog callback");
14049 		qdf_mem_free(cmd_params);
14050 		return status;
14051 	}
14052 
14053 	mlme_set_twt_command_in_progress(mac->psoc,
14054 				(struct qdf_mac_addr *)twt_params->peer_macaddr,
14055 				twt_params->dialog_id, WLAN_TWT_SUSPEND);
14056 
14057 	/* Serialize the req through MC thread */
14058 	mac->sme.twt_ack_context_cb = context;
14059 	twt_msg.bodyptr = cmd_params;
14060 	twt_msg.type = WMA_TWT_PAUSE_DIALOG_REQUEST;
14061 	sme_release_global_lock(&mac->sme);
14062 
14063 	status = scheduler_post_message(QDF_MODULE_ID_SME,
14064 					QDF_MODULE_ID_WMA,
14065 					QDF_MODULE_ID_WMA, &twt_msg);
14066 
14067 	if (QDF_IS_STATUS_ERROR(status)) {
14068 		sme_err("Post twt pause dialog msg fail");
14069 		mlme_set_twt_command_in_progress(
14070 				mac->psoc,
14071 				(struct qdf_mac_addr *)twt_params->peer_macaddr,
14072 				twt_params->dialog_id, WLAN_TWT_NONE);
14073 		qdf_mem_free(cmd_params);
14074 	}
14075 
14076 	SME_EXIT();
14077 	return status;
14078 }
14079 
14080 QDF_STATUS
sme_nudge_dialog_cmd(mac_handle_t mac_handle,struct wmi_twt_nudge_dialog_cmd_param * twt_params,void * context)14081 sme_nudge_dialog_cmd(mac_handle_t mac_handle,
14082 		     struct wmi_twt_nudge_dialog_cmd_param *twt_params,
14083 		     void *context)
14084 {
14085 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
14086 	struct wmi_twt_nudge_dialog_cmd_param *cmd_params;
14087 	struct scheduler_msg twt_msg = {0};
14088 	bool is_twt_cmd_in_progress;
14089 	QDF_STATUS status;
14090 	void *wma_handle;
14091 	enum wlan_twt_commands active_cmd = WLAN_TWT_NONE;
14092 
14093 	SME_ENTER();
14094 
14095 	is_twt_cmd_in_progress = mlme_twt_is_command_in_progress(
14096 			mac->psoc,
14097 			(struct qdf_mac_addr *)twt_params->peer_macaddr,
14098 			twt_params->dialog_id, WLAN_TWT_ANY, &active_cmd);
14099 	if (is_twt_cmd_in_progress) {
14100 		sme_debug("Already TWT command:%d is in progress", active_cmd);
14101 		return QDF_STATUS_E_PENDING;
14102 	}
14103 
14104 	wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
14105 	if (!wma_handle) {
14106 		sme_err("wma_handle is NULL");
14107 		return QDF_STATUS_E_FAILURE;
14108 	}
14109 
14110 	/*bodyptr should be freeable*/
14111 	cmd_params = qdf_mem_malloc(sizeof(*cmd_params));
14112 	if (!cmd_params)
14113 		return QDF_STATUS_E_NOMEM;
14114 
14115 	qdf_mem_copy(cmd_params, twt_params, sizeof(*cmd_params));
14116 
14117 	status = sme_acquire_global_lock(&mac->sme);
14118 	if (QDF_IS_STATUS_ERROR(status)) {
14119 		sme_err("failed to register nudge dialog callback");
14120 		qdf_mem_free(cmd_params);
14121 		return status;
14122 	}
14123 
14124 	mlme_set_twt_command_in_progress(mac->psoc,
14125 				(struct qdf_mac_addr *)twt_params->peer_macaddr,
14126 				twt_params->dialog_id, WLAN_TWT_NUDGE);
14127 
14128 	/* Serialize the req through MC thread */
14129 	mac->sme.twt_ack_context_cb = context;
14130 	twt_msg.bodyptr = cmd_params;
14131 	twt_msg.type = WMA_TWT_NUDGE_DIALOG_REQUEST;
14132 	sme_release_global_lock(&mac->sme);
14133 
14134 	status = scheduler_post_message(QDF_MODULE_ID_SME,
14135 					QDF_MODULE_ID_WMA,
14136 					QDF_MODULE_ID_WMA, &twt_msg);
14137 
14138 	if (QDF_IS_STATUS_ERROR(status)) {
14139 		sme_err("Post twt nudge dialog msg fail");
14140 		mlme_set_twt_command_in_progress(
14141 			mac->psoc,
14142 			(struct qdf_mac_addr *)twt_params->peer_macaddr,
14143 			twt_params->dialog_id, WLAN_TWT_NONE);
14144 		qdf_mem_free(cmd_params);
14145 	}
14146 
14147 	SME_EXIT();
14148 	return status;
14149 }
14150 
14151 QDF_STATUS
sme_resume_dialog_cmd(mac_handle_t mac_handle,struct wmi_twt_resume_dialog_cmd_param * twt_params,void * context)14152 sme_resume_dialog_cmd(mac_handle_t mac_handle,
14153 		      struct wmi_twt_resume_dialog_cmd_param *twt_params,
14154 		      void *context)
14155 {
14156 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
14157 	struct wmi_twt_resume_dialog_cmd_param *cmd_params;
14158 	struct scheduler_msg twt_msg = {0};
14159 	bool is_twt_cmd_in_progress;
14160 	QDF_STATUS status;
14161 	void *wma_handle;
14162 	enum wlan_twt_commands active_cmd = WLAN_TWT_NONE;
14163 
14164 	SME_ENTER();
14165 
14166 	is_twt_cmd_in_progress = mlme_twt_is_command_in_progress(
14167 			mac->psoc,
14168 			(struct qdf_mac_addr *)twt_params->peer_macaddr,
14169 			twt_params->dialog_id, WLAN_TWT_ANY, &active_cmd);
14170 	if (is_twt_cmd_in_progress) {
14171 		sme_debug("Already TWT command:%d is in progress", active_cmd);
14172 		return QDF_STATUS_E_PENDING;
14173 	}
14174 
14175 	wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
14176 	if (!wma_handle)
14177 		return QDF_STATUS_E_FAILURE;
14178 
14179 	/*bodyptr should be freeable*/
14180 	cmd_params = qdf_mem_malloc(sizeof(*cmd_params));
14181 	if (!cmd_params)
14182 		return QDF_STATUS_E_NOMEM;
14183 
14184 	qdf_mem_copy(cmd_params, twt_params, sizeof(*cmd_params));
14185 
14186 	status = sme_acquire_global_lock(&mac->sme);
14187 	if (QDF_IS_STATUS_ERROR(status)) {
14188 		sme_err("failed to register resume dialog callback");
14189 		qdf_mem_free(cmd_params);
14190 		return status;
14191 	}
14192 
14193 	mlme_set_twt_command_in_progress(mac->psoc,
14194 				(struct qdf_mac_addr *)twt_params->peer_macaddr,
14195 				twt_params->dialog_id, WLAN_TWT_RESUME);
14196 
14197 	/* Serialize the req through MC thread */
14198 	mac->sme.twt_ack_context_cb = context;
14199 	twt_msg.bodyptr = cmd_params;
14200 	twt_msg.type = WMA_TWT_RESUME_DIALOG_REQUEST;
14201 	sme_release_global_lock(&mac->sme);
14202 
14203 	status = scheduler_post_message(QDF_MODULE_ID_SME,
14204 					QDF_MODULE_ID_WMA,
14205 					QDF_MODULE_ID_WMA, &twt_msg);
14206 	if (QDF_IS_STATUS_ERROR(status)) {
14207 		sme_err("Post twt resume dialog msg fail");
14208 		mlme_set_twt_command_in_progress(
14209 				mac->psoc,
14210 				(struct qdf_mac_addr *)twt_params->peer_macaddr,
14211 				twt_params->dialog_id, WLAN_TWT_NONE);
14212 		qdf_mem_free(cmd_params);
14213 	}
14214 
14215 	SME_EXIT();
14216 	return status;
14217 }
14218 #endif
14219 
sme_set_smps_cfg(uint32_t vdev_id,uint32_t param_id,uint32_t param_val)14220 QDF_STATUS sme_set_smps_cfg(uint32_t vdev_id, uint32_t param_id,
14221 						uint32_t param_val)
14222 {
14223 	return wma_configure_smps_params(vdev_id, param_id, param_val);
14224 }
14225 
sme_set_reorder_timeout(mac_handle_t mac_handle,struct sir_set_rx_reorder_timeout_val * req)14226 QDF_STATUS sme_set_reorder_timeout(mac_handle_t mac_handle,
14227 				   struct sir_set_rx_reorder_timeout_val *req)
14228 {
14229 	QDF_STATUS status;
14230 	tp_wma_handle wma_handle;
14231 
14232 	wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
14233 	status = wma_set_rx_reorder_timeout_val(wma_handle, req);
14234 
14235 	return status;
14236 }
14237 
sme_set_rx_set_blocksize(mac_handle_t mac_handle,struct sir_peer_set_rx_blocksize * req)14238 QDF_STATUS sme_set_rx_set_blocksize(mac_handle_t mac_handle,
14239 				    struct sir_peer_set_rx_blocksize *req)
14240 {
14241 	QDF_STATUS status;
14242 	tp_wma_handle wma_handle;
14243 
14244 	wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
14245 	status = wma_set_rx_blocksize(wma_handle, req);
14246 
14247 	return status;
14248 }
14249 
sme_cli_set_command(int vdev_id,int param_id,int sval,int vpdev)14250 int sme_cli_set_command(int vdev_id, int param_id, int sval, int vpdev)
14251 {
14252 	return wma_cli_set_command(vdev_id, param_id, sval, vpdev);
14253 }
14254 
sme_set_enable_mem_deep_sleep(mac_handle_t mac_handle,int vdev_id)14255 int sme_set_enable_mem_deep_sleep(mac_handle_t mac_handle, int vdev_id)
14256 {
14257 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
14258 
14259 	return wma_cli_set_command(vdev_id, wmi_pdev_param_hyst_en,
14260 				   mac_ctx->mlme_cfg->gen.memory_deep_sleep,
14261 				   PDEV_CMD);
14262 }
14263 
sme_set_cck_tx_fir_override(mac_handle_t mac_handle,int vdev_id)14264 int sme_set_cck_tx_fir_override(mac_handle_t mac_handle, int vdev_id)
14265 {
14266 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
14267 
14268 	return wma_cli_set_command(vdev_id,
14269 				   wmi_pdev_param_enable_cck_txfir_override,
14270 				   mac_ctx->mlme_cfg->gen.cck_tx_fir_override,
14271 				   PDEV_CMD);
14272 }
14273 
sme_set_bt_activity_info_cb(mac_handle_t mac_handle,bt_activity_info_cb cb)14274 QDF_STATUS sme_set_bt_activity_info_cb(mac_handle_t mac_handle,
14275 				       bt_activity_info_cb cb)
14276 {
14277 	QDF_STATUS status;
14278 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
14279 
14280 	status = sme_acquire_global_lock(&mac->sme);
14281 	if (QDF_IS_STATUS_SUCCESS(status)) {
14282 		mac->sme.bt_activity_info_cb = cb;
14283 		sme_release_global_lock(&mac->sme);
14284 		sme_debug("bt activity info callback set");
14285 	}
14286 
14287 	return status;
14288 }
14289 
sme_get_chain_rssi(mac_handle_t mac_handle,struct get_chain_rssi_req_params * input,get_chain_rssi_callback callback,void * context)14290 QDF_STATUS sme_get_chain_rssi(mac_handle_t mac_handle,
14291 			      struct get_chain_rssi_req_params *input,
14292 			      get_chain_rssi_callback callback,
14293 			      void *context)
14294 {
14295 	QDF_STATUS status = QDF_STATUS_SUCCESS;
14296 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
14297 	tp_wma_handle wma_handle;
14298 
14299 	SME_ENTER();
14300 
14301 	if (!input) {
14302 		sme_err("Invalid req params");
14303 		return QDF_STATUS_E_INVAL;
14304 	}
14305 
14306 	mac_ctx->sme.get_chain_rssi_cb = callback;
14307 	mac_ctx->sme.get_chain_rssi_context = context;
14308 	wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
14309 	wma_get_chain_rssi(wma_handle, input);
14310 
14311 	SME_EXIT();
14312 	return status;
14313 }
14314 
sme_process_msg_callback(struct mac_context * mac,struct scheduler_msg * msg)14315 QDF_STATUS sme_process_msg_callback(struct mac_context *mac,
14316 				    struct scheduler_msg *msg)
14317 {
14318 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
14319 
14320 	if (!msg) {
14321 		sme_err("Empty message for SME Msg callback");
14322 		return status;
14323 	}
14324 	status = sme_process_msg(mac, msg);
14325 	return status;
14326 }
14327 
sme_display_disconnect_stats(mac_handle_t mac_handle,uint8_t session_id)14328 void sme_display_disconnect_stats(mac_handle_t mac_handle, uint8_t session_id)
14329 {
14330 	struct csr_roam_session *session;
14331 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
14332 
14333 	if (!CSR_IS_SESSION_VALID(mac_ctx, session_id)) {
14334 		sme_err("%s Invalid session id: %d", __func__, session_id);
14335 		return;
14336 	}
14337 
14338 	session = CSR_GET_SESSION(mac_ctx, session_id);
14339 	if (!session) {
14340 		sme_err("%s Failed to get session for id: %d",
14341 			__func__, session_id);
14342 		return;
14343 	}
14344 
14345 	sme_nofl_info("Total No. of Disconnections: %d",
14346 		      session->disconnect_stats.disconnection_cnt);
14347 
14348 	sme_nofl_info("No. of Disconnects Triggered by Application: %d",
14349 		      session->disconnect_stats.disconnection_by_app);
14350 
14351 	sme_nofl_info("No. of Disassoc Sent by Peer: %d",
14352 		      session->disconnect_stats.disassoc_by_peer);
14353 
14354 	sme_nofl_info("No. of Deauth Sent by Peer: %d",
14355 		      session->disconnect_stats.deauth_by_peer);
14356 
14357 	sme_nofl_info("No. of Disconnections due to Beacon Miss: %d",
14358 		      session->disconnect_stats.bmiss);
14359 
14360 	sme_nofl_info("No. of Disconnections due to Peer Kickout: %d",
14361 		      session->disconnect_stats.peer_kickout);
14362 }
14363 
14364 #ifdef FEATURE_WLAN_DYNAMIC_CVM
14365  /**
14366  * sme_set_vc_mode_config() - Set voltage corner config to FW
14367  * @bitmap:	Bitmap that refers to voltage corner config with
14368  * different phymode and bw configuration
14369  *
14370  * Return: QDF_STATUS
14371  */
sme_set_vc_mode_config(uint32_t vc_bitmap)14372 QDF_STATUS sme_set_vc_mode_config(uint32_t vc_bitmap)
14373 {
14374 	void *wma_handle;
14375 
14376 	wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
14377 	if (!wma_handle)
14378 		return QDF_STATUS_E_FAILURE;
14379 
14380 	if (QDF_STATUS_SUCCESS !=
14381 		wma_set_vc_mode_config(wma_handle, vc_bitmap)) {
14382 		sme_err("Failed to set Voltage Control config to FW");
14383 		return QDF_STATUS_E_FAILURE;
14384 	}
14385 	return QDF_STATUS_SUCCESS;
14386 }
14387 #endif
14388 
14389 /**
14390  * sme_set_bmiss_bcnt() - set bmiss config parameters
14391  * @vdev_id: virtual device for the command
14392  * @first_cnt: bmiss first value
14393  * @final_cnt: bmiss final value
14394  *
14395  * Return: QDF_STATUS_SUCCESS or non-zero on failure
14396  */
sme_set_bmiss_bcnt(uint32_t vdev_id,uint32_t first_cnt,uint32_t final_cnt)14397 QDF_STATUS sme_set_bmiss_bcnt(uint32_t vdev_id, uint32_t first_cnt,
14398 		uint32_t final_cnt)
14399 {
14400 	return wma_config_bmiss_bcnt_params(vdev_id, first_cnt, final_cnt);
14401 }
14402 
sme_send_limit_off_channel_params(mac_handle_t mac_handle,uint8_t vdev_id,bool is_tos_active,uint32_t max_off_chan_time,uint32_t rest_time,bool skip_dfs_chan)14403 QDF_STATUS sme_send_limit_off_channel_params(mac_handle_t mac_handle,
14404 					     uint8_t vdev_id,
14405 					     bool is_tos_active,
14406 					     uint32_t max_off_chan_time,
14407 					     uint32_t rest_time,
14408 					     bool skip_dfs_chan)
14409 {
14410 	struct sir_limit_off_chan *cmd;
14411 	struct scheduler_msg msg = {0};
14412 
14413 	cmd = qdf_mem_malloc(sizeof(*cmd));
14414 	if (!cmd)
14415 		return QDF_STATUS_E_NOMEM;
14416 
14417 	cmd->vdev_id = vdev_id;
14418 	cmd->is_tos_active = is_tos_active;
14419 	cmd->max_off_chan_time = max_off_chan_time;
14420 	cmd->rest_time = rest_time;
14421 	cmd->skip_dfs_chans = skip_dfs_chan;
14422 
14423 	msg.type = WMA_SET_LIMIT_OFF_CHAN;
14424 	msg.reserved = 0;
14425 	msg.bodyptr = cmd;
14426 
14427 	if (!QDF_IS_STATUS_SUCCESS(scheduler_post_message(QDF_MODULE_ID_SME,
14428 							  QDF_MODULE_ID_WMA,
14429 							  QDF_MODULE_ID_WMA,
14430 							  &msg))) {
14431 		sme_err("Not able to post WMA_SET_LIMIT_OFF_CHAN to WMA");
14432 		qdf_mem_free(cmd);
14433 		return QDF_STATUS_E_FAILURE;
14434 	}
14435 
14436 	return QDF_STATUS_SUCCESS;
14437 }
14438 
sme_unpack_rsn_ie(mac_handle_t mac_handle,uint8_t * buf,uint8_t buf_len,tDot11fIERSN * rsn_ie,bool append_ie)14439 uint32_t sme_unpack_rsn_ie(mac_handle_t mac_handle, uint8_t *buf,
14440 			   uint8_t buf_len, tDot11fIERSN *rsn_ie,
14441 			   bool append_ie)
14442 {
14443 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
14444 
14445 	return dot11f_unpack_ie_rsn(mac_ctx, buf, buf_len, rsn_ie, append_ie);
14446 }
14447 
sme_unpack_assoc_rsp(mac_handle_t mac_handle,struct wlan_cm_connect_resp * rsp,struct sDot11fAssocResponse * assoc_resp)14448 QDF_STATUS sme_unpack_assoc_rsp(mac_handle_t mac_handle,
14449 				struct wlan_cm_connect_resp *rsp,
14450 				struct sDot11fAssocResponse *assoc_resp)
14451 {
14452 	QDF_STATUS status;
14453 	uint8_t ies_offset = WLAN_ASSOC_RSP_IES_OFFSET;
14454 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
14455 
14456 	status = dot11f_parse_assoc_response(mac_ctx,
14457 					     rsp->connect_ies.assoc_rsp.ptr,
14458 					     rsp->connect_ies.assoc_rsp.len,
14459 					     assoc_resp, false);
14460 
14461 	lim_strip_and_decode_eht_cap(rsp->connect_ies.assoc_rsp.ptr + ies_offset,
14462 				     rsp->connect_ies.assoc_rsp.len - ies_offset,
14463 				     &assoc_resp->eht_cap,
14464 				     assoc_resp->he_cap,
14465 				     rsp->freq);
14466 	return status;
14467 }
14468 
sme_get_hs20vendor_ie(mac_handle_t mac_handle,uint8_t * frame,uint32_t frame_len,struct sDot11fIEhs20vendor_ie * hs20vendor_ie)14469 void sme_get_hs20vendor_ie(mac_handle_t mac_handle, uint8_t *frame,
14470 			   uint32_t frame_len,
14471 			   struct sDot11fIEhs20vendor_ie *hs20vendor_ie)
14472 {
14473 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
14474 	struct sSirProbeRespBeacon *beacon_probe_resp =
14475 		qdf_mem_malloc(sizeof(struct sSirProbeRespBeacon));
14476 
14477 	if (!beacon_probe_resp)
14478 		return;
14479 
14480 	sir_parse_beacon_ie(mac_ctx, beacon_probe_resp, frame, frame_len);
14481 
14482 	qdf_mem_copy(hs20vendor_ie, &beacon_probe_resp->hs20vendor_ie,
14483 		     sizeof(struct sDot11fIEhs20vendor_ie));
14484 
14485 	qdf_mem_free(beacon_probe_resp);
14486 }
14487 
sme_add_qcn_ie(mac_handle_t mac_handle,uint8_t * ie_data,uint16_t * ie_len)14488 void sme_add_qcn_ie(mac_handle_t mac_handle, uint8_t *ie_data,
14489 		    uint16_t *ie_len)
14490 {
14491 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
14492 	static const uint8_t qcn_ie[] = {WLAN_ELEMID_VENDOR, 8,
14493 					 0x8C, 0xFD, 0xF0, 0x1,
14494 					 QCN_IE_VERSION_SUBATTR_ID,
14495 					 QCN_IE_VERSION_SUBATTR_DATA_LEN,
14496 					 QCN_IE_VERSION_SUPPORTED,
14497 					 QCN_IE_SUBVERSION_SUPPORTED};
14498 
14499 	if (!mac_ctx->mlme_cfg->sta.qcn_ie_support) {
14500 		sme_debug("QCN IE is not supported");
14501 		return;
14502 	}
14503 
14504 	if (((*ie_len) + sizeof(qcn_ie)) > MAX_DEFAULT_SCAN_IE_LEN) {
14505 		sme_err("IE buffer not enough for QCN IE");
14506 		return;
14507 	}
14508 
14509 	qdf_mem_copy(ie_data + (*ie_len), qcn_ie, sizeof(qcn_ie));
14510 	(*ie_len) += sizeof(qcn_ie);
14511 }
14512 
14513 #ifdef FEATURE_BSS_TRANSITION
14514 /**
14515  * sme_get_status_for_candidate() - Get bss transition status for candidate
14516  * @mac_handle: Opaque handle to the global MAC context
14517  * @conn_bss: connected bss scan entry
14518  * @candidate_bss: candidate bss scan entry
14519  * @info: candiadate bss information
14520  * @trans_reason: transition reason code
14521  * @is_bt_in_progress: bt activity indicator
14522  *
14523  * Return : true if candidate is rejected and reject reason is filled
14524  * @info->status. Otherwise returns false.
14525  */
sme_get_status_for_candidate(mac_handle_t mac_handle,struct scan_cache_entry * conn_bss,struct scan_cache_entry * candidate_bss,struct bss_candidate_info * info,uint8_t trans_reason,bool is_bt_in_progress)14526 static bool sme_get_status_for_candidate(mac_handle_t mac_handle,
14527 					 struct scan_cache_entry *conn_bss,
14528 					 struct scan_cache_entry *candidate_bss,
14529 					 struct bss_candidate_info *info,
14530 					 uint8_t trans_reason,
14531 					 bool is_bt_in_progress)
14532 {
14533 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
14534 	struct wlan_mlme_mbo *mbo_cfg;
14535 	int8_t current_rssi_mcc_thres;
14536 	uint32_t bss_chan_freq, conn_bss_chan_freq;
14537 	bool bss_chan_safe, conn_bss_chan_safe;
14538 
14539 	if (!(mac_ctx->mlme_cfg)) {
14540 		pe_err("mlme cfg is NULL");
14541 		return false;
14542 	}
14543 	mbo_cfg = &mac_ctx->mlme_cfg->mbo_cfg;
14544 
14545 	/*
14546 	 * Low RSSI based rejection
14547 	 * If candidate rssi is less than mbo_candidate_rssi_thres and connected
14548 	 * bss rssi is greater than mbo_current_rssi_thres, then reject the
14549 	 * candidate with MBO reason code 4.
14550 	 */
14551 	if ((candidate_bss->rssi_raw < mbo_cfg->mbo_candidate_rssi_thres) &&
14552 	    (conn_bss->rssi_raw > mbo_cfg->mbo_current_rssi_thres)) {
14553 		sme_err("Candidate BSS " QDF_MAC_ADDR_FMT " has LOW RSSI(%d), hence reject",
14554 			QDF_MAC_ADDR_REF(candidate_bss->bssid.bytes),
14555 			candidate_bss->rssi_raw);
14556 		info->status = QCA_STATUS_REJECT_LOW_RSSI;
14557 		return true;
14558 	}
14559 
14560 	if (trans_reason == MBO_TRANSITION_REASON_LOAD_BALANCING ||
14561 	    trans_reason == MBO_TRANSITION_REASON_TRANSITIONING_TO_PREMIUM_AP) {
14562 		bss_chan_freq = candidate_bss->channel.chan_freq;
14563 		conn_bss_chan_freq = conn_bss->channel.chan_freq;
14564 		/*
14565 		 * MCC rejection
14566 		 * If moving to candidate's channel will result in MCC scenario
14567 		 * and the rssi of connected bss is greater than
14568 		 * mbo_current_rssi_mss_thres, then reject the candidate with
14569 		 * MBO reason code 3.
14570 		 */
14571 		current_rssi_mcc_thres = mbo_cfg->mbo_current_rssi_mcc_thres;
14572 		if ((conn_bss->rssi_raw > current_rssi_mcc_thres) &&
14573 		    csr_is_mcc_channel(mac_ctx, bss_chan_freq)) {
14574 			sme_err("Candidate BSS "  QDF_MAC_ADDR_FMT " causes MCC, hence reject",
14575 				QDF_MAC_ADDR_REF(candidate_bss->bssid.bytes));
14576 			info->status =
14577 				QCA_STATUS_REJECT_INSUFFICIENT_QOS_CAPACITY;
14578 			return true;
14579 		}
14580 
14581 		/*
14582 		 * BT coex rejection
14583 		 * If AP is trying to move the client from 5G to 2.4G and moving
14584 		 * to 2.4G will result in BT coex and candidate channel rssi is
14585 		 * less than mbo_candidate_rssi_btc_thres, then reject the
14586 		 * candidate with MBO reason code 2.
14587 		 */
14588 		if (WLAN_REG_IS_5GHZ_CH_FREQ(conn_bss_chan_freq) &&
14589 		    WLAN_REG_IS_24GHZ_CH_FREQ(bss_chan_freq) &&
14590 		    is_bt_in_progress &&
14591 		    (candidate_bss->rssi_raw < mbo_cfg->mbo_candidate_rssi_btc_thres)) {
14592 			sme_err("Candidate BSS " QDF_MAC_ADDR_FMT " causes BT coex, hence reject",
14593 				QDF_MAC_ADDR_REF(candidate_bss->bssid.bytes));
14594 			info->status =
14595 				QCA_STATUS_REJECT_EXCESSIVE_DELAY_EXPECTED;
14596 			return true;
14597 		}
14598 
14599 		/*
14600 		 * LTE coex rejection
14601 		 * If moving to candidate's channel can cause LTE coex, then
14602 		 * reject the candidate with MBO reason code 5.
14603 		 */
14604 		conn_bss_chan_safe = policy_mgr_is_safe_channel(
14605 			mac_ctx->psoc, conn_bss_chan_freq);
14606 		bss_chan_safe = policy_mgr_is_safe_channel(
14607 			mac_ctx->psoc, bss_chan_freq);
14608 
14609 		if (conn_bss_chan_safe && !bss_chan_safe) {
14610 			sme_err("High interference expected if transitioned to BSS "
14611 				QDF_MAC_ADDR_FMT " hence reject",
14612 				QDF_MAC_ADDR_REF(candidate_bss->bssid.bytes));
14613 			info->status =
14614 				QCA_STATUS_REJECT_HIGH_INTERFERENCE;
14615 			return true;
14616 		}
14617 	}
14618 
14619 	return false;
14620 }
14621 
sme_get_bss_transition_status(mac_handle_t mac_handle,uint8_t transition_reason,struct qdf_mac_addr * bssid,struct bss_candidate_info * info,uint16_t n_candidates,bool is_bt_in_progress)14622 QDF_STATUS sme_get_bss_transition_status(mac_handle_t mac_handle,
14623 					 uint8_t transition_reason,
14624 					 struct qdf_mac_addr *bssid,
14625 					 struct bss_candidate_info *info,
14626 					 uint16_t n_candidates,
14627 					 bool is_bt_in_progress)
14628 {
14629 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
14630 	QDF_STATUS status = QDF_STATUS_SUCCESS;
14631 	uint16_t i;
14632 	qdf_list_t *bssid_list = NULL, *candidate_list = NULL;
14633 	struct scan_cache_node *conn_bss = NULL, *candidate_bss = NULL;
14634 	qdf_list_node_t *cur_lst = NULL;
14635 
14636 	if (!n_candidates || !info) {
14637 		sme_err("No candidate info available");
14638 		return QDF_STATUS_E_INVAL;
14639 	}
14640 
14641 	/* Get the connected BSS descriptor */
14642 	status = csr_scan_get_result_for_bssid(mac_ctx, bssid, &bssid_list);
14643 	if (QDF_IS_STATUS_ERROR(status)) {
14644 		sme_err("connected BSS: " QDF_MAC_ADDR_FMT " not present in scan db",
14645 			QDF_MAC_ADDR_REF(bssid->bytes));
14646 		goto purge;
14647 	}
14648 	qdf_list_peek_front(bssid_list, &cur_lst);
14649 	if (!cur_lst) {
14650 		sme_err("Failed to peek connected BSS : " QDF_MAC_ADDR_FMT,
14651 			QDF_MAC_ADDR_REF(bssid->bytes));
14652 		goto purge;
14653 	}
14654 
14655 	conn_bss =
14656 		qdf_container_of(cur_lst, struct scan_cache_node, node);
14657 
14658 	for (i = 0; i < n_candidates; i++) {
14659 		/* Get candidate BSS descriptors */
14660 		status = csr_scan_get_result_for_bssid(mac_ctx, &info[i].bssid,
14661 						       &candidate_list);
14662 		if (QDF_IS_STATUS_ERROR(status)) {
14663 			sme_err("BSS " QDF_MAC_ADDR_FMT " not present in scan db",
14664 				QDF_MAC_ADDR_REF(info[i].bssid.bytes));
14665 			info[i].status = QCA_STATUS_REJECT_UNKNOWN;
14666 			continue;
14667 		}
14668 		cur_lst = NULL;
14669 		qdf_list_peek_front(candidate_list, &cur_lst);
14670 		if (!cur_lst) {
14671 			sme_err("Failed to peek candidate: " QDF_MAC_ADDR_FMT,
14672 				QDF_MAC_ADDR_REF(info[i].bssid.bytes));
14673 			goto next;
14674 		}
14675 
14676 		candidate_bss =
14677 			qdf_container_of(cur_lst, struct scan_cache_node, node);
14678 		if (!sme_get_status_for_candidate(mac_handle,
14679 						  conn_bss->entry,
14680 						  candidate_bss->entry,
14681 						  &info[i], transition_reason,
14682 						  is_bt_in_progress)) {
14683 			/*
14684 			 * If status is not over written, it means it is a
14685 			 * candidate for accept.
14686 			 */
14687 			info[i].status = QCA_STATUS_ACCEPT;
14688 		}
14689 next:
14690 		wlan_scan_purge_results(candidate_list);
14691 		candidate_list = NULL;
14692 	}
14693 
14694 	/* success */
14695 	status = QDF_STATUS_SUCCESS;
14696 
14697 purge:
14698 	if (bssid_list)
14699 		wlan_scan_purge_results(bssid_list);
14700 	if (candidate_list)
14701 		wlan_scan_purge_results(candidate_list);
14702 
14703 	return status;
14704 }
14705 #endif /* FEATURE_BSS_TRANSITION */
14706 
sme_is_conn_state_connected(mac_handle_t mac_handle,uint8_t session_id)14707 bool sme_is_conn_state_connected(mac_handle_t mac_handle, uint8_t session_id)
14708 {
14709 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
14710 
14711 	return csr_is_conn_state_connected(mac_ctx, session_id);
14712 }
14713 
sme_get_oper_chan_freq(struct wlan_objmgr_vdev * vdev)14714 int16_t sme_get_oper_chan_freq(struct wlan_objmgr_vdev *vdev)
14715 {
14716 	uint8_t vdev_id;
14717 	struct csr_roam_session *session;
14718 	struct mac_context *mac_ctx;
14719 	mac_handle_t mac_handle;
14720 
14721 	if (!vdev) {
14722 		sme_err("Invalid vdev id is passed");
14723 		return 0;
14724 	}
14725 
14726 	mac_handle = cds_get_context(QDF_MODULE_ID_SME);
14727 	if (!mac_handle)
14728 		return 0;
14729 
14730 	mac_ctx = MAC_CONTEXT(mac_handle);
14731 	vdev_id = wlan_vdev_get_id(vdev);
14732 	if (!CSR_IS_SESSION_VALID(mac_ctx, vdev_id)) {
14733 		sme_err("Invalid vdev id is passed");
14734 		return 0;
14735 	}
14736 
14737 	session = CSR_GET_SESSION(mac_ctx, vdev_id);
14738 
14739 	return wlan_get_operation_chan_freq(vdev);
14740 }
14741 
sme_get_oper_ch_width(struct wlan_objmgr_vdev * vdev)14742 enum phy_ch_width sme_get_oper_ch_width(struct wlan_objmgr_vdev *vdev)
14743 {
14744 	struct wlan_channel *des_chan;
14745 
14746 	if (!vdev) {
14747 		sme_err("Invalid vdev id is passed");
14748 		return CH_WIDTH_INVALID;
14749 	}
14750 
14751 	des_chan = wlan_vdev_mlme_get_des_chan(vdev);
14752 	if (!des_chan) {
14753 		sme_debug("NULL des_chan");
14754 		return CH_WIDTH_INVALID;
14755 	}
14756 
14757 	return des_chan->ch_width;
14758 
14759 }
14760 
sme_get_sec20chan_freq_mhz(struct wlan_objmgr_vdev * vdev,uint16_t * sec20chan_freq)14761 int sme_get_sec20chan_freq_mhz(struct wlan_objmgr_vdev *vdev,
14762 						uint16_t *sec20chan_freq)
14763 {
14764 	uint8_t vdev_id;
14765 
14766 	vdev_id = wlan_vdev_get_id(vdev);
14767 	/* Need to extend */
14768 	return 0;
14769 }
14770 
14771 #ifdef WLAN_FEATURE_SAE
sme_handle_sae_msg(mac_handle_t mac_handle,uint8_t session_id,uint8_t sae_status,struct qdf_mac_addr peer_mac_addr,const uint8_t * pmkid)14772 QDF_STATUS sme_handle_sae_msg(mac_handle_t mac_handle,
14773 			      uint8_t session_id,
14774 			      uint8_t sae_status,
14775 			      struct qdf_mac_addr peer_mac_addr,
14776 			      const uint8_t *pmkid)
14777 {
14778 	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
14779 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
14780 	struct sir_sae_msg *sae_msg;
14781 	struct scheduler_msg sch_msg = {0};
14782 	struct wmi_roam_auth_status_params *params;
14783 	struct csr_roam_session *csr_session;
14784 	enum QDF_OPMODE opmode;
14785 
14786 	qdf_status = sme_acquire_global_lock(&mac->sme);
14787 	if (QDF_IS_STATUS_ERROR(qdf_status))
14788 		return qdf_status;
14789 
14790 	csr_session = CSR_GET_SESSION(mac, session_id);
14791 	if (!csr_session) {
14792 		sme_err("session %d not found", session_id);
14793 		qdf_status = QDF_STATUS_E_FAILURE;
14794 		goto error;
14795 	}
14796 
14797 	/* Update the status to SME in below cases
14798 	 * 1. SAP mode: Always
14799 	 * 2. STA mode: When the device is not in joined state
14800 	 *
14801 	 * If the device is in joined state, send the status to WMA which
14802 	 * is meant for roaming.
14803 	 */
14804 	opmode = wlan_get_opmode_from_vdev_id(mac->pdev, session_id);
14805 	if ((opmode == QDF_SAP_MODE) || (opmode == QDF_P2P_GO_MODE) ||
14806 	    !CSR_IS_ROAM_JOINED(mac, session_id)) {
14807 		sae_msg = qdf_mem_malloc(sizeof(*sae_msg));
14808 		if (!sae_msg) {
14809 			qdf_status = QDF_STATUS_E_NOMEM;
14810 			goto error;
14811 		}
14812 
14813 		sae_msg->message_type = eWNI_SME_SEND_SAE_MSG;
14814 		sae_msg->length = sizeof(*sae_msg);
14815 		sae_msg->vdev_id = session_id;
14816 		sae_msg->sae_status = sae_status;
14817 		sae_msg->result_code = eSIR_SME_AUTH_REFUSED;
14818 		qdf_mem_copy(sae_msg->peer_mac_addr,
14819 			     peer_mac_addr.bytes,
14820 			     QDF_MAC_ADDR_SIZE);
14821 		qdf_mem_zero(sae_msg->pmkid, PMKID_LEN);
14822 		if (pmkid)
14823 			qdf_mem_copy(sae_msg->pmkid, pmkid, PMKID_LEN);
14824 		sme_debug("SAE: sae_status %d vdev_id %d Peer: "
14825 			  QDF_MAC_ADDR_FMT, sae_msg->sae_status,
14826 			  sae_msg->vdev_id,
14827 			  QDF_MAC_ADDR_REF(sae_msg->peer_mac_addr));
14828 
14829 		sch_msg.type = eWNI_SME_SEND_SAE_MSG;
14830 		sch_msg.bodyptr = sae_msg;
14831 
14832 		qdf_status = scheduler_post_message(QDF_MODULE_ID_SME,
14833 						    QDF_MODULE_ID_PE,
14834 						    QDF_MODULE_ID_PE,
14835 						    &sch_msg);
14836 		if (QDF_IS_STATUS_ERROR(qdf_status)) {
14837 			qdf_mem_free(sae_msg);
14838 			goto error;
14839 		}
14840 	} else {
14841 		/*
14842 		 * For WPA3 SAE roaming, external auth offload is enabled. The
14843 		 * firmware will send preauth start event after candidate
14844 		 * selection. The supplicant will perform the SAE authentication
14845 		 * and will send the auth status, PMKID in the external auth
14846 		 * cmd.
14847 		 *
14848 		 * csr roam state is CSR_ROAM_STATE_JOINED. So this SAE
14849 		 * external auth event is for wpa3 roam pre-auth offload.
14850 		 *
14851 		 * Post the preauth status to WMA.
14852 		 */
14853 		params = qdf_mem_malloc(sizeof(*params));
14854 		if (!params) {
14855 			qdf_status = QDF_STATUS_E_NOMEM;
14856 			goto error;
14857 		}
14858 
14859 		params->vdev_id = session_id;
14860 		params->preauth_status = sae_status;
14861 		qdf_copy_macaddr(&params->bssid, &peer_mac_addr);
14862 
14863 		qdf_mem_zero(params->pmkid, PMKID_LEN);
14864 		if (pmkid)
14865 			qdf_mem_copy(params->pmkid, pmkid, PMKID_LEN);
14866 
14867 		sch_msg.type = WMA_ROAM_PRE_AUTH_STATUS;
14868 		sch_msg.bodyptr = params;
14869 
14870 		qdf_status = scheduler_post_message(QDF_MODULE_ID_SME,
14871 						    QDF_MODULE_ID_WMA,
14872 						    QDF_MODULE_ID_WMA,
14873 						    &sch_msg);
14874 		if (QDF_IS_STATUS_ERROR(qdf_status)) {
14875 			sme_err("WMA_ROAM_PRE_AUTH_STATUS cmd posting failed");
14876 			qdf_mem_free(params);
14877 		}
14878 	}
14879 error:
14880 	sme_release_global_lock(&mac->sme);
14881 
14882 	return qdf_status;
14883 }
14884 #endif
14885 
sme_is_sta_key_exchange_in_progress(mac_handle_t mac_handle,uint8_t session_id)14886 bool sme_is_sta_key_exchange_in_progress(mac_handle_t mac_handle,
14887 					 uint8_t session_id)
14888 {
14889 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
14890 
14891 	if (!CSR_IS_SESSION_VALID(mac_ctx, session_id)) {
14892 		sme_err("Invalid session id: %d", session_id);
14893 		return false;
14894 	}
14895 
14896 	return CSR_IS_WAIT_FOR_KEY(mac_ctx, session_id);
14897 }
14898 
sme_validate_channel_list(mac_handle_t mac_handle,uint32_t * chan_freq_list,uint8_t num_channels)14899 bool sme_validate_channel_list(mac_handle_t mac_handle,
14900 			       uint32_t *chan_freq_list,
14901 			       uint8_t num_channels)
14902 {
14903 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
14904 	uint8_t i = 0;
14905 	uint8_t j;
14906 	bool found;
14907 	struct csr_channel *ch_lst_info = &mac_ctx->scan.base_channels;
14908 
14909 	if (!chan_freq_list || !num_channels) {
14910 		sme_err("Chan list empty %pK or num_channels is 0",
14911 			chan_freq_list);
14912 		return false;
14913 	}
14914 
14915 	while (i < num_channels) {
14916 		found = false;
14917 		for (j = 0; j < ch_lst_info->numChannels; j++) {
14918 			if (ch_lst_info->channel_freq_list[j] ==
14919 					chan_freq_list[i]) {
14920 				found = true;
14921 				break;
14922 			}
14923 		}
14924 
14925 		if (!found) {
14926 			sme_debug("Invalid channel %d", chan_freq_list[i]);
14927 			return false;
14928 		}
14929 
14930 		i++;
14931 	}
14932 
14933 	return true;
14934 }
14935 
sme_set_pmf_wep_cfg(mac_handle_t mac_handle,uint8_t pmf_wep)14936 void sme_set_pmf_wep_cfg(mac_handle_t mac_handle, uint8_t pmf_wep)
14937 {
14938 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
14939 
14940 	mac_ctx->is_usr_cfg_pmf_wep = pmf_wep;
14941 }
14942 
sme_set_cfg_disable_tx(mac_handle_t mac_handle,uint8_t vdev_id,uint8_t val)14943 void sme_set_cfg_disable_tx(mac_handle_t mac_handle, uint8_t vdev_id,
14944 			    uint8_t val)
14945 {
14946 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
14947 	int ret_val;
14948 
14949 	sme_debug("Block Tx %d", val);
14950 	if (val) {
14951 		if (mac->sme.tx_queue_cb) {
14952 			sme_debug("Blocking the Tx queue");
14953 			mac->sme.tx_queue_cb(mac->hdd_handle, vdev_id,
14954 					WLAN_STOP_ALL_NETIF_QUEUE,
14955 					WLAN_CONTROL_PATH);
14956 		}
14957 	} else {
14958 		if (mac->sme.tx_queue_cb) {
14959 			sme_debug("Enable the Tx queue");
14960 			mac->sme.tx_queue_cb(mac->hdd_handle, vdev_id,
14961 					WLAN_START_ALL_NETIF_QUEUE,
14962 					WLAN_CONTROL_PATH);
14963 		}
14964 	}
14965 
14966 	ret_val = wma_cli_set_command(vdev_id,
14967 			wmi_vdev_param_prohibit_data_mgmt,
14968 			val, VDEV_CMD);
14969 	if (ret_val)
14970 		sme_err("Failed to set firmware, errno %d", ret_val);
14971 
14972 	mac->usr_cfg_disable_rsp_tx = val;
14973 }
14974 
sme_set_amsdu(mac_handle_t mac_handle,bool enable)14975 void sme_set_amsdu(mac_handle_t mac_handle, bool enable)
14976 {
14977 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
14978 	mac_ctx->is_usr_cfg_amsdu_enabled = enable;
14979 }
14980 
sme_set_bss_max_idle_period(mac_handle_t mac_handle,uint16_t cfg_val)14981 void sme_set_bss_max_idle_period(mac_handle_t mac_handle, uint16_t cfg_val)
14982 {
14983 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
14984 	mac_ctx->mlme_cfg->sta.bss_max_idle_period = cfg_val;
14985 }
14986 
14987 #ifdef WLAN_FEATURE_11BE
sme_set_eht_mcs_info(struct mac_context * mac_ctx)14988 static void sme_set_eht_mcs_info(struct mac_context *mac_ctx)
14989 {
14990 	if (mac_ctx->usr_eht_testbed_cfg) {
14991 		mac_ctx->eht_cap_2g.bw_le_80_rx_max_nss_for_mcs_0_to_9 = 1;
14992 		mac_ctx->eht_cap_2g.bw_le_80_tx_max_nss_for_mcs_0_to_9 = 1;
14993 	}
14994 }
14995 #else
14996 #ifdef WLAN_FEATURE_11AX
sme_set_eht_mcs_info(struct mac_context * mac_ctx)14997 static void sme_set_eht_mcs_info(struct mac_context *mac_ctx)
14998 {
14999 }
15000 #endif
15001 #endif
15002 
15003 #ifdef WLAN_FEATURE_11AX
sme_set_he_bw_cap(mac_handle_t mac_handle,uint8_t vdev_id,enum eSirMacHTChannelWidth chwidth)15004 void sme_set_he_bw_cap(mac_handle_t mac_handle, uint8_t vdev_id,
15005 		       enum eSirMacHTChannelWidth chwidth)
15006 {
15007 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
15008 	struct csr_roam_session *session;
15009 
15010 	session = CSR_GET_SESSION(mac_ctx, vdev_id);
15011 	if (!session) {
15012 		sme_debug("No session for id %d", vdev_id);
15013 		return;
15014 	}
15015 	sme_debug("Config HE caps for BW %d", chwidth);
15016 	mac_ctx->mlme_cfg->he_caps.dot11_he_cap.chan_width_0 = 0;
15017 	mac_ctx->mlme_cfg->he_caps.dot11_he_cap.chan_width_1 = 0;
15018 	mac_ctx->mlme_cfg->he_caps.dot11_he_cap.chan_width_2 = 0;
15019 	mac_ctx->mlme_cfg->he_caps.dot11_he_cap.chan_width_3 = 0;
15020 	mac_ctx->mlme_cfg->he_caps.dot11_he_cap.chan_width_4 = 0;
15021 	mac_ctx->mlme_cfg->he_caps.dot11_he_cap.chan_width_5 = 0;
15022 	mac_ctx->mlme_cfg->he_caps.dot11_he_cap.chan_width_6 = 0;
15023 
15024 	mac_ctx->he_cap_2g.chan_width_0 = 0;
15025 	mac_ctx->he_cap_2g.chan_width_1 = 0;
15026 	mac_ctx->he_cap_2g.chan_width_2 = 0;
15027 	mac_ctx->he_cap_2g.chan_width_3 = 0;
15028 	mac_ctx->he_cap_2g.chan_width_4 = 0;
15029 	mac_ctx->he_cap_2g.chan_width_5 = 0;
15030 	mac_ctx->he_cap_2g.chan_width_6 = 0;
15031 
15032 	mac_ctx->he_cap_5g.chan_width_0 = 0;
15033 	mac_ctx->he_cap_5g.chan_width_1 = 0;
15034 	mac_ctx->he_cap_5g.chan_width_2 = 0;
15035 	mac_ctx->he_cap_5g.chan_width_3 = 0;
15036 	mac_ctx->he_cap_5g.chan_width_4 = 0;
15037 	mac_ctx->he_cap_5g.chan_width_5 = 0;
15038 	mac_ctx->he_cap_5g.chan_width_6 = 0;
15039 
15040 	switch (chwidth) {
15041 	case eHT_CHANNEL_WIDTH_160MHZ:
15042 	case eHT_CHANNEL_WIDTH_320MHZ:
15043 		mac_ctx->mlme_cfg->he_caps.dot11_he_cap.chan_width_1 = 1;
15044 		mac_ctx->mlme_cfg->he_caps.dot11_he_cap.chan_width_2 = 1;
15045 		*((uint16_t *)
15046 		mac_ctx->mlme_cfg->he_caps.dot11_he_cap.rx_he_mcs_map_160) =
15047 		mac_ctx->mlme_cfg->he_caps.dot11_he_cap.rx_he_mcs_map_lt_80;
15048 		*((uint16_t *)
15049 		mac_ctx->he_cap_5g.rx_he_mcs_map_160) =
15050 		mac_ctx->he_cap_5g.rx_he_mcs_map_lt_80;
15051 		*((uint16_t *)
15052 		mac_ctx->mlme_cfg->he_caps.dot11_he_cap.tx_he_mcs_map_160) =
15053 		mac_ctx->mlme_cfg->he_caps.dot11_he_cap.tx_he_mcs_map_lt_80;
15054 		*((uint16_t *)
15055 		mac_ctx->he_cap_5g.tx_he_mcs_map_160) =
15056 		mac_ctx->he_cap_5g.tx_he_mcs_map_lt_80;
15057 		mac_ctx->he_cap_5g.chan_width_1 = 1;
15058 		mac_ctx->he_cap_5g.chan_width_2 = 1;
15059 		fallthrough;
15060 	case eHT_CHANNEL_WIDTH_80MHZ:
15061 		mac_ctx->mlme_cfg->he_caps.dot11_he_cap.chan_width_1 = 1;
15062 		mac_ctx->he_cap_5g.chan_width_1 = 1;
15063 		fallthrough;
15064 	case eHT_CHANNEL_WIDTH_40MHZ:
15065 		sme_set_eht_mcs_info(mac_ctx);
15066 		mac_ctx->mlme_cfg->he_caps.dot11_he_cap.chan_width_0 = 1;
15067 		mac_ctx->mlme_cfg->he_caps.dot11_he_cap.chan_width_1 = 1;
15068 		mac_ctx->he_cap_2g.chan_width_0 = 1;
15069 		mac_ctx->he_cap_5g.chan_width_1 = 1;
15070 		fallthrough;
15071 	case eHT_CHANNEL_WIDTH_20MHZ:
15072 		break;
15073 	default:
15074 		sme_debug("Config BW %d not handled", chwidth);
15075 	}
15076 	csr_update_session_he_cap(mac_ctx, session);
15077 }
15078 
sme_check_enable_ru_242_tx(mac_handle_t mac_handle,uint8_t vdev_id)15079 void sme_check_enable_ru_242_tx(mac_handle_t mac_handle, uint8_t vdev_id)
15080 {
15081 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
15082 	int ret;
15083 
15084 	sme_debug("Config VDEV for RU 242 Tx, usr cfg %d",
15085 		  mac_ctx->usr_cfg_ru_242_tone_tx);
15086 	if (mac_ctx->usr_cfg_ru_242_tone_tx) {
15087 		ret = wma_cli_set_command(vdev_id, wmi_vdev_param_chwidth,
15088 					  0, VDEV_CMD);
15089 		if (ret)
15090 			sme_err("Failed to set VDEV BW to 20MHz");
15091 	}
15092 }
15093 
sme_set_ru_242_tone_tx_cfg(mac_handle_t mac_handle,uint8_t cfg_val)15094 void sme_set_ru_242_tone_tx_cfg(mac_handle_t mac_handle, uint8_t cfg_val)
15095 {
15096 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
15097 
15098 	mac_ctx->usr_cfg_ru_242_tone_tx = cfg_val;
15099 }
15100 
sme_set_he_testbed_def(mac_handle_t mac_handle,uint8_t vdev_id)15101 void sme_set_he_testbed_def(mac_handle_t mac_handle, uint8_t vdev_id)
15102 {
15103 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
15104 	struct csr_roam_session *session;
15105 	QDF_STATUS status;
15106 	uint32_t prevent_pm[] = {29, 1};
15107 
15108 	session = CSR_GET_SESSION(mac_ctx, vdev_id);
15109 
15110 	if (!session) {
15111 		sme_debug("No session for id %d", vdev_id);
15112 		return;
15113 	}
15114 	sme_debug("set HE testbed defaults");
15115 	mac_ctx->mlme_cfg->he_caps.dot11_he_cap.htc_he = 0;
15116 	mac_ctx->mlme_cfg->he_caps.dot11_he_cap.amsdu_in_ampdu = 0;
15117 	mac_ctx->mlme_cfg->he_caps.dot11_he_cap.twt_request = 0;
15118 	mac_ctx->mlme_cfg->he_caps.dot11_he_cap.broadcast_twt = 0;
15119 	mac_ctx->mlme_cfg->twt_cfg.disable_btwt_usr_cfg = true;
15120 	mac_ctx->mlme_cfg->he_caps.dot11_he_cap.rx_ctrl_frame = 0;
15121 	mac_ctx->mlme_cfg->he_caps.dot11_he_cap.omi_a_ctrl = 0;
15122 	mac_ctx->mlme_cfg->he_caps.dot11_he_cap.he_ppdu_20_in_160_80p80Mhz = 0;
15123 	mac_ctx->mlme_cfg->he_caps.dot11_he_cap.he_ppdu_20_in_40Mhz_2G = 0;
15124 	mac_ctx->mlme_cfg->he_caps.dot11_he_cap.he_ppdu_80_in_160_80p80Mhz = 0;
15125 	mac_ctx->mlme_cfg->he_caps.dot11_he_cap.dcm_enc_tx = 0;
15126 	mac_ctx->mlme_cfg->he_caps.dot11_he_cap.dcm_enc_rx = 0;
15127 	mac_ctx->mlme_cfg->he_caps.dot11_he_cap.ul_mu = 0;
15128 	mac_ctx->mlme_cfg->he_caps.dot11_he_cap.max_nc = 0;
15129 	mac_ctx->mlme_cfg->he_caps.dot11_he_cap.trigger_frm_mac_pad =
15130 					QCA_WLAN_HE_16US_OF_PROCESS_TIME;
15131 	mac_ctx->mlme_cfg->he_caps.dot11_he_cap.flex_twt_sched = 0;
15132 	mac_ctx->mlme_cfg->he_caps.dot11_he_cap.ofdma_ra = 0;
15133 	mac_ctx->mlme_cfg->he_caps.dot11_he_cap.he_4x_ltf_3200_gi_ndp = 0;
15134 	mac_ctx->mlme_cfg->he_caps.dot11_he_cap.qtp = 0;
15135 	mac_ctx->mlme_cfg->he_caps.dot11_he_cap.bsrp_ampdu_aggr = 0;
15136 	mac_ctx->mlme_cfg->he_caps.dot11_he_cap.a_bqr = 0;
15137 	mac_ctx->mlme_cfg->he_caps.dot11_he_cap.he_sub_ch_sel_tx_supp = 0;
15138 	mac_ctx->mlme_cfg->he_caps.dot11_he_cap.ndp_feedback_supp = 0;
15139 	mac_ctx->mlme_cfg->he_caps.dot11_he_cap.ops_supp = 0;
15140 	mac_ctx->mlme_cfg->he_caps.dot11_he_cap.srp = 0;
15141 	mac_ctx->mlme_cfg->he_caps.dot11_he_cap.power_boost = 0;
15142 	mac_ctx->mlme_cfg->he_caps.dot11_he_cap.num_sounding_lt_80 = 0;
15143 	mac_ctx->mlme_cfg->he_caps.dot11_he_cap.num_sounding_gt_80 = 0;
15144 	mac_ctx->mlme_cfg->he_caps.dot11_he_cap.dl_mu_mimo_part_bw = 0;
15145 	mac_ctx->mlme_cfg->he_caps.dot11_he_cap.non_trig_cqi_feedback = 0;
15146 	mac_ctx->mlme_cfg->he_caps.dot11_he_cap.tx_1024_qam_lt_242_tone_ru = 0;
15147 	mac_ctx->mlme_cfg->he_caps.dot11_he_cap.rx_1024_qam_lt_242_tone_ru = 0;
15148 	mac_ctx->mlme_cfg->he_caps.dot11_he_cap.rx_full_bw_su_he_mu_compress_sigb = 0;
15149 	mac_ctx->mlme_cfg->he_caps.dot11_he_cap.rx_full_bw_su_he_mu_non_cmpr_sigb = 0;
15150 	mac_ctx->mlme_cfg->he_caps.dot11_he_cap.su_beamformer = 0;
15151 	mac_ctx->mlme_cfg->he_caps.dot11_he_cap.multi_tid_aggr_rx_supp = 0;
15152 	mac_ctx->mlme_cfg->he_caps.dot11_he_cap.multi_tid_aggr_tx_supp = 0;
15153 	mac_ctx->mlme_cfg->he_caps.dot11_he_cap.he_dynamic_smps = 0;
15154 	mac_ctx->mlme_cfg->he_caps.dot11_he_cap.punctured_sounding_supp = 0;
15155 	mac_ctx->mlme_cfg->he_caps.dot11_he_cap.ht_vht_trg_frm_rx_supp = 0;
15156 	mac_ctx->mlme_cfg->he_caps.dot11_he_cap.su_feedback_tone16 = 0;
15157 	mac_ctx->mlme_cfg->he_caps.dot11_he_cap.mu_feedback_tone16 = 0;
15158 	mac_ctx->mlme_cfg->he_caps.dot11_he_cap.codebook_su = 0;
15159 	mac_ctx->mlme_cfg->he_caps.dot11_he_cap.codebook_mu = 0;
15160 	mac_ctx->mlme_cfg->he_caps.dot11_he_cap.ul_2x996_tone_ru_supp = 0;
15161 	mac_ctx->mlme_cfg->he_caps.dot11_he_cap.beamforming_feedback = 0;
15162 	mac_ctx->mlme_cfg->he_caps.dot11_he_cap.he_er_su_ppdu = 0;
15163 	mac_ctx->mlme_cfg->he_caps.dot11_he_cap.dl_mu_mimo_part_bw = 0;
15164 	mac_ctx->mlme_cfg->he_caps.dot11_he_cap.rx_pream_puncturing = 0;
15165 	mac_ctx->mlme_cfg->he_caps.dot11_he_cap.chan_width_0 = 0;
15166 	mac_ctx->mlme_cfg->he_caps.dot11_he_cap.chan_width_1 = 1;
15167 	mac_ctx->mlme_cfg->he_caps.dot11_he_cap.chan_width_2 = 0;
15168 	mac_ctx->mlme_cfg->he_caps.dot11_he_cap.chan_width_3 = 0;
15169 	mac_ctx->mlme_cfg->he_caps.dot11_he_cap.chan_width_4 = 0;
15170 	mac_ctx->mlme_cfg->he_caps.dot11_he_cap.chan_width_5 = 0;
15171 	mac_ctx->mlme_cfg->he_caps.dot11_he_cap.chan_width_6 = 0;
15172 	csr_update_session_he_cap(mac_ctx, session);
15173 
15174 	qdf_mem_copy(&mac_ctx->he_cap_2g,
15175 		     &mac_ctx->mlme_cfg->he_caps.dot11_he_cap,
15176 		     sizeof(tDot11fIEhe_cap));
15177 
15178 	mac_ctx->he_cap_2g.chan_width_1 = 0;
15179 	ucfg_mlme_set_channel_bonding_24ghz(mac_ctx->psoc, 0);
15180 	qdf_mem_copy(&mac_ctx->he_cap_5g,
15181 		     &mac_ctx->mlme_cfg->he_caps.dot11_he_cap,
15182 		     sizeof(tDot11fIEhe_cap));
15183 	status = ucfg_mlme_set_enable_bcast_probe_rsp(mac_ctx->psoc, false);
15184 	if (QDF_IS_STATUS_ERROR(status))
15185 		sme_err("Failed not set enable bcast probe resp info, %d",
15186 			status);
15187 	status = sme_send_unit_test_cmd(vdev_id, 77, 2, prevent_pm);
15188 	if (QDF_STATUS_SUCCESS != status)
15189 		sme_err("prevent pm cmd send failed");
15190 	status = wma_cli_set_command(vdev_id,
15191 				     wmi_vdev_param_enable_bcast_probe_response,
15192 				     0, VDEV_CMD);
15193 	if (QDF_IS_STATUS_ERROR(status))
15194 		sme_err("Failed to set enable bcast probe resp in FW, %d",
15195 			status);
15196 
15197 	mac_ctx->mlme_cfg->sta.usr_disabled_roaming = true;
15198 	mac_ctx->mlme_cfg->sta.bss_max_idle_period = 0;
15199 }
15200 
sme_reset_he_caps(mac_handle_t mac_handle,uint8_t vdev_id)15201 void sme_reset_he_caps(mac_handle_t mac_handle, uint8_t vdev_id)
15202 {
15203 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
15204 	struct csr_roam_session *session;
15205 	QDF_STATUS status;
15206 	uint32_t prevent_pm[] = {29, 0};
15207 
15208 	session = CSR_GET_SESSION(mac_ctx, vdev_id);
15209 
15210 	if (!session) {
15211 		sme_err("No session for id %d", vdev_id);
15212 		return;
15213 	}
15214 	sme_debug("reset HE caps");
15215 	mac_ctx->mlme_cfg->he_caps.dot11_he_cap =
15216 		mac_ctx->mlme_cfg->he_caps.he_cap_orig;
15217 	csr_update_session_he_cap(mac_ctx, session);
15218 
15219 	qdf_mem_copy(&mac_ctx->he_cap_2g,
15220 		     &mac_ctx->he_cap_2g_orig,
15221 		     sizeof(tDot11fIEhe_cap));
15222 	qdf_mem_copy(&mac_ctx->he_cap_5g,
15223 		     &mac_ctx->he_cap_5g_orig,
15224 		     sizeof(tDot11fIEhe_cap));
15225 	ucfg_mlme_set_channel_bonding_24ghz(mac_ctx->psoc, 1);
15226 	wlan_cm_set_check_6ghz_security(mac_ctx->psoc, true);
15227 	status = sme_send_unit_test_cmd(vdev_id, 77, 2, prevent_pm);
15228 
15229 	if (QDF_STATUS_SUCCESS != status)
15230 		sme_err("prevent PM reset cmd send failed");
15231 
15232 	mac_ctx->mlme_cfg->twt_cfg.disable_btwt_usr_cfg = false;
15233 	status = ucfg_mlme_set_enable_bcast_probe_rsp(mac_ctx->psoc, true);
15234 	if (QDF_IS_STATUS_ERROR(status))
15235 		sme_err("Failed not set enable bcast probe resp info, %d",
15236 			status);
15237 
15238 	status = wma_cli_set_command(vdev_id,
15239 				     wmi_vdev_param_enable_bcast_probe_response,
15240 				     1, VDEV_CMD);
15241 	if (QDF_IS_STATUS_ERROR(status))
15242 		sme_err("Failed to set enable bcast probe resp in FW, %d",
15243 			status);
15244 	mac_ctx->is_usr_cfg_pmf_wep = PMF_CORRECT_KEY;
15245 	mac_ctx->mlme_cfg->sta.bss_max_idle_period =
15246 			mac_ctx->mlme_cfg->sta.sta_keep_alive_period;
15247 
15248 	if (mac_ctx->usr_cfg_disable_rsp_tx)
15249 		sme_set_cfg_disable_tx(mac_handle, vdev_id, 0);
15250 	mac_ctx->is_usr_cfg_amsdu_enabled = true;
15251 	status = wlan_scan_cfg_set_scan_mode_6g(mac_ctx->psoc,
15252 						SCAN_MODE_6G_ALL_CHANNEL);
15253 	if (QDF_IS_STATUS_ERROR(status))
15254 		sme_err("Failed to set scan mode for 6 GHz, %d", status);
15255 }
15256 #endif
15257 
15258 #ifdef WLAN_FEATURE_11BE
sme_set_mlo_max_links(mac_handle_t mac_handle,uint8_t vdev_id,uint8_t val)15259 void sme_set_mlo_max_links(mac_handle_t mac_handle, uint8_t vdev_id,
15260 			   uint8_t val)
15261 {
15262 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
15263 	struct csr_roam_session *session;
15264 
15265 	session = CSR_GET_SESSION(mac_ctx, vdev_id);
15266 
15267 	if (!session) {
15268 		sme_err("No session for id %d", vdev_id);
15269 		return;
15270 	}
15271 	wlan_mlme_set_sta_mlo_conn_max_num(mac_ctx->psoc, val);
15272 	wlan_mlme_set_user_set_link_num(mac_ctx->psoc, val);
15273 }
15274 
sme_set_mlo_max_simultaneous_links(mac_handle_t mac_handle,uint8_t vdev_id,uint8_t val)15275 void sme_set_mlo_max_simultaneous_links(mac_handle_t mac_handle,
15276 					uint8_t vdev_id, uint8_t val)
15277 {
15278 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
15279 	struct csr_roam_session *session;
15280 
15281 	session = CSR_GET_SESSION(mac_ctx, vdev_id);
15282 	if (!session) {
15283 		sme_err("No session for id %d", vdev_id);
15284 		return;
15285 	}
15286 	wlan_mlme_set_sta_mlo_simultaneous_links(mac_ctx->psoc, val);
15287 }
15288 
sme_set_mlo_assoc_link_band(mac_handle_t mac_handle,uint8_t vdev_id,uint8_t val)15289 void sme_set_mlo_assoc_link_band(mac_handle_t mac_handle, uint8_t vdev_id,
15290 				 uint8_t val)
15291 {
15292 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
15293 	struct csr_roam_session *session;
15294 
15295 	session = CSR_GET_SESSION(mac_ctx, vdev_id);
15296 
15297 	if (!session) {
15298 		sme_err("No session for id %d", vdev_id);
15299 		return;
15300 	}
15301 	wlan_mlme_set_sta_mlo_conn_band_bmp(mac_ctx->psoc, val);
15302 }
15303 
sme_set_eht_testbed_def(mac_handle_t mac_handle,uint8_t vdev_id)15304 void sme_set_eht_testbed_def(mac_handle_t mac_handle, uint8_t vdev_id)
15305 {
15306 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
15307 	struct csr_roam_session *session;
15308 	tDot11fIEeht_cap *mlme_eht_cap;
15309 
15310 	session = CSR_GET_SESSION(mac_ctx, vdev_id);
15311 
15312 	if (!session) {
15313 		sme_err("No session for id %d", vdev_id);
15314 		return;
15315 	}
15316 	mlme_eht_cap = &mac_ctx->mlme_cfg->eht_caps.dot11_eht_cap;
15317 	sme_debug("set EHT caps testbed defaults");
15318 	mlme_eht_cap->epcs_pri_access = 0;
15319 	mlme_eht_cap->eht_om_ctl = 0;
15320 	mlme_eht_cap->triggered_txop_sharing_mode1 = 0;
15321 	mlme_eht_cap->restricted_twt = 0;
15322 	mlme_eht_cap->support_320mhz_6ghz = 0;
15323 	mlme_eht_cap->partial_bw_mu_mimo = 0;
15324 	mlme_eht_cap->su_beamformer = 0;
15325 	mlme_eht_cap->su_beamformee = 1;
15326 	mlme_eht_cap->bfee_ss_le_80mhz = 3;
15327 	mlme_eht_cap->bfee_ss_160mhz = 0;
15328 	mlme_eht_cap->bfee_ss_320mhz = 0;
15329 	mlme_eht_cap->num_sounding_dim_le_80mhz = 0;
15330 	mlme_eht_cap->num_sounding_dim_160mhz = 0;
15331 	mlme_eht_cap->num_sounding_dim_320mhz = 0;
15332 	mlme_eht_cap->mu_bformer_le_80mhz = 0;
15333 	mlme_eht_cap->mu_bformer_160mhz = 0;
15334 	mlme_eht_cap->mu_bformer_320mhz = 0;
15335 	mlme_eht_cap->partial_bw_dl_mu_mimo = 0;
15336 	mlme_eht_cap->ru_242tone_wt_20mhz = 0;
15337 	mlme_eht_cap->psr_based_sr = 0;
15338 	mlme_eht_cap->triggered_cqi_feedback = 0;
15339 	mlme_eht_cap->trig_mu_bforming_partial_bw_feedback = 0;
15340 	mlme_eht_cap->trig_su_bforming_feedback = 0;
15341 	mlme_eht_cap->cb_sz_7_5_su_feedback = 0;
15342 	mlme_eht_cap->cb_sz_4_2_su_feedback = 0;
15343 	mlme_eht_cap->ng_16_mu_feedback = 0;
15344 	mlme_eht_cap->ng_16_su_feedback = 0;
15345 	mlme_eht_cap->ndp_4x_eht_ltf_3dot2_us_gi = 0;
15346 	mlme_eht_cap->common_nominal_pkt_padding = 3;
15347 	mlme_eht_cap->ppet_present = 0;
15348 	mlme_eht_cap->rx_1024_4096_qam_lt_242_tone_ru = 0;
15349 	mlme_eht_cap->tx_1024_4096_qam_lt_242_tone_ru = 0;
15350 	mlme_eht_cap->non_trig_cqi_feedback = 0;
15351 	mlme_eht_cap->max_nc = 0;
15352 	mlme_eht_cap->rx_4k_qam_in_wider_bw_dl_ofdma = 0;
15353 	mlme_eht_cap->rx_1k_qam_in_wider_bw_dl_ofdma = 0;
15354 	mlme_eht_cap->tb_sounding_feedback_rl = 0;
15355 	mlme_eht_cap->op_sta_rx_ndp_wider_bw_20mhz = 0;
15356 	mlme_eht_cap->eht_dup_6ghz = 0;
15357 	mlme_eht_cap->mcs_15 = 0;
15358 	mlme_eht_cap->max_num_eht_ltf = 0;
15359 	mlme_eht_cap->eht_mu_ppdu_4x_ltf_0_8_us_gi = 0;
15360 	mlme_eht_cap->power_boost_factor = 0;
15361 	mlme_eht_cap->bw_20_rx_max_nss_for_mcs_0_to_7 = 1;
15362 	mlme_eht_cap->bw_20_tx_max_nss_for_mcs_0_to_7 = 1;
15363 	mlme_eht_cap->bw_20_rx_max_nss_for_mcs_8_and_9 = 1;
15364 	mlme_eht_cap->bw_20_tx_max_nss_for_mcs_8_and_9 = 1;
15365 	mlme_eht_cap->bw_20_rx_max_nss_for_mcs_10_and_11 = 0;
15366 	mlme_eht_cap->bw_20_tx_max_nss_for_mcs_10_and_11 = 0;
15367 	mlme_eht_cap->bw_20_rx_max_nss_for_mcs_12_and_13 = 0;
15368 	mlme_eht_cap->bw_20_tx_max_nss_for_mcs_12_and_13 = 0;
15369 	mlme_eht_cap->bw_le_80_rx_max_nss_for_mcs_0_to_9 = 1;
15370 	mlme_eht_cap->bw_le_80_tx_max_nss_for_mcs_0_to_9 = 1;
15371 	mlme_eht_cap->bw_le_80_rx_max_nss_for_mcs_10_and_11 = 0;
15372 	mlme_eht_cap->bw_le_80_tx_max_nss_for_mcs_10_and_11 = 0;
15373 	mlme_eht_cap->bw_le_80_rx_max_nss_for_mcs_12_and_13 = 0;
15374 	mlme_eht_cap->bw_le_80_tx_max_nss_for_mcs_12_and_13 = 0;
15375 	mlme_eht_cap->bw_160_rx_max_nss_for_mcs_0_to_9 = 1;
15376 	mlme_eht_cap->bw_160_tx_max_nss_for_mcs_0_to_9 = 1;
15377 	mlme_eht_cap->bw_160_rx_max_nss_for_mcs_10_and_11 = 0;
15378 	mlme_eht_cap->bw_160_tx_max_nss_for_mcs_10_and_11 = 0;
15379 	mlme_eht_cap->bw_160_rx_max_nss_for_mcs_12_and_13 = 0;
15380 	mlme_eht_cap->bw_160_tx_max_nss_for_mcs_12_and_13 = 0;
15381 	mlme_eht_cap->bw_320_rx_max_nss_for_mcs_0_to_9 = 1;
15382 	mlme_eht_cap->bw_320_tx_max_nss_for_mcs_0_to_9 = 1;
15383 	mlme_eht_cap->bw_320_rx_max_nss_for_mcs_10_and_11 = 0;
15384 	mlme_eht_cap->bw_320_tx_max_nss_for_mcs_10_and_11 = 0;
15385 	mlme_eht_cap->bw_320_rx_max_nss_for_mcs_12_and_13 = 0;
15386 	mlme_eht_cap->bw_320_tx_max_nss_for_mcs_12_and_13 = 0;
15387 
15388 	csr_update_session_eht_cap(mac_ctx, session);
15389 
15390 	qdf_mem_copy(&mac_ctx->eht_cap_2g, mlme_eht_cap,
15391 		     sizeof(tDot11fIEeht_cap));
15392 
15393 	mac_ctx->eht_cap_2g.bw_le_80_rx_max_nss_for_mcs_0_to_9 = 0;
15394 	mac_ctx->eht_cap_2g.bw_le_80_tx_max_nss_for_mcs_0_to_9 = 0;
15395 
15396 	qdf_mem_copy(&mac_ctx->eht_cap_5g, mlme_eht_cap,
15397 		     sizeof(tDot11fIEeht_cap));
15398 
15399 	mac_ctx->usr_eht_testbed_cfg = true;
15400 	mac_ctx->roam.configParam.channelBondingMode24GHz = 0;
15401 	wlan_mlme_set_sta_mlo_conn_max_num(mac_ctx->psoc, 1);
15402 	ucfg_mlme_set_bss_color_collision_det_sta(mac_ctx->psoc, false);
15403 }
15404 
sme_set_per_link_ba_mode(mac_handle_t mac_handle,uint8_t val)15405 void sme_set_per_link_ba_mode(mac_handle_t mac_handle, uint8_t val)
15406 {
15407 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
15408 	enum QDF_OPMODE op_mode;
15409 	uint8_t vdev_id;
15410 	int ret_val = 0;
15411 
15412 	for (vdev_id = 0; vdev_id < WLAN_MAX_VDEVS; vdev_id++) {
15413 		op_mode = wlan_get_opmode_from_vdev_id(mac->pdev, vdev_id);
15414 		if (op_mode == QDF_STA_MODE) {
15415 			ret_val = wma_cli_set_command(
15416 						vdev_id,
15417 						wmi_vdev_param_set_ba_mode,
15418 						val, VDEV_CMD);
15419 
15420 		if (QDF_IS_STATUS_ERROR(ret_val))
15421 			sme_err("BA mode set failed for vdev: %d, ret %d",
15422 				vdev_id, ret_val);
15423 		else
15424 			sme_debug("vdev: %d ba mode: %d param id %d",
15425 				  vdev_id, val, wmi_vdev_param_set_ba_mode);
15426 		}
15427 	}
15428 }
15429 
15430 static inline
sme_set_mcs_15_tx_rx_disable(uint8_t vdev_id)15431 void sme_set_mcs_15_tx_rx_disable(uint8_t vdev_id)
15432 {
15433 	uint32_t tx_disable[2] = {67, 0};
15434 	uint32_t rx_disable[3] = {125, 0, 1};
15435 	QDF_STATUS status;
15436 
15437 	sme_debug("Send MCS 15 rx/tx disable to FW");
15438 
15439 	status = sme_send_unit_test_cmd(vdev_id, 10, 2, tx_disable);
15440 	if (status)
15441 		sme_err("Failed to send MCS 15 tx disable");
15442 
15443 	status = sme_send_unit_test_cmd(vdev_id, 67, 3, rx_disable);
15444 	if (status)
15445 		sme_err("Failed to send MCS 15 rx disable");
15446 }
15447 
sme_reset_eht_caps(mac_handle_t mac_handle,uint8_t vdev_id)15448 void sme_reset_eht_caps(mac_handle_t mac_handle, uint8_t vdev_id)
15449 {
15450 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
15451 	struct csr_roam_session *session;
15452 	bool val;
15453 	QDF_STATUS status;
15454 	uint8_t ba_mode_auto = 0;
15455 
15456 	session = CSR_GET_SESSION(mac_ctx, vdev_id);
15457 
15458 	if (!session) {
15459 		sme_err("No session for id %d", vdev_id);
15460 		return;
15461 	}
15462 	sme_debug("reset EHT caps");
15463 	mac_ctx->mlme_cfg->eht_caps.dot11_eht_cap =
15464 		mac_ctx->mlme_cfg->eht_caps.eht_cap_orig;
15465 	csr_update_session_eht_cap(mac_ctx, session);
15466 
15467 	qdf_mem_copy(&mac_ctx->eht_cap_2g,
15468 		     &mac_ctx->eht_cap_2g_orig,
15469 		     sizeof(tDot11fIEeht_cap));
15470 
15471 	qdf_mem_copy(&mac_ctx->eht_cap_5g,
15472 		     &mac_ctx->eht_cap_5g_orig,
15473 		     sizeof(tDot11fIEeht_cap));
15474 	mac_ctx->usr_eht_testbed_cfg = false;
15475 	mac_ctx->roam.configParam.channelBondingMode24GHz = 1;
15476 	wlan_mlme_set_sta_mlo_conn_band_bmp(mac_ctx->psoc, 0x77);
15477 	wlan_mlme_set_sta_mlo_conn_max_num(mac_ctx->psoc, 2);
15478 	status = ucfg_mlme_get_bss_color_collision_det_support(mac_ctx->psoc,
15479 							       &val);
15480 	if (QDF_IS_STATUS_SUCCESS(status))
15481 		ucfg_mlme_set_bss_color_collision_det_sta(mac_ctx->psoc, val);
15482 	sme_set_per_link_ba_mode(mac_handle, ba_mode_auto);
15483 	sme_set_mcs_15_tx_rx_disable(vdev_id);
15484 	wlan_mlme_set_btm_abridge_flag(mac_ctx->psoc, false);
15485 	wlan_mlme_set_eht_mld_id(mac_ctx->psoc, 0);
15486 }
15487 
sme_update_eht_cap_nss(mac_handle_t mac_handle,uint8_t vdev_id,uint8_t nss)15488 void sme_update_eht_cap_nss(mac_handle_t mac_handle, uint8_t vdev_id,
15489 			    uint8_t nss)
15490 {
15491 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
15492 	struct csr_roam_session *session;
15493 	tDot11fIEeht_cap *mlme_eht_cap;
15494 
15495 	session = CSR_GET_SESSION(mac_ctx, vdev_id);
15496 
15497 	if (!session) {
15498 		sme_err("No session for id %d", vdev_id);
15499 		return;
15500 	}
15501 	mlme_eht_cap = &mac_ctx->mlme_cfg->eht_caps.dot11_eht_cap;
15502 	if (!nss || (nss > 2)) {
15503 		sme_err("invalid Nss value nss %d", nss);
15504 		return;
15505 	}
15506 	sme_debug("Nss value %d", nss);
15507 	mlme_eht_cap->bw_20_rx_max_nss_for_mcs_0_to_7 = nss;
15508 	mlme_eht_cap->bw_20_tx_max_nss_for_mcs_0_to_7 = nss;
15509 	mlme_eht_cap->bw_20_rx_max_nss_for_mcs_8_and_9 = nss;
15510 	mlme_eht_cap->bw_20_tx_max_nss_for_mcs_8_and_9 = nss;
15511 	if (mlme_eht_cap->bw_20_rx_max_nss_for_mcs_10_and_11) {
15512 		mlme_eht_cap->bw_20_rx_max_nss_for_mcs_10_and_11 = nss;
15513 		mlme_eht_cap->bw_20_tx_max_nss_for_mcs_10_and_11 = nss;
15514 	}
15515 	if (mlme_eht_cap->bw_20_rx_max_nss_for_mcs_12_and_13) {
15516 		mlme_eht_cap->bw_20_rx_max_nss_for_mcs_12_and_13 = nss;
15517 		mlme_eht_cap->bw_20_tx_max_nss_for_mcs_12_and_13 = nss;
15518 	}
15519 	mlme_eht_cap->bw_le_80_rx_max_nss_for_mcs_0_to_9 = nss;
15520 	mlme_eht_cap->bw_le_80_tx_max_nss_for_mcs_0_to_9 = nss;
15521 	if (mlme_eht_cap->bw_le_80_rx_max_nss_for_mcs_10_and_11) {
15522 		mlme_eht_cap->bw_le_80_rx_max_nss_for_mcs_10_and_11 = nss;
15523 		mlme_eht_cap->bw_le_80_tx_max_nss_for_mcs_10_and_11 = nss;
15524 	}
15525 	if (mlme_eht_cap->bw_le_80_rx_max_nss_for_mcs_12_and_13) {
15526 		mlme_eht_cap->bw_le_80_rx_max_nss_for_mcs_12_and_13 = nss;
15527 		mlme_eht_cap->bw_le_80_tx_max_nss_for_mcs_12_and_13 = nss;
15528 	}
15529 	mlme_eht_cap->bw_160_rx_max_nss_for_mcs_0_to_9 = nss;
15530 	mlme_eht_cap->bw_160_tx_max_nss_for_mcs_0_to_9 = nss;
15531 	if (mlme_eht_cap->bw_160_rx_max_nss_for_mcs_10_and_11) {
15532 		mlme_eht_cap->bw_160_rx_max_nss_for_mcs_10_and_11 = nss;
15533 		mlme_eht_cap->bw_160_tx_max_nss_for_mcs_10_and_11 = nss;
15534 	}
15535 	if (mlme_eht_cap->bw_160_rx_max_nss_for_mcs_12_and_13) {
15536 		mlme_eht_cap->bw_160_rx_max_nss_for_mcs_12_and_13 = nss;
15537 		mlme_eht_cap->bw_160_tx_max_nss_for_mcs_12_and_13 = nss;
15538 	}
15539 	mlme_eht_cap->bw_320_rx_max_nss_for_mcs_0_to_9 = nss;
15540 	mlme_eht_cap->bw_320_tx_max_nss_for_mcs_0_to_9 = nss;
15541 
15542 	if (mlme_eht_cap->bw_320_rx_max_nss_for_mcs_10_and_11) {
15543 		mlme_eht_cap->bw_320_rx_max_nss_for_mcs_10_and_11 = nss;
15544 		mlme_eht_cap->bw_320_tx_max_nss_for_mcs_10_and_11 = nss;
15545 	}
15546 	if (mlme_eht_cap->bw_320_rx_max_nss_for_mcs_12_and_13) {
15547 		mlme_eht_cap->bw_320_rx_max_nss_for_mcs_12_and_13 = nss;
15548 		mlme_eht_cap->bw_320_tx_max_nss_for_mcs_12_and_13 = nss;
15549 	}
15550 
15551 	csr_update_session_eht_cap(mac_ctx, session);
15552 
15553 	qdf_mem_copy(&mac_ctx->eht_cap_2g, mlme_eht_cap,
15554 		     sizeof(tDot11fIEeht_cap));
15555 
15556 	qdf_mem_copy(&mac_ctx->eht_cap_5g, mlme_eht_cap,
15557 		     sizeof(tDot11fIEeht_cap));
15558 }
15559 
sme_update_eht_cap_mcs(mac_handle_t mac_handle,uint8_t vdev_id,uint8_t mcs)15560 void sme_update_eht_cap_mcs(mac_handle_t mac_handle, uint8_t vdev_id,
15561 			    uint8_t mcs)
15562 {
15563 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
15564 	struct csr_roam_session *session;
15565 	tDot11fIEeht_cap *mlme_eht_cap;
15566 	uint8_t nss;
15567 
15568 	session = CSR_GET_SESSION(mac_ctx, vdev_id);
15569 
15570 	if (!session) {
15571 		sme_err("No session for id %d", vdev_id);
15572 		return;
15573 	}
15574 	mlme_eht_cap = &mac_ctx->mlme_cfg->eht_caps.dot11_eht_cap;
15575 	nss = mlme_eht_cap->bw_20_rx_max_nss_for_mcs_0_to_7;
15576 
15577 	if (!nss)
15578 		nss = mlme_eht_cap->bw_le_80_rx_max_nss_for_mcs_0_to_9;
15579 	if (!nss) {
15580 		sme_err("No valid Nss");
15581 		return;
15582 	}
15583 	sme_debug("nss %d, mcs %d", nss, mcs);
15584 
15585 	mlme_eht_cap->bw_20_rx_max_nss_for_mcs_10_and_11 = 0;
15586 	mlme_eht_cap->bw_20_tx_max_nss_for_mcs_10_and_11 = 0;
15587 	mlme_eht_cap->bw_20_rx_max_nss_for_mcs_12_and_13 = 0;
15588 	mlme_eht_cap->bw_20_tx_max_nss_for_mcs_12_and_13 = 0;
15589 	mlme_eht_cap->bw_le_80_rx_max_nss_for_mcs_10_and_11 = 0;
15590 	mlme_eht_cap->bw_le_80_tx_max_nss_for_mcs_10_and_11 = 0;
15591 	mlme_eht_cap->bw_le_80_rx_max_nss_for_mcs_12_and_13 = 0;
15592 	mlme_eht_cap->bw_le_80_tx_max_nss_for_mcs_12_and_13 = 0;
15593 	mlme_eht_cap->bw_160_rx_max_nss_for_mcs_10_and_11 = 0;
15594 	mlme_eht_cap->bw_160_tx_max_nss_for_mcs_10_and_11 = 0;
15595 	mlme_eht_cap->bw_160_rx_max_nss_for_mcs_12_and_13 = 0;
15596 	mlme_eht_cap->bw_160_tx_max_nss_for_mcs_12_and_13 = 0;
15597 	mlme_eht_cap->bw_320_rx_max_nss_for_mcs_10_and_11 = 0;
15598 	mlme_eht_cap->bw_320_tx_max_nss_for_mcs_10_and_11 = 0;
15599 	mlme_eht_cap->bw_320_rx_max_nss_for_mcs_12_and_13 = 0;
15600 	mlme_eht_cap->bw_320_tx_max_nss_for_mcs_12_and_13 = 0;
15601 
15602 	if (mcs > 1) { /* 0 - 11*/
15603 		mlme_eht_cap->bw_20_rx_max_nss_for_mcs_10_and_11 = nss;
15604 		mlme_eht_cap->bw_20_tx_max_nss_for_mcs_10_and_11 = nss;
15605 		mlme_eht_cap->bw_le_80_rx_max_nss_for_mcs_10_and_11 = nss;
15606 		mlme_eht_cap->bw_le_80_tx_max_nss_for_mcs_10_and_11 = nss;
15607 		mlme_eht_cap->bw_160_rx_max_nss_for_mcs_10_and_11 = nss;
15608 		mlme_eht_cap->bw_160_tx_max_nss_for_mcs_10_and_11 = nss;
15609 		mlme_eht_cap->bw_320_rx_max_nss_for_mcs_10_and_11 = nss;
15610 		mlme_eht_cap->bw_320_tx_max_nss_for_mcs_10_and_11 = nss;
15611 		mlme_eht_cap->rx_1024_4096_qam_lt_242_tone_ru = 1;
15612 		mlme_eht_cap->tx_1024_4096_qam_lt_242_tone_ru = 1;
15613 	}
15614 
15615 	if (mcs == 3) { /* 0 - 13*/
15616 		mlme_eht_cap->bw_20_rx_max_nss_for_mcs_12_and_13 = nss;
15617 		mlme_eht_cap->bw_20_tx_max_nss_for_mcs_12_and_13 = nss;
15618 		mlme_eht_cap->bw_le_80_rx_max_nss_for_mcs_12_and_13 = nss;
15619 		mlme_eht_cap->bw_le_80_tx_max_nss_for_mcs_12_and_13 = nss;
15620 		mlme_eht_cap->bw_160_rx_max_nss_for_mcs_12_and_13 = nss;
15621 		mlme_eht_cap->bw_160_tx_max_nss_for_mcs_12_and_13 = nss;
15622 		mlme_eht_cap->bw_320_rx_max_nss_for_mcs_12_and_13 = nss;
15623 		mlme_eht_cap->bw_320_tx_max_nss_for_mcs_12_and_13 = nss;
15624 	}
15625 	csr_update_session_eht_cap(mac_ctx, session);
15626 
15627 	qdf_mem_copy(&mac_ctx->eht_cap_2g, mlme_eht_cap,
15628 		     sizeof(tDot11fIEeht_cap));
15629 
15630 	qdf_mem_copy(&mac_ctx->eht_cap_5g, mlme_eht_cap,
15631 		     sizeof(tDot11fIEeht_cap));
15632 }
15633 
sme_activate_mlo_links(mac_handle_t mac_handle,uint8_t session_id,uint8_t num_links,struct qdf_mac_addr active_link_addr[2])15634 void sme_activate_mlo_links(mac_handle_t mac_handle, uint8_t session_id,
15635 			    uint8_t num_links,
15636 			    struct qdf_mac_addr active_link_addr[2])
15637 {
15638 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
15639 	struct csr_roam_session *session;
15640 
15641 	session = CSR_GET_SESSION(mac_ctx, session_id);
15642 
15643 	if (!session) {
15644 		sme_err("No session for id %d", session_id);
15645 		return;
15646 	}
15647 
15648 	if (ml_is_nlink_service_supported(mac_ctx->psoc)) {
15649 		policy_mgr_activate_mlo_links_nlink(mac_ctx->psoc, session_id,
15650 						    num_links,
15651 						    active_link_addr);
15652 	} else {
15653 		policy_mgr_activate_mlo_links(mac_ctx->psoc, session_id,
15654 					      num_links, active_link_addr);
15655 	}
15656 }
15657 
sme_update_eht_caps(mac_handle_t mac_handle,uint8_t session_id,uint8_t cfg_val,enum sme_eht_tx_bfee_cap_type cap_type,enum QDF_OPMODE op_mode)15658 int sme_update_eht_caps(mac_handle_t mac_handle, uint8_t session_id,
15659 			uint8_t cfg_val, enum sme_eht_tx_bfee_cap_type cap_type,
15660 			enum QDF_OPMODE op_mode)
15661 {
15662 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
15663 	struct csr_roam_session *session;
15664 	tDot11fIEeht_cap *cfg_eht_cap;
15665 
15666 	session = CSR_GET_SESSION(mac_ctx, session_id);
15667 
15668 	if (!session) {
15669 		sme_err("No session for id %d", session_id);
15670 		return -EINVAL;
15671 	}
15672 	cfg_eht_cap = &mac_ctx->mlme_cfg->eht_caps.dot11_eht_cap;
15673 
15674 	switch (cap_type) {
15675 	case EHT_TX_BFEE_ENABLE:
15676 		cfg_eht_cap->su_beamformee = cfg_val;
15677 		break;
15678 	case EHT_TX_BFEE_SS_80MHZ:
15679 		cfg_eht_cap->bfee_ss_le_80mhz = cfg_val;
15680 		break;
15681 	case EHT_TX_BFEE_SS_160MHZ:
15682 		cfg_eht_cap->bfee_ss_160mhz = cfg_val;
15683 		break;
15684 	case EHT_TX_BFEE_SS_320MHZ:
15685 		cfg_eht_cap->bfee_ss_320mhz = cfg_val;
15686 		break;
15687 	case EHT_TX_BFEE_SOUNDING_FEEDBACK_RATELIMIT:
15688 		cfg_eht_cap->tb_sounding_feedback_rl = cfg_val;
15689 		break;
15690 	default:
15691 		sme_debug("default: Unhandled cap type %d", cap_type);
15692 		return -EINVAL;
15693 	}
15694 
15695 	sme_debug("EHT cap: cap type %d, cfg val %d", cap_type, cfg_val);
15696 	csr_update_session_eht_cap(mac_ctx, session);
15697 
15698 	qdf_mem_copy(&mac_ctx->eht_cap_2g, cfg_eht_cap,
15699 		     sizeof(tDot11fIEeht_cap));
15700 	qdf_mem_copy(&mac_ctx->eht_cap_5g, cfg_eht_cap,
15701 		     sizeof(tDot11fIEeht_cap));
15702 	sme_set_vdev_ies_per_band(mac_handle, session_id, op_mode);
15703 
15704 	return 0;
15705 }
15706 
15707 int
sme_send_vdev_pause_for_bcn_period(mac_handle_t mac_handle,uint8_t session_id,uint8_t cfg_val)15708 sme_send_vdev_pause_for_bcn_period(mac_handle_t mac_handle, uint8_t session_id,
15709 				   uint8_t cfg_val)
15710 {
15711 	struct sme_vdev_pause *vdev_pause;
15712 	struct scheduler_msg msg = {0};
15713 	QDF_STATUS status;
15714 
15715 	vdev_pause = qdf_mem_malloc(sizeof(*vdev_pause));
15716 	if (!vdev_pause)
15717 		return -EIO;
15718 
15719 	vdev_pause->session_id = session_id;
15720 	vdev_pause->vdev_pause_duration = cfg_val;
15721 	qdf_mem_zero(&msg, sizeof(msg));
15722 	msg.type = eWNI_SME_VDEV_PAUSE_IND;
15723 	msg.reserved = 0;
15724 	msg.bodyptr = vdev_pause;
15725 	status = scheduler_post_message(QDF_MODULE_ID_SME,
15726 					QDF_MODULE_ID_PE,
15727 					QDF_MODULE_ID_PE, &msg);
15728 	if (status != QDF_STATUS_SUCCESS) {
15729 		sme_err("Not able to post vdev pause indication");
15730 		qdf_mem_free(vdev_pause);
15731 		return -EIO;
15732 	}
15733 
15734 	return 0;
15735 }
15736 #endif
15737 
sme_set_nss_capability(mac_handle_t mac_handle,uint8_t vdev_id,uint8_t nss,enum QDF_OPMODE op_mode)15738 void sme_set_nss_capability(mac_handle_t mac_handle, uint8_t vdev_id,
15739 			    uint8_t nss, enum QDF_OPMODE op_mode)
15740 {
15741 	sme_debug("Nss cap update, NSS %d", nss);
15742 
15743 	sme_update_he_cap_nss(mac_handle, vdev_id, nss);
15744 	sme_update_eht_cap_nss(mac_handle, vdev_id, nss);
15745 	sme_set_vdev_ies_per_band(mac_handle, vdev_id, op_mode);
15746 }
15747 
sme_get_mcs_idx(uint16_t raw_rate,enum tx_rate_info rate_flags,bool is_he_mcs_12_13_supported,uint8_t * nss,uint8_t * dcm,enum txrate_gi * guard_interval,enum tx_rate_info * mcs_rate_flags)15748 uint8_t sme_get_mcs_idx(uint16_t raw_rate, enum tx_rate_info rate_flags,
15749 			bool is_he_mcs_12_13_supported,
15750 			uint8_t *nss, uint8_t *dcm,
15751 			enum txrate_gi *guard_interval,
15752 			enum tx_rate_info *mcs_rate_flags)
15753 {
15754 	return wma_get_mcs_idx(raw_rate, rate_flags, is_he_mcs_12_13_supported,
15755 			       nss, dcm, guard_interval, mcs_rate_flags);
15756 }
15757 
15758 #ifdef WLAN_UNIT_TEST
15759 #ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
sme_get_sta_cxn_info(mac_handle_t mac_handle,uint32_t session_id,char * buf,uint32_t buf_sz)15760 QDF_STATUS sme_get_sta_cxn_info(mac_handle_t mac_handle, uint32_t session_id,
15761 				char *buf, uint32_t buf_sz)
15762 {
15763 	QDF_STATUS status;
15764 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
15765 
15766 	status = sme_acquire_global_lock(&mac_ctx->sme);
15767 	csr_cm_get_sta_cxn_info(mac_ctx, session_id, buf, buf_sz);
15768 	sme_release_global_lock(&mac_ctx->sme);
15769 
15770 	return status;
15771 }
15772 #endif
15773 #endif
15774 
15775 QDF_STATUS
sme_get_roam_scan_stats(mac_handle_t mac_handle,roam_scan_stats_cb cb,void * context,uint32_t vdev_id)15776 sme_get_roam_scan_stats(mac_handle_t mac_handle,
15777 			roam_scan_stats_cb cb, void *context,
15778 			uint32_t vdev_id)
15779 {
15780 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
15781 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
15782 	struct scheduler_msg msg = {0};
15783 	struct sir_roam_scan_stats *req;
15784 
15785 	req = qdf_mem_malloc(sizeof(*req));
15786 	if (!req)
15787 		return QDF_STATUS_E_NOMEM;
15788 
15789 	req->vdev_id = vdev_id;
15790 	req->cb = cb;
15791 	req->context = context;
15792 
15793 	status = sme_acquire_global_lock(&mac->sme);
15794 	if (QDF_IS_STATUS_SUCCESS(status)) {
15795 		msg.bodyptr = req;
15796 		msg.type = WMA_GET_ROAM_SCAN_STATS;
15797 		msg.reserved = 0;
15798 		status = scheduler_post_message(QDF_MODULE_ID_SME,
15799 						QDF_MODULE_ID_WMA,
15800 						QDF_MODULE_ID_WMA,
15801 						&msg);
15802 		sme_release_global_lock(&mac->sme);
15803 		if (!QDF_IS_STATUS_SUCCESS(status)) {
15804 			sme_err("post roam scan stats req failed");
15805 			status = QDF_STATUS_E_FAILURE;
15806 			qdf_mem_free(req);
15807 		}
15808 	} else {
15809 		qdf_mem_free(req);
15810 	}
15811 
15812 	return status;
15813 }
15814 
15815 #ifdef WLAN_FEATURE_11BE
sme_is_phy_mode_11be(eCsrPhyMode phy_mode)15816 static inline bool sme_is_phy_mode_11be(eCsrPhyMode phy_mode)
15817 {
15818 	if (phy_mode == eCSR_DOT11_MODE_AUTO ||
15819 	    CSR_IS_DOT11_PHY_MODE_11BE(phy_mode) ||
15820 	    CSR_IS_DOT11_PHY_MODE_11BE_ONLY(phy_mode)) {
15821 		return true;
15822 	}
15823 
15824 	return false;
15825 }
15826 #else
sme_is_phy_mode_11be(eCsrPhyMode phy_mode)15827 static inline bool sme_is_phy_mode_11be(eCsrPhyMode phy_mode)
15828 {
15829 	return false;
15830 }
15831 #endif
15832 
sme_update_score_config(mac_handle_t mac_handle,eCsrPhyMode phy_mode,uint8_t num_rf_chains)15833 void sme_update_score_config(mac_handle_t mac_handle, eCsrPhyMode phy_mode,
15834 			     uint8_t num_rf_chains)
15835 {
15836 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
15837 	struct wlan_mlme_nss_chains vdev_ini_cfg;
15838 	bool bval = false;
15839 	uint32_t channel_bonding_mode;
15840 	QDF_STATUS status;
15841 	struct psoc_phy_config config = {0};
15842 	bool eht_cap;
15843 
15844 	ucfg_psoc_mlme_get_11be_capab(mac_ctx->psoc, &eht_cap);
15845 	config.eht_cap = eht_cap;
15846 
15847 	qdf_mem_zero(&vdev_ini_cfg, sizeof(struct wlan_mlme_nss_chains));
15848 	/* Populate the nss chain params from ini for this vdev type */
15849 	sme_populate_nss_chain_params(mac_handle, &vdev_ini_cfg,
15850 				      QDF_STA_MODE, num_rf_chains);
15851 
15852 	config.vdev_nss_24g = vdev_ini_cfg.rx_nss[NSS_CHAINS_BAND_2GHZ];
15853 	config.vdev_nss_5g = vdev_ini_cfg.rx_nss[NSS_CHAINS_BAND_5GHZ];
15854 
15855 	if (config.eht_cap ||
15856 	    phy_mode == eCSR_DOT11_MODE_AUTO ||
15857 	    phy_mode == eCSR_DOT11_MODE_11ax ||
15858 	    phy_mode == eCSR_DOT11_MODE_11ax_ONLY)
15859 		config.he_cap = 1;
15860 
15861 	if (config.he_cap ||
15862 	    phy_mode == eCSR_DOT11_MODE_11ac ||
15863 	    phy_mode == eCSR_DOT11_MODE_11ac_ONLY)
15864 		config.vht_cap = 1;
15865 
15866 	if (config.vht_cap || phy_mode == eCSR_DOT11_MODE_11n ||
15867 	    phy_mode == eCSR_DOT11_MODE_11n_ONLY)
15868 		config.ht_cap = 1;
15869 
15870 	if (!IS_FEATURE_SUPPORTED_BY_FW(DOT11AX))
15871 		config.he_cap = 0;
15872 
15873 	if (!IS_FEATURE_SUPPORTED_BY_FW(DOT11AC))
15874 		config.vht_cap = 0;
15875 
15876 	status = wlan_mlme_get_vht_for_24ghz(mac_ctx->psoc, &bval);
15877 	if (!QDF_IS_STATUS_SUCCESS(status))
15878 		sme_err("Failed to get vht_for_24ghz");
15879 	if (config.vht_cap && bval)
15880 		config.vht_24G_cap = 1;
15881 
15882 	status = wlan_mlme_get_vht_enable_tx_bf(mac_ctx->psoc,
15883 						&bval);
15884 	if (!QDF_IS_STATUS_SUCCESS(status))
15885 		sme_err("unable to get vht_enable_tx_bf");
15886 
15887 	if (bval)
15888 		config.beamformee_cap = 1;
15889 
15890 	ucfg_mlme_get_channel_bonding_24ghz(mac_ctx->psoc,
15891 					    &channel_bonding_mode);
15892 	config.bw_above_20_24ghz = channel_bonding_mode;
15893 	ucfg_mlme_get_channel_bonding_5ghz(mac_ctx->psoc,
15894 					   &channel_bonding_mode);
15895 	config.bw_above_20_5ghz = channel_bonding_mode;
15896 	config.max_chan_switch_ie = mlme_max_chan_switch_is_set(mac_ctx->psoc);
15897 
15898 	wlan_psoc_set_phy_config(mac_ctx->psoc, &config);
15899 }
15900 
15901 static void
__sme_enable_fw_module_log_level(uint8_t * enable_fw_module_log_level,uint8_t enable_fw_module_log_level_num,int vdev_id,int param_id)15902 __sme_enable_fw_module_log_level(uint8_t *enable_fw_module_log_level,
15903 				 uint8_t enable_fw_module_log_level_num,
15904 				 int vdev_id, int param_id)
15905 {
15906 	uint8_t count = 0;
15907 	uint32_t value = 0;
15908 	int ret;
15909 
15910 	while (count < enable_fw_module_log_level_num) {
15911 		/*
15912 		 * FW module log level input array looks like
15913 		 * below:
15914 		 * enable_fw_module_log_level = {<FW Module ID>,
15915 		 * <Log Level>,...}
15916 		 * For example:
15917 		 * enable_fw_module_log_level=
15918 		 * {1,0,2,1,3,2,4,3,5,4,6,5,7,6}
15919 		 * Above input array means :
15920 		 * For FW module ID 1 enable log level 0
15921 		 * For FW module ID 2 enable log level 1
15922 		 * For FW module ID 3 enable log level 2
15923 		 * For FW module ID 4 enable log level 3
15924 		 * For FW module ID 5 enable log level 4
15925 		 * For FW module ID 6 enable log level 5
15926 		 * For FW module ID 7 enable log level 6
15927 		 */
15928 
15929 		if ((enable_fw_module_log_level[count] > WLAN_MODULE_ID_MAX) ||
15930 		    (enable_fw_module_log_level[count + 1] > DBGLOG_LVL_MAX)) {
15931 			sme_err("Module id %d or dbglog level %d input value is more than max",
15932 				enable_fw_module_log_level[count],
15933 				enable_fw_module_log_level[count + 1]);
15934 			count += 2;
15935 			continue;
15936 		}
15937 
15938 		value = enable_fw_module_log_level[count] << 16;
15939 		value |= enable_fw_module_log_level[count + 1];
15940 		ret = sme_cli_set_command(vdev_id, param_id, value, DBG_CMD);
15941 		if (ret != 0)
15942 			sme_err("Failed to enable FW module log level %d ret %d",
15943 				value, ret);
15944 
15945 		count += 2;
15946 	}
15947 }
15948 
sme_enable_fw_module_log_level(mac_handle_t mac_handle,int vdev_id)15949 void sme_enable_fw_module_log_level(mac_handle_t mac_handle, int vdev_id)
15950 {
15951 	QDF_STATUS status;
15952 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
15953 	uint8_t *enable_fw_module_log_level;
15954 	uint8_t enable_fw_module_log_level_num;
15955 
15956 	status = ucfg_fwol_get_enable_fw_module_log_level(
15957 			mac_ctx->psoc, &enable_fw_module_log_level,
15958 			&enable_fw_module_log_level_num);
15959 	if (QDF_IS_STATUS_ERROR(status))
15960 		return;
15961 	__sme_enable_fw_module_log_level(enable_fw_module_log_level,
15962 					 enable_fw_module_log_level_num,
15963 					 vdev_id,
15964 					 WMI_DBGLOG_MOD_LOG_LEVEL);
15965 
15966 	enable_fw_module_log_level_num = 0;
15967 	status = ucfg_fwol_wow_get_enable_fw_module_log_level(
15968 			mac_ctx->psoc, &enable_fw_module_log_level,
15969 			&enable_fw_module_log_level_num);
15970 	if (QDF_IS_STATUS_ERROR(status))
15971 		return;
15972 	__sme_enable_fw_module_log_level(enable_fw_module_log_level,
15973 					 enable_fw_module_log_level_num,
15974 					 vdev_id,
15975 					 WMI_DBGLOG_MOD_WOW_LOG_LEVEL);
15976 }
15977 
15978 #ifdef WLAN_FEATURE_MOTION_DETECTION
15979 /**
15980  * sme_set_md_bl_evt_cb - Register/set motion detection baseline callback
15981  * @mac_handle: mac handle
15982  * @callback_fn: callback function pointer
15983  * @hdd_ctx: hdd context
15984  *
15985  * Return: QDF_STATUS_SUCCESS or non-zero on failure
15986  */
sme_set_md_bl_evt_cb(mac_handle_t mac_handle,QDF_STATUS (* callback_fn)(void * ctx,struct sir_md_bl_evt * event),void * hdd_ctx)15987 QDF_STATUS sme_set_md_bl_evt_cb(
15988 	mac_handle_t mac_handle,
15989 	QDF_STATUS (*callback_fn)(void *ctx, struct sir_md_bl_evt *event),
15990 	void *hdd_ctx
15991 )
15992 {
15993 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
15994 	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
15995 
15996 	qdf_status = sme_acquire_global_lock(&mac->sme);
15997 	if (QDF_IS_STATUS_SUCCESS(qdf_status)) {
15998 		mac->sme.md_bl_evt_cb = callback_fn;
15999 		mac->sme.md_ctx = hdd_ctx;
16000 		sme_release_global_lock(&mac->sme);
16001 	}
16002 	return qdf_status;
16003 }
16004 
16005 /**
16006  * sme_set_md_host_evt_cb - Register/set motion detection callback
16007  * @mac_handle: mac handle
16008  * @callback_fn: motion detection callback function pointer
16009  * @hdd_ctx: hdd context
16010  *
16011  * Return: QDF_STATUS_SUCCESS or non-zero on failure
16012  */
sme_set_md_host_evt_cb(mac_handle_t mac_handle,QDF_STATUS (* callback_fn)(void * ctx,struct sir_md_evt * event),void * hdd_ctx)16013 QDF_STATUS sme_set_md_host_evt_cb(
16014 	mac_handle_t mac_handle,
16015 	QDF_STATUS (*callback_fn)(void *ctx, struct sir_md_evt *event),
16016 	void *hdd_ctx
16017 )
16018 {
16019 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
16020 	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
16021 
16022 	qdf_status = sme_acquire_global_lock(&mac->sme);
16023 	if (QDF_IS_STATUS_SUCCESS(qdf_status)) {
16024 		mac->sme.md_host_evt_cb = callback_fn;
16025 		mac->sme.md_ctx = hdd_ctx;
16026 		sme_release_global_lock(&mac->sme);
16027 	}
16028 	return qdf_status;
16029 }
16030 
16031 /**
16032  * sme_motion_det_config - Post motion detection configuration msg to scheduler
16033  * @mac_handle: mac handle
16034  * @motion_det_config: motion detection configuration
16035  *
16036  * Return: QDF_STATUS_SUCCESS or non-zero on failure
16037  */
sme_motion_det_config(mac_handle_t mac_handle,struct sme_motion_det_cfg * motion_det_config)16038 QDF_STATUS sme_motion_det_config(mac_handle_t mac_handle,
16039 				 struct sme_motion_det_cfg *motion_det_config)
16040 {
16041 	struct scheduler_msg msg;
16042 	struct sme_motion_det_cfg *motion_det_cfg;
16043 	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
16044 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
16045 
16046 	qdf_status = sme_acquire_global_lock(&mac->sme);
16047 	if (QDF_IS_STATUS_SUCCESS(qdf_status)) {
16048 		motion_det_cfg =
16049 				qdf_mem_malloc(sizeof(*motion_det_cfg));
16050 		if (!motion_det_cfg) {
16051 			sme_release_global_lock(&mac->sme);
16052 			return QDF_STATUS_E_NOMEM;
16053 		}
16054 
16055 		*motion_det_cfg = *motion_det_config;
16056 
16057 		qdf_mem_set(&msg, sizeof(msg), 0);
16058 		msg.type = WMA_SET_MOTION_DET_CONFIG;
16059 		msg.bodyptr = motion_det_cfg;
16060 
16061 		qdf_status = scheduler_post_message(QDF_MODULE_ID_SME,
16062 						    QDF_MODULE_ID_WMA,
16063 						    QDF_MODULE_ID_WMA,
16064 						    &msg);
16065 		if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
16066 			qdf_mem_free(motion_det_cfg);
16067 			qdf_status = QDF_STATUS_E_FAILURE;
16068 		}
16069 		sme_release_global_lock(&mac->sme);
16070 	}
16071 	return qdf_status;
16072 }
16073 
16074 /**
16075  * sme_motion_det_enable - Post motion detection start/stop msg to scheduler
16076  * @mac_handle: mac handle
16077  * @motion_det_enable: motion detection start/stop
16078  *
16079  * Return: QDF_STATUS_SUCCESS or non-zero on failure
16080  */
sme_motion_det_enable(mac_handle_t mac_handle,struct sme_motion_det_en * motion_det_enable)16081 QDF_STATUS sme_motion_det_enable(mac_handle_t mac_handle,
16082 				 struct sme_motion_det_en *motion_det_enable)
16083 {
16084 	struct scheduler_msg msg;
16085 	struct sme_motion_det_en *motion_det_en;
16086 	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
16087 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
16088 
16089 	qdf_status = sme_acquire_global_lock(&mac->sme);
16090 	if (QDF_IS_STATUS_SUCCESS(qdf_status)) {
16091 		motion_det_en = qdf_mem_malloc(sizeof(*motion_det_en));
16092 		if (!motion_det_en) {
16093 			sme_release_global_lock(&mac->sme);
16094 			return QDF_STATUS_E_NOMEM;
16095 		}
16096 
16097 		*motion_det_en = *motion_det_enable;
16098 
16099 		qdf_mem_set(&msg, sizeof(msg), 0);
16100 		msg.type = WMA_SET_MOTION_DET_ENABLE;
16101 		msg.bodyptr = motion_det_en;
16102 
16103 		qdf_status = scheduler_post_message(QDF_MODULE_ID_SME,
16104 						    QDF_MODULE_ID_WMA,
16105 						    QDF_MODULE_ID_WMA,
16106 						    &msg);
16107 		if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
16108 			qdf_mem_free(motion_det_en);
16109 			qdf_status = QDF_STATUS_E_FAILURE;
16110 		}
16111 		sme_release_global_lock(&mac->sme);
16112 	}
16113 	return qdf_status;
16114 }
16115 
16116 /**
16117  * sme_motion_det_base_line_config - Post md baselining cfg msg to scheduler
16118  * @mac_handle: mac handle
16119  * @motion_det_base_line_config: motion detection baselining configuration
16120  *
16121  * Return: QDF_STATUS_SUCCESS or non-zero on failure
16122  */
sme_motion_det_base_line_config(mac_handle_t mac_handle,struct sme_motion_det_base_line_cfg * motion_det_base_line_config)16123 QDF_STATUS sme_motion_det_base_line_config(
16124 	mac_handle_t mac_handle,
16125 	struct sme_motion_det_base_line_cfg *motion_det_base_line_config)
16126 {
16127 	struct scheduler_msg msg;
16128 	struct sme_motion_det_base_line_cfg *motion_det_base_line_cfg;
16129 	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
16130 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
16131 
16132 	qdf_status = sme_acquire_global_lock(&mac->sme);
16133 	if (QDF_IS_STATUS_SUCCESS(qdf_status)) {
16134 		motion_det_base_line_cfg =
16135 			qdf_mem_malloc(sizeof(*motion_det_base_line_cfg));
16136 
16137 		if (!motion_det_base_line_cfg) {
16138 			sme_release_global_lock(&mac->sme);
16139 			return QDF_STATUS_E_NOMEM;
16140 		}
16141 
16142 		*motion_det_base_line_cfg = *motion_det_base_line_config;
16143 
16144 		qdf_mem_set(&msg, sizeof(msg), 0);
16145 		msg.type = WMA_SET_MOTION_DET_BASE_LINE_CONFIG;
16146 		msg.bodyptr = motion_det_base_line_cfg;
16147 
16148 		qdf_status = scheduler_post_message(QDF_MODULE_ID_SME,
16149 						    QDF_MODULE_ID_WMA,
16150 						    QDF_MODULE_ID_WMA,
16151 						    &msg);
16152 		if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
16153 			qdf_mem_free(motion_det_base_line_cfg);
16154 			qdf_status = QDF_STATUS_E_FAILURE;
16155 		}
16156 		sme_release_global_lock(&mac->sme);
16157 	}
16158 	return qdf_status;
16159 }
16160 
16161 /**
16162  * sme_motion_det_base_line_enable - Post md baselining enable msg to scheduler
16163  * @mac_handle: mac handle
16164  * @motion_det_base_line_enable: motion detection baselining start/stop
16165  *
16166  * Return: QDF_STATUS_SUCCESS or non-zero on failure
16167  */
sme_motion_det_base_line_enable(mac_handle_t mac_handle,struct sme_motion_det_base_line_en * motion_det_base_line_enable)16168 QDF_STATUS sme_motion_det_base_line_enable(
16169 	mac_handle_t mac_handle,
16170 	struct sme_motion_det_base_line_en *motion_det_base_line_enable)
16171 {
16172 	struct scheduler_msg msg;
16173 	struct sme_motion_det_base_line_en *motion_det_base_line_en;
16174 	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
16175 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
16176 
16177 	qdf_status = sme_acquire_global_lock(&mac->sme);
16178 	if (QDF_IS_STATUS_SUCCESS(qdf_status)) {
16179 		motion_det_base_line_en =
16180 			qdf_mem_malloc(sizeof(*motion_det_base_line_en));
16181 
16182 		if (!motion_det_base_line_en) {
16183 			sme_release_global_lock(&mac->sme);
16184 			return QDF_STATUS_E_NOMEM;
16185 		}
16186 
16187 		*motion_det_base_line_en = *motion_det_base_line_enable;
16188 
16189 		qdf_mem_set(&msg, sizeof(msg), 0);
16190 		msg.type = WMA_SET_MOTION_DET_BASE_LINE_ENABLE;
16191 		msg.bodyptr = motion_det_base_line_en;
16192 
16193 		qdf_status = scheduler_post_message(QDF_MODULE_ID_SME,
16194 						    QDF_MODULE_ID_WMA,
16195 						    QDF_MODULE_ID_WMA,
16196 						    &msg);
16197 		if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
16198 			qdf_mem_free(motion_det_base_line_en);
16199 			qdf_status = QDF_STATUS_E_FAILURE;
16200 		}
16201 		sme_release_global_lock(&mac->sme);
16202 	}
16203 	return qdf_status;
16204 }
16205 #endif /* WLAN_FEATURE_MOTION_DETECTION */
16206 
16207 #ifdef FW_THERMAL_THROTTLE_SUPPORT
16208 
16209 /**
16210  * sme_set_thermal_throttle_cfg() - SME API to set the thermal throttle
16211  * configuration parameters
16212  * @mac_handle: Opaque handle to the global MAC context
16213  * @therm_params: structure of thermal configuration parameters
16214  *
16215  * Return: QDF_STATUS
16216  */
sme_set_thermal_throttle_cfg(mac_handle_t mac_handle,struct thermal_mitigation_params * therm_params)16217 QDF_STATUS sme_set_thermal_throttle_cfg(mac_handle_t mac_handle,
16218 			struct thermal_mitigation_params *therm_params)
16219 
16220 {
16221 	struct scheduler_msg msg;
16222 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
16223 	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
16224 	struct thermal_mitigation_params *therm_cfg_params;
16225 
16226 	therm_cfg_params = qdf_mem_malloc(sizeof(*therm_cfg_params));
16227 	if (!therm_cfg_params)
16228 		return QDF_STATUS_E_NOMEM;
16229 
16230 	qdf_mem_set(therm_cfg_params, sizeof(*therm_cfg_params), 0);
16231 	qdf_mem_copy(therm_cfg_params, therm_params, sizeof(*therm_cfg_params));
16232 
16233 	qdf_mem_set(&msg, sizeof(msg), 0);
16234 	msg.type = WMA_SET_THERMAL_THROTTLE_CFG;
16235 	msg.reserved = 0;
16236 	msg.bodyptr = therm_cfg_params;
16237 
16238 	qdf_status = sme_acquire_global_lock(&mac->sme);
16239 	qdf_status =  scheduler_post_message(QDF_MODULE_ID_SME,
16240 					     QDF_MODULE_ID_WMA,
16241 					     QDF_MODULE_ID_WMA, &msg);
16242 	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
16243 		sme_err("failed to schedule throttle config req %d",
16244 			qdf_status);
16245 		qdf_mem_free(therm_cfg_params);
16246 		qdf_status = QDF_STATUS_E_FAILURE;
16247 	}
16248 	sme_release_global_lock(&mac->sme);
16249 	return qdf_status;
16250 }
16251 
16252 /**
16253  * sme_set_thermal_mgmt() - SME API to set the thermal management params
16254  * @mac_handle: Opaque handle to the global MAC context
16255  * @lower_thresh_deg: Lower threshold value of Temperature
16256  * @higher_thresh_deg: Higher threshold value of Temperature
16257  *
16258  * Return: QDF_STATUS
16259  */
sme_set_thermal_mgmt(mac_handle_t mac_handle,uint16_t lower_thresh_deg,uint16_t higher_thresh_deg)16260 QDF_STATUS sme_set_thermal_mgmt(mac_handle_t mac_handle,
16261 				uint16_t lower_thresh_deg,
16262 				uint16_t higher_thresh_deg)
16263 {
16264 	struct scheduler_msg msg;
16265 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
16266 	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
16267 	t_thermal_cmd_params *therm_mgmt_cmd;
16268 
16269 	qdf_status = sme_acquire_global_lock(&mac->sme);
16270 	if (QDF_STATUS_SUCCESS == qdf_status) {
16271 		therm_mgmt_cmd = qdf_mem_malloc(sizeof(*therm_mgmt_cmd));
16272 		if (!therm_mgmt_cmd) {
16273 			sme_release_global_lock(&mac->sme);
16274 			return QDF_STATUS_E_NOMEM;
16275 		}
16276 
16277 		therm_mgmt_cmd->minTemp = lower_thresh_deg;
16278 		therm_mgmt_cmd->maxTemp = higher_thresh_deg;
16279 		therm_mgmt_cmd->thermalEnable = 1;
16280 
16281 		qdf_mem_set(&msg, sizeof(msg), 0);
16282 		msg.type = WMA_SET_THERMAL_MGMT;
16283 		msg.reserved = 0;
16284 		msg.bodyptr = therm_mgmt_cmd;
16285 
16286 		qdf_status =  scheduler_post_message(QDF_MODULE_ID_SME,
16287 						     QDF_MODULE_ID_WMA,
16288 						     QDF_MODULE_ID_WMA, &msg);
16289 		if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
16290 			qdf_mem_free(therm_mgmt_cmd);
16291 			qdf_status = QDF_STATUS_E_FAILURE;
16292 		}
16293 		sme_release_global_lock(&mac->sme);
16294 	}
16295 	return qdf_status;
16296 }
16297 #endif /* FW_THERMAL_THROTTLE_SUPPORT */
16298 
sme_update_hidden_ssid_status_cb(mac_handle_t mac_handle,hidden_ssid_cb cb)16299 QDF_STATUS sme_update_hidden_ssid_status_cb(mac_handle_t mac_handle,
16300 					    hidden_ssid_cb cb)
16301 {
16302 	QDF_STATUS status;
16303 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
16304 
16305 	status = sme_acquire_global_lock(&mac->sme);
16306 	if (QDF_IS_STATUS_SUCCESS(status)) {
16307 		mac->sme.hidden_ssid_cb = cb;
16308 		sme_release_global_lock(&mac->sme);
16309 	}
16310 
16311 	return status;
16312 }
16313 
sme_update_owe_info(struct mac_context * mac,struct assoc_ind * assoc_ind)16314 QDF_STATUS sme_update_owe_info(struct mac_context *mac,
16315 			       struct assoc_ind *assoc_ind)
16316 {
16317 	QDF_STATUS status;
16318 
16319 	status = sme_acquire_global_lock(&mac->sme);
16320 	if (QDF_IS_STATUS_SUCCESS(status)) {
16321 		status = csr_update_owe_info(mac, assoc_ind);
16322 		sme_release_global_lock(&mac->sme);
16323 	}
16324 
16325 	return status;
16326 }
16327 
sme_update_ft_info(struct mac_context * mac,struct assoc_ind * assoc_ind)16328 QDF_STATUS sme_update_ft_info(struct mac_context *mac,
16329 			      struct assoc_ind *assoc_ind)
16330 {
16331 	QDF_STATUS status;
16332 
16333 	status = sme_acquire_global_lock(&mac->sme);
16334 	if (QDF_IS_STATUS_SUCCESS(status)) {
16335 		status = csr_update_ft_info(mac, assoc_ind);
16336 		sme_release_global_lock(&mac->sme);
16337 	}
16338 
16339 	return status;
16340 }
16341 
16342 #ifdef WLAN_MWS_INFO_DEBUGFS
16343 QDF_STATUS
sme_get_mws_coex_info(mac_handle_t mac_handle,uint32_t vdev_id,uint32_t cmd_id,void (* callback_fn)(void * coex_info_data,void * context,wmi_mws_coex_cmd_id cmd_id),void * context)16344 sme_get_mws_coex_info(mac_handle_t mac_handle, uint32_t vdev_id,
16345 		      uint32_t cmd_id, void (*callback_fn)(void *coex_info_data,
16346 							   void *context,
16347 							   wmi_mws_coex_cmd_id
16348 							   cmd_id),
16349 		      void *context)
16350 {
16351 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
16352 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
16353 	struct scheduler_msg msg = {0};
16354 	struct sir_get_mws_coex_info *req;
16355 
16356 	req = qdf_mem_malloc(sizeof(*req));
16357 	if (!req)
16358 		return QDF_STATUS_E_NOMEM;
16359 
16360 	req->vdev_id = vdev_id;
16361 	req->cmd_id  = cmd_id;
16362 	mac->sme.mws_coex_info_state_resp_callback = callback_fn;
16363 	mac->sme.mws_coex_info_ctx = context;
16364 	status = sme_acquire_global_lock(&mac->sme);
16365 	if (QDF_IS_STATUS_SUCCESS(status)) {
16366 		msg.bodyptr = req;
16367 		msg.type = WMA_GET_MWS_COEX_INFO_REQ;
16368 		status = scheduler_post_message(QDF_MODULE_ID_SME,
16369 						QDF_MODULE_ID_WMA,
16370 						QDF_MODULE_ID_WMA,
16371 						&msg);
16372 		sme_release_global_lock(&mac->sme);
16373 		if (!QDF_IS_STATUS_SUCCESS(status)) {
16374 			sme_err("post MWS coex info req failed");
16375 			status = QDF_STATUS_E_FAILURE;
16376 			qdf_mem_free(req);
16377 		}
16378 	} else {
16379 		sme_err("sme_acquire_global_lock failed");
16380 		qdf_mem_free(req);
16381 	}
16382 
16383 	return status;
16384 }
16385 #endif /* WLAN_MWS_INFO_DEBUGFS */
16386 
16387 #ifdef WLAN_BCN_RECV_FEATURE
16388 /**
16389  * sme_scan_event_handler() - Scan complete event handler
16390  * @vdev: vdev obj manager
16391  * @event: scan event
16392  * @arg: arg of scan event
16393  *
16394  * This function is getting called after Host receive scan start
16395  *
16396  * Return: None
16397  */
sme_scan_event_handler(struct wlan_objmgr_vdev * vdev,struct scan_event * event,void * arg)16398 static void sme_scan_event_handler(struct wlan_objmgr_vdev *vdev,
16399 				   struct scan_event *event,
16400 				   void *arg)
16401 {
16402 	struct mac_context *mac = arg;
16403 	uint8_t vdev_id;
16404 
16405 	if (!mac) {
16406 		sme_err("Invalid mac context");
16407 		return;
16408 	}
16409 
16410 	if (!mac->sme.beacon_pause_cb)
16411 		return;
16412 
16413 	if (event->type != SCAN_EVENT_TYPE_STARTED)
16414 		return;
16415 
16416 	for (vdev_id = 0 ; vdev_id < WLAN_MAX_VDEVS ; vdev_id++) {
16417 		if (CSR_IS_SESSION_VALID(mac, vdev_id) &&
16418 		    sme_is_beacon_report_started(MAC_HANDLE(mac), vdev_id)) {
16419 			sme_debug("Send pause ind for vdev_id : %d", vdev_id);
16420 			mac->sme.beacon_pause_cb(mac->hdd_handle, vdev_id,
16421 						 event->type, false);
16422 		}
16423 	}
16424 }
16425 
sme_register_bcn_recv_pause_ind_cb(mac_handle_t mac_handle,beacon_pause_cb cb)16426 QDF_STATUS sme_register_bcn_recv_pause_ind_cb(mac_handle_t mac_handle,
16427 					      beacon_pause_cb cb)
16428 {
16429 	QDF_STATUS status;
16430 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
16431 
16432 	if (!mac) {
16433 		sme_err("Invalid mac context");
16434 		return QDF_STATUS_E_NOMEM;
16435 	}
16436 
16437 	/* scan event de-registration */
16438 	if (!cb) {
16439 		ucfg_scan_unregister_event_handler(mac->pdev,
16440 						   sme_scan_event_handler, mac);
16441 		return QDF_STATUS_SUCCESS;
16442 	}
16443 	status = sme_acquire_global_lock(&mac->sme);
16444 	if (QDF_IS_STATUS_SUCCESS(status)) {
16445 		mac->sme.beacon_pause_cb = cb;
16446 		sme_release_global_lock(&mac->sme);
16447 	}
16448 
16449 	/* scan event registration */
16450 	status = ucfg_scan_register_event_handler(mac->pdev,
16451 						  sme_scan_event_handler, mac);
16452 	if (QDF_IS_STATUS_ERROR(status))
16453 		sme_err("scan event register failed ");
16454 
16455 	return status;
16456 }
16457 #endif
16458 
sme_set_vdev_sw_retry(uint8_t vdev_id,uint8_t sw_retry_count,wmi_vdev_custom_sw_retry_type_t sw_retry_type)16459 QDF_STATUS sme_set_vdev_sw_retry(uint8_t vdev_id, uint8_t sw_retry_count,
16460 				 wmi_vdev_custom_sw_retry_type_t sw_retry_type)
16461 {
16462 	QDF_STATUS status;
16463 
16464 	status = wma_set_vdev_sw_retry_th(vdev_id, sw_retry_count,
16465 					  sw_retry_type);
16466 	if (QDF_IS_STATUS_ERROR(status)) {
16467 		sme_err("Failed to set retry count for vdev: %d", vdev_id);
16468 		return status;
16469 	}
16470 
16471 	return QDF_STATUS_SUCCESS;
16472 }
16473 
sme_set_disconnect_ies(mac_handle_t mac_handle,uint8_t vdev_id,uint8_t * ie_data,uint16_t ie_len)16474 QDF_STATUS sme_set_disconnect_ies(mac_handle_t mac_handle, uint8_t vdev_id,
16475 				  uint8_t *ie_data, uint16_t ie_len)
16476 {
16477 	struct mac_context *mac_ctx;
16478 	struct wlan_objmgr_vdev *vdev;
16479 	struct element_info ie;
16480 
16481 	if (!ie_data || !ie_len) {
16482 		sme_debug("Got NULL disconnect IEs");
16483 		return QDF_STATUS_E_INVAL;
16484 	}
16485 
16486 	mac_ctx = MAC_CONTEXT(mac_handle);
16487 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac_ctx->psoc,
16488 						    vdev_id,
16489 						    WLAN_LEGACY_SME_ID);
16490 	if (!vdev) {
16491 		sme_err("Got NULL vdev obj, returning");
16492 		return QDF_STATUS_E_FAILURE;
16493 	}
16494 
16495 	ie.ptr = ie_data;
16496 	ie.len = ie_len;
16497 
16498 	mlme_set_self_disconnect_ies(vdev, &ie);
16499 
16500 	wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID);
16501 	return QDF_STATUS_SUCCESS;
16502 }
16503 
16504 QDF_STATUS
sme_send_vendor_btm_params(mac_handle_t mac_handle,uint8_t vdev_id)16505 sme_send_vendor_btm_params(mac_handle_t mac_handle, uint8_t vdev_id)
16506 {
16507 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
16508 	QDF_STATUS status = QDF_STATUS_SUCCESS;
16509 
16510 	if (vdev_id >= WLAN_MAX_VDEVS) {
16511 		sme_err("Invalid sme session id: %d", vdev_id);
16512 		return QDF_STATUS_E_INVAL;
16513 	}
16514 
16515 	status = sme_acquire_global_lock(&mac->sme);
16516 	if (QDF_IS_STATUS_SUCCESS(status)) {
16517 		if (mac->mlme_cfg->lfr.roam_scan_offload_enabled)
16518 			wlan_roam_update_cfg(mac->psoc, vdev_id,
16519 					    REASON_ROAM_CONTROL_CONFIG_CHANGED);
16520 		sme_release_global_lock(&mac->sme);
16521 	}
16522 
16523 	return status;
16524 }
16525 
sme_set_roam_config_enable(mac_handle_t mac_handle,uint8_t vdev_id,uint8_t roam_control_enable)16526 QDF_STATUS sme_set_roam_config_enable(mac_handle_t mac_handle,
16527 				      uint8_t vdev_id,
16528 				      uint8_t roam_control_enable)
16529 {
16530 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
16531 	struct cm_roam_values_copy src_config = {};
16532 
16533 	if (!mac->mlme_cfg->lfr.roam_scan_offload_enabled)
16534 		return QDF_STATUS_E_INVAL;
16535 
16536 	src_config.bool_value = !!roam_control_enable;
16537 	return wlan_cm_roam_cfg_set_value(mac->psoc, vdev_id,
16538 					  ROAM_CONFIG_ENABLE,
16539 					  &src_config);
16540 }
16541 
sme_get_roam_config_status(mac_handle_t mac_handle,uint8_t vdev_id,uint8_t * config_status)16542 QDF_STATUS sme_get_roam_config_status(mac_handle_t mac_handle,
16543 				      uint8_t vdev_id,
16544 				      uint8_t *config_status)
16545 {
16546 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
16547 	struct cm_roam_values_copy temp;
16548 
16549 	wlan_cm_roam_cfg_get_value(mac->psoc, vdev_id, ROAM_CONTROL_ENABLE,
16550 				    &temp);
16551 	*config_status = temp.bool_value;
16552 
16553 	return QDF_STATUS_SUCCESS;
16554 }
16555 
sme_get_full_roam_scan_period_global(mac_handle_t mac_handle)16556 uint16_t sme_get_full_roam_scan_period_global(mac_handle_t mac_handle)
16557 {
16558 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
16559 
16560 	return mac->mlme_cfg->lfr.roam_full_scan_period;
16561 }
16562 
16563 QDF_STATUS
sme_get_full_roam_scan_period(mac_handle_t mac_handle,uint8_t vdev_id,uint32_t * full_roam_scan_period)16564 sme_get_full_roam_scan_period(mac_handle_t mac_handle, uint8_t vdev_id,
16565 			      uint32_t *full_roam_scan_period)
16566 {
16567 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
16568 	struct cm_roam_values_copy temp;
16569 
16570 	wlan_cm_roam_cfg_get_value(mac->psoc, vdev_id,
16571 				   FULL_ROAM_SCAN_PERIOD, &temp);
16572 	*full_roam_scan_period = temp.uint_value;
16573 
16574 	return QDF_STATUS_SUCCESS;
16575 }
16576 
sme_check_for_duplicate_session(mac_handle_t mac_handle,uint8_t ** mac_list)16577 QDF_STATUS sme_check_for_duplicate_session(mac_handle_t mac_handle,
16578 					   uint8_t **mac_list)
16579 {
16580 	QDF_STATUS status = QDF_STATUS_SUCCESS;
16581 	bool peer_exist = false;
16582 	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
16583 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
16584 	uint8_t **peer_addr = mac_list;
16585 
16586 	if (!soc)
16587 		return QDF_STATUS_E_INVAL;
16588 
16589 	if (QDF_STATUS_SUCCESS != sme_acquire_global_lock(&mac_ctx->sme))
16590 		return QDF_STATUS_E_INVAL;
16591 
16592 	while (*peer_addr) {
16593 		peer_exist = cdp_find_peer_exist(soc, OL_TXRX_PDEV_ID,
16594 						 *peer_addr);
16595 		if (peer_exist) {
16596 			sme_err("Peer exists with same MAC");
16597 			status = QDF_STATUS_E_EXISTS;
16598 			break;
16599 		}
16600 		peer_addr++;
16601 	}
16602 	sme_release_global_lock(&mac_ctx->sme);
16603 
16604 	return status;
16605 }
16606 
16607 #ifdef FEATURE_ANI_LEVEL_REQUEST
sme_get_ani_level(mac_handle_t mac_handle,uint32_t * freqs,uint8_t num_freqs,void (* callback)(struct wmi_host_ani_level_event * ani,uint8_t num,void * context),void * context)16608 QDF_STATUS sme_get_ani_level(mac_handle_t mac_handle, uint32_t *freqs,
16609 			     uint8_t num_freqs, void (*callback)(
16610 			     struct wmi_host_ani_level_event *ani, uint8_t num,
16611 			     void *context), void *context)
16612 {
16613 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
16614 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
16615 	void *wma_handle;
16616 
16617 	wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
16618 	if (!wma_handle)
16619 		return QDF_STATUS_E_FAILURE;
16620 
16621 	mac->ani_params.ani_level_cb = callback;
16622 	mac->ani_params.context = context;
16623 
16624 	status = wma_send_ani_level_request(wma_handle, freqs, num_freqs);
16625 	return status;
16626 }
16627 #endif /* FEATURE_ANI_LEVEL_REQUEST */
16628 
16629 #ifdef FEATURE_MONITOR_MODE_SUPPORT
16630 
sme_set_monitor_mode_cb(mac_handle_t mac_handle,void (* monitor_mode_cb)(uint8_t vdev_id))16631 QDF_STATUS sme_set_monitor_mode_cb(mac_handle_t mac_handle,
16632 				   void (*monitor_mode_cb)(uint8_t vdev_id))
16633 {
16634 	QDF_STATUS qdf_status;
16635 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
16636 
16637 	qdf_status = sme_acquire_global_lock(&mac->sme);
16638 	if (QDF_IS_STATUS_ERROR(qdf_status)) {
16639 		sme_err("Failed to acquire sme lock; status: %d", qdf_status);
16640 		return qdf_status;
16641 	}
16642 	mac->sme.monitor_mode_cb = monitor_mode_cb;
16643 	sme_release_global_lock(&mac->sme);
16644 
16645 	return qdf_status;
16646 }
16647 
sme_process_monitor_mode_vdev_up_evt(uint8_t vdev_id)16648 QDF_STATUS sme_process_monitor_mode_vdev_up_evt(uint8_t vdev_id)
16649 {
16650 	mac_handle_t mac_handle;
16651 	struct mac_context *mac;
16652 
16653 	mac_handle = cds_get_context(QDF_MODULE_ID_SME);
16654 	if (!mac_handle)
16655 		return QDF_STATUS_E_INVAL;
16656 
16657 	mac = MAC_CONTEXT(mac_handle);
16658 
16659 	if (mac->sme.monitor_mode_cb)
16660 		mac->sme.monitor_mode_cb(vdev_id);
16661 	else {
16662 		sme_warn_rl("monitor_mode_cb is not registered");
16663 		return QDF_STATUS_E_FAILURE;
16664 	}
16665 
16666 	return QDF_STATUS_SUCCESS;
16667 }
16668 #endif
16669 
16670 #if defined(CLD_PM_QOS) && defined(WLAN_FEATURE_LL_MODE)
16671 QDF_STATUS
sme_set_beacon_latency_event_cb(mac_handle_t mac_handle,void (* beacon_latency_event_cb)(uint32_t latency_level))16672 sme_set_beacon_latency_event_cb(mac_handle_t mac_handle,
16673 				void (*beacon_latency_event_cb)
16674 				(uint32_t latency_level))
16675 {
16676 	QDF_STATUS qdf_status;
16677 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
16678 
16679 	qdf_status = sme_acquire_global_lock(&mac->sme);
16680 	if (QDF_IS_STATUS_ERROR(qdf_status)) {
16681 		sme_err("Failed to acquire sme lock; status: %d", qdf_status);
16682 		return qdf_status;
16683 	}
16684 	mac->sme.beacon_latency_event_cb = beacon_latency_event_cb;
16685 	sme_release_global_lock(&mac->sme);
16686 
16687 	return qdf_status;
16688 }
16689 #endif
16690 
sme_fill_enc_type(eCsrEncryptionType * cipher_type,uint32_t cipherset)16691 void sme_fill_enc_type(eCsrEncryptionType *cipher_type,
16692 		       uint32_t cipherset)
16693 {
16694 	csr_fill_enc_type(cipher_type, cipherset);
16695 }
16696 
sme_fill_auth_type(enum csr_akm_type * auth_type,uint32_t authmodeset,uint32_t akm,uint32_t ucastcipherset)16697 void sme_fill_auth_type(enum csr_akm_type *auth_type,
16698 			uint32_t authmodeset, uint32_t akm,
16699 			uint32_t ucastcipherset)
16700 {
16701 	csr_fill_auth_type(auth_type, authmodeset,
16702 			   akm, ucastcipherset);
16703 }
16704 
sme_phy_mode_to_dot11mode(enum wlan_phymode phy_mode)16705 enum csr_cfgdot11mode sme_phy_mode_to_dot11mode(enum wlan_phymode phy_mode)
16706 {
16707 	return csr_phy_mode_to_dot11mode(phy_mode);
16708 }
16709 
sme_switch_channel(mac_handle_t mac_handle,struct qdf_mac_addr * bssid,qdf_freq_t chan_freq,enum phy_ch_width chan_width)16710 QDF_STATUS sme_switch_channel(mac_handle_t mac_handle,
16711 			      struct qdf_mac_addr *bssid,
16712 			      qdf_freq_t chan_freq,
16713 			      enum phy_ch_width chan_width)
16714 {
16715 	struct scheduler_msg msg = {0};
16716 	struct csa_offload_params *csa_offload_event;
16717 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
16718 
16719 	csa_offload_event = qdf_mem_malloc(sizeof(*csa_offload_event));
16720 	if (!csa_offload_event)
16721 		return QDF_STATUS_E_NOMEM;
16722 
16723 	qdf_copy_macaddr(&csa_offload_event->bssid, bssid);
16724 	csa_offload_event->csa_chan_freq = (uint32_t)chan_freq;
16725 	csa_offload_event->new_ch_width = chan_width;
16726 	csa_offload_event->channel =
16727 		wlan_reg_freq_to_chan(mac_ctx->pdev,
16728 				      csa_offload_event->csa_chan_freq);
16729 	csa_offload_event->switch_mode = 1;
16730 
16731 	sme_debug("bssid " QDF_MAC_ADDR_FMT " freq %u width %u",
16732 		  QDF_MAC_ADDR_REF(csa_offload_event->bssid.bytes),
16733 		  csa_offload_event->csa_chan_freq,
16734 		  csa_offload_event->new_ch_width);
16735 
16736 	msg.type = eWNI_SME_CSA_REQ;
16737 	msg.reserved = 0;
16738 	msg.bodyptr = csa_offload_event;
16739 
16740 	if (QDF_STATUS_SUCCESS != scheduler_post_message(QDF_MODULE_ID_SME,
16741 							 QDF_MODULE_ID_PE,
16742 							 QDF_MODULE_ID_PE,
16743 							 &msg)) {
16744 		qdf_mem_free(csa_offload_event);
16745 		sme_err("Not able to post WMA_CSA_OFFLOAD_EVENT to PE");
16746 		return QDF_STATUS_E_FAILURE;
16747 	}
16748 
16749 	return QDF_STATUS_SUCCESS;
16750 }
16751 
16752 #ifdef WLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE
sme_send_set_mac_addr(struct qdf_mac_addr mac_addr,struct qdf_mac_addr mld_addr,struct wlan_objmgr_vdev * vdev)16753 QDF_STATUS sme_send_set_mac_addr(struct qdf_mac_addr mac_addr,
16754 				 struct qdf_mac_addr mld_addr,
16755 				 struct wlan_objmgr_vdev *vdev)
16756 {
16757 	enum QDF_OPMODE vdev_opmode;
16758 	QDF_STATUS status;
16759 	struct vdev_mlme_obj *vdev_mlme;
16760 
16761 	if (!vdev) {
16762 		sme_err("Invalid VDEV");
16763 		return QDF_STATUS_E_INVAL;
16764 	}
16765 
16766 	vdev_opmode = wlan_vdev_mlme_get_opmode(vdev);
16767 
16768 	if (vdev_opmode == QDF_P2P_DEVICE_MODE) {
16769 		status = wma_p2p_self_peer_remove(vdev);
16770 		if (QDF_IS_STATUS_ERROR(status))
16771 			return status;
16772 	}
16773 
16774 	status = wlan_vdev_mlme_send_set_mac_addr(mac_addr, mld_addr, vdev);
16775 	if (QDF_IS_STATUS_SUCCESS(status))
16776 		return status;
16777 
16778 	/**
16779 	 * Failed to send set MAC address command to FW. Create P2P self peer
16780 	 * again with old MAC address
16781 	 */
16782 	if (vdev_opmode == QDF_P2P_DEVICE_MODE) {
16783 		vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev);
16784 		if (!vdev_mlme) {
16785 			sme_err("Invalid vdev MLME context");
16786 			return QDF_STATUS_E_INVAL;
16787 		}
16788 
16789 		status = wma_vdev_self_peer_create(vdev_mlme);
16790 		if (QDF_IS_STATUS_ERROR(status)) {
16791 			sme_nofl_err("Failed to create self peer for P2P device mode. Status:%d",
16792 				     status);
16793 			return QDF_STATUS_E_INVAL;
16794 		}
16795 	}
16796 
16797 	return QDF_STATUS_E_INVAL;
16798 }
16799 
sme_update_vdev_mac_addr(struct wlan_objmgr_vdev * vdev,struct qdf_mac_addr mac_addr,struct qdf_mac_addr mld_addr,bool update_sta_self_peer,bool update_mld_addr,int req_status)16800 QDF_STATUS sme_update_vdev_mac_addr(struct wlan_objmgr_vdev *vdev,
16801 				    struct qdf_mac_addr mac_addr,
16802 				    struct qdf_mac_addr mld_addr,
16803 				    bool update_sta_self_peer,
16804 				    bool update_mld_addr, int req_status)
16805 {
16806 	enum QDF_OPMODE vdev_opmode;
16807 	uint8_t *old_macaddr, *new_macaddr;
16808 	QDF_STATUS qdf_ret_status;
16809 	struct wlan_objmgr_peer *peer;
16810 	struct vdev_mlme_obj *vdev_mlme;
16811 	struct wlan_objmgr_psoc *psoc;
16812 
16813 	psoc = wlan_vdev_get_psoc(vdev);
16814 
16815 	vdev_opmode = wlan_vdev_mlme_get_opmode(vdev);
16816 
16817 	if (req_status)
16818 		goto p2p_self_peer_create;
16819 
16820 	if (vdev_opmode == QDF_STA_MODE && update_sta_self_peer) {
16821 		if (update_mld_addr) {
16822 			old_macaddr = wlan_vdev_mlme_get_mldaddr(vdev);
16823 			new_macaddr = mld_addr.bytes;
16824 		} else {
16825 			old_macaddr = wlan_vdev_mlme_get_macaddr(vdev);
16826 			new_macaddr = mac_addr.bytes;
16827 		}
16828 
16829 		/* Update self peer MAC address */
16830 		peer = wlan_objmgr_get_peer_by_mac(psoc, old_macaddr,
16831 						   WLAN_MLME_NB_ID);
16832 		if (peer) {
16833 			qdf_ret_status = wlan_peer_update_macaddr(peer,
16834 								  new_macaddr);
16835 			wlan_objmgr_peer_release_ref(peer, WLAN_MLME_NB_ID);
16836 			if (QDF_IS_STATUS_ERROR(qdf_ret_status)) {
16837 				sme_nofl_err("Failed to update self peer MAC address. Status:%d",
16838 					     qdf_ret_status);
16839 				return qdf_ret_status;
16840 			}
16841 		} else {
16842 			sme_err("Self peer not found with MAC addr:"
16843 				QDF_MAC_ADDR_FMT,
16844 				QDF_MAC_ADDR_REF(old_macaddr));
16845 				return QDF_STATUS_E_INVAL;
16846 		}
16847 	}
16848 
16849 	/* Update VDEV MAC address */
16850 	if (update_mld_addr) {
16851 		if (update_sta_self_peer || vdev_opmode == QDF_SAP_MODE) {
16852 			qdf_ret_status = wlan_mlo_mgr_update_mld_addr(
16853 					    (struct qdf_mac_addr *)
16854 					       wlan_vdev_mlme_get_mldaddr(vdev),
16855 					    &mld_addr);
16856 			if (QDF_IS_STATUS_ERROR(qdf_ret_status))
16857 				return qdf_ret_status;
16858 		}
16859 		wlan_vdev_mlme_set_mldaddr(vdev, mld_addr.bytes);
16860 	}
16861 	wlan_vdev_mlme_set_macaddr(vdev, mac_addr.bytes);
16862 	wlan_vdev_mlme_set_linkaddr(vdev, mac_addr.bytes);
16863 
16864 	ucfg_vdev_mgr_cdp_vdev_attach(vdev);
16865 p2p_self_peer_create:
16866 	if (vdev_opmode == QDF_P2P_DEVICE_MODE) {
16867 		vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev);
16868 		if (!vdev_mlme) {
16869 			sme_err("Invalid vdev MLME context");
16870 			return QDF_STATUS_E_INVAL;
16871 		}
16872 
16873 		qdf_ret_status = wma_vdev_self_peer_create(vdev_mlme);
16874 		if (QDF_IS_STATUS_ERROR(qdf_ret_status)) {
16875 			sme_nofl_err("Failed to create self peer for P2P device mode. Status:%d",
16876 				     qdf_ret_status);
16877 			return QDF_STATUS_E_INVAL;
16878 		}
16879 	}
16880 	return QDF_STATUS_SUCCESS;
16881 }
16882 #endif
16883 
sme_send_start_bss_msg(struct mac_context * mac,struct start_bss_config * cfg)16884 static QDF_STATUS sme_send_start_bss_msg(struct mac_context *mac,
16885 					 struct start_bss_config *cfg)
16886 {
16887 	struct scheduler_msg msg = {0};
16888 	struct start_bss_config *start_bss_cfg;
16889 	struct start_bss_rsp rsp;
16890 
16891 	if (!cfg)
16892 		return QDF_STATUS_E_FAILURE;
16893 
16894 	csr_roam_state_change(mac, eCSR_ROAMING_STATE_JOINING, cfg->vdev_id);
16895 	csr_roam_substate_change(mac, eCSR_ROAM_SUBSTATE_START_BSS_REQ,
16896 				 cfg->vdev_id);
16897 
16898 	start_bss_cfg = qdf_mem_malloc(sizeof(*start_bss_cfg));
16899 	if (!start_bss_cfg)
16900 		return QDF_STATUS_E_NOMEM;
16901 
16902 	qdf_mem_copy(start_bss_cfg, cfg, sizeof(*start_bss_cfg));
16903 	msg.type =  eWNI_SME_START_BSS_REQ;
16904 	msg.bodyptr = start_bss_cfg;
16905 	msg.reserved = 0;
16906 
16907 	if (QDF_STATUS_SUCCESS != scheduler_post_message(QDF_MODULE_ID_SME,
16908 							 QDF_MODULE_ID_PE,
16909 							 QDF_MODULE_ID_PE,
16910 							 &msg))
16911 		goto failure;
16912 
16913 	return QDF_STATUS_SUCCESS;
16914 failure:
16915 	sme_err("Failed to post start bss request to PE for vdev : %d",
16916 		start_bss_cfg->vdev_id);
16917 	csr_process_sap_response(mac, CSR_SAP_START_BSS_FAILURE, &rsp,
16918 				 start_bss_cfg->vdev_id);
16919 	qdf_mem_free(start_bss_cfg);
16920 	return QDF_STATUS_E_FAILURE;
16921 }
16922 
sme_send_stop_bss_msg(struct mac_context * mac,struct stop_bss_req * cfg)16923 static QDF_STATUS sme_send_stop_bss_msg(struct mac_context *mac,
16924 					struct stop_bss_req *cfg)
16925 {
16926 	struct scheduler_msg msg = {0};
16927 	struct stop_bss_req *stop_bss_req;
16928 
16929 	csr_roam_state_change(mac, eCSR_ROAMING_STATE_JOINING, cfg->vdev_id);
16930 	csr_roam_substate_change(mac, eCSR_ROAM_SUBSTATE_STOP_BSS_REQ,
16931 				 cfg->vdev_id);
16932 
16933 	sme_err("Stop bss request received for vdev : %d cmd_id : %d",
16934 		cfg->vdev_id, cfg->cmd_id);
16935 
16936 	stop_bss_req = qdf_mem_malloc(sizeof(*stop_bss_req));
16937 	if (!stop_bss_req)
16938 		return QDF_STATUS_E_NOMEM;
16939 
16940 	qdf_mem_copy(stop_bss_req, cfg, sizeof(*stop_bss_req));
16941 
16942 	msg.type = eWNI_SME_STOP_BSS_REQ;
16943 	msg.bodyptr = stop_bss_req;
16944 	msg.reserved = 0;
16945 
16946 	if (QDF_STATUS_SUCCESS != scheduler_post_message(QDF_MODULE_ID_SME,
16947 							 QDF_MODULE_ID_PE,
16948 							 QDF_MODULE_ID_PE,
16949 							 &msg)) {
16950 		sme_err("Failed to post stop bss request for vdev id : %d",
16951 			cfg->vdev_id);
16952 		qdf_mem_free(stop_bss_req);
16953 		return QDF_STATUS_E_FAILURE;
16954 	}
16955 	return QDF_STATUS_SUCCESS;
16956 }
16957 
sme_sap_activate_cmd(struct wlan_serialization_command * cmd)16958 static QDF_STATUS sme_sap_activate_cmd(struct wlan_serialization_command *cmd)
16959 {
16960 	QDF_STATUS status = QDF_STATUS_SUCCESS;
16961 	mac_handle_t mac_handle;
16962 	struct mac_context *mac;
16963 
16964 	mac_handle = cds_get_context(QDF_MODULE_ID_SME);
16965 	mac = MAC_CONTEXT(mac_handle);
16966 	if (!mac) {
16967 		QDF_ASSERT(0);
16968 		return QDF_STATUS_E_INVAL;
16969 	}
16970 
16971 	switch (cmd->cmd_type) {
16972 	case WLAN_SER_CMD_VDEV_START_BSS:
16973 		status = sme_send_start_bss_msg(mac, cmd->umac_cmd);
16974 		break;
16975 	case WLAN_SER_CMD_VDEV_STOP_BSS:
16976 		status = sme_send_stop_bss_msg(mac, cmd->umac_cmd);
16977 		break;
16978 	default:
16979 		status = QDF_STATUS_E_FAILURE;
16980 		break;
16981 	}
16982 	return status;
16983 }
16984 
sme_sap_ser_callback(struct wlan_serialization_command * cmd,enum wlan_serialization_cb_reason reason)16985 QDF_STATUS sme_sap_ser_callback(struct wlan_serialization_command *cmd,
16986 				enum wlan_serialization_cb_reason reason)
16987 {
16988 	QDF_STATUS status = QDF_STATUS_SUCCESS;
16989 	mac_handle_t mac_handle;
16990 	struct mac_context *mac_ctx;
16991 
16992 	if (!cmd) {
16993 		sme_err("Invalid Serialization command");
16994 		return QDF_STATUS_E_FAILURE;
16995 	}
16996 
16997 	mac_handle = cds_get_context(QDF_MODULE_ID_SME);
16998 	if (mac_handle)
16999 		mac_ctx = MAC_CONTEXT(mac_handle);
17000 	else
17001 		return QDF_STATUS_E_FAILURE;
17002 
17003 	switch (reason) {
17004 	case WLAN_SER_CB_ACTIVATE_CMD:
17005 		status = sme_sap_activate_cmd(cmd);
17006 		break;
17007 	case WLAN_SER_CB_CANCEL_CMD:
17008 		break;
17009 	case WLAN_SER_CB_RELEASE_MEM_CMD:
17010 		if (cmd->vdev)
17011 			wlan_objmgr_vdev_release_ref(cmd->vdev,
17012 						     WLAN_LEGACY_MAC_ID);
17013 		if (cmd->umac_cmd)
17014 			qdf_mem_free(cmd->umac_cmd);
17015 		break;
17016 	case WLAN_SER_CB_ACTIVE_CMD_TIMEOUT:
17017 		qdf_trigger_self_recovery(mac_ctx->psoc,
17018 					  QDF_ACTIVE_LIST_TIMEOUT);
17019 		break;
17020 	default:
17021 		sme_debug("unknown reason code");
17022 		return QDF_STATUS_E_FAILURE;
17023 	}
17024 	return status;
17025 }
17026 
sme_fill_channel_change_request(mac_handle_t mac_handle,struct channel_change_req * req,eCsrPhyMode phy_mode)17027 void sme_fill_channel_change_request(mac_handle_t mac_handle,
17028 				     struct channel_change_req *req,
17029 				     eCsrPhyMode phy_mode)
17030 {
17031 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
17032 	struct bss_dot11_config dot11_cfg = {0};
17033 
17034 	dot11_cfg.vdev_id = req->vdev_id;
17035 	dot11_cfg.bss_op_ch_freq = req->target_chan_freq;
17036 	dot11_cfg.phy_mode = phy_mode;
17037 
17038 	sme_get_network_params(mac_ctx, &dot11_cfg);
17039 
17040 	req->dot11mode = dot11_cfg.dot11_mode;
17041 	req->nw_type = dot11_cfg.nw_type;
17042 
17043 	if (dot11_cfg.opr_rates.numRates) {
17044 		qdf_mem_copy(req->opr_rates.rate,
17045 			     dot11_cfg.opr_rates.rate,
17046 			     dot11_cfg.opr_rates.numRates);
17047 		req->opr_rates.numRates =
17048 				dot11_cfg.opr_rates.numRates;
17049 	}
17050 
17051 	if (dot11_cfg.ext_rates.numRates) {
17052 		qdf_mem_copy(req->ext_rates.rate,
17053 			     dot11_cfg.ext_rates.rate,
17054 			     dot11_cfg.ext_rates.numRates);
17055 		req->ext_rates.numRates =
17056 				dot11_cfg.ext_rates.numRates;
17057 	}
17058 }
17059 
sme_update_beacon_country_ie(mac_handle_t mac_handle,uint8_t vdev_id,bool country_ie_for_all_band)17060 QDF_STATUS sme_update_beacon_country_ie(mac_handle_t mac_handle,
17061 					uint8_t vdev_id,
17062 					bool country_ie_for_all_band)
17063 {
17064 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
17065 	struct wlan_objmgr_vdev *vdev;
17066 	struct mlme_legacy_priv *mlme_priv;
17067 
17068 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac->psoc, vdev_id,
17069 						    WLAN_MLME_NB_ID);
17070 	if (!vdev) {
17071 		sme_err("vdev object is NULL for vdev_id %d", vdev_id);
17072 		return QDF_STATUS_E_FAILURE;
17073 	}
17074 
17075 	mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev);
17076 	if (!mlme_priv) {
17077 		wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_NB_ID);
17078 		return QDF_STATUS_E_FAILURE;
17079 	}
17080 
17081 	mlme_priv->country_ie_for_all_band = country_ie_for_all_band;
17082 	wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_NB_ID);
17083 
17084 	csr_update_beacon(mac);
17085 
17086 	return QDF_STATUS_SUCCESS;
17087 }
17088 
17089 QDF_STATUS
sme_send_multi_pdev_vdev_set_params(enum mlme_dev_setparam param_type,uint8_t dev_id,struct dev_set_param * param,uint8_t max_index)17090 sme_send_multi_pdev_vdev_set_params(enum mlme_dev_setparam param_type,
17091 				    uint8_t dev_id,
17092 				    struct dev_set_param *param,
17093 				    uint8_t max_index)
17094 {
17095 	return wma_send_multi_pdev_vdev_set_params(param_type, dev_id, param,
17096 						   max_index);
17097 }
17098 
17099 QDF_STATUS
sme_validate_txrx_chain_mask(uint32_t id,uint32_t value)17100 sme_validate_txrx_chain_mask(uint32_t id, uint32_t value)
17101 {
17102 	return wma_validate_txrx_chain_mask(id, value);
17103 }
17104