blob: 7beea7fe5c5ad26b73e424830540fa0b0ca7586b [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Gopichand Nakkala92f07d82013-01-08 21:16:34 -08002 * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
3 *
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/*
Jeff Johnson32d95a32012-09-10 13:15:23 -070022 * Copyright (c) 2012, The Linux Foundation. All rights reserved.
Jeff Johnson295189b2012-06-20 16:38:30 -070023 *
24 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
25 *
26 *
27 * Permission to use, copy, modify, and/or distribute this software for
28 * any purpose with or without fee is hereby granted, provided that the
29 * above copyright notice and this permission notice appear in all
30 * copies.
31 *
32 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
33 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
34 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
35 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
36 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
37 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
38 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
39 * PERFORMANCE OF THIS SOFTWARE.
40 */
41
42/*
43 *
44 * Airgo Networks, Inc proprietary. All rights reserved.
45 * This file limRoamingAlgo.cc contains the code for LIM
46 * algorithms.
47 * Author: Chandra Modumudi
48 * Date: 03/01/02
49 * History:-
50 * Date Modified by Modification Information
51 * --------------------------------------------------------------------
52 *
53 */
54
Jeff Johnson295189b2012-06-20 16:38:30 -070055#include "wniCfgSta.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070056#include "cfgApi.h"
57#include "limTypes.h"
58#include "limTimerUtils.h"
Varun Reddy Yeturue3bbf6e2013-02-08 18:50:55 -080059#include "limTrace.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070060
61
62
Jeff Johnson295189b2012-06-20 16:38:30 -070063/** ----------------------------------------------------------------------
64\fn limSelectsBackgroundScanMode()
65\brief This function is called by limIsBackgroundScanAllowed().
66\ Here LIM decides whether we shall enforce this background
67\ scan or let HAL decide whether to proceed with the background
68\ scan as HAL sees fits. LIM shall enforce background scan if:
69\ 1) station is not in link established state
70\ 2) station is in link established state, but there has been
71\ max number of consecutive background scan failure.
72\
73\param tpAniSirGlobal pMac
74\return none
75\ ------------------------------------------------------------------------- */
76tSirBackgroundScanMode limSelectsBackgroundScanMode(tpAniSirGlobal pMac)
77{
78 tANI_U32 cfgVal;
79
80 if (wlan_cfgGetInt(pMac, WNI_CFG_MAX_CONSECUTIVE_BACKGROUND_SCAN_FAILURE, &cfgVal) != eSIR_SUCCESS)
81 {
Kiran Kumar Lokere5be73a62013-04-01 18:40:00 -070082 limLog(pMac, LOGP, FL("Fail to get WNI_CFG_MAX_CONSECUTIVE_BACKGROUND_SCAN_FAILURE value"));
Jeff Johnson295189b2012-06-20 16:38:30 -070083 return eSIR_NORMAL_BACKGROUND_SCAN;
84 }
85
86 if (cfgVal == 0)
87 return eSIR_NORMAL_BACKGROUND_SCAN;
88
89 /* If the "number of consecutive background scan failure"
90 * exceeds the maximum allowed, then LIM shall trigger an
91 * aggressive background scan.
92 */
93 if (pMac->lim.gLimNumOfConsecutiveBkgndScanFailure >= cfgVal)
94 {
95 pMac->lim.gLimNumOfForcedBkgndScan += 1;
96 limLog(pMac, LOGE,
Kiran Kumar Lokere5be73a62013-04-01 18:40:00 -070097 FL("Had %d consec scan fail(when expect < %d). Trigger AGGRESSIVE bkgnd scan."),
Jeff Johnson295189b2012-06-20 16:38:30 -070098 pMac->lim.gLimNumOfConsecutiveBkgndScanFailure, cfgVal);
99 return eSIR_AGGRESSIVE_BACKGROUND_SCAN;
100 }
101
102 return eSIR_NORMAL_BACKGROUND_SCAN;
103}
104
105
106/** -----------------------------------------------------------
107\fn limIsBackgroundScanAllowed
108\brief This function determines if background scan should be
109\ allowed. It is called by limTriggerBackgroundScan().
110\param tpAniSirGlobal pMac
111\return none
112\ ------------------------------------------------------------- */
113static tANI_U8 limIsBackgroundScanAllowed(tpAniSirGlobal pMac)
114{
115 // if we are in the middle of a scan already, skip the background scan
116 if (limIsSystemInScanState(pMac) ||
117 (pMac->lim.gLimBackgroundScanDisable) ||
118 (pMac->lim.gLimForceBackgroundScanDisable) ||
119 (pMac->lim.gLimBackgroundScanTerminate))
120 return false;
121
122 //need to do background scan in IBSS mode.
123 if (pMac->lim.gLimSystemRole == eLIM_STA_IN_IBSS_ROLE)
124 {
125 if (pMac->lim.gLimSmeState != eLIM_SME_NORMAL_STATE)
126 return false;
127 return true;
128 }
129
130 // If station is not in link established state, then skip background scan
131 if ( (pMac->lim.gLimSystemRole == eLIM_STA_ROLE) && (pMac->lim.gLimSmeState != eLIM_SME_LINK_EST_STATE) )
132 return false;
133
134 /* now that we have checked for scan state, check for other transitional
135 * states which should not be interrupted by scans
136 */
137 if ((! (pMac->lim.gLimSmeState == eLIM_SME_IDLE_STATE) ) &&
138 (! (pMac->lim.gLimSmeState == eLIM_SME_JOIN_FAILURE_STATE) ) &&
139 (! (pMac->lim.gLimSmeState == eLIM_SME_LINK_EST_STATE) ) )
140 return false;
141
142 return true;
143}
144
145
146/** ---------------------------------------------------------------
147\fn limTriggerBackgroundScan()
148\brief This function is called upon background scan interval
149\ when there is an exisiting link with an AP.
150\ SME_SCAN_REQ is issued to SME state machine with Active
151\ scanning is performed on one channel at a time.
152\
153\ Assumptions:
154\ Valid channel list at CFG is either populated by Roaming
155\ algorithm upon determining/selecting a regulatory domain
156\ or by default has all 36 possible channels.
157\
158\param tpAniSirGlobal pMac
159\return none
160\ ----------------------------------------------------------------- */
161void limTriggerBackgroundScan(tpAniSirGlobal pMac)
162{
163 tANI_U32 len = WNI_CFG_BG_SCAN_CHANNEL_LIST_LEN;
164 tANI_U32 ssidLen = SIR_MAC_MAX_SSID_LENGTH;
165 tSirMacChanNum bgScanChannelList[WNI_CFG_BG_SCAN_CHANNEL_LIST_LEN];
166 tSirSmeScanReq smeScanReq;
167 tSirMacAddr bcAddr = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
168 tSirBackgroundScanMode backgroundScan;
169
Kiran Kumar Lokere5be73a62013-04-01 18:40:00 -0700170 PELOG1(limLog(pMac, LOG1, FL("Background Scan: %d success, %d consec fail "),
Jeff Johnson295189b2012-06-20 16:38:30 -0700171 pMac->lim.gLimNumOfBackgroundScanSuccess, pMac->lim.gLimNumOfConsecutiveBkgndScanFailure);)
172
173 if (! limIsBackgroundScanAllowed(pMac))
174 {
Kiran Kumar Lokere5be73a62013-04-01 18:40:00 -0700175 PELOG1(limLog(pMac, LOG1, FL("Skipping Background Scan "));)
Jeff Johnson295189b2012-06-20 16:38:30 -0700176 return;
177 }
178
179 // Get background scan channel list from CFG
180 if (wlan_cfgGetStr(pMac, WNI_CFG_BG_SCAN_CHANNEL_LIST,
181 (tANI_U8 *) bgScanChannelList,
182 (tANI_U32 *) &len) != eSIR_SUCCESS)
183 {
184 /**
185 * Could not get Valid channel list from CFG.
186 * Log error.
187 */
Kiran Kumar Lokere5be73a62013-04-01 18:40:00 -0700188 PELOGE(limLog(pMac, LOGE, FL("could not retrieve valid channel list"));)
Jeff Johnson295189b2012-06-20 16:38:30 -0700189
190 return;
191 }
192
193 // Time to perform background scan. Prepare and issue
194 // SME_SCAN_REQ to SME State machine
195 smeScanReq.messageType = eWNI_SME_SCAN_REQ;
196 smeScanReq.length = sizeof(tSirSmeScanReq);
197 smeScanReq.bssType = eSIR_INFRASTRUCTURE_MODE;
198 palCopyMemory( pMac->hHdd, (tANI_U8 *) smeScanReq.bssId,
199 (tANI_U8 *) &bcAddr, sizeof(tSirMacAddr));
200
201 if (wlan_cfgGetStr(pMac, WNI_CFG_SSID,
202 (tANI_U8 *) (smeScanReq.ssId[0].ssId),
203 (tANI_U32 *) &ssidLen) != eSIR_SUCCESS)
204 {
205 /// Could not get SSID from CFG. Log error.
Kiran Kumar Lokere5be73a62013-04-01 18:40:00 -0700206 limLog(pMac, LOGP, FL("could not retrieve SSID"));
Jeff Johnson295189b2012-06-20 16:38:30 -0700207 }
208 smeScanReq.ssId[0].length = (tANI_U8) ssidLen;
209 smeScanReq.numSsid = 1;
210
211 smeScanReq.scanType = eSIR_ACTIVE_SCAN;
212 smeScanReq.sessionId = 0;
213
214 if (wlan_cfgGetInt(pMac, WNI_CFG_ACTIVE_MINIMUM_CHANNEL_TIME,
215 &smeScanReq.minChannelTime) != eSIR_SUCCESS)
216 {
217 /// Could not get minChlTime value from CFG. Log error.
Kiran Kumar Lokere5be73a62013-04-01 18:40:00 -0700218 PELOGE(limLog(pMac, LOGE, FL("could not retrieve minChlTime value"));)
Jeff Johnson295189b2012-06-20 16:38:30 -0700219
220 return;
221 }
222
223 if (wlan_cfgGetInt(pMac, WNI_CFG_ACTIVE_MAXIMUM_CHANNEL_TIME,
224 &smeScanReq.maxChannelTime) != eSIR_SUCCESS)
225 {
226 /// Could not get maxChlTime value from CFG. Log error.
Kiran Kumar Lokere5be73a62013-04-01 18:40:00 -0700227 PELOGE(limLog(pMac, LOGE, FL("could not retrieve maxChlTime value"));)
Jeff Johnson295189b2012-06-20 16:38:30 -0700228
229 return;
230 }
231
232 smeScanReq.returnAfterFirstMatch = 0;
233 smeScanReq.returnUniqueResults = 1;
234
235 //At the first channel scan, clear the cached results
236 if(pMac->lim.gLimBackgroundScanChannelId == 0)
237 {
238 smeScanReq.returnFreshResults = SIR_BG_SCAN_PURGE_RESUTLS|SIR_BG_SCAN_RETURN_FRESH_RESULTS;
239 }
240 else
241 {
242 smeScanReq.returnFreshResults = SIR_BG_SCAN_RETURN_FRESH_RESULTS;
243 }
244
245
246 smeScanReq.channelList.numChannels = 1;
247 if (pMac->lim.gLimBackgroundScanChannelId >= len)
248 {
249 pMac->lim.gLimBackgroundScanChannelId = 0;
250
Kiran Kumar Lokere5be73a62013-04-01 18:40:00 -0700251 PELOGE(limLog(pMac, LOGE, FL("Skipping Background Scan since the channel list is exhausted."));)
252 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 -0700253
254 /* Stop the BG scan timer here. SME should send WNI_CFG_BACKGROUND_SCAN_PERIOD
255 * indication to start the background scan again.
256 */
257 if (TX_TIMER_VALID(pMac->lim.limTimers.gLimBackgroundScanTimer))
258 {
Varun Reddy Yeturue3bbf6e2013-02-08 18:50:55 -0800259 MTRACE(macTrace(pMac, TRACE_CODE_TIMER_DEACTIVATE, NO_SESSION, eLIM_BACKGROUND_SCAN_TIMER));
Jeff Johnson295189b2012-06-20 16:38:30 -0700260 if (tx_timer_deactivate(&pMac->lim.limTimers.gLimBackgroundScanTimer)
261 != TX_SUCCESS)
262 {
263 // Could not deactivate BackgroundScanTimer timer.
264 // Log error
265 limLog(pMac, LOGP,
Kiran Kumar Lokere5be73a62013-04-01 18:40:00 -0700266 FL("unable to deactivate BackgroundScanTimer timer"));
Jeff Johnson295189b2012-06-20 16:38:30 -0700267 }
268 }
269
270 pMac->lim.gLimBackgroundScanTerminate = TRUE;
271
Kiran Kumar Lokere5be73a62013-04-01 18:40:00 -0700272 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 -0700273 return;
274 }
275 smeScanReq.channelList.channelNumber[0] =
276 bgScanChannelList[pMac->lim.gLimBackgroundScanChannelId++];
277
278 smeScanReq.uIEFieldLen = 0;
279 smeScanReq.uIEFieldOffset = sizeof(tSirSmeScanReq);
280
281 backgroundScan = limSelectsBackgroundScanMode(pMac);
Kiran Kumar Lokere5be73a62013-04-01 18:40:00 -0700282 PELOG1(limLog(pMac, LOG1, FL("Performing (mode %d) Background Scan "), backgroundScan);)
Jeff Johnson295189b2012-06-20 16:38:30 -0700283 smeScanReq.backgroundScanMode = backgroundScan;
284
285 //determine whether to send the results or not, If so, notify the BG scan results to SME
286 if (pMac->lim.gLimBackgroundScanChannelId >= len)
287 {
288 pMac->lim.gLimReportBackgroundScanResults = TRUE;
289 }
290
291 limPostSmeMessage(pMac,
292 eWNI_SME_SCAN_REQ,
293 (tANI_U32 *) &smeScanReq);
294} /*** limTriggerBackgroundScan() ***/
295
296
297/** ----------------------------------------------------------------------
298\fn limAbortBackgroundScan
299\brief This function aborts background scan and send scan
300\ response to SME.
301\param tpAniSirGlobal pMac
302\return none
303\ ------------------------------------------------------------------------- */
304void limAbortBackgroundScan(tpAniSirGlobal pMac)
305{
306 tANI_U16 scanRspLen = 8;
307
308 if(pMac->lim.gLimBackgroundScanTerminate == FALSE)
309 {
Kiran Kumar Lokere5be73a62013-04-01 18:40:00 -0700310 limLog(pMac, LOGE, FL("Abort Background Scan "));
Jeff Johnson295189b2012-06-20 16:38:30 -0700311 if (TX_TIMER_VALID(pMac->lim.limTimers.gLimBackgroundScanTimer))
312 {
313 limDeactivateAndChangeTimer(pMac, eLIM_BACKGROUND_SCAN_TIMER);
314 }
315
316 pMac->lim.gLimBackgroundScanTerminate = TRUE;
317 pMac->lim.gLimBackgroundScanStarted = FALSE;
318
319 if (pMac->lim.gLimSmeScanResultLength == 0)
320 limSendSmeScanRsp(pMac, scanRspLen, eSIR_SME_SUCCESS, 0, 0);
321 else
322 {
323 scanRspLen = sizeof(tSirSmeScanRsp) +
324 pMac->lim.gLimSmeScanResultLength -
325 sizeof(tSirBssDescription);
326 limSendSmeScanRsp(pMac, scanRspLen, eSIR_SME_SUCCESS, 0, 0);
327 }
328 }
329
330 // reset background scan variables
331 pMac->lim.gLimBackgroundScanChannelId = 0;
332 return;
333}
334