blob: 7812ecaf12593e22dfa5ee09e0191f4211463648 [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
Jeff Johnson7730fbb2018-11-08 13:48:27 -0800311 * @mac_handle: opaque handle to the MAC context
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800312 * @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 */
Jeff Johnson7730fbb2018-11-08 13:48:27 -0800324static void sap_process_avoid_ie(mac_handle_t mac_handle,
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
Jeff Johnson7730fbb2018-11-08 13:48:27 -0800337 mac_ctx = PMAC_STRUCT(mac_handle);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800338 spect_ch = spect_info->pSpectCh;
Jeff Johnson7730fbb2018-11-08 13:48:27 -0800339 node = sme_scan_result_get_first(mac_handle, scan_result);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800340
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) {
Jeff Johnson7730fbb2018-11-08 13:48:27 -0800354 node = sme_scan_result_get_next(mac_handle,
Will Huang55ba1042017-03-22 10:43:30 +0800355 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) */
Jeff Johnson7730fbb2018-11-08 13:48:27 -0800388 node = sme_scan_result_get_next(mac_handle, scan_result);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800389 }
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 Johnson7730fbb2018-11-08 13:48:27 -0800409void sap_update_unsafe_channel_list(mac_handle_t mac_handle,
410 struct sap_context *sap_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800411{
412 uint16_t i, j;
Amar Singhalb8d4f152016-02-10 10:21:43 -0800413 uint16_t unsafe_channel_list[NUM_CHANNELS];
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800414 uint16_t unsafe_channel_count = 0;
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -0700415 tpAniSirGlobal mac_ctx = NULL;
416
Yuanyuan Liu0e0aa932016-05-12 10:17:58 -0700417 qdf_device_t qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800418
Yuanyuan Liu97361182016-06-06 09:38:04 -0700419 if (!qdf_ctx) {
420 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_FATAL,
421 "qdf_ctx is NULL");
422 return;
423 }
Jeff Johnson7730fbb2018-11-08 13:48:27 -0800424 mac_ctx = PMAC_STRUCT(mac_handle);
Yuanyuan Liu97361182016-06-06 09:38:04 -0700425
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800426 /* Flush, default set all channel safe */
Amar Singhalb8d4f152016-02-10 10:21:43 -0800427 for (i = 0; i < NUM_CHANNELS; i++) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800428 safe_channels[i].isSafe = true;
429 }
430
431 /* Try to find unsafe channel */
Ryan Hsu4252a2f2016-01-05 11:18:24 -0800432#if defined(FEATURE_WLAN_STA_AP_MODE_DFS_DISABLE)
Amar Singhalb8d4f152016-02-10 10:21:43 -0800433 for (i = 0; i < NUM_CHANNELS; i++) {
Jeff Johnsone13d8062017-09-28 06:54:55 -0700434 if (sap_ctx->dfs_ch_disable == true) {
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -0700435 if (wlan_reg_is_dfs_ch(mac_ctx->pdev,
436 safe_channels[i].channelNumber)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800437 safe_channels[i].isSafe = false;
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530438 QDF_TRACE(QDF_MODULE_ID_SAP,
439 QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800440 "%s: DFS Ch %d is not safe in"
441 " Concurrent mode",
442 __func__,
443 safe_channels[i].channelNumber);
444 }
445 }
446 }
447#endif
Yuanyuan Liu0e0aa932016-05-12 10:17:58 -0700448 pld_get_wlan_unsafe_channel(qdf_ctx->dev,
449 unsafe_channel_list,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800450 &unsafe_channel_count,
451 sizeof(unsafe_channel_list));
452
453 for (i = 0; i < unsafe_channel_count; i++) {
Amar Singhalb8d4f152016-02-10 10:21:43 -0800454 for (j = 0; j < NUM_CHANNELS; j++) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800455 if (safe_channels[j].channelNumber ==
456 unsafe_channel_list[i]) {
457 /* Found unsafe channel, update it */
458 safe_channels[j].isSafe = false;
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530459 QDF_TRACE(QDF_MODULE_ID_SAP,
460 QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800461 FL("CH %d is not safe"),
462 unsafe_channel_list[i]);
463 break;
464 }
465 }
466 }
467
468 return;
469}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800470
471#endif /* FEATURE_WLAN_CH_AVOID */
472
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800473/**
gaoleze5108942017-03-31 16:56:42 +0800474 * sap_channel_in_acs_channel_list() - check if channel in acs channel list
475 * @channel_num: channel to check
476 * @sap_ctx: struct ptSapContext
477 * @spect_info_params: strcut tSapChSelSpectInfo
478 *
479 * This function checks if specified channel is in the configured ACS channel
480 * list.
481 *
482 * Return: channel number if in acs channel list or SAP_CHANNEL_NOT_SELECTED
483 */
gaoleze5108942017-03-31 16:56:42 +0800484uint8_t sap_channel_in_acs_channel_list(uint8_t channel_num,
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -0700485 struct sap_context *sap_ctx,
gaoleze5108942017-03-31 16:56:42 +0800486 tSapChSelSpectInfo *spect_info_params)
487{
488 uint8_t i = 0;
489
490 if ((NULL == sap_ctx->acs_cfg->ch_list) ||
491 (NULL == spect_info_params))
492 return channel_num;
493
494 if (channel_num > 0 && channel_num <= 252) {
495 for (i = 0; i < sap_ctx->acs_cfg->ch_list_count; i++) {
496 if ((sap_ctx->acs_cfg->ch_list[i]) == channel_num)
497 return channel_num;
498 }
499 return SAP_CHANNEL_NOT_SELECTED;
500 } else {
501 return SAP_CHANNEL_NOT_SELECTED;
502 }
503}
504
505/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800506 * sap_select_preferred_channel_from_channel_list() - to calc best cahnnel
507 * @best_chnl: best channel already calculated among all the chanels
508 * @sap_ctx: sap context
509 * @spectinfo_param: Pointer to tSapChSelSpectInfo structure
510 *
511 * This function calculates the best channel among the configured channel list.
512 * If channel list not configured then returns the best channel calculated
513 * among all the channel list.
514 *
515 * Return: uint8_t best channel
516 */
Jeff Johnson464f7ea2016-10-07 10:21:26 -0700517static
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800518uint8_t sap_select_preferred_channel_from_channel_list(uint8_t best_chnl,
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -0700519 struct sap_context *sap_ctx,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800520 tSapChSelSpectInfo *spectinfo_param)
521{
522 uint8_t i = 0;
Tushnim Bhattacharyya518e80f2017-08-30 17:35:33 -0700523 tpAniSirGlobal mac_ctx = sme_get_mac_context();
524
525 if (NULL == mac_ctx) {
526 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
527 "pmac Global Context is NULL");
528 return SAP_CHANNEL_NOT_SELECTED;
529 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800530
531 /*
532 * If Channel List is not Configured don't do anything
533 * Else return the Best Channel from the Channel List
534 */
535 if ((NULL == sap_ctx->acs_cfg->ch_list) ||
536 (NULL == spectinfo_param) ||
537 (0 == sap_ctx->acs_cfg->ch_list_count))
538 return best_chnl;
539
540 if (best_chnl <= 0 || best_chnl > 252)
541 return SAP_CHANNEL_NOT_SELECTED;
542
543 /* Select the best channel from allowed list */
544 for (i = 0; i < sap_ctx->acs_cfg->ch_list_count; i++) {
Tushnim Bhattacharyya518e80f2017-08-30 17:35:33 -0700545 if ((sap_ctx->acs_cfg->ch_list[i] == best_chnl) &&
546 !(wlan_reg_is_dfs_ch(mac_ctx->pdev, best_chnl) &&
547 policy_mgr_disallow_mcc(mac_ctx->psoc, best_chnl))) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530548 QDF_TRACE(QDF_MODULE_ID_SAP,
Ravi Joshi9788fcd2018-02-13 15:12:22 -0800549 QDF_TRACE_LEVEL_INFO,
Naveen Rawatbec64d92017-09-13 14:35:21 -0700550 "Best channel so far is: %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800551 best_chnl);
552 return best_chnl;
553 }
554 }
555
556 return SAP_CHANNEL_NOT_SELECTED;
557}
558
Jeff Johnson7730fbb2018-11-08 13:48:27 -0800559/**
560 * sap_chan_sel_init() - Initialize channel select
561 * @mac_handle: Opaque handle to the global MAC context
562 * @pSpectInfoParams: Pointer to tSapChSelSpectInfo structure
563 * @sap_ctx: Pointer to SAP Context
564 *
565 * Function sap_chan_sel_init allocates the memory, initializes the
566 * structures used by the channel selection algorithm
567 *
568 * Return: bool Success or FAIL
569 */
570static bool sap_chan_sel_init(mac_handle_t mac_handle,
Jeff Johnson464f7ea2016-10-07 10:21:26 -0700571 tSapChSelSpectInfo *pSpectInfoParams,
Jeff Johnsone13d8062017-09-28 06:54:55 -0700572 struct sap_context *sap_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800573{
574 tSapSpectChInfo *pSpectCh = NULL;
575 uint8_t *pChans = NULL;
576 uint16_t channelnum = 0;
Jeff Johnsonb9794442018-11-22 14:21:08 -0800577 tpAniSirGlobal mac = PMAC_STRUCT(mac_handle);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800578 bool chSafe = true;
579#ifdef FEATURE_WLAN_CH_AVOID
580 uint16_t i;
581#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800582 bool include_dfs_ch = true;
Himanshu Agarwalfee2e362018-01-18 20:26:35 +0530583 uint8_t chan_num;
Bala Venkatesh2f25c812017-12-15 17:42:12 +0530584 bool sta_sap_scc_on_dfs_chan =
Jeff Johnsonb9794442018-11-22 14:21:08 -0800585 policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan(mac->psoc);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800586
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530587 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, "In %s",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800588 __func__);
589
590 pSpectInfoParams->numSpectChans =
Jeff Johnsonb9794442018-11-22 14:21:08 -0800591 mac->scan.base_channels.numChannels;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800592
593 /* Allocate memory for weight computation of 2.4GHz */
Arif Hussain256cc282018-10-03 14:10:44 -0700594 pSpectCh = qdf_mem_malloc((pSpectInfoParams->numSpectChans) *
595 sizeof(*pSpectCh));
596 if (!pSpectCh)
Srinivas Girigowda74a66d62017-06-21 23:28:25 -0700597 return false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800598
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800599 /* Initialize the pointers in the DfsParams to the allocated memory */
600 pSpectInfoParams->pSpectCh = pSpectCh;
601
Jeff Johnsonb9794442018-11-22 14:21:08 -0800602 pChans = mac->scan.base_channels.channelList;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800603
Ryan Hsu4252a2f2016-01-05 11:18:24 -0800604#if defined(FEATURE_WLAN_STA_AP_MODE_DFS_DISABLE)
Jeff Johnsone13d8062017-09-28 06:54:55 -0700605 if (sap_ctx->dfs_ch_disable == true)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800606 include_dfs_ch = false;
607#endif
Jeff Johnsonb9794442018-11-22 14:21:08 -0800608 if (!mac->mlme_cfg->dfs_cfg.dfs_master_capable ||
Jeff Johnsone13d8062017-09-28 06:54:55 -0700609 ACS_DFS_MODE_DISABLE == sap_ctx->dfs_mode)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800610 include_dfs_ch = false;
611
612 /* Fill the channel number in the spectrum in the operating freq band */
613 for (channelnum = 0;
614 channelnum < pSpectInfoParams->numSpectChans;
Edhar, Mahesh Kumar4f660672015-10-30 11:53:26 +0530615 channelnum++, pChans++, pSpectCh++) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800616 chSafe = true;
617
Himanshu Agarwal052ce252018-06-18 17:18:59 +0530618 pSpectCh->chNum = *pChans;
619 /* Initialise for all channels */
620 pSpectCh->rssiAgr = SOFTAP_MIN_RSSI;
621 /* Initialise 20MHz for all the Channels */
622 pSpectCh->channelWidth = SOFTAP_HT20_CHANNELWIDTH;
623 /* Initialise max ACS weight for all channels */
624 pSpectCh->weight = SAP_ACS_WEIGHT_MAX;
625
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800626 /* check if the channel is in NOL blacklist */
Himanshu Agarwal052ce252018-06-18 17:18:59 +0530627 if (sap_dfs_is_channel_in_nol_list(
628 sap_ctx, *pChans,
629 PHY_SINGLE_CHANNEL_CENTERED)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530630 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800631 "In %s, Ch %d is in NOL list", __func__,
632 *pChans);
633 chSafe = false;
634 continue;
635 }
636
Bala Venkatesh2f25c812017-12-15 17:42:12 +0530637 if (!include_dfs_ch || sta_sap_scc_on_dfs_chan) {
Jeff Johnsonb9794442018-11-22 14:21:08 -0800638 if (wlan_reg_is_dfs_ch(mac->pdev, *pChans)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800639 chSafe = false;
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530640 QDF_TRACE(QDF_MODULE_ID_SAP,
641 QDF_TRACE_LEVEL_INFO_HIGH,
Bala Venkatesh2f25c812017-12-15 17:42:12 +0530642 "In %s, DFS Ch %d not considered for ACS. include_dfs_ch %u, sta_sap_scc_on_dfs_chan %d",
643 __func__, *pChans, include_dfs_ch,
644 sta_sap_scc_on_dfs_chan);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800645 continue;
646 }
647 }
648
649#ifdef FEATURE_WLAN_CH_AVOID
Amar Singhalb8d4f152016-02-10 10:21:43 -0800650 for (i = 0; i < NUM_CHANNELS; i++) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800651 if ((safe_channels[i].channelNumber == *pChans) &&
652 (false == safe_channels[i].isSafe)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530653 QDF_TRACE(QDF_MODULE_ID_SAP,
654 QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800655 "In %s, Ch %d is not safe", __func__,
656 *pChans);
657 chSafe = false;
658 break;
659 }
660 }
661#endif /* FEATURE_WLAN_CH_AVOID */
662
663 /* OFDM rates are not supported on channel 14 */
664 if (*pChans == 14 &&
Jeff Johnsone13d8062017-09-28 06:54:55 -0700665 eCSR_DOT11_MODE_11b != sap_ctx->csr_roamProfile.phyMode) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800666 continue;
667 }
668
Deepthi Gowri48b89332016-08-30 18:43:05 +0530669 /* Skip DSRC channels */
Jeff Johnsonb9794442018-11-22 14:21:08 -0800670 if (wlan_reg_is_dsrc_chan(mac->pdev, *pChans))
Kiran Kumar Lokere1a43bcf2018-05-15 15:51:58 -0700671 continue;
672
Jeff Johnsonb9794442018-11-22 14:21:08 -0800673 if (!mac->sap.enable_etsi13_srd_chan_support &&
674 wlan_reg_is_etsi13_srd_chan(mac->pdev, *pChans))
Deepthi Gowri48b89332016-08-30 18:43:05 +0530675 continue;
676
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800677 if (true == chSafe) {
Srinivas Girigowda74a66d62017-06-21 23:28:25 -0700678 pSpectCh->valid = true;
Himanshu Agarwalfee2e362018-01-18 20:26:35 +0530679 for (chan_num = 0; chan_num < sap_ctx->num_of_channel;
680 chan_num++) {
681 if (pSpectCh->chNum !=
682 sap_ctx->channelList[chan_num])
683 continue;
684
685 /*
686 * Initialize ACS weight to 0 for channels
687 * present in sap context scan channel list
688 */
689 pSpectCh->weight = 0;
690 break;
691 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800692 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800693 }
Srinivas Girigowda74a66d62017-06-21 23:28:25 -0700694 return true;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800695}
696
gaoleze5108942017-03-31 16:56:42 +0800697/**
698 * sapweight_rssi_count() - calculates the channel weight due to rssi
Anurag Chouhan6d760662016-02-20 16:05:43 +0530699 and data count(here number of BSS observed)
gaoleze5108942017-03-31 16:56:42 +0800700 * @sap_ctx : Softap context
701 * @rssi : Max signal strength receieved from a BSS for the channel
702 * @count : Number of BSS observed in the channel
703 *
704 * Return: uint32_t Calculated channel weight based on above two
705 */
706static
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -0700707uint32_t sapweight_rssi_count(struct sap_context *sap_ctx, int8_t rssi,
gaoleze5108942017-03-31 16:56:42 +0800708 uint16_t count)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800709{
710 int32_t rssiWeight = 0;
711 int32_t countWeight = 0;
712 uint32_t rssicountWeight = 0;
gaoleze5108942017-03-31 16:56:42 +0800713 uint8_t softap_rssi_weight_cfg, softap_count_weight_cfg;
714 uint8_t softap_rssi_weight_local, softap_count_weight_local;
715
716 softap_rssi_weight_cfg =
717 ACS_WEIGHT_SOFTAP_RSSI_CFG(sap_ctx->auto_channel_select_weight);
718
719 softap_count_weight_cfg =
720 ACS_WEIGHT_SOFTAP_COUNT_CFG(sap_ctx->auto_channel_select_weight);
721
722 softap_rssi_weight_local =
723 ACS_WEIGHT_CFG_TO_LOCAL(sap_ctx->auto_channel_select_weight,
724 softap_rssi_weight_cfg);
725
726 softap_count_weight_local =
727 ACS_WEIGHT_CFG_TO_LOCAL(sap_ctx->auto_channel_select_weight,
728 softap_count_weight_cfg);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800729
730 /* Weight from RSSI */
gaoleze5108942017-03-31 16:56:42 +0800731 rssiWeight = ACS_WEIGHT_COMPUTE(sap_ctx->auto_channel_select_weight,
732 softap_rssi_weight_cfg,
733 rssi - SOFTAP_MIN_RSSI,
734 SOFTAP_MAX_RSSI - SOFTAP_MIN_RSSI);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800735
gaoleze5108942017-03-31 16:56:42 +0800736 if (rssiWeight > softap_rssi_weight_local)
737 rssiWeight = softap_rssi_weight_local;
738
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800739 else if (rssiWeight < 0)
740 rssiWeight = 0;
741
742 /* Weight from data count */
gaoleze5108942017-03-31 16:56:42 +0800743 countWeight = ACS_WEIGHT_COMPUTE(sap_ctx->auto_channel_select_weight,
744 softap_count_weight_cfg,
745 count - SOFTAP_MIN_COUNT,
746 SOFTAP_MAX_COUNT - SOFTAP_MIN_COUNT);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800747
gaoleze5108942017-03-31 16:56:42 +0800748 if (countWeight > softap_count_weight_local)
749 countWeight = softap_count_weight_local;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800750
751 rssicountWeight = rssiWeight + countWeight;
752
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530753 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800754 "In %s, rssiWeight=%d, countWeight=%d, rssicountWeight=%d",
755 __func__, rssiWeight, countWeight, rssicountWeight);
756
757 return rssicountWeight;
758}
759
760/**
gaoleze5108942017-03-31 16:56:42 +0800761 * sap_get_channel_status() - get channel info via channel number
762 * @p_mac: Pointer to Global MAC structure
763 * @channel_id: channel id
764 *
765 * Return: chan status info
766 */
767static struct lim_channel_status *sap_get_channel_status
768 (tpAniSirGlobal p_mac, uint32_t channel_id)
769{
770 return csr_get_channel_status(p_mac, channel_id);
771}
772
773/**
774 * sap_clear_channel_status() - clear chan info
775 * @p_mac: Pointer to Global MAC structure
776 *
777 * Return: none
778 */
779static void sap_clear_channel_status(tpAniSirGlobal p_mac)
780{
781 csr_clear_channel_status(p_mac);
782}
783
784/**
785 * sap_weight_channel_noise_floor() - compute noise floor weight
786 * @sap_ctx: sap context
787 * @chn_stat: Pointer to chan status info
788 *
789 * Return: channel noise floor weight
790 */
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -0700791static uint32_t sap_weight_channel_noise_floor(struct sap_context *sap_ctx,
gaoleze5108942017-03-31 16:56:42 +0800792 struct lim_channel_status
793 *channel_stat)
794{
795 uint32_t noise_floor_weight;
796 uint8_t softap_nf_weight_cfg;
797 uint8_t softap_nf_weight_local;
798
799 softap_nf_weight_cfg =
800 ACS_WEIGHT_SOFTAP_NOISE_FLOOR_CFG
801 (sap_ctx->auto_channel_select_weight);
802
803 softap_nf_weight_local =
804 ACS_WEIGHT_CFG_TO_LOCAL(sap_ctx->auto_channel_select_weight,
805 softap_nf_weight_cfg);
806
807 if (channel_stat == NULL || channel_stat->channelfreq == 0) {
Srinivas Girigowda80213e52018-01-23 14:51:33 -0800808 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG,
gaoleze5108942017-03-31 16:56:42 +0800809 "In %s, sanity check failed return max weight",
810 __func__);
811 return softap_nf_weight_local;
812 }
813
814 noise_floor_weight = (channel_stat->noise_floor == 0) ? 0 :
815 (ACS_WEIGHT_COMPUTE(
816 sap_ctx->auto_channel_select_weight,
817 softap_nf_weight_cfg,
818 channel_stat->noise_floor -
819 SOFTAP_MIN_NF,
820 SOFTAP_MAX_NF - SOFTAP_MIN_NF));
821
822 if (noise_floor_weight > softap_nf_weight_local)
823 noise_floor_weight = softap_nf_weight_local;
gaoleze5108942017-03-31 16:56:42 +0800824
825 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
826 "In %s, nf=%d, nfwc=%d, nfwl=%d, nfw=%d",
827 __func__, channel_stat->noise_floor,
828 softap_nf_weight_cfg, softap_nf_weight_local,
829 noise_floor_weight);
830
831 return noise_floor_weight;
832}
833
834/**
835 * sap_weight_channel_free() - compute channel free weight
836 * @sap_ctx: sap context
837 * @chn_stat: Pointer to chan status info
838 *
839 * Return: channel free weight
840 */
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -0700841static uint32_t sap_weight_channel_free(struct sap_context *sap_ctx,
gaoleze5108942017-03-31 16:56:42 +0800842 struct lim_channel_status
843 *channel_stat)
844{
845 uint32_t channel_free_weight;
846 uint8_t softap_channel_free_weight_cfg;
847 uint8_t softap_channel_free_weight_local;
848 uint32_t rx_clear_count = 0;
849 uint32_t cycle_count = 0;
850
851 softap_channel_free_weight_cfg =
852 ACS_WEIGHT_SOFTAP_CHANNEL_FREE_CFG
853 (sap_ctx->auto_channel_select_weight);
854
855 softap_channel_free_weight_local =
856 ACS_WEIGHT_CFG_TO_LOCAL(sap_ctx->auto_channel_select_weight,
857 softap_channel_free_weight_cfg);
858
859 if (channel_stat == NULL || channel_stat->channelfreq == 0) {
Srinivas Girigowda80213e52018-01-23 14:51:33 -0800860 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG,
gaoleze5108942017-03-31 16:56:42 +0800861 "In %s, sanity check failed return max weight",
862 __func__);
863 return softap_channel_free_weight_local;
864 }
865
866 rx_clear_count = channel_stat->rx_clear_count -
867 channel_stat->tx_frame_count -
868 channel_stat->rx_frame_count;
869 cycle_count = channel_stat->cycle_count;
870
871 /* LSH 4, otherwise it is always 0. */
872 channel_free_weight = (cycle_count == 0) ? 0 :
873 (ACS_WEIGHT_COMPUTE(
874 sap_ctx->auto_channel_select_weight,
875 softap_channel_free_weight_cfg,
876 ((rx_clear_count << 8) +
877 (cycle_count >> 1))/cycle_count -
878 (SOFTAP_MIN_CHNFREE << 8),
879 (SOFTAP_MAX_CHNFREE -
880 SOFTAP_MIN_CHNFREE) << 8));
881
882 if (channel_free_weight > softap_channel_free_weight_local)
883 channel_free_weight = softap_channel_free_weight_local;
884
885 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
886 "In %s, rcc=%d, cc=%d, tc=%d, rc=%d, cfwc=%d, cfwl=%d, cfw=%d",
887 __func__, rx_clear_count, cycle_count,
888 channel_stat->tx_frame_count,
889 channel_stat->rx_frame_count,
890 softap_channel_free_weight_cfg,
891 softap_channel_free_weight_local,
892 channel_free_weight);
893
894 return channel_free_weight;
895}
896
897/**
898 * sap_weight_channel_txpwr_range() - compute channel tx power range weight
899 * @sap_ctx: sap context
900 * @chn_stat: Pointer to chan status info
901 *
902 * Return: tx power range weight
903 */
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -0700904static uint32_t sap_weight_channel_txpwr_range(struct sap_context *sap_ctx,
gaoleze5108942017-03-31 16:56:42 +0800905 struct lim_channel_status
906 *channel_stat)
907{
908 uint32_t txpwr_weight_low_speed;
909 uint8_t softap_txpwr_range_weight_cfg;
910 uint8_t softap_txpwr_range_weight_local;
911
912 softap_txpwr_range_weight_cfg =
913 ACS_WEIGHT_SOFTAP_TX_POWER_RANGE_CFG
914 (sap_ctx->auto_channel_select_weight);
915
916 softap_txpwr_range_weight_local =
917 ACS_WEIGHT_CFG_TO_LOCAL(sap_ctx->auto_channel_select_weight,
918 softap_txpwr_range_weight_cfg);
919
920 if (channel_stat == NULL || channel_stat->channelfreq == 0) {
Srinivas Girigowda80213e52018-01-23 14:51:33 -0800921 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG,
gaoleze5108942017-03-31 16:56:42 +0800922 "In %s, sanity check failed return max weight",
923 __func__);
924 return softap_txpwr_range_weight_local;
925 }
926
927 txpwr_weight_low_speed = (channel_stat->chan_tx_pwr_range == 0) ? 0 :
928 (ACS_WEIGHT_COMPUTE(
929 sap_ctx->auto_channel_select_weight,
930 softap_txpwr_range_weight_cfg,
931 SOFTAP_MAX_TXPWR -
932 channel_stat->chan_tx_pwr_range,
933 SOFTAP_MAX_TXPWR - SOFTAP_MIN_TXPWR));
934
935 if (txpwr_weight_low_speed > softap_txpwr_range_weight_local)
936 txpwr_weight_low_speed = softap_txpwr_range_weight_local;
937
938 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
939 "In %s, tpr=%d, tprwc=%d, tprwl=%d, tprw=%d",
940 __func__, channel_stat->chan_tx_pwr_range,
941 softap_txpwr_range_weight_cfg,
942 softap_txpwr_range_weight_local,
943 txpwr_weight_low_speed);
944
945 return txpwr_weight_low_speed;
946}
947
948/**
949 * sap_weight_channel_txpwr_tput() - compute channel tx power
950 * throughput weight
951 * @sap_ctx: sap context
952 * @chn_stat: Pointer to chan status info
953 *
954 * Return: tx power throughput weight
955 */
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -0700956static uint32_t sap_weight_channel_txpwr_tput(struct sap_context *sap_ctx,
gaoleze5108942017-03-31 16:56:42 +0800957 struct lim_channel_status
958 *channel_stat)
959{
960 uint32_t txpwr_weight_high_speed;
961 uint8_t softap_txpwr_tput_weight_cfg;
962 uint8_t softap_txpwr_tput_weight_local;
963
964 softap_txpwr_tput_weight_cfg =
965 ACS_WEIGHT_SOFTAP_TX_POWER_THROUGHPUT_CFG
966 (sap_ctx->auto_channel_select_weight);
967
968 softap_txpwr_tput_weight_local =
969 ACS_WEIGHT_CFG_TO_LOCAL(sap_ctx->auto_channel_select_weight,
970 softap_txpwr_tput_weight_cfg);
971
972 if (channel_stat == NULL || channel_stat->channelfreq == 0) {
Srinivas Girigowda80213e52018-01-23 14:51:33 -0800973 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG,
gaoleze5108942017-03-31 16:56:42 +0800974 "In %s, sanity check failed return max weight",
975 __func__);
976 return softap_txpwr_tput_weight_local;
977 }
978
979 txpwr_weight_high_speed = (channel_stat->chan_tx_pwr_throughput == 0)
980 ? 0 : (ACS_WEIGHT_COMPUTE(
981 sap_ctx->auto_channel_select_weight,
982 softap_txpwr_tput_weight_cfg,
983 SOFTAP_MAX_TXPWR -
984 channel_stat->chan_tx_pwr_throughput,
985 SOFTAP_MAX_TXPWR - SOFTAP_MIN_TXPWR));
986
987 if (txpwr_weight_high_speed > softap_txpwr_tput_weight_local)
988 txpwr_weight_high_speed = softap_txpwr_tput_weight_local;
989
990 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
991 "In %s, tpt=%d, tptwc=%d, tptwl=%d, tptw=%d",
992 __func__, channel_stat->chan_tx_pwr_throughput,
993 softap_txpwr_tput_weight_cfg,
994 softap_txpwr_tput_weight_local,
995 txpwr_weight_high_speed);
996
997 return txpwr_weight_high_speed;
998}
999
1000/**
1001 * sap_weight_channel_status() - compute chan status weight
1002 * @sap_ctx: sap context
1003 * @chn_stat: Pointer to chan status info
1004 *
1005 * Return: chan status weight
1006 */
1007static
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -07001008uint32_t sap_weight_channel_status(struct sap_context *sap_ctx,
gaoleze5108942017-03-31 16:56:42 +08001009 struct lim_channel_status *channel_stat)
1010{
1011 return sap_weight_channel_noise_floor(sap_ctx, channel_stat) +
1012 sap_weight_channel_free(sap_ctx, channel_stat) +
1013 sap_weight_channel_txpwr_range(sap_ctx, channel_stat) +
1014 sap_weight_channel_txpwr_tput(sap_ctx, channel_stat);
1015}
1016
1017/**
Yeshwanth Sriram Guntuka273889e2018-02-16 17:11:46 +05301018 * sap_check_channels_same_band() - Check if two channels belong to same band
1019 * @ch_num1: channel number
1020 * @ch_num2: channel number
1021 *
1022 * Return: true if both channels belong to same band else false
1023 */
1024static bool sap_check_channels_same_band(uint16_t ch_num1, uint16_t ch_num2)
1025{
1026 if ((ch_num1 <= SIR_11B_CHANNEL_END &&
1027 ch_num2 <= SIR_11B_CHANNEL_END) ||
1028 (ch_num1 >= SIR_11A_CHANNEL_BEGIN &&
1029 ch_num2 >= SIR_11A_CHANNEL_BEGIN))
Srinivas Girigowdaeff16d92018-09-12 14:56:29 -07001030 return true;
Yeshwanth Sriram Guntuka273889e2018-02-16 17:11:46 +05301031
1032 return false;
1033}
1034
1035/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001036 * sap_update_rssi_bsscount() - updates bss count and rssi effect.
1037 *
1038 * @pSpectCh: Channel Information
1039 * @offset: Channel Offset
1040 * @sap_24g: Channel is in 2.4G or 5G
Liangwei Dong71ed6502016-10-20 03:40:45 -04001041 * @spectch_start: the start of spect ch array
1042 * @spectch_end: the end of spect ch array
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001043 *
1044 * sap_update_rssi_bsscount updates bss count and rssi effect based
1045 * on the channel offset.
1046 *
1047 * Return: None.
1048 */
1049
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001050static void sap_update_rssi_bsscount(tSapSpectChInfo *pSpectCh, int32_t offset,
Liangwei Dong71ed6502016-10-20 03:40:45 -04001051 bool sap_24g, tSapSpectChInfo *spectch_start,
1052 tSapSpectChInfo *spectch_end)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001053{
1054 tSapSpectChInfo *pExtSpectCh = NULL;
1055 int32_t rssi, rsssi_effect;
1056
1057 pExtSpectCh = (pSpectCh + offset);
Liangwei Dong71ed6502016-10-20 03:40:45 -04001058 if (pExtSpectCh != NULL &&
1059 pExtSpectCh >= spectch_start &&
1060 pExtSpectCh < spectch_end) {
Yeshwanth Sriram Guntuka273889e2018-02-16 17:11:46 +05301061 if (!sap_check_channels_same_band(pSpectCh->chNum,
1062 pExtSpectCh->chNum))
1063 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001064 ++pExtSpectCh->bssCount;
1065 switch (offset) {
1066 case -1:
1067 case 1:
1068 rsssi_effect = sap_24g ?
1069 SAP_24GHZ_FIRST_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY :
1070 SAP_SUBBAND1_RSSI_EFFECT_PRIMARY;
1071 break;
1072 case -2:
1073 case 2:
1074 rsssi_effect = sap_24g ?
1075 SAP_24GHZ_SEC_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY :
1076 SAP_SUBBAND2_RSSI_EFFECT_PRIMARY;
1077 break;
1078 case -3:
1079 case 3:
1080 rsssi_effect = sap_24g ?
1081 SAP_24GHZ_THIRD_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY :
1082 SAP_SUBBAND3_RSSI_EFFECT_PRIMARY;
1083 break;
1084 case -4:
1085 case 4:
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001086 rsssi_effect = sap_24g ?
1087 SAP_24GHZ_FOURTH_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY :
1088 SAP_SUBBAND4_RSSI_EFFECT_PRIMARY;
1089 break;
1090 case -5:
1091 case 5:
1092 rsssi_effect = SAP_SUBBAND5_RSSI_EFFECT_PRIMARY;
1093 break;
1094 case -6:
1095 case 6:
1096 rsssi_effect = SAP_SUBBAND6_RSSI_EFFECT_PRIMARY;
1097 break;
1098 case -7:
1099 case 7:
1100 rsssi_effect = SAP_SUBBAND7_RSSI_EFFECT_PRIMARY;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001101 break;
1102 default:
1103 rsssi_effect = 0;
1104 break;
1105 }
1106
1107 rssi = pSpectCh->rssiAgr + rsssi_effect;
1108 if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi))
1109 pExtSpectCh->rssiAgr = rssi;
1110 if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI)
1111 pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI;
1112 }
1113}
1114
1115/**
1116 * sap_upd_chan_spec_params() - sap_upd_chan_spec_params
1117 * updates channel parameters obtained from Beacon
1118 * @pBeaconStruct Beacon strucutre populated by parse_beacon function
1119 * @channelWidth Channel width
1120 * @secondaryChannelOffset Secondary Channel Offset
1121 * @vhtSupport If channel supports VHT
1122 * @centerFreq Central frequency for the given channel.
1123 *
1124 * sap_upd_chan_spec_params updates the spectrum channels based on the
1125 * pBeaconStruct obtained from Beacon IE
1126 *
1127 * Return: NA.
1128 */
1129
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001130static void sap_upd_chan_spec_params(tSirProbeRespBeacon *pBeaconStruct,
1131 uint16_t *channelWidth,
1132 uint16_t *secondaryChannelOffset,
1133 uint16_t *vhtSupport,
1134 uint16_t *centerFreq,
1135 uint16_t *centerFreq_2)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001136{
1137 if (NULL == pBeaconStruct) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301138 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001139 FL("pBeaconStruct is NULL"));
1140 return;
1141 }
1142
1143 if (pBeaconStruct->HTCaps.present && pBeaconStruct->HTInfo.present) {
1144 *channelWidth = pBeaconStruct->HTCaps.supportedChannelWidthSet;
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001145 *secondaryChannelOffset =
1146 pBeaconStruct->HTInfo.secondaryChannelOffset;
1147 if (!pBeaconStruct->VHTOperation.present)
1148 return;
1149 *vhtSupport = pBeaconStruct->VHTOperation.present;
1150 if (pBeaconStruct->VHTOperation.chanWidth) {
1151 *centerFreq =
1152 pBeaconStruct->VHTOperation.chanCenterFreqSeg1;
1153 *centerFreq_2 =
1154 pBeaconStruct->VHTOperation.chanCenterFreqSeg2;
1155 /*
1156 * LHS follows tSirMacHTChannelWidth, while RHS follows
1157 * WNI_CFG_VHT_CHANNEL_WIDTH_X format hence following
1158 * adjustment
1159 */
1160 *channelWidth =
1161 pBeaconStruct->VHTOperation.chanWidth + 1;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001162
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001163 }
1164 }
1165}
1166
1167/**
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001168 * sap_update_rssi_bsscount_vht_5G() - updates bss count and rssi effect.
1169 *
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001170 * @spect_ch: Channel Information
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001171 * @offset: Channel Offset
1172 * @num_ch: no.of channels
Liangwei Dong71ed6502016-10-20 03:40:45 -04001173 * @spectch_start: the start of spect ch array
1174 * @spectch_end: the end of spect ch array
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001175 *
1176 * sap_update_rssi_bsscount_vht_5G updates bss count and rssi effect based
1177 * on the channel offset.
1178 *
1179 * Return: None.
1180 */
1181
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001182static void sap_update_rssi_bsscount_vht_5G(tSapSpectChInfo *spect_ch,
1183 int32_t offset,
Liangwei Dong71ed6502016-10-20 03:40:45 -04001184 uint16_t num_ch,
1185 tSapSpectChInfo *spectch_start,
1186 tSapSpectChInfo *spectch_end)
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001187{
1188 int32_t ch_offset;
1189 uint16_t i, cnt;
1190
1191 if (!offset)
1192 return;
1193 if (offset > 0)
1194 cnt = num_ch;
1195 else
1196 cnt = num_ch + 1;
1197 for (i = 0; i < cnt; i++) {
1198 ch_offset = offset + i;
1199 if (ch_offset == 0)
1200 continue;
Liangwei Dong71ed6502016-10-20 03:40:45 -04001201 sap_update_rssi_bsscount(spect_ch, ch_offset, false,
1202 spectch_start, spectch_end);
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001203 }
1204}
1205/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001206 * sap_interference_rssi_count_5G() - sap_interference_rssi_count
1207 * considers the Adjacent channel rssi and
1208 * data count(here number of BSS observed)
1209 * @spect_ch: Channel Information
1210 * @chan_width: Channel width parsed from beacon IE
1211 * @sec_chan_offset: Secondary Channel Offset
1212 * @center_freq: Central frequency for the given channel.
1213 * @channel_id: channel_id
Liangwei Dong71ed6502016-10-20 03:40:45 -04001214 * @spectch_start: the start of spect ch array
1215 * @spectch_end: the end of spect ch array
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001216 *
1217 * sap_interference_rssi_count_5G considers the Adjacent channel rssi
1218 * and data count(here number of BSS observed)
1219 *
1220 * Return: NA.
1221 */
1222
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001223static void sap_interference_rssi_count_5G(tSapSpectChInfo *spect_ch,
1224 uint16_t chan_width,
1225 uint16_t sec_chan_offset,
1226 uint16_t center_freq,
1227 uint16_t center_freq_2,
Liangwei Dong71ed6502016-10-20 03:40:45 -04001228 uint8_t channel_id,
1229 tSapSpectChInfo *spectch_start,
1230 tSapSpectChInfo *spectch_end)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001231{
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001232 uint16_t num_ch;
1233 int32_t offset = 0;
Srinivas Girigowda4d65ebe2017-10-13 21:41:42 -07001234
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001235 if (NULL == spect_ch) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301236 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001237 FL("spect_ch is NULL"));
1238 return;
1239 }
1240
1241 /* Updating the received ChannelWidth */
1242 if (spect_ch->channelWidth != chan_width)
1243 spect_ch->channelWidth = chan_width;
1244 /* If received ChannelWidth is other than HT20,
1245 * we need to update the extension channel Params as well
1246 * chan_width == 0, HT20
1247 * chan_width == 1, HT40
1248 * chan_width == 2, VHT80
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001249 * chan_width == 3, VHT160
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001250 */
1251
1252 switch (spect_ch->channelWidth) {
1253 case eHT_CHANNEL_WIDTH_40MHZ: /* HT40 */
1254 switch (sec_chan_offset) {
1255 /* Above the Primary Channel */
1256 case PHY_DOUBLE_CHANNEL_LOW_PRIMARY:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001257 sap_update_rssi_bsscount(spect_ch, 1, false,
1258 spectch_start, spectch_end);
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001259 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001260
1261 /* Below the Primary channel */
1262 case PHY_DOUBLE_CHANNEL_HIGH_PRIMARY:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001263 sap_update_rssi_bsscount(spect_ch, -1, false,
1264 spectch_start, spectch_end);
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001265 return;
1266 }
1267 return;
1268 case eHT_CHANNEL_WIDTH_80MHZ: /* VHT80 */
1269 num_ch = 3;
1270 if ((center_freq - channel_id) == 6) {
1271 offset = 1;
1272 } else if ((center_freq - channel_id) == 2) {
1273 offset = -1;
1274 } else if ((center_freq - channel_id) == -2) {
1275 offset = -2;
1276 } else if ((center_freq - channel_id) == -6) {
1277 offset = -3;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001278 }
1279 break;
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001280 case eHT_CHANNEL_WIDTH_160MHZ: /* VHT160 */
1281 num_ch = 7;
1282 if ((center_freq - channel_id) == 14)
1283 offset = 1;
1284 else if ((center_freq - channel_id) == 10)
1285 offset = -1;
1286 else if ((center_freq - channel_id) == 6)
1287 offset = -2;
1288 else if ((center_freq - channel_id) == 2)
1289 offset = -3;
1290 else if ((center_freq - channel_id) == -2)
1291 offset = -4;
1292 else if ((center_freq - channel_id) == -6)
1293 offset = -5;
1294 else if ((center_freq - channel_id) == -10)
1295 offset = -6;
1296 else if ((center_freq - channel_id) == -14)
1297 offset = -7;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001298 break;
1299 default:
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001300 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001301 }
Liangwei Dong71ed6502016-10-20 03:40:45 -04001302 sap_update_rssi_bsscount_vht_5G(spect_ch, offset, num_ch,
1303 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001304}
1305
1306/**
1307 * sap_interference_rssi_count() - sap_interference_rssi_count
1308 * considers the Adjacent channel rssi
1309 * and data count(here number of BSS observed)
1310 * @spect_ch Channel Information
Liangwei Dong71ed6502016-10-20 03:40:45 -04001311 * @spectch_start: the start of spect ch array
1312 * @spectch_end: the end of spect ch array
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001313 *
1314 * sap_interference_rssi_count considers the Adjacent channel rssi
1315 * and data count(here number of BSS observed)
1316 *
1317 * Return: None.
1318 */
1319
Liangwei Dong71ed6502016-10-20 03:40:45 -04001320static void sap_interference_rssi_count(tSapSpectChInfo *spect_ch,
1321 tSapSpectChInfo *spectch_start,
1322 tSapSpectChInfo *spectch_end)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001323{
1324 if (NULL == spect_ch) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301325 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001326 "%s: spect_ch is NULL", __func__);
1327 return;
1328 }
1329
1330 switch (spect_ch->chNum) {
1331 case CHANNEL_1:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001332 sap_update_rssi_bsscount(spect_ch, 1, true,
1333 spectch_start, spectch_end);
1334 sap_update_rssi_bsscount(spect_ch, 2, true,
1335 spectch_start, spectch_end);
1336 sap_update_rssi_bsscount(spect_ch, 3, true,
1337 spectch_start, spectch_end);
1338 sap_update_rssi_bsscount(spect_ch, 4, true,
1339 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001340 break;
1341
1342 case CHANNEL_2:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001343 sap_update_rssi_bsscount(spect_ch, -1, true,
1344 spectch_start, spectch_end);
1345 sap_update_rssi_bsscount(spect_ch, 1, true,
1346 spectch_start, spectch_end);
1347 sap_update_rssi_bsscount(spect_ch, 2, true,
1348 spectch_start, spectch_end);
1349 sap_update_rssi_bsscount(spect_ch, 3, true,
1350 spectch_start, spectch_end);
1351 sap_update_rssi_bsscount(spect_ch, 4, true,
1352 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001353 break;
1354 case CHANNEL_3:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001355 sap_update_rssi_bsscount(spect_ch, -2, true,
1356 spectch_start, spectch_end);
1357 sap_update_rssi_bsscount(spect_ch, -1, true,
1358 spectch_start, spectch_end);
1359 sap_update_rssi_bsscount(spect_ch, 1, true,
1360 spectch_start, spectch_end);
1361 sap_update_rssi_bsscount(spect_ch, 2, true,
1362 spectch_start, spectch_end);
1363 sap_update_rssi_bsscount(spect_ch, 3, true,
1364 spectch_start, spectch_end);
1365 sap_update_rssi_bsscount(spect_ch, 4, true,
1366 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001367 break;
1368 case CHANNEL_4:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001369 sap_update_rssi_bsscount(spect_ch, -3, true,
1370 spectch_start, spectch_end);
1371 sap_update_rssi_bsscount(spect_ch, -2, true,
1372 spectch_start, spectch_end);
1373 sap_update_rssi_bsscount(spect_ch, -1, true,
1374 spectch_start, spectch_end);
1375 sap_update_rssi_bsscount(spect_ch, 1, true,
1376 spectch_start, spectch_end);
1377 sap_update_rssi_bsscount(spect_ch, 2, true,
1378 spectch_start, spectch_end);
1379 sap_update_rssi_bsscount(spect_ch, 3, true,
1380 spectch_start, spectch_end);
1381 sap_update_rssi_bsscount(spect_ch, 4, true,
1382 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001383 break;
1384
1385 case CHANNEL_5:
1386 case CHANNEL_6:
1387 case CHANNEL_7:
1388 case CHANNEL_8:
1389 case CHANNEL_9:
1390 case CHANNEL_10:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001391 sap_update_rssi_bsscount(spect_ch, -4, true,
1392 spectch_start, spectch_end);
1393 sap_update_rssi_bsscount(spect_ch, -3, true,
1394 spectch_start, spectch_end);
1395 sap_update_rssi_bsscount(spect_ch, -2, true,
1396 spectch_start, spectch_end);
1397 sap_update_rssi_bsscount(spect_ch, -1, true,
1398 spectch_start, spectch_end);
1399 sap_update_rssi_bsscount(spect_ch, 1, true,
1400 spectch_start, spectch_end);
1401 sap_update_rssi_bsscount(spect_ch, 2, true,
1402 spectch_start, spectch_end);
1403 sap_update_rssi_bsscount(spect_ch, 3, true,
1404 spectch_start, spectch_end);
1405 sap_update_rssi_bsscount(spect_ch, 4, true,
1406 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001407 break;
1408
1409 case CHANNEL_11:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001410 sap_update_rssi_bsscount(spect_ch, -4, true,
1411 spectch_start, spectch_end);
1412 sap_update_rssi_bsscount(spect_ch, -3, true,
1413 spectch_start, spectch_end);
1414 sap_update_rssi_bsscount(spect_ch, -2, true,
1415 spectch_start, spectch_end);
1416 sap_update_rssi_bsscount(spect_ch, -1, true,
1417 spectch_start, spectch_end);
1418 sap_update_rssi_bsscount(spect_ch, 1, true,
1419 spectch_start, spectch_end);
1420 sap_update_rssi_bsscount(spect_ch, 2, true,
1421 spectch_start, spectch_end);
1422 sap_update_rssi_bsscount(spect_ch, 3, true,
1423 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001424 break;
1425
1426 case CHANNEL_12:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001427 sap_update_rssi_bsscount(spect_ch, -4, true,
1428 spectch_start, spectch_end);
1429 sap_update_rssi_bsscount(spect_ch, -3, true,
1430 spectch_start, spectch_end);
1431 sap_update_rssi_bsscount(spect_ch, -2, true,
1432 spectch_start, spectch_end);
1433 sap_update_rssi_bsscount(spect_ch, -1, true,
1434 spectch_start, spectch_end);
1435 sap_update_rssi_bsscount(spect_ch, 1, true,
1436 spectch_start, spectch_end);
1437 sap_update_rssi_bsscount(spect_ch, 2, true,
1438 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001439 break;
1440
1441 case CHANNEL_13:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001442 sap_update_rssi_bsscount(spect_ch, -4, true,
1443 spectch_start, spectch_end);
1444 sap_update_rssi_bsscount(spect_ch, -3, true,
1445 spectch_start, spectch_end);
1446 sap_update_rssi_bsscount(spect_ch, -2, true,
1447 spectch_start, spectch_end);
1448 sap_update_rssi_bsscount(spect_ch, -1, true,
1449 spectch_start, spectch_end);
1450 sap_update_rssi_bsscount(spect_ch, 1, true,
1451 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001452 break;
1453
1454 case CHANNEL_14:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001455 sap_update_rssi_bsscount(spect_ch, -4, true,
1456 spectch_start, spectch_end);
1457 sap_update_rssi_bsscount(spect_ch, -3, true,
1458 spectch_start, spectch_end);
1459 sap_update_rssi_bsscount(spect_ch, -2, true,
1460 spectch_start, spectch_end);
1461 sap_update_rssi_bsscount(spect_ch, -1, true,
1462 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001463 break;
1464
1465 default:
1466 break;
1467 }
1468}
1469
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001470/**
1471 * ch_in_pcl() - Is channel in the Preferred Channel List (PCL)
1472 * @sap_ctx: SAP context which contains the current PCL
1473 * @channel: Input channel number to be checked
1474 *
1475 * Check if a channel is in the preferred channel list
1476 *
1477 * Return:
1478 * true: channel is in PCL,
1479 * false: channel is not in PCL
1480 */
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -07001481static bool ch_in_pcl(struct sap_context *sap_ctx, uint8_t channel)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001482{
1483 uint32_t i;
1484
1485 for (i = 0; i < sap_ctx->acs_cfg->pcl_ch_count; i++) {
1486 if (channel == sap_ctx->acs_cfg->pcl_channels[i])
1487 return true;
1488 }
1489
1490 return false;
1491}
1492
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001493/**
1494 * sap_compute_spect_weight() - Compute spectrum weight
1495 * @pSpectInfoParams: Pointer to the tSpectInfoParams structure
Jeff Johnson7730fbb2018-11-08 13:48:27 -08001496 * @mac_handle: Opaque handle to the global MAC context
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001497 * @pResult: Pointer to tScanResultHandle
1498 * @sap_ctx: Context of the SAP
1499 *
1500 * Main function for computing the weight of each channel in the
1501 * spectrum based on the RSSI value of the BSSes on the channel
1502 * and number of BSS
1503 */
1504static void sap_compute_spect_weight(tSapChSelSpectInfo *pSpectInfoParams,
Jeff Johnson7730fbb2018-11-08 13:48:27 -08001505 mac_handle_t mac_handle,
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001506 tScanResultHandle pResult,
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -07001507 struct sap_context *sap_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001508{
1509 int8_t rssi = 0;
1510 uint8_t chn_num = 0;
1511 uint8_t channel_id = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001512 tCsrScanResultInfo *pScanResult;
1513 tSapSpectChInfo *pSpectCh = pSpectInfoParams->pSpectCh;
1514 uint32_t operatingBand;
1515 uint16_t channelWidth;
1516 uint16_t secondaryChannelOffset;
1517 uint16_t centerFreq;
gaurank kathpalia859c9362018-08-02 23:07:21 +05301518 uint8_t i;
1519 bool found;
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001520 uint16_t centerFreq_2 = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001521 uint16_t vhtSupport;
1522 uint32_t ieLen = 0;
1523 tSirProbeRespBeacon *pBeaconStruct;
Jeff Johnsonb9794442018-11-22 14:21:08 -08001524 tpAniSirGlobal mac = MAC_CONTEXT(mac_handle);
Liangwei Dong71ed6502016-10-20 03:40:45 -04001525 tSapSpectChInfo *spectch_start = pSpectInfoParams->pSpectCh;
1526 tSapSpectChInfo *spectch_end = pSpectInfoParams->pSpectCh +
1527 pSpectInfoParams->numSpectChans;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001528
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301529 pBeaconStruct = qdf_mem_malloc(sizeof(tSirProbeRespBeacon));
Arif Hussain256cc282018-10-03 14:10:44 -07001530 if (!pBeaconStruct)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001531 return;
Arif Hussain256cc282018-10-03 14:10:44 -07001532
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301533 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001534 "In %s, Computing spectral weight", __func__);
1535
1536 /**
1537 * Soft AP specific channel weight calculation using DFS formula
1538 */
1539 SET_ACS_BAND(operatingBand, sap_ctx);
1540
Jeff Johnson7730fbb2018-11-08 13:48:27 -08001541 pScanResult = sme_scan_result_get_first(mac_handle, pResult);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001542
1543 while (pScanResult) {
1544 pSpectCh = pSpectInfoParams->pSpectCh;
1545 /* Defining the default values, so that any value will hold the default values */
1546 channelWidth = eHT_CHANNEL_WIDTH_20MHZ;
1547 secondaryChannelOffset = PHY_SINGLE_CHANNEL_CENTERED;
1548 vhtSupport = 0;
1549 centerFreq = 0;
1550
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001551
Yingying Tang22facc12016-10-20 17:43:59 +08001552 ieLen = GET_IE_LEN_IN_BSS(
1553 pScanResult->BssDescriptor.length);
1554 qdf_mem_set((uint8_t *) pBeaconStruct,
1555 sizeof(tSirProbeRespBeacon), 0);
1556
1557
1558 if ((sir_parse_beacon_ie
Jeff Johnsonb9794442018-11-22 14:21:08 -08001559 (mac, pBeaconStruct, (uint8_t *)
Yingying Tang22facc12016-10-20 17:43:59 +08001560 (pScanResult->BssDescriptor.ieFields),
Jeff Johnson83e30fa2018-06-07 23:01:11 -07001561 ieLen)) == QDF_STATUS_SUCCESS)
Yingying Tang22facc12016-10-20 17:43:59 +08001562 sap_upd_chan_spec_params(
1563 pBeaconStruct,
1564 &channelWidth,
1565 &secondaryChannelOffset,
1566 &vhtSupport, &centerFreq,
1567 &centerFreq_2);
1568
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001569 /* Processing for each tCsrScanResultInfo in the tCsrScanResult DLink list */
1570 for (chn_num = 0; chn_num < pSpectInfoParams->numSpectChans;
1571 chn_num++) {
1572
1573 /*
Himanshu Agarwalcf5b8932018-07-02 18:06:49 +05301574 * If the Beacon has channel ID, use it other wise we
1575 * will rely on the channelIdSelf
1576 */
1577 if (pScanResult->BssDescriptor.channelId == 0)
1578 channel_id =
1579 pScanResult->BssDescriptor.channelIdSelf;
1580 else
1581 channel_id =
1582 pScanResult->BssDescriptor.channelId;
1583
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001584 if (pSpectCh && (channel_id == pSpectCh->chNum)) {
1585 if (pSpectCh->rssiAgr <
1586 pScanResult->BssDescriptor.rssi)
1587 pSpectCh->rssiAgr =
1588 pScanResult->BssDescriptor.rssi;
1589
1590 ++pSpectCh->bssCount; /* Increment the count of BSS */
1591
1592 /*
1593 * Connsidering the Extension Channel
1594 * only in a channels
1595 */
1596 switch (operatingBand) {
1597 case eCSR_DOT11_MODE_11a:
1598 sap_interference_rssi_count_5G(
1599 pSpectCh, channelWidth,
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001600 secondaryChannelOffset,
1601 centerFreq,
1602 centerFreq_2,
Liangwei Dong71ed6502016-10-20 03:40:45 -04001603 channel_id,
1604 spectch_start,
1605 spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001606 break;
1607
1608 case eCSR_DOT11_MODE_11g:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001609 sap_interference_rssi_count(pSpectCh,
1610 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001611 break;
1612
1613 case eCSR_DOT11_MODE_abg:
Himanshu Agarwal4f503b82018-03-19 12:10:45 +05301614 if (pSpectCh->chNum >=
1615 SIR_11A_CHANNEL_BEGIN)
1616 sap_interference_rssi_count_5G(
1617 pSpectCh, channelWidth,
1618 secondaryChannelOffset,
1619 centerFreq,
1620 centerFreq_2,
1621 channel_id,
1622 spectch_start,
1623 spectch_end);
1624 else
1625 sap_interference_rssi_count(
1626 pSpectCh,
1627 spectch_start,
1628 spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001629 break;
1630 }
1631
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301632 QDF_TRACE(QDF_MODULE_ID_SAP,
1633 QDF_TRACE_LEVEL_INFO_HIGH,
Jeff Johnsona7c0ddb2017-09-18 08:14:12 -07001634 "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 -08001635 __func__,
1636 pScanResult->BssDescriptor.
1637 channelIdSelf,
1638 pScanResult->BssDescriptor.channelId,
1639 pScanResult->BssDescriptor.rssi,
1640 pSpectCh->bssCount, pScanResult,
1641 pSpectCh->channelWidth,
1642 secondaryChannelOffset, centerFreq);
1643 pSpectCh++;
1644 break;
1645 } else {
1646 pSpectCh++;
1647 }
1648 }
1649
Jeff Johnson7730fbb2018-11-08 13:48:27 -08001650 pScanResult = sme_scan_result_get_next(mac_handle, pResult);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001651 }
1652
1653 /* Calculate the weights for all channels in the spectrum pSpectCh */
1654 pSpectCh = pSpectInfoParams->pSpectCh;
1655
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301656 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001657 "In %s, Spectrum Channels Weight", __func__);
1658
1659 for (chn_num = 0; chn_num < (pSpectInfoParams->numSpectChans);
1660 chn_num++) {
1661
1662 /*
1663 rssi : Maximum received signal strength among all BSS on that channel
1664 bssCount : Number of BSS on that channel
1665 */
1666
1667 rssi = (int8_t) pSpectCh->rssiAgr;
Himanshu Agarwal3697f942018-06-13 14:04:26 +05301668 if (ch_in_pcl(sap_ctx, pSpectCh->chNum))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001669 rssi -= PCL_RSSI_DISCOUNT;
1670
Himanshu Agarwal3697f942018-06-13 14:04:26 +05301671 if (rssi < SOFTAP_MIN_RSSI)
1672 rssi = SOFTAP_MIN_RSSI;
1673
hqub6441f22018-08-09 16:15:31 +08001674 if (pSpectCh->weight == SAP_ACS_WEIGHT_MAX) {
1675 pSpectCh->weight_copy = pSpectCh->weight;
Himanshu Agarwalfee2e362018-01-18 20:26:35 +05301676 goto debug_info;
hqub6441f22018-08-09 16:15:31 +08001677 }
Himanshu Agarwalfee2e362018-01-18 20:26:35 +05301678
gaurank kathpalia859c9362018-08-02 23:07:21 +05301679 /* There may be channels in scanlist, which were not sent to
1680 * FW for scanning as part of ACS scan list, but they do have an
1681 * effect on the neighbouring channels, so they help to find a
1682 * suitable channel, but there weight should be max as they were
1683 * and not meant to be included in the ACS scan results.
1684 * So just assign RSSI as -100, bsscount as 0, and weight as max
1685 * to them, so that they always stay low in sorting of best
1686 * channles which were included in ACS scan list
1687 */
1688 found = false;
1689 for (i = 0; i < sap_ctx->num_of_channel; i++) {
1690 if (pSpectCh->chNum == sap_ctx->channelList[i]) {
1691 /* Scan channel was included in ACS scan list */
1692 found = true;
1693 break;
1694 }
1695 }
1696
1697 if (found)
1698 pSpectCh->weight =
1699 SAPDFS_NORMALISE_1000 *
1700 (sapweight_rssi_count(sap_ctx, rssi,
1701 pSpectCh->bssCount) + sap_weight_channel_status(
Jeff Johnsonb9794442018-11-22 14:21:08 -08001702 sap_ctx, sap_get_channel_status(mac,
gaoleze5108942017-03-31 16:56:42 +08001703 pSpectCh->chNum)));
gaurank kathpalia859c9362018-08-02 23:07:21 +05301704 else {
1705 pSpectCh->weight = SAP_ACS_WEIGHT_MAX;
1706 pSpectCh->rssiAgr = SOFTAP_MIN_RSSI;
1707 rssi = SOFTAP_MIN_RSSI;
1708 pSpectCh->bssCount = SOFTAP_MIN_COUNT;
1709 }
1710
gaoleze5108942017-03-31 16:56:42 +08001711 if (pSpectCh->weight > SAP_ACS_WEIGHT_MAX)
1712 pSpectCh->weight = SAP_ACS_WEIGHT_MAX;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001713 pSpectCh->weight_copy = pSpectCh->weight;
1714
Himanshu Agarwalfee2e362018-01-18 20:26:35 +05301715debug_info:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001716 /* ------ Debug Info ------ */
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301717 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Himanshu Agarwal3697f942018-06-13 14:04:26 +05301718 "In %s, Chan=%d Weight= %d rssiAgr=%d rssi_pcl_discount: %d bssCount=%d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001719 __func__, pSpectCh->chNum, pSpectCh->weight,
Himanshu Agarwal3697f942018-06-13 14:04:26 +05301720 pSpectCh->rssiAgr, rssi, pSpectCh->bssCount);
wadesongcb0ded22018-02-02 17:57:20 +08001721 host_log_acs_chan_spect_weight(pSpectCh->chNum,
1722 (uint16_t)pSpectCh->weight,
1723 pSpectCh->rssiAgr,
1724 pSpectCh->bssCount);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001725 /* ------ Debug Info ------ */
1726 pSpectCh++;
1727 }
Jeff Johnsonb9794442018-11-22 14:21:08 -08001728 sap_clear_channel_status(mac);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301729 qdf_mem_free(pBeaconStruct);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001730}
1731
1732/*==========================================================================
1733 FUNCTION sap_chan_sel_exit
1734
1735 DESCRIPTION
1736 Exit function for free out the allocated memory, to be called
1737 at the end of the dfsSelectChannel function
1738
1739 DEPENDENCIES
1740 NA.
1741
1742 PARAMETERS
1743
1744 IN
1745 pSpectInfoParams : Pointer to the tSapChSelSpectInfo structure
1746
1747 RETURN VALUE
1748 void : NULL
1749
1750 SIDE EFFECTS
1751 ============================================================================*/
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001752static void sap_chan_sel_exit(tSapChSelSpectInfo *pSpectInfoParams)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001753{
1754 /* Free all the allocated memory */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301755 qdf_mem_free(pSpectInfoParams->pSpectCh);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001756}
1757
1758/*==========================================================================
1759 FUNCTION sap_sort_chl_weight
1760
1761 DESCRIPTION
Jeff Johnsonc7e4d162018-05-12 16:20:34 -07001762 Function to sort the channels with the least weight first for 20MHz channels
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001763
1764 DEPENDENCIES
1765 NA.
1766
1767 PARAMETERS
1768
1769 IN
1770 pSpectInfoParams : Pointer to the tSapChSelSpectInfo structure
1771
1772 RETURN VALUE
1773 void : NULL
1774
1775 SIDE EFFECTS
1776 ============================================================================*/
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001777static void sap_sort_chl_weight(tSapChSelSpectInfo *pSpectInfoParams)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001778{
1779 tSapSpectChInfo temp;
1780
1781 tSapSpectChInfo *pSpectCh = NULL;
1782 uint32_t i = 0, j = 0, minWeightIndex = 0;
1783
1784 pSpectCh = pSpectInfoParams->pSpectCh;
1785 for (i = 0; i < pSpectInfoParams->numSpectChans; i++) {
1786 minWeightIndex = i;
1787 for (j = i + 1; j < pSpectInfoParams->numSpectChans; j++) {
1788 if (pSpectCh[j].weight <
1789 pSpectCh[minWeightIndex].weight) {
1790 minWeightIndex = j;
Yeshwanth Sriram Guntuka273889e2018-02-16 17:11:46 +05301791 } else if (pSpectCh[j].weight ==
1792 pSpectCh[minWeightIndex].weight) {
1793 if (pSpectCh[j].bssCount <
1794 pSpectCh[minWeightIndex].bssCount)
1795 minWeightIndex = j;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001796 }
1797 }
1798 if (minWeightIndex != i) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301799 qdf_mem_copy(&temp, &pSpectCh[minWeightIndex],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001800 sizeof(*pSpectCh));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301801 qdf_mem_copy(&pSpectCh[minWeightIndex], &pSpectCh[i],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001802 sizeof(*pSpectCh));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301803 qdf_mem_copy(&pSpectCh[i], &temp, sizeof(*pSpectCh));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001804 }
1805 }
1806}
1807
1808/**
Jeff Johnsonc7e4d162018-05-12 16:20:34 -07001809 * set_ht80_chl_bit() - to set available channel to ht80 channel bitmap
bingse2782382017-03-23 10:34:52 +08001810 * @channel_bitmap: Pointer to the chan_bonding_bitmap structure
1811 * @spect_info_params: Pointer to the tSapChSelSpectInfo structure
1812 *
1813 * Return: none
1814 */
1815static void set_ht80_chl_bit(chan_bonding_bitmap *channel_bitmap,
1816 tSapChSelSpectInfo *spec_info_params)
1817{
1818 uint8_t i, j;
1819 tSapSpectChInfo *spec_info;
1820 int start_channel = 0;
1821
1822 channel_bitmap->chanBondingSet[0].startChannel =
1823 acs_ht80_channels[0].chStartNum;
1824 channel_bitmap->chanBondingSet[1].startChannel =
1825 acs_ht80_channels[1].chStartNum;
1826 channel_bitmap->chanBondingSet[2].startChannel =
1827 acs_ht80_channels[2].chStartNum;
1828 channel_bitmap->chanBondingSet[3].startChannel =
1829 acs_ht80_channels[3].chStartNum;
1830 channel_bitmap->chanBondingSet[4].startChannel =
1831 acs_ht80_channels[4].chStartNum;
1832 channel_bitmap->chanBondingSet[5].startChannel =
1833 acs_ht80_channels[5].chStartNum;
1834
1835 spec_info = spec_info_params->pSpectCh;
1836 for (j = 0; j < spec_info_params->numSpectChans; j++) {
1837 for (i = 0; i < MAX_80MHZ_BANDS; i++) {
1838 start_channel =
1839 channel_bitmap->chanBondingSet[i].startChannel;
1840 if (spec_info[j].chNum >= start_channel &&
1841 (spec_info[j].chNum <= start_channel + 12)) {
1842 channel_bitmap->chanBondingSet[i].channelMap |=
1843 1 << ((spec_info[j].chNum -
1844 start_channel)/4);
1845 break;
1846 }
1847 }
1848 }
1849}
1850
1851/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001852 * sap_sort_chl_weight_ht80() - to sort the channels with the least weight
1853 * @pSpectInfoParams: Pointer to the tSapChSelSpectInfo structure
1854 *
Jeff Johnsonc7e4d162018-05-12 16:20:34 -07001855 * Function to sort the channels with the least weight first for HT80 channels
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001856 *
1857 * Return: none
1858 */
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001859static void sap_sort_chl_weight_ht80(tSapChSelSpectInfo *pSpectInfoParams)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001860{
1861 uint8_t i, j, n;
1862 tSapSpectChInfo *pSpectInfo;
1863 uint8_t minIdx;
bingse2782382017-03-23 10:34:52 +08001864 int start_channel = 0;
1865 chan_bonding_bitmap *channel_bitmap;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001866
bingse2782382017-03-23 10:34:52 +08001867 channel_bitmap = qdf_mem_malloc(sizeof(chan_bonding_bitmap));
Arif Hussain256cc282018-10-03 14:10:44 -07001868 if (!channel_bitmap)
bingse2782382017-03-23 10:34:52 +08001869 return;
Arif Hussain256cc282018-10-03 14:10:44 -07001870
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001871 pSpectInfo = pSpectInfoParams->pSpectCh;
1872 /* for each HT80 channel, calculate the combined weight of the
1873 four 20MHz weight */
1874 for (i = 0; i < ARRAY_SIZE(acs_ht80_channels); i++) {
1875 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
1876 if (pSpectInfo[j].chNum ==
1877 acs_ht80_channels[i].chStartNum)
1878 break;
1879 }
1880 if (j == pSpectInfoParams->numSpectChans)
1881 continue;
1882
1883 if (!(((pSpectInfo[j].chNum + 4) == pSpectInfo[j + 1].chNum) &&
1884 ((pSpectInfo[j].chNum + 8) ==
1885 pSpectInfo[j + 2].chNum) &&
1886 ((pSpectInfo[j].chNum + 12) ==
1887 pSpectInfo[j + 3].chNum))) {
1888 /*
1889 * some channels does not exist in pSectInfo array,
1890 * skip this channel and those in the same HT80 width
1891 */
1892 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 4;
1893 if ((pSpectInfo[j].chNum + 4) ==
1894 pSpectInfo[j + 1].chNum)
1895 pSpectInfo[j + 1].weight =
1896 SAP_ACS_WEIGHT_MAX * 4;
1897 if ((pSpectInfo[j].chNum + 8) ==
1898 pSpectInfo[j + 2].chNum)
1899 pSpectInfo[j + 2].weight =
1900 SAP_ACS_WEIGHT_MAX * 4;
1901 if ((pSpectInfo[j].chNum + 12) ==
1902 pSpectInfo[j + 3].chNum)
1903 pSpectInfo[j + 3].weight =
1904 SAP_ACS_WEIGHT_MAX * 4;
1905 continue;
1906 }
1907 /*found the channel, add the 4 adjacent channels' weight */
1908 acs_ht80_channels[i].weight = pSpectInfo[j].weight +
1909 pSpectInfo[j + 1].weight + pSpectInfo[j + 2].weight +
1910 pSpectInfo[j + 3].weight;
1911 /* find best channel among 4 channels as the primary channel */
1912 if ((pSpectInfo[j].weight + pSpectInfo[j + 1].weight) <
1913 (pSpectInfo[j + 2].weight + pSpectInfo[j + 3].weight)) {
1914 /* lower 2 channels are better choice */
1915 if (pSpectInfo[j].weight < pSpectInfo[j + 1].weight)
1916 minIdx = 0;
1917 else
1918 minIdx = 1;
1919 } else if (pSpectInfo[j + 2].weight <=
1920 pSpectInfo[j + 3].weight) {
1921 /* upper 2 channels are better choice */
1922 minIdx = 2;
1923 } else {
1924 minIdx = 3;
1925 }
1926
1927 /*
1928 * set all 4 channels to max value first, then reset the
1929 * best channel as the selected primary channel, update its
1930 * weightage with the combined weight value
1931 */
1932 for (n = 0; n < 4; n++)
1933 pSpectInfo[j + n].weight = SAP_ACS_WEIGHT_MAX * 4;
1934
1935 pSpectInfo[j + minIdx].weight = acs_ht80_channels[i].weight;
1936 }
1937
bingse2782382017-03-23 10:34:52 +08001938 /*
1939 * mark the weight of the channel that can't satisfy 80MHZ
1940 * as max value, so that it will be sorted to the bottom
1941 */
1942 set_ht80_chl_bit(channel_bitmap, pSpectInfoParams);
1943 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
1944 for (i = 0; i < MAX_80MHZ_BANDS; i++) {
1945 start_channel =
1946 channel_bitmap->chanBondingSet[i].startChannel;
1947 if (pSpectInfo[j].chNum >= start_channel &&
1948 (pSpectInfo[j].chNum <=
1949 start_channel + 12) &&
1950 channel_bitmap->chanBondingSet[i].channelMap !=
1951 SAP_80MHZ_MASK)
1952 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 4;
1953 }
1954 }
1955
Himanshu Agarwal75e74412018-02-01 20:51:47 +05301956 /*
1957 * Assign max weight(SAP_ACS_WEIGHT_MAX * 4) to 2.4 Ghz channels
1958 * and channel 165 as they cannot be part of a 80Mhz channel bonding.
1959 */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001960 pSpectInfo = pSpectInfoParams->pSpectCh;
1961 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
Himanshu Agarwal75e74412018-02-01 20:51:47 +05301962 if ((pSpectInfo[j].chNum >= WLAN_REG_CH_NUM(CHAN_ENUM_1) &&
1963 pSpectInfo[j].chNum <= WLAN_REG_CH_NUM(CHAN_ENUM_14)) ||
1964 (CHANNEL_165 == pSpectInfo[j].chNum))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001965 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 4;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001966 }
1967
Manishekar Chandrasekaran44e334f2016-05-30 16:42:50 +05301968 sap_sort_chl_weight(pSpectInfoParams);
1969
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001970 pSpectInfo = pSpectInfoParams->pSpectCh;
1971 for (j = 0; j < (pSpectInfoParams->numSpectChans); j++) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301972 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001973 FL("Channel=%d Weight= %d rssi=%d bssCount=%d"),
1974 pSpectInfo->chNum, pSpectInfo->weight,
1975 pSpectInfo->rssiAgr, pSpectInfo->bssCount);
1976 pSpectInfo++;
1977 }
bingse2782382017-03-23 10:34:52 +08001978 qdf_mem_free(channel_bitmap);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001979}
1980
1981/**
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001982 * sap_sort_chl_weight_vht160() - to sort the channels with the least weight
1983 * @pSpectInfoParams: Pointer to the tSapChSelSpectInfo structure
1984 *
Jeff Johnsonc7e4d162018-05-12 16:20:34 -07001985 * Function to sort the channels with the least weight first for VHT160 channels
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001986 *
1987 * Return: none
1988 */
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001989static void sap_sort_chl_weight_vht160(tSapChSelSpectInfo *pSpectInfoParams)
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001990{
1991 uint8_t i, j, n, idx;
1992 tSapSpectChInfo *pSpectInfo;
1993 uint8_t minIdx;
1994
1995 pSpectInfo = pSpectInfoParams->pSpectCh;
1996 /* for each VHT160 channel, calculate the combined weight of the
1997 8 20MHz weight */
1998 for (i = 0; i < ARRAY_SIZE(acs_vht160_channels); i++) {
1999 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
2000 if (pSpectInfo[j].chNum ==
2001 acs_vht160_channels[i].chStartNum)
2002 break;
2003 }
2004 if (j == pSpectInfoParams->numSpectChans)
2005 continue;
2006
2007 if (!(((pSpectInfo[j].chNum + 4) == pSpectInfo[j + 1].chNum) &&
2008 ((pSpectInfo[j].chNum + 8) ==
2009 pSpectInfo[j + 2].chNum) &&
2010 ((pSpectInfo[j].chNum + 12) ==
2011 pSpectInfo[j + 3].chNum) &&
2012 ((pSpectInfo[j].chNum + 16) ==
2013 pSpectInfo[j + 4].chNum) &&
2014 ((pSpectInfo[j].chNum + 20) ==
2015 pSpectInfo[j + 5].chNum) &&
2016 ((pSpectInfo[j].chNum + 24) ==
2017 pSpectInfo[j + 6].chNum) &&
2018 ((pSpectInfo[j].chNum + 28) ==
2019 pSpectInfo[j + 7].chNum))) {
2020 /*
2021 * some channels does not exist in pSectInfo array,
2022 * skip this channel and those in the same VHT160 width
2023 */
2024 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 8;
2025 if ((pSpectInfo[j].chNum + 4) ==
2026 pSpectInfo[j + 1].chNum)
2027 pSpectInfo[j + 1].weight =
2028 SAP_ACS_WEIGHT_MAX * 8;
2029 if ((pSpectInfo[j].chNum + 8) ==
2030 pSpectInfo[j + 2].chNum)
2031 pSpectInfo[j + 2].weight =
2032 SAP_ACS_WEIGHT_MAX * 8;
2033 if ((pSpectInfo[j].chNum + 12) ==
2034 pSpectInfo[j + 3].chNum)
2035 pSpectInfo[j + 3].weight =
2036 SAP_ACS_WEIGHT_MAX * 8;
2037 if ((pSpectInfo[j].chNum + 16) ==
2038 pSpectInfo[j + 4].chNum)
2039 pSpectInfo[j + 4].weight =
2040 SAP_ACS_WEIGHT_MAX * 8;
2041 if ((pSpectInfo[j].chNum + 20) ==
2042 pSpectInfo[j + 5].chNum)
2043 pSpectInfo[j + 5].weight =
2044 SAP_ACS_WEIGHT_MAX * 8;
2045 if ((pSpectInfo[j].chNum + 24) ==
2046 pSpectInfo[j + 6].chNum)
2047 pSpectInfo[j + 6].weight =
2048 SAP_ACS_WEIGHT_MAX * 8;
2049 if ((pSpectInfo[j].chNum + 28) ==
2050 pSpectInfo[j + 7].chNum)
2051 pSpectInfo[j + 7].weight =
2052 SAP_ACS_WEIGHT_MAX * 8;
2053 continue;
2054 }
2055 /*found the channel, add the 7 adjacent channels' weight */
2056 acs_vht160_channels[i].weight = pSpectInfo[j].weight +
2057 pSpectInfo[j + 1].weight + pSpectInfo[j + 2].weight +
2058 pSpectInfo[j + 3].weight + pSpectInfo[j + 4].weight +
2059 pSpectInfo[j + 5].weight + pSpectInfo[j + 6].weight +
2060 pSpectInfo[j + 7].weight;
2061
2062 /* find best channel among 8 channels as the primary channel */
2063 if ((pSpectInfo[j].weight + pSpectInfo[j + 1].weight +
2064 pSpectInfo[j + 2].weight + pSpectInfo[j + 3].weight) >
2065 (pSpectInfo[j + 4].weight + pSpectInfo[j + 5].weight +
2066 pSpectInfo[j + 6].weight + pSpectInfo[j + 7].weight))
2067 idx = 4;
2068 else
2069 idx = 0;
2070 /* find best channel among 4 channels as the primary channel */
2071 if ((pSpectInfo[j + idx].weight +
2072 pSpectInfo[j + idx + 1].weight) <
2073 (pSpectInfo[j + idx + 2].weight +
2074 pSpectInfo[j + idx + 3].weight)) {
2075 /* lower 2 channels are better choice */
2076 if (pSpectInfo[j + idx].weight <
2077 pSpectInfo[j + idx + 1].weight)
2078 minIdx = 0 + idx;
2079 else
2080 minIdx = 1 + idx;
2081 } else if (pSpectInfo[j + idx + 2].weight <=
2082 pSpectInfo[j + idx + 3].weight) {
2083 /* upper 2 channels are better choice */
2084 minIdx = 2 + idx;
2085 } else {
2086 minIdx = 3 + idx;
2087 }
2088
2089 /*
2090 * set all 8 channels to max value first, then reset the
2091 * best channel as the selected primary channel, update its
2092 * weightage with the combined weight value
2093 */
2094 for (n = 0; n < 8; n++)
2095 pSpectInfo[j + n].weight = SAP_ACS_WEIGHT_MAX * 8;
2096
2097 pSpectInfo[j + minIdx].weight = acs_vht160_channels[i].weight;
2098 }
2099
Himanshu Agarwal75e74412018-02-01 20:51:47 +05302100 /*
2101 * Assign max weight(SAP_ACS_WEIGHT_MAX * 8) to 2.4 Ghz channels
Kiran Kumar Lokere1a43bcf2018-05-15 15:51:58 -07002102 * and channel 132-173 as they cannot be part of a 160Mhz channel
Himanshu Agarwal75e74412018-02-01 20:51:47 +05302103 * bonding.
2104 */
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07002105 pSpectInfo = pSpectInfoParams->pSpectCh;
2106 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
Himanshu Agarwal75e74412018-02-01 20:51:47 +05302107 if ((pSpectInfo[j].chNum >= WLAN_REG_CH_NUM(CHAN_ENUM_1) &&
2108 pSpectInfo[j].chNum <= WLAN_REG_CH_NUM(CHAN_ENUM_14)) ||
2109 (pSpectInfo[j].chNum >= WLAN_REG_CH_NUM(CHAN_ENUM_132) &&
Kiran Kumar Lokere1a43bcf2018-05-15 15:51:58 -07002110 pSpectInfo[j].chNum <= WLAN_REG_CH_NUM(CHAN_ENUM_173)))
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07002111 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 8;
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07002112 }
2113
Manishekar Chandrasekaran44e334f2016-05-30 16:42:50 +05302114 sap_sort_chl_weight(pSpectInfoParams);
2115
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07002116 pSpectInfo = pSpectInfoParams->pSpectCh;
2117 for (j = 0; j < (pSpectInfoParams->numSpectChans); j++) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302118 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07002119 FL("Channel=%d Weight= %d rssi=%d bssCount=%d"),
2120 pSpectInfo->chNum, pSpectInfo->weight,
2121 pSpectInfo->rssiAgr, pSpectInfo->bssCount);
2122 pSpectInfo++;
2123 }
2124}
2125
2126/**
Himanshu Agarwal91c5c0f2018-02-13 14:40:56 +05302127 * sap_allocate_max_weight_ht40_24_g() - allocate max weight for 40Mhz
2128 * to all 2.4Ghz channels
2129 * @spect_info_params: Pointer to the tSapChSelSpectInfo structure
2130 *
2131 * Return: none
2132 */
2133static void sap_allocate_max_weight_ht40_24_g(
2134 tSapChSelSpectInfo *spect_info_params)
2135{
2136 tSapSpectChInfo *spect_info;
2137 uint8_t j;
2138
2139 /*
2140 * Assign max weight for 40Mhz (SAP_ACS_WEIGHT_MAX * 2) to all
2141 * 2.4 Ghz channels
2142 */
2143 spect_info = spect_info_params->pSpectCh;
2144 for (j = 0; j < spect_info_params->numSpectChans; j++) {
2145 if ((spect_info[j].chNum >= WLAN_REG_CH_NUM(CHAN_ENUM_1) &&
2146 spect_info[j].chNum <= WLAN_REG_CH_NUM(CHAN_ENUM_14)))
2147 spect_info[j].weight = SAP_ACS_WEIGHT_MAX * 2;
2148 }
2149}
2150
2151/**
2152 * sap_allocate_max_weight_ht40_5_g() - allocate max weight for 40Mhz
2153 * to all 5Ghz channels
2154 * @spect_info_params: Pointer to the tSapChSelSpectInfo structure
2155 *
2156 * Return: none
2157 */
2158static void sap_allocate_max_weight_ht40_5_g(
2159 tSapChSelSpectInfo *spect_info_params)
2160{
2161 tSapSpectChInfo *spect_info;
2162 uint8_t j;
2163
2164 /*
2165 * Assign max weight for 40Mhz (SAP_ACS_WEIGHT_MAX * 2) to all
2166 * 5 Ghz channels
2167 */
2168 spect_info = spect_info_params->pSpectCh;
2169 for (j = 0; j < spect_info_params->numSpectChans; j++) {
2170 if ((spect_info[j].chNum >= WLAN_REG_CH_NUM(CHAN_ENUM_36) &&
Kiran Kumar Lokere1a43bcf2018-05-15 15:51:58 -07002171 spect_info[j].chNum <= WLAN_REG_CH_NUM(CHAN_ENUM_173)))
Himanshu Agarwal91c5c0f2018-02-13 14:40:56 +05302172 spect_info[j].weight = SAP_ACS_WEIGHT_MAX * 2;
2173 }
2174}
2175
2176/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002177 * sap_sort_chl_weight_ht40_24_g() - to sort channel with the least weight
2178 * @pSpectInfoParams: Pointer to the tSapChSelSpectInfo structure
2179 *
Jeff Johnsonc7e4d162018-05-12 16:20:34 -07002180 * Function to sort the channels with the least weight first for HT40 channels
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002181 *
2182 * Return: none
2183 */
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002184static void sap_sort_chl_weight_ht40_24_g(tSapChSelSpectInfo *pSpectInfoParams,
2185 v_REGDOMAIN_t domain)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002186{
2187 uint8_t i, j;
2188 tSapSpectChInfo *pSpectInfo;
2189 uint32_t tmpWeight1, tmpWeight2;
bingse2782382017-03-23 10:34:52 +08002190 uint32_t ht40plus2gendch = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002191
2192 pSpectInfo = pSpectInfoParams->pSpectCh;
2193 /*
2194 * for each HT40 channel, calculate the combined weight of the
2195 * two 20MHz weight
2196 */
2197 for (i = 0; i < ARRAY_SIZE(acs_ht40_channels24_g); i++) {
2198 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
2199 if (pSpectInfo[j].chNum ==
2200 acs_ht40_channels24_g[i].chStartNum)
2201 break;
2202 }
2203 if (j == pSpectInfoParams->numSpectChans)
2204 continue;
2205
2206 if (!((pSpectInfo[j].chNum + 4) == pSpectInfo[j + 4].chNum)) {
2207 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2;
2208 continue;
2209 }
2210 /*
2211 * check if there is another channel combination possiblity
2212 * e.g., {1, 5} & {5, 9}
2213 */
2214 if ((pSpectInfo[j + 4].chNum + 4) == pSpectInfo[j + 8].chNum) {
2215 /* need to compare two channel pairs */
2216 tmpWeight1 = pSpectInfo[j].weight +
2217 pSpectInfo[j + 4].weight;
2218 tmpWeight2 = pSpectInfo[j + 4].weight +
2219 pSpectInfo[j + 8].weight;
2220 if (tmpWeight1 <= tmpWeight2) {
2221 if (pSpectInfo[j].weight <=
2222 pSpectInfo[j + 4].weight) {
2223 pSpectInfo[j].weight =
2224 tmpWeight1;
2225 pSpectInfo[j + 4].weight =
2226 SAP_ACS_WEIGHT_MAX * 2;
2227 pSpectInfo[j + 8].weight =
2228 SAP_ACS_WEIGHT_MAX * 2;
2229 } else {
2230 pSpectInfo[j + 4].weight =
2231 tmpWeight1;
2232 /* for secondary channel selection */
2233 pSpectInfo[j].weight =
2234 SAP_ACS_WEIGHT_MAX * 2
2235 - 1;
2236 pSpectInfo[j + 8].weight =
2237 SAP_ACS_WEIGHT_MAX * 2;
2238 }
2239 } else {
2240 if (pSpectInfo[j + 4].weight <=
2241 pSpectInfo[j + 8].weight) {
2242 pSpectInfo[j + 4].weight =
2243 tmpWeight2;
2244 pSpectInfo[j].weight =
2245 SAP_ACS_WEIGHT_MAX * 2;
2246 /* for secondary channel selection */
2247 pSpectInfo[j + 8].weight =
2248 SAP_ACS_WEIGHT_MAX * 2
2249 - 1;
2250 } else {
2251 pSpectInfo[j + 8].weight =
2252 tmpWeight2;
2253 pSpectInfo[j].weight =
2254 SAP_ACS_WEIGHT_MAX * 2;
2255 pSpectInfo[j + 4].weight =
2256 SAP_ACS_WEIGHT_MAX * 2;
2257 }
2258 }
2259 } else {
bingsaa6f96a2017-09-11 09:49:43 +08002260 tmpWeight1 = pSpectInfo[j].weight_copy +
2261 pSpectInfo[j + 4].weight_copy;
2262 if (pSpectInfo[j].weight_copy <=
2263 pSpectInfo[j + 4].weight_copy) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002264 pSpectInfo[j].weight = tmpWeight1;
2265 pSpectInfo[j + 4].weight =
2266 SAP_ACS_WEIGHT_MAX * 2;
2267 } else {
2268 pSpectInfo[j + 4].weight = tmpWeight1;
2269 pSpectInfo[j].weight =
2270 SAP_ACS_WEIGHT_MAX * 2;
2271 }
2272 }
2273 }
bingse2782382017-03-23 10:34:52 +08002274 /*
2275 * Every channel should be checked. Add the check for the omissive
2276 * channel. Mark the channel whose combination can't satisfy 40MHZ
2277 * as max value, so that it will be sorted to the bottom.
2278 */
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002279 if (REGDOMAIN_FCC == domain)
bingse2782382017-03-23 10:34:52 +08002280 ht40plus2gendch = HT40PLUS_2G_FCC_CH_END;
2281 else
2282 ht40plus2gendch = HT40PLUS_2G_EURJAP_CH_END;
2283 for (i = HT40MINUS_2G_CH_START; i <= ht40plus2gendch; i++) {
2284 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
2285 if (pSpectInfo[j].chNum == i &&
2286 ((pSpectInfo[j].chNum + 4) !=
2287 pSpectInfo[j+4].chNum) &&
2288 ((pSpectInfo[j].chNum - 4) !=
2289 pSpectInfo[j-4].chNum))
2290 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2;
2291 }
2292 }
2293 for (i = ht40plus2gendch + 1; i <= HT40MINUS_2G_CH_END; i++) {
2294 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
2295 if (pSpectInfo[j].chNum == i &&
2296 (pSpectInfo[j].chNum - 4) !=
2297 pSpectInfo[j-4].chNum)
2298 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2;
2299 }
2300 }
Himanshu Agarwal91c5c0f2018-02-13 14:40:56 +05302301
2302 pSpectInfo = pSpectInfoParams->pSpectCh;
2303 for (j = 0; j < (pSpectInfoParams->numSpectChans); j++) {
2304 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2305 "In %s, Channel=%d Weight= %d rssi=%d bssCount=%d",
2306 __func__, pSpectInfo->chNum, pSpectInfo->weight,
2307 pSpectInfo->rssiAgr, pSpectInfo->bssCount);
2308 pSpectInfo++;
2309 }
2310
Manishekar Chandrasekaran44e334f2016-05-30 16:42:50 +05302311 sap_sort_chl_weight(pSpectInfoParams);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002312}
2313
2314/*==========================================================================
2315 FUNCTION sap_sort_chl_weight_ht40_5_g
2316
2317 DESCRIPTION
Jeff Johnsonc7e4d162018-05-12 16:20:34 -07002318 Function to sort the channels with the least weight first for HT40 channels
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002319
2320 DEPENDENCIES
2321 NA.
2322
2323 PARAMETERS
2324
2325 IN
2326 pSpectInfoParams : Pointer to the tSapChSelSpectInfo structure
2327
2328 RETURN VALUE
2329 void : NULL
2330
2331 SIDE EFFECTS
2332 ============================================================================*/
Jeff Johnson464f7ea2016-10-07 10:21:26 -07002333static void sap_sort_chl_weight_ht40_5_g(tSapChSelSpectInfo *pSpectInfoParams)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002334{
2335 uint8_t i, j;
2336 tSapSpectChInfo *pSpectInfo;
2337
2338 pSpectInfo = pSpectInfoParams->pSpectCh;
2339 /*for each HT40 channel, calculate the combined weight of the
2340 two 20MHz weight */
2341 for (i = 0; i < ARRAY_SIZE(acs_ht40_channels5_g); i++) {
2342 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
2343 if (pSpectInfo[j].chNum ==
2344 acs_ht40_channels5_g[i].chStartNum)
2345 break;
2346 }
2347 if (j == pSpectInfoParams->numSpectChans)
2348 continue;
2349
2350 /* found the channel, add the two adjacent channels' weight */
2351 if ((pSpectInfo[j].chNum + 4) == pSpectInfo[j + 1].chNum) {
2352 acs_ht40_channels5_g[i].weight = pSpectInfo[j].weight +
2353 pSpectInfo[j + 1].weight;
2354 /* select better of the adjact channel as the primary channel */
2355 if (pSpectInfo[j].weight <= pSpectInfo[j + 1].weight) {
2356 pSpectInfo[j].weight =
2357 acs_ht40_channels5_g[i].weight;
2358 /* mark the adjacent channel's weight as max value so
2359 that it will be sorted to the bottom */
2360 pSpectInfo[j + 1].weight =
2361 SAP_ACS_WEIGHT_MAX * 2;
2362 } else {
2363 pSpectInfo[j + 1].weight =
2364 acs_ht40_channels5_g[i].weight;
2365 /* mark the adjacent channel's weight as max value so
2366 that it will be sorted to the bottom */
2367 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2;
2368 }
2369
2370 } else
2371 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2;
2372 }
2373
bingse2782382017-03-23 10:34:52 +08002374 /*
2375 *Every channel should be checked. Add the check for the omissive
2376 * channel. Mark the channel whose combination can't satisfy 40MHZ
2377 * as max value, so that it will be sorted to the bottom
2378 */
2379 for (j = 1; j < pSpectInfoParams->numSpectChans; j++) {
2380 for (i = 0; i < ARRAY_SIZE(acs_ht40_channels5_g); i++) {
2381 if (pSpectInfo[j].chNum ==
2382 (acs_ht40_channels5_g[i].chStartNum +
2383 4) &&
2384 pSpectInfo[j - 1].chNum !=
2385 acs_ht40_channels5_g[i].chStartNum) {
2386 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2;
2387 break;
2388 }
2389 }
2390 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002391 /* avoid channel 165 by setting its weight to max */
2392 pSpectInfo = pSpectInfoParams->pSpectCh;
2393 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
2394 if (CHANNEL_165 == pSpectInfo[j].chNum) {
2395 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2;
2396 break;
2397 }
2398 }
2399
2400 pSpectInfo = pSpectInfoParams->pSpectCh;
2401 for (j = 0; j < (pSpectInfoParams->numSpectChans); j++) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302402 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002403 "In %s, Channel=%d Weight= %d rssi=%d bssCount=%d",
2404 __func__, pSpectInfo->chNum, pSpectInfo->weight,
2405 pSpectInfo->rssiAgr, pSpectInfo->bssCount);
2406 pSpectInfo++;
2407 }
2408
2409 sap_sort_chl_weight(pSpectInfoParams);
2410}
2411
2412/*==========================================================================
2413 FUNCTION sap_sort_chl_weight_all
2414
2415 DESCRIPTION
Jeff Johnsonc7e4d162018-05-12 16:20:34 -07002416 Function to sort the channels with the least weight first
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002417
2418 DEPENDENCIES
2419 NA.
2420
2421 PARAMETERS
2422
2423 IN
Jeff Johnsone13d8062017-09-28 06:54:55 -07002424 sap_ctx : Pointer to the struct sap_context *structure
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002425 pSpectInfoParams : Pointer to the tSapChSelSpectInfo structure
2426
2427 RETURN VALUE
2428 void : NULL
2429
2430 SIDE EFFECTS
2431 ============================================================================*/
Jeff Johnsone13d8062017-09-28 06:54:55 -07002432static void sap_sort_chl_weight_all(struct sap_context *sap_ctx,
Jeff Johnson464f7ea2016-10-07 10:21:26 -07002433 tSapChSelSpectInfo *pSpectInfoParams,
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002434 uint32_t operatingBand,
2435 v_REGDOMAIN_t domain)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002436{
2437 tSapSpectChInfo *pSpectCh = NULL;
2438 uint32_t j = 0;
2439#ifndef SOFTAP_CHANNEL_RANGE
2440 uint32_t i = 0;
2441#endif
2442
2443 pSpectCh = pSpectInfoParams->pSpectCh;
2444#ifdef SOFTAP_CHANNEL_RANGE
2445
Jeff Johnsone13d8062017-09-28 06:54:55 -07002446 switch (sap_ctx->acs_cfg->ch_width) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002447 case CH_WIDTH_40MHZ:
Himanshu Agarwal91c5c0f2018-02-13 14:40:56 +05302448 /*
2449 * Assign max weight to all 5Ghz channels when operating band
2450 * is 11g and to all 2.4Ghz channels when operating band is 11a
2451 * or 11abg to avoid selection in ACS algorithm for starting SAP
2452 */
2453 if (eCSR_DOT11_MODE_11g == operatingBand) {
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002454 sap_sort_chl_weight_ht40_24_g(pSpectInfoParams, domain);
Himanshu Agarwal91c5c0f2018-02-13 14:40:56 +05302455 sap_allocate_max_weight_ht40_5_g(pSpectInfoParams);
2456 } else {
2457 sap_allocate_max_weight_ht40_24_g(pSpectInfoParams);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002458 sap_sort_chl_weight_ht40_5_g(pSpectInfoParams);
2459 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002460 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002461 case CH_WIDTH_80MHZ:
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07002462 case CH_WIDTH_80P80MHZ:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002463 sap_sort_chl_weight_ht80(pSpectInfoParams);
2464 break;
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07002465 case CH_WIDTH_160MHZ:
2466 sap_sort_chl_weight_vht160(pSpectInfoParams);
2467 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002468 case CH_WIDTH_20MHZ:
2469 default:
2470 /* Sorting the channels as per weights as 20MHz channels */
2471 sap_sort_chl_weight(pSpectInfoParams);
2472 }
2473
2474#else
2475 /* Sorting the channels as per weights */
2476 for (i = 0; i < SPECT_24GHZ_CH_COUNT; i++) {
2477 minWeightIndex = i;
2478 for (j = i + 1; j < SPECT_24GHZ_CH_COUNT; j++) {
2479 if (pSpectCh[j].weight <
2480 pSpectCh[minWeightIndex].weight) {
2481 minWeightIndex = j;
2482 }
2483 }
2484 if (minWeightIndex != i) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302485 qdf_mem_copy(&temp, &pSpectCh[minWeightIndex],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002486 sizeof(*pSpectCh));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302487 qdf_mem_copy(&pSpectCh[minWeightIndex], &pSpectCh[i],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002488 sizeof(*pSpectCh));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302489 qdf_mem_copy(&pSpectCh[i], &temp, sizeof(*pSpectCh));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002490 }
2491 }
2492#endif
2493
2494 /* For testing */
Ravi Joshi9788fcd2018-02-13 15:12:22 -08002495 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002496 "In %s, Sorted Spectrum Channels Weight", __func__);
2497 pSpectCh = pSpectInfoParams->pSpectCh;
2498 for (j = 0; j < (pSpectInfoParams->numSpectChans); j++) {
Ravi Joshi9788fcd2018-02-13 15:12:22 -08002499 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002500 "In %s, Channel=%d Weight= %d rssi=%d bssCount=%d",
2501 __func__, pSpectCh->chNum, pSpectCh->weight,
2502 pSpectCh->rssiAgr, pSpectCh->bssCount);
2503 pSpectCh++;
2504 }
2505
2506}
2507
Naveen Rawatbec64d92017-09-13 14:35:21 -07002508/**
2509 * sap_is_ch_non_overlap() - returns true if non-overlapping channel
2510 * @sap_ctx: Sap context
2511 * @ch: channel number
2512 *
2513 * Returns: true if non-overlapping (1, 6, 11) channel, false otherwise
2514 */
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -07002515static bool sap_is_ch_non_overlap(struct sap_context *sap_ctx, uint16_t ch)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002516{
Naveen Rawatbec64d92017-09-13 14:35:21 -07002517 if (sap_ctx->enableOverLapCh)
Srinivas Girigowda74a66d62017-06-21 23:28:25 -07002518 return true;
Naveen Rawatbec64d92017-09-13 14:35:21 -07002519
2520 if ((ch == CHANNEL_1) || (ch == CHANNEL_6) || (ch == CHANNEL_11))
Srinivas Girigowda74a66d62017-06-21 23:28:25 -07002521 return true;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002522
Srinivas Girigowda74a66d62017-06-21 23:28:25 -07002523 return false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002524}
2525
Dustin Brown0ce56d32016-10-17 16:18:03 -07002526#ifdef FEATURE_WLAN_CH_AVOID
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002527/**
2528 * sap_select_channel_no_scan_result() - select SAP channel when no scan results
2529 * are available.
2530 * @sap_ctx: Sap context
2531 *
2532 * Returns: channel number if success, 0 otherwise
2533 */
Jeff Johnson7730fbb2018-11-08 13:48:27 -08002534static uint8_t sap_select_channel_no_scan_result(mac_handle_t mac_handle,
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -07002535 struct sap_context *sap_ctx)
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002536{
Mohit Khanna841044f2016-03-25 16:16:24 -07002537 enum channel_state ch_type;
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002538 uint8_t i, first_safe_ch_in_range = SAP_CHANNEL_NOT_SELECTED;
Dustin Brown0ce56d32016-10-17 16:18:03 -07002539 uint32_t start_ch_num = sap_ctx->acs_cfg->start_ch;
2540 uint32_t end_ch_num = sap_ctx->acs_cfg->end_ch;
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002541 tpAniSirGlobal mac_ctx = NULL;
2542
Jeff Johnson7730fbb2018-11-08 13:48:27 -08002543 mac_ctx = PMAC_STRUCT(mac_handle);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002544
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002545 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2546 FL("start - end: %d - %d"), start_ch_num, end_ch_num);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002547
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002548 /* get a channel in PCL and within the range */
2549 for (i = 0; i < sap_ctx->acs_cfg->pcl_ch_count; i++) {
2550 if ((sap_ctx->acs_cfg->pcl_channels[i] < start_ch_num) ||
2551 (sap_ctx->acs_cfg->pcl_channels[i] > end_ch_num))
2552 continue;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002553
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002554 first_safe_ch_in_range = sap_ctx->acs_cfg->pcl_channels[i];
2555 break;
2556 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002557
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002558 if (SAP_CHANNEL_NOT_SELECTED != first_safe_ch_in_range)
2559 return first_safe_ch_in_range;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002560
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002561 for (i = 0; i < NUM_CHANNELS; i++) {
2562 if ((safe_channels[i].channelNumber < start_ch_num) ||
2563 (safe_channels[i].channelNumber > end_ch_num))
2564 continue;
2565
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002566 ch_type = wlan_reg_get_channel_state(mac_ctx->pdev,
2567 safe_channels[i].channelNumber);
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002568
2569 if ((ch_type == CHANNEL_STATE_DISABLE) ||
2570 (ch_type == CHANNEL_STATE_INVALID))
2571 continue;
Arif Hussain88d1fdd2018-09-26 16:12:24 -07002572 if ((!mac_ctx->mlme_cfg->dfs_cfg.dfs_master_capable) &&
2573 (CHANNEL_STATE_DFS == ch_type)) {
Kondabattini, Ganesh13bb4b12016-09-04 16:16:53 +05302574 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2575 "%s: DFS master mode disabled. Skip DFS channel %d",
2576 __func__, safe_channels[i].channelNumber);
2577 continue;
2578 }
Agrawal Ashish65634612016-08-18 13:24:32 +05302579 if ((sap_ctx->dfs_mode == ACS_DFS_MODE_DISABLE) &&
2580 (CHANNEL_STATE_DFS == ch_type))
2581 continue;
Kondabattini, Ganesh13bb4b12016-09-04 16:16:53 +05302582
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002583 if (safe_channels[i].isSafe == true) {
2584 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2585 FL("channel %d in the configuration is safe"),
2586 safe_channels[i].channelNumber);
2587 first_safe_ch_in_range = safe_channels[i].channelNumber;
2588 break;
2589 }
2590
2591 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2592 FL("channel %d in the configuration is unsafe"),
2593 safe_channels[i].channelNumber);
2594 }
2595
2596 /* if no channel selected return SAP_CHANNEL_NOT_SELECTED */
2597 return first_safe_ch_in_range;
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002598}
Dustin Brown0ce56d32016-10-17 16:18:03 -07002599#else
Jeff Johnson7730fbb2018-11-08 13:48:27 -08002600static uint8_t sap_select_channel_no_scan_result(mac_handle_t mac_handle,
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -07002601 struct sap_context *sap_ctx)
Dustin Brown0ce56d32016-10-17 16:18:03 -07002602{
2603 uint32_t start_ch_num = sap_ctx->acs_cfg->start_ch;
2604
2605 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2606 FL("start - end: %d - %d"),
2607 start_ch_num,
2608 sap_ctx->acs_cfg->end_ch);
2609
2610 sap_ctx->acs_cfg->pri_ch = start_ch_num;
2611 sap_ctx->acs_cfg->ht_sec_ch = 0;
2612
2613 /* pick the first channel in configured range */
2614 return start_ch_num;
2615}
2616#endif /* FEATURE_WLAN_CH_AVOID */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002617
2618/**
2619 * sap_select_channel() - select SAP channel
Jeff Johnson7730fbb2018-11-08 13:48:27 -08002620 * @mac_handle: Opaque handle to the global MAC context
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002621 * @sap_ctx: Sap context
2622 * @scan_result: Pointer to tScanResultHandle
2623 *
2624 * Runs a algorithm to select the best channel to operate in based on BSS
2625 * rssi and bss count on each channel
2626 *
2627 * Returns: channel number if success, 0 otherwise
2628 */
Jeff Johnson7730fbb2018-11-08 13:48:27 -08002629uint8_t sap_select_channel(mac_handle_t mac_handle,
2630 struct sap_context *sap_ctx,
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002631 tScanResultHandle scan_result)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002632{
2633 /* DFS param object holding all the data req by the algo */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002634 tSapChSelSpectInfo spect_info_obj = { NULL, 0 };
2635 tSapChSelSpectInfo *spect_info = &spect_info_obj;
2636 uint8_t best_ch_num = SAP_CHANNEL_NOT_SELECTED;
bingse2782382017-03-23 10:34:52 +08002637 uint32_t ht40plus2gendch = 0;
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002638 v_REGDOMAIN_t domain;
Arif Hussain21ad4342017-12-21 12:00:54 -08002639 uint8_t country[CDS_COUNTRY_CODE_LEN + 1];
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002640#ifdef SOFTAP_CHANNEL_RANGE
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002641 uint8_t count;
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002642 uint32_t start_ch_num, end_ch_num, tmp_ch_num, operating_band = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002643#endif
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002644 tpAniSirGlobal mac_ctx;
2645
Jeff Johnson7730fbb2018-11-08 13:48:27 -08002646 mac_ctx = PMAC_STRUCT(mac_handle);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302647 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002648 "In %s, Running SAP Ch Select", __func__);
2649
2650#ifdef FEATURE_WLAN_CH_AVOID
Jeff Johnson7730fbb2018-11-08 13:48:27 -08002651 sap_update_unsafe_channel_list(mac_handle, sap_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002652#endif
2653
gaoleze5108942017-03-31 16:56:42 +08002654 /*
2655 * If ACS weight is not enabled on noise_floor/channel_free/tx_power,
2656 * then skip acs process if no bss found.
2657 */
2658 if (NULL == scan_result &&
2659 !(sap_ctx->auto_channel_select_weight & 0xffff00)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302660 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002661 FL("No external AP present"));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002662
2663#ifndef SOFTAP_CHANNEL_RANGE
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002664 return SAP_CHANNEL_NOT_SELECTED;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002665#else
Jeff Johnson7730fbb2018-11-08 13:48:27 -08002666 return sap_select_channel_no_scan_result(mac_handle, sap_ctx);
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002667#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002668 }
2669
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002670 /* Initialize the structure pointed by spect_info */
Jeff Johnson7730fbb2018-11-08 13:48:27 -08002671 if (sap_chan_sel_init(mac_handle, spect_info, sap_ctx) != true) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302672 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002673 FL("Ch Select initialization failed"));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002674 return SAP_CHANNEL_NOT_SELECTED;
2675 }
2676 /* Compute the weight of the entire spectrum in the operating band */
Jeff Johnson7730fbb2018-11-08 13:48:27 -08002677 sap_compute_spect_weight(spect_info, mac_handle, scan_result, sap_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002678
2679#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
2680 /* process avoid channel IE to collect all channels to avoid */
Jeff Johnson7730fbb2018-11-08 13:48:27 -08002681 sap_process_avoid_ie(mac_handle, sap_ctx, scan_result, spect_info);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002682#endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
2683
Paul Zhang0f85b412018-01-18 19:14:51 +08002684 wlan_reg_read_current_country(mac_ctx->psoc, country);
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002685 wlan_reg_get_domain_from_country_code(&domain, country, SOURCE_DRIVER);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002686#ifdef SOFTAP_CHANNEL_RANGE
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002687 start_ch_num = sap_ctx->acs_cfg->start_ch;
2688 end_ch_num = sap_ctx->acs_cfg->end_ch;
2689 SET_ACS_BAND(operating_band, sap_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002690
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002691 sap_ctx->acsBestChannelInfo.channelNum = 0;
2692 sap_ctx->acsBestChannelInfo.weight = SAP_ACS_WEIGHT_MAX;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002693
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002694 /* Sort the ch lst as per the computed weights, lesser weight first. */
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002695 sap_sort_chl_weight_all(sap_ctx, spect_info, operating_band, domain);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002696
2697 /*Loop till get the best channel in the given range */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002698 for (count = 0; count < spect_info->numSpectChans; count++) {
2699 if ((start_ch_num > spect_info->pSpectCh[count].chNum) ||
2700 (end_ch_num < spect_info->pSpectCh[count].chNum))
2701 continue;
2702
2703 if (best_ch_num == SAP_CHANNEL_NOT_SELECTED) {
2704 best_ch_num = spect_info->pSpectCh[count].chNum;
2705 /* check if best_ch_num is in preferred channel list */
2706 best_ch_num =
2707 sap_select_preferred_channel_from_channel_list(
2708 best_ch_num, sap_ctx, spect_info);
2709 /* if not in preferred ch lst, go to nxt best ch */
2710 if (best_ch_num == SAP_CHANNEL_NOT_SELECTED)
2711 continue;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002712
2713#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002714 /*
2715 * Weight of the channels(device's AP is operating)
Jeff Johnson2cc31fd2018-05-05 23:54:23 -07002716 * increased to MAX+1 so that they will be chosen only
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002717 * when there is no other best channel to choose
2718 */
2719 if (sap_check_in_avoid_ch_list(sap_ctx, best_ch_num)) {
2720 best_ch_num = SAP_CHANNEL_NOT_SELECTED;
2721 continue;
2722 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002723#endif
2724
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002725 sap_ctx->acsBestChannelInfo.channelNum = best_ch_num;
2726 sap_ctx->acsBestChannelInfo.weight =
2727 spect_info->pSpectCh[count].weight_copy;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002728 }
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002729
2730 if (best_ch_num == SAP_CHANNEL_NOT_SELECTED)
2731 continue;
2732
Tushnim Bhattacharyya03103fd2017-06-23 10:48:52 -07002733 if (operating_band != eCSR_DOT11_MODE_11g) {
2734 QDF_TRACE(QDF_MODULE_ID_SAP,
2735 QDF_TRACE_LEVEL_INFO_HIGH,
2736 "operating_band %d", operating_band);
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002737 continue;
Tushnim Bhattacharyya03103fd2017-06-23 10:48:52 -07002738 }
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002739
2740 /* Give preference to Non-overlap channels */
Naveen Rawatbec64d92017-09-13 14:35:21 -07002741 if (false == sap_is_ch_non_overlap(sap_ctx,
Tushnim Bhattacharyya03103fd2017-06-23 10:48:52 -07002742 spect_info->pSpectCh[count].chNum)) {
2743 QDF_TRACE(QDF_MODULE_ID_SAP,
2744 QDF_TRACE_LEVEL_INFO_HIGH,
Naveen Rawatbec64d92017-09-13 14:35:21 -07002745 FL("ch: %d skipped as its overlapping ch"),
2746 spect_info->pSpectCh[count].chNum);
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002747 continue;
Tushnim Bhattacharyya03103fd2017-06-23 10:48:52 -07002748 }
2749
2750 if (wlan_reg_is_dfs_ch(mac_ctx->pdev,
2751 spect_info->pSpectCh[count].chNum) &&
2752 policy_mgr_disallow_mcc(mac_ctx->psoc,
2753 spect_info->pSpectCh[count].chNum)) {
2754 QDF_TRACE(QDF_MODULE_ID_SAP,
2755 QDF_TRACE_LEVEL_INFO_HIGH,
2756 "No DFS MCC");
2757 continue;
2758 }
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002759
bings14d1d3b2017-08-03 11:14:29 +08002760 if (spect_info->pSpectCh[count].weight_copy >
2761 sap_ctx->acsBestChannelInfo.weight)
2762 continue;
2763
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002764 tmp_ch_num = spect_info->pSpectCh[count].chNum;
gaoleze5108942017-03-31 16:56:42 +08002765 tmp_ch_num = sap_channel_in_acs_channel_list(
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002766 tmp_ch_num, sap_ctx, spect_info);
2767 if (tmp_ch_num == SAP_CHANNEL_NOT_SELECTED)
2768 continue;
2769
2770 best_ch_num = tmp_ch_num;
2771 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002772 }
2773#else
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002774 /* Sort the ch lst as per the computed weights, lesser weight first. */
Jeff Johnson7730fbb2018-11-08 13:48:27 -08002775 sap_sort_chl_weight_all(sap_ctx, mac_handle, spect_info);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002776 /* Get the first channel in sorted array as best 20M Channel */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002777 best_ch_num = (uint8_t) spect_info->pSpectCh[0].chNum;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002778 /* Select Best Channel from Channel List if Configured */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002779 best_ch_num = sap_select_preferred_channel_from_channel_list(
2780 best_ch_num, sap_ctx, spect_info);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002781#endif
2782
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002783 /*
2784 * in case the best channel seleted is not in PCL and there is another
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002785 * channel which has same weightage and is in PCL, choose the one in
2786 * PCL
2787 */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002788 for (count = 0; count < spect_info->numSpectChans; count++) {
2789 if (!ch_in_pcl(sap_ctx, spect_info->pSpectCh[count].chNum) ||
2790 (spect_info->pSpectCh[count].weight !=
2791 sap_ctx->acsBestChannelInfo.weight))
2792 continue;
2793
2794 if (sap_select_preferred_channel_from_channel_list(
2795 spect_info->pSpectCh[count].chNum, sap_ctx, spect_info)
2796 == SAP_CHANNEL_NOT_SELECTED)
2797 continue;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002798
2799#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002800 if (sap_check_in_avoid_ch_list(sap_ctx, best_ch_num))
2801 continue;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002802#endif
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002803 best_ch_num = spect_info->pSpectCh[count].chNum;
2804 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2805 FL("change best channel to %d in PCL"), best_ch_num);
2806 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002807 }
2808
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002809 sap_ctx->acs_cfg->pri_ch = best_ch_num;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002810 /* determine secondary channel for 2.4G channel 5, 6, 7 in HT40 */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002811 if ((operating_band != eCSR_DOT11_MODE_11g) ||
2812 (sap_ctx->acs_cfg->ch_width != CH_WIDTH_40MHZ))
2813 goto sap_ch_sel_end;
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002814 if (REGDOMAIN_FCC == domain)
bingse2782382017-03-23 10:34:52 +08002815 ht40plus2gendch = HT40PLUS_2G_FCC_CH_END;
2816 else
2817 ht40plus2gendch = HT40PLUS_2G_EURJAP_CH_END;
2818 if ((best_ch_num >= HT40MINUS_2G_CH_START) &&
2819 (best_ch_num <= ht40plus2gendch)) {
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002820 int weight_below, weight_above, i;
2821 tSapSpectChInfo *pspect_info;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002822
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002823 weight_below = weight_above = SAP_ACS_WEIGHT_MAX;
2824 pspect_info = spect_info->pSpectCh;
2825 for (i = 0; i < spect_info->numSpectChans; i++) {
2826 if (pspect_info[i].chNum == (best_ch_num - 4))
2827 weight_below = pspect_info[i].weight;
2828 if (pspect_info[i].chNum == (best_ch_num + 4))
2829 weight_above = pspect_info[i].weight;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002830 }
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002831
2832 if (weight_below < weight_above)
2833 sap_ctx->acs_cfg->ht_sec_ch =
2834 sap_ctx->acs_cfg->pri_ch - 4;
2835 else
2836 sap_ctx->acs_cfg->ht_sec_ch =
2837 sap_ctx->acs_cfg->pri_ch + 4;
2838 } else if (best_ch_num >= 1 && best_ch_num <= 4) {
2839 sap_ctx->acs_cfg->ht_sec_ch = sap_ctx->acs_cfg->pri_ch + 4;
bingse2782382017-03-23 10:34:52 +08002840 } else if (best_ch_num >= ht40plus2gendch && best_ch_num <=
2841 HT40MINUS_2G_CH_END) {
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002842 sap_ctx->acs_cfg->ht_sec_ch = sap_ctx->acs_cfg->pri_ch - 4;
2843 } else if (best_ch_num == 14) {
2844 sap_ctx->acs_cfg->ht_sec_ch = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002845 }
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002846 sap_ctx->secondary_ch = sap_ctx->acs_cfg->ht_sec_ch;
2847
2848sap_ch_sel_end:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002849 /* Free all the allocated memory */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002850 sap_chan_sel_exit(spect_info);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002851
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302852 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002853 FL("Running SAP Ch select Completed, Ch=%d"), best_ch_num);
wadesongcb0ded22018-02-02 17:57:20 +08002854 host_log_acs_best_chan(best_ch_num, sap_ctx->acsBestChannelInfo.weight);
2855
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002856 if (best_ch_num > 0 && best_ch_num <= 252)
2857 return best_ch_num;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002858 else
2859 return SAP_CHANNEL_NOT_SELECTED;
2860}