blob: f5cdd0fd2a366c723d4ffe0c423b2d8e583bd7b0 [file] [log] [blame]
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001/*
Himanshu Agarwalfee2e362018-01-18 20:26:35 +05302 * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003 *
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004 * Permission to use, copy, modify, and/or distribute this software for
5 * any purpose with or without fee is hereby granted, provided that the
6 * above copyright notice and this permission notice appear in all
7 * copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
10 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
11 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
12 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
13 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
14 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
15 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16 * PERFORMANCE OF THIS SOFTWARE.
17 */
18
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019/*===========================================================================
20
Anurag Chouhan6d760662016-02-20 16:05:43 +053021 s a p C h S e l e c t . C
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080022 OVERVIEW:
23
24 This software unit holds the implementation of the WLAN SAP modules
25 functions for channel selection.
26
27 DEPENDENCIES:
28
29 Are listed for each API below.
30 ===========================================================================*/
31
32/*--------------------------------------------------------------------------
33 Include Files
34 ------------------------------------------------------------------------*/
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +053035#include "qdf_trace.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080036#include "csr_api.h"
37#include "sme_api.h"
38#include "sap_ch_select.h"
39#include "sap_internal.h"
40#ifdef ANI_OS_TYPE_QNX
41#include "stdio.h"
42#endif
43#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
44#include "lim_utils.h"
45#include "parser_api.h"
46#endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
Deepthi Gowri48b89332016-08-30 18:43:05 +053047#include "cds_utils.h"
Yuanyuan Liu0e0aa932016-05-12 10:17:58 -070048#include "pld_common.h"
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -070049#include "wlan_reg_services_api.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080050
51/*--------------------------------------------------------------------------
52 Function definitions
53 --------------------------------------------------------------------------*/
54
55/*--------------------------------------------------------------------------
56 Defines
57 --------------------------------------------------------------------------*/
58#define SAP_DEBUG
59
60#define IS_RSSI_VALID(extRssi, rssi) \
61 ( \
62 ((extRssi < rssi) ? true : false) \
63 )
64
Jeff Johnsone13d8062017-09-28 06:54:55 -070065#define SET_ACS_BAND(acs_band, sap_ctx) \
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080066{ \
Jeff Johnsone13d8062017-09-28 06:54:55 -070067 if (sap_ctx->acs_cfg->start_ch <= 14 && \
68 sap_ctx->acs_cfg->end_ch <= 14) \
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080069 acs_band = eCSR_DOT11_MODE_11g; \
Jeff Johnsone13d8062017-09-28 06:54:55 -070070 else if (sap_ctx->acs_cfg->start_ch >= 14)\
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080071 acs_band = eCSR_DOT11_MODE_11a; \
72 else \
73 acs_band = eCSR_DOT11_MODE_abg; \
74}
75
gaoleze5108942017-03-31 16:56:42 +080076#define ACS_WEIGHT_AMOUNT_LOCAL 240
77
78#define ACS_WEIGHT_AMOUNT_CONFIG(weights) \
79 (((weights) & 0xf) + \
80 (((weights) & 0xf0) >> 4) + \
81 (((weights) & 0xf00) >> 8) + \
82 (((weights) & 0xf000) >> 12) + \
83 (((weights) & 0xf0000) >> 16) + \
84 (((weights) & 0xf00000) >> 20))
85
86/*
87 * LSH/RSH 4 to enhance the accurate since
88 * need to do modulation to ACS_WEIGHT_AMOUNT_LOCAL.
89 */
90#define ACS_WEIGHT_COMPUTE(weights, weight, factor, base) \
91 (((((((((weight) << 4) * ACS_WEIGHT_AMOUNT_LOCAL * (factor)) + \
92 (ACS_WEIGHT_AMOUNT_CONFIG((weights)) >> 1)) / \
93 ACS_WEIGHT_AMOUNT_CONFIG((weights))) + \
94 ((base) >> 1)) / (base)) + 8) >> 4)
95
96#define ACS_WEIGHT_CFG_TO_LOCAL(weights, weight) \
97 (((((((weight) << 4) * ACS_WEIGHT_AMOUNT_LOCAL) + \
98 (ACS_WEIGHT_AMOUNT_CONFIG((weights)) >> 1)) / \
99 ACS_WEIGHT_AMOUNT_CONFIG((weights))) + 8) >> 4)
100
101#define ACS_WEIGHT_SOFTAP_RSSI_CFG(weights) \
102 ((weights) & 0xf)
103
104#define ACS_WEIGHT_SOFTAP_COUNT_CFG(weights) \
105 (((weights) & 0xf0) >> 4)
106
107#define ACS_WEIGHT_SOFTAP_NOISE_FLOOR_CFG(weights) \
108 (((weights) & 0xf00) >> 8)
109
110#define ACS_WEIGHT_SOFTAP_CHANNEL_FREE_CFG(weights) \
111 (((weights) & 0xf000) >> 12)
112
113#define ACS_WEIGHT_SOFTAP_TX_POWER_RANGE_CFG(weights) \
114 (((weights) & 0xf0000) >> 16)
115
116#define ACS_WEIGHT_SOFTAP_TX_POWER_THROUGHPUT_CFG(weights) \
117 (((weights) & 0xf00000) >> 20)
118
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800119#ifdef FEATURE_WLAN_CH_AVOID
Amar Singhalb8d4f152016-02-10 10:21:43 -0800120sapSafeChannelType safe_channels[NUM_CHANNELS] = {
121 {1, true},
122 {2, true},
123 {3, true},
124 {4, true},
125 {5, true},
126 {6, true},
127 {7, true},
128 {8, true},
129 {9, true},
130 {10, true},
131 {11, true},
132 {12, true},
133 {13, true},
134 {14, true},
135 {36, true},
136 {40, true},
137 {44, true},
138 {48, true},
139 {52, true},
140 {56, true},
141 {60, true},
142 {64, true},
143 {100, true},
144 {104, true},
145 {108, true},
146 {112, true},
147 {116, true},
148 {120, true},
149 {124, true},
150 {128, true},
151 {132, true},
152 {136, true},
153 {140, true},
154 {144, true},
155 {149, true},
156 {153, true},
157 {157, true},
158 {161, true},
159 {165, true},
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800160};
161#endif
162
163typedef struct {
164 uint16_t chStartNum;
165 uint32_t weight;
166} sapAcsChannelInfo;
167
168sapAcsChannelInfo acs_ht40_channels5_g[] = {
169 {36, SAP_ACS_WEIGHT_MAX},
170 {44, SAP_ACS_WEIGHT_MAX},
171 {52, SAP_ACS_WEIGHT_MAX},
172 {60, SAP_ACS_WEIGHT_MAX},
173 {100, SAP_ACS_WEIGHT_MAX},
174 {108, SAP_ACS_WEIGHT_MAX},
175 {116, SAP_ACS_WEIGHT_MAX},
176 {124, SAP_ACS_WEIGHT_MAX},
177 {132, SAP_ACS_WEIGHT_MAX},
178 {140, SAP_ACS_WEIGHT_MAX},
179 {149, SAP_ACS_WEIGHT_MAX},
180 {157, SAP_ACS_WEIGHT_MAX},
181};
182
183sapAcsChannelInfo acs_ht80_channels[] = {
184 {36, SAP_ACS_WEIGHT_MAX},
185 {52, SAP_ACS_WEIGHT_MAX},
186 {100, SAP_ACS_WEIGHT_MAX},
187 {116, SAP_ACS_WEIGHT_MAX},
188 {132, SAP_ACS_WEIGHT_MAX},
189 {149, SAP_ACS_WEIGHT_MAX},
190};
191
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -0700192sapAcsChannelInfo acs_vht160_channels[] = {
193 {36, SAP_ACS_WEIGHT_MAX},
194 {100, SAP_ACS_WEIGHT_MAX},
195};
196
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800197sapAcsChannelInfo acs_ht40_channels24_g[] = {
198 {1, SAP_ACS_WEIGHT_MAX},
199 {2, SAP_ACS_WEIGHT_MAX},
200 {3, SAP_ACS_WEIGHT_MAX},
201 {4, SAP_ACS_WEIGHT_MAX},
202 {9, SAP_ACS_WEIGHT_MAX},
203};
204
205#define CHANNEL_165 165
206
207/* rssi discount for channels in PCL */
208#define PCL_RSSI_DISCOUNT 10
209
210#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
211/**
212 * sap_check_n_add_channel() - checks and add given channel in sap context's
213 * avoid_channels_info struct
214 * @sap_ctx: sap context.
215 * @new_channel: channel to be added to sap_ctx's avoid ch info
216 *
217 * sap_ctx contains sap_avoid_ch_info strcut containing the list of channels on
218 * which MDM device's AP with MCC was detected. This function will add channels
219 * to that list after checking for duplicates.
220 *
221 * Return: true: if channel was added or already present
222 * else false: if channel list was already full.
223 */
Tang Yingying523322d2017-01-17 23:28:43 +0800224static bool
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -0700225sap_check_n_add_channel(struct sap_context *sap_ctx,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800226 uint8_t new_channel)
227{
228 uint8_t i = 0;
229 struct sap_avoid_channels_info *ie_info =
230 &sap_ctx->sap_detected_avoid_ch_ie;
231
232 for (i = 0; i < sizeof(ie_info->channels); i++) {
233 if (ie_info->channels[i] == new_channel)
234 break;
235
236 if (ie_info->channels[i] == 0) {
237 ie_info->channels[i] = new_channel;
238 break;
239 }
240 }
241 if (i == sizeof(ie_info->channels))
242 return false;
243 else
244 return true;
245}
246/**
247 * sap_check_n_add_overlapped_chnls() - checks & add overlapped channels
248 * to primary channel in 2.4Ghz band.
249 * @sap_ctx: sap context.
250 * @primary_chnl: primary channel to be avoided.
251 *
252 * sap_ctx contains sap_avoid_ch_info struct containing the list of channels on
253 * which MDM device's AP with MCC was detected. This function will add channels
254 * to that list after checking for duplicates.
255 *
256 * Return: true: if channel was added or already present
257 * else false: if channel list was already full.
258 */
259static bool
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -0700260sap_check_n_add_overlapped_chnls(struct sap_context *sap_ctx,
261 uint8_t primary_channel)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800262{
263 uint8_t i = 0, j = 0, upper_chnl = 0, lower_chnl = 0;
264 struct sap_avoid_channels_info *ie_info =
265 &sap_ctx->sap_detected_avoid_ch_ie;
266 /*
267 * if primary channel less than channel 1 or out of 2g band then
268 * no further process is required. return true in this case.
269 */
270 if (primary_channel < CHANNEL_1 || primary_channel > CHANNEL_14)
271 return true;
272
273 /* lower channel is one channel right before primary channel */
274 lower_chnl = primary_channel - 1;
275 /* upper channel is one channel right after primary channel */
276 upper_chnl = primary_channel + 1;
277
278 /* lower channel needs to be non-zero, zero is not valid channel */
279 if (lower_chnl > (CHANNEL_1 - 1)) {
280 for (i = 0; i < sizeof(ie_info->channels); i++) {
281 if (ie_info->channels[i] == lower_chnl)
282 break;
283 if (ie_info->channels[i] == 0) {
284 ie_info->channels[i] = lower_chnl;
285 break;
286 }
287 }
288 }
289 /* upper channel needs to be atleast last channel in 2.4Ghz band */
290 if (upper_chnl < (CHANNEL_14 + 1)) {
291 for (j = 0; j < sizeof(ie_info->channels); j++) {
292 if (ie_info->channels[j] == upper_chnl)
293 break;
294 if (ie_info->channels[j] == 0) {
295 ie_info->channels[j] = upper_chnl;
296 break;
297 }
298 }
299 }
300 if (i == sizeof(ie_info->channels) || j == sizeof(ie_info->channels))
301 return false;
302 else
303 return true;
304}
305
306/**
307 * sap_process_avoid_ie() - processes the detected Q2Q IE
308 * context's avoid_channels_info struct
309 * @hal: hal handle
310 * @sap_ctx: sap context.
311 * @scan_result: scan results for ACS scan.
312 * @spect_info: spectrum weights array to update
313 *
314 * Detection of Q2Q IE indicates presence of another MDM device with its AP
315 * operating in MCC mode. This function parses the scan results and processes
316 * the Q2Q IE if found. It then extracts the channels and populates them in
317 * sap_ctx struct. It also increases the weights of those channels so that
318 * ACS logic will avoid those channels in its selection algorithm.
319 *
320 * Return: void
321 */
Tang Yingying523322d2017-01-17 23:28:43 +0800322static void sap_process_avoid_ie(tHalHandle hal,
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -0700323 struct sap_context *sap_ctx,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800324 tScanResultHandle scan_result,
325 tSapChSelSpectInfo *spect_info)
326{
327 uint32_t total_ie_len = 0;
328 uint8_t *temp_ptr = NULL;
329 uint8_t i = 0;
330 struct sAvoidChannelIE *avoid_ch_ie;
331 tCsrScanResultInfo *node = NULL;
332 tpAniSirGlobal mac_ctx = NULL;
333 tSapSpectChInfo *spect_ch = NULL;
334
335 mac_ctx = PMAC_STRUCT(hal);
336 spect_ch = spect_info->pSpectCh;
337 node = sme_scan_result_get_first(hal, scan_result);
338
339 while (node) {
Abhishek Singh34a4d862016-10-26 16:01:51 +0530340 total_ie_len =
Jeff Johnson38e38a82017-10-06 10:32:31 -0700341 GET_IE_LEN_IN_BSS(node->BssDescriptor.length);
Naveen Rawat08db88f2017-09-08 15:07:48 -0700342 temp_ptr = wlan_get_vendor_ie_ptr_from_oui(
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800343 SIR_MAC_QCOM_VENDOR_OUI,
344 SIR_MAC_QCOM_VENDOR_SIZE,
345 ((uint8_t *)&node->BssDescriptor.ieFields),
346 total_ie_len);
347
348 if (temp_ptr) {
349 avoid_ch_ie = (struct sAvoidChannelIE *)temp_ptr;
Will Huang55ba1042017-03-22 10:43:30 +0800350 if (avoid_ch_ie->type !=
351 QCOM_VENDOR_IE_MCC_AVOID_CH) {
352 node = sme_scan_result_get_next(hal,
353 scan_result);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800354 continue;
Will Huang55ba1042017-03-22 10:43:30 +0800355 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800356
357 sap_ctx->sap_detected_avoid_ch_ie.present = 1;
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530358 QDF_TRACE(QDF_MODULE_ID_SAP,
359 QDF_TRACE_LEVEL_DEBUG,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800360 "Q2Q IE - avoid ch %d",
361 avoid_ch_ie->channel);
362 /* add this channel to to_avoid channel list */
363 sap_check_n_add_channel(sap_ctx,
364 avoid_ch_ie->channel);
365 sap_check_n_add_overlapped_chnls(sap_ctx,
366 avoid_ch_ie->channel);
367 /*
368 * Mark weight of these channel present in IE to MAX
369 * so that ACS logic will to avoid thse channels
370 */
371 for (i = 0; i < spect_info->numSpectChans; i++)
372 if (spect_ch[i].chNum == avoid_ch_ie->channel) {
373 /*
374 * weight is set more than max so that,
375 * in the case of other channels being
376 * assigned max weight due to noise,
377 * they may be preferred over channels
378 * with Q2Q IE.
379 */
380 spect_ch[i].weight = SAP_ACS_WEIGHT_MAX + 1;
381 spect_ch[i].weight_copy =
382 SAP_ACS_WEIGHT_MAX + 1;
383 break;
384 }
385 } /* if (temp_ptr) */
386 node = sme_scan_result_get_next(hal, scan_result);
387 }
388}
389#endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
390
391#ifdef FEATURE_WLAN_CH_AVOID
392/*==========================================================================
393 FUNCTION sap_update_unsafe_channel_list
394
395 DESCRIPTION
396 Function Undate unsafe channel list table
397
398 DEPENDENCIES
399 NA.
400
401 IN
402 SapContext pointer
403
404 RETURN VALUE
405 NULL
406 ============================================================================*/
Jeff Johnsone13d8062017-09-28 06:54:55 -0700407void sap_update_unsafe_channel_list(tHalHandle hal, struct sap_context *sap_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800408{
409 uint16_t i, j;
Amar Singhalb8d4f152016-02-10 10:21:43 -0800410 uint16_t unsafe_channel_list[NUM_CHANNELS];
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800411 uint16_t unsafe_channel_count = 0;
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -0700412 tpAniSirGlobal mac_ctx = NULL;
413
Yuanyuan Liu0e0aa932016-05-12 10:17:58 -0700414 qdf_device_t qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800415
Yuanyuan Liu97361182016-06-06 09:38:04 -0700416 if (!qdf_ctx) {
417 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_FATAL,
418 "qdf_ctx is NULL");
419 return;
420 }
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -0700421 mac_ctx = PMAC_STRUCT(hal);
422 if (!mac_ctx) {
423 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_FATAL,
424 "mac_ctx is NULL");
425 return;
426 }
Yuanyuan Liu97361182016-06-06 09:38:04 -0700427
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800428 /* Flush, default set all channel safe */
Amar Singhalb8d4f152016-02-10 10:21:43 -0800429 for (i = 0; i < NUM_CHANNELS; i++) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800430 safe_channels[i].isSafe = true;
431 }
432
433 /* Try to find unsafe channel */
Ryan Hsu4252a2f2016-01-05 11:18:24 -0800434#if defined(FEATURE_WLAN_STA_AP_MODE_DFS_DISABLE)
Amar Singhalb8d4f152016-02-10 10:21:43 -0800435 for (i = 0; i < NUM_CHANNELS; i++) {
Jeff Johnsone13d8062017-09-28 06:54:55 -0700436 if (sap_ctx->dfs_ch_disable == true) {
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -0700437 if (wlan_reg_is_dfs_ch(mac_ctx->pdev,
438 safe_channels[i].channelNumber)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800439 safe_channels[i].isSafe = false;
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530440 QDF_TRACE(QDF_MODULE_ID_SAP,
441 QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800442 "%s: DFS Ch %d is not safe in"
443 " Concurrent mode",
444 __func__,
445 safe_channels[i].channelNumber);
446 }
447 }
448 }
449#endif
Yuanyuan Liu0e0aa932016-05-12 10:17:58 -0700450 pld_get_wlan_unsafe_channel(qdf_ctx->dev,
451 unsafe_channel_list,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800452 &unsafe_channel_count,
453 sizeof(unsafe_channel_list));
454
455 for (i = 0; i < unsafe_channel_count; i++) {
Amar Singhalb8d4f152016-02-10 10:21:43 -0800456 for (j = 0; j < NUM_CHANNELS; j++) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800457 if (safe_channels[j].channelNumber ==
458 unsafe_channel_list[i]) {
459 /* Found unsafe channel, update it */
460 safe_channels[j].isSafe = false;
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530461 QDF_TRACE(QDF_MODULE_ID_SAP,
462 QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800463 FL("CH %d is not safe"),
464 unsafe_channel_list[i]);
465 break;
466 }
467 }
468 }
469
470 return;
471}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800472
473#endif /* FEATURE_WLAN_CH_AVOID */
474
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800475/**
gaoleze5108942017-03-31 16:56:42 +0800476 * sap_channel_in_acs_channel_list() - check if channel in acs channel list
477 * @channel_num: channel to check
478 * @sap_ctx: struct ptSapContext
479 * @spect_info_params: strcut tSapChSelSpectInfo
480 *
481 * This function checks if specified channel is in the configured ACS channel
482 * list.
483 *
484 * Return: channel number if in acs channel list or SAP_CHANNEL_NOT_SELECTED
485 */
gaoleze5108942017-03-31 16:56:42 +0800486uint8_t sap_channel_in_acs_channel_list(uint8_t channel_num,
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -0700487 struct sap_context *sap_ctx,
gaoleze5108942017-03-31 16:56:42 +0800488 tSapChSelSpectInfo *spect_info_params)
489{
490 uint8_t i = 0;
491
492 if ((NULL == sap_ctx->acs_cfg->ch_list) ||
493 (NULL == spect_info_params))
494 return channel_num;
495
496 if (channel_num > 0 && channel_num <= 252) {
497 for (i = 0; i < sap_ctx->acs_cfg->ch_list_count; i++) {
498 if ((sap_ctx->acs_cfg->ch_list[i]) == channel_num)
499 return channel_num;
500 }
501 return SAP_CHANNEL_NOT_SELECTED;
502 } else {
503 return SAP_CHANNEL_NOT_SELECTED;
504 }
505}
506
507/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800508 * sap_select_preferred_channel_from_channel_list() - to calc best cahnnel
509 * @best_chnl: best channel already calculated among all the chanels
510 * @sap_ctx: sap context
511 * @spectinfo_param: Pointer to tSapChSelSpectInfo structure
512 *
513 * This function calculates the best channel among the configured channel list.
514 * If channel list not configured then returns the best channel calculated
515 * among all the channel list.
516 *
517 * Return: uint8_t best channel
518 */
Jeff Johnson464f7ea2016-10-07 10:21:26 -0700519static
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800520uint8_t sap_select_preferred_channel_from_channel_list(uint8_t best_chnl,
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -0700521 struct sap_context *sap_ctx,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800522 tSapChSelSpectInfo *spectinfo_param)
523{
524 uint8_t i = 0;
Tushnim Bhattacharyya518e80f2017-08-30 17:35:33 -0700525 tpAniSirGlobal mac_ctx = sme_get_mac_context();
526
527 if (NULL == mac_ctx) {
528 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
529 "pmac Global Context is NULL");
530 return SAP_CHANNEL_NOT_SELECTED;
531 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800532
533 /*
534 * If Channel List is not Configured don't do anything
535 * Else return the Best Channel from the Channel List
536 */
537 if ((NULL == sap_ctx->acs_cfg->ch_list) ||
538 (NULL == spectinfo_param) ||
539 (0 == sap_ctx->acs_cfg->ch_list_count))
540 return best_chnl;
541
542 if (best_chnl <= 0 || best_chnl > 252)
543 return SAP_CHANNEL_NOT_SELECTED;
544
545 /* Select the best channel from allowed list */
546 for (i = 0; i < sap_ctx->acs_cfg->ch_list_count; i++) {
Tushnim Bhattacharyya518e80f2017-08-30 17:35:33 -0700547 if ((sap_ctx->acs_cfg->ch_list[i] == best_chnl) &&
548 !(wlan_reg_is_dfs_ch(mac_ctx->pdev, best_chnl) &&
549 policy_mgr_disallow_mcc(mac_ctx->psoc, best_chnl))) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530550 QDF_TRACE(QDF_MODULE_ID_SAP,
Ravi Joshi9788fcd2018-02-13 15:12:22 -0800551 QDF_TRACE_LEVEL_INFO,
Naveen Rawatbec64d92017-09-13 14:35:21 -0700552 "Best channel so far is: %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800553 best_chnl);
554 return best_chnl;
555 }
556 }
557
558 return SAP_CHANNEL_NOT_SELECTED;
559}
560
561/*==========================================================================
562 FUNCTION sap_chan_sel_init
563
564 DESCRIPTION
Jeff Johnsonc7e4d162018-05-12 16:20:34 -0700565 Function sap_chan_sel_init allocates the memory, initializes the
Anurag Chouhan6d760662016-02-20 16:05:43 +0530566 structures used by the channel selection algorithm
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800567
568 DEPENDENCIES
569 NA.
570
571 PARAMETERS
572
573 IN
574 halHandle : Pointer to tHalHandle
575 *pSpectInfoParams : Pointer to tSapChSelSpectInfo structure
Jeff Johnsone13d8062017-09-28 06:54:55 -0700576 sap_ctx : Pointer to SAP Context
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800577
578 RETURN VALUE
579 bool: Success or FAIL
580
581 SIDE EFFECTS
582 ============================================================================*/
Jeff Johnson464f7ea2016-10-07 10:21:26 -0700583static bool sap_chan_sel_init(tHalHandle halHandle,
584 tSapChSelSpectInfo *pSpectInfoParams,
Jeff Johnsone13d8062017-09-28 06:54:55 -0700585 struct sap_context *sap_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800586{
587 tSapSpectChInfo *pSpectCh = NULL;
588 uint8_t *pChans = NULL;
589 uint16_t channelnum = 0;
590 tpAniSirGlobal pMac = PMAC_STRUCT(halHandle);
591 bool chSafe = true;
592#ifdef FEATURE_WLAN_CH_AVOID
593 uint16_t i;
594#endif
595 uint32_t dfs_master_cap_enabled;
596 bool include_dfs_ch = true;
Himanshu Agarwalfee2e362018-01-18 20:26:35 +0530597 uint8_t chan_num;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800598
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530599 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, "In %s",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800600 __func__);
601
602 pSpectInfoParams->numSpectChans =
603 pMac->scan.base_channels.numChannels;
604
605 /* Allocate memory for weight computation of 2.4GHz */
606 pSpectCh =
Himanshu Agarwal052ce252018-06-18 17:18:59 +0530607 (tSapSpectChInfo *)qdf_mem_malloc(
608 (pSpectInfoParams->numSpectChans) *
609 sizeof(*pSpectCh));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800610
611 if (pSpectCh == NULL) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530612 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
Anurag Chouhanf04e84f2016-03-03 10:12:12 +0530613 "In %s, QDF_MALLOC_ERR", __func__);
Srinivas Girigowda74a66d62017-06-21 23:28:25 -0700614 return false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800615 }
616
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800617 /* Initialize the pointers in the DfsParams to the allocated memory */
618 pSpectInfoParams->pSpectCh = pSpectCh;
619
620 pChans = pMac->scan.base_channels.channelList;
621
Ryan Hsu4252a2f2016-01-05 11:18:24 -0800622#if defined(FEATURE_WLAN_STA_AP_MODE_DFS_DISABLE)
Jeff Johnsone13d8062017-09-28 06:54:55 -0700623 if (sap_ctx->dfs_ch_disable == true)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800624 include_dfs_ch = false;
625#endif
626 sme_cfg_get_int(halHandle, WNI_CFG_DFS_MASTER_ENABLED,
627 &dfs_master_cap_enabled);
Agrawal Ashish65634612016-08-18 13:24:32 +0530628 if (dfs_master_cap_enabled == 0 ||
Jeff Johnsone13d8062017-09-28 06:54:55 -0700629 ACS_DFS_MODE_DISABLE == sap_ctx->dfs_mode)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800630 include_dfs_ch = false;
631
632 /* Fill the channel number in the spectrum in the operating freq band */
633 for (channelnum = 0;
634 channelnum < pSpectInfoParams->numSpectChans;
Edhar, Mahesh Kumar4f660672015-10-30 11:53:26 +0530635 channelnum++, pChans++, pSpectCh++) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800636 chSafe = true;
637
Himanshu Agarwal052ce252018-06-18 17:18:59 +0530638 pSpectCh->chNum = *pChans;
639 /* Initialise for all channels */
640 pSpectCh->rssiAgr = SOFTAP_MIN_RSSI;
641 /* Initialise 20MHz for all the Channels */
642 pSpectCh->channelWidth = SOFTAP_HT20_CHANNELWIDTH;
643 /* Initialise max ACS weight for all channels */
644 pSpectCh->weight = SAP_ACS_WEIGHT_MAX;
645
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800646 /* check if the channel is in NOL blacklist */
Himanshu Agarwal052ce252018-06-18 17:18:59 +0530647 if (sap_dfs_is_channel_in_nol_list(
648 sap_ctx, *pChans,
649 PHY_SINGLE_CHANNEL_CENTERED)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530650 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800651 "In %s, Ch %d is in NOL list", __func__,
652 *pChans);
653 chSafe = false;
654 continue;
655 }
656
657 if (include_dfs_ch == false) {
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -0700658 if (wlan_reg_is_dfs_ch(pMac->pdev, *pChans)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800659 chSafe = false;
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530660 QDF_TRACE(QDF_MODULE_ID_SAP,
661 QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800662 "In %s, DFS Ch %d not considered for ACS",
663 __func__, *pChans);
664 continue;
665 }
666 }
667
668#ifdef FEATURE_WLAN_CH_AVOID
Amar Singhalb8d4f152016-02-10 10:21:43 -0800669 for (i = 0; i < NUM_CHANNELS; i++) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800670 if ((safe_channels[i].channelNumber == *pChans) &&
671 (false == safe_channels[i].isSafe)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530672 QDF_TRACE(QDF_MODULE_ID_SAP,
673 QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800674 "In %s, Ch %d is not safe", __func__,
675 *pChans);
676 chSafe = false;
677 break;
678 }
679 }
680#endif /* FEATURE_WLAN_CH_AVOID */
681
682 /* OFDM rates are not supported on channel 14 */
683 if (*pChans == 14 &&
Jeff Johnsone13d8062017-09-28 06:54:55 -0700684 eCSR_DOT11_MODE_11b != sap_ctx->csr_roamProfile.phyMode) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800685 continue;
686 }
687
Deepthi Gowri48b89332016-08-30 18:43:05 +0530688 /* Skip DSRC channels */
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -0700689 if (WLAN_REG_IS_11P_CH(*pChans))
Deepthi Gowri48b89332016-08-30 18:43:05 +0530690 continue;
691
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800692 if (true == chSafe) {
Srinivas Girigowda74a66d62017-06-21 23:28:25 -0700693 pSpectCh->valid = true;
Himanshu Agarwalfee2e362018-01-18 20:26:35 +0530694 for (chan_num = 0; chan_num < sap_ctx->num_of_channel;
695 chan_num++) {
696 if (pSpectCh->chNum !=
697 sap_ctx->channelList[chan_num])
698 continue;
699
700 /*
701 * Initialize ACS weight to 0 for channels
702 * present in sap context scan channel list
703 */
704 pSpectCh->weight = 0;
705 break;
706 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800707 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800708 }
Srinivas Girigowda74a66d62017-06-21 23:28:25 -0700709 return true;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800710}
711
gaoleze5108942017-03-31 16:56:42 +0800712/**
713 * sapweight_rssi_count() - calculates the channel weight due to rssi
Anurag Chouhan6d760662016-02-20 16:05:43 +0530714 and data count(here number of BSS observed)
gaoleze5108942017-03-31 16:56:42 +0800715 * @sap_ctx : Softap context
716 * @rssi : Max signal strength receieved from a BSS for the channel
717 * @count : Number of BSS observed in the channel
718 *
719 * Return: uint32_t Calculated channel weight based on above two
720 */
721static
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -0700722uint32_t sapweight_rssi_count(struct sap_context *sap_ctx, int8_t rssi,
gaoleze5108942017-03-31 16:56:42 +0800723 uint16_t count)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800724{
725 int32_t rssiWeight = 0;
726 int32_t countWeight = 0;
727 uint32_t rssicountWeight = 0;
gaoleze5108942017-03-31 16:56:42 +0800728 uint8_t softap_rssi_weight_cfg, softap_count_weight_cfg;
729 uint8_t softap_rssi_weight_local, softap_count_weight_local;
730
731 softap_rssi_weight_cfg =
732 ACS_WEIGHT_SOFTAP_RSSI_CFG(sap_ctx->auto_channel_select_weight);
733
734 softap_count_weight_cfg =
735 ACS_WEIGHT_SOFTAP_COUNT_CFG(sap_ctx->auto_channel_select_weight);
736
737 softap_rssi_weight_local =
738 ACS_WEIGHT_CFG_TO_LOCAL(sap_ctx->auto_channel_select_weight,
739 softap_rssi_weight_cfg);
740
741 softap_count_weight_local =
742 ACS_WEIGHT_CFG_TO_LOCAL(sap_ctx->auto_channel_select_weight,
743 softap_count_weight_cfg);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800744
745 /* Weight from RSSI */
gaoleze5108942017-03-31 16:56:42 +0800746 rssiWeight = ACS_WEIGHT_COMPUTE(sap_ctx->auto_channel_select_weight,
747 softap_rssi_weight_cfg,
748 rssi - SOFTAP_MIN_RSSI,
749 SOFTAP_MAX_RSSI - SOFTAP_MIN_RSSI);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800750
gaoleze5108942017-03-31 16:56:42 +0800751 if (rssiWeight > softap_rssi_weight_local)
752 rssiWeight = softap_rssi_weight_local;
753
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800754 else if (rssiWeight < 0)
755 rssiWeight = 0;
756
757 /* Weight from data count */
gaoleze5108942017-03-31 16:56:42 +0800758 countWeight = ACS_WEIGHT_COMPUTE(sap_ctx->auto_channel_select_weight,
759 softap_count_weight_cfg,
760 count - SOFTAP_MIN_COUNT,
761 SOFTAP_MAX_COUNT - SOFTAP_MIN_COUNT);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800762
gaoleze5108942017-03-31 16:56:42 +0800763 if (countWeight > softap_count_weight_local)
764 countWeight = softap_count_weight_local;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800765
766 rssicountWeight = rssiWeight + countWeight;
767
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530768 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800769 "In %s, rssiWeight=%d, countWeight=%d, rssicountWeight=%d",
770 __func__, rssiWeight, countWeight, rssicountWeight);
771
772 return rssicountWeight;
773}
774
775/**
gaoleze5108942017-03-31 16:56:42 +0800776 * sap_get_channel_status() - get channel info via channel number
777 * @p_mac: Pointer to Global MAC structure
778 * @channel_id: channel id
779 *
780 * Return: chan status info
781 */
782static struct lim_channel_status *sap_get_channel_status
783 (tpAniSirGlobal p_mac, uint32_t channel_id)
784{
785 return csr_get_channel_status(p_mac, channel_id);
786}
787
788/**
789 * sap_clear_channel_status() - clear chan info
790 * @p_mac: Pointer to Global MAC structure
791 *
792 * Return: none
793 */
794static void sap_clear_channel_status(tpAniSirGlobal p_mac)
795{
796 csr_clear_channel_status(p_mac);
797}
798
799/**
800 * sap_weight_channel_noise_floor() - compute noise floor weight
801 * @sap_ctx: sap context
802 * @chn_stat: Pointer to chan status info
803 *
804 * Return: channel noise floor weight
805 */
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -0700806static uint32_t sap_weight_channel_noise_floor(struct sap_context *sap_ctx,
gaoleze5108942017-03-31 16:56:42 +0800807 struct lim_channel_status
808 *channel_stat)
809{
810 uint32_t noise_floor_weight;
811 uint8_t softap_nf_weight_cfg;
812 uint8_t softap_nf_weight_local;
813
814 softap_nf_weight_cfg =
815 ACS_WEIGHT_SOFTAP_NOISE_FLOOR_CFG
816 (sap_ctx->auto_channel_select_weight);
817
818 softap_nf_weight_local =
819 ACS_WEIGHT_CFG_TO_LOCAL(sap_ctx->auto_channel_select_weight,
820 softap_nf_weight_cfg);
821
822 if (channel_stat == NULL || channel_stat->channelfreq == 0) {
Srinivas Girigowda80213e52018-01-23 14:51:33 -0800823 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG,
gaoleze5108942017-03-31 16:56:42 +0800824 "In %s, sanity check failed return max weight",
825 __func__);
826 return softap_nf_weight_local;
827 }
828
829 noise_floor_weight = (channel_stat->noise_floor == 0) ? 0 :
830 (ACS_WEIGHT_COMPUTE(
831 sap_ctx->auto_channel_select_weight,
832 softap_nf_weight_cfg,
833 channel_stat->noise_floor -
834 SOFTAP_MIN_NF,
835 SOFTAP_MAX_NF - SOFTAP_MIN_NF));
836
837 if (noise_floor_weight > softap_nf_weight_local)
838 noise_floor_weight = softap_nf_weight_local;
839 else if (noise_floor_weight < 0)
840 noise_floor_weight = 0;
841
842 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
843 "In %s, nf=%d, nfwc=%d, nfwl=%d, nfw=%d",
844 __func__, channel_stat->noise_floor,
845 softap_nf_weight_cfg, softap_nf_weight_local,
846 noise_floor_weight);
847
848 return noise_floor_weight;
849}
850
851/**
852 * sap_weight_channel_free() - compute channel free weight
853 * @sap_ctx: sap context
854 * @chn_stat: Pointer to chan status info
855 *
856 * Return: channel free weight
857 */
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -0700858static uint32_t sap_weight_channel_free(struct sap_context *sap_ctx,
gaoleze5108942017-03-31 16:56:42 +0800859 struct lim_channel_status
860 *channel_stat)
861{
862 uint32_t channel_free_weight;
863 uint8_t softap_channel_free_weight_cfg;
864 uint8_t softap_channel_free_weight_local;
865 uint32_t rx_clear_count = 0;
866 uint32_t cycle_count = 0;
867
868 softap_channel_free_weight_cfg =
869 ACS_WEIGHT_SOFTAP_CHANNEL_FREE_CFG
870 (sap_ctx->auto_channel_select_weight);
871
872 softap_channel_free_weight_local =
873 ACS_WEIGHT_CFG_TO_LOCAL(sap_ctx->auto_channel_select_weight,
874 softap_channel_free_weight_cfg);
875
876 if (channel_stat == NULL || channel_stat->channelfreq == 0) {
Srinivas Girigowda80213e52018-01-23 14:51:33 -0800877 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG,
gaoleze5108942017-03-31 16:56:42 +0800878 "In %s, sanity check failed return max weight",
879 __func__);
880 return softap_channel_free_weight_local;
881 }
882
883 rx_clear_count = channel_stat->rx_clear_count -
884 channel_stat->tx_frame_count -
885 channel_stat->rx_frame_count;
886 cycle_count = channel_stat->cycle_count;
887
888 /* LSH 4, otherwise it is always 0. */
889 channel_free_weight = (cycle_count == 0) ? 0 :
890 (ACS_WEIGHT_COMPUTE(
891 sap_ctx->auto_channel_select_weight,
892 softap_channel_free_weight_cfg,
893 ((rx_clear_count << 8) +
894 (cycle_count >> 1))/cycle_count -
895 (SOFTAP_MIN_CHNFREE << 8),
896 (SOFTAP_MAX_CHNFREE -
897 SOFTAP_MIN_CHNFREE) << 8));
898
899 if (channel_free_weight > softap_channel_free_weight_local)
900 channel_free_weight = softap_channel_free_weight_local;
901
902 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
903 "In %s, rcc=%d, cc=%d, tc=%d, rc=%d, cfwc=%d, cfwl=%d, cfw=%d",
904 __func__, rx_clear_count, cycle_count,
905 channel_stat->tx_frame_count,
906 channel_stat->rx_frame_count,
907 softap_channel_free_weight_cfg,
908 softap_channel_free_weight_local,
909 channel_free_weight);
910
911 return channel_free_weight;
912}
913
914/**
915 * sap_weight_channel_txpwr_range() - compute channel tx power range weight
916 * @sap_ctx: sap context
917 * @chn_stat: Pointer to chan status info
918 *
919 * Return: tx power range weight
920 */
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -0700921static uint32_t sap_weight_channel_txpwr_range(struct sap_context *sap_ctx,
gaoleze5108942017-03-31 16:56:42 +0800922 struct lim_channel_status
923 *channel_stat)
924{
925 uint32_t txpwr_weight_low_speed;
926 uint8_t softap_txpwr_range_weight_cfg;
927 uint8_t softap_txpwr_range_weight_local;
928
929 softap_txpwr_range_weight_cfg =
930 ACS_WEIGHT_SOFTAP_TX_POWER_RANGE_CFG
931 (sap_ctx->auto_channel_select_weight);
932
933 softap_txpwr_range_weight_local =
934 ACS_WEIGHT_CFG_TO_LOCAL(sap_ctx->auto_channel_select_weight,
935 softap_txpwr_range_weight_cfg);
936
937 if (channel_stat == NULL || channel_stat->channelfreq == 0) {
Srinivas Girigowda80213e52018-01-23 14:51:33 -0800938 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG,
gaoleze5108942017-03-31 16:56:42 +0800939 "In %s, sanity check failed return max weight",
940 __func__);
941 return softap_txpwr_range_weight_local;
942 }
943
944 txpwr_weight_low_speed = (channel_stat->chan_tx_pwr_range == 0) ? 0 :
945 (ACS_WEIGHT_COMPUTE(
946 sap_ctx->auto_channel_select_weight,
947 softap_txpwr_range_weight_cfg,
948 SOFTAP_MAX_TXPWR -
949 channel_stat->chan_tx_pwr_range,
950 SOFTAP_MAX_TXPWR - SOFTAP_MIN_TXPWR));
951
952 if (txpwr_weight_low_speed > softap_txpwr_range_weight_local)
953 txpwr_weight_low_speed = softap_txpwr_range_weight_local;
954
955 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
956 "In %s, tpr=%d, tprwc=%d, tprwl=%d, tprw=%d",
957 __func__, channel_stat->chan_tx_pwr_range,
958 softap_txpwr_range_weight_cfg,
959 softap_txpwr_range_weight_local,
960 txpwr_weight_low_speed);
961
962 return txpwr_weight_low_speed;
963}
964
965/**
966 * sap_weight_channel_txpwr_tput() - compute channel tx power
967 * throughput weight
968 * @sap_ctx: sap context
969 * @chn_stat: Pointer to chan status info
970 *
971 * Return: tx power throughput weight
972 */
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -0700973static uint32_t sap_weight_channel_txpwr_tput(struct sap_context *sap_ctx,
gaoleze5108942017-03-31 16:56:42 +0800974 struct lim_channel_status
975 *channel_stat)
976{
977 uint32_t txpwr_weight_high_speed;
978 uint8_t softap_txpwr_tput_weight_cfg;
979 uint8_t softap_txpwr_tput_weight_local;
980
981 softap_txpwr_tput_weight_cfg =
982 ACS_WEIGHT_SOFTAP_TX_POWER_THROUGHPUT_CFG
983 (sap_ctx->auto_channel_select_weight);
984
985 softap_txpwr_tput_weight_local =
986 ACS_WEIGHT_CFG_TO_LOCAL(sap_ctx->auto_channel_select_weight,
987 softap_txpwr_tput_weight_cfg);
988
989 if (channel_stat == NULL || channel_stat->channelfreq == 0) {
Srinivas Girigowda80213e52018-01-23 14:51:33 -0800990 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG,
gaoleze5108942017-03-31 16:56:42 +0800991 "In %s, sanity check failed return max weight",
992 __func__);
993 return softap_txpwr_tput_weight_local;
994 }
995
996 txpwr_weight_high_speed = (channel_stat->chan_tx_pwr_throughput == 0)
997 ? 0 : (ACS_WEIGHT_COMPUTE(
998 sap_ctx->auto_channel_select_weight,
999 softap_txpwr_tput_weight_cfg,
1000 SOFTAP_MAX_TXPWR -
1001 channel_stat->chan_tx_pwr_throughput,
1002 SOFTAP_MAX_TXPWR - SOFTAP_MIN_TXPWR));
1003
1004 if (txpwr_weight_high_speed > softap_txpwr_tput_weight_local)
1005 txpwr_weight_high_speed = softap_txpwr_tput_weight_local;
1006
1007 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
1008 "In %s, tpt=%d, tptwc=%d, tptwl=%d, tptw=%d",
1009 __func__, channel_stat->chan_tx_pwr_throughput,
1010 softap_txpwr_tput_weight_cfg,
1011 softap_txpwr_tput_weight_local,
1012 txpwr_weight_high_speed);
1013
1014 return txpwr_weight_high_speed;
1015}
1016
1017/**
1018 * sap_weight_channel_status() - compute chan status weight
1019 * @sap_ctx: sap context
1020 * @chn_stat: Pointer to chan status info
1021 *
1022 * Return: chan status weight
1023 */
1024static
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -07001025uint32_t sap_weight_channel_status(struct sap_context *sap_ctx,
gaoleze5108942017-03-31 16:56:42 +08001026 struct lim_channel_status *channel_stat)
1027{
1028 return sap_weight_channel_noise_floor(sap_ctx, channel_stat) +
1029 sap_weight_channel_free(sap_ctx, channel_stat) +
1030 sap_weight_channel_txpwr_range(sap_ctx, channel_stat) +
1031 sap_weight_channel_txpwr_tput(sap_ctx, channel_stat);
1032}
1033
1034/**
Yeshwanth Sriram Guntuka273889e2018-02-16 17:11:46 +05301035 * sap_check_channels_same_band() - Check if two channels belong to same band
1036 * @ch_num1: channel number
1037 * @ch_num2: channel number
1038 *
1039 * Return: true if both channels belong to same band else false
1040 */
1041static bool sap_check_channels_same_band(uint16_t ch_num1, uint16_t ch_num2)
1042{
1043 if ((ch_num1 <= SIR_11B_CHANNEL_END &&
1044 ch_num2 <= SIR_11B_CHANNEL_END) ||
1045 (ch_num1 >= SIR_11A_CHANNEL_BEGIN &&
1046 ch_num2 >= SIR_11A_CHANNEL_BEGIN))
1047 return true;
1048
1049 return false;
1050}
1051
1052/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001053 * sap_update_rssi_bsscount() - updates bss count and rssi effect.
1054 *
1055 * @pSpectCh: Channel Information
1056 * @offset: Channel Offset
1057 * @sap_24g: Channel is in 2.4G or 5G
Liangwei Dong71ed6502016-10-20 03:40:45 -04001058 * @spectch_start: the start of spect ch array
1059 * @spectch_end: the end of spect ch array
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001060 *
1061 * sap_update_rssi_bsscount updates bss count and rssi effect based
1062 * on the channel offset.
1063 *
1064 * Return: None.
1065 */
1066
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001067static void sap_update_rssi_bsscount(tSapSpectChInfo *pSpectCh, int32_t offset,
Liangwei Dong71ed6502016-10-20 03:40:45 -04001068 bool sap_24g, tSapSpectChInfo *spectch_start,
1069 tSapSpectChInfo *spectch_end)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001070{
1071 tSapSpectChInfo *pExtSpectCh = NULL;
1072 int32_t rssi, rsssi_effect;
1073
1074 pExtSpectCh = (pSpectCh + offset);
Liangwei Dong71ed6502016-10-20 03:40:45 -04001075 if (pExtSpectCh != NULL &&
1076 pExtSpectCh >= spectch_start &&
1077 pExtSpectCh < spectch_end) {
Yeshwanth Sriram Guntuka273889e2018-02-16 17:11:46 +05301078 if (!sap_check_channels_same_band(pSpectCh->chNum,
1079 pExtSpectCh->chNum))
1080 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001081 ++pExtSpectCh->bssCount;
1082 switch (offset) {
1083 case -1:
1084 case 1:
1085 rsssi_effect = sap_24g ?
1086 SAP_24GHZ_FIRST_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY :
1087 SAP_SUBBAND1_RSSI_EFFECT_PRIMARY;
1088 break;
1089 case -2:
1090 case 2:
1091 rsssi_effect = sap_24g ?
1092 SAP_24GHZ_SEC_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY :
1093 SAP_SUBBAND2_RSSI_EFFECT_PRIMARY;
1094 break;
1095 case -3:
1096 case 3:
1097 rsssi_effect = sap_24g ?
1098 SAP_24GHZ_THIRD_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY :
1099 SAP_SUBBAND3_RSSI_EFFECT_PRIMARY;
1100 break;
1101 case -4:
1102 case 4:
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001103 rsssi_effect = sap_24g ?
1104 SAP_24GHZ_FOURTH_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY :
1105 SAP_SUBBAND4_RSSI_EFFECT_PRIMARY;
1106 break;
1107 case -5:
1108 case 5:
1109 rsssi_effect = SAP_SUBBAND5_RSSI_EFFECT_PRIMARY;
1110 break;
1111 case -6:
1112 case 6:
1113 rsssi_effect = SAP_SUBBAND6_RSSI_EFFECT_PRIMARY;
1114 break;
1115 case -7:
1116 case 7:
1117 rsssi_effect = SAP_SUBBAND7_RSSI_EFFECT_PRIMARY;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001118 break;
1119 default:
1120 rsssi_effect = 0;
1121 break;
1122 }
1123
1124 rssi = pSpectCh->rssiAgr + rsssi_effect;
1125 if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi))
1126 pExtSpectCh->rssiAgr = rssi;
1127 if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI)
1128 pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI;
1129 }
1130}
1131
1132/**
1133 * sap_upd_chan_spec_params() - sap_upd_chan_spec_params
1134 * updates channel parameters obtained from Beacon
1135 * @pBeaconStruct Beacon strucutre populated by parse_beacon function
1136 * @channelWidth Channel width
1137 * @secondaryChannelOffset Secondary Channel Offset
1138 * @vhtSupport If channel supports VHT
1139 * @centerFreq Central frequency for the given channel.
1140 *
1141 * sap_upd_chan_spec_params updates the spectrum channels based on the
1142 * pBeaconStruct obtained from Beacon IE
1143 *
1144 * Return: NA.
1145 */
1146
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001147static void sap_upd_chan_spec_params(tSirProbeRespBeacon *pBeaconStruct,
1148 uint16_t *channelWidth,
1149 uint16_t *secondaryChannelOffset,
1150 uint16_t *vhtSupport,
1151 uint16_t *centerFreq,
1152 uint16_t *centerFreq_2)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001153{
1154 if (NULL == pBeaconStruct) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301155 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001156 FL("pBeaconStruct is NULL"));
1157 return;
1158 }
1159
1160 if (pBeaconStruct->HTCaps.present && pBeaconStruct->HTInfo.present) {
1161 *channelWidth = pBeaconStruct->HTCaps.supportedChannelWidthSet;
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001162 *secondaryChannelOffset =
1163 pBeaconStruct->HTInfo.secondaryChannelOffset;
1164 if (!pBeaconStruct->VHTOperation.present)
1165 return;
1166 *vhtSupport = pBeaconStruct->VHTOperation.present;
1167 if (pBeaconStruct->VHTOperation.chanWidth) {
1168 *centerFreq =
1169 pBeaconStruct->VHTOperation.chanCenterFreqSeg1;
1170 *centerFreq_2 =
1171 pBeaconStruct->VHTOperation.chanCenterFreqSeg2;
1172 /*
1173 * LHS follows tSirMacHTChannelWidth, while RHS follows
1174 * WNI_CFG_VHT_CHANNEL_WIDTH_X format hence following
1175 * adjustment
1176 */
1177 *channelWidth =
1178 pBeaconStruct->VHTOperation.chanWidth + 1;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001179
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001180 }
1181 }
1182}
1183
1184/**
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001185 * sap_update_rssi_bsscount_vht_5G() - updates bss count and rssi effect.
1186 *
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001187 * @spect_ch: Channel Information
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001188 * @offset: Channel Offset
1189 * @num_ch: no.of channels
Liangwei Dong71ed6502016-10-20 03:40:45 -04001190 * @spectch_start: the start of spect ch array
1191 * @spectch_end: the end of spect ch array
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001192 *
1193 * sap_update_rssi_bsscount_vht_5G updates bss count and rssi effect based
1194 * on the channel offset.
1195 *
1196 * Return: None.
1197 */
1198
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001199static void sap_update_rssi_bsscount_vht_5G(tSapSpectChInfo *spect_ch,
1200 int32_t offset,
Liangwei Dong71ed6502016-10-20 03:40:45 -04001201 uint16_t num_ch,
1202 tSapSpectChInfo *spectch_start,
1203 tSapSpectChInfo *spectch_end)
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001204{
1205 int32_t ch_offset;
1206 uint16_t i, cnt;
1207
1208 if (!offset)
1209 return;
1210 if (offset > 0)
1211 cnt = num_ch;
1212 else
1213 cnt = num_ch + 1;
1214 for (i = 0; i < cnt; i++) {
1215 ch_offset = offset + i;
1216 if (ch_offset == 0)
1217 continue;
Liangwei Dong71ed6502016-10-20 03:40:45 -04001218 sap_update_rssi_bsscount(spect_ch, ch_offset, false,
1219 spectch_start, spectch_end);
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001220 }
1221}
1222/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001223 * sap_interference_rssi_count_5G() - sap_interference_rssi_count
1224 * considers the Adjacent channel rssi and
1225 * data count(here number of BSS observed)
1226 * @spect_ch: Channel Information
1227 * @chan_width: Channel width parsed from beacon IE
1228 * @sec_chan_offset: Secondary Channel Offset
1229 * @center_freq: Central frequency for the given channel.
1230 * @channel_id: channel_id
Liangwei Dong71ed6502016-10-20 03:40:45 -04001231 * @spectch_start: the start of spect ch array
1232 * @spectch_end: the end of spect ch array
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001233 *
1234 * sap_interference_rssi_count_5G considers the Adjacent channel rssi
1235 * and data count(here number of BSS observed)
1236 *
1237 * Return: NA.
1238 */
1239
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001240static void sap_interference_rssi_count_5G(tSapSpectChInfo *spect_ch,
1241 uint16_t chan_width,
1242 uint16_t sec_chan_offset,
1243 uint16_t center_freq,
1244 uint16_t center_freq_2,
Liangwei Dong71ed6502016-10-20 03:40:45 -04001245 uint8_t channel_id,
1246 tSapSpectChInfo *spectch_start,
1247 tSapSpectChInfo *spectch_end)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001248{
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001249 uint16_t num_ch;
1250 int32_t offset = 0;
Srinivas Girigowda4d65ebe2017-10-13 21:41:42 -07001251
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001252 if (NULL == spect_ch) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301253 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001254 FL("spect_ch is NULL"));
1255 return;
1256 }
1257
1258 /* Updating the received ChannelWidth */
1259 if (spect_ch->channelWidth != chan_width)
1260 spect_ch->channelWidth = chan_width;
1261 /* If received ChannelWidth is other than HT20,
1262 * we need to update the extension channel Params as well
1263 * chan_width == 0, HT20
1264 * chan_width == 1, HT40
1265 * chan_width == 2, VHT80
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001266 * chan_width == 3, VHT160
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001267 */
1268
1269 switch (spect_ch->channelWidth) {
1270 case eHT_CHANNEL_WIDTH_40MHZ: /* HT40 */
1271 switch (sec_chan_offset) {
1272 /* Above the Primary Channel */
1273 case PHY_DOUBLE_CHANNEL_LOW_PRIMARY:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001274 sap_update_rssi_bsscount(spect_ch, 1, false,
1275 spectch_start, spectch_end);
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001276 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001277
1278 /* Below the Primary channel */
1279 case PHY_DOUBLE_CHANNEL_HIGH_PRIMARY:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001280 sap_update_rssi_bsscount(spect_ch, -1, false,
1281 spectch_start, spectch_end);
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001282 return;
1283 }
1284 return;
1285 case eHT_CHANNEL_WIDTH_80MHZ: /* VHT80 */
1286 num_ch = 3;
1287 if ((center_freq - channel_id) == 6) {
1288 offset = 1;
1289 } else if ((center_freq - channel_id) == 2) {
1290 offset = -1;
1291 } else if ((center_freq - channel_id) == -2) {
1292 offset = -2;
1293 } else if ((center_freq - channel_id) == -6) {
1294 offset = -3;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001295 }
1296 break;
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001297 case eHT_CHANNEL_WIDTH_160MHZ: /* VHT160 */
1298 num_ch = 7;
1299 if ((center_freq - channel_id) == 14)
1300 offset = 1;
1301 else if ((center_freq - channel_id) == 10)
1302 offset = -1;
1303 else if ((center_freq - channel_id) == 6)
1304 offset = -2;
1305 else if ((center_freq - channel_id) == 2)
1306 offset = -3;
1307 else if ((center_freq - channel_id) == -2)
1308 offset = -4;
1309 else if ((center_freq - channel_id) == -6)
1310 offset = -5;
1311 else if ((center_freq - channel_id) == -10)
1312 offset = -6;
1313 else if ((center_freq - channel_id) == -14)
1314 offset = -7;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001315 break;
1316 default:
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001317 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001318 }
Liangwei Dong71ed6502016-10-20 03:40:45 -04001319 sap_update_rssi_bsscount_vht_5G(spect_ch, offset, num_ch,
1320 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001321}
1322
1323/**
1324 * sap_interference_rssi_count() - sap_interference_rssi_count
1325 * considers the Adjacent channel rssi
1326 * and data count(here number of BSS observed)
1327 * @spect_ch Channel Information
Liangwei Dong71ed6502016-10-20 03:40:45 -04001328 * @spectch_start: the start of spect ch array
1329 * @spectch_end: the end of spect ch array
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001330 *
1331 * sap_interference_rssi_count considers the Adjacent channel rssi
1332 * and data count(here number of BSS observed)
1333 *
1334 * Return: None.
1335 */
1336
Liangwei Dong71ed6502016-10-20 03:40:45 -04001337static void sap_interference_rssi_count(tSapSpectChInfo *spect_ch,
1338 tSapSpectChInfo *spectch_start,
1339 tSapSpectChInfo *spectch_end)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001340{
1341 if (NULL == spect_ch) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301342 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001343 "%s: spect_ch is NULL", __func__);
1344 return;
1345 }
1346
1347 switch (spect_ch->chNum) {
1348 case CHANNEL_1:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001349 sap_update_rssi_bsscount(spect_ch, 1, true,
1350 spectch_start, spectch_end);
1351 sap_update_rssi_bsscount(spect_ch, 2, true,
1352 spectch_start, spectch_end);
1353 sap_update_rssi_bsscount(spect_ch, 3, true,
1354 spectch_start, spectch_end);
1355 sap_update_rssi_bsscount(spect_ch, 4, true,
1356 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001357 break;
1358
1359 case CHANNEL_2:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001360 sap_update_rssi_bsscount(spect_ch, -1, true,
1361 spectch_start, spectch_end);
1362 sap_update_rssi_bsscount(spect_ch, 1, true,
1363 spectch_start, spectch_end);
1364 sap_update_rssi_bsscount(spect_ch, 2, true,
1365 spectch_start, spectch_end);
1366 sap_update_rssi_bsscount(spect_ch, 3, true,
1367 spectch_start, spectch_end);
1368 sap_update_rssi_bsscount(spect_ch, 4, true,
1369 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001370 break;
1371 case CHANNEL_3:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001372 sap_update_rssi_bsscount(spect_ch, -2, true,
1373 spectch_start, spectch_end);
1374 sap_update_rssi_bsscount(spect_ch, -1, true,
1375 spectch_start, spectch_end);
1376 sap_update_rssi_bsscount(spect_ch, 1, true,
1377 spectch_start, spectch_end);
1378 sap_update_rssi_bsscount(spect_ch, 2, true,
1379 spectch_start, spectch_end);
1380 sap_update_rssi_bsscount(spect_ch, 3, true,
1381 spectch_start, spectch_end);
1382 sap_update_rssi_bsscount(spect_ch, 4, true,
1383 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001384 break;
1385 case CHANNEL_4:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001386 sap_update_rssi_bsscount(spect_ch, -3, true,
1387 spectch_start, spectch_end);
1388 sap_update_rssi_bsscount(spect_ch, -2, true,
1389 spectch_start, spectch_end);
1390 sap_update_rssi_bsscount(spect_ch, -1, true,
1391 spectch_start, spectch_end);
1392 sap_update_rssi_bsscount(spect_ch, 1, true,
1393 spectch_start, spectch_end);
1394 sap_update_rssi_bsscount(spect_ch, 2, true,
1395 spectch_start, spectch_end);
1396 sap_update_rssi_bsscount(spect_ch, 3, true,
1397 spectch_start, spectch_end);
1398 sap_update_rssi_bsscount(spect_ch, 4, true,
1399 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001400 break;
1401
1402 case CHANNEL_5:
1403 case CHANNEL_6:
1404 case CHANNEL_7:
1405 case CHANNEL_8:
1406 case CHANNEL_9:
1407 case CHANNEL_10:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001408 sap_update_rssi_bsscount(spect_ch, -4, true,
1409 spectch_start, spectch_end);
1410 sap_update_rssi_bsscount(spect_ch, -3, true,
1411 spectch_start, spectch_end);
1412 sap_update_rssi_bsscount(spect_ch, -2, true,
1413 spectch_start, spectch_end);
1414 sap_update_rssi_bsscount(spect_ch, -1, true,
1415 spectch_start, spectch_end);
1416 sap_update_rssi_bsscount(spect_ch, 1, true,
1417 spectch_start, spectch_end);
1418 sap_update_rssi_bsscount(spect_ch, 2, true,
1419 spectch_start, spectch_end);
1420 sap_update_rssi_bsscount(spect_ch, 3, true,
1421 spectch_start, spectch_end);
1422 sap_update_rssi_bsscount(spect_ch, 4, true,
1423 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001424 break;
1425
1426 case CHANNEL_11:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001427 sap_update_rssi_bsscount(spect_ch, -4, true,
1428 spectch_start, spectch_end);
1429 sap_update_rssi_bsscount(spect_ch, -3, true,
1430 spectch_start, spectch_end);
1431 sap_update_rssi_bsscount(spect_ch, -2, true,
1432 spectch_start, spectch_end);
1433 sap_update_rssi_bsscount(spect_ch, -1, true,
1434 spectch_start, spectch_end);
1435 sap_update_rssi_bsscount(spect_ch, 1, true,
1436 spectch_start, spectch_end);
1437 sap_update_rssi_bsscount(spect_ch, 2, true,
1438 spectch_start, spectch_end);
1439 sap_update_rssi_bsscount(spect_ch, 3, true,
1440 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001441 break;
1442
1443 case CHANNEL_12:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001444 sap_update_rssi_bsscount(spect_ch, -4, true,
1445 spectch_start, spectch_end);
1446 sap_update_rssi_bsscount(spect_ch, -3, true,
1447 spectch_start, spectch_end);
1448 sap_update_rssi_bsscount(spect_ch, -2, true,
1449 spectch_start, spectch_end);
1450 sap_update_rssi_bsscount(spect_ch, -1, true,
1451 spectch_start, spectch_end);
1452 sap_update_rssi_bsscount(spect_ch, 1, true,
1453 spectch_start, spectch_end);
1454 sap_update_rssi_bsscount(spect_ch, 2, true,
1455 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001456 break;
1457
1458 case CHANNEL_13:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001459 sap_update_rssi_bsscount(spect_ch, -4, true,
1460 spectch_start, spectch_end);
1461 sap_update_rssi_bsscount(spect_ch, -3, true,
1462 spectch_start, spectch_end);
1463 sap_update_rssi_bsscount(spect_ch, -2, true,
1464 spectch_start, spectch_end);
1465 sap_update_rssi_bsscount(spect_ch, -1, true,
1466 spectch_start, spectch_end);
1467 sap_update_rssi_bsscount(spect_ch, 1, true,
1468 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001469 break;
1470
1471 case CHANNEL_14:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001472 sap_update_rssi_bsscount(spect_ch, -4, true,
1473 spectch_start, spectch_end);
1474 sap_update_rssi_bsscount(spect_ch, -3, true,
1475 spectch_start, spectch_end);
1476 sap_update_rssi_bsscount(spect_ch, -2, true,
1477 spectch_start, spectch_end);
1478 sap_update_rssi_bsscount(spect_ch, -1, true,
1479 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001480 break;
1481
1482 default:
1483 break;
1484 }
1485}
1486
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001487/**
1488 * ch_in_pcl() - Is channel in the Preferred Channel List (PCL)
1489 * @sap_ctx: SAP context which contains the current PCL
1490 * @channel: Input channel number to be checked
1491 *
1492 * Check if a channel is in the preferred channel list
1493 *
1494 * Return:
1495 * true: channel is in PCL,
1496 * false: channel is not in PCL
1497 */
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -07001498static bool ch_in_pcl(struct sap_context *sap_ctx, uint8_t channel)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001499{
1500 uint32_t i;
1501
1502 for (i = 0; i < sap_ctx->acs_cfg->pcl_ch_count; i++) {
1503 if (channel == sap_ctx->acs_cfg->pcl_channels[i])
1504 return true;
1505 }
1506
1507 return false;
1508}
1509
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001510/**
1511 * sap_compute_spect_weight() - Compute spectrum weight
1512 * @pSpectInfoParams: Pointer to the tSpectInfoParams structure
1513 * @halHandle: Pointer to HAL handle
1514 * @pResult: Pointer to tScanResultHandle
1515 * @sap_ctx: Context of the SAP
1516 *
1517 * Main function for computing the weight of each channel in the
1518 * spectrum based on the RSSI value of the BSSes on the channel
1519 * and number of BSS
1520 */
1521static void sap_compute_spect_weight(tSapChSelSpectInfo *pSpectInfoParams,
1522 tHalHandle halHandle,
1523 tScanResultHandle pResult,
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -07001524 struct sap_context *sap_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001525{
1526 int8_t rssi = 0;
1527 uint8_t chn_num = 0;
1528 uint8_t channel_id = 0;
Himanshu Agarwal170b4972018-06-27 17:01:40 +05301529 uint8_t i;
1530 bool found = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001531
1532 tCsrScanResultInfo *pScanResult;
1533 tSapSpectChInfo *pSpectCh = pSpectInfoParams->pSpectCh;
1534 uint32_t operatingBand;
1535 uint16_t channelWidth;
1536 uint16_t secondaryChannelOffset;
1537 uint16_t centerFreq;
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001538 uint16_t centerFreq_2 = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001539 uint16_t vhtSupport;
1540 uint32_t ieLen = 0;
1541 tSirProbeRespBeacon *pBeaconStruct;
1542 tpAniSirGlobal pMac = (tpAniSirGlobal) halHandle;
Liangwei Dong71ed6502016-10-20 03:40:45 -04001543 tSapSpectChInfo *spectch_start = pSpectInfoParams->pSpectCh;
1544 tSapSpectChInfo *spectch_end = pSpectInfoParams->pSpectCh +
1545 pSpectInfoParams->numSpectChans;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001546
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301547 pBeaconStruct = qdf_mem_malloc(sizeof(tSirProbeRespBeacon));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001548 if (NULL == pBeaconStruct) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301549 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Kaushik, Sushantee3ed032016-08-04 16:40:46 +05301550 "Unable to allocate memory in sap_compute_spect_weight");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001551 return;
1552 }
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301553 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001554 "In %s, Computing spectral weight", __func__);
1555
1556 /**
1557 * Soft AP specific channel weight calculation using DFS formula
1558 */
1559 SET_ACS_BAND(operatingBand, sap_ctx);
1560
1561 pScanResult = sme_scan_result_get_first(halHandle, pResult);
1562
1563 while (pScanResult) {
1564 pSpectCh = pSpectInfoParams->pSpectCh;
1565 /* Defining the default values, so that any value will hold the default values */
1566 channelWidth = eHT_CHANNEL_WIDTH_20MHZ;
1567 secondaryChannelOffset = PHY_SINGLE_CHANNEL_CENTERED;
1568 vhtSupport = 0;
1569 centerFreq = 0;
1570
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001571
Yingying Tang22facc12016-10-20 17:43:59 +08001572 ieLen = GET_IE_LEN_IN_BSS(
1573 pScanResult->BssDescriptor.length);
1574 qdf_mem_set((uint8_t *) pBeaconStruct,
1575 sizeof(tSirProbeRespBeacon), 0);
1576
1577
1578 if ((sir_parse_beacon_ie
1579 (pMac, pBeaconStruct, (uint8_t *)
1580 (pScanResult->BssDescriptor.ieFields),
Jeff Johnson83e30fa2018-06-07 23:01:11 -07001581 ieLen)) == QDF_STATUS_SUCCESS)
Yingying Tang22facc12016-10-20 17:43:59 +08001582 sap_upd_chan_spec_params(
1583 pBeaconStruct,
1584 &channelWidth,
1585 &secondaryChannelOffset,
1586 &vhtSupport, &centerFreq,
1587 &centerFreq_2);
1588
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001589 /* Processing for each tCsrScanResultInfo in the tCsrScanResult DLink list */
1590 for (chn_num = 0; chn_num < pSpectInfoParams->numSpectChans;
1591 chn_num++) {
1592
1593 /*
Himanshu Agarwalcf5b8932018-07-02 18:06:49 +05301594 * If the Beacon has channel ID, use it other wise we
1595 * will rely on the channelIdSelf
1596 */
1597 if (pScanResult->BssDescriptor.channelId == 0)
1598 channel_id =
1599 pScanResult->BssDescriptor.channelIdSelf;
1600 else
1601 channel_id =
1602 pScanResult->BssDescriptor.channelId;
1603
1604 /*
Himanshu Agarwal170b4972018-06-27 17:01:40 +05301605 * Check if channel is present in scan channel list or
1606 * not. If not present, then continue as no need to
1607 * process the beacon on this channel.
1608 */
1609 for (i = 0; i < sap_ctx->num_of_channel; i++) {
Himanshu Agarwalcf5b8932018-07-02 18:06:49 +05301610 if (channel_id ==
Himanshu Agarwal170b4972018-06-27 17:01:40 +05301611 sap_ctx->channelList[i]) {
1612 found = true;
1613 break;
1614 }
1615 }
1616
1617 if (!found)
1618 continue;
1619
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001620 if (pSpectCh && (channel_id == pSpectCh->chNum)) {
1621 if (pSpectCh->rssiAgr <
1622 pScanResult->BssDescriptor.rssi)
1623 pSpectCh->rssiAgr =
1624 pScanResult->BssDescriptor.rssi;
1625
1626 ++pSpectCh->bssCount; /* Increment the count of BSS */
1627
1628 /*
1629 * Connsidering the Extension Channel
1630 * only in a channels
1631 */
1632 switch (operatingBand) {
1633 case eCSR_DOT11_MODE_11a:
1634 sap_interference_rssi_count_5G(
1635 pSpectCh, channelWidth,
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001636 secondaryChannelOffset,
1637 centerFreq,
1638 centerFreq_2,
Liangwei Dong71ed6502016-10-20 03:40:45 -04001639 channel_id,
1640 spectch_start,
1641 spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001642 break;
1643
1644 case eCSR_DOT11_MODE_11g:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001645 sap_interference_rssi_count(pSpectCh,
1646 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001647 break;
1648
1649 case eCSR_DOT11_MODE_abg:
Himanshu Agarwal4f503b82018-03-19 12:10:45 +05301650 if (pSpectCh->chNum >=
1651 SIR_11A_CHANNEL_BEGIN)
1652 sap_interference_rssi_count_5G(
1653 pSpectCh, channelWidth,
1654 secondaryChannelOffset,
1655 centerFreq,
1656 centerFreq_2,
1657 channel_id,
1658 spectch_start,
1659 spectch_end);
1660 else
1661 sap_interference_rssi_count(
1662 pSpectCh,
1663 spectch_start,
1664 spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001665 break;
1666 }
1667
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301668 QDF_TRACE(QDF_MODULE_ID_SAP,
1669 QDF_TRACE_LEVEL_INFO_HIGH,
Jeff Johnsona7c0ddb2017-09-18 08:14:12 -07001670 "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 -08001671 __func__,
1672 pScanResult->BssDescriptor.
1673 channelIdSelf,
1674 pScanResult->BssDescriptor.channelId,
1675 pScanResult->BssDescriptor.rssi,
1676 pSpectCh->bssCount, pScanResult,
1677 pSpectCh->channelWidth,
1678 secondaryChannelOffset, centerFreq);
1679 pSpectCh++;
1680 break;
1681 } else {
1682 pSpectCh++;
1683 }
1684 }
1685
1686 pScanResult = sme_scan_result_get_next(halHandle, pResult);
1687 }
1688
1689 /* Calculate the weights for all channels in the spectrum pSpectCh */
1690 pSpectCh = pSpectInfoParams->pSpectCh;
1691
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301692 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001693 "In %s, Spectrum Channels Weight", __func__);
1694
1695 for (chn_num = 0; chn_num < (pSpectInfoParams->numSpectChans);
1696 chn_num++) {
1697
1698 /*
1699 rssi : Maximum received signal strength among all BSS on that channel
1700 bssCount : Number of BSS on that channel
1701 */
1702
1703 rssi = (int8_t) pSpectCh->rssiAgr;
Himanshu Agarwal3697f942018-06-13 14:04:26 +05301704 if (ch_in_pcl(sap_ctx, pSpectCh->chNum))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001705 rssi -= PCL_RSSI_DISCOUNT;
1706
Himanshu Agarwal3697f942018-06-13 14:04:26 +05301707 if (rssi < SOFTAP_MIN_RSSI)
1708 rssi = SOFTAP_MIN_RSSI;
1709
Himanshu Agarwalfee2e362018-01-18 20:26:35 +05301710 if (pSpectCh->weight == SAP_ACS_WEIGHT_MAX)
1711 goto debug_info;
1712
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001713 pSpectCh->weight =
gaoleze5108942017-03-31 16:56:42 +08001714 SAPDFS_NORMALISE_1000 *
1715 (sapweight_rssi_count(sap_ctx, rssi,
1716 pSpectCh->bssCount) + sap_weight_channel_status(
1717 sap_ctx, sap_get_channel_status(pMac,
1718 pSpectCh->chNum)));
1719 if (pSpectCh->weight > SAP_ACS_WEIGHT_MAX)
1720 pSpectCh->weight = SAP_ACS_WEIGHT_MAX;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001721 pSpectCh->weight_copy = pSpectCh->weight;
1722
Himanshu Agarwalfee2e362018-01-18 20:26:35 +05301723debug_info:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001724 /* ------ Debug Info ------ */
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301725 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Himanshu Agarwal3697f942018-06-13 14:04:26 +05301726 "In %s, Chan=%d Weight= %d rssiAgr=%d rssi_pcl_discount: %d bssCount=%d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001727 __func__, pSpectCh->chNum, pSpectCh->weight,
Himanshu Agarwal3697f942018-06-13 14:04:26 +05301728 pSpectCh->rssiAgr, rssi, pSpectCh->bssCount);
wadesongcb0ded22018-02-02 17:57:20 +08001729 host_log_acs_chan_spect_weight(pSpectCh->chNum,
1730 (uint16_t)pSpectCh->weight,
1731 pSpectCh->rssiAgr,
1732 pSpectCh->bssCount);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001733 /* ------ Debug Info ------ */
1734 pSpectCh++;
1735 }
gaoleze5108942017-03-31 16:56:42 +08001736 sap_clear_channel_status(pMac);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301737 qdf_mem_free(pBeaconStruct);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001738}
1739
1740/*==========================================================================
1741 FUNCTION sap_chan_sel_exit
1742
1743 DESCRIPTION
1744 Exit function for free out the allocated memory, to be called
1745 at the end of the dfsSelectChannel function
1746
1747 DEPENDENCIES
1748 NA.
1749
1750 PARAMETERS
1751
1752 IN
1753 pSpectInfoParams : Pointer to the tSapChSelSpectInfo structure
1754
1755 RETURN VALUE
1756 void : NULL
1757
1758 SIDE EFFECTS
1759 ============================================================================*/
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001760static void sap_chan_sel_exit(tSapChSelSpectInfo *pSpectInfoParams)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001761{
1762 /* Free all the allocated memory */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301763 qdf_mem_free(pSpectInfoParams->pSpectCh);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001764}
1765
1766/*==========================================================================
1767 FUNCTION sap_sort_chl_weight
1768
1769 DESCRIPTION
Jeff Johnsonc7e4d162018-05-12 16:20:34 -07001770 Function to sort the channels with the least weight first for 20MHz channels
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001771
1772 DEPENDENCIES
1773 NA.
1774
1775 PARAMETERS
1776
1777 IN
1778 pSpectInfoParams : Pointer to the tSapChSelSpectInfo structure
1779
1780 RETURN VALUE
1781 void : NULL
1782
1783 SIDE EFFECTS
1784 ============================================================================*/
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001785static void sap_sort_chl_weight(tSapChSelSpectInfo *pSpectInfoParams)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001786{
1787 tSapSpectChInfo temp;
1788
1789 tSapSpectChInfo *pSpectCh = NULL;
1790 uint32_t i = 0, j = 0, minWeightIndex = 0;
1791
1792 pSpectCh = pSpectInfoParams->pSpectCh;
1793 for (i = 0; i < pSpectInfoParams->numSpectChans; i++) {
1794 minWeightIndex = i;
1795 for (j = i + 1; j < pSpectInfoParams->numSpectChans; j++) {
1796 if (pSpectCh[j].weight <
1797 pSpectCh[minWeightIndex].weight) {
1798 minWeightIndex = j;
Yeshwanth Sriram Guntuka273889e2018-02-16 17:11:46 +05301799 } else if (pSpectCh[j].weight ==
1800 pSpectCh[minWeightIndex].weight) {
1801 if (pSpectCh[j].bssCount <
1802 pSpectCh[minWeightIndex].bssCount)
1803 minWeightIndex = j;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001804 }
1805 }
1806 if (minWeightIndex != i) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301807 qdf_mem_copy(&temp, &pSpectCh[minWeightIndex],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001808 sizeof(*pSpectCh));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301809 qdf_mem_copy(&pSpectCh[minWeightIndex], &pSpectCh[i],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001810 sizeof(*pSpectCh));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301811 qdf_mem_copy(&pSpectCh[i], &temp, sizeof(*pSpectCh));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001812 }
1813 }
1814}
1815
1816/**
Jeff Johnsonc7e4d162018-05-12 16:20:34 -07001817 * set_ht80_chl_bit() - to set available channel to ht80 channel bitmap
bingse2782382017-03-23 10:34:52 +08001818 * @channel_bitmap: Pointer to the chan_bonding_bitmap structure
1819 * @spect_info_params: Pointer to the tSapChSelSpectInfo structure
1820 *
1821 * Return: none
1822 */
1823static void set_ht80_chl_bit(chan_bonding_bitmap *channel_bitmap,
1824 tSapChSelSpectInfo *spec_info_params)
1825{
1826 uint8_t i, j;
1827 tSapSpectChInfo *spec_info;
1828 int start_channel = 0;
1829
1830 channel_bitmap->chanBondingSet[0].startChannel =
1831 acs_ht80_channels[0].chStartNum;
1832 channel_bitmap->chanBondingSet[1].startChannel =
1833 acs_ht80_channels[1].chStartNum;
1834 channel_bitmap->chanBondingSet[2].startChannel =
1835 acs_ht80_channels[2].chStartNum;
1836 channel_bitmap->chanBondingSet[3].startChannel =
1837 acs_ht80_channels[3].chStartNum;
1838 channel_bitmap->chanBondingSet[4].startChannel =
1839 acs_ht80_channels[4].chStartNum;
1840 channel_bitmap->chanBondingSet[5].startChannel =
1841 acs_ht80_channels[5].chStartNum;
1842
1843 spec_info = spec_info_params->pSpectCh;
1844 for (j = 0; j < spec_info_params->numSpectChans; j++) {
1845 for (i = 0; i < MAX_80MHZ_BANDS; i++) {
1846 start_channel =
1847 channel_bitmap->chanBondingSet[i].startChannel;
1848 if (spec_info[j].chNum >= start_channel &&
1849 (spec_info[j].chNum <= start_channel + 12)) {
1850 channel_bitmap->chanBondingSet[i].channelMap |=
1851 1 << ((spec_info[j].chNum -
1852 start_channel)/4);
1853 break;
1854 }
1855 }
1856 }
1857}
1858
1859/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001860 * sap_sort_chl_weight_ht80() - to sort the channels with the least weight
1861 * @pSpectInfoParams: Pointer to the tSapChSelSpectInfo structure
1862 *
Jeff Johnsonc7e4d162018-05-12 16:20:34 -07001863 * Function to sort the channels with the least weight first for HT80 channels
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001864 *
1865 * Return: none
1866 */
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001867static void sap_sort_chl_weight_ht80(tSapChSelSpectInfo *pSpectInfoParams)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001868{
1869 uint8_t i, j, n;
1870 tSapSpectChInfo *pSpectInfo;
1871 uint8_t minIdx;
bingse2782382017-03-23 10:34:52 +08001872 int start_channel = 0;
1873 chan_bonding_bitmap *channel_bitmap;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001874
bingse2782382017-03-23 10:34:52 +08001875 channel_bitmap = qdf_mem_malloc(sizeof(chan_bonding_bitmap));
1876 if (NULL == channel_bitmap) {
1877 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG,
1878 "%s: Failed to allocate memory", __func__);
1879 return;
1880 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001881 pSpectInfo = pSpectInfoParams->pSpectCh;
1882 /* for each HT80 channel, calculate the combined weight of the
1883 four 20MHz weight */
1884 for (i = 0; i < ARRAY_SIZE(acs_ht80_channels); i++) {
1885 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
1886 if (pSpectInfo[j].chNum ==
1887 acs_ht80_channels[i].chStartNum)
1888 break;
1889 }
1890 if (j == pSpectInfoParams->numSpectChans)
1891 continue;
1892
1893 if (!(((pSpectInfo[j].chNum + 4) == pSpectInfo[j + 1].chNum) &&
1894 ((pSpectInfo[j].chNum + 8) ==
1895 pSpectInfo[j + 2].chNum) &&
1896 ((pSpectInfo[j].chNum + 12) ==
1897 pSpectInfo[j + 3].chNum))) {
1898 /*
1899 * some channels does not exist in pSectInfo array,
1900 * skip this channel and those in the same HT80 width
1901 */
1902 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 4;
1903 if ((pSpectInfo[j].chNum + 4) ==
1904 pSpectInfo[j + 1].chNum)
1905 pSpectInfo[j + 1].weight =
1906 SAP_ACS_WEIGHT_MAX * 4;
1907 if ((pSpectInfo[j].chNum + 8) ==
1908 pSpectInfo[j + 2].chNum)
1909 pSpectInfo[j + 2].weight =
1910 SAP_ACS_WEIGHT_MAX * 4;
1911 if ((pSpectInfo[j].chNum + 12) ==
1912 pSpectInfo[j + 3].chNum)
1913 pSpectInfo[j + 3].weight =
1914 SAP_ACS_WEIGHT_MAX * 4;
1915 continue;
1916 }
1917 /*found the channel, add the 4 adjacent channels' weight */
1918 acs_ht80_channels[i].weight = pSpectInfo[j].weight +
1919 pSpectInfo[j + 1].weight + pSpectInfo[j + 2].weight +
1920 pSpectInfo[j + 3].weight;
1921 /* find best channel among 4 channels as the primary channel */
1922 if ((pSpectInfo[j].weight + pSpectInfo[j + 1].weight) <
1923 (pSpectInfo[j + 2].weight + pSpectInfo[j + 3].weight)) {
1924 /* lower 2 channels are better choice */
1925 if (pSpectInfo[j].weight < pSpectInfo[j + 1].weight)
1926 minIdx = 0;
1927 else
1928 minIdx = 1;
1929 } else if (pSpectInfo[j + 2].weight <=
1930 pSpectInfo[j + 3].weight) {
1931 /* upper 2 channels are better choice */
1932 minIdx = 2;
1933 } else {
1934 minIdx = 3;
1935 }
1936
1937 /*
1938 * set all 4 channels to max value first, then reset the
1939 * best channel as the selected primary channel, update its
1940 * weightage with the combined weight value
1941 */
1942 for (n = 0; n < 4; n++)
1943 pSpectInfo[j + n].weight = SAP_ACS_WEIGHT_MAX * 4;
1944
1945 pSpectInfo[j + minIdx].weight = acs_ht80_channels[i].weight;
1946 }
1947
bingse2782382017-03-23 10:34:52 +08001948 /*
1949 * mark the weight of the channel that can't satisfy 80MHZ
1950 * as max value, so that it will be sorted to the bottom
1951 */
1952 set_ht80_chl_bit(channel_bitmap, pSpectInfoParams);
1953 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
1954 for (i = 0; i < MAX_80MHZ_BANDS; i++) {
1955 start_channel =
1956 channel_bitmap->chanBondingSet[i].startChannel;
1957 if (pSpectInfo[j].chNum >= start_channel &&
1958 (pSpectInfo[j].chNum <=
1959 start_channel + 12) &&
1960 channel_bitmap->chanBondingSet[i].channelMap !=
1961 SAP_80MHZ_MASK)
1962 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 4;
1963 }
1964 }
1965
Himanshu Agarwal75e74412018-02-01 20:51:47 +05301966 /*
1967 * Assign max weight(SAP_ACS_WEIGHT_MAX * 4) to 2.4 Ghz channels
1968 * and channel 165 as they cannot be part of a 80Mhz channel bonding.
1969 */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001970 pSpectInfo = pSpectInfoParams->pSpectCh;
1971 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
Himanshu Agarwal75e74412018-02-01 20:51:47 +05301972 if ((pSpectInfo[j].chNum >= WLAN_REG_CH_NUM(CHAN_ENUM_1) &&
1973 pSpectInfo[j].chNum <= WLAN_REG_CH_NUM(CHAN_ENUM_14)) ||
1974 (CHANNEL_165 == pSpectInfo[j].chNum))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001975 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 4;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001976 }
1977
Manishekar Chandrasekaran44e334f2016-05-30 16:42:50 +05301978 sap_sort_chl_weight(pSpectInfoParams);
1979
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001980 pSpectInfo = pSpectInfoParams->pSpectCh;
1981 for (j = 0; j < (pSpectInfoParams->numSpectChans); j++) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301982 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001983 FL("Channel=%d Weight= %d rssi=%d bssCount=%d"),
1984 pSpectInfo->chNum, pSpectInfo->weight,
1985 pSpectInfo->rssiAgr, pSpectInfo->bssCount);
1986 pSpectInfo++;
1987 }
bingse2782382017-03-23 10:34:52 +08001988 qdf_mem_free(channel_bitmap);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001989}
1990
1991/**
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001992 * sap_sort_chl_weight_vht160() - to sort the channels with the least weight
1993 * @pSpectInfoParams: Pointer to the tSapChSelSpectInfo structure
1994 *
Jeff Johnsonc7e4d162018-05-12 16:20:34 -07001995 * Function to sort the channels with the least weight first for VHT160 channels
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001996 *
1997 * Return: none
1998 */
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001999static void sap_sort_chl_weight_vht160(tSapChSelSpectInfo *pSpectInfoParams)
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07002000{
2001 uint8_t i, j, n, idx;
2002 tSapSpectChInfo *pSpectInfo;
2003 uint8_t minIdx;
2004
2005 pSpectInfo = pSpectInfoParams->pSpectCh;
2006 /* for each VHT160 channel, calculate the combined weight of the
2007 8 20MHz weight */
2008 for (i = 0; i < ARRAY_SIZE(acs_vht160_channels); i++) {
2009 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
2010 if (pSpectInfo[j].chNum ==
2011 acs_vht160_channels[i].chStartNum)
2012 break;
2013 }
2014 if (j == pSpectInfoParams->numSpectChans)
2015 continue;
2016
2017 if (!(((pSpectInfo[j].chNum + 4) == pSpectInfo[j + 1].chNum) &&
2018 ((pSpectInfo[j].chNum + 8) ==
2019 pSpectInfo[j + 2].chNum) &&
2020 ((pSpectInfo[j].chNum + 12) ==
2021 pSpectInfo[j + 3].chNum) &&
2022 ((pSpectInfo[j].chNum + 16) ==
2023 pSpectInfo[j + 4].chNum) &&
2024 ((pSpectInfo[j].chNum + 20) ==
2025 pSpectInfo[j + 5].chNum) &&
2026 ((pSpectInfo[j].chNum + 24) ==
2027 pSpectInfo[j + 6].chNum) &&
2028 ((pSpectInfo[j].chNum + 28) ==
2029 pSpectInfo[j + 7].chNum))) {
2030 /*
2031 * some channels does not exist in pSectInfo array,
2032 * skip this channel and those in the same VHT160 width
2033 */
2034 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 8;
2035 if ((pSpectInfo[j].chNum + 4) ==
2036 pSpectInfo[j + 1].chNum)
2037 pSpectInfo[j + 1].weight =
2038 SAP_ACS_WEIGHT_MAX * 8;
2039 if ((pSpectInfo[j].chNum + 8) ==
2040 pSpectInfo[j + 2].chNum)
2041 pSpectInfo[j + 2].weight =
2042 SAP_ACS_WEIGHT_MAX * 8;
2043 if ((pSpectInfo[j].chNum + 12) ==
2044 pSpectInfo[j + 3].chNum)
2045 pSpectInfo[j + 3].weight =
2046 SAP_ACS_WEIGHT_MAX * 8;
2047 if ((pSpectInfo[j].chNum + 16) ==
2048 pSpectInfo[j + 4].chNum)
2049 pSpectInfo[j + 4].weight =
2050 SAP_ACS_WEIGHT_MAX * 8;
2051 if ((pSpectInfo[j].chNum + 20) ==
2052 pSpectInfo[j + 5].chNum)
2053 pSpectInfo[j + 5].weight =
2054 SAP_ACS_WEIGHT_MAX * 8;
2055 if ((pSpectInfo[j].chNum + 24) ==
2056 pSpectInfo[j + 6].chNum)
2057 pSpectInfo[j + 6].weight =
2058 SAP_ACS_WEIGHT_MAX * 8;
2059 if ((pSpectInfo[j].chNum + 28) ==
2060 pSpectInfo[j + 7].chNum)
2061 pSpectInfo[j + 7].weight =
2062 SAP_ACS_WEIGHT_MAX * 8;
2063 continue;
2064 }
2065 /*found the channel, add the 7 adjacent channels' weight */
2066 acs_vht160_channels[i].weight = pSpectInfo[j].weight +
2067 pSpectInfo[j + 1].weight + pSpectInfo[j + 2].weight +
2068 pSpectInfo[j + 3].weight + pSpectInfo[j + 4].weight +
2069 pSpectInfo[j + 5].weight + pSpectInfo[j + 6].weight +
2070 pSpectInfo[j + 7].weight;
2071
2072 /* find best channel among 8 channels as the primary channel */
2073 if ((pSpectInfo[j].weight + pSpectInfo[j + 1].weight +
2074 pSpectInfo[j + 2].weight + pSpectInfo[j + 3].weight) >
2075 (pSpectInfo[j + 4].weight + pSpectInfo[j + 5].weight +
2076 pSpectInfo[j + 6].weight + pSpectInfo[j + 7].weight))
2077 idx = 4;
2078 else
2079 idx = 0;
2080 /* find best channel among 4 channels as the primary channel */
2081 if ((pSpectInfo[j + idx].weight +
2082 pSpectInfo[j + idx + 1].weight) <
2083 (pSpectInfo[j + idx + 2].weight +
2084 pSpectInfo[j + idx + 3].weight)) {
2085 /* lower 2 channels are better choice */
2086 if (pSpectInfo[j + idx].weight <
2087 pSpectInfo[j + idx + 1].weight)
2088 minIdx = 0 + idx;
2089 else
2090 minIdx = 1 + idx;
2091 } else if (pSpectInfo[j + idx + 2].weight <=
2092 pSpectInfo[j + idx + 3].weight) {
2093 /* upper 2 channels are better choice */
2094 minIdx = 2 + idx;
2095 } else {
2096 minIdx = 3 + idx;
2097 }
2098
2099 /*
2100 * set all 8 channels to max value first, then reset the
2101 * best channel as the selected primary channel, update its
2102 * weightage with the combined weight value
2103 */
2104 for (n = 0; n < 8; n++)
2105 pSpectInfo[j + n].weight = SAP_ACS_WEIGHT_MAX * 8;
2106
2107 pSpectInfo[j + minIdx].weight = acs_vht160_channels[i].weight;
2108 }
2109
Himanshu Agarwal75e74412018-02-01 20:51:47 +05302110 /*
2111 * Assign max weight(SAP_ACS_WEIGHT_MAX * 8) to 2.4 Ghz channels
2112 * and channel 132-165 as they cannot be part of a 160Mhz channel
2113 * bonding.
2114 */
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07002115 pSpectInfo = pSpectInfoParams->pSpectCh;
2116 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
Himanshu Agarwal75e74412018-02-01 20:51:47 +05302117 if ((pSpectInfo[j].chNum >= WLAN_REG_CH_NUM(CHAN_ENUM_1) &&
2118 pSpectInfo[j].chNum <= WLAN_REG_CH_NUM(CHAN_ENUM_14)) ||
2119 (pSpectInfo[j].chNum >= WLAN_REG_CH_NUM(CHAN_ENUM_132) &&
2120 pSpectInfo[j].chNum <= WLAN_REG_CH_NUM(CHAN_ENUM_165)))
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07002121 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 8;
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07002122 }
2123
Manishekar Chandrasekaran44e334f2016-05-30 16:42:50 +05302124 sap_sort_chl_weight(pSpectInfoParams);
2125
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07002126 pSpectInfo = pSpectInfoParams->pSpectCh;
2127 for (j = 0; j < (pSpectInfoParams->numSpectChans); j++) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302128 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07002129 FL("Channel=%d Weight= %d rssi=%d bssCount=%d"),
2130 pSpectInfo->chNum, pSpectInfo->weight,
2131 pSpectInfo->rssiAgr, pSpectInfo->bssCount);
2132 pSpectInfo++;
2133 }
2134}
2135
2136/**
Himanshu Agarwal91c5c0f2018-02-13 14:40:56 +05302137 * sap_allocate_max_weight_ht40_24_g() - allocate max weight for 40Mhz
2138 * to all 2.4Ghz channels
2139 * @spect_info_params: Pointer to the tSapChSelSpectInfo structure
2140 *
2141 * Return: none
2142 */
2143static void sap_allocate_max_weight_ht40_24_g(
2144 tSapChSelSpectInfo *spect_info_params)
2145{
2146 tSapSpectChInfo *spect_info;
2147 uint8_t j;
2148
2149 /*
2150 * Assign max weight for 40Mhz (SAP_ACS_WEIGHT_MAX * 2) to all
2151 * 2.4 Ghz channels
2152 */
2153 spect_info = spect_info_params->pSpectCh;
2154 for (j = 0; j < spect_info_params->numSpectChans; j++) {
2155 if ((spect_info[j].chNum >= WLAN_REG_CH_NUM(CHAN_ENUM_1) &&
2156 spect_info[j].chNum <= WLAN_REG_CH_NUM(CHAN_ENUM_14)))
2157 spect_info[j].weight = SAP_ACS_WEIGHT_MAX * 2;
2158 }
2159}
2160
2161/**
2162 * sap_allocate_max_weight_ht40_5_g() - allocate max weight for 40Mhz
2163 * to all 5Ghz channels
2164 * @spect_info_params: Pointer to the tSapChSelSpectInfo structure
2165 *
2166 * Return: none
2167 */
2168static void sap_allocate_max_weight_ht40_5_g(
2169 tSapChSelSpectInfo *spect_info_params)
2170{
2171 tSapSpectChInfo *spect_info;
2172 uint8_t j;
2173
2174 /*
2175 * Assign max weight for 40Mhz (SAP_ACS_WEIGHT_MAX * 2) to all
2176 * 5 Ghz channels
2177 */
2178 spect_info = spect_info_params->pSpectCh;
2179 for (j = 0; j < spect_info_params->numSpectChans; j++) {
2180 if ((spect_info[j].chNum >= WLAN_REG_CH_NUM(CHAN_ENUM_36) &&
2181 spect_info[j].chNum <= WLAN_REG_CH_NUM(CHAN_ENUM_165)))
2182 spect_info[j].weight = SAP_ACS_WEIGHT_MAX * 2;
2183 }
2184}
2185
2186/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002187 * sap_sort_chl_weight_ht40_24_g() - to sort channel with the least weight
2188 * @pSpectInfoParams: Pointer to the tSapChSelSpectInfo structure
2189 *
Jeff Johnsonc7e4d162018-05-12 16:20:34 -07002190 * Function to sort the channels with the least weight first for HT40 channels
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002191 *
2192 * Return: none
2193 */
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002194static void sap_sort_chl_weight_ht40_24_g(tSapChSelSpectInfo *pSpectInfoParams,
2195 v_REGDOMAIN_t domain)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002196{
2197 uint8_t i, j;
2198 tSapSpectChInfo *pSpectInfo;
2199 uint32_t tmpWeight1, tmpWeight2;
bingse2782382017-03-23 10:34:52 +08002200 uint32_t ht40plus2gendch = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002201
2202 pSpectInfo = pSpectInfoParams->pSpectCh;
2203 /*
2204 * for each HT40 channel, calculate the combined weight of the
2205 * two 20MHz weight
2206 */
2207 for (i = 0; i < ARRAY_SIZE(acs_ht40_channels24_g); i++) {
2208 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
2209 if (pSpectInfo[j].chNum ==
2210 acs_ht40_channels24_g[i].chStartNum)
2211 break;
2212 }
2213 if (j == pSpectInfoParams->numSpectChans)
2214 continue;
2215
2216 if (!((pSpectInfo[j].chNum + 4) == pSpectInfo[j + 4].chNum)) {
2217 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2;
2218 continue;
2219 }
2220 /*
2221 * check if there is another channel combination possiblity
2222 * e.g., {1, 5} & {5, 9}
2223 */
2224 if ((pSpectInfo[j + 4].chNum + 4) == pSpectInfo[j + 8].chNum) {
2225 /* need to compare two channel pairs */
2226 tmpWeight1 = pSpectInfo[j].weight +
2227 pSpectInfo[j + 4].weight;
2228 tmpWeight2 = pSpectInfo[j + 4].weight +
2229 pSpectInfo[j + 8].weight;
2230 if (tmpWeight1 <= tmpWeight2) {
2231 if (pSpectInfo[j].weight <=
2232 pSpectInfo[j + 4].weight) {
2233 pSpectInfo[j].weight =
2234 tmpWeight1;
2235 pSpectInfo[j + 4].weight =
2236 SAP_ACS_WEIGHT_MAX * 2;
2237 pSpectInfo[j + 8].weight =
2238 SAP_ACS_WEIGHT_MAX * 2;
2239 } else {
2240 pSpectInfo[j + 4].weight =
2241 tmpWeight1;
2242 /* for secondary channel selection */
2243 pSpectInfo[j].weight =
2244 SAP_ACS_WEIGHT_MAX * 2
2245 - 1;
2246 pSpectInfo[j + 8].weight =
2247 SAP_ACS_WEIGHT_MAX * 2;
2248 }
2249 } else {
2250 if (pSpectInfo[j + 4].weight <=
2251 pSpectInfo[j + 8].weight) {
2252 pSpectInfo[j + 4].weight =
2253 tmpWeight2;
2254 pSpectInfo[j].weight =
2255 SAP_ACS_WEIGHT_MAX * 2;
2256 /* for secondary channel selection */
2257 pSpectInfo[j + 8].weight =
2258 SAP_ACS_WEIGHT_MAX * 2
2259 - 1;
2260 } else {
2261 pSpectInfo[j + 8].weight =
2262 tmpWeight2;
2263 pSpectInfo[j].weight =
2264 SAP_ACS_WEIGHT_MAX * 2;
2265 pSpectInfo[j + 4].weight =
2266 SAP_ACS_WEIGHT_MAX * 2;
2267 }
2268 }
2269 } else {
bingsaa6f96a2017-09-11 09:49:43 +08002270 tmpWeight1 = pSpectInfo[j].weight_copy +
2271 pSpectInfo[j + 4].weight_copy;
2272 if (pSpectInfo[j].weight_copy <=
2273 pSpectInfo[j + 4].weight_copy) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002274 pSpectInfo[j].weight = tmpWeight1;
2275 pSpectInfo[j + 4].weight =
2276 SAP_ACS_WEIGHT_MAX * 2;
2277 } else {
2278 pSpectInfo[j + 4].weight = tmpWeight1;
2279 pSpectInfo[j].weight =
2280 SAP_ACS_WEIGHT_MAX * 2;
2281 }
2282 }
2283 }
bingse2782382017-03-23 10:34:52 +08002284 /*
2285 * Every channel should be checked. Add the check for the omissive
2286 * channel. Mark the channel whose combination can't satisfy 40MHZ
2287 * as max value, so that it will be sorted to the bottom.
2288 */
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002289 if (REGDOMAIN_FCC == domain)
bingse2782382017-03-23 10:34:52 +08002290 ht40plus2gendch = HT40PLUS_2G_FCC_CH_END;
2291 else
2292 ht40plus2gendch = HT40PLUS_2G_EURJAP_CH_END;
2293 for (i = HT40MINUS_2G_CH_START; i <= ht40plus2gendch; i++) {
2294 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
2295 if (pSpectInfo[j].chNum == i &&
2296 ((pSpectInfo[j].chNum + 4) !=
2297 pSpectInfo[j+4].chNum) &&
2298 ((pSpectInfo[j].chNum - 4) !=
2299 pSpectInfo[j-4].chNum))
2300 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2;
2301 }
2302 }
2303 for (i = ht40plus2gendch + 1; i <= HT40MINUS_2G_CH_END; i++) {
2304 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
2305 if (pSpectInfo[j].chNum == i &&
2306 (pSpectInfo[j].chNum - 4) !=
2307 pSpectInfo[j-4].chNum)
2308 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2;
2309 }
2310 }
Himanshu Agarwal91c5c0f2018-02-13 14:40:56 +05302311
2312 pSpectInfo = pSpectInfoParams->pSpectCh;
2313 for (j = 0; j < (pSpectInfoParams->numSpectChans); j++) {
2314 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2315 "In %s, Channel=%d Weight= %d rssi=%d bssCount=%d",
2316 __func__, pSpectInfo->chNum, pSpectInfo->weight,
2317 pSpectInfo->rssiAgr, pSpectInfo->bssCount);
2318 pSpectInfo++;
2319 }
2320
Manishekar Chandrasekaran44e334f2016-05-30 16:42:50 +05302321 sap_sort_chl_weight(pSpectInfoParams);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002322}
2323
2324/*==========================================================================
2325 FUNCTION sap_sort_chl_weight_ht40_5_g
2326
2327 DESCRIPTION
Jeff Johnsonc7e4d162018-05-12 16:20:34 -07002328 Function to sort the channels with the least weight first for HT40 channels
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002329
2330 DEPENDENCIES
2331 NA.
2332
2333 PARAMETERS
2334
2335 IN
2336 pSpectInfoParams : Pointer to the tSapChSelSpectInfo structure
2337
2338 RETURN VALUE
2339 void : NULL
2340
2341 SIDE EFFECTS
2342 ============================================================================*/
Jeff Johnson464f7ea2016-10-07 10:21:26 -07002343static void sap_sort_chl_weight_ht40_5_g(tSapChSelSpectInfo *pSpectInfoParams)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002344{
2345 uint8_t i, j;
2346 tSapSpectChInfo *pSpectInfo;
2347
2348 pSpectInfo = pSpectInfoParams->pSpectCh;
2349 /*for each HT40 channel, calculate the combined weight of the
2350 two 20MHz weight */
2351 for (i = 0; i < ARRAY_SIZE(acs_ht40_channels5_g); i++) {
2352 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
2353 if (pSpectInfo[j].chNum ==
2354 acs_ht40_channels5_g[i].chStartNum)
2355 break;
2356 }
2357 if (j == pSpectInfoParams->numSpectChans)
2358 continue;
2359
2360 /* found the channel, add the two adjacent channels' weight */
2361 if ((pSpectInfo[j].chNum + 4) == pSpectInfo[j + 1].chNum) {
2362 acs_ht40_channels5_g[i].weight = pSpectInfo[j].weight +
2363 pSpectInfo[j + 1].weight;
2364 /* select better of the adjact channel as the primary channel */
2365 if (pSpectInfo[j].weight <= pSpectInfo[j + 1].weight) {
2366 pSpectInfo[j].weight =
2367 acs_ht40_channels5_g[i].weight;
2368 /* mark the adjacent channel's weight as max value so
2369 that it will be sorted to the bottom */
2370 pSpectInfo[j + 1].weight =
2371 SAP_ACS_WEIGHT_MAX * 2;
2372 } else {
2373 pSpectInfo[j + 1].weight =
2374 acs_ht40_channels5_g[i].weight;
2375 /* mark the adjacent channel's weight as max value so
2376 that it will be sorted to the bottom */
2377 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2;
2378 }
2379
2380 } else
2381 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2;
2382 }
2383
bingse2782382017-03-23 10:34:52 +08002384 /*
2385 *Every channel should be checked. Add the check for the omissive
2386 * channel. Mark the channel whose combination can't satisfy 40MHZ
2387 * as max value, so that it will be sorted to the bottom
2388 */
2389 for (j = 1; j < pSpectInfoParams->numSpectChans; j++) {
2390 for (i = 0; i < ARRAY_SIZE(acs_ht40_channels5_g); i++) {
2391 if (pSpectInfo[j].chNum ==
2392 (acs_ht40_channels5_g[i].chStartNum +
2393 4) &&
2394 pSpectInfo[j - 1].chNum !=
2395 acs_ht40_channels5_g[i].chStartNum) {
2396 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2;
2397 break;
2398 }
2399 }
2400 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002401 /* avoid channel 165 by setting its weight to max */
2402 pSpectInfo = pSpectInfoParams->pSpectCh;
2403 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
2404 if (CHANNEL_165 == pSpectInfo[j].chNum) {
2405 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2;
2406 break;
2407 }
2408 }
2409
2410 pSpectInfo = pSpectInfoParams->pSpectCh;
2411 for (j = 0; j < (pSpectInfoParams->numSpectChans); j++) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302412 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002413 "In %s, Channel=%d Weight= %d rssi=%d bssCount=%d",
2414 __func__, pSpectInfo->chNum, pSpectInfo->weight,
2415 pSpectInfo->rssiAgr, pSpectInfo->bssCount);
2416 pSpectInfo++;
2417 }
2418
2419 sap_sort_chl_weight(pSpectInfoParams);
2420}
2421
2422/*==========================================================================
2423 FUNCTION sap_sort_chl_weight_all
2424
2425 DESCRIPTION
Jeff Johnsonc7e4d162018-05-12 16:20:34 -07002426 Function to sort the channels with the least weight first
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002427
2428 DEPENDENCIES
2429 NA.
2430
2431 PARAMETERS
2432
2433 IN
Jeff Johnsone13d8062017-09-28 06:54:55 -07002434 sap_ctx : Pointer to the struct sap_context *structure
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002435 pSpectInfoParams : Pointer to the tSapChSelSpectInfo structure
2436
2437 RETURN VALUE
2438 void : NULL
2439
2440 SIDE EFFECTS
2441 ============================================================================*/
Jeff Johnsone13d8062017-09-28 06:54:55 -07002442static void sap_sort_chl_weight_all(struct sap_context *sap_ctx,
Jeff Johnson464f7ea2016-10-07 10:21:26 -07002443 tSapChSelSpectInfo *pSpectInfoParams,
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002444 uint32_t operatingBand,
2445 v_REGDOMAIN_t domain)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002446{
2447 tSapSpectChInfo *pSpectCh = NULL;
2448 uint32_t j = 0;
2449#ifndef SOFTAP_CHANNEL_RANGE
2450 uint32_t i = 0;
2451#endif
2452
2453 pSpectCh = pSpectInfoParams->pSpectCh;
2454#ifdef SOFTAP_CHANNEL_RANGE
2455
Jeff Johnsone13d8062017-09-28 06:54:55 -07002456 switch (sap_ctx->acs_cfg->ch_width) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002457 case CH_WIDTH_40MHZ:
Himanshu Agarwal91c5c0f2018-02-13 14:40:56 +05302458 /*
2459 * Assign max weight to all 5Ghz channels when operating band
2460 * is 11g and to all 2.4Ghz channels when operating band is 11a
2461 * or 11abg to avoid selection in ACS algorithm for starting SAP
2462 */
2463 if (eCSR_DOT11_MODE_11g == operatingBand) {
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002464 sap_sort_chl_weight_ht40_24_g(pSpectInfoParams, domain);
Himanshu Agarwal91c5c0f2018-02-13 14:40:56 +05302465 sap_allocate_max_weight_ht40_5_g(pSpectInfoParams);
2466 } else {
2467 sap_allocate_max_weight_ht40_24_g(pSpectInfoParams);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002468 sap_sort_chl_weight_ht40_5_g(pSpectInfoParams);
2469 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002470 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002471 case CH_WIDTH_80MHZ:
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07002472 case CH_WIDTH_80P80MHZ:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002473 sap_sort_chl_weight_ht80(pSpectInfoParams);
2474 break;
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07002475 case CH_WIDTH_160MHZ:
2476 sap_sort_chl_weight_vht160(pSpectInfoParams);
2477 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002478 case CH_WIDTH_20MHZ:
2479 default:
2480 /* Sorting the channels as per weights as 20MHz channels */
2481 sap_sort_chl_weight(pSpectInfoParams);
2482 }
2483
2484#else
2485 /* Sorting the channels as per weights */
2486 for (i = 0; i < SPECT_24GHZ_CH_COUNT; i++) {
2487 minWeightIndex = i;
2488 for (j = i + 1; j < SPECT_24GHZ_CH_COUNT; j++) {
2489 if (pSpectCh[j].weight <
2490 pSpectCh[minWeightIndex].weight) {
2491 minWeightIndex = j;
2492 }
2493 }
2494 if (minWeightIndex != i) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302495 qdf_mem_copy(&temp, &pSpectCh[minWeightIndex],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002496 sizeof(*pSpectCh));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302497 qdf_mem_copy(&pSpectCh[minWeightIndex], &pSpectCh[i],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002498 sizeof(*pSpectCh));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302499 qdf_mem_copy(&pSpectCh[i], &temp, sizeof(*pSpectCh));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002500 }
2501 }
2502#endif
2503
2504 /* For testing */
Ravi Joshi9788fcd2018-02-13 15:12:22 -08002505 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002506 "In %s, Sorted Spectrum Channels Weight", __func__);
2507 pSpectCh = pSpectInfoParams->pSpectCh;
2508 for (j = 0; j < (pSpectInfoParams->numSpectChans); j++) {
Ravi Joshi9788fcd2018-02-13 15:12:22 -08002509 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002510 "In %s, Channel=%d Weight= %d rssi=%d bssCount=%d",
2511 __func__, pSpectCh->chNum, pSpectCh->weight,
2512 pSpectCh->rssiAgr, pSpectCh->bssCount);
2513 pSpectCh++;
2514 }
2515
2516}
2517
Naveen Rawatbec64d92017-09-13 14:35:21 -07002518/**
2519 * sap_is_ch_non_overlap() - returns true if non-overlapping channel
2520 * @sap_ctx: Sap context
2521 * @ch: channel number
2522 *
2523 * Returns: true if non-overlapping (1, 6, 11) channel, false otherwise
2524 */
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -07002525static bool sap_is_ch_non_overlap(struct sap_context *sap_ctx, uint16_t ch)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002526{
Naveen Rawatbec64d92017-09-13 14:35:21 -07002527 if (sap_ctx->enableOverLapCh)
Srinivas Girigowda74a66d62017-06-21 23:28:25 -07002528 return true;
Naveen Rawatbec64d92017-09-13 14:35:21 -07002529
2530 if ((ch == CHANNEL_1) || (ch == CHANNEL_6) || (ch == CHANNEL_11))
Srinivas Girigowda74a66d62017-06-21 23:28:25 -07002531 return true;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002532
Srinivas Girigowda74a66d62017-06-21 23:28:25 -07002533 return false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002534}
2535
Dustin Brown0ce56d32016-10-17 16:18:03 -07002536#ifdef FEATURE_WLAN_CH_AVOID
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002537/**
2538 * sap_select_channel_no_scan_result() - select SAP channel when no scan results
2539 * are available.
2540 * @sap_ctx: Sap context
2541 *
2542 * Returns: channel number if success, 0 otherwise
2543 */
Kondabattini, Ganesh13bb4b12016-09-04 16:16:53 +05302544static uint8_t sap_select_channel_no_scan_result(tHalHandle hal,
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -07002545 struct sap_context *sap_ctx)
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002546{
Mohit Khanna841044f2016-03-25 16:16:24 -07002547 enum channel_state ch_type;
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002548 uint8_t i, first_safe_ch_in_range = SAP_CHANNEL_NOT_SELECTED;
Kondabattini, Ganesh13bb4b12016-09-04 16:16:53 +05302549 uint32_t dfs_master_cap_enabled;
Dustin Brown0ce56d32016-10-17 16:18:03 -07002550 uint32_t start_ch_num = sap_ctx->acs_cfg->start_ch;
2551 uint32_t end_ch_num = sap_ctx->acs_cfg->end_ch;
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002552 tpAniSirGlobal mac_ctx = NULL;
2553
2554 mac_ctx = PMAC_STRUCT(hal);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002555
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002556 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2557 FL("start - end: %d - %d"), start_ch_num, end_ch_num);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002558
Kondabattini, Ganesh13bb4b12016-09-04 16:16:53 +05302559 sme_cfg_get_int(hal, WNI_CFG_DFS_MASTER_ENABLED,
2560 &dfs_master_cap_enabled);
2561
2562 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2563 "%s: dfs_master %x", __func__, dfs_master_cap_enabled);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002564
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002565 /* get a channel in PCL and within the range */
2566 for (i = 0; i < sap_ctx->acs_cfg->pcl_ch_count; i++) {
2567 if ((sap_ctx->acs_cfg->pcl_channels[i] < start_ch_num) ||
2568 (sap_ctx->acs_cfg->pcl_channels[i] > end_ch_num))
2569 continue;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002570
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002571 first_safe_ch_in_range = sap_ctx->acs_cfg->pcl_channels[i];
2572 break;
2573 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002574
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002575 if (SAP_CHANNEL_NOT_SELECTED != first_safe_ch_in_range)
2576 return first_safe_ch_in_range;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002577
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002578 for (i = 0; i < NUM_CHANNELS; i++) {
2579 if ((safe_channels[i].channelNumber < start_ch_num) ||
2580 (safe_channels[i].channelNumber > end_ch_num))
2581 continue;
2582
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002583 ch_type = wlan_reg_get_channel_state(mac_ctx->pdev,
2584 safe_channels[i].channelNumber);
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002585
2586 if ((ch_type == CHANNEL_STATE_DISABLE) ||
2587 (ch_type == CHANNEL_STATE_INVALID))
2588 continue;
Kondabattini, Ganesh13bb4b12016-09-04 16:16:53 +05302589 if ((!dfs_master_cap_enabled) &&
2590 (CHANNEL_STATE_DFS == ch_type)) {
2591 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2592 "%s: DFS master mode disabled. Skip DFS channel %d",
2593 __func__, safe_channels[i].channelNumber);
2594 continue;
2595 }
Agrawal Ashish65634612016-08-18 13:24:32 +05302596 if ((sap_ctx->dfs_mode == ACS_DFS_MODE_DISABLE) &&
2597 (CHANNEL_STATE_DFS == ch_type))
2598 continue;
Kondabattini, Ganesh13bb4b12016-09-04 16:16:53 +05302599
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002600 if (safe_channels[i].isSafe == true) {
2601 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2602 FL("channel %d in the configuration is safe"),
2603 safe_channels[i].channelNumber);
2604 first_safe_ch_in_range = safe_channels[i].channelNumber;
2605 break;
2606 }
2607
2608 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2609 FL("channel %d in the configuration is unsafe"),
2610 safe_channels[i].channelNumber);
2611 }
2612
2613 /* if no channel selected return SAP_CHANNEL_NOT_SELECTED */
2614 return first_safe_ch_in_range;
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002615}
Dustin Brown0ce56d32016-10-17 16:18:03 -07002616#else
2617static uint8_t sap_select_channel_no_scan_result(tHalHandle hal,
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -07002618 struct sap_context *sap_ctx)
Dustin Brown0ce56d32016-10-17 16:18:03 -07002619{
2620 uint32_t start_ch_num = sap_ctx->acs_cfg->start_ch;
2621
2622 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2623 FL("start - end: %d - %d"),
2624 start_ch_num,
2625 sap_ctx->acs_cfg->end_ch);
2626
2627 sap_ctx->acs_cfg->pri_ch = start_ch_num;
2628 sap_ctx->acs_cfg->ht_sec_ch = 0;
2629
2630 /* pick the first channel in configured range */
2631 return start_ch_num;
2632}
2633#endif /* FEATURE_WLAN_CH_AVOID */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002634
2635/**
2636 * sap_select_channel() - select SAP channel
2637 * @hal: Pointer to HAL handle
2638 * @sap_ctx: Sap context
2639 * @scan_result: Pointer to tScanResultHandle
2640 *
2641 * Runs a algorithm to select the best channel to operate in based on BSS
2642 * rssi and bss count on each channel
2643 *
2644 * Returns: channel number if success, 0 otherwise
2645 */
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -07002646uint8_t sap_select_channel(tHalHandle hal, struct sap_context *sap_ctx,
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002647 tScanResultHandle scan_result)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002648{
2649 /* DFS param object holding all the data req by the algo */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002650 tSapChSelSpectInfo spect_info_obj = { NULL, 0 };
2651 tSapChSelSpectInfo *spect_info = &spect_info_obj;
2652 uint8_t best_ch_num = SAP_CHANNEL_NOT_SELECTED;
bingse2782382017-03-23 10:34:52 +08002653 uint32_t ht40plus2gendch = 0;
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002654 v_REGDOMAIN_t domain;
Arif Hussain21ad4342017-12-21 12:00:54 -08002655 uint8_t country[CDS_COUNTRY_CODE_LEN + 1];
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002656#ifdef SOFTAP_CHANNEL_RANGE
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002657 uint8_t count;
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002658 uint32_t start_ch_num, end_ch_num, tmp_ch_num, operating_band = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002659#endif
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002660 tpAniSirGlobal mac_ctx;
2661
2662 mac_ctx = PMAC_STRUCT(hal);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302663 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002664 "In %s, Running SAP Ch Select", __func__);
2665
2666#ifdef FEATURE_WLAN_CH_AVOID
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002667 sap_update_unsafe_channel_list(hal, sap_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002668#endif
2669
gaoleze5108942017-03-31 16:56:42 +08002670 /*
2671 * If ACS weight is not enabled on noise_floor/channel_free/tx_power,
2672 * then skip acs process if no bss found.
2673 */
2674 if (NULL == scan_result &&
2675 !(sap_ctx->auto_channel_select_weight & 0xffff00)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302676 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002677 FL("No external AP present"));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002678
2679#ifndef SOFTAP_CHANNEL_RANGE
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002680 return SAP_CHANNEL_NOT_SELECTED;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002681#else
Kondabattini, Ganesh13bb4b12016-09-04 16:16:53 +05302682 return sap_select_channel_no_scan_result(hal, sap_ctx);
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002683#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002684 }
2685
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002686 /* Initialize the structure pointed by spect_info */
Srinivas Girigowda74a66d62017-06-21 23:28:25 -07002687 if (sap_chan_sel_init(hal, spect_info, sap_ctx) != true) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302688 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002689 FL("Ch Select initialization failed"));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002690 return SAP_CHANNEL_NOT_SELECTED;
2691 }
2692 /* Compute the weight of the entire spectrum in the operating band */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002693 sap_compute_spect_weight(spect_info, hal, scan_result, sap_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002694
2695#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
2696 /* process avoid channel IE to collect all channels to avoid */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002697 sap_process_avoid_ie(hal, sap_ctx, scan_result, spect_info);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002698#endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
2699
Paul Zhang0f85b412018-01-18 19:14:51 +08002700 wlan_reg_read_current_country(mac_ctx->psoc, country);
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002701 wlan_reg_get_domain_from_country_code(&domain, country, SOURCE_DRIVER);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002702#ifdef SOFTAP_CHANNEL_RANGE
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002703 start_ch_num = sap_ctx->acs_cfg->start_ch;
2704 end_ch_num = sap_ctx->acs_cfg->end_ch;
2705 SET_ACS_BAND(operating_band, sap_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002706
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002707 sap_ctx->acsBestChannelInfo.channelNum = 0;
2708 sap_ctx->acsBestChannelInfo.weight = SAP_ACS_WEIGHT_MAX;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002709
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002710 /* Sort the ch lst as per the computed weights, lesser weight first. */
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002711 sap_sort_chl_weight_all(sap_ctx, spect_info, operating_band, domain);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002712
2713 /*Loop till get the best channel in the given range */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002714 for (count = 0; count < spect_info->numSpectChans; count++) {
2715 if ((start_ch_num > spect_info->pSpectCh[count].chNum) ||
2716 (end_ch_num < spect_info->pSpectCh[count].chNum))
2717 continue;
2718
2719 if (best_ch_num == SAP_CHANNEL_NOT_SELECTED) {
2720 best_ch_num = spect_info->pSpectCh[count].chNum;
2721 /* check if best_ch_num is in preferred channel list */
2722 best_ch_num =
2723 sap_select_preferred_channel_from_channel_list(
2724 best_ch_num, sap_ctx, spect_info);
2725 /* if not in preferred ch lst, go to nxt best ch */
2726 if (best_ch_num == SAP_CHANNEL_NOT_SELECTED)
2727 continue;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002728
2729#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002730 /*
2731 * Weight of the channels(device's AP is operating)
Jeff Johnson2cc31fd2018-05-05 23:54:23 -07002732 * increased to MAX+1 so that they will be chosen only
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002733 * when there is no other best channel to choose
2734 */
2735 if (sap_check_in_avoid_ch_list(sap_ctx, best_ch_num)) {
2736 best_ch_num = SAP_CHANNEL_NOT_SELECTED;
2737 continue;
2738 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002739#endif
2740
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002741 sap_ctx->acsBestChannelInfo.channelNum = best_ch_num;
2742 sap_ctx->acsBestChannelInfo.weight =
2743 spect_info->pSpectCh[count].weight_copy;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002744 }
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002745
2746 if (best_ch_num == SAP_CHANNEL_NOT_SELECTED)
2747 continue;
2748
Tushnim Bhattacharyya03103fd2017-06-23 10:48:52 -07002749 if (operating_band != eCSR_DOT11_MODE_11g) {
2750 QDF_TRACE(QDF_MODULE_ID_SAP,
2751 QDF_TRACE_LEVEL_INFO_HIGH,
2752 "operating_band %d", operating_band);
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002753 continue;
Tushnim Bhattacharyya03103fd2017-06-23 10:48:52 -07002754 }
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002755
2756 /* Give preference to Non-overlap channels */
Naveen Rawatbec64d92017-09-13 14:35:21 -07002757 if (false == sap_is_ch_non_overlap(sap_ctx,
Tushnim Bhattacharyya03103fd2017-06-23 10:48:52 -07002758 spect_info->pSpectCh[count].chNum)) {
2759 QDF_TRACE(QDF_MODULE_ID_SAP,
2760 QDF_TRACE_LEVEL_INFO_HIGH,
Naveen Rawatbec64d92017-09-13 14:35:21 -07002761 FL("ch: %d skipped as its overlapping ch"),
2762 spect_info->pSpectCh[count].chNum);
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002763 continue;
Tushnim Bhattacharyya03103fd2017-06-23 10:48:52 -07002764 }
2765
2766 if (wlan_reg_is_dfs_ch(mac_ctx->pdev,
2767 spect_info->pSpectCh[count].chNum) &&
2768 policy_mgr_disallow_mcc(mac_ctx->psoc,
2769 spect_info->pSpectCh[count].chNum)) {
2770 QDF_TRACE(QDF_MODULE_ID_SAP,
2771 QDF_TRACE_LEVEL_INFO_HIGH,
2772 "No DFS MCC");
2773 continue;
2774 }
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002775
bings14d1d3b2017-08-03 11:14:29 +08002776 if (spect_info->pSpectCh[count].weight_copy >
2777 sap_ctx->acsBestChannelInfo.weight)
2778 continue;
2779
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002780 tmp_ch_num = spect_info->pSpectCh[count].chNum;
gaoleze5108942017-03-31 16:56:42 +08002781 tmp_ch_num = sap_channel_in_acs_channel_list(
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002782 tmp_ch_num, sap_ctx, spect_info);
2783 if (tmp_ch_num == SAP_CHANNEL_NOT_SELECTED)
2784 continue;
2785
2786 best_ch_num = tmp_ch_num;
2787 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002788 }
2789#else
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002790 /* Sort the ch lst as per the computed weights, lesser weight first. */
2791 sap_sort_chl_weight_all(sap_ctx, hal, spect_info);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002792 /* Get the first channel in sorted array as best 20M Channel */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002793 best_ch_num = (uint8_t) spect_info->pSpectCh[0].chNum;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002794 /* Select Best Channel from Channel List if Configured */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002795 best_ch_num = sap_select_preferred_channel_from_channel_list(
2796 best_ch_num, sap_ctx, spect_info);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002797#endif
2798
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002799 /*
2800 * in case the best channel seleted is not in PCL and there is another
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002801 * channel which has same weightage and is in PCL, choose the one in
2802 * PCL
2803 */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002804 for (count = 0; count < spect_info->numSpectChans; count++) {
2805 if (!ch_in_pcl(sap_ctx, spect_info->pSpectCh[count].chNum) ||
2806 (spect_info->pSpectCh[count].weight !=
2807 sap_ctx->acsBestChannelInfo.weight))
2808 continue;
2809
2810 if (sap_select_preferred_channel_from_channel_list(
2811 spect_info->pSpectCh[count].chNum, sap_ctx, spect_info)
2812 == SAP_CHANNEL_NOT_SELECTED)
2813 continue;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002814
2815#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002816 if (sap_check_in_avoid_ch_list(sap_ctx, best_ch_num))
2817 continue;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002818#endif
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002819 best_ch_num = spect_info->pSpectCh[count].chNum;
2820 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2821 FL("change best channel to %d in PCL"), best_ch_num);
2822 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002823 }
2824
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002825 sap_ctx->acs_cfg->pri_ch = best_ch_num;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002826 /* determine secondary channel for 2.4G channel 5, 6, 7 in HT40 */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002827 if ((operating_band != eCSR_DOT11_MODE_11g) ||
2828 (sap_ctx->acs_cfg->ch_width != CH_WIDTH_40MHZ))
2829 goto sap_ch_sel_end;
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002830 if (REGDOMAIN_FCC == domain)
bingse2782382017-03-23 10:34:52 +08002831 ht40plus2gendch = HT40PLUS_2G_FCC_CH_END;
2832 else
2833 ht40plus2gendch = HT40PLUS_2G_EURJAP_CH_END;
2834 if ((best_ch_num >= HT40MINUS_2G_CH_START) &&
2835 (best_ch_num <= ht40plus2gendch)) {
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002836 int weight_below, weight_above, i;
2837 tSapSpectChInfo *pspect_info;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002838
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002839 weight_below = weight_above = SAP_ACS_WEIGHT_MAX;
2840 pspect_info = spect_info->pSpectCh;
2841 for (i = 0; i < spect_info->numSpectChans; i++) {
2842 if (pspect_info[i].chNum == (best_ch_num - 4))
2843 weight_below = pspect_info[i].weight;
2844 if (pspect_info[i].chNum == (best_ch_num + 4))
2845 weight_above = pspect_info[i].weight;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002846 }
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002847
2848 if (weight_below < weight_above)
2849 sap_ctx->acs_cfg->ht_sec_ch =
2850 sap_ctx->acs_cfg->pri_ch - 4;
2851 else
2852 sap_ctx->acs_cfg->ht_sec_ch =
2853 sap_ctx->acs_cfg->pri_ch + 4;
2854 } else if (best_ch_num >= 1 && best_ch_num <= 4) {
2855 sap_ctx->acs_cfg->ht_sec_ch = sap_ctx->acs_cfg->pri_ch + 4;
bingse2782382017-03-23 10:34:52 +08002856 } else if (best_ch_num >= ht40plus2gendch && best_ch_num <=
2857 HT40MINUS_2G_CH_END) {
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002858 sap_ctx->acs_cfg->ht_sec_ch = sap_ctx->acs_cfg->pri_ch - 4;
2859 } else if (best_ch_num == 14) {
2860 sap_ctx->acs_cfg->ht_sec_ch = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002861 }
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002862 sap_ctx->secondary_ch = sap_ctx->acs_cfg->ht_sec_ch;
2863
2864sap_ch_sel_end:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002865 /* Free all the allocated memory */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002866 sap_chan_sel_exit(spect_info);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002867
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302868 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002869 FL("Running SAP Ch select Completed, Ch=%d"), best_ch_num);
wadesongcb0ded22018-02-02 17:57:20 +08002870 host_log_acs_best_chan(best_ch_num, sap_ctx->acsBestChannelInfo.weight);
2871
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002872 if (best_ch_num > 0 && best_ch_num <= 252)
2873 return best_ch_num;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002874 else
2875 return SAP_CHANNEL_NOT_SELECTED;
2876}