blob: 98a1f2607fc9eb795a21e6a8b6f7b78bacb9237b [file] [log] [blame]
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001/*
2 * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
3 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21
22/*
23 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
26 */
27
28/**=========================================================================
29
30 \file smeApi.c
31
32 \brief Definitions for SME APIs
33
34 ========================================================================*/
35
36/*--------------------------------------------------------------------------
37 Include Files
38 ------------------------------------------------------------------------*/
39
40#include "sms_debug.h"
41#include "sme_api.h"
42#include "csr_inside_api.h"
43#include "sme_inside.h"
44#include "csr_internal.h"
45#include "wma_types.h"
46#include "wma_if.h"
47#include "cdf_trace.h"
48#include "sme_trace.h"
49#include "cdf_types.h"
50#include "cdf_trace.h"
51#include "cds_utils.h"
52#include "sap_api.h"
53#include "mac_trace.h"
54#ifdef WLAN_FEATURE_NAN
55#include "nan_api.h"
56#endif
57#include "cds_regdomain_common.h"
58#include "cfg_api.h"
59#include "sme_power_save_api.h"
60#include "wma.h"
61
62extern tSirRetStatus u_mac_post_ctrl_msg(void *pSirGlobal, tSirMbMsg *pMb);
63
64#define LOG_SIZE 256
65#define READ_MEMORY_DUMP_CMD 9
66#define TL_INIT_STATE 0
67
68static tSelfRecoveryStats g_self_recovery_stats;
69/* TxMB Functions */
70extern CDF_STATUS pmc_prepare_command(tpAniSirGlobal pMac, uint32_t sessionId,
71 eSmeCommandType cmdType, void *pvParam,
72 uint32_t size, tSmeCmd **ppCmd);
73extern void pmc_release_command(tpAniSirGlobal pMac, tSmeCmd *pCommand);
74extern void qos_release_command(tpAniSirGlobal pMac, tSmeCmd *pCommand);
75extern CDF_STATUS p2p_process_remain_on_channel_cmd(tpAniSirGlobal pMac,
76 tSmeCmd *p2pRemainonChn);
77extern CDF_STATUS sme_remain_on_chn_rsp(tpAniSirGlobal pMac, uint8_t *pMsg);
78extern CDF_STATUS sme_mgmt_frm_ind(tHalHandle hHal,
79 tpSirSmeMgmtFrameInd pSmeMgmtFrm);
80extern CDF_STATUS sme_remain_on_chn_ready(tHalHandle hHal, uint8_t *pMsg);
81extern CDF_STATUS sme_send_action_cnf(tHalHandle hHal, uint8_t *pMsg);
82
83static CDF_STATUS init_sme_cmd_list(tpAniSirGlobal pMac);
84static void sme_abort_command(tpAniSirGlobal pMac, tSmeCmd *pCommand,
85 bool fStopping);
86
87eCsrPhyMode sme_get_phy_mode(tHalHandle hHal);
88
89CDF_STATUS sme_handle_change_country_code(tpAniSirGlobal pMac, void *pMsgBuf);
90
91void sme_disconnect_connected_sessions(tpAniSirGlobal pMac);
92
93CDF_STATUS sme_handle_generic_change_country_code(tpAniSirGlobal pMac,
94 void *pMsgBuf);
95
96CDF_STATUS sme_process_nss_update_resp(tpAniSirGlobal mac, uint8_t *msg);
97
98#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
99bool csr_is_supported_channel(tpAniSirGlobal pMac, uint8_t channelId);
100#endif
101
102#ifdef WLAN_FEATURE_11W
103CDF_STATUS sme_unprotected_mgmt_frm_ind(tHalHandle hHal,
104 tpSirSmeUnprotMgmtFrameInd pSmeMgmtFrm);
105#endif
106
107/* Message processor for events from DFS */
108CDF_STATUS dfs_msg_processor(tpAniSirGlobal pMac,
109 uint16_t msg_type, void *pMsgBuf);
110
111/* Channel Change Response Indication Handler */
112CDF_STATUS sme_process_channel_change_resp(tpAniSirGlobal pMac,
113 uint16_t msg_type, void *pMsgBuf);
114
115/* Internal SME APIs */
116CDF_STATUS sme_acquire_global_lock(tSmeStruct *psSme)
117{
118 CDF_STATUS status = CDF_STATUS_E_INVAL;
119
120 if (psSme) {
121 if (CDF_IS_STATUS_SUCCESS
122 (cdf_mutex_acquire(&psSme->lkSmeGlobalLock))) {
123 status = CDF_STATUS_SUCCESS;
124 }
125 }
126
127 return status;
128}
129
130CDF_STATUS sme_release_global_lock(tSmeStruct *psSme)
131{
132 CDF_STATUS status = CDF_STATUS_E_INVAL;
133
134 if (psSme) {
135 if (CDF_IS_STATUS_SUCCESS
136 (cdf_mutex_release(&psSme->lkSmeGlobalLock))) {
137 status = CDF_STATUS_SUCCESS;
138 }
139 }
140
141 return status;
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 */
152static CDF_STATUS sme_process_set_hw_mode_resp(tpAniSirGlobal mac, uint8_t *msg)
153{
154 tListElem *entry = NULL;
155 tSmeCmd *command = NULL;
156 bool found;
157 hw_mode_cb callback = NULL;
158 struct sir_set_hw_mode_resp *param;
159
160 param = (struct sir_set_hw_mode_resp *)msg;
161 if (!param) {
162 sms_log(mac, LOGE, FL("HW mode resp param is NULL"));
163 /* Not returning. Need to check if active command list
164 * needs to be freed
165 */
166 }
167
168 entry = csr_ll_peek_head(&mac->sme.smeCmdActiveList,
169 LL_ACCESS_LOCK);
170 if (!entry) {
171 sms_log(mac, LOGE, FL("No cmd found in active list"));
172 return CDF_STATUS_E_FAILURE;
173 }
174
175 command = GET_BASE_ADDR(entry, tSmeCmd, Link);
176 if (!command) {
177 sms_log(mac, LOGE, FL("Base address is NULL"));
178 return CDF_STATUS_E_FAILURE;
179 }
180
181 if (e_sme_command_set_hw_mode != command->command) {
182 sms_log(mac, LOGE, FL("Command mismatch!"));
183 return CDF_STATUS_E_FAILURE;
184 }
185
186 callback = command->u.set_hw_mode_cmd.set_hw_mode_cb;
187 if (callback) {
188 if (!param) {
189 sms_log(mac, LOGE,
190 FL("Callback failed since HW mode params is NULL"));
191 } else {
192 sms_log(mac, LOGE,
193 FL("Calling HDD callback for HW mode response"));
194 callback(param->status,
195 param->cfgd_hw_mode_index,
196 param->num_vdev_mac_entries,
197 param->vdev_mac_map);
198 }
199 } else {
200 sms_log(mac, LOGE, FL("Callback does not exist"));
201 }
202
203 found = csr_ll_remove_entry(&mac->sme.smeCmdActiveList, entry,
204 LL_ACCESS_LOCK);
205 if (found) {
206 /* Now put this command back on the avilable command list */
207 sme_release_command(mac, command);
208 }
209 sme_process_pending_queue(mac);
210 return CDF_STATUS_SUCCESS;
211}
212
213/**
214 * sme_process_hw_mode_trans_ind() - Process HW mode transition indication
215 * @mac: Global MAC pointer
216 * @msg: HW mode transition response
217 *
218 * Processes the HW mode transition indication and invoke the HDD callback
219 * to process further
220 */
221static CDF_STATUS sme_process_hw_mode_trans_ind(tpAniSirGlobal mac,
222 uint8_t *msg)
223{
224 hw_mode_transition_cb callback = NULL;
225 struct sir_hw_mode_trans_ind *param;
226
227 param = (struct sir_hw_mode_trans_ind *)msg;
228 if (!param) {
229 sms_log(mac, LOGE, FL("HW mode trans ind param is NULL"));
230 return CDF_STATUS_E_FAILURE;
231 }
232
233 callback = mac->sme.sme_hw_mode_trans_cb;
234 if (callback) {
235 sms_log(mac, LOGE, FL("Calling registered callback..."));
236 callback(param->old_hw_mode_index,
237 param->new_hw_mode_index,
238 param->num_vdev_mac_entries,
239 param->vdev_mac_map);
240 }
241
242 return CDF_STATUS_SUCCESS;
243}
244
245static CDF_STATUS init_sme_cmd_list(tpAniSirGlobal pMac)
246{
247 CDF_STATUS status;
248 tSmeCmd *pCmd;
249 uint32_t cmd_idx;
250 CDF_STATUS cdf_status;
251 cdf_mc_timer_t *cmdTimeoutTimer = NULL;
252
253 pMac->sme.totalSmeCmd = SME_TOTAL_COMMAND;
254
255 status = csr_ll_open(pMac->hHdd, &pMac->sme.smeCmdActiveList);
256 if (!CDF_IS_STATUS_SUCCESS(status))
257 goto end;
258
259 status = csr_ll_open(pMac->hHdd, &pMac->sme.smeCmdPendingList);
260 if (!CDF_IS_STATUS_SUCCESS(status))
261 goto end;
262
263 status = csr_ll_open(pMac->hHdd, &pMac->sme.smeScanCmdActiveList);
264 if (!CDF_IS_STATUS_SUCCESS(status))
265 goto end;
266
267 status = csr_ll_open(pMac->hHdd, &pMac->sme.smeScanCmdPendingList);
268 if (!CDF_IS_STATUS_SUCCESS(status))
269 goto end;
270
271 status = csr_ll_open(pMac->hHdd, &pMac->sme.smeCmdFreeList);
272 if (!CDF_IS_STATUS_SUCCESS(status))
273 goto end;
274
275 pCmd = cdf_mem_malloc(sizeof(tSmeCmd) * pMac->sme.totalSmeCmd);
276 if (NULL == pCmd)
277 status = CDF_STATUS_E_NOMEM;
278 else {
279 status = CDF_STATUS_SUCCESS;
280
281 cdf_mem_set(pCmd, sizeof(tSmeCmd) * pMac->sme.totalSmeCmd, 0);
282 pMac->sme.pSmeCmdBufAddr = pCmd;
283
284 for (cmd_idx = 0; cmd_idx < pMac->sme.totalSmeCmd; cmd_idx++) {
285 csr_ll_insert_tail(&pMac->sme.smeCmdFreeList,
286 &pCmd[cmd_idx].Link, LL_ACCESS_LOCK);
287 }
288 }
289
290 /* This timer is only to debug the active list command timeout */
291
292 cmdTimeoutTimer =
293 (cdf_mc_timer_t *) cdf_mem_malloc(sizeof(cdf_mc_timer_t));
294 if (cmdTimeoutTimer) {
295 pMac->sme.smeCmdActiveList.cmdTimeoutTimer = cmdTimeoutTimer;
296 cdf_status =
297 cdf_mc_timer_init(pMac->sme.smeCmdActiveList.
298 cmdTimeoutTimer, CDF_TIMER_TYPE_SW,
299 active_list_cmd_timeout_handle, (void *)pMac);
300
301 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
302 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
303 "Init Timer fail for active list command process time out");
304 cdf_mem_free(pMac->sme.smeCmdActiveList.
305 cmdTimeoutTimer);
306 pMac->sme.smeCmdActiveList.cmdTimeoutTimer = NULL;
307 } else {
308 pMac->sme.smeCmdActiveList.cmdTimeoutDuration =
309 CSR_ACTIVE_LIST_CMD_TIMEOUT_VALUE;
310 }
311 }
312
313end:
314 if (!CDF_IS_STATUS_SUCCESS(status))
315 sms_log(pMac, LOGE, "failed to initialize sme command list:%d\n",
316 status);
317
318 return status;
319}
320
321void sme_release_command(tpAniSirGlobal pMac, tSmeCmd *pCmd)
322{
323 pCmd->command = eSmeNoCommand;
324 csr_ll_insert_tail(&pMac->sme.smeCmdFreeList, &pCmd->Link, LL_ACCESS_LOCK);
325}
326
327static void sme_release_cmd_list(tpAniSirGlobal pMac, tDblLinkList *pList)
328{
329 tListElem *pEntry;
330 tSmeCmd *pCommand;
331
332 while ((pEntry = csr_ll_remove_head(pList, LL_ACCESS_LOCK)) != NULL) {
333 /* TODO: base on command type to call release functions */
334 /* reinitialize different command types so they can be reused */
335 pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link);
336 sme_abort_command(pMac, pCommand, true);
337 }
338}
339
340static void purge_sme_cmd_list(tpAniSirGlobal pMac)
341{
342 /* release any out standing commands back to free command list */
343 sme_release_cmd_list(pMac, &pMac->sme.smeCmdPendingList);
344 sme_release_cmd_list(pMac, &pMac->sme.smeCmdActiveList);
345 sme_release_cmd_list(pMac, &pMac->sme.smeScanCmdPendingList);
346 sme_release_cmd_list(pMac, &pMac->sme.smeScanCmdActiveList);
347}
348
349void purge_sme_session_cmd_list(tpAniSirGlobal pMac, uint32_t sessionId,
350 tDblLinkList *pList)
351{
352 /* release any out standing commands back to free command list */
353 tListElem *pEntry, *pNext;
354 tSmeCmd *pCommand;
355 tDblLinkList localList;
356
357 cdf_mem_zero(&localList, sizeof(tDblLinkList));
358 if (!CDF_IS_STATUS_SUCCESS(csr_ll_open(pMac->hHdd, &localList))) {
359 sms_log(pMac, LOGE, FL(" failed to open list"));
360 return;
361 }
362
363 csr_ll_lock(pList);
364 pEntry = csr_ll_peek_head(pList, LL_ACCESS_NOLOCK);
365 while (pEntry != NULL) {
366 pNext = csr_ll_next(pList, pEntry, LL_ACCESS_NOLOCK);
367 pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link);
368 if (pCommand->sessionId == sessionId) {
369 if (csr_ll_remove_entry(pList, pEntry, LL_ACCESS_NOLOCK)) {
370 csr_ll_insert_tail(&localList, pEntry,
371 LL_ACCESS_NOLOCK);
372 }
373 }
374 pEntry = pNext;
375 }
376 csr_ll_unlock(pList);
377
378 while ((pEntry = csr_ll_remove_head(&localList, LL_ACCESS_NOLOCK))) {
379 pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link);
380 sme_abort_command(pMac, pCommand, true);
381 }
382 csr_ll_close(&localList);
383}
384
385static CDF_STATUS free_sme_cmd_list(tpAniSirGlobal pMac)
386{
387 CDF_STATUS status = CDF_STATUS_SUCCESS;
388
389 purge_sme_cmd_list(pMac);
390 csr_ll_close(&pMac->sme.smeCmdPendingList);
391 csr_ll_close(&pMac->sme.smeCmdActiveList);
392 csr_ll_close(&pMac->sme.smeScanCmdPendingList);
393 csr_ll_close(&pMac->sme.smeScanCmdActiveList);
394 csr_ll_close(&pMac->sme.smeCmdFreeList);
395
396 /*destroy active list command time out timer */
397 cdf_mc_timer_destroy(pMac->sme.smeCmdActiveList.cmdTimeoutTimer);
398 cdf_mem_free(pMac->sme.smeCmdActiveList.cmdTimeoutTimer);
399 pMac->sme.smeCmdActiveList.cmdTimeoutTimer = NULL;
400
401 status = cdf_mutex_acquire(&pMac->sme.lkSmeGlobalLock);
402 if (status != CDF_STATUS_SUCCESS) {
403 sms_log(pMac, LOGE,
404 FL("Failed to acquire the lock status = %d"), status);
405 goto done;
406 }
407
408 if (NULL != pMac->sme.pSmeCmdBufAddr) {
409 cdf_mem_free(pMac->sme.pSmeCmdBufAddr);
410 pMac->sme.pSmeCmdBufAddr = NULL;
411 }
412
413 status = cdf_mutex_release(&pMac->sme.lkSmeGlobalLock);
414 if (status != CDF_STATUS_SUCCESS) {
415 sms_log(pMac, LOGE,
416 FL("Failed to release the lock status = %d"), status);
417 }
418done:
419 return status;
420}
421
422void dump_csr_command_info(tpAniSirGlobal pMac, tSmeCmd *pCmd)
423{
424 switch (pCmd->command) {
425 case eSmeCommandScan:
426 sms_log(pMac, LOGE, " scan command reason is %d",
427 pCmd->u.scanCmd.reason);
428 break;
429
430 case eSmeCommandRoam:
431 sms_log(pMac, LOGE, " roam command reason is %d",
432 pCmd->u.roamCmd.roamReason);
433 break;
434
435 case eSmeCommandWmStatusChange:
436 sms_log(pMac, LOGE, " WMStatusChange command type is %d",
437 pCmd->u.wmStatusChangeCmd.Type);
438 break;
439
440 case eSmeCommandSetKey:
441 sms_log(pMac, LOGE, " setKey command auth(%d) enc(%d)",
442 pCmd->u.setKeyCmd.authType, pCmd->u.setKeyCmd.encType);
443 break;
444
445 default:
446 sms_log(pMac, LOGE, " default: Unhandled command %d",
447 pCmd->command);
448 break;
449 }
450}
451
452tSmeCmd *sme_get_command_buffer(tpAniSirGlobal pMac)
453{
454 tSmeCmd *pRetCmd = NULL, *pTempCmd = NULL;
455 tListElem *pEntry;
456 static int sme_command_queue_full;
457
458 pEntry = csr_ll_remove_head(&pMac->sme.smeCmdFreeList, LL_ACCESS_LOCK);
459
460 /* If we can get another MS Msg buffer, then we are ok. Just link */
461 /* the entry onto the linked list. (We are using the linked list */
462 /* to keep track of tfhe message buffers). */
463 if (pEntry) {
464 pRetCmd = GET_BASE_ADDR(pEntry, tSmeCmd, Link);
465 /* reset when free list is available */
466 sme_command_queue_full = 0;
467 } else {
468 int idx = 1;
469
470 /* Cannot change pRetCmd here since it needs to return later. */
471 pEntry =
472 csr_ll_peek_head(&pMac->sme.smeCmdActiveList, LL_ACCESS_LOCK);
473 if (pEntry) {
474 pTempCmd = GET_BASE_ADDR(pEntry, tSmeCmd, Link);
475 }
476 sms_log(pMac, LOGE,
477 "Out of command buffer.... command (0x%X) stuck",
478 (pTempCmd) ? pTempCmd->command : eSmeNoCommand);
479 if (pTempCmd) {
480 if (eSmeCsrCommandMask & pTempCmd->command) {
481 /* CSR command is stuck. See what the reason code is for that command */
482 dump_csr_command_info(pMac, pTempCmd);
483 }
484 } /* if(pTempCmd) */
485
486 /* dump what is in the pending queue */
487 csr_ll_lock(&pMac->sme.smeCmdPendingList);
488 pEntry =
489 csr_ll_peek_head(&pMac->sme.smeCmdPendingList,
490 LL_ACCESS_NOLOCK);
491 while (pEntry && !sme_command_queue_full) {
492 pTempCmd = GET_BASE_ADDR(pEntry, tSmeCmd, Link);
493 /* Print only 1st five commands from pending queue. */
494 if (idx <= 5)
495 sms_log(pMac, LOGE,
496 "Out of command buffer.... SME pending command #%d (0x%X)",
497 idx, pTempCmd->command);
498 idx++;
499 if (eSmeCsrCommandMask & pTempCmd->command) {
500 /* CSR command is stuck. See what the reason code is for that command */
501 dump_csr_command_info(pMac, pTempCmd);
502 }
503 pEntry =
504 csr_ll_next(&pMac->sme.smeCmdPendingList, pEntry,
505 LL_ACCESS_NOLOCK);
506 }
507 /* Increment static variable so that it prints
508 * pending command only once
509 */
510 sme_command_queue_full++;
511
512 csr_ll_unlock(&pMac->sme.smeCmdPendingList);
513
514 /* There may be some more command in CSR's own pending queue */
515 csr_ll_lock(&pMac->roam.roamCmdPendingList);
516 pEntry =
517 csr_ll_peek_head(&pMac->roam.roamCmdPendingList,
518 LL_ACCESS_NOLOCK);
519 while (pEntry) {
520 pTempCmd = GET_BASE_ADDR(pEntry, tSmeCmd, Link);
521 sms_log(pMac, LOGE,
522 "Out of command buffer.... CSR pending command #%d (0x%X)",
523 idx++, pTempCmd->command);
524 dump_csr_command_info(pMac, pTempCmd);
525 pEntry =
526 csr_ll_next(&pMac->roam.roamCmdPendingList, pEntry,
527 LL_ACCESS_NOLOCK);
528 }
529 csr_ll_unlock(&pMac->roam.roamCmdPendingList);
530 }
531
532 /* memset to zero */
533 if (pRetCmd) {
534 cdf_mem_set((uint8_t *)&pRetCmd->command,
535 sizeof(pRetCmd->command), 0);
536 cdf_mem_set((uint8_t *)&pRetCmd->sessionId,
537 sizeof(pRetCmd->sessionId), 0);
538 cdf_mem_set((uint8_t *)&pRetCmd->u, sizeof(pRetCmd->u), 0);
539 }
540
541 return pRetCmd;
542}
543
544void sme_push_command(tpAniSirGlobal pMac, tSmeCmd *pCmd, bool fHighPriority)
545{
546 if (!SME_IS_START(pMac)) {
547 sms_log(pMac, LOGE, FL("Sme in stop state"));
548 CDF_ASSERT(0);
549 return;
550 }
551
552 if (fHighPriority) {
553 csr_ll_insert_head(&pMac->sme.smeCmdPendingList, &pCmd->Link,
554 LL_ACCESS_LOCK);
555 } else {
556 csr_ll_insert_tail(&pMac->sme.smeCmdPendingList, &pCmd->Link,
557 LL_ACCESS_LOCK);
558 }
559
560 /* process the command queue... */
561 sme_process_pending_queue(pMac);
562
563 return;
564}
565
566/* For commands that need to do extra cleanup. */
567static void sme_abort_command(tpAniSirGlobal pMac, tSmeCmd *pCommand,
568 bool fStopping)
569{
570 if (eSmePmcCommandMask & pCommand->command) {
571 sms_log(pMac, LOG1,
572 "No need to process PMC commands");
573 return;
574 }
575 if (eSmeCsrCommandMask & pCommand->command) {
576 csr_abort_command(pMac, pCommand, fStopping);
577 return;
578 }
579 switch (pCommand->command) {
580 case eSmeCommandRemainOnChannel:
581 if (NULL != pCommand->u.remainChlCmd.callback) {
582 remainOnChanCallback callback =
583 pCommand->u.remainChlCmd.callback;
584 /* process the msg */
585 if (callback) {
586 callback(pMac, pCommand->u.remainChlCmd.
587 callbackCtx, eCSR_SCAN_ABORT,
588 pCommand->u.remainChlCmd.scan_id);
589 }
590 }
591 sme_release_command(pMac, pCommand);
592 break;
593 default:
594 sme_release_command(pMac, pCommand);
595 break;
596 }
597
598}
599
600tListElem *csr_get_cmd_to_process(tpAniSirGlobal pMac, tDblLinkList *pList,
601 uint8_t sessionId, bool fInterlocked)
602{
603 tListElem *pCurEntry = NULL;
604 tSmeCmd *pCommand;
605
606 /* Go through the list and return the command whose session id is not
607 * matching with the current ongoing scan cmd sessionId */
608 pCurEntry = csr_ll_peek_head(pList, LL_ACCESS_LOCK);
609 while (pCurEntry) {
610 pCommand = GET_BASE_ADDR(pCurEntry, tSmeCmd, Link);
611 if (pCommand->sessionId != sessionId) {
612 sms_log(pMac, LOG1,
613 "selected the command with different sessionId");
614 return pCurEntry;
615 }
616
617 pCurEntry = csr_ll_next(pList, pCurEntry, fInterlocked);
618 }
619
620 sms_log(pMac, LOG1, "No command pending with different sessionId");
621 return NULL;
622}
623
624bool sme_process_scan_queue(tpAniSirGlobal pMac)
625{
626 tListElem *pEntry;
627 tSmeCmd *pCommand;
628 tListElem *pSmeEntry = NULL;
629 tSmeCmd *pSmeCommand = NULL;
630 bool status = true;
631
632 if ((!csr_ll_is_list_empty(&pMac->sme.smeCmdActiveList,
633 LL_ACCESS_LOCK))) {
634 pSmeEntry = csr_ll_peek_head(&pMac->sme.smeCmdActiveList,
635 LL_ACCESS_LOCK);
636 if (pSmeEntry)
637 pSmeCommand = GET_BASE_ADDR(pSmeEntry, tSmeCmd, Link);
638 }
639 csr_ll_lock(&pMac->sme.smeScanCmdActiveList);
640 if (csr_ll_is_list_empty(&pMac->sme.smeScanCmdPendingList,
641 LL_ACCESS_LOCK))
642 goto end;
643 pEntry = csr_ll_peek_head(&pMac->sme.smeScanCmdPendingList,
644 LL_ACCESS_LOCK);
645 if (!pEntry)
646 goto end;
647
648 sms_log(pMac, LOGE,
649 FL("scan_count in active scanlist %d "),
650 pMac->sme.smeScanCmdActiveList.Count);
651
652 pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link);
653 if (pSmeCommand != NULL) {
654 /*
655 * if scan is running on one interface and SME receives
656 * the next command on the same interface then
657 * dont the allow the command to be queued to
658 * smeCmdPendingList. If next scan is allowed on
659 * the same interface the CSR state machine will
660 * get screwed up.
661 */
662 if (pSmeCommand->sessionId == pCommand->sessionId) {
663 status = false;
664 goto end;
665 }
666 }
667 /*
668 * We cannot execute any command in wait-for-key state until setKey is
669 * through.
670 */
671 if (CSR_IS_WAIT_FOR_KEY(pMac, pCommand->sessionId)) {
672 if (!CSR_IS_SET_KEY_COMMAND(pCommand)) {
673 sms_log(pMac, LOGE,
674 FL("Can't process cmd(%d), waiting for key"),
675 pCommand->command);
676 status = false;
677 goto end;
678 }
679 }
680 if (csr_ll_remove_entry(&pMac->sme.smeScanCmdPendingList, pEntry,
681 LL_ACCESS_LOCK)) {
682 csr_ll_insert_head(&pMac->sme.smeScanCmdActiveList,
683 &pCommand->Link, LL_ACCESS_NOLOCK);
684 switch (pCommand->command) {
685 case eSmeCommandScan:
686 sms_log(pMac, LOG1, FL("Processing scan offload cmd."));
687 cdf_mc_timer_start(&pCommand->u.scanCmd.csr_scan_timer,
688 CSR_ACTIVE_SCAN_LIST_CMD_TIMEOUT);
689 csr_process_scan_command(pMac, pCommand);
690 break;
691 case eSmeCommandRemainOnChannel:
692 sms_log(pMac, LOG1,
693 FL("Processing remain on channel offload cmd"));
694 p2p_process_remain_on_channel_cmd(pMac, pCommand);
695 break;
696 default:
697 sms_log(pMac, LOGE,
698 FL("Wrong cmd enqueued to ScanCmdPendingList"));
699 pEntry = csr_ll_remove_head(
700 &pMac->sme.smeScanCmdActiveList,
701 LL_ACCESS_NOLOCK);
702 pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link);
703 sme_release_command(pMac, pCommand);
704 break;
705 }
706 }
707end:
708 csr_ll_unlock(&pMac->sme.smeScanCmdActiveList);
709 return status;
710}
711
712/**
713 * sme_process_command() - processes SME commnd
714 * @mac_ctx: mac global context
715 *
716 * This function is called by sme_process_pending_queue() in a while loop
717 *
718 * Return: true indicates that caller function can proceed to next cmd
719 * false otherwise.
720 */
721bool sme_process_command(tpAniSirGlobal pMac)
722{
723 bool fContinue = false;
724 CDF_STATUS status = CDF_STATUS_SUCCESS;
725 tListElem *pEntry;
726 tSmeCmd *pCommand;
727 tListElem *pSmeEntry;
728 tSmeCmd *pSmeCommand;
729
730 /*
731 * if the ActiveList is empty, then nothing is active so we can process
732 * a pending command...
733 * alwasy lock active list before locking pending list
734 */
735 csr_ll_lock(&pMac->sme.smeCmdActiveList);
736 if (!csr_ll_is_list_empty(&pMac->sme.smeCmdActiveList,
737 LL_ACCESS_NOLOCK)) {
738 csr_ll_unlock(&pMac->sme.smeCmdActiveList);
739 goto process_scan_q;
740 }
741
742 if (csr_ll_is_list_empty(&pMac->sme.smeCmdPendingList,
743 LL_ACCESS_LOCK)) {
744 /* No command waiting */
745 csr_ll_unlock(&pMac->sme.smeCmdActiveList);
746 goto process_scan_q;
747 }
748
749 /*
750 * If scan command is pending in the smeScanCmdActive list then pick the
751 * command from smeCmdPendingList which is not matching with the scan
752 * command session id. At any point of time only one command will be
753 * allowed on a single session.
754 */
755 if (!csr_ll_is_list_empty(
756 &pMac->sme.smeScanCmdActiveList, LL_ACCESS_LOCK)) {
757 pSmeEntry = csr_ll_peek_head(&pMac->sme.smeScanCmdActiveList,
758 LL_ACCESS_LOCK);
759 if (pSmeEntry) {
760 pSmeCommand = GET_BASE_ADDR(pSmeEntry, tSmeCmd, Link);
761 pEntry = csr_get_cmd_to_process(pMac,
762 &pMac->sme.smeCmdPendingList,
763 pSmeCommand->sessionId,
764 LL_ACCESS_LOCK);
765 goto sme_process_cmd;
766 }
767 }
768
769 /* Peek the command */
770 pEntry = csr_ll_peek_head(&pMac->sme.smeCmdPendingList, LL_ACCESS_LOCK);
771sme_process_cmd:
772 if (!pEntry) {
773 csr_ll_unlock(&pMac->sme.smeCmdActiveList);
774 goto process_scan_q;
775 }
776 pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link);
777 /*
778 * Allow only disconnect command in wait-for-key state until setKey is
779 * through.
780 */
781 if (CSR_IS_WAIT_FOR_KEY(pMac, pCommand->sessionId)
782 && !CSR_IS_DISCONNECT_COMMAND(pCommand)
783 && !CSR_IS_SET_KEY_COMMAND(pCommand)) {
784 if (CSR_IS_CLOSE_SESSION_COMMAND(pCommand)) {
785 tSmeCmd *sme_cmd = NULL;
786
787 sms_log(pMac, LOGE,
788 FL("SessionId %d: close session command issued while waiting for key, issue disconnect first"),
789 pCommand->sessionId);
790 status = csr_prepare_disconnect_command(pMac,
791 pCommand->sessionId, &sme_cmd);
792 if (status == CDF_STATUS_SUCCESS && sme_cmd) {
793 csr_ll_lock(&pMac->sme.smeCmdPendingList);
794 csr_ll_insert_head(&pMac->sme.smeCmdPendingList,
795 &sme_cmd->Link, LL_ACCESS_NOLOCK);
796 pEntry = csr_ll_peek_head(
797 &pMac->sme.smeCmdPendingList,
798 LL_ACCESS_NOLOCK);
799 csr_ll_unlock(&pMac->sme.smeCmdPendingList);
800 goto sme_process_cmd;
801 }
802 }
803
804 csr_ll_unlock(&pMac->sme.smeCmdActiveList);
805 sms_log(pMac, LOGE,
806 FL("SessionId %d: Can't process cmd(%d), waiting for key"),
807 pCommand->sessionId, pCommand->command);
808 fContinue = false;
809 goto process_scan_q;
810 }
811
812 if (!csr_ll_remove_entry(&pMac->sme.smeCmdPendingList, pEntry,
813 LL_ACCESS_LOCK)) {
814 /* This is odd. Some one else pull off the command. */
815 csr_ll_unlock(&pMac->sme.smeCmdActiveList);
816 goto process_scan_q;
817 }
818 /* we can reuse the pCommand. Insert the command onto the ActiveList */
819 csr_ll_insert_head(&pMac->sme.smeCmdActiveList, &pCommand->Link,
820 LL_ACCESS_NOLOCK);
821 /* .... and process the command. */
822 MTRACE(cdf_trace(CDF_MODULE_ID_SME, TRACE_CODE_SME_COMMAND,
823 pCommand->sessionId, pCommand->command));
824
825 switch (pCommand->command) {
826 case eSmeCommandScan:
827 csr_ll_unlock(&pMac->sme.smeCmdActiveList);
828 status = csr_process_scan_command(pMac, pCommand);
829 break;
830 case eSmeCommandRoam:
831 csr_ll_unlock(&pMac->sme.smeCmdActiveList);
832 status = csr_roam_process_command(pMac, pCommand);
833 if (!CDF_IS_STATUS_SUCCESS(status)
834 && csr_ll_remove_entry(&pMac->sme.smeCmdActiveList,
835 &pCommand->Link, LL_ACCESS_LOCK))
836 csr_release_command_roam(pMac, pCommand);
837 break;
838 case eSmeCommandWmStatusChange:
839 csr_ll_unlock(&pMac->sme.smeCmdActiveList);
840 csr_roam_process_wm_status_change_command(pMac, pCommand);
841 break;
842 case eSmeCommandSetKey:
843 csr_ll_unlock(&pMac->sme.smeCmdActiveList);
844 status = csr_roam_process_set_key_command(pMac, pCommand);
845 if (!CDF_IS_STATUS_SUCCESS(status)
846 && csr_ll_remove_entry(&pMac->sme.smeCmdActiveList,
847 &pCommand->Link, LL_ACCESS_LOCK)) {
848 csr_release_command_set_key(pMac, pCommand);
849 }
850 break;
851 case eSmeCommandAddStaSession:
852 csr_ll_unlock(&pMac->sme.smeCmdActiveList);
853 csr_process_add_sta_session_command(pMac, pCommand);
854 break;
855 case eSmeCommandDelStaSession:
856 csr_ll_unlock(&pMac->sme.smeCmdActiveList);
857 csr_process_del_sta_session_command(pMac, pCommand);
858 break;
859#ifdef FEATURE_OEM_DATA_SUPPORT
860 case eSmeCommandOemDataReq:
861 csr_ll_unlock(&pMac->sme.smeCmdActiveList);
862 oem_data_process_oem_data_req_command(pMac, pCommand);
863 break;
864#endif
865 case eSmeCommandRemainOnChannel:
866 csr_ll_unlock(&pMac->sme.smeCmdActiveList);
867 p2p_process_remain_on_channel_cmd(pMac, pCommand);
868 break;
869 /*
870 * Treat standby differently here because caller may not be able
871 * to handle the failure so we do our best here
872 */
873 case eSmeCommandEnterStandby:
874 break;
875 case eSmeCommandAddTs:
876 case eSmeCommandDelTs:
877 csr_ll_unlock(&pMac->sme.smeCmdActiveList);
878#ifndef WLAN_MDM_CODE_REDUCTION_OPT
879 fContinue = qos_process_command(pMac, pCommand);
880 if (fContinue && csr_ll_remove_entry(
881 &pMac->sme.smeCmdActiveList,
882 &pCommand->Link, LL_ACCESS_NOLOCK)) {
883 /* The command failed, remove it */
884 qos_release_command(pMac, pCommand);
885 }
886#endif
887 break;
888#ifdef FEATURE_WLAN_TDLS
889 case eSmeCommandTdlsSendMgmt:
890 case eSmeCommandTdlsAddPeer:
891 case eSmeCommandTdlsDelPeer:
892 case eSmeCommandTdlsLinkEstablish:
893 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_INFO,
894 FL("sending TDLS Command 0x%x to PE"),
895 pCommand->command);
896 csr_ll_unlock(&pMac->sme.smeCmdActiveList);
897 status = csr_tdls_process_cmd(pMac, pCommand);
898 break;
899#endif
900 case e_sme_command_set_hw_mode:
901 csr_ll_unlock(&pMac->sme.smeCmdActiveList);
902 csr_process_set_hw_mode(pMac, pCommand);
903 break;
904 case e_sme_command_nss_update:
905 csr_ll_unlock(&pMac->sme.smeCmdActiveList);
906 csr_process_nss_update_req(pMac, pCommand);
907 break;
908 case e_sme_command_set_dual_mac_config:
909 csr_ll_unlock(&pMac->sme.smeCmdActiveList);
910 csr_process_set_dual_mac_config(pMac, pCommand);
911 break;
912 default:
913 /* something is wrong */
914 /* remove it from the active list */
915 sms_log(pMac, LOGE, FL("unknown command %d"),
916 pCommand->command);
917 pEntry = csr_ll_remove_head(&pMac->sme.smeCmdActiveList,
918 LL_ACCESS_NOLOCK);
919 csr_ll_unlock(&pMac->sme.smeCmdActiveList);
920 pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link);
921 sme_release_command(pMac, pCommand);
922 status = CDF_STATUS_E_FAILURE;
923 break;
924 }
925 if (!CDF_IS_STATUS_SUCCESS(status))
926 fContinue = true;
927process_scan_q:
928 if (!(sme_process_scan_queue(pMac)))
929 fContinue = false;
930 return fContinue;
931}
932
933void sme_process_pending_queue(tpAniSirGlobal pMac)
934{
935 while (sme_process_command(pMac))
936 ;
937}
938
939bool sme_command_pending(tpAniSirGlobal pMac)
940{
941 return !csr_ll_is_list_empty(&pMac->sme.smeCmdActiveList, LL_ACCESS_NOLOCK)
942 || !csr_ll_is_list_empty(&pMac->sme.smeCmdPendingList,
943 LL_ACCESS_NOLOCK);
944}
945
946/* Global APIs */
947
948/**
949 * sme_open() - Initialze all SME modules and put them at idle state
950 * @hHal: The handle returned by mac_open
951 *
952 * The function initializes each module inside SME, PMC, CSR, etc. Upon
953 * successfully return, all modules are at idle state ready to start.
954 * smeOpen must be called before any other SME APIs can be involved.
955 * smeOpen must be called after mac_open.
956 *
957 * Return: CDF_STATUS_SUCCESS - SME is successfully initialized.
958 * Other status means SME is failed to be initialized
959 */
960CDF_STATUS sme_open(tHalHandle hHal)
961{
962 CDF_STATUS status = CDF_STATUS_E_FAILURE;
963 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
964#ifndef WLAN_FEATURE_MBSSID
965 void *p_cds_gctx = cds_get_global_context();
966#endif
967
968 pMac->sme.state = SME_STATE_STOP;
969 pMac->sme.currDeviceMode = CDF_STA_MODE;
970 if (!CDF_IS_STATUS_SUCCESS(cdf_mutex_init(
971 &pMac->sme.lkSmeGlobalLock))) {
972 sms_log(pMac, LOGE, FL("sme_open failed init lock"));
973 return CDF_STATUS_E_FAILURE;
974 }
975 status = csr_open(pMac);
976 if (!CDF_IS_STATUS_SUCCESS(status)) {
977 sms_log(pMac, LOGE, FL("csr_open failed, status=%d"), status);
978 return status;
979 }
980
981 status = sme_ps_open(hHal);
982 if (!CDF_IS_STATUS_SUCCESS(status)) {
983 sms_log(pMac, LOGE,
984 FL("sme_ps_open failed during initialization with status=%d"),
985 status);
986 return status;
987 }
988#ifdef FEATURE_WLAN_TDLS
989 pMac->is_tdls_power_save_prohibited = 0;
990#endif
991
992#ifndef WLAN_MDM_CODE_REDUCTION_OPT
993 status = sme_qos_open(pMac);
994 if (!CDF_IS_STATUS_SUCCESS(status)) {
995 sms_log(pMac, LOGE, FL("Qos open, status=%d"), status);
996 return status;
997 }
998#endif
999#ifdef FEATURE_OEM_DATA_SUPPORT
1000 status = oem_data_oem_data_req_open(pMac);
1001 if (!CDF_IS_STATUS_SUCCESS(status)) {
1002 sms_log(pMac, LOGE,
1003 FL("oem_data_oem_data_req_open, status=%d"),
1004 status);
1005 return status;
1006 }
1007#endif
1008 status = init_sme_cmd_list(pMac);
1009 if (!CDF_IS_STATUS_SUCCESS(status))
1010 return status;
1011#ifndef WLAN_FEATURE_MBSSID
1012 if (NULL == p_cds_gctx) {
1013 sms_log(pMac, LOGE, FL("p_cds_gctx is NULL"));
1014 return CDF_STATUS_E_FAILURE;
1015 }
1016 status = wlansap_open(p_cds_gctx);
1017 if (!CDF_IS_STATUS_SUCCESS(status)) {
1018 sms_log(pMac, LOGE, FL("wlansap_open failed, status=%d"),
1019 status);
1020 return status;
1021 }
1022#endif
1023
1024#if defined WLAN_FEATURE_VOWIFI
1025 status = rrm_open(pMac);
1026 if (!CDF_IS_STATUS_SUCCESS(status)) {
1027 sms_log(pMac, LOGE, FL("rrm_open failed, status=%d"), status);
1028 return status;
1029 }
1030#endif
1031 sme_p2p_open(pMac);
1032 sme_trace_init(pMac);
1033 return status;
1034}
1035
1036/*
1037 * sme_init_chan_list, triggers channel setup based on country code.
1038 */
1039CDF_STATUS sme_init_chan_list(tHalHandle hal, uint8_t *alpha2,
1040 COUNTRY_CODE_SOURCE cc_src)
1041{
1042 tpAniSirGlobal pmac = PMAC_STRUCT(hal);
1043
1044 if ((cc_src == COUNTRY_CODE_SET_BY_USER) &&
1045 (pmac->roam.configParam.fSupplicantCountryCodeHasPriority)) {
1046 pmac->roam.configParam.Is11dSupportEnabled = false;
1047 }
1048
1049 return csr_init_chan_list(pmac, alpha2);
1050}
1051
1052/*--------------------------------------------------------------------------
1053
1054 \brief sme_set11dinfo() - Set the 11d information about valid channels
1055 and there power using information from nvRAM
1056 This function is called only for AP.
1057
1058 This is a synchronous call
1059
1060 \param hHal - The handle returned by mac_open.
1061 \Param pSmeConfigParams - a pointer to a caller allocated object of
1062 typedef struct _smeConfigParams.
1063
1064 \return CDF_STATUS_SUCCESS - SME update the config parameters successfully.
1065
1066 Other status means SME is failed to update the config parameters.
1067 \sa
1068 --------------------------------------------------------------------------*/
1069
1070CDF_STATUS sme_set11dinfo(tHalHandle hHal, tpSmeConfigParams pSmeConfigParams)
1071{
1072 CDF_STATUS status = CDF_STATUS_E_FAILURE;
1073 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
1074
1075 MTRACE(cdf_trace(CDF_MODULE_ID_SME,
1076 TRACE_CODE_SME_RX_HDD_MSG_SET_11DINFO, NO_SESSION, 0));
1077 if (NULL == pSmeConfigParams) {
1078 sms_log(pMac, LOGE,
1079 "Empty config param structure for SME, nothing to update");
1080 return status;
1081 }
1082
1083 status = csr_set_channels(hHal, &pSmeConfigParams->csrConfig);
1084 if (!CDF_IS_STATUS_SUCCESS(status)) {
1085 sms_log(pMac, LOGE,
1086 "csr_change_default_config_param failed with status=%d",
1087 status);
1088 }
1089 return status;
1090}
1091
1092/**
1093 * sme_set_scan_disable() - Dynamically enable/disable scan
1094 * @h_hal: Handle to HAL
1095 *
1096 * This command gives the user an option to dynamically
1097 * enable or disable scans.
1098 *
1099 * Return: None
1100 */
1101void sme_set_scan_disable(tHalHandle h_hal, int value)
1102{
1103 tpAniSirGlobal mac_ctx = PMAC_STRUCT(h_hal);
1104 mac_ctx->lim.scan_disabled = value;
1105 sms_log(mac_ctx, LOG1, FL("value=%d"), value);
1106}
1107/*--------------------------------------------------------------------------
1108
1109 \brief sme_get_soft_ap_domain() - Get the current regulatory domain of softAp.
1110
1111 This is a synchronous call
1112
1113 \param hHal - The handle returned by HostapdAdapter.
1114 \Param v_REGDOMAIN_t - The current Regulatory Domain requested for SoftAp.
1115
1116 \return CDF_STATUS_SUCCESS - SME successfully completed the request.
1117
1118 Other status means, failed to get the current regulatory domain.
1119 \sa
1120 --------------------------------------------------------------------------*/
1121
1122CDF_STATUS sme_get_soft_ap_domain(tHalHandle hHal, v_REGDOMAIN_t *domainIdSoftAp)
1123{
1124 CDF_STATUS status = CDF_STATUS_E_FAILURE;
1125 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
1126
1127 MTRACE(cdf_trace(CDF_MODULE_ID_SME,
1128 TRACE_CODE_SME_RX_HDD_MSG_GET_SOFTAP_DOMAIN,
1129 NO_SESSION, 0));
1130 if (NULL == domainIdSoftAp) {
1131 sms_log(pMac, LOGE, "Uninitialized domain Id");
1132 return status;
1133 }
1134
1135 *domainIdSoftAp = pMac->scan.domainIdCurrent;
1136 status = CDF_STATUS_SUCCESS;
1137
1138 return status;
1139}
1140
1141CDF_STATUS sme_set_reg_info(tHalHandle hHal, uint8_t *apCntryCode)
1142{
1143 CDF_STATUS status = CDF_STATUS_E_FAILURE;
1144 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
1145
1146 MTRACE(cdf_trace(CDF_MODULE_ID_SME,
1147 TRACE_CODE_SME_RX_HDD_MSG_SET_REGINFO, NO_SESSION, 0));
1148 if (NULL == apCntryCode) {
1149 sms_log(pMac, LOGE, "Empty Country Code, nothing to update");
1150 return status;
1151 }
1152
1153 status = csr_set_reg_info(hHal, apCntryCode);
1154 if (!CDF_IS_STATUS_SUCCESS(status)) {
1155 sms_log(pMac, LOGE, "csr_set_reg_info failed with status=%d",
1156 status);
1157 }
1158 return status;
1159}
1160
1161#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
1162CDF_STATUS sme_set_plm_request(tHalHandle hHal, tpSirPlmReq pPlmReq)
1163{
1164 CDF_STATUS status;
1165 bool ret = false;
1166 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
1167 uint8_t ch_list[WNI_CFG_VALID_CHANNEL_LIST] = { 0 };
1168 uint8_t count, valid_count = 0;
1169 cds_msg_t msg;
1170 tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, pPlmReq->sessionId);
1171
1172 status = sme_acquire_global_lock(&pMac->sme);
1173 if (!CDF_IS_STATUS_SUCCESS(status))
1174 return status;
1175
1176 if (!pSession) {
1177 sms_log(pMac, LOGE, FL("session %d not found"),
1178 pPlmReq->sessionId);
1179 sme_release_global_lock(&pMac->sme);
1180 return CDF_STATUS_E_FAILURE;
1181 }
1182
1183 if (!pSession->sessionActive) {
1184 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
1185 FL("Invalid Sessionid"));
1186 sme_release_global_lock(&pMac->sme);
1187 return CDF_STATUS_E_FAILURE;
1188 }
1189
1190 if (!pPlmReq->enable)
1191 goto send_plm_start;
1192 /* validating channel numbers */
1193 for (count = 0; count < pPlmReq->plmNumCh; count++) {
1194 ret = csr_is_supported_channel(pMac, pPlmReq->plmChList[count]);
1195 if (ret && pPlmReq->plmChList[count] > 14) {
1196 if (CHANNEL_STATE_DFS == cds_get_channel_state(
1197 pPlmReq->plmChList[count])) {
1198 /* DFS channel is provided, no PLM bursts can be
1199 * transmitted. Ignoring these channels.
1200 */
1201 CDF_TRACE(CDF_MODULE_ID_SME,
1202 CDF_TRACE_LEVEL_INFO,
1203 FL("DFS channel %d ignored for PLM"),
1204 pPlmReq->plmChList[count]);
1205 continue;
1206 }
1207 } else if (!ret) {
1208 /* Not supported, ignore the channel */
1209 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_INFO,
1210 FL("Unsupported channel %d ignored for PLM"),
1211 pPlmReq->plmChList[count]);
1212 continue;
1213 }
1214 ch_list[valid_count] = pPlmReq->plmChList[count];
1215 valid_count++;
1216 } /* End of for () */
1217
1218 /* Copying back the valid channel list to plm struct */
1219 cdf_mem_set((void *)pPlmReq->plmChList,
1220 pPlmReq->plmNumCh, 0);
1221 if (valid_count)
1222 cdf_mem_copy(pPlmReq->plmChList, ch_list,
1223 valid_count);
1224 /* All are invalid channels, FW need to send the PLM
1225 * report with "incapable" bit set.
1226 */
1227 pPlmReq->plmNumCh = valid_count;
1228
1229send_plm_start:
1230 /* PLM START */
1231 msg.type = WMA_SET_PLM_REQ;
1232 msg.reserved = 0;
1233 msg.bodyptr = pPlmReq;
1234
1235 if (!CDF_IS_STATUS_SUCCESS(cds_mq_post_message(CDF_MODULE_ID_WMA,
1236 &msg))) {
1237 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
1238 FL("Not able to post WMA_SET_PLM_REQ to WMA"));
1239 sme_release_global_lock(&pMac->sme);
1240 return CDF_STATUS_E_FAILURE;
1241 }
1242
1243 sme_release_global_lock(&pMac->sme);
1244 return status;
1245}
1246#endif
1247
1248/*--------------------------------------------------------------------------
1249
1250 \brief sme_update_config() - Change configurations for all SME moduels
1251
1252 The function updates some configuration for modules in SME, CSR, etc
1253 during SMEs close open sequence.
1254
1255 Modules inside SME apply the new configuration at the next transaction.
1256
1257 This is a synchronous call
1258
1259 \param hHal - The handle returned by mac_open.
1260 \Param pSmeConfigParams - a pointer to a caller allocated object of
1261 typedef struct _smeConfigParams.
1262
1263 \return CDF_STATUS_SUCCESS - SME update the config parameters successfully.
1264
1265 Other status means SME is failed to update the config parameters.
1266 \sa
1267
1268 --------------------------------------------------------------------------*/
1269CDF_STATUS sme_update_config(tHalHandle hHal, tpSmeConfigParams pSmeConfigParams)
1270{
1271 CDF_STATUS status = CDF_STATUS_E_FAILURE;
1272 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
1273
1274 MTRACE(cdf_trace(CDF_MODULE_ID_SME,
1275 TRACE_CODE_SME_RX_HDD_MSG_UPDATE_CONFIG, NO_SESSION,
1276 0));
1277 if (NULL == pSmeConfigParams) {
1278 sms_log(pMac, LOGE,
1279 "Empty config param structure for SME, nothing to update");
1280 return status;
1281 }
1282
1283 status =
1284 csr_change_default_config_param(pMac, &pSmeConfigParams->csrConfig);
1285
1286 if (!CDF_IS_STATUS_SUCCESS(status)) {
1287 sms_log(pMac, LOGE,
1288 "csr_change_default_config_param failed with status=%d",
1289 status);
1290 }
1291#if defined WLAN_FEATURE_VOWIFI
1292 status =
1293 rrm_change_default_config_param(hHal, &pSmeConfigParams->rrmConfig);
1294
1295 if (!CDF_IS_STATUS_SUCCESS(status)) {
1296 sms_log(pMac, LOGE,
1297 "rrm_change_default_config_param failed with status=%d",
1298 status);
1299 }
1300#endif
1301 /* For SOC, CFG is set before start */
1302 /* We don't want to apply global CFG in connect state because that may cause some side affect */
1303 if (csr_is_all_session_disconnected(pMac)) {
1304 csr_set_global_cfgs(pMac);
1305 }
1306
1307 /*
1308 * If scan offload is enabled then lim has allow the sending of
1309 * scan request to firmware even in powersave mode. The firmware has
1310 * to take care of exiting from power save mode
1311 */
1312 status = sme_cfg_set_int(hHal, WNI_CFG_SCAN_IN_POWERSAVE, true);
1313
1314 if (CDF_STATUS_SUCCESS != status) {
1315 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
1316 "Could not pass on WNI_CFG_SCAN_IN_POWERSAVE to CFG");
1317 }
1318 pMac->isCoalesingInIBSSAllowed =
1319 pSmeConfigParams->csrConfig.isCoalesingInIBSSAllowed;
1320
1321 /* update p2p offload status */
1322 pMac->pnoOffload = pSmeConfigParams->pnoOffload;
1323
1324 pMac->fEnableDebugLog = pSmeConfigParams->fEnableDebugLog;
1325
1326 /* update interface configuration */
1327 pMac->sme.max_intf_count = pSmeConfigParams->max_intf_count;
1328
1329 pMac->enable5gEBT = pSmeConfigParams->enable5gEBT;
1330 pMac->sme.enableSelfRecovery = pSmeConfigParams->enableSelfRecovery;
1331
1332 pMac->f_sta_miracast_mcc_rest_time_val =
1333 pSmeConfigParams->f_sta_miracast_mcc_rest_time_val;
1334
1335#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
1336 pMac->sap.sap_channel_avoidance =
1337 pSmeConfigParams->sap_channel_avoidance;
1338#endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
1339
1340 pMac->f_prefer_non_dfs_on_radar =
1341 pSmeConfigParams->f_prefer_non_dfs_on_radar;
1342
1343 pMac->sme.ps_global_info.ps_enabled =
1344 pSmeConfigParams->is_ps_enabled;
1345
1346 pMac->policy_manager_enabled = pSmeConfigParams->policy_manager_enabled;
1347 pMac->fine_time_meas_cap = pSmeConfigParams->fine_time_meas_cap;
1348 pMac->dual_mac_feature_disable =
1349 pSmeConfigParams->dual_mac_feature_disable;
1350
1351 return status;
1352}
1353
1354/**
1355 * sme_update_roam_params() - Store/Update the roaming params
1356 * @hal: Handle for Hal layer
1357 * @session_id: SME Session ID
1358 * @roam_params_src: The source buffer to copy
1359 * @update_param: Type of parameter to be updated
1360 *
1361 * Return: Return the status of the updation.
1362 */
1363CDF_STATUS sme_update_roam_params(tHalHandle hal,
1364 uint8_t session_id, struct roam_ext_params roam_params_src,
1365 int update_param)
1366{
1367 tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
1368 struct roam_ext_params *roam_params_dst;
1369 uint8_t i;
1370
1371 roam_params_dst = &mac_ctx->roam.configParam.roam_params;
1372 switch (update_param) {
1373 case REASON_ROAM_EXT_SCAN_PARAMS_CHANGED:
1374 roam_params_dst->raise_rssi_thresh_5g =
1375 roam_params_src.raise_rssi_thresh_5g;
1376 roam_params_dst->drop_rssi_thresh_5g =
1377 roam_params_src.drop_rssi_thresh_5g;
1378 roam_params_dst->raise_factor_5g =
1379 roam_params_src.raise_factor_5g;
1380 roam_params_dst->drop_factor_5g =
1381 roam_params_src.drop_factor_5g;
1382 roam_params_dst->max_raise_rssi_5g =
1383 roam_params_src.max_raise_rssi_5g;
1384 roam_params_dst->max_drop_rssi_5g =
1385 roam_params_src.max_drop_rssi_5g;
1386 roam_params_dst->alert_rssi_threshold =
1387 roam_params_src.alert_rssi_threshold;
1388 roam_params_dst->is_5g_pref_enabled = true;
1389 break;
1390 case REASON_ROAM_SET_SSID_ALLOWED:
1391 cdf_mem_set(&roam_params_dst->ssid_allowed_list, 0,
1392 sizeof(tSirMacSSid) * MAX_SSID_ALLOWED_LIST);
1393 roam_params_dst->num_ssid_allowed_list =
1394 roam_params_src.num_ssid_allowed_list;
1395 for (i = 0; i < roam_params_dst->num_ssid_allowed_list; i++) {
1396 roam_params_dst->ssid_allowed_list[i].length =
1397 roam_params_src.ssid_allowed_list[i].length;
1398 cdf_mem_copy(roam_params_dst->ssid_allowed_list[i].ssId,
1399 roam_params_src.ssid_allowed_list[i].ssId,
1400 roam_params_dst->ssid_allowed_list[i].length);
1401 }
1402 break;
1403 case REASON_ROAM_SET_FAVORED_BSSID:
1404 cdf_mem_set(&roam_params_dst->bssid_favored, 0,
1405 sizeof(tSirMacAddr) * MAX_BSSID_FAVORED);
1406 roam_params_dst->num_bssid_favored =
1407 roam_params_src.num_bssid_favored;
1408 for (i = 0; i < roam_params_dst->num_bssid_favored; i++) {
1409 cdf_mem_copy(&roam_params_dst->bssid_favored[i],
1410 &roam_params_src.bssid_favored[i],
1411 sizeof(tSirMacAddr));
1412 roam_params_dst->bssid_favored_factor[i] =
1413 roam_params_src.bssid_favored_factor[i];
1414 }
1415 break;
1416 case REASON_ROAM_SET_BLACKLIST_BSSID:
1417 cdf_mem_set(&roam_params_dst->bssid_avoid_list, 0,
1418 sizeof(tSirMacAddr) * MAX_BSSID_AVOID_LIST);
1419 roam_params_dst->num_bssid_avoid_list =
1420 roam_params_src.num_bssid_avoid_list;
1421 for (i = 0; i < roam_params_dst->num_bssid_avoid_list; i++) {
1422 cdf_mem_copy(&roam_params_dst->bssid_avoid_list[i],
1423 &roam_params_src.bssid_avoid_list[i],
1424 sizeof(tSirMacAddr));
1425 }
1426 break;
1427 case REASON_ROAM_GOOD_RSSI_CHANGED:
1428 roam_params_dst->good_rssi_roam =
1429 roam_params_src.good_rssi_roam;
1430 break;
1431 default:
1432 break;
1433 }
1434 csr_roam_offload_scan(mac_ctx, session_id, ROAM_SCAN_OFFLOAD_UPDATE_CFG,
1435 update_param);
1436 return 0;
1437}
1438
1439#ifdef WLAN_FEATURE_GTK_OFFLOAD
1440void sme_process_get_gtk_info_rsp(tHalHandle hHal,
1441 tpSirGtkOffloadGetInfoRspParams
1442 pGtkOffloadGetInfoRsp)
1443{
1444 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
1445
1446 if (NULL == pMac) {
1447 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_FATAL,
1448 "%s: pMac is null", __func__);
1449 return;
1450 }
1451 if (pMac->sme.gtk_offload_get_info_cb == NULL) {
1452 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
1453 "%s: HDD callback is null", __func__);
1454 return;
1455 }
1456 pMac->sme.gtk_offload_get_info_cb(
1457 pMac->sme.gtk_offload_get_info_cb_context,
1458 pGtkOffloadGetInfoRsp);
1459}
1460#endif
1461
1462/*--------------------------------------------------------------------------
1463
1464 \fn - sme_process_ready_to_suspend
1465 \brief - On getting ready to suspend indication, this function calls
1466 callback registered (HDD callbacks) with SME to inform
1467 ready to suspend indication.
1468
1469 \param hHal - Handle returned by mac_open.
1470 pReadyToSuspend - Parameter received along with ready to suspend
1471 indication from WMA.
1472
1473 \return None
1474
1475 \sa
1476
1477 --------------------------------------------------------------------------*/
1478void sme_process_ready_to_suspend(tHalHandle hHal,
1479 tpSirReadyToSuspendInd pReadyToSuspend)
1480{
1481 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
1482
1483 if (NULL == pMac) {
1484 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_FATAL,
1485 "%s: pMac is null", __func__);
1486 return;
1487 }
1488
1489 if (NULL != pMac->readyToSuspendCallback) {
1490 pMac->readyToSuspendCallback(pMac->readyToSuspendContext,
1491 pReadyToSuspend->suspended);
1492 pMac->readyToSuspendCallback = NULL;
1493 }
1494}
1495
1496#ifdef WLAN_FEATURE_EXTWOW_SUPPORT
1497/*--------------------------------------------------------------------------
1498
1499 \fn - sme_process_ready_to_ext_wo_w
1500 \brief - On getting ready to Ext WoW indication, this function calls
1501 callback registered (HDD callbacks) with SME to inform
1502 ready to ExtWoW indication.
1503
1504 \param hHal - Handle returned by mac_open.
1505 pReadyToExtWoW - Parameter received along with ready to Ext WoW
1506 indication from WMA.
1507
1508 \return None
1509
1510 \sa
1511
1512 --------------------------------------------------------------------------*/
1513void sme_process_ready_to_ext_wo_w(tHalHandle hHal,
1514 tpSirReadyToExtWoWInd pReadyToExtWoW)
1515{
1516 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
1517
1518 if (NULL == pMac) {
1519 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_FATAL,
1520 "%s: pMac is null", __func__);
1521 return;
1522 }
1523
1524 if (NULL != pMac->readyToExtWoWCallback) {
1525 pMac->readyToExtWoWCallback(pMac->readyToExtWoWContext,
1526 pReadyToExtWoW->status);
1527 pMac->readyToExtWoWCallback = NULL;
1528 pMac->readyToExtWoWContext = NULL;
1529 }
1530
1531}
1532#endif
1533
1534/* ---------------------------------------------------------------------------
1535 \fn sme_change_config_params
1536 \brief The SME API exposed for HDD to provide config params to SME during
1537 SMEs stop -> start sequence.
1538
1539 If HDD changed the domain that will cause a reset. This function will
1540 provide the new set of 11d information for the new domain. Currrently this
1541 API provides info regarding 11d only at reset but we can extend this for
1542 other params (PMC, QoS) which needs to be initialized again at reset.
1543
1544 This is a synchronous call
1545
1546 \param hHal - The handle returned by mac_open.
1547
1548 \Param
1549 pUpdateConfigParam - a pointer to a structure (tCsrUpdateConfigParam) that
1550 currently provides 11d related information like Country code,
1551 Regulatory domain, valid channel list, Tx power per channel, a
1552 list with active/passive scan allowed per valid channel.
1553
1554 \return CDF_STATUS
1555 ---------------------------------------------------------------------------*/
1556CDF_STATUS sme_change_config_params(tHalHandle hHal,
1557 tCsrUpdateConfigParam *pUpdateConfigParam)
1558{
1559 CDF_STATUS status = CDF_STATUS_E_FAILURE;
1560 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
1561
1562 if (NULL == pUpdateConfigParam) {
1563 sms_log(pMac, LOGE,
1564 "Empty config param structure for SME, nothing to reset");
1565 return status;
1566 }
1567
1568 status = csr_change_config_params(pMac, pUpdateConfigParam);
1569
1570 if (!CDF_IS_STATUS_SUCCESS(status)) {
1571 sms_log(pMac, LOGE, "csrUpdateConfigParam failed with status=%d",
1572 status);
1573 }
1574
1575 return status;
1576
1577}
1578
1579/*--------------------------------------------------------------------------
1580
1581 \brief sme_hdd_ready_ind() - SME sends eWNI_SME_SYS_READY_IND to PE to inform
1582 that the NIC is ready tio run.
1583
1584 The function is called by HDD at the end of initialization stage so PE/HAL can
1585 enable the NIC to running state.
1586
1587 This is a synchronous call
1588 \param hHal - The handle returned by mac_open.
1589
1590 \return CDF_STATUS_SUCCESS - eWNI_SME_SYS_READY_IND is sent to PE
1591 successfully.
1592
1593 Other status means SME failed to send the message to PE.
1594 \sa
1595
1596 --------------------------------------------------------------------------*/
1597CDF_STATUS sme_hdd_ready_ind(tHalHandle hHal)
1598{
1599 tSirSmeReadyReq Msg;
1600 CDF_STATUS status = CDF_STATUS_E_FAILURE;
1601 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
1602
1603 MTRACE(cdf_trace(CDF_MODULE_ID_SME,
1604 TRACE_CODE_SME_RX_HDD_MSG_HDDREADYIND, NO_SESSION, 0));
1605 do {
1606
1607 Msg.messageType = eWNI_SME_SYS_READY_IND;
1608 Msg.length = sizeof(tSirSmeReadyReq);
1609 Msg.add_bssdescr_cb = csr_scan_process_single_bssdescr;
1610
1611
1612 if (eSIR_FAILURE != u_mac_post_ctrl_msg(hHal, (tSirMbMsg *) &Msg)) {
1613 status = CDF_STATUS_SUCCESS;
1614 } else {
1615 sms_log(pMac, LOGE,
1616 "u_mac_post_ctrl_msg failed to send eWNI_SME_SYS_READY_IND");
1617 break;
1618 }
1619
1620 status = csr_ready(pMac);
1621 if (!CDF_IS_STATUS_SUCCESS(status)) {
1622 sms_log(pMac, LOGE,
1623 "csr_ready failed with status=%d",
1624 status);
1625 break;
1626 }
1627
1628#if defined WLAN_FEATURE_VOWIFI
1629 if (CDF_STATUS_SUCCESS != rrm_ready(hHal)) {
1630 status = CDF_STATUS_E_FAILURE;
1631 sms_log(pMac, LOGE, "rrm_ready failed");
1632 break;
1633 }
1634#endif
1635 pMac->sme.state = SME_STATE_READY;
1636 } while (0);
1637
1638 return status;
1639}
1640
1641/*--------------------------------------------------------------------------
1642
1643 \brief sme_start() - Put all SME modules at ready state.
1644
1645 The function starts each module in SME, PMC, CSR, etc. . Upon
1646 successfully return, all modules are ready to run.
1647 This is a synchronous call
1648 \param hHal - The handle returned by mac_open.
1649
1650 \return CDF_STATUS_SUCCESS - SME is ready.
1651
1652 Other status means SME is failed to start
1653 \sa
1654
1655 --------------------------------------------------------------------------*/
1656CDF_STATUS sme_start(tHalHandle hHal)
1657{
1658 CDF_STATUS status = CDF_STATUS_E_FAILURE;
1659 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
1660
1661 do {
1662 status = csr_start(pMac);
1663 if (!CDF_IS_STATUS_SUCCESS(status)) {
1664 sms_log(pMac, LOGE,
1665 "csr_start failed during smeStart with status=%d",
1666 status);
1667 break;
1668 }
1669
1670#ifndef WLAN_FEATURE_MBSSID
1671 status = wlansap_start(cds_get_global_context());
1672 if (!CDF_IS_STATUS_SUCCESS(status)) {
1673 sms_log(pMac, LOGE,
1674 "wlansap_start failed during smeStart with status=%d",
1675 status);
1676 break;
1677 }
1678#endif
1679
1680 pMac->sme.state = SME_STATE_START;
1681 } while (0);
1682
1683 return status;
1684}
1685
1686/**
1687 * sme_handle_scan_req() - Scan request handler
1688 * @mac_ctx: MAC global context
1689 * @msg: message buffer
1690 *
1691 * Scan request message from upper layer is handled as
1692 * part of this API
1693 *
1694 * Return: CDF_STATUS
1695 */
1696static CDF_STATUS sme_handle_scan_req(tpAniSirGlobal mac_ctx,
1697 void *msg)
1698{
1699 struct ani_scan_req *scan_msg;
1700 CDF_STATUS status = CDF_STATUS_E_FAILURE;
1701 uint16_t session_id;
1702 csr_scan_completeCallback callback;
1703
1704 scan_msg = msg;
1705 session_id = scan_msg->session_id;
1706 callback = scan_msg->callback;
1707 status = csr_scan_request(mac_ctx, session_id,
1708 scan_msg->scan_param,
1709 callback, scan_msg->ctx);
1710 if (!CDF_IS_STATUS_SUCCESS(status)) {
1711 sms_log(mac_ctx, LOGE,
1712 FL("scan request failed. session_id %d"), session_id);
1713 }
1714 csr_scan_free_request(mac_ctx, scan_msg->scan_param);
1715 return status;
1716}
1717
1718/**
1719 * sme_handle_roc_req() - Roc request handler
1720 * @mac_ctx: MAC global context
1721 * @msg: message buffer
1722 *
1723 * Roc request message from upper layer is handled as
1724 * part of this API
1725 *
1726 * Return: CDF_STATUS
1727 */
1728static CDF_STATUS sme_handle_roc_req(tHalHandle hal,
1729 void *msg)
1730{
1731 struct ani_roc_req *roc_msg;
1732 CDF_STATUS status = CDF_STATUS_E_FAILURE;
1733 tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
1734 remainOnChanCallback callback;
1735
1736 if (msg == NULL) {
1737 sms_log(mac_ctx, LOGE, FL("ROC request is NULL"));
1738 return status;
1739 }
1740
1741 roc_msg = msg;
1742 callback = roc_msg->callback;
1743 status = p2p_remain_on_channel(hal, roc_msg->session_id,
1744 roc_msg->channel, roc_msg->duration, callback,
1745 roc_msg->ctx, roc_msg->is_p2pprobe_allowed,
1746 roc_msg->scan_id);
1747 if (!CDF_IS_STATUS_SUCCESS(status)) {
1748 sms_log(mac_ctx, LOGE,
1749 FL("scan request failed. session_id %d scan_id %d"),
1750 roc_msg->session_id, roc_msg->scan_id);
1751 }
1752 return status;
1753}
1754
1755#ifdef WLAN_FEATURE_11W
1756/*------------------------------------------------------------------
1757 *
1758 * Handle the unprotected management frame indication from LIM and
1759 * forward it to HDD.
1760 *
1761 *------------------------------------------------------------------*/
1762
1763CDF_STATUS sme_unprotected_mgmt_frm_ind(tHalHandle hHal,
1764 tpSirSmeUnprotMgmtFrameInd pSmeMgmtFrm)
1765{
1766 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
1767 CDF_STATUS status = CDF_STATUS_SUCCESS;
1768 tCsrRoamInfo pRoamInfo = { 0 };
1769 uint32_t SessionId = pSmeMgmtFrm->sessionId;
1770
1771 pRoamInfo.nFrameLength = pSmeMgmtFrm->frameLen;
1772 pRoamInfo.pbFrames = pSmeMgmtFrm->frameBuf;
1773 pRoamInfo.frameType = pSmeMgmtFrm->frameType;
1774
1775 /* forward the mgmt frame to HDD */
1776 csr_roam_call_callback(pMac, SessionId, &pRoamInfo, 0,
1777 eCSR_ROAM_UNPROT_MGMT_FRAME_IND, 0);
1778
1779 return status;
1780}
1781#endif
1782
1783/*------------------------------------------------------------------
1784 *
1785 * Handle the DFS Radar Event and indicate it to the SAP
1786 *
1787 *------------------------------------------------------------------*/
1788CDF_STATUS dfs_msg_processor(tpAniSirGlobal pMac, uint16_t msgType, void *pMsgBuf)
1789{
1790 CDF_STATUS status = CDF_STATUS_SUCCESS;
1791 tCsrRoamInfo roamInfo = { 0 };
1792 tSirSmeDfsEventInd *dfs_event;
1793 tSirSmeCSAIeTxCompleteRsp *csaIeTxCompleteRsp;
1794 uint32_t sessionId = 0;
1795 eRoamCmdStatus roamStatus;
1796 eCsrRoamResult roamResult;
1797 int i;
1798
1799 switch (msgType) {
1800 case eWNI_SME_DFS_RADAR_FOUND:
1801 {
1802 /* Radar found !! */
1803 dfs_event = (tSirSmeDfsEventInd *) pMsgBuf;
1804 if (NULL == dfs_event) {
1805 sms_log(pMac, LOGE,
1806 "%s: pMsg is NULL for eWNI_SME_DFS_RADAR_FOUND message",
1807 __func__);
1808 return CDF_STATUS_E_FAILURE;
1809 }
1810 sessionId = dfs_event->sessionId;
1811 roamInfo.dfs_event.sessionId = sessionId;
1812 roamInfo.dfs_event.chan_list.nchannels =
1813 dfs_event->chan_list.nchannels;
1814 for (i = 0; i < dfs_event->chan_list.nchannels; i++) {
1815 roamInfo.dfs_event.chan_list.channels[i] =
1816 dfs_event->chan_list.channels[i];
1817 }
1818
1819 roamInfo.dfs_event.dfs_radar_status =
1820 dfs_event->dfs_radar_status;
1821 roamInfo.dfs_event.use_nol = dfs_event->use_nol;
1822
1823 roamStatus = eCSR_ROAM_DFS_RADAR_IND;
1824 roamResult = eCSR_ROAM_RESULT_DFS_RADAR_FOUND_IND;
1825 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_INFO_MED,
1826 "sapdfs: Radar indication event occurred");
1827 break;
1828 }
1829 case eWNI_SME_DFS_CSAIE_TX_COMPLETE_IND:
1830 {
1831 csaIeTxCompleteRsp =
1832 (tSirSmeCSAIeTxCompleteRsp *) pMsgBuf;
1833 if (NULL == csaIeTxCompleteRsp) {
1834 sms_log(pMac, LOGE,
1835 "%s: pMsg is NULL for eWNI_SME_DFS_CSAIE_TX_COMPLETE_IND",
1836 __func__);
1837 return CDF_STATUS_E_FAILURE;
1838 }
1839 sessionId = csaIeTxCompleteRsp->sessionId;
1840 roamStatus = eCSR_ROAM_DFS_CHAN_SW_NOTIFY;
1841 roamResult = eCSR_ROAM_RESULT_DFS_CHANSW_UPDATE_SUCCESS;
1842 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_INFO_MED,
1843 "sapdfs: Received eWNI_SME_DFS_CSAIE_TX_COMPLETE_IND for session id [%d]",
1844 sessionId);
1845 break;
1846 }
1847 default:
1848 {
1849 sms_log(pMac, LOG1, "%s: Invalid DFS message = 0x%x",
1850 __func__, msgType);
1851 status = CDF_STATUS_E_FAILURE;
1852 return status;
1853 }
1854 }
1855
1856 /* Indicate Radar Event to SAP */
1857 csr_roam_call_callback(pMac, sessionId, &roamInfo, 0,
1858 roamStatus, roamResult);
1859 return status;
1860}
1861
1862#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
1863/*------------------------------------------------------------------
1864 *
1865 * Handle the tsm ie indication from LIM and forward it to HDD.
1866 *
1867 *------------------------------------------------------------------*/
1868CDF_STATUS sme_tsm_ie_ind(tHalHandle hHal, tSirSmeTsmIEInd *pSmeTsmIeInd)
1869{
1870 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
1871 CDF_STATUS status = CDF_STATUS_SUCCESS;
1872 tCsrRoamInfo pRoamInfo = { 0 };
1873 uint32_t SessionId = pSmeTsmIeInd->sessionId;
1874 pRoamInfo.tsmIe.tsid = pSmeTsmIeInd->tsmIe.tsid;
1875 pRoamInfo.tsmIe.state = pSmeTsmIeInd->tsmIe.state;
1876 pRoamInfo.tsmIe.msmt_interval = pSmeTsmIeInd->tsmIe.msmt_interval;
1877 /* forward the tsm ie information to HDD */
1878 csr_roam_call_callback(pMac,
1879 SessionId, &pRoamInfo, 0, eCSR_ROAM_TSM_IE_IND, 0);
1880 return status;
1881}
1882
1883/* ---------------------------------------------------------------------------
1884 \fn sme_set_cckm_ie
1885 \brief function to store the CCKM IE passed from supplicant and use
1886 it while packing reassociation request
1887 \param hHal - HAL handle for device
1888 \param sessionId - Session Identifier
1889 \param pCckmIe - pointer to CCKM IE data
1890 \param pCckmIeLen - length of the CCKM IE
1891 \- return Success or failure
1892 -------------------------------------------------------------------------*/
1893CDF_STATUS sme_set_cckm_ie(tHalHandle hHal, uint8_t sessionId,
1894 uint8_t *pCckmIe, uint8_t cckmIeLen)
1895{
1896 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
1897 CDF_STATUS status = CDF_STATUS_SUCCESS;
1898 status = sme_acquire_global_lock(&pMac->sme);
1899 if (CDF_IS_STATUS_SUCCESS(status)) {
1900 csr_set_cckm_ie(pMac, sessionId, pCckmIe, cckmIeLen);
1901 sme_release_global_lock(&pMac->sme);
1902 }
1903 return status;
1904}
1905
1906/* ---------------------------------------------------------------------------
1907 \fn sme_set_ese_beacon_request
1908 \brief function to set ESE beacon request parameters
1909 \param hHal - HAL handle for device
1910 \param sessionId - Session id
1911 \param pEseBcnReq - pointer to ESE beacon request
1912 \- return Success or failure
1913 -------------------------------------------------------------------------*/
1914CDF_STATUS sme_set_ese_beacon_request(tHalHandle hHal, const uint8_t sessionId,
1915 const tCsrEseBeaconReq *pEseBcnReq)
1916{
1917 CDF_STATUS status = eSIR_SUCCESS;
1918 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
1919 tpSirBeaconReportReqInd pSmeBcnReportReq = NULL;
1920 tCsrEseBeaconReqParams *pBeaconReq = NULL;
1921 uint8_t counter = 0;
1922 tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
1923 tpRrmSMEContext pSmeRrmContext = &pMac->rrm.rrmSmeContext;
1924
1925 if (pSmeRrmContext->eseBcnReqInProgress == true) {
1926 sms_log(pMac, LOGE,
1927 "A Beacon Report Req is already in progress");
1928 return CDF_STATUS_E_RESOURCES;
1929 }
1930
1931 /* Store the info in RRM context */
1932 cdf_mem_copy(&pSmeRrmContext->eseBcnReqInfo, pEseBcnReq,
1933 sizeof(tCsrEseBeaconReq));
1934
1935 /* Prepare the request to send to SME. */
1936 pSmeBcnReportReq = cdf_mem_malloc(sizeof(tSirBeaconReportReqInd));
1937 if (NULL == pSmeBcnReportReq) {
1938 sms_log(pMac, LOGP,
1939 "Memory Allocation Failure!!! ESE BcnReq Ind to SME");
1940 return CDF_STATUS_E_NOMEM;
1941 }
1942
1943 pSmeRrmContext->eseBcnReqInProgress = true;
1944
1945 sms_log(pMac, LOGE, "Sending Beacon Report Req to SME");
1946 cdf_mem_zero(pSmeBcnReportReq, sizeof(tSirBeaconReportReqInd));
1947
1948 pSmeBcnReportReq->messageType = eWNI_SME_BEACON_REPORT_REQ_IND;
1949 pSmeBcnReportReq->length = sizeof(tSirBeaconReportReqInd);
1950 cdf_mem_copy(pSmeBcnReportReq->bssId,
1951 pSession->connectedProfile.bssid.bytes,
1952 sizeof(tSirMacAddr));
1953 pSmeBcnReportReq->channelInfo.channelNum = 255;
1954 pSmeBcnReportReq->channelList.numChannels = pEseBcnReq->numBcnReqIe;
1955 pSmeBcnReportReq->msgSource = eRRM_MSG_SOURCE_ESE_UPLOAD;
1956
1957 for (counter = 0; counter < pEseBcnReq->numBcnReqIe; counter++) {
1958 pBeaconReq =
1959 (tCsrEseBeaconReqParams *) &pEseBcnReq->bcnReq[counter];
1960 pSmeBcnReportReq->fMeasurementtype[counter] =
1961 pBeaconReq->scanMode;
1962 pSmeBcnReportReq->measurementDuration[counter] =
1963 SYS_TU_TO_MS(pBeaconReq->measurementDuration);
1964 pSmeBcnReportReq->channelList.channelNumber[counter] =
1965 pBeaconReq->channel;
1966 }
1967
1968 status = sme_rrm_process_beacon_report_req_ind(pMac, pSmeBcnReportReq);
1969
1970 if (status != CDF_STATUS_SUCCESS)
1971 pSmeRrmContext->eseBcnReqInProgress = false;
1972
1973 return status;
1974}
1975
1976#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
1977
1978/**
1979 * sme_process_fw_mem_dump_rsp - process fw memory dump response from WMA
1980 *
1981 * @mac_ctx: pointer to MAC handle.
1982 * @msg: pointer to received SME msg.
1983 *
1984 * This function process the received SME message and calls the corresponding
1985 * callback which was already registered with SME.
1986 *
1987 * Return: None
1988 */
1989#ifdef WLAN_FEATURE_MEMDUMP
1990static void sme_process_fw_mem_dump_rsp(tpAniSirGlobal mac_ctx, cds_msg_t *msg)
1991{
1992 if (msg->bodyptr) {
1993 if (mac_ctx->sme.fw_dump_callback)
1994 mac_ctx->sme.fw_dump_callback(mac_ctx->hHdd,
1995 (struct fw_dump_rsp *) msg->bodyptr);
1996 cdf_mem_free(msg->bodyptr);
1997 }
1998}
1999#else
2000static void sme_process_fw_mem_dump_rsp(tpAniSirGlobal mac_ctx, cds_msg_t *msg)
2001{
2002}
2003#endif
2004
2005/**
2006 * sme_process_dual_mac_config_resp() - Process set Dual mac config response
2007 * @mac: Global MAC pointer
2008 * @msg: Dual mac config response
2009 *
2010 * Processes the dual mac configuration response and invokes the HDD callback
2011 * to process further
2012 */
2013static CDF_STATUS sme_process_dual_mac_config_resp(tpAniSirGlobal mac,
2014 uint8_t *msg)
2015{
2016 tListElem *entry = NULL;
2017 tSmeCmd *command = NULL;
2018 bool found;
2019 dual_mac_cb callback = NULL;
2020 struct sir_dual_mac_config_resp *param;
2021
2022 param = (struct sir_dual_mac_config_resp *)msg;
2023 if (!param) {
2024 sms_log(mac, LOGE, FL("Dual mac config resp param is NULL"));
2025 /* Not returning. Need to check if active command list
2026 * needs to be freed
2027 */
2028 }
2029
2030 entry = csr_ll_peek_head(&mac->sme.smeCmdActiveList,
2031 LL_ACCESS_LOCK);
2032 if (!entry) {
2033 sms_log(mac, LOGE, FL("No cmd found in active list"));
2034 return CDF_STATUS_E_FAILURE;
2035 }
2036
2037 command = GET_BASE_ADDR(entry, tSmeCmd, Link);
2038 if (!command) {
2039 sms_log(mac, LOGE, FL("Base address is NULL"));
2040 return CDF_STATUS_E_FAILURE;
2041 }
2042
2043 if (e_sme_command_set_dual_mac_config != command->command) {
2044 sms_log(mac, LOGE, FL("Command mismatch!"));
2045 return CDF_STATUS_E_FAILURE;
2046 }
2047
2048 callback = command->u.set_dual_mac_cmd.set_dual_mac_cb;
2049 if (callback) {
2050 if (!param) {
2051 sms_log(mac, LOGE,
2052 FL("Callback failed-Dual mac config is NULL"));
2053 } else {
2054 sms_log(mac, LOG1,
2055 FL("Calling HDD callback for Dual mac config"));
2056 callback(param->status,
2057 command->u.set_dual_mac_cmd.scan_config,
2058 command->u.set_dual_mac_cmd.fw_mode_config);
2059 }
2060 } else {
2061 sms_log(mac, LOGE, FL("Callback does not exist"));
2062 }
2063
2064 found = csr_ll_remove_entry(&mac->sme.smeCmdActiveList, entry,
2065 LL_ACCESS_LOCK);
2066 if (found)
2067 /* Now put this command back on the available command list */
2068 sme_release_command(mac, command);
2069
2070 sme_process_pending_queue(mac);
2071 return CDF_STATUS_SUCCESS;
2072}
2073
2074/*--------------------------------------------------------------------------
2075
2076 \brief sme_process_msg() - The main message processor for SME.
2077
2078 The function is called by a message dispatcher when to process a message
2079 targeted for SME.
2080
2081 This is a synchronous call
2082 \param hHal - The handle returned by mac_open.
2083 \param pMsg - A pointer to a caller allocated object of tSirMsgQ.
2084
2085 \return CDF_STATUS_SUCCESS - SME successfully process the message.
2086
2087 Other status means SME failed to process the message to HAL.
2088 \sa
2089
2090 --------------------------------------------------------------------------*/
2091CDF_STATUS sme_process_msg(tHalHandle hHal, cds_msg_t *pMsg)
2092{
2093 CDF_STATUS status = CDF_STATUS_E_FAILURE;
2094 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
2095
2096 if (pMsg == NULL) {
2097 sms_log(pMac, LOGE, "Empty message for SME");
2098 return status;
2099 }
2100 status = sme_acquire_global_lock(&pMac->sme);
2101 if (!CDF_IS_STATUS_SUCCESS(status)) {
2102 sms_log(pMac, LOGW, FL("Locking failed, bailing out"));
2103 if (pMsg->bodyptr)
2104 cdf_mem_free(pMsg->bodyptr);
2105 return status;
2106 }
2107 if (!SME_IS_START(pMac)) {
2108 sms_log(pMac, LOGW, FL("message type %d in stop state ignored"),
2109 pMsg->type);
2110 if (pMsg->bodyptr)
2111 cdf_mem_free(pMsg->bodyptr);
2112 goto release_lock;
2113 }
2114 switch (pMsg->type) {
2115#ifdef WLAN_FEATURE_ROAM_OFFLOAD
2116 case eWNI_SME_ROAM_OFFLOAD_SYNCH_IND:
2117 csr_process_roam_offload_synch_ind(pMac,
2118 (roam_offload_synch_ind *) pMsg->bodyptr);
2119 cdf_mem_free(pMsg->bodyptr);
2120 break;
2121 case eWNI_SME_HO_FAIL_IND:
2122 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
2123 FL("LFR3: Rcvd eWNI_SME_HO_FAIL_IND"));
2124 csr_process_ho_fail_ind(pMac, pMsg->bodyptr);
2125 cdf_mem_free(pMsg->bodyptr);
2126 break;
2127#endif
2128 case eWNI_PMC_SMPS_STATE_IND:
2129 break;
2130 case WNI_CFG_SET_CNF:
2131 case WNI_CFG_DNLD_CNF:
2132 case WNI_CFG_GET_RSP:
2133 case WNI_CFG_ADD_GRP_ADDR_CNF:
2134 case WNI_CFG_DEL_GRP_ADDR_CNF:
2135 break;
2136 case eWNI_SME_ADDTS_RSP:
2137 case eWNI_SME_DELTS_RSP:
2138 case eWNI_SME_DELTS_IND:
2139#ifdef WLAN_FEATURE_VOWIFI_11R
2140 case eWNI_SME_FT_AGGR_QOS_RSP:
2141#endif
2142 /* QoS */
2143 if (pMsg->bodyptr) {
2144#ifndef WLAN_MDM_CODE_REDUCTION_OPT
2145 status = sme_qos_msg_processor(pMac, pMsg->type,
2146 pMsg->bodyptr);
2147 cdf_mem_free(pMsg->bodyptr);
2148#endif
2149 } else {
2150 sms_log(pMac, LOGE, FL("Empty message for %d"),
2151 pMsg->type);
2152 }
2153 break;
2154#if defined WLAN_FEATURE_VOWIFI
2155 case eWNI_SME_NEIGHBOR_REPORT_IND:
2156 case eWNI_SME_BEACON_REPORT_REQ_IND:
2157#if defined WLAN_VOWIFI_DEBUG
2158 sms_log(pMac, LOGE, FL("Received RRM message. Message Id = %d"),
2159 pMsg->type);
2160#endif
2161 if (pMsg->bodyptr) {
2162 status = sme_rrm_msg_processor(pMac, pMsg->type,
2163 pMsg->bodyptr);
2164 cdf_mem_free(pMsg->bodyptr);
2165 } else {
2166 sms_log(pMac, LOGE, FL("Empty message for %d"),
2167 pMsg->type);
2168 }
2169 break;
2170#endif
2171#ifdef FEATURE_OEM_DATA_SUPPORT
2172 /* Handle the eWNI_SME_OEM_DATA_RSP: */
2173 case eWNI_SME_OEM_DATA_RSP:
2174 if (pMsg->bodyptr) {
2175 status = sme_handle_oem_data_rsp(pMac, pMsg->bodyptr);
2176 cdf_mem_free(pMsg->bodyptr);
2177 } else {
2178 sms_log(pMac, LOGE, FL("Empty message for %d"),
2179 pMsg->type);
2180 }
2181 sme_process_pending_queue(pMac);
2182 break;
2183#endif
2184 case eWNI_SME_ADD_STA_SELF_RSP:
2185 if (pMsg->bodyptr) {
2186 status = csr_process_add_sta_session_rsp(pMac,
2187 pMsg->bodyptr);
2188 cdf_mem_free(pMsg->bodyptr);
2189 } else {
2190 sms_log(pMac, LOGE, FL("Empty message for %d"),
2191 pMsg->type);
2192 }
2193 break;
2194 case eWNI_SME_DEL_STA_SELF_RSP:
2195 if (pMsg->bodyptr) {
2196 status = csr_process_del_sta_session_rsp(pMac,
2197 pMsg->bodyptr);
2198 cdf_mem_free(pMsg->bodyptr);
2199 } else {
2200 sms_log(pMac, LOGE, FL("Empty message for %d"),
2201 pMsg->type);
2202 }
2203 break;
2204 case eWNI_SME_REMAIN_ON_CHN_RSP:
2205 if (pMsg->bodyptr) {
2206 status = sme_remain_on_chn_rsp(pMac, pMsg->bodyptr);
2207 cdf_mem_free(pMsg->bodyptr);
2208 } else {
2209 sms_log(pMac, LOGE, FL("Empty message for %d"),
2210 pMsg->type);
2211 }
2212 break;
2213 case eWNI_SME_REMAIN_ON_CHN_RDY_IND:
2214 if (pMsg->bodyptr) {
2215 status = sme_remain_on_chn_ready(pMac, pMsg->bodyptr);
2216 cdf_mem_free(pMsg->bodyptr);
2217 } else {
2218 sms_log(pMac, LOGE, FL("Empty message for %d"),
2219 pMsg->type);
2220 }
2221 break;
2222 case eWNI_SME_MGMT_FRM_IND:
2223 if (pMsg->bodyptr) {
2224 sme_mgmt_frm_ind(pMac, pMsg->bodyptr);
2225 cdf_mem_free(pMsg->bodyptr);
2226 } else {
2227 sms_log(pMac, LOGE, FL("Empty message for %d"),
2228 pMsg->type);
2229 }
2230 break;
2231 case eWNI_SME_ACTION_FRAME_SEND_CNF:
2232 if (pMsg->bodyptr) {
2233 status = sme_send_action_cnf(pMac, pMsg->bodyptr);
2234 cdf_mem_free(pMsg->bodyptr);
2235 } else {
2236 sms_log(pMac, LOGE, FL("Empty message for %d"),
2237 pMsg->type);
2238 }
2239 break;
2240#ifdef FEATURE_WLAN_SCAN_PNO
2241 case eWNI_SME_PREF_NETWORK_FOUND_IND:
2242 if (pMsg->bodyptr) {
2243 status = sme_preferred_network_found_ind((void *)pMac,
2244 pMsg->bodyptr);
2245 cdf_mem_free(pMsg->bodyptr);
2246 } else {
2247 sms_log(pMac, LOGE, FL("Empty message for %d"),
2248 pMsg->type);
2249 }
2250 break;
2251#endif /* FEATURE_WLAN_SCAN_PNO */
2252 case eWNI_SME_CHANGE_COUNTRY_CODE:
2253 if (pMsg->bodyptr) {
2254 status = sme_handle_change_country_code((void *)pMac,
2255 pMsg->bodyptr);
2256 cdf_mem_free(pMsg->bodyptr);
2257 } else {
2258 sms_log(pMac, LOGE, FL("Empty message for %d"),
2259 pMsg->type);
2260 }
2261 break;
2262 case eWNI_SME_GENERIC_CHANGE_COUNTRY_CODE:
2263 if (pMsg->bodyptr) {
2264 status = sme_handle_generic_change_country_code(
2265 (void *)pMac, pMsg->bodyptr);
2266 cdf_mem_free(pMsg->bodyptr);
2267 } else {
2268 sms_log(pMac, LOGE, FL("Empty message for %d"),
2269 pMsg->type);
2270 }
2271 break;
2272 case eWNI_SME_SCAN_CMD:
2273 if (pMsg->bodyptr) {
2274 status = sme_handle_scan_req(pMac, pMsg->bodyptr);
2275 cdf_mem_free(pMsg->bodyptr);
2276 } else {
2277 sms_log(pMac, LOGE, FL("Empty message for %d"),
2278 pMsg->type);
2279 }
2280 break;
2281 case eWNI_SME_ROC_CMD:
2282 if (pMsg->bodyptr) {
2283 status = sme_handle_roc_req(hHal, pMsg->bodyptr);
2284 cdf_mem_free(pMsg->bodyptr);
2285 } else {
2286 sms_log(pMac, LOGE, FL("Empty message for %d"),
2287 pMsg->type);
2288 }
2289 break;
2290#ifdef FEATURE_WLAN_TDLS
2291 /*
2292 * command rescived from PE, SME tdls msg processor shall be called
2293 * to process commands recieved from PE
2294 */
2295 case eWNI_SME_TDLS_SEND_MGMT_RSP:
2296 case eWNI_SME_TDLS_ADD_STA_RSP:
2297 case eWNI_SME_TDLS_DEL_STA_RSP:
2298 case eWNI_SME_TDLS_DEL_STA_IND:
2299 case eWNI_SME_TDLS_DEL_ALL_PEER_IND:
2300 case eWNI_SME_MGMT_FRM_TX_COMPLETION_IND:
2301 case eWNI_SME_TDLS_LINK_ESTABLISH_RSP:
2302 case eWNI_SME_TDLS_SHOULD_DISCOVER:
2303 case eWNI_SME_TDLS_SHOULD_TEARDOWN:
2304 case eWNI_SME_TDLS_PEER_DISCONNECTED:
2305 if (pMsg->bodyptr) {
2306 status = tdls_msg_processor(pMac, pMsg->type,
2307 pMsg->bodyptr);
2308 cdf_mem_free(pMsg->bodyptr);
2309 } else {
2310 sms_log(pMac, LOGE, FL("Empty message for %d"),
2311 pMsg->type);
2312 }
2313 break;
2314#endif
2315#ifdef WLAN_FEATURE_11W
2316 case eWNI_SME_UNPROT_MGMT_FRM_IND:
2317 if (pMsg->bodyptr) {
2318 sme_unprotected_mgmt_frm_ind(pMac, pMsg->bodyptr);
2319 cdf_mem_free(pMsg->bodyptr);
2320 } else {
2321 sms_log(pMac, LOGE, FL("Empty message for %d"),
2322 pMsg->type);
2323 }
2324 break;
2325#endif
2326#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
2327 case eWNI_SME_TSM_IE_IND:
2328 if (pMsg->bodyptr) {
2329 sme_tsm_ie_ind(pMac, pMsg->bodyptr);
2330 cdf_mem_free(pMsg->bodyptr);
2331 } else {
2332 sms_log(pMac, LOGE, FL("Empty message for %d"),
2333 pMsg->type);
2334 }
2335 break;
2336#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
2337 case eWNI_SME_ROAM_SCAN_OFFLOAD_RSP:
2338 status = csr_roam_offload_scan_rsp_hdlr((void *)pMac,
2339 pMsg->bodyptr);
2340 cdf_mem_free(pMsg->bodyptr);
2341 break;
2342#ifdef WLAN_FEATURE_GTK_OFFLOAD
2343 case eWNI_PMC_GTK_OFFLOAD_GETINFO_RSP:
2344 if (pMsg->bodyptr) {
2345 sme_process_get_gtk_info_rsp(pMac, pMsg->bodyptr);
2346 cdf_mem_free(pMsg->bodyptr);
2347 } else {
2348 sms_log(pMac, LOGE, FL("Empty message for %d"),
2349 pMsg->type);
2350 }
2351 break;
2352#endif
2353#ifdef FEATURE_WLAN_LPHB
2354 /* LPHB timeout indication arrived, send IND to client */
2355 case eWNI_SME_LPHB_IND:
2356 if (pMac->sme.pLphbIndCb)
2357 pMac->sme.pLphbIndCb(pMac->hHdd, pMsg->bodyptr);
2358 cdf_mem_free(pMsg->bodyptr);
2359 break;
2360#endif /* FEATURE_WLAN_LPHB */
2361
2362 case eWNI_SME_READY_TO_SUSPEND_IND:
2363 if (pMsg->bodyptr) {
2364 sme_process_ready_to_suspend(pMac, pMsg->bodyptr);
2365 cdf_mem_free(pMsg->bodyptr);
2366 } else {
2367 sms_log(pMac, LOGE, FL("Empty message for %d"),
2368 pMsg->type);
2369 }
2370 break;
2371#ifdef WLAN_FEATURE_EXTWOW_SUPPORT
2372 case eWNI_SME_READY_TO_EXTWOW_IND:
2373 if (pMsg->bodyptr) {
2374 sme_process_ready_to_ext_wo_w(pMac, pMsg->bodyptr);
2375 cdf_mem_free(pMsg->bodyptr);
2376 } else {
2377 sms_log(pMac, LOGE, FL("Empty message for %d"),
2378 pMsg->type);
2379 }
2380 break;
2381#endif
2382#ifdef FEATURE_WLAN_CH_AVOID
2383 /* channel avoid message arrived, send IND to client */
2384 case eWNI_SME_CH_AVOID_IND:
2385 if (pMac->sme.pChAvoidNotificationCb) {
2386 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
2387 FL("CH avoid notification"));
2388 pMac->sme.pChAvoidNotificationCb(pMac->hHdd,
2389 pMsg->bodyptr);
2390 }
2391 cdf_mem_free(pMsg->bodyptr);
2392 break;
2393#endif /* FEATURE_WLAN_CH_AVOID */
2394#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
2395 case eWNI_SME_AUTO_SHUTDOWN_IND:
2396 if (pMac->sme.pAutoShutdownNotificationCb) {
2397 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_INFO,
2398 FL("Auto shutdown notification"));
2399 pMac->sme.pAutoShutdownNotificationCb();
2400 }
2401 cdf_mem_free(pMsg->bodyptr);
2402 break;
2403#endif
2404 case eWNI_SME_DFS_RADAR_FOUND:
2405 case eWNI_SME_DFS_CSAIE_TX_COMPLETE_IND:
2406 status = dfs_msg_processor(pMac, pMsg->type, pMsg->bodyptr);
2407 cdf_mem_free(pMsg->bodyptr);
2408 break;
2409 case eWNI_SME_CHANNEL_CHANGE_RSP:
2410 if (pMsg->bodyptr) {
2411 status = sme_process_channel_change_resp(pMac,
2412 pMsg->type,
2413 pMsg->bodyptr);
2414 cdf_mem_free(pMsg->bodyptr);
2415 } else {
2416 sms_log(pMac, LOGE, FL("Empty message for %d"),
2417 pMsg->type);
2418 }
2419 break;
2420#ifdef WLAN_FEATURE_STATS_EXT
2421 case eWNI_SME_STATS_EXT_EVENT:
2422 if (pMsg->bodyptr) {
2423 status = sme_stats_ext_event(hHal, pMsg->bodyptr);
2424 cdf_mem_free(pMsg->bodyptr);
2425 } else {
2426 sms_log(pMac, LOGE, FL("Empty message for %d"),
2427 pMsg->type);
2428 }
2429 break;
2430#endif
2431 case eWNI_SME_LINK_SPEED_IND:
2432 if (pMac->sme.pLinkSpeedIndCb)
2433 pMac->sme.pLinkSpeedIndCb(pMsg->bodyptr,
2434 pMac->sme.pLinkSpeedCbContext);
2435 if (pMsg->bodyptr)
2436 cdf_mem_free(pMsg->bodyptr);
2437 break;
2438 case eWNI_SME_CSA_OFFLOAD_EVENT:
2439 if (pMsg->bodyptr) {
2440 csr_scan_flush_bss_entry(pMac, pMsg->bodyptr);
2441 cdf_mem_free(pMsg->bodyptr);
2442 }
2443 break;
2444#ifdef WLAN_FEATURE_NAN
2445 case eWNI_SME_NAN_EVENT:
2446 if (pMsg->bodyptr) {
2447 sme_nan_event(hHal, pMsg->bodyptr);
2448 cdf_mem_free(pMsg->bodyptr);
2449 }
2450 break;
2451#endif /* WLAN_FEATURE_NAN */
2452 case eWNI_SME_LINK_STATUS_IND:
2453 {
2454 tAniGetLinkStatus *pLinkStatus =
2455 (tAniGetLinkStatus *) pMsg->bodyptr;
2456 if (pLinkStatus) {
2457 if (pMac->sme.linkStatusCallback) {
2458 pMac->sme.linkStatusCallback(
2459 pLinkStatus->linkStatus,
2460 pMac->sme.linkStatusContext);
2461 }
2462 pMac->sme.linkStatusCallback = NULL;
2463 pMac->sme.linkStatusContext = NULL;
2464 cdf_mem_free(pLinkStatus);
2465 }
2466 break;
2467 }
2468 case eWNI_SME_MSG_GET_TEMPERATURE_IND:
2469 if (pMac->sme.pGetTemperatureCb) {
2470 pMac->sme.pGetTemperatureCb(pMsg->bodyval,
2471 pMac->sme.pTemperatureCbContext);
2472 }
2473 break;
2474 case eWNI_SME_SNR_IND:
2475 {
2476 tAniGetSnrReq *pSnrReq = (tAniGetSnrReq *) pMsg->bodyptr;
2477 if (pSnrReq) {
2478 if (pSnrReq->snrCallback) {
2479 ((tCsrSnrCallback)
2480 (pSnrReq->snrCallback))
2481 (pSnrReq->snr, pSnrReq->staId,
2482 pSnrReq->pDevContext);
2483 }
2484 cdf_mem_free(pSnrReq);
2485 }
2486 break;
2487 }
2488#ifdef FEATURE_WLAN_EXTSCAN
2489 case eWNI_SME_EXTSCAN_FULL_SCAN_RESULT_IND:
2490 if (pMac->sme.pExtScanIndCb)
2491 pMac->sme.pExtScanIndCb(pMac->hHdd,
2492 eSIR_EXTSCAN_FULL_SCAN_RESULT_IND,
2493 pMsg->bodyptr);
2494 else
2495 sms_log(pMac, LOGE,
2496 FL("callback not registered to process %d"),
2497 pMsg->type);
2498
2499 cdf_mem_free(pMsg->bodyptr);
2500 break;
2501 case eWNI_SME_EPNO_NETWORK_FOUND_IND:
2502 if (pMac->sme.pExtScanIndCb)
2503 pMac->sme.pExtScanIndCb(pMac->hHdd,
2504 eSIR_EPNO_NETWORK_FOUND_IND,
2505 pMsg->bodyptr);
2506 else
2507 sms_log(pMac, LOGE,
2508 FL("callback not registered to process %d"),
2509 pMsg->type);
2510
2511 cdf_mem_free(pMsg->bodyptr);
2512 break;
2513#endif
2514 case eWNI_SME_FW_DUMP_IND:
2515 sme_process_fw_mem_dump_rsp(pMac, pMsg);
2516 break;
2517 case eWNI_SME_SET_HW_MODE_RESP:
2518 if (pMsg->bodyptr) {
2519 status = sme_process_set_hw_mode_resp(pMac,
2520 pMsg->bodyptr);
2521 cdf_mem_free(pMsg->bodyptr);
2522 } else {
2523 sms_log(pMac, LOGE, FL("Empty message for %d"),
2524 pMsg->type);
2525 }
2526 break;
2527 case eWNI_SME_HW_MODE_TRANS_IND:
2528 if (pMsg->bodyptr) {
2529 status = sme_process_hw_mode_trans_ind(pMac,
2530 pMsg->bodyptr);
2531 cdf_mem_free(pMsg->bodyptr);
2532 } else {
2533 sms_log(pMac, LOGE, FL("Empty message for %d"),
2534 pMsg->type);
2535 }
2536 break;
2537 case eWNI_SME_NSS_UPDATE_RSP:
2538 if (pMsg->bodyptr) {
2539 status = sme_process_nss_update_resp(pMac,
2540 pMsg->bodyptr);
2541 cdf_mem_free(pMsg->bodyptr);
2542 } else {
2543 sms_log(pMac, LOGE, FL("Empty message for %d"),
2544 pMsg->type);
2545 }
2546 break;
2547 case eWNI_SME_OCB_SET_CONFIG_RSP:
2548 if (pMac->sme.ocb_set_config_callback) {
2549 pMac->sme.ocb_set_config_callback(
2550 pMac->sme.ocb_set_config_context,
2551 pMsg->bodyptr);
2552 } else {
2553 sms_log(pMac, LOGE, FL(
2554 "Message error. The callback is NULL."));
2555 }
2556 pMac->sme.ocb_set_config_callback = NULL;
2557 pMac->sme.ocb_set_config_context = NULL;
2558 cdf_mem_free(pMsg->bodyptr);
2559 break;
2560 case eWNI_SME_OCB_GET_TSF_TIMER_RSP:
2561 if (pMac->sme.ocb_get_tsf_timer_callback) {
2562 pMac->sme.ocb_get_tsf_timer_callback(
2563 pMac->sme.ocb_get_tsf_timer_context,
2564 pMsg->bodyptr);
2565 } else {
2566 sms_log(pMac, LOGE, FL(
2567 "Message error. The callback is NULL."));
2568 }
2569 pMac->sme.ocb_get_tsf_timer_callback = NULL;
2570 pMac->sme.ocb_get_tsf_timer_context = NULL;
2571 cdf_mem_free(pMsg->bodyptr);
2572 break;
2573 case eWNI_SME_DCC_GET_STATS_RSP:
2574 if (pMac->sme.dcc_get_stats_callback) {
2575 pMac->sme.dcc_get_stats_callback(
2576 pMac->sme.dcc_get_stats_context,
2577 pMsg->bodyptr);
2578 } else {
2579 sms_log(pMac, LOGE, FL(
2580 "Message error. The callback is NULL."));
2581 }
2582 pMac->sme.dcc_get_stats_callback = NULL;
2583 pMac->sme.dcc_get_stats_context = NULL;
2584 cdf_mem_free(pMsg->bodyptr);
2585 break;
2586 case eWNI_SME_DCC_UPDATE_NDL_RSP:
2587 if (pMac->sme.dcc_update_ndl_callback) {
2588 pMac->sme.dcc_update_ndl_callback(
2589 pMac->sme.dcc_update_ndl_context,
2590 pMsg->bodyptr);
2591 } else {
2592 sms_log(pMac, LOGE, FL(
2593 "Message error. The callback is NULL."));
2594 }
2595 pMac->sme.dcc_update_ndl_callback = NULL;
2596 pMac->sme.dcc_update_ndl_context = NULL;
2597 cdf_mem_free(pMsg->bodyptr);
2598 break;
2599 case eWNI_SME_DCC_STATS_EVENT:
2600 if (pMac->sme.dcc_stats_event_callback) {
2601 pMac->sme.dcc_stats_event_callback(
2602 pMac->sme.dcc_stats_event_context,
2603 pMsg->bodyptr);
2604 } else {
2605 sms_log(pMac, LOGE, FL(
2606 "Message error. The callback is NULL."));
2607 }
2608 cdf_mem_free(pMsg->bodyptr);
2609 break;
2610 case eWNI_SME_SET_DUAL_MAC_CFG_RESP:
2611 if (pMsg->bodyptr) {
2612 status = sme_process_dual_mac_config_resp(pMac,
2613 pMsg->bodyptr);
2614 cdf_mem_free(pMsg->bodyptr);
2615 } else {
2616 sms_log(pMac, LOGE, FL("Empty message for %d"),
2617 pMsg->type);
2618 }
2619 case eWNI_SME_SET_THERMAL_LEVEL_IND:
2620 if (pMac->sme.set_thermal_level_cb)
2621 pMac->sme.set_thermal_level_cb(pMac->hHdd,
2622 pMsg->bodyval);
2623 break;
2624 default:
2625
2626 if ((pMsg->type >= eWNI_SME_MSG_TYPES_BEGIN)
2627 && (pMsg->type <= eWNI_SME_MSG_TYPES_END)) {
2628 /* CSR */
2629 if (pMsg->bodyptr) {
2630 status = csr_msg_processor(hHal, pMsg->bodyptr);
2631 cdf_mem_free(pMsg->bodyptr);
2632 } else {
2633 sms_log(pMac, LOGE, FL("Empty message for %d"),
2634 pMsg->type);
2635 }
2636 } else {
2637 sms_log(pMac, LOGW, FL("Unknown message type %d"),
2638 pMsg->type);
2639 if (pMsg->bodyptr)
2640 cdf_mem_free(pMsg->bodyptr);
2641 }
2642 } /* switch */
2643release_lock:
2644 sme_release_global_lock(&pMac->sme);
2645 return status;
2646}
2647
2648/**
2649 * sme_process_nss_update_resp() - Process nss update response
2650 * @mac: Global MAC pointer
2651 * @msg: nss update response
2652 *
2653 * Processes the nss update response and invokes the HDD
2654 * callback to process further
2655 */
2656CDF_STATUS sme_process_nss_update_resp(tpAniSirGlobal mac, uint8_t *msg)
2657{
2658 tListElem *entry = NULL;
2659 tSmeCmd *command = NULL;
2660 bool found;
2661 nss_update_cb callback = NULL;
2662 struct sir_beacon_tx_complete_rsp *param;
2663
2664 param = (struct sir_beacon_tx_complete_rsp *)msg;
2665 if (!param) {
2666 sms_log(mac, LOGE, FL("nss update resp param is NULL"));
2667 /* Not returning. Need to check if active command list
2668 * needs to be freed
2669 */
2670 }
2671
2672 entry = csr_ll_peek_head(&mac->sme.smeCmdActiveList,
2673 LL_ACCESS_LOCK);
2674 if (!entry) {
2675 sms_log(mac, LOGE, FL("No cmd found in active list"));
2676 return CDF_STATUS_E_FAILURE;
2677 }
2678
2679 command = GET_BASE_ADDR(entry, tSmeCmd, Link);
2680 if (!command) {
2681 sms_log(mac, LOGE, FL("Base address is NULL"));
2682 return CDF_STATUS_E_FAILURE;
2683 }
2684
2685 if (e_sme_command_nss_update != command->command) {
2686 sms_log(mac, LOGE, FL("Command mismatch!"));
2687 return CDF_STATUS_E_FAILURE;
2688 }
2689
2690 callback = command->u.nss_update_cmd.nss_update_cb;
2691 if (callback) {
2692 if (!param) {
2693 sms_log(mac, LOGE,
2694 FL("Callback failed since nss update params is NULL"));
2695 } else {
2696 sms_log(mac, LOGE,
2697 FL("Calling HDD callback for nss update response"));
2698 callback(command->u.nss_update_cmd.context,
2699 param->tx_status,
2700 param->session_id,
2701 command->u.nss_update_cmd.next_action);
2702 }
2703 } else {
2704 sms_log(mac, LOGE, FL("Callback does not exisit"));
2705 }
2706
2707 found = csr_ll_remove_entry(&mac->sme.smeCmdActiveList, entry,
2708 LL_ACCESS_LOCK);
2709 if (found) {
2710 /* Now put this command back on the avilable command list */
2711 sme_release_command(mac, command);
2712 }
2713 sme_process_pending_queue(mac);
2714 return CDF_STATUS_SUCCESS;
2715}
2716
2717/* No need to hold the global lock here because this function can only be called */
2718/* after sme_stop. */
2719void sme_free_msg(tHalHandle hHal, cds_msg_t *pMsg)
2720{
2721 if (pMsg) {
2722 if (pMsg->bodyptr) {
2723 cdf_mem_free(pMsg->bodyptr);
2724 }
2725 }
2726
2727}
2728
2729/*--------------------------------------------------------------------------
2730
2731 \brief sme_stop() - Stop all SME modules and put them at idle state
2732
2733 The function stops each module in SME, PMC, CSR, etc. . Upon
2734 return, all modules are at idle state ready to start.
2735
2736 This is a synchronous call
2737 \param hHal - The handle returned by mac_open
2738 \param tHalStopType - reason for stopping
2739
2740 \return CDF_STATUS_SUCCESS - SME is stopped.
2741
2742 Other status means SME is failed to stop but caller should still
2743 consider SME is stopped.
2744 \sa
2745
2746 --------------------------------------------------------------------------*/
2747CDF_STATUS sme_stop(tHalHandle hHal, tHalStopType stopType)
2748{
2749 CDF_STATUS status = CDF_STATUS_E_FAILURE;
2750 CDF_STATUS fail_status = CDF_STATUS_SUCCESS;
2751 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
2752
2753#ifndef WLAN_FEATURE_MBSSID
2754 status = wlansap_stop(cds_get_global_context());
2755 if (!CDF_IS_STATUS_SUCCESS(status)) {
2756 sms_log(pMac, LOGE,
2757 "wlansap_stop failed during smeStop with status=%d",
2758 status);
2759 fail_status = status;
2760 }
2761#endif
2762
2763 p2p_stop(hHal);
2764
2765 status = csr_stop(pMac, stopType);
2766 if (!CDF_IS_STATUS_SUCCESS(status)) {
2767 sms_log(pMac, LOGE,
2768 "csr_stop failed during smeStop with status=%d", status);
2769 fail_status = status;
2770 }
2771
2772 purge_sme_cmd_list(pMac);
2773
2774 if (!CDF_IS_STATUS_SUCCESS(fail_status)) {
2775 status = fail_status;
2776 }
2777
2778 pMac->sme.state = SME_STATE_STOP;
2779
2780 return status;
2781}
2782
2783/*--------------------------------------------------------------------------
2784
2785 \brief sme_close() - Release all SME modules and their resources.
2786
2787 The function release each module in SME, PMC, CSR, etc. . Upon
2788 return, all modules are at closed state.
2789
2790 No SME APIs can be involved after smeClose except smeOpen.
2791 smeClose must be called before mac_close.
2792 This is a synchronous call
2793 \param hHal - The handle returned by mac_open
2794
2795 \return CDF_STATUS_SUCCESS - SME is successfully close.
2796
2797 Other status means SME is failed to be closed but caller still cannot
2798 call any other SME functions except smeOpen.
2799 \sa
2800
2801 --------------------------------------------------------------------------*/
2802CDF_STATUS sme_close(tHalHandle hHal)
2803{
2804 CDF_STATUS status = CDF_STATUS_E_FAILURE;
2805 CDF_STATUS fail_status = CDF_STATUS_SUCCESS;
2806 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
2807
2808 if (!pMac)
2809 return CDF_STATUS_E_FAILURE;
2810
2811 /* Note: pSession will be invalid from here on, do not access */
2812 status = csr_close(pMac);
2813 if (!CDF_IS_STATUS_SUCCESS(status)) {
2814 sms_log(pMac, LOGE,
2815 "csr_close failed during sme close with status=%d",
2816 status);
2817 fail_status = status;
2818 }
2819#ifndef WLAN_FEATURE_MBSSID
2820 status = wlansap_close(cds_get_global_context());
2821 if (!CDF_IS_STATUS_SUCCESS(status)) {
2822 sms_log(pMac, LOGE,
2823 "WLANSAP_close failed during sme close with status=%d",
2824 status);
2825 fail_status = status;
2826 }
2827#endif
2828
2829#ifndef WLAN_MDM_CODE_REDUCTION_OPT
2830 status = sme_qos_close(pMac);
2831 if (!CDF_IS_STATUS_SUCCESS(status)) {
2832 sms_log(pMac, LOGE,
2833 "Qos close failed during sme close with status=%d",
2834 status);
2835 fail_status = status;
2836 }
2837#endif
2838#ifdef FEATURE_OEM_DATA_SUPPORT
2839 status = oem_data_oem_data_req_close(hHal);
2840 if (!CDF_IS_STATUS_SUCCESS(status)) {
2841 sms_log(pMac, LOGE,
2842 "OEM DATA REQ close failed during sme close with status=%d",
2843 status);
2844 fail_status = status;
2845 }
2846#endif
2847 status = sme_ps_close(hHal);
2848 if (!CDF_IS_STATUS_SUCCESS(status)) {
2849 sms_log(pMac, LOGE,
2850 "sme_ps_close failed during smeClose status=%d",
2851 status);
2852 fail_status = status;
2853 }
2854
2855#if defined WLAN_FEATURE_VOWIFI
2856 status = rrm_close(hHal);
2857 if (!CDF_IS_STATUS_SUCCESS(status)) {
2858 sms_log(pMac, LOGE,
2859 "RRM close failed during sme close with status=%d",
2860 status);
2861 fail_status = status;
2862 }
2863#endif
2864
2865 sme_p2p_close(hHal);
2866
2867 free_sme_cmd_list(pMac);
2868
2869 if (!CDF_IS_STATUS_SUCCESS
2870 (cdf_mutex_destroy(&pMac->sme.lkSmeGlobalLock))) {
2871 fail_status = CDF_STATUS_E_FAILURE;
2872 }
2873
2874 if (!CDF_IS_STATUS_SUCCESS(fail_status)) {
2875 status = fail_status;
2876 }
2877
2878 pMac->sme.state = SME_STATE_STOP;
2879
2880 return status;
2881}
2882
2883/**
2884 * sme_scan_request() - wrapper function to Request a 11d or full scan from CSR.
2885 * @hal: hal global context
2886 * @session_id: session id
2887 * @scan_req: scan req
2888 * @callback: a callback function that scan calls upon finish, will not
2889 * be called if csr_scan_request returns error
2890 * @ctx: a pointer passed in for the callback
2891 *
2892 * This is a wrapper function to Request a 11d or full scan from CSR. This is
2893 * an asynchronous call
2894 *
2895 * Return: Status of operation
2896 */
2897CDF_STATUS sme_scan_request(tHalHandle hal, uint8_t session_id,
2898 tCsrScanRequest *scan_req,
2899 csr_scan_completeCallback callback, void *ctx)
2900{
2901 CDF_STATUS status = CDF_STATUS_E_FAILURE;
2902 tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
2903 struct ani_scan_req *scan_msg;
2904 cds_msg_t msg;
2905 uint32_t scan_req_id, scan_count;
2906
2907 MTRACE(cdf_trace(CDF_MODULE_ID_SME,
2908 TRACE_CODE_SME_RX_HDD_MSG_SCAN_REQ, session_id,
2909 scan_req->scanType));
2910 if (!mac_ctx->scan.fScanEnable) {
2911 sms_log(mac_ctx, LOGE, FL("fScanEnable false"));
2912 return status;
2913 }
2914
2915 scan_count = csr_ll_count(&mac_ctx->sme.smeScanCmdActiveList);
2916 if (scan_count >= mac_ctx->scan.max_scan_count) {
2917 sms_log(mac_ctx, LOGE, FL("Max scan reached"));
2918 return CDF_STATUS_E_FAILURE;
2919 }
2920 wma_get_scan_id(&scan_req_id);
2921 scan_req->scan_id = scan_req_id;
2922
2923 status = sme_acquire_global_lock(&mac_ctx->sme);
2924 if (!CDF_IS_STATUS_SUCCESS(status)) {
2925 sms_log(mac_ctx, LOGE, FL("Unable to acquire lock"));
2926 return status;
2927 }
2928 sms_log(mac_ctx, LOG1, FL(" called"));
2929 scan_msg = cdf_mem_malloc(sizeof(struct ani_scan_req));
2930 if (NULL == scan_msg) {
2931 sms_log(mac_ctx, LOGE,
2932 " scan_req: failed to allocate mem for msg");
2933 sme_release_global_lock(&mac_ctx->sme);
2934 return CDF_STATUS_E_NOMEM;
2935 }
2936 scan_msg->msg_type = eWNI_SME_SCAN_CMD;
2937 scan_msg->msg_len = (uint16_t) sizeof(struct ani_scan_req);
2938 scan_msg->session_id = session_id;
2939 scan_msg->callback = callback;
2940 scan_msg->ctx = ctx;
2941 scan_msg->scan_param = cdf_mem_malloc(sizeof(tCsrScanRequest));
2942 if (NULL == scan_msg->scan_param) {
2943 sms_log(mac_ctx, LOGE,
2944 "scan_req:failed to allocate mem for scanreq");
2945 sme_release_global_lock(&mac_ctx->sme);
2946 cdf_mem_free(scan_msg);
2947 return CDF_STATUS_E_NOMEM;
2948 }
2949 csr_scan_copy_request(mac_ctx, scan_msg->scan_param, scan_req);
2950 msg.type = eWNI_SME_SCAN_CMD;
2951 msg.bodyptr = scan_msg;
2952 msg.reserved = 0;
2953 msg.bodyval = 0;
2954 if (CDF_STATUS_SUCCESS !=
2955 cds_mq_post_message(CDS_MQ_ID_SME, &msg)) {
2956 sms_log(mac_ctx, LOGE,
2957 " sme_scan_req failed to post msg");
2958 csr_scan_free_request(mac_ctx, scan_msg->scan_param);
2959 cdf_mem_free(scan_msg);
2960 status = CDF_STATUS_E_FAILURE;
2961 }
2962 sme_release_global_lock(&mac_ctx->sme);
2963 return status;
2964}
2965
2966/* ---------------------------------------------------------------------------
2967 \fn sme_scan_get_result
2968 \brief a wrapper function to request scan results from CSR.
2969 This is a synchronous call
2970 \param pFilter - If pFilter is NULL, all cached results are returned
2971 \param phResult - an object for the result.
2972 \return CDF_STATUS
2973 ---------------------------------------------------------------------------*/
2974CDF_STATUS sme_scan_get_result(tHalHandle hHal, uint8_t sessionId,
2975 tCsrScanResultFilter *pFilter,
2976 tScanResultHandle *phResult)
2977{
2978 CDF_STATUS status = CDF_STATUS_E_FAILURE;
2979 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
2980
2981 MTRACE(cdf_trace(CDF_MODULE_ID_SME,
2982 TRACE_CODE_SME_RX_HDD_MSG_SCAN_GET_RESULTS, sessionId,
2983 0));
2984 sms_log(pMac, LOG2, FL("enter"));
2985 status = sme_acquire_global_lock(&pMac->sme);
2986 if (CDF_IS_STATUS_SUCCESS(status)) {
2987 status = csr_scan_get_result(hHal, pFilter, phResult);
2988 sme_release_global_lock(&pMac->sme);
2989 }
2990 sms_log(pMac, LOG2, FL("exit status %d"), status);
2991
2992 return status;
2993}
2994
2995/**
2996 * sme_get_ap_channel_from_scan_cache() - a wrapper function to get AP's
2997 * channel id from CSR by filtering the
2998 * result which matches our roam profile.
2999 * @profile: SAP adapter
3000 * @ap_chnl_id: pointer to channel id of SAP. Fill the value after finding the
3001 * best ap from scan cache.
3002 *
3003 * This function is written to get AP's channel id from CSR by filtering
3004 * the result which matches our roam profile. This is a synchronous call.
3005 *
3006 * Return: CDF_STATUS.
3007 */
3008CDF_STATUS sme_get_ap_channel_from_scan_cache(tHalHandle hal_handle,
3009 tCsrRoamProfile *profile,
3010 tScanResultHandle *scan_cache,
3011 uint8_t *ap_chnl_id)
3012{
3013 CDF_STATUS status = CDF_STATUS_E_FAILURE;
3014 tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal_handle);
3015 tCsrScanResultFilter *scan_filter = NULL;
3016 tScanResultHandle filtered_scan_result = NULL;
3017 tSirBssDescription first_ap_profile;
3018
3019 if (NULL == mac_ctx) {
3020 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
3021 FL("mac_ctx is NULL"));
3022 return CDF_STATUS_E_FAILURE;
3023 }
3024 scan_filter = cdf_mem_malloc(sizeof(tCsrScanResultFilter));
3025 if (NULL == scan_filter) {
3026 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
3027 FL("scan_filter mem alloc failed"));
3028 return CDF_STATUS_E_FAILURE;
3029 } else {
3030 cdf_mem_set(scan_filter, sizeof(tCsrScanResultFilter), 0);
3031 cdf_mem_set(&first_ap_profile, sizeof(tSirBssDescription), 0);
3032
3033 if (NULL == profile) {
3034 scan_filter->EncryptionType.numEntries = 1;
3035 scan_filter->EncryptionType.encryptionType[0]
3036 = eCSR_ENCRYPT_TYPE_NONE;
3037 } else {
3038 /* Here is the profile we need to connect to */
3039 status = csr_roam_prepare_filter_from_profile(mac_ctx,
3040 profile,
3041 scan_filter);
3042 }
3043
3044 if (CDF_STATUS_SUCCESS == status) {
3045 /* Save the WPS info */
3046 if (NULL != profile) {
3047 scan_filter->bWPSAssociation =
3048 profile->bWPSAssociation;
3049 scan_filter->bOSENAssociation =
3050 profile->bOSENAssociation;
3051 } else {
3052 scan_filter->bWPSAssociation = 0;
3053 scan_filter->bOSENAssociation = 0;
3054 }
3055 } else {
3056 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
3057 FL("Preparing the profile filter failed"));
3058 cdf_mem_free(scan_filter);
3059 return CDF_STATUS_E_FAILURE;
3060 }
3061 }
3062 status = sme_acquire_global_lock(&mac_ctx->sme);
3063 if (CDF_STATUS_SUCCESS == status) {
3064 status = csr_scan_get_result(hal_handle, scan_filter,
3065 &filtered_scan_result);
3066 if (CDF_STATUS_SUCCESS == status) {
3067 csr_get_bssdescr_from_scan_handle(filtered_scan_result,
3068 &first_ap_profile);
3069 *scan_cache = filtered_scan_result;
3070 if (0 != first_ap_profile.channelId) {
3071 *ap_chnl_id = first_ap_profile.channelId;
3072 CDF_TRACE(CDF_MODULE_ID_SME,
3073 CDF_TRACE_LEVEL_ERROR,
3074 FL("Found best AP & its on chnl[%d]"),
3075 first_ap_profile.channelId);
3076 } else {
3077 /*
3078 * This means scan result is empty
3079 * so set the channel to zero, caller should
3080 * take of zero channel id case.
3081 */
3082 *ap_chnl_id = 0;
3083 CDF_TRACE(CDF_MODULE_ID_SME,
3084 CDF_TRACE_LEVEL_ERROR,
3085 FL("Scan is empty, set chnl to 0"));
3086 status = CDF_STATUS_E_FAILURE;
3087 }
3088 } else {
3089 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
3090 FL("Failed to get scan get result"));
3091 status = CDF_STATUS_E_FAILURE;
3092 }
3093 csr_free_scan_filter(mac_ctx, scan_filter);
3094 sme_release_global_lock(&mac_ctx->sme);
3095 } else {
3096 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
3097 FL("Aquiring lock failed"));
3098 status = CDF_STATUS_E_FAILURE;
3099 }
3100
3101 cdf_mem_free(scan_filter);
3102
3103 return status;
3104}
3105
3106/**
3107 * sme_store_joinreq_param() - This function will pass station's join
3108 * request to store to csr.
3109 * @hal_handle: pointer to hal context.
3110 * @profile: pointer to station's roam profile.
3111 * @scan_cache: pointer to station's scan cache.
3112 * @roam_id: reference to roam_id variable being passed.
3113 * @session_id: station's session id.
3114 *
3115 * This function will pass station's join request further down to csr
3116 * to store it. this stored parameter will be used later.
3117 *
3118 * Return: true or false based on function's overall success.
3119 **/
3120bool sme_store_joinreq_param(tHalHandle hal_handle,
3121 tCsrRoamProfile *profile,
3122 tScanResultHandle scan_cache,
3123 uint32_t *roam_id,
3124 uint32_t session_id)
3125{
3126 tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal_handle);
3127 CDF_STATUS status = CDF_STATUS_E_FAILURE;
3128 bool ret_status = true;
3129
3130 MTRACE(cdf_trace(CDF_MODULE_ID_SME,
3131 TRACE_CODE_SME_RX_HDD_STORE_JOIN_REQ,
3132 session_id, 0));
3133 status = sme_acquire_global_lock(&mac_ctx->sme);
3134 if (CDF_STATUS_SUCCESS == status) {
3135 if (false == csr_store_joinreq_param(mac_ctx, profile,
3136 scan_cache, roam_id, session_id)) {
3137 ret_status = false;
3138 }
3139 sme_release_global_lock(&mac_ctx->sme);
3140 } else {
3141 ret_status = false;
3142 }
3143
3144 return ret_status;
3145}
3146
3147/**
3148 * sme_clear_joinreq_param() - This function will pass station's clear
3149 * the join request to csr.
3150 * @hal_handle: pointer to hal context.
3151 * @session_id: station's session id.
3152 *
3153 * This function will pass station's clear join request further down to csr
3154 * to cleanup.
3155 *
3156 * Return: true or false based on function's overall success.
3157 **/
3158bool sme_clear_joinreq_param(tHalHandle hal_handle,
3159 uint32_t session_id)
3160{
3161 tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal_handle);
3162 CDF_STATUS status = CDF_STATUS_E_FAILURE;
3163 bool ret_status = true;
3164
3165 MTRACE(cdf_trace(CDF_MODULE_ID_SME,
3166 TRACE_CODE_SME_RX_HDD_CLEAR_JOIN_REQ,
3167 session_id, 0));
3168 status = sme_acquire_global_lock(&mac_ctx->sme);
3169 if (CDF_STATUS_SUCCESS == status) {
3170 if (false == csr_clear_joinreq_param(mac_ctx,
3171 session_id)) {
3172 ret_status = false;
3173 }
3174 sme_release_global_lock(&mac_ctx->sme);
3175 } else {
3176 ret_status = false;
3177 }
3178
3179 return ret_status;
3180}
3181
3182/**
3183 * sme_issue_stored_joinreq() - This function will issues station's stored
3184 * the join request to csr.
3185 * @hal_handle: pointer to hal context.
3186 * @roam_id: reference to roam_id variable being passed.
3187 * @session_id: station's session id.
3188 *
3189 * This function will issue station's stored join request further down to csr
3190 * to proceed forward.
3191 *
3192 * Return: CDF_STATUS_SUCCESS or CDF_STATUS_E_FAILURE.
3193 **/
3194CDF_STATUS sme_issue_stored_joinreq(tHalHandle hal_handle,
3195 uint32_t *roam_id,
3196 uint32_t session_id)
3197{
3198 tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal_handle);
3199 CDF_STATUS status = CDF_STATUS_E_FAILURE;
3200 CDF_STATUS ret_status = CDF_STATUS_SUCCESS;
3201
3202 MTRACE(cdf_trace(CDF_MODULE_ID_SME,
3203 TRACE_CODE_SME_RX_HDD_ISSUE_JOIN_REQ,
3204 session_id, 0));
3205 status = sme_acquire_global_lock(&mac_ctx->sme);
3206 if (CDF_STATUS_SUCCESS == status) {
3207 if (CDF_STATUS_SUCCESS != csr_issue_stored_joinreq(mac_ctx,
3208 roam_id,
3209 session_id)) {
3210 ret_status = CDF_STATUS_E_FAILURE;
3211 }
3212 sme_release_global_lock(&mac_ctx->sme);
3213 } else {
3214 csr_clear_joinreq_param(mac_ctx, session_id);
3215 ret_status = CDF_STATUS_E_FAILURE;
3216 }
3217 return ret_status;
3218}
3219
3220/* ---------------------------------------------------------------------------
3221 \fn sme_scan_flush_result
3222 \brief a wrapper function to request CSR to clear scan results.
3223 This is a synchronous call
3224 \return CDF_STATUS
3225 ---------------------------------------------------------------------------*/
3226CDF_STATUS sme_scan_flush_result(tHalHandle hHal)
3227{
3228 CDF_STATUS status = CDF_STATUS_E_FAILURE;
3229 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
3230
3231 MTRACE(cdf_trace(CDF_MODULE_ID_SME,
3232 TRACE_CODE_SME_RX_HDD_MSG_SCAN_FLUSH_RESULTS,
3233 0, 0));
3234 status = sme_acquire_global_lock(&pMac->sme);
3235 if (CDF_IS_STATUS_SUCCESS(status)) {
3236 status = csr_scan_flush_result(hHal);
3237 sme_release_global_lock(&pMac->sme);
3238 }
3239
3240 return status;
3241}
3242
3243/* ---------------------------------------------------------------------------
3244 \fn sme_filter_scan_results
3245 \brief a wrapper function to request CSR to clear scan results.
3246 This is a synchronous call
3247 \param tHalHandle - HAL context handle
3248 \param sessionId - session id
3249 \return CDF_STATUS
3250 ---------------------------------------------------------------------------*/
3251CDF_STATUS sme_filter_scan_results(tHalHandle hHal, uint8_t sessionId)
3252{
3253 CDF_STATUS status = CDF_STATUS_SUCCESS;
3254 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
3255
3256 MTRACE(cdf_trace(CDF_MODULE_ID_SME,
3257 TRACE_CODE_SME_RX_HDD_MSG_SCAN_FLUSH_RESULTS,
3258 sessionId, 0));
3259 status = sme_acquire_global_lock(&pMac->sme);
3260 if (CDF_IS_STATUS_SUCCESS(status)) {
3261 csr_scan_filter_results(pMac);
3262 sme_release_global_lock(&pMac->sme);
3263 }
3264
3265 return status;
3266}
3267
3268CDF_STATUS sme_scan_flush_p2p_result(tHalHandle hHal, uint8_t sessionId)
3269{
3270 CDF_STATUS status = CDF_STATUS_E_FAILURE;
3271 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
3272
3273 MTRACE(cdf_trace(CDF_MODULE_ID_SME,
3274 TRACE_CODE_SME_RX_HDD_MSG_SCAN_FLUSH_P2PRESULTS,
3275 sessionId, 0));
3276 status = sme_acquire_global_lock(&pMac->sme);
3277 if (CDF_IS_STATUS_SUCCESS(status)) {
3278 status = csr_scan_flush_selective_result(hHal, true);
3279 sme_release_global_lock(&pMac->sme);
3280 }
3281
3282 return status;
3283}
3284
3285/* ---------------------------------------------------------------------------
3286 \fn sme_scan_result_get_first
3287 \brief a wrapper function to request CSR to returns the first element of
3288 scan result.
3289 This is a synchronous call
3290 \param hScanResult - returned from csr_scan_get_result
3291 \return tCsrScanResultInfo * - NULL if no result
3292 ---------------------------------------------------------------------------*/
3293tCsrScanResultInfo *sme_scan_result_get_first(tHalHandle hHal,
3294 tScanResultHandle hScanResult)
3295{
3296 CDF_STATUS status = CDF_STATUS_E_FAILURE;
3297 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
3298 tCsrScanResultInfo *pRet = NULL;
3299
3300 MTRACE(cdf_trace(CDF_MODULE_ID_SME,
3301 TRACE_CODE_SME_RX_HDD_MSG_SCAN_RESULT_GETFIRST,
3302 NO_SESSION, 0));
3303 status = sme_acquire_global_lock(&pMac->sme);
3304 if (CDF_IS_STATUS_SUCCESS(status)) {
3305 pRet = csr_scan_result_get_first(pMac, hScanResult);
3306 sme_release_global_lock(&pMac->sme);
3307 }
3308
3309 return pRet;
3310}
3311
3312/* ---------------------------------------------------------------------------
3313 \fn sme_scan_result_get_next
3314 \brief a wrapper function to request CSR to returns the next element of
3315 scan result. It can be called without calling csr_scan_result_get_first
3316 first
3317 This is a synchronous call
3318 \param hScanResult - returned from csr_scan_get_result
3319 \return Null if no result or reach the end
3320 ---------------------------------------------------------------------------*/
3321tCsrScanResultInfo *sme_scan_result_get_next(tHalHandle hHal,
3322 tScanResultHandle hScanResult)
3323{
3324 CDF_STATUS status = CDF_STATUS_E_FAILURE;
3325 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
3326 tCsrScanResultInfo *pRet = NULL;
3327
3328 MTRACE(cdf_trace(CDF_MODULE_ID_SME,
3329 TRACE_CODE_SME_RX_HDD_MSG_SCAN_RESULT_GETNEXT,
3330 NO_SESSION, 0));
3331 status = sme_acquire_global_lock(&pMac->sme);
3332 if (CDF_IS_STATUS_SUCCESS(status)) {
3333 pRet = csr_scan_result_get_next(pMac, hScanResult);
3334 sme_release_global_lock(&pMac->sme);
3335 }
3336
3337 return pRet;
3338}
3339
3340/* ---------------------------------------------------------------------------
3341 \fn sme_scan_result_purge
3342 \brief a wrapper function to request CSR to remove all items(tCsrScanResult)
3343 in the list and free memory for each item
3344 This is a synchronous call
3345 \param hScanResult - returned from csr_scan_get_result. hScanResult is
3346 considered gone by
3347 calling this function and even before this function reutrns.
3348 \return CDF_STATUS
3349 ---------------------------------------------------------------------------*/
3350CDF_STATUS sme_scan_result_purge(tHalHandle hHal, tScanResultHandle hScanResult)
3351{
3352 CDF_STATUS status = CDF_STATUS_E_FAILURE;
3353 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
3354
3355 MTRACE(cdf_trace(CDF_MODULE_ID_SME,
3356 TRACE_CODE_SME_RX_HDD_MSG_SCAN_RESULT_PURGE,
3357 NO_SESSION, 0));
3358 status = sme_acquire_global_lock(&pMac->sme);
3359 if (CDF_IS_STATUS_SUCCESS(status)) {
3360 status = csr_scan_result_purge(hHal, hScanResult);
3361 sme_release_global_lock(&pMac->sme);
3362 }
3363
3364 return status;
3365}
3366
3367/* ---------------------------------------------------------------------------
3368 \fn sme_scan_get_pmkid_candidate_list
3369 \brief a wrapper function to return the PMKID candidate list
3370 This is a synchronous call
3371 \param pPmkidList - caller allocated buffer point to an array of
3372 tPmkidCandidateInfo
3373 \param pNumItems - pointer to a variable that has the number of
3374 tPmkidCandidateInfo allocated when retruning, this is
3375 either the number needed or number of items put into
3376 pPmkidList
3377 \return CDF_STATUS - when fail, it usually means the buffer allocated is not
3378 big enough and pNumItems
3379 has the number of tPmkidCandidateInfo.
3380 \Note: pNumItems is a number of tPmkidCandidateInfo,
3381 not sizeof(tPmkidCandidateInfo) * something
3382 ---------------------------------------------------------------------------*/
3383CDF_STATUS sme_scan_get_pmkid_candidate_list(tHalHandle hHal, uint8_t sessionId,
3384 tPmkidCandidateInfo *pPmkidList,
3385 uint32_t *pNumItems)
3386{
3387 CDF_STATUS status = CDF_STATUS_E_FAILURE;
3388 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
3389
3390 status = sme_acquire_global_lock(&pMac->sme);
3391 if (CDF_IS_STATUS_SUCCESS(status)) {
3392 status =
3393 csr_scan_get_pmkid_candidate_list(pMac, sessionId,
3394 pPmkidList,
3395 pNumItems);
3396 sme_release_global_lock(&pMac->sme);
3397 }
3398
3399 return status;
3400}
3401
3402eCsrPhyMode sme_get_phy_mode(tHalHandle hHal)
3403{
3404 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
3405 return pMac->roam.configParam.phyMode;
3406}
3407
3408/* ---------------------------------------------------------------------------
3409 \fn sme_get_channel_bonding_mode5_g
3410 \brief get the channel bonding mode for 5G band
3411 \param hHal - HAL handle
3412 \return channel bonding mode for 5G
3413 ---------------------------------------------------------------------------*/
3414uint32_t sme_get_channel_bonding_mode5_g(tHalHandle hHal)
3415{
3416 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
3417 tSmeConfigParams smeConfig;
3418
3419 sme_get_config_param(pMac, &smeConfig);
3420
3421 return smeConfig.csrConfig.channelBondingMode5GHz;
3422}
3423
3424/* ---------------------------------------------------------------------------
3425 \fn sme_get_channel_bonding_mode24_g
3426 \brief get the channel bonding mode for 2.4G band
3427 \param hHal - HAL handle
3428 \return channel bonding mode for 2.4G
3429 ---------------------------------------------------------------------------*/
3430uint32_t sme_get_channel_bonding_mode24_g(tHalHandle hHal)
3431{
3432 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
3433 tSmeConfigParams smeConfig;
3434
3435 sme_get_config_param(pMac, &smeConfig);
3436
3437 return smeConfig.csrConfig.channelBondingMode24GHz;
3438}
3439
3440/* ---------------------------------------------------------------------------
3441 \fn sme_roam_connect
3442 \brief a wrapper function to request CSR to inititiate an association
3443 This is an asynchronous call.
3444 \param sessionId - the sessionId returned by sme_open_session.
3445 \param pProfile - description of the network to which to connect
3446 \param hBssListIn - a list of BSS descriptor to roam to. It is returned
3447 from csr_scan_get_result
3448 \param pRoamId - to get back the request ID
3449 \return CDF_STATUS
3450 ---------------------------------------------------------------------------*/
3451CDF_STATUS sme_roam_connect(tHalHandle hHal, uint8_t sessionId,
3452 tCsrRoamProfile *pProfile, uint32_t *pRoamId)
3453{
3454 CDF_STATUS status = CDF_STATUS_E_FAILURE;
3455 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
3456
3457 if (!pMac) {
3458 return CDF_STATUS_E_FAILURE;
3459 }
3460
3461 MTRACE(cdf_trace(CDF_MODULE_ID_SME,
3462 TRACE_CODE_SME_RX_HDD_MSG_CONNECT, sessionId, 0));
3463 sms_log(pMac, LOG2, FL("enter"));
3464 status = sme_acquire_global_lock(&pMac->sme);
3465 if (CDF_IS_STATUS_SUCCESS(status)) {
3466 if (CSR_IS_SESSION_VALID(pMac, sessionId)) {
3467 status =
3468 csr_roam_connect(pMac, sessionId, pProfile,
3469 pRoamId);
3470 } else {
3471 sms_log(pMac, LOGE, FL("invalid sessionID %d"),
3472 sessionId);
3473 status = CDF_STATUS_E_INVAL;
3474 }
3475 sme_release_global_lock(&pMac->sme);
3476 } else {
3477 sms_log(pMac, LOGE, FL("sme_acquire_global_lock failed"));
3478 }
3479
3480 return status;
3481}
3482
3483/* ---------------------------------------------------------------------------
3484
3485 \fn sme_set_phy_mode
3486
3487 \brief Changes the PhyMode.
3488
3489 \param hHal - The handle returned by mac_open.
3490
3491 \param phyMode new phyMode which is to set
3492
3493 \return CDF_STATUS SUCCESS.
3494
3495 -------------------------------------------------------------------------------*/
3496CDF_STATUS sme_set_phy_mode(tHalHandle hHal, eCsrPhyMode phyMode)
3497{
3498 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
3499
3500 if (NULL == pMac) {
3501 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
3502 "%s: invalid context", __func__);
3503 return CDF_STATUS_E_FAILURE;
3504 }
3505
3506 pMac->roam.configParam.phyMode = phyMode;
3507 pMac->roam.configParam.uCfgDot11Mode =
3508 csr_get_cfg_dot11_mode_from_csr_phy_mode(NULL,
3509 pMac->roam.configParam.phyMode,
3510 pMac->roam.configParam.
3511 ProprietaryRatesEnabled);
3512
3513 return CDF_STATUS_SUCCESS;
3514}
3515
3516/* ---------------------------------------------------------------------------
3517 \fn sme_roam_reassoc
3518 \brief a wrapper function to request CSR to inititiate a re-association
3519 \param pProfile - can be NULL to join the currently connected AP. In that
3520 case modProfileFields should carry the modified field(s) which could trigger
3521 reassoc
3522 \param modProfileFields - fields which are part of tCsrRoamConnectedProfile
3523 that might need modification dynamically once STA is up & running and this
3524 could trigger a reassoc
3525 \param pRoamId - to get back the request ID
3526 \return CDF_STATUS
3527 -------------------------------------------------------------------------------*/
3528CDF_STATUS sme_roam_reassoc(tHalHandle hHal, uint8_t sessionId,
3529 tCsrRoamProfile *pProfile,
3530 tCsrRoamModifyProfileFields modProfileFields,
3531 uint32_t *pRoamId, bool fForce)
3532{
3533 CDF_STATUS status = CDF_STATUS_E_FAILURE;
3534 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
3535
3536 MTRACE(cdf_trace(CDF_MODULE_ID_SME,
3537 TRACE_CODE_SME_RX_HDD_ROAM_REASSOC, sessionId, 0));
3538 sms_log(pMac, LOG2, FL("enter"));
3539 status = sme_acquire_global_lock(&pMac->sme);
3540 if (CDF_IS_STATUS_SUCCESS(status)) {
3541 if (CSR_IS_SESSION_VALID(pMac, sessionId)) {
3542 if ((NULL == pProfile) && (fForce == 1)) {
3543 status =
3544 csr_reassoc(pMac, sessionId,
3545 &modProfileFields, pRoamId,
3546 fForce);
3547 } else {
3548 status =
3549 csr_roam_reassoc(pMac, sessionId, pProfile,
3550 modProfileFields, pRoamId);
3551 }
3552 } else {
3553 status = CDF_STATUS_E_INVAL;
3554 }
3555 sme_release_global_lock(&pMac->sme);
3556 }
3557
3558 return status;
3559}
3560
3561/* ---------------------------------------------------------------------------
3562 \fn sme_roam_connect_to_last_profile
3563 \brief a wrapper function to request CSR to disconnect and reconnect with
3564 the same profile
3565 This is an asynchronous call.
3566 \return CDF_STATUS. It returns fail if currently connected
3567 ---------------------------------------------------------------------------*/
3568CDF_STATUS sme_roam_connect_to_last_profile(tHalHandle hHal, uint8_t sessionId)
3569{
3570 CDF_STATUS status = CDF_STATUS_E_FAILURE;
3571 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
3572
3573 MTRACE(cdf_trace(CDF_MODULE_ID_SME,
3574 TRACE_CODE_SME_RX_HDD_ROAM_GET_CONNECTPROFILE,
3575 sessionId, 0));
3576 status = sme_acquire_global_lock(&pMac->sme);
3577 if (CDF_IS_STATUS_SUCCESS(status)) {
3578 if (CSR_IS_SESSION_VALID(pMac, sessionId)) {
3579 status = csr_roam_connect_to_last_profile(pMac, sessionId);
3580 } else {
3581 status = CDF_STATUS_E_INVAL;
3582 }
3583 sme_release_global_lock(&pMac->sme);
3584 }
3585
3586 return status;
3587}
3588
3589/* ---------------------------------------------------------------------------
3590 \fn sme_roam_disconnect
3591 \brief a wrapper function to request CSR to disconnect from a network
3592 This is an asynchronous call.
3593 \param reason -- To indicate the reason for disconnecting. Currently, only
3594 eCSR_DISCONNECT_REASON_MIC_ERROR is meanful.
3595 \return CDF_STATUS
3596 ---------------------------------------------------------------------------*/
3597CDF_STATUS sme_roam_disconnect(tHalHandle hHal, uint8_t sessionId,
3598 eCsrRoamDisconnectReason reason)
3599{
3600 CDF_STATUS status = CDF_STATUS_E_FAILURE;
3601 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
3602
3603 MTRACE(cdf_trace(CDF_MODULE_ID_SME,
3604 TRACE_CODE_SME_RX_HDD_ROAM_DISCONNECT, sessionId,
3605 reason));
3606 sms_log(pMac, LOG2, FL("enter"));
3607 status = sme_acquire_global_lock(&pMac->sme);
3608 if (CDF_IS_STATUS_SUCCESS(status)) {
3609 if (CSR_IS_SESSION_VALID(pMac, sessionId)) {
3610 status = csr_roam_disconnect(pMac, sessionId, reason);
3611 } else {
3612 status = CDF_STATUS_E_INVAL;
3613 }
3614 sme_release_global_lock(&pMac->sme);
3615 }
3616
3617 return status;
3618}
3619
3620/* ---------------------------------------------------------------------------
3621 \fn sme_roam_stop_bss
3622 \brief To stop BSS for Soft AP. This is an asynchronous API.
3623 \param hHal - Global structure
3624 \param sessionId - sessionId of SoftAP
3625 \return CDF_STATUS SUCCESS Roam callback will be called to indicate actual results
3626 -------------------------------------------------------------------------------*/
3627CDF_STATUS sme_roam_stop_bss(tHalHandle hHal, uint8_t sessionId)
3628{
3629 CDF_STATUS status = CDF_STATUS_E_FAILURE;
3630 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
3631
3632 sms_log(pMac, LOG2, FL("enter"));
3633 status = sme_acquire_global_lock(&pMac->sme);
3634 if (CDF_IS_STATUS_SUCCESS(status)) {
3635 if (CSR_IS_SESSION_VALID(pMac, sessionId)) {
3636 status = csr_roam_issue_stop_bss_cmd(pMac, sessionId, true);
3637 } else {
3638 status = CDF_STATUS_E_INVAL;
3639 }
3640 sme_release_global_lock(&pMac->sme);
3641 }
3642
3643 return status;
3644}
3645
3646/* ---------------------------------------------------------------------------
3647 \fn sme_roam_disconnect_sta
3648 \brief To disassociate a station. This is an asynchronous API.
3649 \param hHal - Global structure
3650 \param sessionId - sessionId of SoftAP
3651 \param pPeerMacAddr - Caller allocated memory filled with peer MAC address (6 bytes)
3652 \return CDF_STATUS SUCCESS Roam callback will be called to indicate actual results
3653 -------------------------------------------------------------------------------*/
3654CDF_STATUS sme_roam_disconnect_sta(tHalHandle hHal, uint8_t sessionId,
3655 const uint8_t *pPeerMacAddr)
3656{
3657 CDF_STATUS status = CDF_STATUS_E_FAILURE;
3658 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
3659
3660 if (NULL == pMac) {
3661 CDF_ASSERT(0);
3662 return status;
3663 }
3664
3665 status = sme_acquire_global_lock(&pMac->sme);
3666 if (CDF_IS_STATUS_SUCCESS(status)) {
3667 if (CSR_IS_SESSION_VALID(pMac, sessionId)) {
3668 status = csr_roam_issue_disassociate_sta_cmd(pMac,
3669 sessionId, pPeerMacAddr,
3670 eSIR_MAC_DEAUTH_LEAVING_BSS_REASON);
3671 } else {
3672 status = CDF_STATUS_E_INVAL;
3673 }
3674 sme_release_global_lock(&pMac->sme);
3675 }
3676
3677 return status;
3678}
3679
3680/**
3681 * sme_roam_deauth_sta() - deauthenticate a station
3682 * @hHal: Global structure
3683 * @sessionId: SessionId of SoftAP
3684 * @pDelStaParams: Pointer to parameters of the station to deauthenticate
3685 *
3686 * To disassociate a station. This is an asynchronous API.
3687 *
3688 * Return: CDF_STATUS_SUCCESS on success or another CDF_STATUS error
3689 * code on error. Roam callback will be called to indicate actual
3690 * result
3691 */
3692CDF_STATUS sme_roam_deauth_sta(tHalHandle hHal, uint8_t sessionId,
3693 struct tagCsrDelStaParams *pDelStaParams)
3694{
3695 CDF_STATUS status = CDF_STATUS_E_FAILURE;
3696 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
3697
3698 if (NULL == pMac) {
3699 CDF_ASSERT(0);
3700 return status;
3701 }
3702
3703 status = sme_acquire_global_lock(&pMac->sme);
3704 if (CDF_IS_STATUS_SUCCESS(status)) {
3705 if (CSR_IS_SESSION_VALID(pMac, sessionId)) {
3706 status =
3707 csr_roam_issue_deauth_sta_cmd(pMac, sessionId,
3708 pDelStaParams);
3709 } else {
3710 status = CDF_STATUS_E_INVAL;
3711 }
3712 sme_release_global_lock(&pMac->sme);
3713 }
3714
3715 return status;
3716}
3717
3718/* ---------------------------------------------------------------------------
3719 \fn sme_roam_tkip_counter_measures
3720 \brief To start or stop TKIP counter measures. This is an asynchronous API.
3721 \param sessionId - sessionId of SoftAP
3722 \param pPeerMacAddr - Caller allocated memory filled with peer MAC address (6 bytes)
3723 \return CDF_STATUS
3724 -------------------------------------------------------------------------------*/
3725CDF_STATUS sme_roam_tkip_counter_measures(tHalHandle hHal, uint8_t sessionId,
3726 bool bEnable)
3727{
3728 CDF_STATUS status = CDF_STATUS_E_FAILURE;
3729 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
3730
3731 if (NULL == pMac) {
3732 CDF_ASSERT(0);
3733 return status;
3734 }
3735
3736 status = sme_acquire_global_lock(&pMac->sme);
3737 if (CDF_IS_STATUS_SUCCESS(status)) {
3738 if (CSR_IS_SESSION_VALID(pMac, sessionId)) {
3739 status =
3740 csr_roam_issue_tkip_counter_measures(pMac, sessionId,
3741 bEnable);
3742 } else {
3743 status = CDF_STATUS_E_INVAL;
3744 }
3745 sme_release_global_lock(&pMac->sme);
3746 }
3747
3748 return status;
3749}
3750
3751/* ---------------------------------------------------------------------------
3752 \fn sme_roam_get_associated_stas
3753 \brief To probe the list of associated stations from various modules
3754 of CORE stack.
3755 \This is an asynchronous API.
3756 \param sessionId - sessionId of SoftAP
3757 \param modId - Module from whom list of associtated stations is
3758 to be probed. If an invalid module is passed then
3759 by default CDF_MODULE_ID_PE will be probed.
3760 \param pUsrContext - Opaque HDD context
3761 \param pfnSapEventCallback - Sap event callback in HDD
3762 \param pAssocBuf - Caller allocated memory to be filled with associatd
3763 stations info
3764 \return CDF_STATUS
3765 -------------------------------------------------------------------------------*/
3766CDF_STATUS sme_roam_get_associated_stas(tHalHandle hHal, uint8_t sessionId,
3767 CDF_MODULE_ID modId, void *pUsrContext,
3768 void *pfnSapEventCallback,
3769 uint8_t *pAssocStasBuf)
3770{
3771 CDF_STATUS status = CDF_STATUS_E_FAILURE;
3772 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
3773
3774 if (NULL == pMac) {
3775 CDF_ASSERT(0);
3776 return status;
3777 }
3778
3779 status = sme_acquire_global_lock(&pMac->sme);
3780 if (CDF_IS_STATUS_SUCCESS(status)) {
3781 if (CSR_IS_SESSION_VALID(pMac, sessionId)) {
3782 status =
3783 csr_roam_get_associated_stas(pMac, sessionId, modId,
3784 pUsrContext,
3785 pfnSapEventCallback,
3786 pAssocStasBuf);
3787 } else {
3788 status = CDF_STATUS_E_INVAL;
3789 }
3790 sme_release_global_lock(&pMac->sme);
3791 }
3792
3793 return status;
3794}
3795
3796/* ---------------------------------------------------------------------------
3797 \fn sme_roam_get_wps_session_overlap
3798 \brief To get the WPS PBC session overlap information.
3799 \This is an asynchronous API.
3800 \param sessionId - sessionId of SoftAP
3801 \param pUsrContext - Opaque HDD context
3802 \param pfnSapEventCallback - Sap event callback in HDD
3803 \pRemoveMac - pointer to Mac address which needs to be removed from session
3804 \return CDF_STATUS
3805 -------------------------------------------------------------------------------*/
3806CDF_STATUS sme_roam_get_wps_session_overlap(tHalHandle hHal, uint8_t sessionId,
3807 void *pUsrContext, void
3808 *pfnSapEventCallback,
3809 struct cdf_mac_addr pRemoveMac)
3810{
3811 CDF_STATUS status = CDF_STATUS_E_FAILURE;
3812 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
3813
3814 if (NULL == pMac) {
3815 CDF_ASSERT(0);
3816 return status;
3817 }
3818
3819 status = sme_acquire_global_lock(&pMac->sme);
3820 if (CDF_IS_STATUS_SUCCESS(status)) {
3821 if (CSR_IS_SESSION_VALID(pMac, sessionId)) {
3822 status =
3823 csr_roam_get_wps_session_overlap(pMac, sessionId,
3824 pUsrContext,
3825 pfnSapEventCallback,
3826 pRemoveMac);
3827 } else {
3828 status = CDF_STATUS_E_INVAL;
3829 }
3830 sme_release_global_lock(&pMac->sme);
3831 }
3832
3833 return status;
3834}
3835
3836/* ---------------------------------------------------------------------------
3837 \fn sme_roam_get_connect_state
3838 \brief a wrapper function to request CSR to return the current connect state
3839 of Roaming
3840 This is a synchronous call.
3841 \return CDF_STATUS
3842 ---------------------------------------------------------------------------*/
3843CDF_STATUS sme_roam_get_connect_state(tHalHandle hHal, uint8_t sessionId,
3844 eCsrConnectState *pState)
3845{
3846 CDF_STATUS status = CDF_STATUS_E_FAILURE;
3847 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
3848
3849 status = sme_acquire_global_lock(&pMac->sme);
3850 if (CDF_IS_STATUS_SUCCESS(status)) {
3851 if (CSR_IS_SESSION_VALID(pMac, sessionId)) {
3852 status =
3853 csr_roam_get_connect_state(pMac, sessionId, pState);
3854 } else {
3855 status = CDF_STATUS_E_INVAL;
3856 }
3857 sme_release_global_lock(&pMac->sme);
3858 }
3859
3860 return status;
3861}
3862
3863/* ---------------------------------------------------------------------------
3864 \fn sme_roam_get_connect_profile
3865 \brief a wrapper function to request CSR to return the current connect
3866 profile. Caller must call csr_roam_free_connect_profile after it is done
3867 and before reuse for another csr_roam_get_connect_profile call.
3868 This is a synchronous call.
3869 \param pProfile - pointer to a caller allocated structure
3870 tCsrRoamConnectedProfile
3871 \return CDF_STATUS. Failure if not connected
3872 ---------------------------------------------------------------------------*/
3873CDF_STATUS sme_roam_get_connect_profile(tHalHandle hHal, uint8_t sessionId,
3874 tCsrRoamConnectedProfile *pProfile)
3875{
3876 CDF_STATUS status = CDF_STATUS_E_FAILURE;
3877 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
3878
3879 MTRACE(cdf_trace(CDF_MODULE_ID_SME,
3880 TRACE_CODE_SME_RX_HDD_ROAM_GET_CONNECTPROFILE,
3881 sessionId, 0));
3882 status = sme_acquire_global_lock(&pMac->sme);
3883 if (CDF_IS_STATUS_SUCCESS(status)) {
3884 if (CSR_IS_SESSION_VALID(pMac, sessionId)) {
3885 status =
3886 csr_roam_get_connect_profile(pMac, sessionId, pProfile);
3887 } else {
3888 status = CDF_STATUS_E_INVAL;
3889 }
3890 sme_release_global_lock(&pMac->sme);
3891 }
3892
3893 return status;
3894}
3895
3896/* ---------------------------------------------------------------------------
3897 \fn sme_roam_free_connect_profile
3898 \brief a wrapper function to request CSR to free and reinitialize the
3899 profile returned previously by csr_roam_get_connect_profile.
3900 This is a synchronous call.
3901 \param pProfile - pointer to a caller allocated structure
3902 tCsrRoamConnectedProfile
3903 \return CDF_STATUS.
3904 ---------------------------------------------------------------------------*/
3905CDF_STATUS sme_roam_free_connect_profile(tHalHandle hHal,
3906 tCsrRoamConnectedProfile *pProfile)
3907{
3908 CDF_STATUS status = CDF_STATUS_E_FAILURE;
3909 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
3910
3911 MTRACE(cdf_trace(CDF_MODULE_ID_SME,
3912 TRACE_CODE_SME_RX_HDD_ROAM_FREE_CONNECTPROFILE,
3913 NO_SESSION, 0));
3914 status = sme_acquire_global_lock(&pMac->sme);
3915 if (CDF_IS_STATUS_SUCCESS(status)) {
3916 status = csr_roam_free_connect_profile(pMac, pProfile);
3917 sme_release_global_lock(&pMac->sme);
3918 }
3919
3920 return status;
3921}
3922
3923/* ---------------------------------------------------------------------------
3924 \fn sme_roam_set_pmkid_cache
3925 \brief a wrapper function to request CSR to return the PMKID candidate list
3926 This is a synchronous call.
3927 \param pPMKIDCache - caller allocated buffer point to an array of
3928 tPmkidCacheInfo
3929 \param numItems - a variable that has the number of tPmkidCacheInfo
3930 allocated when retruning, this is either the number needed
3931 or number of items put into pPMKIDCache
3932 \param update_entire_cache - this bool value specifies if the entire pmkid
3933 cache should be overwritten or should it be
3934 updated entry by entry.
3935 \return CDF_STATUS - when fail, it usually means the buffer allocated is not
3936 big enough and pNumItems has the number of
3937 tPmkidCacheInfo.
3938 \Note: pNumItems is a number of tPmkidCacheInfo,
3939 not sizeof(tPmkidCacheInfo) * something
3940 ---------------------------------------------------------------------------*/
3941CDF_STATUS sme_roam_set_pmkid_cache(tHalHandle hHal, uint8_t sessionId,
3942 tPmkidCacheInfo *pPMKIDCache,
3943 uint32_t numItems, bool update_entire_cache)
3944{
3945 CDF_STATUS status = CDF_STATUS_E_FAILURE;
3946 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
3947
3948 MTRACE(cdf_trace(CDF_MODULE_ID_SME,
3949 TRACE_CODE_SME_RX_HDD_ROAM_SET_PMKIDCACHE, sessionId,
3950 numItems));
3951 status = sme_acquire_global_lock(&pMac->sme);
3952 if (CDF_IS_STATUS_SUCCESS(status)) {
3953 if (CSR_IS_SESSION_VALID(pMac, sessionId)) {
3954 status =
3955 csr_roam_set_pmkid_cache(pMac, sessionId, pPMKIDCache,
3956 numItems, update_entire_cache);
3957 } else {
3958 status = CDF_STATUS_E_INVAL;
3959 }
3960 sme_release_global_lock(&pMac->sme);
3961 }
3962
3963 return status;
3964}
3965
3966CDF_STATUS sme_roam_del_pmkid_from_cache(tHalHandle hHal, uint8_t sessionId,
3967 const uint8_t *pBSSId, bool flush_cache)
3968{
3969 CDF_STATUS status = CDF_STATUS_E_FAILURE;
3970 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
3971 status = sme_acquire_global_lock(&pMac->sme);
3972 if (CDF_IS_STATUS_SUCCESS(status)) {
3973 if (CSR_IS_SESSION_VALID(pMac, sessionId)) {
3974 status = csr_roam_del_pmkid_from_cache(pMac, sessionId,
3975 pBSSId, flush_cache);
3976 } else {
3977 status = CDF_STATUS_E_INVAL;
3978 }
3979 sme_release_global_lock(&pMac->sme);
3980 }
3981 return status;
3982}
3983
3984#ifdef WLAN_FEATURE_ROAM_OFFLOAD
3985/* ---------------------------------------------------------------------------
3986 * \fn sme_roam_set_psk_pmk
3987 * \brief a wrapper function to request CSR to save PSK/PMK
3988 * This is a synchronous call.
3989 * \param hHal - Global structure
3990 * \param sessionId - SME sessionId
3991 * \param pPSK_PMK - pointer to an array of Psk[]/Pmk
3992 * \param pmk_len - Length could be only 16 bytes in case if LEAP
3993 * connections. Need to pass this information to
3994 * firmware.
3995 * \return CDF_STATUS -status whether PSK/PMK is set or not
3996 *---------------------------------------------------------------------------
3997 */
3998CDF_STATUS sme_roam_set_psk_pmk(tHalHandle hHal, uint8_t sessionId,
3999 uint8_t *pPSK_PMK, size_t pmk_len)
4000{
4001 CDF_STATUS status = CDF_STATUS_E_FAILURE;
4002 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
4003 status = sme_acquire_global_lock(&pMac->sme);
4004 if (CDF_IS_STATUS_SUCCESS(status)) {
4005 if (CSR_IS_SESSION_VALID(pMac, sessionId)) {
4006 status =
4007 csr_roam_set_psk_pmk(pMac, sessionId, pPSK_PMK,
4008 pmk_len);
4009 } else {
4010 status = CDF_STATUS_E_INVAL;
4011 }
4012 sme_release_global_lock(&pMac->sme);
4013 }
4014 return status;
4015}
4016#endif
4017/* ---------------------------------------------------------------------------
4018 \fn sme_roam_get_security_req_ie
4019 \brief a wrapper function to request CSR to return the WPA or RSN or WAPI IE CSR
4020 passes to PE to JOIN request or START_BSS request
4021 This is a synchronous call.
4022 \param pLen - caller allocated memory that has the length of pBuf as input.
4023 Upon returned, *pLen has the needed or IE length in pBuf.
4024 \param pBuf - Caller allocated memory that contain the IE field, if any,
4025 upon return
4026 \param secType - Specifies whether looking for WPA/WPA2/WAPI IE
4027 \return CDF_STATUS - when fail, it usually means the buffer allocated is not
4028 big enough
4029 ---------------------------------------------------------------------------*/
4030CDF_STATUS sme_roam_get_security_req_ie(tHalHandle hHal, uint8_t sessionId,
4031 uint32_t *pLen, uint8_t *pBuf,
4032 eCsrSecurityType secType)
4033{
4034 CDF_STATUS status = CDF_STATUS_E_FAILURE;
4035 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
4036
4037 status = sme_acquire_global_lock(&pMac->sme);
4038 if (CDF_IS_STATUS_SUCCESS(status)) {
4039 if (CSR_IS_SESSION_VALID(pMac, sessionId)) {
4040 status =
4041 csr_roam_get_wpa_rsn_req_ie(hHal, sessionId, pLen, pBuf);
4042 } else {
4043 status = CDF_STATUS_E_INVAL;
4044 }
4045 sme_release_global_lock(&pMac->sme);
4046 }
4047
4048 return status;
4049}
4050
4051/* ---------------------------------------------------------------------------
4052 \fn sme_roam_get_security_rsp_ie
4053 \brief a wrapper function to request CSR to return the WPA or RSN or
4054 WAPI IE from the beacon or probe rsp if connected
4055 This is a synchronous call.
4056 \param pLen - caller allocated memory that has the length of pBuf as input.
4057 Upon returned, *pLen has the needed or IE length in pBuf.
4058 \param pBuf - Caller allocated memory that contain the IE field, if any,
4059 upon return
4060 \param secType - Specifies whether looking for WPA/WPA2/WAPI IE
4061 \return CDF_STATUS - when fail, it usually means the buffer allocated is not
4062 big enough
4063 ---------------------------------------------------------------------------*/
4064CDF_STATUS sme_roam_get_security_rsp_ie(tHalHandle hHal, uint8_t sessionId,
4065 uint32_t *pLen, uint8_t *pBuf,
4066 eCsrSecurityType secType)
4067{
4068 CDF_STATUS status = CDF_STATUS_E_FAILURE;
4069 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
4070
4071 status = sme_acquire_global_lock(&pMac->sme);
4072 if (CDF_IS_STATUS_SUCCESS(status)) {
4073 if (CSR_IS_SESSION_VALID(pMac, sessionId)) {
4074 status =
4075 csr_roam_get_wpa_rsn_rsp_ie(pMac, sessionId, pLen, pBuf);
4076 } else {
4077 status = CDF_STATUS_E_INVAL;
4078 }
4079 sme_release_global_lock(&pMac->sme);
4080 }
4081
4082 return status;
4083
4084}
4085
4086/* ---------------------------------------------------------------------------
4087 \fn sme_roam_get_num_pmkid_cache
4088 \brief a wrapper function to request CSR to return number of PMKID cache
4089 entries
4090 This is a synchronous call.
4091 \return uint32_t - the number of PMKID cache entries
4092 ---------------------------------------------------------------------------*/
4093uint32_t sme_roam_get_num_pmkid_cache(tHalHandle hHal, uint8_t sessionId)
4094{
4095 CDF_STATUS status = CDF_STATUS_E_FAILURE;
4096 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
4097 uint32_t numPmkidCache = 0;
4098
4099 status = sme_acquire_global_lock(&pMac->sme);
4100 if (CDF_IS_STATUS_SUCCESS(status)) {
4101 if (CSR_IS_SESSION_VALID(pMac, sessionId)) {
4102 numPmkidCache =
4103 csr_roam_get_num_pmkid_cache(pMac, sessionId);
4104 status = CDF_STATUS_SUCCESS;
4105 } else {
4106 status = CDF_STATUS_E_INVAL;
4107 }
4108 sme_release_global_lock(&pMac->sme);
4109 }
4110
4111 return numPmkidCache;
4112}
4113
4114/* ---------------------------------------------------------------------------
4115 \fn sme_roam_get_pmkid_cache
4116 \brief a wrapper function to request CSR to return PMKID cache from CSR
4117 This is a synchronous call.
4118 \param pNum - caller allocated memory that has the space of the number of
4119 pBuf tPmkidCacheInfo as input. Upon returned, *pNum has the
4120 needed or actually number in tPmkidCacheInfo.
4121 \param pPmkidCache - Caller allocated memory that contains PMKID cache, if
4122 any, upon return
4123 \return CDF_STATUS - when fail, it usually means the buffer allocated is not
4124 big enough
4125 ---------------------------------------------------------------------------*/
4126CDF_STATUS sme_roam_get_pmkid_cache(tHalHandle hHal, uint8_t sessionId,
4127 uint32_t *pNum, tPmkidCacheInfo *pPmkidCache)
4128{
4129 CDF_STATUS status = CDF_STATUS_E_FAILURE;
4130 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
4131
4132 MTRACE(cdf_trace(CDF_MODULE_ID_SME,
4133 TRACE_CODE_SME_RX_HDD_ROAM_GET_PMKIDCACHE, sessionId,
4134 0));
4135 status = sme_acquire_global_lock(&pMac->sme);
4136 if (CDF_IS_STATUS_SUCCESS(status)) {
4137 if (CSR_IS_SESSION_VALID(pMac, sessionId)) {
4138 status =
4139 csr_roam_get_pmkid_cache(pMac, sessionId, pNum,
4140 pPmkidCache);
4141 } else {
4142 status = CDF_STATUS_E_INVAL;
4143 }
4144 sme_release_global_lock(&pMac->sme);
4145 }
4146
4147 return status;
4148}
4149
4150/* ---------------------------------------------------------------------------
4151 \fn sme_get_config_param
4152 \brief a wrapper function that HDD calls to get the global settings
4153 currently maintained by CSR.
4154 This is a synchronous call.
4155 \param pParam - caller allocated memory
4156 \return CDF_STATUS
4157 ---------------------------------------------------------------------------*/
4158CDF_STATUS sme_get_config_param(tHalHandle hHal, tSmeConfigParams *pParam)
4159{
4160 CDF_STATUS status = CDF_STATUS_E_FAILURE;
4161 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
4162
4163 MTRACE(cdf_trace(CDF_MODULE_ID_SME,
4164 TRACE_CODE_SME_RX_HDD_GET_CONFIGPARAM, NO_SESSION, 0));
4165 status = sme_acquire_global_lock(&pMac->sme);
4166 if (CDF_IS_STATUS_SUCCESS(status)) {
4167 status = csr_get_config_param(pMac, &pParam->csrConfig);
4168 if (status != CDF_STATUS_SUCCESS) {
4169 sms_log(pMac, LOGE, "%s csr_get_config_param failed",
4170 __func__);
4171 sme_release_global_lock(&pMac->sme);
4172 return status;
4173 }
4174#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
4175 pParam->sap_channel_avoidance = pMac->sap.sap_channel_avoidance;
4176#endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
4177 pParam->max_intf_count = pMac->sme.max_intf_count;
4178 pParam->enableSelfRecovery = pMac->sme.enableSelfRecovery;
4179 pParam->f_prefer_non_dfs_on_radar =
4180 pMac->f_prefer_non_dfs_on_radar;
4181 pParam->policy_manager_enabled = pMac->policy_manager_enabled;
4182 pParam->fine_time_meas_cap = pMac->fine_time_meas_cap;
4183 pParam->dual_mac_feature_disable =
4184 pMac->dual_mac_feature_disable;
4185 pParam->is_ps_enabled = pMac->sme.ps_global_info.ps_enabled;
4186 pParam->pnoOffload = pMac->pnoOffload;
4187 pParam->fEnableDebugLog = pMac->fEnableDebugLog;
4188 pParam->enable5gEBT = pMac->enable5gEBT;
4189 pParam->f_sta_miracast_mcc_rest_time_val =
4190 pMac->f_sta_miracast_mcc_rest_time_val;
4191 sme_release_global_lock(&pMac->sme);
4192 }
4193
4194 return status;
4195}
4196
4197/**
4198 * sme_cfg_set_int() - Sets the cfg parameter value.
4199 * @hal: Handle to hal.
4200 * @cfg_id: Configuration parameter ID.
4201 * @value: value to be saved in the cfg parameter.
4202 *
4203 * This function sets the string value in cfg parameter.
4204 *
4205 * Return: CDF_STATUS
4206 */
4207CDF_STATUS sme_cfg_set_int(tHalHandle hal, uint16_t cfg_id, uint32_t value)
4208{
4209 tpAniSirGlobal pmac = PMAC_STRUCT(hal);
4210 CDF_STATUS status = CDF_STATUS_SUCCESS;
4211
4212 if (eSIR_SUCCESS != cfg_set_int(pmac, cfg_id, value))
4213 status = CDF_STATUS_E_FAILURE;
4214
4215 return status;
4216}
4217
4218/**
4219 * sme_cfg_set_str() - Sets the cfg parameter string.
4220 * @hal: Handle to hal.
4221 * @cfg_id: Configuration parameter ID.
4222 * @str: Pointer to the string buffer.
4223 * @length: Length of the string.
4224 *
4225 * This function sets the string value in cfg parameter.
4226 *
4227 * Return: CDF_STATUS
4228 */
4229CDF_STATUS sme_cfg_set_str(tHalHandle hal, uint16_t cfg_id, uint8_t *str,
4230 uint32_t length)
4231{
4232 tpAniSirGlobal pmac = PMAC_STRUCT(hal);
4233 CDF_STATUS status = CDF_STATUS_SUCCESS;
4234
4235 if (eSIR_SUCCESS != cfg_set_str(pmac, cfg_id, str, length))
4236 status = CDF_STATUS_E_FAILURE;
4237
4238 return status;
4239}
4240
4241/**
4242 * sme_cfg_get_int() - Gets the cfg parameter value.
4243 * @hal: Handle to hal.
4244 * @cfg_id: Configuration parameter ID.
4245 * @cfg_value: Pointer to variable in which cfg value
4246 * will be saved.
4247 *
4248 * This function gets the value of the cfg parameter.
4249 *
4250 * Return: CDF_STATUS
4251 */
4252CDF_STATUS sme_cfg_get_int(tHalHandle hal, uint16_t cfg_id, uint32_t *cfg_value)
4253{
4254 tpAniSirGlobal pmac = PMAC_STRUCT(hal);
4255 CDF_STATUS status = CDF_STATUS_SUCCESS;
4256
4257 if (eSIR_SUCCESS != wlan_cfg_get_int(pmac, cfg_id, cfg_value))
4258 status = CDF_STATUS_E_FAILURE;
4259
4260 return status;
4261}
4262
4263/**
4264 * sme_cfg_get_str() - Gets the cfg parameter string.
4265 * @hal: Handle to hal.
4266 * @cfg_id: Configuration parameter ID.
4267 * @str: Pointer to the string buffer.
4268 * @length: Pointer to length of the string.
4269 *
4270 * This function gets the string value of the cfg parameter.
4271 *
4272 * Return: CDF_STATUS
4273 */
4274CDF_STATUS sme_cfg_get_str(tHalHandle hal, uint16_t cfg_id, uint8_t *str,
4275 uint32_t *length)
4276{
4277 tpAniSirGlobal pmac = PMAC_STRUCT(hal);
4278 CDF_STATUS status = CDF_STATUS_SUCCESS;
4279
4280 if (eSIR_SUCCESS != wlan_cfg_get_str(pmac, cfg_id, str, length))
4281 status = CDF_STATUS_E_INVAL;
4282
4283 return status;
4284}
4285
4286/* ---------------------------------------------------------------------------
4287 \fn sme_get_modify_profile_fields
4288 \brief HDD or SME - QOS calls this function to get the current values of
4289 connected profile fields, changing which can cause reassoc.
4290 This function must be called after CFG is downloaded and STA is in connected
4291 state. Also, make sure to call this function to get the current profile
4292 fields before calling the reassoc. So that pModifyProfileFields will have
4293 all the latest values plus the one(s) has been updated as part of reassoc
4294 request.
4295 \param pModifyProfileFields - pointer to the connected profile fields
4296 changing which can cause reassoc
4297
4298 \return CDF_STATUS
4299 -------------------------------------------------------------------------------*/
4300CDF_STATUS sme_get_modify_profile_fields(tHalHandle hHal, uint8_t sessionId,
4301 tCsrRoamModifyProfileFields *
4302 pModifyProfileFields)
4303{
4304 CDF_STATUS status = CDF_STATUS_E_FAILURE;
4305 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
4306
4307 MTRACE(cdf_trace(CDF_MODULE_ID_SME,
4308 TRACE_CODE_SME_RX_HDD_GET_MODPROFFIELDS, sessionId,
4309 0));
4310 status = sme_acquire_global_lock(&pMac->sme);
4311 if (CDF_IS_STATUS_SUCCESS(status)) {
4312 if (CSR_IS_SESSION_VALID(pMac, sessionId)) {
4313 status =
4314 csr_get_modify_profile_fields(pMac, sessionId,
4315 pModifyProfileFields);
4316 } else {
4317 status = CDF_STATUS_E_INVAL;
4318 }
4319 sme_release_global_lock(&pMac->sme);
4320 }
4321
4322 return status;
4323}
4324
4325/* ---------------------------------------------------------------------------
4326 \fn sme_set_dhcp_till_power_active_flag
4327 \brief Sets/Clears DHCP related flag to disable/enable auto PS
4328 \param hal - The handle returned by mac_open.
4329 ---------------------------------------------------------------------------*/
4330void sme_set_dhcp_till_power_active_flag(tHalHandle hal, uint8_t flag)
4331{
4332 tpAniSirGlobal mac = PMAC_STRUCT(hal);
4333 struct ps_global_info *ps_global_info = &mac->sme.ps_global_info;
4334
4335 MTRACE(cdf_trace(CDF_MODULE_ID_SME,
4336 TRACE_CODE_SME_RX_HDD_SET_DHCP_FLAG, NO_SESSION,
4337 flag));
4338 /* Set/Clear the DHCP flag which will disable/enable auto PS */
4339 ps_global_info->remain_in_power_active_till_dhcp = flag;
4340}
4341
4342/* ---------------------------------------------------------------------------
4343 \fn sme_register11d_scan_done_callback
4344 \brief Register a routine of type csr_scan_completeCallback which is
4345 called whenever an 11d scan is done
4346 \param hHal - The handle returned by mac_open.
4347 \param callback - 11d scan complete routine to be registered
4348 \return CDF_STATUS
4349 ---------------------------------------------------------------------------*/
4350CDF_STATUS sme_register11d_scan_done_callback(tHalHandle hHal,
4351 csr_scan_completeCallback callback)
4352{
4353 CDF_STATUS status = CDF_STATUS_SUCCESS;
4354 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
4355
4356 pMac->scan.callback11dScanDone = callback;
4357
4358 return status;
4359}
4360
4361#ifdef FEATURE_OEM_DATA_SUPPORT
4362/**
4363 * sme_register_oem_data_rsp_callback() - Register a routine of
4364 * type send_oem_data_rsp_msg
4365 * @h_hal: Handle returned by mac_open.
4366 * @callback: Callback to send response
4367 * to oem application.
4368 *
4369 * sme_oem_data_rsp_callback is used to register sme_send_oem_data_rsp_msg
4370 * callback function.
4371 *
4372 * Return: CDF_STATUS.
4373 */
4374CDF_STATUS sme_register_oem_data_rsp_callback(tHalHandle h_hal,
4375 sme_send_oem_data_rsp_msg callback)
4376{
4377 CDF_STATUS status = CDF_STATUS_SUCCESS;
4378 tpAniSirGlobal pmac = PMAC_STRUCT(h_hal);
4379
4380 pmac->oemData.oem_data_rsp_callback = callback;
4381
4382 return status;
4383
4384}
4385#endif
4386
4387/**
4388 * sme_register_ftm_msg_processor() - registers hdd ftm message processor
4389 * function to MAC/SYS
4390 *
4391 * @hal: hal handle
4392 * @callback: hdd function that has to be registered
4393 *
4394 * Return: void
4395 */
4396void sme_register_ftm_msg_processor(tHalHandle hal,
4397 hdd_ftm_msg_processor callback)
4398{
4399 tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
4400
4401 if (mac_ctx == NULL) {
4402 sms_log(mac_ctx, LOGE, FL("mac_ctx is NULL"));
4403 return;
4404 }
4405 mac_ctx->ftm_msg_processor_callback = callback;
4406 return;
4407}
4408
4409/**
4410 * sme_wow_add_pattern() - add a wow pattern in fw
4411 * @hHal: handle returned by mac_open
4412 * @pattern: pointer to input pattern
4413 *
4414 * Add a pattern for Pattern Byte Matching in WoW mode. Firmware will
4415 * do a pattern match on these patterns when WoW is enabled during system
4416 * suspend.
4417 *
4418 * Return: CDF_STATUS
4419 */
4420CDF_STATUS sme_wow_add_pattern(tHalHandle hal,
4421 struct wow_add_pattern *pattern,
4422 uint8_t session_id)
4423{
4424 tpAniSirGlobal pMac = PMAC_STRUCT(hal);
4425 struct wow_add_pattern *ptrn;
4426 tSirRetStatus ret_code = eSIR_SUCCESS;
4427 tSirMsgQ msg_q;
4428 MTRACE(cdf_trace(CDF_MODULE_ID_SME,
4429 TRACE_CODE_SME_RX_HDD_WOWL_ADDBCAST_PATTERN, session_id,
4430 0));
4431 ptrn = cdf_mem_malloc(sizeof(*ptrn));
4432 if (NULL == ptrn) {
4433 sms_log(pMac, LOGP,
4434 FL("Fail to allocate memory for WoWLAN Add Bcast Pattern "));
4435 return CDF_STATUS_E_NOMEM;
4436 }
4437 (void)cdf_mem_copy(ptrn, pattern, sizeof(*ptrn));
4438
4439 msg_q.type = WMA_WOW_ADD_PTRN;
4440 msg_q.reserved = 0;
4441 msg_q.bodyptr = ptrn;
4442 msg_q.bodyval = 0;
4443
4444 sms_log(pMac, LOG1, FL("Sending WMA_WOWL_ADD_BCAST_PTRN to HAL"));
4445 ret_code = wma_post_ctrl_msg(pMac, &msg_q);
4446 if (eSIR_SUCCESS != ret_code) {
4447 sms_log(pMac, LOGE,
4448 FL("Posting WMA_WOWL_ADD_BCAST_PTRN failed, reason=%X"),
4449 ret_code);
4450 }
4451 return ret_code;
4452}
4453
4454/**
4455 * sme_wow_delete_pattern() - delete user configured wow pattern in target
4456 * @hHal: handle returned by mac_open.
4457 * @pattern: pointer to delete pattern parameter
4458 * @sessionId: session id
4459 *
4460 * Return: CDF_STATUS
4461 */
4462CDF_STATUS sme_wow_delete_pattern(tHalHandle hal,
4463 struct wow_delete_pattern *pattern, uint8_t sessionId)
4464{
4465 tpAniSirGlobal pMac = PMAC_STRUCT(hal);
4466 struct wow_delete_pattern *delete_ptrn;
4467 tSirRetStatus ret_code = eSIR_SUCCESS;
4468 tSirMsgQ msg_q;
4469 MTRACE(cdf_trace(CDF_MODULE_ID_SME,
4470 TRACE_CODE_SME_RX_HDD_WOWL_DELBCAST_PATTERN, sessionId,
4471 0));
4472 delete_ptrn = cdf_mem_malloc(sizeof(*delete_ptrn));
4473 if (NULL == delete_ptrn) {
4474 sms_log(pMac, LOGP,
4475 FL("Fail to allocate memory for WoWLAN Delete Bcast Pattern "));
4476 return CDF_STATUS_E_NOMEM;
4477 }
4478 (void)cdf_mem_copy(delete_ptrn, pattern, sizeof(*delete_ptrn));
4479 msg_q.type = WMA_WOW_DEL_PTRN;
4480 msg_q.reserved = 0;
4481 msg_q.bodyptr = delete_ptrn;
4482 msg_q.bodyval = 0;
4483
4484 sms_log(pMac, LOG1, FL("Sending WMA_WOWL_DEL_BCAST_PTRN"));
4485
4486 ret_code = wma_post_ctrl_msg(pMac, &msg_q);
4487 if (eSIR_SUCCESS != ret_code) {
4488 sms_log(pMac, LOGE,
4489 FL("Posting WMA_WOWL_DEL_BCAST_PTRN failed, reason=%X"),
4490 ret_code);
4491 }
4492 return ret_code;
4493}
4494
4495/**
4496 * sme_enter_wowl(): SME API exposed to HDD to request enabling of WOWL mode.
4497 * @hal_ctx - The handle returned by mac_open.
4498 * @enter_wowl_callback_routine - Callback routine provided by HDD.
4499 * Used for success/failure notification by SME
4500 * @enter_wowl_callback_context - A cookie passed by HDD, that is passed
4501 * back to HDD at the time of callback.
4502 * @wake_reason_ind_cb - Callback routine provided by HDD.
4503 * Used for Wake Reason Indication by SME
4504 * @wake_reason_ind_cb_ctx - A cookie passed by HDD, that is passed
4505 * back to HDD at the time of callback.
4506 *
4507 * WoWLAN works on top of BMPS mode.
4508 * If the device is not in BMPS mode,
4509 * SME will will cache the information that
4510 * WOWL has been enabled and attempt to put the device
4511 * in BMPS. On entry into BMPS, SME will enable the
4512 * WOWL mode.
4513 * Note 1: If we exit BMPS mode (someone requests full power),
4514 * we will NOT resume WOWL when we go back to BMPS again.
4515 * Request for full power (while in WOWL mode) means disable
4516 * WOWL and go to full power.
4517 * Note 2: Both UAPSD and WOWL work on top of BMPS.
4518 * On entry into BMPS, SME will give priority to UAPSD and
4519 * enable only UAPSD if both UAPSD and WOWL are required.
4520 * Currently there is no requirement or use case to support
4521 * UAPSD and WOWL at the same time.
4522 *
4523 * Return: CDF_STATUS
4524 * CDF_STATUS_SUCCESS Device is already in WoWLAN mode
4525 * CDF_STATUS_E_FAILURE Device cannot enter WoWLAN mode.
4526 * CDF_STATUS_PMC_PENDING Request accepted. SME will enable
4527 * WOWL after BMPS mode is entered.
4528 */
4529CDF_STATUS sme_enter_wowl(tHalHandle hal_ctx,
4530 void (*enter_wowl_callback_routine)(void
4531 *callback_context,
4532 CDF_STATUS status),
4533 void *enter_wowl_callback_context,
4534#ifdef WLAN_WAKEUP_EVENTS
4535 void (*wakeIndicationCB)(void *callback_context,
4536 tpSirWakeReasonInd
4537 wake_reason_ind),
4538 void *wakeIndicationCBContext,
4539#endif /* WLAN_WAKEUP_EVENTS */
4540 tpSirSmeWowlEnterParams wowl_enter_params,
4541 uint8_t session_id)
4542{
4543 CDF_STATUS status = CDF_STATUS_E_FAILURE;
4544 tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal_ctx);
4545 struct ps_global_info *ps_global_info = &mac_ctx->sme.ps_global_info;
4546 MTRACE(cdf_trace(CDF_MODULE_ID_SME,
4547 TRACE_CODE_SME_RX_HDD_ENTER_WOWL, session_id, 0));
4548
4549 /* cache the WOWL information */
4550 ps_global_info->ps_params[session_id].wowl_enter_params =
4551 *wowl_enter_params;
4552 ps_global_info->ps_params[session_id].enter_wowl_callback_routine =
4553 enter_wowl_callback_routine;
4554 ps_global_info->ps_params[session_id].enter_wowl_callback_context =
4555 enter_wowl_callback_context;
4556#ifdef WLAN_WAKEUP_EVENTS
4557 /* Cache the Wake Reason Indication callback information */
4558 ps_global_info->ps_params[session_id].wake_reason_ind_cb =
4559 wakeIndicationCB;
4560 ps_global_info->ps_params[session_id].wake_reason_ind_cb_ctx =
4561 wakeIndicationCBContext;
4562#endif /* WLAN_WAKEUP_EVENTS */
4563
4564 status = sme_ps_process_command(mac_ctx, session_id, SME_PS_WOWL_ENTER);
4565 return status;
4566}
4567/**
4568 *sme_exit_wowl(): SME API exposed to HDD to request exit from WoWLAN mode.
4569 * @hal_ctx - The handle returned by mac_open.
4570 * @wowl_exit_params - Carries info on which smesession
4571 * wowl exit is requested.
4572 *
4573 * SME will initiate exit from WoWLAN mode and device will be
4574 * put in BMPS mode.
4575 * Return CDF_STATUS
4576 * CDF_STATUS_E_FAILURE Device cannot exit WoWLAN mode.
4577 * CDF_STATUS_SUCCESS Request accepted to exit WoWLAN mode.
4578 */
4579CDF_STATUS sme_exit_wowl(tHalHandle hal_ctx,
4580 tpSirSmeWowlExitParams wowl_exit_params)
4581{
4582 CDF_STATUS status = CDF_STATUS_E_FAILURE;
4583 tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal_ctx);
4584 uint8_t session_id;
4585 MTRACE(cdf_trace(CDF_MODULE_ID_SME,
4586 TRACE_CODE_SME_RX_HDD_EXIT_WOWL, NO_SESSION, 0));
4587 session_id = wowl_exit_params->sessionId;
4588 status = sme_ps_process_command(mac_ctx, session_id, SME_PS_WOWL_EXIT);
4589 return status;
4590}
4591
4592/**
4593 * sme_roam_set_key() - To set encryption key.
4594 * @hal: hal global context
4595 * @session_id: session id
4596 * @set_key: pointer to a caller allocated object of tCsrSetContextInfo
4597 * @ptr_roam_id: Upon success return, this is the id caller can use to
4598 * identify the request in roamcallback
4599 *
4600 * This function should be called only when connected. This is an asynchronous
4601 * API.
4602 *
4603 * Return: Status of operation
4604 */
4605CDF_STATUS sme_roam_set_key(tHalHandle hal, uint8_t session_id,
4606 tCsrRoamSetKey *set_key, uint32_t *ptr_roam_id)
4607{
4608 CDF_STATUS status = CDF_STATUS_E_FAILURE;
4609 tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
4610 uint32_t roam_id;
4611 uint32_t i;
4612 tCsrRoamSession *session = NULL;
4613 struct ps_global_info *ps_global_info = &mac_ctx->sme.ps_global_info;
4614
4615 MTRACE(cdf_trace(CDF_MODULE_ID_SME, TRACE_CODE_SME_RX_HDD_SET_KEY,
4616 session_id, 0));
4617 if (set_key->keyLength > CSR_MAX_KEY_LEN) {
4618 sms_log(mac_ctx, LOGE, FL("Invalid key length %d"),
4619 set_key->keyLength);
4620 return CDF_STATUS_E_FAILURE;
4621 }
4622 /*Once Setkey is done, we can go in BMPS */
4623 if (set_key->keyLength)
4624 ps_global_info->remain_in_power_active_till_dhcp = false;
4625
4626 status = sme_acquire_global_lock(&mac_ctx->sme);
4627 if (!CDF_IS_STATUS_SUCCESS(status))
4628 return status;
4629
4630 roam_id = GET_NEXT_ROAM_ID(&mac_ctx->roam);
4631 if (ptr_roam_id)
4632 *ptr_roam_id = roam_id;
4633
4634 sms_log(mac_ctx, LOG2, FL("keyLength %d"), set_key->keyLength);
4635 for (i = 0; i < set_key->keyLength; i++)
4636 sms_log(mac_ctx, LOG2, FL("%02x"), set_key->Key[i]);
4637
4638 sms_log(mac_ctx, LOG2, "\n session_id=%d roam_id=%d", session_id,
4639 roam_id);
4640 session = CSR_GET_SESSION(mac_ctx, session_id);
4641 if (!session) {
4642 sms_log(mac_ctx, LOGE, FL("session %d not found"), session_id);
4643 sme_release_global_lock(&mac_ctx->sme);
4644 return CDF_STATUS_E_FAILURE;
4645 }
4646 if (CSR_IS_INFRA_AP(&session->connectedProfile)
4647 && set_key->keyDirection == eSIR_TX_DEFAULT) {
4648 if ((eCSR_ENCRYPT_TYPE_WEP40 == set_key->encType)
4649 || (eCSR_ENCRYPT_TYPE_WEP40_STATICKEY ==
4650 set_key->encType)) {
4651 session->pCurRoamProfile->negotiatedUCEncryptionType =
4652 eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
4653 }
4654 if ((eCSR_ENCRYPT_TYPE_WEP104 == set_key->encType)
4655 || (eCSR_ENCRYPT_TYPE_WEP104_STATICKEY ==
4656 set_key->encType)) {
4657 session->pCurRoamProfile->negotiatedUCEncryptionType =
4658 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
4659 }
4660 }
4661 status = csr_roam_set_key(mac_ctx, session_id, set_key, roam_id);
4662 sme_release_global_lock(&mac_ctx->sme);
4663 return status;
4664}
4665
4666/* ---------------------------------------------------------------------------
4667 \fn sme_get_rssi
4668 \brief a wrapper function that client calls to register a callback to get
4669 RSSI
4670
4671 \param hHal - HAL handle for device
4672 \param callback - SME sends back the requested stats using the callback
4673 \param staId - The station ID for which the stats is requested for
4674 \param bssid - The bssid of the connected session
4675 \param lastRSSI - RSSI value at time of request. In case fw cannot provide
4676 RSSI, do not hold up but return this value.
4677 \param pContext - user context to be passed back along with the callback
4678 \param p_cds_context - cds context
4679 \return CDF_STATUS
4680 ---------------------------------------------------------------------------*/
4681CDF_STATUS sme_get_rssi(tHalHandle hHal,
4682 tCsrRssiCallback callback,
4683 uint8_t staId, struct cdf_mac_addr bssId, int8_t lastRSSI,
4684 void *pContext, void *p_cds_context)
4685{
4686 CDF_STATUS status = CDF_STATUS_E_FAILURE;
4687 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
4688
4689 MTRACE(cdf_trace(CDF_MODULE_ID_SME,
4690 TRACE_CODE_SME_RX_HDD_GET_RSSI, NO_SESSION, 0));
4691 status = sme_acquire_global_lock(&pMac->sme);
4692 if (CDF_IS_STATUS_SUCCESS(status)) {
4693 status = csr_get_rssi(pMac, callback,
4694 staId, bssId, lastRSSI,
4695 pContext, p_cds_context);
4696 sme_release_global_lock(&pMac->sme);
4697 }
4698 return status;
4699}
4700
4701/* ---------------------------------------------------------------------------
4702 \fn sme_get_snr
4703 \brief a wrapper function that client calls to register a callback to
4704 get SNR
4705
4706 \param callback - SME sends back the requested stats using the callback
4707 \param staId - The station ID for which the stats is requested for
4708 \param pContext - user context to be passed back along with the callback
4709 \param p_cds_context - cds context
4710 \return CDF_STATUS
4711 ---------------------------------------------------------------------------*/
4712CDF_STATUS sme_get_snr(tHalHandle hHal,
4713 tCsrSnrCallback callback,
4714 uint8_t staId, struct cdf_mac_addr bssId, void *pContext)
4715{
4716 CDF_STATUS status = CDF_STATUS_E_FAILURE;
4717 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
4718
4719 status = sme_acquire_global_lock(&pMac->sme);
4720 if (CDF_IS_STATUS_SUCCESS(status)) {
4721 status = csr_get_snr(pMac, callback, staId, bssId, pContext);
4722 sme_release_global_lock(&pMac->sme);
4723 }
4724 return status;
4725}
4726
4727#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
4728/* ---------------------------------------------------------------------------
4729 \fn sme_get_tsm_stats
4730 \brief a wrapper function that client calls to register a callback to
4731 get TSM Stats
4732 \param callback - SME sends back the requested stats using the callback
4733 \param staId - The station ID for which the stats is requested for
4734 \param pContext - user context to be passed back along with the callback
4735 \param p_cds_context - cds context
4736 \return CDF_STATUS
4737 ---------------------------------------------------------------------------*/
4738CDF_STATUS sme_get_tsm_stats(tHalHandle hHal,
4739 tCsrTsmStatsCallback callback,
4740 uint8_t staId, struct cdf_mac_addr bssId,
4741 void *pContext, void *p_cds_context, uint8_t tid)
4742{
4743 CDF_STATUS status = CDF_STATUS_E_FAILURE;
4744 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
4745 status = sme_acquire_global_lock(&pMac->sme);
4746 if (CDF_IS_STATUS_SUCCESS(status)) {
4747 status = csr_get_tsm_stats(pMac, callback,
4748 staId, bssId, pContext, p_cds_context,
4749 tid);
4750 sme_release_global_lock(&pMac->sme);
4751 }
4752 return status;
4753}
4754#endif
4755
4756/* ---------------------------------------------------------------------------
4757 \fn sme_get_statistics
4758 \brief a wrapper function that client calls to register a callback to get
4759 different PHY level statistics from CSR.
4760
4761 \param requesterId - different client requesting for statistics,
4762 HDD, UMA/GAN etc
4763 \param statsMask - The different category/categories of stats requester
4764 is looking for
4765 \param callback - SME sends back the requested stats using the callback
4766 \param periodicity - If requester needs periodic update in millisec, 0 means
4767 it's an one time request
4768 \param cache - If requester is happy with cached stats
4769 \param staId - The station ID for which the stats is requested for
4770 \param pContext - user context to be passed back along with the callback
4771 \param sessionId - sme session interface
4772 \return CDF_STATUS
4773 ---------------------------------------------------------------------------*/
4774CDF_STATUS sme_get_statistics(tHalHandle hHal,
4775 eCsrStatsRequesterType requesterId,
4776 uint32_t statsMask, tCsrStatsCallback callback,
4777 uint32_t periodicity, bool cache, uint8_t staId,
4778 void *pContext, uint8_t sessionId)
4779{
4780 CDF_STATUS status = CDF_STATUS_E_FAILURE;
4781 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
4782
4783 MTRACE(cdf_trace(CDF_MODULE_ID_SME,
4784 TRACE_CODE_SME_RX_HDD_GET_STATS, NO_SESSION,
4785 periodicity));
4786 status = sme_acquire_global_lock(&pMac->sme);
4787 if (CDF_IS_STATUS_SUCCESS(status)) {
4788 status =
4789 csr_get_statistics(pMac, requesterId, statsMask, callback,
4790 periodicity, cache, staId, pContext,
4791 sessionId);
4792 sme_release_global_lock(&pMac->sme);
4793 }
4794
4795 return status;
4796
4797}
4798
4799CDF_STATUS sme_get_link_status(tHalHandle hHal,
4800 tCsrLinkStatusCallback callback,
4801 void *pContext, uint8_t sessionId)
4802{
4803 CDF_STATUS status = CDF_STATUS_E_FAILURE;
4804 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
4805 tAniGetLinkStatus *pMsg;
4806 cds_msg_t cds_message;
4807
4808 status = sme_acquire_global_lock(&pMac->sme);
4809 if (CDF_IS_STATUS_SUCCESS(status)) {
4810 pMsg = cdf_mem_malloc(sizeof(tAniGetLinkStatus));
4811 if (NULL == pMsg) {
4812 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
4813 "%s: Not able to allocate memory for link status",
4814 __func__);
4815 sme_release_global_lock(&pMac->sme);
4816 return CDF_STATUS_E_NOMEM;
4817 }
4818
4819 pMsg->msgType = WMA_LINK_STATUS_GET_REQ;
4820 pMsg->msgLen = (uint16_t) sizeof(tAniGetLinkStatus);
4821 pMsg->sessionId = sessionId;
4822 pMac->sme.linkStatusContext = pContext;
4823 pMac->sme.linkStatusCallback = callback;
4824
4825 cds_message.type = WMA_LINK_STATUS_GET_REQ;
4826 cds_message.bodyptr = pMsg;
4827 cds_message.reserved = 0;
4828
4829 if (!CDF_IS_STATUS_SUCCESS
4830 (cds_mq_post_message(CDF_MODULE_ID_WMA, &cds_message))) {
4831 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
4832 "%s: Post LINK STATUS MSG fail", __func__);
4833 cdf_mem_free(pMsg);
4834 pMac->sme.linkStatusContext = NULL;
4835 pMac->sme.linkStatusCallback = NULL;
4836 status = CDF_STATUS_E_FAILURE;
4837 }
4838
4839 sme_release_global_lock(&pMac->sme);
4840 }
4841
4842 return status;
4843}
4844
4845/* ---------------------------------------------------------------------------
4846
4847 \fn sme_get_country_code
4848
4849 \brief To return the current country code. If no country code is applied,
4850 default country code is used to fill the buffer.
4851 If 11d supported is turned off, an error is return and the last
4852 applied/default country code is used.
4853 This is a synchronous API.
4854
4855 \param pBuf - pointer to a caller allocated buffer for returned country code.
4856
4857 \param pbLen For input, this parameter indicates how big is the buffer.
4858 Upon return, this parameter has the number of bytes for
4859 country. If pBuf doesn't have enough space, this function
4860 returns fail status and this parameter contains the number
4861 that is needed.
4862
4863 \return CDF_STATUS SUCCESS.
4864
4865 FAILURE or RESOURCES The API finished and failed.
4866
4867 -------------------------------------------------------------------------------*/
4868CDF_STATUS sme_get_country_code(tHalHandle hHal, uint8_t *pBuf, uint8_t *pbLen)
4869{
4870 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
4871
4872 MTRACE(cdf_trace(CDF_MODULE_ID_SME,
4873 TRACE_CODE_SME_RX_HDD_GET_CNTRYCODE, NO_SESSION, 0));
4874
4875 return csr_get_country_code(pMac, pBuf, pbLen);
4876}
4877
4878/**
4879 * sme_apply_channel_power_info_to_fw() - sends channel info to fw
4880 * @hHal: hal handle
4881 *
4882 * This function sends the channel power info to firmware
4883 *
4884 * Return: none
4885 */
4886void sme_apply_channel_power_info_to_fw(tHalHandle hHal)
4887{
4888 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
4889
4890 csr_apply_channel_power_info_wrapper(pMac);
4891}
4892
4893/* some support functions */
4894bool sme_is11d_supported(tHalHandle hHal)
4895{
4896 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
4897
4898 return csr_is11d_supported(pMac);
4899}
4900
4901bool sme_is11h_supported(tHalHandle hHal)
4902{
4903 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
4904
4905 return csr_is11h_supported(pMac);
4906}
4907
4908bool sme_is_wmm_supported(tHalHandle hHal)
4909{
4910 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
4911
4912 return csr_is_wmm_supported(pMac);
4913}
4914
4915/* ---------------------------------------------------------------------------
4916
4917 \fn sme_change_country_code
4918
4919 \brief Change Country code from upperlayer during WLAN driver operation.
4920 This is a synchronous API.
4921
4922 \param hHal - The handle returned by mac_open.
4923
4924 \param pCountry New Country Code String
4925
4926 \param sendRegHint If we want to send reg hint to nl80211
4927
4928 \return CDF_STATUS SUCCESS.
4929
4930 FAILURE or RESOURCES The API finished and failed.
4931
4932 -------------------------------------------------------------------------------*/
4933CDF_STATUS sme_change_country_code(tHalHandle hHal,
4934 tSmeChangeCountryCallback callback,
4935 uint8_t *pCountry,
4936 void *pContext,
4937 void *p_cds_context,
4938 tAniBool countryFromUserSpace,
4939 tAniBool sendRegHint)
4940{
4941 CDF_STATUS status = CDF_STATUS_E_FAILURE;
4942 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
4943 cds_msg_t msg;
4944 tAniChangeCountryCodeReq *pMsg;
4945
4946 MTRACE(cdf_trace(CDF_MODULE_ID_SME,
4947 TRACE_CODE_SME_RX_HDD_CHANGE_CNTRYCODE, NO_SESSION,
4948 0));
4949 status = sme_acquire_global_lock(&pMac->sme);
4950 if (CDF_IS_STATUS_SUCCESS(status)) {
4951 sms_log(pMac, LOG1, FL(" called"));
4952
4953 if ((pMac->roam.configParam.Is11dSupportEnabledOriginal == true)
4954 && (!pMac->roam.configParam.
4955 fSupplicantCountryCodeHasPriority)) {
4956
4957 sms_log(pMac, LOGW,
4958 "Set Country Code Fail since the STA is associated and userspace does not have priority ");
4959
4960 sme_release_global_lock(&pMac->sme);
4961 status = CDF_STATUS_E_FAILURE;
4962 return status;
4963 }
4964
4965 pMsg = cdf_mem_malloc(sizeof(tAniChangeCountryCodeReq));
4966 if (NULL == pMsg) {
4967 sms_log(pMac, LOGE,
4968 " csrChangeCountryCode: failed to allocate mem for req");
4969 sme_release_global_lock(&pMac->sme);
4970 return CDF_STATUS_E_NOMEM;
4971 }
4972
4973 pMsg->msgType = eWNI_SME_CHANGE_COUNTRY_CODE;
4974 pMsg->msgLen = (uint16_t) sizeof(tAniChangeCountryCodeReq);
4975 cdf_mem_copy(pMsg->countryCode, pCountry, 3);
4976 pMsg->countryFromUserSpace = countryFromUserSpace;
4977 pMsg->sendRegHint = sendRegHint;
4978 pMsg->changeCCCallback = callback;
4979 pMsg->pDevContext = pContext;
4980 pMsg->p_cds_context = p_cds_context;
4981
4982 msg.type = eWNI_SME_CHANGE_COUNTRY_CODE;
4983 msg.bodyptr = pMsg;
4984 msg.reserved = 0;
4985
4986 if (CDF_STATUS_SUCCESS !=
4987 cds_mq_post_message(CDS_MQ_ID_SME, &msg)) {
4988 sms_log(pMac, LOGE,
4989 " sme_change_country_code failed to post msg to self ");
4990 cdf_mem_free((void *)pMsg);
4991 status = CDF_STATUS_E_FAILURE;
4992 }
4993 sms_log(pMac, LOG1, FL(" returned"));
4994 sme_release_global_lock(&pMac->sme);
4995 }
4996
4997 return status;
4998}
4999
5000/*--------------------------------------------------------------------------
5001
5002 \fn sme_generic_change_country_code
5003
5004 \brief Change Country code from upperlayer during WLAN driver operation.
5005 This is a synchronous API.
5006
5007 \param hHal - The handle returned by mac_open.
5008
5009 \param pCountry New Country Code String
5010
5011 \param reg_domain regulatory domain
5012
5013 \return CDF_STATUS SUCCESS.
5014
5015 FAILURE or RESOURCES The API finished and failed.
5016
5017 -----------------------------------------------------------------------------*/
5018CDF_STATUS sme_generic_change_country_code(tHalHandle hHal,
5019 uint8_t *pCountry,
5020 v_REGDOMAIN_t reg_domain)
5021{
5022 CDF_STATUS status = CDF_STATUS_E_FAILURE;
5023 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
5024 cds_msg_t msg;
5025 tAniGenericChangeCountryCodeReq *pMsg;
5026
5027 if (NULL == pMac) {
5028 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_FATAL,
5029 "%s: pMac is null", __func__);
5030 return status;
5031 }
5032
5033 status = sme_acquire_global_lock(&pMac->sme);
5034 if (CDF_IS_STATUS_SUCCESS(status)) {
5035 sms_log(pMac, LOG1, FL(" called"));
5036 pMsg = cdf_mem_malloc(sizeof(tAniGenericChangeCountryCodeReq));
5037
5038 if (NULL == pMsg) {
5039 sms_log(pMac, LOGE,
5040 " sme_generic_change_country_code: failed to allocate mem for req");
5041 sme_release_global_lock(&pMac->sme);
5042 return CDF_STATUS_E_NOMEM;
5043 }
5044
5045 pMsg->msgType = eWNI_SME_GENERIC_CHANGE_COUNTRY_CODE;
5046 pMsg->msgLen =
5047 (uint16_t) sizeof(tAniGenericChangeCountryCodeReq);
5048 cdf_mem_copy(pMsg->countryCode, pCountry, 2);
5049 pMsg->domain_index = reg_domain;
5050 pMsg->countryCode[2] = ' '; /* For ASCII space */
5051
5052 msg.type = eWNI_SME_GENERIC_CHANGE_COUNTRY_CODE;
5053 msg.bodyptr = pMsg;
5054 msg.reserved = 0;
5055
5056 if (CDF_STATUS_SUCCESS !=
5057 cds_mq_post_message(CDS_MQ_ID_SME, &msg)) {
5058 sms_log(pMac, LOGE,
5059 "sme_generic_change_country_code failed to post msg to self");
5060 cdf_mem_free(pMsg);
5061 status = CDF_STATUS_E_FAILURE;
5062 }
5063 sms_log(pMac, LOG1, FL(" returned"));
5064 sme_release_global_lock(&pMac->sme);
5065 }
5066
5067 return status;
5068}
5069
5070/* ---------------------------------------------------------------------------
5071
5072 \fn sme_dhcp_start_ind
5073
5074 \brief API to signal the FW about the DHCP Start event.
5075
5076 \param hHal - HAL handle for device.
5077
5078 \param device_mode - mode(AP,SAP etc) of the device.
5079
5080 \param macAddr - MAC address of the adapter.
5081
5082 \param sessionId - session ID.
5083
5084 \return CDF_STATUS SUCCESS.
5085
5086 FAILURE or RESOURCES The API finished and failed.
5087 --------------------------------------------------------------------------*/
5088CDF_STATUS sme_dhcp_start_ind(tHalHandle hHal,
5089 uint8_t device_mode,
5090 uint8_t *macAddr, uint8_t sessionId)
5091{
5092 CDF_STATUS status;
5093 CDF_STATUS cdf_status;
5094 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
5095 cds_msg_t cds_message;
5096 tAniDHCPInd *pMsg;
5097 tCsrRoamSession *pSession;
5098
5099 status = sme_acquire_global_lock(&pMac->sme);
5100 if (CDF_STATUS_SUCCESS == status) {
5101 pSession = CSR_GET_SESSION(pMac, sessionId);
5102
5103 if (!pSession) {
5104 sms_log(pMac, LOGE, FL("session %d not found "),
5105 sessionId);
5106 sme_release_global_lock(&pMac->sme);
5107 return CDF_STATUS_E_FAILURE;
5108 }
5109
5110 pMsg = (tAniDHCPInd *) cdf_mem_malloc(sizeof(tAniDHCPInd));
5111 if (NULL == pMsg) {
5112 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
5113 "%s: Not able to allocate memory for dhcp start",
5114 __func__);
5115 sme_release_global_lock(&pMac->sme);
5116 return CDF_STATUS_E_NOMEM;
5117 }
5118 pMsg->msgType = WMA_DHCP_START_IND;
5119 pMsg->msgLen = (uint16_t) sizeof(tAniDHCPInd);
5120 pMsg->device_mode = device_mode;
5121 cdf_mem_copy(pMsg->adapterMacAddr, macAddr,
5122 sizeof(tSirMacAddr));
5123 cdf_mem_copy(pMsg->peerMacAddr,
5124 pSession->connectedProfile.bssid.bytes,
5125 sizeof(tSirMacAddr));
5126
5127 cds_message.type = WMA_DHCP_START_IND;
5128 cds_message.bodyptr = pMsg;
5129 cds_message.reserved = 0;
5130
5131 cdf_status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message);
5132 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
5133 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
5134 "%s: Post DHCP Start MSG fail", __func__);
5135 cdf_mem_free(pMsg);
5136 status = CDF_STATUS_E_FAILURE;
5137 }
5138 sme_release_global_lock(&pMac->sme);
5139 }
5140 return status;
5141}
5142
5143/* ---------------------------------------------------------------------------
5144 \fn sme_dhcp_stop_ind
5145
5146 \brief API to signal the FW about the DHCP complete event.
5147
5148 \param hHal - HAL handle for device.
5149
5150 \param device_mode - mode(AP, SAP etc) of the device.
5151
5152 \param macAddr - MAC address of the adapter.
5153
5154 \param sessionId - session ID.
5155
5156 \return CDF_STATUS SUCCESS.
5157 FAILURE or RESOURCES The API finished and failed.
5158 --------------------------------------------------------------------------*/
5159CDF_STATUS sme_dhcp_stop_ind(tHalHandle hHal,
5160 uint8_t device_mode,
5161 uint8_t *macAddr, uint8_t sessionId)
5162{
5163 CDF_STATUS status;
5164 CDF_STATUS cdf_status;
5165 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
5166 cds_msg_t cds_message;
5167 tAniDHCPInd *pMsg;
5168 tCsrRoamSession *pSession;
5169
5170 status = sme_acquire_global_lock(&pMac->sme);
5171 if (CDF_STATUS_SUCCESS == status) {
5172 pSession = CSR_GET_SESSION(pMac, sessionId);
5173
5174 if (!pSession) {
5175 sms_log(pMac, LOGE, FL("session %d not found "),
5176 sessionId);
5177 sme_release_global_lock(&pMac->sme);
5178 return CDF_STATUS_E_FAILURE;
5179 }
5180
5181 pMsg = (tAniDHCPInd *) cdf_mem_malloc(sizeof(tAniDHCPInd));
5182 if (NULL == pMsg) {
5183 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
5184 "%s: Not able to allocate memory for dhcp stop",
5185 __func__);
5186 sme_release_global_lock(&pMac->sme);
5187 return CDF_STATUS_E_NOMEM;
5188 }
5189
5190 pMsg->msgType = WMA_DHCP_STOP_IND;
5191 pMsg->msgLen = (uint16_t) sizeof(tAniDHCPInd);
5192 pMsg->device_mode = device_mode;
5193 cdf_mem_copy(pMsg->adapterMacAddr, macAddr,
5194 sizeof(tSirMacAddr));
5195 cdf_mem_copy(pMsg->peerMacAddr,
5196 pSession->connectedProfile.bssid.bytes,
5197 sizeof(tSirMacAddr));
5198
5199 cds_message.type = WMA_DHCP_STOP_IND;
5200 cds_message.bodyptr = pMsg;
5201 cds_message.reserved = 0;
5202
5203 cdf_status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message);
5204 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
5205 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
5206 "%s: Post DHCP Stop MSG fail", __func__);
5207 cdf_mem_free(pMsg);
5208 status = CDF_STATUS_E_FAILURE;
5209 }
5210
5211 sme_release_global_lock(&pMac->sme);
5212 }
5213 return status;
5214}
5215
5216/* ---------------------------------------------------------------------------
5217 \fn sme_set_cfg_privacy
5218 \brief API to set configure privacy parameters
5219 \param hHal - The handle returned by mac_open.
5220 \param pProfile - Pointer CSR Roam profile.
5221 \param fPrivacy - This parameter indicates status of privacy
5222
5223 \return void
5224 ---------------------------------------------------------------------------*/
5225void sme_set_cfg_privacy(tHalHandle hHal,
5226 tCsrRoamProfile *pProfile, bool fPrivacy)
5227{
5228 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
5229 MTRACE(cdf_trace(CDF_MODULE_ID_SME,
5230 TRACE_CODE_SME_RX_HDD_SET_CFGPRIVACY, NO_SESSION, 0));
5231 if (CDF_STATUS_SUCCESS == sme_acquire_global_lock(&pMac->sme)) {
5232 csr_set_cfg_privacy(pMac, pProfile, fPrivacy);
5233 sme_release_global_lock(&pMac->sme);
5234 }
5235}
5236
5237#if defined WLAN_FEATURE_VOWIFI
5238/* ---------------------------------------------------------------------------
5239 \fn sme_neighbor_report_request
5240 \brief API to request neighbor report.
5241 \param hHal - The handle returned by mac_open.
5242 \param pRrmNeighborReq - Pointer to a caller allocated object of type
5243 tRrmNeighborReq. Caller owns the memory and is
5244 responsible for freeing it.
5245 \return CDF_STATUS
5246 CDF_STATUS_E_FAILURE - failure
5247 CDF_STATUS_SUCCESS success
5248 ---------------------------------------------------------------------------*/
5249CDF_STATUS sme_neighbor_report_request(tHalHandle hHal, uint8_t sessionId,
5250 tpRrmNeighborReq pRrmNeighborReq,
5251 tpRrmNeighborRspCallbackInfo callbackInfo)
5252{
5253 CDF_STATUS status = CDF_STATUS_E_FAILURE;
5254 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
5255 MTRACE(cdf_trace(CDF_MODULE_ID_SME,
5256 TRACE_CODE_SME_RX_HDD_NEIGHBOR_REPORTREQ, NO_SESSION,
5257 0));
5258
5259 if (CDF_STATUS_SUCCESS == sme_acquire_global_lock(&pMac->sme)) {
5260 status =
5261 sme_rrm_neighbor_report_request(hHal, sessionId,
5262 pRrmNeighborReq, callbackInfo);
5263 sme_release_global_lock(&pMac->sme);
5264 }
5265
5266 return status;
5267}
5268#endif
5269
5270void sms_log(tpAniSirGlobal pMac, uint32_t loglevel, const char *pString, ...)
5271{
5272#ifdef WLAN_DEBUG
5273 /* Verify against current log level */
5274 if (loglevel >
5275 pMac->utils.gLogDbgLevel[LOG_INDEX_FOR_MODULE(SIR_SMS_MODULE_ID)])
5276 return;
5277 else {
5278 va_list marker;
5279
5280 va_start(marker, pString); /* Initialize variable arguments. */
5281
5282 log_debug(pMac, SIR_SMS_MODULE_ID, loglevel, pString, marker);
5283
5284 va_end(marker); /* Reset variable arguments. */
5285 }
5286#endif
5287}
5288
5289/* ---------------------------------------------------------------------------
5290 \fn sme_get_wcnss_wlan_compiled_version
5291 \brief This API returns the version of the WCNSS WLAN API with
5292 which the HOST driver was built
5293 \param hHal - The handle returned by mac_open.
5294 \param pVersion - Points to the Version structure to be filled
5295 \return CDF_STATUS
5296 CDF_STATUS_E_INVAL - failure
5297 CDF_STATUS_SUCCESS success
5298 ---------------------------------------------------------------------------*/
5299CDF_STATUS sme_get_wcnss_wlan_compiled_version(tHalHandle hHal,
5300 tSirVersionType *pVersion)
5301{
5302 CDF_STATUS status = CDF_STATUS_SUCCESS;
5303 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
5304
5305 if (CDF_STATUS_SUCCESS == sme_acquire_global_lock(&pMac->sme)) {
5306 if (pVersion != NULL)
5307 status = CDF_STATUS_SUCCESS;
5308 else
5309 status = CDF_STATUS_E_INVAL;
5310
5311 sme_release_global_lock(&pMac->sme);
5312 }
5313
5314 return status;
5315}
5316
5317/* ---------------------------------------------------------------------------
5318 \fn sme_get_wcnss_wlan_reported_version
5319 \brief This API returns the version of the WCNSS WLAN API with
5320 which the WCNSS driver reports it was built
5321 \param hHal - The handle returned by mac_open.
5322 \param pVersion - Points to the Version structure to be filled
5323 \return CDF_STATUS
5324 CDF_STATUS_E_INVAL - failure
5325 CDF_STATUS_SUCCESS success
5326 ---------------------------------------------------------------------------*/
5327CDF_STATUS sme_get_wcnss_wlan_reported_version(tHalHandle hHal,
5328 tSirVersionType *pVersion)
5329{
5330 CDF_STATUS status = CDF_STATUS_SUCCESS;
5331 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
5332
5333 if (CDF_STATUS_SUCCESS == sme_acquire_global_lock(&pMac->sme)) {
5334 if (pVersion != NULL)
5335 status = CDF_STATUS_SUCCESS;
5336 else
5337 status = CDF_STATUS_E_INVAL;
5338
5339 sme_release_global_lock(&pMac->sme);
5340 }
5341
5342 return status;
5343}
5344
5345/* ---------------------------------------------------------------------------
5346 \fn sme_get_wcnss_software_version
5347 \brief This API returns the version string of the WCNSS driver
5348 \param hHal - The handle returned by mac_open.
5349 \param pVersion - Points to the Version string buffer to be filled
5350 \param versionBufferSize - THe size of the Version string buffer
5351 \return CDF_STATUS
5352 CDF_STATUS_E_INVAL - failure
5353 CDF_STATUS_SUCCESS success
5354 ---------------------------------------------------------------------------*/
5355CDF_STATUS sme_get_wcnss_software_version(tHalHandle hHal,
5356 uint8_t *pVersion,
5357 uint32_t versionBufferSize)
5358{
5359 CDF_STATUS status = CDF_STATUS_SUCCESS;
5360 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
5361 v_CONTEXT_t cds_context = cds_get_global_context();
5362
5363 if (CDF_STATUS_SUCCESS == sme_acquire_global_lock(&pMac->sme)) {
5364 if (pVersion != NULL) {
5365 status =
5366 wma_get_wcnss_software_version(cds_context,
5367 pVersion,
5368 versionBufferSize);
5369 } else {
5370 status = CDF_STATUS_E_INVAL;
5371 }
5372 sme_release_global_lock(&pMac->sme);
5373 }
5374
5375 return status;
5376}
5377
5378/* ---------------------------------------------------------------------------
5379 \fn sme_get_wcnss_hardware_version
5380 \brief This API returns the version string of the WCNSS hardware
5381 \param hHal - The handle returned by mac_open.
5382 \param pVersion - Points to the Version string buffer to be filled
5383 \param versionBufferSize - THe size of the Version string buffer
5384 \return CDF_STATUS
5385 CDF_STATUS_E_INVAL - failure
5386 CDF_STATUS_SUCCESS success
5387 ---------------------------------------------------------------------------*/
5388CDF_STATUS sme_get_wcnss_hardware_version(tHalHandle hHal,
5389 uint8_t *pVersion,
5390 uint32_t versionBufferSize)
5391{
5392 CDF_STATUS status = CDF_STATUS_SUCCESS;
5393 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
5394
5395 if (CDF_STATUS_SUCCESS == sme_acquire_global_lock(&pMac->sme)) {
5396 if (pVersion != NULL)
5397 status = CDF_STATUS_SUCCESS;
5398 else
5399 status = CDF_STATUS_E_INVAL;
5400
5401 sme_release_global_lock(&pMac->sme);
5402 }
5403
5404 return status;
5405}
5406
5407#ifdef FEATURE_WLAN_WAPI
5408
5409/* ---------------------------------------------------------------------------
5410 \fn sme_scan_get_bkid_candidate_list
5411 \brief a wrapper function to return the BKID candidate list
5412 \param pBkidList - caller allocated buffer point to an array of
5413 tBkidCandidateInfo
5414 \param pNumItems - pointer to a variable that has the number of
5415 tBkidCandidateInfo allocated when retruning, this is
5416 either the number needed or number of items put into
5417 pPmkidList
5418 \return CDF_STATUS - when fail, it usually means the buffer allocated is not
5419 big enough and pNumItems
5420 has the number of tBkidCandidateInfo.
5421 \Note: pNumItems is a number of tBkidCandidateInfo,
5422 not sizeof(tBkidCandidateInfo) * something
5423 ---------------------------------------------------------------------------*/
5424CDF_STATUS sme_scan_get_bkid_candidate_list(tHalHandle hHal, uint32_t sessionId,
5425 tBkidCandidateInfo *pBkidList,
5426 uint32_t *pNumItems)
5427{
5428 CDF_STATUS status = CDF_STATUS_E_FAILURE;
5429 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
5430
5431 status = sme_acquire_global_lock(&pMac->sme);
5432 if (CDF_IS_STATUS_SUCCESS(status)) {
5433 status =
5434 csr_scan_get_bkid_candidate_list(pMac, sessionId, pBkidList,
5435 pNumItems);
5436 sme_release_global_lock(&pMac->sme);
5437 }
5438
5439 return status;
5440}
5441#endif /* FEATURE_WLAN_WAPI */
5442
5443#ifdef FEATURE_OEM_DATA_SUPPORT
5444
5445/*****************************************************************************
5446 OEM DATA related modifications and function additions
5447*****************************************************************************/
5448
5449/* ---------------------------------------------------------------------------
5450 \fn sme_oem_data_req
5451 \brief a wrapper function for OEM DATA REQ
5452 \param sessionId - session id to be used.
5453 \param pOemDataReqId - pointer to an object to get back the request ID
5454 \param callback - a callback function that is called upon finish
5455 \param pContext - a pointer passed in for the callback
5456 \return CDF_STATUS
5457 ---------------------------------------------------------------------------*/
5458CDF_STATUS sme_oem_data_req(tHalHandle hHal,
5459 uint8_t sessionId,
5460 tOemDataReqConfig *pOemDataReqConfig,
5461 uint32_t *pOemDataReqID,
5462 oem_data_oem_data_reqCompleteCallback callback,
5463 void *pContext)
5464{
5465 CDF_STATUS status = CDF_STATUS_SUCCESS;
5466 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
5467
5468 do {
5469 /* acquire the lock for the sme object */
5470 status = sme_acquire_global_lock(&pMac->sme);
5471 if (CDF_IS_STATUS_SUCCESS(status)) {
5472 uint32_t lOemDataReqId = pMac->oemData.oemDataReqID++; /* let it wrap around */
5473
5474 if (pOemDataReqID) {
5475 *pOemDataReqID = lOemDataReqId;
5476 } else {
5477 sme_release_global_lock(&pMac->sme);
5478 return CDF_STATUS_E_FAILURE;
5479 }
5480
5481 status =
5482 oem_data_oem_data_req(hHal, sessionId,
5483 pOemDataReqConfig, pOemDataReqID,
5484 callback, pContext);
5485
5486 /* release the lock for the sme object */
5487 sme_release_global_lock(&pMac->sme);
5488 }
5489 } while (0);
5490
5491 sms_log(pMac, LOGW, "exiting function %s", __func__);
5492
5493 return status;
5494}
5495
5496#endif /*FEATURE_OEM_DATA_SUPPORT */
5497
5498/*--------------------------------------------------------------------------
5499
5500 \brief sme_open_session() - Open a session for scan/roam operation.
5501
5502 This is a synchronous API.
5503
5504 \param hHal - The handle returned by mac_open.
5505 \param callback - A pointer to the function caller specifies for
5506 roam/connect status indication
5507 \param pContext - The context passed with callback
5508 \param pSelfMacAddr - Caller allocated memory filled with self MAC address
5509 (6 bytes)
5510 \param pbSessionId - pointer to a caller allocated buffer for returned session ID
5511
5512 \return CDF_STATUS_SUCCESS - session is opened. sessionId returned.
5513
5514 Other status means SME is failed to open the session.
5515 CDF_STATUS_E_RESOURCES - no more session available.
5516 \sa
5517
5518 --------------------------------------------------------------------------*/
5519CDF_STATUS sme_open_session(tHalHandle hHal, csr_roam_completeCallback callback,
5520 void *pContext,
5521 uint8_t *pSelfMacAddr, uint8_t *pbSessionId,
5522 uint32_t type, uint32_t subType)
5523{
5524 CDF_STATUS status;
5525 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
5526
5527 CDF_TRACE(CDF_MODULE_ID_SAP, CDF_TRACE_LEVEL_INFO_HIGH,
5528 "%s: type=%d, subType=%d", __func__, type, subType);
5529
5530 if (NULL == pbSessionId) {
5531 status = CDF_STATUS_E_INVAL;
5532 } else {
5533 status = sme_acquire_global_lock(&pMac->sme);
5534 if (CDF_IS_STATUS_SUCCESS(status)) {
5535 status =
5536 csr_roam_open_session(pMac, callback, pContext,
5537 pSelfMacAddr, pbSessionId, type,
5538 subType);
5539
5540 sme_release_global_lock(&pMac->sme);
5541 }
5542 }
5543 if (NULL != pbSessionId)
5544 MTRACE(cdf_trace(CDF_MODULE_ID_SME,
5545 TRACE_CODE_SME_RX_HDD_OPEN_SESSION,
5546 *pbSessionId, 0));
5547
5548 return status;
5549}
5550
5551/*--------------------------------------------------------------------------
5552
5553 \brief sme_close_session() - Open a session for scan/roam operation.
5554
5555 This is a synchronous API.
5556
5557 \param hHal - The handle returned by mac_open.
5558
5559 \param sessionId - A previous opened session's ID.
5560
5561 \return CDF_STATUS_SUCCESS - session is closed.
5562
5563 Other status means SME is failed to open the session.
5564 CDF_STATUS_E_INVAL - session is not opened.
5565 \sa
5566
5567 --------------------------------------------------------------------------*/
5568CDF_STATUS sme_close_session(tHalHandle hHal, uint8_t sessionId,
5569 csr_roamSessionCloseCallback callback,
5570 void *pContext)
5571{
5572 CDF_STATUS status;
5573 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
5574
5575 MTRACE(cdf_trace(CDF_MODULE_ID_SME,
5576 TRACE_CODE_SME_RX_HDD_CLOSE_SESSION, sessionId, 0));
5577 status = sme_acquire_global_lock(&pMac->sme);
5578 if (CDF_IS_STATUS_SUCCESS(status)) {
5579 status = csr_roam_close_session(pMac, sessionId, false,
5580 callback, pContext);
5581
5582 sme_release_global_lock(&pMac->sme);
5583 }
5584
5585 return status;
5586}
5587
5588/* ---------------------------------------------------------------------------
5589
5590 \fn sme_roam_update_apwpsie
5591
5592 \brief To update AP's WPS IE. This function should be called after SME AP session is created
5593 This is an asynchronous API.
5594
5595 \param pAPWPSIES - pointer to a caller allocated object of tSirAPWPSIEs
5596
5597 \return CDF_STATUS – SUCCESS –
5598
5599 FAILURE or RESOURCES – The API finished and failed.
5600
5601 -------------------------------------------------------------------------------*/
5602CDF_STATUS sme_roam_update_apwpsie(tHalHandle hHal, uint8_t sessionId,
5603 tSirAPWPSIEs *pAPWPSIES)
5604{
5605
5606 CDF_STATUS status = CDF_STATUS_E_FAILURE;
5607 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
5608
5609 status = sme_acquire_global_lock(&pMac->sme);
5610 if (CDF_IS_STATUS_SUCCESS(status)) {
5611
5612 status = csr_roam_update_apwpsie(pMac, sessionId, pAPWPSIES);
5613
5614 sme_release_global_lock(&pMac->sme);
5615 }
5616
5617 return status;
5618}
5619
5620/* ---------------------------------------------------------------------------
5621
5622 \fn sme_roam_update_apwparsni_es
5623
5624 \brief To update AP's WPA/RSN IEs. This function should be called after SME AP session is created
5625 This is an asynchronous API.
5626
5627 \param pAPSirRSNie - pointer to a caller allocated object of tSirRSNie with WPS/RSN IEs
5628
5629 \return CDF_STATUS – SUCCESS –
5630
5631 FAILURE or RESOURCES – The API finished and failed.
5632
5633 -------------------------------------------------------------------------------*/
5634CDF_STATUS sme_roam_update_apwparsni_es(tHalHandle hHal, uint8_t sessionId,
5635 tSirRSNie *pAPSirRSNie)
5636{
5637
5638 CDF_STATUS status = CDF_STATUS_E_FAILURE;
5639 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
5640
5641 status = sme_acquire_global_lock(&pMac->sme);
5642 if (CDF_IS_STATUS_SUCCESS(status)) {
5643
5644 status = csr_roam_update_wparsni_es(pMac, sessionId, pAPSirRSNie);
5645
5646 sme_release_global_lock(&pMac->sme);
5647 }
5648
5649 return status;
5650}
5651
5652/* ---------------------------------------------------------------------------
5653
5654 \fn sme_change_mcc_beacon_interval
5655
5656 \brief To update P2P-GO beaconInterval. This function should be called after
5657 disassociating all the station is done
5658 This is an asynchronous API.
5659
5660 \param
5661
5662 \return CDF_STATUS SUCCESS
5663 FAILURE or RESOURCES
5664 The API finished and failed.
5665
5666 -------------------------------------------------------------------------------*/
5667CDF_STATUS sme_change_mcc_beacon_interval(tHalHandle hHal, uint8_t sessionId)
5668{
5669 CDF_STATUS status = CDF_STATUS_E_FAILURE;
5670 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
5671
5672 sms_log(pMac, LOG1, FL("Update Beacon PARAMS "));
5673 status = sme_acquire_global_lock(&pMac->sme);
5674 if (CDF_IS_STATUS_SUCCESS(status)) {
5675 status = csr_send_chng_mcc_beacon_interval(pMac, sessionId);
5676 sme_release_global_lock(&pMac->sme);
5677 }
5678 return status;
5679}
5680
5681/**
5682 * sme_set_host_offload(): API to set the host offload feature.
5683 * @hHal: The handle returned by mac_open.
5684 * @sessionId: Session Identifier
5685 * @request: Pointer to the offload request.
5686 *
5687 * Return CDF_STATUS
5688 */
5689CDF_STATUS sme_set_host_offload(tHalHandle hHal, uint8_t sessionId,
5690 tpSirHostOffloadReq request)
5691{
5692 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
5693 CDF_STATUS status = CDF_STATUS_E_FAILURE;
5694
5695 MTRACE(cdf_trace(CDF_MODULE_ID_SME,
5696 TRACE_CODE_SME_RX_HDD_SET_HOSTOFFLOAD, sessionId, 0));
5697 status = sme_acquire_global_lock(&pMac->sme);
5698 if (CDF_IS_STATUS_SUCCESS(status)) {
5699#ifdef WLAN_NS_OFFLOAD
5700 if (SIR_IPV6_NS_OFFLOAD == request->offloadType) {
5701 status = sme_set_ps_ns_offload(hHal, request,
5702 sessionId);
5703 } else
5704#endif /* WLAN_NS_OFFLOAD */
5705 {
5706 status = sme_set_ps_host_offload(hHal, request,
5707 sessionId);
5708 }
5709 sme_release_global_lock(&pMac->sme);
5710 }
5711
5712 return status;
5713}
5714
5715#ifdef WLAN_FEATURE_GTK_OFFLOAD
5716/**
5717 * sme_set_gtk_offload(): API to set GTK offload information.
5718 * @hHal: The handle returned by mac_open.
5719 * @sessionId: Session Identifier
5720 * @pGtkOffload: Pointer to the GTK offload request..
5721 *
5722 * Return CDF_STATUS
5723 */
5724CDF_STATUS sme_set_gtk_offload(tHalHandle hHal,
5725 tpSirGtkOffloadParams pGtkOffload,
5726 uint8_t sessionId)
5727{
5728 tpSirGtkOffloadParams request_buf;
5729 cds_msg_t msg;
5730 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
5731 tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
5732
5733 CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_INFO,
5734 "%s: KeyReplayCounter: %lld", __func__,
5735 pGtkOffload->ullKeyReplayCounter);
5736
5737 if (NULL == pSession) {
5738 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
5739 "%s: Session not found ", __func__);
5740 return CDF_STATUS_E_FAILURE;
5741 }
5742
5743 request_buf = cdf_mem_malloc(sizeof(*request_buf));
5744 if (NULL == request_buf) {
5745 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
5746 FL("Not able to allocate memory for GTK offload request"));
5747 return CDF_STATUS_E_NOMEM;
5748 }
5749
5750 cdf_mem_copy(pGtkOffload->bssId, pSession->connectedProfile.bssid.bytes,
5751 sizeof(tSirMacAddr));
5752
5753 *request_buf = *pGtkOffload;
5754
5755 msg.type = WMA_GTK_OFFLOAD_REQ;
5756 msg.reserved = 0;
5757 msg.bodyptr = request_buf;
5758 if (!CDF_IS_STATUS_SUCCESS
5759 (cds_mq_post_message(CDF_MODULE_ID_WMA, &msg))) {
5760 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
5761 FL("Not able to post SIR_HAL_SET_GTK_OFFLOAD message to HAL"));
5762 cdf_mem_free(request_buf);
5763 return CDF_STATUS_E_FAILURE;
5764 }
5765
5766 return CDF_STATUS_SUCCESS;
5767}
5768
5769/**
5770 * sme_get_gtk_offload(): API to get GTK offload information
5771 * @hHal: The handle returned by mac_open.
5772 * @callback_routine: callback_routine.
5773 * @sessionId: Session Identifier.
5774 * callback_context: callback_context.
5775 *
5776 * Return CDF_STATUS
5777 */
5778CDF_STATUS sme_get_gtk_offload(tHalHandle hHal,
5779 gtk_offload_get_info_callback callback_routine,
5780 void *callback_context, uint8_t session_id)
5781{
5782 tpSirGtkOffloadGetInfoRspParams request_buf;
5783 cds_msg_t msg;
5784 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
5785 tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, session_id);
5786
5787 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_INFO, "%s: Entered",
5788 __func__);
5789
5790 if (NULL == pSession) {
5791 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
5792 "%s: Session not found ", __func__);
5793 return CDF_STATUS_E_FAILURE;
5794 }
5795
5796 request_buf = cdf_mem_malloc(sizeof(*request_buf));
5797 if (NULL == request_buf) {
5798 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
5799 FL("Not able to allocate memory for Get GTK offload request"));
5800 return CDF_STATUS_E_NOMEM;
5801 }
5802
5803 cdf_mem_copy(request_buf->bssId, pSession->connectedProfile.bssid.bytes,
5804 sizeof(tSirMacAddr));
5805
5806 msg.type = WMA_GTK_OFFLOAD_GETINFO_REQ;
5807 msg.reserved = 0;
5808 msg.bodyptr = request_buf;
5809
5810 /* Cache the Get GTK Offload callback information */
5811 if (NULL != pMac->sme.gtk_offload_get_info_cb) {
5812
5813 /* Do we need to check if the callback is in use? */
5814 /* Because we are not sending the same message again
5815 * when it is pending,
5816 * the only case when the callback is not NULL is that
5817 * the previous message was timed out or failed.
5818 * So, it will be safe to set the callback in this case.
5819 */
5820 }
5821
5822 pMac->sme.gtk_offload_get_info_cb = callback_routine;
5823 pMac->sme.gtk_offload_get_info_cb_context = callback_context;
5824
5825 if (!CDF_IS_STATUS_SUCCESS
5826 (cds_mq_post_message(CDF_MODULE_ID_WMA, &msg))) {
5827 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
5828 FL("Not able to post WMA_GTK_OFFLOAD_GETINFO_REQ message to WMA"));
5829 cdf_mem_free(request_buf);
5830 return CDF_STATUS_E_FAILURE;
5831 }
5832
5833 return CDF_STATUS_SUCCESS;
5834}
5835#endif /* WLAN_FEATURE_GTK_OFFLOAD */
5836
5837/* ---------------------------------------------------------------------------
5838 \fn sme_set_keep_alive
5839 \brief API to set the Keep Alive feature.
5840 \param hHal - The handle returned by mac_open.
5841 \param request - Pointer to the Keep Alive request.
5842 \return CDF_STATUS
5843 ---------------------------------------------------------------------------*/
5844CDF_STATUS sme_set_keep_alive(tHalHandle hHal, uint8_t session_id,
5845 tpSirKeepAliveReq request)
5846{
5847 tpSirKeepAliveReq request_buf;
5848 cds_msg_t msg;
5849 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
5850 tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, session_id);
5851
5852 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_INFO_LOW,
5853 FL("WMA_SET_KEEP_ALIVE message"));
5854
5855 if (pSession == NULL) {
5856 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
5857 FL("Session not Found"));
5858 return CDF_STATUS_E_FAILURE;
5859 }
5860 request_buf = cdf_mem_malloc(sizeof(tSirKeepAliveReq));
5861 if (NULL == request_buf) {
5862 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
5863 FL("Not able to allocate memory for keep alive request"));
5864 return CDF_STATUS_E_NOMEM;
5865 }
5866
5867 cdf_mem_copy(request->bssId, pSession->connectedProfile.bssid.bytes,
5868 sizeof(tSirMacAddr));
5869 cdf_mem_copy(request_buf, request, sizeof(tSirKeepAliveReq));
5870
5871 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_INFO_LOW,
5872 "buff TP %d input TP %d ", request_buf->timePeriod,
5873 request->timePeriod);
5874 request_buf->sessionId = session_id;
5875
5876 msg.type = WMA_SET_KEEP_ALIVE;
5877 msg.reserved = 0;
5878 msg.bodyptr = request_buf;
5879 if (CDF_STATUS_SUCCESS !=
5880 cds_mq_post_message(CDF_MODULE_ID_WMA, &msg)) {
5881 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
5882 FL("Not able to post WMA_SET_KEEP_ALIVE message to WMA"));
5883 cdf_mem_free(request_buf);
5884 return CDF_STATUS_E_FAILURE;
5885 }
5886
5887 return CDF_STATUS_SUCCESS;
5888}
5889
5890#ifdef FEATURE_WLAN_SCAN_PNO
5891/* ---------------------------------------------------------------------------
5892 \fn sme_set_preferred_network_list
5893 \brief API to set the Preferred Network List Offload feature.
5894 \param hHal - The handle returned by mac_open.
5895 \param request - Pointer to the offload request.
5896 \return CDF_STATUS
5897 ---------------------------------------------------------------------------*/
5898CDF_STATUS sme_set_preferred_network_list(tHalHandle hHal,
5899 tpSirPNOScanReq request,
5900 uint8_t sessionId,
5901 void (*callback_routine)(void *callback_context,
5902 tSirPrefNetworkFoundInd
5903 *pPrefNetworkFoundInd),
5904 void *callback_context)
5905{
5906 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
5907 CDF_STATUS status;
5908
5909 status = sme_acquire_global_lock(&pMac->sme);
5910 if (CDF_IS_STATUS_SUCCESS(status)) {
5911 sme_set_ps_preferred_network_list(hHal, request, sessionId,
5912 callback_routine, callback_context);
5913 sme_release_global_lock(&pMac->sme);
5914 }
5915
5916 return status;
5917}
5918
5919#endif /* FEATURE_WLAN_SCAN_PNO */
5920
5921/* ---------------------------------------------------------------------------
5922 \fn sme_abort_mac_scan
5923 \brief API to cancel MAC scan.
5924 \param hHal - The handle returned by mac_open.
5925 \param sessionId - sessionId on which we need to abort scan.
5926 \param reason - Reason to abort the scan.
5927 \return CDF_STATUS
5928 CDF_STATUS_E_FAILURE - failure
5929 CDF_STATUS_SUCCESS success
5930 ---------------------------------------------------------------------------*/
5931CDF_STATUS sme_abort_mac_scan(tHalHandle hHal, uint8_t sessionId,
5932 eCsrAbortReason reason)
5933{
5934 CDF_STATUS status;
5935 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
5936
5937 MTRACE(cdf_trace(CDF_MODULE_ID_SME,
5938 TRACE_CODE_SME_RX_HDD_ABORT_MACSCAN, NO_SESSION, 0));
5939 status = sme_acquire_global_lock(&pMac->sme);
5940 if (CDF_IS_STATUS_SUCCESS(status)) {
5941 status = csr_scan_abort_mac_scan(pMac, sessionId, reason);
5942
5943 sme_release_global_lock(&pMac->sme);
5944 }
5945
5946 return status;
5947}
5948
5949/* ----------------------------------------------------------------------------
5950 \fn sme_get_operation_channel
5951 \brief API to get current channel on which STA is parked
5952 this function gives channel information only of infra station or IBSS station
5953 \param hHal, pointer to memory location and sessionId
5954 \returns CDF_STATUS_SUCCESS
5955 CDF_STATUS_E_FAILURE
5956 -------------------------------------------------------------------------------*/
5957CDF_STATUS sme_get_operation_channel(tHalHandle hHal, uint32_t *pChannel,
5958 uint8_t sessionId)
5959{
5960 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
5961 tCsrRoamSession *pSession;
5962
5963 if (CSR_IS_SESSION_VALID(pMac, sessionId)) {
5964 pSession = CSR_GET_SESSION(pMac, sessionId);
5965
5966 if ((pSession->connectedProfile.BSSType ==
5967 eCSR_BSS_TYPE_INFRASTRUCTURE)
5968 || (pSession->connectedProfile.BSSType ==
5969 eCSR_BSS_TYPE_IBSS)
5970 || (pSession->connectedProfile.BSSType ==
5971 eCSR_BSS_TYPE_INFRA_AP)
5972 || (pSession->connectedProfile.BSSType ==
5973 eCSR_BSS_TYPE_START_IBSS)) {
5974 *pChannel = pSession->connectedProfile.operationChannel;
5975 return CDF_STATUS_SUCCESS;
5976 }
5977 }
5978 return CDF_STATUS_E_FAILURE;
5979} /* sme_get_operation_channel ends here */
5980
5981/* ---------------------------------------------------------------------------
5982
5983 \fn sme_RegisterMgtFrame
5984
5985 \brief To register managment frame of specified type and subtype.
5986 \param frameType - type of the frame that needs to be passed to HDD.
5987 \param matchData - data which needs to be matched before passing frame
5988 to HDD.
5989 \param matchDataLen - Length of matched data.
5990 \return CDF_STATUS
5991 -------------------------------------------------------------------------------*/
5992CDF_STATUS sme_register_mgmt_frame(tHalHandle hHal, uint8_t sessionId,
5993 uint16_t frameType, uint8_t *matchData,
5994 uint16_t matchLen)
5995{
5996 CDF_STATUS status = CDF_STATUS_SUCCESS;
5997 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
5998
5999 MTRACE(cdf_trace(CDF_MODULE_ID_SME,
6000 TRACE_CODE_SME_RX_HDD_REGISTER_MGMTFR, sessionId, 0));
6001 status = sme_acquire_global_lock(&pMac->sme);
6002 if (CDF_IS_STATUS_SUCCESS(status)) {
6003 tSirRegisterMgmtFrame *pMsg;
6004 uint16_t len;
6005 tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
6006
6007 if (!CSR_IS_SESSION_ANY(sessionId) && !pSession) {
6008 sms_log(pMac, LOGE, FL(" session %d not found "),
6009 sessionId);
6010 sme_release_global_lock(&pMac->sme);
6011 return CDF_STATUS_E_FAILURE;
6012 }
6013
6014 if (!CSR_IS_SESSION_ANY(sessionId) && !pSession->sessionActive) {
6015 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
6016 "%s Invalid Sessionid", __func__);
6017 sme_release_global_lock(&pMac->sme);
6018 return CDF_STATUS_E_FAILURE;
6019 }
6020
6021 len = sizeof(tSirRegisterMgmtFrame) + matchLen;
6022
6023 pMsg = cdf_mem_malloc(len);
6024 if (NULL == pMsg)
6025 status = CDF_STATUS_E_NOMEM;
6026 else {
6027 cdf_mem_set(pMsg, len, 0);
6028 pMsg->messageType = eWNI_SME_REGISTER_MGMT_FRAME_REQ;
6029 pMsg->length = len;
6030 pMsg->sessionId = sessionId;
6031 pMsg->registerFrame = true;
6032 pMsg->frameType = frameType;
6033 pMsg->matchLen = matchLen;
6034 cdf_mem_copy(pMsg->matchData, matchData, matchLen);
6035 status = cds_send_mb_message_to_mac(pMsg);
6036 }
6037 sme_release_global_lock(&pMac->sme);
6038 }
6039 return status;
6040}
6041
6042/* ---------------------------------------------------------------------------
6043
6044 \fn sme_DeregisterMgtFrame
6045
6046 \brief To De-register managment frame of specified type and subtype.
6047 \param frameType - type of the frame that needs to be passed to HDD.
6048 \param matchData - data which needs to be matched before passing frame
6049 to HDD.
6050 \param matchDataLen - Length of matched data.
6051 \return CDF_STATUS
6052 -------------------------------------------------------------------------------*/
6053CDF_STATUS sme_deregister_mgmt_frame(tHalHandle hHal, uint8_t sessionId,
6054 uint16_t frameType, uint8_t *matchData,
6055 uint16_t matchLen)
6056{
6057 CDF_STATUS status = CDF_STATUS_SUCCESS;
6058 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
6059
6060 MTRACE(cdf_trace(CDF_MODULE_ID_SME,
6061 TRACE_CODE_SME_RX_HDD_DEREGISTER_MGMTFR, sessionId,
6062 0));
6063 status = sme_acquire_global_lock(&pMac->sme);
6064 if (CDF_IS_STATUS_SUCCESS(status)) {
6065 tSirRegisterMgmtFrame *pMsg;
6066 uint16_t len;
6067 tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
6068
6069 if (!CSR_IS_SESSION_ANY(sessionId) && !pSession) {
6070 sms_log(pMac, LOGE, FL(" session %d not found "),
6071 sessionId);
6072 sme_release_global_lock(&pMac->sme);
6073 return CDF_STATUS_E_FAILURE;
6074 }
6075
6076 if (!CSR_IS_SESSION_ANY(sessionId) && !pSession->sessionActive) {
6077 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
6078 "%s Invalid Sessionid", __func__);
6079 sme_release_global_lock(&pMac->sme);
6080 return CDF_STATUS_E_FAILURE;
6081 }
6082
6083 len = sizeof(tSirRegisterMgmtFrame) + matchLen;
6084
6085 pMsg = cdf_mem_malloc(len);
6086 if (NULL == pMsg)
6087 status = CDF_STATUS_E_NOMEM;
6088 else {
6089 cdf_mem_set(pMsg, len, 0);
6090 pMsg->messageType = eWNI_SME_REGISTER_MGMT_FRAME_REQ;
6091 pMsg->length = len;
6092 pMsg->registerFrame = false;
6093 pMsg->frameType = frameType;
6094 pMsg->matchLen = matchLen;
6095 cdf_mem_copy(pMsg->matchData, matchData, matchLen);
6096 status = cds_send_mb_message_to_mac(pMsg);
6097 }
6098 sme_release_global_lock(&pMac->sme);
6099 }
6100 return status;
6101}
6102
6103/**
6104 * sme_remain_on_channel - API to request remain on channel for 'x' duration
6105 *
6106 * @hHal: pointer to MAC handle
6107 * @session_id: Session identifier
6108 * @channel: channel information
6109 * @duration: duration in ms
6110 * @callback: HDD registered callback to process reaminOnChannelRsp
6111 * @context: HDD Callback param
6112 * @scan_id: scan identifier
6113 *
6114 * This function process the roc request and generates scan identifier.s
6115 *
6116 * Return: CDF_STATUS
6117 */
6118CDF_STATUS sme_remain_on_channel(tHalHandle hHal, uint8_t session_id,
6119 uint8_t channel, uint32_t duration,
6120 remainOnChanCallback callback,
6121 void *pContext, uint8_t isP2PProbeReqAllowed,
6122 uint32_t *scan_id)
6123{
6124 CDF_STATUS status = CDF_STATUS_SUCCESS;
6125 tpAniSirGlobal mac_ctx = PMAC_STRUCT(hHal);
6126 uint32_t san_req_id, scan_count;
6127 struct ani_roc_req *roc_msg;
6128 cds_msg_t msg;
6129
6130
6131 MTRACE(cdf_trace(CDF_MODULE_ID_SME,
6132 TRACE_CODE_SME_RX_HDD_REMAIN_ONCHAN, session_id, 0));
6133
6134 scan_count = csr_ll_count(&mac_ctx->sme.smeScanCmdActiveList);
6135 if (scan_count >= mac_ctx->scan.max_scan_count) {
6136 sms_log(mac_ctx, LOGE, FL("Max scan reached"));
6137 return CDF_STATUS_E_FAILURE;
6138 }
6139
6140 wma_get_scan_id(&san_req_id);
6141 *scan_id = san_req_id;
6142 status = sme_acquire_global_lock(&mac_ctx->sme);
6143
6144 sms_log(mac_ctx, LOG1, FL(" called"));
6145 roc_msg = cdf_mem_malloc(sizeof(struct ani_roc_req));
6146 if (NULL == roc_msg) {
6147 sms_log(mac_ctx, LOGE,
6148 " scan_req: failed to allocate mem for msg");
6149 sme_release_global_lock(&mac_ctx->sme);
6150 return CDF_STATUS_E_NOMEM;
6151 }
6152 roc_msg->msg_type = eWNI_SME_ROC_CMD;
6153 roc_msg->msg_len = (uint16_t) sizeof(struct ani_roc_req);
6154 roc_msg->session_id = session_id;
6155 roc_msg->callback = callback;
6156 roc_msg->duration = duration;
6157 roc_msg->channel = channel;
6158 roc_msg->is_p2pprobe_allowed = isP2PProbeReqAllowed;
6159 roc_msg->ctx = pContext;
6160 roc_msg->scan_id = *scan_id;
6161 msg.type = eWNI_SME_ROC_CMD;
6162 msg.bodyptr = roc_msg;
6163 msg.reserved = 0;
6164 msg.bodyval = 0;
6165 if (CDF_STATUS_SUCCESS !=
6166 cds_mq_post_message(CDS_MQ_ID_SME, &msg)) {
6167 sms_log(mac_ctx, LOGE,
6168 " sme_scan_req failed to post msg");
6169 cdf_mem_free(roc_msg);
6170 status = CDF_STATUS_E_FAILURE;
6171 }
6172 sme_release_global_lock(&mac_ctx->sme);
6173 return status;
6174}
6175
6176/* ---------------------------------------------------------------------------
6177 \fn sme_report_probe_req
6178 \brief API to enable/disable forwarding of probeReq to apps in p2p.
6179 \param hHal - The handle returned by mac_open.
6180 \param falg: to set the Probe request forarding to wpa_supplicant in listen state in p2p
6181 \return CDF_STATUS
6182 ---------------------------------------------------------------------------*/
6183
6184#ifndef WLAN_FEATURE_CONCURRENT_P2P
6185CDF_STATUS sme_report_probe_req(tHalHandle hHal, uint8_t flag)
6186{
6187 CDF_STATUS status = CDF_STATUS_SUCCESS;
6188 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
6189
6190 do {
6191 /* acquire the lock for the sme object */
6192 status = sme_acquire_global_lock(&pMac->sme);
6193 if (CDF_IS_STATUS_SUCCESS(status)) {
6194 /* call set in context */
6195 pMac->p2pContext.probeReqForwarding = flag;
6196 /* release the lock for the sme object */
6197 sme_release_global_lock(&pMac->sme);
6198 }
6199 } while (0);
6200
6201 sms_log(pMac, LOGW, "exiting function %s", __func__);
6202
6203 return status;
6204}
6205
6206/* ---------------------------------------------------------------------------
6207 \fn sme_update_p2p_ie
6208 \brief API to set the P2p Ie in p2p context
6209 \param hHal - The handle returned by mac_open.
6210 \param p2pIe - Ptr to p2pIe from HDD.
6211 \param p2pIeLength: length of p2pIe
6212 \return CDF_STATUS
6213 ---------------------------------------------------------------------------*/
6214
6215CDF_STATUS sme_update_p2p_ie(tHalHandle hHal, void *p2pIe, uint32_t p2pIeLength)
6216{
6217 CDF_STATUS status = CDF_STATUS_SUCCESS;
6218 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
6219
6220 MTRACE(cdf_trace(CDF_MODULE_ID_SME,
6221 TRACE_CODE_SME_RX_HDD_UPDATE_P2P_IE, NO_SESSION, 0));
6222 /* acquire the lock for the sme object */
6223 status = sme_acquire_global_lock(&pMac->sme);
6224 if (CDF_IS_STATUS_SUCCESS(status)) {
6225 if (NULL != pMac->p2pContext.probeRspIe) {
6226 cdf_mem_free(pMac->p2pContext.probeRspIe);
6227 pMac->p2pContext.probeRspIeLength = 0;
6228 }
6229
6230 pMac->p2pContext.probeRspIe = cdf_mem_malloc(p2pIeLength);
6231 if (NULL == pMac->p2pContext.probeRspIe) {
6232 sms_log(pMac, LOGE, "%s: Unable to allocate P2P IE",
6233 __func__);
6234 pMac->p2pContext.probeRspIeLength = 0;
6235 status = CDF_STATUS_E_NOMEM;
6236 } else {
6237 pMac->p2pContext.probeRspIeLength = p2pIeLength;
6238
6239 sir_dump_buf(pMac, SIR_LIM_MODULE_ID, LOG2,
6240 pMac->p2pContext.probeRspIe,
6241 pMac->p2pContext.probeRspIeLength);
6242 cdf_mem_copy((uint8_t *) pMac->p2pContext.probeRspIe,
6243 p2pIe, p2pIeLength);
6244 }
6245
6246 /* release the lock for the sme object */
6247 sme_release_global_lock(&pMac->sme);
6248 }
6249
6250 sms_log(pMac, LOG2, "exiting function %s", __func__);
6251
6252 return status;
6253}
6254#endif
6255
6256/* ---------------------------------------------------------------------------
6257 \fn sme_send_action
6258 \brief API to send action frame from supplicant.
6259 \param hHal - The handle returned by mac_open.
6260 \return CDF_STATUS
6261 ---------------------------------------------------------------------------*/
6262
6263CDF_STATUS sme_send_action(tHalHandle hHal, uint8_t sessionId,
6264 const uint8_t *pBuf, uint32_t len,
6265 uint16_t wait, bool noack,
6266 uint16_t channel_freq)
6267{
6268 CDF_STATUS status = CDF_STATUS_SUCCESS;
6269 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
6270
6271 MTRACE(cdf_trace(CDF_MODULE_ID_SME,
6272 TRACE_CODE_SME_RX_HDD_SEND_ACTION, sessionId, 0));
6273 /* acquire the lock for the sme object */
6274 status = sme_acquire_global_lock(&pMac->sme);
6275 if (CDF_IS_STATUS_SUCCESS(status)) {
6276 p2p_send_action(hHal, sessionId, pBuf, len, wait, noack,
6277 channel_freq);
6278 /* release the lock for the sme object */
6279 sme_release_global_lock(&pMac->sme);
6280 }
6281
6282 sms_log(pMac, LOGW, "exiting function %s", __func__);
6283
6284 return status;
6285}
6286
6287CDF_STATUS sme_cancel_remain_on_channel(tHalHandle hHal,
6288 uint8_t sessionId, uint32_t scan_id)
6289{
6290 CDF_STATUS status = CDF_STATUS_SUCCESS;
6291 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
6292
6293 MTRACE(cdf_trace(CDF_MODULE_ID_SME,
6294 TRACE_CODE_SME_RX_HDD_CANCEL_REMAIN_ONCHAN, sessionId,
6295 0));
6296 status = sme_acquire_global_lock(&pMac->sme);
6297 if (CDF_IS_STATUS_SUCCESS(status)) {
6298 status = p2p_cancel_remain_on_channel(hHal, sessionId, scan_id);
6299 sme_release_global_lock(&pMac->sme);
6300 }
6301 return status;
6302}
6303
6304/* Power Save Related */
6305CDF_STATUS sme_p2p_set_ps(tHalHandle hHal, tP2pPsConfig *data)
6306{
6307 CDF_STATUS status = CDF_STATUS_SUCCESS;
6308 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
6309
6310 status = sme_acquire_global_lock(&pMac->sme);
6311 if (CDF_IS_STATUS_SUCCESS(status)) {
6312 status = p2p_set_ps(hHal, data);
6313 sme_release_global_lock(&pMac->sme);
6314 }
6315 return status;
6316}
6317
6318/* ---------------------------------------------------------------------------
6319
6320 \fn sme_configure_rxp_filter
6321
6322 \brief
6323 SME will pass this request to lower mac to set/reset the filter on RXP for
6324 multicast & broadcast traffic.
6325
6326 \param
6327
6328 hHal - The handle returned by mac_open.
6329
6330 filterMask- Currently the API takes a 1 or 0 (set or reset) as filter.
6331 Basically to enable/disable the filter (to filter "all" mcbc traffic) based
6332 on this param. In future we can use this as a mask to set various types of
6333 filters as suggested below:
6334 FILTER_ALL_MULTICAST:
6335 FILTER_ALL_BROADCAST:
6336 FILTER_ALL_MULTICAST_BROADCAST:
6337
6338 \return CDF_STATUS
6339
6340 --------------------------------------------------------------------------- */
6341CDF_STATUS sme_configure_rxp_filter(tHalHandle hHal,
6342 tpSirWlanSetRxpFilters wlanRxpFilterParam)
6343{
6344 CDF_STATUS status = CDF_STATUS_SUCCESS;
6345 CDF_STATUS cdf_status = CDF_STATUS_SUCCESS;
6346 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
6347 cds_msg_t cds_message;
6348
6349 MTRACE(cdf_trace(CDF_MODULE_ID_SME,
6350 TRACE_CODE_SME_RX_HDD_CONFIG_RXPFIL, NO_SESSION, 0));
6351 status = sme_acquire_global_lock(&pMac->sme);
6352 if (CDF_IS_STATUS_SUCCESS(status)) {
6353 /* serialize the req through MC thread */
6354 cds_message.bodyptr = wlanRxpFilterParam;
6355 cds_message.type = WMA_CFG_RXP_FILTER_REQ;
6356 cdf_status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message);
6357 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
6358 status = CDF_STATUS_E_FAILURE;
6359 }
6360 sme_release_global_lock(&pMac->sme);
6361 }
6362 return status;
6363}
6364
6365/* ---------------------------------------------------------------------------
6366
6367 \fn sme_configure_suspend_ind
6368
6369 \brief
6370 SME will pass this request to lower mac to Indicate that the wlan needs to
6371 be suspended
6372
6373 \param
6374
6375 hHal - The handle returned by mac_open.
6376
6377 wlanSuspendParam- Depicts the wlan suspend params
6378
6379 csr_readyToSuspendCallback - Callback to be called when ready to suspend
6380 event is received.
6381 callback_context - Context associated with csr_readyToSuspendCallback.
6382
6383 \return CDF_STATUS
6384
6385 --------------------------------------------------------------------------- */
6386CDF_STATUS sme_configure_suspend_ind(tHalHandle hHal,
6387 tpSirWlanSuspendParam wlanSuspendParam,
6388 csr_readyToSuspendCallback callback,
6389 void *callback_context)
6390{
6391 CDF_STATUS status = CDF_STATUS_SUCCESS;
6392 CDF_STATUS cdf_status = CDF_STATUS_SUCCESS;
6393 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
6394 cds_msg_t cds_message;
6395
6396 MTRACE(cdf_trace(CDF_MODULE_ID_SME,
6397 TRACE_CODE_SME_RX_HDD_CONFIG_SUSPENDIND, NO_SESSION,
6398 0));
6399
6400 pMac->readyToSuspendCallback = callback;
6401 pMac->readyToSuspendContext = callback_context;
6402
6403 status = sme_acquire_global_lock(&pMac->sme);
6404 if (CDF_IS_STATUS_SUCCESS(status)) {
6405 /* serialize the req through MC thread */
6406 cds_message.bodyptr = wlanSuspendParam;
6407 cds_message.type = WMA_WLAN_SUSPEND_IND;
6408 cdf_status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message);
6409 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
6410 pMac->readyToSuspendCallback = NULL;
6411 pMac->readyToSuspendContext = NULL;
6412 status = CDF_STATUS_E_FAILURE;
6413 }
6414 sme_release_global_lock(&pMac->sme);
6415 }
6416
6417 return status;
6418}
6419
6420/* ---------------------------------------------------------------------------
6421
6422 \fn sme_configure_resume_req
6423
6424 \brief
6425 SME will pass this request to lower mac to Indicate that the wlan needs to
6426 be Resumed
6427
6428 \param
6429
6430 hHal - The handle returned by mac_open.
6431
6432 wlanResumeParam- Depicts the wlan resume params
6433
6434 \return CDF_STATUS
6435
6436 --------------------------------------------------------------------------- */
6437CDF_STATUS sme_configure_resume_req(tHalHandle hHal,
6438 tpSirWlanResumeParam wlanResumeParam)
6439{
6440 CDF_STATUS status = CDF_STATUS_SUCCESS;
6441 CDF_STATUS cdf_status = CDF_STATUS_SUCCESS;
6442 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
6443 cds_msg_t cds_message;
6444
6445 MTRACE(cdf_trace(CDF_MODULE_ID_SME,
6446 TRACE_CODE_SME_RX_HDD_CONFIG_RESUMEREQ, NO_SESSION,
6447 0));
6448 status = sme_acquire_global_lock(&pMac->sme);
6449 if (CDF_IS_STATUS_SUCCESS(status)) {
6450 /* serialize the req through MC thread */
6451 cds_message.bodyptr = wlanResumeParam;
6452 cds_message.type = WMA_WLAN_RESUME_REQ;
6453 cdf_status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message);
6454 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
6455 status = CDF_STATUS_E_FAILURE;
6456 }
6457 sme_release_global_lock(&pMac->sme);
6458 }
6459 return status;
6460}
6461
6462#ifdef WLAN_FEATURE_EXTWOW_SUPPORT
6463/* ---------------------------------------------------------------------------
6464
6465 \fn sme_configure_ext_wo_w
6466
6467 \brief
6468 SME will pass this request to lower mac to configure Extr WoW
6469
6470 \param
6471
6472 hHal - The handle returned by mac_open.
6473
6474 wlanExtParams- Depicts the wlan Ext params
6475
6476 \return CDF_STATUS
6477
6478 --------------------------------------------------------------------------- */
6479CDF_STATUS sme_configure_ext_wo_w(tHalHandle hHal,
6480 tpSirExtWoWParams wlanExtParams,
6481 csr_readyToExtWoWCallback callback,
6482 void *callback_context)
6483{
6484 CDF_STATUS status = CDF_STATUS_SUCCESS;
6485 CDF_STATUS cdf_status = CDF_STATUS_SUCCESS;
6486 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
6487 cds_msg_t cds_message;
6488 tpSirExtWoWParams MsgPtr = cdf_mem_malloc(sizeof(*MsgPtr));
6489
6490 if (!MsgPtr)
6491 return CDF_STATUS_E_NOMEM;
6492
6493 MTRACE(cdf_trace(CDF_MODULE_ID_SME,
6494 TRACE_CODE_SME_RX_HDD_CONFIG_EXTWOW, NO_SESSION, 0));
6495
6496 pMac->readyToExtWoWCallback = callback;
6497 pMac->readyToExtWoWContext = callback_context;
6498
6499 status = sme_acquire_global_lock(&pMac->sme);
6500 if (CDF_IS_STATUS_SUCCESS(status)) {
6501
6502 /* serialize the req through MC thread */
6503 cdf_mem_copy(MsgPtr, wlanExtParams, sizeof(*MsgPtr));
6504 cds_message.bodyptr = MsgPtr;
6505 cds_message.type = WMA_WLAN_EXT_WOW;
6506 cdf_status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message);
6507 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
6508 pMac->readyToExtWoWCallback = NULL;
6509 pMac->readyToExtWoWContext = NULL;
6510 cdf_mem_free(MsgPtr);
6511 status = CDF_STATUS_E_FAILURE;
6512 }
6513 sme_release_global_lock(&pMac->sme);
6514 } else {
6515 pMac->readyToExtWoWCallback = NULL;
6516 pMac->readyToExtWoWContext = NULL;
6517 cdf_mem_free(MsgPtr);
6518 }
6519
6520 return status;
6521}
6522
6523/* ---------------------------------------------------------------------------
6524
6525 \fn sme_configure_app_type1_params
6526
6527 \brief
6528 SME will pass this request to lower mac to configure Indoor WoW parameters.
6529
6530 \param
6531
6532 hHal - The handle returned by mac_open.
6533
6534 wlanAppType1Params- Depicts the wlan App Type 1(Indoor) params
6535
6536 \return CDF_STATUS
6537
6538 --------------------------------------------------------------------------- */
6539CDF_STATUS sme_configure_app_type1_params(tHalHandle hHal,
6540 tpSirAppType1Params wlanAppType1Params)
6541{
6542 CDF_STATUS status = CDF_STATUS_SUCCESS;
6543 CDF_STATUS cdf_status = CDF_STATUS_SUCCESS;
6544 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
6545 cds_msg_t cds_message;
6546 tpSirAppType1Params MsgPtr = cdf_mem_malloc(sizeof(*MsgPtr));
6547
6548 if (!MsgPtr)
6549 return CDF_STATUS_E_NOMEM;
6550
6551 MTRACE(cdf_trace(CDF_MODULE_ID_SME,
6552 TRACE_CODE_SME_RX_HDD_CONFIG_APP_TYPE1, NO_SESSION,
6553 0));
6554
6555 status = sme_acquire_global_lock(&pMac->sme);
6556 if (CDF_IS_STATUS_SUCCESS(status)) {
6557 /* serialize the req through MC thread */
6558 cdf_mem_copy(MsgPtr, wlanAppType1Params, sizeof(*MsgPtr));
6559 cds_message.bodyptr = MsgPtr;
6560 cds_message.type = WMA_WLAN_SET_APP_TYPE1_PARAMS;
6561 cdf_status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message);
6562 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
6563 cdf_mem_free(MsgPtr);
6564 status = CDF_STATUS_E_FAILURE;
6565 }
6566 sme_release_global_lock(&pMac->sme);
6567 } else {
6568 cdf_mem_free(MsgPtr);
6569 }
6570
6571 return status;
6572}
6573
6574/* ---------------------------------------------------------------------------
6575
6576 \fn sme_configure_app_type2_params
6577
6578 \brief
6579 SME will pass this request to lower mac to configure Indoor WoW parameters.
6580
6581 \param
6582
6583 hHal - The handle returned by mac_open.
6584
6585 wlanAppType2Params- Depicts the wlan App Type 2 (Outdoor) params
6586
6587 \return CDF_STATUS
6588
6589 --------------------------------------------------------------------------- */
6590CDF_STATUS sme_configure_app_type2_params(tHalHandle hHal,
6591 tpSirAppType2Params wlanAppType2Params)
6592{
6593 CDF_STATUS status = CDF_STATUS_SUCCESS;
6594 CDF_STATUS cdf_status = CDF_STATUS_SUCCESS;
6595 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
6596 cds_msg_t cds_message;
6597 tpSirAppType2Params MsgPtr = cdf_mem_malloc(sizeof(*MsgPtr));
6598
6599 if (!MsgPtr)
6600 return CDF_STATUS_E_NOMEM;
6601
6602 MTRACE(cdf_trace(CDF_MODULE_ID_SME,
6603 TRACE_CODE_SME_RX_HDD_CONFIG_APP_TYPE2, NO_SESSION,
6604 0));
6605
6606 status = sme_acquire_global_lock(&pMac->sme);
6607 if (CDF_IS_STATUS_SUCCESS(status)) {
6608 /* serialize the req through MC thread */
6609 cdf_mem_copy(MsgPtr, wlanAppType2Params, sizeof(*MsgPtr));
6610 cds_message.bodyptr = MsgPtr;
6611 cds_message.type = WMA_WLAN_SET_APP_TYPE2_PARAMS;
6612 cdf_status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message);
6613 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
6614 cdf_mem_free(MsgPtr);
6615 status = CDF_STATUS_E_FAILURE;
6616 }
6617 sme_release_global_lock(&pMac->sme);
6618 } else {
6619 cdf_mem_free(MsgPtr);
6620 }
6621
6622 return status;
6623}
6624#endif
6625
6626/* ---------------------------------------------------------------------------
6627
6628 \fn sme_get_infra_session_id
6629
6630 \brief To get the session ID for infra session, if connected
6631 This is a synchronous API.
6632
6633 \param hHal - The handle returned by mac_open.
6634
6635 \return sessionid, -1 if infra session is not connected
6636
6637 -------------------------------------------------------------------------------*/
6638int8_t sme_get_infra_session_id(tHalHandle hHal)
6639{
6640 CDF_STATUS status = CDF_STATUS_E_FAILURE;
6641 int8_t sessionid = -1;
6642 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
6643
6644 status = sme_acquire_global_lock(&pMac->sme);
6645 if (CDF_IS_STATUS_SUCCESS(status)) {
6646
6647 sessionid = csr_get_infra_session_id(pMac);
6648
6649 sme_release_global_lock(&pMac->sme);
6650 }
6651
6652 return sessionid;
6653}
6654
6655/* ---------------------------------------------------------------------------
6656
6657 \fn sme_get_infra_operation_channel
6658
6659 \brief To get the operating channel for infra session, if connected
6660 This is a synchronous API.
6661
6662 \param hHal - The handle returned by mac_open.
6663 \param sessionId - the sessionId returned by sme_open_session.
6664
6665 \return operating channel, 0 if infra session is not connected
6666
6667 -------------------------------------------------------------------------------*/
6668uint8_t sme_get_infra_operation_channel(tHalHandle hHal, uint8_t sessionId)
6669{
6670 CDF_STATUS status = CDF_STATUS_E_FAILURE;
6671 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
6672 uint8_t channel = 0;
6673 status = sme_acquire_global_lock(&pMac->sme);
6674 if (CDF_IS_STATUS_SUCCESS(status)) {
6675
6676 channel = csr_get_infra_operation_channel(pMac, sessionId);
6677
6678 sme_release_global_lock(&pMac->sme);
6679 }
6680
6681 return channel;
6682}
6683
6684/* This routine will return poerating channel on which other BSS is operating to be used for concurrency mode. */
6685/* If other BSS is not up or not connected it will return 0 */
6686uint8_t sme_get_concurrent_operation_channel(tHalHandle hHal)
6687{
6688 CDF_STATUS status = CDF_STATUS_E_FAILURE;
6689 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
6690 uint8_t channel = 0;
6691 status = sme_acquire_global_lock(&pMac->sme);
6692 if (CDF_IS_STATUS_SUCCESS(status)) {
6693
6694 channel = csr_get_concurrent_operation_channel(pMac);
6695 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_INFO_HIGH, "%s: "
6696 " Other Concurrent Channel = %d", __func__, channel);
6697 sme_release_global_lock(&pMac->sme);
6698 }
6699
6700 return channel;
6701}
6702
6703#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
6704uint16_t sme_check_concurrent_channel_overlap(tHalHandle hHal, uint16_t sap_ch,
6705 eCsrPhyMode sapPhyMode,
6706 uint8_t cc_switch_mode)
6707{
6708 CDF_STATUS status = CDF_STATUS_E_FAILURE;
6709 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
6710 uint16_t channel = 0;
6711
6712 status = sme_acquire_global_lock(&pMac->sme);
6713 if (CDF_IS_STATUS_SUCCESS(status)) {
6714 channel =
6715 csr_check_concurrent_channel_overlap(pMac, sap_ch, sapPhyMode,
6716 cc_switch_mode);
6717 sme_release_global_lock(&pMac->sme);
6718 }
6719
6720 return channel;
6721}
6722#endif
6723
6724#ifdef FEATURE_WLAN_SCAN_PNO
6725/******************************************************************************
6726*
6727* Name: sme_preferred_network_found_ind
6728*
6729* Description:
6730* Invoke Preferred Network Found Indication
6731*
6732* Parameters:
6733* hHal - HAL handle for device
6734* pMsg - found network description
6735*
6736* Returns: CDF_STATUS
6737*
6738******************************************************************************/
6739CDF_STATUS sme_preferred_network_found_ind(tHalHandle hHal, void *pMsg)
6740{
6741 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
6742 CDF_STATUS status = CDF_STATUS_SUCCESS;
6743 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd =
6744 (tSirPrefNetworkFoundInd *) pMsg;
6745 uint8_t dumpSsId[SIR_MAC_MAX_SSID_LENGTH + 1];
6746 uint8_t ssIdLength = 0;
6747
6748 if (NULL == pMsg) {
6749 sms_log(pMac, LOGE, "in %s msg ptr is NULL", __func__);
6750 return CDF_STATUS_E_FAILURE;
6751 }
6752
6753 if (pMac->pnoOffload) {
6754 /* Call Preferred Network Found Indication callback routine. */
6755 if (pMac->sme.pref_netw_found_cb != NULL) {
6756 pMac->sme.pref_netw_found_cb(pMac->sme.
6757 preferred_network_found_ind_cb_ctx,
6758 pPrefNetworkFoundInd);
6759 }
6760 return status;
6761 }
6762
6763 if (pPrefNetworkFoundInd->ssId.length > 0) {
6764 ssIdLength = CSR_MIN(SIR_MAC_MAX_SSID_LENGTH,
6765 pPrefNetworkFoundInd->ssId.length);
6766 cdf_mem_copy(dumpSsId, pPrefNetworkFoundInd->ssId.ssId,
6767 ssIdLength);
6768 dumpSsId[ssIdLength] = 0;
6769 sms_log(pMac, LOG2, "%s:SSID=%s frame length %d",
6770 __func__, dumpSsId, pPrefNetworkFoundInd->frameLength);
6771
6772 /* Flush scan results, So as to avoid indication/updation of
6773 * stale entries, which may not have aged out during APPS collapse
6774 */
6775 sme_scan_flush_result(hHal);
6776
6777 /* Save the frame to scan result */
6778 if (pPrefNetworkFoundInd->mesgLen >
6779 sizeof(tSirPrefNetworkFoundInd)) {
6780 /* we may have a frame */
6781 status = csr_scan_save_preferred_network_found(pMac,
6782 pPrefNetworkFoundInd);
6783 if (!CDF_IS_STATUS_SUCCESS(status)) {
6784 sms_log(pMac, LOGE,
6785 FL(" fail to save preferred network"));
6786 }
6787 } else {
6788 sms_log(pMac, LOGE,
6789 FL(" not enough data length %d needed %zu"),
6790 pPrefNetworkFoundInd->mesgLen,
6791 sizeof(tSirPrefNetworkFoundInd));
6792 }
6793
6794 /* Call Preferred Netowrk Found Indication callback routine. */
6795 if (CDF_IS_STATUS_SUCCESS(status)
6796 && (pMac->sme.pref_netw_found_cb != NULL)) {
6797 pMac->sme.pref_netw_found_cb(pMac->sme.
6798 preferred_network_found_ind_cb_ctx,
6799 pPrefNetworkFoundInd);
6800 }
6801 } else {
6802 sms_log(pMac, LOGE, "%s: callback failed - SSID is NULL",
6803 __func__);
6804 status = CDF_STATUS_E_FAILURE;
6805 }
6806
6807 return status;
6808}
6809
6810#endif /* FEATURE_WLAN_SCAN_PNO */
6811
6812CDF_STATUS sme_get_cfg_valid_channels(tHalHandle hHal, uint8_t *aValidChannels,
6813 uint32_t *len)
6814{
6815 CDF_STATUS status = CDF_STATUS_E_FAILURE;
6816 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
6817
6818 status = sme_acquire_global_lock(&pMac->sme);
6819 if (CDF_IS_STATUS_SUCCESS(status)) {
6820 status = csr_get_cfg_valid_channels(pMac, aValidChannels, len);
6821 sme_release_global_lock(&pMac->sme);
6822 }
6823
6824 return status;
6825}
6826
6827/* ---------------------------------------------------------------------------
6828
6829 \fn sme_handle_change_country_code
6830
6831 \brief Change Country code, Reg Domain and channel list
6832
6833 \details Country Code Priority
6834 If Supplicant country code is priority than 11d is disabled.
6835 If 11D is enabled, we update the country code after every scan.
6836 Hence when Supplicant country code is priority, we don't need 11D info.
6837 Country code from Supplicant is set as current courtry code.
6838 User can send reset command XX (instead of country code) to reset the
6839 country code to default values.
6840 If 11D is priority,
6841 Than Supplicant country code code is set to default code. But 11D code is set as current country code
6842
6843 \param pMac - The handle returned by mac_open.
6844 \param pMsgBuf - MSG Buffer
6845
6846 \return CDF_STATUS
6847
6848 -------------------------------------------------------------------------------*/
6849CDF_STATUS sme_handle_change_country_code(tpAniSirGlobal pMac, void *pMsgBuf)
6850{
6851 CDF_STATUS status = CDF_STATUS_SUCCESS;
6852 tAniChangeCountryCodeReq *pMsg;
6853 v_REGDOMAIN_t domainIdIoctl;
6854 CDF_STATUS cdf_status = CDF_STATUS_SUCCESS;
6855 static country_code_t default_country;
6856 pMsg = (tAniChangeCountryCodeReq *) pMsgBuf;
6857
6858 /*
6859 * if the reset Supplicant country code command is triggered,
6860 * enable 11D, reset the country code and return
6861 */
6862 if (true ==
6863 cdf_mem_compare(pMsg->countryCode, SME_INVALID_COUNTRY_CODE, 2)) {
6864 pMac->roam.configParam.Is11dSupportEnabled =
6865 pMac->roam.configParam.Is11dSupportEnabledOriginal;
6866
6867 cdf_status = cds_read_default_country(default_country);
6868
6869 /* read the country code and use it */
6870 if (CDF_IS_STATUS_SUCCESS(cdf_status)) {
6871 cdf_mem_copy(pMsg->countryCode,
6872 default_country,
6873 WNI_CFG_COUNTRY_CODE_LEN);
6874 } else {
6875 status = CDF_STATUS_E_FAILURE;
6876 return status;
6877 }
6878 /*
6879 * Update the 11d country to default country so that when
6880 * callback is received for this default country, driver will
6881 * not disable the 11d taking it as valid country by user.
6882 */
6883 sms_log(pMac, LOG1,
6884 FL("Set default country code (%c%c) as invalid country received"),
6885 pMsg->countryCode[0], pMsg->countryCode[1]);
6886 cdf_mem_copy(pMac->scan.countryCode11d,
6887 pMsg->countryCode,
6888 WNI_CFG_COUNTRY_CODE_LEN);
6889 } else {
6890 /* if Supplicant country code has priority, disable 11d */
6891 if (pMac->roam.configParam.fSupplicantCountryCodeHasPriority &&
6892 pMsg->countryFromUserSpace) {
6893 pMac->roam.configParam.Is11dSupportEnabled = false;
6894 }
6895 }
6896
6897 if (pMac->roam.configParam.Is11dSupportEnabled)
6898 return CDF_STATUS_SUCCESS;
6899
6900 /* Set Current Country code and Current Regulatory domain */
6901 status = csr_set_country_code(pMac, pMsg->countryCode);
6902 if (CDF_STATUS_SUCCESS != status) {
6903 /* Supplicant country code failed. So give 11D priority */
6904 pMac->roam.configParam.Is11dSupportEnabled =
6905 pMac->roam.configParam.Is11dSupportEnabledOriginal;
6906 sms_log(pMac, LOGE, "Set Country Code Fail %d", status);
6907 return status;
6908 }
6909
6910 /* overwrite the defualt country code */
6911 cdf_mem_copy(pMac->scan.countryCodeDefault,
6912 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
6913
6914 /* Get Domain ID from country code */
6915 status = csr_get_regulatory_domain_for_country(pMac,
6916 pMac->scan.countryCodeCurrent,
6917 (v_REGDOMAIN_t *) &
6918 domainIdIoctl, COUNTRY_QUERY);
6919 if (status != CDF_STATUS_SUCCESS) {
6920 sms_log(pMac, LOGE, FL(" fail to get regId %d"), domainIdIoctl);
6921 return status;
6922 } else if (REGDOMAIN_WORLD == domainIdIoctl) {
6923 /* Supplicant country code is invalid, so we are on world mode now. So
6924 give 11D chance to update */
6925 pMac->roam.configParam.Is11dSupportEnabled =
6926 pMac->roam.configParam.Is11dSupportEnabledOriginal;
6927 sms_log(pMac, LOG1, FL("Country Code unrecognized by driver"));
6928 }
6929
6930 status = wma_set_reg_domain(pMac, domainIdIoctl);
6931
6932 if (status != CDF_STATUS_SUCCESS) {
6933 sms_log(pMac, LOGE, FL(" fail to set regId %d"), domainIdIoctl);
6934 return status;
6935 } else {
6936 /* if 11d has priority, clear currentCountryBssid & countryCode11d to get */
6937 /* set again if we find AP with 11d info during scan */
6938 if (!pMac->roam.configParam.fSupplicantCountryCodeHasPriority) {
6939 sms_log(pMac, LOGW,
6940 FL
6941 ("Clearing currentCountryBssid, countryCode11d"));
6942 cdf_mem_zero(&pMac->scan.currentCountryBssid,
6943 sizeof(struct cdf_mac_addr));
6944 cdf_mem_zero(pMac->scan.countryCode11d,
6945 sizeof(pMac->scan.countryCode11d));
6946 }
6947 }
6948
6949 if (pMsg->changeCCCallback) {
6950 ((tSmeChangeCountryCallback) (pMsg->changeCCCallback))((void *)
6951 pMsg->
6952 pDevContext);
6953 }
6954
6955 return CDF_STATUS_SUCCESS;
6956}
6957
6958/**
6959 * sme_handle_change_country_code_by_user() - handles country ch req
6960 * @mac_ctx: mac global context
6961 * @msg: request msg packet
6962 *
6963 * If Supplicant country code is priority than 11d is disabled.
6964 * If 11D is enabled, we update the country code after every scan.
6965 * Hence when Supplicant country code is priority, we don't need 11D info.
6966 * Country code from Supplicant is set as current country code.
6967 *
6968 * Return: status of operation
6969 */
6970CDF_STATUS
6971sme_handle_change_country_code_by_user(tpAniSirGlobal mac_ctx,
6972 tAniGenericChangeCountryCodeReq *msg)
6973{
6974 CDF_STATUS status = CDF_STATUS_SUCCESS;
6975 v_REGDOMAIN_t reg_domain_id;
6976 bool is_11d_country = false;
6977 bool supplicant_priority =
6978 mac_ctx->roam.configParam.fSupplicantCountryCodeHasPriority;
6979
6980 sms_log(mac_ctx, LOG1, FL(" called"));
6981 reg_domain_id = (v_REGDOMAIN_t) msg->domain_index;
6982 if (memcmp(msg->countryCode, mac_ctx->scan.countryCode11d,
6983 CDS_COUNTRY_CODE_LEN) == 0) {
6984 is_11d_country = true;
6985 }
6986 /* Set the country code given by userspace when 11dOriginal is false
6987 * when 11doriginal is True,is_11d_country =0 and
6988 * fSupplicantCountryCodeHasPriority = 0, then revert the country code,
6989 * and return failure
6990 */
6991 if (mac_ctx->roam.configParam.Is11dSupportEnabledOriginal == true
6992 && !is_11d_country && !supplicant_priority) {
6993 sms_log(mac_ctx, LOGW,
6994 FL("Incorrect country req, nullify this"));
6995
6996 /* we have got a request for a country that should not have been
6997 * added since the STA is associated; nullify this request. If
6998 * both countryCode11d[0] and countryCode11d[1] are zero, revert
6999 * it to World domain to avoid from causing cfg80211 call trace.
7000 */
7001 if ((mac_ctx->scan.countryCode11d[0] == 0)
7002 && (mac_ctx->scan.countryCode11d[1] == 0))
7003 status = csr_get_regulatory_domain_for_country(mac_ctx,
7004 "00", (v_REGDOMAIN_t *) &reg_domain_id,
7005 COUNTRY_IE);
7006 else
7007 status = csr_get_regulatory_domain_for_country(mac_ctx,
7008 mac_ctx->scan.countryCode11d,
7009 (v_REGDOMAIN_t *) &reg_domain_id,
7010 COUNTRY_IE);
7011
7012 return CDF_STATUS_E_FAILURE;
7013 }
7014 /* if Supplicant country code has priority, disable 11d */
7015 if (!is_11d_country && supplicant_priority)
7016 mac_ctx->roam.configParam.Is11dSupportEnabled = false;
7017 cdf_mem_copy(mac_ctx->scan.countryCodeCurrent, msg->countryCode,
7018 WNI_CFG_COUNTRY_CODE_LEN);
7019 status = wma_set_reg_domain(mac_ctx, reg_domain_id);
7020 if (false == is_11d_country) {
7021 /* overwrite the defualt country code */
7022 cdf_mem_copy(mac_ctx->scan.countryCodeDefault,
7023 mac_ctx->scan.countryCodeCurrent,
7024 WNI_CFG_COUNTRY_CODE_LEN);
7025 /* set to default domain ID */
7026 mac_ctx->scan.domainIdDefault = mac_ctx->scan.domainIdCurrent;
7027 }
7028 if (status != CDF_STATUS_SUCCESS) {
7029 sms_log(mac_ctx, LOGE, FL("fail to set regId %d"),
7030 reg_domain_id);
7031 return status;
7032 } else {
7033 /* if 11d has priority, clear currentCountryBssid &
7034 * countryCode11d to get set again if we find AP with 11d info
7035 * during scan
7036 */
7037 if (!supplicant_priority && (false == is_11d_country)) {
7038 sms_log(mac_ctx, LOGW,
7039 FL("Clearing currentCountryBssid, countryCode11d"));
7040 cdf_mem_zero(&mac_ctx->scan.currentCountryBssid,
7041 sizeof(struct cdf_mac_addr));
7042 cdf_mem_zero(mac_ctx->scan.countryCode11d,
7043 sizeof(mac_ctx->scan.countryCode11d));
7044 }
7045 }
7046 /* get the channels based on new cc */
7047 status = csr_get_channel_and_power_list(mac_ctx);
7048
7049 if (status != CDF_STATUS_SUCCESS) {
7050 sms_log(mac_ctx, LOGE, FL("fail to get Channels"));
7051 return status;
7052 }
7053 /* reset info based on new cc, and we are done */
7054 csr_apply_channel_power_info_wrapper(mac_ctx);
7055
7056 /* Country code Changed, Purge Only scan result
7057 * which does not have channel number belong to 11d
7058 * channel list
7059 */
7060 csr_scan_filter_results(mac_ctx);
7061 /* Do active scans after the country is set by User hints or
7062 * Country IE
7063 */
7064 mac_ctx->scan.curScanType = eSIR_ACTIVE_SCAN;
7065 sme_disconnect_connected_sessions(mac_ctx);
7066 sms_log(mac_ctx, LOG1, FL(" returned"));
7067 return CDF_STATUS_SUCCESS;
7068}
7069
7070/* ---------------------------------------------------------------------------
7071
7072 \fn sme_handle_change_country_code_by_core
7073
7074 \brief Update Country code in the driver if set by kernel as world
7075
7076 If 11D is enabled, we update the country code after every scan & notify kernel.
7077 This is to make sure kernel & driver are in sync in case of CC found in
7078 driver but not in kernel database
7079
7080 \param pMac - The handle returned by mac_open.
7081 \param pMsg - Carrying new CC set in kernel
7082
7083 \return CDF_STATUS
7084
7085 -------------------------------------------------------------------------------*/
7086CDF_STATUS sme_handle_change_country_code_by_core(tpAniSirGlobal pMac,
7087 tAniGenericChangeCountryCodeReq *
7088 pMsg)
7089{
7090 CDF_STATUS status;
7091
7092 sms_log(pMac, LOG1, FL(" called"));
7093
7094 /* this is to make sure kernel & driver are in sync in case of CC found in */
7095 /* driver but not in kernel database */
7096 if (('0' == pMsg->countryCode[0]) && ('0' == pMsg->countryCode[1])) {
7097 sms_log(pMac, LOGW,
7098 FL
7099 ("Setting countryCode11d & countryCodeCurrent to world CC"));
7100 cdf_mem_copy(pMac->scan.countryCode11d, pMsg->countryCode,
7101 WNI_CFG_COUNTRY_CODE_LEN);
7102 cdf_mem_copy(pMac->scan.countryCodeCurrent, pMsg->countryCode,
7103 WNI_CFG_COUNTRY_CODE_LEN);
7104 }
7105
7106 status = wma_set_reg_domain(pMac, REGDOMAIN_WORLD);
7107
7108 if (status != CDF_STATUS_SUCCESS) {
7109 sms_log(pMac, LOGE, FL(" fail to set regId"));
7110 return status;
7111 } else {
7112 status = csr_get_channel_and_power_list(pMac);
7113 if (status != CDF_STATUS_SUCCESS) {
7114 sms_log(pMac, LOGE, FL(" fail to get Channels "));
7115 } else {
7116 csr_apply_channel_and_power_list(pMac);
7117 }
7118 }
7119 /* Country code Changed, Purge Only scan result
7120 * which does not have channel number belong to 11d
7121 * channel list
7122 */
7123 csr_scan_filter_results(pMac);
7124 sms_log(pMac, LOG1, FL(" returned"));
7125 return CDF_STATUS_SUCCESS;
7126}
7127
7128static bool
7129sme_search_in_base_ch_lst(tpAniSirGlobal mac_ctx, uint8_t curr_ch)
7130{
7131 uint8_t i;
7132 tCsrChannel *ch_lst_info;
7133 ch_lst_info = &mac_ctx->scan.base_channels;
7134 for (i = 0; i < ch_lst_info->numChannels; i++) {
7135 if (ch_lst_info->channelList[i] == curr_ch)
7136 return true;
7137 }
7138
7139 ch_lst_info = &mac_ctx->scan.base40MHzChannels;
7140 for (i = 0; i < ch_lst_info->numChannels; i++) {
7141 if (ch_lst_info->channelList[i] == curr_ch)
7142 return true;
7143 }
7144 return false;
7145}
7146/**
7147 * sme_disconnect_connected_sessions() - Disconnect STA and P2P client session
7148 * if channel is not supported
7149 * @mac_ctx: mac global context
7150 *
7151 * If new country code does not support the channel on which STA/P2P client
7152 * is connetced, it sends the disconnect to the AP/P2P GO
7153 *
7154 * Return: void
7155 */
7156void sme_disconnect_connected_sessions(tpAniSirGlobal mac_ctx)
7157{
7158 uint8_t session_id, found = false;
7159 uint8_t curr_ch;
7160
7161 for (session_id = 0; session_id < CSR_ROAM_SESSION_MAX; session_id++) {
7162 if (!csr_is_session_client_and_connected(mac_ctx, session_id))
7163 continue;
7164 found = false;
7165 /* Session is connected.Check the channel */
7166 curr_ch = csr_get_infra_operation_channel(mac_ctx,
7167 session_id);
7168 sms_log(mac_ctx, LOGW,
7169 FL("Current Operating channel : %d, session :%d"),
7170 curr_ch, session_id);
7171 found = sme_search_in_base_ch_lst(mac_ctx, curr_ch);
7172 if (!found) {
7173 sms_log(mac_ctx, LOGW, FL("Disconnect Session :%d"),
7174 session_id);
7175 csr_roam_disconnect(mac_ctx, session_id,
7176 eCSR_DISCONNECT_REASON_UNSPECIFIED);
7177 }
7178 }
7179}
7180
7181/* ---------------------------------------------------------------------------
7182
7183 \fn sme_handle_generic_change_country_code
7184
7185 \brief Change Country code, Reg Domain and channel list
7186
7187 If Supplicant country code is priority than 11d is disabled.
7188 If 11D is enabled, we update the country code after every scan.
7189 Hence when Supplicant country code is priority, we don't need 11D info.
7190 Country code from kernel is set as current country code.
7191
7192 \param pMac - The handle returned by mac_open.
7193 \param pMsgBuf - message buffer
7194
7195 \return CDF_STATUS
7196
7197 -------------------------------------------------------------------------------*/
7198CDF_STATUS sme_handle_generic_change_country_code(tpAniSirGlobal pMac,
7199 void *pMsgBuf)
7200{
7201 tAniGenericChangeCountryCodeReq *pMsg;
7202 v_REGDOMAIN_t reg_domain_id;
7203
7204 sms_log(pMac, LOG1, FL(" called"));
7205 pMsg = (tAniGenericChangeCountryCodeReq *) pMsgBuf;
7206 reg_domain_id = (v_REGDOMAIN_t) pMsg->domain_index;
7207
7208 if (REGDOMAIN_COUNT == reg_domain_id) {
7209 sme_handle_change_country_code_by_core(pMac, pMsg);
7210 } else {
7211 sme_handle_change_country_code_by_user(pMac, pMsg);
7212 }
7213 sms_log(pMac, LOG1, FL(" returned"));
7214 return CDF_STATUS_SUCCESS;
7215}
7216
7217#ifdef WLAN_FEATURE_PACKET_FILTERING
7218CDF_STATUS sme_8023_multicast_list(tHalHandle hHal, uint8_t sessionId,
7219 tpSirRcvFltMcAddrList pMulticastAddrs)
7220{
7221 tpSirRcvFltMcAddrList request_buf;
7222 cds_msg_t msg;
7223 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
7224 tCsrRoamSession *pSession = NULL;
7225
7226 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_INFO, "%s: "
7227 "ulMulticastAddrCnt=%d, multicastAddr[0]=%p", __func__,
7228 pMulticastAddrs->ulMulticastAddrCnt,
7229 pMulticastAddrs->multicastAddr[0]);
7230
7231 /*
7232 *Find the connected Infra / P2P_client connected session
7233 */
7234 if (CSR_IS_SESSION_VALID(pMac, sessionId) &&
7235 csr_is_conn_state_infra(pMac, sessionId)) {
7236 pSession = CSR_GET_SESSION(pMac, sessionId);
7237 }
7238
7239 if (pSession == NULL) {
7240 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
7241 "%s: Unable to find " "the session Id: %d", __func__,
7242 sessionId);
7243 return CDF_STATUS_E_FAILURE;
7244 }
7245
7246 request_buf = cdf_mem_malloc(sizeof(tSirRcvFltMcAddrList));
7247 if (NULL == request_buf) {
7248 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
7249 "%s: Not able to "
7250 "allocate memory for 8023 Multicast List request",
7251 __func__);
7252 return CDF_STATUS_E_NOMEM;
7253 }
7254
7255 if (!csr_is_conn_state_connected_infra(pMac, sessionId)) {
7256 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
7257 "%s: Ignoring the "
7258 "indication as we are not connected", __func__);
7259 cdf_mem_free(request_buf);
7260 return CDF_STATUS_E_FAILURE;
7261 }
7262
7263 cdf_mem_copy(request_buf, pMulticastAddrs,
7264 sizeof(tSirRcvFltMcAddrList));
7265
7266 cdf_mem_copy(request_buf->selfMacAddr, pSession->selfMacAddr.bytes,
7267 sizeof(tSirMacAddr));
7268 cdf_mem_copy(request_buf->bssId, pSession->connectedProfile.bssid.bytes,
7269 sizeof(tSirMacAddr));
7270
7271 msg.type = WMA_8023_MULTICAST_LIST_REQ;
7272 msg.reserved = 0;
7273 msg.bodyptr = request_buf;
7274 if (CDF_STATUS_SUCCESS != cds_mq_post_message(CDF_MODULE_ID_WMA, &msg)) {
7275 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
7276 "%s: Not able to "
7277 "post WMA_8023_MULTICAST_LIST message to WMA",
7278 __func__);
7279 cdf_mem_free(request_buf);
7280 return CDF_STATUS_E_FAILURE;
7281 }
7282
7283 return CDF_STATUS_SUCCESS;
7284}
7285
7286CDF_STATUS sme_receive_filter_set_filter(tHalHandle hHal,
7287 tpSirRcvPktFilterCfgType pRcvPktFilterCfg,
7288 uint8_t sessionId)
7289{
7290 tpSirRcvPktFilterCfgType request_buf;
7291 int32_t allocSize;
7292 cds_msg_t msg;
7293 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
7294 tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
7295 uint8_t idx = 0;
7296
7297 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_INFO, "%s: filterType=%d, "
7298 "filterId = %d", __func__,
7299 pRcvPktFilterCfg->filterType, pRcvPktFilterCfg->filterId);
7300
7301 allocSize = sizeof(tSirRcvPktFilterCfgType);
7302
7303 request_buf = cdf_mem_malloc(allocSize);
7304
7305 if (NULL == request_buf) {
7306 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
7307 "%s: Not able to "
7308 "allocate memory for Receive Filter Set Filter request",
7309 __func__);
7310 return CDF_STATUS_E_NOMEM;
7311 }
7312
7313 if (NULL == pSession) {
7314 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
7315 "%s: Session Not found ", __func__);
7316 cdf_mem_free(request_buf);
7317 return CDF_STATUS_E_FAILURE;
7318 }
7319
7320 cdf_mem_copy(pRcvPktFilterCfg->selfMacAddr, pSession->selfMacAddr.bytes,
7321 sizeof(tSirMacAddr));
7322 cdf_mem_copy(pRcvPktFilterCfg->bssId,
7323 pSession->connectedProfile.bssid.bytes,
7324 sizeof(tSirMacAddr));
7325 cdf_mem_copy(request_buf, pRcvPktFilterCfg, allocSize);
7326
7327 msg.type = WMA_RECEIVE_FILTER_SET_FILTER_REQ;
7328 msg.reserved = 0;
7329 msg.bodyptr = request_buf;
7330
7331 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_INFO, "Pkt Flt Req : "
7332 "FT %d FID %d ",
7333 request_buf->filterType, request_buf->filterId);
7334
7335 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_INFO, "Pkt Flt Req : "
7336 "params %d CT %d",
7337 request_buf->numFieldParams, request_buf->coalesceTime);
7338
7339 for (idx = 0; idx < request_buf->numFieldParams; idx++) {
7340
7341 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_INFO,
7342 "Proto %d Comp Flag %d ",
7343 request_buf->paramsData[idx].protocolLayer,
7344 request_buf->paramsData[idx].cmpFlag);
7345
7346 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_INFO,
7347 "Data Offset %d Data Len %d",
7348 request_buf->paramsData[idx].dataOffset,
7349 request_buf->paramsData[idx].dataLength);
7350
7351 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_INFO,
7352 "CData: %d:%d:%d:%d:%d:%d",
7353 request_buf->paramsData[idx].compareData[0],
7354 request_buf->paramsData[idx].compareData[1],
7355 request_buf->paramsData[idx].compareData[2],
7356 request_buf->paramsData[idx].compareData[3],
7357 request_buf->paramsData[idx].compareData[4],
7358 request_buf->paramsData[idx].compareData[5]);
7359
7360 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_INFO,
7361 "MData: %d:%d:%d:%d:%d:%d",
7362 request_buf->paramsData[idx].dataMask[0],
7363 request_buf->paramsData[idx].dataMask[1],
7364 request_buf->paramsData[idx].dataMask[2],
7365 request_buf->paramsData[idx].dataMask[3],
7366 request_buf->paramsData[idx].dataMask[4],
7367 request_buf->paramsData[idx].dataMask[5]);
7368
7369 }
7370
7371 if (CDF_STATUS_SUCCESS != cds_mq_post_message(CDF_MODULE_ID_WMA, &msg)) {
7372 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
7373 "%s: Not able to post "
7374 "WMA_RECEIVE_FILTER_SET_FILTER message to WMA",
7375 __func__);
7376 cdf_mem_free(request_buf);
7377 return CDF_STATUS_E_FAILURE;
7378 }
7379
7380 return CDF_STATUS_SUCCESS;
7381}
7382
7383CDF_STATUS sme_receive_filter_clear_filter(tHalHandle hHal,
7384 tpSirRcvFltPktClearParam
7385 pRcvFltPktClearParam, uint8_t sessionId)
7386{
7387 tpSirRcvFltPktClearParam request_buf;
7388 cds_msg_t msg;
7389 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
7390 tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
7391
7392 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_INFO, "%s: filterId = %d",
7393 __func__, pRcvFltPktClearParam->filterId);
7394
7395 request_buf = cdf_mem_malloc(sizeof(tSirRcvFltPktClearParam));
7396 if (NULL == request_buf) {
7397 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
7398 "%s: Not able to allocate memory for Receive Filter "
7399 "Clear Filter request", __func__);
7400 return CDF_STATUS_E_NOMEM;
7401 }
7402 if (NULL == pSession) {
7403 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
7404 "%s: Session Not find ", __func__);
7405 cdf_mem_free(request_buf);
7406 return CDF_STATUS_E_FAILURE;
7407 }
7408
7409 cdf_mem_copy(pRcvFltPktClearParam->selfMacAddr,
7410 pSession->selfMacAddr.bytes,
7411 sizeof(tSirMacAddr));
7412 cdf_mem_copy(pRcvFltPktClearParam->bssId,
7413 pSession->connectedProfile.bssid.bytes, sizeof(tSirMacAddr));
7414
7415 cdf_mem_copy(request_buf, pRcvFltPktClearParam,
7416 sizeof(tSirRcvFltPktClearParam));
7417
7418 msg.type = WMA_RECEIVE_FILTER_CLEAR_FILTER_REQ;
7419 msg.reserved = 0;
7420 msg.bodyptr = request_buf;
7421 if (CDF_STATUS_SUCCESS != cds_mq_post_message(CDF_MODULE_ID_WMA, &msg)) {
7422 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
7423 "%s: Not able to post "
7424 "WMA_RECEIVE_FILTER_CLEAR_FILTER message to WMA",
7425 __func__);
7426 cdf_mem_free(request_buf);
7427 return CDF_STATUS_E_FAILURE;
7428 }
7429
7430 return CDF_STATUS_SUCCESS;
7431}
7432#endif /* WLAN_FEATURE_PACKET_FILTERING */
7433
7434/* ---------------------------------------------------------------------------
7435
7436 \fn sme_is_channel_valid
7437
7438 \brief To check if the channel is valid for currently established domain
7439 This is a synchronous API.
7440
7441 \param hHal - The handle returned by mac_open.
7442 \param channel - channel to verify
7443
7444 \return true/false, true if channel is valid
7445
7446 -------------------------------------------------------------------------------*/
7447bool sme_is_channel_valid(tHalHandle hHal, uint8_t channel)
7448{
7449 CDF_STATUS status = CDF_STATUS_E_FAILURE;
7450 bool valid = false;
7451 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
7452
7453 status = sme_acquire_global_lock(&pMac->sme);
7454 if (CDF_IS_STATUS_SUCCESS(status)) {
7455
7456 valid = csr_roam_is_channel_valid(pMac, channel);
7457
7458 sme_release_global_lock(&pMac->sme);
7459 }
7460
7461 return valid;
7462}
7463
7464/* ---------------------------------------------------------------------------
7465 \fn sme_set_freq_band
7466 \brief Used to set frequency band.
7467 \param hHal
7468 \param sessionId - Session Identifier
7469 \eBand band value to be configured
7470 \- return CDF_STATUS
7471 -------------------------------------------------------------------------*/
7472CDF_STATUS sme_set_freq_band(tHalHandle hHal, uint8_t sessionId, eCsrBand eBand)
7473{
7474 CDF_STATUS status = CDF_STATUS_E_FAILURE;
7475 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
7476
7477 status = sme_acquire_global_lock(&pMac->sme);
7478 if (CDF_IS_STATUS_SUCCESS(status)) {
7479 status = csr_set_band(hHal, sessionId, eBand);
7480 sme_release_global_lock(&pMac->sme);
7481 }
7482 return status;
7483}
7484
7485/* ---------------------------------------------------------------------------
7486 \fn sme_get_freq_band
7487 \brief Used to get the current band settings.
7488 \param hHal
7489 \pBand pointer to hold band value
7490 \- return CDF_STATUS
7491 -------------------------------------------------------------------------*/
7492CDF_STATUS sme_get_freq_band(tHalHandle hHal, eCsrBand *pBand)
7493{
7494 CDF_STATUS status = CDF_STATUS_E_FAILURE;
7495 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
7496
7497 status = sme_acquire_global_lock(&pMac->sme);
7498 if (CDF_IS_STATUS_SUCCESS(status)) {
7499 *pBand = csr_get_current_band(hHal);
7500 sme_release_global_lock(&pMac->sme);
7501 }
7502 return status;
7503}
7504
7505/* ---------------------------------------------------------------------------
7506 \fn sme_set_max_tx_power_per_band
7507
7508 \brief Set the Maximum Transmit Power specific to band dynamically.
7509 Note: this setting will not persist over reboots.
7510
7511 \param band
7512 \param power to set in dB
7513 \- return CDF_STATUS
7514
7515 ----------------------------------------------------------------------------*/
7516CDF_STATUS sme_set_max_tx_power_per_band(eCsrBand band, int8_t dB)
7517{
7518 cds_msg_t msg;
7519 tpMaxTxPowerPerBandParams pMaxTxPowerPerBandParams = NULL;
7520
7521 pMaxTxPowerPerBandParams =
7522 cdf_mem_malloc(sizeof(tMaxTxPowerPerBandParams));
7523 if (NULL == pMaxTxPowerPerBandParams) {
7524 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
7525 "%s:Not able to allocate memory for pMaxTxPowerPerBandParams",
7526 __func__);
7527 return CDF_STATUS_E_NOMEM;
7528 }
7529
7530 pMaxTxPowerPerBandParams->power = dB;
7531 pMaxTxPowerPerBandParams->bandInfo = band;
7532
7533 msg.type = WMA_SET_MAX_TX_POWER_PER_BAND_REQ;
7534 msg.reserved = 0;
7535 msg.bodyptr = pMaxTxPowerPerBandParams;
7536
7537 if (CDF_STATUS_SUCCESS != cds_mq_post_message(CDF_MODULE_ID_WMA, &msg)) {
7538 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
7539 "%s:Not able to post WMA_SET_MAX_TX_POWER_PER_BAND_REQ",
7540 __func__);
7541 cdf_mem_free(pMaxTxPowerPerBandParams);
7542 return CDF_STATUS_E_FAILURE;
7543 }
7544
7545 return CDF_STATUS_SUCCESS;
7546}
7547
7548/* ---------------------------------------------------------------------------
7549
7550 \fn sme_set_max_tx_power
7551
7552 \brief Set the Maximum Transmit Power dynamically. Note: this setting will
7553 not persist over reboots.
7554
7555 \param hHal
7556 \param pBssid BSSID to set the power cap for
7557 \param pBssid pSelfMacAddress self MAC Address
7558 \param pBssid power to set in dB
7559 \- return CDF_STATUS
7560
7561 -------------------------------------------------------------------------------*/
7562CDF_STATUS sme_set_max_tx_power(tHalHandle hHal, tSirMacAddr pBssid,
7563 tSirMacAddr pSelfMacAddress, int8_t dB)
7564{
7565 cds_msg_t msg;
7566 tpMaxTxPowerParams pMaxTxParams = NULL;
7567
7568 MTRACE(cdf_trace(CDF_MODULE_ID_SME,
7569 TRACE_CODE_SME_RX_HDD_SET_MAXTXPOW, NO_SESSION, 0));
7570 pMaxTxParams = cdf_mem_malloc(sizeof(tMaxTxPowerParams));
7571 if (NULL == pMaxTxParams) {
7572 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
7573 "%s: Not able to allocate memory for pMaxTxParams",
7574 __func__);
7575 return CDF_STATUS_E_NOMEM;
7576 }
7577
7578 cdf_mem_copy(pMaxTxParams->bssId, pBssid, CDF_MAC_ADDR_SIZE);
7579 cdf_mem_copy(pMaxTxParams->selfStaMacAddr, pSelfMacAddress,
7580 CDF_MAC_ADDR_SIZE);
7581 pMaxTxParams->power = dB;
7582
7583 msg.type = WMA_SET_MAX_TX_POWER_REQ;
7584 msg.reserved = 0;
7585 msg.bodyptr = pMaxTxParams;
7586
7587 if (CDF_STATUS_SUCCESS != cds_mq_post_message(CDF_MODULE_ID_WMA, &msg)) {
7588 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
7589 "%s: Not able to post WMA_SET_MAX_TX_POWER_REQ message to WMA",
7590 __func__);
7591 cdf_mem_free(pMaxTxParams);
7592 return CDF_STATUS_E_FAILURE;
7593 }
7594
7595 return CDF_STATUS_SUCCESS;
7596}
7597
7598/* ---------------------------------------------------------------------------
7599
7600 \fn sme_set_custom_mac_addr
7601
7602 \brief Set the customer Mac Address.
7603
7604 \param customMacAddr customer MAC Address
7605 \- return CDF_STATUS
7606
7607 ---------------------------------------------------------------------------*/
7608CDF_STATUS sme_set_custom_mac_addr(tSirMacAddr customMacAddr)
7609{
7610 cds_msg_t msg;
7611 tSirMacAddr *pBaseMacAddr;
7612
7613 pBaseMacAddr = cdf_mem_malloc(sizeof(tSirMacAddr));
7614 if (NULL == pBaseMacAddr) {
7615 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
7616 FL("Not able to allocate memory for pBaseMacAddr"));
7617 return CDF_STATUS_E_NOMEM;
7618 }
7619
7620 cdf_mem_copy(*pBaseMacAddr, customMacAddr, sizeof(tSirMacAddr));
7621
7622 msg.type = SIR_HAL_SET_BASE_MACADDR_IND;
7623 msg.reserved = 0;
7624 msg.bodyptr = pBaseMacAddr;
7625
7626 if (CDF_STATUS_SUCCESS != cds_mq_post_message(CDF_MODULE_ID_WMA, &msg)) {
7627 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
7628 FL
7629 ("Not able to post SIR_HAL_SET_BASE_MACADDR_IND message to WMA"));
7630 cdf_mem_free(pBaseMacAddr);
7631 return CDF_STATUS_E_FAILURE;
7632 }
7633
7634 return CDF_STATUS_SUCCESS;
7635}
7636
7637/* ----------------------------------------------------------------------------
7638 \fn sme_set_tx_power
7639 \brief Set Transmit Power dynamically.
7640 \param hHal
7641 \param sessionId Target Session ID
7642 \pBSSId BSSID
7643 \dev_mode dev_mode such as station, P2PGO, SAP
7644 \param dBm power to set
7645 \- return CDF_STATUS
7646 ---------------------------------------------------------------------------*/
7647CDF_STATUS sme_set_tx_power(tHalHandle hHal, uint8_t sessionId,
7648 tSirMacAddr pBSSId, tCDF_CON_MODE dev_mode, int dBm)
7649{
7650 cds_msg_t msg;
7651 tpMaxTxPowerParams pTxParams = NULL;
7652 int8_t power = (int8_t) dBm;
7653
7654 MTRACE(cdf_trace(CDF_MODULE_ID_SME,
7655 TRACE_CODE_SME_RX_HDD_SET_TXPOW, sessionId, 0));
7656
7657 /* make sure there is no overflow */
7658 if ((int)power != dBm) {
7659 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
7660 "%s: error, invalid power = %d", __func__, dBm);
7661 return CDF_STATUS_E_FAILURE;
7662 }
7663
7664 pTxParams = cdf_mem_malloc(sizeof(tMaxTxPowerParams));
7665 if (NULL == pTxParams) {
7666 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
7667 "%s: Not able to allocate memory for pTxParams",
7668 __func__);
7669 return CDF_STATUS_E_NOMEM;
7670 }
7671
7672 cdf_mem_copy(pTxParams->bssId, pBSSId, CDF_MAC_ADDR_SIZE);
7673 pTxParams->power = power; /* unit is dBm */
7674 pTxParams->dev_mode = dev_mode;
7675 msg.type = WMA_SET_TX_POWER_REQ;
7676 msg.reserved = 0;
7677 msg.bodyptr = pTxParams;
7678
7679 if (CDF_STATUS_SUCCESS != cds_mq_post_message(CDF_MODULE_ID_WMA, &msg)) {
7680 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
7681 "%s: failed to post WMA_SET_TX_POWER_REQ to WMA",
7682 __func__);
7683 cdf_mem_free(pTxParams);
7684 return CDF_STATUS_E_FAILURE;
7685 }
7686
7687 return CDF_STATUS_SUCCESS;
7688}
7689
7690/* ---------------------------------------------------------------------------
7691
7692 \fn sme_hide_ssid
7693
7694 \brief hide/show SSID dynamically. Note: this setting will
7695 not persist over reboots.
7696
7697 \param hHal
7698 \param sessionId
7699 \param ssidHidden 0 - Broadcast SSID, 1 - Disable broadcast SSID
7700 \- return CDF_STATUS
7701
7702 -------------------------------------------------------------------------------*/
7703CDF_STATUS sme_hide_ssid(tHalHandle hHal, uint8_t sessionId, uint8_t ssidHidden)
7704{
7705 CDF_STATUS status = CDF_STATUS_SUCCESS;
7706 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
7707 uint16_t len;
7708
7709 status = sme_acquire_global_lock(&pMac->sme);
7710 if (CDF_IS_STATUS_SUCCESS(status)) {
7711 tpSirUpdateParams pMsg;
7712 tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
7713
7714 if (!pSession) {
7715 sms_log(pMac, LOGE, FL(" session %d not found "),
7716 sessionId);
7717 sme_release_global_lock(&pMac->sme);
7718 return CDF_STATUS_E_FAILURE;
7719 }
7720
7721 if (!pSession->sessionActive)
7722 CDF_ASSERT(0);
7723
7724 /* Create the message and send to lim */
7725 len = sizeof(tSirUpdateParams);
7726 pMsg = cdf_mem_malloc(len);
7727 if (NULL == pMsg)
7728 status = CDF_STATUS_E_NOMEM;
7729 else {
7730 cdf_mem_set(pMsg, sizeof(tSirUpdateParams), 0);
7731 pMsg->messageType = eWNI_SME_HIDE_SSID_REQ;
7732 pMsg->length = len;
7733 /* Data starts from here */
7734 pMsg->sessionId = sessionId;
7735 pMsg->ssidHidden = ssidHidden;
7736 status = cds_send_mb_message_to_mac(pMsg);
7737 }
7738 sme_release_global_lock(&pMac->sme);
7739 }
7740 return status;
7741}
7742
7743/* ---------------------------------------------------------------------------
7744
7745 \fn sme_set_tm_level
7746 \brief Set Thermal Mitigation Level to RIVA
7747 \param hHal - The handle returned by mac_open.
7748 \param newTMLevel - new Thermal Mitigation Level
7749 \param tmMode - Thermal Mitigation handle mode, default 0
7750 \return CDF_STATUS
7751 ---------------------------------------------------------------------------*/
7752CDF_STATUS sme_set_tm_level(tHalHandle hHal, uint16_t newTMLevel, uint16_t tmMode)
7753{
7754 CDF_STATUS status = CDF_STATUS_SUCCESS;
7755 CDF_STATUS cdf_status = CDF_STATUS_SUCCESS;
7756 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
7757 cds_msg_t cds_message;
7758 tAniSetTmLevelReq *setTmLevelReq = NULL;
7759
7760 MTRACE(cdf_trace(CDF_MODULE_ID_SME,
7761 TRACE_CODE_SME_RX_HDD_SET_TMLEVEL, NO_SESSION, 0));
7762 status = sme_acquire_global_lock(&pMac->sme);
7763 if (CDF_IS_STATUS_SUCCESS(status)) {
7764 setTmLevelReq =
7765 (tAniSetTmLevelReq *)
7766 cdf_mem_malloc(sizeof(tAniSetTmLevelReq));
7767 if (NULL == setTmLevelReq) {
7768 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
7769 "%s: Not able to allocate memory for sme_set_tm_level",
7770 __func__);
7771 sme_release_global_lock(&pMac->sme);
7772 return CDF_STATUS_E_NOMEM;
7773 }
7774
7775 setTmLevelReq->tmMode = tmMode;
7776 setTmLevelReq->newTmLevel = newTMLevel;
7777
7778 /* serialize the req through MC thread */
7779 cds_message.bodyptr = setTmLevelReq;
7780 cds_message.type = WMA_SET_TM_LEVEL_REQ;
7781 cdf_status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message);
7782 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
7783 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
7784 "%s: Post Set TM Level MSG fail", __func__);
7785 cdf_mem_free(setTmLevelReq);
7786 status = CDF_STATUS_E_FAILURE;
7787 }
7788 sme_release_global_lock(&pMac->sme);
7789 }
7790 return status;
7791}
7792
7793/*---------------------------------------------------------------------------
7794
7795 \brief sme_feature_caps_exchange() - SME interface to exchange capabilities between
7796 Host and FW.
7797
7798 \param hHal - HAL handle for device
7799
7800 \return NONE
7801
7802 ---------------------------------------------------------------------------*/
7803void sme_feature_caps_exchange(tHalHandle hHal)
7804{
7805 MTRACE(cdf_trace
7806 (CDF_MODULE_ID_SME, TRACE_CODE_SME_RX_HDD_CAPS_EXCH, NO_SESSION,
7807 0));
7808}
7809
7810/*---------------------------------------------------------------------------
7811
7812 \brief sme_disable_feature_capablity() - SME interface to disable Active mode offload capablity
7813 in Host.
7814
7815 \param hHal - HAL handle for device
7816
7817 \return NONE
7818
7819 ---------------------------------------------------------------------------*/
7820void sme_disable_feature_capablity(uint8_t feature_index)
7821{
7822}
7823
7824/* ---------------------------------------------------------------------------
7825 \fn sme_reset_power_values_for5_g
7826 \brief Reset the power values for 5G band with default power values.
7827 \param hHal - HAL handle for device
7828 \- return NONE
7829 -------------------------------------------------------------------------*/
7830void sme_reset_power_values_for5_g(tHalHandle hHal)
7831{
7832 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
7833 MTRACE(cdf_trace(CDF_MODULE_ID_SME,
7834 TRACE_CODE_SME_RX_HDD_RESET_PW5G, NO_SESSION, 0));
7835 csr_save_channel_power_for_band(pMac, true);
7836 csr_apply_power2_current(pMac); /* Store the channel+power info in the global place: Cfg */
7837}
7838
7839#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
7840/* ---------------------------------------------------------------------------
7841 \fn sme_update_roam_prefer5_g_hz
7842 \brief enable/disable Roam prefer 5G runtime option
7843 This function is called through dynamic setConfig callback function
7844 to configure the Roam prefer 5G runtime option
7845 \param hHal - HAL handle for device
7846 \param nRoamPrefer5GHz Enable/Disable Roam prefer 5G runtime option
7847 \- return Success or failure
7848 -------------------------------------------------------------------------*/
7849
7850CDF_STATUS sme_update_roam_prefer5_g_hz(tHalHandle hHal, bool nRoamPrefer5GHz)
7851{
7852 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
7853 CDF_STATUS status = CDF_STATUS_SUCCESS;
7854
7855 MTRACE(cdf_trace(CDF_MODULE_ID_SME,
7856 TRACE_CODE_SME_RX_HDD_UPDATE_RP5G, NO_SESSION, 0));
7857 status = sme_acquire_global_lock(&pMac->sme);
7858 if (CDF_IS_STATUS_SUCCESS(status)) {
7859 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_INFO,
7860 "%s: gRoamPrefer5GHz is changed from %d to %d",
7861 __func__, pMac->roam.configParam.nRoamPrefer5GHz,
7862 nRoamPrefer5GHz);
7863 pMac->roam.configParam.nRoamPrefer5GHz = nRoamPrefer5GHz;
7864 sme_release_global_lock(&pMac->sme);
7865 }
7866
7867 return status;
7868}
7869
7870/* ---------------------------------------------------------------------------
7871 \fn sme_set_roam_intra_band
7872 \brief enable/disable Intra band roaming
7873 This function is called through dynamic setConfig callback function
7874 to configure the intra band roaming
7875 \param hHal - HAL handle for device
7876 \param nRoamIntraBand Enable/Disable Intra band roaming
7877 \- return Success or failure
7878 -------------------------------------------------------------------------*/
7879CDF_STATUS sme_set_roam_intra_band(tHalHandle hHal, const bool nRoamIntraBand)
7880{
7881 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
7882 CDF_STATUS status = CDF_STATUS_SUCCESS;
7883
7884 MTRACE(cdf_trace(CDF_MODULE_ID_SME,
7885 TRACE_CODE_SME_RX_HDD_SET_ROAMIBAND, NO_SESSION, 0));
7886 status = sme_acquire_global_lock(&pMac->sme);
7887 if (CDF_IS_STATUS_SUCCESS(status)) {
7888 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_INFO,
7889 "%s: gRoamIntraBand is changed from %d to %d",
7890 __func__, pMac->roam.configParam.nRoamIntraBand,
7891 nRoamIntraBand);
7892 pMac->roam.configParam.nRoamIntraBand = nRoamIntraBand;
7893 sme_release_global_lock(&pMac->sme);
7894 }
7895
7896 return status;
7897}
7898
7899/* ---------------------------------------------------------------------------
7900 \fn sme_update_roam_scan_n_probes
7901 \brief function to update roam scan N probes
7902 This function is called through dynamic setConfig callback function
7903 to update roam scan N probes
7904 \param hHal - HAL handle for device
7905 \param sessionId - Session Identifier
7906 \param nProbes number of probe requests to be sent out
7907 \- return Success or failure
7908 -------------------------------------------------------------------------*/
7909CDF_STATUS sme_update_roam_scan_n_probes(tHalHandle hHal, uint8_t sessionId,
7910 const uint8_t nProbes)
7911{
7912 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
7913 CDF_STATUS status = CDF_STATUS_SUCCESS;
7914
7915 MTRACE(cdf_trace(CDF_MODULE_ID_SME,
7916 TRACE_CODE_SME_RX_HDD_UPDATE_ROAM_SCAN_N_PROBES,
7917 NO_SESSION, 0));
7918 status = sme_acquire_global_lock(&pMac->sme);
7919 if (CDF_IS_STATUS_SUCCESS(status)) {
7920 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_INFO,
7921 "%s: gRoamScanNProbes is changed from %d to %d",
7922 __func__, pMac->roam.configParam.nProbes, nProbes);
7923 pMac->roam.configParam.nProbes = nProbes;
7924 sme_release_global_lock(&pMac->sme);
7925 }
7926 if (pMac->roam.configParam.isRoamOffloadScanEnabled) {
7927 csr_roam_offload_scan(pMac, sessionId,
7928 ROAM_SCAN_OFFLOAD_UPDATE_CFG,
7929 REASON_NPROBES_CHANGED);
7930 }
7931 return status;
7932}
7933
7934/* ---------------------------------------------------------------------------
7935 \fn sme_update_roam_scan_home_away_time
7936 \brief function to update roam scan Home away time
7937 This function is called through dynamic setConfig callback function
7938 to update roam scan home away time
7939 \param hHal - HAL handle for device
7940 \param sessionId - Session Identifier
7941 \param nRoamScanAwayTime Scan home away time
7942 \param bSendOffloadCmd If true then send offload command to firmware
7943 If false then command is not sent to firmware
7944 \- return Success or failure
7945 -------------------------------------------------------------------------*/
7946CDF_STATUS sme_update_roam_scan_home_away_time(tHalHandle hHal,
7947 uint8_t sessionId,
7948 const uint16_t nRoamScanHomeAwayTime,
7949 const bool bSendOffloadCmd)
7950{
7951 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
7952 CDF_STATUS status = CDF_STATUS_SUCCESS;
7953
7954 MTRACE(cdf_trace(CDF_MODULE_ID_SME,
7955 TRACE_CODE_SME_RX_HDD_UPDATE_ROAM_SCAN_HOME_AWAY_TIME,
7956 NO_SESSION, 0));
7957 status = sme_acquire_global_lock(&pMac->sme);
7958 if (CDF_IS_STATUS_SUCCESS(status)) {
7959 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_INFO,
7960 "%s: gRoamScanHomeAwayTime is changed from %d to %d",
7961 __func__,
7962 pMac->roam.configParam.nRoamScanHomeAwayTime,
7963 nRoamScanHomeAwayTime);
7964 pMac->roam.configParam.nRoamScanHomeAwayTime =
7965 nRoamScanHomeAwayTime;
7966 sme_release_global_lock(&pMac->sme);
7967 }
7968 if (pMac->roam.configParam.isRoamOffloadScanEnabled && bSendOffloadCmd) {
7969 csr_roam_offload_scan(pMac, sessionId,
7970 ROAM_SCAN_OFFLOAD_UPDATE_CFG,
7971 REASON_HOME_AWAY_TIME_CHANGED);
7972 }
7973 return status;
7974}
7975
7976/* ---------------------------------------------------------------------------
7977 \fn sme_get_roam_intra_band
7978 \brief get Intra band roaming
7979 \param hHal - HAL handle for device
7980 \- return Success or failure
7981 -------------------------------------------------------------------------*/
7982bool sme_get_roam_intra_band(tHalHandle hHal)
7983{
7984 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
7985 MTRACE(cdf_trace(CDF_MODULE_ID_SME,
7986 TRACE_CODE_SME_RX_HDD_GET_ROAMIBAND, NO_SESSION, 0));
7987 return pMac->roam.configParam.nRoamIntraBand;
7988}
7989
7990/* ---------------------------------------------------------------------------
7991 \fn sme_get_roam_scan_n_probes
7992 \brief get N Probes
7993 \param hHal - HAL handle for device
7994 \- return Success or failure
7995 -------------------------------------------------------------------------*/
7996uint8_t sme_get_roam_scan_n_probes(tHalHandle hHal)
7997{
7998 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
7999 return pMac->roam.configParam.nProbes;
8000}
8001
8002/* ---------------------------------------------------------------------------
8003 \fn sme_get_roam_scan_home_away_time
8004 \brief get Roam scan home away time
8005 \param hHal - HAL handle for device
8006 \- return Success or failure
8007 -------------------------------------------------------------------------*/
8008uint16_t sme_get_roam_scan_home_away_time(tHalHandle hHal)
8009{
8010 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
8011 return pMac->roam.configParam.nRoamScanHomeAwayTime;
8012}
8013
8014/* ---------------------------------------------------------------------------
8015 \fn sme_update_roam_rssi_diff
8016 \brief Update RoamRssiDiff
8017 This function is called through dynamic setConfig callback function
8018 to configure RoamRssiDiff
8019 Usage: adb shell iwpriv wlan0 setConfig RoamRssiDiff=[0 .. 125]
8020 \param hHal - HAL handle for device
8021 \param sessionId - Session Identifier
8022 \param RoamRssiDiff - minimum rssi difference between potential
8023 candidate and current AP.
8024 \- return Success or failure
8025 -------------------------------------------------------------------------*/
8026
8027CDF_STATUS sme_update_roam_rssi_diff(tHalHandle hHal, uint8_t sessionId,
8028 uint8_t RoamRssiDiff)
8029{
8030 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
8031 CDF_STATUS status = CDF_STATUS_SUCCESS;
8032
8033 status = sme_acquire_global_lock(&pMac->sme);
8034 if (CDF_IS_STATUS_SUCCESS(status)) {
8035 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_DEBUG,
8036 "LFR runtime successfully set roam rssi diff to %d - old value is %d - roam state is %s",
8037 RoamRssiDiff,
8038 pMac->roam.configParam.RoamRssiDiff,
8039 mac_trace_get_neighbour_roam_state(pMac->roam.
8040 neighborRoamInfo
8041 [sessionId].
8042 neighborRoamState));
8043 pMac->roam.configParam.RoamRssiDiff = RoamRssiDiff;
8044 sme_release_global_lock(&pMac->sme);
8045 }
8046 if (pMac->roam.configParam.isRoamOffloadScanEnabled) {
8047 csr_roam_offload_scan(pMac, sessionId,
8048 ROAM_SCAN_OFFLOAD_UPDATE_CFG,
8049 REASON_RSSI_DIFF_CHANGED);
8050 }
8051 return status;
8052}
8053
8054/*--------------------------------------------------------------------------
8055 \brief sme_update_fast_transition_enabled() - enable/disable Fast Transition
8056 support at runtime
8057 It is used at in the REG_DYNAMIC_VARIABLE macro definition of
8058 isFastTransitionEnabled.
8059 This is a synchronous call
8060 \param hHal - The handle returned by mac_open.
8061 \return CDF_STATUS_SUCCESS - SME update isFastTransitionEnabled config
8062 successfully.
8063 Other status means SME is failed to update isFastTransitionEnabled.
8064 \sa
8065 --------------------------------------------------------------------------*/
8066CDF_STATUS sme_update_fast_transition_enabled(tHalHandle hHal,
8067 bool isFastTransitionEnabled)
8068{
8069 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
8070 CDF_STATUS status = CDF_STATUS_SUCCESS;
8071
8072 MTRACE(cdf_trace(CDF_MODULE_ID_SME,
8073 TRACE_CODE_SME_RX_HDD_UPDATE_FTENABLED, NO_SESSION,
8074 0));
8075 status = sme_acquire_global_lock(&pMac->sme);
8076 if (CDF_IS_STATUS_SUCCESS(status)) {
8077 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_INFO,
8078 "%s: FastTransitionEnabled is changed from %d to %d",
8079 __func__,
8080 pMac->roam.configParam.isFastTransitionEnabled,
8081 isFastTransitionEnabled);
8082 pMac->roam.configParam.isFastTransitionEnabled =
8083 isFastTransitionEnabled;
8084 sme_release_global_lock(&pMac->sme);
8085 }
8086
8087 return status;
8088}
8089
8090/* ---------------------------------------------------------------------------
8091 \fn sme_update_wes_mode
8092 \brief Update WES Mode
8093 This function is called through dynamic setConfig callback function
8094 to configure isWESModeEnabled
8095 \param hHal - HAL handle for device
8096 \param isWESModeEnabled - WES mode
8097 \param sessionId - Session Identifier
8098 \return CDF_STATUS_SUCCESS - SME update isWESModeEnabled config successfully.
8099 Other status means SME is failed to update isWESModeEnabled.
8100 -------------------------------------------------------------------------*/
8101
8102CDF_STATUS sme_update_wes_mode(tHalHandle hHal, bool isWESModeEnabled,
8103 uint8_t sessionId)
8104{
8105 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
8106 CDF_STATUS status = CDF_STATUS_SUCCESS;
8107
8108 status = sme_acquire_global_lock(&pMac->sme);
8109 if (CDF_IS_STATUS_SUCCESS(status)) {
8110 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_DEBUG,
8111 "LFR runtime successfully set WES Mode to %d - old value is %d - roam state is %s",
8112 isWESModeEnabled,
8113 pMac->roam.configParam.isWESModeEnabled,
8114 mac_trace_get_neighbour_roam_state(pMac->roam.
8115 neighborRoamInfo
8116 [sessionId].
8117 neighborRoamState));
8118 pMac->roam.configParam.isWESModeEnabled = isWESModeEnabled;
8119 sme_release_global_lock(&pMac->sme);
8120 }
8121
8122 return status;
8123}
8124
8125/* ---------------------------------------------------------------------------
8126 \fn sme_set_roam_scan_control
8127 \brief Set roam scan control
8128 This function is called to set roam scan control
8129 if roam scan control is set to 0, roaming scan cache is cleared
8130 any value other than 0 is treated as invalid value
8131 \param hHal - HAL handle for device
8132 \param sessionId - Session Identifier
8133 \return CDF_STATUS_SUCCESS - SME update config successfully.
8134 Other status means SME failure to update
8135 -------------------------------------------------------------------------*/
8136CDF_STATUS sme_set_roam_scan_control(tHalHandle hHal, uint8_t sessionId,
8137 bool roamScanControl)
8138{
8139 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
8140 CDF_STATUS status = CDF_STATUS_SUCCESS;
8141
8142 MTRACE(cdf_trace(CDF_MODULE_ID_SME,
8143 TRACE_CODE_SME_RX_HDD_SET_SCANCTRL, NO_SESSION, 0));
8144 status = sme_acquire_global_lock(&pMac->sme);
8145 if (CDF_IS_STATUS_SUCCESS(status)) {
8146 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_DEBUG,
8147 "LFR runtime successfully set roam scan control to %d - old value is %d - roam state is %s",
8148 roamScanControl,
8149 pMac->roam.configParam.nRoamScanControl,
8150 mac_trace_get_neighbour_roam_state(pMac->roam.
8151 neighborRoamInfo
8152 [sessionId].
8153 neighborRoamState));
8154 pMac->roam.configParam.nRoamScanControl = roamScanControl;
8155 if (0 == roamScanControl) {
8156 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_DEBUG,
8157 "LFR runtime successfully cleared roam scan cache");
8158 csr_flush_cfg_bg_scan_roam_channel_list(pMac, sessionId);
8159 if (pMac->roam.configParam.isRoamOffloadScanEnabled) {
8160 csr_roam_offload_scan(pMac, sessionId,
8161 ROAM_SCAN_OFFLOAD_UPDATE_CFG,
8162 REASON_FLUSH_CHANNEL_LIST);
8163 }
8164 }
8165 sme_release_global_lock(&pMac->sme);
8166 }
8167 return status;
8168}
8169#endif /* (WLAN_FEATURE_VOWIFI_11R) || (FEATURE_WLAN_ESE) || (FEATURE_WLAN_LFR) */
8170
8171#ifdef FEATURE_WLAN_LFR
8172/*--------------------------------------------------------------------------
8173 \brief sme_update_is_fast_roam_ini_feature_enabled() - enable/disable LFR
8174 support at runtime
8175 It is used at in the REG_DYNAMIC_VARIABLE macro definition of
8176 isFastRoamIniFeatureEnabled.
8177 This is a synchronous call
8178 \param hHal - The handle returned by mac_open.
8179 \param sessionId - Session Identifier
8180 \return CDF_STATUS_SUCCESS - SME update isFastRoamIniFeatureEnabled config
8181 successfully.
8182 Other status means SME is failed to update isFastRoamIniFeatureEnabled.
8183 \sa
8184 --------------------------------------------------------------------------*/
8185CDF_STATUS sme_update_is_fast_roam_ini_feature_enabled
8186 (tHalHandle hHal,
8187 uint8_t sessionId, const bool isFastRoamIniFeatureEnabled) {
8188 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
8189
8190 if (pMac->roam.configParam.isFastRoamIniFeatureEnabled ==
8191 isFastRoamIniFeatureEnabled) {
8192 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_DEBUG,
8193 "%s: FastRoam is already enabled or disabled, nothing to do (returning) old(%d) new(%d)",
8194 __func__,
8195 pMac->roam.configParam.isFastRoamIniFeatureEnabled,
8196 isFastRoamIniFeatureEnabled);
8197 return CDF_STATUS_SUCCESS;
8198 }
8199
8200 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_DEBUG,
8201 "%s: FastRoamEnabled is changed from %d to %d", __func__,
8202 pMac->roam.configParam.isFastRoamIniFeatureEnabled,
8203 isFastRoamIniFeatureEnabled);
8204 pMac->roam.configParam.isFastRoamIniFeatureEnabled =
8205 isFastRoamIniFeatureEnabled;
8206 csr_neighbor_roam_update_fast_roaming_enabled(pMac, sessionId,
8207 isFastRoamIniFeatureEnabled);
8208
8209 return CDF_STATUS_SUCCESS;
8210}
8211
8212/*--------------------------------------------------------------------------
8213 \brief sme_update_is_mawc_ini_feature_enabled() -
8214 Enable/disable LFR MAWC support at runtime
8215 It is used at in the REG_DYNAMIC_VARIABLE macro definition of
8216 isMAWCIniFeatureEnabled.
8217 This is a synchronous call
8218 \param hHal - The handle returned by mac_open.
8219 \return CDF_STATUS_SUCCESS - SME update MAWCEnabled config successfully.
8220 Other status means SME is failed to update MAWCEnabled.
8221 \sa
8222 --------------------------------------------------------------------------*/
8223CDF_STATUS sme_update_is_mawc_ini_feature_enabled(tHalHandle hHal,
8224 const bool MAWCEnabled)
8225{
8226 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
8227 CDF_STATUS status = CDF_STATUS_SUCCESS;
8228
8229 status = sme_acquire_global_lock(&pMac->sme);
8230 if (CDF_IS_STATUS_SUCCESS(status)) {
8231 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_INFO,
8232 "%s: MAWCEnabled is changed from %d to %d", __func__,
8233 pMac->roam.configParam.MAWCEnabled, MAWCEnabled);
8234 pMac->roam.configParam.MAWCEnabled = MAWCEnabled;
8235 sme_release_global_lock(&pMac->sme);
8236 }
8237
8238 return status;
8239
8240}
8241
8242/*--------------------------------------------------------------------------
8243 \brief sme_stop_roaming() - Stop roaming for a given sessionId
8244 This is a synchronous call
8245 \param hHal - The handle returned by mac_open
8246 \param sessionId - Session Identifier
8247 \return CDF_STATUS_SUCCESS on success
8248 Other status on failure
8249 \sa
8250 --------------------------------------------------------------------------*/
8251CDF_STATUS sme_stop_roaming(tHalHandle hHal, uint8_t sessionId, uint8_t reason)
8252{
8253 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
8254 CDF_STATUS status = CDF_STATUS_SUCCESS;
8255
8256 status = sme_acquire_global_lock(&pMac->sme);
8257 if (CDF_IS_STATUS_SUCCESS(status)) {
8258 csr_roam_offload_scan(pMac, sessionId, ROAM_SCAN_OFFLOAD_STOP,
8259 reason);
8260 sme_release_global_lock(&pMac->sme);
8261 }
8262
8263 return status;
8264}
8265
8266/*--------------------------------------------------------------------------
8267 \brief sme_start_roaming() - Start roaming for a given sessionId
8268 This is a synchronous call
8269 \param hHal - The handle returned by mac_open
8270 \param sessionId - Session Identifier
8271 \return CDF_STATUS_SUCCESS on success
8272 Other status on failure
8273 \sa
8274 --------------------------------------------------------------------------*/
8275CDF_STATUS sme_start_roaming(tHalHandle hHal, uint8_t sessionId, uint8_t reason)
8276{
8277 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
8278 CDF_STATUS status = CDF_STATUS_SUCCESS;
8279
8280 status = sme_acquire_global_lock(&pMac->sme);
8281 if (CDF_IS_STATUS_SUCCESS(status)) {
8282 csr_roam_offload_scan(pMac, sessionId, ROAM_SCAN_OFFLOAD_START,
8283 reason);
8284 sme_release_global_lock(&pMac->sme);
8285 }
8286
8287 return status;
8288}
8289
8290/*--------------------------------------------------------------------------
8291 \brief sme_update_enable_fast_roam_in_concurrency() - enable/disable LFR if
8292 Concurrent session exists
8293 This is a synchronuous call
8294 \param hHal - The handle returned by mac_open.
8295 \return CDF_STATUS_SUCCESS
8296 Other status means SME is failed
8297 \sa
8298 --------------------------------------------------------------------------*/
8299
8300CDF_STATUS sme_update_enable_fast_roam_in_concurrency(tHalHandle hHal,
8301 bool
8302 bFastRoamInConIniFeatureEnabled)
8303{
8304
8305 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
8306 CDF_STATUS status = CDF_STATUS_SUCCESS;
8307
8308 status = sme_acquire_global_lock(&pMac->sme);
8309 if (CDF_IS_STATUS_SUCCESS(status)) {
8310 pMac->roam.configParam.bFastRoamInConIniFeatureEnabled =
8311 bFastRoamInConIniFeatureEnabled;
8312 if (0 == pMac->roam.configParam.isRoamOffloadScanEnabled) {
8313 pMac->roam.configParam.bFastRoamInConIniFeatureEnabled =
8314 0;
8315 }
8316 sme_release_global_lock(&pMac->sme);
8317 }
8318
8319 return status;
8320}
8321#endif /* FEATURE_WLAN_LFR */
8322
8323#ifdef FEATURE_WLAN_ESE
8324/*--------------------------------------------------------------------------
8325 \brief sme_update_is_ese_feature_enabled() - enable/disable ESE support at runtime
8326 It is used at in the REG_DYNAMIC_VARIABLE macro definition of
8327 isEseIniFeatureEnabled.
8328 This is a synchronous call
8329 \param hHal - The handle returned by mac_open.
8330 \param sessionId - Session Identifier
8331 \param isEseIniFeatureEnabled - flag to enable/disable
8332 \return CDF_STATUS_SUCCESS - SME update isEseIniFeatureEnabled config
8333 successfully.
8334 Other status means SME is failed to update isEseIniFeatureEnabled.
8335 \sa
8336 --------------------------------------------------------------------------*/
8337CDF_STATUS sme_update_is_ese_feature_enabled
8338 (tHalHandle hHal, uint8_t sessionId, const bool isEseIniFeatureEnabled) {
8339 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
8340
8341 if (pMac->roam.configParam.isEseIniFeatureEnabled ==
8342 isEseIniFeatureEnabled) {
8343 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_INFO,
8344 "%s: ESE Mode is already enabled or disabled, nothing to do (returning) old(%d) new(%d)",
8345 __func__,
8346 pMac->roam.configParam.isEseIniFeatureEnabled,
8347 isEseIniFeatureEnabled);
8348 return CDF_STATUS_SUCCESS;
8349 }
8350
8351 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_INFO,
8352 "%s: EseEnabled is changed from %d to %d", __func__,
8353 pMac->roam.configParam.isEseIniFeatureEnabled,
8354 isEseIniFeatureEnabled);
8355 pMac->roam.configParam.isEseIniFeatureEnabled = isEseIniFeatureEnabled;
8356 csr_neighbor_roam_update_ese_mode_enabled(pMac, sessionId,
8357 isEseIniFeatureEnabled);
8358
8359 if (true == isEseIniFeatureEnabled) {
8360 sme_update_fast_transition_enabled(hHal, true);
8361 }
8362 if (pMac->roam.configParam.isRoamOffloadScanEnabled) {
8363 csr_roam_offload_scan(pMac, sessionId,
8364 ROAM_SCAN_OFFLOAD_UPDATE_CFG,
8365 REASON_ESE_INI_CFG_CHANGED);
8366 }
8367 return CDF_STATUS_SUCCESS;
8368}
8369#endif /* FEATURE_WLAN_ESE */
8370
8371/*--------------------------------------------------------------------------
8372 \brief sme_update_config_fw_rssi_monitoring() - enable/disable firmware RSSI
8373 Monitoring at runtime
8374 It is used at in the REG_DYNAMIC_VARIABLE macro definition of
8375 fEnableFwRssiMonitoring.
8376 This is a synchronous call
8377 \param hHal - The handle returned by mac_open.
8378 \return CDF_STATUS_SUCCESS - SME update fEnableFwRssiMonitoring.
8379 config successfully.
8380 Other status means SME is failed to update fEnableFwRssiMonitoring.
8381 \sa
8382 --------------------------------------------------------------------------*/
8383
8384CDF_STATUS sme_update_config_fw_rssi_monitoring(tHalHandle hHal,
8385 bool fEnableFwRssiMonitoring)
8386{
8387 CDF_STATUS cdf_ret_status = CDF_STATUS_SUCCESS;
8388
8389 if (sme_cfg_set_int (hHal, WNI_CFG_PS_ENABLE_RSSI_MONITOR,
8390 fEnableFwRssiMonitoring) == CDF_STATUS_E_FAILURE) {
8391 cdf_ret_status = CDF_STATUS_E_FAILURE;
8392 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
8393 "Could not pass on WNI_CFG_PS_RSSI_MONITOR to CFG");
8394 }
8395
8396 return cdf_ret_status;
8397}
8398
8399#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING
8400/* ---------------------------------------------------------------------------
8401 \fn sme_set_roam_opportunistic_scan_threshold_diff
8402 \brief Update Opportunistic Scan threshold diff
8403 This function is called through dynamic setConfig callback function
8404 to configure nOpportunisticThresholdDiff
8405 \param hHal - HAL handle for device
8406 \param sessionId - Session Identifier
8407 \param nOpportunisticThresholdDiff - Opportunistic Scan threshold diff
8408 \return CDF_STATUS_SUCCESS - SME update nOpportunisticThresholdDiff config
8409 successfully.
8410 else SME is failed to update nOpportunisticThresholdDiff.
8411 -------------------------------------------------------------------------*/
8412CDF_STATUS sme_set_roam_opportunistic_scan_threshold_diff(tHalHandle hHal,
8413 uint8_t sessionId,
8414 const uint8_t
8415 nOpportunisticThresholdDiff)
8416{
8417 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
8418 CDF_STATUS status = CDF_STATUS_SUCCESS;
8419
8420 status = sme_acquire_global_lock(&pMac->sme);
8421 if (CDF_IS_STATUS_SUCCESS(status)) {
8422 status = csr_neighbor_roam_set_opportunistic_scan_threshold_diff(pMac,
8423 sessionId,
8424 nOpportunisticThresholdDiff);
8425 if (CDF_IS_STATUS_SUCCESS(status)) {
8426 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_DEBUG,
8427 "LFR runtime successfully set "
8428 "opportunistic threshold diff to %d"
8429 " - old value is %d - roam state is %d",
8430 nOpportunisticThresholdDiff,
8431 pMac->roam.configParam.neighborRoamConfig.
8432 nOpportunisticThresholdDiff,
8433 pMac->roam.neighborRoamInfo[sessionId].
8434 neighborRoamState);
8435 pMac->roam.configParam.neighborRoamConfig.
8436 nOpportunisticThresholdDiff =
8437 nOpportunisticThresholdDiff;
8438 }
8439 sme_release_global_lock(&pMac->sme);
8440 }
8441 return status;
8442}
8443
8444/*--------------------------------------------------------------------------
8445 \fn sme_get_roam_opportunistic_scan_threshold_diff()
8446 \brief gets Opportunistic Scan threshold diff
8447 This is a synchronous call
8448 \param hHal - The handle returned by mac_open
8449 \return uint8_t - nOpportunisticThresholdDiff
8450 \sa
8451 --------------------------------------------------------------------------*/
8452uint8_t sme_get_roam_opportunistic_scan_threshold_diff(tHalHandle hHal)
8453{
8454 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
8455 return pMac->roam.configParam.neighborRoamConfig.
8456 nOpportunisticThresholdDiff;
8457}
8458
8459/* ---------------------------------------------------------------------------
8460 \fn sme_set_roam_rescan_rssi_diff
8461 \brief Update roam rescan rssi diff
8462 This function is called through dynamic setConfig callback function
8463 to configure nRoamRescanRssiDiff
8464 \param hHal - HAL handle for device
8465 \param sessionId - Session Identifier
8466 \param nRoamRescanRssiDiff - roam rescan rssi diff
8467 \return CDF_STATUS_SUCCESS - SME update nRoamRescanRssiDiff config
8468 successfully.
8469 else SME is failed to update nRoamRescanRssiDiff.
8470 -------------------------------------------------------------------------*/
8471CDF_STATUS sme_set_roam_rescan_rssi_diff(tHalHandle hHal,
8472 uint8_t sessionId,
8473 const uint8_t nRoamRescanRssiDiff)
8474{
8475 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
8476 CDF_STATUS status = CDF_STATUS_SUCCESS;
8477
8478 status = sme_acquire_global_lock(&pMac->sme);
8479 if (CDF_IS_STATUS_SUCCESS(status)) {
8480 status = csr_neighbor_roam_set_roam_rescan_rssi_diff(pMac, sessionId,
8481 nRoamRescanRssiDiff);
8482 if (CDF_IS_STATUS_SUCCESS(status)) {
8483 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_DEBUG,
8484 "LFR runtime successfully set "
8485 "opportunistic threshold diff to %d"
8486 " - old value is %d - roam state is %d",
8487 nRoamRescanRssiDiff,
8488 pMac->roam.configParam.neighborRoamConfig.
8489 nRoamRescanRssiDiff,
8490 pMac->roam.neighborRoamInfo[sessionId].
8491 neighborRoamState);
8492 pMac->roam.configParam.neighborRoamConfig.
8493 nRoamRescanRssiDiff = nRoamRescanRssiDiff;
8494 }
8495 sme_release_global_lock(&pMac->sme);
8496 }
8497 return status;
8498}
8499
8500/*--------------------------------------------------------------------------
8501 \fn sme_get_roam_rescan_rssi_diff
8502 \brief gets roam rescan rssi diff
8503 This is a synchronous call
8504 \param hHal - The handle returned by mac_open
8505 \return int8_t - nRoamRescanRssiDiff
8506 \sa
8507 --------------------------------------------------------------------------*/
8508uint8_t sme_get_roam_rescan_rssi_diff(tHalHandle hHal)
8509{
8510 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
8511 return pMac->roam.configParam.neighborRoamConfig.nRoamRescanRssiDiff;
8512}
8513
8514/* ---------------------------------------------------------------------------
8515 \fn sme_set_roam_bmiss_first_bcnt
8516 \brief Update Roam count for first beacon miss
8517 This function is called through dynamic setConfig callback function
8518 to configure nRoamBmissFirstBcnt
8519 \param hHal - HAL handle for device
8520 \param sessionId - Session Identifier
8521 \param nRoamBmissFirstBcnt - Roam first bmiss count
8522 \return CDF_STATUS_SUCCESS - SME update nRoamBmissFirstBcnt
8523 successfully.
8524 else SME is failed to update nRoamBmissFirstBcnt
8525 -------------------------------------------------------------------------*/
8526CDF_STATUS sme_set_roam_bmiss_first_bcnt(tHalHandle hHal,
8527 uint8_t sessionId,
8528 const uint8_t nRoamBmissFirstBcnt)
8529{
8530 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
8531 CDF_STATUS status = CDF_STATUS_SUCCESS;
8532
8533 status = sme_acquire_global_lock(&pMac->sme);
8534 if (CDF_IS_STATUS_SUCCESS(status)) {
8535 status = csr_neighbor_roam_set_roam_bmiss_first_bcnt(pMac, sessionId,
8536 nRoamBmissFirstBcnt);
8537 if (CDF_IS_STATUS_SUCCESS(status)) {
8538 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_DEBUG,
8539 "LFR runtime successfully set "
8540 "beacon miss first beacon count to %d"
8541 " - old value is %d - roam state is %d",
8542 nRoamBmissFirstBcnt,
8543 pMac->roam.configParam.neighborRoamConfig.
8544 nRoamBmissFirstBcnt,
8545 pMac->roam.neighborRoamInfo[sessionId].
8546 neighborRoamState);
8547 pMac->roam.configParam.neighborRoamConfig.
8548 nRoamBmissFirstBcnt = nRoamBmissFirstBcnt;
8549 }
8550 sme_release_global_lock(&pMac->sme);
8551 }
8552 return status;
8553}
8554
8555/* ---------------------------------------------------------------------------
8556 \fn sme_get_roam_bmiss_first_bcnt
8557 \brief get neighbor roam beacon miss first count
8558 \param hHal - The handle returned by mac_open.
8559 \return uint8_t - neighbor roam beacon miss first count
8560 -------------------------------------------------------------------------*/
8561uint8_t sme_get_roam_bmiss_first_bcnt(tHalHandle hHal)
8562{
8563 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
8564 return pMac->roam.configParam.neighborRoamConfig.nRoamBmissFirstBcnt;
8565}
8566
8567/* ---------------------------------------------------------------------------
8568 \fn sme_set_roam_bmiss_final_bcnt
8569 \brief Update Roam count for final beacon miss
8570 This function is called through dynamic setConfig callback function
8571 to configure nRoamBmissFinalBcnt
8572 \param hHal - HAL handle for device
8573 \param sessionId - Session Identifier
8574 \param nRoamBmissFinalBcnt - Roam final bmiss count
8575 \return CDF_STATUS_SUCCESS - SME update nRoamBmissFinalBcnt
8576 successfully.
8577 else SME is failed to update nRoamBmissFinalBcnt
8578 -------------------------------------------------------------------------*/
8579CDF_STATUS sme_set_roam_bmiss_final_bcnt(tHalHandle hHal,
8580 uint8_t sessionId,
8581 const uint8_t nRoamBmissFinalBcnt)
8582{
8583 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
8584 CDF_STATUS status = CDF_STATUS_SUCCESS;
8585
8586 status = sme_acquire_global_lock(&pMac->sme);
8587 if (CDF_IS_STATUS_SUCCESS(status)) {
8588 status = csr_neighbor_roam_set_roam_bmiss_final_bcnt(pMac, sessionId,
8589 nRoamBmissFinalBcnt);
8590 if (CDF_IS_STATUS_SUCCESS(status)) {
8591 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_DEBUG,
8592 "LFR runtime successfully set "
8593 "beacon miss final beacon count to %d"
8594 " - old value is %d - roam state is %d",
8595 nRoamBmissFinalBcnt,
8596 pMac->roam.configParam.neighborRoamConfig.
8597 nRoamBmissFinalBcnt,
8598 pMac->roam.neighborRoamInfo[sessionId].
8599 neighborRoamState);
8600 pMac->roam.configParam.neighborRoamConfig.
8601 nRoamBmissFinalBcnt = nRoamBmissFinalBcnt;
8602 }
8603 sme_release_global_lock(&pMac->sme);
8604 }
8605 return status;
8606}
8607
8608/*--------------------------------------------------------------------------
8609 \fn sme_get_roam_bmiss_final_bcnt
8610 \brief gets Roam count for final beacon miss
8611 This is a synchronous call
8612 \param hHal - The handle returned by mac_open
8613 \return uint8_t - nRoamBmissFinalBcnt
8614 \sa
8615 --------------------------------------------------------------------------*/
8616uint8_t sme_get_roam_bmiss_final_bcnt(tHalHandle hHal)
8617{
8618 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
8619 return pMac->roam.configParam.neighborRoamConfig.nRoamBmissFinalBcnt;
8620}
8621
8622/* ---------------------------------------------------------------------------
8623 \fn sme_set_roam_beacon_rssi_weight
8624 \brief Update Roam beacon rssi weight
8625 This function is called through dynamic setConfig callback function
8626 to configure nRoamBeaconRssiWeight
8627 \param hHal - HAL handle for device
8628 \param sessionId - Session Identifier
8629 \param nRoamBeaconRssiWeight - Roam beacon rssi weight
8630 \return CDF_STATUS_SUCCESS - SME update nRoamBeaconRssiWeight config
8631 successfully.
8632 else SME is failed to update nRoamBeaconRssiWeight
8633 -------------------------------------------------------------------------*/
8634CDF_STATUS sme_set_roam_beacon_rssi_weight(tHalHandle hHal,
8635 uint8_t sessionId,
8636 const uint8_t nRoamBeaconRssiWeight)
8637{
8638 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
8639 CDF_STATUS status = CDF_STATUS_SUCCESS;
8640
8641 status = sme_acquire_global_lock(&pMac->sme);
8642 if (CDF_IS_STATUS_SUCCESS(status)) {
8643 status = csr_neighbor_roam_set_roam_beacon_rssi_weight(pMac, sessionId,
8644 nRoamBeaconRssiWeight);
8645 if (CDF_IS_STATUS_SUCCESS(status)) {
8646 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_DEBUG,
8647 "LFR runtime successfully set "
8648 "beacon miss final beacon count to %d"
8649 " - old value is %d - roam state is %d",
8650 nRoamBeaconRssiWeight,
8651 pMac->roam.configParam.neighborRoamConfig.
8652 nRoamBeaconRssiWeight,
8653 pMac->roam.neighborRoamInfo[sessionId].
8654 neighborRoamState);
8655 pMac->roam.configParam.neighborRoamConfig.
8656 nRoamBeaconRssiWeight = nRoamBeaconRssiWeight;
8657 }
8658 sme_release_global_lock(&pMac->sme);
8659 }
8660 return status;
8661}
8662
8663/*--------------------------------------------------------------------------
8664 \fn sme_get_roam_beacon_rssi_weight
8665 \brief gets Roam beacon rssi weight
8666 This is a synchronous call
8667 \param hHal - The handle returned by mac_open
8668 \return uint8_t - nRoamBeaconRssiWeight
8669 \sa
8670 --------------------------------------------------------------------------*/
8671uint8_t sme_get_roam_beacon_rssi_weight(tHalHandle hHal)
8672{
8673 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
8674 return pMac->roam.configParam.neighborRoamConfig.nRoamBeaconRssiWeight;
8675}
8676
8677/*--------------------------------------------------------------------------
8678 \brief sme_set_neighbor_lookup_rssi_threshold() - update neighbor lookup
8679 rssi threshold
8680 This is a synchronous call
8681 \param hHal - The handle returned by mac_open.
8682 \param sessionId - Session Identifier
8683 \return CDF_STATUS_SUCCESS - SME update config successful.
8684 Other status means SME is failed to update
8685 \sa
8686 --------------------------------------------------------------------------*/
8687CDF_STATUS sme_set_neighbor_lookup_rssi_threshold
8688 (tHalHandle hHal, uint8_t sessionId, uint8_t neighborLookupRssiThreshold) {
8689 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
8690 CDF_STATUS status = CDF_STATUS_SUCCESS;
8691
8692 status = sme_acquire_global_lock(&pMac->sme);
8693 if (CDF_IS_STATUS_SUCCESS(status)) {
8694 status = csr_neighbor_roam_set_lookup_rssi_threshold(pMac, sessionId,
8695 neighborLookupRssiThreshold);
8696 if (CDF_IS_STATUS_SUCCESS(status)) {
8697 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_DEBUG,
8698 "LFR runtime successfully set Lookup threshold to %d - old value is %d - roam state is %s",
8699 neighborLookupRssiThreshold,
8700 pMac->roam.configParam.neighborRoamConfig.
8701 nNeighborLookupRssiThreshold,
8702 mac_trace_get_neighbour_roam_state(pMac->roam.
8703 neighborRoamInfo
8704 [sessionId].
8705 neighborRoamState));
8706 pMac->roam.configParam.neighborRoamConfig.
8707 nNeighborLookupRssiThreshold =
8708 neighborLookupRssiThreshold;
8709 }
8710 sme_release_global_lock(&pMac->sme);
8711 }
8712 return status;
8713}
8714
8715/*--------------------------------------------------------------------------
8716 \brief sme_set_delay_before_vdev_stop() - update delay before VDEV_STOP
8717 This is a synchronous call
8718 \param hal - The handle returned by macOpen.
8719 \param session_id - Session Identifier
8720 \param delay_before_vdev_stop - value to be set
8721 \return CDF_STATUS_SUCCESS - SME update config successful.
8722 Other status means SME is failed to update
8723 \sa
8724 --------------------------------------------------------------------------*/
8725CDF_STATUS sme_set_delay_before_vdev_stop(tHalHandle hal,
8726 uint8_t session_id,
8727 uint8_t delay_before_vdev_stop)
8728{
8729 tpAniSirGlobal pMac = PMAC_STRUCT(hal);
8730 CDF_STATUS status = CDF_STATUS_SUCCESS;
8731 status = sme_acquire_global_lock(&pMac->sme);
8732 if (CDF_IS_STATUS_SUCCESS(status)) {
8733 CDF_TRACE(CDF_MODULE_ID_SME,
8734 CDF_TRACE_LEVEL_DEBUG,
8735 FL("LFR param delay_before_vdev_stop changed from %d to %d"),
8736 pMac->roam.configParam.neighborRoamConfig.
8737 delay_before_vdev_stop,
8738 delay_before_vdev_stop);
8739 pMac->roam.neighborRoamInfo[session_id].cfgParams.
8740 delay_before_vdev_stop = delay_before_vdev_stop;
8741 pMac->roam.configParam.neighborRoamConfig.
8742 delay_before_vdev_stop = delay_before_vdev_stop;
8743 sme_release_global_lock(&pMac->sme);
8744 }
8745 return status;
8746}
8747
8748/*--------------------------------------------------------------------------
8749 \brief sme_get_neighbor_lookup_rssi_threshold() - get neighbor lookup
8750 rssi threshold
8751 This is a synchronous call
8752 \param hHal - The handle returned by mac_open.
8753 \return CDF_STATUS_SUCCESS - SME update config successful.
8754 Other status means SME is failed to update
8755 \sa
8756 --------------------------------------------------------------------------*/
8757uint8_t sme_get_neighbor_lookup_rssi_threshold(tHalHandle hHal)
8758{
8759 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
8760 return pMac->roam.configParam.neighborRoamConfig.
8761 nNeighborLookupRssiThreshold;
8762}
8763
8764/*--------------------------------------------------------------------------
8765 \brief sme_set_neighbor_scan_refresh_period() - set neighbor scan results
8766 refresh period
8767 This is a synchronous call
8768 \param hHal - The handle returned by mac_open.
8769 \param sessionId - Session Identifier
8770 \return CDF_STATUS_SUCCESS - SME update config successful.
8771 Other status means SME is failed to update
8772 \sa
8773 --------------------------------------------------------------------------*/
8774CDF_STATUS sme_set_neighbor_scan_refresh_period
8775 (tHalHandle hHal,
8776 uint8_t sessionId, uint16_t neighborScanResultsRefreshPeriod) {
8777 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
8778 CDF_STATUS status = CDF_STATUS_SUCCESS;
8779 tCsrNeighborRoamConfig *pNeighborRoamConfig = NULL;
8780 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = NULL;
8781
8782 status = sme_acquire_global_lock(&pMac->sme);
8783 if (CDF_IS_STATUS_SUCCESS(status)) {
8784 pNeighborRoamConfig =
8785 &pMac->roam.configParam.neighborRoamConfig;
8786 pNeighborRoamInfo = &pMac->roam.neighborRoamInfo[sessionId];
8787 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_DEBUG,
8788 "LFR runtime successfully set roam scan refresh period to %d- old value is %d - roam state is %s",
8789 neighborScanResultsRefreshPeriod,
8790 pMac->roam.configParam.neighborRoamConfig.
8791 nNeighborResultsRefreshPeriod,
8792 mac_trace_get_neighbour_roam_state(pMac->roam.
8793 neighborRoamInfo
8794 [sessionId].
8795 neighborRoamState));
8796 pNeighborRoamConfig->nNeighborResultsRefreshPeriod =
8797 neighborScanResultsRefreshPeriod;
8798 pNeighborRoamInfo->cfgParams.neighborResultsRefreshPeriod =
8799 neighborScanResultsRefreshPeriod;
8800
8801 sme_release_global_lock(&pMac->sme);
8802 }
8803 if (pMac->roam.configParam.isRoamOffloadScanEnabled) {
8804 csr_roam_offload_scan(pMac, sessionId,
8805 ROAM_SCAN_OFFLOAD_UPDATE_CFG,
8806 REASON_NEIGHBOR_SCAN_REFRESH_PERIOD_CHANGED);
8807 }
8808 return status;
8809}
8810
8811/*--------------------------------------------------------------------------
8812 \brief sme_update_roam_scan_offload_enabled() - enable/disable roam scan
8813 offload feaure
8814 It is used at in the REG_DYNAMIC_VARIABLE macro definition of
8815 gRoamScanOffloadEnabled.
8816 This is a synchronous call
8817 \param hHal - The handle returned by mac_open.
8818 \return CDF_STATUS_SUCCESS - SME update config successfully.
8819 Other status means SME is failed to update.
8820 \sa
8821 --------------------------------------------------------------------------*/
8822
8823CDF_STATUS sme_update_roam_scan_offload_enabled(tHalHandle hHal,
8824 bool nRoamScanOffloadEnabled)
8825{
8826 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
8827 CDF_STATUS status = CDF_STATUS_SUCCESS;
8828
8829 status = sme_acquire_global_lock(&pMac->sme);
8830 if (CDF_IS_STATUS_SUCCESS(status)) {
8831 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_DEBUG,
8832 FL
8833 ("gRoamScanOffloadEnabled is changed from %d to %d"),
8834 pMac->roam.configParam.isRoamOffloadScanEnabled,
8835 nRoamScanOffloadEnabled);
8836 pMac->roam.configParam.isRoamOffloadScanEnabled =
8837 nRoamScanOffloadEnabled;
8838 sme_release_global_lock(&pMac->sme);
8839 }
8840
8841 return status;
8842}
8843
8844/*--------------------------------------------------------------------------
8845 \brief sme_get_neighbor_scan_refresh_period() - get neighbor scan results
8846 refresh period
8847 This is a synchronous call
8848 \param hHal - The handle returned by mac_open.
8849 \return uint16_t - Neighbor scan results refresh period value
8850 \sa
8851 --------------------------------------------------------------------------*/
8852uint16_t sme_get_neighbor_scan_refresh_period(tHalHandle hHal)
8853{
8854 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
8855 return pMac->roam.configParam.neighborRoamConfig.
8856 nNeighborResultsRefreshPeriod;
8857}
8858
8859/*--------------------------------------------------------------------------
8860 \brief sme_get_empty_scan_refresh_period() - get empty scan refresh period
8861 This is a synchronuous call
8862 \param hHal - The handle returned by mac_open.
8863 \return CDF_STATUS_SUCCESS - SME update config successful.
8864 Other status means SME is failed to update
8865 \sa
8866 --------------------------------------------------------------------------*/
8867uint16_t sme_get_empty_scan_refresh_period(tHalHandle hHal)
8868{
8869 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
8870 return pMac->roam.configParam.neighborRoamConfig.
8871 nEmptyScanRefreshPeriod;
8872}
8873
8874/* ---------------------------------------------------------------------------
8875 \fn sme_update_empty_scan_refresh_period
8876 \brief Update nEmptyScanRefreshPeriod
8877 This function is called through dynamic setConfig callback function
8878 to configure nEmptyScanRefreshPeriod
8879 Usage: adb shell iwpriv wlan0 setConfig
8880 nEmptyScanRefreshPeriod=[0 .. 60]
8881 \param hHal - HAL handle for device
8882 \param sessionId - Session Identifier
8883 \param nEmptyScanRefreshPeriod - scan period following empty scan results.
8884 \- return Success or failure
8885 -------------------------------------------------------------------------*/
8886
8887CDF_STATUS sme_update_empty_scan_refresh_period(tHalHandle hHal, uint8_t sessionId,
8888 uint16_t nEmptyScanRefreshPeriod)
8889{
8890 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
8891 CDF_STATUS status = CDF_STATUS_SUCCESS;
8892 tCsrNeighborRoamConfig *pNeighborRoamConfig = NULL;
8893 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = NULL;
8894
8895 status = sme_acquire_global_lock(&pMac->sme);
8896 if (CDF_IS_STATUS_SUCCESS(status)) {
8897 pNeighborRoamConfig =
8898 &pMac->roam.configParam.neighborRoamConfig;
8899 pNeighborRoamInfo = &pMac->roam.neighborRoamInfo[sessionId];
8900 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_DEBUG,
8901 "LFR runtime successfully set roam scan period to %d -old value is %d - roam state is %s",
8902 nEmptyScanRefreshPeriod,
8903 pMac->roam.configParam.neighborRoamConfig.
8904 nEmptyScanRefreshPeriod,
8905 mac_trace_get_neighbour_roam_state(pMac->roam.
8906 neighborRoamInfo
8907 [sessionId].
8908 neighborRoamState));
8909 pNeighborRoamConfig->nEmptyScanRefreshPeriod =
8910 nEmptyScanRefreshPeriod;
8911 pNeighborRoamInfo->cfgParams.emptyScanRefreshPeriod =
8912 nEmptyScanRefreshPeriod;
8913 sme_release_global_lock(&pMac->sme);
8914 }
8915 if (pMac->roam.configParam.isRoamOffloadScanEnabled) {
8916 csr_roam_offload_scan(pMac, sessionId,
8917 ROAM_SCAN_OFFLOAD_UPDATE_CFG,
8918 REASON_EMPTY_SCAN_REF_PERIOD_CHANGED);
8919 }
8920 return status;
8921}
8922
8923/* ---------------------------------------------------------------------------
8924 \fn sme_set_neighbor_scan_min_chan_time
8925 \brief Update nNeighborScanMinChanTime
8926 This function is called through dynamic setConfig callback function
8927 to configure gNeighborScanChannelMinTime
8928 Usage: adb shell iwpriv wlan0 setConfig
8929 gNeighborScanChannelMinTime=[0 .. 60]
8930 \param hHal - HAL handle for device
8931 \param nNeighborScanMinChanTime - Channel minimum dwell time
8932 \param sessionId - Session Identifier
8933 \- return Success or failure
8934 -------------------------------------------------------------------------*/
8935CDF_STATUS sme_set_neighbor_scan_min_chan_time(tHalHandle hHal,
8936 const uint16_t
8937 nNeighborScanMinChanTime,
8938 uint8_t sessionId)
8939{
8940 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
8941 CDF_STATUS status = CDF_STATUS_SUCCESS;
8942
8943 status = sme_acquire_global_lock(&pMac->sme);
8944 if (CDF_IS_STATUS_SUCCESS(status)) {
8945 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_DEBUG,
8946 "LFR runtime successfully set channel min dwell time to %d - old value is %d - roam state is %s",
8947 nNeighborScanMinChanTime,
8948 pMac->roam.configParam.neighborRoamConfig.
8949 nNeighborScanMinChanTime,
8950 mac_trace_get_neighbour_roam_state(pMac->roam.
8951 neighborRoamInfo
8952 [sessionId].
8953 neighborRoamState));
8954
8955 pMac->roam.configParam.neighborRoamConfig.
8956 nNeighborScanMinChanTime = nNeighborScanMinChanTime;
8957 pMac->roam.neighborRoamInfo[sessionId].cfgParams.
8958 minChannelScanTime = nNeighborScanMinChanTime;
8959 sme_release_global_lock(&pMac->sme);
8960 }
8961
8962 return status;
8963}
8964
8965/* ---------------------------------------------------------------------------
8966 \fn sme_set_neighbor_scan_max_chan_time
8967 \brief Update nNeighborScanMaxChanTime
8968 This function is called through dynamic setConfig callback function
8969 to configure gNeighborScanChannelMaxTime
8970 Usage: adb shell iwpriv wlan0 setConfig
8971 gNeighborScanChannelMaxTime=[0 .. 60]
8972 \param hHal - HAL handle for device
8973 \param sessionId - Session Identifier
8974 \param nNeighborScanMinChanTime - Channel maximum dwell time
8975 \- return Success or failure
8976 -------------------------------------------------------------------------*/
8977CDF_STATUS sme_set_neighbor_scan_max_chan_time(tHalHandle hHal, uint8_t sessionId,
8978 const uint16_t
8979 nNeighborScanMaxChanTime)
8980{
8981 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
8982 CDF_STATUS status = CDF_STATUS_SUCCESS;
8983 tCsrNeighborRoamConfig *pNeighborRoamConfig = NULL;
8984 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = NULL;
8985
8986 status = sme_acquire_global_lock(&pMac->sme);
8987 if (CDF_IS_STATUS_SUCCESS(status)) {
8988 pNeighborRoamConfig =
8989 &pMac->roam.configParam.neighborRoamConfig;
8990 pNeighborRoamInfo = &pMac->roam.neighborRoamInfo[sessionId];
8991 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_DEBUG,
8992 "LFR runtime successfully set channel max dwell time to %d - old value is %d - roam state is %s",
8993 nNeighborScanMaxChanTime,
8994 pMac->roam.configParam.neighborRoamConfig.
8995 nNeighborScanMaxChanTime,
8996 mac_trace_get_neighbour_roam_state(pMac->roam.
8997 neighborRoamInfo
8998 [sessionId].
8999 neighborRoamState));
9000 pNeighborRoamConfig->nNeighborScanMaxChanTime =
9001 nNeighborScanMaxChanTime;
9002 pNeighborRoamInfo->cfgParams.maxChannelScanTime =
9003 nNeighborScanMaxChanTime;
9004 sme_release_global_lock(&pMac->sme);
9005 }
9006 if (pMac->roam.configParam.isRoamOffloadScanEnabled) {
9007 csr_roam_offload_scan(pMac, sessionId,
9008 ROAM_SCAN_OFFLOAD_UPDATE_CFG,
9009 REASON_SCAN_CH_TIME_CHANGED);
9010 }
9011
9012 return status;
9013}
9014
9015/* ---------------------------------------------------------------------------
9016 \fn sme_get_neighbor_scan_min_chan_time
9017 \brief get neighbor scan min channel time
9018 \param hHal - The handle returned by mac_open.
9019 \param sessionId - Session Identifier
9020 \return uint16_t - channel min time value
9021 -------------------------------------------------------------------------*/
9022uint16_t sme_get_neighbor_scan_min_chan_time(tHalHandle hHal, uint8_t sessionId)
9023{
9024 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
9025 return pMac->roam.neighborRoamInfo[sessionId].cfgParams.
9026 minChannelScanTime;
9027}
9028
9029/* ---------------------------------------------------------------------------
9030 \fn sme_get_neighbor_roam_state
9031 \brief get neighbor roam state
9032 \param hHal - The handle returned by mac_open.
9033 \param sessionId - Session Identifier
9034 \return uint32_t - neighbor roam state
9035 -------------------------------------------------------------------------*/
9036uint32_t sme_get_neighbor_roam_state(tHalHandle hHal, uint8_t sessionId)
9037{
9038 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
9039 return pMac->roam.neighborRoamInfo[sessionId].neighborRoamState;
9040}
9041
9042/* ---------------------------------------------------------------------------
9043 \fn sme_get_current_roam_state
9044 \brief get current roam state
9045 \param hHal - The handle returned by mac_open.
9046 \param sessionId - Session Identifier
9047 \return uint32_t - current roam state
9048 -------------------------------------------------------------------------*/
9049uint32_t sme_get_current_roam_state(tHalHandle hHal, uint8_t sessionId)
9050{
9051 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
9052 return pMac->roam.curState[sessionId];
9053}
9054
9055/* ---------------------------------------------------------------------------
9056 \fn sme_get_current_roam_sub_state
9057 \brief get neighbor roam sub state
9058 \param hHal - The handle returned by mac_open.
9059 \param sessionId - Session Identifier
9060 \return uint32_t - current roam sub state
9061 -------------------------------------------------------------------------*/
9062uint32_t sme_get_current_roam_sub_state(tHalHandle hHal, uint8_t sessionId)
9063{
9064 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
9065 return pMac->roam.curSubState[sessionId];
9066}
9067
9068/* ---------------------------------------------------------------------------
9069 \fn sme_get_lim_sme_state
9070 \brief get Lim Sme state
9071 \param hHal - The handle returned by mac_open.
9072 \return uint32_t - Lim Sme state
9073 -------------------------------------------------------------------------*/
9074uint32_t sme_get_lim_sme_state(tHalHandle hHal)
9075{
9076 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
9077 return pMac->lim.gLimSmeState;
9078}
9079
9080/* ---------------------------------------------------------------------------
9081 \fn sme_get_lim_mlm_state
9082 \brief get Lim Mlm state
9083 \param hHal - The handle returned by mac_open.
9084 \return uint32_t - Lim Mlm state
9085 -------------------------------------------------------------------------*/
9086uint32_t sme_get_lim_mlm_state(tHalHandle hHal)
9087{
9088 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
9089 return pMac->lim.gLimMlmState;
9090}
9091
9092/* ---------------------------------------------------------------------------
9093 \fn sme_is_lim_session_valid
9094 \brief is Lim session valid
9095 \param hHal - The handle returned by mac_open.
9096 \param sessionId - Session Identifier
9097 \return bool - true or false
9098 -------------------------------------------------------------------------*/
9099bool sme_is_lim_session_valid(tHalHandle hHal, uint8_t sessionId)
9100{
9101 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
9102 return pMac->lim.gpSession[sessionId].valid;
9103}
9104
9105/* ---------------------------------------------------------------------------
9106 \fn sme_get_lim_sme_session_state
9107 \brief get Lim Sme session state
9108 \param hHal - The handle returned by mac_open.
9109 \param sessionId - Session Identifier
9110 \return uint32_t - Lim Sme session state
9111 -------------------------------------------------------------------------*/
9112uint32_t sme_get_lim_sme_session_state(tHalHandle hHal, uint8_t sessionId)
9113{
9114 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
9115 return pMac->lim.gpSession[sessionId].limSmeState;
9116}
9117
9118/* ---------------------------------------------------------------------------
9119 \fn sme_get_lim_mlm_session_state
9120 \brief get Lim Mlm session state
9121 \param hHal - The handle returned by mac_open.
9122 \param sessionId - Session Identifier
9123 \return uint32_t - Lim Mlm session state
9124 -------------------------------------------------------------------------*/
9125uint32_t sme_get_lim_mlm_session_state(tHalHandle hHal, uint8_t sessionId)
9126{
9127 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
9128 return pMac->lim.gpSession[sessionId].limMlmState;
9129}
9130
9131/* ---------------------------------------------------------------------------
9132 \fn sme_get_neighbor_scan_max_chan_time
9133 \brief get neighbor scan max channel time
9134 \param hHal - The handle returned by mac_open.
9135 \param sessionId - Session Identifier
9136 \return uint16_t - channel max time value
9137 -------------------------------------------------------------------------*/
9138uint16_t sme_get_neighbor_scan_max_chan_time(tHalHandle hHal, uint8_t sessionId)
9139{
9140 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
9141 return pMac->roam.neighborRoamInfo[sessionId].cfgParams.
9142 maxChannelScanTime;
9143}
9144
9145/* ---------------------------------------------------------------------------
9146 \fn sme_set_neighbor_scan_period
9147 \brief Update nNeighborScanPeriod
9148 This function is called through dynamic setConfig callback function
9149 to configure nNeighborScanPeriod
9150 Usage: adb shell iwpriv wlan0 setConfig
9151 nNeighborScanPeriod=[0 .. 1000]
9152 \param hHal - HAL handle for device
9153 \param sessionId - Session Identifier
9154 \param nNeighborScanPeriod - neighbor scan period
9155 \- return Success or failure
9156 -------------------------------------------------------------------------*/
9157CDF_STATUS sme_set_neighbor_scan_period(tHalHandle hHal, uint8_t sessionId,
9158 const uint16_t nNeighborScanPeriod)
9159{
9160 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
9161 CDF_STATUS status = CDF_STATUS_SUCCESS;
9162 tCsrNeighborRoamConfig *pNeighborRoamConfig = NULL;
9163 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = NULL;
9164
9165 status = sme_acquire_global_lock(&pMac->sme);
9166 if (CDF_IS_STATUS_SUCCESS(status)) {
9167 pNeighborRoamConfig =
9168 &pMac->roam.configParam.neighborRoamConfig;
9169 pNeighborRoamInfo = &pMac->roam.neighborRoamInfo[sessionId];
9170 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_DEBUG,
9171 "LFR runtime successfully set neighbor scan period to %d"
9172 " - old value is %d - roam state is %s",
9173 nNeighborScanPeriod,
9174 pMac->roam.configParam.neighborRoamConfig.
9175 nNeighborScanTimerPeriod,
9176 mac_trace_get_neighbour_roam_state(pMac->roam.
9177 neighborRoamInfo
9178 [sessionId].
9179 neighborRoamState));
9180 pNeighborRoamConfig->nNeighborScanTimerPeriod =
9181 nNeighborScanPeriod;
9182 pNeighborRoamInfo->cfgParams.neighborScanPeriod =
9183 nNeighborScanPeriod;
9184 sme_release_global_lock(&pMac->sme);
9185 }
9186 if (pMac->roam.configParam.isRoamOffloadScanEnabled) {
9187 csr_roam_offload_scan(pMac, sessionId,
9188 ROAM_SCAN_OFFLOAD_UPDATE_CFG,
9189 REASON_SCAN_HOME_TIME_CHANGED);
9190 }
9191
9192 return status;
9193}
9194
9195/* ---------------------------------------------------------------------------
9196 \fn sme_get_neighbor_scan_period
9197 \brief get neighbor scan period
9198 \param hHal - The handle returned by mac_open.
9199 \param sessionId - Session Identifier
9200 \return uint16_t - neighbor scan period
9201 -------------------------------------------------------------------------*/
9202uint16_t sme_get_neighbor_scan_period(tHalHandle hHal, uint8_t sessionId)
9203{
9204 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
9205 return pMac->roam.neighborRoamInfo[sessionId].cfgParams.
9206 neighborScanPeriod;
9207}
9208
9209#endif
9210
9211#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
9212
9213/*--------------------------------------------------------------------------
9214 \brief sme_get_roam_rssi_diff() - get Roam rssi diff
9215 This is a synchronous call
9216 \param hHal - The handle returned by mac_open.
9217 \return uint16_t - Rssi diff value
9218 \sa
9219 --------------------------------------------------------------------------*/
9220uint8_t sme_get_roam_rssi_diff(tHalHandle hHal)
9221{
9222 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
9223 return pMac->roam.configParam.RoamRssiDiff;
9224}
9225
9226/**
9227 * sme_change_roam_scan_channel_list() - to change scan channel list
9228 * @hHal: pointer HAL handle returned by mac_open
9229 * @sessionId: sme session id
9230 * @pChannelList: Output channel list
9231 * @numChannels: Output number of channels
9232 *
9233 * This routine is called to Change roam scan channel list.
9234 * This is a synchronous call
9235 *
9236 * Return: CDF_STATUS
9237 */
9238CDF_STATUS sme_change_roam_scan_channel_list(tHalHandle hHal, uint8_t sessionId,
9239 uint8_t *pChannelList,
9240 uint8_t numChannels)
9241{
9242 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
9243 CDF_STATUS status = CDF_STATUS_SUCCESS;
9244 tpCsrNeighborRoamControlInfo pNeighborRoamInfo =
9245 &pMac->roam.neighborRoamInfo[sessionId];
9246 uint8_t oldChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN * 2] = { 0 };
9247 uint8_t newChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN * 2] = { 0 };
9248 uint8_t i = 0, j = 0;
9249 tCsrChannelInfo *chan_info;
9250
9251
9252 status = sme_acquire_global_lock(&pMac->sme);
9253 if (!CDF_IS_STATUS_SUCCESS(status)) {
9254 if (pMac->roam.configParam.isRoamOffloadScanEnabled)
9255 csr_roam_offload_scan(pMac, sessionId,
9256 ROAM_SCAN_OFFLOAD_UPDATE_CFG,
9257 REASON_CHANNEL_LIST_CHANGED);
9258 return status;
9259 }
9260 chan_info = &pNeighborRoamInfo->cfgParams.channelInfo;
9261
9262 if (NULL != chan_info->ChannelList) {
9263 for (i = 0; i < chan_info->numOfChannels; i++) {
9264 if (j < sizeof(oldChannelList))
9265 j += snprintf(oldChannelList + j,
9266 sizeof(oldChannelList) -
9267 j, "%d",
9268 chan_info->ChannelList[i]);
9269 else
9270 break;
9271 }
9272 }
9273 csr_flush_cfg_bg_scan_roam_channel_list(pMac, sessionId);
9274 csr_create_bg_scan_roam_channel_list(pMac, sessionId, pChannelList,
9275 numChannels);
9276 sme_set_roam_scan_control(hHal, sessionId, 1);
9277 if (NULL != chan_info->ChannelList) {
9278 j = 0;
9279 for (i = 0; i < chan_info->numOfChannels; i++) {
9280 if (j < sizeof(newChannelList))
9281 j += snprintf(newChannelList + j,
9282 sizeof(newChannelList) -
9283 j, " %d",
9284 chan_info->ChannelList[i]);
9285 else
9286 break;
9287 }
9288 }
9289 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_DEBUG,
9290 FL("LFR runtime successfully set roam scan channels to %s - old value is %s - roam state is %d"),
9291 newChannelList, oldChannelList,
9292 pMac->roam.neighborRoamInfo[sessionId].neighborRoamState);
9293 sme_release_global_lock(&pMac->sme);
9294
9295 if (pMac->roam.configParam.isRoamOffloadScanEnabled)
9296 csr_roam_offload_scan(pMac, sessionId,
9297 ROAM_SCAN_OFFLOAD_UPDATE_CFG,
9298 REASON_CHANNEL_LIST_CHANGED);
9299 return status;
9300}
9301
9302#ifdef FEATURE_WLAN_ESE_UPLOAD
9303/**
9304 * sme_set_ese_roam_scan_channel_list() - To set ese roam scan channel list
9305 * @hHal: pointer HAL handle returned by mac_open
9306 * @sessionId: sme session id
9307 * @pChannelList: Output channel list
9308 * @numChannels: Output number of channels
9309 *
9310 * This routine is called to set ese roam scan channel list.
9311 * This is a synchronous call
9312 *
9313 * Return: CDF_STATUS
9314 */
9315CDF_STATUS sme_set_ese_roam_scan_channel_list(tHalHandle hHal,
9316 uint8_t sessionId,
9317 uint8_t *pChannelList,
9318 uint8_t numChannels)
9319{
9320 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
9321 CDF_STATUS status = CDF_STATUS_SUCCESS;
9322 tpCsrNeighborRoamControlInfo pNeighborRoamInfo
9323 = &pMac->roam.neighborRoamInfo[sessionId];
9324 tpCsrChannelInfo curchnl_list_info
9325 = &pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo;
9326 uint8_t oldChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN * 2] = { 0 };
9327 uint8_t newChannelList[128] = { 0 };
9328 uint8_t i = 0, j = 0;
9329
9330 status = sme_acquire_global_lock(&pMac->sme);
9331 if (!CDF_IS_STATUS_SUCCESS(status)) {
9332 if (pMac->roam.configParam.isRoamOffloadScanEnabled)
9333 csr_roam_offload_scan(pMac, sessionId,
9334 ROAM_SCAN_OFFLOAD_UPDATE_CFG,
9335 REASON_CHANNEL_LIST_CHANGED);
9336 return status;
9337 }
9338 if (NULL != curchnl_list_info->ChannelList) {
9339 for (i = 0; i < curchnl_list_info->numOfChannels; i++) {
9340 j += snprintf(oldChannelList + j,
9341 sizeof(oldChannelList) - j, "%d",
9342 curchnl_list_info->ChannelList[i]);
9343 }
9344 }
9345 status = csr_create_roam_scan_channel_list(pMac, sessionId,
9346 pChannelList, numChannels,
9347 csr_get_current_band(hHal));
9348 if (CDF_IS_STATUS_SUCCESS(status)) {
9349 if (NULL != curchnl_list_info->ChannelList) {
9350 j = 0;
9351 for (i = 0; i < curchnl_list_info->numOfChannels; i++) {
9352 j += snprintf(newChannelList + j,
9353 sizeof(newChannelList) - j, "%d",
9354 curchnl_list_info->ChannelList[i]);
9355 }
9356 }
9357 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_DEBUG,
9358 "ESE roam scan chnl list successfully set to %s-old value is %s-roam state is %d",
9359 newChannelList, oldChannelList,
9360 pNeighborRoamInfo->neighborRoamState);
9361 }
9362 sme_release_global_lock(&pMac->sme);
9363 if (pMac->roam.configParam.isRoamOffloadScanEnabled)
9364 csr_roam_offload_scan(pMac, sessionId,
9365 ROAM_SCAN_OFFLOAD_UPDATE_CFG,
9366 REASON_CHANNEL_LIST_CHANGED);
9367 return status;
9368}
9369#endif
9370
9371/**
9372 * sme_get_roam_scan_channel_list() - To get roam scan channel list
9373 * @hHal: HAL pointer
9374 * @pChannelList: Output channel list
9375 * @pNumChannels: Output number of channels
9376 * @sessionId: Session Identifier
9377 *
9378 * To get roam scan channel list This is a synchronous call
9379 *
9380 * Return: CDF_STATUS
9381 */
9382CDF_STATUS sme_get_roam_scan_channel_list(tHalHandle hHal,
9383 uint8_t *pChannelList, uint8_t *pNumChannels,
9384 uint8_t sessionId)
9385{
9386 int i = 0;
9387 uint8_t *pOutPtr = pChannelList;
9388 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
9389 tpCsrNeighborRoamControlInfo pNeighborRoamInfo =
9390 &pMac->roam.neighborRoamInfo[sessionId];
9391 CDF_STATUS status = CDF_STATUS_SUCCESS;
9392
9393 status = sme_acquire_global_lock(&pMac->sme);
9394 if (!CDF_IS_STATUS_SUCCESS(status))
9395 return status;
9396 if (NULL == pNeighborRoamInfo->cfgParams.channelInfo.ChannelList) {
9397 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_WARN,
9398 FL("Roam Scan channel list is NOT yet initialized"));
9399 *pNumChannels = 0;
9400 sme_release_global_lock(&pMac->sme);
9401 return status;
9402 }
9403
9404 *pNumChannels = pNeighborRoamInfo->cfgParams.channelInfo.numOfChannels;
9405 for (i = 0; i < (*pNumChannels); i++) {
9406 pOutPtr[i] =
9407 pNeighborRoamInfo->cfgParams.channelInfo.ChannelList[i];
9408 }
9409 pOutPtr[i] = '\0';
9410 sme_release_global_lock(&pMac->sme);
9411 return status;
9412}
9413
9414/*--------------------------------------------------------------------------
9415 \brief sme_get_is_ese_feature_enabled() - get ESE feature enabled or not
9416 This is a synchronuous call
9417 \param hHal - The handle returned by mac_open.
9418 \return true (1) - if the ESE feature is enabled
9419 false (0) - if feature is disabled (compile or runtime)
9420 \sa
9421 --------------------------------------------------------------------------*/
9422bool sme_get_is_ese_feature_enabled(tHalHandle hHal)
9423{
9424#ifdef FEATURE_WLAN_ESE
9425 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
9426 return csr_roam_is_ese_ini_feature_enabled(pMac);
9427#else
9428 return false;
9429#endif
9430}
9431
9432/*--------------------------------------------------------------------------
9433 \brief sme_get_wes_mode() - get WES Mode
9434 This is a synchronous call
9435 \param hHal - The handle returned by mac_open
9436 \return uint8_t - WES Mode Enabled(1)/Disabled(0)
9437 \sa
9438 --------------------------------------------------------------------------*/
9439bool sme_get_wes_mode(tHalHandle hHal)
9440{
9441 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
9442 return pMac->roam.configParam.isWESModeEnabled;
9443}
9444
9445/*--------------------------------------------------------------------------
9446 \brief sme_get_roam_scan_control() - get scan control
9447 This is a synchronous call
9448 \param hHal - The handle returned by mac_open.
9449 \return bool - Enabled(1)/Disabled(0)
9450 \sa
9451 --------------------------------------------------------------------------*/
9452bool sme_get_roam_scan_control(tHalHandle hHal)
9453{
9454 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
9455 return pMac->roam.configParam.nRoamScanControl;
9456}
9457#endif
9458
9459/*--------------------------------------------------------------------------
9460 \brief sme_get_is_lfr_feature_enabled() - get LFR feature enabled or not
9461 This is a synchronuous call
9462 \param hHal - The handle returned by mac_open.
9463 \return true (1) - if the feature is enabled
9464 false (0) - if feature is disabled (compile or runtime)
9465 \sa
9466 --------------------------------------------------------------------------*/
9467bool sme_get_is_lfr_feature_enabled(tHalHandle hHal)
9468{
9469#ifdef FEATURE_WLAN_LFR
9470 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
9471 return pMac->roam.configParam.isFastRoamIniFeatureEnabled;
9472#else
9473 return false;
9474#endif
9475}
9476
9477/*--------------------------------------------------------------------------
9478 \brief sme_get_is_ft_feature_enabled() - get FT feature enabled or not
9479 This is a synchronuous call
9480 \param hHal - The handle returned by mac_open.
9481 \return true (1) - if the feature is enabled
9482 false (0) - if feature is disabled (compile or runtime)
9483 \sa
9484 --------------------------------------------------------------------------*/
9485bool sme_get_is_ft_feature_enabled(tHalHandle hHal)
9486{
9487#ifdef WLAN_FEATURE_VOWIFI_11R
9488 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
9489 return pMac->roam.configParam.isFastTransitionEnabled;
9490#else
9491 return false;
9492#endif
9493}
9494
9495/* ---------------------------------------------------------------------------
9496 \fn sme_is_feature_supported_by_fw
9497 \brief Check if an feature is enabled by FW
9498
9499 \param feattEnumValue - Enumeration value from placeHolderInCapBitmap
9500 \- return 1/0 (true/false)
9501 -------------------------------------------------------------------------*/
9502uint8_t sme_is_feature_supported_by_fw(uint8_t featEnumValue)
9503{
9504 return IS_FEATURE_SUPPORTED_BY_FW(featEnumValue);
9505}
9506
9507#ifdef FEATURE_WLAN_TDLS
9508
9509/* ---------------------------------------------------------------------------
9510 \fn sme_send_tdls_link_establish_params
9511 \brief API to send TDLS Peer Link Establishment Parameters.
9512
9513 \param peerMac - peer's Mac Adress.
9514 \param tdlsLinkEstablishParams - TDLS Peer Link Establishment Parameters
9515 \- return CDF_STATUS_SUCCES
9516 -------------------------------------------------------------------------*/
9517CDF_STATUS sme_send_tdls_link_establish_params(tHalHandle hHal,
9518 uint8_t sessionId,
9519 const tSirMacAddr peerMac,
9520 tCsrTdlsLinkEstablishParams *
9521 tdlsLinkEstablishParams)
9522{
9523 CDF_STATUS status = CDF_STATUS_SUCCESS;
9524 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
9525
9526 status = sme_acquire_global_lock(&pMac->sme);
9527
9528 if (CDF_IS_STATUS_SUCCESS(status)) {
9529 status = csr_tdls_send_link_establish_params(hHal, sessionId,
9530 peerMac, tdlsLinkEstablishParams);
9531 sme_release_global_lock(&pMac->sme);
9532 }
9533 return status;
9534}
9535
9536/* ---------------------------------------------------------------------------
9537 \fn sme_send_tdls_mgmt_frame
9538 \brief API to send TDLS management frames.
9539
9540 \param peerMac - peer's Mac Adress.
9541 \param frame_type - Type of TDLS mgmt frame to be sent.
9542 \param dialog - dialog token used in the frame.
9543 \param status - status to be incuded in the frame.
9544 \param peerCapability - peer cpabilities
9545 \param buf - additional IEs to be included
9546 \param len - lenght of additional Ies
9547 \param responder - Tdls request type
9548 \- return CDF_STATUS_SUCCES
9549 -------------------------------------------------------------------------*/
9550CDF_STATUS sme_send_tdls_mgmt_frame(tHalHandle hHal, uint8_t sessionId,
9551 const tSirMacAddr peerMac,
9552 uint8_t frame_type,
9553 uint8_t dialog, uint16_t statusCode,
9554 uint32_t peerCapability, uint8_t *buf,
9555 uint8_t len, uint8_t responder)
9556{
9557 CDF_STATUS status = CDF_STATUS_SUCCESS;
9558 tCsrTdlsSendMgmt sendTdlsReq = { {0} };
9559 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
9560
9561 status = sme_acquire_global_lock(&pMac->sme);
9562 if (CDF_IS_STATUS_SUCCESS(status)) {
9563 cdf_mem_copy(sendTdlsReq.peerMac, peerMac, sizeof(tSirMacAddr));
9564 sendTdlsReq.frameType = frame_type;
9565 sendTdlsReq.buf = buf;
9566 sendTdlsReq.len = len;
9567 sendTdlsReq.dialog = dialog;
9568 sendTdlsReq.statusCode = statusCode;
9569 sendTdlsReq.responder = responder;
9570 sendTdlsReq.peerCapability = peerCapability;
9571
9572 status = csr_tdls_send_mgmt_req(hHal, sessionId, &sendTdlsReq);
9573
9574 sme_release_global_lock(&pMac->sme);
9575 }
9576
9577 return status;
9578
9579}
9580
9581/* ---------------------------------------------------------------------------
9582 \fn sme_change_tdls_peer_sta
9583 \brief API to Update TDLS peer sta parameters.
9584
9585 \param peerMac - peer's Mac Adress.
9586 \param staParams - Peer Station Parameters
9587 \- return CDF_STATUS_SUCCES
9588 -------------------------------------------------------------------------*/
9589CDF_STATUS sme_change_tdls_peer_sta(tHalHandle hHal, uint8_t sessionId,
9590 const tSirMacAddr peerMac,
9591 tCsrStaParams *pstaParams)
9592{
9593 CDF_STATUS status = CDF_STATUS_SUCCESS;
9594 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
9595
9596 if (NULL == pstaParams) {
9597 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
9598 "%s :pstaParams is NULL", __func__);
9599 return CDF_STATUS_E_FAILURE;
9600 }
9601 status = sme_acquire_global_lock(&pMac->sme);
9602 if (CDF_IS_STATUS_SUCCESS(status)) {
9603 status = csr_tdls_change_peer_sta(hHal, sessionId, peerMac,
9604 pstaParams);
9605
9606 sme_release_global_lock(&pMac->sme);
9607 }
9608
9609 return status;
9610
9611}
9612
9613/* ---------------------------------------------------------------------------
9614 \fn sme_add_tdls_peer_sta
9615 \brief API to Add TDLS peer sta entry.
9616
9617 \param peerMac - peer's Mac Adress.
9618 \- return CDF_STATUS_SUCCES
9619 -------------------------------------------------------------------------*/
9620CDF_STATUS sme_add_tdls_peer_sta(tHalHandle hHal, uint8_t sessionId,
9621 const tSirMacAddr peerMac)
9622{
9623 CDF_STATUS status = CDF_STATUS_SUCCESS;
9624 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
9625
9626 status = sme_acquire_global_lock(&pMac->sme);
9627 if (CDF_IS_STATUS_SUCCESS(status)) {
9628 status = csr_tdls_add_peer_sta(hHal, sessionId, peerMac);
9629
9630 sme_release_global_lock(&pMac->sme);
9631 }
9632
9633 return status;
9634
9635}
9636
9637/* ---------------------------------------------------------------------------
9638 \fn sme_delete_tdls_peer_sta
9639 \brief API to Delete TDLS peer sta entry.
9640
9641 \param peerMac - peer's Mac Adress.
9642 \- return CDF_STATUS_SUCCES
9643 -------------------------------------------------------------------------*/
9644CDF_STATUS sme_delete_tdls_peer_sta(tHalHandle hHal, uint8_t sessionId,
9645 const tSirMacAddr peerMac)
9646{
9647 CDF_STATUS status = CDF_STATUS_SUCCESS;
9648 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
9649
9650 status = sme_acquire_global_lock(&pMac->sme);
9651 if (CDF_IS_STATUS_SUCCESS(status)) {
9652 status = csr_tdls_del_peer_sta(hHal, sessionId, peerMac);
9653
9654 sme_release_global_lock(&pMac->sme);
9655 }
9656
9657 return status;
9658
9659}
9660
9661/* ---------------------------------------------------------------------------
9662 \fn sme_set_tdls_power_save_prohibited
9663 \API to set/reset the is_tdls_power_save_prohibited.
9664
9665 \- return void
9666 -------------------------------------------------------------------------*/
9667void sme_set_tdls_power_save_prohibited(tHalHandle hHal, uint32_t sessionId,
9668 bool val)
9669{
9670 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
9671 struct ps_global_info *ps_global_info = &pMac->sme.ps_global_info;
9672 struct ps_params *ps_param = &ps_global_info->ps_params[sessionId];
9673 ps_param->is_tdls_power_save_prohibited = val;
9674 return;
9675}
9676
9677/* ---------------------------------------------------------------------------
9678 \fn sme_update_fw_tdls_state
9679
9680 \brief
9681 SME will send message to WMA to set TDLS state in f/w
9682
9683 \param
9684
9685 hHal - The handle returned by mac_open
9686
9687 psmeTdlsParams - TDLS state info to update in f/w
9688
9689 useSmeLock - Need to acquire SME Global Lock before state update or not
9690
9691 \return CDF_STATUS
9692 --------------------------------------------------------------------------- */
9693CDF_STATUS sme_update_fw_tdls_state(tHalHandle hHal, void *psmeTdlsParams,
9694 bool useSmeLock)
9695{
9696 CDF_STATUS status = CDF_STATUS_SUCCESS;
9697 CDF_STATUS cdf_status = CDF_STATUS_SUCCESS;
9698 tpAniSirGlobal pMac = NULL;
9699 cds_msg_t cds_message;
9700
9701 /* only acquire sme global lock before state update if asked to */
9702 if (useSmeLock) {
9703 pMac = PMAC_STRUCT(hHal);
9704 if (NULL == pMac)
9705 return CDF_STATUS_E_FAILURE;
9706
9707 status = sme_acquire_global_lock(&pMac->sme);
9708 if (CDF_STATUS_SUCCESS != status)
9709 return status;
9710 }
9711
9712 /* serialize the req through MC thread */
9713 cds_message.bodyptr = psmeTdlsParams;
9714 cds_message.type = WMA_UPDATE_FW_TDLS_STATE;
9715 cdf_status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message);
9716 if (!CDF_IS_STATUS_SUCCESS(cdf_status))
9717 status = CDF_STATUS_E_FAILURE;
9718
9719 /* release the lock if it was acquired */
9720 if (useSmeLock)
9721 sme_release_global_lock(&pMac->sme);
9722
9723 return status;
9724}
9725
9726/**
9727 * sme_update_tdls_peer_state() - to update the state of TDLS peer
9728 * @hHal: The handle returned by mac_open
9729 * @peerStateParams: TDLS Peer state info to update in f/w
9730 *
9731 * SME will send message to WMA to set TDLS Peer state in f/w
9732 *
9733 * Return: CDF_STATUS
9734 */
9735CDF_STATUS sme_update_tdls_peer_state(tHalHandle hHal,
9736 tSmeTdlsPeerStateParams *peerStateParams)
9737{
9738 CDF_STATUS status = CDF_STATUS_SUCCESS;
9739 CDF_STATUS cdf_status = CDF_STATUS_SUCCESS;
9740 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
9741 tTdlsPeerStateParams *pTdlsPeerStateParams = NULL;
9742 tTdlsPeerCapParams *peer_cap = NULL;
9743 cds_msg_t cds_message;
9744 uint8_t num;
9745 uint8_t chanId;
9746 uint8_t i;
9747
9748 status = sme_acquire_global_lock(&pMac->sme);
9749 if (!CDF_IS_STATUS_SUCCESS(status))
9750 return status;
9751 pTdlsPeerStateParams = cdf_mem_malloc(sizeof(*pTdlsPeerStateParams));
9752 if (NULL == pTdlsPeerStateParams) {
9753 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
9754 FL("failed to allocate mem for tdls peer state param"));
9755 sme_release_global_lock(&pMac->sme);
9756 return CDF_STATUS_E_NOMEM;
9757 }
9758
9759 cdf_mem_zero(pTdlsPeerStateParams, sizeof(*pTdlsPeerStateParams));
9760 cdf_mem_copy(&pTdlsPeerStateParams->peerMacAddr,
9761 &peerStateParams->peerMacAddr, sizeof(tSirMacAddr));
9762 pTdlsPeerStateParams->vdevId = peerStateParams->vdevId;
9763 pTdlsPeerStateParams->peerState = peerStateParams->peerState;
9764
9765 switch (peerStateParams->peerState) {
9766 case eSME_TDLS_PEER_STATE_PEERING:
9767 pTdlsPeerStateParams->peerState =
9768 WMA_TDLS_PEER_STATE_PEERING;
9769 break;
9770
9771 case eSME_TDLS_PEER_STATE_CONNECTED:
9772 pTdlsPeerStateParams->peerState =
9773 WMA_TDLS_PEER_STATE_CONNECTED;
9774 break;
9775
9776 case eSME_TDLS_PEER_STATE_TEARDOWN:
9777 pTdlsPeerStateParams->peerState =
9778 WMA_TDLS_PEER_STATE_TEARDOWN;
9779 break;
9780
9781 default:
9782 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
9783 FL("invalid peer state param (%d)"),
9784 peerStateParams->peerState);
9785 cdf_mem_free(pTdlsPeerStateParams);
9786 sme_release_global_lock(&pMac->sme);
9787 return CDF_STATUS_E_FAILURE;
9788 }
9789 peer_cap = &(pTdlsPeerStateParams->peerCap);
9790 peer_cap->isPeerResponder =
9791 peerStateParams->peerCap.isPeerResponder;
9792 peer_cap->peerUapsdQueue =
9793 peerStateParams->peerCap.peerUapsdQueue;
9794 peer_cap->peerMaxSp =
9795 peerStateParams->peerCap.peerMaxSp;
9796 peer_cap->peerBuffStaSupport =
9797 peerStateParams->peerCap.peerBuffStaSupport;
9798 peer_cap->peerOffChanSupport =
9799 peerStateParams->peerCap.peerOffChanSupport;
9800 peer_cap->peerCurrOperClass =
9801 peerStateParams->peerCap.peerCurrOperClass;
9802 peer_cap->selfCurrOperClass =
9803 peerStateParams->peerCap.selfCurrOperClass;
9804
9805 num = 0;
9806 for (i = 0; i < peerStateParams->peerCap.peerChanLen; i++) {
9807 chanId = peerStateParams->peerCap.peerChan[i];
9808 if (!csr_roam_is_channel_valid(pMac, chanId))
9809 continue;
9810 peer_cap->peerChan[num].chanId = chanId;
9811 peer_cap->peerChan[num].pwr =
9812 csr_get_cfg_max_tx_power(pMac, chanId);
9813
9814 if (cds_get_channel_state(chanId) == CHANNEL_STATE_DFS)
9815 peer_cap->peerChan[num].dfsSet =
9816 true;
9817 else
9818 peer_cap->peerChan[num].dfsSet =
9819 false;
9820 num++;
9821 }
9822 peer_cap->peerChanLen = num;
9823 peer_cap->peerOperClassLen =
9824 peerStateParams->peerCap.peerOperClassLen;
9825 for (i = 0; i < HAL_TDLS_MAX_SUPP_OPER_CLASSES; i++) {
9826 peer_cap->peerOperClass[i] =
9827 peerStateParams->peerCap.peerOperClass[i];
9828 }
9829
9830 peer_cap->prefOffChanNum =
9831 peerStateParams->peerCap.prefOffChanNum;
9832 peer_cap->prefOffChanBandwidth =
9833 peerStateParams->peerCap.prefOffChanBandwidth;
9834
9835 if (peerStateParams->peerCap.opClassForPrefOffChanIsSet) {
9836 peer_cap->opClassForPrefOffChan =
9837 peerStateParams->peerCap.opClassForPrefOffChan;
9838 } else {
9839 /*
9840 * redgm opclass table contains opclass for 40MHz low
9841 * primary, 40MHz high primary and 20MHz. No support
9842 * for 80MHz yet. So first we will check if bit for
9843 * 40MHz is set and if so find matching opclass either
9844 * with low primary or high primary (a channel would
9845 * never be in both) and then search for opclass
9846 * matching 20MHz, else for any BW.
9847 */
9848 if (peer_cap->prefOffChanBandwidth &
9849 (1 << BW_40_OFFSET_BIT)) {
9850 peer_cap->opClassForPrefOffChan =
9851 cds_regdm_get_opclass_from_channel(
9852 pMac->scan.countryCodeCurrent,
9853 peer_cap->prefOffChanNum,
9854 BW40_LOW_PRIMARY);
9855 if (!peer_cap->opClassForPrefOffChan) {
9856 peer_cap->opClassForPrefOffChan =
9857 cds_regdm_get_opclass_from_channel(
9858 pMac->scan.countryCodeCurrent,
9859 peer_cap->prefOffChanNum,
9860 BW40_HIGH_PRIMARY);
9861 }
9862 } else if (peer_cap->prefOffChanBandwidth &
9863 (1 << BW_20_OFFSET_BIT)) {
9864 peer_cap->opClassForPrefOffChan =
9865 cds_regdm_get_opclass_from_channel(
9866 pMac->scan.countryCodeCurrent,
9867 peer_cap->prefOffChanNum,
9868 BW20);
9869 } else {
9870 peer_cap->opClassForPrefOffChan =
9871 cds_regdm_get_opclass_from_channel(
9872 pMac->scan.countryCodeCurrent,
9873 peer_cap->prefOffChanNum,
9874 BWALL);
9875 }
9876 }
9877 cds_message.type = WMA_UPDATE_TDLS_PEER_STATE;
9878 cds_message.reserved = 0;
9879 cds_message.bodyptr = pTdlsPeerStateParams;
9880
9881 cdf_status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message);
9882 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
9883 cdf_mem_free(pTdlsPeerStateParams);
9884 status = CDF_STATUS_E_FAILURE;
9885 }
9886 sme_release_global_lock(&pMac->sme);
9887 return status;
9888}
9889
9890/**
9891 * sme_send_tdls_chan_switch_req() - send tdls channel switch request
9892 * @hal: UMAC handler
9893 * @ch_switch_params: Pointer to the chan switch parameter structure
9894 *
9895 * API to set tdls channel switch parameters.
9896 *
9897 * Return: CDF_STATUS_SUCCESS on success; another CDF_STATUS_* code otherwise
9898 */
9899CDF_STATUS sme_send_tdls_chan_switch_req(tHalHandle hal,
9900 sme_tdls_chan_switch_params *ch_switch_params)
9901{
9902 CDF_STATUS status = CDF_STATUS_SUCCESS;
9903 CDF_STATUS cdf_status = CDF_STATUS_SUCCESS;
9904 tpAniSirGlobal mac = PMAC_STRUCT(hal);
9905 tdls_chan_switch_params *chan_switch_params = NULL;
9906 cds_msg_t cds_message;
9907
9908 status = sme_acquire_global_lock(&mac->sme);
9909 if (CDF_STATUS_SUCCESS != status)
9910 return status;
9911 chan_switch_params = cdf_mem_malloc(sizeof(*chan_switch_params));
9912 if (NULL == chan_switch_params) {
9913 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
9914 FL("fail to alloc mem for tdls chan switch param"));
9915 sme_release_global_lock(&mac->sme);
9916 return CDF_STATUS_E_FAILURE;
9917 }
9918 cdf_mem_zero(chan_switch_params, sizeof(*chan_switch_params));
9919
9920 switch (ch_switch_params->tdls_off_ch_mode) {
9921 case ENABLE_CHANSWITCH:
9922 chan_switch_params->tdls_sw_mode = WMA_TDLS_ENABLE_OFFCHANNEL;
9923 break;
9924
9925 case DISABLE_CHANSWITCH:
9926 chan_switch_params->tdls_sw_mode = WMA_TDLS_DISABLE_OFFCHANNEL;
9927 break;
9928
9929 default:
9930 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
9931 FL("invalid off channel command (%d)"),
9932 ch_switch_params->tdls_off_ch_mode);
9933 cdf_mem_free(chan_switch_params);
9934 sme_release_global_lock(&mac->sme);
9935 return CDF_STATUS_E_FAILURE;
9936 }
9937
9938 cdf_mem_copy(&chan_switch_params->peer_mac_addr,
9939 &ch_switch_params->peer_mac_addr, sizeof(tSirMacAddr));
9940 chan_switch_params->vdev_id = ch_switch_params->vdev_id;
9941 chan_switch_params->tdls_off_ch = ch_switch_params->tdls_off_channel;
9942 chan_switch_params->tdls_off_ch_bw_offset =
9943 ch_switch_params->tdls_off_ch_bw_offset;
9944 chan_switch_params->is_responder = ch_switch_params->is_responder;
9945
9946 switch (chan_switch_params->tdls_off_ch_bw_offset) {
9947 case (1 << BW_20_OFFSET_BIT):
9948 chan_switch_params->oper_class =
9949 cds_regdm_get_opclass_from_channel(
9950 mac->scan.countryCodeCurrent,
9951 chan_switch_params->tdls_off_ch,
9952 BW20);
9953 break;
9954 case (1 << BW_40_OFFSET_BIT):
9955 chan_switch_params->oper_class =
9956 cds_regdm_get_opclass_from_channel(
9957 mac->scan.countryCodeCurrent,
9958 chan_switch_params->tdls_off_ch,
9959 BW40_LOW_PRIMARY);
9960 if (!chan_switch_params->oper_class) {
9961 chan_switch_params->oper_class =
9962 cds_regdm_get_opclass_from_channel(
9963 mac->scan.countryCodeCurrent,
9964 chan_switch_params->tdls_off_ch,
9965 BW40_HIGH_PRIMARY);
9966 }
9967 break;
9968 default:
9969 chan_switch_params->oper_class =
9970 cds_regdm_get_opclass_from_channel(
9971 mac->scan.countryCodeCurrent,
9972 chan_switch_params->tdls_off_ch,
9973 BWALL);
9974 break;
9975 } /* end switch */
9976
9977 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_INFO,
9978 FL("Country Code=%s, Req offset=%d, Selected Operate Class=%d"),
9979 mac->scan.countryCodeCurrent,
9980 chan_switch_params->tdls_off_ch_bw_offset,
9981 chan_switch_params->oper_class);
9982
9983 cds_message.type = WMA_TDLS_SET_OFFCHAN_MODE;
9984 cds_message.reserved = 0;
9985 cds_message.bodyptr = chan_switch_params;
9986
9987 cdf_status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message);
9988 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
9989 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
9990 FL("Message Post failed status=%d"),
9991 cdf_status);
9992 cdf_mem_free(chan_switch_params);
9993 status = CDF_STATUS_E_FAILURE;
9994 }
9995 sme_release_global_lock(&mac->sme);
9996 return status;
9997}
9998#endif /* FEATURE_WLAN_TDLS */
9999
10000CDF_STATUS sme_get_link_speed(tHalHandle hHal, tSirLinkSpeedInfo *lsReq,
10001 void *plsContext,
10002 void (*pCallbackfn)(tSirLinkSpeedInfo *indParam,
10003 void *pContext))
10004{
10005
10006 CDF_STATUS status = CDF_STATUS_SUCCESS;
10007 CDF_STATUS cdf_status = CDF_STATUS_SUCCESS;
10008 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
10009 cds_msg_t cds_message;
10010
10011 status = sme_acquire_global_lock(&pMac->sme);
10012 if (CDF_STATUS_SUCCESS == status) {
10013 if ((NULL == pCallbackfn) &&
10014 (NULL == pMac->sme.pLinkSpeedIndCb)) {
10015 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
10016 "%s: Indication Call back did not registered",
10017 __func__);
10018 sme_release_global_lock(&pMac->sme);
10019 return CDF_STATUS_E_FAILURE;
10020 } else if (NULL != pCallbackfn) {
10021 pMac->sme.pLinkSpeedCbContext = plsContext;
10022 pMac->sme.pLinkSpeedIndCb = pCallbackfn;
10023 }
10024 /* serialize the req through MC thread */
10025 cds_message.bodyptr = lsReq;
10026 cds_message.type = WMA_GET_LINK_SPEED;
10027 cdf_status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message);
10028 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
10029 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
10030 "%s: Post Link Speed msg fail", __func__);
10031 status = CDF_STATUS_E_FAILURE;
10032 }
10033 sme_release_global_lock(&pMac->sme);
10034 }
10035 return status;
10036}
10037
10038
10039/*
10040 * SME API to enable/disable WLAN driver initiated SSR
10041 */
10042void sme_update_enable_ssr(tHalHandle hHal, bool enableSSR)
10043{
10044 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
10045 CDF_STATUS status = CDF_STATUS_SUCCESS;
10046
10047 status = sme_acquire_global_lock(&pMac->sme);
10048 if (CDF_IS_STATUS_SUCCESS(status)) {
10049 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_DEBUG,
10050 "SSR level is changed %d", enableSSR);
10051 /* not serializing this messsage, as this is only going
10052 * to set a variable in WMA/WDI
10053 */
10054 WMA_SetEnableSSR(enableSSR);
10055 sme_release_global_lock(&pMac->sme);
10056 }
10057 return;
10058}
10059
10060CDF_STATUS sme_check_ch_in_band(tpAniSirGlobal mac_ctx, uint8_t start_ch,
10061 uint8_t ch_cnt)
10062{
10063 uint8_t i;
10064 for (i = 0; i < ch_cnt; i++) {
10065 if (CDF_STATUS_SUCCESS != csr_is_valid_channel(mac_ctx,
10066 (start_ch + i*4)))
10067 return CDF_STATUS_E_FAILURE;
10068 }
10069 return CDF_STATUS_SUCCESS;
10070}
10071
10072void sme_set_160bw_params(tpAniSirGlobal mac_ctx, uint8_t channel,
10073 chan_params_t *ch_params)
10074{
10075 uint8_t start_ch = 0;
10076 CDF_STATUS status = CDF_STATUS_SUCCESS;
10077
10078 if (channel >= 36 && channel <= 64) {
10079 ch_params->center_freq_seg0 = 50;
10080 start_ch = 36;
10081 } else if (channel >= 100 && channel <= 128) {
10082 ch_params->center_freq_seg0 = 114;
10083 start_ch = 100;
10084 } else {
10085 ch_params->ch_width = CH_WIDTH_80MHZ;
10086 }
10087
10088 if (ch_params->ch_width == CH_WIDTH_160MHZ)
10089 status = sme_check_ch_in_band(mac_ctx, start_ch, 8);
10090
10091 if (CDF_STATUS_SUCCESS != status)
10092 ch_params->ch_width = CH_WIDTH_80MHZ;
10093}
10094
10095void sme_set_80bw_params(tpAniSirGlobal mac_ctx, uint8_t channel,
10096 chan_params_t *ch_params)
10097{
10098 uint8_t start_ch = 0;
10099 CDF_STATUS status = CDF_STATUS_SUCCESS;
10100
10101 if (channel >= 36 && channel <= 48) {
10102 ch_params->center_freq_seg0 = 42;
10103 start_ch = 36;
10104 } else if (channel >= 52 && channel <= 64) {
10105 ch_params->center_freq_seg0 = 58;
10106 start_ch = 52;
10107 } else if (channel >= 100 && channel <= 112) {
10108 ch_params->center_freq_seg0 = 106;
10109 start_ch = 100;
10110 } else if (channel >= 116 && channel <= 128) {
10111 ch_params->center_freq_seg0 = 122;
10112 start_ch = 116;
10113 } else if (channel >= 132 && channel <= 144) {
10114 ch_params->center_freq_seg0 = 138;
10115 start_ch = 132;
10116 } else if (channel >= 149 && channel <= 161) {
10117 ch_params->center_freq_seg0 = 155;
10118 start_ch = 149;
10119 } else {
10120 ch_params->ch_width = CH_WIDTH_40MHZ;
10121 }
10122
10123 if (ch_params->ch_width == CH_WIDTH_80MHZ)
10124 status = sme_check_ch_in_band(mac_ctx, start_ch, 4);
10125
10126 if (CDF_STATUS_SUCCESS != status)
10127 ch_params->ch_width = CH_WIDTH_40MHZ;
10128}
10129
10130void sme_set_40bw_params(tpAniSirGlobal mac_ctx, uint8_t channel,
10131 chan_params_t *ch_params, uint8_t is_11ac_mode)
10132{
10133 uint8_t tmp;
10134 uint8_t center_freq = 0;
10135 bool valid_40Mhz_ch = true;
10136
10137 if (channel == 165) {
10138 ch_params->ch_width = CH_WIDTH_20MHZ;
10139 ch_params->center_freq_seg0 = 0;
10140 ch_params->sec_ch_offset = PHY_SINGLE_CHANNEL_CENTERED;
10141 return;
10142 }
10143 tmp = channel % 2;
10144 if ((channel - tmp) % 8) {
10145 ch_params->sec_ch_offset = PHY_DOUBLE_CHANNEL_LOW_PRIMARY;
10146 center_freq = channel + 2;
10147 } else {
10148 ch_params->sec_ch_offset = PHY_DOUBLE_CHANNEL_HIGH_PRIMARY;
10149 center_freq = channel - 2;
10150 }
10151 if ((!is_11ac_mode) || (is_11ac_mode &&
10152 (ch_params->ch_width == CH_WIDTH_40MHZ))) {
10153 ch_params->ch_width = CH_WIDTH_40MHZ;
10154 ch_params->center_freq_seg0 = center_freq;
10155 valid_40Mhz_ch = csr_roam_is_valid40_mhz_channel(mac_ctx,
10156 ch_params->center_freq_seg0);
10157 }
10158 if (!valid_40Mhz_ch) {
10159 ch_params->ch_width = CH_WIDTH_20MHZ;
10160 ch_params->center_freq_seg0 = 0;
10161 ch_params->sec_ch_offset = PHY_SINGLE_CHANNEL_CENTERED;
10162 }
10163}
10164
10165/*
10166 * SME API to determine the channel bonding mode
10167 */
10168CDF_STATUS sme_set_ch_params(tHalHandle hHal, eCsrPhyMode eCsrPhyMode,
10169 uint8_t channel, uint8_t ht_sec_ch, chan_params_t *ch_params)
10170{
10171 tpAniSirGlobal mac_ctx = PMAC_STRUCT(hHal);
10172 int is_11ac_mode = CSR_IS_PHY_MODE_11ac(eCsrPhyMode);
10173
10174 if (!CSR_IS_PHY_MODE_11n(eCsrPhyMode) ||
10175 ch_params->ch_width == CH_WIDTH_20MHZ ||
10176 CDF_STATUS_SUCCESS != csr_is_valid_channel(mac_ctx, channel)) {
10177 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
10178 "%s: Invalid Channel/phymode config: CB Mode disabled",
10179 __func__);
10180 ch_params->ch_width = CH_WIDTH_20MHZ;
10181 ch_params->sec_ch_offset = PHY_SINGLE_CHANNEL_CENTERED;
10182 if (channel <= 14)
10183 mac_ctx->roam.configParam.channelBondingMode24GHz =
10184 PHY_SINGLE_CHANNEL_CENTERED;
10185 else
10186 mac_ctx->roam.configParam.channelBondingMode5GHz =
10187 PHY_SINGLE_CHANNEL_CENTERED;
10188 return CDF_STATUS_SUCCESS;
10189 }
10190
10191 sms_log(mac_ctx, LOGW, "%s: channel - %d, vht channel width - %d",
10192 __func__, channel, ch_params->ch_width);
10193
10194 if (CDS_IS_CHANNEL_5GHZ(channel)) {
10195 if (ch_params->ch_width == CH_WIDTH_160MHZ)
10196 sme_set_160bw_params(mac_ctx, channel, ch_params);
10197 if ((ch_params->ch_width == CH_WIDTH_80MHZ) ||
10198 (ch_params->ch_width == CH_WIDTH_80P80MHZ))
10199 sme_set_80bw_params(mac_ctx, channel, ch_params);
10200
10201 sme_set_40bw_params(mac_ctx, channel,
10202 ch_params, is_11ac_mode);
10203
10204 mac_ctx->roam.configParam.channelBondingMode5GHz =
10205 ch_params->sec_ch_offset;
10206 } else if (CDS_IS_CHANNEL_24GHZ(channel)) {
10207 if (channel >= 1 && channel < 5) {
10208 ch_params->ch_width = CH_WIDTH_40MHZ;
10209 ch_params->sec_ch_offset =
10210 PHY_DOUBLE_CHANNEL_LOW_PRIMARY;
10211 ch_params->center_freq_seg0 = channel + 2;
10212 } else if (channel >= 5 && channel <= 9) {
10213 ch_params->ch_width = CH_WIDTH_40MHZ;
10214 if (0 != ht_sec_ch) {
10215 if (ht_sec_ch > channel) {
10216 ch_params->sec_ch_offset =
10217 PHY_DOUBLE_CHANNEL_LOW_PRIMARY;
10218 ch_params->center_freq_seg0 =
10219 channel + 2;
10220 } else {
10221 ch_params->sec_ch_offset =
10222 PHY_DOUBLE_CHANNEL_HIGH_PRIMARY;
10223 ch_params->center_freq_seg0 =
10224 channel - 2;
10225 }
10226 } else {
10227 /* in case ht_sec_ch is not set by ACS or
10228 * calling function, set the secondary channel
10229 * offset value to lower channel
10230 */
10231 ch_params->sec_ch_offset =
10232 PHY_DOUBLE_CHANNEL_HIGH_PRIMARY;
10233 ch_params->center_freq_seg0 = channel - 2;
10234 }
10235 } else if (channel > 9 && channel <= 13) {
10236 ch_params->ch_width = CH_WIDTH_40MHZ;
10237 ch_params->sec_ch_offset =
10238 PHY_DOUBLE_CHANNEL_HIGH_PRIMARY;
10239 ch_params->center_freq_seg0 = channel - 2;
10240 } else if (channel == 14) {
10241 ch_params->ch_width = CH_WIDTH_20MHZ;
10242 ch_params->sec_ch_offset =
10243 PHY_SINGLE_CHANNEL_CENTERED;
10244 ch_params->center_freq_seg0 = 0;
10245 }
10246 mac_ctx->roam.configParam.channelBondingMode24GHz =
10247 ch_params->sec_ch_offset;
10248 }
10249 return CDF_STATUS_SUCCESS;
10250}
10251
10252/*convert the ini value to the ENUM used in csr and MAC for CB state*/
10253ePhyChanBondState sme_get_cb_phy_state_from_cb_ini_value(uint32_t cb_ini_value)
10254{
10255 return csr_convert_cb_ini_value_to_phy_cb_state(cb_ini_value);
10256}
10257
10258/*--------------------------------------------------------------------------
10259
10260 \brief sme_set_curr_device_mode() - Sets the current operating device mode.
10261 \param hHal - The handle returned by mac_open.
10262 \param currDeviceMode - Current operating device mode.
10263 --------------------------------------------------------------------------*/
10264
10265void sme_set_curr_device_mode(tHalHandle hHal, tCDF_CON_MODE currDeviceMode)
10266{
10267 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
10268 pMac->sme.currDeviceMode = currDeviceMode;
10269 return;
10270}
10271
10272/*--------------------------------------------------------------------------
10273 \brief sme_handoff_request() - a wrapper function to Request a handoff
10274 from CSR.
10275 This is a synchronous call
10276 \param hHal - The handle returned by mac_open
10277 \param sessionId - Session Identifier
10278 \param pHandoffInfo - info provided by HDD with the handoff request (namely:
10279 BSSID, channel etc.)
10280 \return CDF_STATUS_SUCCESS - SME passed the request to CSR successfully.
10281 Other status means SME is failed to send the request.
10282 \sa
10283 --------------------------------------------------------------------------*/
10284
10285CDF_STATUS sme_handoff_request(tHalHandle hHal,
10286 uint8_t sessionId,
10287 tCsrHandoffRequest *pHandoffInfo)
10288{
10289 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
10290 CDF_STATUS status = CDF_STATUS_SUCCESS;
10291
10292 status = sme_acquire_global_lock(&pMac->sme);
10293 if (CDF_IS_STATUS_SUCCESS(status)) {
10294 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_INFO,
10295 "%s: invoked", __func__);
10296 status = csr_handoff_request(pMac, sessionId, pHandoffInfo);
10297 sme_release_global_lock(&pMac->sme);
10298 }
10299
10300 return status;
10301}
10302
10303#ifdef IPA_OFFLOAD
10304/* ---------------------------------------------------------------------------
10305 \fn sme_ipa_offload_enable_disable
10306 \brief API to enable/disable IPA offload
10307 \param hal - The handle returned by macOpen.
10308 \param session_id - Session Identifier
10309 \param request - Pointer to the offload request.
10310 \return CDF_STATUS
10311 ---------------------------------------------------------------------------*/
10312CDF_STATUS sme_ipa_offload_enable_disable(tHalHandle hal, uint8_t session_id,
10313 struct sir_ipa_offload_enable_disable *request)
10314{
10315 tpAniSirGlobal pMac = PMAC_STRUCT(hal);
10316 CDF_STATUS status = CDF_STATUS_E_FAILURE;
10317 struct sir_ipa_offload_enable_disable *request_buf;
10318 cds_msg_t msg;
10319
10320 status = sme_acquire_global_lock(&pMac->sme);
10321 if (CDF_STATUS_SUCCESS == status) {
10322 request_buf = cdf_mem_malloc(sizeof(*request_buf));
10323 if (NULL == request_buf) {
10324 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
10325 FL("Not able to allocate memory for \
10326 IPA_OFFLOAD_ENABLE_DISABLE"));
10327 sme_release_global_lock(&pMac->sme);
10328 return CDF_STATUS_E_NOMEM;
10329 }
10330
10331 request_buf->offload_type = request->offload_type;
10332 request_buf->vdev_id = request->vdev_id;
10333 request_buf->enable = request->enable;
10334
10335 msg.type = WMA_IPA_OFFLOAD_ENABLE_DISABLE;
10336 msg.reserved = 0;
10337 msg.bodyptr = request_buf;
10338 if (!CDF_IS_STATUS_SUCCESS(
10339 cds_mq_post_message(CDS_MQ_ID_WMA, &msg))) {
10340 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
10341 FL("Not able to post WMA_IPA_OFFLOAD_\
10342 ENABLE_DISABLE message to WMA"));
10343 cdf_mem_free(request_buf);
10344 sme_release_global_lock(&pMac->sme);
10345 return CDF_STATUS_E_FAILURE;
10346 }
10347
10348 sme_release_global_lock(&pMac->sme);
10349 }
10350
10351 return CDF_STATUS_SUCCESS;
10352}
10353#endif /* IPA_OFFLOAD */
10354
10355/*
10356 * SME API to check if there is any infra station or
10357 * P2P client is connected
10358 */
10359CDF_STATUS sme_is_sta_p2p_client_connected(tHalHandle hHal)
10360{
10361 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
10362 if (csr_is_infra_connected(pMac)) {
10363 return CDF_STATUS_SUCCESS;
10364 }
10365 return CDF_STATUS_E_FAILURE;
10366}
10367
10368#ifdef FEATURE_WLAN_LPHB
10369/* ---------------------------------------------------------------------------
10370 \fn sme_lphb_config_req
10371 \API to make configuration LPHB within FW.
10372 \param hHal - The handle returned by mac_open
10373 \param lphdReq - LPHB request argument by client
10374 \param pCallbackfn - LPHB timeout notification callback function pointer
10375 \- return Configuration message posting status, SUCCESS or Fail
10376 -------------------------------------------------------------------------*/
10377CDF_STATUS sme_lphb_config_req
10378 (tHalHandle hHal,
10379 tSirLPHBReq *lphdReq,
10380 void (*pCallbackfn)(void *pHddCtx, tSirLPHBInd *indParam)
10381 ) {
10382 CDF_STATUS status = CDF_STATUS_SUCCESS;
10383 CDF_STATUS cdf_status = CDF_STATUS_SUCCESS;
10384 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
10385 cds_msg_t cds_message;
10386
10387 status = sme_acquire_global_lock(&pMac->sme);
10388 if (CDF_STATUS_SUCCESS == status) {
10389 if ((LPHB_SET_EN_PARAMS_INDID == lphdReq->cmd) &&
10390 (NULL == pCallbackfn) && (NULL == pMac->sme.pLphbIndCb)) {
10391 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
10392 "%s: Indication Call back did not registered",
10393 __func__);
10394 sme_release_global_lock(&pMac->sme);
10395 return CDF_STATUS_E_FAILURE;
10396 } else if (NULL != pCallbackfn) {
10397 pMac->sme.pLphbIndCb = pCallbackfn;
10398 }
10399
10400 /* serialize the req through MC thread */
10401 cds_message.bodyptr = lphdReq;
10402 cds_message.type = WMA_LPHB_CONF_REQ;
10403 cdf_status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message);
10404 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
10405 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
10406 "%s: Post Config LPHB MSG fail", __func__);
10407 status = CDF_STATUS_E_FAILURE;
10408 }
10409 sme_release_global_lock(&pMac->sme);
10410 }
10411
10412 return status;
10413}
10414#endif /* FEATURE_WLAN_LPHB */
10415/*--------------------------------------------------------------------------
10416 \brief sme_enable_disable_split_scan() - a wrapper function to set the split
10417 scan parameter.
10418 This is a synchronous call
10419 \param hHal - The handle returned by mac_open
10420 \return NONE.
10421 \sa
10422 --------------------------------------------------------------------------*/
10423void sme_enable_disable_split_scan(tHalHandle hHal, uint8_t nNumStaChan,
10424 uint8_t nNumP2PChan)
10425{
10426 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
10427
10428 pMac->roam.configParam.nNumStaChanCombinedConc = nNumStaChan;
10429 pMac->roam.configParam.nNumP2PChanCombinedConc = nNumP2PChan;
10430
10431 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_INFO,
10432 "%s: SCAN nNumStaChanCombinedConc : %d,"
10433 "nNumP2PChanCombinedConc : %d ",
10434 __func__, nNumStaChan, nNumP2PChan);
10435
10436 return;
10437
10438}
10439
10440/**
10441 * sme_add_periodic_tx_ptrn() - Add Periodic TX Pattern
10442 * @hal: global hal handle
10443 * @addPeriodicTxPtrnParams: request message
10444 *
10445 * Return: CDF_STATUS enumeration
10446 */
10447CDF_STATUS
10448sme_add_periodic_tx_ptrn(tHalHandle hal,
10449 struct sSirAddPeriodicTxPtrn *addPeriodicTxPtrnParams)
10450{
10451 CDF_STATUS status = CDF_STATUS_SUCCESS;
10452 tpAniSirGlobal mac = PMAC_STRUCT(hal);
10453 struct sSirAddPeriodicTxPtrn *req_msg;
10454 cds_msg_t msg;
10455
10456 sms_log(mac, LOG1, FL("enter"));
10457
10458 req_msg = cdf_mem_malloc(sizeof(*req_msg));
10459 if (!req_msg) {
10460 sms_log(mac, LOGE, FL("memory allocation failed"));
10461 return CDF_STATUS_E_NOMEM;
10462 }
10463
10464 *req_msg = *addPeriodicTxPtrnParams;
10465
10466 status = sme_acquire_global_lock(&mac->sme);
10467 if (!CDF_IS_STATUS_SUCCESS(status)) {
10468 sms_log(mac, LOGE,
10469 FL("sme_acquire_global_lock failed!(status=%d)"),
10470 status);
10471 cdf_mem_free(req_msg);
10472 return status;
10473 }
10474
10475 /* Serialize the req through MC thread */
10476 msg.bodyptr = req_msg;
10477 msg.type = WMA_ADD_PERIODIC_TX_PTRN_IND;
10478 status = cds_mq_post_message(CDF_MODULE_ID_WMA, &msg);
10479 if (!CDF_IS_STATUS_SUCCESS(status)) {
10480 sms_log(mac, LOGE,
10481 FL("cds_mq_post_message failed!(err=%d)"),
10482 status);
10483 cdf_mem_free(req_msg);
10484 }
10485 sme_release_global_lock(&mac->sme);
10486 return status;
10487}
10488
10489/**
10490 * sme_del_periodic_tx_ptrn() - Delete Periodic TX Pattern
10491 * @hal: global hal handle
10492 * @delPeriodicTxPtrnParams: request message
10493 *
10494 * Return: CDF_STATUS enumeration
10495 */
10496CDF_STATUS
10497sme_del_periodic_tx_ptrn(tHalHandle hal,
10498 struct sSirDelPeriodicTxPtrn *delPeriodicTxPtrnParams)
10499{
10500 CDF_STATUS status = CDF_STATUS_SUCCESS;
10501 tpAniSirGlobal mac = PMAC_STRUCT(hal);
10502 struct sSirDelPeriodicTxPtrn *req_msg;
10503 cds_msg_t msg;
10504
10505 sms_log(mac, LOG1, FL("enter"));
10506
10507 req_msg = cdf_mem_malloc(sizeof(*req_msg));
10508 if (!req_msg) {
10509 sms_log(mac, LOGE, FL("memory allocation failed"));
10510 return CDF_STATUS_E_NOMEM;
10511 }
10512
10513 *req_msg = *delPeriodicTxPtrnParams;
10514
10515 status = sme_acquire_global_lock(&mac->sme);
10516 if (!CDF_IS_STATUS_SUCCESS(status)) {
10517 sms_log(mac, LOGE,
10518 FL("sme_acquire_global_lock failed!(status=%d)"),
10519 status);
10520 cdf_mem_free(req_msg);
10521 return status;
10522 }
10523
10524 /* Serialize the req through MC thread */
10525 msg.bodyptr = req_msg;
10526 msg.type = WMA_DEL_PERIODIC_TX_PTRN_IND;
10527 status = cds_mq_post_message(CDF_MODULE_ID_WMA, &msg);
10528 if (!CDF_IS_STATUS_SUCCESS(status)) {
10529 sms_log(mac, LOGE,
10530 FL("cds_mq_post_message failed!(err=%d)"),
10531 status);
10532 cdf_mem_free(req_msg);
10533 }
10534 sme_release_global_lock(&mac->sme);
10535 return status;
10536}
10537
10538void sme_get_command_q_status(tHalHandle hHal)
10539{
10540 tSmeCmd *pTempCmd = NULL;
10541 tListElem *pEntry;
10542 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
10543
10544 if (NULL == pMac) {
10545 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
10546 "%s: pMac is NULL", __func__);
10547 return;
10548 }
10549
10550 pEntry = csr_ll_peek_head(&pMac->sme.smeCmdActiveList, LL_ACCESS_LOCK);
10551 if (pEntry) {
10552 pTempCmd = GET_BASE_ADDR(pEntry, tSmeCmd, Link);
10553 }
10554 sms_log(pMac, LOGE, "Currently smeCmdActiveList has command (0x%X)",
10555 (pTempCmd) ? pTempCmd->command : eSmeNoCommand);
10556 if (pTempCmd) {
10557 if (eSmeCsrCommandMask & pTempCmd->command) {
10558 /* CSR command is stuck. See what the reason code is for that command */
10559 dump_csr_command_info(pMac, pTempCmd);
10560 }
10561 } /* if(pTempCmd) */
10562
10563 sms_log(pMac, LOGE, "Currently smeCmdPendingList has %d commands",
10564 csr_ll_count(&pMac->sme.smeCmdPendingList));
10565
10566 sms_log(pMac, LOGE, "Currently roamCmdPendingList has %d commands",
10567 csr_ll_count(&pMac->roam.roamCmdPendingList));
10568
10569 return;
10570}
10571
10572/**
10573 * sme_set_dot11p_config() - API to set the 802.11p config
10574 * @hHal: The handle returned by macOpen
10575 * @enable_dot11p: 802.11p config param
10576 */
10577void sme_set_dot11p_config(tHalHandle hHal, bool enable_dot11p)
10578{
10579 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
10580 pMac->enable_dot11p = enable_dot11p;
10581}
10582
10583/**
10584 * copy_sir_ocb_config() - Performs deep copy of an OCB configuration
10585 * @src: the source configuration
10586 *
10587 * Return: pointer to the copied OCB configuration
10588 */
10589static struct sir_ocb_config *sme_copy_sir_ocb_config(
10590 struct sir_ocb_config *src)
10591{
10592 struct sir_ocb_config *dst;
10593 uint32_t length;
10594 void *cursor;
10595
10596 length = sizeof(*src) +
10597 src->channel_count * sizeof(*src->channels) +
10598 src->schedule_size * sizeof(*src->schedule) +
10599 src->dcc_ndl_chan_list_len +
10600 src->dcc_ndl_active_state_list_len;
10601
10602 dst = cdf_mem_malloc(length);
10603 if (!dst)
10604 return NULL;
10605
10606 *dst = *src;
10607
10608 cursor = dst;
10609 cursor += sizeof(*dst);
10610 dst->channels = cursor;
10611 cursor += src->channel_count * sizeof(*src->channels);
10612 cdf_mem_copy(dst->channels, src->channels,
10613 src->channel_count * sizeof(*src->channels));
10614 dst->schedule = cursor;
10615 cursor += src->schedule_size * sizeof(*src->schedule);
10616 cdf_mem_copy(dst->schedule, src->schedule,
10617 src->schedule_size * sizeof(*src->schedule));
10618 dst->dcc_ndl_chan_list = cursor;
10619 cursor += src->dcc_ndl_chan_list_len;
10620 cdf_mem_copy(dst->dcc_ndl_chan_list, src->dcc_ndl_chan_list,
10621 src->dcc_ndl_chan_list_len);
10622 dst->dcc_ndl_active_state_list = cursor;
10623 cursor += src->dcc_ndl_active_state_list_len;
10624 cdf_mem_copy(dst->dcc_ndl_active_state_list,
10625 src->dcc_ndl_active_state_list,
10626 src->dcc_ndl_active_state_list_len);
10627 return dst;
10628}
10629
10630/**
10631 * sme_ocb_set_config() - Set the OCB configuration
10632 * @hHal: reference to the HAL
10633 * @context: the context of the call
10634 * @callback: the callback to hdd
10635 * @config: the OCB configuration
10636 *
10637 * Return: CDF_STATUS_SUCCESS on success, CDF_STATUS_E_FAILURE on failure
10638 */
10639CDF_STATUS sme_ocb_set_config(tHalHandle hHal, void *context,
10640 ocb_callback callback,
10641 struct sir_ocb_config *config)
10642{
10643 CDF_STATUS status = CDF_STATUS_E_FAILURE;
10644 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
10645 cds_msg_t msg = {0};
10646 struct sir_ocb_config *msg_body;
10647
10648 /* Lock the SME structure */
10649 status = sme_acquire_global_lock(&pMac->sme);
10650 if (!CDF_IS_STATUS_SUCCESS(status))
10651 return status;
10652
10653 /*
10654 * Check if there is a pending request and return an error if one
10655 * exists
10656 */
10657 if (pMac->sme.ocb_set_config_callback) {
10658 status = CDF_STATUS_E_BUSY;
10659 goto end;
10660 }
10661
10662 msg_body = sme_copy_sir_ocb_config(config);
10663
10664 if (!msg_body) {
10665 status = CDF_STATUS_E_NOMEM;
10666 goto end;
10667 }
10668
10669 msg.type = WMA_OCB_SET_CONFIG_CMD;
10670 msg.bodyptr = msg_body;
10671
10672 /* Set the request callback and context */
10673 pMac->sme.ocb_set_config_callback = callback;
10674 pMac->sme.ocb_set_config_context = context;
10675
10676 status = cds_mq_post_message(CDF_MODULE_ID_WMA, &msg);
10677 if (!CDF_IS_STATUS_SUCCESS(status)) {
10678 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
10679 FL("Error posting message to WDA: %d"), status);
10680 pMac->sme.ocb_set_config_callback = callback;
10681 pMac->sme.ocb_set_config_context = context;
10682 cdf_mem_free(msg_body);
10683 goto end;
10684 }
10685
10686end:
10687 sme_release_global_lock(&pMac->sme);
10688
10689 return status;
10690}
10691
10692/**
10693 * sme_ocb_set_utc_time() - Set the OCB UTC time
10694 * @hHal: reference to the HAL
10695 * @utc: the UTC time struct
10696 *
10697 * Return: CDF_STATUS_SUCCESS on success, CDF_STATUS_E_FAILURE on failure
10698 */
10699CDF_STATUS sme_ocb_set_utc_time(tHalHandle hHal, struct sir_ocb_utc *utc)
10700{
10701 CDF_STATUS status = CDF_STATUS_E_FAILURE;
10702 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
10703 cds_msg_t msg = {0};
10704 struct sir_ocb_utc *sme_utc;
10705
10706 /* Lock the SME structure */
10707 status = sme_acquire_global_lock(&pMac->sme);
10708 if (!CDF_IS_STATUS_SUCCESS(status))
10709 return status;
10710
10711 sme_utc = cdf_mem_malloc(sizeof(*sme_utc));
10712 if (!sme_utc) {
10713 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
10714 FL("Malloc failed"));
10715 status = CDF_STATUS_E_NOMEM;
10716 goto end;
10717 }
10718 *sme_utc = *utc;
10719
10720 msg.type = WMA_OCB_SET_UTC_TIME_CMD;
10721 msg.reserved = 0;
10722 msg.bodyptr = sme_utc;
10723 status = cds_mq_post_message(CDF_MODULE_ID_WMA, &msg);
10724 if (!CDF_IS_STATUS_SUCCESS(status)) {
10725 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
10726 FL("Not able to post message to WDA"));
10727 cdf_mem_free(utc);
10728 goto end;
10729 }
10730
10731end:
10732 sme_release_global_lock(&pMac->sme);
10733
10734 return status;
10735}
10736
10737/**
10738 * sme_ocb_start_timing_advert() - Start sending timing advert frames
10739 * @hHal: reference to the HAL
10740 * @timing_advert: the timing advertisement struct
10741 *
10742 * Return: CDF_STATUS_SUCCESS on success, CDF_STATUS_E_FAILURE on failure
10743 */
10744CDF_STATUS sme_ocb_start_timing_advert(tHalHandle hHal,
10745 struct sir_ocb_timing_advert *timing_advert)
10746{
10747 CDF_STATUS status = CDF_STATUS_E_FAILURE;
10748 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
10749 cds_msg_t msg = {0};
10750 void *buf;
10751 struct sir_ocb_timing_advert *sme_timing_advert;
10752
10753 /* Lock the SME structure */
10754 status = sme_acquire_global_lock(&pMac->sme);
10755 if (!CDF_IS_STATUS_SUCCESS(status))
10756 return status;
10757
10758 buf = cdf_mem_malloc(sizeof(*sme_timing_advert) +
10759 timing_advert->template_length);
10760 if (!buf) {
10761 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
10762 FL("Not able to allocate memory for start TA"));
10763 status = CDF_STATUS_E_NOMEM;
10764 goto end;
10765 }
10766
10767 sme_timing_advert = (struct sir_ocb_timing_advert *)buf;
10768 *sme_timing_advert = *timing_advert;
10769 sme_timing_advert->template_value = buf + sizeof(*sme_timing_advert);
10770 cdf_mem_copy(sme_timing_advert->template_value,
10771 timing_advert->template_value, timing_advert->template_length);
10772
10773 msg.type = WMA_OCB_START_TIMING_ADVERT_CMD;
10774 msg.reserved = 0;
10775 msg.bodyptr = buf;
10776 status = cds_mq_post_message(CDF_MODULE_ID_WMA, &msg);
10777 if (!CDF_IS_STATUS_SUCCESS(status)) {
10778 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
10779 FL("Not able to post msg to WDA"));
10780 goto end;
10781 }
10782
10783end:
10784 sme_release_global_lock(&pMac->sme);
10785
10786 return status;
10787}
10788
10789/**
10790 * sme_ocb_stop_timing_advert() - Stop sending timing advert frames on a channel
10791 * @hHal: reference to the HAL
10792 * @timing_advert: the timing advertisement struct
10793 *
10794 * Return: CDF_STATUS_SUCCESS on success, CDF_STATUS_E_FAILURE on failure
10795 */
10796CDF_STATUS sme_ocb_stop_timing_advert(tHalHandle hHal,
10797 struct sir_ocb_timing_advert *timing_advert)
10798{
10799 CDF_STATUS status = CDF_STATUS_E_FAILURE;
10800 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
10801 cds_msg_t msg = {0};
10802 struct sir_ocb_timing_advert *sme_timing_advert;
10803
10804 /* Lock the SME structure */
10805 status = sme_acquire_global_lock(&pMac->sme);
10806 if (!CDF_IS_STATUS_SUCCESS(status))
10807 return status;
10808
10809 sme_timing_advert = cdf_mem_malloc(sizeof(*timing_advert));
10810 if (!sme_timing_advert) {
10811 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
10812 FL("Not able to allocate memory for stop TA"));
10813 status = CDF_STATUS_E_NOMEM;
10814 goto end;
10815 }
10816 *sme_timing_advert = *timing_advert;
10817
10818 msg.type = WMA_OCB_STOP_TIMING_ADVERT_CMD;
10819 msg.reserved = 0;
10820 msg.bodyptr = sme_timing_advert;
10821 status = cds_mq_post_message(CDF_MODULE_ID_WMA, &msg);
10822 if (!CDF_IS_STATUS_SUCCESS(status)) {
10823 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
10824 FL("Not able to post msg to WDA"));
10825 goto end;
10826 }
10827
10828end:
10829 sme_release_global_lock(&pMac->sme);
10830
10831 return status;
10832}
10833
10834/**
10835 * sme_ocb_get_tsf_timer() - Get the TSF timer value
10836 * @hHal: reference to the HAL
10837 * @context: the context of the call
10838 * @callback: the callback to hdd
10839 * @request: the TSF timer request
10840 *
10841 * Return: CDF_STATUS_SUCCESS on success, CDF_STATUS_E_FAILURE on failure
10842 */
10843CDF_STATUS sme_ocb_get_tsf_timer(tHalHandle hHal, void *context,
10844 ocb_callback callback,
10845 struct sir_ocb_get_tsf_timer *request)
10846{
10847 CDF_STATUS status = CDF_STATUS_E_FAILURE;
10848 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
10849 cds_msg_t msg = {0};
10850 struct sir_ocb_get_tsf_timer *msg_body;
10851
10852 /* Lock the SME structure */
10853 status = sme_acquire_global_lock(&pMac->sme);
10854 if (!CDF_IS_STATUS_SUCCESS(status))
10855 return status;
10856
10857 /* Allocate memory for the WMI request, and copy the parameter */
10858 msg_body = cdf_mem_malloc(sizeof(*msg_body));
10859 if (!msg_body) {
10860 status = CDF_STATUS_E_NOMEM;
10861 goto end;
10862 }
10863 *msg_body = *request;
10864
10865 msg.type = WMA_OCB_GET_TSF_TIMER_CMD;
10866 msg.bodyptr = msg_body;
10867
10868 /* Set the request callback and the context */
10869 pMac->sme.ocb_get_tsf_timer_callback = callback;
10870 pMac->sme.ocb_get_tsf_timer_context = context;
10871
10872 /* Post the message to WDA */
10873 status = cds_mq_post_message(CDF_MODULE_ID_WMA, &msg);
10874 if (!CDF_IS_STATUS_SUCCESS(status)) {
10875 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
10876 FL("Error posting message to WDA: %d"), status);
10877 pMac->sme.ocb_get_tsf_timer_callback = NULL;
10878 pMac->sme.ocb_get_tsf_timer_context = NULL;
10879 cdf_mem_free(msg_body);
10880 goto end;
10881 }
10882
10883end:
10884 sme_release_global_lock(&pMac->sme);
10885
10886 return status;
10887}
10888
10889/**
10890 * sme_dcc_get_stats() - Get the DCC stats
10891 * @hHal: reference to the HAL
10892 * @context: the context of the call
10893 * @callback: the callback to hdd
10894 * @request: the get DCC stats request
10895 *
10896 * Return: CDF_STATUS_SUCCESS on success, CDF_STATUS_E_FAILURE on failure
10897 */
10898CDF_STATUS sme_dcc_get_stats(tHalHandle hHal, void *context,
10899 ocb_callback callback,
10900 struct sir_dcc_get_stats *request)
10901{
10902 CDF_STATUS status = CDF_STATUS_E_FAILURE;
10903 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
10904 cds_msg_t msg = {0};
10905 struct sir_dcc_get_stats *msg_body;
10906
10907 /* Lock the SME structure */
10908 status = sme_acquire_global_lock(&pMac->sme);
10909 if (!CDF_IS_STATUS_SUCCESS(status))
10910 return status;
10911
10912 /* Allocate memory for the WMI request, and copy the parameter */
10913 msg_body = cdf_mem_malloc(sizeof(*msg_body) +
10914 request->request_array_len);
10915 if (!msg_body) {
10916 status = CDF_STATUS_E_NOMEM;
10917 goto end;
10918 }
10919 *msg_body = *request;
10920 msg_body->request_array = (void *)msg_body + sizeof(*msg_body);
10921 cdf_mem_copy(msg_body->request_array, request->request_array,
10922 request->request_array_len);
10923
10924 msg.type = WMA_DCC_GET_STATS_CMD;
10925 msg.bodyptr = msg_body;
10926
10927 /* Set the request callback and context */
10928 pMac->sme.dcc_get_stats_callback = callback;
10929 pMac->sme.dcc_get_stats_context = context;
10930
10931 status = cds_mq_post_message(CDF_MODULE_ID_WMA, &msg);
10932 if (!CDF_IS_STATUS_SUCCESS(status)) {
10933 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
10934 FL("Error posting message to WDA: %d"), status);
10935 pMac->sme.dcc_get_stats_callback = callback;
10936 pMac->sme.dcc_get_stats_context = context;
10937 cdf_mem_free(msg_body);
10938 goto end;
10939 }
10940
10941end:
10942 sme_release_global_lock(&pMac->sme);
10943
10944 return status;
10945}
10946
10947/**
10948 * sme_dcc_clear_stats() - Clear the DCC stats
10949 * @hHal: reference to the HAL
10950 * @vdev_id: vdev id for OCB interface
10951 * @dcc_stats_bitmap: the entries in the stats to clear
10952 *
10953 * Return: CDF_STATUS_SUCCESS on success, CDF_STATUS_E_FAILURE on failure
10954 */
10955CDF_STATUS sme_dcc_clear_stats(tHalHandle hHal, uint32_t vdev_id,
10956 uint32_t dcc_stats_bitmap)
10957{
10958 CDF_STATUS status = CDF_STATUS_E_FAILURE;
10959 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
10960 cds_msg_t msg = {0};
10961 struct sir_dcc_clear_stats *request;
10962
10963 /* Lock the SME structure */
10964 status = sme_acquire_global_lock(&pMac->sme);
10965 if (!CDF_IS_STATUS_SUCCESS(status))
10966 return status;
10967
10968 request = cdf_mem_malloc(sizeof(struct sir_dcc_clear_stats));
10969 if (!request) {
10970 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
10971 FL("Not able to allocate memory"));
10972 status = CDF_STATUS_E_NOMEM;
10973 goto end;
10974 }
10975
10976 cdf_mem_zero(request, sizeof(*request));
10977 request->vdev_id = vdev_id;
10978 request->dcc_stats_bitmap = dcc_stats_bitmap;
10979
10980 msg.type = WMA_DCC_CLEAR_STATS_CMD;
10981 msg.bodyptr = request;
10982
10983 status = cds_mq_post_message(CDF_MODULE_ID_WMA, &msg);
10984 if (!CDF_IS_STATUS_SUCCESS(status)) {
10985 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
10986 FL("Not able to post msg to WDA"));
10987 cdf_mem_free(request);
10988 goto end;
10989 }
10990
10991end:
10992 sme_release_global_lock(&pMac->sme);
10993
10994 return status;
10995}
10996
10997/**
10998 * sme_dcc_update_ndl() - Update the DCC settings
10999 * @hHal: reference to the HAL
11000 * @context: the context of the call
11001 * @callback: the callback to hdd
11002 * @request: the update DCC request
11003 *
11004 * Return: CDF_STATUS_SUCCESS on success, CDF_STATUS_E_FAILURE on failure
11005 */
11006CDF_STATUS sme_dcc_update_ndl(tHalHandle hHal, void *context,
11007 ocb_callback callback,
11008 struct sir_dcc_update_ndl *request)
11009{
11010 CDF_STATUS status = CDF_STATUS_E_FAILURE;
11011 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
11012 cds_msg_t msg = {0};
11013 struct sir_dcc_update_ndl *msg_body;
11014
11015 /* Lock the SME structure */
11016 status = sme_acquire_global_lock(&pMac->sme);
11017 if (!CDF_IS_STATUS_SUCCESS(status))
11018 return status;
11019
11020 /* Allocate memory for the WMI request, and copy the parameter */
11021 msg_body = cdf_mem_malloc(sizeof(*msg_body) +
11022 request->dcc_ndl_chan_list_len +
11023 request->dcc_ndl_active_state_list_len);
11024 if (!msg_body) {
11025 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
11026 FL("Failed to allocate memory"));
11027 status = CDF_STATUS_E_NOMEM;
11028 goto end;
11029 }
11030
11031 *msg_body = *request;
11032
11033 msg_body->dcc_ndl_chan_list = (void *)msg_body + sizeof(*msg_body);
11034 msg_body->dcc_ndl_active_state_list = msg_body->dcc_ndl_chan_list +
11035 request->dcc_ndl_chan_list_len;
11036 cdf_mem_copy(msg_body->dcc_ndl_chan_list, request->dcc_ndl_chan_list,
11037 request->dcc_ndl_active_state_list_len);
11038 cdf_mem_copy(msg_body->dcc_ndl_active_state_list,
11039 request->dcc_ndl_active_state_list,
11040 request->dcc_ndl_active_state_list_len);
11041
11042 msg.type = WMA_DCC_UPDATE_NDL_CMD;
11043 msg.bodyptr = msg_body;
11044
11045 /* Set the request callback and the context */
11046 pMac->sme.dcc_update_ndl_callback = callback;
11047 pMac->sme.dcc_update_ndl_context = context;
11048
11049 status = cds_mq_post_message(CDF_MODULE_ID_WMA, &msg);
11050 if (!CDF_IS_STATUS_SUCCESS(status)) {
11051 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
11052 FL("Error posting message to WDA: %d"), status);
11053 pMac->sme.dcc_update_ndl_callback = NULL;
11054 pMac->sme.dcc_update_ndl_context = NULL;
11055 cdf_mem_free(msg_body);
11056 goto end;
11057 }
11058
11059end:
11060 sme_release_global_lock(&pMac->sme);
11061
11062 return status;
11063}
11064
11065/**
11066 * sme_register_for_dcc_stats_event() - Register for the periodic DCC stats
11067 * event
11068 * @hHal: reference to the HAL
11069 * @context: the context of the call
11070 * @callback: the callback to hdd
11071 *
11072 * Return: CDF_STATUS_SUCCESS on success, CDF_STATUS_E_FAILURE on failure
11073 */
11074CDF_STATUS sme_register_for_dcc_stats_event(tHalHandle hHal, void *context,
11075 ocb_callback callback)
11076{
11077 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
11078 CDF_STATUS status = CDF_STATUS_E_FAILURE;
11079
11080 status = sme_acquire_global_lock(&pMac->sme);
11081 pMac->sme.dcc_stats_event_callback = callback;
11082 pMac->sme.dcc_stats_event_context = context;
11083 sme_release_global_lock(&pMac->sme);
11084
11085 return 0;
11086}
11087
11088void sme_get_recovery_stats(tHalHandle hHal)
11089{
11090 uint8_t i;
11091
11092 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
11093 "Self Recovery Stats");
11094 for (i = 0; i < MAX_ACTIVE_CMD_STATS; i++) {
11095 if (eSmeNoCommand !=
11096 g_self_recovery_stats.activeCmdStats[i].command) {
11097 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
11098 "timestamp %llu: command 0x%0X: reason %d: session %d",
11099 g_self_recovery_stats.activeCmdStats[i].
11100 timestamp,
11101 g_self_recovery_stats.activeCmdStats[i].command,
11102 g_self_recovery_stats.activeCmdStats[i].reason,
11103 g_self_recovery_stats.activeCmdStats[i].
11104 sessionId);
11105 }
11106 }
11107}
11108
11109/**
11110 * sme_save_active_cmd_stats() - To save active command stats
11111 * @hHal: HAL context
11112 *
11113 * This routine is to save active command stats
11114 *
11115 * Return: None
11116 */
11117void sme_save_active_cmd_stats(tHalHandle hHal)
11118{
11119 tSmeCmd *pTempCmd = NULL;
11120 tListElem *pEntry;
11121 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
11122 uint8_t statidx = 0;
11123 tActiveCmdStats *actv_cmd_stat = NULL;
11124
11125 if (NULL == pMac) {
11126 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
11127 FL("pMac is NULL"));
11128 return;
11129 }
11130
11131 pEntry = csr_ll_peek_head(&pMac->sme.smeCmdActiveList, LL_ACCESS_LOCK);
11132 if (pEntry)
11133 pTempCmd = GET_BASE_ADDR(pEntry, tSmeCmd, Link);
11134
11135 if (!pTempCmd)
11136 return;
11137
11138 if (eSmeCsrCommandMask & pTempCmd->command) {
11139 statidx = g_self_recovery_stats.cmdStatsIndx;
11140 actv_cmd_stat = &g_self_recovery_stats.activeCmdStats[statidx];
11141 actv_cmd_stat->command = pTempCmd->command;
11142 actv_cmd_stat->sessionId = pTempCmd->sessionId;
11143 actv_cmd_stat->timestamp = cds_get_monotonic_boottime();
11144 if (eSmeCommandRoam == pTempCmd->command)
11145 actv_cmd_stat->reason = pTempCmd->u.roamCmd.roamReason;
11146 else if (eSmeCommandScan == pTempCmd->command)
11147 actv_cmd_stat->reason = pTempCmd->u.scanCmd.reason;
11148 else
11149 actv_cmd_stat->reason = 0xFF;
11150
11151 g_self_recovery_stats.cmdStatsIndx =
11152 ((g_self_recovery_stats.cmdStatsIndx + 1) &
11153 (MAX_ACTIVE_CMD_STATS - 1));
11154 }
11155 return;
11156}
11157
11158void active_list_cmd_timeout_handle(void *userData)
11159{
11160 if (NULL == userData)
11161 return;
11162 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
11163 "%s: Active List command timeout Cmd List Count %d", __func__,
11164 csr_ll_count(&((tpAniSirGlobal) userData)->sme.
11165 smeCmdActiveList));
11166 sme_get_command_q_status((tHalHandle) userData);
11167
11168 if (((tpAniSirGlobal) userData)->sme.enableSelfRecovery) {
11169 sme_save_active_cmd_stats((tHalHandle) userData);
11170 cds_trigger_recovery();
11171 } else {
11172 CDF_BUG(0);
11173 }
11174}
11175
11176CDF_STATUS sme_notify_modem_power_state(tHalHandle hHal, uint32_t value)
11177{
11178 cds_msg_t msg;
11179 tpSirModemPowerStateInd request_buf;
11180 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
11181
11182 if (NULL == pMac) {
11183 return CDF_STATUS_E_FAILURE;
11184 }
11185
11186 request_buf = cdf_mem_malloc(sizeof(tSirModemPowerStateInd));
11187 if (NULL == request_buf) {
11188 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
11189 "%s: Not able to allocate memory for MODEM POWER STATE IND",
11190 __func__);
11191 return CDF_STATUS_E_NOMEM;
11192 }
11193
11194 request_buf->param = value;
11195
11196 msg.type = WMA_MODEM_POWER_STATE_IND;
11197 msg.reserved = 0;
11198 msg.bodyptr = request_buf;
11199 if (!CDF_IS_STATUS_SUCCESS
11200 (cds_mq_post_message(CDF_MODULE_ID_WMA, &msg))) {
11201 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
11202 "%s: Not able to post WMA_MODEM_POWER_STATE_IND message"
11203 " to WMA", __func__);
11204 cdf_mem_free(request_buf);
11205 return CDF_STATUS_E_FAILURE;
11206 }
11207
11208 return CDF_STATUS_SUCCESS;
11209}
11210
11211#ifdef QCA_HT_2040_COEX
11212CDF_STATUS sme_notify_ht2040_mode(tHalHandle hHal, uint16_t staId,
11213 struct cdf_mac_addr macAddrSTA,
11214 uint8_t sessionId,
11215 uint8_t channel_type)
11216{
11217 cds_msg_t msg;
11218 tUpdateVHTOpMode *pHtOpMode = NULL;
11219 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
11220
11221 if (NULL == pMac) {
11222 return CDF_STATUS_E_FAILURE;
11223 }
11224
11225 pHtOpMode = cdf_mem_malloc(sizeof(tUpdateVHTOpMode));
11226 if (NULL == pHtOpMode) {
11227 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
11228 "%s: Not able to allocate memory for setting OP mode",
11229 __func__);
11230 return CDF_STATUS_E_NOMEM;
11231 }
11232
11233 switch (channel_type) {
11234 case eHT_CHAN_HT20:
11235 pHtOpMode->opMode = eHT_CHANNEL_WIDTH_20MHZ;
11236 break;
11237
11238 case eHT_CHAN_HT40MINUS:
11239 case eHT_CHAN_HT40PLUS:
11240 pHtOpMode->opMode = eHT_CHANNEL_WIDTH_40MHZ;
11241 break;
11242
11243 default:
11244 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
11245 "%s: Invalid OP mode", __func__);
11246 return CDF_STATUS_E_FAILURE;
11247 }
11248
11249 pHtOpMode->staId = staId,
11250 cdf_mem_copy(pHtOpMode->peer_mac, macAddrSTA.bytes,
11251 sizeof(tSirMacAddr));
11252 pHtOpMode->smesessionId = sessionId;
11253
11254 msg.type = WMA_UPDATE_OP_MODE;
11255 msg.reserved = 0;
11256 msg.bodyptr = pHtOpMode;
11257 if (!CDF_IS_STATUS_SUCCESS
11258 (cds_mq_post_message(CDF_MODULE_ID_WMA, &msg))) {
11259 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
11260 "%s: Not able to post WMA_UPDATE_OP_MODE message"
11261 " to WMA", __func__);
11262 cdf_mem_free(pHtOpMode);
11263 return CDF_STATUS_E_FAILURE;
11264 }
11265
11266 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_INFO,
11267 "%s: Notifed FW about OP mode: %d for staId=%d",
11268 __func__, pHtOpMode->opMode, staId);
11269
11270 return CDF_STATUS_SUCCESS;
11271}
11272
11273/* ---------------------------------------------------------------------------
11274
11275 \fn sme_set_ht2040_mode
11276
11277 \brief To update HT Operation beacon IE.
11278
11279 \param
11280
11281 \return CDF_STATUS SUCCESS
11282 FAILURE or RESOURCES
11283 The API finished and failed.
11284
11285 -------------------------------------------------------------------------------*/
11286CDF_STATUS sme_set_ht2040_mode(tHalHandle hHal, uint8_t sessionId,
11287 uint8_t channel_type, bool obssEnabled)
11288{
11289 CDF_STATUS status = CDF_STATUS_E_FAILURE;
11290 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
11291 ePhyChanBondState cbMode;
11292
11293 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_INFO,
11294 "%s: Update HT operation beacon IE, channel_type=%d",
11295 __func__, channel_type);
11296
11297 switch (channel_type) {
11298 case eHT_CHAN_HT20:
11299 cbMode = PHY_SINGLE_CHANNEL_CENTERED;
11300 break;
11301 case eHT_CHAN_HT40MINUS:
11302 cbMode = PHY_DOUBLE_CHANNEL_HIGH_PRIMARY;
11303 break;
11304 case eHT_CHAN_HT40PLUS:
11305 cbMode = PHY_DOUBLE_CHANNEL_LOW_PRIMARY;
11306 break;
11307 default:
11308 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
11309 "%s:Error!!! Invalid HT20/40 mode !", __func__);
11310 return CDF_STATUS_E_FAILURE;
11311 }
11312 status = sme_acquire_global_lock(&pMac->sme);
11313 if (CDF_IS_STATUS_SUCCESS(status)) {
11314 status = csr_set_ht2040_mode(pMac, sessionId,
11315 cbMode, obssEnabled);
11316 sme_release_global_lock(&pMac->sme);
11317 }
11318 return status;
11319}
11320
11321/* ---------------------------------------------------------------------------
11322
11323 \fn sme_set_phy_cb_mode24_g
11324
11325 \brief Changes PHY channel bonding mode
11326
11327 \param hHal - The handle returned by mac_open.
11328
11329 \param cbMode new channel bonding mode which is to set
11330
11331 \return CDF_STATUS SUCCESS.
11332
11333 -------------------------------------------------------------------------------*/
11334CDF_STATUS sme_set_phy_cb_mode24_g(tHalHandle hHal, ePhyChanBondState phyCBMode)
11335{
11336 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
11337
11338 if (NULL == pMac) {
11339 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
11340 "%s: invalid context", __func__);
11341 return CDF_STATUS_E_FAILURE;
11342 }
11343
11344 pMac->roam.configParam.channelBondingMode24GHz = phyCBMode;
11345
11346 return CDF_STATUS_SUCCESS;
11347}
11348#endif
11349
11350/*
11351 * SME API to enable/disable idle mode powersave
11352 * This should be called only if powersave offload
11353 * is enabled
11354 */
11355CDF_STATUS sme_set_idle_powersave_config(void *cds_context,
11356 tHalHandle hHal, uint32_t value)
11357{
11358 void *wmaContext = cds_get_context(CDF_MODULE_ID_WMA);
11359 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
11360
11361 if (NULL == wmaContext) {
11362 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
11363 "%s: wmaContext is NULL", __func__);
11364 return CDF_STATUS_E_FAILURE;
11365 }
11366 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_DEBUG,
11367 " Idle Ps Set Value %d", value);
11368
11369 pMac->imps_enabled = false;
11370 if (CDF_STATUS_SUCCESS != wma_set_idle_ps_config(wmaContext, value)) {
11371 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
11372 " Failed to Set Idle Ps Value %d", value);
11373 return CDF_STATUS_E_FAILURE;
11374 }
11375 if (value)
11376 pMac->imps_enabled = true;
11377 return CDF_STATUS_SUCCESS;
11378}
11379
11380int16_t sme_get_ht_config(tHalHandle hHal, uint8_t session_id, uint16_t ht_capab)
11381{
11382 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
11383 tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, session_id);
11384
11385 if (NULL == pSession) {
11386 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
11387 "%s: pSession is NULL", __func__);
11388 return -EIO;
11389 }
11390 switch (ht_capab) {
11391 case WNI_CFG_HT_CAP_INFO_ADVANCE_CODING:
11392 return pSession->htConfig.ht_rx_ldpc;
11393 case WNI_CFG_HT_CAP_INFO_TX_STBC:
11394 return pSession->htConfig.ht_tx_stbc;
11395 case WNI_CFG_HT_CAP_INFO_RX_STBC:
11396 return pSession->htConfig.ht_rx_stbc;
11397 case WNI_CFG_HT_CAP_INFO_SHORT_GI_20MHZ:
11398 case WNI_CFG_HT_CAP_INFO_SHORT_GI_40MHZ:
11399 return pSession->htConfig.ht_sgi;
11400 default:
11401 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
11402 "invalid ht capability");
11403 return -EIO;
11404 }
11405}
11406
11407int sme_update_ht_config(tHalHandle hHal, uint8_t sessionId, uint16_t htCapab,
11408 int value)
11409{
11410 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
11411 tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
11412
11413 if (NULL == pSession) {
11414 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
11415 "%s: pSession is NULL", __func__);
11416 return -EIO;
11417 }
11418
11419 if (CDF_STATUS_SUCCESS != wma_set_htconfig(sessionId, htCapab, value)) {
11420 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
11421 "Failed to set ht capability in target");
11422 return -EIO;
11423 }
11424
11425 switch (htCapab) {
11426 case WNI_CFG_HT_CAP_INFO_ADVANCE_CODING:
11427 pSession->htConfig.ht_rx_ldpc = value;
11428 break;
11429 case WNI_CFG_HT_CAP_INFO_TX_STBC:
11430 pSession->htConfig.ht_tx_stbc = value;
11431 break;
11432 case WNI_CFG_HT_CAP_INFO_RX_STBC:
11433 pSession->htConfig.ht_rx_stbc = value;
11434 break;
11435 case WNI_CFG_HT_CAP_INFO_SHORT_GI_20MHZ:
11436 case WNI_CFG_HT_CAP_INFO_SHORT_GI_40MHZ:
11437 pSession->htConfig.ht_sgi = value;
11438 break;
11439 }
11440
11441 return 0;
11442}
11443
11444#define HT20_SHORT_GI_MCS7_RATE 722
11445/* ---------------------------------------------------------------------------
11446 \fn sme_send_rate_update_ind
11447 \brief API to Update rate
11448 \param hHal - The handle returned by mac_open
11449 \param rateUpdateParams - Pointer to rate update params
11450 \return CDF_STATUS
11451 ---------------------------------------------------------------------------*/
11452CDF_STATUS sme_send_rate_update_ind(tHalHandle hHal,
11453 tSirRateUpdateInd *rateUpdateParams)
11454{
11455 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
11456 CDF_STATUS status;
11457 cds_msg_t msg;
11458 tSirRateUpdateInd *rate_upd = cdf_mem_malloc(sizeof(tSirRateUpdateInd));
11459
11460 if (rate_upd == NULL) {
11461 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
11462 "Rate update struct alloc failed");
11463 return CDF_STATUS_E_FAILURE;
11464 }
11465 *rate_upd = *rateUpdateParams;
11466
11467 if (rate_upd->mcastDataRate24GHz == HT20_SHORT_GI_MCS7_RATE)
11468 rate_upd->mcastDataRate24GHzTxFlag =
11469 eHAL_TX_RATE_HT20 | eHAL_TX_RATE_SGI;
11470 else if (rate_upd->reliableMcastDataRate ==
11471 HT20_SHORT_GI_MCS7_RATE)
11472 rate_upd->reliableMcastDataRateTxFlag =
11473 eHAL_TX_RATE_HT20 | eHAL_TX_RATE_SGI;
11474
11475 status = sme_acquire_global_lock(&pMac->sme);
11476 if (CDF_STATUS_SUCCESS == status) {
11477 msg.type = WMA_RATE_UPDATE_IND;
11478 msg.bodyptr = rate_upd;
11479
11480 if (!CDF_IS_STATUS_SUCCESS
11481 (cds_mq_post_message(CDF_MODULE_ID_WMA, &msg))) {
11482 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
11483 "%s: Not able "
11484 "to post WMA_SET_RMC_RATE_IND to WMA!",
11485 __func__);
11486
11487 sme_release_global_lock(&pMac->sme);
11488 cdf_mem_free(rate_upd);
11489 return CDF_STATUS_E_FAILURE;
11490 }
11491
11492 sme_release_global_lock(&pMac->sme);
11493 return CDF_STATUS_SUCCESS;
11494 }
11495
11496 return status;
11497}
11498
11499/**
11500 * sme_get_reg_info() - To get registration info
11501 * @hHal: HAL context
11502 * @chanId: channel id
11503 * @regInfo1: first reg info to fill
11504 * @regInfo2: second reg info to fill
11505 *
11506 * This routine will give you reg info
11507 *
11508 * Return: CDF_STATUS
11509 */
11510CDF_STATUS sme_get_reg_info(tHalHandle hHal, uint8_t chanId,
11511 uint32_t *regInfo1, uint32_t *regInfo2)
11512{
11513 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
11514 CDF_STATUS status;
11515 uint8_t i;
11516 bool found = false;
11517
11518 status = sme_acquire_global_lock(&pMac->sme);
11519 *regInfo1 = 0;
11520 *regInfo2 = 0;
11521 if (!CDF_IS_STATUS_SUCCESS(status))
11522 return status;
11523
11524 for (i = 0; i < WNI_CFG_VALID_CHANNEL_LIST_LEN; i++) {
11525 if (pMac->scan.defaultPowerTable[i].chanId == chanId) {
11526 SME_SET_CHANNEL_REG_POWER(*regInfo1,
11527 pMac->scan.defaultPowerTable[i].pwr);
11528
11529 SME_SET_CHANNEL_MAX_TX_POWER(*regInfo2,
11530 pMac->scan.defaultPowerTable[i].pwr);
11531 found = true;
11532 break;
11533 }
11534 }
11535 if (!found)
11536 status = CDF_STATUS_E_FAILURE;
11537
11538 sme_release_global_lock(&pMac->sme);
11539 return status;
11540}
11541
11542#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
11543/* ---------------------------------------------------------------------------
11544 \fn sme_auto_shutdown_cb
11545 \brief Used to plug in callback function for receiving auto shutdown evt
11546 \param hHal
11547 \param pCallbackfn : callback function pointer should be plugged in
11548 \- return CDF_STATUS
11549 -------------------------------------------------------------------------*/
11550CDF_STATUS sme_set_auto_shutdown_cb(tHalHandle hHal, void (*pCallbackfn)(void)
11551 ) {
11552 CDF_STATUS status = CDF_STATUS_SUCCESS;
11553 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
11554
11555 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
11556 "%s: Plug in Auto shutdown event callback", __func__);
11557
11558 status = sme_acquire_global_lock(&pMac->sme);
11559 if (CDF_STATUS_SUCCESS == status) {
11560 if (NULL != pCallbackfn) {
11561 pMac->sme.pAutoShutdownNotificationCb = pCallbackfn;
11562 }
11563 sme_release_global_lock(&pMac->sme);
11564 }
11565
11566 return status;
11567}
11568
11569/* ---------------------------------------------------------------------------
11570 \fn sme_set_auto_shutdown_timer
11571 \API to set auto shutdown timer value in FW.
11572 \param hHal - The handle returned by mac_open
11573 \param timer_val - The auto shutdown timer value to be set
11574 \- return Configuration message posting status, SUCCESS or Fail
11575 -------------------------------------------------------------------------*/
11576CDF_STATUS sme_set_auto_shutdown_timer(tHalHandle hHal, uint32_t timer_val)
11577{
11578 CDF_STATUS status = CDF_STATUS_SUCCESS;
11579 CDF_STATUS cdf_status = CDF_STATUS_SUCCESS;
11580 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
11581 tSirAutoShutdownCmdParams *auto_sh_cmd;
11582 cds_msg_t cds_message;
11583
11584 status = sme_acquire_global_lock(&pMac->sme);
11585 if (CDF_STATUS_SUCCESS == status) {
11586 auto_sh_cmd = (tSirAutoShutdownCmdParams *)
11587 cdf_mem_malloc(sizeof(tSirAutoShutdownCmdParams));
11588 if (auto_sh_cmd == NULL) {
11589 CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_ERROR,
11590 "%s Request Buffer Alloc Fail", __func__);
11591 sme_release_global_lock(&pMac->sme);
11592 return CDF_STATUS_E_NOMEM;
11593 }
11594
11595 auto_sh_cmd->timer_val = timer_val;
11596
11597 /* serialize the req through MC thread */
11598 cds_message.bodyptr = auto_sh_cmd;
11599 cds_message.type = WMA_SET_AUTO_SHUTDOWN_TIMER_REQ;
11600 cdf_status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message);
11601 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
11602 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
11603 "%s: Post Auto shutdown MSG fail", __func__);
11604 cdf_mem_free(auto_sh_cmd);
11605 sme_release_global_lock(&pMac->sme);
11606 return CDF_STATUS_E_FAILURE;
11607 }
11608 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_INFO,
11609 "%s: Posted Auto shutdown MSG", __func__);
11610 sme_release_global_lock(&pMac->sme);
11611 }
11612
11613 return status;
11614}
11615#endif
11616
11617#ifdef FEATURE_WLAN_CH_AVOID
11618/* ---------------------------------------------------------------------------
11619 \fn sme_add_ch_avoid_callback
11620 \brief Used to plug in callback function
11621 Which notify channel may not be used with SAP or P2PGO mode.
11622 Notification come from FW.
11623 \param hHal
11624 \param pCallbackfn : callback function pointer should be plugged in
11625 \- return CDF_STATUS
11626 -------------------------------------------------------------------------*/
11627CDF_STATUS sme_add_ch_avoid_callback
11628 (tHalHandle hHal, void (*pCallbackfn)(void *pAdapter, void *indParam)
11629 ) {
11630 CDF_STATUS status = CDF_STATUS_SUCCESS;
11631 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
11632
11633 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
11634 "%s: Plug in CH AVOID CB", __func__);
11635
11636 status = sme_acquire_global_lock(&pMac->sme);
11637 if (CDF_STATUS_SUCCESS == status) {
11638 if (NULL != pCallbackfn) {
11639 pMac->sme.pChAvoidNotificationCb = pCallbackfn;
11640 }
11641 sme_release_global_lock(&pMac->sme);
11642 }
11643
11644 return status;
11645}
11646
11647/* ---------------------------------------------------------------------------
11648 \fn sme_ch_avoid_update_req
11649 \API to request channel avoidance update from FW.
11650 \param hHal - The handle returned by mac_open
11651 \param update_type - The udpate_type parameter of this request call
11652 \- return Configuration message posting status, SUCCESS or Fail
11653 -------------------------------------------------------------------------*/
11654CDF_STATUS sme_ch_avoid_update_req(tHalHandle hHal)
11655{
11656 CDF_STATUS status = CDF_STATUS_SUCCESS;
11657 CDF_STATUS cdf_status = CDF_STATUS_SUCCESS;
11658 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
11659 tSirChAvoidUpdateReq *cauReq;
11660 cds_msg_t cds_message;
11661
11662 status = sme_acquire_global_lock(&pMac->sme);
11663 if (CDF_STATUS_SUCCESS == status) {
11664 cauReq = (tSirChAvoidUpdateReq *)
11665 cdf_mem_malloc(sizeof(tSirChAvoidUpdateReq));
11666 if (NULL == cauReq) {
11667 CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_ERROR,
11668 "%s Request Buffer Alloc Fail", __func__);
11669 sme_release_global_lock(&pMac->sme);
11670 return CDF_STATUS_E_NOMEM;
11671 }
11672
11673 cauReq->reserved_param = 0;
11674
11675 /* serialize the req through MC thread */
11676 cds_message.bodyptr = cauReq;
11677 cds_message.type = WMA_CH_AVOID_UPDATE_REQ;
11678 cdf_status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message);
11679 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
11680 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
11681 "%s: Post Ch Avoid Update MSG fail",
11682 __func__);
11683 cdf_mem_free(cauReq);
11684 sme_release_global_lock(&pMac->sme);
11685 return CDF_STATUS_E_FAILURE;
11686 }
11687 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_INFO,
11688 "%s: Posted Ch Avoid Update MSG", __func__);
11689 sme_release_global_lock(&pMac->sme);
11690 }
11691
11692 return status;
11693}
11694#endif /* FEATURE_WLAN_CH_AVOID */
11695
11696/**
11697 * sme_set_miracast() - Function to set miracast value to UMAC
11698 * @hal: Handle returned by macOpen
11699 * @filter_type: 0-Disabled, 1-Source, 2-sink
11700 *
11701 * This function passes down the value of miracast set by
11702 * framework to UMAC
11703 *
11704 * Return: Configuration message posting status, SUCCESS or Fail
11705 *
11706 */
11707CDF_STATUS sme_set_miracast(tHalHandle hal, uint8_t filter_type)
11708{
11709 cds_msg_t msg;
11710 uint32_t *val;
11711 tpAniSirGlobal mac_ptr = PMAC_STRUCT(hal);
11712
11713 val = cdf_mem_malloc(sizeof(*val));
11714 if (NULL == val || NULL == mac_ptr) {
11715 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
11716 "%s: Invalid pointer", __func__);
11717 return CDF_STATUS_E_NOMEM;
11718 }
11719
11720 *val = filter_type;
11721
11722 msg.type = SIR_HAL_SET_MIRACAST;
11723 msg.reserved = 0;
11724 msg.bodyptr = val;
11725
11726 if (!CDF_IS_STATUS_SUCCESS(
11727 cds_mq_post_message(CDF_MODULE_ID_WMA, &msg))) {
11728 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
11729 "%s: Not able to post WDA_SET_MAS_ENABLE_DISABLE to WMA!",
11730 __func__);
11731 cdf_mem_free(val);
11732 return CDF_STATUS_E_FAILURE;
11733 }
11734
11735 mac_ptr->sme.miracast_value = filter_type;
11736 return CDF_STATUS_SUCCESS;
11737}
11738
11739/**
11740 * sme_set_mas() - Function to set MAS value to UMAC
11741 * @val: 1-Enable, 0-Disable
11742 *
11743 * This function passes down the value of MAS to the UMAC. A
11744 * value of 1 will enable MAS and a value of 0 will disable MAS
11745 *
11746 * Return: Configuration message posting status, SUCCESS or Fail
11747 *
11748 */
11749CDF_STATUS sme_set_mas(uint32_t val)
11750{
11751 cds_msg_t msg;
11752 uint32_t *ptr_val;
11753
11754 ptr_val = cdf_mem_malloc(sizeof(*ptr_val));
11755 if (NULL == ptr_val) {
11756 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
11757 "%s: could not allocate ptr_val", __func__);
11758 return CDF_STATUS_E_NOMEM;
11759 }
11760
11761 *ptr_val = val;
11762
11763 msg.type = SIR_HAL_SET_MAS;
11764 msg.reserved = 0;
11765 msg.bodyptr = ptr_val;
11766
11767 if (!CDF_IS_STATUS_SUCCESS(
11768 cds_mq_post_message(CDF_MODULE_ID_WMA, &msg))) {
11769 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
11770 "%s: Not able to post WDA_SET_MAS_ENABLE_DISABLE to WMA!",
11771 __func__);
11772 cdf_mem_free(ptr_val);
11773 return CDF_STATUS_E_FAILURE;
11774 }
11775 return CDF_STATUS_SUCCESS;
11776}
11777
11778/* -------------------------------------------------------------------------
11779 \fn sme_roam_channel_change_req
11780 \brief API to Indicate Channel change to new target channel
11781 \param hHal - The handle returned by mac_open
11782 \param targetChannel - New Channel to move the SAP to.
11783 \return CDF_STATUS
11784 ---------------------------------------------------------------------------*/
11785CDF_STATUS sme_roam_channel_change_req(tHalHandle hHal,
11786 struct cdf_mac_addr bssid, uint32_t cb_mode, tCsrRoamProfile *profile)
11787{
11788 CDF_STATUS status = CDF_STATUS_E_FAILURE;
11789 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
11790 uint8_t ch_mode;
11791
11792 ch_mode = (profile->ChannelInfo.ChannelList[0] <=
11793 CSR_MAX_2_4_GHZ_SUPPORTED_CHANNELS) ?
11794 pMac->roam.configParam.channelBondingMode24GHz :
11795 pMac->roam.configParam.channelBondingMode5GHz;
11796
11797 status = sme_acquire_global_lock(&pMac->sme);
11798 if (CDF_IS_STATUS_SUCCESS(status)) {
11799
11800 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_INFO_MED,
11801 FL("sapdfs: requested cbmode=[%d] & new negotiated cbmode[%d]"),
11802 cb_mode, ch_mode);
11803 status = csr_roam_channel_change_req(pMac, bssid, ch_mode,
11804 profile);
11805 sme_release_global_lock(&pMac->sme);
11806 }
11807 return status;
11808}
11809
11810/* -------------------------------------------------------------------------
11811 \fn sme_process_channel_change_resp
11812 \brief API to Indicate Channel change response message to SAP.
11813 \return CDF_STATUS
11814 ---------------------------------------------------------------------------*/
11815CDF_STATUS sme_process_channel_change_resp(tpAniSirGlobal pMac,
11816 uint16_t msg_type, void *pMsgBuf)
11817{
11818 CDF_STATUS status = CDF_STATUS_SUCCESS;
11819 tCsrRoamInfo proam_info = { 0 };
11820 eCsrRoamResult roamResult;
11821 tpSwitchChannelParams pChnlParams = (tpSwitchChannelParams) pMsgBuf;
11822 uint32_t SessionId = pChnlParams->peSessionId;
11823
11824 proam_info.channelChangeRespEvent =
11825 (tSirChanChangeResponse *)
11826 cdf_mem_malloc(sizeof(tSirChanChangeResponse));
11827 if (NULL == proam_info.channelChangeRespEvent) {
11828 status = CDF_STATUS_E_NOMEM;
11829 sms_log(pMac, LOGE,
11830 "Channel Change Event Allocation Failed: %d\n", status);
11831 return status;
11832 }
11833 if (msg_type == eWNI_SME_CHANNEL_CHANGE_RSP) {
11834 proam_info.channelChangeRespEvent->sessionId = SessionId;
11835 proam_info.channelChangeRespEvent->newChannelNumber =
11836 pChnlParams->channelNumber;
11837 proam_info.channelChangeRespEvent->secondaryChannelOffset =
11838 pChnlParams->ch_width;
11839
11840 if (pChnlParams->status == CDF_STATUS_SUCCESS) {
11841 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_INFO_MED,
11842 "sapdfs: Received success eWNI_SME_CHANNEL_CHANGE_RSP for sessionId[%d]",
11843 SessionId);
11844 proam_info.channelChangeRespEvent->channelChangeStatus =
11845 1;
11846 roamResult = eCSR_ROAM_RESULT_CHANNEL_CHANGE_SUCCESS;
11847 } else {
11848 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_INFO_MED,
11849 "sapdfs: Received failure eWNI_SME_CHANNEL_CHANGE_RSP for sessionId[%d]",
11850 SessionId);
11851 proam_info.channelChangeRespEvent->channelChangeStatus =
11852 0;
11853 roamResult = eCSR_ROAM_RESULT_CHANNEL_CHANGE_FAILURE;
11854 }
11855
11856 csr_roam_call_callback(pMac, SessionId, &proam_info, 0,
11857 eCSR_ROAM_SET_CHANNEL_RSP, roamResult);
11858
11859 } else {
11860 status = CDF_STATUS_E_FAILURE;
11861 sms_log(pMac, LOGE, "Invalid Channel Change Resp Message: %d\n",
11862 status);
11863 }
11864 cdf_mem_free(proam_info.channelChangeRespEvent);
11865
11866 return status;
11867}
11868
11869/* -------------------------------------------------------------------------
11870 \fn sme_roam_start_beacon_req
11871 \brief API to Indicate LIM to start Beacon Tx
11872 \after SAP CAC Wait is completed.
11873 \param hHal - The handle returned by mac_open
11874 \param sessionId - session ID
11875 \param dfsCacWaitStatus - CAC WAIT status flag
11876 \return CDF_STATUS
11877 ---------------------------------------------------------------------------*/
11878CDF_STATUS sme_roam_start_beacon_req(tHalHandle hHal, struct cdf_mac_addr bssid,
11879 uint8_t dfsCacWaitStatus)
11880{
11881 CDF_STATUS status = CDF_STATUS_E_FAILURE;
11882 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
11883 status = sme_acquire_global_lock(&pMac->sme);
11884
11885 if (CDF_IS_STATUS_SUCCESS(status)) {
11886 status = csr_roam_start_beacon_req(pMac, bssid, dfsCacWaitStatus);
11887 sme_release_global_lock(&pMac->sme);
11888 }
11889 return status;
11890}
11891
11892/* -------------------------------------------------------------------------
11893 \fn sme_roam_csa_ie_request
11894 \brief API to request CSA IE transmission from PE
11895 \param hHal - The handle returned by mac_open
11896 \param pDfsCsaReq - CSA IE request
11897 \param bssid - SAP bssid
11898 \param ch_bandwidth - Channel offset
11899 \return CDF_STATUS
11900 ---------------------------------------------------------------------------*/
11901CDF_STATUS sme_roam_csa_ie_request(tHalHandle hHal, struct cdf_mac_addr bssid,
11902 uint8_t targetChannel, uint8_t csaIeReqd,
11903 uint8_t ch_bandwidth)
11904{
11905 CDF_STATUS status = CDF_STATUS_E_FAILURE;
11906 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
11907 status = sme_acquire_global_lock(&pMac->sme);
11908 if (CDF_IS_STATUS_SUCCESS(status)) {
11909 status = csr_roam_send_chan_sw_ie_request(pMac, bssid, targetChannel,
11910 csaIeReqd, ch_bandwidth);
11911 sme_release_global_lock(&pMac->sme);
11912 }
11913 return status;
11914}
11915
11916/* ---------------------------------------------------------------------------
11917 \fn sme_init_thermal_info
11918 \brief SME API to initialize the thermal mitigation parameters
11919 \param hHal
11920 \param thermalParam : thermal mitigation parameters
11921 \- return CDF_STATUS
11922 -------------------------------------------------------------------------*/
11923CDF_STATUS sme_init_thermal_info(tHalHandle hHal, tSmeThermalParams thermalParam)
11924{
11925 t_thermal_mgmt *pWmaParam;
11926 cds_msg_t msg;
11927 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
11928
11929 pWmaParam = (t_thermal_mgmt *) cdf_mem_malloc(sizeof(t_thermal_mgmt));
11930 if (NULL == pWmaParam) {
11931 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
11932 "%s: could not allocate tThermalMgmt", __func__);
11933 return CDF_STATUS_E_NOMEM;
11934 }
11935
11936 cdf_mem_zero((void *)pWmaParam, sizeof(t_thermal_mgmt));
11937
11938 pWmaParam->thermalMgmtEnabled = thermalParam.smeThermalMgmtEnabled;
11939 pWmaParam->throttlePeriod = thermalParam.smeThrottlePeriod;
11940 pWmaParam->thermalLevels[0].minTempThreshold =
11941 thermalParam.smeThermalLevels[0].smeMinTempThreshold;
11942 pWmaParam->thermalLevels[0].maxTempThreshold =
11943 thermalParam.smeThermalLevels[0].smeMaxTempThreshold;
11944 pWmaParam->thermalLevels[1].minTempThreshold =
11945 thermalParam.smeThermalLevels[1].smeMinTempThreshold;
11946 pWmaParam->thermalLevels[1].maxTempThreshold =
11947 thermalParam.smeThermalLevels[1].smeMaxTempThreshold;
11948 pWmaParam->thermalLevels[2].minTempThreshold =
11949 thermalParam.smeThermalLevels[2].smeMinTempThreshold;
11950 pWmaParam->thermalLevels[2].maxTempThreshold =
11951 thermalParam.smeThermalLevels[2].smeMaxTempThreshold;
11952 pWmaParam->thermalLevels[3].minTempThreshold =
11953 thermalParam.smeThermalLevels[3].smeMinTempThreshold;
11954 pWmaParam->thermalLevels[3].maxTempThreshold =
11955 thermalParam.smeThermalLevels[3].smeMaxTempThreshold;
11956
11957 if (CDF_STATUS_SUCCESS == sme_acquire_global_lock(&pMac->sme)) {
11958 msg.type = WMA_INIT_THERMAL_INFO_CMD;
11959 msg.bodyptr = pWmaParam;
11960
11961 if (!CDF_IS_STATUS_SUCCESS
11962 (cds_mq_post_message(CDF_MODULE_ID_WMA, &msg))) {
11963 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
11964 "%s: Not able to post WMA_SET_THERMAL_INFO_CMD to WMA!",
11965 __func__);
11966 cdf_mem_free(pWmaParam);
11967 sme_release_global_lock(&pMac->sme);
11968 return CDF_STATUS_E_FAILURE;
11969 }
11970 sme_release_global_lock(&pMac->sme);
11971 return CDF_STATUS_SUCCESS;
11972 }
11973 cdf_mem_free(pWmaParam);
11974 return CDF_STATUS_E_FAILURE;
11975}
11976
11977/**
11978 * sme_add_set_thermal_level_callback() - Plug in set thermal level callback
11979 * @hal: Handle returned by macOpen
11980 * @callback: sme_set_thermal_level_callback
11981 *
11982 * Plug in set thermal level callback
11983 *
11984 * Return: none
11985 */
11986void sme_add_set_thermal_level_callback(tHalHandle hal,
11987 sme_set_thermal_level_callback callback)
11988{
11989 tpAniSirGlobal pMac = PMAC_STRUCT(hal);
11990
11991 pMac->sme.set_thermal_level_cb = callback;
11992}
11993
11994/**
11995 * sme_set_thermal_level() - SME API to set the thermal mitigation level
11996 * @hal: Handler to HAL
11997 * @level: Thermal mitigation level
11998 *
11999 * Return: CDF_STATUS
12000 */
12001CDF_STATUS sme_set_thermal_level(tHalHandle hal, uint8_t level)
12002{
12003 cds_msg_t msg;
12004 tpAniSirGlobal pMac = PMAC_STRUCT(hal);
12005 CDF_STATUS cdf_status = CDF_STATUS_SUCCESS;
12006
12007 if (CDF_STATUS_SUCCESS == sme_acquire_global_lock(&pMac->sme)) {
12008 cdf_mem_set(&msg, sizeof(msg), 0);
12009 msg.type = WMA_SET_THERMAL_LEVEL;
12010 msg.bodyval = level;
12011
12012 cdf_status = cds_mq_post_message(CDF_MODULE_ID_WMA, &msg);
12013 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
12014 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
12015 "%s: Not able to post WMA_SET_THERMAL_LEVEL to WMA!",
12016 __func__);
12017 sme_release_global_lock(&pMac->sme);
12018 return CDF_STATUS_E_FAILURE;
12019 }
12020 sme_release_global_lock(&pMac->sme);
12021 return CDF_STATUS_SUCCESS;
12022 }
12023 return CDF_STATUS_E_FAILURE;
12024}
12025
12026/* ---------------------------------------------------------------------------
12027 \fn sme_txpower_limit
12028 \brief SME API to set txpower limits
12029 \param hHal
12030 \param psmetx : power limits for 2g/5g
12031 \- return CDF_STATUS
12032 -------------------------------------------------------------------------*/
12033CDF_STATUS sme_txpower_limit(tHalHandle hHal, tSirTxPowerLimit *psmetx)
12034{
12035 CDF_STATUS status = CDF_STATUS_SUCCESS;
12036 CDF_STATUS cdf_status = CDF_STATUS_SUCCESS;
12037 cds_msg_t cds_message;
12038 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
12039
12040 status = sme_acquire_global_lock(&pMac->sme);
12041 if (CDF_IS_STATUS_SUCCESS(status)) {
12042 cds_message.type = WMA_TX_POWER_LIMIT;
12043 cds_message.reserved = 0;
12044 cds_message.bodyptr = psmetx;
12045
12046 cdf_status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message);
12047 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
12048 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
12049 "%s: not able to post WMA_TX_POWER_LIMIT",
12050 __func__);
12051 status = CDF_STATUS_E_FAILURE;
12052 cdf_mem_free(psmetx);
12053 }
12054 sme_release_global_lock(&pMac->sme);
12055 }
12056 return status;
12057}
12058
12059CDF_STATUS sme_update_connect_debug(tHalHandle hHal, uint32_t set_value)
12060{
12061 CDF_STATUS status = CDF_STATUS_SUCCESS;
12062 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
12063 pMac->fEnableDebugLog = set_value;
12064 return status;
12065}
12066
12067/* ---------------------------------------------------------------------------
12068 \fn sme_ap_disable_intra_bss_fwd
12069
12070 \brief
12071 SME will send message to WMA to set Intra BSS in txrx
12072
12073 \param
12074
12075 hHal - The handle returned by mac_open
12076
12077 sessionId - session id ( vdev id)
12078
12079 disablefwd - bool value that indicate disable intrabss fwd disable
12080
12081 \return CDF_STATUS
12082 --------------------------------------------------------------------------- */
12083CDF_STATUS sme_ap_disable_intra_bss_fwd(tHalHandle hHal, uint8_t sessionId,
12084 bool disablefwd)
12085{
12086 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
12087 int status = CDF_STATUS_SUCCESS;
12088 CDF_STATUS cdf_status = CDF_STATUS_SUCCESS;
12089 cds_msg_t cds_message;
12090 tpDisableIntraBssFwd pSapDisableIntraFwd = NULL;
12091
12092 /* Prepare the request to send to SME. */
12093 pSapDisableIntraFwd = cdf_mem_malloc(sizeof(tDisableIntraBssFwd));
12094 if (NULL == pSapDisableIntraFwd) {
12095 sms_log(pMac, LOGP, "Memory Allocation Failure!!! %s", __func__);
12096 return CDF_STATUS_E_NOMEM;
12097 }
12098
12099 cdf_mem_zero(pSapDisableIntraFwd, sizeof(tDisableIntraBssFwd));
12100
12101 pSapDisableIntraFwd->sessionId = sessionId;
12102 pSapDisableIntraFwd->disableintrabssfwd = disablefwd;
12103
12104 status = sme_acquire_global_lock(&pMac->sme);
12105 if (CDF_IS_STATUS_SUCCESS(status)) {
12106 /* serialize the req through MC thread */
12107 cds_message.bodyptr = pSapDisableIntraFwd;
12108 cds_message.type = WMA_SET_SAP_INTRABSS_DIS;
12109 cdf_status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message);
12110 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
12111 status = CDF_STATUS_E_FAILURE;
12112 cdf_mem_free(pSapDisableIntraFwd);
12113 }
12114 sme_release_global_lock(&pMac->sme);
12115 }
12116 return status;
12117}
12118
12119#ifdef WLAN_FEATURE_STATS_EXT
12120
12121/******************************************************************************
12122 \fn sme_stats_ext_register_callback
12123
12124 \brief
12125 a function called to register the callback that send vendor event for stats
12126 ext
12127
12128 \param callback - callback to be registered
12129******************************************************************************/
12130void sme_stats_ext_register_callback(tHalHandle hHal, StatsExtCallback callback)
12131{
12132 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
12133
12134 pMac->sme.StatsExtCallback = callback;
12135}
12136
12137/******************************************************************************
12138 \fn sme_stats_ext_request
12139
12140 \brief
12141 a function called when HDD receives STATS EXT vendor command from userspace
12142
12143 \param sessionID - vdevID for the stats ext request
12144
12145 \param input - Stats Ext Request structure ptr
12146
12147 \return CDF_STATUS
12148******************************************************************************/
12149CDF_STATUS sme_stats_ext_request(uint8_t session_id, tpStatsExtRequestReq input)
12150{
12151 cds_msg_t msg;
12152 tpStatsExtRequest data;
12153 size_t data_len;
12154
12155 data_len = sizeof(tStatsExtRequest) + input->request_data_len;
12156 data = cdf_mem_malloc(data_len);
12157
12158 if (data == NULL) {
12159 return CDF_STATUS_E_NOMEM;
12160 }
12161
12162 cdf_mem_zero(data, data_len);
12163 data->vdev_id = session_id;
12164 data->request_data_len = input->request_data_len;
12165 if (input->request_data_len) {
12166 cdf_mem_copy(data->request_data,
12167 input->request_data, input->request_data_len);
12168 }
12169
12170 msg.type = WMA_STATS_EXT_REQUEST;
12171 msg.reserved = 0;
12172 msg.bodyptr = data;
12173
12174 if (CDF_STATUS_SUCCESS != cds_mq_post_message(CDF_MODULE_ID_WMA, &msg)) {
12175 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
12176 "%s: Not able to post WMA_STATS_EXT_REQUEST message to WMA",
12177 __func__);
12178 cdf_mem_free(data);
12179 return CDF_STATUS_E_FAILURE;
12180 }
12181
12182 return CDF_STATUS_SUCCESS;
12183}
12184
12185/******************************************************************************
12186 \fn sme_stats_ext_event
12187
12188 \brief
12189 a callback function called when SME received eWNI_SME_STATS_EXT_EVENT
12190 response from WMA
12191
12192 \param hHal - HAL handle for device
12193 \param pMsg - Message body passed from WMA; includes NAN header
12194 \return CDF_STATUS
12195******************************************************************************/
12196CDF_STATUS sme_stats_ext_event(tHalHandle hHal, void *pMsg)
12197{
12198 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
12199 CDF_STATUS status = CDF_STATUS_SUCCESS;
12200
12201 if (NULL == pMsg) {
12202 sms_log(pMac, LOGE, "in %s msg ptr is NULL", __func__);
12203 status = CDF_STATUS_E_FAILURE;
12204 } else {
12205 sms_log(pMac, LOG2, "SME: entering %s", __func__);
12206
12207 if (pMac->sme.StatsExtCallback) {
12208 pMac->sme.StatsExtCallback(pMac->hHdd,
12209 (tpStatsExtEvent) pMsg);
12210 }
12211 }
12212
12213 return status;
12214}
12215
12216#endif
12217
12218/* ---------------------------------------------------------------------------
12219 \fn sme_update_dfs_scan_mode
12220 \brief Update DFS roam scan mode
12221 This function is called through dynamic setConfig callback function
12222 to configure allowDFSChannelRoam.
12223 \param hHal - HAL handle for device
12224 \param sessionId - Session Identifier
12225 \param allowDFSChannelRoam - DFS roaming scan mode 0 (disable),
12226 1 (passive), 2 (active)
12227 \return CDF_STATUS_SUCCESS - SME update DFS roaming scan config
12228 successfully.
12229 Other status means SME failed to update DFS roaming scan config.
12230 \sa
12231 -------------------------------------------------------------------------*/
12232CDF_STATUS sme_update_dfs_scan_mode(tHalHandle hHal, uint8_t sessionId,
12233 uint8_t allowDFSChannelRoam)
12234{
12235 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
12236 CDF_STATUS status = CDF_STATUS_SUCCESS;
12237
12238 status = sme_acquire_global_lock(&pMac->sme);
12239 if (CDF_IS_STATUS_SUCCESS(status)) {
12240 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_DEBUG,
12241 "LFR runtime successfully set AllowDFSChannelRoam Mode to "
12242 "%d - old value is %d - roam state is %s",
12243 allowDFSChannelRoam,
12244 pMac->roam.configParam.allowDFSChannelRoam,
12245 mac_trace_get_neighbour_roam_state(pMac->roam.
12246 neighborRoamInfo
12247 [sessionId].
12248 neighborRoamState));
12249 pMac->roam.configParam.allowDFSChannelRoam =
12250 allowDFSChannelRoam;
12251 sme_release_global_lock(&pMac->sme);
12252 }
12253 if (pMac->roam.configParam.isRoamOffloadScanEnabled) {
12254 csr_roam_offload_scan(pMac, sessionId,
12255 ROAM_SCAN_OFFLOAD_UPDATE_CFG,
12256 REASON_ROAM_DFS_SCAN_MODE_CHANGED);
12257 }
12258
12259 return status;
12260}
12261
12262/*--------------------------------------------------------------------------
12263 \brief sme_get_dfs_scan_mode() - get DFS roam scan mode
12264 This is a synchronous call
12265 \param hHal - The handle returned by mac_open.
12266 \return DFS roaming scan mode 0 (disable), 1 (passive), 2 (active)
12267 \sa
12268 --------------------------------------------------------------------------*/
12269uint8_t sme_get_dfs_scan_mode(tHalHandle hHal)
12270{
12271 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
12272 return pMac->roam.configParam.allowDFSChannelRoam;
12273}
12274
12275/*----------------------------------------------------------------------------
12276 \fn sme_modify_add_ie
12277 \brief This function sends msg to updates the additional IE buffers in PE
12278 \param hHal - global structure
12279 \param pModifyIE - pointer to tModifyIE structure
12280 \param updateType - type of buffer
12281 \- return Success or failure
12282 -----------------------------------------------------------------------------*/
12283CDF_STATUS sme_modify_add_ie(tHalHandle hHal,
12284 tSirModifyIE *pModifyIE, eUpdateIEsType updateType)
12285{
12286 CDF_STATUS status = CDF_STATUS_E_FAILURE;
12287 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
12288 status = sme_acquire_global_lock(&pMac->sme);
12289
12290 if (CDF_IS_STATUS_SUCCESS(status)) {
12291 status = csr_roam_modify_add_ies(pMac, pModifyIE, updateType);
12292 sme_release_global_lock(&pMac->sme);
12293 }
12294 return status;
12295}
12296
12297/*----------------------------------------------------------------------------
12298 \fn sme_update_add_ie
12299 \brief This function sends msg to updates the additional IE buffers in PE
12300 \param hHal - global structure
12301 \param pUpdateIE - pointer to structure tUpdateIE
12302 \param updateType - type of buffer
12303 \- return Success or failure
12304 -----------------------------------------------------------------------------*/
12305CDF_STATUS sme_update_add_ie(tHalHandle hHal,
12306 tSirUpdateIE *pUpdateIE, eUpdateIEsType updateType)
12307{
12308 CDF_STATUS status = CDF_STATUS_E_FAILURE;
12309 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
12310 status = sme_acquire_global_lock(&pMac->sme);
12311
12312 if (CDF_IS_STATUS_SUCCESS(status)) {
12313 status = csr_roam_update_add_ies(pMac, pUpdateIE, updateType);
12314 sme_release_global_lock(&pMac->sme);
12315 }
12316 return status;
12317}
12318
12319/* ---------------------------------------------------------------------------
12320 \fn sme_sta_in_middle_of_roaming
12321 \brief This function returns true if STA is in the middle of roaming state
12322 \param hHal - HAL handle for device
12323 \param sessionId - Session Identifier
12324 \- return true or false
12325 -------------------------------------------------------------------------*/
12326bool sme_sta_in_middle_of_roaming(tHalHandle hHal, uint8_t sessionId)
12327{
12328 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
12329 CDF_STATUS status = CDF_STATUS_SUCCESS;
12330 bool ret = false;
12331
12332 status = sme_acquire_global_lock(&pMac->sme);
12333 if (CDF_IS_STATUS_SUCCESS(status)) {
12334 ret = csr_neighbor_middle_of_roaming(hHal, sessionId);
12335 sme_release_global_lock(&pMac->sme);
12336 }
12337 return ret;
12338}
12339
12340
12341/**
12342 * sme_update_dsc_pto_up_mapping()
12343 * @hHal: HAL context
12344 * @dscpmapping: pointer to DSCP mapping structure
12345 * @sessionId: SME session id
12346 *
12347 * This routine is called to update dscp mapping
12348 *
12349 * Return: CDF_STATUS
12350 */
12351CDF_STATUS sme_update_dsc_pto_up_mapping(tHalHandle hHal,
12352 sme_QosWmmUpType *dscpmapping,
12353 uint8_t sessionId)
12354{
12355 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
12356 CDF_STATUS status = CDF_STATUS_SUCCESS;
12357 uint8_t i, j, peSessionId;
12358 tCsrRoamSession *pCsrSession = NULL;
12359 tpPESession pSession = NULL;
12360
12361 status = sme_acquire_global_lock(&pMac->sme);
12362 if (!CDF_IS_STATUS_SUCCESS(status))
12363 return status;
12364 pCsrSession = CSR_GET_SESSION(pMac, sessionId);
12365 if (pCsrSession == NULL) {
12366 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
12367 FL("Session lookup fails for CSR session"));
12368 sme_release_global_lock(&pMac->sme);
12369 return CDF_STATUS_E_FAILURE;
12370 }
12371 if (!CSR_IS_SESSION_VALID(pMac, sessionId)) {
12372 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
12373 FL("Invalid session Id %u"), sessionId);
12374 sme_release_global_lock(&pMac->sme);
12375 return CDF_STATUS_E_FAILURE;
12376 }
12377
12378 pSession = pe_find_session_by_bssid(pMac,
12379 pCsrSession->connectedProfile.bssid.bytes,
12380 &peSessionId);
12381
12382 if (pSession == NULL) {
12383 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
12384 FL(" Session lookup fails for BSSID"));
12385 sme_release_global_lock(&pMac->sme);
12386 return CDF_STATUS_E_FAILURE;
12387 }
12388
12389 if (!pSession->QosMapSet.present) {
12390 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
12391 FL("QOS Mapping IE not present"));
12392 sme_release_global_lock(&pMac->sme);
12393 return CDF_STATUS_E_FAILURE;
12394 }
12395 for (i = 0; i < SME_QOS_WMM_UP_MAX; i++) {
12396 for (j = pSession->QosMapSet.dscp_range[i][0];
12397 j <= pSession->QosMapSet.dscp_range[i][1];
12398 j++) {
12399 if ((pSession->QosMapSet.dscp_range[i][0] == 255)
12400 && (pSession->QosMapSet.dscp_range[i][1] ==
12401 255)) {
12402 dscpmapping[j] = 0;
12403 CDF_TRACE(CDF_MODULE_ID_SME,
12404 CDF_TRACE_LEVEL_ERROR,
12405 FL("User Priority %d isn't used"), i);
12406 break;
12407 } else {
12408 dscpmapping[j] = i;
12409 }
12410 }
12411 }
12412 for (i = 0; i < pSession->QosMapSet.num_dscp_exceptions; i++)
12413 if (pSession->QosMapSet.dscp_exceptions[i][0] != 255)
12414 dscpmapping[pSession->QosMapSet.dscp_exceptions[i][0]] =
12415 pSession->QosMapSet.dscp_exceptions[i][1];
12416
12417 sme_release_global_lock(&pMac->sme);
12418 return status;
12419}
12420
12421/* ---------------------------------------------------------------------------
12422 \fn sme_abort_roam_scan
12423 \brief API to abort current roam scan cycle by roam scan offload module.
12424 \param hHal - The handle returned by mac_open.
12425 \param sessionId - Session Identifier
12426 \return CDF_STATUS
12427 ---------------------------------------------------------------------------*/
12428
12429CDF_STATUS sme_abort_roam_scan(tHalHandle hHal, uint8_t sessionId)
12430{
12431 CDF_STATUS status = CDF_STATUS_SUCCESS;
12432 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
12433
12434 sms_log(pMac, LOGW, "entering function %s", __func__);
12435 if (pMac->roam.configParam.isRoamOffloadScanEnabled) {
12436 /* acquire the lock for the sme object */
12437 status = sme_acquire_global_lock(&pMac->sme);
12438 if (CDF_IS_STATUS_SUCCESS(status)) {
12439 csr_roam_offload_scan(pMac, sessionId,
12440 ROAM_SCAN_OFFLOAD_ABORT_SCAN,
12441 REASON_ROAM_ABORT_ROAM_SCAN);
12442 /* release the lock for the sme object */
12443 sme_release_global_lock(&pMac->sme);
12444 }
12445 }
12446
12447 return status;
12448}
12449
12450#ifdef FEATURE_WLAN_EXTSCAN
12451/**
12452 * sme_get_valid_channels_by_band() - to fetch valid channels filtered by band
12453 * @hHal: HAL context
12454 * @wifiBand: RF band information
12455 * @aValidChannels: output array to store channel info
12456 * @pNumChannels: output number of channels
12457 *
12458 * SME API to fetch all valid channels filtered by band
12459 *
12460 * Return: CDF_STATUS
12461 */
12462CDF_STATUS sme_get_valid_channels_by_band(tHalHandle hHal,
12463 uint8_t wifiBand,
12464 uint32_t *aValidChannels,
12465 uint8_t *pNumChannels)
12466{
12467 CDF_STATUS status = CDF_STATUS_SUCCESS;
12468 uint8_t chanList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = { 0 };
12469 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
12470 uint8_t numChannels = 0;
12471 uint8_t i = 0;
12472 uint32_t totValidChannels = WNI_CFG_VALID_CHANNEL_LIST_LEN;
12473
12474 if (!aValidChannels || !pNumChannels) {
12475 sms_log(pMac, CDF_TRACE_LEVEL_ERROR,
12476 FL("Output channel list/NumChannels is NULL"));
12477 return CDF_STATUS_E_INVAL;
12478 }
12479
12480 if ((wifiBand < WIFI_BAND_UNSPECIFIED) || (wifiBand >= WIFI_BAND_MAX)) {
12481 sms_log(pMac, CDF_TRACE_LEVEL_ERROR,
12482 FL("Invalid wifiBand (%d)"), wifiBand);
12483 return CDF_STATUS_E_INVAL;
12484 }
12485
12486 status = sme_get_cfg_valid_channels(hHal, &chanList[0],
12487 &totValidChannels);
12488 if (!CDF_IS_STATUS_SUCCESS(status)) {
12489 sms_log(pMac, CDF_TRACE_LEVEL_ERROR,
12490 FL("Fail to get valid channel list (err=%d)"), status);
12491 return status;
12492 }
12493
12494 switch (wifiBand) {
12495 case WIFI_BAND_UNSPECIFIED:
12496 sms_log(pMac, CDF_TRACE_LEVEL_INFO,
12497 FL("Unspec Band, return all (%d) valid channels"),
12498 totValidChannels);
12499 numChannels = totValidChannels;
12500 for (i = 0; i < totValidChannels; i++) {
12501 aValidChannels[i] = cds_chan_to_freq(chanList[i]);
12502 }
12503 break;
12504
12505 case WIFI_BAND_BG:
12506 sms_log(pMac, CDF_TRACE_LEVEL_INFO,
12507 FL("WIFI_BAND_BG (2.4 GHz)"));
12508 for (i = 0; i < totValidChannels; i++) {
12509 if (CDS_IS_CHANNEL_24GHZ(chanList[i])) {
12510 aValidChannels[numChannels++] =
12511 cds_chan_to_freq(chanList[i]);
12512 }
12513 }
12514 break;
12515
12516 case WIFI_BAND_A:
12517 sms_log(pMac, CDF_TRACE_LEVEL_INFO,
12518 FL("WIFI_BAND_A (5 GHz without DFS)"));
12519 for (i = 0; i < totValidChannels; i++) {
12520 if (CDS_IS_CHANNEL_5GHZ(chanList[i]) &&
12521 !CDS_IS_DFS_CH(chanList[i])) {
12522 aValidChannels[numChannels++] =
12523 cds_chan_to_freq(chanList[i]);
12524 }
12525 }
12526 break;
12527
12528 case WIFI_BAND_ABG:
12529 sms_log(pMac, CDF_TRACE_LEVEL_INFO,
12530 FL("WIFI_BAND_ABG (2.4 GHz + 5 GHz; no DFS)"));
12531 for (i = 0; i < totValidChannels; i++) {
12532 if ((CDS_IS_CHANNEL_24GHZ(chanList[i]) ||
12533 CDS_IS_CHANNEL_5GHZ(chanList[i])) &&
12534 !CDS_IS_DFS_CH(chanList[i])) {
12535 aValidChannels[numChannels++] =
12536 cds_chan_to_freq(chanList[i]);
12537 }
12538 }
12539 break;
12540
12541 case WIFI_BAND_A_DFS_ONLY:
12542 sms_log(pMac, CDF_TRACE_LEVEL_INFO,
12543 FL("WIFI_BAND_A_DFS (5 GHz DFS only)"));
12544 for (i = 0; i < totValidChannels; i++) {
12545 if (CDS_IS_CHANNEL_5GHZ(chanList[i]) &&
12546 CDS_IS_DFS_CH(chanList[i])) {
12547 aValidChannels[numChannels++] =
12548 cds_chan_to_freq(chanList[i]);
12549 }
12550 }
12551 break;
12552
12553 case WIFI_BAND_A_WITH_DFS:
12554 sms_log(pMac, CDF_TRACE_LEVEL_INFO,
12555 FL("WIFI_BAND_A_WITH_DFS (5 GHz with DFS)"));
12556 for (i = 0; i < totValidChannels; i++) {
12557 if (CDS_IS_CHANNEL_5GHZ(chanList[i])) {
12558 aValidChannels[numChannels++] =
12559 cds_chan_to_freq(chanList[i]);
12560 }
12561 }
12562 break;
12563
12564 case WIFI_BAND_ABG_WITH_DFS:
12565 sms_log(pMac, CDF_TRACE_LEVEL_INFO,
12566 FL("WIFI_BAND_ABG_WITH_DFS (2.4 GHz+5 GHz with DFS)"));
12567 for (i = 0; i < totValidChannels; i++) {
12568 if (CDS_IS_CHANNEL_24GHZ(chanList[i]) ||
12569 CDS_IS_CHANNEL_5GHZ(chanList[i])) {
12570 aValidChannels[numChannels++] =
12571 cds_chan_to_freq(chanList[i]);
12572 }
12573 }
12574 break;
12575
12576 default:
12577 sms_log(pMac, CDF_TRACE_LEVEL_ERROR,
12578 FL("Unknown wifiBand (%d))"), wifiBand);
12579 return CDF_STATUS_E_INVAL;
12580 break;
12581 }
12582 *pNumChannels = numChannels;
12583
12584 return status;
12585}
12586
12587/* ---------------------------------------------------------------------------
12588 \fn sme_ext_scan_get_capabilities
12589 \brief SME API to fetch extscan capabilities
12590 \param hHal
12591 \param pReq: extscan capabilities structure
12592 \- return CDF_STATUS
12593 -------------------------------------------------------------------------*/
12594CDF_STATUS sme_ext_scan_get_capabilities(tHalHandle hHal,
12595 tSirGetExtScanCapabilitiesReqParams *
12596 pReq)
12597{
12598 CDF_STATUS status = CDF_STATUS_SUCCESS;
12599 CDF_STATUS cdf_status = CDF_STATUS_SUCCESS;
12600 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
12601 cds_msg_t cds_message;
12602
12603 status = sme_acquire_global_lock(&pMac->sme);
12604 if (CDF_IS_STATUS_SUCCESS(status)) {
12605 /* Serialize the req through MC thread */
12606 cds_message.bodyptr = pReq;
12607 cds_message.type = WMA_EXTSCAN_GET_CAPABILITIES_REQ;
12608 cdf_status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message);
12609 if (!CDF_IS_STATUS_SUCCESS(cdf_status))
12610 status = CDF_STATUS_E_FAILURE;
12611
12612 sme_release_global_lock(&pMac->sme);
12613 }
12614 return status;
12615}
12616
12617/* ---------------------------------------------------------------------------
12618 \fn sme_ext_scan_start
12619 \brief SME API to issue extscan start
12620 \param hHal
12621 \param pStartCmd: extscan start structure
12622 \- return CDF_STATUS
12623 -------------------------------------------------------------------------*/
12624CDF_STATUS sme_ext_scan_start(tHalHandle hHal,
12625 tSirWifiScanCmdReqParams *pStartCmd)
12626{
12627 CDF_STATUS status = CDF_STATUS_SUCCESS;
12628 CDF_STATUS cdf_status = CDF_STATUS_SUCCESS;
12629 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
12630 cds_msg_t cds_message;
12631
12632 status = sme_acquire_global_lock(&pMac->sme);
12633 if (CDF_IS_STATUS_SUCCESS(status)) {
12634 /* Serialize the req through MC thread */
12635 cds_message.bodyptr = pStartCmd;
12636 cds_message.type = WMA_EXTSCAN_START_REQ;
12637 cdf_status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message);
12638 if (!CDF_IS_STATUS_SUCCESS(cdf_status))
12639 status = CDF_STATUS_E_FAILURE;
12640
12641 sme_release_global_lock(&pMac->sme);
12642 }
12643 return status;
12644}
12645
12646/* ---------------------------------------------------------------------------
12647 \fn sme_ext_scan_stop
12648 \brief SME API to issue extscan stop
12649 \param hHal
12650 \param pStopReq: extscan stop structure
12651 \- return CDF_STATUS
12652 -------------------------------------------------------------------------*/
12653CDF_STATUS sme_ext_scan_stop(tHalHandle hHal, tSirExtScanStopReqParams *pStopReq)
12654{
12655 CDF_STATUS status = CDF_STATUS_SUCCESS;
12656 CDF_STATUS cdf_status = CDF_STATUS_SUCCESS;
12657 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
12658 cds_msg_t cds_message;
12659
12660 status = sme_acquire_global_lock(&pMac->sme);
12661 if (CDF_IS_STATUS_SUCCESS(status)) {
12662 /* Serialize the req through MC thread */
12663 cds_message.bodyptr = pStopReq;
12664 cds_message.type = WMA_EXTSCAN_STOP_REQ;
12665 cdf_status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message);
12666 if (!CDF_IS_STATUS_SUCCESS(cdf_status))
12667 status = CDF_STATUS_E_FAILURE;
12668 sme_release_global_lock(&pMac->sme);
12669 }
12670 return status;
12671}
12672
12673/* ---------------------------------------------------------------------------
12674 \fn sme_set_bss_hotlist
12675 \brief SME API to set BSSID hotlist
12676 \param hHal
12677 \param pSetHotListReq: extscan set hotlist structure
12678 \- return CDF_STATUS
12679 -------------------------------------------------------------------------*/
12680CDF_STATUS sme_set_bss_hotlist(tHalHandle hHal,
12681 tSirExtScanSetBssidHotListReqParams *
12682 pSetHotListReq)
12683{
12684 CDF_STATUS status = CDF_STATUS_SUCCESS;
12685 CDF_STATUS cdf_status = CDF_STATUS_SUCCESS;
12686 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
12687 cds_msg_t cds_message;
12688
12689 status = sme_acquire_global_lock(&pMac->sme);
12690 if (CDF_IS_STATUS_SUCCESS(status)) {
12691 /* Serialize the req through MC thread */
12692 cds_message.bodyptr = pSetHotListReq;
12693 cds_message.type = WMA_EXTSCAN_SET_BSSID_HOTLIST_REQ;
12694 cdf_status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message);
12695 if (!CDF_IS_STATUS_SUCCESS(cdf_status))
12696 status = CDF_STATUS_E_FAILURE;
12697
12698 sme_release_global_lock(&pMac->sme);
12699 }
12700 return status;
12701}
12702
12703/* ---------------------------------------------------------------------------
12704 \fn sme_reset_bss_hotlist
12705 \brief SME API to reset BSSID hotlist
12706 \param hHal
12707 \param pSetHotListReq: extscan set hotlist structure
12708 \- return CDF_STATUS
12709 -------------------------------------------------------------------------*/
12710CDF_STATUS sme_reset_bss_hotlist(tHalHandle hHal,
12711 tSirExtScanResetBssidHotlistReqParams *
12712 pResetReq)
12713{
12714 CDF_STATUS status = CDF_STATUS_SUCCESS;
12715 CDF_STATUS cdf_status = CDF_STATUS_SUCCESS;
12716 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
12717 cds_msg_t cds_message;
12718
12719 status = sme_acquire_global_lock(&pMac->sme);
12720 if (CDF_IS_STATUS_SUCCESS(status)) {
12721 /* Serialize the req through MC thread */
12722 cds_message.bodyptr = pResetReq;
12723 cds_message.type = WMA_EXTSCAN_RESET_BSSID_HOTLIST_REQ;
12724 cdf_status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message);
12725 if (!CDF_IS_STATUS_SUCCESS(cdf_status))
12726 status = CDF_STATUS_E_FAILURE;
12727
12728 sme_release_global_lock(&pMac->sme);
12729 }
12730 return status;
12731}
12732
12733/* ---------------------------------------------------------------------------
12734 \fn sme_set_significant_change
12735 \brief SME API to set significant change
12736 \param hHal
12737 \param pSetSignificantChangeReq: extscan set significant change structure
12738 \- return CDF_STATUS
12739 -------------------------------------------------------------------------*/
12740CDF_STATUS sme_set_significant_change(tHalHandle hHal,
12741 tSirExtScanSetSigChangeReqParams *
12742 pSetSignificantChangeReq)
12743{
12744 CDF_STATUS status = CDF_STATUS_SUCCESS;
12745 CDF_STATUS cdf_status = CDF_STATUS_SUCCESS;
12746 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
12747 cds_msg_t cds_message;
12748
12749 status = sme_acquire_global_lock(&pMac->sme);
12750 if (CDF_IS_STATUS_SUCCESS(status)) {
12751 /* Serialize the req through MC thread */
12752 cds_message.bodyptr = pSetSignificantChangeReq;
12753 cds_message.type = WMA_EXTSCAN_SET_SIGNF_CHANGE_REQ;
12754 cdf_status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message);
12755 if (!CDF_IS_STATUS_SUCCESS(cdf_status))
12756 status = CDF_STATUS_E_FAILURE;
12757
12758 sme_release_global_lock(&pMac->sme);
12759 }
12760 return status;
12761}
12762
12763/* ---------------------------------------------------------------------------
12764 \fn sme_reset_significant_change
12765 \brief SME API to reset significant change
12766 \param hHal
12767 \param pResetReq: extscan reset significant change structure
12768 \- return CDF_STATUS
12769 -------------------------------------------------------------------------*/
12770CDF_STATUS sme_reset_significant_change(tHalHandle hHal,
12771 tSirExtScanResetSignificantChangeReqParams
12772 *pResetReq)
12773{
12774 CDF_STATUS status = CDF_STATUS_SUCCESS;
12775 CDF_STATUS cdf_status = CDF_STATUS_SUCCESS;
12776 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
12777 cds_msg_t cds_message;
12778
12779 status = sme_acquire_global_lock(&pMac->sme);
12780 if (CDF_IS_STATUS_SUCCESS(status)) {
12781 /* Serialize the req through MC thread */
12782 cds_message.bodyptr = pResetReq;
12783 cds_message.type = WMA_EXTSCAN_RESET_SIGNF_CHANGE_REQ;
12784 cdf_status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message);
12785 if (!CDF_IS_STATUS_SUCCESS(cdf_status))
12786 status = CDF_STATUS_E_FAILURE;
12787
12788 sme_release_global_lock(&pMac->sme);
12789 }
12790 return status;
12791}
12792
12793/* ---------------------------------------------------------------------------
12794 \fn sme_get_cached_results
12795 \brief SME API to get cached results
12796 \param hHal
12797 \param pCachedResultsReq: extscan get cached results structure
12798 \- return CDF_STATUS
12799 -------------------------------------------------------------------------*/
12800CDF_STATUS sme_get_cached_results(tHalHandle hHal,
12801 tSirExtScanGetCachedResultsReqParams *
12802 pCachedResultsReq)
12803{
12804 CDF_STATUS status = CDF_STATUS_SUCCESS;
12805 CDF_STATUS cdf_status = CDF_STATUS_SUCCESS;
12806 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
12807 cds_msg_t cds_message;
12808
12809 status = sme_acquire_global_lock(&pMac->sme);
12810 if (CDF_IS_STATUS_SUCCESS(status)) {
12811 /* Serialize the req through MC thread */
12812 cds_message.bodyptr = pCachedResultsReq;
12813 cds_message.type = WMA_EXTSCAN_GET_CACHED_RESULTS_REQ;
12814 cdf_status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message);
12815 if (!CDF_IS_STATUS_SUCCESS(cdf_status))
12816 status = CDF_STATUS_E_FAILURE;
12817
12818 sme_release_global_lock(&pMac->sme);
12819 }
12820 return status;
12821}
12822
12823/**
12824 * sme_set_epno_list() - set epno network list
12825 * @hHal: global hal handle
12826 * @input: request message
12827 *
12828 * This function constructs the cds message and fill in message type,
12829 * bodyptr with %input and posts it to WDA queue.
12830 *
12831 * Return: eHalStatus enumeration
12832 */
12833CDF_STATUS sme_set_epno_list(tHalHandle hal,
12834 struct wifi_epno_params *input)
12835{
12836 CDF_STATUS status = CDF_STATUS_SUCCESS;
12837 tpAniSirGlobal mac = PMAC_STRUCT(hal);
12838 cds_msg_t cds_message;
12839 struct wifi_epno_params *req_msg;
12840 int len, i;
12841
12842 sms_log(mac, LOG1, FL("enter"));
12843 len = sizeof(*req_msg) +
12844 (input->num_networks * sizeof(struct wifi_epno_network));
12845 req_msg = cdf_mem_malloc(len);
12846 if (!req_msg) {
12847 sms_log(mac, LOGE, FL("cdf_mem_malloc failed"));
12848 return CDF_STATUS_E_NOMEM;
12849 }
12850
12851 cdf_mem_zero(req_msg, len);
12852 req_msg->num_networks = input->num_networks;
12853 req_msg->request_id = input->request_id;
12854 req_msg->session_id = input->session_id;
12855 for (i = 0; i < req_msg->num_networks; i++) {
12856 req_msg->networks[i].rssi_threshold =
12857 input->networks[i].rssi_threshold;
12858 req_msg->networks[i].flags = input->networks[i].flags;
12859 req_msg->networks[i].auth_bit_field =
12860 input->networks[i].auth_bit_field;
12861 req_msg->networks[i].ssid.length =
12862 input->networks[i].ssid.length;
12863 cdf_mem_copy(req_msg->networks[i].ssid.ssId,
12864 input->networks[i].ssid.ssId,
12865 req_msg->networks[i].ssid.length);
12866 }
12867
12868 status = sme_acquire_global_lock(&mac->sme);
12869 if (CDF_IS_STATUS_SUCCESS(status)) {
12870 sms_log(mac, LOGE,
12871 FL("sme_acquire_global_lock failed!(status=%d)"),
12872 status);
12873 cdf_mem_free(req_msg);
12874 return status;
12875 }
12876
12877 /* Serialize the req through MC thread */
12878 cds_message.bodyptr = req_msg;
12879 cds_message.type = WMA_SET_EPNO_LIST_REQ;
12880 status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message);
12881 if (!CDF_IS_STATUS_SUCCESS(status)) {
12882 sms_log(mac, LOGE,
12883 FL("cds_mq_post_message failed!(err=%d)"),
12884 status);
12885 cdf_mem_free(req_msg);
12886 status = CDF_STATUS_E_FAILURE;
12887 }
12888 sme_release_global_lock(&mac->sme);
12889 return status;
12890}
12891
12892/**
12893 * sme_set_passpoint_list() - set passpoint network list
12894 * @hal: global hal handle
12895 * @input: request message
12896 *
12897 * This function constructs the cds message and fill in message type,
12898 * bodyptr with @input and posts it to WDA queue.
12899 *
12900 * Return: eHalStatus enumeration
12901 */
12902CDF_STATUS sme_set_passpoint_list(tHalHandle hal,
12903 struct wifi_passpoint_req *input)
12904{
12905 CDF_STATUS status = CDF_STATUS_SUCCESS;
12906 tpAniSirGlobal mac = PMAC_STRUCT(hal);
12907 cds_msg_t cds_message;
12908 struct wifi_passpoint_req *req_msg;
12909 int len, i;
12910
12911 sms_log(mac, LOG1, FL("enter"));
12912 len = sizeof(*req_msg) +
12913 (input->num_networks * sizeof(struct wifi_passpoint_network));
12914 req_msg = cdf_mem_malloc(len);
12915 if (!req_msg) {
12916 sms_log(mac, LOGE, FL("cdf_mem_malloc failed"));
12917 return CDF_STATUS_E_NOMEM;
12918 }
12919
12920 cdf_mem_zero(req_msg, len);
12921 req_msg->num_networks = input->num_networks;
12922 req_msg->request_id = input->request_id;
12923 req_msg->session_id = input->session_id;
12924 for (i = 0; i < req_msg->num_networks; i++) {
12925 req_msg->networks[i].id =
12926 input->networks[i].id;
12927 cdf_mem_copy(req_msg->networks[i].realm,
12928 input->networks[i].realm,
12929 strlen(input->networks[i].realm) + 1);
12930 cdf_mem_copy(req_msg->networks[i].plmn,
12931 input->networks[i].plmn,
12932 SIR_PASSPOINT_PLMN_LEN);
12933 cdf_mem_copy(req_msg->networks[i].roaming_consortium_ids,
12934 input->networks[i].roaming_consortium_ids,
12935 sizeof(req_msg->networks[i].roaming_consortium_ids));
12936 }
12937
12938 status = sme_acquire_global_lock(&mac->sme);
12939 if (CDF_IS_STATUS_SUCCESS(status)) {
12940 sms_log(mac, LOGE,
12941 FL("sme_acquire_global_lock failed!(status=%d)"),
12942 status);
12943 cdf_mem_free(req_msg);
12944 return status;
12945 }
12946
12947 /* Serialize the req through MC thread */
12948 cds_message.bodyptr = req_msg;
12949 cds_message.type = WMA_SET_PASSPOINT_LIST_REQ;
12950 status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message);
12951 if (!CDF_IS_STATUS_SUCCESS(status)) {
12952 sms_log(mac, LOGE,
12953 FL("cds_mq_post_message failed!(err=%d)"),
12954 status);
12955 cdf_mem_free(req_msg);
12956 status = CDF_STATUS_E_FAILURE;
12957 }
12958 sme_release_global_lock(&mac->sme);
12959 return status;
12960}
12961
12962/**
12963 * sme_reset_passpoint_list() - reset passpoint network list
12964 * @hHal: global hal handle
12965 * @input: request message
12966 *
12967 * Return: eHalStatus enumeration
12968 */
12969CDF_STATUS sme_reset_passpoint_list(tHalHandle hal,
12970 struct wifi_passpoint_req *input)
12971{
12972 CDF_STATUS status = CDF_STATUS_SUCCESS;
12973 tpAniSirGlobal mac = PMAC_STRUCT(hal);
12974 cds_msg_t cds_message;
12975 struct wifi_passpoint_req *req_msg;
12976
12977 sms_log(mac, LOG1, FL("enter"));
12978 req_msg = cdf_mem_malloc(sizeof(*req_msg));
12979 if (!req_msg) {
12980 sms_log(mac, LOGE, FL("cdf_mem_malloc failed"));
12981 return CDF_STATUS_E_NOMEM;
12982 }
12983
12984 cdf_mem_zero(req_msg, sizeof(*req_msg));
12985 req_msg->request_id = input->request_id;
12986 req_msg->session_id = input->session_id;
12987
12988 status = sme_acquire_global_lock(&mac->sme);
12989 if (CDF_IS_STATUS_SUCCESS(status)) {
12990 sms_log(mac, LOGE,
12991 FL("sme_acquire_global_lock failed!(status=%d)"),
12992 status);
12993 cdf_mem_free(req_msg);
12994 return status;
12995 }
12996
12997 /* Serialize the req through MC thread */
12998 cds_message.bodyptr = req_msg;
12999 cds_message.type = WMA_RESET_PASSPOINT_LIST_REQ;
13000 status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message);
13001 if (!CDF_IS_STATUS_SUCCESS(status)) {
13002 sms_log(mac, LOGE,
13003 FL("cds_mq_post_message failed!(err=%d)"),
13004 status);
13005 cdf_mem_free(req_msg);
13006 status = CDF_STATUS_E_FAILURE;
13007 }
13008 sme_release_global_lock(&mac->sme);
13009 return status;
13010}
13011
13012/**
13013 * sme_set_ssid_hotlist() - Set the SSID hotlist
13014 * @hal: SME handle
13015 * @request: set ssid hotlist request
13016 *
13017 * Return: eHalStatus
13018 */
13019CDF_STATUS
13020sme_set_ssid_hotlist(tHalHandle hal,
13021 struct sir_set_ssid_hotlist_request *request)
13022{
13023 CDF_STATUS status = CDF_STATUS_SUCCESS;
13024 tpAniSirGlobal mac = PMAC_STRUCT(hal);
13025 cds_msg_t cds_message;
13026 struct sir_set_ssid_hotlist_request *set_req;
13027
13028 set_req = cdf_mem_malloc(sizeof(*set_req));
13029 if (!set_req) {
13030 sms_log(mac, LOGE, FL("cdf_mem_malloc failed"));
13031 return CDF_STATUS_E_FAILURE;
13032 }
13033
13034 *set_req = *request;
13035 status = sme_acquire_global_lock(&mac->sme);
13036 if (CDF_STATUS_SUCCESS == status) {
13037 /* Serialize the req through MC thread */
13038 cds_message.bodyptr = set_req;
13039 cds_message.type = WMA_EXTSCAN_SET_SSID_HOTLIST_REQ;
13040 status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message);
13041 sme_release_global_lock(&mac->sme);
13042 if (!CDF_IS_STATUS_SUCCESS(status)) {
13043 cdf_mem_free(set_req);
13044 status = CDF_STATUS_E_FAILURE;
13045 }
13046 } else {
13047 sms_log(mac, LOGE,
13048 FL("sme_acquire_global_lock failed!(status=%d)"),
13049 status);
13050 cdf_mem_free(set_req);
13051 status = CDF_STATUS_E_FAILURE;
13052 }
13053 return status;
13054}
13055
13056CDF_STATUS sme_ext_scan_register_callback(tHalHandle hHal,
13057 void (*pExtScanIndCb)(void *,
13058 const uint16_t,
13059 void *))
13060{
13061 CDF_STATUS status = CDF_STATUS_SUCCESS;
13062 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
13063
13064 status = sme_acquire_global_lock(&pMac->sme);
13065 if (CDF_IS_STATUS_SUCCESS(status)) {
13066 pMac->sme.pExtScanIndCb = pExtScanIndCb;
13067 sme_release_global_lock(&pMac->sme);
13068 }
13069 return status;
13070}
13071
13072#else
13073CDF_STATUS sme_ext_scan_register_callback(tHalHandle hHal,
13074 void (*pExtScanIndCb)(void *, const uint16_t, void *))
13075{
13076 return CDF_STATUS_SUCCESS;
13077}
13078
13079#endif /* FEATURE_WLAN_EXTSCAN */
13080
13081#ifdef WLAN_FEATURE_LINK_LAYER_STATS
13082
13083/* ---------------------------------------------------------------------------
13084 \fn sme_ll_stats_clear_req
13085 \brief SME API to clear Link Layer Statistics
13086 \param hHal
13087 \param pclearStatsReq: Link Layer clear stats request params structure
13088 \- return CDF_STATUS
13089 -------------------------------------------------------------------------*/
13090CDF_STATUS sme_ll_stats_clear_req(tHalHandle hHal,
13091 tSirLLStatsClearReq *pclearStatsReq)
13092{
13093 CDF_STATUS status = CDF_STATUS_SUCCESS;
13094 CDF_STATUS cdf_status = CDF_STATUS_SUCCESS;
13095 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
13096 cds_msg_t cds_message;
13097 tSirLLStatsClearReq *clear_stats_req;
13098
13099 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_INFO,
13100 "staId = %u", pclearStatsReq->staId);
13101 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_INFO,
13102 "statsClearReqMask = 0x%X",
13103 pclearStatsReq->statsClearReqMask);
13104 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_INFO,
13105 "stopReq = %u", pclearStatsReq->stopReq);
13106
13107 clear_stats_req = cdf_mem_malloc(sizeof(*clear_stats_req));
13108
13109 if (!clear_stats_req) {
13110 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
13111 "%s: Not able to allocate memory for WMA_LL_STATS_CLEAR_REQ",
13112 __func__);
13113 return CDF_STATUS_E_NOMEM;
13114 }
13115
13116 *clear_stats_req = *pclearStatsReq;
13117
13118 if (CDF_STATUS_SUCCESS == sme_acquire_global_lock(&pMac->sme)) {
13119 /* Serialize the req through MC thread */
13120 cds_message.bodyptr = clear_stats_req;
13121 cds_message.type = WMA_LINK_LAYER_STATS_CLEAR_REQ;
13122 cdf_status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message);
13123 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
13124 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
13125 "%s: not able to post WMA_LL_STATS_CLEAR_REQ",
13126 __func__);
13127 cdf_mem_free(clear_stats_req);
13128 status = CDF_STATUS_E_FAILURE;
13129 }
13130 sme_release_global_lock(&pMac->sme);
13131 } else {
13132 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR, "%s: "
13133 "sme_acquire_global_lock error", __func__);
13134 cdf_mem_free(clear_stats_req);
13135 status = CDF_STATUS_E_FAILURE;
13136 }
13137
13138 return status;
13139}
13140
13141/* ---------------------------------------------------------------------------
13142 \fn sme_ll_stats_set_req
13143 \brief SME API to set the Link Layer Statistics
13144 \param hHal
13145 \param psetStatsReq: Link Layer set stats request params structure
13146 \- return CDF_STATUS
13147 -------------------------------------------------------------------------*/
13148CDF_STATUS sme_ll_stats_set_req(tHalHandle hHal, tSirLLStatsSetReq *psetStatsReq)
13149{
13150 CDF_STATUS status = CDF_STATUS_SUCCESS;
13151 CDF_STATUS cdf_status = CDF_STATUS_SUCCESS;
13152 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
13153 cds_msg_t cds_message;
13154 tSirLLStatsSetReq *set_stats_req;
13155
13156 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_INFO,
13157 "%s: MPDU Size = %u", __func__,
13158 psetStatsReq->mpduSizeThreshold);
13159 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_INFO,
13160 " Aggressive Stats Collections = %u",
13161 psetStatsReq->aggressiveStatisticsGathering);
13162
13163 set_stats_req = cdf_mem_malloc(sizeof(*set_stats_req));
13164
13165 if (!set_stats_req) {
13166 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
13167 "%s: Not able to allocate memory for WMA_LL_STATS_SET_REQ",
13168 __func__);
13169 return CDF_STATUS_E_NOMEM;
13170 }
13171
13172 *set_stats_req = *psetStatsReq;
13173
13174 if (CDF_STATUS_SUCCESS == sme_acquire_global_lock(&pMac->sme)) {
13175 /* Serialize the req through MC thread */
13176 cds_message.bodyptr = set_stats_req;
13177 cds_message.type = WMA_LINK_LAYER_STATS_SET_REQ;
13178 cdf_status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message);
13179 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
13180 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
13181 "%s: not able to post WMA_LL_STATS_SET_REQ",
13182 __func__);
13183 cdf_mem_free(set_stats_req);
13184 status = CDF_STATUS_E_FAILURE;
13185 }
13186 sme_release_global_lock(&pMac->sme);
13187 } else {
13188 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR, "%s: "
13189 "sme_acquire_global_lock error", __func__);
13190 cdf_mem_free(set_stats_req);
13191 status = CDF_STATUS_E_FAILURE;
13192 }
13193
13194 return status;
13195}
13196
13197/* ---------------------------------------------------------------------------
13198 \fn sme_ll_stats_get_req
13199 \brief SME API to get the Link Layer Statistics
13200 \param hHal
13201 \param pgetStatsReq: Link Layer get stats request params structure
13202 \- return CDF_STATUS
13203 -------------------------------------------------------------------------*/
13204CDF_STATUS sme_ll_stats_get_req(tHalHandle hHal, tSirLLStatsGetReq *pgetStatsReq)
13205{
13206 CDF_STATUS status = CDF_STATUS_SUCCESS;
13207 CDF_STATUS cdf_status = CDF_STATUS_SUCCESS;
13208 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
13209 cds_msg_t cds_message;
13210 tSirLLStatsGetReq *get_stats_req;
13211
13212 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_INFO,
13213 "reqId = %u", pgetStatsReq->reqId);
13214 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_INFO,
13215 "staId = %u", pgetStatsReq->staId);
13216 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_INFO,
13217 "Stats Type = %u", pgetStatsReq->paramIdMask);
13218
13219 get_stats_req = cdf_mem_malloc(sizeof(*get_stats_req));
13220
13221 if (!get_stats_req) {
13222 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
13223 "%s: Not able to allocate memory for WMA_LL_STATS_GET_REQ",
13224 __func__);
13225 return CDF_STATUS_E_NOMEM;
13226 }
13227
13228 *get_stats_req = *pgetStatsReq;
13229
13230 if (CDF_STATUS_SUCCESS == sme_acquire_global_lock(&pMac->sme)) {
13231 /* Serialize the req through MC thread */
13232 cds_message.bodyptr = get_stats_req;
13233 cds_message.type = WMA_LINK_LAYER_STATS_GET_REQ;
13234 cdf_status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message);
13235 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
13236 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
13237 "%s: not able to post WMA_LL_STATS_GET_REQ",
13238 __func__);
13239
13240 cdf_mem_free(get_stats_req);
13241 status = CDF_STATUS_E_FAILURE;
13242
13243 }
13244 sme_release_global_lock(&pMac->sme);
13245 } else {
13246 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR, "%s: "
13247 "sme_acquire_global_lock error", __func__);
13248 cdf_mem_free(get_stats_req);
13249 status = CDF_STATUS_E_FAILURE;
13250 }
13251
13252 return status;
13253}
13254
13255/* ---------------------------------------------------------------------------
13256 \fn sme_set_link_layer_stats_ind_cb
13257 \brief SME API to trigger the stats are available after get request
13258 \param hHal
13259 \param callback_routine - HDD callback which needs to be invoked after
13260 getting status notification from FW
13261 \- return CDF_STATUS
13262 -------------------------------------------------------------------------*/
13263CDF_STATUS sme_set_link_layer_stats_ind_cb
13264 (tHalHandle hHal,
13265 void (*callback_routine)(void *callbackCtx, int indType, void *pRsp)
13266 ) {
13267 CDF_STATUS status = CDF_STATUS_SUCCESS;
13268 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
13269
13270 status = sme_acquire_global_lock(&pMac->sme);
13271 if (CDF_IS_STATUS_SUCCESS(status)) {
13272 pMac->sme.pLinkLayerStatsIndCallback = callback_routine;
13273 sme_release_global_lock(&pMac->sme);
13274 } else {
13275 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR, "%s: "
13276 "sme_acquire_global_lock error", __func__);
13277 }
13278
13279 return status;
13280}
13281
13282#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
13283
13284/**
13285 * sme_fw_mem_dump_register_cb() - Register fw memory dump callback
13286 *
13287 * @hal - MAC global handle
13288 * @callback_routine - callback routine from HDD
13289 *
13290 * This API is invoked by HDD to register its callback in SME
13291 *
13292 * Return: CDF_STATUS
13293 */
13294#ifdef WLAN_FEATURE_MEMDUMP
13295CDF_STATUS sme_fw_mem_dump_register_cb(tHalHandle hal,
13296 void (*callback_routine)(void *cb_context,
13297 struct fw_dump_rsp *rsp))
13298{
13299 CDF_STATUS status = CDF_STATUS_SUCCESS;
13300 tpAniSirGlobal pmac = PMAC_STRUCT(hal);
13301
13302 status = sme_acquire_global_lock(&pmac->sme);
13303 if (CDF_STATUS_SUCCESS == status) {
13304 pmac->sme.fw_dump_callback = callback_routine;
13305 sme_release_global_lock(&pmac->sme);
13306 } else {
13307 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
13308 FL("sme_acquire_global_lock error"));
13309 }
13310
13311 return status;
13312}
13313#else
13314CDF_STATUS sme_fw_mem_dump_register_cb(tHalHandle hal,
13315 void (*callback_routine)(void *cb_context,
13316 struct fw_dump_rsp *rsp))
13317{
13318 return CDF_STATUS_SUCCESS;
13319}
13320#endif /* WLAN_FEATURE_MEMDUMP */
13321
13322/**
13323 * sme_fw_mem_dump_unregister_cb() - Unregister fw memory dump callback
13324 *
13325 * @hHal - MAC global handle
13326 *
13327 * This API is invoked by HDD to unregister its callback in SME
13328 *
13329 * Return: CDF_STATUS
13330 */
13331#ifdef WLAN_FEATURE_MEMDUMP
13332CDF_STATUS sme_fw_mem_dump_unregister_cb(tHalHandle hal)
13333{
13334 CDF_STATUS status;
13335 tpAniSirGlobal pmac = PMAC_STRUCT(hal);
13336
13337 status = sme_acquire_global_lock(&pmac->sme);
13338 if (CDF_STATUS_SUCCESS == status) {
13339 pmac->sme.fw_dump_callback = NULL;
13340 sme_release_global_lock(&pmac->sme);
13341 } else {
13342 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
13343 FL("sme_acquire_global_lock error"));
13344 }
13345
13346 return status;
13347}
13348#else
13349CDF_STATUS sme_fw_mem_dump_unregister_cb(tHalHandle hal)
13350{
13351 return CDF_STATUS_SUCCESS;
13352}
13353#endif /* WLAN_FEATURE_MEMDUMP */
13354
13355#ifdef WLAN_FEATURE_ROAM_OFFLOAD
13356/*--------------------------------------------------------------------------
13357 \brief sme_update_roam_offload_enabled() - enable/disable roam offload feaure
13358 It is used at in the REG_DYNAMIC_VARIABLE macro definition of
13359 \param hHal - The handle returned by mac_open.
13360 \param nRoamOffloadEnabled - The bool to update with
13361 \return CDF_STATUS_SUCCESS - SME update config successfully.
13362 Other status means SME is failed to update.
13363 \sa
13364 --------------------------------------------------------------------------*/
13365
13366CDF_STATUS sme_update_roam_offload_enabled(tHalHandle hHal,
13367 bool nRoamOffloadEnabled)
13368{
13369 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
13370 CDF_STATUS status = CDF_STATUS_SUCCESS;
13371
13372 status = sme_acquire_global_lock(&pMac->sme);
13373 if (CDF_IS_STATUS_SUCCESS(status)) {
13374 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_INFO,
13375 "%s: LFR3:gRoamOffloadEnabled is changed from %d to %d",
13376 __func__, pMac->roam.configParam.isRoamOffloadEnabled,
13377 nRoamOffloadEnabled);
13378 pMac->roam.configParam.isRoamOffloadEnabled =
13379 nRoamOffloadEnabled;
13380 sme_release_global_lock(&pMac->sme);
13381 }
13382
13383 return status;
13384}
13385
13386/*--------------------------------------------------------------------------
13387 \brief sme_update_roam_key_mgmt_offload_enabled() - enable/disable key mgmt
13388 offload
13389 This is a synchronous call
13390 \param hHal - The handle returned by mac_open.
13391 \param sessionId - Session Identifier
13392 \param nRoamKeyMgmtOffloadEnabled - The bool to update with
13393 \return CDF_STATUS_SUCCESS - SME update config successfully.
13394 Other status means SME is failed to update.
13395 \sa
13396 --------------------------------------------------------------------------*/
13397
13398CDF_STATUS sme_update_roam_key_mgmt_offload_enabled(tHalHandle hHal,
13399 uint8_t sessionId,
13400 bool nRoamKeyMgmtOffloadEnabled)
13401{
13402 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
13403 CDF_STATUS status = CDF_STATUS_SUCCESS;
13404
13405 status = sme_acquire_global_lock(&pMac->sme);
13406 if (CDF_IS_STATUS_SUCCESS(status)) {
13407 if (CSR_IS_SESSION_VALID(pMac, sessionId)) {
13408 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_INFO,
13409 "%s: LFR3: KeyMgmtOffloadEnabled changed to %d",
13410 __func__, nRoamKeyMgmtOffloadEnabled);
13411 status = csr_roam_set_key_mgmt_offload(pMac,
13412 sessionId,
13413 nRoamKeyMgmtOffloadEnabled);
13414 } else {
13415 status = CDF_STATUS_E_INVAL;
13416 }
13417 sme_release_global_lock(&pMac->sme);
13418 }
13419
13420 return status;
13421}
13422
13423/* ---------------------------------------------------------------------------
13424 \fn sme_get_temperature
13425 \brief SME API to get the pdev temperature
13426 \param hHal
13427 \param temperature context
13428 \param pCallbackfn: callback fn with response (temperature)
13429 \- return CDF_STATUS
13430 -------------------------------------------------------------------------*/
13431CDF_STATUS sme_get_temperature(tHalHandle hHal,
13432 void *tempContext,
13433 void (*pCallbackfn)(int temperature,
13434 void *pContext))
13435{
13436 CDF_STATUS status = CDF_STATUS_SUCCESS;
13437 CDF_STATUS cdf_status = CDF_STATUS_SUCCESS;
13438 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
13439 cds_msg_t cds_message;
13440
13441 status = sme_acquire_global_lock(&pMac->sme);
13442 if (CDF_STATUS_SUCCESS == status) {
13443 if ((NULL == pCallbackfn) &&
13444 (NULL == pMac->sme.pGetTemperatureCb)) {
13445 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
13446 FL
13447 ("Indication Call back did not registered"));
13448 sme_release_global_lock(&pMac->sme);
13449 return CDF_STATUS_E_FAILURE;
13450 } else if (NULL != pCallbackfn) {
13451 pMac->sme.pTemperatureCbContext = tempContext;
13452 pMac->sme.pGetTemperatureCb = pCallbackfn;
13453 }
13454 /* serialize the req through MC thread */
13455 cds_message.bodyptr = NULL;
13456 cds_message.type = WMA_GET_TEMPERATURE_REQ;
13457 cdf_status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message);
13458 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
13459 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
13460 FL("Post Get Temperature msg fail"));
13461 status = CDF_STATUS_E_FAILURE;
13462 }
13463 sme_release_global_lock(&pMac->sme);
13464 }
13465 return status;
13466}
13467
13468/* ---------------------------------------------------------------------------
13469 \fn sme_set_scanning_mac_oui
13470 \brief SME API to set scanning mac oui
13471 \param hHal
13472 \param pScanMacOui: Scanning Mac Oui (input 3 bytes)
13473 \- return CDF_STATUS
13474 -------------------------------------------------------------------------*/
13475CDF_STATUS sme_set_scanning_mac_oui(tHalHandle hHal, tSirScanMacOui *pScanMacOui)
13476{
13477 CDF_STATUS status = CDF_STATUS_SUCCESS;
13478 CDF_STATUS cdf_status = CDF_STATUS_SUCCESS;
13479 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
13480 cds_msg_t cds_message;
13481
13482 status = sme_acquire_global_lock(&pMac->sme);
13483 if (CDF_STATUS_SUCCESS == status) {
13484 /* Serialize the req through MC thread */
13485 cds_message.bodyptr = pScanMacOui;
13486 cds_message.type = WMA_SET_SCAN_MAC_OUI_REQ;
13487 cdf_status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message);
13488 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
13489 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
13490 FL("Msg post Set Scan Mac OUI failed"));
13491 status = CDF_STATUS_E_FAILURE;
13492 }
13493 sme_release_global_lock(&pMac->sme);
13494 }
13495 return status;
13496}
13497#endif
13498
13499#ifdef DHCP_SERVER_OFFLOAD
13500/* ---------------------------------------------------------------------------
13501 \fn sme_set_dhcp_srv_offload
13502 \brief SME API to set DHCP server offload info
13503 \param hHal
13504 \param pDhcpSrvInfo : DHCP server offload info struct
13505 \- return CDF_STATUS
13506 -------------------------------------------------------------------------*/
13507CDF_STATUS sme_set_dhcp_srv_offload(tHalHandle hHal,
13508 tSirDhcpSrvOffloadInfo *pDhcpSrvInfo)
13509{
13510 cds_msg_t cds_message;
13511 tSirDhcpSrvOffloadInfo *pSmeDhcpSrvInfo;
13512 CDF_STATUS status = CDF_STATUS_SUCCESS;
13513 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
13514
13515 pSmeDhcpSrvInfo = cdf_mem_malloc(sizeof(*pSmeDhcpSrvInfo));
13516
13517 if (!pSmeDhcpSrvInfo) {
13518 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
13519 "%s: Not able to allocate memory for WMA_SET_DHCP_SERVER_OFFLOAD_CMD",
13520 __func__);
13521 return CDF_STATUS_E_NOMEM;
13522 }
13523
13524 *pSmeDhcpSrvInfo = *pDhcpSrvInfo;
13525
13526 status = sme_acquire_global_lock(&pMac->sme);
13527 if (CDF_STATUS_SUCCESS == status) {
13528 /* serialize the req through MC thread */
13529 cds_message.type = WMA_SET_DHCP_SERVER_OFFLOAD_CMD;
13530 cds_message.bodyptr = pSmeDhcpSrvInfo;
13531
13532 if (!CDF_IS_STATUS_SUCCESS
13533 (cds_mq_post_message(CDF_MODULE_ID_WMA, &cds_message))) {
13534 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
13535 "%s: Not able to post WMA_SET_DHCP_SERVER_OFFLOAD_CMD to WMA!",
13536 __func__);
13537 cdf_mem_free(pSmeDhcpSrvInfo);
13538 status = CDF_STATUS_E_FAILURE;
13539 }
13540 sme_release_global_lock(&pMac->sme);
13541 } else {
13542 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
13543 "%s: sme_acquire_global_lock error!", __func__);
13544 cdf_mem_free(pSmeDhcpSrvInfo);
13545 }
13546
13547 return status;
13548}
13549#endif /* DHCP_SERVER_OFFLOAD */
13550
13551#ifdef WLAN_FEATURE_GPIO_LED_FLASHING
13552/* ---------------------------------------------------------------------------
13553 \fn sme_set_led_flashing
13554 \brief API to set the Led flashing parameters.
13555 \param hHal - The handle returned by mac_open.
13556 \param x0, x1 - led flashing parameters
13557 \return CDF_STATUS
13558 ---------------------------------------------------------------------------*/
13559CDF_STATUS sme_set_led_flashing(tHalHandle hHal, uint8_t type,
13560 uint32_t x0, uint32_t x1)
13561{
13562 CDF_STATUS status = CDF_STATUS_SUCCESS;
13563 CDF_STATUS cdf_status = CDF_STATUS_SUCCESS;
13564 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
13565 cds_msg_t cds_message;
13566 tSirLedFlashingReq *ledflashing;
13567
13568 ledflashing = cdf_mem_malloc(sizeof(*ledflashing));
13569 if (!ledflashing) {
13570 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
13571 FL
13572 ("Not able to allocate memory for WMA_LED_TIMING_REQ"));
13573 return CDF_STATUS_E_NOMEM;
13574 }
13575
13576 ledflashing->pattern_id = type;
13577 ledflashing->led_x0 = x0;
13578 ledflashing->led_x1 = x1;
13579
13580 status = sme_acquire_global_lock(&pMac->sme);
13581 if (CDF_IS_STATUS_SUCCESS(status)) {
13582 /* Serialize the req through MC thread */
13583 cds_message.bodyptr = ledflashing;
13584 cds_message.type = WMA_LED_FLASHING_REQ;
13585 cdf_status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message);
13586 if (!CDF_IS_STATUS_SUCCESS(cdf_status))
13587 status = CDF_STATUS_E_FAILURE;
13588 sme_release_global_lock(&pMac->sme);
13589 }
13590 return status;
13591}
13592#endif
13593
13594/**
13595 * sme_handle_dfS_chan_scan() - handle DFS channel configuration
13596 * @h_hal: corestack handler
13597 * @dfs_flag: flag indicating dfs channel enable/disable
13598 * Return: CDF_STATUS
13599 */
13600CDF_STATUS sme_handle_dfs_chan_scan(tHalHandle h_hal, uint8_t dfs_flag)
13601{
13602 CDF_STATUS status = CDF_STATUS_SUCCESS;
13603 tpAniSirGlobal mac = PMAC_STRUCT(h_hal);
13604
13605 status = sme_acquire_global_lock(&mac->sme);
13606
13607 if (CDF_STATUS_SUCCESS == status) {
13608
13609 mac->scan.fEnableDFSChnlScan = dfs_flag;
13610
13611 /* update the channel list to the firmware */
13612 status = csr_update_channel_list(mac);
13613
13614 sme_release_global_lock(&mac->sme);
13615 }
13616
13617 return status;
13618}
13619
13620
13621/**
13622 * sme_configure_stats_avg_factor() - function to config avg. stats factor
13623 * @hal: hal
13624 * @session_id: session ID
13625 * @stats_avg_factor: average stats factor
13626 *
13627 * This function configures the stats avg factor in firmware
13628 *
13629 * Return: CDF_STATUS
13630 */
13631CDF_STATUS sme_configure_stats_avg_factor(tHalHandle hal, uint8_t session_id,
13632 uint16_t stats_avg_factor)
13633{
13634 cds_msg_t msg;
13635 CDF_STATUS status = CDF_STATUS_SUCCESS;
13636 tpAniSirGlobal mac = PMAC_STRUCT(hal);
13637 struct sir_stats_avg_factor *stats_factor;
13638
13639 stats_factor = cdf_mem_malloc(sizeof(*stats_factor));
13640
13641 if (!stats_factor) {
13642 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
13643 "%s: Not able to allocate memory for SIR_HAL_CONFIG_STATS_FACTOR",
13644 __func__);
13645 return CDF_STATUS_E_NOMEM;
13646 }
13647
13648 status = sme_acquire_global_lock(&mac->sme);
13649
13650 if (CDF_STATUS_SUCCESS == status) {
13651
13652 stats_factor->vdev_id = session_id;
13653 stats_factor->stats_avg_factor = stats_avg_factor;
13654
13655 /* serialize the req through MC thread */
13656 msg.type = SIR_HAL_CONFIG_STATS_FACTOR;
13657 msg.bodyptr = stats_factor;
13658
13659 if (!CDF_IS_STATUS_SUCCESS(
13660 cds_mq_post_message(CDF_MODULE_ID_WMA, &msg))) {
13661 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
13662 "%s: Not able to post SIR_HAL_CONFIG_STATS_FACTOR to WMA!",
13663 __func__);
13664 cdf_mem_free(stats_factor);
13665 status = CDF_STATUS_E_FAILURE;
13666 }
13667 sme_release_global_lock(&mac->sme);
13668 } else {
13669 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
13670 "%s: sme_acquire_global_lock error!",
13671 __func__);
13672 cdf_mem_free(stats_factor);
13673 }
13674
13675 return status;
13676}
13677
13678/**
13679 * sme_configure_guard_time() - function to configure guard time
13680 * @hal: hal
13681 * @session_id: session id
13682 * @guard_time: guard time
13683 *
13684 * This function configures the guard time in firmware
13685 *
13686 * Return: CDF_STATUS
13687 */
13688CDF_STATUS sme_configure_guard_time(tHalHandle hal, uint8_t session_id,
13689 uint32_t guard_time)
13690{
13691 cds_msg_t msg;
13692 CDF_STATUS status = CDF_STATUS_SUCCESS;
13693 tpAniSirGlobal mac = PMAC_STRUCT(hal);
13694 struct sir_guard_time_request *g_time;
13695
13696 g_time = cdf_mem_malloc(sizeof(*g_time));
13697
13698 if (!g_time) {
13699 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
13700 "%s: Not able to allocate memory for SIR_HAL_CONFIG_GUARD_TIME",
13701 __func__);
13702 return CDF_STATUS_E_NOMEM;
13703 }
13704
13705 status = sme_acquire_global_lock(&mac->sme);
13706
13707 if (CDF_STATUS_SUCCESS == status) {
13708
13709 g_time->vdev_id = session_id;
13710 g_time->guard_time = guard_time;
13711
13712 /* serialize the req through MC thread */
13713 msg.type = SIR_HAL_CONFIG_GUARD_TIME;
13714 msg.bodyptr = g_time;
13715
13716 if (!CDF_IS_STATUS_SUCCESS(
13717 cds_mq_post_message(CDF_MODULE_ID_WMA, &msg))) {
13718 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
13719 "%s: Not able to post SIR_HAL_CONFIG_GUARD_TIME to WMA!",
13720 __func__);
13721 cdf_mem_free(g_time);
13722 status = CDF_STATUS_E_FAILURE;
13723 }
13724 sme_release_global_lock(&mac->sme);
13725 } else {
13726 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
13727 "%s: sme_acquire_global_lock error!",
13728 __func__);
13729 cdf_mem_free(g_time);
13730 }
13731
13732 return status;
13733}
13734
13735/**
13736 * sme_configure_modulated_dtim() - function to configure modulated dtim
13737 * @h_hal: SME API to enable/disable modulated DTIM instantaneously
13738 * @session_id: session ID
13739 * @modulated_dtim: modulated dtim value
13740 *
13741 * This function configures the modulated dtim in firmware
13742 *
13743 * Return: CDF_STATUS
13744 */
13745CDF_STATUS sme_configure_modulated_dtim(tHalHandle h_hal, uint8_t session_id,
13746 uint32_t modulated_dtim)
13747{
13748 cds_msg_t msg;
13749 CDF_STATUS status = CDF_STATUS_SUCCESS;
13750 tpAniSirGlobal mac = PMAC_STRUCT(h_hal);
13751 wma_cli_set_cmd_t *iwcmd;
13752
13753 iwcmd = cdf_mem_malloc(sizeof(*iwcmd));
13754 if (NULL == iwcmd) {
13755 CDF_TRACE(CDF_MODULE_ID_SME,
13756 CDF_TRACE_LEVEL_FATAL,
13757 "%s: cdf_mem_alloc failed", __func__);
13758 return CDF_STATUS_E_NOMEM;
13759 }
13760
13761 status = sme_acquire_global_lock(&mac->sme);
13762
13763 if (CDF_STATUS_SUCCESS == status) {
13764
13765 cdf_mem_zero((void *)iwcmd, sizeof(*iwcmd));
13766 iwcmd->param_value = modulated_dtim;
13767 iwcmd->param_vdev_id = session_id;
13768 iwcmd->param_id = GEN_PARAM_MODULATED_DTIM;
13769 iwcmd->param_vp_dev = GEN_CMD;
13770 msg.type = WMA_CLI_SET_CMD;
13771 msg.reserved = 0;
13772 msg.bodyptr = (void *)iwcmd;
13773
13774 if (!CDF_IS_STATUS_SUCCESS(
13775 cds_mq_post_message(CDF_MODULE_ID_WMA, &msg))) {
13776 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
13777 "%s: Not able to post GEN_PARAM_DYNAMIC_DTIM to WMA!",
13778 __func__);
13779 cdf_mem_free(iwcmd);
13780 status = CDF_STATUS_E_FAILURE;
13781 }
13782 sme_release_global_lock(&mac->sme);
13783 } else {
13784 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
13785 "%s: sme_acquire_global_lock error!",
13786 __func__);
13787 cdf_mem_free(iwcmd);
13788 }
13789
13790 return status;
13791}
13792
13793/*
13794 * sme_wifi_start_logger() - Send the start/stop logging command to WMA
13795 * to either start/stop logging
13796 * @hal: HAL context
13797 * @start_log: Structure containing the wifi start logger params
13798 *
13799 * This function sends the start/stop logging command to WMA
13800 *
13801 * Return: CDF_STATUS_SUCCESS on successful posting
13802 */
13803CDF_STATUS sme_wifi_start_logger(tHalHandle hal,
13804 struct sir_wifi_start_log start_log)
13805{
13806 CDF_STATUS status = CDF_STATUS_SUCCESS;
13807 tpAniSirGlobal mac = PMAC_STRUCT(hal);
13808 cds_msg_t cds_message;
13809 struct sir_wifi_start_log *req_msg;
13810 uint32_t len;
13811
13812 len = sizeof(*req_msg);
13813 req_msg = cdf_mem_malloc(len);
13814 if (!req_msg) {
13815 sms_log(mac, LOGE, FL("cdf_mem_malloc failed"));
13816 return CDF_STATUS_E_NOMEM;
13817 }
13818
13819 cdf_mem_zero(req_msg, len);
13820
13821 req_msg->verbose_level = start_log.verbose_level;
13822 req_msg->flag = start_log.flag;
13823 req_msg->ring_id = start_log.ring_id;
13824
13825 status = sme_acquire_global_lock(&mac->sme);
13826 if (status != CDF_STATUS_SUCCESS) {
13827 sms_log(mac, LOGE,
13828 FL("sme_acquire_global_lock failed(status=%d)"),
13829 status);
13830 cdf_mem_free(req_msg);
13831 return status;
13832 }
13833
13834 /* Serialize the req through MC thread */
13835 cds_message.bodyptr = req_msg;
13836 cds_message.type = SIR_HAL_START_STOP_LOGGING;
13837 status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message);
13838 if (!CDF_IS_STATUS_SUCCESS(status)) {
13839 sms_log(mac, LOGE,
13840 FL("vos_mq_post_message failed!(err=%d)"),
13841 status);
13842 cdf_mem_free(req_msg);
13843 status = CDF_STATUS_E_FAILURE;
13844 }
13845 sme_release_global_lock(&mac->sme);
13846
13847 return status;
13848}
13849
13850/**
13851 * sme_neighbor_middle_of_roaming() - Function to know if
13852 * STA is in the middle of roaming states
13853 * @hal: Handle returned by macOpen
13854 * @sessionId: sessionId of the STA session
13855 *
13856 * This function is a wrapper to call
13857 * csr_neighbor_middle_of_roaming to know STA is in the
13858 * middle of roaming states
13859 *
13860 * Return: True or False
13861 *
13862 */
13863bool sme_neighbor_middle_of_roaming(tHalHandle hHal, uint8_t sessionId)
13864{
13865 return csr_neighbor_middle_of_roaming(PMAC_STRUCT(hHal), sessionId);
13866}
13867
13868/*
13869 * sme_send_flush_logs_cmd_to_fw() - Flush FW logs
13870 * @mac: MAC handle
13871 *
13872 * This function is used to send the command that will
13873 * be used to flush the logs in the firmware
13874 *
13875 * Return: eHalStatus
13876 */
13877CDF_STATUS sme_send_flush_logs_cmd_to_fw(tpAniSirGlobal mac)
13878{
13879 CDF_STATUS status;
13880 cds_msg_t message;
13881
13882 status = sme_acquire_global_lock(&mac->sme);
13883 if (status != CDF_STATUS_SUCCESS) {
13884 sms_log(mac, LOGE,
13885 FL("sme_acquire_global_lock failed!(status=%d)"),
13886 status);
13887 return status;
13888 }
13889
13890 /* Serialize the req through MC thread */
13891 message.bodyptr = NULL;
13892 message.type = SIR_HAL_FLUSH_LOG_TO_FW;
13893 status = cds_mq_post_message(CDS_MQ_ID_WMA, &message);
13894 if (!CDF_IS_STATUS_SUCCESS(status)) {
13895 sms_log(mac, LOGE,
13896 FL("cds_mq_post_message failed!(err=%d)"),
13897 status);
13898 status = CDF_STATUS_E_FAILURE;
13899 }
13900 sme_release_global_lock(&mac->sme);
13901 return status;
13902}
13903
13904/**
13905 * sme_enable_uapsd_for_ac() - enable uapsd for access catagory requerst to WMA
13906 * @cds_ctx: cds context
13907 * @sta_id: station id
13908 * @ac: access catagory
13909 * @tid: tid value
13910 * @pri: user priority
13911 * @srvc_int: service interval
13912 * @sus_int: suspend interval
13913 * @dir: tspec direction
13914 * @psb: PSB value
13915 * @sessionId: session id
13916 * @delay_interval: delay interval
13917 *
13918 * Return: CDF status
13919 */
13920CDF_STATUS sme_enable_uapsd_for_ac(void *cds_ctx, uint8_t sta_id,
13921 sme_ac_enum_type ac, uint8_t tid,
13922 uint8_t pri, uint32_t srvc_int,
13923 uint32_t sus_int,
13924 sme_tspec_dir_type dir,
13925 uint8_t psb, uint32_t sessionId,
13926 uint32_t delay_interval)
13927{
13928 void *wma_handle;
13929 t_wma_trigger_uapsd_params uapsd_params;
13930 enum uapsd_ac access_category;
13931
13932 if (!psb) {
13933 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_DEBUG,
13934 "No need to configure auto trigger:psb is 0");
13935 return CDF_STATUS_SUCCESS;
13936 }
13937
13938 wma_handle = cds_get_context(CDF_MODULE_ID_WMA);
13939 if (!wma_handle) {
13940 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
13941 "wma_handle is NULL");
13942 return CDF_STATUS_E_FAILURE;
13943 }
13944
13945 switch (ac) {
13946 case SME_AC_BK:
13947 access_category = UAPSD_BK;
13948 break;
13949 case SME_AC_BE:
13950 access_category = UAPSD_BE;
13951 break;
13952 case SME_AC_VI:
13953 access_category = UAPSD_VI;
13954 break;
13955 case SME_AC_VO:
13956 access_category = UAPSD_VO;
13957 break;
13958 default:
13959 return CDF_STATUS_E_FAILURE;
13960 }
13961
13962 uapsd_params.wmm_ac = access_category;
13963 uapsd_params.user_priority = pri;
13964 uapsd_params.service_interval = srvc_int;
13965 uapsd_params.delay_interval = delay_interval;
13966 uapsd_params.suspend_interval = sus_int;
13967
13968 if (CDF_STATUS_SUCCESS !=
13969 wma_trigger_uapsd_params(wma_handle, sessionId, &uapsd_params)) {
13970 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
13971 "Failed to Trigger Uapsd params for sessionId %d",
13972 sessionId);
13973 return CDF_STATUS_E_FAILURE;
13974 }
13975 return CDF_STATUS_SUCCESS;
13976}
13977
13978/**
13979 * sme_disable_uapsd_for_ac() - disable uapsed access catagory request to WMA
13980 * @cds_ctx: cds context
13981 * @sta_id: station id
13982 * @ac: access catagory
13983 * @sessionId: session id
13984 *
13985 * Return: CDF status
13986 */
13987CDF_STATUS sme_disable_uapsd_for_ac(void *cds_ctx, uint8_t sta_id,
13988 sme_ac_enum_type ac,
13989 uint32_t sessionId)
13990{
13991 void *wma_handle;
13992 enum uapsd_ac access_category;
13993
13994 switch (ac) {
13995 case SME_AC_BK:
13996 access_category = UAPSD_BK;
13997 break;
13998 case SME_AC_BE:
13999 access_category = UAPSD_BE;
14000 break;
14001 case SME_AC_VI:
14002 access_category = UAPSD_VI;
14003 break;
14004 case SME_AC_VO:
14005 access_category = UAPSD_VO;
14006 break;
14007 default:
14008 return CDF_STATUS_E_FAILURE;
14009 }
14010
14011 wma_handle = cds_get_context(CDF_MODULE_ID_WMA);
14012 if (!wma_handle) {
14013 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
14014 "wma handle is NULL");
14015 return CDF_STATUS_E_FAILURE;
14016 }
14017 if (CDF_STATUS_SUCCESS !=
14018 wma_disable_uapsd_per_ac(wma_handle, sessionId, access_category)) {
14019 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
14020 "Failed to disable uapsd for ac %d for sessionId %d",
14021 ac, sessionId);
14022 return CDF_STATUS_E_FAILURE;
14023 }
14024 return CDF_STATUS_SUCCESS;
14025}
14026
14027/**
14028 * sme_update_nss() - SME API to change the number for spatial streams
14029 * (1 or 2)
14030 * @hal: Handle returned by mac open
14031 * @nss: Number of spatial streams
14032 *
14033 * This function is used to update the number of spatial streams supported.
14034 *
14035 * Return: Success upon successfully changing nss else failure
14036 *
14037 */
14038CDF_STATUS sme_update_nss(tHalHandle h_hal, uint8_t nss)
14039{
14040 CDF_STATUS status;
14041 tpAniSirGlobal mac_ctx = PMAC_STRUCT(h_hal);
14042 uint32_t i, value = 0;
14043 union {
14044 uint16_t cfg_value16;
14045 tSirMacHTCapabilityInfo ht_cap_info;
14046 } uHTCapabilityInfo;
14047 tCsrRoamSession *csr_session;
14048
14049 status = sme_acquire_global_lock(&mac_ctx->sme);
14050
14051 if (CDF_STATUS_SUCCESS == status) {
14052 mac_ctx->roam.configParam.enable2x2 = (nss == 1) ? 0 : 1;
14053
14054 /* get the HT capability info*/
14055 sme_cfg_get_int(mac_ctx, WNI_CFG_HT_CAP_INFO, &value);
14056 uHTCapabilityInfo.cfg_value16 = (0xFFFF & value);
14057
14058 for (i = 0; i < CSR_ROAM_SESSION_MAX; i++) {
14059 if (CSR_IS_SESSION_VALID(mac_ctx, i)) {
14060 csr_session = &mac_ctx->roam.roamSession[i];
14061 csr_session->htConfig.ht_tx_stbc =
14062 uHTCapabilityInfo.ht_cap_info.txSTBC;
14063 }
14064 }
14065
14066 sme_release_global_lock(&mac_ctx->sme);
14067 }
14068 return status;
14069}
14070
14071/**
14072 * sme_set_rssi_threshold_breached_cb() - set rssi threshold breached callback
14073 * @hal: global hal handle
14074 * @cb: callback function pointer
14075 *
14076 * This function stores the rssi threshold breached callback function.
14077 *
14078 * Return: CDF_STATUS enumeration.
14079 */
14080CDF_STATUS sme_set_rssi_threshold_breached_cb(tHalHandle hal,
14081 void (*cb)(void *, struct rssi_breach_event *))
14082{
14083 CDF_STATUS status = CDF_STATUS_SUCCESS;
14084 tpAniSirGlobal mac = PMAC_STRUCT(hal);
14085
14086 status = sme_acquire_global_lock(&mac->sme);
14087 if (!CDF_IS_STATUS_SUCCESS(status)) {
14088 sms_log(mac, LOGE,
14089 FL("sme_acquire_global_lock failed!(status=%d)"),
14090 status);
14091 return status;
14092 }
14093
14094 mac->sme.rssi_threshold_breached_cb = cb;
14095 sme_release_global_lock(&mac->sme);
14096 return status;
14097}
14098
14099/**
14100 * sme_is_any_session_in_connected_state() - SME wrapper API to
14101 * check if any session is in connected state or not.
14102 *
14103 * @hal: Handle returned by mac open
14104 *
14105 * This function is used to check if any valid sme session is in
14106 * connected state or not.
14107 *
14108 * Return: true if any session is connected, else false.
14109 *
14110 */
14111bool sme_is_any_session_in_connected_state(tHalHandle h_hal)
14112{
14113 tpAniSirGlobal mac_ctx = PMAC_STRUCT(h_hal);
14114 CDF_STATUS status;
14115 bool ret = false;
14116
14117 status = sme_acquire_global_lock(&mac_ctx->sme);
14118 if (CDF_STATUS_SUCCESS == status) {
14119 ret = csr_is_any_session_in_connect_state(mac_ctx);
14120 sme_release_global_lock(&mac_ctx->sme);
14121 }
14122 return ret;
14123}
14124
14125/**
14126 * sme_set_rssi_monitoring() - set rssi monitoring
14127 * @hal: global hal handle
14128 * @input: request message
14129 *
14130 * This function constructs the vos message and fill in message type,
14131 * bodyptr with @input and posts it to WDA queue.
14132 *
14133 * Return: CDF_STATUS enumeration
14134 */
14135CDF_STATUS sme_set_rssi_monitoring(tHalHandle hal,
14136 struct rssi_monitor_req *input)
14137{
14138 CDF_STATUS status = CDF_STATUS_SUCCESS;
14139 tpAniSirGlobal mac = PMAC_STRUCT(hal);
14140 cds_msg_t cds_message;
14141 struct rssi_monitor_req *req_msg;
14142
14143 sms_log(mac, LOG1, FL("enter"));
14144 req_msg = cdf_mem_malloc(sizeof(*req_msg));
14145 if (!req_msg) {
14146 sms_log(mac, LOGE, FL("memory allocation failed"));
14147 return CDF_STATUS_E_NOMEM;
14148 }
14149
14150 *req_msg = *input;
14151
14152 status = sme_acquire_global_lock(&mac->sme);
14153 if (!CDF_IS_STATUS_SUCCESS(status)) {
14154 sms_log(mac, LOGE,
14155 FL("sme_acquire_global_lock failed!(status=%d)"),
14156 status);
14157 cdf_mem_free(req_msg);
14158 return status;
14159 }
14160
14161 /* Serialize the req through MC thread */
14162 cds_message.bodyptr = req_msg;
14163 cds_message.type = WMA_SET_RSSI_MONITOR_REQ;
14164 status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message);
14165 if (!CDF_IS_STATUS_SUCCESS(status)) {
14166 sms_log(mac, LOGE,
14167 FL("cds_mq_post_message failed!(err=%d)"),
14168 status);
14169 cdf_mem_free(req_msg);
14170 }
14171 sme_release_global_lock(&mac->sme);
14172
14173 return status;
14174}
14175
14176/**
14177 * sme_fw_mem_dump() - Get FW memory dump
14178 * @hHal: hal handle
14179 * @recvd_req: received memory dump request.
14180 *
14181 * This API is invoked by HDD to indicate FW to start
14182 * dumping firmware memory.
14183 *
14184 * Return: CDF_STATUS
14185 */
14186#ifdef WLAN_FEATURE_MEMDUMP
14187CDF_STATUS sme_fw_mem_dump(tHalHandle hHal, void *recvd_req)
14188{
14189 CDF_STATUS status = CDF_STATUS_SUCCESS;
14190 CDF_STATUS cdf_status = CDF_STATUS_SUCCESS;
14191 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
14192 cds_msg_t msg;
14193 struct fw_dump_req *send_req;
14194 struct fw_dump_seg_req seg_req;
14195 int loop;
14196
14197 send_req = cdf_mem_malloc(sizeof(*send_req));
14198 if (!send_req) {
14199 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
14200 FL("Memory allocation failed for WDA_FW_MEM_DUMP"));
14201 return CDF_STATUS_E_FAILURE;
14202 }
14203 cdf_mem_copy(send_req, recvd_req, sizeof(*send_req));
14204
14205 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_INFO,
14206 FL("request_id:%d num_seg:%d"),
14207 send_req->request_id, send_req->num_seg);
14208 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_INFO,
14209 FL("Segment Information"));
14210 for (loop = 0; loop < send_req->num_seg; loop++) {
14211 seg_req = send_req->segment[loop];
14212 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_INFO,
14213 FL("seg_number:%d"), loop);
14214 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_INFO,
14215 FL("seg_id:%d start_addr_lo:0x%x start_addr_hi:0x%x"),
14216 seg_req.seg_id, seg_req.seg_start_addr_lo,
14217 seg_req.seg_start_addr_hi);
14218 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_INFO,
14219 FL("seg_length:%d dst_addr_lo:0x%x dst_addr_hi:0x%x"),
14220 seg_req.seg_length, seg_req.dst_addr_lo,
14221 seg_req.dst_addr_hi);
14222 }
14223
14224 if (CDF_STATUS_SUCCESS == sme_acquire_global_lock(&pMac->sme)) {
14225 msg.bodyptr = send_req;
14226 msg.type = WMA_FW_MEM_DUMP_REQ;
14227 msg.reserved = 0;
14228
14229 cdf_status = cds_mq_post_message(CDF_MODULE_ID_WMA, &msg);
14230 if (CDF_STATUS_SUCCESS != cdf_status) {
14231 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
14232 FL("Not able to post WMA_FW_MEM_DUMP"));
14233 cdf_mem_free(send_req);
14234 status = CDF_STATUS_E_FAILURE;
14235 }
14236 sme_release_global_lock(&pMac->sme);
14237 } else {
14238 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
14239 FL("Failed to acquire SME Global Lock"));
14240 cdf_mem_free(send_req);
14241 status = CDF_STATUS_E_FAILURE;
14242 }
14243
14244 return status;
14245}
14246#else
14247CDF_STATUS sme_fw_mem_dump(tHalHandle hHal, void *recvd_req)
14248{
14249 return CDF_STATUS_SUCCESS;
14250}
14251#endif /* WLAN_FEATURE_MEMDUMP */
14252
14253/*
14254 * sme_soc_set_pcl() - Send WMI_SOC_SET_PCL_CMDID to the WMA
14255 * @hal: Handle returned by macOpen
14256 * @msg: PCL channel list and length structure
14257 *
14258 * Sends the command to WMA to send WMI_SOC_SET_PCL_CMDID to FW
14259 * Return: CDF_STATUS_SUCCESS on successful posting
14260 */
14261CDF_STATUS sme_soc_set_pcl(tHalHandle hal,
14262 struct sir_pcl_list msg)
14263{
14264 CDF_STATUS status = CDF_STATUS_SUCCESS;
14265 tpAniSirGlobal mac = PMAC_STRUCT(hal);
14266 cds_msg_t cds_message;
14267 struct sir_pcl_list *req_msg;
14268 uint32_t len, i;
14269
14270 len = sizeof(*req_msg);
14271
14272 req_msg = cdf_mem_malloc(len);
14273 if (!req_msg) {
14274 sms_log(mac, LOGE, FL("cdf_mem_malloc failed"));
14275 return CDF_STATUS_E_NOMEM;
14276 }
14277
14278 cdf_mem_zero(req_msg, len);
14279
14280 for (i = 0; i < msg.pcl_len; i++)
14281 req_msg->pcl_list[i] = msg.pcl_list[i];
14282
14283 req_msg->pcl_len = msg.pcl_len;
14284
14285 status = sme_acquire_global_lock(&mac->sme);
14286 if (status != CDF_STATUS_SUCCESS) {
14287 sms_log(mac, LOGE,
14288 FL("sme_AcquireGlobalLock failed!(status=%d)"),
14289 status);
14290 cdf_mem_free(req_msg);
14291 return status;
14292 }
14293
14294 /* Serialize the req through MC thread */
14295 cds_message.bodyptr = req_msg;
14296 cds_message.type = SIR_HAL_SOC_SET_PCL_TO_FW;
14297 status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message);
14298 if (!CDF_IS_STATUS_SUCCESS(status)) {
14299 sms_log(mac, LOGE,
14300 FL("vos_mq_post_message failed!(err=%d)"),
14301 status);
14302 cdf_mem_free(req_msg);
14303 status = CDF_STATUS_E_FAILURE;
14304 }
14305 sme_release_global_lock(&mac->sme);
14306
14307 return status;
14308}
14309
14310/*
14311 * sme_soc_set_hw_mode() - Send WMI_SOC_SET_HW_MODE_CMDID to the WMA
14312 * @hal: Handle returned by macOpen
14313 * @msg: HW mode structure containing hw mode and callback details
14314 *
14315 * Sends the command to CSR to send WMI_SOC_SET_HW_MODE_CMDID to FW
14316 * Return: CDF_STATUS_SUCCESS on successful posting
14317 */
14318CDF_STATUS sme_soc_set_hw_mode(tHalHandle hal,
14319 struct sir_hw_mode msg)
14320{
14321 CDF_STATUS status = CDF_STATUS_SUCCESS;
14322 tpAniSirGlobal mac = PMAC_STRUCT(hal);
14323 tSmeCmd *cmd = NULL;
14324
14325 status = sme_acquire_global_lock(&mac->sme);
14326 if (!CDF_IS_STATUS_SUCCESS(status)) {
14327 sms_log(mac, LOGE, FL("Failed to acquire lock"));
14328 return CDF_STATUS_E_RESOURCES;
14329 }
14330
14331 cmd = sme_get_command_buffer(mac);
14332 if (!cmd) {
14333 sms_log(mac, LOGE, FL("Get command buffer failed"));
14334 sme_release_global_lock(&mac->sme);
14335 return CDF_STATUS_E_NULL_VALUE;
14336 }
14337
14338 cmd->command = e_sme_command_set_hw_mode;
14339 cmd->u.set_hw_mode_cmd.hw_mode_index = msg.hw_mode_index;
14340 cmd->u.set_hw_mode_cmd.set_hw_mode_cb = msg.set_hw_mode_cb;
14341
14342 sms_log(mac, LOG1, FL("Queuing e_sme_command_set_hw_mode to CSR"));
14343 csr_queue_sme_command(mac, cmd, false);
14344
14345 sme_release_global_lock(&mac->sme);
14346 return CDF_STATUS_SUCCESS;
14347}
14348
14349/**
14350 * sme_register_hw_mode_trans_cb() - HW mode transition callback registration
14351 * @hal: Handle returned by macOpen
14352 * @callback: HDD callback to be registered
14353 *
14354 * Registers the HDD callback with SME. This callback will be invoked when
14355 * HW mode transition event is received from the FW
14356 *
14357 * Return: None
14358 */
14359void sme_register_hw_mode_trans_cb(tHalHandle hal,
14360 hw_mode_transition_cb callback)
14361{
14362 tpAniSirGlobal mac = PMAC_STRUCT(hal);
14363
14364 mac->sme.sme_hw_mode_trans_cb = callback;
14365 sms_log(mac, LOG1, FL("HW mode transition callback registered"));
14366}
14367
14368/**
14369 * sme_nss_update_request() - Send beacon templete update to FW with new
14370 * nss value
14371 * @hal: Handle returned by macOpen
14372 * @vdev_id: the session id
14373 * @new_nss: the new nss value
14374 * @cback: hdd callback
14375 * @next_action: next action to happen at policy mgr after beacon update
14376 *
14377 * Sends the command to CSR to send to PE
14378 * Return: CDF_STATUS_SUCCESS on successful posting
14379 */
14380CDF_STATUS sme_nss_update_request(tHalHandle hHal, uint32_t vdev_id,
14381 uint8_t new_nss, void *cback, uint8_t next_action,
14382 void *hdd_context)
14383{
14384 CDF_STATUS status = CDF_STATUS_E_FAILURE;
14385 tpAniSirGlobal mac = PMAC_STRUCT(hHal);
14386 tSmeCmd *cmd = NULL;
14387
14388 status = sme_acquire_global_lock(&mac->sme);
14389 if (CDF_IS_STATUS_SUCCESS(status)) {
14390 cmd = sme_get_command_buffer(mac);
14391 if (!cmd) {
14392 sms_log(mac, LOGE, FL("Get command buffer failed"));
14393 sme_release_global_lock(&mac->sme);
14394 return CDF_STATUS_E_NULL_VALUE;
14395 }
14396 cmd->command = e_sme_command_nss_update;
14397 /* Sessionized modules may require this info */
14398 cmd->sessionId = vdev_id;
14399 cmd->u.nss_update_cmd.new_nss = new_nss;
14400 cmd->u.nss_update_cmd.session_id = vdev_id;
14401 cmd->u.nss_update_cmd.nss_update_cb = cback;
14402 cmd->u.nss_update_cmd.context = hdd_context;
14403 cmd->u.nss_update_cmd.next_action = next_action;
14404
14405 sms_log(mac, LOG1, FL("Queuing e_sme_command_nss_update to CSR"));
14406 csr_queue_sme_command(mac, cmd, false);
14407 sme_release_global_lock(&mac->sme);
14408 }
14409 return status;
14410}
14411
14412/**
14413 * sme_soc_set_dual_mac_config() - Set dual mac configurations
14414 * @hal: Handle returned by macOpen
14415 * @msg: Structure containing the dual mac config parameters
14416 *
14417 * Queues configuration information to CSR to configure
14418 * WLAN firmware for the dual MAC features
14419 *
14420 * Return: CDF_STATUS
14421 */
14422CDF_STATUS sme_soc_set_dual_mac_config(tHalHandle hal,
14423 struct sir_dual_mac_config msg)
14424{
14425 CDF_STATUS status = CDF_STATUS_SUCCESS;
14426 tpAniSirGlobal mac = PMAC_STRUCT(hal);
14427 tSmeCmd *cmd;
14428
14429 status = sme_acquire_global_lock(&mac->sme);
14430 if (!CDF_IS_STATUS_SUCCESS(status)) {
14431 sms_log(mac, LOGE, FL("Failed to acquire lock"));
14432 return CDF_STATUS_E_RESOURCES;
14433 }
14434
14435 cmd = sme_get_command_buffer(mac);
14436 if (!cmd) {
14437 sms_log(mac, LOGE, FL("Get command buffer failed"));
14438 sme_release_global_lock(&mac->sme);
14439 return CDF_STATUS_E_NULL_VALUE;
14440 }
14441
14442 cmd->command = e_sme_command_set_dual_mac_config;
14443 cmd->u.set_dual_mac_cmd.scan_config = msg.scan_config;
14444 cmd->u.set_dual_mac_cmd.fw_mode_config = msg.fw_mode_config;
14445 cmd->u.set_dual_mac_cmd.set_dual_mac_cb = msg.set_dual_mac_cb;
14446
14447 sms_log(mac, LOG1,
14448 FL("Queuing e_sme_command_set_dual_mac_config to CSR: %x %x"),
14449 cmd->u.set_dual_mac_cmd.scan_config,
14450 cmd->u.set_dual_mac_cmd.fw_mode_config);
14451 csr_queue_sme_command(mac, cmd, false);
14452
14453 sme_release_global_lock(&mac->sme);
14454 return CDF_STATUS_SUCCESS;
14455}
14456
14457/**
14458 * sme_set_peer_authorized() - call peer authorized callback
14459 * @peer_addr: peer mac address
14460 * @auth_cb: auth callback
14461 * @vdev_id: vdev id
14462 *
14463 * Return: CDF Status
14464 */
14465CDF_STATUS sme_set_peer_authorized(uint8_t *peer_addr,
14466 sme_peer_authorized_fp auth_cb,
14467 uint32_t vdev_id)
14468{
14469 void *wma_handle;
14470
14471 wma_handle = cds_get_context(CDF_MODULE_ID_WMA);
14472 if (!wma_handle) {
14473 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
14474 "wma handle is NULL");
14475 return CDF_STATUS_E_FAILURE;
14476 }
14477
14478 wma_set_peer_authorized_cb(wma_handle, auth_cb);
14479 return wma_set_peer_param(wma_handle, peer_addr, WMI_PEER_AUTHORIZE,
14480 1, vdev_id);
14481}
14482
14483/*
14484 * sme_disable_non_fcc_channel() - non-fcc channel disable request
14485 * @hal: HAL pointer
14486 * @fcc_constraint: true: disable, false; enable
14487 *
14488 * Return: CDF_STATUS
14489 */
14490CDF_STATUS sme_disable_non_fcc_channel(tHalHandle hal, bool fcc_constraint)
14491{
14492 CDF_STATUS status;
14493 tpAniSirGlobal mac_ptr = PMAC_STRUCT(hal);
14494
14495 status = sme_acquire_global_lock(&mac_ptr->sme);
14496
14497 if (CDF_STATUS_SUCCESS == status) {
14498
14499 if (fcc_constraint != mac_ptr->scan.fcc_constraint) {
14500 mac_ptr->scan.fcc_constraint = fcc_constraint;
14501
14502 /* update the channel list in firmware */
14503 status = csr_update_channel_list(mac_ptr);
14504 }
14505
14506 sme_release_global_lock(&mac_ptr->sme);
14507 }
14508
14509 return status;
14510}
14511/**
14512 * sme_setdef_dot11mode() - Updates pMac with default dot11mode
14513 * @hal: Global MAC pointer
14514 *
14515 * Return: NULL.
14516 */
14517void sme_setdef_dot11mode(tHalHandle hal)
14518{
14519 tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
14520 csr_set_default_dot11_mode(mac_ctx);
14521}
14522
14523/**
14524 * sme_update_roam_scan_hi_rssi_scan_params() - update high rssi scan
14525 * params
14526 * @hal_handle - The handle returned by macOpen.
14527 * @session_id - Session Identifier
14528 * @notify_id - Identifies 1 of the 4 parameters to be modified
14529 * @val New value of the parameter
14530 *
14531 * Return: CDF_STATUS - SME update config successful.
14532 * Other status means SME failed to update
14533 */
14534
14535CDF_STATUS sme_update_roam_scan_hi_rssi_scan_params(tHalHandle hal_handle,
14536 uint8_t session_id,
14537 uint32_t notify_id,
14538 int32_t val)
14539{
14540 tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal_handle);
14541 CDF_STATUS status = CDF_STATUS_SUCCESS;
14542 tCsrNeighborRoamConfig *nr_config = NULL;
14543 tpCsrNeighborRoamControlInfo nr_info = NULL;
14544 uint32_t reason = 0;
14545
14546 status = sme_acquire_global_lock(&mac_ctx->sme);
14547 if (CDF_IS_STATUS_SUCCESS(status)) {
14548 nr_config = &mac_ctx->roam.configParam.neighborRoamConfig;
14549 nr_info = &mac_ctx->roam.neighborRoamInfo[session_id];
14550 switch (notify_id) {
14551 case eCSR_HI_RSSI_SCAN_MAXCOUNT_ID:
14552 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_INFO,
14553 "%s: gRoamScanHirssiMaxCount %d => %d",
14554 __func__, nr_config->nhi_rssi_scan_max_count,
14555 val);
14556 nr_config->nhi_rssi_scan_max_count = val;
14557 nr_info->cfgParams.hi_rssi_scan_max_count = val;
14558 reason = REASON_ROAM_SCAN_HI_RSSI_MAXCOUNT_CHANGED;
14559 break;
14560
14561 case eCSR_HI_RSSI_SCAN_RSSI_DELTA_ID:
14562 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_INFO,
14563 FL("gRoamScanHiRssiDelta %d => %d"),
14564 nr_config->nhi_rssi_scan_rssi_delta,
14565 val);
14566 nr_config->nhi_rssi_scan_rssi_delta = val;
14567 nr_info->cfgParams.hi_rssi_scan_rssi_delta = val;
14568 reason = REASON_ROAM_SCAN_HI_RSSI_DELTA_CHANGED;
14569 break;
14570
14571 case eCSR_HI_RSSI_SCAN_DELAY_ID:
14572 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_INFO,
14573 FL("gRoamScanHiRssiDelay %d => %d"),
14574 nr_config->nhi_rssi_scan_delay,
14575 val);
14576 nr_config->nhi_rssi_scan_delay = val;
14577 nr_info->cfgParams.hi_rssi_scan_delay = val;
14578 reason = REASON_ROAM_SCAN_HI_RSSI_DELAY_CHANGED;
14579 break;
14580
14581 case eCSR_HI_RSSI_SCAN_RSSI_UB_ID:
14582 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_INFO,
14583 FL("gRoamScanHiRssiUpperBound %d => %d"),
14584 nr_config->nhi_rssi_scan_rssi_ub,
14585 val);
14586 nr_config->nhi_rssi_scan_rssi_ub = val;
14587 nr_info->cfgParams.hi_rssi_scan_rssi_ub = val;
14588 reason = REASON_ROAM_SCAN_HI_RSSI_UB_CHANGED;
14589 break;
14590
14591 default:
14592 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_INFO,
14593 FL("invalid parameter notify_id %d"),
14594 notify_id);
14595 status = CDF_STATUS_E_INVAL;
14596 break;
14597 }
14598 sme_release_global_lock(&mac_ctx->sme);
14599 }
14600#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
14601 if (mac_ctx->roam.configParam.isRoamOffloadScanEnabled &&
14602 status == CDF_STATUS_SUCCESS) {
14603 csr_roam_offload_scan(mac_ctx, session_id,
14604 ROAM_SCAN_OFFLOAD_UPDATE_CFG, reason);
14605 }
14606#endif
14607
14608 return status;
14609}
14610