• 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
19u8_t zfQueryOppositeRate(zdev_t* dev, u8_t dst_mac[6], u8_t frameType)
20{
21    zmw_get_wlan_dev(dev);
22
23    /* For AP's rate adaption */
24    if ( wd->wlanMode == ZM_MODE_AP )
25    {
26        return 0;
27    }
28
29    /* For STA's rate adaption */
30    if ( (frameType & 0x0c) == ZM_WLAN_DATA_FRAME )
31    {
32        if ( ZM_IS_MULTICAST(dst_mac) )
33        {
34            return wd->sta.mTxRate;
35        }
36        else
37        {
38            return wd->sta.uTxRate;
39        }
40    }
41
42    return wd->sta.mmTxRate;
43}
44
45void zfCopyToIntTxBuffer(zdev_t* dev, zbuf_t* buf, u8_t* src,
46                         u16_t offset, u16_t length)
47{
48    u16_t i;
49
50    for(i=0; i<length;i++)
51    {
52        zmw_tx_buf_writeb(dev, buf, offset+i, src[i]);
53    }
54}
55
56void zfCopyToRxBuffer(zdev_t* dev, zbuf_t* buf, u8_t* src,
57                      u16_t offset, u16_t length)
58{
59    u16_t i;
60
61    for(i=0; i<length;i++)
62    {
63        zmw_rx_buf_writeb(dev, buf, offset+i, src[i]);
64    }
65}
66
67void zfCopyFromIntTxBuffer(zdev_t* dev, zbuf_t* buf, u8_t* dst,
68                           u16_t offset, u16_t length)
69{
70    u16_t i;
71
72    for(i=0; i<length; i++)
73    {
74        dst[i] = zmw_tx_buf_readb(dev, buf, offset+i);
75    }
76}
77
78void zfCopyFromRxBuffer(zdev_t* dev, zbuf_t* buf, u8_t* dst,
79                        u16_t offset, u16_t length)
80{
81    u16_t i;
82
83    for(i=0; i<length; i++)
84    {
85        dst[i] = zmw_rx_buf_readb(dev, buf, offset+i);
86    }
87}
88
89void zfMemoryCopy(u8_t* dst, u8_t* src, u16_t length)
90{
91    zfwMemoryCopy(dst, src, length);
92}
93
94void zfMemoryMove(u8_t* dst, u8_t* src, u16_t length)
95{
96    zfwMemoryMove(dst, src, length);
97}
98
99void zfZeroMemory(u8_t* va, u16_t length)
100{
101    zfwZeroMemory(va, length);
102}
103
104u8_t zfMemoryIsEqual(u8_t* m1, u8_t* m2, u16_t length)
105{
106    return zfwMemoryIsEqual(m1, m2, length);
107}
108
109u8_t zfRxBufferEqualToStr(zdev_t* dev, zbuf_t* buf,
110                          const u8_t* str, u16_t offset, u16_t length)
111{
112    u16_t i;
113    u8_t ch;
114
115    for(i=0; i<length; i++)
116    {
117        ch = zmw_rx_buf_readb(dev, buf, offset+i);
118        if ( ch != str[i] )
119        {
120            return FALSE;
121        }
122    }
123
124    return TRUE;
125}
126
127void zfTxBufferCopy(zdev_t*dev, zbuf_t* dst, zbuf_t* src,
128                    u16_t dstOffset, u16_t srcOffset, u16_t length)
129{
130    u16_t i;
131
132    for(i=0; i<length; i++)
133    {
134        zmw_tx_buf_writeb(dev, dst, dstOffset+i,
135                          zmw_tx_buf_readb(dev, src, srcOffset+i));
136    }
137}
138
139void zfRxBufferCopy(zdev_t*dev, zbuf_t* dst, zbuf_t* src,
140                    u16_t dstOffset, u16_t srcOffset, u16_t length)
141{
142    u16_t i;
143
144    for(i=0; i<length; i++)
145    {
146        zmw_rx_buf_writeb(dev, dst, dstOffset+i,
147                             zmw_rx_buf_readb(dev, src, srcOffset+i));
148    }
149}
150
151
152void zfCollectHWTally(zdev_t*dev, u32_t* rsp, u8_t id)
153{
154    zmw_get_wlan_dev(dev);
155
156    zmw_declare_for_critical_section();
157
158    zmw_enter_critical_section(dev);
159
160    if (id == 0)
161    {
162        wd->commTally.Hw_UnderrunCnt += (0xFFFF & rsp[1]);
163        wd->commTally.Hw_TotalRxFrm += rsp[2];
164        wd->commTally.Hw_CRC32Cnt += rsp[3];
165        wd->commTally.Hw_CRC16Cnt += rsp[4];
166        #ifdef ZM_ENABLE_NATIVE_WIFI
167        /* These code are here to satisfy Vista DTM */
168        wd->commTally.Hw_DecrypErr_UNI += ((rsp[5]>50) && (rsp[5]<60))?50:rsp[5];
169        #else
170        wd->commTally.Hw_DecrypErr_UNI += rsp[5];
171        #endif
172        wd->commTally.Hw_RxFIFOOverrun += rsp[6];
173        wd->commTally.Hw_DecrypErr_Mul += rsp[7];
174        wd->commTally.Hw_RetryCnt += rsp[8];
175        wd->commTally.Hw_TotalTxFrm += rsp[9];
176        wd->commTally.Hw_RxTimeOut +=rsp[10];
177
178        wd->commTally.Tx_MPDU += rsp[11];
179        wd->commTally.BA_Fail += rsp[12];
180        wd->commTally.Hw_Tx_AMPDU += rsp[13];
181        wd->commTally.Hw_Tx_MPDU += rsp[14];
182        wd->commTally.RateCtrlTxMPDU += rsp[11];
183        wd->commTally.RateCtrlBAFail += rsp[12];
184    }
185    else
186    {
187        wd->commTally.Hw_RxMPDU += rsp[1];
188        wd->commTally.Hw_RxDropMPDU += rsp[2];
189        wd->commTally.Hw_RxDelMPDU += rsp[3];
190
191        wd->commTally.Hw_RxPhyMiscError += rsp[4];
192        wd->commTally.Hw_RxPhyXRError += rsp[5];
193        wd->commTally.Hw_RxPhyOFDMError += rsp[6];
194        wd->commTally.Hw_RxPhyCCKError += rsp[7];
195        wd->commTally.Hw_RxPhyHTError += rsp[8];
196        wd->commTally.Hw_RxPhyTotalCount += rsp[9];
197    }
198
199    zmw_leave_critical_section(dev);
200
201    if (id == 0)
202    {
203        zm_msg1_mm(ZM_LV_1, "rsplen =", rsp[0]);
204        zm_msg1_mm(ZM_LV_1, "Hw_UnderrunCnt    = ", (0xFFFF & rsp[1]));
205        zm_msg1_mm(ZM_LV_1, "Hw_TotalRxFrm     = ", rsp[2]);
206        zm_msg1_mm(ZM_LV_1, "Hw_CRC32Cnt       = ", rsp[3]);
207        zm_msg1_mm(ZM_LV_1, "Hw_CRC16Cnt       = ", rsp[4]);
208        zm_msg1_mm(ZM_LV_1, "Hw_DecrypErr_UNI  = ", rsp[5]);
209        zm_msg1_mm(ZM_LV_1, "Hw_RxFIFOOverrun  = ", rsp[6]);
210        zm_msg1_mm(ZM_LV_1, "Hw_DecrypErr_Mul  = ", rsp[7]);
211        zm_msg1_mm(ZM_LV_1, "Hw_RetryCnt       = ", rsp[8]);
212        zm_msg1_mm(ZM_LV_1, "Hw_TotalTxFrm     = ", rsp[9]);
213        zm_msg1_mm(ZM_LV_1, "Hw_RxTimeOut      = ", rsp[10]);
214        zm_msg1_mm(ZM_LV_1, "Tx_MPDU           = ", rsp[11]);
215        zm_msg1_mm(ZM_LV_1, "BA_Fail           = ", rsp[12]);
216        zm_msg1_mm(ZM_LV_1, "Hw_Tx_AMPDU       = ", rsp[13]);
217        zm_msg1_mm(ZM_LV_1, "Hw_Tx_MPDU        = ", rsp[14]);
218    }
219    else
220    {
221        zm_msg1_mm(ZM_LV_1, "rsplen             = ", rsp[0]);
222        zm_msg1_mm(ZM_LV_1, "Hw_RxMPDU          = ", (0xFFFF & rsp[1]));
223        zm_msg1_mm(ZM_LV_1, "Hw_RxDropMPDU      = ", rsp[2]);
224        zm_msg1_mm(ZM_LV_1, "Hw_RxDelMPDU       = ", rsp[3]);
225        zm_msg1_mm(ZM_LV_1, "Hw_RxPhyMiscError  = ", rsp[4]);
226        zm_msg1_mm(ZM_LV_1, "Hw_RxPhyXRError    = ", rsp[5]);
227        zm_msg1_mm(ZM_LV_1, "Hw_RxPhyOFDMError  = ", rsp[6]);
228        zm_msg1_mm(ZM_LV_1, "Hw_RxPhyCCKError   = ", rsp[7]);
229        zm_msg1_mm(ZM_LV_1, "Hw_RxPhyHTError    = ", rsp[8]);
230        zm_msg1_mm(ZM_LV_1, "Hw_RxPhyTotalCount = ", rsp[9]);
231    }
232
233}
234
235/* Timer related functions */
236void zfTimerInit(zdev_t* dev)
237{
238    u8_t   i;
239
240    zmw_get_wlan_dev(dev);
241
242    zm_debug_msg0("");
243
244    wd->timerList.freeCount = ZM_MAX_TIMER_COUNT;
245    wd->timerList.head = &(wd->timerList.list[0]);
246    wd->timerList.tail = &(wd->timerList.list[ZM_MAX_TIMER_COUNT-1]);
247    wd->timerList.head->pre = NULL;
248    wd->timerList.head->next = &(wd->timerList.list[1]);
249    wd->timerList.tail->pre = &(wd->timerList.list[ZM_MAX_TIMER_COUNT-2]);
250    wd->timerList.tail->next = NULL;
251
252    for( i=1; i<(ZM_MAX_TIMER_COUNT-1); i++ )
253    {
254        wd->timerList.list[i].pre = &(wd->timerList.list[i-1]);
255        wd->timerList.list[i].next = &(wd->timerList.list[i+1]);
256    }
257
258    wd->bTimerReady = TRUE;
259}
260
261
262u16_t zfTimerSchedule(zdev_t* dev, u16_t event, u32_t tick)
263{
264    struct zsTimerEntry *pFreeEntry;
265    struct zsTimerEntry *pEntry;
266    u8_t   i, count;
267
268    zmw_get_wlan_dev(dev);
269
270    if ( wd->timerList.freeCount == 0 )
271    {
272        zm_debug_msg0("no more timer");
273        return 1;
274    }
275
276    //zm_debug_msg2("event = ", event);
277    //zm_debug_msg1("target tick = ", wd->tick + tick);
278
279    count = ZM_MAX_TIMER_COUNT - wd->timerList.freeCount;
280
281    if ( count == 0 )
282    {
283        wd->timerList.freeCount--;
284        wd->timerList.head->event = event;
285        wd->timerList.head->timer = wd->tick + tick;
286        //zm_debug_msg1("free timer count = ", wd->timerList.freeCount);
287
288        return 0;
289    }
290
291    pFreeEntry = wd->timerList.tail;
292    pFreeEntry->timer = wd->tick + tick;
293    pFreeEntry->event = event;
294    wd->timerList.tail = pFreeEntry->pre;
295    pEntry = wd->timerList.head;
296
297    for( i=0; i<count; i++ )
298    {
299        // prevent from the case of tick overflow
300        if ( ( pEntry->timer > pFreeEntry->timer )&&
301             ((pEntry->timer - pFreeEntry->timer) < 1000000000) )
302        {
303            if ( i != 0 )
304            {
305                pFreeEntry->pre = pEntry->pre;
306                pFreeEntry->pre->next = pFreeEntry;
307            }
308            else
309            {
310                pFreeEntry->pre = NULL;
311            }
312
313            pEntry->pre = pFreeEntry;
314            pFreeEntry->next = pEntry;
315            break;
316        }
317
318        pEntry = pEntry->next;
319    }
320
321    if ( i == 0 )
322    {
323        wd->timerList.head = pFreeEntry;
324    }
325
326    if ( i == count )
327    {
328        pFreeEntry->pre = pEntry->pre;
329        pFreeEntry->pre->next = pFreeEntry;
330        pEntry->pre = pFreeEntry;
331        pFreeEntry->next = pEntry;
332    }
333
334    wd->timerList.freeCount--;
335    //zm_debug_msg1("free timer count = ", wd->timerList.freeCount);
336
337    return 0;
338}
339
340u16_t zfTimerCancel(zdev_t* dev, u16_t event)
341{
342    struct zsTimerEntry *pEntry;
343    u8_t   i, count;
344
345    zmw_get_wlan_dev(dev);
346
347    //zm_debug_msg2("event = ", event);
348    //zm_debug_msg1("free timer count(b) = ", wd->timerList.freeCount);
349
350    pEntry = wd->timerList.head;
351    count = ZM_MAX_TIMER_COUNT - wd->timerList.freeCount;
352
353    for( i=0; i<count; i++ )
354    {
355        if ( pEntry->event == event )
356        {
357            if ( pEntry == wd->timerList.head )
358            {   /* remove head entry */
359                wd->timerList.head = pEntry->next;
360                wd->timerList.tail->next = pEntry;
361                pEntry->pre = wd->timerList.tail;
362                wd->timerList.tail = pEntry;
363                pEntry = wd->timerList.head;
364            }
365            else
366            {   /* remove non-head entry */
367                pEntry->pre->next = pEntry->next;
368                pEntry->next->pre = pEntry->pre;
369                wd->timerList.tail->next = pEntry;
370                pEntry->pre = wd->timerList.tail;
371                wd->timerList.tail = pEntry;
372                pEntry = pEntry->next;
373            }
374
375            wd->timerList.freeCount++;
376        }
377        else
378        {
379            pEntry = pEntry->next;
380        }
381    }
382
383    //zm_debug_msg1("free timer count(a) = ", wd->timerList.freeCount);
384
385    return 0;
386}
387
388void zfTimerClear(zdev_t* dev)
389{
390    zmw_get_wlan_dev(dev);
391
392    wd->timerList.freeCount = ZM_MAX_TIMER_COUNT;
393}
394
395u16_t zfTimerCheckAndHandle(zdev_t* dev)
396{
397    struct zsTimerEntry *pEntry;
398    struct zsTimerEntry *pTheLastEntry = NULL;
399    u16_t  event[ZM_MAX_TIMER_COUNT];
400    u8_t   i, j=0, count;
401
402    zmw_get_wlan_dev(dev);
403
404    zmw_declare_for_critical_section();
405
406    if ( !wd->bTimerReady )
407    {
408        return 0;
409    }
410
411    zmw_enter_critical_section(dev);
412
413    pEntry = wd->timerList.head;
414    count = ZM_MAX_TIMER_COUNT - wd->timerList.freeCount;
415
416    for( i=0; i<count; i++ )
417    {
418        // prevent from the case of tick overflow
419        if ( ( pEntry->timer > wd->tick )&&
420             ((pEntry->timer - wd->tick) < 1000000000) )
421        {
422            break;
423        }
424
425        event[j++] = pEntry->event;
426        pTheLastEntry = pEntry;
427        pEntry = pEntry->next;
428    }
429
430    if ( j > 0 )
431    {
432        wd->timerList.tail->next = wd->timerList.head;
433        wd->timerList.head->pre = wd->timerList.tail;
434        wd->timerList.head = pEntry;
435        wd->timerList.tail = pTheLastEntry;
436        wd->timerList.freeCount += j;
437        //zm_debug_msg1("free timer count = ", wd->timerList.freeCount);
438    }
439
440    zmw_leave_critical_section(dev);
441
442    zfProcessEvent(dev, event, j);
443
444    return 0;
445}
446
447u32_t zfCoreSetKey(zdev_t* dev, u8_t user, u8_t keyId, u8_t type,
448        u16_t* mac, u32_t* key)
449{
450    u32_t ret;
451
452    zmw_get_wlan_dev(dev);
453    zmw_declare_for_critical_section();
454
455    zmw_enter_critical_section(dev);
456    wd->sta.flagKeyChanging++;
457    zm_debug_msg1("   zfCoreSetKey++++ ", wd->sta.flagKeyChanging);
458    zmw_leave_critical_section(dev);
459
460    ret = zfHpSetKey(dev, user, keyId, type, mac, key);
461    return ret;
462}
463
464void zfCoreSetKeyComplete(zdev_t* dev)
465{
466    zmw_get_wlan_dev(dev);
467    zmw_declare_for_critical_section();
468
469    if(wd->sta.flagKeyChanging)
470    {
471        zmw_enter_critical_section(dev);
472        wd->sta.flagKeyChanging--;
473        zmw_leave_critical_section(dev);
474    }
475    zm_debug_msg1("  zfCoreSetKeyComplete--- ", wd->sta.flagKeyChanging);
476
477    zfPushVtxq(dev);
478}
479
480void zfCoreHalInitComplete(zdev_t* dev)
481{
482    zmw_get_wlan_dev(dev);
483    zmw_declare_for_critical_section();
484
485    zmw_enter_critical_section(dev);
486    wd->halState = ZM_HAL_STATE_RUNNING;
487    zmw_leave_critical_section(dev);
488
489    zfPushVtxq(dev);
490}
491
492void zfCoreMacAddressNotify(zdev_t* dev, u8_t* addr)
493{
494    zmw_get_wlan_dev(dev);
495
496    wd->macAddr[0] = addr[0] | ((u16_t)addr[1]<<8);
497    wd->macAddr[1] = addr[2] | ((u16_t)addr[3]<<8);
498    wd->macAddr[2] = addr[4] | ((u16_t)addr[5]<<8);
499
500
501    //zfHpSetMacAddress(dev, wd->macAddr, 0);
502    if (wd->zfcbMacAddressNotify != NULL)
503    {
504        wd->zfcbMacAddressNotify(dev, addr);
505    }
506}
507
508void zfCoreSetIsoName(zdev_t* dev, u8_t* isoName)
509{
510    zmw_get_wlan_dev(dev);
511
512    wd->ws.countryIsoName[0] = isoName[0];
513    wd->ws.countryIsoName[1] = isoName[1];
514    wd->ws.countryIsoName[2] = '\0';
515 }
516
517
518extern void zfScanMgrScanEventStart(zdev_t* dev);
519extern u8_t zfScanMgrScanEventTimeout(zdev_t* dev);
520extern void zfScanMgrScanEventRetry(zdev_t* dev);
521
522void zfProcessEvent(zdev_t* dev, u16_t* eventArray, u8_t eventCount)
523{
524    u8_t i, j, bypass = FALSE;
525    u16_t eventBypass[32];
526    u8_t eventBypassCount = 0;
527
528    zmw_get_wlan_dev(dev);
529
530    zmw_declare_for_critical_section();
531
532    zfZeroMemory((u8_t*) eventBypass, 64);
533
534    for( i=0; i<eventCount; i++ )
535    {
536        for( j=0; j<eventBypassCount; j++ )
537        {
538            if ( eventBypass[j] == eventArray[i] )
539            {
540                bypass = TRUE;
541                break;
542            }
543        }
544
545        if ( bypass )
546        {
547            continue;
548        }
549
550        switch( eventArray[i] )
551        {
552            case ZM_EVENT_SCAN:
553                {
554                    zfScanMgrScanEventStart(dev);
555                    eventBypass[eventBypassCount++] = ZM_EVENT_IN_SCAN;
556                    eventBypass[eventBypassCount++] = ZM_EVENT_TIMEOUT_SCAN;
557                }
558                break;
559
560            case ZM_EVENT_TIMEOUT_SCAN:
561                {
562                    u8_t res;
563
564                    res = zfScanMgrScanEventTimeout(dev);
565                    if ( res == 0 )
566                    {
567                        eventBypass[eventBypassCount++] = ZM_EVENT_TIMEOUT_SCAN;
568                    }
569                    else if ( res == 1 )
570                    {
571                        eventBypass[eventBypassCount++] = ZM_EVENT_IN_SCAN;
572                    }
573                }
574                break;
575
576            case ZM_EVENT_IBSS_MONITOR:
577                {
578                    zfStaIbssMonitoring(dev, 0);
579                }
580                break;
581
582            case ZM_EVENT_IN_SCAN:
583                {
584                    zfScanMgrScanEventRetry(dev);
585                }
586                break;
587
588            case ZM_EVENT_CM_TIMER:
589                {
590                    zm_msg0_mm(ZM_LV_0, "ZM_EVENT_CM_TIMER");
591
592                    wd->sta.cmMicFailureCount = 0;
593                }
594                break;
595
596            case ZM_EVENT_CM_DISCONNECT:
597                {
598                    zm_msg0_mm(ZM_LV_0, "ZM_EVENT_CM_DISCONNECT");
599
600                    zfChangeAdapterState(dev, ZM_STA_STATE_DISCONNECT);
601
602                    zmw_enter_critical_section(dev);
603                    //zfTimerSchedule(dev, ZM_EVENT_CM_BLOCK_TIMER,
604                    //                ZM_TICK_CM_BLOCK_TIMEOUT);
605
606                    /* Timer Resolution on WinXP is 15/16 ms  */
607                    /* Decrease Time offset for <XP> Counter Measure */
608                    zfTimerSchedule(dev, ZM_EVENT_CM_BLOCK_TIMER,
609                                         ZM_TICK_CM_BLOCK_TIMEOUT - ZM_TICK_CM_BLOCK_TIMEOUT_OFFSET);
610
611                    zmw_leave_critical_section(dev);
612                    wd->sta.cmMicFailureCount = 0;
613                    //zfiWlanDisable(dev);
614                    zfHpResetKeyCache(dev);
615                    if (wd->zfcbConnectNotify != NULL)
616                    {
617                        wd->zfcbConnectNotify(dev, ZM_STATUS_MEDIA_DISCONNECT_MIC_FAIL,
618                             wd->sta.bssid);
619                    }
620                }
621                break;
622
623            case ZM_EVENT_CM_BLOCK_TIMER:
624                {
625                    zm_msg0_mm(ZM_LV_0, "ZM_EVENT_CM_BLOCK_TIMER");
626
627                    //zmw_enter_critical_section(dev);
628                    wd->sta.cmDisallowSsidLength = 0;
629                    if ( wd->sta.bAutoReconnect )
630                    {
631                        zm_msg0_mm(ZM_LV_0, "ZM_EVENT_CM_BLOCK_TIMER:bAutoReconnect!=0");
632                        zfScanMgrScanStop(dev, ZM_SCAN_MGR_SCAN_INTERNAL);
633                        zfScanMgrScanStart(dev, ZM_SCAN_MGR_SCAN_INTERNAL);
634                    }
635                    //zmw_leave_critical_section(dev);
636                }
637                break;
638
639            case ZM_EVENT_TIMEOUT_ADDBA:
640                {
641                    if (!wd->addbaComplete && (wd->addbaCount < 5))
642                    {
643                        zfAggSendAddbaRequest(dev, wd->sta.bssid, 0, 0);
644                        wd->addbaCount++;
645                        zfTimerSchedule(dev, ZM_EVENT_TIMEOUT_ADDBA, 100);
646                    }
647                    else
648                    {
649                        zfTimerCancel(dev, ZM_EVENT_TIMEOUT_ADDBA);
650                    }
651                }
652                break;
653
654            #ifdef ZM_ENABLE_PERFORMANCE_EVALUATION
655            case ZM_EVENT_TIMEOUT_PERFORMANCE:
656                {
657                    zfiPerformanceRefresh(dev);
658                }
659                break;
660            #endif
661            case ZM_EVENT_SKIP_COUNTERMEASURE:
662				//enable the Countermeasure
663				{
664					zm_debug_msg0("Countermeasure : Enable MIC Check ");
665					wd->TKIP_Group_KeyChanging = 0x0;
666				}
667				break;
668
669            default:
670                break;
671        }
672    }
673}
674
675void zfBssInfoCreate(zdev_t* dev)
676{
677    u8_t   i;
678
679    zmw_get_wlan_dev(dev);
680
681    zmw_declare_for_critical_section();
682
683    zmw_enter_critical_section(dev);
684
685    wd->sta.bssList.bssCount = 0;
686    wd->sta.bssList.head = NULL;
687    wd->sta.bssList.tail = NULL;
688    wd->sta.bssInfoArrayHead = 0;
689    wd->sta.bssInfoArrayTail = 0;
690    wd->sta.bssInfoFreeCount = ZM_MAX_BSS;
691
692    for( i=0; i< ZM_MAX_BSS; i++ )
693    {
694        //wd->sta.bssInfoArray[i] = &(wd->sta.bssInfoPool[i]);
695        wd->sta.bssInfoArray[i] = zfwMemAllocate(dev, sizeof(struct zsBssInfo));
696
697    }
698
699    zmw_leave_critical_section(dev);
700}
701
702void zfBssInfoDestroy(zdev_t* dev)
703{
704    u8_t   i;
705    zmw_get_wlan_dev(dev);
706
707    zfBssInfoRefresh(dev, 1);
708
709    for( i=0; i< ZM_MAX_BSS; i++ )
710    {
711        if (wd->sta.bssInfoArray[i] != NULL)
712        {
713            zfwMemFree(dev, wd->sta.bssInfoArray[i], sizeof(struct zsBssInfo));
714        }
715        else
716        {
717            zm_assert(0);
718        }
719    }
720    return;
721}
722
723struct zsBssInfo* zfBssInfoAllocate(zdev_t* dev)
724{
725    struct zsBssInfo* pBssInfo;
726
727    zmw_get_wlan_dev(dev);
728
729    if (wd->sta.bssInfoFreeCount == 0)
730        return NULL;
731
732    pBssInfo = wd->sta.bssInfoArray[wd->sta.bssInfoArrayHead];
733    wd->sta.bssInfoArray[wd->sta.bssInfoArrayHead] = NULL;
734    wd->sta.bssInfoArrayHead = (wd->sta.bssInfoArrayHead + 1) & (ZM_MAX_BSS - 1);
735    wd->sta.bssInfoFreeCount--;
736
737    zfZeroMemory((u8_t*)pBssInfo, sizeof(struct zsBssInfo));
738
739    return pBssInfo;
740}
741
742void zfBssInfoFree(zdev_t* dev, struct zsBssInfo* pBssInfo)
743{
744    zmw_get_wlan_dev(dev);
745
746    zm_assert(wd->sta.bssInfoArray[wd->sta.bssInfoArrayTail] == NULL);
747
748    pBssInfo->signalStrength = pBssInfo->signalQuality = 0;
749    pBssInfo->sortValue = 0;
750
751    wd->sta.bssInfoArray[wd->sta.bssInfoArrayTail] = pBssInfo;
752    wd->sta.bssInfoArrayTail = (wd->sta.bssInfoArrayTail + 1) & (ZM_MAX_BSS - 1);
753    wd->sta.bssInfoFreeCount++;
754}
755
756void zfBssInfoReorderList(zdev_t* dev)
757{
758    struct zsBssInfo* pBssInfo = NULL;
759    struct zsBssInfo* pInsBssInfo = NULL;
760    struct zsBssInfo* pNextBssInfo = NULL;
761    struct zsBssInfo* pPreBssInfo = NULL;
762    u8_t i = 0;
763
764    zmw_get_wlan_dev(dev);
765
766    zmw_declare_for_critical_section();
767
768    zmw_enter_critical_section(dev);
769
770    if (wd->sta.bssList.bssCount > 1)
771    {
772        pInsBssInfo = wd->sta.bssList.head;
773        wd->sta.bssList.tail = pInsBssInfo;
774        pBssInfo = pInsBssInfo->next;
775        pInsBssInfo->next = NULL;
776        while (pBssInfo != NULL)
777        {
778            i = 0;
779            while (1)
780            {
781//                if (pBssInfo->signalStrength >= pInsBssInfo->signalStrength)
782                if( pBssInfo->sortValue >= pInsBssInfo->sortValue)
783                {
784                    if (i==0)
785                    {
786                        //Insert BssInfo to head
787                        wd->sta.bssList.head = pBssInfo;
788                        pNextBssInfo = pBssInfo->next;
789                        pBssInfo->next = pInsBssInfo;
790                        break;
791                    }
792                    else
793                    {
794                        //Insert BssInfo to neither head nor tail
795                        pPreBssInfo->next = pBssInfo;
796                        pNextBssInfo = pBssInfo->next;
797                        pBssInfo->next = pInsBssInfo;
798                        break;
799                    }
800                }
801                else
802                {
803                    if (pInsBssInfo->next != NULL)
804                    {
805                        //Signal strength smaller than current BssInfo, check next
806                        pPreBssInfo = pInsBssInfo;
807                        pInsBssInfo = pInsBssInfo->next;
808                    }
809                    else
810                    {
811                        //Insert BssInfo to tail
812                        pInsBssInfo->next = pBssInfo;
813                        pNextBssInfo = pBssInfo->next;
814                        wd->sta.bssList.tail = pBssInfo;
815                        pBssInfo->next = NULL;
816                        break;
817                    }
818                }
819                i++;
820            }
821            pBssInfo = pNextBssInfo;
822            pInsBssInfo = wd->sta.bssList.head;
823        }
824    } //if (wd->sta.bssList.bssCount > 1)
825
826    zmw_leave_critical_section(dev);
827}
828
829void zfBssInfoInsertToList(zdev_t* dev, struct zsBssInfo* pBssInfo)
830{
831    zmw_get_wlan_dev(dev);
832
833    zm_assert(pBssInfo);
834
835    //zm_debug_msg2("pBssInfo = ", pBssInfo);
836
837    if ( wd->sta.bssList.bssCount == 0 )
838    {
839        wd->sta.bssList.head = pBssInfo;
840        wd->sta.bssList.tail = pBssInfo;
841    }
842    else
843    {
844        wd->sta.bssList.tail->next = pBssInfo;
845        wd->sta.bssList.tail = pBssInfo;
846    }
847
848    pBssInfo->next = NULL;
849    wd->sta.bssList.bssCount++;
850
851    //zm_debug_msg2("bss count = ", wd->sta.bssList.bssCount);
852}
853
854void zfBssInfoRemoveFromList(zdev_t* dev, struct zsBssInfo* pBssInfo)
855{
856    struct zsBssInfo* pNowBssInfo;
857    struct zsBssInfo* pPreBssInfo = NULL;
858    u8_t   i;
859
860    zmw_get_wlan_dev(dev);
861
862    zm_assert(pBssInfo);
863    zm_assert(wd->sta.bssList.bssCount);
864
865    //zm_debug_msg2("pBssInfo = ", pBssInfo);
866
867    pNowBssInfo = wd->sta.bssList.head;
868
869    for( i=0; i<wd->sta.bssList.bssCount; i++ )
870    {
871        if ( pNowBssInfo == pBssInfo )
872        {
873            if ( i == 0 )
874            {   /* remove head */
875                wd->sta.bssList.head = pBssInfo->next;
876            }
877            else
878            {
879                pPreBssInfo->next = pBssInfo->next;
880            }
881
882            if ( i == (wd->sta.bssList.bssCount - 1) )
883            {   /* remove tail */
884                wd->sta.bssList.tail = pPreBssInfo;
885            }
886
887            break;
888        }
889
890        pPreBssInfo = pNowBssInfo;
891        pNowBssInfo = pNowBssInfo->next;
892    }
893
894    zm_assert(i != wd->sta.bssList.bssCount);
895    wd->sta.bssList.bssCount--;
896
897    //zm_debug_msg2("bss count = ", wd->sta.bssList.bssCount);
898}
899
900void zfBssInfoRefresh(zdev_t* dev, u16_t mode)
901{
902    struct zsBssInfo*   pBssInfo;
903    struct zsBssInfo*   pNextBssInfo;
904    u8_t   i, bssCount;
905
906    zmw_get_wlan_dev(dev);
907
908    pBssInfo = wd->sta.bssList.head;
909    bssCount = wd->sta.bssList.bssCount;
910
911    for( i=0; i<bssCount; i++ )
912    {
913        if (mode == 1)
914        {
915            pNextBssInfo = pBssInfo->next;
916            zfBssInfoRemoveFromList(dev, pBssInfo);
917            zfBssInfoFree(dev, pBssInfo);
918            pBssInfo = pNextBssInfo;
919        }
920        else
921        {
922            if ( pBssInfo->flag & ZM_BSS_INFO_VALID_BIT )
923            {   /* this one must be kept */
924                pBssInfo->flag &= ~ZM_BSS_INFO_VALID_BIT;
925                pBssInfo = pBssInfo->next;
926            }
927            else
928            {
929                #define ZM_BSS_CACHE_TIME_IN_MS   20000
930                if ((wd->tick - pBssInfo->tick) > (ZM_BSS_CACHE_TIME_IN_MS/ZM_MS_PER_TICK))
931                {
932                    pNextBssInfo = pBssInfo->next;
933                    zfBssInfoRemoveFromList(dev, pBssInfo);
934                    zfBssInfoFree(dev, pBssInfo);
935                    pBssInfo = pNextBssInfo;
936                }
937                else
938                {
939                    pBssInfo = pBssInfo->next;
940                }
941            }
942        }
943    } //for( i=0; i<bssCount; i++ )
944    return;
945}
946
947void zfDumpSSID(u8_t length, u8_t *value)
948{
949    u8_t buf[50];
950    u8_t tmpLength = length;
951
952    if ( tmpLength > 49 )
953    {
954        tmpLength = 49;
955    }
956
957    zfMemoryCopy(buf, value, tmpLength);
958    buf[tmpLength] = '\0';
959    //printk("SSID: %s\n", buf);
960    //zm_debug_msg_s("ssid = ", value);
961}
962
963void zfCoreReinit(zdev_t* dev)
964{
965    zmw_get_wlan_dev(dev);
966
967    wd->sta.flagKeyChanging = 0;
968    wd->sta.flagFreqChanging = 0;
969}
970
971void zfGenerateRandomBSSID(zdev_t* dev, u8_t *MACAddr, u8_t *BSSID)
972{
973    //ULONGLONG   time;
974    u32_t time;
975
976    zmw_get_wlan_dev(dev);
977
978    time = wd->tick;
979
980    //
981    // Initialize the random BSSID to be the same as MAC address.
982    //
983
984    // RtlCopyMemory(BSSID, MACAddr, sizeof(DOT11_MAC_ADDRESS));
985    zfMemoryCopy(BSSID, MACAddr, 6);
986
987    //
988    // Get the system time in 10 millisecond.
989    //
990
991    // NdisGetCurrentSystemTime((PLARGE_INTEGER)&time);
992    // time /= 100000;
993
994    //
995    // Randomize the first 4 bytes of BSSID.
996    //
997
998    BSSID[0] ^= (u8_t)(time & 0xff);
999    BSSID[0] &= ~0x01;              // Turn off multicast bit
1000    BSSID[0] |= 0x02;               // Turn on local bit
1001
1002    time >>= 8;
1003    BSSID[1] ^= (u8_t)(time & 0xff);
1004
1005    time >>= 8;
1006    BSSID[2] ^= (u8_t)(time & 0xff);
1007
1008    time >>= 8;
1009    BSSID[3] ^= (u8_t)(time & 0xff);
1010}
1011
1012u8_t zfiWlanGetDestAddrFromBuf(zdev_t *dev, zbuf_t *buf, u16_t *macAddr)
1013{
1014#ifdef ZM_ENABLE_NATIVE_WIFI
1015    zmw_get_wlan_dev(dev);
1016
1017    if ( wd->wlanMode == ZM_MODE_INFRASTRUCTURE )
1018    {
1019        /* DA */
1020        macAddr[0] = zmw_tx_buf_readh(dev, buf, 16);
1021        macAddr[1] = zmw_tx_buf_readh(dev, buf, 18);
1022        macAddr[2] = zmw_tx_buf_readh(dev, buf, 20);
1023    }
1024    else if ( wd->wlanMode == ZM_MODE_IBSS )
1025    {
1026        /* DA */
1027        macAddr[0] = zmw_tx_buf_readh(dev, buf, 4);
1028        macAddr[1] = zmw_tx_buf_readh(dev, buf, 6);
1029        macAddr[2] = zmw_tx_buf_readh(dev, buf, 8);
1030    }
1031    else if ( wd->wlanMode == ZM_MODE_AP )
1032    {
1033        /* DA */
1034        macAddr[0] = zmw_tx_buf_readh(dev, buf, 4);
1035        macAddr[1] = zmw_tx_buf_readh(dev, buf, 6);
1036        macAddr[2] = zmw_tx_buf_readh(dev, buf, 8);
1037    }
1038    else
1039    {
1040        return 1;
1041    }
1042#else
1043    /* DA */
1044    macAddr[0] = zmw_tx_buf_readh(dev, buf, 0);
1045    macAddr[1] = zmw_tx_buf_readh(dev, buf, 2);
1046    macAddr[2] = zmw_tx_buf_readh(dev, buf, 4);
1047#endif
1048
1049    return 0;
1050}
1051
1052/* Leave an empty line below to remove warning message on some compiler */
1053
1054u16_t zfFindCleanFrequency(zdev_t* dev, u32_t adhocMode)
1055{
1056    u8_t   i, j;
1057    u16_t  returnChannel;
1058    u16_t  count_24G = 0, min24GIndex = 0;
1059    u16_t  count_5G = 0,  min5GIndex = 0;
1060    u16_t  CombinationBssNumberIn24G[15] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
1061    u16_t  BssNumberIn24G[17]  = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
1062    u16_t  Array_24G[15]       = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
1063    u16_t  BssNumberIn5G[31]   = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
1064    u16_t  Array_5G[31]        = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
1065    struct zsBssInfo* pBssInfo;
1066
1067    zmw_get_wlan_dev(dev);
1068
1069    pBssInfo = wd->sta.bssList.head;
1070    if (pBssInfo == NULL)
1071    {
1072        if( adhocMode == ZM_ADHOCBAND_B || adhocMode == ZM_ADHOCBAND_G ||
1073            adhocMode == ZM_ADHOCBAND_BG || adhocMode == ZM_ADHOCBAND_ABG )
1074        {
1075            returnChannel = zfChGetFirst2GhzChannel(dev);
1076        }
1077        else
1078        {
1079            returnChannel = zfChGetFirst5GhzChannel(dev);
1080        }
1081
1082        return returnChannel;
1083    }
1084
1085    /* #1 Get Allowed Channel following Country Code ! */
1086    zmw_declare_for_critical_section();
1087    zmw_enter_critical_section(dev);
1088    for (i = 0; i < wd->regulationTable.allowChannelCnt; i++)
1089    {
1090        if (wd->regulationTable.allowChannel[i].channel < 3000)
1091        { // 2.4GHz
1092            Array_24G[count_24G] = wd->regulationTable.allowChannel[i].channel;
1093            count_24G++;
1094        }
1095        else
1096        { // 5GHz
1097            count_5G++;
1098            Array_5G[i] = wd->regulationTable.allowChannel[i].channel;
1099        }
1100    }
1101    zmw_leave_critical_section(dev);
1102
1103    while( pBssInfo != NULL )
1104    {
1105        /* #2_1 Count BSS number in some specificed frequency in 2.4GHz band ! */
1106        if( adhocMode == ZM_ADHOCBAND_B || adhocMode == ZM_ADHOCBAND_G ||
1107            adhocMode == ZM_ADHOCBAND_BG || adhocMode == ZM_ADHOCBAND_ABG )
1108        {
1109            for( i=0; i<=(count_24G+3); i++ )
1110            {
1111                if( pBssInfo->frequency == Array_24G[i] )
1112                { // Array_24G[0] correspond to BssNumberIn24G[2]
1113                    BssNumberIn24G[pBssInfo->channel+1]++;
1114                }
1115            }
1116        }
1117
1118        /* #2_2 Count BSS number in some specificed frequency in 5GHz band ! */
1119        if( adhocMode == ZM_ADHOCBAND_A || adhocMode == ZM_ADHOCBAND_ABG )
1120        {
1121            for( i=0; i<count_5G; i++ )
1122            { // 5GHz channel is not equal to array index
1123                if( pBssInfo->frequency == Array_5G[i] )
1124                { // Array_5G[0] correspond to BssNumberIn5G[0]
1125                    BssNumberIn5G[i]++;
1126                }
1127            }
1128        }
1129
1130        pBssInfo = pBssInfo->next;
1131    }
1132
1133
1134    if( adhocMode == ZM_ADHOCBAND_B || adhocMode == ZM_ADHOCBAND_G ||
1135        adhocMode == ZM_ADHOCBAND_BG || adhocMode == ZM_ADHOCBAND_ABG )
1136    {
1137        /* #3_1 Count BSS number that influence the specificed frequency in 2.4GHz ! */
1138        for( j=0; j<count_24G; j++ )
1139        {
1140            CombinationBssNumberIn24G[j] = BssNumberIn24G[j]   + BssNumberIn24G[j+1] +
1141                                           BssNumberIn24G[j+2] + BssNumberIn24G[j+3] +
1142                                           BssNumberIn24G[j+4];
1143            //printk("After combine, the number of BSS network channel %d is %d",
1144            //                                   j , CombinationBssNumberIn24G[j]);
1145        }
1146
1147        /* #4_1 Find the less utilized frequency in 2.4GHz band ! */
1148        min24GIndex = zfFindMinimumUtilizationChannelIndex(dev, CombinationBssNumberIn24G, count_24G);
1149    }
1150
1151    /* #4_2 Find the less utilized frequency in 5GHz band ! */
1152    if( adhocMode == ZM_ADHOCBAND_A || adhocMode == ZM_ADHOCBAND_ABG )
1153    {
1154        min5GIndex = zfFindMinimumUtilizationChannelIndex(dev, BssNumberIn5G, count_5G);
1155    }
1156
1157    if( adhocMode == ZM_ADHOCBAND_B || adhocMode == ZM_ADHOCBAND_G || adhocMode == ZM_ADHOCBAND_BG )
1158    {
1159        return Array_24G[min24GIndex];
1160    }
1161    else if( adhocMode == ZM_ADHOCBAND_A )
1162    {
1163        return Array_5G[min5GIndex];
1164    }
1165    else if( adhocMode == ZM_ADHOCBAND_ABG )
1166    {
1167        if ( CombinationBssNumberIn24G[min24GIndex] <= BssNumberIn5G[min5GIndex] )
1168            return Array_24G[min24GIndex];
1169        else
1170            return Array_5G[min5GIndex];
1171    }
1172    else
1173        return 2412;
1174}
1175
1176u16_t zfFindMinimumUtilizationChannelIndex(zdev_t* dev, u16_t* array, u16_t count)
1177{
1178    u8_t   i;
1179    u16_t  tempMinIndex, tempMinValue;
1180
1181    i = 1;
1182    tempMinIndex = 0;
1183    tempMinValue = array[tempMinIndex];
1184    while( i< count )
1185    {
1186        if( array[i] < tempMinValue )
1187        {
1188            tempMinValue = array[i];
1189            tempMinIndex = i;
1190        }
1191        i++;
1192    }
1193
1194    return tempMinIndex;
1195}
1196
1197u8_t zfCompareWithBssid(zdev_t* dev, u16_t* bssid)
1198{
1199    zmw_get_wlan_dev(dev);
1200
1201    if ( zfMemoryIsEqual((u8_t*)bssid, (u8_t*)wd->sta.bssid, 6) )
1202    {
1203        return 1;
1204    }
1205    else
1206    {
1207        return 0;
1208    }
1209}
1210