2 * Copyright (c) 2007-2008 Atheros Communications Inc.
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19 void zfScanMgrInit(zdev_t* dev)
21 zmw_get_wlan_dev(dev);
23 wd->sta.scanMgr.scanReqs[0] = 0;
24 wd->sta.scanMgr.scanReqs[1] = 0;
26 wd->sta.scanMgr.currScanType = ZM_SCAN_MGR_SCAN_NONE;
27 wd->sta.scanMgr.scanStartDelay = 3;
28 //wd->sta.scanMgr.scanStartDelay = 0;
31 u8_t zfScanMgrScanStart(zdev_t* dev, u8_t scanType)
35 zmw_get_wlan_dev(dev);
37 zm_debug_msg1("scanType = ", scanType);
39 zmw_declare_for_critical_section();
41 if ( scanType != ZM_SCAN_MGR_SCAN_INTERNAL &&
42 scanType != ZM_SCAN_MGR_SCAN_EXTERNAL )
44 zm_debug_msg0("unknown scanType");
47 else if (zfStaIsConnecting(dev))
49 zm_debug_msg0("reject scan request due to connecting");
55 zmw_enter_critical_section(dev);
57 if ( wd->sta.scanMgr.scanReqs[i] == 1 )
59 zm_debug_msg1("scan rescheduled", scanType);
63 wd->sta.scanMgr.scanReqs[i] = 1;
64 zm_debug_msg1("scan scheduled: ", scanType);
66 // If there's no scan pending, we do the scan right away.
67 // If there's an internal scan and the new scan request is external one,
68 // we will restart the scan.
69 if ( wd->sta.scanMgr.currScanType == ZM_SCAN_MGR_SCAN_NONE )
73 else if ( wd->sta.scanMgr.currScanType == ZM_SCAN_MGR_SCAN_INTERNAL &&
74 scanType == ZM_SCAN_MGR_SCAN_EXTERNAL )
76 // Stop the internal scan & schedule external scan first
77 zfTimerCancel(dev, ZM_EVENT_SCAN);
79 /* Fix for WHQL sendrecv => we do not apply delay time in which the device
80 stop transmitting packet when we already connect to some AP */
81 wd->sta.bScheduleScan = FALSE;
83 zfTimerCancel(dev, ZM_EVENT_TIMEOUT_SCAN);
84 zfTimerCancel(dev, ZM_EVENT_IN_SCAN);
86 wd->sta.bChannelScan = FALSE;
91 zm_debug_msg0("Scan is busy...waiting later to start\n");
94 zmw_leave_critical_section(dev);
98 zmw_leave_critical_section(dev);
103 wd->sta.bScheduleScan = TRUE;
105 zfTimerSchedule(dev, ZM_EVENT_SCAN, wd->sta.scanMgr.scanStartDelay);
106 wd->sta.scanMgr.scanStartDelay = 3;
107 //wd->sta.scanMgr.scanStartDelay = 0;
108 wd->sta.scanMgr.currScanType = scanType;
109 zmw_leave_critical_section(dev);
111 if ((zfStaIsConnected(dev)) && (!zfPowerSavingMgrIsSleeping(dev)))
113 zfSendNullData(dev, 1);
118 void zfScanMgrScanStop(zdev_t* dev, u8_t scanType)
120 u8_t scanNotifyRequired = 0;
121 u8_t theOtherScan = ZM_SCAN_MGR_SCAN_NONE;
123 zmw_get_wlan_dev(dev);
125 zmw_declare_for_critical_section();
127 zmw_enter_critical_section(dev);
129 if ( wd->sta.scanMgr.currScanType == ZM_SCAN_MGR_SCAN_NONE )
131 zm_assert(wd->sta.scanMgr.scanReqs[0] == 0);
132 zm_assert(wd->sta.scanMgr.scanReqs[1] == 0);
138 case ZM_SCAN_MGR_SCAN_EXTERNAL:
139 scanNotifyRequired = 1;
140 theOtherScan = ZM_SCAN_MGR_SCAN_INTERNAL;
143 case ZM_SCAN_MGR_SCAN_INTERNAL:
144 theOtherScan = ZM_SCAN_MGR_SCAN_EXTERNAL;
151 if ( wd->sta.scanMgr.currScanType != scanType )
156 zfTimerCancel(dev, ZM_EVENT_SCAN);
158 /* Fix for WHQL sendrecv => we do not apply delay time in which the device
159 stop transmitting packet when we already connect to some AP */
160 wd->sta.bScheduleScan = FALSE;
162 zfTimerCancel(dev, ZM_EVENT_TIMEOUT_SCAN);
163 zfTimerCancel(dev, ZM_EVENT_IN_SCAN);
165 wd->sta.bChannelScan = FALSE;
166 wd->sta.scanFrequency = 0;
168 if ( wd->sta.scanMgr.scanReqs[theOtherScan - 1] )
170 wd->sta.scanMgr.currScanType = theOtherScan;
172 // Schedule the other scan after 1 second later
173 zfTimerSchedule(dev, ZM_EVENT_SCAN, 100);
177 wd->sta.scanMgr.currScanType = ZM_SCAN_MGR_SCAN_NONE;
181 wd->sta.scanMgr.scanReqs[scanType - 1] = 0;
183 zmw_leave_critical_section(dev);
185 /* avoid lose receive packet when site survey */
186 if ((zfStaIsConnected(dev)) && (!zfPowerSavingMgrIsSleeping(dev)))
188 zfSendNullData(dev, 0);
191 if ( scanNotifyRequired )
193 zm_debug_msg0("Scan notify after reset");
194 if (wd->zfcbScanNotify != NULL)
196 wd->zfcbScanNotify(dev, NULL);
203 zmw_leave_critical_section(dev);
207 void zfScanMgrScanAck(zdev_t* dev)
209 zmw_get_wlan_dev(dev);
211 zmw_declare_for_critical_section();
213 zmw_enter_critical_section(dev);
215 wd->sta.scanMgr.scanStartDelay = 3;
216 //wd->sta.scanMgr.scanStartDelay = 0;
218 zmw_leave_critical_section(dev);
222 extern void zfStaReconnect(zdev_t* dev);
224 static void zfScanSendProbeRequest(zdev_t* dev)
227 u16_t dst[3] = { 0xffff, 0xffff, 0xffff };
229 zmw_get_wlan_dev(dev);
231 /* Increase rxBeaconCount to prevent beacon lost */
232 if (zfStaIsConnected(dev))
234 wd->sta.rxBeaconCount++;
237 if ( wd->sta.bPassiveScan )
241 /* enable 802.l11h and in DFS Band , disable sending probe request */
242 if (wd->sta.DFSEnable)
244 if (zfHpIsDfsChannel(dev, wd->sta.scanFrequency))
250 zfSendMmFrame(dev, ZM_WLAN_FRAME_TYPE_PROBEREQ, dst, 0, 0, 0);
252 if ( wd->sta.disableProbingWithSsid )
257 for (k=1; k<=ZM_MAX_PROBE_HIDDEN_SSID_SIZE; k++)
259 if ( wd->ws.probingSsidList[k-1].ssidLen != 0 )
261 zfSendMmFrame(dev, ZM_WLAN_FRAME_TYPE_PROBEREQ, dst, k, 0, 0);
266 static void zfScanMgrEventSetFreqCompleteCb(zdev_t* dev)
268 zmw_get_wlan_dev(dev);
270 zmw_declare_for_critical_section();
272 //printk("zfScanMgrEventSetFreqCompleteCb #1\n");
274 zmw_enter_critical_section(dev);
275 zfTimerSchedule(dev, ZM_EVENT_IN_SCAN, ZM_TICK_IN_SCAN);
276 if (wd->sta.bPassiveScan)
278 zfTimerSchedule(dev, ZM_EVENT_TIMEOUT_SCAN, wd->sta.passiveScanTickPerChannel);
282 zfTimerSchedule(dev, ZM_EVENT_TIMEOUT_SCAN, wd->sta.activescanTickPerChannel);
284 zmw_leave_critical_section(dev);
286 zfScanSendProbeRequest(dev);
290 static void zfScanMgrEventScanCompleteCb(zdev_t* dev)
292 zmw_get_wlan_dev(dev);
294 if ((zfStaIsConnected(dev)) && (!zfPowerSavingMgrIsSleeping(dev)))
296 zfSendNullData(dev, 0);
302 void zfScanMgrScanEventRetry(zdev_t* dev)
304 zmw_get_wlan_dev(dev);
306 if ( !wd->sta.bChannelScan )
311 if ( !wd->sta.bPassiveScan )
313 zfScanSendProbeRequest(dev);
315 zmw_enter_critical_section(dev);
316 zfTimerSchedule(dev, ZM_EVENT_IN_SCAN, ZM_TICK_IN_SCAN);
317 zmw_leave_critical_section(dev);
322 u8_t zfScanMgrScanEventTimeout(zdev_t* dev)
324 u16_t nextScanFrequency = 0;
327 zmw_get_wlan_dev(dev);
329 zmw_declare_for_critical_section();
331 zmw_enter_critical_section(dev);
332 if ( wd->sta.scanFrequency == 0 )
334 zmw_leave_critical_section(dev);
338 nextScanFrequency = zfChGetNextChannel(dev, wd->sta.scanFrequency,
339 &wd->sta.bPassiveScan);
341 if ( (nextScanFrequency == 0xffff)
342 || (wd->sta.scanFrequency == zfChGetLastChannel(dev, &temp)) )
345 u8_t isExternalScan = 0;
346 u8_t isInternalScan = 0;
348 //zm_debug_msg1("end scan = ", KeQueryInterruptTime());
349 wd->sta.scanFrequency = 0;
351 zm_debug_msg1("scan 1 type: ", wd->sta.scanMgr.currScanType);
352 zm_debug_msg1("scan channel count = ", wd->regulationTable.allowChannelCnt);
354 //zfBssInfoRefresh(dev);
355 zfTimerCancel(dev, ZM_EVENT_TIMEOUT_SCAN);
357 if ( wd->sta.bChannelScan == FALSE )
359 zm_debug_msg0("WOW!! scan is cancelled\n");
360 zmw_leave_critical_section(dev);
361 goto report_scan_result;
365 currScanType = wd->sta.scanMgr.currScanType;
368 case ZM_SCAN_MGR_SCAN_EXTERNAL:
371 if ( wd->sta.scanMgr.scanReqs[ZM_SCAN_MGR_SCAN_INTERNAL - 1] )
373 wd->sta.scanMgr.scanReqs[ZM_SCAN_MGR_SCAN_INTERNAL - 1] = 0;
379 case ZM_SCAN_MGR_SCAN_INTERNAL:
382 if ( wd->sta.scanMgr.scanReqs[ZM_SCAN_MGR_SCAN_EXTERNAL - 1] )
384 // Because the external scan should pre-empts internal scan.
385 // So this shall not be happened!!
396 wd->sta.scanMgr.scanReqs[currScanType - 1] = 0;
397 wd->sta.scanMgr.scanStartDelay = 100;
398 wd->sta.scanMgr.currScanType = ZM_SCAN_MGR_SCAN_NONE;
399 zmw_leave_critical_section(dev);
401 //Set channel according to AP's configuration
402 zfCoreSetFrequencyEx(dev, wd->frequency, wd->BandWidth40,
403 wd->ExtOffset, zfScanMgrEventScanCompleteCb);
405 wd->sta.bChannelScan = FALSE;
408 if (zfStaIsConnected(dev))
409 { // Finish site survey, reset the variable to detect using wrong frequency !
410 zfHpFinishSiteSurvey(dev, 1);
411 zmw_enter_critical_section(dev);
412 wd->sta.ibssSiteSurveyStatus = 2;
413 wd->tickIbssReceiveBeacon = 0;
414 wd->sta.ibssReceiveBeaconCount = 0;
415 zmw_leave_critical_section(dev);
417 /* #5 Re-enable RIFS function after the site survey ! */
418 /* This is because switch band will reset the BB register to initial value */
419 if( wd->sta.rifsState == ZM_RIFS_STATE_DETECTED )
421 zfHpEnableRifs(dev, ((wd->sta.currentFrequency<3000)?1:0), wd->sta.EnableHT, wd->sta.HT2040);
426 zfHpFinishSiteSurvey(dev, 0);
427 zmw_enter_critical_section(dev);
428 wd->sta.ibssSiteSurveyStatus = 0;
429 zmw_leave_critical_section(dev);
434 /* avoid lose receive packet when site survey */
435 //if ((zfStaIsConnected(dev)) && (!zfPowerSavingMgrIsSleeping(dev)))
437 // zfSendNullData(dev, 0);
440 if ( isExternalScan )//Quickly reboot
442 if (wd->zfcbScanNotify != NULL)
444 wd->zfcbScanNotify(dev, NULL);
448 if ( isInternalScan )
450 //wd->sta.InternalScanReq = 0;
458 wd->sta.scanFrequency = nextScanFrequency;
460 //zmw_enter_critical_section(dev);
461 zfTimerCancel(dev, ZM_EVENT_IN_SCAN);
462 zmw_leave_critical_section(dev);
464 zm_debug_msg0("scan 2");
465 zfCoreSetFrequencyV2(dev, wd->sta.scanFrequency, zfScanMgrEventSetFreqCompleteCb);
471 void zfScanMgrScanEventStart(zdev_t* dev)
473 zmw_get_wlan_dev(dev);
475 zmw_declare_for_critical_section();
477 if ( wd->sta.bChannelScan )
482 zfPowerSavingMgrWakeup(dev);
484 zmw_enter_critical_section(dev);
486 if ( wd->sta.scanMgr.currScanType == ZM_SCAN_MGR_SCAN_NONE )
491 //zfBssInfoRefresh(dev);
492 zfBssInfoRefresh(dev, 0);
493 wd->sta.bChannelScan = TRUE;
494 wd->sta.bScheduleScan = FALSE;
495 zfTimerCancel(dev, ZM_EVENT_IN_SCAN);
496 zfTimerCancel(dev, ZM_EVENT_TIMEOUT_SCAN);
498 //zm_debug_msg1("start scan = ", KeQueryInterruptTime());
499 wd->sta.scanFrequency = zfChGetFirstChannel(dev, &wd->sta.bPassiveScan);
500 zmw_leave_critical_section(dev);
502 /* avoid lose receive packet when site survey */
503 //if ((zfStaIsConnected(dev)) && (!zfPowerSavingMgrIsSleeping(dev)))
505 // zfSendNullData(dev, 1);
507 // zm_debug_msg0("scan 0");
508 // zfCoreSetFrequencyV2(dev, wd->sta.scanFrequency, zfScanMgrEventSetFreqCompleteCb);
511 if (zfStaIsConnected(dev))
512 {// If doing site survey !
513 zfHpBeginSiteSurvey(dev, 1);
514 zmw_enter_critical_section(dev);
515 wd->sta.ibssSiteSurveyStatus = 1;
516 zmw_leave_critical_section(dev);
520 zfHpBeginSiteSurvey(dev, 0);
521 zmw_enter_critical_section(dev);
522 wd->sta.ibssSiteSurveyStatus = 0;
523 zmw_leave_critical_section(dev);
527 zm_debug_msg0("scan 0");
528 zfCoreSetFrequencyV2(dev, wd->sta.scanFrequency, zfScanMgrEventSetFreqCompleteCb);
533 zmw_leave_critical_section(dev);