blob: e9f7aa75a794f56e7dd021f07c145e51b8fbbcd5 [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 Johnson7730fbb2018-11-08 13:48:27 -0800410void 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}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800474
475#endif /* FEATURE_WLAN_CH_AVOID */
476
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800477/**
gaoleze5108942017-03-31 16:56:42 +0800478 * sap_channel_in_acs_channel_list() - check if channel in acs channel list
479 * @channel_num: channel to check
480 * @sap_ctx: struct ptSapContext
481 * @spect_info_params: strcut tSapChSelSpectInfo
482 *
483 * This function checks if specified channel is in the configured ACS channel
484 * list.
485 *
486 * Return: channel number if in acs channel list or SAP_CHANNEL_NOT_SELECTED
487 */
gaoleze5108942017-03-31 16:56:42 +0800488uint8_t sap_channel_in_acs_channel_list(uint8_t channel_num,
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -0700489 struct sap_context *sap_ctx,
gaoleze5108942017-03-31 16:56:42 +0800490 tSapChSelSpectInfo *spect_info_params)
491{
492 uint8_t i = 0;
493
Jeff Johnson4cfe6cc2019-03-18 13:40:27 -0700494 if ((!sap_ctx->acs_cfg->ch_list) ||
495 (!spect_info_params))
gaoleze5108942017-03-31 16:56:42 +0800496 return channel_num;
497
498 if (channel_num > 0 && channel_num <= 252) {
499 for (i = 0; i < sap_ctx->acs_cfg->ch_list_count; i++) {
500 if ((sap_ctx->acs_cfg->ch_list[i]) == channel_num)
501 return channel_num;
502 }
503 return SAP_CHANNEL_NOT_SELECTED;
504 } else {
505 return SAP_CHANNEL_NOT_SELECTED;
506 }
507}
508
509/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800510 * sap_select_preferred_channel_from_channel_list() - to calc best cahnnel
511 * @best_chnl: best channel already calculated among all the chanels
512 * @sap_ctx: sap context
513 * @spectinfo_param: Pointer to tSapChSelSpectInfo structure
514 *
515 * This function calculates the best channel among the configured channel list.
516 * If channel list not configured then returns the best channel calculated
517 * among all the channel list.
518 *
519 * Return: uint8_t best channel
520 */
Jeff Johnson464f7ea2016-10-07 10:21:26 -0700521static
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800522uint8_t sap_select_preferred_channel_from_channel_list(uint8_t best_chnl,
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -0700523 struct sap_context *sap_ctx,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800524 tSapChSelSpectInfo *spectinfo_param)
525{
526 uint8_t i = 0;
Jeff Johnsonc59ef8b2018-12-02 12:01:21 -0800527 struct mac_context *mac_ctx = sme_get_mac_context();
Tushnim Bhattacharyya518e80f2017-08-30 17:35:33 -0700528
Jeff Johnson4cfe6cc2019-03-18 13:40:27 -0700529 if (!mac_ctx) {
Tushnim Bhattacharyya518e80f2017-08-30 17:35:33 -0700530 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
531 "pmac Global Context is NULL");
532 return SAP_CHANNEL_NOT_SELECTED;
533 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800534
535 /*
536 * If Channel List is not Configured don't do anything
537 * Else return the Best Channel from the Channel List
538 */
Jeff Johnson4cfe6cc2019-03-18 13:40:27 -0700539 if ((!sap_ctx->acs_cfg->ch_list) ||
540 (!spectinfo_param) ||
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800541 (0 == sap_ctx->acs_cfg->ch_list_count))
542 return best_chnl;
543
544 if (best_chnl <= 0 || best_chnl > 252)
545 return SAP_CHANNEL_NOT_SELECTED;
546
547 /* Select the best channel from allowed list */
548 for (i = 0; i < sap_ctx->acs_cfg->ch_list_count; i++) {
Tushnim Bhattacharyya518e80f2017-08-30 17:35:33 -0700549 if ((sap_ctx->acs_cfg->ch_list[i] == best_chnl) &&
550 !(wlan_reg_is_dfs_ch(mac_ctx->pdev, best_chnl) &&
551 policy_mgr_disallow_mcc(mac_ctx->psoc, best_chnl))) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530552 QDF_TRACE(QDF_MODULE_ID_SAP,
Ravi Joshi9788fcd2018-02-13 15:12:22 -0800553 QDF_TRACE_LEVEL_INFO,
Naveen Rawatbec64d92017-09-13 14:35:21 -0700554 "Best channel so far is: %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800555 best_chnl);
556 return best_chnl;
557 }
558 }
559
560 return SAP_CHANNEL_NOT_SELECTED;
561}
562
Jeff Johnson7730fbb2018-11-08 13:48:27 -0800563/**
564 * sap_chan_sel_init() - Initialize channel select
565 * @mac_handle: Opaque handle to the global MAC context
566 * @pSpectInfoParams: Pointer to tSapChSelSpectInfo structure
567 * @sap_ctx: Pointer to SAP Context
568 *
569 * Function sap_chan_sel_init allocates the memory, initializes the
570 * structures used by the channel selection algorithm
571 *
572 * Return: bool Success or FAIL
573 */
574static bool sap_chan_sel_init(mac_handle_t mac_handle,
Jeff Johnson464f7ea2016-10-07 10:21:26 -0700575 tSapChSelSpectInfo *pSpectInfoParams,
Jeff Johnsone13d8062017-09-28 06:54:55 -0700576 struct sap_context *sap_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800577{
578 tSapSpectChInfo *pSpectCh = NULL;
579 uint8_t *pChans = NULL;
580 uint16_t channelnum = 0;
Jeff Johnsonc59ef8b2018-12-02 12:01:21 -0800581 struct mac_context *mac = MAC_CONTEXT(mac_handle);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800582 bool chSafe = true;
583#ifdef FEATURE_WLAN_CH_AVOID
584 uint16_t i;
585#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800586 bool include_dfs_ch = true;
Himanshu Agarwalfee2e362018-01-18 20:26:35 +0530587 uint8_t chan_num;
Bala Venkatesh2f25c812017-12-15 17:42:12 +0530588 bool sta_sap_scc_on_dfs_chan =
Jeff Johnsonb9794442018-11-22 14:21:08 -0800589 policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan(mac->psoc);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800590
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530591 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, "In %s",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800592 __func__);
593
594 pSpectInfoParams->numSpectChans =
Jeff Johnsonb9794442018-11-22 14:21:08 -0800595 mac->scan.base_channels.numChannels;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800596
597 /* Allocate memory for weight computation of 2.4GHz */
Arif Hussain256cc282018-10-03 14:10:44 -0700598 pSpectCh = qdf_mem_malloc((pSpectInfoParams->numSpectChans) *
599 sizeof(*pSpectCh));
600 if (!pSpectCh)
Srinivas Girigowda74a66d62017-06-21 23:28:25 -0700601 return false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800602
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800603 /* Initialize the pointers in the DfsParams to the allocated memory */
604 pSpectInfoParams->pSpectCh = pSpectCh;
605
Jeff Johnsonb9794442018-11-22 14:21:08 -0800606 pChans = mac->scan.base_channels.channelList;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800607
Ryan Hsu4252a2f2016-01-05 11:18:24 -0800608#if defined(FEATURE_WLAN_STA_AP_MODE_DFS_DISABLE)
Jeff Johnsone13d8062017-09-28 06:54:55 -0700609 if (sap_ctx->dfs_ch_disable == true)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800610 include_dfs_ch = false;
611#endif
Jeff Johnsonb9794442018-11-22 14:21:08 -0800612 if (!mac->mlme_cfg->dfs_cfg.dfs_master_capable ||
Jeff Johnsone13d8062017-09-28 06:54:55 -0700613 ACS_DFS_MODE_DISABLE == sap_ctx->dfs_mode)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800614 include_dfs_ch = false;
615
616 /* Fill the channel number in the spectrum in the operating freq band */
617 for (channelnum = 0;
618 channelnum < pSpectInfoParams->numSpectChans;
Edhar, Mahesh Kumar4f660672015-10-30 11:53:26 +0530619 channelnum++, pChans++, pSpectCh++) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800620 chSafe = true;
621
Himanshu Agarwal052ce252018-06-18 17:18:59 +0530622 pSpectCh->chNum = *pChans;
623 /* Initialise for all channels */
624 pSpectCh->rssiAgr = SOFTAP_MIN_RSSI;
625 /* Initialise 20MHz for all the Channels */
626 pSpectCh->channelWidth = SOFTAP_HT20_CHANNELWIDTH;
627 /* Initialise max ACS weight for all channels */
628 pSpectCh->weight = SAP_ACS_WEIGHT_MAX;
629
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800630 /* check if the channel is in NOL blacklist */
Himanshu Agarwal052ce252018-06-18 17:18:59 +0530631 if (sap_dfs_is_channel_in_nol_list(
632 sap_ctx, *pChans,
633 PHY_SINGLE_CHANNEL_CENTERED)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530634 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800635 "In %s, Ch %d is in NOL list", __func__,
636 *pChans);
637 chSafe = false;
638 continue;
639 }
640
Bala Venkatesh2f25c812017-12-15 17:42:12 +0530641 if (!include_dfs_ch || sta_sap_scc_on_dfs_chan) {
Jeff Johnsonb9794442018-11-22 14:21:08 -0800642 if (wlan_reg_is_dfs_ch(mac->pdev, *pChans)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800643 chSafe = false;
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530644 QDF_TRACE(QDF_MODULE_ID_SAP,
645 QDF_TRACE_LEVEL_INFO_HIGH,
Bala Venkatesh2f25c812017-12-15 17:42:12 +0530646 "In %s, DFS Ch %d not considered for ACS. include_dfs_ch %u, sta_sap_scc_on_dfs_chan %d",
647 __func__, *pChans, include_dfs_ch,
648 sta_sap_scc_on_dfs_chan);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800649 continue;
650 }
651 }
652
653#ifdef FEATURE_WLAN_CH_AVOID
Amar Singhalb8d4f152016-02-10 10:21:43 -0800654 for (i = 0; i < NUM_CHANNELS; i++) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800655 if ((safe_channels[i].channelNumber == *pChans) &&
656 (false == safe_channels[i].isSafe)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530657 QDF_TRACE(QDF_MODULE_ID_SAP,
658 QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800659 "In %s, Ch %d is not safe", __func__,
660 *pChans);
661 chSafe = false;
662 break;
663 }
664 }
665#endif /* FEATURE_WLAN_CH_AVOID */
666
667 /* OFDM rates are not supported on channel 14 */
668 if (*pChans == 14 &&
Jeff Johnsone13d8062017-09-28 06:54:55 -0700669 eCSR_DOT11_MODE_11b != sap_ctx->csr_roamProfile.phyMode) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800670 continue;
671 }
672
Deepthi Gowri48b89332016-08-30 18:43:05 +0530673 /* Skip DSRC channels */
Jeff Johnsonb9794442018-11-22 14:21:08 -0800674 if (wlan_reg_is_dsrc_chan(mac->pdev, *pChans))
Kiran Kumar Lokere1a43bcf2018-05-15 15:51:58 -0700675 continue;
676
lifeng0b46ae52018-12-13 09:42:27 +0800677 if (!mac->mlme_cfg->reg.etsi13_srd_chan_in_master_mode &&
Jeff Johnsonb9794442018-11-22 14:21:08 -0800678 wlan_reg_is_etsi13_srd_chan(mac->pdev, *pChans))
Deepthi Gowri48b89332016-08-30 18:43:05 +0530679 continue;
680
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800681 if (true == chSafe) {
Srinivas Girigowda74a66d62017-06-21 23:28:25 -0700682 pSpectCh->valid = true;
Himanshu Agarwalfee2e362018-01-18 20:26:35 +0530683 for (chan_num = 0; chan_num < sap_ctx->num_of_channel;
684 chan_num++) {
685 if (pSpectCh->chNum !=
686 sap_ctx->channelList[chan_num])
687 continue;
688
689 /*
690 * Initialize ACS weight to 0 for channels
691 * present in sap context scan channel list
692 */
693 pSpectCh->weight = 0;
694 break;
695 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800696 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800697 }
Srinivas Girigowda74a66d62017-06-21 23:28:25 -0700698 return true;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800699}
700
gaoleze5108942017-03-31 16:56:42 +0800701/**
702 * sapweight_rssi_count() - calculates the channel weight due to rssi
Anurag Chouhan6d760662016-02-20 16:05:43 +0530703 and data count(here number of BSS observed)
gaoleze5108942017-03-31 16:56:42 +0800704 * @sap_ctx : Softap context
705 * @rssi : Max signal strength receieved from a BSS for the channel
706 * @count : Number of BSS observed in the channel
707 *
708 * Return: uint32_t Calculated channel weight based on above two
709 */
710static
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -0700711uint32_t sapweight_rssi_count(struct sap_context *sap_ctx, int8_t rssi,
gaoleze5108942017-03-31 16:56:42 +0800712 uint16_t count)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800713{
714 int32_t rssiWeight = 0;
715 int32_t countWeight = 0;
716 uint32_t rssicountWeight = 0;
gaoleze5108942017-03-31 16:56:42 +0800717 uint8_t softap_rssi_weight_cfg, softap_count_weight_cfg;
718 uint8_t softap_rssi_weight_local, softap_count_weight_local;
719
720 softap_rssi_weight_cfg =
721 ACS_WEIGHT_SOFTAP_RSSI_CFG(sap_ctx->auto_channel_select_weight);
722
723 softap_count_weight_cfg =
724 ACS_WEIGHT_SOFTAP_COUNT_CFG(sap_ctx->auto_channel_select_weight);
725
726 softap_rssi_weight_local =
727 ACS_WEIGHT_CFG_TO_LOCAL(sap_ctx->auto_channel_select_weight,
728 softap_rssi_weight_cfg);
729
730 softap_count_weight_local =
731 ACS_WEIGHT_CFG_TO_LOCAL(sap_ctx->auto_channel_select_weight,
732 softap_count_weight_cfg);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800733
734 /* Weight from RSSI */
gaoleze5108942017-03-31 16:56:42 +0800735 rssiWeight = ACS_WEIGHT_COMPUTE(sap_ctx->auto_channel_select_weight,
736 softap_rssi_weight_cfg,
737 rssi - SOFTAP_MIN_RSSI,
738 SOFTAP_MAX_RSSI - SOFTAP_MIN_RSSI);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800739
gaoleze5108942017-03-31 16:56:42 +0800740 if (rssiWeight > softap_rssi_weight_local)
741 rssiWeight = softap_rssi_weight_local;
742
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800743 else if (rssiWeight < 0)
744 rssiWeight = 0;
745
746 /* Weight from data count */
gaoleze5108942017-03-31 16:56:42 +0800747 countWeight = ACS_WEIGHT_COMPUTE(sap_ctx->auto_channel_select_weight,
748 softap_count_weight_cfg,
749 count - SOFTAP_MIN_COUNT,
750 SOFTAP_MAX_COUNT - SOFTAP_MIN_COUNT);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800751
gaoleze5108942017-03-31 16:56:42 +0800752 if (countWeight > softap_count_weight_local)
753 countWeight = softap_count_weight_local;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800754
755 rssicountWeight = rssiWeight + countWeight;
756
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530757 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800758 "In %s, rssiWeight=%d, countWeight=%d, rssicountWeight=%d",
759 __func__, rssiWeight, countWeight, rssicountWeight);
760
761 return rssicountWeight;
762}
763
764/**
gaoleze5108942017-03-31 16:56:42 +0800765 * sap_get_channel_status() - get channel info via channel number
766 * @p_mac: Pointer to Global MAC structure
767 * @channel_id: channel id
768 *
769 * Return: chan status info
770 */
771static struct lim_channel_status *sap_get_channel_status
Jeff Johnsonc59ef8b2018-12-02 12:01:21 -0800772 (struct mac_context *p_mac, uint32_t channel_id)
gaoleze5108942017-03-31 16:56:42 +0800773{
774 return csr_get_channel_status(p_mac, channel_id);
775}
776
777/**
778 * sap_clear_channel_status() - clear chan info
779 * @p_mac: Pointer to Global MAC structure
780 *
781 * Return: none
782 */
Jeff Johnsonc59ef8b2018-12-02 12:01:21 -0800783static void sap_clear_channel_status(struct mac_context *p_mac)
gaoleze5108942017-03-31 16:56:42 +0800784{
785 csr_clear_channel_status(p_mac);
786}
787
788/**
789 * sap_weight_channel_noise_floor() - compute noise floor weight
790 * @sap_ctx: sap context
791 * @chn_stat: Pointer to chan status info
792 *
793 * Return: channel noise floor weight
794 */
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -0700795static uint32_t sap_weight_channel_noise_floor(struct sap_context *sap_ctx,
gaoleze5108942017-03-31 16:56:42 +0800796 struct lim_channel_status
797 *channel_stat)
798{
799 uint32_t noise_floor_weight;
800 uint8_t softap_nf_weight_cfg;
801 uint8_t softap_nf_weight_local;
802
803 softap_nf_weight_cfg =
804 ACS_WEIGHT_SOFTAP_NOISE_FLOOR_CFG
805 (sap_ctx->auto_channel_select_weight);
806
807 softap_nf_weight_local =
808 ACS_WEIGHT_CFG_TO_LOCAL(sap_ctx->auto_channel_select_weight,
809 softap_nf_weight_cfg);
810
Jeff Johnson4cfe6cc2019-03-18 13:40:27 -0700811 if (!channel_stat || channel_stat->channelfreq == 0) {
Srinivas Girigowda80213e52018-01-23 14:51:33 -0800812 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG,
gaoleze5108942017-03-31 16:56:42 +0800813 "In %s, sanity check failed return max weight",
814 __func__);
815 return softap_nf_weight_local;
816 }
817
818 noise_floor_weight = (channel_stat->noise_floor == 0) ? 0 :
819 (ACS_WEIGHT_COMPUTE(
820 sap_ctx->auto_channel_select_weight,
821 softap_nf_weight_cfg,
822 channel_stat->noise_floor -
823 SOFTAP_MIN_NF,
824 SOFTAP_MAX_NF - SOFTAP_MIN_NF));
825
826 if (noise_floor_weight > softap_nf_weight_local)
827 noise_floor_weight = softap_nf_weight_local;
gaoleze5108942017-03-31 16:56:42 +0800828
829 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
830 "In %s, nf=%d, nfwc=%d, nfwl=%d, nfw=%d",
831 __func__, channel_stat->noise_floor,
832 softap_nf_weight_cfg, softap_nf_weight_local,
833 noise_floor_weight);
834
835 return noise_floor_weight;
836}
837
838/**
839 * sap_weight_channel_free() - compute channel free weight
840 * @sap_ctx: sap context
841 * @chn_stat: Pointer to chan status info
842 *
843 * Return: channel free weight
844 */
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -0700845static uint32_t sap_weight_channel_free(struct sap_context *sap_ctx,
gaoleze5108942017-03-31 16:56:42 +0800846 struct lim_channel_status
847 *channel_stat)
848{
849 uint32_t channel_free_weight;
850 uint8_t softap_channel_free_weight_cfg;
851 uint8_t softap_channel_free_weight_local;
852 uint32_t rx_clear_count = 0;
853 uint32_t cycle_count = 0;
854
855 softap_channel_free_weight_cfg =
856 ACS_WEIGHT_SOFTAP_CHANNEL_FREE_CFG
857 (sap_ctx->auto_channel_select_weight);
858
859 softap_channel_free_weight_local =
860 ACS_WEIGHT_CFG_TO_LOCAL(sap_ctx->auto_channel_select_weight,
861 softap_channel_free_weight_cfg);
862
Jeff Johnson4cfe6cc2019-03-18 13:40:27 -0700863 if (!channel_stat || channel_stat->channelfreq == 0) {
Srinivas Girigowda80213e52018-01-23 14:51:33 -0800864 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG,
gaoleze5108942017-03-31 16:56:42 +0800865 "In %s, sanity check failed return max weight",
866 __func__);
867 return softap_channel_free_weight_local;
868 }
869
870 rx_clear_count = channel_stat->rx_clear_count -
871 channel_stat->tx_frame_count -
872 channel_stat->rx_frame_count;
873 cycle_count = channel_stat->cycle_count;
874
875 /* LSH 4, otherwise it is always 0. */
876 channel_free_weight = (cycle_count == 0) ? 0 :
877 (ACS_WEIGHT_COMPUTE(
878 sap_ctx->auto_channel_select_weight,
879 softap_channel_free_weight_cfg,
880 ((rx_clear_count << 8) +
881 (cycle_count >> 1))/cycle_count -
882 (SOFTAP_MIN_CHNFREE << 8),
883 (SOFTAP_MAX_CHNFREE -
884 SOFTAP_MIN_CHNFREE) << 8));
885
886 if (channel_free_weight > softap_channel_free_weight_local)
887 channel_free_weight = softap_channel_free_weight_local;
888
889 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
890 "In %s, rcc=%d, cc=%d, tc=%d, rc=%d, cfwc=%d, cfwl=%d, cfw=%d",
891 __func__, rx_clear_count, cycle_count,
892 channel_stat->tx_frame_count,
893 channel_stat->rx_frame_count,
894 softap_channel_free_weight_cfg,
895 softap_channel_free_weight_local,
896 channel_free_weight);
897
898 return channel_free_weight;
899}
900
901/**
902 * sap_weight_channel_txpwr_range() - compute channel tx power range weight
903 * @sap_ctx: sap context
904 * @chn_stat: Pointer to chan status info
905 *
906 * Return: tx power range weight
907 */
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -0700908static uint32_t sap_weight_channel_txpwr_range(struct sap_context *sap_ctx,
gaoleze5108942017-03-31 16:56:42 +0800909 struct lim_channel_status
910 *channel_stat)
911{
912 uint32_t txpwr_weight_low_speed;
913 uint8_t softap_txpwr_range_weight_cfg;
914 uint8_t softap_txpwr_range_weight_local;
915
916 softap_txpwr_range_weight_cfg =
917 ACS_WEIGHT_SOFTAP_TX_POWER_RANGE_CFG
918 (sap_ctx->auto_channel_select_weight);
919
920 softap_txpwr_range_weight_local =
921 ACS_WEIGHT_CFG_TO_LOCAL(sap_ctx->auto_channel_select_weight,
922 softap_txpwr_range_weight_cfg);
923
Jeff Johnson4cfe6cc2019-03-18 13:40:27 -0700924 if (!channel_stat || channel_stat->channelfreq == 0) {
Srinivas Girigowda80213e52018-01-23 14:51:33 -0800925 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG,
gaoleze5108942017-03-31 16:56:42 +0800926 "In %s, sanity check failed return max weight",
927 __func__);
928 return softap_txpwr_range_weight_local;
929 }
930
931 txpwr_weight_low_speed = (channel_stat->chan_tx_pwr_range == 0) ? 0 :
932 (ACS_WEIGHT_COMPUTE(
933 sap_ctx->auto_channel_select_weight,
934 softap_txpwr_range_weight_cfg,
935 SOFTAP_MAX_TXPWR -
936 channel_stat->chan_tx_pwr_range,
937 SOFTAP_MAX_TXPWR - SOFTAP_MIN_TXPWR));
938
939 if (txpwr_weight_low_speed > softap_txpwr_range_weight_local)
940 txpwr_weight_low_speed = softap_txpwr_range_weight_local;
941
942 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
943 "In %s, tpr=%d, tprwc=%d, tprwl=%d, tprw=%d",
944 __func__, channel_stat->chan_tx_pwr_range,
945 softap_txpwr_range_weight_cfg,
946 softap_txpwr_range_weight_local,
947 txpwr_weight_low_speed);
948
949 return txpwr_weight_low_speed;
950}
951
952/**
953 * sap_weight_channel_txpwr_tput() - compute channel tx power
954 * throughput weight
955 * @sap_ctx: sap context
956 * @chn_stat: Pointer to chan status info
957 *
958 * Return: tx power throughput weight
959 */
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -0700960static uint32_t sap_weight_channel_txpwr_tput(struct sap_context *sap_ctx,
gaoleze5108942017-03-31 16:56:42 +0800961 struct lim_channel_status
962 *channel_stat)
963{
964 uint32_t txpwr_weight_high_speed;
965 uint8_t softap_txpwr_tput_weight_cfg;
966 uint8_t softap_txpwr_tput_weight_local;
967
968 softap_txpwr_tput_weight_cfg =
969 ACS_WEIGHT_SOFTAP_TX_POWER_THROUGHPUT_CFG
970 (sap_ctx->auto_channel_select_weight);
971
972 softap_txpwr_tput_weight_local =
973 ACS_WEIGHT_CFG_TO_LOCAL(sap_ctx->auto_channel_select_weight,
974 softap_txpwr_tput_weight_cfg);
975
Jeff Johnson4cfe6cc2019-03-18 13:40:27 -0700976 if (!channel_stat || channel_stat->channelfreq == 0) {
Srinivas Girigowda80213e52018-01-23 14:51:33 -0800977 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG,
gaoleze5108942017-03-31 16:56:42 +0800978 "In %s, sanity check failed return max weight",
979 __func__);
980 return softap_txpwr_tput_weight_local;
981 }
982
983 txpwr_weight_high_speed = (channel_stat->chan_tx_pwr_throughput == 0)
984 ? 0 : (ACS_WEIGHT_COMPUTE(
985 sap_ctx->auto_channel_select_weight,
986 softap_txpwr_tput_weight_cfg,
987 SOFTAP_MAX_TXPWR -
988 channel_stat->chan_tx_pwr_throughput,
989 SOFTAP_MAX_TXPWR - SOFTAP_MIN_TXPWR));
990
991 if (txpwr_weight_high_speed > softap_txpwr_tput_weight_local)
992 txpwr_weight_high_speed = softap_txpwr_tput_weight_local;
993
994 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
995 "In %s, tpt=%d, tptwc=%d, tptwl=%d, tptw=%d",
996 __func__, channel_stat->chan_tx_pwr_throughput,
997 softap_txpwr_tput_weight_cfg,
998 softap_txpwr_tput_weight_local,
999 txpwr_weight_high_speed);
1000
1001 return txpwr_weight_high_speed;
1002}
1003
1004/**
1005 * sap_weight_channel_status() - compute chan status weight
1006 * @sap_ctx: sap context
1007 * @chn_stat: Pointer to chan status info
1008 *
1009 * Return: chan status weight
1010 */
1011static
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -07001012uint32_t sap_weight_channel_status(struct sap_context *sap_ctx,
gaoleze5108942017-03-31 16:56:42 +08001013 struct lim_channel_status *channel_stat)
1014{
1015 return sap_weight_channel_noise_floor(sap_ctx, channel_stat) +
1016 sap_weight_channel_free(sap_ctx, channel_stat) +
1017 sap_weight_channel_txpwr_range(sap_ctx, channel_stat) +
1018 sap_weight_channel_txpwr_tput(sap_ctx, channel_stat);
1019}
1020
1021/**
Yeshwanth Sriram Guntuka273889e2018-02-16 17:11:46 +05301022 * sap_check_channels_same_band() - Check if two channels belong to same band
1023 * @ch_num1: channel number
1024 * @ch_num2: channel number
1025 *
1026 * Return: true if both channels belong to same band else false
1027 */
1028static bool sap_check_channels_same_band(uint16_t ch_num1, uint16_t ch_num2)
1029{
1030 if ((ch_num1 <= SIR_11B_CHANNEL_END &&
1031 ch_num2 <= SIR_11B_CHANNEL_END) ||
1032 (ch_num1 >= SIR_11A_CHANNEL_BEGIN &&
1033 ch_num2 >= SIR_11A_CHANNEL_BEGIN))
Srinivas Girigowdaeff16d92018-09-12 14:56:29 -07001034 return true;
Yeshwanth Sriram Guntuka273889e2018-02-16 17:11:46 +05301035
1036 return false;
1037}
1038
1039/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001040 * sap_update_rssi_bsscount() - updates bss count and rssi effect.
1041 *
1042 * @pSpectCh: Channel Information
1043 * @offset: Channel Offset
1044 * @sap_24g: Channel is in 2.4G or 5G
Liangwei Dong71ed6502016-10-20 03:40:45 -04001045 * @spectch_start: the start of spect ch array
1046 * @spectch_end: the end of spect ch array
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001047 *
1048 * sap_update_rssi_bsscount updates bss count and rssi effect based
1049 * on the channel offset.
1050 *
1051 * Return: None.
1052 */
1053
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001054static void sap_update_rssi_bsscount(tSapSpectChInfo *pSpectCh, int32_t offset,
Liangwei Dong71ed6502016-10-20 03:40:45 -04001055 bool sap_24g, tSapSpectChInfo *spectch_start,
1056 tSapSpectChInfo *spectch_end)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001057{
1058 tSapSpectChInfo *pExtSpectCh = NULL;
1059 int32_t rssi, rsssi_effect;
1060
1061 pExtSpectCh = (pSpectCh + offset);
Jeff Johnson4cfe6cc2019-03-18 13:40:27 -07001062 if (pExtSpectCh &&
Liangwei Dong71ed6502016-10-20 03:40:45 -04001063 pExtSpectCh >= spectch_start &&
1064 pExtSpectCh < spectch_end) {
Yeshwanth Sriram Guntuka273889e2018-02-16 17:11:46 +05301065 if (!sap_check_channels_same_band(pSpectCh->chNum,
1066 pExtSpectCh->chNum))
1067 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001068 ++pExtSpectCh->bssCount;
1069 switch (offset) {
1070 case -1:
1071 case 1:
1072 rsssi_effect = sap_24g ?
1073 SAP_24GHZ_FIRST_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY :
1074 SAP_SUBBAND1_RSSI_EFFECT_PRIMARY;
1075 break;
1076 case -2:
1077 case 2:
1078 rsssi_effect = sap_24g ?
1079 SAP_24GHZ_SEC_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY :
1080 SAP_SUBBAND2_RSSI_EFFECT_PRIMARY;
1081 break;
1082 case -3:
1083 case 3:
1084 rsssi_effect = sap_24g ?
1085 SAP_24GHZ_THIRD_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY :
1086 SAP_SUBBAND3_RSSI_EFFECT_PRIMARY;
1087 break;
1088 case -4:
1089 case 4:
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001090 rsssi_effect = sap_24g ?
1091 SAP_24GHZ_FOURTH_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY :
1092 SAP_SUBBAND4_RSSI_EFFECT_PRIMARY;
1093 break;
1094 case -5:
1095 case 5:
1096 rsssi_effect = SAP_SUBBAND5_RSSI_EFFECT_PRIMARY;
1097 break;
1098 case -6:
1099 case 6:
1100 rsssi_effect = SAP_SUBBAND6_RSSI_EFFECT_PRIMARY;
1101 break;
1102 case -7:
1103 case 7:
1104 rsssi_effect = SAP_SUBBAND7_RSSI_EFFECT_PRIMARY;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001105 break;
1106 default:
1107 rsssi_effect = 0;
1108 break;
1109 }
1110
1111 rssi = pSpectCh->rssiAgr + rsssi_effect;
1112 if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi))
1113 pExtSpectCh->rssiAgr = rssi;
1114 if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI)
1115 pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI;
1116 }
1117}
1118
1119/**
1120 * sap_upd_chan_spec_params() - sap_upd_chan_spec_params
1121 * updates channel parameters obtained from Beacon
1122 * @pBeaconStruct Beacon strucutre populated by parse_beacon function
1123 * @channelWidth Channel width
1124 * @secondaryChannelOffset Secondary Channel Offset
1125 * @vhtSupport If channel supports VHT
1126 * @centerFreq Central frequency for the given channel.
1127 *
1128 * sap_upd_chan_spec_params updates the spectrum channels based on the
1129 * pBeaconStruct obtained from Beacon IE
1130 *
1131 * Return: NA.
1132 */
1133
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001134static void sap_upd_chan_spec_params(tSirProbeRespBeacon *pBeaconStruct,
1135 uint16_t *channelWidth,
1136 uint16_t *secondaryChannelOffset,
1137 uint16_t *vhtSupport,
1138 uint16_t *centerFreq,
1139 uint16_t *centerFreq_2)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001140{
Jeff Johnson4cfe6cc2019-03-18 13:40:27 -07001141 if (!pBeaconStruct) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301142 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001143 FL("pBeaconStruct is NULL"));
1144 return;
1145 }
1146
1147 if (pBeaconStruct->HTCaps.present && pBeaconStruct->HTInfo.present) {
1148 *channelWidth = pBeaconStruct->HTCaps.supportedChannelWidthSet;
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001149 *secondaryChannelOffset =
1150 pBeaconStruct->HTInfo.secondaryChannelOffset;
1151 if (!pBeaconStruct->VHTOperation.present)
1152 return;
1153 *vhtSupport = pBeaconStruct->VHTOperation.present;
1154 if (pBeaconStruct->VHTOperation.chanWidth) {
1155 *centerFreq =
1156 pBeaconStruct->VHTOperation.chanCenterFreqSeg1;
1157 *centerFreq_2 =
1158 pBeaconStruct->VHTOperation.chanCenterFreqSeg2;
1159 /*
1160 * LHS follows tSirMacHTChannelWidth, while RHS follows
1161 * WNI_CFG_VHT_CHANNEL_WIDTH_X format hence following
1162 * adjustment
1163 */
1164 *channelWidth =
1165 pBeaconStruct->VHTOperation.chanWidth + 1;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001166
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001167 }
1168 }
1169}
1170
1171/**
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001172 * sap_update_rssi_bsscount_vht_5G() - updates bss count and rssi effect.
1173 *
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001174 * @spect_ch: Channel Information
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001175 * @offset: Channel Offset
1176 * @num_ch: no.of channels
Liangwei Dong71ed6502016-10-20 03:40:45 -04001177 * @spectch_start: the start of spect ch array
1178 * @spectch_end: the end of spect ch array
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001179 *
1180 * sap_update_rssi_bsscount_vht_5G updates bss count and rssi effect based
1181 * on the channel offset.
1182 *
1183 * Return: None.
1184 */
1185
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001186static void sap_update_rssi_bsscount_vht_5G(tSapSpectChInfo *spect_ch,
1187 int32_t offset,
Liangwei Dong71ed6502016-10-20 03:40:45 -04001188 uint16_t num_ch,
1189 tSapSpectChInfo *spectch_start,
1190 tSapSpectChInfo *spectch_end)
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001191{
1192 int32_t ch_offset;
1193 uint16_t i, cnt;
1194
1195 if (!offset)
1196 return;
1197 if (offset > 0)
1198 cnt = num_ch;
1199 else
1200 cnt = num_ch + 1;
1201 for (i = 0; i < cnt; i++) {
1202 ch_offset = offset + i;
1203 if (ch_offset == 0)
1204 continue;
Liangwei Dong71ed6502016-10-20 03:40:45 -04001205 sap_update_rssi_bsscount(spect_ch, ch_offset, false,
1206 spectch_start, spectch_end);
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001207 }
1208}
1209/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001210 * sap_interference_rssi_count_5G() - sap_interference_rssi_count
1211 * considers the Adjacent channel rssi and
1212 * data count(here number of BSS observed)
1213 * @spect_ch: Channel Information
1214 * @chan_width: Channel width parsed from beacon IE
1215 * @sec_chan_offset: Secondary Channel Offset
1216 * @center_freq: Central frequency for the given channel.
1217 * @channel_id: channel_id
Liangwei Dong71ed6502016-10-20 03:40:45 -04001218 * @spectch_start: the start of spect ch array
1219 * @spectch_end: the end of spect ch array
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001220 *
1221 * sap_interference_rssi_count_5G considers the Adjacent channel rssi
1222 * and data count(here number of BSS observed)
1223 *
1224 * Return: NA.
1225 */
1226
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001227static void sap_interference_rssi_count_5G(tSapSpectChInfo *spect_ch,
1228 uint16_t chan_width,
1229 uint16_t sec_chan_offset,
1230 uint16_t center_freq,
1231 uint16_t center_freq_2,
Liangwei Dong71ed6502016-10-20 03:40:45 -04001232 uint8_t channel_id,
1233 tSapSpectChInfo *spectch_start,
1234 tSapSpectChInfo *spectch_end)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001235{
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001236 uint16_t num_ch;
1237 int32_t offset = 0;
Srinivas Girigowda4d65ebe2017-10-13 21:41:42 -07001238
Jeff Johnson4cfe6cc2019-03-18 13:40:27 -07001239 if (!spect_ch) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301240 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001241 FL("spect_ch is NULL"));
1242 return;
1243 }
1244
1245 /* Updating the received ChannelWidth */
1246 if (spect_ch->channelWidth != chan_width)
1247 spect_ch->channelWidth = chan_width;
1248 /* If received ChannelWidth is other than HT20,
1249 * we need to update the extension channel Params as well
1250 * chan_width == 0, HT20
1251 * chan_width == 1, HT40
1252 * chan_width == 2, VHT80
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001253 * chan_width == 3, VHT160
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001254 */
1255
1256 switch (spect_ch->channelWidth) {
1257 case eHT_CHANNEL_WIDTH_40MHZ: /* HT40 */
1258 switch (sec_chan_offset) {
1259 /* Above the Primary Channel */
1260 case PHY_DOUBLE_CHANNEL_LOW_PRIMARY:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001261 sap_update_rssi_bsscount(spect_ch, 1, false,
1262 spectch_start, spectch_end);
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001263 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001264
1265 /* Below the Primary channel */
1266 case PHY_DOUBLE_CHANNEL_HIGH_PRIMARY:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001267 sap_update_rssi_bsscount(spect_ch, -1, false,
1268 spectch_start, spectch_end);
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001269 return;
1270 }
1271 return;
1272 case eHT_CHANNEL_WIDTH_80MHZ: /* VHT80 */
1273 num_ch = 3;
1274 if ((center_freq - channel_id) == 6) {
1275 offset = 1;
1276 } else if ((center_freq - channel_id) == 2) {
1277 offset = -1;
1278 } else if ((center_freq - channel_id) == -2) {
1279 offset = -2;
1280 } else if ((center_freq - channel_id) == -6) {
1281 offset = -3;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001282 }
1283 break;
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001284 case eHT_CHANNEL_WIDTH_160MHZ: /* VHT160 */
1285 num_ch = 7;
1286 if ((center_freq - channel_id) == 14)
1287 offset = 1;
1288 else if ((center_freq - channel_id) == 10)
1289 offset = -1;
1290 else if ((center_freq - channel_id) == 6)
1291 offset = -2;
1292 else if ((center_freq - channel_id) == 2)
1293 offset = -3;
1294 else if ((center_freq - channel_id) == -2)
1295 offset = -4;
1296 else if ((center_freq - channel_id) == -6)
1297 offset = -5;
1298 else if ((center_freq - channel_id) == -10)
1299 offset = -6;
1300 else if ((center_freq - channel_id) == -14)
1301 offset = -7;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001302 break;
1303 default:
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001304 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001305 }
Liangwei Dong71ed6502016-10-20 03:40:45 -04001306 sap_update_rssi_bsscount_vht_5G(spect_ch, offset, num_ch,
1307 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001308}
1309
1310/**
1311 * sap_interference_rssi_count() - sap_interference_rssi_count
1312 * considers the Adjacent channel rssi
1313 * and data count(here number of BSS observed)
1314 * @spect_ch Channel Information
Liangwei Dong71ed6502016-10-20 03:40:45 -04001315 * @spectch_start: the start of spect ch array
1316 * @spectch_end: the end of spect ch array
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001317 *
1318 * sap_interference_rssi_count considers the Adjacent channel rssi
1319 * and data count(here number of BSS observed)
1320 *
1321 * Return: None.
1322 */
1323
Liangwei Dong71ed6502016-10-20 03:40:45 -04001324static void sap_interference_rssi_count(tSapSpectChInfo *spect_ch,
1325 tSapSpectChInfo *spectch_start,
1326 tSapSpectChInfo *spectch_end)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001327{
Jeff Johnson4cfe6cc2019-03-18 13:40:27 -07001328 if (!spect_ch) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301329 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001330 "%s: spect_ch is NULL", __func__);
1331 return;
1332 }
1333
1334 switch (spect_ch->chNum) {
1335 case CHANNEL_1:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001336 sap_update_rssi_bsscount(spect_ch, 1, true,
1337 spectch_start, spectch_end);
1338 sap_update_rssi_bsscount(spect_ch, 2, true,
1339 spectch_start, spectch_end);
1340 sap_update_rssi_bsscount(spect_ch, 3, true,
1341 spectch_start, spectch_end);
1342 sap_update_rssi_bsscount(spect_ch, 4, true,
1343 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001344 break;
1345
1346 case CHANNEL_2:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001347 sap_update_rssi_bsscount(spect_ch, -1, true,
1348 spectch_start, spectch_end);
1349 sap_update_rssi_bsscount(spect_ch, 1, true,
1350 spectch_start, spectch_end);
1351 sap_update_rssi_bsscount(spect_ch, 2, true,
1352 spectch_start, spectch_end);
1353 sap_update_rssi_bsscount(spect_ch, 3, true,
1354 spectch_start, spectch_end);
1355 sap_update_rssi_bsscount(spect_ch, 4, true,
1356 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001357 break;
1358 case CHANNEL_3:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001359 sap_update_rssi_bsscount(spect_ch, -2, true,
1360 spectch_start, spectch_end);
1361 sap_update_rssi_bsscount(spect_ch, -1, true,
1362 spectch_start, spectch_end);
1363 sap_update_rssi_bsscount(spect_ch, 1, true,
1364 spectch_start, spectch_end);
1365 sap_update_rssi_bsscount(spect_ch, 2, true,
1366 spectch_start, spectch_end);
1367 sap_update_rssi_bsscount(spect_ch, 3, true,
1368 spectch_start, spectch_end);
1369 sap_update_rssi_bsscount(spect_ch, 4, true,
1370 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001371 break;
1372 case CHANNEL_4:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001373 sap_update_rssi_bsscount(spect_ch, -3, true,
1374 spectch_start, spectch_end);
1375 sap_update_rssi_bsscount(spect_ch, -2, true,
1376 spectch_start, spectch_end);
1377 sap_update_rssi_bsscount(spect_ch, -1, true,
1378 spectch_start, spectch_end);
1379 sap_update_rssi_bsscount(spect_ch, 1, true,
1380 spectch_start, spectch_end);
1381 sap_update_rssi_bsscount(spect_ch, 2, true,
1382 spectch_start, spectch_end);
1383 sap_update_rssi_bsscount(spect_ch, 3, true,
1384 spectch_start, spectch_end);
1385 sap_update_rssi_bsscount(spect_ch, 4, true,
1386 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001387 break;
1388
1389 case CHANNEL_5:
1390 case CHANNEL_6:
1391 case CHANNEL_7:
1392 case CHANNEL_8:
1393 case CHANNEL_9:
1394 case CHANNEL_10:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001395 sap_update_rssi_bsscount(spect_ch, -4, true,
1396 spectch_start, spectch_end);
1397 sap_update_rssi_bsscount(spect_ch, -3, true,
1398 spectch_start, spectch_end);
1399 sap_update_rssi_bsscount(spect_ch, -2, true,
1400 spectch_start, spectch_end);
1401 sap_update_rssi_bsscount(spect_ch, -1, true,
1402 spectch_start, spectch_end);
1403 sap_update_rssi_bsscount(spect_ch, 1, true,
1404 spectch_start, spectch_end);
1405 sap_update_rssi_bsscount(spect_ch, 2, true,
1406 spectch_start, spectch_end);
1407 sap_update_rssi_bsscount(spect_ch, 3, true,
1408 spectch_start, spectch_end);
1409 sap_update_rssi_bsscount(spect_ch, 4, true,
1410 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001411 break;
1412
1413 case CHANNEL_11:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001414 sap_update_rssi_bsscount(spect_ch, -4, true,
1415 spectch_start, spectch_end);
1416 sap_update_rssi_bsscount(spect_ch, -3, true,
1417 spectch_start, spectch_end);
1418 sap_update_rssi_bsscount(spect_ch, -2, true,
1419 spectch_start, spectch_end);
1420 sap_update_rssi_bsscount(spect_ch, -1, true,
1421 spectch_start, spectch_end);
1422 sap_update_rssi_bsscount(spect_ch, 1, true,
1423 spectch_start, spectch_end);
1424 sap_update_rssi_bsscount(spect_ch, 2, true,
1425 spectch_start, spectch_end);
1426 sap_update_rssi_bsscount(spect_ch, 3, true,
1427 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001428 break;
1429
1430 case CHANNEL_12:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001431 sap_update_rssi_bsscount(spect_ch, -4, true,
1432 spectch_start, spectch_end);
1433 sap_update_rssi_bsscount(spect_ch, -3, true,
1434 spectch_start, spectch_end);
1435 sap_update_rssi_bsscount(spect_ch, -2, true,
1436 spectch_start, spectch_end);
1437 sap_update_rssi_bsscount(spect_ch, -1, true,
1438 spectch_start, spectch_end);
1439 sap_update_rssi_bsscount(spect_ch, 1, true,
1440 spectch_start, spectch_end);
1441 sap_update_rssi_bsscount(spect_ch, 2, true,
1442 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001443 break;
1444
1445 case CHANNEL_13:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001446 sap_update_rssi_bsscount(spect_ch, -4, true,
1447 spectch_start, spectch_end);
1448 sap_update_rssi_bsscount(spect_ch, -3, true,
1449 spectch_start, spectch_end);
1450 sap_update_rssi_bsscount(spect_ch, -2, true,
1451 spectch_start, spectch_end);
1452 sap_update_rssi_bsscount(spect_ch, -1, true,
1453 spectch_start, spectch_end);
1454 sap_update_rssi_bsscount(spect_ch, 1, true,
1455 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001456 break;
1457
1458 case CHANNEL_14:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001459 sap_update_rssi_bsscount(spect_ch, -4, true,
1460 spectch_start, spectch_end);
1461 sap_update_rssi_bsscount(spect_ch, -3, true,
1462 spectch_start, spectch_end);
1463 sap_update_rssi_bsscount(spect_ch, -2, true,
1464 spectch_start, spectch_end);
1465 sap_update_rssi_bsscount(spect_ch, -1, true,
1466 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001467 break;
1468
1469 default:
1470 break;
1471 }
1472}
1473
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001474/**
1475 * ch_in_pcl() - Is channel in the Preferred Channel List (PCL)
1476 * @sap_ctx: SAP context which contains the current PCL
1477 * @channel: Input channel number to be checked
1478 *
1479 * Check if a channel is in the preferred channel list
1480 *
1481 * Return:
1482 * true: channel is in PCL,
1483 * false: channel is not in PCL
1484 */
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -07001485static bool ch_in_pcl(struct sap_context *sap_ctx, uint8_t channel)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001486{
1487 uint32_t i;
1488
1489 for (i = 0; i < sap_ctx->acs_cfg->pcl_ch_count; i++) {
1490 if (channel == sap_ctx->acs_cfg->pcl_channels[i])
1491 return true;
1492 }
1493
1494 return false;
1495}
1496
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001497/**
1498 * sap_compute_spect_weight() - Compute spectrum weight
1499 * @pSpectInfoParams: Pointer to the tSpectInfoParams structure
Jeff Johnson7730fbb2018-11-08 13:48:27 -08001500 * @mac_handle: Opaque handle to the global MAC context
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001501 * @pResult: Pointer to tScanResultHandle
1502 * @sap_ctx: Context of the SAP
1503 *
1504 * Main function for computing the weight of each channel in the
1505 * spectrum based on the RSSI value of the BSSes on the channel
1506 * and number of BSS
1507 */
1508static void sap_compute_spect_weight(tSapChSelSpectInfo *pSpectInfoParams,
Jeff Johnson7730fbb2018-11-08 13:48:27 -08001509 mac_handle_t mac_handle,
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001510 tScanResultHandle pResult,
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -07001511 struct sap_context *sap_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001512{
1513 int8_t rssi = 0;
1514 uint8_t chn_num = 0;
1515 uint8_t channel_id = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001516 tCsrScanResultInfo *pScanResult;
1517 tSapSpectChInfo *pSpectCh = pSpectInfoParams->pSpectCh;
1518 uint32_t operatingBand;
1519 uint16_t channelWidth;
1520 uint16_t secondaryChannelOffset;
1521 uint16_t centerFreq;
gaurank kathpalia859c9362018-08-02 23:07:21 +05301522 uint8_t i;
1523 bool found;
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001524 uint16_t centerFreq_2 = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001525 uint16_t vhtSupport;
1526 uint32_t ieLen = 0;
1527 tSirProbeRespBeacon *pBeaconStruct;
Jeff Johnsonc59ef8b2018-12-02 12:01:21 -08001528 struct mac_context *mac = MAC_CONTEXT(mac_handle);
Liangwei Dong71ed6502016-10-20 03:40:45 -04001529 tSapSpectChInfo *spectch_start = pSpectInfoParams->pSpectCh;
1530 tSapSpectChInfo *spectch_end = pSpectInfoParams->pSpectCh +
1531 pSpectInfoParams->numSpectChans;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001532
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301533 pBeaconStruct = qdf_mem_malloc(sizeof(tSirProbeRespBeacon));
Arif Hussain256cc282018-10-03 14:10:44 -07001534 if (!pBeaconStruct)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001535 return;
Arif Hussain256cc282018-10-03 14:10:44 -07001536
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301537 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001538 "In %s, Computing spectral weight", __func__);
1539
1540 /**
1541 * Soft AP specific channel weight calculation using DFS formula
1542 */
1543 SET_ACS_BAND(operatingBand, sap_ctx);
1544
Jeff Johnson7730fbb2018-11-08 13:48:27 -08001545 pScanResult = sme_scan_result_get_first(mac_handle, pResult);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001546
1547 while (pScanResult) {
1548 pSpectCh = pSpectInfoParams->pSpectCh;
1549 /* Defining the default values, so that any value will hold the default values */
1550 channelWidth = eHT_CHANNEL_WIDTH_20MHZ;
1551 secondaryChannelOffset = PHY_SINGLE_CHANNEL_CENTERED;
1552 vhtSupport = 0;
1553 centerFreq = 0;
1554
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001555
Yingying Tang22facc12016-10-20 17:43:59 +08001556 ieLen = GET_IE_LEN_IN_BSS(
1557 pScanResult->BssDescriptor.length);
hangtian127c9532019-01-12 13:29:07 +08001558 qdf_mem_zero((uint8_t *) pBeaconStruct,
1559 sizeof(tSirProbeRespBeacon));
Yingying Tang22facc12016-10-20 17:43:59 +08001560
1561
1562 if ((sir_parse_beacon_ie
Jeff Johnsonb9794442018-11-22 14:21:08 -08001563 (mac, pBeaconStruct, (uint8_t *)
Yingying Tang22facc12016-10-20 17:43:59 +08001564 (pScanResult->BssDescriptor.ieFields),
Jeff Johnson83e30fa2018-06-07 23:01:11 -07001565 ieLen)) == QDF_STATUS_SUCCESS)
Yingying Tang22facc12016-10-20 17:43:59 +08001566 sap_upd_chan_spec_params(
1567 pBeaconStruct,
1568 &channelWidth,
1569 &secondaryChannelOffset,
1570 &vhtSupport, &centerFreq,
1571 &centerFreq_2);
1572
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001573 /* Processing for each tCsrScanResultInfo in the tCsrScanResult DLink list */
1574 for (chn_num = 0; chn_num < pSpectInfoParams->numSpectChans;
1575 chn_num++) {
1576
1577 /*
Himanshu Agarwalcf5b8932018-07-02 18:06:49 +05301578 * If the Beacon has channel ID, use it other wise we
1579 * will rely on the channelIdSelf
1580 */
1581 if (pScanResult->BssDescriptor.channelId == 0)
1582 channel_id =
1583 pScanResult->BssDescriptor.channelIdSelf;
1584 else
1585 channel_id =
1586 pScanResult->BssDescriptor.channelId;
1587
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001588 if (pSpectCh && (channel_id == pSpectCh->chNum)) {
1589 if (pSpectCh->rssiAgr <
1590 pScanResult->BssDescriptor.rssi)
1591 pSpectCh->rssiAgr =
1592 pScanResult->BssDescriptor.rssi;
1593
1594 ++pSpectCh->bssCount; /* Increment the count of BSS */
1595
1596 /*
1597 * Connsidering the Extension Channel
1598 * only in a channels
1599 */
1600 switch (operatingBand) {
1601 case eCSR_DOT11_MODE_11a:
1602 sap_interference_rssi_count_5G(
1603 pSpectCh, channelWidth,
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001604 secondaryChannelOffset,
1605 centerFreq,
1606 centerFreq_2,
Liangwei Dong71ed6502016-10-20 03:40:45 -04001607 channel_id,
1608 spectch_start,
1609 spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001610 break;
1611
1612 case eCSR_DOT11_MODE_11g:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001613 sap_interference_rssi_count(pSpectCh,
1614 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001615 break;
1616
1617 case eCSR_DOT11_MODE_abg:
Himanshu Agarwal4f503b82018-03-19 12:10:45 +05301618 if (pSpectCh->chNum >=
1619 SIR_11A_CHANNEL_BEGIN)
1620 sap_interference_rssi_count_5G(
1621 pSpectCh, channelWidth,
1622 secondaryChannelOffset,
1623 centerFreq,
1624 centerFreq_2,
1625 channel_id,
1626 spectch_start,
1627 spectch_end);
1628 else
1629 sap_interference_rssi_count(
1630 pSpectCh,
1631 spectch_start,
1632 spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001633 break;
1634 }
1635
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301636 QDF_TRACE(QDF_MODULE_ID_SAP,
1637 QDF_TRACE_LEVEL_INFO_HIGH,
Jeff Johnsona7c0ddb2017-09-18 08:14:12 -07001638 "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 -08001639 __func__,
1640 pScanResult->BssDescriptor.
1641 channelIdSelf,
1642 pScanResult->BssDescriptor.channelId,
1643 pScanResult->BssDescriptor.rssi,
1644 pSpectCh->bssCount, pScanResult,
1645 pSpectCh->channelWidth,
1646 secondaryChannelOffset, centerFreq);
1647 pSpectCh++;
1648 break;
1649 } else {
1650 pSpectCh++;
1651 }
1652 }
1653
Jeff Johnson7730fbb2018-11-08 13:48:27 -08001654 pScanResult = sme_scan_result_get_next(mac_handle, pResult);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001655 }
1656
1657 /* Calculate the weights for all channels in the spectrum pSpectCh */
1658 pSpectCh = pSpectInfoParams->pSpectCh;
1659
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301660 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001661 "In %s, Spectrum Channels Weight", __func__);
1662
1663 for (chn_num = 0; chn_num < (pSpectInfoParams->numSpectChans);
1664 chn_num++) {
1665
1666 /*
1667 rssi : Maximum received signal strength among all BSS on that channel
1668 bssCount : Number of BSS on that channel
1669 */
1670
1671 rssi = (int8_t) pSpectCh->rssiAgr;
Himanshu Agarwal3697f942018-06-13 14:04:26 +05301672 if (ch_in_pcl(sap_ctx, pSpectCh->chNum))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001673 rssi -= PCL_RSSI_DISCOUNT;
1674
Himanshu Agarwal3697f942018-06-13 14:04:26 +05301675 if (rssi < SOFTAP_MIN_RSSI)
1676 rssi = SOFTAP_MIN_RSSI;
1677
hqub6441f22018-08-09 16:15:31 +08001678 if (pSpectCh->weight == SAP_ACS_WEIGHT_MAX) {
1679 pSpectCh->weight_copy = pSpectCh->weight;
Himanshu Agarwalfee2e362018-01-18 20:26:35 +05301680 goto debug_info;
hqub6441f22018-08-09 16:15:31 +08001681 }
Himanshu Agarwalfee2e362018-01-18 20:26:35 +05301682
gaurank kathpalia859c9362018-08-02 23:07:21 +05301683 /* There may be channels in scanlist, which were not sent to
1684 * FW for scanning as part of ACS scan list, but they do have an
1685 * effect on the neighbouring channels, so they help to find a
1686 * suitable channel, but there weight should be max as they were
1687 * and not meant to be included in the ACS scan results.
1688 * So just assign RSSI as -100, bsscount as 0, and weight as max
1689 * to them, so that they always stay low in sorting of best
1690 * channles which were included in ACS scan list
1691 */
1692 found = false;
1693 for (i = 0; i < sap_ctx->num_of_channel; i++) {
1694 if (pSpectCh->chNum == sap_ctx->channelList[i]) {
1695 /* Scan channel was included in ACS scan list */
1696 found = true;
1697 break;
1698 }
1699 }
1700
1701 if (found)
1702 pSpectCh->weight =
1703 SAPDFS_NORMALISE_1000 *
1704 (sapweight_rssi_count(sap_ctx, rssi,
1705 pSpectCh->bssCount) + sap_weight_channel_status(
Jeff Johnsonb9794442018-11-22 14:21:08 -08001706 sap_ctx, sap_get_channel_status(mac,
gaoleze5108942017-03-31 16:56:42 +08001707 pSpectCh->chNum)));
gaurank kathpalia859c9362018-08-02 23:07:21 +05301708 else {
1709 pSpectCh->weight = SAP_ACS_WEIGHT_MAX;
1710 pSpectCh->rssiAgr = SOFTAP_MIN_RSSI;
1711 rssi = SOFTAP_MIN_RSSI;
1712 pSpectCh->bssCount = SOFTAP_MIN_COUNT;
1713 }
1714
gaoleze5108942017-03-31 16:56:42 +08001715 if (pSpectCh->weight > SAP_ACS_WEIGHT_MAX)
1716 pSpectCh->weight = SAP_ACS_WEIGHT_MAX;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001717 pSpectCh->weight_copy = pSpectCh->weight;
1718
Himanshu Agarwalfee2e362018-01-18 20:26:35 +05301719debug_info:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001720 /* ------ Debug Info ------ */
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301721 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Himanshu Agarwal3697f942018-06-13 14:04:26 +05301722 "In %s, Chan=%d Weight= %d rssiAgr=%d rssi_pcl_discount: %d bssCount=%d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001723 __func__, pSpectCh->chNum, pSpectCh->weight,
Himanshu Agarwal3697f942018-06-13 14:04:26 +05301724 pSpectCh->rssiAgr, rssi, pSpectCh->bssCount);
wadesongcb0ded22018-02-02 17:57:20 +08001725 host_log_acs_chan_spect_weight(pSpectCh->chNum,
1726 (uint16_t)pSpectCh->weight,
1727 pSpectCh->rssiAgr,
1728 pSpectCh->bssCount);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001729 /* ------ Debug Info ------ */
1730 pSpectCh++;
1731 }
Jeff Johnsonb9794442018-11-22 14:21:08 -08001732 sap_clear_channel_status(mac);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301733 qdf_mem_free(pBeaconStruct);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001734}
1735
1736/*==========================================================================
1737 FUNCTION sap_chan_sel_exit
1738
1739 DESCRIPTION
1740 Exit function for free out the allocated memory, to be called
1741 at the end of the dfsSelectChannel function
1742
1743 DEPENDENCIES
1744 NA.
1745
1746 PARAMETERS
1747
1748 IN
1749 pSpectInfoParams : Pointer to the tSapChSelSpectInfo structure
1750
1751 RETURN VALUE
1752 void : NULL
1753
1754 SIDE EFFECTS
1755 ============================================================================*/
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001756static void sap_chan_sel_exit(tSapChSelSpectInfo *pSpectInfoParams)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001757{
1758 /* Free all the allocated memory */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301759 qdf_mem_free(pSpectInfoParams->pSpectCh);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001760}
1761
1762/*==========================================================================
1763 FUNCTION sap_sort_chl_weight
1764
1765 DESCRIPTION
Jeff Johnsonc7e4d162018-05-12 16:20:34 -07001766 Function to sort the channels with the least weight first for 20MHz channels
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001767
1768 DEPENDENCIES
1769 NA.
1770
1771 PARAMETERS
1772
1773 IN
1774 pSpectInfoParams : Pointer to the tSapChSelSpectInfo structure
1775
1776 RETURN VALUE
1777 void : NULL
1778
1779 SIDE EFFECTS
1780 ============================================================================*/
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001781static void sap_sort_chl_weight(tSapChSelSpectInfo *pSpectInfoParams)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001782{
1783 tSapSpectChInfo temp;
1784
1785 tSapSpectChInfo *pSpectCh = NULL;
1786 uint32_t i = 0, j = 0, minWeightIndex = 0;
1787
1788 pSpectCh = pSpectInfoParams->pSpectCh;
1789 for (i = 0; i < pSpectInfoParams->numSpectChans; i++) {
1790 minWeightIndex = i;
1791 for (j = i + 1; j < pSpectInfoParams->numSpectChans; j++) {
1792 if (pSpectCh[j].weight <
1793 pSpectCh[minWeightIndex].weight) {
1794 minWeightIndex = j;
Yeshwanth Sriram Guntuka273889e2018-02-16 17:11:46 +05301795 } else if (pSpectCh[j].weight ==
1796 pSpectCh[minWeightIndex].weight) {
1797 if (pSpectCh[j].bssCount <
1798 pSpectCh[minWeightIndex].bssCount)
1799 minWeightIndex = j;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001800 }
1801 }
1802 if (minWeightIndex != i) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301803 qdf_mem_copy(&temp, &pSpectCh[minWeightIndex],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001804 sizeof(*pSpectCh));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301805 qdf_mem_copy(&pSpectCh[minWeightIndex], &pSpectCh[i],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001806 sizeof(*pSpectCh));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301807 qdf_mem_copy(&pSpectCh[i], &temp, sizeof(*pSpectCh));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001808 }
1809 }
1810}
1811
1812/**
Jeff Johnsonc7e4d162018-05-12 16:20:34 -07001813 * set_ht80_chl_bit() - to set available channel to ht80 channel bitmap
bingse2782382017-03-23 10:34:52 +08001814 * @channel_bitmap: Pointer to the chan_bonding_bitmap structure
1815 * @spect_info_params: Pointer to the tSapChSelSpectInfo structure
1816 *
1817 * Return: none
1818 */
1819static void set_ht80_chl_bit(chan_bonding_bitmap *channel_bitmap,
1820 tSapChSelSpectInfo *spec_info_params)
1821{
1822 uint8_t i, j;
1823 tSapSpectChInfo *spec_info;
1824 int start_channel = 0;
1825
1826 channel_bitmap->chanBondingSet[0].startChannel =
1827 acs_ht80_channels[0].chStartNum;
1828 channel_bitmap->chanBondingSet[1].startChannel =
1829 acs_ht80_channels[1].chStartNum;
1830 channel_bitmap->chanBondingSet[2].startChannel =
1831 acs_ht80_channels[2].chStartNum;
1832 channel_bitmap->chanBondingSet[3].startChannel =
1833 acs_ht80_channels[3].chStartNum;
1834 channel_bitmap->chanBondingSet[4].startChannel =
1835 acs_ht80_channels[4].chStartNum;
1836 channel_bitmap->chanBondingSet[5].startChannel =
1837 acs_ht80_channels[5].chStartNum;
1838
1839 spec_info = spec_info_params->pSpectCh;
1840 for (j = 0; j < spec_info_params->numSpectChans; j++) {
1841 for (i = 0; i < MAX_80MHZ_BANDS; i++) {
1842 start_channel =
1843 channel_bitmap->chanBondingSet[i].startChannel;
1844 if (spec_info[j].chNum >= start_channel &&
1845 (spec_info[j].chNum <= start_channel + 12)) {
1846 channel_bitmap->chanBondingSet[i].channelMap |=
1847 1 << ((spec_info[j].chNum -
1848 start_channel)/4);
1849 break;
1850 }
1851 }
1852 }
1853}
1854
1855/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001856 * sap_sort_chl_weight_ht80() - to sort the channels with the least weight
1857 * @pSpectInfoParams: Pointer to the tSapChSelSpectInfo structure
1858 *
Jeff Johnsonc7e4d162018-05-12 16:20:34 -07001859 * Function to sort the channels with the least weight first for HT80 channels
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001860 *
1861 * Return: none
1862 */
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001863static void sap_sort_chl_weight_ht80(tSapChSelSpectInfo *pSpectInfoParams)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001864{
1865 uint8_t i, j, n;
1866 tSapSpectChInfo *pSpectInfo;
1867 uint8_t minIdx;
bingse2782382017-03-23 10:34:52 +08001868 int start_channel = 0;
1869 chan_bonding_bitmap *channel_bitmap;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001870
bingse2782382017-03-23 10:34:52 +08001871 channel_bitmap = qdf_mem_malloc(sizeof(chan_bonding_bitmap));
Arif Hussain256cc282018-10-03 14:10:44 -07001872 if (!channel_bitmap)
bingse2782382017-03-23 10:34:52 +08001873 return;
Arif Hussain256cc282018-10-03 14:10:44 -07001874
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001875 pSpectInfo = pSpectInfoParams->pSpectCh;
1876 /* for each HT80 channel, calculate the combined weight of the
1877 four 20MHz weight */
1878 for (i = 0; i < ARRAY_SIZE(acs_ht80_channels); i++) {
1879 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
1880 if (pSpectInfo[j].chNum ==
1881 acs_ht80_channels[i].chStartNum)
1882 break;
1883 }
1884 if (j == pSpectInfoParams->numSpectChans)
1885 continue;
1886
1887 if (!(((pSpectInfo[j].chNum + 4) == pSpectInfo[j + 1].chNum) &&
1888 ((pSpectInfo[j].chNum + 8) ==
1889 pSpectInfo[j + 2].chNum) &&
1890 ((pSpectInfo[j].chNum + 12) ==
1891 pSpectInfo[j + 3].chNum))) {
1892 /*
1893 * some channels does not exist in pSectInfo array,
1894 * skip this channel and those in the same HT80 width
1895 */
1896 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 4;
1897 if ((pSpectInfo[j].chNum + 4) ==
1898 pSpectInfo[j + 1].chNum)
1899 pSpectInfo[j + 1].weight =
1900 SAP_ACS_WEIGHT_MAX * 4;
1901 if ((pSpectInfo[j].chNum + 8) ==
1902 pSpectInfo[j + 2].chNum)
1903 pSpectInfo[j + 2].weight =
1904 SAP_ACS_WEIGHT_MAX * 4;
1905 if ((pSpectInfo[j].chNum + 12) ==
1906 pSpectInfo[j + 3].chNum)
1907 pSpectInfo[j + 3].weight =
1908 SAP_ACS_WEIGHT_MAX * 4;
1909 continue;
1910 }
1911 /*found the channel, add the 4 adjacent channels' weight */
1912 acs_ht80_channels[i].weight = pSpectInfo[j].weight +
1913 pSpectInfo[j + 1].weight + pSpectInfo[j + 2].weight +
1914 pSpectInfo[j + 3].weight;
1915 /* find best channel among 4 channels as the primary channel */
1916 if ((pSpectInfo[j].weight + pSpectInfo[j + 1].weight) <
1917 (pSpectInfo[j + 2].weight + pSpectInfo[j + 3].weight)) {
1918 /* lower 2 channels are better choice */
1919 if (pSpectInfo[j].weight < pSpectInfo[j + 1].weight)
1920 minIdx = 0;
1921 else
1922 minIdx = 1;
1923 } else if (pSpectInfo[j + 2].weight <=
1924 pSpectInfo[j + 3].weight) {
1925 /* upper 2 channels are better choice */
1926 minIdx = 2;
1927 } else {
1928 minIdx = 3;
1929 }
1930
1931 /*
1932 * set all 4 channels to max value first, then reset the
1933 * best channel as the selected primary channel, update its
1934 * weightage with the combined weight value
1935 */
1936 for (n = 0; n < 4; n++)
1937 pSpectInfo[j + n].weight = SAP_ACS_WEIGHT_MAX * 4;
1938
1939 pSpectInfo[j + minIdx].weight = acs_ht80_channels[i].weight;
1940 }
1941
bingse2782382017-03-23 10:34:52 +08001942 /*
1943 * mark the weight of the channel that can't satisfy 80MHZ
1944 * as max value, so that it will be sorted to the bottom
1945 */
1946 set_ht80_chl_bit(channel_bitmap, pSpectInfoParams);
1947 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
1948 for (i = 0; i < MAX_80MHZ_BANDS; i++) {
1949 start_channel =
1950 channel_bitmap->chanBondingSet[i].startChannel;
1951 if (pSpectInfo[j].chNum >= start_channel &&
1952 (pSpectInfo[j].chNum <=
1953 start_channel + 12) &&
1954 channel_bitmap->chanBondingSet[i].channelMap !=
1955 SAP_80MHZ_MASK)
1956 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 4;
1957 }
1958 }
1959
Himanshu Agarwal75e74412018-02-01 20:51:47 +05301960 /*
1961 * Assign max weight(SAP_ACS_WEIGHT_MAX * 4) to 2.4 Ghz channels
1962 * and channel 165 as they cannot be part of a 80Mhz channel bonding.
1963 */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001964 pSpectInfo = pSpectInfoParams->pSpectCh;
1965 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
Himanshu Agarwal75e74412018-02-01 20:51:47 +05301966 if ((pSpectInfo[j].chNum >= WLAN_REG_CH_NUM(CHAN_ENUM_1) &&
1967 pSpectInfo[j].chNum <= WLAN_REG_CH_NUM(CHAN_ENUM_14)) ||
gaurank kathpalia1dea75b2019-01-10 13:53:43 +05301968 (pSpectInfo[j].chNum >= CHANNEL_165))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001969 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 4;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001970 }
1971
Manishekar Chandrasekaran44e334f2016-05-30 16:42:50 +05301972 sap_sort_chl_weight(pSpectInfoParams);
1973
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001974 pSpectInfo = pSpectInfoParams->pSpectCh;
1975 for (j = 0; j < (pSpectInfoParams->numSpectChans); j++) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301976 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001977 FL("Channel=%d Weight= %d rssi=%d bssCount=%d"),
1978 pSpectInfo->chNum, pSpectInfo->weight,
1979 pSpectInfo->rssiAgr, pSpectInfo->bssCount);
1980 pSpectInfo++;
1981 }
bingse2782382017-03-23 10:34:52 +08001982 qdf_mem_free(channel_bitmap);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001983}
1984
1985/**
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001986 * sap_sort_chl_weight_vht160() - to sort the channels with the least weight
1987 * @pSpectInfoParams: Pointer to the tSapChSelSpectInfo structure
1988 *
Jeff Johnsonc7e4d162018-05-12 16:20:34 -07001989 * Function to sort the channels with the least weight first for VHT160 channels
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001990 *
1991 * Return: none
1992 */
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001993static void sap_sort_chl_weight_vht160(tSapChSelSpectInfo *pSpectInfoParams)
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001994{
1995 uint8_t i, j, n, idx;
1996 tSapSpectChInfo *pSpectInfo;
1997 uint8_t minIdx;
1998
1999 pSpectInfo = pSpectInfoParams->pSpectCh;
2000 /* for each VHT160 channel, calculate the combined weight of the
2001 8 20MHz weight */
2002 for (i = 0; i < ARRAY_SIZE(acs_vht160_channels); i++) {
2003 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
2004 if (pSpectInfo[j].chNum ==
2005 acs_vht160_channels[i].chStartNum)
2006 break;
2007 }
2008 if (j == pSpectInfoParams->numSpectChans)
2009 continue;
2010
2011 if (!(((pSpectInfo[j].chNum + 4) == pSpectInfo[j + 1].chNum) &&
2012 ((pSpectInfo[j].chNum + 8) ==
2013 pSpectInfo[j + 2].chNum) &&
2014 ((pSpectInfo[j].chNum + 12) ==
2015 pSpectInfo[j + 3].chNum) &&
2016 ((pSpectInfo[j].chNum + 16) ==
2017 pSpectInfo[j + 4].chNum) &&
2018 ((pSpectInfo[j].chNum + 20) ==
2019 pSpectInfo[j + 5].chNum) &&
2020 ((pSpectInfo[j].chNum + 24) ==
2021 pSpectInfo[j + 6].chNum) &&
2022 ((pSpectInfo[j].chNum + 28) ==
2023 pSpectInfo[j + 7].chNum))) {
2024 /*
2025 * some channels does not exist in pSectInfo array,
2026 * skip this channel and those in the same VHT160 width
2027 */
2028 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 8;
2029 if ((pSpectInfo[j].chNum + 4) ==
2030 pSpectInfo[j + 1].chNum)
2031 pSpectInfo[j + 1].weight =
2032 SAP_ACS_WEIGHT_MAX * 8;
2033 if ((pSpectInfo[j].chNum + 8) ==
2034 pSpectInfo[j + 2].chNum)
2035 pSpectInfo[j + 2].weight =
2036 SAP_ACS_WEIGHT_MAX * 8;
2037 if ((pSpectInfo[j].chNum + 12) ==
2038 pSpectInfo[j + 3].chNum)
2039 pSpectInfo[j + 3].weight =
2040 SAP_ACS_WEIGHT_MAX * 8;
2041 if ((pSpectInfo[j].chNum + 16) ==
2042 pSpectInfo[j + 4].chNum)
2043 pSpectInfo[j + 4].weight =
2044 SAP_ACS_WEIGHT_MAX * 8;
2045 if ((pSpectInfo[j].chNum + 20) ==
2046 pSpectInfo[j + 5].chNum)
2047 pSpectInfo[j + 5].weight =
2048 SAP_ACS_WEIGHT_MAX * 8;
2049 if ((pSpectInfo[j].chNum + 24) ==
2050 pSpectInfo[j + 6].chNum)
2051 pSpectInfo[j + 6].weight =
2052 SAP_ACS_WEIGHT_MAX * 8;
2053 if ((pSpectInfo[j].chNum + 28) ==
2054 pSpectInfo[j + 7].chNum)
2055 pSpectInfo[j + 7].weight =
2056 SAP_ACS_WEIGHT_MAX * 8;
2057 continue;
2058 }
2059 /*found the channel, add the 7 adjacent channels' weight */
2060 acs_vht160_channels[i].weight = pSpectInfo[j].weight +
2061 pSpectInfo[j + 1].weight + pSpectInfo[j + 2].weight +
2062 pSpectInfo[j + 3].weight + pSpectInfo[j + 4].weight +
2063 pSpectInfo[j + 5].weight + pSpectInfo[j + 6].weight +
2064 pSpectInfo[j + 7].weight;
2065
2066 /* find best channel among 8 channels as the primary channel */
2067 if ((pSpectInfo[j].weight + pSpectInfo[j + 1].weight +
2068 pSpectInfo[j + 2].weight + pSpectInfo[j + 3].weight) >
2069 (pSpectInfo[j + 4].weight + pSpectInfo[j + 5].weight +
2070 pSpectInfo[j + 6].weight + pSpectInfo[j + 7].weight))
2071 idx = 4;
2072 else
2073 idx = 0;
2074 /* find best channel among 4 channels as the primary channel */
2075 if ((pSpectInfo[j + idx].weight +
2076 pSpectInfo[j + idx + 1].weight) <
2077 (pSpectInfo[j + idx + 2].weight +
2078 pSpectInfo[j + idx + 3].weight)) {
2079 /* lower 2 channels are better choice */
2080 if (pSpectInfo[j + idx].weight <
2081 pSpectInfo[j + idx + 1].weight)
2082 minIdx = 0 + idx;
2083 else
2084 minIdx = 1 + idx;
2085 } else if (pSpectInfo[j + idx + 2].weight <=
2086 pSpectInfo[j + idx + 3].weight) {
2087 /* upper 2 channels are better choice */
2088 minIdx = 2 + idx;
2089 } else {
2090 minIdx = 3 + idx;
2091 }
2092
2093 /*
2094 * set all 8 channels to max value first, then reset the
2095 * best channel as the selected primary channel, update its
2096 * weightage with the combined weight value
2097 */
2098 for (n = 0; n < 8; n++)
2099 pSpectInfo[j + n].weight = SAP_ACS_WEIGHT_MAX * 8;
2100
2101 pSpectInfo[j + minIdx].weight = acs_vht160_channels[i].weight;
2102 }
2103
Himanshu Agarwal75e74412018-02-01 20:51:47 +05302104 /*
2105 * Assign max weight(SAP_ACS_WEIGHT_MAX * 8) to 2.4 Ghz channels
Kiran Kumar Lokere1a43bcf2018-05-15 15:51:58 -07002106 * and channel 132-173 as they cannot be part of a 160Mhz channel
Himanshu Agarwal75e74412018-02-01 20:51:47 +05302107 * bonding.
2108 */
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07002109 pSpectInfo = pSpectInfoParams->pSpectCh;
2110 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
Himanshu Agarwal75e74412018-02-01 20:51:47 +05302111 if ((pSpectInfo[j].chNum >= WLAN_REG_CH_NUM(CHAN_ENUM_1) &&
2112 pSpectInfo[j].chNum <= WLAN_REG_CH_NUM(CHAN_ENUM_14)) ||
2113 (pSpectInfo[j].chNum >= WLAN_REG_CH_NUM(CHAN_ENUM_132) &&
Kiran Kumar Lokere1a43bcf2018-05-15 15:51:58 -07002114 pSpectInfo[j].chNum <= WLAN_REG_CH_NUM(CHAN_ENUM_173)))
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07002115 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 8;
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07002116 }
2117
Manishekar Chandrasekaran44e334f2016-05-30 16:42:50 +05302118 sap_sort_chl_weight(pSpectInfoParams);
2119
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07002120 pSpectInfo = pSpectInfoParams->pSpectCh;
2121 for (j = 0; j < (pSpectInfoParams->numSpectChans); j++) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302122 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07002123 FL("Channel=%d Weight= %d rssi=%d bssCount=%d"),
2124 pSpectInfo->chNum, pSpectInfo->weight,
2125 pSpectInfo->rssiAgr, pSpectInfo->bssCount);
2126 pSpectInfo++;
2127 }
2128}
2129
2130/**
Himanshu Agarwal91c5c0f2018-02-13 14:40:56 +05302131 * sap_allocate_max_weight_ht40_24_g() - allocate max weight for 40Mhz
2132 * to all 2.4Ghz channels
2133 * @spect_info_params: Pointer to the tSapChSelSpectInfo structure
2134 *
2135 * Return: none
2136 */
2137static void sap_allocate_max_weight_ht40_24_g(
2138 tSapChSelSpectInfo *spect_info_params)
2139{
2140 tSapSpectChInfo *spect_info;
2141 uint8_t j;
2142
2143 /*
2144 * Assign max weight for 40Mhz (SAP_ACS_WEIGHT_MAX * 2) to all
2145 * 2.4 Ghz channels
2146 */
2147 spect_info = spect_info_params->pSpectCh;
2148 for (j = 0; j < spect_info_params->numSpectChans; j++) {
2149 if ((spect_info[j].chNum >= WLAN_REG_CH_NUM(CHAN_ENUM_1) &&
2150 spect_info[j].chNum <= WLAN_REG_CH_NUM(CHAN_ENUM_14)))
2151 spect_info[j].weight = SAP_ACS_WEIGHT_MAX * 2;
2152 }
2153}
2154
2155/**
2156 * sap_allocate_max_weight_ht40_5_g() - allocate max weight for 40Mhz
2157 * to all 5Ghz channels
2158 * @spect_info_params: Pointer to the tSapChSelSpectInfo structure
2159 *
2160 * Return: none
2161 */
2162static void sap_allocate_max_weight_ht40_5_g(
2163 tSapChSelSpectInfo *spect_info_params)
2164{
2165 tSapSpectChInfo *spect_info;
2166 uint8_t j;
2167
2168 /*
2169 * Assign max weight for 40Mhz (SAP_ACS_WEIGHT_MAX * 2) to all
2170 * 5 Ghz channels
2171 */
2172 spect_info = spect_info_params->pSpectCh;
2173 for (j = 0; j < spect_info_params->numSpectChans; j++) {
2174 if ((spect_info[j].chNum >= WLAN_REG_CH_NUM(CHAN_ENUM_36) &&
Kiran Kumar Lokere1a43bcf2018-05-15 15:51:58 -07002175 spect_info[j].chNum <= WLAN_REG_CH_NUM(CHAN_ENUM_173)))
Himanshu Agarwal91c5c0f2018-02-13 14:40:56 +05302176 spect_info[j].weight = SAP_ACS_WEIGHT_MAX * 2;
2177 }
2178}
2179
2180/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002181 * sap_sort_chl_weight_ht40_24_g() - to sort channel with the least weight
2182 * @pSpectInfoParams: Pointer to the tSapChSelSpectInfo structure
2183 *
Jeff Johnsonc7e4d162018-05-12 16:20:34 -07002184 * Function to sort the channels with the least weight first for HT40 channels
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002185 *
2186 * Return: none
2187 */
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002188static void sap_sort_chl_weight_ht40_24_g(tSapChSelSpectInfo *pSpectInfoParams,
2189 v_REGDOMAIN_t domain)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002190{
2191 uint8_t i, j;
2192 tSapSpectChInfo *pSpectInfo;
2193 uint32_t tmpWeight1, tmpWeight2;
bingse2782382017-03-23 10:34:52 +08002194 uint32_t ht40plus2gendch = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002195
2196 pSpectInfo = pSpectInfoParams->pSpectCh;
2197 /*
2198 * for each HT40 channel, calculate the combined weight of the
2199 * two 20MHz weight
2200 */
2201 for (i = 0; i < ARRAY_SIZE(acs_ht40_channels24_g); i++) {
2202 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
2203 if (pSpectInfo[j].chNum ==
2204 acs_ht40_channels24_g[i].chStartNum)
2205 break;
2206 }
2207 if (j == pSpectInfoParams->numSpectChans)
2208 continue;
2209
2210 if (!((pSpectInfo[j].chNum + 4) == pSpectInfo[j + 4].chNum)) {
2211 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2;
2212 continue;
2213 }
2214 /*
2215 * check if there is another channel combination possiblity
2216 * e.g., {1, 5} & {5, 9}
2217 */
2218 if ((pSpectInfo[j + 4].chNum + 4) == pSpectInfo[j + 8].chNum) {
2219 /* need to compare two channel pairs */
2220 tmpWeight1 = pSpectInfo[j].weight +
2221 pSpectInfo[j + 4].weight;
2222 tmpWeight2 = pSpectInfo[j + 4].weight +
2223 pSpectInfo[j + 8].weight;
2224 if (tmpWeight1 <= tmpWeight2) {
2225 if (pSpectInfo[j].weight <=
2226 pSpectInfo[j + 4].weight) {
2227 pSpectInfo[j].weight =
2228 tmpWeight1;
2229 pSpectInfo[j + 4].weight =
2230 SAP_ACS_WEIGHT_MAX * 2;
2231 pSpectInfo[j + 8].weight =
2232 SAP_ACS_WEIGHT_MAX * 2;
2233 } else {
2234 pSpectInfo[j + 4].weight =
2235 tmpWeight1;
2236 /* for secondary channel selection */
2237 pSpectInfo[j].weight =
2238 SAP_ACS_WEIGHT_MAX * 2
2239 - 1;
2240 pSpectInfo[j + 8].weight =
2241 SAP_ACS_WEIGHT_MAX * 2;
2242 }
2243 } else {
2244 if (pSpectInfo[j + 4].weight <=
2245 pSpectInfo[j + 8].weight) {
2246 pSpectInfo[j + 4].weight =
2247 tmpWeight2;
2248 pSpectInfo[j].weight =
2249 SAP_ACS_WEIGHT_MAX * 2;
2250 /* for secondary channel selection */
2251 pSpectInfo[j + 8].weight =
2252 SAP_ACS_WEIGHT_MAX * 2
2253 - 1;
2254 } else {
2255 pSpectInfo[j + 8].weight =
2256 tmpWeight2;
2257 pSpectInfo[j].weight =
2258 SAP_ACS_WEIGHT_MAX * 2;
2259 pSpectInfo[j + 4].weight =
2260 SAP_ACS_WEIGHT_MAX * 2;
2261 }
2262 }
2263 } else {
bingsaa6f96a2017-09-11 09:49:43 +08002264 tmpWeight1 = pSpectInfo[j].weight_copy +
2265 pSpectInfo[j + 4].weight_copy;
2266 if (pSpectInfo[j].weight_copy <=
2267 pSpectInfo[j + 4].weight_copy) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002268 pSpectInfo[j].weight = tmpWeight1;
2269 pSpectInfo[j + 4].weight =
2270 SAP_ACS_WEIGHT_MAX * 2;
2271 } else {
2272 pSpectInfo[j + 4].weight = tmpWeight1;
2273 pSpectInfo[j].weight =
2274 SAP_ACS_WEIGHT_MAX * 2;
2275 }
2276 }
2277 }
bingse2782382017-03-23 10:34:52 +08002278 /*
2279 * Every channel should be checked. Add the check for the omissive
2280 * channel. Mark the channel whose combination can't satisfy 40MHZ
2281 * as max value, so that it will be sorted to the bottom.
2282 */
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002283 if (REGDOMAIN_FCC == domain)
bingse2782382017-03-23 10:34:52 +08002284 ht40plus2gendch = HT40PLUS_2G_FCC_CH_END;
2285 else
2286 ht40plus2gendch = HT40PLUS_2G_EURJAP_CH_END;
2287 for (i = HT40MINUS_2G_CH_START; i <= ht40plus2gendch; i++) {
2288 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
2289 if (pSpectInfo[j].chNum == i &&
2290 ((pSpectInfo[j].chNum + 4) !=
2291 pSpectInfo[j+4].chNum) &&
2292 ((pSpectInfo[j].chNum - 4) !=
2293 pSpectInfo[j-4].chNum))
2294 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2;
2295 }
2296 }
2297 for (i = ht40plus2gendch + 1; i <= HT40MINUS_2G_CH_END; i++) {
2298 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
2299 if (pSpectInfo[j].chNum == i &&
2300 (pSpectInfo[j].chNum - 4) !=
2301 pSpectInfo[j-4].chNum)
2302 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2;
2303 }
2304 }
Himanshu Agarwal91c5c0f2018-02-13 14:40:56 +05302305
2306 pSpectInfo = pSpectInfoParams->pSpectCh;
2307 for (j = 0; j < (pSpectInfoParams->numSpectChans); j++) {
2308 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2309 "In %s, Channel=%d Weight= %d rssi=%d bssCount=%d",
2310 __func__, pSpectInfo->chNum, pSpectInfo->weight,
2311 pSpectInfo->rssiAgr, pSpectInfo->bssCount);
2312 pSpectInfo++;
2313 }
2314
Manishekar Chandrasekaran44e334f2016-05-30 16:42:50 +05302315 sap_sort_chl_weight(pSpectInfoParams);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002316}
2317
2318/*==========================================================================
2319 FUNCTION sap_sort_chl_weight_ht40_5_g
2320
2321 DESCRIPTION
Jeff Johnsonc7e4d162018-05-12 16:20:34 -07002322 Function to sort the channels with the least weight first for HT40 channels
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002323
2324 DEPENDENCIES
2325 NA.
2326
2327 PARAMETERS
2328
2329 IN
2330 pSpectInfoParams : Pointer to the tSapChSelSpectInfo structure
2331
2332 RETURN VALUE
2333 void : NULL
2334
2335 SIDE EFFECTS
2336 ============================================================================*/
Jeff Johnson464f7ea2016-10-07 10:21:26 -07002337static void sap_sort_chl_weight_ht40_5_g(tSapChSelSpectInfo *pSpectInfoParams)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002338{
2339 uint8_t i, j;
2340 tSapSpectChInfo *pSpectInfo;
2341
2342 pSpectInfo = pSpectInfoParams->pSpectCh;
2343 /*for each HT40 channel, calculate the combined weight of the
2344 two 20MHz weight */
2345 for (i = 0; i < ARRAY_SIZE(acs_ht40_channels5_g); i++) {
2346 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
2347 if (pSpectInfo[j].chNum ==
2348 acs_ht40_channels5_g[i].chStartNum)
2349 break;
2350 }
2351 if (j == pSpectInfoParams->numSpectChans)
2352 continue;
2353
2354 /* found the channel, add the two adjacent channels' weight */
2355 if ((pSpectInfo[j].chNum + 4) == pSpectInfo[j + 1].chNum) {
2356 acs_ht40_channels5_g[i].weight = pSpectInfo[j].weight +
2357 pSpectInfo[j + 1].weight;
2358 /* select better of the adjact channel as the primary channel */
2359 if (pSpectInfo[j].weight <= pSpectInfo[j + 1].weight) {
2360 pSpectInfo[j].weight =
2361 acs_ht40_channels5_g[i].weight;
2362 /* mark the adjacent channel's weight as max value so
2363 that it will be sorted to the bottom */
2364 pSpectInfo[j + 1].weight =
2365 SAP_ACS_WEIGHT_MAX * 2;
2366 } else {
2367 pSpectInfo[j + 1].weight =
2368 acs_ht40_channels5_g[i].weight;
2369 /* mark the adjacent channel's weight as max value so
2370 that it will be sorted to the bottom */
2371 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2;
2372 }
2373
2374 } else
2375 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2;
2376 }
2377
bingse2782382017-03-23 10:34:52 +08002378 /*
2379 *Every channel should be checked. Add the check for the omissive
2380 * channel. Mark the channel whose combination can't satisfy 40MHZ
2381 * as max value, so that it will be sorted to the bottom
2382 */
2383 for (j = 1; j < pSpectInfoParams->numSpectChans; j++) {
2384 for (i = 0; i < ARRAY_SIZE(acs_ht40_channels5_g); i++) {
2385 if (pSpectInfo[j].chNum ==
2386 (acs_ht40_channels5_g[i].chStartNum +
2387 4) &&
2388 pSpectInfo[j - 1].chNum !=
2389 acs_ht40_channels5_g[i].chStartNum) {
2390 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2;
2391 break;
2392 }
2393 }
2394 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002395 /* avoid channel 165 by setting its weight to max */
2396 pSpectInfo = pSpectInfoParams->pSpectCh;
2397 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
gaurank kathpalia1dea75b2019-01-10 13:53:43 +05302398 if (pSpectInfo[j].chNum >= CHANNEL_165) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002399 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2;
2400 break;
2401 }
2402 }
2403
2404 pSpectInfo = pSpectInfoParams->pSpectCh;
2405 for (j = 0; j < (pSpectInfoParams->numSpectChans); j++) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302406 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002407 "In %s, Channel=%d Weight= %d rssi=%d bssCount=%d",
2408 __func__, pSpectInfo->chNum, pSpectInfo->weight,
2409 pSpectInfo->rssiAgr, pSpectInfo->bssCount);
2410 pSpectInfo++;
2411 }
2412
2413 sap_sort_chl_weight(pSpectInfoParams);
2414}
2415
2416/*==========================================================================
2417 FUNCTION sap_sort_chl_weight_all
2418
2419 DESCRIPTION
Jeff Johnsonc7e4d162018-05-12 16:20:34 -07002420 Function to sort the channels with the least weight first
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002421
2422 DEPENDENCIES
2423 NA.
2424
2425 PARAMETERS
2426
2427 IN
Jeff Johnsone13d8062017-09-28 06:54:55 -07002428 sap_ctx : Pointer to the struct sap_context *structure
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002429 pSpectInfoParams : Pointer to the tSapChSelSpectInfo structure
2430
2431 RETURN VALUE
2432 void : NULL
2433
2434 SIDE EFFECTS
2435 ============================================================================*/
Jeff Johnsone13d8062017-09-28 06:54:55 -07002436static void sap_sort_chl_weight_all(struct sap_context *sap_ctx,
Jeff Johnson464f7ea2016-10-07 10:21:26 -07002437 tSapChSelSpectInfo *pSpectInfoParams,
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002438 uint32_t operatingBand,
2439 v_REGDOMAIN_t domain)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002440{
2441 tSapSpectChInfo *pSpectCh = NULL;
2442 uint32_t j = 0;
2443#ifndef SOFTAP_CHANNEL_RANGE
2444 uint32_t i = 0;
2445#endif
2446
2447 pSpectCh = pSpectInfoParams->pSpectCh;
2448#ifdef SOFTAP_CHANNEL_RANGE
2449
Jeff Johnsone13d8062017-09-28 06:54:55 -07002450 switch (sap_ctx->acs_cfg->ch_width) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002451 case CH_WIDTH_40MHZ:
Himanshu Agarwal91c5c0f2018-02-13 14:40:56 +05302452 /*
2453 * Assign max weight to all 5Ghz channels when operating band
2454 * is 11g and to all 2.4Ghz channels when operating band is 11a
2455 * or 11abg to avoid selection in ACS algorithm for starting SAP
2456 */
2457 if (eCSR_DOT11_MODE_11g == operatingBand) {
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002458 sap_sort_chl_weight_ht40_24_g(pSpectInfoParams, domain);
Himanshu Agarwal91c5c0f2018-02-13 14:40:56 +05302459 sap_allocate_max_weight_ht40_5_g(pSpectInfoParams);
2460 } else {
2461 sap_allocate_max_weight_ht40_24_g(pSpectInfoParams);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002462 sap_sort_chl_weight_ht40_5_g(pSpectInfoParams);
2463 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002464 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002465 case CH_WIDTH_80MHZ:
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07002466 case CH_WIDTH_80P80MHZ:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002467 sap_sort_chl_weight_ht80(pSpectInfoParams);
2468 break;
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07002469 case CH_WIDTH_160MHZ:
2470 sap_sort_chl_weight_vht160(pSpectInfoParams);
2471 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002472 case CH_WIDTH_20MHZ:
2473 default:
2474 /* Sorting the channels as per weights as 20MHz channels */
2475 sap_sort_chl_weight(pSpectInfoParams);
2476 }
2477
2478#else
2479 /* Sorting the channels as per weights */
2480 for (i = 0; i < SPECT_24GHZ_CH_COUNT; i++) {
2481 minWeightIndex = i;
2482 for (j = i + 1; j < SPECT_24GHZ_CH_COUNT; j++) {
2483 if (pSpectCh[j].weight <
2484 pSpectCh[minWeightIndex].weight) {
2485 minWeightIndex = j;
2486 }
2487 }
2488 if (minWeightIndex != i) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302489 qdf_mem_copy(&temp, &pSpectCh[minWeightIndex],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002490 sizeof(*pSpectCh));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302491 qdf_mem_copy(&pSpectCh[minWeightIndex], &pSpectCh[i],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002492 sizeof(*pSpectCh));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302493 qdf_mem_copy(&pSpectCh[i], &temp, sizeof(*pSpectCh));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002494 }
2495 }
2496#endif
2497
2498 /* For testing */
Ravi Joshi9788fcd2018-02-13 15:12:22 -08002499 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002500 "In %s, Sorted Spectrum Channels Weight", __func__);
2501 pSpectCh = pSpectInfoParams->pSpectCh;
2502 for (j = 0; j < (pSpectInfoParams->numSpectChans); j++) {
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, Channel=%d Weight= %d rssi=%d bssCount=%d",
2505 __func__, pSpectCh->chNum, pSpectCh->weight,
2506 pSpectCh->rssiAgr, pSpectCh->bssCount);
2507 pSpectCh++;
2508 }
2509
2510}
2511
Naveen Rawatbec64d92017-09-13 14:35:21 -07002512/**
2513 * sap_is_ch_non_overlap() - returns true if non-overlapping channel
2514 * @sap_ctx: Sap context
2515 * @ch: channel number
2516 *
2517 * Returns: true if non-overlapping (1, 6, 11) channel, false otherwise
2518 */
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -07002519static bool sap_is_ch_non_overlap(struct sap_context *sap_ctx, uint16_t ch)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002520{
Naveen Rawatbec64d92017-09-13 14:35:21 -07002521 if (sap_ctx->enableOverLapCh)
Srinivas Girigowda74a66d62017-06-21 23:28:25 -07002522 return true;
Naveen Rawatbec64d92017-09-13 14:35:21 -07002523
2524 if ((ch == CHANNEL_1) || (ch == CHANNEL_6) || (ch == CHANNEL_11))
Srinivas Girigowda74a66d62017-06-21 23:28:25 -07002525 return true;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002526
Srinivas Girigowda74a66d62017-06-21 23:28:25 -07002527 return false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002528}
2529
Dustin Brown0ce56d32016-10-17 16:18:03 -07002530#ifdef FEATURE_WLAN_CH_AVOID
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002531/**
2532 * sap_select_channel_no_scan_result() - select SAP channel when no scan results
2533 * are available.
2534 * @sap_ctx: Sap context
2535 *
2536 * Returns: channel number if success, 0 otherwise
2537 */
Jeff Johnson7730fbb2018-11-08 13:48:27 -08002538static uint8_t sap_select_channel_no_scan_result(mac_handle_t mac_handle,
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -07002539 struct sap_context *sap_ctx)
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002540{
Mohit Khanna841044f2016-03-25 16:16:24 -07002541 enum channel_state ch_type;
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002542 uint8_t i, first_safe_ch_in_range = SAP_CHANNEL_NOT_SELECTED;
Dustin Brown0ce56d32016-10-17 16:18:03 -07002543 uint32_t start_ch_num = sap_ctx->acs_cfg->start_ch;
2544 uint32_t end_ch_num = sap_ctx->acs_cfg->end_ch;
Jeff Johnsonc59ef8b2018-12-02 12:01:21 -08002545 struct mac_context *mac_ctx = NULL;
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002546
Jeff Johnsona0619e42018-11-28 17:43:00 -08002547 mac_ctx = MAC_CONTEXT(mac_handle);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002548
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002549 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2550 FL("start - end: %d - %d"), start_ch_num, end_ch_num);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002551
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002552 /* get a channel in PCL and within the range */
2553 for (i = 0; i < sap_ctx->acs_cfg->pcl_ch_count; i++) {
2554 if ((sap_ctx->acs_cfg->pcl_channels[i] < start_ch_num) ||
2555 (sap_ctx->acs_cfg->pcl_channels[i] > end_ch_num))
2556 continue;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002557
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002558 first_safe_ch_in_range = sap_ctx->acs_cfg->pcl_channels[i];
2559 break;
2560 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002561
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002562 if (SAP_CHANNEL_NOT_SELECTED != first_safe_ch_in_range)
2563 return first_safe_ch_in_range;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002564
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002565 for (i = 0; i < NUM_CHANNELS; i++) {
2566 if ((safe_channels[i].channelNumber < start_ch_num) ||
2567 (safe_channels[i].channelNumber > end_ch_num))
2568 continue;
2569
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002570 ch_type = wlan_reg_get_channel_state(mac_ctx->pdev,
2571 safe_channels[i].channelNumber);
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002572
2573 if ((ch_type == CHANNEL_STATE_DISABLE) ||
2574 (ch_type == CHANNEL_STATE_INVALID))
2575 continue;
Arif Hussain88d1fdd2018-09-26 16:12:24 -07002576 if ((!mac_ctx->mlme_cfg->dfs_cfg.dfs_master_capable) &&
2577 (CHANNEL_STATE_DFS == ch_type)) {
Kondabattini, Ganesh13bb4b12016-09-04 16:16:53 +05302578 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2579 "%s: DFS master mode disabled. Skip DFS channel %d",
2580 __func__, safe_channels[i].channelNumber);
2581 continue;
2582 }
Agrawal Ashish65634612016-08-18 13:24:32 +05302583 if ((sap_ctx->dfs_mode == ACS_DFS_MODE_DISABLE) &&
2584 (CHANNEL_STATE_DFS == ch_type))
2585 continue;
Kondabattini, Ganesh13bb4b12016-09-04 16:16:53 +05302586
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002587 if (safe_channels[i].isSafe == true) {
2588 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2589 FL("channel %d in the configuration is safe"),
2590 safe_channels[i].channelNumber);
2591 first_safe_ch_in_range = safe_channels[i].channelNumber;
2592 break;
2593 }
2594
2595 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2596 FL("channel %d in the configuration is unsafe"),
2597 safe_channels[i].channelNumber);
2598 }
2599
2600 /* if no channel selected return SAP_CHANNEL_NOT_SELECTED */
2601 return first_safe_ch_in_range;
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002602}
Dustin Brown0ce56d32016-10-17 16:18:03 -07002603#else
Jeff Johnson7730fbb2018-11-08 13:48:27 -08002604static uint8_t sap_select_channel_no_scan_result(mac_handle_t mac_handle,
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -07002605 struct sap_context *sap_ctx)
Dustin Brown0ce56d32016-10-17 16:18:03 -07002606{
2607 uint32_t start_ch_num = sap_ctx->acs_cfg->start_ch;
2608
2609 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2610 FL("start - end: %d - %d"),
2611 start_ch_num,
2612 sap_ctx->acs_cfg->end_ch);
2613
2614 sap_ctx->acs_cfg->pri_ch = start_ch_num;
2615 sap_ctx->acs_cfg->ht_sec_ch = 0;
2616
2617 /* pick the first channel in configured range */
2618 return start_ch_num;
2619}
2620#endif /* FEATURE_WLAN_CH_AVOID */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002621
2622/**
2623 * sap_select_channel() - select SAP channel
Jeff Johnson7730fbb2018-11-08 13:48:27 -08002624 * @mac_handle: Opaque handle to the global MAC context
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002625 * @sap_ctx: Sap context
2626 * @scan_result: Pointer to tScanResultHandle
2627 *
2628 * Runs a algorithm to select the best channel to operate in based on BSS
2629 * rssi and bss count on each channel
2630 *
2631 * Returns: channel number if success, 0 otherwise
2632 */
Jeff Johnson7730fbb2018-11-08 13:48:27 -08002633uint8_t sap_select_channel(mac_handle_t mac_handle,
2634 struct sap_context *sap_ctx,
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002635 tScanResultHandle scan_result)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002636{
2637 /* DFS param object holding all the data req by the algo */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002638 tSapChSelSpectInfo spect_info_obj = { NULL, 0 };
2639 tSapChSelSpectInfo *spect_info = &spect_info_obj;
2640 uint8_t best_ch_num = SAP_CHANNEL_NOT_SELECTED;
bingse2782382017-03-23 10:34:52 +08002641 uint32_t ht40plus2gendch = 0;
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002642 v_REGDOMAIN_t domain;
Arif Hussain21ad4342017-12-21 12:00:54 -08002643 uint8_t country[CDS_COUNTRY_CODE_LEN + 1];
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002644#ifdef SOFTAP_CHANNEL_RANGE
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002645 uint8_t count;
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002646 uint32_t start_ch_num, end_ch_num, tmp_ch_num, operating_band = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002647#endif
Jeff Johnsonc59ef8b2018-12-02 12:01:21 -08002648 struct mac_context *mac_ctx;
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002649
Jeff Johnsona0619e42018-11-28 17:43:00 -08002650 mac_ctx = MAC_CONTEXT(mac_handle);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302651 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002652 "In %s, Running SAP Ch Select", __func__);
2653
2654#ifdef FEATURE_WLAN_CH_AVOID
Jeff Johnson7730fbb2018-11-08 13:48:27 -08002655 sap_update_unsafe_channel_list(mac_handle, sap_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002656#endif
2657
gaoleze5108942017-03-31 16:56:42 +08002658 /*
2659 * If ACS weight is not enabled on noise_floor/channel_free/tx_power,
2660 * then skip acs process if no bss found.
2661 */
Jeff Johnson4cfe6cc2019-03-18 13:40:27 -07002662 if (!scan_result &&
gaoleze5108942017-03-31 16:56:42 +08002663 !(sap_ctx->auto_channel_select_weight & 0xffff00)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302664 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002665 FL("No external AP present"));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002666
2667#ifndef SOFTAP_CHANNEL_RANGE
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002668 return SAP_CHANNEL_NOT_SELECTED;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002669#else
Jeff Johnson7730fbb2018-11-08 13:48:27 -08002670 return sap_select_channel_no_scan_result(mac_handle, sap_ctx);
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002671#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002672 }
2673
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002674 /* Initialize the structure pointed by spect_info */
Jeff Johnson7730fbb2018-11-08 13:48:27 -08002675 if (sap_chan_sel_init(mac_handle, spect_info, sap_ctx) != true) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302676 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002677 FL("Ch Select initialization failed"));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002678 return SAP_CHANNEL_NOT_SELECTED;
2679 }
2680 /* Compute the weight of the entire spectrum in the operating band */
Jeff Johnson7730fbb2018-11-08 13:48:27 -08002681 sap_compute_spect_weight(spect_info, mac_handle, scan_result, sap_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002682
2683#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
2684 /* process avoid channel IE to collect all channels to avoid */
Jeff Johnson7730fbb2018-11-08 13:48:27 -08002685 sap_process_avoid_ie(mac_handle, sap_ctx, scan_result, spect_info);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002686#endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
2687
Paul Zhang0f85b412018-01-18 19:14:51 +08002688 wlan_reg_read_current_country(mac_ctx->psoc, country);
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002689 wlan_reg_get_domain_from_country_code(&domain, country, SOURCE_DRIVER);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002690#ifdef SOFTAP_CHANNEL_RANGE
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002691 start_ch_num = sap_ctx->acs_cfg->start_ch;
2692 end_ch_num = sap_ctx->acs_cfg->end_ch;
2693 SET_ACS_BAND(operating_band, sap_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002694
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002695 sap_ctx->acsBestChannelInfo.channelNum = 0;
2696 sap_ctx->acsBestChannelInfo.weight = SAP_ACS_WEIGHT_MAX;
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
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002729 sap_ctx->acsBestChannelInfo.channelNum = best_ch_num;
2730 sap_ctx->acsBestChannelInfo.weight =
2731 spect_info->pSpectCh[count].weight_copy;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002732 }
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002733
2734 if (best_ch_num == SAP_CHANNEL_NOT_SELECTED)
2735 continue;
2736
Tushnim Bhattacharyya03103fd2017-06-23 10:48:52 -07002737 if (operating_band != eCSR_DOT11_MODE_11g) {
2738 QDF_TRACE(QDF_MODULE_ID_SAP,
2739 QDF_TRACE_LEVEL_INFO_HIGH,
2740 "operating_band %d", operating_band);
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002741 continue;
Tushnim Bhattacharyya03103fd2017-06-23 10:48:52 -07002742 }
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002743
2744 /* Give preference to Non-overlap channels */
Naveen Rawatbec64d92017-09-13 14:35:21 -07002745 if (false == sap_is_ch_non_overlap(sap_ctx,
Tushnim Bhattacharyya03103fd2017-06-23 10:48:52 -07002746 spect_info->pSpectCh[count].chNum)) {
2747 QDF_TRACE(QDF_MODULE_ID_SAP,
2748 QDF_TRACE_LEVEL_INFO_HIGH,
Naveen Rawatbec64d92017-09-13 14:35:21 -07002749 FL("ch: %d skipped as its overlapping ch"),
2750 spect_info->pSpectCh[count].chNum);
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002751 continue;
Tushnim Bhattacharyya03103fd2017-06-23 10:48:52 -07002752 }
2753
2754 if (wlan_reg_is_dfs_ch(mac_ctx->pdev,
2755 spect_info->pSpectCh[count].chNum) &&
2756 policy_mgr_disallow_mcc(mac_ctx->psoc,
2757 spect_info->pSpectCh[count].chNum)) {
2758 QDF_TRACE(QDF_MODULE_ID_SAP,
2759 QDF_TRACE_LEVEL_INFO_HIGH,
2760 "No DFS MCC");
2761 continue;
2762 }
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002763
bings14d1d3b2017-08-03 11:14:29 +08002764 if (spect_info->pSpectCh[count].weight_copy >
2765 sap_ctx->acsBestChannelInfo.weight)
2766 continue;
2767
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002768 tmp_ch_num = spect_info->pSpectCh[count].chNum;
gaoleze5108942017-03-31 16:56:42 +08002769 tmp_ch_num = sap_channel_in_acs_channel_list(
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002770 tmp_ch_num, sap_ctx, spect_info);
2771 if (tmp_ch_num == SAP_CHANNEL_NOT_SELECTED)
2772 continue;
2773
2774 best_ch_num = tmp_ch_num;
2775 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002776 }
2777#else
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002778 /* Sort the ch lst as per the computed weights, lesser weight first. */
Jeff Johnson7730fbb2018-11-08 13:48:27 -08002779 sap_sort_chl_weight_all(sap_ctx, mac_handle, spect_info);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002780 /* Get the first channel in sorted array as best 20M Channel */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002781 best_ch_num = (uint8_t) spect_info->pSpectCh[0].chNum;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002782 /* Select Best Channel from Channel List if Configured */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002783 best_ch_num = sap_select_preferred_channel_from_channel_list(
2784 best_ch_num, sap_ctx, spect_info);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002785#endif
2786
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002787 /*
2788 * in case the best channel seleted is not in PCL and there is another
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002789 * channel which has same weightage and is in PCL, choose the one in
2790 * PCL
2791 */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002792 for (count = 0; count < spect_info->numSpectChans; count++) {
2793 if (!ch_in_pcl(sap_ctx, spect_info->pSpectCh[count].chNum) ||
2794 (spect_info->pSpectCh[count].weight !=
2795 sap_ctx->acsBestChannelInfo.weight))
2796 continue;
2797
2798 if (sap_select_preferred_channel_from_channel_list(
2799 spect_info->pSpectCh[count].chNum, sap_ctx, spect_info)
2800 == SAP_CHANNEL_NOT_SELECTED)
2801 continue;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002802
2803#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002804 if (sap_check_in_avoid_ch_list(sap_ctx, best_ch_num))
2805 continue;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002806#endif
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002807 best_ch_num = spect_info->pSpectCh[count].chNum;
2808 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2809 FL("change best channel to %d in PCL"), best_ch_num);
2810 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002811 }
2812
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002813 sap_ctx->acs_cfg->pri_ch = best_ch_num;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002814 /* determine secondary channel for 2.4G channel 5, 6, 7 in HT40 */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002815 if ((operating_band != eCSR_DOT11_MODE_11g) ||
2816 (sap_ctx->acs_cfg->ch_width != CH_WIDTH_40MHZ))
2817 goto sap_ch_sel_end;
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002818 if (REGDOMAIN_FCC == domain)
bingse2782382017-03-23 10:34:52 +08002819 ht40plus2gendch = HT40PLUS_2G_FCC_CH_END;
2820 else
2821 ht40plus2gendch = HT40PLUS_2G_EURJAP_CH_END;
2822 if ((best_ch_num >= HT40MINUS_2G_CH_START) &&
2823 (best_ch_num <= ht40plus2gendch)) {
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002824 int weight_below, weight_above, i;
2825 tSapSpectChInfo *pspect_info;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002826
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002827 weight_below = weight_above = SAP_ACS_WEIGHT_MAX;
2828 pspect_info = spect_info->pSpectCh;
2829 for (i = 0; i < spect_info->numSpectChans; i++) {
2830 if (pspect_info[i].chNum == (best_ch_num - 4))
2831 weight_below = pspect_info[i].weight;
2832 if (pspect_info[i].chNum == (best_ch_num + 4))
2833 weight_above = pspect_info[i].weight;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002834 }
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002835
2836 if (weight_below < weight_above)
2837 sap_ctx->acs_cfg->ht_sec_ch =
2838 sap_ctx->acs_cfg->pri_ch - 4;
2839 else
2840 sap_ctx->acs_cfg->ht_sec_ch =
2841 sap_ctx->acs_cfg->pri_ch + 4;
2842 } else if (best_ch_num >= 1 && best_ch_num <= 4) {
2843 sap_ctx->acs_cfg->ht_sec_ch = sap_ctx->acs_cfg->pri_ch + 4;
bingse2782382017-03-23 10:34:52 +08002844 } else if (best_ch_num >= ht40plus2gendch && best_ch_num <=
2845 HT40MINUS_2G_CH_END) {
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002846 sap_ctx->acs_cfg->ht_sec_ch = sap_ctx->acs_cfg->pri_ch - 4;
2847 } else if (best_ch_num == 14) {
2848 sap_ctx->acs_cfg->ht_sec_ch = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002849 }
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002850 sap_ctx->secondary_ch = sap_ctx->acs_cfg->ht_sec_ch;
2851
2852sap_ch_sel_end:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002853 /* Free all the allocated memory */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002854 sap_chan_sel_exit(spect_info);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002855
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302856 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002857 FL("Running SAP Ch select Completed, Ch=%d"), best_ch_num);
wadesongcb0ded22018-02-02 17:57:20 +08002858 host_log_acs_best_chan(best_ch_num, sap_ctx->acsBestChannelInfo.weight);
2859
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002860 if (best_ch_num > 0 && best_ch_num <= 252)
2861 return best_ch_num;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002862 else
2863 return SAP_CHANNEL_NOT_SELECTED;
2864}