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