1 /*
2 * Copyright (c) 2011-2021 The Linux Foundation. All rights reserved.
3 * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
4 *
5 * Permission to use, copy, modify, and/or distribute this software for
6 * any purpose with or without fee is hereby granted, provided that the
7 * above copyright notice and this permission notice appear in all
8 * copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
11 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
12 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
13 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
16 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17 * PERFORMANCE OF THIS SOFTWARE.
18 */
19
20 /*
21 * DOC: csr_api_scan.c
22 *
23 * Implementation for the Common Scan interfaces.
24 */
25
26 #include "ani_global.h"
27
28 #include "csr_inside_api.h"
29 #include "sme_inside.h"
30
31 #include "csr_support.h"
32
33 #include "host_diag_core_log.h"
34 #include "host_diag_core_event.h"
35
36 #include "cds_reg_service.h"
37 #include "wma_types.h"
38 #include "cds_utils.h"
39 #include "wma.h"
40
41 #include "wlan_policy_mgr_api.h"
42 #include "wlan_hdd_main.h"
43 #include "pld_common.h"
44 #include "csr_internal.h"
45 #include <wlan_scan_api.h>
46 #include <wlan_scan_api.h>
47 #include <wlan_scan_utils_api.h>
48 #include <wlan_objmgr_vdev_obj.h>
49 #include <wlan_objmgr_pdev_obj.h>
50 #include <wlan_utility.h>
51 #include "wlan_reg_services_api.h"
52 #include "sch_api.h"
53 #include "wlan_dlm_api.h"
54 #include "qdf_crypto.h"
55 #include <wlan_crypto_global_api.h>
56 #include "wlan_reg_ucfg_api.h"
57 #include "wlan_cm_bss_score_param.h"
58
59 static void csr_set_cfg_valid_channel_list(struct mac_context *mac,
60 uint32_t *pchan_freq_list,
61 uint8_t NumChannels);
62
63 static void csr_save_tx_power_to_cfg(struct mac_context *mac,
64 tDblLinkList *pList,
65 uint32_t cfgId);
66
67 static void csr_purge_channel_power(struct mac_context *mac,
68 tDblLinkList *pChannelList);
69
70 /* pResult is invalid calling this function. */
csr_free_scan_result_entry(struct mac_context * mac,struct tag_csrscan_result * pResult)71 void csr_free_scan_result_entry(struct mac_context *mac,
72 struct tag_csrscan_result *pResult)
73 {
74 if (pResult->Result.pvIes)
75 qdf_mem_free(pResult->Result.pvIes);
76
77 qdf_mem_free(pResult);
78 }
79
csr_ll_scan_purge_result(struct mac_context * mac,tDblLinkList * pList)80 static QDF_STATUS csr_ll_scan_purge_result(struct mac_context *mac,
81 tDblLinkList *pList)
82 {
83 QDF_STATUS status = QDF_STATUS_SUCCESS;
84 tListElem *pEntry;
85 struct tag_csrscan_result *bss_desc;
86
87 while ((pEntry = csr_ll_remove_head(pList, LL_ACCESS_NOLOCK)) != NULL) {
88 bss_desc = GET_BASE_ADDR(pEntry, struct tag_csrscan_result,
89 Link);
90 csr_free_scan_result_entry(mac, bss_desc);
91 }
92
93 return status;
94 }
95
csr_scan_open(struct mac_context * mac_ctx)96 QDF_STATUS csr_scan_open(struct mac_context *mac_ctx)
97 {
98 csr_ll_open(&mac_ctx->scan.channelPowerInfoList24);
99 csr_ll_open(&mac_ctx->scan.channelPowerInfoList5G);
100
101 return QDF_STATUS_SUCCESS;
102 }
103
csr_scan_close(struct mac_context * mac)104 QDF_STATUS csr_scan_close(struct mac_context *mac)
105 {
106 csr_purge_channel_power(mac, &mac->scan.channelPowerInfoList24);
107 csr_purge_channel_power(mac, &mac->scan.channelPowerInfoList5G);
108 csr_ll_close(&mac->scan.channelPowerInfoList24);
109 csr_ll_close(&mac->scan.channelPowerInfoList5G);
110 wlan_scan_psoc_set_disable(mac->psoc, REASON_SYSTEM_DOWN);
111
112 return QDF_STATUS_SUCCESS;
113 }
114
csr_scan_result_purge(struct mac_context * mac,tScanResultHandle hScanList)115 QDF_STATUS csr_scan_result_purge(struct mac_context *mac,
116 tScanResultHandle hScanList)
117 {
118 QDF_STATUS status = QDF_STATUS_E_INVAL;
119 struct scan_result_list *pScanList =
120 (struct scan_result_list *) hScanList;
121
122 if (pScanList) {
123 status = csr_ll_scan_purge_result(mac, &pScanList->List);
124 csr_ll_close(&pScanList->List);
125 qdf_mem_free(pScanList);
126 }
127 return status;
128 }
129
csr_purge_channel_power(struct mac_context * mac,tDblLinkList * pChannelList)130 static void csr_purge_channel_power(struct mac_context *mac,
131 tDblLinkList *pChannelList)
132 {
133 struct csr_channel_powerinfo *pChannelSet;
134 tListElem *pEntry;
135
136 /*
137 * Remove the channel sets from the learned list and put them
138 * in the free list
139 */
140 csr_ll_lock(pChannelList);
141 while ((pEntry = csr_ll_remove_head(pChannelList,
142 LL_ACCESS_NOLOCK)) != NULL) {
143 pChannelSet = GET_BASE_ADDR(pEntry,
144 struct csr_channel_powerinfo, link);
145 if (pChannelSet)
146 qdf_mem_free(pChannelSet);
147 }
148 csr_ll_unlock(pChannelList);
149 }
150
151 #define FREQ_SIZE 4
152 #define SPACE_SIZE 2
153 #define SIZEOFNULL 1
154 #define BUF24GHZSIZE (NUM_24GHZ_CHANNELS * (\
155 FREQ_SIZE + SPACE_SIZE) + SIZEOFNULL)
156 #define BUF5GHZSIZE (NUM_5GHZ_CHANNELS * (\
157 FREQ_SIZE + SPACE_SIZE) + SIZEOFNULL)
158
159 /*
160 * Save the channelList into the ultimate storage as the final stage of channel
161 * Input: pCountryInfo -- the country code (e.g. "USI"), channel list, and power
162 * limit are all stored inside this data structure
163 */
csr_save_to_channel_power2_g_5_g(struct mac_context * mac,uint32_t tableSize,struct pwr_channel_info * channelTable)164 QDF_STATUS csr_save_to_channel_power2_g_5_g(struct mac_context *mac,
165 uint32_t tableSize,
166 struct pwr_channel_info *channelTable)
167 {
168 uint32_t i = tableSize / sizeof(struct pwr_channel_info);
169 struct pwr_channel_info *pChannelInfo;
170 struct csr_channel_powerinfo *pchannelset;
171 bool f2GHzInfoFound = false;
172 bool f2GListPurged = false, f5GListPurged = false;
173 uint8_t *buf24ghz = qdf_mem_malloc(BUF24GHZSIZE);
174 uint8_t *buf5ghz = qdf_mem_malloc(BUF5GHZSIZE);
175 uint32_t size24ghz = 0, size5ghz = 0;
176
177 if (!buf24ghz || !buf5ghz) {
178 if (buf24ghz)
179 qdf_mem_free(buf24ghz);
180 if (buf5ghz)
181 qdf_mem_free(buf5ghz);
182 return QDF_STATUS_E_NOMEM;
183 }
184 pChannelInfo = channelTable;
185 /* atleast 3 bytes have to be remaining -- from "countryString" */
186 while (i--) {
187 pchannelset = qdf_mem_malloc(sizeof(struct csr_channel_powerinfo));
188 if (!pchannelset) {
189 pChannelInfo++;
190 continue;
191 }
192 pchannelset->first_chan_freq = pChannelInfo->first_freq;
193 pchannelset->numChannels = pChannelInfo->num_chan;
194 /*
195 * Now set the inter-channel offset based on the frequency band
196 * the channel set lies in
197 */
198 if (WLAN_REG_IS_24GHZ_CH_FREQ(pchannelset->first_chan_freq) &&
199 (pchannelset->first_chan_freq + 5 * (pchannelset->numChannels - 1) <=
200 WLAN_REG_MAX_24GHZ_CHAN_FREQ)) {
201 pchannelset->interChannelOffset = 5;
202 f2GHzInfoFound = true;
203 } else if (WLAN_REG_IS_5GHZ_CH_FREQ(pchannelset->first_chan_freq) &&
204 (pchannelset->first_chan_freq + 20 * (pchannelset->numChannels - 1) <=
205 WLAN_REG_MAX_5GHZ_CHAN_FREQ)) {
206 pchannelset->interChannelOffset = 20;
207 f2GHzInfoFound = false;
208 } else {
209 sme_warn("Invalid Channel freq %d Present in Country IE",
210 pchannelset->first_chan_freq);
211 qdf_mem_free(pchannelset);
212 qdf_mem_free(buf24ghz);
213 qdf_mem_free(buf5ghz);
214 return QDF_STATUS_E_FAILURE;
215 }
216 pchannelset->txPower = pChannelInfo->max_tx_pwr;
217 if (f2GHzInfoFound) {
218 if (!f2GListPurged) {
219 /* purge previous results if found new */
220 csr_purge_channel_power(mac,
221 &mac->scan.
222 channelPowerInfoList24);
223 f2GListPurged = true;
224 }
225 if (CSR_IS_OPERATING_BG_BAND(mac)) {
226 /* add to the list of 2.4 GHz channel sets */
227 csr_ll_insert_tail(&mac->scan.
228 channelPowerInfoList24,
229 &pchannelset->link,
230 LL_ACCESS_LOCK);
231 } else {
232 size24ghz += qdf_scnprintf(
233 buf24ghz + size24ghz,
234 BUF24GHZSIZE - size24ghz, " %d",
235 pchannelset->first_chan_freq);
236 qdf_mem_free(pchannelset);
237 }
238 } else {
239 /* 5GHz info found */
240 if (!f5GListPurged) {
241 /* purge previous results if found new */
242 csr_purge_channel_power(mac,
243 &mac->scan.
244 channelPowerInfoList5G);
245 f5GListPurged = true;
246 }
247 if (CSR_IS_OPERATING_A_BAND(mac)) {
248 /* add to the list of 5GHz channel sets */
249 csr_ll_insert_tail(&mac->scan.
250 channelPowerInfoList5G,
251 &pchannelset->link,
252 LL_ACCESS_LOCK);
253 } else {
254 size5ghz += qdf_scnprintf(
255 buf5ghz + size5ghz,
256 BUF5GHZSIZE - size5ghz, " %d",
257 pchannelset->first_chan_freq);
258 qdf_mem_free(pchannelset);
259 }
260 }
261 pChannelInfo++; /* move to next entry */
262 }
263 if (size24ghz)
264 sme_nofl_debug("Adding 11B/G ch in 11A:%s", buf24ghz);
265 qdf_mem_free(buf24ghz);
266 if (size5ghz)
267 sme_nofl_debug("Adding 11A ch in B/G:%s", buf5ghz);
268 qdf_mem_free(buf5ghz);
269 return QDF_STATUS_SUCCESS;
270 }
csr_apply_power2_current(struct mac_context * mac)271 void csr_apply_power2_current(struct mac_context *mac)
272 {
273 sme_debug("Updating Cfg with power settings");
274 csr_save_tx_power_to_cfg(mac, &mac->scan.channelPowerInfoList24,
275 BAND_2G);
276 csr_save_tx_power_to_cfg(mac, &mac->scan.channelPowerInfoList5G,
277 BAND_5G);
278 }
279
csr_apply_channel_power_info_to_fw(struct mac_context * mac_ctx,struct csr_channel * ch_lst)280 void csr_apply_channel_power_info_to_fw(struct mac_context *mac_ctx,
281 struct csr_channel *ch_lst)
282 {
283 int i;
284 uint8_t num_ch = 0;
285 uint8_t tempNumChannels = 0;
286 struct csr_channel tmp_ch_lst;
287
288 if (ch_lst->numChannels) {
289 tempNumChannels = QDF_MIN(ch_lst->numChannels,
290 CFG_VALID_CHANNEL_LIST_LEN);
291 for (i = 0; i < tempNumChannels; i++) {
292 tmp_ch_lst.channel_freq_list[num_ch] = ch_lst->channel_freq_list[i];
293 num_ch++;
294 }
295 tmp_ch_lst.numChannels = num_ch;
296 /* Store the channel+power info in the global place: Cfg */
297 csr_apply_power2_current(mac_ctx);
298 csr_set_cfg_valid_channel_list(mac_ctx, tmp_ch_lst.channel_freq_list,
299 tmp_ch_lst.numChannels);
300 } else {
301 sme_err("11D channel list is empty");
302 }
303 sch_edca_profile_update_all(mac_ctx);
304 }
305
306 #ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
csr_diag_reset_country_information(struct mac_context * mac)307 static void csr_diag_reset_country_information(struct mac_context *mac)
308 {
309
310 host_log_802_11d_pkt_type *p11dLog;
311 int Index;
312 uint8_t reg_cc[REG_ALPHA2_LEN + 1];
313
314 WLAN_HOST_DIAG_LOG_ALLOC(p11dLog, host_log_802_11d_pkt_type,
315 LOG_WLAN_80211D_C);
316 if (!p11dLog)
317 return;
318
319 p11dLog->eventId = WLAN_80211D_EVENT_RESET;
320 wlan_reg_read_current_country(mac->psoc, reg_cc);
321 qdf_mem_copy(p11dLog->countryCode, reg_cc, 3);
322 p11dLog->numChannel = mac->scan.base_channels.numChannels;
323 if (p11dLog->numChannel <= HOST_LOG_MAX_NUM_CHANNEL) {
324 for (Index = 0;
325 Index < mac->scan.base_channels.numChannels;
326 Index++) {
327 p11dLog->Channels[Index] =
328 wlan_reg_freq_to_chan(mac->pdev, mac->scan.base_channels.channel_freq_list[Index]);
329 p11dLog->TxPwr[Index] =
330 mac->scan.defaultPowerTable[Index].tx_power;
331 }
332 }
333
334 WLAN_HOST_DIAG_LOG_REPORT(p11dLog);
335 }
336 #endif /* FEATURE_WLAN_DIAG_SUPPORT_CSR */
337
338 /**
339 * csr_apply_channel_power_info_wrapper() - sends channel info to fw
340 * @mac: main MAC data structure
341 *
342 * This function sends the channel power info to firmware
343 *
344 * Return: none
345 */
csr_apply_channel_power_info_wrapper(struct mac_context * mac)346 void csr_apply_channel_power_info_wrapper(struct mac_context *mac)
347 {
348
349 #ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
350 csr_diag_reset_country_information(mac);
351 #endif /* FEATURE_WLAN_DIAG_SUPPORT_CSR */
352 csr_prune_channel_list_for_mode(mac, &mac->scan.base_channels);
353 csr_save_channel_power_for_band(mac, false);
354 csr_save_channel_power_for_band(mac, true);
355 /* apply the channel list, power settings, and the country code. */
356 csr_apply_channel_power_info_to_fw(mac, &mac->scan.base_channels);
357 /* clear the 11d channel list */
358 qdf_mem_zero(&mac->scan.channels11d, sizeof(mac->scan.channels11d));
359 }
360
csr_save_channel_power_for_band(struct mac_context * mac,bool fill_5f)361 void csr_save_channel_power_for_band(struct mac_context *mac, bool fill_5f)
362 {
363 uint32_t idx, count = 0;
364 struct pwr_channel_info *chan_info;
365 struct pwr_channel_info *ch_info_start;
366 int32_t max_ch_idx;
367 bool tmp_bool;
368 uint32_t ch_freq = 0;
369
370 max_ch_idx =
371 (mac->scan.base_channels.numChannels <
372 CFG_VALID_CHANNEL_LIST_LEN) ?
373 mac->scan.base_channels.numChannels :
374 CFG_VALID_CHANNEL_LIST_LEN;
375
376 chan_info = qdf_mem_malloc(sizeof(struct pwr_channel_info) *
377 CFG_VALID_CHANNEL_LIST_LEN);
378 if (!chan_info)
379 return;
380
381 ch_info_start = chan_info;
382 for (idx = 0; idx < max_ch_idx; idx++) {
383 ch_freq = mac->scan.defaultPowerTable[idx].center_freq;
384 tmp_bool = (fill_5f && WLAN_REG_IS_5GHZ_CH_FREQ(ch_freq)) ||
385 (!fill_5f && WLAN_REG_IS_24GHZ_CH_FREQ(ch_freq));
386 if (!tmp_bool)
387 continue;
388
389 if (count >= CFG_VALID_CHANNEL_LIST_LEN) {
390 sme_warn("count: %d exceeded", count);
391 break;
392 }
393
394 chan_info->first_freq =
395 mac->scan.defaultPowerTable[idx].center_freq;
396 chan_info->num_chan = 1;
397 chan_info->max_tx_pwr =
398 mac->scan.defaultPowerTable[idx].tx_power;
399 chan_info++;
400 count++;
401 }
402 if (count) {
403 csr_save_to_channel_power2_g_5_g(mac,
404 count * sizeof(struct pwr_channel_info),
405 ch_info_start);
406 }
407 qdf_mem_free(ch_info_start);
408 }
409
csr_is_supported_channel(struct mac_context * mac,uint32_t chan_freq)410 bool csr_is_supported_channel(struct mac_context *mac, uint32_t chan_freq)
411 {
412 bool fRet = false;
413 uint32_t i;
414
415 for (i = 0; i < mac->scan.base_channels.numChannels; i++) {
416 if (chan_freq == mac->scan.base_channels.channel_freq_list[i]) {
417 fRet = true;
418 break;
419 }
420 }
421
422 return fRet;
423 }
424
csr_scan_result_get_first(struct mac_context * mac,tScanResultHandle hScanResult)425 tCsrScanResultInfo *csr_scan_result_get_first(struct mac_context *mac,
426 tScanResultHandle hScanResult)
427 {
428 tListElem *pEntry;
429 struct tag_csrscan_result *pResult;
430 tCsrScanResultInfo *pRet = NULL;
431 struct scan_result_list *pResultList =
432 (struct scan_result_list *) hScanResult;
433
434 if (pResultList) {
435 pEntry = csr_ll_peek_head(&pResultList->List, LL_ACCESS_NOLOCK);
436 if (pEntry) {
437 pResult = GET_BASE_ADDR(pEntry, struct
438 tag_csrscan_result, Link);
439 pRet = &pResult->Result;
440 }
441 pResultList->pCurEntry = pEntry;
442 }
443
444 return pRet;
445 }
446
csr_scan_result_get_next(struct mac_context * mac,tScanResultHandle hScanResult)447 tCsrScanResultInfo *csr_scan_result_get_next(struct mac_context *mac,
448 tScanResultHandle hScanResult)
449 {
450 tListElem *pEntry = NULL;
451 struct tag_csrscan_result *pResult = NULL;
452 tCsrScanResultInfo *pRet = NULL;
453 struct scan_result_list *pResultList =
454 (struct scan_result_list *) hScanResult;
455
456 if (!pResultList)
457 return NULL;
458
459 if (!pResultList->pCurEntry)
460 pEntry = csr_ll_peek_head(&pResultList->List, LL_ACCESS_NOLOCK);
461 else
462 pEntry = csr_ll_next(&pResultList->List, pResultList->pCurEntry,
463 LL_ACCESS_NOLOCK);
464
465 if (pEntry) {
466 pResult = GET_BASE_ADDR(pEntry, struct tag_csrscan_result,
467 Link);
468 pRet = &pResult->Result;
469 }
470 pResultList->pCurEntry = pEntry;
471
472 return pRet;
473 }
474
csr_set_cfg_valid_channel_list(struct mac_context * mac,uint32_t * pchan_freq_list,uint8_t NumChannels)475 static void csr_set_cfg_valid_channel_list(struct mac_context *mac,
476 uint32_t *pchan_freq_list,
477 uint8_t NumChannels)
478 {
479 QDF_STATUS status;
480 uint8_t i;
481
482 sme_debug("dump valid channel list(NumChannels(%d))", NumChannels);
483 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
484 pchan_freq_list, NumChannels);
485 for (i = 0; i < NumChannels; i++) {
486 mac->mlme_cfg->reg.valid_channel_freq_list[i] = pchan_freq_list[i];
487 }
488
489 mac->mlme_cfg->reg.valid_channel_list_num = NumChannels;
490
491 sme_debug("Scan offload is enabled, update default chan list");
492 /*
493 * disable fcc constraint since new country code
494 * is being set
495 */
496 mac->scan.fcc_constraint = false;
497 status = csr_update_channel_list(mac);
498 if (QDF_STATUS_SUCCESS != status) {
499 sme_err("failed to update the supported channel list");
500 }
501 }
502
503 /*
504 * The Tx power limits are saved in the cfg for future usage.
505 */
csr_save_tx_power_to_cfg(struct mac_context * mac,tDblLinkList * pList,enum band_info band)506 static void csr_save_tx_power_to_cfg(struct mac_context *mac,
507 tDblLinkList *pList,
508 enum band_info band)
509 {
510 tListElem *pEntry;
511 uint32_t cbLen = 0, dataLen, tmp_len;
512 struct csr_channel_powerinfo *ch_set;
513 uint32_t idx, count = 0;
514 struct pwr_channel_info *ch_pwr_set;
515 uint8_t *p_buf = NULL;
516
517 /* allocate maximum space for all channels */
518 dataLen = CFG_VALID_CHANNEL_LIST_LEN * sizeof(struct pwr_channel_info);
519 p_buf = qdf_mem_malloc(dataLen);
520 if (!p_buf)
521 return;
522
523 ch_pwr_set = (struct pwr_channel_info *)(p_buf);
524 csr_ll_lock(pList);
525 pEntry = csr_ll_peek_head(pList, LL_ACCESS_NOLOCK);
526 /*
527 * write the tuples (startChan, numChan, txPower) for each channel found
528 * in the channel power list.
529 */
530 while (pEntry) {
531 ch_set = GET_BASE_ADDR(pEntry,
532 struct csr_channel_powerinfo, link);
533 if (ch_set->interChannelOffset != 5) {
534 /*
535 * we keep the 5G channel sets internally with an
536 * interchannel offset of 4. Expand these to the right
537 * format. (inter channel offset of 1 is the only option
538 * for the triplets that 11d advertises.
539 */
540 tmp_len = cbLen + (ch_set->numChannels *
541 sizeof(struct pwr_channel_info));
542 if (tmp_len >= dataLen) {
543 /*
544 * expanding this entry will overflow our
545 * allocation
546 */
547 sme_err(
548 "Buffer overflow, start freq %d, num %d, offset %d",
549 ch_set->first_chan_freq,
550 ch_set->numChannels,
551 ch_set->interChannelOffset);
552 break;
553 }
554
555 for (idx = 0; idx < ch_set->numChannels; idx++) {
556 ch_pwr_set->first_freq =
557 ch_set->first_chan_freq;
558 ch_pwr_set->num_chan = 1;
559 ch_pwr_set->max_tx_pwr = ch_set->txPower;
560 cbLen += sizeof(struct pwr_channel_info);
561 ch_pwr_set++;
562 count++;
563 }
564 } else {
565 if (cbLen + sizeof(struct pwr_channel_info) >= dataLen) {
566 /* this entry will overflow our allocation */
567 sme_err(
568 "Buffer overflow, start freq %d, num %d, offset %d",
569 ch_set->first_chan_freq,
570 ch_set->numChannels,
571 ch_set->interChannelOffset);
572 break;
573 }
574 ch_pwr_set->first_freq = ch_set->first_chan_freq;
575 ch_pwr_set->num_chan = ch_set->numChannels;
576 ch_pwr_set->max_tx_pwr = ch_set->txPower;
577 cbLen += sizeof(struct pwr_channel_info);
578 ch_pwr_set++;
579 count++;
580 }
581 pEntry = csr_ll_next(pList, pEntry, LL_ACCESS_NOLOCK);
582 }
583 csr_ll_unlock(pList);
584 if (band == BAND_2G) {
585 mac->mlme_cfg->power.max_tx_power_24.len =
586 sizeof(struct pwr_channel_info) * count;
587 if (mac->mlme_cfg->power.max_tx_power_24.len >
588 CFG_MAX_TX_POWER_2_4_LEN)
589 mac->mlme_cfg->power.max_tx_power_24.len =
590 CFG_MAX_TX_POWER_2_4_LEN;
591 qdf_mem_copy(mac->mlme_cfg->power.max_tx_power_24.data,
592 (uint8_t *)p_buf,
593 mac->mlme_cfg->power.max_tx_power_24.len);
594 }
595 if (band == BAND_5G) {
596 mac->mlme_cfg->power.max_tx_power_5.len =
597 sizeof(struct pwr_channel_info) * count;
598 if (mac->mlme_cfg->power.max_tx_power_5.len >
599 CFG_MAX_TX_POWER_5_LEN)
600 mac->mlme_cfg->power.max_tx_power_5.len =
601 CFG_MAX_TX_POWER_5_LEN;
602 qdf_mem_copy(mac->mlme_cfg->power.max_tx_power_5.data,
603 (uint8_t *)p_buf,
604 mac->mlme_cfg->power.max_tx_power_5.len);
605 }
606 qdf_mem_free(p_buf);
607 }
608
csr_fill_rsn_auth_type(enum csr_akm_type * auth_type,uint32_t akm)609 static void csr_fill_rsn_auth_type(enum csr_akm_type *auth_type, uint32_t akm)
610 {
611 /* Try the more preferred ones first. */
612 if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_FT_FILS_SHA384))
613 *auth_type = eCSR_AUTH_TYPE_FT_FILS_SHA384;
614 else if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_FT_FILS_SHA256))
615 *auth_type = eCSR_AUTH_TYPE_FT_FILS_SHA256;
616 else if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_FILS_SHA384))
617 *auth_type = eCSR_AUTH_TYPE_FILS_SHA384;
618 else if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_FILS_SHA256))
619 *auth_type = eCSR_AUTH_TYPE_FILS_SHA256;
620 else if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_FT_SAE_EXT_KEY))
621 *auth_type = eCSR_AUTH_TYPE_FT_SAE_EXT_KEY;
622 else if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_SAE_EXT_KEY))
623 *auth_type = eCSR_AUTH_TYPE_SAE_EXT_KEY;
624 else if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_FT_SAE))
625 *auth_type = eCSR_AUTH_TYPE_FT_SAE;
626 else if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_SAE))
627 *auth_type = eCSR_AUTH_TYPE_SAE;
628 else if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_DPP))
629 *auth_type = eCSR_AUTH_TYPE_DPP_RSN;
630 else if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_OSEN))
631 *auth_type = eCSR_AUTH_TYPE_OSEN;
632 else if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_OWE))
633 *auth_type = eCSR_AUTH_TYPE_OWE;
634 else if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_FT_IEEE8021X))
635 *auth_type = eCSR_AUTH_TYPE_FT_RSN;
636 else if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_FT_PSK))
637 *auth_type = eCSR_AUTH_TYPE_FT_RSN_PSK;
638 else if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_IEEE8021X))
639 *auth_type = eCSR_AUTH_TYPE_RSN;
640 else if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_PSK))
641 *auth_type = eCSR_AUTH_TYPE_RSN_PSK;
642 else if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_CCKM))
643 *auth_type = eCSR_AUTH_TYPE_CCKM_RSN;
644 else if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_PSK_SHA256))
645 *auth_type = eCSR_AUTH_TYPE_RSN_PSK_SHA256;
646 else if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_IEEE8021X_SHA256))
647 *auth_type = eCSR_AUTH_TYPE_RSN_8021X_SHA256;
648 else if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_IEEE8021X_SUITE_B))
649 *auth_type = eCSR_AUTH_TYPE_SUITEB_EAP_SHA256;
650 else if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_IEEE8021X_SUITE_B_192))
651 *auth_type = eCSR_AUTH_TYPE_SUITEB_EAP_SHA384;
652 else if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_FT_IEEE8021X_SHA384))
653 *auth_type = eCSR_AUTH_TYPE_FT_SUITEB_EAP_SHA384;
654 else
655 *auth_type = eCSR_AUTH_TYPE_NONE;
656 }
657
csr_fill_wpa_auth_type(enum csr_akm_type * auth_type,uint32_t akm)658 static void csr_fill_wpa_auth_type(enum csr_akm_type *auth_type, uint32_t akm)
659 {
660 /* Try the more preferred ones first. */
661 if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_IEEE8021X))
662 *auth_type = eCSR_AUTH_TYPE_WPA;
663 else if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_PSK))
664 *auth_type = eCSR_AUTH_TYPE_WPA_PSK;
665 else if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_CCKM))
666 *auth_type = eCSR_AUTH_TYPE_CCKM_WPA;
667 else
668 *auth_type = eCSR_AUTH_TYPE_WPA_NONE;
669 }
670
csr_fill_wapi_auth_type(enum csr_akm_type * auth_type,uint32_t akm)671 static void csr_fill_wapi_auth_type(enum csr_akm_type *auth_type, uint32_t akm)
672 {
673 /* Try the more preferred ones first. */
674 if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_WAPI_CERT))
675 *auth_type = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
676 else if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_WAPI_PSK))
677 *auth_type = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
678 else
679 *auth_type = eCSR_AUTH_TYPE_NONE;
680 }
681
csr_fill_auth_type(enum csr_akm_type * auth_type,uint32_t authmodeset,uint32_t akm,uint32_t ucastcipherset)682 void csr_fill_auth_type(enum csr_akm_type *auth_type,
683 uint32_t authmodeset, uint32_t akm,
684 uint32_t ucastcipherset)
685 {
686 if (!authmodeset) {
687 *auth_type = eCSR_AUTH_TYPE_OPEN_SYSTEM;
688 return;
689 }
690
691 if (QDF_HAS_PARAM(authmodeset, WLAN_CRYPTO_AUTH_NONE) ||
692 QDF_HAS_PARAM(authmodeset, WLAN_CRYPTO_AUTH_OPEN)) {
693 *auth_type = eCSR_AUTH_TYPE_OPEN_SYSTEM;
694 return;
695 }
696
697 if (QDF_HAS_PARAM(authmodeset, WLAN_CRYPTO_AUTH_AUTO)) {
698 if ((QDF_HAS_PARAM(ucastcipherset, WLAN_CRYPTO_CIPHER_WEP) ||
699 QDF_HAS_PARAM(ucastcipherset, WLAN_CRYPTO_CIPHER_WEP_40) ||
700 QDF_HAS_PARAM(ucastcipherset, WLAN_CRYPTO_CIPHER_WEP_104)))
701 *auth_type = eCSR_AUTH_TYPE_AUTOSWITCH;
702 else
703 *auth_type = eCSR_AUTH_TYPE_OPEN_SYSTEM;
704
705 return;
706 }
707
708 if (QDF_HAS_PARAM(authmodeset, WLAN_CRYPTO_AUTH_SHARED)) {
709 *auth_type = eCSR_AUTH_TYPE_SHARED_KEY;
710 return;
711 }
712
713 if (QDF_HAS_PARAM(authmodeset, WLAN_CRYPTO_AUTH_8021X) ||
714 QDF_HAS_PARAM(authmodeset, WLAN_CRYPTO_AUTH_RSNA) ||
715 QDF_HAS_PARAM(authmodeset, WLAN_CRYPTO_AUTH_CCKM) ||
716 QDF_HAS_PARAM(authmodeset, WLAN_CRYPTO_AUTH_SAE) ||
717 QDF_HAS_PARAM(authmodeset, WLAN_CRYPTO_AUTH_FILS_SK)) {
718 csr_fill_rsn_auth_type(auth_type, akm);
719 return;
720 }
721
722 if (QDF_HAS_PARAM(authmodeset, WLAN_CRYPTO_AUTH_WPA)) {
723 csr_fill_wpa_auth_type(auth_type, akm);
724 return;
725 }
726
727 if (QDF_HAS_PARAM(authmodeset, WLAN_CRYPTO_AUTH_WAPI)) {
728 csr_fill_wapi_auth_type(auth_type, akm);
729 return;
730 }
731
732 *auth_type = eCSR_AUTH_TYPE_OPEN_SYSTEM;
733 }
734
csr_fill_enc_type(eCsrEncryptionType * cipher_type,uint32_t cipherset)735 void csr_fill_enc_type(eCsrEncryptionType *cipher_type, uint32_t cipherset)
736 {
737 if (!cipherset) {
738 *cipher_type = eCSR_ENCRYPT_TYPE_NONE;
739 return;
740 }
741 if (QDF_HAS_PARAM(cipherset, WLAN_CRYPTO_CIPHER_AES_GCM_256))
742 *cipher_type = eCSR_ENCRYPT_TYPE_AES_GCMP_256;
743 else if (QDF_HAS_PARAM(cipherset, WLAN_CRYPTO_CIPHER_AES_GCM))
744 *cipher_type = eCSR_ENCRYPT_TYPE_AES_GCMP;
745 else if (QDF_HAS_PARAM(cipherset, WLAN_CRYPTO_CIPHER_AES_CCM) ||
746 QDF_HAS_PARAM(cipherset, WLAN_CRYPTO_CIPHER_AES_OCB) ||
747 QDF_HAS_PARAM(cipherset, WLAN_CRYPTO_CIPHER_AES_CCM_256))
748 *cipher_type = eCSR_ENCRYPT_TYPE_AES;
749 else if (QDF_HAS_PARAM(cipherset, WLAN_CRYPTO_CIPHER_TKIP))
750 *cipher_type = eCSR_ENCRYPT_TYPE_TKIP;
751 else if (QDF_HAS_PARAM(cipherset, WLAN_CRYPTO_CIPHER_AES_CMAC) ||
752 QDF_HAS_PARAM(cipherset, WLAN_CRYPTO_CIPHER_AES_CMAC_256))
753 *cipher_type = eCSR_ENCRYPT_TYPE_AES_CMAC;
754 else if (QDF_HAS_PARAM(cipherset, WLAN_CRYPTO_CIPHER_WAPI_GCM4) ||
755 QDF_HAS_PARAM(cipherset, WLAN_CRYPTO_CIPHER_WAPI_SMS4))
756 *cipher_type = eCSR_ENCRYPT_TYPE_WPI;
757 else if (QDF_HAS_PARAM(cipherset, WLAN_CRYPTO_CIPHER_AES_GMAC))
758 *cipher_type = eCSR_ENCRYPT_TYPE_AES_GMAC_128;
759 else if (QDF_HAS_PARAM(cipherset, WLAN_CRYPTO_CIPHER_AES_GMAC_256))
760 *cipher_type = eCSR_ENCRYPT_TYPE_AES_GMAC_256;
761 else if (QDF_HAS_PARAM(cipherset, WLAN_CRYPTO_CIPHER_WEP))
762 *cipher_type = eCSR_ENCRYPT_TYPE_WEP40;
763 else if (QDF_HAS_PARAM(cipherset, WLAN_CRYPTO_CIPHER_WEP_40))
764 *cipher_type = eCSR_ENCRYPT_TYPE_WEP40;
765 else if (QDF_HAS_PARAM(cipherset, WLAN_CRYPTO_CIPHER_WEP_104))
766 *cipher_type = eCSR_ENCRYPT_TYPE_WEP104;
767 else
768 *cipher_type = eCSR_ENCRYPT_TYPE_NONE;
769 }
770
csr_fill_neg_crypto_info(struct tag_csrscan_result * bss,struct security_info * sec_info)771 static void csr_fill_neg_crypto_info(struct tag_csrscan_result *bss,
772 struct security_info *sec_info)
773 {
774 if (!sec_info->authmodeset && !sec_info->key_mgmt &&
775 !sec_info->ucastcipherset)
776 return;
777
778 csr_fill_enc_type(&bss->ucEncryptionType, sec_info->ucastcipherset);
779 csr_fill_enc_type(&bss->mcEncryptionType, sec_info->mcastcipherset);
780 csr_fill_auth_type(&bss->authType, sec_info->authmodeset,
781 sec_info->key_mgmt, sec_info->ucastcipherset);
782 sme_debug("Authmode %x, AKM %x, Cipher Uc %x Mc %x CSR: Auth %d, Cipher Uc %d Mc %d",
783 sec_info->authmodeset, sec_info->key_mgmt,
784 sec_info->ucastcipherset, sec_info->mcastcipherset,
785 bss->authType, bss->ucEncryptionType, bss->mcEncryptionType);
786 }
787
csr_fill_bss_from_scan_entry(struct mac_context * mac_ctx,struct scan_cache_entry * scan_entry,struct tag_csrscan_result ** p_result)788 static QDF_STATUS csr_fill_bss_from_scan_entry(struct mac_context *mac_ctx,
789 struct scan_cache_entry *scan_entry,
790 struct tag_csrscan_result **p_result)
791 {
792 tDot11fBeaconIEs *bcn_ies;
793 struct bss_description *bss_desc;
794 tCsrScanResultInfo *result_info;
795 uint8_t *ie_ptr;
796 struct tag_csrscan_result *bss;
797 uint32_t bss_len, alloc_len, ie_len;
798 QDF_STATUS status;
799 enum channel_state ap_channel_state;
800
801 ap_channel_state =
802 wlan_reg_get_channel_state_for_pwrmode(
803 mac_ctx->pdev,
804 scan_entry->channel.chan_freq,
805 REG_CURRENT_PWR_MODE);
806 if (ap_channel_state == CHANNEL_STATE_DISABLE ||
807 ap_channel_state == CHANNEL_STATE_INVALID) {
808 sme_err("BSS "QDF_MAC_ADDR_FMT" channel %d invalid, not populating this BSSID",
809 QDF_MAC_ADDR_REF(scan_entry->bssid.bytes),
810 scan_entry->channel.chan_freq);
811 return QDF_STATUS_E_INVAL;
812 }
813
814 ie_len = util_scan_entry_ie_len(scan_entry);
815 ie_ptr = util_scan_entry_ie_data(scan_entry);
816
817 bss_len = (uint16_t)(offsetof(struct bss_description,
818 ieFields[0]) + ie_len);
819 alloc_len = sizeof(struct tag_csrscan_result) + bss_len;
820 bss = qdf_mem_malloc(alloc_len);
821 if (!bss)
822 return QDF_STATUS_E_NOMEM;
823
824 csr_fill_neg_crypto_info(bss, &scan_entry->neg_sec_info);
825
826 result_info = &bss->Result;
827 result_info->ssId.length = scan_entry->ssid.length;
828 qdf_mem_copy(result_info->ssId.ssId,
829 scan_entry->ssid.ssid,
830 result_info->ssId.length);
831 result_info->timer = scan_entry->hidden_ssid_timestamp;
832
833 bss_desc = &result_info->BssDescriptor;
834
835 wlan_fill_bss_desc_from_scan_entry(mac_ctx, bss_desc, scan_entry);
836
837 status = wlan_get_parsed_bss_description_ies(mac_ctx, bss_desc,
838 &bcn_ies);
839 if (QDF_IS_STATUS_ERROR(status)) {
840 qdf_mem_free(bss);
841 return status;
842 }
843 result_info->pvIes = bcn_ies;
844
845 *p_result = bss;
846 return QDF_STATUS_SUCCESS;
847 }
848
csr_parse_scan_list(struct mac_context * mac_ctx,struct scan_result_list * ret_list,qdf_list_t * scan_list)849 static QDF_STATUS csr_parse_scan_list(struct mac_context *mac_ctx,
850 struct scan_result_list *ret_list,
851 qdf_list_t *scan_list)
852 {
853 struct tag_csrscan_result *pResult = NULL;
854 struct scan_cache_node *cur_node = NULL;
855 struct scan_cache_node *next_node = NULL;
856
857 qdf_list_peek_front(scan_list, (qdf_list_node_t **) &cur_node);
858
859 while (cur_node) {
860 qdf_list_peek_next(scan_list, (qdf_list_node_t *) cur_node,
861 (qdf_list_node_t **) &next_node);
862 pResult = NULL;
863 csr_fill_bss_from_scan_entry(mac_ctx,
864 cur_node->entry, &pResult);
865 if (pResult)
866 csr_ll_insert_tail(&ret_list->List, &pResult->Link,
867 LL_ACCESS_NOLOCK);
868 cur_node = next_node;
869 next_node = NULL;
870 }
871
872 return QDF_STATUS_SUCCESS;
873 }
874
csr_scan_get_result(struct mac_context * mac_ctx,struct scan_filter * filter,tScanResultHandle * results)875 QDF_STATUS csr_scan_get_result(struct mac_context *mac_ctx,
876 struct scan_filter *filter,
877 tScanResultHandle *results)
878 {
879 QDF_STATUS status;
880 struct scan_result_list *ret_list = NULL;
881 qdf_list_t *list = NULL;
882 struct wlan_objmgr_pdev *pdev = NULL;
883 uint32_t num_bss = 0;
884
885 if (results)
886 *results = CSR_INVALID_SCANRESULT_HANDLE;
887
888 pdev = wlan_objmgr_get_pdev_by_id(mac_ctx->psoc,
889 0, WLAN_LEGACY_MAC_ID);
890 if (!pdev) {
891 sme_err("pdev is NULL");
892 return QDF_STATUS_E_INVAL;
893 }
894
895 list = wlan_scan_get_result(pdev, filter);
896 if (list) {
897 num_bss = qdf_list_size(list);
898 sme_debug("num_entries %d", num_bss);
899 }
900
901 if (!list || (list && !qdf_list_size(list))) {
902 sme_debug("scan list empty");
903 if (num_bss)
904 status = QDF_STATUS_E_EXISTS;
905 else
906 status = QDF_STATUS_E_NULL_VALUE;
907 goto error;
908 }
909
910 ret_list = qdf_mem_malloc(sizeof(struct scan_result_list));
911 if (!ret_list) {
912 status = QDF_STATUS_E_NOMEM;
913 goto error;
914 }
915
916 csr_ll_open(&ret_list->List);
917 ret_list->pCurEntry = NULL;
918 status = csr_parse_scan_list(mac_ctx, ret_list, list);
919 if (QDF_IS_STATUS_ERROR(status) || !results)
920 /* Fail or No one wants the result. */
921 csr_scan_result_purge(mac_ctx, (tScanResultHandle) ret_list);
922 else {
923 if (!csr_ll_count(&ret_list->List)) {
924 /* This mean that there is no match */
925 csr_ll_close(&ret_list->List);
926 qdf_mem_free(ret_list);
927 /*
928 * Do not trigger scan for ssid if the scan entries
929 * are removed either due to rssi reject or assoc
930 * disallowed.
931 */
932 if (num_bss)
933 status = QDF_STATUS_E_EXISTS;
934 else
935 status = QDF_STATUS_E_NULL_VALUE;
936 } else if (results) {
937 *results = ret_list;
938 }
939 }
940
941 error:
942 if (list)
943 wlan_scan_purge_results(list);
944 if (pdev)
945 wlan_objmgr_pdev_release_ref(pdev, WLAN_LEGACY_MAC_ID);
946
947 return status;
948 }
949
csr_scan_get_result_for_bssid(struct mac_context * mac_ctx,struct qdf_mac_addr * bssid,qdf_list_t ** ret_list)950 QDF_STATUS csr_scan_get_result_for_bssid(struct mac_context *mac_ctx,
951 struct qdf_mac_addr *bssid,
952 qdf_list_t **ret_list)
953 {
954 struct scan_filter *scan_filter;
955 qdf_list_t *list = NULL;
956
957 *ret_list = NULL;
958 scan_filter = qdf_mem_malloc(sizeof(*scan_filter));
959 if (!scan_filter)
960 return QDF_STATUS_E_NOMEM;
961
962 scan_filter->num_of_bssid = 1;
963 qdf_mem_copy(scan_filter->bssid_list[0].bytes, bssid->bytes,
964 QDF_MAC_ADDR_SIZE);
965 scan_filter->ignore_auth_enc_type = true;
966
967 list = wlan_scan_get_result(mac_ctx->pdev, scan_filter);
968 qdf_mem_free(scan_filter);
969 if (!list || (list && !qdf_list_size(list)))
970 goto purge_list;
971
972 *ret_list = list;
973 return QDF_STATUS_SUCCESS;
974
975 purge_list:
976 if (list)
977 wlan_scan_purge_results(list);
978
979 return QDF_STATUS_E_FAILURE;
980 }
981
csr_scan_filter_results(struct mac_context * mac_ctx)982 QDF_STATUS csr_scan_filter_results(struct mac_context *mac_ctx)
983 {
984 uint32_t len = mac_ctx->mlme_cfg->reg.valid_channel_list_num;
985 struct wlan_objmgr_pdev *pdev = NULL;
986 uint32_t i, valid_chan_len = 0;
987 uint32_t ch_freq;
988 uint32_t valid_ch_freq_list[CFG_VALID_CHANNEL_LIST_LEN];
989
990 pdev = wlan_objmgr_get_pdev_by_id(mac_ctx->psoc,
991 0, WLAN_LEGACY_MAC_ID);
992 if (!pdev) {
993 sme_err("pdev is NULL");
994 return QDF_STATUS_E_INVAL;
995 }
996
997 /* This is a temporary conversion till the scm handles freq */
998 for (i = 0; i < len; i++) {
999 if (wlan_reg_is_dsrc_freq(
1000 mac_ctx->mlme_cfg->reg.valid_channel_freq_list[i]))
1001 continue;
1002 ch_freq = mac_ctx->mlme_cfg->reg.valid_channel_freq_list[i];
1003 valid_ch_freq_list[valid_chan_len++] = ch_freq;
1004 }
1005 sme_debug("No of valid channel %d", valid_chan_len);
1006
1007 ucfg_scan_filter_valid_channel(pdev, valid_ch_freq_list,
1008 valid_chan_len);
1009
1010 wlan_objmgr_pdev_release_ref(pdev, WLAN_LEGACY_MAC_ID);
1011
1012 return QDF_STATUS_SUCCESS;
1013 }
1014
csr_update_beacon(struct mac_context * mac)1015 void csr_update_beacon(struct mac_context *mac)
1016 {
1017 struct scheduler_msg msg = { 0 };
1018 QDF_STATUS status;
1019
1020 msg.type = SIR_LIM_UPDATE_BEACON;
1021 status = scheduler_post_message(QDF_MODULE_ID_SME, QDF_MODULE_ID_PE,
1022 QDF_MODULE_ID_PE, &msg);
1023 if (status != QDF_STATUS_SUCCESS)
1024 sme_err("scheduler_post_message failed, status = %u", status);
1025 }
1026