blob: d14148cd369664f78e4f7712d881b086900a42e8 [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
Jeff Johnsone13d8062017-09-28 06:54:55 -070074#define SET_ACS_BAND(acs_band, sap_ctx) \
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080075{ \
Jeff Johnsone13d8062017-09-28 06:54:55 -070076 if (sap_ctx->acs_cfg->start_ch <= 14 && \
77 sap_ctx->acs_cfg->end_ch <= 14) \
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080078 acs_band = eCSR_DOT11_MODE_11g; \
Jeff Johnsone13d8062017-09-28 06:54:55 -070079 else if (sap_ctx->acs_cfg->start_ch >= 14)\
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080080 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 Johnsone13d8062017-09-28 06:54:55 -0700419void sap_update_unsafe_channel_list(tHalHandle hal, struct sap_context *sap_ctx)
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++) {
Jeff Johnsone13d8062017-09-28 06:54:55 -0700448 if (sap_ctx->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
Jeff Johnsone13d8062017-09-28 06:54:55 -0700487void sap_cleanup_channel_list(struct sap_context *sap_ctx)
Ryan Hsu4252a2f2016-01-05 11:18:24 -0800488{
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800489
Srinivas Girigowda678586c2017-03-10 00:13:58 -0800490 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800491 "Cleaning up the channel list structure");
492
Jeff Johnsone13d8062017-09-28 06:54:55 -0700493 if (NULL == sap_ctx) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530494 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800495 "SAP Context is NULL");
496 return;
497 }
498
Jeff Johnsone13d8062017-09-28 06:54:55 -0700499 sap_ctx->SapChnlList.numChannel = 0;
500 if (sap_ctx->SapChnlList.channelList) {
501 qdf_mem_free(sap_ctx->SapChnlList.channelList);
502 sap_ctx->SapChnlList.channelList = NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800503 }
504
Jeff Johnsone13d8062017-09-28 06:54:55 -0700505 sap_ctx->SapAllChnlList.numChannel = 0;
506 if (sap_ctx->SapAllChnlList.channelList) {
507 qdf_mem_free(sap_ctx->SapAllChnlList.channelList);
508 sap_ctx->SapAllChnlList.channelList = NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800509 }
510}
511
512/**
gaoleze5108942017-03-31 16:56:42 +0800513 * sap_channel_in_acs_channel_list() - check if channel in acs channel list
514 * @channel_num: channel to check
515 * @sap_ctx: struct ptSapContext
516 * @spect_info_params: strcut tSapChSelSpectInfo
517 *
518 * This function checks if specified channel is in the configured ACS channel
519 * list.
520 *
521 * Return: channel number if in acs channel list or SAP_CHANNEL_NOT_SELECTED
522 */
523static
524uint8_t sap_channel_in_acs_channel_list(uint8_t channel_num,
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -0700525 struct sap_context *sap_ctx,
gaoleze5108942017-03-31 16:56:42 +0800526 tSapChSelSpectInfo *spect_info_params)
527{
528 uint8_t i = 0;
529
530 if ((NULL == sap_ctx->acs_cfg->ch_list) ||
531 (NULL == spect_info_params))
532 return channel_num;
533
534 if (channel_num > 0 && channel_num <= 252) {
535 for (i = 0; i < sap_ctx->acs_cfg->ch_list_count; i++) {
536 if ((sap_ctx->acs_cfg->ch_list[i]) == channel_num)
537 return channel_num;
538 }
539 return SAP_CHANNEL_NOT_SELECTED;
540 } else {
541 return SAP_CHANNEL_NOT_SELECTED;
542 }
543}
544
545/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800546 * sap_select_preferred_channel_from_channel_list() - to calc best cahnnel
547 * @best_chnl: best channel already calculated among all the chanels
548 * @sap_ctx: sap context
549 * @spectinfo_param: Pointer to tSapChSelSpectInfo structure
550 *
551 * This function calculates the best channel among the configured channel list.
552 * If channel list not configured then returns the best channel calculated
553 * among all the channel list.
554 *
555 * Return: uint8_t best channel
556 */
Jeff Johnson464f7ea2016-10-07 10:21:26 -0700557static
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800558uint8_t sap_select_preferred_channel_from_channel_list(uint8_t best_chnl,
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -0700559 struct sap_context *sap_ctx,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800560 tSapChSelSpectInfo *spectinfo_param)
561{
562 uint8_t i = 0;
Tushnim Bhattacharyya518e80f2017-08-30 17:35:33 -0700563 tpAniSirGlobal mac_ctx = sme_get_mac_context();
564
565 if (NULL == mac_ctx) {
566 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
567 "pmac Global Context is NULL");
568 return SAP_CHANNEL_NOT_SELECTED;
569 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800570
571 /*
572 * If Channel List is not Configured don't do anything
573 * Else return the Best Channel from the Channel List
574 */
575 if ((NULL == sap_ctx->acs_cfg->ch_list) ||
576 (NULL == spectinfo_param) ||
577 (0 == sap_ctx->acs_cfg->ch_list_count))
578 return best_chnl;
579
580 if (best_chnl <= 0 || best_chnl > 252)
581 return SAP_CHANNEL_NOT_SELECTED;
582
583 /* Select the best channel from allowed list */
584 for (i = 0; i < sap_ctx->acs_cfg->ch_list_count; i++) {
Tushnim Bhattacharyya518e80f2017-08-30 17:35:33 -0700585 if ((sap_ctx->acs_cfg->ch_list[i] == best_chnl) &&
586 !(wlan_reg_is_dfs_ch(mac_ctx->pdev, best_chnl) &&
587 policy_mgr_disallow_mcc(mac_ctx->psoc, best_chnl))) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530588 QDF_TRACE(QDF_MODULE_ID_SAP,
589 QDF_TRACE_LEVEL_INFO_HIGH,
Naveen Rawatbec64d92017-09-13 14:35:21 -0700590 "Best channel so far is: %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800591 best_chnl);
592 return best_chnl;
593 }
594 }
595
596 return SAP_CHANNEL_NOT_SELECTED;
597}
598
599/*==========================================================================
600 FUNCTION sap_chan_sel_init
601
602 DESCRIPTION
603 Function sap_chan_sel_init allocates the memory, intializes the
Anurag Chouhan6d760662016-02-20 16:05:43 +0530604 structures used by the channel selection algorithm
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800605
606 DEPENDENCIES
607 NA.
608
609 PARAMETERS
610
611 IN
612 halHandle : Pointer to tHalHandle
613 *pSpectInfoParams : Pointer to tSapChSelSpectInfo structure
Jeff Johnsone13d8062017-09-28 06:54:55 -0700614 sap_ctx : Pointer to SAP Context
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800615
616 RETURN VALUE
617 bool: Success or FAIL
618
619 SIDE EFFECTS
620 ============================================================================*/
Jeff Johnson464f7ea2016-10-07 10:21:26 -0700621static bool sap_chan_sel_init(tHalHandle halHandle,
622 tSapChSelSpectInfo *pSpectInfoParams,
Jeff Johnsone13d8062017-09-28 06:54:55 -0700623 struct sap_context *sap_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800624{
625 tSapSpectChInfo *pSpectCh = NULL;
626 uint8_t *pChans = NULL;
627 uint16_t channelnum = 0;
628 tpAniSirGlobal pMac = PMAC_STRUCT(halHandle);
629 bool chSafe = true;
630#ifdef FEATURE_WLAN_CH_AVOID
631 uint16_t i;
632#endif
633 uint32_t dfs_master_cap_enabled;
634 bool include_dfs_ch = true;
635
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530636 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, "In %s",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800637 __func__);
638
639 pSpectInfoParams->numSpectChans =
640 pMac->scan.base_channels.numChannels;
641
642 /* Allocate memory for weight computation of 2.4GHz */
643 pSpectCh =
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530644 (tSapSpectChInfo *) qdf_mem_malloc((pSpectInfoParams->numSpectChans)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800645 * sizeof(*pSpectCh));
646
647 if (pSpectCh == NULL) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530648 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
Anurag Chouhanf04e84f2016-03-03 10:12:12 +0530649 "In %s, QDF_MALLOC_ERR", __func__);
Srinivas Girigowda74a66d62017-06-21 23:28:25 -0700650 return false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800651 }
652
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800653 /* Initialize the pointers in the DfsParams to the allocated memory */
654 pSpectInfoParams->pSpectCh = pSpectCh;
655
656 pChans = pMac->scan.base_channels.channelList;
657
Ryan Hsu4252a2f2016-01-05 11:18:24 -0800658#if defined(FEATURE_WLAN_STA_AP_MODE_DFS_DISABLE)
Jeff Johnsone13d8062017-09-28 06:54:55 -0700659 if (sap_ctx->dfs_ch_disable == true)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800660 include_dfs_ch = false;
661#endif
662 sme_cfg_get_int(halHandle, WNI_CFG_DFS_MASTER_ENABLED,
663 &dfs_master_cap_enabled);
Agrawal Ashish65634612016-08-18 13:24:32 +0530664 if (dfs_master_cap_enabled == 0 ||
Jeff Johnsone13d8062017-09-28 06:54:55 -0700665 ACS_DFS_MODE_DISABLE == sap_ctx->dfs_mode)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800666 include_dfs_ch = false;
667
668 /* Fill the channel number in the spectrum in the operating freq band */
669 for (channelnum = 0;
670 channelnum < pSpectInfoParams->numSpectChans;
Edhar, Mahesh Kumar4f660672015-10-30 11:53:26 +0530671 channelnum++, pChans++, pSpectCh++) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800672 chSafe = true;
673
674 /* check if the channel is in NOL blacklist */
Jeff Johnsone13d8062017-09-28 06:54:55 -0700675 if (sap_dfs_is_channel_in_nol_list(sap_ctx, *pChans,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800676 PHY_SINGLE_CHANNEL_CENTERED)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530677 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800678 "In %s, Ch %d is in NOL list", __func__,
679 *pChans);
680 chSafe = false;
681 continue;
682 }
683
684 if (include_dfs_ch == false) {
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -0700685 if (wlan_reg_is_dfs_ch(pMac->pdev, *pChans)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800686 chSafe = false;
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530687 QDF_TRACE(QDF_MODULE_ID_SAP,
688 QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800689 "In %s, DFS Ch %d not considered for ACS",
690 __func__, *pChans);
691 continue;
692 }
693 }
694
695#ifdef FEATURE_WLAN_CH_AVOID
Amar Singhalb8d4f152016-02-10 10:21:43 -0800696 for (i = 0; i < NUM_CHANNELS; i++) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800697 if ((safe_channels[i].channelNumber == *pChans) &&
698 (false == safe_channels[i].isSafe)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530699 QDF_TRACE(QDF_MODULE_ID_SAP,
700 QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800701 "In %s, Ch %d is not safe", __func__,
702 *pChans);
703 chSafe = false;
704 break;
705 }
706 }
707#endif /* FEATURE_WLAN_CH_AVOID */
708
709 /* OFDM rates are not supported on channel 14 */
710 if (*pChans == 14 &&
Jeff Johnsone13d8062017-09-28 06:54:55 -0700711 eCSR_DOT11_MODE_11b != sap_ctx->csr_roamProfile.phyMode) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800712 continue;
713 }
714
Deepthi Gowri48b89332016-08-30 18:43:05 +0530715 /* Skip DSRC channels */
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -0700716 if (WLAN_REG_IS_11P_CH(*pChans))
Deepthi Gowri48b89332016-08-30 18:43:05 +0530717 continue;
718
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800719 if (true == chSafe) {
720 pSpectCh->chNum = *pChans;
Srinivas Girigowda74a66d62017-06-21 23:28:25 -0700721 pSpectCh->valid = true;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800722 pSpectCh->rssiAgr = SOFTAP_MIN_RSSI; /* Initialise for all channels */
723 pSpectCh->channelWidth = SOFTAP_HT20_CHANNELWIDTH; /* Initialise 20MHz for all the Channels */
724 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800725 }
Srinivas Girigowda74a66d62017-06-21 23:28:25 -0700726 return true;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800727}
728
gaoleze5108942017-03-31 16:56:42 +0800729/**
730 * sapweight_rssi_count() - calculates the channel weight due to rssi
Anurag Chouhan6d760662016-02-20 16:05:43 +0530731 and data count(here number of BSS observed)
gaoleze5108942017-03-31 16:56:42 +0800732 * @sap_ctx : Softap context
733 * @rssi : Max signal strength receieved from a BSS for the channel
734 * @count : Number of BSS observed in the channel
735 *
736 * Return: uint32_t Calculated channel weight based on above two
737 */
738static
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -0700739uint32_t sapweight_rssi_count(struct sap_context *sap_ctx, int8_t rssi,
gaoleze5108942017-03-31 16:56:42 +0800740 uint16_t count)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800741{
742 int32_t rssiWeight = 0;
743 int32_t countWeight = 0;
744 uint32_t rssicountWeight = 0;
gaoleze5108942017-03-31 16:56:42 +0800745 uint8_t softap_rssi_weight_cfg, softap_count_weight_cfg;
746 uint8_t softap_rssi_weight_local, softap_count_weight_local;
747
748 softap_rssi_weight_cfg =
749 ACS_WEIGHT_SOFTAP_RSSI_CFG(sap_ctx->auto_channel_select_weight);
750
751 softap_count_weight_cfg =
752 ACS_WEIGHT_SOFTAP_COUNT_CFG(sap_ctx->auto_channel_select_weight);
753
754 softap_rssi_weight_local =
755 ACS_WEIGHT_CFG_TO_LOCAL(sap_ctx->auto_channel_select_weight,
756 softap_rssi_weight_cfg);
757
758 softap_count_weight_local =
759 ACS_WEIGHT_CFG_TO_LOCAL(sap_ctx->auto_channel_select_weight,
760 softap_count_weight_cfg);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800761
762 /* Weight from RSSI */
gaoleze5108942017-03-31 16:56:42 +0800763 rssiWeight = ACS_WEIGHT_COMPUTE(sap_ctx->auto_channel_select_weight,
764 softap_rssi_weight_cfg,
765 rssi - SOFTAP_MIN_RSSI,
766 SOFTAP_MAX_RSSI - SOFTAP_MIN_RSSI);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800767
gaoleze5108942017-03-31 16:56:42 +0800768 if (rssiWeight > softap_rssi_weight_local)
769 rssiWeight = softap_rssi_weight_local;
770
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800771 else if (rssiWeight < 0)
772 rssiWeight = 0;
773
774 /* Weight from data count */
gaoleze5108942017-03-31 16:56:42 +0800775 countWeight = ACS_WEIGHT_COMPUTE(sap_ctx->auto_channel_select_weight,
776 softap_count_weight_cfg,
777 count - SOFTAP_MIN_COUNT,
778 SOFTAP_MAX_COUNT - SOFTAP_MIN_COUNT);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800779
gaoleze5108942017-03-31 16:56:42 +0800780 if (countWeight > softap_count_weight_local)
781 countWeight = softap_count_weight_local;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800782
783 rssicountWeight = rssiWeight + countWeight;
784
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530785 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800786 "In %s, rssiWeight=%d, countWeight=%d, rssicountWeight=%d",
787 __func__, rssiWeight, countWeight, rssicountWeight);
788
789 return rssicountWeight;
790}
791
792/**
gaoleze5108942017-03-31 16:56:42 +0800793 * sap_get_channel_status() - get channel info via channel number
794 * @p_mac: Pointer to Global MAC structure
795 * @channel_id: channel id
796 *
797 * Return: chan status info
798 */
799static struct lim_channel_status *sap_get_channel_status
800 (tpAniSirGlobal p_mac, uint32_t channel_id)
801{
802 return csr_get_channel_status(p_mac, channel_id);
803}
804
805/**
806 * sap_clear_channel_status() - clear chan info
807 * @p_mac: Pointer to Global MAC structure
808 *
809 * Return: none
810 */
811static void sap_clear_channel_status(tpAniSirGlobal p_mac)
812{
813 csr_clear_channel_status(p_mac);
814}
815
816/**
817 * sap_weight_channel_noise_floor() - compute noise floor weight
818 * @sap_ctx: sap context
819 * @chn_stat: Pointer to chan status info
820 *
821 * Return: channel noise floor weight
822 */
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -0700823static uint32_t sap_weight_channel_noise_floor(struct sap_context *sap_ctx,
gaoleze5108942017-03-31 16:56:42 +0800824 struct lim_channel_status
825 *channel_stat)
826{
827 uint32_t noise_floor_weight;
828 uint8_t softap_nf_weight_cfg;
829 uint8_t softap_nf_weight_local;
830
831 softap_nf_weight_cfg =
832 ACS_WEIGHT_SOFTAP_NOISE_FLOOR_CFG
833 (sap_ctx->auto_channel_select_weight);
834
835 softap_nf_weight_local =
836 ACS_WEIGHT_CFG_TO_LOCAL(sap_ctx->auto_channel_select_weight,
837 softap_nf_weight_cfg);
838
839 if (channel_stat == NULL || channel_stat->channelfreq == 0) {
840 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
841 "In %s, sanity check failed return max weight",
842 __func__);
843 return softap_nf_weight_local;
844 }
845
846 noise_floor_weight = (channel_stat->noise_floor == 0) ? 0 :
847 (ACS_WEIGHT_COMPUTE(
848 sap_ctx->auto_channel_select_weight,
849 softap_nf_weight_cfg,
850 channel_stat->noise_floor -
851 SOFTAP_MIN_NF,
852 SOFTAP_MAX_NF - SOFTAP_MIN_NF));
853
854 if (noise_floor_weight > softap_nf_weight_local)
855 noise_floor_weight = softap_nf_weight_local;
856 else if (noise_floor_weight < 0)
857 noise_floor_weight = 0;
858
859 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
860 "In %s, nf=%d, nfwc=%d, nfwl=%d, nfw=%d",
861 __func__, channel_stat->noise_floor,
862 softap_nf_weight_cfg, softap_nf_weight_local,
863 noise_floor_weight);
864
865 return noise_floor_weight;
866}
867
868/**
869 * sap_weight_channel_free() - compute channel free weight
870 * @sap_ctx: sap context
871 * @chn_stat: Pointer to chan status info
872 *
873 * Return: channel free weight
874 */
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -0700875static uint32_t sap_weight_channel_free(struct sap_context *sap_ctx,
gaoleze5108942017-03-31 16:56:42 +0800876 struct lim_channel_status
877 *channel_stat)
878{
879 uint32_t channel_free_weight;
880 uint8_t softap_channel_free_weight_cfg;
881 uint8_t softap_channel_free_weight_local;
882 uint32_t rx_clear_count = 0;
883 uint32_t cycle_count = 0;
884
885 softap_channel_free_weight_cfg =
886 ACS_WEIGHT_SOFTAP_CHANNEL_FREE_CFG
887 (sap_ctx->auto_channel_select_weight);
888
889 softap_channel_free_weight_local =
890 ACS_WEIGHT_CFG_TO_LOCAL(sap_ctx->auto_channel_select_weight,
891 softap_channel_free_weight_cfg);
892
893 if (channel_stat == NULL || channel_stat->channelfreq == 0) {
894 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
895 "In %s, sanity check failed return max weight",
896 __func__);
897 return softap_channel_free_weight_local;
898 }
899
900 rx_clear_count = channel_stat->rx_clear_count -
901 channel_stat->tx_frame_count -
902 channel_stat->rx_frame_count;
903 cycle_count = channel_stat->cycle_count;
904
905 /* LSH 4, otherwise it is always 0. */
906 channel_free_weight = (cycle_count == 0) ? 0 :
907 (ACS_WEIGHT_COMPUTE(
908 sap_ctx->auto_channel_select_weight,
909 softap_channel_free_weight_cfg,
910 ((rx_clear_count << 8) +
911 (cycle_count >> 1))/cycle_count -
912 (SOFTAP_MIN_CHNFREE << 8),
913 (SOFTAP_MAX_CHNFREE -
914 SOFTAP_MIN_CHNFREE) << 8));
915
916 if (channel_free_weight > softap_channel_free_weight_local)
917 channel_free_weight = softap_channel_free_weight_local;
918
919 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
920 "In %s, rcc=%d, cc=%d, tc=%d, rc=%d, cfwc=%d, cfwl=%d, cfw=%d",
921 __func__, rx_clear_count, cycle_count,
922 channel_stat->tx_frame_count,
923 channel_stat->rx_frame_count,
924 softap_channel_free_weight_cfg,
925 softap_channel_free_weight_local,
926 channel_free_weight);
927
928 return channel_free_weight;
929}
930
931/**
932 * sap_weight_channel_txpwr_range() - compute channel tx power range weight
933 * @sap_ctx: sap context
934 * @chn_stat: Pointer to chan status info
935 *
936 * Return: tx power range weight
937 */
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -0700938static uint32_t sap_weight_channel_txpwr_range(struct sap_context *sap_ctx,
gaoleze5108942017-03-31 16:56:42 +0800939 struct lim_channel_status
940 *channel_stat)
941{
942 uint32_t txpwr_weight_low_speed;
943 uint8_t softap_txpwr_range_weight_cfg;
944 uint8_t softap_txpwr_range_weight_local;
945
946 softap_txpwr_range_weight_cfg =
947 ACS_WEIGHT_SOFTAP_TX_POWER_RANGE_CFG
948 (sap_ctx->auto_channel_select_weight);
949
950 softap_txpwr_range_weight_local =
951 ACS_WEIGHT_CFG_TO_LOCAL(sap_ctx->auto_channel_select_weight,
952 softap_txpwr_range_weight_cfg);
953
954 if (channel_stat == NULL || channel_stat->channelfreq == 0) {
955 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
956 "In %s, sanity check failed return max weight",
957 __func__);
958 return softap_txpwr_range_weight_local;
959 }
960
961 txpwr_weight_low_speed = (channel_stat->chan_tx_pwr_range == 0) ? 0 :
962 (ACS_WEIGHT_COMPUTE(
963 sap_ctx->auto_channel_select_weight,
964 softap_txpwr_range_weight_cfg,
965 SOFTAP_MAX_TXPWR -
966 channel_stat->chan_tx_pwr_range,
967 SOFTAP_MAX_TXPWR - SOFTAP_MIN_TXPWR));
968
969 if (txpwr_weight_low_speed > softap_txpwr_range_weight_local)
970 txpwr_weight_low_speed = softap_txpwr_range_weight_local;
971
972 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
973 "In %s, tpr=%d, tprwc=%d, tprwl=%d, tprw=%d",
974 __func__, channel_stat->chan_tx_pwr_range,
975 softap_txpwr_range_weight_cfg,
976 softap_txpwr_range_weight_local,
977 txpwr_weight_low_speed);
978
979 return txpwr_weight_low_speed;
980}
981
982/**
983 * sap_weight_channel_txpwr_tput() - compute channel tx power
984 * throughput weight
985 * @sap_ctx: sap context
986 * @chn_stat: Pointer to chan status info
987 *
988 * Return: tx power throughput weight
989 */
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -0700990static uint32_t sap_weight_channel_txpwr_tput(struct sap_context *sap_ctx,
gaoleze5108942017-03-31 16:56:42 +0800991 struct lim_channel_status
992 *channel_stat)
993{
994 uint32_t txpwr_weight_high_speed;
995 uint8_t softap_txpwr_tput_weight_cfg;
996 uint8_t softap_txpwr_tput_weight_local;
997
998 softap_txpwr_tput_weight_cfg =
999 ACS_WEIGHT_SOFTAP_TX_POWER_THROUGHPUT_CFG
1000 (sap_ctx->auto_channel_select_weight);
1001
1002 softap_txpwr_tput_weight_local =
1003 ACS_WEIGHT_CFG_TO_LOCAL(sap_ctx->auto_channel_select_weight,
1004 softap_txpwr_tput_weight_cfg);
1005
1006 if (channel_stat == NULL || channel_stat->channelfreq == 0) {
1007 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
1008 "In %s, sanity check failed return max weight",
1009 __func__);
1010 return softap_txpwr_tput_weight_local;
1011 }
1012
1013 txpwr_weight_high_speed = (channel_stat->chan_tx_pwr_throughput == 0)
1014 ? 0 : (ACS_WEIGHT_COMPUTE(
1015 sap_ctx->auto_channel_select_weight,
1016 softap_txpwr_tput_weight_cfg,
1017 SOFTAP_MAX_TXPWR -
1018 channel_stat->chan_tx_pwr_throughput,
1019 SOFTAP_MAX_TXPWR - SOFTAP_MIN_TXPWR));
1020
1021 if (txpwr_weight_high_speed > softap_txpwr_tput_weight_local)
1022 txpwr_weight_high_speed = softap_txpwr_tput_weight_local;
1023
1024 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
1025 "In %s, tpt=%d, tptwc=%d, tptwl=%d, tptw=%d",
1026 __func__, channel_stat->chan_tx_pwr_throughput,
1027 softap_txpwr_tput_weight_cfg,
1028 softap_txpwr_tput_weight_local,
1029 txpwr_weight_high_speed);
1030
1031 return txpwr_weight_high_speed;
1032}
1033
1034/**
1035 * sap_weight_channel_status() - compute chan status weight
1036 * @sap_ctx: sap context
1037 * @chn_stat: Pointer to chan status info
1038 *
1039 * Return: chan status weight
1040 */
1041static
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -07001042uint32_t sap_weight_channel_status(struct sap_context *sap_ctx,
gaoleze5108942017-03-31 16:56:42 +08001043 struct lim_channel_status *channel_stat)
1044{
1045 return sap_weight_channel_noise_floor(sap_ctx, channel_stat) +
1046 sap_weight_channel_free(sap_ctx, channel_stat) +
1047 sap_weight_channel_txpwr_range(sap_ctx, channel_stat) +
1048 sap_weight_channel_txpwr_tput(sap_ctx, channel_stat);
1049}
1050
1051/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001052 * sap_update_rssi_bsscount() - updates bss count and rssi effect.
1053 *
1054 * @pSpectCh: Channel Information
1055 * @offset: Channel Offset
1056 * @sap_24g: Channel is in 2.4G or 5G
Liangwei Dong71ed6502016-10-20 03:40:45 -04001057 * @spectch_start: the start of spect ch array
1058 * @spectch_end: the end of spect ch array
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001059 *
1060 * sap_update_rssi_bsscount updates bss count and rssi effect based
1061 * on the channel offset.
1062 *
1063 * Return: None.
1064 */
1065
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001066static void sap_update_rssi_bsscount(tSapSpectChInfo *pSpectCh, int32_t offset,
Liangwei Dong71ed6502016-10-20 03:40:45 -04001067 bool sap_24g, tSapSpectChInfo *spectch_start,
1068 tSapSpectChInfo *spectch_end)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001069{
1070 tSapSpectChInfo *pExtSpectCh = NULL;
1071 int32_t rssi, rsssi_effect;
1072
1073 pExtSpectCh = (pSpectCh + offset);
Liangwei Dong71ed6502016-10-20 03:40:45 -04001074 if (pExtSpectCh != NULL &&
1075 pExtSpectCh >= spectch_start &&
1076 pExtSpectCh < spectch_end) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001077 ++pExtSpectCh->bssCount;
1078 switch (offset) {
1079 case -1:
1080 case 1:
1081 rsssi_effect = sap_24g ?
1082 SAP_24GHZ_FIRST_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY :
1083 SAP_SUBBAND1_RSSI_EFFECT_PRIMARY;
1084 break;
1085 case -2:
1086 case 2:
1087 rsssi_effect = sap_24g ?
1088 SAP_24GHZ_SEC_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY :
1089 SAP_SUBBAND2_RSSI_EFFECT_PRIMARY;
1090 break;
1091 case -3:
1092 case 3:
1093 rsssi_effect = sap_24g ?
1094 SAP_24GHZ_THIRD_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY :
1095 SAP_SUBBAND3_RSSI_EFFECT_PRIMARY;
1096 break;
1097 case -4:
1098 case 4:
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001099 rsssi_effect = sap_24g ?
1100 SAP_24GHZ_FOURTH_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY :
1101 SAP_SUBBAND4_RSSI_EFFECT_PRIMARY;
1102 break;
1103 case -5:
1104 case 5:
1105 rsssi_effect = SAP_SUBBAND5_RSSI_EFFECT_PRIMARY;
1106 break;
1107 case -6:
1108 case 6:
1109 rsssi_effect = SAP_SUBBAND6_RSSI_EFFECT_PRIMARY;
1110 break;
1111 case -7:
1112 case 7:
1113 rsssi_effect = SAP_SUBBAND7_RSSI_EFFECT_PRIMARY;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001114 break;
1115 default:
1116 rsssi_effect = 0;
1117 break;
1118 }
1119
1120 rssi = pSpectCh->rssiAgr + rsssi_effect;
1121 if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi))
1122 pExtSpectCh->rssiAgr = rssi;
1123 if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI)
1124 pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI;
1125 }
1126}
1127
1128/**
1129 * sap_upd_chan_spec_params() - sap_upd_chan_spec_params
1130 * updates channel parameters obtained from Beacon
1131 * @pBeaconStruct Beacon strucutre populated by parse_beacon function
1132 * @channelWidth Channel width
1133 * @secondaryChannelOffset Secondary Channel Offset
1134 * @vhtSupport If channel supports VHT
1135 * @centerFreq Central frequency for the given channel.
1136 *
1137 * sap_upd_chan_spec_params updates the spectrum channels based on the
1138 * pBeaconStruct obtained from Beacon IE
1139 *
1140 * Return: NA.
1141 */
1142
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001143static void sap_upd_chan_spec_params(tSirProbeRespBeacon *pBeaconStruct,
1144 uint16_t *channelWidth,
1145 uint16_t *secondaryChannelOffset,
1146 uint16_t *vhtSupport,
1147 uint16_t *centerFreq,
1148 uint16_t *centerFreq_2)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001149{
1150 if (NULL == pBeaconStruct) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301151 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001152 FL("pBeaconStruct is NULL"));
1153 return;
1154 }
1155
1156 if (pBeaconStruct->HTCaps.present && pBeaconStruct->HTInfo.present) {
1157 *channelWidth = pBeaconStruct->HTCaps.supportedChannelWidthSet;
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001158 *secondaryChannelOffset =
1159 pBeaconStruct->HTInfo.secondaryChannelOffset;
1160 if (!pBeaconStruct->VHTOperation.present)
1161 return;
1162 *vhtSupport = pBeaconStruct->VHTOperation.present;
1163 if (pBeaconStruct->VHTOperation.chanWidth) {
1164 *centerFreq =
1165 pBeaconStruct->VHTOperation.chanCenterFreqSeg1;
1166 *centerFreq_2 =
1167 pBeaconStruct->VHTOperation.chanCenterFreqSeg2;
1168 /*
1169 * LHS follows tSirMacHTChannelWidth, while RHS follows
1170 * WNI_CFG_VHT_CHANNEL_WIDTH_X format hence following
1171 * adjustment
1172 */
1173 *channelWidth =
1174 pBeaconStruct->VHTOperation.chanWidth + 1;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001175
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001176 }
1177 }
1178}
1179
1180/**
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001181 * sap_update_rssi_bsscount_vht_5G() - updates bss count and rssi effect.
1182 *
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001183 * @spect_ch: Channel Information
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001184 * @offset: Channel Offset
1185 * @num_ch: no.of channels
Liangwei Dong71ed6502016-10-20 03:40:45 -04001186 * @spectch_start: the start of spect ch array
1187 * @spectch_end: the end of spect ch array
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001188 *
1189 * sap_update_rssi_bsscount_vht_5G updates bss count and rssi effect based
1190 * on the channel offset.
1191 *
1192 * Return: None.
1193 */
1194
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001195static void sap_update_rssi_bsscount_vht_5G(tSapSpectChInfo *spect_ch,
1196 int32_t offset,
Liangwei Dong71ed6502016-10-20 03:40:45 -04001197 uint16_t num_ch,
1198 tSapSpectChInfo *spectch_start,
1199 tSapSpectChInfo *spectch_end)
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001200{
1201 int32_t ch_offset;
1202 uint16_t i, cnt;
1203
1204 if (!offset)
1205 return;
1206 if (offset > 0)
1207 cnt = num_ch;
1208 else
1209 cnt = num_ch + 1;
1210 for (i = 0; i < cnt; i++) {
1211 ch_offset = offset + i;
1212 if (ch_offset == 0)
1213 continue;
Liangwei Dong71ed6502016-10-20 03:40:45 -04001214 sap_update_rssi_bsscount(spect_ch, ch_offset, false,
1215 spectch_start, spectch_end);
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001216 }
1217}
1218/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001219 * sap_interference_rssi_count_5G() - sap_interference_rssi_count
1220 * considers the Adjacent channel rssi and
1221 * data count(here number of BSS observed)
1222 * @spect_ch: Channel Information
1223 * @chan_width: Channel width parsed from beacon IE
1224 * @sec_chan_offset: Secondary Channel Offset
1225 * @center_freq: Central frequency for the given channel.
1226 * @channel_id: channel_id
Liangwei Dong71ed6502016-10-20 03:40:45 -04001227 * @spectch_start: the start of spect ch array
1228 * @spectch_end: the end of spect ch array
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001229 *
1230 * sap_interference_rssi_count_5G considers the Adjacent channel rssi
1231 * and data count(here number of BSS observed)
1232 *
1233 * Return: NA.
1234 */
1235
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001236static void sap_interference_rssi_count_5G(tSapSpectChInfo *spect_ch,
1237 uint16_t chan_width,
1238 uint16_t sec_chan_offset,
1239 uint16_t center_freq,
1240 uint16_t center_freq_2,
Liangwei Dong71ed6502016-10-20 03:40:45 -04001241 uint8_t channel_id,
1242 tSapSpectChInfo *spectch_start,
1243 tSapSpectChInfo *spectch_end)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001244{
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001245 uint16_t num_ch;
1246 int32_t offset = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001247 if (NULL == spect_ch) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301248 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001249 FL("spect_ch is NULL"));
1250 return;
1251 }
1252
1253 /* Updating the received ChannelWidth */
1254 if (spect_ch->channelWidth != chan_width)
1255 spect_ch->channelWidth = chan_width;
1256 /* If received ChannelWidth is other than HT20,
1257 * we need to update the extension channel Params as well
1258 * chan_width == 0, HT20
1259 * chan_width == 1, HT40
1260 * chan_width == 2, VHT80
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001261 * chan_width == 3, VHT160
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001262 */
1263
1264 switch (spect_ch->channelWidth) {
1265 case eHT_CHANNEL_WIDTH_40MHZ: /* HT40 */
1266 switch (sec_chan_offset) {
1267 /* Above the Primary Channel */
1268 case PHY_DOUBLE_CHANNEL_LOW_PRIMARY:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001269 sap_update_rssi_bsscount(spect_ch, 1, false,
1270 spectch_start, spectch_end);
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001271 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001272
1273 /* Below the Primary channel */
1274 case PHY_DOUBLE_CHANNEL_HIGH_PRIMARY:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001275 sap_update_rssi_bsscount(spect_ch, -1, false,
1276 spectch_start, spectch_end);
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001277 return;
1278 }
1279 return;
1280 case eHT_CHANNEL_WIDTH_80MHZ: /* VHT80 */
1281 num_ch = 3;
1282 if ((center_freq - channel_id) == 6) {
1283 offset = 1;
1284 } else if ((center_freq - channel_id) == 2) {
1285 offset = -1;
1286 } else if ((center_freq - channel_id) == -2) {
1287 offset = -2;
1288 } else if ((center_freq - channel_id) == -6) {
1289 offset = -3;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001290 }
1291 break;
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001292 case eHT_CHANNEL_WIDTH_160MHZ: /* VHT160 */
1293 num_ch = 7;
1294 if ((center_freq - channel_id) == 14)
1295 offset = 1;
1296 else if ((center_freq - channel_id) == 10)
1297 offset = -1;
1298 else if ((center_freq - channel_id) == 6)
1299 offset = -2;
1300 else if ((center_freq - channel_id) == 2)
1301 offset = -3;
1302 else if ((center_freq - channel_id) == -2)
1303 offset = -4;
1304 else if ((center_freq - channel_id) == -6)
1305 offset = -5;
1306 else if ((center_freq - channel_id) == -10)
1307 offset = -6;
1308 else if ((center_freq - channel_id) == -14)
1309 offset = -7;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001310 break;
1311 default:
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001312 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001313 }
Liangwei Dong71ed6502016-10-20 03:40:45 -04001314 sap_update_rssi_bsscount_vht_5G(spect_ch, offset, num_ch,
1315 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001316}
1317
1318/**
1319 * sap_interference_rssi_count() - sap_interference_rssi_count
1320 * considers the Adjacent channel rssi
1321 * and data count(here number of BSS observed)
1322 * @spect_ch Channel Information
Liangwei Dong71ed6502016-10-20 03:40:45 -04001323 * @spectch_start: the start of spect ch array
1324 * @spectch_end: the end of spect ch array
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001325 *
1326 * sap_interference_rssi_count considers the Adjacent channel rssi
1327 * and data count(here number of BSS observed)
1328 *
1329 * Return: None.
1330 */
1331
Liangwei Dong71ed6502016-10-20 03:40:45 -04001332static void sap_interference_rssi_count(tSapSpectChInfo *spect_ch,
1333 tSapSpectChInfo *spectch_start,
1334 tSapSpectChInfo *spectch_end)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001335{
1336 if (NULL == spect_ch) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301337 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001338 "%s: spect_ch is NULL", __func__);
1339 return;
1340 }
1341
1342 switch (spect_ch->chNum) {
1343 case CHANNEL_1:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001344 sap_update_rssi_bsscount(spect_ch, 1, true,
1345 spectch_start, spectch_end);
1346 sap_update_rssi_bsscount(spect_ch, 2, true,
1347 spectch_start, spectch_end);
1348 sap_update_rssi_bsscount(spect_ch, 3, true,
1349 spectch_start, spectch_end);
1350 sap_update_rssi_bsscount(spect_ch, 4, true,
1351 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001352 break;
1353
1354 case CHANNEL_2:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001355 sap_update_rssi_bsscount(spect_ch, -1, true,
1356 spectch_start, spectch_end);
1357 sap_update_rssi_bsscount(spect_ch, 1, true,
1358 spectch_start, spectch_end);
1359 sap_update_rssi_bsscount(spect_ch, 2, true,
1360 spectch_start, spectch_end);
1361 sap_update_rssi_bsscount(spect_ch, 3, true,
1362 spectch_start, spectch_end);
1363 sap_update_rssi_bsscount(spect_ch, 4, true,
1364 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001365 break;
1366 case CHANNEL_3:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001367 sap_update_rssi_bsscount(spect_ch, -2, true,
1368 spectch_start, spectch_end);
1369 sap_update_rssi_bsscount(spect_ch, -1, true,
1370 spectch_start, spectch_end);
1371 sap_update_rssi_bsscount(spect_ch, 1, true,
1372 spectch_start, spectch_end);
1373 sap_update_rssi_bsscount(spect_ch, 2, true,
1374 spectch_start, spectch_end);
1375 sap_update_rssi_bsscount(spect_ch, 3, true,
1376 spectch_start, spectch_end);
1377 sap_update_rssi_bsscount(spect_ch, 4, true,
1378 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001379 break;
1380 case CHANNEL_4:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001381 sap_update_rssi_bsscount(spect_ch, -3, true,
1382 spectch_start, spectch_end);
1383 sap_update_rssi_bsscount(spect_ch, -2, true,
1384 spectch_start, spectch_end);
1385 sap_update_rssi_bsscount(spect_ch, -1, true,
1386 spectch_start, spectch_end);
1387 sap_update_rssi_bsscount(spect_ch, 1, true,
1388 spectch_start, spectch_end);
1389 sap_update_rssi_bsscount(spect_ch, 2, true,
1390 spectch_start, spectch_end);
1391 sap_update_rssi_bsscount(spect_ch, 3, true,
1392 spectch_start, spectch_end);
1393 sap_update_rssi_bsscount(spect_ch, 4, true,
1394 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001395 break;
1396
1397 case CHANNEL_5:
1398 case CHANNEL_6:
1399 case CHANNEL_7:
1400 case CHANNEL_8:
1401 case CHANNEL_9:
1402 case CHANNEL_10:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001403 sap_update_rssi_bsscount(spect_ch, -4, true,
1404 spectch_start, spectch_end);
1405 sap_update_rssi_bsscount(spect_ch, -3, true,
1406 spectch_start, spectch_end);
1407 sap_update_rssi_bsscount(spect_ch, -2, true,
1408 spectch_start, spectch_end);
1409 sap_update_rssi_bsscount(spect_ch, -1, 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, 2, true,
1414 spectch_start, spectch_end);
1415 sap_update_rssi_bsscount(spect_ch, 3, true,
1416 spectch_start, spectch_end);
1417 sap_update_rssi_bsscount(spect_ch, 4, true,
1418 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001419 break;
1420
1421 case CHANNEL_11:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001422 sap_update_rssi_bsscount(spect_ch, -4, true,
1423 spectch_start, spectch_end);
1424 sap_update_rssi_bsscount(spect_ch, -3, true,
1425 spectch_start, spectch_end);
1426 sap_update_rssi_bsscount(spect_ch, -2, true,
1427 spectch_start, spectch_end);
1428 sap_update_rssi_bsscount(spect_ch, -1, true,
1429 spectch_start, spectch_end);
1430 sap_update_rssi_bsscount(spect_ch, 1, true,
1431 spectch_start, spectch_end);
1432 sap_update_rssi_bsscount(spect_ch, 2, true,
1433 spectch_start, spectch_end);
1434 sap_update_rssi_bsscount(spect_ch, 3, true,
1435 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001436 break;
1437
1438 case CHANNEL_12:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001439 sap_update_rssi_bsscount(spect_ch, -4, 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, -2, true,
1444 spectch_start, spectch_end);
1445 sap_update_rssi_bsscount(spect_ch, -1, true,
1446 spectch_start, spectch_end);
1447 sap_update_rssi_bsscount(spect_ch, 1, true,
1448 spectch_start, spectch_end);
1449 sap_update_rssi_bsscount(spect_ch, 2, true,
1450 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001451 break;
1452
1453 case CHANNEL_13:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001454 sap_update_rssi_bsscount(spect_ch, -4, true,
1455 spectch_start, spectch_end);
1456 sap_update_rssi_bsscount(spect_ch, -3, 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, -1, true,
1461 spectch_start, spectch_end);
1462 sap_update_rssi_bsscount(spect_ch, 1, true,
1463 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001464 break;
1465
1466 case CHANNEL_14:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001467 sap_update_rssi_bsscount(spect_ch, -4, true,
1468 spectch_start, spectch_end);
1469 sap_update_rssi_bsscount(spect_ch, -3, true,
1470 spectch_start, spectch_end);
1471 sap_update_rssi_bsscount(spect_ch, -2, true,
1472 spectch_start, spectch_end);
1473 sap_update_rssi_bsscount(spect_ch, -1, true,
1474 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001475 break;
1476
1477 default:
1478 break;
1479 }
1480}
1481
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001482/**
1483 * ch_in_pcl() - Is channel in the Preferred Channel List (PCL)
1484 * @sap_ctx: SAP context which contains the current PCL
1485 * @channel: Input channel number to be checked
1486 *
1487 * Check if a channel is in the preferred channel list
1488 *
1489 * Return:
1490 * true: channel is in PCL,
1491 * false: channel is not in PCL
1492 */
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -07001493static bool ch_in_pcl(struct sap_context *sap_ctx, uint8_t channel)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001494{
1495 uint32_t i;
1496
1497 for (i = 0; i < sap_ctx->acs_cfg->pcl_ch_count; i++) {
1498 if (channel == sap_ctx->acs_cfg->pcl_channels[i])
1499 return true;
1500 }
1501
1502 return false;
1503}
1504
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001505/**
1506 * sap_compute_spect_weight() - Compute spectrum weight
1507 * @pSpectInfoParams: Pointer to the tSpectInfoParams structure
1508 * @halHandle: Pointer to HAL handle
1509 * @pResult: Pointer to tScanResultHandle
1510 * @sap_ctx: Context of the SAP
1511 *
1512 * Main function for computing the weight of each channel in the
1513 * spectrum based on the RSSI value of the BSSes on the channel
1514 * and number of BSS
1515 */
1516static void sap_compute_spect_weight(tSapChSelSpectInfo *pSpectInfoParams,
1517 tHalHandle halHandle,
1518 tScanResultHandle pResult,
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -07001519 struct sap_context *sap_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001520{
1521 int8_t rssi = 0;
1522 uint8_t chn_num = 0;
1523 uint8_t channel_id = 0;
1524
1525 tCsrScanResultInfo *pScanResult;
1526 tSapSpectChInfo *pSpectCh = pSpectInfoParams->pSpectCh;
1527 uint32_t operatingBand;
1528 uint16_t channelWidth;
1529 uint16_t secondaryChannelOffset;
1530 uint16_t centerFreq;
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001531 uint16_t centerFreq_2 = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001532 uint16_t vhtSupport;
1533 uint32_t ieLen = 0;
1534 tSirProbeRespBeacon *pBeaconStruct;
1535 tpAniSirGlobal pMac = (tpAniSirGlobal) halHandle;
Liangwei Dong71ed6502016-10-20 03:40:45 -04001536 tSapSpectChInfo *spectch_start = pSpectInfoParams->pSpectCh;
1537 tSapSpectChInfo *spectch_end = pSpectInfoParams->pSpectCh +
1538 pSpectInfoParams->numSpectChans;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001539
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301540 pBeaconStruct = qdf_mem_malloc(sizeof(tSirProbeRespBeacon));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001541 if (NULL == pBeaconStruct) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301542 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Kaushik, Sushantee3ed032016-08-04 16:40:46 +05301543 "Unable to allocate memory in sap_compute_spect_weight");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001544 return;
1545 }
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301546 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001547 "In %s, Computing spectral weight", __func__);
1548
1549 /**
1550 * Soft AP specific channel weight calculation using DFS formula
1551 */
1552 SET_ACS_BAND(operatingBand, sap_ctx);
1553
1554 pScanResult = sme_scan_result_get_first(halHandle, pResult);
1555
1556 while (pScanResult) {
1557 pSpectCh = pSpectInfoParams->pSpectCh;
1558 /* Defining the default values, so that any value will hold the default values */
1559 channelWidth = eHT_CHANNEL_WIDTH_20MHZ;
1560 secondaryChannelOffset = PHY_SINGLE_CHANNEL_CENTERED;
1561 vhtSupport = 0;
1562 centerFreq = 0;
1563
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001564
Yingying Tang22facc12016-10-20 17:43:59 +08001565 ieLen = GET_IE_LEN_IN_BSS(
1566 pScanResult->BssDescriptor.length);
1567 qdf_mem_set((uint8_t *) pBeaconStruct,
1568 sizeof(tSirProbeRespBeacon), 0);
1569
1570
1571 if ((sir_parse_beacon_ie
1572 (pMac, pBeaconStruct, (uint8_t *)
1573 (pScanResult->BssDescriptor.ieFields),
1574 ieLen)) == eSIR_SUCCESS)
1575 sap_upd_chan_spec_params(
1576 pBeaconStruct,
1577 &channelWidth,
1578 &secondaryChannelOffset,
1579 &vhtSupport, &centerFreq,
1580 &centerFreq_2);
1581
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001582 /* Processing for each tCsrScanResultInfo in the tCsrScanResult DLink list */
1583 for (chn_num = 0; chn_num < pSpectInfoParams->numSpectChans;
1584 chn_num++) {
1585
1586 /*
1587 * if the Beacon has channel ID, use it other wise we will
1588 * rely on the channelIdSelf
1589 */
1590 if (pScanResult->BssDescriptor.channelId == 0)
1591 channel_id =
1592 pScanResult->BssDescriptor.channelIdSelf;
1593 else
1594 channel_id =
1595 pScanResult->BssDescriptor.channelId;
1596
1597 if (pSpectCh && (channel_id == pSpectCh->chNum)) {
1598 if (pSpectCh->rssiAgr <
1599 pScanResult->BssDescriptor.rssi)
1600 pSpectCh->rssiAgr =
1601 pScanResult->BssDescriptor.rssi;
1602
1603 ++pSpectCh->bssCount; /* Increment the count of BSS */
1604
1605 /*
1606 * Connsidering the Extension Channel
1607 * only in a channels
1608 */
1609 switch (operatingBand) {
1610 case eCSR_DOT11_MODE_11a:
1611 sap_interference_rssi_count_5G(
1612 pSpectCh, channelWidth,
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001613 secondaryChannelOffset,
1614 centerFreq,
1615 centerFreq_2,
Liangwei Dong71ed6502016-10-20 03:40:45 -04001616 channel_id,
1617 spectch_start,
1618 spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001619 break;
1620
1621 case eCSR_DOT11_MODE_11g:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001622 sap_interference_rssi_count(pSpectCh,
1623 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001624 break;
1625
1626 case eCSR_DOT11_MODE_abg:
1627 sap_interference_rssi_count_5G(
1628 pSpectCh, channelWidth,
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001629 secondaryChannelOffset,
1630 centerFreq,
1631 centerFreq_2,
Liangwei Dong71ed6502016-10-20 03:40:45 -04001632 channel_id,
1633 spectch_start,
1634 spectch_end);
1635 sap_interference_rssi_count(pSpectCh,
1636 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001637 break;
1638 }
1639
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301640 QDF_TRACE(QDF_MODULE_ID_SAP,
1641 QDF_TRACE_LEVEL_INFO_HIGH,
Jeff Johnsona7c0ddb2017-09-18 08:14:12 -07001642 "In %s, bssdes.ch_self=%d, bssdes.ch_ID=%d, bssdes.rssi=%d, SpectCh.bssCount=%d, pScanResult=%pK, ChannelWidth %d, secondaryChanOffset %d, center frequency %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001643 __func__,
1644 pScanResult->BssDescriptor.
1645 channelIdSelf,
1646 pScanResult->BssDescriptor.channelId,
1647 pScanResult->BssDescriptor.rssi,
1648 pSpectCh->bssCount, pScanResult,
1649 pSpectCh->channelWidth,
1650 secondaryChannelOffset, centerFreq);
1651 pSpectCh++;
1652 break;
1653 } else {
1654 pSpectCh++;
1655 }
1656 }
1657
1658 pScanResult = sme_scan_result_get_next(halHandle, pResult);
1659 }
1660
1661 /* Calculate the weights for all channels in the spectrum pSpectCh */
1662 pSpectCh = pSpectInfoParams->pSpectCh;
1663
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301664 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001665 "In %s, Spectrum Channels Weight", __func__);
1666
1667 for (chn_num = 0; chn_num < (pSpectInfoParams->numSpectChans);
1668 chn_num++) {
1669
1670 /*
1671 rssi : Maximum received signal strength among all BSS on that channel
1672 bssCount : Number of BSS on that channel
1673 */
1674
1675 rssi = (int8_t) pSpectCh->rssiAgr;
1676 if (ch_in_pcl(sap_ctx, chn_num))
1677 rssi -= PCL_RSSI_DISCOUNT;
1678
1679 pSpectCh->weight =
gaoleze5108942017-03-31 16:56:42 +08001680 SAPDFS_NORMALISE_1000 *
1681 (sapweight_rssi_count(sap_ctx, rssi,
1682 pSpectCh->bssCount) + sap_weight_channel_status(
1683 sap_ctx, sap_get_channel_status(pMac,
1684 pSpectCh->chNum)));
1685 if (pSpectCh->weight > SAP_ACS_WEIGHT_MAX)
1686 pSpectCh->weight = SAP_ACS_WEIGHT_MAX;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001687 pSpectCh->weight_copy = pSpectCh->weight;
1688
1689 /* ------ Debug Info ------ */
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, Chan=%d Weight= %d rssiAgr=%d bssCount=%d",
1692 __func__, pSpectCh->chNum, pSpectCh->weight,
1693 pSpectCh->rssiAgr, pSpectCh->bssCount);
1694 /* ------ Debug Info ------ */
1695 pSpectCh++;
1696 }
gaoleze5108942017-03-31 16:56:42 +08001697 sap_clear_channel_status(pMac);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301698 qdf_mem_free(pBeaconStruct);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001699}
1700
1701/*==========================================================================
1702 FUNCTION sap_chan_sel_exit
1703
1704 DESCRIPTION
1705 Exit function for free out the allocated memory, to be called
1706 at the end of the dfsSelectChannel function
1707
1708 DEPENDENCIES
1709 NA.
1710
1711 PARAMETERS
1712
1713 IN
1714 pSpectInfoParams : Pointer to the tSapChSelSpectInfo structure
1715
1716 RETURN VALUE
1717 void : NULL
1718
1719 SIDE EFFECTS
1720 ============================================================================*/
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001721static void sap_chan_sel_exit(tSapChSelSpectInfo *pSpectInfoParams)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001722{
1723 /* Free all the allocated memory */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301724 qdf_mem_free(pSpectInfoParams->pSpectCh);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001725}
1726
1727/*==========================================================================
1728 FUNCTION sap_sort_chl_weight
1729
1730 DESCRIPTION
1731 Funtion to sort the channels with the least weight first for 20MHz channels
1732
1733 DEPENDENCIES
1734 NA.
1735
1736 PARAMETERS
1737
1738 IN
1739 pSpectInfoParams : Pointer to the tSapChSelSpectInfo structure
1740
1741 RETURN VALUE
1742 void : NULL
1743
1744 SIDE EFFECTS
1745 ============================================================================*/
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001746static void sap_sort_chl_weight(tSapChSelSpectInfo *pSpectInfoParams)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001747{
1748 tSapSpectChInfo temp;
1749
1750 tSapSpectChInfo *pSpectCh = NULL;
1751 uint32_t i = 0, j = 0, minWeightIndex = 0;
1752
1753 pSpectCh = pSpectInfoParams->pSpectCh;
1754 for (i = 0; i < pSpectInfoParams->numSpectChans; i++) {
1755 minWeightIndex = i;
1756 for (j = i + 1; j < pSpectInfoParams->numSpectChans; j++) {
1757 if (pSpectCh[j].weight <
1758 pSpectCh[minWeightIndex].weight) {
1759 minWeightIndex = j;
1760 }
1761 }
1762 if (minWeightIndex != i) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301763 qdf_mem_copy(&temp, &pSpectCh[minWeightIndex],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001764 sizeof(*pSpectCh));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301765 qdf_mem_copy(&pSpectCh[minWeightIndex], &pSpectCh[i],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001766 sizeof(*pSpectCh));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301767 qdf_mem_copy(&pSpectCh[i], &temp, sizeof(*pSpectCh));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001768 }
1769 }
1770}
1771
1772/**
bingse2782382017-03-23 10:34:52 +08001773 * set_ht80_chl_bit() - to set availabe channel to ht80 channel bitmap
1774 * @channel_bitmap: Pointer to the chan_bonding_bitmap structure
1775 * @spect_info_params: Pointer to the tSapChSelSpectInfo structure
1776 *
1777 * Return: none
1778 */
1779static void set_ht80_chl_bit(chan_bonding_bitmap *channel_bitmap,
1780 tSapChSelSpectInfo *spec_info_params)
1781{
1782 uint8_t i, j;
1783 tSapSpectChInfo *spec_info;
1784 int start_channel = 0;
1785
1786 channel_bitmap->chanBondingSet[0].startChannel =
1787 acs_ht80_channels[0].chStartNum;
1788 channel_bitmap->chanBondingSet[1].startChannel =
1789 acs_ht80_channels[1].chStartNum;
1790 channel_bitmap->chanBondingSet[2].startChannel =
1791 acs_ht80_channels[2].chStartNum;
1792 channel_bitmap->chanBondingSet[3].startChannel =
1793 acs_ht80_channels[3].chStartNum;
1794 channel_bitmap->chanBondingSet[4].startChannel =
1795 acs_ht80_channels[4].chStartNum;
1796 channel_bitmap->chanBondingSet[5].startChannel =
1797 acs_ht80_channels[5].chStartNum;
1798
1799 spec_info = spec_info_params->pSpectCh;
1800 for (j = 0; j < spec_info_params->numSpectChans; j++) {
1801 for (i = 0; i < MAX_80MHZ_BANDS; i++) {
1802 start_channel =
1803 channel_bitmap->chanBondingSet[i].startChannel;
1804 if (spec_info[j].chNum >= start_channel &&
1805 (spec_info[j].chNum <= start_channel + 12)) {
1806 channel_bitmap->chanBondingSet[i].channelMap |=
1807 1 << ((spec_info[j].chNum -
1808 start_channel)/4);
1809 break;
1810 }
1811 }
1812 }
1813}
1814
1815/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001816 * sap_sort_chl_weight_ht80() - to sort the channels with the least weight
1817 * @pSpectInfoParams: Pointer to the tSapChSelSpectInfo structure
1818 *
1819 * Funtion to sort the channels with the least weight first for HT80 channels
1820 *
1821 * Return: none
1822 */
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001823static void sap_sort_chl_weight_ht80(tSapChSelSpectInfo *pSpectInfoParams)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001824{
1825 uint8_t i, j, n;
1826 tSapSpectChInfo *pSpectInfo;
1827 uint8_t minIdx;
bingse2782382017-03-23 10:34:52 +08001828 int start_channel = 0;
1829 chan_bonding_bitmap *channel_bitmap;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001830
bingse2782382017-03-23 10:34:52 +08001831 channel_bitmap = qdf_mem_malloc(sizeof(chan_bonding_bitmap));
1832 if (NULL == channel_bitmap) {
1833 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG,
1834 "%s: Failed to allocate memory", __func__);
1835 return;
1836 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001837 pSpectInfo = pSpectInfoParams->pSpectCh;
1838 /* for each HT80 channel, calculate the combined weight of the
1839 four 20MHz weight */
1840 for (i = 0; i < ARRAY_SIZE(acs_ht80_channels); i++) {
1841 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
1842 if (pSpectInfo[j].chNum ==
1843 acs_ht80_channels[i].chStartNum)
1844 break;
1845 }
1846 if (j == pSpectInfoParams->numSpectChans)
1847 continue;
1848
1849 if (!(((pSpectInfo[j].chNum + 4) == pSpectInfo[j + 1].chNum) &&
1850 ((pSpectInfo[j].chNum + 8) ==
1851 pSpectInfo[j + 2].chNum) &&
1852 ((pSpectInfo[j].chNum + 12) ==
1853 pSpectInfo[j + 3].chNum))) {
1854 /*
1855 * some channels does not exist in pSectInfo array,
1856 * skip this channel and those in the same HT80 width
1857 */
1858 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 4;
1859 if ((pSpectInfo[j].chNum + 4) ==
1860 pSpectInfo[j + 1].chNum)
1861 pSpectInfo[j + 1].weight =
1862 SAP_ACS_WEIGHT_MAX * 4;
1863 if ((pSpectInfo[j].chNum + 8) ==
1864 pSpectInfo[j + 2].chNum)
1865 pSpectInfo[j + 2].weight =
1866 SAP_ACS_WEIGHT_MAX * 4;
1867 if ((pSpectInfo[j].chNum + 12) ==
1868 pSpectInfo[j + 3].chNum)
1869 pSpectInfo[j + 3].weight =
1870 SAP_ACS_WEIGHT_MAX * 4;
1871 continue;
1872 }
1873 /*found the channel, add the 4 adjacent channels' weight */
1874 acs_ht80_channels[i].weight = pSpectInfo[j].weight +
1875 pSpectInfo[j + 1].weight + pSpectInfo[j + 2].weight +
1876 pSpectInfo[j + 3].weight;
1877 /* find best channel among 4 channels as the primary channel */
1878 if ((pSpectInfo[j].weight + pSpectInfo[j + 1].weight) <
1879 (pSpectInfo[j + 2].weight + pSpectInfo[j + 3].weight)) {
1880 /* lower 2 channels are better choice */
1881 if (pSpectInfo[j].weight < pSpectInfo[j + 1].weight)
1882 minIdx = 0;
1883 else
1884 minIdx = 1;
1885 } else if (pSpectInfo[j + 2].weight <=
1886 pSpectInfo[j + 3].weight) {
1887 /* upper 2 channels are better choice */
1888 minIdx = 2;
1889 } else {
1890 minIdx = 3;
1891 }
1892
1893 /*
1894 * set all 4 channels to max value first, then reset the
1895 * best channel as the selected primary channel, update its
1896 * weightage with the combined weight value
1897 */
1898 for (n = 0; n < 4; n++)
1899 pSpectInfo[j + n].weight = SAP_ACS_WEIGHT_MAX * 4;
1900
1901 pSpectInfo[j + minIdx].weight = acs_ht80_channels[i].weight;
1902 }
1903
bingse2782382017-03-23 10:34:52 +08001904 /*
1905 * mark the weight of the channel that can't satisfy 80MHZ
1906 * as max value, so that it will be sorted to the bottom
1907 */
1908 set_ht80_chl_bit(channel_bitmap, pSpectInfoParams);
1909 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
1910 for (i = 0; i < MAX_80MHZ_BANDS; i++) {
1911 start_channel =
1912 channel_bitmap->chanBondingSet[i].startChannel;
1913 if (pSpectInfo[j].chNum >= start_channel &&
1914 (pSpectInfo[j].chNum <=
1915 start_channel + 12) &&
1916 channel_bitmap->chanBondingSet[i].channelMap !=
1917 SAP_80MHZ_MASK)
1918 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 4;
1919 }
1920 }
1921
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001922 pSpectInfo = pSpectInfoParams->pSpectCh;
1923 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
1924 if (CHANNEL_165 == pSpectInfo[j].chNum) {
1925 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 4;
1926 break;
1927 }
1928 }
1929
Manishekar Chandrasekaran44e334f2016-05-30 16:42:50 +05301930 sap_sort_chl_weight(pSpectInfoParams);
1931
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001932 pSpectInfo = pSpectInfoParams->pSpectCh;
1933 for (j = 0; j < (pSpectInfoParams->numSpectChans); j++) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301934 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001935 FL("Channel=%d Weight= %d rssi=%d bssCount=%d"),
1936 pSpectInfo->chNum, pSpectInfo->weight,
1937 pSpectInfo->rssiAgr, pSpectInfo->bssCount);
1938 pSpectInfo++;
1939 }
bingse2782382017-03-23 10:34:52 +08001940 qdf_mem_free(channel_bitmap);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001941}
1942
1943/**
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001944 * sap_sort_chl_weight_vht160() - to sort the channels with the least weight
1945 * @pSpectInfoParams: Pointer to the tSapChSelSpectInfo structure
1946 *
1947 * Funtion to sort the channels with the least weight first for VHT160 channels
1948 *
1949 * Return: none
1950 */
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001951static void sap_sort_chl_weight_vht160(tSapChSelSpectInfo *pSpectInfoParams)
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001952{
1953 uint8_t i, j, n, idx;
1954 tSapSpectChInfo *pSpectInfo;
1955 uint8_t minIdx;
1956
1957 pSpectInfo = pSpectInfoParams->pSpectCh;
1958 /* for each VHT160 channel, calculate the combined weight of the
1959 8 20MHz weight */
1960 for (i = 0; i < ARRAY_SIZE(acs_vht160_channels); i++) {
1961 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
1962 if (pSpectInfo[j].chNum ==
1963 acs_vht160_channels[i].chStartNum)
1964 break;
1965 }
1966 if (j == pSpectInfoParams->numSpectChans)
1967 continue;
1968
1969 if (!(((pSpectInfo[j].chNum + 4) == pSpectInfo[j + 1].chNum) &&
1970 ((pSpectInfo[j].chNum + 8) ==
1971 pSpectInfo[j + 2].chNum) &&
1972 ((pSpectInfo[j].chNum + 12) ==
1973 pSpectInfo[j + 3].chNum) &&
1974 ((pSpectInfo[j].chNum + 16) ==
1975 pSpectInfo[j + 4].chNum) &&
1976 ((pSpectInfo[j].chNum + 20) ==
1977 pSpectInfo[j + 5].chNum) &&
1978 ((pSpectInfo[j].chNum + 24) ==
1979 pSpectInfo[j + 6].chNum) &&
1980 ((pSpectInfo[j].chNum + 28) ==
1981 pSpectInfo[j + 7].chNum))) {
1982 /*
1983 * some channels does not exist in pSectInfo array,
1984 * skip this channel and those in the same VHT160 width
1985 */
1986 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 8;
1987 if ((pSpectInfo[j].chNum + 4) ==
1988 pSpectInfo[j + 1].chNum)
1989 pSpectInfo[j + 1].weight =
1990 SAP_ACS_WEIGHT_MAX * 8;
1991 if ((pSpectInfo[j].chNum + 8) ==
1992 pSpectInfo[j + 2].chNum)
1993 pSpectInfo[j + 2].weight =
1994 SAP_ACS_WEIGHT_MAX * 8;
1995 if ((pSpectInfo[j].chNum + 12) ==
1996 pSpectInfo[j + 3].chNum)
1997 pSpectInfo[j + 3].weight =
1998 SAP_ACS_WEIGHT_MAX * 8;
1999 if ((pSpectInfo[j].chNum + 16) ==
2000 pSpectInfo[j + 4].chNum)
2001 pSpectInfo[j + 4].weight =
2002 SAP_ACS_WEIGHT_MAX * 8;
2003 if ((pSpectInfo[j].chNum + 20) ==
2004 pSpectInfo[j + 5].chNum)
2005 pSpectInfo[j + 5].weight =
2006 SAP_ACS_WEIGHT_MAX * 8;
2007 if ((pSpectInfo[j].chNum + 24) ==
2008 pSpectInfo[j + 6].chNum)
2009 pSpectInfo[j + 6].weight =
2010 SAP_ACS_WEIGHT_MAX * 8;
2011 if ((pSpectInfo[j].chNum + 28) ==
2012 pSpectInfo[j + 7].chNum)
2013 pSpectInfo[j + 7].weight =
2014 SAP_ACS_WEIGHT_MAX * 8;
2015 continue;
2016 }
2017 /*found the channel, add the 7 adjacent channels' weight */
2018 acs_vht160_channels[i].weight = pSpectInfo[j].weight +
2019 pSpectInfo[j + 1].weight + pSpectInfo[j + 2].weight +
2020 pSpectInfo[j + 3].weight + pSpectInfo[j + 4].weight +
2021 pSpectInfo[j + 5].weight + pSpectInfo[j + 6].weight +
2022 pSpectInfo[j + 7].weight;
2023
2024 /* find best channel among 8 channels as the primary channel */
2025 if ((pSpectInfo[j].weight + pSpectInfo[j + 1].weight +
2026 pSpectInfo[j + 2].weight + pSpectInfo[j + 3].weight) >
2027 (pSpectInfo[j + 4].weight + pSpectInfo[j + 5].weight +
2028 pSpectInfo[j + 6].weight + pSpectInfo[j + 7].weight))
2029 idx = 4;
2030 else
2031 idx = 0;
2032 /* find best channel among 4 channels as the primary channel */
2033 if ((pSpectInfo[j + idx].weight +
2034 pSpectInfo[j + idx + 1].weight) <
2035 (pSpectInfo[j + idx + 2].weight +
2036 pSpectInfo[j + idx + 3].weight)) {
2037 /* lower 2 channels are better choice */
2038 if (pSpectInfo[j + idx].weight <
2039 pSpectInfo[j + idx + 1].weight)
2040 minIdx = 0 + idx;
2041 else
2042 minIdx = 1 + idx;
2043 } else if (pSpectInfo[j + idx + 2].weight <=
2044 pSpectInfo[j + idx + 3].weight) {
2045 /* upper 2 channels are better choice */
2046 minIdx = 2 + idx;
2047 } else {
2048 minIdx = 3 + idx;
2049 }
2050
2051 /*
2052 * set all 8 channels to max value first, then reset the
2053 * best channel as the selected primary channel, update its
2054 * weightage with the combined weight value
2055 */
2056 for (n = 0; n < 8; n++)
2057 pSpectInfo[j + n].weight = SAP_ACS_WEIGHT_MAX * 8;
2058
2059 pSpectInfo[j + minIdx].weight = acs_vht160_channels[i].weight;
2060 }
2061
2062 pSpectInfo = pSpectInfoParams->pSpectCh;
2063 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
2064 if (CHANNEL_165 == pSpectInfo[j].chNum) {
2065 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 8;
2066 break;
2067 }
2068 }
2069
Manishekar Chandrasekaran44e334f2016-05-30 16:42:50 +05302070 sap_sort_chl_weight(pSpectInfoParams);
2071
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07002072 pSpectInfo = pSpectInfoParams->pSpectCh;
2073 for (j = 0; j < (pSpectInfoParams->numSpectChans); j++) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302074 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07002075 FL("Channel=%d Weight= %d rssi=%d bssCount=%d"),
2076 pSpectInfo->chNum, pSpectInfo->weight,
2077 pSpectInfo->rssiAgr, pSpectInfo->bssCount);
2078 pSpectInfo++;
2079 }
2080}
2081
2082/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002083 * sap_sort_chl_weight_ht40_24_g() - to sort channel with the least weight
2084 * @pSpectInfoParams: Pointer to the tSapChSelSpectInfo structure
2085 *
2086 * Funtion to sort the channels with the least weight first for HT40 channels
2087 *
2088 * Return: none
2089 */
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002090static void sap_sort_chl_weight_ht40_24_g(tSapChSelSpectInfo *pSpectInfoParams,
2091 v_REGDOMAIN_t domain)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002092{
2093 uint8_t i, j;
2094 tSapSpectChInfo *pSpectInfo;
2095 uint32_t tmpWeight1, tmpWeight2;
bingse2782382017-03-23 10:34:52 +08002096 uint32_t ht40plus2gendch = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002097
2098 pSpectInfo = pSpectInfoParams->pSpectCh;
2099 /*
2100 * for each HT40 channel, calculate the combined weight of the
2101 * two 20MHz weight
2102 */
2103 for (i = 0; i < ARRAY_SIZE(acs_ht40_channels24_g); i++) {
2104 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
2105 if (pSpectInfo[j].chNum ==
2106 acs_ht40_channels24_g[i].chStartNum)
2107 break;
2108 }
2109 if (j == pSpectInfoParams->numSpectChans)
2110 continue;
2111
2112 if (!((pSpectInfo[j].chNum + 4) == pSpectInfo[j + 4].chNum)) {
2113 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2;
2114 continue;
2115 }
2116 /*
2117 * check if there is another channel combination possiblity
2118 * e.g., {1, 5} & {5, 9}
2119 */
2120 if ((pSpectInfo[j + 4].chNum + 4) == pSpectInfo[j + 8].chNum) {
2121 /* need to compare two channel pairs */
2122 tmpWeight1 = pSpectInfo[j].weight +
2123 pSpectInfo[j + 4].weight;
2124 tmpWeight2 = pSpectInfo[j + 4].weight +
2125 pSpectInfo[j + 8].weight;
2126 if (tmpWeight1 <= tmpWeight2) {
2127 if (pSpectInfo[j].weight <=
2128 pSpectInfo[j + 4].weight) {
2129 pSpectInfo[j].weight =
2130 tmpWeight1;
2131 pSpectInfo[j + 4].weight =
2132 SAP_ACS_WEIGHT_MAX * 2;
2133 pSpectInfo[j + 8].weight =
2134 SAP_ACS_WEIGHT_MAX * 2;
2135 } else {
2136 pSpectInfo[j + 4].weight =
2137 tmpWeight1;
2138 /* for secondary channel selection */
2139 pSpectInfo[j].weight =
2140 SAP_ACS_WEIGHT_MAX * 2
2141 - 1;
2142 pSpectInfo[j + 8].weight =
2143 SAP_ACS_WEIGHT_MAX * 2;
2144 }
2145 } else {
2146 if (pSpectInfo[j + 4].weight <=
2147 pSpectInfo[j + 8].weight) {
2148 pSpectInfo[j + 4].weight =
2149 tmpWeight2;
2150 pSpectInfo[j].weight =
2151 SAP_ACS_WEIGHT_MAX * 2;
2152 /* for secondary channel selection */
2153 pSpectInfo[j + 8].weight =
2154 SAP_ACS_WEIGHT_MAX * 2
2155 - 1;
2156 } else {
2157 pSpectInfo[j + 8].weight =
2158 tmpWeight2;
2159 pSpectInfo[j].weight =
2160 SAP_ACS_WEIGHT_MAX * 2;
2161 pSpectInfo[j + 4].weight =
2162 SAP_ACS_WEIGHT_MAX * 2;
2163 }
2164 }
2165 } else {
bingsaa6f96a2017-09-11 09:49:43 +08002166 tmpWeight1 = pSpectInfo[j].weight_copy +
2167 pSpectInfo[j + 4].weight_copy;
2168 if (pSpectInfo[j].weight_copy <=
2169 pSpectInfo[j + 4].weight_copy) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002170 pSpectInfo[j].weight = tmpWeight1;
2171 pSpectInfo[j + 4].weight =
2172 SAP_ACS_WEIGHT_MAX * 2;
2173 } else {
2174 pSpectInfo[j + 4].weight = tmpWeight1;
2175 pSpectInfo[j].weight =
2176 SAP_ACS_WEIGHT_MAX * 2;
2177 }
2178 }
2179 }
bingse2782382017-03-23 10:34:52 +08002180 /*
2181 * Every channel should be checked. Add the check for the omissive
2182 * channel. Mark the channel whose combination can't satisfy 40MHZ
2183 * as max value, so that it will be sorted to the bottom.
2184 */
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002185 if (REGDOMAIN_FCC == domain)
bingse2782382017-03-23 10:34:52 +08002186 ht40plus2gendch = HT40PLUS_2G_FCC_CH_END;
2187 else
2188 ht40plus2gendch = HT40PLUS_2G_EURJAP_CH_END;
2189 for (i = HT40MINUS_2G_CH_START; i <= ht40plus2gendch; i++) {
2190 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
2191 if (pSpectInfo[j].chNum == i &&
2192 ((pSpectInfo[j].chNum + 4) !=
2193 pSpectInfo[j+4].chNum) &&
2194 ((pSpectInfo[j].chNum - 4) !=
2195 pSpectInfo[j-4].chNum))
2196 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2;
2197 }
2198 }
2199 for (i = ht40plus2gendch + 1; i <= HT40MINUS_2G_CH_END; i++) {
2200 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
2201 if (pSpectInfo[j].chNum == i &&
2202 (pSpectInfo[j].chNum - 4) !=
2203 pSpectInfo[j-4].chNum)
2204 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2;
2205 }
2206 }
Manishekar Chandrasekaran44e334f2016-05-30 16:42:50 +05302207 sap_sort_chl_weight(pSpectInfoParams);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002208}
2209
2210/*==========================================================================
2211 FUNCTION sap_sort_chl_weight_ht40_5_g
2212
2213 DESCRIPTION
2214 Funtion to sort the channels with the least weight first for HT40 channels
2215
2216 DEPENDENCIES
2217 NA.
2218
2219 PARAMETERS
2220
2221 IN
2222 pSpectInfoParams : Pointer to the tSapChSelSpectInfo structure
2223
2224 RETURN VALUE
2225 void : NULL
2226
2227 SIDE EFFECTS
2228 ============================================================================*/
Jeff Johnson464f7ea2016-10-07 10:21:26 -07002229static void sap_sort_chl_weight_ht40_5_g(tSapChSelSpectInfo *pSpectInfoParams)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002230{
2231 uint8_t i, j;
2232 tSapSpectChInfo *pSpectInfo;
2233
2234 pSpectInfo = pSpectInfoParams->pSpectCh;
2235 /*for each HT40 channel, calculate the combined weight of the
2236 two 20MHz weight */
2237 for (i = 0; i < ARRAY_SIZE(acs_ht40_channels5_g); i++) {
2238 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
2239 if (pSpectInfo[j].chNum ==
2240 acs_ht40_channels5_g[i].chStartNum)
2241 break;
2242 }
2243 if (j == pSpectInfoParams->numSpectChans)
2244 continue;
2245
2246 /* found the channel, add the two adjacent channels' weight */
2247 if ((pSpectInfo[j].chNum + 4) == pSpectInfo[j + 1].chNum) {
2248 acs_ht40_channels5_g[i].weight = pSpectInfo[j].weight +
2249 pSpectInfo[j + 1].weight;
2250 /* select better of the adjact channel as the primary channel */
2251 if (pSpectInfo[j].weight <= pSpectInfo[j + 1].weight) {
2252 pSpectInfo[j].weight =
2253 acs_ht40_channels5_g[i].weight;
2254 /* mark the adjacent channel's weight as max value so
2255 that it will be sorted to the bottom */
2256 pSpectInfo[j + 1].weight =
2257 SAP_ACS_WEIGHT_MAX * 2;
2258 } else {
2259 pSpectInfo[j + 1].weight =
2260 acs_ht40_channels5_g[i].weight;
2261 /* mark the adjacent channel's weight as max value so
2262 that it will be sorted to the bottom */
2263 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2;
2264 }
2265
2266 } else
2267 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2;
2268 }
2269
bingse2782382017-03-23 10:34:52 +08002270 /*
2271 *Every channel should be checked. Add the check for the omissive
2272 * channel. Mark the channel whose combination can't satisfy 40MHZ
2273 * as max value, so that it will be sorted to the bottom
2274 */
2275 for (j = 1; j < pSpectInfoParams->numSpectChans; j++) {
2276 for (i = 0; i < ARRAY_SIZE(acs_ht40_channels5_g); i++) {
2277 if (pSpectInfo[j].chNum ==
2278 (acs_ht40_channels5_g[i].chStartNum +
2279 4) &&
2280 pSpectInfo[j - 1].chNum !=
2281 acs_ht40_channels5_g[i].chStartNum) {
2282 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2;
2283 break;
2284 }
2285 }
2286 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002287 /* avoid channel 165 by setting its weight to max */
2288 pSpectInfo = pSpectInfoParams->pSpectCh;
2289 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
2290 if (CHANNEL_165 == pSpectInfo[j].chNum) {
2291 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2;
2292 break;
2293 }
2294 }
2295
2296 pSpectInfo = pSpectInfoParams->pSpectCh;
2297 for (j = 0; j < (pSpectInfoParams->numSpectChans); j++) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302298 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002299 "In %s, Channel=%d Weight= %d rssi=%d bssCount=%d",
2300 __func__, pSpectInfo->chNum, pSpectInfo->weight,
2301 pSpectInfo->rssiAgr, pSpectInfo->bssCount);
2302 pSpectInfo++;
2303 }
2304
2305 sap_sort_chl_weight(pSpectInfoParams);
2306}
2307
2308/*==========================================================================
2309 FUNCTION sap_sort_chl_weight_all
2310
2311 DESCRIPTION
2312 Funtion to sort the channels with the least weight first
2313
2314 DEPENDENCIES
2315 NA.
2316
2317 PARAMETERS
2318
2319 IN
Jeff Johnsone13d8062017-09-28 06:54:55 -07002320 sap_ctx : Pointer to the struct sap_context *structure
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002321 pSpectInfoParams : Pointer to the tSapChSelSpectInfo structure
2322
2323 RETURN VALUE
2324 void : NULL
2325
2326 SIDE EFFECTS
2327 ============================================================================*/
Jeff Johnsone13d8062017-09-28 06:54:55 -07002328static void sap_sort_chl_weight_all(struct sap_context *sap_ctx,
Jeff Johnson464f7ea2016-10-07 10:21:26 -07002329 tSapChSelSpectInfo *pSpectInfoParams,
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002330 uint32_t operatingBand,
2331 v_REGDOMAIN_t domain)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002332{
2333 tSapSpectChInfo *pSpectCh = NULL;
2334 uint32_t j = 0;
2335#ifndef SOFTAP_CHANNEL_RANGE
2336 uint32_t i = 0;
2337#endif
2338
2339 pSpectCh = pSpectInfoParams->pSpectCh;
2340#ifdef SOFTAP_CHANNEL_RANGE
2341
Jeff Johnsone13d8062017-09-28 06:54:55 -07002342 switch (sap_ctx->acs_cfg->ch_width) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002343 case CH_WIDTH_40MHZ:
2344 if (eCSR_DOT11_MODE_11g == operatingBand)
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002345 sap_sort_chl_weight_ht40_24_g(pSpectInfoParams, domain);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002346 else if (eCSR_DOT11_MODE_11a == operatingBand)
2347 sap_sort_chl_weight_ht40_5_g(pSpectInfoParams);
2348 else {
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002349 sap_sort_chl_weight_ht40_24_g(pSpectInfoParams, domain);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002350 sap_sort_chl_weight_ht40_5_g(pSpectInfoParams);
2351 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002352 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002353 case CH_WIDTH_80MHZ:
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07002354 case CH_WIDTH_80P80MHZ:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002355 sap_sort_chl_weight_ht80(pSpectInfoParams);
2356 break;
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07002357 case CH_WIDTH_160MHZ:
2358 sap_sort_chl_weight_vht160(pSpectInfoParams);
2359 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002360 case CH_WIDTH_20MHZ:
2361 default:
2362 /* Sorting the channels as per weights as 20MHz channels */
2363 sap_sort_chl_weight(pSpectInfoParams);
2364 }
2365
2366#else
2367 /* Sorting the channels as per weights */
2368 for (i = 0; i < SPECT_24GHZ_CH_COUNT; i++) {
2369 minWeightIndex = i;
2370 for (j = i + 1; j < SPECT_24GHZ_CH_COUNT; j++) {
2371 if (pSpectCh[j].weight <
2372 pSpectCh[minWeightIndex].weight) {
2373 minWeightIndex = j;
2374 }
2375 }
2376 if (minWeightIndex != i) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302377 qdf_mem_copy(&temp, &pSpectCh[minWeightIndex],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002378 sizeof(*pSpectCh));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302379 qdf_mem_copy(&pSpectCh[minWeightIndex], &pSpectCh[i],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002380 sizeof(*pSpectCh));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302381 qdf_mem_copy(&pSpectCh[i], &temp, sizeof(*pSpectCh));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002382 }
2383 }
2384#endif
2385
2386 /* For testing */
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302387 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002388 "In %s, Sorted Spectrum Channels Weight", __func__);
2389 pSpectCh = pSpectInfoParams->pSpectCh;
2390 for (j = 0; j < (pSpectInfoParams->numSpectChans); j++) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302391 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002392 "In %s, Channel=%d Weight= %d rssi=%d bssCount=%d",
2393 __func__, pSpectCh->chNum, pSpectCh->weight,
2394 pSpectCh->rssiAgr, pSpectCh->bssCount);
2395 pSpectCh++;
2396 }
2397
2398}
2399
Naveen Rawatbec64d92017-09-13 14:35:21 -07002400/**
2401 * sap_is_ch_non_overlap() - returns true if non-overlapping channel
2402 * @sap_ctx: Sap context
2403 * @ch: channel number
2404 *
2405 * Returns: true if non-overlapping (1, 6, 11) channel, false otherwise
2406 */
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -07002407static bool sap_is_ch_non_overlap(struct sap_context *sap_ctx, uint16_t ch)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002408{
Naveen Rawatbec64d92017-09-13 14:35:21 -07002409 if (sap_ctx->enableOverLapCh)
Srinivas Girigowda74a66d62017-06-21 23:28:25 -07002410 return true;
Naveen Rawatbec64d92017-09-13 14:35:21 -07002411
2412 if ((ch == CHANNEL_1) || (ch == CHANNEL_6) || (ch == CHANNEL_11))
Srinivas Girigowda74a66d62017-06-21 23:28:25 -07002413 return true;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002414
Srinivas Girigowda74a66d62017-06-21 23:28:25 -07002415 return false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002416}
2417
Dustin Brown0ce56d32016-10-17 16:18:03 -07002418#ifdef FEATURE_WLAN_CH_AVOID
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002419/**
2420 * sap_select_channel_no_scan_result() - select SAP channel when no scan results
2421 * are available.
2422 * @sap_ctx: Sap context
2423 *
2424 * Returns: channel number if success, 0 otherwise
2425 */
Kondabattini, Ganesh13bb4b12016-09-04 16:16:53 +05302426static uint8_t sap_select_channel_no_scan_result(tHalHandle hal,
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -07002427 struct sap_context *sap_ctx)
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002428{
Mohit Khanna841044f2016-03-25 16:16:24 -07002429 enum channel_state ch_type;
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002430 uint8_t i, first_safe_ch_in_range = SAP_CHANNEL_NOT_SELECTED;
Kondabattini, Ganesh13bb4b12016-09-04 16:16:53 +05302431 uint32_t dfs_master_cap_enabled;
Dustin Brown0ce56d32016-10-17 16:18:03 -07002432 uint32_t start_ch_num = sap_ctx->acs_cfg->start_ch;
2433 uint32_t end_ch_num = sap_ctx->acs_cfg->end_ch;
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002434 tpAniSirGlobal mac_ctx = NULL;
2435
2436 mac_ctx = PMAC_STRUCT(hal);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002437
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002438 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2439 FL("start - end: %d - %d"), start_ch_num, end_ch_num);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002440
Kondabattini, Ganesh13bb4b12016-09-04 16:16:53 +05302441 sme_cfg_get_int(hal, WNI_CFG_DFS_MASTER_ENABLED,
2442 &dfs_master_cap_enabled);
2443
2444 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2445 "%s: dfs_master %x", __func__, dfs_master_cap_enabled);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002446
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002447 /* get a channel in PCL and within the range */
2448 for (i = 0; i < sap_ctx->acs_cfg->pcl_ch_count; i++) {
2449 if ((sap_ctx->acs_cfg->pcl_channels[i] < start_ch_num) ||
2450 (sap_ctx->acs_cfg->pcl_channels[i] > end_ch_num))
2451 continue;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002452
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002453 first_safe_ch_in_range = sap_ctx->acs_cfg->pcl_channels[i];
2454 break;
2455 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002456
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002457 if (SAP_CHANNEL_NOT_SELECTED != first_safe_ch_in_range)
2458 return first_safe_ch_in_range;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002459
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002460 for (i = 0; i < NUM_CHANNELS; i++) {
2461 if ((safe_channels[i].channelNumber < start_ch_num) ||
2462 (safe_channels[i].channelNumber > end_ch_num))
2463 continue;
2464
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002465 ch_type = wlan_reg_get_channel_state(mac_ctx->pdev,
2466 safe_channels[i].channelNumber);
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002467
2468 if ((ch_type == CHANNEL_STATE_DISABLE) ||
2469 (ch_type == CHANNEL_STATE_INVALID))
2470 continue;
Kondabattini, Ganesh13bb4b12016-09-04 16:16:53 +05302471 if ((!dfs_master_cap_enabled) &&
2472 (CHANNEL_STATE_DFS == ch_type)) {
2473 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2474 "%s: DFS master mode disabled. Skip DFS channel %d",
2475 __func__, safe_channels[i].channelNumber);
2476 continue;
2477 }
Agrawal Ashish65634612016-08-18 13:24:32 +05302478 if ((sap_ctx->dfs_mode == ACS_DFS_MODE_DISABLE) &&
2479 (CHANNEL_STATE_DFS == ch_type))
2480 continue;
Kondabattini, Ganesh13bb4b12016-09-04 16:16:53 +05302481
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002482 if (safe_channels[i].isSafe == true) {
2483 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2484 FL("channel %d in the configuration is safe"),
2485 safe_channels[i].channelNumber);
2486 first_safe_ch_in_range = safe_channels[i].channelNumber;
2487 break;
2488 }
2489
2490 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2491 FL("channel %d in the configuration is unsafe"),
2492 safe_channels[i].channelNumber);
2493 }
2494
2495 /* if no channel selected return SAP_CHANNEL_NOT_SELECTED */
2496 return first_safe_ch_in_range;
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002497}
Dustin Brown0ce56d32016-10-17 16:18:03 -07002498#else
2499static uint8_t sap_select_channel_no_scan_result(tHalHandle hal,
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -07002500 struct sap_context *sap_ctx)
Dustin Brown0ce56d32016-10-17 16:18:03 -07002501{
2502 uint32_t start_ch_num = sap_ctx->acs_cfg->start_ch;
2503
2504 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2505 FL("start - end: %d - %d"),
2506 start_ch_num,
2507 sap_ctx->acs_cfg->end_ch);
2508
2509 sap_ctx->acs_cfg->pri_ch = start_ch_num;
2510 sap_ctx->acs_cfg->ht_sec_ch = 0;
2511
2512 /* pick the first channel in configured range */
2513 return start_ch_num;
2514}
2515#endif /* FEATURE_WLAN_CH_AVOID */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002516
2517/**
2518 * sap_select_channel() - select SAP channel
2519 * @hal: Pointer to HAL handle
2520 * @sap_ctx: Sap context
2521 * @scan_result: Pointer to tScanResultHandle
2522 *
2523 * Runs a algorithm to select the best channel to operate in based on BSS
2524 * rssi and bss count on each channel
2525 *
2526 * Returns: channel number if success, 0 otherwise
2527 */
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -07002528uint8_t sap_select_channel(tHalHandle hal, struct sap_context *sap_ctx,
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002529 tScanResultHandle scan_result)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002530{
2531 /* DFS param object holding all the data req by the algo */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002532 tSapChSelSpectInfo spect_info_obj = { NULL, 0 };
2533 tSapChSelSpectInfo *spect_info = &spect_info_obj;
2534 uint8_t best_ch_num = SAP_CHANNEL_NOT_SELECTED;
bingse2782382017-03-23 10:34:52 +08002535 uint32_t ht40plus2gendch = 0;
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002536 v_REGDOMAIN_t domain;
2537 uint8_t country[CDS_COUNTRY_CODE_LEN];
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002538#ifdef SOFTAP_CHANNEL_RANGE
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002539 uint8_t count;
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002540 uint32_t start_ch_num, end_ch_num, tmp_ch_num, operating_band = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002541#endif
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002542 tpAniSirGlobal mac_ctx;
2543
2544 mac_ctx = PMAC_STRUCT(hal);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302545 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002546 "In %s, Running SAP Ch Select", __func__);
2547
2548#ifdef FEATURE_WLAN_CH_AVOID
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002549 sap_update_unsafe_channel_list(hal, sap_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002550#endif
2551
gaoleze5108942017-03-31 16:56:42 +08002552 /*
2553 * If ACS weight is not enabled on noise_floor/channel_free/tx_power,
2554 * then skip acs process if no bss found.
2555 */
2556 if (NULL == scan_result &&
2557 !(sap_ctx->auto_channel_select_weight & 0xffff00)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302558 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002559 FL("No external AP present"));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002560
2561#ifndef SOFTAP_CHANNEL_RANGE
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002562 return SAP_CHANNEL_NOT_SELECTED;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002563#else
Kondabattini, Ganesh13bb4b12016-09-04 16:16:53 +05302564 return sap_select_channel_no_scan_result(hal, sap_ctx);
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002565#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002566 }
2567
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002568 /* Initialize the structure pointed by spect_info */
Srinivas Girigowda74a66d62017-06-21 23:28:25 -07002569 if (sap_chan_sel_init(hal, spect_info, sap_ctx) != true) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302570 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002571 FL("Ch Select initialization failed"));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002572 return SAP_CHANNEL_NOT_SELECTED;
2573 }
2574 /* Compute the weight of the entire spectrum in the operating band */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002575 sap_compute_spect_weight(spect_info, hal, scan_result, sap_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002576
2577#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
2578 /* process avoid channel IE to collect all channels to avoid */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002579 sap_process_avoid_ie(hal, sap_ctx, scan_result, spect_info);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002580#endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
2581
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002582 wlan_reg_read_default_country(mac_ctx->psoc, country);
2583 wlan_reg_get_domain_from_country_code(&domain, country, SOURCE_DRIVER);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002584#ifdef SOFTAP_CHANNEL_RANGE
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002585 start_ch_num = sap_ctx->acs_cfg->start_ch;
2586 end_ch_num = sap_ctx->acs_cfg->end_ch;
2587 SET_ACS_BAND(operating_band, sap_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002588
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002589 sap_ctx->acsBestChannelInfo.channelNum = 0;
2590 sap_ctx->acsBestChannelInfo.weight = SAP_ACS_WEIGHT_MAX;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002591
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002592 /* Sort the ch lst as per the computed weights, lesser weight first. */
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002593 sap_sort_chl_weight_all(sap_ctx, spect_info, operating_band, domain);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002594
2595 /*Loop till get the best channel in the given range */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002596 for (count = 0; count < spect_info->numSpectChans; count++) {
2597 if ((start_ch_num > spect_info->pSpectCh[count].chNum) ||
2598 (end_ch_num < spect_info->pSpectCh[count].chNum))
2599 continue;
2600
2601 if (best_ch_num == SAP_CHANNEL_NOT_SELECTED) {
2602 best_ch_num = spect_info->pSpectCh[count].chNum;
2603 /* check if best_ch_num is in preferred channel list */
2604 best_ch_num =
2605 sap_select_preferred_channel_from_channel_list(
2606 best_ch_num, sap_ctx, spect_info);
2607 /* if not in preferred ch lst, go to nxt best ch */
2608 if (best_ch_num == SAP_CHANNEL_NOT_SELECTED)
2609 continue;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002610
2611#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002612 /*
2613 * Weight of the channels(device's AP is operating)
2614 * increased to MAX+1 so that they will be choosen only
2615 * when there is no other best channel to choose
2616 */
2617 if (sap_check_in_avoid_ch_list(sap_ctx, best_ch_num)) {
2618 best_ch_num = SAP_CHANNEL_NOT_SELECTED;
2619 continue;
2620 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002621#endif
2622
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002623 sap_ctx->acsBestChannelInfo.channelNum = best_ch_num;
2624 sap_ctx->acsBestChannelInfo.weight =
2625 spect_info->pSpectCh[count].weight_copy;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002626 }
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002627
2628 if (best_ch_num == SAP_CHANNEL_NOT_SELECTED)
2629 continue;
2630
Tushnim Bhattacharyya03103fd2017-06-23 10:48:52 -07002631 if (operating_band != eCSR_DOT11_MODE_11g) {
2632 QDF_TRACE(QDF_MODULE_ID_SAP,
2633 QDF_TRACE_LEVEL_INFO_HIGH,
2634 "operating_band %d", operating_band);
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002635 continue;
Tushnim Bhattacharyya03103fd2017-06-23 10:48:52 -07002636 }
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002637
2638 /* Give preference to Non-overlap channels */
Naveen Rawatbec64d92017-09-13 14:35:21 -07002639 if (false == sap_is_ch_non_overlap(sap_ctx,
Tushnim Bhattacharyya03103fd2017-06-23 10:48:52 -07002640 spect_info->pSpectCh[count].chNum)) {
2641 QDF_TRACE(QDF_MODULE_ID_SAP,
2642 QDF_TRACE_LEVEL_INFO_HIGH,
Naveen Rawatbec64d92017-09-13 14:35:21 -07002643 FL("ch: %d skipped as its overlapping ch"),
2644 spect_info->pSpectCh[count].chNum);
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002645 continue;
Tushnim Bhattacharyya03103fd2017-06-23 10:48:52 -07002646 }
2647
2648 if (wlan_reg_is_dfs_ch(mac_ctx->pdev,
2649 spect_info->pSpectCh[count].chNum) &&
2650 policy_mgr_disallow_mcc(mac_ctx->psoc,
2651 spect_info->pSpectCh[count].chNum)) {
2652 QDF_TRACE(QDF_MODULE_ID_SAP,
2653 QDF_TRACE_LEVEL_INFO_HIGH,
2654 "No DFS MCC");
2655 continue;
2656 }
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002657
bings14d1d3b2017-08-03 11:14:29 +08002658 if (spect_info->pSpectCh[count].weight_copy >
2659 sap_ctx->acsBestChannelInfo.weight)
2660 continue;
2661
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002662 tmp_ch_num = spect_info->pSpectCh[count].chNum;
gaoleze5108942017-03-31 16:56:42 +08002663 tmp_ch_num = sap_channel_in_acs_channel_list(
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002664 tmp_ch_num, sap_ctx, spect_info);
2665 if (tmp_ch_num == SAP_CHANNEL_NOT_SELECTED)
2666 continue;
2667
2668 best_ch_num = tmp_ch_num;
2669 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002670 }
2671#else
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002672 /* Sort the ch lst as per the computed weights, lesser weight first. */
2673 sap_sort_chl_weight_all(sap_ctx, hal, spect_info);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002674 /* Get the first channel in sorted array as best 20M Channel */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002675 best_ch_num = (uint8_t) spect_info->pSpectCh[0].chNum;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002676 /* Select Best Channel from Channel List if Configured */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002677 best_ch_num = sap_select_preferred_channel_from_channel_list(
2678 best_ch_num, sap_ctx, spect_info);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002679#endif
2680
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002681 /*
2682 * in case the best channel seleted is not in PCL and there is another
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002683 * channel which has same weightage and is in PCL, choose the one in
2684 * PCL
2685 */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002686 for (count = 0; count < spect_info->numSpectChans; count++) {
2687 if (!ch_in_pcl(sap_ctx, spect_info->pSpectCh[count].chNum) ||
2688 (spect_info->pSpectCh[count].weight !=
2689 sap_ctx->acsBestChannelInfo.weight))
2690 continue;
2691
2692 if (sap_select_preferred_channel_from_channel_list(
2693 spect_info->pSpectCh[count].chNum, sap_ctx, spect_info)
2694 == SAP_CHANNEL_NOT_SELECTED)
2695 continue;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002696
2697#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002698 if (sap_check_in_avoid_ch_list(sap_ctx, best_ch_num))
2699 continue;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002700#endif
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002701 best_ch_num = spect_info->pSpectCh[count].chNum;
2702 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2703 FL("change best channel to %d in PCL"), best_ch_num);
2704 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002705 }
2706
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002707 sap_ctx->acs_cfg->pri_ch = best_ch_num;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002708 /* determine secondary channel for 2.4G channel 5, 6, 7 in HT40 */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002709 if ((operating_band != eCSR_DOT11_MODE_11g) ||
2710 (sap_ctx->acs_cfg->ch_width != CH_WIDTH_40MHZ))
2711 goto sap_ch_sel_end;
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002712 if (REGDOMAIN_FCC == domain)
bingse2782382017-03-23 10:34:52 +08002713 ht40plus2gendch = HT40PLUS_2G_FCC_CH_END;
2714 else
2715 ht40plus2gendch = HT40PLUS_2G_EURJAP_CH_END;
2716 if ((best_ch_num >= HT40MINUS_2G_CH_START) &&
2717 (best_ch_num <= ht40plus2gendch)) {
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002718 int weight_below, weight_above, i;
2719 tSapSpectChInfo *pspect_info;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002720
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002721 weight_below = weight_above = SAP_ACS_WEIGHT_MAX;
2722 pspect_info = spect_info->pSpectCh;
2723 for (i = 0; i < spect_info->numSpectChans; i++) {
2724 if (pspect_info[i].chNum == (best_ch_num - 4))
2725 weight_below = pspect_info[i].weight;
2726 if (pspect_info[i].chNum == (best_ch_num + 4))
2727 weight_above = pspect_info[i].weight;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002728 }
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002729
2730 if (weight_below < weight_above)
2731 sap_ctx->acs_cfg->ht_sec_ch =
2732 sap_ctx->acs_cfg->pri_ch - 4;
2733 else
2734 sap_ctx->acs_cfg->ht_sec_ch =
2735 sap_ctx->acs_cfg->pri_ch + 4;
2736 } else if (best_ch_num >= 1 && best_ch_num <= 4) {
2737 sap_ctx->acs_cfg->ht_sec_ch = sap_ctx->acs_cfg->pri_ch + 4;
bingse2782382017-03-23 10:34:52 +08002738 } else if (best_ch_num >= ht40plus2gendch && best_ch_num <=
2739 HT40MINUS_2G_CH_END) {
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002740 sap_ctx->acs_cfg->ht_sec_ch = sap_ctx->acs_cfg->pri_ch - 4;
2741 } else if (best_ch_num == 14) {
2742 sap_ctx->acs_cfg->ht_sec_ch = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002743 }
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002744 sap_ctx->secondary_ch = sap_ctx->acs_cfg->ht_sec_ch;
2745
2746sap_ch_sel_end:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002747 /* Free all the allocated memory */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002748 sap_chan_sel_exit(spect_info);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002749
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302750 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002751 FL("Running SAP Ch select Completed, Ch=%d"), best_ch_num);
2752 if (best_ch_num > 0 && best_ch_num <= 252)
2753 return best_ch_num;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002754 else
2755 return SAP_CHANNEL_NOT_SELECTED;
2756}