blob: 16f780d72e2f0eb95a66ebdfe951380cf7f4adbe [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},
Kiran Kumar Lokere1a43bcf2018-05-15 15:51:58 -0700160 {169, true},
161 {173, true},
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800162};
163#endif
164
165typedef struct {
166 uint16_t chStartNum;
167 uint32_t weight;
168} sapAcsChannelInfo;
169
170sapAcsChannelInfo acs_ht40_channels5_g[] = {
171 {36, SAP_ACS_WEIGHT_MAX},
172 {44, SAP_ACS_WEIGHT_MAX},
173 {52, SAP_ACS_WEIGHT_MAX},
174 {60, SAP_ACS_WEIGHT_MAX},
175 {100, SAP_ACS_WEIGHT_MAX},
176 {108, SAP_ACS_WEIGHT_MAX},
177 {116, SAP_ACS_WEIGHT_MAX},
178 {124, SAP_ACS_WEIGHT_MAX},
179 {132, SAP_ACS_WEIGHT_MAX},
180 {140, SAP_ACS_WEIGHT_MAX},
181 {149, SAP_ACS_WEIGHT_MAX},
182 {157, SAP_ACS_WEIGHT_MAX},
183};
184
185sapAcsChannelInfo acs_ht80_channels[] = {
186 {36, SAP_ACS_WEIGHT_MAX},
187 {52, SAP_ACS_WEIGHT_MAX},
188 {100, SAP_ACS_WEIGHT_MAX},
189 {116, SAP_ACS_WEIGHT_MAX},
190 {132, SAP_ACS_WEIGHT_MAX},
191 {149, SAP_ACS_WEIGHT_MAX},
192};
193
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -0700194sapAcsChannelInfo acs_vht160_channels[] = {
195 {36, SAP_ACS_WEIGHT_MAX},
196 {100, SAP_ACS_WEIGHT_MAX},
197};
198
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800199sapAcsChannelInfo acs_ht40_channels24_g[] = {
200 {1, SAP_ACS_WEIGHT_MAX},
201 {2, SAP_ACS_WEIGHT_MAX},
202 {3, SAP_ACS_WEIGHT_MAX},
203 {4, SAP_ACS_WEIGHT_MAX},
204 {9, SAP_ACS_WEIGHT_MAX},
205};
206
207#define CHANNEL_165 165
208
209/* rssi discount for channels in PCL */
210#define PCL_RSSI_DISCOUNT 10
211
212#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
213/**
214 * sap_check_n_add_channel() - checks and add given channel in sap context's
215 * avoid_channels_info struct
216 * @sap_ctx: sap context.
217 * @new_channel: channel to be added to sap_ctx's avoid ch info
218 *
219 * sap_ctx contains sap_avoid_ch_info strcut containing the list of channels on
220 * which MDM device's AP with MCC was detected. This function will add channels
221 * to that list after checking for duplicates.
222 *
223 * Return: true: if channel was added or already present
224 * else false: if channel list was already full.
225 */
Tang Yingying523322d2017-01-17 23:28:43 +0800226static bool
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -0700227sap_check_n_add_channel(struct sap_context *sap_ctx,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800228 uint8_t new_channel)
229{
230 uint8_t i = 0;
231 struct sap_avoid_channels_info *ie_info =
232 &sap_ctx->sap_detected_avoid_ch_ie;
233
234 for (i = 0; i < sizeof(ie_info->channels); i++) {
235 if (ie_info->channels[i] == new_channel)
236 break;
237
238 if (ie_info->channels[i] == 0) {
239 ie_info->channels[i] = new_channel;
240 break;
241 }
242 }
243 if (i == sizeof(ie_info->channels))
244 return false;
245 else
246 return true;
247}
248/**
249 * sap_check_n_add_overlapped_chnls() - checks & add overlapped channels
250 * to primary channel in 2.4Ghz band.
251 * @sap_ctx: sap context.
252 * @primary_chnl: primary channel to be avoided.
253 *
254 * sap_ctx contains sap_avoid_ch_info struct containing the list of channels on
255 * which MDM device's AP with MCC was detected. This function will add channels
256 * to that list after checking for duplicates.
257 *
258 * Return: true: if channel was added or already present
259 * else false: if channel list was already full.
260 */
261static bool
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -0700262sap_check_n_add_overlapped_chnls(struct sap_context *sap_ctx,
263 uint8_t primary_channel)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800264{
265 uint8_t i = 0, j = 0, upper_chnl = 0, lower_chnl = 0;
266 struct sap_avoid_channels_info *ie_info =
267 &sap_ctx->sap_detected_avoid_ch_ie;
268 /*
269 * if primary channel less than channel 1 or out of 2g band then
270 * no further process is required. return true in this case.
271 */
272 if (primary_channel < CHANNEL_1 || primary_channel > CHANNEL_14)
273 return true;
274
275 /* lower channel is one channel right before primary channel */
276 lower_chnl = primary_channel - 1;
277 /* upper channel is one channel right after primary channel */
278 upper_chnl = primary_channel + 1;
279
280 /* lower channel needs to be non-zero, zero is not valid channel */
281 if (lower_chnl > (CHANNEL_1 - 1)) {
282 for (i = 0; i < sizeof(ie_info->channels); i++) {
283 if (ie_info->channels[i] == lower_chnl)
284 break;
285 if (ie_info->channels[i] == 0) {
286 ie_info->channels[i] = lower_chnl;
287 break;
288 }
289 }
290 }
291 /* upper channel needs to be atleast last channel in 2.4Ghz band */
292 if (upper_chnl < (CHANNEL_14 + 1)) {
293 for (j = 0; j < sizeof(ie_info->channels); j++) {
294 if (ie_info->channels[j] == upper_chnl)
295 break;
296 if (ie_info->channels[j] == 0) {
297 ie_info->channels[j] = upper_chnl;
298 break;
299 }
300 }
301 }
302 if (i == sizeof(ie_info->channels) || j == sizeof(ie_info->channels))
303 return false;
304 else
305 return true;
306}
307
308/**
309 * sap_process_avoid_ie() - processes the detected Q2Q IE
310 * context's avoid_channels_info struct
311 * @hal: hal handle
312 * @sap_ctx: sap context.
313 * @scan_result: scan results for ACS scan.
314 * @spect_info: spectrum weights array to update
315 *
316 * Detection of Q2Q IE indicates presence of another MDM device with its AP
317 * operating in MCC mode. This function parses the scan results and processes
318 * the Q2Q IE if found. It then extracts the channels and populates them in
319 * sap_ctx struct. It also increases the weights of those channels so that
320 * ACS logic will avoid those channels in its selection algorithm.
321 *
322 * Return: void
323 */
Tang Yingying523322d2017-01-17 23:28:43 +0800324static void sap_process_avoid_ie(tHalHandle hal,
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -0700325 struct sap_context *sap_ctx,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800326 tScanResultHandle scan_result,
327 tSapChSelSpectInfo *spect_info)
328{
329 uint32_t total_ie_len = 0;
330 uint8_t *temp_ptr = NULL;
331 uint8_t i = 0;
332 struct sAvoidChannelIE *avoid_ch_ie;
333 tCsrScanResultInfo *node = NULL;
334 tpAniSirGlobal mac_ctx = NULL;
335 tSapSpectChInfo *spect_ch = NULL;
336
337 mac_ctx = PMAC_STRUCT(hal);
338 spect_ch = spect_info->pSpectCh;
339 node = sme_scan_result_get_first(hal, scan_result);
340
341 while (node) {
Abhishek Singh34a4d862016-10-26 16:01:51 +0530342 total_ie_len =
Jeff Johnson38e38a82017-10-06 10:32:31 -0700343 GET_IE_LEN_IN_BSS(node->BssDescriptor.length);
Naveen Rawat08db88f2017-09-08 15:07:48 -0700344 temp_ptr = wlan_get_vendor_ie_ptr_from_oui(
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800345 SIR_MAC_QCOM_VENDOR_OUI,
346 SIR_MAC_QCOM_VENDOR_SIZE,
347 ((uint8_t *)&node->BssDescriptor.ieFields),
348 total_ie_len);
349
350 if (temp_ptr) {
351 avoid_ch_ie = (struct sAvoidChannelIE *)temp_ptr;
Will Huang55ba1042017-03-22 10:43:30 +0800352 if (avoid_ch_ie->type !=
353 QCOM_VENDOR_IE_MCC_AVOID_CH) {
354 node = sme_scan_result_get_next(hal,
355 scan_result);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800356 continue;
Will Huang55ba1042017-03-22 10:43:30 +0800357 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800358
359 sap_ctx->sap_detected_avoid_ch_ie.present = 1;
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530360 QDF_TRACE(QDF_MODULE_ID_SAP,
361 QDF_TRACE_LEVEL_DEBUG,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800362 "Q2Q IE - avoid ch %d",
363 avoid_ch_ie->channel);
364 /* add this channel to to_avoid channel list */
365 sap_check_n_add_channel(sap_ctx,
366 avoid_ch_ie->channel);
367 sap_check_n_add_overlapped_chnls(sap_ctx,
368 avoid_ch_ie->channel);
369 /*
370 * Mark weight of these channel present in IE to MAX
371 * so that ACS logic will to avoid thse channels
372 */
373 for (i = 0; i < spect_info->numSpectChans; i++)
374 if (spect_ch[i].chNum == avoid_ch_ie->channel) {
375 /*
376 * weight is set more than max so that,
377 * in the case of other channels being
378 * assigned max weight due to noise,
379 * they may be preferred over channels
380 * with Q2Q IE.
381 */
382 spect_ch[i].weight = SAP_ACS_WEIGHT_MAX + 1;
383 spect_ch[i].weight_copy =
384 SAP_ACS_WEIGHT_MAX + 1;
385 break;
386 }
387 } /* if (temp_ptr) */
388 node = sme_scan_result_get_next(hal, scan_result);
389 }
390}
391#endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
392
393#ifdef FEATURE_WLAN_CH_AVOID
394/*==========================================================================
395 FUNCTION sap_update_unsafe_channel_list
396
397 DESCRIPTION
398 Function Undate unsafe channel list table
399
400 DEPENDENCIES
401 NA.
402
403 IN
404 SapContext pointer
405
406 RETURN VALUE
407 NULL
408 ============================================================================*/
Jeff Johnsone13d8062017-09-28 06:54:55 -0700409void sap_update_unsafe_channel_list(tHalHandle hal, struct sap_context *sap_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800410{
411 uint16_t i, j;
Amar Singhalb8d4f152016-02-10 10:21:43 -0800412 uint16_t unsafe_channel_list[NUM_CHANNELS];
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800413 uint16_t unsafe_channel_count = 0;
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -0700414 tpAniSirGlobal mac_ctx = NULL;
415
Yuanyuan Liu0e0aa932016-05-12 10:17:58 -0700416 qdf_device_t qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800417
Yuanyuan Liu97361182016-06-06 09:38:04 -0700418 if (!qdf_ctx) {
419 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_FATAL,
420 "qdf_ctx is NULL");
421 return;
422 }
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -0700423 mac_ctx = PMAC_STRUCT(hal);
Yuanyuan Liu97361182016-06-06 09:38:04 -0700424
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800425 /* Flush, default set all channel safe */
Amar Singhalb8d4f152016-02-10 10:21:43 -0800426 for (i = 0; i < NUM_CHANNELS; i++) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800427 safe_channels[i].isSafe = true;
428 }
429
430 /* Try to find unsafe channel */
Ryan Hsu4252a2f2016-01-05 11:18:24 -0800431#if defined(FEATURE_WLAN_STA_AP_MODE_DFS_DISABLE)
Amar Singhalb8d4f152016-02-10 10:21:43 -0800432 for (i = 0; i < NUM_CHANNELS; i++) {
Jeff Johnsone13d8062017-09-28 06:54:55 -0700433 if (sap_ctx->dfs_ch_disable == true) {
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -0700434 if (wlan_reg_is_dfs_ch(mac_ctx->pdev,
435 safe_channels[i].channelNumber)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800436 safe_channels[i].isSafe = false;
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530437 QDF_TRACE(QDF_MODULE_ID_SAP,
438 QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800439 "%s: DFS Ch %d is not safe in"
440 " Concurrent mode",
441 __func__,
442 safe_channels[i].channelNumber);
443 }
444 }
445 }
446#endif
Yuanyuan Liu0e0aa932016-05-12 10:17:58 -0700447 pld_get_wlan_unsafe_channel(qdf_ctx->dev,
448 unsafe_channel_list,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800449 &unsafe_channel_count,
450 sizeof(unsafe_channel_list));
451
452 for (i = 0; i < unsafe_channel_count; i++) {
Amar Singhalb8d4f152016-02-10 10:21:43 -0800453 for (j = 0; j < NUM_CHANNELS; j++) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800454 if (safe_channels[j].channelNumber ==
455 unsafe_channel_list[i]) {
456 /* Found unsafe channel, update it */
457 safe_channels[j].isSafe = false;
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530458 QDF_TRACE(QDF_MODULE_ID_SAP,
459 QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800460 FL("CH %d is not safe"),
461 unsafe_channel_list[i]);
462 break;
463 }
464 }
465 }
466
467 return;
468}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800469
470#endif /* FEATURE_WLAN_CH_AVOID */
471
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800472/**
gaoleze5108942017-03-31 16:56:42 +0800473 * sap_channel_in_acs_channel_list() - check if channel in acs channel list
474 * @channel_num: channel to check
475 * @sap_ctx: struct ptSapContext
476 * @spect_info_params: strcut tSapChSelSpectInfo
477 *
478 * This function checks if specified channel is in the configured ACS channel
479 * list.
480 *
481 * Return: channel number if in acs channel list or SAP_CHANNEL_NOT_SELECTED
482 */
gaoleze5108942017-03-31 16:56:42 +0800483uint8_t sap_channel_in_acs_channel_list(uint8_t channel_num,
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -0700484 struct sap_context *sap_ctx,
gaoleze5108942017-03-31 16:56:42 +0800485 tSapChSelSpectInfo *spect_info_params)
486{
487 uint8_t i = 0;
488
489 if ((NULL == sap_ctx->acs_cfg->ch_list) ||
490 (NULL == spect_info_params))
491 return channel_num;
492
493 if (channel_num > 0 && channel_num <= 252) {
494 for (i = 0; i < sap_ctx->acs_cfg->ch_list_count; i++) {
495 if ((sap_ctx->acs_cfg->ch_list[i]) == channel_num)
496 return channel_num;
497 }
498 return SAP_CHANNEL_NOT_SELECTED;
499 } else {
500 return SAP_CHANNEL_NOT_SELECTED;
501 }
502}
503
504/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800505 * sap_select_preferred_channel_from_channel_list() - to calc best cahnnel
506 * @best_chnl: best channel already calculated among all the chanels
507 * @sap_ctx: sap context
508 * @spectinfo_param: Pointer to tSapChSelSpectInfo structure
509 *
510 * This function calculates the best channel among the configured channel list.
511 * If channel list not configured then returns the best channel calculated
512 * among all the channel list.
513 *
514 * Return: uint8_t best channel
515 */
Jeff Johnson464f7ea2016-10-07 10:21:26 -0700516static
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800517uint8_t sap_select_preferred_channel_from_channel_list(uint8_t best_chnl,
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -0700518 struct sap_context *sap_ctx,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800519 tSapChSelSpectInfo *spectinfo_param)
520{
521 uint8_t i = 0;
Tushnim Bhattacharyya518e80f2017-08-30 17:35:33 -0700522 tpAniSirGlobal mac_ctx = sme_get_mac_context();
523
524 if (NULL == mac_ctx) {
525 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
526 "pmac Global Context is NULL");
527 return SAP_CHANNEL_NOT_SELECTED;
528 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800529
530 /*
531 * If Channel List is not Configured don't do anything
532 * Else return the Best Channel from the Channel List
533 */
534 if ((NULL == sap_ctx->acs_cfg->ch_list) ||
535 (NULL == spectinfo_param) ||
536 (0 == sap_ctx->acs_cfg->ch_list_count))
537 return best_chnl;
538
539 if (best_chnl <= 0 || best_chnl > 252)
540 return SAP_CHANNEL_NOT_SELECTED;
541
542 /* Select the best channel from allowed list */
543 for (i = 0; i < sap_ctx->acs_cfg->ch_list_count; i++) {
Tushnim Bhattacharyya518e80f2017-08-30 17:35:33 -0700544 if ((sap_ctx->acs_cfg->ch_list[i] == best_chnl) &&
545 !(wlan_reg_is_dfs_ch(mac_ctx->pdev, best_chnl) &&
546 policy_mgr_disallow_mcc(mac_ctx->psoc, best_chnl))) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530547 QDF_TRACE(QDF_MODULE_ID_SAP,
Ravi Joshi9788fcd2018-02-13 15:12:22 -0800548 QDF_TRACE_LEVEL_INFO,
Naveen Rawatbec64d92017-09-13 14:35:21 -0700549 "Best channel so far is: %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800550 best_chnl);
551 return best_chnl;
552 }
553 }
554
555 return SAP_CHANNEL_NOT_SELECTED;
556}
557
558/*==========================================================================
559 FUNCTION sap_chan_sel_init
560
561 DESCRIPTION
Jeff Johnsonc7e4d162018-05-12 16:20:34 -0700562 Function sap_chan_sel_init allocates the memory, initializes the
Anurag Chouhan6d760662016-02-20 16:05:43 +0530563 structures used by the channel selection algorithm
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800564
565 DEPENDENCIES
566 NA.
567
568 PARAMETERS
569
570 IN
571 halHandle : Pointer to tHalHandle
572 *pSpectInfoParams : Pointer to tSapChSelSpectInfo structure
Jeff Johnsone13d8062017-09-28 06:54:55 -0700573 sap_ctx : Pointer to SAP Context
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800574
575 RETURN VALUE
576 bool: Success or FAIL
577
578 SIDE EFFECTS
579 ============================================================================*/
Jeff Johnson464f7ea2016-10-07 10:21:26 -0700580static bool sap_chan_sel_init(tHalHandle halHandle,
581 tSapChSelSpectInfo *pSpectInfoParams,
Jeff Johnsone13d8062017-09-28 06:54:55 -0700582 struct sap_context *sap_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800583{
584 tSapSpectChInfo *pSpectCh = NULL;
585 uint8_t *pChans = NULL;
586 uint16_t channelnum = 0;
587 tpAniSirGlobal pMac = PMAC_STRUCT(halHandle);
588 bool chSafe = true;
589#ifdef FEATURE_WLAN_CH_AVOID
590 uint16_t i;
591#endif
592 uint32_t dfs_master_cap_enabled;
593 bool include_dfs_ch = true;
Himanshu Agarwalfee2e362018-01-18 20:26:35 +0530594 uint8_t chan_num;
Bala Venkatesh2f25c812017-12-15 17:42:12 +0530595 bool sta_sap_scc_on_dfs_chan =
596 policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan(pMac->psoc);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800597
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530598 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, "In %s",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800599 __func__);
600
601 pSpectInfoParams->numSpectChans =
602 pMac->scan.base_channels.numChannels;
603
604 /* Allocate memory for weight computation of 2.4GHz */
605 pSpectCh =
Himanshu Agarwal052ce252018-06-18 17:18:59 +0530606 (tSapSpectChInfo *)qdf_mem_malloc(
607 (pSpectInfoParams->numSpectChans) *
608 sizeof(*pSpectCh));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800609
610 if (pSpectCh == NULL) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530611 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
Anurag Chouhanf04e84f2016-03-03 10:12:12 +0530612 "In %s, QDF_MALLOC_ERR", __func__);
Srinivas Girigowda74a66d62017-06-21 23:28:25 -0700613 return false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800614 }
615
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800616 /* Initialize the pointers in the DfsParams to the allocated memory */
617 pSpectInfoParams->pSpectCh = pSpectCh;
618
619 pChans = pMac->scan.base_channels.channelList;
620
Ryan Hsu4252a2f2016-01-05 11:18:24 -0800621#if defined(FEATURE_WLAN_STA_AP_MODE_DFS_DISABLE)
Jeff Johnsone13d8062017-09-28 06:54:55 -0700622 if (sap_ctx->dfs_ch_disable == true)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800623 include_dfs_ch = false;
624#endif
625 sme_cfg_get_int(halHandle, WNI_CFG_DFS_MASTER_ENABLED,
626 &dfs_master_cap_enabled);
Agrawal Ashish65634612016-08-18 13:24:32 +0530627 if (dfs_master_cap_enabled == 0 ||
Jeff Johnsone13d8062017-09-28 06:54:55 -0700628 ACS_DFS_MODE_DISABLE == sap_ctx->dfs_mode)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800629 include_dfs_ch = false;
630
631 /* Fill the channel number in the spectrum in the operating freq band */
632 for (channelnum = 0;
633 channelnum < pSpectInfoParams->numSpectChans;
Edhar, Mahesh Kumar4f660672015-10-30 11:53:26 +0530634 channelnum++, pChans++, pSpectCh++) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800635 chSafe = true;
636
Himanshu Agarwal052ce252018-06-18 17:18:59 +0530637 pSpectCh->chNum = *pChans;
638 /* Initialise for all channels */
639 pSpectCh->rssiAgr = SOFTAP_MIN_RSSI;
640 /* Initialise 20MHz for all the Channels */
641 pSpectCh->channelWidth = SOFTAP_HT20_CHANNELWIDTH;
642 /* Initialise max ACS weight for all channels */
643 pSpectCh->weight = SAP_ACS_WEIGHT_MAX;
644
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800645 /* check if the channel is in NOL blacklist */
Himanshu Agarwal052ce252018-06-18 17:18:59 +0530646 if (sap_dfs_is_channel_in_nol_list(
647 sap_ctx, *pChans,
648 PHY_SINGLE_CHANNEL_CENTERED)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530649 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800650 "In %s, Ch %d is in NOL list", __func__,
651 *pChans);
652 chSafe = false;
653 continue;
654 }
655
Bala Venkatesh2f25c812017-12-15 17:42:12 +0530656 if (!include_dfs_ch || sta_sap_scc_on_dfs_chan) {
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -0700657 if (wlan_reg_is_dfs_ch(pMac->pdev, *pChans)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800658 chSafe = false;
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530659 QDF_TRACE(QDF_MODULE_ID_SAP,
660 QDF_TRACE_LEVEL_INFO_HIGH,
Bala Venkatesh2f25c812017-12-15 17:42:12 +0530661 "In %s, DFS Ch %d not considered for ACS. include_dfs_ch %u, sta_sap_scc_on_dfs_chan %d",
662 __func__, *pChans, include_dfs_ch,
663 sta_sap_scc_on_dfs_chan);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800664 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 Lokere1a43bcf2018-05-15 15:51:58 -0700689 if (wlan_reg_is_dsrc_chan(pMac->pdev, *pChans))
690 continue;
691
692 if (!pMac->sap.enable_etsi13_srd_chan_support &&
693 wlan_reg_is_etsi13_srd_chan(pMac->pdev, *pChans))
Deepthi Gowri48b89332016-08-30 18:43:05 +0530694 continue;
695
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800696 if (true == chSafe) {
Srinivas Girigowda74a66d62017-06-21 23:28:25 -0700697 pSpectCh->valid = true;
Himanshu Agarwalfee2e362018-01-18 20:26:35 +0530698 for (chan_num = 0; chan_num < sap_ctx->num_of_channel;
699 chan_num++) {
700 if (pSpectCh->chNum !=
701 sap_ctx->channelList[chan_num])
702 continue;
703
704 /*
705 * Initialize ACS weight to 0 for channels
706 * present in sap context scan channel list
707 */
708 pSpectCh->weight = 0;
709 break;
710 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800711 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800712 }
Srinivas Girigowda74a66d62017-06-21 23:28:25 -0700713 return true;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800714}
715
gaoleze5108942017-03-31 16:56:42 +0800716/**
717 * sapweight_rssi_count() - calculates the channel weight due to rssi
Anurag Chouhan6d760662016-02-20 16:05:43 +0530718 and data count(here number of BSS observed)
gaoleze5108942017-03-31 16:56:42 +0800719 * @sap_ctx : Softap context
720 * @rssi : Max signal strength receieved from a BSS for the channel
721 * @count : Number of BSS observed in the channel
722 *
723 * Return: uint32_t Calculated channel weight based on above two
724 */
725static
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -0700726uint32_t sapweight_rssi_count(struct sap_context *sap_ctx, int8_t rssi,
gaoleze5108942017-03-31 16:56:42 +0800727 uint16_t count)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800728{
729 int32_t rssiWeight = 0;
730 int32_t countWeight = 0;
731 uint32_t rssicountWeight = 0;
gaoleze5108942017-03-31 16:56:42 +0800732 uint8_t softap_rssi_weight_cfg, softap_count_weight_cfg;
733 uint8_t softap_rssi_weight_local, softap_count_weight_local;
734
735 softap_rssi_weight_cfg =
736 ACS_WEIGHT_SOFTAP_RSSI_CFG(sap_ctx->auto_channel_select_weight);
737
738 softap_count_weight_cfg =
739 ACS_WEIGHT_SOFTAP_COUNT_CFG(sap_ctx->auto_channel_select_weight);
740
741 softap_rssi_weight_local =
742 ACS_WEIGHT_CFG_TO_LOCAL(sap_ctx->auto_channel_select_weight,
743 softap_rssi_weight_cfg);
744
745 softap_count_weight_local =
746 ACS_WEIGHT_CFG_TO_LOCAL(sap_ctx->auto_channel_select_weight,
747 softap_count_weight_cfg);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800748
749 /* Weight from RSSI */
gaoleze5108942017-03-31 16:56:42 +0800750 rssiWeight = ACS_WEIGHT_COMPUTE(sap_ctx->auto_channel_select_weight,
751 softap_rssi_weight_cfg,
752 rssi - SOFTAP_MIN_RSSI,
753 SOFTAP_MAX_RSSI - SOFTAP_MIN_RSSI);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800754
gaoleze5108942017-03-31 16:56:42 +0800755 if (rssiWeight > softap_rssi_weight_local)
756 rssiWeight = softap_rssi_weight_local;
757
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800758 else if (rssiWeight < 0)
759 rssiWeight = 0;
760
761 /* Weight from data count */
gaoleze5108942017-03-31 16:56:42 +0800762 countWeight = ACS_WEIGHT_COMPUTE(sap_ctx->auto_channel_select_weight,
763 softap_count_weight_cfg,
764 count - SOFTAP_MIN_COUNT,
765 SOFTAP_MAX_COUNT - SOFTAP_MIN_COUNT);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800766
gaoleze5108942017-03-31 16:56:42 +0800767 if (countWeight > softap_count_weight_local)
768 countWeight = softap_count_weight_local;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800769
770 rssicountWeight = rssiWeight + countWeight;
771
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530772 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800773 "In %s, rssiWeight=%d, countWeight=%d, rssicountWeight=%d",
774 __func__, rssiWeight, countWeight, rssicountWeight);
775
776 return rssicountWeight;
777}
778
779/**
gaoleze5108942017-03-31 16:56:42 +0800780 * sap_get_channel_status() - get channel info via channel number
781 * @p_mac: Pointer to Global MAC structure
782 * @channel_id: channel id
783 *
784 * Return: chan status info
785 */
786static struct lim_channel_status *sap_get_channel_status
787 (tpAniSirGlobal p_mac, uint32_t channel_id)
788{
789 return csr_get_channel_status(p_mac, channel_id);
790}
791
792/**
793 * sap_clear_channel_status() - clear chan info
794 * @p_mac: Pointer to Global MAC structure
795 *
796 * Return: none
797 */
798static void sap_clear_channel_status(tpAniSirGlobal p_mac)
799{
800 csr_clear_channel_status(p_mac);
801}
802
803/**
804 * sap_weight_channel_noise_floor() - compute noise floor weight
805 * @sap_ctx: sap context
806 * @chn_stat: Pointer to chan status info
807 *
808 * Return: channel noise floor weight
809 */
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -0700810static uint32_t sap_weight_channel_noise_floor(struct sap_context *sap_ctx,
gaoleze5108942017-03-31 16:56:42 +0800811 struct lim_channel_status
812 *channel_stat)
813{
814 uint32_t noise_floor_weight;
815 uint8_t softap_nf_weight_cfg;
816 uint8_t softap_nf_weight_local;
817
818 softap_nf_weight_cfg =
819 ACS_WEIGHT_SOFTAP_NOISE_FLOOR_CFG
820 (sap_ctx->auto_channel_select_weight);
821
822 softap_nf_weight_local =
823 ACS_WEIGHT_CFG_TO_LOCAL(sap_ctx->auto_channel_select_weight,
824 softap_nf_weight_cfg);
825
826 if (channel_stat == NULL || channel_stat->channelfreq == 0) {
Srinivas Girigowda80213e52018-01-23 14:51:33 -0800827 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG,
gaoleze5108942017-03-31 16:56:42 +0800828 "In %s, sanity check failed return max weight",
829 __func__);
830 return softap_nf_weight_local;
831 }
832
833 noise_floor_weight = (channel_stat->noise_floor == 0) ? 0 :
834 (ACS_WEIGHT_COMPUTE(
835 sap_ctx->auto_channel_select_weight,
836 softap_nf_weight_cfg,
837 channel_stat->noise_floor -
838 SOFTAP_MIN_NF,
839 SOFTAP_MAX_NF - SOFTAP_MIN_NF));
840
841 if (noise_floor_weight > softap_nf_weight_local)
842 noise_floor_weight = softap_nf_weight_local;
843 else if (noise_floor_weight < 0)
844 noise_floor_weight = 0;
845
846 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
847 "In %s, nf=%d, nfwc=%d, nfwl=%d, nfw=%d",
848 __func__, channel_stat->noise_floor,
849 softap_nf_weight_cfg, softap_nf_weight_local,
850 noise_floor_weight);
851
852 return noise_floor_weight;
853}
854
855/**
856 * sap_weight_channel_free() - compute channel free weight
857 * @sap_ctx: sap context
858 * @chn_stat: Pointer to chan status info
859 *
860 * Return: channel free weight
861 */
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -0700862static uint32_t sap_weight_channel_free(struct sap_context *sap_ctx,
gaoleze5108942017-03-31 16:56:42 +0800863 struct lim_channel_status
864 *channel_stat)
865{
866 uint32_t channel_free_weight;
867 uint8_t softap_channel_free_weight_cfg;
868 uint8_t softap_channel_free_weight_local;
869 uint32_t rx_clear_count = 0;
870 uint32_t cycle_count = 0;
871
872 softap_channel_free_weight_cfg =
873 ACS_WEIGHT_SOFTAP_CHANNEL_FREE_CFG
874 (sap_ctx->auto_channel_select_weight);
875
876 softap_channel_free_weight_local =
877 ACS_WEIGHT_CFG_TO_LOCAL(sap_ctx->auto_channel_select_weight,
878 softap_channel_free_weight_cfg);
879
880 if (channel_stat == NULL || channel_stat->channelfreq == 0) {
Srinivas Girigowda80213e52018-01-23 14:51:33 -0800881 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG,
gaoleze5108942017-03-31 16:56:42 +0800882 "In %s, sanity check failed return max weight",
883 __func__);
884 return softap_channel_free_weight_local;
885 }
886
887 rx_clear_count = channel_stat->rx_clear_count -
888 channel_stat->tx_frame_count -
889 channel_stat->rx_frame_count;
890 cycle_count = channel_stat->cycle_count;
891
892 /* LSH 4, otherwise it is always 0. */
893 channel_free_weight = (cycle_count == 0) ? 0 :
894 (ACS_WEIGHT_COMPUTE(
895 sap_ctx->auto_channel_select_weight,
896 softap_channel_free_weight_cfg,
897 ((rx_clear_count << 8) +
898 (cycle_count >> 1))/cycle_count -
899 (SOFTAP_MIN_CHNFREE << 8),
900 (SOFTAP_MAX_CHNFREE -
901 SOFTAP_MIN_CHNFREE) << 8));
902
903 if (channel_free_weight > softap_channel_free_weight_local)
904 channel_free_weight = softap_channel_free_weight_local;
905
906 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
907 "In %s, rcc=%d, cc=%d, tc=%d, rc=%d, cfwc=%d, cfwl=%d, cfw=%d",
908 __func__, rx_clear_count, cycle_count,
909 channel_stat->tx_frame_count,
910 channel_stat->rx_frame_count,
911 softap_channel_free_weight_cfg,
912 softap_channel_free_weight_local,
913 channel_free_weight);
914
915 return channel_free_weight;
916}
917
918/**
919 * sap_weight_channel_txpwr_range() - compute channel tx power range weight
920 * @sap_ctx: sap context
921 * @chn_stat: Pointer to chan status info
922 *
923 * Return: tx power range weight
924 */
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -0700925static uint32_t sap_weight_channel_txpwr_range(struct sap_context *sap_ctx,
gaoleze5108942017-03-31 16:56:42 +0800926 struct lim_channel_status
927 *channel_stat)
928{
929 uint32_t txpwr_weight_low_speed;
930 uint8_t softap_txpwr_range_weight_cfg;
931 uint8_t softap_txpwr_range_weight_local;
932
933 softap_txpwr_range_weight_cfg =
934 ACS_WEIGHT_SOFTAP_TX_POWER_RANGE_CFG
935 (sap_ctx->auto_channel_select_weight);
936
937 softap_txpwr_range_weight_local =
938 ACS_WEIGHT_CFG_TO_LOCAL(sap_ctx->auto_channel_select_weight,
939 softap_txpwr_range_weight_cfg);
940
941 if (channel_stat == NULL || channel_stat->channelfreq == 0) {
Srinivas Girigowda80213e52018-01-23 14:51:33 -0800942 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG,
gaoleze5108942017-03-31 16:56:42 +0800943 "In %s, sanity check failed return max weight",
944 __func__);
945 return softap_txpwr_range_weight_local;
946 }
947
948 txpwr_weight_low_speed = (channel_stat->chan_tx_pwr_range == 0) ? 0 :
949 (ACS_WEIGHT_COMPUTE(
950 sap_ctx->auto_channel_select_weight,
951 softap_txpwr_range_weight_cfg,
952 SOFTAP_MAX_TXPWR -
953 channel_stat->chan_tx_pwr_range,
954 SOFTAP_MAX_TXPWR - SOFTAP_MIN_TXPWR));
955
956 if (txpwr_weight_low_speed > softap_txpwr_range_weight_local)
957 txpwr_weight_low_speed = softap_txpwr_range_weight_local;
958
959 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
960 "In %s, tpr=%d, tprwc=%d, tprwl=%d, tprw=%d",
961 __func__, channel_stat->chan_tx_pwr_range,
962 softap_txpwr_range_weight_cfg,
963 softap_txpwr_range_weight_local,
964 txpwr_weight_low_speed);
965
966 return txpwr_weight_low_speed;
967}
968
969/**
970 * sap_weight_channel_txpwr_tput() - compute channel tx power
971 * throughput weight
972 * @sap_ctx: sap context
973 * @chn_stat: Pointer to chan status info
974 *
975 * Return: tx power throughput weight
976 */
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -0700977static uint32_t sap_weight_channel_txpwr_tput(struct sap_context *sap_ctx,
gaoleze5108942017-03-31 16:56:42 +0800978 struct lim_channel_status
979 *channel_stat)
980{
981 uint32_t txpwr_weight_high_speed;
982 uint8_t softap_txpwr_tput_weight_cfg;
983 uint8_t softap_txpwr_tput_weight_local;
984
985 softap_txpwr_tput_weight_cfg =
986 ACS_WEIGHT_SOFTAP_TX_POWER_THROUGHPUT_CFG
987 (sap_ctx->auto_channel_select_weight);
988
989 softap_txpwr_tput_weight_local =
990 ACS_WEIGHT_CFG_TO_LOCAL(sap_ctx->auto_channel_select_weight,
991 softap_txpwr_tput_weight_cfg);
992
993 if (channel_stat == NULL || channel_stat->channelfreq == 0) {
Srinivas Girigowda80213e52018-01-23 14:51:33 -0800994 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG,
gaoleze5108942017-03-31 16:56:42 +0800995 "In %s, sanity check failed return max weight",
996 __func__);
997 return softap_txpwr_tput_weight_local;
998 }
999
1000 txpwr_weight_high_speed = (channel_stat->chan_tx_pwr_throughput == 0)
1001 ? 0 : (ACS_WEIGHT_COMPUTE(
1002 sap_ctx->auto_channel_select_weight,
1003 softap_txpwr_tput_weight_cfg,
1004 SOFTAP_MAX_TXPWR -
1005 channel_stat->chan_tx_pwr_throughput,
1006 SOFTAP_MAX_TXPWR - SOFTAP_MIN_TXPWR));
1007
1008 if (txpwr_weight_high_speed > softap_txpwr_tput_weight_local)
1009 txpwr_weight_high_speed = softap_txpwr_tput_weight_local;
1010
1011 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
1012 "In %s, tpt=%d, tptwc=%d, tptwl=%d, tptw=%d",
1013 __func__, channel_stat->chan_tx_pwr_throughput,
1014 softap_txpwr_tput_weight_cfg,
1015 softap_txpwr_tput_weight_local,
1016 txpwr_weight_high_speed);
1017
1018 return txpwr_weight_high_speed;
1019}
1020
1021/**
1022 * sap_weight_channel_status() - compute chan status weight
1023 * @sap_ctx: sap context
1024 * @chn_stat: Pointer to chan status info
1025 *
1026 * Return: chan status weight
1027 */
1028static
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -07001029uint32_t sap_weight_channel_status(struct sap_context *sap_ctx,
gaoleze5108942017-03-31 16:56:42 +08001030 struct lim_channel_status *channel_stat)
1031{
1032 return sap_weight_channel_noise_floor(sap_ctx, channel_stat) +
1033 sap_weight_channel_free(sap_ctx, channel_stat) +
1034 sap_weight_channel_txpwr_range(sap_ctx, channel_stat) +
1035 sap_weight_channel_txpwr_tput(sap_ctx, channel_stat);
1036}
1037
1038/**
Yeshwanth Sriram Guntuka273889e2018-02-16 17:11:46 +05301039 * sap_check_channels_same_band() - Check if two channels belong to same band
1040 * @ch_num1: channel number
1041 * @ch_num2: channel number
1042 *
1043 * Return: true if both channels belong to same band else false
1044 */
1045static bool sap_check_channels_same_band(uint16_t ch_num1, uint16_t ch_num2)
1046{
1047 if ((ch_num1 <= SIR_11B_CHANNEL_END &&
1048 ch_num2 <= SIR_11B_CHANNEL_END) ||
1049 (ch_num1 >= SIR_11A_CHANNEL_BEGIN &&
1050 ch_num2 >= SIR_11A_CHANNEL_BEGIN))
1051 return true;
1052
1053 return false;
1054}
1055
1056/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001057 * sap_update_rssi_bsscount() - updates bss count and rssi effect.
1058 *
1059 * @pSpectCh: Channel Information
1060 * @offset: Channel Offset
1061 * @sap_24g: Channel is in 2.4G or 5G
Liangwei Dong71ed6502016-10-20 03:40:45 -04001062 * @spectch_start: the start of spect ch array
1063 * @spectch_end: the end of spect ch array
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001064 *
1065 * sap_update_rssi_bsscount updates bss count and rssi effect based
1066 * on the channel offset.
1067 *
1068 * Return: None.
1069 */
1070
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001071static void sap_update_rssi_bsscount(tSapSpectChInfo *pSpectCh, int32_t offset,
Liangwei Dong71ed6502016-10-20 03:40:45 -04001072 bool sap_24g, tSapSpectChInfo *spectch_start,
1073 tSapSpectChInfo *spectch_end)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001074{
1075 tSapSpectChInfo *pExtSpectCh = NULL;
1076 int32_t rssi, rsssi_effect;
1077
1078 pExtSpectCh = (pSpectCh + offset);
Liangwei Dong71ed6502016-10-20 03:40:45 -04001079 if (pExtSpectCh != NULL &&
1080 pExtSpectCh >= spectch_start &&
1081 pExtSpectCh < spectch_end) {
Yeshwanth Sriram Guntuka273889e2018-02-16 17:11:46 +05301082 if (!sap_check_channels_same_band(pSpectCh->chNum,
1083 pExtSpectCh->chNum))
1084 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001085 ++pExtSpectCh->bssCount;
1086 switch (offset) {
1087 case -1:
1088 case 1:
1089 rsssi_effect = sap_24g ?
1090 SAP_24GHZ_FIRST_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY :
1091 SAP_SUBBAND1_RSSI_EFFECT_PRIMARY;
1092 break;
1093 case -2:
1094 case 2:
1095 rsssi_effect = sap_24g ?
1096 SAP_24GHZ_SEC_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY :
1097 SAP_SUBBAND2_RSSI_EFFECT_PRIMARY;
1098 break;
1099 case -3:
1100 case 3:
1101 rsssi_effect = sap_24g ?
1102 SAP_24GHZ_THIRD_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY :
1103 SAP_SUBBAND3_RSSI_EFFECT_PRIMARY;
1104 break;
1105 case -4:
1106 case 4:
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001107 rsssi_effect = sap_24g ?
1108 SAP_24GHZ_FOURTH_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY :
1109 SAP_SUBBAND4_RSSI_EFFECT_PRIMARY;
1110 break;
1111 case -5:
1112 case 5:
1113 rsssi_effect = SAP_SUBBAND5_RSSI_EFFECT_PRIMARY;
1114 break;
1115 case -6:
1116 case 6:
1117 rsssi_effect = SAP_SUBBAND6_RSSI_EFFECT_PRIMARY;
1118 break;
1119 case -7:
1120 case 7:
1121 rsssi_effect = SAP_SUBBAND7_RSSI_EFFECT_PRIMARY;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001122 break;
1123 default:
1124 rsssi_effect = 0;
1125 break;
1126 }
1127
1128 rssi = pSpectCh->rssiAgr + rsssi_effect;
1129 if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi))
1130 pExtSpectCh->rssiAgr = rssi;
1131 if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI)
1132 pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI;
1133 }
1134}
1135
1136/**
1137 * sap_upd_chan_spec_params() - sap_upd_chan_spec_params
1138 * updates channel parameters obtained from Beacon
1139 * @pBeaconStruct Beacon strucutre populated by parse_beacon function
1140 * @channelWidth Channel width
1141 * @secondaryChannelOffset Secondary Channel Offset
1142 * @vhtSupport If channel supports VHT
1143 * @centerFreq Central frequency for the given channel.
1144 *
1145 * sap_upd_chan_spec_params updates the spectrum channels based on the
1146 * pBeaconStruct obtained from Beacon IE
1147 *
1148 * Return: NA.
1149 */
1150
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001151static void sap_upd_chan_spec_params(tSirProbeRespBeacon *pBeaconStruct,
1152 uint16_t *channelWidth,
1153 uint16_t *secondaryChannelOffset,
1154 uint16_t *vhtSupport,
1155 uint16_t *centerFreq,
1156 uint16_t *centerFreq_2)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001157{
1158 if (NULL == pBeaconStruct) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301159 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001160 FL("pBeaconStruct is NULL"));
1161 return;
1162 }
1163
1164 if (pBeaconStruct->HTCaps.present && pBeaconStruct->HTInfo.present) {
1165 *channelWidth = pBeaconStruct->HTCaps.supportedChannelWidthSet;
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001166 *secondaryChannelOffset =
1167 pBeaconStruct->HTInfo.secondaryChannelOffset;
1168 if (!pBeaconStruct->VHTOperation.present)
1169 return;
1170 *vhtSupport = pBeaconStruct->VHTOperation.present;
1171 if (pBeaconStruct->VHTOperation.chanWidth) {
1172 *centerFreq =
1173 pBeaconStruct->VHTOperation.chanCenterFreqSeg1;
1174 *centerFreq_2 =
1175 pBeaconStruct->VHTOperation.chanCenterFreqSeg2;
1176 /*
1177 * LHS follows tSirMacHTChannelWidth, while RHS follows
1178 * WNI_CFG_VHT_CHANNEL_WIDTH_X format hence following
1179 * adjustment
1180 */
1181 *channelWidth =
1182 pBeaconStruct->VHTOperation.chanWidth + 1;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001183
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001184 }
1185 }
1186}
1187
1188/**
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001189 * sap_update_rssi_bsscount_vht_5G() - updates bss count and rssi effect.
1190 *
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001191 * @spect_ch: Channel Information
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001192 * @offset: Channel Offset
1193 * @num_ch: no.of channels
Liangwei Dong71ed6502016-10-20 03:40:45 -04001194 * @spectch_start: the start of spect ch array
1195 * @spectch_end: the end of spect ch array
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001196 *
1197 * sap_update_rssi_bsscount_vht_5G updates bss count and rssi effect based
1198 * on the channel offset.
1199 *
1200 * Return: None.
1201 */
1202
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001203static void sap_update_rssi_bsscount_vht_5G(tSapSpectChInfo *spect_ch,
1204 int32_t offset,
Liangwei Dong71ed6502016-10-20 03:40:45 -04001205 uint16_t num_ch,
1206 tSapSpectChInfo *spectch_start,
1207 tSapSpectChInfo *spectch_end)
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001208{
1209 int32_t ch_offset;
1210 uint16_t i, cnt;
1211
1212 if (!offset)
1213 return;
1214 if (offset > 0)
1215 cnt = num_ch;
1216 else
1217 cnt = num_ch + 1;
1218 for (i = 0; i < cnt; i++) {
1219 ch_offset = offset + i;
1220 if (ch_offset == 0)
1221 continue;
Liangwei Dong71ed6502016-10-20 03:40:45 -04001222 sap_update_rssi_bsscount(spect_ch, ch_offset, false,
1223 spectch_start, spectch_end);
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001224 }
1225}
1226/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001227 * sap_interference_rssi_count_5G() - sap_interference_rssi_count
1228 * considers the Adjacent channel rssi and
1229 * data count(here number of BSS observed)
1230 * @spect_ch: Channel Information
1231 * @chan_width: Channel width parsed from beacon IE
1232 * @sec_chan_offset: Secondary Channel Offset
1233 * @center_freq: Central frequency for the given channel.
1234 * @channel_id: channel_id
Liangwei Dong71ed6502016-10-20 03:40:45 -04001235 * @spectch_start: the start of spect ch array
1236 * @spectch_end: the end of spect ch array
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001237 *
1238 * sap_interference_rssi_count_5G considers the Adjacent channel rssi
1239 * and data count(here number of BSS observed)
1240 *
1241 * Return: NA.
1242 */
1243
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001244static void sap_interference_rssi_count_5G(tSapSpectChInfo *spect_ch,
1245 uint16_t chan_width,
1246 uint16_t sec_chan_offset,
1247 uint16_t center_freq,
1248 uint16_t center_freq_2,
Liangwei Dong71ed6502016-10-20 03:40:45 -04001249 uint8_t channel_id,
1250 tSapSpectChInfo *spectch_start,
1251 tSapSpectChInfo *spectch_end)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001252{
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001253 uint16_t num_ch;
1254 int32_t offset = 0;
Srinivas Girigowda4d65ebe2017-10-13 21:41:42 -07001255
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001256 if (NULL == spect_ch) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301257 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001258 FL("spect_ch is NULL"));
1259 return;
1260 }
1261
1262 /* Updating the received ChannelWidth */
1263 if (spect_ch->channelWidth != chan_width)
1264 spect_ch->channelWidth = chan_width;
1265 /* If received ChannelWidth is other than HT20,
1266 * we need to update the extension channel Params as well
1267 * chan_width == 0, HT20
1268 * chan_width == 1, HT40
1269 * chan_width == 2, VHT80
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001270 * chan_width == 3, VHT160
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001271 */
1272
1273 switch (spect_ch->channelWidth) {
1274 case eHT_CHANNEL_WIDTH_40MHZ: /* HT40 */
1275 switch (sec_chan_offset) {
1276 /* Above the Primary Channel */
1277 case PHY_DOUBLE_CHANNEL_LOW_PRIMARY:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001278 sap_update_rssi_bsscount(spect_ch, 1, false,
1279 spectch_start, spectch_end);
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001280 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001281
1282 /* Below the Primary channel */
1283 case PHY_DOUBLE_CHANNEL_HIGH_PRIMARY:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001284 sap_update_rssi_bsscount(spect_ch, -1, false,
1285 spectch_start, spectch_end);
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001286 return;
1287 }
1288 return;
1289 case eHT_CHANNEL_WIDTH_80MHZ: /* VHT80 */
1290 num_ch = 3;
1291 if ((center_freq - channel_id) == 6) {
1292 offset = 1;
1293 } else if ((center_freq - channel_id) == 2) {
1294 offset = -1;
1295 } else if ((center_freq - channel_id) == -2) {
1296 offset = -2;
1297 } else if ((center_freq - channel_id) == -6) {
1298 offset = -3;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001299 }
1300 break;
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001301 case eHT_CHANNEL_WIDTH_160MHZ: /* VHT160 */
1302 num_ch = 7;
1303 if ((center_freq - channel_id) == 14)
1304 offset = 1;
1305 else if ((center_freq - channel_id) == 10)
1306 offset = -1;
1307 else if ((center_freq - channel_id) == 6)
1308 offset = -2;
1309 else if ((center_freq - channel_id) == 2)
1310 offset = -3;
1311 else if ((center_freq - channel_id) == -2)
1312 offset = -4;
1313 else if ((center_freq - channel_id) == -6)
1314 offset = -5;
1315 else if ((center_freq - channel_id) == -10)
1316 offset = -6;
1317 else if ((center_freq - channel_id) == -14)
1318 offset = -7;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001319 break;
1320 default:
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001321 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001322 }
Liangwei Dong71ed6502016-10-20 03:40:45 -04001323 sap_update_rssi_bsscount_vht_5G(spect_ch, offset, num_ch,
1324 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001325}
1326
1327/**
1328 * sap_interference_rssi_count() - sap_interference_rssi_count
1329 * considers the Adjacent channel rssi
1330 * and data count(here number of BSS observed)
1331 * @spect_ch Channel Information
Liangwei Dong71ed6502016-10-20 03:40:45 -04001332 * @spectch_start: the start of spect ch array
1333 * @spectch_end: the end of spect ch array
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001334 *
1335 * sap_interference_rssi_count considers the Adjacent channel rssi
1336 * and data count(here number of BSS observed)
1337 *
1338 * Return: None.
1339 */
1340
Liangwei Dong71ed6502016-10-20 03:40:45 -04001341static void sap_interference_rssi_count(tSapSpectChInfo *spect_ch,
1342 tSapSpectChInfo *spectch_start,
1343 tSapSpectChInfo *spectch_end)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001344{
1345 if (NULL == spect_ch) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301346 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001347 "%s: spect_ch is NULL", __func__);
1348 return;
1349 }
1350
1351 switch (spect_ch->chNum) {
1352 case CHANNEL_1:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001353 sap_update_rssi_bsscount(spect_ch, 1, true,
1354 spectch_start, spectch_end);
1355 sap_update_rssi_bsscount(spect_ch, 2, true,
1356 spectch_start, spectch_end);
1357 sap_update_rssi_bsscount(spect_ch, 3, true,
1358 spectch_start, spectch_end);
1359 sap_update_rssi_bsscount(spect_ch, 4, true,
1360 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001361 break;
1362
1363 case CHANNEL_2:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001364 sap_update_rssi_bsscount(spect_ch, -1, true,
1365 spectch_start, spectch_end);
1366 sap_update_rssi_bsscount(spect_ch, 1, true,
1367 spectch_start, spectch_end);
1368 sap_update_rssi_bsscount(spect_ch, 2, true,
1369 spectch_start, spectch_end);
1370 sap_update_rssi_bsscount(spect_ch, 3, true,
1371 spectch_start, spectch_end);
1372 sap_update_rssi_bsscount(spect_ch, 4, true,
1373 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001374 break;
1375 case CHANNEL_3:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001376 sap_update_rssi_bsscount(spect_ch, -2, true,
1377 spectch_start, spectch_end);
1378 sap_update_rssi_bsscount(spect_ch, -1, true,
1379 spectch_start, spectch_end);
1380 sap_update_rssi_bsscount(spect_ch, 1, true,
1381 spectch_start, spectch_end);
1382 sap_update_rssi_bsscount(spect_ch, 2, true,
1383 spectch_start, spectch_end);
1384 sap_update_rssi_bsscount(spect_ch, 3, true,
1385 spectch_start, spectch_end);
1386 sap_update_rssi_bsscount(spect_ch, 4, true,
1387 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001388 break;
1389 case CHANNEL_4:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001390 sap_update_rssi_bsscount(spect_ch, -3, true,
1391 spectch_start, spectch_end);
1392 sap_update_rssi_bsscount(spect_ch, -2, true,
1393 spectch_start, spectch_end);
1394 sap_update_rssi_bsscount(spect_ch, -1, true,
1395 spectch_start, spectch_end);
1396 sap_update_rssi_bsscount(spect_ch, 1, true,
1397 spectch_start, spectch_end);
1398 sap_update_rssi_bsscount(spect_ch, 2, true,
1399 spectch_start, spectch_end);
1400 sap_update_rssi_bsscount(spect_ch, 3, true,
1401 spectch_start, spectch_end);
1402 sap_update_rssi_bsscount(spect_ch, 4, true,
1403 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001404 break;
1405
1406 case CHANNEL_5:
1407 case CHANNEL_6:
1408 case CHANNEL_7:
1409 case CHANNEL_8:
1410 case CHANNEL_9:
1411 case CHANNEL_10:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001412 sap_update_rssi_bsscount(spect_ch, -4, true,
1413 spectch_start, spectch_end);
1414 sap_update_rssi_bsscount(spect_ch, -3, true,
1415 spectch_start, spectch_end);
1416 sap_update_rssi_bsscount(spect_ch, -2, true,
1417 spectch_start, spectch_end);
1418 sap_update_rssi_bsscount(spect_ch, -1, true,
1419 spectch_start, spectch_end);
1420 sap_update_rssi_bsscount(spect_ch, 1, true,
1421 spectch_start, spectch_end);
1422 sap_update_rssi_bsscount(spect_ch, 2, true,
1423 spectch_start, spectch_end);
1424 sap_update_rssi_bsscount(spect_ch, 3, true,
1425 spectch_start, spectch_end);
1426 sap_update_rssi_bsscount(spect_ch, 4, true,
1427 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001428 break;
1429
1430 case CHANNEL_11:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001431 sap_update_rssi_bsscount(spect_ch, -4, true,
1432 spectch_start, spectch_end);
1433 sap_update_rssi_bsscount(spect_ch, -3, true,
1434 spectch_start, spectch_end);
1435 sap_update_rssi_bsscount(spect_ch, -2, true,
1436 spectch_start, spectch_end);
1437 sap_update_rssi_bsscount(spect_ch, -1, true,
1438 spectch_start, spectch_end);
1439 sap_update_rssi_bsscount(spect_ch, 1, true,
1440 spectch_start, spectch_end);
1441 sap_update_rssi_bsscount(spect_ch, 2, true,
1442 spectch_start, spectch_end);
1443 sap_update_rssi_bsscount(spect_ch, 3, true,
1444 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001445 break;
1446
1447 case CHANNEL_12:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001448 sap_update_rssi_bsscount(spect_ch, -4, true,
1449 spectch_start, spectch_end);
1450 sap_update_rssi_bsscount(spect_ch, -3, true,
1451 spectch_start, spectch_end);
1452 sap_update_rssi_bsscount(spect_ch, -2, true,
1453 spectch_start, spectch_end);
1454 sap_update_rssi_bsscount(spect_ch, -1, true,
1455 spectch_start, spectch_end);
1456 sap_update_rssi_bsscount(spect_ch, 1, true,
1457 spectch_start, spectch_end);
1458 sap_update_rssi_bsscount(spect_ch, 2, true,
1459 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001460 break;
1461
1462 case CHANNEL_13:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001463 sap_update_rssi_bsscount(spect_ch, -4, true,
1464 spectch_start, spectch_end);
1465 sap_update_rssi_bsscount(spect_ch, -3, true,
1466 spectch_start, spectch_end);
1467 sap_update_rssi_bsscount(spect_ch, -2, true,
1468 spectch_start, spectch_end);
1469 sap_update_rssi_bsscount(spect_ch, -1, true,
1470 spectch_start, spectch_end);
1471 sap_update_rssi_bsscount(spect_ch, 1, true,
1472 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001473 break;
1474
1475 case CHANNEL_14:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001476 sap_update_rssi_bsscount(spect_ch, -4, true,
1477 spectch_start, spectch_end);
1478 sap_update_rssi_bsscount(spect_ch, -3, true,
1479 spectch_start, spectch_end);
1480 sap_update_rssi_bsscount(spect_ch, -2, true,
1481 spectch_start, spectch_end);
1482 sap_update_rssi_bsscount(spect_ch, -1, true,
1483 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001484 break;
1485
1486 default:
1487 break;
1488 }
1489}
1490
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001491/**
1492 * ch_in_pcl() - Is channel in the Preferred Channel List (PCL)
1493 * @sap_ctx: SAP context which contains the current PCL
1494 * @channel: Input channel number to be checked
1495 *
1496 * Check if a channel is in the preferred channel list
1497 *
1498 * Return:
1499 * true: channel is in PCL,
1500 * false: channel is not in PCL
1501 */
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -07001502static bool ch_in_pcl(struct sap_context *sap_ctx, uint8_t channel)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001503{
1504 uint32_t i;
1505
1506 for (i = 0; i < sap_ctx->acs_cfg->pcl_ch_count; i++) {
1507 if (channel == sap_ctx->acs_cfg->pcl_channels[i])
1508 return true;
1509 }
1510
1511 return false;
1512}
1513
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001514/**
1515 * sap_compute_spect_weight() - Compute spectrum weight
1516 * @pSpectInfoParams: Pointer to the tSpectInfoParams structure
1517 * @halHandle: Pointer to HAL handle
1518 * @pResult: Pointer to tScanResultHandle
1519 * @sap_ctx: Context of the SAP
1520 *
1521 * Main function for computing the weight of each channel in the
1522 * spectrum based on the RSSI value of the BSSes on the channel
1523 * and number of BSS
1524 */
1525static void sap_compute_spect_weight(tSapChSelSpectInfo *pSpectInfoParams,
1526 tHalHandle halHandle,
1527 tScanResultHandle pResult,
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -07001528 struct sap_context *sap_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001529{
1530 int8_t rssi = 0;
1531 uint8_t chn_num = 0;
1532 uint8_t channel_id = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001533 tCsrScanResultInfo *pScanResult;
1534 tSapSpectChInfo *pSpectCh = pSpectInfoParams->pSpectCh;
1535 uint32_t operatingBand;
1536 uint16_t channelWidth;
1537 uint16_t secondaryChannelOffset;
1538 uint16_t centerFreq;
gaurank kathpalia859c9362018-08-02 23:07:21 +05301539 uint8_t i;
1540 bool found;
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001541 uint16_t centerFreq_2 = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001542 uint16_t vhtSupport;
1543 uint32_t ieLen = 0;
1544 tSirProbeRespBeacon *pBeaconStruct;
1545 tpAniSirGlobal pMac = (tpAniSirGlobal) halHandle;
Liangwei Dong71ed6502016-10-20 03:40:45 -04001546 tSapSpectChInfo *spectch_start = pSpectInfoParams->pSpectCh;
1547 tSapSpectChInfo *spectch_end = pSpectInfoParams->pSpectCh +
1548 pSpectInfoParams->numSpectChans;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001549
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301550 pBeaconStruct = qdf_mem_malloc(sizeof(tSirProbeRespBeacon));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001551 if (NULL == pBeaconStruct) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301552 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Kaushik, Sushantee3ed032016-08-04 16:40:46 +05301553 "Unable to allocate memory in sap_compute_spect_weight");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001554 return;
1555 }
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301556 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001557 "In %s, Computing spectral weight", __func__);
1558
1559 /**
1560 * Soft AP specific channel weight calculation using DFS formula
1561 */
1562 SET_ACS_BAND(operatingBand, sap_ctx);
1563
1564 pScanResult = sme_scan_result_get_first(halHandle, pResult);
1565
1566 while (pScanResult) {
1567 pSpectCh = pSpectInfoParams->pSpectCh;
1568 /* Defining the default values, so that any value will hold the default values */
1569 channelWidth = eHT_CHANNEL_WIDTH_20MHZ;
1570 secondaryChannelOffset = PHY_SINGLE_CHANNEL_CENTERED;
1571 vhtSupport = 0;
1572 centerFreq = 0;
1573
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001574
Yingying Tang22facc12016-10-20 17:43:59 +08001575 ieLen = GET_IE_LEN_IN_BSS(
1576 pScanResult->BssDescriptor.length);
1577 qdf_mem_set((uint8_t *) pBeaconStruct,
1578 sizeof(tSirProbeRespBeacon), 0);
1579
1580
1581 if ((sir_parse_beacon_ie
1582 (pMac, pBeaconStruct, (uint8_t *)
1583 (pScanResult->BssDescriptor.ieFields),
Jeff Johnson83e30fa2018-06-07 23:01:11 -07001584 ieLen)) == QDF_STATUS_SUCCESS)
Yingying Tang22facc12016-10-20 17:43:59 +08001585 sap_upd_chan_spec_params(
1586 pBeaconStruct,
1587 &channelWidth,
1588 &secondaryChannelOffset,
1589 &vhtSupport, &centerFreq,
1590 &centerFreq_2);
1591
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001592 /* Processing for each tCsrScanResultInfo in the tCsrScanResult DLink list */
1593 for (chn_num = 0; chn_num < pSpectInfoParams->numSpectChans;
1594 chn_num++) {
1595
1596 /*
Himanshu Agarwalcf5b8932018-07-02 18:06:49 +05301597 * If the Beacon has channel ID, use it other wise we
1598 * will rely on the channelIdSelf
1599 */
1600 if (pScanResult->BssDescriptor.channelId == 0)
1601 channel_id =
1602 pScanResult->BssDescriptor.channelIdSelf;
1603 else
1604 channel_id =
1605 pScanResult->BssDescriptor.channelId;
1606
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001607 if (pSpectCh && (channel_id == pSpectCh->chNum)) {
1608 if (pSpectCh->rssiAgr <
1609 pScanResult->BssDescriptor.rssi)
1610 pSpectCh->rssiAgr =
1611 pScanResult->BssDescriptor.rssi;
1612
1613 ++pSpectCh->bssCount; /* Increment the count of BSS */
1614
1615 /*
1616 * Connsidering the Extension Channel
1617 * only in a channels
1618 */
1619 switch (operatingBand) {
1620 case eCSR_DOT11_MODE_11a:
1621 sap_interference_rssi_count_5G(
1622 pSpectCh, channelWidth,
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001623 secondaryChannelOffset,
1624 centerFreq,
1625 centerFreq_2,
Liangwei Dong71ed6502016-10-20 03:40:45 -04001626 channel_id,
1627 spectch_start,
1628 spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001629 break;
1630
1631 case eCSR_DOT11_MODE_11g:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001632 sap_interference_rssi_count(pSpectCh,
1633 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001634 break;
1635
1636 case eCSR_DOT11_MODE_abg:
Himanshu Agarwal4f503b82018-03-19 12:10:45 +05301637 if (pSpectCh->chNum >=
1638 SIR_11A_CHANNEL_BEGIN)
1639 sap_interference_rssi_count_5G(
1640 pSpectCh, channelWidth,
1641 secondaryChannelOffset,
1642 centerFreq,
1643 centerFreq_2,
1644 channel_id,
1645 spectch_start,
1646 spectch_end);
1647 else
1648 sap_interference_rssi_count(
1649 pSpectCh,
1650 spectch_start,
1651 spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001652 break;
1653 }
1654
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301655 QDF_TRACE(QDF_MODULE_ID_SAP,
1656 QDF_TRACE_LEVEL_INFO_HIGH,
Jeff Johnsona7c0ddb2017-09-18 08:14:12 -07001657 "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 -08001658 __func__,
1659 pScanResult->BssDescriptor.
1660 channelIdSelf,
1661 pScanResult->BssDescriptor.channelId,
1662 pScanResult->BssDescriptor.rssi,
1663 pSpectCh->bssCount, pScanResult,
1664 pSpectCh->channelWidth,
1665 secondaryChannelOffset, centerFreq);
1666 pSpectCh++;
1667 break;
1668 } else {
1669 pSpectCh++;
1670 }
1671 }
1672
1673 pScanResult = sme_scan_result_get_next(halHandle, pResult);
1674 }
1675
1676 /* Calculate the weights for all channels in the spectrum pSpectCh */
1677 pSpectCh = pSpectInfoParams->pSpectCh;
1678
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301679 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001680 "In %s, Spectrum Channels Weight", __func__);
1681
1682 for (chn_num = 0; chn_num < (pSpectInfoParams->numSpectChans);
1683 chn_num++) {
1684
1685 /*
1686 rssi : Maximum received signal strength among all BSS on that channel
1687 bssCount : Number of BSS on that channel
1688 */
1689
1690 rssi = (int8_t) pSpectCh->rssiAgr;
Himanshu Agarwal3697f942018-06-13 14:04:26 +05301691 if (ch_in_pcl(sap_ctx, pSpectCh->chNum))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001692 rssi -= PCL_RSSI_DISCOUNT;
1693
Himanshu Agarwal3697f942018-06-13 14:04:26 +05301694 if (rssi < SOFTAP_MIN_RSSI)
1695 rssi = SOFTAP_MIN_RSSI;
1696
Himanshu Agarwalfee2e362018-01-18 20:26:35 +05301697 if (pSpectCh->weight == SAP_ACS_WEIGHT_MAX)
1698 goto debug_info;
1699
gaurank kathpalia859c9362018-08-02 23:07:21 +05301700 /* There may be channels in scanlist, which were not sent to
1701 * FW for scanning as part of ACS scan list, but they do have an
1702 * effect on the neighbouring channels, so they help to find a
1703 * suitable channel, but there weight should be max as they were
1704 * and not meant to be included in the ACS scan results.
1705 * So just assign RSSI as -100, bsscount as 0, and weight as max
1706 * to them, so that they always stay low in sorting of best
1707 * channles which were included in ACS scan list
1708 */
1709 found = false;
1710 for (i = 0; i < sap_ctx->num_of_channel; i++) {
1711 if (pSpectCh->chNum == sap_ctx->channelList[i]) {
1712 /* Scan channel was included in ACS scan list */
1713 found = true;
1714 break;
1715 }
1716 }
1717
1718 if (found)
1719 pSpectCh->weight =
1720 SAPDFS_NORMALISE_1000 *
1721 (sapweight_rssi_count(sap_ctx, rssi,
1722 pSpectCh->bssCount) + sap_weight_channel_status(
1723 sap_ctx, sap_get_channel_status(pMac,
gaoleze5108942017-03-31 16:56:42 +08001724 pSpectCh->chNum)));
gaurank kathpalia859c9362018-08-02 23:07:21 +05301725 else {
1726 pSpectCh->weight = SAP_ACS_WEIGHT_MAX;
1727 pSpectCh->rssiAgr = SOFTAP_MIN_RSSI;
1728 rssi = SOFTAP_MIN_RSSI;
1729 pSpectCh->bssCount = SOFTAP_MIN_COUNT;
1730 }
1731
gaoleze5108942017-03-31 16:56:42 +08001732 if (pSpectCh->weight > SAP_ACS_WEIGHT_MAX)
1733 pSpectCh->weight = SAP_ACS_WEIGHT_MAX;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001734 pSpectCh->weight_copy = pSpectCh->weight;
1735
Himanshu Agarwalfee2e362018-01-18 20:26:35 +05301736debug_info:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001737 /* ------ Debug Info ------ */
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301738 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Himanshu Agarwal3697f942018-06-13 14:04:26 +05301739 "In %s, Chan=%d Weight= %d rssiAgr=%d rssi_pcl_discount: %d bssCount=%d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001740 __func__, pSpectCh->chNum, pSpectCh->weight,
Himanshu Agarwal3697f942018-06-13 14:04:26 +05301741 pSpectCh->rssiAgr, rssi, pSpectCh->bssCount);
wadesongcb0ded22018-02-02 17:57:20 +08001742 host_log_acs_chan_spect_weight(pSpectCh->chNum,
1743 (uint16_t)pSpectCh->weight,
1744 pSpectCh->rssiAgr,
1745 pSpectCh->bssCount);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001746 /* ------ Debug Info ------ */
1747 pSpectCh++;
1748 }
gaoleze5108942017-03-31 16:56:42 +08001749 sap_clear_channel_status(pMac);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301750 qdf_mem_free(pBeaconStruct);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001751}
1752
1753/*==========================================================================
1754 FUNCTION sap_chan_sel_exit
1755
1756 DESCRIPTION
1757 Exit function for free out the allocated memory, to be called
1758 at the end of the dfsSelectChannel function
1759
1760 DEPENDENCIES
1761 NA.
1762
1763 PARAMETERS
1764
1765 IN
1766 pSpectInfoParams : Pointer to the tSapChSelSpectInfo structure
1767
1768 RETURN VALUE
1769 void : NULL
1770
1771 SIDE EFFECTS
1772 ============================================================================*/
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001773static void sap_chan_sel_exit(tSapChSelSpectInfo *pSpectInfoParams)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001774{
1775 /* Free all the allocated memory */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301776 qdf_mem_free(pSpectInfoParams->pSpectCh);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001777}
1778
1779/*==========================================================================
1780 FUNCTION sap_sort_chl_weight
1781
1782 DESCRIPTION
Jeff Johnsonc7e4d162018-05-12 16:20:34 -07001783 Function to sort the channels with the least weight first for 20MHz channels
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001784
1785 DEPENDENCIES
1786 NA.
1787
1788 PARAMETERS
1789
1790 IN
1791 pSpectInfoParams : Pointer to the tSapChSelSpectInfo structure
1792
1793 RETURN VALUE
1794 void : NULL
1795
1796 SIDE EFFECTS
1797 ============================================================================*/
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001798static void sap_sort_chl_weight(tSapChSelSpectInfo *pSpectInfoParams)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001799{
1800 tSapSpectChInfo temp;
1801
1802 tSapSpectChInfo *pSpectCh = NULL;
1803 uint32_t i = 0, j = 0, minWeightIndex = 0;
1804
1805 pSpectCh = pSpectInfoParams->pSpectCh;
1806 for (i = 0; i < pSpectInfoParams->numSpectChans; i++) {
1807 minWeightIndex = i;
1808 for (j = i + 1; j < pSpectInfoParams->numSpectChans; j++) {
1809 if (pSpectCh[j].weight <
1810 pSpectCh[minWeightIndex].weight) {
1811 minWeightIndex = j;
Yeshwanth Sriram Guntuka273889e2018-02-16 17:11:46 +05301812 } else if (pSpectCh[j].weight ==
1813 pSpectCh[minWeightIndex].weight) {
1814 if (pSpectCh[j].bssCount <
1815 pSpectCh[minWeightIndex].bssCount)
1816 minWeightIndex = j;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001817 }
1818 }
1819 if (minWeightIndex != i) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301820 qdf_mem_copy(&temp, &pSpectCh[minWeightIndex],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001821 sizeof(*pSpectCh));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301822 qdf_mem_copy(&pSpectCh[minWeightIndex], &pSpectCh[i],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001823 sizeof(*pSpectCh));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301824 qdf_mem_copy(&pSpectCh[i], &temp, sizeof(*pSpectCh));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001825 }
1826 }
1827}
1828
1829/**
Jeff Johnsonc7e4d162018-05-12 16:20:34 -07001830 * set_ht80_chl_bit() - to set available channel to ht80 channel bitmap
bingse2782382017-03-23 10:34:52 +08001831 * @channel_bitmap: Pointer to the chan_bonding_bitmap structure
1832 * @spect_info_params: Pointer to the tSapChSelSpectInfo structure
1833 *
1834 * Return: none
1835 */
1836static void set_ht80_chl_bit(chan_bonding_bitmap *channel_bitmap,
1837 tSapChSelSpectInfo *spec_info_params)
1838{
1839 uint8_t i, j;
1840 tSapSpectChInfo *spec_info;
1841 int start_channel = 0;
1842
1843 channel_bitmap->chanBondingSet[0].startChannel =
1844 acs_ht80_channels[0].chStartNum;
1845 channel_bitmap->chanBondingSet[1].startChannel =
1846 acs_ht80_channels[1].chStartNum;
1847 channel_bitmap->chanBondingSet[2].startChannel =
1848 acs_ht80_channels[2].chStartNum;
1849 channel_bitmap->chanBondingSet[3].startChannel =
1850 acs_ht80_channels[3].chStartNum;
1851 channel_bitmap->chanBondingSet[4].startChannel =
1852 acs_ht80_channels[4].chStartNum;
1853 channel_bitmap->chanBondingSet[5].startChannel =
1854 acs_ht80_channels[5].chStartNum;
1855
1856 spec_info = spec_info_params->pSpectCh;
1857 for (j = 0; j < spec_info_params->numSpectChans; j++) {
1858 for (i = 0; i < MAX_80MHZ_BANDS; i++) {
1859 start_channel =
1860 channel_bitmap->chanBondingSet[i].startChannel;
1861 if (spec_info[j].chNum >= start_channel &&
1862 (spec_info[j].chNum <= start_channel + 12)) {
1863 channel_bitmap->chanBondingSet[i].channelMap |=
1864 1 << ((spec_info[j].chNum -
1865 start_channel)/4);
1866 break;
1867 }
1868 }
1869 }
1870}
1871
1872/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001873 * sap_sort_chl_weight_ht80() - to sort the channels with the least weight
1874 * @pSpectInfoParams: Pointer to the tSapChSelSpectInfo structure
1875 *
Jeff Johnsonc7e4d162018-05-12 16:20:34 -07001876 * Function to sort the channels with the least weight first for HT80 channels
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001877 *
1878 * Return: none
1879 */
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001880static void sap_sort_chl_weight_ht80(tSapChSelSpectInfo *pSpectInfoParams)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001881{
1882 uint8_t i, j, n;
1883 tSapSpectChInfo *pSpectInfo;
1884 uint8_t minIdx;
bingse2782382017-03-23 10:34:52 +08001885 int start_channel = 0;
1886 chan_bonding_bitmap *channel_bitmap;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001887
bingse2782382017-03-23 10:34:52 +08001888 channel_bitmap = qdf_mem_malloc(sizeof(chan_bonding_bitmap));
1889 if (NULL == channel_bitmap) {
1890 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG,
1891 "%s: Failed to allocate memory", __func__);
1892 return;
1893 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001894 pSpectInfo = pSpectInfoParams->pSpectCh;
1895 /* for each HT80 channel, calculate the combined weight of the
1896 four 20MHz weight */
1897 for (i = 0; i < ARRAY_SIZE(acs_ht80_channels); i++) {
1898 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
1899 if (pSpectInfo[j].chNum ==
1900 acs_ht80_channels[i].chStartNum)
1901 break;
1902 }
1903 if (j == pSpectInfoParams->numSpectChans)
1904 continue;
1905
1906 if (!(((pSpectInfo[j].chNum + 4) == pSpectInfo[j + 1].chNum) &&
1907 ((pSpectInfo[j].chNum + 8) ==
1908 pSpectInfo[j + 2].chNum) &&
1909 ((pSpectInfo[j].chNum + 12) ==
1910 pSpectInfo[j + 3].chNum))) {
1911 /*
1912 * some channels does not exist in pSectInfo array,
1913 * skip this channel and those in the same HT80 width
1914 */
1915 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 4;
1916 if ((pSpectInfo[j].chNum + 4) ==
1917 pSpectInfo[j + 1].chNum)
1918 pSpectInfo[j + 1].weight =
1919 SAP_ACS_WEIGHT_MAX * 4;
1920 if ((pSpectInfo[j].chNum + 8) ==
1921 pSpectInfo[j + 2].chNum)
1922 pSpectInfo[j + 2].weight =
1923 SAP_ACS_WEIGHT_MAX * 4;
1924 if ((pSpectInfo[j].chNum + 12) ==
1925 pSpectInfo[j + 3].chNum)
1926 pSpectInfo[j + 3].weight =
1927 SAP_ACS_WEIGHT_MAX * 4;
1928 continue;
1929 }
1930 /*found the channel, add the 4 adjacent channels' weight */
1931 acs_ht80_channels[i].weight = pSpectInfo[j].weight +
1932 pSpectInfo[j + 1].weight + pSpectInfo[j + 2].weight +
1933 pSpectInfo[j + 3].weight;
1934 /* find best channel among 4 channels as the primary channel */
1935 if ((pSpectInfo[j].weight + pSpectInfo[j + 1].weight) <
1936 (pSpectInfo[j + 2].weight + pSpectInfo[j + 3].weight)) {
1937 /* lower 2 channels are better choice */
1938 if (pSpectInfo[j].weight < pSpectInfo[j + 1].weight)
1939 minIdx = 0;
1940 else
1941 minIdx = 1;
1942 } else if (pSpectInfo[j + 2].weight <=
1943 pSpectInfo[j + 3].weight) {
1944 /* upper 2 channels are better choice */
1945 minIdx = 2;
1946 } else {
1947 minIdx = 3;
1948 }
1949
1950 /*
1951 * set all 4 channels to max value first, then reset the
1952 * best channel as the selected primary channel, update its
1953 * weightage with the combined weight value
1954 */
1955 for (n = 0; n < 4; n++)
1956 pSpectInfo[j + n].weight = SAP_ACS_WEIGHT_MAX * 4;
1957
1958 pSpectInfo[j + minIdx].weight = acs_ht80_channels[i].weight;
1959 }
1960
bingse2782382017-03-23 10:34:52 +08001961 /*
1962 * mark the weight of the channel that can't satisfy 80MHZ
1963 * as max value, so that it will be sorted to the bottom
1964 */
1965 set_ht80_chl_bit(channel_bitmap, pSpectInfoParams);
1966 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
1967 for (i = 0; i < MAX_80MHZ_BANDS; i++) {
1968 start_channel =
1969 channel_bitmap->chanBondingSet[i].startChannel;
1970 if (pSpectInfo[j].chNum >= start_channel &&
1971 (pSpectInfo[j].chNum <=
1972 start_channel + 12) &&
1973 channel_bitmap->chanBondingSet[i].channelMap !=
1974 SAP_80MHZ_MASK)
1975 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 4;
1976 }
1977 }
1978
Himanshu Agarwal75e74412018-02-01 20:51:47 +05301979 /*
1980 * Assign max weight(SAP_ACS_WEIGHT_MAX * 4) to 2.4 Ghz channels
1981 * and channel 165 as they cannot be part of a 80Mhz channel bonding.
1982 */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001983 pSpectInfo = pSpectInfoParams->pSpectCh;
1984 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
Himanshu Agarwal75e74412018-02-01 20:51:47 +05301985 if ((pSpectInfo[j].chNum >= WLAN_REG_CH_NUM(CHAN_ENUM_1) &&
1986 pSpectInfo[j].chNum <= WLAN_REG_CH_NUM(CHAN_ENUM_14)) ||
1987 (CHANNEL_165 == pSpectInfo[j].chNum))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001988 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 4;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001989 }
1990
Manishekar Chandrasekaran44e334f2016-05-30 16:42:50 +05301991 sap_sort_chl_weight(pSpectInfoParams);
1992
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001993 pSpectInfo = pSpectInfoParams->pSpectCh;
1994 for (j = 0; j < (pSpectInfoParams->numSpectChans); j++) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301995 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001996 FL("Channel=%d Weight= %d rssi=%d bssCount=%d"),
1997 pSpectInfo->chNum, pSpectInfo->weight,
1998 pSpectInfo->rssiAgr, pSpectInfo->bssCount);
1999 pSpectInfo++;
2000 }
bingse2782382017-03-23 10:34:52 +08002001 qdf_mem_free(channel_bitmap);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002002}
2003
2004/**
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07002005 * sap_sort_chl_weight_vht160() - to sort the channels with the least weight
2006 * @pSpectInfoParams: Pointer to the tSapChSelSpectInfo structure
2007 *
Jeff Johnsonc7e4d162018-05-12 16:20:34 -07002008 * Function to sort the channels with the least weight first for VHT160 channels
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07002009 *
2010 * Return: none
2011 */
Jeff Johnson464f7ea2016-10-07 10:21:26 -07002012static void sap_sort_chl_weight_vht160(tSapChSelSpectInfo *pSpectInfoParams)
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07002013{
2014 uint8_t i, j, n, idx;
2015 tSapSpectChInfo *pSpectInfo;
2016 uint8_t minIdx;
2017
2018 pSpectInfo = pSpectInfoParams->pSpectCh;
2019 /* for each VHT160 channel, calculate the combined weight of the
2020 8 20MHz weight */
2021 for (i = 0; i < ARRAY_SIZE(acs_vht160_channels); i++) {
2022 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
2023 if (pSpectInfo[j].chNum ==
2024 acs_vht160_channels[i].chStartNum)
2025 break;
2026 }
2027 if (j == pSpectInfoParams->numSpectChans)
2028 continue;
2029
2030 if (!(((pSpectInfo[j].chNum + 4) == pSpectInfo[j + 1].chNum) &&
2031 ((pSpectInfo[j].chNum + 8) ==
2032 pSpectInfo[j + 2].chNum) &&
2033 ((pSpectInfo[j].chNum + 12) ==
2034 pSpectInfo[j + 3].chNum) &&
2035 ((pSpectInfo[j].chNum + 16) ==
2036 pSpectInfo[j + 4].chNum) &&
2037 ((pSpectInfo[j].chNum + 20) ==
2038 pSpectInfo[j + 5].chNum) &&
2039 ((pSpectInfo[j].chNum + 24) ==
2040 pSpectInfo[j + 6].chNum) &&
2041 ((pSpectInfo[j].chNum + 28) ==
2042 pSpectInfo[j + 7].chNum))) {
2043 /*
2044 * some channels does not exist in pSectInfo array,
2045 * skip this channel and those in the same VHT160 width
2046 */
2047 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 8;
2048 if ((pSpectInfo[j].chNum + 4) ==
2049 pSpectInfo[j + 1].chNum)
2050 pSpectInfo[j + 1].weight =
2051 SAP_ACS_WEIGHT_MAX * 8;
2052 if ((pSpectInfo[j].chNum + 8) ==
2053 pSpectInfo[j + 2].chNum)
2054 pSpectInfo[j + 2].weight =
2055 SAP_ACS_WEIGHT_MAX * 8;
2056 if ((pSpectInfo[j].chNum + 12) ==
2057 pSpectInfo[j + 3].chNum)
2058 pSpectInfo[j + 3].weight =
2059 SAP_ACS_WEIGHT_MAX * 8;
2060 if ((pSpectInfo[j].chNum + 16) ==
2061 pSpectInfo[j + 4].chNum)
2062 pSpectInfo[j + 4].weight =
2063 SAP_ACS_WEIGHT_MAX * 8;
2064 if ((pSpectInfo[j].chNum + 20) ==
2065 pSpectInfo[j + 5].chNum)
2066 pSpectInfo[j + 5].weight =
2067 SAP_ACS_WEIGHT_MAX * 8;
2068 if ((pSpectInfo[j].chNum + 24) ==
2069 pSpectInfo[j + 6].chNum)
2070 pSpectInfo[j + 6].weight =
2071 SAP_ACS_WEIGHT_MAX * 8;
2072 if ((pSpectInfo[j].chNum + 28) ==
2073 pSpectInfo[j + 7].chNum)
2074 pSpectInfo[j + 7].weight =
2075 SAP_ACS_WEIGHT_MAX * 8;
2076 continue;
2077 }
2078 /*found the channel, add the 7 adjacent channels' weight */
2079 acs_vht160_channels[i].weight = pSpectInfo[j].weight +
2080 pSpectInfo[j + 1].weight + pSpectInfo[j + 2].weight +
2081 pSpectInfo[j + 3].weight + pSpectInfo[j + 4].weight +
2082 pSpectInfo[j + 5].weight + pSpectInfo[j + 6].weight +
2083 pSpectInfo[j + 7].weight;
2084
2085 /* find best channel among 8 channels as the primary channel */
2086 if ((pSpectInfo[j].weight + pSpectInfo[j + 1].weight +
2087 pSpectInfo[j + 2].weight + pSpectInfo[j + 3].weight) >
2088 (pSpectInfo[j + 4].weight + pSpectInfo[j + 5].weight +
2089 pSpectInfo[j + 6].weight + pSpectInfo[j + 7].weight))
2090 idx = 4;
2091 else
2092 idx = 0;
2093 /* find best channel among 4 channels as the primary channel */
2094 if ((pSpectInfo[j + idx].weight +
2095 pSpectInfo[j + idx + 1].weight) <
2096 (pSpectInfo[j + idx + 2].weight +
2097 pSpectInfo[j + idx + 3].weight)) {
2098 /* lower 2 channels are better choice */
2099 if (pSpectInfo[j + idx].weight <
2100 pSpectInfo[j + idx + 1].weight)
2101 minIdx = 0 + idx;
2102 else
2103 minIdx = 1 + idx;
2104 } else if (pSpectInfo[j + idx + 2].weight <=
2105 pSpectInfo[j + idx + 3].weight) {
2106 /* upper 2 channels are better choice */
2107 minIdx = 2 + idx;
2108 } else {
2109 minIdx = 3 + idx;
2110 }
2111
2112 /*
2113 * set all 8 channels to max value first, then reset the
2114 * best channel as the selected primary channel, update its
2115 * weightage with the combined weight value
2116 */
2117 for (n = 0; n < 8; n++)
2118 pSpectInfo[j + n].weight = SAP_ACS_WEIGHT_MAX * 8;
2119
2120 pSpectInfo[j + minIdx].weight = acs_vht160_channels[i].weight;
2121 }
2122
Himanshu Agarwal75e74412018-02-01 20:51:47 +05302123 /*
2124 * Assign max weight(SAP_ACS_WEIGHT_MAX * 8) to 2.4 Ghz channels
Kiran Kumar Lokere1a43bcf2018-05-15 15:51:58 -07002125 * and channel 132-173 as they cannot be part of a 160Mhz channel
Himanshu Agarwal75e74412018-02-01 20:51:47 +05302126 * bonding.
2127 */
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07002128 pSpectInfo = pSpectInfoParams->pSpectCh;
2129 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
Himanshu Agarwal75e74412018-02-01 20:51:47 +05302130 if ((pSpectInfo[j].chNum >= WLAN_REG_CH_NUM(CHAN_ENUM_1) &&
2131 pSpectInfo[j].chNum <= WLAN_REG_CH_NUM(CHAN_ENUM_14)) ||
2132 (pSpectInfo[j].chNum >= WLAN_REG_CH_NUM(CHAN_ENUM_132) &&
Kiran Kumar Lokere1a43bcf2018-05-15 15:51:58 -07002133 pSpectInfo[j].chNum <= WLAN_REG_CH_NUM(CHAN_ENUM_173)))
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07002134 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 8;
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07002135 }
2136
Manishekar Chandrasekaran44e334f2016-05-30 16:42:50 +05302137 sap_sort_chl_weight(pSpectInfoParams);
2138
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07002139 pSpectInfo = pSpectInfoParams->pSpectCh;
2140 for (j = 0; j < (pSpectInfoParams->numSpectChans); j++) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302141 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07002142 FL("Channel=%d Weight= %d rssi=%d bssCount=%d"),
2143 pSpectInfo->chNum, pSpectInfo->weight,
2144 pSpectInfo->rssiAgr, pSpectInfo->bssCount);
2145 pSpectInfo++;
2146 }
2147}
2148
2149/**
Himanshu Agarwal91c5c0f2018-02-13 14:40:56 +05302150 * sap_allocate_max_weight_ht40_24_g() - allocate max weight for 40Mhz
2151 * to all 2.4Ghz channels
2152 * @spect_info_params: Pointer to the tSapChSelSpectInfo structure
2153 *
2154 * Return: none
2155 */
2156static void sap_allocate_max_weight_ht40_24_g(
2157 tSapChSelSpectInfo *spect_info_params)
2158{
2159 tSapSpectChInfo *spect_info;
2160 uint8_t j;
2161
2162 /*
2163 * Assign max weight for 40Mhz (SAP_ACS_WEIGHT_MAX * 2) to all
2164 * 2.4 Ghz channels
2165 */
2166 spect_info = spect_info_params->pSpectCh;
2167 for (j = 0; j < spect_info_params->numSpectChans; j++) {
2168 if ((spect_info[j].chNum >= WLAN_REG_CH_NUM(CHAN_ENUM_1) &&
2169 spect_info[j].chNum <= WLAN_REG_CH_NUM(CHAN_ENUM_14)))
2170 spect_info[j].weight = SAP_ACS_WEIGHT_MAX * 2;
2171 }
2172}
2173
2174/**
2175 * sap_allocate_max_weight_ht40_5_g() - allocate max weight for 40Mhz
2176 * to all 5Ghz channels
2177 * @spect_info_params: Pointer to the tSapChSelSpectInfo structure
2178 *
2179 * Return: none
2180 */
2181static void sap_allocate_max_weight_ht40_5_g(
2182 tSapChSelSpectInfo *spect_info_params)
2183{
2184 tSapSpectChInfo *spect_info;
2185 uint8_t j;
2186
2187 /*
2188 * Assign max weight for 40Mhz (SAP_ACS_WEIGHT_MAX * 2) to all
2189 * 5 Ghz channels
2190 */
2191 spect_info = spect_info_params->pSpectCh;
2192 for (j = 0; j < spect_info_params->numSpectChans; j++) {
2193 if ((spect_info[j].chNum >= WLAN_REG_CH_NUM(CHAN_ENUM_36) &&
Kiran Kumar Lokere1a43bcf2018-05-15 15:51:58 -07002194 spect_info[j].chNum <= WLAN_REG_CH_NUM(CHAN_ENUM_173)))
Himanshu Agarwal91c5c0f2018-02-13 14:40:56 +05302195 spect_info[j].weight = SAP_ACS_WEIGHT_MAX * 2;
2196 }
2197}
2198
2199/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002200 * sap_sort_chl_weight_ht40_24_g() - to sort channel with the least weight
2201 * @pSpectInfoParams: Pointer to the tSapChSelSpectInfo structure
2202 *
Jeff Johnsonc7e4d162018-05-12 16:20:34 -07002203 * Function to sort the channels with the least weight first for HT40 channels
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002204 *
2205 * Return: none
2206 */
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002207static void sap_sort_chl_weight_ht40_24_g(tSapChSelSpectInfo *pSpectInfoParams,
2208 v_REGDOMAIN_t domain)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002209{
2210 uint8_t i, j;
2211 tSapSpectChInfo *pSpectInfo;
2212 uint32_t tmpWeight1, tmpWeight2;
bingse2782382017-03-23 10:34:52 +08002213 uint32_t ht40plus2gendch = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002214
2215 pSpectInfo = pSpectInfoParams->pSpectCh;
2216 /*
2217 * for each HT40 channel, calculate the combined weight of the
2218 * two 20MHz weight
2219 */
2220 for (i = 0; i < ARRAY_SIZE(acs_ht40_channels24_g); i++) {
2221 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
2222 if (pSpectInfo[j].chNum ==
2223 acs_ht40_channels24_g[i].chStartNum)
2224 break;
2225 }
2226 if (j == pSpectInfoParams->numSpectChans)
2227 continue;
2228
2229 if (!((pSpectInfo[j].chNum + 4) == pSpectInfo[j + 4].chNum)) {
2230 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2;
2231 continue;
2232 }
2233 /*
2234 * check if there is another channel combination possiblity
2235 * e.g., {1, 5} & {5, 9}
2236 */
2237 if ((pSpectInfo[j + 4].chNum + 4) == pSpectInfo[j + 8].chNum) {
2238 /* need to compare two channel pairs */
2239 tmpWeight1 = pSpectInfo[j].weight +
2240 pSpectInfo[j + 4].weight;
2241 tmpWeight2 = pSpectInfo[j + 4].weight +
2242 pSpectInfo[j + 8].weight;
2243 if (tmpWeight1 <= tmpWeight2) {
2244 if (pSpectInfo[j].weight <=
2245 pSpectInfo[j + 4].weight) {
2246 pSpectInfo[j].weight =
2247 tmpWeight1;
2248 pSpectInfo[j + 4].weight =
2249 SAP_ACS_WEIGHT_MAX * 2;
2250 pSpectInfo[j + 8].weight =
2251 SAP_ACS_WEIGHT_MAX * 2;
2252 } else {
2253 pSpectInfo[j + 4].weight =
2254 tmpWeight1;
2255 /* for secondary channel selection */
2256 pSpectInfo[j].weight =
2257 SAP_ACS_WEIGHT_MAX * 2
2258 - 1;
2259 pSpectInfo[j + 8].weight =
2260 SAP_ACS_WEIGHT_MAX * 2;
2261 }
2262 } else {
2263 if (pSpectInfo[j + 4].weight <=
2264 pSpectInfo[j + 8].weight) {
2265 pSpectInfo[j + 4].weight =
2266 tmpWeight2;
2267 pSpectInfo[j].weight =
2268 SAP_ACS_WEIGHT_MAX * 2;
2269 /* for secondary channel selection */
2270 pSpectInfo[j + 8].weight =
2271 SAP_ACS_WEIGHT_MAX * 2
2272 - 1;
2273 } else {
2274 pSpectInfo[j + 8].weight =
2275 tmpWeight2;
2276 pSpectInfo[j].weight =
2277 SAP_ACS_WEIGHT_MAX * 2;
2278 pSpectInfo[j + 4].weight =
2279 SAP_ACS_WEIGHT_MAX * 2;
2280 }
2281 }
2282 } else {
bingsaa6f96a2017-09-11 09:49:43 +08002283 tmpWeight1 = pSpectInfo[j].weight_copy +
2284 pSpectInfo[j + 4].weight_copy;
2285 if (pSpectInfo[j].weight_copy <=
2286 pSpectInfo[j + 4].weight_copy) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002287 pSpectInfo[j].weight = tmpWeight1;
2288 pSpectInfo[j + 4].weight =
2289 SAP_ACS_WEIGHT_MAX * 2;
2290 } else {
2291 pSpectInfo[j + 4].weight = tmpWeight1;
2292 pSpectInfo[j].weight =
2293 SAP_ACS_WEIGHT_MAX * 2;
2294 }
2295 }
2296 }
bingse2782382017-03-23 10:34:52 +08002297 /*
2298 * Every channel should be checked. Add the check for the omissive
2299 * channel. Mark the channel whose combination can't satisfy 40MHZ
2300 * as max value, so that it will be sorted to the bottom.
2301 */
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002302 if (REGDOMAIN_FCC == domain)
bingse2782382017-03-23 10:34:52 +08002303 ht40plus2gendch = HT40PLUS_2G_FCC_CH_END;
2304 else
2305 ht40plus2gendch = HT40PLUS_2G_EURJAP_CH_END;
2306 for (i = HT40MINUS_2G_CH_START; i <= ht40plus2gendch; i++) {
2307 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
2308 if (pSpectInfo[j].chNum == i &&
2309 ((pSpectInfo[j].chNum + 4) !=
2310 pSpectInfo[j+4].chNum) &&
2311 ((pSpectInfo[j].chNum - 4) !=
2312 pSpectInfo[j-4].chNum))
2313 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2;
2314 }
2315 }
2316 for (i = ht40plus2gendch + 1; i <= HT40MINUS_2G_CH_END; i++) {
2317 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
2318 if (pSpectInfo[j].chNum == i &&
2319 (pSpectInfo[j].chNum - 4) !=
2320 pSpectInfo[j-4].chNum)
2321 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2;
2322 }
2323 }
Himanshu Agarwal91c5c0f2018-02-13 14:40:56 +05302324
2325 pSpectInfo = pSpectInfoParams->pSpectCh;
2326 for (j = 0; j < (pSpectInfoParams->numSpectChans); j++) {
2327 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2328 "In %s, Channel=%d Weight= %d rssi=%d bssCount=%d",
2329 __func__, pSpectInfo->chNum, pSpectInfo->weight,
2330 pSpectInfo->rssiAgr, pSpectInfo->bssCount);
2331 pSpectInfo++;
2332 }
2333
Manishekar Chandrasekaran44e334f2016-05-30 16:42:50 +05302334 sap_sort_chl_weight(pSpectInfoParams);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002335}
2336
2337/*==========================================================================
2338 FUNCTION sap_sort_chl_weight_ht40_5_g
2339
2340 DESCRIPTION
Jeff Johnsonc7e4d162018-05-12 16:20:34 -07002341 Function to sort the channels with the least weight first for HT40 channels
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002342
2343 DEPENDENCIES
2344 NA.
2345
2346 PARAMETERS
2347
2348 IN
2349 pSpectInfoParams : Pointer to the tSapChSelSpectInfo structure
2350
2351 RETURN VALUE
2352 void : NULL
2353
2354 SIDE EFFECTS
2355 ============================================================================*/
Jeff Johnson464f7ea2016-10-07 10:21:26 -07002356static void sap_sort_chl_weight_ht40_5_g(tSapChSelSpectInfo *pSpectInfoParams)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002357{
2358 uint8_t i, j;
2359 tSapSpectChInfo *pSpectInfo;
2360
2361 pSpectInfo = pSpectInfoParams->pSpectCh;
2362 /*for each HT40 channel, calculate the combined weight of the
2363 two 20MHz weight */
2364 for (i = 0; i < ARRAY_SIZE(acs_ht40_channels5_g); i++) {
2365 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
2366 if (pSpectInfo[j].chNum ==
2367 acs_ht40_channels5_g[i].chStartNum)
2368 break;
2369 }
2370 if (j == pSpectInfoParams->numSpectChans)
2371 continue;
2372
2373 /* found the channel, add the two adjacent channels' weight */
2374 if ((pSpectInfo[j].chNum + 4) == pSpectInfo[j + 1].chNum) {
2375 acs_ht40_channels5_g[i].weight = pSpectInfo[j].weight +
2376 pSpectInfo[j + 1].weight;
2377 /* select better of the adjact channel as the primary channel */
2378 if (pSpectInfo[j].weight <= pSpectInfo[j + 1].weight) {
2379 pSpectInfo[j].weight =
2380 acs_ht40_channels5_g[i].weight;
2381 /* mark the adjacent channel's weight as max value so
2382 that it will be sorted to the bottom */
2383 pSpectInfo[j + 1].weight =
2384 SAP_ACS_WEIGHT_MAX * 2;
2385 } else {
2386 pSpectInfo[j + 1].weight =
2387 acs_ht40_channels5_g[i].weight;
2388 /* mark the adjacent channel's weight as max value so
2389 that it will be sorted to the bottom */
2390 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2;
2391 }
2392
2393 } else
2394 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2;
2395 }
2396
bingse2782382017-03-23 10:34:52 +08002397 /*
2398 *Every channel should be checked. Add the check for the omissive
2399 * channel. Mark the channel whose combination can't satisfy 40MHZ
2400 * as max value, so that it will be sorted to the bottom
2401 */
2402 for (j = 1; j < pSpectInfoParams->numSpectChans; j++) {
2403 for (i = 0; i < ARRAY_SIZE(acs_ht40_channels5_g); i++) {
2404 if (pSpectInfo[j].chNum ==
2405 (acs_ht40_channels5_g[i].chStartNum +
2406 4) &&
2407 pSpectInfo[j - 1].chNum !=
2408 acs_ht40_channels5_g[i].chStartNum) {
2409 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2;
2410 break;
2411 }
2412 }
2413 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002414 /* avoid channel 165 by setting its weight to max */
2415 pSpectInfo = pSpectInfoParams->pSpectCh;
2416 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
2417 if (CHANNEL_165 == pSpectInfo[j].chNum) {
2418 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2;
2419 break;
2420 }
2421 }
2422
2423 pSpectInfo = pSpectInfoParams->pSpectCh;
2424 for (j = 0; j < (pSpectInfoParams->numSpectChans); j++) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302425 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002426 "In %s, Channel=%d Weight= %d rssi=%d bssCount=%d",
2427 __func__, pSpectInfo->chNum, pSpectInfo->weight,
2428 pSpectInfo->rssiAgr, pSpectInfo->bssCount);
2429 pSpectInfo++;
2430 }
2431
2432 sap_sort_chl_weight(pSpectInfoParams);
2433}
2434
2435/*==========================================================================
2436 FUNCTION sap_sort_chl_weight_all
2437
2438 DESCRIPTION
Jeff Johnsonc7e4d162018-05-12 16:20:34 -07002439 Function to sort the channels with the least weight first
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002440
2441 DEPENDENCIES
2442 NA.
2443
2444 PARAMETERS
2445
2446 IN
Jeff Johnsone13d8062017-09-28 06:54:55 -07002447 sap_ctx : Pointer to the struct sap_context *structure
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002448 pSpectInfoParams : Pointer to the tSapChSelSpectInfo structure
2449
2450 RETURN VALUE
2451 void : NULL
2452
2453 SIDE EFFECTS
2454 ============================================================================*/
Jeff Johnsone13d8062017-09-28 06:54:55 -07002455static void sap_sort_chl_weight_all(struct sap_context *sap_ctx,
Jeff Johnson464f7ea2016-10-07 10:21:26 -07002456 tSapChSelSpectInfo *pSpectInfoParams,
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002457 uint32_t operatingBand,
2458 v_REGDOMAIN_t domain)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002459{
2460 tSapSpectChInfo *pSpectCh = NULL;
2461 uint32_t j = 0;
2462#ifndef SOFTAP_CHANNEL_RANGE
2463 uint32_t i = 0;
2464#endif
2465
2466 pSpectCh = pSpectInfoParams->pSpectCh;
2467#ifdef SOFTAP_CHANNEL_RANGE
2468
Jeff Johnsone13d8062017-09-28 06:54:55 -07002469 switch (sap_ctx->acs_cfg->ch_width) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002470 case CH_WIDTH_40MHZ:
Himanshu Agarwal91c5c0f2018-02-13 14:40:56 +05302471 /*
2472 * Assign max weight to all 5Ghz channels when operating band
2473 * is 11g and to all 2.4Ghz channels when operating band is 11a
2474 * or 11abg to avoid selection in ACS algorithm for starting SAP
2475 */
2476 if (eCSR_DOT11_MODE_11g == operatingBand) {
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002477 sap_sort_chl_weight_ht40_24_g(pSpectInfoParams, domain);
Himanshu Agarwal91c5c0f2018-02-13 14:40:56 +05302478 sap_allocate_max_weight_ht40_5_g(pSpectInfoParams);
2479 } else {
2480 sap_allocate_max_weight_ht40_24_g(pSpectInfoParams);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002481 sap_sort_chl_weight_ht40_5_g(pSpectInfoParams);
2482 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002483 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002484 case CH_WIDTH_80MHZ:
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07002485 case CH_WIDTH_80P80MHZ:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002486 sap_sort_chl_weight_ht80(pSpectInfoParams);
2487 break;
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07002488 case CH_WIDTH_160MHZ:
2489 sap_sort_chl_weight_vht160(pSpectInfoParams);
2490 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002491 case CH_WIDTH_20MHZ:
2492 default:
2493 /* Sorting the channels as per weights as 20MHz channels */
2494 sap_sort_chl_weight(pSpectInfoParams);
2495 }
2496
2497#else
2498 /* Sorting the channels as per weights */
2499 for (i = 0; i < SPECT_24GHZ_CH_COUNT; i++) {
2500 minWeightIndex = i;
2501 for (j = i + 1; j < SPECT_24GHZ_CH_COUNT; j++) {
2502 if (pSpectCh[j].weight <
2503 pSpectCh[minWeightIndex].weight) {
2504 minWeightIndex = j;
2505 }
2506 }
2507 if (minWeightIndex != i) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302508 qdf_mem_copy(&temp, &pSpectCh[minWeightIndex],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002509 sizeof(*pSpectCh));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302510 qdf_mem_copy(&pSpectCh[minWeightIndex], &pSpectCh[i],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002511 sizeof(*pSpectCh));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302512 qdf_mem_copy(&pSpectCh[i], &temp, sizeof(*pSpectCh));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002513 }
2514 }
2515#endif
2516
2517 /* For testing */
Ravi Joshi9788fcd2018-02-13 15:12:22 -08002518 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002519 "In %s, Sorted Spectrum Channels Weight", __func__);
2520 pSpectCh = pSpectInfoParams->pSpectCh;
2521 for (j = 0; j < (pSpectInfoParams->numSpectChans); j++) {
Ravi Joshi9788fcd2018-02-13 15:12:22 -08002522 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002523 "In %s, Channel=%d Weight= %d rssi=%d bssCount=%d",
2524 __func__, pSpectCh->chNum, pSpectCh->weight,
2525 pSpectCh->rssiAgr, pSpectCh->bssCount);
2526 pSpectCh++;
2527 }
2528
2529}
2530
Naveen Rawatbec64d92017-09-13 14:35:21 -07002531/**
2532 * sap_is_ch_non_overlap() - returns true if non-overlapping channel
2533 * @sap_ctx: Sap context
2534 * @ch: channel number
2535 *
2536 * Returns: true if non-overlapping (1, 6, 11) channel, false otherwise
2537 */
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -07002538static bool sap_is_ch_non_overlap(struct sap_context *sap_ctx, uint16_t ch)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002539{
Naveen Rawatbec64d92017-09-13 14:35:21 -07002540 if (sap_ctx->enableOverLapCh)
Srinivas Girigowda74a66d62017-06-21 23:28:25 -07002541 return true;
Naveen Rawatbec64d92017-09-13 14:35:21 -07002542
2543 if ((ch == CHANNEL_1) || (ch == CHANNEL_6) || (ch == CHANNEL_11))
Srinivas Girigowda74a66d62017-06-21 23:28:25 -07002544 return true;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002545
Srinivas Girigowda74a66d62017-06-21 23:28:25 -07002546 return false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002547}
2548
Dustin Brown0ce56d32016-10-17 16:18:03 -07002549#ifdef FEATURE_WLAN_CH_AVOID
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002550/**
2551 * sap_select_channel_no_scan_result() - select SAP channel when no scan results
2552 * are available.
2553 * @sap_ctx: Sap context
2554 *
2555 * Returns: channel number if success, 0 otherwise
2556 */
Kondabattini, Ganesh13bb4b12016-09-04 16:16:53 +05302557static uint8_t sap_select_channel_no_scan_result(tHalHandle hal,
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -07002558 struct sap_context *sap_ctx)
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002559{
Mohit Khanna841044f2016-03-25 16:16:24 -07002560 enum channel_state ch_type;
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002561 uint8_t i, first_safe_ch_in_range = SAP_CHANNEL_NOT_SELECTED;
Kondabattini, Ganesh13bb4b12016-09-04 16:16:53 +05302562 uint32_t dfs_master_cap_enabled;
Dustin Brown0ce56d32016-10-17 16:18:03 -07002563 uint32_t start_ch_num = sap_ctx->acs_cfg->start_ch;
2564 uint32_t end_ch_num = sap_ctx->acs_cfg->end_ch;
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002565 tpAniSirGlobal mac_ctx = NULL;
2566
2567 mac_ctx = PMAC_STRUCT(hal);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002568
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002569 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2570 FL("start - end: %d - %d"), start_ch_num, end_ch_num);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002571
Kondabattini, Ganesh13bb4b12016-09-04 16:16:53 +05302572 sme_cfg_get_int(hal, WNI_CFG_DFS_MASTER_ENABLED,
2573 &dfs_master_cap_enabled);
2574
2575 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2576 "%s: dfs_master %x", __func__, dfs_master_cap_enabled);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002577
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002578 /* get a channel in PCL and within the range */
2579 for (i = 0; i < sap_ctx->acs_cfg->pcl_ch_count; i++) {
2580 if ((sap_ctx->acs_cfg->pcl_channels[i] < start_ch_num) ||
2581 (sap_ctx->acs_cfg->pcl_channels[i] > end_ch_num))
2582 continue;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002583
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002584 first_safe_ch_in_range = sap_ctx->acs_cfg->pcl_channels[i];
2585 break;
2586 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002587
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002588 if (SAP_CHANNEL_NOT_SELECTED != first_safe_ch_in_range)
2589 return first_safe_ch_in_range;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002590
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002591 for (i = 0; i < NUM_CHANNELS; i++) {
2592 if ((safe_channels[i].channelNumber < start_ch_num) ||
2593 (safe_channels[i].channelNumber > end_ch_num))
2594 continue;
2595
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002596 ch_type = wlan_reg_get_channel_state(mac_ctx->pdev,
2597 safe_channels[i].channelNumber);
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002598
2599 if ((ch_type == CHANNEL_STATE_DISABLE) ||
2600 (ch_type == CHANNEL_STATE_INVALID))
2601 continue;
Kondabattini, Ganesh13bb4b12016-09-04 16:16:53 +05302602 if ((!dfs_master_cap_enabled) &&
2603 (CHANNEL_STATE_DFS == ch_type)) {
2604 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2605 "%s: DFS master mode disabled. Skip DFS channel %d",
2606 __func__, safe_channels[i].channelNumber);
2607 continue;
2608 }
Agrawal Ashish65634612016-08-18 13:24:32 +05302609 if ((sap_ctx->dfs_mode == ACS_DFS_MODE_DISABLE) &&
2610 (CHANNEL_STATE_DFS == ch_type))
2611 continue;
Kondabattini, Ganesh13bb4b12016-09-04 16:16:53 +05302612
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002613 if (safe_channels[i].isSafe == true) {
2614 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2615 FL("channel %d in the configuration is safe"),
2616 safe_channels[i].channelNumber);
2617 first_safe_ch_in_range = safe_channels[i].channelNumber;
2618 break;
2619 }
2620
2621 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2622 FL("channel %d in the configuration is unsafe"),
2623 safe_channels[i].channelNumber);
2624 }
2625
2626 /* if no channel selected return SAP_CHANNEL_NOT_SELECTED */
2627 return first_safe_ch_in_range;
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002628}
Dustin Brown0ce56d32016-10-17 16:18:03 -07002629#else
2630static uint8_t sap_select_channel_no_scan_result(tHalHandle hal,
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -07002631 struct sap_context *sap_ctx)
Dustin Brown0ce56d32016-10-17 16:18:03 -07002632{
2633 uint32_t start_ch_num = sap_ctx->acs_cfg->start_ch;
2634
2635 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2636 FL("start - end: %d - %d"),
2637 start_ch_num,
2638 sap_ctx->acs_cfg->end_ch);
2639
2640 sap_ctx->acs_cfg->pri_ch = start_ch_num;
2641 sap_ctx->acs_cfg->ht_sec_ch = 0;
2642
2643 /* pick the first channel in configured range */
2644 return start_ch_num;
2645}
2646#endif /* FEATURE_WLAN_CH_AVOID */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002647
2648/**
2649 * sap_select_channel() - select SAP channel
2650 * @hal: Pointer to HAL handle
2651 * @sap_ctx: Sap context
2652 * @scan_result: Pointer to tScanResultHandle
2653 *
2654 * Runs a algorithm to select the best channel to operate in based on BSS
2655 * rssi and bss count on each channel
2656 *
2657 * Returns: channel number if success, 0 otherwise
2658 */
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -07002659uint8_t sap_select_channel(tHalHandle hal, struct sap_context *sap_ctx,
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002660 tScanResultHandle scan_result)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002661{
2662 /* DFS param object holding all the data req by the algo */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002663 tSapChSelSpectInfo spect_info_obj = { NULL, 0 };
2664 tSapChSelSpectInfo *spect_info = &spect_info_obj;
2665 uint8_t best_ch_num = SAP_CHANNEL_NOT_SELECTED;
bingse2782382017-03-23 10:34:52 +08002666 uint32_t ht40plus2gendch = 0;
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002667 v_REGDOMAIN_t domain;
Arif Hussain21ad4342017-12-21 12:00:54 -08002668 uint8_t country[CDS_COUNTRY_CODE_LEN + 1];
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002669#ifdef SOFTAP_CHANNEL_RANGE
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002670 uint8_t count;
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002671 uint32_t start_ch_num, end_ch_num, tmp_ch_num, operating_band = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002672#endif
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002673 tpAniSirGlobal mac_ctx;
2674
2675 mac_ctx = PMAC_STRUCT(hal);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302676 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002677 "In %s, Running SAP Ch Select", __func__);
2678
2679#ifdef FEATURE_WLAN_CH_AVOID
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002680 sap_update_unsafe_channel_list(hal, sap_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002681#endif
2682
gaoleze5108942017-03-31 16:56:42 +08002683 /*
2684 * If ACS weight is not enabled on noise_floor/channel_free/tx_power,
2685 * then skip acs process if no bss found.
2686 */
2687 if (NULL == scan_result &&
2688 !(sap_ctx->auto_channel_select_weight & 0xffff00)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302689 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002690 FL("No external AP present"));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002691
2692#ifndef SOFTAP_CHANNEL_RANGE
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002693 return SAP_CHANNEL_NOT_SELECTED;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002694#else
Kondabattini, Ganesh13bb4b12016-09-04 16:16:53 +05302695 return sap_select_channel_no_scan_result(hal, sap_ctx);
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002696#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002697 }
2698
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002699 /* Initialize the structure pointed by spect_info */
Srinivas Girigowda74a66d62017-06-21 23:28:25 -07002700 if (sap_chan_sel_init(hal, spect_info, sap_ctx) != true) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302701 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002702 FL("Ch Select initialization failed"));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002703 return SAP_CHANNEL_NOT_SELECTED;
2704 }
2705 /* Compute the weight of the entire spectrum in the operating band */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002706 sap_compute_spect_weight(spect_info, hal, scan_result, sap_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002707
2708#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
2709 /* process avoid channel IE to collect all channels to avoid */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002710 sap_process_avoid_ie(hal, sap_ctx, scan_result, spect_info);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002711#endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
2712
Paul Zhang0f85b412018-01-18 19:14:51 +08002713 wlan_reg_read_current_country(mac_ctx->psoc, country);
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002714 wlan_reg_get_domain_from_country_code(&domain, country, SOURCE_DRIVER);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002715#ifdef SOFTAP_CHANNEL_RANGE
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002716 start_ch_num = sap_ctx->acs_cfg->start_ch;
2717 end_ch_num = sap_ctx->acs_cfg->end_ch;
2718 SET_ACS_BAND(operating_band, sap_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002719
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002720 sap_ctx->acsBestChannelInfo.channelNum = 0;
2721 sap_ctx->acsBestChannelInfo.weight = SAP_ACS_WEIGHT_MAX;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002722
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002723 /* Sort the ch lst as per the computed weights, lesser weight first. */
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002724 sap_sort_chl_weight_all(sap_ctx, spect_info, operating_band, domain);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002725
2726 /*Loop till get the best channel in the given range */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002727 for (count = 0; count < spect_info->numSpectChans; count++) {
2728 if ((start_ch_num > spect_info->pSpectCh[count].chNum) ||
2729 (end_ch_num < spect_info->pSpectCh[count].chNum))
2730 continue;
2731
2732 if (best_ch_num == SAP_CHANNEL_NOT_SELECTED) {
2733 best_ch_num = spect_info->pSpectCh[count].chNum;
2734 /* check if best_ch_num is in preferred channel list */
2735 best_ch_num =
2736 sap_select_preferred_channel_from_channel_list(
2737 best_ch_num, sap_ctx, spect_info);
2738 /* if not in preferred ch lst, go to nxt best ch */
2739 if (best_ch_num == SAP_CHANNEL_NOT_SELECTED)
2740 continue;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002741
2742#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002743 /*
2744 * Weight of the channels(device's AP is operating)
Jeff Johnson2cc31fd2018-05-05 23:54:23 -07002745 * increased to MAX+1 so that they will be chosen only
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002746 * when there is no other best channel to choose
2747 */
2748 if (sap_check_in_avoid_ch_list(sap_ctx, best_ch_num)) {
2749 best_ch_num = SAP_CHANNEL_NOT_SELECTED;
2750 continue;
2751 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002752#endif
2753
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002754 sap_ctx->acsBestChannelInfo.channelNum = best_ch_num;
2755 sap_ctx->acsBestChannelInfo.weight =
2756 spect_info->pSpectCh[count].weight_copy;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002757 }
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002758
2759 if (best_ch_num == SAP_CHANNEL_NOT_SELECTED)
2760 continue;
2761
Tushnim Bhattacharyya03103fd2017-06-23 10:48:52 -07002762 if (operating_band != eCSR_DOT11_MODE_11g) {
2763 QDF_TRACE(QDF_MODULE_ID_SAP,
2764 QDF_TRACE_LEVEL_INFO_HIGH,
2765 "operating_band %d", operating_band);
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002766 continue;
Tushnim Bhattacharyya03103fd2017-06-23 10:48:52 -07002767 }
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002768
2769 /* Give preference to Non-overlap channels */
Naveen Rawatbec64d92017-09-13 14:35:21 -07002770 if (false == sap_is_ch_non_overlap(sap_ctx,
Tushnim Bhattacharyya03103fd2017-06-23 10:48:52 -07002771 spect_info->pSpectCh[count].chNum)) {
2772 QDF_TRACE(QDF_MODULE_ID_SAP,
2773 QDF_TRACE_LEVEL_INFO_HIGH,
Naveen Rawatbec64d92017-09-13 14:35:21 -07002774 FL("ch: %d skipped as its overlapping ch"),
2775 spect_info->pSpectCh[count].chNum);
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002776 continue;
Tushnim Bhattacharyya03103fd2017-06-23 10:48:52 -07002777 }
2778
2779 if (wlan_reg_is_dfs_ch(mac_ctx->pdev,
2780 spect_info->pSpectCh[count].chNum) &&
2781 policy_mgr_disallow_mcc(mac_ctx->psoc,
2782 spect_info->pSpectCh[count].chNum)) {
2783 QDF_TRACE(QDF_MODULE_ID_SAP,
2784 QDF_TRACE_LEVEL_INFO_HIGH,
2785 "No DFS MCC");
2786 continue;
2787 }
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002788
bings14d1d3b2017-08-03 11:14:29 +08002789 if (spect_info->pSpectCh[count].weight_copy >
2790 sap_ctx->acsBestChannelInfo.weight)
2791 continue;
2792
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002793 tmp_ch_num = spect_info->pSpectCh[count].chNum;
gaoleze5108942017-03-31 16:56:42 +08002794 tmp_ch_num = sap_channel_in_acs_channel_list(
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002795 tmp_ch_num, sap_ctx, spect_info);
2796 if (tmp_ch_num == SAP_CHANNEL_NOT_SELECTED)
2797 continue;
2798
2799 best_ch_num = tmp_ch_num;
2800 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002801 }
2802#else
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002803 /* Sort the ch lst as per the computed weights, lesser weight first. */
2804 sap_sort_chl_weight_all(sap_ctx, hal, spect_info);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002805 /* Get the first channel in sorted array as best 20M Channel */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002806 best_ch_num = (uint8_t) spect_info->pSpectCh[0].chNum;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002807 /* Select Best Channel from Channel List if Configured */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002808 best_ch_num = sap_select_preferred_channel_from_channel_list(
2809 best_ch_num, sap_ctx, spect_info);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002810#endif
2811
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002812 /*
2813 * in case the best channel seleted is not in PCL and there is another
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002814 * channel which has same weightage and is in PCL, choose the one in
2815 * PCL
2816 */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002817 for (count = 0; count < spect_info->numSpectChans; count++) {
2818 if (!ch_in_pcl(sap_ctx, spect_info->pSpectCh[count].chNum) ||
2819 (spect_info->pSpectCh[count].weight !=
2820 sap_ctx->acsBestChannelInfo.weight))
2821 continue;
2822
2823 if (sap_select_preferred_channel_from_channel_list(
2824 spect_info->pSpectCh[count].chNum, sap_ctx, spect_info)
2825 == SAP_CHANNEL_NOT_SELECTED)
2826 continue;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002827
2828#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002829 if (sap_check_in_avoid_ch_list(sap_ctx, best_ch_num))
2830 continue;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002831#endif
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002832 best_ch_num = spect_info->pSpectCh[count].chNum;
2833 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2834 FL("change best channel to %d in PCL"), best_ch_num);
2835 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002836 }
2837
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002838 sap_ctx->acs_cfg->pri_ch = best_ch_num;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002839 /* determine secondary channel for 2.4G channel 5, 6, 7 in HT40 */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002840 if ((operating_band != eCSR_DOT11_MODE_11g) ||
2841 (sap_ctx->acs_cfg->ch_width != CH_WIDTH_40MHZ))
2842 goto sap_ch_sel_end;
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002843 if (REGDOMAIN_FCC == domain)
bingse2782382017-03-23 10:34:52 +08002844 ht40plus2gendch = HT40PLUS_2G_FCC_CH_END;
2845 else
2846 ht40plus2gendch = HT40PLUS_2G_EURJAP_CH_END;
2847 if ((best_ch_num >= HT40MINUS_2G_CH_START) &&
2848 (best_ch_num <= ht40plus2gendch)) {
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002849 int weight_below, weight_above, i;
2850 tSapSpectChInfo *pspect_info;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002851
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002852 weight_below = weight_above = SAP_ACS_WEIGHT_MAX;
2853 pspect_info = spect_info->pSpectCh;
2854 for (i = 0; i < spect_info->numSpectChans; i++) {
2855 if (pspect_info[i].chNum == (best_ch_num - 4))
2856 weight_below = pspect_info[i].weight;
2857 if (pspect_info[i].chNum == (best_ch_num + 4))
2858 weight_above = pspect_info[i].weight;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002859 }
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002860
2861 if (weight_below < weight_above)
2862 sap_ctx->acs_cfg->ht_sec_ch =
2863 sap_ctx->acs_cfg->pri_ch - 4;
2864 else
2865 sap_ctx->acs_cfg->ht_sec_ch =
2866 sap_ctx->acs_cfg->pri_ch + 4;
2867 } else if (best_ch_num >= 1 && best_ch_num <= 4) {
2868 sap_ctx->acs_cfg->ht_sec_ch = sap_ctx->acs_cfg->pri_ch + 4;
bingse2782382017-03-23 10:34:52 +08002869 } else if (best_ch_num >= ht40plus2gendch && best_ch_num <=
2870 HT40MINUS_2G_CH_END) {
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002871 sap_ctx->acs_cfg->ht_sec_ch = sap_ctx->acs_cfg->pri_ch - 4;
2872 } else if (best_ch_num == 14) {
2873 sap_ctx->acs_cfg->ht_sec_ch = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002874 }
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002875 sap_ctx->secondary_ch = sap_ctx->acs_cfg->ht_sec_ch;
2876
2877sap_ch_sel_end:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002878 /* Free all the allocated memory */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002879 sap_chan_sel_exit(spect_info);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002880
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302881 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002882 FL("Running SAP Ch select Completed, Ch=%d"), best_ch_num);
wadesongcb0ded22018-02-02 17:57:20 +08002883 host_log_acs_best_chan(best_ch_num, sap_ctx->acsBestChannelInfo.weight);
2884
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002885 if (best_ch_num > 0 && best_ch_num <= 252)
2886 return best_ch_num;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002887 else
2888 return SAP_CHANNEL_NOT_SELECTED;
2889}