Staging: add otus Atheros wireless network driver
[linux-2.6] / drivers / staging / otus / 80211core / cscanmgr.c
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
19 void 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
31 u8_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
97 scan_done:
98     zmw_leave_critical_section(dev);
99     return 1;
100
101 schedule_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
118 void 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
180 stop_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
202 done:
203     zmw_leave_critical_section(dev);
204     return;
205 }
206
207 void 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
222 extern void zfStaReconnect(zdev_t* dev);
223
224 static 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
266 static 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
290 static void zfScanMgrEventScanCompleteCb(zdev_t* dev)
291 {
292     zmw_get_wlan_dev(dev);
293
294     if ((zfStaIsConnected(dev)) && (!zfPowerSavingMgrIsSleeping(dev)))
295     {
296         zfSendNullData(dev, 0);
297     }
298     return;
299 }
300
301
302 void zfScanMgrScanEventRetry(zdev_t* dev)
303 {
304     zmw_get_wlan_dev(dev);
305
306     if ( !wd->sta.bChannelScan )
307     {
308         return;
309     }
310
311     if ( !wd->sta.bPassiveScan )
312     {
313         zfScanSendProbeRequest(dev);
314         #if 0
315         zmw_enter_critical_section(dev);
316         zfTimerSchedule(dev, ZM_EVENT_IN_SCAN, ZM_TICK_IN_SCAN);
317         zmw_leave_critical_section(dev);
318         #endif
319     }
320 }
321
322 u8_t zfScanMgrScanEventTimeout(zdev_t* dev)
323 {
324     u16_t   nextScanFrequency = 0;
325     u8_t    temp;
326
327     zmw_get_wlan_dev(dev);
328
329     zmw_declare_for_critical_section();
330
331     zmw_enter_critical_section(dev);
332     if ( wd->sta.scanFrequency == 0 )
333     {
334         zmw_leave_critical_section(dev);
335         return -1;
336     }
337
338     nextScanFrequency = zfChGetNextChannel(dev, wd->sta.scanFrequency,
339                                            &wd->sta.bPassiveScan);
340
341     if ( (nextScanFrequency == 0xffff)
342          || (wd->sta.scanFrequency == zfChGetLastChannel(dev, &temp)) )
343     {
344         u8_t currScanType;
345         u8_t isExternalScan = 0;
346         u8_t isInternalScan = 0;
347
348         //zm_debug_msg1("end scan = ", KeQueryInterruptTime());
349         wd->sta.scanFrequency = 0;
350
351         zm_debug_msg1("scan 1 type: ", wd->sta.scanMgr.currScanType);
352         zm_debug_msg1("scan channel count = ", wd->regulationTable.allowChannelCnt);
353
354         //zfBssInfoRefresh(dev);
355         zfTimerCancel(dev, ZM_EVENT_TIMEOUT_SCAN);
356
357         if ( wd->sta.bChannelScan == FALSE )
358         {
359             zm_debug_msg0("WOW!! scan is cancelled\n");
360             zmw_leave_critical_section(dev);
361             goto report_scan_result;
362         }
363
364
365         currScanType = wd->sta.scanMgr.currScanType;
366         switch(currScanType)
367         {
368             case ZM_SCAN_MGR_SCAN_EXTERNAL:
369                 isExternalScan = 1;
370
371                 if ( wd->sta.scanMgr.scanReqs[ZM_SCAN_MGR_SCAN_INTERNAL - 1] )
372                 {
373                     wd->sta.scanMgr.scanReqs[ZM_SCAN_MGR_SCAN_INTERNAL - 1] = 0;
374                     isInternalScan = 1;
375                 }
376
377                 break;
378
379             case ZM_SCAN_MGR_SCAN_INTERNAL:
380                 isInternalScan = 1;
381
382                 if ( wd->sta.scanMgr.scanReqs[ZM_SCAN_MGR_SCAN_EXTERNAL - 1] )
383                 {
384                     // Because the external scan should pre-empts internal scan.
385                     // So this shall not be happened!!
386                     zm_assert(0);
387                 }
388
389                 break;
390
391             default:
392                 zm_assert(0);
393                 break;
394         }
395
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);
400
401         //Set channel according to AP's configuration
402         zfCoreSetFrequencyEx(dev, wd->frequency, wd->BandWidth40,
403                 wd->ExtOffset, zfScanMgrEventScanCompleteCb);
404
405         wd->sta.bChannelScan = FALSE;
406
407         #if 1
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);
416
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 )
420             {
421                 zfHpEnableRifs(dev, ((wd->sta.currentFrequency<3000)?1:0), wd->sta.EnableHT, wd->sta.HT2040);
422             }
423         }
424         else
425         {
426             zfHpFinishSiteSurvey(dev, 0);
427             zmw_enter_critical_section(dev);
428             wd->sta.ibssSiteSurveyStatus = 0;
429             zmw_leave_critical_section(dev);
430         }
431         #endif
432
433 report_scan_result:
434         /* avoid lose receive packet when site survey */
435         //if ((zfStaIsConnected(dev)) && (!zfPowerSavingMgrIsSleeping(dev)))
436         //{
437         //    zfSendNullData(dev, 0);
438         //}
439
440         if ( isExternalScan )//Quickly reboot
441         {
442             if (wd->zfcbScanNotify != NULL)
443             {
444                 wd->zfcbScanNotify(dev, NULL);
445             }
446         }
447
448         if ( isInternalScan )
449         {
450             //wd->sta.InternalScanReq = 0;
451             zfStaReconnect(dev);
452         }
453
454         return 0;
455     }
456     else
457     {
458         wd->sta.scanFrequency = nextScanFrequency;
459
460         //zmw_enter_critical_section(dev);
461         zfTimerCancel(dev, ZM_EVENT_IN_SCAN);
462         zmw_leave_critical_section(dev);
463
464         zm_debug_msg0("scan 2");
465         zfCoreSetFrequencyV2(dev, wd->sta.scanFrequency, zfScanMgrEventSetFreqCompleteCb);
466
467         return 1;
468     }
469 }
470
471 void zfScanMgrScanEventStart(zdev_t* dev)
472 {
473     zmw_get_wlan_dev(dev);
474
475     zmw_declare_for_critical_section();
476
477     if ( wd->sta.bChannelScan )
478     {
479         return;
480     }
481
482     zfPowerSavingMgrWakeup(dev);
483
484     zmw_enter_critical_section(dev);
485
486     if ( wd->sta.scanMgr.currScanType == ZM_SCAN_MGR_SCAN_NONE )
487     {
488         goto no_scan;
489     }
490
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);
497
498     //zm_debug_msg1("start scan = ", KeQueryInterruptTime());
499     wd->sta.scanFrequency = zfChGetFirstChannel(dev, &wd->sta.bPassiveScan);
500     zmw_leave_critical_section(dev);
501
502     /* avoid lose receive packet when site survey */
503     //if ((zfStaIsConnected(dev)) && (!zfPowerSavingMgrIsSleeping(dev)))
504     //{
505     //    zfSendNullData(dev, 1);
506     //}
507 //    zm_debug_msg0("scan 0");
508 //    zfCoreSetFrequencyV2(dev, wd->sta.scanFrequency, zfScanMgrEventSetFreqCompleteCb);
509
510     #if 1
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);
517     }
518     else
519     {
520         zfHpBeginSiteSurvey(dev, 0);
521         zmw_enter_critical_section(dev);
522         wd->sta.ibssSiteSurveyStatus = 0;
523         zmw_leave_critical_section(dev);
524     }
525     #endif
526
527     zm_debug_msg0("scan 0");
528     zfCoreSetFrequencyV2(dev, wd->sta.scanFrequency, zfScanMgrEventSetFreqCompleteCb);
529
530     return;
531
532 no_scan:
533     zmw_leave_critical_section(dev);
534     return;
535 }