blob: 1271eaac06240ca178c73d024888616a8d1e21b8 [file] [log] [blame]
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001/*
Himanshu Agarwalfee2e362018-01-18 20:26:35 +05302 * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003 *
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004 * Permission to use, copy, modify, and/or distribute this software for
5 * any purpose with or without fee is hereby granted, provided that the
6 * above copyright notice and this permission notice appear in all
7 * copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
10 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
11 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
12 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
13 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
14 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
15 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16 * PERFORMANCE OF THIS SOFTWARE.
17 */
18
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019/*===========================================================================
20
Anurag Chouhan6d760662016-02-20 16:05:43 +053021 s a p C h S e l e c t . C
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080022 OVERVIEW:
23
24 This software unit holds the implementation of the WLAN SAP modules
25 functions for channel selection.
26
27 DEPENDENCIES:
28
29 Are listed for each API below.
30 ===========================================================================*/
31
32/*--------------------------------------------------------------------------
33 Include Files
34 ------------------------------------------------------------------------*/
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +053035#include "qdf_trace.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080036#include "csr_api.h"
37#include "sme_api.h"
38#include "sap_ch_select.h"
39#include "sap_internal.h"
40#ifdef ANI_OS_TYPE_QNX
41#include "stdio.h"
42#endif
43#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
44#include "lim_utils.h"
45#include "parser_api.h"
jiad391c5282018-11-26 16:21:04 +080046#include <wlan_utility.h>
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080047#endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
Deepthi Gowri48b89332016-08-30 18:43:05 +053048#include "cds_utils.h"
Yuanyuan Liu0e0aa932016-05-12 10:17:58 -070049#include "pld_common.h"
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -070050#include "wlan_reg_services_api.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080051
52/*--------------------------------------------------------------------------
53 Function definitions
54 --------------------------------------------------------------------------*/
55
56/*--------------------------------------------------------------------------
57 Defines
58 --------------------------------------------------------------------------*/
59#define SAP_DEBUG
60
61#define IS_RSSI_VALID(extRssi, rssi) \
62 ( \
63 ((extRssi < rssi) ? true : false) \
64 )
65
Jeff Johnsone13d8062017-09-28 06:54:55 -070066#define SET_ACS_BAND(acs_band, sap_ctx) \
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080067{ \
Jeff Johnsone13d8062017-09-28 06:54:55 -070068 if (sap_ctx->acs_cfg->start_ch <= 14 && \
69 sap_ctx->acs_cfg->end_ch <= 14) \
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080070 acs_band = eCSR_DOT11_MODE_11g; \
Jeff Johnsone13d8062017-09-28 06:54:55 -070071 else if (sap_ctx->acs_cfg->start_ch >= 14)\
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080072 acs_band = eCSR_DOT11_MODE_11a; \
73 else \
74 acs_band = eCSR_DOT11_MODE_abg; \
75}
76
gaoleze5108942017-03-31 16:56:42 +080077#define ACS_WEIGHT_AMOUNT_LOCAL 240
78
79#define ACS_WEIGHT_AMOUNT_CONFIG(weights) \
80 (((weights) & 0xf) + \
81 (((weights) & 0xf0) >> 4) + \
82 (((weights) & 0xf00) >> 8) + \
83 (((weights) & 0xf000) >> 12) + \
84 (((weights) & 0xf0000) >> 16) + \
85 (((weights) & 0xf00000) >> 20))
86
87/*
88 * LSH/RSH 4 to enhance the accurate since
89 * need to do modulation to ACS_WEIGHT_AMOUNT_LOCAL.
90 */
91#define ACS_WEIGHT_COMPUTE(weights, weight, factor, base) \
92 (((((((((weight) << 4) * ACS_WEIGHT_AMOUNT_LOCAL * (factor)) + \
93 (ACS_WEIGHT_AMOUNT_CONFIG((weights)) >> 1)) / \
94 ACS_WEIGHT_AMOUNT_CONFIG((weights))) + \
95 ((base) >> 1)) / (base)) + 8) >> 4)
96
97#define ACS_WEIGHT_CFG_TO_LOCAL(weights, weight) \
98 (((((((weight) << 4) * ACS_WEIGHT_AMOUNT_LOCAL) + \
99 (ACS_WEIGHT_AMOUNT_CONFIG((weights)) >> 1)) / \
100 ACS_WEIGHT_AMOUNT_CONFIG((weights))) + 8) >> 4)
101
102#define ACS_WEIGHT_SOFTAP_RSSI_CFG(weights) \
103 ((weights) & 0xf)
104
105#define ACS_WEIGHT_SOFTAP_COUNT_CFG(weights) \
106 (((weights) & 0xf0) >> 4)
107
108#define ACS_WEIGHT_SOFTAP_NOISE_FLOOR_CFG(weights) \
109 (((weights) & 0xf00) >> 8)
110
111#define ACS_WEIGHT_SOFTAP_CHANNEL_FREE_CFG(weights) \
112 (((weights) & 0xf000) >> 12)
113
114#define ACS_WEIGHT_SOFTAP_TX_POWER_RANGE_CFG(weights) \
115 (((weights) & 0xf0000) >> 16)
116
117#define ACS_WEIGHT_SOFTAP_TX_POWER_THROUGHPUT_CFG(weights) \
118 (((weights) & 0xf00000) >> 20)
119
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800120#ifdef FEATURE_WLAN_CH_AVOID
Amar Singhalb8d4f152016-02-10 10:21:43 -0800121sapSafeChannelType safe_channels[NUM_CHANNELS] = {
122 {1, true},
123 {2, true},
124 {3, true},
125 {4, true},
126 {5, true},
127 {6, true},
128 {7, true},
129 {8, true},
130 {9, true},
131 {10, true},
132 {11, true},
133 {12, true},
134 {13, true},
135 {14, true},
136 {36, true},
137 {40, true},
138 {44, true},
139 {48, true},
140 {52, true},
141 {56, true},
142 {60, true},
143 {64, true},
144 {100, true},
145 {104, true},
146 {108, true},
147 {112, true},
148 {116, true},
149 {120, true},
150 {124, true},
151 {128, true},
152 {132, true},
153 {136, true},
154 {140, true},
155 {144, true},
156 {149, true},
157 {153, true},
158 {157, true},
159 {161, true},
160 {165, true},
Kiran Kumar Lokere1a43bcf2018-05-15 15:51:58 -0700161 {169, true},
162 {173, true},
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800163};
164#endif
165
166typedef struct {
167 uint16_t chStartNum;
168 uint32_t weight;
169} sapAcsChannelInfo;
170
171sapAcsChannelInfo acs_ht40_channels5_g[] = {
172 {36, SAP_ACS_WEIGHT_MAX},
173 {44, SAP_ACS_WEIGHT_MAX},
174 {52, SAP_ACS_WEIGHT_MAX},
175 {60, SAP_ACS_WEIGHT_MAX},
176 {100, SAP_ACS_WEIGHT_MAX},
177 {108, SAP_ACS_WEIGHT_MAX},
178 {116, SAP_ACS_WEIGHT_MAX},
179 {124, SAP_ACS_WEIGHT_MAX},
180 {132, SAP_ACS_WEIGHT_MAX},
181 {140, SAP_ACS_WEIGHT_MAX},
182 {149, SAP_ACS_WEIGHT_MAX},
183 {157, SAP_ACS_WEIGHT_MAX},
184};
185
186sapAcsChannelInfo acs_ht80_channels[] = {
187 {36, SAP_ACS_WEIGHT_MAX},
188 {52, SAP_ACS_WEIGHT_MAX},
189 {100, SAP_ACS_WEIGHT_MAX},
190 {116, SAP_ACS_WEIGHT_MAX},
191 {132, SAP_ACS_WEIGHT_MAX},
192 {149, SAP_ACS_WEIGHT_MAX},
193};
194
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -0700195sapAcsChannelInfo acs_vht160_channels[] = {
196 {36, SAP_ACS_WEIGHT_MAX},
197 {100, SAP_ACS_WEIGHT_MAX},
198};
199
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800200sapAcsChannelInfo acs_ht40_channels24_g[] = {
201 {1, SAP_ACS_WEIGHT_MAX},
202 {2, SAP_ACS_WEIGHT_MAX},
203 {3, SAP_ACS_WEIGHT_MAX},
204 {4, SAP_ACS_WEIGHT_MAX},
205 {9, SAP_ACS_WEIGHT_MAX},
206};
207
208#define CHANNEL_165 165
209
210/* rssi discount for channels in PCL */
211#define PCL_RSSI_DISCOUNT 10
212
213#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
214/**
215 * sap_check_n_add_channel() - checks and add given channel in sap context's
216 * avoid_channels_info struct
217 * @sap_ctx: sap context.
218 * @new_channel: channel to be added to sap_ctx's avoid ch info
219 *
220 * sap_ctx contains sap_avoid_ch_info strcut containing the list of channels on
221 * which MDM device's AP with MCC was detected. This function will add channels
222 * to that list after checking for duplicates.
223 *
224 * Return: true: if channel was added or already present
225 * else false: if channel list was already full.
226 */
Tang Yingying523322d2017-01-17 23:28:43 +0800227static bool
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -0700228sap_check_n_add_channel(struct sap_context *sap_ctx,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800229 uint8_t new_channel)
230{
231 uint8_t i = 0;
232 struct sap_avoid_channels_info *ie_info =
233 &sap_ctx->sap_detected_avoid_ch_ie;
234
235 for (i = 0; i < sizeof(ie_info->channels); i++) {
236 if (ie_info->channels[i] == new_channel)
237 break;
238
239 if (ie_info->channels[i] == 0) {
240 ie_info->channels[i] = new_channel;
241 break;
242 }
243 }
244 if (i == sizeof(ie_info->channels))
245 return false;
246 else
247 return true;
248}
249/**
250 * sap_check_n_add_overlapped_chnls() - checks & add overlapped channels
251 * to primary channel in 2.4Ghz band.
252 * @sap_ctx: sap context.
253 * @primary_chnl: primary channel to be avoided.
254 *
255 * sap_ctx contains sap_avoid_ch_info struct containing the list of channels on
256 * which MDM device's AP with MCC was detected. This function will add channels
257 * to that list after checking for duplicates.
258 *
259 * Return: true: if channel was added or already present
260 * else false: if channel list was already full.
261 */
262static bool
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -0700263sap_check_n_add_overlapped_chnls(struct sap_context *sap_ctx,
264 uint8_t primary_channel)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800265{
266 uint8_t i = 0, j = 0, upper_chnl = 0, lower_chnl = 0;
267 struct sap_avoid_channels_info *ie_info =
268 &sap_ctx->sap_detected_avoid_ch_ie;
269 /*
270 * if primary channel less than channel 1 or out of 2g band then
271 * no further process is required. return true in this case.
272 */
273 if (primary_channel < CHANNEL_1 || primary_channel > CHANNEL_14)
274 return true;
275
276 /* lower channel is one channel right before primary channel */
277 lower_chnl = primary_channel - 1;
278 /* upper channel is one channel right after primary channel */
279 upper_chnl = primary_channel + 1;
280
281 /* lower channel needs to be non-zero, zero is not valid channel */
282 if (lower_chnl > (CHANNEL_1 - 1)) {
283 for (i = 0; i < sizeof(ie_info->channels); i++) {
284 if (ie_info->channels[i] == lower_chnl)
285 break;
286 if (ie_info->channels[i] == 0) {
287 ie_info->channels[i] = lower_chnl;
288 break;
289 }
290 }
291 }
292 /* upper channel needs to be atleast last channel in 2.4Ghz band */
293 if (upper_chnl < (CHANNEL_14 + 1)) {
294 for (j = 0; j < sizeof(ie_info->channels); j++) {
295 if (ie_info->channels[j] == upper_chnl)
296 break;
297 if (ie_info->channels[j] == 0) {
298 ie_info->channels[j] = upper_chnl;
299 break;
300 }
301 }
302 }
303 if (i == sizeof(ie_info->channels) || j == sizeof(ie_info->channels))
304 return false;
305 else
306 return true;
307}
308
309/**
310 * sap_process_avoid_ie() - processes the detected Q2Q IE
311 * context's avoid_channels_info struct
Jeff Johnson7730fbb2018-11-08 13:48:27 -0800312 * @mac_handle: opaque handle to the MAC context
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800313 * @sap_ctx: sap context.
314 * @scan_result: scan results for ACS scan.
315 * @spect_info: spectrum weights array to update
316 *
317 * Detection of Q2Q IE indicates presence of another MDM device with its AP
318 * operating in MCC mode. This function parses the scan results and processes
319 * the Q2Q IE if found. It then extracts the channels and populates them in
320 * sap_ctx struct. It also increases the weights of those channels so that
321 * ACS logic will avoid those channels in its selection algorithm.
322 *
323 * Return: void
324 */
Jeff Johnson7730fbb2018-11-08 13:48:27 -0800325static void sap_process_avoid_ie(mac_handle_t mac_handle,
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -0700326 struct sap_context *sap_ctx,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800327 tScanResultHandle scan_result,
328 tSapChSelSpectInfo *spect_info)
329{
330 uint32_t total_ie_len = 0;
jiad391c5282018-11-26 16:21:04 +0800331 const uint8_t *temp_ptr = NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800332 uint8_t i = 0;
333 struct sAvoidChannelIE *avoid_ch_ie;
334 tCsrScanResultInfo *node = NULL;
Jeff Johnsonc59ef8b2018-12-02 12:01:21 -0800335 struct mac_context *mac_ctx = NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800336 tSapSpectChInfo *spect_ch = NULL;
337
Jeff Johnsona0619e42018-11-28 17:43:00 -0800338 mac_ctx = MAC_CONTEXT(mac_handle);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800339 spect_ch = spect_info->pSpectCh;
Jeff Johnson7730fbb2018-11-08 13:48:27 -0800340 node = sme_scan_result_get_first(mac_handle, scan_result);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800341
342 while (node) {
Abhishek Singh34a4d862016-10-26 16:01:51 +0530343 total_ie_len =
Jeff Johnson38e38a82017-10-06 10:32:31 -0700344 GET_IE_LEN_IN_BSS(node->BssDescriptor.length);
Naveen Rawat08db88f2017-09-08 15:07:48 -0700345 temp_ptr = wlan_get_vendor_ie_ptr_from_oui(
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800346 SIR_MAC_QCOM_VENDOR_OUI,
347 SIR_MAC_QCOM_VENDOR_SIZE,
348 ((uint8_t *)&node->BssDescriptor.ieFields),
349 total_ie_len);
350
351 if (temp_ptr) {
352 avoid_ch_ie = (struct sAvoidChannelIE *)temp_ptr;
Will Huang55ba1042017-03-22 10:43:30 +0800353 if (avoid_ch_ie->type !=
354 QCOM_VENDOR_IE_MCC_AVOID_CH) {
Jeff Johnson7730fbb2018-11-08 13:48:27 -0800355 node = sme_scan_result_get_next(mac_handle,
Will Huang55ba1042017-03-22 10:43:30 +0800356 scan_result);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800357 continue;
Will Huang55ba1042017-03-22 10:43:30 +0800358 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800359
360 sap_ctx->sap_detected_avoid_ch_ie.present = 1;
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530361 QDF_TRACE(QDF_MODULE_ID_SAP,
362 QDF_TRACE_LEVEL_DEBUG,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800363 "Q2Q IE - avoid ch %d",
364 avoid_ch_ie->channel);
365 /* add this channel to to_avoid channel list */
366 sap_check_n_add_channel(sap_ctx,
367 avoid_ch_ie->channel);
368 sap_check_n_add_overlapped_chnls(sap_ctx,
369 avoid_ch_ie->channel);
370 /*
371 * Mark weight of these channel present in IE to MAX
372 * so that ACS logic will to avoid thse channels
373 */
374 for (i = 0; i < spect_info->numSpectChans; i++)
375 if (spect_ch[i].chNum == avoid_ch_ie->channel) {
376 /*
377 * weight is set more than max so that,
378 * in the case of other channels being
379 * assigned max weight due to noise,
380 * they may be preferred over channels
381 * with Q2Q IE.
382 */
383 spect_ch[i].weight = SAP_ACS_WEIGHT_MAX + 1;
384 spect_ch[i].weight_copy =
385 SAP_ACS_WEIGHT_MAX + 1;
386 break;
387 }
388 } /* if (temp_ptr) */
Jeff Johnson7730fbb2018-11-08 13:48:27 -0800389 node = sme_scan_result_get_next(mac_handle, scan_result);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800390 }
391}
392#endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
393
394#ifdef FEATURE_WLAN_CH_AVOID
395/*==========================================================================
396 FUNCTION sap_update_unsafe_channel_list
397
398 DESCRIPTION
399 Function Undate unsafe channel list table
400
401 DEPENDENCIES
402 NA.
403
404 IN
405 SapContext pointer
406
407 RETURN VALUE
408 NULL
409 ============================================================================*/
Jeff Johnson7730fbb2018-11-08 13:48:27 -0800410void sap_update_unsafe_channel_list(mac_handle_t mac_handle,
411 struct sap_context *sap_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800412{
413 uint16_t i, j;
Amar Singhalb8d4f152016-02-10 10:21:43 -0800414 uint16_t unsafe_channel_list[NUM_CHANNELS];
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800415 uint16_t unsafe_channel_count = 0;
Jeff Johnsonc59ef8b2018-12-02 12:01:21 -0800416 struct mac_context *mac_ctx = NULL;
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -0700417
Yuanyuan Liu0e0aa932016-05-12 10:17:58 -0700418 qdf_device_t qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800419
Yuanyuan Liu97361182016-06-06 09:38:04 -0700420 if (!qdf_ctx) {
421 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_FATAL,
422 "qdf_ctx is NULL");
423 return;
424 }
Jeff Johnsona0619e42018-11-28 17:43:00 -0800425 mac_ctx = MAC_CONTEXT(mac_handle);
Yuanyuan Liu97361182016-06-06 09:38:04 -0700426
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800427 /* Flush, default set all channel safe */
Amar Singhalb8d4f152016-02-10 10:21:43 -0800428 for (i = 0; i < NUM_CHANNELS; i++) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800429 safe_channels[i].isSafe = true;
430 }
431
432 /* Try to find unsafe channel */
Ryan Hsu4252a2f2016-01-05 11:18:24 -0800433#if defined(FEATURE_WLAN_STA_AP_MODE_DFS_DISABLE)
Amar Singhalb8d4f152016-02-10 10:21:43 -0800434 for (i = 0; i < NUM_CHANNELS; i++) {
Jeff Johnsone13d8062017-09-28 06:54:55 -0700435 if (sap_ctx->dfs_ch_disable == true) {
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -0700436 if (wlan_reg_is_dfs_ch(mac_ctx->pdev,
437 safe_channels[i].channelNumber)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800438 safe_channels[i].isSafe = false;
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530439 QDF_TRACE(QDF_MODULE_ID_SAP,
440 QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800441 "%s: DFS Ch %d is not safe in"
442 " Concurrent mode",
443 __func__,
444 safe_channels[i].channelNumber);
445 }
446 }
447 }
448#endif
Yuanyuan Liu0e0aa932016-05-12 10:17:58 -0700449 pld_get_wlan_unsafe_channel(qdf_ctx->dev,
450 unsafe_channel_list,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800451 &unsafe_channel_count,
452 sizeof(unsafe_channel_list));
453
454 for (i = 0; i < unsafe_channel_count; i++) {
Amar Singhalb8d4f152016-02-10 10:21:43 -0800455 for (j = 0; j < NUM_CHANNELS; j++) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800456 if (safe_channels[j].channelNumber ==
457 unsafe_channel_list[i]) {
458 /* Found unsafe channel, update it */
459 safe_channels[j].isSafe = false;
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530460 QDF_TRACE(QDF_MODULE_ID_SAP,
461 QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800462 FL("CH %d is not safe"),
463 unsafe_channel_list[i]);
464 break;
465 }
466 }
467 }
468
469 return;
470}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800471
472#endif /* FEATURE_WLAN_CH_AVOID */
473
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800474/**
gaoleze5108942017-03-31 16:56:42 +0800475 * sap_channel_in_acs_channel_list() - check if channel in acs channel list
476 * @channel_num: channel to check
477 * @sap_ctx: struct ptSapContext
478 * @spect_info_params: strcut tSapChSelSpectInfo
479 *
480 * This function checks if specified channel is in the configured ACS channel
481 * list.
482 *
483 * Return: channel number if in acs channel list or SAP_CHANNEL_NOT_SELECTED
484 */
gaoleze5108942017-03-31 16:56:42 +0800485uint8_t sap_channel_in_acs_channel_list(uint8_t channel_num,
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -0700486 struct sap_context *sap_ctx,
gaoleze5108942017-03-31 16:56:42 +0800487 tSapChSelSpectInfo *spect_info_params)
488{
489 uint8_t i = 0;
490
491 if ((NULL == sap_ctx->acs_cfg->ch_list) ||
492 (NULL == spect_info_params))
493 return channel_num;
494
495 if (channel_num > 0 && channel_num <= 252) {
496 for (i = 0; i < sap_ctx->acs_cfg->ch_list_count; i++) {
497 if ((sap_ctx->acs_cfg->ch_list[i]) == channel_num)
498 return channel_num;
499 }
500 return SAP_CHANNEL_NOT_SELECTED;
501 } else {
502 return SAP_CHANNEL_NOT_SELECTED;
503 }
504}
505
506/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800507 * sap_select_preferred_channel_from_channel_list() - to calc best cahnnel
508 * @best_chnl: best channel already calculated among all the chanels
509 * @sap_ctx: sap context
510 * @spectinfo_param: Pointer to tSapChSelSpectInfo structure
511 *
512 * This function calculates the best channel among the configured channel list.
513 * If channel list not configured then returns the best channel calculated
514 * among all the channel list.
515 *
516 * Return: uint8_t best channel
517 */
Jeff Johnson464f7ea2016-10-07 10:21:26 -0700518static
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800519uint8_t sap_select_preferred_channel_from_channel_list(uint8_t best_chnl,
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -0700520 struct sap_context *sap_ctx,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800521 tSapChSelSpectInfo *spectinfo_param)
522{
523 uint8_t i = 0;
Jeff Johnsonc59ef8b2018-12-02 12:01:21 -0800524 struct mac_context *mac_ctx = sme_get_mac_context();
Tushnim Bhattacharyya518e80f2017-08-30 17:35:33 -0700525
526 if (NULL == mac_ctx) {
527 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
528 "pmac Global Context is NULL");
529 return SAP_CHANNEL_NOT_SELECTED;
530 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800531
532 /*
533 * If Channel List is not Configured don't do anything
534 * Else return the Best Channel from the Channel List
535 */
536 if ((NULL == sap_ctx->acs_cfg->ch_list) ||
537 (NULL == spectinfo_param) ||
538 (0 == sap_ctx->acs_cfg->ch_list_count))
539 return best_chnl;
540
541 if (best_chnl <= 0 || best_chnl > 252)
542 return SAP_CHANNEL_NOT_SELECTED;
543
544 /* Select the best channel from allowed list */
545 for (i = 0; i < sap_ctx->acs_cfg->ch_list_count; i++) {
Tushnim Bhattacharyya518e80f2017-08-30 17:35:33 -0700546 if ((sap_ctx->acs_cfg->ch_list[i] == best_chnl) &&
547 !(wlan_reg_is_dfs_ch(mac_ctx->pdev, best_chnl) &&
548 policy_mgr_disallow_mcc(mac_ctx->psoc, best_chnl))) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530549 QDF_TRACE(QDF_MODULE_ID_SAP,
Ravi Joshi9788fcd2018-02-13 15:12:22 -0800550 QDF_TRACE_LEVEL_INFO,
Naveen Rawatbec64d92017-09-13 14:35:21 -0700551 "Best channel so far is: %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800552 best_chnl);
553 return best_chnl;
554 }
555 }
556
557 return SAP_CHANNEL_NOT_SELECTED;
558}
559
Jeff Johnson7730fbb2018-11-08 13:48:27 -0800560/**
561 * sap_chan_sel_init() - Initialize channel select
562 * @mac_handle: Opaque handle to the global MAC context
563 * @pSpectInfoParams: Pointer to tSapChSelSpectInfo structure
564 * @sap_ctx: Pointer to SAP Context
565 *
566 * Function sap_chan_sel_init allocates the memory, initializes the
567 * structures used by the channel selection algorithm
568 *
569 * Return: bool Success or FAIL
570 */
571static bool sap_chan_sel_init(mac_handle_t mac_handle,
Jeff Johnson464f7ea2016-10-07 10:21:26 -0700572 tSapChSelSpectInfo *pSpectInfoParams,
Jeff Johnsone13d8062017-09-28 06:54:55 -0700573 struct sap_context *sap_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800574{
575 tSapSpectChInfo *pSpectCh = NULL;
576 uint8_t *pChans = NULL;
577 uint16_t channelnum = 0;
Jeff Johnsonc59ef8b2018-12-02 12:01:21 -0800578 struct mac_context *mac = MAC_CONTEXT(mac_handle);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800579 bool chSafe = true;
580#ifdef FEATURE_WLAN_CH_AVOID
581 uint16_t i;
582#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800583 bool include_dfs_ch = true;
Himanshu Agarwalfee2e362018-01-18 20:26:35 +0530584 uint8_t chan_num;
Bala Venkatesh2f25c812017-12-15 17:42:12 +0530585 bool sta_sap_scc_on_dfs_chan =
Jeff Johnsonb9794442018-11-22 14:21:08 -0800586 policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan(mac->psoc);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800587
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530588 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, "In %s",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800589 __func__);
590
591 pSpectInfoParams->numSpectChans =
Jeff Johnsonb9794442018-11-22 14:21:08 -0800592 mac->scan.base_channels.numChannels;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800593
594 /* Allocate memory for weight computation of 2.4GHz */
Arif Hussain256cc282018-10-03 14:10:44 -0700595 pSpectCh = qdf_mem_malloc((pSpectInfoParams->numSpectChans) *
596 sizeof(*pSpectCh));
597 if (!pSpectCh)
Srinivas Girigowda74a66d62017-06-21 23:28:25 -0700598 return false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800599
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800600 /* Initialize the pointers in the DfsParams to the allocated memory */
601 pSpectInfoParams->pSpectCh = pSpectCh;
602
Jeff Johnsonb9794442018-11-22 14:21:08 -0800603 pChans = mac->scan.base_channels.channelList;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800604
Ryan Hsu4252a2f2016-01-05 11:18:24 -0800605#if defined(FEATURE_WLAN_STA_AP_MODE_DFS_DISABLE)
Jeff Johnsone13d8062017-09-28 06:54:55 -0700606 if (sap_ctx->dfs_ch_disable == true)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800607 include_dfs_ch = false;
608#endif
Jeff Johnsonb9794442018-11-22 14:21:08 -0800609 if (!mac->mlme_cfg->dfs_cfg.dfs_master_capable ||
Jeff Johnsone13d8062017-09-28 06:54:55 -0700610 ACS_DFS_MODE_DISABLE == sap_ctx->dfs_mode)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800611 include_dfs_ch = false;
612
613 /* Fill the channel number in the spectrum in the operating freq band */
614 for (channelnum = 0;
615 channelnum < pSpectInfoParams->numSpectChans;
Edhar, Mahesh Kumar4f660672015-10-30 11:53:26 +0530616 channelnum++, pChans++, pSpectCh++) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800617 chSafe = true;
618
Himanshu Agarwal052ce252018-06-18 17:18:59 +0530619 pSpectCh->chNum = *pChans;
620 /* Initialise for all channels */
621 pSpectCh->rssiAgr = SOFTAP_MIN_RSSI;
622 /* Initialise 20MHz for all the Channels */
623 pSpectCh->channelWidth = SOFTAP_HT20_CHANNELWIDTH;
624 /* Initialise max ACS weight for all channels */
625 pSpectCh->weight = SAP_ACS_WEIGHT_MAX;
626
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800627 /* check if the channel is in NOL blacklist */
Himanshu Agarwal052ce252018-06-18 17:18:59 +0530628 if (sap_dfs_is_channel_in_nol_list(
629 sap_ctx, *pChans,
630 PHY_SINGLE_CHANNEL_CENTERED)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530631 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800632 "In %s, Ch %d is in NOL list", __func__,
633 *pChans);
634 chSafe = false;
635 continue;
636 }
637
Bala Venkatesh2f25c812017-12-15 17:42:12 +0530638 if (!include_dfs_ch || sta_sap_scc_on_dfs_chan) {
Jeff Johnsonb9794442018-11-22 14:21:08 -0800639 if (wlan_reg_is_dfs_ch(mac->pdev, *pChans)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800640 chSafe = false;
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530641 QDF_TRACE(QDF_MODULE_ID_SAP,
642 QDF_TRACE_LEVEL_INFO_HIGH,
Bala Venkatesh2f25c812017-12-15 17:42:12 +0530643 "In %s, DFS Ch %d not considered for ACS. include_dfs_ch %u, sta_sap_scc_on_dfs_chan %d",
644 __func__, *pChans, include_dfs_ch,
645 sta_sap_scc_on_dfs_chan);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800646 continue;
647 }
648 }
649
650#ifdef FEATURE_WLAN_CH_AVOID
Amar Singhalb8d4f152016-02-10 10:21:43 -0800651 for (i = 0; i < NUM_CHANNELS; i++) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800652 if ((safe_channels[i].channelNumber == *pChans) &&
653 (false == safe_channels[i].isSafe)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530654 QDF_TRACE(QDF_MODULE_ID_SAP,
655 QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800656 "In %s, Ch %d is not safe", __func__,
657 *pChans);
658 chSafe = false;
659 break;
660 }
661 }
662#endif /* FEATURE_WLAN_CH_AVOID */
663
664 /* OFDM rates are not supported on channel 14 */
665 if (*pChans == 14 &&
Jeff Johnsone13d8062017-09-28 06:54:55 -0700666 eCSR_DOT11_MODE_11b != sap_ctx->csr_roamProfile.phyMode) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800667 continue;
668 }
669
Deepthi Gowri48b89332016-08-30 18:43:05 +0530670 /* Skip DSRC channels */
Jeff Johnsonb9794442018-11-22 14:21:08 -0800671 if (wlan_reg_is_dsrc_chan(mac->pdev, *pChans))
Kiran Kumar Lokere1a43bcf2018-05-15 15:51:58 -0700672 continue;
673
lifeng0b46ae52018-12-13 09:42:27 +0800674 if (!mac->mlme_cfg->reg.etsi13_srd_chan_in_master_mode &&
Jeff Johnsonb9794442018-11-22 14:21:08 -0800675 wlan_reg_is_etsi13_srd_chan(mac->pdev, *pChans))
Deepthi Gowri48b89332016-08-30 18:43:05 +0530676 continue;
677
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800678 if (true == chSafe) {
Srinivas Girigowda74a66d62017-06-21 23:28:25 -0700679 pSpectCh->valid = true;
Himanshu Agarwalfee2e362018-01-18 20:26:35 +0530680 for (chan_num = 0; chan_num < sap_ctx->num_of_channel;
681 chan_num++) {
682 if (pSpectCh->chNum !=
683 sap_ctx->channelList[chan_num])
684 continue;
685
686 /*
687 * Initialize ACS weight to 0 for channels
688 * present in sap context scan channel list
689 */
690 pSpectCh->weight = 0;
691 break;
692 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800693 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800694 }
Srinivas Girigowda74a66d62017-06-21 23:28:25 -0700695 return true;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800696}
697
gaoleze5108942017-03-31 16:56:42 +0800698/**
699 * sapweight_rssi_count() - calculates the channel weight due to rssi
Anurag Chouhan6d760662016-02-20 16:05:43 +0530700 and data count(here number of BSS observed)
gaoleze5108942017-03-31 16:56:42 +0800701 * @sap_ctx : Softap context
702 * @rssi : Max signal strength receieved from a BSS for the channel
703 * @count : Number of BSS observed in the channel
704 *
705 * Return: uint32_t Calculated channel weight based on above two
706 */
707static
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -0700708uint32_t sapweight_rssi_count(struct sap_context *sap_ctx, int8_t rssi,
gaoleze5108942017-03-31 16:56:42 +0800709 uint16_t count)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800710{
711 int32_t rssiWeight = 0;
712 int32_t countWeight = 0;
713 uint32_t rssicountWeight = 0;
gaoleze5108942017-03-31 16:56:42 +0800714 uint8_t softap_rssi_weight_cfg, softap_count_weight_cfg;
715 uint8_t softap_rssi_weight_local, softap_count_weight_local;
716
717 softap_rssi_weight_cfg =
718 ACS_WEIGHT_SOFTAP_RSSI_CFG(sap_ctx->auto_channel_select_weight);
719
720 softap_count_weight_cfg =
721 ACS_WEIGHT_SOFTAP_COUNT_CFG(sap_ctx->auto_channel_select_weight);
722
723 softap_rssi_weight_local =
724 ACS_WEIGHT_CFG_TO_LOCAL(sap_ctx->auto_channel_select_weight,
725 softap_rssi_weight_cfg);
726
727 softap_count_weight_local =
728 ACS_WEIGHT_CFG_TO_LOCAL(sap_ctx->auto_channel_select_weight,
729 softap_count_weight_cfg);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800730
731 /* Weight from RSSI */
gaoleze5108942017-03-31 16:56:42 +0800732 rssiWeight = ACS_WEIGHT_COMPUTE(sap_ctx->auto_channel_select_weight,
733 softap_rssi_weight_cfg,
734 rssi - SOFTAP_MIN_RSSI,
735 SOFTAP_MAX_RSSI - SOFTAP_MIN_RSSI);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800736
gaoleze5108942017-03-31 16:56:42 +0800737 if (rssiWeight > softap_rssi_weight_local)
738 rssiWeight = softap_rssi_weight_local;
739
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800740 else if (rssiWeight < 0)
741 rssiWeight = 0;
742
743 /* Weight from data count */
gaoleze5108942017-03-31 16:56:42 +0800744 countWeight = ACS_WEIGHT_COMPUTE(sap_ctx->auto_channel_select_weight,
745 softap_count_weight_cfg,
746 count - SOFTAP_MIN_COUNT,
747 SOFTAP_MAX_COUNT - SOFTAP_MIN_COUNT);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800748
gaoleze5108942017-03-31 16:56:42 +0800749 if (countWeight > softap_count_weight_local)
750 countWeight = softap_count_weight_local;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800751
752 rssicountWeight = rssiWeight + countWeight;
753
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530754 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800755 "In %s, rssiWeight=%d, countWeight=%d, rssicountWeight=%d",
756 __func__, rssiWeight, countWeight, rssicountWeight);
757
758 return rssicountWeight;
759}
760
761/**
gaoleze5108942017-03-31 16:56:42 +0800762 * sap_get_channel_status() - get channel info via channel number
763 * @p_mac: Pointer to Global MAC structure
764 * @channel_id: channel id
765 *
766 * Return: chan status info
767 */
768static struct lim_channel_status *sap_get_channel_status
Jeff Johnsonc59ef8b2018-12-02 12:01:21 -0800769 (struct mac_context *p_mac, uint32_t channel_id)
gaoleze5108942017-03-31 16:56:42 +0800770{
771 return csr_get_channel_status(p_mac, channel_id);
772}
773
774/**
775 * sap_clear_channel_status() - clear chan info
776 * @p_mac: Pointer to Global MAC structure
777 *
778 * Return: none
779 */
Jeff Johnsonc59ef8b2018-12-02 12:01:21 -0800780static void sap_clear_channel_status(struct mac_context *p_mac)
gaoleze5108942017-03-31 16:56:42 +0800781{
782 csr_clear_channel_status(p_mac);
783}
784
785/**
786 * sap_weight_channel_noise_floor() - compute noise floor weight
787 * @sap_ctx: sap context
788 * @chn_stat: Pointer to chan status info
789 *
790 * Return: channel noise floor weight
791 */
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -0700792static uint32_t sap_weight_channel_noise_floor(struct sap_context *sap_ctx,
gaoleze5108942017-03-31 16:56:42 +0800793 struct lim_channel_status
794 *channel_stat)
795{
796 uint32_t noise_floor_weight;
797 uint8_t softap_nf_weight_cfg;
798 uint8_t softap_nf_weight_local;
799
800 softap_nf_weight_cfg =
801 ACS_WEIGHT_SOFTAP_NOISE_FLOOR_CFG
802 (sap_ctx->auto_channel_select_weight);
803
804 softap_nf_weight_local =
805 ACS_WEIGHT_CFG_TO_LOCAL(sap_ctx->auto_channel_select_weight,
806 softap_nf_weight_cfg);
807
808 if (channel_stat == NULL || channel_stat->channelfreq == 0) {
Srinivas Girigowda80213e52018-01-23 14:51:33 -0800809 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG,
gaoleze5108942017-03-31 16:56:42 +0800810 "In %s, sanity check failed return max weight",
811 __func__);
812 return softap_nf_weight_local;
813 }
814
815 noise_floor_weight = (channel_stat->noise_floor == 0) ? 0 :
816 (ACS_WEIGHT_COMPUTE(
817 sap_ctx->auto_channel_select_weight,
818 softap_nf_weight_cfg,
819 channel_stat->noise_floor -
820 SOFTAP_MIN_NF,
821 SOFTAP_MAX_NF - SOFTAP_MIN_NF));
822
823 if (noise_floor_weight > softap_nf_weight_local)
824 noise_floor_weight = softap_nf_weight_local;
gaoleze5108942017-03-31 16:56:42 +0800825
826 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
827 "In %s, nf=%d, nfwc=%d, nfwl=%d, nfw=%d",
828 __func__, channel_stat->noise_floor,
829 softap_nf_weight_cfg, softap_nf_weight_local,
830 noise_floor_weight);
831
832 return noise_floor_weight;
833}
834
835/**
836 * sap_weight_channel_free() - compute channel free weight
837 * @sap_ctx: sap context
838 * @chn_stat: Pointer to chan status info
839 *
840 * Return: channel free weight
841 */
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -0700842static uint32_t sap_weight_channel_free(struct sap_context *sap_ctx,
gaoleze5108942017-03-31 16:56:42 +0800843 struct lim_channel_status
844 *channel_stat)
845{
846 uint32_t channel_free_weight;
847 uint8_t softap_channel_free_weight_cfg;
848 uint8_t softap_channel_free_weight_local;
849 uint32_t rx_clear_count = 0;
850 uint32_t cycle_count = 0;
851
852 softap_channel_free_weight_cfg =
853 ACS_WEIGHT_SOFTAP_CHANNEL_FREE_CFG
854 (sap_ctx->auto_channel_select_weight);
855
856 softap_channel_free_weight_local =
857 ACS_WEIGHT_CFG_TO_LOCAL(sap_ctx->auto_channel_select_weight,
858 softap_channel_free_weight_cfg);
859
860 if (channel_stat == NULL || channel_stat->channelfreq == 0) {
Srinivas Girigowda80213e52018-01-23 14:51:33 -0800861 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG,
gaoleze5108942017-03-31 16:56:42 +0800862 "In %s, sanity check failed return max weight",
863 __func__);
864 return softap_channel_free_weight_local;
865 }
866
867 rx_clear_count = channel_stat->rx_clear_count -
868 channel_stat->tx_frame_count -
869 channel_stat->rx_frame_count;
870 cycle_count = channel_stat->cycle_count;
871
872 /* LSH 4, otherwise it is always 0. */
873 channel_free_weight = (cycle_count == 0) ? 0 :
874 (ACS_WEIGHT_COMPUTE(
875 sap_ctx->auto_channel_select_weight,
876 softap_channel_free_weight_cfg,
877 ((rx_clear_count << 8) +
878 (cycle_count >> 1))/cycle_count -
879 (SOFTAP_MIN_CHNFREE << 8),
880 (SOFTAP_MAX_CHNFREE -
881 SOFTAP_MIN_CHNFREE) << 8));
882
883 if (channel_free_weight > softap_channel_free_weight_local)
884 channel_free_weight = softap_channel_free_weight_local;
885
886 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
887 "In %s, rcc=%d, cc=%d, tc=%d, rc=%d, cfwc=%d, cfwl=%d, cfw=%d",
888 __func__, rx_clear_count, cycle_count,
889 channel_stat->tx_frame_count,
890 channel_stat->rx_frame_count,
891 softap_channel_free_weight_cfg,
892 softap_channel_free_weight_local,
893 channel_free_weight);
894
895 return channel_free_weight;
896}
897
898/**
899 * sap_weight_channel_txpwr_range() - compute channel tx power range weight
900 * @sap_ctx: sap context
901 * @chn_stat: Pointer to chan status info
902 *
903 * Return: tx power range weight
904 */
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -0700905static uint32_t sap_weight_channel_txpwr_range(struct sap_context *sap_ctx,
gaoleze5108942017-03-31 16:56:42 +0800906 struct lim_channel_status
907 *channel_stat)
908{
909 uint32_t txpwr_weight_low_speed;
910 uint8_t softap_txpwr_range_weight_cfg;
911 uint8_t softap_txpwr_range_weight_local;
912
913 softap_txpwr_range_weight_cfg =
914 ACS_WEIGHT_SOFTAP_TX_POWER_RANGE_CFG
915 (sap_ctx->auto_channel_select_weight);
916
917 softap_txpwr_range_weight_local =
918 ACS_WEIGHT_CFG_TO_LOCAL(sap_ctx->auto_channel_select_weight,
919 softap_txpwr_range_weight_cfg);
920
921 if (channel_stat == NULL || channel_stat->channelfreq == 0) {
Srinivas Girigowda80213e52018-01-23 14:51:33 -0800922 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG,
gaoleze5108942017-03-31 16:56:42 +0800923 "In %s, sanity check failed return max weight",
924 __func__);
925 return softap_txpwr_range_weight_local;
926 }
927
928 txpwr_weight_low_speed = (channel_stat->chan_tx_pwr_range == 0) ? 0 :
929 (ACS_WEIGHT_COMPUTE(
930 sap_ctx->auto_channel_select_weight,
931 softap_txpwr_range_weight_cfg,
932 SOFTAP_MAX_TXPWR -
933 channel_stat->chan_tx_pwr_range,
934 SOFTAP_MAX_TXPWR - SOFTAP_MIN_TXPWR));
935
936 if (txpwr_weight_low_speed > softap_txpwr_range_weight_local)
937 txpwr_weight_low_speed = softap_txpwr_range_weight_local;
938
939 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
940 "In %s, tpr=%d, tprwc=%d, tprwl=%d, tprw=%d",
941 __func__, channel_stat->chan_tx_pwr_range,
942 softap_txpwr_range_weight_cfg,
943 softap_txpwr_range_weight_local,
944 txpwr_weight_low_speed);
945
946 return txpwr_weight_low_speed;
947}
948
949/**
950 * sap_weight_channel_txpwr_tput() - compute channel tx power
951 * throughput weight
952 * @sap_ctx: sap context
953 * @chn_stat: Pointer to chan status info
954 *
955 * Return: tx power throughput weight
956 */
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -0700957static uint32_t sap_weight_channel_txpwr_tput(struct sap_context *sap_ctx,
gaoleze5108942017-03-31 16:56:42 +0800958 struct lim_channel_status
959 *channel_stat)
960{
961 uint32_t txpwr_weight_high_speed;
962 uint8_t softap_txpwr_tput_weight_cfg;
963 uint8_t softap_txpwr_tput_weight_local;
964
965 softap_txpwr_tput_weight_cfg =
966 ACS_WEIGHT_SOFTAP_TX_POWER_THROUGHPUT_CFG
967 (sap_ctx->auto_channel_select_weight);
968
969 softap_txpwr_tput_weight_local =
970 ACS_WEIGHT_CFG_TO_LOCAL(sap_ctx->auto_channel_select_weight,
971 softap_txpwr_tput_weight_cfg);
972
973 if (channel_stat == NULL || channel_stat->channelfreq == 0) {
Srinivas Girigowda80213e52018-01-23 14:51:33 -0800974 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG,
gaoleze5108942017-03-31 16:56:42 +0800975 "In %s, sanity check failed return max weight",
976 __func__);
977 return softap_txpwr_tput_weight_local;
978 }
979
980 txpwr_weight_high_speed = (channel_stat->chan_tx_pwr_throughput == 0)
981 ? 0 : (ACS_WEIGHT_COMPUTE(
982 sap_ctx->auto_channel_select_weight,
983 softap_txpwr_tput_weight_cfg,
984 SOFTAP_MAX_TXPWR -
985 channel_stat->chan_tx_pwr_throughput,
986 SOFTAP_MAX_TXPWR - SOFTAP_MIN_TXPWR));
987
988 if (txpwr_weight_high_speed > softap_txpwr_tput_weight_local)
989 txpwr_weight_high_speed = softap_txpwr_tput_weight_local;
990
991 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
992 "In %s, tpt=%d, tptwc=%d, tptwl=%d, tptw=%d",
993 __func__, channel_stat->chan_tx_pwr_throughput,
994 softap_txpwr_tput_weight_cfg,
995 softap_txpwr_tput_weight_local,
996 txpwr_weight_high_speed);
997
998 return txpwr_weight_high_speed;
999}
1000
1001/**
1002 * sap_weight_channel_status() - compute chan status weight
1003 * @sap_ctx: sap context
1004 * @chn_stat: Pointer to chan status info
1005 *
1006 * Return: chan status weight
1007 */
1008static
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -07001009uint32_t sap_weight_channel_status(struct sap_context *sap_ctx,
gaoleze5108942017-03-31 16:56:42 +08001010 struct lim_channel_status *channel_stat)
1011{
1012 return sap_weight_channel_noise_floor(sap_ctx, channel_stat) +
1013 sap_weight_channel_free(sap_ctx, channel_stat) +
1014 sap_weight_channel_txpwr_range(sap_ctx, channel_stat) +
1015 sap_weight_channel_txpwr_tput(sap_ctx, channel_stat);
1016}
1017
1018/**
Yeshwanth Sriram Guntuka273889e2018-02-16 17:11:46 +05301019 * sap_check_channels_same_band() - Check if two channels belong to same band
1020 * @ch_num1: channel number
1021 * @ch_num2: channel number
1022 *
1023 * Return: true if both channels belong to same band else false
1024 */
1025static bool sap_check_channels_same_band(uint16_t ch_num1, uint16_t ch_num2)
1026{
1027 if ((ch_num1 <= SIR_11B_CHANNEL_END &&
1028 ch_num2 <= SIR_11B_CHANNEL_END) ||
1029 (ch_num1 >= SIR_11A_CHANNEL_BEGIN &&
1030 ch_num2 >= SIR_11A_CHANNEL_BEGIN))
Srinivas Girigowdaeff16d92018-09-12 14:56:29 -07001031 return true;
Yeshwanth Sriram Guntuka273889e2018-02-16 17:11:46 +05301032
1033 return false;
1034}
1035
1036/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001037 * sap_update_rssi_bsscount() - updates bss count and rssi effect.
1038 *
1039 * @pSpectCh: Channel Information
1040 * @offset: Channel Offset
1041 * @sap_24g: Channel is in 2.4G or 5G
Liangwei Dong71ed6502016-10-20 03:40:45 -04001042 * @spectch_start: the start of spect ch array
1043 * @spectch_end: the end of spect ch array
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001044 *
1045 * sap_update_rssi_bsscount updates bss count and rssi effect based
1046 * on the channel offset.
1047 *
1048 * Return: None.
1049 */
1050
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001051static void sap_update_rssi_bsscount(tSapSpectChInfo *pSpectCh, int32_t offset,
Liangwei Dong71ed6502016-10-20 03:40:45 -04001052 bool sap_24g, tSapSpectChInfo *spectch_start,
1053 tSapSpectChInfo *spectch_end)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001054{
1055 tSapSpectChInfo *pExtSpectCh = NULL;
1056 int32_t rssi, rsssi_effect;
1057
1058 pExtSpectCh = (pSpectCh + offset);
Liangwei Dong71ed6502016-10-20 03:40:45 -04001059 if (pExtSpectCh != NULL &&
1060 pExtSpectCh >= spectch_start &&
1061 pExtSpectCh < spectch_end) {
Yeshwanth Sriram Guntuka273889e2018-02-16 17:11:46 +05301062 if (!sap_check_channels_same_band(pSpectCh->chNum,
1063 pExtSpectCh->chNum))
1064 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001065 ++pExtSpectCh->bssCount;
1066 switch (offset) {
1067 case -1:
1068 case 1:
1069 rsssi_effect = sap_24g ?
1070 SAP_24GHZ_FIRST_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY :
1071 SAP_SUBBAND1_RSSI_EFFECT_PRIMARY;
1072 break;
1073 case -2:
1074 case 2:
1075 rsssi_effect = sap_24g ?
1076 SAP_24GHZ_SEC_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY :
1077 SAP_SUBBAND2_RSSI_EFFECT_PRIMARY;
1078 break;
1079 case -3:
1080 case 3:
1081 rsssi_effect = sap_24g ?
1082 SAP_24GHZ_THIRD_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY :
1083 SAP_SUBBAND3_RSSI_EFFECT_PRIMARY;
1084 break;
1085 case -4:
1086 case 4:
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001087 rsssi_effect = sap_24g ?
1088 SAP_24GHZ_FOURTH_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY :
1089 SAP_SUBBAND4_RSSI_EFFECT_PRIMARY;
1090 break;
1091 case -5:
1092 case 5:
1093 rsssi_effect = SAP_SUBBAND5_RSSI_EFFECT_PRIMARY;
1094 break;
1095 case -6:
1096 case 6:
1097 rsssi_effect = SAP_SUBBAND6_RSSI_EFFECT_PRIMARY;
1098 break;
1099 case -7:
1100 case 7:
1101 rsssi_effect = SAP_SUBBAND7_RSSI_EFFECT_PRIMARY;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001102 break;
1103 default:
1104 rsssi_effect = 0;
1105 break;
1106 }
1107
1108 rssi = pSpectCh->rssiAgr + rsssi_effect;
1109 if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi))
1110 pExtSpectCh->rssiAgr = rssi;
1111 if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI)
1112 pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI;
1113 }
1114}
1115
1116/**
1117 * sap_upd_chan_spec_params() - sap_upd_chan_spec_params
1118 * updates channel parameters obtained from Beacon
1119 * @pBeaconStruct Beacon strucutre populated by parse_beacon function
1120 * @channelWidth Channel width
1121 * @secondaryChannelOffset Secondary Channel Offset
1122 * @vhtSupport If channel supports VHT
1123 * @centerFreq Central frequency for the given channel.
1124 *
1125 * sap_upd_chan_spec_params updates the spectrum channels based on the
1126 * pBeaconStruct obtained from Beacon IE
1127 *
1128 * Return: NA.
1129 */
1130
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001131static void sap_upd_chan_spec_params(tSirProbeRespBeacon *pBeaconStruct,
1132 uint16_t *channelWidth,
1133 uint16_t *secondaryChannelOffset,
1134 uint16_t *vhtSupport,
1135 uint16_t *centerFreq,
1136 uint16_t *centerFreq_2)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001137{
1138 if (NULL == pBeaconStruct) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301139 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001140 FL("pBeaconStruct is NULL"));
1141 return;
1142 }
1143
1144 if (pBeaconStruct->HTCaps.present && pBeaconStruct->HTInfo.present) {
1145 *channelWidth = pBeaconStruct->HTCaps.supportedChannelWidthSet;
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001146 *secondaryChannelOffset =
1147 pBeaconStruct->HTInfo.secondaryChannelOffset;
1148 if (!pBeaconStruct->VHTOperation.present)
1149 return;
1150 *vhtSupport = pBeaconStruct->VHTOperation.present;
1151 if (pBeaconStruct->VHTOperation.chanWidth) {
1152 *centerFreq =
1153 pBeaconStruct->VHTOperation.chanCenterFreqSeg1;
1154 *centerFreq_2 =
1155 pBeaconStruct->VHTOperation.chanCenterFreqSeg2;
1156 /*
1157 * LHS follows tSirMacHTChannelWidth, while RHS follows
1158 * WNI_CFG_VHT_CHANNEL_WIDTH_X format hence following
1159 * adjustment
1160 */
1161 *channelWidth =
1162 pBeaconStruct->VHTOperation.chanWidth + 1;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001163
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001164 }
1165 }
1166}
1167
1168/**
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001169 * sap_update_rssi_bsscount_vht_5G() - updates bss count and rssi effect.
1170 *
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001171 * @spect_ch: Channel Information
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001172 * @offset: Channel Offset
1173 * @num_ch: no.of channels
Liangwei Dong71ed6502016-10-20 03:40:45 -04001174 * @spectch_start: the start of spect ch array
1175 * @spectch_end: the end of spect ch array
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001176 *
1177 * sap_update_rssi_bsscount_vht_5G updates bss count and rssi effect based
1178 * on the channel offset.
1179 *
1180 * Return: None.
1181 */
1182
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001183static void sap_update_rssi_bsscount_vht_5G(tSapSpectChInfo *spect_ch,
1184 int32_t offset,
Liangwei Dong71ed6502016-10-20 03:40:45 -04001185 uint16_t num_ch,
1186 tSapSpectChInfo *spectch_start,
1187 tSapSpectChInfo *spectch_end)
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001188{
1189 int32_t ch_offset;
1190 uint16_t i, cnt;
1191
1192 if (!offset)
1193 return;
1194 if (offset > 0)
1195 cnt = num_ch;
1196 else
1197 cnt = num_ch + 1;
1198 for (i = 0; i < cnt; i++) {
1199 ch_offset = offset + i;
1200 if (ch_offset == 0)
1201 continue;
Liangwei Dong71ed6502016-10-20 03:40:45 -04001202 sap_update_rssi_bsscount(spect_ch, ch_offset, false,
1203 spectch_start, spectch_end);
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001204 }
1205}
1206/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001207 * sap_interference_rssi_count_5G() - sap_interference_rssi_count
1208 * considers the Adjacent channel rssi and
1209 * data count(here number of BSS observed)
1210 * @spect_ch: Channel Information
1211 * @chan_width: Channel width parsed from beacon IE
1212 * @sec_chan_offset: Secondary Channel Offset
1213 * @center_freq: Central frequency for the given channel.
1214 * @channel_id: channel_id
Liangwei Dong71ed6502016-10-20 03:40:45 -04001215 * @spectch_start: the start of spect ch array
1216 * @spectch_end: the end of spect ch array
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001217 *
1218 * sap_interference_rssi_count_5G considers the Adjacent channel rssi
1219 * and data count(here number of BSS observed)
1220 *
1221 * Return: NA.
1222 */
1223
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001224static void sap_interference_rssi_count_5G(tSapSpectChInfo *spect_ch,
1225 uint16_t chan_width,
1226 uint16_t sec_chan_offset,
1227 uint16_t center_freq,
1228 uint16_t center_freq_2,
Liangwei Dong71ed6502016-10-20 03:40:45 -04001229 uint8_t channel_id,
1230 tSapSpectChInfo *spectch_start,
1231 tSapSpectChInfo *spectch_end)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001232{
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001233 uint16_t num_ch;
1234 int32_t offset = 0;
Srinivas Girigowda4d65ebe2017-10-13 21:41:42 -07001235
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001236 if (NULL == spect_ch) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301237 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001238 FL("spect_ch is NULL"));
1239 return;
1240 }
1241
1242 /* Updating the received ChannelWidth */
1243 if (spect_ch->channelWidth != chan_width)
1244 spect_ch->channelWidth = chan_width;
1245 /* If received ChannelWidth is other than HT20,
1246 * we need to update the extension channel Params as well
1247 * chan_width == 0, HT20
1248 * chan_width == 1, HT40
1249 * chan_width == 2, VHT80
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001250 * chan_width == 3, VHT160
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001251 */
1252
1253 switch (spect_ch->channelWidth) {
1254 case eHT_CHANNEL_WIDTH_40MHZ: /* HT40 */
1255 switch (sec_chan_offset) {
1256 /* Above the Primary Channel */
1257 case PHY_DOUBLE_CHANNEL_LOW_PRIMARY:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001258 sap_update_rssi_bsscount(spect_ch, 1, false,
1259 spectch_start, spectch_end);
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001260 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001261
1262 /* Below the Primary channel */
1263 case PHY_DOUBLE_CHANNEL_HIGH_PRIMARY:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001264 sap_update_rssi_bsscount(spect_ch, -1, false,
1265 spectch_start, spectch_end);
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001266 return;
1267 }
1268 return;
1269 case eHT_CHANNEL_WIDTH_80MHZ: /* VHT80 */
1270 num_ch = 3;
1271 if ((center_freq - channel_id) == 6) {
1272 offset = 1;
1273 } else if ((center_freq - channel_id) == 2) {
1274 offset = -1;
1275 } else if ((center_freq - channel_id) == -2) {
1276 offset = -2;
1277 } else if ((center_freq - channel_id) == -6) {
1278 offset = -3;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001279 }
1280 break;
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001281 case eHT_CHANNEL_WIDTH_160MHZ: /* VHT160 */
1282 num_ch = 7;
1283 if ((center_freq - channel_id) == 14)
1284 offset = 1;
1285 else if ((center_freq - channel_id) == 10)
1286 offset = -1;
1287 else if ((center_freq - channel_id) == 6)
1288 offset = -2;
1289 else if ((center_freq - channel_id) == 2)
1290 offset = -3;
1291 else if ((center_freq - channel_id) == -2)
1292 offset = -4;
1293 else if ((center_freq - channel_id) == -6)
1294 offset = -5;
1295 else if ((center_freq - channel_id) == -10)
1296 offset = -6;
1297 else if ((center_freq - channel_id) == -14)
1298 offset = -7;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001299 break;
1300 default:
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001301 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001302 }
Liangwei Dong71ed6502016-10-20 03:40:45 -04001303 sap_update_rssi_bsscount_vht_5G(spect_ch, offset, num_ch,
1304 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001305}
1306
1307/**
1308 * sap_interference_rssi_count() - sap_interference_rssi_count
1309 * considers the Adjacent channel rssi
1310 * and data count(here number of BSS observed)
1311 * @spect_ch Channel Information
Liangwei Dong71ed6502016-10-20 03:40:45 -04001312 * @spectch_start: the start of spect ch array
1313 * @spectch_end: the end of spect ch array
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001314 *
1315 * sap_interference_rssi_count considers the Adjacent channel rssi
1316 * and data count(here number of BSS observed)
1317 *
1318 * Return: None.
1319 */
1320
Liangwei Dong71ed6502016-10-20 03:40:45 -04001321static void sap_interference_rssi_count(tSapSpectChInfo *spect_ch,
1322 tSapSpectChInfo *spectch_start,
1323 tSapSpectChInfo *spectch_end)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001324{
1325 if (NULL == spect_ch) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301326 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001327 "%s: spect_ch is NULL", __func__);
1328 return;
1329 }
1330
1331 switch (spect_ch->chNum) {
1332 case CHANNEL_1:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001333 sap_update_rssi_bsscount(spect_ch, 1, true,
1334 spectch_start, spectch_end);
1335 sap_update_rssi_bsscount(spect_ch, 2, true,
1336 spectch_start, spectch_end);
1337 sap_update_rssi_bsscount(spect_ch, 3, true,
1338 spectch_start, spectch_end);
1339 sap_update_rssi_bsscount(spect_ch, 4, true,
1340 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001341 break;
1342
1343 case CHANNEL_2:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001344 sap_update_rssi_bsscount(spect_ch, -1, true,
1345 spectch_start, spectch_end);
1346 sap_update_rssi_bsscount(spect_ch, 1, true,
1347 spectch_start, spectch_end);
1348 sap_update_rssi_bsscount(spect_ch, 2, true,
1349 spectch_start, spectch_end);
1350 sap_update_rssi_bsscount(spect_ch, 3, true,
1351 spectch_start, spectch_end);
1352 sap_update_rssi_bsscount(spect_ch, 4, true,
1353 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001354 break;
1355 case CHANNEL_3:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001356 sap_update_rssi_bsscount(spect_ch, -2, true,
1357 spectch_start, spectch_end);
1358 sap_update_rssi_bsscount(spect_ch, -1, true,
1359 spectch_start, spectch_end);
1360 sap_update_rssi_bsscount(spect_ch, 1, true,
1361 spectch_start, spectch_end);
1362 sap_update_rssi_bsscount(spect_ch, 2, true,
1363 spectch_start, spectch_end);
1364 sap_update_rssi_bsscount(spect_ch, 3, true,
1365 spectch_start, spectch_end);
1366 sap_update_rssi_bsscount(spect_ch, 4, true,
1367 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001368 break;
1369 case CHANNEL_4:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001370 sap_update_rssi_bsscount(spect_ch, -3, true,
1371 spectch_start, spectch_end);
1372 sap_update_rssi_bsscount(spect_ch, -2, true,
1373 spectch_start, spectch_end);
1374 sap_update_rssi_bsscount(spect_ch, -1, true,
1375 spectch_start, spectch_end);
1376 sap_update_rssi_bsscount(spect_ch, 1, true,
1377 spectch_start, spectch_end);
1378 sap_update_rssi_bsscount(spect_ch, 2, true,
1379 spectch_start, spectch_end);
1380 sap_update_rssi_bsscount(spect_ch, 3, true,
1381 spectch_start, spectch_end);
1382 sap_update_rssi_bsscount(spect_ch, 4, true,
1383 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001384 break;
1385
1386 case CHANNEL_5:
1387 case CHANNEL_6:
1388 case CHANNEL_7:
1389 case CHANNEL_8:
1390 case CHANNEL_9:
1391 case CHANNEL_10:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001392 sap_update_rssi_bsscount(spect_ch, -4, true,
1393 spectch_start, spectch_end);
1394 sap_update_rssi_bsscount(spect_ch, -3, true,
1395 spectch_start, spectch_end);
1396 sap_update_rssi_bsscount(spect_ch, -2, true,
1397 spectch_start, spectch_end);
1398 sap_update_rssi_bsscount(spect_ch, -1, true,
1399 spectch_start, spectch_end);
1400 sap_update_rssi_bsscount(spect_ch, 1, true,
1401 spectch_start, spectch_end);
1402 sap_update_rssi_bsscount(spect_ch, 2, true,
1403 spectch_start, spectch_end);
1404 sap_update_rssi_bsscount(spect_ch, 3, true,
1405 spectch_start, spectch_end);
1406 sap_update_rssi_bsscount(spect_ch, 4, true,
1407 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001408 break;
1409
1410 case CHANNEL_11:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001411 sap_update_rssi_bsscount(spect_ch, -4, true,
1412 spectch_start, spectch_end);
1413 sap_update_rssi_bsscount(spect_ch, -3, true,
1414 spectch_start, spectch_end);
1415 sap_update_rssi_bsscount(spect_ch, -2, true,
1416 spectch_start, spectch_end);
1417 sap_update_rssi_bsscount(spect_ch, -1, true,
1418 spectch_start, spectch_end);
1419 sap_update_rssi_bsscount(spect_ch, 1, true,
1420 spectch_start, spectch_end);
1421 sap_update_rssi_bsscount(spect_ch, 2, true,
1422 spectch_start, spectch_end);
1423 sap_update_rssi_bsscount(spect_ch, 3, true,
1424 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001425 break;
1426
1427 case CHANNEL_12:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001428 sap_update_rssi_bsscount(spect_ch, -4, true,
1429 spectch_start, spectch_end);
1430 sap_update_rssi_bsscount(spect_ch, -3, true,
1431 spectch_start, spectch_end);
1432 sap_update_rssi_bsscount(spect_ch, -2, 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, 1, true,
1437 spectch_start, spectch_end);
1438 sap_update_rssi_bsscount(spect_ch, 2, true,
1439 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001440 break;
1441
1442 case CHANNEL_13:
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);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001453 break;
1454
1455 case CHANNEL_14:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001456 sap_update_rssi_bsscount(spect_ch, -4, true,
1457 spectch_start, spectch_end);
1458 sap_update_rssi_bsscount(spect_ch, -3, true,
1459 spectch_start, spectch_end);
1460 sap_update_rssi_bsscount(spect_ch, -2, true,
1461 spectch_start, spectch_end);
1462 sap_update_rssi_bsscount(spect_ch, -1, true,
1463 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001464 break;
1465
1466 default:
1467 break;
1468 }
1469}
1470
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001471/**
1472 * ch_in_pcl() - Is channel in the Preferred Channel List (PCL)
1473 * @sap_ctx: SAP context which contains the current PCL
1474 * @channel: Input channel number to be checked
1475 *
1476 * Check if a channel is in the preferred channel list
1477 *
1478 * Return:
1479 * true: channel is in PCL,
1480 * false: channel is not in PCL
1481 */
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -07001482static bool ch_in_pcl(struct sap_context *sap_ctx, uint8_t channel)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001483{
1484 uint32_t i;
1485
1486 for (i = 0; i < sap_ctx->acs_cfg->pcl_ch_count; i++) {
1487 if (channel == sap_ctx->acs_cfg->pcl_channels[i])
1488 return true;
1489 }
1490
1491 return false;
1492}
1493
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001494/**
1495 * sap_compute_spect_weight() - Compute spectrum weight
1496 * @pSpectInfoParams: Pointer to the tSpectInfoParams structure
Jeff Johnson7730fbb2018-11-08 13:48:27 -08001497 * @mac_handle: Opaque handle to the global MAC context
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001498 * @pResult: Pointer to tScanResultHandle
1499 * @sap_ctx: Context of the SAP
1500 *
1501 * Main function for computing the weight of each channel in the
1502 * spectrum based on the RSSI value of the BSSes on the channel
1503 * and number of BSS
1504 */
1505static void sap_compute_spect_weight(tSapChSelSpectInfo *pSpectInfoParams,
Jeff Johnson7730fbb2018-11-08 13:48:27 -08001506 mac_handle_t mac_handle,
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001507 tScanResultHandle pResult,
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -07001508 struct sap_context *sap_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001509{
1510 int8_t rssi = 0;
1511 uint8_t chn_num = 0;
1512 uint8_t channel_id = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001513 tCsrScanResultInfo *pScanResult;
1514 tSapSpectChInfo *pSpectCh = pSpectInfoParams->pSpectCh;
1515 uint32_t operatingBand;
1516 uint16_t channelWidth;
1517 uint16_t secondaryChannelOffset;
1518 uint16_t centerFreq;
gaurank kathpalia859c9362018-08-02 23:07:21 +05301519 uint8_t i;
1520 bool found;
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001521 uint16_t centerFreq_2 = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001522 uint16_t vhtSupport;
1523 uint32_t ieLen = 0;
1524 tSirProbeRespBeacon *pBeaconStruct;
Jeff Johnsonc59ef8b2018-12-02 12:01:21 -08001525 struct mac_context *mac = MAC_CONTEXT(mac_handle);
Liangwei Dong71ed6502016-10-20 03:40:45 -04001526 tSapSpectChInfo *spectch_start = pSpectInfoParams->pSpectCh;
1527 tSapSpectChInfo *spectch_end = pSpectInfoParams->pSpectCh +
1528 pSpectInfoParams->numSpectChans;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001529
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301530 pBeaconStruct = qdf_mem_malloc(sizeof(tSirProbeRespBeacon));
Arif Hussain256cc282018-10-03 14:10:44 -07001531 if (!pBeaconStruct)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001532 return;
Arif Hussain256cc282018-10-03 14:10:44 -07001533
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301534 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001535 "In %s, Computing spectral weight", __func__);
1536
1537 /**
1538 * Soft AP specific channel weight calculation using DFS formula
1539 */
1540 SET_ACS_BAND(operatingBand, sap_ctx);
1541
Jeff Johnson7730fbb2018-11-08 13:48:27 -08001542 pScanResult = sme_scan_result_get_first(mac_handle, pResult);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001543
1544 while (pScanResult) {
1545 pSpectCh = pSpectInfoParams->pSpectCh;
1546 /* Defining the default values, so that any value will hold the default values */
1547 channelWidth = eHT_CHANNEL_WIDTH_20MHZ;
1548 secondaryChannelOffset = PHY_SINGLE_CHANNEL_CENTERED;
1549 vhtSupport = 0;
1550 centerFreq = 0;
1551
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001552
Yingying Tang22facc12016-10-20 17:43:59 +08001553 ieLen = GET_IE_LEN_IN_BSS(
1554 pScanResult->BssDescriptor.length);
1555 qdf_mem_set((uint8_t *) pBeaconStruct,
1556 sizeof(tSirProbeRespBeacon), 0);
1557
1558
1559 if ((sir_parse_beacon_ie
Jeff Johnsonb9794442018-11-22 14:21:08 -08001560 (mac, pBeaconStruct, (uint8_t *)
Yingying Tang22facc12016-10-20 17:43:59 +08001561 (pScanResult->BssDescriptor.ieFields),
Jeff Johnson83e30fa2018-06-07 23:01:11 -07001562 ieLen)) == QDF_STATUS_SUCCESS)
Yingying Tang22facc12016-10-20 17:43:59 +08001563 sap_upd_chan_spec_params(
1564 pBeaconStruct,
1565 &channelWidth,
1566 &secondaryChannelOffset,
1567 &vhtSupport, &centerFreq,
1568 &centerFreq_2);
1569
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001570 /* Processing for each tCsrScanResultInfo in the tCsrScanResult DLink list */
1571 for (chn_num = 0; chn_num < pSpectInfoParams->numSpectChans;
1572 chn_num++) {
1573
1574 /*
Himanshu Agarwalcf5b8932018-07-02 18:06:49 +05301575 * If the Beacon has channel ID, use it other wise we
1576 * will rely on the channelIdSelf
1577 */
1578 if (pScanResult->BssDescriptor.channelId == 0)
1579 channel_id =
1580 pScanResult->BssDescriptor.channelIdSelf;
1581 else
1582 channel_id =
1583 pScanResult->BssDescriptor.channelId;
1584
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001585 if (pSpectCh && (channel_id == pSpectCh->chNum)) {
1586 if (pSpectCh->rssiAgr <
1587 pScanResult->BssDescriptor.rssi)
1588 pSpectCh->rssiAgr =
1589 pScanResult->BssDescriptor.rssi;
1590
1591 ++pSpectCh->bssCount; /* Increment the count of BSS */
1592
1593 /*
1594 * Connsidering the Extension Channel
1595 * only in a channels
1596 */
1597 switch (operatingBand) {
1598 case eCSR_DOT11_MODE_11a:
1599 sap_interference_rssi_count_5G(
1600 pSpectCh, channelWidth,
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001601 secondaryChannelOffset,
1602 centerFreq,
1603 centerFreq_2,
Liangwei Dong71ed6502016-10-20 03:40:45 -04001604 channel_id,
1605 spectch_start,
1606 spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001607 break;
1608
1609 case eCSR_DOT11_MODE_11g:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001610 sap_interference_rssi_count(pSpectCh,
1611 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001612 break;
1613
1614 case eCSR_DOT11_MODE_abg:
Himanshu Agarwal4f503b82018-03-19 12:10:45 +05301615 if (pSpectCh->chNum >=
1616 SIR_11A_CHANNEL_BEGIN)
1617 sap_interference_rssi_count_5G(
1618 pSpectCh, channelWidth,
1619 secondaryChannelOffset,
1620 centerFreq,
1621 centerFreq_2,
1622 channel_id,
1623 spectch_start,
1624 spectch_end);
1625 else
1626 sap_interference_rssi_count(
1627 pSpectCh,
1628 spectch_start,
1629 spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001630 break;
1631 }
1632
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301633 QDF_TRACE(QDF_MODULE_ID_SAP,
1634 QDF_TRACE_LEVEL_INFO_HIGH,
Jeff Johnsona7c0ddb2017-09-18 08:14:12 -07001635 "In %s, bssdes.ch_self=%d, bssdes.ch_ID=%d, bssdes.rssi=%d, SpectCh.bssCount=%d, pScanResult=%pK, ChannelWidth %d, secondaryChanOffset %d, center frequency %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001636 __func__,
1637 pScanResult->BssDescriptor.
1638 channelIdSelf,
1639 pScanResult->BssDescriptor.channelId,
1640 pScanResult->BssDescriptor.rssi,
1641 pSpectCh->bssCount, pScanResult,
1642 pSpectCh->channelWidth,
1643 secondaryChannelOffset, centerFreq);
1644 pSpectCh++;
1645 break;
1646 } else {
1647 pSpectCh++;
1648 }
1649 }
1650
Jeff Johnson7730fbb2018-11-08 13:48:27 -08001651 pScanResult = sme_scan_result_get_next(mac_handle, pResult);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001652 }
1653
1654 /* Calculate the weights for all channels in the spectrum pSpectCh */
1655 pSpectCh = pSpectInfoParams->pSpectCh;
1656
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301657 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001658 "In %s, Spectrum Channels Weight", __func__);
1659
1660 for (chn_num = 0; chn_num < (pSpectInfoParams->numSpectChans);
1661 chn_num++) {
1662
1663 /*
1664 rssi : Maximum received signal strength among all BSS on that channel
1665 bssCount : Number of BSS on that channel
1666 */
1667
1668 rssi = (int8_t) pSpectCh->rssiAgr;
Himanshu Agarwal3697f942018-06-13 14:04:26 +05301669 if (ch_in_pcl(sap_ctx, pSpectCh->chNum))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001670 rssi -= PCL_RSSI_DISCOUNT;
1671
Himanshu Agarwal3697f942018-06-13 14:04:26 +05301672 if (rssi < SOFTAP_MIN_RSSI)
1673 rssi = SOFTAP_MIN_RSSI;
1674
hqub6441f22018-08-09 16:15:31 +08001675 if (pSpectCh->weight == SAP_ACS_WEIGHT_MAX) {
1676 pSpectCh->weight_copy = pSpectCh->weight;
Himanshu Agarwalfee2e362018-01-18 20:26:35 +05301677 goto debug_info;
hqub6441f22018-08-09 16:15:31 +08001678 }
Himanshu Agarwalfee2e362018-01-18 20:26:35 +05301679
gaurank kathpalia859c9362018-08-02 23:07:21 +05301680 /* There may be channels in scanlist, which were not sent to
1681 * FW for scanning as part of ACS scan list, but they do have an
1682 * effect on the neighbouring channels, so they help to find a
1683 * suitable channel, but there weight should be max as they were
1684 * and not meant to be included in the ACS scan results.
1685 * So just assign RSSI as -100, bsscount as 0, and weight as max
1686 * to them, so that they always stay low in sorting of best
1687 * channles which were included in ACS scan list
1688 */
1689 found = false;
1690 for (i = 0; i < sap_ctx->num_of_channel; i++) {
1691 if (pSpectCh->chNum == sap_ctx->channelList[i]) {
1692 /* Scan channel was included in ACS scan list */
1693 found = true;
1694 break;
1695 }
1696 }
1697
1698 if (found)
1699 pSpectCh->weight =
1700 SAPDFS_NORMALISE_1000 *
1701 (sapweight_rssi_count(sap_ctx, rssi,
1702 pSpectCh->bssCount) + sap_weight_channel_status(
Jeff Johnsonb9794442018-11-22 14:21:08 -08001703 sap_ctx, sap_get_channel_status(mac,
gaoleze5108942017-03-31 16:56:42 +08001704 pSpectCh->chNum)));
gaurank kathpalia859c9362018-08-02 23:07:21 +05301705 else {
1706 pSpectCh->weight = SAP_ACS_WEIGHT_MAX;
1707 pSpectCh->rssiAgr = SOFTAP_MIN_RSSI;
1708 rssi = SOFTAP_MIN_RSSI;
1709 pSpectCh->bssCount = SOFTAP_MIN_COUNT;
1710 }
1711
gaoleze5108942017-03-31 16:56:42 +08001712 if (pSpectCh->weight > SAP_ACS_WEIGHT_MAX)
1713 pSpectCh->weight = SAP_ACS_WEIGHT_MAX;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001714 pSpectCh->weight_copy = pSpectCh->weight;
1715
Himanshu Agarwalfee2e362018-01-18 20:26:35 +05301716debug_info:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001717 /* ------ Debug Info ------ */
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301718 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Himanshu Agarwal3697f942018-06-13 14:04:26 +05301719 "In %s, Chan=%d Weight= %d rssiAgr=%d rssi_pcl_discount: %d bssCount=%d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001720 __func__, pSpectCh->chNum, pSpectCh->weight,
Himanshu Agarwal3697f942018-06-13 14:04:26 +05301721 pSpectCh->rssiAgr, rssi, pSpectCh->bssCount);
wadesongcb0ded22018-02-02 17:57:20 +08001722 host_log_acs_chan_spect_weight(pSpectCh->chNum,
1723 (uint16_t)pSpectCh->weight,
1724 pSpectCh->rssiAgr,
1725 pSpectCh->bssCount);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001726 /* ------ Debug Info ------ */
1727 pSpectCh++;
1728 }
Jeff Johnsonb9794442018-11-22 14:21:08 -08001729 sap_clear_channel_status(mac);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301730 qdf_mem_free(pBeaconStruct);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001731}
1732
1733/*==========================================================================
1734 FUNCTION sap_chan_sel_exit
1735
1736 DESCRIPTION
1737 Exit function for free out the allocated memory, to be called
1738 at the end of the dfsSelectChannel function
1739
1740 DEPENDENCIES
1741 NA.
1742
1743 PARAMETERS
1744
1745 IN
1746 pSpectInfoParams : Pointer to the tSapChSelSpectInfo structure
1747
1748 RETURN VALUE
1749 void : NULL
1750
1751 SIDE EFFECTS
1752 ============================================================================*/
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001753static void sap_chan_sel_exit(tSapChSelSpectInfo *pSpectInfoParams)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001754{
1755 /* Free all the allocated memory */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301756 qdf_mem_free(pSpectInfoParams->pSpectCh);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001757}
1758
1759/*==========================================================================
1760 FUNCTION sap_sort_chl_weight
1761
1762 DESCRIPTION
Jeff Johnsonc7e4d162018-05-12 16:20:34 -07001763 Function to sort the channels with the least weight first for 20MHz channels
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001764
1765 DEPENDENCIES
1766 NA.
1767
1768 PARAMETERS
1769
1770 IN
1771 pSpectInfoParams : Pointer to the tSapChSelSpectInfo structure
1772
1773 RETURN VALUE
1774 void : NULL
1775
1776 SIDE EFFECTS
1777 ============================================================================*/
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001778static void sap_sort_chl_weight(tSapChSelSpectInfo *pSpectInfoParams)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001779{
1780 tSapSpectChInfo temp;
1781
1782 tSapSpectChInfo *pSpectCh = NULL;
1783 uint32_t i = 0, j = 0, minWeightIndex = 0;
1784
1785 pSpectCh = pSpectInfoParams->pSpectCh;
1786 for (i = 0; i < pSpectInfoParams->numSpectChans; i++) {
1787 minWeightIndex = i;
1788 for (j = i + 1; j < pSpectInfoParams->numSpectChans; j++) {
1789 if (pSpectCh[j].weight <
1790 pSpectCh[minWeightIndex].weight) {
1791 minWeightIndex = j;
Yeshwanth Sriram Guntuka273889e2018-02-16 17:11:46 +05301792 } else if (pSpectCh[j].weight ==
1793 pSpectCh[minWeightIndex].weight) {
1794 if (pSpectCh[j].bssCount <
1795 pSpectCh[minWeightIndex].bssCount)
1796 minWeightIndex = j;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001797 }
1798 }
1799 if (minWeightIndex != i) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301800 qdf_mem_copy(&temp, &pSpectCh[minWeightIndex],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001801 sizeof(*pSpectCh));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301802 qdf_mem_copy(&pSpectCh[minWeightIndex], &pSpectCh[i],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001803 sizeof(*pSpectCh));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301804 qdf_mem_copy(&pSpectCh[i], &temp, sizeof(*pSpectCh));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001805 }
1806 }
1807}
1808
1809/**
Jeff Johnsonc7e4d162018-05-12 16:20:34 -07001810 * set_ht80_chl_bit() - to set available channel to ht80 channel bitmap
bingse2782382017-03-23 10:34:52 +08001811 * @channel_bitmap: Pointer to the chan_bonding_bitmap structure
1812 * @spect_info_params: Pointer to the tSapChSelSpectInfo structure
1813 *
1814 * Return: none
1815 */
1816static void set_ht80_chl_bit(chan_bonding_bitmap *channel_bitmap,
1817 tSapChSelSpectInfo *spec_info_params)
1818{
1819 uint8_t i, j;
1820 tSapSpectChInfo *spec_info;
1821 int start_channel = 0;
1822
1823 channel_bitmap->chanBondingSet[0].startChannel =
1824 acs_ht80_channels[0].chStartNum;
1825 channel_bitmap->chanBondingSet[1].startChannel =
1826 acs_ht80_channels[1].chStartNum;
1827 channel_bitmap->chanBondingSet[2].startChannel =
1828 acs_ht80_channels[2].chStartNum;
1829 channel_bitmap->chanBondingSet[3].startChannel =
1830 acs_ht80_channels[3].chStartNum;
1831 channel_bitmap->chanBondingSet[4].startChannel =
1832 acs_ht80_channels[4].chStartNum;
1833 channel_bitmap->chanBondingSet[5].startChannel =
1834 acs_ht80_channels[5].chStartNum;
1835
1836 spec_info = spec_info_params->pSpectCh;
1837 for (j = 0; j < spec_info_params->numSpectChans; j++) {
1838 for (i = 0; i < MAX_80MHZ_BANDS; i++) {
1839 start_channel =
1840 channel_bitmap->chanBondingSet[i].startChannel;
1841 if (spec_info[j].chNum >= start_channel &&
1842 (spec_info[j].chNum <= start_channel + 12)) {
1843 channel_bitmap->chanBondingSet[i].channelMap |=
1844 1 << ((spec_info[j].chNum -
1845 start_channel)/4);
1846 break;
1847 }
1848 }
1849 }
1850}
1851
1852/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001853 * sap_sort_chl_weight_ht80() - to sort the channels with the least weight
1854 * @pSpectInfoParams: Pointer to the tSapChSelSpectInfo structure
1855 *
Jeff Johnsonc7e4d162018-05-12 16:20:34 -07001856 * Function to sort the channels with the least weight first for HT80 channels
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001857 *
1858 * Return: none
1859 */
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001860static void sap_sort_chl_weight_ht80(tSapChSelSpectInfo *pSpectInfoParams)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001861{
1862 uint8_t i, j, n;
1863 tSapSpectChInfo *pSpectInfo;
1864 uint8_t minIdx;
bingse2782382017-03-23 10:34:52 +08001865 int start_channel = 0;
1866 chan_bonding_bitmap *channel_bitmap;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001867
bingse2782382017-03-23 10:34:52 +08001868 channel_bitmap = qdf_mem_malloc(sizeof(chan_bonding_bitmap));
Arif Hussain256cc282018-10-03 14:10:44 -07001869 if (!channel_bitmap)
bingse2782382017-03-23 10:34:52 +08001870 return;
Arif Hussain256cc282018-10-03 14:10:44 -07001871
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001872 pSpectInfo = pSpectInfoParams->pSpectCh;
1873 /* for each HT80 channel, calculate the combined weight of the
1874 four 20MHz weight */
1875 for (i = 0; i < ARRAY_SIZE(acs_ht80_channels); i++) {
1876 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
1877 if (pSpectInfo[j].chNum ==
1878 acs_ht80_channels[i].chStartNum)
1879 break;
1880 }
1881 if (j == pSpectInfoParams->numSpectChans)
1882 continue;
1883
1884 if (!(((pSpectInfo[j].chNum + 4) == pSpectInfo[j + 1].chNum) &&
1885 ((pSpectInfo[j].chNum + 8) ==
1886 pSpectInfo[j + 2].chNum) &&
1887 ((pSpectInfo[j].chNum + 12) ==
1888 pSpectInfo[j + 3].chNum))) {
1889 /*
1890 * some channels does not exist in pSectInfo array,
1891 * skip this channel and those in the same HT80 width
1892 */
1893 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 4;
1894 if ((pSpectInfo[j].chNum + 4) ==
1895 pSpectInfo[j + 1].chNum)
1896 pSpectInfo[j + 1].weight =
1897 SAP_ACS_WEIGHT_MAX * 4;
1898 if ((pSpectInfo[j].chNum + 8) ==
1899 pSpectInfo[j + 2].chNum)
1900 pSpectInfo[j + 2].weight =
1901 SAP_ACS_WEIGHT_MAX * 4;
1902 if ((pSpectInfo[j].chNum + 12) ==
1903 pSpectInfo[j + 3].chNum)
1904 pSpectInfo[j + 3].weight =
1905 SAP_ACS_WEIGHT_MAX * 4;
1906 continue;
1907 }
1908 /*found the channel, add the 4 adjacent channels' weight */
1909 acs_ht80_channels[i].weight = pSpectInfo[j].weight +
1910 pSpectInfo[j + 1].weight + pSpectInfo[j + 2].weight +
1911 pSpectInfo[j + 3].weight;
1912 /* find best channel among 4 channels as the primary channel */
1913 if ((pSpectInfo[j].weight + pSpectInfo[j + 1].weight) <
1914 (pSpectInfo[j + 2].weight + pSpectInfo[j + 3].weight)) {
1915 /* lower 2 channels are better choice */
1916 if (pSpectInfo[j].weight < pSpectInfo[j + 1].weight)
1917 minIdx = 0;
1918 else
1919 minIdx = 1;
1920 } else if (pSpectInfo[j + 2].weight <=
1921 pSpectInfo[j + 3].weight) {
1922 /* upper 2 channels are better choice */
1923 minIdx = 2;
1924 } else {
1925 minIdx = 3;
1926 }
1927
1928 /*
1929 * set all 4 channels to max value first, then reset the
1930 * best channel as the selected primary channel, update its
1931 * weightage with the combined weight value
1932 */
1933 for (n = 0; n < 4; n++)
1934 pSpectInfo[j + n].weight = SAP_ACS_WEIGHT_MAX * 4;
1935
1936 pSpectInfo[j + minIdx].weight = acs_ht80_channels[i].weight;
1937 }
1938
bingse2782382017-03-23 10:34:52 +08001939 /*
1940 * mark the weight of the channel that can't satisfy 80MHZ
1941 * as max value, so that it will be sorted to the bottom
1942 */
1943 set_ht80_chl_bit(channel_bitmap, pSpectInfoParams);
1944 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
1945 for (i = 0; i < MAX_80MHZ_BANDS; i++) {
1946 start_channel =
1947 channel_bitmap->chanBondingSet[i].startChannel;
1948 if (pSpectInfo[j].chNum >= start_channel &&
1949 (pSpectInfo[j].chNum <=
1950 start_channel + 12) &&
1951 channel_bitmap->chanBondingSet[i].channelMap !=
1952 SAP_80MHZ_MASK)
1953 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 4;
1954 }
1955 }
1956
Himanshu Agarwal75e74412018-02-01 20:51:47 +05301957 /*
1958 * Assign max weight(SAP_ACS_WEIGHT_MAX * 4) to 2.4 Ghz channels
1959 * and channel 165 as they cannot be part of a 80Mhz channel bonding.
1960 */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001961 pSpectInfo = pSpectInfoParams->pSpectCh;
1962 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
Himanshu Agarwal75e74412018-02-01 20:51:47 +05301963 if ((pSpectInfo[j].chNum >= WLAN_REG_CH_NUM(CHAN_ENUM_1) &&
1964 pSpectInfo[j].chNum <= WLAN_REG_CH_NUM(CHAN_ENUM_14)) ||
1965 (CHANNEL_165 == pSpectInfo[j].chNum))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001966 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 4;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001967 }
1968
Manishekar Chandrasekaran44e334f2016-05-30 16:42:50 +05301969 sap_sort_chl_weight(pSpectInfoParams);
1970
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001971 pSpectInfo = pSpectInfoParams->pSpectCh;
1972 for (j = 0; j < (pSpectInfoParams->numSpectChans); j++) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301973 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001974 FL("Channel=%d Weight= %d rssi=%d bssCount=%d"),
1975 pSpectInfo->chNum, pSpectInfo->weight,
1976 pSpectInfo->rssiAgr, pSpectInfo->bssCount);
1977 pSpectInfo++;
1978 }
bingse2782382017-03-23 10:34:52 +08001979 qdf_mem_free(channel_bitmap);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001980}
1981
1982/**
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001983 * sap_sort_chl_weight_vht160() - to sort the channels with the least weight
1984 * @pSpectInfoParams: Pointer to the tSapChSelSpectInfo structure
1985 *
Jeff Johnsonc7e4d162018-05-12 16:20:34 -07001986 * Function to sort the channels with the least weight first for VHT160 channels
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001987 *
1988 * Return: none
1989 */
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001990static void sap_sort_chl_weight_vht160(tSapChSelSpectInfo *pSpectInfoParams)
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001991{
1992 uint8_t i, j, n, idx;
1993 tSapSpectChInfo *pSpectInfo;
1994 uint8_t minIdx;
1995
1996 pSpectInfo = pSpectInfoParams->pSpectCh;
1997 /* for each VHT160 channel, calculate the combined weight of the
1998 8 20MHz weight */
1999 for (i = 0; i < ARRAY_SIZE(acs_vht160_channels); i++) {
2000 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
2001 if (pSpectInfo[j].chNum ==
2002 acs_vht160_channels[i].chStartNum)
2003 break;
2004 }
2005 if (j == pSpectInfoParams->numSpectChans)
2006 continue;
2007
2008 if (!(((pSpectInfo[j].chNum + 4) == pSpectInfo[j + 1].chNum) &&
2009 ((pSpectInfo[j].chNum + 8) ==
2010 pSpectInfo[j + 2].chNum) &&
2011 ((pSpectInfo[j].chNum + 12) ==
2012 pSpectInfo[j + 3].chNum) &&
2013 ((pSpectInfo[j].chNum + 16) ==
2014 pSpectInfo[j + 4].chNum) &&
2015 ((pSpectInfo[j].chNum + 20) ==
2016 pSpectInfo[j + 5].chNum) &&
2017 ((pSpectInfo[j].chNum + 24) ==
2018 pSpectInfo[j + 6].chNum) &&
2019 ((pSpectInfo[j].chNum + 28) ==
2020 pSpectInfo[j + 7].chNum))) {
2021 /*
2022 * some channels does not exist in pSectInfo array,
2023 * skip this channel and those in the same VHT160 width
2024 */
2025 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 8;
2026 if ((pSpectInfo[j].chNum + 4) ==
2027 pSpectInfo[j + 1].chNum)
2028 pSpectInfo[j + 1].weight =
2029 SAP_ACS_WEIGHT_MAX * 8;
2030 if ((pSpectInfo[j].chNum + 8) ==
2031 pSpectInfo[j + 2].chNum)
2032 pSpectInfo[j + 2].weight =
2033 SAP_ACS_WEIGHT_MAX * 8;
2034 if ((pSpectInfo[j].chNum + 12) ==
2035 pSpectInfo[j + 3].chNum)
2036 pSpectInfo[j + 3].weight =
2037 SAP_ACS_WEIGHT_MAX * 8;
2038 if ((pSpectInfo[j].chNum + 16) ==
2039 pSpectInfo[j + 4].chNum)
2040 pSpectInfo[j + 4].weight =
2041 SAP_ACS_WEIGHT_MAX * 8;
2042 if ((pSpectInfo[j].chNum + 20) ==
2043 pSpectInfo[j + 5].chNum)
2044 pSpectInfo[j + 5].weight =
2045 SAP_ACS_WEIGHT_MAX * 8;
2046 if ((pSpectInfo[j].chNum + 24) ==
2047 pSpectInfo[j + 6].chNum)
2048 pSpectInfo[j + 6].weight =
2049 SAP_ACS_WEIGHT_MAX * 8;
2050 if ((pSpectInfo[j].chNum + 28) ==
2051 pSpectInfo[j + 7].chNum)
2052 pSpectInfo[j + 7].weight =
2053 SAP_ACS_WEIGHT_MAX * 8;
2054 continue;
2055 }
2056 /*found the channel, add the 7 adjacent channels' weight */
2057 acs_vht160_channels[i].weight = pSpectInfo[j].weight +
2058 pSpectInfo[j + 1].weight + pSpectInfo[j + 2].weight +
2059 pSpectInfo[j + 3].weight + pSpectInfo[j + 4].weight +
2060 pSpectInfo[j + 5].weight + pSpectInfo[j + 6].weight +
2061 pSpectInfo[j + 7].weight;
2062
2063 /* find best channel among 8 channels as the primary channel */
2064 if ((pSpectInfo[j].weight + pSpectInfo[j + 1].weight +
2065 pSpectInfo[j + 2].weight + pSpectInfo[j + 3].weight) >
2066 (pSpectInfo[j + 4].weight + pSpectInfo[j + 5].weight +
2067 pSpectInfo[j + 6].weight + pSpectInfo[j + 7].weight))
2068 idx = 4;
2069 else
2070 idx = 0;
2071 /* find best channel among 4 channels as the primary channel */
2072 if ((pSpectInfo[j + idx].weight +
2073 pSpectInfo[j + idx + 1].weight) <
2074 (pSpectInfo[j + idx + 2].weight +
2075 pSpectInfo[j + idx + 3].weight)) {
2076 /* lower 2 channels are better choice */
2077 if (pSpectInfo[j + idx].weight <
2078 pSpectInfo[j + idx + 1].weight)
2079 minIdx = 0 + idx;
2080 else
2081 minIdx = 1 + idx;
2082 } else if (pSpectInfo[j + idx + 2].weight <=
2083 pSpectInfo[j + idx + 3].weight) {
2084 /* upper 2 channels are better choice */
2085 minIdx = 2 + idx;
2086 } else {
2087 minIdx = 3 + idx;
2088 }
2089
2090 /*
2091 * set all 8 channels to max value first, then reset the
2092 * best channel as the selected primary channel, update its
2093 * weightage with the combined weight value
2094 */
2095 for (n = 0; n < 8; n++)
2096 pSpectInfo[j + n].weight = SAP_ACS_WEIGHT_MAX * 8;
2097
2098 pSpectInfo[j + minIdx].weight = acs_vht160_channels[i].weight;
2099 }
2100
Himanshu Agarwal75e74412018-02-01 20:51:47 +05302101 /*
2102 * Assign max weight(SAP_ACS_WEIGHT_MAX * 8) to 2.4 Ghz channels
Kiran Kumar Lokere1a43bcf2018-05-15 15:51:58 -07002103 * and channel 132-173 as they cannot be part of a 160Mhz channel
Himanshu Agarwal75e74412018-02-01 20:51:47 +05302104 * bonding.
2105 */
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07002106 pSpectInfo = pSpectInfoParams->pSpectCh;
2107 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
Himanshu Agarwal75e74412018-02-01 20:51:47 +05302108 if ((pSpectInfo[j].chNum >= WLAN_REG_CH_NUM(CHAN_ENUM_1) &&
2109 pSpectInfo[j].chNum <= WLAN_REG_CH_NUM(CHAN_ENUM_14)) ||
2110 (pSpectInfo[j].chNum >= WLAN_REG_CH_NUM(CHAN_ENUM_132) &&
Kiran Kumar Lokere1a43bcf2018-05-15 15:51:58 -07002111 pSpectInfo[j].chNum <= WLAN_REG_CH_NUM(CHAN_ENUM_173)))
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07002112 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 8;
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07002113 }
2114
Manishekar Chandrasekaran44e334f2016-05-30 16:42:50 +05302115 sap_sort_chl_weight(pSpectInfoParams);
2116
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07002117 pSpectInfo = pSpectInfoParams->pSpectCh;
2118 for (j = 0; j < (pSpectInfoParams->numSpectChans); j++) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302119 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07002120 FL("Channel=%d Weight= %d rssi=%d bssCount=%d"),
2121 pSpectInfo->chNum, pSpectInfo->weight,
2122 pSpectInfo->rssiAgr, pSpectInfo->bssCount);
2123 pSpectInfo++;
2124 }
2125}
2126
2127/**
Himanshu Agarwal91c5c0f2018-02-13 14:40:56 +05302128 * sap_allocate_max_weight_ht40_24_g() - allocate max weight for 40Mhz
2129 * to all 2.4Ghz channels
2130 * @spect_info_params: Pointer to the tSapChSelSpectInfo structure
2131 *
2132 * Return: none
2133 */
2134static void sap_allocate_max_weight_ht40_24_g(
2135 tSapChSelSpectInfo *spect_info_params)
2136{
2137 tSapSpectChInfo *spect_info;
2138 uint8_t j;
2139
2140 /*
2141 * Assign max weight for 40Mhz (SAP_ACS_WEIGHT_MAX * 2) to all
2142 * 2.4 Ghz channels
2143 */
2144 spect_info = spect_info_params->pSpectCh;
2145 for (j = 0; j < spect_info_params->numSpectChans; j++) {
2146 if ((spect_info[j].chNum >= WLAN_REG_CH_NUM(CHAN_ENUM_1) &&
2147 spect_info[j].chNum <= WLAN_REG_CH_NUM(CHAN_ENUM_14)))
2148 spect_info[j].weight = SAP_ACS_WEIGHT_MAX * 2;
2149 }
2150}
2151
2152/**
2153 * sap_allocate_max_weight_ht40_5_g() - allocate max weight for 40Mhz
2154 * to all 5Ghz channels
2155 * @spect_info_params: Pointer to the tSapChSelSpectInfo structure
2156 *
2157 * Return: none
2158 */
2159static void sap_allocate_max_weight_ht40_5_g(
2160 tSapChSelSpectInfo *spect_info_params)
2161{
2162 tSapSpectChInfo *spect_info;
2163 uint8_t j;
2164
2165 /*
2166 * Assign max weight for 40Mhz (SAP_ACS_WEIGHT_MAX * 2) to all
2167 * 5 Ghz channels
2168 */
2169 spect_info = spect_info_params->pSpectCh;
2170 for (j = 0; j < spect_info_params->numSpectChans; j++) {
2171 if ((spect_info[j].chNum >= WLAN_REG_CH_NUM(CHAN_ENUM_36) &&
Kiran Kumar Lokere1a43bcf2018-05-15 15:51:58 -07002172 spect_info[j].chNum <= WLAN_REG_CH_NUM(CHAN_ENUM_173)))
Himanshu Agarwal91c5c0f2018-02-13 14:40:56 +05302173 spect_info[j].weight = SAP_ACS_WEIGHT_MAX * 2;
2174 }
2175}
2176
2177/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002178 * sap_sort_chl_weight_ht40_24_g() - to sort channel with the least weight
2179 * @pSpectInfoParams: Pointer to the tSapChSelSpectInfo structure
2180 *
Jeff Johnsonc7e4d162018-05-12 16:20:34 -07002181 * Function to sort the channels with the least weight first for HT40 channels
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002182 *
2183 * Return: none
2184 */
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002185static void sap_sort_chl_weight_ht40_24_g(tSapChSelSpectInfo *pSpectInfoParams,
2186 v_REGDOMAIN_t domain)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002187{
2188 uint8_t i, j;
2189 tSapSpectChInfo *pSpectInfo;
2190 uint32_t tmpWeight1, tmpWeight2;
bingse2782382017-03-23 10:34:52 +08002191 uint32_t ht40plus2gendch = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002192
2193 pSpectInfo = pSpectInfoParams->pSpectCh;
2194 /*
2195 * for each HT40 channel, calculate the combined weight of the
2196 * two 20MHz weight
2197 */
2198 for (i = 0; i < ARRAY_SIZE(acs_ht40_channels24_g); i++) {
2199 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
2200 if (pSpectInfo[j].chNum ==
2201 acs_ht40_channels24_g[i].chStartNum)
2202 break;
2203 }
2204 if (j == pSpectInfoParams->numSpectChans)
2205 continue;
2206
2207 if (!((pSpectInfo[j].chNum + 4) == pSpectInfo[j + 4].chNum)) {
2208 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2;
2209 continue;
2210 }
2211 /*
2212 * check if there is another channel combination possiblity
2213 * e.g., {1, 5} & {5, 9}
2214 */
2215 if ((pSpectInfo[j + 4].chNum + 4) == pSpectInfo[j + 8].chNum) {
2216 /* need to compare two channel pairs */
2217 tmpWeight1 = pSpectInfo[j].weight +
2218 pSpectInfo[j + 4].weight;
2219 tmpWeight2 = pSpectInfo[j + 4].weight +
2220 pSpectInfo[j + 8].weight;
2221 if (tmpWeight1 <= tmpWeight2) {
2222 if (pSpectInfo[j].weight <=
2223 pSpectInfo[j + 4].weight) {
2224 pSpectInfo[j].weight =
2225 tmpWeight1;
2226 pSpectInfo[j + 4].weight =
2227 SAP_ACS_WEIGHT_MAX * 2;
2228 pSpectInfo[j + 8].weight =
2229 SAP_ACS_WEIGHT_MAX * 2;
2230 } else {
2231 pSpectInfo[j + 4].weight =
2232 tmpWeight1;
2233 /* for secondary channel selection */
2234 pSpectInfo[j].weight =
2235 SAP_ACS_WEIGHT_MAX * 2
2236 - 1;
2237 pSpectInfo[j + 8].weight =
2238 SAP_ACS_WEIGHT_MAX * 2;
2239 }
2240 } else {
2241 if (pSpectInfo[j + 4].weight <=
2242 pSpectInfo[j + 8].weight) {
2243 pSpectInfo[j + 4].weight =
2244 tmpWeight2;
2245 pSpectInfo[j].weight =
2246 SAP_ACS_WEIGHT_MAX * 2;
2247 /* for secondary channel selection */
2248 pSpectInfo[j + 8].weight =
2249 SAP_ACS_WEIGHT_MAX * 2
2250 - 1;
2251 } else {
2252 pSpectInfo[j + 8].weight =
2253 tmpWeight2;
2254 pSpectInfo[j].weight =
2255 SAP_ACS_WEIGHT_MAX * 2;
2256 pSpectInfo[j + 4].weight =
2257 SAP_ACS_WEIGHT_MAX * 2;
2258 }
2259 }
2260 } else {
bingsaa6f96a2017-09-11 09:49:43 +08002261 tmpWeight1 = pSpectInfo[j].weight_copy +
2262 pSpectInfo[j + 4].weight_copy;
2263 if (pSpectInfo[j].weight_copy <=
2264 pSpectInfo[j + 4].weight_copy) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002265 pSpectInfo[j].weight = tmpWeight1;
2266 pSpectInfo[j + 4].weight =
2267 SAP_ACS_WEIGHT_MAX * 2;
2268 } else {
2269 pSpectInfo[j + 4].weight = tmpWeight1;
2270 pSpectInfo[j].weight =
2271 SAP_ACS_WEIGHT_MAX * 2;
2272 }
2273 }
2274 }
bingse2782382017-03-23 10:34:52 +08002275 /*
2276 * Every channel should be checked. Add the check for the omissive
2277 * channel. Mark the channel whose combination can't satisfy 40MHZ
2278 * as max value, so that it will be sorted to the bottom.
2279 */
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002280 if (REGDOMAIN_FCC == domain)
bingse2782382017-03-23 10:34:52 +08002281 ht40plus2gendch = HT40PLUS_2G_FCC_CH_END;
2282 else
2283 ht40plus2gendch = HT40PLUS_2G_EURJAP_CH_END;
2284 for (i = HT40MINUS_2G_CH_START; i <= ht40plus2gendch; i++) {
2285 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
2286 if (pSpectInfo[j].chNum == i &&
2287 ((pSpectInfo[j].chNum + 4) !=
2288 pSpectInfo[j+4].chNum) &&
2289 ((pSpectInfo[j].chNum - 4) !=
2290 pSpectInfo[j-4].chNum))
2291 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2;
2292 }
2293 }
2294 for (i = ht40plus2gendch + 1; i <= HT40MINUS_2G_CH_END; i++) {
2295 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
2296 if (pSpectInfo[j].chNum == i &&
2297 (pSpectInfo[j].chNum - 4) !=
2298 pSpectInfo[j-4].chNum)
2299 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2;
2300 }
2301 }
Himanshu Agarwal91c5c0f2018-02-13 14:40:56 +05302302
2303 pSpectInfo = pSpectInfoParams->pSpectCh;
2304 for (j = 0; j < (pSpectInfoParams->numSpectChans); j++) {
2305 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2306 "In %s, Channel=%d Weight= %d rssi=%d bssCount=%d",
2307 __func__, pSpectInfo->chNum, pSpectInfo->weight,
2308 pSpectInfo->rssiAgr, pSpectInfo->bssCount);
2309 pSpectInfo++;
2310 }
2311
Manishekar Chandrasekaran44e334f2016-05-30 16:42:50 +05302312 sap_sort_chl_weight(pSpectInfoParams);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002313}
2314
2315/*==========================================================================
2316 FUNCTION sap_sort_chl_weight_ht40_5_g
2317
2318 DESCRIPTION
Jeff Johnsonc7e4d162018-05-12 16:20:34 -07002319 Function to sort the channels with the least weight first for HT40 channels
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002320
2321 DEPENDENCIES
2322 NA.
2323
2324 PARAMETERS
2325
2326 IN
2327 pSpectInfoParams : Pointer to the tSapChSelSpectInfo structure
2328
2329 RETURN VALUE
2330 void : NULL
2331
2332 SIDE EFFECTS
2333 ============================================================================*/
Jeff Johnson464f7ea2016-10-07 10:21:26 -07002334static void sap_sort_chl_weight_ht40_5_g(tSapChSelSpectInfo *pSpectInfoParams)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002335{
2336 uint8_t i, j;
2337 tSapSpectChInfo *pSpectInfo;
2338
2339 pSpectInfo = pSpectInfoParams->pSpectCh;
2340 /*for each HT40 channel, calculate the combined weight of the
2341 two 20MHz weight */
2342 for (i = 0; i < ARRAY_SIZE(acs_ht40_channels5_g); i++) {
2343 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
2344 if (pSpectInfo[j].chNum ==
2345 acs_ht40_channels5_g[i].chStartNum)
2346 break;
2347 }
2348 if (j == pSpectInfoParams->numSpectChans)
2349 continue;
2350
2351 /* found the channel, add the two adjacent channels' weight */
2352 if ((pSpectInfo[j].chNum + 4) == pSpectInfo[j + 1].chNum) {
2353 acs_ht40_channels5_g[i].weight = pSpectInfo[j].weight +
2354 pSpectInfo[j + 1].weight;
2355 /* select better of the adjact channel as the primary channel */
2356 if (pSpectInfo[j].weight <= pSpectInfo[j + 1].weight) {
2357 pSpectInfo[j].weight =
2358 acs_ht40_channels5_g[i].weight;
2359 /* mark the adjacent channel's weight as max value so
2360 that it will be sorted to the bottom */
2361 pSpectInfo[j + 1].weight =
2362 SAP_ACS_WEIGHT_MAX * 2;
2363 } else {
2364 pSpectInfo[j + 1].weight =
2365 acs_ht40_channels5_g[i].weight;
2366 /* mark the adjacent channel's weight as max value so
2367 that it will be sorted to the bottom */
2368 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2;
2369 }
2370
2371 } else
2372 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2;
2373 }
2374
bingse2782382017-03-23 10:34:52 +08002375 /*
2376 *Every channel should be checked. Add the check for the omissive
2377 * channel. Mark the channel whose combination can't satisfy 40MHZ
2378 * as max value, so that it will be sorted to the bottom
2379 */
2380 for (j = 1; j < pSpectInfoParams->numSpectChans; j++) {
2381 for (i = 0; i < ARRAY_SIZE(acs_ht40_channels5_g); i++) {
2382 if (pSpectInfo[j].chNum ==
2383 (acs_ht40_channels5_g[i].chStartNum +
2384 4) &&
2385 pSpectInfo[j - 1].chNum !=
2386 acs_ht40_channels5_g[i].chStartNum) {
2387 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2;
2388 break;
2389 }
2390 }
2391 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002392 /* avoid channel 165 by setting its weight to max */
2393 pSpectInfo = pSpectInfoParams->pSpectCh;
2394 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
2395 if (CHANNEL_165 == pSpectInfo[j].chNum) {
2396 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2;
2397 break;
2398 }
2399 }
2400
2401 pSpectInfo = pSpectInfoParams->pSpectCh;
2402 for (j = 0; j < (pSpectInfoParams->numSpectChans); j++) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302403 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002404 "In %s, Channel=%d Weight= %d rssi=%d bssCount=%d",
2405 __func__, pSpectInfo->chNum, pSpectInfo->weight,
2406 pSpectInfo->rssiAgr, pSpectInfo->bssCount);
2407 pSpectInfo++;
2408 }
2409
2410 sap_sort_chl_weight(pSpectInfoParams);
2411}
2412
2413/*==========================================================================
2414 FUNCTION sap_sort_chl_weight_all
2415
2416 DESCRIPTION
Jeff Johnsonc7e4d162018-05-12 16:20:34 -07002417 Function to sort the channels with the least weight first
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002418
2419 DEPENDENCIES
2420 NA.
2421
2422 PARAMETERS
2423
2424 IN
Jeff Johnsone13d8062017-09-28 06:54:55 -07002425 sap_ctx : Pointer to the struct sap_context *structure
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002426 pSpectInfoParams : Pointer to the tSapChSelSpectInfo structure
2427
2428 RETURN VALUE
2429 void : NULL
2430
2431 SIDE EFFECTS
2432 ============================================================================*/
Jeff Johnsone13d8062017-09-28 06:54:55 -07002433static void sap_sort_chl_weight_all(struct sap_context *sap_ctx,
Jeff Johnson464f7ea2016-10-07 10:21:26 -07002434 tSapChSelSpectInfo *pSpectInfoParams,
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002435 uint32_t operatingBand,
2436 v_REGDOMAIN_t domain)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002437{
2438 tSapSpectChInfo *pSpectCh = NULL;
2439 uint32_t j = 0;
2440#ifndef SOFTAP_CHANNEL_RANGE
2441 uint32_t i = 0;
2442#endif
2443
2444 pSpectCh = pSpectInfoParams->pSpectCh;
2445#ifdef SOFTAP_CHANNEL_RANGE
2446
Jeff Johnsone13d8062017-09-28 06:54:55 -07002447 switch (sap_ctx->acs_cfg->ch_width) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002448 case CH_WIDTH_40MHZ:
Himanshu Agarwal91c5c0f2018-02-13 14:40:56 +05302449 /*
2450 * Assign max weight to all 5Ghz channels when operating band
2451 * is 11g and to all 2.4Ghz channels when operating band is 11a
2452 * or 11abg to avoid selection in ACS algorithm for starting SAP
2453 */
2454 if (eCSR_DOT11_MODE_11g == operatingBand) {
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002455 sap_sort_chl_weight_ht40_24_g(pSpectInfoParams, domain);
Himanshu Agarwal91c5c0f2018-02-13 14:40:56 +05302456 sap_allocate_max_weight_ht40_5_g(pSpectInfoParams);
2457 } else {
2458 sap_allocate_max_weight_ht40_24_g(pSpectInfoParams);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002459 sap_sort_chl_weight_ht40_5_g(pSpectInfoParams);
2460 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002461 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002462 case CH_WIDTH_80MHZ:
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07002463 case CH_WIDTH_80P80MHZ:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002464 sap_sort_chl_weight_ht80(pSpectInfoParams);
2465 break;
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07002466 case CH_WIDTH_160MHZ:
2467 sap_sort_chl_weight_vht160(pSpectInfoParams);
2468 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002469 case CH_WIDTH_20MHZ:
2470 default:
2471 /* Sorting the channels as per weights as 20MHz channels */
2472 sap_sort_chl_weight(pSpectInfoParams);
2473 }
2474
2475#else
2476 /* Sorting the channels as per weights */
2477 for (i = 0; i < SPECT_24GHZ_CH_COUNT; i++) {
2478 minWeightIndex = i;
2479 for (j = i + 1; j < SPECT_24GHZ_CH_COUNT; j++) {
2480 if (pSpectCh[j].weight <
2481 pSpectCh[minWeightIndex].weight) {
2482 minWeightIndex = j;
2483 }
2484 }
2485 if (minWeightIndex != i) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302486 qdf_mem_copy(&temp, &pSpectCh[minWeightIndex],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002487 sizeof(*pSpectCh));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302488 qdf_mem_copy(&pSpectCh[minWeightIndex], &pSpectCh[i],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002489 sizeof(*pSpectCh));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302490 qdf_mem_copy(&pSpectCh[i], &temp, sizeof(*pSpectCh));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002491 }
2492 }
2493#endif
2494
2495 /* For testing */
Ravi Joshi9788fcd2018-02-13 15:12:22 -08002496 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002497 "In %s, Sorted Spectrum Channels Weight", __func__);
2498 pSpectCh = pSpectInfoParams->pSpectCh;
2499 for (j = 0; j < (pSpectInfoParams->numSpectChans); j++) {
Ravi Joshi9788fcd2018-02-13 15:12:22 -08002500 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002501 "In %s, Channel=%d Weight= %d rssi=%d bssCount=%d",
2502 __func__, pSpectCh->chNum, pSpectCh->weight,
2503 pSpectCh->rssiAgr, pSpectCh->bssCount);
2504 pSpectCh++;
2505 }
2506
2507}
2508
Naveen Rawatbec64d92017-09-13 14:35:21 -07002509/**
2510 * sap_is_ch_non_overlap() - returns true if non-overlapping channel
2511 * @sap_ctx: Sap context
2512 * @ch: channel number
2513 *
2514 * Returns: true if non-overlapping (1, 6, 11) channel, false otherwise
2515 */
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -07002516static bool sap_is_ch_non_overlap(struct sap_context *sap_ctx, uint16_t ch)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002517{
Naveen Rawatbec64d92017-09-13 14:35:21 -07002518 if (sap_ctx->enableOverLapCh)
Srinivas Girigowda74a66d62017-06-21 23:28:25 -07002519 return true;
Naveen Rawatbec64d92017-09-13 14:35:21 -07002520
2521 if ((ch == CHANNEL_1) || (ch == CHANNEL_6) || (ch == CHANNEL_11))
Srinivas Girigowda74a66d62017-06-21 23:28:25 -07002522 return true;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002523
Srinivas Girigowda74a66d62017-06-21 23:28:25 -07002524 return false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002525}
2526
Dustin Brown0ce56d32016-10-17 16:18:03 -07002527#ifdef FEATURE_WLAN_CH_AVOID
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002528/**
2529 * sap_select_channel_no_scan_result() - select SAP channel when no scan results
2530 * are available.
2531 * @sap_ctx: Sap context
2532 *
2533 * Returns: channel number if success, 0 otherwise
2534 */
Jeff Johnson7730fbb2018-11-08 13:48:27 -08002535static uint8_t sap_select_channel_no_scan_result(mac_handle_t mac_handle,
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -07002536 struct sap_context *sap_ctx)
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002537{
Mohit Khanna841044f2016-03-25 16:16:24 -07002538 enum channel_state ch_type;
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002539 uint8_t i, first_safe_ch_in_range = SAP_CHANNEL_NOT_SELECTED;
Dustin Brown0ce56d32016-10-17 16:18:03 -07002540 uint32_t start_ch_num = sap_ctx->acs_cfg->start_ch;
2541 uint32_t end_ch_num = sap_ctx->acs_cfg->end_ch;
Jeff Johnsonc59ef8b2018-12-02 12:01:21 -08002542 struct mac_context *mac_ctx = NULL;
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002543
Jeff Johnsona0619e42018-11-28 17:43:00 -08002544 mac_ctx = MAC_CONTEXT(mac_handle);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002545
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002546 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2547 FL("start - end: %d - %d"), start_ch_num, end_ch_num);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002548
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002549 /* get a channel in PCL and within the range */
2550 for (i = 0; i < sap_ctx->acs_cfg->pcl_ch_count; i++) {
2551 if ((sap_ctx->acs_cfg->pcl_channels[i] < start_ch_num) ||
2552 (sap_ctx->acs_cfg->pcl_channels[i] > end_ch_num))
2553 continue;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002554
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002555 first_safe_ch_in_range = sap_ctx->acs_cfg->pcl_channels[i];
2556 break;
2557 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002558
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002559 if (SAP_CHANNEL_NOT_SELECTED != first_safe_ch_in_range)
2560 return first_safe_ch_in_range;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002561
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002562 for (i = 0; i < NUM_CHANNELS; i++) {
2563 if ((safe_channels[i].channelNumber < start_ch_num) ||
2564 (safe_channels[i].channelNumber > end_ch_num))
2565 continue;
2566
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002567 ch_type = wlan_reg_get_channel_state(mac_ctx->pdev,
2568 safe_channels[i].channelNumber);
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002569
2570 if ((ch_type == CHANNEL_STATE_DISABLE) ||
2571 (ch_type == CHANNEL_STATE_INVALID))
2572 continue;
Arif Hussain88d1fdd2018-09-26 16:12:24 -07002573 if ((!mac_ctx->mlme_cfg->dfs_cfg.dfs_master_capable) &&
2574 (CHANNEL_STATE_DFS == ch_type)) {
Kondabattini, Ganesh13bb4b12016-09-04 16:16:53 +05302575 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2576 "%s: DFS master mode disabled. Skip DFS channel %d",
2577 __func__, safe_channels[i].channelNumber);
2578 continue;
2579 }
Agrawal Ashish65634612016-08-18 13:24:32 +05302580 if ((sap_ctx->dfs_mode == ACS_DFS_MODE_DISABLE) &&
2581 (CHANNEL_STATE_DFS == ch_type))
2582 continue;
Kondabattini, Ganesh13bb4b12016-09-04 16:16:53 +05302583
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002584 if (safe_channels[i].isSafe == true) {
2585 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2586 FL("channel %d in the configuration is safe"),
2587 safe_channels[i].channelNumber);
2588 first_safe_ch_in_range = safe_channels[i].channelNumber;
2589 break;
2590 }
2591
2592 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2593 FL("channel %d in the configuration is unsafe"),
2594 safe_channels[i].channelNumber);
2595 }
2596
2597 /* if no channel selected return SAP_CHANNEL_NOT_SELECTED */
2598 return first_safe_ch_in_range;
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002599}
Dustin Brown0ce56d32016-10-17 16:18:03 -07002600#else
Jeff Johnson7730fbb2018-11-08 13:48:27 -08002601static uint8_t sap_select_channel_no_scan_result(mac_handle_t mac_handle,
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -07002602 struct sap_context *sap_ctx)
Dustin Brown0ce56d32016-10-17 16:18:03 -07002603{
2604 uint32_t start_ch_num = sap_ctx->acs_cfg->start_ch;
2605
2606 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2607 FL("start - end: %d - %d"),
2608 start_ch_num,
2609 sap_ctx->acs_cfg->end_ch);
2610
2611 sap_ctx->acs_cfg->pri_ch = start_ch_num;
2612 sap_ctx->acs_cfg->ht_sec_ch = 0;
2613
2614 /* pick the first channel in configured range */
2615 return start_ch_num;
2616}
2617#endif /* FEATURE_WLAN_CH_AVOID */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002618
2619/**
2620 * sap_select_channel() - select SAP channel
Jeff Johnson7730fbb2018-11-08 13:48:27 -08002621 * @mac_handle: Opaque handle to the global MAC context
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002622 * @sap_ctx: Sap context
2623 * @scan_result: Pointer to tScanResultHandle
2624 *
2625 * Runs a algorithm to select the best channel to operate in based on BSS
2626 * rssi and bss count on each channel
2627 *
2628 * Returns: channel number if success, 0 otherwise
2629 */
Jeff Johnson7730fbb2018-11-08 13:48:27 -08002630uint8_t sap_select_channel(mac_handle_t mac_handle,
2631 struct sap_context *sap_ctx,
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002632 tScanResultHandle scan_result)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002633{
2634 /* DFS param object holding all the data req by the algo */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002635 tSapChSelSpectInfo spect_info_obj = { NULL, 0 };
2636 tSapChSelSpectInfo *spect_info = &spect_info_obj;
2637 uint8_t best_ch_num = SAP_CHANNEL_NOT_SELECTED;
bingse2782382017-03-23 10:34:52 +08002638 uint32_t ht40plus2gendch = 0;
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002639 v_REGDOMAIN_t domain;
Arif Hussain21ad4342017-12-21 12:00:54 -08002640 uint8_t country[CDS_COUNTRY_CODE_LEN + 1];
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002641#ifdef SOFTAP_CHANNEL_RANGE
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002642 uint8_t count;
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002643 uint32_t start_ch_num, end_ch_num, tmp_ch_num, operating_band = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002644#endif
Jeff Johnsonc59ef8b2018-12-02 12:01:21 -08002645 struct mac_context *mac_ctx;
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002646
Jeff Johnsona0619e42018-11-28 17:43:00 -08002647 mac_ctx = MAC_CONTEXT(mac_handle);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302648 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002649 "In %s, Running SAP Ch Select", __func__);
2650
2651#ifdef FEATURE_WLAN_CH_AVOID
Jeff Johnson7730fbb2018-11-08 13:48:27 -08002652 sap_update_unsafe_channel_list(mac_handle, sap_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002653#endif
2654
gaoleze5108942017-03-31 16:56:42 +08002655 /*
2656 * If ACS weight is not enabled on noise_floor/channel_free/tx_power,
2657 * then skip acs process if no bss found.
2658 */
2659 if (NULL == scan_result &&
2660 !(sap_ctx->auto_channel_select_weight & 0xffff00)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302661 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002662 FL("No external AP present"));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002663
2664#ifndef SOFTAP_CHANNEL_RANGE
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002665 return SAP_CHANNEL_NOT_SELECTED;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002666#else
Jeff Johnson7730fbb2018-11-08 13:48:27 -08002667 return sap_select_channel_no_scan_result(mac_handle, sap_ctx);
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002668#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002669 }
2670
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002671 /* Initialize the structure pointed by spect_info */
Jeff Johnson7730fbb2018-11-08 13:48:27 -08002672 if (sap_chan_sel_init(mac_handle, spect_info, sap_ctx) != true) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302673 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002674 FL("Ch Select initialization failed"));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002675 return SAP_CHANNEL_NOT_SELECTED;
2676 }
2677 /* Compute the weight of the entire spectrum in the operating band */
Jeff Johnson7730fbb2018-11-08 13:48:27 -08002678 sap_compute_spect_weight(spect_info, mac_handle, scan_result, sap_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002679
2680#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
2681 /* process avoid channel IE to collect all channels to avoid */
Jeff Johnson7730fbb2018-11-08 13:48:27 -08002682 sap_process_avoid_ie(mac_handle, sap_ctx, scan_result, spect_info);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002683#endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
2684
Paul Zhang0f85b412018-01-18 19:14:51 +08002685 wlan_reg_read_current_country(mac_ctx->psoc, country);
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002686 wlan_reg_get_domain_from_country_code(&domain, country, SOURCE_DRIVER);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002687#ifdef SOFTAP_CHANNEL_RANGE
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002688 start_ch_num = sap_ctx->acs_cfg->start_ch;
2689 end_ch_num = sap_ctx->acs_cfg->end_ch;
2690 SET_ACS_BAND(operating_band, sap_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002691
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002692 sap_ctx->acsBestChannelInfo.channelNum = 0;
2693 sap_ctx->acsBestChannelInfo.weight = SAP_ACS_WEIGHT_MAX;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002694
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002695 /* Sort the ch lst as per the computed weights, lesser weight first. */
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002696 sap_sort_chl_weight_all(sap_ctx, spect_info, operating_band, domain);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002697
2698 /*Loop till get the best channel in the given range */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002699 for (count = 0; count < spect_info->numSpectChans; count++) {
2700 if ((start_ch_num > spect_info->pSpectCh[count].chNum) ||
2701 (end_ch_num < spect_info->pSpectCh[count].chNum))
2702 continue;
2703
2704 if (best_ch_num == SAP_CHANNEL_NOT_SELECTED) {
2705 best_ch_num = spect_info->pSpectCh[count].chNum;
2706 /* check if best_ch_num is in preferred channel list */
2707 best_ch_num =
2708 sap_select_preferred_channel_from_channel_list(
2709 best_ch_num, sap_ctx, spect_info);
2710 /* if not in preferred ch lst, go to nxt best ch */
2711 if (best_ch_num == SAP_CHANNEL_NOT_SELECTED)
2712 continue;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002713
2714#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002715 /*
2716 * Weight of the channels(device's AP is operating)
Jeff Johnson2cc31fd2018-05-05 23:54:23 -07002717 * increased to MAX+1 so that they will be chosen only
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002718 * when there is no other best channel to choose
2719 */
2720 if (sap_check_in_avoid_ch_list(sap_ctx, best_ch_num)) {
2721 best_ch_num = SAP_CHANNEL_NOT_SELECTED;
2722 continue;
2723 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002724#endif
2725
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002726 sap_ctx->acsBestChannelInfo.channelNum = best_ch_num;
2727 sap_ctx->acsBestChannelInfo.weight =
2728 spect_info->pSpectCh[count].weight_copy;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002729 }
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002730
2731 if (best_ch_num == SAP_CHANNEL_NOT_SELECTED)
2732 continue;
2733
Tushnim Bhattacharyya03103fd2017-06-23 10:48:52 -07002734 if (operating_band != eCSR_DOT11_MODE_11g) {
2735 QDF_TRACE(QDF_MODULE_ID_SAP,
2736 QDF_TRACE_LEVEL_INFO_HIGH,
2737 "operating_band %d", operating_band);
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002738 continue;
Tushnim Bhattacharyya03103fd2017-06-23 10:48:52 -07002739 }
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002740
2741 /* Give preference to Non-overlap channels */
Naveen Rawatbec64d92017-09-13 14:35:21 -07002742 if (false == sap_is_ch_non_overlap(sap_ctx,
Tushnim Bhattacharyya03103fd2017-06-23 10:48:52 -07002743 spect_info->pSpectCh[count].chNum)) {
2744 QDF_TRACE(QDF_MODULE_ID_SAP,
2745 QDF_TRACE_LEVEL_INFO_HIGH,
Naveen Rawatbec64d92017-09-13 14:35:21 -07002746 FL("ch: %d skipped as its overlapping ch"),
2747 spect_info->pSpectCh[count].chNum);
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002748 continue;
Tushnim Bhattacharyya03103fd2017-06-23 10:48:52 -07002749 }
2750
2751 if (wlan_reg_is_dfs_ch(mac_ctx->pdev,
2752 spect_info->pSpectCh[count].chNum) &&
2753 policy_mgr_disallow_mcc(mac_ctx->psoc,
2754 spect_info->pSpectCh[count].chNum)) {
2755 QDF_TRACE(QDF_MODULE_ID_SAP,
2756 QDF_TRACE_LEVEL_INFO_HIGH,
2757 "No DFS MCC");
2758 continue;
2759 }
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002760
bings14d1d3b2017-08-03 11:14:29 +08002761 if (spect_info->pSpectCh[count].weight_copy >
2762 sap_ctx->acsBestChannelInfo.weight)
2763 continue;
2764
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002765 tmp_ch_num = spect_info->pSpectCh[count].chNum;
gaoleze5108942017-03-31 16:56:42 +08002766 tmp_ch_num = sap_channel_in_acs_channel_list(
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002767 tmp_ch_num, sap_ctx, spect_info);
2768 if (tmp_ch_num == SAP_CHANNEL_NOT_SELECTED)
2769 continue;
2770
2771 best_ch_num = tmp_ch_num;
2772 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002773 }
2774#else
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002775 /* Sort the ch lst as per the computed weights, lesser weight first. */
Jeff Johnson7730fbb2018-11-08 13:48:27 -08002776 sap_sort_chl_weight_all(sap_ctx, mac_handle, spect_info);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002777 /* Get the first channel in sorted array as best 20M Channel */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002778 best_ch_num = (uint8_t) spect_info->pSpectCh[0].chNum;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002779 /* Select Best Channel from Channel List if Configured */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002780 best_ch_num = sap_select_preferred_channel_from_channel_list(
2781 best_ch_num, sap_ctx, spect_info);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002782#endif
2783
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002784 /*
2785 * in case the best channel seleted is not in PCL and there is another
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002786 * channel which has same weightage and is in PCL, choose the one in
2787 * PCL
2788 */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002789 for (count = 0; count < spect_info->numSpectChans; count++) {
2790 if (!ch_in_pcl(sap_ctx, spect_info->pSpectCh[count].chNum) ||
2791 (spect_info->pSpectCh[count].weight !=
2792 sap_ctx->acsBestChannelInfo.weight))
2793 continue;
2794
2795 if (sap_select_preferred_channel_from_channel_list(
2796 spect_info->pSpectCh[count].chNum, sap_ctx, spect_info)
2797 == SAP_CHANNEL_NOT_SELECTED)
2798 continue;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002799
2800#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002801 if (sap_check_in_avoid_ch_list(sap_ctx, best_ch_num))
2802 continue;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002803#endif
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002804 best_ch_num = spect_info->pSpectCh[count].chNum;
2805 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2806 FL("change best channel to %d in PCL"), best_ch_num);
2807 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002808 }
2809
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002810 sap_ctx->acs_cfg->pri_ch = best_ch_num;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002811 /* determine secondary channel for 2.4G channel 5, 6, 7 in HT40 */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002812 if ((operating_band != eCSR_DOT11_MODE_11g) ||
2813 (sap_ctx->acs_cfg->ch_width != CH_WIDTH_40MHZ))
2814 goto sap_ch_sel_end;
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002815 if (REGDOMAIN_FCC == domain)
bingse2782382017-03-23 10:34:52 +08002816 ht40plus2gendch = HT40PLUS_2G_FCC_CH_END;
2817 else
2818 ht40plus2gendch = HT40PLUS_2G_EURJAP_CH_END;
2819 if ((best_ch_num >= HT40MINUS_2G_CH_START) &&
2820 (best_ch_num <= ht40plus2gendch)) {
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002821 int weight_below, weight_above, i;
2822 tSapSpectChInfo *pspect_info;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002823
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002824 weight_below = weight_above = SAP_ACS_WEIGHT_MAX;
2825 pspect_info = spect_info->pSpectCh;
2826 for (i = 0; i < spect_info->numSpectChans; i++) {
2827 if (pspect_info[i].chNum == (best_ch_num - 4))
2828 weight_below = pspect_info[i].weight;
2829 if (pspect_info[i].chNum == (best_ch_num + 4))
2830 weight_above = pspect_info[i].weight;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002831 }
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002832
2833 if (weight_below < weight_above)
2834 sap_ctx->acs_cfg->ht_sec_ch =
2835 sap_ctx->acs_cfg->pri_ch - 4;
2836 else
2837 sap_ctx->acs_cfg->ht_sec_ch =
2838 sap_ctx->acs_cfg->pri_ch + 4;
2839 } else if (best_ch_num >= 1 && best_ch_num <= 4) {
2840 sap_ctx->acs_cfg->ht_sec_ch = sap_ctx->acs_cfg->pri_ch + 4;
bingse2782382017-03-23 10:34:52 +08002841 } else if (best_ch_num >= ht40plus2gendch && best_ch_num <=
2842 HT40MINUS_2G_CH_END) {
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002843 sap_ctx->acs_cfg->ht_sec_ch = sap_ctx->acs_cfg->pri_ch - 4;
2844 } else if (best_ch_num == 14) {
2845 sap_ctx->acs_cfg->ht_sec_ch = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002846 }
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002847 sap_ctx->secondary_ch = sap_ctx->acs_cfg->ht_sec_ch;
2848
2849sap_ch_sel_end:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002850 /* Free all the allocated memory */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002851 sap_chan_sel_exit(spect_info);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002852
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302853 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002854 FL("Running SAP Ch select Completed, Ch=%d"), best_ch_num);
wadesongcb0ded22018-02-02 17:57:20 +08002855 host_log_acs_best_chan(best_ch_num, sap_ctx->acsBestChannelInfo.weight);
2856
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002857 if (best_ch_num > 0 && best_ch_num <= 252)
2858 return best_ch_num;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002859 else
2860 return SAP_CHANNEL_NOT_SELECTED;
2861}