• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /netgear-R7000-V1.0.7.12_1.2.5/components/opensource/linux/linux-2.6.36/drivers/staging/otus/80211core/
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{
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    }
313}
314
315u8_t zfScanMgrScanEventTimeout(zdev_t* dev)
316{
317    u16_t   nextScanFrequency = 0;
318    u8_t    temp;
319
320    zmw_get_wlan_dev(dev);
321
322    zmw_declare_for_critical_section();
323
324    zmw_enter_critical_section(dev);
325    if ( wd->sta.scanFrequency == 0 )
326    {
327        zmw_leave_critical_section(dev);
328        return -1;
329    }
330
331    nextScanFrequency = zfChGetNextChannel(dev, wd->sta.scanFrequency,
332                                           &wd->sta.bPassiveScan);
333
334    if ( (nextScanFrequency == 0xffff)
335         || (wd->sta.scanFrequency == zfChGetLastChannel(dev, &temp)) )
336    {
337        u8_t currScanType;
338        u8_t isExternalScan = 0;
339        u8_t isInternalScan = 0;
340
341        //zm_debug_msg1("end scan = ", KeQueryInterruptTime());
342        wd->sta.scanFrequency = 0;
343
344        zm_debug_msg1("scan 1 type: ", wd->sta.scanMgr.currScanType);
345        zm_debug_msg1("scan channel count = ", wd->regulationTable.allowChannelCnt);
346
347        //zfBssInfoRefresh(dev);
348        zfTimerCancel(dev, ZM_EVENT_TIMEOUT_SCAN);
349
350        if ( wd->sta.bChannelScan == FALSE )
351        {
352            zm_debug_msg0("WOW!! scan is cancelled\n");
353            zmw_leave_critical_section(dev);
354            goto report_scan_result;
355        }
356
357
358        currScanType = wd->sta.scanMgr.currScanType;
359        switch(currScanType)
360        {
361            case ZM_SCAN_MGR_SCAN_EXTERNAL:
362                isExternalScan = 1;
363
364                if ( wd->sta.scanMgr.scanReqs[ZM_SCAN_MGR_SCAN_INTERNAL - 1] )
365                {
366                    wd->sta.scanMgr.scanReqs[ZM_SCAN_MGR_SCAN_INTERNAL - 1] = 0;
367                    isInternalScan = 1;
368                }
369
370                break;
371
372            case ZM_SCAN_MGR_SCAN_INTERNAL:
373                isInternalScan = 1;
374
375                if ( wd->sta.scanMgr.scanReqs[ZM_SCAN_MGR_SCAN_EXTERNAL - 1] )
376                {
377                    // Because the external scan should pre-empts internal scan.
378                    // So this shall not be happened!!
379                    zm_assert(0);
380                }
381
382                break;
383
384            default:
385                zm_assert(0);
386                break;
387        }
388
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);
393
394        //Set channel according to AP's configuration
395        zfCoreSetFrequencyEx(dev, wd->frequency, wd->BandWidth40,
396                wd->ExtOffset, zfScanMgrEventScanCompleteCb);
397
398        wd->sta.bChannelScan = FALSE;
399
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);
408
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 )
412            {
413                zfHpEnableRifs(dev, ((wd->sta.currentFrequency<3000)?1:0), wd->sta.EnableHT, wd->sta.HT2040);
414            }
415        }
416        else
417        {
418            zfHpFinishSiteSurvey(dev, 0);
419            zmw_enter_critical_section(dev);
420            wd->sta.ibssSiteSurveyStatus = 0;
421            zmw_leave_critical_section(dev);
422        }
423
424report_scan_result:
425        /* avoid lose receive packet when site survey */
426        //if ((zfStaIsConnected(dev)) && (!zfPowerSavingMgrIsSleeping(dev)))
427        //{
428        //    zfSendNullData(dev, 0);
429        //}
430
431        if ( isExternalScan )//Quickly reboot
432        {
433            if (wd->zfcbScanNotify != NULL)
434            {
435                wd->zfcbScanNotify(dev, NULL);
436            }
437        }
438
439        if ( isInternalScan )
440        {
441            //wd->sta.InternalScanReq = 0;
442            zfStaReconnect(dev);
443        }
444
445        return 0;
446    }
447    else
448    {
449        wd->sta.scanFrequency = nextScanFrequency;
450
451        //zmw_enter_critical_section(dev);
452        zfTimerCancel(dev, ZM_EVENT_IN_SCAN);
453        zmw_leave_critical_section(dev);
454
455        zm_debug_msg0("scan 2");
456        zfCoreSetFrequencyV2(dev, wd->sta.scanFrequency, zfScanMgrEventSetFreqCompleteCb);
457
458        return 1;
459    }
460}
461
462void zfScanMgrScanEventStart(zdev_t* dev)
463{
464    zmw_get_wlan_dev(dev);
465
466    zmw_declare_for_critical_section();
467
468    if ( wd->sta.bChannelScan )
469    {
470        return;
471    }
472
473    zfPowerSavingMgrWakeup(dev);
474
475    zmw_enter_critical_section(dev);
476
477    if ( wd->sta.scanMgr.currScanType == ZM_SCAN_MGR_SCAN_NONE )
478    {
479        goto no_scan;
480    }
481
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);
488
489    //zm_debug_msg1("start scan = ", KeQueryInterruptTime());
490    wd->sta.scanFrequency = zfChGetFirstChannel(dev, &wd->sta.bPassiveScan);
491    zmw_leave_critical_section(dev);
492
493    /* avoid lose receive packet when site survey */
494    //if ((zfStaIsConnected(dev)) && (!zfPowerSavingMgrIsSleeping(dev)))
495    //{
496    //    zfSendNullData(dev, 1);
497    //}
498//    zm_debug_msg0("scan 0");
499//    zfCoreSetFrequencyV2(dev, wd->sta.scanFrequency, zfScanMgrEventSetFreqCompleteCb);
500
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);
507    }
508    else
509    {
510        zfHpBeginSiteSurvey(dev, 0);
511        zmw_enter_critical_section(dev);
512        wd->sta.ibssSiteSurveyStatus = 0;
513        zmw_leave_critical_section(dev);
514    }
515
516    zm_debug_msg0("scan 0");
517    zfCoreSetFrequencyV2(dev, wd->sta.scanFrequency, zfScanMgrEventSetFreqCompleteCb);
518
519    return;
520
521no_scan:
522    zmw_leave_critical_section(dev);
523    return;
524}
525