blob: 9e7aabc01787dfed7104efd670ca00f3f6e093e0 [file] [log] [blame]
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001/*
2 * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
3 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21
22/*
23 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
26 */
27
28/*===========================================================================
29
30 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 */
437#if defined(FEATURE_WLAN_STA_AP_MODE_DFS_DISABLE) || \
438 defined(WLAN_FEATURE_MBSSID)
439 for (i = 0; i < NUM_20MHZ_RF_CHANNELS; i++) {
440 if (pSapCtx->dfs_ch_disable == true) {
441 if (CDS_IS_DFS_CH(safe_channels[i].channelNumber)) {
442 safe_channels[i].isSafe = false;
443 CDF_TRACE(CDF_MODULE_ID_SAP,
444 CDF_TRACE_LEVEL_INFO_HIGH,
445 "%s: DFS Ch %d is not safe in"
446 " Concurrent mode",
447 __func__,
448 safe_channels[i].channelNumber);
449 }
450 }
451 }
452#endif
453
454 cnss_get_wlan_unsafe_channel(unsafe_channel_list,
455 &unsafe_channel_count,
456 sizeof(unsafe_channel_list));
457
458 for (i = 0; i < unsafe_channel_count; i++) {
459 for (j = 0; j < NUM_20MHZ_RF_CHANNELS; j++) {
460 if (safe_channels[j].channelNumber ==
461 unsafe_channel_list[i]) {
462 /* Found unsafe channel, update it */
463 safe_channels[j].isSafe = false;
464 CDF_TRACE(CDF_MODULE_ID_SAP,
465 CDF_TRACE_LEVEL_ERROR,
466 FL("CH %d is not safe"),
467 unsafe_channel_list[i]);
468 break;
469 }
470 }
471 }
472
473 return;
474}
475#else
476void sap_update_unsafe_channel_list(ptSapContext pSapCtx)
477{
478 CDF_TRACE(CDF_MODULE_ID_SAP, CDF_TRACE_LEVEL_ERROR,
479 "%s: Not implemented", __func__);
480 return;
481}
482#endif
483
484#endif /* FEATURE_WLAN_CH_AVOID */
485
486/*==========================================================================
487 FUNCTION sap_cleanup_channel_list
488
489 DESCRIPTION
490 Function sap_cleanup_channel_list frees up the memory allocated to the channel list.
491
492 DEPENDENCIES
493 NA.
494
495 PARAMETERS
496
497 IN
498 NULL
499
500 RETURN VALUE
501 NULL
502 ============================================================================*/
503
504void sap_cleanup_channel_list(
505#ifdef WLAN_FEATURE_MBSSID
506 void *p_cds_gctx
507#else
508 void
509#endif
510 ) {
511#ifndef WLAN_FEATURE_MBSSID
512 void *p_cds_gctx = cds_get_global_context();
513#endif
514 ptSapContext pSapCtx;
515
516 CDF_TRACE(CDF_MODULE_ID_SAP, CDF_TRACE_LEVEL_INFO,
517 "Cleaning up the channel list structure");
518
519 if (NULL == p_cds_gctx) {
520 CDF_TRACE(CDF_MODULE_ID_SAP, CDF_TRACE_LEVEL_FATAL,
521 "SAP Global Context is NULL");
522 return;
523 }
524
525 pSapCtx = CDS_GET_SAP_CB(p_cds_gctx);
526 if (NULL == pSapCtx) {
527 CDF_TRACE(CDF_MODULE_ID_SAP, CDF_TRACE_LEVEL_FATAL,
528 "SAP Context is NULL");
529 return;
530 }
531
532 pSapCtx->SapChnlList.numChannel = 0;
533 if (pSapCtx->SapChnlList.channelList) {
534 cdf_mem_free(pSapCtx->SapChnlList.channelList);
535 pSapCtx->SapChnlList.channelList = NULL;
536 }
537
538 pSapCtx->SapAllChnlList.numChannel = 0;
539 if (pSapCtx->SapAllChnlList.channelList) {
540 cdf_mem_free(pSapCtx->SapAllChnlList.channelList);
541 pSapCtx->SapAllChnlList.channelList = NULL;
542 }
543}
544
545/**
546 * sap_select_preferred_channel_from_channel_list() - to calc best cahnnel
547 * @best_chnl: best channel already calculated among all the chanels
548 * @sap_ctx: sap context
549 * @spectinfo_param: Pointer to tSapChSelSpectInfo structure
550 *
551 * This function calculates the best channel among the configured channel list.
552 * If channel list not configured then returns the best channel calculated
553 * among all the channel list.
554 *
555 * Return: uint8_t best channel
556 */
557uint8_t sap_select_preferred_channel_from_channel_list(uint8_t best_chnl,
558 ptSapContext sap_ctx,
559 tSapChSelSpectInfo *spectinfo_param)
560{
561 uint8_t i = 0;
562
563 /*
564 * If Channel List is not Configured don't do anything
565 * Else return the Best Channel from the Channel List
566 */
567 if ((NULL == sap_ctx->acs_cfg->ch_list) ||
568 (NULL == spectinfo_param) ||
569 (0 == sap_ctx->acs_cfg->ch_list_count))
570 return best_chnl;
571
572 if (best_chnl <= 0 || best_chnl > 252)
573 return SAP_CHANNEL_NOT_SELECTED;
574
575 /* Select the best channel from allowed list */
576 for (i = 0; i < sap_ctx->acs_cfg->ch_list_count; i++) {
577 if (sap_ctx->acs_cfg->ch_list[i] == best_chnl) {
578 CDF_TRACE(CDF_MODULE_ID_SAP,
579 CDF_TRACE_LEVEL_INFO_HIGH,
580 "Best channel is: %d",
581 best_chnl);
582 return best_chnl;
583 }
584 }
585
586 return SAP_CHANNEL_NOT_SELECTED;
587}
588
589/*==========================================================================
590 FUNCTION sap_chan_sel_init
591
592 DESCRIPTION
593 Function sap_chan_sel_init allocates the memory, intializes the
594 structures used by the channel selection algorithm
595
596 DEPENDENCIES
597 NA.
598
599 PARAMETERS
600
601 IN
602 halHandle : Pointer to tHalHandle
603 *pSpectInfoParams : Pointer to tSapChSelSpectInfo structure
604 pSapCtx : Pointer to SAP Context
605
606 RETURN VALUE
607 bool: Success or FAIL
608
609 SIDE EFFECTS
610 ============================================================================*/
611bool sap_chan_sel_init(tHalHandle halHandle,
612 tSapChSelSpectInfo *pSpectInfoParams, ptSapContext pSapCtx)
613{
614 tSapSpectChInfo *pSpectCh = NULL;
615 uint8_t *pChans = NULL;
616 uint16_t channelnum = 0;
617 tpAniSirGlobal pMac = PMAC_STRUCT(halHandle);
618 bool chSafe = true;
619#ifdef FEATURE_WLAN_CH_AVOID
620 uint16_t i;
621#endif
622 uint32_t dfs_master_cap_enabled;
623 bool include_dfs_ch = true;
624
625 CDF_TRACE(CDF_MODULE_ID_SAP, CDF_TRACE_LEVEL_INFO_HIGH, "In %s",
626 __func__);
627
628 pSpectInfoParams->numSpectChans =
629 pMac->scan.base_channels.numChannels;
630
631 /* Allocate memory for weight computation of 2.4GHz */
632 pSpectCh =
633 (tSapSpectChInfo *) cdf_mem_malloc((pSpectInfoParams->numSpectChans)
634 * sizeof(*pSpectCh));
635
636 if (pSpectCh == NULL) {
637 CDF_TRACE(CDF_MODULE_ID_SAP, CDF_TRACE_LEVEL_ERROR,
638 "In %s, CDF_MALLOC_ERR", __func__);
639 return eSAP_FALSE;
640 }
641
642 cdf_mem_zero(pSpectCh,
643 (pSpectInfoParams->numSpectChans) * sizeof(*pSpectCh));
644
645 /* Initialize the pointers in the DfsParams to the allocated memory */
646 pSpectInfoParams->pSpectCh = pSpectCh;
647
648 pChans = pMac->scan.base_channels.channelList;
649
650#if defined(FEATURE_WLAN_STA_AP_MODE_DFS_DISABLE) || defined(WLAN_FEATURE_MBSSID)
651 if (pSapCtx->dfs_ch_disable == true)
652 include_dfs_ch = false;
653#endif
654 sme_cfg_get_int(halHandle, WNI_CFG_DFS_MASTER_ENABLED,
655 &dfs_master_cap_enabled);
656 if (dfs_master_cap_enabled == 0)
657 include_dfs_ch = false;
658
659 /* Fill the channel number in the spectrum in the operating freq band */
660 for (channelnum = 0;
661 channelnum < pSpectInfoParams->numSpectChans;
Edhar, Mahesh Kumar4f660672015-10-30 11:53:26 +0530662 channelnum++, pChans++, pSpectCh++) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800663 chSafe = true;
664
665 /* check if the channel is in NOL blacklist */
666 if (sap_dfs_is_channel_in_nol_list(pSapCtx, *pChans,
667 PHY_SINGLE_CHANNEL_CENTERED)) {
668 CDF_TRACE(CDF_MODULE_ID_SAP, CDF_TRACE_LEVEL_INFO_HIGH,
669 "In %s, Ch %d is in NOL list", __func__,
670 *pChans);
671 chSafe = false;
672 continue;
673 }
674
675 if (include_dfs_ch == false) {
676 if (CDS_IS_DFS_CH(*pChans)) {
677 chSafe = false;
678 CDF_TRACE(CDF_MODULE_ID_SAP,
679 CDF_TRACE_LEVEL_INFO_HIGH,
680 "In %s, DFS Ch %d not considered for ACS",
681 __func__, *pChans);
682 continue;
683 }
684 }
685
686#ifdef FEATURE_WLAN_CH_AVOID
687 for (i = 0; i < NUM_20MHZ_RF_CHANNELS; i++) {
688 if ((safe_channels[i].channelNumber == *pChans) &&
689 (false == safe_channels[i].isSafe)) {
690 CDF_TRACE(CDF_MODULE_ID_SAP,
691 CDF_TRACE_LEVEL_INFO_HIGH,
692 "In %s, Ch %d is not safe", __func__,
693 *pChans);
694 chSafe = false;
695 break;
696 }
697 }
698#endif /* FEATURE_WLAN_CH_AVOID */
699
700 /* OFDM rates are not supported on channel 14 */
701 if (*pChans == 14 &&
702 eCSR_DOT11_MODE_11b != pSapCtx->csr_roamProfile.phyMode) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800703 continue;
704 }
705
706 if (true == chSafe) {
707 pSpectCh->chNum = *pChans;
708 pSpectCh->valid = eSAP_TRUE;
709 pSpectCh->rssiAgr = SOFTAP_MIN_RSSI; /* Initialise for all channels */
710 pSpectCh->channelWidth = SOFTAP_HT20_CHANNELWIDTH; /* Initialise 20MHz for all the Channels */
711 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800712 }
713 return eSAP_TRUE;
714}
715
716/*==========================================================================
717 FUNCTION sapweight_rssi_count
718
719 DESCRIPTION
720 Function weightRssiCount calculates the channel weight due to rssi
721 and data count(here number of BSS observed)
722
723 DEPENDENCIES
724 NA.
725
726 PARAMETERS
727
728 IN
729 rssi : Max signal strength receieved from a BSS for the channel
730 count : Number of BSS observed in the channel
731
732 RETURN VALUE
733 uint32_t : Calculated channel weight based on above two
734
735 SIDE EFFECTS
736 ============================================================================*/
737uint32_t sapweight_rssi_count(int8_t rssi, uint16_t count)
738{
739 int32_t rssiWeight = 0;
740 int32_t countWeight = 0;
741 uint32_t rssicountWeight = 0;
742
743 /* Weight from RSSI */
744 rssiWeight = SOFTAP_RSSI_WEIGHT * (rssi - SOFTAP_MIN_RSSI)
745 / (SOFTAP_MAX_RSSI - SOFTAP_MIN_RSSI);
746
747 if (rssiWeight > SOFTAP_RSSI_WEIGHT)
748 rssiWeight = SOFTAP_RSSI_WEIGHT;
749 else if (rssiWeight < 0)
750 rssiWeight = 0;
751
752 /* Weight from data count */
753 countWeight = SOFTAP_COUNT_WEIGHT * (count - SOFTAP_MIN_COUNT)
754 / (SOFTAP_MAX_COUNT - SOFTAP_MIN_COUNT);
755
756 if (countWeight > SOFTAP_COUNT_WEIGHT)
757 countWeight = SOFTAP_COUNT_WEIGHT;
758
759 rssicountWeight = rssiWeight + countWeight;
760
761 CDF_TRACE(CDF_MODULE_ID_SAP, CDF_TRACE_LEVEL_INFO_HIGH,
762 "In %s, rssiWeight=%d, countWeight=%d, rssicountWeight=%d",
763 __func__, rssiWeight, countWeight, rssicountWeight);
764
765 return rssicountWeight;
766}
767
768/**
769 * sap_update_rssi_bsscount() - updates bss count and rssi effect.
770 *
771 * @pSpectCh: Channel Information
772 * @offset: Channel Offset
773 * @sap_24g: Channel is in 2.4G or 5G
774 *
775 * sap_update_rssi_bsscount updates bss count and rssi effect based
776 * on the channel offset.
777 *
778 * Return: None.
779 */
780
781void sap_update_rssi_bsscount(tSapSpectChInfo *pSpectCh, int32_t offset,
782 bool sap_24g)
783{
784 tSapSpectChInfo *pExtSpectCh = NULL;
785 int32_t rssi, rsssi_effect;
786
787 pExtSpectCh = (pSpectCh + offset);
788 if (pExtSpectCh != NULL) {
789 ++pExtSpectCh->bssCount;
790 switch (offset) {
791 case -1:
792 case 1:
793 rsssi_effect = sap_24g ?
794 SAP_24GHZ_FIRST_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY :
795 SAP_SUBBAND1_RSSI_EFFECT_PRIMARY;
796 break;
797 case -2:
798 case 2:
799 rsssi_effect = sap_24g ?
800 SAP_24GHZ_SEC_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY :
801 SAP_SUBBAND2_RSSI_EFFECT_PRIMARY;
802 break;
803 case -3:
804 case 3:
805 rsssi_effect = sap_24g ?
806 SAP_24GHZ_THIRD_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY :
807 SAP_SUBBAND3_RSSI_EFFECT_PRIMARY;
808 break;
809 case -4:
810 case 4:
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -0700811 rsssi_effect = sap_24g ?
812 SAP_24GHZ_FOURTH_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY :
813 SAP_SUBBAND4_RSSI_EFFECT_PRIMARY;
814 break;
815 case -5:
816 case 5:
817 rsssi_effect = SAP_SUBBAND5_RSSI_EFFECT_PRIMARY;
818 break;
819 case -6:
820 case 6:
821 rsssi_effect = SAP_SUBBAND6_RSSI_EFFECT_PRIMARY;
822 break;
823 case -7:
824 case 7:
825 rsssi_effect = SAP_SUBBAND7_RSSI_EFFECT_PRIMARY;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800826 break;
827 default:
828 rsssi_effect = 0;
829 break;
830 }
831
832 rssi = pSpectCh->rssiAgr + rsssi_effect;
833 if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi))
834 pExtSpectCh->rssiAgr = rssi;
835 if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI)
836 pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI;
837 }
838}
839
840/**
841 * sap_upd_chan_spec_params() - sap_upd_chan_spec_params
842 * updates channel parameters obtained from Beacon
843 * @pBeaconStruct Beacon strucutre populated by parse_beacon function
844 * @channelWidth Channel width
845 * @secondaryChannelOffset Secondary Channel Offset
846 * @vhtSupport If channel supports VHT
847 * @centerFreq Central frequency for the given channel.
848 *
849 * sap_upd_chan_spec_params updates the spectrum channels based on the
850 * pBeaconStruct obtained from Beacon IE
851 *
852 * Return: NA.
853 */
854
855void sap_upd_chan_spec_params(tSirProbeRespBeacon *pBeaconStruct,
856 uint16_t *channelWidth,
857 uint16_t *secondaryChannelOffset,
858 uint16_t *vhtSupport,
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -0700859 uint16_t *centerFreq,
860 uint16_t *centerFreq_2)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800861{
862 if (NULL == pBeaconStruct) {
863 CDF_TRACE(CDF_MODULE_ID_SAP, CDF_TRACE_LEVEL_ERROR,
864 FL("pBeaconStruct is NULL"));
865 return;
866 }
867
868 if (pBeaconStruct->HTCaps.present && pBeaconStruct->HTInfo.present) {
869 *channelWidth = pBeaconStruct->HTCaps.supportedChannelWidthSet;
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -0700870 *secondaryChannelOffset =
871 pBeaconStruct->HTInfo.secondaryChannelOffset;
872 if (!pBeaconStruct->VHTOperation.present)
873 return;
874 *vhtSupport = pBeaconStruct->VHTOperation.present;
875 if (pBeaconStruct->VHTOperation.chanWidth) {
876 *centerFreq =
877 pBeaconStruct->VHTOperation.chanCenterFreqSeg1;
878 *centerFreq_2 =
879 pBeaconStruct->VHTOperation.chanCenterFreqSeg2;
880 /*
881 * LHS follows tSirMacHTChannelWidth, while RHS follows
882 * WNI_CFG_VHT_CHANNEL_WIDTH_X format hence following
883 * adjustment
884 */
885 *channelWidth =
886 pBeaconStruct->VHTOperation.chanWidth + 1;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800887
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800888 }
889 }
890}
891
892/**
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -0700893 * sap_update_rssi_bsscount_vht_5G() - updates bss count and rssi effect.
894 *
895 * @pSpectCh: Channel Information
896 * @offset: Channel Offset
897 * @num_ch: no.of channels
898 *
899 * sap_update_rssi_bsscount_vht_5G updates bss count and rssi effect based
900 * on the channel offset.
901 *
902 * Return: None.
903 */
904
905void sap_update_rssi_bsscount_vht_5G(tSapSpectChInfo *spect_ch, int32_t offset,
906 uint16_t num_ch)
907{
908 int32_t ch_offset;
909 uint16_t i, cnt;
910
911 if (!offset)
912 return;
913 if (offset > 0)
914 cnt = num_ch;
915 else
916 cnt = num_ch + 1;
917 for (i = 0; i < cnt; i++) {
918 ch_offset = offset + i;
919 if (ch_offset == 0)
920 continue;
921 sap_update_rssi_bsscount(spect_ch, ch_offset, false);
922 }
923}
924/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800925 * sap_interference_rssi_count_5G() - sap_interference_rssi_count
926 * considers the Adjacent channel rssi and
927 * data count(here number of BSS observed)
928 * @spect_ch: Channel Information
929 * @chan_width: Channel width parsed from beacon IE
930 * @sec_chan_offset: Secondary Channel Offset
931 * @center_freq: Central frequency for the given channel.
932 * @channel_id: channel_id
933 *
934 * sap_interference_rssi_count_5G considers the Adjacent channel rssi
935 * and data count(here number of BSS observed)
936 *
937 * Return: NA.
938 */
939
940void sap_interference_rssi_count_5G(tSapSpectChInfo *spect_ch,
941 uint16_t chan_width,
942 uint16_t sec_chan_offset,
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -0700943 uint16_t center_freq,
944 uint16_t center_freq_2,
945 uint8_t channel_id)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800946{
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -0700947 uint16_t num_ch;
948 int32_t offset = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800949 if (NULL == spect_ch) {
950 CDF_TRACE(CDF_MODULE_ID_SAP, CDF_TRACE_LEVEL_ERROR,
951 FL("spect_ch is NULL"));
952 return;
953 }
954
955 /* Updating the received ChannelWidth */
956 if (spect_ch->channelWidth != chan_width)
957 spect_ch->channelWidth = chan_width;
958 /* If received ChannelWidth is other than HT20,
959 * we need to update the extension channel Params as well
960 * chan_width == 0, HT20
961 * chan_width == 1, HT40
962 * chan_width == 2, VHT80
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -0700963 * chan_width == 3, VHT160
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800964 */
965
966 switch (spect_ch->channelWidth) {
967 case eHT_CHANNEL_WIDTH_40MHZ: /* HT40 */
968 switch (sec_chan_offset) {
969 /* Above the Primary Channel */
970 case PHY_DOUBLE_CHANNEL_LOW_PRIMARY:
971 sap_update_rssi_bsscount(spect_ch, 1, false);
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -0700972 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800973
974 /* Below the Primary channel */
975 case PHY_DOUBLE_CHANNEL_HIGH_PRIMARY:
976 sap_update_rssi_bsscount(spect_ch, -1, false);
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -0700977 return;
978 }
979 return;
980 case eHT_CHANNEL_WIDTH_80MHZ: /* VHT80 */
981 num_ch = 3;
982 if ((center_freq - channel_id) == 6) {
983 offset = 1;
984 } else if ((center_freq - channel_id) == 2) {
985 offset = -1;
986 } else if ((center_freq - channel_id) == -2) {
987 offset = -2;
988 } else if ((center_freq - channel_id) == -6) {
989 offset = -3;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800990 }
991 break;
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -0700992 case eHT_CHANNEL_WIDTH_160MHZ: /* VHT160 */
993 num_ch = 7;
994 if ((center_freq - channel_id) == 14)
995 offset = 1;
996 else if ((center_freq - channel_id) == 10)
997 offset = -1;
998 else if ((center_freq - channel_id) == 6)
999 offset = -2;
1000 else if ((center_freq - channel_id) == 2)
1001 offset = -3;
1002 else if ((center_freq - channel_id) == -2)
1003 offset = -4;
1004 else if ((center_freq - channel_id) == -6)
1005 offset = -5;
1006 else if ((center_freq - channel_id) == -10)
1007 offset = -6;
1008 else if ((center_freq - channel_id) == -14)
1009 offset = -7;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001010 break;
1011 default:
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001012 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001013 }
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001014 sap_update_rssi_bsscount_vht_5G(spect_ch, offset, num_ch);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001015}
1016
1017/**
1018 * sap_interference_rssi_count() - sap_interference_rssi_count
1019 * considers the Adjacent channel rssi
1020 * and data count(here number of BSS observed)
1021 * @spect_ch Channel Information
1022 *
1023 * sap_interference_rssi_count considers the Adjacent channel rssi
1024 * and data count(here number of BSS observed)
1025 *
1026 * Return: None.
1027 */
1028
1029void sap_interference_rssi_count(tSapSpectChInfo *spect_ch)
1030{
1031 if (NULL == spect_ch) {
1032 CDF_TRACE(CDF_MODULE_ID_SAP, CDF_TRACE_LEVEL_ERROR,
1033 "%s: spect_ch is NULL", __func__);
1034 return;
1035 }
1036
1037 switch (spect_ch->chNum) {
1038 case CHANNEL_1:
1039 sap_update_rssi_bsscount(spect_ch, 1, true);
1040 sap_update_rssi_bsscount(spect_ch, 2, true);
1041 sap_update_rssi_bsscount(spect_ch, 3, true);
1042 sap_update_rssi_bsscount(spect_ch, 4, true);
1043 break;
1044
1045 case CHANNEL_2:
1046 sap_update_rssi_bsscount(spect_ch, -1, true);
1047 sap_update_rssi_bsscount(spect_ch, 1, true);
1048 sap_update_rssi_bsscount(spect_ch, 2, true);
1049 sap_update_rssi_bsscount(spect_ch, 3, true);
1050 sap_update_rssi_bsscount(spect_ch, 4, true);
1051 break;
1052 case CHANNEL_3:
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 case CHANNEL_4:
1061 sap_update_rssi_bsscount(spect_ch, -3, true);
1062 sap_update_rssi_bsscount(spect_ch, -2, true);
1063 sap_update_rssi_bsscount(spect_ch, -1, true);
1064 sap_update_rssi_bsscount(spect_ch, 1, true);
1065 sap_update_rssi_bsscount(spect_ch, 2, true);
1066 sap_update_rssi_bsscount(spect_ch, 3, true);
1067 sap_update_rssi_bsscount(spect_ch, 4, true);
1068 break;
1069
1070 case CHANNEL_5:
1071 case CHANNEL_6:
1072 case CHANNEL_7:
1073 case CHANNEL_8:
1074 case CHANNEL_9:
1075 case CHANNEL_10:
1076 sap_update_rssi_bsscount(spect_ch, -4, true);
1077 sap_update_rssi_bsscount(spect_ch, -3, true);
1078 sap_update_rssi_bsscount(spect_ch, -2, true);
1079 sap_update_rssi_bsscount(spect_ch, -1, true);
1080 sap_update_rssi_bsscount(spect_ch, 1, true);
1081 sap_update_rssi_bsscount(spect_ch, 2, true);
1082 sap_update_rssi_bsscount(spect_ch, 3, true);
1083 sap_update_rssi_bsscount(spect_ch, 4, true);
1084 break;
1085
1086 case CHANNEL_11:
1087 sap_update_rssi_bsscount(spect_ch, -4, true);
1088 sap_update_rssi_bsscount(spect_ch, -3, true);
1089 sap_update_rssi_bsscount(spect_ch, -2, true);
1090 sap_update_rssi_bsscount(spect_ch, -1, true);
1091 sap_update_rssi_bsscount(spect_ch, 1, true);
1092 sap_update_rssi_bsscount(spect_ch, 2, true);
1093 sap_update_rssi_bsscount(spect_ch, 3, true);
1094 break;
1095
1096 case CHANNEL_12:
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 sap_update_rssi_bsscount(spect_ch, 2, true);
1103 break;
1104
1105 case CHANNEL_13:
1106 sap_update_rssi_bsscount(spect_ch, -4, true);
1107 sap_update_rssi_bsscount(spect_ch, -3, true);
1108 sap_update_rssi_bsscount(spect_ch, -2, true);
1109 sap_update_rssi_bsscount(spect_ch, -1, true);
1110 sap_update_rssi_bsscount(spect_ch, 1, true);
1111 break;
1112
1113 case CHANNEL_14:
1114 sap_update_rssi_bsscount(spect_ch, -4, true);
1115 sap_update_rssi_bsscount(spect_ch, -3, true);
1116 sap_update_rssi_bsscount(spect_ch, -2, true);
1117 sap_update_rssi_bsscount(spect_ch, -1, true);
1118 break;
1119
1120 default:
1121 break;
1122 }
1123}
1124
1125/*==========================================================================
1126 Function ch_in_pcl
1127
1128 Description
1129 Check if a channel is in the preferred channel list
1130
1131 Parameters
1132 sap_ctx SAP context pointer
1133 channel input channel number
1134
1135 Return Value
1136 true: channel is in PCL
1137 false: channel is not in PCL
1138 ==========================================================================*/
1139bool ch_in_pcl(ptSapContext sap_ctx, uint8_t channel)
1140{
1141 uint32_t i;
1142
1143 for (i = 0; i < sap_ctx->acs_cfg->pcl_ch_count; i++) {
1144 if (channel == sap_ctx->acs_cfg->pcl_channels[i])
1145 return true;
1146 }
1147
1148 return false;
1149}
1150
1151/*==========================================================================
1152 FUNCTION sap_compute_spect_weight
1153
1154 DESCRIPTION
1155 Main function for computing the weight of each channel in the
1156 spectrum based on the RSSI value of the BSSes on the channel
1157 and number of BSS
1158
1159 DEPENDENCIES
1160 NA.
1161
1162 PARAMETERS
1163
1164 IN
1165 pSpectInfoParams : Pointer to the tSpectInfoParams structure
1166 halHandle : Pointer to HAL handle
1167 pResult : Pointer to tScanResultHandle
1168
1169 RETURN VALUE
1170 void : NULL
1171
1172 SIDE EFFECTS
1173 ============================================================================*/
1174void sap_compute_spect_weight(tSapChSelSpectInfo *pSpectInfoParams,
1175 tHalHandle halHandle, tScanResultHandle pResult,
1176 ptSapContext sap_ctx)
1177{
1178 int8_t rssi = 0;
1179 uint8_t chn_num = 0;
1180 uint8_t channel_id = 0;
1181
1182 tCsrScanResultInfo *pScanResult;
1183 tSapSpectChInfo *pSpectCh = pSpectInfoParams->pSpectCh;
1184 uint32_t operatingBand;
1185 uint16_t channelWidth;
1186 uint16_t secondaryChannelOffset;
1187 uint16_t centerFreq;
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001188 uint16_t centerFreq_2 = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001189 uint16_t vhtSupport;
1190 uint32_t ieLen = 0;
1191 tSirProbeRespBeacon *pBeaconStruct;
1192 tpAniSirGlobal pMac = (tpAniSirGlobal) halHandle;
1193
1194 pBeaconStruct = cdf_mem_malloc(sizeof(tSirProbeRespBeacon));
1195 if (NULL == pBeaconStruct) {
1196 CDF_TRACE(CDF_MODULE_ID_SAP, CDF_TRACE_LEVEL_INFO_HIGH,
1197 "Unable to allocate memory in sap_compute_spect_weight\n");
1198 return;
1199 }
1200 CDF_TRACE(CDF_MODULE_ID_SAP, CDF_TRACE_LEVEL_INFO_HIGH,
1201 "In %s, Computing spectral weight", __func__);
1202
1203 /**
1204 * Soft AP specific channel weight calculation using DFS formula
1205 */
1206 SET_ACS_BAND(operatingBand, sap_ctx);
1207
1208 pScanResult = sme_scan_result_get_first(halHandle, pResult);
1209
1210 while (pScanResult) {
1211 pSpectCh = pSpectInfoParams->pSpectCh;
1212 /* Defining the default values, so that any value will hold the default values */
1213 channelWidth = eHT_CHANNEL_WIDTH_20MHZ;
1214 secondaryChannelOffset = PHY_SINGLE_CHANNEL_CENTERED;
1215 vhtSupport = 0;
1216 centerFreq = 0;
1217
1218 if (pScanResult->BssDescriptor.ieFields != NULL) {
1219 ieLen =
1220 (pScanResult->BssDescriptor.length +
1221 sizeof(uint16_t) + sizeof(uint32_t) -
1222 sizeof(tSirBssDescription));
1223 cdf_mem_set((uint8_t *) pBeaconStruct,
1224 sizeof(tSirProbeRespBeacon), 0);
1225
1226 if ((sir_parse_beacon_ie
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001227 (pMac, pBeaconStruct, (uint8_t *)
1228 (pScanResult->BssDescriptor.ieFields),
1229 ieLen)) == eSIR_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001230 sap_upd_chan_spec_params(pBeaconStruct,
1231 &channelWidth, &secondaryChannelOffset,
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001232 &vhtSupport, &centerFreq,
1233 &centerFreq_2);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001234 }
1235 }
1236 /* Processing for each tCsrScanResultInfo in the tCsrScanResult DLink list */
1237 for (chn_num = 0; chn_num < pSpectInfoParams->numSpectChans;
1238 chn_num++) {
1239
1240 /*
1241 * if the Beacon has channel ID, use it other wise we will
1242 * rely on the channelIdSelf
1243 */
1244 if (pScanResult->BssDescriptor.channelId == 0)
1245 channel_id =
1246 pScanResult->BssDescriptor.channelIdSelf;
1247 else
1248 channel_id =
1249 pScanResult->BssDescriptor.channelId;
1250
1251 if (pSpectCh && (channel_id == pSpectCh->chNum)) {
1252 if (pSpectCh->rssiAgr <
1253 pScanResult->BssDescriptor.rssi)
1254 pSpectCh->rssiAgr =
1255 pScanResult->BssDescriptor.rssi;
1256
1257 ++pSpectCh->bssCount; /* Increment the count of BSS */
1258
1259 /*
1260 * Connsidering the Extension Channel
1261 * only in a channels
1262 */
1263 switch (operatingBand) {
1264 case eCSR_DOT11_MODE_11a:
1265 sap_interference_rssi_count_5G(
1266 pSpectCh, channelWidth,
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001267 secondaryChannelOffset,
1268 centerFreq,
1269 centerFreq_2,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001270 channel_id);
1271 break;
1272
1273 case eCSR_DOT11_MODE_11g:
1274 sap_interference_rssi_count(pSpectCh);
1275 break;
1276
1277 case eCSR_DOT11_MODE_abg:
1278 sap_interference_rssi_count_5G(
1279 pSpectCh, channelWidth,
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001280 secondaryChannelOffset,
1281 centerFreq,
1282 centerFreq_2,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001283 channel_id);
1284 sap_interference_rssi_count(pSpectCh);
1285 break;
1286 }
1287
1288 CDF_TRACE(CDF_MODULE_ID_SAP,
1289 CDF_TRACE_LEVEL_INFO_HIGH,
1290 "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",
1291 __func__,
1292 pScanResult->BssDescriptor.
1293 channelIdSelf,
1294 pScanResult->BssDescriptor.channelId,
1295 pScanResult->BssDescriptor.rssi,
1296 pSpectCh->bssCount, pScanResult,
1297 pSpectCh->channelWidth,
1298 secondaryChannelOffset, centerFreq);
1299 pSpectCh++;
1300 break;
1301 } else {
1302 pSpectCh++;
1303 }
1304 }
1305
1306 pScanResult = sme_scan_result_get_next(halHandle, pResult);
1307 }
1308
1309 /* Calculate the weights for all channels in the spectrum pSpectCh */
1310 pSpectCh = pSpectInfoParams->pSpectCh;
1311
1312 CDF_TRACE(CDF_MODULE_ID_SAP, CDF_TRACE_LEVEL_INFO_HIGH,
1313 "In %s, Spectrum Channels Weight", __func__);
1314
1315 for (chn_num = 0; chn_num < (pSpectInfoParams->numSpectChans);
1316 chn_num++) {
1317
1318 /*
1319 rssi : Maximum received signal strength among all BSS on that channel
1320 bssCount : Number of BSS on that channel
1321 */
1322
1323 rssi = (int8_t) pSpectCh->rssiAgr;
1324 if (ch_in_pcl(sap_ctx, chn_num))
1325 rssi -= PCL_RSSI_DISCOUNT;
1326
1327 pSpectCh->weight =
1328 SAPDFS_NORMALISE_1000 * sapweight_rssi_count(rssi,
1329 pSpectCh->
1330 bssCount);
1331 pSpectCh->weight_copy = pSpectCh->weight;
1332
1333 /* ------ Debug Info ------ */
1334 CDF_TRACE(CDF_MODULE_ID_SAP, CDF_TRACE_LEVEL_INFO_HIGH,
1335 "In %s, Chan=%d Weight= %d rssiAgr=%d bssCount=%d",
1336 __func__, pSpectCh->chNum, pSpectCh->weight,
1337 pSpectCh->rssiAgr, pSpectCh->bssCount);
1338 /* ------ Debug Info ------ */
1339 pSpectCh++;
1340 }
1341 cdf_mem_free(pBeaconStruct);
1342}
1343
1344/*==========================================================================
1345 FUNCTION sap_chan_sel_exit
1346
1347 DESCRIPTION
1348 Exit function for free out the allocated memory, to be called
1349 at the end of the dfsSelectChannel function
1350
1351 DEPENDENCIES
1352 NA.
1353
1354 PARAMETERS
1355
1356 IN
1357 pSpectInfoParams : Pointer to the tSapChSelSpectInfo structure
1358
1359 RETURN VALUE
1360 void : NULL
1361
1362 SIDE EFFECTS
1363 ============================================================================*/
1364void sap_chan_sel_exit(tSapChSelSpectInfo *pSpectInfoParams)
1365{
1366 /* Free all the allocated memory */
1367 cdf_mem_free(pSpectInfoParams->pSpectCh);
1368}
1369
1370/*==========================================================================
1371 FUNCTION sap_sort_chl_weight
1372
1373 DESCRIPTION
1374 Funtion to sort the channels with the least weight first for 20MHz channels
1375
1376 DEPENDENCIES
1377 NA.
1378
1379 PARAMETERS
1380
1381 IN
1382 pSpectInfoParams : Pointer to the tSapChSelSpectInfo structure
1383
1384 RETURN VALUE
1385 void : NULL
1386
1387 SIDE EFFECTS
1388 ============================================================================*/
1389void sap_sort_chl_weight(tSapChSelSpectInfo *pSpectInfoParams)
1390{
1391 tSapSpectChInfo temp;
1392
1393 tSapSpectChInfo *pSpectCh = NULL;
1394 uint32_t i = 0, j = 0, minWeightIndex = 0;
1395
1396 pSpectCh = pSpectInfoParams->pSpectCh;
1397 for (i = 0; i < pSpectInfoParams->numSpectChans; i++) {
1398 minWeightIndex = i;
1399 for (j = i + 1; j < pSpectInfoParams->numSpectChans; j++) {
1400 if (pSpectCh[j].weight <
1401 pSpectCh[minWeightIndex].weight) {
1402 minWeightIndex = j;
1403 }
1404 }
1405 if (minWeightIndex != i) {
1406 cdf_mem_copy(&temp, &pSpectCh[minWeightIndex],
1407 sizeof(*pSpectCh));
1408 cdf_mem_copy(&pSpectCh[minWeightIndex], &pSpectCh[i],
1409 sizeof(*pSpectCh));
1410 cdf_mem_copy(&pSpectCh[i], &temp, sizeof(*pSpectCh));
1411 }
1412 }
1413}
1414
1415/**
1416 * sap_sort_chl_weight_ht80() - to sort the channels with the least weight
1417 * @pSpectInfoParams: Pointer to the tSapChSelSpectInfo structure
1418 *
1419 * Funtion to sort the channels with the least weight first for HT80 channels
1420 *
1421 * Return: none
1422 */
1423void sap_sort_chl_weight_ht80(tSapChSelSpectInfo *pSpectInfoParams)
1424{
1425 uint8_t i, j, n;
1426 tSapSpectChInfo *pSpectInfo;
1427 uint8_t minIdx;
1428
1429 pSpectInfo = pSpectInfoParams->pSpectCh;
1430 /* for each HT80 channel, calculate the combined weight of the
1431 four 20MHz weight */
1432 for (i = 0; i < ARRAY_SIZE(acs_ht80_channels); i++) {
1433 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
1434 if (pSpectInfo[j].chNum ==
1435 acs_ht80_channels[i].chStartNum)
1436 break;
1437 }
1438 if (j == pSpectInfoParams->numSpectChans)
1439 continue;
1440
1441 if (!(((pSpectInfo[j].chNum + 4) == pSpectInfo[j + 1].chNum) &&
1442 ((pSpectInfo[j].chNum + 8) ==
1443 pSpectInfo[j + 2].chNum) &&
1444 ((pSpectInfo[j].chNum + 12) ==
1445 pSpectInfo[j + 3].chNum))) {
1446 /*
1447 * some channels does not exist in pSectInfo array,
1448 * skip this channel and those in the same HT80 width
1449 */
1450 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 4;
1451 if ((pSpectInfo[j].chNum + 4) ==
1452 pSpectInfo[j + 1].chNum)
1453 pSpectInfo[j + 1].weight =
1454 SAP_ACS_WEIGHT_MAX * 4;
1455 if ((pSpectInfo[j].chNum + 8) ==
1456 pSpectInfo[j + 2].chNum)
1457 pSpectInfo[j + 2].weight =
1458 SAP_ACS_WEIGHT_MAX * 4;
1459 if ((pSpectInfo[j].chNum + 12) ==
1460 pSpectInfo[j + 3].chNum)
1461 pSpectInfo[j + 3].weight =
1462 SAP_ACS_WEIGHT_MAX * 4;
1463 continue;
1464 }
1465 /*found the channel, add the 4 adjacent channels' weight */
1466 acs_ht80_channels[i].weight = pSpectInfo[j].weight +
1467 pSpectInfo[j + 1].weight + pSpectInfo[j + 2].weight +
1468 pSpectInfo[j + 3].weight;
1469 /* find best channel among 4 channels as the primary channel */
1470 if ((pSpectInfo[j].weight + pSpectInfo[j + 1].weight) <
1471 (pSpectInfo[j + 2].weight + pSpectInfo[j + 3].weight)) {
1472 /* lower 2 channels are better choice */
1473 if (pSpectInfo[j].weight < pSpectInfo[j + 1].weight)
1474 minIdx = 0;
1475 else
1476 minIdx = 1;
1477 } else if (pSpectInfo[j + 2].weight <=
1478 pSpectInfo[j + 3].weight) {
1479 /* upper 2 channels are better choice */
1480 minIdx = 2;
1481 } else {
1482 minIdx = 3;
1483 }
1484
1485 /*
1486 * set all 4 channels to max value first, then reset the
1487 * best channel as the selected primary channel, update its
1488 * weightage with the combined weight value
1489 */
1490 for (n = 0; n < 4; n++)
1491 pSpectInfo[j + n].weight = SAP_ACS_WEIGHT_MAX * 4;
1492
1493 pSpectInfo[j + minIdx].weight = acs_ht80_channels[i].weight;
1494 }
1495
1496 pSpectInfo = pSpectInfoParams->pSpectCh;
1497 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
1498 if (CHANNEL_165 == pSpectInfo[j].chNum) {
1499 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 4;
1500 break;
1501 }
1502 }
1503
1504 pSpectInfo = pSpectInfoParams->pSpectCh;
1505 for (j = 0; j < (pSpectInfoParams->numSpectChans); j++) {
1506 CDF_TRACE(CDF_MODULE_ID_SAP, CDF_TRACE_LEVEL_INFO_HIGH,
1507 FL("Channel=%d Weight= %d rssi=%d bssCount=%d"),
1508 pSpectInfo->chNum, pSpectInfo->weight,
1509 pSpectInfo->rssiAgr, pSpectInfo->bssCount);
1510 pSpectInfo++;
1511 }
1512}
1513
1514/**
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001515 * sap_sort_chl_weight_vht160() - to sort the channels with the least weight
1516 * @pSpectInfoParams: Pointer to the tSapChSelSpectInfo structure
1517 *
1518 * Funtion to sort the channels with the least weight first for VHT160 channels
1519 *
1520 * Return: none
1521 */
1522void sap_sort_chl_weight_vht160(tSapChSelSpectInfo *pSpectInfoParams)
1523{
1524 uint8_t i, j, n, idx;
1525 tSapSpectChInfo *pSpectInfo;
1526 uint8_t minIdx;
1527
1528 pSpectInfo = pSpectInfoParams->pSpectCh;
1529 /* for each VHT160 channel, calculate the combined weight of the
1530 8 20MHz weight */
1531 for (i = 0; i < ARRAY_SIZE(acs_vht160_channels); i++) {
1532 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
1533 if (pSpectInfo[j].chNum ==
1534 acs_vht160_channels[i].chStartNum)
1535 break;
1536 }
1537 if (j == pSpectInfoParams->numSpectChans)
1538 continue;
1539
1540 if (!(((pSpectInfo[j].chNum + 4) == pSpectInfo[j + 1].chNum) &&
1541 ((pSpectInfo[j].chNum + 8) ==
1542 pSpectInfo[j + 2].chNum) &&
1543 ((pSpectInfo[j].chNum + 12) ==
1544 pSpectInfo[j + 3].chNum) &&
1545 ((pSpectInfo[j].chNum + 16) ==
1546 pSpectInfo[j + 4].chNum) &&
1547 ((pSpectInfo[j].chNum + 20) ==
1548 pSpectInfo[j + 5].chNum) &&
1549 ((pSpectInfo[j].chNum + 24) ==
1550 pSpectInfo[j + 6].chNum) &&
1551 ((pSpectInfo[j].chNum + 28) ==
1552 pSpectInfo[j + 7].chNum))) {
1553 /*
1554 * some channels does not exist in pSectInfo array,
1555 * skip this channel and those in the same VHT160 width
1556 */
1557 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 8;
1558 if ((pSpectInfo[j].chNum + 4) ==
1559 pSpectInfo[j + 1].chNum)
1560 pSpectInfo[j + 1].weight =
1561 SAP_ACS_WEIGHT_MAX * 8;
1562 if ((pSpectInfo[j].chNum + 8) ==
1563 pSpectInfo[j + 2].chNum)
1564 pSpectInfo[j + 2].weight =
1565 SAP_ACS_WEIGHT_MAX * 8;
1566 if ((pSpectInfo[j].chNum + 12) ==
1567 pSpectInfo[j + 3].chNum)
1568 pSpectInfo[j + 3].weight =
1569 SAP_ACS_WEIGHT_MAX * 8;
1570 if ((pSpectInfo[j].chNum + 16) ==
1571 pSpectInfo[j + 4].chNum)
1572 pSpectInfo[j + 4].weight =
1573 SAP_ACS_WEIGHT_MAX * 8;
1574 if ((pSpectInfo[j].chNum + 20) ==
1575 pSpectInfo[j + 5].chNum)
1576 pSpectInfo[j + 5].weight =
1577 SAP_ACS_WEIGHT_MAX * 8;
1578 if ((pSpectInfo[j].chNum + 24) ==
1579 pSpectInfo[j + 6].chNum)
1580 pSpectInfo[j + 6].weight =
1581 SAP_ACS_WEIGHT_MAX * 8;
1582 if ((pSpectInfo[j].chNum + 28) ==
1583 pSpectInfo[j + 7].chNum)
1584 pSpectInfo[j + 7].weight =
1585 SAP_ACS_WEIGHT_MAX * 8;
1586 continue;
1587 }
1588 /*found the channel, add the 7 adjacent channels' weight */
1589 acs_vht160_channels[i].weight = pSpectInfo[j].weight +
1590 pSpectInfo[j + 1].weight + pSpectInfo[j + 2].weight +
1591 pSpectInfo[j + 3].weight + pSpectInfo[j + 4].weight +
1592 pSpectInfo[j + 5].weight + pSpectInfo[j + 6].weight +
1593 pSpectInfo[j + 7].weight;
1594
1595 /* find best channel among 8 channels as the primary channel */
1596 if ((pSpectInfo[j].weight + pSpectInfo[j + 1].weight +
1597 pSpectInfo[j + 2].weight + pSpectInfo[j + 3].weight) >
1598 (pSpectInfo[j + 4].weight + pSpectInfo[j + 5].weight +
1599 pSpectInfo[j + 6].weight + pSpectInfo[j + 7].weight))
1600 idx = 4;
1601 else
1602 idx = 0;
1603 /* find best channel among 4 channels as the primary channel */
1604 if ((pSpectInfo[j + idx].weight +
1605 pSpectInfo[j + idx + 1].weight) <
1606 (pSpectInfo[j + idx + 2].weight +
1607 pSpectInfo[j + idx + 3].weight)) {
1608 /* lower 2 channels are better choice */
1609 if (pSpectInfo[j + idx].weight <
1610 pSpectInfo[j + idx + 1].weight)
1611 minIdx = 0 + idx;
1612 else
1613 minIdx = 1 + idx;
1614 } else if (pSpectInfo[j + idx + 2].weight <=
1615 pSpectInfo[j + idx + 3].weight) {
1616 /* upper 2 channels are better choice */
1617 minIdx = 2 + idx;
1618 } else {
1619 minIdx = 3 + idx;
1620 }
1621
1622 /*
1623 * set all 8 channels to max value first, then reset the
1624 * best channel as the selected primary channel, update its
1625 * weightage with the combined weight value
1626 */
1627 for (n = 0; n < 8; n++)
1628 pSpectInfo[j + n].weight = SAP_ACS_WEIGHT_MAX * 8;
1629
1630 pSpectInfo[j + minIdx].weight = acs_vht160_channels[i].weight;
1631 }
1632
1633 pSpectInfo = pSpectInfoParams->pSpectCh;
1634 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
1635 if (CHANNEL_165 == pSpectInfo[j].chNum) {
1636 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 8;
1637 break;
1638 }
1639 }
1640
1641 pSpectInfo = pSpectInfoParams->pSpectCh;
1642 for (j = 0; j < (pSpectInfoParams->numSpectChans); j++) {
1643 CDF_TRACE(CDF_MODULE_ID_SAP, CDF_TRACE_LEVEL_INFO_HIGH,
1644 FL("Channel=%d Weight= %d rssi=%d bssCount=%d"),
1645 pSpectInfo->chNum, pSpectInfo->weight,
1646 pSpectInfo->rssiAgr, pSpectInfo->bssCount);
1647 pSpectInfo++;
1648 }
1649}
1650
1651/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001652 * sap_sort_chl_weight_ht40_24_g() - to sort channel with the least weight
1653 * @pSpectInfoParams: Pointer to the tSapChSelSpectInfo structure
1654 *
1655 * Funtion to sort the channels with the least weight first for HT40 channels
1656 *
1657 * Return: none
1658 */
1659void sap_sort_chl_weight_ht40_24_g(tSapChSelSpectInfo *pSpectInfoParams)
1660{
1661 uint8_t i, j;
1662 tSapSpectChInfo *pSpectInfo;
1663 uint32_t tmpWeight1, tmpWeight2;
1664
1665 pSpectInfo = pSpectInfoParams->pSpectCh;
1666 /*
1667 * for each HT40 channel, calculate the combined weight of the
1668 * two 20MHz weight
1669 */
1670 for (i = 0; i < ARRAY_SIZE(acs_ht40_channels24_g); i++) {
1671 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
1672 if (pSpectInfo[j].chNum ==
1673 acs_ht40_channels24_g[i].chStartNum)
1674 break;
1675 }
1676 if (j == pSpectInfoParams->numSpectChans)
1677 continue;
1678
1679 if (!((pSpectInfo[j].chNum + 4) == pSpectInfo[j + 4].chNum)) {
1680 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2;
1681 continue;
1682 }
1683 /*
1684 * check if there is another channel combination possiblity
1685 * e.g., {1, 5} & {5, 9}
1686 */
1687 if ((pSpectInfo[j + 4].chNum + 4) == pSpectInfo[j + 8].chNum) {
1688 /* need to compare two channel pairs */
1689 tmpWeight1 = pSpectInfo[j].weight +
1690 pSpectInfo[j + 4].weight;
1691 tmpWeight2 = pSpectInfo[j + 4].weight +
1692 pSpectInfo[j + 8].weight;
1693 if (tmpWeight1 <= tmpWeight2) {
1694 if (pSpectInfo[j].weight <=
1695 pSpectInfo[j + 4].weight) {
1696 pSpectInfo[j].weight =
1697 tmpWeight1;
1698 pSpectInfo[j + 4].weight =
1699 SAP_ACS_WEIGHT_MAX * 2;
1700 pSpectInfo[j + 8].weight =
1701 SAP_ACS_WEIGHT_MAX * 2;
1702 } else {
1703 pSpectInfo[j + 4].weight =
1704 tmpWeight1;
1705 /* for secondary channel selection */
1706 pSpectInfo[j].weight =
1707 SAP_ACS_WEIGHT_MAX * 2
1708 - 1;
1709 pSpectInfo[j + 8].weight =
1710 SAP_ACS_WEIGHT_MAX * 2;
1711 }
1712 } else {
1713 if (pSpectInfo[j + 4].weight <=
1714 pSpectInfo[j + 8].weight) {
1715 pSpectInfo[j + 4].weight =
1716 tmpWeight2;
1717 pSpectInfo[j].weight =
1718 SAP_ACS_WEIGHT_MAX * 2;
1719 /* for secondary channel selection */
1720 pSpectInfo[j + 8].weight =
1721 SAP_ACS_WEIGHT_MAX * 2
1722 - 1;
1723 } else {
1724 pSpectInfo[j + 8].weight =
1725 tmpWeight2;
1726 pSpectInfo[j].weight =
1727 SAP_ACS_WEIGHT_MAX * 2;
1728 pSpectInfo[j + 4].weight =
1729 SAP_ACS_WEIGHT_MAX * 2;
1730 }
1731 }
1732 } else {
1733 tmpWeight1 = pSpectInfo[j].weight +
1734 pSpectInfo[j + 4].weight;
1735 if (pSpectInfo[j].weight <=
1736 pSpectInfo[j + 4].weight) {
1737 pSpectInfo[j].weight = tmpWeight1;
1738 pSpectInfo[j + 4].weight =
1739 SAP_ACS_WEIGHT_MAX * 2;
1740 } else {
1741 pSpectInfo[j + 4].weight = tmpWeight1;
1742 pSpectInfo[j].weight =
1743 SAP_ACS_WEIGHT_MAX * 2;
1744 }
1745 }
1746 }
1747}
1748
1749/*==========================================================================
1750 FUNCTION sap_sort_chl_weight_ht40_5_g
1751
1752 DESCRIPTION
1753 Funtion to sort the channels with the least weight first for HT40 channels
1754
1755 DEPENDENCIES
1756 NA.
1757
1758 PARAMETERS
1759
1760 IN
1761 pSpectInfoParams : Pointer to the tSapChSelSpectInfo structure
1762
1763 RETURN VALUE
1764 void : NULL
1765
1766 SIDE EFFECTS
1767 ============================================================================*/
1768void sap_sort_chl_weight_ht40_5_g(tSapChSelSpectInfo *pSpectInfoParams)
1769{
1770 uint8_t i, j;
1771 tSapSpectChInfo *pSpectInfo;
1772
1773 pSpectInfo = pSpectInfoParams->pSpectCh;
1774 /*for each HT40 channel, calculate the combined weight of the
1775 two 20MHz weight */
1776 for (i = 0; i < ARRAY_SIZE(acs_ht40_channels5_g); i++) {
1777 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
1778 if (pSpectInfo[j].chNum ==
1779 acs_ht40_channels5_g[i].chStartNum)
1780 break;
1781 }
1782 if (j == pSpectInfoParams->numSpectChans)
1783 continue;
1784
1785 /* found the channel, add the two adjacent channels' weight */
1786 if ((pSpectInfo[j].chNum + 4) == pSpectInfo[j + 1].chNum) {
1787 acs_ht40_channels5_g[i].weight = pSpectInfo[j].weight +
1788 pSpectInfo[j + 1].weight;
1789 /* select better of the adjact channel as the primary channel */
1790 if (pSpectInfo[j].weight <= pSpectInfo[j + 1].weight) {
1791 pSpectInfo[j].weight =
1792 acs_ht40_channels5_g[i].weight;
1793 /* mark the adjacent channel's weight as max value so
1794 that it will be sorted to the bottom */
1795 pSpectInfo[j + 1].weight =
1796 SAP_ACS_WEIGHT_MAX * 2;
1797 } else {
1798 pSpectInfo[j + 1].weight =
1799 acs_ht40_channels5_g[i].weight;
1800 /* mark the adjacent channel's weight as max value so
1801 that it will be sorted to the bottom */
1802 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2;
1803 }
1804
1805 } else
1806 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2;
1807 }
1808
1809 /* avoid channel 165 by setting its weight to max */
1810 pSpectInfo = pSpectInfoParams->pSpectCh;
1811 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
1812 if (CHANNEL_165 == pSpectInfo[j].chNum) {
1813 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2;
1814 break;
1815 }
1816 }
1817
1818 pSpectInfo = pSpectInfoParams->pSpectCh;
1819 for (j = 0; j < (pSpectInfoParams->numSpectChans); j++) {
1820 CDF_TRACE(CDF_MODULE_ID_SAP, CDF_TRACE_LEVEL_INFO_HIGH,
1821 "In %s, Channel=%d Weight= %d rssi=%d bssCount=%d",
1822 __func__, pSpectInfo->chNum, pSpectInfo->weight,
1823 pSpectInfo->rssiAgr, pSpectInfo->bssCount);
1824 pSpectInfo++;
1825 }
1826
1827 sap_sort_chl_weight(pSpectInfoParams);
1828}
1829
1830/*==========================================================================
1831 FUNCTION sap_sort_chl_weight_all
1832
1833 DESCRIPTION
1834 Funtion to sort the channels with the least weight first
1835
1836 DEPENDENCIES
1837 NA.
1838
1839 PARAMETERS
1840
1841 IN
1842 ptSapContext : Pointer to the ptSapContext structure
1843 pSpectInfoParams : Pointer to the tSapChSelSpectInfo structure
1844
1845 RETURN VALUE
1846 void : NULL
1847
1848 SIDE EFFECTS
1849 ============================================================================*/
1850void sap_sort_chl_weight_all(ptSapContext pSapCtx,
1851 tSapChSelSpectInfo *pSpectInfoParams,
1852 uint32_t operatingBand)
1853{
1854 tSapSpectChInfo *pSpectCh = NULL;
1855 uint32_t j = 0;
1856#ifndef SOFTAP_CHANNEL_RANGE
1857 uint32_t i = 0;
1858#endif
1859
1860 pSpectCh = pSpectInfoParams->pSpectCh;
1861#ifdef SOFTAP_CHANNEL_RANGE
1862
1863 switch (pSapCtx->acs_cfg->ch_width) {
1864 case CH_WIDTH_40MHZ:
1865 if (eCSR_DOT11_MODE_11g == operatingBand)
1866 sap_sort_chl_weight_ht40_24_g(pSpectInfoParams);
1867 else if (eCSR_DOT11_MODE_11a == operatingBand)
1868 sap_sort_chl_weight_ht40_5_g(pSpectInfoParams);
1869 else {
1870 sap_sort_chl_weight_ht40_24_g(pSpectInfoParams);
1871 sap_sort_chl_weight_ht40_5_g(pSpectInfoParams);
1872 }
1873 sap_sort_chl_weight(pSpectInfoParams);
1874 break;
1875
1876 case CH_WIDTH_80MHZ:
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001877 case CH_WIDTH_80P80MHZ:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001878 sap_sort_chl_weight_ht80(pSpectInfoParams);
1879 break;
1880
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001881 case CH_WIDTH_160MHZ:
1882 sap_sort_chl_weight_vht160(pSpectInfoParams);
1883 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001884 case CH_WIDTH_20MHZ:
1885 default:
1886 /* Sorting the channels as per weights as 20MHz channels */
1887 sap_sort_chl_weight(pSpectInfoParams);
1888 }
1889
1890#else
1891 /* Sorting the channels as per weights */
1892 for (i = 0; i < SPECT_24GHZ_CH_COUNT; i++) {
1893 minWeightIndex = i;
1894 for (j = i + 1; j < SPECT_24GHZ_CH_COUNT; j++) {
1895 if (pSpectCh[j].weight <
1896 pSpectCh[minWeightIndex].weight) {
1897 minWeightIndex = j;
1898 }
1899 }
1900 if (minWeightIndex != i) {
1901 cdf_mem_copy(&temp, &pSpectCh[minWeightIndex],
1902 sizeof(*pSpectCh));
1903 cdf_mem_copy(&pSpectCh[minWeightIndex], &pSpectCh[i],
1904 sizeof(*pSpectCh));
1905 cdf_mem_copy(&pSpectCh[i], &temp, sizeof(*pSpectCh));
1906 }
1907 }
1908#endif
1909
1910 /* For testing */
1911 CDF_TRACE(CDF_MODULE_ID_SAP, CDF_TRACE_LEVEL_INFO_HIGH,
1912 "In %s, Sorted Spectrum Channels Weight", __func__);
1913 pSpectCh = pSpectInfoParams->pSpectCh;
1914 for (j = 0; j < (pSpectInfoParams->numSpectChans); j++) {
1915 CDF_TRACE(CDF_MODULE_ID_SAP, CDF_TRACE_LEVEL_INFO_HIGH,
1916 "In %s, Channel=%d Weight= %d rssi=%d bssCount=%d",
1917 __func__, pSpectCh->chNum, pSpectCh->weight,
1918 pSpectCh->rssiAgr, pSpectCh->bssCount);
1919 pSpectCh++;
1920 }
1921
1922}
1923
1924/*==========================================================================
1925 FUNCTION sap_filter_over_lap_ch
1926
1927 DESCRIPTION
1928 return true if ch is acceptable.
1929 This function will decide if we will filter over lap channel or not.
1930
1931 DEPENDENCIES
1932 shall called after ap start.
1933
1934 PARAMETERS
1935
1936 IN
1937 pSapCtx : Pointer to ptSapContext.
1938 chNum : Filter channel number.
1939
1940 RETURN VALUE
1941 bool : true if channel is accepted.
1942
1943 SIDE EFFECTS
1944 ============================================================================*/
1945bool sap_filter_over_lap_ch(ptSapContext pSapCtx, uint16_t chNum)
1946{
1947 if (pSapCtx->enableOverLapCh)
1948 return eSAP_TRUE;
1949 else if ((chNum == CHANNEL_1) ||
1950 (chNum == CHANNEL_6) || (chNum == CHANNEL_11))
1951 return eSAP_TRUE;
1952
1953 return eSAP_FALSE;
1954}
1955
1956/*==========================================================================
1957 FUNCTION sap_select_channel
1958
1959 DESCRIPTION
1960 Runs a algorithm to select the best channel to operate in based on BSS
1961 rssi and bss count on each channel
1962
1963 DEPENDENCIES
1964 NA.
1965
1966 PARAMETERS
1967
1968 IN
1969 halHandle : Pointer to HAL handle
1970 pResult : Pointer to tScanResultHandle
1971
1972 RETURN VALUE
1973 uint8_t : Success - channel number, Fail - zero
1974
1975 SIDE EFFECTS
1976 ============================================================================*/
1977uint8_t sap_select_channel(tHalHandle halHandle, ptSapContext pSapCtx,
1978 tScanResultHandle pScanResult)
1979{
1980 /* DFS param object holding all the data req by the algo */
1981 tSapChSelSpectInfo oSpectInfoParams = { NULL, 0 };
1982 tSapChSelSpectInfo *pSpectInfoParams = &oSpectInfoParams; /* Memory? NB */
1983 uint8_t bestChNum = SAP_CHANNEL_NOT_SELECTED;
1984#ifdef FEATURE_WLAN_CH_AVOID
1985 uint8_t i;
1986 uint8_t firstSafeChannelInRange = SAP_CHANNEL_NOT_SELECTED;
1987#endif
1988#ifdef SOFTAP_CHANNEL_RANGE
1989 uint32_t startChannelNum;
1990 uint32_t endChannelNum;
1991 uint32_t operatingBand = 0;
1992 uint32_t tmpChNum;
1993 uint8_t count;
1994#endif
1995 CDF_TRACE(CDF_MODULE_ID_SAP, CDF_TRACE_LEVEL_INFO_HIGH,
1996 "In %s, Running SAP Ch Select", __func__);
1997
1998#ifdef FEATURE_WLAN_CH_AVOID
1999 sap_update_unsafe_channel_list(pSapCtx);
2000#endif
2001
2002 if (NULL == pScanResult) {
2003 CDF_TRACE(CDF_MODULE_ID_SAP, CDF_TRACE_LEVEL_INFO_HIGH,
2004 "%s: No external AP present\n", __func__);
2005
2006#ifndef SOFTAP_CHANNEL_RANGE
2007 return bestChNum;
2008#else
2009 startChannelNum = pSapCtx->acs_cfg->start_ch;
2010 endChannelNum = pSapCtx->acs_cfg->end_ch;
2011
2012
2013 CDF_TRACE(CDF_MODULE_ID_SAP, CDF_TRACE_LEVEL_INFO_HIGH,
2014 "%s: start - end: %d - %d\n", __func__,
2015 startChannelNum, endChannelNum);
2016
2017#ifndef FEATURE_WLAN_CH_AVOID /* FEATURE_WLAN_CH_AVOID NOT defined case */
2018 pSapCtx->acs_cfg->pri_ch = startChannelNum;
2019 pSapCtx->acs_cfg->ht_sec_ch = 0;
2020 /* pick the first channel in configured range */
2021 return startChannelNum;
2022#else /* FEATURE_WLAN_CH_AVOID defined */
2023
2024 /* get a channel in PCL and within the range */
2025 for (i = 0; i < pSapCtx->acs_cfg->pcl_ch_count; i++) {
2026 if ((pSapCtx->acs_cfg->pcl_channels[i] >=
2027 startChannelNum)
2028 && (pSapCtx->acs_cfg->pcl_channels[i] <=
2029 endChannelNum)) {
2030 firstSafeChannelInRange =
2031 pSapCtx->acs_cfg->pcl_channels[i];
2032 break;
2033 }
2034 }
2035 if (SAP_CHANNEL_NOT_SELECTED != firstSafeChannelInRange)
2036 return firstSafeChannelInRange;
2037
2038 for (i = 0; i < NUM_20MHZ_RF_CHANNELS; i++) {
2039 if ((safe_channels[i].channelNumber >= startChannelNum)
2040 && (safe_channels[i].channelNumber <=
2041 endChannelNum)) {
2042 CHANNEL_STATE channel_type =
2043 cds_get_channel_state(safe_channels[i].
2044 channelNumber);
2045
2046 if ((channel_type == CHANNEL_STATE_DISABLE) ||
2047 (channel_type == CHANNEL_STATE_INVALID))
2048 continue;
2049
2050 if (safe_channels[i].isSafe == true) {
2051 CDF_TRACE(CDF_MODULE_ID_SAP,
2052 CDF_TRACE_LEVEL_INFO_HIGH,
2053 "%s: channel %d in the configuration is safe\n",
2054 __func__,
2055 safe_channels[i].
2056 channelNumber);
2057 firstSafeChannelInRange =
2058 safe_channels[i].channelNumber;
2059 break;
2060 }
2061
2062 CDF_TRACE(CDF_MODULE_ID_SAP,
2063 CDF_TRACE_LEVEL_INFO_HIGH,
2064 "%s: channel %d in the configuration is unsafe\n",
2065 __func__,
2066 safe_channels[i].channelNumber);
2067 }
2068 }
2069
2070 /* if no channel selected return SAP_CHANNEL_NOT_SELECTED */
2071 return firstSafeChannelInRange;
2072#endif /* !FEATURE_WLAN_CH_AVOID */
2073#endif /* SOFTAP_CHANNEL_RANGE */
2074 }
2075
2076 /* Initialize the structure pointed by pSpectInfoParams */
2077 if (sap_chan_sel_init(halHandle, pSpectInfoParams, pSapCtx) != eSAP_TRUE) {
2078 CDF_TRACE(CDF_MODULE_ID_SAP, CDF_TRACE_LEVEL_ERROR,
2079 "In %s, Ch Select initialization failed", __func__);
2080 return SAP_CHANNEL_NOT_SELECTED;
2081 }
2082 /* Compute the weight of the entire spectrum in the operating band */
2083 sap_compute_spect_weight(pSpectInfoParams, halHandle, pScanResult,
2084 pSapCtx);
2085
2086#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
2087 /* process avoid channel IE to collect all channels to avoid */
2088 sap_process_avoid_ie(halHandle, pSapCtx, pScanResult, pSpectInfoParams);
2089#endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
2090
2091#ifdef SOFTAP_CHANNEL_RANGE
2092 startChannelNum = pSapCtx->acs_cfg->start_ch;
2093 endChannelNum = pSapCtx->acs_cfg->end_ch;
2094 SET_ACS_BAND(operatingBand, pSapCtx);
2095
2096 pSapCtx->acsBestChannelInfo.channelNum = 0;
2097 pSapCtx->acsBestChannelInfo.weight = SAP_ACS_WEIGHT_MAX;
2098
2099 /* Sort the channel list as per the computed weights, lesser weight first. */
2100 sap_sort_chl_weight_all(pSapCtx, pSpectInfoParams, operatingBand);
2101
2102 /*Loop till get the best channel in the given range */
2103 for (count = 0; count < pSpectInfoParams->numSpectChans; count++) {
2104 if ((startChannelNum <= pSpectInfoParams->pSpectCh[count].chNum)
2105 && (endChannelNum >=
2106 pSpectInfoParams->pSpectCh[count].chNum)) {
2107 if (bestChNum == SAP_CHANNEL_NOT_SELECTED) {
2108 bestChNum =
2109 pSpectInfoParams->pSpectCh[count].chNum;
2110 /* check if bestChNum is in preferred channel list */
2111 bestChNum =
2112 sap_select_preferred_channel_from_channel_list
2113 (bestChNum, pSapCtx, pSpectInfoParams);
2114 if (bestChNum == SAP_CHANNEL_NOT_SELECTED) {
2115 /* not in preferred channel list, go to next best channel */
2116 continue;
2117 }
2118
2119#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
2120 /* Weight of the channels(device's AP is
2121 * operating) increased to MAX+1 so that they
2122 * will be choosen only when there is no other
2123 * best channel to choose
2124 */
2125 if (sap_check_in_avoid_ch_list(pSapCtx,
2126 bestChNum)) {
2127 bestChNum = SAP_CHANNEL_NOT_SELECTED;
2128 continue;
2129 }
2130#endif
2131
2132 pSapCtx->acsBestChannelInfo.channelNum =
2133 bestChNum;
2134 pSapCtx->acsBestChannelInfo.weight =
2135 pSpectInfoParams->
2136 pSpectCh[count].
2137 weight_copy;
2138 }
2139
2140 if (bestChNum != SAP_CHANNEL_NOT_SELECTED) {
2141 if (operatingBand == eCSR_DOT11_MODE_11g) {
2142 /* Give preference to Non-overlap channels */
2143 if (sap_filter_over_lap_ch(pSapCtx,
2144 pSpectInfoParams->
2145 pSpectCh[count].
2146 chNum)) {
2147 tmpChNum =
2148 pSpectInfoParams->
2149 pSpectCh[count].chNum;
2150 tmpChNum =
2151 sap_select_preferred_channel_from_channel_list
2152 (tmpChNum, pSapCtx,
2153 pSpectInfoParams);
2154 if (tmpChNum !=
2155 SAP_CHANNEL_NOT_SELECTED) {
2156 bestChNum = tmpChNum;
2157 break;
2158 }
2159 }
2160 }
2161 }
2162 }
2163 }
2164#else
2165 /* Sort the channel list as per the computed weights, lesser weight first. */
2166 sap_sort_chl_weight_all(pSapCtx, halHandle, pSpectInfoParams);
2167 /* Get the first channel in sorted array as best 20M Channel */
2168 bestChNum = (uint8_t) pSpectInfoParams->pSpectCh[0].chNum;
2169 /* Select Best Channel from Channel List if Configured */
2170 bestChNum = sap_select_preferred_channel_from_channel_list(bestChNum,
2171 pSapCtx,
2172 pSpectInfoParams);
2173#endif
2174
2175 /** in case the best channel seleted is not in PCL and there is another
2176 * channel which has same weightage and is in PCL, choose the one in
2177 * PCL
2178 */
2179 for (count = 0; count < pSpectInfoParams->numSpectChans; count++) {
2180 /** check if a pcl channel has the same weightage
2181 * as the best channel
2182 */
2183 if (ch_in_pcl(pSapCtx, pSpectInfoParams->pSpectCh[count].chNum)
2184 && (pSpectInfoParams->pSpectCh[count].weight ==
2185 pSapCtx->acsBestChannelInfo.weight)) {
2186 if (sap_select_preferred_channel_from_channel_list(
2187 pSpectInfoParams->pSpectCh[count].chNum,
2188 pSapCtx, pSpectInfoParams) ==
2189 SAP_CHANNEL_NOT_SELECTED)
2190 continue;
2191
2192#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
2193 if (sap_check_in_avoid_ch_list(pSapCtx, bestChNum))
2194 continue;
2195#endif
2196 bestChNum = pSpectInfoParams->pSpectCh[count].chNum;
2197 CDF_TRACE(CDF_MODULE_ID_SAP,
2198 CDF_TRACE_LEVEL_INFO_HIGH,
2199 "change best channel to %d in PCL",
2200 bestChNum);
2201 break;
2202 }
2203 }
2204
2205 pSapCtx->acs_cfg->pri_ch = bestChNum;
2206 /* determine secondary channel for 2.4G channel 5, 6, 7 in HT40 */
2207 if ((operatingBand == eCSR_DOT11_MODE_11g) &&
2208 (pSapCtx->acs_cfg->ch_width == CH_WIDTH_40MHZ)) {
2209 if ((bestChNum >= 5) && (bestChNum <= 7)) {
2210 int weight_below, weight_above, i;
2211 tSapSpectChInfo *pspect_info;
2212
2213 weight_below = weight_above = SAP_ACS_WEIGHT_MAX;
2214 pspect_info = pSpectInfoParams->pSpectCh;
2215 for (i = 0; i < pSpectInfoParams->numSpectChans;
2216 i++) {
2217 if (pspect_info[i].chNum == (bestChNum - 4))
2218 weight_below = pspect_info[i].weight;
2219
2220 if (pspect_info[i].chNum == (bestChNum + 4))
2221 weight_above = pspect_info[i].weight;
2222 }
2223
2224 if (weight_below < weight_above)
2225 pSapCtx->acs_cfg->ht_sec_ch =
2226 pSapCtx->acs_cfg->pri_ch - 4;
2227 else
2228 pSapCtx->acs_cfg->ht_sec_ch =
2229 pSapCtx->acs_cfg->pri_ch + 4;
2230 } else if (bestChNum >= 1 && bestChNum <= 4) {
2231 pSapCtx->acs_cfg->ht_sec_ch =
2232 pSapCtx->acs_cfg->pri_ch + 4;
2233 } else if (bestChNum >= 8 && bestChNum <= 13) {
2234 pSapCtx->acs_cfg->ht_sec_ch =
2235 pSapCtx->acs_cfg->pri_ch - 4;
2236 } else if (bestChNum == 14) {
2237 pSapCtx->acs_cfg->ht_sec_ch = 0;
2238 }
2239 pSapCtx->secondary_ch = pSapCtx->acs_cfg->ht_sec_ch;
2240 }
2241 /* Free all the allocated memory */
2242 sap_chan_sel_exit(pSpectInfoParams);
2243
2244 CDF_TRACE(CDF_MODULE_ID_SAP, CDF_TRACE_LEVEL_INFO_HIGH,
2245 "In %s, Running SAP Ch select Completed, Ch=%d", __func__,
2246 bestChNum);
2247 if (bestChNum > 0 && bestChNum <= 252)
2248 return bestChNum;
2249 else
2250 return SAP_CHANNEL_NOT_SELECTED;
2251}