blob: 8401fe1d6bd1d3c3e3b44f47d457fdb89ae8c870 [file] [log] [blame]
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001/*
gaurank kathpalia1dea75b2019-01-10 13:53:43 +05302 * Copyright (c) 2012-2019 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"
jiad391c5282018-11-26 16:21:04 +080046#include <wlan_utility.h>
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080047#endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
Deepthi Gowri48b89332016-08-30 18:43:05 +053048#include "cds_utils.h"
Yuanyuan Liu0e0aa932016-05-12 10:17:58 -070049#include "pld_common.h"
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -070050#include "wlan_reg_services_api.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080051
52/*--------------------------------------------------------------------------
53 Function definitions
54 --------------------------------------------------------------------------*/
55
56/*--------------------------------------------------------------------------
57 Defines
58 --------------------------------------------------------------------------*/
59#define SAP_DEBUG
60
61#define IS_RSSI_VALID(extRssi, rssi) \
62 ( \
63 ((extRssi < rssi) ? true : false) \
64 )
65
Jeff Johnsone13d8062017-09-28 06:54:55 -070066#define SET_ACS_BAND(acs_band, sap_ctx) \
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080067{ \
Jeff Johnsone13d8062017-09-28 06:54:55 -070068 if (sap_ctx->acs_cfg->start_ch <= 14 && \
69 sap_ctx->acs_cfg->end_ch <= 14) \
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080070 acs_band = eCSR_DOT11_MODE_11g; \
Jeff Johnsone13d8062017-09-28 06:54:55 -070071 else if (sap_ctx->acs_cfg->start_ch >= 14)\
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080072 acs_band = eCSR_DOT11_MODE_11a; \
73 else \
74 acs_band = eCSR_DOT11_MODE_abg; \
75}
76
gaoleze5108942017-03-31 16:56:42 +080077#define ACS_WEIGHT_AMOUNT_LOCAL 240
78
79#define ACS_WEIGHT_AMOUNT_CONFIG(weights) \
80 (((weights) & 0xf) + \
81 (((weights) & 0xf0) >> 4) + \
82 (((weights) & 0xf00) >> 8) + \
83 (((weights) & 0xf000) >> 12) + \
84 (((weights) & 0xf0000) >> 16) + \
85 (((weights) & 0xf00000) >> 20))
86
87/*
88 * LSH/RSH 4 to enhance the accurate since
89 * need to do modulation to ACS_WEIGHT_AMOUNT_LOCAL.
90 */
91#define ACS_WEIGHT_COMPUTE(weights, weight, factor, base) \
92 (((((((((weight) << 4) * ACS_WEIGHT_AMOUNT_LOCAL * (factor)) + \
93 (ACS_WEIGHT_AMOUNT_CONFIG((weights)) >> 1)) / \
94 ACS_WEIGHT_AMOUNT_CONFIG((weights))) + \
95 ((base) >> 1)) / (base)) + 8) >> 4)
96
97#define ACS_WEIGHT_CFG_TO_LOCAL(weights, weight) \
98 (((((((weight) << 4) * ACS_WEIGHT_AMOUNT_LOCAL) + \
99 (ACS_WEIGHT_AMOUNT_CONFIG((weights)) >> 1)) / \
100 ACS_WEIGHT_AMOUNT_CONFIG((weights))) + 8) >> 4)
101
102#define ACS_WEIGHT_SOFTAP_RSSI_CFG(weights) \
103 ((weights) & 0xf)
104
105#define ACS_WEIGHT_SOFTAP_COUNT_CFG(weights) \
106 (((weights) & 0xf0) >> 4)
107
108#define ACS_WEIGHT_SOFTAP_NOISE_FLOOR_CFG(weights) \
109 (((weights) & 0xf00) >> 8)
110
111#define ACS_WEIGHT_SOFTAP_CHANNEL_FREE_CFG(weights) \
112 (((weights) & 0xf000) >> 12)
113
114#define ACS_WEIGHT_SOFTAP_TX_POWER_RANGE_CFG(weights) \
115 (((weights) & 0xf0000) >> 16)
116
117#define ACS_WEIGHT_SOFTAP_TX_POWER_THROUGHPUT_CFG(weights) \
118 (((weights) & 0xf00000) >> 20)
119
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800120#ifdef FEATURE_WLAN_CH_AVOID
Amar Singhalb8d4f152016-02-10 10:21:43 -0800121sapSafeChannelType safe_channels[NUM_CHANNELS] = {
122 {1, true},
123 {2, true},
124 {3, true},
125 {4, true},
126 {5, true},
127 {6, true},
128 {7, true},
129 {8, true},
130 {9, true},
131 {10, true},
132 {11, true},
133 {12, true},
134 {13, true},
135 {14, true},
136 {36, true},
137 {40, true},
138 {44, true},
139 {48, true},
140 {52, true},
141 {56, true},
142 {60, true},
143 {64, true},
144 {100, true},
145 {104, true},
146 {108, true},
147 {112, true},
148 {116, true},
149 {120, true},
150 {124, true},
151 {128, true},
152 {132, true},
153 {136, true},
154 {140, true},
155 {144, true},
156 {149, true},
157 {153, true},
158 {157, true},
159 {161, true},
160 {165, true},
Kiran Kumar Lokere1a43bcf2018-05-15 15:51:58 -0700161 {169, true},
162 {173, true},
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800163};
164#endif
165
166typedef struct {
167 uint16_t chStartNum;
168 uint32_t weight;
169} sapAcsChannelInfo;
170
171sapAcsChannelInfo acs_ht40_channels5_g[] = {
172 {36, SAP_ACS_WEIGHT_MAX},
173 {44, SAP_ACS_WEIGHT_MAX},
174 {52, SAP_ACS_WEIGHT_MAX},
175 {60, SAP_ACS_WEIGHT_MAX},
176 {100, SAP_ACS_WEIGHT_MAX},
177 {108, SAP_ACS_WEIGHT_MAX},
178 {116, SAP_ACS_WEIGHT_MAX},
179 {124, SAP_ACS_WEIGHT_MAX},
180 {132, SAP_ACS_WEIGHT_MAX},
181 {140, SAP_ACS_WEIGHT_MAX},
182 {149, SAP_ACS_WEIGHT_MAX},
183 {157, SAP_ACS_WEIGHT_MAX},
184};
185
186sapAcsChannelInfo acs_ht80_channels[] = {
187 {36, SAP_ACS_WEIGHT_MAX},
188 {52, SAP_ACS_WEIGHT_MAX},
189 {100, SAP_ACS_WEIGHT_MAX},
190 {116, SAP_ACS_WEIGHT_MAX},
191 {132, SAP_ACS_WEIGHT_MAX},
192 {149, SAP_ACS_WEIGHT_MAX},
193};
194
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -0700195sapAcsChannelInfo acs_vht160_channels[] = {
196 {36, SAP_ACS_WEIGHT_MAX},
197 {100, SAP_ACS_WEIGHT_MAX},
198};
199
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800200sapAcsChannelInfo acs_ht40_channels24_g[] = {
201 {1, SAP_ACS_WEIGHT_MAX},
202 {2, SAP_ACS_WEIGHT_MAX},
203 {3, SAP_ACS_WEIGHT_MAX},
204 {4, SAP_ACS_WEIGHT_MAX},
205 {9, SAP_ACS_WEIGHT_MAX},
206};
207
208#define CHANNEL_165 165
209
210/* rssi discount for channels in PCL */
211#define PCL_RSSI_DISCOUNT 10
212
213#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
214/**
215 * sap_check_n_add_channel() - checks and add given channel in sap context's
216 * avoid_channels_info struct
217 * @sap_ctx: sap context.
218 * @new_channel: channel to be added to sap_ctx's avoid ch info
219 *
220 * sap_ctx contains sap_avoid_ch_info strcut containing the list of channels on
221 * which MDM device's AP with MCC was detected. This function will add channels
222 * to that list after checking for duplicates.
223 *
224 * Return: true: if channel was added or already present
225 * else false: if channel list was already full.
226 */
Tang Yingying523322d2017-01-17 23:28:43 +0800227static bool
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -0700228sap_check_n_add_channel(struct sap_context *sap_ctx,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800229 uint8_t new_channel)
230{
231 uint8_t i = 0;
232 struct sap_avoid_channels_info *ie_info =
233 &sap_ctx->sap_detected_avoid_ch_ie;
234
235 for (i = 0; i < sizeof(ie_info->channels); i++) {
236 if (ie_info->channels[i] == new_channel)
237 break;
238
239 if (ie_info->channels[i] == 0) {
240 ie_info->channels[i] = new_channel;
241 break;
242 }
243 }
244 if (i == sizeof(ie_info->channels))
245 return false;
246 else
247 return true;
248}
249/**
250 * sap_check_n_add_overlapped_chnls() - checks & add overlapped channels
251 * to primary channel in 2.4Ghz band.
252 * @sap_ctx: sap context.
253 * @primary_chnl: primary channel to be avoided.
254 *
255 * sap_ctx contains sap_avoid_ch_info struct containing the list of channels on
256 * which MDM device's AP with MCC was detected. This function will add channels
257 * to that list after checking for duplicates.
258 *
259 * Return: true: if channel was added or already present
260 * else false: if channel list was already full.
261 */
262static bool
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -0700263sap_check_n_add_overlapped_chnls(struct sap_context *sap_ctx,
264 uint8_t primary_channel)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800265{
266 uint8_t i = 0, j = 0, upper_chnl = 0, lower_chnl = 0;
267 struct sap_avoid_channels_info *ie_info =
268 &sap_ctx->sap_detected_avoid_ch_ie;
269 /*
270 * if primary channel less than channel 1 or out of 2g band then
271 * no further process is required. return true in this case.
272 */
273 if (primary_channel < CHANNEL_1 || primary_channel > CHANNEL_14)
274 return true;
275
276 /* lower channel is one channel right before primary channel */
277 lower_chnl = primary_channel - 1;
278 /* upper channel is one channel right after primary channel */
279 upper_chnl = primary_channel + 1;
280
281 /* lower channel needs to be non-zero, zero is not valid channel */
282 if (lower_chnl > (CHANNEL_1 - 1)) {
283 for (i = 0; i < sizeof(ie_info->channels); i++) {
284 if (ie_info->channels[i] == lower_chnl)
285 break;
286 if (ie_info->channels[i] == 0) {
287 ie_info->channels[i] = lower_chnl;
288 break;
289 }
290 }
291 }
292 /* upper channel needs to be atleast last channel in 2.4Ghz band */
293 if (upper_chnl < (CHANNEL_14 + 1)) {
294 for (j = 0; j < sizeof(ie_info->channels); j++) {
295 if (ie_info->channels[j] == upper_chnl)
296 break;
297 if (ie_info->channels[j] == 0) {
298 ie_info->channels[j] = upper_chnl;
299 break;
300 }
301 }
302 }
303 if (i == sizeof(ie_info->channels) || j == sizeof(ie_info->channels))
304 return false;
305 else
306 return true;
307}
308
309/**
310 * sap_process_avoid_ie() - processes the detected Q2Q IE
311 * context's avoid_channels_info struct
Jeff Johnson7730fbb2018-11-08 13:48:27 -0800312 * @mac_handle: opaque handle to the MAC context
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800313 * @sap_ctx: sap context.
314 * @scan_result: scan results for ACS scan.
315 * @spect_info: spectrum weights array to update
316 *
317 * Detection of Q2Q IE indicates presence of another MDM device with its AP
318 * operating in MCC mode. This function parses the scan results and processes
319 * the Q2Q IE if found. It then extracts the channels and populates them in
320 * sap_ctx struct. It also increases the weights of those channels so that
321 * ACS logic will avoid those channels in its selection algorithm.
322 *
323 * Return: void
324 */
Jeff Johnson7730fbb2018-11-08 13:48:27 -0800325static void sap_process_avoid_ie(mac_handle_t mac_handle,
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -0700326 struct sap_context *sap_ctx,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800327 tScanResultHandle scan_result,
328 tSapChSelSpectInfo *spect_info)
329{
330 uint32_t total_ie_len = 0;
jiad391c5282018-11-26 16:21:04 +0800331 const uint8_t *temp_ptr = NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800332 uint8_t i = 0;
333 struct sAvoidChannelIE *avoid_ch_ie;
334 tCsrScanResultInfo *node = NULL;
Jeff Johnsonc59ef8b2018-12-02 12:01:21 -0800335 struct mac_context *mac_ctx = NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800336 tSapSpectChInfo *spect_ch = NULL;
337
Jeff Johnsona0619e42018-11-28 17:43:00 -0800338 mac_ctx = MAC_CONTEXT(mac_handle);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800339 spect_ch = spect_info->pSpectCh;
Jeff Johnson7730fbb2018-11-08 13:48:27 -0800340 node = sme_scan_result_get_first(mac_handle, scan_result);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800341
342 while (node) {
Abhishek Singh34a4d862016-10-26 16:01:51 +0530343 total_ie_len =
Jeff Johnson38e38a82017-10-06 10:32:31 -0700344 GET_IE_LEN_IN_BSS(node->BssDescriptor.length);
Naveen Rawat08db88f2017-09-08 15:07:48 -0700345 temp_ptr = wlan_get_vendor_ie_ptr_from_oui(
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800346 SIR_MAC_QCOM_VENDOR_OUI,
347 SIR_MAC_QCOM_VENDOR_SIZE,
348 ((uint8_t *)&node->BssDescriptor.ieFields),
349 total_ie_len);
350
351 if (temp_ptr) {
352 avoid_ch_ie = (struct sAvoidChannelIE *)temp_ptr;
Will Huang55ba1042017-03-22 10:43:30 +0800353 if (avoid_ch_ie->type !=
354 QCOM_VENDOR_IE_MCC_AVOID_CH) {
Jeff Johnson7730fbb2018-11-08 13:48:27 -0800355 node = sme_scan_result_get_next(mac_handle,
Will Huang55ba1042017-03-22 10:43:30 +0800356 scan_result);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800357 continue;
Will Huang55ba1042017-03-22 10:43:30 +0800358 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800359
360 sap_ctx->sap_detected_avoid_ch_ie.present = 1;
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530361 QDF_TRACE(QDF_MODULE_ID_SAP,
362 QDF_TRACE_LEVEL_DEBUG,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800363 "Q2Q IE - avoid ch %d",
364 avoid_ch_ie->channel);
365 /* add this channel to to_avoid channel list */
366 sap_check_n_add_channel(sap_ctx,
367 avoid_ch_ie->channel);
368 sap_check_n_add_overlapped_chnls(sap_ctx,
369 avoid_ch_ie->channel);
370 /*
371 * Mark weight of these channel present in IE to MAX
372 * so that ACS logic will to avoid thse channels
373 */
374 for (i = 0; i < spect_info->numSpectChans; i++)
375 if (spect_ch[i].chNum == avoid_ch_ie->channel) {
376 /*
377 * weight is set more than max so that,
378 * in the case of other channels being
379 * assigned max weight due to noise,
380 * they may be preferred over channels
381 * with Q2Q IE.
382 */
383 spect_ch[i].weight = SAP_ACS_WEIGHT_MAX + 1;
384 spect_ch[i].weight_copy =
385 SAP_ACS_WEIGHT_MAX + 1;
386 break;
387 }
388 } /* if (temp_ptr) */
Jeff Johnson7730fbb2018-11-08 13:48:27 -0800389 node = sme_scan_result_get_next(mac_handle, scan_result);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800390 }
391}
392#endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
393
394#ifdef FEATURE_WLAN_CH_AVOID
395/*==========================================================================
396 FUNCTION sap_update_unsafe_channel_list
397
398 DESCRIPTION
399 Function Undate unsafe channel list table
400
401 DEPENDENCIES
402 NA.
403
404 IN
405 SapContext pointer
406
407 RETURN VALUE
408 NULL
409 ============================================================================*/
Jeff Johnsonb91e2d92019-03-26 09:51:30 -0700410static void sap_update_unsafe_channel_list(mac_handle_t mac_handle,
411 struct sap_context *sap_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800412{
413 uint16_t i, j;
Amar Singhalb8d4f152016-02-10 10:21:43 -0800414 uint16_t unsafe_channel_list[NUM_CHANNELS];
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800415 uint16_t unsafe_channel_count = 0;
Jeff Johnsonc59ef8b2018-12-02 12:01:21 -0800416 struct mac_context *mac_ctx = NULL;
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -0700417
Yuanyuan Liu0e0aa932016-05-12 10:17:58 -0700418 qdf_device_t qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800419
Yuanyuan Liu97361182016-06-06 09:38:04 -0700420 if (!qdf_ctx) {
421 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_FATAL,
422 "qdf_ctx is NULL");
423 return;
424 }
Jeff Johnsona0619e42018-11-28 17:43:00 -0800425 mac_ctx = MAC_CONTEXT(mac_handle);
Yuanyuan Liu97361182016-06-06 09:38:04 -0700426
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800427 /* Flush, default set all channel safe */
Amar Singhalb8d4f152016-02-10 10:21:43 -0800428 for (i = 0; i < NUM_CHANNELS; i++) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800429 safe_channels[i].isSafe = true;
430 }
431
432 /* Try to find unsafe channel */
Ryan Hsu4252a2f2016-01-05 11:18:24 -0800433#if defined(FEATURE_WLAN_STA_AP_MODE_DFS_DISABLE)
Amar Singhalb8d4f152016-02-10 10:21:43 -0800434 for (i = 0; i < NUM_CHANNELS; i++) {
Jeff Johnsone13d8062017-09-28 06:54:55 -0700435 if (sap_ctx->dfs_ch_disable == true) {
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -0700436 if (wlan_reg_is_dfs_ch(mac_ctx->pdev,
437 safe_channels[i].channelNumber)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800438 safe_channels[i].isSafe = false;
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530439 QDF_TRACE(QDF_MODULE_ID_SAP,
440 QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800441 "%s: DFS Ch %d is not safe in"
442 " Concurrent mode",
443 __func__,
444 safe_channels[i].channelNumber);
445 }
446 }
447 }
448#endif
Yuanyuan Liu0e0aa932016-05-12 10:17:58 -0700449 pld_get_wlan_unsafe_channel(qdf_ctx->dev,
450 unsafe_channel_list,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800451 &unsafe_channel_count,
452 sizeof(unsafe_channel_list));
453
Jingxiang Ge37d878c2019-01-08 14:43:05 +0800454 unsafe_channel_count = QDF_MIN(unsafe_channel_count,
455 (uint16_t)NUM_CHANNELS);
456
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800457 for (i = 0; i < unsafe_channel_count; i++) {
Amar Singhalb8d4f152016-02-10 10:21:43 -0800458 for (j = 0; j < NUM_CHANNELS; j++) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800459 if (safe_channels[j].channelNumber ==
460 unsafe_channel_list[i]) {
461 /* Found unsafe channel, update it */
462 safe_channels[j].isSafe = false;
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530463 QDF_TRACE(QDF_MODULE_ID_SAP,
464 QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800465 FL("CH %d is not safe"),
466 unsafe_channel_list[i]);
467 break;
468 }
469 }
470 }
471
472 return;
473}
Jeff Johnsonb91e2d92019-03-26 09:51:30 -0700474#else
475static void sap_update_unsafe_channel_list(mac_handle_t mac_handle,
476 struct sap_context *sap_ctx)
477{
478}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800479#endif /* FEATURE_WLAN_CH_AVOID */
480
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800481/**
gaoleze5108942017-03-31 16:56:42 +0800482 * sap_channel_in_acs_channel_list() - check if channel in acs channel list
483 * @channel_num: channel to check
484 * @sap_ctx: struct ptSapContext
485 * @spect_info_params: strcut tSapChSelSpectInfo
486 *
487 * This function checks if specified channel is in the configured ACS channel
488 * list.
489 *
490 * Return: channel number if in acs channel list or SAP_CHANNEL_NOT_SELECTED
491 */
gaoleze5108942017-03-31 16:56:42 +0800492uint8_t sap_channel_in_acs_channel_list(uint8_t channel_num,
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -0700493 struct sap_context *sap_ctx,
gaoleze5108942017-03-31 16:56:42 +0800494 tSapChSelSpectInfo *spect_info_params)
495{
496 uint8_t i = 0;
497
Jeff Johnson4cfe6cc2019-03-18 13:40:27 -0700498 if ((!sap_ctx->acs_cfg->ch_list) ||
499 (!spect_info_params))
gaoleze5108942017-03-31 16:56:42 +0800500 return channel_num;
501
502 if (channel_num > 0 && channel_num <= 252) {
503 for (i = 0; i < sap_ctx->acs_cfg->ch_list_count; i++) {
504 if ((sap_ctx->acs_cfg->ch_list[i]) == channel_num)
505 return channel_num;
506 }
507 return SAP_CHANNEL_NOT_SELECTED;
508 } else {
509 return SAP_CHANNEL_NOT_SELECTED;
510 }
511}
512
513/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800514 * sap_select_preferred_channel_from_channel_list() - to calc best cahnnel
515 * @best_chnl: best channel already calculated among all the chanels
516 * @sap_ctx: sap context
517 * @spectinfo_param: Pointer to tSapChSelSpectInfo structure
518 *
519 * This function calculates the best channel among the configured channel list.
520 * If channel list not configured then returns the best channel calculated
521 * among all the channel list.
522 *
523 * Return: uint8_t best channel
524 */
Jeff Johnson464f7ea2016-10-07 10:21:26 -0700525static
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800526uint8_t sap_select_preferred_channel_from_channel_list(uint8_t best_chnl,
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -0700527 struct sap_context *sap_ctx,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800528 tSapChSelSpectInfo *spectinfo_param)
529{
530 uint8_t i = 0;
Jeff Johnsonc59ef8b2018-12-02 12:01:21 -0800531 struct mac_context *mac_ctx = sme_get_mac_context();
Tushnim Bhattacharyya518e80f2017-08-30 17:35:33 -0700532
Jeff Johnson4cfe6cc2019-03-18 13:40:27 -0700533 if (!mac_ctx) {
Tushnim Bhattacharyya518e80f2017-08-30 17:35:33 -0700534 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
535 "pmac Global Context is NULL");
536 return SAP_CHANNEL_NOT_SELECTED;
537 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800538
539 /*
540 * If Channel List is not Configured don't do anything
541 * Else return the Best Channel from the Channel List
542 */
Jeff Johnson4cfe6cc2019-03-18 13:40:27 -0700543 if ((!sap_ctx->acs_cfg->ch_list) ||
544 (!spectinfo_param) ||
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800545 (0 == sap_ctx->acs_cfg->ch_list_count))
546 return best_chnl;
547
548 if (best_chnl <= 0 || best_chnl > 252)
549 return SAP_CHANNEL_NOT_SELECTED;
550
551 /* Select the best channel from allowed list */
552 for (i = 0; i < sap_ctx->acs_cfg->ch_list_count; i++) {
Tushnim Bhattacharyya518e80f2017-08-30 17:35:33 -0700553 if ((sap_ctx->acs_cfg->ch_list[i] == best_chnl) &&
554 !(wlan_reg_is_dfs_ch(mac_ctx->pdev, best_chnl) &&
555 policy_mgr_disallow_mcc(mac_ctx->psoc, best_chnl))) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530556 QDF_TRACE(QDF_MODULE_ID_SAP,
Ravi Joshi9788fcd2018-02-13 15:12:22 -0800557 QDF_TRACE_LEVEL_INFO,
Naveen Rawatbec64d92017-09-13 14:35:21 -0700558 "Best channel so far is: %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800559 best_chnl);
560 return best_chnl;
561 }
562 }
563
564 return SAP_CHANNEL_NOT_SELECTED;
565}
566
Jeff Johnson7730fbb2018-11-08 13:48:27 -0800567/**
568 * sap_chan_sel_init() - Initialize channel select
569 * @mac_handle: Opaque handle to the global MAC context
570 * @pSpectInfoParams: Pointer to tSapChSelSpectInfo structure
571 * @sap_ctx: Pointer to SAP Context
572 *
573 * Function sap_chan_sel_init allocates the memory, initializes the
574 * structures used by the channel selection algorithm
575 *
576 * Return: bool Success or FAIL
577 */
578static bool sap_chan_sel_init(mac_handle_t mac_handle,
Jeff Johnson464f7ea2016-10-07 10:21:26 -0700579 tSapChSelSpectInfo *pSpectInfoParams,
Jeff Johnsone13d8062017-09-28 06:54:55 -0700580 struct sap_context *sap_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800581{
582 tSapSpectChInfo *pSpectCh = NULL;
583 uint8_t *pChans = NULL;
584 uint16_t channelnum = 0;
Jeff Johnsonc59ef8b2018-12-02 12:01:21 -0800585 struct mac_context *mac = MAC_CONTEXT(mac_handle);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800586 bool chSafe = true;
587#ifdef FEATURE_WLAN_CH_AVOID
588 uint16_t i;
589#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800590 bool include_dfs_ch = true;
Himanshu Agarwalfee2e362018-01-18 20:26:35 +0530591 uint8_t chan_num;
Bala Venkatesh2f25c812017-12-15 17:42:12 +0530592 bool sta_sap_scc_on_dfs_chan =
Jeff Johnsonb9794442018-11-22 14:21:08 -0800593 policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan(mac->psoc);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800594
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530595 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, "In %s",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800596 __func__);
597
598 pSpectInfoParams->numSpectChans =
Jeff Johnsonb9794442018-11-22 14:21:08 -0800599 mac->scan.base_channels.numChannels;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800600
601 /* Allocate memory for weight computation of 2.4GHz */
Arif Hussain256cc282018-10-03 14:10:44 -0700602 pSpectCh = qdf_mem_malloc((pSpectInfoParams->numSpectChans) *
603 sizeof(*pSpectCh));
604 if (!pSpectCh)
Srinivas Girigowda74a66d62017-06-21 23:28:25 -0700605 return false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800606
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800607 /* Initialize the pointers in the DfsParams to the allocated memory */
608 pSpectInfoParams->pSpectCh = pSpectCh;
609
Jeff Johnsonb9794442018-11-22 14:21:08 -0800610 pChans = mac->scan.base_channels.channelList;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800611
Ryan Hsu4252a2f2016-01-05 11:18:24 -0800612#if defined(FEATURE_WLAN_STA_AP_MODE_DFS_DISABLE)
Jeff Johnsone13d8062017-09-28 06:54:55 -0700613 if (sap_ctx->dfs_ch_disable == true)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800614 include_dfs_ch = false;
615#endif
Jeff Johnsonb9794442018-11-22 14:21:08 -0800616 if (!mac->mlme_cfg->dfs_cfg.dfs_master_capable ||
Jeff Johnsone13d8062017-09-28 06:54:55 -0700617 ACS_DFS_MODE_DISABLE == sap_ctx->dfs_mode)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800618 include_dfs_ch = false;
619
620 /* Fill the channel number in the spectrum in the operating freq band */
621 for (channelnum = 0;
622 channelnum < pSpectInfoParams->numSpectChans;
Edhar, Mahesh Kumar4f660672015-10-30 11:53:26 +0530623 channelnum++, pChans++, pSpectCh++) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800624 chSafe = true;
625
Himanshu Agarwal052ce252018-06-18 17:18:59 +0530626 pSpectCh->chNum = *pChans;
627 /* Initialise for all channels */
628 pSpectCh->rssiAgr = SOFTAP_MIN_RSSI;
629 /* Initialise 20MHz for all the Channels */
630 pSpectCh->channelWidth = SOFTAP_HT20_CHANNELWIDTH;
631 /* Initialise max ACS weight for all channels */
632 pSpectCh->weight = SAP_ACS_WEIGHT_MAX;
633
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800634 /* check if the channel is in NOL blacklist */
Himanshu Agarwal052ce252018-06-18 17:18:59 +0530635 if (sap_dfs_is_channel_in_nol_list(
636 sap_ctx, *pChans,
637 PHY_SINGLE_CHANNEL_CENTERED)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530638 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800639 "In %s, Ch %d is in NOL list", __func__,
640 *pChans);
641 chSafe = false;
642 continue;
643 }
644
Bala Venkatesh2f25c812017-12-15 17:42:12 +0530645 if (!include_dfs_ch || sta_sap_scc_on_dfs_chan) {
Jeff Johnsonb9794442018-11-22 14:21:08 -0800646 if (wlan_reg_is_dfs_ch(mac->pdev, *pChans)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800647 chSafe = false;
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530648 QDF_TRACE(QDF_MODULE_ID_SAP,
649 QDF_TRACE_LEVEL_INFO_HIGH,
Bala Venkatesh2f25c812017-12-15 17:42:12 +0530650 "In %s, DFS Ch %d not considered for ACS. include_dfs_ch %u, sta_sap_scc_on_dfs_chan %d",
651 __func__, *pChans, include_dfs_ch,
652 sta_sap_scc_on_dfs_chan);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800653 continue;
654 }
655 }
656
657#ifdef FEATURE_WLAN_CH_AVOID
Amar Singhalb8d4f152016-02-10 10:21:43 -0800658 for (i = 0; i < NUM_CHANNELS; i++) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800659 if ((safe_channels[i].channelNumber == *pChans) &&
660 (false == safe_channels[i].isSafe)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530661 QDF_TRACE(QDF_MODULE_ID_SAP,
662 QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800663 "In %s, Ch %d is not safe", __func__,
664 *pChans);
665 chSafe = false;
666 break;
667 }
668 }
669#endif /* FEATURE_WLAN_CH_AVOID */
670
671 /* OFDM rates are not supported on channel 14 */
672 if (*pChans == 14 &&
Jeff Johnsone13d8062017-09-28 06:54:55 -0700673 eCSR_DOT11_MODE_11b != sap_ctx->csr_roamProfile.phyMode) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800674 continue;
675 }
676
Deepthi Gowri48b89332016-08-30 18:43:05 +0530677 /* Skip DSRC channels */
Jeff Johnsonb9794442018-11-22 14:21:08 -0800678 if (wlan_reg_is_dsrc_chan(mac->pdev, *pChans))
Kiran Kumar Lokere1a43bcf2018-05-15 15:51:58 -0700679 continue;
680
lifeng0b46ae52018-12-13 09:42:27 +0800681 if (!mac->mlme_cfg->reg.etsi13_srd_chan_in_master_mode &&
Jeff Johnsonb9794442018-11-22 14:21:08 -0800682 wlan_reg_is_etsi13_srd_chan(mac->pdev, *pChans))
Deepthi Gowri48b89332016-08-30 18:43:05 +0530683 continue;
684
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800685 if (true == chSafe) {
Srinivas Girigowda74a66d62017-06-21 23:28:25 -0700686 pSpectCh->valid = true;
Himanshu Agarwalfee2e362018-01-18 20:26:35 +0530687 for (chan_num = 0; chan_num < sap_ctx->num_of_channel;
688 chan_num++) {
689 if (pSpectCh->chNum !=
690 sap_ctx->channelList[chan_num])
691 continue;
692
693 /*
694 * Initialize ACS weight to 0 for channels
695 * present in sap context scan channel list
696 */
697 pSpectCh->weight = 0;
698 break;
699 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800700 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800701 }
Srinivas Girigowda74a66d62017-06-21 23:28:25 -0700702 return true;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800703}
704
gaoleze5108942017-03-31 16:56:42 +0800705/**
706 * sapweight_rssi_count() - calculates the channel weight due to rssi
Anurag Chouhan6d760662016-02-20 16:05:43 +0530707 and data count(here number of BSS observed)
gaoleze5108942017-03-31 16:56:42 +0800708 * @sap_ctx : Softap context
709 * @rssi : Max signal strength receieved from a BSS for the channel
710 * @count : Number of BSS observed in the channel
711 *
712 * Return: uint32_t Calculated channel weight based on above two
713 */
714static
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -0700715uint32_t sapweight_rssi_count(struct sap_context *sap_ctx, int8_t rssi,
gaoleze5108942017-03-31 16:56:42 +0800716 uint16_t count)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800717{
718 int32_t rssiWeight = 0;
719 int32_t countWeight = 0;
720 uint32_t rssicountWeight = 0;
gaoleze5108942017-03-31 16:56:42 +0800721 uint8_t softap_rssi_weight_cfg, softap_count_weight_cfg;
722 uint8_t softap_rssi_weight_local, softap_count_weight_local;
723
724 softap_rssi_weight_cfg =
725 ACS_WEIGHT_SOFTAP_RSSI_CFG(sap_ctx->auto_channel_select_weight);
726
727 softap_count_weight_cfg =
728 ACS_WEIGHT_SOFTAP_COUNT_CFG(sap_ctx->auto_channel_select_weight);
729
730 softap_rssi_weight_local =
731 ACS_WEIGHT_CFG_TO_LOCAL(sap_ctx->auto_channel_select_weight,
732 softap_rssi_weight_cfg);
733
734 softap_count_weight_local =
735 ACS_WEIGHT_CFG_TO_LOCAL(sap_ctx->auto_channel_select_weight,
736 softap_count_weight_cfg);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800737
738 /* Weight from RSSI */
gaoleze5108942017-03-31 16:56:42 +0800739 rssiWeight = ACS_WEIGHT_COMPUTE(sap_ctx->auto_channel_select_weight,
740 softap_rssi_weight_cfg,
741 rssi - SOFTAP_MIN_RSSI,
742 SOFTAP_MAX_RSSI - SOFTAP_MIN_RSSI);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800743
gaoleze5108942017-03-31 16:56:42 +0800744 if (rssiWeight > softap_rssi_weight_local)
745 rssiWeight = softap_rssi_weight_local;
746
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800747 else if (rssiWeight < 0)
748 rssiWeight = 0;
749
750 /* Weight from data count */
gaoleze5108942017-03-31 16:56:42 +0800751 countWeight = ACS_WEIGHT_COMPUTE(sap_ctx->auto_channel_select_weight,
752 softap_count_weight_cfg,
753 count - SOFTAP_MIN_COUNT,
754 SOFTAP_MAX_COUNT - SOFTAP_MIN_COUNT);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800755
gaoleze5108942017-03-31 16:56:42 +0800756 if (countWeight > softap_count_weight_local)
757 countWeight = softap_count_weight_local;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800758
759 rssicountWeight = rssiWeight + countWeight;
760
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530761 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800762 "In %s, rssiWeight=%d, countWeight=%d, rssicountWeight=%d",
763 __func__, rssiWeight, countWeight, rssicountWeight);
764
765 return rssicountWeight;
766}
767
768/**
gaoleze5108942017-03-31 16:56:42 +0800769 * sap_get_channel_status() - get channel info via channel number
770 * @p_mac: Pointer to Global MAC structure
771 * @channel_id: channel id
772 *
773 * Return: chan status info
774 */
775static struct lim_channel_status *sap_get_channel_status
Jeff Johnsonc59ef8b2018-12-02 12:01:21 -0800776 (struct mac_context *p_mac, uint32_t channel_id)
gaoleze5108942017-03-31 16:56:42 +0800777{
778 return csr_get_channel_status(p_mac, channel_id);
779}
780
781/**
782 * sap_clear_channel_status() - clear chan info
783 * @p_mac: Pointer to Global MAC structure
784 *
785 * Return: none
786 */
Jeff Johnsonc59ef8b2018-12-02 12:01:21 -0800787static void sap_clear_channel_status(struct mac_context *p_mac)
gaoleze5108942017-03-31 16:56:42 +0800788{
789 csr_clear_channel_status(p_mac);
790}
791
792/**
793 * sap_weight_channel_noise_floor() - compute noise floor weight
794 * @sap_ctx: sap context
795 * @chn_stat: Pointer to chan status info
796 *
797 * Return: channel noise floor weight
798 */
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -0700799static uint32_t sap_weight_channel_noise_floor(struct sap_context *sap_ctx,
gaoleze5108942017-03-31 16:56:42 +0800800 struct lim_channel_status
801 *channel_stat)
802{
803 uint32_t noise_floor_weight;
804 uint8_t softap_nf_weight_cfg;
805 uint8_t softap_nf_weight_local;
806
807 softap_nf_weight_cfg =
808 ACS_WEIGHT_SOFTAP_NOISE_FLOOR_CFG
809 (sap_ctx->auto_channel_select_weight);
810
811 softap_nf_weight_local =
812 ACS_WEIGHT_CFG_TO_LOCAL(sap_ctx->auto_channel_select_weight,
813 softap_nf_weight_cfg);
814
Jeff Johnson4cfe6cc2019-03-18 13:40:27 -0700815 if (!channel_stat || channel_stat->channelfreq == 0) {
Srinivas Girigowda80213e52018-01-23 14:51:33 -0800816 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG,
gaoleze5108942017-03-31 16:56:42 +0800817 "In %s, sanity check failed return max weight",
818 __func__);
819 return softap_nf_weight_local;
820 }
821
822 noise_floor_weight = (channel_stat->noise_floor == 0) ? 0 :
823 (ACS_WEIGHT_COMPUTE(
824 sap_ctx->auto_channel_select_weight,
825 softap_nf_weight_cfg,
826 channel_stat->noise_floor -
827 SOFTAP_MIN_NF,
828 SOFTAP_MAX_NF - SOFTAP_MIN_NF));
829
830 if (noise_floor_weight > softap_nf_weight_local)
831 noise_floor_weight = softap_nf_weight_local;
gaoleze5108942017-03-31 16:56:42 +0800832
833 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
834 "In %s, nf=%d, nfwc=%d, nfwl=%d, nfw=%d",
835 __func__, channel_stat->noise_floor,
836 softap_nf_weight_cfg, softap_nf_weight_local,
837 noise_floor_weight);
838
839 return noise_floor_weight;
840}
841
842/**
843 * sap_weight_channel_free() - compute channel free weight
844 * @sap_ctx: sap context
845 * @chn_stat: Pointer to chan status info
846 *
847 * Return: channel free weight
848 */
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -0700849static uint32_t sap_weight_channel_free(struct sap_context *sap_ctx,
gaoleze5108942017-03-31 16:56:42 +0800850 struct lim_channel_status
851 *channel_stat)
852{
853 uint32_t channel_free_weight;
854 uint8_t softap_channel_free_weight_cfg;
855 uint8_t softap_channel_free_weight_local;
856 uint32_t rx_clear_count = 0;
857 uint32_t cycle_count = 0;
858
859 softap_channel_free_weight_cfg =
860 ACS_WEIGHT_SOFTAP_CHANNEL_FREE_CFG
861 (sap_ctx->auto_channel_select_weight);
862
863 softap_channel_free_weight_local =
864 ACS_WEIGHT_CFG_TO_LOCAL(sap_ctx->auto_channel_select_weight,
865 softap_channel_free_weight_cfg);
866
Jeff Johnson4cfe6cc2019-03-18 13:40:27 -0700867 if (!channel_stat || channel_stat->channelfreq == 0) {
Srinivas Girigowda80213e52018-01-23 14:51:33 -0800868 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG,
gaoleze5108942017-03-31 16:56:42 +0800869 "In %s, sanity check failed return max weight",
870 __func__);
871 return softap_channel_free_weight_local;
872 }
873
874 rx_clear_count = channel_stat->rx_clear_count -
875 channel_stat->tx_frame_count -
876 channel_stat->rx_frame_count;
877 cycle_count = channel_stat->cycle_count;
878
879 /* LSH 4, otherwise it is always 0. */
880 channel_free_weight = (cycle_count == 0) ? 0 :
881 (ACS_WEIGHT_COMPUTE(
882 sap_ctx->auto_channel_select_weight,
883 softap_channel_free_weight_cfg,
884 ((rx_clear_count << 8) +
885 (cycle_count >> 1))/cycle_count -
886 (SOFTAP_MIN_CHNFREE << 8),
887 (SOFTAP_MAX_CHNFREE -
888 SOFTAP_MIN_CHNFREE) << 8));
889
890 if (channel_free_weight > softap_channel_free_weight_local)
891 channel_free_weight = softap_channel_free_weight_local;
892
893 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
894 "In %s, rcc=%d, cc=%d, tc=%d, rc=%d, cfwc=%d, cfwl=%d, cfw=%d",
895 __func__, rx_clear_count, cycle_count,
896 channel_stat->tx_frame_count,
897 channel_stat->rx_frame_count,
898 softap_channel_free_weight_cfg,
899 softap_channel_free_weight_local,
900 channel_free_weight);
901
902 return channel_free_weight;
903}
904
905/**
906 * sap_weight_channel_txpwr_range() - compute channel tx power range weight
907 * @sap_ctx: sap context
908 * @chn_stat: Pointer to chan status info
909 *
910 * Return: tx power range weight
911 */
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -0700912static uint32_t sap_weight_channel_txpwr_range(struct sap_context *sap_ctx,
gaoleze5108942017-03-31 16:56:42 +0800913 struct lim_channel_status
914 *channel_stat)
915{
916 uint32_t txpwr_weight_low_speed;
917 uint8_t softap_txpwr_range_weight_cfg;
918 uint8_t softap_txpwr_range_weight_local;
919
920 softap_txpwr_range_weight_cfg =
921 ACS_WEIGHT_SOFTAP_TX_POWER_RANGE_CFG
922 (sap_ctx->auto_channel_select_weight);
923
924 softap_txpwr_range_weight_local =
925 ACS_WEIGHT_CFG_TO_LOCAL(sap_ctx->auto_channel_select_weight,
926 softap_txpwr_range_weight_cfg);
927
Jeff Johnson4cfe6cc2019-03-18 13:40:27 -0700928 if (!channel_stat || channel_stat->channelfreq == 0) {
Srinivas Girigowda80213e52018-01-23 14:51:33 -0800929 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG,
gaoleze5108942017-03-31 16:56:42 +0800930 "In %s, sanity check failed return max weight",
931 __func__);
932 return softap_txpwr_range_weight_local;
933 }
934
935 txpwr_weight_low_speed = (channel_stat->chan_tx_pwr_range == 0) ? 0 :
936 (ACS_WEIGHT_COMPUTE(
937 sap_ctx->auto_channel_select_weight,
938 softap_txpwr_range_weight_cfg,
939 SOFTAP_MAX_TXPWR -
940 channel_stat->chan_tx_pwr_range,
941 SOFTAP_MAX_TXPWR - SOFTAP_MIN_TXPWR));
942
943 if (txpwr_weight_low_speed > softap_txpwr_range_weight_local)
944 txpwr_weight_low_speed = softap_txpwr_range_weight_local;
945
946 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
947 "In %s, tpr=%d, tprwc=%d, tprwl=%d, tprw=%d",
948 __func__, channel_stat->chan_tx_pwr_range,
949 softap_txpwr_range_weight_cfg,
950 softap_txpwr_range_weight_local,
951 txpwr_weight_low_speed);
952
953 return txpwr_weight_low_speed;
954}
955
956/**
957 * sap_weight_channel_txpwr_tput() - compute channel tx power
958 * throughput weight
959 * @sap_ctx: sap context
960 * @chn_stat: Pointer to chan status info
961 *
962 * Return: tx power throughput weight
963 */
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -0700964static uint32_t sap_weight_channel_txpwr_tput(struct sap_context *sap_ctx,
gaoleze5108942017-03-31 16:56:42 +0800965 struct lim_channel_status
966 *channel_stat)
967{
968 uint32_t txpwr_weight_high_speed;
969 uint8_t softap_txpwr_tput_weight_cfg;
970 uint8_t softap_txpwr_tput_weight_local;
971
972 softap_txpwr_tput_weight_cfg =
973 ACS_WEIGHT_SOFTAP_TX_POWER_THROUGHPUT_CFG
974 (sap_ctx->auto_channel_select_weight);
975
976 softap_txpwr_tput_weight_local =
977 ACS_WEIGHT_CFG_TO_LOCAL(sap_ctx->auto_channel_select_weight,
978 softap_txpwr_tput_weight_cfg);
979
Jeff Johnson4cfe6cc2019-03-18 13:40:27 -0700980 if (!channel_stat || channel_stat->channelfreq == 0) {
Srinivas Girigowda80213e52018-01-23 14:51:33 -0800981 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG,
gaoleze5108942017-03-31 16:56:42 +0800982 "In %s, sanity check failed return max weight",
983 __func__);
984 return softap_txpwr_tput_weight_local;
985 }
986
987 txpwr_weight_high_speed = (channel_stat->chan_tx_pwr_throughput == 0)
988 ? 0 : (ACS_WEIGHT_COMPUTE(
989 sap_ctx->auto_channel_select_weight,
990 softap_txpwr_tput_weight_cfg,
991 SOFTAP_MAX_TXPWR -
992 channel_stat->chan_tx_pwr_throughput,
993 SOFTAP_MAX_TXPWR - SOFTAP_MIN_TXPWR));
994
995 if (txpwr_weight_high_speed > softap_txpwr_tput_weight_local)
996 txpwr_weight_high_speed = softap_txpwr_tput_weight_local;
997
998 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
999 "In %s, tpt=%d, tptwc=%d, tptwl=%d, tptw=%d",
1000 __func__, channel_stat->chan_tx_pwr_throughput,
1001 softap_txpwr_tput_weight_cfg,
1002 softap_txpwr_tput_weight_local,
1003 txpwr_weight_high_speed);
1004
1005 return txpwr_weight_high_speed;
1006}
1007
1008/**
1009 * sap_weight_channel_status() - compute chan status weight
1010 * @sap_ctx: sap context
1011 * @chn_stat: Pointer to chan status info
1012 *
1013 * Return: chan status weight
1014 */
1015static
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -07001016uint32_t sap_weight_channel_status(struct sap_context *sap_ctx,
gaoleze5108942017-03-31 16:56:42 +08001017 struct lim_channel_status *channel_stat)
1018{
1019 return sap_weight_channel_noise_floor(sap_ctx, channel_stat) +
1020 sap_weight_channel_free(sap_ctx, channel_stat) +
1021 sap_weight_channel_txpwr_range(sap_ctx, channel_stat) +
1022 sap_weight_channel_txpwr_tput(sap_ctx, channel_stat);
1023}
1024
1025/**
Yeshwanth Sriram Guntuka273889e2018-02-16 17:11:46 +05301026 * sap_check_channels_same_band() - Check if two channels belong to same band
1027 * @ch_num1: channel number
1028 * @ch_num2: channel number
1029 *
1030 * Return: true if both channels belong to same band else false
1031 */
1032static bool sap_check_channels_same_band(uint16_t ch_num1, uint16_t ch_num2)
1033{
1034 if ((ch_num1 <= SIR_11B_CHANNEL_END &&
1035 ch_num2 <= SIR_11B_CHANNEL_END) ||
1036 (ch_num1 >= SIR_11A_CHANNEL_BEGIN &&
1037 ch_num2 >= SIR_11A_CHANNEL_BEGIN))
Srinivas Girigowdaeff16d92018-09-12 14:56:29 -07001038 return true;
Yeshwanth Sriram Guntuka273889e2018-02-16 17:11:46 +05301039
1040 return false;
1041}
1042
1043/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001044 * sap_update_rssi_bsscount() - updates bss count and rssi effect.
1045 *
1046 * @pSpectCh: Channel Information
1047 * @offset: Channel Offset
1048 * @sap_24g: Channel is in 2.4G or 5G
Liangwei Dong71ed6502016-10-20 03:40:45 -04001049 * @spectch_start: the start of spect ch array
1050 * @spectch_end: the end of spect ch array
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001051 *
1052 * sap_update_rssi_bsscount updates bss count and rssi effect based
1053 * on the channel offset.
1054 *
1055 * Return: None.
1056 */
1057
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001058static void sap_update_rssi_bsscount(tSapSpectChInfo *pSpectCh, int32_t offset,
Liangwei Dong71ed6502016-10-20 03:40:45 -04001059 bool sap_24g, tSapSpectChInfo *spectch_start,
1060 tSapSpectChInfo *spectch_end)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001061{
1062 tSapSpectChInfo *pExtSpectCh = NULL;
1063 int32_t rssi, rsssi_effect;
1064
1065 pExtSpectCh = (pSpectCh + offset);
Jeff Johnson4cfe6cc2019-03-18 13:40:27 -07001066 if (pExtSpectCh &&
Liangwei Dong71ed6502016-10-20 03:40:45 -04001067 pExtSpectCh >= spectch_start &&
1068 pExtSpectCh < spectch_end) {
Yeshwanth Sriram Guntuka273889e2018-02-16 17:11:46 +05301069 if (!sap_check_channels_same_band(pSpectCh->chNum,
1070 pExtSpectCh->chNum))
1071 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001072 ++pExtSpectCh->bssCount;
1073 switch (offset) {
1074 case -1:
1075 case 1:
1076 rsssi_effect = sap_24g ?
1077 SAP_24GHZ_FIRST_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY :
1078 SAP_SUBBAND1_RSSI_EFFECT_PRIMARY;
1079 break;
1080 case -2:
1081 case 2:
1082 rsssi_effect = sap_24g ?
1083 SAP_24GHZ_SEC_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY :
1084 SAP_SUBBAND2_RSSI_EFFECT_PRIMARY;
1085 break;
1086 case -3:
1087 case 3:
1088 rsssi_effect = sap_24g ?
1089 SAP_24GHZ_THIRD_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY :
1090 SAP_SUBBAND3_RSSI_EFFECT_PRIMARY;
1091 break;
1092 case -4:
1093 case 4:
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001094 rsssi_effect = sap_24g ?
1095 SAP_24GHZ_FOURTH_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY :
1096 SAP_SUBBAND4_RSSI_EFFECT_PRIMARY;
1097 break;
1098 case -5:
1099 case 5:
1100 rsssi_effect = SAP_SUBBAND5_RSSI_EFFECT_PRIMARY;
1101 break;
1102 case -6:
1103 case 6:
1104 rsssi_effect = SAP_SUBBAND6_RSSI_EFFECT_PRIMARY;
1105 break;
1106 case -7:
1107 case 7:
1108 rsssi_effect = SAP_SUBBAND7_RSSI_EFFECT_PRIMARY;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001109 break;
1110 default:
1111 rsssi_effect = 0;
1112 break;
1113 }
1114
1115 rssi = pSpectCh->rssiAgr + rsssi_effect;
1116 if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi))
1117 pExtSpectCh->rssiAgr = rssi;
1118 if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI)
1119 pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI;
1120 }
1121}
1122
1123/**
1124 * sap_upd_chan_spec_params() - sap_upd_chan_spec_params
1125 * updates channel parameters obtained from Beacon
1126 * @pBeaconStruct Beacon strucutre populated by parse_beacon function
1127 * @channelWidth Channel width
1128 * @secondaryChannelOffset Secondary Channel Offset
1129 * @vhtSupport If channel supports VHT
1130 * @centerFreq Central frequency for the given channel.
1131 *
1132 * sap_upd_chan_spec_params updates the spectrum channels based on the
1133 * pBeaconStruct obtained from Beacon IE
1134 *
1135 * Return: NA.
1136 */
1137
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001138static void sap_upd_chan_spec_params(tSirProbeRespBeacon *pBeaconStruct,
1139 uint16_t *channelWidth,
1140 uint16_t *secondaryChannelOffset,
1141 uint16_t *vhtSupport,
1142 uint16_t *centerFreq,
1143 uint16_t *centerFreq_2)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001144{
Jeff Johnson4cfe6cc2019-03-18 13:40:27 -07001145 if (!pBeaconStruct) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301146 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001147 FL("pBeaconStruct is NULL"));
1148 return;
1149 }
1150
1151 if (pBeaconStruct->HTCaps.present && pBeaconStruct->HTInfo.present) {
1152 *channelWidth = pBeaconStruct->HTCaps.supportedChannelWidthSet;
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001153 *secondaryChannelOffset =
1154 pBeaconStruct->HTInfo.secondaryChannelOffset;
1155 if (!pBeaconStruct->VHTOperation.present)
1156 return;
1157 *vhtSupport = pBeaconStruct->VHTOperation.present;
1158 if (pBeaconStruct->VHTOperation.chanWidth) {
1159 *centerFreq =
1160 pBeaconStruct->VHTOperation.chanCenterFreqSeg1;
1161 *centerFreq_2 =
1162 pBeaconStruct->VHTOperation.chanCenterFreqSeg2;
1163 /*
1164 * LHS follows tSirMacHTChannelWidth, while RHS follows
1165 * WNI_CFG_VHT_CHANNEL_WIDTH_X format hence following
1166 * adjustment
1167 */
1168 *channelWidth =
1169 pBeaconStruct->VHTOperation.chanWidth + 1;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001170
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001171 }
1172 }
1173}
1174
1175/**
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001176 * sap_update_rssi_bsscount_vht_5G() - updates bss count and rssi effect.
1177 *
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001178 * @spect_ch: Channel Information
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001179 * @offset: Channel Offset
1180 * @num_ch: no.of channels
Liangwei Dong71ed6502016-10-20 03:40:45 -04001181 * @spectch_start: the start of spect ch array
1182 * @spectch_end: the end of spect ch array
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001183 *
1184 * sap_update_rssi_bsscount_vht_5G updates bss count and rssi effect based
1185 * on the channel offset.
1186 *
1187 * Return: None.
1188 */
1189
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001190static void sap_update_rssi_bsscount_vht_5G(tSapSpectChInfo *spect_ch,
1191 int32_t offset,
Liangwei Dong71ed6502016-10-20 03:40:45 -04001192 uint16_t num_ch,
1193 tSapSpectChInfo *spectch_start,
1194 tSapSpectChInfo *spectch_end)
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001195{
1196 int32_t ch_offset;
1197 uint16_t i, cnt;
1198
1199 if (!offset)
1200 return;
1201 if (offset > 0)
1202 cnt = num_ch;
1203 else
1204 cnt = num_ch + 1;
1205 for (i = 0; i < cnt; i++) {
1206 ch_offset = offset + i;
1207 if (ch_offset == 0)
1208 continue;
Liangwei Dong71ed6502016-10-20 03:40:45 -04001209 sap_update_rssi_bsscount(spect_ch, ch_offset, false,
1210 spectch_start, spectch_end);
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001211 }
1212}
1213/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001214 * sap_interference_rssi_count_5G() - sap_interference_rssi_count
1215 * considers the Adjacent channel rssi and
1216 * data count(here number of BSS observed)
1217 * @spect_ch: Channel Information
1218 * @chan_width: Channel width parsed from beacon IE
1219 * @sec_chan_offset: Secondary Channel Offset
1220 * @center_freq: Central frequency for the given channel.
1221 * @channel_id: channel_id
Liangwei Dong71ed6502016-10-20 03:40:45 -04001222 * @spectch_start: the start of spect ch array
1223 * @spectch_end: the end of spect ch array
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001224 *
1225 * sap_interference_rssi_count_5G considers the Adjacent channel rssi
1226 * and data count(here number of BSS observed)
1227 *
1228 * Return: NA.
1229 */
1230
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001231static void sap_interference_rssi_count_5G(tSapSpectChInfo *spect_ch,
1232 uint16_t chan_width,
1233 uint16_t sec_chan_offset,
1234 uint16_t center_freq,
1235 uint16_t center_freq_2,
Liangwei Dong71ed6502016-10-20 03:40:45 -04001236 uint8_t channel_id,
1237 tSapSpectChInfo *spectch_start,
1238 tSapSpectChInfo *spectch_end)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001239{
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001240 uint16_t num_ch;
1241 int32_t offset = 0;
Srinivas Girigowda4d65ebe2017-10-13 21:41:42 -07001242
Jeff Johnson4cfe6cc2019-03-18 13:40:27 -07001243 if (!spect_ch) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301244 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001245 FL("spect_ch is NULL"));
1246 return;
1247 }
1248
1249 /* Updating the received ChannelWidth */
1250 if (spect_ch->channelWidth != chan_width)
1251 spect_ch->channelWidth = chan_width;
1252 /* If received ChannelWidth is other than HT20,
1253 * we need to update the extension channel Params as well
1254 * chan_width == 0, HT20
1255 * chan_width == 1, HT40
1256 * chan_width == 2, VHT80
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001257 * chan_width == 3, VHT160
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001258 */
1259
1260 switch (spect_ch->channelWidth) {
1261 case eHT_CHANNEL_WIDTH_40MHZ: /* HT40 */
1262 switch (sec_chan_offset) {
1263 /* Above the Primary Channel */
1264 case PHY_DOUBLE_CHANNEL_LOW_PRIMARY:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001265 sap_update_rssi_bsscount(spect_ch, 1, false,
1266 spectch_start, spectch_end);
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001267 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001268
1269 /* Below the Primary channel */
1270 case PHY_DOUBLE_CHANNEL_HIGH_PRIMARY:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001271 sap_update_rssi_bsscount(spect_ch, -1, false,
1272 spectch_start, spectch_end);
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001273 return;
1274 }
1275 return;
1276 case eHT_CHANNEL_WIDTH_80MHZ: /* VHT80 */
1277 num_ch = 3;
1278 if ((center_freq - channel_id) == 6) {
1279 offset = 1;
1280 } else if ((center_freq - channel_id) == 2) {
1281 offset = -1;
1282 } else if ((center_freq - channel_id) == -2) {
1283 offset = -2;
1284 } else if ((center_freq - channel_id) == -6) {
1285 offset = -3;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001286 }
1287 break;
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001288 case eHT_CHANNEL_WIDTH_160MHZ: /* VHT160 */
1289 num_ch = 7;
1290 if ((center_freq - channel_id) == 14)
1291 offset = 1;
1292 else if ((center_freq - channel_id) == 10)
1293 offset = -1;
1294 else if ((center_freq - channel_id) == 6)
1295 offset = -2;
1296 else if ((center_freq - channel_id) == 2)
1297 offset = -3;
1298 else if ((center_freq - channel_id) == -2)
1299 offset = -4;
1300 else if ((center_freq - channel_id) == -6)
1301 offset = -5;
1302 else if ((center_freq - channel_id) == -10)
1303 offset = -6;
1304 else if ((center_freq - channel_id) == -14)
1305 offset = -7;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001306 break;
1307 default:
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001308 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001309 }
Liangwei Dong71ed6502016-10-20 03:40:45 -04001310 sap_update_rssi_bsscount_vht_5G(spect_ch, offset, num_ch,
1311 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001312}
1313
1314/**
1315 * sap_interference_rssi_count() - sap_interference_rssi_count
1316 * considers the Adjacent channel rssi
1317 * and data count(here number of BSS observed)
1318 * @spect_ch Channel Information
Liangwei Dong71ed6502016-10-20 03:40:45 -04001319 * @spectch_start: the start of spect ch array
1320 * @spectch_end: the end of spect ch array
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001321 *
1322 * sap_interference_rssi_count considers the Adjacent channel rssi
1323 * and data count(here number of BSS observed)
1324 *
1325 * Return: None.
1326 */
1327
Liangwei Dong71ed6502016-10-20 03:40:45 -04001328static void sap_interference_rssi_count(tSapSpectChInfo *spect_ch,
1329 tSapSpectChInfo *spectch_start,
1330 tSapSpectChInfo *spectch_end)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001331{
Jeff Johnson4cfe6cc2019-03-18 13:40:27 -07001332 if (!spect_ch) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301333 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001334 "%s: spect_ch is NULL", __func__);
1335 return;
1336 }
1337
1338 switch (spect_ch->chNum) {
1339 case CHANNEL_1:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001340 sap_update_rssi_bsscount(spect_ch, 1, true,
1341 spectch_start, spectch_end);
1342 sap_update_rssi_bsscount(spect_ch, 2, true,
1343 spectch_start, spectch_end);
1344 sap_update_rssi_bsscount(spect_ch, 3, true,
1345 spectch_start, spectch_end);
1346 sap_update_rssi_bsscount(spect_ch, 4, true,
1347 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001348 break;
1349
1350 case CHANNEL_2:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001351 sap_update_rssi_bsscount(spect_ch, -1, true,
1352 spectch_start, spectch_end);
1353 sap_update_rssi_bsscount(spect_ch, 1, true,
1354 spectch_start, spectch_end);
1355 sap_update_rssi_bsscount(spect_ch, 2, true,
1356 spectch_start, spectch_end);
1357 sap_update_rssi_bsscount(spect_ch, 3, true,
1358 spectch_start, spectch_end);
1359 sap_update_rssi_bsscount(spect_ch, 4, true,
1360 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001361 break;
1362 case CHANNEL_3:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001363 sap_update_rssi_bsscount(spect_ch, -2, true,
1364 spectch_start, spectch_end);
1365 sap_update_rssi_bsscount(spect_ch, -1, true,
1366 spectch_start, spectch_end);
1367 sap_update_rssi_bsscount(spect_ch, 1, true,
1368 spectch_start, spectch_end);
1369 sap_update_rssi_bsscount(spect_ch, 2, true,
1370 spectch_start, spectch_end);
1371 sap_update_rssi_bsscount(spect_ch, 3, true,
1372 spectch_start, spectch_end);
1373 sap_update_rssi_bsscount(spect_ch, 4, true,
1374 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001375 break;
1376 case CHANNEL_4:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001377 sap_update_rssi_bsscount(spect_ch, -3, true,
1378 spectch_start, spectch_end);
1379 sap_update_rssi_bsscount(spect_ch, -2, true,
1380 spectch_start, spectch_end);
1381 sap_update_rssi_bsscount(spect_ch, -1, true,
1382 spectch_start, spectch_end);
1383 sap_update_rssi_bsscount(spect_ch, 1, true,
1384 spectch_start, spectch_end);
1385 sap_update_rssi_bsscount(spect_ch, 2, true,
1386 spectch_start, spectch_end);
1387 sap_update_rssi_bsscount(spect_ch, 3, true,
1388 spectch_start, spectch_end);
1389 sap_update_rssi_bsscount(spect_ch, 4, true,
1390 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001391 break;
1392
1393 case CHANNEL_5:
1394 case CHANNEL_6:
1395 case CHANNEL_7:
1396 case CHANNEL_8:
1397 case CHANNEL_9:
1398 case CHANNEL_10:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001399 sap_update_rssi_bsscount(spect_ch, -4, true,
1400 spectch_start, spectch_end);
1401 sap_update_rssi_bsscount(spect_ch, -3, true,
1402 spectch_start, spectch_end);
1403 sap_update_rssi_bsscount(spect_ch, -2, true,
1404 spectch_start, spectch_end);
1405 sap_update_rssi_bsscount(spect_ch, -1, true,
1406 spectch_start, spectch_end);
1407 sap_update_rssi_bsscount(spect_ch, 1, true,
1408 spectch_start, spectch_end);
1409 sap_update_rssi_bsscount(spect_ch, 2, true,
1410 spectch_start, spectch_end);
1411 sap_update_rssi_bsscount(spect_ch, 3, true,
1412 spectch_start, spectch_end);
1413 sap_update_rssi_bsscount(spect_ch, 4, true,
1414 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001415 break;
1416
1417 case CHANNEL_11:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001418 sap_update_rssi_bsscount(spect_ch, -4, true,
1419 spectch_start, spectch_end);
1420 sap_update_rssi_bsscount(spect_ch, -3, true,
1421 spectch_start, spectch_end);
1422 sap_update_rssi_bsscount(spect_ch, -2, true,
1423 spectch_start, spectch_end);
1424 sap_update_rssi_bsscount(spect_ch, -1, true,
1425 spectch_start, spectch_end);
1426 sap_update_rssi_bsscount(spect_ch, 1, true,
1427 spectch_start, spectch_end);
1428 sap_update_rssi_bsscount(spect_ch, 2, true,
1429 spectch_start, spectch_end);
1430 sap_update_rssi_bsscount(spect_ch, 3, true,
1431 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001432 break;
1433
1434 case CHANNEL_12:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001435 sap_update_rssi_bsscount(spect_ch, -4, true,
1436 spectch_start, spectch_end);
1437 sap_update_rssi_bsscount(spect_ch, -3, true,
1438 spectch_start, spectch_end);
1439 sap_update_rssi_bsscount(spect_ch, -2, true,
1440 spectch_start, spectch_end);
1441 sap_update_rssi_bsscount(spect_ch, -1, true,
1442 spectch_start, spectch_end);
1443 sap_update_rssi_bsscount(spect_ch, 1, true,
1444 spectch_start, spectch_end);
1445 sap_update_rssi_bsscount(spect_ch, 2, true,
1446 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001447 break;
1448
1449 case CHANNEL_13:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001450 sap_update_rssi_bsscount(spect_ch, -4, true,
1451 spectch_start, spectch_end);
1452 sap_update_rssi_bsscount(spect_ch, -3, true,
1453 spectch_start, spectch_end);
1454 sap_update_rssi_bsscount(spect_ch, -2, true,
1455 spectch_start, spectch_end);
1456 sap_update_rssi_bsscount(spect_ch, -1, true,
1457 spectch_start, spectch_end);
1458 sap_update_rssi_bsscount(spect_ch, 1, true,
1459 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001460 break;
1461
1462 case CHANNEL_14:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001463 sap_update_rssi_bsscount(spect_ch, -4, true,
1464 spectch_start, spectch_end);
1465 sap_update_rssi_bsscount(spect_ch, -3, true,
1466 spectch_start, spectch_end);
1467 sap_update_rssi_bsscount(spect_ch, -2, true,
1468 spectch_start, spectch_end);
1469 sap_update_rssi_bsscount(spect_ch, -1, true,
1470 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001471 break;
1472
1473 default:
1474 break;
1475 }
1476}
1477
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001478/**
1479 * ch_in_pcl() - Is channel in the Preferred Channel List (PCL)
1480 * @sap_ctx: SAP context which contains the current PCL
1481 * @channel: Input channel number to be checked
1482 *
1483 * Check if a channel is in the preferred channel list
1484 *
1485 * Return:
1486 * true: channel is in PCL,
1487 * false: channel is not in PCL
1488 */
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -07001489static bool ch_in_pcl(struct sap_context *sap_ctx, uint8_t channel)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001490{
1491 uint32_t i;
1492
1493 for (i = 0; i < sap_ctx->acs_cfg->pcl_ch_count; i++) {
1494 if (channel == sap_ctx->acs_cfg->pcl_channels[i])
1495 return true;
1496 }
1497
1498 return false;
1499}
1500
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001501/**
1502 * sap_compute_spect_weight() - Compute spectrum weight
1503 * @pSpectInfoParams: Pointer to the tSpectInfoParams structure
Jeff Johnson7730fbb2018-11-08 13:48:27 -08001504 * @mac_handle: Opaque handle to the global MAC context
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001505 * @pResult: Pointer to tScanResultHandle
1506 * @sap_ctx: Context of the SAP
1507 *
1508 * Main function for computing the weight of each channel in the
1509 * spectrum based on the RSSI value of the BSSes on the channel
1510 * and number of BSS
1511 */
1512static void sap_compute_spect_weight(tSapChSelSpectInfo *pSpectInfoParams,
Jeff Johnson7730fbb2018-11-08 13:48:27 -08001513 mac_handle_t mac_handle,
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001514 tScanResultHandle pResult,
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -07001515 struct sap_context *sap_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001516{
1517 int8_t rssi = 0;
1518 uint8_t chn_num = 0;
1519 uint8_t channel_id = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001520 tCsrScanResultInfo *pScanResult;
1521 tSapSpectChInfo *pSpectCh = pSpectInfoParams->pSpectCh;
1522 uint32_t operatingBand;
1523 uint16_t channelWidth;
1524 uint16_t secondaryChannelOffset;
1525 uint16_t centerFreq;
gaurank kathpalia859c9362018-08-02 23:07:21 +05301526 uint8_t i;
1527 bool found;
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001528 uint16_t centerFreq_2 = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001529 uint16_t vhtSupport;
1530 uint32_t ieLen = 0;
1531 tSirProbeRespBeacon *pBeaconStruct;
Jeff Johnsonc59ef8b2018-12-02 12:01:21 -08001532 struct mac_context *mac = MAC_CONTEXT(mac_handle);
Liangwei Dong71ed6502016-10-20 03:40:45 -04001533 tSapSpectChInfo *spectch_start = pSpectInfoParams->pSpectCh;
1534 tSapSpectChInfo *spectch_end = pSpectInfoParams->pSpectCh +
1535 pSpectInfoParams->numSpectChans;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001536
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301537 pBeaconStruct = qdf_mem_malloc(sizeof(tSirProbeRespBeacon));
Arif Hussain256cc282018-10-03 14:10:44 -07001538 if (!pBeaconStruct)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001539 return;
Arif Hussain256cc282018-10-03 14:10:44 -07001540
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301541 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001542 "In %s, Computing spectral weight", __func__);
1543
1544 /**
1545 * Soft AP specific channel weight calculation using DFS formula
1546 */
1547 SET_ACS_BAND(operatingBand, sap_ctx);
1548
Jeff Johnson7730fbb2018-11-08 13:48:27 -08001549 pScanResult = sme_scan_result_get_first(mac_handle, pResult);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001550
1551 while (pScanResult) {
1552 pSpectCh = pSpectInfoParams->pSpectCh;
1553 /* Defining the default values, so that any value will hold the default values */
1554 channelWidth = eHT_CHANNEL_WIDTH_20MHZ;
1555 secondaryChannelOffset = PHY_SINGLE_CHANNEL_CENTERED;
1556 vhtSupport = 0;
1557 centerFreq = 0;
1558
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001559
Yingying Tang22facc12016-10-20 17:43:59 +08001560 ieLen = GET_IE_LEN_IN_BSS(
1561 pScanResult->BssDescriptor.length);
hangtian127c9532019-01-12 13:29:07 +08001562 qdf_mem_zero((uint8_t *) pBeaconStruct,
1563 sizeof(tSirProbeRespBeacon));
Yingying Tang22facc12016-10-20 17:43:59 +08001564
1565
1566 if ((sir_parse_beacon_ie
Jeff Johnsonb9794442018-11-22 14:21:08 -08001567 (mac, pBeaconStruct, (uint8_t *)
Yingying Tang22facc12016-10-20 17:43:59 +08001568 (pScanResult->BssDescriptor.ieFields),
Jeff Johnson83e30fa2018-06-07 23:01:11 -07001569 ieLen)) == QDF_STATUS_SUCCESS)
Yingying Tang22facc12016-10-20 17:43:59 +08001570 sap_upd_chan_spec_params(
1571 pBeaconStruct,
1572 &channelWidth,
1573 &secondaryChannelOffset,
1574 &vhtSupport, &centerFreq,
1575 &centerFreq_2);
1576
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001577 /* Processing for each tCsrScanResultInfo in the tCsrScanResult DLink list */
1578 for (chn_num = 0; chn_num < pSpectInfoParams->numSpectChans;
1579 chn_num++) {
1580
1581 /*
Himanshu Agarwalcf5b8932018-07-02 18:06:49 +05301582 * If the Beacon has channel ID, use it other wise we
1583 * will rely on the channelIdSelf
1584 */
1585 if (pScanResult->BssDescriptor.channelId == 0)
1586 channel_id =
1587 pScanResult->BssDescriptor.channelIdSelf;
1588 else
1589 channel_id =
1590 pScanResult->BssDescriptor.channelId;
1591
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001592 if (pSpectCh && (channel_id == pSpectCh->chNum)) {
1593 if (pSpectCh->rssiAgr <
1594 pScanResult->BssDescriptor.rssi)
1595 pSpectCh->rssiAgr =
1596 pScanResult->BssDescriptor.rssi;
1597
1598 ++pSpectCh->bssCount; /* Increment the count of BSS */
1599
1600 /*
1601 * Connsidering the Extension Channel
1602 * only in a channels
1603 */
1604 switch (operatingBand) {
1605 case eCSR_DOT11_MODE_11a:
1606 sap_interference_rssi_count_5G(
1607 pSpectCh, channelWidth,
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001608 secondaryChannelOffset,
1609 centerFreq,
1610 centerFreq_2,
Liangwei Dong71ed6502016-10-20 03:40:45 -04001611 channel_id,
1612 spectch_start,
1613 spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001614 break;
1615
1616 case eCSR_DOT11_MODE_11g:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001617 sap_interference_rssi_count(pSpectCh,
1618 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001619 break;
1620
1621 case eCSR_DOT11_MODE_abg:
Himanshu Agarwal4f503b82018-03-19 12:10:45 +05301622 if (pSpectCh->chNum >=
1623 SIR_11A_CHANNEL_BEGIN)
1624 sap_interference_rssi_count_5G(
1625 pSpectCh, channelWidth,
1626 secondaryChannelOffset,
1627 centerFreq,
1628 centerFreq_2,
1629 channel_id,
1630 spectch_start,
1631 spectch_end);
1632 else
1633 sap_interference_rssi_count(
1634 pSpectCh,
1635 spectch_start,
1636 spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001637 break;
1638 }
1639
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301640 QDF_TRACE(QDF_MODULE_ID_SAP,
1641 QDF_TRACE_LEVEL_INFO_HIGH,
Jeff Johnsona7c0ddb2017-09-18 08:14:12 -07001642 "In %s, bssdes.ch_self=%d, bssdes.ch_ID=%d, bssdes.rssi=%d, SpectCh.bssCount=%d, pScanResult=%pK, ChannelWidth %d, secondaryChanOffset %d, center frequency %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001643 __func__,
1644 pScanResult->BssDescriptor.
1645 channelIdSelf,
1646 pScanResult->BssDescriptor.channelId,
1647 pScanResult->BssDescriptor.rssi,
1648 pSpectCh->bssCount, pScanResult,
1649 pSpectCh->channelWidth,
1650 secondaryChannelOffset, centerFreq);
1651 pSpectCh++;
1652 break;
1653 } else {
1654 pSpectCh++;
1655 }
1656 }
1657
Jeff Johnson7730fbb2018-11-08 13:48:27 -08001658 pScanResult = sme_scan_result_get_next(mac_handle, pResult);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001659 }
1660
1661 /* Calculate the weights for all channels in the spectrum pSpectCh */
1662 pSpectCh = pSpectInfoParams->pSpectCh;
1663
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301664 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001665 "In %s, Spectrum Channels Weight", __func__);
1666
1667 for (chn_num = 0; chn_num < (pSpectInfoParams->numSpectChans);
1668 chn_num++) {
1669
1670 /*
1671 rssi : Maximum received signal strength among all BSS on that channel
1672 bssCount : Number of BSS on that channel
1673 */
1674
1675 rssi = (int8_t) pSpectCh->rssiAgr;
Himanshu Agarwal3697f942018-06-13 14:04:26 +05301676 if (ch_in_pcl(sap_ctx, pSpectCh->chNum))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001677 rssi -= PCL_RSSI_DISCOUNT;
1678
Himanshu Agarwal3697f942018-06-13 14:04:26 +05301679 if (rssi < SOFTAP_MIN_RSSI)
1680 rssi = SOFTAP_MIN_RSSI;
1681
hqub6441f22018-08-09 16:15:31 +08001682 if (pSpectCh->weight == SAP_ACS_WEIGHT_MAX) {
1683 pSpectCh->weight_copy = pSpectCh->weight;
Himanshu Agarwalfee2e362018-01-18 20:26:35 +05301684 goto debug_info;
hqub6441f22018-08-09 16:15:31 +08001685 }
Himanshu Agarwalfee2e362018-01-18 20:26:35 +05301686
gaurank kathpalia859c9362018-08-02 23:07:21 +05301687 /* There may be channels in scanlist, which were not sent to
1688 * FW for scanning as part of ACS scan list, but they do have an
1689 * effect on the neighbouring channels, so they help to find a
1690 * suitable channel, but there weight should be max as they were
1691 * and not meant to be included in the ACS scan results.
1692 * So just assign RSSI as -100, bsscount as 0, and weight as max
1693 * to them, so that they always stay low in sorting of best
1694 * channles which were included in ACS scan list
1695 */
1696 found = false;
1697 for (i = 0; i < sap_ctx->num_of_channel; i++) {
1698 if (pSpectCh->chNum == sap_ctx->channelList[i]) {
1699 /* Scan channel was included in ACS scan list */
1700 found = true;
1701 break;
1702 }
1703 }
1704
1705 if (found)
1706 pSpectCh->weight =
1707 SAPDFS_NORMALISE_1000 *
1708 (sapweight_rssi_count(sap_ctx, rssi,
1709 pSpectCh->bssCount) + sap_weight_channel_status(
Jeff Johnsonb9794442018-11-22 14:21:08 -08001710 sap_ctx, sap_get_channel_status(mac,
gaoleze5108942017-03-31 16:56:42 +08001711 pSpectCh->chNum)));
gaurank kathpalia859c9362018-08-02 23:07:21 +05301712 else {
1713 pSpectCh->weight = SAP_ACS_WEIGHT_MAX;
1714 pSpectCh->rssiAgr = SOFTAP_MIN_RSSI;
1715 rssi = SOFTAP_MIN_RSSI;
1716 pSpectCh->bssCount = SOFTAP_MIN_COUNT;
1717 }
1718
gaoleze5108942017-03-31 16:56:42 +08001719 if (pSpectCh->weight > SAP_ACS_WEIGHT_MAX)
1720 pSpectCh->weight = SAP_ACS_WEIGHT_MAX;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001721 pSpectCh->weight_copy = pSpectCh->weight;
1722
Himanshu Agarwalfee2e362018-01-18 20:26:35 +05301723debug_info:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001724 /* ------ Debug Info ------ */
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301725 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Himanshu Agarwal3697f942018-06-13 14:04:26 +05301726 "In %s, Chan=%d Weight= %d rssiAgr=%d rssi_pcl_discount: %d bssCount=%d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001727 __func__, pSpectCh->chNum, pSpectCh->weight,
Himanshu Agarwal3697f942018-06-13 14:04:26 +05301728 pSpectCh->rssiAgr, rssi, pSpectCh->bssCount);
wadesongcb0ded22018-02-02 17:57:20 +08001729 host_log_acs_chan_spect_weight(pSpectCh->chNum,
1730 (uint16_t)pSpectCh->weight,
1731 pSpectCh->rssiAgr,
1732 pSpectCh->bssCount);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001733 /* ------ Debug Info ------ */
1734 pSpectCh++;
1735 }
Jeff Johnsonb9794442018-11-22 14:21:08 -08001736 sap_clear_channel_status(mac);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301737 qdf_mem_free(pBeaconStruct);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001738}
1739
1740/*==========================================================================
1741 FUNCTION sap_chan_sel_exit
1742
1743 DESCRIPTION
1744 Exit function for free out the allocated memory, to be called
1745 at the end of the dfsSelectChannel function
1746
1747 DEPENDENCIES
1748 NA.
1749
1750 PARAMETERS
1751
1752 IN
1753 pSpectInfoParams : Pointer to the tSapChSelSpectInfo structure
1754
1755 RETURN VALUE
1756 void : NULL
1757
1758 SIDE EFFECTS
1759 ============================================================================*/
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001760static void sap_chan_sel_exit(tSapChSelSpectInfo *pSpectInfoParams)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001761{
1762 /* Free all the allocated memory */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301763 qdf_mem_free(pSpectInfoParams->pSpectCh);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001764}
1765
1766/*==========================================================================
1767 FUNCTION sap_sort_chl_weight
1768
1769 DESCRIPTION
Jeff Johnsonc7e4d162018-05-12 16:20:34 -07001770 Function to sort the channels with the least weight first for 20MHz channels
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001771
1772 DEPENDENCIES
1773 NA.
1774
1775 PARAMETERS
1776
1777 IN
1778 pSpectInfoParams : Pointer to the tSapChSelSpectInfo structure
1779
1780 RETURN VALUE
1781 void : NULL
1782
1783 SIDE EFFECTS
1784 ============================================================================*/
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001785static void sap_sort_chl_weight(tSapChSelSpectInfo *pSpectInfoParams)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001786{
1787 tSapSpectChInfo temp;
1788
1789 tSapSpectChInfo *pSpectCh = NULL;
1790 uint32_t i = 0, j = 0, minWeightIndex = 0;
1791
1792 pSpectCh = pSpectInfoParams->pSpectCh;
1793 for (i = 0; i < pSpectInfoParams->numSpectChans; i++) {
1794 minWeightIndex = i;
1795 for (j = i + 1; j < pSpectInfoParams->numSpectChans; j++) {
1796 if (pSpectCh[j].weight <
1797 pSpectCh[minWeightIndex].weight) {
1798 minWeightIndex = j;
Yeshwanth Sriram Guntuka273889e2018-02-16 17:11:46 +05301799 } else if (pSpectCh[j].weight ==
1800 pSpectCh[minWeightIndex].weight) {
1801 if (pSpectCh[j].bssCount <
1802 pSpectCh[minWeightIndex].bssCount)
1803 minWeightIndex = j;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001804 }
1805 }
1806 if (minWeightIndex != i) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301807 qdf_mem_copy(&temp, &pSpectCh[minWeightIndex],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001808 sizeof(*pSpectCh));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301809 qdf_mem_copy(&pSpectCh[minWeightIndex], &pSpectCh[i],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001810 sizeof(*pSpectCh));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301811 qdf_mem_copy(&pSpectCh[i], &temp, sizeof(*pSpectCh));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001812 }
1813 }
1814}
1815
1816/**
Jeff Johnsonc7e4d162018-05-12 16:20:34 -07001817 * set_ht80_chl_bit() - to set available channel to ht80 channel bitmap
bingse2782382017-03-23 10:34:52 +08001818 * @channel_bitmap: Pointer to the chan_bonding_bitmap structure
1819 * @spect_info_params: Pointer to the tSapChSelSpectInfo structure
1820 *
1821 * Return: none
1822 */
1823static void set_ht80_chl_bit(chan_bonding_bitmap *channel_bitmap,
1824 tSapChSelSpectInfo *spec_info_params)
1825{
1826 uint8_t i, j;
1827 tSapSpectChInfo *spec_info;
1828 int start_channel = 0;
1829
1830 channel_bitmap->chanBondingSet[0].startChannel =
1831 acs_ht80_channels[0].chStartNum;
1832 channel_bitmap->chanBondingSet[1].startChannel =
1833 acs_ht80_channels[1].chStartNum;
1834 channel_bitmap->chanBondingSet[2].startChannel =
1835 acs_ht80_channels[2].chStartNum;
1836 channel_bitmap->chanBondingSet[3].startChannel =
1837 acs_ht80_channels[3].chStartNum;
1838 channel_bitmap->chanBondingSet[4].startChannel =
1839 acs_ht80_channels[4].chStartNum;
1840 channel_bitmap->chanBondingSet[5].startChannel =
1841 acs_ht80_channels[5].chStartNum;
1842
1843 spec_info = spec_info_params->pSpectCh;
1844 for (j = 0; j < spec_info_params->numSpectChans; j++) {
1845 for (i = 0; i < MAX_80MHZ_BANDS; i++) {
1846 start_channel =
1847 channel_bitmap->chanBondingSet[i].startChannel;
1848 if (spec_info[j].chNum >= start_channel &&
1849 (spec_info[j].chNum <= start_channel + 12)) {
1850 channel_bitmap->chanBondingSet[i].channelMap |=
1851 1 << ((spec_info[j].chNum -
1852 start_channel)/4);
1853 break;
1854 }
1855 }
1856 }
1857}
1858
1859/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001860 * sap_sort_chl_weight_ht80() - to sort the channels with the least weight
1861 * @pSpectInfoParams: Pointer to the tSapChSelSpectInfo structure
1862 *
Jeff Johnsonc7e4d162018-05-12 16:20:34 -07001863 * Function to sort the channels with the least weight first for HT80 channels
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001864 *
1865 * Return: none
1866 */
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001867static void sap_sort_chl_weight_ht80(tSapChSelSpectInfo *pSpectInfoParams)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001868{
1869 uint8_t i, j, n;
1870 tSapSpectChInfo *pSpectInfo;
1871 uint8_t minIdx;
bingse2782382017-03-23 10:34:52 +08001872 int start_channel = 0;
1873 chan_bonding_bitmap *channel_bitmap;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001874
bingse2782382017-03-23 10:34:52 +08001875 channel_bitmap = qdf_mem_malloc(sizeof(chan_bonding_bitmap));
Arif Hussain256cc282018-10-03 14:10:44 -07001876 if (!channel_bitmap)
bingse2782382017-03-23 10:34:52 +08001877 return;
Arif Hussain256cc282018-10-03 14:10:44 -07001878
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001879 pSpectInfo = pSpectInfoParams->pSpectCh;
1880 /* for each HT80 channel, calculate the combined weight of the
1881 four 20MHz weight */
1882 for (i = 0; i < ARRAY_SIZE(acs_ht80_channels); i++) {
1883 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
1884 if (pSpectInfo[j].chNum ==
1885 acs_ht80_channels[i].chStartNum)
1886 break;
1887 }
1888 if (j == pSpectInfoParams->numSpectChans)
1889 continue;
1890
1891 if (!(((pSpectInfo[j].chNum + 4) == pSpectInfo[j + 1].chNum) &&
1892 ((pSpectInfo[j].chNum + 8) ==
1893 pSpectInfo[j + 2].chNum) &&
1894 ((pSpectInfo[j].chNum + 12) ==
1895 pSpectInfo[j + 3].chNum))) {
1896 /*
1897 * some channels does not exist in pSectInfo array,
1898 * skip this channel and those in the same HT80 width
1899 */
1900 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 4;
1901 if ((pSpectInfo[j].chNum + 4) ==
1902 pSpectInfo[j + 1].chNum)
1903 pSpectInfo[j + 1].weight =
1904 SAP_ACS_WEIGHT_MAX * 4;
1905 if ((pSpectInfo[j].chNum + 8) ==
1906 pSpectInfo[j + 2].chNum)
1907 pSpectInfo[j + 2].weight =
1908 SAP_ACS_WEIGHT_MAX * 4;
1909 if ((pSpectInfo[j].chNum + 12) ==
1910 pSpectInfo[j + 3].chNum)
1911 pSpectInfo[j + 3].weight =
1912 SAP_ACS_WEIGHT_MAX * 4;
1913 continue;
1914 }
1915 /*found the channel, add the 4 adjacent channels' weight */
1916 acs_ht80_channels[i].weight = pSpectInfo[j].weight +
1917 pSpectInfo[j + 1].weight + pSpectInfo[j + 2].weight +
1918 pSpectInfo[j + 3].weight;
1919 /* find best channel among 4 channels as the primary channel */
1920 if ((pSpectInfo[j].weight + pSpectInfo[j + 1].weight) <
1921 (pSpectInfo[j + 2].weight + pSpectInfo[j + 3].weight)) {
1922 /* lower 2 channels are better choice */
1923 if (pSpectInfo[j].weight < pSpectInfo[j + 1].weight)
1924 minIdx = 0;
1925 else
1926 minIdx = 1;
1927 } else if (pSpectInfo[j + 2].weight <=
1928 pSpectInfo[j + 3].weight) {
1929 /* upper 2 channels are better choice */
1930 minIdx = 2;
1931 } else {
1932 minIdx = 3;
1933 }
1934
1935 /*
1936 * set all 4 channels to max value first, then reset the
1937 * best channel as the selected primary channel, update its
1938 * weightage with the combined weight value
1939 */
1940 for (n = 0; n < 4; n++)
1941 pSpectInfo[j + n].weight = SAP_ACS_WEIGHT_MAX * 4;
1942
1943 pSpectInfo[j + minIdx].weight = acs_ht80_channels[i].weight;
1944 }
1945
bingse2782382017-03-23 10:34:52 +08001946 /*
1947 * mark the weight of the channel that can't satisfy 80MHZ
1948 * as max value, so that it will be sorted to the bottom
1949 */
1950 set_ht80_chl_bit(channel_bitmap, pSpectInfoParams);
1951 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
1952 for (i = 0; i < MAX_80MHZ_BANDS; i++) {
1953 start_channel =
1954 channel_bitmap->chanBondingSet[i].startChannel;
1955 if (pSpectInfo[j].chNum >= start_channel &&
1956 (pSpectInfo[j].chNum <=
1957 start_channel + 12) &&
1958 channel_bitmap->chanBondingSet[i].channelMap !=
1959 SAP_80MHZ_MASK)
1960 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 4;
1961 }
1962 }
1963
Himanshu Agarwal75e74412018-02-01 20:51:47 +05301964 /*
1965 * Assign max weight(SAP_ACS_WEIGHT_MAX * 4) to 2.4 Ghz channels
1966 * and channel 165 as they cannot be part of a 80Mhz channel bonding.
1967 */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001968 pSpectInfo = pSpectInfoParams->pSpectCh;
1969 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
Himanshu Agarwal75e74412018-02-01 20:51:47 +05301970 if ((pSpectInfo[j].chNum >= WLAN_REG_CH_NUM(CHAN_ENUM_1) &&
1971 pSpectInfo[j].chNum <= WLAN_REG_CH_NUM(CHAN_ENUM_14)) ||
gaurank kathpalia1dea75b2019-01-10 13:53:43 +05301972 (pSpectInfo[j].chNum >= CHANNEL_165))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001973 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 4;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001974 }
1975
Manishekar Chandrasekaran44e334f2016-05-30 16:42:50 +05301976 sap_sort_chl_weight(pSpectInfoParams);
1977
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001978 pSpectInfo = pSpectInfoParams->pSpectCh;
1979 for (j = 0; j < (pSpectInfoParams->numSpectChans); j++) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301980 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001981 FL("Channel=%d Weight= %d rssi=%d bssCount=%d"),
1982 pSpectInfo->chNum, pSpectInfo->weight,
1983 pSpectInfo->rssiAgr, pSpectInfo->bssCount);
1984 pSpectInfo++;
1985 }
bingse2782382017-03-23 10:34:52 +08001986 qdf_mem_free(channel_bitmap);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001987}
1988
1989/**
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001990 * sap_sort_chl_weight_vht160() - to sort the channels with the least weight
1991 * @pSpectInfoParams: Pointer to the tSapChSelSpectInfo structure
1992 *
Jeff Johnsonc7e4d162018-05-12 16:20:34 -07001993 * Function to sort the channels with the least weight first for VHT160 channels
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001994 *
1995 * Return: none
1996 */
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001997static void sap_sort_chl_weight_vht160(tSapChSelSpectInfo *pSpectInfoParams)
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001998{
1999 uint8_t i, j, n, idx;
2000 tSapSpectChInfo *pSpectInfo;
2001 uint8_t minIdx;
2002
2003 pSpectInfo = pSpectInfoParams->pSpectCh;
2004 /* for each VHT160 channel, calculate the combined weight of the
2005 8 20MHz weight */
2006 for (i = 0; i < ARRAY_SIZE(acs_vht160_channels); i++) {
2007 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
2008 if (pSpectInfo[j].chNum ==
2009 acs_vht160_channels[i].chStartNum)
2010 break;
2011 }
2012 if (j == pSpectInfoParams->numSpectChans)
2013 continue;
2014
2015 if (!(((pSpectInfo[j].chNum + 4) == pSpectInfo[j + 1].chNum) &&
2016 ((pSpectInfo[j].chNum + 8) ==
2017 pSpectInfo[j + 2].chNum) &&
2018 ((pSpectInfo[j].chNum + 12) ==
2019 pSpectInfo[j + 3].chNum) &&
2020 ((pSpectInfo[j].chNum + 16) ==
2021 pSpectInfo[j + 4].chNum) &&
2022 ((pSpectInfo[j].chNum + 20) ==
2023 pSpectInfo[j + 5].chNum) &&
2024 ((pSpectInfo[j].chNum + 24) ==
2025 pSpectInfo[j + 6].chNum) &&
2026 ((pSpectInfo[j].chNum + 28) ==
2027 pSpectInfo[j + 7].chNum))) {
2028 /*
2029 * some channels does not exist in pSectInfo array,
2030 * skip this channel and those in the same VHT160 width
2031 */
2032 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 8;
2033 if ((pSpectInfo[j].chNum + 4) ==
2034 pSpectInfo[j + 1].chNum)
2035 pSpectInfo[j + 1].weight =
2036 SAP_ACS_WEIGHT_MAX * 8;
2037 if ((pSpectInfo[j].chNum + 8) ==
2038 pSpectInfo[j + 2].chNum)
2039 pSpectInfo[j + 2].weight =
2040 SAP_ACS_WEIGHT_MAX * 8;
2041 if ((pSpectInfo[j].chNum + 12) ==
2042 pSpectInfo[j + 3].chNum)
2043 pSpectInfo[j + 3].weight =
2044 SAP_ACS_WEIGHT_MAX * 8;
2045 if ((pSpectInfo[j].chNum + 16) ==
2046 pSpectInfo[j + 4].chNum)
2047 pSpectInfo[j + 4].weight =
2048 SAP_ACS_WEIGHT_MAX * 8;
2049 if ((pSpectInfo[j].chNum + 20) ==
2050 pSpectInfo[j + 5].chNum)
2051 pSpectInfo[j + 5].weight =
2052 SAP_ACS_WEIGHT_MAX * 8;
2053 if ((pSpectInfo[j].chNum + 24) ==
2054 pSpectInfo[j + 6].chNum)
2055 pSpectInfo[j + 6].weight =
2056 SAP_ACS_WEIGHT_MAX * 8;
2057 if ((pSpectInfo[j].chNum + 28) ==
2058 pSpectInfo[j + 7].chNum)
2059 pSpectInfo[j + 7].weight =
2060 SAP_ACS_WEIGHT_MAX * 8;
2061 continue;
2062 }
2063 /*found the channel, add the 7 adjacent channels' weight */
2064 acs_vht160_channels[i].weight = pSpectInfo[j].weight +
2065 pSpectInfo[j + 1].weight + pSpectInfo[j + 2].weight +
2066 pSpectInfo[j + 3].weight + pSpectInfo[j + 4].weight +
2067 pSpectInfo[j + 5].weight + pSpectInfo[j + 6].weight +
2068 pSpectInfo[j + 7].weight;
2069
2070 /* find best channel among 8 channels as the primary channel */
2071 if ((pSpectInfo[j].weight + pSpectInfo[j + 1].weight +
2072 pSpectInfo[j + 2].weight + pSpectInfo[j + 3].weight) >
2073 (pSpectInfo[j + 4].weight + pSpectInfo[j + 5].weight +
2074 pSpectInfo[j + 6].weight + pSpectInfo[j + 7].weight))
2075 idx = 4;
2076 else
2077 idx = 0;
2078 /* find best channel among 4 channels as the primary channel */
2079 if ((pSpectInfo[j + idx].weight +
2080 pSpectInfo[j + idx + 1].weight) <
2081 (pSpectInfo[j + idx + 2].weight +
2082 pSpectInfo[j + idx + 3].weight)) {
2083 /* lower 2 channels are better choice */
2084 if (pSpectInfo[j + idx].weight <
2085 pSpectInfo[j + idx + 1].weight)
2086 minIdx = 0 + idx;
2087 else
2088 minIdx = 1 + idx;
2089 } else if (pSpectInfo[j + idx + 2].weight <=
2090 pSpectInfo[j + idx + 3].weight) {
2091 /* upper 2 channels are better choice */
2092 minIdx = 2 + idx;
2093 } else {
2094 minIdx = 3 + idx;
2095 }
2096
2097 /*
2098 * set all 8 channels to max value first, then reset the
2099 * best channel as the selected primary channel, update its
2100 * weightage with the combined weight value
2101 */
2102 for (n = 0; n < 8; n++)
2103 pSpectInfo[j + n].weight = SAP_ACS_WEIGHT_MAX * 8;
2104
2105 pSpectInfo[j + minIdx].weight = acs_vht160_channels[i].weight;
2106 }
2107
Himanshu Agarwal75e74412018-02-01 20:51:47 +05302108 /*
2109 * Assign max weight(SAP_ACS_WEIGHT_MAX * 8) to 2.4 Ghz channels
Kiran Kumar Lokere1a43bcf2018-05-15 15:51:58 -07002110 * and channel 132-173 as they cannot be part of a 160Mhz channel
Himanshu Agarwal75e74412018-02-01 20:51:47 +05302111 * bonding.
2112 */
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07002113 pSpectInfo = pSpectInfoParams->pSpectCh;
2114 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
Himanshu Agarwal75e74412018-02-01 20:51:47 +05302115 if ((pSpectInfo[j].chNum >= WLAN_REG_CH_NUM(CHAN_ENUM_1) &&
2116 pSpectInfo[j].chNum <= WLAN_REG_CH_NUM(CHAN_ENUM_14)) ||
2117 (pSpectInfo[j].chNum >= WLAN_REG_CH_NUM(CHAN_ENUM_132) &&
Kiran Kumar Lokere1a43bcf2018-05-15 15:51:58 -07002118 pSpectInfo[j].chNum <= WLAN_REG_CH_NUM(CHAN_ENUM_173)))
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07002119 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 8;
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07002120 }
2121
Manishekar Chandrasekaran44e334f2016-05-30 16:42:50 +05302122 sap_sort_chl_weight(pSpectInfoParams);
2123
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07002124 pSpectInfo = pSpectInfoParams->pSpectCh;
2125 for (j = 0; j < (pSpectInfoParams->numSpectChans); j++) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302126 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07002127 FL("Channel=%d Weight= %d rssi=%d bssCount=%d"),
2128 pSpectInfo->chNum, pSpectInfo->weight,
2129 pSpectInfo->rssiAgr, pSpectInfo->bssCount);
2130 pSpectInfo++;
2131 }
2132}
2133
2134/**
Himanshu Agarwal91c5c0f2018-02-13 14:40:56 +05302135 * sap_allocate_max_weight_ht40_24_g() - allocate max weight for 40Mhz
2136 * to all 2.4Ghz channels
2137 * @spect_info_params: Pointer to the tSapChSelSpectInfo structure
2138 *
2139 * Return: none
2140 */
2141static void sap_allocate_max_weight_ht40_24_g(
2142 tSapChSelSpectInfo *spect_info_params)
2143{
2144 tSapSpectChInfo *spect_info;
2145 uint8_t j;
2146
2147 /*
2148 * Assign max weight for 40Mhz (SAP_ACS_WEIGHT_MAX * 2) to all
2149 * 2.4 Ghz channels
2150 */
2151 spect_info = spect_info_params->pSpectCh;
2152 for (j = 0; j < spect_info_params->numSpectChans; j++) {
2153 if ((spect_info[j].chNum >= WLAN_REG_CH_NUM(CHAN_ENUM_1) &&
2154 spect_info[j].chNum <= WLAN_REG_CH_NUM(CHAN_ENUM_14)))
2155 spect_info[j].weight = SAP_ACS_WEIGHT_MAX * 2;
2156 }
2157}
2158
2159/**
2160 * sap_allocate_max_weight_ht40_5_g() - allocate max weight for 40Mhz
2161 * to all 5Ghz channels
2162 * @spect_info_params: Pointer to the tSapChSelSpectInfo structure
2163 *
2164 * Return: none
2165 */
2166static void sap_allocate_max_weight_ht40_5_g(
2167 tSapChSelSpectInfo *spect_info_params)
2168{
2169 tSapSpectChInfo *spect_info;
2170 uint8_t j;
2171
2172 /*
2173 * Assign max weight for 40Mhz (SAP_ACS_WEIGHT_MAX * 2) to all
2174 * 5 Ghz channels
2175 */
2176 spect_info = spect_info_params->pSpectCh;
2177 for (j = 0; j < spect_info_params->numSpectChans; j++) {
2178 if ((spect_info[j].chNum >= WLAN_REG_CH_NUM(CHAN_ENUM_36) &&
Kiran Kumar Lokere1a43bcf2018-05-15 15:51:58 -07002179 spect_info[j].chNum <= WLAN_REG_CH_NUM(CHAN_ENUM_173)))
Himanshu Agarwal91c5c0f2018-02-13 14:40:56 +05302180 spect_info[j].weight = SAP_ACS_WEIGHT_MAX * 2;
2181 }
2182}
2183
2184/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002185 * sap_sort_chl_weight_ht40_24_g() - to sort channel with the least weight
2186 * @pSpectInfoParams: Pointer to the tSapChSelSpectInfo structure
2187 *
Jeff Johnsonc7e4d162018-05-12 16:20:34 -07002188 * Function to sort the channels with the least weight first for HT40 channels
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002189 *
2190 * Return: none
2191 */
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002192static void sap_sort_chl_weight_ht40_24_g(tSapChSelSpectInfo *pSpectInfoParams,
2193 v_REGDOMAIN_t domain)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002194{
2195 uint8_t i, j;
2196 tSapSpectChInfo *pSpectInfo;
2197 uint32_t tmpWeight1, tmpWeight2;
bingse2782382017-03-23 10:34:52 +08002198 uint32_t ht40plus2gendch = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002199
2200 pSpectInfo = pSpectInfoParams->pSpectCh;
2201 /*
2202 * for each HT40 channel, calculate the combined weight of the
2203 * two 20MHz weight
2204 */
2205 for (i = 0; i < ARRAY_SIZE(acs_ht40_channels24_g); i++) {
2206 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
2207 if (pSpectInfo[j].chNum ==
2208 acs_ht40_channels24_g[i].chStartNum)
2209 break;
2210 }
2211 if (j == pSpectInfoParams->numSpectChans)
2212 continue;
2213
2214 if (!((pSpectInfo[j].chNum + 4) == pSpectInfo[j + 4].chNum)) {
2215 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2;
2216 continue;
2217 }
2218 /*
2219 * check if there is another channel combination possiblity
2220 * e.g., {1, 5} & {5, 9}
2221 */
2222 if ((pSpectInfo[j + 4].chNum + 4) == pSpectInfo[j + 8].chNum) {
2223 /* need to compare two channel pairs */
2224 tmpWeight1 = pSpectInfo[j].weight +
2225 pSpectInfo[j + 4].weight;
2226 tmpWeight2 = pSpectInfo[j + 4].weight +
2227 pSpectInfo[j + 8].weight;
2228 if (tmpWeight1 <= tmpWeight2) {
2229 if (pSpectInfo[j].weight <=
2230 pSpectInfo[j + 4].weight) {
2231 pSpectInfo[j].weight =
2232 tmpWeight1;
2233 pSpectInfo[j + 4].weight =
2234 SAP_ACS_WEIGHT_MAX * 2;
2235 pSpectInfo[j + 8].weight =
2236 SAP_ACS_WEIGHT_MAX * 2;
2237 } else {
2238 pSpectInfo[j + 4].weight =
2239 tmpWeight1;
2240 /* for secondary channel selection */
2241 pSpectInfo[j].weight =
2242 SAP_ACS_WEIGHT_MAX * 2
2243 - 1;
2244 pSpectInfo[j + 8].weight =
2245 SAP_ACS_WEIGHT_MAX * 2;
2246 }
2247 } else {
2248 if (pSpectInfo[j + 4].weight <=
2249 pSpectInfo[j + 8].weight) {
2250 pSpectInfo[j + 4].weight =
2251 tmpWeight2;
2252 pSpectInfo[j].weight =
2253 SAP_ACS_WEIGHT_MAX * 2;
2254 /* for secondary channel selection */
2255 pSpectInfo[j + 8].weight =
2256 SAP_ACS_WEIGHT_MAX * 2
2257 - 1;
2258 } else {
2259 pSpectInfo[j + 8].weight =
2260 tmpWeight2;
2261 pSpectInfo[j].weight =
2262 SAP_ACS_WEIGHT_MAX * 2;
2263 pSpectInfo[j + 4].weight =
2264 SAP_ACS_WEIGHT_MAX * 2;
2265 }
2266 }
2267 } else {
bingsaa6f96a2017-09-11 09:49:43 +08002268 tmpWeight1 = pSpectInfo[j].weight_copy +
2269 pSpectInfo[j + 4].weight_copy;
2270 if (pSpectInfo[j].weight_copy <=
2271 pSpectInfo[j + 4].weight_copy) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002272 pSpectInfo[j].weight = tmpWeight1;
2273 pSpectInfo[j + 4].weight =
2274 SAP_ACS_WEIGHT_MAX * 2;
2275 } else {
2276 pSpectInfo[j + 4].weight = tmpWeight1;
2277 pSpectInfo[j].weight =
2278 SAP_ACS_WEIGHT_MAX * 2;
2279 }
2280 }
2281 }
bingse2782382017-03-23 10:34:52 +08002282 /*
2283 * Every channel should be checked. Add the check for the omissive
2284 * channel. Mark the channel whose combination can't satisfy 40MHZ
2285 * as max value, so that it will be sorted to the bottom.
2286 */
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002287 if (REGDOMAIN_FCC == domain)
bingse2782382017-03-23 10:34:52 +08002288 ht40plus2gendch = HT40PLUS_2G_FCC_CH_END;
2289 else
2290 ht40plus2gendch = HT40PLUS_2G_EURJAP_CH_END;
2291 for (i = HT40MINUS_2G_CH_START; i <= ht40plus2gendch; i++) {
2292 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
2293 if (pSpectInfo[j].chNum == i &&
2294 ((pSpectInfo[j].chNum + 4) !=
2295 pSpectInfo[j+4].chNum) &&
2296 ((pSpectInfo[j].chNum - 4) !=
2297 pSpectInfo[j-4].chNum))
2298 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2;
2299 }
2300 }
2301 for (i = ht40plus2gendch + 1; i <= HT40MINUS_2G_CH_END; i++) {
2302 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
2303 if (pSpectInfo[j].chNum == i &&
2304 (pSpectInfo[j].chNum - 4) !=
2305 pSpectInfo[j-4].chNum)
2306 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2;
2307 }
2308 }
Himanshu Agarwal91c5c0f2018-02-13 14:40:56 +05302309
2310 pSpectInfo = pSpectInfoParams->pSpectCh;
2311 for (j = 0; j < (pSpectInfoParams->numSpectChans); j++) {
2312 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2313 "In %s, Channel=%d Weight= %d rssi=%d bssCount=%d",
2314 __func__, pSpectInfo->chNum, pSpectInfo->weight,
2315 pSpectInfo->rssiAgr, pSpectInfo->bssCount);
2316 pSpectInfo++;
2317 }
2318
Manishekar Chandrasekaran44e334f2016-05-30 16:42:50 +05302319 sap_sort_chl_weight(pSpectInfoParams);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002320}
2321
2322/*==========================================================================
2323 FUNCTION sap_sort_chl_weight_ht40_5_g
2324
2325 DESCRIPTION
Jeff Johnsonc7e4d162018-05-12 16:20:34 -07002326 Function to sort the channels with the least weight first for HT40 channels
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002327
2328 DEPENDENCIES
2329 NA.
2330
2331 PARAMETERS
2332
2333 IN
2334 pSpectInfoParams : Pointer to the tSapChSelSpectInfo structure
2335
2336 RETURN VALUE
2337 void : NULL
2338
2339 SIDE EFFECTS
2340 ============================================================================*/
Jeff Johnson464f7ea2016-10-07 10:21:26 -07002341static void sap_sort_chl_weight_ht40_5_g(tSapChSelSpectInfo *pSpectInfoParams)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002342{
2343 uint8_t i, j;
2344 tSapSpectChInfo *pSpectInfo;
2345
2346 pSpectInfo = pSpectInfoParams->pSpectCh;
2347 /*for each HT40 channel, calculate the combined weight of the
2348 two 20MHz weight */
2349 for (i = 0; i < ARRAY_SIZE(acs_ht40_channels5_g); i++) {
2350 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
2351 if (pSpectInfo[j].chNum ==
2352 acs_ht40_channels5_g[i].chStartNum)
2353 break;
2354 }
2355 if (j == pSpectInfoParams->numSpectChans)
2356 continue;
2357
2358 /* found the channel, add the two adjacent channels' weight */
2359 if ((pSpectInfo[j].chNum + 4) == pSpectInfo[j + 1].chNum) {
2360 acs_ht40_channels5_g[i].weight = pSpectInfo[j].weight +
2361 pSpectInfo[j + 1].weight;
2362 /* select better of the adjact channel as the primary channel */
2363 if (pSpectInfo[j].weight <= pSpectInfo[j + 1].weight) {
2364 pSpectInfo[j].weight =
2365 acs_ht40_channels5_g[i].weight;
2366 /* mark the adjacent channel's weight as max value so
2367 that it will be sorted to the bottom */
2368 pSpectInfo[j + 1].weight =
2369 SAP_ACS_WEIGHT_MAX * 2;
2370 } else {
2371 pSpectInfo[j + 1].weight =
2372 acs_ht40_channels5_g[i].weight;
2373 /* mark the adjacent channel's weight as max value so
2374 that it will be sorted to the bottom */
2375 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2;
2376 }
2377
2378 } else
2379 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2;
2380 }
2381
bingse2782382017-03-23 10:34:52 +08002382 /*
2383 *Every channel should be checked. Add the check for the omissive
2384 * channel. Mark the channel whose combination can't satisfy 40MHZ
2385 * as max value, so that it will be sorted to the bottom
2386 */
2387 for (j = 1; j < pSpectInfoParams->numSpectChans; j++) {
2388 for (i = 0; i < ARRAY_SIZE(acs_ht40_channels5_g); i++) {
2389 if (pSpectInfo[j].chNum ==
2390 (acs_ht40_channels5_g[i].chStartNum +
2391 4) &&
2392 pSpectInfo[j - 1].chNum !=
2393 acs_ht40_channels5_g[i].chStartNum) {
2394 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2;
2395 break;
2396 }
2397 }
2398 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002399 /* avoid channel 165 by setting its weight to max */
2400 pSpectInfo = pSpectInfoParams->pSpectCh;
2401 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
gaurank kathpalia1dea75b2019-01-10 13:53:43 +05302402 if (pSpectInfo[j].chNum >= CHANNEL_165) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002403 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2;
2404 break;
2405 }
2406 }
2407
2408 pSpectInfo = pSpectInfoParams->pSpectCh;
2409 for (j = 0; j < (pSpectInfoParams->numSpectChans); j++) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302410 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002411 "In %s, Channel=%d Weight= %d rssi=%d bssCount=%d",
2412 __func__, pSpectInfo->chNum, pSpectInfo->weight,
2413 pSpectInfo->rssiAgr, pSpectInfo->bssCount);
2414 pSpectInfo++;
2415 }
2416
2417 sap_sort_chl_weight(pSpectInfoParams);
2418}
2419
2420/*==========================================================================
2421 FUNCTION sap_sort_chl_weight_all
2422
2423 DESCRIPTION
Jeff Johnsonc7e4d162018-05-12 16:20:34 -07002424 Function to sort the channels with the least weight first
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002425
2426 DEPENDENCIES
2427 NA.
2428
2429 PARAMETERS
2430
2431 IN
Jeff Johnsone13d8062017-09-28 06:54:55 -07002432 sap_ctx : Pointer to the struct sap_context *structure
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002433 pSpectInfoParams : Pointer to the tSapChSelSpectInfo structure
2434
2435 RETURN VALUE
2436 void : NULL
2437
2438 SIDE EFFECTS
2439 ============================================================================*/
Jeff Johnsone13d8062017-09-28 06:54:55 -07002440static void sap_sort_chl_weight_all(struct sap_context *sap_ctx,
Jeff Johnson464f7ea2016-10-07 10:21:26 -07002441 tSapChSelSpectInfo *pSpectInfoParams,
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002442 uint32_t operatingBand,
2443 v_REGDOMAIN_t domain)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002444{
2445 tSapSpectChInfo *pSpectCh = NULL;
2446 uint32_t j = 0;
2447#ifndef SOFTAP_CHANNEL_RANGE
2448 uint32_t i = 0;
2449#endif
2450
2451 pSpectCh = pSpectInfoParams->pSpectCh;
2452#ifdef SOFTAP_CHANNEL_RANGE
2453
Jeff Johnsone13d8062017-09-28 06:54:55 -07002454 switch (sap_ctx->acs_cfg->ch_width) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002455 case CH_WIDTH_40MHZ:
Himanshu Agarwal91c5c0f2018-02-13 14:40:56 +05302456 /*
2457 * Assign max weight to all 5Ghz channels when operating band
2458 * is 11g and to all 2.4Ghz channels when operating band is 11a
2459 * or 11abg to avoid selection in ACS algorithm for starting SAP
2460 */
2461 if (eCSR_DOT11_MODE_11g == operatingBand) {
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002462 sap_sort_chl_weight_ht40_24_g(pSpectInfoParams, domain);
Himanshu Agarwal91c5c0f2018-02-13 14:40:56 +05302463 sap_allocate_max_weight_ht40_5_g(pSpectInfoParams);
2464 } else {
2465 sap_allocate_max_weight_ht40_24_g(pSpectInfoParams);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002466 sap_sort_chl_weight_ht40_5_g(pSpectInfoParams);
2467 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002468 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002469 case CH_WIDTH_80MHZ:
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07002470 case CH_WIDTH_80P80MHZ:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002471 sap_sort_chl_weight_ht80(pSpectInfoParams);
2472 break;
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07002473 case CH_WIDTH_160MHZ:
2474 sap_sort_chl_weight_vht160(pSpectInfoParams);
2475 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002476 case CH_WIDTH_20MHZ:
2477 default:
2478 /* Sorting the channels as per weights as 20MHz channels */
2479 sap_sort_chl_weight(pSpectInfoParams);
2480 }
2481
2482#else
2483 /* Sorting the channels as per weights */
2484 for (i = 0; i < SPECT_24GHZ_CH_COUNT; i++) {
2485 minWeightIndex = i;
2486 for (j = i + 1; j < SPECT_24GHZ_CH_COUNT; j++) {
2487 if (pSpectCh[j].weight <
2488 pSpectCh[minWeightIndex].weight) {
2489 minWeightIndex = j;
2490 }
2491 }
2492 if (minWeightIndex != i) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302493 qdf_mem_copy(&temp, &pSpectCh[minWeightIndex],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002494 sizeof(*pSpectCh));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302495 qdf_mem_copy(&pSpectCh[minWeightIndex], &pSpectCh[i],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002496 sizeof(*pSpectCh));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302497 qdf_mem_copy(&pSpectCh[i], &temp, sizeof(*pSpectCh));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002498 }
2499 }
2500#endif
2501
2502 /* For testing */
Ravi Joshi9788fcd2018-02-13 15:12:22 -08002503 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002504 "In %s, Sorted Spectrum Channels Weight", __func__);
2505 pSpectCh = pSpectInfoParams->pSpectCh;
2506 for (j = 0; j < (pSpectInfoParams->numSpectChans); j++) {
Ravi Joshi9788fcd2018-02-13 15:12:22 -08002507 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002508 "In %s, Channel=%d Weight= %d rssi=%d bssCount=%d",
2509 __func__, pSpectCh->chNum, pSpectCh->weight,
2510 pSpectCh->rssiAgr, pSpectCh->bssCount);
2511 pSpectCh++;
2512 }
2513
2514}
2515
Naveen Rawatbec64d92017-09-13 14:35:21 -07002516/**
2517 * sap_is_ch_non_overlap() - returns true if non-overlapping channel
2518 * @sap_ctx: Sap context
2519 * @ch: channel number
2520 *
2521 * Returns: true if non-overlapping (1, 6, 11) channel, false otherwise
2522 */
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -07002523static bool sap_is_ch_non_overlap(struct sap_context *sap_ctx, uint16_t ch)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002524{
Naveen Rawatbec64d92017-09-13 14:35:21 -07002525 if (sap_ctx->enableOverLapCh)
Srinivas Girigowda74a66d62017-06-21 23:28:25 -07002526 return true;
Naveen Rawatbec64d92017-09-13 14:35:21 -07002527
2528 if ((ch == CHANNEL_1) || (ch == CHANNEL_6) || (ch == CHANNEL_11))
Srinivas Girigowda74a66d62017-06-21 23:28:25 -07002529 return true;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002530
Srinivas Girigowda74a66d62017-06-21 23:28:25 -07002531 return false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002532}
2533
Dustin Brown0ce56d32016-10-17 16:18:03 -07002534#ifdef FEATURE_WLAN_CH_AVOID
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002535/**
2536 * sap_select_channel_no_scan_result() - select SAP channel when no scan results
2537 * are available.
2538 * @sap_ctx: Sap context
2539 *
2540 * Returns: channel number if success, 0 otherwise
2541 */
Jeff Johnson7730fbb2018-11-08 13:48:27 -08002542static uint8_t sap_select_channel_no_scan_result(mac_handle_t mac_handle,
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -07002543 struct sap_context *sap_ctx)
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002544{
Mohit Khanna841044f2016-03-25 16:16:24 -07002545 enum channel_state ch_type;
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002546 uint8_t i, first_safe_ch_in_range = SAP_CHANNEL_NOT_SELECTED;
Dustin Brown0ce56d32016-10-17 16:18:03 -07002547 uint32_t start_ch_num = sap_ctx->acs_cfg->start_ch;
2548 uint32_t end_ch_num = sap_ctx->acs_cfg->end_ch;
Jeff Johnsonc59ef8b2018-12-02 12:01:21 -08002549 struct mac_context *mac_ctx = NULL;
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002550
Jeff Johnsona0619e42018-11-28 17:43:00 -08002551 mac_ctx = MAC_CONTEXT(mac_handle);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002552
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002553 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2554 FL("start - end: %d - %d"), start_ch_num, end_ch_num);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002555
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002556 /* get a channel in PCL and within the range */
2557 for (i = 0; i < sap_ctx->acs_cfg->pcl_ch_count; i++) {
2558 if ((sap_ctx->acs_cfg->pcl_channels[i] < start_ch_num) ||
2559 (sap_ctx->acs_cfg->pcl_channels[i] > end_ch_num))
2560 continue;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002561
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002562 first_safe_ch_in_range = sap_ctx->acs_cfg->pcl_channels[i];
2563 break;
2564 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002565
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002566 if (SAP_CHANNEL_NOT_SELECTED != first_safe_ch_in_range)
2567 return first_safe_ch_in_range;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002568
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002569 for (i = 0; i < NUM_CHANNELS; i++) {
2570 if ((safe_channels[i].channelNumber < start_ch_num) ||
2571 (safe_channels[i].channelNumber > end_ch_num))
2572 continue;
2573
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002574 ch_type = wlan_reg_get_channel_state(mac_ctx->pdev,
2575 safe_channels[i].channelNumber);
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002576
2577 if ((ch_type == CHANNEL_STATE_DISABLE) ||
2578 (ch_type == CHANNEL_STATE_INVALID))
2579 continue;
Arif Hussain88d1fdd2018-09-26 16:12:24 -07002580 if ((!mac_ctx->mlme_cfg->dfs_cfg.dfs_master_capable) &&
2581 (CHANNEL_STATE_DFS == ch_type)) {
Kondabattini, Ganesh13bb4b12016-09-04 16:16:53 +05302582 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2583 "%s: DFS master mode disabled. Skip DFS channel %d",
2584 __func__, safe_channels[i].channelNumber);
2585 continue;
2586 }
Agrawal Ashish65634612016-08-18 13:24:32 +05302587 if ((sap_ctx->dfs_mode == ACS_DFS_MODE_DISABLE) &&
2588 (CHANNEL_STATE_DFS == ch_type))
2589 continue;
Kondabattini, Ganesh13bb4b12016-09-04 16:16:53 +05302590
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002591 if (safe_channels[i].isSafe == true) {
2592 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2593 FL("channel %d in the configuration is safe"),
2594 safe_channels[i].channelNumber);
2595 first_safe_ch_in_range = safe_channels[i].channelNumber;
2596 break;
2597 }
2598
2599 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2600 FL("channel %d in the configuration is unsafe"),
2601 safe_channels[i].channelNumber);
2602 }
2603
2604 /* if no channel selected return SAP_CHANNEL_NOT_SELECTED */
2605 return first_safe_ch_in_range;
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002606}
Dustin Brown0ce56d32016-10-17 16:18:03 -07002607#else
Jeff Johnson7730fbb2018-11-08 13:48:27 -08002608static uint8_t sap_select_channel_no_scan_result(mac_handle_t mac_handle,
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -07002609 struct sap_context *sap_ctx)
Dustin Brown0ce56d32016-10-17 16:18:03 -07002610{
2611 uint32_t start_ch_num = sap_ctx->acs_cfg->start_ch;
2612
2613 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2614 FL("start - end: %d - %d"),
2615 start_ch_num,
2616 sap_ctx->acs_cfg->end_ch);
2617
2618 sap_ctx->acs_cfg->pri_ch = start_ch_num;
2619 sap_ctx->acs_cfg->ht_sec_ch = 0;
2620
2621 /* pick the first channel in configured range */
2622 return start_ch_num;
2623}
2624#endif /* FEATURE_WLAN_CH_AVOID */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002625
2626/**
2627 * sap_select_channel() - select SAP channel
Jeff Johnson7730fbb2018-11-08 13:48:27 -08002628 * @mac_handle: Opaque handle to the global MAC context
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002629 * @sap_ctx: Sap context
2630 * @scan_result: Pointer to tScanResultHandle
2631 *
2632 * Runs a algorithm to select the best channel to operate in based on BSS
2633 * rssi and bss count on each channel
2634 *
2635 * Returns: channel number if success, 0 otherwise
2636 */
Jeff Johnson7730fbb2018-11-08 13:48:27 -08002637uint8_t sap_select_channel(mac_handle_t mac_handle,
2638 struct sap_context *sap_ctx,
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002639 tScanResultHandle scan_result)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002640{
2641 /* DFS param object holding all the data req by the algo */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002642 tSapChSelSpectInfo spect_info_obj = { NULL, 0 };
2643 tSapChSelSpectInfo *spect_info = &spect_info_obj;
2644 uint8_t best_ch_num = SAP_CHANNEL_NOT_SELECTED;
Jeff Johnson6c336832019-03-26 09:09:08 -07002645 uint32_t best_ch_weight = SAP_ACS_WEIGHT_MAX;
bingse2782382017-03-23 10:34:52 +08002646 uint32_t ht40plus2gendch = 0;
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002647 v_REGDOMAIN_t domain;
Arif Hussain21ad4342017-12-21 12:00:54 -08002648 uint8_t country[CDS_COUNTRY_CODE_LEN + 1];
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002649#ifdef SOFTAP_CHANNEL_RANGE
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002650 uint8_t count;
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002651 uint32_t start_ch_num, end_ch_num, tmp_ch_num, operating_band = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002652#endif
Jeff Johnsonc59ef8b2018-12-02 12:01:21 -08002653 struct mac_context *mac_ctx;
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002654
Jeff Johnsona0619e42018-11-28 17:43:00 -08002655 mac_ctx = MAC_CONTEXT(mac_handle);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302656 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002657 "In %s, Running SAP Ch Select", __func__);
2658
Jeff Johnson7730fbb2018-11-08 13:48:27 -08002659 sap_update_unsafe_channel_list(mac_handle, sap_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002660
gaoleze5108942017-03-31 16:56:42 +08002661 /*
2662 * If ACS weight is not enabled on noise_floor/channel_free/tx_power,
2663 * then skip acs process if no bss found.
2664 */
Jeff Johnson4cfe6cc2019-03-18 13:40:27 -07002665 if (!scan_result &&
gaoleze5108942017-03-31 16:56:42 +08002666 !(sap_ctx->auto_channel_select_weight & 0xffff00)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302667 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002668 FL("No external AP present"));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002669
2670#ifndef SOFTAP_CHANNEL_RANGE
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002671 return SAP_CHANNEL_NOT_SELECTED;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002672#else
Jeff Johnson7730fbb2018-11-08 13:48:27 -08002673 return sap_select_channel_no_scan_result(mac_handle, sap_ctx);
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002674#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002675 }
2676
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002677 /* Initialize the structure pointed by spect_info */
Jeff Johnson7730fbb2018-11-08 13:48:27 -08002678 if (sap_chan_sel_init(mac_handle, spect_info, sap_ctx) != true) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302679 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002680 FL("Ch Select initialization failed"));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002681 return SAP_CHANNEL_NOT_SELECTED;
2682 }
2683 /* Compute the weight of the entire spectrum in the operating band */
Jeff Johnson7730fbb2018-11-08 13:48:27 -08002684 sap_compute_spect_weight(spect_info, mac_handle, scan_result, sap_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002685
2686#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
2687 /* process avoid channel IE to collect all channels to avoid */
Jeff Johnson7730fbb2018-11-08 13:48:27 -08002688 sap_process_avoid_ie(mac_handle, sap_ctx, scan_result, spect_info);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002689#endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
2690
Paul Zhang0f85b412018-01-18 19:14:51 +08002691 wlan_reg_read_current_country(mac_ctx->psoc, country);
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002692 wlan_reg_get_domain_from_country_code(&domain, country, SOURCE_DRIVER);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002693#ifdef SOFTAP_CHANNEL_RANGE
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002694 start_ch_num = sap_ctx->acs_cfg->start_ch;
2695 end_ch_num = sap_ctx->acs_cfg->end_ch;
2696 SET_ACS_BAND(operating_band, sap_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002697
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002698 /* Sort the ch lst as per the computed weights, lesser weight first. */
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002699 sap_sort_chl_weight_all(sap_ctx, spect_info, operating_band, domain);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002700
2701 /*Loop till get the best channel in the given range */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002702 for (count = 0; count < spect_info->numSpectChans; count++) {
2703 if ((start_ch_num > spect_info->pSpectCh[count].chNum) ||
2704 (end_ch_num < spect_info->pSpectCh[count].chNum))
2705 continue;
2706
2707 if (best_ch_num == SAP_CHANNEL_NOT_SELECTED) {
2708 best_ch_num = spect_info->pSpectCh[count].chNum;
2709 /* check if best_ch_num is in preferred channel list */
2710 best_ch_num =
2711 sap_select_preferred_channel_from_channel_list(
2712 best_ch_num, sap_ctx, spect_info);
2713 /* if not in preferred ch lst, go to nxt best ch */
2714 if (best_ch_num == SAP_CHANNEL_NOT_SELECTED)
2715 continue;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002716
2717#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002718 /*
2719 * Weight of the channels(device's AP is operating)
Jeff Johnson2cc31fd2018-05-05 23:54:23 -07002720 * increased to MAX+1 so that they will be chosen only
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002721 * when there is no other best channel to choose
2722 */
2723 if (sap_check_in_avoid_ch_list(sap_ctx, best_ch_num)) {
2724 best_ch_num = SAP_CHANNEL_NOT_SELECTED;
2725 continue;
2726 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002727#endif
2728
Jeff Johnson6c336832019-03-26 09:09:08 -07002729 best_ch_weight =
2730 spect_info->pSpectCh[count].weight_copy;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002731 }
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002732
2733 if (best_ch_num == SAP_CHANNEL_NOT_SELECTED)
2734 continue;
2735
Tushnim Bhattacharyya03103fd2017-06-23 10:48:52 -07002736 if (operating_band != eCSR_DOT11_MODE_11g) {
2737 QDF_TRACE(QDF_MODULE_ID_SAP,
2738 QDF_TRACE_LEVEL_INFO_HIGH,
2739 "operating_band %d", operating_band);
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002740 continue;
Tushnim Bhattacharyya03103fd2017-06-23 10:48:52 -07002741 }
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002742
2743 /* Give preference to Non-overlap channels */
Naveen Rawatbec64d92017-09-13 14:35:21 -07002744 if (false == sap_is_ch_non_overlap(sap_ctx,
Tushnim Bhattacharyya03103fd2017-06-23 10:48:52 -07002745 spect_info->pSpectCh[count].chNum)) {
2746 QDF_TRACE(QDF_MODULE_ID_SAP,
2747 QDF_TRACE_LEVEL_INFO_HIGH,
Naveen Rawatbec64d92017-09-13 14:35:21 -07002748 FL("ch: %d skipped as its overlapping ch"),
2749 spect_info->pSpectCh[count].chNum);
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002750 continue;
Tushnim Bhattacharyya03103fd2017-06-23 10:48:52 -07002751 }
2752
2753 if (wlan_reg_is_dfs_ch(mac_ctx->pdev,
2754 spect_info->pSpectCh[count].chNum) &&
2755 policy_mgr_disallow_mcc(mac_ctx->psoc,
2756 spect_info->pSpectCh[count].chNum)) {
2757 QDF_TRACE(QDF_MODULE_ID_SAP,
2758 QDF_TRACE_LEVEL_INFO_HIGH,
2759 "No DFS MCC");
2760 continue;
2761 }
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002762
Jeff Johnson6c336832019-03-26 09:09:08 -07002763 if (spect_info->pSpectCh[count].weight_copy > best_ch_weight)
bings14d1d3b2017-08-03 11:14:29 +08002764 continue;
2765
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002766 tmp_ch_num = spect_info->pSpectCh[count].chNum;
gaoleze5108942017-03-31 16:56:42 +08002767 tmp_ch_num = sap_channel_in_acs_channel_list(
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002768 tmp_ch_num, sap_ctx, spect_info);
2769 if (tmp_ch_num == SAP_CHANNEL_NOT_SELECTED)
2770 continue;
2771
2772 best_ch_num = tmp_ch_num;
2773 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002774 }
2775#else
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002776 /* Sort the ch lst as per the computed weights, lesser weight first. */
Jeff Johnson7730fbb2018-11-08 13:48:27 -08002777 sap_sort_chl_weight_all(sap_ctx, mac_handle, spect_info);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002778 /* Get the first channel in sorted array as best 20M Channel */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002779 best_ch_num = (uint8_t) spect_info->pSpectCh[0].chNum;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002780 /* Select Best Channel from Channel List if Configured */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002781 best_ch_num = sap_select_preferred_channel_from_channel_list(
2782 best_ch_num, sap_ctx, spect_info);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002783#endif
2784
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002785 /*
2786 * in case the best channel seleted is not in PCL and there is another
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002787 * channel which has same weightage and is in PCL, choose the one in
2788 * PCL
2789 */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002790 for (count = 0; count < spect_info->numSpectChans; count++) {
2791 if (!ch_in_pcl(sap_ctx, spect_info->pSpectCh[count].chNum) ||
Jeff Johnson6c336832019-03-26 09:09:08 -07002792 (spect_info->pSpectCh[count].weight != best_ch_weight))
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002793 continue;
2794
2795 if (sap_select_preferred_channel_from_channel_list(
2796 spect_info->pSpectCh[count].chNum, sap_ctx, spect_info)
2797 == SAP_CHANNEL_NOT_SELECTED)
2798 continue;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002799
2800#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002801 if (sap_check_in_avoid_ch_list(sap_ctx, best_ch_num))
2802 continue;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002803#endif
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002804 best_ch_num = spect_info->pSpectCh[count].chNum;
2805 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2806 FL("change best channel to %d in PCL"), best_ch_num);
2807 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002808 }
2809
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002810 sap_ctx->acs_cfg->pri_ch = best_ch_num;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002811 /* determine secondary channel for 2.4G channel 5, 6, 7 in HT40 */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002812 if ((operating_band != eCSR_DOT11_MODE_11g) ||
2813 (sap_ctx->acs_cfg->ch_width != CH_WIDTH_40MHZ))
2814 goto sap_ch_sel_end;
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002815 if (REGDOMAIN_FCC == domain)
bingse2782382017-03-23 10:34:52 +08002816 ht40plus2gendch = HT40PLUS_2G_FCC_CH_END;
2817 else
2818 ht40plus2gendch = HT40PLUS_2G_EURJAP_CH_END;
2819 if ((best_ch_num >= HT40MINUS_2G_CH_START) &&
2820 (best_ch_num <= ht40plus2gendch)) {
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002821 int weight_below, weight_above, i;
2822 tSapSpectChInfo *pspect_info;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002823
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002824 weight_below = weight_above = SAP_ACS_WEIGHT_MAX;
2825 pspect_info = spect_info->pSpectCh;
2826 for (i = 0; i < spect_info->numSpectChans; i++) {
2827 if (pspect_info[i].chNum == (best_ch_num - 4))
2828 weight_below = pspect_info[i].weight;
2829 if (pspect_info[i].chNum == (best_ch_num + 4))
2830 weight_above = pspect_info[i].weight;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002831 }
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002832
2833 if (weight_below < weight_above)
2834 sap_ctx->acs_cfg->ht_sec_ch =
2835 sap_ctx->acs_cfg->pri_ch - 4;
2836 else
2837 sap_ctx->acs_cfg->ht_sec_ch =
2838 sap_ctx->acs_cfg->pri_ch + 4;
2839 } else if (best_ch_num >= 1 && best_ch_num <= 4) {
2840 sap_ctx->acs_cfg->ht_sec_ch = sap_ctx->acs_cfg->pri_ch + 4;
bingse2782382017-03-23 10:34:52 +08002841 } else if (best_ch_num >= ht40plus2gendch && best_ch_num <=
2842 HT40MINUS_2G_CH_END) {
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002843 sap_ctx->acs_cfg->ht_sec_ch = sap_ctx->acs_cfg->pri_ch - 4;
2844 } else if (best_ch_num == 14) {
2845 sap_ctx->acs_cfg->ht_sec_ch = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002846 }
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002847 sap_ctx->secondary_ch = sap_ctx->acs_cfg->ht_sec_ch;
2848
2849sap_ch_sel_end:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002850 /* Free all the allocated memory */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002851 sap_chan_sel_exit(spect_info);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002852
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302853 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002854 FL("Running SAP Ch select Completed, Ch=%d"), best_ch_num);
Jeff Johnson6c336832019-03-26 09:09:08 -07002855 host_log_acs_best_chan(best_ch_num, best_ch_weight);
wadesongcb0ded22018-02-02 17:57:20 +08002856
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002857 if (best_ch_num > 0 && best_ch_num <= 252)
2858 return best_ch_num;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002859 else
2860 return SAP_CHANNEL_NOT_SELECTED;
2861}