blob: a24cb1dad955ad35a53e771a49fb060f196df9d2 [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"
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -070058#include "wlan_reg_services_api.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080059
60/*--------------------------------------------------------------------------
61 Function definitions
62 --------------------------------------------------------------------------*/
63
64/*--------------------------------------------------------------------------
65 Defines
66 --------------------------------------------------------------------------*/
67#define SAP_DEBUG
68
69#define IS_RSSI_VALID(extRssi, rssi) \
70 ( \
71 ((extRssi < rssi) ? true : false) \
72 )
73
74#define SET_ACS_BAND(acs_band, pSapCtx) \
75{ \
76 if (pSapCtx->acs_cfg->start_ch <= 14 && \
77 pSapCtx->acs_cfg->end_ch <= 14) \
78 acs_band = eCSR_DOT11_MODE_11g; \
79 else if (pSapCtx->acs_cfg->start_ch >= 14)\
80 acs_band = eCSR_DOT11_MODE_11a; \
81 else \
82 acs_band = eCSR_DOT11_MODE_abg; \
83}
84
Tang Yingying523322d2017-01-17 23:28:43 +080085#define GET_IE_LEN_IN_BSS_DESC(lenInBss) (lenInBss + sizeof(lenInBss) - \
86 ((uintptr_t)OFFSET_OF(tSirBssDescription, ieFields)))
87
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080088#ifdef FEATURE_WLAN_CH_AVOID
Amar Singhalb8d4f152016-02-10 10:21:43 -080089sapSafeChannelType safe_channels[NUM_CHANNELS] = {
90 {1, true},
91 {2, true},
92 {3, true},
93 {4, true},
94 {5, true},
95 {6, true},
96 {7, true},
97 {8, true},
98 {9, true},
99 {10, true},
100 {11, true},
101 {12, true},
102 {13, true},
103 {14, true},
104 {36, true},
105 {40, true},
106 {44, true},
107 {48, true},
108 {52, true},
109 {56, true},
110 {60, true},
111 {64, true},
112 {100, true},
113 {104, true},
114 {108, true},
115 {112, true},
116 {116, true},
117 {120, true},
118 {124, true},
119 {128, true},
120 {132, true},
121 {136, true},
122 {140, true},
123 {144, true},
124 {149, true},
125 {153, true},
126 {157, true},
127 {161, true},
128 {165, true},
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800129};
130#endif
131
132typedef struct {
133 uint16_t chStartNum;
134 uint32_t weight;
135} sapAcsChannelInfo;
136
137sapAcsChannelInfo acs_ht40_channels5_g[] = {
138 {36, SAP_ACS_WEIGHT_MAX},
139 {44, SAP_ACS_WEIGHT_MAX},
140 {52, SAP_ACS_WEIGHT_MAX},
141 {60, SAP_ACS_WEIGHT_MAX},
142 {100, SAP_ACS_WEIGHT_MAX},
143 {108, SAP_ACS_WEIGHT_MAX},
144 {116, SAP_ACS_WEIGHT_MAX},
145 {124, SAP_ACS_WEIGHT_MAX},
146 {132, SAP_ACS_WEIGHT_MAX},
147 {140, SAP_ACS_WEIGHT_MAX},
148 {149, SAP_ACS_WEIGHT_MAX},
149 {157, SAP_ACS_WEIGHT_MAX},
150};
151
152sapAcsChannelInfo acs_ht80_channels[] = {
153 {36, SAP_ACS_WEIGHT_MAX},
154 {52, SAP_ACS_WEIGHT_MAX},
155 {100, SAP_ACS_WEIGHT_MAX},
156 {116, SAP_ACS_WEIGHT_MAX},
157 {132, SAP_ACS_WEIGHT_MAX},
158 {149, SAP_ACS_WEIGHT_MAX},
159};
160
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -0700161sapAcsChannelInfo acs_vht160_channels[] = {
162 {36, SAP_ACS_WEIGHT_MAX},
163 {100, SAP_ACS_WEIGHT_MAX},
164};
165
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800166sapAcsChannelInfo acs_ht40_channels24_g[] = {
167 {1, SAP_ACS_WEIGHT_MAX},
168 {2, SAP_ACS_WEIGHT_MAX},
169 {3, SAP_ACS_WEIGHT_MAX},
170 {4, SAP_ACS_WEIGHT_MAX},
171 {9, SAP_ACS_WEIGHT_MAX},
172};
173
174#define CHANNEL_165 165
175
176/* rssi discount for channels in PCL */
177#define PCL_RSSI_DISCOUNT 10
178
179#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
180/**
181 * sap_check_n_add_channel() - checks and add given channel in sap context's
182 * avoid_channels_info struct
183 * @sap_ctx: sap context.
184 * @new_channel: channel to be added to sap_ctx's avoid ch info
185 *
186 * sap_ctx contains sap_avoid_ch_info strcut containing the list of channels on
187 * which MDM device's AP with MCC was detected. This function will add channels
188 * to that list after checking for duplicates.
189 *
190 * Return: true: if channel was added or already present
191 * else false: if channel list was already full.
192 */
Tang Yingying523322d2017-01-17 23:28:43 +0800193static bool
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800194sap_check_n_add_channel(ptSapContext sap_ctx,
195 uint8_t new_channel)
196{
197 uint8_t i = 0;
198 struct sap_avoid_channels_info *ie_info =
199 &sap_ctx->sap_detected_avoid_ch_ie;
200
201 for (i = 0; i < sizeof(ie_info->channels); i++) {
202 if (ie_info->channels[i] == new_channel)
203 break;
204
205 if (ie_info->channels[i] == 0) {
206 ie_info->channels[i] = new_channel;
207 break;
208 }
209 }
210 if (i == sizeof(ie_info->channels))
211 return false;
212 else
213 return true;
214}
215/**
216 * sap_check_n_add_overlapped_chnls() - checks & add overlapped channels
217 * to primary channel in 2.4Ghz band.
218 * @sap_ctx: sap context.
219 * @primary_chnl: primary channel to be avoided.
220 *
221 * sap_ctx contains sap_avoid_ch_info struct containing the list of channels on
222 * which MDM device's AP with MCC was detected. This function will add channels
223 * to that list after checking for duplicates.
224 *
225 * Return: true: if channel was added or already present
226 * else false: if channel list was already full.
227 */
228static bool
229sap_check_n_add_overlapped_chnls(ptSapContext sap_ctx, uint8_t primary_channel)
230{
231 uint8_t i = 0, j = 0, upper_chnl = 0, lower_chnl = 0;
232 struct sap_avoid_channels_info *ie_info =
233 &sap_ctx->sap_detected_avoid_ch_ie;
234 /*
235 * if primary channel less than channel 1 or out of 2g band then
236 * no further process is required. return true in this case.
237 */
238 if (primary_channel < CHANNEL_1 || primary_channel > CHANNEL_14)
239 return true;
240
241 /* lower channel is one channel right before primary channel */
242 lower_chnl = primary_channel - 1;
243 /* upper channel is one channel right after primary channel */
244 upper_chnl = primary_channel + 1;
245
246 /* lower channel needs to be non-zero, zero is not valid channel */
247 if (lower_chnl > (CHANNEL_1 - 1)) {
248 for (i = 0; i < sizeof(ie_info->channels); i++) {
249 if (ie_info->channels[i] == lower_chnl)
250 break;
251 if (ie_info->channels[i] == 0) {
252 ie_info->channels[i] = lower_chnl;
253 break;
254 }
255 }
256 }
257 /* upper channel needs to be atleast last channel in 2.4Ghz band */
258 if (upper_chnl < (CHANNEL_14 + 1)) {
259 for (j = 0; j < sizeof(ie_info->channels); j++) {
260 if (ie_info->channels[j] == upper_chnl)
261 break;
262 if (ie_info->channels[j] == 0) {
263 ie_info->channels[j] = upper_chnl;
264 break;
265 }
266 }
267 }
268 if (i == sizeof(ie_info->channels) || j == sizeof(ie_info->channels))
269 return false;
270 else
271 return true;
272}
273
274/**
275 * sap_process_avoid_ie() - processes the detected Q2Q IE
276 * context's avoid_channels_info struct
277 * @hal: hal handle
278 * @sap_ctx: sap context.
279 * @scan_result: scan results for ACS scan.
280 * @spect_info: spectrum weights array to update
281 *
282 * Detection of Q2Q IE indicates presence of another MDM device with its AP
283 * operating in MCC mode. This function parses the scan results and processes
284 * the Q2Q IE if found. It then extracts the channels and populates them in
285 * sap_ctx struct. It also increases the weights of those channels so that
286 * ACS logic will avoid those channels in its selection algorithm.
287 *
288 * Return: void
289 */
Tang Yingying523322d2017-01-17 23:28:43 +0800290static void sap_process_avoid_ie(tHalHandle hal,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800291 ptSapContext sap_ctx,
292 tScanResultHandle scan_result,
293 tSapChSelSpectInfo *spect_info)
294{
295 uint32_t total_ie_len = 0;
296 uint8_t *temp_ptr = NULL;
297 uint8_t i = 0;
298 struct sAvoidChannelIE *avoid_ch_ie;
299 tCsrScanResultInfo *node = NULL;
300 tpAniSirGlobal mac_ctx = NULL;
301 tSapSpectChInfo *spect_ch = NULL;
302
303 mac_ctx = PMAC_STRUCT(hal);
304 spect_ch = spect_info->pSpectCh;
305 node = sme_scan_result_get_first(hal, scan_result);
306
307 while (node) {
Abhishek Singh34a4d862016-10-26 16:01:51 +0530308 total_ie_len =
309 GET_IE_LEN_IN_BSS_DESC(node->BssDescriptor.length);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800310 temp_ptr = cfg_get_vendor_ie_ptr_from_oui(mac_ctx,
311 SIR_MAC_QCOM_VENDOR_OUI,
312 SIR_MAC_QCOM_VENDOR_SIZE,
313 ((uint8_t *)&node->BssDescriptor.ieFields),
314 total_ie_len);
315
316 if (temp_ptr) {
317 avoid_ch_ie = (struct sAvoidChannelIE *)temp_ptr;
Will Huang55ba1042017-03-22 10:43:30 +0800318 if (avoid_ch_ie->type !=
319 QCOM_VENDOR_IE_MCC_AVOID_CH) {
320 node = sme_scan_result_get_next(hal,
321 scan_result);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800322 continue;
Will Huang55ba1042017-03-22 10:43:30 +0800323 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800324
325 sap_ctx->sap_detected_avoid_ch_ie.present = 1;
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530326 QDF_TRACE(QDF_MODULE_ID_SAP,
327 QDF_TRACE_LEVEL_DEBUG,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800328 "Q2Q IE - avoid ch %d",
329 avoid_ch_ie->channel);
330 /* add this channel to to_avoid channel list */
331 sap_check_n_add_channel(sap_ctx,
332 avoid_ch_ie->channel);
333 sap_check_n_add_overlapped_chnls(sap_ctx,
334 avoid_ch_ie->channel);
335 /*
336 * Mark weight of these channel present in IE to MAX
337 * so that ACS logic will to avoid thse channels
338 */
339 for (i = 0; i < spect_info->numSpectChans; i++)
340 if (spect_ch[i].chNum == avoid_ch_ie->channel) {
341 /*
342 * weight is set more than max so that,
343 * in the case of other channels being
344 * assigned max weight due to noise,
345 * they may be preferred over channels
346 * with Q2Q IE.
347 */
348 spect_ch[i].weight = SAP_ACS_WEIGHT_MAX + 1;
349 spect_ch[i].weight_copy =
350 SAP_ACS_WEIGHT_MAX + 1;
351 break;
352 }
353 } /* if (temp_ptr) */
354 node = sme_scan_result_get_next(hal, scan_result);
355 }
356}
357#endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
358
359#ifdef FEATURE_WLAN_CH_AVOID
360/*==========================================================================
361 FUNCTION sap_update_unsafe_channel_list
362
363 DESCRIPTION
364 Function Undate unsafe channel list table
365
366 DEPENDENCIES
367 NA.
368
369 IN
370 SapContext pointer
371
372 RETURN VALUE
373 NULL
374 ============================================================================*/
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -0700375void sap_update_unsafe_channel_list(tHalHandle hal, ptSapContext pSapCtx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800376{
377 uint16_t i, j;
Amar Singhalb8d4f152016-02-10 10:21:43 -0800378 uint16_t unsafe_channel_list[NUM_CHANNELS];
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800379 uint16_t unsafe_channel_count = 0;
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -0700380 tpAniSirGlobal mac_ctx = NULL;
381
Yuanyuan Liu0e0aa932016-05-12 10:17:58 -0700382 qdf_device_t qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800383
Yuanyuan Liu97361182016-06-06 09:38:04 -0700384 if (!qdf_ctx) {
385 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_FATAL,
386 "qdf_ctx is NULL");
387 return;
388 }
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -0700389 mac_ctx = PMAC_STRUCT(hal);
390 if (!mac_ctx) {
391 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_FATAL,
392 "mac_ctx is NULL");
393 return;
394 }
Yuanyuan Liu97361182016-06-06 09:38:04 -0700395
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800396 /* Flush, default set all channel safe */
Amar Singhalb8d4f152016-02-10 10:21:43 -0800397 for (i = 0; i < NUM_CHANNELS; i++) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800398 safe_channels[i].isSafe = true;
399 }
400
401 /* Try to find unsafe channel */
Ryan Hsu4252a2f2016-01-05 11:18:24 -0800402#if defined(FEATURE_WLAN_STA_AP_MODE_DFS_DISABLE)
Amar Singhalb8d4f152016-02-10 10:21:43 -0800403 for (i = 0; i < NUM_CHANNELS; i++) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800404 if (pSapCtx->dfs_ch_disable == true) {
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -0700405 if (wlan_reg_is_dfs_ch(mac_ctx->pdev,
406 safe_channels[i].channelNumber)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800407 safe_channels[i].isSafe = false;
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530408 QDF_TRACE(QDF_MODULE_ID_SAP,
409 QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800410 "%s: DFS Ch %d is not safe in"
411 " Concurrent mode",
412 __func__,
413 safe_channels[i].channelNumber);
414 }
415 }
416 }
417#endif
Yuanyuan Liu0e0aa932016-05-12 10:17:58 -0700418 pld_get_wlan_unsafe_channel(qdf_ctx->dev,
419 unsafe_channel_list,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800420 &unsafe_channel_count,
421 sizeof(unsafe_channel_list));
422
423 for (i = 0; i < unsafe_channel_count; i++) {
Amar Singhalb8d4f152016-02-10 10:21:43 -0800424 for (j = 0; j < NUM_CHANNELS; j++) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800425 if (safe_channels[j].channelNumber ==
426 unsafe_channel_list[i]) {
427 /* Found unsafe channel, update it */
428 safe_channels[j].isSafe = false;
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530429 QDF_TRACE(QDF_MODULE_ID_SAP,
430 QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800431 FL("CH %d is not safe"),
432 unsafe_channel_list[i]);
433 break;
434 }
435 }
436 }
437
438 return;
439}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800440
441#endif /* FEATURE_WLAN_CH_AVOID */
442
443/*==========================================================================
444 FUNCTION sap_cleanup_channel_list
445
446 DESCRIPTION
447 Function sap_cleanup_channel_list frees up the memory allocated to the channel list.
448
449 DEPENDENCIES
450 NA.
451
452 PARAMETERS
453
454 IN
455 NULL
456
457 RETURN VALUE
458 NULL
459 ============================================================================*/
460
Ryan Hsu4252a2f2016-01-05 11:18:24 -0800461void sap_cleanup_channel_list(void *p_cds_gctx)
462{
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800463 ptSapContext pSapCtx;
464
Srinivas Girigowda678586c2017-03-10 00:13:58 -0800465 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800466 "Cleaning up the channel list structure");
467
468 if (NULL == p_cds_gctx) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530469 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800470 "SAP Global Context is NULL");
471 return;
472 }
473
474 pSapCtx = CDS_GET_SAP_CB(p_cds_gctx);
475 if (NULL == pSapCtx) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530476 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800477 "SAP Context is NULL");
478 return;
479 }
480
481 pSapCtx->SapChnlList.numChannel = 0;
482 if (pSapCtx->SapChnlList.channelList) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530483 qdf_mem_free(pSapCtx->SapChnlList.channelList);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800484 pSapCtx->SapChnlList.channelList = NULL;
485 }
486
487 pSapCtx->SapAllChnlList.numChannel = 0;
488 if (pSapCtx->SapAllChnlList.channelList) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530489 qdf_mem_free(pSapCtx->SapAllChnlList.channelList);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800490 pSapCtx->SapAllChnlList.channelList = NULL;
491 }
492}
493
494/**
495 * sap_select_preferred_channel_from_channel_list() - to calc best cahnnel
496 * @best_chnl: best channel already calculated among all the chanels
497 * @sap_ctx: sap context
498 * @spectinfo_param: Pointer to tSapChSelSpectInfo structure
499 *
500 * This function calculates the best channel among the configured channel list.
501 * If channel list not configured then returns the best channel calculated
502 * among all the channel list.
503 *
504 * Return: uint8_t best channel
505 */
Jeff Johnson464f7ea2016-10-07 10:21:26 -0700506static
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800507uint8_t sap_select_preferred_channel_from_channel_list(uint8_t best_chnl,
508 ptSapContext sap_ctx,
509 tSapChSelSpectInfo *spectinfo_param)
510{
511 uint8_t i = 0;
512
513 /*
514 * If Channel List is not Configured don't do anything
515 * Else return the Best Channel from the Channel List
516 */
517 if ((NULL == sap_ctx->acs_cfg->ch_list) ||
518 (NULL == spectinfo_param) ||
519 (0 == sap_ctx->acs_cfg->ch_list_count))
520 return best_chnl;
521
522 if (best_chnl <= 0 || best_chnl > 252)
523 return SAP_CHANNEL_NOT_SELECTED;
524
525 /* Select the best channel from allowed list */
526 for (i = 0; i < sap_ctx->acs_cfg->ch_list_count; i++) {
527 if (sap_ctx->acs_cfg->ch_list[i] == best_chnl) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530528 QDF_TRACE(QDF_MODULE_ID_SAP,
529 QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800530 "Best channel is: %d",
531 best_chnl);
532 return best_chnl;
533 }
534 }
535
536 return SAP_CHANNEL_NOT_SELECTED;
537}
538
539/*==========================================================================
540 FUNCTION sap_chan_sel_init
541
542 DESCRIPTION
543 Function sap_chan_sel_init allocates the memory, intializes the
Anurag Chouhan6d760662016-02-20 16:05:43 +0530544 structures used by the channel selection algorithm
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800545
546 DEPENDENCIES
547 NA.
548
549 PARAMETERS
550
551 IN
552 halHandle : Pointer to tHalHandle
553 *pSpectInfoParams : Pointer to tSapChSelSpectInfo structure
554 pSapCtx : Pointer to SAP Context
555
556 RETURN VALUE
557 bool: Success or FAIL
558
559 SIDE EFFECTS
560 ============================================================================*/
Jeff Johnson464f7ea2016-10-07 10:21:26 -0700561static bool sap_chan_sel_init(tHalHandle halHandle,
562 tSapChSelSpectInfo *pSpectInfoParams,
563 ptSapContext pSapCtx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800564{
565 tSapSpectChInfo *pSpectCh = NULL;
566 uint8_t *pChans = NULL;
567 uint16_t channelnum = 0;
568 tpAniSirGlobal pMac = PMAC_STRUCT(halHandle);
569 bool chSafe = true;
570#ifdef FEATURE_WLAN_CH_AVOID
571 uint16_t i;
572#endif
573 uint32_t dfs_master_cap_enabled;
574 bool include_dfs_ch = true;
575
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530576 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, "In %s",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800577 __func__);
578
579 pSpectInfoParams->numSpectChans =
580 pMac->scan.base_channels.numChannels;
581
582 /* Allocate memory for weight computation of 2.4GHz */
583 pSpectCh =
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530584 (tSapSpectChInfo *) qdf_mem_malloc((pSpectInfoParams->numSpectChans)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800585 * sizeof(*pSpectCh));
586
587 if (pSpectCh == NULL) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530588 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
Anurag Chouhanf04e84f2016-03-03 10:12:12 +0530589 "In %s, QDF_MALLOC_ERR", __func__);
Srinivas Girigowda74a66d62017-06-21 23:28:25 -0700590 return false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800591 }
592
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800593 /* Initialize the pointers in the DfsParams to the allocated memory */
594 pSpectInfoParams->pSpectCh = pSpectCh;
595
596 pChans = pMac->scan.base_channels.channelList;
597
Ryan Hsu4252a2f2016-01-05 11:18:24 -0800598#if defined(FEATURE_WLAN_STA_AP_MODE_DFS_DISABLE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800599 if (pSapCtx->dfs_ch_disable == true)
600 include_dfs_ch = false;
601#endif
602 sme_cfg_get_int(halHandle, WNI_CFG_DFS_MASTER_ENABLED,
603 &dfs_master_cap_enabled);
Agrawal Ashish65634612016-08-18 13:24:32 +0530604 if (dfs_master_cap_enabled == 0 ||
605 ACS_DFS_MODE_DISABLE == pSapCtx->dfs_mode)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800606 include_dfs_ch = false;
607
608 /* Fill the channel number in the spectrum in the operating freq band */
609 for (channelnum = 0;
610 channelnum < pSpectInfoParams->numSpectChans;
Edhar, Mahesh Kumar4f660672015-10-30 11:53:26 +0530611 channelnum++, pChans++, pSpectCh++) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800612 chSafe = true;
613
614 /* check if the channel is in NOL blacklist */
615 if (sap_dfs_is_channel_in_nol_list(pSapCtx, *pChans,
616 PHY_SINGLE_CHANNEL_CENTERED)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530617 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800618 "In %s, Ch %d is in NOL list", __func__,
619 *pChans);
620 chSafe = false;
621 continue;
622 }
623
624 if (include_dfs_ch == false) {
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -0700625 if (wlan_reg_is_dfs_ch(pMac->pdev, *pChans)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800626 chSafe = false;
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530627 QDF_TRACE(QDF_MODULE_ID_SAP,
628 QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800629 "In %s, DFS Ch %d not considered for ACS",
630 __func__, *pChans);
631 continue;
632 }
633 }
634
635#ifdef FEATURE_WLAN_CH_AVOID
Amar Singhalb8d4f152016-02-10 10:21:43 -0800636 for (i = 0; i < NUM_CHANNELS; i++) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800637 if ((safe_channels[i].channelNumber == *pChans) &&
638 (false == safe_channels[i].isSafe)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530639 QDF_TRACE(QDF_MODULE_ID_SAP,
640 QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800641 "In %s, Ch %d is not safe", __func__,
642 *pChans);
643 chSafe = false;
644 break;
645 }
646 }
647#endif /* FEATURE_WLAN_CH_AVOID */
648
649 /* OFDM rates are not supported on channel 14 */
650 if (*pChans == 14 &&
651 eCSR_DOT11_MODE_11b != pSapCtx->csr_roamProfile.phyMode) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800652 continue;
653 }
654
Deepthi Gowri48b89332016-08-30 18:43:05 +0530655 /* Skip DSRC channels */
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -0700656 if (WLAN_REG_IS_11P_CH(*pChans))
Deepthi Gowri48b89332016-08-30 18:43:05 +0530657 continue;
658
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800659 if (true == chSafe) {
660 pSpectCh->chNum = *pChans;
Srinivas Girigowda74a66d62017-06-21 23:28:25 -0700661 pSpectCh->valid = true;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800662 pSpectCh->rssiAgr = SOFTAP_MIN_RSSI; /* Initialise for all channels */
663 pSpectCh->channelWidth = SOFTAP_HT20_CHANNELWIDTH; /* Initialise 20MHz for all the Channels */
664 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800665 }
Srinivas Girigowda74a66d62017-06-21 23:28:25 -0700666 return true;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800667}
668
669/*==========================================================================
670 FUNCTION sapweight_rssi_count
671
672 DESCRIPTION
673 Function weightRssiCount calculates the channel weight due to rssi
Anurag Chouhan6d760662016-02-20 16:05:43 +0530674 and data count(here number of BSS observed)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800675
676 DEPENDENCIES
677 NA.
678
679 PARAMETERS
680
681 IN
682 rssi : Max signal strength receieved from a BSS for the channel
683 count : Number of BSS observed in the channel
684
685 RETURN VALUE
686 uint32_t : Calculated channel weight based on above two
687
688 SIDE EFFECTS
689 ============================================================================*/
Jeff Johnson464f7ea2016-10-07 10:21:26 -0700690static uint32_t sapweight_rssi_count(int8_t rssi, uint16_t count)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800691{
692 int32_t rssiWeight = 0;
693 int32_t countWeight = 0;
694 uint32_t rssicountWeight = 0;
695
696 /* Weight from RSSI */
697 rssiWeight = SOFTAP_RSSI_WEIGHT * (rssi - SOFTAP_MIN_RSSI)
698 / (SOFTAP_MAX_RSSI - SOFTAP_MIN_RSSI);
699
700 if (rssiWeight > SOFTAP_RSSI_WEIGHT)
701 rssiWeight = SOFTAP_RSSI_WEIGHT;
702 else if (rssiWeight < 0)
703 rssiWeight = 0;
704
705 /* Weight from data count */
706 countWeight = SOFTAP_COUNT_WEIGHT * (count - SOFTAP_MIN_COUNT)
707 / (SOFTAP_MAX_COUNT - SOFTAP_MIN_COUNT);
708
709 if (countWeight > SOFTAP_COUNT_WEIGHT)
710 countWeight = SOFTAP_COUNT_WEIGHT;
711
712 rssicountWeight = rssiWeight + countWeight;
713
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530714 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800715 "In %s, rssiWeight=%d, countWeight=%d, rssicountWeight=%d",
716 __func__, rssiWeight, countWeight, rssicountWeight);
717
718 return rssicountWeight;
719}
720
721/**
722 * sap_update_rssi_bsscount() - updates bss count and rssi effect.
723 *
724 * @pSpectCh: Channel Information
725 * @offset: Channel Offset
726 * @sap_24g: Channel is in 2.4G or 5G
Liangwei Dong71ed6502016-10-20 03:40:45 -0400727 * @spectch_start: the start of spect ch array
728 * @spectch_end: the end of spect ch array
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800729 *
730 * sap_update_rssi_bsscount updates bss count and rssi effect based
731 * on the channel offset.
732 *
733 * Return: None.
734 */
735
Jeff Johnson464f7ea2016-10-07 10:21:26 -0700736static void sap_update_rssi_bsscount(tSapSpectChInfo *pSpectCh, int32_t offset,
Liangwei Dong71ed6502016-10-20 03:40:45 -0400737 bool sap_24g, tSapSpectChInfo *spectch_start,
738 tSapSpectChInfo *spectch_end)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800739{
740 tSapSpectChInfo *pExtSpectCh = NULL;
741 int32_t rssi, rsssi_effect;
742
743 pExtSpectCh = (pSpectCh + offset);
Liangwei Dong71ed6502016-10-20 03:40:45 -0400744 if (pExtSpectCh != NULL &&
745 pExtSpectCh >= spectch_start &&
746 pExtSpectCh < spectch_end) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800747 ++pExtSpectCh->bssCount;
748 switch (offset) {
749 case -1:
750 case 1:
751 rsssi_effect = sap_24g ?
752 SAP_24GHZ_FIRST_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY :
753 SAP_SUBBAND1_RSSI_EFFECT_PRIMARY;
754 break;
755 case -2:
756 case 2:
757 rsssi_effect = sap_24g ?
758 SAP_24GHZ_SEC_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY :
759 SAP_SUBBAND2_RSSI_EFFECT_PRIMARY;
760 break;
761 case -3:
762 case 3:
763 rsssi_effect = sap_24g ?
764 SAP_24GHZ_THIRD_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY :
765 SAP_SUBBAND3_RSSI_EFFECT_PRIMARY;
766 break;
767 case -4:
768 case 4:
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -0700769 rsssi_effect = sap_24g ?
770 SAP_24GHZ_FOURTH_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY :
771 SAP_SUBBAND4_RSSI_EFFECT_PRIMARY;
772 break;
773 case -5:
774 case 5:
775 rsssi_effect = SAP_SUBBAND5_RSSI_EFFECT_PRIMARY;
776 break;
777 case -6:
778 case 6:
779 rsssi_effect = SAP_SUBBAND6_RSSI_EFFECT_PRIMARY;
780 break;
781 case -7:
782 case 7:
783 rsssi_effect = SAP_SUBBAND7_RSSI_EFFECT_PRIMARY;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800784 break;
785 default:
786 rsssi_effect = 0;
787 break;
788 }
789
790 rssi = pSpectCh->rssiAgr + rsssi_effect;
791 if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi))
792 pExtSpectCh->rssiAgr = rssi;
793 if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI)
794 pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI;
795 }
796}
797
798/**
799 * sap_upd_chan_spec_params() - sap_upd_chan_spec_params
800 * updates channel parameters obtained from Beacon
801 * @pBeaconStruct Beacon strucutre populated by parse_beacon function
802 * @channelWidth Channel width
803 * @secondaryChannelOffset Secondary Channel Offset
804 * @vhtSupport If channel supports VHT
805 * @centerFreq Central frequency for the given channel.
806 *
807 * sap_upd_chan_spec_params updates the spectrum channels based on the
808 * pBeaconStruct obtained from Beacon IE
809 *
810 * Return: NA.
811 */
812
Jeff Johnson464f7ea2016-10-07 10:21:26 -0700813static void sap_upd_chan_spec_params(tSirProbeRespBeacon *pBeaconStruct,
814 uint16_t *channelWidth,
815 uint16_t *secondaryChannelOffset,
816 uint16_t *vhtSupport,
817 uint16_t *centerFreq,
818 uint16_t *centerFreq_2)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800819{
820 if (NULL == pBeaconStruct) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530821 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800822 FL("pBeaconStruct is NULL"));
823 return;
824 }
825
826 if (pBeaconStruct->HTCaps.present && pBeaconStruct->HTInfo.present) {
827 *channelWidth = pBeaconStruct->HTCaps.supportedChannelWidthSet;
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -0700828 *secondaryChannelOffset =
829 pBeaconStruct->HTInfo.secondaryChannelOffset;
830 if (!pBeaconStruct->VHTOperation.present)
831 return;
832 *vhtSupport = pBeaconStruct->VHTOperation.present;
833 if (pBeaconStruct->VHTOperation.chanWidth) {
834 *centerFreq =
835 pBeaconStruct->VHTOperation.chanCenterFreqSeg1;
836 *centerFreq_2 =
837 pBeaconStruct->VHTOperation.chanCenterFreqSeg2;
838 /*
839 * LHS follows tSirMacHTChannelWidth, while RHS follows
840 * WNI_CFG_VHT_CHANNEL_WIDTH_X format hence following
841 * adjustment
842 */
843 *channelWidth =
844 pBeaconStruct->VHTOperation.chanWidth + 1;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800845
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800846 }
847 }
848}
849
850/**
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -0700851 * sap_update_rssi_bsscount_vht_5G() - updates bss count and rssi effect.
852 *
Jeff Johnson464f7ea2016-10-07 10:21:26 -0700853 * @spect_ch: Channel Information
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -0700854 * @offset: Channel Offset
855 * @num_ch: no.of channels
Liangwei Dong71ed6502016-10-20 03:40:45 -0400856 * @spectch_start: the start of spect ch array
857 * @spectch_end: the end of spect ch array
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -0700858 *
859 * sap_update_rssi_bsscount_vht_5G updates bss count and rssi effect based
860 * on the channel offset.
861 *
862 * Return: None.
863 */
864
Jeff Johnson464f7ea2016-10-07 10:21:26 -0700865static void sap_update_rssi_bsscount_vht_5G(tSapSpectChInfo *spect_ch,
866 int32_t offset,
Liangwei Dong71ed6502016-10-20 03:40:45 -0400867 uint16_t num_ch,
868 tSapSpectChInfo *spectch_start,
869 tSapSpectChInfo *spectch_end)
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -0700870{
871 int32_t ch_offset;
872 uint16_t i, cnt;
873
874 if (!offset)
875 return;
876 if (offset > 0)
877 cnt = num_ch;
878 else
879 cnt = num_ch + 1;
880 for (i = 0; i < cnt; i++) {
881 ch_offset = offset + i;
882 if (ch_offset == 0)
883 continue;
Liangwei Dong71ed6502016-10-20 03:40:45 -0400884 sap_update_rssi_bsscount(spect_ch, ch_offset, false,
885 spectch_start, spectch_end);
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -0700886 }
887}
888/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800889 * sap_interference_rssi_count_5G() - sap_interference_rssi_count
890 * considers the Adjacent channel rssi and
891 * data count(here number of BSS observed)
892 * @spect_ch: Channel Information
893 * @chan_width: Channel width parsed from beacon IE
894 * @sec_chan_offset: Secondary Channel Offset
895 * @center_freq: Central frequency for the given channel.
896 * @channel_id: channel_id
Liangwei Dong71ed6502016-10-20 03:40:45 -0400897 * @spectch_start: the start of spect ch array
898 * @spectch_end: the end of spect ch array
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800899 *
900 * sap_interference_rssi_count_5G considers the Adjacent channel rssi
901 * and data count(here number of BSS observed)
902 *
903 * Return: NA.
904 */
905
Jeff Johnson464f7ea2016-10-07 10:21:26 -0700906static void sap_interference_rssi_count_5G(tSapSpectChInfo *spect_ch,
907 uint16_t chan_width,
908 uint16_t sec_chan_offset,
909 uint16_t center_freq,
910 uint16_t center_freq_2,
Liangwei Dong71ed6502016-10-20 03:40:45 -0400911 uint8_t channel_id,
912 tSapSpectChInfo *spectch_start,
913 tSapSpectChInfo *spectch_end)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800914{
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -0700915 uint16_t num_ch;
916 int32_t offset = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800917 if (NULL == spect_ch) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530918 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800919 FL("spect_ch is NULL"));
920 return;
921 }
922
923 /* Updating the received ChannelWidth */
924 if (spect_ch->channelWidth != chan_width)
925 spect_ch->channelWidth = chan_width;
926 /* If received ChannelWidth is other than HT20,
927 * we need to update the extension channel Params as well
928 * chan_width == 0, HT20
929 * chan_width == 1, HT40
930 * chan_width == 2, VHT80
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -0700931 * chan_width == 3, VHT160
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800932 */
933
934 switch (spect_ch->channelWidth) {
935 case eHT_CHANNEL_WIDTH_40MHZ: /* HT40 */
936 switch (sec_chan_offset) {
937 /* Above the Primary Channel */
938 case PHY_DOUBLE_CHANNEL_LOW_PRIMARY:
Liangwei Dong71ed6502016-10-20 03:40:45 -0400939 sap_update_rssi_bsscount(spect_ch, 1, false,
940 spectch_start, spectch_end);
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -0700941 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800942
943 /* Below the Primary channel */
944 case PHY_DOUBLE_CHANNEL_HIGH_PRIMARY:
Liangwei Dong71ed6502016-10-20 03:40:45 -0400945 sap_update_rssi_bsscount(spect_ch, -1, false,
946 spectch_start, spectch_end);
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -0700947 return;
948 }
949 return;
950 case eHT_CHANNEL_WIDTH_80MHZ: /* VHT80 */
951 num_ch = 3;
952 if ((center_freq - channel_id) == 6) {
953 offset = 1;
954 } else if ((center_freq - channel_id) == 2) {
955 offset = -1;
956 } else if ((center_freq - channel_id) == -2) {
957 offset = -2;
958 } else if ((center_freq - channel_id) == -6) {
959 offset = -3;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800960 }
961 break;
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -0700962 case eHT_CHANNEL_WIDTH_160MHZ: /* VHT160 */
963 num_ch = 7;
964 if ((center_freq - channel_id) == 14)
965 offset = 1;
966 else if ((center_freq - channel_id) == 10)
967 offset = -1;
968 else if ((center_freq - channel_id) == 6)
969 offset = -2;
970 else if ((center_freq - channel_id) == 2)
971 offset = -3;
972 else if ((center_freq - channel_id) == -2)
973 offset = -4;
974 else if ((center_freq - channel_id) == -6)
975 offset = -5;
976 else if ((center_freq - channel_id) == -10)
977 offset = -6;
978 else if ((center_freq - channel_id) == -14)
979 offset = -7;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800980 break;
981 default:
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -0700982 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800983 }
Liangwei Dong71ed6502016-10-20 03:40:45 -0400984 sap_update_rssi_bsscount_vht_5G(spect_ch, offset, num_ch,
985 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800986}
987
988/**
989 * sap_interference_rssi_count() - sap_interference_rssi_count
990 * considers the Adjacent channel rssi
991 * and data count(here number of BSS observed)
992 * @spect_ch Channel Information
Liangwei Dong71ed6502016-10-20 03:40:45 -0400993 * @spectch_start: the start of spect ch array
994 * @spectch_end: the end of spect ch array
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800995 *
996 * sap_interference_rssi_count considers the Adjacent channel rssi
997 * and data count(here number of BSS observed)
998 *
999 * Return: None.
1000 */
1001
Liangwei Dong71ed6502016-10-20 03:40:45 -04001002static void sap_interference_rssi_count(tSapSpectChInfo *spect_ch,
1003 tSapSpectChInfo *spectch_start,
1004 tSapSpectChInfo *spectch_end)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001005{
1006 if (NULL == spect_ch) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301007 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001008 "%s: spect_ch is NULL", __func__);
1009 return;
1010 }
1011
1012 switch (spect_ch->chNum) {
1013 case CHANNEL_1:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001014 sap_update_rssi_bsscount(spect_ch, 1, true,
1015 spectch_start, spectch_end);
1016 sap_update_rssi_bsscount(spect_ch, 2, true,
1017 spectch_start, spectch_end);
1018 sap_update_rssi_bsscount(spect_ch, 3, true,
1019 spectch_start, spectch_end);
1020 sap_update_rssi_bsscount(spect_ch, 4, true,
1021 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001022 break;
1023
1024 case CHANNEL_2:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001025 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_3:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001037 sap_update_rssi_bsscount(spect_ch, -2, true,
1038 spectch_start, spectch_end);
1039 sap_update_rssi_bsscount(spect_ch, -1, 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, 2, true,
1044 spectch_start, spectch_end);
1045 sap_update_rssi_bsscount(spect_ch, 3, true,
1046 spectch_start, spectch_end);
1047 sap_update_rssi_bsscount(spect_ch, 4, true,
1048 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001049 break;
1050 case CHANNEL_4:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001051 sap_update_rssi_bsscount(spect_ch, -3, true,
1052 spectch_start, spectch_end);
1053 sap_update_rssi_bsscount(spect_ch, -2, true,
1054 spectch_start, spectch_end);
1055 sap_update_rssi_bsscount(spect_ch, -1, true,
1056 spectch_start, spectch_end);
1057 sap_update_rssi_bsscount(spect_ch, 1, true,
1058 spectch_start, spectch_end);
1059 sap_update_rssi_bsscount(spect_ch, 2, 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, 4, true,
1064 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001065 break;
1066
1067 case CHANNEL_5:
1068 case CHANNEL_6:
1069 case CHANNEL_7:
1070 case CHANNEL_8:
1071 case CHANNEL_9:
1072 case CHANNEL_10:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001073 sap_update_rssi_bsscount(spect_ch, -4, true,
1074 spectch_start, spectch_end);
1075 sap_update_rssi_bsscount(spect_ch, -3, true,
1076 spectch_start, spectch_end);
1077 sap_update_rssi_bsscount(spect_ch, -2, true,
1078 spectch_start, spectch_end);
1079 sap_update_rssi_bsscount(spect_ch, -1, true,
1080 spectch_start, spectch_end);
1081 sap_update_rssi_bsscount(spect_ch, 1, true,
1082 spectch_start, spectch_end);
1083 sap_update_rssi_bsscount(spect_ch, 2, true,
1084 spectch_start, spectch_end);
1085 sap_update_rssi_bsscount(spect_ch, 3, true,
1086 spectch_start, spectch_end);
1087 sap_update_rssi_bsscount(spect_ch, 4, true,
1088 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001089 break;
1090
1091 case CHANNEL_11:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001092 sap_update_rssi_bsscount(spect_ch, -4, true,
1093 spectch_start, spectch_end);
1094 sap_update_rssi_bsscount(spect_ch, -3, true,
1095 spectch_start, spectch_end);
1096 sap_update_rssi_bsscount(spect_ch, -2, true,
1097 spectch_start, spectch_end);
1098 sap_update_rssi_bsscount(spect_ch, -1, true,
1099 spectch_start, spectch_end);
1100 sap_update_rssi_bsscount(spect_ch, 1, true,
1101 spectch_start, spectch_end);
1102 sap_update_rssi_bsscount(spect_ch, 2, true,
1103 spectch_start, spectch_end);
1104 sap_update_rssi_bsscount(spect_ch, 3, true,
1105 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001106 break;
1107
1108 case CHANNEL_12:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001109 sap_update_rssi_bsscount(spect_ch, -4, true,
1110 spectch_start, spectch_end);
1111 sap_update_rssi_bsscount(spect_ch, -3, true,
1112 spectch_start, spectch_end);
1113 sap_update_rssi_bsscount(spect_ch, -2, true,
1114 spectch_start, spectch_end);
1115 sap_update_rssi_bsscount(spect_ch, -1, true,
1116 spectch_start, spectch_end);
1117 sap_update_rssi_bsscount(spect_ch, 1, true,
1118 spectch_start, spectch_end);
1119 sap_update_rssi_bsscount(spect_ch, 2, true,
1120 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001121 break;
1122
1123 case CHANNEL_13:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001124 sap_update_rssi_bsscount(spect_ch, -4, true,
1125 spectch_start, spectch_end);
1126 sap_update_rssi_bsscount(spect_ch, -3, true,
1127 spectch_start, spectch_end);
1128 sap_update_rssi_bsscount(spect_ch, -2, true,
1129 spectch_start, spectch_end);
1130 sap_update_rssi_bsscount(spect_ch, -1, true,
1131 spectch_start, spectch_end);
1132 sap_update_rssi_bsscount(spect_ch, 1, true,
1133 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001134 break;
1135
1136 case CHANNEL_14:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001137 sap_update_rssi_bsscount(spect_ch, -4, true,
1138 spectch_start, spectch_end);
1139 sap_update_rssi_bsscount(spect_ch, -3, true,
1140 spectch_start, spectch_end);
1141 sap_update_rssi_bsscount(spect_ch, -2, true,
1142 spectch_start, spectch_end);
1143 sap_update_rssi_bsscount(spect_ch, -1, true,
1144 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001145 break;
1146
1147 default:
1148 break;
1149 }
1150}
1151
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001152/**
1153 * ch_in_pcl() - Is channel in the Preferred Channel List (PCL)
1154 * @sap_ctx: SAP context which contains the current PCL
1155 * @channel: Input channel number to be checked
1156 *
1157 * Check if a channel is in the preferred channel list
1158 *
1159 * Return:
1160 * true: channel is in PCL,
1161 * false: channel is not in PCL
1162 */
1163static bool ch_in_pcl(ptSapContext sap_ctx, uint8_t channel)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001164{
1165 uint32_t i;
1166
1167 for (i = 0; i < sap_ctx->acs_cfg->pcl_ch_count; i++) {
1168 if (channel == sap_ctx->acs_cfg->pcl_channels[i])
1169 return true;
1170 }
1171
1172 return false;
1173}
1174
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001175/**
1176 * sap_compute_spect_weight() - Compute spectrum weight
1177 * @pSpectInfoParams: Pointer to the tSpectInfoParams structure
1178 * @halHandle: Pointer to HAL handle
1179 * @pResult: Pointer to tScanResultHandle
1180 * @sap_ctx: Context of the SAP
1181 *
1182 * Main function for computing the weight of each channel in the
1183 * spectrum based on the RSSI value of the BSSes on the channel
1184 * and number of BSS
1185 */
1186static void sap_compute_spect_weight(tSapChSelSpectInfo *pSpectInfoParams,
1187 tHalHandle halHandle,
1188 tScanResultHandle pResult,
1189 ptSapContext sap_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001190{
1191 int8_t rssi = 0;
1192 uint8_t chn_num = 0;
1193 uint8_t channel_id = 0;
1194
1195 tCsrScanResultInfo *pScanResult;
1196 tSapSpectChInfo *pSpectCh = pSpectInfoParams->pSpectCh;
1197 uint32_t operatingBand;
1198 uint16_t channelWidth;
1199 uint16_t secondaryChannelOffset;
1200 uint16_t centerFreq;
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001201 uint16_t centerFreq_2 = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001202 uint16_t vhtSupport;
1203 uint32_t ieLen = 0;
1204 tSirProbeRespBeacon *pBeaconStruct;
1205 tpAniSirGlobal pMac = (tpAniSirGlobal) halHandle;
Liangwei Dong71ed6502016-10-20 03:40:45 -04001206 tSapSpectChInfo *spectch_start = pSpectInfoParams->pSpectCh;
1207 tSapSpectChInfo *spectch_end = pSpectInfoParams->pSpectCh +
1208 pSpectInfoParams->numSpectChans;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001209
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301210 pBeaconStruct = qdf_mem_malloc(sizeof(tSirProbeRespBeacon));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001211 if (NULL == pBeaconStruct) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301212 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Kaushik, Sushantee3ed032016-08-04 16:40:46 +05301213 "Unable to allocate memory in sap_compute_spect_weight");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001214 return;
1215 }
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301216 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001217 "In %s, Computing spectral weight", __func__);
1218
1219 /**
1220 * Soft AP specific channel weight calculation using DFS formula
1221 */
1222 SET_ACS_BAND(operatingBand, sap_ctx);
1223
1224 pScanResult = sme_scan_result_get_first(halHandle, pResult);
1225
1226 while (pScanResult) {
1227 pSpectCh = pSpectInfoParams->pSpectCh;
1228 /* Defining the default values, so that any value will hold the default values */
1229 channelWidth = eHT_CHANNEL_WIDTH_20MHZ;
1230 secondaryChannelOffset = PHY_SINGLE_CHANNEL_CENTERED;
1231 vhtSupport = 0;
1232 centerFreq = 0;
1233
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001234
Yingying Tang22facc12016-10-20 17:43:59 +08001235 ieLen = GET_IE_LEN_IN_BSS(
1236 pScanResult->BssDescriptor.length);
1237 qdf_mem_set((uint8_t *) pBeaconStruct,
1238 sizeof(tSirProbeRespBeacon), 0);
1239
1240
1241 if ((sir_parse_beacon_ie
1242 (pMac, pBeaconStruct, (uint8_t *)
1243 (pScanResult->BssDescriptor.ieFields),
1244 ieLen)) == eSIR_SUCCESS)
1245 sap_upd_chan_spec_params(
1246 pBeaconStruct,
1247 &channelWidth,
1248 &secondaryChannelOffset,
1249 &vhtSupport, &centerFreq,
1250 &centerFreq_2);
1251
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001252 /* Processing for each tCsrScanResultInfo in the tCsrScanResult DLink list */
1253 for (chn_num = 0; chn_num < pSpectInfoParams->numSpectChans;
1254 chn_num++) {
1255
1256 /*
1257 * if the Beacon has channel ID, use it other wise we will
1258 * rely on the channelIdSelf
1259 */
1260 if (pScanResult->BssDescriptor.channelId == 0)
1261 channel_id =
1262 pScanResult->BssDescriptor.channelIdSelf;
1263 else
1264 channel_id =
1265 pScanResult->BssDescriptor.channelId;
1266
1267 if (pSpectCh && (channel_id == pSpectCh->chNum)) {
1268 if (pSpectCh->rssiAgr <
1269 pScanResult->BssDescriptor.rssi)
1270 pSpectCh->rssiAgr =
1271 pScanResult->BssDescriptor.rssi;
1272
1273 ++pSpectCh->bssCount; /* Increment the count of BSS */
1274
1275 /*
1276 * Connsidering the Extension Channel
1277 * only in a channels
1278 */
1279 switch (operatingBand) {
1280 case eCSR_DOT11_MODE_11a:
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);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001289 break;
1290
1291 case eCSR_DOT11_MODE_11g:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001292 sap_interference_rssi_count(pSpectCh,
1293 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001294 break;
1295
1296 case eCSR_DOT11_MODE_abg:
1297 sap_interference_rssi_count_5G(
1298 pSpectCh, channelWidth,
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001299 secondaryChannelOffset,
1300 centerFreq,
1301 centerFreq_2,
Liangwei Dong71ed6502016-10-20 03:40:45 -04001302 channel_id,
1303 spectch_start,
1304 spectch_end);
1305 sap_interference_rssi_count(pSpectCh,
1306 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001307 break;
1308 }
1309
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301310 QDF_TRACE(QDF_MODULE_ID_SAP,
1311 QDF_TRACE_LEVEL_INFO_HIGH,
Kaushik, Sushantee3ed032016-08-04 16:40:46 +05301312 "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 -08001313 __func__,
1314 pScanResult->BssDescriptor.
1315 channelIdSelf,
1316 pScanResult->BssDescriptor.channelId,
1317 pScanResult->BssDescriptor.rssi,
1318 pSpectCh->bssCount, pScanResult,
1319 pSpectCh->channelWidth,
1320 secondaryChannelOffset, centerFreq);
1321 pSpectCh++;
1322 break;
1323 } else {
1324 pSpectCh++;
1325 }
1326 }
1327
1328 pScanResult = sme_scan_result_get_next(halHandle, pResult);
1329 }
1330
1331 /* Calculate the weights for all channels in the spectrum pSpectCh */
1332 pSpectCh = pSpectInfoParams->pSpectCh;
1333
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301334 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001335 "In %s, Spectrum Channels Weight", __func__);
1336
1337 for (chn_num = 0; chn_num < (pSpectInfoParams->numSpectChans);
1338 chn_num++) {
1339
1340 /*
1341 rssi : Maximum received signal strength among all BSS on that channel
1342 bssCount : Number of BSS on that channel
1343 */
1344
1345 rssi = (int8_t) pSpectCh->rssiAgr;
1346 if (ch_in_pcl(sap_ctx, chn_num))
1347 rssi -= PCL_RSSI_DISCOUNT;
1348
1349 pSpectCh->weight =
1350 SAPDFS_NORMALISE_1000 * sapweight_rssi_count(rssi,
1351 pSpectCh->
1352 bssCount);
1353 pSpectCh->weight_copy = pSpectCh->weight;
1354
1355 /* ------ Debug Info ------ */
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301356 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001357 "In %s, Chan=%d Weight= %d rssiAgr=%d bssCount=%d",
1358 __func__, pSpectCh->chNum, pSpectCh->weight,
1359 pSpectCh->rssiAgr, pSpectCh->bssCount);
1360 /* ------ Debug Info ------ */
1361 pSpectCh++;
1362 }
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301363 qdf_mem_free(pBeaconStruct);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001364}
1365
1366/*==========================================================================
1367 FUNCTION sap_chan_sel_exit
1368
1369 DESCRIPTION
1370 Exit function for free out the allocated memory, to be called
1371 at the end of the dfsSelectChannel function
1372
1373 DEPENDENCIES
1374 NA.
1375
1376 PARAMETERS
1377
1378 IN
1379 pSpectInfoParams : Pointer to the tSapChSelSpectInfo structure
1380
1381 RETURN VALUE
1382 void : NULL
1383
1384 SIDE EFFECTS
1385 ============================================================================*/
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001386static void sap_chan_sel_exit(tSapChSelSpectInfo *pSpectInfoParams)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001387{
1388 /* Free all the allocated memory */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301389 qdf_mem_free(pSpectInfoParams->pSpectCh);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001390}
1391
1392/*==========================================================================
1393 FUNCTION sap_sort_chl_weight
1394
1395 DESCRIPTION
1396 Funtion to sort the channels with the least weight first for 20MHz channels
1397
1398 DEPENDENCIES
1399 NA.
1400
1401 PARAMETERS
1402
1403 IN
1404 pSpectInfoParams : Pointer to the tSapChSelSpectInfo structure
1405
1406 RETURN VALUE
1407 void : NULL
1408
1409 SIDE EFFECTS
1410 ============================================================================*/
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001411static void sap_sort_chl_weight(tSapChSelSpectInfo *pSpectInfoParams)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001412{
1413 tSapSpectChInfo temp;
1414
1415 tSapSpectChInfo *pSpectCh = NULL;
1416 uint32_t i = 0, j = 0, minWeightIndex = 0;
1417
1418 pSpectCh = pSpectInfoParams->pSpectCh;
1419 for (i = 0; i < pSpectInfoParams->numSpectChans; i++) {
1420 minWeightIndex = i;
1421 for (j = i + 1; j < pSpectInfoParams->numSpectChans; j++) {
1422 if (pSpectCh[j].weight <
1423 pSpectCh[minWeightIndex].weight) {
1424 minWeightIndex = j;
1425 }
1426 }
1427 if (minWeightIndex != i) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301428 qdf_mem_copy(&temp, &pSpectCh[minWeightIndex],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001429 sizeof(*pSpectCh));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301430 qdf_mem_copy(&pSpectCh[minWeightIndex], &pSpectCh[i],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001431 sizeof(*pSpectCh));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301432 qdf_mem_copy(&pSpectCh[i], &temp, sizeof(*pSpectCh));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001433 }
1434 }
1435}
1436
1437/**
bingse2782382017-03-23 10:34:52 +08001438 * set_ht80_chl_bit() - to set availabe channel to ht80 channel bitmap
1439 * @channel_bitmap: Pointer to the chan_bonding_bitmap structure
1440 * @spect_info_params: Pointer to the tSapChSelSpectInfo structure
1441 *
1442 * Return: none
1443 */
1444static void set_ht80_chl_bit(chan_bonding_bitmap *channel_bitmap,
1445 tSapChSelSpectInfo *spec_info_params)
1446{
1447 uint8_t i, j;
1448 tSapSpectChInfo *spec_info;
1449 int start_channel = 0;
1450
1451 channel_bitmap->chanBondingSet[0].startChannel =
1452 acs_ht80_channels[0].chStartNum;
1453 channel_bitmap->chanBondingSet[1].startChannel =
1454 acs_ht80_channels[1].chStartNum;
1455 channel_bitmap->chanBondingSet[2].startChannel =
1456 acs_ht80_channels[2].chStartNum;
1457 channel_bitmap->chanBondingSet[3].startChannel =
1458 acs_ht80_channels[3].chStartNum;
1459 channel_bitmap->chanBondingSet[4].startChannel =
1460 acs_ht80_channels[4].chStartNum;
1461 channel_bitmap->chanBondingSet[5].startChannel =
1462 acs_ht80_channels[5].chStartNum;
1463
1464 spec_info = spec_info_params->pSpectCh;
1465 for (j = 0; j < spec_info_params->numSpectChans; j++) {
1466 for (i = 0; i < MAX_80MHZ_BANDS; i++) {
1467 start_channel =
1468 channel_bitmap->chanBondingSet[i].startChannel;
1469 if (spec_info[j].chNum >= start_channel &&
1470 (spec_info[j].chNum <= start_channel + 12)) {
1471 channel_bitmap->chanBondingSet[i].channelMap |=
1472 1 << ((spec_info[j].chNum -
1473 start_channel)/4);
1474 break;
1475 }
1476 }
1477 }
1478}
1479
1480/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001481 * sap_sort_chl_weight_ht80() - to sort the channels with the least weight
1482 * @pSpectInfoParams: Pointer to the tSapChSelSpectInfo structure
1483 *
1484 * Funtion to sort the channels with the least weight first for HT80 channels
1485 *
1486 * Return: none
1487 */
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001488static void sap_sort_chl_weight_ht80(tSapChSelSpectInfo *pSpectInfoParams)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001489{
1490 uint8_t i, j, n;
1491 tSapSpectChInfo *pSpectInfo;
1492 uint8_t minIdx;
bingse2782382017-03-23 10:34:52 +08001493 int start_channel = 0;
1494 chan_bonding_bitmap *channel_bitmap;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001495
bingse2782382017-03-23 10:34:52 +08001496 channel_bitmap = qdf_mem_malloc(sizeof(chan_bonding_bitmap));
1497 if (NULL == channel_bitmap) {
1498 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG,
1499 "%s: Failed to allocate memory", __func__);
1500 return;
1501 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001502 pSpectInfo = pSpectInfoParams->pSpectCh;
1503 /* for each HT80 channel, calculate the combined weight of the
1504 four 20MHz weight */
1505 for (i = 0; i < ARRAY_SIZE(acs_ht80_channels); i++) {
1506 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
1507 if (pSpectInfo[j].chNum ==
1508 acs_ht80_channels[i].chStartNum)
1509 break;
1510 }
1511 if (j == pSpectInfoParams->numSpectChans)
1512 continue;
1513
1514 if (!(((pSpectInfo[j].chNum + 4) == pSpectInfo[j + 1].chNum) &&
1515 ((pSpectInfo[j].chNum + 8) ==
1516 pSpectInfo[j + 2].chNum) &&
1517 ((pSpectInfo[j].chNum + 12) ==
1518 pSpectInfo[j + 3].chNum))) {
1519 /*
1520 * some channels does not exist in pSectInfo array,
1521 * skip this channel and those in the same HT80 width
1522 */
1523 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 4;
1524 if ((pSpectInfo[j].chNum + 4) ==
1525 pSpectInfo[j + 1].chNum)
1526 pSpectInfo[j + 1].weight =
1527 SAP_ACS_WEIGHT_MAX * 4;
1528 if ((pSpectInfo[j].chNum + 8) ==
1529 pSpectInfo[j + 2].chNum)
1530 pSpectInfo[j + 2].weight =
1531 SAP_ACS_WEIGHT_MAX * 4;
1532 if ((pSpectInfo[j].chNum + 12) ==
1533 pSpectInfo[j + 3].chNum)
1534 pSpectInfo[j + 3].weight =
1535 SAP_ACS_WEIGHT_MAX * 4;
1536 continue;
1537 }
1538 /*found the channel, add the 4 adjacent channels' weight */
1539 acs_ht80_channels[i].weight = pSpectInfo[j].weight +
1540 pSpectInfo[j + 1].weight + pSpectInfo[j + 2].weight +
1541 pSpectInfo[j + 3].weight;
1542 /* find best channel among 4 channels as the primary channel */
1543 if ((pSpectInfo[j].weight + pSpectInfo[j + 1].weight) <
1544 (pSpectInfo[j + 2].weight + pSpectInfo[j + 3].weight)) {
1545 /* lower 2 channels are better choice */
1546 if (pSpectInfo[j].weight < pSpectInfo[j + 1].weight)
1547 minIdx = 0;
1548 else
1549 minIdx = 1;
1550 } else if (pSpectInfo[j + 2].weight <=
1551 pSpectInfo[j + 3].weight) {
1552 /* upper 2 channels are better choice */
1553 minIdx = 2;
1554 } else {
1555 minIdx = 3;
1556 }
1557
1558 /*
1559 * set all 4 channels to max value first, then reset the
1560 * best channel as the selected primary channel, update its
1561 * weightage with the combined weight value
1562 */
1563 for (n = 0; n < 4; n++)
1564 pSpectInfo[j + n].weight = SAP_ACS_WEIGHT_MAX * 4;
1565
1566 pSpectInfo[j + minIdx].weight = acs_ht80_channels[i].weight;
1567 }
1568
bingse2782382017-03-23 10:34:52 +08001569 /*
1570 * mark the weight of the channel that can't satisfy 80MHZ
1571 * as max value, so that it will be sorted to the bottom
1572 */
1573 set_ht80_chl_bit(channel_bitmap, pSpectInfoParams);
1574 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
1575 for (i = 0; i < MAX_80MHZ_BANDS; i++) {
1576 start_channel =
1577 channel_bitmap->chanBondingSet[i].startChannel;
1578 if (pSpectInfo[j].chNum >= start_channel &&
1579 (pSpectInfo[j].chNum <=
1580 start_channel + 12) &&
1581 channel_bitmap->chanBondingSet[i].channelMap !=
1582 SAP_80MHZ_MASK)
1583 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 4;
1584 }
1585 }
1586
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001587 pSpectInfo = pSpectInfoParams->pSpectCh;
1588 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
1589 if (CHANNEL_165 == pSpectInfo[j].chNum) {
1590 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 4;
1591 break;
1592 }
1593 }
1594
Manishekar Chandrasekaran44e334f2016-05-30 16:42:50 +05301595 sap_sort_chl_weight(pSpectInfoParams);
1596
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001597 pSpectInfo = pSpectInfoParams->pSpectCh;
1598 for (j = 0; j < (pSpectInfoParams->numSpectChans); j++) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301599 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001600 FL("Channel=%d Weight= %d rssi=%d bssCount=%d"),
1601 pSpectInfo->chNum, pSpectInfo->weight,
1602 pSpectInfo->rssiAgr, pSpectInfo->bssCount);
1603 pSpectInfo++;
1604 }
bingse2782382017-03-23 10:34:52 +08001605 qdf_mem_free(channel_bitmap);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001606}
1607
1608/**
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001609 * sap_sort_chl_weight_vht160() - to sort the channels with the least weight
1610 * @pSpectInfoParams: Pointer to the tSapChSelSpectInfo structure
1611 *
1612 * Funtion to sort the channels with the least weight first for VHT160 channels
1613 *
1614 * Return: none
1615 */
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001616static void sap_sort_chl_weight_vht160(tSapChSelSpectInfo *pSpectInfoParams)
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001617{
1618 uint8_t i, j, n, idx;
1619 tSapSpectChInfo *pSpectInfo;
1620 uint8_t minIdx;
1621
1622 pSpectInfo = pSpectInfoParams->pSpectCh;
1623 /* for each VHT160 channel, calculate the combined weight of the
1624 8 20MHz weight */
1625 for (i = 0; i < ARRAY_SIZE(acs_vht160_channels); i++) {
1626 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
1627 if (pSpectInfo[j].chNum ==
1628 acs_vht160_channels[i].chStartNum)
1629 break;
1630 }
1631 if (j == pSpectInfoParams->numSpectChans)
1632 continue;
1633
1634 if (!(((pSpectInfo[j].chNum + 4) == pSpectInfo[j + 1].chNum) &&
1635 ((pSpectInfo[j].chNum + 8) ==
1636 pSpectInfo[j + 2].chNum) &&
1637 ((pSpectInfo[j].chNum + 12) ==
1638 pSpectInfo[j + 3].chNum) &&
1639 ((pSpectInfo[j].chNum + 16) ==
1640 pSpectInfo[j + 4].chNum) &&
1641 ((pSpectInfo[j].chNum + 20) ==
1642 pSpectInfo[j + 5].chNum) &&
1643 ((pSpectInfo[j].chNum + 24) ==
1644 pSpectInfo[j + 6].chNum) &&
1645 ((pSpectInfo[j].chNum + 28) ==
1646 pSpectInfo[j + 7].chNum))) {
1647 /*
1648 * some channels does not exist in pSectInfo array,
1649 * skip this channel and those in the same VHT160 width
1650 */
1651 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 8;
1652 if ((pSpectInfo[j].chNum + 4) ==
1653 pSpectInfo[j + 1].chNum)
1654 pSpectInfo[j + 1].weight =
1655 SAP_ACS_WEIGHT_MAX * 8;
1656 if ((pSpectInfo[j].chNum + 8) ==
1657 pSpectInfo[j + 2].chNum)
1658 pSpectInfo[j + 2].weight =
1659 SAP_ACS_WEIGHT_MAX * 8;
1660 if ((pSpectInfo[j].chNum + 12) ==
1661 pSpectInfo[j + 3].chNum)
1662 pSpectInfo[j + 3].weight =
1663 SAP_ACS_WEIGHT_MAX * 8;
1664 if ((pSpectInfo[j].chNum + 16) ==
1665 pSpectInfo[j + 4].chNum)
1666 pSpectInfo[j + 4].weight =
1667 SAP_ACS_WEIGHT_MAX * 8;
1668 if ((pSpectInfo[j].chNum + 20) ==
1669 pSpectInfo[j + 5].chNum)
1670 pSpectInfo[j + 5].weight =
1671 SAP_ACS_WEIGHT_MAX * 8;
1672 if ((pSpectInfo[j].chNum + 24) ==
1673 pSpectInfo[j + 6].chNum)
1674 pSpectInfo[j + 6].weight =
1675 SAP_ACS_WEIGHT_MAX * 8;
1676 if ((pSpectInfo[j].chNum + 28) ==
1677 pSpectInfo[j + 7].chNum)
1678 pSpectInfo[j + 7].weight =
1679 SAP_ACS_WEIGHT_MAX * 8;
1680 continue;
1681 }
1682 /*found the channel, add the 7 adjacent channels' weight */
1683 acs_vht160_channels[i].weight = pSpectInfo[j].weight +
1684 pSpectInfo[j + 1].weight + pSpectInfo[j + 2].weight +
1685 pSpectInfo[j + 3].weight + pSpectInfo[j + 4].weight +
1686 pSpectInfo[j + 5].weight + pSpectInfo[j + 6].weight +
1687 pSpectInfo[j + 7].weight;
1688
1689 /* find best channel among 8 channels as the primary channel */
1690 if ((pSpectInfo[j].weight + pSpectInfo[j + 1].weight +
1691 pSpectInfo[j + 2].weight + pSpectInfo[j + 3].weight) >
1692 (pSpectInfo[j + 4].weight + pSpectInfo[j + 5].weight +
1693 pSpectInfo[j + 6].weight + pSpectInfo[j + 7].weight))
1694 idx = 4;
1695 else
1696 idx = 0;
1697 /* find best channel among 4 channels as the primary channel */
1698 if ((pSpectInfo[j + idx].weight +
1699 pSpectInfo[j + idx + 1].weight) <
1700 (pSpectInfo[j + idx + 2].weight +
1701 pSpectInfo[j + idx + 3].weight)) {
1702 /* lower 2 channels are better choice */
1703 if (pSpectInfo[j + idx].weight <
1704 pSpectInfo[j + idx + 1].weight)
1705 minIdx = 0 + idx;
1706 else
1707 minIdx = 1 + idx;
1708 } else if (pSpectInfo[j + idx + 2].weight <=
1709 pSpectInfo[j + idx + 3].weight) {
1710 /* upper 2 channels are better choice */
1711 minIdx = 2 + idx;
1712 } else {
1713 minIdx = 3 + idx;
1714 }
1715
1716 /*
1717 * set all 8 channels to max value first, then reset the
1718 * best channel as the selected primary channel, update its
1719 * weightage with the combined weight value
1720 */
1721 for (n = 0; n < 8; n++)
1722 pSpectInfo[j + n].weight = SAP_ACS_WEIGHT_MAX * 8;
1723
1724 pSpectInfo[j + minIdx].weight = acs_vht160_channels[i].weight;
1725 }
1726
1727 pSpectInfo = pSpectInfoParams->pSpectCh;
1728 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
1729 if (CHANNEL_165 == pSpectInfo[j].chNum) {
1730 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 8;
1731 break;
1732 }
1733 }
1734
Manishekar Chandrasekaran44e334f2016-05-30 16:42:50 +05301735 sap_sort_chl_weight(pSpectInfoParams);
1736
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001737 pSpectInfo = pSpectInfoParams->pSpectCh;
1738 for (j = 0; j < (pSpectInfoParams->numSpectChans); j++) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301739 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001740 FL("Channel=%d Weight= %d rssi=%d bssCount=%d"),
1741 pSpectInfo->chNum, pSpectInfo->weight,
1742 pSpectInfo->rssiAgr, pSpectInfo->bssCount);
1743 pSpectInfo++;
1744 }
1745}
1746
1747/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001748 * sap_sort_chl_weight_ht40_24_g() - to sort channel with the least weight
1749 * @pSpectInfoParams: Pointer to the tSapChSelSpectInfo structure
1750 *
1751 * Funtion to sort the channels with the least weight first for HT40 channels
1752 *
1753 * Return: none
1754 */
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07001755static void sap_sort_chl_weight_ht40_24_g(tSapChSelSpectInfo *pSpectInfoParams,
1756 v_REGDOMAIN_t domain)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001757{
1758 uint8_t i, j;
1759 tSapSpectChInfo *pSpectInfo;
1760 uint32_t tmpWeight1, tmpWeight2;
bingse2782382017-03-23 10:34:52 +08001761 uint32_t ht40plus2gendch = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001762
1763 pSpectInfo = pSpectInfoParams->pSpectCh;
1764 /*
1765 * for each HT40 channel, calculate the combined weight of the
1766 * two 20MHz weight
1767 */
1768 for (i = 0; i < ARRAY_SIZE(acs_ht40_channels24_g); i++) {
1769 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
1770 if (pSpectInfo[j].chNum ==
1771 acs_ht40_channels24_g[i].chStartNum)
1772 break;
1773 }
1774 if (j == pSpectInfoParams->numSpectChans)
1775 continue;
1776
1777 if (!((pSpectInfo[j].chNum + 4) == pSpectInfo[j + 4].chNum)) {
1778 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2;
1779 continue;
1780 }
1781 /*
1782 * check if there is another channel combination possiblity
1783 * e.g., {1, 5} & {5, 9}
1784 */
1785 if ((pSpectInfo[j + 4].chNum + 4) == pSpectInfo[j + 8].chNum) {
1786 /* need to compare two channel pairs */
1787 tmpWeight1 = pSpectInfo[j].weight +
1788 pSpectInfo[j + 4].weight;
1789 tmpWeight2 = pSpectInfo[j + 4].weight +
1790 pSpectInfo[j + 8].weight;
1791 if (tmpWeight1 <= tmpWeight2) {
1792 if (pSpectInfo[j].weight <=
1793 pSpectInfo[j + 4].weight) {
1794 pSpectInfo[j].weight =
1795 tmpWeight1;
1796 pSpectInfo[j + 4].weight =
1797 SAP_ACS_WEIGHT_MAX * 2;
1798 pSpectInfo[j + 8].weight =
1799 SAP_ACS_WEIGHT_MAX * 2;
1800 } else {
1801 pSpectInfo[j + 4].weight =
1802 tmpWeight1;
1803 /* for secondary channel selection */
1804 pSpectInfo[j].weight =
1805 SAP_ACS_WEIGHT_MAX * 2
1806 - 1;
1807 pSpectInfo[j + 8].weight =
1808 SAP_ACS_WEIGHT_MAX * 2;
1809 }
1810 } else {
1811 if (pSpectInfo[j + 4].weight <=
1812 pSpectInfo[j + 8].weight) {
1813 pSpectInfo[j + 4].weight =
1814 tmpWeight2;
1815 pSpectInfo[j].weight =
1816 SAP_ACS_WEIGHT_MAX * 2;
1817 /* for secondary channel selection */
1818 pSpectInfo[j + 8].weight =
1819 SAP_ACS_WEIGHT_MAX * 2
1820 - 1;
1821 } else {
1822 pSpectInfo[j + 8].weight =
1823 tmpWeight2;
1824 pSpectInfo[j].weight =
1825 SAP_ACS_WEIGHT_MAX * 2;
1826 pSpectInfo[j + 4].weight =
1827 SAP_ACS_WEIGHT_MAX * 2;
1828 }
1829 }
1830 } else {
1831 tmpWeight1 = pSpectInfo[j].weight +
1832 pSpectInfo[j + 4].weight;
1833 if (pSpectInfo[j].weight <=
1834 pSpectInfo[j + 4].weight) {
1835 pSpectInfo[j].weight = tmpWeight1;
1836 pSpectInfo[j + 4].weight =
1837 SAP_ACS_WEIGHT_MAX * 2;
1838 } else {
1839 pSpectInfo[j + 4].weight = tmpWeight1;
1840 pSpectInfo[j].weight =
1841 SAP_ACS_WEIGHT_MAX * 2;
1842 }
1843 }
1844 }
bingse2782382017-03-23 10:34:52 +08001845 /*
1846 * Every channel should be checked. Add the check for the omissive
1847 * channel. Mark the channel whose combination can't satisfy 40MHZ
1848 * as max value, so that it will be sorted to the bottom.
1849 */
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07001850 if (REGDOMAIN_FCC == domain)
bingse2782382017-03-23 10:34:52 +08001851 ht40plus2gendch = HT40PLUS_2G_FCC_CH_END;
1852 else
1853 ht40plus2gendch = HT40PLUS_2G_EURJAP_CH_END;
1854 for (i = HT40MINUS_2G_CH_START; i <= ht40plus2gendch; i++) {
1855 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
1856 if (pSpectInfo[j].chNum == i &&
1857 ((pSpectInfo[j].chNum + 4) !=
1858 pSpectInfo[j+4].chNum) &&
1859 ((pSpectInfo[j].chNum - 4) !=
1860 pSpectInfo[j-4].chNum))
1861 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2;
1862 }
1863 }
1864 for (i = ht40plus2gendch + 1; i <= HT40MINUS_2G_CH_END; i++) {
1865 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
1866 if (pSpectInfo[j].chNum == i &&
1867 (pSpectInfo[j].chNum - 4) !=
1868 pSpectInfo[j-4].chNum)
1869 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2;
1870 }
1871 }
Manishekar Chandrasekaran44e334f2016-05-30 16:42:50 +05301872 sap_sort_chl_weight(pSpectInfoParams);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001873}
1874
1875/*==========================================================================
1876 FUNCTION sap_sort_chl_weight_ht40_5_g
1877
1878 DESCRIPTION
1879 Funtion to sort the channels with the least weight first for HT40 channels
1880
1881 DEPENDENCIES
1882 NA.
1883
1884 PARAMETERS
1885
1886 IN
1887 pSpectInfoParams : Pointer to the tSapChSelSpectInfo structure
1888
1889 RETURN VALUE
1890 void : NULL
1891
1892 SIDE EFFECTS
1893 ============================================================================*/
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001894static void sap_sort_chl_weight_ht40_5_g(tSapChSelSpectInfo *pSpectInfoParams)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001895{
1896 uint8_t i, j;
1897 tSapSpectChInfo *pSpectInfo;
1898
1899 pSpectInfo = pSpectInfoParams->pSpectCh;
1900 /*for each HT40 channel, calculate the combined weight of the
1901 two 20MHz weight */
1902 for (i = 0; i < ARRAY_SIZE(acs_ht40_channels5_g); i++) {
1903 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
1904 if (pSpectInfo[j].chNum ==
1905 acs_ht40_channels5_g[i].chStartNum)
1906 break;
1907 }
1908 if (j == pSpectInfoParams->numSpectChans)
1909 continue;
1910
1911 /* found the channel, add the two adjacent channels' weight */
1912 if ((pSpectInfo[j].chNum + 4) == pSpectInfo[j + 1].chNum) {
1913 acs_ht40_channels5_g[i].weight = pSpectInfo[j].weight +
1914 pSpectInfo[j + 1].weight;
1915 /* select better of the adjact channel as the primary channel */
1916 if (pSpectInfo[j].weight <= pSpectInfo[j + 1].weight) {
1917 pSpectInfo[j].weight =
1918 acs_ht40_channels5_g[i].weight;
1919 /* mark the adjacent channel's weight as max value so
1920 that it will be sorted to the bottom */
1921 pSpectInfo[j + 1].weight =
1922 SAP_ACS_WEIGHT_MAX * 2;
1923 } else {
1924 pSpectInfo[j + 1].weight =
1925 acs_ht40_channels5_g[i].weight;
1926 /* mark the adjacent channel's weight as max value so
1927 that it will be sorted to the bottom */
1928 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2;
1929 }
1930
1931 } else
1932 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2;
1933 }
1934
bingse2782382017-03-23 10:34:52 +08001935 /*
1936 *Every channel should be checked. Add the check for the omissive
1937 * channel. Mark the channel whose combination can't satisfy 40MHZ
1938 * as max value, so that it will be sorted to the bottom
1939 */
1940 for (j = 1; j < pSpectInfoParams->numSpectChans; j++) {
1941 for (i = 0; i < ARRAY_SIZE(acs_ht40_channels5_g); i++) {
1942 if (pSpectInfo[j].chNum ==
1943 (acs_ht40_channels5_g[i].chStartNum +
1944 4) &&
1945 pSpectInfo[j - 1].chNum !=
1946 acs_ht40_channels5_g[i].chStartNum) {
1947 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2;
1948 break;
1949 }
1950 }
1951 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001952 /* avoid channel 165 by setting its weight to max */
1953 pSpectInfo = pSpectInfoParams->pSpectCh;
1954 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
1955 if (CHANNEL_165 == pSpectInfo[j].chNum) {
1956 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2;
1957 break;
1958 }
1959 }
1960
1961 pSpectInfo = pSpectInfoParams->pSpectCh;
1962 for (j = 0; j < (pSpectInfoParams->numSpectChans); j++) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301963 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001964 "In %s, Channel=%d Weight= %d rssi=%d bssCount=%d",
1965 __func__, pSpectInfo->chNum, pSpectInfo->weight,
1966 pSpectInfo->rssiAgr, pSpectInfo->bssCount);
1967 pSpectInfo++;
1968 }
1969
1970 sap_sort_chl_weight(pSpectInfoParams);
1971}
1972
1973/*==========================================================================
1974 FUNCTION sap_sort_chl_weight_all
1975
1976 DESCRIPTION
1977 Funtion to sort the channels with the least weight first
1978
1979 DEPENDENCIES
1980 NA.
1981
1982 PARAMETERS
1983
1984 IN
1985 ptSapContext : Pointer to the ptSapContext structure
1986 pSpectInfoParams : Pointer to the tSapChSelSpectInfo structure
1987
1988 RETURN VALUE
1989 void : NULL
1990
1991 SIDE EFFECTS
1992 ============================================================================*/
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001993static void sap_sort_chl_weight_all(ptSapContext pSapCtx,
1994 tSapChSelSpectInfo *pSpectInfoParams,
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07001995 uint32_t operatingBand,
1996 v_REGDOMAIN_t domain)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001997{
1998 tSapSpectChInfo *pSpectCh = NULL;
1999 uint32_t j = 0;
2000#ifndef SOFTAP_CHANNEL_RANGE
2001 uint32_t i = 0;
2002#endif
2003
2004 pSpectCh = pSpectInfoParams->pSpectCh;
2005#ifdef SOFTAP_CHANNEL_RANGE
2006
2007 switch (pSapCtx->acs_cfg->ch_width) {
2008 case CH_WIDTH_40MHZ:
2009 if (eCSR_DOT11_MODE_11g == operatingBand)
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002010 sap_sort_chl_weight_ht40_24_g(pSpectInfoParams, domain);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002011 else if (eCSR_DOT11_MODE_11a == operatingBand)
2012 sap_sort_chl_weight_ht40_5_g(pSpectInfoParams);
2013 else {
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002014 sap_sort_chl_weight_ht40_24_g(pSpectInfoParams, domain);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002015 sap_sort_chl_weight_ht40_5_g(pSpectInfoParams);
2016 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002017 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002018 case CH_WIDTH_80MHZ:
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07002019 case CH_WIDTH_80P80MHZ:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002020 sap_sort_chl_weight_ht80(pSpectInfoParams);
2021 break;
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07002022 case CH_WIDTH_160MHZ:
2023 sap_sort_chl_weight_vht160(pSpectInfoParams);
2024 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002025 case CH_WIDTH_20MHZ:
2026 default:
2027 /* Sorting the channels as per weights as 20MHz channels */
2028 sap_sort_chl_weight(pSpectInfoParams);
2029 }
2030
2031#else
2032 /* Sorting the channels as per weights */
2033 for (i = 0; i < SPECT_24GHZ_CH_COUNT; i++) {
2034 minWeightIndex = i;
2035 for (j = i + 1; j < SPECT_24GHZ_CH_COUNT; j++) {
2036 if (pSpectCh[j].weight <
2037 pSpectCh[minWeightIndex].weight) {
2038 minWeightIndex = j;
2039 }
2040 }
2041 if (minWeightIndex != i) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302042 qdf_mem_copy(&temp, &pSpectCh[minWeightIndex],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002043 sizeof(*pSpectCh));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302044 qdf_mem_copy(&pSpectCh[minWeightIndex], &pSpectCh[i],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002045 sizeof(*pSpectCh));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302046 qdf_mem_copy(&pSpectCh[i], &temp, sizeof(*pSpectCh));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002047 }
2048 }
2049#endif
2050
2051 /* For testing */
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302052 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002053 "In %s, Sorted Spectrum Channels Weight", __func__);
2054 pSpectCh = pSpectInfoParams->pSpectCh;
2055 for (j = 0; j < (pSpectInfoParams->numSpectChans); j++) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302056 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002057 "In %s, Channel=%d Weight= %d rssi=%d bssCount=%d",
2058 __func__, pSpectCh->chNum, pSpectCh->weight,
2059 pSpectCh->rssiAgr, pSpectCh->bssCount);
2060 pSpectCh++;
2061 }
2062
2063}
2064
2065/*==========================================================================
2066 FUNCTION sap_filter_over_lap_ch
2067
2068 DESCRIPTION
2069 return true if ch is acceptable.
2070 This function will decide if we will filter over lap channel or not.
2071
2072 DEPENDENCIES
2073 shall called after ap start.
2074
2075 PARAMETERS
2076
2077 IN
2078 pSapCtx : Pointer to ptSapContext.
2079 chNum : Filter channel number.
2080
2081 RETURN VALUE
2082 bool : true if channel is accepted.
2083
2084 SIDE EFFECTS
2085 ============================================================================*/
Jeff Johnson464f7ea2016-10-07 10:21:26 -07002086static bool sap_filter_over_lap_ch(ptSapContext pSapCtx, uint16_t chNum)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002087{
2088 if (pSapCtx->enableOverLapCh)
Srinivas Girigowda74a66d62017-06-21 23:28:25 -07002089 return true;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002090 else if ((chNum == CHANNEL_1) ||
2091 (chNum == CHANNEL_6) || (chNum == CHANNEL_11))
Srinivas Girigowda74a66d62017-06-21 23:28:25 -07002092 return true;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002093
Srinivas Girigowda74a66d62017-06-21 23:28:25 -07002094 return false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002095}
2096
Dustin Brown0ce56d32016-10-17 16:18:03 -07002097#ifdef FEATURE_WLAN_CH_AVOID
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002098/**
2099 * sap_select_channel_no_scan_result() - select SAP channel when no scan results
2100 * are available.
2101 * @sap_ctx: Sap context
2102 *
2103 * Returns: channel number if success, 0 otherwise
2104 */
Kondabattini, Ganesh13bb4b12016-09-04 16:16:53 +05302105static uint8_t sap_select_channel_no_scan_result(tHalHandle hal,
Dustin Brown0ce56d32016-10-17 16:18:03 -07002106 ptSapContext sap_ctx)
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002107{
Mohit Khanna841044f2016-03-25 16:16:24 -07002108 enum channel_state ch_type;
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002109 uint8_t i, first_safe_ch_in_range = SAP_CHANNEL_NOT_SELECTED;
Kondabattini, Ganesh13bb4b12016-09-04 16:16:53 +05302110 uint32_t dfs_master_cap_enabled;
Dustin Brown0ce56d32016-10-17 16:18:03 -07002111 uint32_t start_ch_num = sap_ctx->acs_cfg->start_ch;
2112 uint32_t end_ch_num = sap_ctx->acs_cfg->end_ch;
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002113 tpAniSirGlobal mac_ctx = NULL;
2114
2115 mac_ctx = PMAC_STRUCT(hal);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002116
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002117 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2118 FL("start - end: %d - %d"), start_ch_num, end_ch_num);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002119
Kondabattini, Ganesh13bb4b12016-09-04 16:16:53 +05302120 sme_cfg_get_int(hal, WNI_CFG_DFS_MASTER_ENABLED,
2121 &dfs_master_cap_enabled);
2122
2123 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2124 "%s: dfs_master %x", __func__, dfs_master_cap_enabled);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002125
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002126 /* get a channel in PCL and within the range */
2127 for (i = 0; i < sap_ctx->acs_cfg->pcl_ch_count; i++) {
2128 if ((sap_ctx->acs_cfg->pcl_channels[i] < start_ch_num) ||
2129 (sap_ctx->acs_cfg->pcl_channels[i] > end_ch_num))
2130 continue;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002131
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002132 first_safe_ch_in_range = sap_ctx->acs_cfg->pcl_channels[i];
2133 break;
2134 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002135
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002136 if (SAP_CHANNEL_NOT_SELECTED != first_safe_ch_in_range)
2137 return first_safe_ch_in_range;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002138
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002139 for (i = 0; i < NUM_CHANNELS; i++) {
2140 if ((safe_channels[i].channelNumber < start_ch_num) ||
2141 (safe_channels[i].channelNumber > end_ch_num))
2142 continue;
2143
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002144 ch_type = wlan_reg_get_channel_state(mac_ctx->pdev,
2145 safe_channels[i].channelNumber);
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002146
2147 if ((ch_type == CHANNEL_STATE_DISABLE) ||
2148 (ch_type == CHANNEL_STATE_INVALID))
2149 continue;
Kondabattini, Ganesh13bb4b12016-09-04 16:16:53 +05302150 if ((!dfs_master_cap_enabled) &&
2151 (CHANNEL_STATE_DFS == ch_type)) {
2152 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2153 "%s: DFS master mode disabled. Skip DFS channel %d",
2154 __func__, safe_channels[i].channelNumber);
2155 continue;
2156 }
Agrawal Ashish65634612016-08-18 13:24:32 +05302157 if ((sap_ctx->dfs_mode == ACS_DFS_MODE_DISABLE) &&
2158 (CHANNEL_STATE_DFS == ch_type))
2159 continue;
Kondabattini, Ganesh13bb4b12016-09-04 16:16:53 +05302160
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002161 if (safe_channels[i].isSafe == true) {
2162 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2163 FL("channel %d in the configuration is safe"),
2164 safe_channels[i].channelNumber);
2165 first_safe_ch_in_range = safe_channels[i].channelNumber;
2166 break;
2167 }
2168
2169 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2170 FL("channel %d in the configuration is unsafe"),
2171 safe_channels[i].channelNumber);
2172 }
2173
2174 /* if no channel selected return SAP_CHANNEL_NOT_SELECTED */
2175 return first_safe_ch_in_range;
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002176}
Dustin Brown0ce56d32016-10-17 16:18:03 -07002177#else
2178static uint8_t sap_select_channel_no_scan_result(tHalHandle hal,
2179 ptSapContext sap_ctx)
2180{
2181 uint32_t start_ch_num = sap_ctx->acs_cfg->start_ch;
2182
2183 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2184 FL("start - end: %d - %d"),
2185 start_ch_num,
2186 sap_ctx->acs_cfg->end_ch);
2187
2188 sap_ctx->acs_cfg->pri_ch = start_ch_num;
2189 sap_ctx->acs_cfg->ht_sec_ch = 0;
2190
2191 /* pick the first channel in configured range */
2192 return start_ch_num;
2193}
2194#endif /* FEATURE_WLAN_CH_AVOID */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002195
2196/**
2197 * sap_select_channel() - select SAP channel
2198 * @hal: Pointer to HAL handle
2199 * @sap_ctx: Sap context
2200 * @scan_result: Pointer to tScanResultHandle
2201 *
2202 * Runs a algorithm to select the best channel to operate in based on BSS
2203 * rssi and bss count on each channel
2204 *
2205 * Returns: channel number if success, 0 otherwise
2206 */
2207uint8_t sap_select_channel(tHalHandle hal, ptSapContext sap_ctx,
2208 tScanResultHandle scan_result)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002209{
2210 /* DFS param object holding all the data req by the algo */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002211 tSapChSelSpectInfo spect_info_obj = { NULL, 0 };
2212 tSapChSelSpectInfo *spect_info = &spect_info_obj;
2213 uint8_t best_ch_num = SAP_CHANNEL_NOT_SELECTED;
bingse2782382017-03-23 10:34:52 +08002214 uint32_t ht40plus2gendch = 0;
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002215 v_REGDOMAIN_t domain;
2216 uint8_t country[CDS_COUNTRY_CODE_LEN];
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002217#ifdef SOFTAP_CHANNEL_RANGE
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002218 uint8_t count;
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002219 uint32_t start_ch_num, end_ch_num, tmp_ch_num, operating_band = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002220#endif
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002221 tpAniSirGlobal mac_ctx;
2222
2223 mac_ctx = PMAC_STRUCT(hal);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302224 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002225 "In %s, Running SAP Ch Select", __func__);
2226
2227#ifdef FEATURE_WLAN_CH_AVOID
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002228 sap_update_unsafe_channel_list(hal, sap_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002229#endif
2230
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002231 if (NULL == scan_result) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302232 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002233 FL("No external AP present"));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002234
2235#ifndef SOFTAP_CHANNEL_RANGE
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002236 return SAP_CHANNEL_NOT_SELECTED;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002237#else
Kondabattini, Ganesh13bb4b12016-09-04 16:16:53 +05302238 return sap_select_channel_no_scan_result(hal, sap_ctx);
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002239#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002240 }
2241
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002242 /* Initialize the structure pointed by spect_info */
Srinivas Girigowda74a66d62017-06-21 23:28:25 -07002243 if (sap_chan_sel_init(hal, spect_info, sap_ctx) != true) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302244 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002245 FL("Ch Select initialization failed"));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002246 return SAP_CHANNEL_NOT_SELECTED;
2247 }
2248 /* Compute the weight of the entire spectrum in the operating band */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002249 sap_compute_spect_weight(spect_info, hal, scan_result, sap_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002250
2251#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
2252 /* process avoid channel IE to collect all channels to avoid */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002253 sap_process_avoid_ie(hal, sap_ctx, scan_result, spect_info);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002254#endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
2255
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002256 wlan_reg_read_default_country(mac_ctx->psoc, country);
2257 wlan_reg_get_domain_from_country_code(&domain, country, SOURCE_DRIVER);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002258#ifdef SOFTAP_CHANNEL_RANGE
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002259 start_ch_num = sap_ctx->acs_cfg->start_ch;
2260 end_ch_num = sap_ctx->acs_cfg->end_ch;
2261 SET_ACS_BAND(operating_band, sap_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002262
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002263 sap_ctx->acsBestChannelInfo.channelNum = 0;
2264 sap_ctx->acsBestChannelInfo.weight = SAP_ACS_WEIGHT_MAX;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002265
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002266 /* Sort the ch lst as per the computed weights, lesser weight first. */
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002267 sap_sort_chl_weight_all(sap_ctx, spect_info, operating_band, domain);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002268
2269 /*Loop till get the best channel in the given range */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002270 for (count = 0; count < spect_info->numSpectChans; count++) {
2271 if ((start_ch_num > spect_info->pSpectCh[count].chNum) ||
2272 (end_ch_num < spect_info->pSpectCh[count].chNum))
2273 continue;
2274
2275 if (best_ch_num == SAP_CHANNEL_NOT_SELECTED) {
2276 best_ch_num = spect_info->pSpectCh[count].chNum;
2277 /* check if best_ch_num is in preferred channel list */
2278 best_ch_num =
2279 sap_select_preferred_channel_from_channel_list(
2280 best_ch_num, sap_ctx, spect_info);
2281 /* if not in preferred ch lst, go to nxt best ch */
2282 if (best_ch_num == SAP_CHANNEL_NOT_SELECTED)
2283 continue;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002284
2285#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002286 /*
2287 * Weight of the channels(device's AP is operating)
2288 * increased to MAX+1 so that they will be choosen only
2289 * when there is no other best channel to choose
2290 */
2291 if (sap_check_in_avoid_ch_list(sap_ctx, best_ch_num)) {
2292 best_ch_num = SAP_CHANNEL_NOT_SELECTED;
2293 continue;
2294 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002295#endif
2296
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002297 sap_ctx->acsBestChannelInfo.channelNum = best_ch_num;
2298 sap_ctx->acsBestChannelInfo.weight =
2299 spect_info->pSpectCh[count].weight_copy;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002300 }
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002301
2302 if (best_ch_num == SAP_CHANNEL_NOT_SELECTED)
2303 continue;
2304
2305 if (operating_band != eCSR_DOT11_MODE_11g)
2306 continue;
2307
2308 /* Give preference to Non-overlap channels */
2309 if (false == sap_filter_over_lap_ch(sap_ctx,
2310 spect_info->pSpectCh[count].chNum))
2311 continue;
2312
bings14d1d3b2017-08-03 11:14:29 +08002313 if (spect_info->pSpectCh[count].weight_copy >
2314 sap_ctx->acsBestChannelInfo.weight)
2315 continue;
2316
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002317 tmp_ch_num = spect_info->pSpectCh[count].chNum;
2318 tmp_ch_num = sap_select_preferred_channel_from_channel_list(
2319 tmp_ch_num, sap_ctx, spect_info);
2320 if (tmp_ch_num == SAP_CHANNEL_NOT_SELECTED)
2321 continue;
2322
2323 best_ch_num = tmp_ch_num;
2324 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002325 }
2326#else
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002327 /* Sort the ch lst as per the computed weights, lesser weight first. */
2328 sap_sort_chl_weight_all(sap_ctx, hal, spect_info);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002329 /* Get the first channel in sorted array as best 20M Channel */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002330 best_ch_num = (uint8_t) spect_info->pSpectCh[0].chNum;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002331 /* Select Best Channel from Channel List if Configured */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002332 best_ch_num = sap_select_preferred_channel_from_channel_list(
2333 best_ch_num, sap_ctx, spect_info);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002334#endif
2335
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002336 /*
2337 * in case the best channel seleted is not in PCL and there is another
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002338 * channel which has same weightage and is in PCL, choose the one in
2339 * PCL
2340 */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002341 for (count = 0; count < spect_info->numSpectChans; count++) {
2342 if (!ch_in_pcl(sap_ctx, spect_info->pSpectCh[count].chNum) ||
2343 (spect_info->pSpectCh[count].weight !=
2344 sap_ctx->acsBestChannelInfo.weight))
2345 continue;
2346
2347 if (sap_select_preferred_channel_from_channel_list(
2348 spect_info->pSpectCh[count].chNum, sap_ctx, spect_info)
2349 == SAP_CHANNEL_NOT_SELECTED)
2350 continue;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002351
2352#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002353 if (sap_check_in_avoid_ch_list(sap_ctx, best_ch_num))
2354 continue;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002355#endif
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002356 best_ch_num = spect_info->pSpectCh[count].chNum;
2357 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2358 FL("change best channel to %d in PCL"), best_ch_num);
2359 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002360 }
2361
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002362 sap_ctx->acs_cfg->pri_ch = best_ch_num;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002363 /* determine secondary channel for 2.4G channel 5, 6, 7 in HT40 */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002364 if ((operating_band != eCSR_DOT11_MODE_11g) ||
2365 (sap_ctx->acs_cfg->ch_width != CH_WIDTH_40MHZ))
2366 goto sap_ch_sel_end;
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002367 if (REGDOMAIN_FCC == domain)
bingse2782382017-03-23 10:34:52 +08002368 ht40plus2gendch = HT40PLUS_2G_FCC_CH_END;
2369 else
2370 ht40plus2gendch = HT40PLUS_2G_EURJAP_CH_END;
2371 if ((best_ch_num >= HT40MINUS_2G_CH_START) &&
2372 (best_ch_num <= ht40plus2gendch)) {
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002373 int weight_below, weight_above, i;
2374 tSapSpectChInfo *pspect_info;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002375
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002376 weight_below = weight_above = SAP_ACS_WEIGHT_MAX;
2377 pspect_info = spect_info->pSpectCh;
2378 for (i = 0; i < spect_info->numSpectChans; i++) {
2379 if (pspect_info[i].chNum == (best_ch_num - 4))
2380 weight_below = pspect_info[i].weight;
2381 if (pspect_info[i].chNum == (best_ch_num + 4))
2382 weight_above = pspect_info[i].weight;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002383 }
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002384
2385 if (weight_below < weight_above)
2386 sap_ctx->acs_cfg->ht_sec_ch =
2387 sap_ctx->acs_cfg->pri_ch - 4;
2388 else
2389 sap_ctx->acs_cfg->ht_sec_ch =
2390 sap_ctx->acs_cfg->pri_ch + 4;
2391 } else if (best_ch_num >= 1 && best_ch_num <= 4) {
2392 sap_ctx->acs_cfg->ht_sec_ch = sap_ctx->acs_cfg->pri_ch + 4;
bingse2782382017-03-23 10:34:52 +08002393 } else if (best_ch_num >= ht40plus2gendch && best_ch_num <=
2394 HT40MINUS_2G_CH_END) {
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002395 sap_ctx->acs_cfg->ht_sec_ch = sap_ctx->acs_cfg->pri_ch - 4;
2396 } else if (best_ch_num == 14) {
2397 sap_ctx->acs_cfg->ht_sec_ch = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002398 }
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002399 sap_ctx->secondary_ch = sap_ctx->acs_cfg->ht_sec_ch;
2400
2401sap_ch_sel_end:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002402 /* Free all the allocated memory */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002403 sap_chan_sel_exit(spect_info);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002404
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302405 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002406 FL("Running SAP Ch select Completed, Ch=%d"), best_ch_num);
2407 if (best_ch_num > 0 && best_ch_num <= 252)
2408 return best_ch_num;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002409 else
2410 return SAP_CHANNEL_NOT_SELECTED;
2411}