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
);
315 u8_t
zfScanMgrScanEventTimeout(zdev_t
* dev
)
317 u16_t nextScanFrequency
= 0;
320 zmw_get_wlan_dev(dev
);
322 zmw_declare_for_critical_section();
324 zmw_enter_critical_section(dev
);
325 if ( wd
->sta
.scanFrequency
== 0 )
327 zmw_leave_critical_section(dev
);
331 nextScanFrequency
= zfChGetNextChannel(dev
, wd
->sta
.scanFrequency
,
332 &wd
->sta
.bPassiveScan
);
334 if ( (nextScanFrequency
== 0xffff)
335 || (wd
->sta
.scanFrequency
== zfChGetLastChannel(dev
, &temp
)) )
338 u8_t isExternalScan
= 0;
339 u8_t isInternalScan
= 0;
341 //zm_debug_msg1("end scan = ", KeQueryInterruptTime());
342 wd
->sta
.scanFrequency
= 0;
344 zm_debug_msg1("scan 1 type: ", wd
->sta
.scanMgr
.currScanType
);
345 zm_debug_msg1("scan channel count = ", wd
->regulationTable
.allowChannelCnt
);
347 //zfBssInfoRefresh(dev);
348 zfTimerCancel(dev
, ZM_EVENT_TIMEOUT_SCAN
);
350 if ( wd
->sta
.bChannelScan
== FALSE
)
352 zm_debug_msg0("WOW!! scan is cancelled\n");
353 zmw_leave_critical_section(dev
);
354 goto report_scan_result
;
358 currScanType
= wd
->sta
.scanMgr
.currScanType
;
361 case ZM_SCAN_MGR_SCAN_EXTERNAL
:
364 if ( wd
->sta
.scanMgr
.scanReqs
[ZM_SCAN_MGR_SCAN_INTERNAL
- 1] )
366 wd
->sta
.scanMgr
.scanReqs
[ZM_SCAN_MGR_SCAN_INTERNAL
- 1] = 0;
372 case ZM_SCAN_MGR_SCAN_INTERNAL
:
375 if ( wd
->sta
.scanMgr
.scanReqs
[ZM_SCAN_MGR_SCAN_EXTERNAL
- 1] )
377 // Because the external scan should pre-empts internal scan.
378 // So this shall not be happened!!
389 wd
->sta
.scanMgr
.scanReqs
[currScanType
- 1] = 0;
390 wd
->sta
.scanMgr
.scanStartDelay
= 100;
391 wd
->sta
.scanMgr
.currScanType
= ZM_SCAN_MGR_SCAN_NONE
;
392 zmw_leave_critical_section(dev
);
394 //Set channel according to AP's configuration
395 zfCoreSetFrequencyEx(dev
, wd
->frequency
, wd
->BandWidth40
,
396 wd
->ExtOffset
, zfScanMgrEventScanCompleteCb
);
398 wd
->sta
.bChannelScan
= FALSE
;
400 if (zfStaIsConnected(dev
))
401 { // Finish site survey, reset the variable to detect using wrong frequency !
402 zfHpFinishSiteSurvey(dev
, 1);
403 zmw_enter_critical_section(dev
);
404 wd
->sta
.ibssSiteSurveyStatus
= 2;
405 wd
->tickIbssReceiveBeacon
= 0;
406 wd
->sta
.ibssReceiveBeaconCount
= 0;
407 zmw_leave_critical_section(dev
);
409 /* #5 Re-enable RIFS function after the site survey ! */
410 /* This is because switch band will reset the BB register to initial value */
411 if( wd
->sta
.rifsState
== ZM_RIFS_STATE_DETECTED
)
413 zfHpEnableRifs(dev
, ((wd
->sta
.currentFrequency
<3000)?1:0), wd
->sta
.EnableHT
, wd
->sta
.HT2040
);
418 zfHpFinishSiteSurvey(dev
, 0);
419 zmw_enter_critical_section(dev
);
420 wd
->sta
.ibssSiteSurveyStatus
= 0;
421 zmw_leave_critical_section(dev
);
425 /* avoid lose receive packet when site survey */
426 //if ((zfStaIsConnected(dev)) && (!zfPowerSavingMgrIsSleeping(dev)))
428 // zfSendNullData(dev, 0);
431 if ( isExternalScan
)//Quickly reboot
433 if (wd
->zfcbScanNotify
!= NULL
)
435 wd
->zfcbScanNotify(dev
, NULL
);
439 if ( isInternalScan
)
441 //wd->sta.InternalScanReq = 0;
449 wd
->sta
.scanFrequency
= nextScanFrequency
;
451 //zmw_enter_critical_section(dev);
452 zfTimerCancel(dev
, ZM_EVENT_IN_SCAN
);
453 zmw_leave_critical_section(dev
);
455 zm_debug_msg0("scan 2");
456 zfCoreSetFrequencyV2(dev
, wd
->sta
.scanFrequency
, zfScanMgrEventSetFreqCompleteCb
);
462 void zfScanMgrScanEventStart(zdev_t
* dev
)
464 zmw_get_wlan_dev(dev
);
466 zmw_declare_for_critical_section();
468 if ( wd
->sta
.bChannelScan
)
473 zfPowerSavingMgrWakeup(dev
);
475 zmw_enter_critical_section(dev
);
477 if ( wd
->sta
.scanMgr
.currScanType
== ZM_SCAN_MGR_SCAN_NONE
)
482 //zfBssInfoRefresh(dev);
483 zfBssInfoRefresh(dev
, 0);
484 wd
->sta
.bChannelScan
= TRUE
;
485 wd
->sta
.bScheduleScan
= FALSE
;
486 zfTimerCancel(dev
, ZM_EVENT_IN_SCAN
);
487 zfTimerCancel(dev
, ZM_EVENT_TIMEOUT_SCAN
);
489 //zm_debug_msg1("start scan = ", KeQueryInterruptTime());
490 wd
->sta
.scanFrequency
= zfChGetFirstChannel(dev
, &wd
->sta
.bPassiveScan
);
491 zmw_leave_critical_section(dev
);
493 /* avoid lose receive packet when site survey */
494 //if ((zfStaIsConnected(dev)) && (!zfPowerSavingMgrIsSleeping(dev)))
496 // zfSendNullData(dev, 1);
498 // zm_debug_msg0("scan 0");
499 // zfCoreSetFrequencyV2(dev, wd->sta.scanFrequency, zfScanMgrEventSetFreqCompleteCb);
501 if (zfStaIsConnected(dev
))
502 {// If doing site survey !
503 zfHpBeginSiteSurvey(dev
, 1);
504 zmw_enter_critical_section(dev
);
505 wd
->sta
.ibssSiteSurveyStatus
= 1;
506 zmw_leave_critical_section(dev
);
510 zfHpBeginSiteSurvey(dev
, 0);
511 zmw_enter_critical_section(dev
);
512 wd
->sta
.ibssSiteSurveyStatus
= 0;
513 zmw_leave_critical_section(dev
);
516 zm_debug_msg0("scan 0");
517 zfCoreSetFrequencyV2(dev
, wd
->sta
.scanFrequency
, zfScanMgrEventSetFreqCompleteCb
);
522 zmw_leave_critical_section(dev
);