blob: e02b76cb10f0eacc3cbb04fc5e4e3fb86ce790a8 [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"
Abhishek Singhd1cd4ae2019-05-10 11:22:21 +053051#include <wlan_scan_utils_api.h>
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080052
53/*--------------------------------------------------------------------------
54 Function definitions
55 --------------------------------------------------------------------------*/
56
57/*--------------------------------------------------------------------------
58 Defines
59 --------------------------------------------------------------------------*/
60#define SAP_DEBUG
61
62#define IS_RSSI_VALID(extRssi, rssi) \
63 ( \
64 ((extRssi < rssi) ? true : false) \
65 )
66
Jeff Johnsone13d8062017-09-28 06:54:55 -070067#define SET_ACS_BAND(acs_band, sap_ctx) \
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080068{ \
Jeff Johnsone13d8062017-09-28 06:54:55 -070069 if (sap_ctx->acs_cfg->start_ch <= 14 && \
70 sap_ctx->acs_cfg->end_ch <= 14) \
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080071 acs_band = eCSR_DOT11_MODE_11g; \
Jeff Johnsone13d8062017-09-28 06:54:55 -070072 else if (sap_ctx->acs_cfg->start_ch >= 14)\
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080073 acs_band = eCSR_DOT11_MODE_11a; \
74 else \
75 acs_band = eCSR_DOT11_MODE_abg; \
76}
77
gaoleze5108942017-03-31 16:56:42 +080078#define ACS_WEIGHT_AMOUNT_LOCAL 240
79
80#define ACS_WEIGHT_AMOUNT_CONFIG(weights) \
81 (((weights) & 0xf) + \
82 (((weights) & 0xf0) >> 4) + \
83 (((weights) & 0xf00) >> 8) + \
84 (((weights) & 0xf000) >> 12) + \
85 (((weights) & 0xf0000) >> 16) + \
86 (((weights) & 0xf00000) >> 20))
87
88/*
89 * LSH/RSH 4 to enhance the accurate since
90 * need to do modulation to ACS_WEIGHT_AMOUNT_LOCAL.
91 */
92#define ACS_WEIGHT_COMPUTE(weights, weight, factor, base) \
93 (((((((((weight) << 4) * ACS_WEIGHT_AMOUNT_LOCAL * (factor)) + \
94 (ACS_WEIGHT_AMOUNT_CONFIG((weights)) >> 1)) / \
95 ACS_WEIGHT_AMOUNT_CONFIG((weights))) + \
96 ((base) >> 1)) / (base)) + 8) >> 4)
97
98#define ACS_WEIGHT_CFG_TO_LOCAL(weights, weight) \
99 (((((((weight) << 4) * ACS_WEIGHT_AMOUNT_LOCAL) + \
100 (ACS_WEIGHT_AMOUNT_CONFIG((weights)) >> 1)) / \
101 ACS_WEIGHT_AMOUNT_CONFIG((weights))) + 8) >> 4)
102
103#define ACS_WEIGHT_SOFTAP_RSSI_CFG(weights) \
104 ((weights) & 0xf)
105
106#define ACS_WEIGHT_SOFTAP_COUNT_CFG(weights) \
107 (((weights) & 0xf0) >> 4)
108
109#define ACS_WEIGHT_SOFTAP_NOISE_FLOOR_CFG(weights) \
110 (((weights) & 0xf00) >> 8)
111
112#define ACS_WEIGHT_SOFTAP_CHANNEL_FREE_CFG(weights) \
113 (((weights) & 0xf000) >> 12)
114
115#define ACS_WEIGHT_SOFTAP_TX_POWER_RANGE_CFG(weights) \
116 (((weights) & 0xf0000) >> 16)
117
118#define ACS_WEIGHT_SOFTAP_TX_POWER_THROUGHPUT_CFG(weights) \
119 (((weights) & 0xf00000) >> 20)
120
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800121#ifdef FEATURE_WLAN_CH_AVOID
Amar Singhalb8d4f152016-02-10 10:21:43 -0800122sapSafeChannelType safe_channels[NUM_CHANNELS] = {
123 {1, true},
124 {2, true},
125 {3, true},
126 {4, true},
127 {5, true},
128 {6, true},
129 {7, true},
130 {8, true},
131 {9, true},
132 {10, true},
133 {11, true},
134 {12, true},
135 {13, true},
136 {14, true},
137 {36, true},
138 {40, true},
139 {44, true},
140 {48, true},
141 {52, true},
142 {56, true},
143 {60, true},
144 {64, true},
145 {100, true},
146 {104, true},
147 {108, true},
148 {112, true},
149 {116, true},
150 {120, true},
151 {124, true},
152 {128, true},
153 {132, true},
154 {136, true},
155 {140, true},
156 {144, true},
157 {149, true},
158 {153, true},
159 {157, true},
160 {161, true},
161 {165, true},
Kiran Kumar Lokere1a43bcf2018-05-15 15:51:58 -0700162 {169, true},
163 {173, true},
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800164};
165#endif
166
167typedef struct {
168 uint16_t chStartNum;
169 uint32_t weight;
170} sapAcsChannelInfo;
171
172sapAcsChannelInfo acs_ht40_channels5_g[] = {
173 {36, SAP_ACS_WEIGHT_MAX},
174 {44, SAP_ACS_WEIGHT_MAX},
175 {52, SAP_ACS_WEIGHT_MAX},
176 {60, SAP_ACS_WEIGHT_MAX},
177 {100, SAP_ACS_WEIGHT_MAX},
178 {108, SAP_ACS_WEIGHT_MAX},
179 {116, SAP_ACS_WEIGHT_MAX},
180 {124, SAP_ACS_WEIGHT_MAX},
181 {132, SAP_ACS_WEIGHT_MAX},
182 {140, SAP_ACS_WEIGHT_MAX},
183 {149, SAP_ACS_WEIGHT_MAX},
184 {157, SAP_ACS_WEIGHT_MAX},
185};
186
187sapAcsChannelInfo acs_ht80_channels[] = {
188 {36, SAP_ACS_WEIGHT_MAX},
189 {52, SAP_ACS_WEIGHT_MAX},
190 {100, SAP_ACS_WEIGHT_MAX},
191 {116, SAP_ACS_WEIGHT_MAX},
192 {132, SAP_ACS_WEIGHT_MAX},
193 {149, SAP_ACS_WEIGHT_MAX},
194};
195
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -0700196sapAcsChannelInfo acs_vht160_channels[] = {
197 {36, SAP_ACS_WEIGHT_MAX},
198 {100, SAP_ACS_WEIGHT_MAX},
199};
200
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800201sapAcsChannelInfo acs_ht40_channels24_g[] = {
202 {1, SAP_ACS_WEIGHT_MAX},
203 {2, SAP_ACS_WEIGHT_MAX},
204 {3, SAP_ACS_WEIGHT_MAX},
205 {4, SAP_ACS_WEIGHT_MAX},
206 {9, SAP_ACS_WEIGHT_MAX},
207};
208
209#define CHANNEL_165 165
210
211/* rssi discount for channels in PCL */
212#define PCL_RSSI_DISCOUNT 10
213
214#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
215/**
216 * sap_check_n_add_channel() - checks and add given channel in sap context's
217 * avoid_channels_info struct
218 * @sap_ctx: sap context.
219 * @new_channel: channel to be added to sap_ctx's avoid ch info
220 *
221 * sap_ctx contains sap_avoid_ch_info strcut containing the list of channels on
222 * which MDM device's AP with MCC was detected. This function will add channels
223 * to that list after checking for duplicates.
224 *
225 * Return: true: if channel was added or already present
226 * else false: if channel list was already full.
227 */
Tang Yingying523322d2017-01-17 23:28:43 +0800228static bool
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -0700229sap_check_n_add_channel(struct sap_context *sap_ctx,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800230 uint8_t new_channel)
231{
232 uint8_t i = 0;
233 struct sap_avoid_channels_info *ie_info =
234 &sap_ctx->sap_detected_avoid_ch_ie;
235
236 for (i = 0; i < sizeof(ie_info->channels); i++) {
237 if (ie_info->channels[i] == new_channel)
238 break;
239
240 if (ie_info->channels[i] == 0) {
241 ie_info->channels[i] = new_channel;
242 break;
243 }
244 }
245 if (i == sizeof(ie_info->channels))
246 return false;
247 else
248 return true;
249}
250/**
251 * sap_check_n_add_overlapped_chnls() - checks & add overlapped channels
252 * to primary channel in 2.4Ghz band.
253 * @sap_ctx: sap context.
254 * @primary_chnl: primary channel to be avoided.
255 *
256 * sap_ctx contains sap_avoid_ch_info struct containing the list of channels on
257 * which MDM device's AP with MCC was detected. This function will add channels
258 * to that list after checking for duplicates.
259 *
260 * Return: true: if channel was added or already present
261 * else false: if channel list was already full.
262 */
263static bool
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -0700264sap_check_n_add_overlapped_chnls(struct sap_context *sap_ctx,
265 uint8_t primary_channel)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800266{
267 uint8_t i = 0, j = 0, upper_chnl = 0, lower_chnl = 0;
268 struct sap_avoid_channels_info *ie_info =
269 &sap_ctx->sap_detected_avoid_ch_ie;
270 /*
271 * if primary channel less than channel 1 or out of 2g band then
272 * no further process is required. return true in this case.
273 */
274 if (primary_channel < CHANNEL_1 || primary_channel > CHANNEL_14)
275 return true;
276
277 /* lower channel is one channel right before primary channel */
278 lower_chnl = primary_channel - 1;
279 /* upper channel is one channel right after primary channel */
280 upper_chnl = primary_channel + 1;
281
282 /* lower channel needs to be non-zero, zero is not valid channel */
283 if (lower_chnl > (CHANNEL_1 - 1)) {
284 for (i = 0; i < sizeof(ie_info->channels); i++) {
285 if (ie_info->channels[i] == lower_chnl)
286 break;
287 if (ie_info->channels[i] == 0) {
288 ie_info->channels[i] = lower_chnl;
289 break;
290 }
291 }
292 }
293 /* upper channel needs to be atleast last channel in 2.4Ghz band */
294 if (upper_chnl < (CHANNEL_14 + 1)) {
295 for (j = 0; j < sizeof(ie_info->channels); j++) {
296 if (ie_info->channels[j] == upper_chnl)
297 break;
298 if (ie_info->channels[j] == 0) {
299 ie_info->channels[j] = upper_chnl;
300 break;
301 }
302 }
303 }
304 if (i == sizeof(ie_info->channels) || j == sizeof(ie_info->channels))
305 return false;
306 else
307 return true;
308}
309
310/**
311 * sap_process_avoid_ie() - processes the detected Q2Q IE
312 * context's avoid_channels_info struct
Jeff Johnson7730fbb2018-11-08 13:48:27 -0800313 * @mac_handle: opaque handle to the MAC context
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800314 * @sap_ctx: sap context.
315 * @scan_result: scan results for ACS scan.
316 * @spect_info: spectrum weights array to update
317 *
318 * Detection of Q2Q IE indicates presence of another MDM device with its AP
319 * operating in MCC mode. This function parses the scan results and processes
320 * the Q2Q IE if found. It then extracts the channels and populates them in
321 * sap_ctx struct. It also increases the weights of those channels so that
322 * ACS logic will avoid those channels in its selection algorithm.
323 *
324 * Return: void
325 */
Jeff Johnson7730fbb2018-11-08 13:48:27 -0800326static void sap_process_avoid_ie(mac_handle_t mac_handle,
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -0700327 struct sap_context *sap_ctx,
Abhishek Singhd1cd4ae2019-05-10 11:22:21 +0530328 qdf_list_t *scan_list,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800329 tSapChSelSpectInfo *spect_info)
330{
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;
Jeff Johnsonc59ef8b2018-12-02 12:01:21 -0800334 struct mac_context *mac_ctx = NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800335 tSapSpectChInfo *spect_ch = NULL;
Abhishek Singhd1cd4ae2019-05-10 11:22:21 +0530336 qdf_list_node_t *cur_lst = NULL, *next_lst = NULL;
337 struct scan_cache_node *cur_node = NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800338
Jeff Johnsona0619e42018-11-28 17:43:00 -0800339 mac_ctx = MAC_CONTEXT(mac_handle);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800340 spect_ch = spect_info->pSpectCh;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800341
Rachit Kankane2dba6752019-05-20 14:55:31 +0530342 if (scan_list)
343 qdf_list_peek_front(scan_list, &cur_lst);
Abhishek Singhd1cd4ae2019-05-10 11:22:21 +0530344 while (cur_lst) {
345 cur_node = qdf_container_of(cur_lst, struct scan_cache_node,
346 node);
347
Naveen Rawat08db88f2017-09-08 15:07:48 -0700348 temp_ptr = wlan_get_vendor_ie_ptr_from_oui(
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800349 SIR_MAC_QCOM_VENDOR_OUI,
350 SIR_MAC_QCOM_VENDOR_SIZE,
Abhishek Singhd1cd4ae2019-05-10 11:22:21 +0530351 util_scan_entry_ie_data(cur_node->entry),
352 util_scan_entry_ie_len(cur_node->entry));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800353
354 if (temp_ptr) {
355 avoid_ch_ie = (struct sAvoidChannelIE *)temp_ptr;
Will Huang55ba1042017-03-22 10:43:30 +0800356 if (avoid_ch_ie->type !=
357 QCOM_VENDOR_IE_MCC_AVOID_CH) {
Abhishek Singhd1cd4ae2019-05-10 11:22:21 +0530358 qdf_list_peek_next(scan_list,
359 cur_lst, &next_lst);
360 cur_lst = next_lst;
361 next_lst = NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800362 continue;
Will Huang55ba1042017-03-22 10:43:30 +0800363 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800364
365 sap_ctx->sap_detected_avoid_ch_ie.present = 1;
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530366 QDF_TRACE(QDF_MODULE_ID_SAP,
367 QDF_TRACE_LEVEL_DEBUG,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800368 "Q2Q IE - avoid ch %d",
369 avoid_ch_ie->channel);
370 /* add this channel to to_avoid channel list */
371 sap_check_n_add_channel(sap_ctx,
372 avoid_ch_ie->channel);
373 sap_check_n_add_overlapped_chnls(sap_ctx,
374 avoid_ch_ie->channel);
375 /*
376 * Mark weight of these channel present in IE to MAX
377 * so that ACS logic will to avoid thse channels
378 */
379 for (i = 0; i < spect_info->numSpectChans; i++)
380 if (spect_ch[i].chNum == avoid_ch_ie->channel) {
381 /*
382 * weight is set more than max so that,
383 * in the case of other channels being
384 * assigned max weight due to noise,
385 * they may be preferred over channels
386 * with Q2Q IE.
387 */
388 spect_ch[i].weight = SAP_ACS_WEIGHT_MAX + 1;
389 spect_ch[i].weight_copy =
390 SAP_ACS_WEIGHT_MAX + 1;
391 break;
392 }
393 } /* if (temp_ptr) */
Abhishek Singhd1cd4ae2019-05-10 11:22:21 +0530394
395 qdf_list_peek_next(scan_list, cur_lst, &next_lst);
396 cur_lst = next_lst;
397 next_lst = NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800398 }
399}
400#endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
401
402#ifdef FEATURE_WLAN_CH_AVOID
403/*==========================================================================
404 FUNCTION sap_update_unsafe_channel_list
405
406 DESCRIPTION
407 Function Undate unsafe channel list table
408
409 DEPENDENCIES
410 NA.
411
412 IN
413 SapContext pointer
414
415 RETURN VALUE
416 NULL
417 ============================================================================*/
Jeff Johnsonb91e2d92019-03-26 09:51:30 -0700418static void sap_update_unsafe_channel_list(mac_handle_t mac_handle,
419 struct sap_context *sap_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800420{
421 uint16_t i, j;
Amar Singhalb8d4f152016-02-10 10:21:43 -0800422 uint16_t unsafe_channel_list[NUM_CHANNELS];
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800423 uint16_t unsafe_channel_count = 0;
Jeff Johnsonc59ef8b2018-12-02 12:01:21 -0800424 struct mac_context *mac_ctx = NULL;
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -0700425
Yuanyuan Liu0e0aa932016-05-12 10:17:58 -0700426 qdf_device_t qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800427
Yuanyuan Liu97361182016-06-06 09:38:04 -0700428 if (!qdf_ctx) {
429 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_FATAL,
430 "qdf_ctx is NULL");
431 return;
432 }
Jeff Johnsona0619e42018-11-28 17:43:00 -0800433 mac_ctx = MAC_CONTEXT(mac_handle);
Yuanyuan Liu97361182016-06-06 09:38:04 -0700434
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800435 /* Flush, default set all channel safe */
Amar Singhalb8d4f152016-02-10 10:21:43 -0800436 for (i = 0; i < NUM_CHANNELS; i++) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800437 safe_channels[i].isSafe = true;
438 }
439
440 /* Try to find unsafe channel */
Ryan Hsu4252a2f2016-01-05 11:18:24 -0800441#if defined(FEATURE_WLAN_STA_AP_MODE_DFS_DISABLE)
Amar Singhalb8d4f152016-02-10 10:21:43 -0800442 for (i = 0; i < NUM_CHANNELS; i++) {
Jeff Johnsone13d8062017-09-28 06:54:55 -0700443 if (sap_ctx->dfs_ch_disable == true) {
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -0700444 if (wlan_reg_is_dfs_ch(mac_ctx->pdev,
445 safe_channels[i].channelNumber)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800446 safe_channels[i].isSafe = false;
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530447 QDF_TRACE(QDF_MODULE_ID_SAP,
448 QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800449 "%s: DFS Ch %d is not safe in"
450 " Concurrent mode",
451 __func__,
452 safe_channels[i].channelNumber);
453 }
454 }
455 }
456#endif
Yuanyuan Liu0e0aa932016-05-12 10:17:58 -0700457 pld_get_wlan_unsafe_channel(qdf_ctx->dev,
458 unsafe_channel_list,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800459 &unsafe_channel_count,
460 sizeof(unsafe_channel_list));
461
Jingxiang Ge37d878c2019-01-08 14:43:05 +0800462 unsafe_channel_count = QDF_MIN(unsafe_channel_count,
463 (uint16_t)NUM_CHANNELS);
464
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800465 for (i = 0; i < unsafe_channel_count; i++) {
Amar Singhalb8d4f152016-02-10 10:21:43 -0800466 for (j = 0; j < NUM_CHANNELS; j++) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800467 if (safe_channels[j].channelNumber ==
468 unsafe_channel_list[i]) {
469 /* Found unsafe channel, update it */
470 safe_channels[j].isSafe = false;
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530471 QDF_TRACE(QDF_MODULE_ID_SAP,
472 QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800473 FL("CH %d is not safe"),
474 unsafe_channel_list[i]);
475 break;
476 }
477 }
478 }
479
480 return;
481}
Jeff Johnsonb91e2d92019-03-26 09:51:30 -0700482#else
483static void sap_update_unsafe_channel_list(mac_handle_t mac_handle,
484 struct sap_context *sap_ctx)
485{
486}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800487#endif /* FEATURE_WLAN_CH_AVOID */
488
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800489/**
gaoleze5108942017-03-31 16:56:42 +0800490 * sap_channel_in_acs_channel_list() - check if channel in acs channel list
491 * @channel_num: channel to check
492 * @sap_ctx: struct ptSapContext
493 * @spect_info_params: strcut tSapChSelSpectInfo
494 *
495 * This function checks if specified channel is in the configured ACS channel
496 * list.
497 *
498 * Return: channel number if in acs channel list or SAP_CHANNEL_NOT_SELECTED
499 */
gaoleze5108942017-03-31 16:56:42 +0800500uint8_t sap_channel_in_acs_channel_list(uint8_t channel_num,
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -0700501 struct sap_context *sap_ctx,
gaoleze5108942017-03-31 16:56:42 +0800502 tSapChSelSpectInfo *spect_info_params)
503{
504 uint8_t i = 0;
505
Jeff Johnson4cfe6cc2019-03-18 13:40:27 -0700506 if ((!sap_ctx->acs_cfg->ch_list) ||
507 (!spect_info_params))
gaoleze5108942017-03-31 16:56:42 +0800508 return channel_num;
509
510 if (channel_num > 0 && channel_num <= 252) {
511 for (i = 0; i < sap_ctx->acs_cfg->ch_list_count; i++) {
512 if ((sap_ctx->acs_cfg->ch_list[i]) == channel_num)
513 return channel_num;
514 }
515 return SAP_CHANNEL_NOT_SELECTED;
516 } else {
517 return SAP_CHANNEL_NOT_SELECTED;
518 }
519}
520
521/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800522 * sap_select_preferred_channel_from_channel_list() - to calc best cahnnel
523 * @best_chnl: best channel already calculated among all the chanels
524 * @sap_ctx: sap context
525 * @spectinfo_param: Pointer to tSapChSelSpectInfo structure
526 *
527 * This function calculates the best channel among the configured channel list.
528 * If channel list not configured then returns the best channel calculated
529 * among all the channel list.
530 *
531 * Return: uint8_t best channel
532 */
Jeff Johnson464f7ea2016-10-07 10:21:26 -0700533static
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800534uint8_t sap_select_preferred_channel_from_channel_list(uint8_t best_chnl,
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -0700535 struct sap_context *sap_ctx,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800536 tSapChSelSpectInfo *spectinfo_param)
537{
538 uint8_t i = 0;
Jeff Johnsonc59ef8b2018-12-02 12:01:21 -0800539 struct mac_context *mac_ctx = sme_get_mac_context();
Tushnim Bhattacharyya518e80f2017-08-30 17:35:33 -0700540
Jeff Johnson4cfe6cc2019-03-18 13:40:27 -0700541 if (!mac_ctx) {
Tushnim Bhattacharyya518e80f2017-08-30 17:35:33 -0700542 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
543 "pmac Global Context is NULL");
544 return SAP_CHANNEL_NOT_SELECTED;
545 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800546
547 /*
548 * If Channel List is not Configured don't do anything
549 * Else return the Best Channel from the Channel List
550 */
Jeff Johnson4cfe6cc2019-03-18 13:40:27 -0700551 if ((!sap_ctx->acs_cfg->ch_list) ||
552 (!spectinfo_param) ||
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800553 (0 == sap_ctx->acs_cfg->ch_list_count))
554 return best_chnl;
555
556 if (best_chnl <= 0 || best_chnl > 252)
557 return SAP_CHANNEL_NOT_SELECTED;
558
559 /* Select the best channel from allowed list */
560 for (i = 0; i < sap_ctx->acs_cfg->ch_list_count; i++) {
Tushnim Bhattacharyya518e80f2017-08-30 17:35:33 -0700561 if ((sap_ctx->acs_cfg->ch_list[i] == best_chnl) &&
562 !(wlan_reg_is_dfs_ch(mac_ctx->pdev, best_chnl) &&
563 policy_mgr_disallow_mcc(mac_ctx->psoc, best_chnl))) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530564 QDF_TRACE(QDF_MODULE_ID_SAP,
Ravi Joshi9788fcd2018-02-13 15:12:22 -0800565 QDF_TRACE_LEVEL_INFO,
Naveen Rawatbec64d92017-09-13 14:35:21 -0700566 "Best channel so far is: %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800567 best_chnl);
568 return best_chnl;
569 }
570 }
571
572 return SAP_CHANNEL_NOT_SELECTED;
573}
574
Jeff Johnson7730fbb2018-11-08 13:48:27 -0800575/**
576 * sap_chan_sel_init() - Initialize channel select
577 * @mac_handle: Opaque handle to the global MAC context
578 * @pSpectInfoParams: Pointer to tSapChSelSpectInfo structure
579 * @sap_ctx: Pointer to SAP Context
580 *
581 * Function sap_chan_sel_init allocates the memory, initializes the
582 * structures used by the channel selection algorithm
583 *
584 * Return: bool Success or FAIL
585 */
586static bool sap_chan_sel_init(mac_handle_t mac_handle,
Jeff Johnson464f7ea2016-10-07 10:21:26 -0700587 tSapChSelSpectInfo *pSpectInfoParams,
Jeff Johnsone13d8062017-09-28 06:54:55 -0700588 struct sap_context *sap_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800589{
590 tSapSpectChInfo *pSpectCh = NULL;
591 uint8_t *pChans = NULL;
592 uint16_t channelnum = 0;
Jeff Johnsonc59ef8b2018-12-02 12:01:21 -0800593 struct mac_context *mac = MAC_CONTEXT(mac_handle);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800594 bool chSafe = true;
595#ifdef FEATURE_WLAN_CH_AVOID
596 uint16_t i;
597#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800598 bool include_dfs_ch = true;
Himanshu Agarwalfee2e362018-01-18 20:26:35 +0530599 uint8_t chan_num;
Bala Venkatesh2f25c812017-12-15 17:42:12 +0530600 bool sta_sap_scc_on_dfs_chan =
Jeff Johnsonb9794442018-11-22 14:21:08 -0800601 policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan(mac->psoc);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800602
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530603 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, "In %s",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800604 __func__);
605
606 pSpectInfoParams->numSpectChans =
Jeff Johnsonb9794442018-11-22 14:21:08 -0800607 mac->scan.base_channels.numChannels;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800608
609 /* Allocate memory for weight computation of 2.4GHz */
Arif Hussain256cc282018-10-03 14:10:44 -0700610 pSpectCh = qdf_mem_malloc((pSpectInfoParams->numSpectChans) *
611 sizeof(*pSpectCh));
612 if (!pSpectCh)
Srinivas Girigowda74a66d62017-06-21 23:28:25 -0700613 return false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800614
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800615 /* Initialize the pointers in the DfsParams to the allocated memory */
616 pSpectInfoParams->pSpectCh = pSpectCh;
617
Jeff Johnsonb9794442018-11-22 14:21:08 -0800618 pChans = mac->scan.base_channels.channelList;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800619
Ryan Hsu4252a2f2016-01-05 11:18:24 -0800620#if defined(FEATURE_WLAN_STA_AP_MODE_DFS_DISABLE)
Jeff Johnsone13d8062017-09-28 06:54:55 -0700621 if (sap_ctx->dfs_ch_disable == true)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800622 include_dfs_ch = false;
623#endif
Jeff Johnsonb9794442018-11-22 14:21:08 -0800624 if (!mac->mlme_cfg->dfs_cfg.dfs_master_capable ||
Jeff Johnsone13d8062017-09-28 06:54:55 -0700625 ACS_DFS_MODE_DISABLE == sap_ctx->dfs_mode)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800626 include_dfs_ch = false;
627
628 /* Fill the channel number in the spectrum in the operating freq band */
629 for (channelnum = 0;
630 channelnum < pSpectInfoParams->numSpectChans;
Edhar, Mahesh Kumar4f660672015-10-30 11:53:26 +0530631 channelnum++, pChans++, pSpectCh++) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800632 chSafe = true;
633
Himanshu Agarwal052ce252018-06-18 17:18:59 +0530634 pSpectCh->chNum = *pChans;
635 /* Initialise for all channels */
636 pSpectCh->rssiAgr = SOFTAP_MIN_RSSI;
637 /* Initialise 20MHz for all the Channels */
638 pSpectCh->channelWidth = SOFTAP_HT20_CHANNELWIDTH;
639 /* Initialise max ACS weight for all channels */
640 pSpectCh->weight = SAP_ACS_WEIGHT_MAX;
641
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800642 /* check if the channel is in NOL blacklist */
Himanshu Agarwal052ce252018-06-18 17:18:59 +0530643 if (sap_dfs_is_channel_in_nol_list(
644 sap_ctx, *pChans,
645 PHY_SINGLE_CHANNEL_CENTERED)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530646 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800647 "In %s, Ch %d is in NOL list", __func__,
648 *pChans);
649 chSafe = false;
650 continue;
651 }
652
Bala Venkatesh2f25c812017-12-15 17:42:12 +0530653 if (!include_dfs_ch || sta_sap_scc_on_dfs_chan) {
Jeff Johnsonb9794442018-11-22 14:21:08 -0800654 if (wlan_reg_is_dfs_ch(mac->pdev, *pChans)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800655 chSafe = false;
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530656 QDF_TRACE(QDF_MODULE_ID_SAP,
657 QDF_TRACE_LEVEL_INFO_HIGH,
Bala Venkatesh2f25c812017-12-15 17:42:12 +0530658 "In %s, DFS Ch %d not considered for ACS. include_dfs_ch %u, sta_sap_scc_on_dfs_chan %d",
659 __func__, *pChans, include_dfs_ch,
660 sta_sap_scc_on_dfs_chan);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800661 continue;
662 }
663 }
664
665#ifdef FEATURE_WLAN_CH_AVOID
Amar Singhalb8d4f152016-02-10 10:21:43 -0800666 for (i = 0; i < NUM_CHANNELS; i++) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800667 if ((safe_channels[i].channelNumber == *pChans) &&
668 (false == safe_channels[i].isSafe)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530669 QDF_TRACE(QDF_MODULE_ID_SAP,
670 QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800671 "In %s, Ch %d is not safe", __func__,
672 *pChans);
673 chSafe = false;
674 break;
675 }
676 }
677#endif /* FEATURE_WLAN_CH_AVOID */
678
679 /* OFDM rates are not supported on channel 14 */
680 if (*pChans == 14 &&
Jeff Johnsone13d8062017-09-28 06:54:55 -0700681 eCSR_DOT11_MODE_11b != sap_ctx->csr_roamProfile.phyMode) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800682 continue;
683 }
684
Deepthi Gowri48b89332016-08-30 18:43:05 +0530685 /* Skip DSRC channels */
Jeff Johnsonb9794442018-11-22 14:21:08 -0800686 if (wlan_reg_is_dsrc_chan(mac->pdev, *pChans))
Kiran Kumar Lokere1a43bcf2018-05-15 15:51:58 -0700687 continue;
688
lifeng0b46ae52018-12-13 09:42:27 +0800689 if (!mac->mlme_cfg->reg.etsi13_srd_chan_in_master_mode &&
Jeff Johnsonb9794442018-11-22 14:21:08 -0800690 wlan_reg_is_etsi13_srd_chan(mac->pdev, *pChans))
Deepthi Gowri48b89332016-08-30 18:43:05 +0530691 continue;
692
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800693 if (true == chSafe) {
Srinivas Girigowda74a66d62017-06-21 23:28:25 -0700694 pSpectCh->valid = true;
Himanshu Agarwalfee2e362018-01-18 20:26:35 +0530695 for (chan_num = 0; chan_num < sap_ctx->num_of_channel;
696 chan_num++) {
697 if (pSpectCh->chNum !=
698 sap_ctx->channelList[chan_num])
699 continue;
700
701 /*
702 * Initialize ACS weight to 0 for channels
703 * present in sap context scan channel list
704 */
705 pSpectCh->weight = 0;
706 break;
707 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800708 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800709 }
Srinivas Girigowda74a66d62017-06-21 23:28:25 -0700710 return true;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800711}
712
gaoleze5108942017-03-31 16:56:42 +0800713/**
714 * sapweight_rssi_count() - calculates the channel weight due to rssi
Anurag Chouhan6d760662016-02-20 16:05:43 +0530715 and data count(here number of BSS observed)
gaoleze5108942017-03-31 16:56:42 +0800716 * @sap_ctx : Softap context
717 * @rssi : Max signal strength receieved from a BSS for the channel
718 * @count : Number of BSS observed in the channel
719 *
720 * Return: uint32_t Calculated channel weight based on above two
721 */
722static
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -0700723uint32_t sapweight_rssi_count(struct sap_context *sap_ctx, int8_t rssi,
gaoleze5108942017-03-31 16:56:42 +0800724 uint16_t count)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800725{
726 int32_t rssiWeight = 0;
727 int32_t countWeight = 0;
728 uint32_t rssicountWeight = 0;
gaoleze5108942017-03-31 16:56:42 +0800729 uint8_t softap_rssi_weight_cfg, softap_count_weight_cfg;
730 uint8_t softap_rssi_weight_local, softap_count_weight_local;
731
732 softap_rssi_weight_cfg =
733 ACS_WEIGHT_SOFTAP_RSSI_CFG(sap_ctx->auto_channel_select_weight);
734
735 softap_count_weight_cfg =
736 ACS_WEIGHT_SOFTAP_COUNT_CFG(sap_ctx->auto_channel_select_weight);
737
738 softap_rssi_weight_local =
739 ACS_WEIGHT_CFG_TO_LOCAL(sap_ctx->auto_channel_select_weight,
740 softap_rssi_weight_cfg);
741
742 softap_count_weight_local =
743 ACS_WEIGHT_CFG_TO_LOCAL(sap_ctx->auto_channel_select_weight,
744 softap_count_weight_cfg);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800745
746 /* Weight from RSSI */
gaoleze5108942017-03-31 16:56:42 +0800747 rssiWeight = ACS_WEIGHT_COMPUTE(sap_ctx->auto_channel_select_weight,
748 softap_rssi_weight_cfg,
749 rssi - SOFTAP_MIN_RSSI,
750 SOFTAP_MAX_RSSI - SOFTAP_MIN_RSSI);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800751
gaoleze5108942017-03-31 16:56:42 +0800752 if (rssiWeight > softap_rssi_weight_local)
753 rssiWeight = softap_rssi_weight_local;
754
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800755 else if (rssiWeight < 0)
756 rssiWeight = 0;
757
758 /* Weight from data count */
gaoleze5108942017-03-31 16:56:42 +0800759 countWeight = ACS_WEIGHT_COMPUTE(sap_ctx->auto_channel_select_weight,
760 softap_count_weight_cfg,
761 count - SOFTAP_MIN_COUNT,
762 SOFTAP_MAX_COUNT - SOFTAP_MIN_COUNT);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800763
gaoleze5108942017-03-31 16:56:42 +0800764 if (countWeight > softap_count_weight_local)
765 countWeight = softap_count_weight_local;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800766
767 rssicountWeight = rssiWeight + countWeight;
768
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530769 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800770 "In %s, rssiWeight=%d, countWeight=%d, rssicountWeight=%d",
771 __func__, rssiWeight, countWeight, rssicountWeight);
772
773 return rssicountWeight;
774}
775
776/**
gaoleze5108942017-03-31 16:56:42 +0800777 * sap_get_channel_status() - get channel info via channel number
778 * @p_mac: Pointer to Global MAC structure
779 * @channel_id: channel id
780 *
781 * Return: chan status info
782 */
783static struct lim_channel_status *sap_get_channel_status
Jeff Johnsonc59ef8b2018-12-02 12:01:21 -0800784 (struct mac_context *p_mac, uint32_t channel_id)
gaoleze5108942017-03-31 16:56:42 +0800785{
786 return csr_get_channel_status(p_mac, channel_id);
787}
788
789/**
790 * sap_clear_channel_status() - clear chan info
791 * @p_mac: Pointer to Global MAC structure
792 *
793 * Return: none
794 */
Jeff Johnsonc59ef8b2018-12-02 12:01:21 -0800795static void sap_clear_channel_status(struct mac_context *p_mac)
gaoleze5108942017-03-31 16:56:42 +0800796{
797 csr_clear_channel_status(p_mac);
798}
799
800/**
801 * sap_weight_channel_noise_floor() - compute noise floor weight
802 * @sap_ctx: sap context
803 * @chn_stat: Pointer to chan status info
804 *
805 * Return: channel noise floor weight
806 */
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -0700807static uint32_t sap_weight_channel_noise_floor(struct sap_context *sap_ctx,
gaoleze5108942017-03-31 16:56:42 +0800808 struct lim_channel_status
809 *channel_stat)
810{
811 uint32_t noise_floor_weight;
812 uint8_t softap_nf_weight_cfg;
813 uint8_t softap_nf_weight_local;
814
815 softap_nf_weight_cfg =
816 ACS_WEIGHT_SOFTAP_NOISE_FLOOR_CFG
817 (sap_ctx->auto_channel_select_weight);
818
819 softap_nf_weight_local =
820 ACS_WEIGHT_CFG_TO_LOCAL(sap_ctx->auto_channel_select_weight,
821 softap_nf_weight_cfg);
822
Jeff Johnson4cfe6cc2019-03-18 13:40:27 -0700823 if (!channel_stat || channel_stat->channelfreq == 0) {
Srinivas Girigowda80213e52018-01-23 14:51:33 -0800824 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG,
gaoleze5108942017-03-31 16:56:42 +0800825 "In %s, sanity check failed return max weight",
826 __func__);
827 return softap_nf_weight_local;
828 }
829
830 noise_floor_weight = (channel_stat->noise_floor == 0) ? 0 :
831 (ACS_WEIGHT_COMPUTE(
832 sap_ctx->auto_channel_select_weight,
833 softap_nf_weight_cfg,
834 channel_stat->noise_floor -
835 SOFTAP_MIN_NF,
836 SOFTAP_MAX_NF - SOFTAP_MIN_NF));
837
838 if (noise_floor_weight > softap_nf_weight_local)
839 noise_floor_weight = softap_nf_weight_local;
gaoleze5108942017-03-31 16:56:42 +0800840
841 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
842 "In %s, nf=%d, nfwc=%d, nfwl=%d, nfw=%d",
843 __func__, channel_stat->noise_floor,
844 softap_nf_weight_cfg, softap_nf_weight_local,
845 noise_floor_weight);
846
847 return noise_floor_weight;
848}
849
850/**
851 * sap_weight_channel_free() - compute channel free weight
852 * @sap_ctx: sap context
853 * @chn_stat: Pointer to chan status info
854 *
855 * Return: channel free weight
856 */
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -0700857static uint32_t sap_weight_channel_free(struct sap_context *sap_ctx,
gaoleze5108942017-03-31 16:56:42 +0800858 struct lim_channel_status
859 *channel_stat)
860{
861 uint32_t channel_free_weight;
862 uint8_t softap_channel_free_weight_cfg;
863 uint8_t softap_channel_free_weight_local;
864 uint32_t rx_clear_count = 0;
865 uint32_t cycle_count = 0;
866
867 softap_channel_free_weight_cfg =
868 ACS_WEIGHT_SOFTAP_CHANNEL_FREE_CFG
869 (sap_ctx->auto_channel_select_weight);
870
871 softap_channel_free_weight_local =
872 ACS_WEIGHT_CFG_TO_LOCAL(sap_ctx->auto_channel_select_weight,
873 softap_channel_free_weight_cfg);
874
Jeff Johnson4cfe6cc2019-03-18 13:40:27 -0700875 if (!channel_stat || channel_stat->channelfreq == 0) {
Srinivas Girigowda80213e52018-01-23 14:51:33 -0800876 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG,
gaoleze5108942017-03-31 16:56:42 +0800877 "In %s, sanity check failed return max weight",
878 __func__);
879 return softap_channel_free_weight_local;
880 }
881
882 rx_clear_count = channel_stat->rx_clear_count -
883 channel_stat->tx_frame_count -
884 channel_stat->rx_frame_count;
885 cycle_count = channel_stat->cycle_count;
886
887 /* LSH 4, otherwise it is always 0. */
888 channel_free_weight = (cycle_count == 0) ? 0 :
889 (ACS_WEIGHT_COMPUTE(
890 sap_ctx->auto_channel_select_weight,
891 softap_channel_free_weight_cfg,
892 ((rx_clear_count << 8) +
893 (cycle_count >> 1))/cycle_count -
894 (SOFTAP_MIN_CHNFREE << 8),
895 (SOFTAP_MAX_CHNFREE -
896 SOFTAP_MIN_CHNFREE) << 8));
897
898 if (channel_free_weight > softap_channel_free_weight_local)
899 channel_free_weight = softap_channel_free_weight_local;
900
901 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
902 "In %s, rcc=%d, cc=%d, tc=%d, rc=%d, cfwc=%d, cfwl=%d, cfw=%d",
903 __func__, rx_clear_count, cycle_count,
904 channel_stat->tx_frame_count,
905 channel_stat->rx_frame_count,
906 softap_channel_free_weight_cfg,
907 softap_channel_free_weight_local,
908 channel_free_weight);
909
910 return channel_free_weight;
911}
912
913/**
914 * sap_weight_channel_txpwr_range() - compute channel tx power range weight
915 * @sap_ctx: sap context
916 * @chn_stat: Pointer to chan status info
917 *
918 * Return: tx power range weight
919 */
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -0700920static uint32_t sap_weight_channel_txpwr_range(struct sap_context *sap_ctx,
gaoleze5108942017-03-31 16:56:42 +0800921 struct lim_channel_status
922 *channel_stat)
923{
924 uint32_t txpwr_weight_low_speed;
925 uint8_t softap_txpwr_range_weight_cfg;
926 uint8_t softap_txpwr_range_weight_local;
927
928 softap_txpwr_range_weight_cfg =
929 ACS_WEIGHT_SOFTAP_TX_POWER_RANGE_CFG
930 (sap_ctx->auto_channel_select_weight);
931
932 softap_txpwr_range_weight_local =
933 ACS_WEIGHT_CFG_TO_LOCAL(sap_ctx->auto_channel_select_weight,
934 softap_txpwr_range_weight_cfg);
935
Jeff Johnson4cfe6cc2019-03-18 13:40:27 -0700936 if (!channel_stat || channel_stat->channelfreq == 0) {
Srinivas Girigowda80213e52018-01-23 14:51:33 -0800937 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG,
gaoleze5108942017-03-31 16:56:42 +0800938 "In %s, sanity check failed return max weight",
939 __func__);
940 return softap_txpwr_range_weight_local;
941 }
942
943 txpwr_weight_low_speed = (channel_stat->chan_tx_pwr_range == 0) ? 0 :
944 (ACS_WEIGHT_COMPUTE(
945 sap_ctx->auto_channel_select_weight,
946 softap_txpwr_range_weight_cfg,
947 SOFTAP_MAX_TXPWR -
948 channel_stat->chan_tx_pwr_range,
949 SOFTAP_MAX_TXPWR - SOFTAP_MIN_TXPWR));
950
951 if (txpwr_weight_low_speed > softap_txpwr_range_weight_local)
952 txpwr_weight_low_speed = softap_txpwr_range_weight_local;
953
954 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
955 "In %s, tpr=%d, tprwc=%d, tprwl=%d, tprw=%d",
956 __func__, channel_stat->chan_tx_pwr_range,
957 softap_txpwr_range_weight_cfg,
958 softap_txpwr_range_weight_local,
959 txpwr_weight_low_speed);
960
961 return txpwr_weight_low_speed;
962}
963
964/**
965 * sap_weight_channel_txpwr_tput() - compute channel tx power
966 * throughput weight
967 * @sap_ctx: sap context
968 * @chn_stat: Pointer to chan status info
969 *
970 * Return: tx power throughput weight
971 */
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -0700972static uint32_t sap_weight_channel_txpwr_tput(struct sap_context *sap_ctx,
gaoleze5108942017-03-31 16:56:42 +0800973 struct lim_channel_status
974 *channel_stat)
975{
976 uint32_t txpwr_weight_high_speed;
977 uint8_t softap_txpwr_tput_weight_cfg;
978 uint8_t softap_txpwr_tput_weight_local;
979
980 softap_txpwr_tput_weight_cfg =
981 ACS_WEIGHT_SOFTAP_TX_POWER_THROUGHPUT_CFG
982 (sap_ctx->auto_channel_select_weight);
983
984 softap_txpwr_tput_weight_local =
985 ACS_WEIGHT_CFG_TO_LOCAL(sap_ctx->auto_channel_select_weight,
986 softap_txpwr_tput_weight_cfg);
987
Jeff Johnson4cfe6cc2019-03-18 13:40:27 -0700988 if (!channel_stat || channel_stat->channelfreq == 0) {
Srinivas Girigowda80213e52018-01-23 14:51:33 -0800989 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG,
gaoleze5108942017-03-31 16:56:42 +0800990 "In %s, sanity check failed return max weight",
991 __func__);
992 return softap_txpwr_tput_weight_local;
993 }
994
995 txpwr_weight_high_speed = (channel_stat->chan_tx_pwr_throughput == 0)
996 ? 0 : (ACS_WEIGHT_COMPUTE(
997 sap_ctx->auto_channel_select_weight,
998 softap_txpwr_tput_weight_cfg,
999 SOFTAP_MAX_TXPWR -
1000 channel_stat->chan_tx_pwr_throughput,
1001 SOFTAP_MAX_TXPWR - SOFTAP_MIN_TXPWR));
1002
1003 if (txpwr_weight_high_speed > softap_txpwr_tput_weight_local)
1004 txpwr_weight_high_speed = softap_txpwr_tput_weight_local;
1005
1006 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
1007 "In %s, tpt=%d, tptwc=%d, tptwl=%d, tptw=%d",
1008 __func__, channel_stat->chan_tx_pwr_throughput,
1009 softap_txpwr_tput_weight_cfg,
1010 softap_txpwr_tput_weight_local,
1011 txpwr_weight_high_speed);
1012
1013 return txpwr_weight_high_speed;
1014}
1015
1016/**
1017 * sap_weight_channel_status() - compute chan status weight
1018 * @sap_ctx: sap context
1019 * @chn_stat: Pointer to chan status info
1020 *
1021 * Return: chan status weight
1022 */
1023static
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -07001024uint32_t sap_weight_channel_status(struct sap_context *sap_ctx,
gaoleze5108942017-03-31 16:56:42 +08001025 struct lim_channel_status *channel_stat)
1026{
1027 return sap_weight_channel_noise_floor(sap_ctx, channel_stat) +
1028 sap_weight_channel_free(sap_ctx, channel_stat) +
1029 sap_weight_channel_txpwr_range(sap_ctx, channel_stat) +
1030 sap_weight_channel_txpwr_tput(sap_ctx, channel_stat);
1031}
1032
1033/**
Yeshwanth Sriram Guntuka273889e2018-02-16 17:11:46 +05301034 * sap_check_channels_same_band() - Check if two channels belong to same band
1035 * @ch_num1: channel number
1036 * @ch_num2: channel number
1037 *
1038 * Return: true if both channels belong to same band else false
1039 */
1040static bool sap_check_channels_same_band(uint16_t ch_num1, uint16_t ch_num2)
1041{
1042 if ((ch_num1 <= SIR_11B_CHANNEL_END &&
1043 ch_num2 <= SIR_11B_CHANNEL_END) ||
1044 (ch_num1 >= SIR_11A_CHANNEL_BEGIN &&
1045 ch_num2 >= SIR_11A_CHANNEL_BEGIN))
Srinivas Girigowdaeff16d92018-09-12 14:56:29 -07001046 return true;
Yeshwanth Sriram Guntuka273889e2018-02-16 17:11:46 +05301047
1048 return false;
1049}
1050
1051/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001052 * sap_update_rssi_bsscount() - updates bss count and rssi effect.
1053 *
1054 * @pSpectCh: Channel Information
1055 * @offset: Channel Offset
1056 * @sap_24g: Channel is in 2.4G or 5G
Liangwei Dong71ed6502016-10-20 03:40:45 -04001057 * @spectch_start: the start of spect ch array
1058 * @spectch_end: the end of spect ch array
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001059 *
1060 * sap_update_rssi_bsscount updates bss count and rssi effect based
1061 * on the channel offset.
1062 *
1063 * Return: None.
1064 */
1065
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001066static void sap_update_rssi_bsscount(tSapSpectChInfo *pSpectCh, int32_t offset,
Liangwei Dong71ed6502016-10-20 03:40:45 -04001067 bool sap_24g, tSapSpectChInfo *spectch_start,
1068 tSapSpectChInfo *spectch_end)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001069{
1070 tSapSpectChInfo *pExtSpectCh = NULL;
1071 int32_t rssi, rsssi_effect;
1072
1073 pExtSpectCh = (pSpectCh + offset);
Jeff Johnson4cfe6cc2019-03-18 13:40:27 -07001074 if (pExtSpectCh &&
Liangwei Dong71ed6502016-10-20 03:40:45 -04001075 pExtSpectCh >= spectch_start &&
1076 pExtSpectCh < spectch_end) {
Yeshwanth Sriram Guntuka273889e2018-02-16 17:11:46 +05301077 if (!sap_check_channels_same_band(pSpectCh->chNum,
1078 pExtSpectCh->chNum))
1079 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001080 ++pExtSpectCh->bssCount;
1081 switch (offset) {
1082 case -1:
1083 case 1:
1084 rsssi_effect = sap_24g ?
1085 SAP_24GHZ_FIRST_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY :
1086 SAP_SUBBAND1_RSSI_EFFECT_PRIMARY;
1087 break;
1088 case -2:
1089 case 2:
1090 rsssi_effect = sap_24g ?
1091 SAP_24GHZ_SEC_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY :
1092 SAP_SUBBAND2_RSSI_EFFECT_PRIMARY;
1093 break;
1094 case -3:
1095 case 3:
1096 rsssi_effect = sap_24g ?
1097 SAP_24GHZ_THIRD_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY :
1098 SAP_SUBBAND3_RSSI_EFFECT_PRIMARY;
1099 break;
1100 case -4:
1101 case 4:
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001102 rsssi_effect = sap_24g ?
1103 SAP_24GHZ_FOURTH_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY :
1104 SAP_SUBBAND4_RSSI_EFFECT_PRIMARY;
1105 break;
1106 case -5:
1107 case 5:
1108 rsssi_effect = SAP_SUBBAND5_RSSI_EFFECT_PRIMARY;
1109 break;
1110 case -6:
1111 case 6:
1112 rsssi_effect = SAP_SUBBAND6_RSSI_EFFECT_PRIMARY;
1113 break;
1114 case -7:
1115 case 7:
1116 rsssi_effect = SAP_SUBBAND7_RSSI_EFFECT_PRIMARY;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001117 break;
1118 default:
1119 rsssi_effect = 0;
1120 break;
1121 }
1122
1123 rssi = pSpectCh->rssiAgr + rsssi_effect;
1124 if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi))
1125 pExtSpectCh->rssiAgr = rssi;
1126 if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI)
1127 pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI;
1128 }
1129}
1130
1131/**
1132 * sap_upd_chan_spec_params() - sap_upd_chan_spec_params
1133 * updates channel parameters obtained from Beacon
1134 * @pBeaconStruct Beacon strucutre populated by parse_beacon function
1135 * @channelWidth Channel width
1136 * @secondaryChannelOffset Secondary Channel Offset
1137 * @vhtSupport If channel supports VHT
1138 * @centerFreq Central frequency for the given channel.
1139 *
1140 * sap_upd_chan_spec_params updates the spectrum channels based on the
1141 * pBeaconStruct obtained from Beacon IE
1142 *
1143 * Return: NA.
1144 */
1145
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001146static void sap_upd_chan_spec_params(tSirProbeRespBeacon *pBeaconStruct,
1147 uint16_t *channelWidth,
1148 uint16_t *secondaryChannelOffset,
1149 uint16_t *vhtSupport,
1150 uint16_t *centerFreq,
1151 uint16_t *centerFreq_2)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001152{
Jeff Johnson4cfe6cc2019-03-18 13:40:27 -07001153 if (!pBeaconStruct) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301154 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001155 FL("pBeaconStruct is NULL"));
1156 return;
1157 }
1158
1159 if (pBeaconStruct->HTCaps.present && pBeaconStruct->HTInfo.present) {
1160 *channelWidth = pBeaconStruct->HTCaps.supportedChannelWidthSet;
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001161 *secondaryChannelOffset =
1162 pBeaconStruct->HTInfo.secondaryChannelOffset;
1163 if (!pBeaconStruct->VHTOperation.present)
1164 return;
1165 *vhtSupport = pBeaconStruct->VHTOperation.present;
1166 if (pBeaconStruct->VHTOperation.chanWidth) {
1167 *centerFreq =
1168 pBeaconStruct->VHTOperation.chanCenterFreqSeg1;
1169 *centerFreq_2 =
1170 pBeaconStruct->VHTOperation.chanCenterFreqSeg2;
1171 /*
1172 * LHS follows tSirMacHTChannelWidth, while RHS follows
1173 * WNI_CFG_VHT_CHANNEL_WIDTH_X format hence following
1174 * adjustment
1175 */
1176 *channelWidth =
1177 pBeaconStruct->VHTOperation.chanWidth + 1;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001178
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001179 }
1180 }
1181}
1182
1183/**
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001184 * sap_update_rssi_bsscount_vht_5G() - updates bss count and rssi effect.
1185 *
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001186 * @spect_ch: Channel Information
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001187 * @offset: Channel Offset
1188 * @num_ch: no.of channels
Liangwei Dong71ed6502016-10-20 03:40:45 -04001189 * @spectch_start: the start of spect ch array
1190 * @spectch_end: the end of spect ch array
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001191 *
1192 * sap_update_rssi_bsscount_vht_5G updates bss count and rssi effect based
1193 * on the channel offset.
1194 *
1195 * Return: None.
1196 */
1197
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001198static void sap_update_rssi_bsscount_vht_5G(tSapSpectChInfo *spect_ch,
1199 int32_t offset,
Liangwei Dong71ed6502016-10-20 03:40:45 -04001200 uint16_t num_ch,
1201 tSapSpectChInfo *spectch_start,
1202 tSapSpectChInfo *spectch_end)
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001203{
1204 int32_t ch_offset;
1205 uint16_t i, cnt;
1206
1207 if (!offset)
1208 return;
1209 if (offset > 0)
1210 cnt = num_ch;
1211 else
1212 cnt = num_ch + 1;
1213 for (i = 0; i < cnt; i++) {
1214 ch_offset = offset + i;
1215 if (ch_offset == 0)
1216 continue;
Liangwei Dong71ed6502016-10-20 03:40:45 -04001217 sap_update_rssi_bsscount(spect_ch, ch_offset, false,
1218 spectch_start, spectch_end);
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001219 }
1220}
1221/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001222 * sap_interference_rssi_count_5G() - sap_interference_rssi_count
1223 * considers the Adjacent channel rssi and
1224 * data count(here number of BSS observed)
1225 * @spect_ch: Channel Information
1226 * @chan_width: Channel width parsed from beacon IE
1227 * @sec_chan_offset: Secondary Channel Offset
1228 * @center_freq: Central frequency for the given channel.
1229 * @channel_id: channel_id
Liangwei Dong71ed6502016-10-20 03:40:45 -04001230 * @spectch_start: the start of spect ch array
1231 * @spectch_end: the end of spect ch array
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001232 *
1233 * sap_interference_rssi_count_5G considers the Adjacent channel rssi
1234 * and data count(here number of BSS observed)
1235 *
1236 * Return: NA.
1237 */
1238
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001239static void sap_interference_rssi_count_5G(tSapSpectChInfo *spect_ch,
1240 uint16_t chan_width,
1241 uint16_t sec_chan_offset,
1242 uint16_t center_freq,
1243 uint16_t center_freq_2,
Liangwei Dong71ed6502016-10-20 03:40:45 -04001244 uint8_t channel_id,
1245 tSapSpectChInfo *spectch_start,
1246 tSapSpectChInfo *spectch_end)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001247{
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001248 uint16_t num_ch;
1249 int32_t offset = 0;
Srinivas Girigowda4d65ebe2017-10-13 21:41:42 -07001250
Jeff Johnson4cfe6cc2019-03-18 13:40:27 -07001251 if (!spect_ch) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301252 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001253 FL("spect_ch is NULL"));
1254 return;
1255 }
1256
1257 /* Updating the received ChannelWidth */
1258 if (spect_ch->channelWidth != chan_width)
1259 spect_ch->channelWidth = chan_width;
1260 /* If received ChannelWidth is other than HT20,
1261 * we need to update the extension channel Params as well
1262 * chan_width == 0, HT20
1263 * chan_width == 1, HT40
1264 * chan_width == 2, VHT80
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001265 * chan_width == 3, VHT160
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001266 */
1267
1268 switch (spect_ch->channelWidth) {
1269 case eHT_CHANNEL_WIDTH_40MHZ: /* HT40 */
1270 switch (sec_chan_offset) {
1271 /* Above the Primary Channel */
1272 case PHY_DOUBLE_CHANNEL_LOW_PRIMARY:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001273 sap_update_rssi_bsscount(spect_ch, 1, false,
1274 spectch_start, spectch_end);
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001275 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001276
1277 /* Below the Primary channel */
1278 case PHY_DOUBLE_CHANNEL_HIGH_PRIMARY:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001279 sap_update_rssi_bsscount(spect_ch, -1, false,
1280 spectch_start, spectch_end);
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001281 return;
1282 }
1283 return;
1284 case eHT_CHANNEL_WIDTH_80MHZ: /* VHT80 */
1285 num_ch = 3;
1286 if ((center_freq - channel_id) == 6) {
1287 offset = 1;
1288 } else if ((center_freq - channel_id) == 2) {
1289 offset = -1;
1290 } else if ((center_freq - channel_id) == -2) {
1291 offset = -2;
1292 } else if ((center_freq - channel_id) == -6) {
1293 offset = -3;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001294 }
1295 break;
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001296 case eHT_CHANNEL_WIDTH_160MHZ: /* VHT160 */
1297 num_ch = 7;
1298 if ((center_freq - channel_id) == 14)
1299 offset = 1;
1300 else if ((center_freq - channel_id) == 10)
1301 offset = -1;
1302 else if ((center_freq - channel_id) == 6)
1303 offset = -2;
1304 else if ((center_freq - channel_id) == 2)
1305 offset = -3;
1306 else if ((center_freq - channel_id) == -2)
1307 offset = -4;
1308 else if ((center_freq - channel_id) == -6)
1309 offset = -5;
1310 else if ((center_freq - channel_id) == -10)
1311 offset = -6;
1312 else if ((center_freq - channel_id) == -14)
1313 offset = -7;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001314 break;
1315 default:
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001316 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001317 }
Liangwei Dong71ed6502016-10-20 03:40:45 -04001318 sap_update_rssi_bsscount_vht_5G(spect_ch, offset, num_ch,
1319 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001320}
1321
1322/**
1323 * sap_interference_rssi_count() - sap_interference_rssi_count
1324 * considers the Adjacent channel rssi
1325 * and data count(here number of BSS observed)
1326 * @spect_ch Channel Information
Liangwei Dong71ed6502016-10-20 03:40:45 -04001327 * @spectch_start: the start of spect ch array
1328 * @spectch_end: the end of spect ch array
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001329 *
1330 * sap_interference_rssi_count considers the Adjacent channel rssi
1331 * and data count(here number of BSS observed)
1332 *
1333 * Return: None.
1334 */
1335
Liangwei Dong71ed6502016-10-20 03:40:45 -04001336static void sap_interference_rssi_count(tSapSpectChInfo *spect_ch,
1337 tSapSpectChInfo *spectch_start,
1338 tSapSpectChInfo *spectch_end)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001339{
Jeff Johnson4cfe6cc2019-03-18 13:40:27 -07001340 if (!spect_ch) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301341 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001342 "%s: spect_ch is NULL", __func__);
1343 return;
1344 }
1345
1346 switch (spect_ch->chNum) {
1347 case CHANNEL_1:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001348 sap_update_rssi_bsscount(spect_ch, 1, true,
1349 spectch_start, spectch_end);
1350 sap_update_rssi_bsscount(spect_ch, 2, true,
1351 spectch_start, spectch_end);
1352 sap_update_rssi_bsscount(spect_ch, 3, true,
1353 spectch_start, spectch_end);
1354 sap_update_rssi_bsscount(spect_ch, 4, true,
1355 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001356 break;
1357
1358 case CHANNEL_2:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001359 sap_update_rssi_bsscount(spect_ch, -1, 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, 2, true,
1364 spectch_start, spectch_end);
1365 sap_update_rssi_bsscount(spect_ch, 3, true,
1366 spectch_start, spectch_end);
1367 sap_update_rssi_bsscount(spect_ch, 4, true,
1368 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001369 break;
1370 case CHANNEL_3:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001371 sap_update_rssi_bsscount(spect_ch, -2, true,
1372 spectch_start, spectch_end);
1373 sap_update_rssi_bsscount(spect_ch, -1, true,
1374 spectch_start, spectch_end);
1375 sap_update_rssi_bsscount(spect_ch, 1, true,
1376 spectch_start, spectch_end);
1377 sap_update_rssi_bsscount(spect_ch, 2, true,
1378 spectch_start, spectch_end);
1379 sap_update_rssi_bsscount(spect_ch, 3, true,
1380 spectch_start, spectch_end);
1381 sap_update_rssi_bsscount(spect_ch, 4, true,
1382 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001383 break;
1384 case CHANNEL_4:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001385 sap_update_rssi_bsscount(spect_ch, -3, true,
1386 spectch_start, spectch_end);
1387 sap_update_rssi_bsscount(spect_ch, -2, true,
1388 spectch_start, spectch_end);
1389 sap_update_rssi_bsscount(spect_ch, -1, true,
1390 spectch_start, spectch_end);
1391 sap_update_rssi_bsscount(spect_ch, 1, true,
1392 spectch_start, spectch_end);
1393 sap_update_rssi_bsscount(spect_ch, 2, true,
1394 spectch_start, spectch_end);
1395 sap_update_rssi_bsscount(spect_ch, 3, true,
1396 spectch_start, spectch_end);
1397 sap_update_rssi_bsscount(spect_ch, 4, true,
1398 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001399 break;
1400
1401 case CHANNEL_5:
1402 case CHANNEL_6:
1403 case CHANNEL_7:
1404 case CHANNEL_8:
1405 case CHANNEL_9:
1406 case CHANNEL_10:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001407 sap_update_rssi_bsscount(spect_ch, -4, true,
1408 spectch_start, spectch_end);
1409 sap_update_rssi_bsscount(spect_ch, -3, true,
1410 spectch_start, spectch_end);
1411 sap_update_rssi_bsscount(spect_ch, -2, true,
1412 spectch_start, spectch_end);
1413 sap_update_rssi_bsscount(spect_ch, -1, true,
1414 spectch_start, spectch_end);
1415 sap_update_rssi_bsscount(spect_ch, 1, true,
1416 spectch_start, spectch_end);
1417 sap_update_rssi_bsscount(spect_ch, 2, true,
1418 spectch_start, spectch_end);
1419 sap_update_rssi_bsscount(spect_ch, 3, true,
1420 spectch_start, spectch_end);
1421 sap_update_rssi_bsscount(spect_ch, 4, true,
1422 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001423 break;
1424
1425 case CHANNEL_11:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001426 sap_update_rssi_bsscount(spect_ch, -4, true,
1427 spectch_start, spectch_end);
1428 sap_update_rssi_bsscount(spect_ch, -3, true,
1429 spectch_start, spectch_end);
1430 sap_update_rssi_bsscount(spect_ch, -2, true,
1431 spectch_start, spectch_end);
1432 sap_update_rssi_bsscount(spect_ch, -1, true,
1433 spectch_start, spectch_end);
1434 sap_update_rssi_bsscount(spect_ch, 1, true,
1435 spectch_start, spectch_end);
1436 sap_update_rssi_bsscount(spect_ch, 2, true,
1437 spectch_start, spectch_end);
1438 sap_update_rssi_bsscount(spect_ch, 3, true,
1439 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001440 break;
1441
1442 case CHANNEL_12:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001443 sap_update_rssi_bsscount(spect_ch, -4, true,
1444 spectch_start, spectch_end);
1445 sap_update_rssi_bsscount(spect_ch, -3, true,
1446 spectch_start, spectch_end);
1447 sap_update_rssi_bsscount(spect_ch, -2, true,
1448 spectch_start, spectch_end);
1449 sap_update_rssi_bsscount(spect_ch, -1, true,
1450 spectch_start, spectch_end);
1451 sap_update_rssi_bsscount(spect_ch, 1, true,
1452 spectch_start, spectch_end);
1453 sap_update_rssi_bsscount(spect_ch, 2, true,
1454 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001455 break;
1456
1457 case CHANNEL_13:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001458 sap_update_rssi_bsscount(spect_ch, -4, true,
1459 spectch_start, spectch_end);
1460 sap_update_rssi_bsscount(spect_ch, -3, true,
1461 spectch_start, spectch_end);
1462 sap_update_rssi_bsscount(spect_ch, -2, true,
1463 spectch_start, spectch_end);
1464 sap_update_rssi_bsscount(spect_ch, -1, true,
1465 spectch_start, spectch_end);
1466 sap_update_rssi_bsscount(spect_ch, 1, true,
1467 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001468 break;
1469
1470 case CHANNEL_14:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001471 sap_update_rssi_bsscount(spect_ch, -4, true,
1472 spectch_start, spectch_end);
1473 sap_update_rssi_bsscount(spect_ch, -3, true,
1474 spectch_start, spectch_end);
1475 sap_update_rssi_bsscount(spect_ch, -2, true,
1476 spectch_start, spectch_end);
1477 sap_update_rssi_bsscount(spect_ch, -1, true,
1478 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001479 break;
1480
1481 default:
1482 break;
1483 }
1484}
1485
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001486/**
1487 * ch_in_pcl() - Is channel in the Preferred Channel List (PCL)
1488 * @sap_ctx: SAP context which contains the current PCL
1489 * @channel: Input channel number to be checked
1490 *
1491 * Check if a channel is in the preferred channel list
1492 *
1493 * Return:
1494 * true: channel is in PCL,
1495 * false: channel is not in PCL
1496 */
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -07001497static bool ch_in_pcl(struct sap_context *sap_ctx, uint8_t channel)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001498{
1499 uint32_t i;
1500
1501 for (i = 0; i < sap_ctx->acs_cfg->pcl_ch_count; i++) {
1502 if (channel == sap_ctx->acs_cfg->pcl_channels[i])
1503 return true;
1504 }
1505
1506 return false;
1507}
1508
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001509/**
1510 * sap_compute_spect_weight() - Compute spectrum weight
1511 * @pSpectInfoParams: Pointer to the tSpectInfoParams structure
Jeff Johnson7730fbb2018-11-08 13:48:27 -08001512 * @mac_handle: Opaque handle to the global MAC context
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001513 * @pResult: Pointer to tScanResultHandle
1514 * @sap_ctx: Context of the SAP
1515 *
1516 * Main function for computing the weight of each channel in the
1517 * spectrum based on the RSSI value of the BSSes on the channel
1518 * and number of BSS
1519 */
1520static void sap_compute_spect_weight(tSapChSelSpectInfo *pSpectInfoParams,
Jeff Johnson7730fbb2018-11-08 13:48:27 -08001521 mac_handle_t mac_handle,
Abhishek Singhd1cd4ae2019-05-10 11:22:21 +05301522 qdf_list_t *scan_list,
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -07001523 struct sap_context *sap_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001524{
1525 int8_t rssi = 0;
1526 uint8_t chn_num = 0;
1527 uint8_t channel_id = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001528 tSapSpectChInfo *pSpectCh = pSpectInfoParams->pSpectCh;
1529 uint32_t operatingBand;
1530 uint16_t channelWidth;
1531 uint16_t secondaryChannelOffset;
1532 uint16_t centerFreq;
gaurank kathpalia859c9362018-08-02 23:07:21 +05301533 uint8_t i;
1534 bool found;
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001535 uint16_t centerFreq_2 = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001536 uint16_t vhtSupport;
Abhishek Singhd1cd4ae2019-05-10 11:22:21 +05301537 tSirProbeRespBeacon *bcn_struct;
Jeff Johnsonc59ef8b2018-12-02 12:01:21 -08001538 struct mac_context *mac = MAC_CONTEXT(mac_handle);
Liangwei Dong71ed6502016-10-20 03:40:45 -04001539 tSapSpectChInfo *spectch_start = pSpectInfoParams->pSpectCh;
1540 tSapSpectChInfo *spectch_end = pSpectInfoParams->pSpectCh +
1541 pSpectInfoParams->numSpectChans;
Abhishek Singhd1cd4ae2019-05-10 11:22:21 +05301542 qdf_list_node_t *cur_lst = NULL, *next_lst = NULL;
1543 struct scan_cache_node *cur_node = NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001544
Abhishek Singhd1cd4ae2019-05-10 11:22:21 +05301545 bcn_struct = qdf_mem_malloc(sizeof(tSirProbeRespBeacon));
1546 if (!bcn_struct)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001547 return;
Arif Hussain256cc282018-10-03 14:10:44 -07001548
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301549 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001550 "In %s, Computing spectral weight", __func__);
1551
1552 /**
1553 * Soft AP specific channel weight calculation using DFS formula
1554 */
1555 SET_ACS_BAND(operatingBand, sap_ctx);
1556
Rachit Kankane2dba6752019-05-20 14:55:31 +05301557 if (scan_list)
1558 qdf_list_peek_front(scan_list, &cur_lst);
Abhishek Singhd1cd4ae2019-05-10 11:22:21 +05301559 while (cur_lst) {
1560 uint32_t ie_len = 0;
1561 uint8_t *ie_ptr;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001562
Abhishek Singhd1cd4ae2019-05-10 11:22:21 +05301563 cur_node = qdf_container_of(cur_lst, struct scan_cache_node,
1564 node);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001565 pSpectCh = pSpectInfoParams->pSpectCh;
1566 /* Defining the default values, so that any value will hold the default values */
1567 channelWidth = eHT_CHANNEL_WIDTH_20MHZ;
1568 secondaryChannelOffset = PHY_SINGLE_CHANNEL_CENTERED;
1569 vhtSupport = 0;
1570 centerFreq = 0;
1571
Abhishek Singhd1cd4ae2019-05-10 11:22:21 +05301572 ie_len = util_scan_entry_ie_len(cur_node->entry);
1573 ie_ptr = util_scan_entry_ie_data(cur_node->entry);
1574 qdf_mem_zero((uint8_t *)bcn_struct,
1575 sizeof(tSirProbeRespBeacon));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001576
Abhishek Singhd1cd4ae2019-05-10 11:22:21 +05301577 if ((sir_parse_beacon_ie(mac, bcn_struct, ie_ptr, ie_len)) ==
1578 QDF_STATUS_SUCCESS)
Yingying Tang22facc12016-10-20 17:43:59 +08001579 sap_upd_chan_spec_params(
Abhishek Singhd1cd4ae2019-05-10 11:22:21 +05301580 bcn_struct,
Yingying Tang22facc12016-10-20 17:43:59 +08001581 &channelWidth,
1582 &secondaryChannelOffset,
1583 &vhtSupport, &centerFreq,
1584 &centerFreq_2);
1585
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001586 /* Processing for each tCsrScanResultInfo in the tCsrScanResult DLink list */
1587 for (chn_num = 0; chn_num < pSpectInfoParams->numSpectChans;
1588 chn_num++) {
1589
Abhishek Singhd1cd4ae2019-05-10 11:22:21 +05301590 channel_id =
1591 util_scan_entry_channel_num(cur_node->entry);
Himanshu Agarwalcf5b8932018-07-02 18:06:49 +05301592
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001593 if (pSpectCh && (channel_id == pSpectCh->chNum)) {
1594 if (pSpectCh->rssiAgr <
Abhishek Singhd1cd4ae2019-05-10 11:22:21 +05301595 cur_node->entry->rssi_raw)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001596 pSpectCh->rssiAgr =
Abhishek Singhd1cd4ae2019-05-10 11:22:21 +05301597 cur_node->entry->rssi_raw;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001598
1599 ++pSpectCh->bssCount; /* Increment the count of BSS */
1600
1601 /*
1602 * Connsidering the Extension Channel
1603 * only in a channels
1604 */
1605 switch (operatingBand) {
1606 case eCSR_DOT11_MODE_11a:
1607 sap_interference_rssi_count_5G(
1608 pSpectCh, channelWidth,
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001609 secondaryChannelOffset,
1610 centerFreq,
1611 centerFreq_2,
Liangwei Dong71ed6502016-10-20 03:40:45 -04001612 channel_id,
1613 spectch_start,
1614 spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001615 break;
1616
1617 case eCSR_DOT11_MODE_11g:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001618 sap_interference_rssi_count(pSpectCh,
1619 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001620 break;
1621
1622 case eCSR_DOT11_MODE_abg:
Himanshu Agarwal4f503b82018-03-19 12:10:45 +05301623 if (pSpectCh->chNum >=
1624 SIR_11A_CHANNEL_BEGIN)
1625 sap_interference_rssi_count_5G(
1626 pSpectCh, channelWidth,
1627 secondaryChannelOffset,
1628 centerFreq,
1629 centerFreq_2,
1630 channel_id,
1631 spectch_start,
1632 spectch_end);
1633 else
1634 sap_interference_rssi_count(
1635 pSpectCh,
1636 spectch_start,
1637 spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001638 break;
1639 }
1640
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301641 QDF_TRACE(QDF_MODULE_ID_SAP,
1642 QDF_TRACE_LEVEL_INFO_HIGH,
Abhishek Singhd1cd4ae2019-05-10 11:22:21 +05301643 "In %s, channel_id=%d, bssdes.rssi=%d, SpectCh.bssCount=%d, ChannelWidth %d, secondaryChanOffset %d, center frequency %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001644 __func__,
Abhishek Singhd1cd4ae2019-05-10 11:22:21 +05301645 channel_id,
1646 cur_node->entry->rssi_raw,
1647 pSpectCh->bssCount,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001648 pSpectCh->channelWidth,
1649 secondaryChannelOffset, centerFreq);
1650 pSpectCh++;
1651 break;
1652 } else {
1653 pSpectCh++;
1654 }
1655 }
1656
Abhishek Singhd1cd4ae2019-05-10 11:22:21 +05301657 qdf_list_peek_next(scan_list, cur_lst, &next_lst);
1658 cur_lst = next_lst;
1659 next_lst = NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001660 }
1661
Abhishek Singhd1cd4ae2019-05-10 11:22:21 +05301662 qdf_mem_free(bcn_struct);
1663
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001664 /* Calculate the weights for all channels in the spectrum pSpectCh */
1665 pSpectCh = pSpectInfoParams->pSpectCh;
1666
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301667 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001668 "In %s, Spectrum Channels Weight", __func__);
1669
1670 for (chn_num = 0; chn_num < (pSpectInfoParams->numSpectChans);
1671 chn_num++) {
1672
1673 /*
1674 rssi : Maximum received signal strength among all BSS on that channel
1675 bssCount : Number of BSS on that channel
1676 */
1677
1678 rssi = (int8_t) pSpectCh->rssiAgr;
Himanshu Agarwal3697f942018-06-13 14:04:26 +05301679 if (ch_in_pcl(sap_ctx, pSpectCh->chNum))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001680 rssi -= PCL_RSSI_DISCOUNT;
1681
Himanshu Agarwal3697f942018-06-13 14:04:26 +05301682 if (rssi < SOFTAP_MIN_RSSI)
1683 rssi = SOFTAP_MIN_RSSI;
1684
hqub6441f22018-08-09 16:15:31 +08001685 if (pSpectCh->weight == SAP_ACS_WEIGHT_MAX) {
1686 pSpectCh->weight_copy = pSpectCh->weight;
Himanshu Agarwalfee2e362018-01-18 20:26:35 +05301687 goto debug_info;
hqub6441f22018-08-09 16:15:31 +08001688 }
Himanshu Agarwalfee2e362018-01-18 20:26:35 +05301689
gaurank kathpalia859c9362018-08-02 23:07:21 +05301690 /* There may be channels in scanlist, which were not sent to
1691 * FW for scanning as part of ACS scan list, but they do have an
1692 * effect on the neighbouring channels, so they help to find a
1693 * suitable channel, but there weight should be max as they were
1694 * and not meant to be included in the ACS scan results.
1695 * So just assign RSSI as -100, bsscount as 0, and weight as max
1696 * to them, so that they always stay low in sorting of best
1697 * channles which were included in ACS scan list
1698 */
1699 found = false;
1700 for (i = 0; i < sap_ctx->num_of_channel; i++) {
1701 if (pSpectCh->chNum == sap_ctx->channelList[i]) {
1702 /* Scan channel was included in ACS scan list */
1703 found = true;
1704 break;
1705 }
1706 }
1707
1708 if (found)
1709 pSpectCh->weight =
1710 SAPDFS_NORMALISE_1000 *
1711 (sapweight_rssi_count(sap_ctx, rssi,
1712 pSpectCh->bssCount) + sap_weight_channel_status(
Jeff Johnsonb9794442018-11-22 14:21:08 -08001713 sap_ctx, sap_get_channel_status(mac,
gaoleze5108942017-03-31 16:56:42 +08001714 pSpectCh->chNum)));
gaurank kathpalia859c9362018-08-02 23:07:21 +05301715 else {
1716 pSpectCh->weight = SAP_ACS_WEIGHT_MAX;
1717 pSpectCh->rssiAgr = SOFTAP_MIN_RSSI;
1718 rssi = SOFTAP_MIN_RSSI;
1719 pSpectCh->bssCount = SOFTAP_MIN_COUNT;
1720 }
1721
gaoleze5108942017-03-31 16:56:42 +08001722 if (pSpectCh->weight > SAP_ACS_WEIGHT_MAX)
1723 pSpectCh->weight = SAP_ACS_WEIGHT_MAX;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001724 pSpectCh->weight_copy = pSpectCh->weight;
1725
Himanshu Agarwalfee2e362018-01-18 20:26:35 +05301726debug_info:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001727 /* ------ Debug Info ------ */
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301728 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Himanshu Agarwal3697f942018-06-13 14:04:26 +05301729 "In %s, Chan=%d Weight= %d rssiAgr=%d rssi_pcl_discount: %d bssCount=%d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001730 __func__, pSpectCh->chNum, pSpectCh->weight,
Himanshu Agarwal3697f942018-06-13 14:04:26 +05301731 pSpectCh->rssiAgr, rssi, pSpectCh->bssCount);
wadesongcb0ded22018-02-02 17:57:20 +08001732 host_log_acs_chan_spect_weight(pSpectCh->chNum,
1733 (uint16_t)pSpectCh->weight,
1734 pSpectCh->rssiAgr,
1735 pSpectCh->bssCount);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001736 /* ------ Debug Info ------ */
1737 pSpectCh++;
1738 }
Jeff Johnsonb9794442018-11-22 14:21:08 -08001739 sap_clear_channel_status(mac);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001740}
1741
1742/*==========================================================================
1743 FUNCTION sap_chan_sel_exit
1744
1745 DESCRIPTION
1746 Exit function for free out the allocated memory, to be called
1747 at the end of the dfsSelectChannel function
1748
1749 DEPENDENCIES
1750 NA.
1751
1752 PARAMETERS
1753
1754 IN
1755 pSpectInfoParams : Pointer to the tSapChSelSpectInfo structure
1756
1757 RETURN VALUE
1758 void : NULL
1759
1760 SIDE EFFECTS
1761 ============================================================================*/
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001762static void sap_chan_sel_exit(tSapChSelSpectInfo *pSpectInfoParams)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001763{
1764 /* Free all the allocated memory */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301765 qdf_mem_free(pSpectInfoParams->pSpectCh);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001766}
1767
1768/*==========================================================================
1769 FUNCTION sap_sort_chl_weight
1770
1771 DESCRIPTION
Jeff Johnsonc7e4d162018-05-12 16:20:34 -07001772 Function to sort the channels with the least weight first for 20MHz channels
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001773
1774 DEPENDENCIES
1775 NA.
1776
1777 PARAMETERS
1778
1779 IN
1780 pSpectInfoParams : Pointer to the tSapChSelSpectInfo structure
1781
1782 RETURN VALUE
1783 void : NULL
1784
1785 SIDE EFFECTS
1786 ============================================================================*/
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001787static void sap_sort_chl_weight(tSapChSelSpectInfo *pSpectInfoParams)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001788{
1789 tSapSpectChInfo temp;
1790
1791 tSapSpectChInfo *pSpectCh = NULL;
1792 uint32_t i = 0, j = 0, minWeightIndex = 0;
1793
1794 pSpectCh = pSpectInfoParams->pSpectCh;
1795 for (i = 0; i < pSpectInfoParams->numSpectChans; i++) {
1796 minWeightIndex = i;
1797 for (j = i + 1; j < pSpectInfoParams->numSpectChans; j++) {
1798 if (pSpectCh[j].weight <
1799 pSpectCh[minWeightIndex].weight) {
1800 minWeightIndex = j;
Yeshwanth Sriram Guntuka273889e2018-02-16 17:11:46 +05301801 } else if (pSpectCh[j].weight ==
1802 pSpectCh[minWeightIndex].weight) {
1803 if (pSpectCh[j].bssCount <
1804 pSpectCh[minWeightIndex].bssCount)
1805 minWeightIndex = j;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001806 }
1807 }
1808 if (minWeightIndex != i) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301809 qdf_mem_copy(&temp, &pSpectCh[minWeightIndex],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001810 sizeof(*pSpectCh));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301811 qdf_mem_copy(&pSpectCh[minWeightIndex], &pSpectCh[i],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001812 sizeof(*pSpectCh));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301813 qdf_mem_copy(&pSpectCh[i], &temp, sizeof(*pSpectCh));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001814 }
1815 }
1816}
1817
1818/**
Jeff Johnsonc7e4d162018-05-12 16:20:34 -07001819 * set_ht80_chl_bit() - to set available channel to ht80 channel bitmap
bingse2782382017-03-23 10:34:52 +08001820 * @channel_bitmap: Pointer to the chan_bonding_bitmap structure
1821 * @spect_info_params: Pointer to the tSapChSelSpectInfo structure
1822 *
1823 * Return: none
1824 */
1825static void set_ht80_chl_bit(chan_bonding_bitmap *channel_bitmap,
1826 tSapChSelSpectInfo *spec_info_params)
1827{
1828 uint8_t i, j;
1829 tSapSpectChInfo *spec_info;
1830 int start_channel = 0;
1831
1832 channel_bitmap->chanBondingSet[0].startChannel =
1833 acs_ht80_channels[0].chStartNum;
1834 channel_bitmap->chanBondingSet[1].startChannel =
1835 acs_ht80_channels[1].chStartNum;
1836 channel_bitmap->chanBondingSet[2].startChannel =
1837 acs_ht80_channels[2].chStartNum;
1838 channel_bitmap->chanBondingSet[3].startChannel =
1839 acs_ht80_channels[3].chStartNum;
1840 channel_bitmap->chanBondingSet[4].startChannel =
1841 acs_ht80_channels[4].chStartNum;
1842 channel_bitmap->chanBondingSet[5].startChannel =
1843 acs_ht80_channels[5].chStartNum;
1844
1845 spec_info = spec_info_params->pSpectCh;
1846 for (j = 0; j < spec_info_params->numSpectChans; j++) {
1847 for (i = 0; i < MAX_80MHZ_BANDS; i++) {
1848 start_channel =
1849 channel_bitmap->chanBondingSet[i].startChannel;
1850 if (spec_info[j].chNum >= start_channel &&
1851 (spec_info[j].chNum <= start_channel + 12)) {
1852 channel_bitmap->chanBondingSet[i].channelMap |=
1853 1 << ((spec_info[j].chNum -
1854 start_channel)/4);
1855 break;
1856 }
1857 }
1858 }
1859}
1860
1861/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001862 * sap_sort_chl_weight_ht80() - to sort the channels with the least weight
1863 * @pSpectInfoParams: Pointer to the tSapChSelSpectInfo structure
1864 *
Jeff Johnsonc7e4d162018-05-12 16:20:34 -07001865 * Function to sort the channels with the least weight first for HT80 channels
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001866 *
1867 * Return: none
1868 */
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001869static void sap_sort_chl_weight_ht80(tSapChSelSpectInfo *pSpectInfoParams)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001870{
1871 uint8_t i, j, n;
1872 tSapSpectChInfo *pSpectInfo;
1873 uint8_t minIdx;
bingse2782382017-03-23 10:34:52 +08001874 int start_channel = 0;
1875 chan_bonding_bitmap *channel_bitmap;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001876
bingse2782382017-03-23 10:34:52 +08001877 channel_bitmap = qdf_mem_malloc(sizeof(chan_bonding_bitmap));
Arif Hussain256cc282018-10-03 14:10:44 -07001878 if (!channel_bitmap)
bingse2782382017-03-23 10:34:52 +08001879 return;
Arif Hussain256cc282018-10-03 14:10:44 -07001880
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001881 pSpectInfo = pSpectInfoParams->pSpectCh;
1882 /* for each HT80 channel, calculate the combined weight of the
1883 four 20MHz weight */
1884 for (i = 0; i < ARRAY_SIZE(acs_ht80_channels); i++) {
1885 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
1886 if (pSpectInfo[j].chNum ==
1887 acs_ht80_channels[i].chStartNum)
1888 break;
1889 }
1890 if (j == pSpectInfoParams->numSpectChans)
1891 continue;
1892
1893 if (!(((pSpectInfo[j].chNum + 4) == pSpectInfo[j + 1].chNum) &&
1894 ((pSpectInfo[j].chNum + 8) ==
1895 pSpectInfo[j + 2].chNum) &&
1896 ((pSpectInfo[j].chNum + 12) ==
1897 pSpectInfo[j + 3].chNum))) {
1898 /*
1899 * some channels does not exist in pSectInfo array,
1900 * skip this channel and those in the same HT80 width
1901 */
1902 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 4;
1903 if ((pSpectInfo[j].chNum + 4) ==
1904 pSpectInfo[j + 1].chNum)
1905 pSpectInfo[j + 1].weight =
1906 SAP_ACS_WEIGHT_MAX * 4;
1907 if ((pSpectInfo[j].chNum + 8) ==
1908 pSpectInfo[j + 2].chNum)
1909 pSpectInfo[j + 2].weight =
1910 SAP_ACS_WEIGHT_MAX * 4;
1911 if ((pSpectInfo[j].chNum + 12) ==
1912 pSpectInfo[j + 3].chNum)
1913 pSpectInfo[j + 3].weight =
1914 SAP_ACS_WEIGHT_MAX * 4;
1915 continue;
1916 }
1917 /*found the channel, add the 4 adjacent channels' weight */
1918 acs_ht80_channels[i].weight = pSpectInfo[j].weight +
1919 pSpectInfo[j + 1].weight + pSpectInfo[j + 2].weight +
1920 pSpectInfo[j + 3].weight;
1921 /* find best channel among 4 channels as the primary channel */
1922 if ((pSpectInfo[j].weight + pSpectInfo[j + 1].weight) <
1923 (pSpectInfo[j + 2].weight + pSpectInfo[j + 3].weight)) {
1924 /* lower 2 channels are better choice */
1925 if (pSpectInfo[j].weight < pSpectInfo[j + 1].weight)
1926 minIdx = 0;
1927 else
1928 minIdx = 1;
1929 } else if (pSpectInfo[j + 2].weight <=
1930 pSpectInfo[j + 3].weight) {
1931 /* upper 2 channels are better choice */
1932 minIdx = 2;
1933 } else {
1934 minIdx = 3;
1935 }
1936
1937 /*
1938 * set all 4 channels to max value first, then reset the
1939 * best channel as the selected primary channel, update its
1940 * weightage with the combined weight value
1941 */
1942 for (n = 0; n < 4; n++)
1943 pSpectInfo[j + n].weight = SAP_ACS_WEIGHT_MAX * 4;
1944
1945 pSpectInfo[j + minIdx].weight = acs_ht80_channels[i].weight;
1946 }
1947
bingse2782382017-03-23 10:34:52 +08001948 /*
1949 * mark the weight of the channel that can't satisfy 80MHZ
1950 * as max value, so that it will be sorted to the bottom
1951 */
1952 set_ht80_chl_bit(channel_bitmap, pSpectInfoParams);
1953 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
1954 for (i = 0; i < MAX_80MHZ_BANDS; i++) {
1955 start_channel =
1956 channel_bitmap->chanBondingSet[i].startChannel;
1957 if (pSpectInfo[j].chNum >= start_channel &&
1958 (pSpectInfo[j].chNum <=
1959 start_channel + 12) &&
1960 channel_bitmap->chanBondingSet[i].channelMap !=
1961 SAP_80MHZ_MASK)
1962 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 4;
1963 }
1964 }
1965
Himanshu Agarwal75e74412018-02-01 20:51:47 +05301966 /*
1967 * Assign max weight(SAP_ACS_WEIGHT_MAX * 4) to 2.4 Ghz channels
1968 * and channel 165 as they cannot be part of a 80Mhz channel bonding.
1969 */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001970 pSpectInfo = pSpectInfoParams->pSpectCh;
1971 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
Himanshu Agarwal75e74412018-02-01 20:51:47 +05301972 if ((pSpectInfo[j].chNum >= WLAN_REG_CH_NUM(CHAN_ENUM_1) &&
1973 pSpectInfo[j].chNum <= WLAN_REG_CH_NUM(CHAN_ENUM_14)) ||
gaurank kathpalia1dea75b2019-01-10 13:53:43 +05301974 (pSpectInfo[j].chNum >= CHANNEL_165))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001975 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 4;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001976 }
1977
Manishekar Chandrasekaran44e334f2016-05-30 16:42:50 +05301978 sap_sort_chl_weight(pSpectInfoParams);
1979
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001980 pSpectInfo = pSpectInfoParams->pSpectCh;
1981 for (j = 0; j < (pSpectInfoParams->numSpectChans); j++) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301982 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001983 FL("Channel=%d Weight= %d rssi=%d bssCount=%d"),
1984 pSpectInfo->chNum, pSpectInfo->weight,
1985 pSpectInfo->rssiAgr, pSpectInfo->bssCount);
1986 pSpectInfo++;
1987 }
bingse2782382017-03-23 10:34:52 +08001988 qdf_mem_free(channel_bitmap);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001989}
1990
1991/**
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001992 * sap_sort_chl_weight_vht160() - to sort the channels with the least weight
1993 * @pSpectInfoParams: Pointer to the tSapChSelSpectInfo structure
1994 *
Jeff Johnsonc7e4d162018-05-12 16:20:34 -07001995 * Function to sort the channels with the least weight first for VHT160 channels
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001996 *
1997 * Return: none
1998 */
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001999static void sap_sort_chl_weight_vht160(tSapChSelSpectInfo *pSpectInfoParams)
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07002000{
2001 uint8_t i, j, n, idx;
2002 tSapSpectChInfo *pSpectInfo;
2003 uint8_t minIdx;
2004
2005 pSpectInfo = pSpectInfoParams->pSpectCh;
2006 /* for each VHT160 channel, calculate the combined weight of the
2007 8 20MHz weight */
2008 for (i = 0; i < ARRAY_SIZE(acs_vht160_channels); i++) {
2009 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
2010 if (pSpectInfo[j].chNum ==
2011 acs_vht160_channels[i].chStartNum)
2012 break;
2013 }
2014 if (j == pSpectInfoParams->numSpectChans)
2015 continue;
2016
2017 if (!(((pSpectInfo[j].chNum + 4) == pSpectInfo[j + 1].chNum) &&
2018 ((pSpectInfo[j].chNum + 8) ==
2019 pSpectInfo[j + 2].chNum) &&
2020 ((pSpectInfo[j].chNum + 12) ==
2021 pSpectInfo[j + 3].chNum) &&
2022 ((pSpectInfo[j].chNum + 16) ==
2023 pSpectInfo[j + 4].chNum) &&
2024 ((pSpectInfo[j].chNum + 20) ==
2025 pSpectInfo[j + 5].chNum) &&
2026 ((pSpectInfo[j].chNum + 24) ==
2027 pSpectInfo[j + 6].chNum) &&
2028 ((pSpectInfo[j].chNum + 28) ==
2029 pSpectInfo[j + 7].chNum))) {
2030 /*
2031 * some channels does not exist in pSectInfo array,
2032 * skip this channel and those in the same VHT160 width
2033 */
2034 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 8;
2035 if ((pSpectInfo[j].chNum + 4) ==
2036 pSpectInfo[j + 1].chNum)
2037 pSpectInfo[j + 1].weight =
2038 SAP_ACS_WEIGHT_MAX * 8;
2039 if ((pSpectInfo[j].chNum + 8) ==
2040 pSpectInfo[j + 2].chNum)
2041 pSpectInfo[j + 2].weight =
2042 SAP_ACS_WEIGHT_MAX * 8;
2043 if ((pSpectInfo[j].chNum + 12) ==
2044 pSpectInfo[j + 3].chNum)
2045 pSpectInfo[j + 3].weight =
2046 SAP_ACS_WEIGHT_MAX * 8;
2047 if ((pSpectInfo[j].chNum + 16) ==
2048 pSpectInfo[j + 4].chNum)
2049 pSpectInfo[j + 4].weight =
2050 SAP_ACS_WEIGHT_MAX * 8;
2051 if ((pSpectInfo[j].chNum + 20) ==
2052 pSpectInfo[j + 5].chNum)
2053 pSpectInfo[j + 5].weight =
2054 SAP_ACS_WEIGHT_MAX * 8;
2055 if ((pSpectInfo[j].chNum + 24) ==
2056 pSpectInfo[j + 6].chNum)
2057 pSpectInfo[j + 6].weight =
2058 SAP_ACS_WEIGHT_MAX * 8;
2059 if ((pSpectInfo[j].chNum + 28) ==
2060 pSpectInfo[j + 7].chNum)
2061 pSpectInfo[j + 7].weight =
2062 SAP_ACS_WEIGHT_MAX * 8;
2063 continue;
2064 }
2065 /*found the channel, add the 7 adjacent channels' weight */
2066 acs_vht160_channels[i].weight = pSpectInfo[j].weight +
2067 pSpectInfo[j + 1].weight + pSpectInfo[j + 2].weight +
2068 pSpectInfo[j + 3].weight + pSpectInfo[j + 4].weight +
2069 pSpectInfo[j + 5].weight + pSpectInfo[j + 6].weight +
2070 pSpectInfo[j + 7].weight;
2071
2072 /* find best channel among 8 channels as the primary channel */
2073 if ((pSpectInfo[j].weight + pSpectInfo[j + 1].weight +
2074 pSpectInfo[j + 2].weight + pSpectInfo[j + 3].weight) >
2075 (pSpectInfo[j + 4].weight + pSpectInfo[j + 5].weight +
2076 pSpectInfo[j + 6].weight + pSpectInfo[j + 7].weight))
2077 idx = 4;
2078 else
2079 idx = 0;
2080 /* find best channel among 4 channels as the primary channel */
2081 if ((pSpectInfo[j + idx].weight +
2082 pSpectInfo[j + idx + 1].weight) <
2083 (pSpectInfo[j + idx + 2].weight +
2084 pSpectInfo[j + idx + 3].weight)) {
2085 /* lower 2 channels are better choice */
2086 if (pSpectInfo[j + idx].weight <
2087 pSpectInfo[j + idx + 1].weight)
2088 minIdx = 0 + idx;
2089 else
2090 minIdx = 1 + idx;
2091 } else if (pSpectInfo[j + idx + 2].weight <=
2092 pSpectInfo[j + idx + 3].weight) {
2093 /* upper 2 channels are better choice */
2094 minIdx = 2 + idx;
2095 } else {
2096 minIdx = 3 + idx;
2097 }
2098
2099 /*
2100 * set all 8 channels to max value first, then reset the
2101 * best channel as the selected primary channel, update its
2102 * weightage with the combined weight value
2103 */
2104 for (n = 0; n < 8; n++)
2105 pSpectInfo[j + n].weight = SAP_ACS_WEIGHT_MAX * 8;
2106
2107 pSpectInfo[j + minIdx].weight = acs_vht160_channels[i].weight;
2108 }
2109
Himanshu Agarwal75e74412018-02-01 20:51:47 +05302110 /*
2111 * Assign max weight(SAP_ACS_WEIGHT_MAX * 8) to 2.4 Ghz channels
Kiran Kumar Lokere1a43bcf2018-05-15 15:51:58 -07002112 * and channel 132-173 as they cannot be part of a 160Mhz channel
Himanshu Agarwal75e74412018-02-01 20:51:47 +05302113 * bonding.
2114 */
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07002115 pSpectInfo = pSpectInfoParams->pSpectCh;
2116 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
Himanshu Agarwal75e74412018-02-01 20:51:47 +05302117 if ((pSpectInfo[j].chNum >= WLAN_REG_CH_NUM(CHAN_ENUM_1) &&
2118 pSpectInfo[j].chNum <= WLAN_REG_CH_NUM(CHAN_ENUM_14)) ||
2119 (pSpectInfo[j].chNum >= WLAN_REG_CH_NUM(CHAN_ENUM_132) &&
Kiran Kumar Lokere1a43bcf2018-05-15 15:51:58 -07002120 pSpectInfo[j].chNum <= WLAN_REG_CH_NUM(CHAN_ENUM_173)))
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07002121 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 8;
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07002122 }
2123
Manishekar Chandrasekaran44e334f2016-05-30 16:42:50 +05302124 sap_sort_chl_weight(pSpectInfoParams);
2125
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07002126 pSpectInfo = pSpectInfoParams->pSpectCh;
2127 for (j = 0; j < (pSpectInfoParams->numSpectChans); j++) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302128 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07002129 FL("Channel=%d Weight= %d rssi=%d bssCount=%d"),
2130 pSpectInfo->chNum, pSpectInfo->weight,
2131 pSpectInfo->rssiAgr, pSpectInfo->bssCount);
2132 pSpectInfo++;
2133 }
2134}
2135
2136/**
Himanshu Agarwal91c5c0f2018-02-13 14:40:56 +05302137 * sap_allocate_max_weight_ht40_24_g() - allocate max weight for 40Mhz
2138 * to all 2.4Ghz channels
2139 * @spect_info_params: Pointer to the tSapChSelSpectInfo structure
2140 *
2141 * Return: none
2142 */
2143static void sap_allocate_max_weight_ht40_24_g(
2144 tSapChSelSpectInfo *spect_info_params)
2145{
2146 tSapSpectChInfo *spect_info;
2147 uint8_t j;
2148
2149 /*
2150 * Assign max weight for 40Mhz (SAP_ACS_WEIGHT_MAX * 2) to all
2151 * 2.4 Ghz channels
2152 */
2153 spect_info = spect_info_params->pSpectCh;
2154 for (j = 0; j < spect_info_params->numSpectChans; j++) {
2155 if ((spect_info[j].chNum >= WLAN_REG_CH_NUM(CHAN_ENUM_1) &&
2156 spect_info[j].chNum <= WLAN_REG_CH_NUM(CHAN_ENUM_14)))
2157 spect_info[j].weight = SAP_ACS_WEIGHT_MAX * 2;
2158 }
2159}
2160
2161/**
2162 * sap_allocate_max_weight_ht40_5_g() - allocate max weight for 40Mhz
2163 * to all 5Ghz channels
2164 * @spect_info_params: Pointer to the tSapChSelSpectInfo structure
2165 *
2166 * Return: none
2167 */
2168static void sap_allocate_max_weight_ht40_5_g(
2169 tSapChSelSpectInfo *spect_info_params)
2170{
2171 tSapSpectChInfo *spect_info;
2172 uint8_t j;
2173
2174 /*
2175 * Assign max weight for 40Mhz (SAP_ACS_WEIGHT_MAX * 2) to all
2176 * 5 Ghz channels
2177 */
2178 spect_info = spect_info_params->pSpectCh;
2179 for (j = 0; j < spect_info_params->numSpectChans; j++) {
2180 if ((spect_info[j].chNum >= WLAN_REG_CH_NUM(CHAN_ENUM_36) &&
Kiran Kumar Lokere1a43bcf2018-05-15 15:51:58 -07002181 spect_info[j].chNum <= WLAN_REG_CH_NUM(CHAN_ENUM_173)))
Himanshu Agarwal91c5c0f2018-02-13 14:40:56 +05302182 spect_info[j].weight = SAP_ACS_WEIGHT_MAX * 2;
2183 }
2184}
2185
2186/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002187 * sap_sort_chl_weight_ht40_24_g() - to sort channel with the least weight
2188 * @pSpectInfoParams: Pointer to the tSapChSelSpectInfo structure
2189 *
Jeff Johnsonc7e4d162018-05-12 16:20:34 -07002190 * Function to sort the channels with the least weight first for HT40 channels
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002191 *
2192 * Return: none
2193 */
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002194static void sap_sort_chl_weight_ht40_24_g(tSapChSelSpectInfo *pSpectInfoParams,
2195 v_REGDOMAIN_t domain)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002196{
2197 uint8_t i, j;
2198 tSapSpectChInfo *pSpectInfo;
2199 uint32_t tmpWeight1, tmpWeight2;
bingse2782382017-03-23 10:34:52 +08002200 uint32_t ht40plus2gendch = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002201
2202 pSpectInfo = pSpectInfoParams->pSpectCh;
2203 /*
2204 * for each HT40 channel, calculate the combined weight of the
2205 * two 20MHz weight
2206 */
2207 for (i = 0; i < ARRAY_SIZE(acs_ht40_channels24_g); i++) {
2208 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
2209 if (pSpectInfo[j].chNum ==
2210 acs_ht40_channels24_g[i].chStartNum)
2211 break;
2212 }
2213 if (j == pSpectInfoParams->numSpectChans)
2214 continue;
2215
2216 if (!((pSpectInfo[j].chNum + 4) == pSpectInfo[j + 4].chNum)) {
2217 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2;
2218 continue;
2219 }
2220 /*
2221 * check if there is another channel combination possiblity
2222 * e.g., {1, 5} & {5, 9}
2223 */
2224 if ((pSpectInfo[j + 4].chNum + 4) == pSpectInfo[j + 8].chNum) {
2225 /* need to compare two channel pairs */
2226 tmpWeight1 = pSpectInfo[j].weight +
2227 pSpectInfo[j + 4].weight;
2228 tmpWeight2 = pSpectInfo[j + 4].weight +
2229 pSpectInfo[j + 8].weight;
2230 if (tmpWeight1 <= tmpWeight2) {
2231 if (pSpectInfo[j].weight <=
2232 pSpectInfo[j + 4].weight) {
2233 pSpectInfo[j].weight =
2234 tmpWeight1;
2235 pSpectInfo[j + 4].weight =
2236 SAP_ACS_WEIGHT_MAX * 2;
2237 pSpectInfo[j + 8].weight =
2238 SAP_ACS_WEIGHT_MAX * 2;
2239 } else {
2240 pSpectInfo[j + 4].weight =
2241 tmpWeight1;
2242 /* for secondary channel selection */
2243 pSpectInfo[j].weight =
2244 SAP_ACS_WEIGHT_MAX * 2
2245 - 1;
2246 pSpectInfo[j + 8].weight =
2247 SAP_ACS_WEIGHT_MAX * 2;
2248 }
2249 } else {
2250 if (pSpectInfo[j + 4].weight <=
2251 pSpectInfo[j + 8].weight) {
2252 pSpectInfo[j + 4].weight =
2253 tmpWeight2;
2254 pSpectInfo[j].weight =
2255 SAP_ACS_WEIGHT_MAX * 2;
2256 /* for secondary channel selection */
2257 pSpectInfo[j + 8].weight =
2258 SAP_ACS_WEIGHT_MAX * 2
2259 - 1;
2260 } else {
2261 pSpectInfo[j + 8].weight =
2262 tmpWeight2;
2263 pSpectInfo[j].weight =
2264 SAP_ACS_WEIGHT_MAX * 2;
2265 pSpectInfo[j + 4].weight =
2266 SAP_ACS_WEIGHT_MAX * 2;
2267 }
2268 }
2269 } else {
bingsaa6f96a2017-09-11 09:49:43 +08002270 tmpWeight1 = pSpectInfo[j].weight_copy +
2271 pSpectInfo[j + 4].weight_copy;
2272 if (pSpectInfo[j].weight_copy <=
2273 pSpectInfo[j + 4].weight_copy) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002274 pSpectInfo[j].weight = tmpWeight1;
2275 pSpectInfo[j + 4].weight =
2276 SAP_ACS_WEIGHT_MAX * 2;
2277 } else {
2278 pSpectInfo[j + 4].weight = tmpWeight1;
2279 pSpectInfo[j].weight =
2280 SAP_ACS_WEIGHT_MAX * 2;
2281 }
2282 }
2283 }
bingse2782382017-03-23 10:34:52 +08002284 /*
2285 * Every channel should be checked. Add the check for the omissive
2286 * channel. Mark the channel whose combination can't satisfy 40MHZ
2287 * as max value, so that it will be sorted to the bottom.
2288 */
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002289 if (REGDOMAIN_FCC == domain)
bingse2782382017-03-23 10:34:52 +08002290 ht40plus2gendch = HT40PLUS_2G_FCC_CH_END;
2291 else
2292 ht40plus2gendch = HT40PLUS_2G_EURJAP_CH_END;
2293 for (i = HT40MINUS_2G_CH_START; i <= ht40plus2gendch; i++) {
2294 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
2295 if (pSpectInfo[j].chNum == i &&
2296 ((pSpectInfo[j].chNum + 4) !=
2297 pSpectInfo[j+4].chNum) &&
2298 ((pSpectInfo[j].chNum - 4) !=
2299 pSpectInfo[j-4].chNum))
2300 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2;
2301 }
2302 }
2303 for (i = ht40plus2gendch + 1; i <= HT40MINUS_2G_CH_END; i++) {
2304 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
2305 if (pSpectInfo[j].chNum == i &&
2306 (pSpectInfo[j].chNum - 4) !=
2307 pSpectInfo[j-4].chNum)
2308 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2;
2309 }
2310 }
Himanshu Agarwal91c5c0f2018-02-13 14:40:56 +05302311
2312 pSpectInfo = pSpectInfoParams->pSpectCh;
2313 for (j = 0; j < (pSpectInfoParams->numSpectChans); j++) {
2314 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2315 "In %s, Channel=%d Weight= %d rssi=%d bssCount=%d",
2316 __func__, pSpectInfo->chNum, pSpectInfo->weight,
2317 pSpectInfo->rssiAgr, pSpectInfo->bssCount);
2318 pSpectInfo++;
2319 }
2320
Manishekar Chandrasekaran44e334f2016-05-30 16:42:50 +05302321 sap_sort_chl_weight(pSpectInfoParams);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002322}
2323
2324/*==========================================================================
2325 FUNCTION sap_sort_chl_weight_ht40_5_g
2326
2327 DESCRIPTION
Jeff Johnsonc7e4d162018-05-12 16:20:34 -07002328 Function to sort the channels with the least weight first for HT40 channels
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002329
2330 DEPENDENCIES
2331 NA.
2332
2333 PARAMETERS
2334
2335 IN
2336 pSpectInfoParams : Pointer to the tSapChSelSpectInfo structure
2337
2338 RETURN VALUE
2339 void : NULL
2340
2341 SIDE EFFECTS
2342 ============================================================================*/
Jeff Johnson464f7ea2016-10-07 10:21:26 -07002343static void sap_sort_chl_weight_ht40_5_g(tSapChSelSpectInfo *pSpectInfoParams)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002344{
2345 uint8_t i, j;
2346 tSapSpectChInfo *pSpectInfo;
2347
2348 pSpectInfo = pSpectInfoParams->pSpectCh;
2349 /*for each HT40 channel, calculate the combined weight of the
2350 two 20MHz weight */
2351 for (i = 0; i < ARRAY_SIZE(acs_ht40_channels5_g); i++) {
2352 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
2353 if (pSpectInfo[j].chNum ==
2354 acs_ht40_channels5_g[i].chStartNum)
2355 break;
2356 }
2357 if (j == pSpectInfoParams->numSpectChans)
2358 continue;
2359
2360 /* found the channel, add the two adjacent channels' weight */
2361 if ((pSpectInfo[j].chNum + 4) == pSpectInfo[j + 1].chNum) {
2362 acs_ht40_channels5_g[i].weight = pSpectInfo[j].weight +
2363 pSpectInfo[j + 1].weight;
2364 /* select better of the adjact channel as the primary channel */
2365 if (pSpectInfo[j].weight <= pSpectInfo[j + 1].weight) {
2366 pSpectInfo[j].weight =
2367 acs_ht40_channels5_g[i].weight;
2368 /* mark the adjacent channel's weight as max value so
2369 that it will be sorted to the bottom */
2370 pSpectInfo[j + 1].weight =
2371 SAP_ACS_WEIGHT_MAX * 2;
2372 } else {
2373 pSpectInfo[j + 1].weight =
2374 acs_ht40_channels5_g[i].weight;
2375 /* mark the adjacent channel's weight as max value so
2376 that it will be sorted to the bottom */
2377 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2;
2378 }
2379
2380 } else
2381 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2;
2382 }
2383
bingse2782382017-03-23 10:34:52 +08002384 /*
2385 *Every channel should be checked. Add the check for the omissive
2386 * channel. Mark the channel whose combination can't satisfy 40MHZ
2387 * as max value, so that it will be sorted to the bottom
2388 */
2389 for (j = 1; j < pSpectInfoParams->numSpectChans; j++) {
2390 for (i = 0; i < ARRAY_SIZE(acs_ht40_channels5_g); i++) {
2391 if (pSpectInfo[j].chNum ==
2392 (acs_ht40_channels5_g[i].chStartNum +
2393 4) &&
2394 pSpectInfo[j - 1].chNum !=
2395 acs_ht40_channels5_g[i].chStartNum) {
2396 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2;
2397 break;
2398 }
2399 }
2400 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002401 /* avoid channel 165 by setting its weight to max */
2402 pSpectInfo = pSpectInfoParams->pSpectCh;
2403 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
gaurank kathpalia1dea75b2019-01-10 13:53:43 +05302404 if (pSpectInfo[j].chNum >= CHANNEL_165) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002405 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2;
2406 break;
2407 }
2408 }
2409
2410 pSpectInfo = pSpectInfoParams->pSpectCh;
2411 for (j = 0; j < (pSpectInfoParams->numSpectChans); j++) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302412 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002413 "In %s, Channel=%d Weight= %d rssi=%d bssCount=%d",
2414 __func__, pSpectInfo->chNum, pSpectInfo->weight,
2415 pSpectInfo->rssiAgr, pSpectInfo->bssCount);
2416 pSpectInfo++;
2417 }
2418
2419 sap_sort_chl_weight(pSpectInfoParams);
2420}
2421
2422/*==========================================================================
2423 FUNCTION sap_sort_chl_weight_all
2424
2425 DESCRIPTION
Jeff Johnsonc7e4d162018-05-12 16:20:34 -07002426 Function to sort the channels with the least weight first
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002427
2428 DEPENDENCIES
2429 NA.
2430
2431 PARAMETERS
2432
2433 IN
Jeff Johnsone13d8062017-09-28 06:54:55 -07002434 sap_ctx : Pointer to the struct sap_context *structure
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002435 pSpectInfoParams : Pointer to the tSapChSelSpectInfo structure
2436
2437 RETURN VALUE
2438 void : NULL
2439
2440 SIDE EFFECTS
2441 ============================================================================*/
Jeff Johnsone13d8062017-09-28 06:54:55 -07002442static void sap_sort_chl_weight_all(struct sap_context *sap_ctx,
Jeff Johnson464f7ea2016-10-07 10:21:26 -07002443 tSapChSelSpectInfo *pSpectInfoParams,
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002444 uint32_t operatingBand,
2445 v_REGDOMAIN_t domain)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002446{
2447 tSapSpectChInfo *pSpectCh = NULL;
2448 uint32_t j = 0;
2449#ifndef SOFTAP_CHANNEL_RANGE
2450 uint32_t i = 0;
2451#endif
2452
2453 pSpectCh = pSpectInfoParams->pSpectCh;
2454#ifdef SOFTAP_CHANNEL_RANGE
2455
Jeff Johnsone13d8062017-09-28 06:54:55 -07002456 switch (sap_ctx->acs_cfg->ch_width) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002457 case CH_WIDTH_40MHZ:
Himanshu Agarwal91c5c0f2018-02-13 14:40:56 +05302458 /*
2459 * Assign max weight to all 5Ghz channels when operating band
2460 * is 11g and to all 2.4Ghz channels when operating band is 11a
2461 * or 11abg to avoid selection in ACS algorithm for starting SAP
2462 */
2463 if (eCSR_DOT11_MODE_11g == operatingBand) {
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002464 sap_sort_chl_weight_ht40_24_g(pSpectInfoParams, domain);
Himanshu Agarwal91c5c0f2018-02-13 14:40:56 +05302465 sap_allocate_max_weight_ht40_5_g(pSpectInfoParams);
2466 } else {
2467 sap_allocate_max_weight_ht40_24_g(pSpectInfoParams);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002468 sap_sort_chl_weight_ht40_5_g(pSpectInfoParams);
2469 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002470 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002471 case CH_WIDTH_80MHZ:
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07002472 case CH_WIDTH_80P80MHZ:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002473 sap_sort_chl_weight_ht80(pSpectInfoParams);
2474 break;
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07002475 case CH_WIDTH_160MHZ:
2476 sap_sort_chl_weight_vht160(pSpectInfoParams);
2477 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002478 case CH_WIDTH_20MHZ:
2479 default:
2480 /* Sorting the channels as per weights as 20MHz channels */
2481 sap_sort_chl_weight(pSpectInfoParams);
2482 }
2483
2484#else
2485 /* Sorting the channels as per weights */
2486 for (i = 0; i < SPECT_24GHZ_CH_COUNT; i++) {
2487 minWeightIndex = i;
2488 for (j = i + 1; j < SPECT_24GHZ_CH_COUNT; j++) {
2489 if (pSpectCh[j].weight <
2490 pSpectCh[minWeightIndex].weight) {
2491 minWeightIndex = j;
2492 }
2493 }
2494 if (minWeightIndex != i) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302495 qdf_mem_copy(&temp, &pSpectCh[minWeightIndex],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002496 sizeof(*pSpectCh));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302497 qdf_mem_copy(&pSpectCh[minWeightIndex], &pSpectCh[i],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002498 sizeof(*pSpectCh));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302499 qdf_mem_copy(&pSpectCh[i], &temp, sizeof(*pSpectCh));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002500 }
2501 }
2502#endif
2503
2504 /* For testing */
Ravi Joshi9788fcd2018-02-13 15:12:22 -08002505 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002506 "In %s, Sorted Spectrum Channels Weight", __func__);
2507 pSpectCh = pSpectInfoParams->pSpectCh;
2508 for (j = 0; j < (pSpectInfoParams->numSpectChans); j++) {
Ravi Joshi9788fcd2018-02-13 15:12:22 -08002509 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002510 "In %s, Channel=%d Weight= %d rssi=%d bssCount=%d",
2511 __func__, pSpectCh->chNum, pSpectCh->weight,
2512 pSpectCh->rssiAgr, pSpectCh->bssCount);
2513 pSpectCh++;
2514 }
2515
2516}
2517
Naveen Rawatbec64d92017-09-13 14:35:21 -07002518/**
2519 * sap_is_ch_non_overlap() - returns true if non-overlapping channel
2520 * @sap_ctx: Sap context
2521 * @ch: channel number
2522 *
2523 * Returns: true if non-overlapping (1, 6, 11) channel, false otherwise
2524 */
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -07002525static bool sap_is_ch_non_overlap(struct sap_context *sap_ctx, uint16_t ch)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002526{
Naveen Rawatbec64d92017-09-13 14:35:21 -07002527 if (sap_ctx->enableOverLapCh)
Srinivas Girigowda74a66d62017-06-21 23:28:25 -07002528 return true;
Naveen Rawatbec64d92017-09-13 14:35:21 -07002529
2530 if ((ch == CHANNEL_1) || (ch == CHANNEL_6) || (ch == CHANNEL_11))
Srinivas Girigowda74a66d62017-06-21 23:28:25 -07002531 return true;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002532
Srinivas Girigowda74a66d62017-06-21 23:28:25 -07002533 return false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002534}
2535
Dustin Brown0ce56d32016-10-17 16:18:03 -07002536#ifdef FEATURE_WLAN_CH_AVOID
Rachit Kankane057097f2019-04-22 15:16:03 +05302537static uint8_t get_channel_from_safe_channels(mac_handle_t mac_handle,
2538 struct sap_context *sap_ctx)
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002539{
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002540 uint8_t i, first_safe_ch_in_range = SAP_CHANNEL_NOT_SELECTED;
Rachit Kankane057097f2019-04-22 15:16:03 +05302541 enum channel_state ch_type;
Dustin Brown0ce56d32016-10-17 16:18:03 -07002542 uint32_t start_ch_num = sap_ctx->acs_cfg->start_ch;
2543 uint32_t end_ch_num = sap_ctx->acs_cfg->end_ch;
Rachit Kankane057097f2019-04-22 15:16:03 +05302544 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002545
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002546
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002547 for (i = 0; i < NUM_CHANNELS; i++) {
2548 if ((safe_channels[i].channelNumber < start_ch_num) ||
2549 (safe_channels[i].channelNumber > end_ch_num))
2550 continue;
2551
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002552 ch_type = wlan_reg_get_channel_state(mac_ctx->pdev,
2553 safe_channels[i].channelNumber);
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002554
2555 if ((ch_type == CHANNEL_STATE_DISABLE) ||
2556 (ch_type == CHANNEL_STATE_INVALID))
2557 continue;
Arif Hussain88d1fdd2018-09-26 16:12:24 -07002558 if ((!mac_ctx->mlme_cfg->dfs_cfg.dfs_master_capable) &&
2559 (CHANNEL_STATE_DFS == ch_type)) {
Rachit Kankane057097f2019-04-22 15:16:03 +05302560 sap_debug("DFS master mode disabled. Skip DFS channel %d",
2561 safe_channels[i].channelNumber);
Kondabattini, Ganesh13bb4b12016-09-04 16:16:53 +05302562 continue;
2563 }
Agrawal Ashish65634612016-08-18 13:24:32 +05302564 if ((sap_ctx->dfs_mode == ACS_DFS_MODE_DISABLE) &&
2565 (CHANNEL_STATE_DFS == ch_type))
2566 continue;
Kondabattini, Ganesh13bb4b12016-09-04 16:16:53 +05302567
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002568 if (safe_channels[i].isSafe == true) {
Rachit Kankane057097f2019-04-22 15:16:03 +05302569 sap_debug("channel %d in the configuration is safe",
2570 safe_channels[i].channelNumber);
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002571 first_safe_ch_in_range = safe_channels[i].channelNumber;
2572 break;
2573 }
2574
Rachit Kankane057097f2019-04-22 15:16:03 +05302575 sap_debug("channel %d in the configuration is unsafe",
2576 safe_channels[i].channelNumber);
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002577 }
2578
2579 /* if no channel selected return SAP_CHANNEL_NOT_SELECTED */
2580 return first_safe_ch_in_range;
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002581}
Dustin Brown0ce56d32016-10-17 16:18:03 -07002582#else
Rachit Kankane057097f2019-04-22 15:16:03 +05302583static uint8_t get_channel_from_safe_channels(mac_handle_t mac_handle,
2584 struct sap_context *sap_ctx)
Dustin Brown0ce56d32016-10-17 16:18:03 -07002585{
2586 uint32_t start_ch_num = sap_ctx->acs_cfg->start_ch;
2587
Dustin Brown0ce56d32016-10-17 16:18:03 -07002588 sap_ctx->acs_cfg->pri_ch = start_ch_num;
2589 sap_ctx->acs_cfg->ht_sec_ch = 0;
2590
2591 /* pick the first channel in configured range */
2592 return start_ch_num;
2593}
2594#endif /* FEATURE_WLAN_CH_AVOID */
Rachit Kankane057097f2019-04-22 15:16:03 +05302595/**
2596 * sap_select_channel_no_scan_result() - select SAP channel when no scan results
2597 * are available.
2598 * @sap_ctx: Sap context
2599 *
2600 * Returns: channel number if success, 0 otherwise
2601 */
2602static uint8_t sap_select_channel_no_scan_result(mac_handle_t mac_handle,
2603 struct sap_context *sap_ctx)
2604{
2605 uint8_t i, channel = SAP_CHANNEL_NOT_SELECTED;
2606 uint32_t start_ch_num = sap_ctx->acs_cfg->start_ch;
2607 uint32_t end_ch_num = sap_ctx->acs_cfg->end_ch;
2608
2609 sap_debug("start - end: %d - %d", start_ch_num, end_ch_num);
2610 /* get a channel in PCL and within the range */
2611 for (i = 0; i < sap_ctx->acs_cfg->pcl_ch_count; i++) {
2612 if ((sap_ctx->acs_cfg->pcl_channels[i] < start_ch_num) ||
2613 (sap_ctx->acs_cfg->pcl_channels[i] > end_ch_num))
2614 continue;
2615
2616 channel = sap_ctx->acs_cfg->pcl_channels[i];
2617 break;
2618 }
2619
2620 if (channel == SAP_CHANNEL_NOT_SELECTED)
2621 channel = get_channel_from_safe_channels(mac_handle, sap_ctx);
2622
2623 return channel;
2624}
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002625
Jeff Johnson7730fbb2018-11-08 13:48:27 -08002626uint8_t sap_select_channel(mac_handle_t mac_handle,
2627 struct sap_context *sap_ctx,
Abhishek Singhd1cd4ae2019-05-10 11:22:21 +05302628 qdf_list_t *scan_list)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002629{
2630 /* DFS param object holding all the data req by the algo */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002631 tSapChSelSpectInfo spect_info_obj = { NULL, 0 };
2632 tSapChSelSpectInfo *spect_info = &spect_info_obj;
2633 uint8_t best_ch_num = SAP_CHANNEL_NOT_SELECTED;
Jeff Johnson6c336832019-03-26 09:09:08 -07002634 uint32_t best_ch_weight = SAP_ACS_WEIGHT_MAX;
bingse2782382017-03-23 10:34:52 +08002635 uint32_t ht40plus2gendch = 0;
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002636 v_REGDOMAIN_t domain;
Arif Hussain21ad4342017-12-21 12:00:54 -08002637 uint8_t country[CDS_COUNTRY_CODE_LEN + 1];
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002638#ifdef SOFTAP_CHANNEL_RANGE
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002639 uint8_t count;
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002640 uint32_t start_ch_num, end_ch_num, tmp_ch_num, operating_band = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002641#endif
Jeff Johnsonc59ef8b2018-12-02 12:01:21 -08002642 struct mac_context *mac_ctx;
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002643
Jeff Johnsona0619e42018-11-28 17:43:00 -08002644 mac_ctx = MAC_CONTEXT(mac_handle);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302645 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002646 "In %s, Running SAP Ch Select", __func__);
2647
Jeff Johnson7730fbb2018-11-08 13:48:27 -08002648 sap_update_unsafe_channel_list(mac_handle, sap_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002649
gaoleze5108942017-03-31 16:56:42 +08002650 /*
2651 * If ACS weight is not enabled on noise_floor/channel_free/tx_power,
2652 * then skip acs process if no bss found.
2653 */
Rachit Kankane2dba6752019-05-20 14:55:31 +05302654 if ((!scan_list || !qdf_list_size(scan_list)) &&
gaoleze5108942017-03-31 16:56:42 +08002655 !(sap_ctx->auto_channel_select_weight & 0xffff00)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302656 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002657 FL("No external AP present"));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002658
2659#ifndef SOFTAP_CHANNEL_RANGE
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002660 return SAP_CHANNEL_NOT_SELECTED;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002661#else
Jeff Johnson7730fbb2018-11-08 13:48:27 -08002662 return sap_select_channel_no_scan_result(mac_handle, sap_ctx);
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002663#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002664 }
2665
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002666 /* Initialize the structure pointed by spect_info */
Jeff Johnson7730fbb2018-11-08 13:48:27 -08002667 if (sap_chan_sel_init(mac_handle, spect_info, sap_ctx) != true) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302668 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002669 FL("Ch Select initialization failed"));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002670 return SAP_CHANNEL_NOT_SELECTED;
2671 }
2672 /* Compute the weight of the entire spectrum in the operating band */
Abhishek Singhd1cd4ae2019-05-10 11:22:21 +05302673 sap_compute_spect_weight(spect_info, mac_handle, scan_list, sap_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002674
2675#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
2676 /* process avoid channel IE to collect all channels to avoid */
Abhishek Singhd1cd4ae2019-05-10 11:22:21 +05302677 sap_process_avoid_ie(mac_handle, sap_ctx, scan_list, spect_info);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002678#endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
2679
Paul Zhang0f85b412018-01-18 19:14:51 +08002680 wlan_reg_read_current_country(mac_ctx->psoc, country);
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002681 wlan_reg_get_domain_from_country_code(&domain, country, SOURCE_DRIVER);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002682#ifdef SOFTAP_CHANNEL_RANGE
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002683 start_ch_num = sap_ctx->acs_cfg->start_ch;
2684 end_ch_num = sap_ctx->acs_cfg->end_ch;
2685 SET_ACS_BAND(operating_band, sap_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002686
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002687 /* Sort the ch lst as per the computed weights, lesser weight first. */
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002688 sap_sort_chl_weight_all(sap_ctx, spect_info, operating_band, domain);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002689
2690 /*Loop till get the best channel in the given range */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002691 for (count = 0; count < spect_info->numSpectChans; count++) {
2692 if ((start_ch_num > spect_info->pSpectCh[count].chNum) ||
2693 (end_ch_num < spect_info->pSpectCh[count].chNum))
2694 continue;
2695
2696 if (best_ch_num == SAP_CHANNEL_NOT_SELECTED) {
2697 best_ch_num = spect_info->pSpectCh[count].chNum;
2698 /* check if best_ch_num is in preferred channel list */
2699 best_ch_num =
2700 sap_select_preferred_channel_from_channel_list(
2701 best_ch_num, sap_ctx, spect_info);
2702 /* if not in preferred ch lst, go to nxt best ch */
2703 if (best_ch_num == SAP_CHANNEL_NOT_SELECTED)
2704 continue;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002705
2706#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002707 /*
2708 * Weight of the channels(device's AP is operating)
Jeff Johnson2cc31fd2018-05-05 23:54:23 -07002709 * increased to MAX+1 so that they will be chosen only
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002710 * when there is no other best channel to choose
2711 */
2712 if (sap_check_in_avoid_ch_list(sap_ctx, best_ch_num)) {
2713 best_ch_num = SAP_CHANNEL_NOT_SELECTED;
2714 continue;
2715 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002716#endif
2717
Jeff Johnson6c336832019-03-26 09:09:08 -07002718 best_ch_weight =
2719 spect_info->pSpectCh[count].weight_copy;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002720 }
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002721
2722 if (best_ch_num == SAP_CHANNEL_NOT_SELECTED)
2723 continue;
2724
Tushnim Bhattacharyya03103fd2017-06-23 10:48:52 -07002725 if (operating_band != eCSR_DOT11_MODE_11g) {
2726 QDF_TRACE(QDF_MODULE_ID_SAP,
2727 QDF_TRACE_LEVEL_INFO_HIGH,
2728 "operating_band %d", operating_band);
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002729 continue;
Tushnim Bhattacharyya03103fd2017-06-23 10:48:52 -07002730 }
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002731
2732 /* Give preference to Non-overlap channels */
Naveen Rawatbec64d92017-09-13 14:35:21 -07002733 if (false == sap_is_ch_non_overlap(sap_ctx,
Tushnim Bhattacharyya03103fd2017-06-23 10:48:52 -07002734 spect_info->pSpectCh[count].chNum)) {
2735 QDF_TRACE(QDF_MODULE_ID_SAP,
2736 QDF_TRACE_LEVEL_INFO_HIGH,
Naveen Rawatbec64d92017-09-13 14:35:21 -07002737 FL("ch: %d skipped as its overlapping ch"),
2738 spect_info->pSpectCh[count].chNum);
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002739 continue;
Tushnim Bhattacharyya03103fd2017-06-23 10:48:52 -07002740 }
2741
2742 if (wlan_reg_is_dfs_ch(mac_ctx->pdev,
2743 spect_info->pSpectCh[count].chNum) &&
2744 policy_mgr_disallow_mcc(mac_ctx->psoc,
2745 spect_info->pSpectCh[count].chNum)) {
2746 QDF_TRACE(QDF_MODULE_ID_SAP,
2747 QDF_TRACE_LEVEL_INFO_HIGH,
2748 "No DFS MCC");
2749 continue;
2750 }
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002751
Jeff Johnson6c336832019-03-26 09:09:08 -07002752 if (spect_info->pSpectCh[count].weight_copy > best_ch_weight)
bings14d1d3b2017-08-03 11:14:29 +08002753 continue;
2754
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002755 tmp_ch_num = spect_info->pSpectCh[count].chNum;
gaoleze5108942017-03-31 16:56:42 +08002756 tmp_ch_num = sap_channel_in_acs_channel_list(
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002757 tmp_ch_num, sap_ctx, spect_info);
2758 if (tmp_ch_num == SAP_CHANNEL_NOT_SELECTED)
2759 continue;
2760
2761 best_ch_num = tmp_ch_num;
2762 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002763 }
2764#else
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002765 /* Sort the ch lst as per the computed weights, lesser weight first. */
Jeff Johnson7730fbb2018-11-08 13:48:27 -08002766 sap_sort_chl_weight_all(sap_ctx, mac_handle, spect_info);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002767 /* Get the first channel in sorted array as best 20M Channel */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002768 best_ch_num = (uint8_t) spect_info->pSpectCh[0].chNum;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002769 /* Select Best Channel from Channel List if Configured */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002770 best_ch_num = sap_select_preferred_channel_from_channel_list(
2771 best_ch_num, sap_ctx, spect_info);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002772#endif
2773
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002774 /*
2775 * in case the best channel seleted is not in PCL and there is another
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002776 * channel which has same weightage and is in PCL, choose the one in
2777 * PCL
2778 */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002779 for (count = 0; count < spect_info->numSpectChans; count++) {
2780 if (!ch_in_pcl(sap_ctx, spect_info->pSpectCh[count].chNum) ||
Jeff Johnson6c336832019-03-26 09:09:08 -07002781 (spect_info->pSpectCh[count].weight != best_ch_weight))
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002782 continue;
2783
2784 if (sap_select_preferred_channel_from_channel_list(
2785 spect_info->pSpectCh[count].chNum, sap_ctx, spect_info)
2786 == SAP_CHANNEL_NOT_SELECTED)
2787 continue;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002788
2789#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002790 if (sap_check_in_avoid_ch_list(sap_ctx, best_ch_num))
2791 continue;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002792#endif
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002793 best_ch_num = spect_info->pSpectCh[count].chNum;
2794 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2795 FL("change best channel to %d in PCL"), best_ch_num);
2796 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002797 }
2798
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002799 sap_ctx->acs_cfg->pri_ch = best_ch_num;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002800 /* determine secondary channel for 2.4G channel 5, 6, 7 in HT40 */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002801 if ((operating_band != eCSR_DOT11_MODE_11g) ||
2802 (sap_ctx->acs_cfg->ch_width != CH_WIDTH_40MHZ))
2803 goto sap_ch_sel_end;
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002804 if (REGDOMAIN_FCC == domain)
bingse2782382017-03-23 10:34:52 +08002805 ht40plus2gendch = HT40PLUS_2G_FCC_CH_END;
2806 else
2807 ht40plus2gendch = HT40PLUS_2G_EURJAP_CH_END;
2808 if ((best_ch_num >= HT40MINUS_2G_CH_START) &&
2809 (best_ch_num <= ht40plus2gendch)) {
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002810 int weight_below, weight_above, i;
2811 tSapSpectChInfo *pspect_info;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002812
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002813 weight_below = weight_above = SAP_ACS_WEIGHT_MAX;
2814 pspect_info = spect_info->pSpectCh;
2815 for (i = 0; i < spect_info->numSpectChans; i++) {
2816 if (pspect_info[i].chNum == (best_ch_num - 4))
2817 weight_below = pspect_info[i].weight;
2818 if (pspect_info[i].chNum == (best_ch_num + 4))
2819 weight_above = pspect_info[i].weight;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002820 }
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002821
2822 if (weight_below < weight_above)
2823 sap_ctx->acs_cfg->ht_sec_ch =
2824 sap_ctx->acs_cfg->pri_ch - 4;
2825 else
2826 sap_ctx->acs_cfg->ht_sec_ch =
2827 sap_ctx->acs_cfg->pri_ch + 4;
2828 } else if (best_ch_num >= 1 && best_ch_num <= 4) {
2829 sap_ctx->acs_cfg->ht_sec_ch = sap_ctx->acs_cfg->pri_ch + 4;
bingse2782382017-03-23 10:34:52 +08002830 } else if (best_ch_num >= ht40plus2gendch && best_ch_num <=
2831 HT40MINUS_2G_CH_END) {
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002832 sap_ctx->acs_cfg->ht_sec_ch = sap_ctx->acs_cfg->pri_ch - 4;
2833 } else if (best_ch_num == 14) {
2834 sap_ctx->acs_cfg->ht_sec_ch = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002835 }
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002836 sap_ctx->secondary_ch = sap_ctx->acs_cfg->ht_sec_ch;
2837
2838sap_ch_sel_end:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002839 /* Free all the allocated memory */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002840 sap_chan_sel_exit(spect_info);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002841
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302842 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002843 FL("Running SAP Ch select Completed, Ch=%d"), best_ch_num);
Jeff Johnson6c336832019-03-26 09:09:08 -07002844 host_log_acs_best_chan(best_ch_num, best_ch_weight);
wadesongcb0ded22018-02-02 17:57:20 +08002845
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002846 if (best_ch_num > 0 && best_ch_num <= 252)
2847 return best_ch_num;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002848 else
2849 return SAP_CHANNEL_NOT_SELECTED;
2850}