blob: 1792ff79069ee85e38527dceecacc3f838388138 [file] [log] [blame]
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001/*
Ryan Hsu4252a2f2016-01-05 11:18:24 -08002 * Copyright (c) 2012-2016 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 */
56
Yuanyuan Liu0e0aa932016-05-12 10:17:58 -070057#include "pld_common.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080058
59/*--------------------------------------------------------------------------
60 Function definitions
61 --------------------------------------------------------------------------*/
62
63/*--------------------------------------------------------------------------
64 Defines
65 --------------------------------------------------------------------------*/
66#define SAP_DEBUG
67
68#define IS_RSSI_VALID(extRssi, rssi) \
69 ( \
70 ((extRssi < rssi) ? true : false) \
71 )
72
73#define SET_ACS_BAND(acs_band, pSapCtx) \
74{ \
75 if (pSapCtx->acs_cfg->start_ch <= 14 && \
76 pSapCtx->acs_cfg->end_ch <= 14) \
77 acs_band = eCSR_DOT11_MODE_11g; \
78 else if (pSapCtx->acs_cfg->start_ch >= 14)\
79 acs_band = eCSR_DOT11_MODE_11a; \
80 else \
81 acs_band = eCSR_DOT11_MODE_abg; \
82}
83
84#ifdef FEATURE_WLAN_CH_AVOID
Amar Singhalb8d4f152016-02-10 10:21:43 -080085sapSafeChannelType safe_channels[NUM_CHANNELS] = {
86 {1, true},
87 {2, true},
88 {3, true},
89 {4, true},
90 {5, true},
91 {6, true},
92 {7, true},
93 {8, true},
94 {9, true},
95 {10, true},
96 {11, true},
97 {12, true},
98 {13, true},
99 {14, true},
100 {36, true},
101 {40, true},
102 {44, true},
103 {48, true},
104 {52, true},
105 {56, true},
106 {60, true},
107 {64, true},
108 {100, true},
109 {104, true},
110 {108, true},
111 {112, true},
112 {116, true},
113 {120, true},
114 {124, true},
115 {128, true},
116 {132, true},
117 {136, true},
118 {140, true},
119 {144, true},
120 {149, true},
121 {153, true},
122 {157, true},
123 {161, true},
124 {165, true},
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800125};
126#endif
127
128typedef struct {
129 uint16_t chStartNum;
130 uint32_t weight;
131} sapAcsChannelInfo;
132
133sapAcsChannelInfo acs_ht40_channels5_g[] = {
134 {36, SAP_ACS_WEIGHT_MAX},
135 {44, SAP_ACS_WEIGHT_MAX},
136 {52, SAP_ACS_WEIGHT_MAX},
137 {60, SAP_ACS_WEIGHT_MAX},
138 {100, SAP_ACS_WEIGHT_MAX},
139 {108, SAP_ACS_WEIGHT_MAX},
140 {116, SAP_ACS_WEIGHT_MAX},
141 {124, SAP_ACS_WEIGHT_MAX},
142 {132, SAP_ACS_WEIGHT_MAX},
143 {140, SAP_ACS_WEIGHT_MAX},
144 {149, SAP_ACS_WEIGHT_MAX},
145 {157, SAP_ACS_WEIGHT_MAX},
146};
147
148sapAcsChannelInfo acs_ht80_channels[] = {
149 {36, SAP_ACS_WEIGHT_MAX},
150 {52, SAP_ACS_WEIGHT_MAX},
151 {100, SAP_ACS_WEIGHT_MAX},
152 {116, SAP_ACS_WEIGHT_MAX},
153 {132, SAP_ACS_WEIGHT_MAX},
154 {149, SAP_ACS_WEIGHT_MAX},
155};
156
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -0700157sapAcsChannelInfo acs_vht160_channels[] = {
158 {36, SAP_ACS_WEIGHT_MAX},
159 {100, SAP_ACS_WEIGHT_MAX},
160};
161
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800162sapAcsChannelInfo acs_ht40_channels24_g[] = {
163 {1, SAP_ACS_WEIGHT_MAX},
164 {2, SAP_ACS_WEIGHT_MAX},
165 {3, SAP_ACS_WEIGHT_MAX},
166 {4, SAP_ACS_WEIGHT_MAX},
167 {9, SAP_ACS_WEIGHT_MAX},
168};
169
170#define CHANNEL_165 165
171
172/* rssi discount for channels in PCL */
173#define PCL_RSSI_DISCOUNT 10
174
175#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
176/**
177 * sap_check_n_add_channel() - checks and add given channel in sap context's
178 * avoid_channels_info struct
179 * @sap_ctx: sap context.
180 * @new_channel: channel to be added to sap_ctx's avoid ch info
181 *
182 * sap_ctx contains sap_avoid_ch_info strcut containing the list of channels on
183 * which MDM device's AP with MCC was detected. This function will add channels
184 * to that list after checking for duplicates.
185 *
186 * Return: true: if channel was added or already present
187 * else false: if channel list was already full.
188 */
189bool
190sap_check_n_add_channel(ptSapContext sap_ctx,
191 uint8_t new_channel)
192{
193 uint8_t i = 0;
194 struct sap_avoid_channels_info *ie_info =
195 &sap_ctx->sap_detected_avoid_ch_ie;
196
197 for (i = 0; i < sizeof(ie_info->channels); i++) {
198 if (ie_info->channels[i] == new_channel)
199 break;
200
201 if (ie_info->channels[i] == 0) {
202 ie_info->channels[i] = new_channel;
203 break;
204 }
205 }
206 if (i == sizeof(ie_info->channels))
207 return false;
208 else
209 return true;
210}
211/**
212 * sap_check_n_add_overlapped_chnls() - checks & add overlapped channels
213 * to primary channel in 2.4Ghz band.
214 * @sap_ctx: sap context.
215 * @primary_chnl: primary channel to be avoided.
216 *
217 * sap_ctx contains sap_avoid_ch_info struct containing the list of channels on
218 * which MDM device's AP with MCC was detected. This function will add channels
219 * to that list after checking for duplicates.
220 *
221 * Return: true: if channel was added or already present
222 * else false: if channel list was already full.
223 */
224static bool
225sap_check_n_add_overlapped_chnls(ptSapContext sap_ctx, uint8_t primary_channel)
226{
227 uint8_t i = 0, j = 0, upper_chnl = 0, lower_chnl = 0;
228 struct sap_avoid_channels_info *ie_info =
229 &sap_ctx->sap_detected_avoid_ch_ie;
230 /*
231 * if primary channel less than channel 1 or out of 2g band then
232 * no further process is required. return true in this case.
233 */
234 if (primary_channel < CHANNEL_1 || primary_channel > CHANNEL_14)
235 return true;
236
237 /* lower channel is one channel right before primary channel */
238 lower_chnl = primary_channel - 1;
239 /* upper channel is one channel right after primary channel */
240 upper_chnl = primary_channel + 1;
241
242 /* lower channel needs to be non-zero, zero is not valid channel */
243 if (lower_chnl > (CHANNEL_1 - 1)) {
244 for (i = 0; i < sizeof(ie_info->channels); i++) {
245 if (ie_info->channels[i] == lower_chnl)
246 break;
247 if (ie_info->channels[i] == 0) {
248 ie_info->channels[i] = lower_chnl;
249 break;
250 }
251 }
252 }
253 /* upper channel needs to be atleast last channel in 2.4Ghz band */
254 if (upper_chnl < (CHANNEL_14 + 1)) {
255 for (j = 0; j < sizeof(ie_info->channels); j++) {
256 if (ie_info->channels[j] == upper_chnl)
257 break;
258 if (ie_info->channels[j] == 0) {
259 ie_info->channels[j] = upper_chnl;
260 break;
261 }
262 }
263 }
264 if (i == sizeof(ie_info->channels) || j == sizeof(ie_info->channels))
265 return false;
266 else
267 return true;
268}
269
270/**
271 * sap_process_avoid_ie() - processes the detected Q2Q IE
272 * context's avoid_channels_info struct
273 * @hal: hal handle
274 * @sap_ctx: sap context.
275 * @scan_result: scan results for ACS scan.
276 * @spect_info: spectrum weights array to update
277 *
278 * Detection of Q2Q IE indicates presence of another MDM device with its AP
279 * operating in MCC mode. This function parses the scan results and processes
280 * the Q2Q IE if found. It then extracts the channels and populates them in
281 * sap_ctx struct. It also increases the weights of those channels so that
282 * ACS logic will avoid those channels in its selection algorithm.
283 *
284 * Return: void
285 */
286void sap_process_avoid_ie(tHalHandle hal,
287 ptSapContext sap_ctx,
288 tScanResultHandle scan_result,
289 tSapChSelSpectInfo *spect_info)
290{
291 uint32_t total_ie_len = 0;
292 uint8_t *temp_ptr = NULL;
293 uint8_t i = 0;
294 struct sAvoidChannelIE *avoid_ch_ie;
295 tCsrScanResultInfo *node = NULL;
296 tpAniSirGlobal mac_ctx = NULL;
297 tSapSpectChInfo *spect_ch = NULL;
298
299 mac_ctx = PMAC_STRUCT(hal);
300 spect_ch = spect_info->pSpectCh;
301 node = sme_scan_result_get_first(hal, scan_result);
302
303 while (node) {
304 total_ie_len = (node->BssDescriptor.length +
305 sizeof(uint16_t) + sizeof(uint32_t) -
306 sizeof(tSirBssDescription));
307 temp_ptr = cfg_get_vendor_ie_ptr_from_oui(mac_ctx,
308 SIR_MAC_QCOM_VENDOR_OUI,
309 SIR_MAC_QCOM_VENDOR_SIZE,
310 ((uint8_t *)&node->BssDescriptor.ieFields),
311 total_ie_len);
312
313 if (temp_ptr) {
314 avoid_ch_ie = (struct sAvoidChannelIE *)temp_ptr;
315 if (avoid_ch_ie->type != QCOM_VENDOR_IE_MCC_AVOID_CH)
316 continue;
317
318 sap_ctx->sap_detected_avoid_ch_ie.present = 1;
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530319 QDF_TRACE(QDF_MODULE_ID_SAP,
320 QDF_TRACE_LEVEL_DEBUG,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800321 "Q2Q IE - avoid ch %d",
322 avoid_ch_ie->channel);
323 /* add this channel to to_avoid channel list */
324 sap_check_n_add_channel(sap_ctx,
325 avoid_ch_ie->channel);
326 sap_check_n_add_overlapped_chnls(sap_ctx,
327 avoid_ch_ie->channel);
328 /*
329 * Mark weight of these channel present in IE to MAX
330 * so that ACS logic will to avoid thse channels
331 */
332 for (i = 0; i < spect_info->numSpectChans; i++)
333 if (spect_ch[i].chNum == avoid_ch_ie->channel) {
334 /*
335 * weight is set more than max so that,
336 * in the case of other channels being
337 * assigned max weight due to noise,
338 * they may be preferred over channels
339 * with Q2Q IE.
340 */
341 spect_ch[i].weight = SAP_ACS_WEIGHT_MAX + 1;
342 spect_ch[i].weight_copy =
343 SAP_ACS_WEIGHT_MAX + 1;
344 break;
345 }
346 } /* if (temp_ptr) */
347 node = sme_scan_result_get_next(hal, scan_result);
348 }
349}
350#endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
351
352#ifdef FEATURE_WLAN_CH_AVOID
353/*==========================================================================
354 FUNCTION sap_update_unsafe_channel_list
355
356 DESCRIPTION
357 Function Undate unsafe channel list table
358
359 DEPENDENCIES
360 NA.
361
362 IN
363 SapContext pointer
364
365 RETURN VALUE
366 NULL
367 ============================================================================*/
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800368void sap_update_unsafe_channel_list(ptSapContext pSapCtx)
369{
370 uint16_t i, j;
Amar Singhalb8d4f152016-02-10 10:21:43 -0800371 uint16_t unsafe_channel_list[NUM_CHANNELS];
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800372 uint16_t unsafe_channel_count = 0;
Yuanyuan Liu0e0aa932016-05-12 10:17:58 -0700373 qdf_device_t qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800374
375 /* Flush, default set all channel safe */
Amar Singhalb8d4f152016-02-10 10:21:43 -0800376 for (i = 0; i < NUM_CHANNELS; i++) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800377 safe_channels[i].isSafe = true;
378 }
379
380 /* Try to find unsafe channel */
Ryan Hsu4252a2f2016-01-05 11:18:24 -0800381#if defined(FEATURE_WLAN_STA_AP_MODE_DFS_DISABLE)
Amar Singhalb8d4f152016-02-10 10:21:43 -0800382 for (i = 0; i < NUM_CHANNELS; i++) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800383 if (pSapCtx->dfs_ch_disable == true) {
384 if (CDS_IS_DFS_CH(safe_channels[i].channelNumber)) {
385 safe_channels[i].isSafe = false;
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530386 QDF_TRACE(QDF_MODULE_ID_SAP,
387 QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800388 "%s: DFS Ch %d is not safe in"
389 " Concurrent mode",
390 __func__,
391 safe_channels[i].channelNumber);
392 }
393 }
394 }
395#endif
Yuanyuan Liu0e0aa932016-05-12 10:17:58 -0700396 pld_get_wlan_unsafe_channel(qdf_ctx->dev,
397 unsafe_channel_list,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800398 &unsafe_channel_count,
399 sizeof(unsafe_channel_list));
400
401 for (i = 0; i < unsafe_channel_count; i++) {
Amar Singhalb8d4f152016-02-10 10:21:43 -0800402 for (j = 0; j < NUM_CHANNELS; j++) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800403 if (safe_channels[j].channelNumber ==
404 unsafe_channel_list[i]) {
405 /* Found unsafe channel, update it */
406 safe_channels[j].isSafe = false;
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530407 QDF_TRACE(QDF_MODULE_ID_SAP,
408 QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800409 FL("CH %d is not safe"),
410 unsafe_channel_list[i]);
411 break;
412 }
413 }
414 }
415
416 return;
417}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800418
419#endif /* FEATURE_WLAN_CH_AVOID */
420
421/*==========================================================================
422 FUNCTION sap_cleanup_channel_list
423
424 DESCRIPTION
425 Function sap_cleanup_channel_list frees up the memory allocated to the channel list.
426
427 DEPENDENCIES
428 NA.
429
430 PARAMETERS
431
432 IN
433 NULL
434
435 RETURN VALUE
436 NULL
437 ============================================================================*/
438
Ryan Hsu4252a2f2016-01-05 11:18:24 -0800439void sap_cleanup_channel_list(void *p_cds_gctx)
440{
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800441 ptSapContext pSapCtx;
442
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530443 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800444 "Cleaning up the channel list structure");
445
446 if (NULL == p_cds_gctx) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530447 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800448 "SAP Global Context is NULL");
449 return;
450 }
451
452 pSapCtx = CDS_GET_SAP_CB(p_cds_gctx);
453 if (NULL == pSapCtx) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530454 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800455 "SAP Context is NULL");
456 return;
457 }
458
459 pSapCtx->SapChnlList.numChannel = 0;
460 if (pSapCtx->SapChnlList.channelList) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530461 qdf_mem_free(pSapCtx->SapChnlList.channelList);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800462 pSapCtx->SapChnlList.channelList = NULL;
463 }
464
465 pSapCtx->SapAllChnlList.numChannel = 0;
466 if (pSapCtx->SapAllChnlList.channelList) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530467 qdf_mem_free(pSapCtx->SapAllChnlList.channelList);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800468 pSapCtx->SapAllChnlList.channelList = NULL;
469 }
470}
471
472/**
473 * sap_select_preferred_channel_from_channel_list() - to calc best cahnnel
474 * @best_chnl: best channel already calculated among all the chanels
475 * @sap_ctx: sap context
476 * @spectinfo_param: Pointer to tSapChSelSpectInfo structure
477 *
478 * This function calculates the best channel among the configured channel list.
479 * If channel list not configured then returns the best channel calculated
480 * among all the channel list.
481 *
482 * Return: uint8_t best channel
483 */
484uint8_t sap_select_preferred_channel_from_channel_list(uint8_t best_chnl,
485 ptSapContext sap_ctx,
486 tSapChSelSpectInfo *spectinfo_param)
487{
488 uint8_t i = 0;
489
490 /*
491 * If Channel List is not Configured don't do anything
492 * Else return the Best Channel from the Channel List
493 */
494 if ((NULL == sap_ctx->acs_cfg->ch_list) ||
495 (NULL == spectinfo_param) ||
496 (0 == sap_ctx->acs_cfg->ch_list_count))
497 return best_chnl;
498
499 if (best_chnl <= 0 || best_chnl > 252)
500 return SAP_CHANNEL_NOT_SELECTED;
501
502 /* Select the best channel from allowed list */
503 for (i = 0; i < sap_ctx->acs_cfg->ch_list_count; i++) {
504 if (sap_ctx->acs_cfg->ch_list[i] == best_chnl) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530505 QDF_TRACE(QDF_MODULE_ID_SAP,
506 QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800507 "Best channel is: %d",
508 best_chnl);
509 return best_chnl;
510 }
511 }
512
513 return SAP_CHANNEL_NOT_SELECTED;
514}
515
516/*==========================================================================
517 FUNCTION sap_chan_sel_init
518
519 DESCRIPTION
520 Function sap_chan_sel_init allocates the memory, intializes the
Anurag Chouhan6d760662016-02-20 16:05:43 +0530521 structures used by the channel selection algorithm
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800522
523 DEPENDENCIES
524 NA.
525
526 PARAMETERS
527
528 IN
529 halHandle : Pointer to tHalHandle
530 *pSpectInfoParams : Pointer to tSapChSelSpectInfo structure
531 pSapCtx : Pointer to SAP Context
532
533 RETURN VALUE
534 bool: Success or FAIL
535
536 SIDE EFFECTS
537 ============================================================================*/
538bool sap_chan_sel_init(tHalHandle halHandle,
539 tSapChSelSpectInfo *pSpectInfoParams, ptSapContext pSapCtx)
540{
541 tSapSpectChInfo *pSpectCh = NULL;
542 uint8_t *pChans = NULL;
543 uint16_t channelnum = 0;
544 tpAniSirGlobal pMac = PMAC_STRUCT(halHandle);
545 bool chSafe = true;
546#ifdef FEATURE_WLAN_CH_AVOID
547 uint16_t i;
548#endif
549 uint32_t dfs_master_cap_enabled;
550 bool include_dfs_ch = true;
551
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530552 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, "In %s",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800553 __func__);
554
555 pSpectInfoParams->numSpectChans =
556 pMac->scan.base_channels.numChannels;
557
558 /* Allocate memory for weight computation of 2.4GHz */
559 pSpectCh =
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530560 (tSapSpectChInfo *) qdf_mem_malloc((pSpectInfoParams->numSpectChans)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800561 * sizeof(*pSpectCh));
562
563 if (pSpectCh == NULL) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530564 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
Anurag Chouhanf04e84f2016-03-03 10:12:12 +0530565 "In %s, QDF_MALLOC_ERR", __func__);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800566 return eSAP_FALSE;
567 }
568
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530569 qdf_mem_zero(pSpectCh,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800570 (pSpectInfoParams->numSpectChans) * sizeof(*pSpectCh));
571
572 /* Initialize the pointers in the DfsParams to the allocated memory */
573 pSpectInfoParams->pSpectCh = pSpectCh;
574
575 pChans = pMac->scan.base_channels.channelList;
576
Ryan Hsu4252a2f2016-01-05 11:18:24 -0800577#if defined(FEATURE_WLAN_STA_AP_MODE_DFS_DISABLE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800578 if (pSapCtx->dfs_ch_disable == true)
579 include_dfs_ch = false;
580#endif
581 sme_cfg_get_int(halHandle, WNI_CFG_DFS_MASTER_ENABLED,
582 &dfs_master_cap_enabled);
583 if (dfs_master_cap_enabled == 0)
584 include_dfs_ch = false;
585
586 /* Fill the channel number in the spectrum in the operating freq band */
587 for (channelnum = 0;
588 channelnum < pSpectInfoParams->numSpectChans;
Edhar, Mahesh Kumar4f660672015-10-30 11:53:26 +0530589 channelnum++, pChans++, pSpectCh++) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800590 chSafe = true;
591
592 /* check if the channel is in NOL blacklist */
593 if (sap_dfs_is_channel_in_nol_list(pSapCtx, *pChans,
594 PHY_SINGLE_CHANNEL_CENTERED)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530595 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800596 "In %s, Ch %d is in NOL list", __func__,
597 *pChans);
598 chSafe = false;
599 continue;
600 }
601
602 if (include_dfs_ch == false) {
603 if (CDS_IS_DFS_CH(*pChans)) {
604 chSafe = false;
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530605 QDF_TRACE(QDF_MODULE_ID_SAP,
606 QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800607 "In %s, DFS Ch %d not considered for ACS",
608 __func__, *pChans);
609 continue;
610 }
611 }
612
613#ifdef FEATURE_WLAN_CH_AVOID
Amar Singhalb8d4f152016-02-10 10:21:43 -0800614 for (i = 0; i < NUM_CHANNELS; i++) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800615 if ((safe_channels[i].channelNumber == *pChans) &&
616 (false == safe_channels[i].isSafe)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530617 QDF_TRACE(QDF_MODULE_ID_SAP,
618 QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800619 "In %s, Ch %d is not safe", __func__,
620 *pChans);
621 chSafe = false;
622 break;
623 }
624 }
625#endif /* FEATURE_WLAN_CH_AVOID */
626
627 /* OFDM rates are not supported on channel 14 */
628 if (*pChans == 14 &&
629 eCSR_DOT11_MODE_11b != pSapCtx->csr_roamProfile.phyMode) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800630 continue;
631 }
632
633 if (true == chSafe) {
634 pSpectCh->chNum = *pChans;
635 pSpectCh->valid = eSAP_TRUE;
636 pSpectCh->rssiAgr = SOFTAP_MIN_RSSI; /* Initialise for all channels */
637 pSpectCh->channelWidth = SOFTAP_HT20_CHANNELWIDTH; /* Initialise 20MHz for all the Channels */
638 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800639 }
640 return eSAP_TRUE;
641}
642
643/*==========================================================================
644 FUNCTION sapweight_rssi_count
645
646 DESCRIPTION
647 Function weightRssiCount calculates the channel weight due to rssi
Anurag Chouhan6d760662016-02-20 16:05:43 +0530648 and data count(here number of BSS observed)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800649
650 DEPENDENCIES
651 NA.
652
653 PARAMETERS
654
655 IN
656 rssi : Max signal strength receieved from a BSS for the channel
657 count : Number of BSS observed in the channel
658
659 RETURN VALUE
660 uint32_t : Calculated channel weight based on above two
661
662 SIDE EFFECTS
663 ============================================================================*/
664uint32_t sapweight_rssi_count(int8_t rssi, uint16_t count)
665{
666 int32_t rssiWeight = 0;
667 int32_t countWeight = 0;
668 uint32_t rssicountWeight = 0;
669
670 /* Weight from RSSI */
671 rssiWeight = SOFTAP_RSSI_WEIGHT * (rssi - SOFTAP_MIN_RSSI)
672 / (SOFTAP_MAX_RSSI - SOFTAP_MIN_RSSI);
673
674 if (rssiWeight > SOFTAP_RSSI_WEIGHT)
675 rssiWeight = SOFTAP_RSSI_WEIGHT;
676 else if (rssiWeight < 0)
677 rssiWeight = 0;
678
679 /* Weight from data count */
680 countWeight = SOFTAP_COUNT_WEIGHT * (count - SOFTAP_MIN_COUNT)
681 / (SOFTAP_MAX_COUNT - SOFTAP_MIN_COUNT);
682
683 if (countWeight > SOFTAP_COUNT_WEIGHT)
684 countWeight = SOFTAP_COUNT_WEIGHT;
685
686 rssicountWeight = rssiWeight + countWeight;
687
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530688 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800689 "In %s, rssiWeight=%d, countWeight=%d, rssicountWeight=%d",
690 __func__, rssiWeight, countWeight, rssicountWeight);
691
692 return rssicountWeight;
693}
694
695/**
696 * sap_update_rssi_bsscount() - updates bss count and rssi effect.
697 *
698 * @pSpectCh: Channel Information
699 * @offset: Channel Offset
700 * @sap_24g: Channel is in 2.4G or 5G
701 *
702 * sap_update_rssi_bsscount updates bss count and rssi effect based
703 * on the channel offset.
704 *
705 * Return: None.
706 */
707
708void sap_update_rssi_bsscount(tSapSpectChInfo *pSpectCh, int32_t offset,
709 bool sap_24g)
710{
711 tSapSpectChInfo *pExtSpectCh = NULL;
712 int32_t rssi, rsssi_effect;
713
714 pExtSpectCh = (pSpectCh + offset);
715 if (pExtSpectCh != NULL) {
716 ++pExtSpectCh->bssCount;
717 switch (offset) {
718 case -1:
719 case 1:
720 rsssi_effect = sap_24g ?
721 SAP_24GHZ_FIRST_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY :
722 SAP_SUBBAND1_RSSI_EFFECT_PRIMARY;
723 break;
724 case -2:
725 case 2:
726 rsssi_effect = sap_24g ?
727 SAP_24GHZ_SEC_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY :
728 SAP_SUBBAND2_RSSI_EFFECT_PRIMARY;
729 break;
730 case -3:
731 case 3:
732 rsssi_effect = sap_24g ?
733 SAP_24GHZ_THIRD_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY :
734 SAP_SUBBAND3_RSSI_EFFECT_PRIMARY;
735 break;
736 case -4:
737 case 4:
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -0700738 rsssi_effect = sap_24g ?
739 SAP_24GHZ_FOURTH_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY :
740 SAP_SUBBAND4_RSSI_EFFECT_PRIMARY;
741 break;
742 case -5:
743 case 5:
744 rsssi_effect = SAP_SUBBAND5_RSSI_EFFECT_PRIMARY;
745 break;
746 case -6:
747 case 6:
748 rsssi_effect = SAP_SUBBAND6_RSSI_EFFECT_PRIMARY;
749 break;
750 case -7:
751 case 7:
752 rsssi_effect = SAP_SUBBAND7_RSSI_EFFECT_PRIMARY;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800753 break;
754 default:
755 rsssi_effect = 0;
756 break;
757 }
758
759 rssi = pSpectCh->rssiAgr + rsssi_effect;
760 if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi))
761 pExtSpectCh->rssiAgr = rssi;
762 if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI)
763 pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI;
764 }
765}
766
767/**
768 * sap_upd_chan_spec_params() - sap_upd_chan_spec_params
769 * updates channel parameters obtained from Beacon
770 * @pBeaconStruct Beacon strucutre populated by parse_beacon function
771 * @channelWidth Channel width
772 * @secondaryChannelOffset Secondary Channel Offset
773 * @vhtSupport If channel supports VHT
774 * @centerFreq Central frequency for the given channel.
775 *
776 * sap_upd_chan_spec_params updates the spectrum channels based on the
777 * pBeaconStruct obtained from Beacon IE
778 *
779 * Return: NA.
780 */
781
782void sap_upd_chan_spec_params(tSirProbeRespBeacon *pBeaconStruct,
783 uint16_t *channelWidth,
784 uint16_t *secondaryChannelOffset,
785 uint16_t *vhtSupport,
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -0700786 uint16_t *centerFreq,
787 uint16_t *centerFreq_2)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800788{
789 if (NULL == pBeaconStruct) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530790 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800791 FL("pBeaconStruct is NULL"));
792 return;
793 }
794
795 if (pBeaconStruct->HTCaps.present && pBeaconStruct->HTInfo.present) {
796 *channelWidth = pBeaconStruct->HTCaps.supportedChannelWidthSet;
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -0700797 *secondaryChannelOffset =
798 pBeaconStruct->HTInfo.secondaryChannelOffset;
799 if (!pBeaconStruct->VHTOperation.present)
800 return;
801 *vhtSupport = pBeaconStruct->VHTOperation.present;
802 if (pBeaconStruct->VHTOperation.chanWidth) {
803 *centerFreq =
804 pBeaconStruct->VHTOperation.chanCenterFreqSeg1;
805 *centerFreq_2 =
806 pBeaconStruct->VHTOperation.chanCenterFreqSeg2;
807 /*
808 * LHS follows tSirMacHTChannelWidth, while RHS follows
809 * WNI_CFG_VHT_CHANNEL_WIDTH_X format hence following
810 * adjustment
811 */
812 *channelWidth =
813 pBeaconStruct->VHTOperation.chanWidth + 1;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800814
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800815 }
816 }
817}
818
819/**
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -0700820 * sap_update_rssi_bsscount_vht_5G() - updates bss count and rssi effect.
821 *
822 * @pSpectCh: Channel Information
823 * @offset: Channel Offset
824 * @num_ch: no.of channels
825 *
826 * sap_update_rssi_bsscount_vht_5G updates bss count and rssi effect based
827 * on the channel offset.
828 *
829 * Return: None.
830 */
831
832void sap_update_rssi_bsscount_vht_5G(tSapSpectChInfo *spect_ch, int32_t offset,
833 uint16_t num_ch)
834{
835 int32_t ch_offset;
836 uint16_t i, cnt;
837
838 if (!offset)
839 return;
840 if (offset > 0)
841 cnt = num_ch;
842 else
843 cnt = num_ch + 1;
844 for (i = 0; i < cnt; i++) {
845 ch_offset = offset + i;
846 if (ch_offset == 0)
847 continue;
848 sap_update_rssi_bsscount(spect_ch, ch_offset, false);
849 }
850}
851/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800852 * sap_interference_rssi_count_5G() - sap_interference_rssi_count
853 * considers the Adjacent channel rssi and
854 * data count(here number of BSS observed)
855 * @spect_ch: Channel Information
856 * @chan_width: Channel width parsed from beacon IE
857 * @sec_chan_offset: Secondary Channel Offset
858 * @center_freq: Central frequency for the given channel.
859 * @channel_id: channel_id
860 *
861 * sap_interference_rssi_count_5G considers the Adjacent channel rssi
862 * and data count(here number of BSS observed)
863 *
864 * Return: NA.
865 */
866
867void sap_interference_rssi_count_5G(tSapSpectChInfo *spect_ch,
868 uint16_t chan_width,
869 uint16_t sec_chan_offset,
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -0700870 uint16_t center_freq,
871 uint16_t center_freq_2,
872 uint8_t channel_id)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800873{
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -0700874 uint16_t num_ch;
875 int32_t offset = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800876 if (NULL == spect_ch) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530877 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800878 FL("spect_ch is NULL"));
879 return;
880 }
881
882 /* Updating the received ChannelWidth */
883 if (spect_ch->channelWidth != chan_width)
884 spect_ch->channelWidth = chan_width;
885 /* If received ChannelWidth is other than HT20,
886 * we need to update the extension channel Params as well
887 * chan_width == 0, HT20
888 * chan_width == 1, HT40
889 * chan_width == 2, VHT80
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -0700890 * chan_width == 3, VHT160
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800891 */
892
893 switch (spect_ch->channelWidth) {
894 case eHT_CHANNEL_WIDTH_40MHZ: /* HT40 */
895 switch (sec_chan_offset) {
896 /* Above the Primary Channel */
897 case PHY_DOUBLE_CHANNEL_LOW_PRIMARY:
898 sap_update_rssi_bsscount(spect_ch, 1, false);
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -0700899 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800900
901 /* Below the Primary channel */
902 case PHY_DOUBLE_CHANNEL_HIGH_PRIMARY:
903 sap_update_rssi_bsscount(spect_ch, -1, false);
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -0700904 return;
905 }
906 return;
907 case eHT_CHANNEL_WIDTH_80MHZ: /* VHT80 */
908 num_ch = 3;
909 if ((center_freq - channel_id) == 6) {
910 offset = 1;
911 } else if ((center_freq - channel_id) == 2) {
912 offset = -1;
913 } else if ((center_freq - channel_id) == -2) {
914 offset = -2;
915 } else if ((center_freq - channel_id) == -6) {
916 offset = -3;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800917 }
918 break;
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -0700919 case eHT_CHANNEL_WIDTH_160MHZ: /* VHT160 */
920 num_ch = 7;
921 if ((center_freq - channel_id) == 14)
922 offset = 1;
923 else if ((center_freq - channel_id) == 10)
924 offset = -1;
925 else if ((center_freq - channel_id) == 6)
926 offset = -2;
927 else if ((center_freq - channel_id) == 2)
928 offset = -3;
929 else if ((center_freq - channel_id) == -2)
930 offset = -4;
931 else if ((center_freq - channel_id) == -6)
932 offset = -5;
933 else if ((center_freq - channel_id) == -10)
934 offset = -6;
935 else if ((center_freq - channel_id) == -14)
936 offset = -7;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800937 break;
938 default:
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -0700939 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800940 }
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -0700941 sap_update_rssi_bsscount_vht_5G(spect_ch, offset, num_ch);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800942}
943
944/**
945 * sap_interference_rssi_count() - sap_interference_rssi_count
946 * considers the Adjacent channel rssi
947 * and data count(here number of BSS observed)
948 * @spect_ch Channel Information
949 *
950 * sap_interference_rssi_count considers the Adjacent channel rssi
951 * and data count(here number of BSS observed)
952 *
953 * Return: None.
954 */
955
956void sap_interference_rssi_count(tSapSpectChInfo *spect_ch)
957{
958 if (NULL == spect_ch) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530959 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800960 "%s: spect_ch is NULL", __func__);
961 return;
962 }
963
964 switch (spect_ch->chNum) {
965 case CHANNEL_1:
966 sap_update_rssi_bsscount(spect_ch, 1, true);
967 sap_update_rssi_bsscount(spect_ch, 2, true);
968 sap_update_rssi_bsscount(spect_ch, 3, true);
969 sap_update_rssi_bsscount(spect_ch, 4, true);
970 break;
971
972 case CHANNEL_2:
973 sap_update_rssi_bsscount(spect_ch, -1, true);
974 sap_update_rssi_bsscount(spect_ch, 1, true);
975 sap_update_rssi_bsscount(spect_ch, 2, true);
976 sap_update_rssi_bsscount(spect_ch, 3, true);
977 sap_update_rssi_bsscount(spect_ch, 4, true);
978 break;
979 case CHANNEL_3:
980 sap_update_rssi_bsscount(spect_ch, -2, true);
981 sap_update_rssi_bsscount(spect_ch, -1, true);
982 sap_update_rssi_bsscount(spect_ch, 1, true);
983 sap_update_rssi_bsscount(spect_ch, 2, true);
984 sap_update_rssi_bsscount(spect_ch, 3, true);
985 sap_update_rssi_bsscount(spect_ch, 4, true);
986 break;
987 case CHANNEL_4:
988 sap_update_rssi_bsscount(spect_ch, -3, true);
989 sap_update_rssi_bsscount(spect_ch, -2, true);
990 sap_update_rssi_bsscount(spect_ch, -1, true);
991 sap_update_rssi_bsscount(spect_ch, 1, true);
992 sap_update_rssi_bsscount(spect_ch, 2, true);
993 sap_update_rssi_bsscount(spect_ch, 3, true);
994 sap_update_rssi_bsscount(spect_ch, 4, true);
995 break;
996
997 case CHANNEL_5:
998 case CHANNEL_6:
999 case CHANNEL_7:
1000 case CHANNEL_8:
1001 case CHANNEL_9:
1002 case CHANNEL_10:
1003 sap_update_rssi_bsscount(spect_ch, -4, true);
1004 sap_update_rssi_bsscount(spect_ch, -3, true);
1005 sap_update_rssi_bsscount(spect_ch, -2, true);
1006 sap_update_rssi_bsscount(spect_ch, -1, true);
1007 sap_update_rssi_bsscount(spect_ch, 1, true);
1008 sap_update_rssi_bsscount(spect_ch, 2, true);
1009 sap_update_rssi_bsscount(spect_ch, 3, true);
1010 sap_update_rssi_bsscount(spect_ch, 4, true);
1011 break;
1012
1013 case CHANNEL_11:
1014 sap_update_rssi_bsscount(spect_ch, -4, true);
1015 sap_update_rssi_bsscount(spect_ch, -3, true);
1016 sap_update_rssi_bsscount(spect_ch, -2, true);
1017 sap_update_rssi_bsscount(spect_ch, -1, true);
1018 sap_update_rssi_bsscount(spect_ch, 1, true);
1019 sap_update_rssi_bsscount(spect_ch, 2, true);
1020 sap_update_rssi_bsscount(spect_ch, 3, true);
1021 break;
1022
1023 case CHANNEL_12:
1024 sap_update_rssi_bsscount(spect_ch, -4, true);
1025 sap_update_rssi_bsscount(spect_ch, -3, true);
1026 sap_update_rssi_bsscount(spect_ch, -2, true);
1027 sap_update_rssi_bsscount(spect_ch, -1, true);
1028 sap_update_rssi_bsscount(spect_ch, 1, true);
1029 sap_update_rssi_bsscount(spect_ch, 2, true);
1030 break;
1031
1032 case CHANNEL_13:
1033 sap_update_rssi_bsscount(spect_ch, -4, true);
1034 sap_update_rssi_bsscount(spect_ch, -3, true);
1035 sap_update_rssi_bsscount(spect_ch, -2, true);
1036 sap_update_rssi_bsscount(spect_ch, -1, true);
1037 sap_update_rssi_bsscount(spect_ch, 1, true);
1038 break;
1039
1040 case CHANNEL_14:
1041 sap_update_rssi_bsscount(spect_ch, -4, true);
1042 sap_update_rssi_bsscount(spect_ch, -3, true);
1043 sap_update_rssi_bsscount(spect_ch, -2, true);
1044 sap_update_rssi_bsscount(spect_ch, -1, true);
1045 break;
1046
1047 default:
1048 break;
1049 }
1050}
1051
1052/*==========================================================================
1053 Function ch_in_pcl
1054
1055 Description
1056 Check if a channel is in the preferred channel list
1057
1058 Parameters
1059 sap_ctx SAP context pointer
1060 channel input channel number
1061
1062 Return Value
1063 true: channel is in PCL
1064 false: channel is not in PCL
1065 ==========================================================================*/
1066bool ch_in_pcl(ptSapContext sap_ctx, uint8_t channel)
1067{
1068 uint32_t i;
1069
1070 for (i = 0; i < sap_ctx->acs_cfg->pcl_ch_count; i++) {
1071 if (channel == sap_ctx->acs_cfg->pcl_channels[i])
1072 return true;
1073 }
1074
1075 return false;
1076}
1077
1078/*==========================================================================
1079 FUNCTION sap_compute_spect_weight
1080
1081 DESCRIPTION
1082 Main function for computing the weight of each channel in the
1083 spectrum based on the RSSI value of the BSSes on the channel
1084 and number of BSS
1085
1086 DEPENDENCIES
1087 NA.
1088
1089 PARAMETERS
1090
1091 IN
1092 pSpectInfoParams : Pointer to the tSpectInfoParams structure
1093 halHandle : Pointer to HAL handle
1094 pResult : Pointer to tScanResultHandle
1095
1096 RETURN VALUE
1097 void : NULL
1098
1099 SIDE EFFECTS
1100 ============================================================================*/
1101void sap_compute_spect_weight(tSapChSelSpectInfo *pSpectInfoParams,
1102 tHalHandle halHandle, tScanResultHandle pResult,
1103 ptSapContext sap_ctx)
1104{
1105 int8_t rssi = 0;
1106 uint8_t chn_num = 0;
1107 uint8_t channel_id = 0;
1108
1109 tCsrScanResultInfo *pScanResult;
1110 tSapSpectChInfo *pSpectCh = pSpectInfoParams->pSpectCh;
1111 uint32_t operatingBand;
1112 uint16_t channelWidth;
1113 uint16_t secondaryChannelOffset;
1114 uint16_t centerFreq;
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001115 uint16_t centerFreq_2 = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001116 uint16_t vhtSupport;
1117 uint32_t ieLen = 0;
1118 tSirProbeRespBeacon *pBeaconStruct;
1119 tpAniSirGlobal pMac = (tpAniSirGlobal) halHandle;
1120
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301121 pBeaconStruct = qdf_mem_malloc(sizeof(tSirProbeRespBeacon));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001122 if (NULL == pBeaconStruct) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301123 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001124 "Unable to allocate memory in sap_compute_spect_weight\n");
1125 return;
1126 }
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301127 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001128 "In %s, Computing spectral weight", __func__);
1129
1130 /**
1131 * Soft AP specific channel weight calculation using DFS formula
1132 */
1133 SET_ACS_BAND(operatingBand, sap_ctx);
1134
1135 pScanResult = sme_scan_result_get_first(halHandle, pResult);
1136
1137 while (pScanResult) {
1138 pSpectCh = pSpectInfoParams->pSpectCh;
1139 /* Defining the default values, so that any value will hold the default values */
1140 channelWidth = eHT_CHANNEL_WIDTH_20MHZ;
1141 secondaryChannelOffset = PHY_SINGLE_CHANNEL_CENTERED;
1142 vhtSupport = 0;
1143 centerFreq = 0;
1144
1145 if (pScanResult->BssDescriptor.ieFields != NULL) {
1146 ieLen =
1147 (pScanResult->BssDescriptor.length +
1148 sizeof(uint16_t) + sizeof(uint32_t) -
1149 sizeof(tSirBssDescription));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301150 qdf_mem_set((uint8_t *) pBeaconStruct,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001151 sizeof(tSirProbeRespBeacon), 0);
1152
1153 if ((sir_parse_beacon_ie
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001154 (pMac, pBeaconStruct, (uint8_t *)
1155 (pScanResult->BssDescriptor.ieFields),
1156 ieLen)) == eSIR_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001157 sap_upd_chan_spec_params(pBeaconStruct,
1158 &channelWidth, &secondaryChannelOffset,
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001159 &vhtSupport, &centerFreq,
1160 &centerFreq_2);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001161 }
1162 }
1163 /* Processing for each tCsrScanResultInfo in the tCsrScanResult DLink list */
1164 for (chn_num = 0; chn_num < pSpectInfoParams->numSpectChans;
1165 chn_num++) {
1166
1167 /*
1168 * if the Beacon has channel ID, use it other wise we will
1169 * rely on the channelIdSelf
1170 */
1171 if (pScanResult->BssDescriptor.channelId == 0)
1172 channel_id =
1173 pScanResult->BssDescriptor.channelIdSelf;
1174 else
1175 channel_id =
1176 pScanResult->BssDescriptor.channelId;
1177
1178 if (pSpectCh && (channel_id == pSpectCh->chNum)) {
1179 if (pSpectCh->rssiAgr <
1180 pScanResult->BssDescriptor.rssi)
1181 pSpectCh->rssiAgr =
1182 pScanResult->BssDescriptor.rssi;
1183
1184 ++pSpectCh->bssCount; /* Increment the count of BSS */
1185
1186 /*
1187 * Connsidering the Extension Channel
1188 * only in a channels
1189 */
1190 switch (operatingBand) {
1191 case eCSR_DOT11_MODE_11a:
1192 sap_interference_rssi_count_5G(
1193 pSpectCh, channelWidth,
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001194 secondaryChannelOffset,
1195 centerFreq,
1196 centerFreq_2,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001197 channel_id);
1198 break;
1199
1200 case eCSR_DOT11_MODE_11g:
1201 sap_interference_rssi_count(pSpectCh);
1202 break;
1203
1204 case eCSR_DOT11_MODE_abg:
1205 sap_interference_rssi_count_5G(
1206 pSpectCh, channelWidth,
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001207 secondaryChannelOffset,
1208 centerFreq,
1209 centerFreq_2,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001210 channel_id);
1211 sap_interference_rssi_count(pSpectCh);
1212 break;
1213 }
1214
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301215 QDF_TRACE(QDF_MODULE_ID_SAP,
1216 QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001217 "In %s, bssdes.ch_self=%d, bssdes.ch_ID=%d, bssdes.rssi=%d, SpectCh.bssCount=%d, pScanResult=%p, ChannelWidth %d, secondaryChanOffset %d, center frequency %d \n",
1218 __func__,
1219 pScanResult->BssDescriptor.
1220 channelIdSelf,
1221 pScanResult->BssDescriptor.channelId,
1222 pScanResult->BssDescriptor.rssi,
1223 pSpectCh->bssCount, pScanResult,
1224 pSpectCh->channelWidth,
1225 secondaryChannelOffset, centerFreq);
1226 pSpectCh++;
1227 break;
1228 } else {
1229 pSpectCh++;
1230 }
1231 }
1232
1233 pScanResult = sme_scan_result_get_next(halHandle, pResult);
1234 }
1235
1236 /* Calculate the weights for all channels in the spectrum pSpectCh */
1237 pSpectCh = pSpectInfoParams->pSpectCh;
1238
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301239 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001240 "In %s, Spectrum Channels Weight", __func__);
1241
1242 for (chn_num = 0; chn_num < (pSpectInfoParams->numSpectChans);
1243 chn_num++) {
1244
1245 /*
1246 rssi : Maximum received signal strength among all BSS on that channel
1247 bssCount : Number of BSS on that channel
1248 */
1249
1250 rssi = (int8_t) pSpectCh->rssiAgr;
1251 if (ch_in_pcl(sap_ctx, chn_num))
1252 rssi -= PCL_RSSI_DISCOUNT;
1253
1254 pSpectCh->weight =
1255 SAPDFS_NORMALISE_1000 * sapweight_rssi_count(rssi,
1256 pSpectCh->
1257 bssCount);
1258 pSpectCh->weight_copy = pSpectCh->weight;
1259
1260 /* ------ Debug Info ------ */
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301261 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001262 "In %s, Chan=%d Weight= %d rssiAgr=%d bssCount=%d",
1263 __func__, pSpectCh->chNum, pSpectCh->weight,
1264 pSpectCh->rssiAgr, pSpectCh->bssCount);
1265 /* ------ Debug Info ------ */
1266 pSpectCh++;
1267 }
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301268 qdf_mem_free(pBeaconStruct);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001269}
1270
1271/*==========================================================================
1272 FUNCTION sap_chan_sel_exit
1273
1274 DESCRIPTION
1275 Exit function for free out the allocated memory, to be called
1276 at the end of the dfsSelectChannel function
1277
1278 DEPENDENCIES
1279 NA.
1280
1281 PARAMETERS
1282
1283 IN
1284 pSpectInfoParams : Pointer to the tSapChSelSpectInfo structure
1285
1286 RETURN VALUE
1287 void : NULL
1288
1289 SIDE EFFECTS
1290 ============================================================================*/
1291void sap_chan_sel_exit(tSapChSelSpectInfo *pSpectInfoParams)
1292{
1293 /* Free all the allocated memory */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301294 qdf_mem_free(pSpectInfoParams->pSpectCh);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001295}
1296
1297/*==========================================================================
1298 FUNCTION sap_sort_chl_weight
1299
1300 DESCRIPTION
1301 Funtion to sort the channels with the least weight first for 20MHz channels
1302
1303 DEPENDENCIES
1304 NA.
1305
1306 PARAMETERS
1307
1308 IN
1309 pSpectInfoParams : Pointer to the tSapChSelSpectInfo structure
1310
1311 RETURN VALUE
1312 void : NULL
1313
1314 SIDE EFFECTS
1315 ============================================================================*/
1316void sap_sort_chl_weight(tSapChSelSpectInfo *pSpectInfoParams)
1317{
1318 tSapSpectChInfo temp;
1319
1320 tSapSpectChInfo *pSpectCh = NULL;
1321 uint32_t i = 0, j = 0, minWeightIndex = 0;
1322
1323 pSpectCh = pSpectInfoParams->pSpectCh;
1324 for (i = 0; i < pSpectInfoParams->numSpectChans; i++) {
1325 minWeightIndex = i;
1326 for (j = i + 1; j < pSpectInfoParams->numSpectChans; j++) {
1327 if (pSpectCh[j].weight <
1328 pSpectCh[minWeightIndex].weight) {
1329 minWeightIndex = j;
1330 }
1331 }
1332 if (minWeightIndex != i) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301333 qdf_mem_copy(&temp, &pSpectCh[minWeightIndex],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001334 sizeof(*pSpectCh));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301335 qdf_mem_copy(&pSpectCh[minWeightIndex], &pSpectCh[i],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001336 sizeof(*pSpectCh));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301337 qdf_mem_copy(&pSpectCh[i], &temp, sizeof(*pSpectCh));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001338 }
1339 }
1340}
1341
1342/**
1343 * sap_sort_chl_weight_ht80() - to sort the channels with the least weight
1344 * @pSpectInfoParams: Pointer to the tSapChSelSpectInfo structure
1345 *
1346 * Funtion to sort the channels with the least weight first for HT80 channels
1347 *
1348 * Return: none
1349 */
1350void sap_sort_chl_weight_ht80(tSapChSelSpectInfo *pSpectInfoParams)
1351{
1352 uint8_t i, j, n;
1353 tSapSpectChInfo *pSpectInfo;
1354 uint8_t minIdx;
1355
1356 pSpectInfo = pSpectInfoParams->pSpectCh;
1357 /* for each HT80 channel, calculate the combined weight of the
1358 four 20MHz weight */
1359 for (i = 0; i < ARRAY_SIZE(acs_ht80_channels); i++) {
1360 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
1361 if (pSpectInfo[j].chNum ==
1362 acs_ht80_channels[i].chStartNum)
1363 break;
1364 }
1365 if (j == pSpectInfoParams->numSpectChans)
1366 continue;
1367
1368 if (!(((pSpectInfo[j].chNum + 4) == pSpectInfo[j + 1].chNum) &&
1369 ((pSpectInfo[j].chNum + 8) ==
1370 pSpectInfo[j + 2].chNum) &&
1371 ((pSpectInfo[j].chNum + 12) ==
1372 pSpectInfo[j + 3].chNum))) {
1373 /*
1374 * some channels does not exist in pSectInfo array,
1375 * skip this channel and those in the same HT80 width
1376 */
1377 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 4;
1378 if ((pSpectInfo[j].chNum + 4) ==
1379 pSpectInfo[j + 1].chNum)
1380 pSpectInfo[j + 1].weight =
1381 SAP_ACS_WEIGHT_MAX * 4;
1382 if ((pSpectInfo[j].chNum + 8) ==
1383 pSpectInfo[j + 2].chNum)
1384 pSpectInfo[j + 2].weight =
1385 SAP_ACS_WEIGHT_MAX * 4;
1386 if ((pSpectInfo[j].chNum + 12) ==
1387 pSpectInfo[j + 3].chNum)
1388 pSpectInfo[j + 3].weight =
1389 SAP_ACS_WEIGHT_MAX * 4;
1390 continue;
1391 }
1392 /*found the channel, add the 4 adjacent channels' weight */
1393 acs_ht80_channels[i].weight = pSpectInfo[j].weight +
1394 pSpectInfo[j + 1].weight + pSpectInfo[j + 2].weight +
1395 pSpectInfo[j + 3].weight;
1396 /* find best channel among 4 channels as the primary channel */
1397 if ((pSpectInfo[j].weight + pSpectInfo[j + 1].weight) <
1398 (pSpectInfo[j + 2].weight + pSpectInfo[j + 3].weight)) {
1399 /* lower 2 channels are better choice */
1400 if (pSpectInfo[j].weight < pSpectInfo[j + 1].weight)
1401 minIdx = 0;
1402 else
1403 minIdx = 1;
1404 } else if (pSpectInfo[j + 2].weight <=
1405 pSpectInfo[j + 3].weight) {
1406 /* upper 2 channels are better choice */
1407 minIdx = 2;
1408 } else {
1409 minIdx = 3;
1410 }
1411
1412 /*
1413 * set all 4 channels to max value first, then reset the
1414 * best channel as the selected primary channel, update its
1415 * weightage with the combined weight value
1416 */
1417 for (n = 0; n < 4; n++)
1418 pSpectInfo[j + n].weight = SAP_ACS_WEIGHT_MAX * 4;
1419
1420 pSpectInfo[j + minIdx].weight = acs_ht80_channels[i].weight;
1421 }
1422
1423 pSpectInfo = pSpectInfoParams->pSpectCh;
1424 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
1425 if (CHANNEL_165 == pSpectInfo[j].chNum) {
1426 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 4;
1427 break;
1428 }
1429 }
1430
Manishekar Chandrasekaran44e334f2016-05-30 16:42:50 +05301431 sap_sort_chl_weight(pSpectInfoParams);
1432
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001433 pSpectInfo = pSpectInfoParams->pSpectCh;
1434 for (j = 0; j < (pSpectInfoParams->numSpectChans); j++) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301435 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001436 FL("Channel=%d Weight= %d rssi=%d bssCount=%d"),
1437 pSpectInfo->chNum, pSpectInfo->weight,
1438 pSpectInfo->rssiAgr, pSpectInfo->bssCount);
1439 pSpectInfo++;
1440 }
1441}
1442
1443/**
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001444 * sap_sort_chl_weight_vht160() - to sort the channels with the least weight
1445 * @pSpectInfoParams: Pointer to the tSapChSelSpectInfo structure
1446 *
1447 * Funtion to sort the channels with the least weight first for VHT160 channels
1448 *
1449 * Return: none
1450 */
1451void sap_sort_chl_weight_vht160(tSapChSelSpectInfo *pSpectInfoParams)
1452{
1453 uint8_t i, j, n, idx;
1454 tSapSpectChInfo *pSpectInfo;
1455 uint8_t minIdx;
1456
1457 pSpectInfo = pSpectInfoParams->pSpectCh;
1458 /* for each VHT160 channel, calculate the combined weight of the
1459 8 20MHz weight */
1460 for (i = 0; i < ARRAY_SIZE(acs_vht160_channels); i++) {
1461 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
1462 if (pSpectInfo[j].chNum ==
1463 acs_vht160_channels[i].chStartNum)
1464 break;
1465 }
1466 if (j == pSpectInfoParams->numSpectChans)
1467 continue;
1468
1469 if (!(((pSpectInfo[j].chNum + 4) == pSpectInfo[j + 1].chNum) &&
1470 ((pSpectInfo[j].chNum + 8) ==
1471 pSpectInfo[j + 2].chNum) &&
1472 ((pSpectInfo[j].chNum + 12) ==
1473 pSpectInfo[j + 3].chNum) &&
1474 ((pSpectInfo[j].chNum + 16) ==
1475 pSpectInfo[j + 4].chNum) &&
1476 ((pSpectInfo[j].chNum + 20) ==
1477 pSpectInfo[j + 5].chNum) &&
1478 ((pSpectInfo[j].chNum + 24) ==
1479 pSpectInfo[j + 6].chNum) &&
1480 ((pSpectInfo[j].chNum + 28) ==
1481 pSpectInfo[j + 7].chNum))) {
1482 /*
1483 * some channels does not exist in pSectInfo array,
1484 * skip this channel and those in the same VHT160 width
1485 */
1486 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 8;
1487 if ((pSpectInfo[j].chNum + 4) ==
1488 pSpectInfo[j + 1].chNum)
1489 pSpectInfo[j + 1].weight =
1490 SAP_ACS_WEIGHT_MAX * 8;
1491 if ((pSpectInfo[j].chNum + 8) ==
1492 pSpectInfo[j + 2].chNum)
1493 pSpectInfo[j + 2].weight =
1494 SAP_ACS_WEIGHT_MAX * 8;
1495 if ((pSpectInfo[j].chNum + 12) ==
1496 pSpectInfo[j + 3].chNum)
1497 pSpectInfo[j + 3].weight =
1498 SAP_ACS_WEIGHT_MAX * 8;
1499 if ((pSpectInfo[j].chNum + 16) ==
1500 pSpectInfo[j + 4].chNum)
1501 pSpectInfo[j + 4].weight =
1502 SAP_ACS_WEIGHT_MAX * 8;
1503 if ((pSpectInfo[j].chNum + 20) ==
1504 pSpectInfo[j + 5].chNum)
1505 pSpectInfo[j + 5].weight =
1506 SAP_ACS_WEIGHT_MAX * 8;
1507 if ((pSpectInfo[j].chNum + 24) ==
1508 pSpectInfo[j + 6].chNum)
1509 pSpectInfo[j + 6].weight =
1510 SAP_ACS_WEIGHT_MAX * 8;
1511 if ((pSpectInfo[j].chNum + 28) ==
1512 pSpectInfo[j + 7].chNum)
1513 pSpectInfo[j + 7].weight =
1514 SAP_ACS_WEIGHT_MAX * 8;
1515 continue;
1516 }
1517 /*found the channel, add the 7 adjacent channels' weight */
1518 acs_vht160_channels[i].weight = pSpectInfo[j].weight +
1519 pSpectInfo[j + 1].weight + pSpectInfo[j + 2].weight +
1520 pSpectInfo[j + 3].weight + pSpectInfo[j + 4].weight +
1521 pSpectInfo[j + 5].weight + pSpectInfo[j + 6].weight +
1522 pSpectInfo[j + 7].weight;
1523
1524 /* find best channel among 8 channels as the primary channel */
1525 if ((pSpectInfo[j].weight + pSpectInfo[j + 1].weight +
1526 pSpectInfo[j + 2].weight + pSpectInfo[j + 3].weight) >
1527 (pSpectInfo[j + 4].weight + pSpectInfo[j + 5].weight +
1528 pSpectInfo[j + 6].weight + pSpectInfo[j + 7].weight))
1529 idx = 4;
1530 else
1531 idx = 0;
1532 /* find best channel among 4 channels as the primary channel */
1533 if ((pSpectInfo[j + idx].weight +
1534 pSpectInfo[j + idx + 1].weight) <
1535 (pSpectInfo[j + idx + 2].weight +
1536 pSpectInfo[j + idx + 3].weight)) {
1537 /* lower 2 channels are better choice */
1538 if (pSpectInfo[j + idx].weight <
1539 pSpectInfo[j + idx + 1].weight)
1540 minIdx = 0 + idx;
1541 else
1542 minIdx = 1 + idx;
1543 } else if (pSpectInfo[j + idx + 2].weight <=
1544 pSpectInfo[j + idx + 3].weight) {
1545 /* upper 2 channels are better choice */
1546 minIdx = 2 + idx;
1547 } else {
1548 minIdx = 3 + idx;
1549 }
1550
1551 /*
1552 * set all 8 channels to max value first, then reset the
1553 * best channel as the selected primary channel, update its
1554 * weightage with the combined weight value
1555 */
1556 for (n = 0; n < 8; n++)
1557 pSpectInfo[j + n].weight = SAP_ACS_WEIGHT_MAX * 8;
1558
1559 pSpectInfo[j + minIdx].weight = acs_vht160_channels[i].weight;
1560 }
1561
1562 pSpectInfo = pSpectInfoParams->pSpectCh;
1563 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
1564 if (CHANNEL_165 == pSpectInfo[j].chNum) {
1565 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 8;
1566 break;
1567 }
1568 }
1569
Manishekar Chandrasekaran44e334f2016-05-30 16:42:50 +05301570 sap_sort_chl_weight(pSpectInfoParams);
1571
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001572 pSpectInfo = pSpectInfoParams->pSpectCh;
1573 for (j = 0; j < (pSpectInfoParams->numSpectChans); j++) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301574 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001575 FL("Channel=%d Weight= %d rssi=%d bssCount=%d"),
1576 pSpectInfo->chNum, pSpectInfo->weight,
1577 pSpectInfo->rssiAgr, pSpectInfo->bssCount);
1578 pSpectInfo++;
1579 }
1580}
1581
1582/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001583 * sap_sort_chl_weight_ht40_24_g() - to sort channel with the least weight
1584 * @pSpectInfoParams: Pointer to the tSapChSelSpectInfo structure
1585 *
1586 * Funtion to sort the channels with the least weight first for HT40 channels
1587 *
1588 * Return: none
1589 */
1590void sap_sort_chl_weight_ht40_24_g(tSapChSelSpectInfo *pSpectInfoParams)
1591{
1592 uint8_t i, j;
1593 tSapSpectChInfo *pSpectInfo;
1594 uint32_t tmpWeight1, tmpWeight2;
1595
1596 pSpectInfo = pSpectInfoParams->pSpectCh;
1597 /*
1598 * for each HT40 channel, calculate the combined weight of the
1599 * two 20MHz weight
1600 */
1601 for (i = 0; i < ARRAY_SIZE(acs_ht40_channels24_g); i++) {
1602 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
1603 if (pSpectInfo[j].chNum ==
1604 acs_ht40_channels24_g[i].chStartNum)
1605 break;
1606 }
1607 if (j == pSpectInfoParams->numSpectChans)
1608 continue;
1609
1610 if (!((pSpectInfo[j].chNum + 4) == pSpectInfo[j + 4].chNum)) {
1611 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2;
1612 continue;
1613 }
1614 /*
1615 * check if there is another channel combination possiblity
1616 * e.g., {1, 5} & {5, 9}
1617 */
1618 if ((pSpectInfo[j + 4].chNum + 4) == pSpectInfo[j + 8].chNum) {
1619 /* need to compare two channel pairs */
1620 tmpWeight1 = pSpectInfo[j].weight +
1621 pSpectInfo[j + 4].weight;
1622 tmpWeight2 = pSpectInfo[j + 4].weight +
1623 pSpectInfo[j + 8].weight;
1624 if (tmpWeight1 <= tmpWeight2) {
1625 if (pSpectInfo[j].weight <=
1626 pSpectInfo[j + 4].weight) {
1627 pSpectInfo[j].weight =
1628 tmpWeight1;
1629 pSpectInfo[j + 4].weight =
1630 SAP_ACS_WEIGHT_MAX * 2;
1631 pSpectInfo[j + 8].weight =
1632 SAP_ACS_WEIGHT_MAX * 2;
1633 } else {
1634 pSpectInfo[j + 4].weight =
1635 tmpWeight1;
1636 /* for secondary channel selection */
1637 pSpectInfo[j].weight =
1638 SAP_ACS_WEIGHT_MAX * 2
1639 - 1;
1640 pSpectInfo[j + 8].weight =
1641 SAP_ACS_WEIGHT_MAX * 2;
1642 }
1643 } else {
1644 if (pSpectInfo[j + 4].weight <=
1645 pSpectInfo[j + 8].weight) {
1646 pSpectInfo[j + 4].weight =
1647 tmpWeight2;
1648 pSpectInfo[j].weight =
1649 SAP_ACS_WEIGHT_MAX * 2;
1650 /* for secondary channel selection */
1651 pSpectInfo[j + 8].weight =
1652 SAP_ACS_WEIGHT_MAX * 2
1653 - 1;
1654 } else {
1655 pSpectInfo[j + 8].weight =
1656 tmpWeight2;
1657 pSpectInfo[j].weight =
1658 SAP_ACS_WEIGHT_MAX * 2;
1659 pSpectInfo[j + 4].weight =
1660 SAP_ACS_WEIGHT_MAX * 2;
1661 }
1662 }
1663 } else {
1664 tmpWeight1 = pSpectInfo[j].weight +
1665 pSpectInfo[j + 4].weight;
1666 if (pSpectInfo[j].weight <=
1667 pSpectInfo[j + 4].weight) {
1668 pSpectInfo[j].weight = tmpWeight1;
1669 pSpectInfo[j + 4].weight =
1670 SAP_ACS_WEIGHT_MAX * 2;
1671 } else {
1672 pSpectInfo[j + 4].weight = tmpWeight1;
1673 pSpectInfo[j].weight =
1674 SAP_ACS_WEIGHT_MAX * 2;
1675 }
1676 }
1677 }
Manishekar Chandrasekaran44e334f2016-05-30 16:42:50 +05301678 sap_sort_chl_weight(pSpectInfoParams);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001679}
1680
1681/*==========================================================================
1682 FUNCTION sap_sort_chl_weight_ht40_5_g
1683
1684 DESCRIPTION
1685 Funtion to sort the channels with the least weight first for HT40 channels
1686
1687 DEPENDENCIES
1688 NA.
1689
1690 PARAMETERS
1691
1692 IN
1693 pSpectInfoParams : Pointer to the tSapChSelSpectInfo structure
1694
1695 RETURN VALUE
1696 void : NULL
1697
1698 SIDE EFFECTS
1699 ============================================================================*/
1700void sap_sort_chl_weight_ht40_5_g(tSapChSelSpectInfo *pSpectInfoParams)
1701{
1702 uint8_t i, j;
1703 tSapSpectChInfo *pSpectInfo;
1704
1705 pSpectInfo = pSpectInfoParams->pSpectCh;
1706 /*for each HT40 channel, calculate the combined weight of the
1707 two 20MHz weight */
1708 for (i = 0; i < ARRAY_SIZE(acs_ht40_channels5_g); i++) {
1709 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
1710 if (pSpectInfo[j].chNum ==
1711 acs_ht40_channels5_g[i].chStartNum)
1712 break;
1713 }
1714 if (j == pSpectInfoParams->numSpectChans)
1715 continue;
1716
1717 /* found the channel, add the two adjacent channels' weight */
1718 if ((pSpectInfo[j].chNum + 4) == pSpectInfo[j + 1].chNum) {
1719 acs_ht40_channels5_g[i].weight = pSpectInfo[j].weight +
1720 pSpectInfo[j + 1].weight;
1721 /* select better of the adjact channel as the primary channel */
1722 if (pSpectInfo[j].weight <= pSpectInfo[j + 1].weight) {
1723 pSpectInfo[j].weight =
1724 acs_ht40_channels5_g[i].weight;
1725 /* mark the adjacent channel's weight as max value so
1726 that it will be sorted to the bottom */
1727 pSpectInfo[j + 1].weight =
1728 SAP_ACS_WEIGHT_MAX * 2;
1729 } else {
1730 pSpectInfo[j + 1].weight =
1731 acs_ht40_channels5_g[i].weight;
1732 /* mark the adjacent channel's weight as max value so
1733 that it will be sorted to the bottom */
1734 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2;
1735 }
1736
1737 } else
1738 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2;
1739 }
1740
1741 /* avoid channel 165 by setting its weight to max */
1742 pSpectInfo = pSpectInfoParams->pSpectCh;
1743 for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
1744 if (CHANNEL_165 == pSpectInfo[j].chNum) {
1745 pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2;
1746 break;
1747 }
1748 }
1749
1750 pSpectInfo = pSpectInfoParams->pSpectCh;
1751 for (j = 0; j < (pSpectInfoParams->numSpectChans); j++) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301752 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001753 "In %s, Channel=%d Weight= %d rssi=%d bssCount=%d",
1754 __func__, pSpectInfo->chNum, pSpectInfo->weight,
1755 pSpectInfo->rssiAgr, pSpectInfo->bssCount);
1756 pSpectInfo++;
1757 }
1758
1759 sap_sort_chl_weight(pSpectInfoParams);
1760}
1761
1762/*==========================================================================
1763 FUNCTION sap_sort_chl_weight_all
1764
1765 DESCRIPTION
1766 Funtion to sort the channels with the least weight first
1767
1768 DEPENDENCIES
1769 NA.
1770
1771 PARAMETERS
1772
1773 IN
1774 ptSapContext : Pointer to the ptSapContext structure
1775 pSpectInfoParams : Pointer to the tSapChSelSpectInfo structure
1776
1777 RETURN VALUE
1778 void : NULL
1779
1780 SIDE EFFECTS
1781 ============================================================================*/
1782void sap_sort_chl_weight_all(ptSapContext pSapCtx,
1783 tSapChSelSpectInfo *pSpectInfoParams,
1784 uint32_t operatingBand)
1785{
1786 tSapSpectChInfo *pSpectCh = NULL;
1787 uint32_t j = 0;
1788#ifndef SOFTAP_CHANNEL_RANGE
1789 uint32_t i = 0;
1790#endif
1791
1792 pSpectCh = pSpectInfoParams->pSpectCh;
1793#ifdef SOFTAP_CHANNEL_RANGE
1794
1795 switch (pSapCtx->acs_cfg->ch_width) {
1796 case CH_WIDTH_40MHZ:
1797 if (eCSR_DOT11_MODE_11g == operatingBand)
1798 sap_sort_chl_weight_ht40_24_g(pSpectInfoParams);
1799 else if (eCSR_DOT11_MODE_11a == operatingBand)
1800 sap_sort_chl_weight_ht40_5_g(pSpectInfoParams);
1801 else {
1802 sap_sort_chl_weight_ht40_24_g(pSpectInfoParams);
1803 sap_sort_chl_weight_ht40_5_g(pSpectInfoParams);
1804 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001805 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001806 case CH_WIDTH_80MHZ:
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001807 case CH_WIDTH_80P80MHZ:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001808 sap_sort_chl_weight_ht80(pSpectInfoParams);
1809 break;
Kiran Kumar Lokereb3d8b5b2015-10-06 19:33:42 -07001810 case CH_WIDTH_160MHZ:
1811 sap_sort_chl_weight_vht160(pSpectInfoParams);
1812 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001813 case CH_WIDTH_20MHZ:
1814 default:
1815 /* Sorting the channels as per weights as 20MHz channels */
1816 sap_sort_chl_weight(pSpectInfoParams);
1817 }
1818
1819#else
1820 /* Sorting the channels as per weights */
1821 for (i = 0; i < SPECT_24GHZ_CH_COUNT; i++) {
1822 minWeightIndex = i;
1823 for (j = i + 1; j < SPECT_24GHZ_CH_COUNT; j++) {
1824 if (pSpectCh[j].weight <
1825 pSpectCh[minWeightIndex].weight) {
1826 minWeightIndex = j;
1827 }
1828 }
1829 if (minWeightIndex != i) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301830 qdf_mem_copy(&temp, &pSpectCh[minWeightIndex],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001831 sizeof(*pSpectCh));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301832 qdf_mem_copy(&pSpectCh[minWeightIndex], &pSpectCh[i],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001833 sizeof(*pSpectCh));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301834 qdf_mem_copy(&pSpectCh[i], &temp, sizeof(*pSpectCh));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001835 }
1836 }
1837#endif
1838
1839 /* For testing */
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301840 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001841 "In %s, Sorted Spectrum Channels Weight", __func__);
1842 pSpectCh = pSpectInfoParams->pSpectCh;
1843 for (j = 0; j < (pSpectInfoParams->numSpectChans); j++) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301844 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001845 "In %s, Channel=%d Weight= %d rssi=%d bssCount=%d",
1846 __func__, pSpectCh->chNum, pSpectCh->weight,
1847 pSpectCh->rssiAgr, pSpectCh->bssCount);
1848 pSpectCh++;
1849 }
1850
1851}
1852
1853/*==========================================================================
1854 FUNCTION sap_filter_over_lap_ch
1855
1856 DESCRIPTION
1857 return true if ch is acceptable.
1858 This function will decide if we will filter over lap channel or not.
1859
1860 DEPENDENCIES
1861 shall called after ap start.
1862
1863 PARAMETERS
1864
1865 IN
1866 pSapCtx : Pointer to ptSapContext.
1867 chNum : Filter channel number.
1868
1869 RETURN VALUE
1870 bool : true if channel is accepted.
1871
1872 SIDE EFFECTS
1873 ============================================================================*/
1874bool sap_filter_over_lap_ch(ptSapContext pSapCtx, uint16_t chNum)
1875{
1876 if (pSapCtx->enableOverLapCh)
1877 return eSAP_TRUE;
1878 else if ((chNum == CHANNEL_1) ||
1879 (chNum == CHANNEL_6) || (chNum == CHANNEL_11))
1880 return eSAP_TRUE;
1881
1882 return eSAP_FALSE;
1883}
1884
Naveen Rawat365d1cb2016-02-05 12:10:43 -08001885/**
1886 * sap_select_channel_no_scan_result() - select SAP channel when no scan results
1887 * are available.
1888 * @sap_ctx: Sap context
1889 *
1890 * Returns: channel number if success, 0 otherwise
1891 */
1892static uint8_t sap_select_channel_no_scan_result(ptSapContext sap_ctx)
1893{
1894 enum channel_state ch_type;
1895 uint32_t start_ch_num, end_ch_num;
1896#ifdef FEATURE_WLAN_CH_AVOID
1897 uint8_t i, first_safe_ch_in_range = SAP_CHANNEL_NOT_SELECTED;
1898#endif
1899 start_ch_num = sap_ctx->acs_cfg->start_ch;
1900 end_ch_num = sap_ctx->acs_cfg->end_ch;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001901
Naveen Rawat365d1cb2016-02-05 12:10:43 -08001902 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
1903 FL("start - end: %d - %d"), start_ch_num, end_ch_num);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001904
Naveen Rawat365d1cb2016-02-05 12:10:43 -08001905#ifndef FEATURE_WLAN_CH_AVOID
1906 sap_ctx->acs_cfg->pri_ch = start_ch_num;
1907 sap_ctx->acs_cfg->ht_sec_ch = 0;
1908 /* pick the first channel in configured range */
1909 return start_ch_num;
1910#else
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001911
Naveen Rawat365d1cb2016-02-05 12:10:43 -08001912 /* get a channel in PCL and within the range */
1913 for (i = 0; i < sap_ctx->acs_cfg->pcl_ch_count; i++) {
1914 if ((sap_ctx->acs_cfg->pcl_channels[i] < start_ch_num) ||
1915 (sap_ctx->acs_cfg->pcl_channels[i] > end_ch_num))
1916 continue;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001917
Naveen Rawat365d1cb2016-02-05 12:10:43 -08001918 first_safe_ch_in_range = sap_ctx->acs_cfg->pcl_channels[i];
1919 break;
1920 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001921
Naveen Rawat365d1cb2016-02-05 12:10:43 -08001922 if (SAP_CHANNEL_NOT_SELECTED != first_safe_ch_in_range)
1923 return first_safe_ch_in_range;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001924
Naveen Rawat365d1cb2016-02-05 12:10:43 -08001925 for (i = 0; i < NUM_CHANNELS; i++) {
1926 if ((safe_channels[i].channelNumber < start_ch_num) ||
1927 (safe_channels[i].channelNumber > end_ch_num))
1928 continue;
1929
1930 ch_type = cds_get_channel_state(safe_channels[i].channelNumber);
1931
1932 if ((ch_type == CHANNEL_STATE_DISABLE) ||
1933 (ch_type == CHANNEL_STATE_INVALID))
1934 continue;
1935
1936 if (safe_channels[i].isSafe == true) {
1937 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
1938 FL("channel %d in the configuration is safe"),
1939 safe_channels[i].channelNumber);
1940 first_safe_ch_in_range = safe_channels[i].channelNumber;
1941 break;
1942 }
1943
1944 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
1945 FL("channel %d in the configuration is unsafe"),
1946 safe_channels[i].channelNumber);
1947 }
1948
1949 /* if no channel selected return SAP_CHANNEL_NOT_SELECTED */
1950 return first_safe_ch_in_range;
1951#endif /* !FEATURE_WLAN_CH_AVOID */
1952}
1953
1954/**
1955 * sap_select_channel() - select SAP channel
1956 * @hal: Pointer to HAL handle
1957 * @sap_ctx: Sap context
1958 * @scan_result: Pointer to tScanResultHandle
1959 *
1960 * Runs a algorithm to select the best channel to operate in based on BSS
1961 * rssi and bss count on each channel
1962 *
1963 * Returns: channel number if success, 0 otherwise
1964 */
1965uint8_t sap_select_channel(tHalHandle hal, ptSapContext sap_ctx,
1966 tScanResultHandle scan_result)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001967{
1968 /* DFS param object holding all the data req by the algo */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08001969 tSapChSelSpectInfo spect_info_obj = { NULL, 0 };
1970 tSapChSelSpectInfo *spect_info = &spect_info_obj;
1971 uint8_t best_ch_num = SAP_CHANNEL_NOT_SELECTED;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001972#ifdef SOFTAP_CHANNEL_RANGE
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001973 uint8_t count;
Naveen Rawat365d1cb2016-02-05 12:10:43 -08001974 uint32_t start_ch_num, end_ch_num, tmp_ch_num, operating_band = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001975#endif
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301976 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001977 "In %s, Running SAP Ch Select", __func__);
1978
1979#ifdef FEATURE_WLAN_CH_AVOID
Naveen Rawat365d1cb2016-02-05 12:10:43 -08001980 sap_update_unsafe_channel_list(sap_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001981#endif
1982
Naveen Rawat365d1cb2016-02-05 12:10:43 -08001983 if (NULL == scan_result) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301984 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Naveen Rawat365d1cb2016-02-05 12:10:43 -08001985 FL("No external AP present"));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001986
1987#ifndef SOFTAP_CHANNEL_RANGE
Naveen Rawat365d1cb2016-02-05 12:10:43 -08001988 return SAP_CHANNEL_NOT_SELECTED;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001989#else
Naveen Rawat365d1cb2016-02-05 12:10:43 -08001990 return sap_select_channel_no_scan_result(sap_ctx);
1991#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001992 }
1993
Naveen Rawat365d1cb2016-02-05 12:10:43 -08001994 /* Initialize the structure pointed by spect_info */
1995 if (sap_chan_sel_init(hal, spect_info, sap_ctx) != eSAP_TRUE) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301996 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
Naveen Rawat365d1cb2016-02-05 12:10:43 -08001997 FL("Ch Select initialization failed"));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001998 return SAP_CHANNEL_NOT_SELECTED;
1999 }
2000 /* Compute the weight of the entire spectrum in the operating band */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002001 sap_compute_spect_weight(spect_info, hal, scan_result, sap_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002002
2003#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
2004 /* process avoid channel IE to collect all channels to avoid */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002005 sap_process_avoid_ie(hal, sap_ctx, scan_result, spect_info);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002006#endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
2007
2008#ifdef SOFTAP_CHANNEL_RANGE
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002009 start_ch_num = sap_ctx->acs_cfg->start_ch;
2010 end_ch_num = sap_ctx->acs_cfg->end_ch;
2011 SET_ACS_BAND(operating_band, sap_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002012
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002013 sap_ctx->acsBestChannelInfo.channelNum = 0;
2014 sap_ctx->acsBestChannelInfo.weight = SAP_ACS_WEIGHT_MAX;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002015
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002016 /* Sort the ch lst as per the computed weights, lesser weight first. */
2017 sap_sort_chl_weight_all(sap_ctx, spect_info, operating_band);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002018
2019 /*Loop till get the best channel in the given range */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002020 for (count = 0; count < spect_info->numSpectChans; count++) {
2021 if ((start_ch_num > spect_info->pSpectCh[count].chNum) ||
2022 (end_ch_num < spect_info->pSpectCh[count].chNum))
2023 continue;
2024
2025 if (best_ch_num == SAP_CHANNEL_NOT_SELECTED) {
2026 best_ch_num = spect_info->pSpectCh[count].chNum;
2027 /* check if best_ch_num is in preferred channel list */
2028 best_ch_num =
2029 sap_select_preferred_channel_from_channel_list(
2030 best_ch_num, sap_ctx, spect_info);
2031 /* if not in preferred ch lst, go to nxt best ch */
2032 if (best_ch_num == SAP_CHANNEL_NOT_SELECTED)
2033 continue;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002034
2035#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002036 /*
2037 * Weight of the channels(device's AP is operating)
2038 * increased to MAX+1 so that they will be choosen only
2039 * when there is no other best channel to choose
2040 */
2041 if (sap_check_in_avoid_ch_list(sap_ctx, best_ch_num)) {
2042 best_ch_num = SAP_CHANNEL_NOT_SELECTED;
2043 continue;
2044 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002045#endif
2046
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002047 sap_ctx->acsBestChannelInfo.channelNum = best_ch_num;
2048 sap_ctx->acsBestChannelInfo.weight =
2049 spect_info->pSpectCh[count].weight_copy;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002050 }
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002051
2052 if (best_ch_num == SAP_CHANNEL_NOT_SELECTED)
2053 continue;
2054
2055 if (operating_band != eCSR_DOT11_MODE_11g)
2056 continue;
2057
2058 /* Give preference to Non-overlap channels */
2059 if (false == sap_filter_over_lap_ch(sap_ctx,
2060 spect_info->pSpectCh[count].chNum))
2061 continue;
2062
2063 tmp_ch_num = spect_info->pSpectCh[count].chNum;
2064 tmp_ch_num = sap_select_preferred_channel_from_channel_list(
2065 tmp_ch_num, sap_ctx, spect_info);
2066 if (tmp_ch_num == SAP_CHANNEL_NOT_SELECTED)
2067 continue;
2068
2069 best_ch_num = tmp_ch_num;
2070 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002071 }
2072#else
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002073 /* Sort the ch lst as per the computed weights, lesser weight first. */
2074 sap_sort_chl_weight_all(sap_ctx, hal, spect_info);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002075 /* Get the first channel in sorted array as best 20M Channel */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002076 best_ch_num = (uint8_t) spect_info->pSpectCh[0].chNum;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002077 /* Select Best Channel from Channel List if Configured */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002078 best_ch_num = sap_select_preferred_channel_from_channel_list(
2079 best_ch_num, sap_ctx, spect_info);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002080#endif
2081
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002082 /*
2083 * in case the best channel seleted is not in PCL and there is another
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002084 * channel which has same weightage and is in PCL, choose the one in
2085 * PCL
2086 */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002087 for (count = 0; count < spect_info->numSpectChans; count++) {
2088 if (!ch_in_pcl(sap_ctx, spect_info->pSpectCh[count].chNum) ||
2089 (spect_info->pSpectCh[count].weight !=
2090 sap_ctx->acsBestChannelInfo.weight))
2091 continue;
2092
2093 if (sap_select_preferred_channel_from_channel_list(
2094 spect_info->pSpectCh[count].chNum, sap_ctx, spect_info)
2095 == SAP_CHANNEL_NOT_SELECTED)
2096 continue;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002097
2098#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002099 if (sap_check_in_avoid_ch_list(sap_ctx, best_ch_num))
2100 continue;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002101#endif
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002102 best_ch_num = spect_info->pSpectCh[count].chNum;
2103 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2104 FL("change best channel to %d in PCL"), best_ch_num);
2105 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002106 }
2107
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002108 sap_ctx->acs_cfg->pri_ch = best_ch_num;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002109 /* determine secondary channel for 2.4G channel 5, 6, 7 in HT40 */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002110 if ((operating_band != eCSR_DOT11_MODE_11g) ||
2111 (sap_ctx->acs_cfg->ch_width != CH_WIDTH_40MHZ))
2112 goto sap_ch_sel_end;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002113
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002114 if ((best_ch_num >= 5) && (best_ch_num <= 7)) {
2115 int weight_below, weight_above, i;
2116 tSapSpectChInfo *pspect_info;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002117
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002118 weight_below = weight_above = SAP_ACS_WEIGHT_MAX;
2119 pspect_info = spect_info->pSpectCh;
2120 for (i = 0; i < spect_info->numSpectChans; i++) {
2121 if (pspect_info[i].chNum == (best_ch_num - 4))
2122 weight_below = pspect_info[i].weight;
2123 if (pspect_info[i].chNum == (best_ch_num + 4))
2124 weight_above = pspect_info[i].weight;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002125 }
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002126
2127 if (weight_below < weight_above)
2128 sap_ctx->acs_cfg->ht_sec_ch =
2129 sap_ctx->acs_cfg->pri_ch - 4;
2130 else
2131 sap_ctx->acs_cfg->ht_sec_ch =
2132 sap_ctx->acs_cfg->pri_ch + 4;
2133 } else if (best_ch_num >= 1 && best_ch_num <= 4) {
2134 sap_ctx->acs_cfg->ht_sec_ch = sap_ctx->acs_cfg->pri_ch + 4;
2135 } else if (best_ch_num >= 8 && best_ch_num <= 13) {
2136 sap_ctx->acs_cfg->ht_sec_ch = sap_ctx->acs_cfg->pri_ch - 4;
2137 } else if (best_ch_num == 14) {
2138 sap_ctx->acs_cfg->ht_sec_ch = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002139 }
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002140 sap_ctx->secondary_ch = sap_ctx->acs_cfg->ht_sec_ch;
2141
2142sap_ch_sel_end:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002143 /* Free all the allocated memory */
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002144 sap_chan_sel_exit(spect_info);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002145
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302146 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
Naveen Rawat365d1cb2016-02-05 12:10:43 -08002147 FL("Running SAP Ch select Completed, Ch=%d"), best_ch_num);
2148 if (best_ch_num > 0 && best_ch_num <= 252)
2149 return best_ch_num;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002150 else
2151 return SAP_CHANNEL_NOT_SELECTED;
2152}