blob: fcf1b578b3b8769a0914f09f1a8bd7788b5771ce [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 */
Jeff Johnson464f7ea2016-10-07 10:21:26 -0700490static
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800491uint8_t sap_select_preferred_channel_from_channel_list(uint8_t best_chnl,
492 ptSapContext sap_ctx,
493 tSapChSelSpectInfo *spectinfo_param)
494{
495 uint8_t i = 0;
496
497 /*
498 * If Channel List is not Configured don't do anything
499 * Else return the Best Channel from the Channel List
500 */
501 if ((NULL == sap_ctx->acs_cfg->ch_list) ||
502 (NULL == spectinfo_param) ||
503 (0 == sap_ctx->acs_cfg->ch_list_count))
504 return best_chnl;
505
506 if (best_chnl <= 0 || best_chnl > 252)
507 return SAP_CHANNEL_NOT_SELECTED;
508
509 /* Select the best channel from allowed list */
510 for (i = 0; i < sap_ctx->acs_cfg->ch_list_count; i++) {
511 if (sap_ctx->acs_cfg->ch_list[i] == best_chnl) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530512 QDF_TRACE(QDF_MODULE_ID_SAP,
513 QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800514 "Best channel is: %d",
515 best_chnl);
516 return best_chnl;
517 }
518 }
519
520 return SAP_CHANNEL_NOT_SELECTED;
521}
522
523/*==========================================================================
524 FUNCTION sap_chan_sel_init
525
526 DESCRIPTION
527 Function sap_chan_sel_init allocates the memory, intializes the
Anurag Chouhan6d760662016-02-20 16:05:43 +0530528 structures used by the channel selection algorithm
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800529
530 DEPENDENCIES
531 NA.
532
533 PARAMETERS
534
535 IN
536 halHandle : Pointer to tHalHandle
537 *pSpectInfoParams : Pointer to tSapChSelSpectInfo structure
538 pSapCtx : Pointer to SAP Context
539
540 RETURN VALUE
541 bool: Success or FAIL
542
543 SIDE EFFECTS
544 ============================================================================*/
Jeff Johnson464f7ea2016-10-07 10:21:26 -0700545static bool sap_chan_sel_init(tHalHandle halHandle,
546 tSapChSelSpectInfo *pSpectInfoParams,
547 ptSapContext pSapCtx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800548{
549 tSapSpectChInfo *pSpectCh = NULL;
550 uint8_t *pChans = NULL;
551 uint16_t channelnum = 0;
552 tpAniSirGlobal pMac = PMAC_STRUCT(halHandle);
553 bool chSafe = true;
554#ifdef FEATURE_WLAN_CH_AVOID
555 uint16_t i;
556#endif
557 uint32_t dfs_master_cap_enabled;
558 bool include_dfs_ch = true;
559
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530560 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, "In %s",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800561 __func__);
562
563 pSpectInfoParams->numSpectChans =
564 pMac->scan.base_channels.numChannels;
565
566 /* Allocate memory for weight computation of 2.4GHz */
567 pSpectCh =
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530568 (tSapSpectChInfo *) qdf_mem_malloc((pSpectInfoParams->numSpectChans)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800569 * sizeof(*pSpectCh));
570
571 if (pSpectCh == NULL) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530572 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
Anurag Chouhanf04e84f2016-03-03 10:12:12 +0530573 "In %s, QDF_MALLOC_ERR", __func__);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800574 return eSAP_FALSE;
575 }
576
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530577 qdf_mem_zero(pSpectCh,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800578 (pSpectInfoParams->numSpectChans) * sizeof(*pSpectCh));
579
580 /* Initialize the pointers in the DfsParams to the allocated memory */
581 pSpectInfoParams->pSpectCh = pSpectCh;
582
583 pChans = pMac->scan.base_channels.channelList;
584
Ryan Hsu4252a2f2016-01-05 11:18:24 -0800585#if defined(FEATURE_WLAN_STA_AP_MODE_DFS_DISABLE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800586 if (pSapCtx->dfs_ch_disable == true)
587 include_dfs_ch = false;
588#endif
589 sme_cfg_get_int(halHandle, WNI_CFG_DFS_MASTER_ENABLED,
590 &dfs_master_cap_enabled);
Agrawal Ashish65634612016-08-18 13:24:32 +0530591 if (dfs_master_cap_enabled == 0 ||
592 ACS_DFS_MODE_DISABLE == pSapCtx->dfs_mode)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800593 include_dfs_ch = false;
594
595 /* Fill the channel number in the spectrum in the operating freq band */
596 for (channelnum = 0;
597 channelnum < pSpectInfoParams->numSpectChans;
Edhar, Mahesh Kumar4f660672015-10-30 11:53:26 +0530598 channelnum++, pChans++, pSpectCh++) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800599 chSafe = true;
600
601 /* check if the channel is in NOL blacklist */
602 if (sap_dfs_is_channel_in_nol_list(pSapCtx, *pChans,
603 PHY_SINGLE_CHANNEL_CENTERED)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530604 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800605 "In %s, Ch %d is in NOL list", __func__,
606 *pChans);
607 chSafe = false;
608 continue;
609 }
610
611 if (include_dfs_ch == false) {
612 if (CDS_IS_DFS_CH(*pChans)) {
613 chSafe = false;
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530614 QDF_TRACE(QDF_MODULE_ID_SAP,
615 QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800616 "In %s, DFS Ch %d not considered for ACS",
617 __func__, *pChans);
618 continue;
619 }
620 }
621
622#ifdef FEATURE_WLAN_CH_AVOID
Amar Singhalb8d4f152016-02-10 10:21:43 -0800623 for (i = 0; i < NUM_CHANNELS; i++) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800624 if ((safe_channels[i].channelNumber == *pChans) &&
625 (false == safe_channels[i].isSafe)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530626 QDF_TRACE(QDF_MODULE_ID_SAP,
627 QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800628 "In %s, Ch %d is not safe", __func__,
629 *pChans);
630 chSafe = false;
631 break;
632 }
633 }
634#endif /* FEATURE_WLAN_CH_AVOID */
635
636 /* OFDM rates are not supported on channel 14 */
637 if (*pChans == 14 &&
638 eCSR_DOT11_MODE_11b != pSapCtx->csr_roamProfile.phyMode) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800639 continue;
640 }
641
Deepthi Gowri48b89332016-08-30 18:43:05 +0530642 /* Skip DSRC channels */
643 if (cds_is_dsrc_channel(cds_chan_to_freq(*pChans)))
644 continue;
645
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800646 if (true == chSafe) {
647 pSpectCh->chNum = *pChans;
648 pSpectCh->valid = eSAP_TRUE;
649 pSpectCh->rssiAgr = SOFTAP_MIN_RSSI; /* Initialise for all channels */
650 pSpectCh->channelWidth = SOFTAP_HT20_CHANNELWIDTH; /* Initialise 20MHz for all the Channels */
651 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800652 }
653 return eSAP_TRUE;
654}
655
656/*==========================================================================
657 FUNCTION sapweight_rssi_count
658
659 DESCRIPTION
660 Function weightRssiCount calculates the channel weight due to rssi
Anurag Chouhan6d760662016-02-20 16:05:43 +0530661 and data count(here number of BSS observed)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800662
663 DEPENDENCIES
664 NA.
665
666 PARAMETERS
667
668 IN
669 rssi : Max signal strength receieved from a BSS for the channel
670 count : Number of BSS observed in the channel
671
672 RETURN VALUE
673 uint32_t : Calculated channel weight based on above two
674
675 SIDE EFFECTS
676 ============================================================================*/
Jeff Johnson464f7ea2016-10-07 10:21:26 -0700677static uint32_t sapweight_rssi_count(int8_t rssi, uint16_t count)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800678{
679 int32_t rssiWeight = 0;
680 int32_t countWeight = 0;
681 uint32_t rssicountWeight = 0;
682
683 /* Weight from RSSI */
684 rssiWeight = SOFTAP_RSSI_WEIGHT * (rssi - SOFTAP_MIN_RSSI)
685 / (SOFTAP_MAX_RSSI - SOFTAP_MIN_RSSI);
686
687 if (rssiWeight > SOFTAP_RSSI_WEIGHT)
688 rssiWeight = SOFTAP_RSSI_WEIGHT;
689 else if (rssiWeight < 0)
690 rssiWeight = 0;
691
692 /* Weight from data count */
693 countWeight = SOFTAP_COUNT_WEIGHT * (count - SOFTAP_MIN_COUNT)
694 / (SOFTAP_MAX_COUNT - SOFTAP_MIN_COUNT);
695
696 if (countWeight > SOFTAP_COUNT_WEIGHT)
697 countWeight = SOFTAP_COUNT_WEIGHT;
698
699 rssicountWeight = rssiWeight + countWeight;
700
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530701 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800702 "In %s, rssiWeight=%d, countWeight=%d, rssicountWeight=%d",
703 __func__, rssiWeight, countWeight, rssicountWeight);
704
705 return rssicountWeight;
706}
707
708/**
709 * sap_update_rssi_bsscount() - updates bss count and rssi effect.
710 *
711 * @pSpectCh: Channel Information
712 * @offset: Channel Offset
713 * @sap_24g: Channel is in 2.4G or 5G
714 *
715 * sap_update_rssi_bsscount updates bss count and rssi effect based
716 * on the channel offset.
717 *
718 * Return: None.
719 */
720
Jeff Johnson464f7ea2016-10-07 10:21:26 -0700721static void sap_update_rssi_bsscount(tSapSpectChInfo *pSpectCh, int32_t offset,
722 bool sap_24g)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800723{
724 tSapSpectChInfo *pExtSpectCh = NULL;
725 int32_t rssi, rsssi_effect;
726
727 pExtSpectCh = (pSpectCh + offset);
728 if (pExtSpectCh != NULL) {
729 ++pExtSpectCh->bssCount;
730 switch (offset) {
731 case -1:
732 case 1:
733 rsssi_effect = sap_24g ?
734 SAP_24GHZ_FIRST_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY :
735 SAP_SUBBAND1_RSSI_EFFECT_PRIMARY;
736 break;
737 case -2:
738 case 2:
739 rsssi_effect = sap_24g ?
740 SAP_24GHZ_SEC_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY :
741 SAP_SUBBAND2_RSSI_EFFECT_PRIMARY;
742 break;
743 case -3:
744 case 3:
745 rsssi_effect = sap_24g ?
746 SAP_24GHZ_THIRD_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY :
747 SAP_SUBBAND3_RSSI_EFFECT_PRIMARY;
748 break;
749 case -4:
750 case 4:
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -0700751 rsssi_effect = sap_24g ?
752 SAP_24GHZ_FOURTH_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY :
753 SAP_SUBBAND4_RSSI_EFFECT_PRIMARY;
754 break;
755 case -5:
756 case 5:
757 rsssi_effect = SAP_SUBBAND5_RSSI_EFFECT_PRIMARY;
758 break;
759 case -6:
760 case 6:
761 rsssi_effect = SAP_SUBBAND6_RSSI_EFFECT_PRIMARY;
762 break;
763 case -7:
764 case 7:
765 rsssi_effect = SAP_SUBBAND7_RSSI_EFFECT_PRIMARY;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800766 break;
767 default:
768 rsssi_effect = 0;
769 break;
770 }
771
772 rssi = pSpectCh->rssiAgr + rsssi_effect;
773 if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi))
774 pExtSpectCh->rssiAgr = rssi;
775 if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI)
776 pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI;
777 }
778}
779
780/**
781 * sap_upd_chan_spec_params() - sap_upd_chan_spec_params
782 * updates channel parameters obtained from Beacon
783 * @pBeaconStruct Beacon strucutre populated by parse_beacon function
784 * @channelWidth Channel width
785 * @secondaryChannelOffset Secondary Channel Offset
786 * @vhtSupport If channel supports VHT
787 * @centerFreq Central frequency for the given channel.
788 *
789 * sap_upd_chan_spec_params updates the spectrum channels based on the
790 * pBeaconStruct obtained from Beacon IE
791 *
792 * Return: NA.
793 */
794
Jeff Johnson464f7ea2016-10-07 10:21:26 -0700795static void sap_upd_chan_spec_params(tSirProbeRespBeacon *pBeaconStruct,
796 uint16_t *channelWidth,
797 uint16_t *secondaryChannelOffset,
798 uint16_t *vhtSupport,
799 uint16_t *centerFreq,
800 uint16_t *centerFreq_2)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800801{
802 if (NULL == pBeaconStruct) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530803 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800804 FL("pBeaconStruct is NULL"));
805 return;
806 }
807
808 if (pBeaconStruct->HTCaps.present && pBeaconStruct->HTInfo.present) {
809 *channelWidth = pBeaconStruct->HTCaps.supportedChannelWidthSet;
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -0700810 *secondaryChannelOffset =
811 pBeaconStruct->HTInfo.secondaryChannelOffset;
812 if (!pBeaconStruct->VHTOperation.present)
813 return;
814 *vhtSupport = pBeaconStruct->VHTOperation.present;
815 if (pBeaconStruct->VHTOperation.chanWidth) {
816 *centerFreq =
817 pBeaconStruct->VHTOperation.chanCenterFreqSeg1;
818 *centerFreq_2 =
819 pBeaconStruct->VHTOperation.chanCenterFreqSeg2;
820 /*
821 * LHS follows tSirMacHTChannelWidth, while RHS follows
822 * WNI_CFG_VHT_CHANNEL_WIDTH_X format hence following
823 * adjustment
824 */
825 *channelWidth =
826 pBeaconStruct->VHTOperation.chanWidth + 1;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800827
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800828 }
829 }
830}
831
832/**
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -0700833 * sap_update_rssi_bsscount_vht_5G() - updates bss count and rssi effect.
834 *
Jeff Johnson464f7ea2016-10-07 10:21:26 -0700835 * @spect_ch: Channel Information
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -0700836 * @offset: Channel Offset
837 * @num_ch: no.of channels
838 *
839 * sap_update_rssi_bsscount_vht_5G updates bss count and rssi effect based
840 * on the channel offset.
841 *
842 * Return: None.
843 */
844
Jeff Johnson464f7ea2016-10-07 10:21:26 -0700845static void sap_update_rssi_bsscount_vht_5G(tSapSpectChInfo *spect_ch,
846 int32_t offset,
847 uint16_t num_ch)
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -0700848{
849 int32_t ch_offset;
850 uint16_t i, cnt;
851
852 if (!offset)
853 return;
854 if (offset > 0)
855 cnt = num_ch;
856 else
857 cnt = num_ch + 1;
858 for (i = 0; i < cnt; i++) {
859 ch_offset = offset + i;
860 if (ch_offset == 0)
861 continue;
862 sap_update_rssi_bsscount(spect_ch, ch_offset, false);
863 }
864}
865/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800866 * sap_interference_rssi_count_5G() - sap_interference_rssi_count
867 * considers the Adjacent channel rssi and
868 * data count(here number of BSS observed)
869 * @spect_ch: Channel Information
870 * @chan_width: Channel width parsed from beacon IE
871 * @sec_chan_offset: Secondary Channel Offset
872 * @center_freq: Central frequency for the given channel.
873 * @channel_id: channel_id
874 *
875 * sap_interference_rssi_count_5G considers the Adjacent channel rssi
876 * and data count(here number of BSS observed)
877 *
878 * Return: NA.
879 */
880
Jeff Johnson464f7ea2016-10-07 10:21:26 -0700881static void sap_interference_rssi_count_5G(tSapSpectChInfo *spect_ch,
882 uint16_t chan_width,
883 uint16_t sec_chan_offset,
884 uint16_t center_freq,
885 uint16_t center_freq_2,
886 uint8_t channel_id)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800887{
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -0700888 uint16_t num_ch;
889 int32_t offset = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800890 if (NULL == spect_ch) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530891 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800892 FL("spect_ch is NULL"));
893 return;
894 }
895
896 /* Updating the received ChannelWidth */
897 if (spect_ch->channelWidth != chan_width)
898 spect_ch->channelWidth = chan_width;
899 /* If received ChannelWidth is other than HT20,
900 * we need to update the extension channel Params as well
901 * chan_width == 0, HT20
902 * chan_width == 1, HT40
903 * chan_width == 2, VHT80
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -0700904 * chan_width == 3, VHT160
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800905 */
906
907 switch (spect_ch->channelWidth) {
908 case eHT_CHANNEL_WIDTH_40MHZ: /* HT40 */
909 switch (sec_chan_offset) {
910 /* Above the Primary Channel */
911 case PHY_DOUBLE_CHANNEL_LOW_PRIMARY:
912 sap_update_rssi_bsscount(spect_ch, 1, false);
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -0700913 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800914
915 /* Below the Primary channel */
916 case PHY_DOUBLE_CHANNEL_HIGH_PRIMARY:
917 sap_update_rssi_bsscount(spect_ch, -1, false);
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -0700918 return;
919 }
920 return;
921 case eHT_CHANNEL_WIDTH_80MHZ: /* VHT80 */
922 num_ch = 3;
923 if ((center_freq - channel_id) == 6) {
924 offset = 1;
925 } else if ((center_freq - channel_id) == 2) {
926 offset = -1;
927 } else if ((center_freq - channel_id) == -2) {
928 offset = -2;
929 } else if ((center_freq - channel_id) == -6) {
930 offset = -3;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800931 }
932 break;
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -0700933 case eHT_CHANNEL_WIDTH_160MHZ: /* VHT160 */
934 num_ch = 7;
935 if ((center_freq - channel_id) == 14)
936 offset = 1;
937 else if ((center_freq - channel_id) == 10)
938 offset = -1;
939 else if ((center_freq - channel_id) == 6)
940 offset = -2;
941 else if ((center_freq - channel_id) == 2)
942 offset = -3;
943 else if ((center_freq - channel_id) == -2)
944 offset = -4;
945 else if ((center_freq - channel_id) == -6)
946 offset = -5;
947 else if ((center_freq - channel_id) == -10)
948 offset = -6;
949 else if ((center_freq - channel_id) == -14)
950 offset = -7;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800951 break;
952 default:
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -0700953 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800954 }
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -0700955 sap_update_rssi_bsscount_vht_5G(spect_ch, offset, num_ch);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800956}
957
958/**
959 * sap_interference_rssi_count() - sap_interference_rssi_count
960 * considers the Adjacent channel rssi
961 * and data count(here number of BSS observed)
962 * @spect_ch Channel Information
963 *
964 * sap_interference_rssi_count considers the Adjacent channel rssi
965 * and data count(here number of BSS observed)
966 *
967 * Return: None.
968 */
969
Jeff Johnson464f7ea2016-10-07 10:21:26 -0700970static void sap_interference_rssi_count(tSapSpectChInfo *spect_ch)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800971{
972 if (NULL == spect_ch) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530973 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800974 "%s: spect_ch is NULL", __func__);
975 return;
976 }
977
978 switch (spect_ch->chNum) {
979 case CHANNEL_1:
980 sap_update_rssi_bsscount(spect_ch, 1, true);
981 sap_update_rssi_bsscount(spect_ch, 2, true);
982 sap_update_rssi_bsscount(spect_ch, 3, true);
983 sap_update_rssi_bsscount(spect_ch, 4, true);
984 break;
985
986 case CHANNEL_2:
987 sap_update_rssi_bsscount(spect_ch, -1, true);
988 sap_update_rssi_bsscount(spect_ch, 1, true);
989 sap_update_rssi_bsscount(spect_ch, 2, true);
990 sap_update_rssi_bsscount(spect_ch, 3, true);
991 sap_update_rssi_bsscount(spect_ch, 4, true);
992 break;
993 case CHANNEL_3:
994 sap_update_rssi_bsscount(spect_ch, -2, true);
995 sap_update_rssi_bsscount(spect_ch, -1, true);
996 sap_update_rssi_bsscount(spect_ch, 1, true);
997 sap_update_rssi_bsscount(spect_ch, 2, true);
998 sap_update_rssi_bsscount(spect_ch, 3, true);
999 sap_update_rssi_bsscount(spect_ch, 4, true);
1000 break;
1001 case CHANNEL_4:
1002 sap_update_rssi_bsscount(spect_ch, -3, true);
1003 sap_update_rssi_bsscount(spect_ch, -2, true);
1004 sap_update_rssi_bsscount(spect_ch, -1, true);
1005 sap_update_rssi_bsscount(spect_ch, 1, true);
1006 sap_update_rssi_bsscount(spect_ch, 2, true);
1007 sap_update_rssi_bsscount(spect_ch, 3, true);
1008 sap_update_rssi_bsscount(spect_ch, 4, true);
1009 break;
1010
1011 case CHANNEL_5:
1012 case CHANNEL_6:
1013 case CHANNEL_7:
1014 case CHANNEL_8:
1015 case CHANNEL_9:
1016 case CHANNEL_10:
1017 sap_update_rssi_bsscount(spect_ch, -4, true);
1018 sap_update_rssi_bsscount(spect_ch, -3, true);
1019 sap_update_rssi_bsscount(spect_ch, -2, true);
1020 sap_update_rssi_bsscount(spect_ch, -1, true);
1021 sap_update_rssi_bsscount(spect_ch, 1, true);
1022 sap_update_rssi_bsscount(spect_ch, 2, true);
1023 sap_update_rssi_bsscount(spect_ch, 3, true);
1024 sap_update_rssi_bsscount(spect_ch, 4, true);
1025 break;
1026
1027 case CHANNEL_11:
1028 sap_update_rssi_bsscount(spect_ch, -4, true);
1029 sap_update_rssi_bsscount(spect_ch, -3, true);
1030 sap_update_rssi_bsscount(spect_ch, -2, true);
1031 sap_update_rssi_bsscount(spect_ch, -1, true);
1032 sap_update_rssi_bsscount(spect_ch, 1, true);
1033 sap_update_rssi_bsscount(spect_ch, 2, true);
1034 sap_update_rssi_bsscount(spect_ch, 3, true);
1035 break;
1036
1037 case CHANNEL_12:
1038 sap_update_rssi_bsscount(spect_ch, -4, true);
1039 sap_update_rssi_bsscount(spect_ch, -3, true);
1040 sap_update_rssi_bsscount(spect_ch, -2, true);
1041 sap_update_rssi_bsscount(spect_ch, -1, true);
1042 sap_update_rssi_bsscount(spect_ch, 1, true);
1043 sap_update_rssi_bsscount(spect_ch, 2, true);
1044 break;
1045
1046 case CHANNEL_13:
1047 sap_update_rssi_bsscount(spect_ch, -4, true);
1048 sap_update_rssi_bsscount(spect_ch, -3, true);
1049 sap_update_rssi_bsscount(spect_ch, -2, true);
1050 sap_update_rssi_bsscount(spect_ch, -1, true);
1051 sap_update_rssi_bsscount(spect_ch, 1, true);
1052 break;
1053
1054 case CHANNEL_14:
1055 sap_update_rssi_bsscount(spect_ch, -4, true);
1056 sap_update_rssi_bsscount(spect_ch, -3, true);
1057 sap_update_rssi_bsscount(spect_ch, -2, true);
1058 sap_update_rssi_bsscount(spect_ch, -1, true);
1059 break;
1060
1061 default:
1062 break;
1063 }
1064}
1065
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001066/**
1067 * ch_in_pcl() - Is channel in the Preferred Channel List (PCL)
1068 * @sap_ctx: SAP context which contains the current PCL
1069 * @channel: Input channel number to be checked
1070 *
1071 * Check if a channel is in the preferred channel list
1072 *
1073 * Return:
1074 * true: channel is in PCL,
1075 * false: channel is not in PCL
1076 */
1077static bool ch_in_pcl(ptSapContext sap_ctx, uint8_t channel)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001078{
1079 uint32_t i;
1080
1081 for (i = 0; i < sap_ctx->acs_cfg->pcl_ch_count; i++) {
1082 if (channel == sap_ctx->acs_cfg->pcl_channels[i])
1083 return true;
1084 }
1085
1086 return false;
1087}
1088
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001089/**
1090 * sap_compute_spect_weight() - Compute spectrum weight
1091 * @pSpectInfoParams: Pointer to the tSpectInfoParams structure
1092 * @halHandle: Pointer to HAL handle
1093 * @pResult: Pointer to tScanResultHandle
1094 * @sap_ctx: Context of the SAP
1095 *
1096 * Main function for computing the weight of each channel in the
1097 * spectrum based on the RSSI value of the BSSes on the channel
1098 * and number of BSS
1099 */
1100static void sap_compute_spect_weight(tSapChSelSpectInfo *pSpectInfoParams,
1101 tHalHandle halHandle,
1102 tScanResultHandle pResult,
1103 ptSapContext sap_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001104{
1105 int8_t rssi = 0;
1106 uint8_t chn_num = 0;
1107 uint8_t channel_id = 0;
1108
1109 tCsrScanResultInfo *pScanResult;
1110 tSapSpectChInfo *pSpectCh = pSpectInfoParams->pSpectCh;
1111 uint32_t operatingBand;
1112 uint16_t channelWidth;
1113 uint16_t secondaryChannelOffset;
1114 uint16_t centerFreq;
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001115 uint16_t centerFreq_2 = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001116 uint16_t vhtSupport;
1117 uint32_t ieLen = 0;
1118 tSirProbeRespBeacon *pBeaconStruct;
1119 tpAniSirGlobal pMac = (tpAniSirGlobal) halHandle;
1120
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301121 pBeaconStruct = qdf_mem_malloc(sizeof(tSirProbeRespBeacon));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001122 if (NULL == pBeaconStruct) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301123 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Kaushik, Sushantee3ed032016-08-04 16:40:46 +05301124 "Unable to allocate memory in sap_compute_spect_weight");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001125 return;
1126 }
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301127 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001128 "In %s, Computing spectral weight", __func__);
1129
1130 /**
1131 * Soft AP specific channel weight calculation using DFS formula
1132 */
1133 SET_ACS_BAND(operatingBand, sap_ctx);
1134
1135 pScanResult = sme_scan_result_get_first(halHandle, pResult);
1136
1137 while (pScanResult) {
1138 pSpectCh = pSpectInfoParams->pSpectCh;
1139 /* Defining the default values, so that any value will hold the default values */
1140 channelWidth = eHT_CHANNEL_WIDTH_20MHZ;
1141 secondaryChannelOffset = PHY_SINGLE_CHANNEL_CENTERED;
1142 vhtSupport = 0;
1143 centerFreq = 0;
1144
1145 if (pScanResult->BssDescriptor.ieFields != NULL) {
1146 ieLen =
1147 (pScanResult->BssDescriptor.length +
1148 sizeof(uint16_t) + sizeof(uint32_t) -
1149 sizeof(tSirBssDescription));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301150 qdf_mem_set((uint8_t *) pBeaconStruct,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001151 sizeof(tSirProbeRespBeacon), 0);
1152
1153 if ((sir_parse_beacon_ie
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001154 (pMac, pBeaconStruct, (uint8_t *)
1155 (pScanResult->BssDescriptor.ieFields),
1156 ieLen)) == eSIR_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001157 sap_upd_chan_spec_params(pBeaconStruct,
1158 &channelWidth, &secondaryChannelOffset,
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001159 &vhtSupport, &centerFreq,
1160 &centerFreq_2);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001161 }
1162 }
1163 /* Processing for each tCsrScanResultInfo in the tCsrScanResult DLink list */
1164 for (chn_num = 0; chn_num < pSpectInfoParams->numSpectChans;
1165 chn_num++) {
1166
1167 /*
1168 * if the Beacon has channel ID, use it other wise we will
1169 * rely on the channelIdSelf
1170 */
1171 if (pScanResult->BssDescriptor.channelId == 0)
1172 channel_id =
1173 pScanResult->BssDescriptor.channelIdSelf;
1174 else
1175 channel_id =
1176 pScanResult->BssDescriptor.channelId;
1177
1178 if (pSpectCh && (channel_id == pSpectCh->chNum)) {
1179 if (pSpectCh->rssiAgr <
1180 pScanResult->BssDescriptor.rssi)
1181 pSpectCh->rssiAgr =
1182 pScanResult->BssDescriptor.rssi;
1183
1184 ++pSpectCh->bssCount; /* Increment the count of BSS */
1185
1186 /*
1187 * Connsidering the Extension Channel
1188 * only in a channels
1189 */
1190 switch (operatingBand) {
1191 case eCSR_DOT11_MODE_11a:
1192 sap_interference_rssi_count_5G(
1193 pSpectCh, channelWidth,
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001194 secondaryChannelOffset,
1195 centerFreq,
1196 centerFreq_2,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001197 channel_id);
1198 break;
1199
1200 case eCSR_DOT11_MODE_11g:
1201 sap_interference_rssi_count(pSpectCh);
1202 break;
1203
1204 case eCSR_DOT11_MODE_abg:
1205 sap_interference_rssi_count_5G(
1206 pSpectCh, channelWidth,
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001207 secondaryChannelOffset,
1208 centerFreq,
1209 centerFreq_2,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001210 channel_id);
1211 sap_interference_rssi_count(pSpectCh);
1212 break;
1213 }
1214
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301215 QDF_TRACE(QDF_MODULE_ID_SAP,
1216 QDF_TRACE_LEVEL_INFO_HIGH,
Kaushik, Sushantee3ed032016-08-04 16:40:46 +05301217 "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 -08001218 __func__,
1219 pScanResult->BssDescriptor.
1220 channelIdSelf,
1221 pScanResult->BssDescriptor.channelId,
1222 pScanResult->BssDescriptor.rssi,
1223 pSpectCh->bssCount, pScanResult,
1224 pSpectCh->channelWidth,
1225 secondaryChannelOffset, centerFreq);
1226 pSpectCh++;
1227 break;
1228 } else {
1229 pSpectCh++;
1230 }
1231 }
1232
1233 pScanResult = sme_scan_result_get_next(halHandle, pResult);
1234 }
1235
1236 /* Calculate the weights for all channels in the spectrum pSpectCh */
1237 pSpectCh = pSpectInfoParams->pSpectCh;
1238
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301239 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001240 "In %s, Spectrum Channels Weight", __func__);
1241
1242 for (chn_num = 0; chn_num < (pSpectInfoParams->numSpectChans);
1243 chn_num++) {
1244
1245 /*
1246 rssi : Maximum received signal strength among all BSS on that channel
1247 bssCount : Number of BSS on that channel
1248 */
1249
1250 rssi = (int8_t) pSpectCh->rssiAgr;
1251 if (ch_in_pcl(sap_ctx, chn_num))
1252 rssi -= PCL_RSSI_DISCOUNT;
1253
1254 pSpectCh->weight =
1255 SAPDFS_NORMALISE_1000 * sapweight_rssi_count(rssi,
1256 pSpectCh->
1257 bssCount);
1258 pSpectCh->weight_copy = pSpectCh->weight;
1259
1260 /* ------ Debug Info ------ */
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301261 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001262 "In %s, Chan=%d Weight= %d rssiAgr=%d bssCount=%d",
1263 __func__, pSpectCh->chNum, pSpectCh->weight,
1264 pSpectCh->rssiAgr, pSpectCh->bssCount);
1265 /* ------ Debug Info ------ */
1266 pSpectCh++;
1267 }
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301268 qdf_mem_free(pBeaconStruct);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001269}
1270
1271/*==========================================================================
1272 FUNCTION sap_chan_sel_exit
1273
1274 DESCRIPTION
1275 Exit function for free out the allocated memory, to be called
1276 at the end of the dfsSelectChannel function
1277
1278 DEPENDENCIES
1279 NA.
1280
1281 PARAMETERS
1282
1283 IN
1284 pSpectInfoParams : Pointer to the tSapChSelSpectInfo structure
1285
1286 RETURN VALUE
1287 void : NULL
1288
1289 SIDE EFFECTS
1290 ============================================================================*/
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001291static void sap_chan_sel_exit(tSapChSelSpectInfo *pSpectInfoParams)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001292{
1293 /* Free all the allocated memory */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301294 qdf_mem_free(pSpectInfoParams->pSpectCh);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001295}
1296
1297/*==========================================================================
1298 FUNCTION sap_sort_chl_weight
1299
1300 DESCRIPTION
1301 Funtion to sort the channels with the least weight first for 20MHz channels
1302
1303 DEPENDENCIES
1304 NA.
1305
1306 PARAMETERS
1307
1308 IN
1309 pSpectInfoParams : Pointer to the tSapChSelSpectInfo structure
1310
1311 RETURN VALUE
1312 void : NULL
1313
1314 SIDE EFFECTS
1315 ============================================================================*/
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001316static void sap_sort_chl_weight(tSapChSelSpectInfo *pSpectInfoParams)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001317{
1318 tSapSpectChInfo temp;
1319
1320 tSapSpectChInfo *pSpectCh = NULL;
1321 uint32_t i = 0, j = 0, minWeightIndex = 0;
1322
1323 pSpectCh = pSpectInfoParams->pSpectCh;
1324 for (i = 0; i < pSpectInfoParams->numSpectChans; i++) {
1325 minWeightIndex = i;
1326 for (j = i + 1; j < pSpectInfoParams->numSpectChans; j++) {
1327 if (pSpectCh[j].weight <
1328 pSpectCh[minWeightIndex].weight) {
1329 minWeightIndex = j;
1330 }
1331 }
1332 if (minWeightIndex != i) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301333 qdf_mem_copy(&temp, &pSpectCh[minWeightIndex],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001334 sizeof(*pSpectCh));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301335 qdf_mem_copy(&pSpectCh[minWeightIndex], &pSpectCh[i],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001336 sizeof(*pSpectCh));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301337 qdf_mem_copy(&pSpectCh[i], &temp, sizeof(*pSpectCh));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001338 }
1339 }
1340}
1341
1342/**
1343 * sap_sort_chl_weight_ht80() - to sort the channels with the least weight
1344 * @pSpectInfoParams: Pointer to the tSapChSelSpectInfo structure
1345 *
1346 * Funtion to sort the channels with the least weight first for HT80 channels
1347 *
1348 * Return: none
1349 */
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001350static void sap_sort_chl_weight_ht80(tSapChSelSpectInfo *pSpectInfoParams)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001351{
1352 uint8_t i, j, n;
1353 tSapSpectChInfo *pSpectInfo;
1354 uint8_t minIdx;
1355
1356 pSpectInfo = pSpectInfoParams->pSpectCh;
1357 /* for each HT80 channel, calculate the combined weight of the
1358 four 20MHz weight */
1359 for (i = 0; i < ARRAY_SIZE(acs_ht80_channels); i++) {
1360 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
1361 if (pSpectInfo[j].chNum ==
1362 acs_ht80_channels[i].chStartNum)
1363 break;
1364 }
1365 if (j == pSpectInfoParams->numSpectChans)
1366 continue;
1367
1368 if (!(((pSpectInfo[j].chNum + 4) == pSpectInfo[j + 1].chNum) &&
1369 ((pSpectInfo[j].chNum + 8) ==
1370 pSpectInfo[j + 2].chNum) &&
1371 ((pSpectInfo[j].chNum + 12) ==
1372 pSpectInfo[j + 3].chNum))) {
1373 /*
1374 * some channels does not exist in pSectInfo array,
1375 * skip this channel and those in the same HT80 width
1376 */
1377 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 4;
1378 if ((pSpectInfo[j].chNum + 4) ==
1379 pSpectInfo[j + 1].chNum)
1380 pSpectInfo[j + 1].weight =
1381 SAP_ACS_WEIGHT_MAX * 4;
1382 if ((pSpectInfo[j].chNum + 8) ==
1383 pSpectInfo[j + 2].chNum)
1384 pSpectInfo[j + 2].weight =
1385 SAP_ACS_WEIGHT_MAX * 4;
1386 if ((pSpectInfo[j].chNum + 12) ==
1387 pSpectInfo[j + 3].chNum)
1388 pSpectInfo[j + 3].weight =
1389 SAP_ACS_WEIGHT_MAX * 4;
1390 continue;
1391 }
1392 /*found the channel, add the 4 adjacent channels' weight */
1393 acs_ht80_channels[i].weight = pSpectInfo[j].weight +
1394 pSpectInfo[j + 1].weight + pSpectInfo[j + 2].weight +
1395 pSpectInfo[j + 3].weight;
1396 /* find best channel among 4 channels as the primary channel */
1397 if ((pSpectInfo[j].weight + pSpectInfo[j + 1].weight) <
1398 (pSpectInfo[j + 2].weight + pSpectInfo[j + 3].weight)) {
1399 /* lower 2 channels are better choice */
1400 if (pSpectInfo[j].weight < pSpectInfo[j + 1].weight)
1401 minIdx = 0;
1402 else
1403 minIdx = 1;
1404 } else if (pSpectInfo[j + 2].weight <=
1405 pSpectInfo[j + 3].weight) {
1406 /* upper 2 channels are better choice */
1407 minIdx = 2;
1408 } else {
1409 minIdx = 3;
1410 }
1411
1412 /*
1413 * set all 4 channels to max value first, then reset the
1414 * best channel as the selected primary channel, update its
1415 * weightage with the combined weight value
1416 */
1417 for (n = 0; n < 4; n++)
1418 pSpectInfo[j + n].weight = SAP_ACS_WEIGHT_MAX * 4;
1419
1420 pSpectInfo[j + minIdx].weight = acs_ht80_channels[i].weight;
1421 }
1422
1423 pSpectInfo = pSpectInfoParams->pSpectCh;
1424 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
1425 if (CHANNEL_165 == pSpectInfo[j].chNum) {
1426 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 4;
1427 break;
1428 }
1429 }
1430
Manishekar Chandrasekaran44e334f2016-05-30 16:42:50 +05301431 sap_sort_chl_weight(pSpectInfoParams);
1432
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001433 pSpectInfo = pSpectInfoParams->pSpectCh;
1434 for (j = 0; j < (pSpectInfoParams->numSpectChans); j++) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301435 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001436 FL("Channel=%d Weight= %d rssi=%d bssCount=%d"),
1437 pSpectInfo->chNum, pSpectInfo->weight,
1438 pSpectInfo->rssiAgr, pSpectInfo->bssCount);
1439 pSpectInfo++;
1440 }
1441}
1442
1443/**
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001444 * sap_sort_chl_weight_vht160() - to sort the channels with the least weight
1445 * @pSpectInfoParams: Pointer to the tSapChSelSpectInfo structure
1446 *
1447 * Funtion to sort the channels with the least weight first for VHT160 channels
1448 *
1449 * Return: none
1450 */
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001451static void sap_sort_chl_weight_vht160(tSapChSelSpectInfo *pSpectInfoParams)
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001452{
1453 uint8_t i, j, n, idx;
1454 tSapSpectChInfo *pSpectInfo;
1455 uint8_t minIdx;
1456
1457 pSpectInfo = pSpectInfoParams->pSpectCh;
1458 /* for each VHT160 channel, calculate the combined weight of the
1459 8 20MHz weight */
1460 for (i = 0; i < ARRAY_SIZE(acs_vht160_channels); i++) {
1461 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
1462 if (pSpectInfo[j].chNum ==
1463 acs_vht160_channels[i].chStartNum)
1464 break;
1465 }
1466 if (j == pSpectInfoParams->numSpectChans)
1467 continue;
1468
1469 if (!(((pSpectInfo[j].chNum + 4) == pSpectInfo[j + 1].chNum) &&
1470 ((pSpectInfo[j].chNum + 8) ==
1471 pSpectInfo[j + 2].chNum) &&
1472 ((pSpectInfo[j].chNum + 12) ==
1473 pSpectInfo[j + 3].chNum) &&
1474 ((pSpectInfo[j].chNum + 16) ==
1475 pSpectInfo[j + 4].chNum) &&
1476 ((pSpectInfo[j].chNum + 20) ==
1477 pSpectInfo[j + 5].chNum) &&
1478 ((pSpectInfo[j].chNum + 24) ==
1479 pSpectInfo[j + 6].chNum) &&
1480 ((pSpectInfo[j].chNum + 28) ==
1481 pSpectInfo[j + 7].chNum))) {
1482 /*
1483 * some channels does not exist in pSectInfo array,
1484 * skip this channel and those in the same VHT160 width
1485 */
1486 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 8;
1487 if ((pSpectInfo[j].chNum + 4) ==
1488 pSpectInfo[j + 1].chNum)
1489 pSpectInfo[j + 1].weight =
1490 SAP_ACS_WEIGHT_MAX * 8;
1491 if ((pSpectInfo[j].chNum + 8) ==
1492 pSpectInfo[j + 2].chNum)
1493 pSpectInfo[j + 2].weight =
1494 SAP_ACS_WEIGHT_MAX * 8;
1495 if ((pSpectInfo[j].chNum + 12) ==
1496 pSpectInfo[j + 3].chNum)
1497 pSpectInfo[j + 3].weight =
1498 SAP_ACS_WEIGHT_MAX * 8;
1499 if ((pSpectInfo[j].chNum + 16) ==
1500 pSpectInfo[j + 4].chNum)
1501 pSpectInfo[j + 4].weight =
1502 SAP_ACS_WEIGHT_MAX * 8;
1503 if ((pSpectInfo[j].chNum + 20) ==
1504 pSpectInfo[j + 5].chNum)
1505 pSpectInfo[j + 5].weight =
1506 SAP_ACS_WEIGHT_MAX * 8;
1507 if ((pSpectInfo[j].chNum + 24) ==
1508 pSpectInfo[j + 6].chNum)
1509 pSpectInfo[j + 6].weight =
1510 SAP_ACS_WEIGHT_MAX * 8;
1511 if ((pSpectInfo[j].chNum + 28) ==
1512 pSpectInfo[j + 7].chNum)
1513 pSpectInfo[j + 7].weight =
1514 SAP_ACS_WEIGHT_MAX * 8;
1515 continue;
1516 }
1517 /*found the channel, add the 7 adjacent channels' weight */
1518 acs_vht160_channels[i].weight = pSpectInfo[j].weight +
1519 pSpectInfo[j + 1].weight + pSpectInfo[j + 2].weight +
1520 pSpectInfo[j + 3].weight + pSpectInfo[j + 4].weight +
1521 pSpectInfo[j + 5].weight + pSpectInfo[j + 6].weight +
1522 pSpectInfo[j + 7].weight;
1523
1524 /* find best channel among 8 channels as the primary channel */
1525 if ((pSpectInfo[j].weight + pSpectInfo[j + 1].weight +
1526 pSpectInfo[j + 2].weight + pSpectInfo[j + 3].weight) >
1527 (pSpectInfo[j + 4].weight + pSpectInfo[j + 5].weight +
1528 pSpectInfo[j + 6].weight + pSpectInfo[j + 7].weight))
1529 idx = 4;
1530 else
1531 idx = 0;
1532 /* find best channel among 4 channels as the primary channel */
1533 if ((pSpectInfo[j + idx].weight +
1534 pSpectInfo[j + idx + 1].weight) <
1535 (pSpectInfo[j + idx + 2].weight +
1536 pSpectInfo[j + idx + 3].weight)) {
1537 /* lower 2 channels are better choice */
1538 if (pSpectInfo[j + idx].weight <
1539 pSpectInfo[j + idx + 1].weight)
1540 minIdx = 0 + idx;
1541 else
1542 minIdx = 1 + idx;
1543 } else if (pSpectInfo[j + idx + 2].weight <=
1544 pSpectInfo[j + idx + 3].weight) {
1545 /* upper 2 channels are better choice */
1546 minIdx = 2 + idx;
1547 } else {
1548 minIdx = 3 + idx;
1549 }
1550
1551 /*
1552 * set all 8 channels to max value first, then reset the
1553 * best channel as the selected primary channel, update its
1554 * weightage with the combined weight value
1555 */
1556 for (n = 0; n < 8; n++)
1557 pSpectInfo[j + n].weight = SAP_ACS_WEIGHT_MAX * 8;
1558
1559 pSpectInfo[j + minIdx].weight = acs_vht160_channels[i].weight;
1560 }
1561
1562 pSpectInfo = pSpectInfoParams->pSpectCh;
1563 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
1564 if (CHANNEL_165 == pSpectInfo[j].chNum) {
1565 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 8;
1566 break;
1567 }
1568 }
1569
Manishekar Chandrasekaran44e334f2016-05-30 16:42:50 +05301570 sap_sort_chl_weight(pSpectInfoParams);
1571
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001572 pSpectInfo = pSpectInfoParams->pSpectCh;
1573 for (j = 0; j < (pSpectInfoParams->numSpectChans); j++) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301574 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001575 FL("Channel=%d Weight= %d rssi=%d bssCount=%d"),
1576 pSpectInfo->chNum, pSpectInfo->weight,
1577 pSpectInfo->rssiAgr, pSpectInfo->bssCount);
1578 pSpectInfo++;
1579 }
1580}
1581
1582/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001583 * sap_sort_chl_weight_ht40_24_g() - to sort channel with the least weight
1584 * @pSpectInfoParams: Pointer to the tSapChSelSpectInfo structure
1585 *
1586 * Funtion to sort the channels with the least weight first for HT40 channels
1587 *
1588 * Return: none
1589 */
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001590static void sap_sort_chl_weight_ht40_24_g(tSapChSelSpectInfo *pSpectInfoParams)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001591{
1592 uint8_t i, j;
1593 tSapSpectChInfo *pSpectInfo;
1594 uint32_t tmpWeight1, tmpWeight2;
1595
1596 pSpectInfo = pSpectInfoParams->pSpectCh;
1597 /*
1598 * for each HT40 channel, calculate the combined weight of the
1599 * two 20MHz weight
1600 */
1601 for (i = 0; i < ARRAY_SIZE(acs_ht40_channels24_g); i++) {
1602 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
1603 if (pSpectInfo[j].chNum ==
1604 acs_ht40_channels24_g[i].chStartNum)
1605 break;
1606 }
1607 if (j == pSpectInfoParams->numSpectChans)
1608 continue;
1609
1610 if (!((pSpectInfo[j].chNum + 4) == pSpectInfo[j + 4].chNum)) {
1611 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2;
1612 continue;
1613 }
1614 /*
1615 * check if there is another channel combination possiblity
1616 * e.g., {1, 5} & {5, 9}
1617 */
1618 if ((pSpectInfo[j + 4].chNum + 4) == pSpectInfo[j + 8].chNum) {
1619 /* need to compare two channel pairs */
1620 tmpWeight1 = pSpectInfo[j].weight +
1621 pSpectInfo[j + 4].weight;
1622 tmpWeight2 = pSpectInfo[j + 4].weight +
1623 pSpectInfo[j + 8].weight;
1624 if (tmpWeight1 <= tmpWeight2) {
1625 if (pSpectInfo[j].weight <=
1626 pSpectInfo[j + 4].weight) {
1627 pSpectInfo[j].weight =
1628 tmpWeight1;
1629 pSpectInfo[j + 4].weight =
1630 SAP_ACS_WEIGHT_MAX * 2;
1631 pSpectInfo[j + 8].weight =
1632 SAP_ACS_WEIGHT_MAX * 2;
1633 } else {
1634 pSpectInfo[j + 4].weight =
1635 tmpWeight1;
1636 /* for secondary channel selection */
1637 pSpectInfo[j].weight =
1638 SAP_ACS_WEIGHT_MAX * 2
1639 - 1;
1640 pSpectInfo[j + 8].weight =
1641 SAP_ACS_WEIGHT_MAX * 2;
1642 }
1643 } else {
1644 if (pSpectInfo[j + 4].weight <=
1645 pSpectInfo[j + 8].weight) {
1646 pSpectInfo[j + 4].weight =
1647 tmpWeight2;
1648 pSpectInfo[j].weight =
1649 SAP_ACS_WEIGHT_MAX * 2;
1650 /* for secondary channel selection */
1651 pSpectInfo[j + 8].weight =
1652 SAP_ACS_WEIGHT_MAX * 2
1653 - 1;
1654 } else {
1655 pSpectInfo[j + 8].weight =
1656 tmpWeight2;
1657 pSpectInfo[j].weight =
1658 SAP_ACS_WEIGHT_MAX * 2;
1659 pSpectInfo[j + 4].weight =
1660 SAP_ACS_WEIGHT_MAX * 2;
1661 }
1662 }
1663 } else {
1664 tmpWeight1 = pSpectInfo[j].weight +
1665 pSpectInfo[j + 4].weight;
1666 if (pSpectInfo[j].weight <=
1667 pSpectInfo[j + 4].weight) {
1668 pSpectInfo[j].weight = tmpWeight1;
1669 pSpectInfo[j + 4].weight =
1670 SAP_ACS_WEIGHT_MAX * 2;
1671 } else {
1672 pSpectInfo[j + 4].weight = tmpWeight1;
1673 pSpectInfo[j].weight =
1674 SAP_ACS_WEIGHT_MAX * 2;
1675 }
1676 }
1677 }
Manishekar Chandrasekaran44e334f2016-05-30 16:42:50 +05301678 sap_sort_chl_weight(pSpectInfoParams);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001679}
1680
1681/*==========================================================================
1682 FUNCTION sap_sort_chl_weight_ht40_5_g
1683
1684 DESCRIPTION
1685 Funtion to sort the channels with the least weight first for HT40 channels
1686
1687 DEPENDENCIES
1688 NA.
1689
1690 PARAMETERS
1691
1692 IN
1693 pSpectInfoParams : Pointer to the tSapChSelSpectInfo structure
1694
1695 RETURN VALUE
1696 void : NULL
1697
1698 SIDE EFFECTS
1699 ============================================================================*/
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001700static void sap_sort_chl_weight_ht40_5_g(tSapChSelSpectInfo *pSpectInfoParams)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001701{
1702 uint8_t i, j;
1703 tSapSpectChInfo *pSpectInfo;
1704
1705 pSpectInfo = pSpectInfoParams->pSpectCh;
1706 /*for each HT40 channel, calculate the combined weight of the
1707 two 20MHz weight */
1708 for (i = 0; i < ARRAY_SIZE(acs_ht40_channels5_g); i++) {
1709 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
1710 if (pSpectInfo[j].chNum ==
1711 acs_ht40_channels5_g[i].chStartNum)
1712 break;
1713 }
1714 if (j == pSpectInfoParams->numSpectChans)
1715 continue;
1716
1717 /* found the channel, add the two adjacent channels' weight */
1718 if ((pSpectInfo[j].chNum + 4) == pSpectInfo[j + 1].chNum) {
1719 acs_ht40_channels5_g[i].weight = pSpectInfo[j].weight +
1720 pSpectInfo[j + 1].weight;
1721 /* select better of the adjact channel as the primary channel */
1722 if (pSpectInfo[j].weight <= pSpectInfo[j + 1].weight) {
1723 pSpectInfo[j].weight =
1724 acs_ht40_channels5_g[i].weight;
1725 /* mark the adjacent channel's weight as max value so
1726 that it will be sorted to the bottom */
1727 pSpectInfo[j + 1].weight =
1728 SAP_ACS_WEIGHT_MAX * 2;
1729 } else {
1730 pSpectInfo[j + 1].weight =
1731 acs_ht40_channels5_g[i].weight;
1732 /* mark the adjacent channel's weight as max value so
1733 that it will be sorted to the bottom */
1734 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2;
1735 }
1736
1737 } else
1738 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2;
1739 }
1740
1741 /* avoid channel 165 by setting its weight to max */
1742 pSpectInfo = pSpectInfoParams->pSpectCh;
1743 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
1744 if (CHANNEL_165 == pSpectInfo[j].chNum) {
1745 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2;
1746 break;
1747 }
1748 }
1749
1750 pSpectInfo = pSpectInfoParams->pSpectCh;
1751 for (j = 0; j < (pSpectInfoParams->numSpectChans); j++) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301752 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001753 "In %s, Channel=%d Weight= %d rssi=%d bssCount=%d",
1754 __func__, pSpectInfo->chNum, pSpectInfo->weight,
1755 pSpectInfo->rssiAgr, pSpectInfo->bssCount);
1756 pSpectInfo++;
1757 }
1758
1759 sap_sort_chl_weight(pSpectInfoParams);
1760}
1761
1762/*==========================================================================
1763 FUNCTION sap_sort_chl_weight_all
1764
1765 DESCRIPTION
1766 Funtion to sort the channels with the least weight first
1767
1768 DEPENDENCIES
1769 NA.
1770
1771 PARAMETERS
1772
1773 IN
1774 ptSapContext : Pointer to the ptSapContext structure
1775 pSpectInfoParams : Pointer to the tSapChSelSpectInfo structure
1776
1777 RETURN VALUE
1778 void : NULL
1779
1780 SIDE EFFECTS
1781 ============================================================================*/
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001782static void sap_sort_chl_weight_all(ptSapContext pSapCtx,
1783 tSapChSelSpectInfo *pSpectInfoParams,
1784 uint32_t operatingBand)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001785{
1786 tSapSpectChInfo *pSpectCh = NULL;
1787 uint32_t j = 0;
1788#ifndef SOFTAP_CHANNEL_RANGE
1789 uint32_t i = 0;
1790#endif
1791
1792 pSpectCh = pSpectInfoParams->pSpectCh;
1793#ifdef SOFTAP_CHANNEL_RANGE
1794
1795 switch (pSapCtx->acs_cfg->ch_width) {
1796 case CH_WIDTH_40MHZ:
1797 if (eCSR_DOT11_MODE_11g == operatingBand)
1798 sap_sort_chl_weight_ht40_24_g(pSpectInfoParams);
1799 else if (eCSR_DOT11_MODE_11a == operatingBand)
1800 sap_sort_chl_weight_ht40_5_g(pSpectInfoParams);
1801 else {
1802 sap_sort_chl_weight_ht40_24_g(pSpectInfoParams);
1803 sap_sort_chl_weight_ht40_5_g(pSpectInfoParams);
1804 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001805 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001806 case CH_WIDTH_80MHZ:
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001807 case CH_WIDTH_80P80MHZ:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001808 sap_sort_chl_weight_ht80(pSpectInfoParams);
1809 break;
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001810 case CH_WIDTH_160MHZ:
1811 sap_sort_chl_weight_vht160(pSpectInfoParams);
1812 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001813 case CH_WIDTH_20MHZ:
1814 default:
1815 /* Sorting the channels as per weights as 20MHz channels */
1816 sap_sort_chl_weight(pSpectInfoParams);
1817 }
1818
1819#else
1820 /* Sorting the channels as per weights */
1821 for (i = 0; i < SPECT_24GHZ_CH_COUNT; i++) {
1822 minWeightIndex = i;
1823 for (j = i + 1; j < SPECT_24GHZ_CH_COUNT; j++) {
1824 if (pSpectCh[j].weight <
1825 pSpectCh[minWeightIndex].weight) {
1826 minWeightIndex = j;
1827 }
1828 }
1829 if (minWeightIndex != i) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301830 qdf_mem_copy(&temp, &pSpectCh[minWeightIndex],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001831 sizeof(*pSpectCh));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301832 qdf_mem_copy(&pSpectCh[minWeightIndex], &pSpectCh[i],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001833 sizeof(*pSpectCh));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301834 qdf_mem_copy(&pSpectCh[i], &temp, sizeof(*pSpectCh));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001835 }
1836 }
1837#endif
1838
1839 /* For testing */
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301840 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001841 "In %s, Sorted Spectrum Channels Weight", __func__);
1842 pSpectCh = pSpectInfoParams->pSpectCh;
1843 for (j = 0; j < (pSpectInfoParams->numSpectChans); j++) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301844 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001845 "In %s, Channel=%d Weight= %d rssi=%d bssCount=%d",
1846 __func__, pSpectCh->chNum, pSpectCh->weight,
1847 pSpectCh->rssiAgr, pSpectCh->bssCount);
1848 pSpectCh++;
1849 }
1850
1851}
1852
1853/*==========================================================================
1854 FUNCTION sap_filter_over_lap_ch
1855
1856 DESCRIPTION
1857 return true if ch is acceptable.
1858 This function will decide if we will filter over lap channel or not.
1859
1860 DEPENDENCIES
1861 shall called after ap start.
1862
1863 PARAMETERS
1864
1865 IN
1866 pSapCtx : Pointer to ptSapContext.
1867 chNum : Filter channel number.
1868
1869 RETURN VALUE
1870 bool : true if channel is accepted.
1871
1872 SIDE EFFECTS
1873 ============================================================================*/
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001874static bool sap_filter_over_lap_ch(ptSapContext pSapCtx, uint16_t chNum)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001875{
1876 if (pSapCtx->enableOverLapCh)
1877 return eSAP_TRUE;
1878 else if ((chNum == CHANNEL_1) ||
1879 (chNum == CHANNEL_6) || (chNum == CHANNEL_11))
1880 return eSAP_TRUE;
1881
1882 return eSAP_FALSE;
1883}
1884
Naveen Rawat365d1cb2016-02-05 12:10:43 -08001885/**
1886 * sap_select_channel_no_scan_result() - select SAP channel when no scan results
1887 * are available.
1888 * @sap_ctx: Sap context
1889 *
1890 * Returns: channel number if success, 0 otherwise
1891 */
Kondabattini, Ganesh13bb4b12016-09-04 16:16:53 +05301892static uint8_t sap_select_channel_no_scan_result(tHalHandle hal,
1893 ptSapContext sap_ctx)
Naveen Rawat365d1cb2016-02-05 12:10:43 -08001894{
Naveen Rawat365d1cb2016-02-05 12:10:43 -08001895 uint32_t start_ch_num, end_ch_num;
1896#ifdef FEATURE_WLAN_CH_AVOID
Mohit Khanna841044f2016-03-25 16:16:24 -07001897 enum channel_state ch_type;
Naveen Rawat365d1cb2016-02-05 12:10:43 -08001898 uint8_t i, first_safe_ch_in_range = SAP_CHANNEL_NOT_SELECTED;
1899#endif
Kondabattini, Ganesh13bb4b12016-09-04 16:16:53 +05301900 uint32_t dfs_master_cap_enabled;
Naveen Rawat365d1cb2016-02-05 12:10:43 -08001901 start_ch_num = sap_ctx->acs_cfg->start_ch;
1902 end_ch_num = sap_ctx->acs_cfg->end_ch;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001903
Naveen Rawat365d1cb2016-02-05 12:10:43 -08001904 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
1905 FL("start - end: %d - %d"), start_ch_num, end_ch_num);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001906
Naveen Rawat365d1cb2016-02-05 12:10:43 -08001907#ifndef FEATURE_WLAN_CH_AVOID
1908 sap_ctx->acs_cfg->pri_ch = start_ch_num;
1909 sap_ctx->acs_cfg->ht_sec_ch = 0;
1910 /* pick the first channel in configured range */
1911 return start_ch_num;
1912#else
Kondabattini, Ganesh13bb4b12016-09-04 16:16:53 +05301913 sme_cfg_get_int(hal, WNI_CFG_DFS_MASTER_ENABLED,
1914 &dfs_master_cap_enabled);
1915
1916 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
1917 "%s: dfs_master %x", __func__, dfs_master_cap_enabled);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001918
Naveen Rawat365d1cb2016-02-05 12:10:43 -08001919 /* get a channel in PCL and within the range */
1920 for (i = 0; i < sap_ctx->acs_cfg->pcl_ch_count; i++) {
1921 if ((sap_ctx->acs_cfg->pcl_channels[i] < start_ch_num) ||
1922 (sap_ctx->acs_cfg->pcl_channels[i] > end_ch_num))
1923 continue;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001924
Naveen Rawat365d1cb2016-02-05 12:10:43 -08001925 first_safe_ch_in_range = sap_ctx->acs_cfg->pcl_channels[i];
1926 break;
1927 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001928
Naveen Rawat365d1cb2016-02-05 12:10:43 -08001929 if (SAP_CHANNEL_NOT_SELECTED != first_safe_ch_in_range)
1930 return first_safe_ch_in_range;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001931
Naveen Rawat365d1cb2016-02-05 12:10:43 -08001932 for (i = 0; i < NUM_CHANNELS; i++) {
1933 if ((safe_channels[i].channelNumber < start_ch_num) ||
1934 (safe_channels[i].channelNumber > end_ch_num))
1935 continue;
1936
1937 ch_type = cds_get_channel_state(safe_channels[i].channelNumber);
1938
1939 if ((ch_type == CHANNEL_STATE_DISABLE) ||
1940 (ch_type == CHANNEL_STATE_INVALID))
1941 continue;
Kondabattini, Ganesh13bb4b12016-09-04 16:16:53 +05301942 if ((!dfs_master_cap_enabled) &&
1943 (CHANNEL_STATE_DFS == ch_type)) {
1944 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
1945 "%s: DFS master mode disabled. Skip DFS channel %d",
1946 __func__, safe_channels[i].channelNumber);
1947 continue;
1948 }
Agrawal Ashish65634612016-08-18 13:24:32 +05301949 if ((sap_ctx->dfs_mode == ACS_DFS_MODE_DISABLE) &&
1950 (CHANNEL_STATE_DFS == ch_type))
1951 continue;
Kondabattini, Ganesh13bb4b12016-09-04 16:16:53 +05301952
Naveen Rawat365d1cb2016-02-05 12:10:43 -08001953 if (safe_channels[i].isSafe == true) {
1954 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
1955 FL("channel %d in the configuration is safe"),
1956 safe_channels[i].channelNumber);
1957 first_safe_ch_in_range = safe_channels[i].channelNumber;
1958 break;
1959 }
1960
1961 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
1962 FL("channel %d in the configuration is unsafe"),
1963 safe_channels[i].channelNumber);
1964 }
1965
1966 /* if no channel selected return SAP_CHANNEL_NOT_SELECTED */
1967 return first_safe_ch_in_range;
1968#endif /* !FEATURE_WLAN_CH_AVOID */
1969}
1970
1971/**
1972 * sap_select_channel() - select SAP channel
1973 * @hal: Pointer to HAL handle
1974 * @sap_ctx: Sap context
1975 * @scan_result: Pointer to tScanResultHandle
1976 *
1977 * Runs a algorithm to select the best channel to operate in based on BSS
1978 * rssi and bss count on each channel
1979 *
1980 * Returns: channel number if success, 0 otherwise
1981 */
1982uint8_t sap_select_channel(tHalHandle hal, ptSapContext sap_ctx,
1983 tScanResultHandle scan_result)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001984{
1985 /* DFS param object holding all the data req by the algo */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08001986 tSapChSelSpectInfo spect_info_obj = { NULL, 0 };
1987 tSapChSelSpectInfo *spect_info = &spect_info_obj;
1988 uint8_t best_ch_num = SAP_CHANNEL_NOT_SELECTED;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001989#ifdef SOFTAP_CHANNEL_RANGE
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001990 uint8_t count;
Naveen Rawat365d1cb2016-02-05 12:10:43 -08001991 uint32_t start_ch_num, end_ch_num, tmp_ch_num, operating_band = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001992#endif
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301993 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001994 "In %s, Running SAP Ch Select", __func__);
1995
1996#ifdef FEATURE_WLAN_CH_AVOID
Naveen Rawat365d1cb2016-02-05 12:10:43 -08001997 sap_update_unsafe_channel_list(sap_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001998#endif
1999
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002000 if (NULL == scan_result) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302001 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002002 FL("No external AP present"));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002003
2004#ifndef SOFTAP_CHANNEL_RANGE
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002005 return SAP_CHANNEL_NOT_SELECTED;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002006#else
Kondabattini, Ganesh13bb4b12016-09-04 16:16:53 +05302007 return sap_select_channel_no_scan_result(hal, sap_ctx);
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002008#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002009 }
2010
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002011 /* Initialize the structure pointed by spect_info */
2012 if (sap_chan_sel_init(hal, spect_info, sap_ctx) != eSAP_TRUE) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302013 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002014 FL("Ch Select initialization failed"));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002015 return SAP_CHANNEL_NOT_SELECTED;
2016 }
2017 /* Compute the weight of the entire spectrum in the operating band */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002018 sap_compute_spect_weight(spect_info, hal, scan_result, sap_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002019
2020#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
2021 /* process avoid channel IE to collect all channels to avoid */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002022 sap_process_avoid_ie(hal, sap_ctx, scan_result, spect_info);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002023#endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
2024
2025#ifdef SOFTAP_CHANNEL_RANGE
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002026 start_ch_num = sap_ctx->acs_cfg->start_ch;
2027 end_ch_num = sap_ctx->acs_cfg->end_ch;
2028 SET_ACS_BAND(operating_band, sap_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002029
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002030 sap_ctx->acsBestChannelInfo.channelNum = 0;
2031 sap_ctx->acsBestChannelInfo.weight = SAP_ACS_WEIGHT_MAX;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002032
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002033 /* Sort the ch lst as per the computed weights, lesser weight first. */
2034 sap_sort_chl_weight_all(sap_ctx, spect_info, operating_band);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002035
2036 /*Loop till get the best channel in the given range */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002037 for (count = 0; count < spect_info->numSpectChans; count++) {
2038 if ((start_ch_num > spect_info->pSpectCh[count].chNum) ||
2039 (end_ch_num < spect_info->pSpectCh[count].chNum))
2040 continue;
2041
2042 if (best_ch_num == SAP_CHANNEL_NOT_SELECTED) {
2043 best_ch_num = spect_info->pSpectCh[count].chNum;
2044 /* check if best_ch_num is in preferred channel list */
2045 best_ch_num =
2046 sap_select_preferred_channel_from_channel_list(
2047 best_ch_num, sap_ctx, spect_info);
2048 /* if not in preferred ch lst, go to nxt best ch */
2049 if (best_ch_num == SAP_CHANNEL_NOT_SELECTED)
2050 continue;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002051
2052#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002053 /*
2054 * Weight of the channels(device's AP is operating)
2055 * increased to MAX+1 so that they will be choosen only
2056 * when there is no other best channel to choose
2057 */
2058 if (sap_check_in_avoid_ch_list(sap_ctx, best_ch_num)) {
2059 best_ch_num = SAP_CHANNEL_NOT_SELECTED;
2060 continue;
2061 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002062#endif
2063
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002064 sap_ctx->acsBestChannelInfo.channelNum = best_ch_num;
2065 sap_ctx->acsBestChannelInfo.weight =
2066 spect_info->pSpectCh[count].weight_copy;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002067 }
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002068
2069 if (best_ch_num == SAP_CHANNEL_NOT_SELECTED)
2070 continue;
2071
2072 if (operating_band != eCSR_DOT11_MODE_11g)
2073 continue;
2074
2075 /* Give preference to Non-overlap channels */
2076 if (false == sap_filter_over_lap_ch(sap_ctx,
2077 spect_info->pSpectCh[count].chNum))
2078 continue;
2079
2080 tmp_ch_num = spect_info->pSpectCh[count].chNum;
2081 tmp_ch_num = sap_select_preferred_channel_from_channel_list(
2082 tmp_ch_num, sap_ctx, spect_info);
2083 if (tmp_ch_num == SAP_CHANNEL_NOT_SELECTED)
2084 continue;
2085
2086 best_ch_num = tmp_ch_num;
2087 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002088 }
2089#else
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002090 /* Sort the ch lst as per the computed weights, lesser weight first. */
2091 sap_sort_chl_weight_all(sap_ctx, hal, spect_info);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002092 /* Get the first channel in sorted array as best 20M Channel */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002093 best_ch_num = (uint8_t) spect_info->pSpectCh[0].chNum;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002094 /* Select Best Channel from Channel List if Configured */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002095 best_ch_num = sap_select_preferred_channel_from_channel_list(
2096 best_ch_num, sap_ctx, spect_info);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002097#endif
2098
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002099 /*
2100 * in case the best channel seleted is not in PCL and there is another
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002101 * channel which has same weightage and is in PCL, choose the one in
2102 * PCL
2103 */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002104 for (count = 0; count < spect_info->numSpectChans; count++) {
2105 if (!ch_in_pcl(sap_ctx, spect_info->pSpectCh[count].chNum) ||
2106 (spect_info->pSpectCh[count].weight !=
2107 sap_ctx->acsBestChannelInfo.weight))
2108 continue;
2109
2110 if (sap_select_preferred_channel_from_channel_list(
2111 spect_info->pSpectCh[count].chNum, sap_ctx, spect_info)
2112 == SAP_CHANNEL_NOT_SELECTED)
2113 continue;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002114
2115#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002116 if (sap_check_in_avoid_ch_list(sap_ctx, best_ch_num))
2117 continue;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002118#endif
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002119 best_ch_num = spect_info->pSpectCh[count].chNum;
2120 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2121 FL("change best channel to %d in PCL"), best_ch_num);
2122 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002123 }
2124
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002125 sap_ctx->acs_cfg->pri_ch = best_ch_num;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002126 /* determine secondary channel for 2.4G channel 5, 6, 7 in HT40 */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002127 if ((operating_band != eCSR_DOT11_MODE_11g) ||
2128 (sap_ctx->acs_cfg->ch_width != CH_WIDTH_40MHZ))
2129 goto sap_ch_sel_end;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002130
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002131 if ((best_ch_num >= 5) && (best_ch_num <= 7)) {
2132 int weight_below, weight_above, i;
2133 tSapSpectChInfo *pspect_info;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002134
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002135 weight_below = weight_above = SAP_ACS_WEIGHT_MAX;
2136 pspect_info = spect_info->pSpectCh;
2137 for (i = 0; i < spect_info->numSpectChans; i++) {
2138 if (pspect_info[i].chNum == (best_ch_num - 4))
2139 weight_below = pspect_info[i].weight;
2140 if (pspect_info[i].chNum == (best_ch_num + 4))
2141 weight_above = pspect_info[i].weight;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002142 }
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002143
2144 if (weight_below < weight_above)
2145 sap_ctx->acs_cfg->ht_sec_ch =
2146 sap_ctx->acs_cfg->pri_ch - 4;
2147 else
2148 sap_ctx->acs_cfg->ht_sec_ch =
2149 sap_ctx->acs_cfg->pri_ch + 4;
2150 } else if (best_ch_num >= 1 && best_ch_num <= 4) {
2151 sap_ctx->acs_cfg->ht_sec_ch = sap_ctx->acs_cfg->pri_ch + 4;
2152 } else if (best_ch_num >= 8 && best_ch_num <= 13) {
2153 sap_ctx->acs_cfg->ht_sec_ch = sap_ctx->acs_cfg->pri_ch - 4;
2154 } else if (best_ch_num == 14) {
2155 sap_ctx->acs_cfg->ht_sec_ch = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002156 }
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002157 sap_ctx->secondary_ch = sap_ctx->acs_cfg->ht_sec_ch;
2158
2159sap_ch_sel_end:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002160 /* Free all the allocated memory */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002161 sap_chan_sel_exit(spect_info);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002162
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302163 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002164 FL("Running SAP Ch select Completed, Ch=%d"), best_ch_num);
2165 if (best_ch_num > 0 && best_ch_num <= 252)
2166 return best_ch_num;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002167 else
2168 return SAP_CHANNEL_NOT_SELECTED;
2169}