• 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#include "ratectrl.h"
19#include "../hal/hpreg.h"
20
21/* TODO : change global variable to constant */
22u8_t   zgWpaRadiusOui[] = { 0x00, 0x50, 0xf2, 0x01 };
23u8_t   zgWpaAesOui[] = { 0x00, 0x50, 0xf2, 0x04 };
24u8_t   zgWpa2RadiusOui[] = { 0x00, 0x0f, 0xac, 0x01 };
25u8_t   zgWpa2AesOui[] = { 0x00, 0x0f, 0xac, 0x04 };
26
27const u16_t zcCwTlb[16] = {   0,    1,    3,    7,   15,   31,   63,  127,
28                            255,  511, 1023, 2047, 4095, 4095, 4095, 4095};
29
30void zfStaStartConnectCb(zdev_t* dev);
31
32/************************************************************************/
33/*                                                                      */
34/*    FUNCTION DESCRIPTION                  zfStaPutApIntoBlockingList  */
35/*      Put AP into blocking AP list.                                   */
36/*                                                                      */
37/*    INPUTS                                                            */
38/*      dev : device pointer                                            */
39/*      bssid : AP's BSSID                                              */
40/*      weight : weight of AP                                           */
41/*                                                                      */
42/*    OUTPUTS                                                           */
43/*      none                                                            */
44/*                                                                      */
45/*    AUTHOR                                                            */
46/*      Stephen Chen        Atheros Communications, INC.    2006.12     */
47/*                                                                      */
48/************************************************************************/
49void zfStaPutApIntoBlockingList(zdev_t* dev, u8_t* bssid, u8_t weight)
50{
51    u16_t i, j;
52    zmw_get_wlan_dev(dev);
53    zmw_declare_for_critical_section();
54
55    if (weight > 0)
56    {
57        zmw_enter_critical_section(dev);
58        /*Find same bssid entry first*/
59        for (i=0; i<ZM_MAX_BLOCKING_AP_LIST_SIZE; i++)
60        {
61            for (j=0; j<6; j++)
62            {
63                if(wd->sta.blockingApList[i].addr[j]!= bssid[j])
64                {
65                    break;
66                }
67            }
68
69            if(j==6)
70            {
71                break;
72            }
73        }
74        /*This bssid doesn't have old record.Find an empty entry*/
75        if (i == ZM_MAX_BLOCKING_AP_LIST_SIZE)
76        {
77            for (i=0; i<ZM_MAX_BLOCKING_AP_LIST_SIZE; i++)
78            {
79                if (wd->sta.blockingApList[i].weight == 0)
80                {
81                    break;
82                }
83            }
84        }
85
86        /* If the list is full, pick one entry for replacement */
87        if (i == ZM_MAX_BLOCKING_AP_LIST_SIZE)
88        {
89            i = bssid[5] & (ZM_MAX_BLOCKING_AP_LIST_SIZE-1);
90        }
91
92        /* Update AP address and weight */
93        for (j=0; j<6; j++)
94        {
95            wd->sta.blockingApList[i].addr[j] = bssid[j];
96        }
97
98        wd->sta.blockingApList[i].weight = weight;
99        zmw_leave_critical_section(dev);
100    }
101
102    return;
103}
104
105
106/************************************************************************/
107/*                                                                      */
108/*    FUNCTION DESCRIPTION                  zfStaIsApInBlockingList     */
109/*      Is AP in blocking list.                                         */
110/*                                                                      */
111/*    INPUTS                                                            */
112/*      dev : device pointer                                            */
113/*      bssid : AP's BSSID                                              */
114/*                                                                      */
115/*    OUTPUTS                                                           */
116/*      TRUE : AP in blocking list                                      */
117/*      FALSE : AP not in blocking list                                 */
118/*                                                                      */
119/*    AUTHOR                                                            */
120/*      Stephen Chen        Atheros Communications, INC.    2006.12     */
121/*                                                                      */
122/************************************************************************/
123u16_t zfStaIsApInBlockingList(zdev_t* dev, u8_t* bssid)
124{
125    u16_t i, j;
126    zmw_get_wlan_dev(dev);
127    //zmw_declare_for_critical_section();
128
129    //zmw_enter_critical_section(dev);
130    for (i=0; i<ZM_MAX_BLOCKING_AP_LIST_SIZE; i++)
131    {
132        if (wd->sta.blockingApList[i].weight != 0)
133        {
134            for (j=0; j<6; j++)
135            {
136                if (wd->sta.blockingApList[i].addr[j] != bssid[j])
137                {
138                    break;
139                }
140            }
141            if (j == 6)
142            {
143                //zmw_leave_critical_section(dev);
144                return TRUE;
145            }
146        }
147    }
148    //zmw_leave_critical_section(dev);
149    return FALSE;
150}
151
152
153/************************************************************************/
154/*                                                                      */
155/*    FUNCTION DESCRIPTION                  zfStaRefreshBlockList       */
156/*      Is AP in blocking list.                                         */
157/*                                                                      */
158/*    INPUTS                                                            */
159/*      dev : device pointer                                            */
160/*      flushFlag : flush whole blocking list                           */
161/*                                                                      */
162/*    OUTPUTS                                                           */
163/*      none                                                            */
164/*                                                                      */
165/*    AUTHOR                                                            */
166/*      Stephen Chen        Atheros Communications, INC.    2006.12     */
167/*                                                                      */
168/************************************************************************/
169void zfStaRefreshBlockList(zdev_t* dev, u16_t flushFlag)
170{
171    u16_t i;
172    zmw_get_wlan_dev(dev);
173    zmw_declare_for_critical_section();
174
175    zmw_enter_critical_section(dev);
176    for (i=0; i<ZM_MAX_BLOCKING_AP_LIST_SIZE; i++)
177    {
178        if (wd->sta.blockingApList[i].weight != 0)
179        {
180            if (flushFlag != 0)
181            {
182                wd->sta.blockingApList[i].weight = 0;
183            }
184            else
185            {
186                wd->sta.blockingApList[i].weight--;
187            }
188        }
189    }
190    zmw_leave_critical_section(dev);
191    return;
192}
193
194
195/************************************************************************/
196/*                                                                      */
197/*    FUNCTION DESCRIPTION                  zfStaConnectFail            */
198/*      Handle Connect failure.                                         */
199/*                                                                      */
200/*    INPUTS                                                            */
201/*      dev : device pointer                                            */
202/*      bssid : BSSID                                                   */
203/*      reason : reason of failure                                      */
204/*                                                                      */
205/*    OUTPUTS                                                           */
206/*      none                                                            */
207/*                                                                      */
208/*    AUTHOR                                                            */
209/*      Stephen Chen        Atheros Communications, INC.    2006.12     */
210/*                                                                      */
211/************************************************************************/
212void zfStaConnectFail(zdev_t* dev, u16_t reason, u16_t* bssid, u8_t weight)
213{
214    zmw_get_wlan_dev(dev);
215
216    /* Change internal state */
217    zfChangeAdapterState(dev, ZM_STA_STATE_DISCONNECT);
218
219    /* Improve WEP/TKIP performance with HT AP, detail information please look bug#32495 */
220    //zfHpSetTTSIFSTime(dev, 0x8);
221
222    /* Notify wrapper of connection status changes */
223    if (wd->zfcbConnectNotify != NULL)
224    {
225        wd->zfcbConnectNotify(dev, reason, bssid);
226    }
227
228    /* Put AP into internal blocking list */
229    zfStaPutApIntoBlockingList(dev, (u8_t *)bssid, weight);
230
231    /* Issue another SCAN */
232    if ( wd->sta.bAutoReconnect )
233    {
234        zm_debug_msg0("Start internal scan...");
235        zfScanMgrScanStop(dev, ZM_SCAN_MGR_SCAN_INTERNAL);
236        zfScanMgrScanStart(dev, ZM_SCAN_MGR_SCAN_INTERNAL);
237    }
238}
239
240u8_t zfiWlanIBSSGetPeerStationsCount(zdev_t* dev)
241{
242    zmw_get_wlan_dev(dev);
243
244    return wd->sta.oppositeCount;
245}
246
247u8_t zfiWlanIBSSIteratePeerStations(zdev_t* dev, u8_t numToIterate, zfpIBSSIteratePeerStationCb callback, void *ctx)
248{
249    u8_t oppositeCount;
250    u8_t i;
251    u8_t index = 0;
252
253    zmw_get_wlan_dev(dev);
254
255    zmw_declare_for_critical_section();
256
257    zmw_enter_critical_section(dev);
258
259    oppositeCount = wd->sta.oppositeCount;
260    if ( oppositeCount > numToIterate )
261    {
262        oppositeCount = numToIterate;
263    }
264
265    for(i=0; i < ZM_MAX_OPPOSITE_COUNT; i++)
266    {
267        if ( oppositeCount == 0 )
268        {
269            break;
270        }
271
272        if ( wd->sta.oppositeInfo[i].valid == 0 )
273        {
274            continue;
275        }
276
277        callback(dev, &wd->sta.oppositeInfo[i], ctx, index++);
278        oppositeCount--;
279
280    }
281
282    zmw_leave_critical_section(dev);
283
284    return index;
285}
286
287
288s8_t zfStaFindFreeOpposite(zdev_t* dev, u16_t *sa, int *pFoundIdx)
289{
290    int oppositeCount;
291    int i;
292
293    zmw_get_wlan_dev(dev);
294
295    oppositeCount = wd->sta.oppositeCount;
296
297    for(i=0; i < ZM_MAX_OPPOSITE_COUNT; i++)
298    {
299        if ( oppositeCount == 0 )
300        {
301            break;
302        }
303
304        if ( wd->sta.oppositeInfo[i].valid == 0 )
305        {
306            continue;
307        }
308
309        oppositeCount--;
310        if ( zfMemoryIsEqual((u8_t*) sa, wd->sta.oppositeInfo[i].macAddr, 6) )
311        {
312            //wd->sta.oppositeInfo[i].aliveCounter++;
313            wd->sta.oppositeInfo[i].aliveCounter = ZM_IBSS_PEER_ALIVE_COUNTER;
314
315            /* it is already stored */
316            return 1;
317        }
318    }
319
320    // Check if there's still space for new comer
321    if ( wd->sta.oppositeCount == ZM_MAX_OPPOSITE_COUNT )
322    {
323        return -1;
324    }
325
326    // Find an unused slot for new peer station
327    for(i=0; i < ZM_MAX_OPPOSITE_COUNT; i++)
328    {
329        if ( wd->sta.oppositeInfo[i].valid == 0 )
330        {
331            break;
332        }
333    }
334
335    *pFoundIdx = i;
336    return 0;
337}
338
339s8_t zfStaFindOppositeByMACAddr(zdev_t* dev, u16_t *sa, u8_t *pFoundIdx)
340{
341    u32_t oppositeCount;
342    u32_t i;
343
344    zmw_get_wlan_dev(dev);
345
346    oppositeCount = wd->sta.oppositeCount;
347
348    for(i=0; i < ZM_MAX_OPPOSITE_COUNT; i++)
349    {
350        if ( oppositeCount == 0 )
351        {
352            break;
353        }
354
355        if ( wd->sta.oppositeInfo[i].valid == 0 )
356        {
357            continue;
358        }
359
360        oppositeCount--;
361        if ( zfMemoryIsEqual((u8_t*) sa, wd->sta.oppositeInfo[i].macAddr, 6) )
362        {
363            *pFoundIdx = (u8_t)i;
364
365            return 0;
366        }
367    }
368
369    *pFoundIdx = 0;
370    return 1;
371}
372
373static void zfStaInitCommonOppositeInfo(zdev_t* dev, int i)
374{
375    zmw_get_wlan_dev(dev);
376
377    /* set the default rate to the highest rate */
378    wd->sta.oppositeInfo[i].valid = 1;
379    wd->sta.oppositeInfo[i].aliveCounter = ZM_IBSS_PEER_ALIVE_COUNTER;
380    wd->sta.oppositeCount++;
381
382#ifdef ZM_ENABLE_IBSS_WPA2PSK
383    /* Set parameters for new opposite peer station !!! */
384    wd->sta.oppositeInfo[i].camIdx = 0xff;  // Not set key in this location
385    wd->sta.oppositeInfo[i].pkInstalled = 0;
386    wd->sta.oppositeInfo[i].wpaState = ZM_STA_WPA_STATE_INIT ;  // No encryption
387#endif
388}
389
390int zfStaSetOppositeInfoFromBSSInfo(zdev_t* dev, struct zsBssInfo* pBssInfo)
391{
392    int i;
393    u8_t*  dst;
394    u16_t  sa[3];
395    int res;
396    u32_t oneTxStreamCap;
397
398    zmw_get_wlan_dev(dev);
399
400    zfMemoryCopy((u8_t*) sa, pBssInfo->macaddr, 6);
401
402    res = zfStaFindFreeOpposite(dev, sa, &i);
403    if ( res != 0 )
404    {
405        goto zlReturn;
406    }
407
408    dst = wd->sta.oppositeInfo[i].macAddr;
409    zfMemoryCopy(dst, (u8_t *)sa, 6);
410
411    oneTxStreamCap = (zfHpCapability(dev) & ZM_HP_CAP_11N_ONE_TX_STREAM);
412
413    if (pBssInfo->extSupportedRates[1] != 0)
414    {
415        /* TODO : Handle 11n */
416        if (pBssInfo->frequency < 3000)
417        {
418            /* 2.4GHz */
419            if (pBssInfo->EnableHT == 1)
420                zfRateCtrlInitCell(dev, &wd->sta.oppositeInfo[i].rcCell, (oneTxStreamCap!=0)?3:2, 1, pBssInfo->SG40);
421            else
422                zfRateCtrlInitCell(dev, &wd->sta.oppositeInfo[i].rcCell, 1, 1, pBssInfo->SG40);
423        }
424        else
425        {
426            /* 5GHz */
427            if (pBssInfo->EnableHT == 1)
428                zfRateCtrlInitCell(dev, &wd->sta.oppositeInfo[i].rcCell, (oneTxStreamCap!=0)?3:2, 0, pBssInfo->SG40);
429            else
430                zfRateCtrlInitCell(dev, &wd->sta.oppositeInfo[i].rcCell, 1, 0, pBssInfo->SG40);
431        }
432    }
433    else
434    {
435        /* TODO : Handle 11n */
436        if (pBssInfo->frequency < 3000)
437        {
438            /* 2.4GHz */
439            if (pBssInfo->EnableHT == 1)
440                zfRateCtrlInitCell(dev, &wd->sta.oppositeInfo[i].rcCell, (oneTxStreamCap!=0)?3:2, 1, pBssInfo->SG40);
441            else
442                zfRateCtrlInitCell(dev, &wd->sta.oppositeInfo[i].rcCell, 0, 1, pBssInfo->SG40);
443        }
444        else
445        {
446            /* 5GHz */
447            if (pBssInfo->EnableHT == 1)
448                zfRateCtrlInitCell(dev, &wd->sta.oppositeInfo[i].rcCell, (oneTxStreamCap!=0)?3:2, 0, pBssInfo->SG40);
449            else
450                zfRateCtrlInitCell(dev, &wd->sta.oppositeInfo[i].rcCell, 1, 0, pBssInfo->SG40);
451        }
452    }
453
454
455    zfStaInitCommonOppositeInfo(dev, i);
456zlReturn:
457    return 0;
458}
459
460int zfStaSetOppositeInfoFromRxBuf(zdev_t* dev, zbuf_t* buf)
461{
462    int   i;
463    u8_t*  dst;
464    u16_t  sa[3];
465    int res = 0;
466    u16_t  offset;
467    u8_t   bSupportExtRate;
468    u32_t rtsctsRate = 0xffffffff; /* CTS:OFDM 6M, RTS:OFDM 6M */
469    u32_t oneTxStreamCap;
470
471    zmw_get_wlan_dev(dev);
472    zmw_declare_for_critical_section();
473
474    sa[0] = zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A2_OFFSET);
475    sa[1] = zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A2_OFFSET+2);
476    sa[2] = zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A2_OFFSET+4);
477
478    zmw_enter_critical_section(dev);
479
480    res = zfStaFindFreeOpposite(dev, sa, &i);
481    if ( res != 0 )
482    {
483        goto zlReturn;
484    }
485
486    dst = wd->sta.oppositeInfo[i].macAddr;
487    zfCopyFromRxBuffer(dev, buf, dst, ZM_WLAN_HEADER_A2_OFFSET, 6);
488
489    if ( (wd->sta.currentFrequency < 3000) && !(wd->supportMode & (ZM_WIRELESS_MODE_24_54|ZM_WIRELESS_MODE_24_N)) )
490    {
491        bSupportExtRate = 0;
492    } else {
493        bSupportExtRate = 1;
494    }
495
496    if ( (bSupportExtRate == 1)
497         && (wd->sta.currentFrequency < 3000)
498         && (wd->wlanMode == ZM_MODE_IBSS)
499         && (wd->wfc.bIbssGMode == 0) )
500    {
501        bSupportExtRate = 0;
502    }
503
504    wd->sta.connection_11b = 0;
505    oneTxStreamCap = (zfHpCapability(dev) & ZM_HP_CAP_11N_ONE_TX_STREAM);
506
507    if ( ((offset = zfFindElement(dev, buf, ZM_WLAN_EID_EXTENDED_RATE)) != 0xffff)
508         && (bSupportExtRate == 1) )
509    {
510        /* TODO : Handle 11n */
511        if (wd->sta.currentFrequency < 3000)
512        {
513            /* 2.4GHz */
514            if (wd->sta.EnableHT == 1)
515            {
516                //11ng
517                zfRateCtrlInitCell(dev, &wd->sta.oppositeInfo[i].rcCell, (oneTxStreamCap!=0)?3:2, 1, wd->sta.SG40);
518            }
519            else
520            {
521                //11g
522                zfRateCtrlInitCell(dev, &wd->sta.oppositeInfo[i].rcCell, 1, 1, wd->sta.SG40);
523            }
524            rtsctsRate = 0x00001bb; /* CTS:CCK 1M, RTS:OFDM 6M */
525        }
526        else
527        {
528            /* 5GHz */
529            if (wd->sta.EnableHT == 1)
530            {
531                //11na
532                zfRateCtrlInitCell(dev, &wd->sta.oppositeInfo[i].rcCell, (oneTxStreamCap!=0)?3:2, 0, wd->sta.SG40);
533            }
534            else
535            {
536                //11a
537                zfRateCtrlInitCell(dev, &wd->sta.oppositeInfo[i].rcCell, 1, 0, wd->sta.SG40);
538            }
539            rtsctsRate = 0x10b01bb; /* CTS:OFDM 6M, RTS:OFDM 6M */
540        }
541    }
542    else
543    {
544        /* TODO : Handle 11n */
545        if (wd->sta.currentFrequency < 3000)
546        {
547            /* 2.4GHz */
548            if (wd->sta.EnableHT == 1)
549            {
550                //11ng
551                zfRateCtrlInitCell(dev, &wd->sta.oppositeInfo[i].rcCell, (oneTxStreamCap!=0)?3:2, 1, wd->sta.SG40);
552                rtsctsRate = 0x00001bb; /* CTS:CCK 1M, RTS:OFDM 6M */
553            }
554            else
555            {
556                //11b
557                zfRateCtrlInitCell(dev, &wd->sta.oppositeInfo[i].rcCell, 0, 1, wd->sta.SG40);
558                rtsctsRate = 0x0; /* CTS:CCK 1M, RTS:CCK 1M */
559                wd->sta.connection_11b = 1;
560            }
561        }
562        else
563        {
564            /* 5GHz */
565            if (wd->sta.EnableHT == 1)
566            {
567                //11na
568                zfRateCtrlInitCell(dev, &wd->sta.oppositeInfo[i].rcCell, (oneTxStreamCap!=0)?3:2, 0, wd->sta.SG40);
569            }
570            else
571            {
572                //11a
573                zfRateCtrlInitCell(dev, &wd->sta.oppositeInfo[i].rcCell, 1, 0, wd->sta.SG40);
574            }
575            rtsctsRate = 0x10b01bb; /* CTS:OFDM 6M, RTS:OFDM 6M */
576        }
577    }
578
579    zfStaInitCommonOppositeInfo(dev, i);
580
581zlReturn:
582    zmw_leave_critical_section(dev);
583
584    if (rtsctsRate != 0xffffffff)
585    {
586        zfHpSetRTSCTSRate(dev, rtsctsRate);
587    }
588    return res;
589}
590
591void zfStaProtErpMonitor(zdev_t* dev, zbuf_t* buf)
592{
593    u16_t   offset;
594    u8_t    erp;
595    u8_t    bssid[6];
596
597    zmw_get_wlan_dev(dev);
598
599    if ( (wd->wlanMode == ZM_MODE_INFRASTRUCTURE)&&(zfStaIsConnected(dev)) )
600    {
601        ZM_MAC_WORD_TO_BYTE(wd->sta.bssid, bssid);
602
603        if (zfRxBufferEqualToStr(dev, buf, bssid, ZM_WLAN_HEADER_A2_OFFSET, 6))
604        {
605            offset = zfFindElement(dev, buf, ZM_WLAN_EID_ERP);
606            if (offset != 0xffff)
607            {
608                erp = zmw_rx_buf_readb(dev, buf, offset+2);
609
610                if ( erp & ZM_BIT_1 )
611                {
612                    //zm_debug_msg0("protection mode on");
613                    if (wd->sta.bProtectionMode == FALSE)
614                    {
615                        wd->sta.bProtectionMode = TRUE;
616                        zfHpSetSlotTime(dev, 0);
617                    }
618                }
619                else
620                {
621                    //zm_debug_msg0("protection mode off");
622                    if (wd->sta.bProtectionMode == TRUE)
623                    {
624                        wd->sta.bProtectionMode = FALSE;
625                        zfHpSetSlotTime(dev, 1);
626                    }
627                }
628            }
629        }
630		//Check the existence of Non-N AP
631		//Follow the check the "pBssInfo->EnableHT"
632			offset = zfFindElement(dev, buf, ZM_WLAN_EID_HT_CAPABILITY);
633			if (offset != 0xffff)
634			{}
635			else if ((offset = zfFindElement(dev, buf, ZM_WLAN_PREN2_EID_HTCAPABILITY)) != 0xffff)
636			{}
637			else
638			{wd->sta.NonNAPcount++;}
639    }
640}
641
642void zfStaUpdateWmeParameter(zdev_t* dev, zbuf_t* buf)
643{
644    u16_t   tmp;
645    u16_t   aifs[5];
646    u16_t   cwmin[5];
647    u16_t   cwmax[5];
648    u16_t   txop[5];
649    u8_t    acm;
650    u8_t    ac;
651    u16_t   len;
652    u16_t   i;
653   	u16_t   offset;
654    u8_t    rxWmeParameterSetCount;
655
656    zmw_get_wlan_dev(dev);
657
658    /* Update if WME parameter set count is changed */
659    /* If connect to WME AP */
660    if (wd->sta.wmeConnected != 0)
661    {
662        /* Find WME parameter element */
663        offset = zfFindWifiElement(dev, buf, 2, 1);
664        if (offset != 0xffff)
665        {
666            len = zmw_rx_buf_readb(dev, buf, offset+1);
667            if (len >= 7)
668            {
669                rxWmeParameterSetCount=zmw_rx_buf_readb(dev, buf, offset+8);
670                if (rxWmeParameterSetCount != wd->sta.wmeParameterSetCount)
671                {
672                    zm_msg0_mm(ZM_LV_0, "wmeParameterSetCount changed!");
673                    wd->sta.wmeParameterSetCount = rxWmeParameterSetCount;
674                    /* retrieve WME parameter and update TxQ parameters */
675                    acm = 0xf;
676                    for (i=0; i<4; i++)
677                    {
678                        if (len >= (8+(i*4)+4))
679                        {
680                            tmp=zmw_rx_buf_readb(dev, buf, offset+10+i*4);
681                            ac = (tmp >> 5) & 0x3;
682                            if ((tmp & 0x10) == 0)
683                            {
684                                acm &= (~(1<<ac));
685                            }
686                            aifs[ac] = ((tmp & 0xf) * 9) + 10;
687                            tmp=zmw_rx_buf_readb(dev, buf, offset+11+i*4);
688                            /* Convert to 2^n */
689                            cwmin[ac] = zcCwTlb[(tmp & 0xf)];
690                            cwmax[ac] = zcCwTlb[(tmp >> 4)];
691                            txop[ac]=zmw_rx_buf_readh(dev, buf,
692                                    offset+12+i*4);
693                        }
694                    }
695
696                    if ((acm & 0x4) != 0)
697                    {
698                        cwmin[2] = cwmin[0];
699                        cwmax[2] = cwmax[0];
700                        aifs[2] = aifs[0];
701                        txop[2] = txop[0];
702                    }
703                    if ((acm & 0x8) != 0)
704                    {
705                        cwmin[3] = cwmin[2];
706                        cwmax[3] = cwmax[2];
707                        aifs[3] = aifs[2];
708                        txop[3] = txop[2];
709                    }
710                    cwmin[4] = 3;
711                    cwmax[4] = 7;
712                    aifs[4] = 28;
713
714                    if ((cwmin[2]+aifs[2]) > ((cwmin[0]+aifs[0])+1))
715                    {
716                        wd->sta.ac0PriorityHigherThanAc2 = 1;
717                    }
718                    else
719                    {
720                        wd->sta.ac0PriorityHigherThanAc2 = 0;
721                    }
722                    zfHpUpdateQosParameter(dev, cwmin, cwmax, aifs, txop);
723                }
724            }
725        }
726    } //if (wd->sta.wmeConnected != 0)
727}
728/* process 802.11h Dynamic Frequency Selection */
729void zfStaUpdateDot11HDFS(zdev_t* dev, zbuf_t* buf)
730{
731    //u8_t    length, channel, is5G;
732    u16_t   offset;
733
734    zmw_get_wlan_dev(dev);
735
736    /*
737    Channel Switch Announcement Element Format
738    +------+----------+------+-------------------+------------------+--------------------+
739    |Format|Element ID|Length|Channel Switch Mode|New Channel Number|Channel Switch Count|
740    +------+----------+------+-------------------+------------------+--------------------+
741    |Bytes |   1      |  1   |	     1           |       1          |          1         |
742    +------+----------+------+-------------------+------------------+--------------------+
743    |Value |   37     |  3   |       0 or 1      |unsigned integer  |unsigned integer    |
744    +------+----------+------+-------------------+------------------+--------------------+
745    */
746
747    /* get EID(Channel Switch Announcement) */
748    offset = zfFindElement(dev, buf, ZM_WLAN_EID_CHANNEL_SWITCH_ANNOUNCE);
749    if (offset == 0xffff)
750    {
751        //zm_debug_msg0("EID(Channel Switch Announcement) not found");
752        return;
753    }
754    else if ( zmw_rx_buf_readb(dev, buf, offset+1) == 0x3 )
755    {
756        zm_debug_msg0("EID(Channel Switch Announcement) found");
757
758        //length = zmw_rx_buf_readb(dev, buf, offset+1);
759        //zfCopyFromRxBuffer(dev, buf, pBssInfo->supportedRates, offset, length+2);
760
761        //Chanell Switch Mode set to 1, driver should disable transmit immediate
762        //we do this by poll CCA high
763        if (zmw_rx_buf_readb(dev, buf, offset+2) == 0x1 )
764        {
765        	//use ZM_OID_INTERNAL_WRITE,ZM_CMD_RESET to notice firmware flush quene and stop dma,
766        	//then restart rx dma but not tx dma
767        	if (wd->sta.DFSDisableTx != TRUE)
768        	{
769                /* TODO : zfHpResetTxRx would cause Rx hang */
770                //zfHpResetTxRx(dev);
771                wd->sta.DFSDisableTx = TRUE;
772                /* Trgger Rx DMA */
773                zfHpStartRecv(dev);
774            }
775        	//Adapter->ZD80211HSetting.DisableTxBy80211H=TRUE;
776        	//AcquireCtrOfPhyReg(Adapter);
777        	//ZD1205_WRITE_REGISTER(Adapter,CR24, 0x0);
778        	//ReleaseDoNotSleep(Adapter);
779        }
780
781        if (zmw_rx_buf_readb(dev, buf, offset+4) <= 0x2 )
782        {
783        	//Channel Switch
784        	//if Channel Switch Count = 0 , STA should change channel immediately.
785        	//if Channel Switch Count > 0 , STA should change channel after TBTT*count
786        	//But it won't be accurate to let driver calculate TBTT*count, and the value of
787        	//Channel Switch Count will decrease by one each when continue receving beacon
788        	//So we change channel here when we receive count <=2.
789
790            zfHpDeleteAllowChannel(dev, wd->sta.currentFrequency);
791        	wd->frequency = zfChNumToFreq(dev, zmw_rx_buf_readb(dev, buf, offset+3), 0);
792        	//zfHpAddAllowChannel(dev, wd->frequency);
793        	zm_debug_msg1("CWY - jump to frequency = ", wd->frequency);
794        	zfCoreSetFrequency(dev, wd->frequency);
795        	wd->sta.DFSDisableTx = FALSE;
796            /* Increase rxBeaconCount to prevent beacon lost */
797            if (zfStaIsConnected(dev))
798            {
799                wd->sta.rxBeaconCount = 1 << 6; // 2 times of check would pass
800            }
801        	//start tx dma to transmit packet
802
803        	//if (zmw_rx_buf_readb(dev, buf, offset+3) != wd->frequency)
804        	//{
805        	//	//ZDDbgPrint(("Radar Detect by AP\n"));
806        	//	zfCoreSetFrequency();
807        	//	ProcessRadarDetectEvent(Adapter);
808        	//	Set_RF_Channel(Adapter, SwRfd->Rfd->RxBuffer[index+3], (UCHAR)Adapter->RF_Mode, 1);
809        	//	Adapter->CardSetting.Channel = SwRfd->Rfd->RxBuffer[index+3];
810        	//	Adapter->SaveChannel = Adapter->CardSetting.Channel;
811        	//	Adapter->UtilityChannel = Adapter->CardSetting.Channel;
812        	//}
813        }
814    }
815
816}
817/* TODO : process 802.11h Transmission Power Control */
818void zfStaUpdateDot11HTPC(zdev_t* dev, zbuf_t* buf)
819{
820}
821
822/* IBSS power-saving mode */
823void zfStaIbssPSCheckState(zdev_t* dev, zbuf_t* buf)
824{
825    u8_t   i, frameCtrl;
826
827    zmw_get_wlan_dev(dev);
828
829    if ( !zfStaIsConnected(dev) )
830    {
831        return;
832    }
833
834    if ( wd->wlanMode != ZM_MODE_IBSS )
835    {
836        return ;
837    }
838
839    /* check BSSID */
840    if ( !zfRxBufferEqualToStr(dev, buf, (u8_t*) wd->sta.bssid,
841                               ZM_WLAN_HEADER_A3_OFFSET, 6) )
842    {
843        return;
844    }
845
846    frameCtrl = zmw_rx_buf_readb(dev, buf, 1);
847
848    /* check power management bit */
849    if ( frameCtrl & ZM_BIT_4 )
850    {
851        for(i=1; i<ZM_MAX_PS_STA; i++)
852        {
853            if ( !wd->sta.staPSList.entity[i].bUsed )
854            {
855                continue;
856            }
857
858            /* check source address */
859            if ( zfRxBufferEqualToStr(dev, buf,
860                                      wd->sta.staPSList.entity[i].macAddr,
861                                      ZM_WLAN_HEADER_A2_OFFSET, 6) )
862            {
863                return;
864            }
865        }
866
867        for(i=1; i<ZM_MAX_PS_STA; i++)
868        {
869            if ( !wd->sta.staPSList.entity[i].bUsed )
870            {
871                wd->sta.staPSList.entity[i].bUsed = TRUE;
872                wd->sta.staPSList.entity[i].bDataQueued = FALSE;
873                break;
874            }
875        }
876
877        if ( i == ZM_MAX_PS_STA )
878        {
879            /* STA list is full */
880            return;
881        }
882
883        zfCopyFromRxBuffer(dev, buf, wd->sta.staPSList.entity[i].macAddr,
884                           ZM_WLAN_HEADER_A2_OFFSET, 6);
885
886        if ( wd->sta.staPSList.count == 0 )
887        {
888            // enable ATIM window
889            //zfEnableAtimWindow(dev);
890        }
891
892        wd->sta.staPSList.count++;
893    }
894    else if ( wd->sta.staPSList.count )
895    {
896        for(i=1; i<ZM_MAX_PS_STA; i++)
897        {
898            if ( wd->sta.staPSList.entity[i].bUsed )
899            {
900                if ( zfRxBufferEqualToStr(dev, buf,
901                                          wd->sta.staPSList.entity[i].macAddr,
902                                          ZM_WLAN_HEADER_A2_OFFSET, 6) )
903                {
904                    wd->sta.staPSList.entity[i].bUsed = FALSE;
905                    wd->sta.staPSList.count--;
906
907                    if ( wd->sta.staPSList.entity[i].bDataQueued )
908                    {
909                        /* send queued data */
910                    }
911                }
912            }
913        }
914
915        if ( wd->sta.staPSList.count == 0 )
916        {
917            /* disable ATIM window */
918            //zfDisableAtimWindow(dev);
919        }
920
921    }
922}
923
924/* IBSS power-saving mode */
925u8_t zfStaIbssPSQueueData(zdev_t* dev, zbuf_t* buf)
926{
927    u8_t   i;
928    u16_t  da[3];
929
930    zmw_get_wlan_dev(dev);
931
932    if ( !zfStaIsConnected(dev) )
933    {
934        return 0;
935    }
936
937    if ( wd->wlanMode != ZM_MODE_IBSS )
938    {
939        return 0;
940    }
941
942    if ( wd->sta.staPSList.count == 0 && wd->sta.powerSaveMode <= ZM_STA_PS_NONE )
943    {
944        return 0;
945    }
946
947    /* DA */
948#ifdef ZM_ENABLE_NATIVE_WIFI
949    da[0] = zmw_tx_buf_readh(dev, buf, ZM_WLAN_HEADER_A1_OFFSET);
950    da[1] = zmw_tx_buf_readh(dev, buf, ZM_WLAN_HEADER_A1_OFFSET + 2);
951    da[2] = zmw_tx_buf_readh(dev, buf, ZM_WLAN_HEADER_A1_OFFSET + 4);
952#else
953    da[0] = zmw_tx_buf_readh(dev, buf, 0);
954    da[1] = zmw_tx_buf_readh(dev, buf, 2);
955    da[2] = zmw_tx_buf_readh(dev, buf, 4);
956#endif
957
958    if ( ZM_IS_MULTICAST_OR_BROADCAST(da) )
959    {
960        wd->sta.staPSList.entity[0].bDataQueued = TRUE;
961        wd->sta.ibssPSDataQueue[wd->sta.ibssPSDataCount++] = buf;
962        return 1;
963    }
964
965    // Unicast packet...
966
967    for(i=1; i<ZM_MAX_PS_STA; i++)
968    {
969        if ( zfMemoryIsEqual(wd->sta.staPSList.entity[i].macAddr,
970                             (u8_t*) da, 6) )
971        {
972            wd->sta.staPSList.entity[i].bDataQueued = TRUE;
973            wd->sta.ibssPSDataQueue[wd->sta.ibssPSDataCount++] = buf;
974
975            return 1;
976        }
977    }
978
979
980    return 0;
981}
982
983/* IBSS power-saving mode */
984void zfStaIbssPSSend(zdev_t* dev)
985{
986    u8_t   i;
987    u16_t  bcastAddr[3] = {0xffff, 0xffff, 0xffff};
988
989    zmw_get_wlan_dev(dev);
990
991    if ( !zfStaIsConnected(dev) )
992    {
993        return ;
994    }
995
996    if ( wd->wlanMode != ZM_MODE_IBSS )
997    {
998        return ;
999    }
1000
1001    for(i=0; i<ZM_MAX_PS_STA; i++)
1002    {
1003        if ( wd->sta.staPSList.entity[i].bDataQueued )
1004        {
1005            if ( i == 0 )
1006            {
1007                zfSendMmFrame(dev, ZM_WLAN_FRAME_TYPE_ATIM,
1008                              bcastAddr,
1009                              0, 0, 0);
1010            }
1011            else if ( wd->sta.staPSList.entity[i].bUsed )
1012            {
1013                // Send ATIM to prevent the peer to go to sleep
1014                zfSendMmFrame(dev, ZM_WLAN_FRAME_TYPE_ATIM,
1015                              (u16_t*) wd->sta.staPSList.entity[i].macAddr,
1016                              0, 0, 0);
1017            }
1018
1019            wd->sta.staPSList.entity[i].bDataQueued = FALSE;
1020        }
1021    }
1022
1023    for(i=0; i<wd->sta.ibssPSDataCount; i++)
1024    {
1025        zfTxSendEth(dev, wd->sta.ibssPSDataQueue[i], 0,
1026                    ZM_EXTERNAL_ALLOC_BUF, 0);
1027    }
1028
1029    wd->sta.ibssPrevPSDataCount = wd->sta.ibssPSDataCount;
1030    wd->sta.ibssPSDataCount = 0;
1031}
1032
1033
1034void zfStaReconnect(zdev_t* dev)
1035{
1036    zmw_get_wlan_dev(dev);
1037    zmw_declare_for_critical_section();
1038
1039    if ( wd->wlanMode != ZM_MODE_INFRASTRUCTURE &&
1040         wd->wlanMode != ZM_MODE_IBSS )
1041    {
1042        return;
1043    }
1044
1045    if ( (zfStaIsConnected(dev))||(zfStaIsConnecting(dev)) )
1046    {
1047        return;
1048    }
1049
1050    if ( wd->sta.bChannelScan )
1051    {
1052        return;
1053    }
1054
1055    /* Recover zero SSID length  */
1056    if ( (wd->wlanMode == ZM_MODE_INFRASTRUCTURE) && (wd->ws.ssidLen == 0))
1057    {
1058        zm_debug_msg0("zfStaReconnect: NOT Support!! Set SSID to any BSS");
1059        /* ANY BSS */
1060        zmw_enter_critical_section(dev);
1061        wd->sta.ssid[0] = 0;
1062        wd->sta.ssidLen = 0;
1063        zmw_leave_critical_section(dev);
1064    }
1065
1066    // RAY: To ensure no TX pending before re-connecting
1067    zfFlushVtxq(dev);
1068    zfWlanEnable(dev);
1069    zfScanMgrScanAck(dev);
1070}
1071
1072void zfStaTimer100ms(zdev_t* dev)
1073{
1074    zmw_get_wlan_dev(dev);
1075
1076    if ( (wd->tick % 10) == 0 )
1077    {
1078        zfPushVtxq(dev);
1079//        zfPowerSavingMgrMain(dev);
1080    }
1081}
1082
1083
1084void zfStaCheckRxBeacon(zdev_t* dev)
1085{
1086    zmw_get_wlan_dev(dev);
1087
1088    if (( wd->wlanMode == ZM_MODE_INFRASTRUCTURE ) && (zfStaIsConnected(dev)))
1089    {
1090        if (wd->beaconInterval == 0)
1091        {
1092            wd->beaconInterval = 100;
1093        }
1094        if ( (wd->tick % ((wd->beaconInterval * 10) / ZM_MS_PER_TICK)) == 0 )
1095        {
1096            /* Check rxBeaconCount */
1097            if (wd->sta.rxBeaconCount == 0)
1098            {
1099                if (wd->sta.beaconMissState == 1)
1100                {
1101            	/*notify AP that we left*/
1102            	zfSendMmFrame(dev, ZM_WLAN_FRAME_TYPE_DEAUTH, wd->sta.bssid, 3, 0, 0);
1103                /* Beacon Lost */
1104                zfStaConnectFail(dev, ZM_STATUS_MEDIA_DISCONNECT_BEACON_MISS,
1105                        wd->sta.bssid, 0);
1106                }
1107                else
1108                {
1109                    wd->sta.beaconMissState = 1;
1110                    /* Reset channel */
1111                    zfCoreSetFrequencyExV2(dev, wd->frequency, wd->BandWidth40,
1112                            wd->ExtOffset, NULL, 1);
1113                }
1114            }
1115            else
1116            {
1117                wd->sta.beaconMissState = 0;
1118            }
1119            wd->sta.rxBeaconCount = 0;
1120        }
1121    }
1122}
1123
1124
1125
1126void zfStaCheckConnectTimeout(zdev_t* dev)
1127{
1128    zmw_get_wlan_dev(dev);
1129    zmw_declare_for_critical_section();
1130
1131    if ( wd->wlanMode != ZM_MODE_INFRASTRUCTURE )
1132    {
1133        return;
1134    }
1135
1136    if ( !zfStaIsConnecting(dev) )
1137    {
1138        return;
1139    }
1140
1141    zmw_enter_critical_section(dev);
1142    if ( (wd->sta.connectState == ZM_STA_CONN_STATE_AUTH_OPEN)||
1143         (wd->sta.connectState == ZM_STA_CONN_STATE_AUTH_SHARE_1)||
1144         (wd->sta.connectState == ZM_STA_CONN_STATE_AUTH_SHARE_2)||
1145         (wd->sta.connectState == ZM_STA_CONN_STATE_ASSOCIATE) )
1146    {
1147        if ( (wd->tick - wd->sta.connectTimer) > ZM_INTERVAL_CONNECT_TIMEOUT )
1148        {
1149            if ( wd->sta.connectByReasso )
1150            {
1151                wd->sta.failCntOfReasso++;
1152                if ( wd->sta.failCntOfReasso > 2 )
1153                {
1154                    wd->sta.connectByReasso = FALSE;
1155                }
1156            }
1157
1158            wd->sta.connectState = ZM_STA_CONN_STATE_NONE;
1159            zm_debug_msg1("connect timeout, state = ", wd->sta.connectState);
1160            //zfiWlanDisable(dev);
1161            goto failed;
1162        }
1163    }
1164
1165    zmw_leave_critical_section(dev);
1166    return;
1167
1168failed:
1169    zmw_leave_critical_section(dev);
1170    if(wd->sta.authMode == ZM_AUTH_MODE_AUTO)
1171	{ // Fix some AP not send authentication failed message to sta and lead to connect timeout !
1172            wd->sta.connectTimeoutCount++;
1173	}
1174    zfStaConnectFail(dev, ZM_STATUS_MEDIA_DISCONNECT_TIMEOUT, wd->sta.bssid, 2);
1175    return;
1176}
1177
1178void zfMmStaTimeTick(zdev_t* dev)
1179{
1180    zmw_get_wlan_dev(dev);
1181
1182    /* airopeek */
1183    if (wd->wlanMode != ZM_MODE_AP && !wd->swSniffer)
1184    {
1185        if ( wd->tick & 1 )
1186        {
1187            zfTimerCheckAndHandle(dev);
1188        }
1189
1190        zfStaCheckRxBeacon(dev);
1191        zfStaTimer100ms(dev);
1192        zfStaCheckConnectTimeout(dev);
1193        zfPowerSavingMgrMain(dev);
1194    }
1195
1196#ifdef ZM_ENABLE_AGGREGATION
1197    /*
1198     * add by honda
1199     */
1200    zfAggScanAndClear(dev, wd->tick);
1201#endif
1202}
1203
1204void zfStaSendBeacon(zdev_t* dev)
1205{
1206    zbuf_t* buf;
1207    u16_t offset, seq;
1208
1209    zmw_get_wlan_dev(dev);
1210
1211    zmw_declare_for_critical_section();
1212
1213    //zm_debug_msg0("\n");
1214
1215    /* TBD : Maximum size of beacon */
1216    buf = zfwBufAllocate(dev, 1024);
1217    if (buf == NULL)
1218    {
1219        zm_debug_msg0("Allocate beacon buffer failed");
1220        return;
1221    }
1222
1223    offset = 0;
1224    /* wlan header */
1225    /* Frame control */
1226    zmw_tx_buf_writeh(dev, buf, offset, 0x0080);
1227    offset+=2;
1228    /* Duration */
1229    zmw_tx_buf_writeh(dev, buf, offset, 0x0000);
1230    offset+=2;
1231    /* Address 1 */
1232    zmw_tx_buf_writeh(dev, buf, offset, 0xffff);
1233    offset+=2;
1234    zmw_tx_buf_writeh(dev, buf, offset, 0xffff);
1235    offset+=2;
1236    zmw_tx_buf_writeh(dev, buf, offset, 0xffff);
1237    offset+=2;
1238    /* Address 2 */
1239    zmw_tx_buf_writeh(dev, buf, offset, wd->macAddr[0]);
1240    offset+=2;
1241    zmw_tx_buf_writeh(dev, buf, offset, wd->macAddr[1]);
1242    offset+=2;
1243    zmw_tx_buf_writeh(dev, buf, offset, wd->macAddr[2]);
1244    offset+=2;
1245    /* Address 3 */
1246    zmw_tx_buf_writeh(dev, buf, offset, wd->sta.bssid[0]);
1247    offset+=2;
1248    zmw_tx_buf_writeh(dev, buf, offset, wd->sta.bssid[1]);
1249    offset+=2;
1250    zmw_tx_buf_writeh(dev, buf, offset, wd->sta.bssid[2]);
1251    offset+=2;
1252
1253    /* Sequence number */
1254    zmw_enter_critical_section(dev);
1255    seq = ((wd->mmseq++)<<4);
1256    zmw_leave_critical_section(dev);
1257    zmw_tx_buf_writeh(dev, buf, offset, seq);
1258    offset+=2;
1259
1260    /* 24-31 Time Stamp : hardware will fill this field */
1261    offset+=8;
1262
1263    /* Beacon Interval */
1264    zmw_tx_buf_writeh(dev, buf, offset, wd->beaconInterval);
1265    offset+=2;
1266
1267    /* Capability */
1268    zmw_tx_buf_writeb(dev, buf, offset++, wd->sta.capability[0]);
1269    zmw_tx_buf_writeb(dev, buf, offset++, wd->sta.capability[1]);
1270
1271    /* SSID */
1272    offset = zfStaAddIeSsid(dev, buf, offset);
1273
1274    if(wd->frequency <= ZM_CH_G_14)  // 2.4 GHz  b+g
1275    {
1276
1277    	/* Support Rate */
1278    	offset = zfMmAddIeSupportRate(dev, buf, offset,
1279                                  		ZM_WLAN_EID_SUPPORT_RATE, ZM_RATE_SET_CCK);
1280
1281    	/* DS parameter set */
1282    	offset = zfMmAddIeDs(dev, buf, offset);
1283
1284    	offset = zfStaAddIeIbss(dev, buf, offset);
1285
1286        if( wd->wfc.bIbssGMode
1287            && (wd->supportMode & (ZM_WIRELESS_MODE_24_54|ZM_WIRELESS_MODE_24_N)) )    // Only accompany with enabling a mode .
1288        {
1289      	    /* ERP Information */
1290       	    wd->erpElement = 0;
1291       	    offset = zfMmAddIeErp(dev, buf, offset);
1292       	}
1293
1294       	/* TODO : country information */
1295        /* RSN */
1296        if ( wd->sta.authMode == ZM_AUTH_MODE_WPA2PSK )
1297        {
1298            offset = zfwStaAddIeWpaRsn(dev, buf, offset, ZM_WLAN_FRAME_TYPE_AUTH);
1299        }
1300
1301        if( wd->wfc.bIbssGMode
1302            && (wd->supportMode & (ZM_WIRELESS_MODE_24_54|ZM_WIRELESS_MODE_24_N)) )    // Only accompany with enabling a mode .
1303        {
1304            /* Enable G Mode */
1305            /* Extended Supported Rates */
1306       	    offset = zfMmAddIeSupportRate(dev, buf, offset,
1307                                   		    ZM_WLAN_EID_EXTENDED_RATE, ZM_RATE_SET_OFDM);
1308	    }
1309    }
1310    else    // 5GHz a
1311    {
1312        /* Support Rate a Mode */
1313    	offset = zfMmAddIeSupportRate(dev, buf, offset,
1314        	                            ZM_WLAN_EID_SUPPORT_RATE, ZM_RATE_SET_OFDM);
1315
1316        /* DS parameter set */
1317    	offset = zfMmAddIeDs(dev, buf, offset);
1318
1319    	offset = zfStaAddIeIbss(dev, buf, offset);
1320
1321        /* TODO : country information */
1322        /* RSN */
1323        if ( wd->sta.authMode == ZM_AUTH_MODE_WPA2PSK )
1324        {
1325            offset = zfwStaAddIeWpaRsn(dev, buf, offset, ZM_WLAN_FRAME_TYPE_AUTH);
1326        }
1327    }
1328
1329    if ( wd->wlanMode != ZM_MODE_IBSS )
1330    {
1331        /* TODO : Need to check if it is ok */
1332        /* HT Capabilities Info */
1333        offset = zfMmAddHTCapability(dev, buf, offset);
1334
1335        /* Extended HT Capabilities Info */
1336        offset = zfMmAddExtendedHTCapability(dev, buf, offset);
1337    }
1338
1339    if ( wd->sta.ibssAdditionalIESize )
1340        offset = zfStaAddIbssAdditionalIE(dev, buf, offset);
1341
1342    /* 1212 : write to beacon fifo */
1343    /* 1221 : write to share memory */
1344    zfHpSendBeacon(dev, buf, offset);
1345
1346    /* Free beacon buffer */
1347    //zfwBufFree(dev, buf, 0);
1348}
1349
1350void zfStaSignalStatistic(zdev_t* dev, u8_t SignalStrength, u8_t SignalQuality) //CWYang(+)
1351{
1352    zmw_get_wlan_dev(dev);
1353
1354    /* Add Your Code to Do Works Like Moving Average Here */
1355    wd->SignalStrength = (wd->SignalStrength * 7 + SignalStrength * 3)/10;
1356    wd->SignalQuality = (wd->SignalQuality * 7 + SignalQuality * 3)/10;
1357
1358}
1359
1360struct zsBssInfo* zfStaFindBssInfo(zdev_t* dev, zbuf_t* buf, struct zsWlanProbeRspFrameHeader *pProbeRspHeader)
1361{
1362    u8_t    i;
1363    u8_t    j;
1364    u8_t    k;
1365    u8_t    isMatched, length, channel;
1366    u16_t   offset, frequency;
1367    struct zsBssInfo* pBssInfo;
1368
1369    zmw_get_wlan_dev(dev);
1370
1371    pBssInfo = wd->sta.bssList.head;
1372    if (pBssInfo == NULL)
1373    {
1374        return NULL;
1375    }
1376
1377    for( i=0; i<wd->sta.bssList.bssCount; i++ )
1378    {
1379        //zm_debug_msg2("check pBssInfo = ", pBssInfo);
1380
1381        /* Check BSSID */
1382        for( j=0; j<6; j++ )
1383        {
1384            if ( pBssInfo->bssid[j] != pProbeRspHeader->bssid[j] )
1385            {
1386                break;
1387            }
1388        }
1389
1390		/* Check SSID */
1391        if (j == 6)
1392        {
1393            if (pProbeRspHeader->ssid[1] <= 32)
1394            {
1395                /* compare length and ssid */
1396                isMatched = 1;
1397				if((pProbeRspHeader->ssid[1] != 0) && (pBssInfo->ssid[1] != 0))
1398				{
1399                for( k=1; k<pProbeRspHeader->ssid[1] + 1; k++ )
1400                {
1401                    if ( pBssInfo->ssid[k] != pProbeRspHeader->ssid[k] )
1402                    {
1403                        isMatched = 0;
1404                        break;
1405                    }
1406                }
1407            }
1408            }
1409            else
1410            {
1411                isMatched = 0;
1412            }
1413        }
1414        else
1415        {
1416            isMatched = 0;
1417        }
1418
1419        /* Check channel */
1420        /* Add check channel to solve the bug #31222 */
1421        if (isMatched) {
1422            offset = zfFindElement(dev, buf, ZM_WLAN_EID_DS);
1423            if (offset != 0xffff) {
1424                length = zmw_rx_buf_readb(dev, buf, offset+1);
1425                if (length == 1) {
1426                    channel = zmw_rx_buf_readb(dev, buf, offset+2);
1427                    if (zfHpIsAllowedChannel(dev, zfChNumToFreq(dev, channel, 0)) == 0) {
1428                        frequency = 0;
1429                    } else {
1430                        frequency = zfChNumToFreq(dev, channel, 0);;
1431                    }
1432                } else {
1433                    frequency = 0;
1434                }
1435            } else {
1436                frequency = wd->sta.currentFrequency;
1437            }
1438
1439            if (frequency != 0) {
1440                if ( ((frequency > 3000) && (pBssInfo->frequency > 3000))
1441                     || ((frequency < 3000) && (pBssInfo->frequency < 3000)) ) {
1442                    /* redundant */
1443                    break;
1444                }
1445            }
1446        }
1447
1448        pBssInfo = pBssInfo->next;
1449    }
1450
1451    if ( i == wd->sta.bssList.bssCount )
1452    {
1453        pBssInfo = NULL;
1454    }
1455
1456    return pBssInfo;
1457}
1458
1459u8_t zfStaInitBssInfo(zdev_t* dev, zbuf_t* buf,
1460        struct zsWlanProbeRspFrameHeader *pProbeRspHeader,
1461        struct zsBssInfo* pBssInfo, struct zsAdditionInfo* AddInfo, u8_t type)
1462{
1463    u8_t    length, channel, is5G;
1464    u16_t   i, offset;
1465    u8_t    apQosInfo;
1466    u16_t    eachIElength = 0;
1467    u16_t   accumulateLen = 0;
1468
1469    zmw_get_wlan_dev(dev);
1470
1471    if ((type == 1) && ((pBssInfo->flag & ZM_BSS_INFO_VALID_BIT) != 0))
1472    {
1473        goto zlUpdateRssi;
1474    }
1475
1476    /* get SSID */
1477    offset = zfFindElement(dev, buf, ZM_WLAN_EID_SSID);
1478    if (offset == 0xffff)
1479    {
1480        zm_debug_msg0("EID(SSID) not found");
1481        goto zlError;
1482    }
1483
1484    length = zmw_rx_buf_readb(dev, buf, offset+1);
1485
1486	{
1487		u8_t Show_Flag = 0;
1488		zfwGetShowZeroLengthSSID(dev, &Show_Flag);
1489
1490		if(Show_Flag)
1491		{
1492			if (length > ZM_MAX_SSID_LENGTH )
1493			{
1494				zm_debug_msg0("EID(SSID) is invalid");
1495				goto zlError;
1496			}
1497		}
1498		else
1499		{
1500    if ( length == 0 || length > ZM_MAX_SSID_LENGTH )
1501    {
1502        zm_debug_msg0("EID(SSID) is invalid");
1503        goto zlError;
1504    }
1505
1506		}
1507	}
1508    zfCopyFromRxBuffer(dev, buf, pBssInfo->ssid, offset, length+2);
1509
1510    /* get DS parameter */
1511    offset = zfFindElement(dev, buf, ZM_WLAN_EID_DS);
1512    if (offset != 0xffff)
1513    {
1514        length = zmw_rx_buf_readb(dev, buf, offset+1);
1515        if ( length != 1 )
1516        {
1517            zm_msg0_mm(ZM_LV_0, "Abnormal DS Param Set IE");
1518            goto zlError;
1519        }
1520        channel = zmw_rx_buf_readb(dev, buf, offset+2);
1521
1522        if (zfHpIsAllowedChannel(dev, zfChNumToFreq(dev, channel, 0)) == 0)
1523        {
1524            goto zlError2;
1525        }
1526
1527        pBssInfo->frequency = zfChNumToFreq(dev, channel, 0); // auto check
1528        pBssInfo->channel = channel;
1529
1530
1531    }
1532    else
1533    {
1534        /* DS parameter not found */
1535        pBssInfo->frequency = wd->sta.currentFrequency;
1536        pBssInfo->channel = zfChFreqToNum(wd->sta.currentFrequency, &is5G);
1537    }
1538
1539    /* initialize security type */
1540    pBssInfo->securityType = ZM_SECURITY_TYPE_NONE;
1541
1542    /* get macaddr */
1543    for( i=0; i<6; i++ )
1544    {
1545        pBssInfo->macaddr[i] = pProbeRspHeader->sa[i];
1546    }
1547
1548    /* get bssid */
1549    for( i=0; i<6; i++ )
1550    {
1551        pBssInfo->bssid[i] = pProbeRspHeader->bssid[i];
1552    }
1553
1554    /* get timestamp */
1555    for( i=0; i<8; i++ )
1556    {
1557        pBssInfo->timeStamp[i] = pProbeRspHeader->timeStamp[i];
1558    }
1559
1560    /* get beacon interval */
1561    pBssInfo->beaconInterval[0] = pProbeRspHeader->beaconInterval[0];
1562    pBssInfo->beaconInterval[1] = pProbeRspHeader->beaconInterval[1];
1563
1564    /* get capability */
1565    pBssInfo->capability[0] = pProbeRspHeader->capability[0];
1566    pBssInfo->capability[1] = pProbeRspHeader->capability[1];
1567
1568    /* Copy frame body */
1569    offset = 36;            // Copy from the start of variable IE
1570    pBssInfo->frameBodysize = zfwBufGetSize(dev, buf)-offset;
1571    if (pBssInfo->frameBodysize > (ZM_MAX_PROBE_FRAME_BODY_SIZE-1))
1572    {
1573        pBssInfo->frameBodysize = ZM_MAX_PROBE_FRAME_BODY_SIZE-1;
1574    }
1575    accumulateLen = 0;
1576    do
1577    {
1578        eachIElength = zmw_rx_buf_readb(dev, buf, offset + accumulateLen+1) + 2;  //Len+(EID+Data)
1579
1580        if ( (eachIElength >= 2)
1581             && ((accumulateLen + eachIElength) <= pBssInfo->frameBodysize) )
1582        {
1583            zfCopyFromRxBuffer(dev, buf, pBssInfo->frameBody+accumulateLen, offset+accumulateLen, eachIElength);
1584            accumulateLen+=(u16_t)eachIElength;
1585        }
1586        else
1587        {
1588            zm_msg0_mm(ZM_LV_1, "probersp frameBodysize abnormal");
1589            break;
1590        }
1591    }
1592    while(accumulateLen < pBssInfo->frameBodysize);
1593    pBssInfo->frameBodysize = accumulateLen;
1594
1595    /* get supported rates */
1596    offset = zfFindElement(dev, buf, ZM_WLAN_EID_SUPPORT_RATE);
1597    if (offset == 0xffff)
1598    {
1599        zm_debug_msg0("EID(supported rates) not found");
1600        goto zlError;
1601    }
1602
1603    length = zmw_rx_buf_readb(dev, buf, offset+1);
1604    if ( length == 0 || length > ZM_MAX_SUPP_RATES_IE_SIZE)
1605    {
1606        zm_msg0_mm(ZM_LV_0, "Supported rates IE length abnormal");
1607        goto zlError;
1608    }
1609    zfCopyFromRxBuffer(dev, buf, pBssInfo->supportedRates, offset, length+2);
1610
1611
1612
1613    /* get Country information */
1614    offset = zfFindElement(dev, buf, ZM_WLAN_EID_COUNTRY);
1615    if (offset != 0xffff)
1616    {
1617        length = zmw_rx_buf_readb(dev, buf, offset+1);
1618        if (length > ZM_MAX_COUNTRY_INFO_SIZE)
1619        {
1620            length = ZM_MAX_COUNTRY_INFO_SIZE;
1621        }
1622        zfCopyFromRxBuffer(dev, buf, pBssInfo->countryInfo, offset, length+2);
1623        /* check 802.11d support data */
1624        if (wd->sta.b802_11D)
1625        {
1626            zfHpGetRegulationTablefromISO(dev, (u8_t *)&pBssInfo->countryInfo, 3);
1627            /* only set regulatory one time */
1628            wd->sta.b802_11D = 0;
1629        }
1630    }
1631
1632    /* get ERP information */
1633    offset = zfFindElement(dev, buf, ZM_WLAN_EID_ERP);
1634    if (offset != 0xffff)
1635    {
1636        pBssInfo->erp = zmw_rx_buf_readb(dev, buf, offset+2);
1637    }
1638
1639    /* get extended supported rates */
1640    offset = zfFindElement(dev, buf, ZM_WLAN_EID_EXTENDED_RATE);
1641    if (offset != 0xffff)
1642    {
1643        length = zmw_rx_buf_readb(dev, buf, offset+1);
1644        if (length > ZM_MAX_SUPP_RATES_IE_SIZE)
1645        {
1646            zm_msg0_mm(ZM_LV_0, "Extended rates IE length abnormal");
1647            goto zlError;
1648        }
1649        zfCopyFromRxBuffer(dev, buf, pBssInfo->extSupportedRates, offset, length+2);
1650    }
1651    else
1652    {
1653        pBssInfo->extSupportedRates[0] = 0;
1654        pBssInfo->extSupportedRates[1] = 0;
1655    }
1656
1657    /* get WPA IE */
1658    offset = zfFindElement(dev, buf, ZM_WLAN_EID_WPA_IE);
1659    if (offset != 0xffff)
1660    {
1661        length = zmw_rx_buf_readb(dev, buf, offset+1);
1662        if (length > ZM_MAX_IE_SIZE)
1663        {
1664            length = ZM_MAX_IE_SIZE;
1665        }
1666        zfCopyFromRxBuffer(dev, buf, pBssInfo->wpaIe, offset, length+2);
1667        pBssInfo->securityType = ZM_SECURITY_TYPE_WPA;
1668    }
1669    else
1670    {
1671        pBssInfo->wpaIe[1] = 0;
1672    }
1673
1674    /* get WPS IE */
1675    offset = zfFindWifiElement(dev, buf, 4, 0xff);
1676    if (offset != 0xffff)
1677    {
1678        length = zmw_rx_buf_readb(dev, buf, offset+1);
1679        if (length > ZM_MAX_WPS_IE_SIZE )
1680        {
1681            length = ZM_MAX_WPS_IE_SIZE;
1682        }
1683        zfCopyFromRxBuffer(dev, buf, pBssInfo->wscIe, offset, length+2);
1684    }
1685    else
1686    {
1687        pBssInfo->wscIe[1] = 0;
1688    }
1689
1690    /* get SuperG IE */
1691    offset = zfFindSuperGElement(dev, buf, ZM_WLAN_EID_VENDOR_PRIVATE);
1692    if (offset != 0xffff)
1693    {
1694        pBssInfo->apCap |= ZM_SuperG_AP;
1695    }
1696
1697    /* get XR IE */
1698    offset = zfFindXRElement(dev, buf, ZM_WLAN_EID_VENDOR_PRIVATE);
1699    if (offset != 0xffff)
1700    {
1701        pBssInfo->apCap |= ZM_XR_AP;
1702    }
1703
1704    /* get RSN IE */
1705    offset = zfFindElement(dev, buf, ZM_WLAN_EID_RSN_IE);
1706    if (offset != 0xffff)
1707    {
1708        length = zmw_rx_buf_readb(dev, buf, offset+1);
1709        if (length > ZM_MAX_IE_SIZE)
1710        {
1711            length = ZM_MAX_IE_SIZE;
1712        }
1713        zfCopyFromRxBuffer(dev, buf, pBssInfo->rsnIe, offset, length+2);
1714        pBssInfo->securityType = ZM_SECURITY_TYPE_WPA;
1715    }
1716    else
1717    {
1718        pBssInfo->rsnIe[1] = 0;
1719    }
1720#ifdef ZM_ENABLE_CENC
1721    /* get CENC IE */
1722    offset = zfFindElement(dev, buf, ZM_WLAN_EID_CENC_IE);
1723    if (offset != 0xffff)
1724    {
1725        length = zmw_rx_buf_readb(dev, buf, offset+1);
1726        if (length > ZM_MAX_IE_SIZE )
1727        {
1728            length = ZM_MAX_IE_SIZE;
1729        }
1730        zfCopyFromRxBuffer(dev, buf, pBssInfo->cencIe, offset, length+2);
1731        pBssInfo->securityType = ZM_SECURITY_TYPE_CENC;
1732        pBssInfo->capability[0] &= 0xffef;
1733    }
1734    else
1735    {
1736        pBssInfo->cencIe[1] = 0;
1737    }
1738#endif //ZM_ENABLE_CENC
1739    /* get WME Parameter IE, probe rsp may contain WME parameter element */
1740    //if ( wd->bQoSEnable )
1741    {
1742        offset = zfFindWifiElement(dev, buf, 2, 1);
1743        if (offset != 0xffff)
1744        {
1745            apQosInfo = zmw_rx_buf_readb(dev, buf, offset+8) & 0x80;
1746            pBssInfo->wmeSupport = 1 | apQosInfo;
1747        }
1748        else if ((offset = zfFindWifiElement(dev, buf, 2, 0)) != 0xffff)
1749        {
1750            apQosInfo = zmw_rx_buf_readb(dev, buf, offset+8) & 0x80;
1751            pBssInfo->wmeSupport = 1  | apQosInfo;
1752        }
1753        else
1754        {
1755            pBssInfo->wmeSupport = 0;
1756        }
1757    }
1758    //CWYang(+)
1759    offset = zfFindElement(dev, buf, ZM_WLAN_EID_HT_CAPABILITY);
1760    if (offset != 0xffff)
1761    {
1762        /* 11n AP */
1763        pBssInfo->EnableHT = 1;
1764        if (zmw_rx_buf_readb(dev, buf, offset+1) & 0x02)
1765        {
1766            pBssInfo->enableHT40 = 1;
1767        }
1768        else
1769        {
1770            pBssInfo->enableHT40 = 0;
1771        }
1772
1773        if (zmw_rx_buf_readb(dev, buf, offset+1) & 0x40)
1774        {
1775            pBssInfo->SG40 = 1;
1776        }
1777        else
1778        {
1779            pBssInfo->SG40 = 0;
1780        }
1781    }
1782    else if ((offset = zfFindElement(dev, buf, ZM_WLAN_PREN2_EID_HTCAPABILITY)) != 0xffff)
1783    {
1784        /* 11n AP */
1785        pBssInfo->EnableHT = 1;
1786        pBssInfo->apCap |= ZM_All11N_AP;
1787        if (zmw_rx_buf_readb(dev, buf, offset+2) & 0x02)
1788        {
1789            pBssInfo->enableHT40 = 1;
1790        }
1791        else
1792        {
1793            pBssInfo->enableHT40 = 0;
1794        }
1795
1796        if (zmw_rx_buf_readb(dev, buf, offset+2) & 0x40)
1797        {
1798            pBssInfo->SG40 = 1;
1799        }
1800        else
1801        {
1802            pBssInfo->SG40 = 0;
1803        }
1804    }
1805    else
1806    {
1807        pBssInfo->EnableHT = 0;
1808    }
1809    /* HT information */
1810    offset = zfFindElement(dev, buf, ZM_WLAN_EID_EXTENDED_HT_CAPABILITY);
1811    if (offset != 0xffff)
1812    {
1813        /* atheros pre n */
1814        pBssInfo->extChOffset = zmw_rx_buf_readb(dev, buf, offset+2) & 0x03;
1815    }
1816    else if ((offset = zfFindElement(dev, buf, ZM_WLAN_PREN2_EID_HTINFORMATION)) != 0xffff)
1817    {
1818        /* pre n 2.0 standard */
1819        pBssInfo->extChOffset = zmw_rx_buf_readb(dev, buf, offset+3) & 0x03;
1820    }
1821    else
1822    {
1823        pBssInfo->extChOffset = 0;
1824    }
1825
1826    if ( (pBssInfo->enableHT40 == 1)
1827         && ((pBssInfo->extChOffset != 1) && (pBssInfo->extChOffset != 3)) )
1828    {
1829        pBssInfo->enableHT40 = 0;
1830    }
1831
1832    if (pBssInfo->enableHT40 == 1)
1833    {
1834        if (zfHpIsAllowedChannel(dev, pBssInfo->frequency+((pBssInfo->extChOffset==1)?20:-20)) == 0)
1835        {
1836            /* if extension channel is not an allowed channel, treat AP as non-HT mode */
1837            pBssInfo->EnableHT = 0;
1838            pBssInfo->enableHT40 = 0;
1839            pBssInfo->extChOffset = 0;
1840        }
1841    }
1842
1843    /* get ATH Extended Capability */
1844    if ( ((offset = zfFindElement(dev, buf, ZM_WLAN_EID_EXTENDED_HT_CAPABILITY)) != 0xffff)&&
1845        ((offset = zfFindBrdcmMrvlRlnkExtCap(dev, buf)) == 0xffff))
1846
1847    {
1848        pBssInfo->athOwlAp = 1;
1849    }
1850    else
1851    {
1852        pBssInfo->athOwlAp = 0;
1853    }
1854
1855    /* get Broadcom Extended Capability */
1856    if ( (pBssInfo->EnableHT == 1) //((offset = zfFindElement(dev, buf, ZM_WLAN_EID_EXTENDED_HT_CAPABILITY)) != 0xffff)
1857         && ((offset = zfFindBroadcomExtCap(dev, buf)) != 0xffff) )
1858    {
1859        pBssInfo->broadcomHTAp = 1;
1860    }
1861    else
1862    {
1863        pBssInfo->broadcomHTAp = 0;
1864    }
1865
1866    /* get Marvel Extended Capability */
1867    offset = zfFindMarvelExtCap(dev, buf);
1868    if (offset != 0xffff)
1869    {
1870        pBssInfo->marvelAp = 1;
1871    }
1872    else
1873    {
1874        pBssInfo->marvelAp = 0;
1875    }
1876
1877    /* get ATIM window */
1878    offset = zfFindElement(dev, buf, ZM_WLAN_EID_IBSS);
1879    if (offset != 0xffff )
1880    {
1881        pBssInfo->atimWindow = zmw_rx_buf_readh(dev, buf,offset+2);
1882    }
1883
1884    /* Fit for support mode */
1885    if (pBssInfo->frequency > 3000) {
1886        if (wd->supportMode & ZM_WIRELESS_MODE_5_N) {
1887        } else {
1888            if (wd->supportMode & ZM_WIRELESS_MODE_5_54) {
1889                /* support mode: a */
1890                /* delete n mode information */
1891                pBssInfo->EnableHT = 0;
1892                pBssInfo->enableHT40 = 0;
1893                pBssInfo->apCap &= (~ZM_All11N_AP);
1894                pBssInfo->extChOffset = 0;
1895                pBssInfo->frameBodysize = zfRemoveElement(dev, pBssInfo->frameBody,
1896                            pBssInfo->frameBodysize, ZM_WLAN_EID_HT_CAPABILITY);
1897                pBssInfo->frameBodysize = zfRemoveElement(dev, pBssInfo->frameBody,
1898                            pBssInfo->frameBodysize, ZM_WLAN_PREN2_EID_HTCAPABILITY);
1899                pBssInfo->frameBodysize = zfRemoveElement(dev, pBssInfo->frameBody,
1900                            pBssInfo->frameBodysize, ZM_WLAN_EID_EXTENDED_HT_CAPABILITY);
1901                pBssInfo->frameBodysize = zfRemoveElement(dev, pBssInfo->frameBody,
1902                            pBssInfo->frameBodysize, ZM_WLAN_PREN2_EID_HTINFORMATION);
1903            } else {
1904                /* support mode: none */
1905                goto zlError2;
1906            }
1907        }
1908    } else {
1909        if (wd->supportMode & ZM_WIRELESS_MODE_24_N) {
1910        } else {
1911            /* delete n mode information */
1912            pBssInfo->EnableHT = 0;
1913            pBssInfo->enableHT40 = 0;
1914            pBssInfo->apCap &= (~ZM_All11N_AP);
1915            pBssInfo->extChOffset = 0;
1916            pBssInfo->frameBodysize = zfRemoveElement(dev, pBssInfo->frameBody,
1917                        pBssInfo->frameBodysize, ZM_WLAN_EID_HT_CAPABILITY);
1918            pBssInfo->frameBodysize = zfRemoveElement(dev, pBssInfo->frameBody,
1919                        pBssInfo->frameBodysize, ZM_WLAN_PREN2_EID_HTCAPABILITY);
1920            pBssInfo->frameBodysize = zfRemoveElement(dev, pBssInfo->frameBody,
1921                        pBssInfo->frameBodysize, ZM_WLAN_EID_EXTENDED_HT_CAPABILITY);
1922            pBssInfo->frameBodysize = zfRemoveElement(dev, pBssInfo->frameBody,
1923                        pBssInfo->frameBodysize, ZM_WLAN_PREN2_EID_HTINFORMATION);
1924
1925            if (wd->supportMode & ZM_WIRELESS_MODE_24_54) {
1926            } else {
1927                if (wd->supportMode & ZM_WIRELESS_MODE_24_11) {
1928                    /* support mode: b */
1929                    /* delete n mode information */
1930                    if ( zfIsGOnlyMode(dev, pBssInfo->frequency, pBssInfo->supportedRates)
1931                         || zfIsGOnlyMode(dev, pBssInfo->frequency, pBssInfo->extSupportedRates) ) {
1932                        goto zlError2;
1933                    } else {
1934                        zfGatherBMode(dev, pBssInfo->supportedRates,
1935                                          pBssInfo->extSupportedRates);
1936                        pBssInfo->erp = 0;
1937
1938                        pBssInfo->frameBodysize = zfRemoveElement(dev,
1939                            pBssInfo->frameBody, pBssInfo->frameBodysize,
1940                            ZM_WLAN_EID_ERP);
1941                        pBssInfo->frameBodysize = zfRemoveElement(dev,
1942                            pBssInfo->frameBody, pBssInfo->frameBodysize,
1943                            ZM_WLAN_EID_EXTENDED_RATE);
1944
1945                        pBssInfo->frameBodysize = zfUpdateElement(dev,
1946                            pBssInfo->frameBody, pBssInfo->frameBodysize,
1947                            pBssInfo->supportedRates);
1948                    }
1949                } else {
1950                    /* support mode: none */
1951                    goto zlError2;
1952                }
1953            }
1954        }
1955    }
1956
1957    pBssInfo->flag |= ZM_BSS_INFO_VALID_BIT;
1958
1959zlUpdateRssi:
1960    /* Update Timer information */
1961    pBssInfo->tick = wd->tick;
1962
1963    /* Update ERP information */
1964    offset = zfFindElement(dev, buf, ZM_WLAN_EID_ERP);
1965    if (offset != 0xffff)
1966    {
1967        pBssInfo->erp = zmw_rx_buf_readb(dev, buf, offset+2);
1968    }
1969
1970    if( (s8_t)pBssInfo->signalStrength < (s8_t)AddInfo->Tail.Data.SignalStrength1 )
1971    {
1972        /* Update signal strength */
1973        pBssInfo->signalStrength = (u8_t)AddInfo->Tail.Data.SignalStrength1;
1974        /* Update signal quality */
1975        pBssInfo->signalQuality = (u8_t)(AddInfo->Tail.Data.SignalStrength1 * 2);
1976
1977        /* Update the sorting value  */
1978        pBssInfo->sortValue = zfComputeBssInfoWeightValue(dev,
1979                                               (pBssInfo->supportedRates[6] + pBssInfo->extSupportedRates[0]),
1980                                               pBssInfo->EnableHT,
1981                                               pBssInfo->enableHT40,
1982                                               pBssInfo->signalStrength);
1983    }
1984
1985    return 0;
1986
1987zlError:
1988
1989    return 1;
1990
1991zlError2:
1992
1993    return 2;
1994}
1995
1996void zfStaProcessBeacon(zdev_t* dev, zbuf_t* buf, struct zsAdditionInfo* AddInfo) //CWYang(m)
1997{
1998    /* Parse TIM and send PS-POLL in power saving mode */
1999    struct zsWlanBeaconFrameHeader*  pBeaconHeader;
2000    struct zsBssInfo* pBssInfo;
2001    u8_t   pBuf[sizeof(struct zsWlanBeaconFrameHeader)];
2002    u8_t   bssid[6];
2003    int    res;
2004
2005    zmw_get_wlan_dev(dev);
2006
2007    zmw_declare_for_critical_section();
2008
2009    /* sta routine jobs */
2010    zfStaProtErpMonitor(dev, buf);  /* check protection mode */
2011
2012    if (zfStaIsConnected(dev))
2013    {
2014        ZM_MAC_WORD_TO_BYTE(wd->sta.bssid, bssid);
2015
2016        if ( wd->wlanMode == ZM_MODE_INFRASTRUCTURE )
2017        {
2018            if ( zfRxBufferEqualToStr(dev, buf, bssid, ZM_WLAN_HEADER_A2_OFFSET, 6) )
2019            {
2020                zfPowerSavingMgrProcessBeacon(dev, buf);
2021                zfStaUpdateWmeParameter(dev, buf);
2022                if (wd->sta.DFSEnable)
2023                    zfStaUpdateDot11HDFS(dev, buf);
2024                if (wd->sta.TPCEnable)
2025                    zfStaUpdateDot11HTPC(dev, buf);
2026                /* update signal strength and signal quality */
2027                zfStaSignalStatistic(dev, AddInfo->Tail.Data.SignalStrength1,
2028                        AddInfo->Tail.Data.SignalQuality); //CWYang(+)
2029                wd->sta.rxBeaconCount++;
2030            }
2031        }
2032        else if ( wd->wlanMode == ZM_MODE_IBSS )
2033        {
2034            if ( zfRxBufferEqualToStr(dev, buf, bssid, ZM_WLAN_HEADER_A3_OFFSET, 6) )
2035            {
2036                int res;
2037                struct zsPartnerNotifyEvent event;
2038
2039                zm_debug_msg0("20070916 Receive opposite Beacon!");
2040                zmw_enter_critical_section(dev);
2041                wd->sta.ibssReceiveBeaconCount++;
2042                zmw_leave_critical_section(dev);
2043
2044                res = zfStaSetOppositeInfoFromRxBuf(dev, buf);
2045                if ( res == 0 )
2046                {
2047                    // New peer station found. Notify the wrapper now
2048                    zfInitPartnerNotifyEvent(dev, buf, &event);
2049                    if (wd->zfcbIbssPartnerNotify != NULL)
2050                    {
2051                        wd->zfcbIbssPartnerNotify(dev, 1, &event);
2052                    }
2053                }
2054                /* update signal strength and signal quality */
2055                zfStaSignalStatistic(dev, AddInfo->Tail.Data.SignalStrength1,
2056                        AddInfo->Tail.Data.SignalQuality); //CWYang(+)
2057            }
2058            //else if ( wd->sta.ibssPartnerStatus == ZM_IBSS_PARTNER_LOST )
2059            // Why does this happen in IBSS?? The impact of Vista since
2060            // we need to tell it the BSSID
2061        }
2062    }
2063
2064    /* return if not channel scan */
2065    if ( !wd->sta.bChannelScan )
2066    {
2067        goto zlReturn;
2068    }
2069
2070    zfCopyFromRxBuffer(dev, buf, pBuf, 0, sizeof(struct zsWlanBeaconFrameHeader));
2071    pBeaconHeader = (struct zsWlanBeaconFrameHeader*) pBuf;
2072
2073    zmw_enter_critical_section(dev);
2074
2075    //zm_debug_msg1("bss count = ", wd->sta.bssList.bssCount);
2076
2077    pBssInfo = zfStaFindBssInfo(dev, buf, pBeaconHeader);
2078
2079    if ( pBssInfo == NULL )
2080    {
2081        /* Allocate a new entry if BSS not in the scan list */
2082        pBssInfo = zfBssInfoAllocate(dev);
2083        if (pBssInfo != NULL)
2084        {
2085            res = zfStaInitBssInfo(dev, buf, pBeaconHeader, pBssInfo, AddInfo, 0);
2086            //zfDumpSSID(pBssInfo->ssid[1], &(pBssInfo->ssid[2]));
2087            if ( res != 0 )
2088            {
2089                zfBssInfoFree(dev, pBssInfo);
2090            }
2091            else
2092            {
2093                zfBssInfoInsertToList(dev, pBssInfo);
2094            }
2095        }
2096    }
2097    else
2098    {
2099        res = zfStaInitBssInfo(dev, buf, pBeaconHeader, pBssInfo, AddInfo, 1);
2100        if (res == 2)
2101        {
2102            zfBssInfoRemoveFromList(dev, pBssInfo);
2103            zfBssInfoFree(dev, pBssInfo);
2104        }
2105        else if ( wd->wlanMode == ZM_MODE_IBSS )
2106        {
2107            int idx;
2108
2109            // It would reset the alive counter if the peer station is found!
2110            zfStaFindFreeOpposite(dev, (u16_t *)pBssInfo->macaddr, &idx);
2111        }
2112    }
2113
2114    zmw_leave_critical_section(dev);
2115
2116zlReturn:
2117
2118    return;
2119}
2120
2121
2122void zfAuthFreqCompleteCb(zdev_t* dev)
2123{
2124    zmw_get_wlan_dev(dev);
2125    zmw_declare_for_critical_section();
2126
2127    zmw_enter_critical_section(dev);
2128
2129    if (wd->sta.connectState == ZM_STA_CONN_STATE_AUTH_COMPLETED)
2130    {
2131        zm_debug_msg0("ZM_STA_CONN_STATE_ASSOCIATE");
2132        wd->sta.connectTimer = wd->tick;
2133        wd->sta.connectState = ZM_STA_CONN_STATE_ASSOCIATE;
2134    }
2135
2136    zmw_leave_critical_section(dev);
2137    return;
2138}
2139
2140/************************************************************************/
2141/*                                                                      */
2142/*    FUNCTION DESCRIPTION                  zfProcessAuth               */
2143/*      Process authenticate management frame.                          */
2144/*                                                                      */
2145/*    INPUTS                                                            */
2146/*      dev : device pointer                                            */
2147/*      buf : auth frame buffer                                         */
2148/*                                                                      */
2149/*    OUTPUTS                                                           */
2150/*      none                                                            */
2151/*                                                                      */
2152/*    AUTHOR                                                            */
2153/*      Stephen Chen        ZyDAS Technology Corporation    2005.10     */
2154/*                                                                      */
2155/************************************************************************/
2156/* Note : AP allows one authenticating STA at a time, does not          */
2157/*        support multiple authentication process. Make sure            */
2158/*        authentication state machine will not be blocked due          */
2159/*        to incompleted authentication handshake.                      */
2160void zfStaProcessAuth(zdev_t* dev, zbuf_t* buf, u16_t* src, u16_t apId)
2161{
2162    struct zsWlanAuthFrameHeader* pAuthFrame;
2163    u8_t  pBuf[sizeof(struct zsWlanAuthFrameHeader)];
2164    u32_t p1, p2;
2165
2166    zmw_get_wlan_dev(dev);
2167    zmw_declare_for_critical_section();
2168
2169    if ( !zfStaIsConnecting(dev) )
2170    {
2171        return;
2172    }
2173
2174    pAuthFrame = (struct zsWlanAuthFrameHeader*) pBuf;
2175    zfCopyFromRxBuffer(dev, buf, pBuf, 0, sizeof(struct zsWlanAuthFrameHeader));
2176
2177    if ( wd->sta.connectState == ZM_STA_CONN_STATE_AUTH_OPEN )
2178    {
2179        if ( (zmw_le16_to_cpu(pAuthFrame->seq) == 2)&&
2180             (zmw_le16_to_cpu(pAuthFrame->algo) == 0)&&
2181             (zmw_le16_to_cpu(pAuthFrame->status) == 0) )
2182        {
2183
2184            zmw_enter_critical_section(dev);
2185            wd->sta.connectTimer = wd->tick;
2186            zm_debug_msg0("ZM_STA_CONN_STATE_AUTH_COMPLETED");
2187            wd->sta.connectState = ZM_STA_CONN_STATE_AUTH_COMPLETED;
2188            zmw_leave_critical_section(dev);
2189
2190            //Set channel according to AP's configuration
2191            //Move to here because of Cisco 11n AP feature
2192            zfCoreSetFrequencyEx(dev, wd->frequency, wd->BandWidth40,
2193                    wd->ExtOffset, zfAuthFreqCompleteCb);
2194
2195            /* send association frame */
2196            if ( wd->sta.connectByReasso )
2197            {
2198                zfSendMmFrame(dev, ZM_WLAN_FRAME_TYPE_REASOCREQ,
2199                              wd->sta.bssid, 0, 0, 0);
2200            }
2201            else
2202            {
2203                zfSendMmFrame(dev, ZM_WLAN_FRAME_TYPE_ASOCREQ,
2204                              wd->sta.bssid, 0, 0, 0);
2205            }
2206
2207
2208        }
2209        else
2210        {
2211            zm_debug_msg1("authentication failed, status = ",
2212                          pAuthFrame->status);
2213
2214            if (wd->sta.authMode == ZM_AUTH_MODE_AUTO)
2215            {
2216                wd->sta.bIsSharedKey = 1;
2217                zfStaStartConnect(dev, wd->sta.bIsSharedKey);
2218            }
2219            else
2220            {
2221                zm_debug_msg0("ZM_STA_STATE_DISCONNECT");
2222                zfStaConnectFail(dev, ZM_STATUS_MEDIA_DISCONNECT_AUTH_FAILED, wd->sta.bssid, 3);
2223            }
2224        }
2225    }
2226    else if ( wd->sta.connectState == ZM_STA_CONN_STATE_AUTH_SHARE_1 )
2227    {
2228        if ( (zmw_le16_to_cpu(pAuthFrame->algo) == 1) &&
2229             (zmw_le16_to_cpu(pAuthFrame->seq) == 2) &&
2230             (zmw_le16_to_cpu(pAuthFrame->status) == 0))
2231              //&& (pAuthFrame->challengeText[1] <= 255) )
2232        {
2233            zfMemoryCopy(wd->sta.challengeText, pAuthFrame->challengeText,
2234                         pAuthFrame->challengeText[1]+2);
2235
2236            /* send the 3rd authentication frame */
2237            p1 = 0x30001;
2238            p2 = 0;
2239            zfSendMmFrame(dev, ZM_WLAN_FRAME_TYPE_AUTH,
2240                          wd->sta.bssid, p1, p2, 0);
2241
2242            zmw_enter_critical_section(dev);
2243            wd->sta.connectTimer = wd->tick;
2244
2245            zm_debug_msg0("ZM_STA_SUB_STATE_AUTH_SHARE_2");
2246            wd->sta.connectState = ZM_STA_CONN_STATE_AUTH_SHARE_2;
2247            zmw_leave_critical_section(dev);
2248        }
2249        else
2250        {
2251            zm_debug_msg1("authentication failed, status = ",
2252                          pAuthFrame->status);
2253
2254            zm_debug_msg0("ZM_STA_STATE_DISCONNECT");
2255            zfStaConnectFail(dev, ZM_STATUS_MEDIA_DISCONNECT_AUTH_FAILED, wd->sta.bssid, 3);
2256        }
2257    }
2258    else if ( wd->sta.connectState == ZM_STA_CONN_STATE_AUTH_SHARE_2 )
2259    {
2260        if ( (zmw_le16_to_cpu(pAuthFrame->algo) == 1)&&
2261             (zmw_le16_to_cpu(pAuthFrame->seq) == 4)&&
2262             (zmw_le16_to_cpu(pAuthFrame->status) == 0) )
2263        {
2264            //Set channel according to AP's configuration
2265            //Move to here because of Cisco 11n AP feature
2266            zfCoreSetFrequencyEx(dev, wd->frequency, wd->BandWidth40,
2267                    wd->ExtOffset, NULL);
2268
2269            /* send association frame */
2270            zfSendMmFrame(dev, ZM_WLAN_FRAME_TYPE_ASOCREQ,
2271                          wd->sta.bssid, 0, 0, 0);
2272
2273            zmw_enter_critical_section(dev);
2274            wd->sta.connectTimer = wd->tick;
2275
2276            zm_debug_msg0("ZM_STA_SUB_STATE_ASSOCIATE");
2277            wd->sta.connectState = ZM_STA_CONN_STATE_ASSOCIATE;
2278            zmw_leave_critical_section(dev);
2279        }
2280        else
2281        {
2282            zm_debug_msg1("authentication failed, status = ",
2283                          pAuthFrame->status);
2284
2285            zm_debug_msg0("ZM_STA_STATE_DISCONNECT");
2286            zfStaConnectFail(dev, ZM_STATUS_MEDIA_DISCONNECT_AUTH_FAILED, wd->sta.bssid, 3);
2287        }
2288    }
2289    else
2290    {
2291        zm_debug_msg0("unknown case");
2292    }
2293}
2294
2295void zfStaProcessAsocReq(zdev_t* dev, zbuf_t* buf, u16_t* src, u16_t apId)
2296{
2297
2298    return;
2299}
2300
2301void zfStaProcessAsocRsp(zdev_t* dev, zbuf_t* buf)
2302{
2303    struct zsWlanAssoFrameHeader* pAssoFrame;
2304    u8_t  pBuf[sizeof(struct zsWlanAssoFrameHeader)];
2305    u16_t offset;
2306    u32_t i;
2307    u32_t oneTxStreamCap;
2308
2309    zmw_get_wlan_dev(dev);
2310
2311    if ( !zfStaIsConnecting(dev) )
2312    {
2313        return;
2314    }
2315
2316    pAssoFrame = (struct zsWlanAssoFrameHeader*) pBuf;
2317    zfCopyFromRxBuffer(dev, buf, pBuf, 0, sizeof(struct zsWlanAssoFrameHeader));
2318
2319    if ( wd->sta.connectState == ZM_STA_CONN_STATE_ASSOCIATE )
2320    {
2321        if ( pAssoFrame->status == 0 )
2322        {
2323            zm_debug_msg0("ZM_STA_STATE_CONNECTED");
2324
2325            if (wd->sta.EnableHT == 1)
2326            {
2327                wd->sta.wmeConnected = 1;
2328            }
2329            if ((wd->sta.wmeEnabled & ZM_STA_WME_ENABLE_BIT) != 0) //WME enabled
2330            {
2331                /* Asoc rsp may contain WME parameter element */
2332                offset = zfFindWifiElement(dev, buf, 2, 1);
2333                if (offset != 0xffff)
2334                {
2335                    zm_debug_msg0("WME enable");
2336                    wd->sta.wmeConnected = 1;
2337                    if ((wd->sta.wmeEnabled & ZM_STA_UAPSD_ENABLE_BIT) != 0)
2338                    {
2339                        if ((zmw_rx_buf_readb(dev, buf, offset+8) & 0x80) != 0)
2340                        {
2341                            zm_debug_msg0("UAPSD enable");
2342                            wd->sta.qosInfo = wd->sta.wmeQosInfo;
2343                        }
2344                    }
2345
2346                    zfStaUpdateWmeParameter(dev, buf);
2347                }
2348            }
2349
2350
2351            //Store asoc response frame body, for VISTA only
2352            wd->sta.asocRspFrameBodySize = zfwBufGetSize(dev, buf)-24;
2353            if (wd->sta.asocRspFrameBodySize > ZM_CACHED_FRAMEBODY_SIZE)
2354            {
2355                wd->sta.asocRspFrameBodySize = ZM_CACHED_FRAMEBODY_SIZE;
2356            }
2357            for (i=0; i<wd->sta.asocRspFrameBodySize; i++)
2358            {
2359                wd->sta.asocRspFrameBody[i] = zmw_rx_buf_readb(dev, buf, i+24);
2360            }
2361
2362            zfStaStoreAsocRspIe(dev, buf);
2363            if (wd->sta.EnableHT &&
2364                ((wd->sta.ie.HtCap.HtCapInfo & HTCAP_SupChannelWidthSet) != 0) &&
2365                (wd->ExtOffset != 0))
2366            {
2367                wd->sta.htCtrlBandwidth = 1;
2368            }
2369            else
2370            {
2371                wd->sta.htCtrlBandwidth = 0;
2372            }
2373
2374            //Set channel according to AP's configuration
2375            //zfCoreSetFrequencyEx(dev, wd->frequency, wd->BandWidth40,
2376            //        wd->ExtOffset, NULL);
2377
2378            if (wd->sta.EnableHT == 1)
2379            {
2380                wd->addbaComplete = 0;
2381
2382                if ((wd->sta.SWEncryptEnable & ZM_SW_TKIP_ENCRY_EN) == 0 &&
2383                    (wd->sta.SWEncryptEnable & ZM_SW_WEP_ENCRY_EN) == 0)
2384                {
2385                    wd->addbaCount = 1;
2386                    zfAggSendAddbaRequest(dev, wd->sta.bssid, 0, 0);
2387                    zfTimerSchedule(dev, ZM_EVENT_TIMEOUT_ADDBA, 100);
2388                }
2389            }
2390
2391            /* set RIFS support */
2392            if(wd->sta.ie.HtInfo.ChannelInfo & ExtHtCap_RIFSMode)
2393            {
2394                wd->sta.HT2040 = 1;
2395//                zfHpSetRifs(dev, wd->sta.EnableHT, 1, (wd->sta.currentFrequency < 3000)? 1:0);
2396            }
2397
2398            wd->sta.aid = pAssoFrame->aid & 0x3fff;
2399            wd->sta.oppositeCount = 0;    /* reset opposite count */
2400            zfStaSetOppositeInfoFromRxBuf(dev, buf);
2401
2402            wd->sta.rxBeaconCount = 16;
2403
2404            zfChangeAdapterState(dev, ZM_STA_STATE_CONNECTED);
2405            wd->sta.connPowerInHalfDbm = zfHpGetTransmitPower(dev);
2406            if (wd->zfcbConnectNotify != NULL)
2407            {
2408                if (wd->sta.EnableHT != 0) /* 11n */
2409            	{
2410    		        oneTxStreamCap = (zfHpCapability(dev) & ZM_HP_CAP_11N_ONE_TX_STREAM);
2411    		        if (wd->sta.htCtrlBandwidth == 1) /* HT40*/
2412    		        {
2413    					if(oneTxStreamCap) /* one Tx stream */
2414    				    {
2415    				        if (wd->sta.SG40)
2416    				        {
2417    				            wd->CurrentTxRateKbps = 150000;
2418    						    wd->CurrentRxRateKbps = 300000;
2419    				        }
2420    				        else
2421    				        {
2422    				            wd->CurrentTxRateKbps = 135000;
2423    						    wd->CurrentRxRateKbps = 270000;
2424    				        }
2425    				    }
2426    				    else /* Two Tx streams */
2427    				    {
2428    				        if (wd->sta.SG40)
2429    				        {
2430    				            wd->CurrentTxRateKbps = 300000;
2431    						    wd->CurrentRxRateKbps = 300000;
2432    				        }
2433    				        else
2434    				        {
2435    				            wd->CurrentTxRateKbps = 270000;
2436    						    wd->CurrentRxRateKbps = 270000;
2437    				        }
2438    				    }
2439    		        }
2440    		        else /* HT20 */
2441    		        {
2442    		            if(oneTxStreamCap) /* one Tx stream */
2443    				    {
2444    				        wd->CurrentTxRateKbps = 650000;
2445    						wd->CurrentRxRateKbps = 130000;
2446    				    }
2447    				    else /* Two Tx streams */
2448    				    {
2449    				        wd->CurrentTxRateKbps = 130000;
2450    					    wd->CurrentRxRateKbps = 130000;
2451    				    }
2452    		        }
2453                }
2454                else /* 11abg */
2455                {
2456                    if (wd->sta.connection_11b != 0)
2457                    {
2458                        wd->CurrentTxRateKbps = 11000;
2459    			        wd->CurrentRxRateKbps = 11000;
2460                    }
2461                    else
2462                    {
2463                        wd->CurrentTxRateKbps = 54000;
2464    			        wd->CurrentRxRateKbps = 54000;
2465    			    }
2466                }
2467
2468
2469                wd->zfcbConnectNotify(dev, ZM_STATUS_MEDIA_CONNECT, wd->sta.bssid);
2470            }
2471            wd->sta.connectByReasso = TRUE;
2472            wd->sta.failCntOfReasso = 0;
2473
2474            zfPowerSavingMgrConnectNotify(dev);
2475
2476            /* Disable here because fixed rate is only for test, TBD. */
2477            //if (wd->sta.EnableHT)
2478            //{
2479            //    wd->txMCS = 7; //Rate = 65Mbps
2480            //    wd->txMT = 2; // Ht rate
2481            //    wd->enableAggregation = 2; // Enable Aggregation
2482            //}
2483        }
2484        else
2485        {
2486            zm_debug_msg1("association failed, status = ",
2487                          pAssoFrame->status);
2488
2489            zm_debug_msg0("ZM_STA_STATE_DISCONNECT");
2490            wd->sta.connectByReasso = FALSE;
2491            zfStaConnectFail(dev, ZM_STATUS_MEDIA_DISCONNECT_ASOC_FAILED, wd->sta.bssid, 3);
2492        }
2493    }
2494
2495}
2496
2497void zfStaStoreAsocRspIe(zdev_t* dev, zbuf_t* buf)
2498{
2499    u16_t offset;
2500    u32_t i;
2501    u16_t length;
2502    u8_t  *htcap;
2503    u8_t  asocBw40 = 0;
2504    u8_t  asocExtOffset = 0;
2505
2506    zmw_get_wlan_dev(dev);
2507
2508    for (i=0; i<wd->sta.asocRspFrameBodySize; i++)
2509    {
2510        wd->sta.asocRspFrameBody[i] = zmw_rx_buf_readb(dev, buf, i+24);
2511    }
2512
2513    /* HT capabilities: 28 octets */
2514    if (    ((wd->sta.currentFrequency > 3000) && !(wd->supportMode & ZM_WIRELESS_MODE_5_N))
2515         || ((wd->sta.currentFrequency < 3000) && !(wd->supportMode & ZM_WIRELESS_MODE_24_N)) )
2516    {
2517        /* not 11n AP */
2518        htcap = (u8_t *)&wd->sta.ie.HtCap;
2519        for (i=0; i<28; i++)
2520        {
2521            htcap[i] = 0;
2522        }
2523        wd->BandWidth40 = 0;
2524        wd->ExtOffset = 0;
2525        return;
2526    }
2527
2528    offset = zfFindElement(dev, buf, ZM_WLAN_EID_HT_CAPABILITY);
2529    if (offset != 0xffff)
2530    {
2531        /* atheros pre n */
2532        zm_debug_msg0("atheros pre n");
2533        htcap = (u8_t *)&wd->sta.ie.HtCap;
2534        htcap[0] = zmw_rx_buf_readb(dev, buf, offset);
2535        htcap[1] = 26;
2536        for (i=1; i<=26; i++)
2537        {
2538            htcap[i+1] = zmw_rx_buf_readb(dev, buf, offset + i);
2539            zm_msg2_mm(ZM_LV_1, "ASOC:  HT Capabilities, htcap=", htcap[i+1]);
2540        }
2541    }
2542    else if ((offset = zfFindElement(dev, buf, ZM_WLAN_PREN2_EID_HTCAPABILITY)) != 0xffff)
2543    {
2544        /* pre n 2.0 standard */
2545        zm_debug_msg0("pre n 2.0 standard");
2546        htcap = (u8_t *)&wd->sta.ie.HtCap;
2547        for (i=0; i<28; i++)
2548        {
2549            htcap[i] = zmw_rx_buf_readb(dev, buf, offset + i);
2550            zm_msg2_mm(ZM_LV_1, "ASOC:  HT Capabilities, htcap=", htcap[i]);
2551        }
2552    }
2553    else
2554    {
2555        /* not 11n AP */
2556        htcap = (u8_t *)&wd->sta.ie.HtCap;
2557        for (i=0; i<28; i++)
2558        {
2559            htcap[i] = 0;
2560        }
2561        wd->BandWidth40 = 0;
2562        wd->ExtOffset = 0;
2563        return;
2564    }
2565
2566    asocBw40 = (u8_t)((wd->sta.ie.HtCap.HtCapInfo & HTCAP_SupChannelWidthSet) >> 1);
2567
2568    /* HT information */
2569    offset = zfFindElement(dev, buf, ZM_WLAN_EID_EXTENDED_HT_CAPABILITY);
2570    if (offset != 0xffff)
2571    {
2572        /* atheros pre n */
2573        zm_debug_msg0("atheros pre n HTINFO");
2574        length = 22;
2575        htcap = (u8_t *)&wd->sta.ie.HtInfo;
2576        htcap[0] = zmw_rx_buf_readb(dev, buf, offset);
2577        htcap[1] = 22;
2578        for (i=1; i<=22; i++)
2579        {
2580            htcap[i+1] = zmw_rx_buf_readb(dev, buf, offset + i);
2581            zm_msg2_mm(ZM_LV_1, "ASOC:  HT Info, htinfo=", htcap[i+1]);
2582        }
2583    }
2584    else if ((offset = zfFindElement(dev, buf, ZM_WLAN_PREN2_EID_HTINFORMATION)) != 0xffff)
2585    {
2586        /* pre n 2.0 standard */
2587        zm_debug_msg0("pre n 2.0 standard HTINFO");
2588        length = zmw_rx_buf_readb(dev, buf, offset + 1);
2589        htcap = (u8_t *)&wd->sta.ie.HtInfo;
2590        for (i=0; i<24; i++)
2591        {
2592            htcap[i] = zmw_rx_buf_readb(dev, buf, offset + i);
2593            zm_msg2_mm(ZM_LV_1, "ASOC:  HT Info, htinfo=", htcap[i]);
2594        }
2595    }
2596    else
2597    {
2598        zm_debug_msg0("no HTINFO");
2599        htcap = (u8_t *)&wd->sta.ie.HtInfo;
2600        for (i=0; i<24; i++)
2601        {
2602            htcap[i] = 0;
2603        }
2604    }
2605    asocExtOffset = wd->sta.ie.HtInfo.ChannelInfo & ExtHtCap_ExtChannelOffsetBelow;
2606
2607    if ((wd->sta.EnableHT == 1) && (asocBw40 == 1) && ((asocExtOffset == 1) || (asocExtOffset == 3)))
2608    {
2609        wd->BandWidth40 = asocBw40;
2610        wd->ExtOffset = asocExtOffset;
2611    }
2612    else
2613    {
2614        wd->BandWidth40 = 0;
2615        wd->ExtOffset = 0;
2616    }
2617
2618    return;
2619}
2620
2621void zfStaProcessDeauth(zdev_t* dev, zbuf_t* buf)
2622{
2623    u16_t apMacAddr[3];
2624
2625    zmw_get_wlan_dev(dev);
2626    zmw_declare_for_critical_section();
2627
2628    /* STA : if SA=connected AP then disconnect with AP */
2629    if ( wd->wlanMode == ZM_MODE_INFRASTRUCTURE )
2630    {
2631        apMacAddr[0] = zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A3_OFFSET);
2632        apMacAddr[1] = zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A3_OFFSET+2);
2633        apMacAddr[2] = zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A3_OFFSET+4);
2634  	if ((apMacAddr[0] == wd->sta.bssid[0]) && (apMacAddr[1] == wd->sta.bssid[1]) && (apMacAddr[2] == wd->sta.bssid[2]))
2635        {
2636            if (zfwBufGetSize(dev, buf) >= 24+2) //not a malformed frame
2637            {
2638                if ( zfStaIsConnected(dev) )
2639                {
2640                    zfStaConnectFail(dev, ZM_STATUS_MEDIA_DISCONNECT_DEAUTH, wd->sta.bssid, 2);
2641                }
2642                else if (zfStaIsConnecting(dev))
2643                {
2644                    zfStaConnectFail(dev, ZM_STATUS_MEDIA_DISCONNECT_AUTH_FAILED, wd->sta.bssid, 3);
2645                }
2646                else
2647                {
2648                }
2649            }
2650        }
2651    }
2652    else if ( wd->wlanMode == ZM_MODE_IBSS )
2653    {
2654        u16_t peerMacAddr[3];
2655        u8_t  peerIdx;
2656        s8_t  res;
2657
2658        if ( zfStaIsConnected(dev) )
2659        {
2660            peerMacAddr[0] = zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A2_OFFSET);
2661            peerMacAddr[1] = zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A2_OFFSET+2);
2662            peerMacAddr[2] = zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A2_OFFSET+4);
2663
2664            zmw_enter_critical_section(dev);
2665            res = zfStaFindOppositeByMACAddr(dev, peerMacAddr, &peerIdx);
2666            if ( res == 0 )
2667            {
2668                wd->sta.oppositeInfo[peerIdx].aliveCounter = 0;
2669            }
2670            zmw_leave_critical_section(dev);
2671        }
2672    }
2673}
2674
2675void zfStaProcessDisasoc(zdev_t* dev, zbuf_t* buf)
2676{
2677    u16_t apMacAddr[3];
2678
2679    zmw_get_wlan_dev(dev);
2680
2681    /* STA : if SA=connected AP then disconnect with AP */
2682    if ( wd->wlanMode == ZM_MODE_INFRASTRUCTURE )
2683    {
2684        apMacAddr[0] = zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A3_OFFSET);
2685        apMacAddr[1] = zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A3_OFFSET+2);
2686        apMacAddr[2] = zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A3_OFFSET+4);
2687
2688        if ((apMacAddr[0] == wd->sta.bssid[0]) && (apMacAddr[1] == wd->sta.bssid[1]) && (apMacAddr[2] == wd->sta.bssid[2]))
2689        {
2690            if (zfwBufGetSize(dev, buf) >= 24+2) //not a malformed frame
2691            {
2692                if ( zfStaIsConnected(dev) )
2693                {
2694                    zfStaConnectFail(dev, ZM_STATUS_MEDIA_DISCONNECT_DISASOC, wd->sta.bssid, 2);
2695                }
2696                else
2697                {
2698                    zfStaConnectFail(dev, ZM_STATUS_MEDIA_DISCONNECT_ASOC_FAILED, wd->sta.bssid, 3);
2699                }
2700            }
2701        }
2702    }
2703}
2704
2705
2706
2707/************************************************************************/
2708/*                                                                      */
2709/*    FUNCTION DESCRIPTION                  zfProcessProbeReq           */
2710/*      Process probe request management frame.                         */
2711/*                                                                      */
2712/*    INPUTS                                                            */
2713/*      dev : device pointer                                            */
2714/*      buf : auth frame buffer                                         */
2715/*                                                                      */
2716/*    OUTPUTS                                                           */
2717/*      none                                                            */
2718/*                                                                      */
2719/*    AUTHOR                                                            */
2720/*      Stephen Chen        ZyDAS Technology Corporation    2005.10     */
2721/*                                                                      */
2722/************************************************************************/
2723void zfStaProcessProbeReq(zdev_t* dev, zbuf_t* buf, u16_t* src)
2724{
2725    u16_t offset;
2726    u8_t len;
2727    u16_t i, j;
2728    u16_t sendFlag;
2729
2730    zmw_get_wlan_dev(dev);
2731
2732    /* check mode : AP/IBSS */
2733    if ((wd->wlanMode != ZM_MODE_AP) && (wd->wlanMode != ZM_MODE_IBSS))
2734    {
2735        zm_msg0_mm(ZM_LV_3, "Ignore probe req");
2736        return;
2737    }
2738
2739    /* check SSID */
2740    offset = zfFindElement(dev, buf, ZM_WLAN_EID_SSID);
2741    if (offset == 0xffff)
2742    {
2743        zm_msg0_mm(ZM_LV_3, "probe req SSID not found");
2744        return;
2745    }
2746
2747    len = zmw_rx_buf_readb(dev, buf, offset+1);
2748
2749    for (i=0; i<ZM_MAX_AP_SUPPORT; i++)
2750    {
2751        if ((wd->ap.apBitmap & (i<<i)) != 0)
2752        {
2753            sendFlag = 0;
2754            /* boardcast SSID */
2755            if ((len == 0) && (wd->ap.hideSsid[i] == 0))
2756            {
2757                sendFlag = 1;
2758            }
2759            /* Not broadcast SSID */
2760            else if (wd->ap.ssidLen[i] == len)
2761            {
2762                for (j=0; j<len; j++)
2763                {
2764                    if (zmw_rx_buf_readb(dev, buf, offset+1+j)
2765                            != wd->ap.ssid[i][j])
2766                    {
2767                        break;
2768                    }
2769                }
2770                if (j == len)
2771                {
2772                    sendFlag = 1;
2773                }
2774            }
2775            if (sendFlag == 1)
2776            {
2777                /* Send probe response */
2778                zfSendMmFrame(dev, ZM_WLAN_FRAME_TYPE_PROBERSP, src, i, 0, 0);
2779            }
2780        }
2781    }
2782}
2783
2784void zfStaProcessProbeRsp(zdev_t* dev, zbuf_t* buf, struct zsAdditionInfo* AddInfo)
2785{
2786    /* return if not channel scan */
2787    // Probe response is sent with unicast. Is this required?
2788    // IBSS would send probe request and the code below would prevent
2789    // the probe response from handling.
2790
2791    zfProcessProbeRsp(dev, buf, AddInfo);
2792}
2793
2794void zfIBSSSetupBssDesc(zdev_t *dev)
2795{
2796#ifdef ZM_ENABLE_IBSS_WPA2PSK
2797    u8_t i;
2798#endif
2799    struct zsBssInfo *pBssInfo;
2800    u16_t offset = 0;
2801
2802    zmw_get_wlan_dev(dev);
2803
2804    pBssInfo = &wd->sta.ibssBssDesc;
2805    zfZeroMemory((u8_t *)pBssInfo, sizeof(struct zsBssInfo));
2806
2807    pBssInfo->signalStrength = 100;
2808
2809    zfMemoryCopy((u8_t *)pBssInfo->macaddr, (u8_t *)wd->macAddr,6);
2810    zfMemoryCopy((u8_t *)pBssInfo->bssid, (u8_t *)wd->sta.bssid, 6);
2811
2812    pBssInfo->beaconInterval[0] = (u8_t)(wd->beaconInterval) ;
2813    pBssInfo->beaconInterval[1] = (u8_t)((wd->beaconInterval) >> 8) ;
2814
2815    pBssInfo->capability[0] = wd->sta.capability[0];
2816    pBssInfo->capability[1] = wd->sta.capability[1];
2817
2818    pBssInfo->ssid[0] = ZM_WLAN_EID_SSID;
2819    pBssInfo->ssid[1] = wd->sta.ssidLen;
2820    zfMemoryCopy((u8_t *)&pBssInfo->ssid[2], (u8_t *)wd->sta.ssid, wd->sta.ssidLen);
2821    zfMemoryCopy((u8_t *)&pBssInfo->frameBody[offset], (u8_t *)pBssInfo->ssid,
2822                 wd->sta.ssidLen + 2);
2823    offset += wd->sta.ssidLen + 2;
2824
2825    /* support rate */
2826
2827    /* DS parameter set */
2828    pBssInfo->channel = zfChFreqToNum(wd->frequency, NULL);
2829    pBssInfo->frequency = wd->frequency;
2830    pBssInfo->atimWindow = wd->sta.atimWindow;
2831
2832#ifdef ZM_ENABLE_IBSS_WPA2PSK
2833    if ( wd->sta.authMode == ZM_AUTH_MODE_WPA2PSK )
2834    {
2835        u8_t rsn[64]=
2836        {
2837                    /* Element ID */
2838                    0x30,
2839                    /* Length */
2840                    0x14,
2841                    /* Version */
2842                    0x01, 0x00,
2843                    /* Group Cipher Suite, default=TKIP */
2844                    0x00, 0x0f, 0xac, 0x04,
2845                    /* Pairwise Cipher Suite Count */
2846                    0x01, 0x00,
2847                    /* Pairwise Cipher Suite, default=TKIP */
2848                    0x00, 0x0f, 0xac, 0x02,
2849                    /* Authentication and Key Management Suite Count */
2850                    0x01, 0x00,
2851                    /* Authentication type, default=PSK */
2852                    0x00, 0x0f, 0xac, 0x02,
2853                    /* RSN capability */
2854                    0x00, 0x00
2855        };
2856
2857        /* Overwrite Group Cipher Suite by AP's setting */
2858        zfMemoryCopy(rsn+4, zgWpa2AesOui, 4);
2859
2860        if ( wd->sta.wepStatus == ZM_ENCRYPTION_AES )
2861        {
2862            /* Overwrite Pairwise Cipher Suite by AES */
2863            zfMemoryCopy(rsn+10, zgWpa2AesOui, 4);
2864        }
2865
2866        // RSN element id
2867        pBssInfo->frameBody[offset++] = ZM_WLAN_EID_RSN_IE ;
2868
2869        // RSN length
2870        pBssInfo->frameBody[offset++] = rsn[1] ;
2871
2872        // RSN information
2873        for(i=0; i<rsn[1]; i++)
2874        {
2875            pBssInfo->frameBody[offset++] = rsn[i+2] ;
2876        }
2877
2878        zfMemoryCopy(pBssInfo->rsnIe, rsn, rsn[1]+2);
2879    }
2880#endif
2881}
2882
2883void zfIbssConnectNetwork(zdev_t* dev)
2884{
2885    struct zsBssInfo* pBssInfo;
2886    struct zsBssInfo tmpBssInfo;
2887    u8_t   macAddr[6], bssid[6], bssNotFound = TRUE;
2888    u16_t  i, j=100;
2889    u16_t  k;
2890    struct zsPartnerNotifyEvent event;
2891    u32_t  channelFlags;
2892    u16_t  oppositeWepStatus;
2893
2894    zmw_get_wlan_dev(dev);
2895
2896    zmw_declare_for_critical_section();
2897
2898    /* change state to CONNECTING and stop the channel scanning */
2899    zfChangeAdapterState(dev, ZM_STA_STATE_CONNECTING);
2900    zfPowerSavingMgrWakeup(dev);
2901
2902    /* Set TxQs CWMIN, CWMAX, AIFS and TXO to WME STA default. */
2903    zfUpdateDefaultQosParameter(dev, 0);
2904
2905    wd->sta.bProtectionMode = FALSE;
2906    zfHpSetSlotTime(dev, 1);
2907
2908    /* ESS bit off */
2909    wd->sta.capability[0] &= ~ZM_BIT_0;
2910    /* IBSS bit on */
2911    wd->sta.capability[0] |= ZM_BIT_1;
2912    /* not not use short slot time */
2913    wd->sta.capability[1] &= ~ZM_BIT_2;
2914
2915    wd->sta.wmeConnected = 0;
2916    wd->sta.psMgr.tempWakeUp = 0;
2917    wd->sta.qosInfo = 0;
2918    wd->sta.EnableHT = 0;
2919    wd->BandWidth40 = 0;
2920    wd->ExtOffset = 0;
2921
2922    if ( wd->sta.bssList.bssCount )
2923    {
2924        //Reorder BssList by RSSI--CWYang(+)
2925        zfBssInfoReorderList(dev);
2926
2927        zmw_enter_critical_section(dev);
2928
2929        pBssInfo = wd->sta.bssList.head;
2930
2931        for(i=0; i<wd->sta.bssList.bssCount; i++)
2932        {
2933            // 20070806 #1 Privacy bit
2934            if ( pBssInfo->capability[0] & ZM_BIT_4 )
2935            { // Privacy Ibss network
2936//                zm_debug_msg0("Privacy bit on");
2937                oppositeWepStatus = ZM_ENCRYPTION_WEP_ENABLED;
2938
2939                if ( pBssInfo->rsnIe[1] != 0 )
2940                {
2941                    if ( (pBssInfo->rsnIe[7] == 0x01) || (pBssInfo->rsnIe[7] == 0x05) )
2942                    { // WEP-40 & WEP-104
2943//                        zm_debug_msg0("WEP40 or WEP104");
2944                        oppositeWepStatus = ZM_ENCRYPTION_WEP_ENABLED;
2945                    }
2946                    else if ( pBssInfo->rsnIe[7] == 0x02 )
2947                    { // TKIP
2948//                        zm_debug_msg0("TKIP");
2949                        oppositeWepStatus = ZM_ENCRYPTION_TKIP;
2950                    }
2951                    else if ( pBssInfo->rsnIe[7] == 0x04 )
2952                    { // AES
2953//                        zm_debug_msg0("CCMP-AES");
2954                        oppositeWepStatus = ZM_ENCRYPTION_AES;
2955                    }
2956                }
2957            }
2958            else
2959            {
2960//                zm_debug_msg0("Privacy bit off");
2961                oppositeWepStatus = ZM_ENCRYPTION_WEP_DISABLED;
2962            }
2963
2964            if ( (zfMemoryIsEqual(&(pBssInfo->ssid[2]), wd->sta.ssid,
2965                                  wd->sta.ssidLen))&&
2966                 (wd->sta.ssidLen == pBssInfo->ssid[1])&&
2967                 (oppositeWepStatus == wd->sta.wepStatus) )
2968            {
2969                /* Check support mode */
2970                if (pBssInfo->frequency > 3000) {
2971                    if (   (pBssInfo->EnableHT == 1)
2972                        || (pBssInfo->apCap & ZM_All11N_AP) ) //11n AP
2973                    {
2974                        channelFlags = CHANNEL_A_HT;
2975                        if (pBssInfo->enableHT40 == 1) {
2976                            channelFlags |= CHANNEL_HT40;
2977                        }
2978                    } else {
2979                        channelFlags = CHANNEL_A;
2980                    }
2981                } else {
2982                    if (   (pBssInfo->EnableHT == 1)
2983                        || (pBssInfo->apCap & ZM_All11N_AP) ) //11n AP
2984                    {
2985                        channelFlags = CHANNEL_G_HT;
2986                        if(pBssInfo->enableHT40 == 1) {
2987                            channelFlags |= CHANNEL_HT40;
2988                        }
2989                    } else {
2990                        if (pBssInfo->extSupportedRates[1] == 0) {
2991                            channelFlags = CHANNEL_B;
2992                        } else {
2993                            channelFlags = CHANNEL_G;
2994                        }
2995                    }
2996                }
2997
2998                if (   ((channelFlags == CHANNEL_B) && (wd->connectMode & ZM_BIT_0))
2999                    || ((channelFlags == CHANNEL_G) && (wd->connectMode & ZM_BIT_1))
3000                    || ((channelFlags == CHANNEL_A) && (wd->connectMode & ZM_BIT_2))
3001                    || ((channelFlags & CHANNEL_HT20) && (wd->connectMode & ZM_BIT_3)) )
3002                {
3003                    pBssInfo = pBssInfo->next;
3004                    continue;
3005                }
3006
3007                /* Bypass DFS channel */
3008                if (zfHpIsDfsChannelNCS(dev, pBssInfo->frequency))
3009                {
3010                    zm_debug_msg0("Bypass DFS channel");
3011                    continue;
3012                }
3013
3014                /* check IBSS bit */
3015                if ( pBssInfo->capability[0] & ZM_BIT_1 )
3016                {
3017                    /* may check timestamp here */
3018                    j = i;
3019                    break;
3020                }
3021            }
3022
3023            pBssInfo = pBssInfo->next;
3024        }
3025
3026        if ((j < wd->sta.bssList.bssCount) && (pBssInfo != NULL))
3027        {
3028            zfwMemoryCopy((u8_t*)&tmpBssInfo, (u8_t*)(pBssInfo), sizeof(struct zsBssInfo));
3029            pBssInfo = &tmpBssInfo;
3030        }
3031        else
3032        {
3033            pBssInfo = NULL;
3034        }
3035
3036        zmw_leave_critical_section(dev);
3037
3038        //if ( j < wd->sta.bssList.bssCount )
3039        if (pBssInfo != NULL)
3040        {
3041            int res;
3042
3043            zm_debug_msg0("IBSS found");
3044
3045            /* Found IBSS, reset bssNotFoundCount */
3046            zmw_enter_critical_section(dev);
3047            wd->sta.bssNotFoundCount = 0;
3048            zmw_leave_critical_section(dev);
3049
3050            bssNotFound = FALSE;
3051            wd->sta.atimWindow = pBssInfo->atimWindow;
3052            wd->frequency = pBssInfo->frequency;
3053            //wd->sta.flagFreqChanging = 1;
3054            zfCoreSetFrequency(dev, wd->frequency);
3055            zfUpdateBssid(dev, pBssInfo->bssid);
3056            zfResetSupportRate(dev, ZM_DEFAULT_SUPPORT_RATE_ZERO);
3057            zfUpdateSupportRate(dev, pBssInfo->supportedRates);
3058            zfUpdateSupportRate(dev, pBssInfo->extSupportedRates);
3059            wd->beaconInterval = pBssInfo->beaconInterval[0] +
3060                                 (((u16_t) pBssInfo->beaconInterval[1]) << 8);
3061
3062            if (wd->beaconInterval == 0)
3063            {
3064                wd->beaconInterval = 100;
3065            }
3066
3067            /* rsn information element */
3068            if ( pBssInfo->rsnIe[1] != 0 )
3069            {
3070                zfMemoryCopy(wd->sta.rsnIe, pBssInfo->rsnIe,
3071                             pBssInfo->rsnIe[1]+2);
3072
3073#ifdef ZM_ENABLE_IBSS_WPA2PSK
3074                /* If not use RSNA , run traditional */
3075                zmw_enter_critical_section(dev);
3076                wd->sta.ibssWpa2Psk = 1;
3077                zmw_leave_critical_section(dev);
3078#endif
3079            }
3080            else
3081            {
3082                wd->sta.rsnIe[1] = 0;
3083            }
3084
3085            /* privacy bit */
3086            if ( pBssInfo->capability[0] & ZM_BIT_4 )
3087            {
3088                wd->sta.capability[0] |= ZM_BIT_4;
3089            }
3090            else
3091            {
3092                wd->sta.capability[0] &= ~ZM_BIT_4;
3093            }
3094
3095            /* preamble type */
3096            wd->preambleTypeInUsed = wd->preambleType;
3097            if ( wd->preambleTypeInUsed == ZM_PREAMBLE_TYPE_AUTO )
3098            {
3099                if (pBssInfo->capability[0] & ZM_BIT_5)
3100                {
3101                    wd->preambleTypeInUsed = ZM_PREAMBLE_TYPE_SHORT;
3102                }
3103                else
3104                {
3105                    wd->preambleTypeInUsed = ZM_PREAMBLE_TYPE_LONG;
3106                }
3107            }
3108
3109            if (wd->preambleTypeInUsed == ZM_PREAMBLE_TYPE_LONG)
3110            {
3111                wd->sta.capability[0] &= ~ZM_BIT_5;
3112            }
3113            else
3114            {
3115                wd->sta.capability[0] |= ZM_BIT_5;
3116            }
3117
3118            wd->sta.beaconFrameBodySize = pBssInfo->frameBodysize + 12;
3119
3120            if (wd->sta.beaconFrameBodySize > ZM_CACHED_FRAMEBODY_SIZE)
3121            {
3122                wd->sta.beaconFrameBodySize = ZM_CACHED_FRAMEBODY_SIZE;
3123            }
3124
3125            for (k=0; k<8; k++)
3126            {
3127                wd->sta.beaconFrameBody[k] = pBssInfo->timeStamp[k];
3128            }
3129            wd->sta.beaconFrameBody[8] = pBssInfo->beaconInterval[0];
3130            wd->sta.beaconFrameBody[9] = pBssInfo->beaconInterval[1];
3131            wd->sta.beaconFrameBody[10] = pBssInfo->capability[0];
3132            wd->sta.beaconFrameBody[11] = pBssInfo->capability[1];
3133            //for (k=12; k<wd->sta.beaconFrameBodySize; k++)
3134            for (k=0; k<pBssInfo->frameBodysize; k++)
3135            {
3136                wd->sta.beaconFrameBody[k+12] = pBssInfo->frameBody[k];
3137            }
3138
3139            zmw_enter_critical_section(dev);
3140            res = zfStaSetOppositeInfoFromBSSInfo(dev, pBssInfo);
3141            if ( res == 0 )
3142            {
3143                zfMemoryCopy(event.bssid, (u8_t *)(pBssInfo->bssid), 6);
3144                zfMemoryCopy(event.peerMacAddr, (u8_t *)(pBssInfo->macaddr), 6);
3145            }
3146            zmw_leave_critical_section(dev);
3147
3148            //zfwIbssPartnerNotify(dev, 1, &event);
3149            goto connect_done;
3150        }
3151    }
3152
3153    /* IBSS not found */
3154    if ( bssNotFound )
3155    {
3156#ifdef ZM_ENABLE_IBSS_WPA2PSK
3157        u16_t offset ;
3158#endif
3159        if ( wd->sta.ibssJoinOnly )
3160        {
3161            zm_debug_msg0("IBSS join only...retry...");
3162            goto retry_ibss;
3163        }
3164
3165        if(wd->sta.bssNotFoundCount<2)
3166        {
3167            zmw_enter_critical_section(dev);
3168            zm_debug_msg1("IBSS not found, do sitesurvey!!  bssNotFoundCount=", wd->sta.bssNotFoundCount);
3169            wd->sta.bssNotFoundCount++;
3170            zmw_leave_critical_section(dev);
3171            goto retry_ibss;
3172        }
3173        else
3174        {
3175            zmw_enter_critical_section(dev);
3176            /* Fail IBSS found, TODO create IBSS */
3177            wd->sta.bssNotFoundCount = 0;
3178            zmw_leave_critical_section(dev);
3179        }
3180
3181
3182        if (zfHpIsDfsChannel(dev, wd->frequency))
3183        {
3184            wd->frequency = zfHpFindFirstNonDfsChannel(dev, wd->frequency > 3000);
3185        }
3186
3187        if( wd->ws.autoSetFrequency == 0 )
3188        { /* Auto set frequency */
3189            zm_debug_msg1("Create Ad Hoc Network Band ", wd->ws.adhocMode);
3190            wd->frequency = zfFindCleanFrequency(dev, wd->ws.adhocMode);
3191            wd->ws.autoSetFrequency = 0xff;
3192        }
3193        zm_debug_msg1("IBSS not found, created one in channel ", wd->frequency);
3194
3195        wd->sta.ibssBssIsCreator = 1;
3196
3197        //wd->sta.flagFreqChanging = 1;
3198        zfCoreSetFrequency(dev, wd->frequency);
3199        if (wd->sta.bDesiredBssid == TRUE)
3200        {
3201            for (k=0; k<6; k++)
3202            {
3203                bssid[k] = wd->sta.desiredBssid[k];
3204            }
3205        }
3206        else
3207        {
3208            macAddr[0] = (wd->macAddr[0] & 0xff);
3209            macAddr[1] = (wd->macAddr[0] >> 8);
3210            macAddr[2] = (wd->macAddr[1] & 0xff);
3211            macAddr[3] = (wd->macAddr[1] >> 8);
3212            macAddr[4] = (wd->macAddr[2] & 0xff);
3213            macAddr[5] = (wd->macAddr[2] >> 8);
3214            zfGenerateRandomBSSID(dev, (u8_t *)wd->macAddr, (u8_t *)bssid);
3215        }
3216
3217        zfUpdateBssid(dev, bssid);
3218        //wd->sta.atimWindow = 0x0a;
3219
3220        /* rate information */
3221        if(wd->frequency <= ZM_CH_G_14)  // 2.4 GHz  b+g
3222        {
3223            if ( wd->wfc.bIbssGMode
3224                 && (wd->supportMode & (ZM_WIRELESS_MODE_24_54|ZM_WIRELESS_MODE_24_N)) )
3225            {
3226                zfResetSupportRate(dev, ZM_DEFAULT_SUPPORT_RATE_IBSS_AG);
3227            }
3228            else
3229            {
3230                zfResetSupportRate(dev, ZM_DEFAULT_SUPPORT_RATE_IBSS_B);
3231            }
3232        } else {
3233            zfResetSupportRate(dev, ZM_DEFAULT_SUPPORT_RATE_IBSS_AG);
3234        }
3235
3236        if ( wd->sta.wepStatus == ZM_ENCRYPTION_WEP_DISABLED )
3237        {
3238            wd->sta.capability[0] &= ~ZM_BIT_4;
3239        }
3240        else
3241        {
3242            wd->sta.capability[0] |= ZM_BIT_4;
3243        }
3244
3245        wd->preambleTypeInUsed = wd->preambleType;
3246        if (wd->preambleTypeInUsed == ZM_PREAMBLE_TYPE_LONG)
3247        {
3248            wd->sta.capability[0] &= ~ZM_BIT_5;
3249        }
3250        else
3251        {
3252            wd->preambleTypeInUsed = ZM_PREAMBLE_TYPE_SHORT;
3253            wd->sta.capability[0] |= ZM_BIT_5;
3254        }
3255
3256        zfIBSSSetupBssDesc(dev);
3257
3258#ifdef ZM_ENABLE_IBSS_WPA2PSK
3259
3260        // 20070411 Add WPA2PSK information to its IBSS network !!!
3261        offset = 0 ;
3262
3263        /* timestamp */
3264        offset += 8 ;
3265
3266        /* beacon interval */
3267        wd->sta.beaconFrameBody[offset++] = (u8_t)(wd->beaconInterval) ;
3268        wd->sta.beaconFrameBody[offset++] = (u8_t)((wd->beaconInterval) >> 8) ;
3269
3270        /* capability information */
3271        wd->sta.beaconFrameBody[offset++] = wd->sta.capability[0] ;
3272        wd->sta.beaconFrameBody[offset++] = wd->sta.capability[1] ;
3273
3274        /* RSN : important information influence the result of creating an IBSS network */
3275        if ( wd->sta.authMode == ZM_AUTH_MODE_WPA2PSK )
3276        {
3277            u8_t frameType = ZM_WLAN_FRAME_TYPE_AUTH ;
3278            u8_t    rsn[64]=
3279            {
3280                        /* Element ID */
3281                        0x30,
3282                        /* Length */
3283                        0x14,
3284                        /* Version */
3285                        0x01, 0x00,
3286                        /* Group Cipher Suite, default=TKIP */
3287                        0x00, 0x0f, 0xac, 0x04,
3288                        /* Pairwise Cipher Suite Count */
3289                        0x01, 0x00,
3290                        /* Pairwise Cipher Suite, default=TKIP */
3291                        0x00, 0x0f, 0xac, 0x02,
3292                        /* Authentication and Key Management Suite Count */
3293                        0x01, 0x00,
3294                        /* Authentication type, default=PSK */
3295                        0x00, 0x0f, 0xac, 0x02,
3296                        /* RSN capability */
3297                        0x00, 0x00
3298            };
3299
3300            /* Overwrite Group Cipher Suite by AP's setting */
3301            zfMemoryCopy(rsn+4, zgWpa2AesOui, 4);
3302
3303            if ( wd->sta.wepStatus == ZM_ENCRYPTION_AES )
3304            {
3305                /* Overwrite Pairwise Cipher Suite by AES */
3306                zfMemoryCopy(rsn+10, zgWpa2AesOui, 4);
3307            }
3308
3309            // RSN element id
3310            wd->sta.beaconFrameBody[offset++] = ZM_WLAN_EID_RSN_IE ;
3311
3312            // RSN length
3313            wd->sta.beaconFrameBody[offset++] = rsn[1] ;
3314
3315            // RSN information
3316            for(i=0; i<rsn[1]; i++)
3317                wd->sta.beaconFrameBody[offset++] = rsn[i+2] ;
3318
3319            zfMemoryCopy(wd->sta.rsnIe, rsn, rsn[1]+2);
3320
3321#ifdef ZM_ENABLE_IBSS_WPA2PSK
3322            /* If not use RSNA , run traditional */
3323            zmw_enter_critical_section(dev);
3324            wd->sta.ibssWpa2Psk = 1;
3325            zmw_leave_critical_section(dev);
3326#endif
3327        }
3328
3329
3330        wd->sta.beaconFrameBodySize = offset ;
3331
3332        if (wd->sta.beaconFrameBodySize > ZM_CACHED_FRAMEBODY_SIZE)
3333        {
3334            wd->sta.beaconFrameBodySize = ZM_CACHED_FRAMEBODY_SIZE;
3335        }
3336
3337        // 20070416 Let Create IBSS network could enter the zfwIbssPartnerNotify function
3338        // bssNotFound = FALSE ;
3339
3340        printk("The capability info 1 = %02x\n", wd->sta.capability[0]) ;
3341        printk("The capability info 2 = %02x\n", wd->sta.capability[1]) ;
3342        for(k=0; k<wd->sta.beaconFrameBodySize; k++)
3343        {
3344	     printk("%02x ", wd->sta.beaconFrameBody[k]) ;
3345        }
3346#endif
3347
3348        //zmw_enter_critical_section(dev);
3349        //wd->sta.ibssPartnerStatus = ZM_IBSS_PARTNER_LOST;
3350        //zmw_leave_critical_section(dev);
3351    }
3352    else
3353    {
3354        wd->sta.ibssBssIsCreator = 0;
3355    }
3356
3357connect_done:
3358    zfHpEnableBeacon(dev, ZM_MODE_IBSS, wd->beaconInterval, wd->dtim, (u8_t)wd->sta.atimWindow);
3359    zfStaSendBeacon(dev); // Refresh Beacon content for ZD1211B HalPlus
3360    zfHpSetAtimWindow(dev, wd->sta.atimWindow);
3361
3362    // Start the IBSS timer to monitor for new stations
3363    zmw_enter_critical_section(dev);
3364    zfTimerSchedule(dev, ZM_EVENT_IBSS_MONITOR, ZM_TICK_IBSS_MONITOR);
3365    zmw_leave_critical_section(dev);
3366
3367
3368    if (wd->zfcbConnectNotify != NULL)
3369    {
3370        wd->zfcbConnectNotify(dev, ZM_STATUS_MEDIA_CONNECT, wd->sta.bssid);
3371    }
3372    zfChangeAdapterState(dev, ZM_STA_STATE_CONNECTED);
3373    wd->sta.connPowerInHalfDbm = zfHpGetTransmitPower(dev);
3374
3375#ifdef ZM_ENABLE_IBSS_DELAYED_JOIN_INDICATION
3376    if ( !bssNotFound )
3377    {
3378        wd->sta.ibssDelayedInd = 1;
3379        zfMemoryCopy((u8_t *)&wd->sta.ibssDelayedIndEvent, (u8_t *)&event, sizeof(struct zsPartnerNotifyEvent));
3380    }
3381#else
3382    if ( !bssNotFound )
3383    {
3384        if (wd->zfcbIbssPartnerNotify != NULL)
3385        {
3386            wd->zfcbIbssPartnerNotify(dev, 1, &event);
3387        }
3388    }
3389#endif
3390
3391    return;
3392
3393retry_ibss:
3394    zfChangeAdapterState(dev, ZM_STA_STATE_CONNECTING);
3395    zfStaConnectFail(dev, ZM_STATUS_MEDIA_DISCONNECT_NOT_FOUND, wd->sta.bssid, 0);
3396    return;
3397}
3398
3399void zfStaProcessAtim(zdev_t* dev, zbuf_t* buf)
3400{
3401    zmw_get_wlan_dev(dev);
3402
3403    zm_debug_msg0("Receiving Atim window notification");
3404
3405    wd->sta.recvAtim = 1;
3406}
3407
3408static struct zsBssInfo* zfInfraFindAPToConnect(zdev_t* dev,
3409        struct zsBssInfo* candidateBss)
3410{
3411    struct zsBssInfo* pBssInfo;
3412    struct zsBssInfo* pNowBssInfo=NULL;
3413    u16_t i;
3414    u16_t ret, apWepStatus;
3415    u32_t k;
3416    u32_t channelFlags;
3417
3418    zmw_get_wlan_dev(dev);
3419    zmw_declare_for_critical_section();
3420
3421    zmw_enter_critical_section(dev);
3422
3423    pBssInfo = wd->sta.bssList.head;
3424
3425    for(i=0; i<wd->sta.bssList.bssCount; i++)
3426    {
3427        if ( pBssInfo->capability[0] & ZM_BIT_4 )
3428        {
3429            apWepStatus = ZM_ENCRYPTION_WEP_ENABLED;
3430        }
3431        else
3432        {
3433            apWepStatus = ZM_ENCRYPTION_WEP_DISABLED;
3434        }
3435
3436        if ( ((zfMemoryIsEqual(&(pBssInfo->ssid[2]), wd->sta.ssid,
3437                               wd->sta.ssidLen))&&
3438              (wd->sta.ssidLen == pBssInfo->ssid[1]))||
3439             ((wd->sta.ssidLen == 0)&&
3440               /* connect to any BSS: AP's ans STA's WEP status must match */
3441              (wd->sta.wepStatus == apWepStatus )&&
3442              (pBssInfo->securityType != ZM_SECURITY_TYPE_WPA) ))
3443        {
3444            if ( wd->sta.ssidLen == 0 )
3445            {
3446                zm_debug_msg0("ANY BSS found");
3447            }
3448
3449            if ( ((wd->sta.wepStatus == ZM_ENCRYPTION_WEP_DISABLED && apWepStatus == ZM_ENCRYPTION_WEP_ENABLED) ||
3450                 (wd->sta.wepStatus == ZM_ENCRYPTION_WEP_ENABLED &&
3451                 (apWepStatus == ZM_ENCRYPTION_WEP_DISABLED && wd->sta.dropUnencryptedPkts == 1))) &&
3452                 (wd->sta.authMode >= ZM_AUTH_MODE_OPEN && wd->sta.authMode <= ZM_AUTH_MODE_AUTO) )
3453            {
3454                zm_debug_msg0("Privacy policy is inconsistent");
3455                pBssInfo = pBssInfo->next;
3456                continue;
3457            }
3458
3459            /* for WPA negative test */
3460            if ( !zfCheckAuthentication(dev, pBssInfo) )
3461            {
3462                pBssInfo = pBssInfo->next;
3463                continue;
3464            }
3465
3466            /* Check bssid */
3467            if (wd->sta.bDesiredBssid == TRUE)
3468            {
3469                for (k=0; k<6; k++)
3470                {
3471                    if (wd->sta.desiredBssid[k] != pBssInfo->bssid[k])
3472                    {
3473                        zm_msg0_mm(ZM_LV_1, "desired bssid not matched 1");
3474                        break;
3475                    }
3476                }
3477
3478                if (k != 6)
3479                {
3480                    zm_msg0_mm(ZM_LV_1, "desired bssid not matched 2");
3481                    pBssInfo = pBssInfo->next;
3482                    continue;
3483                }
3484            }
3485
3486            /* Check support mode */
3487            if (pBssInfo->frequency > 3000) {
3488                if (   (pBssInfo->EnableHT == 1)
3489                    || (pBssInfo->apCap & ZM_All11N_AP) ) //11n AP
3490                {
3491                    channelFlags = CHANNEL_A_HT;
3492                    if (pBssInfo->enableHT40 == 1) {
3493                        channelFlags |= CHANNEL_HT40;
3494                    }
3495                } else {
3496                    channelFlags = CHANNEL_A;
3497                }
3498            } else {
3499                if (   (pBssInfo->EnableHT == 1)
3500                    || (pBssInfo->apCap & ZM_All11N_AP) ) //11n AP
3501                {
3502                    channelFlags = CHANNEL_G_HT;
3503                    if(pBssInfo->enableHT40 == 1) {
3504                        channelFlags |= CHANNEL_HT40;
3505                    }
3506                } else {
3507                    if (pBssInfo->extSupportedRates[1] == 0) {
3508                        channelFlags = CHANNEL_B;
3509                    } else {
3510                        channelFlags = CHANNEL_G;
3511                    }
3512                }
3513            }
3514
3515            if (   ((channelFlags == CHANNEL_B) && (wd->connectMode & ZM_BIT_0))
3516                || ((channelFlags == CHANNEL_G) && (wd->connectMode & ZM_BIT_1))
3517                || ((channelFlags == CHANNEL_A) && (wd->connectMode & ZM_BIT_2))
3518                || ((channelFlags & CHANNEL_HT20) && (wd->connectMode & ZM_BIT_3)) )
3519            {
3520                pBssInfo = pBssInfo->next;
3521                continue;
3522            }
3523
3524            /* Skip if AP in blocking list */
3525            ret = zfStaIsApInBlockingList(dev, pBssInfo->bssid);
3526            if (ret == TRUE)
3527            {
3528                zm_msg0_mm(ZM_LV_0, "Candidate AP in blocking List, skip if there's stilla choice!");
3529                pNowBssInfo = pBssInfo;
3530                pBssInfo = pBssInfo->next;
3531                continue;
3532            }
3533
3534            if ( pBssInfo->capability[0] & ZM_BIT_0 )  // check if infra-BSS
3535            {
3536                    pNowBssInfo = pBssInfo;
3537                    wd->sta.apWmeCapability = pBssInfo->wmeSupport;
3538
3539
3540                    goto done;
3541            }
3542        }
3543
3544        pBssInfo = pBssInfo->next;
3545    }
3546
3547done:
3548    if (pNowBssInfo != NULL)
3549    {
3550        zfwMemoryCopy((void*)candidateBss, (void*)pNowBssInfo, sizeof(struct zsBssInfo));
3551        pNowBssInfo = candidateBss;
3552    }
3553
3554    zmw_leave_critical_section(dev);
3555
3556    return pNowBssInfo;
3557}
3558
3559
3560void zfInfraConnectNetwork(zdev_t* dev)
3561{
3562    struct zsBssInfo* pBssInfo;
3563    struct zsBssInfo* pNowBssInfo=NULL;
3564    struct zsBssInfo candidateBss;
3565    //u16_t i, j=100, quality=10000;
3566    //u8_t ret=FALSE, apWepStatus;
3567    u8_t ret=FALSE;
3568    u16_t k;
3569    u8_t density = ZM_MPDU_DENSITY_NONE;
3570
3571    zmw_get_wlan_dev(dev);
3572    zmw_declare_for_critical_section();
3573
3574    /* Reset bssNotFoundCount for Ad-Hoc:IBSS */
3575    /* Need review : IbssConn -> InfraConn -> IbssConn etc, flag/counter reset? */
3576    zmw_enter_critical_section(dev);
3577    wd->sta.bssNotFoundCount = 0;
3578    zmw_leave_critical_section(dev);
3579
3580    /* Set TxQs CWMIN, CWMAX, AIFS and TXO to WME STA default. */
3581    zfUpdateDefaultQosParameter(dev, 0);
3582
3583    zfStaRefreshBlockList(dev, 0);
3584
3585    /* change state to CONNECTING and stop the channel scanning */
3586    zfChangeAdapterState(dev, ZM_STA_STATE_CONNECTING);
3587    zfPowerSavingMgrWakeup(dev);
3588
3589    wd->sta.wmeConnected = 0;
3590    wd->sta.psMgr.tempWakeUp = 0;
3591    wd->sta.qosInfo = 0;
3592    zfQueueFlush(dev, wd->sta.uapsdQ);
3593
3594    wd->sta.connectState = ZM_STA_CONN_STATE_NONE;
3595
3596    //Reorder BssList by RSSI--CWYang(+)
3597    zfBssInfoReorderList(dev);
3598
3599    pNowBssInfo = zfInfraFindAPToConnect(dev, &candidateBss);
3600
3601	if (wd->sta.SWEncryptEnable != 0)
3602	{
3603	    if (wd->sta.bSafeMode == 0)
3604	    {
3605		    zfStaDisableSWEncryption(dev);//Quickly reboot
3606	    }
3607	}
3608    if ( pNowBssInfo != NULL )
3609    {
3610        //zm_assert(pNowBssInfo != NULL);
3611
3612        pBssInfo = pNowBssInfo;
3613        wd->sta.ssidLen = pBssInfo->ssid[1];
3614        zfMemoryCopy(wd->sta.ssid, &(pBssInfo->ssid[2]), pBssInfo->ssid[1]);
3615        wd->frequency = pBssInfo->frequency;
3616        //wd->sta.flagFreqChanging = 1;
3617
3618        //zfCoreSetFrequency(dev, wd->frequency);
3619        zfUpdateBssid(dev, pBssInfo->bssid);
3620        zfResetSupportRate(dev, ZM_DEFAULT_SUPPORT_RATE_ZERO);
3621        zfUpdateSupportRate(dev, pBssInfo->supportedRates);
3622        zfUpdateSupportRate(dev, pBssInfo->extSupportedRates);
3623
3624        wd->beaconInterval = pBssInfo->beaconInterval[0] +
3625                             (((u16_t) pBssInfo->beaconInterval[1]) << 8);
3626        if (wd->beaconInterval == 0)
3627        {
3628            wd->beaconInterval = 100;
3629        }
3630
3631        /* ESS bit on */
3632        wd->sta.capability[0] |= ZM_BIT_0;
3633        /* IBSS bit off */
3634        wd->sta.capability[0] &= ~ZM_BIT_1;
3635
3636        /* 11n AP flag */
3637        wd->sta.EnableHT = pBssInfo->EnableHT;
3638        wd->sta.SG40 = pBssInfo->SG40;
3639#ifdef ZM_ENABLE_CENC
3640        if ( pBssInfo->securityType == ZM_SECURITY_TYPE_CENC )
3641        {
3642            wd->sta.wmeEnabled = 0; //Disable WMM in CENC
3643            cencInit(dev);
3644            cencSetCENCMode(dev, NdisCENC_PSK);
3645            wd->sta.wpaState = ZM_STA_WPA_STATE_INIT;
3646            /* CENC */
3647            if ( pBssInfo->cencIe[1] != 0 )
3648            {
3649                //wd->sta.wepStatus = ZM_ENCRYPTION_CENC;
3650                //wd->sta.encryMode = ZM_CENC;
3651                zfwCencHandleBeaconProbrespon(dev, (u8_t *)&pBssInfo->cencIe,
3652                        (u8_t *)&pBssInfo->ssid, (u8_t *)&pBssInfo->macaddr);
3653                zfMemoryCopy(wd->sta.cencIe, pBssInfo->cencIe,
3654                        pBssInfo->cencIe[1]+2);
3655            }
3656            else
3657            {
3658                wd->sta.cencIe[1] = 0;
3659            }
3660        }
3661#endif //ZM_ENABLE_CENC
3662        if ( pBssInfo->securityType == ZM_SECURITY_TYPE_WPA )
3663        {
3664            wd->sta.wpaState = ZM_STA_WPA_STATE_INIT;
3665
3666            if ( wd->sta.wepStatus == ZM_ENCRYPTION_TKIP )
3667            {
3668                wd->sta.encryMode = ZM_TKIP;
3669
3670                /* Turn on software encryption/decryption for TKIP */
3671                if (wd->sta.EnableHT == 1)
3672                {
3673                    zfStaEnableSWEncryption(dev, (ZM_SW_TKIP_ENCRY_EN|ZM_SW_TKIP_DECRY_EN));
3674                }
3675
3676                /* Do not support TKIP in 11n mode */
3677                //wd->sta.EnableHT = 0;
3678                //pBssInfo->enableHT40 = 0;
3679            }
3680            else if ( wd->sta.wepStatus == ZM_ENCRYPTION_AES )
3681            {
3682                wd->sta.encryMode = ZM_AES;
3683
3684                /* If AP supports HT mode */
3685                if (wd->sta.EnableHT)
3686                {
3687                    /* Set MPDU density to 8 us*/
3688                    density = ZM_MPDU_DENSITY_8US;
3689                }
3690            }
3691
3692            if ( pBssInfo->wpaIe[1] != 0 )
3693            {
3694                zfMemoryCopy(wd->sta.wpaIe, pBssInfo->wpaIe,
3695                             pBssInfo->wpaIe[1]+2);
3696            }
3697            else
3698            {
3699                wd->sta.wpaIe[1] = 0;
3700            }
3701
3702            if ( pBssInfo->rsnIe[1] != 0 )
3703            {
3704                zfMemoryCopy(wd->sta.rsnIe, pBssInfo->rsnIe,
3705                             pBssInfo->rsnIe[1]+2);
3706            }
3707            else
3708            {
3709                wd->sta.rsnIe[1] = 0;
3710            }
3711        }
3712
3713
3714
3715        /* check preamble bit */
3716        wd->preambleTypeInUsed = wd->preambleType;
3717        if ( wd->preambleTypeInUsed == ZM_PREAMBLE_TYPE_AUTO )
3718        {
3719            if (pBssInfo->capability[0] & ZM_BIT_5)
3720            {
3721                wd->preambleTypeInUsed = ZM_PREAMBLE_TYPE_SHORT;
3722            }
3723            else
3724            {
3725                wd->preambleTypeInUsed = ZM_PREAMBLE_TYPE_LONG;
3726            }
3727        }
3728
3729        if (wd->preambleTypeInUsed == ZM_PREAMBLE_TYPE_LONG)
3730        {
3731            wd->sta.capability[0] &= ~ZM_BIT_5;
3732        }
3733        else
3734        {
3735            wd->sta.capability[0] |= ZM_BIT_5;
3736        }
3737
3738        /* check 802.11n 40MHz Setting */
3739        if ((pBssInfo->enableHT40 == 1) &&
3740            ((pBssInfo->extChOffset == 1) || (pBssInfo->extChOffset == 3)))
3741        {
3742            wd->BandWidth40 = pBssInfo->enableHT40;
3743            wd->ExtOffset = pBssInfo->extChOffset;
3744        }
3745        else
3746        {
3747            wd->BandWidth40 = 0;
3748            wd->ExtOffset = 0;
3749        }
3750
3751        /* check 802.11H support bit */
3752
3753        /* check Owl Ap */
3754        if ( pBssInfo->athOwlAp & ZM_BIT_0 )
3755        {
3756            /* In this function, FW retry will be enable, ZM_MAC_REG_RETRY_MAX
3757               will be set to 0.
3758             */
3759            zfHpDisableHwRetry(dev);
3760            wd->sta.athOwlAp = 1;
3761            /* Set MPDU density to 8 us*/
3762            density = ZM_MPDU_DENSITY_8US;
3763        }
3764        else
3765        {
3766            /* In this function, FW retry will be disable, ZM_MAC_REG_RETRY_MAX
3767               will be set to 3.
3768             */
3769            zfHpEnableHwRetry(dev);
3770            wd->sta.athOwlAp = 0;
3771        }
3772        wd->reorder = 1;
3773
3774        /* Set MPDU density */
3775        zfHpSetMPDUDensity(dev, density);
3776
3777        /* check short slot time bit */
3778        if ( pBssInfo->capability[1] & ZM_BIT_2 )
3779        {
3780            wd->sta.capability[1] |= ZM_BIT_2;
3781        }
3782
3783        if ( pBssInfo->erp & ZM_BIT_1 )
3784        {
3785            //zm_debug_msg0("protection mode on");
3786            wd->sta.bProtectionMode = TRUE;
3787            zfHpSetSlotTime(dev, 0);
3788        }
3789        else
3790        {
3791            //zm_debug_msg0("protection mode off");
3792            wd->sta.bProtectionMode = FALSE;
3793            zfHpSetSlotTime(dev, 1);
3794        }
3795
3796        if (pBssInfo->marvelAp == 1)
3797        {
3798            wd->sta.enableDrvBA = 0;
3799            /*
3800             * 8701 : NetGear 3500 (MARVELL)
3801             * Downlink issue : set slottime to 20.
3802             */
3803            zfHpSetSlotTimeRegister(dev, 0);
3804        }
3805        else
3806        {
3807            wd->sta.enableDrvBA = 1;
3808
3809            /*
3810             * This is not good for here do reset slot time.
3811             * I think it should reset when leave MARVELL ap
3812             * or enter disconnect state etc.
3813             */
3814            zfHpSetSlotTimeRegister(dev, 1);
3815        }
3816
3817        //Store probe response frame body, for VISTA only
3818        wd->sta.beaconFrameBodySize = pBssInfo->frameBodysize + 12;
3819        if (wd->sta.beaconFrameBodySize > ZM_CACHED_FRAMEBODY_SIZE)
3820        {
3821            wd->sta.beaconFrameBodySize = ZM_CACHED_FRAMEBODY_SIZE;
3822        }
3823        for (k=0; k<8; k++)
3824        {
3825            wd->sta.beaconFrameBody[k] = pBssInfo->timeStamp[k];
3826        }
3827        wd->sta.beaconFrameBody[8] = pBssInfo->beaconInterval[0];
3828        wd->sta.beaconFrameBody[9] = pBssInfo->beaconInterval[1];
3829        wd->sta.beaconFrameBody[10] = pBssInfo->capability[0];
3830        wd->sta.beaconFrameBody[11] = pBssInfo->capability[1];
3831        for (k=0; k<(wd->sta.beaconFrameBodySize - 12); k++)
3832        {
3833            wd->sta.beaconFrameBody[k+12] = pBssInfo->frameBody[k];
3834        }
3835
3836        if ( ( pBssInfo->capability[0] & ZM_BIT_4 )&&
3837             (( wd->sta.authMode == ZM_AUTH_MODE_OPEN )||
3838              ( wd->sta.authMode == ZM_AUTH_MODE_SHARED_KEY)||
3839              (wd->sta.authMode == ZM_AUTH_MODE_AUTO)) )
3840        {   /* privacy enabled */
3841
3842            if ( wd->sta.wepStatus == ZM_ENCRYPTION_WEP_DISABLED )
3843            {
3844                zm_debug_msg0("Adapter is no WEP, try to connect to WEP AP");
3845                ret = FALSE;
3846            }
3847
3848            /* Do not support WEP in 11n mode */
3849            if ( wd->sta.wepStatus == ZM_ENCRYPTION_WEP_ENABLED )
3850            {
3851                /* Turn on software encryption/decryption for WEP */
3852                if (wd->sta.EnableHT == 1)
3853                {
3854                    zfStaEnableSWEncryption(dev, (ZM_SW_WEP_ENCRY_EN|ZM_SW_WEP_DECRY_EN));
3855                }
3856
3857                //wd->sta.EnableHT = 0;
3858                //wd->BandWidth40 = 0;
3859                //wd->ExtOffset = 0;
3860            }
3861
3862            wd->sta.capability[0] |= ZM_BIT_4;
3863
3864            if ( wd->sta.authMode == ZM_AUTH_MODE_AUTO )
3865            { /* Try to use open and shared-key authehtication alternatively */
3866                if ( (wd->sta.connectTimeoutCount % 2) == 0 )
3867                    wd->sta.bIsSharedKey = 0;
3868                else
3869                    wd->sta.bIsSharedKey = 1;
3870            }
3871            else if ( wd->sta.authMode != ZM_AUTH_MODE_SHARED_KEY )
3872            {   /* open  or auto */
3873                //zfStaStartConnect(dev, 0);
3874                wd->sta.bIsSharedKey = 0;
3875            }
3876            else if ( wd->sta.authMode != ZM_AUTH_MODE_OPEN )
3877            {   /* shared key */
3878                //zfStaStartConnect(dev, 1) ;
3879                wd->sta.bIsSharedKey = 1;
3880            }
3881        }
3882        else
3883        {
3884            if ( (pBssInfo->securityType == ZM_SECURITY_TYPE_WPA)||
3885                 (pBssInfo->capability[0] & ZM_BIT_4) )
3886            {
3887                wd->sta.capability[0] |= ZM_BIT_4;
3888                /* initialize WPA related parameters */
3889            }
3890            else
3891            {
3892                wd->sta.capability[0] &= (~ZM_BIT_4);
3893            }
3894
3895            /* authentication with open system */
3896            //zfStaStartConnect(dev, 0);
3897            wd->sta.bIsSharedKey = 0;
3898        }
3899
3900        /* Improve WEP/TKIP performance with HT AP, detail information please look bug#32495 */
3901        /*
3902        if ( (pBssInfo->broadcomHTAp == 1)
3903             && (wd->sta.SWEncryptEnable != 0) )
3904        {
3905            zfHpSetTTSIFSTime(dev, 0xa);
3906        }
3907        else
3908        {
3909            zfHpSetTTSIFSTime(dev, 0x8);
3910        }
3911        */
3912    }
3913    else
3914    {
3915        zm_debug_msg0("Desired SSID not found");
3916        goto zlConnectFailed;
3917    }
3918
3919
3920    zfCoreSetFrequencyV2(dev, wd->frequency, zfStaStartConnectCb);
3921    return;
3922
3923zlConnectFailed:
3924    zfStaConnectFail(dev, ZM_STATUS_MEDIA_DISCONNECT_NOT_FOUND, wd->sta.bssid, 0);
3925    return;
3926}
3927
3928u8_t zfCheckWPAAuth(zdev_t* dev, struct zsBssInfo* pBssInfo)
3929{
3930    u8_t   ret=TRUE;
3931    u8_t   pmkCount;
3932    u8_t   i;
3933    u16_t   encAlgoType = 0;
3934
3935    zmw_get_wlan_dev(dev);
3936
3937    if ( wd->sta.wepStatus == ZM_ENCRYPTION_TKIP )
3938    {
3939        encAlgoType = ZM_TKIP;
3940    }
3941    else if ( wd->sta.wepStatus == ZM_ENCRYPTION_AES )
3942    {
3943        encAlgoType = ZM_AES;
3944    }
3945
3946    switch(wd->sta.authMode)
3947    {
3948        case ZM_AUTH_MODE_WPA:
3949        case ZM_AUTH_MODE_WPAPSK:
3950            if ( pBssInfo->wpaIe[1] == 0 )
3951            {
3952                ret = FALSE;
3953                break;
3954            }
3955
3956            pmkCount = pBssInfo->wpaIe[12];
3957            for(i=0; i < pmkCount; i++)
3958            {
3959                if ( pBssInfo->wpaIe[17 + 4*i] == encAlgoType )
3960                {
3961                    ret = TRUE;
3962                    goto done;
3963                }
3964            }
3965
3966            ret = FALSE;
3967            break;
3968
3969        case ZM_AUTH_MODE_WPA2:
3970        case ZM_AUTH_MODE_WPA2PSK:
3971            if ( pBssInfo->rsnIe[1] == 0 )
3972            {
3973                ret = FALSE;
3974                break;
3975            }
3976
3977            pmkCount = pBssInfo->rsnIe[8];
3978            for(i=0; i < pmkCount; i++)
3979            {
3980                if ( pBssInfo->rsnIe[13 + 4*i] == encAlgoType )
3981                {
3982                    ret = TRUE;
3983                    goto done;
3984                }
3985            }
3986
3987            ret = FALSE;
3988            break;
3989    }
3990
3991done:
3992    return ret;
3993}
3994
3995u8_t zfCheckAuthentication(zdev_t* dev, struct zsBssInfo* pBssInfo)
3996{
3997    u8_t   ret=TRUE;
3998    u16_t  encAlgoType;
3999    u16_t UnicastCipherNum;
4000
4001    zmw_get_wlan_dev(dev);
4002
4003    /* Connecting to ANY has been checked */
4004    if ( wd->sta.ssidLen == 0 )
4005    {
4006        return ret;
4007    }
4008
4009
4010	switch(wd->sta.authMode)
4011	//switch(wd->ws.authMode)//Quickly reboot
4012    {
4013        case ZM_AUTH_MODE_WPA_AUTO:
4014        case ZM_AUTH_MODE_WPAPSK_AUTO:
4015            encAlgoType = 0;
4016            if(pBssInfo->rsnIe[1] != 0)
4017            {
4018                UnicastCipherNum = (pBssInfo->rsnIe[8]) +
4019                                   (pBssInfo->rsnIe[9] << 8);
4020
4021                /* If there is only one unicast cipher */
4022                if (UnicastCipherNum == 1)
4023                {
4024                    encAlgoType = pBssInfo->rsnIe[13];
4025                    //encAlgoType = pBssInfo->rsnIe[7];
4026                }
4027                else
4028                {
4029                    u16_t ii;
4030                    u16_t desiredCipher = 0;
4031                    u16_t IEOffSet = 13;
4032
4033                    /* Enumerate all the supported unicast cipher */
4034                    for (ii = 0; ii < UnicastCipherNum; ii++)
4035                    {
4036                        if (pBssInfo->rsnIe[IEOffSet+ii*4] > desiredCipher)
4037                        {
4038                            desiredCipher = pBssInfo->rsnIe[IEOffSet+ii*4];
4039                        }
4040                    }
4041
4042                    encAlgoType = desiredCipher;
4043                }
4044
4045                if ( encAlgoType == 0x02 )
4046                {
4047    			    wd->sta.wepStatus = ZM_ENCRYPTION_TKIP;
4048
4049    			    if ( wd->sta.authMode == ZM_AUTH_MODE_WPA_AUTO )
4050                    {
4051                        wd->sta.currentAuthMode = ZM_AUTH_MODE_WPA2;
4052                    }
4053                    else //ZM_AUTH_MODE_WPAPSK_AUTO
4054                    {
4055                        wd->sta.currentAuthMode = ZM_AUTH_MODE_WPA2PSK;
4056                    }
4057                }
4058                else if ( encAlgoType == 0x04 )
4059                {
4060                    wd->sta.wepStatus = ZM_ENCRYPTION_AES;
4061
4062                    if ( wd->sta.authMode == ZM_AUTH_MODE_WPA_AUTO )
4063                    {
4064                        wd->sta.currentAuthMode = ZM_AUTH_MODE_WPA2;
4065                    }
4066                    else //ZM_AUTH_MODE_WPAPSK_AUTO
4067                    {
4068                        wd->sta.currentAuthMode = ZM_AUTH_MODE_WPA2PSK;
4069                    }
4070                }
4071                else
4072                {
4073                    ret = FALSE;
4074                }
4075            }
4076            else if(pBssInfo->wpaIe[1] != 0)
4077            {
4078                UnicastCipherNum = (pBssInfo->wpaIe[12]) +
4079                                   (pBssInfo->wpaIe[13] << 8);
4080
4081                /* If there is only one unicast cipher */
4082                if (UnicastCipherNum == 1)
4083                {
4084                    encAlgoType = pBssInfo->wpaIe[17];
4085                    //encAlgoType = pBssInfo->wpaIe[11];
4086                }
4087                else
4088                {
4089                    u16_t ii;
4090                    u16_t desiredCipher = 0;
4091                    u16_t IEOffSet = 17;
4092
4093                    /* Enumerate all the supported unicast cipher */
4094                    for (ii = 0; ii < UnicastCipherNum; ii++)
4095                    {
4096                        if (pBssInfo->wpaIe[IEOffSet+ii*4] > desiredCipher)
4097                        {
4098                            desiredCipher = pBssInfo->wpaIe[IEOffSet+ii*4];
4099                        }
4100                    }
4101
4102                    encAlgoType = desiredCipher;
4103                }
4104
4105                if ( encAlgoType == 0x02 )
4106                {
4107    			    wd->sta.wepStatus = ZM_ENCRYPTION_TKIP;
4108
4109    			    if ( wd->sta.authMode == ZM_AUTH_MODE_WPA_AUTO )
4110                    {
4111                        wd->sta.currentAuthMode = ZM_AUTH_MODE_WPA;
4112                    }
4113                    else //ZM_AUTH_MODE_WPAPSK_AUTO
4114                    {
4115                        wd->sta.currentAuthMode = ZM_AUTH_MODE_WPAPSK;
4116                    }
4117                }
4118                else if ( encAlgoType == 0x04 )
4119                {
4120                    wd->sta.wepStatus = ZM_ENCRYPTION_AES;
4121
4122                    if ( wd->sta.authMode == ZM_AUTH_MODE_WPA_AUTO )
4123                    {
4124                        wd->sta.currentAuthMode = ZM_AUTH_MODE_WPA;
4125                    }
4126                    else //ZM_AUTH_MODE_WPAPSK_AUTO
4127                    {
4128                        wd->sta.currentAuthMode = ZM_AUTH_MODE_WPAPSK;
4129                    }
4130                }
4131                else
4132                {
4133                    ret = FALSE;
4134                }
4135
4136
4137            }
4138            else
4139            {
4140                ret = FALSE;
4141            }
4142
4143            break;
4144
4145        case ZM_AUTH_MODE_WPA:
4146        case ZM_AUTH_MODE_WPAPSK:
4147        case ZM_AUTH_MODE_WPA_NONE:
4148        case ZM_AUTH_MODE_WPA2:
4149        case ZM_AUTH_MODE_WPA2PSK:
4150            {
4151                if ( pBssInfo->securityType != ZM_SECURITY_TYPE_WPA )
4152                {
4153                    ret = FALSE;
4154                }
4155
4156                ret = zfCheckWPAAuth(dev, pBssInfo);
4157            }
4158            break;
4159
4160        case ZM_AUTH_MODE_OPEN:
4161        case ZM_AUTH_MODE_SHARED_KEY:
4162        case ZM_AUTH_MODE_AUTO:
4163            {
4164                if ( pBssInfo->wscIe[1] )
4165                {
4166                    // If the AP is a Jumpstart AP, it's ok!! Ray
4167                    break;
4168                }
4169                else if ( pBssInfo->securityType == ZM_SECURITY_TYPE_WPA )
4170                {
4171                    ret = FALSE;
4172                }
4173            }
4174            break;
4175
4176        default:
4177            break;
4178    }
4179
4180    return ret;
4181}
4182
4183u8_t zfStaIsConnected(zdev_t* dev)
4184{
4185    zmw_get_wlan_dev(dev);
4186
4187    if ( wd->sta.adapterState == ZM_STA_STATE_CONNECTED )
4188    {
4189        return TRUE;
4190    }
4191
4192    return FALSE;
4193}
4194
4195u8_t zfStaIsConnecting(zdev_t* dev)
4196{
4197    zmw_get_wlan_dev(dev);
4198
4199    if ( wd->sta.adapterState == ZM_STA_STATE_CONNECTING )
4200    {
4201        return TRUE;
4202    }
4203
4204    return FALSE;
4205}
4206
4207u8_t zfStaIsDisconnect(zdev_t* dev)
4208{
4209    zmw_get_wlan_dev(dev);
4210
4211    if ( wd->sta.adapterState == ZM_STA_STATE_DISCONNECT )
4212    {
4213        return TRUE;
4214    }
4215
4216    return FALSE;
4217}
4218
4219u8_t zfChangeAdapterState(zdev_t* dev, u8_t newState)
4220{
4221    u8_t ret = TRUE;
4222
4223    zmw_get_wlan_dev(dev);
4224
4225    zmw_declare_for_critical_section();
4226
4227    //if ( newState == wd->sta.adapterState )
4228    //{
4229    //    return FALSE;
4230    //}
4231
4232    switch(newState)
4233    {
4234    case ZM_STA_STATE_DISCONNECT:
4235        zfResetSupportRate(dev, ZM_DEFAULT_SUPPORT_RATE_DISCONNECT);
4236
4237            zfScanMgrScanStop(dev, ZM_SCAN_MGR_SCAN_INTERNAL);
4238
4239        break;
4240    case ZM_STA_STATE_CONNECTING:
4241            zfScanMgrScanStop(dev, ZM_SCAN_MGR_SCAN_INTERNAL);
4242
4243        break;
4244    case ZM_STA_STATE_CONNECTED:
4245        break;
4246    default:
4247        break;
4248    }
4249
4250    //if ( ret )
4251    //{
4252        zmw_enter_critical_section(dev);
4253        wd->sta.adapterState = newState;
4254        zmw_leave_critical_section(dev);
4255
4256        zm_debug_msg1("change adapter state = ", newState);
4257    //}
4258
4259    return ret;
4260}
4261
4262/************************************************************************/
4263/*                                                                      */
4264/*    FUNCTION DESCRIPTION                  zfStaMmAddIeSsid            */
4265/*      Add information element SSID to buffer.                         */
4266/*                                                                      */
4267/*    INPUTS                                                            */
4268/*      dev : device pointer                                            */
4269/*      buf : buffer to add information element                         */
4270/*      offset : add information element from this offset               */
4271/*                                                                      */
4272/*    OUTPUTS                                                           */
4273/*      buffer offset after adding information element                  */
4274/*                                                                      */
4275/*    AUTHOR                                                            */
4276/*      Ji-Huang Lee        ZyDAS Technology Corporation    2005.11     */
4277/*                                                                      */
4278/************************************************************************/
4279u16_t zfStaAddIeSsid(zdev_t* dev, zbuf_t* buf, u16_t offset)
4280{
4281    u16_t i;
4282
4283    zmw_get_wlan_dev(dev);
4284
4285    /* Element ID */
4286    zmw_tx_buf_writeb(dev, buf, offset++, ZM_WLAN_EID_SSID);
4287
4288    /* Element Length */
4289    zmw_tx_buf_writeb(dev, buf, offset++, wd->sta.ssidLen);
4290
4291    /* Information : SSID */
4292    for (i=0; i<wd->sta.ssidLen; i++)
4293    {
4294        zmw_tx_buf_writeb(dev, buf, offset++, wd->sta.ssid[i]);
4295    }
4296
4297    return offset;
4298}
4299
4300/************************************************************************/
4301/*                                                                      */
4302/*    FUNCTION DESCRIPTION                  zfStaMmAddIeWpa             */
4303/*      Add information element SSID to buffer.                         */
4304/*                                                                      */
4305/*    INPUTS                                                            */
4306/*      dev : device pointer                                            */
4307/*      buf : buffer to add information element                         */
4308/*      offset : add information element from this offset               */
4309/*                                                                      */
4310/*    OUTPUTS                                                           */
4311/*      buffer offset after adding information element                  */
4312/*                                                                      */
4313/*    AUTHOR                                                            */
4314/*      Ji-Huang Lee        ZyDAS Technology Corporation    2006.01     */
4315/*                                                                      */
4316/************************************************************************/
4317u16_t zfStaAddIeWpaRsn(zdev_t* dev, zbuf_t* buf, u16_t offset, u8_t frameType)
4318{
4319    u32_t  i;
4320    u8_t    ssn[64]={
4321                        /* Element ID */
4322                        0xdd,
4323                        /* Length */
4324                        0x18,
4325                        /* OUI type */
4326                        0x00, 0x50, 0xf2, 0x01,
4327                        /* Version */
4328                        0x01, 0x00,
4329                        /* Group Cipher Suite, default=TKIP */
4330                        0x00, 0x50, 0xf2, 0x02,
4331                        /* Pairwise Cipher Suite Count */
4332                        0x01, 0x00,
4333                        /* Pairwise Cipher Suite, default=TKIP */
4334                        0x00, 0x50, 0xf2, 0x02,
4335                        /* Authentication and Key Management Suite Count */
4336                        0x01, 0x00,
4337                        /* Authentication type, default=PSK */
4338                        0x00, 0x50, 0xf2, 0x02,
4339                        /* WPA capability */
4340                        0x00, 0x00
4341                    };
4342
4343    u8_t    rsn[64]={
4344                        /* Element ID */
4345                        0x30,
4346                        /* Length */
4347                        0x14,
4348                        /* Version */
4349                        0x01, 0x00,
4350                        /* Group Cipher Suite, default=TKIP */
4351                        0x00, 0x0f, 0xac, 0x02,
4352                        /* Pairwise Cipher Suite Count */
4353                        0x01, 0x00,
4354                        /* Pairwise Cipher Suite, default=TKIP */
4355                        0x00, 0x0f, 0xac, 0x02,
4356                        /* Authentication and Key Management Suite Count */
4357                        0x01, 0x00,
4358                        /* Authentication type, default=PSK */
4359                        0x00, 0x0f, 0xac, 0x02,
4360                        /* RSN capability */
4361                        0x00, 0x00
4362                    };
4363
4364    zmw_get_wlan_dev(dev);
4365
4366    if ( wd->sta.currentAuthMode == ZM_AUTH_MODE_WPAPSK )
4367    {
4368        /* Overwrite Group Cipher Suite by AP's setting */
4369        zfMemoryCopy(ssn+8, wd->sta.wpaIe+8, 4);
4370
4371        if ( wd->sta.wepStatus == ZM_ENCRYPTION_AES )
4372        {
4373            /* Overwrite Pairwise Cipher Suite by AES */
4374            zfMemoryCopy(ssn+14, zgWpaAesOui, 4);
4375        }
4376
4377        zfCopyToIntTxBuffer(dev, buf, ssn, offset, ssn[1]+2);
4378        zfMemoryCopy(wd->sta.wpaIe, ssn, ssn[1]+2);
4379        offset += (ssn[1]+2);
4380    }
4381    else if ( wd->sta.currentAuthMode == ZM_AUTH_MODE_WPA )
4382    {
4383        /* Overwrite Group Cipher Suite by AP's setting */
4384        zfMemoryCopy(ssn+8, wd->sta.wpaIe+8, 4);
4385        /* Overwrite Key Management Suite by WPA-Radius */
4386        zfMemoryCopy(ssn+20, zgWpaRadiusOui, 4);
4387
4388        if ( wd->sta.wepStatus == ZM_ENCRYPTION_AES )
4389        {
4390            /* Overwrite Pairwise Cipher Suite by AES */
4391            zfMemoryCopy(ssn+14, zgWpaAesOui, 4);
4392        }
4393
4394        zfCopyToIntTxBuffer(dev, buf, ssn, offset, ssn[1]+2);
4395        zfMemoryCopy(wd->sta.wpaIe, ssn, ssn[1]+2);
4396        offset += (ssn[1]+2);
4397    }
4398    else if ( wd->sta.currentAuthMode == ZM_AUTH_MODE_WPA2PSK )
4399    {
4400        /* Overwrite Group Cipher Suite by AP's setting */
4401        zfMemoryCopy(rsn+4, wd->sta.rsnIe+4, 4);
4402
4403        if ( wd->sta.wepStatus == ZM_ENCRYPTION_AES )
4404        {
4405            /* Overwrite Pairwise Cipher Suite by AES */
4406            zfMemoryCopy(rsn+10, zgWpa2AesOui, 4);
4407        }
4408
4409        if ( frameType == ZM_WLAN_FRAME_TYPE_REASOCREQ )
4410        {
4411            for(i=0; i<wd->sta.pmkidInfo.bssidCount; i++)
4412            {
4413                if ( zfMemoryIsEqual((u8_t*) wd->sta.pmkidInfo.bssidInfo[i].bssid,
4414                                     (u8_t*) wd->sta.bssid, 6) )
4415                {
4416                    /* matched */
4417                    break;
4418                }
4419
4420                if ( i < wd->sta.pmkidInfo.bssidCount )
4421                {
4422                    // Fill PMKID Count in RSN information element
4423                    rsn[22] = 0x01;
4424                    rsn[23] = 0x00;
4425
4426                    // Fill PMKID in RSN information element
4427                    zfMemoryCopy(rsn+24,
4428                                 wd->sta.pmkidInfo.bssidInfo[i].pmkid, 16);
4429			                 rsn[1] += 18;
4430                }
4431            }
4432        }
4433
4434        zfCopyToIntTxBuffer(dev, buf, rsn, offset, rsn[1]+2);
4435        zfMemoryCopy(wd->sta.rsnIe, rsn, rsn[1]+2);
4436        offset += (rsn[1]+2);
4437    }
4438    else if ( wd->sta.currentAuthMode == ZM_AUTH_MODE_WPA2 )
4439    {
4440        /* Overwrite Group Cipher Suite by AP's setting */
4441        zfMemoryCopy(rsn+4, wd->sta.rsnIe+4, 4);
4442        /* Overwrite Key Management Suite by WPA2-Radius */
4443        zfMemoryCopy(rsn+16, zgWpa2RadiusOui, 4);
4444
4445        if ( wd->sta.wepStatus == ZM_ENCRYPTION_AES )
4446        {
4447            /* Overwrite Pairwise Cipher Suite by AES */
4448            zfMemoryCopy(rsn+10, zgWpa2AesOui, 4);
4449        }
4450
4451        if (( frameType == ZM_WLAN_FRAME_TYPE_REASOCREQ || ( frameType == ZM_WLAN_FRAME_TYPE_ASOCREQ )))
4452        {
4453
4454            if (wd->sta.pmkidInfo.bssidCount != 0) {
4455                // Fill PMKID Count in RSN information element
4456                rsn[22] = 1;
4457                rsn[23] = 0;
4458                /*
4459                 *  The caller is respnsible to give us the relevant PMKID.
4460                 *  We'll only accept 1 PMKID for now.
4461                 */
4462                for(i=0; i<wd->sta.pmkidInfo.bssidCount; i++)
4463                {
4464                    if ( zfMemoryIsEqual((u8_t*) wd->sta.pmkidInfo.bssidInfo[i].bssid, (u8_t*) wd->sta.bssid, 6) )
4465                    {
4466                        zfMemoryCopy(rsn+24, wd->sta.pmkidInfo.bssidInfo[i].pmkid, 16);
4467                        break;
4468                    }
4469                }
4470                rsn[1] += 18;
4471            }
4472
4473        }
4474
4475        zfCopyToIntTxBuffer(dev, buf, rsn, offset, rsn[1]+2);
4476        zfMemoryCopy(wd->sta.rsnIe, rsn, rsn[1]+2);
4477        offset += (rsn[1]+2);
4478    }
4479
4480    return offset;
4481}
4482
4483/************************************************************************/
4484/*                                                                      */
4485/*    FUNCTION DESCRIPTION                  zfStaAddIeIbss              */
4486/*      Add information element IBSS parameter to buffer.               */
4487/*                                                                      */
4488/*    INPUTS                                                            */
4489/*      dev : device pointer                                            */
4490/*      buf : buffer to add information element                         */
4491/*      offset : add information element from this offset               */
4492/*                                                                      */
4493/*    OUTPUTS                                                           */
4494/*      buffer offset after adding information element                  */
4495/*                                                                      */
4496/*    AUTHOR                                                            */
4497/*      Ji-Huang Lee        ZyDAS Technology Corporation    2005.12     */
4498/*                                                                      */
4499/************************************************************************/
4500u16_t zfStaAddIeIbss(zdev_t* dev, zbuf_t* buf, u16_t offset)
4501{
4502    zmw_get_wlan_dev(dev);
4503
4504    /* Element ID */
4505    zmw_tx_buf_writeb(dev, buf, offset++, ZM_WLAN_EID_IBSS);
4506
4507    /* Element Length */
4508    zmw_tx_buf_writeb(dev, buf, offset++, 2);
4509
4510    /* ATIM window */
4511    zmw_tx_buf_writeh(dev, buf, offset, wd->sta.atimWindow);
4512    offset += 2;
4513
4514    return offset;
4515}
4516
4517
4518
4519/************************************************************************/
4520/*                                                                      */
4521/*    FUNCTION DESCRIPTION                  zfStaAddIeWmeInfo           */
4522/*      Add WME Information Element to buffer.                          */
4523/*                                                                      */
4524/*    INPUTS                                                            */
4525/*      dev : device pointer                                            */
4526/*      buf : buffer to add information element                         */
4527/*      offset : add information element from this offset               */
4528/*                                                                      */
4529/*    OUTPUTS                                                           */
4530/*      buffer offset after adding information element                  */
4531/*                                                                      */
4532/*    AUTHOR                                                            */
4533/*      Stephen Chen        ZyDAS Technology Corporation    2006.6      */
4534/*                                                                      */
4535/************************************************************************/
4536u16_t zfStaAddIeWmeInfo(zdev_t* dev, zbuf_t* buf, u16_t offset, u8_t qosInfo)
4537{
4538    /* Element ID */
4539    zmw_tx_buf_writeb(dev, buf, offset++, ZM_WLAN_EID_WIFI_IE);
4540
4541    /* Element Length */
4542    zmw_tx_buf_writeb(dev, buf, offset++, 7);
4543
4544    /* OUI */
4545    zmw_tx_buf_writeb(dev, buf, offset++, 0x00);
4546    zmw_tx_buf_writeb(dev, buf, offset++, 0x50);
4547    zmw_tx_buf_writeb(dev, buf, offset++, 0xF2);
4548    zmw_tx_buf_writeb(dev, buf, offset++, 0x02);
4549    zmw_tx_buf_writeb(dev, buf, offset++, 0x00);
4550    zmw_tx_buf_writeb(dev, buf, offset++, 0x01);
4551
4552    /* QoS Info */
4553    zmw_tx_buf_writeb(dev, buf, offset++, qosInfo);
4554
4555    return offset;
4556}
4557
4558/************************************************************************/
4559/*                                                                      */
4560/*    FUNCTION DESCRIPTION                  zfStaAddIePowerCap          */
4561/*      Add information element Power capability to buffer.             */
4562/*                                                                      */
4563/*    INPUTS                                                            */
4564/*      dev : device pointer                                            */
4565/*      buf : buffer to add information element                         */
4566/*      offset : add information element from this offset               */
4567/*                                                                      */
4568/*    OUTPUTS                                                           */
4569/*      buffer offset after adding information element                  */
4570/*                                                                      */
4571/*    AUTHOR                                                            */
4572/*      Sharon                                            2007.12       */
4573/*                                                                      */
4574/************************************************************************/
4575u16_t zfStaAddIePowerCap(zdev_t* dev, zbuf_t* buf, u16_t offset)
4576{
4577    u8_t MaxTxPower;
4578    u8_t MinTxPower;
4579
4580    /* Element ID */
4581    zmw_tx_buf_writeb(dev, buf, offset++, ZM_WLAN_EID_POWER_CAPABILITY);
4582
4583    /* Element Length */
4584    zmw_tx_buf_writeb(dev, buf, offset++, 2);
4585
4586    MinTxPower = (u8_t)(zfHpGetMinTxPower(dev)/2);
4587    MaxTxPower = (u8_t)(zfHpGetMaxTxPower(dev)/2);
4588
4589    /* Min Transmit Power Cap */
4590    zmw_tx_buf_writeh(dev, buf, offset++, MinTxPower);
4591
4592    /* Max Transmit Power Cap */
4593    zmw_tx_buf_writeh(dev, buf, offset++, MaxTxPower);
4594
4595    return offset;
4596}
4597/************************************************************************/
4598/*                                                                      */
4599/*    FUNCTION DESCRIPTION                  zfStaAddIeSupportCh              */
4600/*      Add information element supported channels to buffer.               */
4601/*                                                                      */
4602/*    INPUTS                                                            */
4603/*      dev : device pointer                                            */
4604/*      buf : buffer to add information element                         */
4605/*      offset : add information element from this offset               */
4606/*                                                                      */
4607/*    OUTPUTS                                                           */
4608/*      buffer offset after adding information element                  */
4609/*                                                                      */
4610/*    AUTHOR                                                            */
4611/*      Sharon            2007.12     */
4612/*                                                                      */
4613/************************************************************************/
4614u16_t zfStaAddIeSupportCh(zdev_t* dev, zbuf_t* buf, u16_t offset)
4615{
4616
4617    u8_t   i;
4618    u16_t  count_24G = 0;
4619    u16_t  count_5G = 0;
4620    u16_t  channelNum;
4621    u8_t   length;
4622
4623    zmw_get_wlan_dev(dev);
4624
4625    zmw_declare_for_critical_section();
4626    zmw_enter_critical_section(dev);
4627
4628    for (i = 0; i < wd->regulationTable.allowChannelCnt; i++)
4629    {
4630        if (wd->regulationTable.allowChannel[i].channel < 3000)
4631        { // 2.4Hz
4632            count_24G++;
4633        }
4634        else
4635        { // 5GHz
4636            count_5G++;
4637        }
4638    }
4639
4640    length = (u8_t)(count_5G * 2 + 2); //5G fill by pair, 2,4G (continuous channels) fill 2 bytes
4641
4642    /* Element ID */
4643    zmw_tx_buf_writeb(dev, buf, offset++, ZM_WLAN_EID_SUPPORTED_CHANNELS );
4644
4645    /* Element Length */
4646    zmw_tx_buf_writeb(dev, buf, offset++, length);
4647
4648    // 2.4GHz (continuous channels)
4649    /* First channel number */
4650    zmw_tx_buf_writeh(dev, buf, offset++, 1); //Start from channle 1
4651    /* Number of channels */
4652    zmw_tx_buf_writeh(dev, buf, offset++, count_24G);
4653
4654    for (i = 0; i < wd->regulationTable.allowChannelCnt ; i++)
4655    {
4656        if (wd->regulationTable.allowChannel[i].channel > 4000 && wd->regulationTable.allowChannel[i].channel < 5000)
4657        { // 5GHz 4000 -5000Mhz
4658            channelNum = (wd->regulationTable.allowChannel[i].channel-4000)/5;
4659            /* First channel number */
4660            zmw_tx_buf_writeh(dev, buf, offset++, channelNum);
4661            /* Number of channels */
4662            zmw_tx_buf_writeh(dev, buf, offset++, 1);
4663        }
4664        else if (wd->regulationTable.allowChannel[i].channel >= 5000)
4665        { // 5GHz >5000Mhz
4666            channelNum = (wd->regulationTable.allowChannel[i].channel-5000)/5;
4667            /* First channel number */
4668            zmw_tx_buf_writeh(dev, buf, offset++, channelNum);
4669            /* Number of channels */
4670            zmw_tx_buf_writeh(dev, buf, offset++, 1);
4671        }
4672    }
4673   zmw_leave_critical_section(dev);
4674
4675    return offset;
4676}
4677
4678void zfStaStartConnectCb(zdev_t* dev)
4679{
4680    zmw_get_wlan_dev(dev);
4681
4682    zfStaStartConnect(dev, wd->sta.bIsSharedKey);
4683}
4684
4685void zfStaStartConnect(zdev_t* dev, u8_t bIsSharedKey)
4686{
4687    u32_t p1, p2;
4688    u8_t newConnState;
4689
4690    zmw_get_wlan_dev(dev);
4691    zmw_declare_for_critical_section();
4692
4693    /* p1_low = algorithm number, p1_high = transaction sequence number */
4694    if ( bIsSharedKey )
4695    {
4696        //wd->sta.connectState = ZM_STA_CONN_STATE_AUTH_SHARE_1;
4697        newConnState = ZM_STA_CONN_STATE_AUTH_SHARE_1;
4698        zm_debug_msg0("ZM_STA_CONN_STATE_AUTH_SHARE_1");
4699        p1 = ZM_AUTH_ALGO_SHARED_KEY;
4700    }
4701    else
4702    {
4703        //wd->sta.connectState = ZM_STA_CONN_STATE_AUTH_OPEN;
4704        newConnState = ZM_STA_CONN_STATE_AUTH_OPEN;
4705        zm_debug_msg0("ZM_STA_CONN_STATE_AUTH_OPEN");
4706        if( wd->sta.leapEnabled )
4707            p1 = ZM_AUTH_ALGO_LEAP;
4708        else
4709            p1 = ZM_AUTH_ALGO_OPEN_SYSTEM;
4710    }
4711
4712    /* status code */
4713    p2 = 0x0;
4714
4715    zmw_enter_critical_section(dev);
4716    wd->sta.connectTimer = wd->tick;
4717    wd->sta.connectState = newConnState;
4718    zmw_leave_critical_section(dev);
4719
4720    /* send the 1st authentication frame */
4721    zfSendMmFrame(dev, ZM_WLAN_FRAME_TYPE_AUTH, wd->sta.bssid, p1, p2, 0);
4722
4723    return;
4724}
4725
4726void zfSendNullData(zdev_t* dev, u8_t type)
4727{
4728    zbuf_t* buf;
4729    //u16_t addrTblSize;
4730    //struct zsAddrTbl addrTbl;
4731    u16_t err;
4732    u16_t hlen;
4733    u16_t header[(34+8+1)/2];
4734    u16_t bcastAddr[3] = {0xffff,0xffff,0xffff};
4735    u16_t *dstAddr;
4736
4737    zmw_get_wlan_dev(dev);
4738
4739    buf = zfwBufAllocate(dev, 1024);
4740    if (buf == NULL)
4741    {
4742        zm_msg0_mm(ZM_LV_0, "Alloc mm buf Fail!");
4743        return;
4744    }
4745
4746    zfwBufSetSize(dev, buf, 0);
4747
4748    //zm_msg2_mm(ZM_LV_2, "buf->len=", buf->len);
4749
4750    if ( wd->wlanMode == ZM_MODE_IBSS)
4751    {
4752        dstAddr = bcastAddr;
4753    }
4754    else
4755    {
4756        dstAddr = wd->sta.bssid;
4757    }
4758
4759    if (wd->sta.wmeConnected != 0)
4760    {
4761        /* If connect to a WMM AP, Send QoS Null data */
4762        hlen = zfTxGenMmHeader(dev, ZM_WLAN_FRAME_TYPE_QOS_NULL, dstAddr, header, 0, buf, 0, 0);
4763    }
4764    else
4765    {
4766        hlen = zfTxGenMmHeader(dev, ZM_WLAN_FRAME_TYPE_NULL, dstAddr, header, 0, buf, 0, 0);
4767    }
4768
4769    if (wd->wlanMode == ZM_MODE_INFRASTRUCTURE)
4770    {
4771        header[4] |= 0x0100; //TODS bit
4772    }
4773
4774    if ( type == 1 )
4775    {
4776        header[4] |= 0x1000;
4777    }
4778
4779    /* Get buffer DMA address */
4780    //if ((addrTblSize = zfwBufMapDma(dev, buf, &addrTbl)) == 0)
4781    //if ((addrTblSize = zfwMapTxDma(dev, buf, &addrTbl)) == 0)
4782    //{
4783    //    goto zlError;
4784    //}
4785
4786    /*increase unicast frame counter*/
4787    wd->commTally.txUnicastFrm++;
4788
4789    err = zfHpSend(dev, header, hlen, NULL, 0, NULL, 0, buf, 0,
4790            ZM_INTERNAL_ALLOC_BUF, 0, 0xff);
4791    if (err != ZM_SUCCESS)
4792    {
4793        goto zlError;
4794    }
4795
4796
4797    return;
4798
4799zlError:
4800
4801    zfwBufFree(dev, buf, 0);
4802    return;
4803
4804}
4805
4806void zfSendPSPoll(zdev_t* dev)
4807{
4808    zbuf_t* buf;
4809    //u16_t addrTblSize;
4810    //struct zsAddrTbl addrTbl;
4811    u16_t err;
4812    u16_t hlen;
4813    u16_t header[(8+24+1)/2];
4814
4815    zmw_get_wlan_dev(dev);
4816
4817    buf = zfwBufAllocate(dev, 1024);
4818    if (buf == NULL)
4819    {
4820        zm_msg0_mm(ZM_LV_0, "Alloc mm buf Fail!");
4821        return;
4822    }
4823
4824    zfwBufSetSize(dev, buf, 0);
4825
4826    //zm_msg2_mm(ZM_LV_2, "buf->len=", buf->len);
4827
4828    zfTxGenMmHeader(dev, ZM_WLAN_FRAME_TYPE_PSPOLL, wd->sta.bssid, header, 0, buf, 0, 0);
4829
4830    header[0] = 20;
4831    header[4] |= 0x1000;
4832    header[5] = wd->sta.aid | 0xc000; //Both bit-14 and bit-15 are 1
4833    hlen = 16 + 8;
4834
4835    /* Get buffer DMA address */
4836    //if ((addrTblSize = zfwBufMapDma(dev, buf, &addrTbl)) == 0)
4837    //if ((addrTblSize = zfwMapTxDma(dev, buf, &addrTbl)) == 0)
4838    //{
4839    //    goto zlError;
4840    //}
4841
4842    err = zfHpSend(dev, header, hlen, NULL, 0, NULL, 0, buf, 0,
4843		   ZM_INTERNAL_ALLOC_BUF, 0, 0xff);
4844    if (err != ZM_SUCCESS)
4845    {
4846        goto zlError;
4847    }
4848
4849    return;
4850
4851zlError:
4852
4853    zfwBufFree(dev, buf, 0);
4854    return;
4855
4856}
4857
4858void zfSendBA(zdev_t* dev, u16_t start_seq, u8_t *bitmap)
4859{
4860    zbuf_t* buf;
4861    //u16_t addrTblSize;
4862    //struct zsAddrTbl addrTbl;
4863    u16_t err;
4864    u16_t hlen;
4865    u16_t header[(8+24+1)/2];
4866    u16_t i, offset = 0;
4867
4868    zmw_get_wlan_dev(dev);
4869
4870    buf = zfwBufAllocate(dev, 1024);
4871    if (buf == NULL)
4872    {
4873        zm_msg0_mm(ZM_LV_0, "Alloc mm buf Fail!");
4874        return;
4875    }
4876
4877    zfwBufSetSize(dev, buf, 12); // 28 = FC 2 + DU 2 + RA 6 + TA 6 + BAC 2 + SEQ 2 + BitMap 8
4878                                 // 12 = BAC 2 + SEQ 2 + BitMap 8
4879
4880    //zm_msg2_mm(ZM_LV_2, "buf->len=", buf->len);
4881
4882    zfTxGenMmHeader(dev, ZM_WLAN_FRAME_TYPE_BA, wd->sta.bssid, header, 0, buf, 0, 0);
4883
4884    header[0] = 32; /* MAC header 16 + BA control 2 + BA info 10 + FCS 4*/
4885    header[1] = 0x4;  /* No ACK */
4886
4887    /* send by OFDM 6M */
4888    header[2] = (u16_t)(zcRateToPhyCtrl[4] & 0xffff);
4889    header[3] = (u16_t)(zcRateToPhyCtrl[4]>>16) & 0xffff;
4890
4891    hlen = 16 + 8;  /* MAC header 16 + control 8*/
4892    offset = 0;
4893    zmw_tx_buf_writeh(dev, buf, offset, 0x05); /*compressed bitmap on*/
4894    offset+=2;
4895    zmw_tx_buf_writeh(dev, buf, offset, start_seq);
4896    offset+=2;
4897
4898    for (i=0; i<8; i++) {
4899        zmw_tx_buf_writeb(dev, buf, offset, bitmap[i]);
4900        offset++;
4901    }
4902
4903    err = zfHpSend(dev, header, hlen, NULL, 0, NULL, 0, buf, 0,
4904		   ZM_INTERNAL_ALLOC_BUF, 0, 0xff);
4905    if (err != ZM_SUCCESS)
4906    {
4907        goto zlError;
4908    }
4909
4910    return;
4911
4912zlError:
4913
4914    zfwBufFree(dev, buf, 0);
4915    return;
4916
4917}
4918
4919void zfStaGetTxRate(zdev_t* dev, u16_t* macAddr, u32_t* phyCtrl,
4920        u16_t* rcProbingFlag)
4921{
4922    u8_t   addr[6], i;
4923    u8_t   rate;
4924    zmw_get_wlan_dev(dev);
4925    zmw_declare_for_critical_section();
4926
4927    ZM_MAC_WORD_TO_BYTE(macAddr, addr);
4928    *phyCtrl = 0;
4929
4930    if ( wd->wlanMode == ZM_MODE_INFRASTRUCTURE )
4931    {
4932        zmw_enter_critical_section(dev);
4933        rate = (u8_t)zfRateCtrlGetTxRate(dev, &wd->sta.oppositeInfo[0].rcCell, rcProbingFlag);
4934//#ifdef ZM_FB50
4935        //rate = 27;
4936//#endif
4937        *phyCtrl = zcRateToPhyCtrl[rate];
4938        zmw_leave_critical_section(dev);
4939    }
4940    else
4941    {
4942        zmw_enter_critical_section(dev);
4943        for(i=0; i<wd->sta.oppositeCount; i++)
4944        {
4945            if ( addr[0] && 0x01 == 1 ) // The default beacon transmitted rate is CCK and 1 Mbps , but the a mode should use
4946                                        // OFDM modulation and 6Mbps to transmit beacon.
4947            {
4948                //rate = (u8_t)zfRateCtrlGetTxRate(dev, &wd->sta.oppositeInfo[i].rcCell, rcProbingFlag);
4949                rate = wd->sta.oppositeInfo[i].rcCell.operationRateSet[0];
4950                *phyCtrl = zcRateToPhyCtrl[rate];
4951                break;
4952            }
4953            else if ( zfMemoryIsEqual(addr, wd->sta.oppositeInfo[i].macAddr, 6) )
4954            {
4955                rate = (u8_t)zfRateCtrlGetTxRate(dev, &wd->sta.oppositeInfo[i].rcCell, rcProbingFlag);
4956                *phyCtrl = zcRateToPhyCtrl[rate];
4957                break;
4958            }
4959        }
4960        zmw_leave_critical_section(dev);
4961    }
4962
4963    return;
4964}
4965
4966struct zsMicVar* zfStaGetRxMicKey(zdev_t* dev, zbuf_t* buf)
4967{
4968    u8_t keyIndex;
4969    u8_t da0;
4970
4971    zmw_get_wlan_dev(dev);
4972
4973    /* if need not check MIC, return NULL */
4974    if ( ((wd->sta.encryMode != ZM_TKIP)&&(wd->sta.encryMode != ZM_AES))||
4975         (wd->sta.wpaState < ZM_STA_WPA_STATE_PK_OK) )
4976    {
4977        return NULL;
4978    }
4979
4980    da0 = zmw_rx_buf_readb(dev, buf, ZM_WLAN_HEADER_A1_OFFSET);
4981
4982    if ((zmw_rx_buf_readb(dev, buf, 0) & 0x80) == 0x80)
4983        keyIndex = zmw_rx_buf_readb(dev, buf, ZM_WLAN_HEADER_IV_OFFSET+5); /* Qos Packet*/
4984    else
4985        keyIndex = zmw_rx_buf_readb(dev, buf, ZM_WLAN_HEADER_IV_OFFSET+3); /* normal Packet*/
4986    keyIndex = (keyIndex & 0xc0) >> 6;
4987
4988    return (&wd->sta.rxMicKey[keyIndex]);
4989}
4990
4991struct zsMicVar* zfStaGetTxMicKey(zdev_t* dev, zbuf_t* buf)
4992{
4993    zmw_get_wlan_dev(dev);
4994
4995    /* if need not check MIC, return NULL */
4996    //if ( ((wd->sta.encryMode != ZM_TKIP)&&(wd->sta.encryMode != ZM_AES))||
4997    //     (wd->sta.wpaState < ZM_STA_WPA_STATE_PK_OK) )
4998    if ( (wd->sta.encryMode != ZM_TKIP) || (wd->sta.wpaState < ZM_STA_WPA_STATE_PK_OK) )
4999    {
5000        return NULL;
5001    }
5002
5003    return (&wd->sta.txMicKey);
5004}
5005
5006u16_t zfStaRxValidateFrame(zdev_t* dev, zbuf_t* buf)
5007{
5008    u8_t   frameType, frameCtrl;
5009    u8_t   da0;
5010    //u16_t  sa[3];
5011    u16_t  ret;
5012    //u8_t    sa0;
5013
5014    zmw_get_wlan_dev(dev);
5015
5016    frameType = zmw_rx_buf_readb(dev, buf, 0);
5017    da0 = zmw_rx_buf_readb(dev, buf, ZM_WLAN_HEADER_A1_OFFSET);
5018    //sa0 = zmw_rx_buf_readb(dev, buf, ZM_WLAN_HEADER_A2_OFFSET);
5019
5020    if ( (!zfStaIsConnected(dev))&&((frameType & 0xf) == ZM_WLAN_DATA_FRAME) )
5021    {
5022        return ZM_ERR_DATA_BEFORE_CONNECTED;
5023    }
5024
5025
5026    if ( (zfStaIsConnected(dev))&&((frameType & 0xf) == ZM_WLAN_DATA_FRAME) )
5027    {
5028        /* check BSSID */
5029        if ( wd->wlanMode == ZM_MODE_INFRASTRUCTURE )
5030        {
5031            /* Big Endian and Little Endian Compatibility */
5032            u16_t mac[3];
5033            mac[0] = zmw_cpu_to_le16(wd->sta.bssid[0]);
5034            mac[1] = zmw_cpu_to_le16(wd->sta.bssid[1]);
5035            mac[2] = zmw_cpu_to_le16(wd->sta.bssid[2]);
5036            if ( !zfRxBufferEqualToStr(dev, buf, (u8_t *)mac,
5037                                       ZM_WLAN_HEADER_A2_OFFSET, 6) )
5038            {
5039/*We will get lots of garbage data, especially in AES mode.*/
5040/*To avoid sending too many deauthentication frames in STA mode, mark it.*/
5041                return ZM_ERR_DATA_BSSID_NOT_MATCHED;
5042            }
5043        }
5044        else if ( wd->wlanMode == ZM_MODE_IBSS )
5045        {
5046            /* Big Endian and Little Endian Compatibility */
5047            u16_t mac[3];
5048            mac[0] = zmw_cpu_to_le16(wd->sta.bssid[0]);
5049            mac[1] = zmw_cpu_to_le16(wd->sta.bssid[1]);
5050            mac[2] = zmw_cpu_to_le16(wd->sta.bssid[2]);
5051            if ( !zfRxBufferEqualToStr(dev, buf, (u8_t *)mac,
5052                                       ZM_WLAN_HEADER_A3_OFFSET, 6) )
5053            {
5054                return ZM_ERR_DATA_BSSID_NOT_MATCHED;
5055            }
5056        }
5057
5058        frameCtrl = zmw_rx_buf_readb(dev, buf, 1);
5059
5060        /* check security bit */
5061        if ( wd->sta.dropUnencryptedPkts &&
5062             (wd->sta.wepStatus != ZM_ENCRYPTION_WEP_DISABLED )&&
5063             ( !(frameCtrl & ZM_BIT_6) ) )
5064        {   /* security on, but got data without encryption */
5065
5066            ret = ZM_ERR_DATA_NOT_ENCRYPTED;
5067            if ( wd->sta.pStaRxSecurityCheckCb != NULL )
5068            {
5069                ret = wd->sta.pStaRxSecurityCheckCb(dev, buf);
5070            }
5071            else
5072            {
5073                ret = ZM_ERR_DATA_NOT_ENCRYPTED;
5074            }
5075            if (ret == ZM_ERR_DATA_NOT_ENCRYPTED)
5076            {
5077                wd->commTally.swRxDropUnencryptedCount++;
5078            }
5079            return ret;
5080        }
5081    }
5082
5083    return ZM_SUCCESS;
5084}
5085
5086void zfStaMicFailureHandling(zdev_t* dev, zbuf_t* buf)
5087{
5088    u8_t   da0;
5089    u8_t   micNotify = 1;
5090
5091    zmw_get_wlan_dev(dev);
5092
5093    zmw_declare_for_critical_section();
5094
5095    if ( wd->sta.wpaState <  ZM_STA_WPA_STATE_PK_OK )
5096    {
5097        return;
5098    }
5099
5100    zmw_enter_critical_section(dev);
5101
5102    wd->sta.cmMicFailureCount++;
5103
5104    if ( wd->sta.cmMicFailureCount == 1 )
5105    {
5106        zm_debug_msg0("get the first MIC failure");
5107        //zfTimerSchedule(dev, ZM_EVENT_CM_TIMER, ZM_TICK_CM_TIMEOUT);
5108
5109        /* Timer Resolution on WinXP is 15/16 ms  */
5110        /* Decrease Time offset for <XP> Counter Measure */
5111        zfTimerSchedule(dev, ZM_EVENT_CM_TIMER, ZM_TICK_CM_TIMEOUT - ZM_TICK_CM_TIMEOUT_OFFSET);
5112    }
5113    else if ( wd->sta.cmMicFailureCount == 2 )
5114    {
5115        zm_debug_msg0("get the second MIC failure");
5116        /* reserve 2 second for OS to send MIC failure report to AP */
5117        wd->sta.cmDisallowSsidLength = wd->sta.ssidLen;
5118        zfMemoryCopy(wd->sta.cmDisallowSsid, wd->sta.ssid, wd->sta.ssidLen);
5119        //wd->sta.cmMicFailureCount = 0;
5120        zfTimerCancel(dev, ZM_EVENT_CM_TIMER);
5121        //zfTimerSchedule(dev, ZM_EVENT_CM_DISCONNECT, ZM_TICK_CM_DISCONNECT);
5122
5123        /* Timer Resolution on WinXP is 15/16 ms  */
5124        /* Decrease Time offset for <XP> Counter Measure */
5125        zfTimerSchedule(dev, ZM_EVENT_CM_DISCONNECT, ZM_TICK_CM_DISCONNECT - ZM_TICK_CM_DISCONNECT_OFFSET);
5126    }
5127    else
5128    {
5129        micNotify = 0;
5130    }
5131
5132    zmw_leave_critical_section(dev);
5133
5134    if (micNotify == 1)
5135    {
5136        da0 = zmw_rx_buf_readb(dev, buf, ZM_WLAN_HEADER_A1_OFFSET);
5137        if ( da0 & 0x01 )
5138        {
5139            if (wd->zfcbMicFailureNotify != NULL)
5140            {
5141                wd->zfcbMicFailureNotify(dev, wd->sta.bssid, ZM_MIC_GROUP_ERROR);
5142            }
5143        }
5144        else
5145        {
5146            if (wd->zfcbMicFailureNotify != NULL)
5147            {
5148                wd->zfcbMicFailureNotify(dev, wd->sta.bssid, ZM_MIC_PAIRWISE_ERROR);
5149            }
5150        }
5151    }
5152}
5153
5154
5155u8_t zfStaBlockWlanScan(zdev_t* dev)
5156{
5157    u8_t   ret=FALSE;
5158
5159    zmw_get_wlan_dev(dev);
5160
5161    if ( wd->sta.bChannelScan )
5162    {
5163        return TRUE;
5164    }
5165
5166    return ret;
5167}
5168
5169void zfStaResetStatus(zdev_t* dev, u8_t bInit)
5170{
5171    u8_t   i;
5172
5173    zmw_get_wlan_dev(dev);
5174
5175    zfHpDisableBeacon(dev);
5176
5177    wd->dtim = 1;
5178    wd->sta.capability[0] = 0x01;
5179    wd->sta.capability[1] = 0x00;
5180    /* 802.11h */
5181    if (wd->sta.DFSEnable || wd->sta.TPCEnable)
5182        wd->sta.capability[1] |= ZM_BIT_0;
5183
5184    /* release queued packets */
5185    for(i=0; i<wd->sta.ibssPSDataCount; i++)
5186    {
5187        zfwBufFree(dev, wd->sta.ibssPSDataQueue[i], 0);
5188    }
5189
5190    for(i=0; i<wd->sta.staPSDataCount; i++)
5191    {
5192        zfwBufFree(dev, wd->sta.staPSDataQueue[i], 0);
5193    }
5194
5195    wd->sta.ibssPSDataCount = 0;
5196    wd->sta.staPSDataCount = 0;
5197    zfZeroMemory((u8_t*) &wd->sta.staPSList, sizeof(struct zsStaPSList));
5198
5199    wd->sta.wmeConnected = 0;
5200    wd->sta.psMgr.tempWakeUp = 0;
5201    wd->sta.qosInfo = 0;
5202    zfQueueFlush(dev, wd->sta.uapsdQ);
5203
5204    return;
5205
5206}
5207
5208void zfStaIbssMonitoring(zdev_t* dev, u8_t reset)
5209{
5210    u16_t i;
5211    u16_t oppositeCount;
5212    struct zsPartnerNotifyEvent event;
5213
5214    zmw_get_wlan_dev(dev);
5215
5216    zmw_declare_for_critical_section();
5217
5218    //zm_debug_msg1("zfStaIbssMonitoring %d", wd->sta.oppositeCount);
5219
5220    zmw_enter_critical_section(dev);
5221
5222    if ( wd->sta.oppositeCount == 0 )
5223    {
5224        goto done;
5225    }
5226
5227    if ( wd->sta.bChannelScan )
5228    {
5229        goto done;
5230    }
5231
5232    oppositeCount = wd->sta.oppositeCount;
5233
5234    for(i=0; i < ZM_MAX_OPPOSITE_COUNT; i++)
5235    {
5236        if ( oppositeCount == 0 )
5237        {
5238            break;
5239        }
5240
5241        if ( reset )
5242        {
5243            wd->sta.oppositeInfo[i].valid = 0;
5244        }
5245
5246        if ( wd->sta.oppositeInfo[i].valid == 0 )
5247        {
5248            continue;
5249        }
5250
5251        oppositeCount--;
5252
5253        if ( wd->sta.oppositeInfo[i].aliveCounter )
5254        {
5255            zm_debug_msg1("Setting alive to ", wd->sta.oppositeInfo[i].aliveCounter);
5256
5257            zmw_leave_critical_section(dev);
5258
5259            if ( wd->sta.oppositeInfo[i].aliveCounter != ZM_IBSS_PEER_ALIVE_COUNTER )
5260            {
5261                zfSendMmFrame(dev, ZM_WLAN_FRAME_TYPE_PROBEREQ,
5262                              (u16_t*)wd->sta.oppositeInfo[i].macAddr, 1, 0, 0);
5263            }
5264
5265            zmw_enter_critical_section(dev);
5266            wd->sta.oppositeInfo[i].aliveCounter--;
5267        }
5268        else
5269        {
5270            zm_debug_msg0("zfStaIbssMonitoring remove the peer station");
5271            zfMemoryCopy(event.bssid, (u8_t *)(wd->sta.bssid), 6);
5272            zfMemoryCopy(event.peerMacAddr, wd->sta.oppositeInfo[i].macAddr, 6);
5273
5274            wd->sta.oppositeInfo[i].valid = 0;
5275            wd->sta.oppositeCount--;
5276            if (wd->zfcbIbssPartnerNotify != NULL)
5277            {
5278                zmw_leave_critical_section(dev);
5279                wd->zfcbIbssPartnerNotify(dev, 0, &event);
5280                zmw_enter_critical_section(dev);
5281            }
5282        }
5283    }
5284
5285done:
5286    if ( reset == 0 )
5287    {
5288        zfTimerSchedule(dev, ZM_EVENT_IBSS_MONITOR, ZM_TICK_IBSS_MONITOR);
5289    }
5290
5291    zmw_leave_critical_section(dev);
5292}
5293
5294void zfInitPartnerNotifyEvent(zdev_t* dev, zbuf_t* buf, struct zsPartnerNotifyEvent *event)
5295{
5296    u16_t  *peerMacAddr;
5297
5298    zmw_get_wlan_dev(dev);
5299
5300    peerMacAddr = (u16_t *)event->peerMacAddr;
5301
5302    zfMemoryCopy(event->bssid, (u8_t *)(wd->sta.bssid), 6);
5303    peerMacAddr[0] = zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A2_OFFSET);
5304    peerMacAddr[1] = zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A2_OFFSET + 2);
5305    peerMacAddr[2] = zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A2_OFFSET + 4);
5306}
5307
5308void zfStaInitOppositeInfo(zdev_t* dev)
5309{
5310    int i;
5311
5312    zmw_get_wlan_dev(dev);
5313
5314    for(i=0; i<ZM_MAX_OPPOSITE_COUNT; i++)
5315    {
5316        wd->sta.oppositeInfo[i].valid = 0;
5317        wd->sta.oppositeInfo[i].aliveCounter = ZM_IBSS_PEER_ALIVE_COUNTER;
5318    }
5319}
5320#ifdef ZM_ENABLE_CENC
5321u16_t zfStaAddIeCenc(zdev_t* dev, zbuf_t* buf, u16_t offset)
5322{
5323    zmw_get_wlan_dev(dev);
5324
5325    if (wd->sta.cencIe[1] != 0)
5326    {
5327        zfCopyToIntTxBuffer(dev, buf, wd->sta.cencIe, offset, wd->sta.cencIe[1]+2);
5328        offset += (wd->sta.cencIe[1]+2);
5329    }
5330    return offset;
5331}
5332#endif //ZM_ENABLE_CENC
5333u16_t zfStaProcessAction(zdev_t* dev, zbuf_t* buf)
5334{
5335    u8_t category, actionDetails;
5336    zmw_get_wlan_dev(dev);
5337
5338    category = zmw_rx_buf_readb(dev, buf, 24);
5339    actionDetails = zmw_rx_buf_readb(dev, buf, 25);
5340    switch (category)
5341    {
5342        case 0:		//Spectrum Management
5343	        switch(actionDetails)
5344	        {
5345	        	case 0:			//Measurement Request
5346	        		break;
5347	        	case 1:			//Measurement Report
5348	        		//ProcessActionSpectrumFrame_MeasurementReport(Adapter,pActionBody+3);
5349	        		break;
5350	        	case 2:			//TPC request
5351                    //if (wd->sta.TPCEnable)
5352                    //    zfStaUpdateDot11HTPC(dev, buf);
5353	        		break;
5354	        	case 3:			//TPC report
5355                    //if (wd->sta.TPCEnable)
5356                    //    zfStaUpdateDot11HTPC(dev, buf);
5357	        		break;
5358	        	case 4:			//Channel Switch Announcement
5359                    if (wd->sta.DFSEnable)
5360                        zfStaUpdateDot11HDFS(dev, buf);
5361	        		break;
5362	        	default:
5363	        		zm_debug_msg1("Action Frame contain not support action field ", actionDetails);
5364	        		break;
5365	        }
5366        	break;
5367        case ZM_WLAN_BLOCK_ACK_ACTION_FRAME:
5368            zfAggBlockAckActionFrame(dev, buf);
5369            break;
5370        case 17:	//Qos Management
5371        	break;
5372    }
5373
5374    return 0;
5375}
5376
5377/* Determine the time not send beacon , if more than some value ,
5378   re-write the beacon start address */
5379void zfReWriteBeaconStartAddress(zdev_t* dev)
5380{
5381    zmw_get_wlan_dev(dev);
5382
5383    zmw_declare_for_critical_section();
5384
5385    zmw_enter_critical_section(dev);
5386    wd->tickIbssSendBeacon++;    // Increase 1 per 10ms .
5387    zmw_leave_critical_section(dev);
5388
5389    if ( wd->tickIbssSendBeacon == 40 )
5390    {
5391//        DbgPrint("20070727");
5392        zfHpEnableBeacon(dev, ZM_MODE_IBSS, wd->beaconInterval, wd->dtim, (u8_t)wd->sta.atimWindow);
5393        zmw_enter_critical_section(dev);
5394        wd->tickIbssSendBeacon = 0;
5395        zmw_leave_critical_section(dev);
5396    }
5397}
5398
5399struct zsTkipSeed* zfStaGetRxSeed(zdev_t* dev, zbuf_t* buf)
5400{
5401    u8_t keyIndex;
5402    u8_t da0;
5403
5404    zmw_get_wlan_dev(dev);
5405
5406    /* if need not check MIC, return NULL */
5407    if ( ((wd->sta.encryMode != ZM_TKIP)&&(wd->sta.encryMode != ZM_AES))||
5408         (wd->sta.wpaState < ZM_STA_WPA_STATE_PK_OK) )
5409    {
5410        return NULL;
5411    }
5412
5413    da0 = zmw_rx_buf_readb(dev, buf, ZM_WLAN_HEADER_A1_OFFSET);
5414
5415    if ((zmw_rx_buf_readb(dev, buf, 0) & 0x80) == 0x80)
5416        keyIndex = zmw_rx_buf_readb(dev, buf, ZM_WLAN_HEADER_IV_OFFSET+5); /* Qos Packet*/
5417    else
5418        keyIndex = zmw_rx_buf_readb(dev, buf, ZM_WLAN_HEADER_IV_OFFSET+3); /* normal Packet*/
5419    keyIndex = (keyIndex & 0xc0) >> 6;
5420
5421    return (&wd->sta.rxSeed[keyIndex]);
5422}
5423
5424void zfStaEnableSWEncryption(zdev_t *dev, u8_t value)
5425{
5426    zmw_get_wlan_dev(dev);
5427
5428    wd->sta.SWEncryptEnable = value;
5429    zfHpSWDecrypt(dev, 1);
5430    zfHpSWEncrypt(dev, 1);
5431}
5432
5433void zfStaDisableSWEncryption(zdev_t *dev)
5434{
5435    zmw_get_wlan_dev(dev);
5436
5437    wd->sta.SWEncryptEnable = 0;
5438    zfHpSWDecrypt(dev, 0);
5439    zfHpSWEncrypt(dev, 0);
5440}
5441
5442u16_t zfComputeBssInfoWeightValue(zdev_t *dev, u8_t isBMode, u8_t isHT, u8_t isHT40, u8_t signalStrength)
5443{
5444	u8_t  weightOfB           = 0;
5445	u8_t  weightOfAGBelowThr  = 0;
5446	u8_t  weightOfAGUpThr     = 15;
5447	u8_t  weightOfN20BelowThr = 15;
5448	u8_t  weightOfN20UpThr    = 30;
5449	u8_t  weightOfN40BelowThr = 16;
5450	u8_t  weightOfN40UpThr    = 32;
5451
5452    if( isBMode == 0 )
5453        return (signalStrength + weightOfB);    // pure b mode , do not add the weight value for this AP !
5454    else
5455    {
5456        if( isHT == 0 && isHT40 == 0 )
5457        { // a , g , b/g mode ! add the weight value 15 for this AP if it's signal strength is more than some value !
5458            if( signalStrength < 18 ) // -77 dBm
5459				return signalStrength + weightOfAGBelowThr;
5460			else
5461				return (signalStrength + weightOfAGUpThr);
5462        }
5463        else if( isHT == 1 && isHT40 == 0 )
5464        { // 80211n mode use 20MHz
5465            if( signalStrength < 23 ) // -72 dBm
5466                return (signalStrength + weightOfN20BelowThr);
5467            else
5468                return (signalStrength + weightOfN20UpThr);
5469        }
5470        else // isHT == 1 && isHT40 == 1
5471        { // 80211n mode use 40MHz
5472            if( signalStrength < 16 ) // -79 dBm
5473                return (signalStrength + weightOfN40BelowThr);
5474            else
5475                return (signalStrength + weightOfN40UpThr);
5476        }
5477    }
5478}
5479
5480u16_t zfStaAddIbssAdditionalIE(zdev_t* dev, zbuf_t* buf, u16_t offset)
5481{
5482	u16_t i;
5483
5484    zmw_get_wlan_dev(dev);
5485
5486    for (i=0; i<wd->sta.ibssAdditionalIESize; i++)
5487    {
5488        zmw_tx_buf_writeb(dev, buf, offset++, wd->sta.ibssAdditionalIE[i]);
5489    }
5490
5491    return offset;
5492}
5493