blob: b22f6cffdb9686053a11cae0d99188f392a3ef05 [file] [log] [blame]
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001/*
Ryan Hsu4252a2f2016-01-05 11:18:24 -08002 * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003 *
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 s a p C h S e l e c t . C
31 OVERVIEW:
32
33 This software unit holds the implementation of the WLAN SAP modules
34 functions for channel selection.
35
36 DEPENDENCIES:
37
38 Are listed for each API below.
39 ===========================================================================*/
40
41/*--------------------------------------------------------------------------
42 Include Files
43 ------------------------------------------------------------------------*/
44#include "cdf_trace.h"
45#include "csr_api.h"
46#include "sme_api.h"
47#include "sap_ch_select.h"
48#include "sap_internal.h"
49#ifdef ANI_OS_TYPE_QNX
50#include "stdio.h"
51#endif
52#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
53#include "lim_utils.h"
54#include "parser_api.h"
55#endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
56
57#ifdef CONFIG_CNSS
58#include <net/cnss.h>
59#endif
60
61/*--------------------------------------------------------------------------
62 Function definitions
63 --------------------------------------------------------------------------*/
64
65/*--------------------------------------------------------------------------
66 Defines
67 --------------------------------------------------------------------------*/
68#define SAP_DEBUG
69
70#define IS_RSSI_VALID(extRssi, rssi) \
71 ( \
72 ((extRssi < rssi) ? true : false) \
73 )
74
75#define SET_ACS_BAND(acs_band, pSapCtx) \
76{ \
77 if (pSapCtx->acs_cfg->start_ch <= 14 && \
78 pSapCtx->acs_cfg->end_ch <= 14) \
79 acs_band = eCSR_DOT11_MODE_11g; \
80 else if (pSapCtx->acs_cfg->start_ch >= 14)\
81 acs_band = eCSR_DOT11_MODE_11a; \
82 else \
83 acs_band = eCSR_DOT11_MODE_abg; \
84}
85
86#ifdef FEATURE_WLAN_CH_AVOID
87sapSafeChannelType safe_channels[NUM_20MHZ_RF_CHANNELS] = {
88 /*CH , SAFE, default safe */
89 {1, true}
90 , /* RF_CHAN_1, */
91 {2, true}
92 , /* RF_CHAN_2, */
93 {3, true}
94 , /* RF_CHAN_3, */
95 {4, true}
96 , /* RF_CHAN_4, */
97 {5, true}
98 , /* RF_CHAN_5, */
99 {6, true}
100 , /* RF_CHAN_6, */
101 {7, true}
102 , /* RF_CHAN_7, */
103 {8, true}
104 , /* RF_CHAN_8, */
105 {9, true}
106 , /* RF_CHAN_9, */
107 {10, true}
108 , /* RF_CHAN_10, */
109 {11, true}
110 , /* RF_CHAN_11, */
111 {12, true}
112 , /* RF_CHAN_12, */
113 {13, true}
114 , /* RF_CHAN_13, */
115 {14, true}
116 , /* RF_CHAN_14, */
117 {240, true}
118 , /* RF_CHAN_240, */
119 {244, true}
120 , /* RF_CHAN_244, */
121 {248, true}
122 , /* RF_CHAN_248, */
123 {252, true}
124 , /* RF_CHAN_252, */
125 {208, true}
126 , /* RF_CHAN_208, */
127 {212, true}
128 , /* RF_CHAN_212, */
129 {216, true}
130 , /* RF_CHAN_216, */
131 {36, true}
132 , /* RF_CHAN_36, */
133 {40, true}
134 , /* RF_CHAN_40, */
135 {44, true}
136 , /* RF_CHAN_44, */
137 {48, true}
138 , /* RF_CHAN_48, */
139 {52, true}
140 , /* RF_CHAN_52, */
141 {56, true}
142 , /* RF_CHAN_56, */
143 {60, true}
144 , /* RF_CHAN_60, */
145 {64, true}
146 , /* RF_CHAN_64, */
147 {100, true}
148 , /* RF_CHAN_100, */
149 {104, true}
150 , /* RF_CHAN_104, */
151 {108, true}
152 , /* RF_CHAN_108, */
153 {112, true}
154 , /* RF_CHAN_112, */
155 {116, true}
156 , /* RF_CHAN_116, */
157 {120, true}
158 , /* RF_CHAN_120, */
159 {124, true}
160 , /* RF_CHAN_124, */
161 {128, true}
162 , /* RF_CHAN_128, */
163 {132, true}
164 , /* RF_CHAN_132, */
165 {136, true}
166 , /* RF_CHAN_136, */
167 {140, true}
168 , /* RF_CHAN_140, */
169 {144, true}
170 , /* RF_CHAN_144, */
171 {149, true}
172 , /* RF_CHAN_149, */
173 {153, true}
174 , /* RF_CHAN_153, */
175 {157, true}
176 , /* RF_CHAN_157, */
177 {161, true}
178 , /* RF_CHAN_161, */
179 {165, true}
180 , /* RF_CHAN_165, */
181};
182#endif
183
184typedef struct {
185 uint16_t chStartNum;
186 uint32_t weight;
187} sapAcsChannelInfo;
188
189sapAcsChannelInfo acs_ht40_channels5_g[] = {
190 {36, SAP_ACS_WEIGHT_MAX},
191 {44, SAP_ACS_WEIGHT_MAX},
192 {52, SAP_ACS_WEIGHT_MAX},
193 {60, SAP_ACS_WEIGHT_MAX},
194 {100, SAP_ACS_WEIGHT_MAX},
195 {108, SAP_ACS_WEIGHT_MAX},
196 {116, SAP_ACS_WEIGHT_MAX},
197 {124, SAP_ACS_WEIGHT_MAX},
198 {132, SAP_ACS_WEIGHT_MAX},
199 {140, SAP_ACS_WEIGHT_MAX},
200 {149, SAP_ACS_WEIGHT_MAX},
201 {157, SAP_ACS_WEIGHT_MAX},
202};
203
204sapAcsChannelInfo acs_ht80_channels[] = {
205 {36, SAP_ACS_WEIGHT_MAX},
206 {52, SAP_ACS_WEIGHT_MAX},
207 {100, SAP_ACS_WEIGHT_MAX},
208 {116, SAP_ACS_WEIGHT_MAX},
209 {132, SAP_ACS_WEIGHT_MAX},
210 {149, SAP_ACS_WEIGHT_MAX},
211};
212
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -0700213sapAcsChannelInfo acs_vht160_channels[] = {
214 {36, SAP_ACS_WEIGHT_MAX},
215 {100, SAP_ACS_WEIGHT_MAX},
216};
217
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800218sapAcsChannelInfo acs_ht40_channels24_g[] = {
219 {1, SAP_ACS_WEIGHT_MAX},
220 {2, SAP_ACS_WEIGHT_MAX},
221 {3, SAP_ACS_WEIGHT_MAX},
222 {4, SAP_ACS_WEIGHT_MAX},
223 {9, SAP_ACS_WEIGHT_MAX},
224};
225
226#define CHANNEL_165 165
227
228/* rssi discount for channels in PCL */
229#define PCL_RSSI_DISCOUNT 10
230
231#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
232/**
233 * sap_check_n_add_channel() - checks and add given channel in sap context's
234 * avoid_channels_info struct
235 * @sap_ctx: sap context.
236 * @new_channel: channel to be added to sap_ctx's avoid ch info
237 *
238 * sap_ctx contains sap_avoid_ch_info strcut containing the list of channels on
239 * which MDM device's AP with MCC was detected. This function will add channels
240 * to that list after checking for duplicates.
241 *
242 * Return: true: if channel was added or already present
243 * else false: if channel list was already full.
244 */
245bool
246sap_check_n_add_channel(ptSapContext sap_ctx,
247 uint8_t new_channel)
248{
249 uint8_t i = 0;
250 struct sap_avoid_channels_info *ie_info =
251 &sap_ctx->sap_detected_avoid_ch_ie;
252
253 for (i = 0; i < sizeof(ie_info->channels); i++) {
254 if (ie_info->channels[i] == new_channel)
255 break;
256
257 if (ie_info->channels[i] == 0) {
258 ie_info->channels[i] = new_channel;
259 break;
260 }
261 }
262 if (i == sizeof(ie_info->channels))
263 return false;
264 else
265 return true;
266}
267/**
268 * sap_check_n_add_overlapped_chnls() - checks & add overlapped channels
269 * to primary channel in 2.4Ghz band.
270 * @sap_ctx: sap context.
271 * @primary_chnl: primary channel to be avoided.
272 *
273 * sap_ctx contains sap_avoid_ch_info struct containing the list of channels on
274 * which MDM device's AP with MCC was detected. This function will add channels
275 * to that list after checking for duplicates.
276 *
277 * Return: true: if channel was added or already present
278 * else false: if channel list was already full.
279 */
280static bool
281sap_check_n_add_overlapped_chnls(ptSapContext sap_ctx, uint8_t primary_channel)
282{
283 uint8_t i = 0, j = 0, upper_chnl = 0, lower_chnl = 0;
284 struct sap_avoid_channels_info *ie_info =
285 &sap_ctx->sap_detected_avoid_ch_ie;
286 /*
287 * if primary channel less than channel 1 or out of 2g band then
288 * no further process is required. return true in this case.
289 */
290 if (primary_channel < CHANNEL_1 || primary_channel > CHANNEL_14)
291 return true;
292
293 /* lower channel is one channel right before primary channel */
294 lower_chnl = primary_channel - 1;
295 /* upper channel is one channel right after primary channel */
296 upper_chnl = primary_channel + 1;
297
298 /* lower channel needs to be non-zero, zero is not valid channel */
299 if (lower_chnl > (CHANNEL_1 - 1)) {
300 for (i = 0; i < sizeof(ie_info->channels); i++) {
301 if (ie_info->channels[i] == lower_chnl)
302 break;
303 if (ie_info->channels[i] == 0) {
304 ie_info->channels[i] = lower_chnl;
305 break;
306 }
307 }
308 }
309 /* upper channel needs to be atleast last channel in 2.4Ghz band */
310 if (upper_chnl < (CHANNEL_14 + 1)) {
311 for (j = 0; j < sizeof(ie_info->channels); j++) {
312 if (ie_info->channels[j] == upper_chnl)
313 break;
314 if (ie_info->channels[j] == 0) {
315 ie_info->channels[j] = upper_chnl;
316 break;
317 }
318 }
319 }
320 if (i == sizeof(ie_info->channels) || j == sizeof(ie_info->channels))
321 return false;
322 else
323 return true;
324}
325
326/**
327 * sap_process_avoid_ie() - processes the detected Q2Q IE
328 * context's avoid_channels_info struct
329 * @hal: hal handle
330 * @sap_ctx: sap context.
331 * @scan_result: scan results for ACS scan.
332 * @spect_info: spectrum weights array to update
333 *
334 * Detection of Q2Q IE indicates presence of another MDM device with its AP
335 * operating in MCC mode. This function parses the scan results and processes
336 * the Q2Q IE if found. It then extracts the channels and populates them in
337 * sap_ctx struct. It also increases the weights of those channels so that
338 * ACS logic will avoid those channels in its selection algorithm.
339 *
340 * Return: void
341 */
342void sap_process_avoid_ie(tHalHandle hal,
343 ptSapContext sap_ctx,
344 tScanResultHandle scan_result,
345 tSapChSelSpectInfo *spect_info)
346{
347 uint32_t total_ie_len = 0;
348 uint8_t *temp_ptr = NULL;
349 uint8_t i = 0;
350 struct sAvoidChannelIE *avoid_ch_ie;
351 tCsrScanResultInfo *node = NULL;
352 tpAniSirGlobal mac_ctx = NULL;
353 tSapSpectChInfo *spect_ch = NULL;
354
355 mac_ctx = PMAC_STRUCT(hal);
356 spect_ch = spect_info->pSpectCh;
357 node = sme_scan_result_get_first(hal, scan_result);
358
359 while (node) {
360 total_ie_len = (node->BssDescriptor.length +
361 sizeof(uint16_t) + sizeof(uint32_t) -
362 sizeof(tSirBssDescription));
363 temp_ptr = cfg_get_vendor_ie_ptr_from_oui(mac_ctx,
364 SIR_MAC_QCOM_VENDOR_OUI,
365 SIR_MAC_QCOM_VENDOR_SIZE,
366 ((uint8_t *)&node->BssDescriptor.ieFields),
367 total_ie_len);
368
369 if (temp_ptr) {
370 avoid_ch_ie = (struct sAvoidChannelIE *)temp_ptr;
371 if (avoid_ch_ie->type != QCOM_VENDOR_IE_MCC_AVOID_CH)
372 continue;
373
374 sap_ctx->sap_detected_avoid_ch_ie.present = 1;
375 CDF_TRACE(CDF_MODULE_ID_SAP,
376 CDF_TRACE_LEVEL_DEBUG,
377 "Q2Q IE - avoid ch %d",
378 avoid_ch_ie->channel);
379 /* add this channel to to_avoid channel list */
380 sap_check_n_add_channel(sap_ctx,
381 avoid_ch_ie->channel);
382 sap_check_n_add_overlapped_chnls(sap_ctx,
383 avoid_ch_ie->channel);
384 /*
385 * Mark weight of these channel present in IE to MAX
386 * so that ACS logic will to avoid thse channels
387 */
388 for (i = 0; i < spect_info->numSpectChans; i++)
389 if (spect_ch[i].chNum == avoid_ch_ie->channel) {
390 /*
391 * weight is set more than max so that,
392 * in the case of other channels being
393 * assigned max weight due to noise,
394 * they may be preferred over channels
395 * with Q2Q IE.
396 */
397 spect_ch[i].weight = SAP_ACS_WEIGHT_MAX + 1;
398 spect_ch[i].weight_copy =
399 SAP_ACS_WEIGHT_MAX + 1;
400 break;
401 }
402 } /* if (temp_ptr) */
403 node = sme_scan_result_get_next(hal, scan_result);
404 }
405}
406#endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
407
408#ifdef FEATURE_WLAN_CH_AVOID
409/*==========================================================================
410 FUNCTION sap_update_unsafe_channel_list
411
412 DESCRIPTION
413 Function Undate unsafe channel list table
414
415 DEPENDENCIES
416 NA.
417
418 IN
419 SapContext pointer
420
421 RETURN VALUE
422 NULL
423 ============================================================================*/
424#ifdef CONFIG_CNSS
425void sap_update_unsafe_channel_list(ptSapContext pSapCtx)
426{
427 uint16_t i, j;
428 uint16_t unsafe_channel_list[NUM_20MHZ_RF_CHANNELS];
429 uint16_t unsafe_channel_count = 0;
430
431 /* Flush, default set all channel safe */
432 for (i = 0; i < NUM_20MHZ_RF_CHANNELS; i++) {
433 safe_channels[i].isSafe = true;
434 }
435
436 /* Try to find unsafe channel */
Ryan Hsu4252a2f2016-01-05 11:18:24 -0800437#if defined(FEATURE_WLAN_STA_AP_MODE_DFS_DISABLE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800438 for (i = 0; i < NUM_20MHZ_RF_CHANNELS; i++) {
439 if (pSapCtx->dfs_ch_disable == true) {
440 if (CDS_IS_DFS_CH(safe_channels[i].channelNumber)) {
441 safe_channels[i].isSafe = false;
442 CDF_TRACE(CDF_MODULE_ID_SAP,
443 CDF_TRACE_LEVEL_INFO_HIGH,
444 "%s: DFS Ch %d is not safe in"
445 " Concurrent mode",
446 __func__,
447 safe_channels[i].channelNumber);
448 }
449 }
450 }
451#endif
452
453 cnss_get_wlan_unsafe_channel(unsafe_channel_list,
454 &unsafe_channel_count,
455 sizeof(unsafe_channel_list));
456
457 for (i = 0; i < unsafe_channel_count; i++) {
458 for (j = 0; j < NUM_20MHZ_RF_CHANNELS; j++) {
459 if (safe_channels[j].channelNumber ==
460 unsafe_channel_list[i]) {
461 /* Found unsafe channel, update it */
462 safe_channels[j].isSafe = false;
463 CDF_TRACE(CDF_MODULE_ID_SAP,
464 CDF_TRACE_LEVEL_ERROR,
465 FL("CH %d is not safe"),
466 unsafe_channel_list[i]);
467 break;
468 }
469 }
470 }
471
472 return;
473}
474#else
475void sap_update_unsafe_channel_list(ptSapContext pSapCtx)
476{
477 CDF_TRACE(CDF_MODULE_ID_SAP, CDF_TRACE_LEVEL_ERROR,
478 "%s: Not implemented", __func__);
479 return;
480}
481#endif
482
483#endif /* FEATURE_WLAN_CH_AVOID */
484
485/*==========================================================================
486 FUNCTION sap_cleanup_channel_list
487
488 DESCRIPTION
489 Function sap_cleanup_channel_list frees up the memory allocated to the channel list.
490
491 DEPENDENCIES
492 NA.
493
494 PARAMETERS
495
496 IN
497 NULL
498
499 RETURN VALUE
500 NULL
501 ============================================================================*/
502
Ryan Hsu4252a2f2016-01-05 11:18:24 -0800503void sap_cleanup_channel_list(void *p_cds_gctx)
504{
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800505 ptSapContext pSapCtx;
506
507 CDF_TRACE(CDF_MODULE_ID_SAP, CDF_TRACE_LEVEL_INFO,
508 "Cleaning up the channel list structure");
509
510 if (NULL == p_cds_gctx) {
511 CDF_TRACE(CDF_MODULE_ID_SAP, CDF_TRACE_LEVEL_FATAL,
512 "SAP Global Context is NULL");
513 return;
514 }
515
516 pSapCtx = CDS_GET_SAP_CB(p_cds_gctx);
517 if (NULL == pSapCtx) {
518 CDF_TRACE(CDF_MODULE_ID_SAP, CDF_TRACE_LEVEL_FATAL,
519 "SAP Context is NULL");
520 return;
521 }
522
523 pSapCtx->SapChnlList.numChannel = 0;
524 if (pSapCtx->SapChnlList.channelList) {
525 cdf_mem_free(pSapCtx->SapChnlList.channelList);
526 pSapCtx->SapChnlList.channelList = NULL;
527 }
528
529 pSapCtx->SapAllChnlList.numChannel = 0;
530 if (pSapCtx->SapAllChnlList.channelList) {
531 cdf_mem_free(pSapCtx->SapAllChnlList.channelList);
532 pSapCtx->SapAllChnlList.channelList = NULL;
533 }
534}
535
536/**
537 * sap_select_preferred_channel_from_channel_list() - to calc best cahnnel
538 * @best_chnl: best channel already calculated among all the chanels
539 * @sap_ctx: sap context
540 * @spectinfo_param: Pointer to tSapChSelSpectInfo structure
541 *
542 * This function calculates the best channel among the configured channel list.
543 * If channel list not configured then returns the best channel calculated
544 * among all the channel list.
545 *
546 * Return: uint8_t best channel
547 */
548uint8_t sap_select_preferred_channel_from_channel_list(uint8_t best_chnl,
549 ptSapContext sap_ctx,
550 tSapChSelSpectInfo *spectinfo_param)
551{
552 uint8_t i = 0;
553
554 /*
555 * If Channel List is not Configured don't do anything
556 * Else return the Best Channel from the Channel List
557 */
558 if ((NULL == sap_ctx->acs_cfg->ch_list) ||
559 (NULL == spectinfo_param) ||
560 (0 == sap_ctx->acs_cfg->ch_list_count))
561 return best_chnl;
562
563 if (best_chnl <= 0 || best_chnl > 252)
564 return SAP_CHANNEL_NOT_SELECTED;
565
566 /* Select the best channel from allowed list */
567 for (i = 0; i < sap_ctx->acs_cfg->ch_list_count; i++) {
568 if (sap_ctx->acs_cfg->ch_list[i] == best_chnl) {
569 CDF_TRACE(CDF_MODULE_ID_SAP,
570 CDF_TRACE_LEVEL_INFO_HIGH,
571 "Best channel is: %d",
572 best_chnl);
573 return best_chnl;
574 }
575 }
576
577 return SAP_CHANNEL_NOT_SELECTED;
578}
579
580/*==========================================================================
581 FUNCTION sap_chan_sel_init
582
583 DESCRIPTION
584 Function sap_chan_sel_init allocates the memory, intializes the
585 structures used by the channel selection algorithm
586
587 DEPENDENCIES
588 NA.
589
590 PARAMETERS
591
592 IN
593 halHandle : Pointer to tHalHandle
594 *pSpectInfoParams : Pointer to tSapChSelSpectInfo structure
595 pSapCtx : Pointer to SAP Context
596
597 RETURN VALUE
598 bool: Success or FAIL
599
600 SIDE EFFECTS
601 ============================================================================*/
602bool sap_chan_sel_init(tHalHandle halHandle,
603 tSapChSelSpectInfo *pSpectInfoParams, ptSapContext pSapCtx)
604{
605 tSapSpectChInfo *pSpectCh = NULL;
606 uint8_t *pChans = NULL;
607 uint16_t channelnum = 0;
608 tpAniSirGlobal pMac = PMAC_STRUCT(halHandle);
609 bool chSafe = true;
610#ifdef FEATURE_WLAN_CH_AVOID
611 uint16_t i;
612#endif
613 uint32_t dfs_master_cap_enabled;
614 bool include_dfs_ch = true;
615
616 CDF_TRACE(CDF_MODULE_ID_SAP, CDF_TRACE_LEVEL_INFO_HIGH, "In %s",
617 __func__);
618
619 pSpectInfoParams->numSpectChans =
620 pMac->scan.base_channels.numChannels;
621
622 /* Allocate memory for weight computation of 2.4GHz */
623 pSpectCh =
624 (tSapSpectChInfo *) cdf_mem_malloc((pSpectInfoParams->numSpectChans)
625 * sizeof(*pSpectCh));
626
627 if (pSpectCh == NULL) {
628 CDF_TRACE(CDF_MODULE_ID_SAP, CDF_TRACE_LEVEL_ERROR,
629 "In %s, CDF_MALLOC_ERR", __func__);
630 return eSAP_FALSE;
631 }
632
633 cdf_mem_zero(pSpectCh,
634 (pSpectInfoParams->numSpectChans) * sizeof(*pSpectCh));
635
636 /* Initialize the pointers in the DfsParams to the allocated memory */
637 pSpectInfoParams->pSpectCh = pSpectCh;
638
639 pChans = pMac->scan.base_channels.channelList;
640
Ryan Hsu4252a2f2016-01-05 11:18:24 -0800641#if defined(FEATURE_WLAN_STA_AP_MODE_DFS_DISABLE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800642 if (pSapCtx->dfs_ch_disable == true)
643 include_dfs_ch = false;
644#endif
645 sme_cfg_get_int(halHandle, WNI_CFG_DFS_MASTER_ENABLED,
646 &dfs_master_cap_enabled);
647 if (dfs_master_cap_enabled == 0)
648 include_dfs_ch = false;
649
650 /* Fill the channel number in the spectrum in the operating freq band */
651 for (channelnum = 0;
652 channelnum < pSpectInfoParams->numSpectChans;
Edhar, Mahesh Kumar4f660672015-10-30 11:53:26 +0530653 channelnum++, pChans++, pSpectCh++) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800654 chSafe = true;
655
656 /* check if the channel is in NOL blacklist */
657 if (sap_dfs_is_channel_in_nol_list(pSapCtx, *pChans,
658 PHY_SINGLE_CHANNEL_CENTERED)) {
659 CDF_TRACE(CDF_MODULE_ID_SAP, CDF_TRACE_LEVEL_INFO_HIGH,
660 "In %s, Ch %d is in NOL list", __func__,
661 *pChans);
662 chSafe = false;
663 continue;
664 }
665
666 if (include_dfs_ch == false) {
667 if (CDS_IS_DFS_CH(*pChans)) {
668 chSafe = false;
669 CDF_TRACE(CDF_MODULE_ID_SAP,
670 CDF_TRACE_LEVEL_INFO_HIGH,
671 "In %s, DFS Ch %d not considered for ACS",
672 __func__, *pChans);
673 continue;
674 }
675 }
676
677#ifdef FEATURE_WLAN_CH_AVOID
678 for (i = 0; i < NUM_20MHZ_RF_CHANNELS; i++) {
679 if ((safe_channels[i].channelNumber == *pChans) &&
680 (false == safe_channels[i].isSafe)) {
681 CDF_TRACE(CDF_MODULE_ID_SAP,
682 CDF_TRACE_LEVEL_INFO_HIGH,
683 "In %s, Ch %d is not safe", __func__,
684 *pChans);
685 chSafe = false;
686 break;
687 }
688 }
689#endif /* FEATURE_WLAN_CH_AVOID */
690
691 /* OFDM rates are not supported on channel 14 */
692 if (*pChans == 14 &&
693 eCSR_DOT11_MODE_11b != pSapCtx->csr_roamProfile.phyMode) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800694 continue;
695 }
696
697 if (true == chSafe) {
698 pSpectCh->chNum = *pChans;
699 pSpectCh->valid = eSAP_TRUE;
700 pSpectCh->rssiAgr = SOFTAP_MIN_RSSI; /* Initialise for all channels */
701 pSpectCh->channelWidth = SOFTAP_HT20_CHANNELWIDTH; /* Initialise 20MHz for all the Channels */
702 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800703 }
704 return eSAP_TRUE;
705}
706
707/*==========================================================================
708 FUNCTION sapweight_rssi_count
709
710 DESCRIPTION
711 Function weightRssiCount calculates the channel weight due to rssi
712 and data count(here number of BSS observed)
713
714 DEPENDENCIES
715 NA.
716
717 PARAMETERS
718
719 IN
720 rssi : Max signal strength receieved from a BSS for the channel
721 count : Number of BSS observed in the channel
722
723 RETURN VALUE
724 uint32_t : Calculated channel weight based on above two
725
726 SIDE EFFECTS
727 ============================================================================*/
728uint32_t sapweight_rssi_count(int8_t rssi, uint16_t count)
729{
730 int32_t rssiWeight = 0;
731 int32_t countWeight = 0;
732 uint32_t rssicountWeight = 0;
733
734 /* Weight from RSSI */
735 rssiWeight = SOFTAP_RSSI_WEIGHT * (rssi - SOFTAP_MIN_RSSI)
736 / (SOFTAP_MAX_RSSI - SOFTAP_MIN_RSSI);
737
738 if (rssiWeight > SOFTAP_RSSI_WEIGHT)
739 rssiWeight = SOFTAP_RSSI_WEIGHT;
740 else if (rssiWeight < 0)
741 rssiWeight = 0;
742
743 /* Weight from data count */
744 countWeight = SOFTAP_COUNT_WEIGHT * (count - SOFTAP_MIN_COUNT)
745 / (SOFTAP_MAX_COUNT - SOFTAP_MIN_COUNT);
746
747 if (countWeight > SOFTAP_COUNT_WEIGHT)
748 countWeight = SOFTAP_COUNT_WEIGHT;
749
750 rssicountWeight = rssiWeight + countWeight;
751
752 CDF_TRACE(CDF_MODULE_ID_SAP, CDF_TRACE_LEVEL_INFO_HIGH,
753 "In %s, rssiWeight=%d, countWeight=%d, rssicountWeight=%d",
754 __func__, rssiWeight, countWeight, rssicountWeight);
755
756 return rssicountWeight;
757}
758
759/**
760 * sap_update_rssi_bsscount() - updates bss count and rssi effect.
761 *
762 * @pSpectCh: Channel Information
763 * @offset: Channel Offset
764 * @sap_24g: Channel is in 2.4G or 5G
765 *
766 * sap_update_rssi_bsscount updates bss count and rssi effect based
767 * on the channel offset.
768 *
769 * Return: None.
770 */
771
772void sap_update_rssi_bsscount(tSapSpectChInfo *pSpectCh, int32_t offset,
773 bool sap_24g)
774{
775 tSapSpectChInfo *pExtSpectCh = NULL;
776 int32_t rssi, rsssi_effect;
777
778 pExtSpectCh = (pSpectCh + offset);
779 if (pExtSpectCh != NULL) {
780 ++pExtSpectCh->bssCount;
781 switch (offset) {
782 case -1:
783 case 1:
784 rsssi_effect = sap_24g ?
785 SAP_24GHZ_FIRST_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY :
786 SAP_SUBBAND1_RSSI_EFFECT_PRIMARY;
787 break;
788 case -2:
789 case 2:
790 rsssi_effect = sap_24g ?
791 SAP_24GHZ_SEC_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY :
792 SAP_SUBBAND2_RSSI_EFFECT_PRIMARY;
793 break;
794 case -3:
795 case 3:
796 rsssi_effect = sap_24g ?
797 SAP_24GHZ_THIRD_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY :
798 SAP_SUBBAND3_RSSI_EFFECT_PRIMARY;
799 break;
800 case -4:
801 case 4:
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -0700802 rsssi_effect = sap_24g ?
803 SAP_24GHZ_FOURTH_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY :
804 SAP_SUBBAND4_RSSI_EFFECT_PRIMARY;
805 break;
806 case -5:
807 case 5:
808 rsssi_effect = SAP_SUBBAND5_RSSI_EFFECT_PRIMARY;
809 break;
810 case -6:
811 case 6:
812 rsssi_effect = SAP_SUBBAND6_RSSI_EFFECT_PRIMARY;
813 break;
814 case -7:
815 case 7:
816 rsssi_effect = SAP_SUBBAND7_RSSI_EFFECT_PRIMARY;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800817 break;
818 default:
819 rsssi_effect = 0;
820 break;
821 }
822
823 rssi = pSpectCh->rssiAgr + rsssi_effect;
824 if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi))
825 pExtSpectCh->rssiAgr = rssi;
826 if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI)
827 pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI;
828 }
829}
830
831/**
832 * sap_upd_chan_spec_params() - sap_upd_chan_spec_params
833 * updates channel parameters obtained from Beacon
834 * @pBeaconStruct Beacon strucutre populated by parse_beacon function
835 * @channelWidth Channel width
836 * @secondaryChannelOffset Secondary Channel Offset
837 * @vhtSupport If channel supports VHT
838 * @centerFreq Central frequency for the given channel.
839 *
840 * sap_upd_chan_spec_params updates the spectrum channels based on the
841 * pBeaconStruct obtained from Beacon IE
842 *
843 * Return: NA.
844 */
845
846void sap_upd_chan_spec_params(tSirProbeRespBeacon *pBeaconStruct,
847 uint16_t *channelWidth,
848 uint16_t *secondaryChannelOffset,
849 uint16_t *vhtSupport,
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -0700850 uint16_t *centerFreq,
851 uint16_t *centerFreq_2)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800852{
853 if (NULL == pBeaconStruct) {
854 CDF_TRACE(CDF_MODULE_ID_SAP, CDF_TRACE_LEVEL_ERROR,
855 FL("pBeaconStruct is NULL"));
856 return;
857 }
858
859 if (pBeaconStruct->HTCaps.present && pBeaconStruct->HTInfo.present) {
860 *channelWidth = pBeaconStruct->HTCaps.supportedChannelWidthSet;
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -0700861 *secondaryChannelOffset =
862 pBeaconStruct->HTInfo.secondaryChannelOffset;
863 if (!pBeaconStruct->VHTOperation.present)
864 return;
865 *vhtSupport = pBeaconStruct->VHTOperation.present;
866 if (pBeaconStruct->VHTOperation.chanWidth) {
867 *centerFreq =
868 pBeaconStruct->VHTOperation.chanCenterFreqSeg1;
869 *centerFreq_2 =
870 pBeaconStruct->VHTOperation.chanCenterFreqSeg2;
871 /*
872 * LHS follows tSirMacHTChannelWidth, while RHS follows
873 * WNI_CFG_VHT_CHANNEL_WIDTH_X format hence following
874 * adjustment
875 */
876 *channelWidth =
877 pBeaconStruct->VHTOperation.chanWidth + 1;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800878
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800879 }
880 }
881}
882
883/**
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -0700884 * sap_update_rssi_bsscount_vht_5G() - updates bss count and rssi effect.
885 *
886 * @pSpectCh: Channel Information
887 * @offset: Channel Offset
888 * @num_ch: no.of channels
889 *
890 * sap_update_rssi_bsscount_vht_5G updates bss count and rssi effect based
891 * on the channel offset.
892 *
893 * Return: None.
894 */
895
896void sap_update_rssi_bsscount_vht_5G(tSapSpectChInfo *spect_ch, int32_t offset,
897 uint16_t num_ch)
898{
899 int32_t ch_offset;
900 uint16_t i, cnt;
901
902 if (!offset)
903 return;
904 if (offset > 0)
905 cnt = num_ch;
906 else
907 cnt = num_ch + 1;
908 for (i = 0; i < cnt; i++) {
909 ch_offset = offset + i;
910 if (ch_offset == 0)
911 continue;
912 sap_update_rssi_bsscount(spect_ch, ch_offset, false);
913 }
914}
915/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800916 * sap_interference_rssi_count_5G() - sap_interference_rssi_count
917 * considers the Adjacent channel rssi and
918 * data count(here number of BSS observed)
919 * @spect_ch: Channel Information
920 * @chan_width: Channel width parsed from beacon IE
921 * @sec_chan_offset: Secondary Channel Offset
922 * @center_freq: Central frequency for the given channel.
923 * @channel_id: channel_id
924 *
925 * sap_interference_rssi_count_5G considers the Adjacent channel rssi
926 * and data count(here number of BSS observed)
927 *
928 * Return: NA.
929 */
930
931void sap_interference_rssi_count_5G(tSapSpectChInfo *spect_ch,
932 uint16_t chan_width,
933 uint16_t sec_chan_offset,
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -0700934 uint16_t center_freq,
935 uint16_t center_freq_2,
936 uint8_t channel_id)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800937{
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -0700938 uint16_t num_ch;
939 int32_t offset = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800940 if (NULL == spect_ch) {
941 CDF_TRACE(CDF_MODULE_ID_SAP, CDF_TRACE_LEVEL_ERROR,
942 FL("spect_ch is NULL"));
943 return;
944 }
945
946 /* Updating the received ChannelWidth */
947 if (spect_ch->channelWidth != chan_width)
948 spect_ch->channelWidth = chan_width;
949 /* If received ChannelWidth is other than HT20,
950 * we need to update the extension channel Params as well
951 * chan_width == 0, HT20
952 * chan_width == 1, HT40
953 * chan_width == 2, VHT80
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -0700954 * chan_width == 3, VHT160
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800955 */
956
957 switch (spect_ch->channelWidth) {
958 case eHT_CHANNEL_WIDTH_40MHZ: /* HT40 */
959 switch (sec_chan_offset) {
960 /* Above the Primary Channel */
961 case PHY_DOUBLE_CHANNEL_LOW_PRIMARY:
962 sap_update_rssi_bsscount(spect_ch, 1, false);
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -0700963 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800964
965 /* Below the Primary channel */
966 case PHY_DOUBLE_CHANNEL_HIGH_PRIMARY:
967 sap_update_rssi_bsscount(spect_ch, -1, false);
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -0700968 return;
969 }
970 return;
971 case eHT_CHANNEL_WIDTH_80MHZ: /* VHT80 */
972 num_ch = 3;
973 if ((center_freq - channel_id) == 6) {
974 offset = 1;
975 } else if ((center_freq - channel_id) == 2) {
976 offset = -1;
977 } else if ((center_freq - channel_id) == -2) {
978 offset = -2;
979 } else if ((center_freq - channel_id) == -6) {
980 offset = -3;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800981 }
982 break;
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -0700983 case eHT_CHANNEL_WIDTH_160MHZ: /* VHT160 */
984 num_ch = 7;
985 if ((center_freq - channel_id) == 14)
986 offset = 1;
987 else if ((center_freq - channel_id) == 10)
988 offset = -1;
989 else if ((center_freq - channel_id) == 6)
990 offset = -2;
991 else if ((center_freq - channel_id) == 2)
992 offset = -3;
993 else if ((center_freq - channel_id) == -2)
994 offset = -4;
995 else if ((center_freq - channel_id) == -6)
996 offset = -5;
997 else if ((center_freq - channel_id) == -10)
998 offset = -6;
999 else if ((center_freq - channel_id) == -14)
1000 offset = -7;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001001 break;
1002 default:
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001003 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001004 }
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001005 sap_update_rssi_bsscount_vht_5G(spect_ch, offset, num_ch);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001006}
1007
1008/**
1009 * sap_interference_rssi_count() - sap_interference_rssi_count
1010 * considers the Adjacent channel rssi
1011 * and data count(here number of BSS observed)
1012 * @spect_ch Channel Information
1013 *
1014 * sap_interference_rssi_count considers the Adjacent channel rssi
1015 * and data count(here number of BSS observed)
1016 *
1017 * Return: None.
1018 */
1019
1020void sap_interference_rssi_count(tSapSpectChInfo *spect_ch)
1021{
1022 if (NULL == spect_ch) {
1023 CDF_TRACE(CDF_MODULE_ID_SAP, CDF_TRACE_LEVEL_ERROR,
1024 "%s: spect_ch is NULL", __func__);
1025 return;
1026 }
1027
1028 switch (spect_ch->chNum) {
1029 case CHANNEL_1:
1030 sap_update_rssi_bsscount(spect_ch, 1, true);
1031 sap_update_rssi_bsscount(spect_ch, 2, true);
1032 sap_update_rssi_bsscount(spect_ch, 3, true);
1033 sap_update_rssi_bsscount(spect_ch, 4, true);
1034 break;
1035
1036 case CHANNEL_2:
1037 sap_update_rssi_bsscount(spect_ch, -1, true);
1038 sap_update_rssi_bsscount(spect_ch, 1, true);
1039 sap_update_rssi_bsscount(spect_ch, 2, true);
1040 sap_update_rssi_bsscount(spect_ch, 3, true);
1041 sap_update_rssi_bsscount(spect_ch, 4, true);
1042 break;
1043 case CHANNEL_3:
1044 sap_update_rssi_bsscount(spect_ch, -2, true);
1045 sap_update_rssi_bsscount(spect_ch, -1, true);
1046 sap_update_rssi_bsscount(spect_ch, 1, true);
1047 sap_update_rssi_bsscount(spect_ch, 2, true);
1048 sap_update_rssi_bsscount(spect_ch, 3, true);
1049 sap_update_rssi_bsscount(spect_ch, 4, true);
1050 break;
1051 case CHANNEL_4:
1052 sap_update_rssi_bsscount(spect_ch, -3, true);
1053 sap_update_rssi_bsscount(spect_ch, -2, true);
1054 sap_update_rssi_bsscount(spect_ch, -1, true);
1055 sap_update_rssi_bsscount(spect_ch, 1, true);
1056 sap_update_rssi_bsscount(spect_ch, 2, true);
1057 sap_update_rssi_bsscount(spect_ch, 3, true);
1058 sap_update_rssi_bsscount(spect_ch, 4, true);
1059 break;
1060
1061 case CHANNEL_5:
1062 case CHANNEL_6:
1063 case CHANNEL_7:
1064 case CHANNEL_8:
1065 case CHANNEL_9:
1066 case CHANNEL_10:
1067 sap_update_rssi_bsscount(spect_ch, -4, true);
1068 sap_update_rssi_bsscount(spect_ch, -3, true);
1069 sap_update_rssi_bsscount(spect_ch, -2, true);
1070 sap_update_rssi_bsscount(spect_ch, -1, true);
1071 sap_update_rssi_bsscount(spect_ch, 1, true);
1072 sap_update_rssi_bsscount(spect_ch, 2, true);
1073 sap_update_rssi_bsscount(spect_ch, 3, true);
1074 sap_update_rssi_bsscount(spect_ch, 4, true);
1075 break;
1076
1077 case CHANNEL_11:
1078 sap_update_rssi_bsscount(spect_ch, -4, true);
1079 sap_update_rssi_bsscount(spect_ch, -3, true);
1080 sap_update_rssi_bsscount(spect_ch, -2, true);
1081 sap_update_rssi_bsscount(spect_ch, -1, true);
1082 sap_update_rssi_bsscount(spect_ch, 1, true);
1083 sap_update_rssi_bsscount(spect_ch, 2, true);
1084 sap_update_rssi_bsscount(spect_ch, 3, true);
1085 break;
1086
1087 case CHANNEL_12:
1088 sap_update_rssi_bsscount(spect_ch, -4, true);
1089 sap_update_rssi_bsscount(spect_ch, -3, true);
1090 sap_update_rssi_bsscount(spect_ch, -2, true);
1091 sap_update_rssi_bsscount(spect_ch, -1, true);
1092 sap_update_rssi_bsscount(spect_ch, 1, true);
1093 sap_update_rssi_bsscount(spect_ch, 2, true);
1094 break;
1095
1096 case CHANNEL_13:
1097 sap_update_rssi_bsscount(spect_ch, -4, true);
1098 sap_update_rssi_bsscount(spect_ch, -3, true);
1099 sap_update_rssi_bsscount(spect_ch, -2, true);
1100 sap_update_rssi_bsscount(spect_ch, -1, true);
1101 sap_update_rssi_bsscount(spect_ch, 1, true);
1102 break;
1103
1104 case CHANNEL_14:
1105 sap_update_rssi_bsscount(spect_ch, -4, true);
1106 sap_update_rssi_bsscount(spect_ch, -3, true);
1107 sap_update_rssi_bsscount(spect_ch, -2, true);
1108 sap_update_rssi_bsscount(spect_ch, -1, true);
1109 break;
1110
1111 default:
1112 break;
1113 }
1114}
1115
1116/*==========================================================================
1117 Function ch_in_pcl
1118
1119 Description
1120 Check if a channel is in the preferred channel list
1121
1122 Parameters
1123 sap_ctx SAP context pointer
1124 channel input channel number
1125
1126 Return Value
1127 true: channel is in PCL
1128 false: channel is not in PCL
1129 ==========================================================================*/
1130bool ch_in_pcl(ptSapContext sap_ctx, uint8_t channel)
1131{
1132 uint32_t i;
1133
1134 for (i = 0; i < sap_ctx->acs_cfg->pcl_ch_count; i++) {
1135 if (channel == sap_ctx->acs_cfg->pcl_channels[i])
1136 return true;
1137 }
1138
1139 return false;
1140}
1141
1142/*==========================================================================
1143 FUNCTION sap_compute_spect_weight
1144
1145 DESCRIPTION
1146 Main function for computing the weight of each channel in the
1147 spectrum based on the RSSI value of the BSSes on the channel
1148 and number of BSS
1149
1150 DEPENDENCIES
1151 NA.
1152
1153 PARAMETERS
1154
1155 IN
1156 pSpectInfoParams : Pointer to the tSpectInfoParams structure
1157 halHandle : Pointer to HAL handle
1158 pResult : Pointer to tScanResultHandle
1159
1160 RETURN VALUE
1161 void : NULL
1162
1163 SIDE EFFECTS
1164 ============================================================================*/
1165void sap_compute_spect_weight(tSapChSelSpectInfo *pSpectInfoParams,
1166 tHalHandle halHandle, tScanResultHandle pResult,
1167 ptSapContext sap_ctx)
1168{
1169 int8_t rssi = 0;
1170 uint8_t chn_num = 0;
1171 uint8_t channel_id = 0;
1172
1173 tCsrScanResultInfo *pScanResult;
1174 tSapSpectChInfo *pSpectCh = pSpectInfoParams->pSpectCh;
1175 uint32_t operatingBand;
1176 uint16_t channelWidth;
1177 uint16_t secondaryChannelOffset;
1178 uint16_t centerFreq;
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001179 uint16_t centerFreq_2 = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001180 uint16_t vhtSupport;
1181 uint32_t ieLen = 0;
1182 tSirProbeRespBeacon *pBeaconStruct;
1183 tpAniSirGlobal pMac = (tpAniSirGlobal) halHandle;
1184
1185 pBeaconStruct = cdf_mem_malloc(sizeof(tSirProbeRespBeacon));
1186 if (NULL == pBeaconStruct) {
1187 CDF_TRACE(CDF_MODULE_ID_SAP, CDF_TRACE_LEVEL_INFO_HIGH,
1188 "Unable to allocate memory in sap_compute_spect_weight\n");
1189 return;
1190 }
1191 CDF_TRACE(CDF_MODULE_ID_SAP, CDF_TRACE_LEVEL_INFO_HIGH,
1192 "In %s, Computing spectral weight", __func__);
1193
1194 /**
1195 * Soft AP specific channel weight calculation using DFS formula
1196 */
1197 SET_ACS_BAND(operatingBand, sap_ctx);
1198
1199 pScanResult = sme_scan_result_get_first(halHandle, pResult);
1200
1201 while (pScanResult) {
1202 pSpectCh = pSpectInfoParams->pSpectCh;
1203 /* Defining the default values, so that any value will hold the default values */
1204 channelWidth = eHT_CHANNEL_WIDTH_20MHZ;
1205 secondaryChannelOffset = PHY_SINGLE_CHANNEL_CENTERED;
1206 vhtSupport = 0;
1207 centerFreq = 0;
1208
1209 if (pScanResult->BssDescriptor.ieFields != NULL) {
1210 ieLen =
1211 (pScanResult->BssDescriptor.length +
1212 sizeof(uint16_t) + sizeof(uint32_t) -
1213 sizeof(tSirBssDescription));
1214 cdf_mem_set((uint8_t *) pBeaconStruct,
1215 sizeof(tSirProbeRespBeacon), 0);
1216
1217 if ((sir_parse_beacon_ie
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001218 (pMac, pBeaconStruct, (uint8_t *)
1219 (pScanResult->BssDescriptor.ieFields),
1220 ieLen)) == eSIR_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001221 sap_upd_chan_spec_params(pBeaconStruct,
1222 &channelWidth, &secondaryChannelOffset,
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001223 &vhtSupport, &centerFreq,
1224 &centerFreq_2);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001225 }
1226 }
1227 /* Processing for each tCsrScanResultInfo in the tCsrScanResult DLink list */
1228 for (chn_num = 0; chn_num < pSpectInfoParams->numSpectChans;
1229 chn_num++) {
1230
1231 /*
1232 * if the Beacon has channel ID, use it other wise we will
1233 * rely on the channelIdSelf
1234 */
1235 if (pScanResult->BssDescriptor.channelId == 0)
1236 channel_id =
1237 pScanResult->BssDescriptor.channelIdSelf;
1238 else
1239 channel_id =
1240 pScanResult->BssDescriptor.channelId;
1241
1242 if (pSpectCh && (channel_id == pSpectCh->chNum)) {
1243 if (pSpectCh->rssiAgr <
1244 pScanResult->BssDescriptor.rssi)
1245 pSpectCh->rssiAgr =
1246 pScanResult->BssDescriptor.rssi;
1247
1248 ++pSpectCh->bssCount; /* Increment the count of BSS */
1249
1250 /*
1251 * Connsidering the Extension Channel
1252 * only in a channels
1253 */
1254 switch (operatingBand) {
1255 case eCSR_DOT11_MODE_11a:
1256 sap_interference_rssi_count_5G(
1257 pSpectCh, channelWidth,
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001258 secondaryChannelOffset,
1259 centerFreq,
1260 centerFreq_2,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001261 channel_id);
1262 break;
1263
1264 case eCSR_DOT11_MODE_11g:
1265 sap_interference_rssi_count(pSpectCh);
1266 break;
1267
1268 case eCSR_DOT11_MODE_abg:
1269 sap_interference_rssi_count_5G(
1270 pSpectCh, channelWidth,
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001271 secondaryChannelOffset,
1272 centerFreq,
1273 centerFreq_2,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001274 channel_id);
1275 sap_interference_rssi_count(pSpectCh);
1276 break;
1277 }
1278
1279 CDF_TRACE(CDF_MODULE_ID_SAP,
1280 CDF_TRACE_LEVEL_INFO_HIGH,
1281 "In %s, bssdes.ch_self=%d, bssdes.ch_ID=%d, bssdes.rssi=%d, SpectCh.bssCount=%d, pScanResult=%p, ChannelWidth %d, secondaryChanOffset %d, center frequency %d \n",
1282 __func__,
1283 pScanResult->BssDescriptor.
1284 channelIdSelf,
1285 pScanResult->BssDescriptor.channelId,
1286 pScanResult->BssDescriptor.rssi,
1287 pSpectCh->bssCount, pScanResult,
1288 pSpectCh->channelWidth,
1289 secondaryChannelOffset, centerFreq);
1290 pSpectCh++;
1291 break;
1292 } else {
1293 pSpectCh++;
1294 }
1295 }
1296
1297 pScanResult = sme_scan_result_get_next(halHandle, pResult);
1298 }
1299
1300 /* Calculate the weights for all channels in the spectrum pSpectCh */
1301 pSpectCh = pSpectInfoParams->pSpectCh;
1302
1303 CDF_TRACE(CDF_MODULE_ID_SAP, CDF_TRACE_LEVEL_INFO_HIGH,
1304 "In %s, Spectrum Channels Weight", __func__);
1305
1306 for (chn_num = 0; chn_num < (pSpectInfoParams->numSpectChans);
1307 chn_num++) {
1308
1309 /*
1310 rssi : Maximum received signal strength among all BSS on that channel
1311 bssCount : Number of BSS on that channel
1312 */
1313
1314 rssi = (int8_t) pSpectCh->rssiAgr;
1315 if (ch_in_pcl(sap_ctx, chn_num))
1316 rssi -= PCL_RSSI_DISCOUNT;
1317
1318 pSpectCh->weight =
1319 SAPDFS_NORMALISE_1000 * sapweight_rssi_count(rssi,
1320 pSpectCh->
1321 bssCount);
1322 pSpectCh->weight_copy = pSpectCh->weight;
1323
1324 /* ------ Debug Info ------ */
1325 CDF_TRACE(CDF_MODULE_ID_SAP, CDF_TRACE_LEVEL_INFO_HIGH,
1326 "In %s, Chan=%d Weight= %d rssiAgr=%d bssCount=%d",
1327 __func__, pSpectCh->chNum, pSpectCh->weight,
1328 pSpectCh->rssiAgr, pSpectCh->bssCount);
1329 /* ------ Debug Info ------ */
1330 pSpectCh++;
1331 }
1332 cdf_mem_free(pBeaconStruct);
1333}
1334
1335/*==========================================================================
1336 FUNCTION sap_chan_sel_exit
1337
1338 DESCRIPTION
1339 Exit function for free out the allocated memory, to be called
1340 at the end of the dfsSelectChannel function
1341
1342 DEPENDENCIES
1343 NA.
1344
1345 PARAMETERS
1346
1347 IN
1348 pSpectInfoParams : Pointer to the tSapChSelSpectInfo structure
1349
1350 RETURN VALUE
1351 void : NULL
1352
1353 SIDE EFFECTS
1354 ============================================================================*/
1355void sap_chan_sel_exit(tSapChSelSpectInfo *pSpectInfoParams)
1356{
1357 /* Free all the allocated memory */
1358 cdf_mem_free(pSpectInfoParams->pSpectCh);
1359}
1360
1361/*==========================================================================
1362 FUNCTION sap_sort_chl_weight
1363
1364 DESCRIPTION
1365 Funtion to sort the channels with the least weight first for 20MHz channels
1366
1367 DEPENDENCIES
1368 NA.
1369
1370 PARAMETERS
1371
1372 IN
1373 pSpectInfoParams : Pointer to the tSapChSelSpectInfo structure
1374
1375 RETURN VALUE
1376 void : NULL
1377
1378 SIDE EFFECTS
1379 ============================================================================*/
1380void sap_sort_chl_weight(tSapChSelSpectInfo *pSpectInfoParams)
1381{
1382 tSapSpectChInfo temp;
1383
1384 tSapSpectChInfo *pSpectCh = NULL;
1385 uint32_t i = 0, j = 0, minWeightIndex = 0;
1386
1387 pSpectCh = pSpectInfoParams->pSpectCh;
1388 for (i = 0; i < pSpectInfoParams->numSpectChans; i++) {
1389 minWeightIndex = i;
1390 for (j = i + 1; j < pSpectInfoParams->numSpectChans; j++) {
1391 if (pSpectCh[j].weight <
1392 pSpectCh[minWeightIndex].weight) {
1393 minWeightIndex = j;
1394 }
1395 }
1396 if (minWeightIndex != i) {
1397 cdf_mem_copy(&temp, &pSpectCh[minWeightIndex],
1398 sizeof(*pSpectCh));
1399 cdf_mem_copy(&pSpectCh[minWeightIndex], &pSpectCh[i],
1400 sizeof(*pSpectCh));
1401 cdf_mem_copy(&pSpectCh[i], &temp, sizeof(*pSpectCh));
1402 }
1403 }
1404}
1405
1406/**
1407 * sap_sort_chl_weight_ht80() - to sort the channels with the least weight
1408 * @pSpectInfoParams: Pointer to the tSapChSelSpectInfo structure
1409 *
1410 * Funtion to sort the channels with the least weight first for HT80 channels
1411 *
1412 * Return: none
1413 */
1414void sap_sort_chl_weight_ht80(tSapChSelSpectInfo *pSpectInfoParams)
1415{
1416 uint8_t i, j, n;
1417 tSapSpectChInfo *pSpectInfo;
1418 uint8_t minIdx;
1419
1420 pSpectInfo = pSpectInfoParams->pSpectCh;
1421 /* for each HT80 channel, calculate the combined weight of the
1422 four 20MHz weight */
1423 for (i = 0; i < ARRAY_SIZE(acs_ht80_channels); i++) {
1424 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
1425 if (pSpectInfo[j].chNum ==
1426 acs_ht80_channels[i].chStartNum)
1427 break;
1428 }
1429 if (j == pSpectInfoParams->numSpectChans)
1430 continue;
1431
1432 if (!(((pSpectInfo[j].chNum + 4) == pSpectInfo[j + 1].chNum) &&
1433 ((pSpectInfo[j].chNum + 8) ==
1434 pSpectInfo[j + 2].chNum) &&
1435 ((pSpectInfo[j].chNum + 12) ==
1436 pSpectInfo[j + 3].chNum))) {
1437 /*
1438 * some channels does not exist in pSectInfo array,
1439 * skip this channel and those in the same HT80 width
1440 */
1441 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 4;
1442 if ((pSpectInfo[j].chNum + 4) ==
1443 pSpectInfo[j + 1].chNum)
1444 pSpectInfo[j + 1].weight =
1445 SAP_ACS_WEIGHT_MAX * 4;
1446 if ((pSpectInfo[j].chNum + 8) ==
1447 pSpectInfo[j + 2].chNum)
1448 pSpectInfo[j + 2].weight =
1449 SAP_ACS_WEIGHT_MAX * 4;
1450 if ((pSpectInfo[j].chNum + 12) ==
1451 pSpectInfo[j + 3].chNum)
1452 pSpectInfo[j + 3].weight =
1453 SAP_ACS_WEIGHT_MAX * 4;
1454 continue;
1455 }
1456 /*found the channel, add the 4 adjacent channels' weight */
1457 acs_ht80_channels[i].weight = pSpectInfo[j].weight +
1458 pSpectInfo[j + 1].weight + pSpectInfo[j + 2].weight +
1459 pSpectInfo[j + 3].weight;
1460 /* find best channel among 4 channels as the primary channel */
1461 if ((pSpectInfo[j].weight + pSpectInfo[j + 1].weight) <
1462 (pSpectInfo[j + 2].weight + pSpectInfo[j + 3].weight)) {
1463 /* lower 2 channels are better choice */
1464 if (pSpectInfo[j].weight < pSpectInfo[j + 1].weight)
1465 minIdx = 0;
1466 else
1467 minIdx = 1;
1468 } else if (pSpectInfo[j + 2].weight <=
1469 pSpectInfo[j + 3].weight) {
1470 /* upper 2 channels are better choice */
1471 minIdx = 2;
1472 } else {
1473 minIdx = 3;
1474 }
1475
1476 /*
1477 * set all 4 channels to max value first, then reset the
1478 * best channel as the selected primary channel, update its
1479 * weightage with the combined weight value
1480 */
1481 for (n = 0; n < 4; n++)
1482 pSpectInfo[j + n].weight = SAP_ACS_WEIGHT_MAX * 4;
1483
1484 pSpectInfo[j + minIdx].weight = acs_ht80_channels[i].weight;
1485 }
1486
1487 pSpectInfo = pSpectInfoParams->pSpectCh;
1488 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
1489 if (CHANNEL_165 == pSpectInfo[j].chNum) {
1490 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 4;
1491 break;
1492 }
1493 }
1494
1495 pSpectInfo = pSpectInfoParams->pSpectCh;
1496 for (j = 0; j < (pSpectInfoParams->numSpectChans); j++) {
1497 CDF_TRACE(CDF_MODULE_ID_SAP, CDF_TRACE_LEVEL_INFO_HIGH,
1498 FL("Channel=%d Weight= %d rssi=%d bssCount=%d"),
1499 pSpectInfo->chNum, pSpectInfo->weight,
1500 pSpectInfo->rssiAgr, pSpectInfo->bssCount);
1501 pSpectInfo++;
1502 }
1503}
1504
1505/**
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001506 * sap_sort_chl_weight_vht160() - to sort the channels with the least weight
1507 * @pSpectInfoParams: Pointer to the tSapChSelSpectInfo structure
1508 *
1509 * Funtion to sort the channels with the least weight first for VHT160 channels
1510 *
1511 * Return: none
1512 */
1513void sap_sort_chl_weight_vht160(tSapChSelSpectInfo *pSpectInfoParams)
1514{
1515 uint8_t i, j, n, idx;
1516 tSapSpectChInfo *pSpectInfo;
1517 uint8_t minIdx;
1518
1519 pSpectInfo = pSpectInfoParams->pSpectCh;
1520 /* for each VHT160 channel, calculate the combined weight of the
1521 8 20MHz weight */
1522 for (i = 0; i < ARRAY_SIZE(acs_vht160_channels); i++) {
1523 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
1524 if (pSpectInfo[j].chNum ==
1525 acs_vht160_channels[i].chStartNum)
1526 break;
1527 }
1528 if (j == pSpectInfoParams->numSpectChans)
1529 continue;
1530
1531 if (!(((pSpectInfo[j].chNum + 4) == pSpectInfo[j + 1].chNum) &&
1532 ((pSpectInfo[j].chNum + 8) ==
1533 pSpectInfo[j + 2].chNum) &&
1534 ((pSpectInfo[j].chNum + 12) ==
1535 pSpectInfo[j + 3].chNum) &&
1536 ((pSpectInfo[j].chNum + 16) ==
1537 pSpectInfo[j + 4].chNum) &&
1538 ((pSpectInfo[j].chNum + 20) ==
1539 pSpectInfo[j + 5].chNum) &&
1540 ((pSpectInfo[j].chNum + 24) ==
1541 pSpectInfo[j + 6].chNum) &&
1542 ((pSpectInfo[j].chNum + 28) ==
1543 pSpectInfo[j + 7].chNum))) {
1544 /*
1545 * some channels does not exist in pSectInfo array,
1546 * skip this channel and those in the same VHT160 width
1547 */
1548 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 8;
1549 if ((pSpectInfo[j].chNum + 4) ==
1550 pSpectInfo[j + 1].chNum)
1551 pSpectInfo[j + 1].weight =
1552 SAP_ACS_WEIGHT_MAX * 8;
1553 if ((pSpectInfo[j].chNum + 8) ==
1554 pSpectInfo[j + 2].chNum)
1555 pSpectInfo[j + 2].weight =
1556 SAP_ACS_WEIGHT_MAX * 8;
1557 if ((pSpectInfo[j].chNum + 12) ==
1558 pSpectInfo[j + 3].chNum)
1559 pSpectInfo[j + 3].weight =
1560 SAP_ACS_WEIGHT_MAX * 8;
1561 if ((pSpectInfo[j].chNum + 16) ==
1562 pSpectInfo[j + 4].chNum)
1563 pSpectInfo[j + 4].weight =
1564 SAP_ACS_WEIGHT_MAX * 8;
1565 if ((pSpectInfo[j].chNum + 20) ==
1566 pSpectInfo[j + 5].chNum)
1567 pSpectInfo[j + 5].weight =
1568 SAP_ACS_WEIGHT_MAX * 8;
1569 if ((pSpectInfo[j].chNum + 24) ==
1570 pSpectInfo[j + 6].chNum)
1571 pSpectInfo[j + 6].weight =
1572 SAP_ACS_WEIGHT_MAX * 8;
1573 if ((pSpectInfo[j].chNum + 28) ==
1574 pSpectInfo[j + 7].chNum)
1575 pSpectInfo[j + 7].weight =
1576 SAP_ACS_WEIGHT_MAX * 8;
1577 continue;
1578 }
1579 /*found the channel, add the 7 adjacent channels' weight */
1580 acs_vht160_channels[i].weight = pSpectInfo[j].weight +
1581 pSpectInfo[j + 1].weight + pSpectInfo[j + 2].weight +
1582 pSpectInfo[j + 3].weight + pSpectInfo[j + 4].weight +
1583 pSpectInfo[j + 5].weight + pSpectInfo[j + 6].weight +
1584 pSpectInfo[j + 7].weight;
1585
1586 /* find best channel among 8 channels as the primary channel */
1587 if ((pSpectInfo[j].weight + pSpectInfo[j + 1].weight +
1588 pSpectInfo[j + 2].weight + pSpectInfo[j + 3].weight) >
1589 (pSpectInfo[j + 4].weight + pSpectInfo[j + 5].weight +
1590 pSpectInfo[j + 6].weight + pSpectInfo[j + 7].weight))
1591 idx = 4;
1592 else
1593 idx = 0;
1594 /* find best channel among 4 channels as the primary channel */
1595 if ((pSpectInfo[j + idx].weight +
1596 pSpectInfo[j + idx + 1].weight) <
1597 (pSpectInfo[j + idx + 2].weight +
1598 pSpectInfo[j + idx + 3].weight)) {
1599 /* lower 2 channels are better choice */
1600 if (pSpectInfo[j + idx].weight <
1601 pSpectInfo[j + idx + 1].weight)
1602 minIdx = 0 + idx;
1603 else
1604 minIdx = 1 + idx;
1605 } else if (pSpectInfo[j + idx + 2].weight <=
1606 pSpectInfo[j + idx + 3].weight) {
1607 /* upper 2 channels are better choice */
1608 minIdx = 2 + idx;
1609 } else {
1610 minIdx = 3 + idx;
1611 }
1612
1613 /*
1614 * set all 8 channels to max value first, then reset the
1615 * best channel as the selected primary channel, update its
1616 * weightage with the combined weight value
1617 */
1618 for (n = 0; n < 8; n++)
1619 pSpectInfo[j + n].weight = SAP_ACS_WEIGHT_MAX * 8;
1620
1621 pSpectInfo[j + minIdx].weight = acs_vht160_channels[i].weight;
1622 }
1623
1624 pSpectInfo = pSpectInfoParams->pSpectCh;
1625 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
1626 if (CHANNEL_165 == pSpectInfo[j].chNum) {
1627 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 8;
1628 break;
1629 }
1630 }
1631
1632 pSpectInfo = pSpectInfoParams->pSpectCh;
1633 for (j = 0; j < (pSpectInfoParams->numSpectChans); j++) {
1634 CDF_TRACE(CDF_MODULE_ID_SAP, CDF_TRACE_LEVEL_INFO_HIGH,
1635 FL("Channel=%d Weight= %d rssi=%d bssCount=%d"),
1636 pSpectInfo->chNum, pSpectInfo->weight,
1637 pSpectInfo->rssiAgr, pSpectInfo->bssCount);
1638 pSpectInfo++;
1639 }
1640}
1641
1642/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001643 * sap_sort_chl_weight_ht40_24_g() - to sort channel with the least weight
1644 * @pSpectInfoParams: Pointer to the tSapChSelSpectInfo structure
1645 *
1646 * Funtion to sort the channels with the least weight first for HT40 channels
1647 *
1648 * Return: none
1649 */
1650void sap_sort_chl_weight_ht40_24_g(tSapChSelSpectInfo *pSpectInfoParams)
1651{
1652 uint8_t i, j;
1653 tSapSpectChInfo *pSpectInfo;
1654 uint32_t tmpWeight1, tmpWeight2;
1655
1656 pSpectInfo = pSpectInfoParams->pSpectCh;
1657 /*
1658 * for each HT40 channel, calculate the combined weight of the
1659 * two 20MHz weight
1660 */
1661 for (i = 0; i < ARRAY_SIZE(acs_ht40_channels24_g); i++) {
1662 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
1663 if (pSpectInfo[j].chNum ==
1664 acs_ht40_channels24_g[i].chStartNum)
1665 break;
1666 }
1667 if (j == pSpectInfoParams->numSpectChans)
1668 continue;
1669
1670 if (!((pSpectInfo[j].chNum + 4) == pSpectInfo[j + 4].chNum)) {
1671 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2;
1672 continue;
1673 }
1674 /*
1675 * check if there is another channel combination possiblity
1676 * e.g., {1, 5} & {5, 9}
1677 */
1678 if ((pSpectInfo[j + 4].chNum + 4) == pSpectInfo[j + 8].chNum) {
1679 /* need to compare two channel pairs */
1680 tmpWeight1 = pSpectInfo[j].weight +
1681 pSpectInfo[j + 4].weight;
1682 tmpWeight2 = pSpectInfo[j + 4].weight +
1683 pSpectInfo[j + 8].weight;
1684 if (tmpWeight1 <= tmpWeight2) {
1685 if (pSpectInfo[j].weight <=
1686 pSpectInfo[j + 4].weight) {
1687 pSpectInfo[j].weight =
1688 tmpWeight1;
1689 pSpectInfo[j + 4].weight =
1690 SAP_ACS_WEIGHT_MAX * 2;
1691 pSpectInfo[j + 8].weight =
1692 SAP_ACS_WEIGHT_MAX * 2;
1693 } else {
1694 pSpectInfo[j + 4].weight =
1695 tmpWeight1;
1696 /* for secondary channel selection */
1697 pSpectInfo[j].weight =
1698 SAP_ACS_WEIGHT_MAX * 2
1699 - 1;
1700 pSpectInfo[j + 8].weight =
1701 SAP_ACS_WEIGHT_MAX * 2;
1702 }
1703 } else {
1704 if (pSpectInfo[j + 4].weight <=
1705 pSpectInfo[j + 8].weight) {
1706 pSpectInfo[j + 4].weight =
1707 tmpWeight2;
1708 pSpectInfo[j].weight =
1709 SAP_ACS_WEIGHT_MAX * 2;
1710 /* for secondary channel selection */
1711 pSpectInfo[j + 8].weight =
1712 SAP_ACS_WEIGHT_MAX * 2
1713 - 1;
1714 } else {
1715 pSpectInfo[j + 8].weight =
1716 tmpWeight2;
1717 pSpectInfo[j].weight =
1718 SAP_ACS_WEIGHT_MAX * 2;
1719 pSpectInfo[j + 4].weight =
1720 SAP_ACS_WEIGHT_MAX * 2;
1721 }
1722 }
1723 } else {
1724 tmpWeight1 = pSpectInfo[j].weight +
1725 pSpectInfo[j + 4].weight;
1726 if (pSpectInfo[j].weight <=
1727 pSpectInfo[j + 4].weight) {
1728 pSpectInfo[j].weight = tmpWeight1;
1729 pSpectInfo[j + 4].weight =
1730 SAP_ACS_WEIGHT_MAX * 2;
1731 } else {
1732 pSpectInfo[j + 4].weight = tmpWeight1;
1733 pSpectInfo[j].weight =
1734 SAP_ACS_WEIGHT_MAX * 2;
1735 }
1736 }
1737 }
1738}
1739
1740/*==========================================================================
1741 FUNCTION sap_sort_chl_weight_ht40_5_g
1742
1743 DESCRIPTION
1744 Funtion to sort the channels with the least weight first for HT40 channels
1745
1746 DEPENDENCIES
1747 NA.
1748
1749 PARAMETERS
1750
1751 IN
1752 pSpectInfoParams : Pointer to the tSapChSelSpectInfo structure
1753
1754 RETURN VALUE
1755 void : NULL
1756
1757 SIDE EFFECTS
1758 ============================================================================*/
1759void sap_sort_chl_weight_ht40_5_g(tSapChSelSpectInfo *pSpectInfoParams)
1760{
1761 uint8_t i, j;
1762 tSapSpectChInfo *pSpectInfo;
1763
1764 pSpectInfo = pSpectInfoParams->pSpectCh;
1765 /*for each HT40 channel, calculate the combined weight of the
1766 two 20MHz weight */
1767 for (i = 0; i < ARRAY_SIZE(acs_ht40_channels5_g); i++) {
1768 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
1769 if (pSpectInfo[j].chNum ==
1770 acs_ht40_channels5_g[i].chStartNum)
1771 break;
1772 }
1773 if (j == pSpectInfoParams->numSpectChans)
1774 continue;
1775
1776 /* found the channel, add the two adjacent channels' weight */
1777 if ((pSpectInfo[j].chNum + 4) == pSpectInfo[j + 1].chNum) {
1778 acs_ht40_channels5_g[i].weight = pSpectInfo[j].weight +
1779 pSpectInfo[j + 1].weight;
1780 /* select better of the adjact channel as the primary channel */
1781 if (pSpectInfo[j].weight <= pSpectInfo[j + 1].weight) {
1782 pSpectInfo[j].weight =
1783 acs_ht40_channels5_g[i].weight;
1784 /* mark the adjacent channel's weight as max value so
1785 that it will be sorted to the bottom */
1786 pSpectInfo[j + 1].weight =
1787 SAP_ACS_WEIGHT_MAX * 2;
1788 } else {
1789 pSpectInfo[j + 1].weight =
1790 acs_ht40_channels5_g[i].weight;
1791 /* mark the adjacent channel's weight as max value so
1792 that it will be sorted to the bottom */
1793 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2;
1794 }
1795
1796 } else
1797 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2;
1798 }
1799
1800 /* avoid channel 165 by setting its weight to max */
1801 pSpectInfo = pSpectInfoParams->pSpectCh;
1802 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
1803 if (CHANNEL_165 == pSpectInfo[j].chNum) {
1804 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2;
1805 break;
1806 }
1807 }
1808
1809 pSpectInfo = pSpectInfoParams->pSpectCh;
1810 for (j = 0; j < (pSpectInfoParams->numSpectChans); j++) {
1811 CDF_TRACE(CDF_MODULE_ID_SAP, CDF_TRACE_LEVEL_INFO_HIGH,
1812 "In %s, Channel=%d Weight= %d rssi=%d bssCount=%d",
1813 __func__, pSpectInfo->chNum, pSpectInfo->weight,
1814 pSpectInfo->rssiAgr, pSpectInfo->bssCount);
1815 pSpectInfo++;
1816 }
1817
1818 sap_sort_chl_weight(pSpectInfoParams);
1819}
1820
1821/*==========================================================================
1822 FUNCTION sap_sort_chl_weight_all
1823
1824 DESCRIPTION
1825 Funtion to sort the channels with the least weight first
1826
1827 DEPENDENCIES
1828 NA.
1829
1830 PARAMETERS
1831
1832 IN
1833 ptSapContext : Pointer to the ptSapContext structure
1834 pSpectInfoParams : Pointer to the tSapChSelSpectInfo structure
1835
1836 RETURN VALUE
1837 void : NULL
1838
1839 SIDE EFFECTS
1840 ============================================================================*/
1841void sap_sort_chl_weight_all(ptSapContext pSapCtx,
1842 tSapChSelSpectInfo *pSpectInfoParams,
1843 uint32_t operatingBand)
1844{
1845 tSapSpectChInfo *pSpectCh = NULL;
1846 uint32_t j = 0;
1847#ifndef SOFTAP_CHANNEL_RANGE
1848 uint32_t i = 0;
1849#endif
1850
1851 pSpectCh = pSpectInfoParams->pSpectCh;
1852#ifdef SOFTAP_CHANNEL_RANGE
1853
1854 switch (pSapCtx->acs_cfg->ch_width) {
1855 case CH_WIDTH_40MHZ:
1856 if (eCSR_DOT11_MODE_11g == operatingBand)
1857 sap_sort_chl_weight_ht40_24_g(pSpectInfoParams);
1858 else if (eCSR_DOT11_MODE_11a == operatingBand)
1859 sap_sort_chl_weight_ht40_5_g(pSpectInfoParams);
1860 else {
1861 sap_sort_chl_weight_ht40_24_g(pSpectInfoParams);
1862 sap_sort_chl_weight_ht40_5_g(pSpectInfoParams);
1863 }
1864 sap_sort_chl_weight(pSpectInfoParams);
1865 break;
1866
1867 case CH_WIDTH_80MHZ:
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001868 case CH_WIDTH_80P80MHZ:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001869 sap_sort_chl_weight_ht80(pSpectInfoParams);
1870 break;
1871
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001872 case CH_WIDTH_160MHZ:
1873 sap_sort_chl_weight_vht160(pSpectInfoParams);
1874 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001875 case CH_WIDTH_20MHZ:
1876 default:
1877 /* Sorting the channels as per weights as 20MHz channels */
1878 sap_sort_chl_weight(pSpectInfoParams);
1879 }
1880
1881#else
1882 /* Sorting the channels as per weights */
1883 for (i = 0; i < SPECT_24GHZ_CH_COUNT; i++) {
1884 minWeightIndex = i;
1885 for (j = i + 1; j < SPECT_24GHZ_CH_COUNT; j++) {
1886 if (pSpectCh[j].weight <
1887 pSpectCh[minWeightIndex].weight) {
1888 minWeightIndex = j;
1889 }
1890 }
1891 if (minWeightIndex != i) {
1892 cdf_mem_copy(&temp, &pSpectCh[minWeightIndex],
1893 sizeof(*pSpectCh));
1894 cdf_mem_copy(&pSpectCh[minWeightIndex], &pSpectCh[i],
1895 sizeof(*pSpectCh));
1896 cdf_mem_copy(&pSpectCh[i], &temp, sizeof(*pSpectCh));
1897 }
1898 }
1899#endif
1900
1901 /* For testing */
1902 CDF_TRACE(CDF_MODULE_ID_SAP, CDF_TRACE_LEVEL_INFO_HIGH,
1903 "In %s, Sorted Spectrum Channels Weight", __func__);
1904 pSpectCh = pSpectInfoParams->pSpectCh;
1905 for (j = 0; j < (pSpectInfoParams->numSpectChans); j++) {
1906 CDF_TRACE(CDF_MODULE_ID_SAP, CDF_TRACE_LEVEL_INFO_HIGH,
1907 "In %s, Channel=%d Weight= %d rssi=%d bssCount=%d",
1908 __func__, pSpectCh->chNum, pSpectCh->weight,
1909 pSpectCh->rssiAgr, pSpectCh->bssCount);
1910 pSpectCh++;
1911 }
1912
1913}
1914
1915/*==========================================================================
1916 FUNCTION sap_filter_over_lap_ch
1917
1918 DESCRIPTION
1919 return true if ch is acceptable.
1920 This function will decide if we will filter over lap channel or not.
1921
1922 DEPENDENCIES
1923 shall called after ap start.
1924
1925 PARAMETERS
1926
1927 IN
1928 pSapCtx : Pointer to ptSapContext.
1929 chNum : Filter channel number.
1930
1931 RETURN VALUE
1932 bool : true if channel is accepted.
1933
1934 SIDE EFFECTS
1935 ============================================================================*/
1936bool sap_filter_over_lap_ch(ptSapContext pSapCtx, uint16_t chNum)
1937{
1938 if (pSapCtx->enableOverLapCh)
1939 return eSAP_TRUE;
1940 else if ((chNum == CHANNEL_1) ||
1941 (chNum == CHANNEL_6) || (chNum == CHANNEL_11))
1942 return eSAP_TRUE;
1943
1944 return eSAP_FALSE;
1945}
1946
1947/*==========================================================================
1948 FUNCTION sap_select_channel
1949
1950 DESCRIPTION
1951 Runs a algorithm to select the best channel to operate in based on BSS
1952 rssi and bss count on each channel
1953
1954 DEPENDENCIES
1955 NA.
1956
1957 PARAMETERS
1958
1959 IN
1960 halHandle : Pointer to HAL handle
1961 pResult : Pointer to tScanResultHandle
1962
1963 RETURN VALUE
1964 uint8_t : Success - channel number, Fail - zero
1965
1966 SIDE EFFECTS
1967 ============================================================================*/
1968uint8_t sap_select_channel(tHalHandle halHandle, ptSapContext pSapCtx,
1969 tScanResultHandle pScanResult)
1970{
1971 /* DFS param object holding all the data req by the algo */
1972 tSapChSelSpectInfo oSpectInfoParams = { NULL, 0 };
1973 tSapChSelSpectInfo *pSpectInfoParams = &oSpectInfoParams; /* Memory? NB */
1974 uint8_t bestChNum = SAP_CHANNEL_NOT_SELECTED;
1975#ifdef FEATURE_WLAN_CH_AVOID
1976 uint8_t i;
1977 uint8_t firstSafeChannelInRange = SAP_CHANNEL_NOT_SELECTED;
1978#endif
1979#ifdef SOFTAP_CHANNEL_RANGE
1980 uint32_t startChannelNum;
1981 uint32_t endChannelNum;
1982 uint32_t operatingBand = 0;
1983 uint32_t tmpChNum;
1984 uint8_t count;
1985#endif
1986 CDF_TRACE(CDF_MODULE_ID_SAP, CDF_TRACE_LEVEL_INFO_HIGH,
1987 "In %s, Running SAP Ch Select", __func__);
1988
1989#ifdef FEATURE_WLAN_CH_AVOID
1990 sap_update_unsafe_channel_list(pSapCtx);
1991#endif
1992
1993 if (NULL == pScanResult) {
1994 CDF_TRACE(CDF_MODULE_ID_SAP, CDF_TRACE_LEVEL_INFO_HIGH,
1995 "%s: No external AP present\n", __func__);
1996
1997#ifndef SOFTAP_CHANNEL_RANGE
1998 return bestChNum;
1999#else
2000 startChannelNum = pSapCtx->acs_cfg->start_ch;
2001 endChannelNum = pSapCtx->acs_cfg->end_ch;
2002
2003
2004 CDF_TRACE(CDF_MODULE_ID_SAP, CDF_TRACE_LEVEL_INFO_HIGH,
2005 "%s: start - end: %d - %d\n", __func__,
2006 startChannelNum, endChannelNum);
2007
2008#ifndef FEATURE_WLAN_CH_AVOID /* FEATURE_WLAN_CH_AVOID NOT defined case */
2009 pSapCtx->acs_cfg->pri_ch = startChannelNum;
2010 pSapCtx->acs_cfg->ht_sec_ch = 0;
2011 /* pick the first channel in configured range */
2012 return startChannelNum;
2013#else /* FEATURE_WLAN_CH_AVOID defined */
2014
2015 /* get a channel in PCL and within the range */
2016 for (i = 0; i < pSapCtx->acs_cfg->pcl_ch_count; i++) {
2017 if ((pSapCtx->acs_cfg->pcl_channels[i] >=
2018 startChannelNum)
2019 && (pSapCtx->acs_cfg->pcl_channels[i] <=
2020 endChannelNum)) {
2021 firstSafeChannelInRange =
2022 pSapCtx->acs_cfg->pcl_channels[i];
2023 break;
2024 }
2025 }
2026 if (SAP_CHANNEL_NOT_SELECTED != firstSafeChannelInRange)
2027 return firstSafeChannelInRange;
2028
2029 for (i = 0; i < NUM_20MHZ_RF_CHANNELS; i++) {
2030 if ((safe_channels[i].channelNumber >= startChannelNum)
2031 && (safe_channels[i].channelNumber <=
2032 endChannelNum)) {
2033 CHANNEL_STATE channel_type =
2034 cds_get_channel_state(safe_channels[i].
2035 channelNumber);
2036
2037 if ((channel_type == CHANNEL_STATE_DISABLE) ||
2038 (channel_type == CHANNEL_STATE_INVALID))
2039 continue;
2040
2041 if (safe_channels[i].isSafe == true) {
2042 CDF_TRACE(CDF_MODULE_ID_SAP,
2043 CDF_TRACE_LEVEL_INFO_HIGH,
2044 "%s: channel %d in the configuration is safe\n",
2045 __func__,
2046 safe_channels[i].
2047 channelNumber);
2048 firstSafeChannelInRange =
2049 safe_channels[i].channelNumber;
2050 break;
2051 }
2052
2053 CDF_TRACE(CDF_MODULE_ID_SAP,
2054 CDF_TRACE_LEVEL_INFO_HIGH,
2055 "%s: channel %d in the configuration is unsafe\n",
2056 __func__,
2057 safe_channels[i].channelNumber);
2058 }
2059 }
2060
2061 /* if no channel selected return SAP_CHANNEL_NOT_SELECTED */
2062 return firstSafeChannelInRange;
2063#endif /* !FEATURE_WLAN_CH_AVOID */
2064#endif /* SOFTAP_CHANNEL_RANGE */
2065 }
2066
2067 /* Initialize the structure pointed by pSpectInfoParams */
2068 if (sap_chan_sel_init(halHandle, pSpectInfoParams, pSapCtx) != eSAP_TRUE) {
2069 CDF_TRACE(CDF_MODULE_ID_SAP, CDF_TRACE_LEVEL_ERROR,
2070 "In %s, Ch Select initialization failed", __func__);
2071 return SAP_CHANNEL_NOT_SELECTED;
2072 }
2073 /* Compute the weight of the entire spectrum in the operating band */
2074 sap_compute_spect_weight(pSpectInfoParams, halHandle, pScanResult,
2075 pSapCtx);
2076
2077#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
2078 /* process avoid channel IE to collect all channels to avoid */
2079 sap_process_avoid_ie(halHandle, pSapCtx, pScanResult, pSpectInfoParams);
2080#endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
2081
2082#ifdef SOFTAP_CHANNEL_RANGE
2083 startChannelNum = pSapCtx->acs_cfg->start_ch;
2084 endChannelNum = pSapCtx->acs_cfg->end_ch;
2085 SET_ACS_BAND(operatingBand, pSapCtx);
2086
2087 pSapCtx->acsBestChannelInfo.channelNum = 0;
2088 pSapCtx->acsBestChannelInfo.weight = SAP_ACS_WEIGHT_MAX;
2089
2090 /* Sort the channel list as per the computed weights, lesser weight first. */
2091 sap_sort_chl_weight_all(pSapCtx, pSpectInfoParams, operatingBand);
2092
2093 /*Loop till get the best channel in the given range */
2094 for (count = 0; count < pSpectInfoParams->numSpectChans; count++) {
2095 if ((startChannelNum <= pSpectInfoParams->pSpectCh[count].chNum)
2096 && (endChannelNum >=
2097 pSpectInfoParams->pSpectCh[count].chNum)) {
2098 if (bestChNum == SAP_CHANNEL_NOT_SELECTED) {
2099 bestChNum =
2100 pSpectInfoParams->pSpectCh[count].chNum;
2101 /* check if bestChNum is in preferred channel list */
2102 bestChNum =
2103 sap_select_preferred_channel_from_channel_list
2104 (bestChNum, pSapCtx, pSpectInfoParams);
2105 if (bestChNum == SAP_CHANNEL_NOT_SELECTED) {
2106 /* not in preferred channel list, go to next best channel */
2107 continue;
2108 }
2109
2110#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
2111 /* Weight of the channels(device's AP is
2112 * operating) increased to MAX+1 so that they
2113 * will be choosen only when there is no other
2114 * best channel to choose
2115 */
2116 if (sap_check_in_avoid_ch_list(pSapCtx,
2117 bestChNum)) {
2118 bestChNum = SAP_CHANNEL_NOT_SELECTED;
2119 continue;
2120 }
2121#endif
2122
2123 pSapCtx->acsBestChannelInfo.channelNum =
2124 bestChNum;
2125 pSapCtx->acsBestChannelInfo.weight =
2126 pSpectInfoParams->
2127 pSpectCh[count].
2128 weight_copy;
2129 }
2130
2131 if (bestChNum != SAP_CHANNEL_NOT_SELECTED) {
2132 if (operatingBand == eCSR_DOT11_MODE_11g) {
2133 /* Give preference to Non-overlap channels */
2134 if (sap_filter_over_lap_ch(pSapCtx,
2135 pSpectInfoParams->
2136 pSpectCh[count].
2137 chNum)) {
2138 tmpChNum =
2139 pSpectInfoParams->
2140 pSpectCh[count].chNum;
2141 tmpChNum =
2142 sap_select_preferred_channel_from_channel_list
2143 (tmpChNum, pSapCtx,
2144 pSpectInfoParams);
2145 if (tmpChNum !=
2146 SAP_CHANNEL_NOT_SELECTED) {
2147 bestChNum = tmpChNum;
2148 break;
2149 }
2150 }
2151 }
2152 }
2153 }
2154 }
2155#else
2156 /* Sort the channel list as per the computed weights, lesser weight first. */
2157 sap_sort_chl_weight_all(pSapCtx, halHandle, pSpectInfoParams);
2158 /* Get the first channel in sorted array as best 20M Channel */
2159 bestChNum = (uint8_t) pSpectInfoParams->pSpectCh[0].chNum;
2160 /* Select Best Channel from Channel List if Configured */
2161 bestChNum = sap_select_preferred_channel_from_channel_list(bestChNum,
2162 pSapCtx,
2163 pSpectInfoParams);
2164#endif
2165
2166 /** in case the best channel seleted is not in PCL and there is another
2167 * channel which has same weightage and is in PCL, choose the one in
2168 * PCL
2169 */
2170 for (count = 0; count < pSpectInfoParams->numSpectChans; count++) {
2171 /** check if a pcl channel has the same weightage
2172 * as the best channel
2173 */
2174 if (ch_in_pcl(pSapCtx, pSpectInfoParams->pSpectCh[count].chNum)
2175 && (pSpectInfoParams->pSpectCh[count].weight ==
2176 pSapCtx->acsBestChannelInfo.weight)) {
2177 if (sap_select_preferred_channel_from_channel_list(
2178 pSpectInfoParams->pSpectCh[count].chNum,
2179 pSapCtx, pSpectInfoParams) ==
2180 SAP_CHANNEL_NOT_SELECTED)
2181 continue;
2182
2183#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
2184 if (sap_check_in_avoid_ch_list(pSapCtx, bestChNum))
2185 continue;
2186#endif
2187 bestChNum = pSpectInfoParams->pSpectCh[count].chNum;
2188 CDF_TRACE(CDF_MODULE_ID_SAP,
2189 CDF_TRACE_LEVEL_INFO_HIGH,
2190 "change best channel to %d in PCL",
2191 bestChNum);
2192 break;
2193 }
2194 }
2195
2196 pSapCtx->acs_cfg->pri_ch = bestChNum;
2197 /* determine secondary channel for 2.4G channel 5, 6, 7 in HT40 */
2198 if ((operatingBand == eCSR_DOT11_MODE_11g) &&
2199 (pSapCtx->acs_cfg->ch_width == CH_WIDTH_40MHZ)) {
2200 if ((bestChNum >= 5) && (bestChNum <= 7)) {
2201 int weight_below, weight_above, i;
2202 tSapSpectChInfo *pspect_info;
2203
2204 weight_below = weight_above = SAP_ACS_WEIGHT_MAX;
2205 pspect_info = pSpectInfoParams->pSpectCh;
2206 for (i = 0; i < pSpectInfoParams->numSpectChans;
2207 i++) {
2208 if (pspect_info[i].chNum == (bestChNum - 4))
2209 weight_below = pspect_info[i].weight;
2210
2211 if (pspect_info[i].chNum == (bestChNum + 4))
2212 weight_above = pspect_info[i].weight;
2213 }
2214
2215 if (weight_below < weight_above)
2216 pSapCtx->acs_cfg->ht_sec_ch =
2217 pSapCtx->acs_cfg->pri_ch - 4;
2218 else
2219 pSapCtx->acs_cfg->ht_sec_ch =
2220 pSapCtx->acs_cfg->pri_ch + 4;
2221 } else if (bestChNum >= 1 && bestChNum <= 4) {
2222 pSapCtx->acs_cfg->ht_sec_ch =
2223 pSapCtx->acs_cfg->pri_ch + 4;
2224 } else if (bestChNum >= 8 && bestChNum <= 13) {
2225 pSapCtx->acs_cfg->ht_sec_ch =
2226 pSapCtx->acs_cfg->pri_ch - 4;
2227 } else if (bestChNum == 14) {
2228 pSapCtx->acs_cfg->ht_sec_ch = 0;
2229 }
2230 pSapCtx->secondary_ch = pSapCtx->acs_cfg->ht_sec_ch;
2231 }
2232 /* Free all the allocated memory */
2233 sap_chan_sel_exit(pSpectInfoParams);
2234
2235 CDF_TRACE(CDF_MODULE_ID_SAP, CDF_TRACE_LEVEL_INFO_HIGH,
2236 "In %s, Running SAP Ch select Completed, Ch=%d", __func__,
2237 bestChNum);
2238 if (bestChNum > 0 && bestChNum <= 252)
2239 return bestChNum;
2240 else
2241 return SAP_CHANNEL_NOT_SELECTED;
2242}