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 if ((zfStaIsConnected(dev
)) && (!zfPowerSavingMgrIsSleeping(dev
)))
294 zfSendNullData(dev
, 0);
300 void zfScanMgrScanEventRetry(zdev_t
* dev
)
302 zmw_get_wlan_dev(dev
);
304 if ( !wd
->sta
.bChannelScan
)
309 if ( !wd
->sta
.bPassiveScan
)
311 zfScanSendProbeRequest(dev
);
313 zmw_enter_critical_section(dev
);
314 zfTimerSchedule(dev
, ZM_EVENT_IN_SCAN
, ZM_TICK_IN_SCAN
);
315 zmw_leave_critical_section(dev
);
320 u8_t
zfScanMgrScanEventTimeout(zdev_t
* dev
)
322 u16_t nextScanFrequency
= 0;
325 zmw_get_wlan_dev(dev
);
327 zmw_declare_for_critical_section();
329 zmw_enter_critical_section(dev
);
330 if ( wd
->sta
.scanFrequency
== 0 )
332 zmw_leave_critical_section(dev
);
336 nextScanFrequency
= zfChGetNextChannel(dev
, wd
->sta
.scanFrequency
,
337 &wd
->sta
.bPassiveScan
);
339 if ( (nextScanFrequency
== 0xffff)
340 || (wd
->sta
.scanFrequency
== zfChGetLastChannel(dev
, &temp
)) )
343 u8_t isExternalScan
= 0;
344 u8_t isInternalScan
= 0;
346 //zm_debug_msg1("end scan = ", KeQueryInterruptTime());
347 wd
->sta
.scanFrequency
= 0;
349 zm_debug_msg1("scan 1 type: ", wd
->sta
.scanMgr
.currScanType
);
350 zm_debug_msg1("scan channel count = ", wd
->regulationTable
.allowChannelCnt
);
352 //zfBssInfoRefresh(dev);
353 zfTimerCancel(dev
, ZM_EVENT_TIMEOUT_SCAN
);
355 if ( wd
->sta
.bChannelScan
== FALSE
)
357 zm_debug_msg0("WOW!! scan is cancelled\n");
358 zmw_leave_critical_section(dev
);
359 goto report_scan_result
;
363 currScanType
= wd
->sta
.scanMgr
.currScanType
;
366 case ZM_SCAN_MGR_SCAN_EXTERNAL
:
369 if ( wd
->sta
.scanMgr
.scanReqs
[ZM_SCAN_MGR_SCAN_INTERNAL
- 1] )
371 wd
->sta
.scanMgr
.scanReqs
[ZM_SCAN_MGR_SCAN_INTERNAL
- 1] = 0;
377 case ZM_SCAN_MGR_SCAN_INTERNAL
:
380 if ( wd
->sta
.scanMgr
.scanReqs
[ZM_SCAN_MGR_SCAN_EXTERNAL
- 1] )
382 // Because the external scan should pre-empts internal scan.
383 // So this shall not be happened!!
394 wd
->sta
.scanMgr
.scanReqs
[currScanType
- 1] = 0;
395 wd
->sta
.scanMgr
.scanStartDelay
= 100;
396 wd
->sta
.scanMgr
.currScanType
= ZM_SCAN_MGR_SCAN_NONE
;
397 zmw_leave_critical_section(dev
);
399 //Set channel according to AP's configuration
400 zfCoreSetFrequencyEx(dev
, wd
->frequency
, wd
->BandWidth40
,
401 wd
->ExtOffset
, zfScanMgrEventScanCompleteCb
);
403 wd
->sta
.bChannelScan
= FALSE
;
406 if (zfStaIsConnected(dev
))
407 { // Finish site survey, reset the variable to detect using wrong frequency !
408 zfHpFinishSiteSurvey(dev
, 1);
409 zmw_enter_critical_section(dev
);
410 wd
->sta
.ibssSiteSurveyStatus
= 2;
411 wd
->tickIbssReceiveBeacon
= 0;
412 wd
->sta
.ibssReceiveBeaconCount
= 0;
413 zmw_leave_critical_section(dev
);
415 /* #5 Re-enable RIFS function after the site survey ! */
416 /* This is because switch band will reset the BB register to initial value */
417 if( wd
->sta
.rifsState
== ZM_RIFS_STATE_DETECTED
)
419 zfHpEnableRifs(dev
, ((wd
->sta
.currentFrequency
<3000)?1:0), wd
->sta
.EnableHT
, wd
->sta
.HT2040
);
424 zfHpFinishSiteSurvey(dev
, 0);
425 zmw_enter_critical_section(dev
);
426 wd
->sta
.ibssSiteSurveyStatus
= 0;
427 zmw_leave_critical_section(dev
);
432 /* avoid lose receive packet when site survey */
433 //if ((zfStaIsConnected(dev)) && (!zfPowerSavingMgrIsSleeping(dev)))
435 // zfSendNullData(dev, 0);
438 if ( isExternalScan
)//Quickly reboot
440 if (wd
->zfcbScanNotify
!= NULL
)
442 wd
->zfcbScanNotify(dev
, NULL
);
446 if ( isInternalScan
)
448 //wd->sta.InternalScanReq = 0;
456 wd
->sta
.scanFrequency
= nextScanFrequency
;
458 //zmw_enter_critical_section(dev);
459 zfTimerCancel(dev
, ZM_EVENT_IN_SCAN
);
460 zmw_leave_critical_section(dev
);
462 zm_debug_msg0("scan 2");
463 zfCoreSetFrequencyV2(dev
, wd
->sta
.scanFrequency
, zfScanMgrEventSetFreqCompleteCb
);
469 void zfScanMgrScanEventStart(zdev_t
* dev
)
471 zmw_get_wlan_dev(dev
);
473 zmw_declare_for_critical_section();
475 if ( wd
->sta
.bChannelScan
)
480 zfPowerSavingMgrWakeup(dev
);
482 zmw_enter_critical_section(dev
);
484 if ( wd
->sta
.scanMgr
.currScanType
== ZM_SCAN_MGR_SCAN_NONE
)
489 //zfBssInfoRefresh(dev);
490 zfBssInfoRefresh(dev
, 0);
491 wd
->sta
.bChannelScan
= TRUE
;
492 wd
->sta
.bScheduleScan
= FALSE
;
493 zfTimerCancel(dev
, ZM_EVENT_IN_SCAN
);
494 zfTimerCancel(dev
, ZM_EVENT_TIMEOUT_SCAN
);
496 //zm_debug_msg1("start scan = ", KeQueryInterruptTime());
497 wd
->sta
.scanFrequency
= zfChGetFirstChannel(dev
, &wd
->sta
.bPassiveScan
);
498 zmw_leave_critical_section(dev
);
500 /* avoid lose receive packet when site survey */
501 //if ((zfStaIsConnected(dev)) && (!zfPowerSavingMgrIsSleeping(dev)))
503 // zfSendNullData(dev, 1);
505 // zm_debug_msg0("scan 0");
506 // zfCoreSetFrequencyV2(dev, wd->sta.scanFrequency, zfScanMgrEventSetFreqCompleteCb);
509 if (zfStaIsConnected(dev
))
510 {// If doing site survey !
511 zfHpBeginSiteSurvey(dev
, 1);
512 zmw_enter_critical_section(dev
);
513 wd
->sta
.ibssSiteSurveyStatus
= 1;
514 zmw_leave_critical_section(dev
);
518 zfHpBeginSiteSurvey(dev
, 0);
519 zmw_enter_critical_section(dev
);
520 wd
->sta
.ibssSiteSurveyStatus
= 0;
521 zmw_leave_critical_section(dev
);
525 zm_debug_msg0("scan 0");
526 zfCoreSetFrequencyV2(dev
, wd
->sta
.scanFrequency
, zfScanMgrEventSetFreqCompleteCb
);
531 zmw_leave_critical_section(dev
);