blob: cb05559ad545848041ceac71961afce0e69e9570 [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 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21
22/*
23 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
26 */
27
28/*===========================================================================
29
Anurag Chouhan6d760662016-02-20 16:05:43 +053030 s a p C h S e l e c t . C
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080031 OVERVIEW:
32
33 This software unit holds the implementation of the WLAN SAP modules
34 functions for channel selection.
35
36 DEPENDENCIES:
37
38 Are listed for each API below.
39 ===========================================================================*/
40
41/*--------------------------------------------------------------------------
42 Include Files
43 ------------------------------------------------------------------------*/
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +053044#include "qdf_trace.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080045#include "csr_api.h"
46#include "sme_api.h"
47#include "sap_ch_select.h"
48#include "sap_internal.h"
49#ifdef ANI_OS_TYPE_QNX
50#include "stdio.h"
51#endif
52#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
53#include "lim_utils.h"
54#include "parser_api.h"
55#endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
Deepthi Gowri48b89332016-08-30 18:43:05 +053056#include "cds_utils.h"
Yuanyuan Liu0e0aa932016-05-12 10:17:58 -070057#include "pld_common.h"
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -070058#include "wlan_reg_services_api.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080059
60/*--------------------------------------------------------------------------
61 Function definitions
62 --------------------------------------------------------------------------*/
63
64/*--------------------------------------------------------------------------
65 Defines
66 --------------------------------------------------------------------------*/
67#define SAP_DEBUG
68
69#define IS_RSSI_VALID(extRssi, rssi) \
70 ( \
71 ((extRssi < rssi) ? true : false) \
72 )
73
Jeff Johnsone13d8062017-09-28 06:54:55 -070074#define SET_ACS_BAND(acs_band, sap_ctx) \
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080075{ \
Jeff Johnsone13d8062017-09-28 06:54:55 -070076 if (sap_ctx->acs_cfg->start_ch <= 14 && \
77 sap_ctx->acs_cfg->end_ch <= 14) \
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080078 acs_band = eCSR_DOT11_MODE_11g; \
Jeff Johnsone13d8062017-09-28 06:54:55 -070079 else if (sap_ctx->acs_cfg->start_ch >= 14)\
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080080 acs_band = eCSR_DOT11_MODE_11a; \
81 else \
82 acs_band = eCSR_DOT11_MODE_abg; \
83}
84
gaoleze5108942017-03-31 16:56:42 +080085#define ACS_WEIGHT_AMOUNT_LOCAL 240
86
87#define ACS_WEIGHT_AMOUNT_CONFIG(weights) \
88 (((weights) & 0xf) + \
89 (((weights) & 0xf0) >> 4) + \
90 (((weights) & 0xf00) >> 8) + \
91 (((weights) & 0xf000) >> 12) + \
92 (((weights) & 0xf0000) >> 16) + \
93 (((weights) & 0xf00000) >> 20))
94
95/*
96 * LSH/RSH 4 to enhance the accurate since
97 * need to do modulation to ACS_WEIGHT_AMOUNT_LOCAL.
98 */
99#define ACS_WEIGHT_COMPUTE(weights, weight, factor, base) \
100 (((((((((weight) << 4) * ACS_WEIGHT_AMOUNT_LOCAL * (factor)) + \
101 (ACS_WEIGHT_AMOUNT_CONFIG((weights)) >> 1)) / \
102 ACS_WEIGHT_AMOUNT_CONFIG((weights))) + \
103 ((base) >> 1)) / (base)) + 8) >> 4)
104
105#define ACS_WEIGHT_CFG_TO_LOCAL(weights, weight) \
106 (((((((weight) << 4) * ACS_WEIGHT_AMOUNT_LOCAL) + \
107 (ACS_WEIGHT_AMOUNT_CONFIG((weights)) >> 1)) / \
108 ACS_WEIGHT_AMOUNT_CONFIG((weights))) + 8) >> 4)
109
110#define ACS_WEIGHT_SOFTAP_RSSI_CFG(weights) \
111 ((weights) & 0xf)
112
113#define ACS_WEIGHT_SOFTAP_COUNT_CFG(weights) \
114 (((weights) & 0xf0) >> 4)
115
116#define ACS_WEIGHT_SOFTAP_NOISE_FLOOR_CFG(weights) \
117 (((weights) & 0xf00) >> 8)
118
119#define ACS_WEIGHT_SOFTAP_CHANNEL_FREE_CFG(weights) \
120 (((weights) & 0xf000) >> 12)
121
122#define ACS_WEIGHT_SOFTAP_TX_POWER_RANGE_CFG(weights) \
123 (((weights) & 0xf0000) >> 16)
124
125#define ACS_WEIGHT_SOFTAP_TX_POWER_THROUGHPUT_CFG(weights) \
126 (((weights) & 0xf00000) >> 20)
127
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800128#ifdef FEATURE_WLAN_CH_AVOID
Amar Singhalb8d4f152016-02-10 10:21:43 -0800129sapSafeChannelType safe_channels[NUM_CHANNELS] = {
130 {1, true},
131 {2, true},
132 {3, true},
133 {4, true},
134 {5, true},
135 {6, true},
136 {7, true},
137 {8, true},
138 {9, true},
139 {10, true},
140 {11, true},
141 {12, true},
142 {13, true},
143 {14, true},
144 {36, true},
145 {40, true},
146 {44, true},
147 {48, true},
148 {52, true},
149 {56, true},
150 {60, true},
151 {64, true},
152 {100, true},
153 {104, true},
154 {108, true},
155 {112, true},
156 {116, true},
157 {120, true},
158 {124, true},
159 {128, true},
160 {132, true},
161 {136, true},
162 {140, true},
163 {144, true},
164 {149, true},
165 {153, true},
166 {157, true},
167 {161, true},
168 {165, true},
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800169};
170#endif
171
172typedef struct {
173 uint16_t chStartNum;
174 uint32_t weight;
175} sapAcsChannelInfo;
176
177sapAcsChannelInfo acs_ht40_channels5_g[] = {
178 {36, SAP_ACS_WEIGHT_MAX},
179 {44, SAP_ACS_WEIGHT_MAX},
180 {52, SAP_ACS_WEIGHT_MAX},
181 {60, SAP_ACS_WEIGHT_MAX},
182 {100, SAP_ACS_WEIGHT_MAX},
183 {108, SAP_ACS_WEIGHT_MAX},
184 {116, SAP_ACS_WEIGHT_MAX},
185 {124, SAP_ACS_WEIGHT_MAX},
186 {132, SAP_ACS_WEIGHT_MAX},
187 {140, SAP_ACS_WEIGHT_MAX},
188 {149, SAP_ACS_WEIGHT_MAX},
189 {157, SAP_ACS_WEIGHT_MAX},
190};
191
192sapAcsChannelInfo acs_ht80_channels[] = {
193 {36, SAP_ACS_WEIGHT_MAX},
194 {52, SAP_ACS_WEIGHT_MAX},
195 {100, SAP_ACS_WEIGHT_MAX},
196 {116, SAP_ACS_WEIGHT_MAX},
197 {132, SAP_ACS_WEIGHT_MAX},
198 {149, SAP_ACS_WEIGHT_MAX},
199};
200
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -0700201sapAcsChannelInfo acs_vht160_channels[] = {
202 {36, SAP_ACS_WEIGHT_MAX},
203 {100, SAP_ACS_WEIGHT_MAX},
204};
205
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800206sapAcsChannelInfo acs_ht40_channels24_g[] = {
207 {1, SAP_ACS_WEIGHT_MAX},
208 {2, SAP_ACS_WEIGHT_MAX},
209 {3, SAP_ACS_WEIGHT_MAX},
210 {4, SAP_ACS_WEIGHT_MAX},
211 {9, SAP_ACS_WEIGHT_MAX},
212};
213
214#define CHANNEL_165 165
215
216/* rssi discount for channels in PCL */
217#define PCL_RSSI_DISCOUNT 10
218
219#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
220/**
221 * sap_check_n_add_channel() - checks and add given channel in sap context's
222 * avoid_channels_info struct
223 * @sap_ctx: sap context.
224 * @new_channel: channel to be added to sap_ctx's avoid ch info
225 *
226 * sap_ctx contains sap_avoid_ch_info strcut containing the list of channels on
227 * which MDM device's AP with MCC was detected. This function will add channels
228 * to that list after checking for duplicates.
229 *
230 * Return: true: if channel was added or already present
231 * else false: if channel list was already full.
232 */
Tang Yingying523322d2017-01-17 23:28:43 +0800233static bool
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -0700234sap_check_n_add_channel(struct sap_context *sap_ctx,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800235 uint8_t new_channel)
236{
237 uint8_t i = 0;
238 struct sap_avoid_channels_info *ie_info =
239 &sap_ctx->sap_detected_avoid_ch_ie;
240
241 for (i = 0; i < sizeof(ie_info->channels); i++) {
242 if (ie_info->channels[i] == new_channel)
243 break;
244
245 if (ie_info->channels[i] == 0) {
246 ie_info->channels[i] = new_channel;
247 break;
248 }
249 }
250 if (i == sizeof(ie_info->channels))
251 return false;
252 else
253 return true;
254}
255/**
256 * sap_check_n_add_overlapped_chnls() - checks & add overlapped channels
257 * to primary channel in 2.4Ghz band.
258 * @sap_ctx: sap context.
259 * @primary_chnl: primary channel to be avoided.
260 *
261 * sap_ctx contains sap_avoid_ch_info struct containing the list of channels on
262 * which MDM device's AP with MCC was detected. This function will add channels
263 * to that list after checking for duplicates.
264 *
265 * Return: true: if channel was added or already present
266 * else false: if channel list was already full.
267 */
268static bool
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -0700269sap_check_n_add_overlapped_chnls(struct sap_context *sap_ctx,
270 uint8_t primary_channel)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800271{
272 uint8_t i = 0, j = 0, upper_chnl = 0, lower_chnl = 0;
273 struct sap_avoid_channels_info *ie_info =
274 &sap_ctx->sap_detected_avoid_ch_ie;
275 /*
276 * if primary channel less than channel 1 or out of 2g band then
277 * no further process is required. return true in this case.
278 */
279 if (primary_channel < CHANNEL_1 || primary_channel > CHANNEL_14)
280 return true;
281
282 /* lower channel is one channel right before primary channel */
283 lower_chnl = primary_channel - 1;
284 /* upper channel is one channel right after primary channel */
285 upper_chnl = primary_channel + 1;
286
287 /* lower channel needs to be non-zero, zero is not valid channel */
288 if (lower_chnl > (CHANNEL_1 - 1)) {
289 for (i = 0; i < sizeof(ie_info->channels); i++) {
290 if (ie_info->channels[i] == lower_chnl)
291 break;
292 if (ie_info->channels[i] == 0) {
293 ie_info->channels[i] = lower_chnl;
294 break;
295 }
296 }
297 }
298 /* upper channel needs to be atleast last channel in 2.4Ghz band */
299 if (upper_chnl < (CHANNEL_14 + 1)) {
300 for (j = 0; j < sizeof(ie_info->channels); j++) {
301 if (ie_info->channels[j] == upper_chnl)
302 break;
303 if (ie_info->channels[j] == 0) {
304 ie_info->channels[j] = upper_chnl;
305 break;
306 }
307 }
308 }
309 if (i == sizeof(ie_info->channels) || j == sizeof(ie_info->channels))
310 return false;
311 else
312 return true;
313}
314
315/**
316 * sap_process_avoid_ie() - processes the detected Q2Q IE
317 * context's avoid_channels_info struct
318 * @hal: hal handle
319 * @sap_ctx: sap context.
320 * @scan_result: scan results for ACS scan.
321 * @spect_info: spectrum weights array to update
322 *
323 * Detection of Q2Q IE indicates presence of another MDM device with its AP
324 * operating in MCC mode. This function parses the scan results and processes
325 * the Q2Q IE if found. It then extracts the channels and populates them in
326 * sap_ctx struct. It also increases the weights of those channels so that
327 * ACS logic will avoid those channels in its selection algorithm.
328 *
329 * Return: void
330 */
Tang Yingying523322d2017-01-17 23:28:43 +0800331static void sap_process_avoid_ie(tHalHandle hal,
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -0700332 struct sap_context *sap_ctx,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800333 tScanResultHandle scan_result,
334 tSapChSelSpectInfo *spect_info)
335{
336 uint32_t total_ie_len = 0;
337 uint8_t *temp_ptr = NULL;
338 uint8_t i = 0;
339 struct sAvoidChannelIE *avoid_ch_ie;
340 tCsrScanResultInfo *node = NULL;
341 tpAniSirGlobal mac_ctx = NULL;
342 tSapSpectChInfo *spect_ch = NULL;
343
344 mac_ctx = PMAC_STRUCT(hal);
345 spect_ch = spect_info->pSpectCh;
346 node = sme_scan_result_get_first(hal, scan_result);
347
348 while (node) {
Abhishek Singh34a4d862016-10-26 16:01:51 +0530349 total_ie_len =
Jeff Johnson38e38a82017-10-06 10:32:31 -0700350 GET_IE_LEN_IN_BSS(node->BssDescriptor.length);
Naveen Rawat08db88f2017-09-08 15:07:48 -0700351 temp_ptr = wlan_get_vendor_ie_ptr_from_oui(
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800352 SIR_MAC_QCOM_VENDOR_OUI,
353 SIR_MAC_QCOM_VENDOR_SIZE,
354 ((uint8_t *)&node->BssDescriptor.ieFields),
355 total_ie_len);
356
357 if (temp_ptr) {
358 avoid_ch_ie = (struct sAvoidChannelIE *)temp_ptr;
Will Huang55ba1042017-03-22 10:43:30 +0800359 if (avoid_ch_ie->type !=
360 QCOM_VENDOR_IE_MCC_AVOID_CH) {
361 node = sme_scan_result_get_next(hal,
362 scan_result);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800363 continue;
Will Huang55ba1042017-03-22 10:43:30 +0800364 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800365
366 sap_ctx->sap_detected_avoid_ch_ie.present = 1;
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530367 QDF_TRACE(QDF_MODULE_ID_SAP,
368 QDF_TRACE_LEVEL_DEBUG,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800369 "Q2Q IE - avoid ch %d",
370 avoid_ch_ie->channel);
371 /* add this channel to to_avoid channel list */
372 sap_check_n_add_channel(sap_ctx,
373 avoid_ch_ie->channel);
374 sap_check_n_add_overlapped_chnls(sap_ctx,
375 avoid_ch_ie->channel);
376 /*
377 * Mark weight of these channel present in IE to MAX
378 * so that ACS logic will to avoid thse channels
379 */
380 for (i = 0; i < spect_info->numSpectChans; i++)
381 if (spect_ch[i].chNum == avoid_ch_ie->channel) {
382 /*
383 * weight is set more than max so that,
384 * in the case of other channels being
385 * assigned max weight due to noise,
386 * they may be preferred over channels
387 * with Q2Q IE.
388 */
389 spect_ch[i].weight = SAP_ACS_WEIGHT_MAX + 1;
390 spect_ch[i].weight_copy =
391 SAP_ACS_WEIGHT_MAX + 1;
392 break;
393 }
394 } /* if (temp_ptr) */
395 node = sme_scan_result_get_next(hal, scan_result);
396 }
397}
398#endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
399
400#ifdef FEATURE_WLAN_CH_AVOID
401/*==========================================================================
402 FUNCTION sap_update_unsafe_channel_list
403
404 DESCRIPTION
405 Function Undate unsafe channel list table
406
407 DEPENDENCIES
408 NA.
409
410 IN
411 SapContext pointer
412
413 RETURN VALUE
414 NULL
415 ============================================================================*/
Jeff Johnsone13d8062017-09-28 06:54:55 -0700416void sap_update_unsafe_channel_list(tHalHandle hal, struct sap_context *sap_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800417{
418 uint16_t i, j;
Amar Singhalb8d4f152016-02-10 10:21:43 -0800419 uint16_t unsafe_channel_list[NUM_CHANNELS];
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800420 uint16_t unsafe_channel_count = 0;
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -0700421 tpAniSirGlobal mac_ctx = NULL;
422
Yuanyuan Liu0e0aa932016-05-12 10:17:58 -0700423 qdf_device_t qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800424
Yuanyuan Liu97361182016-06-06 09:38:04 -0700425 if (!qdf_ctx) {
426 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_FATAL,
427 "qdf_ctx is NULL");
428 return;
429 }
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -0700430 mac_ctx = PMAC_STRUCT(hal);
431 if (!mac_ctx) {
432 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_FATAL,
433 "mac_ctx is NULL");
434 return;
435 }
Yuanyuan Liu97361182016-06-06 09:38:04 -0700436
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800437 /* Flush, default set all channel safe */
Amar Singhalb8d4f152016-02-10 10:21:43 -0800438 for (i = 0; i < NUM_CHANNELS; i++) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800439 safe_channels[i].isSafe = true;
440 }
441
442 /* Try to find unsafe channel */
Ryan Hsu4252a2f2016-01-05 11:18:24 -0800443#if defined(FEATURE_WLAN_STA_AP_MODE_DFS_DISABLE)
Amar Singhalb8d4f152016-02-10 10:21:43 -0800444 for (i = 0; i < NUM_CHANNELS; i++) {
Jeff Johnsone13d8062017-09-28 06:54:55 -0700445 if (sap_ctx->dfs_ch_disable == true) {
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -0700446 if (wlan_reg_is_dfs_ch(mac_ctx->pdev,
447 safe_channels[i].channelNumber)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800448 safe_channels[i].isSafe = false;
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530449 QDF_TRACE(QDF_MODULE_ID_SAP,
450 QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800451 "%s: DFS Ch %d is not safe in"
452 " Concurrent mode",
453 __func__,
454 safe_channels[i].channelNumber);
455 }
456 }
457 }
458#endif
Yuanyuan Liu0e0aa932016-05-12 10:17:58 -0700459 pld_get_wlan_unsafe_channel(qdf_ctx->dev,
460 unsafe_channel_list,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800461 &unsafe_channel_count,
462 sizeof(unsafe_channel_list));
463
464 for (i = 0; i < unsafe_channel_count; i++) {
Amar Singhalb8d4f152016-02-10 10:21:43 -0800465 for (j = 0; j < NUM_CHANNELS; j++) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800466 if (safe_channels[j].channelNumber ==
467 unsafe_channel_list[i]) {
468 /* Found unsafe channel, update it */
469 safe_channels[j].isSafe = false;
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530470 QDF_TRACE(QDF_MODULE_ID_SAP,
471 QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800472 FL("CH %d is not safe"),
473 unsafe_channel_list[i]);
474 break;
475 }
476 }
477 }
478
479 return;
480}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800481
482#endif /* FEATURE_WLAN_CH_AVOID */
483
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800484/**
gaoleze5108942017-03-31 16:56:42 +0800485 * sap_channel_in_acs_channel_list() - check if channel in acs channel list
486 * @channel_num: channel to check
487 * @sap_ctx: struct ptSapContext
488 * @spect_info_params: strcut tSapChSelSpectInfo
489 *
490 * This function checks if specified channel is in the configured ACS channel
491 * list.
492 *
493 * Return: channel number if in acs channel list or SAP_CHANNEL_NOT_SELECTED
494 */
495static
496uint8_t sap_channel_in_acs_channel_list(uint8_t channel_num,
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -0700497 struct sap_context *sap_ctx,
gaoleze5108942017-03-31 16:56:42 +0800498 tSapChSelSpectInfo *spect_info_params)
499{
500 uint8_t i = 0;
501
502 if ((NULL == sap_ctx->acs_cfg->ch_list) ||
503 (NULL == spect_info_params))
504 return channel_num;
505
506 if (channel_num > 0 && channel_num <= 252) {
507 for (i = 0; i < sap_ctx->acs_cfg->ch_list_count; i++) {
508 if ((sap_ctx->acs_cfg->ch_list[i]) == channel_num)
509 return channel_num;
510 }
511 return SAP_CHANNEL_NOT_SELECTED;
512 } else {
513 return SAP_CHANNEL_NOT_SELECTED;
514 }
515}
516
517/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800518 * sap_select_preferred_channel_from_channel_list() - to calc best cahnnel
519 * @best_chnl: best channel already calculated among all the chanels
520 * @sap_ctx: sap context
521 * @spectinfo_param: Pointer to tSapChSelSpectInfo structure
522 *
523 * This function calculates the best channel among the configured channel list.
524 * If channel list not configured then returns the best channel calculated
525 * among all the channel list.
526 *
527 * Return: uint8_t best channel
528 */
Jeff Johnson464f7ea2016-10-07 10:21:26 -0700529static
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800530uint8_t sap_select_preferred_channel_from_channel_list(uint8_t best_chnl,
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -0700531 struct sap_context *sap_ctx,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800532 tSapChSelSpectInfo *spectinfo_param)
533{
534 uint8_t i = 0;
Tushnim Bhattacharyya518e80f2017-08-30 17:35:33 -0700535 tpAniSirGlobal mac_ctx = sme_get_mac_context();
536
537 if (NULL == mac_ctx) {
538 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
539 "pmac Global Context is NULL");
540 return SAP_CHANNEL_NOT_SELECTED;
541 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800542
543 /*
544 * If Channel List is not Configured don't do anything
545 * Else return the Best Channel from the Channel List
546 */
547 if ((NULL == sap_ctx->acs_cfg->ch_list) ||
548 (NULL == spectinfo_param) ||
549 (0 == sap_ctx->acs_cfg->ch_list_count))
550 return best_chnl;
551
552 if (best_chnl <= 0 || best_chnl > 252)
553 return SAP_CHANNEL_NOT_SELECTED;
554
555 /* Select the best channel from allowed list */
556 for (i = 0; i < sap_ctx->acs_cfg->ch_list_count; i++) {
Tushnim Bhattacharyya518e80f2017-08-30 17:35:33 -0700557 if ((sap_ctx->acs_cfg->ch_list[i] == best_chnl) &&
558 !(wlan_reg_is_dfs_ch(mac_ctx->pdev, best_chnl) &&
559 policy_mgr_disallow_mcc(mac_ctx->psoc, best_chnl))) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530560 QDF_TRACE(QDF_MODULE_ID_SAP,
561 QDF_TRACE_LEVEL_INFO_HIGH,
Naveen Rawatbec64d92017-09-13 14:35:21 -0700562 "Best channel so far is: %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800563 best_chnl);
564 return best_chnl;
565 }
566 }
567
568 return SAP_CHANNEL_NOT_SELECTED;
569}
570
571/*==========================================================================
572 FUNCTION sap_chan_sel_init
573
574 DESCRIPTION
575 Function sap_chan_sel_init allocates the memory, intializes the
Anurag Chouhan6d760662016-02-20 16:05:43 +0530576 structures used by the channel selection algorithm
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800577
578 DEPENDENCIES
579 NA.
580
581 PARAMETERS
582
583 IN
584 halHandle : Pointer to tHalHandle
585 *pSpectInfoParams : Pointer to tSapChSelSpectInfo structure
Jeff Johnsone13d8062017-09-28 06:54:55 -0700586 sap_ctx : Pointer to SAP Context
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800587
588 RETURN VALUE
589 bool: Success or FAIL
590
591 SIDE EFFECTS
592 ============================================================================*/
Jeff Johnson464f7ea2016-10-07 10:21:26 -0700593static bool sap_chan_sel_init(tHalHandle halHandle,
594 tSapChSelSpectInfo *pSpectInfoParams,
Jeff Johnsone13d8062017-09-28 06:54:55 -0700595 struct sap_context *sap_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800596{
597 tSapSpectChInfo *pSpectCh = NULL;
598 uint8_t *pChans = NULL;
599 uint16_t channelnum = 0;
600 tpAniSirGlobal pMac = PMAC_STRUCT(halHandle);
601 bool chSafe = true;
602#ifdef FEATURE_WLAN_CH_AVOID
603 uint16_t i;
604#endif
605 uint32_t dfs_master_cap_enabled;
606 bool include_dfs_ch = true;
Himanshu Agarwalfee2e362018-01-18 20:26:35 +0530607 uint8_t chan_num;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800608
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530609 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, "In %s",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800610 __func__);
611
612 pSpectInfoParams->numSpectChans =
613 pMac->scan.base_channels.numChannels;
614
615 /* Allocate memory for weight computation of 2.4GHz */
616 pSpectCh =
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530617 (tSapSpectChInfo *) qdf_mem_malloc((pSpectInfoParams->numSpectChans)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800618 * sizeof(*pSpectCh));
619
620 if (pSpectCh == NULL) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530621 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
Anurag Chouhanf04e84f2016-03-03 10:12:12 +0530622 "In %s, QDF_MALLOC_ERR", __func__);
Srinivas Girigowda74a66d62017-06-21 23:28:25 -0700623 return false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800624 }
625
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800626 /* Initialize the pointers in the DfsParams to the allocated memory */
627 pSpectInfoParams->pSpectCh = pSpectCh;
628
629 pChans = pMac->scan.base_channels.channelList;
630
Ryan Hsu4252a2f2016-01-05 11:18:24 -0800631#if defined(FEATURE_WLAN_STA_AP_MODE_DFS_DISABLE)
Jeff Johnsone13d8062017-09-28 06:54:55 -0700632 if (sap_ctx->dfs_ch_disable == true)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800633 include_dfs_ch = false;
634#endif
635 sme_cfg_get_int(halHandle, WNI_CFG_DFS_MASTER_ENABLED,
636 &dfs_master_cap_enabled);
Agrawal Ashish65634612016-08-18 13:24:32 +0530637 if (dfs_master_cap_enabled == 0 ||
Jeff Johnsone13d8062017-09-28 06:54:55 -0700638 ACS_DFS_MODE_DISABLE == sap_ctx->dfs_mode)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800639 include_dfs_ch = false;
640
641 /* Fill the channel number in the spectrum in the operating freq band */
642 for (channelnum = 0;
643 channelnum < pSpectInfoParams->numSpectChans;
Edhar, Mahesh Kumar4f660672015-10-30 11:53:26 +0530644 channelnum++, pChans++, pSpectCh++) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800645 chSafe = true;
646
647 /* check if the channel is in NOL blacklist */
Jeff Johnsone13d8062017-09-28 06:54:55 -0700648 if (sap_dfs_is_channel_in_nol_list(sap_ctx, *pChans,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800649 PHY_SINGLE_CHANNEL_CENTERED)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530650 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800651 "In %s, Ch %d is in NOL list", __func__,
652 *pChans);
653 chSafe = false;
654 continue;
655 }
656
657 if (include_dfs_ch == false) {
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -0700658 if (wlan_reg_is_dfs_ch(pMac->pdev, *pChans)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800659 chSafe = false;
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530660 QDF_TRACE(QDF_MODULE_ID_SAP,
661 QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800662 "In %s, DFS Ch %d not considered for ACS",
663 __func__, *pChans);
664 continue;
665 }
666 }
667
668#ifdef FEATURE_WLAN_CH_AVOID
Amar Singhalb8d4f152016-02-10 10:21:43 -0800669 for (i = 0; i < NUM_CHANNELS; i++) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800670 if ((safe_channels[i].channelNumber == *pChans) &&
671 (false == safe_channels[i].isSafe)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530672 QDF_TRACE(QDF_MODULE_ID_SAP,
673 QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800674 "In %s, Ch %d is not safe", __func__,
675 *pChans);
676 chSafe = false;
677 break;
678 }
679 }
680#endif /* FEATURE_WLAN_CH_AVOID */
681
682 /* OFDM rates are not supported on channel 14 */
683 if (*pChans == 14 &&
Jeff Johnsone13d8062017-09-28 06:54:55 -0700684 eCSR_DOT11_MODE_11b != sap_ctx->csr_roamProfile.phyMode) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800685 continue;
686 }
687
Deepthi Gowri48b89332016-08-30 18:43:05 +0530688 /* Skip DSRC channels */
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -0700689 if (WLAN_REG_IS_11P_CH(*pChans))
Deepthi Gowri48b89332016-08-30 18:43:05 +0530690 continue;
691
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800692 if (true == chSafe) {
693 pSpectCh->chNum = *pChans;
Srinivas Girigowda74a66d62017-06-21 23:28:25 -0700694 pSpectCh->valid = true;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800695 pSpectCh->rssiAgr = SOFTAP_MIN_RSSI; /* Initialise for all channels */
696 pSpectCh->channelWidth = SOFTAP_HT20_CHANNELWIDTH; /* Initialise 20MHz for all the Channels */
Himanshu Agarwalfee2e362018-01-18 20:26:35 +0530697 /* Initialise max ACS weight for all channels */
698 pSpectCh->weight = SAP_ACS_WEIGHT_MAX;
699 for (chan_num = 0; chan_num < sap_ctx->num_of_channel;
700 chan_num++) {
701 if (pSpectCh->chNum !=
702 sap_ctx->channelList[chan_num])
703 continue;
704
705 /*
706 * Initialize ACS weight to 0 for channels
707 * present in sap context scan channel list
708 */
709 pSpectCh->weight = 0;
710 break;
711 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800712 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800713 }
Srinivas Girigowda74a66d62017-06-21 23:28:25 -0700714 return true;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800715}
716
gaoleze5108942017-03-31 16:56:42 +0800717/**
718 * sapweight_rssi_count() - calculates the channel weight due to rssi
Anurag Chouhan6d760662016-02-20 16:05:43 +0530719 and data count(here number of BSS observed)
gaoleze5108942017-03-31 16:56:42 +0800720 * @sap_ctx : Softap context
721 * @rssi : Max signal strength receieved from a BSS for the channel
722 * @count : Number of BSS observed in the channel
723 *
724 * Return: uint32_t Calculated channel weight based on above two
725 */
726static
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -0700727uint32_t sapweight_rssi_count(struct sap_context *sap_ctx, int8_t rssi,
gaoleze5108942017-03-31 16:56:42 +0800728 uint16_t count)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800729{
730 int32_t rssiWeight = 0;
731 int32_t countWeight = 0;
732 uint32_t rssicountWeight = 0;
gaoleze5108942017-03-31 16:56:42 +0800733 uint8_t softap_rssi_weight_cfg, softap_count_weight_cfg;
734 uint8_t softap_rssi_weight_local, softap_count_weight_local;
735
736 softap_rssi_weight_cfg =
737 ACS_WEIGHT_SOFTAP_RSSI_CFG(sap_ctx->auto_channel_select_weight);
738
739 softap_count_weight_cfg =
740 ACS_WEIGHT_SOFTAP_COUNT_CFG(sap_ctx->auto_channel_select_weight);
741
742 softap_rssi_weight_local =
743 ACS_WEIGHT_CFG_TO_LOCAL(sap_ctx->auto_channel_select_weight,
744 softap_rssi_weight_cfg);
745
746 softap_count_weight_local =
747 ACS_WEIGHT_CFG_TO_LOCAL(sap_ctx->auto_channel_select_weight,
748 softap_count_weight_cfg);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800749
750 /* Weight from RSSI */
gaoleze5108942017-03-31 16:56:42 +0800751 rssiWeight = ACS_WEIGHT_COMPUTE(sap_ctx->auto_channel_select_weight,
752 softap_rssi_weight_cfg,
753 rssi - SOFTAP_MIN_RSSI,
754 SOFTAP_MAX_RSSI - SOFTAP_MIN_RSSI);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800755
gaoleze5108942017-03-31 16:56:42 +0800756 if (rssiWeight > softap_rssi_weight_local)
757 rssiWeight = softap_rssi_weight_local;
758
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800759 else if (rssiWeight < 0)
760 rssiWeight = 0;
761
762 /* Weight from data count */
gaoleze5108942017-03-31 16:56:42 +0800763 countWeight = ACS_WEIGHT_COMPUTE(sap_ctx->auto_channel_select_weight,
764 softap_count_weight_cfg,
765 count - SOFTAP_MIN_COUNT,
766 SOFTAP_MAX_COUNT - SOFTAP_MIN_COUNT);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800767
gaoleze5108942017-03-31 16:56:42 +0800768 if (countWeight > softap_count_weight_local)
769 countWeight = softap_count_weight_local;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800770
771 rssicountWeight = rssiWeight + countWeight;
772
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530773 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800774 "In %s, rssiWeight=%d, countWeight=%d, rssicountWeight=%d",
775 __func__, rssiWeight, countWeight, rssicountWeight);
776
777 return rssicountWeight;
778}
779
780/**
gaoleze5108942017-03-31 16:56:42 +0800781 * sap_get_channel_status() - get channel info via channel number
782 * @p_mac: Pointer to Global MAC structure
783 * @channel_id: channel id
784 *
785 * Return: chan status info
786 */
787static struct lim_channel_status *sap_get_channel_status
788 (tpAniSirGlobal p_mac, uint32_t channel_id)
789{
790 return csr_get_channel_status(p_mac, channel_id);
791}
792
793/**
794 * sap_clear_channel_status() - clear chan info
795 * @p_mac: Pointer to Global MAC structure
796 *
797 * Return: none
798 */
799static void sap_clear_channel_status(tpAniSirGlobal p_mac)
800{
801 csr_clear_channel_status(p_mac);
802}
803
804/**
805 * sap_weight_channel_noise_floor() - compute noise floor weight
806 * @sap_ctx: sap context
807 * @chn_stat: Pointer to chan status info
808 *
809 * Return: channel noise floor weight
810 */
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -0700811static uint32_t sap_weight_channel_noise_floor(struct sap_context *sap_ctx,
gaoleze5108942017-03-31 16:56:42 +0800812 struct lim_channel_status
813 *channel_stat)
814{
815 uint32_t noise_floor_weight;
816 uint8_t softap_nf_weight_cfg;
817 uint8_t softap_nf_weight_local;
818
819 softap_nf_weight_cfg =
820 ACS_WEIGHT_SOFTAP_NOISE_FLOOR_CFG
821 (sap_ctx->auto_channel_select_weight);
822
823 softap_nf_weight_local =
824 ACS_WEIGHT_CFG_TO_LOCAL(sap_ctx->auto_channel_select_weight,
825 softap_nf_weight_cfg);
826
827 if (channel_stat == NULL || channel_stat->channelfreq == 0) {
828 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
829 "In %s, sanity check failed return max weight",
830 __func__);
831 return softap_nf_weight_local;
832 }
833
834 noise_floor_weight = (channel_stat->noise_floor == 0) ? 0 :
835 (ACS_WEIGHT_COMPUTE(
836 sap_ctx->auto_channel_select_weight,
837 softap_nf_weight_cfg,
838 channel_stat->noise_floor -
839 SOFTAP_MIN_NF,
840 SOFTAP_MAX_NF - SOFTAP_MIN_NF));
841
842 if (noise_floor_weight > softap_nf_weight_local)
843 noise_floor_weight = softap_nf_weight_local;
844 else if (noise_floor_weight < 0)
845 noise_floor_weight = 0;
846
847 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
848 "In %s, nf=%d, nfwc=%d, nfwl=%d, nfw=%d",
849 __func__, channel_stat->noise_floor,
850 softap_nf_weight_cfg, softap_nf_weight_local,
851 noise_floor_weight);
852
853 return noise_floor_weight;
854}
855
856/**
857 * sap_weight_channel_free() - compute channel free weight
858 * @sap_ctx: sap context
859 * @chn_stat: Pointer to chan status info
860 *
861 * Return: channel free weight
862 */
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -0700863static uint32_t sap_weight_channel_free(struct sap_context *sap_ctx,
gaoleze5108942017-03-31 16:56:42 +0800864 struct lim_channel_status
865 *channel_stat)
866{
867 uint32_t channel_free_weight;
868 uint8_t softap_channel_free_weight_cfg;
869 uint8_t softap_channel_free_weight_local;
870 uint32_t rx_clear_count = 0;
871 uint32_t cycle_count = 0;
872
873 softap_channel_free_weight_cfg =
874 ACS_WEIGHT_SOFTAP_CHANNEL_FREE_CFG
875 (sap_ctx->auto_channel_select_weight);
876
877 softap_channel_free_weight_local =
878 ACS_WEIGHT_CFG_TO_LOCAL(sap_ctx->auto_channel_select_weight,
879 softap_channel_free_weight_cfg);
880
881 if (channel_stat == NULL || channel_stat->channelfreq == 0) {
882 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
883 "In %s, sanity check failed return max weight",
884 __func__);
885 return softap_channel_free_weight_local;
886 }
887
888 rx_clear_count = channel_stat->rx_clear_count -
889 channel_stat->tx_frame_count -
890 channel_stat->rx_frame_count;
891 cycle_count = channel_stat->cycle_count;
892
893 /* LSH 4, otherwise it is always 0. */
894 channel_free_weight = (cycle_count == 0) ? 0 :
895 (ACS_WEIGHT_COMPUTE(
896 sap_ctx->auto_channel_select_weight,
897 softap_channel_free_weight_cfg,
898 ((rx_clear_count << 8) +
899 (cycle_count >> 1))/cycle_count -
900 (SOFTAP_MIN_CHNFREE << 8),
901 (SOFTAP_MAX_CHNFREE -
902 SOFTAP_MIN_CHNFREE) << 8));
903
904 if (channel_free_weight > softap_channel_free_weight_local)
905 channel_free_weight = softap_channel_free_weight_local;
906
907 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
908 "In %s, rcc=%d, cc=%d, tc=%d, rc=%d, cfwc=%d, cfwl=%d, cfw=%d",
909 __func__, rx_clear_count, cycle_count,
910 channel_stat->tx_frame_count,
911 channel_stat->rx_frame_count,
912 softap_channel_free_weight_cfg,
913 softap_channel_free_weight_local,
914 channel_free_weight);
915
916 return channel_free_weight;
917}
918
919/**
920 * sap_weight_channel_txpwr_range() - compute channel tx power range weight
921 * @sap_ctx: sap context
922 * @chn_stat: Pointer to chan status info
923 *
924 * Return: tx power range weight
925 */
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -0700926static uint32_t sap_weight_channel_txpwr_range(struct sap_context *sap_ctx,
gaoleze5108942017-03-31 16:56:42 +0800927 struct lim_channel_status
928 *channel_stat)
929{
930 uint32_t txpwr_weight_low_speed;
931 uint8_t softap_txpwr_range_weight_cfg;
932 uint8_t softap_txpwr_range_weight_local;
933
934 softap_txpwr_range_weight_cfg =
935 ACS_WEIGHT_SOFTAP_TX_POWER_RANGE_CFG
936 (sap_ctx->auto_channel_select_weight);
937
938 softap_txpwr_range_weight_local =
939 ACS_WEIGHT_CFG_TO_LOCAL(sap_ctx->auto_channel_select_weight,
940 softap_txpwr_range_weight_cfg);
941
942 if (channel_stat == NULL || channel_stat->channelfreq == 0) {
943 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
944 "In %s, sanity check failed return max weight",
945 __func__);
946 return softap_txpwr_range_weight_local;
947 }
948
949 txpwr_weight_low_speed = (channel_stat->chan_tx_pwr_range == 0) ? 0 :
950 (ACS_WEIGHT_COMPUTE(
951 sap_ctx->auto_channel_select_weight,
952 softap_txpwr_range_weight_cfg,
953 SOFTAP_MAX_TXPWR -
954 channel_stat->chan_tx_pwr_range,
955 SOFTAP_MAX_TXPWR - SOFTAP_MIN_TXPWR));
956
957 if (txpwr_weight_low_speed > softap_txpwr_range_weight_local)
958 txpwr_weight_low_speed = softap_txpwr_range_weight_local;
959
960 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
961 "In %s, tpr=%d, tprwc=%d, tprwl=%d, tprw=%d",
962 __func__, channel_stat->chan_tx_pwr_range,
963 softap_txpwr_range_weight_cfg,
964 softap_txpwr_range_weight_local,
965 txpwr_weight_low_speed);
966
967 return txpwr_weight_low_speed;
968}
969
970/**
971 * sap_weight_channel_txpwr_tput() - compute channel tx power
972 * throughput weight
973 * @sap_ctx: sap context
974 * @chn_stat: Pointer to chan status info
975 *
976 * Return: tx power throughput weight
977 */
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -0700978static uint32_t sap_weight_channel_txpwr_tput(struct sap_context *sap_ctx,
gaoleze5108942017-03-31 16:56:42 +0800979 struct lim_channel_status
980 *channel_stat)
981{
982 uint32_t txpwr_weight_high_speed;
983 uint8_t softap_txpwr_tput_weight_cfg;
984 uint8_t softap_txpwr_tput_weight_local;
985
986 softap_txpwr_tput_weight_cfg =
987 ACS_WEIGHT_SOFTAP_TX_POWER_THROUGHPUT_CFG
988 (sap_ctx->auto_channel_select_weight);
989
990 softap_txpwr_tput_weight_local =
991 ACS_WEIGHT_CFG_TO_LOCAL(sap_ctx->auto_channel_select_weight,
992 softap_txpwr_tput_weight_cfg);
993
994 if (channel_stat == NULL || channel_stat->channelfreq == 0) {
995 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
996 "In %s, sanity check failed return max weight",
997 __func__);
998 return softap_txpwr_tput_weight_local;
999 }
1000
1001 txpwr_weight_high_speed = (channel_stat->chan_tx_pwr_throughput == 0)
1002 ? 0 : (ACS_WEIGHT_COMPUTE(
1003 sap_ctx->auto_channel_select_weight,
1004 softap_txpwr_tput_weight_cfg,
1005 SOFTAP_MAX_TXPWR -
1006 channel_stat->chan_tx_pwr_throughput,
1007 SOFTAP_MAX_TXPWR - SOFTAP_MIN_TXPWR));
1008
1009 if (txpwr_weight_high_speed > softap_txpwr_tput_weight_local)
1010 txpwr_weight_high_speed = softap_txpwr_tput_weight_local;
1011
1012 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
1013 "In %s, tpt=%d, tptwc=%d, tptwl=%d, tptw=%d",
1014 __func__, channel_stat->chan_tx_pwr_throughput,
1015 softap_txpwr_tput_weight_cfg,
1016 softap_txpwr_tput_weight_local,
1017 txpwr_weight_high_speed);
1018
1019 return txpwr_weight_high_speed;
1020}
1021
1022/**
1023 * sap_weight_channel_status() - compute chan status weight
1024 * @sap_ctx: sap context
1025 * @chn_stat: Pointer to chan status info
1026 *
1027 * Return: chan status weight
1028 */
1029static
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -07001030uint32_t sap_weight_channel_status(struct sap_context *sap_ctx,
gaoleze5108942017-03-31 16:56:42 +08001031 struct lim_channel_status *channel_stat)
1032{
1033 return sap_weight_channel_noise_floor(sap_ctx, channel_stat) +
1034 sap_weight_channel_free(sap_ctx, channel_stat) +
1035 sap_weight_channel_txpwr_range(sap_ctx, channel_stat) +
1036 sap_weight_channel_txpwr_tput(sap_ctx, channel_stat);
1037}
1038
1039/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001040 * sap_update_rssi_bsscount() - updates bss count and rssi effect.
1041 *
1042 * @pSpectCh: Channel Information
1043 * @offset: Channel Offset
1044 * @sap_24g: Channel is in 2.4G or 5G
Liangwei Dong71ed6502016-10-20 03:40:45 -04001045 * @spectch_start: the start of spect ch array
1046 * @spectch_end: the end of spect ch array
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001047 *
1048 * sap_update_rssi_bsscount updates bss count and rssi effect based
1049 * on the channel offset.
1050 *
1051 * Return: None.
1052 */
1053
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001054static void sap_update_rssi_bsscount(tSapSpectChInfo *pSpectCh, int32_t offset,
Liangwei Dong71ed6502016-10-20 03:40:45 -04001055 bool sap_24g, tSapSpectChInfo *spectch_start,
1056 tSapSpectChInfo *spectch_end)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001057{
1058 tSapSpectChInfo *pExtSpectCh = NULL;
1059 int32_t rssi, rsssi_effect;
1060
1061 pExtSpectCh = (pSpectCh + offset);
Liangwei Dong71ed6502016-10-20 03:40:45 -04001062 if (pExtSpectCh != NULL &&
1063 pExtSpectCh >= spectch_start &&
1064 pExtSpectCh < spectch_end) {
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
1497 * @halHandle: Pointer to HAL handle
1498 * @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,
1506 tHalHandle halHandle,
1507 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;
1513
1514 tCsrScanResultInfo *pScanResult;
1515 tSapSpectChInfo *pSpectCh = pSpectInfoParams->pSpectCh;
1516 uint32_t operatingBand;
1517 uint16_t channelWidth;
1518 uint16_t secondaryChannelOffset;
1519 uint16_t centerFreq;
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001520 uint16_t centerFreq_2 = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001521 uint16_t vhtSupport;
1522 uint32_t ieLen = 0;
1523 tSirProbeRespBeacon *pBeaconStruct;
1524 tpAniSirGlobal pMac = (tpAniSirGlobal) halHandle;
Liangwei Dong71ed6502016-10-20 03:40:45 -04001525 tSapSpectChInfo *spectch_start = pSpectInfoParams->pSpectCh;
1526 tSapSpectChInfo *spectch_end = pSpectInfoParams->pSpectCh +
1527 pSpectInfoParams->numSpectChans;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001528
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301529 pBeaconStruct = qdf_mem_malloc(sizeof(tSirProbeRespBeacon));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001530 if (NULL == pBeaconStruct) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301531 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Kaushik, Sushantee3ed032016-08-04 16:40:46 +05301532 "Unable to allocate memory in sap_compute_spect_weight");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001533 return;
1534 }
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301535 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001536 "In %s, Computing spectral weight", __func__);
1537
1538 /**
1539 * Soft AP specific channel weight calculation using DFS formula
1540 */
1541 SET_ACS_BAND(operatingBand, sap_ctx);
1542
1543 pScanResult = sme_scan_result_get_first(halHandle, pResult);
1544
1545 while (pScanResult) {
1546 pSpectCh = pSpectInfoParams->pSpectCh;
1547 /* Defining the default values, so that any value will hold the default values */
1548 channelWidth = eHT_CHANNEL_WIDTH_20MHZ;
1549 secondaryChannelOffset = PHY_SINGLE_CHANNEL_CENTERED;
1550 vhtSupport = 0;
1551 centerFreq = 0;
1552
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001553
Yingying Tang22facc12016-10-20 17:43:59 +08001554 ieLen = GET_IE_LEN_IN_BSS(
1555 pScanResult->BssDescriptor.length);
1556 qdf_mem_set((uint8_t *) pBeaconStruct,
1557 sizeof(tSirProbeRespBeacon), 0);
1558
1559
1560 if ((sir_parse_beacon_ie
1561 (pMac, pBeaconStruct, (uint8_t *)
1562 (pScanResult->BssDescriptor.ieFields),
1563 ieLen)) == eSIR_SUCCESS)
1564 sap_upd_chan_spec_params(
1565 pBeaconStruct,
1566 &channelWidth,
1567 &secondaryChannelOffset,
1568 &vhtSupport, &centerFreq,
1569 &centerFreq_2);
1570
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001571 /* Processing for each tCsrScanResultInfo in the tCsrScanResult DLink list */
1572 for (chn_num = 0; chn_num < pSpectInfoParams->numSpectChans;
1573 chn_num++) {
1574
1575 /*
1576 * if the Beacon has channel ID, use it other wise we will
1577 * rely on the channelIdSelf
1578 */
1579 if (pScanResult->BssDescriptor.channelId == 0)
1580 channel_id =
1581 pScanResult->BssDescriptor.channelIdSelf;
1582 else
1583 channel_id =
1584 pScanResult->BssDescriptor.channelId;
1585
1586 if (pSpectCh && (channel_id == pSpectCh->chNum)) {
1587 if (pSpectCh->rssiAgr <
1588 pScanResult->BssDescriptor.rssi)
1589 pSpectCh->rssiAgr =
1590 pScanResult->BssDescriptor.rssi;
1591
1592 ++pSpectCh->bssCount; /* Increment the count of BSS */
1593
1594 /*
1595 * Connsidering the Extension Channel
1596 * only in a channels
1597 */
1598 switch (operatingBand) {
1599 case eCSR_DOT11_MODE_11a:
1600 sap_interference_rssi_count_5G(
1601 pSpectCh, channelWidth,
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001602 secondaryChannelOffset,
1603 centerFreq,
1604 centerFreq_2,
Liangwei Dong71ed6502016-10-20 03:40:45 -04001605 channel_id,
1606 spectch_start,
1607 spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001608 break;
1609
1610 case eCSR_DOT11_MODE_11g:
Liangwei Dong71ed6502016-10-20 03:40:45 -04001611 sap_interference_rssi_count(pSpectCh,
1612 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001613 break;
1614
1615 case eCSR_DOT11_MODE_abg:
1616 sap_interference_rssi_count_5G(
1617 pSpectCh, channelWidth,
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001618 secondaryChannelOffset,
1619 centerFreq,
1620 centerFreq_2,
Liangwei Dong71ed6502016-10-20 03:40:45 -04001621 channel_id,
1622 spectch_start,
1623 spectch_end);
1624 sap_interference_rssi_count(pSpectCh,
1625 spectch_start, spectch_end);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001626 break;
1627 }
1628
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301629 QDF_TRACE(QDF_MODULE_ID_SAP,
1630 QDF_TRACE_LEVEL_INFO_HIGH,
Jeff Johnsona7c0ddb2017-09-18 08:14:12 -07001631 "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 -08001632 __func__,
1633 pScanResult->BssDescriptor.
1634 channelIdSelf,
1635 pScanResult->BssDescriptor.channelId,
1636 pScanResult->BssDescriptor.rssi,
1637 pSpectCh->bssCount, pScanResult,
1638 pSpectCh->channelWidth,
1639 secondaryChannelOffset, centerFreq);
1640 pSpectCh++;
1641 break;
1642 } else {
1643 pSpectCh++;
1644 }
1645 }
1646
1647 pScanResult = sme_scan_result_get_next(halHandle, pResult);
1648 }
1649
1650 /* Calculate the weights for all channels in the spectrum pSpectCh */
1651 pSpectCh = pSpectInfoParams->pSpectCh;
1652
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301653 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001654 "In %s, Spectrum Channels Weight", __func__);
1655
1656 for (chn_num = 0; chn_num < (pSpectInfoParams->numSpectChans);
1657 chn_num++) {
1658
1659 /*
1660 rssi : Maximum received signal strength among all BSS on that channel
1661 bssCount : Number of BSS on that channel
1662 */
1663
1664 rssi = (int8_t) pSpectCh->rssiAgr;
1665 if (ch_in_pcl(sap_ctx, chn_num))
1666 rssi -= PCL_RSSI_DISCOUNT;
1667
Himanshu Agarwalfee2e362018-01-18 20:26:35 +05301668 if (pSpectCh->weight == SAP_ACS_WEIGHT_MAX)
1669 goto debug_info;
1670
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001671 pSpectCh->weight =
gaoleze5108942017-03-31 16:56:42 +08001672 SAPDFS_NORMALISE_1000 *
1673 (sapweight_rssi_count(sap_ctx, rssi,
1674 pSpectCh->bssCount) + sap_weight_channel_status(
1675 sap_ctx, sap_get_channel_status(pMac,
1676 pSpectCh->chNum)));
1677 if (pSpectCh->weight > SAP_ACS_WEIGHT_MAX)
1678 pSpectCh->weight = SAP_ACS_WEIGHT_MAX;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001679 pSpectCh->weight_copy = pSpectCh->weight;
1680
Himanshu Agarwalfee2e362018-01-18 20:26:35 +05301681debug_info:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001682 /* ------ Debug Info ------ */
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301683 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001684 "In %s, Chan=%d Weight= %d rssiAgr=%d bssCount=%d",
1685 __func__, pSpectCh->chNum, pSpectCh->weight,
1686 pSpectCh->rssiAgr, pSpectCh->bssCount);
1687 /* ------ Debug Info ------ */
1688 pSpectCh++;
1689 }
gaoleze5108942017-03-31 16:56:42 +08001690 sap_clear_channel_status(pMac);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301691 qdf_mem_free(pBeaconStruct);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001692}
1693
1694/*==========================================================================
1695 FUNCTION sap_chan_sel_exit
1696
1697 DESCRIPTION
1698 Exit function for free out the allocated memory, to be called
1699 at the end of the dfsSelectChannel function
1700
1701 DEPENDENCIES
1702 NA.
1703
1704 PARAMETERS
1705
1706 IN
1707 pSpectInfoParams : Pointer to the tSapChSelSpectInfo structure
1708
1709 RETURN VALUE
1710 void : NULL
1711
1712 SIDE EFFECTS
1713 ============================================================================*/
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001714static void sap_chan_sel_exit(tSapChSelSpectInfo *pSpectInfoParams)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001715{
1716 /* Free all the allocated memory */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301717 qdf_mem_free(pSpectInfoParams->pSpectCh);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001718}
1719
1720/*==========================================================================
1721 FUNCTION sap_sort_chl_weight
1722
1723 DESCRIPTION
1724 Funtion to sort the channels with the least weight first for 20MHz channels
1725
1726 DEPENDENCIES
1727 NA.
1728
1729 PARAMETERS
1730
1731 IN
1732 pSpectInfoParams : Pointer to the tSapChSelSpectInfo structure
1733
1734 RETURN VALUE
1735 void : NULL
1736
1737 SIDE EFFECTS
1738 ============================================================================*/
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001739static void sap_sort_chl_weight(tSapChSelSpectInfo *pSpectInfoParams)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001740{
1741 tSapSpectChInfo temp;
1742
1743 tSapSpectChInfo *pSpectCh = NULL;
1744 uint32_t i = 0, j = 0, minWeightIndex = 0;
1745
1746 pSpectCh = pSpectInfoParams->pSpectCh;
1747 for (i = 0; i < pSpectInfoParams->numSpectChans; i++) {
1748 minWeightIndex = i;
1749 for (j = i + 1; j < pSpectInfoParams->numSpectChans; j++) {
1750 if (pSpectCh[j].weight <
1751 pSpectCh[minWeightIndex].weight) {
1752 minWeightIndex = j;
1753 }
1754 }
1755 if (minWeightIndex != i) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301756 qdf_mem_copy(&temp, &pSpectCh[minWeightIndex],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001757 sizeof(*pSpectCh));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301758 qdf_mem_copy(&pSpectCh[minWeightIndex], &pSpectCh[i],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001759 sizeof(*pSpectCh));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301760 qdf_mem_copy(&pSpectCh[i], &temp, sizeof(*pSpectCh));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001761 }
1762 }
1763}
1764
1765/**
bingse2782382017-03-23 10:34:52 +08001766 * set_ht80_chl_bit() - to set availabe channel to ht80 channel bitmap
1767 * @channel_bitmap: Pointer to the chan_bonding_bitmap structure
1768 * @spect_info_params: Pointer to the tSapChSelSpectInfo structure
1769 *
1770 * Return: none
1771 */
1772static void set_ht80_chl_bit(chan_bonding_bitmap *channel_bitmap,
1773 tSapChSelSpectInfo *spec_info_params)
1774{
1775 uint8_t i, j;
1776 tSapSpectChInfo *spec_info;
1777 int start_channel = 0;
1778
1779 channel_bitmap->chanBondingSet[0].startChannel =
1780 acs_ht80_channels[0].chStartNum;
1781 channel_bitmap->chanBondingSet[1].startChannel =
1782 acs_ht80_channels[1].chStartNum;
1783 channel_bitmap->chanBondingSet[2].startChannel =
1784 acs_ht80_channels[2].chStartNum;
1785 channel_bitmap->chanBondingSet[3].startChannel =
1786 acs_ht80_channels[3].chStartNum;
1787 channel_bitmap->chanBondingSet[4].startChannel =
1788 acs_ht80_channels[4].chStartNum;
1789 channel_bitmap->chanBondingSet[5].startChannel =
1790 acs_ht80_channels[5].chStartNum;
1791
1792 spec_info = spec_info_params->pSpectCh;
1793 for (j = 0; j < spec_info_params->numSpectChans; j++) {
1794 for (i = 0; i < MAX_80MHZ_BANDS; i++) {
1795 start_channel =
1796 channel_bitmap->chanBondingSet[i].startChannel;
1797 if (spec_info[j].chNum >= start_channel &&
1798 (spec_info[j].chNum <= start_channel + 12)) {
1799 channel_bitmap->chanBondingSet[i].channelMap |=
1800 1 << ((spec_info[j].chNum -
1801 start_channel)/4);
1802 break;
1803 }
1804 }
1805 }
1806}
1807
1808/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001809 * sap_sort_chl_weight_ht80() - to sort the channels with the least weight
1810 * @pSpectInfoParams: Pointer to the tSapChSelSpectInfo structure
1811 *
1812 * Funtion to sort the channels with the least weight first for HT80 channels
1813 *
1814 * Return: none
1815 */
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001816static void sap_sort_chl_weight_ht80(tSapChSelSpectInfo *pSpectInfoParams)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001817{
1818 uint8_t i, j, n;
1819 tSapSpectChInfo *pSpectInfo;
1820 uint8_t minIdx;
bingse2782382017-03-23 10:34:52 +08001821 int start_channel = 0;
1822 chan_bonding_bitmap *channel_bitmap;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001823
bingse2782382017-03-23 10:34:52 +08001824 channel_bitmap = qdf_mem_malloc(sizeof(chan_bonding_bitmap));
1825 if (NULL == channel_bitmap) {
1826 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG,
1827 "%s: Failed to allocate memory", __func__);
1828 return;
1829 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001830 pSpectInfo = pSpectInfoParams->pSpectCh;
1831 /* for each HT80 channel, calculate the combined weight of the
1832 four 20MHz weight */
1833 for (i = 0; i < ARRAY_SIZE(acs_ht80_channels); i++) {
1834 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
1835 if (pSpectInfo[j].chNum ==
1836 acs_ht80_channels[i].chStartNum)
1837 break;
1838 }
1839 if (j == pSpectInfoParams->numSpectChans)
1840 continue;
1841
1842 if (!(((pSpectInfo[j].chNum + 4) == pSpectInfo[j + 1].chNum) &&
1843 ((pSpectInfo[j].chNum + 8) ==
1844 pSpectInfo[j + 2].chNum) &&
1845 ((pSpectInfo[j].chNum + 12) ==
1846 pSpectInfo[j + 3].chNum))) {
1847 /*
1848 * some channels does not exist in pSectInfo array,
1849 * skip this channel and those in the same HT80 width
1850 */
1851 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 4;
1852 if ((pSpectInfo[j].chNum + 4) ==
1853 pSpectInfo[j + 1].chNum)
1854 pSpectInfo[j + 1].weight =
1855 SAP_ACS_WEIGHT_MAX * 4;
1856 if ((pSpectInfo[j].chNum + 8) ==
1857 pSpectInfo[j + 2].chNum)
1858 pSpectInfo[j + 2].weight =
1859 SAP_ACS_WEIGHT_MAX * 4;
1860 if ((pSpectInfo[j].chNum + 12) ==
1861 pSpectInfo[j + 3].chNum)
1862 pSpectInfo[j + 3].weight =
1863 SAP_ACS_WEIGHT_MAX * 4;
1864 continue;
1865 }
1866 /*found the channel, add the 4 adjacent channels' weight */
1867 acs_ht80_channels[i].weight = pSpectInfo[j].weight +
1868 pSpectInfo[j + 1].weight + pSpectInfo[j + 2].weight +
1869 pSpectInfo[j + 3].weight;
1870 /* find best channel among 4 channels as the primary channel */
1871 if ((pSpectInfo[j].weight + pSpectInfo[j + 1].weight) <
1872 (pSpectInfo[j + 2].weight + pSpectInfo[j + 3].weight)) {
1873 /* lower 2 channels are better choice */
1874 if (pSpectInfo[j].weight < pSpectInfo[j + 1].weight)
1875 minIdx = 0;
1876 else
1877 minIdx = 1;
1878 } else if (pSpectInfo[j + 2].weight <=
1879 pSpectInfo[j + 3].weight) {
1880 /* upper 2 channels are better choice */
1881 minIdx = 2;
1882 } else {
1883 minIdx = 3;
1884 }
1885
1886 /*
1887 * set all 4 channels to max value first, then reset the
1888 * best channel as the selected primary channel, update its
1889 * weightage with the combined weight value
1890 */
1891 for (n = 0; n < 4; n++)
1892 pSpectInfo[j + n].weight = SAP_ACS_WEIGHT_MAX * 4;
1893
1894 pSpectInfo[j + minIdx].weight = acs_ht80_channels[i].weight;
1895 }
1896
bingse2782382017-03-23 10:34:52 +08001897 /*
1898 * mark the weight of the channel that can't satisfy 80MHZ
1899 * as max value, so that it will be sorted to the bottom
1900 */
1901 set_ht80_chl_bit(channel_bitmap, pSpectInfoParams);
1902 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
1903 for (i = 0; i < MAX_80MHZ_BANDS; i++) {
1904 start_channel =
1905 channel_bitmap->chanBondingSet[i].startChannel;
1906 if (pSpectInfo[j].chNum >= start_channel &&
1907 (pSpectInfo[j].chNum <=
1908 start_channel + 12) &&
1909 channel_bitmap->chanBondingSet[i].channelMap !=
1910 SAP_80MHZ_MASK)
1911 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 4;
1912 }
1913 }
1914
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001915 pSpectInfo = pSpectInfoParams->pSpectCh;
1916 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
1917 if (CHANNEL_165 == pSpectInfo[j].chNum) {
1918 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 4;
1919 break;
1920 }
1921 }
1922
Manishekar Chandrasekaran44e334f2016-05-30 16:42:50 +05301923 sap_sort_chl_weight(pSpectInfoParams);
1924
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001925 pSpectInfo = pSpectInfoParams->pSpectCh;
1926 for (j = 0; j < (pSpectInfoParams->numSpectChans); j++) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301927 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001928 FL("Channel=%d Weight= %d rssi=%d bssCount=%d"),
1929 pSpectInfo->chNum, pSpectInfo->weight,
1930 pSpectInfo->rssiAgr, pSpectInfo->bssCount);
1931 pSpectInfo++;
1932 }
bingse2782382017-03-23 10:34:52 +08001933 qdf_mem_free(channel_bitmap);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001934}
1935
1936/**
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001937 * sap_sort_chl_weight_vht160() - to sort the channels with the least weight
1938 * @pSpectInfoParams: Pointer to the tSapChSelSpectInfo structure
1939 *
1940 * Funtion to sort the channels with the least weight first for VHT160 channels
1941 *
1942 * Return: none
1943 */
Jeff Johnson464f7ea2016-10-07 10:21:26 -07001944static void sap_sort_chl_weight_vht160(tSapChSelSpectInfo *pSpectInfoParams)
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001945{
1946 uint8_t i, j, n, idx;
1947 tSapSpectChInfo *pSpectInfo;
1948 uint8_t minIdx;
1949
1950 pSpectInfo = pSpectInfoParams->pSpectCh;
1951 /* for each VHT160 channel, calculate the combined weight of the
1952 8 20MHz weight */
1953 for (i = 0; i < ARRAY_SIZE(acs_vht160_channels); i++) {
1954 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
1955 if (pSpectInfo[j].chNum ==
1956 acs_vht160_channels[i].chStartNum)
1957 break;
1958 }
1959 if (j == pSpectInfoParams->numSpectChans)
1960 continue;
1961
1962 if (!(((pSpectInfo[j].chNum + 4) == pSpectInfo[j + 1].chNum) &&
1963 ((pSpectInfo[j].chNum + 8) ==
1964 pSpectInfo[j + 2].chNum) &&
1965 ((pSpectInfo[j].chNum + 12) ==
1966 pSpectInfo[j + 3].chNum) &&
1967 ((pSpectInfo[j].chNum + 16) ==
1968 pSpectInfo[j + 4].chNum) &&
1969 ((pSpectInfo[j].chNum + 20) ==
1970 pSpectInfo[j + 5].chNum) &&
1971 ((pSpectInfo[j].chNum + 24) ==
1972 pSpectInfo[j + 6].chNum) &&
1973 ((pSpectInfo[j].chNum + 28) ==
1974 pSpectInfo[j + 7].chNum))) {
1975 /*
1976 * some channels does not exist in pSectInfo array,
1977 * skip this channel and those in the same VHT160 width
1978 */
1979 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 8;
1980 if ((pSpectInfo[j].chNum + 4) ==
1981 pSpectInfo[j + 1].chNum)
1982 pSpectInfo[j + 1].weight =
1983 SAP_ACS_WEIGHT_MAX * 8;
1984 if ((pSpectInfo[j].chNum + 8) ==
1985 pSpectInfo[j + 2].chNum)
1986 pSpectInfo[j + 2].weight =
1987 SAP_ACS_WEIGHT_MAX * 8;
1988 if ((pSpectInfo[j].chNum + 12) ==
1989 pSpectInfo[j + 3].chNum)
1990 pSpectInfo[j + 3].weight =
1991 SAP_ACS_WEIGHT_MAX * 8;
1992 if ((pSpectInfo[j].chNum + 16) ==
1993 pSpectInfo[j + 4].chNum)
1994 pSpectInfo[j + 4].weight =
1995 SAP_ACS_WEIGHT_MAX * 8;
1996 if ((pSpectInfo[j].chNum + 20) ==
1997 pSpectInfo[j + 5].chNum)
1998 pSpectInfo[j + 5].weight =
1999 SAP_ACS_WEIGHT_MAX * 8;
2000 if ((pSpectInfo[j].chNum + 24) ==
2001 pSpectInfo[j + 6].chNum)
2002 pSpectInfo[j + 6].weight =
2003 SAP_ACS_WEIGHT_MAX * 8;
2004 if ((pSpectInfo[j].chNum + 28) ==
2005 pSpectInfo[j + 7].chNum)
2006 pSpectInfo[j + 7].weight =
2007 SAP_ACS_WEIGHT_MAX * 8;
2008 continue;
2009 }
2010 /*found the channel, add the 7 adjacent channels' weight */
2011 acs_vht160_channels[i].weight = pSpectInfo[j].weight +
2012 pSpectInfo[j + 1].weight + pSpectInfo[j + 2].weight +
2013 pSpectInfo[j + 3].weight + pSpectInfo[j + 4].weight +
2014 pSpectInfo[j + 5].weight + pSpectInfo[j + 6].weight +
2015 pSpectInfo[j + 7].weight;
2016
2017 /* find best channel among 8 channels as the primary channel */
2018 if ((pSpectInfo[j].weight + pSpectInfo[j + 1].weight +
2019 pSpectInfo[j + 2].weight + pSpectInfo[j + 3].weight) >
2020 (pSpectInfo[j + 4].weight + pSpectInfo[j + 5].weight +
2021 pSpectInfo[j + 6].weight + pSpectInfo[j + 7].weight))
2022 idx = 4;
2023 else
2024 idx = 0;
2025 /* find best channel among 4 channels as the primary channel */
2026 if ((pSpectInfo[j + idx].weight +
2027 pSpectInfo[j + idx + 1].weight) <
2028 (pSpectInfo[j + idx + 2].weight +
2029 pSpectInfo[j + idx + 3].weight)) {
2030 /* lower 2 channels are better choice */
2031 if (pSpectInfo[j + idx].weight <
2032 pSpectInfo[j + idx + 1].weight)
2033 minIdx = 0 + idx;
2034 else
2035 minIdx = 1 + idx;
2036 } else if (pSpectInfo[j + idx + 2].weight <=
2037 pSpectInfo[j + idx + 3].weight) {
2038 /* upper 2 channels are better choice */
2039 minIdx = 2 + idx;
2040 } else {
2041 minIdx = 3 + idx;
2042 }
2043
2044 /*
2045 * set all 8 channels to max value first, then reset the
2046 * best channel as the selected primary channel, update its
2047 * weightage with the combined weight value
2048 */
2049 for (n = 0; n < 8; n++)
2050 pSpectInfo[j + n].weight = SAP_ACS_WEIGHT_MAX * 8;
2051
2052 pSpectInfo[j + minIdx].weight = acs_vht160_channels[i].weight;
2053 }
2054
2055 pSpectInfo = pSpectInfoParams->pSpectCh;
2056 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
2057 if (CHANNEL_165 == pSpectInfo[j].chNum) {
2058 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 8;
2059 break;
2060 }
2061 }
2062
Manishekar Chandrasekaran44e334f2016-05-30 16:42:50 +05302063 sap_sort_chl_weight(pSpectInfoParams);
2064
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07002065 pSpectInfo = pSpectInfoParams->pSpectCh;
2066 for (j = 0; j < (pSpectInfoParams->numSpectChans); j++) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302067 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07002068 FL("Channel=%d Weight= %d rssi=%d bssCount=%d"),
2069 pSpectInfo->chNum, pSpectInfo->weight,
2070 pSpectInfo->rssiAgr, pSpectInfo->bssCount);
2071 pSpectInfo++;
2072 }
2073}
2074
2075/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002076 * sap_sort_chl_weight_ht40_24_g() - to sort channel with the least weight
2077 * @pSpectInfoParams: Pointer to the tSapChSelSpectInfo structure
2078 *
2079 * Funtion to sort the channels with the least weight first for HT40 channels
2080 *
2081 * Return: none
2082 */
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002083static void sap_sort_chl_weight_ht40_24_g(tSapChSelSpectInfo *pSpectInfoParams,
2084 v_REGDOMAIN_t domain)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002085{
2086 uint8_t i, j;
2087 tSapSpectChInfo *pSpectInfo;
2088 uint32_t tmpWeight1, tmpWeight2;
bingse2782382017-03-23 10:34:52 +08002089 uint32_t ht40plus2gendch = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002090
2091 pSpectInfo = pSpectInfoParams->pSpectCh;
2092 /*
2093 * for each HT40 channel, calculate the combined weight of the
2094 * two 20MHz weight
2095 */
2096 for (i = 0; i < ARRAY_SIZE(acs_ht40_channels24_g); i++) {
2097 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
2098 if (pSpectInfo[j].chNum ==
2099 acs_ht40_channels24_g[i].chStartNum)
2100 break;
2101 }
2102 if (j == pSpectInfoParams->numSpectChans)
2103 continue;
2104
2105 if (!((pSpectInfo[j].chNum + 4) == pSpectInfo[j + 4].chNum)) {
2106 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2;
2107 continue;
2108 }
2109 /*
2110 * check if there is another channel combination possiblity
2111 * e.g., {1, 5} & {5, 9}
2112 */
2113 if ((pSpectInfo[j + 4].chNum + 4) == pSpectInfo[j + 8].chNum) {
2114 /* need to compare two channel pairs */
2115 tmpWeight1 = pSpectInfo[j].weight +
2116 pSpectInfo[j + 4].weight;
2117 tmpWeight2 = pSpectInfo[j + 4].weight +
2118 pSpectInfo[j + 8].weight;
2119 if (tmpWeight1 <= tmpWeight2) {
2120 if (pSpectInfo[j].weight <=
2121 pSpectInfo[j + 4].weight) {
2122 pSpectInfo[j].weight =
2123 tmpWeight1;
2124 pSpectInfo[j + 4].weight =
2125 SAP_ACS_WEIGHT_MAX * 2;
2126 pSpectInfo[j + 8].weight =
2127 SAP_ACS_WEIGHT_MAX * 2;
2128 } else {
2129 pSpectInfo[j + 4].weight =
2130 tmpWeight1;
2131 /* for secondary channel selection */
2132 pSpectInfo[j].weight =
2133 SAP_ACS_WEIGHT_MAX * 2
2134 - 1;
2135 pSpectInfo[j + 8].weight =
2136 SAP_ACS_WEIGHT_MAX * 2;
2137 }
2138 } else {
2139 if (pSpectInfo[j + 4].weight <=
2140 pSpectInfo[j + 8].weight) {
2141 pSpectInfo[j + 4].weight =
2142 tmpWeight2;
2143 pSpectInfo[j].weight =
2144 SAP_ACS_WEIGHT_MAX * 2;
2145 /* for secondary channel selection */
2146 pSpectInfo[j + 8].weight =
2147 SAP_ACS_WEIGHT_MAX * 2
2148 - 1;
2149 } else {
2150 pSpectInfo[j + 8].weight =
2151 tmpWeight2;
2152 pSpectInfo[j].weight =
2153 SAP_ACS_WEIGHT_MAX * 2;
2154 pSpectInfo[j + 4].weight =
2155 SAP_ACS_WEIGHT_MAX * 2;
2156 }
2157 }
2158 } else {
bingsaa6f96a2017-09-11 09:49:43 +08002159 tmpWeight1 = pSpectInfo[j].weight_copy +
2160 pSpectInfo[j + 4].weight_copy;
2161 if (pSpectInfo[j].weight_copy <=
2162 pSpectInfo[j + 4].weight_copy) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002163 pSpectInfo[j].weight = tmpWeight1;
2164 pSpectInfo[j + 4].weight =
2165 SAP_ACS_WEIGHT_MAX * 2;
2166 } else {
2167 pSpectInfo[j + 4].weight = tmpWeight1;
2168 pSpectInfo[j].weight =
2169 SAP_ACS_WEIGHT_MAX * 2;
2170 }
2171 }
2172 }
bingse2782382017-03-23 10:34:52 +08002173 /*
2174 * Every channel should be checked. Add the check for the omissive
2175 * channel. Mark the channel whose combination can't satisfy 40MHZ
2176 * as max value, so that it will be sorted to the bottom.
2177 */
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002178 if (REGDOMAIN_FCC == domain)
bingse2782382017-03-23 10:34:52 +08002179 ht40plus2gendch = HT40PLUS_2G_FCC_CH_END;
2180 else
2181 ht40plus2gendch = HT40PLUS_2G_EURJAP_CH_END;
2182 for (i = HT40MINUS_2G_CH_START; i <= ht40plus2gendch; i++) {
2183 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
2184 if (pSpectInfo[j].chNum == i &&
2185 ((pSpectInfo[j].chNum + 4) !=
2186 pSpectInfo[j+4].chNum) &&
2187 ((pSpectInfo[j].chNum - 4) !=
2188 pSpectInfo[j-4].chNum))
2189 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2;
2190 }
2191 }
2192 for (i = ht40plus2gendch + 1; i <= HT40MINUS_2G_CH_END; i++) {
2193 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
2194 if (pSpectInfo[j].chNum == i &&
2195 (pSpectInfo[j].chNum - 4) !=
2196 pSpectInfo[j-4].chNum)
2197 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2;
2198 }
2199 }
Manishekar Chandrasekaran44e334f2016-05-30 16:42:50 +05302200 sap_sort_chl_weight(pSpectInfoParams);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002201}
2202
2203/*==========================================================================
2204 FUNCTION sap_sort_chl_weight_ht40_5_g
2205
2206 DESCRIPTION
2207 Funtion to sort the channels with the least weight first for HT40 channels
2208
2209 DEPENDENCIES
2210 NA.
2211
2212 PARAMETERS
2213
2214 IN
2215 pSpectInfoParams : Pointer to the tSapChSelSpectInfo structure
2216
2217 RETURN VALUE
2218 void : NULL
2219
2220 SIDE EFFECTS
2221 ============================================================================*/
Jeff Johnson464f7ea2016-10-07 10:21:26 -07002222static void sap_sort_chl_weight_ht40_5_g(tSapChSelSpectInfo *pSpectInfoParams)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002223{
2224 uint8_t i, j;
2225 tSapSpectChInfo *pSpectInfo;
2226
2227 pSpectInfo = pSpectInfoParams->pSpectCh;
2228 /*for each HT40 channel, calculate the combined weight of the
2229 two 20MHz weight */
2230 for (i = 0; i < ARRAY_SIZE(acs_ht40_channels5_g); i++) {
2231 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
2232 if (pSpectInfo[j].chNum ==
2233 acs_ht40_channels5_g[i].chStartNum)
2234 break;
2235 }
2236 if (j == pSpectInfoParams->numSpectChans)
2237 continue;
2238
2239 /* found the channel, add the two adjacent channels' weight */
2240 if ((pSpectInfo[j].chNum + 4) == pSpectInfo[j + 1].chNum) {
2241 acs_ht40_channels5_g[i].weight = pSpectInfo[j].weight +
2242 pSpectInfo[j + 1].weight;
2243 /* select better of the adjact channel as the primary channel */
2244 if (pSpectInfo[j].weight <= pSpectInfo[j + 1].weight) {
2245 pSpectInfo[j].weight =
2246 acs_ht40_channels5_g[i].weight;
2247 /* mark the adjacent channel's weight as max value so
2248 that it will be sorted to the bottom */
2249 pSpectInfo[j + 1].weight =
2250 SAP_ACS_WEIGHT_MAX * 2;
2251 } else {
2252 pSpectInfo[j + 1].weight =
2253 acs_ht40_channels5_g[i].weight;
2254 /* mark the adjacent channel's weight as max value so
2255 that it will be sorted to the bottom */
2256 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2;
2257 }
2258
2259 } else
2260 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2;
2261 }
2262
bingse2782382017-03-23 10:34:52 +08002263 /*
2264 *Every channel should be checked. Add the check for the omissive
2265 * channel. Mark the channel whose combination can't satisfy 40MHZ
2266 * as max value, so that it will be sorted to the bottom
2267 */
2268 for (j = 1; j < pSpectInfoParams->numSpectChans; j++) {
2269 for (i = 0; i < ARRAY_SIZE(acs_ht40_channels5_g); i++) {
2270 if (pSpectInfo[j].chNum ==
2271 (acs_ht40_channels5_g[i].chStartNum +
2272 4) &&
2273 pSpectInfo[j - 1].chNum !=
2274 acs_ht40_channels5_g[i].chStartNum) {
2275 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2;
2276 break;
2277 }
2278 }
2279 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002280 /* avoid channel 165 by setting its weight to max */
2281 pSpectInfo = pSpectInfoParams->pSpectCh;
2282 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
2283 if (CHANNEL_165 == pSpectInfo[j].chNum) {
2284 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2;
2285 break;
2286 }
2287 }
2288
2289 pSpectInfo = pSpectInfoParams->pSpectCh;
2290 for (j = 0; j < (pSpectInfoParams->numSpectChans); j++) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302291 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002292 "In %s, Channel=%d Weight= %d rssi=%d bssCount=%d",
2293 __func__, pSpectInfo->chNum, pSpectInfo->weight,
2294 pSpectInfo->rssiAgr, pSpectInfo->bssCount);
2295 pSpectInfo++;
2296 }
2297
2298 sap_sort_chl_weight(pSpectInfoParams);
2299}
2300
2301/*==========================================================================
2302 FUNCTION sap_sort_chl_weight_all
2303
2304 DESCRIPTION
2305 Funtion to sort the channels with the least weight first
2306
2307 DEPENDENCIES
2308 NA.
2309
2310 PARAMETERS
2311
2312 IN
Jeff Johnsone13d8062017-09-28 06:54:55 -07002313 sap_ctx : Pointer to the struct sap_context *structure
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002314 pSpectInfoParams : Pointer to the tSapChSelSpectInfo structure
2315
2316 RETURN VALUE
2317 void : NULL
2318
2319 SIDE EFFECTS
2320 ============================================================================*/
Jeff Johnsone13d8062017-09-28 06:54:55 -07002321static void sap_sort_chl_weight_all(struct sap_context *sap_ctx,
Jeff Johnson464f7ea2016-10-07 10:21:26 -07002322 tSapChSelSpectInfo *pSpectInfoParams,
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002323 uint32_t operatingBand,
2324 v_REGDOMAIN_t domain)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002325{
2326 tSapSpectChInfo *pSpectCh = NULL;
2327 uint32_t j = 0;
2328#ifndef SOFTAP_CHANNEL_RANGE
2329 uint32_t i = 0;
2330#endif
2331
2332 pSpectCh = pSpectInfoParams->pSpectCh;
2333#ifdef SOFTAP_CHANNEL_RANGE
2334
Jeff Johnsone13d8062017-09-28 06:54:55 -07002335 switch (sap_ctx->acs_cfg->ch_width) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002336 case CH_WIDTH_40MHZ:
2337 if (eCSR_DOT11_MODE_11g == operatingBand)
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002338 sap_sort_chl_weight_ht40_24_g(pSpectInfoParams, domain);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002339 else if (eCSR_DOT11_MODE_11a == operatingBand)
2340 sap_sort_chl_weight_ht40_5_g(pSpectInfoParams);
2341 else {
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002342 sap_sort_chl_weight_ht40_24_g(pSpectInfoParams, domain);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002343 sap_sort_chl_weight_ht40_5_g(pSpectInfoParams);
2344 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002345 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002346 case CH_WIDTH_80MHZ:
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07002347 case CH_WIDTH_80P80MHZ:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002348 sap_sort_chl_weight_ht80(pSpectInfoParams);
2349 break;
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07002350 case CH_WIDTH_160MHZ:
2351 sap_sort_chl_weight_vht160(pSpectInfoParams);
2352 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002353 case CH_WIDTH_20MHZ:
2354 default:
2355 /* Sorting the channels as per weights as 20MHz channels */
2356 sap_sort_chl_weight(pSpectInfoParams);
2357 }
2358
2359#else
2360 /* Sorting the channels as per weights */
2361 for (i = 0; i < SPECT_24GHZ_CH_COUNT; i++) {
2362 minWeightIndex = i;
2363 for (j = i + 1; j < SPECT_24GHZ_CH_COUNT; j++) {
2364 if (pSpectCh[j].weight <
2365 pSpectCh[minWeightIndex].weight) {
2366 minWeightIndex = j;
2367 }
2368 }
2369 if (minWeightIndex != i) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302370 qdf_mem_copy(&temp, &pSpectCh[minWeightIndex],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002371 sizeof(*pSpectCh));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302372 qdf_mem_copy(&pSpectCh[minWeightIndex], &pSpectCh[i],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002373 sizeof(*pSpectCh));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302374 qdf_mem_copy(&pSpectCh[i], &temp, sizeof(*pSpectCh));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002375 }
2376 }
2377#endif
2378
2379 /* For testing */
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302380 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002381 "In %s, Sorted Spectrum Channels Weight", __func__);
2382 pSpectCh = pSpectInfoParams->pSpectCh;
2383 for (j = 0; j < (pSpectInfoParams->numSpectChans); j++) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302384 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002385 "In %s, Channel=%d Weight= %d rssi=%d bssCount=%d",
2386 __func__, pSpectCh->chNum, pSpectCh->weight,
2387 pSpectCh->rssiAgr, pSpectCh->bssCount);
2388 pSpectCh++;
2389 }
2390
2391}
2392
Naveen Rawatbec64d92017-09-13 14:35:21 -07002393/**
2394 * sap_is_ch_non_overlap() - returns true if non-overlapping channel
2395 * @sap_ctx: Sap context
2396 * @ch: channel number
2397 *
2398 * Returns: true if non-overlapping (1, 6, 11) channel, false otherwise
2399 */
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -07002400static bool sap_is_ch_non_overlap(struct sap_context *sap_ctx, uint16_t ch)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002401{
Naveen Rawatbec64d92017-09-13 14:35:21 -07002402 if (sap_ctx->enableOverLapCh)
Srinivas Girigowda74a66d62017-06-21 23:28:25 -07002403 return true;
Naveen Rawatbec64d92017-09-13 14:35:21 -07002404
2405 if ((ch == CHANNEL_1) || (ch == CHANNEL_6) || (ch == CHANNEL_11))
Srinivas Girigowda74a66d62017-06-21 23:28:25 -07002406 return true;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002407
Srinivas Girigowda74a66d62017-06-21 23:28:25 -07002408 return false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002409}
2410
Dustin Brown0ce56d32016-10-17 16:18:03 -07002411#ifdef FEATURE_WLAN_CH_AVOID
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002412/**
2413 * sap_select_channel_no_scan_result() - select SAP channel when no scan results
2414 * are available.
2415 * @sap_ctx: Sap context
2416 *
2417 * Returns: channel number if success, 0 otherwise
2418 */
Kondabattini, Ganesh13bb4b12016-09-04 16:16:53 +05302419static uint8_t sap_select_channel_no_scan_result(tHalHandle hal,
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -07002420 struct sap_context *sap_ctx)
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002421{
Mohit Khanna841044f2016-03-25 16:16:24 -07002422 enum channel_state ch_type;
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002423 uint8_t i, first_safe_ch_in_range = SAP_CHANNEL_NOT_SELECTED;
Kondabattini, Ganesh13bb4b12016-09-04 16:16:53 +05302424 uint32_t dfs_master_cap_enabled;
Dustin Brown0ce56d32016-10-17 16:18:03 -07002425 uint32_t start_ch_num = sap_ctx->acs_cfg->start_ch;
2426 uint32_t end_ch_num = sap_ctx->acs_cfg->end_ch;
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002427 tpAniSirGlobal mac_ctx = NULL;
2428
2429 mac_ctx = PMAC_STRUCT(hal);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002430
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002431 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2432 FL("start - end: %d - %d"), start_ch_num, end_ch_num);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002433
Kondabattini, Ganesh13bb4b12016-09-04 16:16:53 +05302434 sme_cfg_get_int(hal, WNI_CFG_DFS_MASTER_ENABLED,
2435 &dfs_master_cap_enabled);
2436
2437 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2438 "%s: dfs_master %x", __func__, dfs_master_cap_enabled);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002439
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002440 /* get a channel in PCL and within the range */
2441 for (i = 0; i < sap_ctx->acs_cfg->pcl_ch_count; i++) {
2442 if ((sap_ctx->acs_cfg->pcl_channels[i] < start_ch_num) ||
2443 (sap_ctx->acs_cfg->pcl_channels[i] > end_ch_num))
2444 continue;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002445
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002446 first_safe_ch_in_range = sap_ctx->acs_cfg->pcl_channels[i];
2447 break;
2448 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002449
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002450 if (SAP_CHANNEL_NOT_SELECTED != first_safe_ch_in_range)
2451 return first_safe_ch_in_range;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002452
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002453 for (i = 0; i < NUM_CHANNELS; i++) {
2454 if ((safe_channels[i].channelNumber < start_ch_num) ||
2455 (safe_channels[i].channelNumber > end_ch_num))
2456 continue;
2457
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002458 ch_type = wlan_reg_get_channel_state(mac_ctx->pdev,
2459 safe_channels[i].channelNumber);
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002460
2461 if ((ch_type == CHANNEL_STATE_DISABLE) ||
2462 (ch_type == CHANNEL_STATE_INVALID))
2463 continue;
Kondabattini, Ganesh13bb4b12016-09-04 16:16:53 +05302464 if ((!dfs_master_cap_enabled) &&
2465 (CHANNEL_STATE_DFS == ch_type)) {
2466 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2467 "%s: DFS master mode disabled. Skip DFS channel %d",
2468 __func__, safe_channels[i].channelNumber);
2469 continue;
2470 }
Agrawal Ashish65634612016-08-18 13:24:32 +05302471 if ((sap_ctx->dfs_mode == ACS_DFS_MODE_DISABLE) &&
2472 (CHANNEL_STATE_DFS == ch_type))
2473 continue;
Kondabattini, Ganesh13bb4b12016-09-04 16:16:53 +05302474
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002475 if (safe_channels[i].isSafe == true) {
2476 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2477 FL("channel %d in the configuration is safe"),
2478 safe_channels[i].channelNumber);
2479 first_safe_ch_in_range = safe_channels[i].channelNumber;
2480 break;
2481 }
2482
2483 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2484 FL("channel %d in the configuration is unsafe"),
2485 safe_channels[i].channelNumber);
2486 }
2487
2488 /* if no channel selected return SAP_CHANNEL_NOT_SELECTED */
2489 return first_safe_ch_in_range;
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002490}
Dustin Brown0ce56d32016-10-17 16:18:03 -07002491#else
2492static uint8_t sap_select_channel_no_scan_result(tHalHandle hal,
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -07002493 struct sap_context *sap_ctx)
Dustin Brown0ce56d32016-10-17 16:18:03 -07002494{
2495 uint32_t start_ch_num = sap_ctx->acs_cfg->start_ch;
2496
2497 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2498 FL("start - end: %d - %d"),
2499 start_ch_num,
2500 sap_ctx->acs_cfg->end_ch);
2501
2502 sap_ctx->acs_cfg->pri_ch = start_ch_num;
2503 sap_ctx->acs_cfg->ht_sec_ch = 0;
2504
2505 /* pick the first channel in configured range */
2506 return start_ch_num;
2507}
2508#endif /* FEATURE_WLAN_CH_AVOID */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002509
2510/**
2511 * sap_select_channel() - select SAP channel
2512 * @hal: Pointer to HAL handle
2513 * @sap_ctx: Sap context
2514 * @scan_result: Pointer to tScanResultHandle
2515 *
2516 * Runs a algorithm to select the best channel to operate in based on BSS
2517 * rssi and bss count on each channel
2518 *
2519 * Returns: channel number if success, 0 otherwise
2520 */
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -07002521uint8_t sap_select_channel(tHalHandle hal, struct sap_context *sap_ctx,
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002522 tScanResultHandle scan_result)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002523{
2524 /* DFS param object holding all the data req by the algo */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002525 tSapChSelSpectInfo spect_info_obj = { NULL, 0 };
2526 tSapChSelSpectInfo *spect_info = &spect_info_obj;
2527 uint8_t best_ch_num = SAP_CHANNEL_NOT_SELECTED;
bingse2782382017-03-23 10:34:52 +08002528 uint32_t ht40plus2gendch = 0;
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002529 v_REGDOMAIN_t domain;
Arif Hussain21ad4342017-12-21 12:00:54 -08002530 uint8_t country[CDS_COUNTRY_CODE_LEN + 1];
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002531#ifdef SOFTAP_CHANNEL_RANGE
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002532 uint8_t count;
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002533 uint32_t start_ch_num, end_ch_num, tmp_ch_num, operating_band = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002534#endif
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002535 tpAniSirGlobal mac_ctx;
2536
2537 mac_ctx = PMAC_STRUCT(hal);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302538 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002539 "In %s, Running SAP Ch Select", __func__);
2540
2541#ifdef FEATURE_WLAN_CH_AVOID
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002542 sap_update_unsafe_channel_list(hal, sap_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002543#endif
2544
gaoleze5108942017-03-31 16:56:42 +08002545 /*
2546 * If ACS weight is not enabled on noise_floor/channel_free/tx_power,
2547 * then skip acs process if no bss found.
2548 */
2549 if (NULL == scan_result &&
2550 !(sap_ctx->auto_channel_select_weight & 0xffff00)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302551 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002552 FL("No external AP present"));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002553
2554#ifndef SOFTAP_CHANNEL_RANGE
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002555 return SAP_CHANNEL_NOT_SELECTED;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002556#else
Kondabattini, Ganesh13bb4b12016-09-04 16:16:53 +05302557 return sap_select_channel_no_scan_result(hal, sap_ctx);
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002558#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002559 }
2560
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002561 /* Initialize the structure pointed by spect_info */
Srinivas Girigowda74a66d62017-06-21 23:28:25 -07002562 if (sap_chan_sel_init(hal, spect_info, sap_ctx) != true) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302563 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002564 FL("Ch Select initialization failed"));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002565 return SAP_CHANNEL_NOT_SELECTED;
2566 }
2567 /* Compute the weight of the entire spectrum in the operating band */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002568 sap_compute_spect_weight(spect_info, hal, scan_result, sap_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002569
2570#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
2571 /* process avoid channel IE to collect all channels to avoid */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002572 sap_process_avoid_ie(hal, sap_ctx, scan_result, spect_info);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002573#endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
2574
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002575 wlan_reg_read_default_country(mac_ctx->psoc, country);
2576 wlan_reg_get_domain_from_country_code(&domain, country, SOURCE_DRIVER);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002577#ifdef SOFTAP_CHANNEL_RANGE
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002578 start_ch_num = sap_ctx->acs_cfg->start_ch;
2579 end_ch_num = sap_ctx->acs_cfg->end_ch;
2580 SET_ACS_BAND(operating_band, sap_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002581
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002582 sap_ctx->acsBestChannelInfo.channelNum = 0;
2583 sap_ctx->acsBestChannelInfo.weight = SAP_ACS_WEIGHT_MAX;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002584
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002585 /* Sort the ch lst as per the computed weights, lesser weight first. */
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002586 sap_sort_chl_weight_all(sap_ctx, spect_info, operating_band, domain);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002587
2588 /*Loop till get the best channel in the given range */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002589 for (count = 0; count < spect_info->numSpectChans; count++) {
2590 if ((start_ch_num > spect_info->pSpectCh[count].chNum) ||
2591 (end_ch_num < spect_info->pSpectCh[count].chNum))
2592 continue;
2593
2594 if (best_ch_num == SAP_CHANNEL_NOT_SELECTED) {
2595 best_ch_num = spect_info->pSpectCh[count].chNum;
2596 /* check if best_ch_num is in preferred channel list */
2597 best_ch_num =
2598 sap_select_preferred_channel_from_channel_list(
2599 best_ch_num, sap_ctx, spect_info);
2600 /* if not in preferred ch lst, go to nxt best ch */
2601 if (best_ch_num == SAP_CHANNEL_NOT_SELECTED)
2602 continue;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002603
2604#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002605 /*
2606 * Weight of the channels(device's AP is operating)
2607 * increased to MAX+1 so that they will be choosen only
2608 * when there is no other best channel to choose
2609 */
2610 if (sap_check_in_avoid_ch_list(sap_ctx, best_ch_num)) {
2611 best_ch_num = SAP_CHANNEL_NOT_SELECTED;
2612 continue;
2613 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002614#endif
2615
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002616 sap_ctx->acsBestChannelInfo.channelNum = best_ch_num;
2617 sap_ctx->acsBestChannelInfo.weight =
2618 spect_info->pSpectCh[count].weight_copy;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002619 }
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002620
2621 if (best_ch_num == SAP_CHANNEL_NOT_SELECTED)
2622 continue;
2623
Tushnim Bhattacharyya03103fd2017-06-23 10:48:52 -07002624 if (operating_band != eCSR_DOT11_MODE_11g) {
2625 QDF_TRACE(QDF_MODULE_ID_SAP,
2626 QDF_TRACE_LEVEL_INFO_HIGH,
2627 "operating_band %d", operating_band);
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002628 continue;
Tushnim Bhattacharyya03103fd2017-06-23 10:48:52 -07002629 }
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002630
2631 /* Give preference to Non-overlap channels */
Naveen Rawatbec64d92017-09-13 14:35:21 -07002632 if (false == sap_is_ch_non_overlap(sap_ctx,
Tushnim Bhattacharyya03103fd2017-06-23 10:48:52 -07002633 spect_info->pSpectCh[count].chNum)) {
2634 QDF_TRACE(QDF_MODULE_ID_SAP,
2635 QDF_TRACE_LEVEL_INFO_HIGH,
Naveen Rawatbec64d92017-09-13 14:35:21 -07002636 FL("ch: %d skipped as its overlapping ch"),
2637 spect_info->pSpectCh[count].chNum);
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002638 continue;
Tushnim Bhattacharyya03103fd2017-06-23 10:48:52 -07002639 }
2640
2641 if (wlan_reg_is_dfs_ch(mac_ctx->pdev,
2642 spect_info->pSpectCh[count].chNum) &&
2643 policy_mgr_disallow_mcc(mac_ctx->psoc,
2644 spect_info->pSpectCh[count].chNum)) {
2645 QDF_TRACE(QDF_MODULE_ID_SAP,
2646 QDF_TRACE_LEVEL_INFO_HIGH,
2647 "No DFS MCC");
2648 continue;
2649 }
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002650
bings14d1d3b2017-08-03 11:14:29 +08002651 if (spect_info->pSpectCh[count].weight_copy >
2652 sap_ctx->acsBestChannelInfo.weight)
2653 continue;
2654
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002655 tmp_ch_num = spect_info->pSpectCh[count].chNum;
gaoleze5108942017-03-31 16:56:42 +08002656 tmp_ch_num = sap_channel_in_acs_channel_list(
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002657 tmp_ch_num, sap_ctx, spect_info);
2658 if (tmp_ch_num == SAP_CHANNEL_NOT_SELECTED)
2659 continue;
2660
2661 best_ch_num = tmp_ch_num;
2662 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002663 }
2664#else
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002665 /* Sort the ch lst as per the computed weights, lesser weight first. */
2666 sap_sort_chl_weight_all(sap_ctx, hal, spect_info);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002667 /* Get the first channel in sorted array as best 20M Channel */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002668 best_ch_num = (uint8_t) spect_info->pSpectCh[0].chNum;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002669 /* Select Best Channel from Channel List if Configured */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002670 best_ch_num = sap_select_preferred_channel_from_channel_list(
2671 best_ch_num, sap_ctx, spect_info);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002672#endif
2673
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002674 /*
2675 * in case the best channel seleted is not in PCL and there is another
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002676 * channel which has same weightage and is in PCL, choose the one in
2677 * PCL
2678 */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002679 for (count = 0; count < spect_info->numSpectChans; count++) {
2680 if (!ch_in_pcl(sap_ctx, spect_info->pSpectCh[count].chNum) ||
2681 (spect_info->pSpectCh[count].weight !=
2682 sap_ctx->acsBestChannelInfo.weight))
2683 continue;
2684
2685 if (sap_select_preferred_channel_from_channel_list(
2686 spect_info->pSpectCh[count].chNum, sap_ctx, spect_info)
2687 == SAP_CHANNEL_NOT_SELECTED)
2688 continue;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002689
2690#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002691 if (sap_check_in_avoid_ch_list(sap_ctx, best_ch_num))
2692 continue;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002693#endif
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002694 best_ch_num = spect_info->pSpectCh[count].chNum;
2695 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2696 FL("change best channel to %d in PCL"), best_ch_num);
2697 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002698 }
2699
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002700 sap_ctx->acs_cfg->pri_ch = best_ch_num;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002701 /* determine secondary channel for 2.4G channel 5, 6, 7 in HT40 */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002702 if ((operating_band != eCSR_DOT11_MODE_11g) ||
2703 (sap_ctx->acs_cfg->ch_width != CH_WIDTH_40MHZ))
2704 goto sap_ch_sel_end;
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002705 if (REGDOMAIN_FCC == domain)
bingse2782382017-03-23 10:34:52 +08002706 ht40plus2gendch = HT40PLUS_2G_FCC_CH_END;
2707 else
2708 ht40plus2gendch = HT40PLUS_2G_EURJAP_CH_END;
2709 if ((best_ch_num >= HT40MINUS_2G_CH_START) &&
2710 (best_ch_num <= ht40plus2gendch)) {
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002711 int weight_below, weight_above, i;
2712 tSapSpectChInfo *pspect_info;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002713
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002714 weight_below = weight_above = SAP_ACS_WEIGHT_MAX;
2715 pspect_info = spect_info->pSpectCh;
2716 for (i = 0; i < spect_info->numSpectChans; i++) {
2717 if (pspect_info[i].chNum == (best_ch_num - 4))
2718 weight_below = pspect_info[i].weight;
2719 if (pspect_info[i].chNum == (best_ch_num + 4))
2720 weight_above = pspect_info[i].weight;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002721 }
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002722
2723 if (weight_below < weight_above)
2724 sap_ctx->acs_cfg->ht_sec_ch =
2725 sap_ctx->acs_cfg->pri_ch - 4;
2726 else
2727 sap_ctx->acs_cfg->ht_sec_ch =
2728 sap_ctx->acs_cfg->pri_ch + 4;
2729 } else if (best_ch_num >= 1 && best_ch_num <= 4) {
2730 sap_ctx->acs_cfg->ht_sec_ch = sap_ctx->acs_cfg->pri_ch + 4;
bingse2782382017-03-23 10:34:52 +08002731 } else if (best_ch_num >= ht40plus2gendch && best_ch_num <=
2732 HT40MINUS_2G_CH_END) {
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002733 sap_ctx->acs_cfg->ht_sec_ch = sap_ctx->acs_cfg->pri_ch - 4;
2734 } else if (best_ch_num == 14) {
2735 sap_ctx->acs_cfg->ht_sec_ch = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002736 }
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002737 sap_ctx->secondary_ch = sap_ctx->acs_cfg->ht_sec_ch;
2738
2739sap_ch_sel_end:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002740 /* Free all the allocated memory */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002741 sap_chan_sel_exit(spect_info);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002742
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302743 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002744 FL("Running SAP Ch select Completed, Ch=%d"), best_ch_num);
2745 if (best_ch_num > 0 && best_ch_num <= 252)
2746 return best_ch_num;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002747 else
2748 return SAP_CHANNEL_NOT_SELECTED;
2749}