blob: 4a0f06759fd13768de48d171f988d07e5bb6d29a [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Satyanarayana Dash6f438272015-03-03 18:01:06 +05302 * Copyright (c) 2011-2015 The Linux Foundation. All rights reserved.
Kiet Lam842dad02014-02-18 18:44:02 -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.
Gopichand Nakkala92f07d82013-01-08 21:16:34 -080020 */
Kiet Lam842dad02014-02-18 18:44:02 -080021
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
Gopichand Nakkala92f07d82013-01-08 21:16:34 -080028/*
Jeff Johnson295189b2012-06-20 16:38:30 -070029 *
Jeff Johnson295189b2012-06-20 16:38:30 -070030 * This file limRoamingAlgo.cc contains the code for LIM
31 * algorithms.
32 * Author: Chandra Modumudi
33 * Date: 03/01/02
34 * History:-
35 * Date Modified by Modification Information
36 * --------------------------------------------------------------------
37 *
38 */
39
Satyanarayana Dash6f438272015-03-03 18:01:06 +053040#include "wniCfg.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070041#include "cfgApi.h"
42#include "limTypes.h"
43#include "limTimerUtils.h"
Varun Reddy Yeturue3bbf6e2013-02-08 18:50:55 -080044#include "limTrace.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070045
46
47
Jeff Johnson295189b2012-06-20 16:38:30 -070048/** ----------------------------------------------------------------------
49\fn limSelectsBackgroundScanMode()
50\brief This function is called by limIsBackgroundScanAllowed().
51\ Here LIM decides whether we shall enforce this background
52\ scan or let HAL decide whether to proceed with the background
53\ scan as HAL sees fits. LIM shall enforce background scan if:
54\ 1) station is not in link established state
55\ 2) station is in link established state, but there has been
56\ max number of consecutive background scan failure.
57\
58\param tpAniSirGlobal pMac
59\return none
60\ ------------------------------------------------------------------------- */
61tSirBackgroundScanMode limSelectsBackgroundScanMode(tpAniSirGlobal pMac)
62{
63 tANI_U32 cfgVal;
64
65 if (wlan_cfgGetInt(pMac, WNI_CFG_MAX_CONSECUTIVE_BACKGROUND_SCAN_FAILURE, &cfgVal) != eSIR_SUCCESS)
66 {
Kiran Kumar Lokere5be73a62013-04-01 18:40:00 -070067 limLog(pMac, LOGP, FL("Fail to get WNI_CFG_MAX_CONSECUTIVE_BACKGROUND_SCAN_FAILURE value"));
Jeff Johnson295189b2012-06-20 16:38:30 -070068 return eSIR_NORMAL_BACKGROUND_SCAN;
69 }
70
71 if (cfgVal == 0)
72 return eSIR_NORMAL_BACKGROUND_SCAN;
73
74 /* If the "number of consecutive background scan failure"
75 * exceeds the maximum allowed, then LIM shall trigger an
76 * aggressive background scan.
77 */
78 if (pMac->lim.gLimNumOfConsecutiveBkgndScanFailure >= cfgVal)
79 {
80 pMac->lim.gLimNumOfForcedBkgndScan += 1;
81 limLog(pMac, LOGE,
Kiran Kumar Lokere5be73a62013-04-01 18:40:00 -070082 FL("Had %d consec scan fail(when expect < %d). Trigger AGGRESSIVE bkgnd scan."),
Jeff Johnson295189b2012-06-20 16:38:30 -070083 pMac->lim.gLimNumOfConsecutiveBkgndScanFailure, cfgVal);
84 return eSIR_AGGRESSIVE_BACKGROUND_SCAN;
85 }
86
87 return eSIR_NORMAL_BACKGROUND_SCAN;
88}
89
90
91/** -----------------------------------------------------------
92\fn limIsBackgroundScanAllowed
93\brief This function determines if background scan should be
94\ allowed. It is called by limTriggerBackgroundScan().
95\param tpAniSirGlobal pMac
96\return none
97\ ------------------------------------------------------------- */
98static tANI_U8 limIsBackgroundScanAllowed(tpAniSirGlobal pMac)
99{
100 // if we are in the middle of a scan already, skip the background scan
101 if (limIsSystemInScanState(pMac) ||
102 (pMac->lim.gLimBackgroundScanDisable) ||
103 (pMac->lim.gLimForceBackgroundScanDisable) ||
104 (pMac->lim.gLimBackgroundScanTerminate))
105 return false;
106
107 //need to do background scan in IBSS mode.
108 if (pMac->lim.gLimSystemRole == eLIM_STA_IN_IBSS_ROLE)
109 {
110 if (pMac->lim.gLimSmeState != eLIM_SME_NORMAL_STATE)
111 return false;
112 return true;
113 }
114
115 // If station is not in link established state, then skip background scan
116 if ( (pMac->lim.gLimSystemRole == eLIM_STA_ROLE) && (pMac->lim.gLimSmeState != eLIM_SME_LINK_EST_STATE) )
117 return false;
118
119 /* now that we have checked for scan state, check for other transitional
120 * states which should not be interrupted by scans
121 */
122 if ((! (pMac->lim.gLimSmeState == eLIM_SME_IDLE_STATE) ) &&
123 (! (pMac->lim.gLimSmeState == eLIM_SME_JOIN_FAILURE_STATE) ) &&
124 (! (pMac->lim.gLimSmeState == eLIM_SME_LINK_EST_STATE) ) )
125 return false;
126
127 return true;
128}
129
130
131/** ---------------------------------------------------------------
132\fn limTriggerBackgroundScan()
133\brief This function is called upon background scan interval
134\ when there is an exisiting link with an AP.
135\ SME_SCAN_REQ is issued to SME state machine with Active
136\ scanning is performed on one channel at a time.
137\
138\ Assumptions:
139\ Valid channel list at CFG is either populated by Roaming
140\ algorithm upon determining/selecting a regulatory domain
141\ or by default has all 36 possible channels.
142\
143\param tpAniSirGlobal pMac
144\return none
145\ ----------------------------------------------------------------- */
146void limTriggerBackgroundScan(tpAniSirGlobal pMac)
147{
148 tANI_U32 len = WNI_CFG_BG_SCAN_CHANNEL_LIST_LEN;
149 tANI_U32 ssidLen = SIR_MAC_MAX_SSID_LENGTH;
150 tSirMacChanNum bgScanChannelList[WNI_CFG_BG_SCAN_CHANNEL_LIST_LEN];
151 tSirSmeScanReq smeScanReq;
152 tSirMacAddr bcAddr = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
153 tSirBackgroundScanMode backgroundScan;
154
Abhishek Singh3cbf6052014-12-15 16:46:42 +0530155 limLog(pMac, LOG1, FL("Background Scan: %d success, %d consec fail "),
156 pMac->lim.gLimNumOfBackgroundScanSuccess, pMac->lim.gLimNumOfConsecutiveBkgndScanFailure);
Jeff Johnson295189b2012-06-20 16:38:30 -0700157
158 if (! limIsBackgroundScanAllowed(pMac))
159 {
Kiran Kumar Lokere5be73a62013-04-01 18:40:00 -0700160 PELOG1(limLog(pMac, LOG1, FL("Skipping Background Scan "));)
Jeff Johnson295189b2012-06-20 16:38:30 -0700161 return;
162 }
163
164 // Get background scan channel list from CFG
165 if (wlan_cfgGetStr(pMac, WNI_CFG_BG_SCAN_CHANNEL_LIST,
166 (tANI_U8 *) bgScanChannelList,
167 (tANI_U32 *) &len) != eSIR_SUCCESS)
168 {
169 /**
170 * Could not get Valid channel list from CFG.
171 * Log error.
172 */
Kiran Kumar Lokere5be73a62013-04-01 18:40:00 -0700173 PELOGE(limLog(pMac, LOGE, FL("could not retrieve valid channel list"));)
Jeff Johnson295189b2012-06-20 16:38:30 -0700174
175 return;
176 }
177
178 // Time to perform background scan. Prepare and issue
179 // SME_SCAN_REQ to SME State machine
180 smeScanReq.messageType = eWNI_SME_SCAN_REQ;
181 smeScanReq.length = sizeof(tSirSmeScanReq);
182 smeScanReq.bssType = eSIR_INFRASTRUCTURE_MODE;
Madan Mohan Koyyalamudi9e8ce1f2013-07-11 10:40:43 +0530183 vos_mem_copy( (tANI_U8 *) smeScanReq.bssId,
Jeff Johnson295189b2012-06-20 16:38:30 -0700184 (tANI_U8 *) &bcAddr, sizeof(tSirMacAddr));
185
186 if (wlan_cfgGetStr(pMac, WNI_CFG_SSID,
187 (tANI_U8 *) (smeScanReq.ssId[0].ssId),
188 (tANI_U32 *) &ssidLen) != eSIR_SUCCESS)
189 {
190 /// Could not get SSID from CFG. Log error.
Kiran Kumar Lokere5be73a62013-04-01 18:40:00 -0700191 limLog(pMac, LOGP, FL("could not retrieve SSID"));
Jeff Johnson295189b2012-06-20 16:38:30 -0700192 }
193 smeScanReq.ssId[0].length = (tANI_U8) ssidLen;
194 smeScanReq.numSsid = 1;
195
196 smeScanReq.scanType = eSIR_ACTIVE_SCAN;
197 smeScanReq.sessionId = 0;
198
199 if (wlan_cfgGetInt(pMac, WNI_CFG_ACTIVE_MINIMUM_CHANNEL_TIME,
200 &smeScanReq.minChannelTime) != eSIR_SUCCESS)
201 {
202 /// Could not get minChlTime value from CFG. Log error.
Kiran Kumar Lokere5be73a62013-04-01 18:40:00 -0700203 PELOGE(limLog(pMac, LOGE, FL("could not retrieve minChlTime value"));)
Jeff Johnson295189b2012-06-20 16:38:30 -0700204
205 return;
206 }
207
208 if (wlan_cfgGetInt(pMac, WNI_CFG_ACTIVE_MAXIMUM_CHANNEL_TIME,
209 &smeScanReq.maxChannelTime) != eSIR_SUCCESS)
210 {
211 /// Could not get maxChlTime value from CFG. Log error.
Kiran Kumar Lokere5be73a62013-04-01 18:40:00 -0700212 PELOGE(limLog(pMac, LOGE, FL("could not retrieve maxChlTime value"));)
Jeff Johnson295189b2012-06-20 16:38:30 -0700213
214 return;
215 }
216
217 smeScanReq.returnAfterFirstMatch = 0;
218 smeScanReq.returnUniqueResults = 1;
219
220 //At the first channel scan, clear the cached results
221 if(pMac->lim.gLimBackgroundScanChannelId == 0)
222 {
223 smeScanReq.returnFreshResults = SIR_BG_SCAN_PURGE_RESUTLS|SIR_BG_SCAN_RETURN_FRESH_RESULTS;
224 }
225 else
226 {
227 smeScanReq.returnFreshResults = SIR_BG_SCAN_RETURN_FRESH_RESULTS;
228 }
229
230
231 smeScanReq.channelList.numChannels = 1;
232 if (pMac->lim.gLimBackgroundScanChannelId >= len)
233 {
234 pMac->lim.gLimBackgroundScanChannelId = 0;
235
Kiran Kumar Lokere5be73a62013-04-01 18:40:00 -0700236 PELOGE(limLog(pMac, LOGE, FL("Skipping Background Scan since the channel list is exhausted."));)
237 PELOGE(limLog(pMac, LOGE, FL("SME should send WNI_CFG_BACKGROUND_SCAN_PERIOD indication to start the background scan again."));)
Jeff Johnson295189b2012-06-20 16:38:30 -0700238
239 /* Stop the BG scan timer here. SME should send WNI_CFG_BACKGROUND_SCAN_PERIOD
240 * indication to start the background scan again.
241 */
242 if (TX_TIMER_VALID(pMac->lim.limTimers.gLimBackgroundScanTimer))
243 {
Varun Reddy Yeturue3bbf6e2013-02-08 18:50:55 -0800244 MTRACE(macTrace(pMac, TRACE_CODE_TIMER_DEACTIVATE, NO_SESSION, eLIM_BACKGROUND_SCAN_TIMER));
Jeff Johnson295189b2012-06-20 16:38:30 -0700245 if (tx_timer_deactivate(&pMac->lim.limTimers.gLimBackgroundScanTimer)
246 != TX_SUCCESS)
247 {
248 // Could not deactivate BackgroundScanTimer timer.
249 // Log error
250 limLog(pMac, LOGP,
Kiran Kumar Lokere5be73a62013-04-01 18:40:00 -0700251 FL("unable to deactivate BackgroundScanTimer timer"));
Jeff Johnson295189b2012-06-20 16:38:30 -0700252 }
253 }
254
255 pMac->lim.gLimBackgroundScanTerminate = TRUE;
256
Kiran Kumar Lokere5be73a62013-04-01 18:40:00 -0700257 PELOGE(limLog(pMac, LOGE, FL("Send dummy scan with returnFreshResults as 0 to report BG scan results to SME."));)
Jeff Johnson295189b2012-06-20 16:38:30 -0700258 return;
259 }
260 smeScanReq.channelList.channelNumber[0] =
261 bgScanChannelList[pMac->lim.gLimBackgroundScanChannelId++];
262
263 smeScanReq.uIEFieldLen = 0;
264 smeScanReq.uIEFieldOffset = sizeof(tSirSmeScanReq);
265
266 backgroundScan = limSelectsBackgroundScanMode(pMac);
Sushant Kaushike0d2cce2014-04-10 14:36:07 +0530267 PELOG1(limLog(pMac, LOG1, FL("Performing (mode %s (%d)) Background Scan"),
268 lim_BackgroundScanModetoString(backgroundScan),
269 backgroundScan);)
Jeff Johnson295189b2012-06-20 16:38:30 -0700270 smeScanReq.backgroundScanMode = backgroundScan;
271
272 //determine whether to send the results or not, If so, notify the BG scan results to SME
273 if (pMac->lim.gLimBackgroundScanChannelId >= len)
274 {
275 pMac->lim.gLimReportBackgroundScanResults = TRUE;
276 }
277
278 limPostSmeMessage(pMac,
279 eWNI_SME_SCAN_REQ,
280 (tANI_U32 *) &smeScanReq);
281} /*** limTriggerBackgroundScan() ***/
282
283
284/** ----------------------------------------------------------------------
285\fn limAbortBackgroundScan
286\brief This function aborts background scan and send scan
287\ response to SME.
288\param tpAniSirGlobal pMac
289\return none
290\ ------------------------------------------------------------------------- */
291void limAbortBackgroundScan(tpAniSirGlobal pMac)
292{
293 tANI_U16 scanRspLen = 8;
294
295 if(pMac->lim.gLimBackgroundScanTerminate == FALSE)
296 {
Kiran Kumar Lokere5be73a62013-04-01 18:40:00 -0700297 limLog(pMac, LOGE, FL("Abort Background Scan "));
Jeff Johnson295189b2012-06-20 16:38:30 -0700298 if (TX_TIMER_VALID(pMac->lim.limTimers.gLimBackgroundScanTimer))
299 {
300 limDeactivateAndChangeTimer(pMac, eLIM_BACKGROUND_SCAN_TIMER);
301 }
302
303 pMac->lim.gLimBackgroundScanTerminate = TRUE;
304 pMac->lim.gLimBackgroundScanStarted = FALSE;
305
306 if (pMac->lim.gLimSmeScanResultLength == 0)
307 limSendSmeScanRsp(pMac, scanRspLen, eSIR_SME_SUCCESS, 0, 0);
308 else
309 {
310 scanRspLen = sizeof(tSirSmeScanRsp) +
311 pMac->lim.gLimSmeScanResultLength -
312 sizeof(tSirBssDescription);
313 limSendSmeScanRsp(pMac, scanRspLen, eSIR_SME_SUCCESS, 0, 0);
314 }
315 }
316
317 // reset background scan variables
318 pMac->lim.gLimBackgroundScanChannelId = 0;
319 return;
320}
321