blob: 37b8e270ae642a74b37c04621e06e77051216bf4 [file] [log] [blame]
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001/*
Tang Yingying523322d2017-01-17 23:28:43 +08002 * Copyright (c) 2012-2017 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
Tang Yingying523322d2017-01-17 23:28:43 +080084#define GET_IE_LEN_IN_BSS_DESC(lenInBss) (lenInBss + sizeof(lenInBss) - \
85 ((uintptr_t)OFFSET_OF(tSirBssDescription, ieFields)))
86
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080087#ifdef FEATURE_WLAN_CH_AVOID
Amar Singhalb8d4f152016-02-10 10:21:43 -080088sapSafeChannelType safe_channels[NUM_CHANNELS] = {
89 {1, true},
90 {2, true},
91 {3, true},
92 {4, true},
93 {5, true},
94 {6, true},
95 {7, true},
96 {8, true},
97 {9, true},
98 {10, true},
99 {11, true},
100 {12, true},
101 {13, true},
102 {14, true},
103 {36, true},
104 {40, true},
105 {44, true},
106 {48, true},
107 {52, true},
108 {56, true},
109 {60, true},
110 {64, true},
111 {100, true},
112 {104, true},
113 {108, true},
114 {112, true},
115 {116, true},
116 {120, true},
117 {124, true},
118 {128, true},
119 {132, true},
120 {136, true},
121 {140, true},
122 {144, true},
123 {149, true},
124 {153, true},
125 {157, true},
126 {161, true},
127 {165, true},
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800128};
129#endif
130
131typedef struct {
132 uint16_t chStartNum;
133 uint32_t weight;
134} sapAcsChannelInfo;
135
136sapAcsChannelInfo acs_ht40_channels5_g[] = {
137 {36, SAP_ACS_WEIGHT_MAX},
138 {44, SAP_ACS_WEIGHT_MAX},
139 {52, SAP_ACS_WEIGHT_MAX},
140 {60, SAP_ACS_WEIGHT_MAX},
141 {100, SAP_ACS_WEIGHT_MAX},
142 {108, SAP_ACS_WEIGHT_MAX},
143 {116, SAP_ACS_WEIGHT_MAX},
144 {124, SAP_ACS_WEIGHT_MAX},
145 {132, SAP_ACS_WEIGHT_MAX},
146 {140, SAP_ACS_WEIGHT_MAX},
147 {149, SAP_ACS_WEIGHT_MAX},
148 {157, SAP_ACS_WEIGHT_MAX},
149};
150
151sapAcsChannelInfo acs_ht80_channels[] = {
152 {36, SAP_ACS_WEIGHT_MAX},
153 {52, SAP_ACS_WEIGHT_MAX},
154 {100, SAP_ACS_WEIGHT_MAX},
155 {116, SAP_ACS_WEIGHT_MAX},
156 {132, SAP_ACS_WEIGHT_MAX},
157 {149, SAP_ACS_WEIGHT_MAX},
158};
159
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -0700160sapAcsChannelInfo acs_vht160_channels[] = {
161 {36, SAP_ACS_WEIGHT_MAX},
162 {100, SAP_ACS_WEIGHT_MAX},
163};
164
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800165sapAcsChannelInfo acs_ht40_channels24_g[] = {
166 {1, SAP_ACS_WEIGHT_MAX},
167 {2, SAP_ACS_WEIGHT_MAX},
168 {3, SAP_ACS_WEIGHT_MAX},
169 {4, SAP_ACS_WEIGHT_MAX},
170 {9, SAP_ACS_WEIGHT_MAX},
171};
172
173#define CHANNEL_165 165
174
175/* rssi discount for channels in PCL */
176#define PCL_RSSI_DISCOUNT 10
177
178#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
179/**
180 * sap_check_n_add_channel() - checks and add given channel in sap context's
181 * avoid_channels_info struct
182 * @sap_ctx: sap context.
183 * @new_channel: channel to be added to sap_ctx's avoid ch info
184 *
185 * sap_ctx contains sap_avoid_ch_info strcut containing the list of channels on
186 * which MDM device's AP with MCC was detected. This function will add channels
187 * to that list after checking for duplicates.
188 *
189 * Return: true: if channel was added or already present
190 * else false: if channel list was already full.
191 */
Tang Yingying523322d2017-01-17 23:28:43 +0800192static bool
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800193sap_check_n_add_channel(ptSapContext sap_ctx,
194 uint8_t new_channel)
195{
196 uint8_t i = 0;
197 struct sap_avoid_channels_info *ie_info =
198 &sap_ctx->sap_detected_avoid_ch_ie;
199
200 for (i = 0; i < sizeof(ie_info->channels); i++) {
201 if (ie_info->channels[i] == new_channel)
202 break;
203
204 if (ie_info->channels[i] == 0) {
205 ie_info->channels[i] = new_channel;
206 break;
207 }
208 }
209 if (i == sizeof(ie_info->channels))
210 return false;
211 else
212 return true;
213}
214/**
215 * sap_check_n_add_overlapped_chnls() - checks & add overlapped channels
216 * to primary channel in 2.4Ghz band.
217 * @sap_ctx: sap context.
218 * @primary_chnl: primary channel to be avoided.
219 *
220 * sap_ctx contains sap_avoid_ch_info struct containing the list of channels on
221 * which MDM device's AP with MCC was detected. This function will add channels
222 * to that list after checking for duplicates.
223 *
224 * Return: true: if channel was added or already present
225 * else false: if channel list was already full.
226 */
227static bool
228sap_check_n_add_overlapped_chnls(ptSapContext sap_ctx, uint8_t primary_channel)
229{
230 uint8_t i = 0, j = 0, upper_chnl = 0, lower_chnl = 0;
231 struct sap_avoid_channels_info *ie_info =
232 &sap_ctx->sap_detected_avoid_ch_ie;
233 /*
234 * if primary channel less than channel 1 or out of 2g band then
235 * no further process is required. return true in this case.
236 */
237 if (primary_channel < CHANNEL_1 || primary_channel > CHANNEL_14)
238 return true;
239
240 /* lower channel is one channel right before primary channel */
241 lower_chnl = primary_channel - 1;
242 /* upper channel is one channel right after primary channel */
243 upper_chnl = primary_channel + 1;
244
245 /* lower channel needs to be non-zero, zero is not valid channel */
246 if (lower_chnl > (CHANNEL_1 - 1)) {
247 for (i = 0; i < sizeof(ie_info->channels); i++) {
248 if (ie_info->channels[i] == lower_chnl)
249 break;
250 if (ie_info->channels[i] == 0) {
251 ie_info->channels[i] = lower_chnl;
252 break;
253 }
254 }
255 }
256 /* upper channel needs to be atleast last channel in 2.4Ghz band */
257 if (upper_chnl < (CHANNEL_14 + 1)) {
258 for (j = 0; j < sizeof(ie_info->channels); j++) {
259 if (ie_info->channels[j] == upper_chnl)
260 break;
261 if (ie_info->channels[j] == 0) {
262 ie_info->channels[j] = upper_chnl;
263 break;
264 }
265 }
266 }
267 if (i == sizeof(ie_info->channels) || j == sizeof(ie_info->channels))
268 return false;
269 else
270 return true;
271}
272
273/**
274 * sap_process_avoid_ie() - processes the detected Q2Q IE
275 * context's avoid_channels_info struct
276 * @hal: hal handle
277 * @sap_ctx: sap context.
278 * @scan_result: scan results for ACS scan.
279 * @spect_info: spectrum weights array to update
280 *
281 * Detection of Q2Q IE indicates presence of another MDM device with its AP
282 * operating in MCC mode. This function parses the scan results and processes
283 * the Q2Q IE if found. It then extracts the channels and populates them in
284 * sap_ctx struct. It also increases the weights of those channels so that
285 * ACS logic will avoid those channels in its selection algorithm.
286 *
287 * Return: void
288 */
Tang Yingying523322d2017-01-17 23:28:43 +0800289static void sap_process_avoid_ie(tHalHandle hal,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800290 ptSapContext sap_ctx,
291 tScanResultHandle scan_result,
292 tSapChSelSpectInfo *spect_info)
293{
294 uint32_t total_ie_len = 0;
295 uint8_t *temp_ptr = NULL;
296 uint8_t i = 0;
297 struct sAvoidChannelIE *avoid_ch_ie;
298 tCsrScanResultInfo *node = NULL;
299 tpAniSirGlobal mac_ctx = NULL;
300 tSapSpectChInfo *spect_ch = NULL;
301
302 mac_ctx = PMAC_STRUCT(hal);
303 spect_ch = spect_info->pSpectCh;
304 node = sme_scan_result_get_first(hal, scan_result);
305
306 while (node) {
Abhishek Singh34a4d862016-10-26 16:01:51 +0530307 total_ie_len =
308 GET_IE_LEN_IN_BSS_DESC(node->BssDescriptor.length);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800309 temp_ptr = cfg_get_vendor_ie_ptr_from_oui(mac_ctx,
310 SIR_MAC_QCOM_VENDOR_OUI,
311 SIR_MAC_QCOM_VENDOR_SIZE,
312 ((uint8_t *)&node->BssDescriptor.ieFields),
313 total_ie_len);
314
315 if (temp_ptr) {
316 avoid_ch_ie = (struct sAvoidChannelIE *)temp_ptr;
317 if (avoid_ch_ie->type != QCOM_VENDOR_IE_MCC_AVOID_CH)
318 continue;
319
320 sap_ctx->sap_detected_avoid_ch_ie.present = 1;
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530321 QDF_TRACE(QDF_MODULE_ID_SAP,
322 QDF_TRACE_LEVEL_DEBUG,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800323 "Q2Q IE - avoid ch %d",
324 avoid_ch_ie->channel);
325 /* add this channel to to_avoid channel list */
326 sap_check_n_add_channel(sap_ctx,
327 avoid_ch_ie->channel);
328 sap_check_n_add_overlapped_chnls(sap_ctx,
329 avoid_ch_ie->channel);
330 /*
331 * Mark weight of these channel present in IE to MAX
332 * so that ACS logic will to avoid thse channels
333 */
334 for (i = 0; i < spect_info->numSpectChans; i++)
335 if (spect_ch[i].chNum == avoid_ch_ie->channel) {
336 /*
337 * weight is set more than max so that,
338 * in the case of other channels being
339 * assigned max weight due to noise,
340 * they may be preferred over channels
341 * with Q2Q IE.
342 */
343 spect_ch[i].weight = SAP_ACS_WEIGHT_MAX + 1;
344 spect_ch[i].weight_copy =
345 SAP_ACS_WEIGHT_MAX + 1;
346 break;
347 }
348 } /* if (temp_ptr) */
349 node = sme_scan_result_get_next(hal, scan_result);
350 }
351}
352#endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
353
354#ifdef FEATURE_WLAN_CH_AVOID
355/*==========================================================================
356 FUNCTION sap_update_unsafe_channel_list
357
358 DESCRIPTION
359 Function Undate unsafe channel list table
360
361 DEPENDENCIES
362 NA.
363
364 IN
365 SapContext pointer
366
367 RETURN VALUE
368 NULL
369 ============================================================================*/
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800370void sap_update_unsafe_channel_list(ptSapContext pSapCtx)
371{
372 uint16_t i, j;
Amar Singhalb8d4f152016-02-10 10:21:43 -0800373 uint16_t unsafe_channel_list[NUM_CHANNELS];
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800374 uint16_t unsafe_channel_count = 0;
Yuanyuan Liu0e0aa932016-05-12 10:17:58 -0700375 qdf_device_t qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800376
Yuanyuan Liu97361182016-06-06 09:38:04 -0700377 if (!qdf_ctx) {
378 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_FATAL,
379 "qdf_ctx is NULL");
380 return;
381 }
382
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800383 /* Flush, default set all channel safe */
Amar Singhalb8d4f152016-02-10 10:21:43 -0800384 for (i = 0; i < NUM_CHANNELS; i++) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800385 safe_channels[i].isSafe = true;
386 }
387
388 /* Try to find unsafe channel */
Ryan Hsu4252a2f2016-01-05 11:18:24 -0800389#if defined(FEATURE_WLAN_STA_AP_MODE_DFS_DISABLE)
Amar Singhalb8d4f152016-02-10 10:21:43 -0800390 for (i = 0; i < NUM_CHANNELS; i++) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800391 if (pSapCtx->dfs_ch_disable == true) {
392 if (CDS_IS_DFS_CH(safe_channels[i].channelNumber)) {
393 safe_channels[i].isSafe = false;
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530394 QDF_TRACE(QDF_MODULE_ID_SAP,
395 QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800396 "%s: DFS Ch %d is not safe in"
397 " Concurrent mode",
398 __func__,
399 safe_channels[i].channelNumber);
400 }
401 }
402 }
403#endif
Yuanyuan Liu0e0aa932016-05-12 10:17:58 -0700404 pld_get_wlan_unsafe_channel(qdf_ctx->dev,
405 unsafe_channel_list,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800406 &unsafe_channel_count,
407 sizeof(unsafe_channel_list));
408
409 for (i = 0; i < unsafe_channel_count; i++) {
Amar Singhalb8d4f152016-02-10 10:21:43 -0800410 for (j = 0; j < NUM_CHANNELS; j++) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800411 if (safe_channels[j].channelNumber ==
412 unsafe_channel_list[i]) {
413 /* Found unsafe channel, update it */
414 safe_channels[j].isSafe = false;
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530415 QDF_TRACE(QDF_MODULE_ID_SAP,
416 QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800417 FL("CH %d is not safe"),
418 unsafe_channel_list[i]);
419 break;
420 }
421 }
422 }
423
424 return;
425}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800426
427#endif /* FEATURE_WLAN_CH_AVOID */
428
429/*==========================================================================
430 FUNCTION sap_cleanup_channel_list
431
432 DESCRIPTION
433 Function sap_cleanup_channel_list frees up the memory allocated to the channel list.
434
435 DEPENDENCIES
436 NA.
437
438 PARAMETERS
439
440 IN
441 NULL
442
443 RETURN VALUE
444 NULL
445 ============================================================================*/
446
Ryan Hsu4252a2f2016-01-05 11:18:24 -0800447void sap_cleanup_channel_list(void *p_cds_gctx)
448{
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800449 ptSapContext pSapCtx;
450
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530451 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800452 "Cleaning up the channel list structure");
453
454 if (NULL == p_cds_gctx) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530455 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800456 "SAP Global Context is NULL");
457 return;
458 }
459
460 pSapCtx = CDS_GET_SAP_CB(p_cds_gctx);
461 if (NULL == pSapCtx) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530462 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800463 "SAP Context is NULL");
464 return;
465 }
466
467 pSapCtx->SapChnlList.numChannel = 0;
468 if (pSapCtx->SapChnlList.channelList) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530469 qdf_mem_free(pSapCtx->SapChnlList.channelList);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800470 pSapCtx->SapChnlList.channelList = NULL;
471 }
472
473 pSapCtx->SapAllChnlList.numChannel = 0;
474 if (pSapCtx->SapAllChnlList.channelList) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530475 qdf_mem_free(pSapCtx->SapAllChnlList.channelList);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800476 pSapCtx->SapAllChnlList.channelList = NULL;
477 }
478}
479
480/**
481 * sap_select_preferred_channel_from_channel_list() - to calc best cahnnel
482 * @best_chnl: best channel already calculated among all the chanels
483 * @sap_ctx: sap context
484 * @spectinfo_param: Pointer to tSapChSelSpectInfo structure
485 *
486 * This function calculates the best channel among the configured channel list.
487 * If channel list not configured then returns the best channel calculated
488 * among all the channel list.
489 *
490 * Return: uint8_t best channel
491 */
Jeff Johnson464f7ea2016-10-07 10:21:26 -0700492static
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800493uint8_t sap_select_preferred_channel_from_channel_list(uint8_t best_chnl,
494 ptSapContext sap_ctx,
495 tSapChSelSpectInfo *spectinfo_param)
496{
497 uint8_t i = 0;
498
499 /*
500 * If Channel List is not Configured don't do anything
501 * Else return the Best Channel from the Channel List
502 */
503 if ((NULL == sap_ctx->acs_cfg->ch_list) ||
504 (NULL == spectinfo_param) ||
505 (0 == sap_ctx->acs_cfg->ch_list_count))
506 return best_chnl;
507
508 if (best_chnl <= 0 || best_chnl > 252)
509 return SAP_CHANNEL_NOT_SELECTED;
510
511 /* Select the best channel from allowed list */
512 for (i = 0; i < sap_ctx->acs_cfg->ch_list_count; i++) {
513 if (sap_ctx->acs_cfg->ch_list[i] == best_chnl) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530514 QDF_TRACE(QDF_MODULE_ID_SAP,
515 QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800516 "Best channel is: %d",
517 best_chnl);
518 return best_chnl;
519 }
520 }
521
522 return SAP_CHANNEL_NOT_SELECTED;
523}
524
525/*==========================================================================
526 FUNCTION sap_chan_sel_init
527
528 DESCRIPTION
529 Function sap_chan_sel_init allocates the memory, intializes the
Anurag Chouhan6d760662016-02-20 16:05:43 +0530530 structures used by the channel selection algorithm
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800531
532 DEPENDENCIES
533 NA.
534
535 PARAMETERS
536
537 IN
538 halHandle : Pointer to tHalHandle
539 *pSpectInfoParams : Pointer to tSapChSelSpectInfo structure
540 pSapCtx : Pointer to SAP Context
541
542 RETURN VALUE
543 bool: Success or FAIL
544
545 SIDE EFFECTS
546 ============================================================================*/
Jeff Johnson464f7ea2016-10-07 10:21:26 -0700547static bool sap_chan_sel_init(tHalHandle halHandle,
548 tSapChSelSpectInfo *pSpectInfoParams,
549 ptSapContext pSapCtx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800550{
551 tSapSpectChInfo *pSpectCh = NULL;
552 uint8_t *pChans = NULL;
553 uint16_t channelnum = 0;
554 tpAniSirGlobal pMac = PMAC_STRUCT(halHandle);
555 bool chSafe = true;
556#ifdef FEATURE_WLAN_CH_AVOID
557 uint16_t i;
558#endif
559 uint32_t dfs_master_cap_enabled;
560 bool include_dfs_ch = true;
561
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530562 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, "In %s",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800563 __func__);
564
565 pSpectInfoParams->numSpectChans =
566 pMac->scan.base_channels.numChannels;
567
568 /* Allocate memory for weight computation of 2.4GHz */
569 pSpectCh =
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530570 (tSapSpectChInfo *) qdf_mem_malloc((pSpectInfoParams->numSpectChans)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800571 * sizeof(*pSpectCh));
572
573 if (pSpectCh == NULL) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530574 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
Anurag Chouhanf04e84f2016-03-03 10:12:12 +0530575 "In %s, QDF_MALLOC_ERR", __func__);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800576 return eSAP_FALSE;
577 }
578
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800579 /* Initialize the pointers in the DfsParams to the allocated memory */
580 pSpectInfoParams->pSpectCh = pSpectCh;
581
582 pChans = pMac->scan.base_channels.channelList;
583
Ryan Hsu4252a2f2016-01-05 11:18:24 -0800584#if defined(FEATURE_WLAN_STA_AP_MODE_DFS_DISABLE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800585 if (pSapCtx->dfs_ch_disable == true)
586 include_dfs_ch = false;
587#endif
588 sme_cfg_get_int(halHandle, WNI_CFG_DFS_MASTER_ENABLED,
589 &dfs_master_cap_enabled);
Agrawal Ashish65634612016-08-18 13:24:32 +0530590 if (dfs_master_cap_enabled == 0 ||
591 ACS_DFS_MODE_DISABLE == pSapCtx->dfs_mode)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800592 include_dfs_ch = false;
593
594 /* Fill the channel number in the spectrum in the operating freq band */
595 for (channelnum = 0;
596 channelnum < pSpectInfoParams->numSpectChans;
Edhar, Mahesh Kumar4f660672015-10-30 11:53:26 +0530597 channelnum++, pChans++, pSpectCh++) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800598 chSafe = true;
599
600 /* check if the channel is in NOL blacklist */
601 if (sap_dfs_is_channel_in_nol_list(pSapCtx, *pChans,
602 PHY_SINGLE_CHANNEL_CENTERED)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530603 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800604 "In %s, Ch %d is in NOL list", __func__,
605 *pChans);
606 chSafe = false;
607 continue;
608 }
609
610 if (include_dfs_ch == false) {
611 if (CDS_IS_DFS_CH(*pChans)) {
612 chSafe = false;
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530613 QDF_TRACE(QDF_MODULE_ID_SAP,
614 QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800615 "In %s, DFS Ch %d not considered for ACS",
616 __func__, *pChans);
617 continue;
618 }
619 }
620
621#ifdef FEATURE_WLAN_CH_AVOID
Amar Singhalb8d4f152016-02-10 10:21:43 -0800622 for (i = 0; i < NUM_CHANNELS; i++) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800623 if ((safe_channels[i].channelNumber == *pChans) &&
624 (false == safe_channels[i].isSafe)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530625 QDF_TRACE(QDF_MODULE_ID_SAP,
626 QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800627 "In %s, Ch %d is not safe", __func__,
628 *pChans);
629 chSafe = false;
630 break;
631 }
632 }
633#endif /* FEATURE_WLAN_CH_AVOID */
634
635 /* OFDM rates are not supported on channel 14 */
636 if (*pChans == 14 &&
637 eCSR_DOT11_MODE_11b != pSapCtx->csr_roamProfile.phyMode) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800638 continue;
639 }
640
Deepthi Gowri48b89332016-08-30 18:43:05 +0530641 /* Skip DSRC channels */
642 if (cds_is_dsrc_channel(cds_chan_to_freq(*pChans)))
643 continue;
644
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800645 if (true == chSafe) {
646 pSpectCh->chNum = *pChans;
647 pSpectCh->valid = eSAP_TRUE;
648 pSpectCh->rssiAgr = SOFTAP_MIN_RSSI; /* Initialise for all channels */
649 pSpectCh->channelWidth = SOFTAP_HT20_CHANNELWIDTH; /* Initialise 20MHz for all the Channels */
650 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800651 }
652 return eSAP_TRUE;
653}
654
655/*==========================================================================
656 FUNCTION sapweight_rssi_count
657
658 DESCRIPTION
659 Function weightRssiCount calculates the channel weight due to rssi
Anurag Chouhan6d760662016-02-20 16:05:43 +0530660 and data count(here number of BSS observed)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800661
662 DEPENDENCIES
663 NA.
664
665 PARAMETERS
666
667 IN
668 rssi : Max signal strength receieved from a BSS for the channel
669 count : Number of BSS observed in the channel
670
671 RETURN VALUE
672 uint32_t : Calculated channel weight based on above two
673
674 SIDE EFFECTS
675 ============================================================================*/
Jeff Johnson464f7ea2016-10-07 10:21:26 -0700676static uint32_t sapweight_rssi_count(int8_t rssi, uint16_t count)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800677{
678 int32_t rssiWeight = 0;
679 int32_t countWeight = 0;
680 uint32_t rssicountWeight = 0;
681
682 /* Weight from RSSI */
683 rssiWeight = SOFTAP_RSSI_WEIGHT * (rssi - SOFTAP_MIN_RSSI)
684 / (SOFTAP_MAX_RSSI - SOFTAP_MIN_RSSI);
685
686 if (rssiWeight > SOFTAP_RSSI_WEIGHT)
687 rssiWeight = SOFTAP_RSSI_WEIGHT;
688 else if (rssiWeight < 0)
689 rssiWeight = 0;
690
691 /* Weight from data count */
692 countWeight = SOFTAP_COUNT_WEIGHT * (count - SOFTAP_MIN_COUNT)
693 / (SOFTAP_MAX_COUNT - SOFTAP_MIN_COUNT);
694
695 if (countWeight > SOFTAP_COUNT_WEIGHT)
696 countWeight = SOFTAP_COUNT_WEIGHT;
697
698 rssicountWeight = rssiWeight + countWeight;
699
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530700 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800701 "In %s, rssiWeight=%d, countWeight=%d, rssicountWeight=%d",
702 __func__, rssiWeight, countWeight, rssicountWeight);
703
704 return rssicountWeight;
705}
706
707/**
708 * sap_update_rssi_bsscount() - updates bss count and rssi effect.
709 *
710 * @pSpectCh: Channel Information
711 * @offset: Channel Offset
712 * @sap_24g: Channel is in 2.4G or 5G
Liangwei Dong71ed6502016-10-20 03:40:45 -0400713 * @spectch_start: the start of spect ch array
714 * @spectch_end: the end of spect ch array
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800715 *
716 * sap_update_rssi_bsscount updates bss count and rssi effect based
717 * on the channel offset.
718 *
719 * Return: None.
720 */
721
Jeff Johnson464f7ea2016-10-07 10:21:26 -0700722static void sap_update_rssi_bsscount(tSapSpectChInfo *pSpectCh, int32_t offset,
Liangwei Dong71ed6502016-10-20 03:40:45 -0400723 bool sap_24g, tSapSpectChInfo *spectch_start,
724 tSapSpectChInfo *spectch_end)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800725{
726 tSapSpectChInfo *pExtSpectCh = NULL;
727 int32_t rssi, rsssi_effect;
728
729 pExtSpectCh = (pSpectCh + offset);
Liangwei Dong71ed6502016-10-20 03:40:45 -0400730 if (pExtSpectCh != NULL &&
731 pExtSpectCh >= spectch_start &&
732 pExtSpectCh < spectch_end) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800733 ++pExtSpectCh->bssCount;
734 switch (offset) {
735 case -1:
736 case 1:
737 rsssi_effect = sap_24g ?
738 SAP_24GHZ_FIRST_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY :
739 SAP_SUBBAND1_RSSI_EFFECT_PRIMARY;
740 break;
741 case -2:
742 case 2:
743 rsssi_effect = sap_24g ?
744 SAP_24GHZ_SEC_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY :
745 SAP_SUBBAND2_RSSI_EFFECT_PRIMARY;
746 break;
747 case -3:
748 case 3:
749 rsssi_effect = sap_24g ?
750 SAP_24GHZ_THIRD_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY :
751 SAP_SUBBAND3_RSSI_EFFECT_PRIMARY;
752 break;
753 case -4:
754 case 4:
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -0700755 rsssi_effect = sap_24g ?
756 SAP_24GHZ_FOURTH_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY :
757 SAP_SUBBAND4_RSSI_EFFECT_PRIMARY;
758 break;
759 case -5:
760 case 5:
761 rsssi_effect = SAP_SUBBAND5_RSSI_EFFECT_PRIMARY;
762 break;
763 case -6:
764 case 6:
765 rsssi_effect = SAP_SUBBAND6_RSSI_EFFECT_PRIMARY;
766 break;
767 case -7:
768 case 7:
769 rsssi_effect = SAP_SUBBAND7_RSSI_EFFECT_PRIMARY;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800770 break;
771 default:
772 rsssi_effect = 0;
773 break;
774 }
775
776 rssi = pSpectCh->rssiAgr + rsssi_effect;
777 if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi))
778 pExtSpectCh->rssiAgr = rssi;
779 if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI)
780 pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI;
781 }
782}
783
784/**
785 * sap_upd_chan_spec_params() - sap_upd_chan_spec_params
786 * updates channel parameters obtained from Beacon
787 * @pBeaconStruct Beacon strucutre populated by parse_beacon function
788 * @channelWidth Channel width
789 * @secondaryChannelOffset Secondary Channel Offset
790 * @vhtSupport If channel supports VHT
791 * @centerFreq Central frequency for the given channel.
792 *
793 * sap_upd_chan_spec_params updates the spectrum channels based on the
794 * pBeaconStruct obtained from Beacon IE
795 *
796 * Return: NA.
797 */
798
Jeff Johnson464f7ea2016-10-07 10:21:26 -0700799static void sap_upd_chan_spec_params(tSirProbeRespBeacon *pBeaconStruct,
800 uint16_t *channelWidth,
801 uint16_t *secondaryChannelOffset,
802 uint16_t *vhtSupport,
803 uint16_t *centerFreq,
804 uint16_t *centerFreq_2)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800805{
806 if (NULL == pBeaconStruct) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530807 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800808 FL("pBeaconStruct is NULL"));
809 return;
810 }
811
812 if (pBeaconStruct->HTCaps.present && pBeaconStruct->HTInfo.present) {
813 *channelWidth = pBeaconStruct->HTCaps.supportedChannelWidthSet;
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -0700814 *secondaryChannelOffset =
815 pBeaconStruct->HTInfo.secondaryChannelOffset;
816 if (!pBeaconStruct->VHTOperation.present)
817 return;
818 *vhtSupport = pBeaconStruct->VHTOperation.present;
819 if (pBeaconStruct->VHTOperation.chanWidth) {
820 *centerFreq =
821 pBeaconStruct->VHTOperation.chanCenterFreqSeg1;
822 *centerFreq_2 =
823 pBeaconStruct->VHTOperation.chanCenterFreqSeg2;
824 /*
825 * LHS follows tSirMacHTChannelWidth, while RHS follows
826 * WNI_CFG_VHT_CHANNEL_WIDTH_X format hence following
827 * adjustment
828 */
829 *channelWidth =
830 pBeaconStruct->VHTOperation.chanWidth + 1;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800831
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800832 }
833 }
834}
835
836/**
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -0700837 * sap_update_rssi_bsscount_vht_5G() - updates bss count and rssi effect.
838 *
Jeff Johnson464f7ea2016-10-07 10:21:26 -0700839 * @spect_ch: Channel Information
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -0700840 * @offset: Channel Offset
841 * @num_ch: no.of channels
Liangwei Dong71ed6502016-10-20 03:40:45 -0400842 * @spectch_start: the start of spect ch array
843 * @spectch_end: the end of spect ch array
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -0700844 *
845 * sap_update_rssi_bsscount_vht_5G updates bss count and rssi effect based
846 * on the channel offset.
847 *
848 * Return: None.
849 */
850
Jeff Johnson464f7ea2016-10-07 10:21:26 -0700851static void sap_update_rssi_bsscount_vht_5G(tSapSpectChInfo *spect_ch,
852 int32_t offset,
Liangwei Dong71ed6502016-10-20 03:40:45 -0400853 uint16_t num_ch,
854 tSapSpectChInfo *spectch_start,
855 tSapSpectChInfo *spectch_end)
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -0700856{
857 int32_t ch_offset;
858 uint16_t i, cnt;
859
860 if (!offset)
861 return;
862 if (offset > 0)
863 cnt = num_ch;
864 else
865 cnt = num_ch + 1;
866 for (i = 0; i < cnt; i++) {
867 ch_offset = offset + i;
868 if (ch_offset == 0)
869 continue;
Liangwei Dong71ed6502016-10-20 03:40:45 -0400870 sap_update_rssi_bsscount(spect_ch, ch_offset, false,
871 spectch_start, spectch_end);
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -0700872 }
873}
874/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800875 * sap_interference_rssi_count_5G() - sap_interference_rssi_count
876 * considers the Adjacent channel rssi and
877 * data count(here number of BSS observed)
878 * @spect_ch: Channel Information
879 * @chan_width: Channel width parsed from beacon IE
880 * @sec_chan_offset: Secondary Channel Offset
881 * @center_freq: Central frequency for the given channel.
882 * @channel_id: channel_id
Liangwei Dong71ed6502016-10-20 03:40:45 -0400883 * @spectch_start: the start of spect ch array
884 * @spectch_end: the end of spect ch array
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800885 *
886 * sap_interference_rssi_count_5G considers the Adjacent channel rssi
887 * and data count(here number of BSS observed)
888 *
889 * Return: NA.
890 */
891
Jeff Johnson464f7ea2016-10-07 10:21:26 -0700892static void sap_interference_rssi_count_5G(tSapSpectChInfo *spect_ch,
893 uint16_t chan_width,
894 uint16_t sec_chan_offset,
895 uint16_t center_freq,
896 uint16_t center_freq_2,
Liangwei Dong71ed6502016-10-20 03:40:45 -0400897 uint8_t channel_id,
898 tSapSpectChInfo *spectch_start,
899 tSapSpectChInfo *spectch_end)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800900{
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -0700901 uint16_t num_ch;
902 int32_t offset = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800903 if (NULL == spect_ch) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530904 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800905 FL("spect_ch is NULL"));
906 return;
907 }
908
909 /* Updating the received ChannelWidth */
910 if (spect_ch->channelWidth != chan_width)
911 spect_ch->channelWidth = chan_width;
912 /* If received ChannelWidth is other than HT20,
913 * we need to update the extension channel Params as well
914 * chan_width == 0, HT20
915 * chan_width == 1, HT40
916 * chan_width == 2, VHT80
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -0700917 * chan_width == 3, VHT160
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800918 */
919
920 switch (spect_ch->channelWidth) {
921 case eHT_CHANNEL_WIDTH_40MHZ: /* HT40 */
922 switch (sec_chan_offset) {
923 /* Above the Primary Channel */
924 case PHY_DOUBLE_CHANNEL_LOW_PRIMARY:
Liangwei Dong71ed6502016-10-20 03:40:45 -0400925 sap_update_rssi_bsscount(spect_ch, 1, false,
926 spectch_start, spectch_end);
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -0700927 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800928
929 /* Below the Primary channel */
930 case PHY_DOUBLE_CHANNEL_HIGH_PRIMARY:
Liangwei Dong71ed6502016-10-20 03:40:45 -0400931 sap_update_rssi_bsscount(spect_ch, -1, false,
932 spectch_start, spectch_end);
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -0700933 return;
934 }
935 return;
936 case eHT_CHANNEL_WIDTH_80MHZ: /* VHT80 */
937 num_ch = 3;
938 if ((center_freq - channel_id) == 6) {
939 offset = 1;
940 } else if ((center_freq - channel_id) == 2) {
941 offset = -1;
942 } else if ((center_freq - channel_id) == -2) {
943 offset = -2;
944 } else if ((center_freq - channel_id) == -6) {
945 offset = -3;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800946 }
947 break;
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -0700948 case eHT_CHANNEL_WIDTH_160MHZ: /* VHT160 */
949 num_ch = 7;
950 if ((center_freq - channel_id) == 14)
951 offset = 1;
952 else if ((center_freq - channel_id) == 10)
953 offset = -1;
954 else if ((center_freq - channel_id) == 6)
955 offset = -2;
956 else if ((center_freq - channel_id) == 2)
957 offset = -3;
958 else if ((center_freq - channel_id) == -2)
959 offset = -4;
960 else if ((center_freq - channel_id) == -6)
961 offset = -5;
962 else if ((center_freq - channel_id) == -10)
963 offset = -6;
964 else if ((center_freq - channel_id) == -14)
965 offset = -7;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800966 break;
967 default:
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -0700968 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800969 }
Liangwei Dong71ed6502016-10-20 03:40:45 -0400970 sap_update_rssi_bsscount_vht_5G(spect_ch, offset, num_ch,
971 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800972}
973
974/**
975 * sap_interference_rssi_count() - sap_interference_rssi_count
976 * considers the Adjacent channel rssi
977 * and data count(here number of BSS observed)
978 * @spect_ch Channel Information
Liangwei Dong71ed6502016-10-20 03:40:45 -0400979 * @spectch_start: the start of spect ch array
980 * @spectch_end: the end of spect ch array
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800981 *
982 * sap_interference_rssi_count considers the Adjacent channel rssi
983 * and data count(here number of BSS observed)
984 *
985 * Return: None.
986 */
987
Liangwei Dong71ed6502016-10-20 03:40:45 -0400988static void sap_interference_rssi_count(tSapSpectChInfo *spect_ch,
989 tSapSpectChInfo *spectch_start,
990 tSapSpectChInfo *spectch_end)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800991{
992 if (NULL == spect_ch) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530993 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800994 "%s: spect_ch is NULL", __func__);
995 return;
996 }
997
998 switch (spect_ch->chNum) {
999 case CHANNEL_1:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001000 sap_update_rssi_bsscount(spect_ch, 1, true,
1001 spectch_start, spectch_end);
1002 sap_update_rssi_bsscount(spect_ch, 2, true,
1003 spectch_start, spectch_end);
1004 sap_update_rssi_bsscount(spect_ch, 3, true,
1005 spectch_start, spectch_end);
1006 sap_update_rssi_bsscount(spect_ch, 4, true,
1007 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001008 break;
1009
1010 case CHANNEL_2:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001011 sap_update_rssi_bsscount(spect_ch, -1, true,
1012 spectch_start, spectch_end);
1013 sap_update_rssi_bsscount(spect_ch, 1, true,
1014 spectch_start, spectch_end);
1015 sap_update_rssi_bsscount(spect_ch, 2, true,
1016 spectch_start, spectch_end);
1017 sap_update_rssi_bsscount(spect_ch, 3, true,
1018 spectch_start, spectch_end);
1019 sap_update_rssi_bsscount(spect_ch, 4, true,
1020 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001021 break;
1022 case CHANNEL_3:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001023 sap_update_rssi_bsscount(spect_ch, -2, true,
1024 spectch_start, spectch_end);
1025 sap_update_rssi_bsscount(spect_ch, -1, true,
1026 spectch_start, spectch_end);
1027 sap_update_rssi_bsscount(spect_ch, 1, true,
1028 spectch_start, spectch_end);
1029 sap_update_rssi_bsscount(spect_ch, 2, true,
1030 spectch_start, spectch_end);
1031 sap_update_rssi_bsscount(spect_ch, 3, true,
1032 spectch_start, spectch_end);
1033 sap_update_rssi_bsscount(spect_ch, 4, true,
1034 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001035 break;
1036 case CHANNEL_4:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001037 sap_update_rssi_bsscount(spect_ch, -3, true,
1038 spectch_start, spectch_end);
1039 sap_update_rssi_bsscount(spect_ch, -2, true,
1040 spectch_start, spectch_end);
1041 sap_update_rssi_bsscount(spect_ch, -1, true,
1042 spectch_start, spectch_end);
1043 sap_update_rssi_bsscount(spect_ch, 1, true,
1044 spectch_start, spectch_end);
1045 sap_update_rssi_bsscount(spect_ch, 2, true,
1046 spectch_start, spectch_end);
1047 sap_update_rssi_bsscount(spect_ch, 3, true,
1048 spectch_start, spectch_end);
1049 sap_update_rssi_bsscount(spect_ch, 4, true,
1050 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001051 break;
1052
1053 case CHANNEL_5:
1054 case CHANNEL_6:
1055 case CHANNEL_7:
1056 case CHANNEL_8:
1057 case CHANNEL_9:
1058 case CHANNEL_10:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001059 sap_update_rssi_bsscount(spect_ch, -4, true,
1060 spectch_start, spectch_end);
1061 sap_update_rssi_bsscount(spect_ch, -3, true,
1062 spectch_start, spectch_end);
1063 sap_update_rssi_bsscount(spect_ch, -2, true,
1064 spectch_start, spectch_end);
1065 sap_update_rssi_bsscount(spect_ch, -1, true,
1066 spectch_start, spectch_end);
1067 sap_update_rssi_bsscount(spect_ch, 1, true,
1068 spectch_start, spectch_end);
1069 sap_update_rssi_bsscount(spect_ch, 2, true,
1070 spectch_start, spectch_end);
1071 sap_update_rssi_bsscount(spect_ch, 3, true,
1072 spectch_start, spectch_end);
1073 sap_update_rssi_bsscount(spect_ch, 4, true,
1074 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001075 break;
1076
1077 case CHANNEL_11:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001078 sap_update_rssi_bsscount(spect_ch, -4, true,
1079 spectch_start, spectch_end);
1080 sap_update_rssi_bsscount(spect_ch, -3, true,
1081 spectch_start, spectch_end);
1082 sap_update_rssi_bsscount(spect_ch, -2, true,
1083 spectch_start, spectch_end);
1084 sap_update_rssi_bsscount(spect_ch, -1, true,
1085 spectch_start, spectch_end);
1086 sap_update_rssi_bsscount(spect_ch, 1, true,
1087 spectch_start, spectch_end);
1088 sap_update_rssi_bsscount(spect_ch, 2, true,
1089 spectch_start, spectch_end);
1090 sap_update_rssi_bsscount(spect_ch, 3, true,
1091 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001092 break;
1093
1094 case CHANNEL_12:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001095 sap_update_rssi_bsscount(spect_ch, -4, true,
1096 spectch_start, spectch_end);
1097 sap_update_rssi_bsscount(spect_ch, -3, true,
1098 spectch_start, spectch_end);
1099 sap_update_rssi_bsscount(spect_ch, -2, true,
1100 spectch_start, spectch_end);
1101 sap_update_rssi_bsscount(spect_ch, -1, true,
1102 spectch_start, spectch_end);
1103 sap_update_rssi_bsscount(spect_ch, 1, true,
1104 spectch_start, spectch_end);
1105 sap_update_rssi_bsscount(spect_ch, 2, true,
1106 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001107 break;
1108
1109 case CHANNEL_13:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001110 sap_update_rssi_bsscount(spect_ch, -4, true,
1111 spectch_start, spectch_end);
1112 sap_update_rssi_bsscount(spect_ch, -3, true,
1113 spectch_start, spectch_end);
1114 sap_update_rssi_bsscount(spect_ch, -2, true,
1115 spectch_start, spectch_end);
1116 sap_update_rssi_bsscount(spect_ch, -1, true,
1117 spectch_start, spectch_end);
1118 sap_update_rssi_bsscount(spect_ch, 1, true,
1119 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001120 break;
1121
1122 case CHANNEL_14:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001123 sap_update_rssi_bsscount(spect_ch, -4, true,
1124 spectch_start, spectch_end);
1125 sap_update_rssi_bsscount(spect_ch, -3, true,
1126 spectch_start, spectch_end);
1127 sap_update_rssi_bsscount(spect_ch, -2, true,
1128 spectch_start, spectch_end);
1129 sap_update_rssi_bsscount(spect_ch, -1, true,
1130 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001131 break;
1132
1133 default:
1134 break;
1135 }
1136}
1137
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001138/**
1139 * ch_in_pcl() - Is channel in the Preferred Channel List (PCL)
1140 * @sap_ctx: SAP context which contains the current PCL
1141 * @channel: Input channel number to be checked
1142 *
1143 * Check if a channel is in the preferred channel list
1144 *
1145 * Return:
1146 * true: channel is in PCL,
1147 * false: channel is not in PCL
1148 */
1149static bool ch_in_pcl(ptSapContext sap_ctx, uint8_t channel)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001150{
1151 uint32_t i;
1152
1153 for (i = 0; i < sap_ctx->acs_cfg->pcl_ch_count; i++) {
1154 if (channel == sap_ctx->acs_cfg->pcl_channels[i])
1155 return true;
1156 }
1157
1158 return false;
1159}
1160
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001161/**
1162 * sap_compute_spect_weight() - Compute spectrum weight
1163 * @pSpectInfoParams: Pointer to the tSpectInfoParams structure
1164 * @halHandle: Pointer to HAL handle
1165 * @pResult: Pointer to tScanResultHandle
1166 * @sap_ctx: Context of the SAP
1167 *
1168 * Main function for computing the weight of each channel in the
1169 * spectrum based on the RSSI value of the BSSes on the channel
1170 * and number of BSS
1171 */
1172static void sap_compute_spect_weight(tSapChSelSpectInfo *pSpectInfoParams,
1173 tHalHandle halHandle,
1174 tScanResultHandle pResult,
1175 ptSapContext sap_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001176{
1177 int8_t rssi = 0;
1178 uint8_t chn_num = 0;
1179 uint8_t channel_id = 0;
1180
1181 tCsrScanResultInfo *pScanResult;
1182 tSapSpectChInfo *pSpectCh = pSpectInfoParams->pSpectCh;
1183 uint32_t operatingBand;
1184 uint16_t channelWidth;
1185 uint16_t secondaryChannelOffset;
1186 uint16_t centerFreq;
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001187 uint16_t centerFreq_2 = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001188 uint16_t vhtSupport;
1189 uint32_t ieLen = 0;
1190 tSirProbeRespBeacon *pBeaconStruct;
1191 tpAniSirGlobal pMac = (tpAniSirGlobal) halHandle;
Liangwei Dong71ed6502016-10-20 03:40:45 -04001192 tSapSpectChInfo *spectch_start = pSpectInfoParams->pSpectCh;
1193 tSapSpectChInfo *spectch_end = pSpectInfoParams->pSpectCh +
1194 pSpectInfoParams->numSpectChans;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001195
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301196 pBeaconStruct = qdf_mem_malloc(sizeof(tSirProbeRespBeacon));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001197 if (NULL == pBeaconStruct) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301198 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Kaushik, Sushantee3ed032016-08-04 16:40:46 +05301199 "Unable to allocate memory in sap_compute_spect_weight");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001200 return;
1201 }
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301202 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001203 "In %s, Computing spectral weight", __func__);
1204
1205 /**
1206 * Soft AP specific channel weight calculation using DFS formula
1207 */
1208 SET_ACS_BAND(operatingBand, sap_ctx);
1209
1210 pScanResult = sme_scan_result_get_first(halHandle, pResult);
1211
1212 while (pScanResult) {
1213 pSpectCh = pSpectInfoParams->pSpectCh;
1214 /* Defining the default values, so that any value will hold the default values */
1215 channelWidth = eHT_CHANNEL_WIDTH_20MHZ;
1216 secondaryChannelOffset = PHY_SINGLE_CHANNEL_CENTERED;
1217 vhtSupport = 0;
1218 centerFreq = 0;
1219
1220 if (pScanResult->BssDescriptor.ieFields != NULL) {
Abhishek Singh34a4d862016-10-26 16:01:51 +05301221 ieLen = GET_IE_LEN_IN_BSS(
1222 pScanResult->BssDescriptor.length);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301223 qdf_mem_set((uint8_t *) pBeaconStruct,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001224 sizeof(tSirProbeRespBeacon), 0);
1225
1226 if ((sir_parse_beacon_ie
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001227 (pMac, pBeaconStruct, (uint8_t *)
1228 (pScanResult->BssDescriptor.ieFields),
1229 ieLen)) == eSIR_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001230 sap_upd_chan_spec_params(pBeaconStruct,
1231 &channelWidth, &secondaryChannelOffset,
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001232 &vhtSupport, &centerFreq,
1233 &centerFreq_2);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001234 }
1235 }
1236 /* Processing for each tCsrScanResultInfo in the tCsrScanResult DLink list */
1237 for (chn_num = 0; chn_num < pSpectInfoParams->numSpectChans;
1238 chn_num++) {
1239
1240 /*
1241 * if the Beacon has channel ID, use it other wise we will
1242 * rely on the channelIdSelf
1243 */
1244 if (pScanResult->BssDescriptor.channelId == 0)
1245 channel_id =
1246 pScanResult->BssDescriptor.channelIdSelf;
1247 else
1248 channel_id =
1249 pScanResult->BssDescriptor.channelId;
1250
1251 if (pSpectCh && (channel_id == pSpectCh->chNum)) {
1252 if (pSpectCh->rssiAgr <
1253 pScanResult->BssDescriptor.rssi)
1254 pSpectCh->rssiAgr =
1255 pScanResult->BssDescriptor.rssi;
1256
1257 ++pSpectCh->bssCount; /* Increment the count of BSS */
1258
1259 /*
1260 * Connsidering the Extension Channel
1261 * only in a channels
1262 */
1263 switch (operatingBand) {
1264 case eCSR_DOT11_MODE_11a:
1265 sap_interference_rssi_count_5G(
1266 pSpectCh, channelWidth,
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001267 secondaryChannelOffset,
1268 centerFreq,
1269 centerFreq_2,
Liangwei Dong71ed6502016-10-20 03:40:45 -04001270 channel_id,
1271 spectch_start,
1272 spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001273 break;
1274
1275 case eCSR_DOT11_MODE_11g:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001276 sap_interference_rssi_count(pSpectCh,
1277 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001278 break;
1279
1280 case eCSR_DOT11_MODE_abg:
1281 sap_interference_rssi_count_5G(
1282 pSpectCh, channelWidth,
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001283 secondaryChannelOffset,
1284 centerFreq,
1285 centerFreq_2,
Liangwei Dong71ed6502016-10-20 03:40:45 -04001286 channel_id,
1287 spectch_start,
1288 spectch_end);
1289 sap_interference_rssi_count(pSpectCh,
1290 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001291 break;
1292 }
1293
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301294 QDF_TRACE(QDF_MODULE_ID_SAP,
1295 QDF_TRACE_LEVEL_INFO_HIGH,
Kaushik, Sushantee3ed032016-08-04 16:40:46 +05301296 "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 -08001297 __func__,
1298 pScanResult->BssDescriptor.
1299 channelIdSelf,
1300 pScanResult->BssDescriptor.channelId,
1301 pScanResult->BssDescriptor.rssi,
1302 pSpectCh->bssCount, pScanResult,
1303 pSpectCh->channelWidth,
1304 secondaryChannelOffset, centerFreq);
1305 pSpectCh++;
1306 break;
1307 } else {
1308 pSpectCh++;
1309 }
1310 }
1311
1312 pScanResult = sme_scan_result_get_next(halHandle, pResult);
1313 }
1314
1315 /* Calculate the weights for all channels in the spectrum pSpectCh */
1316 pSpectCh = pSpectInfoParams->pSpectCh;
1317
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301318 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001319 "In %s, Spectrum Channels Weight", __func__);
1320
1321 for (chn_num = 0; chn_num < (pSpectInfoParams->numSpectChans);
1322 chn_num++) {
1323
1324 /*
1325 rssi : Maximum received signal strength among all BSS on that channel
1326 bssCount : Number of BSS on that channel
1327 */
1328
1329 rssi = (int8_t) pSpectCh->rssiAgr;
1330 if (ch_in_pcl(sap_ctx, chn_num))
1331 rssi -= PCL_RSSI_DISCOUNT;
1332
1333 pSpectCh->weight =
1334 SAPDFS_NORMALISE_1000 * sapweight_rssi_count(rssi,
1335 pSpectCh->
1336 bssCount);
1337 pSpectCh->weight_copy = pSpectCh->weight;
1338
1339 /* ------ Debug Info ------ */
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301340 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001341 "In %s, Chan=%d Weight= %d rssiAgr=%d bssCount=%d",
1342 __func__, pSpectCh->chNum, pSpectCh->weight,
1343 pSpectCh->rssiAgr, pSpectCh->bssCount);
1344 /* ------ Debug Info ------ */
1345 pSpectCh++;
1346 }
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301347 qdf_mem_free(pBeaconStruct);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001348}
1349
1350/*==========================================================================
1351 FUNCTION sap_chan_sel_exit
1352
1353 DESCRIPTION
1354 Exit function for free out the allocated memory, to be called
1355 at the end of the dfsSelectChannel function
1356
1357 DEPENDENCIES
1358 NA.
1359
1360 PARAMETERS
1361
1362 IN
1363 pSpectInfoParams : Pointer to the tSapChSelSpectInfo structure
1364
1365 RETURN VALUE
1366 void : NULL
1367
1368 SIDE EFFECTS
1369 ============================================================================*/
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001370static void sap_chan_sel_exit(tSapChSelSpectInfo *pSpectInfoParams)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001371{
1372 /* Free all the allocated memory */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301373 qdf_mem_free(pSpectInfoParams->pSpectCh);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001374}
1375
1376/*==========================================================================
1377 FUNCTION sap_sort_chl_weight
1378
1379 DESCRIPTION
1380 Funtion to sort the channels with the least weight first for 20MHz channels
1381
1382 DEPENDENCIES
1383 NA.
1384
1385 PARAMETERS
1386
1387 IN
1388 pSpectInfoParams : Pointer to the tSapChSelSpectInfo structure
1389
1390 RETURN VALUE
1391 void : NULL
1392
1393 SIDE EFFECTS
1394 ============================================================================*/
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001395static void sap_sort_chl_weight(tSapChSelSpectInfo *pSpectInfoParams)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001396{
1397 tSapSpectChInfo temp;
1398
1399 tSapSpectChInfo *pSpectCh = NULL;
1400 uint32_t i = 0, j = 0, minWeightIndex = 0;
1401
1402 pSpectCh = pSpectInfoParams->pSpectCh;
1403 for (i = 0; i < pSpectInfoParams->numSpectChans; i++) {
1404 minWeightIndex = i;
1405 for (j = i + 1; j < pSpectInfoParams->numSpectChans; j++) {
1406 if (pSpectCh[j].weight <
1407 pSpectCh[minWeightIndex].weight) {
1408 minWeightIndex = j;
1409 }
1410 }
1411 if (minWeightIndex != i) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301412 qdf_mem_copy(&temp, &pSpectCh[minWeightIndex],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001413 sizeof(*pSpectCh));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301414 qdf_mem_copy(&pSpectCh[minWeightIndex], &pSpectCh[i],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001415 sizeof(*pSpectCh));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301416 qdf_mem_copy(&pSpectCh[i], &temp, sizeof(*pSpectCh));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001417 }
1418 }
1419}
1420
1421/**
1422 * sap_sort_chl_weight_ht80() - to sort the channels with the least weight
1423 * @pSpectInfoParams: Pointer to the tSapChSelSpectInfo structure
1424 *
1425 * Funtion to sort the channels with the least weight first for HT80 channels
1426 *
1427 * Return: none
1428 */
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001429static void sap_sort_chl_weight_ht80(tSapChSelSpectInfo *pSpectInfoParams)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001430{
1431 uint8_t i, j, n;
1432 tSapSpectChInfo *pSpectInfo;
1433 uint8_t minIdx;
1434
1435 pSpectInfo = pSpectInfoParams->pSpectCh;
1436 /* for each HT80 channel, calculate the combined weight of the
1437 four 20MHz weight */
1438 for (i = 0; i < ARRAY_SIZE(acs_ht80_channels); i++) {
1439 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
1440 if (pSpectInfo[j].chNum ==
1441 acs_ht80_channels[i].chStartNum)
1442 break;
1443 }
1444 if (j == pSpectInfoParams->numSpectChans)
1445 continue;
1446
1447 if (!(((pSpectInfo[j].chNum + 4) == pSpectInfo[j + 1].chNum) &&
1448 ((pSpectInfo[j].chNum + 8) ==
1449 pSpectInfo[j + 2].chNum) &&
1450 ((pSpectInfo[j].chNum + 12) ==
1451 pSpectInfo[j + 3].chNum))) {
1452 /*
1453 * some channels does not exist in pSectInfo array,
1454 * skip this channel and those in the same HT80 width
1455 */
1456 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 4;
1457 if ((pSpectInfo[j].chNum + 4) ==
1458 pSpectInfo[j + 1].chNum)
1459 pSpectInfo[j + 1].weight =
1460 SAP_ACS_WEIGHT_MAX * 4;
1461 if ((pSpectInfo[j].chNum + 8) ==
1462 pSpectInfo[j + 2].chNum)
1463 pSpectInfo[j + 2].weight =
1464 SAP_ACS_WEIGHT_MAX * 4;
1465 if ((pSpectInfo[j].chNum + 12) ==
1466 pSpectInfo[j + 3].chNum)
1467 pSpectInfo[j + 3].weight =
1468 SAP_ACS_WEIGHT_MAX * 4;
1469 continue;
1470 }
1471 /*found the channel, add the 4 adjacent channels' weight */
1472 acs_ht80_channels[i].weight = pSpectInfo[j].weight +
1473 pSpectInfo[j + 1].weight + pSpectInfo[j + 2].weight +
1474 pSpectInfo[j + 3].weight;
1475 /* find best channel among 4 channels as the primary channel */
1476 if ((pSpectInfo[j].weight + pSpectInfo[j + 1].weight) <
1477 (pSpectInfo[j + 2].weight + pSpectInfo[j + 3].weight)) {
1478 /* lower 2 channels are better choice */
1479 if (pSpectInfo[j].weight < pSpectInfo[j + 1].weight)
1480 minIdx = 0;
1481 else
1482 minIdx = 1;
1483 } else if (pSpectInfo[j + 2].weight <=
1484 pSpectInfo[j + 3].weight) {
1485 /* upper 2 channels are better choice */
1486 minIdx = 2;
1487 } else {
1488 minIdx = 3;
1489 }
1490
1491 /*
1492 * set all 4 channels to max value first, then reset the
1493 * best channel as the selected primary channel, update its
1494 * weightage with the combined weight value
1495 */
1496 for (n = 0; n < 4; n++)
1497 pSpectInfo[j + n].weight = SAP_ACS_WEIGHT_MAX * 4;
1498
1499 pSpectInfo[j + minIdx].weight = acs_ht80_channels[i].weight;
1500 }
1501
1502 pSpectInfo = pSpectInfoParams->pSpectCh;
1503 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
1504 if (CHANNEL_165 == pSpectInfo[j].chNum) {
1505 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 4;
1506 break;
1507 }
1508 }
1509
Manishekar Chandrasekaran44e334f2016-05-30 16:42:50 +05301510 sap_sort_chl_weight(pSpectInfoParams);
1511
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001512 pSpectInfo = pSpectInfoParams->pSpectCh;
1513 for (j = 0; j < (pSpectInfoParams->numSpectChans); j++) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301514 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001515 FL("Channel=%d Weight= %d rssi=%d bssCount=%d"),
1516 pSpectInfo->chNum, pSpectInfo->weight,
1517 pSpectInfo->rssiAgr, pSpectInfo->bssCount);
1518 pSpectInfo++;
1519 }
1520}
1521
1522/**
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001523 * sap_sort_chl_weight_vht160() - to sort the channels with the least weight
1524 * @pSpectInfoParams: Pointer to the tSapChSelSpectInfo structure
1525 *
1526 * Funtion to sort the channels with the least weight first for VHT160 channels
1527 *
1528 * Return: none
1529 */
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001530static void sap_sort_chl_weight_vht160(tSapChSelSpectInfo *pSpectInfoParams)
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001531{
1532 uint8_t i, j, n, idx;
1533 tSapSpectChInfo *pSpectInfo;
1534 uint8_t minIdx;
1535
1536 pSpectInfo = pSpectInfoParams->pSpectCh;
1537 /* for each VHT160 channel, calculate the combined weight of the
1538 8 20MHz weight */
1539 for (i = 0; i < ARRAY_SIZE(acs_vht160_channels); i++) {
1540 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
1541 if (pSpectInfo[j].chNum ==
1542 acs_vht160_channels[i].chStartNum)
1543 break;
1544 }
1545 if (j == pSpectInfoParams->numSpectChans)
1546 continue;
1547
1548 if (!(((pSpectInfo[j].chNum + 4) == pSpectInfo[j + 1].chNum) &&
1549 ((pSpectInfo[j].chNum + 8) ==
1550 pSpectInfo[j + 2].chNum) &&
1551 ((pSpectInfo[j].chNum + 12) ==
1552 pSpectInfo[j + 3].chNum) &&
1553 ((pSpectInfo[j].chNum + 16) ==
1554 pSpectInfo[j + 4].chNum) &&
1555 ((pSpectInfo[j].chNum + 20) ==
1556 pSpectInfo[j + 5].chNum) &&
1557 ((pSpectInfo[j].chNum + 24) ==
1558 pSpectInfo[j + 6].chNum) &&
1559 ((pSpectInfo[j].chNum + 28) ==
1560 pSpectInfo[j + 7].chNum))) {
1561 /*
1562 * some channels does not exist in pSectInfo array,
1563 * skip this channel and those in the same VHT160 width
1564 */
1565 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 8;
1566 if ((pSpectInfo[j].chNum + 4) ==
1567 pSpectInfo[j + 1].chNum)
1568 pSpectInfo[j + 1].weight =
1569 SAP_ACS_WEIGHT_MAX * 8;
1570 if ((pSpectInfo[j].chNum + 8) ==
1571 pSpectInfo[j + 2].chNum)
1572 pSpectInfo[j + 2].weight =
1573 SAP_ACS_WEIGHT_MAX * 8;
1574 if ((pSpectInfo[j].chNum + 12) ==
1575 pSpectInfo[j + 3].chNum)
1576 pSpectInfo[j + 3].weight =
1577 SAP_ACS_WEIGHT_MAX * 8;
1578 if ((pSpectInfo[j].chNum + 16) ==
1579 pSpectInfo[j + 4].chNum)
1580 pSpectInfo[j + 4].weight =
1581 SAP_ACS_WEIGHT_MAX * 8;
1582 if ((pSpectInfo[j].chNum + 20) ==
1583 pSpectInfo[j + 5].chNum)
1584 pSpectInfo[j + 5].weight =
1585 SAP_ACS_WEIGHT_MAX * 8;
1586 if ((pSpectInfo[j].chNum + 24) ==
1587 pSpectInfo[j + 6].chNum)
1588 pSpectInfo[j + 6].weight =
1589 SAP_ACS_WEIGHT_MAX * 8;
1590 if ((pSpectInfo[j].chNum + 28) ==
1591 pSpectInfo[j + 7].chNum)
1592 pSpectInfo[j + 7].weight =
1593 SAP_ACS_WEIGHT_MAX * 8;
1594 continue;
1595 }
1596 /*found the channel, add the 7 adjacent channels' weight */
1597 acs_vht160_channels[i].weight = pSpectInfo[j].weight +
1598 pSpectInfo[j + 1].weight + pSpectInfo[j + 2].weight +
1599 pSpectInfo[j + 3].weight + pSpectInfo[j + 4].weight +
1600 pSpectInfo[j + 5].weight + pSpectInfo[j + 6].weight +
1601 pSpectInfo[j + 7].weight;
1602
1603 /* find best channel among 8 channels as the primary channel */
1604 if ((pSpectInfo[j].weight + pSpectInfo[j + 1].weight +
1605 pSpectInfo[j + 2].weight + pSpectInfo[j + 3].weight) >
1606 (pSpectInfo[j + 4].weight + pSpectInfo[j + 5].weight +
1607 pSpectInfo[j + 6].weight + pSpectInfo[j + 7].weight))
1608 idx = 4;
1609 else
1610 idx = 0;
1611 /* find best channel among 4 channels as the primary channel */
1612 if ((pSpectInfo[j + idx].weight +
1613 pSpectInfo[j + idx + 1].weight) <
1614 (pSpectInfo[j + idx + 2].weight +
1615 pSpectInfo[j + idx + 3].weight)) {
1616 /* lower 2 channels are better choice */
1617 if (pSpectInfo[j + idx].weight <
1618 pSpectInfo[j + idx + 1].weight)
1619 minIdx = 0 + idx;
1620 else
1621 minIdx = 1 + idx;
1622 } else if (pSpectInfo[j + idx + 2].weight <=
1623 pSpectInfo[j + idx + 3].weight) {
1624 /* upper 2 channels are better choice */
1625 minIdx = 2 + idx;
1626 } else {
1627 minIdx = 3 + idx;
1628 }
1629
1630 /*
1631 * set all 8 channels to max value first, then reset the
1632 * best channel as the selected primary channel, update its
1633 * weightage with the combined weight value
1634 */
1635 for (n = 0; n < 8; n++)
1636 pSpectInfo[j + n].weight = SAP_ACS_WEIGHT_MAX * 8;
1637
1638 pSpectInfo[j + minIdx].weight = acs_vht160_channels[i].weight;
1639 }
1640
1641 pSpectInfo = pSpectInfoParams->pSpectCh;
1642 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
1643 if (CHANNEL_165 == pSpectInfo[j].chNum) {
1644 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 8;
1645 break;
1646 }
1647 }
1648
Manishekar Chandrasekaran44e334f2016-05-30 16:42:50 +05301649 sap_sort_chl_weight(pSpectInfoParams);
1650
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001651 pSpectInfo = pSpectInfoParams->pSpectCh;
1652 for (j = 0; j < (pSpectInfoParams->numSpectChans); j++) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301653 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001654 FL("Channel=%d Weight= %d rssi=%d bssCount=%d"),
1655 pSpectInfo->chNum, pSpectInfo->weight,
1656 pSpectInfo->rssiAgr, pSpectInfo->bssCount);
1657 pSpectInfo++;
1658 }
1659}
1660
1661/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001662 * sap_sort_chl_weight_ht40_24_g() - to sort channel with the least weight
1663 * @pSpectInfoParams: Pointer to the tSapChSelSpectInfo structure
1664 *
1665 * Funtion to sort the channels with the least weight first for HT40 channels
1666 *
1667 * Return: none
1668 */
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001669static void sap_sort_chl_weight_ht40_24_g(tSapChSelSpectInfo *pSpectInfoParams)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001670{
1671 uint8_t i, j;
1672 tSapSpectChInfo *pSpectInfo;
1673 uint32_t tmpWeight1, tmpWeight2;
1674
1675 pSpectInfo = pSpectInfoParams->pSpectCh;
1676 /*
1677 * for each HT40 channel, calculate the combined weight of the
1678 * two 20MHz weight
1679 */
1680 for (i = 0; i < ARRAY_SIZE(acs_ht40_channels24_g); i++) {
1681 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
1682 if (pSpectInfo[j].chNum ==
1683 acs_ht40_channels24_g[i].chStartNum)
1684 break;
1685 }
1686 if (j == pSpectInfoParams->numSpectChans)
1687 continue;
1688
1689 if (!((pSpectInfo[j].chNum + 4) == pSpectInfo[j + 4].chNum)) {
1690 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2;
1691 continue;
1692 }
1693 /*
1694 * check if there is another channel combination possiblity
1695 * e.g., {1, 5} & {5, 9}
1696 */
1697 if ((pSpectInfo[j + 4].chNum + 4) == pSpectInfo[j + 8].chNum) {
1698 /* need to compare two channel pairs */
1699 tmpWeight1 = pSpectInfo[j].weight +
1700 pSpectInfo[j + 4].weight;
1701 tmpWeight2 = pSpectInfo[j + 4].weight +
1702 pSpectInfo[j + 8].weight;
1703 if (tmpWeight1 <= tmpWeight2) {
1704 if (pSpectInfo[j].weight <=
1705 pSpectInfo[j + 4].weight) {
1706 pSpectInfo[j].weight =
1707 tmpWeight1;
1708 pSpectInfo[j + 4].weight =
1709 SAP_ACS_WEIGHT_MAX * 2;
1710 pSpectInfo[j + 8].weight =
1711 SAP_ACS_WEIGHT_MAX * 2;
1712 } else {
1713 pSpectInfo[j + 4].weight =
1714 tmpWeight1;
1715 /* for secondary channel selection */
1716 pSpectInfo[j].weight =
1717 SAP_ACS_WEIGHT_MAX * 2
1718 - 1;
1719 pSpectInfo[j + 8].weight =
1720 SAP_ACS_WEIGHT_MAX * 2;
1721 }
1722 } else {
1723 if (pSpectInfo[j + 4].weight <=
1724 pSpectInfo[j + 8].weight) {
1725 pSpectInfo[j + 4].weight =
1726 tmpWeight2;
1727 pSpectInfo[j].weight =
1728 SAP_ACS_WEIGHT_MAX * 2;
1729 /* for secondary channel selection */
1730 pSpectInfo[j + 8].weight =
1731 SAP_ACS_WEIGHT_MAX * 2
1732 - 1;
1733 } else {
1734 pSpectInfo[j + 8].weight =
1735 tmpWeight2;
1736 pSpectInfo[j].weight =
1737 SAP_ACS_WEIGHT_MAX * 2;
1738 pSpectInfo[j + 4].weight =
1739 SAP_ACS_WEIGHT_MAX * 2;
1740 }
1741 }
1742 } else {
1743 tmpWeight1 = pSpectInfo[j].weight +
1744 pSpectInfo[j + 4].weight;
1745 if (pSpectInfo[j].weight <=
1746 pSpectInfo[j + 4].weight) {
1747 pSpectInfo[j].weight = tmpWeight1;
1748 pSpectInfo[j + 4].weight =
1749 SAP_ACS_WEIGHT_MAX * 2;
1750 } else {
1751 pSpectInfo[j + 4].weight = tmpWeight1;
1752 pSpectInfo[j].weight =
1753 SAP_ACS_WEIGHT_MAX * 2;
1754 }
1755 }
1756 }
Manishekar Chandrasekaran44e334f2016-05-30 16:42:50 +05301757 sap_sort_chl_weight(pSpectInfoParams);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001758}
1759
1760/*==========================================================================
1761 FUNCTION sap_sort_chl_weight_ht40_5_g
1762
1763 DESCRIPTION
1764 Funtion to sort the channels with the least weight first for HT40 channels
1765
1766 DEPENDENCIES
1767 NA.
1768
1769 PARAMETERS
1770
1771 IN
1772 pSpectInfoParams : Pointer to the tSapChSelSpectInfo structure
1773
1774 RETURN VALUE
1775 void : NULL
1776
1777 SIDE EFFECTS
1778 ============================================================================*/
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001779static void sap_sort_chl_weight_ht40_5_g(tSapChSelSpectInfo *pSpectInfoParams)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001780{
1781 uint8_t i, j;
1782 tSapSpectChInfo *pSpectInfo;
1783
1784 pSpectInfo = pSpectInfoParams->pSpectCh;
1785 /*for each HT40 channel, calculate the combined weight of the
1786 two 20MHz weight */
1787 for (i = 0; i < ARRAY_SIZE(acs_ht40_channels5_g); i++) {
1788 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
1789 if (pSpectInfo[j].chNum ==
1790 acs_ht40_channels5_g[i].chStartNum)
1791 break;
1792 }
1793 if (j == pSpectInfoParams->numSpectChans)
1794 continue;
1795
1796 /* found the channel, add the two adjacent channels' weight */
1797 if ((pSpectInfo[j].chNum + 4) == pSpectInfo[j + 1].chNum) {
1798 acs_ht40_channels5_g[i].weight = pSpectInfo[j].weight +
1799 pSpectInfo[j + 1].weight;
1800 /* select better of the adjact channel as the primary channel */
1801 if (pSpectInfo[j].weight <= pSpectInfo[j + 1].weight) {
1802 pSpectInfo[j].weight =
1803 acs_ht40_channels5_g[i].weight;
1804 /* mark the adjacent channel's weight as max value so
1805 that it will be sorted to the bottom */
1806 pSpectInfo[j + 1].weight =
1807 SAP_ACS_WEIGHT_MAX * 2;
1808 } else {
1809 pSpectInfo[j + 1].weight =
1810 acs_ht40_channels5_g[i].weight;
1811 /* mark the adjacent channel's weight as max value so
1812 that it will be sorted to the bottom */
1813 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2;
1814 }
1815
1816 } else
1817 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2;
1818 }
1819
1820 /* avoid channel 165 by setting its weight to max */
1821 pSpectInfo = pSpectInfoParams->pSpectCh;
1822 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
1823 if (CHANNEL_165 == pSpectInfo[j].chNum) {
1824 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2;
1825 break;
1826 }
1827 }
1828
1829 pSpectInfo = pSpectInfoParams->pSpectCh;
1830 for (j = 0; j < (pSpectInfoParams->numSpectChans); j++) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301831 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001832 "In %s, Channel=%d Weight= %d rssi=%d bssCount=%d",
1833 __func__, pSpectInfo->chNum, pSpectInfo->weight,
1834 pSpectInfo->rssiAgr, pSpectInfo->bssCount);
1835 pSpectInfo++;
1836 }
1837
1838 sap_sort_chl_weight(pSpectInfoParams);
1839}
1840
1841/*==========================================================================
1842 FUNCTION sap_sort_chl_weight_all
1843
1844 DESCRIPTION
1845 Funtion to sort the channels with the least weight first
1846
1847 DEPENDENCIES
1848 NA.
1849
1850 PARAMETERS
1851
1852 IN
1853 ptSapContext : Pointer to the ptSapContext structure
1854 pSpectInfoParams : Pointer to the tSapChSelSpectInfo structure
1855
1856 RETURN VALUE
1857 void : NULL
1858
1859 SIDE EFFECTS
1860 ============================================================================*/
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001861static void sap_sort_chl_weight_all(ptSapContext pSapCtx,
1862 tSapChSelSpectInfo *pSpectInfoParams,
1863 uint32_t operatingBand)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001864{
1865 tSapSpectChInfo *pSpectCh = NULL;
1866 uint32_t j = 0;
1867#ifndef SOFTAP_CHANNEL_RANGE
1868 uint32_t i = 0;
1869#endif
1870
1871 pSpectCh = pSpectInfoParams->pSpectCh;
1872#ifdef SOFTAP_CHANNEL_RANGE
1873
1874 switch (pSapCtx->acs_cfg->ch_width) {
1875 case CH_WIDTH_40MHZ:
1876 if (eCSR_DOT11_MODE_11g == operatingBand)
1877 sap_sort_chl_weight_ht40_24_g(pSpectInfoParams);
1878 else if (eCSR_DOT11_MODE_11a == operatingBand)
1879 sap_sort_chl_weight_ht40_5_g(pSpectInfoParams);
1880 else {
1881 sap_sort_chl_weight_ht40_24_g(pSpectInfoParams);
1882 sap_sort_chl_weight_ht40_5_g(pSpectInfoParams);
1883 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001884 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001885 case CH_WIDTH_80MHZ:
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001886 case CH_WIDTH_80P80MHZ:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001887 sap_sort_chl_weight_ht80(pSpectInfoParams);
1888 break;
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001889 case CH_WIDTH_160MHZ:
1890 sap_sort_chl_weight_vht160(pSpectInfoParams);
1891 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001892 case CH_WIDTH_20MHZ:
1893 default:
1894 /* Sorting the channels as per weights as 20MHz channels */
1895 sap_sort_chl_weight(pSpectInfoParams);
1896 }
1897
1898#else
1899 /* Sorting the channels as per weights */
1900 for (i = 0; i < SPECT_24GHZ_CH_COUNT; i++) {
1901 minWeightIndex = i;
1902 for (j = i + 1; j < SPECT_24GHZ_CH_COUNT; j++) {
1903 if (pSpectCh[j].weight <
1904 pSpectCh[minWeightIndex].weight) {
1905 minWeightIndex = j;
1906 }
1907 }
1908 if (minWeightIndex != i) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301909 qdf_mem_copy(&temp, &pSpectCh[minWeightIndex],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001910 sizeof(*pSpectCh));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301911 qdf_mem_copy(&pSpectCh[minWeightIndex], &pSpectCh[i],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001912 sizeof(*pSpectCh));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301913 qdf_mem_copy(&pSpectCh[i], &temp, sizeof(*pSpectCh));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001914 }
1915 }
1916#endif
1917
1918 /* For testing */
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301919 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001920 "In %s, Sorted Spectrum Channels Weight", __func__);
1921 pSpectCh = pSpectInfoParams->pSpectCh;
1922 for (j = 0; j < (pSpectInfoParams->numSpectChans); j++) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301923 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001924 "In %s, Channel=%d Weight= %d rssi=%d bssCount=%d",
1925 __func__, pSpectCh->chNum, pSpectCh->weight,
1926 pSpectCh->rssiAgr, pSpectCh->bssCount);
1927 pSpectCh++;
1928 }
1929
1930}
1931
1932/*==========================================================================
1933 FUNCTION sap_filter_over_lap_ch
1934
1935 DESCRIPTION
1936 return true if ch is acceptable.
1937 This function will decide if we will filter over lap channel or not.
1938
1939 DEPENDENCIES
1940 shall called after ap start.
1941
1942 PARAMETERS
1943
1944 IN
1945 pSapCtx : Pointer to ptSapContext.
1946 chNum : Filter channel number.
1947
1948 RETURN VALUE
1949 bool : true if channel is accepted.
1950
1951 SIDE EFFECTS
1952 ============================================================================*/
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001953static bool sap_filter_over_lap_ch(ptSapContext pSapCtx, uint16_t chNum)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001954{
1955 if (pSapCtx->enableOverLapCh)
1956 return eSAP_TRUE;
1957 else if ((chNum == CHANNEL_1) ||
1958 (chNum == CHANNEL_6) || (chNum == CHANNEL_11))
1959 return eSAP_TRUE;
1960
1961 return eSAP_FALSE;
1962}
1963
Dustin Brown0ce56d32016-10-17 16:18:03 -07001964#ifdef FEATURE_WLAN_CH_AVOID
Naveen Rawat365d1cb2016-02-05 12:10:43 -08001965/**
1966 * sap_select_channel_no_scan_result() - select SAP channel when no scan results
1967 * are available.
1968 * @sap_ctx: Sap context
1969 *
1970 * Returns: channel number if success, 0 otherwise
1971 */
Kondabattini, Ganesh13bb4b12016-09-04 16:16:53 +05301972static uint8_t sap_select_channel_no_scan_result(tHalHandle hal,
Dustin Brown0ce56d32016-10-17 16:18:03 -07001973 ptSapContext sap_ctx)
Naveen Rawat365d1cb2016-02-05 12:10:43 -08001974{
Mohit Khanna841044f2016-03-25 16:16:24 -07001975 enum channel_state ch_type;
Naveen Rawat365d1cb2016-02-05 12:10:43 -08001976 uint8_t i, first_safe_ch_in_range = SAP_CHANNEL_NOT_SELECTED;
Kondabattini, Ganesh13bb4b12016-09-04 16:16:53 +05301977 uint32_t dfs_master_cap_enabled;
Dustin Brown0ce56d32016-10-17 16:18:03 -07001978 uint32_t start_ch_num = sap_ctx->acs_cfg->start_ch;
1979 uint32_t end_ch_num = sap_ctx->acs_cfg->end_ch;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001980
Naveen Rawat365d1cb2016-02-05 12:10:43 -08001981 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
1982 FL("start - end: %d - %d"), start_ch_num, end_ch_num);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001983
Kondabattini, Ganesh13bb4b12016-09-04 16:16:53 +05301984 sme_cfg_get_int(hal, WNI_CFG_DFS_MASTER_ENABLED,
1985 &dfs_master_cap_enabled);
1986
1987 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
1988 "%s: dfs_master %x", __func__, dfs_master_cap_enabled);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001989
Naveen Rawat365d1cb2016-02-05 12:10:43 -08001990 /* get a channel in PCL and within the range */
1991 for (i = 0; i < sap_ctx->acs_cfg->pcl_ch_count; i++) {
1992 if ((sap_ctx->acs_cfg->pcl_channels[i] < start_ch_num) ||
1993 (sap_ctx->acs_cfg->pcl_channels[i] > end_ch_num))
1994 continue;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001995
Naveen Rawat365d1cb2016-02-05 12:10:43 -08001996 first_safe_ch_in_range = sap_ctx->acs_cfg->pcl_channels[i];
1997 break;
1998 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001999
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002000 if (SAP_CHANNEL_NOT_SELECTED != first_safe_ch_in_range)
2001 return first_safe_ch_in_range;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002002
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002003 for (i = 0; i < NUM_CHANNELS; i++) {
2004 if ((safe_channels[i].channelNumber < start_ch_num) ||
2005 (safe_channels[i].channelNumber > end_ch_num))
2006 continue;
2007
2008 ch_type = cds_get_channel_state(safe_channels[i].channelNumber);
2009
2010 if ((ch_type == CHANNEL_STATE_DISABLE) ||
2011 (ch_type == CHANNEL_STATE_INVALID))
2012 continue;
Kondabattini, Ganesh13bb4b12016-09-04 16:16:53 +05302013 if ((!dfs_master_cap_enabled) &&
2014 (CHANNEL_STATE_DFS == ch_type)) {
2015 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2016 "%s: DFS master mode disabled. Skip DFS channel %d",
2017 __func__, safe_channels[i].channelNumber);
2018 continue;
2019 }
Agrawal Ashish65634612016-08-18 13:24:32 +05302020 if ((sap_ctx->dfs_mode == ACS_DFS_MODE_DISABLE) &&
2021 (CHANNEL_STATE_DFS == ch_type))
2022 continue;
Kondabattini, Ganesh13bb4b12016-09-04 16:16:53 +05302023
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002024 if (safe_channels[i].isSafe == true) {
2025 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2026 FL("channel %d in the configuration is safe"),
2027 safe_channels[i].channelNumber);
2028 first_safe_ch_in_range = safe_channels[i].channelNumber;
2029 break;
2030 }
2031
2032 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2033 FL("channel %d in the configuration is unsafe"),
2034 safe_channels[i].channelNumber);
2035 }
2036
2037 /* if no channel selected return SAP_CHANNEL_NOT_SELECTED */
2038 return first_safe_ch_in_range;
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002039}
Dustin Brown0ce56d32016-10-17 16:18:03 -07002040#else
2041static uint8_t sap_select_channel_no_scan_result(tHalHandle hal,
2042 ptSapContext sap_ctx)
2043{
2044 uint32_t start_ch_num = sap_ctx->acs_cfg->start_ch;
2045
2046 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2047 FL("start - end: %d - %d"),
2048 start_ch_num,
2049 sap_ctx->acs_cfg->end_ch);
2050
2051 sap_ctx->acs_cfg->pri_ch = start_ch_num;
2052 sap_ctx->acs_cfg->ht_sec_ch = 0;
2053
2054 /* pick the first channel in configured range */
2055 return start_ch_num;
2056}
2057#endif /* FEATURE_WLAN_CH_AVOID */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002058
2059/**
2060 * sap_select_channel() - select SAP channel
2061 * @hal: Pointer to HAL handle
2062 * @sap_ctx: Sap context
2063 * @scan_result: Pointer to tScanResultHandle
2064 *
2065 * Runs a algorithm to select the best channel to operate in based on BSS
2066 * rssi and bss count on each channel
2067 *
2068 * Returns: channel number if success, 0 otherwise
2069 */
2070uint8_t sap_select_channel(tHalHandle hal, ptSapContext sap_ctx,
2071 tScanResultHandle scan_result)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002072{
2073 /* DFS param object holding all the data req by the algo */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002074 tSapChSelSpectInfo spect_info_obj = { NULL, 0 };
2075 tSapChSelSpectInfo *spect_info = &spect_info_obj;
2076 uint8_t best_ch_num = SAP_CHANNEL_NOT_SELECTED;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002077#ifdef SOFTAP_CHANNEL_RANGE
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002078 uint8_t count;
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002079 uint32_t start_ch_num, end_ch_num, tmp_ch_num, operating_band = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002080#endif
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302081 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002082 "In %s, Running SAP Ch Select", __func__);
2083
2084#ifdef FEATURE_WLAN_CH_AVOID
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002085 sap_update_unsafe_channel_list(sap_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002086#endif
2087
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002088 if (NULL == scan_result) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302089 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002090 FL("No external AP present"));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002091
2092#ifndef SOFTAP_CHANNEL_RANGE
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002093 return SAP_CHANNEL_NOT_SELECTED;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002094#else
Kondabattini, Ganesh13bb4b12016-09-04 16:16:53 +05302095 return sap_select_channel_no_scan_result(hal, sap_ctx);
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002096#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002097 }
2098
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002099 /* Initialize the structure pointed by spect_info */
2100 if (sap_chan_sel_init(hal, spect_info, sap_ctx) != eSAP_TRUE) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302101 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002102 FL("Ch Select initialization failed"));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002103 return SAP_CHANNEL_NOT_SELECTED;
2104 }
2105 /* Compute the weight of the entire spectrum in the operating band */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002106 sap_compute_spect_weight(spect_info, hal, scan_result, sap_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002107
2108#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
2109 /* process avoid channel IE to collect all channels to avoid */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002110 sap_process_avoid_ie(hal, sap_ctx, scan_result, spect_info);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002111#endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
2112
2113#ifdef SOFTAP_CHANNEL_RANGE
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002114 start_ch_num = sap_ctx->acs_cfg->start_ch;
2115 end_ch_num = sap_ctx->acs_cfg->end_ch;
2116 SET_ACS_BAND(operating_band, sap_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002117
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002118 sap_ctx->acsBestChannelInfo.channelNum = 0;
2119 sap_ctx->acsBestChannelInfo.weight = SAP_ACS_WEIGHT_MAX;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002120
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002121 /* Sort the ch lst as per the computed weights, lesser weight first. */
2122 sap_sort_chl_weight_all(sap_ctx, spect_info, operating_band);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002123
2124 /*Loop till get the best channel in the given range */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002125 for (count = 0; count < spect_info->numSpectChans; count++) {
2126 if ((start_ch_num > spect_info->pSpectCh[count].chNum) ||
2127 (end_ch_num < spect_info->pSpectCh[count].chNum))
2128 continue;
2129
2130 if (best_ch_num == SAP_CHANNEL_NOT_SELECTED) {
2131 best_ch_num = spect_info->pSpectCh[count].chNum;
2132 /* check if best_ch_num is in preferred channel list */
2133 best_ch_num =
2134 sap_select_preferred_channel_from_channel_list(
2135 best_ch_num, sap_ctx, spect_info);
2136 /* if not in preferred ch lst, go to nxt best ch */
2137 if (best_ch_num == SAP_CHANNEL_NOT_SELECTED)
2138 continue;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002139
2140#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002141 /*
2142 * Weight of the channels(device's AP is operating)
2143 * increased to MAX+1 so that they will be choosen only
2144 * when there is no other best channel to choose
2145 */
2146 if (sap_check_in_avoid_ch_list(sap_ctx, best_ch_num)) {
2147 best_ch_num = SAP_CHANNEL_NOT_SELECTED;
2148 continue;
2149 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002150#endif
2151
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002152 sap_ctx->acsBestChannelInfo.channelNum = best_ch_num;
2153 sap_ctx->acsBestChannelInfo.weight =
2154 spect_info->pSpectCh[count].weight_copy;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002155 }
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002156
2157 if (best_ch_num == SAP_CHANNEL_NOT_SELECTED)
2158 continue;
2159
2160 if (operating_band != eCSR_DOT11_MODE_11g)
2161 continue;
2162
2163 /* Give preference to Non-overlap channels */
2164 if (false == sap_filter_over_lap_ch(sap_ctx,
2165 spect_info->pSpectCh[count].chNum))
2166 continue;
2167
2168 tmp_ch_num = spect_info->pSpectCh[count].chNum;
2169 tmp_ch_num = sap_select_preferred_channel_from_channel_list(
2170 tmp_ch_num, sap_ctx, spect_info);
2171 if (tmp_ch_num == SAP_CHANNEL_NOT_SELECTED)
2172 continue;
2173
2174 best_ch_num = tmp_ch_num;
2175 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002176 }
2177#else
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002178 /* Sort the ch lst as per the computed weights, lesser weight first. */
2179 sap_sort_chl_weight_all(sap_ctx, hal, spect_info);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002180 /* Get the first channel in sorted array as best 20M Channel */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002181 best_ch_num = (uint8_t) spect_info->pSpectCh[0].chNum;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002182 /* Select Best Channel from Channel List if Configured */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002183 best_ch_num = sap_select_preferred_channel_from_channel_list(
2184 best_ch_num, sap_ctx, spect_info);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002185#endif
2186
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002187 /*
2188 * in case the best channel seleted is not in PCL and there is another
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002189 * channel which has same weightage and is in PCL, choose the one in
2190 * PCL
2191 */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002192 for (count = 0; count < spect_info->numSpectChans; count++) {
2193 if (!ch_in_pcl(sap_ctx, spect_info->pSpectCh[count].chNum) ||
2194 (spect_info->pSpectCh[count].weight !=
2195 sap_ctx->acsBestChannelInfo.weight))
2196 continue;
2197
2198 if (sap_select_preferred_channel_from_channel_list(
2199 spect_info->pSpectCh[count].chNum, sap_ctx, spect_info)
2200 == SAP_CHANNEL_NOT_SELECTED)
2201 continue;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002202
2203#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002204 if (sap_check_in_avoid_ch_list(sap_ctx, best_ch_num))
2205 continue;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002206#endif
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002207 best_ch_num = spect_info->pSpectCh[count].chNum;
2208 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2209 FL("change best channel to %d in PCL"), best_ch_num);
2210 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002211 }
2212
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002213 sap_ctx->acs_cfg->pri_ch = best_ch_num;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002214 /* determine secondary channel for 2.4G channel 5, 6, 7 in HT40 */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002215 if ((operating_band != eCSR_DOT11_MODE_11g) ||
2216 (sap_ctx->acs_cfg->ch_width != CH_WIDTH_40MHZ))
2217 goto sap_ch_sel_end;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002218
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002219 if ((best_ch_num >= 5) && (best_ch_num <= 7)) {
2220 int weight_below, weight_above, i;
2221 tSapSpectChInfo *pspect_info;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002222
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002223 weight_below = weight_above = SAP_ACS_WEIGHT_MAX;
2224 pspect_info = spect_info->pSpectCh;
2225 for (i = 0; i < spect_info->numSpectChans; i++) {
2226 if (pspect_info[i].chNum == (best_ch_num - 4))
2227 weight_below = pspect_info[i].weight;
2228 if (pspect_info[i].chNum == (best_ch_num + 4))
2229 weight_above = pspect_info[i].weight;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002230 }
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002231
2232 if (weight_below < weight_above)
2233 sap_ctx->acs_cfg->ht_sec_ch =
2234 sap_ctx->acs_cfg->pri_ch - 4;
2235 else
2236 sap_ctx->acs_cfg->ht_sec_ch =
2237 sap_ctx->acs_cfg->pri_ch + 4;
2238 } else if (best_ch_num >= 1 && best_ch_num <= 4) {
2239 sap_ctx->acs_cfg->ht_sec_ch = sap_ctx->acs_cfg->pri_ch + 4;
2240 } else if (best_ch_num >= 8 && best_ch_num <= 13) {
2241 sap_ctx->acs_cfg->ht_sec_ch = sap_ctx->acs_cfg->pri_ch - 4;
2242 } else if (best_ch_num == 14) {
2243 sap_ctx->acs_cfg->ht_sec_ch = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002244 }
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002245 sap_ctx->secondary_ch = sap_ctx->acs_cfg->ht_sec_ch;
2246
2247sap_ch_sel_end:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002248 /* Free all the allocated memory */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002249 sap_chan_sel_exit(spect_info);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002250
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302251 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002252 FL("Running SAP Ch select Completed, Ch=%d"), best_ch_num);
2253 if (best_ch_num > 0 && best_ch_num <= 252)
2254 return best_ch_num;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002255 else
2256 return SAP_CHANNEL_NOT_SELECTED;
2257}