]> bbs.cooldavid.org Git - net-next-2.6.git/blame - drivers/staging/otus/80211core/cscanmgr.c
Staging: comedi: fix EXPORT SYMBOL coding style issue in ni_labpc.c
[net-next-2.6.git] / drivers / staging / otus / 80211core / cscanmgr.c
CommitLineData
4bd43f50
LR
1/*
2 * Copyright (c) 2007-2008 Atheros Communications Inc.
3 *
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.
7 *
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.
15 */
16
17#include "cprecomp.h"
18
19void zfScanMgrInit(zdev_t* dev)
20{
21 zmw_get_wlan_dev(dev);
22
23 wd->sta.scanMgr.scanReqs[0] = 0;
24 wd->sta.scanMgr.scanReqs[1] = 0;
25
26 wd->sta.scanMgr.currScanType = ZM_SCAN_MGR_SCAN_NONE;
27 wd->sta.scanMgr.scanStartDelay = 3;
28 //wd->sta.scanMgr.scanStartDelay = 0;
29}
30
31u8_t zfScanMgrScanStart(zdev_t* dev, u8_t scanType)
32{
33 u8_t i;
34
35 zmw_get_wlan_dev(dev);
36
37 zm_debug_msg1("scanType = ", scanType);
38
39 zmw_declare_for_critical_section();
40
41 if ( scanType != ZM_SCAN_MGR_SCAN_INTERNAL &&
42 scanType != ZM_SCAN_MGR_SCAN_EXTERNAL )
43 {
44 zm_debug_msg0("unknown scanType");
45 return 1;
46 }
47 else if (zfStaIsConnecting(dev))
48 {
49 zm_debug_msg0("reject scan request due to connecting");
50 return 1;
51 }
52
53 i = scanType - 1;
54
55 zmw_enter_critical_section(dev);
56
57 if ( wd->sta.scanMgr.scanReqs[i] == 1 )
58 {
59 zm_debug_msg1("scan rescheduled", scanType);
60 goto scan_done;
61 }
62
63 wd->sta.scanMgr.scanReqs[i] = 1;
64 zm_debug_msg1("scan scheduled: ", scanType);
65
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 )
70 {
71 goto schedule_scan;
72 }
73 else if ( wd->sta.scanMgr.currScanType == ZM_SCAN_MGR_SCAN_INTERNAL &&
74 scanType == ZM_SCAN_MGR_SCAN_EXTERNAL )
75 {
76 // Stop the internal scan & schedule external scan first
77 zfTimerCancel(dev, ZM_EVENT_SCAN);
78
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;
82
83 zfTimerCancel(dev, ZM_EVENT_TIMEOUT_SCAN);
84 zfTimerCancel(dev, ZM_EVENT_IN_SCAN);
85
86 wd->sta.bChannelScan = FALSE;
87 goto schedule_scan;
88 }
89 else
90 {
91 zm_debug_msg0("Scan is busy...waiting later to start\n");
92 }
93
94 zmw_leave_critical_section(dev);
95 return 0;
96
97scan_done:
98 zmw_leave_critical_section(dev);
99 return 1;
100
101schedule_scan:
102
103 wd->sta.bScheduleScan = TRUE;
104
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);
110
111 if ((zfStaIsConnected(dev)) && (!zfPowerSavingMgrIsSleeping(dev)))
112 {
113 zfSendNullData(dev, 1);
114 }
115 return 0;
116}
117
118void zfScanMgrScanStop(zdev_t* dev, u8_t scanType)
119{
120 u8_t scanNotifyRequired = 0;
121 u8_t theOtherScan = ZM_SCAN_MGR_SCAN_NONE;
122
123 zmw_get_wlan_dev(dev);
124
125 zmw_declare_for_critical_section();
126
127 zmw_enter_critical_section(dev);
128
129 if ( wd->sta.scanMgr.currScanType == ZM_SCAN_MGR_SCAN_NONE )
130 {
131 zm_assert(wd->sta.scanMgr.scanReqs[0] == 0);
132 zm_assert(wd->sta.scanMgr.scanReqs[1] == 0);
133 goto done;
134 }
135
136 switch(scanType)
137 {
138 case ZM_SCAN_MGR_SCAN_EXTERNAL:
139 scanNotifyRequired = 1;
140 theOtherScan = ZM_SCAN_MGR_SCAN_INTERNAL;
141 break;
142
143 case ZM_SCAN_MGR_SCAN_INTERNAL:
144 theOtherScan = ZM_SCAN_MGR_SCAN_EXTERNAL;
145 break;
146
147 default:
148 goto done;
149 }
150
151 if ( wd->sta.scanMgr.currScanType != scanType )
152 {
153 goto stop_done;
154 }
155
156 zfTimerCancel(dev, ZM_EVENT_SCAN);
157
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;
161
162 zfTimerCancel(dev, ZM_EVENT_TIMEOUT_SCAN);
163 zfTimerCancel(dev, ZM_EVENT_IN_SCAN);
164
165 wd->sta.bChannelScan = FALSE;
166 wd->sta.scanFrequency = 0;
167
168 if ( wd->sta.scanMgr.scanReqs[theOtherScan - 1] )
169 {
170 wd->sta.scanMgr.currScanType = theOtherScan;
171
172 // Schedule the other scan after 1 second later
173 zfTimerSchedule(dev, ZM_EVENT_SCAN, 100);
174 }
175 else
176 {
177 wd->sta.scanMgr.currScanType = ZM_SCAN_MGR_SCAN_NONE;
178 }
179
180stop_done:
181 wd->sta.scanMgr.scanReqs[scanType - 1] = 0;
182
183 zmw_leave_critical_section(dev);
184
185 /* avoid lose receive packet when site survey */
186 if ((zfStaIsConnected(dev)) && (!zfPowerSavingMgrIsSleeping(dev)))
187 {
188 zfSendNullData(dev, 0);
189 }
190
191 if ( scanNotifyRequired )
192 {
193 zm_debug_msg0("Scan notify after reset");
194 if (wd->zfcbScanNotify != NULL)
195 {
196 wd->zfcbScanNotify(dev, NULL);
197 }
198 }
199
200 return;
201
202done:
203 zmw_leave_critical_section(dev);
204 return;
205}
206
207void zfScanMgrScanAck(zdev_t* dev)
208{
209 zmw_get_wlan_dev(dev);
210
211 zmw_declare_for_critical_section();
212
213 zmw_enter_critical_section(dev);
214
215 wd->sta.scanMgr.scanStartDelay = 3;
216 //wd->sta.scanMgr.scanStartDelay = 0;
217
218 zmw_leave_critical_section(dev);
219 return;
220}
221
222extern void zfStaReconnect(zdev_t* dev);
223
224static void zfScanSendProbeRequest(zdev_t* dev)
225{
226 u8_t k;
227 u16_t dst[3] = { 0xffff, 0xffff, 0xffff };
228
229 zmw_get_wlan_dev(dev);
230
231 /* Increase rxBeaconCount to prevent beacon lost */
232 if (zfStaIsConnected(dev))
233 {
234 wd->sta.rxBeaconCount++;
235 }
236
237 if ( wd->sta.bPassiveScan )
238 {
239 return;
240 }
241 /* enable 802.l11h and in DFS Band , disable sending probe request */
242 if (wd->sta.DFSEnable)
243 {
244 if (zfHpIsDfsChannel(dev, wd->sta.scanFrequency))
245 {
246 return;
247 }
248 }
249
250 zfSendMmFrame(dev, ZM_WLAN_FRAME_TYPE_PROBEREQ, dst, 0, 0, 0);
251
252 if ( wd->sta.disableProbingWithSsid )
253 {
254 return;
255 }
256
257 for (k=1; k<=ZM_MAX_PROBE_HIDDEN_SSID_SIZE; k++)
258 {
259 if ( wd->ws.probingSsidList[k-1].ssidLen != 0 )
260 {
261 zfSendMmFrame(dev, ZM_WLAN_FRAME_TYPE_PROBEREQ, dst, k, 0, 0);
262 }
263 }
264}
265
266static void zfScanMgrEventSetFreqCompleteCb(zdev_t* dev)
267{
268 zmw_get_wlan_dev(dev);
269
270 zmw_declare_for_critical_section();
271
272//printk("zfScanMgrEventSetFreqCompleteCb #1\n");
273
274 zmw_enter_critical_section(dev);
275 zfTimerSchedule(dev, ZM_EVENT_IN_SCAN, ZM_TICK_IN_SCAN);
276 if (wd->sta.bPassiveScan)
277 {
278 zfTimerSchedule(dev, ZM_EVENT_TIMEOUT_SCAN, wd->sta.passiveScanTickPerChannel);
279 }
280 else
281 {
282 zfTimerSchedule(dev, ZM_EVENT_TIMEOUT_SCAN, wd->sta.activescanTickPerChannel);
283 }
284 zmw_leave_critical_section(dev);
285
286 zfScanSendProbeRequest(dev);
287}
288
289
290static void zfScanMgrEventScanCompleteCb(zdev_t* dev)
291{
4bd43f50
LR
292 if ((zfStaIsConnected(dev)) && (!zfPowerSavingMgrIsSleeping(dev)))
293 {
294 zfSendNullData(dev, 0);
295 }
296 return;
297}
298
299
300void zfScanMgrScanEventRetry(zdev_t* dev)
301{
302 zmw_get_wlan_dev(dev);
303
304 if ( !wd->sta.bChannelScan )
305 {
306 return;
307 }
308
309 if ( !wd->sta.bPassiveScan )
310 {
311 zfScanSendProbeRequest(dev);
312 #if 0
313 zmw_enter_critical_section(dev);
314 zfTimerSchedule(dev, ZM_EVENT_IN_SCAN, ZM_TICK_IN_SCAN);
315 zmw_leave_critical_section(dev);
316 #endif
317 }
318}
319
320u8_t zfScanMgrScanEventTimeout(zdev_t* dev)
321{
322 u16_t nextScanFrequency = 0;
323 u8_t temp;
324
325 zmw_get_wlan_dev(dev);
326
327 zmw_declare_for_critical_section();
328
329 zmw_enter_critical_section(dev);
330 if ( wd->sta.scanFrequency == 0 )
331 {
332 zmw_leave_critical_section(dev);
333 return -1;
334 }
335
336 nextScanFrequency = zfChGetNextChannel(dev, wd->sta.scanFrequency,
337 &wd->sta.bPassiveScan);
338
339 if ( (nextScanFrequency == 0xffff)
340 || (wd->sta.scanFrequency == zfChGetLastChannel(dev, &temp)) )
341 {
342 u8_t currScanType;
343 u8_t isExternalScan = 0;
344 u8_t isInternalScan = 0;
345
346 //zm_debug_msg1("end scan = ", KeQueryInterruptTime());
347 wd->sta.scanFrequency = 0;
348
349 zm_debug_msg1("scan 1 type: ", wd->sta.scanMgr.currScanType);
350 zm_debug_msg1("scan channel count = ", wd->regulationTable.allowChannelCnt);
351
352 //zfBssInfoRefresh(dev);
353 zfTimerCancel(dev, ZM_EVENT_TIMEOUT_SCAN);
354
355 if ( wd->sta.bChannelScan == FALSE )
356 {
357 zm_debug_msg0("WOW!! scan is cancelled\n");
358 zmw_leave_critical_section(dev);
359 goto report_scan_result;
360 }
361
362
363 currScanType = wd->sta.scanMgr.currScanType;
364 switch(currScanType)
365 {
366 case ZM_SCAN_MGR_SCAN_EXTERNAL:
367 isExternalScan = 1;
368
369 if ( wd->sta.scanMgr.scanReqs[ZM_SCAN_MGR_SCAN_INTERNAL - 1] )
370 {
371 wd->sta.scanMgr.scanReqs[ZM_SCAN_MGR_SCAN_INTERNAL - 1] = 0;
372 isInternalScan = 1;
373 }
374
375 break;
376
377 case ZM_SCAN_MGR_SCAN_INTERNAL:
378 isInternalScan = 1;
379
380 if ( wd->sta.scanMgr.scanReqs[ZM_SCAN_MGR_SCAN_EXTERNAL - 1] )
381 {
382 // Because the external scan should pre-empts internal scan.
383 // So this shall not be happened!!
384 zm_assert(0);
385 }
386
387 break;
388
389 default:
390 zm_assert(0);
391 break;
392 }
393
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);
398
399 //Set channel according to AP's configuration
400 zfCoreSetFrequencyEx(dev, wd->frequency, wd->BandWidth40,
401 wd->ExtOffset, zfScanMgrEventScanCompleteCb);
402
403 wd->sta.bChannelScan = FALSE;
404
405 #if 1
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);
414
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 )
418 {
419 zfHpEnableRifs(dev, ((wd->sta.currentFrequency<3000)?1:0), wd->sta.EnableHT, wd->sta.HT2040);
420 }
421 }
422 else
423 {
424 zfHpFinishSiteSurvey(dev, 0);
425 zmw_enter_critical_section(dev);
426 wd->sta.ibssSiteSurveyStatus = 0;
427 zmw_leave_critical_section(dev);
428 }
429 #endif
430
431report_scan_result:
432 /* avoid lose receive packet when site survey */
433 //if ((zfStaIsConnected(dev)) && (!zfPowerSavingMgrIsSleeping(dev)))
434 //{
435 // zfSendNullData(dev, 0);
436 //}
437
438 if ( isExternalScan )//Quickly reboot
439 {
440 if (wd->zfcbScanNotify != NULL)
441 {
442 wd->zfcbScanNotify(dev, NULL);
443 }
444 }
445
446 if ( isInternalScan )
447 {
448 //wd->sta.InternalScanReq = 0;
449 zfStaReconnect(dev);
450 }
451
452 return 0;
453 }
454 else
455 {
456 wd->sta.scanFrequency = nextScanFrequency;
457
458 //zmw_enter_critical_section(dev);
459 zfTimerCancel(dev, ZM_EVENT_IN_SCAN);
460 zmw_leave_critical_section(dev);
461
462 zm_debug_msg0("scan 2");
463 zfCoreSetFrequencyV2(dev, wd->sta.scanFrequency, zfScanMgrEventSetFreqCompleteCb);
464
465 return 1;
466 }
467}
468
469void zfScanMgrScanEventStart(zdev_t* dev)
470{
471 zmw_get_wlan_dev(dev);
472
473 zmw_declare_for_critical_section();
474
475 if ( wd->sta.bChannelScan )
476 {
477 return;
478 }
479
480 zfPowerSavingMgrWakeup(dev);
481
482 zmw_enter_critical_section(dev);
483
484 if ( wd->sta.scanMgr.currScanType == ZM_SCAN_MGR_SCAN_NONE )
485 {
486 goto no_scan;
487 }
488
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);
495
496 //zm_debug_msg1("start scan = ", KeQueryInterruptTime());
497 wd->sta.scanFrequency = zfChGetFirstChannel(dev, &wd->sta.bPassiveScan);
498 zmw_leave_critical_section(dev);
499
500 /* avoid lose receive packet when site survey */
501 //if ((zfStaIsConnected(dev)) && (!zfPowerSavingMgrIsSleeping(dev)))
502 //{
503 // zfSendNullData(dev, 1);
504 //}
505// zm_debug_msg0("scan 0");
506// zfCoreSetFrequencyV2(dev, wd->sta.scanFrequency, zfScanMgrEventSetFreqCompleteCb);
507
508 #if 1
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);
515 }
516 else
517 {
518 zfHpBeginSiteSurvey(dev, 0);
519 zmw_enter_critical_section(dev);
520 wd->sta.ibssSiteSurveyStatus = 0;
521 zmw_leave_critical_section(dev);
522 }
523 #endif
524
525 zm_debug_msg0("scan 0");
526 zfCoreSetFrequencyV2(dev, wd->sta.scanFrequency, zfScanMgrEventSetFreqCompleteCb);
527
528 return;
529
530no_scan:
531 zmw_leave_critical_section(dev);
532 return;
533}