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(¶ms, client_id_bitmap, force_reset);
7540
7541 status = wma_set_wlm_latency_level(wma, ¶ms);
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(¶m_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(¶ms->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