blob: a00c48db3a0306a471c5fbc51e5e0471a3d85d92 [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
Anurag Chouhan6d760662016-02-20 16:05:43 +053030 s a p C h S e l e c t . C
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080031 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 ------------------------------------------------------------------------*/
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +053044#include "qdf_trace.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080045#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
Yuanyuan Liu0e0aa932016-05-12 10:17:58 -070057#include "pld_common.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080058
59/*--------------------------------------------------------------------------
60 Function definitions
61 --------------------------------------------------------------------------*/
62
63/*--------------------------------------------------------------------------
64 Defines
65 --------------------------------------------------------------------------*/
66#define SAP_DEBUG
67
68#define IS_RSSI_VALID(extRssi, rssi) \
69 ( \
70 ((extRssi < rssi) ? true : false) \
71 )
72
73#define SET_ACS_BAND(acs_band, pSapCtx) \
74{ \
75 if (pSapCtx->acs_cfg->start_ch <= 14 && \
76 pSapCtx->acs_cfg->end_ch <= 14) \
77 acs_band = eCSR_DOT11_MODE_11g; \
78 else if (pSapCtx->acs_cfg->start_ch >= 14)\
79 acs_band = eCSR_DOT11_MODE_11a; \
80 else \
81 acs_band = eCSR_DOT11_MODE_abg; \
82}
83
84#ifdef FEATURE_WLAN_CH_AVOID
Amar Singhalb8d4f152016-02-10 10:21:43 -080085sapSafeChannelType safe_channels[NUM_CHANNELS] = {
86 {1, true},
87 {2, true},
88 {3, true},
89 {4, true},
90 {5, true},
91 {6, true},
92 {7, true},
93 {8, true},
94 {9, true},
95 {10, true},
96 {11, true},
97 {12, true},
98 {13, true},
99 {14, true},
100 {36, true},
101 {40, true},
102 {44, true},
103 {48, true},
104 {52, true},
105 {56, true},
106 {60, true},
107 {64, true},
108 {100, true},
109 {104, true},
110 {108, true},
111 {112, true},
112 {116, true},
113 {120, true},
114 {124, true},
115 {128, true},
116 {132, true},
117 {136, true},
118 {140, true},
119 {144, true},
120 {149, true},
121 {153, true},
122 {157, true},
123 {161, true},
124 {165, true},
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800125};
126#endif
127
128typedef struct {
129 uint16_t chStartNum;
130 uint32_t weight;
131} sapAcsChannelInfo;
132
133sapAcsChannelInfo acs_ht40_channels5_g[] = {
134 {36, SAP_ACS_WEIGHT_MAX},
135 {44, SAP_ACS_WEIGHT_MAX},
136 {52, SAP_ACS_WEIGHT_MAX},
137 {60, SAP_ACS_WEIGHT_MAX},
138 {100, SAP_ACS_WEIGHT_MAX},
139 {108, SAP_ACS_WEIGHT_MAX},
140 {116, SAP_ACS_WEIGHT_MAX},
141 {124, SAP_ACS_WEIGHT_MAX},
142 {132, SAP_ACS_WEIGHT_MAX},
143 {140, SAP_ACS_WEIGHT_MAX},
144 {149, SAP_ACS_WEIGHT_MAX},
145 {157, SAP_ACS_WEIGHT_MAX},
146};
147
148sapAcsChannelInfo acs_ht80_channels[] = {
149 {36, SAP_ACS_WEIGHT_MAX},
150 {52, SAP_ACS_WEIGHT_MAX},
151 {100, SAP_ACS_WEIGHT_MAX},
152 {116, SAP_ACS_WEIGHT_MAX},
153 {132, SAP_ACS_WEIGHT_MAX},
154 {149, SAP_ACS_WEIGHT_MAX},
155};
156
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -0700157sapAcsChannelInfo acs_vht160_channels[] = {
158 {36, SAP_ACS_WEIGHT_MAX},
159 {100, SAP_ACS_WEIGHT_MAX},
160};
161
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800162sapAcsChannelInfo acs_ht40_channels24_g[] = {
163 {1, SAP_ACS_WEIGHT_MAX},
164 {2, SAP_ACS_WEIGHT_MAX},
165 {3, SAP_ACS_WEIGHT_MAX},
166 {4, SAP_ACS_WEIGHT_MAX},
167 {9, SAP_ACS_WEIGHT_MAX},
168};
169
170#define CHANNEL_165 165
171
172/* rssi discount for channels in PCL */
173#define PCL_RSSI_DISCOUNT 10
174
175#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
176/**
177 * sap_check_n_add_channel() - checks and add given channel in sap context's
178 * avoid_channels_info struct
179 * @sap_ctx: sap context.
180 * @new_channel: channel to be added to sap_ctx's avoid ch info
181 *
182 * sap_ctx contains sap_avoid_ch_info strcut containing the list of channels on
183 * which MDM device's AP with MCC was detected. This function will add channels
184 * to that list after checking for duplicates.
185 *
186 * Return: true: if channel was added or already present
187 * else false: if channel list was already full.
188 */
189bool
190sap_check_n_add_channel(ptSapContext sap_ctx,
191 uint8_t new_channel)
192{
193 uint8_t i = 0;
194 struct sap_avoid_channels_info *ie_info =
195 &sap_ctx->sap_detected_avoid_ch_ie;
196
197 for (i = 0; i < sizeof(ie_info->channels); i++) {
198 if (ie_info->channels[i] == new_channel)
199 break;
200
201 if (ie_info->channels[i] == 0) {
202 ie_info->channels[i] = new_channel;
203 break;
204 }
205 }
206 if (i == sizeof(ie_info->channels))
207 return false;
208 else
209 return true;
210}
211/**
212 * sap_check_n_add_overlapped_chnls() - checks & add overlapped channels
213 * to primary channel in 2.4Ghz band.
214 * @sap_ctx: sap context.
215 * @primary_chnl: primary channel to be avoided.
216 *
217 * sap_ctx contains sap_avoid_ch_info struct containing the list of channels on
218 * which MDM device's AP with MCC was detected. This function will add channels
219 * to that list after checking for duplicates.
220 *
221 * Return: true: if channel was added or already present
222 * else false: if channel list was already full.
223 */
224static bool
225sap_check_n_add_overlapped_chnls(ptSapContext sap_ctx, uint8_t primary_channel)
226{
227 uint8_t i = 0, j = 0, upper_chnl = 0, lower_chnl = 0;
228 struct sap_avoid_channels_info *ie_info =
229 &sap_ctx->sap_detected_avoid_ch_ie;
230 /*
231 * if primary channel less than channel 1 or out of 2g band then
232 * no further process is required. return true in this case.
233 */
234 if (primary_channel < CHANNEL_1 || primary_channel > CHANNEL_14)
235 return true;
236
237 /* lower channel is one channel right before primary channel */
238 lower_chnl = primary_channel - 1;
239 /* upper channel is one channel right after primary channel */
240 upper_chnl = primary_channel + 1;
241
242 /* lower channel needs to be non-zero, zero is not valid channel */
243 if (lower_chnl > (CHANNEL_1 - 1)) {
244 for (i = 0; i < sizeof(ie_info->channels); i++) {
245 if (ie_info->channels[i] == lower_chnl)
246 break;
247 if (ie_info->channels[i] == 0) {
248 ie_info->channels[i] = lower_chnl;
249 break;
250 }
251 }
252 }
253 /* upper channel needs to be atleast last channel in 2.4Ghz band */
254 if (upper_chnl < (CHANNEL_14 + 1)) {
255 for (j = 0; j < sizeof(ie_info->channels); j++) {
256 if (ie_info->channels[j] == upper_chnl)
257 break;
258 if (ie_info->channels[j] == 0) {
259 ie_info->channels[j] = upper_chnl;
260 break;
261 }
262 }
263 }
264 if (i == sizeof(ie_info->channels) || j == sizeof(ie_info->channels))
265 return false;
266 else
267 return true;
268}
269
270/**
271 * sap_process_avoid_ie() - processes the detected Q2Q IE
272 * context's avoid_channels_info struct
273 * @hal: hal handle
274 * @sap_ctx: sap context.
275 * @scan_result: scan results for ACS scan.
276 * @spect_info: spectrum weights array to update
277 *
278 * Detection of Q2Q IE indicates presence of another MDM device with its AP
279 * operating in MCC mode. This function parses the scan results and processes
280 * the Q2Q IE if found. It then extracts the channels and populates them in
281 * sap_ctx struct. It also increases the weights of those channels so that
282 * ACS logic will avoid those channels in its selection algorithm.
283 *
284 * Return: void
285 */
286void sap_process_avoid_ie(tHalHandle hal,
287 ptSapContext sap_ctx,
288 tScanResultHandle scan_result,
289 tSapChSelSpectInfo *spect_info)
290{
291 uint32_t total_ie_len = 0;
292 uint8_t *temp_ptr = NULL;
293 uint8_t i = 0;
294 struct sAvoidChannelIE *avoid_ch_ie;
295 tCsrScanResultInfo *node = NULL;
296 tpAniSirGlobal mac_ctx = NULL;
297 tSapSpectChInfo *spect_ch = NULL;
298
299 mac_ctx = PMAC_STRUCT(hal);
300 spect_ch = spect_info->pSpectCh;
301 node = sme_scan_result_get_first(hal, scan_result);
302
303 while (node) {
304 total_ie_len = (node->BssDescriptor.length +
305 sizeof(uint16_t) + sizeof(uint32_t) -
306 sizeof(tSirBssDescription));
307 temp_ptr = cfg_get_vendor_ie_ptr_from_oui(mac_ctx,
308 SIR_MAC_QCOM_VENDOR_OUI,
309 SIR_MAC_QCOM_VENDOR_SIZE,
310 ((uint8_t *)&node->BssDescriptor.ieFields),
311 total_ie_len);
312
313 if (temp_ptr) {
314 avoid_ch_ie = (struct sAvoidChannelIE *)temp_ptr;
315 if (avoid_ch_ie->type != QCOM_VENDOR_IE_MCC_AVOID_CH)
316 continue;
317
318 sap_ctx->sap_detected_avoid_ch_ie.present = 1;
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530319 QDF_TRACE(QDF_MODULE_ID_SAP,
320 QDF_TRACE_LEVEL_DEBUG,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800321 "Q2Q IE - avoid ch %d",
322 avoid_ch_ie->channel);
323 /* add this channel to to_avoid channel list */
324 sap_check_n_add_channel(sap_ctx,
325 avoid_ch_ie->channel);
326 sap_check_n_add_overlapped_chnls(sap_ctx,
327 avoid_ch_ie->channel);
328 /*
329 * Mark weight of these channel present in IE to MAX
330 * so that ACS logic will to avoid thse channels
331 */
332 for (i = 0; i < spect_info->numSpectChans; i++)
333 if (spect_ch[i].chNum == avoid_ch_ie->channel) {
334 /*
335 * weight is set more than max so that,
336 * in the case of other channels being
337 * assigned max weight due to noise,
338 * they may be preferred over channels
339 * with Q2Q IE.
340 */
341 spect_ch[i].weight = SAP_ACS_WEIGHT_MAX + 1;
342 spect_ch[i].weight_copy =
343 SAP_ACS_WEIGHT_MAX + 1;
344 break;
345 }
346 } /* if (temp_ptr) */
347 node = sme_scan_result_get_next(hal, scan_result);
348 }
349}
350#endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
351
352#ifdef FEATURE_WLAN_CH_AVOID
353/*==========================================================================
354 FUNCTION sap_update_unsafe_channel_list
355
356 DESCRIPTION
357 Function Undate unsafe channel list table
358
359 DEPENDENCIES
360 NA.
361
362 IN
363 SapContext pointer
364
365 RETURN VALUE
366 NULL
367 ============================================================================*/
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800368void sap_update_unsafe_channel_list(ptSapContext pSapCtx)
369{
370 uint16_t i, j;
Amar Singhalb8d4f152016-02-10 10:21:43 -0800371 uint16_t unsafe_channel_list[NUM_CHANNELS];
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800372 uint16_t unsafe_channel_count = 0;
Yuanyuan Liu0e0aa932016-05-12 10:17:58 -0700373 qdf_device_t qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800374
Yuanyuan Liu97361182016-06-06 09:38:04 -0700375 if (!qdf_ctx) {
376 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_FATAL,
377 "qdf_ctx is NULL");
378 return;
379 }
380
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800381 /* Flush, default set all channel safe */
Amar Singhalb8d4f152016-02-10 10:21:43 -0800382 for (i = 0; i < NUM_CHANNELS; i++) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800383 safe_channels[i].isSafe = true;
384 }
385
386 /* Try to find unsafe channel */
Ryan Hsu4252a2f2016-01-05 11:18:24 -0800387#if defined(FEATURE_WLAN_STA_AP_MODE_DFS_DISABLE)
Amar Singhalb8d4f152016-02-10 10:21:43 -0800388 for (i = 0; i < NUM_CHANNELS; i++) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800389 if (pSapCtx->dfs_ch_disable == true) {
390 if (CDS_IS_DFS_CH(safe_channels[i].channelNumber)) {
391 safe_channels[i].isSafe = false;
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530392 QDF_TRACE(QDF_MODULE_ID_SAP,
393 QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800394 "%s: DFS Ch %d is not safe in"
395 " Concurrent mode",
396 __func__,
397 safe_channels[i].channelNumber);
398 }
399 }
400 }
401#endif
Yuanyuan Liu0e0aa932016-05-12 10:17:58 -0700402 pld_get_wlan_unsafe_channel(qdf_ctx->dev,
403 unsafe_channel_list,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800404 &unsafe_channel_count,
405 sizeof(unsafe_channel_list));
406
407 for (i = 0; i < unsafe_channel_count; i++) {
Amar Singhalb8d4f152016-02-10 10:21:43 -0800408 for (j = 0; j < NUM_CHANNELS; j++) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800409 if (safe_channels[j].channelNumber ==
410 unsafe_channel_list[i]) {
411 /* Found unsafe channel, update it */
412 safe_channels[j].isSafe = false;
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530413 QDF_TRACE(QDF_MODULE_ID_SAP,
414 QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800415 FL("CH %d is not safe"),
416 unsafe_channel_list[i]);
417 break;
418 }
419 }
420 }
421
422 return;
423}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800424
425#endif /* FEATURE_WLAN_CH_AVOID */
426
427/*==========================================================================
428 FUNCTION sap_cleanup_channel_list
429
430 DESCRIPTION
431 Function sap_cleanup_channel_list frees up the memory allocated to the channel list.
432
433 DEPENDENCIES
434 NA.
435
436 PARAMETERS
437
438 IN
439 NULL
440
441 RETURN VALUE
442 NULL
443 ============================================================================*/
444
Ryan Hsu4252a2f2016-01-05 11:18:24 -0800445void sap_cleanup_channel_list(void *p_cds_gctx)
446{
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800447 ptSapContext pSapCtx;
448
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530449 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800450 "Cleaning up the channel list structure");
451
452 if (NULL == p_cds_gctx) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530453 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800454 "SAP Global Context is NULL");
455 return;
456 }
457
458 pSapCtx = CDS_GET_SAP_CB(p_cds_gctx);
459 if (NULL == pSapCtx) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530460 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800461 "SAP Context is NULL");
462 return;
463 }
464
465 pSapCtx->SapChnlList.numChannel = 0;
466 if (pSapCtx->SapChnlList.channelList) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530467 qdf_mem_free(pSapCtx->SapChnlList.channelList);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800468 pSapCtx->SapChnlList.channelList = NULL;
469 }
470
471 pSapCtx->SapAllChnlList.numChannel = 0;
472 if (pSapCtx->SapAllChnlList.channelList) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530473 qdf_mem_free(pSapCtx->SapAllChnlList.channelList);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800474 pSapCtx->SapAllChnlList.channelList = NULL;
475 }
476}
477
478/**
479 * sap_select_preferred_channel_from_channel_list() - to calc best cahnnel
480 * @best_chnl: best channel already calculated among all the chanels
481 * @sap_ctx: sap context
482 * @spectinfo_param: Pointer to tSapChSelSpectInfo structure
483 *
484 * This function calculates the best channel among the configured channel list.
485 * If channel list not configured then returns the best channel calculated
486 * among all the channel list.
487 *
488 * Return: uint8_t best channel
489 */
490uint8_t sap_select_preferred_channel_from_channel_list(uint8_t best_chnl,
491 ptSapContext sap_ctx,
492 tSapChSelSpectInfo *spectinfo_param)
493{
494 uint8_t i = 0;
495
496 /*
497 * If Channel List is not Configured don't do anything
498 * Else return the Best Channel from the Channel List
499 */
500 if ((NULL == sap_ctx->acs_cfg->ch_list) ||
501 (NULL == spectinfo_param) ||
502 (0 == sap_ctx->acs_cfg->ch_list_count))
503 return best_chnl;
504
505 if (best_chnl <= 0 || best_chnl > 252)
506 return SAP_CHANNEL_NOT_SELECTED;
507
508 /* Select the best channel from allowed list */
509 for (i = 0; i < sap_ctx->acs_cfg->ch_list_count; i++) {
510 if (sap_ctx->acs_cfg->ch_list[i] == best_chnl) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530511 QDF_TRACE(QDF_MODULE_ID_SAP,
512 QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800513 "Best channel is: %d",
514 best_chnl);
515 return best_chnl;
516 }
517 }
518
519 return SAP_CHANNEL_NOT_SELECTED;
520}
521
522/*==========================================================================
523 FUNCTION sap_chan_sel_init
524
525 DESCRIPTION
526 Function sap_chan_sel_init allocates the memory, intializes the
Anurag Chouhan6d760662016-02-20 16:05:43 +0530527 structures used by the channel selection algorithm
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800528
529 DEPENDENCIES
530 NA.
531
532 PARAMETERS
533
534 IN
535 halHandle : Pointer to tHalHandle
536 *pSpectInfoParams : Pointer to tSapChSelSpectInfo structure
537 pSapCtx : Pointer to SAP Context
538
539 RETURN VALUE
540 bool: Success or FAIL
541
542 SIDE EFFECTS
543 ============================================================================*/
544bool sap_chan_sel_init(tHalHandle halHandle,
545 tSapChSelSpectInfo *pSpectInfoParams, ptSapContext pSapCtx)
546{
547 tSapSpectChInfo *pSpectCh = NULL;
548 uint8_t *pChans = NULL;
549 uint16_t channelnum = 0;
550 tpAniSirGlobal pMac = PMAC_STRUCT(halHandle);
551 bool chSafe = true;
552#ifdef FEATURE_WLAN_CH_AVOID
553 uint16_t i;
554#endif
555 uint32_t dfs_master_cap_enabled;
556 bool include_dfs_ch = true;
557
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530558 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, "In %s",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800559 __func__);
560
561 pSpectInfoParams->numSpectChans =
562 pMac->scan.base_channels.numChannels;
563
564 /* Allocate memory for weight computation of 2.4GHz */
565 pSpectCh =
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530566 (tSapSpectChInfo *) qdf_mem_malloc((pSpectInfoParams->numSpectChans)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800567 * sizeof(*pSpectCh));
568
569 if (pSpectCh == NULL) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530570 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
Anurag Chouhanf04e84f2016-03-03 10:12:12 +0530571 "In %s, QDF_MALLOC_ERR", __func__);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800572 return eSAP_FALSE;
573 }
574
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530575 qdf_mem_zero(pSpectCh,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800576 (pSpectInfoParams->numSpectChans) * sizeof(*pSpectCh));
577
578 /* Initialize the pointers in the DfsParams to the allocated memory */
579 pSpectInfoParams->pSpectCh = pSpectCh;
580
581 pChans = pMac->scan.base_channels.channelList;
582
Ryan Hsu4252a2f2016-01-05 11:18:24 -0800583#if defined(FEATURE_WLAN_STA_AP_MODE_DFS_DISABLE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800584 if (pSapCtx->dfs_ch_disable == true)
585 include_dfs_ch = false;
586#endif
587 sme_cfg_get_int(halHandle, WNI_CFG_DFS_MASTER_ENABLED,
588 &dfs_master_cap_enabled);
589 if (dfs_master_cap_enabled == 0)
590 include_dfs_ch = false;
591
592 /* Fill the channel number in the spectrum in the operating freq band */
593 for (channelnum = 0;
594 channelnum < pSpectInfoParams->numSpectChans;
Edhar, Mahesh Kumar4f660672015-10-30 11:53:26 +0530595 channelnum++, pChans++, pSpectCh++) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800596 chSafe = true;
597
598 /* check if the channel is in NOL blacklist */
599 if (sap_dfs_is_channel_in_nol_list(pSapCtx, *pChans,
600 PHY_SINGLE_CHANNEL_CENTERED)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530601 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800602 "In %s, Ch %d is in NOL list", __func__,
603 *pChans);
604 chSafe = false;
605 continue;
606 }
607
608 if (include_dfs_ch == false) {
609 if (CDS_IS_DFS_CH(*pChans)) {
610 chSafe = false;
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530611 QDF_TRACE(QDF_MODULE_ID_SAP,
612 QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800613 "In %s, DFS Ch %d not considered for ACS",
614 __func__, *pChans);
615 continue;
616 }
617 }
618
619#ifdef FEATURE_WLAN_CH_AVOID
Amar Singhalb8d4f152016-02-10 10:21:43 -0800620 for (i = 0; i < NUM_CHANNELS; i++) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800621 if ((safe_channels[i].channelNumber == *pChans) &&
622 (false == safe_channels[i].isSafe)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530623 QDF_TRACE(QDF_MODULE_ID_SAP,
624 QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800625 "In %s, Ch %d is not safe", __func__,
626 *pChans);
627 chSafe = false;
628 break;
629 }
630 }
631#endif /* FEATURE_WLAN_CH_AVOID */
632
633 /* OFDM rates are not supported on channel 14 */
634 if (*pChans == 14 &&
635 eCSR_DOT11_MODE_11b != pSapCtx->csr_roamProfile.phyMode) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800636 continue;
637 }
638
639 if (true == chSafe) {
640 pSpectCh->chNum = *pChans;
641 pSpectCh->valid = eSAP_TRUE;
642 pSpectCh->rssiAgr = SOFTAP_MIN_RSSI; /* Initialise for all channels */
643 pSpectCh->channelWidth = SOFTAP_HT20_CHANNELWIDTH; /* Initialise 20MHz for all the Channels */
644 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800645 }
646 return eSAP_TRUE;
647}
648
649/*==========================================================================
650 FUNCTION sapweight_rssi_count
651
652 DESCRIPTION
653 Function weightRssiCount calculates the channel weight due to rssi
Anurag Chouhan6d760662016-02-20 16:05:43 +0530654 and data count(here number of BSS observed)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800655
656 DEPENDENCIES
657 NA.
658
659 PARAMETERS
660
661 IN
662 rssi : Max signal strength receieved from a BSS for the channel
663 count : Number of BSS observed in the channel
664
665 RETURN VALUE
666 uint32_t : Calculated channel weight based on above two
667
668 SIDE EFFECTS
669 ============================================================================*/
670uint32_t sapweight_rssi_count(int8_t rssi, uint16_t count)
671{
672 int32_t rssiWeight = 0;
673 int32_t countWeight = 0;
674 uint32_t rssicountWeight = 0;
675
676 /* Weight from RSSI */
677 rssiWeight = SOFTAP_RSSI_WEIGHT * (rssi - SOFTAP_MIN_RSSI)
678 / (SOFTAP_MAX_RSSI - SOFTAP_MIN_RSSI);
679
680 if (rssiWeight > SOFTAP_RSSI_WEIGHT)
681 rssiWeight = SOFTAP_RSSI_WEIGHT;
682 else if (rssiWeight < 0)
683 rssiWeight = 0;
684
685 /* Weight from data count */
686 countWeight = SOFTAP_COUNT_WEIGHT * (count - SOFTAP_MIN_COUNT)
687 / (SOFTAP_MAX_COUNT - SOFTAP_MIN_COUNT);
688
689 if (countWeight > SOFTAP_COUNT_WEIGHT)
690 countWeight = SOFTAP_COUNT_WEIGHT;
691
692 rssicountWeight = rssiWeight + countWeight;
693
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530694 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800695 "In %s, rssiWeight=%d, countWeight=%d, rssicountWeight=%d",
696 __func__, rssiWeight, countWeight, rssicountWeight);
697
698 return rssicountWeight;
699}
700
701/**
702 * sap_update_rssi_bsscount() - updates bss count and rssi effect.
703 *
704 * @pSpectCh: Channel Information
705 * @offset: Channel Offset
706 * @sap_24g: Channel is in 2.4G or 5G
707 *
708 * sap_update_rssi_bsscount updates bss count and rssi effect based
709 * on the channel offset.
710 *
711 * Return: None.
712 */
713
714void sap_update_rssi_bsscount(tSapSpectChInfo *pSpectCh, int32_t offset,
715 bool sap_24g)
716{
717 tSapSpectChInfo *pExtSpectCh = NULL;
718 int32_t rssi, rsssi_effect;
719
720 pExtSpectCh = (pSpectCh + offset);
721 if (pExtSpectCh != NULL) {
722 ++pExtSpectCh->bssCount;
723 switch (offset) {
724 case -1:
725 case 1:
726 rsssi_effect = sap_24g ?
727 SAP_24GHZ_FIRST_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY :
728 SAP_SUBBAND1_RSSI_EFFECT_PRIMARY;
729 break;
730 case -2:
731 case 2:
732 rsssi_effect = sap_24g ?
733 SAP_24GHZ_SEC_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY :
734 SAP_SUBBAND2_RSSI_EFFECT_PRIMARY;
735 break;
736 case -3:
737 case 3:
738 rsssi_effect = sap_24g ?
739 SAP_24GHZ_THIRD_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY :
740 SAP_SUBBAND3_RSSI_EFFECT_PRIMARY;
741 break;
742 case -4:
743 case 4:
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -0700744 rsssi_effect = sap_24g ?
745 SAP_24GHZ_FOURTH_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY :
746 SAP_SUBBAND4_RSSI_EFFECT_PRIMARY;
747 break;
748 case -5:
749 case 5:
750 rsssi_effect = SAP_SUBBAND5_RSSI_EFFECT_PRIMARY;
751 break;
752 case -6:
753 case 6:
754 rsssi_effect = SAP_SUBBAND6_RSSI_EFFECT_PRIMARY;
755 break;
756 case -7:
757 case 7:
758 rsssi_effect = SAP_SUBBAND7_RSSI_EFFECT_PRIMARY;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800759 break;
760 default:
761 rsssi_effect = 0;
762 break;
763 }
764
765 rssi = pSpectCh->rssiAgr + rsssi_effect;
766 if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi))
767 pExtSpectCh->rssiAgr = rssi;
768 if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI)
769 pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI;
770 }
771}
772
773/**
774 * sap_upd_chan_spec_params() - sap_upd_chan_spec_params
775 * updates channel parameters obtained from Beacon
776 * @pBeaconStruct Beacon strucutre populated by parse_beacon function
777 * @channelWidth Channel width
778 * @secondaryChannelOffset Secondary Channel Offset
779 * @vhtSupport If channel supports VHT
780 * @centerFreq Central frequency for the given channel.
781 *
782 * sap_upd_chan_spec_params updates the spectrum channels based on the
783 * pBeaconStruct obtained from Beacon IE
784 *
785 * Return: NA.
786 */
787
788void sap_upd_chan_spec_params(tSirProbeRespBeacon *pBeaconStruct,
789 uint16_t *channelWidth,
790 uint16_t *secondaryChannelOffset,
791 uint16_t *vhtSupport,
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -0700792 uint16_t *centerFreq,
793 uint16_t *centerFreq_2)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800794{
795 if (NULL == pBeaconStruct) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530796 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800797 FL("pBeaconStruct is NULL"));
798 return;
799 }
800
801 if (pBeaconStruct->HTCaps.present && pBeaconStruct->HTInfo.present) {
802 *channelWidth = pBeaconStruct->HTCaps.supportedChannelWidthSet;
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -0700803 *secondaryChannelOffset =
804 pBeaconStruct->HTInfo.secondaryChannelOffset;
805 if (!pBeaconStruct->VHTOperation.present)
806 return;
807 *vhtSupport = pBeaconStruct->VHTOperation.present;
808 if (pBeaconStruct->VHTOperation.chanWidth) {
809 *centerFreq =
810 pBeaconStruct->VHTOperation.chanCenterFreqSeg1;
811 *centerFreq_2 =
812 pBeaconStruct->VHTOperation.chanCenterFreqSeg2;
813 /*
814 * LHS follows tSirMacHTChannelWidth, while RHS follows
815 * WNI_CFG_VHT_CHANNEL_WIDTH_X format hence following
816 * adjustment
817 */
818 *channelWidth =
819 pBeaconStruct->VHTOperation.chanWidth + 1;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800820
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800821 }
822 }
823}
824
825/**
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -0700826 * sap_update_rssi_bsscount_vht_5G() - updates bss count and rssi effect.
827 *
828 * @pSpectCh: Channel Information
829 * @offset: Channel Offset
830 * @num_ch: no.of channels
831 *
832 * sap_update_rssi_bsscount_vht_5G updates bss count and rssi effect based
833 * on the channel offset.
834 *
835 * Return: None.
836 */
837
838void sap_update_rssi_bsscount_vht_5G(tSapSpectChInfo *spect_ch, int32_t offset,
839 uint16_t num_ch)
840{
841 int32_t ch_offset;
842 uint16_t i, cnt;
843
844 if (!offset)
845 return;
846 if (offset > 0)
847 cnt = num_ch;
848 else
849 cnt = num_ch + 1;
850 for (i = 0; i < cnt; i++) {
851 ch_offset = offset + i;
852 if (ch_offset == 0)
853 continue;
854 sap_update_rssi_bsscount(spect_ch, ch_offset, false);
855 }
856}
857/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800858 * sap_interference_rssi_count_5G() - sap_interference_rssi_count
859 * considers the Adjacent channel rssi and
860 * data count(here number of BSS observed)
861 * @spect_ch: Channel Information
862 * @chan_width: Channel width parsed from beacon IE
863 * @sec_chan_offset: Secondary Channel Offset
864 * @center_freq: Central frequency for the given channel.
865 * @channel_id: channel_id
866 *
867 * sap_interference_rssi_count_5G considers the Adjacent channel rssi
868 * and data count(here number of BSS observed)
869 *
870 * Return: NA.
871 */
872
873void sap_interference_rssi_count_5G(tSapSpectChInfo *spect_ch,
874 uint16_t chan_width,
875 uint16_t sec_chan_offset,
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -0700876 uint16_t center_freq,
877 uint16_t center_freq_2,
878 uint8_t channel_id)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800879{
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -0700880 uint16_t num_ch;
881 int32_t offset = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800882 if (NULL == spect_ch) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530883 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800884 FL("spect_ch is NULL"));
885 return;
886 }
887
888 /* Updating the received ChannelWidth */
889 if (spect_ch->channelWidth != chan_width)
890 spect_ch->channelWidth = chan_width;
891 /* If received ChannelWidth is other than HT20,
892 * we need to update the extension channel Params as well
893 * chan_width == 0, HT20
894 * chan_width == 1, HT40
895 * chan_width == 2, VHT80
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -0700896 * chan_width == 3, VHT160
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800897 */
898
899 switch (spect_ch->channelWidth) {
900 case eHT_CHANNEL_WIDTH_40MHZ: /* HT40 */
901 switch (sec_chan_offset) {
902 /* Above the Primary Channel */
903 case PHY_DOUBLE_CHANNEL_LOW_PRIMARY:
904 sap_update_rssi_bsscount(spect_ch, 1, false);
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -0700905 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800906
907 /* Below the Primary channel */
908 case PHY_DOUBLE_CHANNEL_HIGH_PRIMARY:
909 sap_update_rssi_bsscount(spect_ch, -1, false);
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -0700910 return;
911 }
912 return;
913 case eHT_CHANNEL_WIDTH_80MHZ: /* VHT80 */
914 num_ch = 3;
915 if ((center_freq - channel_id) == 6) {
916 offset = 1;
917 } else if ((center_freq - channel_id) == 2) {
918 offset = -1;
919 } else if ((center_freq - channel_id) == -2) {
920 offset = -2;
921 } else if ((center_freq - channel_id) == -6) {
922 offset = -3;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800923 }
924 break;
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -0700925 case eHT_CHANNEL_WIDTH_160MHZ: /* VHT160 */
926 num_ch = 7;
927 if ((center_freq - channel_id) == 14)
928 offset = 1;
929 else if ((center_freq - channel_id) == 10)
930 offset = -1;
931 else if ((center_freq - channel_id) == 6)
932 offset = -2;
933 else if ((center_freq - channel_id) == 2)
934 offset = -3;
935 else if ((center_freq - channel_id) == -2)
936 offset = -4;
937 else if ((center_freq - channel_id) == -6)
938 offset = -5;
939 else if ((center_freq - channel_id) == -10)
940 offset = -6;
941 else if ((center_freq - channel_id) == -14)
942 offset = -7;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800943 break;
944 default:
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -0700945 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800946 }
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -0700947 sap_update_rssi_bsscount_vht_5G(spect_ch, offset, num_ch);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800948}
949
950/**
951 * sap_interference_rssi_count() - sap_interference_rssi_count
952 * considers the Adjacent channel rssi
953 * and data count(here number of BSS observed)
954 * @spect_ch Channel Information
955 *
956 * sap_interference_rssi_count considers the Adjacent channel rssi
957 * and data count(here number of BSS observed)
958 *
959 * Return: None.
960 */
961
962void sap_interference_rssi_count(tSapSpectChInfo *spect_ch)
963{
964 if (NULL == spect_ch) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530965 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800966 "%s: spect_ch is NULL", __func__);
967 return;
968 }
969
970 switch (spect_ch->chNum) {
971 case CHANNEL_1:
972 sap_update_rssi_bsscount(spect_ch, 1, true);
973 sap_update_rssi_bsscount(spect_ch, 2, true);
974 sap_update_rssi_bsscount(spect_ch, 3, true);
975 sap_update_rssi_bsscount(spect_ch, 4, true);
976 break;
977
978 case CHANNEL_2:
979 sap_update_rssi_bsscount(spect_ch, -1, true);
980 sap_update_rssi_bsscount(spect_ch, 1, true);
981 sap_update_rssi_bsscount(spect_ch, 2, true);
982 sap_update_rssi_bsscount(spect_ch, 3, true);
983 sap_update_rssi_bsscount(spect_ch, 4, true);
984 break;
985 case CHANNEL_3:
986 sap_update_rssi_bsscount(spect_ch, -2, true);
987 sap_update_rssi_bsscount(spect_ch, -1, true);
988 sap_update_rssi_bsscount(spect_ch, 1, true);
989 sap_update_rssi_bsscount(spect_ch, 2, true);
990 sap_update_rssi_bsscount(spect_ch, 3, true);
991 sap_update_rssi_bsscount(spect_ch, 4, true);
992 break;
993 case CHANNEL_4:
994 sap_update_rssi_bsscount(spect_ch, -3, true);
995 sap_update_rssi_bsscount(spect_ch, -2, true);
996 sap_update_rssi_bsscount(spect_ch, -1, true);
997 sap_update_rssi_bsscount(spect_ch, 1, true);
998 sap_update_rssi_bsscount(spect_ch, 2, true);
999 sap_update_rssi_bsscount(spect_ch, 3, true);
1000 sap_update_rssi_bsscount(spect_ch, 4, true);
1001 break;
1002
1003 case CHANNEL_5:
1004 case CHANNEL_6:
1005 case CHANNEL_7:
1006 case CHANNEL_8:
1007 case CHANNEL_9:
1008 case CHANNEL_10:
1009 sap_update_rssi_bsscount(spect_ch, -4, true);
1010 sap_update_rssi_bsscount(spect_ch, -3, true);
1011 sap_update_rssi_bsscount(spect_ch, -2, true);
1012 sap_update_rssi_bsscount(spect_ch, -1, true);
1013 sap_update_rssi_bsscount(spect_ch, 1, true);
1014 sap_update_rssi_bsscount(spect_ch, 2, true);
1015 sap_update_rssi_bsscount(spect_ch, 3, true);
1016 sap_update_rssi_bsscount(spect_ch, 4, true);
1017 break;
1018
1019 case CHANNEL_11:
1020 sap_update_rssi_bsscount(spect_ch, -4, true);
1021 sap_update_rssi_bsscount(spect_ch, -3, true);
1022 sap_update_rssi_bsscount(spect_ch, -2, true);
1023 sap_update_rssi_bsscount(spect_ch, -1, true);
1024 sap_update_rssi_bsscount(spect_ch, 1, true);
1025 sap_update_rssi_bsscount(spect_ch, 2, true);
1026 sap_update_rssi_bsscount(spect_ch, 3, true);
1027 break;
1028
1029 case CHANNEL_12:
1030 sap_update_rssi_bsscount(spect_ch, -4, true);
1031 sap_update_rssi_bsscount(spect_ch, -3, true);
1032 sap_update_rssi_bsscount(spect_ch, -2, true);
1033 sap_update_rssi_bsscount(spect_ch, -1, true);
1034 sap_update_rssi_bsscount(spect_ch, 1, true);
1035 sap_update_rssi_bsscount(spect_ch, 2, true);
1036 break;
1037
1038 case CHANNEL_13:
1039 sap_update_rssi_bsscount(spect_ch, -4, true);
1040 sap_update_rssi_bsscount(spect_ch, -3, true);
1041 sap_update_rssi_bsscount(spect_ch, -2, true);
1042 sap_update_rssi_bsscount(spect_ch, -1, true);
1043 sap_update_rssi_bsscount(spect_ch, 1, true);
1044 break;
1045
1046 case CHANNEL_14:
1047 sap_update_rssi_bsscount(spect_ch, -4, true);
1048 sap_update_rssi_bsscount(spect_ch, -3, true);
1049 sap_update_rssi_bsscount(spect_ch, -2, true);
1050 sap_update_rssi_bsscount(spect_ch, -1, true);
1051 break;
1052
1053 default:
1054 break;
1055 }
1056}
1057
1058/*==========================================================================
1059 Function ch_in_pcl
1060
1061 Description
1062 Check if a channel is in the preferred channel list
1063
1064 Parameters
1065 sap_ctx SAP context pointer
1066 channel input channel number
1067
1068 Return Value
1069 true: channel is in PCL
1070 false: channel is not in PCL
1071 ==========================================================================*/
1072bool ch_in_pcl(ptSapContext sap_ctx, uint8_t channel)
1073{
1074 uint32_t i;
1075
1076 for (i = 0; i < sap_ctx->acs_cfg->pcl_ch_count; i++) {
1077 if (channel == sap_ctx->acs_cfg->pcl_channels[i])
1078 return true;
1079 }
1080
1081 return false;
1082}
1083
1084/*==========================================================================
1085 FUNCTION sap_compute_spect_weight
1086
1087 DESCRIPTION
1088 Main function for computing the weight of each channel in the
1089 spectrum based on the RSSI value of the BSSes on the channel
1090 and number of BSS
1091
1092 DEPENDENCIES
1093 NA.
1094
1095 PARAMETERS
1096
1097 IN
1098 pSpectInfoParams : Pointer to the tSpectInfoParams structure
1099 halHandle : Pointer to HAL handle
1100 pResult : Pointer to tScanResultHandle
1101
1102 RETURN VALUE
1103 void : NULL
1104
1105 SIDE EFFECTS
1106 ============================================================================*/
1107void sap_compute_spect_weight(tSapChSelSpectInfo *pSpectInfoParams,
1108 tHalHandle halHandle, tScanResultHandle pResult,
1109 ptSapContext sap_ctx)
1110{
1111 int8_t rssi = 0;
1112 uint8_t chn_num = 0;
1113 uint8_t channel_id = 0;
1114
1115 tCsrScanResultInfo *pScanResult;
1116 tSapSpectChInfo *pSpectCh = pSpectInfoParams->pSpectCh;
1117 uint32_t operatingBand;
1118 uint16_t channelWidth;
1119 uint16_t secondaryChannelOffset;
1120 uint16_t centerFreq;
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001121 uint16_t centerFreq_2 = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001122 uint16_t vhtSupport;
1123 uint32_t ieLen = 0;
1124 tSirProbeRespBeacon *pBeaconStruct;
1125 tpAniSirGlobal pMac = (tpAniSirGlobal) halHandle;
1126
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301127 pBeaconStruct = qdf_mem_malloc(sizeof(tSirProbeRespBeacon));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001128 if (NULL == pBeaconStruct) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301129 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001130 "Unable to allocate memory in sap_compute_spect_weight\n");
1131 return;
1132 }
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301133 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001134 "In %s, Computing spectral weight", __func__);
1135
1136 /**
1137 * Soft AP specific channel weight calculation using DFS formula
1138 */
1139 SET_ACS_BAND(operatingBand, sap_ctx);
1140
1141 pScanResult = sme_scan_result_get_first(halHandle, pResult);
1142
1143 while (pScanResult) {
1144 pSpectCh = pSpectInfoParams->pSpectCh;
1145 /* Defining the default values, so that any value will hold the default values */
1146 channelWidth = eHT_CHANNEL_WIDTH_20MHZ;
1147 secondaryChannelOffset = PHY_SINGLE_CHANNEL_CENTERED;
1148 vhtSupport = 0;
1149 centerFreq = 0;
1150
1151 if (pScanResult->BssDescriptor.ieFields != NULL) {
1152 ieLen =
1153 (pScanResult->BssDescriptor.length +
1154 sizeof(uint16_t) + sizeof(uint32_t) -
1155 sizeof(tSirBssDescription));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301156 qdf_mem_set((uint8_t *) pBeaconStruct,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001157 sizeof(tSirProbeRespBeacon), 0);
1158
1159 if ((sir_parse_beacon_ie
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001160 (pMac, pBeaconStruct, (uint8_t *)
1161 (pScanResult->BssDescriptor.ieFields),
1162 ieLen)) == eSIR_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001163 sap_upd_chan_spec_params(pBeaconStruct,
1164 &channelWidth, &secondaryChannelOffset,
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001165 &vhtSupport, &centerFreq,
1166 &centerFreq_2);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001167 }
1168 }
1169 /* Processing for each tCsrScanResultInfo in the tCsrScanResult DLink list */
1170 for (chn_num = 0; chn_num < pSpectInfoParams->numSpectChans;
1171 chn_num++) {
1172
1173 /*
1174 * if the Beacon has channel ID, use it other wise we will
1175 * rely on the channelIdSelf
1176 */
1177 if (pScanResult->BssDescriptor.channelId == 0)
1178 channel_id =
1179 pScanResult->BssDescriptor.channelIdSelf;
1180 else
1181 channel_id =
1182 pScanResult->BssDescriptor.channelId;
1183
1184 if (pSpectCh && (channel_id == pSpectCh->chNum)) {
1185 if (pSpectCh->rssiAgr <
1186 pScanResult->BssDescriptor.rssi)
1187 pSpectCh->rssiAgr =
1188 pScanResult->BssDescriptor.rssi;
1189
1190 ++pSpectCh->bssCount; /* Increment the count of BSS */
1191
1192 /*
1193 * Connsidering the Extension Channel
1194 * only in a channels
1195 */
1196 switch (operatingBand) {
1197 case eCSR_DOT11_MODE_11a:
1198 sap_interference_rssi_count_5G(
1199 pSpectCh, channelWidth,
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001200 secondaryChannelOffset,
1201 centerFreq,
1202 centerFreq_2,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001203 channel_id);
1204 break;
1205
1206 case eCSR_DOT11_MODE_11g:
1207 sap_interference_rssi_count(pSpectCh);
1208 break;
1209
1210 case eCSR_DOT11_MODE_abg:
1211 sap_interference_rssi_count_5G(
1212 pSpectCh, channelWidth,
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001213 secondaryChannelOffset,
1214 centerFreq,
1215 centerFreq_2,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001216 channel_id);
1217 sap_interference_rssi_count(pSpectCh);
1218 break;
1219 }
1220
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301221 QDF_TRACE(QDF_MODULE_ID_SAP,
1222 QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001223 "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",
1224 __func__,
1225 pScanResult->BssDescriptor.
1226 channelIdSelf,
1227 pScanResult->BssDescriptor.channelId,
1228 pScanResult->BssDescriptor.rssi,
1229 pSpectCh->bssCount, pScanResult,
1230 pSpectCh->channelWidth,
1231 secondaryChannelOffset, centerFreq);
1232 pSpectCh++;
1233 break;
1234 } else {
1235 pSpectCh++;
1236 }
1237 }
1238
1239 pScanResult = sme_scan_result_get_next(halHandle, pResult);
1240 }
1241
1242 /* Calculate the weights for all channels in the spectrum pSpectCh */
1243 pSpectCh = pSpectInfoParams->pSpectCh;
1244
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301245 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001246 "In %s, Spectrum Channels Weight", __func__);
1247
1248 for (chn_num = 0; chn_num < (pSpectInfoParams->numSpectChans);
1249 chn_num++) {
1250
1251 /*
1252 rssi : Maximum received signal strength among all BSS on that channel
1253 bssCount : Number of BSS on that channel
1254 */
1255
1256 rssi = (int8_t) pSpectCh->rssiAgr;
1257 if (ch_in_pcl(sap_ctx, chn_num))
1258 rssi -= PCL_RSSI_DISCOUNT;
1259
1260 pSpectCh->weight =
1261 SAPDFS_NORMALISE_1000 * sapweight_rssi_count(rssi,
1262 pSpectCh->
1263 bssCount);
1264 pSpectCh->weight_copy = pSpectCh->weight;
1265
1266 /* ------ Debug Info ------ */
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301267 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001268 "In %s, Chan=%d Weight= %d rssiAgr=%d bssCount=%d",
1269 __func__, pSpectCh->chNum, pSpectCh->weight,
1270 pSpectCh->rssiAgr, pSpectCh->bssCount);
1271 /* ------ Debug Info ------ */
1272 pSpectCh++;
1273 }
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301274 qdf_mem_free(pBeaconStruct);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001275}
1276
1277/*==========================================================================
1278 FUNCTION sap_chan_sel_exit
1279
1280 DESCRIPTION
1281 Exit function for free out the allocated memory, to be called
1282 at the end of the dfsSelectChannel function
1283
1284 DEPENDENCIES
1285 NA.
1286
1287 PARAMETERS
1288
1289 IN
1290 pSpectInfoParams : Pointer to the tSapChSelSpectInfo structure
1291
1292 RETURN VALUE
1293 void : NULL
1294
1295 SIDE EFFECTS
1296 ============================================================================*/
1297void sap_chan_sel_exit(tSapChSelSpectInfo *pSpectInfoParams)
1298{
1299 /* Free all the allocated memory */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301300 qdf_mem_free(pSpectInfoParams->pSpectCh);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001301}
1302
1303/*==========================================================================
1304 FUNCTION sap_sort_chl_weight
1305
1306 DESCRIPTION
1307 Funtion to sort the channels with the least weight first for 20MHz channels
1308
1309 DEPENDENCIES
1310 NA.
1311
1312 PARAMETERS
1313
1314 IN
1315 pSpectInfoParams : Pointer to the tSapChSelSpectInfo structure
1316
1317 RETURN VALUE
1318 void : NULL
1319
1320 SIDE EFFECTS
1321 ============================================================================*/
1322void sap_sort_chl_weight(tSapChSelSpectInfo *pSpectInfoParams)
1323{
1324 tSapSpectChInfo temp;
1325
1326 tSapSpectChInfo *pSpectCh = NULL;
1327 uint32_t i = 0, j = 0, minWeightIndex = 0;
1328
1329 pSpectCh = pSpectInfoParams->pSpectCh;
1330 for (i = 0; i < pSpectInfoParams->numSpectChans; i++) {
1331 minWeightIndex = i;
1332 for (j = i + 1; j < pSpectInfoParams->numSpectChans; j++) {
1333 if (pSpectCh[j].weight <
1334 pSpectCh[minWeightIndex].weight) {
1335 minWeightIndex = j;
1336 }
1337 }
1338 if (minWeightIndex != i) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301339 qdf_mem_copy(&temp, &pSpectCh[minWeightIndex],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001340 sizeof(*pSpectCh));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301341 qdf_mem_copy(&pSpectCh[minWeightIndex], &pSpectCh[i],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001342 sizeof(*pSpectCh));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301343 qdf_mem_copy(&pSpectCh[i], &temp, sizeof(*pSpectCh));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001344 }
1345 }
1346}
1347
1348/**
1349 * sap_sort_chl_weight_ht80() - to sort the channels with the least weight
1350 * @pSpectInfoParams: Pointer to the tSapChSelSpectInfo structure
1351 *
1352 * Funtion to sort the channels with the least weight first for HT80 channels
1353 *
1354 * Return: none
1355 */
1356void sap_sort_chl_weight_ht80(tSapChSelSpectInfo *pSpectInfoParams)
1357{
1358 uint8_t i, j, n;
1359 tSapSpectChInfo *pSpectInfo;
1360 uint8_t minIdx;
1361
1362 pSpectInfo = pSpectInfoParams->pSpectCh;
1363 /* for each HT80 channel, calculate the combined weight of the
1364 four 20MHz weight */
1365 for (i = 0; i < ARRAY_SIZE(acs_ht80_channels); i++) {
1366 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
1367 if (pSpectInfo[j].chNum ==
1368 acs_ht80_channels[i].chStartNum)
1369 break;
1370 }
1371 if (j == pSpectInfoParams->numSpectChans)
1372 continue;
1373
1374 if (!(((pSpectInfo[j].chNum + 4) == pSpectInfo[j + 1].chNum) &&
1375 ((pSpectInfo[j].chNum + 8) ==
1376 pSpectInfo[j + 2].chNum) &&
1377 ((pSpectInfo[j].chNum + 12) ==
1378 pSpectInfo[j + 3].chNum))) {
1379 /*
1380 * some channels does not exist in pSectInfo array,
1381 * skip this channel and those in the same HT80 width
1382 */
1383 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 4;
1384 if ((pSpectInfo[j].chNum + 4) ==
1385 pSpectInfo[j + 1].chNum)
1386 pSpectInfo[j + 1].weight =
1387 SAP_ACS_WEIGHT_MAX * 4;
1388 if ((pSpectInfo[j].chNum + 8) ==
1389 pSpectInfo[j + 2].chNum)
1390 pSpectInfo[j + 2].weight =
1391 SAP_ACS_WEIGHT_MAX * 4;
1392 if ((pSpectInfo[j].chNum + 12) ==
1393 pSpectInfo[j + 3].chNum)
1394 pSpectInfo[j + 3].weight =
1395 SAP_ACS_WEIGHT_MAX * 4;
1396 continue;
1397 }
1398 /*found the channel, add the 4 adjacent channels' weight */
1399 acs_ht80_channels[i].weight = pSpectInfo[j].weight +
1400 pSpectInfo[j + 1].weight + pSpectInfo[j + 2].weight +
1401 pSpectInfo[j + 3].weight;
1402 /* find best channel among 4 channels as the primary channel */
1403 if ((pSpectInfo[j].weight + pSpectInfo[j + 1].weight) <
1404 (pSpectInfo[j + 2].weight + pSpectInfo[j + 3].weight)) {
1405 /* lower 2 channels are better choice */
1406 if (pSpectInfo[j].weight < pSpectInfo[j + 1].weight)
1407 minIdx = 0;
1408 else
1409 minIdx = 1;
1410 } else if (pSpectInfo[j + 2].weight <=
1411 pSpectInfo[j + 3].weight) {
1412 /* upper 2 channels are better choice */
1413 minIdx = 2;
1414 } else {
1415 minIdx = 3;
1416 }
1417
1418 /*
1419 * set all 4 channels to max value first, then reset the
1420 * best channel as the selected primary channel, update its
1421 * weightage with the combined weight value
1422 */
1423 for (n = 0; n < 4; n++)
1424 pSpectInfo[j + n].weight = SAP_ACS_WEIGHT_MAX * 4;
1425
1426 pSpectInfo[j + minIdx].weight = acs_ht80_channels[i].weight;
1427 }
1428
1429 pSpectInfo = pSpectInfoParams->pSpectCh;
1430 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
1431 if (CHANNEL_165 == pSpectInfo[j].chNum) {
1432 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 4;
1433 break;
1434 }
1435 }
1436
Manishekar Chandrasekaran44e334f2016-05-30 16:42:50 +05301437 sap_sort_chl_weight(pSpectInfoParams);
1438
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001439 pSpectInfo = pSpectInfoParams->pSpectCh;
1440 for (j = 0; j < (pSpectInfoParams->numSpectChans); j++) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301441 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001442 FL("Channel=%d Weight= %d rssi=%d bssCount=%d"),
1443 pSpectInfo->chNum, pSpectInfo->weight,
1444 pSpectInfo->rssiAgr, pSpectInfo->bssCount);
1445 pSpectInfo++;
1446 }
1447}
1448
1449/**
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001450 * sap_sort_chl_weight_vht160() - to sort the channels with the least weight
1451 * @pSpectInfoParams: Pointer to the tSapChSelSpectInfo structure
1452 *
1453 * Funtion to sort the channels with the least weight first for VHT160 channels
1454 *
1455 * Return: none
1456 */
1457void sap_sort_chl_weight_vht160(tSapChSelSpectInfo *pSpectInfoParams)
1458{
1459 uint8_t i, j, n, idx;
1460 tSapSpectChInfo *pSpectInfo;
1461 uint8_t minIdx;
1462
1463 pSpectInfo = pSpectInfoParams->pSpectCh;
1464 /* for each VHT160 channel, calculate the combined weight of the
1465 8 20MHz weight */
1466 for (i = 0; i < ARRAY_SIZE(acs_vht160_channels); i++) {
1467 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
1468 if (pSpectInfo[j].chNum ==
1469 acs_vht160_channels[i].chStartNum)
1470 break;
1471 }
1472 if (j == pSpectInfoParams->numSpectChans)
1473 continue;
1474
1475 if (!(((pSpectInfo[j].chNum + 4) == pSpectInfo[j + 1].chNum) &&
1476 ((pSpectInfo[j].chNum + 8) ==
1477 pSpectInfo[j + 2].chNum) &&
1478 ((pSpectInfo[j].chNum + 12) ==
1479 pSpectInfo[j + 3].chNum) &&
1480 ((pSpectInfo[j].chNum + 16) ==
1481 pSpectInfo[j + 4].chNum) &&
1482 ((pSpectInfo[j].chNum + 20) ==
1483 pSpectInfo[j + 5].chNum) &&
1484 ((pSpectInfo[j].chNum + 24) ==
1485 pSpectInfo[j + 6].chNum) &&
1486 ((pSpectInfo[j].chNum + 28) ==
1487 pSpectInfo[j + 7].chNum))) {
1488 /*
1489 * some channels does not exist in pSectInfo array,
1490 * skip this channel and those in the same VHT160 width
1491 */
1492 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 8;
1493 if ((pSpectInfo[j].chNum + 4) ==
1494 pSpectInfo[j + 1].chNum)
1495 pSpectInfo[j + 1].weight =
1496 SAP_ACS_WEIGHT_MAX * 8;
1497 if ((pSpectInfo[j].chNum + 8) ==
1498 pSpectInfo[j + 2].chNum)
1499 pSpectInfo[j + 2].weight =
1500 SAP_ACS_WEIGHT_MAX * 8;
1501 if ((pSpectInfo[j].chNum + 12) ==
1502 pSpectInfo[j + 3].chNum)
1503 pSpectInfo[j + 3].weight =
1504 SAP_ACS_WEIGHT_MAX * 8;
1505 if ((pSpectInfo[j].chNum + 16) ==
1506 pSpectInfo[j + 4].chNum)
1507 pSpectInfo[j + 4].weight =
1508 SAP_ACS_WEIGHT_MAX * 8;
1509 if ((pSpectInfo[j].chNum + 20) ==
1510 pSpectInfo[j + 5].chNum)
1511 pSpectInfo[j + 5].weight =
1512 SAP_ACS_WEIGHT_MAX * 8;
1513 if ((pSpectInfo[j].chNum + 24) ==
1514 pSpectInfo[j + 6].chNum)
1515 pSpectInfo[j + 6].weight =
1516 SAP_ACS_WEIGHT_MAX * 8;
1517 if ((pSpectInfo[j].chNum + 28) ==
1518 pSpectInfo[j + 7].chNum)
1519 pSpectInfo[j + 7].weight =
1520 SAP_ACS_WEIGHT_MAX * 8;
1521 continue;
1522 }
1523 /*found the channel, add the 7 adjacent channels' weight */
1524 acs_vht160_channels[i].weight = pSpectInfo[j].weight +
1525 pSpectInfo[j + 1].weight + pSpectInfo[j + 2].weight +
1526 pSpectInfo[j + 3].weight + pSpectInfo[j + 4].weight +
1527 pSpectInfo[j + 5].weight + pSpectInfo[j + 6].weight +
1528 pSpectInfo[j + 7].weight;
1529
1530 /* find best channel among 8 channels as the primary channel */
1531 if ((pSpectInfo[j].weight + pSpectInfo[j + 1].weight +
1532 pSpectInfo[j + 2].weight + pSpectInfo[j + 3].weight) >
1533 (pSpectInfo[j + 4].weight + pSpectInfo[j + 5].weight +
1534 pSpectInfo[j + 6].weight + pSpectInfo[j + 7].weight))
1535 idx = 4;
1536 else
1537 idx = 0;
1538 /* find best channel among 4 channels as the primary channel */
1539 if ((pSpectInfo[j + idx].weight +
1540 pSpectInfo[j + idx + 1].weight) <
1541 (pSpectInfo[j + idx + 2].weight +
1542 pSpectInfo[j + idx + 3].weight)) {
1543 /* lower 2 channels are better choice */
1544 if (pSpectInfo[j + idx].weight <
1545 pSpectInfo[j + idx + 1].weight)
1546 minIdx = 0 + idx;
1547 else
1548 minIdx = 1 + idx;
1549 } else if (pSpectInfo[j + idx + 2].weight <=
1550 pSpectInfo[j + idx + 3].weight) {
1551 /* upper 2 channels are better choice */
1552 minIdx = 2 + idx;
1553 } else {
1554 minIdx = 3 + idx;
1555 }
1556
1557 /*
1558 * set all 8 channels to max value first, then reset the
1559 * best channel as the selected primary channel, update its
1560 * weightage with the combined weight value
1561 */
1562 for (n = 0; n < 8; n++)
1563 pSpectInfo[j + n].weight = SAP_ACS_WEIGHT_MAX * 8;
1564
1565 pSpectInfo[j + minIdx].weight = acs_vht160_channels[i].weight;
1566 }
1567
1568 pSpectInfo = pSpectInfoParams->pSpectCh;
1569 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
1570 if (CHANNEL_165 == pSpectInfo[j].chNum) {
1571 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 8;
1572 break;
1573 }
1574 }
1575
Manishekar Chandrasekaran44e334f2016-05-30 16:42:50 +05301576 sap_sort_chl_weight(pSpectInfoParams);
1577
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001578 pSpectInfo = pSpectInfoParams->pSpectCh;
1579 for (j = 0; j < (pSpectInfoParams->numSpectChans); j++) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301580 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001581 FL("Channel=%d Weight= %d rssi=%d bssCount=%d"),
1582 pSpectInfo->chNum, pSpectInfo->weight,
1583 pSpectInfo->rssiAgr, pSpectInfo->bssCount);
1584 pSpectInfo++;
1585 }
1586}
1587
1588/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001589 * sap_sort_chl_weight_ht40_24_g() - to sort channel with the least weight
1590 * @pSpectInfoParams: Pointer to the tSapChSelSpectInfo structure
1591 *
1592 * Funtion to sort the channels with the least weight first for HT40 channels
1593 *
1594 * Return: none
1595 */
1596void sap_sort_chl_weight_ht40_24_g(tSapChSelSpectInfo *pSpectInfoParams)
1597{
1598 uint8_t i, j;
1599 tSapSpectChInfo *pSpectInfo;
1600 uint32_t tmpWeight1, tmpWeight2;
1601
1602 pSpectInfo = pSpectInfoParams->pSpectCh;
1603 /*
1604 * for each HT40 channel, calculate the combined weight of the
1605 * two 20MHz weight
1606 */
1607 for (i = 0; i < ARRAY_SIZE(acs_ht40_channels24_g); i++) {
1608 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
1609 if (pSpectInfo[j].chNum ==
1610 acs_ht40_channels24_g[i].chStartNum)
1611 break;
1612 }
1613 if (j == pSpectInfoParams->numSpectChans)
1614 continue;
1615
1616 if (!((pSpectInfo[j].chNum + 4) == pSpectInfo[j + 4].chNum)) {
1617 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2;
1618 continue;
1619 }
1620 /*
1621 * check if there is another channel combination possiblity
1622 * e.g., {1, 5} & {5, 9}
1623 */
1624 if ((pSpectInfo[j + 4].chNum + 4) == pSpectInfo[j + 8].chNum) {
1625 /* need to compare two channel pairs */
1626 tmpWeight1 = pSpectInfo[j].weight +
1627 pSpectInfo[j + 4].weight;
1628 tmpWeight2 = pSpectInfo[j + 4].weight +
1629 pSpectInfo[j + 8].weight;
1630 if (tmpWeight1 <= tmpWeight2) {
1631 if (pSpectInfo[j].weight <=
1632 pSpectInfo[j + 4].weight) {
1633 pSpectInfo[j].weight =
1634 tmpWeight1;
1635 pSpectInfo[j + 4].weight =
1636 SAP_ACS_WEIGHT_MAX * 2;
1637 pSpectInfo[j + 8].weight =
1638 SAP_ACS_WEIGHT_MAX * 2;
1639 } else {
1640 pSpectInfo[j + 4].weight =
1641 tmpWeight1;
1642 /* for secondary channel selection */
1643 pSpectInfo[j].weight =
1644 SAP_ACS_WEIGHT_MAX * 2
1645 - 1;
1646 pSpectInfo[j + 8].weight =
1647 SAP_ACS_WEIGHT_MAX * 2;
1648 }
1649 } else {
1650 if (pSpectInfo[j + 4].weight <=
1651 pSpectInfo[j + 8].weight) {
1652 pSpectInfo[j + 4].weight =
1653 tmpWeight2;
1654 pSpectInfo[j].weight =
1655 SAP_ACS_WEIGHT_MAX * 2;
1656 /* for secondary channel selection */
1657 pSpectInfo[j + 8].weight =
1658 SAP_ACS_WEIGHT_MAX * 2
1659 - 1;
1660 } else {
1661 pSpectInfo[j + 8].weight =
1662 tmpWeight2;
1663 pSpectInfo[j].weight =
1664 SAP_ACS_WEIGHT_MAX * 2;
1665 pSpectInfo[j + 4].weight =
1666 SAP_ACS_WEIGHT_MAX * 2;
1667 }
1668 }
1669 } else {
1670 tmpWeight1 = pSpectInfo[j].weight +
1671 pSpectInfo[j + 4].weight;
1672 if (pSpectInfo[j].weight <=
1673 pSpectInfo[j + 4].weight) {
1674 pSpectInfo[j].weight = tmpWeight1;
1675 pSpectInfo[j + 4].weight =
1676 SAP_ACS_WEIGHT_MAX * 2;
1677 } else {
1678 pSpectInfo[j + 4].weight = tmpWeight1;
1679 pSpectInfo[j].weight =
1680 SAP_ACS_WEIGHT_MAX * 2;
1681 }
1682 }
1683 }
Manishekar Chandrasekaran44e334f2016-05-30 16:42:50 +05301684 sap_sort_chl_weight(pSpectInfoParams);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001685}
1686
1687/*==========================================================================
1688 FUNCTION sap_sort_chl_weight_ht40_5_g
1689
1690 DESCRIPTION
1691 Funtion to sort the channels with the least weight first for HT40 channels
1692
1693 DEPENDENCIES
1694 NA.
1695
1696 PARAMETERS
1697
1698 IN
1699 pSpectInfoParams : Pointer to the tSapChSelSpectInfo structure
1700
1701 RETURN VALUE
1702 void : NULL
1703
1704 SIDE EFFECTS
1705 ============================================================================*/
1706void sap_sort_chl_weight_ht40_5_g(tSapChSelSpectInfo *pSpectInfoParams)
1707{
1708 uint8_t i, j;
1709 tSapSpectChInfo *pSpectInfo;
1710
1711 pSpectInfo = pSpectInfoParams->pSpectCh;
1712 /*for each HT40 channel, calculate the combined weight of the
1713 two 20MHz weight */
1714 for (i = 0; i < ARRAY_SIZE(acs_ht40_channels5_g); i++) {
1715 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
1716 if (pSpectInfo[j].chNum ==
1717 acs_ht40_channels5_g[i].chStartNum)
1718 break;
1719 }
1720 if (j == pSpectInfoParams->numSpectChans)
1721 continue;
1722
1723 /* found the channel, add the two adjacent channels' weight */
1724 if ((pSpectInfo[j].chNum + 4) == pSpectInfo[j + 1].chNum) {
1725 acs_ht40_channels5_g[i].weight = pSpectInfo[j].weight +
1726 pSpectInfo[j + 1].weight;
1727 /* select better of the adjact channel as the primary channel */
1728 if (pSpectInfo[j].weight <= pSpectInfo[j + 1].weight) {
1729 pSpectInfo[j].weight =
1730 acs_ht40_channels5_g[i].weight;
1731 /* mark the adjacent channel's weight as max value so
1732 that it will be sorted to the bottom */
1733 pSpectInfo[j + 1].weight =
1734 SAP_ACS_WEIGHT_MAX * 2;
1735 } else {
1736 pSpectInfo[j + 1].weight =
1737 acs_ht40_channels5_g[i].weight;
1738 /* mark the adjacent channel's weight as max value so
1739 that it will be sorted to the bottom */
1740 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2;
1741 }
1742
1743 } else
1744 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2;
1745 }
1746
1747 /* avoid channel 165 by setting its weight to max */
1748 pSpectInfo = pSpectInfoParams->pSpectCh;
1749 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
1750 if (CHANNEL_165 == pSpectInfo[j].chNum) {
1751 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2;
1752 break;
1753 }
1754 }
1755
1756 pSpectInfo = pSpectInfoParams->pSpectCh;
1757 for (j = 0; j < (pSpectInfoParams->numSpectChans); j++) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301758 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001759 "In %s, Channel=%d Weight= %d rssi=%d bssCount=%d",
1760 __func__, pSpectInfo->chNum, pSpectInfo->weight,
1761 pSpectInfo->rssiAgr, pSpectInfo->bssCount);
1762 pSpectInfo++;
1763 }
1764
1765 sap_sort_chl_weight(pSpectInfoParams);
1766}
1767
1768/*==========================================================================
1769 FUNCTION sap_sort_chl_weight_all
1770
1771 DESCRIPTION
1772 Funtion to sort the channels with the least weight first
1773
1774 DEPENDENCIES
1775 NA.
1776
1777 PARAMETERS
1778
1779 IN
1780 ptSapContext : Pointer to the ptSapContext structure
1781 pSpectInfoParams : Pointer to the tSapChSelSpectInfo structure
1782
1783 RETURN VALUE
1784 void : NULL
1785
1786 SIDE EFFECTS
1787 ============================================================================*/
1788void sap_sort_chl_weight_all(ptSapContext pSapCtx,
1789 tSapChSelSpectInfo *pSpectInfoParams,
1790 uint32_t operatingBand)
1791{
1792 tSapSpectChInfo *pSpectCh = NULL;
1793 uint32_t j = 0;
1794#ifndef SOFTAP_CHANNEL_RANGE
1795 uint32_t i = 0;
1796#endif
1797
1798 pSpectCh = pSpectInfoParams->pSpectCh;
1799#ifdef SOFTAP_CHANNEL_RANGE
1800
1801 switch (pSapCtx->acs_cfg->ch_width) {
1802 case CH_WIDTH_40MHZ:
1803 if (eCSR_DOT11_MODE_11g == operatingBand)
1804 sap_sort_chl_weight_ht40_24_g(pSpectInfoParams);
1805 else if (eCSR_DOT11_MODE_11a == operatingBand)
1806 sap_sort_chl_weight_ht40_5_g(pSpectInfoParams);
1807 else {
1808 sap_sort_chl_weight_ht40_24_g(pSpectInfoParams);
1809 sap_sort_chl_weight_ht40_5_g(pSpectInfoParams);
1810 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001811 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001812 case CH_WIDTH_80MHZ:
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001813 case CH_WIDTH_80P80MHZ:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001814 sap_sort_chl_weight_ht80(pSpectInfoParams);
1815 break;
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001816 case CH_WIDTH_160MHZ:
1817 sap_sort_chl_weight_vht160(pSpectInfoParams);
1818 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001819 case CH_WIDTH_20MHZ:
1820 default:
1821 /* Sorting the channels as per weights as 20MHz channels */
1822 sap_sort_chl_weight(pSpectInfoParams);
1823 }
1824
1825#else
1826 /* Sorting the channels as per weights */
1827 for (i = 0; i < SPECT_24GHZ_CH_COUNT; i++) {
1828 minWeightIndex = i;
1829 for (j = i + 1; j < SPECT_24GHZ_CH_COUNT; j++) {
1830 if (pSpectCh[j].weight <
1831 pSpectCh[minWeightIndex].weight) {
1832 minWeightIndex = j;
1833 }
1834 }
1835 if (minWeightIndex != i) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301836 qdf_mem_copy(&temp, &pSpectCh[minWeightIndex],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001837 sizeof(*pSpectCh));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301838 qdf_mem_copy(&pSpectCh[minWeightIndex], &pSpectCh[i],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001839 sizeof(*pSpectCh));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301840 qdf_mem_copy(&pSpectCh[i], &temp, sizeof(*pSpectCh));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001841 }
1842 }
1843#endif
1844
1845 /* For testing */
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301846 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001847 "In %s, Sorted Spectrum Channels Weight", __func__);
1848 pSpectCh = pSpectInfoParams->pSpectCh;
1849 for (j = 0; j < (pSpectInfoParams->numSpectChans); j++) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301850 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001851 "In %s, Channel=%d Weight= %d rssi=%d bssCount=%d",
1852 __func__, pSpectCh->chNum, pSpectCh->weight,
1853 pSpectCh->rssiAgr, pSpectCh->bssCount);
1854 pSpectCh++;
1855 }
1856
1857}
1858
1859/*==========================================================================
1860 FUNCTION sap_filter_over_lap_ch
1861
1862 DESCRIPTION
1863 return true if ch is acceptable.
1864 This function will decide if we will filter over lap channel or not.
1865
1866 DEPENDENCIES
1867 shall called after ap start.
1868
1869 PARAMETERS
1870
1871 IN
1872 pSapCtx : Pointer to ptSapContext.
1873 chNum : Filter channel number.
1874
1875 RETURN VALUE
1876 bool : true if channel is accepted.
1877
1878 SIDE EFFECTS
1879 ============================================================================*/
1880bool sap_filter_over_lap_ch(ptSapContext pSapCtx, uint16_t chNum)
1881{
1882 if (pSapCtx->enableOverLapCh)
1883 return eSAP_TRUE;
1884 else if ((chNum == CHANNEL_1) ||
1885 (chNum == CHANNEL_6) || (chNum == CHANNEL_11))
1886 return eSAP_TRUE;
1887
1888 return eSAP_FALSE;
1889}
1890
Naveen Rawat365d1cb2016-02-05 12:10:43 -08001891/**
1892 * sap_select_channel_no_scan_result() - select SAP channel when no scan results
1893 * are available.
1894 * @sap_ctx: Sap context
1895 *
1896 * Returns: channel number if success, 0 otherwise
1897 */
1898static uint8_t sap_select_channel_no_scan_result(ptSapContext sap_ctx)
1899{
1900 enum channel_state ch_type;
1901 uint32_t start_ch_num, end_ch_num;
1902#ifdef FEATURE_WLAN_CH_AVOID
1903 uint8_t i, first_safe_ch_in_range = SAP_CHANNEL_NOT_SELECTED;
1904#endif
1905 start_ch_num = sap_ctx->acs_cfg->start_ch;
1906 end_ch_num = sap_ctx->acs_cfg->end_ch;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001907
Naveen Rawat365d1cb2016-02-05 12:10:43 -08001908 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
1909 FL("start - end: %d - %d"), start_ch_num, end_ch_num);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001910
Naveen Rawat365d1cb2016-02-05 12:10:43 -08001911#ifndef FEATURE_WLAN_CH_AVOID
1912 sap_ctx->acs_cfg->pri_ch = start_ch_num;
1913 sap_ctx->acs_cfg->ht_sec_ch = 0;
1914 /* pick the first channel in configured range */
1915 return start_ch_num;
1916#else
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001917
Naveen Rawat365d1cb2016-02-05 12:10:43 -08001918 /* get a channel in PCL and within the range */
1919 for (i = 0; i < sap_ctx->acs_cfg->pcl_ch_count; i++) {
1920 if ((sap_ctx->acs_cfg->pcl_channels[i] < start_ch_num) ||
1921 (sap_ctx->acs_cfg->pcl_channels[i] > end_ch_num))
1922 continue;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001923
Naveen Rawat365d1cb2016-02-05 12:10:43 -08001924 first_safe_ch_in_range = sap_ctx->acs_cfg->pcl_channels[i];
1925 break;
1926 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001927
Naveen Rawat365d1cb2016-02-05 12:10:43 -08001928 if (SAP_CHANNEL_NOT_SELECTED != first_safe_ch_in_range)
1929 return first_safe_ch_in_range;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001930
Naveen Rawat365d1cb2016-02-05 12:10:43 -08001931 for (i = 0; i < NUM_CHANNELS; i++) {
1932 if ((safe_channels[i].channelNumber < start_ch_num) ||
1933 (safe_channels[i].channelNumber > end_ch_num))
1934 continue;
1935
1936 ch_type = cds_get_channel_state(safe_channels[i].channelNumber);
1937
1938 if ((ch_type == CHANNEL_STATE_DISABLE) ||
1939 (ch_type == CHANNEL_STATE_INVALID))
1940 continue;
1941
1942 if (safe_channels[i].isSafe == true) {
1943 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
1944 FL("channel %d in the configuration is safe"),
1945 safe_channels[i].channelNumber);
1946 first_safe_ch_in_range = safe_channels[i].channelNumber;
1947 break;
1948 }
1949
1950 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
1951 FL("channel %d in the configuration is unsafe"),
1952 safe_channels[i].channelNumber);
1953 }
1954
1955 /* if no channel selected return SAP_CHANNEL_NOT_SELECTED */
1956 return first_safe_ch_in_range;
1957#endif /* !FEATURE_WLAN_CH_AVOID */
1958}
1959
1960/**
1961 * sap_select_channel() - select SAP channel
1962 * @hal: Pointer to HAL handle
1963 * @sap_ctx: Sap context
1964 * @scan_result: Pointer to tScanResultHandle
1965 *
1966 * Runs a algorithm to select the best channel to operate in based on BSS
1967 * rssi and bss count on each channel
1968 *
1969 * Returns: channel number if success, 0 otherwise
1970 */
1971uint8_t sap_select_channel(tHalHandle hal, ptSapContext sap_ctx,
1972 tScanResultHandle scan_result)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001973{
1974 /* DFS param object holding all the data req by the algo */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08001975 tSapChSelSpectInfo spect_info_obj = { NULL, 0 };
1976 tSapChSelSpectInfo *spect_info = &spect_info_obj;
1977 uint8_t best_ch_num = SAP_CHANNEL_NOT_SELECTED;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001978#ifdef SOFTAP_CHANNEL_RANGE
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001979 uint8_t count;
Naveen Rawat365d1cb2016-02-05 12:10:43 -08001980 uint32_t start_ch_num, end_ch_num, tmp_ch_num, operating_band = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001981#endif
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301982 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001983 "In %s, Running SAP Ch Select", __func__);
1984
1985#ifdef FEATURE_WLAN_CH_AVOID
Naveen Rawat365d1cb2016-02-05 12:10:43 -08001986 sap_update_unsafe_channel_list(sap_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001987#endif
1988
Naveen Rawat365d1cb2016-02-05 12:10:43 -08001989 if (NULL == scan_result) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301990 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Naveen Rawat365d1cb2016-02-05 12:10:43 -08001991 FL("No external AP present"));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001992
1993#ifndef SOFTAP_CHANNEL_RANGE
Naveen Rawat365d1cb2016-02-05 12:10:43 -08001994 return SAP_CHANNEL_NOT_SELECTED;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001995#else
Naveen Rawat365d1cb2016-02-05 12:10:43 -08001996 return sap_select_channel_no_scan_result(sap_ctx);
1997#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001998 }
1999
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002000 /* Initialize the structure pointed by spect_info */
2001 if (sap_chan_sel_init(hal, spect_info, sap_ctx) != eSAP_TRUE) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302002 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002003 FL("Ch Select initialization failed"));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002004 return SAP_CHANNEL_NOT_SELECTED;
2005 }
2006 /* Compute the weight of the entire spectrum in the operating band */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002007 sap_compute_spect_weight(spect_info, hal, scan_result, sap_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002008
2009#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
2010 /* process avoid channel IE to collect all channels to avoid */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002011 sap_process_avoid_ie(hal, sap_ctx, scan_result, spect_info);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002012#endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
2013
2014#ifdef SOFTAP_CHANNEL_RANGE
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002015 start_ch_num = sap_ctx->acs_cfg->start_ch;
2016 end_ch_num = sap_ctx->acs_cfg->end_ch;
2017 SET_ACS_BAND(operating_band, sap_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002018
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002019 sap_ctx->acsBestChannelInfo.channelNum = 0;
2020 sap_ctx->acsBestChannelInfo.weight = SAP_ACS_WEIGHT_MAX;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002021
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002022 /* Sort the ch lst as per the computed weights, lesser weight first. */
2023 sap_sort_chl_weight_all(sap_ctx, spect_info, operating_band);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002024
2025 /*Loop till get the best channel in the given range */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002026 for (count = 0; count < spect_info->numSpectChans; count++) {
2027 if ((start_ch_num > spect_info->pSpectCh[count].chNum) ||
2028 (end_ch_num < spect_info->pSpectCh[count].chNum))
2029 continue;
2030
2031 if (best_ch_num == SAP_CHANNEL_NOT_SELECTED) {
2032 best_ch_num = spect_info->pSpectCh[count].chNum;
2033 /* check if best_ch_num is in preferred channel list */
2034 best_ch_num =
2035 sap_select_preferred_channel_from_channel_list(
2036 best_ch_num, sap_ctx, spect_info);
2037 /* if not in preferred ch lst, go to nxt best ch */
2038 if (best_ch_num == SAP_CHANNEL_NOT_SELECTED)
2039 continue;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002040
2041#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002042 /*
2043 * Weight of the channels(device's AP is operating)
2044 * increased to MAX+1 so that they will be choosen only
2045 * when there is no other best channel to choose
2046 */
2047 if (sap_check_in_avoid_ch_list(sap_ctx, best_ch_num)) {
2048 best_ch_num = SAP_CHANNEL_NOT_SELECTED;
2049 continue;
2050 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002051#endif
2052
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002053 sap_ctx->acsBestChannelInfo.channelNum = best_ch_num;
2054 sap_ctx->acsBestChannelInfo.weight =
2055 spect_info->pSpectCh[count].weight_copy;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002056 }
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002057
2058 if (best_ch_num == SAP_CHANNEL_NOT_SELECTED)
2059 continue;
2060
2061 if (operating_band != eCSR_DOT11_MODE_11g)
2062 continue;
2063
2064 /* Give preference to Non-overlap channels */
2065 if (false == sap_filter_over_lap_ch(sap_ctx,
2066 spect_info->pSpectCh[count].chNum))
2067 continue;
2068
2069 tmp_ch_num = spect_info->pSpectCh[count].chNum;
2070 tmp_ch_num = sap_select_preferred_channel_from_channel_list(
2071 tmp_ch_num, sap_ctx, spect_info);
2072 if (tmp_ch_num == SAP_CHANNEL_NOT_SELECTED)
2073 continue;
2074
2075 best_ch_num = tmp_ch_num;
2076 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002077 }
2078#else
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002079 /* Sort the ch lst as per the computed weights, lesser weight first. */
2080 sap_sort_chl_weight_all(sap_ctx, hal, spect_info);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002081 /* Get the first channel in sorted array as best 20M Channel */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002082 best_ch_num = (uint8_t) spect_info->pSpectCh[0].chNum;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002083 /* Select Best Channel from Channel List if Configured */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002084 best_ch_num = sap_select_preferred_channel_from_channel_list(
2085 best_ch_num, sap_ctx, spect_info);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002086#endif
2087
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002088 /*
2089 * in case the best channel seleted is not in PCL and there is another
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002090 * channel which has same weightage and is in PCL, choose the one in
2091 * PCL
2092 */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002093 for (count = 0; count < spect_info->numSpectChans; count++) {
2094 if (!ch_in_pcl(sap_ctx, spect_info->pSpectCh[count].chNum) ||
2095 (spect_info->pSpectCh[count].weight !=
2096 sap_ctx->acsBestChannelInfo.weight))
2097 continue;
2098
2099 if (sap_select_preferred_channel_from_channel_list(
2100 spect_info->pSpectCh[count].chNum, sap_ctx, spect_info)
2101 == SAP_CHANNEL_NOT_SELECTED)
2102 continue;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002103
2104#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002105 if (sap_check_in_avoid_ch_list(sap_ctx, best_ch_num))
2106 continue;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002107#endif
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002108 best_ch_num = spect_info->pSpectCh[count].chNum;
2109 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2110 FL("change best channel to %d in PCL"), best_ch_num);
2111 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002112 }
2113
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002114 sap_ctx->acs_cfg->pri_ch = best_ch_num;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002115 /* determine secondary channel for 2.4G channel 5, 6, 7 in HT40 */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002116 if ((operating_band != eCSR_DOT11_MODE_11g) ||
2117 (sap_ctx->acs_cfg->ch_width != CH_WIDTH_40MHZ))
2118 goto sap_ch_sel_end;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002119
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002120 if ((best_ch_num >= 5) && (best_ch_num <= 7)) {
2121 int weight_below, weight_above, i;
2122 tSapSpectChInfo *pspect_info;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002123
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002124 weight_below = weight_above = SAP_ACS_WEIGHT_MAX;
2125 pspect_info = spect_info->pSpectCh;
2126 for (i = 0; i < spect_info->numSpectChans; i++) {
2127 if (pspect_info[i].chNum == (best_ch_num - 4))
2128 weight_below = pspect_info[i].weight;
2129 if (pspect_info[i].chNum == (best_ch_num + 4))
2130 weight_above = pspect_info[i].weight;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002131 }
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002132
2133 if (weight_below < weight_above)
2134 sap_ctx->acs_cfg->ht_sec_ch =
2135 sap_ctx->acs_cfg->pri_ch - 4;
2136 else
2137 sap_ctx->acs_cfg->ht_sec_ch =
2138 sap_ctx->acs_cfg->pri_ch + 4;
2139 } else if (best_ch_num >= 1 && best_ch_num <= 4) {
2140 sap_ctx->acs_cfg->ht_sec_ch = sap_ctx->acs_cfg->pri_ch + 4;
2141 } else if (best_ch_num >= 8 && best_ch_num <= 13) {
2142 sap_ctx->acs_cfg->ht_sec_ch = sap_ctx->acs_cfg->pri_ch - 4;
2143 } else if (best_ch_num == 14) {
2144 sap_ctx->acs_cfg->ht_sec_ch = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002145 }
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002146 sap_ctx->secondary_ch = sap_ctx->acs_cfg->ht_sec_ch;
2147
2148sap_ch_sel_end:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002149 /* Free all the allocated memory */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002150 sap_chan_sel_exit(spect_info);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002151
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302152 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002153 FL("Running SAP Ch select Completed, Ch=%d"), best_ch_num);
2154 if (best_ch_num > 0 && best_ch_num <= 252)
2155 return best_ch_num;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002156 else
2157 return SAP_CHANNEL_NOT_SELECTED;
2158}