blob: 396cc54217eadb1f98e027e1c35e058efa2c8eed [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
gaoleze5108942017-03-31 16:56:42 +080088#define ACS_WEIGHT_AMOUNT_LOCAL 240
89
90#define ACS_WEIGHT_AMOUNT_CONFIG(weights) \
91 (((weights) & 0xf) + \
92 (((weights) & 0xf0) >> 4) + \
93 (((weights) & 0xf00) >> 8) + \
94 (((weights) & 0xf000) >> 12) + \
95 (((weights) & 0xf0000) >> 16) + \
96 (((weights) & 0xf00000) >> 20))
97
98/*
99 * LSH/RSH 4 to enhance the accurate since
100 * need to do modulation to ACS_WEIGHT_AMOUNT_LOCAL.
101 */
102#define ACS_WEIGHT_COMPUTE(weights, weight, factor, base) \
103 (((((((((weight) << 4) * ACS_WEIGHT_AMOUNT_LOCAL * (factor)) + \
104 (ACS_WEIGHT_AMOUNT_CONFIG((weights)) >> 1)) / \
105 ACS_WEIGHT_AMOUNT_CONFIG((weights))) + \
106 ((base) >> 1)) / (base)) + 8) >> 4)
107
108#define ACS_WEIGHT_CFG_TO_LOCAL(weights, weight) \
109 (((((((weight) << 4) * ACS_WEIGHT_AMOUNT_LOCAL) + \
110 (ACS_WEIGHT_AMOUNT_CONFIG((weights)) >> 1)) / \
111 ACS_WEIGHT_AMOUNT_CONFIG((weights))) + 8) >> 4)
112
113#define ACS_WEIGHT_SOFTAP_RSSI_CFG(weights) \
114 ((weights) & 0xf)
115
116#define ACS_WEIGHT_SOFTAP_COUNT_CFG(weights) \
117 (((weights) & 0xf0) >> 4)
118
119#define ACS_WEIGHT_SOFTAP_NOISE_FLOOR_CFG(weights) \
120 (((weights) & 0xf00) >> 8)
121
122#define ACS_WEIGHT_SOFTAP_CHANNEL_FREE_CFG(weights) \
123 (((weights) & 0xf000) >> 12)
124
125#define ACS_WEIGHT_SOFTAP_TX_POWER_RANGE_CFG(weights) \
126 (((weights) & 0xf0000) >> 16)
127
128#define ACS_WEIGHT_SOFTAP_TX_POWER_THROUGHPUT_CFG(weights) \
129 (((weights) & 0xf00000) >> 20)
130
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800131#ifdef FEATURE_WLAN_CH_AVOID
Amar Singhalb8d4f152016-02-10 10:21:43 -0800132sapSafeChannelType safe_channels[NUM_CHANNELS] = {
133 {1, true},
134 {2, true},
135 {3, true},
136 {4, true},
137 {5, true},
138 {6, true},
139 {7, true},
140 {8, true},
141 {9, true},
142 {10, true},
143 {11, true},
144 {12, true},
145 {13, true},
146 {14, true},
147 {36, true},
148 {40, true},
149 {44, true},
150 {48, true},
151 {52, true},
152 {56, true},
153 {60, true},
154 {64, true},
155 {100, true},
156 {104, true},
157 {108, true},
158 {112, true},
159 {116, true},
160 {120, true},
161 {124, true},
162 {128, true},
163 {132, true},
164 {136, true},
165 {140, true},
166 {144, true},
167 {149, true},
168 {153, true},
169 {157, true},
170 {161, true},
171 {165, true},
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800172};
173#endif
174
175typedef struct {
176 uint16_t chStartNum;
177 uint32_t weight;
178} sapAcsChannelInfo;
179
180sapAcsChannelInfo acs_ht40_channels5_g[] = {
181 {36, SAP_ACS_WEIGHT_MAX},
182 {44, SAP_ACS_WEIGHT_MAX},
183 {52, SAP_ACS_WEIGHT_MAX},
184 {60, SAP_ACS_WEIGHT_MAX},
185 {100, SAP_ACS_WEIGHT_MAX},
186 {108, SAP_ACS_WEIGHT_MAX},
187 {116, SAP_ACS_WEIGHT_MAX},
188 {124, SAP_ACS_WEIGHT_MAX},
189 {132, SAP_ACS_WEIGHT_MAX},
190 {140, SAP_ACS_WEIGHT_MAX},
191 {149, SAP_ACS_WEIGHT_MAX},
192 {157, SAP_ACS_WEIGHT_MAX},
193};
194
195sapAcsChannelInfo acs_ht80_channels[] = {
196 {36, SAP_ACS_WEIGHT_MAX},
197 {52, SAP_ACS_WEIGHT_MAX},
198 {100, SAP_ACS_WEIGHT_MAX},
199 {116, SAP_ACS_WEIGHT_MAX},
200 {132, SAP_ACS_WEIGHT_MAX},
201 {149, SAP_ACS_WEIGHT_MAX},
202};
203
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -0700204sapAcsChannelInfo acs_vht160_channels[] = {
205 {36, SAP_ACS_WEIGHT_MAX},
206 {100, SAP_ACS_WEIGHT_MAX},
207};
208
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800209sapAcsChannelInfo acs_ht40_channels24_g[] = {
210 {1, SAP_ACS_WEIGHT_MAX},
211 {2, SAP_ACS_WEIGHT_MAX},
212 {3, SAP_ACS_WEIGHT_MAX},
213 {4, SAP_ACS_WEIGHT_MAX},
214 {9, SAP_ACS_WEIGHT_MAX},
215};
216
217#define CHANNEL_165 165
218
219/* rssi discount for channels in PCL */
220#define PCL_RSSI_DISCOUNT 10
221
222#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
223/**
224 * sap_check_n_add_channel() - checks and add given channel in sap context's
225 * avoid_channels_info struct
226 * @sap_ctx: sap context.
227 * @new_channel: channel to be added to sap_ctx's avoid ch info
228 *
229 * sap_ctx contains sap_avoid_ch_info strcut containing the list of channels on
230 * which MDM device's AP with MCC was detected. This function will add channels
231 * to that list after checking for duplicates.
232 *
233 * Return: true: if channel was added or already present
234 * else false: if channel list was already full.
235 */
Tang Yingying523322d2017-01-17 23:28:43 +0800236static bool
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -0700237sap_check_n_add_channel(struct sap_context *sap_ctx,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800238 uint8_t new_channel)
239{
240 uint8_t i = 0;
241 struct sap_avoid_channels_info *ie_info =
242 &sap_ctx->sap_detected_avoid_ch_ie;
243
244 for (i = 0; i < sizeof(ie_info->channels); i++) {
245 if (ie_info->channels[i] == new_channel)
246 break;
247
248 if (ie_info->channels[i] == 0) {
249 ie_info->channels[i] = new_channel;
250 break;
251 }
252 }
253 if (i == sizeof(ie_info->channels))
254 return false;
255 else
256 return true;
257}
258/**
259 * sap_check_n_add_overlapped_chnls() - checks & add overlapped channels
260 * to primary channel in 2.4Ghz band.
261 * @sap_ctx: sap context.
262 * @primary_chnl: primary channel to be avoided.
263 *
264 * sap_ctx contains sap_avoid_ch_info struct containing the list of channels on
265 * which MDM device's AP with MCC was detected. This function will add channels
266 * to that list after checking for duplicates.
267 *
268 * Return: true: if channel was added or already present
269 * else false: if channel list was already full.
270 */
271static bool
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -0700272sap_check_n_add_overlapped_chnls(struct sap_context *sap_ctx,
273 uint8_t primary_channel)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800274{
275 uint8_t i = 0, j = 0, upper_chnl = 0, lower_chnl = 0;
276 struct sap_avoid_channels_info *ie_info =
277 &sap_ctx->sap_detected_avoid_ch_ie;
278 /*
279 * if primary channel less than channel 1 or out of 2g band then
280 * no further process is required. return true in this case.
281 */
282 if (primary_channel < CHANNEL_1 || primary_channel > CHANNEL_14)
283 return true;
284
285 /* lower channel is one channel right before primary channel */
286 lower_chnl = primary_channel - 1;
287 /* upper channel is one channel right after primary channel */
288 upper_chnl = primary_channel + 1;
289
290 /* lower channel needs to be non-zero, zero is not valid channel */
291 if (lower_chnl > (CHANNEL_1 - 1)) {
292 for (i = 0; i < sizeof(ie_info->channels); i++) {
293 if (ie_info->channels[i] == lower_chnl)
294 break;
295 if (ie_info->channels[i] == 0) {
296 ie_info->channels[i] = lower_chnl;
297 break;
298 }
299 }
300 }
301 /* upper channel needs to be atleast last channel in 2.4Ghz band */
302 if (upper_chnl < (CHANNEL_14 + 1)) {
303 for (j = 0; j < sizeof(ie_info->channels); j++) {
304 if (ie_info->channels[j] == upper_chnl)
305 break;
306 if (ie_info->channels[j] == 0) {
307 ie_info->channels[j] = upper_chnl;
308 break;
309 }
310 }
311 }
312 if (i == sizeof(ie_info->channels) || j == sizeof(ie_info->channels))
313 return false;
314 else
315 return true;
316}
317
318/**
319 * sap_process_avoid_ie() - processes the detected Q2Q IE
320 * context's avoid_channels_info struct
321 * @hal: hal handle
322 * @sap_ctx: sap context.
323 * @scan_result: scan results for ACS scan.
324 * @spect_info: spectrum weights array to update
325 *
326 * Detection of Q2Q IE indicates presence of another MDM device with its AP
327 * operating in MCC mode. This function parses the scan results and processes
328 * the Q2Q IE if found. It then extracts the channels and populates them in
329 * sap_ctx struct. It also increases the weights of those channels so that
330 * ACS logic will avoid those channels in its selection algorithm.
331 *
332 * Return: void
333 */
Tang Yingying523322d2017-01-17 23:28:43 +0800334static void sap_process_avoid_ie(tHalHandle hal,
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -0700335 struct sap_context *sap_ctx,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800336 tScanResultHandle scan_result,
337 tSapChSelSpectInfo *spect_info)
338{
339 uint32_t total_ie_len = 0;
340 uint8_t *temp_ptr = NULL;
341 uint8_t i = 0;
342 struct sAvoidChannelIE *avoid_ch_ie;
343 tCsrScanResultInfo *node = NULL;
344 tpAniSirGlobal mac_ctx = NULL;
345 tSapSpectChInfo *spect_ch = NULL;
346
347 mac_ctx = PMAC_STRUCT(hal);
348 spect_ch = spect_info->pSpectCh;
349 node = sme_scan_result_get_first(hal, scan_result);
350
351 while (node) {
Abhishek Singh34a4d862016-10-26 16:01:51 +0530352 total_ie_len =
353 GET_IE_LEN_IN_BSS_DESC(node->BssDescriptor.length);
Naveen Rawat08db88f2017-09-08 15:07:48 -0700354 temp_ptr = wlan_get_vendor_ie_ptr_from_oui(
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800355 SIR_MAC_QCOM_VENDOR_OUI,
356 SIR_MAC_QCOM_VENDOR_SIZE,
357 ((uint8_t *)&node->BssDescriptor.ieFields),
358 total_ie_len);
359
360 if (temp_ptr) {
361 avoid_ch_ie = (struct sAvoidChannelIE *)temp_ptr;
Will Huang55ba1042017-03-22 10:43:30 +0800362 if (avoid_ch_ie->type !=
363 QCOM_VENDOR_IE_MCC_AVOID_CH) {
364 node = sme_scan_result_get_next(hal,
365 scan_result);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800366 continue;
Will Huang55ba1042017-03-22 10:43:30 +0800367 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800368
369 sap_ctx->sap_detected_avoid_ch_ie.present = 1;
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530370 QDF_TRACE(QDF_MODULE_ID_SAP,
371 QDF_TRACE_LEVEL_DEBUG,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800372 "Q2Q IE - avoid ch %d",
373 avoid_ch_ie->channel);
374 /* add this channel to to_avoid channel list */
375 sap_check_n_add_channel(sap_ctx,
376 avoid_ch_ie->channel);
377 sap_check_n_add_overlapped_chnls(sap_ctx,
378 avoid_ch_ie->channel);
379 /*
380 * Mark weight of these channel present in IE to MAX
381 * so that ACS logic will to avoid thse channels
382 */
383 for (i = 0; i < spect_info->numSpectChans; i++)
384 if (spect_ch[i].chNum == avoid_ch_ie->channel) {
385 /*
386 * weight is set more than max so that,
387 * in the case of other channels being
388 * assigned max weight due to noise,
389 * they may be preferred over channels
390 * with Q2Q IE.
391 */
392 spect_ch[i].weight = SAP_ACS_WEIGHT_MAX + 1;
393 spect_ch[i].weight_copy =
394 SAP_ACS_WEIGHT_MAX + 1;
395 break;
396 }
397 } /* if (temp_ptr) */
398 node = sme_scan_result_get_next(hal, scan_result);
399 }
400}
401#endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
402
403#ifdef FEATURE_WLAN_CH_AVOID
404/*==========================================================================
405 FUNCTION sap_update_unsafe_channel_list
406
407 DESCRIPTION
408 Function Undate unsafe channel list table
409
410 DEPENDENCIES
411 NA.
412
413 IN
414 SapContext pointer
415
416 RETURN VALUE
417 NULL
418 ============================================================================*/
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -0700419void sap_update_unsafe_channel_list(tHalHandle hal, struct sap_context *pSapCtx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800420{
421 uint16_t i, j;
Amar Singhalb8d4f152016-02-10 10:21:43 -0800422 uint16_t unsafe_channel_list[NUM_CHANNELS];
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800423 uint16_t unsafe_channel_count = 0;
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -0700424 tpAniSirGlobal mac_ctx = NULL;
425
Yuanyuan Liu0e0aa932016-05-12 10:17:58 -0700426 qdf_device_t qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800427
Yuanyuan Liu97361182016-06-06 09:38:04 -0700428 if (!qdf_ctx) {
429 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_FATAL,
430 "qdf_ctx is NULL");
431 return;
432 }
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -0700433 mac_ctx = PMAC_STRUCT(hal);
434 if (!mac_ctx) {
435 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_FATAL,
436 "mac_ctx is NULL");
437 return;
438 }
Yuanyuan Liu97361182016-06-06 09:38:04 -0700439
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800440 /* Flush, default set all channel safe */
Amar Singhalb8d4f152016-02-10 10:21:43 -0800441 for (i = 0; i < NUM_CHANNELS; i++) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800442 safe_channels[i].isSafe = true;
443 }
444
445 /* Try to find unsafe channel */
Ryan Hsu4252a2f2016-01-05 11:18:24 -0800446#if defined(FEATURE_WLAN_STA_AP_MODE_DFS_DISABLE)
Amar Singhalb8d4f152016-02-10 10:21:43 -0800447 for (i = 0; i < NUM_CHANNELS; i++) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800448 if (pSapCtx->dfs_ch_disable == true) {
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -0700449 if (wlan_reg_is_dfs_ch(mac_ctx->pdev,
450 safe_channels[i].channelNumber)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800451 safe_channels[i].isSafe = false;
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530452 QDF_TRACE(QDF_MODULE_ID_SAP,
453 QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800454 "%s: DFS Ch %d is not safe in"
455 " Concurrent mode",
456 __func__,
457 safe_channels[i].channelNumber);
458 }
459 }
460 }
461#endif
Yuanyuan Liu0e0aa932016-05-12 10:17:58 -0700462 pld_get_wlan_unsafe_channel(qdf_ctx->dev,
463 unsafe_channel_list,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800464 &unsafe_channel_count,
465 sizeof(unsafe_channel_list));
466
467 for (i = 0; i < unsafe_channel_count; i++) {
Amar Singhalb8d4f152016-02-10 10:21:43 -0800468 for (j = 0; j < NUM_CHANNELS; j++) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800469 if (safe_channels[j].channelNumber ==
470 unsafe_channel_list[i]) {
471 /* Found unsafe channel, update it */
472 safe_channels[j].isSafe = false;
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530473 QDF_TRACE(QDF_MODULE_ID_SAP,
474 QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800475 FL("CH %d is not safe"),
476 unsafe_channel_list[i]);
477 break;
478 }
479 }
480 }
481
482 return;
483}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800484
485#endif /* FEATURE_WLAN_CH_AVOID */
486
487/*==========================================================================
488 FUNCTION sap_cleanup_channel_list
489
490 DESCRIPTION
491 Function sap_cleanup_channel_list frees up the memory allocated to the channel list.
492
493 DEPENDENCIES
494 NA.
495
496 PARAMETERS
497
498 IN
499 NULL
500
501 RETURN VALUE
502 NULL
503 ============================================================================*/
504
Ryan Hsu4252a2f2016-01-05 11:18:24 -0800505void sap_cleanup_channel_list(void *p_cds_gctx)
506{
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -0700507 struct sap_context *pSapCtx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800508
Srinivas Girigowda678586c2017-03-10 00:13:58 -0800509 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800510 "Cleaning up the channel list structure");
511
512 if (NULL == p_cds_gctx) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530513 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800514 "SAP Global Context is NULL");
515 return;
516 }
517
518 pSapCtx = CDS_GET_SAP_CB(p_cds_gctx);
519 if (NULL == pSapCtx) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530520 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800521 "SAP Context is NULL");
522 return;
523 }
524
525 pSapCtx->SapChnlList.numChannel = 0;
526 if (pSapCtx->SapChnlList.channelList) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530527 qdf_mem_free(pSapCtx->SapChnlList.channelList);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800528 pSapCtx->SapChnlList.channelList = NULL;
529 }
530
531 pSapCtx->SapAllChnlList.numChannel = 0;
532 if (pSapCtx->SapAllChnlList.channelList) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530533 qdf_mem_free(pSapCtx->SapAllChnlList.channelList);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800534 pSapCtx->SapAllChnlList.channelList = NULL;
535 }
536}
537
538/**
gaoleze5108942017-03-31 16:56:42 +0800539 * sap_channel_in_acs_channel_list() - check if channel in acs channel list
540 * @channel_num: channel to check
541 * @sap_ctx: struct ptSapContext
542 * @spect_info_params: strcut tSapChSelSpectInfo
543 *
544 * This function checks if specified channel is in the configured ACS channel
545 * list.
546 *
547 * Return: channel number if in acs channel list or SAP_CHANNEL_NOT_SELECTED
548 */
549static
550uint8_t sap_channel_in_acs_channel_list(uint8_t channel_num,
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -0700551 struct sap_context *sap_ctx,
gaoleze5108942017-03-31 16:56:42 +0800552 tSapChSelSpectInfo *spect_info_params)
553{
554 uint8_t i = 0;
555
556 if ((NULL == sap_ctx->acs_cfg->ch_list) ||
557 (NULL == spect_info_params))
558 return channel_num;
559
560 if (channel_num > 0 && channel_num <= 252) {
561 for (i = 0; i < sap_ctx->acs_cfg->ch_list_count; i++) {
562 if ((sap_ctx->acs_cfg->ch_list[i]) == channel_num)
563 return channel_num;
564 }
565 return SAP_CHANNEL_NOT_SELECTED;
566 } else {
567 return SAP_CHANNEL_NOT_SELECTED;
568 }
569}
570
571/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800572 * sap_select_preferred_channel_from_channel_list() - to calc best cahnnel
573 * @best_chnl: best channel already calculated among all the chanels
574 * @sap_ctx: sap context
575 * @spectinfo_param: Pointer to tSapChSelSpectInfo structure
576 *
577 * This function calculates the best channel among the configured channel list.
578 * If channel list not configured then returns the best channel calculated
579 * among all the channel list.
580 *
581 * Return: uint8_t best channel
582 */
Jeff Johnson464f7ea2016-10-07 10:21:26 -0700583static
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800584uint8_t sap_select_preferred_channel_from_channel_list(uint8_t best_chnl,
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -0700585 struct sap_context *sap_ctx,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800586 tSapChSelSpectInfo *spectinfo_param)
587{
588 uint8_t i = 0;
Tushnim Bhattacharyya518e80f2017-08-30 17:35:33 -0700589 tpAniSirGlobal mac_ctx = sme_get_mac_context();
590
591 if (NULL == mac_ctx) {
592 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
593 "pmac Global Context is NULL");
594 return SAP_CHANNEL_NOT_SELECTED;
595 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800596
597 /*
598 * If Channel List is not Configured don't do anything
599 * Else return the Best Channel from the Channel List
600 */
601 if ((NULL == sap_ctx->acs_cfg->ch_list) ||
602 (NULL == spectinfo_param) ||
603 (0 == sap_ctx->acs_cfg->ch_list_count))
604 return best_chnl;
605
606 if (best_chnl <= 0 || best_chnl > 252)
607 return SAP_CHANNEL_NOT_SELECTED;
608
609 /* Select the best channel from allowed list */
610 for (i = 0; i < sap_ctx->acs_cfg->ch_list_count; i++) {
Tushnim Bhattacharyya518e80f2017-08-30 17:35:33 -0700611 if ((sap_ctx->acs_cfg->ch_list[i] == best_chnl) &&
612 !(wlan_reg_is_dfs_ch(mac_ctx->pdev, best_chnl) &&
613 policy_mgr_disallow_mcc(mac_ctx->psoc, best_chnl))) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530614 QDF_TRACE(QDF_MODULE_ID_SAP,
615 QDF_TRACE_LEVEL_INFO_HIGH,
Naveen Rawatbec64d92017-09-13 14:35:21 -0700616 "Best channel so far is: %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800617 best_chnl);
618 return best_chnl;
619 }
620 }
621
622 return SAP_CHANNEL_NOT_SELECTED;
623}
624
625/*==========================================================================
626 FUNCTION sap_chan_sel_init
627
628 DESCRIPTION
629 Function sap_chan_sel_init allocates the memory, intializes the
Anurag Chouhan6d760662016-02-20 16:05:43 +0530630 structures used by the channel selection algorithm
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800631
632 DEPENDENCIES
633 NA.
634
635 PARAMETERS
636
637 IN
638 halHandle : Pointer to tHalHandle
639 *pSpectInfoParams : Pointer to tSapChSelSpectInfo structure
640 pSapCtx : Pointer to SAP Context
641
642 RETURN VALUE
643 bool: Success or FAIL
644
645 SIDE EFFECTS
646 ============================================================================*/
Jeff Johnson464f7ea2016-10-07 10:21:26 -0700647static bool sap_chan_sel_init(tHalHandle halHandle,
648 tSapChSelSpectInfo *pSpectInfoParams,
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -0700649 struct sap_context *pSapCtx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800650{
651 tSapSpectChInfo *pSpectCh = NULL;
652 uint8_t *pChans = NULL;
653 uint16_t channelnum = 0;
654 tpAniSirGlobal pMac = PMAC_STRUCT(halHandle);
655 bool chSafe = true;
656#ifdef FEATURE_WLAN_CH_AVOID
657 uint16_t i;
658#endif
659 uint32_t dfs_master_cap_enabled;
660 bool include_dfs_ch = true;
661
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530662 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, "In %s",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800663 __func__);
664
665 pSpectInfoParams->numSpectChans =
666 pMac->scan.base_channels.numChannels;
667
668 /* Allocate memory for weight computation of 2.4GHz */
669 pSpectCh =
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530670 (tSapSpectChInfo *) qdf_mem_malloc((pSpectInfoParams->numSpectChans)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800671 * sizeof(*pSpectCh));
672
673 if (pSpectCh == NULL) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530674 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
Anurag Chouhanf04e84f2016-03-03 10:12:12 +0530675 "In %s, QDF_MALLOC_ERR", __func__);
Srinivas Girigowda74a66d62017-06-21 23:28:25 -0700676 return false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800677 }
678
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800679 /* Initialize the pointers in the DfsParams to the allocated memory */
680 pSpectInfoParams->pSpectCh = pSpectCh;
681
682 pChans = pMac->scan.base_channels.channelList;
683
Ryan Hsu4252a2f2016-01-05 11:18:24 -0800684#if defined(FEATURE_WLAN_STA_AP_MODE_DFS_DISABLE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800685 if (pSapCtx->dfs_ch_disable == true)
686 include_dfs_ch = false;
687#endif
688 sme_cfg_get_int(halHandle, WNI_CFG_DFS_MASTER_ENABLED,
689 &dfs_master_cap_enabled);
Agrawal Ashish65634612016-08-18 13:24:32 +0530690 if (dfs_master_cap_enabled == 0 ||
691 ACS_DFS_MODE_DISABLE == pSapCtx->dfs_mode)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800692 include_dfs_ch = false;
693
694 /* Fill the channel number in the spectrum in the operating freq band */
695 for (channelnum = 0;
696 channelnum < pSpectInfoParams->numSpectChans;
Edhar, Mahesh Kumar4f660672015-10-30 11:53:26 +0530697 channelnum++, pChans++, pSpectCh++) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800698 chSafe = true;
699
700 /* check if the channel is in NOL blacklist */
701 if (sap_dfs_is_channel_in_nol_list(pSapCtx, *pChans,
702 PHY_SINGLE_CHANNEL_CENTERED)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530703 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800704 "In %s, Ch %d is in NOL list", __func__,
705 *pChans);
706 chSafe = false;
707 continue;
708 }
709
710 if (include_dfs_ch == false) {
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -0700711 if (wlan_reg_is_dfs_ch(pMac->pdev, *pChans)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800712 chSafe = false;
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530713 QDF_TRACE(QDF_MODULE_ID_SAP,
714 QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800715 "In %s, DFS Ch %d not considered for ACS",
716 __func__, *pChans);
717 continue;
718 }
719 }
720
721#ifdef FEATURE_WLAN_CH_AVOID
Amar Singhalb8d4f152016-02-10 10:21:43 -0800722 for (i = 0; i < NUM_CHANNELS; i++) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800723 if ((safe_channels[i].channelNumber == *pChans) &&
724 (false == safe_channels[i].isSafe)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530725 QDF_TRACE(QDF_MODULE_ID_SAP,
726 QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800727 "In %s, Ch %d is not safe", __func__,
728 *pChans);
729 chSafe = false;
730 break;
731 }
732 }
733#endif /* FEATURE_WLAN_CH_AVOID */
734
735 /* OFDM rates are not supported on channel 14 */
736 if (*pChans == 14 &&
737 eCSR_DOT11_MODE_11b != pSapCtx->csr_roamProfile.phyMode) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800738 continue;
739 }
740
Deepthi Gowri48b89332016-08-30 18:43:05 +0530741 /* Skip DSRC channels */
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -0700742 if (WLAN_REG_IS_11P_CH(*pChans))
Deepthi Gowri48b89332016-08-30 18:43:05 +0530743 continue;
744
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800745 if (true == chSafe) {
746 pSpectCh->chNum = *pChans;
Srinivas Girigowda74a66d62017-06-21 23:28:25 -0700747 pSpectCh->valid = true;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800748 pSpectCh->rssiAgr = SOFTAP_MIN_RSSI; /* Initialise for all channels */
749 pSpectCh->channelWidth = SOFTAP_HT20_CHANNELWIDTH; /* Initialise 20MHz for all the Channels */
750 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800751 }
Srinivas Girigowda74a66d62017-06-21 23:28:25 -0700752 return true;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800753}
754
gaoleze5108942017-03-31 16:56:42 +0800755/**
756 * sapweight_rssi_count() - calculates the channel weight due to rssi
Anurag Chouhan6d760662016-02-20 16:05:43 +0530757 and data count(here number of BSS observed)
gaoleze5108942017-03-31 16:56:42 +0800758 * @sap_ctx : Softap context
759 * @rssi : Max signal strength receieved from a BSS for the channel
760 * @count : Number of BSS observed in the channel
761 *
762 * Return: uint32_t Calculated channel weight based on above two
763 */
764static
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -0700765uint32_t sapweight_rssi_count(struct sap_context *sap_ctx, int8_t rssi,
gaoleze5108942017-03-31 16:56:42 +0800766 uint16_t count)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800767{
768 int32_t rssiWeight = 0;
769 int32_t countWeight = 0;
770 uint32_t rssicountWeight = 0;
gaoleze5108942017-03-31 16:56:42 +0800771 uint8_t softap_rssi_weight_cfg, softap_count_weight_cfg;
772 uint8_t softap_rssi_weight_local, softap_count_weight_local;
773
774 softap_rssi_weight_cfg =
775 ACS_WEIGHT_SOFTAP_RSSI_CFG(sap_ctx->auto_channel_select_weight);
776
777 softap_count_weight_cfg =
778 ACS_WEIGHT_SOFTAP_COUNT_CFG(sap_ctx->auto_channel_select_weight);
779
780 softap_rssi_weight_local =
781 ACS_WEIGHT_CFG_TO_LOCAL(sap_ctx->auto_channel_select_weight,
782 softap_rssi_weight_cfg);
783
784 softap_count_weight_local =
785 ACS_WEIGHT_CFG_TO_LOCAL(sap_ctx->auto_channel_select_weight,
786 softap_count_weight_cfg);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800787
788 /* Weight from RSSI */
gaoleze5108942017-03-31 16:56:42 +0800789 rssiWeight = ACS_WEIGHT_COMPUTE(sap_ctx->auto_channel_select_weight,
790 softap_rssi_weight_cfg,
791 rssi - SOFTAP_MIN_RSSI,
792 SOFTAP_MAX_RSSI - SOFTAP_MIN_RSSI);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800793
gaoleze5108942017-03-31 16:56:42 +0800794 if (rssiWeight > softap_rssi_weight_local)
795 rssiWeight = softap_rssi_weight_local;
796
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800797 else if (rssiWeight < 0)
798 rssiWeight = 0;
799
800 /* Weight from data count */
gaoleze5108942017-03-31 16:56:42 +0800801 countWeight = ACS_WEIGHT_COMPUTE(sap_ctx->auto_channel_select_weight,
802 softap_count_weight_cfg,
803 count - SOFTAP_MIN_COUNT,
804 SOFTAP_MAX_COUNT - SOFTAP_MIN_COUNT);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800805
gaoleze5108942017-03-31 16:56:42 +0800806 if (countWeight > softap_count_weight_local)
807 countWeight = softap_count_weight_local;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800808
809 rssicountWeight = rssiWeight + countWeight;
810
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530811 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800812 "In %s, rssiWeight=%d, countWeight=%d, rssicountWeight=%d",
813 __func__, rssiWeight, countWeight, rssicountWeight);
814
815 return rssicountWeight;
816}
817
818/**
gaoleze5108942017-03-31 16:56:42 +0800819 * sap_get_channel_status() - get channel info via channel number
820 * @p_mac: Pointer to Global MAC structure
821 * @channel_id: channel id
822 *
823 * Return: chan status info
824 */
825static struct lim_channel_status *sap_get_channel_status
826 (tpAniSirGlobal p_mac, uint32_t channel_id)
827{
828 return csr_get_channel_status(p_mac, channel_id);
829}
830
831/**
832 * sap_clear_channel_status() - clear chan info
833 * @p_mac: Pointer to Global MAC structure
834 *
835 * Return: none
836 */
837static void sap_clear_channel_status(tpAniSirGlobal p_mac)
838{
839 csr_clear_channel_status(p_mac);
840}
841
842/**
843 * sap_weight_channel_noise_floor() - compute noise floor weight
844 * @sap_ctx: sap context
845 * @chn_stat: Pointer to chan status info
846 *
847 * Return: channel noise floor weight
848 */
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -0700849static uint32_t sap_weight_channel_noise_floor(struct sap_context *sap_ctx,
gaoleze5108942017-03-31 16:56:42 +0800850 struct lim_channel_status
851 *channel_stat)
852{
853 uint32_t noise_floor_weight;
854 uint8_t softap_nf_weight_cfg;
855 uint8_t softap_nf_weight_local;
856
857 softap_nf_weight_cfg =
858 ACS_WEIGHT_SOFTAP_NOISE_FLOOR_CFG
859 (sap_ctx->auto_channel_select_weight);
860
861 softap_nf_weight_local =
862 ACS_WEIGHT_CFG_TO_LOCAL(sap_ctx->auto_channel_select_weight,
863 softap_nf_weight_cfg);
864
865 if (channel_stat == NULL || channel_stat->channelfreq == 0) {
866 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
867 "In %s, sanity check failed return max weight",
868 __func__);
869 return softap_nf_weight_local;
870 }
871
872 noise_floor_weight = (channel_stat->noise_floor == 0) ? 0 :
873 (ACS_WEIGHT_COMPUTE(
874 sap_ctx->auto_channel_select_weight,
875 softap_nf_weight_cfg,
876 channel_stat->noise_floor -
877 SOFTAP_MIN_NF,
878 SOFTAP_MAX_NF - SOFTAP_MIN_NF));
879
880 if (noise_floor_weight > softap_nf_weight_local)
881 noise_floor_weight = softap_nf_weight_local;
882 else if (noise_floor_weight < 0)
883 noise_floor_weight = 0;
884
885 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
886 "In %s, nf=%d, nfwc=%d, nfwl=%d, nfw=%d",
887 __func__, channel_stat->noise_floor,
888 softap_nf_weight_cfg, softap_nf_weight_local,
889 noise_floor_weight);
890
891 return noise_floor_weight;
892}
893
894/**
895 * sap_weight_channel_free() - compute channel free weight
896 * @sap_ctx: sap context
897 * @chn_stat: Pointer to chan status info
898 *
899 * Return: channel free weight
900 */
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -0700901static uint32_t sap_weight_channel_free(struct sap_context *sap_ctx,
gaoleze5108942017-03-31 16:56:42 +0800902 struct lim_channel_status
903 *channel_stat)
904{
905 uint32_t channel_free_weight;
906 uint8_t softap_channel_free_weight_cfg;
907 uint8_t softap_channel_free_weight_local;
908 uint32_t rx_clear_count = 0;
909 uint32_t cycle_count = 0;
910
911 softap_channel_free_weight_cfg =
912 ACS_WEIGHT_SOFTAP_CHANNEL_FREE_CFG
913 (sap_ctx->auto_channel_select_weight);
914
915 softap_channel_free_weight_local =
916 ACS_WEIGHT_CFG_TO_LOCAL(sap_ctx->auto_channel_select_weight,
917 softap_channel_free_weight_cfg);
918
919 if (channel_stat == NULL || channel_stat->channelfreq == 0) {
920 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
921 "In %s, sanity check failed return max weight",
922 __func__);
923 return softap_channel_free_weight_local;
924 }
925
926 rx_clear_count = channel_stat->rx_clear_count -
927 channel_stat->tx_frame_count -
928 channel_stat->rx_frame_count;
929 cycle_count = channel_stat->cycle_count;
930
931 /* LSH 4, otherwise it is always 0. */
932 channel_free_weight = (cycle_count == 0) ? 0 :
933 (ACS_WEIGHT_COMPUTE(
934 sap_ctx->auto_channel_select_weight,
935 softap_channel_free_weight_cfg,
936 ((rx_clear_count << 8) +
937 (cycle_count >> 1))/cycle_count -
938 (SOFTAP_MIN_CHNFREE << 8),
939 (SOFTAP_MAX_CHNFREE -
940 SOFTAP_MIN_CHNFREE) << 8));
941
942 if (channel_free_weight > softap_channel_free_weight_local)
943 channel_free_weight = softap_channel_free_weight_local;
944
945 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
946 "In %s, rcc=%d, cc=%d, tc=%d, rc=%d, cfwc=%d, cfwl=%d, cfw=%d",
947 __func__, rx_clear_count, cycle_count,
948 channel_stat->tx_frame_count,
949 channel_stat->rx_frame_count,
950 softap_channel_free_weight_cfg,
951 softap_channel_free_weight_local,
952 channel_free_weight);
953
954 return channel_free_weight;
955}
956
957/**
958 * sap_weight_channel_txpwr_range() - compute channel tx power range weight
959 * @sap_ctx: sap context
960 * @chn_stat: Pointer to chan status info
961 *
962 * Return: tx power range weight
963 */
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -0700964static uint32_t sap_weight_channel_txpwr_range(struct sap_context *sap_ctx,
gaoleze5108942017-03-31 16:56:42 +0800965 struct lim_channel_status
966 *channel_stat)
967{
968 uint32_t txpwr_weight_low_speed;
969 uint8_t softap_txpwr_range_weight_cfg;
970 uint8_t softap_txpwr_range_weight_local;
971
972 softap_txpwr_range_weight_cfg =
973 ACS_WEIGHT_SOFTAP_TX_POWER_RANGE_CFG
974 (sap_ctx->auto_channel_select_weight);
975
976 softap_txpwr_range_weight_local =
977 ACS_WEIGHT_CFG_TO_LOCAL(sap_ctx->auto_channel_select_weight,
978 softap_txpwr_range_weight_cfg);
979
980 if (channel_stat == NULL || channel_stat->channelfreq == 0) {
981 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
982 "In %s, sanity check failed return max weight",
983 __func__);
984 return softap_txpwr_range_weight_local;
985 }
986
987 txpwr_weight_low_speed = (channel_stat->chan_tx_pwr_range == 0) ? 0 :
988 (ACS_WEIGHT_COMPUTE(
989 sap_ctx->auto_channel_select_weight,
990 softap_txpwr_range_weight_cfg,
991 SOFTAP_MAX_TXPWR -
992 channel_stat->chan_tx_pwr_range,
993 SOFTAP_MAX_TXPWR - SOFTAP_MIN_TXPWR));
994
995 if (txpwr_weight_low_speed > softap_txpwr_range_weight_local)
996 txpwr_weight_low_speed = softap_txpwr_range_weight_local;
997
998 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
999 "In %s, tpr=%d, tprwc=%d, tprwl=%d, tprw=%d",
1000 __func__, channel_stat->chan_tx_pwr_range,
1001 softap_txpwr_range_weight_cfg,
1002 softap_txpwr_range_weight_local,
1003 txpwr_weight_low_speed);
1004
1005 return txpwr_weight_low_speed;
1006}
1007
1008/**
1009 * sap_weight_channel_txpwr_tput() - compute channel tx power
1010 * throughput weight
1011 * @sap_ctx: sap context
1012 * @chn_stat: Pointer to chan status info
1013 *
1014 * Return: tx power throughput weight
1015 */
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -07001016static uint32_t sap_weight_channel_txpwr_tput(struct sap_context *sap_ctx,
gaoleze5108942017-03-31 16:56:42 +08001017 struct lim_channel_status
1018 *channel_stat)
1019{
1020 uint32_t txpwr_weight_high_speed;
1021 uint8_t softap_txpwr_tput_weight_cfg;
1022 uint8_t softap_txpwr_tput_weight_local;
1023
1024 softap_txpwr_tput_weight_cfg =
1025 ACS_WEIGHT_SOFTAP_TX_POWER_THROUGHPUT_CFG
1026 (sap_ctx->auto_channel_select_weight);
1027
1028 softap_txpwr_tput_weight_local =
1029 ACS_WEIGHT_CFG_TO_LOCAL(sap_ctx->auto_channel_select_weight,
1030 softap_txpwr_tput_weight_cfg);
1031
1032 if (channel_stat == NULL || channel_stat->channelfreq == 0) {
1033 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
1034 "In %s, sanity check failed return max weight",
1035 __func__);
1036 return softap_txpwr_tput_weight_local;
1037 }
1038
1039 txpwr_weight_high_speed = (channel_stat->chan_tx_pwr_throughput == 0)
1040 ? 0 : (ACS_WEIGHT_COMPUTE(
1041 sap_ctx->auto_channel_select_weight,
1042 softap_txpwr_tput_weight_cfg,
1043 SOFTAP_MAX_TXPWR -
1044 channel_stat->chan_tx_pwr_throughput,
1045 SOFTAP_MAX_TXPWR - SOFTAP_MIN_TXPWR));
1046
1047 if (txpwr_weight_high_speed > softap_txpwr_tput_weight_local)
1048 txpwr_weight_high_speed = softap_txpwr_tput_weight_local;
1049
1050 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
1051 "In %s, tpt=%d, tptwc=%d, tptwl=%d, tptw=%d",
1052 __func__, channel_stat->chan_tx_pwr_throughput,
1053 softap_txpwr_tput_weight_cfg,
1054 softap_txpwr_tput_weight_local,
1055 txpwr_weight_high_speed);
1056
1057 return txpwr_weight_high_speed;
1058}
1059
1060/**
1061 * sap_weight_channel_status() - compute chan status weight
1062 * @sap_ctx: sap context
1063 * @chn_stat: Pointer to chan status info
1064 *
1065 * Return: chan status weight
1066 */
1067static
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -07001068uint32_t sap_weight_channel_status(struct sap_context *sap_ctx,
gaoleze5108942017-03-31 16:56:42 +08001069 struct lim_channel_status *channel_stat)
1070{
1071 return sap_weight_channel_noise_floor(sap_ctx, channel_stat) +
1072 sap_weight_channel_free(sap_ctx, channel_stat) +
1073 sap_weight_channel_txpwr_range(sap_ctx, channel_stat) +
1074 sap_weight_channel_txpwr_tput(sap_ctx, channel_stat);
1075}
1076
1077/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001078 * sap_update_rssi_bsscount() - updates bss count and rssi effect.
1079 *
1080 * @pSpectCh: Channel Information
1081 * @offset: Channel Offset
1082 * @sap_24g: Channel is in 2.4G or 5G
Liangwei Dong71ed6502016-10-20 03:40:45 -04001083 * @spectch_start: the start of spect ch array
1084 * @spectch_end: the end of spect ch array
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001085 *
1086 * sap_update_rssi_bsscount updates bss count and rssi effect based
1087 * on the channel offset.
1088 *
1089 * Return: None.
1090 */
1091
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001092static void sap_update_rssi_bsscount(tSapSpectChInfo *pSpectCh, int32_t offset,
Liangwei Dong71ed6502016-10-20 03:40:45 -04001093 bool sap_24g, tSapSpectChInfo *spectch_start,
1094 tSapSpectChInfo *spectch_end)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001095{
1096 tSapSpectChInfo *pExtSpectCh = NULL;
1097 int32_t rssi, rsssi_effect;
1098
1099 pExtSpectCh = (pSpectCh + offset);
Liangwei Dong71ed6502016-10-20 03:40:45 -04001100 if (pExtSpectCh != NULL &&
1101 pExtSpectCh >= spectch_start &&
1102 pExtSpectCh < spectch_end) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001103 ++pExtSpectCh->bssCount;
1104 switch (offset) {
1105 case -1:
1106 case 1:
1107 rsssi_effect = sap_24g ?
1108 SAP_24GHZ_FIRST_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY :
1109 SAP_SUBBAND1_RSSI_EFFECT_PRIMARY;
1110 break;
1111 case -2:
1112 case 2:
1113 rsssi_effect = sap_24g ?
1114 SAP_24GHZ_SEC_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY :
1115 SAP_SUBBAND2_RSSI_EFFECT_PRIMARY;
1116 break;
1117 case -3:
1118 case 3:
1119 rsssi_effect = sap_24g ?
1120 SAP_24GHZ_THIRD_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY :
1121 SAP_SUBBAND3_RSSI_EFFECT_PRIMARY;
1122 break;
1123 case -4:
1124 case 4:
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001125 rsssi_effect = sap_24g ?
1126 SAP_24GHZ_FOURTH_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY :
1127 SAP_SUBBAND4_RSSI_EFFECT_PRIMARY;
1128 break;
1129 case -5:
1130 case 5:
1131 rsssi_effect = SAP_SUBBAND5_RSSI_EFFECT_PRIMARY;
1132 break;
1133 case -6:
1134 case 6:
1135 rsssi_effect = SAP_SUBBAND6_RSSI_EFFECT_PRIMARY;
1136 break;
1137 case -7:
1138 case 7:
1139 rsssi_effect = SAP_SUBBAND7_RSSI_EFFECT_PRIMARY;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001140 break;
1141 default:
1142 rsssi_effect = 0;
1143 break;
1144 }
1145
1146 rssi = pSpectCh->rssiAgr + rsssi_effect;
1147 if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi))
1148 pExtSpectCh->rssiAgr = rssi;
1149 if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI)
1150 pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI;
1151 }
1152}
1153
1154/**
1155 * sap_upd_chan_spec_params() - sap_upd_chan_spec_params
1156 * updates channel parameters obtained from Beacon
1157 * @pBeaconStruct Beacon strucutre populated by parse_beacon function
1158 * @channelWidth Channel width
1159 * @secondaryChannelOffset Secondary Channel Offset
1160 * @vhtSupport If channel supports VHT
1161 * @centerFreq Central frequency for the given channel.
1162 *
1163 * sap_upd_chan_spec_params updates the spectrum channels based on the
1164 * pBeaconStruct obtained from Beacon IE
1165 *
1166 * Return: NA.
1167 */
1168
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001169static void sap_upd_chan_spec_params(tSirProbeRespBeacon *pBeaconStruct,
1170 uint16_t *channelWidth,
1171 uint16_t *secondaryChannelOffset,
1172 uint16_t *vhtSupport,
1173 uint16_t *centerFreq,
1174 uint16_t *centerFreq_2)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001175{
1176 if (NULL == pBeaconStruct) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301177 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001178 FL("pBeaconStruct is NULL"));
1179 return;
1180 }
1181
1182 if (pBeaconStruct->HTCaps.present && pBeaconStruct->HTInfo.present) {
1183 *channelWidth = pBeaconStruct->HTCaps.supportedChannelWidthSet;
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001184 *secondaryChannelOffset =
1185 pBeaconStruct->HTInfo.secondaryChannelOffset;
1186 if (!pBeaconStruct->VHTOperation.present)
1187 return;
1188 *vhtSupport = pBeaconStruct->VHTOperation.present;
1189 if (pBeaconStruct->VHTOperation.chanWidth) {
1190 *centerFreq =
1191 pBeaconStruct->VHTOperation.chanCenterFreqSeg1;
1192 *centerFreq_2 =
1193 pBeaconStruct->VHTOperation.chanCenterFreqSeg2;
1194 /*
1195 * LHS follows tSirMacHTChannelWidth, while RHS follows
1196 * WNI_CFG_VHT_CHANNEL_WIDTH_X format hence following
1197 * adjustment
1198 */
1199 *channelWidth =
1200 pBeaconStruct->VHTOperation.chanWidth + 1;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001201
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001202 }
1203 }
1204}
1205
1206/**
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001207 * sap_update_rssi_bsscount_vht_5G() - updates bss count and rssi effect.
1208 *
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001209 * @spect_ch: Channel Information
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001210 * @offset: Channel Offset
1211 * @num_ch: no.of channels
Liangwei Dong71ed6502016-10-20 03:40:45 -04001212 * @spectch_start: the start of spect ch array
1213 * @spectch_end: the end of spect ch array
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001214 *
1215 * sap_update_rssi_bsscount_vht_5G updates bss count and rssi effect based
1216 * on the channel offset.
1217 *
1218 * Return: None.
1219 */
1220
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001221static void sap_update_rssi_bsscount_vht_5G(tSapSpectChInfo *spect_ch,
1222 int32_t offset,
Liangwei Dong71ed6502016-10-20 03:40:45 -04001223 uint16_t num_ch,
1224 tSapSpectChInfo *spectch_start,
1225 tSapSpectChInfo *spectch_end)
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001226{
1227 int32_t ch_offset;
1228 uint16_t i, cnt;
1229
1230 if (!offset)
1231 return;
1232 if (offset > 0)
1233 cnt = num_ch;
1234 else
1235 cnt = num_ch + 1;
1236 for (i = 0; i < cnt; i++) {
1237 ch_offset = offset + i;
1238 if (ch_offset == 0)
1239 continue;
Liangwei Dong71ed6502016-10-20 03:40:45 -04001240 sap_update_rssi_bsscount(spect_ch, ch_offset, false,
1241 spectch_start, spectch_end);
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001242 }
1243}
1244/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001245 * sap_interference_rssi_count_5G() - sap_interference_rssi_count
1246 * considers the Adjacent channel rssi and
1247 * data count(here number of BSS observed)
1248 * @spect_ch: Channel Information
1249 * @chan_width: Channel width parsed from beacon IE
1250 * @sec_chan_offset: Secondary Channel Offset
1251 * @center_freq: Central frequency for the given channel.
1252 * @channel_id: channel_id
Liangwei Dong71ed6502016-10-20 03:40:45 -04001253 * @spectch_start: the start of spect ch array
1254 * @spectch_end: the end of spect ch array
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001255 *
1256 * sap_interference_rssi_count_5G considers the Adjacent channel rssi
1257 * and data count(here number of BSS observed)
1258 *
1259 * Return: NA.
1260 */
1261
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001262static void sap_interference_rssi_count_5G(tSapSpectChInfo *spect_ch,
1263 uint16_t chan_width,
1264 uint16_t sec_chan_offset,
1265 uint16_t center_freq,
1266 uint16_t center_freq_2,
Liangwei Dong71ed6502016-10-20 03:40:45 -04001267 uint8_t channel_id,
1268 tSapSpectChInfo *spectch_start,
1269 tSapSpectChInfo *spectch_end)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001270{
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001271 uint16_t num_ch;
1272 int32_t offset = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001273 if (NULL == spect_ch) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301274 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001275 FL("spect_ch is NULL"));
1276 return;
1277 }
1278
1279 /* Updating the received ChannelWidth */
1280 if (spect_ch->channelWidth != chan_width)
1281 spect_ch->channelWidth = chan_width;
1282 /* If received ChannelWidth is other than HT20,
1283 * we need to update the extension channel Params as well
1284 * chan_width == 0, HT20
1285 * chan_width == 1, HT40
1286 * chan_width == 2, VHT80
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001287 * chan_width == 3, VHT160
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001288 */
1289
1290 switch (spect_ch->channelWidth) {
1291 case eHT_CHANNEL_WIDTH_40MHZ: /* HT40 */
1292 switch (sec_chan_offset) {
1293 /* Above the Primary Channel */
1294 case PHY_DOUBLE_CHANNEL_LOW_PRIMARY:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001295 sap_update_rssi_bsscount(spect_ch, 1, false,
1296 spectch_start, spectch_end);
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001297 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001298
1299 /* Below the Primary channel */
1300 case PHY_DOUBLE_CHANNEL_HIGH_PRIMARY:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001301 sap_update_rssi_bsscount(spect_ch, -1, false,
1302 spectch_start, spectch_end);
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001303 return;
1304 }
1305 return;
1306 case eHT_CHANNEL_WIDTH_80MHZ: /* VHT80 */
1307 num_ch = 3;
1308 if ((center_freq - channel_id) == 6) {
1309 offset = 1;
1310 } else if ((center_freq - channel_id) == 2) {
1311 offset = -1;
1312 } else if ((center_freq - channel_id) == -2) {
1313 offset = -2;
1314 } else if ((center_freq - channel_id) == -6) {
1315 offset = -3;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001316 }
1317 break;
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001318 case eHT_CHANNEL_WIDTH_160MHZ: /* VHT160 */
1319 num_ch = 7;
1320 if ((center_freq - channel_id) == 14)
1321 offset = 1;
1322 else if ((center_freq - channel_id) == 10)
1323 offset = -1;
1324 else if ((center_freq - channel_id) == 6)
1325 offset = -2;
1326 else if ((center_freq - channel_id) == 2)
1327 offset = -3;
1328 else if ((center_freq - channel_id) == -2)
1329 offset = -4;
1330 else if ((center_freq - channel_id) == -6)
1331 offset = -5;
1332 else if ((center_freq - channel_id) == -10)
1333 offset = -6;
1334 else if ((center_freq - channel_id) == -14)
1335 offset = -7;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001336 break;
1337 default:
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001338 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001339 }
Liangwei Dong71ed6502016-10-20 03:40:45 -04001340 sap_update_rssi_bsscount_vht_5G(spect_ch, offset, num_ch,
1341 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001342}
1343
1344/**
1345 * sap_interference_rssi_count() - sap_interference_rssi_count
1346 * considers the Adjacent channel rssi
1347 * and data count(here number of BSS observed)
1348 * @spect_ch Channel Information
Liangwei Dong71ed6502016-10-20 03:40:45 -04001349 * @spectch_start: the start of spect ch array
1350 * @spectch_end: the end of spect ch array
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001351 *
1352 * sap_interference_rssi_count considers the Adjacent channel rssi
1353 * and data count(here number of BSS observed)
1354 *
1355 * Return: None.
1356 */
1357
Liangwei Dong71ed6502016-10-20 03:40:45 -04001358static void sap_interference_rssi_count(tSapSpectChInfo *spect_ch,
1359 tSapSpectChInfo *spectch_start,
1360 tSapSpectChInfo *spectch_end)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001361{
1362 if (NULL == spect_ch) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301363 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001364 "%s: spect_ch is NULL", __func__);
1365 return;
1366 }
1367
1368 switch (spect_ch->chNum) {
1369 case CHANNEL_1:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001370 sap_update_rssi_bsscount(spect_ch, 1, true,
1371 spectch_start, spectch_end);
1372 sap_update_rssi_bsscount(spect_ch, 2, true,
1373 spectch_start, spectch_end);
1374 sap_update_rssi_bsscount(spect_ch, 3, true,
1375 spectch_start, spectch_end);
1376 sap_update_rssi_bsscount(spect_ch, 4, true,
1377 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001378 break;
1379
1380 case CHANNEL_2:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001381 sap_update_rssi_bsscount(spect_ch, -1, true,
1382 spectch_start, spectch_end);
1383 sap_update_rssi_bsscount(spect_ch, 1, true,
1384 spectch_start, spectch_end);
1385 sap_update_rssi_bsscount(spect_ch, 2, true,
1386 spectch_start, spectch_end);
1387 sap_update_rssi_bsscount(spect_ch, 3, true,
1388 spectch_start, spectch_end);
1389 sap_update_rssi_bsscount(spect_ch, 4, true,
1390 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001391 break;
1392 case CHANNEL_3:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001393 sap_update_rssi_bsscount(spect_ch, -2, true,
1394 spectch_start, spectch_end);
1395 sap_update_rssi_bsscount(spect_ch, -1, true,
1396 spectch_start, spectch_end);
1397 sap_update_rssi_bsscount(spect_ch, 1, true,
1398 spectch_start, spectch_end);
1399 sap_update_rssi_bsscount(spect_ch, 2, true,
1400 spectch_start, spectch_end);
1401 sap_update_rssi_bsscount(spect_ch, 3, true,
1402 spectch_start, spectch_end);
1403 sap_update_rssi_bsscount(spect_ch, 4, true,
1404 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001405 break;
1406 case CHANNEL_4:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001407 sap_update_rssi_bsscount(spect_ch, -3, true,
1408 spectch_start, spectch_end);
1409 sap_update_rssi_bsscount(spect_ch, -2, true,
1410 spectch_start, spectch_end);
1411 sap_update_rssi_bsscount(spect_ch, -1, true,
1412 spectch_start, spectch_end);
1413 sap_update_rssi_bsscount(spect_ch, 1, true,
1414 spectch_start, spectch_end);
1415 sap_update_rssi_bsscount(spect_ch, 2, true,
1416 spectch_start, spectch_end);
1417 sap_update_rssi_bsscount(spect_ch, 3, true,
1418 spectch_start, spectch_end);
1419 sap_update_rssi_bsscount(spect_ch, 4, true,
1420 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001421 break;
1422
1423 case CHANNEL_5:
1424 case CHANNEL_6:
1425 case CHANNEL_7:
1426 case CHANNEL_8:
1427 case CHANNEL_9:
1428 case CHANNEL_10:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001429 sap_update_rssi_bsscount(spect_ch, -4, true,
1430 spectch_start, spectch_end);
1431 sap_update_rssi_bsscount(spect_ch, -3, true,
1432 spectch_start, spectch_end);
1433 sap_update_rssi_bsscount(spect_ch, -2, true,
1434 spectch_start, spectch_end);
1435 sap_update_rssi_bsscount(spect_ch, -1, true,
1436 spectch_start, spectch_end);
1437 sap_update_rssi_bsscount(spect_ch, 1, true,
1438 spectch_start, spectch_end);
1439 sap_update_rssi_bsscount(spect_ch, 2, true,
1440 spectch_start, spectch_end);
1441 sap_update_rssi_bsscount(spect_ch, 3, true,
1442 spectch_start, spectch_end);
1443 sap_update_rssi_bsscount(spect_ch, 4, true,
1444 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001445 break;
1446
1447 case CHANNEL_11:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001448 sap_update_rssi_bsscount(spect_ch, -4, true,
1449 spectch_start, spectch_end);
1450 sap_update_rssi_bsscount(spect_ch, -3, true,
1451 spectch_start, spectch_end);
1452 sap_update_rssi_bsscount(spect_ch, -2, true,
1453 spectch_start, spectch_end);
1454 sap_update_rssi_bsscount(spect_ch, -1, true,
1455 spectch_start, spectch_end);
1456 sap_update_rssi_bsscount(spect_ch, 1, true,
1457 spectch_start, spectch_end);
1458 sap_update_rssi_bsscount(spect_ch, 2, true,
1459 spectch_start, spectch_end);
1460 sap_update_rssi_bsscount(spect_ch, 3, true,
1461 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001462 break;
1463
1464 case CHANNEL_12:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001465 sap_update_rssi_bsscount(spect_ch, -4, true,
1466 spectch_start, spectch_end);
1467 sap_update_rssi_bsscount(spect_ch, -3, true,
1468 spectch_start, spectch_end);
1469 sap_update_rssi_bsscount(spect_ch, -2, true,
1470 spectch_start, spectch_end);
1471 sap_update_rssi_bsscount(spect_ch, -1, true,
1472 spectch_start, spectch_end);
1473 sap_update_rssi_bsscount(spect_ch, 1, true,
1474 spectch_start, spectch_end);
1475 sap_update_rssi_bsscount(spect_ch, 2, true,
1476 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001477 break;
1478
1479 case CHANNEL_13:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001480 sap_update_rssi_bsscount(spect_ch, -4, true,
1481 spectch_start, spectch_end);
1482 sap_update_rssi_bsscount(spect_ch, -3, true,
1483 spectch_start, spectch_end);
1484 sap_update_rssi_bsscount(spect_ch, -2, true,
1485 spectch_start, spectch_end);
1486 sap_update_rssi_bsscount(spect_ch, -1, true,
1487 spectch_start, spectch_end);
1488 sap_update_rssi_bsscount(spect_ch, 1, true,
1489 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001490 break;
1491
1492 case CHANNEL_14:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001493 sap_update_rssi_bsscount(spect_ch, -4, true,
1494 spectch_start, spectch_end);
1495 sap_update_rssi_bsscount(spect_ch, -3, true,
1496 spectch_start, spectch_end);
1497 sap_update_rssi_bsscount(spect_ch, -2, true,
1498 spectch_start, spectch_end);
1499 sap_update_rssi_bsscount(spect_ch, -1, true,
1500 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001501 break;
1502
1503 default:
1504 break;
1505 }
1506}
1507
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001508/**
1509 * ch_in_pcl() - Is channel in the Preferred Channel List (PCL)
1510 * @sap_ctx: SAP context which contains the current PCL
1511 * @channel: Input channel number to be checked
1512 *
1513 * Check if a channel is in the preferred channel list
1514 *
1515 * Return:
1516 * true: channel is in PCL,
1517 * false: channel is not in PCL
1518 */
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -07001519static bool ch_in_pcl(struct sap_context *sap_ctx, uint8_t channel)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001520{
1521 uint32_t i;
1522
1523 for (i = 0; i < sap_ctx->acs_cfg->pcl_ch_count; i++) {
1524 if (channel == sap_ctx->acs_cfg->pcl_channels[i])
1525 return true;
1526 }
1527
1528 return false;
1529}
1530
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001531/**
1532 * sap_compute_spect_weight() - Compute spectrum weight
1533 * @pSpectInfoParams: Pointer to the tSpectInfoParams structure
1534 * @halHandle: Pointer to HAL handle
1535 * @pResult: Pointer to tScanResultHandle
1536 * @sap_ctx: Context of the SAP
1537 *
1538 * Main function for computing the weight of each channel in the
1539 * spectrum based on the RSSI value of the BSSes on the channel
1540 * and number of BSS
1541 */
1542static void sap_compute_spect_weight(tSapChSelSpectInfo *pSpectInfoParams,
1543 tHalHandle halHandle,
1544 tScanResultHandle pResult,
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -07001545 struct sap_context *sap_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001546{
1547 int8_t rssi = 0;
1548 uint8_t chn_num = 0;
1549 uint8_t channel_id = 0;
1550
1551 tCsrScanResultInfo *pScanResult;
1552 tSapSpectChInfo *pSpectCh = pSpectInfoParams->pSpectCh;
1553 uint32_t operatingBand;
1554 uint16_t channelWidth;
1555 uint16_t secondaryChannelOffset;
1556 uint16_t centerFreq;
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001557 uint16_t centerFreq_2 = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001558 uint16_t vhtSupport;
1559 uint32_t ieLen = 0;
1560 tSirProbeRespBeacon *pBeaconStruct;
1561 tpAniSirGlobal pMac = (tpAniSirGlobal) halHandle;
Liangwei Dong71ed6502016-10-20 03:40:45 -04001562 tSapSpectChInfo *spectch_start = pSpectInfoParams->pSpectCh;
1563 tSapSpectChInfo *spectch_end = pSpectInfoParams->pSpectCh +
1564 pSpectInfoParams->numSpectChans;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001565
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301566 pBeaconStruct = qdf_mem_malloc(sizeof(tSirProbeRespBeacon));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001567 if (NULL == pBeaconStruct) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301568 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Kaushik, Sushantee3ed032016-08-04 16:40:46 +05301569 "Unable to allocate memory in sap_compute_spect_weight");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001570 return;
1571 }
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301572 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001573 "In %s, Computing spectral weight", __func__);
1574
1575 /**
1576 * Soft AP specific channel weight calculation using DFS formula
1577 */
1578 SET_ACS_BAND(operatingBand, sap_ctx);
1579
1580 pScanResult = sme_scan_result_get_first(halHandle, pResult);
1581
1582 while (pScanResult) {
1583 pSpectCh = pSpectInfoParams->pSpectCh;
1584 /* Defining the default values, so that any value will hold the default values */
1585 channelWidth = eHT_CHANNEL_WIDTH_20MHZ;
1586 secondaryChannelOffset = PHY_SINGLE_CHANNEL_CENTERED;
1587 vhtSupport = 0;
1588 centerFreq = 0;
1589
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001590
Yingying Tang22facc12016-10-20 17:43:59 +08001591 ieLen = GET_IE_LEN_IN_BSS(
1592 pScanResult->BssDescriptor.length);
1593 qdf_mem_set((uint8_t *) pBeaconStruct,
1594 sizeof(tSirProbeRespBeacon), 0);
1595
1596
1597 if ((sir_parse_beacon_ie
1598 (pMac, pBeaconStruct, (uint8_t *)
1599 (pScanResult->BssDescriptor.ieFields),
1600 ieLen)) == eSIR_SUCCESS)
1601 sap_upd_chan_spec_params(
1602 pBeaconStruct,
1603 &channelWidth,
1604 &secondaryChannelOffset,
1605 &vhtSupport, &centerFreq,
1606 &centerFreq_2);
1607
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001608 /* Processing for each tCsrScanResultInfo in the tCsrScanResult DLink list */
1609 for (chn_num = 0; chn_num < pSpectInfoParams->numSpectChans;
1610 chn_num++) {
1611
1612 /*
1613 * if the Beacon has channel ID, use it other wise we will
1614 * rely on the channelIdSelf
1615 */
1616 if (pScanResult->BssDescriptor.channelId == 0)
1617 channel_id =
1618 pScanResult->BssDescriptor.channelIdSelf;
1619 else
1620 channel_id =
1621 pScanResult->BssDescriptor.channelId;
1622
1623 if (pSpectCh && (channel_id == pSpectCh->chNum)) {
1624 if (pSpectCh->rssiAgr <
1625 pScanResult->BssDescriptor.rssi)
1626 pSpectCh->rssiAgr =
1627 pScanResult->BssDescriptor.rssi;
1628
1629 ++pSpectCh->bssCount; /* Increment the count of BSS */
1630
1631 /*
1632 * Connsidering the Extension Channel
1633 * only in a channels
1634 */
1635 switch (operatingBand) {
1636 case eCSR_DOT11_MODE_11a:
1637 sap_interference_rssi_count_5G(
1638 pSpectCh, channelWidth,
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001639 secondaryChannelOffset,
1640 centerFreq,
1641 centerFreq_2,
Liangwei Dong71ed6502016-10-20 03:40:45 -04001642 channel_id,
1643 spectch_start,
1644 spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001645 break;
1646
1647 case eCSR_DOT11_MODE_11g:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001648 sap_interference_rssi_count(pSpectCh,
1649 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001650 break;
1651
1652 case eCSR_DOT11_MODE_abg:
1653 sap_interference_rssi_count_5G(
1654 pSpectCh, channelWidth,
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001655 secondaryChannelOffset,
1656 centerFreq,
1657 centerFreq_2,
Liangwei Dong71ed6502016-10-20 03:40:45 -04001658 channel_id,
1659 spectch_start,
1660 spectch_end);
1661 sap_interference_rssi_count(pSpectCh,
1662 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001663 break;
1664 }
1665
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301666 QDF_TRACE(QDF_MODULE_ID_SAP,
1667 QDF_TRACE_LEVEL_INFO_HIGH,
Kaushik, Sushantee3ed032016-08-04 16:40:46 +05301668 "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 -08001669 __func__,
1670 pScanResult->BssDescriptor.
1671 channelIdSelf,
1672 pScanResult->BssDescriptor.channelId,
1673 pScanResult->BssDescriptor.rssi,
1674 pSpectCh->bssCount, pScanResult,
1675 pSpectCh->channelWidth,
1676 secondaryChannelOffset, centerFreq);
1677 pSpectCh++;
1678 break;
1679 } else {
1680 pSpectCh++;
1681 }
1682 }
1683
1684 pScanResult = sme_scan_result_get_next(halHandle, pResult);
1685 }
1686
1687 /* Calculate the weights for all channels in the spectrum pSpectCh */
1688 pSpectCh = pSpectInfoParams->pSpectCh;
1689
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301690 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001691 "In %s, Spectrum Channels Weight", __func__);
1692
1693 for (chn_num = 0; chn_num < (pSpectInfoParams->numSpectChans);
1694 chn_num++) {
1695
1696 /*
1697 rssi : Maximum received signal strength among all BSS on that channel
1698 bssCount : Number of BSS on that channel
1699 */
1700
1701 rssi = (int8_t) pSpectCh->rssiAgr;
1702 if (ch_in_pcl(sap_ctx, chn_num))
1703 rssi -= PCL_RSSI_DISCOUNT;
1704
1705 pSpectCh->weight =
gaoleze5108942017-03-31 16:56:42 +08001706 SAPDFS_NORMALISE_1000 *
1707 (sapweight_rssi_count(sap_ctx, rssi,
1708 pSpectCh->bssCount) + sap_weight_channel_status(
1709 sap_ctx, sap_get_channel_status(pMac,
1710 pSpectCh->chNum)));
1711 if (pSpectCh->weight > SAP_ACS_WEIGHT_MAX)
1712 pSpectCh->weight = SAP_ACS_WEIGHT_MAX;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001713 pSpectCh->weight_copy = pSpectCh->weight;
1714
1715 /* ------ Debug Info ------ */
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301716 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001717 "In %s, Chan=%d Weight= %d rssiAgr=%d bssCount=%d",
1718 __func__, pSpectCh->chNum, pSpectCh->weight,
1719 pSpectCh->rssiAgr, pSpectCh->bssCount);
1720 /* ------ Debug Info ------ */
1721 pSpectCh++;
1722 }
gaoleze5108942017-03-31 16:56:42 +08001723 sap_clear_channel_status(pMac);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301724 qdf_mem_free(pBeaconStruct);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001725}
1726
1727/*==========================================================================
1728 FUNCTION sap_chan_sel_exit
1729
1730 DESCRIPTION
1731 Exit function for free out the allocated memory, to be called
1732 at the end of the dfsSelectChannel function
1733
1734 DEPENDENCIES
1735 NA.
1736
1737 PARAMETERS
1738
1739 IN
1740 pSpectInfoParams : Pointer to the tSapChSelSpectInfo structure
1741
1742 RETURN VALUE
1743 void : NULL
1744
1745 SIDE EFFECTS
1746 ============================================================================*/
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001747static void sap_chan_sel_exit(tSapChSelSpectInfo *pSpectInfoParams)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001748{
1749 /* Free all the allocated memory */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301750 qdf_mem_free(pSpectInfoParams->pSpectCh);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001751}
1752
1753/*==========================================================================
1754 FUNCTION sap_sort_chl_weight
1755
1756 DESCRIPTION
1757 Funtion to sort the channels with the least weight first for 20MHz channels
1758
1759 DEPENDENCIES
1760 NA.
1761
1762 PARAMETERS
1763
1764 IN
1765 pSpectInfoParams : Pointer to the tSapChSelSpectInfo structure
1766
1767 RETURN VALUE
1768 void : NULL
1769
1770 SIDE EFFECTS
1771 ============================================================================*/
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001772static void sap_sort_chl_weight(tSapChSelSpectInfo *pSpectInfoParams)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001773{
1774 tSapSpectChInfo temp;
1775
1776 tSapSpectChInfo *pSpectCh = NULL;
1777 uint32_t i = 0, j = 0, minWeightIndex = 0;
1778
1779 pSpectCh = pSpectInfoParams->pSpectCh;
1780 for (i = 0; i < pSpectInfoParams->numSpectChans; i++) {
1781 minWeightIndex = i;
1782 for (j = i + 1; j < pSpectInfoParams->numSpectChans; j++) {
1783 if (pSpectCh[j].weight <
1784 pSpectCh[minWeightIndex].weight) {
1785 minWeightIndex = j;
1786 }
1787 }
1788 if (minWeightIndex != i) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301789 qdf_mem_copy(&temp, &pSpectCh[minWeightIndex],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001790 sizeof(*pSpectCh));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301791 qdf_mem_copy(&pSpectCh[minWeightIndex], &pSpectCh[i],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001792 sizeof(*pSpectCh));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301793 qdf_mem_copy(&pSpectCh[i], &temp, sizeof(*pSpectCh));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001794 }
1795 }
1796}
1797
1798/**
bingse2782382017-03-23 10:34:52 +08001799 * set_ht80_chl_bit() - to set availabe channel to ht80 channel bitmap
1800 * @channel_bitmap: Pointer to the chan_bonding_bitmap structure
1801 * @spect_info_params: Pointer to the tSapChSelSpectInfo structure
1802 *
1803 * Return: none
1804 */
1805static void set_ht80_chl_bit(chan_bonding_bitmap *channel_bitmap,
1806 tSapChSelSpectInfo *spec_info_params)
1807{
1808 uint8_t i, j;
1809 tSapSpectChInfo *spec_info;
1810 int start_channel = 0;
1811
1812 channel_bitmap->chanBondingSet[0].startChannel =
1813 acs_ht80_channels[0].chStartNum;
1814 channel_bitmap->chanBondingSet[1].startChannel =
1815 acs_ht80_channels[1].chStartNum;
1816 channel_bitmap->chanBondingSet[2].startChannel =
1817 acs_ht80_channels[2].chStartNum;
1818 channel_bitmap->chanBondingSet[3].startChannel =
1819 acs_ht80_channels[3].chStartNum;
1820 channel_bitmap->chanBondingSet[4].startChannel =
1821 acs_ht80_channels[4].chStartNum;
1822 channel_bitmap->chanBondingSet[5].startChannel =
1823 acs_ht80_channels[5].chStartNum;
1824
1825 spec_info = spec_info_params->pSpectCh;
1826 for (j = 0; j < spec_info_params->numSpectChans; j++) {
1827 for (i = 0; i < MAX_80MHZ_BANDS; i++) {
1828 start_channel =
1829 channel_bitmap->chanBondingSet[i].startChannel;
1830 if (spec_info[j].chNum >= start_channel &&
1831 (spec_info[j].chNum <= start_channel + 12)) {
1832 channel_bitmap->chanBondingSet[i].channelMap |=
1833 1 << ((spec_info[j].chNum -
1834 start_channel)/4);
1835 break;
1836 }
1837 }
1838 }
1839}
1840
1841/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001842 * sap_sort_chl_weight_ht80() - to sort the channels with the least weight
1843 * @pSpectInfoParams: Pointer to the tSapChSelSpectInfo structure
1844 *
1845 * Funtion to sort the channels with the least weight first for HT80 channels
1846 *
1847 * Return: none
1848 */
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001849static void sap_sort_chl_weight_ht80(tSapChSelSpectInfo *pSpectInfoParams)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001850{
1851 uint8_t i, j, n;
1852 tSapSpectChInfo *pSpectInfo;
1853 uint8_t minIdx;
bingse2782382017-03-23 10:34:52 +08001854 int start_channel = 0;
1855 chan_bonding_bitmap *channel_bitmap;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001856
bingse2782382017-03-23 10:34:52 +08001857 channel_bitmap = qdf_mem_malloc(sizeof(chan_bonding_bitmap));
1858 if (NULL == channel_bitmap) {
1859 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG,
1860 "%s: Failed to allocate memory", __func__);
1861 return;
1862 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001863 pSpectInfo = pSpectInfoParams->pSpectCh;
1864 /* for each HT80 channel, calculate the combined weight of the
1865 four 20MHz weight */
1866 for (i = 0; i < ARRAY_SIZE(acs_ht80_channels); i++) {
1867 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
1868 if (pSpectInfo[j].chNum ==
1869 acs_ht80_channels[i].chStartNum)
1870 break;
1871 }
1872 if (j == pSpectInfoParams->numSpectChans)
1873 continue;
1874
1875 if (!(((pSpectInfo[j].chNum + 4) == pSpectInfo[j + 1].chNum) &&
1876 ((pSpectInfo[j].chNum + 8) ==
1877 pSpectInfo[j + 2].chNum) &&
1878 ((pSpectInfo[j].chNum + 12) ==
1879 pSpectInfo[j + 3].chNum))) {
1880 /*
1881 * some channels does not exist in pSectInfo array,
1882 * skip this channel and those in the same HT80 width
1883 */
1884 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 4;
1885 if ((pSpectInfo[j].chNum + 4) ==
1886 pSpectInfo[j + 1].chNum)
1887 pSpectInfo[j + 1].weight =
1888 SAP_ACS_WEIGHT_MAX * 4;
1889 if ((pSpectInfo[j].chNum + 8) ==
1890 pSpectInfo[j + 2].chNum)
1891 pSpectInfo[j + 2].weight =
1892 SAP_ACS_WEIGHT_MAX * 4;
1893 if ((pSpectInfo[j].chNum + 12) ==
1894 pSpectInfo[j + 3].chNum)
1895 pSpectInfo[j + 3].weight =
1896 SAP_ACS_WEIGHT_MAX * 4;
1897 continue;
1898 }
1899 /*found the channel, add the 4 adjacent channels' weight */
1900 acs_ht80_channels[i].weight = pSpectInfo[j].weight +
1901 pSpectInfo[j + 1].weight + pSpectInfo[j + 2].weight +
1902 pSpectInfo[j + 3].weight;
1903 /* find best channel among 4 channels as the primary channel */
1904 if ((pSpectInfo[j].weight + pSpectInfo[j + 1].weight) <
1905 (pSpectInfo[j + 2].weight + pSpectInfo[j + 3].weight)) {
1906 /* lower 2 channels are better choice */
1907 if (pSpectInfo[j].weight < pSpectInfo[j + 1].weight)
1908 minIdx = 0;
1909 else
1910 minIdx = 1;
1911 } else if (pSpectInfo[j + 2].weight <=
1912 pSpectInfo[j + 3].weight) {
1913 /* upper 2 channels are better choice */
1914 minIdx = 2;
1915 } else {
1916 minIdx = 3;
1917 }
1918
1919 /*
1920 * set all 4 channels to max value first, then reset the
1921 * best channel as the selected primary channel, update its
1922 * weightage with the combined weight value
1923 */
1924 for (n = 0; n < 4; n++)
1925 pSpectInfo[j + n].weight = SAP_ACS_WEIGHT_MAX * 4;
1926
1927 pSpectInfo[j + minIdx].weight = acs_ht80_channels[i].weight;
1928 }
1929
bingse2782382017-03-23 10:34:52 +08001930 /*
1931 * mark the weight of the channel that can't satisfy 80MHZ
1932 * as max value, so that it will be sorted to the bottom
1933 */
1934 set_ht80_chl_bit(channel_bitmap, pSpectInfoParams);
1935 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
1936 for (i = 0; i < MAX_80MHZ_BANDS; i++) {
1937 start_channel =
1938 channel_bitmap->chanBondingSet[i].startChannel;
1939 if (pSpectInfo[j].chNum >= start_channel &&
1940 (pSpectInfo[j].chNum <=
1941 start_channel + 12) &&
1942 channel_bitmap->chanBondingSet[i].channelMap !=
1943 SAP_80MHZ_MASK)
1944 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 4;
1945 }
1946 }
1947
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001948 pSpectInfo = pSpectInfoParams->pSpectCh;
1949 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
1950 if (CHANNEL_165 == pSpectInfo[j].chNum) {
1951 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 4;
1952 break;
1953 }
1954 }
1955
Manishekar Chandrasekaran44e334f2016-05-30 16:42:50 +05301956 sap_sort_chl_weight(pSpectInfoParams);
1957
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001958 pSpectInfo = pSpectInfoParams->pSpectCh;
1959 for (j = 0; j < (pSpectInfoParams->numSpectChans); j++) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301960 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001961 FL("Channel=%d Weight= %d rssi=%d bssCount=%d"),
1962 pSpectInfo->chNum, pSpectInfo->weight,
1963 pSpectInfo->rssiAgr, pSpectInfo->bssCount);
1964 pSpectInfo++;
1965 }
bingse2782382017-03-23 10:34:52 +08001966 qdf_mem_free(channel_bitmap);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001967}
1968
1969/**
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001970 * sap_sort_chl_weight_vht160() - to sort the channels with the least weight
1971 * @pSpectInfoParams: Pointer to the tSapChSelSpectInfo structure
1972 *
1973 * Funtion to sort the channels with the least weight first for VHT160 channels
1974 *
1975 * Return: none
1976 */
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001977static void sap_sort_chl_weight_vht160(tSapChSelSpectInfo *pSpectInfoParams)
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001978{
1979 uint8_t i, j, n, idx;
1980 tSapSpectChInfo *pSpectInfo;
1981 uint8_t minIdx;
1982
1983 pSpectInfo = pSpectInfoParams->pSpectCh;
1984 /* for each VHT160 channel, calculate the combined weight of the
1985 8 20MHz weight */
1986 for (i = 0; i < ARRAY_SIZE(acs_vht160_channels); i++) {
1987 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
1988 if (pSpectInfo[j].chNum ==
1989 acs_vht160_channels[i].chStartNum)
1990 break;
1991 }
1992 if (j == pSpectInfoParams->numSpectChans)
1993 continue;
1994
1995 if (!(((pSpectInfo[j].chNum + 4) == pSpectInfo[j + 1].chNum) &&
1996 ((pSpectInfo[j].chNum + 8) ==
1997 pSpectInfo[j + 2].chNum) &&
1998 ((pSpectInfo[j].chNum + 12) ==
1999 pSpectInfo[j + 3].chNum) &&
2000 ((pSpectInfo[j].chNum + 16) ==
2001 pSpectInfo[j + 4].chNum) &&
2002 ((pSpectInfo[j].chNum + 20) ==
2003 pSpectInfo[j + 5].chNum) &&
2004 ((pSpectInfo[j].chNum + 24) ==
2005 pSpectInfo[j + 6].chNum) &&
2006 ((pSpectInfo[j].chNum + 28) ==
2007 pSpectInfo[j + 7].chNum))) {
2008 /*
2009 * some channels does not exist in pSectInfo array,
2010 * skip this channel and those in the same VHT160 width
2011 */
2012 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 8;
2013 if ((pSpectInfo[j].chNum + 4) ==
2014 pSpectInfo[j + 1].chNum)
2015 pSpectInfo[j + 1].weight =
2016 SAP_ACS_WEIGHT_MAX * 8;
2017 if ((pSpectInfo[j].chNum + 8) ==
2018 pSpectInfo[j + 2].chNum)
2019 pSpectInfo[j + 2].weight =
2020 SAP_ACS_WEIGHT_MAX * 8;
2021 if ((pSpectInfo[j].chNum + 12) ==
2022 pSpectInfo[j + 3].chNum)
2023 pSpectInfo[j + 3].weight =
2024 SAP_ACS_WEIGHT_MAX * 8;
2025 if ((pSpectInfo[j].chNum + 16) ==
2026 pSpectInfo[j + 4].chNum)
2027 pSpectInfo[j + 4].weight =
2028 SAP_ACS_WEIGHT_MAX * 8;
2029 if ((pSpectInfo[j].chNum + 20) ==
2030 pSpectInfo[j + 5].chNum)
2031 pSpectInfo[j + 5].weight =
2032 SAP_ACS_WEIGHT_MAX * 8;
2033 if ((pSpectInfo[j].chNum + 24) ==
2034 pSpectInfo[j + 6].chNum)
2035 pSpectInfo[j + 6].weight =
2036 SAP_ACS_WEIGHT_MAX * 8;
2037 if ((pSpectInfo[j].chNum + 28) ==
2038 pSpectInfo[j + 7].chNum)
2039 pSpectInfo[j + 7].weight =
2040 SAP_ACS_WEIGHT_MAX * 8;
2041 continue;
2042 }
2043 /*found the channel, add the 7 adjacent channels' weight */
2044 acs_vht160_channels[i].weight = pSpectInfo[j].weight +
2045 pSpectInfo[j + 1].weight + pSpectInfo[j + 2].weight +
2046 pSpectInfo[j + 3].weight + pSpectInfo[j + 4].weight +
2047 pSpectInfo[j + 5].weight + pSpectInfo[j + 6].weight +
2048 pSpectInfo[j + 7].weight;
2049
2050 /* find best channel among 8 channels as the primary channel */
2051 if ((pSpectInfo[j].weight + pSpectInfo[j + 1].weight +
2052 pSpectInfo[j + 2].weight + pSpectInfo[j + 3].weight) >
2053 (pSpectInfo[j + 4].weight + pSpectInfo[j + 5].weight +
2054 pSpectInfo[j + 6].weight + pSpectInfo[j + 7].weight))
2055 idx = 4;
2056 else
2057 idx = 0;
2058 /* find best channel among 4 channels as the primary channel */
2059 if ((pSpectInfo[j + idx].weight +
2060 pSpectInfo[j + idx + 1].weight) <
2061 (pSpectInfo[j + idx + 2].weight +
2062 pSpectInfo[j + idx + 3].weight)) {
2063 /* lower 2 channels are better choice */
2064 if (pSpectInfo[j + idx].weight <
2065 pSpectInfo[j + idx + 1].weight)
2066 minIdx = 0 + idx;
2067 else
2068 minIdx = 1 + idx;
2069 } else if (pSpectInfo[j + idx + 2].weight <=
2070 pSpectInfo[j + idx + 3].weight) {
2071 /* upper 2 channels are better choice */
2072 minIdx = 2 + idx;
2073 } else {
2074 minIdx = 3 + idx;
2075 }
2076
2077 /*
2078 * set all 8 channels to max value first, then reset the
2079 * best channel as the selected primary channel, update its
2080 * weightage with the combined weight value
2081 */
2082 for (n = 0; n < 8; n++)
2083 pSpectInfo[j + n].weight = SAP_ACS_WEIGHT_MAX * 8;
2084
2085 pSpectInfo[j + minIdx].weight = acs_vht160_channels[i].weight;
2086 }
2087
2088 pSpectInfo = pSpectInfoParams->pSpectCh;
2089 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
2090 if (CHANNEL_165 == pSpectInfo[j].chNum) {
2091 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 8;
2092 break;
2093 }
2094 }
2095
Manishekar Chandrasekaran44e334f2016-05-30 16:42:50 +05302096 sap_sort_chl_weight(pSpectInfoParams);
2097
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07002098 pSpectInfo = pSpectInfoParams->pSpectCh;
2099 for (j = 0; j < (pSpectInfoParams->numSpectChans); j++) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302100 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07002101 FL("Channel=%d Weight= %d rssi=%d bssCount=%d"),
2102 pSpectInfo->chNum, pSpectInfo->weight,
2103 pSpectInfo->rssiAgr, pSpectInfo->bssCount);
2104 pSpectInfo++;
2105 }
2106}
2107
2108/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002109 * sap_sort_chl_weight_ht40_24_g() - to sort channel with the least weight
2110 * @pSpectInfoParams: Pointer to the tSapChSelSpectInfo structure
2111 *
2112 * Funtion to sort the channels with the least weight first for HT40 channels
2113 *
2114 * Return: none
2115 */
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002116static void sap_sort_chl_weight_ht40_24_g(tSapChSelSpectInfo *pSpectInfoParams,
2117 v_REGDOMAIN_t domain)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002118{
2119 uint8_t i, j;
2120 tSapSpectChInfo *pSpectInfo;
2121 uint32_t tmpWeight1, tmpWeight2;
bingse2782382017-03-23 10:34:52 +08002122 uint32_t ht40plus2gendch = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002123
2124 pSpectInfo = pSpectInfoParams->pSpectCh;
2125 /*
2126 * for each HT40 channel, calculate the combined weight of the
2127 * two 20MHz weight
2128 */
2129 for (i = 0; i < ARRAY_SIZE(acs_ht40_channels24_g); i++) {
2130 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
2131 if (pSpectInfo[j].chNum ==
2132 acs_ht40_channels24_g[i].chStartNum)
2133 break;
2134 }
2135 if (j == pSpectInfoParams->numSpectChans)
2136 continue;
2137
2138 if (!((pSpectInfo[j].chNum + 4) == pSpectInfo[j + 4].chNum)) {
2139 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2;
2140 continue;
2141 }
2142 /*
2143 * check if there is another channel combination possiblity
2144 * e.g., {1, 5} & {5, 9}
2145 */
2146 if ((pSpectInfo[j + 4].chNum + 4) == pSpectInfo[j + 8].chNum) {
2147 /* need to compare two channel pairs */
2148 tmpWeight1 = pSpectInfo[j].weight +
2149 pSpectInfo[j + 4].weight;
2150 tmpWeight2 = pSpectInfo[j + 4].weight +
2151 pSpectInfo[j + 8].weight;
2152 if (tmpWeight1 <= tmpWeight2) {
2153 if (pSpectInfo[j].weight <=
2154 pSpectInfo[j + 4].weight) {
2155 pSpectInfo[j].weight =
2156 tmpWeight1;
2157 pSpectInfo[j + 4].weight =
2158 SAP_ACS_WEIGHT_MAX * 2;
2159 pSpectInfo[j + 8].weight =
2160 SAP_ACS_WEIGHT_MAX * 2;
2161 } else {
2162 pSpectInfo[j + 4].weight =
2163 tmpWeight1;
2164 /* for secondary channel selection */
2165 pSpectInfo[j].weight =
2166 SAP_ACS_WEIGHT_MAX * 2
2167 - 1;
2168 pSpectInfo[j + 8].weight =
2169 SAP_ACS_WEIGHT_MAX * 2;
2170 }
2171 } else {
2172 if (pSpectInfo[j + 4].weight <=
2173 pSpectInfo[j + 8].weight) {
2174 pSpectInfo[j + 4].weight =
2175 tmpWeight2;
2176 pSpectInfo[j].weight =
2177 SAP_ACS_WEIGHT_MAX * 2;
2178 /* for secondary channel selection */
2179 pSpectInfo[j + 8].weight =
2180 SAP_ACS_WEIGHT_MAX * 2
2181 - 1;
2182 } else {
2183 pSpectInfo[j + 8].weight =
2184 tmpWeight2;
2185 pSpectInfo[j].weight =
2186 SAP_ACS_WEIGHT_MAX * 2;
2187 pSpectInfo[j + 4].weight =
2188 SAP_ACS_WEIGHT_MAX * 2;
2189 }
2190 }
2191 } else {
bingsaa6f96a2017-09-11 09:49:43 +08002192 tmpWeight1 = pSpectInfo[j].weight_copy +
2193 pSpectInfo[j + 4].weight_copy;
2194 if (pSpectInfo[j].weight_copy <=
2195 pSpectInfo[j + 4].weight_copy) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002196 pSpectInfo[j].weight = tmpWeight1;
2197 pSpectInfo[j + 4].weight =
2198 SAP_ACS_WEIGHT_MAX * 2;
2199 } else {
2200 pSpectInfo[j + 4].weight = tmpWeight1;
2201 pSpectInfo[j].weight =
2202 SAP_ACS_WEIGHT_MAX * 2;
2203 }
2204 }
2205 }
bingse2782382017-03-23 10:34:52 +08002206 /*
2207 * Every channel should be checked. Add the check for the omissive
2208 * channel. Mark the channel whose combination can't satisfy 40MHZ
2209 * as max value, so that it will be sorted to the bottom.
2210 */
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002211 if (REGDOMAIN_FCC == domain)
bingse2782382017-03-23 10:34:52 +08002212 ht40plus2gendch = HT40PLUS_2G_FCC_CH_END;
2213 else
2214 ht40plus2gendch = HT40PLUS_2G_EURJAP_CH_END;
2215 for (i = HT40MINUS_2G_CH_START; i <= ht40plus2gendch; i++) {
2216 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
2217 if (pSpectInfo[j].chNum == i &&
2218 ((pSpectInfo[j].chNum + 4) !=
2219 pSpectInfo[j+4].chNum) &&
2220 ((pSpectInfo[j].chNum - 4) !=
2221 pSpectInfo[j-4].chNum))
2222 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2;
2223 }
2224 }
2225 for (i = ht40plus2gendch + 1; i <= HT40MINUS_2G_CH_END; i++) {
2226 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
2227 if (pSpectInfo[j].chNum == i &&
2228 (pSpectInfo[j].chNum - 4) !=
2229 pSpectInfo[j-4].chNum)
2230 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2;
2231 }
2232 }
Manishekar Chandrasekaran44e334f2016-05-30 16:42:50 +05302233 sap_sort_chl_weight(pSpectInfoParams);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002234}
2235
2236/*==========================================================================
2237 FUNCTION sap_sort_chl_weight_ht40_5_g
2238
2239 DESCRIPTION
2240 Funtion to sort the channels with the least weight first for HT40 channels
2241
2242 DEPENDENCIES
2243 NA.
2244
2245 PARAMETERS
2246
2247 IN
2248 pSpectInfoParams : Pointer to the tSapChSelSpectInfo structure
2249
2250 RETURN VALUE
2251 void : NULL
2252
2253 SIDE EFFECTS
2254 ============================================================================*/
Jeff Johnson464f7ea2016-10-07 10:21:26 -07002255static void sap_sort_chl_weight_ht40_5_g(tSapChSelSpectInfo *pSpectInfoParams)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002256{
2257 uint8_t i, j;
2258 tSapSpectChInfo *pSpectInfo;
2259
2260 pSpectInfo = pSpectInfoParams->pSpectCh;
2261 /*for each HT40 channel, calculate the combined weight of the
2262 two 20MHz weight */
2263 for (i = 0; i < ARRAY_SIZE(acs_ht40_channels5_g); i++) {
2264 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
2265 if (pSpectInfo[j].chNum ==
2266 acs_ht40_channels5_g[i].chStartNum)
2267 break;
2268 }
2269 if (j == pSpectInfoParams->numSpectChans)
2270 continue;
2271
2272 /* found the channel, add the two adjacent channels' weight */
2273 if ((pSpectInfo[j].chNum + 4) == pSpectInfo[j + 1].chNum) {
2274 acs_ht40_channels5_g[i].weight = pSpectInfo[j].weight +
2275 pSpectInfo[j + 1].weight;
2276 /* select better of the adjact channel as the primary channel */
2277 if (pSpectInfo[j].weight <= pSpectInfo[j + 1].weight) {
2278 pSpectInfo[j].weight =
2279 acs_ht40_channels5_g[i].weight;
2280 /* mark the adjacent channel's weight as max value so
2281 that it will be sorted to the bottom */
2282 pSpectInfo[j + 1].weight =
2283 SAP_ACS_WEIGHT_MAX * 2;
2284 } else {
2285 pSpectInfo[j + 1].weight =
2286 acs_ht40_channels5_g[i].weight;
2287 /* mark the adjacent channel's weight as max value so
2288 that it will be sorted to the bottom */
2289 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2;
2290 }
2291
2292 } else
2293 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2;
2294 }
2295
bingse2782382017-03-23 10:34:52 +08002296 /*
2297 *Every channel should be checked. Add the check for the omissive
2298 * channel. Mark the channel whose combination can't satisfy 40MHZ
2299 * as max value, so that it will be sorted to the bottom
2300 */
2301 for (j = 1; j < pSpectInfoParams->numSpectChans; j++) {
2302 for (i = 0; i < ARRAY_SIZE(acs_ht40_channels5_g); i++) {
2303 if (pSpectInfo[j].chNum ==
2304 (acs_ht40_channels5_g[i].chStartNum +
2305 4) &&
2306 pSpectInfo[j - 1].chNum !=
2307 acs_ht40_channels5_g[i].chStartNum) {
2308 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2;
2309 break;
2310 }
2311 }
2312 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002313 /* avoid channel 165 by setting its weight to max */
2314 pSpectInfo = pSpectInfoParams->pSpectCh;
2315 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
2316 if (CHANNEL_165 == pSpectInfo[j].chNum) {
2317 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2;
2318 break;
2319 }
2320 }
2321
2322 pSpectInfo = pSpectInfoParams->pSpectCh;
2323 for (j = 0; j < (pSpectInfoParams->numSpectChans); j++) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302324 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002325 "In %s, Channel=%d Weight= %d rssi=%d bssCount=%d",
2326 __func__, pSpectInfo->chNum, pSpectInfo->weight,
2327 pSpectInfo->rssiAgr, pSpectInfo->bssCount);
2328 pSpectInfo++;
2329 }
2330
2331 sap_sort_chl_weight(pSpectInfoParams);
2332}
2333
2334/*==========================================================================
2335 FUNCTION sap_sort_chl_weight_all
2336
2337 DESCRIPTION
2338 Funtion to sort the channels with the least weight first
2339
2340 DEPENDENCIES
2341 NA.
2342
2343 PARAMETERS
2344
2345 IN
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -07002346 pSapCtx : Pointer to the struct sap_context *structure
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002347 pSpectInfoParams : Pointer to the tSapChSelSpectInfo structure
2348
2349 RETURN VALUE
2350 void : NULL
2351
2352 SIDE EFFECTS
2353 ============================================================================*/
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -07002354static void sap_sort_chl_weight_all(struct sap_context *pSapCtx,
Jeff Johnson464f7ea2016-10-07 10:21:26 -07002355 tSapChSelSpectInfo *pSpectInfoParams,
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002356 uint32_t operatingBand,
2357 v_REGDOMAIN_t domain)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002358{
2359 tSapSpectChInfo *pSpectCh = NULL;
2360 uint32_t j = 0;
2361#ifndef SOFTAP_CHANNEL_RANGE
2362 uint32_t i = 0;
2363#endif
2364
2365 pSpectCh = pSpectInfoParams->pSpectCh;
2366#ifdef SOFTAP_CHANNEL_RANGE
2367
2368 switch (pSapCtx->acs_cfg->ch_width) {
2369 case CH_WIDTH_40MHZ:
2370 if (eCSR_DOT11_MODE_11g == operatingBand)
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002371 sap_sort_chl_weight_ht40_24_g(pSpectInfoParams, domain);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002372 else if (eCSR_DOT11_MODE_11a == operatingBand)
2373 sap_sort_chl_weight_ht40_5_g(pSpectInfoParams);
2374 else {
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002375 sap_sort_chl_weight_ht40_24_g(pSpectInfoParams, domain);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002376 sap_sort_chl_weight_ht40_5_g(pSpectInfoParams);
2377 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002378 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002379 case CH_WIDTH_80MHZ:
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07002380 case CH_WIDTH_80P80MHZ:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002381 sap_sort_chl_weight_ht80(pSpectInfoParams);
2382 break;
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07002383 case CH_WIDTH_160MHZ:
2384 sap_sort_chl_weight_vht160(pSpectInfoParams);
2385 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002386 case CH_WIDTH_20MHZ:
2387 default:
2388 /* Sorting the channels as per weights as 20MHz channels */
2389 sap_sort_chl_weight(pSpectInfoParams);
2390 }
2391
2392#else
2393 /* Sorting the channels as per weights */
2394 for (i = 0; i < SPECT_24GHZ_CH_COUNT; i++) {
2395 minWeightIndex = i;
2396 for (j = i + 1; j < SPECT_24GHZ_CH_COUNT; j++) {
2397 if (pSpectCh[j].weight <
2398 pSpectCh[minWeightIndex].weight) {
2399 minWeightIndex = j;
2400 }
2401 }
2402 if (minWeightIndex != i) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302403 qdf_mem_copy(&temp, &pSpectCh[minWeightIndex],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002404 sizeof(*pSpectCh));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302405 qdf_mem_copy(&pSpectCh[minWeightIndex], &pSpectCh[i],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002406 sizeof(*pSpectCh));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302407 qdf_mem_copy(&pSpectCh[i], &temp, sizeof(*pSpectCh));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002408 }
2409 }
2410#endif
2411
2412 /* For testing */
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302413 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002414 "In %s, Sorted Spectrum Channels Weight", __func__);
2415 pSpectCh = pSpectInfoParams->pSpectCh;
2416 for (j = 0; j < (pSpectInfoParams->numSpectChans); j++) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302417 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002418 "In %s, Channel=%d Weight= %d rssi=%d bssCount=%d",
2419 __func__, pSpectCh->chNum, pSpectCh->weight,
2420 pSpectCh->rssiAgr, pSpectCh->bssCount);
2421 pSpectCh++;
2422 }
2423
2424}
2425
Naveen Rawatbec64d92017-09-13 14:35:21 -07002426/**
2427 * sap_is_ch_non_overlap() - returns true if non-overlapping channel
2428 * @sap_ctx: Sap context
2429 * @ch: channel number
2430 *
2431 * Returns: true if non-overlapping (1, 6, 11) channel, false otherwise
2432 */
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -07002433static bool sap_is_ch_non_overlap(struct sap_context *sap_ctx, uint16_t ch)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002434{
Naveen Rawatbec64d92017-09-13 14:35:21 -07002435 if (sap_ctx->enableOverLapCh)
Srinivas Girigowda74a66d62017-06-21 23:28:25 -07002436 return true;
Naveen Rawatbec64d92017-09-13 14:35:21 -07002437
2438 if ((ch == CHANNEL_1) || (ch == CHANNEL_6) || (ch == CHANNEL_11))
Srinivas Girigowda74a66d62017-06-21 23:28:25 -07002439 return true;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002440
Srinivas Girigowda74a66d62017-06-21 23:28:25 -07002441 return false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002442}
2443
Dustin Brown0ce56d32016-10-17 16:18:03 -07002444#ifdef FEATURE_WLAN_CH_AVOID
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002445/**
2446 * sap_select_channel_no_scan_result() - select SAP channel when no scan results
2447 * are available.
2448 * @sap_ctx: Sap context
2449 *
2450 * Returns: channel number if success, 0 otherwise
2451 */
Kondabattini, Ganesh13bb4b12016-09-04 16:16:53 +05302452static uint8_t sap_select_channel_no_scan_result(tHalHandle hal,
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -07002453 struct sap_context *sap_ctx)
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002454{
Mohit Khanna841044f2016-03-25 16:16:24 -07002455 enum channel_state ch_type;
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002456 uint8_t i, first_safe_ch_in_range = SAP_CHANNEL_NOT_SELECTED;
Kondabattini, Ganesh13bb4b12016-09-04 16:16:53 +05302457 uint32_t dfs_master_cap_enabled;
Dustin Brown0ce56d32016-10-17 16:18:03 -07002458 uint32_t start_ch_num = sap_ctx->acs_cfg->start_ch;
2459 uint32_t end_ch_num = sap_ctx->acs_cfg->end_ch;
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002460 tpAniSirGlobal mac_ctx = NULL;
2461
2462 mac_ctx = PMAC_STRUCT(hal);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002463
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002464 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2465 FL("start - end: %d - %d"), start_ch_num, end_ch_num);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002466
Kondabattini, Ganesh13bb4b12016-09-04 16:16:53 +05302467 sme_cfg_get_int(hal, WNI_CFG_DFS_MASTER_ENABLED,
2468 &dfs_master_cap_enabled);
2469
2470 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2471 "%s: dfs_master %x", __func__, dfs_master_cap_enabled);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002472
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002473 /* get a channel in PCL and within the range */
2474 for (i = 0; i < sap_ctx->acs_cfg->pcl_ch_count; i++) {
2475 if ((sap_ctx->acs_cfg->pcl_channels[i] < start_ch_num) ||
2476 (sap_ctx->acs_cfg->pcl_channels[i] > end_ch_num))
2477 continue;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002478
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002479 first_safe_ch_in_range = sap_ctx->acs_cfg->pcl_channels[i];
2480 break;
2481 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002482
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002483 if (SAP_CHANNEL_NOT_SELECTED != first_safe_ch_in_range)
2484 return first_safe_ch_in_range;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002485
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002486 for (i = 0; i < NUM_CHANNELS; i++) {
2487 if ((safe_channels[i].channelNumber < start_ch_num) ||
2488 (safe_channels[i].channelNumber > end_ch_num))
2489 continue;
2490
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002491 ch_type = wlan_reg_get_channel_state(mac_ctx->pdev,
2492 safe_channels[i].channelNumber);
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002493
2494 if ((ch_type == CHANNEL_STATE_DISABLE) ||
2495 (ch_type == CHANNEL_STATE_INVALID))
2496 continue;
Kondabattini, Ganesh13bb4b12016-09-04 16:16:53 +05302497 if ((!dfs_master_cap_enabled) &&
2498 (CHANNEL_STATE_DFS == ch_type)) {
2499 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2500 "%s: DFS master mode disabled. Skip DFS channel %d",
2501 __func__, safe_channels[i].channelNumber);
2502 continue;
2503 }
Agrawal Ashish65634612016-08-18 13:24:32 +05302504 if ((sap_ctx->dfs_mode == ACS_DFS_MODE_DISABLE) &&
2505 (CHANNEL_STATE_DFS == ch_type))
2506 continue;
Kondabattini, Ganesh13bb4b12016-09-04 16:16:53 +05302507
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002508 if (safe_channels[i].isSafe == true) {
2509 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2510 FL("channel %d in the configuration is safe"),
2511 safe_channels[i].channelNumber);
2512 first_safe_ch_in_range = safe_channels[i].channelNumber;
2513 break;
2514 }
2515
2516 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2517 FL("channel %d in the configuration is unsafe"),
2518 safe_channels[i].channelNumber);
2519 }
2520
2521 /* if no channel selected return SAP_CHANNEL_NOT_SELECTED */
2522 return first_safe_ch_in_range;
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002523}
Dustin Brown0ce56d32016-10-17 16:18:03 -07002524#else
2525static uint8_t sap_select_channel_no_scan_result(tHalHandle hal,
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -07002526 struct sap_context *sap_ctx)
Dustin Brown0ce56d32016-10-17 16:18:03 -07002527{
2528 uint32_t start_ch_num = sap_ctx->acs_cfg->start_ch;
2529
2530 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2531 FL("start - end: %d - %d"),
2532 start_ch_num,
2533 sap_ctx->acs_cfg->end_ch);
2534
2535 sap_ctx->acs_cfg->pri_ch = start_ch_num;
2536 sap_ctx->acs_cfg->ht_sec_ch = 0;
2537
2538 /* pick the first channel in configured range */
2539 return start_ch_num;
2540}
2541#endif /* FEATURE_WLAN_CH_AVOID */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002542
2543/**
2544 * sap_select_channel() - select SAP channel
2545 * @hal: Pointer to HAL handle
2546 * @sap_ctx: Sap context
2547 * @scan_result: Pointer to tScanResultHandle
2548 *
2549 * Runs a algorithm to select the best channel to operate in based on BSS
2550 * rssi and bss count on each channel
2551 *
2552 * Returns: channel number if success, 0 otherwise
2553 */
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -07002554uint8_t sap_select_channel(tHalHandle hal, struct sap_context *sap_ctx,
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002555 tScanResultHandle scan_result)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002556{
2557 /* DFS param object holding all the data req by the algo */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002558 tSapChSelSpectInfo spect_info_obj = { NULL, 0 };
2559 tSapChSelSpectInfo *spect_info = &spect_info_obj;
2560 uint8_t best_ch_num = SAP_CHANNEL_NOT_SELECTED;
bingse2782382017-03-23 10:34:52 +08002561 uint32_t ht40plus2gendch = 0;
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002562 v_REGDOMAIN_t domain;
2563 uint8_t country[CDS_COUNTRY_CODE_LEN];
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002564#ifdef SOFTAP_CHANNEL_RANGE
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002565 uint8_t count;
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002566 uint32_t start_ch_num, end_ch_num, tmp_ch_num, operating_band = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002567#endif
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002568 tpAniSirGlobal mac_ctx;
2569
2570 mac_ctx = PMAC_STRUCT(hal);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302571 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002572 "In %s, Running SAP Ch Select", __func__);
2573
2574#ifdef FEATURE_WLAN_CH_AVOID
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002575 sap_update_unsafe_channel_list(hal, sap_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002576#endif
2577
gaoleze5108942017-03-31 16:56:42 +08002578 /*
2579 * If ACS weight is not enabled on noise_floor/channel_free/tx_power,
2580 * then skip acs process if no bss found.
2581 */
2582 if (NULL == scan_result &&
2583 !(sap_ctx->auto_channel_select_weight & 0xffff00)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302584 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002585 FL("No external AP present"));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002586
2587#ifndef SOFTAP_CHANNEL_RANGE
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002588 return SAP_CHANNEL_NOT_SELECTED;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002589#else
Kondabattini, Ganesh13bb4b12016-09-04 16:16:53 +05302590 return sap_select_channel_no_scan_result(hal, sap_ctx);
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002591#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002592 }
2593
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002594 /* Initialize the structure pointed by spect_info */
Srinivas Girigowda74a66d62017-06-21 23:28:25 -07002595 if (sap_chan_sel_init(hal, spect_info, sap_ctx) != true) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302596 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002597 FL("Ch Select initialization failed"));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002598 return SAP_CHANNEL_NOT_SELECTED;
2599 }
2600 /* Compute the weight of the entire spectrum in the operating band */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002601 sap_compute_spect_weight(spect_info, hal, scan_result, sap_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002602
2603#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
2604 /* process avoid channel IE to collect all channels to avoid */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002605 sap_process_avoid_ie(hal, sap_ctx, scan_result, spect_info);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002606#endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
2607
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002608 wlan_reg_read_default_country(mac_ctx->psoc, country);
2609 wlan_reg_get_domain_from_country_code(&domain, country, SOURCE_DRIVER);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002610#ifdef SOFTAP_CHANNEL_RANGE
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002611 start_ch_num = sap_ctx->acs_cfg->start_ch;
2612 end_ch_num = sap_ctx->acs_cfg->end_ch;
2613 SET_ACS_BAND(operating_band, sap_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002614
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002615 sap_ctx->acsBestChannelInfo.channelNum = 0;
2616 sap_ctx->acsBestChannelInfo.weight = SAP_ACS_WEIGHT_MAX;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002617
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002618 /* Sort the ch lst as per the computed weights, lesser weight first. */
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002619 sap_sort_chl_weight_all(sap_ctx, spect_info, operating_band, domain);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002620
2621 /*Loop till get the best channel in the given range */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002622 for (count = 0; count < spect_info->numSpectChans; count++) {
2623 if ((start_ch_num > spect_info->pSpectCh[count].chNum) ||
2624 (end_ch_num < spect_info->pSpectCh[count].chNum))
2625 continue;
2626
2627 if (best_ch_num == SAP_CHANNEL_NOT_SELECTED) {
2628 best_ch_num = spect_info->pSpectCh[count].chNum;
2629 /* check if best_ch_num is in preferred channel list */
2630 best_ch_num =
2631 sap_select_preferred_channel_from_channel_list(
2632 best_ch_num, sap_ctx, spect_info);
2633 /* if not in preferred ch lst, go to nxt best ch */
2634 if (best_ch_num == SAP_CHANNEL_NOT_SELECTED)
2635 continue;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002636
2637#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002638 /*
2639 * Weight of the channels(device's AP is operating)
2640 * increased to MAX+1 so that they will be choosen only
2641 * when there is no other best channel to choose
2642 */
2643 if (sap_check_in_avoid_ch_list(sap_ctx, best_ch_num)) {
2644 best_ch_num = SAP_CHANNEL_NOT_SELECTED;
2645 continue;
2646 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002647#endif
2648
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002649 sap_ctx->acsBestChannelInfo.channelNum = best_ch_num;
2650 sap_ctx->acsBestChannelInfo.weight =
2651 spect_info->pSpectCh[count].weight_copy;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002652 }
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002653
2654 if (best_ch_num == SAP_CHANNEL_NOT_SELECTED)
2655 continue;
2656
Tushnim Bhattacharyya03103fd2017-06-23 10:48:52 -07002657 if (operating_band != eCSR_DOT11_MODE_11g) {
2658 QDF_TRACE(QDF_MODULE_ID_SAP,
2659 QDF_TRACE_LEVEL_INFO_HIGH,
2660 "operating_band %d", operating_band);
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002661 continue;
Tushnim Bhattacharyya03103fd2017-06-23 10:48:52 -07002662 }
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002663
2664 /* Give preference to Non-overlap channels */
Naveen Rawatbec64d92017-09-13 14:35:21 -07002665 if (false == sap_is_ch_non_overlap(sap_ctx,
Tushnim Bhattacharyya03103fd2017-06-23 10:48:52 -07002666 spect_info->pSpectCh[count].chNum)) {
2667 QDF_TRACE(QDF_MODULE_ID_SAP,
2668 QDF_TRACE_LEVEL_INFO_HIGH,
Naveen Rawatbec64d92017-09-13 14:35:21 -07002669 FL("ch: %d skipped as its overlapping ch"),
2670 spect_info->pSpectCh[count].chNum);
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002671 continue;
Tushnim Bhattacharyya03103fd2017-06-23 10:48:52 -07002672 }
2673
2674 if (wlan_reg_is_dfs_ch(mac_ctx->pdev,
2675 spect_info->pSpectCh[count].chNum) &&
2676 policy_mgr_disallow_mcc(mac_ctx->psoc,
2677 spect_info->pSpectCh[count].chNum)) {
2678 QDF_TRACE(QDF_MODULE_ID_SAP,
2679 QDF_TRACE_LEVEL_INFO_HIGH,
2680 "No DFS MCC");
2681 continue;
2682 }
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002683
bings14d1d3b2017-08-03 11:14:29 +08002684 if (spect_info->pSpectCh[count].weight_copy >
2685 sap_ctx->acsBestChannelInfo.weight)
2686 continue;
2687
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002688 tmp_ch_num = spect_info->pSpectCh[count].chNum;
gaoleze5108942017-03-31 16:56:42 +08002689 tmp_ch_num = sap_channel_in_acs_channel_list(
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002690 tmp_ch_num, sap_ctx, spect_info);
2691 if (tmp_ch_num == SAP_CHANNEL_NOT_SELECTED)
2692 continue;
2693
2694 best_ch_num = tmp_ch_num;
2695 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002696 }
2697#else
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002698 /* Sort the ch lst as per the computed weights, lesser weight first. */
2699 sap_sort_chl_weight_all(sap_ctx, hal, spect_info);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002700 /* Get the first channel in sorted array as best 20M Channel */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002701 best_ch_num = (uint8_t) spect_info->pSpectCh[0].chNum;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002702 /* Select Best Channel from Channel List if Configured */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002703 best_ch_num = sap_select_preferred_channel_from_channel_list(
2704 best_ch_num, sap_ctx, spect_info);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002705#endif
2706
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002707 /*
2708 * in case the best channel seleted is not in PCL and there is another
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002709 * channel which has same weightage and is in PCL, choose the one in
2710 * PCL
2711 */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002712 for (count = 0; count < spect_info->numSpectChans; count++) {
2713 if (!ch_in_pcl(sap_ctx, spect_info->pSpectCh[count].chNum) ||
2714 (spect_info->pSpectCh[count].weight !=
2715 sap_ctx->acsBestChannelInfo.weight))
2716 continue;
2717
2718 if (sap_select_preferred_channel_from_channel_list(
2719 spect_info->pSpectCh[count].chNum, sap_ctx, spect_info)
2720 == SAP_CHANNEL_NOT_SELECTED)
2721 continue;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002722
2723#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002724 if (sap_check_in_avoid_ch_list(sap_ctx, best_ch_num))
2725 continue;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002726#endif
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002727 best_ch_num = spect_info->pSpectCh[count].chNum;
2728 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2729 FL("change best channel to %d in PCL"), best_ch_num);
2730 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002731 }
2732
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002733 sap_ctx->acs_cfg->pri_ch = best_ch_num;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002734 /* determine secondary channel for 2.4G channel 5, 6, 7 in HT40 */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002735 if ((operating_band != eCSR_DOT11_MODE_11g) ||
2736 (sap_ctx->acs_cfg->ch_width != CH_WIDTH_40MHZ))
2737 goto sap_ch_sel_end;
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002738 if (REGDOMAIN_FCC == domain)
bingse2782382017-03-23 10:34:52 +08002739 ht40plus2gendch = HT40PLUS_2G_FCC_CH_END;
2740 else
2741 ht40plus2gendch = HT40PLUS_2G_EURJAP_CH_END;
2742 if ((best_ch_num >= HT40MINUS_2G_CH_START) &&
2743 (best_ch_num <= ht40plus2gendch)) {
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002744 int weight_below, weight_above, i;
2745 tSapSpectChInfo *pspect_info;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002746
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002747 weight_below = weight_above = SAP_ACS_WEIGHT_MAX;
2748 pspect_info = spect_info->pSpectCh;
2749 for (i = 0; i < spect_info->numSpectChans; i++) {
2750 if (pspect_info[i].chNum == (best_ch_num - 4))
2751 weight_below = pspect_info[i].weight;
2752 if (pspect_info[i].chNum == (best_ch_num + 4))
2753 weight_above = pspect_info[i].weight;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002754 }
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002755
2756 if (weight_below < weight_above)
2757 sap_ctx->acs_cfg->ht_sec_ch =
2758 sap_ctx->acs_cfg->pri_ch - 4;
2759 else
2760 sap_ctx->acs_cfg->ht_sec_ch =
2761 sap_ctx->acs_cfg->pri_ch + 4;
2762 } else if (best_ch_num >= 1 && best_ch_num <= 4) {
2763 sap_ctx->acs_cfg->ht_sec_ch = sap_ctx->acs_cfg->pri_ch + 4;
bingse2782382017-03-23 10:34:52 +08002764 } else if (best_ch_num >= ht40plus2gendch && best_ch_num <=
2765 HT40MINUS_2G_CH_END) {
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002766 sap_ctx->acs_cfg->ht_sec_ch = sap_ctx->acs_cfg->pri_ch - 4;
2767 } else if (best_ch_num == 14) {
2768 sap_ctx->acs_cfg->ht_sec_ch = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002769 }
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002770 sap_ctx->secondary_ch = sap_ctx->acs_cfg->ht_sec_ch;
2771
2772sap_ch_sel_end:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002773 /* Free all the allocated memory */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002774 sap_chan_sel_exit(spect_info);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002775
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302776 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002777 FL("Running SAP Ch select Completed, Ch=%d"), best_ch_num);
2778 if (best_ch_num > 0 && best_ch_num <= 252)
2779 return best_ch_num;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002780 else
2781 return SAP_CHANNEL_NOT_SELECTED;
2782}