blob: 0f488b99bdfa554d6d0f2a98d41f2f224825c8e3 [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 */
Deepthi Gowri48b89332016-08-30 18:43:05 +053056#include "cds_utils.h"
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
Deepthi Gowri48b89332016-08-30 18:43:05 +0530639 /* Skip DSRC channels */
640 if (cds_is_dsrc_channel(cds_chan_to_freq(*pChans)))
641 continue;
642
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800643 if (true == chSafe) {
644 pSpectCh->chNum = *pChans;
645 pSpectCh->valid = eSAP_TRUE;
646 pSpectCh->rssiAgr = SOFTAP_MIN_RSSI; /* Initialise for all channels */
647 pSpectCh->channelWidth = SOFTAP_HT20_CHANNELWIDTH; /* Initialise 20MHz for all the Channels */
648 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800649 }
650 return eSAP_TRUE;
651}
652
653/*==========================================================================
654 FUNCTION sapweight_rssi_count
655
656 DESCRIPTION
657 Function weightRssiCount calculates the channel weight due to rssi
Anurag Chouhan6d760662016-02-20 16:05:43 +0530658 and data count(here number of BSS observed)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800659
660 DEPENDENCIES
661 NA.
662
663 PARAMETERS
664
665 IN
666 rssi : Max signal strength receieved from a BSS for the channel
667 count : Number of BSS observed in the channel
668
669 RETURN VALUE
670 uint32_t : Calculated channel weight based on above two
671
672 SIDE EFFECTS
673 ============================================================================*/
674uint32_t sapweight_rssi_count(int8_t rssi, uint16_t count)
675{
676 int32_t rssiWeight = 0;
677 int32_t countWeight = 0;
678 uint32_t rssicountWeight = 0;
679
680 /* Weight from RSSI */
681 rssiWeight = SOFTAP_RSSI_WEIGHT * (rssi - SOFTAP_MIN_RSSI)
682 / (SOFTAP_MAX_RSSI - SOFTAP_MIN_RSSI);
683
684 if (rssiWeight > SOFTAP_RSSI_WEIGHT)
685 rssiWeight = SOFTAP_RSSI_WEIGHT;
686 else if (rssiWeight < 0)
687 rssiWeight = 0;
688
689 /* Weight from data count */
690 countWeight = SOFTAP_COUNT_WEIGHT * (count - SOFTAP_MIN_COUNT)
691 / (SOFTAP_MAX_COUNT - SOFTAP_MIN_COUNT);
692
693 if (countWeight > SOFTAP_COUNT_WEIGHT)
694 countWeight = SOFTAP_COUNT_WEIGHT;
695
696 rssicountWeight = rssiWeight + countWeight;
697
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530698 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800699 "In %s, rssiWeight=%d, countWeight=%d, rssicountWeight=%d",
700 __func__, rssiWeight, countWeight, rssicountWeight);
701
702 return rssicountWeight;
703}
704
705/**
706 * sap_update_rssi_bsscount() - updates bss count and rssi effect.
707 *
708 * @pSpectCh: Channel Information
709 * @offset: Channel Offset
710 * @sap_24g: Channel is in 2.4G or 5G
711 *
712 * sap_update_rssi_bsscount updates bss count and rssi effect based
713 * on the channel offset.
714 *
715 * Return: None.
716 */
717
718void sap_update_rssi_bsscount(tSapSpectChInfo *pSpectCh, int32_t offset,
719 bool sap_24g)
720{
721 tSapSpectChInfo *pExtSpectCh = NULL;
722 int32_t rssi, rsssi_effect;
723
724 pExtSpectCh = (pSpectCh + offset);
725 if (pExtSpectCh != NULL) {
726 ++pExtSpectCh->bssCount;
727 switch (offset) {
728 case -1:
729 case 1:
730 rsssi_effect = sap_24g ?
731 SAP_24GHZ_FIRST_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY :
732 SAP_SUBBAND1_RSSI_EFFECT_PRIMARY;
733 break;
734 case -2:
735 case 2:
736 rsssi_effect = sap_24g ?
737 SAP_24GHZ_SEC_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY :
738 SAP_SUBBAND2_RSSI_EFFECT_PRIMARY;
739 break;
740 case -3:
741 case 3:
742 rsssi_effect = sap_24g ?
743 SAP_24GHZ_THIRD_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY :
744 SAP_SUBBAND3_RSSI_EFFECT_PRIMARY;
745 break;
746 case -4:
747 case 4:
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -0700748 rsssi_effect = sap_24g ?
749 SAP_24GHZ_FOURTH_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY :
750 SAP_SUBBAND4_RSSI_EFFECT_PRIMARY;
751 break;
752 case -5:
753 case 5:
754 rsssi_effect = SAP_SUBBAND5_RSSI_EFFECT_PRIMARY;
755 break;
756 case -6:
757 case 6:
758 rsssi_effect = SAP_SUBBAND6_RSSI_EFFECT_PRIMARY;
759 break;
760 case -7:
761 case 7:
762 rsssi_effect = SAP_SUBBAND7_RSSI_EFFECT_PRIMARY;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800763 break;
764 default:
765 rsssi_effect = 0;
766 break;
767 }
768
769 rssi = pSpectCh->rssiAgr + rsssi_effect;
770 if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi))
771 pExtSpectCh->rssiAgr = rssi;
772 if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI)
773 pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI;
774 }
775}
776
777/**
778 * sap_upd_chan_spec_params() - sap_upd_chan_spec_params
779 * updates channel parameters obtained from Beacon
780 * @pBeaconStruct Beacon strucutre populated by parse_beacon function
781 * @channelWidth Channel width
782 * @secondaryChannelOffset Secondary Channel Offset
783 * @vhtSupport If channel supports VHT
784 * @centerFreq Central frequency for the given channel.
785 *
786 * sap_upd_chan_spec_params updates the spectrum channels based on the
787 * pBeaconStruct obtained from Beacon IE
788 *
789 * Return: NA.
790 */
791
792void sap_upd_chan_spec_params(tSirProbeRespBeacon *pBeaconStruct,
793 uint16_t *channelWidth,
794 uint16_t *secondaryChannelOffset,
795 uint16_t *vhtSupport,
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -0700796 uint16_t *centerFreq,
797 uint16_t *centerFreq_2)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800798{
799 if (NULL == pBeaconStruct) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530800 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800801 FL("pBeaconStruct is NULL"));
802 return;
803 }
804
805 if (pBeaconStruct->HTCaps.present && pBeaconStruct->HTInfo.present) {
806 *channelWidth = pBeaconStruct->HTCaps.supportedChannelWidthSet;
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -0700807 *secondaryChannelOffset =
808 pBeaconStruct->HTInfo.secondaryChannelOffset;
809 if (!pBeaconStruct->VHTOperation.present)
810 return;
811 *vhtSupport = pBeaconStruct->VHTOperation.present;
812 if (pBeaconStruct->VHTOperation.chanWidth) {
813 *centerFreq =
814 pBeaconStruct->VHTOperation.chanCenterFreqSeg1;
815 *centerFreq_2 =
816 pBeaconStruct->VHTOperation.chanCenterFreqSeg2;
817 /*
818 * LHS follows tSirMacHTChannelWidth, while RHS follows
819 * WNI_CFG_VHT_CHANNEL_WIDTH_X format hence following
820 * adjustment
821 */
822 *channelWidth =
823 pBeaconStruct->VHTOperation.chanWidth + 1;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800824
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800825 }
826 }
827}
828
829/**
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -0700830 * sap_update_rssi_bsscount_vht_5G() - updates bss count and rssi effect.
831 *
832 * @pSpectCh: Channel Information
833 * @offset: Channel Offset
834 * @num_ch: no.of channels
835 *
836 * sap_update_rssi_bsscount_vht_5G updates bss count and rssi effect based
837 * on the channel offset.
838 *
839 * Return: None.
840 */
841
842void sap_update_rssi_bsscount_vht_5G(tSapSpectChInfo *spect_ch, int32_t offset,
843 uint16_t num_ch)
844{
845 int32_t ch_offset;
846 uint16_t i, cnt;
847
848 if (!offset)
849 return;
850 if (offset > 0)
851 cnt = num_ch;
852 else
853 cnt = num_ch + 1;
854 for (i = 0; i < cnt; i++) {
855 ch_offset = offset + i;
856 if (ch_offset == 0)
857 continue;
858 sap_update_rssi_bsscount(spect_ch, ch_offset, false);
859 }
860}
861/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800862 * sap_interference_rssi_count_5G() - sap_interference_rssi_count
863 * considers the Adjacent channel rssi and
864 * data count(here number of BSS observed)
865 * @spect_ch: Channel Information
866 * @chan_width: Channel width parsed from beacon IE
867 * @sec_chan_offset: Secondary Channel Offset
868 * @center_freq: Central frequency for the given channel.
869 * @channel_id: channel_id
870 *
871 * sap_interference_rssi_count_5G considers the Adjacent channel rssi
872 * and data count(here number of BSS observed)
873 *
874 * Return: NA.
875 */
876
877void sap_interference_rssi_count_5G(tSapSpectChInfo *spect_ch,
878 uint16_t chan_width,
879 uint16_t sec_chan_offset,
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -0700880 uint16_t center_freq,
881 uint16_t center_freq_2,
882 uint8_t channel_id)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800883{
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -0700884 uint16_t num_ch;
885 int32_t offset = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800886 if (NULL == spect_ch) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530887 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800888 FL("spect_ch is NULL"));
889 return;
890 }
891
892 /* Updating the received ChannelWidth */
893 if (spect_ch->channelWidth != chan_width)
894 spect_ch->channelWidth = chan_width;
895 /* If received ChannelWidth is other than HT20,
896 * we need to update the extension channel Params as well
897 * chan_width == 0, HT20
898 * chan_width == 1, HT40
899 * chan_width == 2, VHT80
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -0700900 * chan_width == 3, VHT160
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800901 */
902
903 switch (spect_ch->channelWidth) {
904 case eHT_CHANNEL_WIDTH_40MHZ: /* HT40 */
905 switch (sec_chan_offset) {
906 /* Above the Primary Channel */
907 case PHY_DOUBLE_CHANNEL_LOW_PRIMARY:
908 sap_update_rssi_bsscount(spect_ch, 1, false);
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -0700909 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800910
911 /* Below the Primary channel */
912 case PHY_DOUBLE_CHANNEL_HIGH_PRIMARY:
913 sap_update_rssi_bsscount(spect_ch, -1, false);
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -0700914 return;
915 }
916 return;
917 case eHT_CHANNEL_WIDTH_80MHZ: /* VHT80 */
918 num_ch = 3;
919 if ((center_freq - channel_id) == 6) {
920 offset = 1;
921 } else if ((center_freq - channel_id) == 2) {
922 offset = -1;
923 } else if ((center_freq - channel_id) == -2) {
924 offset = -2;
925 } else if ((center_freq - channel_id) == -6) {
926 offset = -3;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800927 }
928 break;
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -0700929 case eHT_CHANNEL_WIDTH_160MHZ: /* VHT160 */
930 num_ch = 7;
931 if ((center_freq - channel_id) == 14)
932 offset = 1;
933 else if ((center_freq - channel_id) == 10)
934 offset = -1;
935 else if ((center_freq - channel_id) == 6)
936 offset = -2;
937 else if ((center_freq - channel_id) == 2)
938 offset = -3;
939 else if ((center_freq - channel_id) == -2)
940 offset = -4;
941 else if ((center_freq - channel_id) == -6)
942 offset = -5;
943 else if ((center_freq - channel_id) == -10)
944 offset = -6;
945 else if ((center_freq - channel_id) == -14)
946 offset = -7;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800947 break;
948 default:
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -0700949 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800950 }
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -0700951 sap_update_rssi_bsscount_vht_5G(spect_ch, offset, num_ch);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800952}
953
954/**
955 * sap_interference_rssi_count() - sap_interference_rssi_count
956 * considers the Adjacent channel rssi
957 * and data count(here number of BSS observed)
958 * @spect_ch Channel Information
959 *
960 * sap_interference_rssi_count considers the Adjacent channel rssi
961 * and data count(here number of BSS observed)
962 *
963 * Return: None.
964 */
965
966void sap_interference_rssi_count(tSapSpectChInfo *spect_ch)
967{
968 if (NULL == spect_ch) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530969 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800970 "%s: spect_ch is NULL", __func__);
971 return;
972 }
973
974 switch (spect_ch->chNum) {
975 case CHANNEL_1:
976 sap_update_rssi_bsscount(spect_ch, 1, true);
977 sap_update_rssi_bsscount(spect_ch, 2, true);
978 sap_update_rssi_bsscount(spect_ch, 3, true);
979 sap_update_rssi_bsscount(spect_ch, 4, true);
980 break;
981
982 case CHANNEL_2:
983 sap_update_rssi_bsscount(spect_ch, -1, true);
984 sap_update_rssi_bsscount(spect_ch, 1, true);
985 sap_update_rssi_bsscount(spect_ch, 2, true);
986 sap_update_rssi_bsscount(spect_ch, 3, true);
987 sap_update_rssi_bsscount(spect_ch, 4, true);
988 break;
989 case CHANNEL_3:
990 sap_update_rssi_bsscount(spect_ch, -2, true);
991 sap_update_rssi_bsscount(spect_ch, -1, true);
992 sap_update_rssi_bsscount(spect_ch, 1, true);
993 sap_update_rssi_bsscount(spect_ch, 2, true);
994 sap_update_rssi_bsscount(spect_ch, 3, true);
995 sap_update_rssi_bsscount(spect_ch, 4, true);
996 break;
997 case CHANNEL_4:
998 sap_update_rssi_bsscount(spect_ch, -3, true);
999 sap_update_rssi_bsscount(spect_ch, -2, true);
1000 sap_update_rssi_bsscount(spect_ch, -1, true);
1001 sap_update_rssi_bsscount(spect_ch, 1, true);
1002 sap_update_rssi_bsscount(spect_ch, 2, true);
1003 sap_update_rssi_bsscount(spect_ch, 3, true);
1004 sap_update_rssi_bsscount(spect_ch, 4, true);
1005 break;
1006
1007 case CHANNEL_5:
1008 case CHANNEL_6:
1009 case CHANNEL_7:
1010 case CHANNEL_8:
1011 case CHANNEL_9:
1012 case CHANNEL_10:
1013 sap_update_rssi_bsscount(spect_ch, -4, true);
1014 sap_update_rssi_bsscount(spect_ch, -3, true);
1015 sap_update_rssi_bsscount(spect_ch, -2, true);
1016 sap_update_rssi_bsscount(spect_ch, -1, true);
1017 sap_update_rssi_bsscount(spect_ch, 1, true);
1018 sap_update_rssi_bsscount(spect_ch, 2, true);
1019 sap_update_rssi_bsscount(spect_ch, 3, true);
1020 sap_update_rssi_bsscount(spect_ch, 4, true);
1021 break;
1022
1023 case CHANNEL_11:
1024 sap_update_rssi_bsscount(spect_ch, -4, true);
1025 sap_update_rssi_bsscount(spect_ch, -3, true);
1026 sap_update_rssi_bsscount(spect_ch, -2, true);
1027 sap_update_rssi_bsscount(spect_ch, -1, true);
1028 sap_update_rssi_bsscount(spect_ch, 1, true);
1029 sap_update_rssi_bsscount(spect_ch, 2, true);
1030 sap_update_rssi_bsscount(spect_ch, 3, true);
1031 break;
1032
1033 case CHANNEL_12:
1034 sap_update_rssi_bsscount(spect_ch, -4, true);
1035 sap_update_rssi_bsscount(spect_ch, -3, true);
1036 sap_update_rssi_bsscount(spect_ch, -2, true);
1037 sap_update_rssi_bsscount(spect_ch, -1, true);
1038 sap_update_rssi_bsscount(spect_ch, 1, true);
1039 sap_update_rssi_bsscount(spect_ch, 2, true);
1040 break;
1041
1042 case CHANNEL_13:
1043 sap_update_rssi_bsscount(spect_ch, -4, true);
1044 sap_update_rssi_bsscount(spect_ch, -3, true);
1045 sap_update_rssi_bsscount(spect_ch, -2, true);
1046 sap_update_rssi_bsscount(spect_ch, -1, true);
1047 sap_update_rssi_bsscount(spect_ch, 1, true);
1048 break;
1049
1050 case CHANNEL_14:
1051 sap_update_rssi_bsscount(spect_ch, -4, true);
1052 sap_update_rssi_bsscount(spect_ch, -3, true);
1053 sap_update_rssi_bsscount(spect_ch, -2, true);
1054 sap_update_rssi_bsscount(spect_ch, -1, true);
1055 break;
1056
1057 default:
1058 break;
1059 }
1060}
1061
1062/*==========================================================================
1063 Function ch_in_pcl
1064
1065 Description
1066 Check if a channel is in the preferred channel list
1067
1068 Parameters
1069 sap_ctx SAP context pointer
1070 channel input channel number
1071
1072 Return Value
1073 true: channel is in PCL
1074 false: channel is not in PCL
1075 ==========================================================================*/
1076bool ch_in_pcl(ptSapContext sap_ctx, uint8_t channel)
1077{
1078 uint32_t i;
1079
1080 for (i = 0; i < sap_ctx->acs_cfg->pcl_ch_count; i++) {
1081 if (channel == sap_ctx->acs_cfg->pcl_channels[i])
1082 return true;
1083 }
1084
1085 return false;
1086}
1087
1088/*==========================================================================
1089 FUNCTION sap_compute_spect_weight
1090
1091 DESCRIPTION
1092 Main function for computing the weight of each channel in the
1093 spectrum based on the RSSI value of the BSSes on the channel
1094 and number of BSS
1095
1096 DEPENDENCIES
1097 NA.
1098
1099 PARAMETERS
1100
1101 IN
1102 pSpectInfoParams : Pointer to the tSpectInfoParams structure
1103 halHandle : Pointer to HAL handle
1104 pResult : Pointer to tScanResultHandle
1105
1106 RETURN VALUE
1107 void : NULL
1108
1109 SIDE EFFECTS
1110 ============================================================================*/
1111void sap_compute_spect_weight(tSapChSelSpectInfo *pSpectInfoParams,
1112 tHalHandle halHandle, tScanResultHandle pResult,
1113 ptSapContext sap_ctx)
1114{
1115 int8_t rssi = 0;
1116 uint8_t chn_num = 0;
1117 uint8_t channel_id = 0;
1118
1119 tCsrScanResultInfo *pScanResult;
1120 tSapSpectChInfo *pSpectCh = pSpectInfoParams->pSpectCh;
1121 uint32_t operatingBand;
1122 uint16_t channelWidth;
1123 uint16_t secondaryChannelOffset;
1124 uint16_t centerFreq;
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001125 uint16_t centerFreq_2 = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001126 uint16_t vhtSupport;
1127 uint32_t ieLen = 0;
1128 tSirProbeRespBeacon *pBeaconStruct;
1129 tpAniSirGlobal pMac = (tpAniSirGlobal) halHandle;
1130
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301131 pBeaconStruct = qdf_mem_malloc(sizeof(tSirProbeRespBeacon));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001132 if (NULL == pBeaconStruct) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301133 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Kaushik, Sushantee3ed032016-08-04 16:40:46 +05301134 "Unable to allocate memory in sap_compute_spect_weight");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001135 return;
1136 }
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301137 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001138 "In %s, Computing spectral weight", __func__);
1139
1140 /**
1141 * Soft AP specific channel weight calculation using DFS formula
1142 */
1143 SET_ACS_BAND(operatingBand, sap_ctx);
1144
1145 pScanResult = sme_scan_result_get_first(halHandle, pResult);
1146
1147 while (pScanResult) {
1148 pSpectCh = pSpectInfoParams->pSpectCh;
1149 /* Defining the default values, so that any value will hold the default values */
1150 channelWidth = eHT_CHANNEL_WIDTH_20MHZ;
1151 secondaryChannelOffset = PHY_SINGLE_CHANNEL_CENTERED;
1152 vhtSupport = 0;
1153 centerFreq = 0;
1154
1155 if (pScanResult->BssDescriptor.ieFields != NULL) {
1156 ieLen =
1157 (pScanResult->BssDescriptor.length +
1158 sizeof(uint16_t) + sizeof(uint32_t) -
1159 sizeof(tSirBssDescription));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301160 qdf_mem_set((uint8_t *) pBeaconStruct,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001161 sizeof(tSirProbeRespBeacon), 0);
1162
1163 if ((sir_parse_beacon_ie
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001164 (pMac, pBeaconStruct, (uint8_t *)
1165 (pScanResult->BssDescriptor.ieFields),
1166 ieLen)) == eSIR_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001167 sap_upd_chan_spec_params(pBeaconStruct,
1168 &channelWidth, &secondaryChannelOffset,
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001169 &vhtSupport, &centerFreq,
1170 &centerFreq_2);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001171 }
1172 }
1173 /* Processing for each tCsrScanResultInfo in the tCsrScanResult DLink list */
1174 for (chn_num = 0; chn_num < pSpectInfoParams->numSpectChans;
1175 chn_num++) {
1176
1177 /*
1178 * if the Beacon has channel ID, use it other wise we will
1179 * rely on the channelIdSelf
1180 */
1181 if (pScanResult->BssDescriptor.channelId == 0)
1182 channel_id =
1183 pScanResult->BssDescriptor.channelIdSelf;
1184 else
1185 channel_id =
1186 pScanResult->BssDescriptor.channelId;
1187
1188 if (pSpectCh && (channel_id == pSpectCh->chNum)) {
1189 if (pSpectCh->rssiAgr <
1190 pScanResult->BssDescriptor.rssi)
1191 pSpectCh->rssiAgr =
1192 pScanResult->BssDescriptor.rssi;
1193
1194 ++pSpectCh->bssCount; /* Increment the count of BSS */
1195
1196 /*
1197 * Connsidering the Extension Channel
1198 * only in a channels
1199 */
1200 switch (operatingBand) {
1201 case eCSR_DOT11_MODE_11a:
1202 sap_interference_rssi_count_5G(
1203 pSpectCh, channelWidth,
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001204 secondaryChannelOffset,
1205 centerFreq,
1206 centerFreq_2,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001207 channel_id);
1208 break;
1209
1210 case eCSR_DOT11_MODE_11g:
1211 sap_interference_rssi_count(pSpectCh);
1212 break;
1213
1214 case eCSR_DOT11_MODE_abg:
1215 sap_interference_rssi_count_5G(
1216 pSpectCh, channelWidth,
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001217 secondaryChannelOffset,
1218 centerFreq,
1219 centerFreq_2,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001220 channel_id);
1221 sap_interference_rssi_count(pSpectCh);
1222 break;
1223 }
1224
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301225 QDF_TRACE(QDF_MODULE_ID_SAP,
1226 QDF_TRACE_LEVEL_INFO_HIGH,
Kaushik, Sushantee3ed032016-08-04 16:40:46 +05301227 "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",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001228 __func__,
1229 pScanResult->BssDescriptor.
1230 channelIdSelf,
1231 pScanResult->BssDescriptor.channelId,
1232 pScanResult->BssDescriptor.rssi,
1233 pSpectCh->bssCount, pScanResult,
1234 pSpectCh->channelWidth,
1235 secondaryChannelOffset, centerFreq);
1236 pSpectCh++;
1237 break;
1238 } else {
1239 pSpectCh++;
1240 }
1241 }
1242
1243 pScanResult = sme_scan_result_get_next(halHandle, pResult);
1244 }
1245
1246 /* Calculate the weights for all channels in the spectrum pSpectCh */
1247 pSpectCh = pSpectInfoParams->pSpectCh;
1248
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301249 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001250 "In %s, Spectrum Channels Weight", __func__);
1251
1252 for (chn_num = 0; chn_num < (pSpectInfoParams->numSpectChans);
1253 chn_num++) {
1254
1255 /*
1256 rssi : Maximum received signal strength among all BSS on that channel
1257 bssCount : Number of BSS on that channel
1258 */
1259
1260 rssi = (int8_t) pSpectCh->rssiAgr;
1261 if (ch_in_pcl(sap_ctx, chn_num))
1262 rssi -= PCL_RSSI_DISCOUNT;
1263
1264 pSpectCh->weight =
1265 SAPDFS_NORMALISE_1000 * sapweight_rssi_count(rssi,
1266 pSpectCh->
1267 bssCount);
1268 pSpectCh->weight_copy = pSpectCh->weight;
1269
1270 /* ------ Debug Info ------ */
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301271 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001272 "In %s, Chan=%d Weight= %d rssiAgr=%d bssCount=%d",
1273 __func__, pSpectCh->chNum, pSpectCh->weight,
1274 pSpectCh->rssiAgr, pSpectCh->bssCount);
1275 /* ------ Debug Info ------ */
1276 pSpectCh++;
1277 }
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301278 qdf_mem_free(pBeaconStruct);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001279}
1280
1281/*==========================================================================
1282 FUNCTION sap_chan_sel_exit
1283
1284 DESCRIPTION
1285 Exit function for free out the allocated memory, to be called
1286 at the end of the dfsSelectChannel function
1287
1288 DEPENDENCIES
1289 NA.
1290
1291 PARAMETERS
1292
1293 IN
1294 pSpectInfoParams : Pointer to the tSapChSelSpectInfo structure
1295
1296 RETURN VALUE
1297 void : NULL
1298
1299 SIDE EFFECTS
1300 ============================================================================*/
1301void sap_chan_sel_exit(tSapChSelSpectInfo *pSpectInfoParams)
1302{
1303 /* Free all the allocated memory */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301304 qdf_mem_free(pSpectInfoParams->pSpectCh);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001305}
1306
1307/*==========================================================================
1308 FUNCTION sap_sort_chl_weight
1309
1310 DESCRIPTION
1311 Funtion to sort the channels with the least weight first for 20MHz channels
1312
1313 DEPENDENCIES
1314 NA.
1315
1316 PARAMETERS
1317
1318 IN
1319 pSpectInfoParams : Pointer to the tSapChSelSpectInfo structure
1320
1321 RETURN VALUE
1322 void : NULL
1323
1324 SIDE EFFECTS
1325 ============================================================================*/
1326void sap_sort_chl_weight(tSapChSelSpectInfo *pSpectInfoParams)
1327{
1328 tSapSpectChInfo temp;
1329
1330 tSapSpectChInfo *pSpectCh = NULL;
1331 uint32_t i = 0, j = 0, minWeightIndex = 0;
1332
1333 pSpectCh = pSpectInfoParams->pSpectCh;
1334 for (i = 0; i < pSpectInfoParams->numSpectChans; i++) {
1335 minWeightIndex = i;
1336 for (j = i + 1; j < pSpectInfoParams->numSpectChans; j++) {
1337 if (pSpectCh[j].weight <
1338 pSpectCh[minWeightIndex].weight) {
1339 minWeightIndex = j;
1340 }
1341 }
1342 if (minWeightIndex != i) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301343 qdf_mem_copy(&temp, &pSpectCh[minWeightIndex],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001344 sizeof(*pSpectCh));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301345 qdf_mem_copy(&pSpectCh[minWeightIndex], &pSpectCh[i],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001346 sizeof(*pSpectCh));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301347 qdf_mem_copy(&pSpectCh[i], &temp, sizeof(*pSpectCh));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001348 }
1349 }
1350}
1351
1352/**
1353 * sap_sort_chl_weight_ht80() - to sort the channels with the least weight
1354 * @pSpectInfoParams: Pointer to the tSapChSelSpectInfo structure
1355 *
1356 * Funtion to sort the channels with the least weight first for HT80 channels
1357 *
1358 * Return: none
1359 */
1360void sap_sort_chl_weight_ht80(tSapChSelSpectInfo *pSpectInfoParams)
1361{
1362 uint8_t i, j, n;
1363 tSapSpectChInfo *pSpectInfo;
1364 uint8_t minIdx;
1365
1366 pSpectInfo = pSpectInfoParams->pSpectCh;
1367 /* for each HT80 channel, calculate the combined weight of the
1368 four 20MHz weight */
1369 for (i = 0; i < ARRAY_SIZE(acs_ht80_channels); i++) {
1370 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
1371 if (pSpectInfo[j].chNum ==
1372 acs_ht80_channels[i].chStartNum)
1373 break;
1374 }
1375 if (j == pSpectInfoParams->numSpectChans)
1376 continue;
1377
1378 if (!(((pSpectInfo[j].chNum + 4) == pSpectInfo[j + 1].chNum) &&
1379 ((pSpectInfo[j].chNum + 8) ==
1380 pSpectInfo[j + 2].chNum) &&
1381 ((pSpectInfo[j].chNum + 12) ==
1382 pSpectInfo[j + 3].chNum))) {
1383 /*
1384 * some channels does not exist in pSectInfo array,
1385 * skip this channel and those in the same HT80 width
1386 */
1387 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 4;
1388 if ((pSpectInfo[j].chNum + 4) ==
1389 pSpectInfo[j + 1].chNum)
1390 pSpectInfo[j + 1].weight =
1391 SAP_ACS_WEIGHT_MAX * 4;
1392 if ((pSpectInfo[j].chNum + 8) ==
1393 pSpectInfo[j + 2].chNum)
1394 pSpectInfo[j + 2].weight =
1395 SAP_ACS_WEIGHT_MAX * 4;
1396 if ((pSpectInfo[j].chNum + 12) ==
1397 pSpectInfo[j + 3].chNum)
1398 pSpectInfo[j + 3].weight =
1399 SAP_ACS_WEIGHT_MAX * 4;
1400 continue;
1401 }
1402 /*found the channel, add the 4 adjacent channels' weight */
1403 acs_ht80_channels[i].weight = pSpectInfo[j].weight +
1404 pSpectInfo[j + 1].weight + pSpectInfo[j + 2].weight +
1405 pSpectInfo[j + 3].weight;
1406 /* find best channel among 4 channels as the primary channel */
1407 if ((pSpectInfo[j].weight + pSpectInfo[j + 1].weight) <
1408 (pSpectInfo[j + 2].weight + pSpectInfo[j + 3].weight)) {
1409 /* lower 2 channels are better choice */
1410 if (pSpectInfo[j].weight < pSpectInfo[j + 1].weight)
1411 minIdx = 0;
1412 else
1413 minIdx = 1;
1414 } else if (pSpectInfo[j + 2].weight <=
1415 pSpectInfo[j + 3].weight) {
1416 /* upper 2 channels are better choice */
1417 minIdx = 2;
1418 } else {
1419 minIdx = 3;
1420 }
1421
1422 /*
1423 * set all 4 channels to max value first, then reset the
1424 * best channel as the selected primary channel, update its
1425 * weightage with the combined weight value
1426 */
1427 for (n = 0; n < 4; n++)
1428 pSpectInfo[j + n].weight = SAP_ACS_WEIGHT_MAX * 4;
1429
1430 pSpectInfo[j + minIdx].weight = acs_ht80_channels[i].weight;
1431 }
1432
1433 pSpectInfo = pSpectInfoParams->pSpectCh;
1434 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
1435 if (CHANNEL_165 == pSpectInfo[j].chNum) {
1436 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 4;
1437 break;
1438 }
1439 }
1440
Manishekar Chandrasekaran44e334f2016-05-30 16:42:50 +05301441 sap_sort_chl_weight(pSpectInfoParams);
1442
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001443 pSpectInfo = pSpectInfoParams->pSpectCh;
1444 for (j = 0; j < (pSpectInfoParams->numSpectChans); j++) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301445 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001446 FL("Channel=%d Weight= %d rssi=%d bssCount=%d"),
1447 pSpectInfo->chNum, pSpectInfo->weight,
1448 pSpectInfo->rssiAgr, pSpectInfo->bssCount);
1449 pSpectInfo++;
1450 }
1451}
1452
1453/**
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001454 * sap_sort_chl_weight_vht160() - to sort the channels with the least weight
1455 * @pSpectInfoParams: Pointer to the tSapChSelSpectInfo structure
1456 *
1457 * Funtion to sort the channels with the least weight first for VHT160 channels
1458 *
1459 * Return: none
1460 */
1461void sap_sort_chl_weight_vht160(tSapChSelSpectInfo *pSpectInfoParams)
1462{
1463 uint8_t i, j, n, idx;
1464 tSapSpectChInfo *pSpectInfo;
1465 uint8_t minIdx;
1466
1467 pSpectInfo = pSpectInfoParams->pSpectCh;
1468 /* for each VHT160 channel, calculate the combined weight of the
1469 8 20MHz weight */
1470 for (i = 0; i < ARRAY_SIZE(acs_vht160_channels); i++) {
1471 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
1472 if (pSpectInfo[j].chNum ==
1473 acs_vht160_channels[i].chStartNum)
1474 break;
1475 }
1476 if (j == pSpectInfoParams->numSpectChans)
1477 continue;
1478
1479 if (!(((pSpectInfo[j].chNum + 4) == pSpectInfo[j + 1].chNum) &&
1480 ((pSpectInfo[j].chNum + 8) ==
1481 pSpectInfo[j + 2].chNum) &&
1482 ((pSpectInfo[j].chNum + 12) ==
1483 pSpectInfo[j + 3].chNum) &&
1484 ((pSpectInfo[j].chNum + 16) ==
1485 pSpectInfo[j + 4].chNum) &&
1486 ((pSpectInfo[j].chNum + 20) ==
1487 pSpectInfo[j + 5].chNum) &&
1488 ((pSpectInfo[j].chNum + 24) ==
1489 pSpectInfo[j + 6].chNum) &&
1490 ((pSpectInfo[j].chNum + 28) ==
1491 pSpectInfo[j + 7].chNum))) {
1492 /*
1493 * some channels does not exist in pSectInfo array,
1494 * skip this channel and those in the same VHT160 width
1495 */
1496 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 8;
1497 if ((pSpectInfo[j].chNum + 4) ==
1498 pSpectInfo[j + 1].chNum)
1499 pSpectInfo[j + 1].weight =
1500 SAP_ACS_WEIGHT_MAX * 8;
1501 if ((pSpectInfo[j].chNum + 8) ==
1502 pSpectInfo[j + 2].chNum)
1503 pSpectInfo[j + 2].weight =
1504 SAP_ACS_WEIGHT_MAX * 8;
1505 if ((pSpectInfo[j].chNum + 12) ==
1506 pSpectInfo[j + 3].chNum)
1507 pSpectInfo[j + 3].weight =
1508 SAP_ACS_WEIGHT_MAX * 8;
1509 if ((pSpectInfo[j].chNum + 16) ==
1510 pSpectInfo[j + 4].chNum)
1511 pSpectInfo[j + 4].weight =
1512 SAP_ACS_WEIGHT_MAX * 8;
1513 if ((pSpectInfo[j].chNum + 20) ==
1514 pSpectInfo[j + 5].chNum)
1515 pSpectInfo[j + 5].weight =
1516 SAP_ACS_WEIGHT_MAX * 8;
1517 if ((pSpectInfo[j].chNum + 24) ==
1518 pSpectInfo[j + 6].chNum)
1519 pSpectInfo[j + 6].weight =
1520 SAP_ACS_WEIGHT_MAX * 8;
1521 if ((pSpectInfo[j].chNum + 28) ==
1522 pSpectInfo[j + 7].chNum)
1523 pSpectInfo[j + 7].weight =
1524 SAP_ACS_WEIGHT_MAX * 8;
1525 continue;
1526 }
1527 /*found the channel, add the 7 adjacent channels' weight */
1528 acs_vht160_channels[i].weight = pSpectInfo[j].weight +
1529 pSpectInfo[j + 1].weight + pSpectInfo[j + 2].weight +
1530 pSpectInfo[j + 3].weight + pSpectInfo[j + 4].weight +
1531 pSpectInfo[j + 5].weight + pSpectInfo[j + 6].weight +
1532 pSpectInfo[j + 7].weight;
1533
1534 /* find best channel among 8 channels as the primary channel */
1535 if ((pSpectInfo[j].weight + pSpectInfo[j + 1].weight +
1536 pSpectInfo[j + 2].weight + pSpectInfo[j + 3].weight) >
1537 (pSpectInfo[j + 4].weight + pSpectInfo[j + 5].weight +
1538 pSpectInfo[j + 6].weight + pSpectInfo[j + 7].weight))
1539 idx = 4;
1540 else
1541 idx = 0;
1542 /* find best channel among 4 channels as the primary channel */
1543 if ((pSpectInfo[j + idx].weight +
1544 pSpectInfo[j + idx + 1].weight) <
1545 (pSpectInfo[j + idx + 2].weight +
1546 pSpectInfo[j + idx + 3].weight)) {
1547 /* lower 2 channels are better choice */
1548 if (pSpectInfo[j + idx].weight <
1549 pSpectInfo[j + idx + 1].weight)
1550 minIdx = 0 + idx;
1551 else
1552 minIdx = 1 + idx;
1553 } else if (pSpectInfo[j + idx + 2].weight <=
1554 pSpectInfo[j + idx + 3].weight) {
1555 /* upper 2 channels are better choice */
1556 minIdx = 2 + idx;
1557 } else {
1558 minIdx = 3 + idx;
1559 }
1560
1561 /*
1562 * set all 8 channels to max value first, then reset the
1563 * best channel as the selected primary channel, update its
1564 * weightage with the combined weight value
1565 */
1566 for (n = 0; n < 8; n++)
1567 pSpectInfo[j + n].weight = SAP_ACS_WEIGHT_MAX * 8;
1568
1569 pSpectInfo[j + minIdx].weight = acs_vht160_channels[i].weight;
1570 }
1571
1572 pSpectInfo = pSpectInfoParams->pSpectCh;
1573 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
1574 if (CHANNEL_165 == pSpectInfo[j].chNum) {
1575 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 8;
1576 break;
1577 }
1578 }
1579
Manishekar Chandrasekaran44e334f2016-05-30 16:42:50 +05301580 sap_sort_chl_weight(pSpectInfoParams);
1581
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001582 pSpectInfo = pSpectInfoParams->pSpectCh;
1583 for (j = 0; j < (pSpectInfoParams->numSpectChans); j++) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301584 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001585 FL("Channel=%d Weight= %d rssi=%d bssCount=%d"),
1586 pSpectInfo->chNum, pSpectInfo->weight,
1587 pSpectInfo->rssiAgr, pSpectInfo->bssCount);
1588 pSpectInfo++;
1589 }
1590}
1591
1592/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001593 * sap_sort_chl_weight_ht40_24_g() - to sort channel with the least weight
1594 * @pSpectInfoParams: Pointer to the tSapChSelSpectInfo structure
1595 *
1596 * Funtion to sort the channels with the least weight first for HT40 channels
1597 *
1598 * Return: none
1599 */
1600void sap_sort_chl_weight_ht40_24_g(tSapChSelSpectInfo *pSpectInfoParams)
1601{
1602 uint8_t i, j;
1603 tSapSpectChInfo *pSpectInfo;
1604 uint32_t tmpWeight1, tmpWeight2;
1605
1606 pSpectInfo = pSpectInfoParams->pSpectCh;
1607 /*
1608 * for each HT40 channel, calculate the combined weight of the
1609 * two 20MHz weight
1610 */
1611 for (i = 0; i < ARRAY_SIZE(acs_ht40_channels24_g); i++) {
1612 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
1613 if (pSpectInfo[j].chNum ==
1614 acs_ht40_channels24_g[i].chStartNum)
1615 break;
1616 }
1617 if (j == pSpectInfoParams->numSpectChans)
1618 continue;
1619
1620 if (!((pSpectInfo[j].chNum + 4) == pSpectInfo[j + 4].chNum)) {
1621 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2;
1622 continue;
1623 }
1624 /*
1625 * check if there is another channel combination possiblity
1626 * e.g., {1, 5} & {5, 9}
1627 */
1628 if ((pSpectInfo[j + 4].chNum + 4) == pSpectInfo[j + 8].chNum) {
1629 /* need to compare two channel pairs */
1630 tmpWeight1 = pSpectInfo[j].weight +
1631 pSpectInfo[j + 4].weight;
1632 tmpWeight2 = pSpectInfo[j + 4].weight +
1633 pSpectInfo[j + 8].weight;
1634 if (tmpWeight1 <= tmpWeight2) {
1635 if (pSpectInfo[j].weight <=
1636 pSpectInfo[j + 4].weight) {
1637 pSpectInfo[j].weight =
1638 tmpWeight1;
1639 pSpectInfo[j + 4].weight =
1640 SAP_ACS_WEIGHT_MAX * 2;
1641 pSpectInfo[j + 8].weight =
1642 SAP_ACS_WEIGHT_MAX * 2;
1643 } else {
1644 pSpectInfo[j + 4].weight =
1645 tmpWeight1;
1646 /* for secondary channel selection */
1647 pSpectInfo[j].weight =
1648 SAP_ACS_WEIGHT_MAX * 2
1649 - 1;
1650 pSpectInfo[j + 8].weight =
1651 SAP_ACS_WEIGHT_MAX * 2;
1652 }
1653 } else {
1654 if (pSpectInfo[j + 4].weight <=
1655 pSpectInfo[j + 8].weight) {
1656 pSpectInfo[j + 4].weight =
1657 tmpWeight2;
1658 pSpectInfo[j].weight =
1659 SAP_ACS_WEIGHT_MAX * 2;
1660 /* for secondary channel selection */
1661 pSpectInfo[j + 8].weight =
1662 SAP_ACS_WEIGHT_MAX * 2
1663 - 1;
1664 } else {
1665 pSpectInfo[j + 8].weight =
1666 tmpWeight2;
1667 pSpectInfo[j].weight =
1668 SAP_ACS_WEIGHT_MAX * 2;
1669 pSpectInfo[j + 4].weight =
1670 SAP_ACS_WEIGHT_MAX * 2;
1671 }
1672 }
1673 } else {
1674 tmpWeight1 = pSpectInfo[j].weight +
1675 pSpectInfo[j + 4].weight;
1676 if (pSpectInfo[j].weight <=
1677 pSpectInfo[j + 4].weight) {
1678 pSpectInfo[j].weight = tmpWeight1;
1679 pSpectInfo[j + 4].weight =
1680 SAP_ACS_WEIGHT_MAX * 2;
1681 } else {
1682 pSpectInfo[j + 4].weight = tmpWeight1;
1683 pSpectInfo[j].weight =
1684 SAP_ACS_WEIGHT_MAX * 2;
1685 }
1686 }
1687 }
Manishekar Chandrasekaran44e334f2016-05-30 16:42:50 +05301688 sap_sort_chl_weight(pSpectInfoParams);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001689}
1690
1691/*==========================================================================
1692 FUNCTION sap_sort_chl_weight_ht40_5_g
1693
1694 DESCRIPTION
1695 Funtion to sort the channels with the least weight first for HT40 channels
1696
1697 DEPENDENCIES
1698 NA.
1699
1700 PARAMETERS
1701
1702 IN
1703 pSpectInfoParams : Pointer to the tSapChSelSpectInfo structure
1704
1705 RETURN VALUE
1706 void : NULL
1707
1708 SIDE EFFECTS
1709 ============================================================================*/
1710void sap_sort_chl_weight_ht40_5_g(tSapChSelSpectInfo *pSpectInfoParams)
1711{
1712 uint8_t i, j;
1713 tSapSpectChInfo *pSpectInfo;
1714
1715 pSpectInfo = pSpectInfoParams->pSpectCh;
1716 /*for each HT40 channel, calculate the combined weight of the
1717 two 20MHz weight */
1718 for (i = 0; i < ARRAY_SIZE(acs_ht40_channels5_g); i++) {
1719 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
1720 if (pSpectInfo[j].chNum ==
1721 acs_ht40_channels5_g[i].chStartNum)
1722 break;
1723 }
1724 if (j == pSpectInfoParams->numSpectChans)
1725 continue;
1726
1727 /* found the channel, add the two adjacent channels' weight */
1728 if ((pSpectInfo[j].chNum + 4) == pSpectInfo[j + 1].chNum) {
1729 acs_ht40_channels5_g[i].weight = pSpectInfo[j].weight +
1730 pSpectInfo[j + 1].weight;
1731 /* select better of the adjact channel as the primary channel */
1732 if (pSpectInfo[j].weight <= pSpectInfo[j + 1].weight) {
1733 pSpectInfo[j].weight =
1734 acs_ht40_channels5_g[i].weight;
1735 /* mark the adjacent channel's weight as max value so
1736 that it will be sorted to the bottom */
1737 pSpectInfo[j + 1].weight =
1738 SAP_ACS_WEIGHT_MAX * 2;
1739 } else {
1740 pSpectInfo[j + 1].weight =
1741 acs_ht40_channels5_g[i].weight;
1742 /* mark the adjacent channel's weight as max value so
1743 that it will be sorted to the bottom */
1744 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2;
1745 }
1746
1747 } else
1748 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2;
1749 }
1750
1751 /* avoid channel 165 by setting its weight to max */
1752 pSpectInfo = pSpectInfoParams->pSpectCh;
1753 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
1754 if (CHANNEL_165 == pSpectInfo[j].chNum) {
1755 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2;
1756 break;
1757 }
1758 }
1759
1760 pSpectInfo = pSpectInfoParams->pSpectCh;
1761 for (j = 0; j < (pSpectInfoParams->numSpectChans); j++) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301762 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001763 "In %s, Channel=%d Weight= %d rssi=%d bssCount=%d",
1764 __func__, pSpectInfo->chNum, pSpectInfo->weight,
1765 pSpectInfo->rssiAgr, pSpectInfo->bssCount);
1766 pSpectInfo++;
1767 }
1768
1769 sap_sort_chl_weight(pSpectInfoParams);
1770}
1771
1772/*==========================================================================
1773 FUNCTION sap_sort_chl_weight_all
1774
1775 DESCRIPTION
1776 Funtion to sort the channels with the least weight first
1777
1778 DEPENDENCIES
1779 NA.
1780
1781 PARAMETERS
1782
1783 IN
1784 ptSapContext : Pointer to the ptSapContext structure
1785 pSpectInfoParams : Pointer to the tSapChSelSpectInfo structure
1786
1787 RETURN VALUE
1788 void : NULL
1789
1790 SIDE EFFECTS
1791 ============================================================================*/
1792void sap_sort_chl_weight_all(ptSapContext pSapCtx,
1793 tSapChSelSpectInfo *pSpectInfoParams,
1794 uint32_t operatingBand)
1795{
1796 tSapSpectChInfo *pSpectCh = NULL;
1797 uint32_t j = 0;
1798#ifndef SOFTAP_CHANNEL_RANGE
1799 uint32_t i = 0;
1800#endif
1801
1802 pSpectCh = pSpectInfoParams->pSpectCh;
1803#ifdef SOFTAP_CHANNEL_RANGE
1804
1805 switch (pSapCtx->acs_cfg->ch_width) {
1806 case CH_WIDTH_40MHZ:
1807 if (eCSR_DOT11_MODE_11g == operatingBand)
1808 sap_sort_chl_weight_ht40_24_g(pSpectInfoParams);
1809 else if (eCSR_DOT11_MODE_11a == operatingBand)
1810 sap_sort_chl_weight_ht40_5_g(pSpectInfoParams);
1811 else {
1812 sap_sort_chl_weight_ht40_24_g(pSpectInfoParams);
1813 sap_sort_chl_weight_ht40_5_g(pSpectInfoParams);
1814 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001815 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001816 case CH_WIDTH_80MHZ:
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001817 case CH_WIDTH_80P80MHZ:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001818 sap_sort_chl_weight_ht80(pSpectInfoParams);
1819 break;
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001820 case CH_WIDTH_160MHZ:
1821 sap_sort_chl_weight_vht160(pSpectInfoParams);
1822 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001823 case CH_WIDTH_20MHZ:
1824 default:
1825 /* Sorting the channels as per weights as 20MHz channels */
1826 sap_sort_chl_weight(pSpectInfoParams);
1827 }
1828
1829#else
1830 /* Sorting the channels as per weights */
1831 for (i = 0; i < SPECT_24GHZ_CH_COUNT; i++) {
1832 minWeightIndex = i;
1833 for (j = i + 1; j < SPECT_24GHZ_CH_COUNT; j++) {
1834 if (pSpectCh[j].weight <
1835 pSpectCh[minWeightIndex].weight) {
1836 minWeightIndex = j;
1837 }
1838 }
1839 if (minWeightIndex != i) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301840 qdf_mem_copy(&temp, &pSpectCh[minWeightIndex],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001841 sizeof(*pSpectCh));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301842 qdf_mem_copy(&pSpectCh[minWeightIndex], &pSpectCh[i],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001843 sizeof(*pSpectCh));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301844 qdf_mem_copy(&pSpectCh[i], &temp, sizeof(*pSpectCh));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001845 }
1846 }
1847#endif
1848
1849 /* For testing */
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, Sorted Spectrum Channels Weight", __func__);
1852 pSpectCh = pSpectInfoParams->pSpectCh;
1853 for (j = 0; j < (pSpectInfoParams->numSpectChans); j++) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301854 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001855 "In %s, Channel=%d Weight= %d rssi=%d bssCount=%d",
1856 __func__, pSpectCh->chNum, pSpectCh->weight,
1857 pSpectCh->rssiAgr, pSpectCh->bssCount);
1858 pSpectCh++;
1859 }
1860
1861}
1862
1863/*==========================================================================
1864 FUNCTION sap_filter_over_lap_ch
1865
1866 DESCRIPTION
1867 return true if ch is acceptable.
1868 This function will decide if we will filter over lap channel or not.
1869
1870 DEPENDENCIES
1871 shall called after ap start.
1872
1873 PARAMETERS
1874
1875 IN
1876 pSapCtx : Pointer to ptSapContext.
1877 chNum : Filter channel number.
1878
1879 RETURN VALUE
1880 bool : true if channel is accepted.
1881
1882 SIDE EFFECTS
1883 ============================================================================*/
1884bool sap_filter_over_lap_ch(ptSapContext pSapCtx, uint16_t chNum)
1885{
1886 if (pSapCtx->enableOverLapCh)
1887 return eSAP_TRUE;
1888 else if ((chNum == CHANNEL_1) ||
1889 (chNum == CHANNEL_6) || (chNum == CHANNEL_11))
1890 return eSAP_TRUE;
1891
1892 return eSAP_FALSE;
1893}
1894
Naveen Rawat365d1cb2016-02-05 12:10:43 -08001895/**
1896 * sap_select_channel_no_scan_result() - select SAP channel when no scan results
1897 * are available.
1898 * @sap_ctx: Sap context
1899 *
1900 * Returns: channel number if success, 0 otherwise
1901 */
Kondabattini, Ganesh13bb4b12016-09-04 16:16:53 +05301902static uint8_t sap_select_channel_no_scan_result(tHalHandle hal,
1903 ptSapContext sap_ctx)
Naveen Rawat365d1cb2016-02-05 12:10:43 -08001904{
Naveen Rawat365d1cb2016-02-05 12:10:43 -08001905 uint32_t start_ch_num, end_ch_num;
1906#ifdef FEATURE_WLAN_CH_AVOID
Mohit Khanna841044f2016-03-25 16:16:24 -07001907 enum channel_state ch_type;
Naveen Rawat365d1cb2016-02-05 12:10:43 -08001908 uint8_t i, first_safe_ch_in_range = SAP_CHANNEL_NOT_SELECTED;
1909#endif
Kondabattini, Ganesh13bb4b12016-09-04 16:16:53 +05301910 uint32_t dfs_master_cap_enabled;
Naveen Rawat365d1cb2016-02-05 12:10:43 -08001911 start_ch_num = sap_ctx->acs_cfg->start_ch;
1912 end_ch_num = sap_ctx->acs_cfg->end_ch;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001913
Naveen Rawat365d1cb2016-02-05 12:10:43 -08001914 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
1915 FL("start - end: %d - %d"), start_ch_num, end_ch_num);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001916
Naveen Rawat365d1cb2016-02-05 12:10:43 -08001917#ifndef FEATURE_WLAN_CH_AVOID
1918 sap_ctx->acs_cfg->pri_ch = start_ch_num;
1919 sap_ctx->acs_cfg->ht_sec_ch = 0;
1920 /* pick the first channel in configured range */
1921 return start_ch_num;
1922#else
Kondabattini, Ganesh13bb4b12016-09-04 16:16:53 +05301923 sme_cfg_get_int(hal, WNI_CFG_DFS_MASTER_ENABLED,
1924 &dfs_master_cap_enabled);
1925
1926 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
1927 "%s: dfs_master %x", __func__, dfs_master_cap_enabled);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001928
Naveen Rawat365d1cb2016-02-05 12:10:43 -08001929 /* get a channel in PCL and within the range */
1930 for (i = 0; i < sap_ctx->acs_cfg->pcl_ch_count; i++) {
1931 if ((sap_ctx->acs_cfg->pcl_channels[i] < start_ch_num) ||
1932 (sap_ctx->acs_cfg->pcl_channels[i] > end_ch_num))
1933 continue;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001934
Naveen Rawat365d1cb2016-02-05 12:10:43 -08001935 first_safe_ch_in_range = sap_ctx->acs_cfg->pcl_channels[i];
1936 break;
1937 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001938
Naveen Rawat365d1cb2016-02-05 12:10:43 -08001939 if (SAP_CHANNEL_NOT_SELECTED != first_safe_ch_in_range)
1940 return first_safe_ch_in_range;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001941
Naveen Rawat365d1cb2016-02-05 12:10:43 -08001942 for (i = 0; i < NUM_CHANNELS; i++) {
1943 if ((safe_channels[i].channelNumber < start_ch_num) ||
1944 (safe_channels[i].channelNumber > end_ch_num))
1945 continue;
1946
1947 ch_type = cds_get_channel_state(safe_channels[i].channelNumber);
1948
1949 if ((ch_type == CHANNEL_STATE_DISABLE) ||
1950 (ch_type == CHANNEL_STATE_INVALID))
1951 continue;
1952
Kondabattini, Ganesh13bb4b12016-09-04 16:16:53 +05301953 if ((!dfs_master_cap_enabled) &&
1954 (CHANNEL_STATE_DFS == ch_type)) {
1955 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
1956 "%s: DFS master mode disabled. Skip DFS channel %d",
1957 __func__, safe_channels[i].channelNumber);
1958 continue;
1959 }
1960
Naveen Rawat365d1cb2016-02-05 12:10:43 -08001961 if (safe_channels[i].isSafe == true) {
1962 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
1963 FL("channel %d in the configuration is safe"),
1964 safe_channels[i].channelNumber);
1965 first_safe_ch_in_range = safe_channels[i].channelNumber;
1966 break;
1967 }
1968
1969 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
1970 FL("channel %d in the configuration is unsafe"),
1971 safe_channels[i].channelNumber);
1972 }
1973
1974 /* if no channel selected return SAP_CHANNEL_NOT_SELECTED */
1975 return first_safe_ch_in_range;
1976#endif /* !FEATURE_WLAN_CH_AVOID */
1977}
1978
1979/**
1980 * sap_select_channel() - select SAP channel
1981 * @hal: Pointer to HAL handle
1982 * @sap_ctx: Sap context
1983 * @scan_result: Pointer to tScanResultHandle
1984 *
1985 * Runs a algorithm to select the best channel to operate in based on BSS
1986 * rssi and bss count on each channel
1987 *
1988 * Returns: channel number if success, 0 otherwise
1989 */
1990uint8_t sap_select_channel(tHalHandle hal, ptSapContext sap_ctx,
1991 tScanResultHandle scan_result)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001992{
1993 /* DFS param object holding all the data req by the algo */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08001994 tSapChSelSpectInfo spect_info_obj = { NULL, 0 };
1995 tSapChSelSpectInfo *spect_info = &spect_info_obj;
1996 uint8_t best_ch_num = SAP_CHANNEL_NOT_SELECTED;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001997#ifdef SOFTAP_CHANNEL_RANGE
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001998 uint8_t count;
Naveen Rawat365d1cb2016-02-05 12:10:43 -08001999 uint32_t start_ch_num, end_ch_num, tmp_ch_num, operating_band = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002000#endif
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302001 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002002 "In %s, Running SAP Ch Select", __func__);
2003
2004#ifdef FEATURE_WLAN_CH_AVOID
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002005 sap_update_unsafe_channel_list(sap_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002006#endif
2007
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002008 if (NULL == scan_result) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302009 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002010 FL("No external AP present"));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002011
2012#ifndef SOFTAP_CHANNEL_RANGE
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002013 return SAP_CHANNEL_NOT_SELECTED;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002014#else
Kondabattini, Ganesh13bb4b12016-09-04 16:16:53 +05302015 return sap_select_channel_no_scan_result(hal, sap_ctx);
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002016#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002017 }
2018
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002019 /* Initialize the structure pointed by spect_info */
2020 if (sap_chan_sel_init(hal, spect_info, sap_ctx) != eSAP_TRUE) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302021 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002022 FL("Ch Select initialization failed"));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002023 return SAP_CHANNEL_NOT_SELECTED;
2024 }
2025 /* Compute the weight of the entire spectrum in the operating band */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002026 sap_compute_spect_weight(spect_info, hal, scan_result, sap_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002027
2028#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
2029 /* process avoid channel IE to collect all channels to avoid */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002030 sap_process_avoid_ie(hal, sap_ctx, scan_result, spect_info);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002031#endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
2032
2033#ifdef SOFTAP_CHANNEL_RANGE
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002034 start_ch_num = sap_ctx->acs_cfg->start_ch;
2035 end_ch_num = sap_ctx->acs_cfg->end_ch;
2036 SET_ACS_BAND(operating_band, sap_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002037
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002038 sap_ctx->acsBestChannelInfo.channelNum = 0;
2039 sap_ctx->acsBestChannelInfo.weight = SAP_ACS_WEIGHT_MAX;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002040
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002041 /* Sort the ch lst as per the computed weights, lesser weight first. */
2042 sap_sort_chl_weight_all(sap_ctx, spect_info, operating_band);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002043
2044 /*Loop till get the best channel in the given range */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002045 for (count = 0; count < spect_info->numSpectChans; count++) {
2046 if ((start_ch_num > spect_info->pSpectCh[count].chNum) ||
2047 (end_ch_num < spect_info->pSpectCh[count].chNum))
2048 continue;
2049
2050 if (best_ch_num == SAP_CHANNEL_NOT_SELECTED) {
2051 best_ch_num = spect_info->pSpectCh[count].chNum;
2052 /* check if best_ch_num is in preferred channel list */
2053 best_ch_num =
2054 sap_select_preferred_channel_from_channel_list(
2055 best_ch_num, sap_ctx, spect_info);
2056 /* if not in preferred ch lst, go to nxt best ch */
2057 if (best_ch_num == SAP_CHANNEL_NOT_SELECTED)
2058 continue;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002059
2060#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002061 /*
2062 * Weight of the channels(device's AP is operating)
2063 * increased to MAX+1 so that they will be choosen only
2064 * when there is no other best channel to choose
2065 */
2066 if (sap_check_in_avoid_ch_list(sap_ctx, best_ch_num)) {
2067 best_ch_num = SAP_CHANNEL_NOT_SELECTED;
2068 continue;
2069 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002070#endif
2071
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002072 sap_ctx->acsBestChannelInfo.channelNum = best_ch_num;
2073 sap_ctx->acsBestChannelInfo.weight =
2074 spect_info->pSpectCh[count].weight_copy;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002075 }
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002076
2077 if (best_ch_num == SAP_CHANNEL_NOT_SELECTED)
2078 continue;
2079
2080 if (operating_band != eCSR_DOT11_MODE_11g)
2081 continue;
2082
2083 /* Give preference to Non-overlap channels */
2084 if (false == sap_filter_over_lap_ch(sap_ctx,
2085 spect_info->pSpectCh[count].chNum))
2086 continue;
2087
2088 tmp_ch_num = spect_info->pSpectCh[count].chNum;
2089 tmp_ch_num = sap_select_preferred_channel_from_channel_list(
2090 tmp_ch_num, sap_ctx, spect_info);
2091 if (tmp_ch_num == SAP_CHANNEL_NOT_SELECTED)
2092 continue;
2093
2094 best_ch_num = tmp_ch_num;
2095 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002096 }
2097#else
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002098 /* Sort the ch lst as per the computed weights, lesser weight first. */
2099 sap_sort_chl_weight_all(sap_ctx, hal, spect_info);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002100 /* Get the first channel in sorted array as best 20M Channel */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002101 best_ch_num = (uint8_t) spect_info->pSpectCh[0].chNum;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002102 /* Select Best Channel from Channel List if Configured */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002103 best_ch_num = sap_select_preferred_channel_from_channel_list(
2104 best_ch_num, sap_ctx, spect_info);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002105#endif
2106
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002107 /*
2108 * in case the best channel seleted is not in PCL and there is another
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002109 * channel which has same weightage and is in PCL, choose the one in
2110 * PCL
2111 */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002112 for (count = 0; count < spect_info->numSpectChans; count++) {
2113 if (!ch_in_pcl(sap_ctx, spect_info->pSpectCh[count].chNum) ||
2114 (spect_info->pSpectCh[count].weight !=
2115 sap_ctx->acsBestChannelInfo.weight))
2116 continue;
2117
2118 if (sap_select_preferred_channel_from_channel_list(
2119 spect_info->pSpectCh[count].chNum, sap_ctx, spect_info)
2120 == SAP_CHANNEL_NOT_SELECTED)
2121 continue;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002122
2123#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002124 if (sap_check_in_avoid_ch_list(sap_ctx, best_ch_num))
2125 continue;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002126#endif
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002127 best_ch_num = spect_info->pSpectCh[count].chNum;
2128 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2129 FL("change best channel to %d in PCL"), best_ch_num);
2130 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002131 }
2132
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002133 sap_ctx->acs_cfg->pri_ch = best_ch_num;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002134 /* determine secondary channel for 2.4G channel 5, 6, 7 in HT40 */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002135 if ((operating_band != eCSR_DOT11_MODE_11g) ||
2136 (sap_ctx->acs_cfg->ch_width != CH_WIDTH_40MHZ))
2137 goto sap_ch_sel_end;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002138
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002139 if ((best_ch_num >= 5) && (best_ch_num <= 7)) {
2140 int weight_below, weight_above, i;
2141 tSapSpectChInfo *pspect_info;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002142
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002143 weight_below = weight_above = SAP_ACS_WEIGHT_MAX;
2144 pspect_info = spect_info->pSpectCh;
2145 for (i = 0; i < spect_info->numSpectChans; i++) {
2146 if (pspect_info[i].chNum == (best_ch_num - 4))
2147 weight_below = pspect_info[i].weight;
2148 if (pspect_info[i].chNum == (best_ch_num + 4))
2149 weight_above = pspect_info[i].weight;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002150 }
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002151
2152 if (weight_below < weight_above)
2153 sap_ctx->acs_cfg->ht_sec_ch =
2154 sap_ctx->acs_cfg->pri_ch - 4;
2155 else
2156 sap_ctx->acs_cfg->ht_sec_ch =
2157 sap_ctx->acs_cfg->pri_ch + 4;
2158 } else if (best_ch_num >= 1 && best_ch_num <= 4) {
2159 sap_ctx->acs_cfg->ht_sec_ch = sap_ctx->acs_cfg->pri_ch + 4;
2160 } else if (best_ch_num >= 8 && best_ch_num <= 13) {
2161 sap_ctx->acs_cfg->ht_sec_ch = sap_ctx->acs_cfg->pri_ch - 4;
2162 } else if (best_ch_num == 14) {
2163 sap_ctx->acs_cfg->ht_sec_ch = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002164 }
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002165 sap_ctx->secondary_ch = sap_ctx->acs_cfg->ht_sec_ch;
2166
2167sap_ch_sel_end:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002168 /* Free all the allocated memory */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002169 sap_chan_sel_exit(spect_info);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002170
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302171 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002172 FL("Running SAP Ch select Completed, Ch=%d"), best_ch_num);
2173 if (best_ch_num > 0 && best_ch_num <= 252)
2174 return best_ch_num;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002175 else
2176 return SAP_CHANNEL_NOT_SELECTED;
2177}