Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wirel...
[pandora-kernel.git] / 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     if ((zfStaIsConnected(dev)) && (!zfPowerSavingMgrIsSleeping(dev)))
293     {
294         zfSendNullData(dev, 0);
295     }
296     return;
297 }
298
299
300 void 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
320 u8_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
431 report_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
469 void 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
530 no_scan:
531     zmw_leave_critical_section(dev);
532     return;
533 }