Linux-libre 2.6.32.58-gnu1
[librecmc/linux-libre.git] / drivers / staging / otus / 80211core / cmmap.c
1 /*
2  * Copyright (c) 2007-2008 Atheros Communications Inc.
3  *
4  * Permission to use, copy, modify, and/or distribute this software for any
5  * purpose with or without fee is hereby granted, provided that the above
6  * copyright notice and this permission notice appear in all copies.
7  *
8  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15  */
16 /*                                                                      */
17 /*  Module Name : mm.c                                                  */
18 /*                                                                      */
19 /*  Abstract                                                            */
20 /*      This module contains common functions for handle AP             */
21 /*      management frame.                                               */
22 /*                                                                      */
23 /*  NOTES                                                               */
24 /*      None                                                            */
25 /*                                                                      */
26 /************************************************************************/
27 #include "cprecomp.h"
28 #include "ratectrl.h"
29
30 extern const u8_t zcUpToAc[];
31
32 void zfMmApTimeTick(zdev_t* dev)
33 {
34     u32_t now;
35     zmw_get_wlan_dev(dev);
36
37     //zm_debug_msg1("wd->wlanMode : ", wd->wlanMode);
38     if (wd->wlanMode == ZM_MODE_AP)
39     {
40         /* => every 1.28 seconds */
41         /* AP : aging STA that does not active for wd->ap.staAgingTime    */
42         now = wd->tick & 0x7f;
43         if (now == 0x0)
44         {
45             zfApAgingSta(dev);
46         }
47         else if (now == 0x1f)
48         {
49             zfQueueAge(dev, wd->ap.uapsdQ, wd->tick, 10000);
50         }
51         /* AP : check (wd->ap.protectedObss) and (wd->ap.bStaAssociated)  */
52         /*      to enable NonErp and Protection mode                      */
53         else if (now == 0x3f)
54         {
55             //zfApProtctionMonitor(dev);
56         }
57     }
58 }
59
60 /************************************************************************/
61 /*                                                                      */
62 /*    FUNCTION DESCRIPTION                  zfApInitStaTbl              */
63 /*      Init AP's station table.                                        */
64 /*                                                                      */
65 /*    INPUTS                                                            */
66 /*      dev : device pointer                                            */
67 /*                                                                      */
68 /*    OUTPUTS                                                           */
69 /*      None                                                            */
70 /*                                                                      */
71 /*    AUTHOR                                                            */
72 /*      Stephen Chen        ZyDAS Technology Corporation    2005.10     */
73 /*                                                                      */
74 /************************************************************************/
75 void zfApInitStaTbl(zdev_t* dev)
76 {
77     u16_t i;
78
79     zmw_get_wlan_dev(dev);
80
81     for (i=0; i<ZM_MAX_STA_SUPPORT; i++)
82     {
83         wd->ap.staTable[i].valid = 0;
84         wd->ap.staTable[i].state = 0;
85         wd->ap.staTable[i].addr[0] = 0;
86         wd->ap.staTable[i].addr[1] = 0;
87         wd->ap.staTable[i].addr[2] = 0;
88         wd->ap.staTable[i].time = 0;
89         wd->ap.staTable[i].vap = 0;
90         wd->ap.staTable[i].encryMode = ZM_NO_WEP;
91     }
92     return;
93 }
94
95
96 /************************************************************************/
97 /*                                                                      */
98 /*    FUNCTION DESCRIPTION                  zfApFindSta                 */
99 /*      Find a STA in station table.                                    */
100 /*                                                                      */
101 /*    INPUTS                                                            */
102 /*      dev : device pointer                                            */
103 /*      addr : Target STA address                                       */
104 /*                                                                      */
105 /*    OUTPUTS                                                           */
106 /*      0xffff : fail                                                   */
107 /*      other : STA table index                                         */
108 /*                                                                      */
109 /*    AUTHOR                                                            */
110 /*      Stephen Chen        ZyDAS Technology Corporation    2005.10     */
111 /*                                                                      */
112 /************************************************************************/
113 u16_t zfApFindSta(zdev_t* dev, u16_t* addr)
114 {
115     u16_t i;
116
117     zmw_get_wlan_dev(dev);
118
119     for (i=0; i<ZM_MAX_STA_SUPPORT; i++)
120     {
121         if (wd->ap.staTable[i].valid == 1)
122         {
123             if ((wd->ap.staTable[i].addr[0] == addr[0])
124                     && (wd->ap.staTable[i].addr[1] == addr[1])
125                     && (wd->ap.staTable[i].addr[2] == addr[2]))
126             {
127                 return i;
128             }
129         }
130     }
131     return 0xffff;
132 }
133
134 u16_t zfApGetSTAInfo(zdev_t* dev, u16_t* addr, u16_t* state, u8_t* vap)
135 {
136     u16_t id;
137
138     zmw_get_wlan_dev(dev);
139
140     zmw_declare_for_critical_section();
141
142     zmw_enter_critical_section(dev);
143
144     if ((id = zfApFindSta(dev, addr)) != 0xffff)
145     {
146         *vap = wd->ap.staTable[id].vap;
147         *state = wd->ap.staTable[id++].state;
148     }
149
150     zmw_leave_critical_section(dev);
151
152     return id;
153 }
154
155
156 void zfApGetStaQosType(zdev_t* dev, u16_t* addr, u8_t* qosType)
157 {
158     u16_t id;
159
160     zmw_get_wlan_dev(dev);
161
162     zmw_declare_for_critical_section();
163
164     zmw_enter_critical_section(dev);
165
166     if ((id = zfApFindSta(dev, addr)) != 0xffff)
167     {
168         *qosType = wd->ap.staTable[id].qosType;
169     }
170     else
171     {
172         *qosType = 0;
173     }
174
175     zmw_leave_critical_section(dev);
176
177     return;
178 }
179
180 void zfApGetStaTxRateAndQosType(zdev_t* dev, u16_t* addr, u32_t* phyCtrl,
181                                 u8_t* qosType, u16_t* rcProbingFlag)
182 {
183     u16_t id;
184     u8_t rate;
185
186     zmw_get_wlan_dev(dev);
187
188     zmw_declare_for_critical_section();
189
190     zmw_enter_critical_section(dev);
191
192     if ((id = zfApFindSta(dev, addr)) != 0xffff)
193     {
194         rate = (u8_t)zfRateCtrlGetTxRate(dev, &wd->ap.staTable[id].rcCell, rcProbingFlag);
195 #ifdef ZM_AP_DEBUG
196         //rate = 15;
197 #endif
198         *phyCtrl = zcRateToPhyCtrl[rate];
199         *qosType = wd->ap.staTable[id].qosType;
200     }
201     else
202     {
203         if (wd->frequency < 3000)
204         {
205             /* CCK 1M */
206             //header[2] = 0x0f00;          //PHY control L
207             //header[3] = 0x0000;          //PHY control H
208             *phyCtrl = 0x00000F00;
209         }
210         else
211         {
212             /* CCK 6M */
213             //header[2] = 0x0f01;          //PHY control L
214             //header[3] = 0x000B;          //PHY control H
215             *phyCtrl = 0x000B0F01;
216         }
217         *qosType = 0;
218     }
219
220     zmw_leave_critical_section(dev);
221
222     zm_msg2_mm(ZM_LV_3, "PhyCtrl=", *phyCtrl);
223     return;
224 }
225
226 void zfApGetStaEncryType(zdev_t* dev, u16_t* addr, u8_t* encryType)
227 {
228     //struct zsWlanDev* wd = (struct zsWlanDev*) zmw_wlan_dev(dev);
229     u16_t id;
230
231     zmw_get_wlan_dev(dev);
232
233     zmw_declare_for_critical_section();
234
235     zmw_enter_critical_section(dev);
236
237     if ((id = zfApFindSta(dev, addr)) != 0xffff)
238     {
239         *encryType = wd->ap.staTable[id].encryMode;
240     }
241     else
242     {
243         *encryType = ZM_NO_WEP;
244     }
245
246     zmw_leave_critical_section(dev);
247
248     zm_msg2_mm(ZM_LV_3, "encyrType=", *encryType);
249     return;
250 }
251
252 void zfApGetStaWpaIv(zdev_t* dev, u16_t* addr, u16_t* iv16, u32_t* iv32)
253 {
254     //struct zsWlanDev* wd = (struct zsWlanDev*) zmw_wlan_dev(dev);
255     u16_t id;
256
257     zmw_get_wlan_dev(dev);
258
259     zmw_declare_for_critical_section();
260
261     zmw_enter_critical_section(dev);
262
263     if ((id = zfApFindSta(dev, addr)) != 0xffff)
264     {
265         *iv16 = wd->ap.staTable[id].iv16;
266         *iv32 = wd->ap.staTable[id].iv32;
267     }
268     else
269     {
270         *iv16 = 0;
271         *iv32 = 0;
272     }
273
274     zmw_leave_critical_section(dev);
275
276     zm_msg2_mm(ZM_LV_3, "iv16=", *iv16);
277     zm_msg2_mm(ZM_LV_3, "iv32=", *iv32);
278     return;
279 }
280
281 void zfApSetStaWpaIv(zdev_t* dev, u16_t* addr, u16_t iv16, u32_t iv32)
282 {
283     //struct zsWlanDev* wd = (struct zsWlanDev*) zmw_wlan_dev(dev);
284     u16_t id;
285
286     zmw_get_wlan_dev(dev);
287
288     zmw_declare_for_critical_section();
289
290     zmw_enter_critical_section(dev);
291
292     if ((id = zfApFindSta(dev, addr)) != 0xffff)
293     {
294         wd->ap.staTable[id].iv16 = iv16;
295         wd->ap.staTable[id].iv32 = iv32;
296     }
297
298     zmw_leave_critical_section(dev);
299
300     zm_msg2_mm(ZM_LV_3, "iv16=", iv16);
301     zm_msg2_mm(ZM_LV_3, "iv32=", iv32);
302     return;
303 }
304
305 void zfApClearStaKey(zdev_t* dev, u16_t* addr)
306 {
307     //struct zsWlanDev* wd = (struct zsWlanDev*) zmw_wlan_dev(dev);
308     u16_t bcAddr[3] = { 0xffff, 0xffff, 0xffff };
309     u16_t id;
310
311     zmw_get_wlan_dev(dev);
312
313     if (zfMemoryIsEqual((u8_t*)bcAddr, (u8_t*)addr, sizeof(bcAddr)) == TRUE)
314     {
315         /* Turn off group key information */
316     //    zfClearKey(dev, 0);
317     }
318     else
319     {
320         zmw_declare_for_critical_section();
321
322         zmw_enter_critical_section(dev);
323
324         if ((id = zfApFindSta(dev, addr)) != 0xffff)
325         {
326             /* Turn off STA's key information */
327             zfHpRemoveKey(dev, id+1);
328
329             /* Update STA's Encryption Type */
330             wd->ap.staTable[id].encryMode = ZM_NO_WEP;
331         }
332         else
333         {
334             zm_msg0_mm(ZM_LV_3, "Can't find STA address\n");
335         }
336         zmw_leave_critical_section(dev);
337     }
338 }
339
340 #ifdef ZM_ENABLE_CENC
341 void zfApGetStaCencIvAndKeyIdx(zdev_t* dev, u16_t* addr, u32_t *iv, u8_t *keyIdx)
342 {
343     //struct zsWlanDev* wd = (struct zsWlanDev*) zmw_wlan_dev(dev);
344     u16_t id;
345     zmw_get_wlan_dev(dev);
346     zmw_declare_for_critical_section();
347
348
349     zmw_enter_critical_section(dev);
350
351     if ((id = zfApFindSta(dev, addr)) != 0xffff)
352     {
353         *iv++ = wd->ap.staTable[id].txiv[0];
354         *iv++ = wd->ap.staTable[id].txiv[1];
355         *iv++ = wd->ap.staTable[id].txiv[2];
356         *iv = wd->ap.staTable[id].txiv[3];
357         *keyIdx = wd->ap.staTable[id].cencKeyIdx;
358     }
359     else
360     {
361         *iv++ = 0x5c365c37;
362         *iv++ = 0x5c365c36;
363         *iv++ = 0x5c365c36;
364         *iv = 0x5c365c36;
365         *keyIdx = 0;
366     }
367
368     zmw_leave_critical_section(dev);
369     return;
370 }
371
372 void zfApSetStaCencIv(zdev_t* dev, u16_t* addr, u32_t *iv)
373 {
374     //struct zsWlanDev* wd = (struct zsWlanDev*) zmw_wlan_dev(dev);
375     u16_t id;
376     zmw_get_wlan_dev(dev);
377     zmw_declare_for_critical_section();
378
379
380     zmw_enter_critical_section(dev);
381
382     if ((id = zfApFindSta(dev, addr)) != 0xffff)
383     {
384         wd->ap.staTable[id].txiv[0] = *iv++;
385         wd->ap.staTable[id].txiv[1] = *iv++;
386         wd->ap.staTable[id].txiv[2] = *iv++;
387         wd->ap.staTable[id].txiv[3] = *iv;
388     }
389
390     zmw_leave_critical_section(dev);
391
392     return;
393 }
394 #endif //ZM_ENABLE_CENC
395
396
397 /************************************************************************/
398 /*                                                                      */
399 /*    FUNCTION DESCRIPTION                  zfApFlushBufferedPsFrame    */
400 /*      Free buffered PS frames.                                        */
401 /*                                                                      */
402 /*    INPUTS                                                            */
403 /*      dev : device pointer                                            */
404 /*                                                                      */
405 /*    OUTPUTS                                                           */
406 /*      None                                                            */
407 /*                                                                      */
408 /*    AUTHOR                                                            */
409 /*      Stephen Chen        Atheros Communications, INC.    2007.1      */
410 /*                                                                      */
411 /************************************************************************/
412 void zfApFlushBufferedPsFrame(zdev_t* dev)
413 {
414     u16_t emptyFlag;
415     u16_t freeCount;
416     u16_t vap;
417     zbuf_t* psBuf = NULL;
418     zmw_get_wlan_dev(dev);
419     zmw_declare_for_critical_section();
420
421     freeCount = 0;
422     emptyFlag = 0;
423     while (1)
424     {
425         psBuf = NULL;
426         zmw_enter_critical_section(dev);
427         if (wd->ap.uniHead != wd->ap.uniTail)
428         {
429             psBuf = wd->ap.uniArray[wd->ap.uniHead];
430             wd->ap.uniHead = (wd->ap.uniHead + 1) & (ZM_UNI_ARRAY_SIZE - 1);
431         }
432         else
433         {
434             emptyFlag = 1;
435         }
436         zmw_leave_critical_section(dev);
437
438         if (psBuf != NULL)
439         {
440             zfwBufFree(dev, psBuf, ZM_ERR_FLUSH_PS_QUEUE);
441         }
442         zm_assert(freeCount++ < (ZM_UNI_ARRAY_SIZE*2));
443
444         if (emptyFlag != 0)
445         {
446             break;
447         }
448     }
449
450     for (vap=0; vap<ZM_MAX_AP_SUPPORT; vap++)
451     {
452         freeCount = 0;
453         emptyFlag = 0;
454         while (1)
455         {
456             psBuf = NULL;
457             zmw_enter_critical_section(dev);
458             if (wd->ap.bcmcHead[vap] != wd->ap.bcmcTail[vap])
459             {
460                 psBuf = wd->ap.bcmcArray[vap][wd->ap.bcmcHead[vap]];
461                 wd->ap.bcmcHead[vap] = (wd->ap.bcmcHead[vap] + 1)
462                         & (ZM_BCMC_ARRAY_SIZE - 1);
463             }
464             else
465             {
466                 emptyFlag = 1;
467             }
468             zmw_leave_critical_section(dev);
469
470             if (psBuf != NULL)
471             {
472                 zfwBufFree(dev, psBuf, ZM_ERR_FLUSH_PS_QUEUE);
473             }
474             zm_assert(freeCount++ < (ZM_BCMC_ARRAY_SIZE*2));
475
476             if (emptyFlag != 0)
477             {
478                 break;
479             }
480         }
481     }
482     return;
483 }
484
485
486 u16_t zfApBufferPsFrame(zdev_t* dev, zbuf_t* buf, u16_t port)
487 {
488     u16_t id;
489     u16_t addr[3];
490     u16_t vap = 0;
491     u8_t up;
492     u16_t fragOff;
493     u8_t ac;
494     u16_t ret;
495
496     zmw_get_wlan_dev(dev);
497
498     zmw_declare_for_critical_section();
499
500     if (port < ZM_MAX_AP_SUPPORT)
501     {
502         vap = port;
503     }
504
505     addr[0] = zmw_rx_buf_readh(dev, buf, 0);
506     addr[1] = zmw_rx_buf_readh(dev, buf, 2);
507     addr[2] = zmw_rx_buf_readh(dev, buf, 4);
508
509     if ((addr[0] & 0x1) == 0x1)
510     {
511         if (wd->ap.staPowerSaving > 0)
512         {
513             zmw_enter_critical_section(dev);
514
515             /* Buffer this BC or MC frame */
516             if (((wd->ap.bcmcTail[vap]+1)&(ZM_BCMC_ARRAY_SIZE-1))
517                     != wd->ap.bcmcHead[vap])
518             {
519                 wd->ap.bcmcArray[vap][wd->ap.bcmcTail[vap]++] = buf;
520                 wd->ap.bcmcTail[vap] &= (ZM_BCMC_ARRAY_SIZE-1);
521                 zmw_leave_critical_section(dev);
522
523                 zm_msg0_tx(ZM_LV_0, "Buffer BCMC");
524             }
525             else
526             {
527                 /* bcmcArray full */
528                 zmw_leave_critical_section(dev);
529
530                 zm_msg0_tx(ZM_LV_0, "BCMC buffer full");
531
532                 /* free buffer according to buffer type */
533                 zfwBufFree(dev, buf, ZM_ERR_BCMC_PS_BUFFER_UNAVAILABLE);
534             }
535             return 1;
536         }
537     }
538     else
539     {
540         zmw_enter_critical_section(dev);
541
542         if ((id = zfApFindSta(dev, addr)) != 0xffff)
543         {
544             if (wd->ap.staTable[id].psMode == 1)
545             {
546
547                 zfTxGetIpTosAndFrag(dev, buf, &up, &fragOff);
548                 ac = zcUpToAc[up&0x7] & 0x3;
549
550                 if ((wd->ap.staTable[id].qosType == 1) &&
551                         ((wd->ap.staTable[id].qosInfo & (0x8>>ac)) != 0))
552                 {
553                     ret = zfQueuePutNcs(dev, wd->ap.uapsdQ, buf, wd->tick);
554                     zmw_leave_critical_section(dev);
555                     if (ret != ZM_SUCCESS)
556                     {
557                         zfwBufFree(dev, buf, ZM_ERR_AP_UAPSD_QUEUE_FULL);
558                     }
559                 }
560                 else
561                 {
562                 /* Buffer this unicast frame */
563                 if (((wd->ap.uniTail+1)&(ZM_UNI_ARRAY_SIZE-1))
564                         != wd->ap.uniHead)
565                 {
566                     wd->ap.uniArray[wd->ap.uniTail++] = buf;
567                     wd->ap.uniTail &= (ZM_UNI_ARRAY_SIZE-1);
568                     zmw_leave_critical_section(dev);
569                     zm_msg0_tx(ZM_LV_0, "Buffer UNI");
570
571                 }
572                 else
573                 {
574                     /* uniArray full */
575                     zmw_leave_critical_section(dev);
576                     zm_msg0_tx(ZM_LV_0, "UNI buffer full");
577                     /* free buffer according to buffer type */
578                     zfwBufFree(dev, buf, ZM_ERR_UNI_PS_BUFFER_UNAVAILABLE);
579                 }
580                 }
581                 return 1;
582             } /* if (wd->ap.staTable[id++].psMode == 1) */
583         } /* if ((id = zfApFindSta(dev, addr)) != 0xffff) */
584         zmw_leave_critical_section(dev);
585     }
586
587     return 0;
588 }
589
590 u16_t zfApGetSTAInfoAndUpdatePs(zdev_t* dev, u16_t* addr, u16_t* state,
591                                 u8_t* vap, u16_t psMode, u8_t* uapsdTrig)
592 {
593     u16_t id;
594     u8_t uapsdStaAwake = 0;
595
596     zmw_get_wlan_dev(dev);
597
598     zmw_declare_for_critical_section();
599
600     zmw_enter_critical_section(dev);
601
602 #ifdef ZM_AP_DEBUG
603     //psMode=0;
604 #endif
605
606     if ((id = zfApFindSta(dev, addr)) != 0xffff)
607     {
608         if (psMode != 0)
609         {
610             zm_msg0_mm(ZM_LV_0, "psMode = 1");
611             if (wd->ap.staTable[id].psMode == 0)
612             {
613                 wd->ap.staPowerSaving++;
614             }
615             else
616             {
617                 if (wd->ap.staTable[id].qosType == 1)
618                 {
619                     zm_msg0_mm(ZM_LV_0, "UAPSD trigger");
620                     *uapsdTrig = wd->ap.staTable[id].qosInfo;
621                 }
622             }
623         }
624         else
625         {
626             if (wd->ap.staTable[id].psMode != 0)
627             {
628                 wd->ap.staPowerSaving--;
629                 if ((wd->ap.staTable[id].qosType == 1) && ((wd->ap.staTable[id].qosInfo&0xf)!=0))
630                 {
631                     uapsdStaAwake = 1;
632                 }
633             }
634         }
635
636         wd->ap.staTable[id].psMode = (u8_t) psMode;
637         wd->ap.staTable[id].time = wd->tick;
638         *vap = wd->ap.staTable[id].vap;
639         *state = wd->ap.staTable[id++].state;
640     }
641
642     zmw_leave_critical_section(dev);
643
644     if (uapsdStaAwake == 1)
645     {
646         zbuf_t* psBuf;
647         u8_t mb;
648
649         while (1)
650         {
651             if ((psBuf = zfQueueGetWithMac(dev, wd->ap.uapsdQ, (u8_t*)addr, &mb)) != NULL)
652             {
653                 zfTxSendEth(dev, psBuf, 0, ZM_EXTERNAL_ALLOC_BUF, 0);
654             }
655             else
656             {
657                 break;
658             }
659         }
660     }
661
662     return id;
663 }
664
665 /************************************************************************/
666 /*                                                                      */
667 /*    FUNCTION DESCRIPTION                  zfApGetNewSta               */
668 /*      Get a new STA from station table.                               */
669 /*                                                                      */
670 /*    INPUTS                                                            */
671 /*      dev : device pointer                                            */
672 /*                                                                      */
673 /*    OUTPUTS                                                           */
674 /*      0xffff : fail                                                   */
675 /*      other : STA table index                                         */
676 /*                                                                      */
677 /*    AUTHOR                                                            */
678 /*      Stephen Chen        ZyDAS Technology Corporation    2005.10     */
679 /*                                                                      */
680 /************************************************************************/
681 u16_t zfApGetNewSta(zdev_t* dev)
682 {
683     u16_t i;
684
685     zmw_get_wlan_dev(dev);
686
687     for (i=0; i<ZM_MAX_STA_SUPPORT; i++)
688     {
689         if (wd->ap.staTable[i].valid == 0)
690         {
691             zm_msg2_mm(ZM_LV_0, "zfApGetNewSta=", i);
692             return i;
693         }
694     }
695     return 0xffff;
696 }
697
698
699 /************************************************************************/
700 /*                                                                      */
701 /*    FUNCTION DESCRIPTION                  zfApAddSta                  */
702 /*      Add a STA to station table.                                     */
703 /*                                                                      */
704 /*    INPUTS                                                            */
705 /*      dev : device pointer                                            */
706 /*      addr : STA MAC address                                          */
707 /*      state : STA state                                               */
708 /*      apId : Virtual AP ID                                            */
709 /*      type : 0=>11b, 1=>11g                                           */
710 /*                                                                      */
711 /*    OUTPUTS                                                           */
712 /*      0xffff : fail                                                   */
713 /*      Other : index                                                   */
714 /*                                                                      */
715 /*    AUTHOR                                                            */
716 /*      Stephen Chen        ZyDAS Technology Corporation    2005.10     */
717 /*                                                                      */
718 /************************************************************************/
719 u16_t zfApAddSta(zdev_t* dev, u16_t* addr, u16_t state, u16_t apId, u8_t type,
720                  u8_t qosType, u8_t qosInfo)
721 {
722     u16_t index;
723     u16_t i;
724
725     zmw_get_wlan_dev(dev);
726
727     zmw_declare_for_critical_section();
728
729     zm_msg1_mm(ZM_LV_0, "STA type=", type);
730
731     zmw_enter_critical_section(dev);
732
733     if ((index = zfApFindSta(dev, addr)) != 0xffff)
734     {
735         zm_msg0_mm(ZM_LV_2, "found");
736         /* Update STA state */
737         if ((state == ZM_STATE_AUTH) || (state == ZM_STATE_PREAUTH))
738         {
739             wd->ap.staTable[index].state = state;
740             wd->ap.staTable[index].time = wd->tick;
741             wd->ap.staTable[index].vap = (u8_t)apId;
742         }
743         else if (state == ZM_STATE_ASOC)
744         {
745             if ((wd->ap.staTable[index].state == ZM_STATE_AUTH))
746                     //&& (wd->ap.staTable[index].vap == apId))
747             {
748                 wd->ap.staTable[index].state = state;
749                 wd->ap.staTable[index].time = wd->tick;
750                 wd->ap.staTable[index].qosType = qosType;
751                 wd->ap.staTable[index].vap = (u8_t)apId;
752                 wd->ap.staTable[index].staType = type;
753                 wd->ap.staTable[index].qosInfo = qosInfo;
754
755                 if (wd->frequency < 3000)
756                 {
757                     /* Init 11b/g */
758                     zfRateCtrlInitCell(dev, &wd->ap.staTable[index].rcCell, type, 1, 1);
759                 }
760                 else
761                 {
762                     /* Init 11a */
763                     zfRateCtrlInitCell(dev, &wd->ap.staTable[index].rcCell, type, 0, 1);
764                 }
765
766                 if (wd->zfcbApConnectNotify != NULL)
767                 {
768                     wd->zfcbApConnectNotify(dev, (u8_t*)addr, apId);
769                 }
770             }
771             else
772             {
773                 index = 0xffff;
774             }
775         }
776     }
777     else
778     {
779         zm_msg0_mm(ZM_LV_2, "Not found");
780         if ((state == ZM_STATE_AUTH) || (state == ZM_STATE_PREAUTH))
781         {
782             /* Get a new STA and update state */
783             index = zfApGetNewSta(dev);
784             zm_msg2_mm(ZM_LV_1, "new STA index=", index);
785
786             if (index != 0xffff)
787             {
788                 for (i=0; i<3; i++)
789                 {
790                     wd->ap.staTable[index].addr[i] = addr[i];
791                 }
792                 wd->ap.staTable[index].state = state;
793                 wd->ap.staTable[index].valid = 1;
794                 wd->ap.staTable[index].time = wd->tick;
795                 wd->ap.staTable[index].vap = (u8_t)apId;
796                 wd->ap.staTable[index].encryMode = ZM_NO_WEP;
797             }
798         }
799     }
800
801     zmw_leave_critical_section(dev);
802
803     return index;
804 }
805
806
807 /************************************************************************/
808 /*                                                                      */
809 /*    FUNCTION DESCRIPTION                  zfApAgingSta                */
810 /*      Aging STA in station table.                                     */
811 /*                                                                      */
812 /*    INPUTS                                                            */
813 /*      dev : device pointer                                            */
814 /*                                                                      */
815 /*    OUTPUTS                                                           */
816 /*      number of 11b STA in STA table                                  */
817 /*                                                                      */
818 /*    AUTHOR                                                            */
819 /*      Stephen Chen        ZyDAS Technology Corporation    2005.10     */
820 /*                                                                      */
821 /************************************************************************/
822 void zfApAgingSta(zdev_t* dev)
823 {
824     u16_t i;
825     u32_t deltaMs;
826     u16_t addr[3];
827     u16_t txFlag;
828     u16_t psStaCount = 0;
829
830     zmw_get_wlan_dev(dev);
831
832     zmw_declare_for_critical_section();
833
834     wd->ap.gStaAssociated = wd->ap.bStaAssociated = 0;
835
836     for (i=0; i<ZM_MAX_STA_SUPPORT; i++)
837     {
838         txFlag = 0;
839         zmw_enter_critical_section(dev);
840         if (wd->ap.staTable[i].valid == 1)
841         {
842             addr[0] = wd->ap.staTable[i].addr[0];
843             addr[1] = wd->ap.staTable[i].addr[1];
844             addr[2] = wd->ap.staTable[i].addr[2];
845             /* millisecond */
846             deltaMs = (u32_t)((u32_t)wd->tick-(u32_t)wd->ap.staTable[i].time)
847                       * ZM_MS_PER_TICK;
848
849             /* preauth */
850             if ((wd->ap.staTable[i].state == ZM_STATE_PREAUTH)
851                     && (deltaMs > ZM_PREAUTH_TIMEOUT_MS))
852             {
853                 /* Aging STA */
854                 wd->ap.staTable[i].valid = 0;
855                 wd->ap.authSharing = 0;
856                 txFlag = 1;
857             }
858
859             /* auth */
860             if ((wd->ap.staTable[i].state == ZM_STATE_AUTH)
861                     && (deltaMs > ZM_AUTH_TIMEOUT_MS))
862             {
863                 /* Aging STA */
864                 wd->ap.staTable[i].valid = 0;
865                 txFlag = 1;
866             }
867
868             /* asoc */
869             if (wd->ap.staTable[i].state == ZM_STATE_ASOC)
870             {
871                 if (wd->ap.staTable[i].psMode != 0)
872                 {
873                     psStaCount++;
874                 }
875
876                 if (deltaMs > ((u32_t)wd->ap.staAgingTimeSec<<10))
877                 {
878                     /* Aging STA */
879                     zm_msg1_mm(ZM_LV_0, "Age STA index=", i);
880                     wd->ap.staTable[i].valid = 0;
881                     txFlag = 1;
882                 }
883                 else if (deltaMs > ((u32_t)wd->ap.staProbingTimeSec<<10))
884                 {
885                     if (wd->ap.staTable[i].psMode == 0)
886                     {
887                         /* Probing non-PS STA */
888                         zm_msg1_mm(ZM_LV_0, "Probing STA index=", i);
889                         wd->ap.staTable[i].time +=
890                                 (wd->ap.staProbingTimeSec * ZM_TICK_PER_SECOND);
891                         txFlag = 2;
892                     }
893                 }
894             }
895
896
897         }
898         zmw_leave_critical_section(dev);
899
900         if (txFlag == 1)
901         {
902             /* Send deauthentication management frame */
903             zfSendMmFrame(dev, ZM_WLAN_FRAME_TYPE_DEAUTH, addr, 4, 0, 0);
904         }
905         else if (txFlag == 2)
906         {
907             zfSendMmFrame(dev, ZM_WLAN_DATA_FRAME, addr, 0, 0, 0);
908         }
909
910     }
911
912     wd->ap.staPowerSaving = psStaCount;
913
914     return;
915 }
916
917 void zfApProtctionMonitor(zdev_t* dev)
918 {
919     zmw_get_wlan_dev(dev);
920
921     /* 11b STA associated => nonErp, Protect */
922     if (wd->ap.bStaAssociated > 0)
923     {
924         /* Enable NonErp bit in information element */
925         wd->erpElement = ZM_WLAN_NON_ERP_PRESENT_BIT
926                          | ZM_WLAN_USE_PROTECTION_BIT;
927
928         /* Enable protection mode */
929         zfApSetProtectionMode(dev, 1);
930
931     }
932     /* 11b STA not associated, protection OBSS present => Protect */
933     else if (wd->ap.protectedObss > 2) //Threshold
934     {
935         if (wd->disableSelfCts == 0)
936         {
937             /* Disable NonErp bit in information element */
938             wd->erpElement = ZM_WLAN_USE_PROTECTION_BIT;
939
940             /* Enable protection mode */
941             zfApSetProtectionMode(dev, 1);
942         }
943     }
944     else
945     {
946         /* Disable NonErp bit in information element */
947         wd->erpElement = 0;
948
949         /* Disable protection mode */
950         zfApSetProtectionMode(dev, 0);
951     }
952     wd->ap.protectedObss = 0;
953 }
954
955
956 void zfApProcessBeacon(zdev_t* dev, zbuf_t* buf)
957 {
958     u16_t offset;
959     u8_t ch;
960
961     zmw_get_wlan_dev(dev);
962
963     zm_msg0_mm(ZM_LV_3, "Rx beacon");
964
965     /* update Non-ERP flag(wd->ap.nonErpObss) */
966     if ((offset = zfFindElement(dev, buf, ZM_WLAN_EID_ERP)) == 0xffff)
967     {
968         /* 11b OBSS */
969         wd->ap.protectedObss++;
970         return;
971     }
972
973     ch = zmw_rx_buf_readb(dev, buf, offset+2);
974     if ((ch & ZM_WLAN_USE_PROTECTION_BIT) == ZM_WLAN_USE_PROTECTION_BIT)
975     {
976         /* Protected OBSS */
977         wd->ap.protectedObss = 1;
978     }
979
980     return;
981 }
982
983
984 /************************************************************************/
985 /*                                                                      */
986 /*    FUNCTION DESCRIPTION                  zfProcessAuth               */
987 /*      Process authenticate management frame.                          */
988 /*                                                                      */
989 /*    INPUTS                                                            */
990 /*      dev : device pointer                                            */
991 /*      buf : auth frame buffer                                         */
992 /*                                                                      */
993 /*    OUTPUTS                                                           */
994 /*      none                                                            */
995 /*                                                                      */
996 /*    AUTHOR                                                            */
997 /*      Stephen Chen        ZyDAS Technology Corporation    2005.10     */
998 /*                                                                      */
999 /************************************************************************/
1000 /* Note : AP allows one authenticating STA at a time, does not          */
1001 /*        support multiple authentication process. Make sure            */
1002 /*        authentication state machine will not be blocked due          */
1003 /*        to incompleted authentication handshake.                      */
1004 void zfApProcessAuth(zdev_t* dev, zbuf_t* buf, u16_t* src, u16_t apId)
1005 {
1006     u16_t algo, seq, status;
1007     u8_t authSharing;
1008     u16_t ret;
1009     u16_t i;
1010     u8_t challengePassed = 0;
1011     u8_t frameCtrl;
1012     u32_t retAlgoSeq;
1013     u32_t retStatus;
1014     zmw_get_wlan_dev(dev);
1015     zmw_declare_for_critical_section();
1016
1017
1018     frameCtrl = zmw_rx_buf_readb(dev, buf, 1);
1019     /* AP : Auth share 3 */
1020     /* shift for WEP IV */
1021     if ((frameCtrl & 0x40) != 0)
1022     {
1023         algo = zmw_rx_buf_readh(dev, buf, 28);
1024         seq = zmw_rx_buf_readh(dev, buf, 30);
1025         status = zmw_rx_buf_readh(dev, buf, 32);
1026     }
1027     else
1028     {
1029         algo = zmw_rx_buf_readh(dev, buf, 24);
1030         seq = zmw_rx_buf_readh(dev, buf, 26);
1031         status = zmw_rx_buf_readh(dev, buf, 28);
1032     }
1033
1034     zm_msg2_mm(ZM_LV_0, "Rx Auth, seq=", seq);
1035
1036     /* Set default to authentication algorithm not support */
1037     retAlgoSeq = 0x20000 | algo;
1038     retStatus = 13; /* authentication algorithm not support */
1039
1040     /* AP : Auth open 1 */
1041     if (algo == 0)
1042     {
1043         if (wd->ap.authAlgo[apId] == 0)
1044         {
1045             retAlgoSeq = 0x20000;
1046             if (seq == 1)
1047             {
1048                 /* AP : update STA to auth */
1049                 if ((ret = zfApAddSta(dev, src, ZM_STATE_AUTH, apId, 0, 0, 0)) != 0xffff)
1050                 {
1051                     /* AP : call zfwAuthNotify() for host to judge */
1052                     //zfwAuthNotify(dev, src);
1053
1054                     /* AP : response Auth seq=2, success */
1055                     retStatus = 0;
1056
1057                 }
1058                 else
1059                 {
1060                     /* AP : response Auth seq=2, unspecific error */
1061                     retStatus = 1;
1062                 }
1063             }
1064             else
1065             {
1066                 /* AP : response Auth seq=2, sequence number out of expected */
1067                 retStatus = 14;
1068             }
1069         }
1070     }
1071     /* AP : Auth share 1 */
1072     else if (algo == 1)
1073     {
1074         if (wd->ap.authAlgo[apId] == 1)
1075         {
1076             if (seq == 1)
1077             {
1078                 retAlgoSeq = 0x20001;
1079
1080                 /* critical section */
1081                 zmw_enter_critical_section(dev);
1082                 if (wd->ap.authSharing == 1)
1083                 {
1084                     authSharing = 1;
1085                 }
1086                 else
1087                 {
1088                     authSharing = 0;
1089                     wd->ap.authSharing = 1;
1090                 }
1091                 /* end of critical section */
1092                 zmw_leave_critical_section(dev);
1093
1094                 if (authSharing == 1)
1095                 {
1096                     /* AP : response Auth seq=2, status = fail */
1097                     retStatus = 1;
1098                 }
1099                 else
1100                 {
1101                     /* AP : update STA to preauth */
1102                     zfApAddSta(dev, src, ZM_STATE_PREAUTH, apId, 0, 0, 0);
1103
1104                     /* AP : call zfwAuthNotify() for host to judge */
1105                     //zfwAuthNotify(dev, src);
1106
1107                     /* AP : response Auth seq=2 */
1108                     retStatus = 0;
1109                 }
1110             }
1111             else if (seq == 3)
1112             {
1113                 retAlgoSeq = 0x40001;
1114
1115                 if (wd->ap.authSharing == 1)
1116                 {
1117                     /* check challenge text */
1118                     if (zmw_buf_readh(dev, buf, 30+4) == 0x8010)
1119                     {
1120                         for (i=0; i<128; i++)
1121                         {
1122                             if (wd->ap.challengeText[i]
1123                                         != zmw_buf_readb(dev, buf, 32+i+4))
1124                             {
1125                                 break;
1126                             }
1127                         }
1128                         if (i == 128)
1129                         {
1130                             challengePassed = 1;
1131                         }
1132                     }
1133
1134                     if (challengePassed == 1)
1135                     {
1136                         /* AP : update STA to auth */
1137                         zfApAddSta(dev, src, ZM_STATE_AUTH, apId, 0, 0, 0);
1138
1139                         /* AP : response Auth seq=2 */
1140                         retStatus = 0;
1141                     }
1142                     else
1143                     {
1144                         /* AP : response Auth seq=2, challenge failure */
1145                         retStatus = 15;
1146
1147                         /* TODO : delete STA */
1148                     }
1149
1150                     wd->ap.authSharing = 0;
1151                 }
1152             }
1153             else
1154             {
1155                 retAlgoSeq = 0x40001;
1156                 retStatus = 14;
1157             }
1158         }
1159     }
1160
1161     zfSendMmFrame(dev, ZM_WLAN_FRAME_TYPE_AUTH, src, retAlgoSeq,
1162             retStatus, apId);
1163     return;
1164 }
1165
1166 void zfApProcessAsocReq(zdev_t* dev, zbuf_t* buf, u16_t* src, u16_t apId)
1167 {
1168     u16_t aid = 0xffff;
1169     u8_t frameType;
1170     u16_t offset;
1171     u8_t staType = 0;
1172     u8_t qosType = 0;
1173     u8_t qosInfo = 0;
1174     u8_t tmp;
1175     u16_t i, j, k;
1176     u16_t encMode = 0;
1177
1178     zmw_get_wlan_dev(dev);
1179     /* AP : check SSID */
1180     if ((offset = zfFindElement(dev, buf, ZM_WLAN_EID_SSID)) != 0xffff)
1181     {
1182         k = 0;
1183         for (j = 0; j < wd->ap.vapNumber; j++)
1184         {
1185             if ((tmp = zmw_buf_readb(dev, buf, offset+1))
1186                         != wd->ap.ssidLen[j])
1187             {
1188                 k++;
1189             }
1190         }
1191         if (k == wd->ap.vapNumber)
1192         {
1193             goto zlDeauth;
1194         }
1195
1196         k = 0;
1197         for (j = 0; j < wd->ap.vapNumber; j++)
1198         {
1199             for (i=0; i<wd->ap.ssidLen[j]; i++)
1200             {
1201                 if ((tmp = zmw_buf_readb(dev, buf, offset+2+i))
1202                         != wd->ap.ssid[j][i])
1203                 {
1204                     break;
1205                 }
1206             }
1207             if (i == wd->ap.ssidLen[j])
1208             {
1209                 apId = j;
1210             }
1211             else
1212             {
1213                 k++;
1214             }
1215         }
1216         if (k == wd->ap.vapNumber)
1217         {
1218             goto zlDeauth;
1219         }
1220     }
1221
1222     /* TODO : check capability */
1223
1224     /* AP : check support rate */
1225     if ((offset = zfFindElement(dev, buf, ZM_WLAN_EID_EXTENDED_RATE)) != 0xffff)
1226     {
1227         /* 11g STA */
1228         staType = 1;
1229     }
1230     //CWYang(+)
1231     if ((offset = zfFindElement(dev, buf, ZM_WLAN_EID_HT_CAPABILITY)) != 0xffff)
1232     {
1233         /* 11n STA */
1234         staType = 2;
1235     }
1236
1237     /* TODO : do not allow 11b STA to associated in Pure G mode */
1238     if (wd->ap.wlanType[apId] == ZM_WLAN_TYPE_PURE_G && staType == 0)
1239     {
1240         zfSendMmFrame(dev, ZM_WLAN_FRAME_TYPE_DEAUTH, src, 3, 0, 0);
1241         return;
1242     }
1243
1244     /* In pure B mode, we set G STA into B mode */
1245     if (wd->ap.wlanType[apId] == ZM_WLAN_TYPE_PURE_B && staType == 1)
1246     {
1247         staType = 0;
1248     }
1249
1250     /* AP : check 11i and WPA */
1251     /* AP : check 11h */
1252
1253     /* AP : check WME */
1254     if ((offset = zfFindWifiElement(dev, buf, 2, 0)) != 0xffff)
1255     {
1256         /* WME STA */
1257         qosType = 1;
1258         zm_msg0_mm(ZM_LV_0, "WME STA");
1259
1260         if (wd->ap.uapsdEnabled != 0)
1261         {
1262             qosInfo = zmw_rx_buf_readb(dev, buf, offset+8);
1263         }
1264     }
1265
1266     if (wd->ap.wpaSupport[apId] == 1)
1267     {
1268         if ( (offset = zfFindElement(dev, buf, ZM_WLAN_EID_WPA_IE)) != 0xffff )
1269         {
1270             /* get WPA IE */
1271             u8_t length = zmw_rx_buf_readb(dev, buf, offset+1);
1272             if (length+2 < ZM_MAX_WPAIE_SIZE)
1273             {
1274                 zfCopyFromRxBuffer(dev, buf, wd->ap.stawpaIe[apId], offset, length+2);
1275                 wd->ap.stawpaLen[apId] = length+2;
1276                 encMode = 1;
1277
1278
1279                 zm_msg1_mm(ZM_LV_0, "WPA Mode zfwAsocNotify, apId=", apId);
1280
1281                 /* AP : Call zfwAsocNotify() */
1282                 if (wd->zfcbAsocNotify != NULL)
1283                 {
1284                     wd->zfcbAsocNotify(dev, src, wd->ap.stawpaIe[apId], wd->ap.stawpaLen[apId], apId);
1285                 }
1286             }
1287             else
1288             {
1289                 goto zlDeauth;
1290             }
1291         }
1292         else if ( (offset = zfFindElement(dev, buf, ZM_WLAN_EID_RSN_IE)) != 0xffff )
1293         {
1294             /* get RSN IE */
1295             u8_t length = zmw_rx_buf_readb(dev, buf, offset+1);
1296             if (length+2 < ZM_MAX_WPAIE_SIZE)
1297             {
1298                 zfCopyFromRxBuffer(dev, buf, wd->ap.stawpaIe[apId], offset, length+2);
1299                 wd->ap.stawpaLen[apId] = length+2;
1300                 encMode = 1;
1301
1302                 zm_msg1_mm(ZM_LV_0, "RSN Mode zfwAsocNotify, apId=", apId);
1303
1304                 /* AP : Call zfwAsocNotify() */
1305                 if (wd->zfcbAsocNotify != NULL)
1306                 {
1307                     wd->zfcbAsocNotify(dev, src, wd->ap.stawpaIe[apId], wd->ap.stawpaLen[apId], apId);
1308                 }
1309             }
1310             else
1311             {
1312                 goto zlDeauth;
1313             }
1314         }
1315 #ifdef ZM_ENABLE_CENC
1316         else if ( (offset = zfFindElement(dev, buf, ZM_WLAN_EID_CENC_IE)) != 0xffff )
1317         {
1318             /* get CENC IE */
1319             u8_t length = zmw_rx_buf_readb(dev, buf, offset+1);
1320
1321             if (length+2 < ZM_MAX_WPAIE_SIZE)
1322             {
1323                 zfCopyFromRxBuffer(dev, buf, wd->ap.stawpaIe[apId], offset, length+2);
1324                 wd->ap.stawpaLen[apId] = length+2;
1325                 encMode = 1;
1326
1327                 zm_msg1_mm(ZM_LV_0, "CENC Mode zfwAsocNotify, apId=", apId);
1328
1329                 /* AP : Call zfwAsocNotify() */
1330                 if (wd->zfcbCencAsocNotify != NULL)
1331                 {
1332                     wd->zfcbCencAsocNotify(dev, src, wd->ap.stawpaIe[apId],
1333                             wd->ap.stawpaLen[apId], apId);
1334                 }
1335             }
1336             else
1337             {
1338                 goto zlDeauth;
1339             }
1340         }
1341 #endif //ZM_ENABLE_CENC
1342         else
1343         {   /* ap is encryption but sta has no wpa/rsn ie */
1344             zfSendMmFrame(dev, ZM_WLAN_FRAME_TYPE_DEAUTH, src, 6, 0, 0);
1345             return;
1346         }
1347     }
1348     /* sta has wpa/rsn ie but ap is no encryption */
1349     if ((wd->ap.wpaSupport[apId] == 0) && (encMode == 1))
1350     {
1351         zfSendMmFrame(dev, ZM_WLAN_FRAME_TYPE_DEAUTH, src, 6, 0, 0);
1352         return;
1353     }
1354
1355     /* AP : update STA to asoc */
1356     aid = zfApAddSta(dev, src, ZM_STATE_ASOC, apId, staType, qosType, qosInfo);
1357
1358     zfApStoreAsocReqIe(dev, buf, aid);
1359
1360 zlDeauth:
1361     /* AP : send asoc rsp2 */
1362     if (aid != 0xffff)
1363     {
1364         frameType = zmw_rx_buf_readb(dev, buf, 0);
1365
1366         if (frameType == ZM_WLAN_FRAME_TYPE_ASOCREQ)
1367         {
1368             zfSendMmFrame(dev, ZM_WLAN_FRAME_TYPE_ASOCRSP, src, 0, aid+1, apId);
1369         }
1370         else
1371         {
1372             zfSendMmFrame(dev, ZM_WLAN_FRAME_TYPE_REASOCRSP, src, 0, aid+1, apId);
1373         }
1374     }
1375     else
1376     {
1377         /* TODO : send deauthentication */
1378         zfSendMmFrame(dev, ZM_WLAN_FRAME_TYPE_DEAUTH, src, 6, 0, 0);
1379     }
1380
1381     return;
1382 }
1383
1384 void zfApStoreAsocReqIe(zdev_t* dev, zbuf_t* buf, u16_t aid)
1385 {
1386     //struct zsWlanAssoFrameHeader* pAssoFrame;
1387     //u8_t  pBuf[sizeof(struct zsWlanAssoFrameHeader)];
1388     u16_t offset;
1389     u32_t i;
1390     u16_t length;
1391     u8_t  *htcap;
1392
1393     zmw_get_wlan_dev(dev);
1394
1395     for (i=0; i<wd->sta.asocRspFrameBodySize; i++)
1396     {
1397         wd->sta.asocRspFrameBody[i] = zmw_rx_buf_readb(dev, buf, i+24);
1398     }
1399     /* capability: 2 octets */
1400     offset = 24;
1401
1402     /* Listen interval: 2 octets */
1403     offset = 26;
1404
1405     /* SSID */
1406     offset = 28;
1407
1408     /* supported rates */
1409     if ((offset = zfFindElement(dev, buf, ZM_WLAN_EID_SUPPORT_RATE)) == 0xffff)
1410         return;
1411     length = zmw_rx_buf_readb(dev, buf, offset + 1);
1412
1413     /* extended supported rates */
1414     if ((offset = zfFindElement(dev, buf, ZM_WLAN_EID_EXTENDED_RATE)) == 0xffff)
1415         return;
1416     length = zmw_rx_buf_readb(dev, buf, offset + 1);
1417
1418     /* power capability:4 octets */
1419     offset = offset + 2 + length;
1420
1421     /* supported channels: 4 octets */
1422     offset = offset + 2 + 4;
1423
1424     /* RSN */
1425
1426     /* QoS */
1427
1428     /* HT capabilities: 28 octets */
1429     if ((offset = zfFindElement(dev, buf, ZM_WLAN_EID_HT_CAPABILITY)) != 0xffff) {
1430         /* atheros pre n */
1431         htcap = (u8_t *)&wd->ap.ie[aid].HtCap;
1432         htcap[0] = zmw_rx_buf_readb(dev, buf, offset);
1433         htcap[1] = 26;
1434         for (i=1; i<=26; i++)
1435         {
1436             htcap[i+1] = zmw_rx_buf_readb(dev, buf, offset + i);
1437             zm_debug_msg2("ASOC:  HT Capabilities, htcap=", htcap[i+1]);
1438         }
1439         return;
1440     }
1441     else if ((offset = zfFindElement(dev, buf, ZM_WLAN_PREN2_EID_HTCAPABILITY)) != 0xffff) {
1442         /* pre n 2.0 standard */
1443         htcap = (u8_t *)&wd->ap.ie[aid].HtCap;
1444         for (i=0; i<28; i++)
1445         {
1446             htcap[i] = zmw_rx_buf_readb(dev, buf, offset + i);
1447             zm_debug_msg2("ASOC:  HT Capabilities, htcap=", htcap[i]);
1448         }
1449     }
1450     else {
1451         /* not 11n AP */
1452         return;
1453     }
1454
1455
1456     /* supported regulatory classes */
1457     offset = offset + length;
1458     //length = zmw_rx_buf_readb(dev, buf, offset + 1);
1459     {
1460     u8_t *htcap;
1461     htcap = (u8_t *)&wd->sta.ie.HtInfo;
1462     //zm_debug_msg2("ASOC:  HT Capabilities info=", ((u16_t *)htcap)[1]);
1463     //zm_debug_msg2("ASOC:  A-MPDU parameters=", htcap[4]);
1464     //zm_debug_msg2("ASOC:  Supported MCS set=", ((u32_t *)htcap)[1]>>8);
1465     }
1466
1467 }
1468
1469 void zfApProcessAsocRsp(zdev_t* dev, zbuf_t* buf)
1470 {
1471
1472 }
1473
1474 void zfApProcessDeauth(zdev_t* dev, zbuf_t* buf, u16_t* src, u16_t apId)
1475 {
1476     u16_t aid;
1477     zmw_get_wlan_dev(dev);
1478     zmw_declare_for_critical_section();
1479
1480     zmw_enter_critical_section(dev);
1481     /* AP : if SA=associated STA then deauthenticate STA */
1482     if ((aid = zfApFindSta(dev, src)) != 0xffff)
1483     {
1484         /* Clear STA table */
1485         wd->ap.staTable[aid].valid = 0;
1486         if (wd->zfcbDisAsocNotify != NULL)
1487         {
1488             wd->zfcbDisAsocNotify(dev, (u8_t*)src, apId);
1489         }
1490     }
1491     zmw_leave_critical_section(dev);
1492
1493 }
1494
1495 void zfApProcessDisasoc(zdev_t* dev, zbuf_t* buf, u16_t* src, u16_t apId)
1496 {
1497     u16_t aid;
1498     zmw_get_wlan_dev(dev);
1499     zmw_declare_for_critical_section();
1500
1501     zmw_enter_critical_section(dev);
1502     /* AP : if SA=associated STA then deauthenticate STA */
1503     if ((aid = zfApFindSta(dev, src)) != 0xffff)
1504     {
1505         /* Clear STA table */
1506         wd->ap.staTable[aid].valid = 0;
1507         zmw_leave_critical_section(dev);
1508         if (wd->zfcbDisAsocNotify != NULL)
1509         {
1510             wd->zfcbDisAsocNotify(dev, (u8_t*)src, apId);
1511         }
1512     }
1513     zmw_leave_critical_section(dev);
1514
1515 }
1516
1517
1518 void zfApProcessProbeRsp(zdev_t* dev, zbuf_t* buf, struct zsAdditionInfo* AddInfo)
1519 {
1520 #if 0
1521     zmw_get_wlan_dev(dev);
1522
1523     zm_msg0_mm(ZM_LV_0, "Rx probersp");
1524
1525     /* Gather scan result */
1526
1527     //zm_debug_msg1("bssList Count = ", wd->sta.bssList.bssCount);
1528     /* return if not in scanning */
1529     if ((wd->heartBeatNotification & ZM_BSSID_LIST_SCAN)
1530             != ZM_BSSID_LIST_SCAN)
1531     {
1532         return;
1533     }
1534
1535     //if ( wd->sta.pUpdateBssList->bssCount == ZM_MAX_BSS )
1536     if ( wd->sta.bssList.bssCount == ZM_MAX_BSS )
1537     {
1538         return;
1539     }
1540
1541     zfProcessProbeRsp(dev, buf, AddInfo);
1542
1543 #endif
1544 }
1545
1546 /************************************************************************/
1547 /*                                                                      */
1548 /*    FUNCTION DESCRIPTION                  zfApAddIeSsid               */
1549 /*      Add AP information element SSID to buffer.                      */
1550 /*                                                                      */
1551 /*    INPUTS                                                            */
1552 /*      dev : device pointer                                            */
1553 /*      buf : buffer to add information element                         */
1554 /*      offset : add information element from this offset               */
1555 /*      vap : virtual AP ID                                             */
1556 /*                                                                      */
1557 /*    OUTPUTS                                                           */
1558 /*      buffer offset after adding information element                  */
1559 /*                                                                      */
1560 /*    AUTHOR                                                            */
1561 /*      Stephen Chen        ZyDAS Technology Corporation    2005.11     */
1562 /*                                                                      */
1563 /************************************************************************/
1564 u16_t zfApAddIeSsid(zdev_t* dev, zbuf_t* buf, u16_t offset, u16_t vap)
1565 {
1566     u16_t i;
1567
1568     zmw_get_wlan_dev(dev);
1569
1570     /* Element ID */
1571     zmw_tx_buf_writeb(dev, buf, offset++, ZM_WLAN_EID_SSID);
1572
1573     /* Element Length */
1574     zmw_tx_buf_writeb(dev, buf, offset++, wd->ap.ssidLen[vap]);
1575
1576     /* Information : SSID */
1577     for (i=0; i<wd->ap.ssidLen[vap]; i++)
1578     {
1579         zmw_tx_buf_writeb(dev, buf, offset++, wd->ap.ssid[vap][i]);
1580     }
1581
1582     return offset;
1583 }
1584
1585
1586 /************************************************************************/
1587 /*                                                                      */
1588 /*    FUNCTION DESCRIPTION                  zfApAddIeTim                */
1589 /*      Add AP information element TIM to buffer.                       */
1590 /*                                                                      */
1591 /*    INPUTS                                                            */
1592 /*      dev : device pointer                                            */
1593 /*      buf : buffer to add information element                         */
1594 /*      offset : add information element from this offset               */
1595 /*      vap : virtual AP ID                                             */
1596 /*                                                                      */
1597 /*    OUTPUTS                                                           */
1598 /*      buffer offset after adding information element                  */
1599 /*                                                                      */
1600 /*    AUTHOR                                                            */
1601 /*      Stephen Chen        ZyDAS Technology Corporation    2005.11     */
1602 /*                                                                      */
1603 /************************************************************************/
1604 u16_t zfApAddIeTim(zdev_t* dev, zbuf_t* buf, u16_t offset, u16_t vap)
1605 {
1606     u8_t uniBitMap[9];
1607     u16_t highestByte;
1608     u16_t i;
1609     u16_t lenOffset;
1610     u16_t id;
1611     u16_t dst[3];
1612     u16_t aid;
1613     u16_t bitPosition;
1614     u16_t bytePosition;
1615     zbuf_t* psBuf;
1616     zbuf_t* tmpBufArray[ZM_UNI_ARRAY_SIZE];
1617     u16_t tmpBufArraySize = 0;
1618
1619     zmw_get_wlan_dev(dev);
1620
1621     zmw_declare_for_critical_section();
1622
1623     /* Element ID */
1624     zmw_tx_buf_writeb(dev, buf, offset++, ZM_WLAN_EID_TIM);
1625
1626     /* offset of Element Length */
1627     lenOffset = offset++;
1628
1629     /* Information : TIM */
1630     /* DTIM count */
1631     /* TODO : Doesn't work for Virtual AP's case */
1632     wd->CurrentDtimCount++;
1633     if (wd->CurrentDtimCount >= wd->dtim)
1634     {
1635         wd->CurrentDtimCount = 0;
1636     }
1637     zmw_tx_buf_writeb(dev, buf, offset++, wd->CurrentDtimCount);
1638     /* DTIM period */
1639     zmw_tx_buf_writeb(dev, buf, offset++, wd->dtim);
1640     /* bitmap offset */
1641     zmw_tx_buf_writeb(dev, buf, offset++, 0);
1642
1643     /* Update BCMC bit */
1644     if (wd->CurrentDtimCount == 0)
1645     {
1646         zmw_enter_critical_section(dev);
1647         wd->ap.timBcmcBit[vap] = (wd->ap.bcmcTail[vap]!=wd->ap.bcmcHead[vap])?1:0;
1648         zmw_leave_critical_section(dev);
1649     }
1650     else
1651     {
1652         wd->ap.timBcmcBit[vap] = 0;
1653     }
1654
1655     /* Update Unicast bitmap */
1656     /* reset bit map */
1657     for (i=0; i<9; i++)
1658     {
1659         uniBitMap[i] = 0;
1660     }
1661     highestByte = 0;
1662 #if 1
1663
1664     zmw_enter_critical_section(dev);
1665
1666     id = wd->ap.uniHead;
1667     while (id != wd->ap.uniTail)
1668     {
1669         psBuf = wd->ap.uniArray[id];
1670
1671         /* TODO : Aging PS frame after queuing for more than 10 seconds */
1672
1673         /* get destination STA's aid */
1674         dst[0] = zmw_tx_buf_readh(dev, psBuf, 0);
1675         dst[1] = zmw_tx_buf_readh(dev, psBuf, 2);
1676         dst[2] = zmw_tx_buf_readh(dev, psBuf, 4);
1677         if ((aid = zfApFindSta(dev, dst)) != 0xffff)
1678         {
1679             if (wd->ap.staTable[aid].psMode != 0)
1680             {
1681                 zm_msg1_mm(ZM_LV_0, "aid=",aid);
1682                 aid++;
1683                 zm_assert(aid<=64);
1684                 bitPosition = (1 << (aid & 0x7));
1685                 bytePosition = (aid >> 3);
1686                 uniBitMap[bytePosition] |= bitPosition;
1687
1688                 if (bytePosition>highestByte)
1689                 {
1690                     highestByte = bytePosition;
1691                 }
1692                 id = (id+1) & (ZM_UNI_ARRAY_SIZE-1);
1693             }
1694             else
1695             {
1696                 zm_msg0_mm(ZM_LV_0, "Send PS frame which STA no longer in PS mode");
1697                 /* Send PS frame which STA no longer in PS mode */
1698                 zfApRemoveFromPsQueue(dev, id, dst);
1699                 tmpBufArray[tmpBufArraySize++] = psBuf;
1700             }
1701         }
1702         else
1703         {
1704             zm_msg0_mm(ZM_LV_0, "Free garbage PS frame");
1705             /* Free garbage PS frame */
1706             zfApRemoveFromPsQueue(dev, id, dst);
1707             zfwBufFree(dev, psBuf, 0);
1708         }
1709     }
1710
1711     zmw_leave_critical_section(dev);
1712 #endif
1713
1714     zfQueueGenerateUapsdTim(dev, wd->ap.uapsdQ, uniBitMap, &highestByte);
1715
1716     zm_msg1_mm(ZM_LV_3, "bm=",uniBitMap[0]);
1717     zm_msg1_mm(ZM_LV_3, "highestByte=",highestByte);
1718     zm_msg1_mm(ZM_LV_3, "timBcmcBit[]=",wd->ap.timBcmcBit[vap]);
1719
1720     /* bitmap */
1721     zmw_tx_buf_writeb(dev, buf, offset++,
1722                          uniBitMap[0] | wd->ap.timBcmcBit[vap]);
1723     for (i=0; i<highestByte; i++)
1724     {
1725         zmw_tx_buf_writeb(dev, buf, offset++, uniBitMap[i+1]);
1726     }
1727
1728     /* Element Length */
1729     zmw_tx_buf_writeb(dev, buf, lenOffset, highestByte+4);
1730
1731     for (i=0; i<tmpBufArraySize; i++)
1732     {
1733         /* Put to VTXQ[ac] */
1734         zfPutVtxq(dev, tmpBufArray[i]);
1735     }
1736     /* Push VTXQ[ac] */
1737     zfPushVtxq(dev);
1738
1739     return offset;
1740 }
1741
1742
1743
1744 /************************************************************************/
1745 /*                                                                      */
1746 /*    FUNCTION DESCRIPTION                  zfApRemoveFromPsQueue       */
1747 /*      Remove zbuf from PS queue.                                      */
1748 /*                                                                      */
1749 /*    INPUTS                                                            */
1750 /*      dev : device pointer                                            */
1751 /*      id : index in ps queue                                          */
1752 /*                                                                      */
1753 /*    OUTPUTS                                                           */
1754 /*      more data bit                                                   */
1755 /*                                                                      */
1756 /*    AUTHOR                                                            */
1757 /*      Stephen Chen        Atheros Communications, INC.    2007.1      */
1758 /*                                                                      */
1759 /************************************************************************/
1760 u8_t zfApRemoveFromPsQueue(zdev_t* dev, u16_t id, u16_t* addr)
1761 {
1762     u16_t dst[3];
1763     u16_t nid;
1764     u8_t moreData = 0;
1765     zmw_get_wlan_dev(dev);
1766
1767     wd->ap.uniTail = (wd->ap.uniTail-1) & (ZM_UNI_ARRAY_SIZE-1);
1768     while (id != wd->ap.uniTail)
1769     {
1770         nid = (id + 1) & (ZM_UNI_ARRAY_SIZE - 1);
1771         wd->ap.uniArray[id] = wd->ap.uniArray[nid];
1772
1773         /* Search until tail to config more data bit */
1774         dst[0] = zmw_buf_readh(dev, wd->ap.uniArray[id], 0);
1775         dst[1] = zmw_buf_readh(dev, wd->ap.uniArray[id], 2);
1776         dst[2] = zmw_buf_readh(dev, wd->ap.uniArray[id], 4);
1777         if ((addr[0] == dst[0]) && (addr[1] == dst[1])
1778                 && (addr[2] == dst[2]))
1779         {
1780             moreData = 0x20;
1781         }
1782
1783         id = nid;
1784     }
1785     return moreData;
1786 }
1787
1788 /************************************************************************/
1789 /*                                                                      */
1790 /*    FUNCTION DESCRIPTION                  zfApAddIeWmePara            */
1791 /*      Add WME Parameter Element to buffer.                            */
1792 /*                                                                      */
1793 /*    INPUTS                                                            */
1794 /*      dev : device pointer                                            */
1795 /*      buf : buffer to add information element                         */
1796 /*      offset : add information element from this offset               */
1797 /*      vap : virtual AP ID                                             */
1798 /*                                                                      */
1799 /*    OUTPUTS                                                           */
1800 /*      buffer offset after adding information element                  */
1801 /*                                                                      */
1802 /*    AUTHOR                                                            */
1803 /*      Stephen Chen        ZyDAS Technology Corporation    2006.1      */
1804 /*                                                                      */
1805 /************************************************************************/
1806 u16_t zfApAddIeWmePara(zdev_t* dev, zbuf_t* buf, u16_t offset, u16_t vap)
1807 {
1808     zmw_get_wlan_dev(dev);
1809
1810     /* Element ID */
1811     zmw_tx_buf_writeb(dev, buf, offset++, ZM_WLAN_EID_WIFI_IE);
1812
1813     /* Element Length */
1814     zmw_tx_buf_writeb(dev, buf, offset++, 24);
1815
1816     /* OUI */
1817     zmw_tx_buf_writeb(dev, buf, offset++, 0x00);
1818     zmw_tx_buf_writeb(dev, buf, offset++, 0x50);
1819     zmw_tx_buf_writeb(dev, buf, offset++, 0xF2);
1820     zmw_tx_buf_writeb(dev, buf, offset++, 0x02);
1821     zmw_tx_buf_writeb(dev, buf, offset++, 0x01);
1822     zmw_tx_buf_writeb(dev, buf, offset++, 0x01);
1823
1824     /* QoS Info */
1825     if (wd->ap.uapsdEnabled)
1826     {
1827         zmw_tx_buf_writeb(dev, buf, offset++, 0x81);
1828     }
1829     else
1830     {
1831     zmw_tx_buf_writeb(dev, buf, offset++, 0x01);
1832     }
1833
1834     /* Reserved */
1835     zmw_tx_buf_writeb(dev, buf, offset++, 0x00);
1836
1837     /* Best Effort AC parameters */
1838     zmw_tx_buf_writeb(dev, buf, offset++, 0x03);
1839     zmw_tx_buf_writeb(dev, buf, offset++, 0xA4);
1840     zmw_tx_buf_writeb(dev, buf, offset++, 0x00);
1841     zmw_tx_buf_writeb(dev, buf, offset++, 0x00);
1842     /* Backfround AC parameters */
1843     zmw_tx_buf_writeb(dev, buf, offset++, 0x27);
1844     zmw_tx_buf_writeb(dev, buf, offset++, 0xA4);
1845     zmw_tx_buf_writeb(dev, buf, offset++, 0x00);
1846     zmw_tx_buf_writeb(dev, buf, offset++, 0x00);
1847     /* Video AC parameters */
1848     zmw_tx_buf_writeb(dev, buf, offset++, 0x42);
1849     zmw_tx_buf_writeb(dev, buf, offset++, 0x43);
1850     zmw_tx_buf_writeb(dev, buf, offset++, 0x5E);
1851     zmw_tx_buf_writeb(dev, buf, offset++, 0x00);
1852     /* Voice AC parameters */
1853     zmw_tx_buf_writeb(dev, buf, offset++, 0x62);
1854     zmw_tx_buf_writeb(dev, buf, offset++, 0x32);
1855     zmw_tx_buf_writeb(dev, buf, offset++, 0x2F);
1856     zmw_tx_buf_writeb(dev, buf, offset++, 0x00);
1857
1858     return offset;
1859 }
1860
1861
1862 /************************************************************************/
1863 /*                                                                      */
1864 /*    FUNCTION DESCRIPTION                  zfApSendBeacon              */
1865 /*      Sned AP mode beacon.                                            */
1866 /*                                                                      */
1867 /*    INPUTS                                                            */
1868 /*      dev : device pointer                                            */
1869 /*                                                                      */
1870 /*    OUTPUTS                                                           */
1871 /*      none                                                            */
1872 /*                                                                      */
1873 /*    AUTHOR                                                            */
1874 /*      Stephen Chen        ZyDAS Technology Corporation    2005.11     */
1875 /*                                                                      */
1876 /************************************************************************/
1877 void zfApSendBeacon(zdev_t* dev)
1878 {
1879     zbuf_t* buf;
1880     u16_t offset;
1881     u16_t vap;
1882     u16_t seq;
1883
1884     zmw_get_wlan_dev(dev);
1885
1886     zmw_declare_for_critical_section();
1887
1888     wd->ap.beaconCounter++;
1889     if (wd->ap.beaconCounter >= wd->ap.vapNumber)
1890     {
1891         wd->ap.beaconCounter = 0;
1892     }
1893     vap = wd->ap.beaconCounter;
1894
1895
1896     zm_msg1_mm(ZM_LV_2, "Send beacon, vap=", vap);
1897
1898     /* TBD : Maximum size of beacon */
1899     if ((buf = zfwBufAllocate(dev, 1024)) == NULL)
1900     {
1901         zm_msg0_mm(ZM_LV_0, "Alloc beacon buf Fail!");
1902         return;
1903     }
1904
1905     offset = 0;
1906
1907     /* wlan header */
1908     /* Frame control */
1909     zmw_tx_buf_writeh(dev, buf, offset, 0x0080);
1910     offset+=2;
1911     /* Duration */
1912     zmw_tx_buf_writeh(dev, buf, offset, 0x0000);
1913     offset+=2;
1914     /* Address 1 */
1915     zmw_tx_buf_writeh(dev, buf, offset, 0xffff);
1916     offset+=2;
1917     zmw_tx_buf_writeh(dev, buf, offset, 0xffff);
1918     offset+=2;
1919     zmw_tx_buf_writeh(dev, buf, offset, 0xffff);
1920     offset+=2;
1921     /* Address 2 */
1922     zmw_tx_buf_writeh(dev, buf, offset, wd->macAddr[0]);
1923     offset+=2;
1924     zmw_tx_buf_writeh(dev, buf, offset, wd->macAddr[1]);
1925     offset+=2;
1926 #ifdef ZM_VAPMODE_MULTILE_SSID
1927     zmw_tx_buf_writeh(dev, buf, offset, wd->macAddr[2]); //Multiple SSID
1928 #else
1929     zmw_tx_buf_writeh(dev, buf, offset, (wd->macAddr[2]+(vap<<8))); //VAP
1930 #endif
1931     offset+=2;
1932     /* Address 3 */
1933     zmw_tx_buf_writeh(dev, buf, offset, wd->macAddr[0]);
1934     offset+=2;
1935     zmw_tx_buf_writeh(dev, buf, offset, wd->macAddr[1]);
1936     offset+=2;
1937 #ifdef ZM_VAPMODE_MULTILE_SSID
1938     zmw_tx_buf_writeh(dev, buf, offset, wd->macAddr[2]); //Multiple SSID
1939 #else
1940     zmw_tx_buf_writeh(dev, buf, offset, (wd->macAddr[2]+(vap<<8))); //VAP
1941 #endif
1942     offset+=2;
1943
1944     /* Sequence number */
1945     zmw_enter_critical_section(dev);
1946     seq = ((wd->mmseq++)<<4);
1947     zmw_leave_critical_section(dev);
1948     zmw_tx_buf_writeh(dev, buf, offset, seq);
1949     offset+=2;
1950
1951     /* 24-31 Time Stamp : hardware will fill this field */
1952     zmw_tx_buf_writeh(dev, buf, offset, 0);
1953     zmw_tx_buf_writeh(dev, buf, offset+2, 0);
1954     zmw_tx_buf_writeh(dev, buf, offset+4, 0);
1955     zmw_tx_buf_writeh(dev, buf, offset+6, 0);
1956     offset+=8;
1957
1958     /* Beacon Interval */
1959     zmw_tx_buf_writeh(dev, buf, offset, wd->beaconInterval);
1960     offset+=2;
1961
1962     /* Capability */
1963     zmw_tx_buf_writeh(dev, buf, offset, wd->ap.capab[vap]);
1964     offset+=2;
1965
1966     /* SSID */
1967     if (wd->ap.hideSsid[vap] == 0)
1968     {
1969         offset = zfApAddIeSsid(dev, buf, offset, vap);
1970     }
1971     else
1972     {
1973         zmw_tx_buf_writeb(dev, buf, offset++, ZM_WLAN_EID_SSID);
1974         zmw_tx_buf_writeb(dev, buf, offset++, 0);
1975
1976     }
1977
1978     /* Support Rate */
1979     if ( wd->frequency < 3000 )
1980     {
1981     offset = zfMmAddIeSupportRate(dev, buf, offset,
1982                                   ZM_WLAN_EID_SUPPORT_RATE, ZM_RATE_SET_CCK);
1983     }
1984     else
1985     {
1986         offset = zfMmAddIeSupportRate(dev, buf, offset,
1987                                   ZM_WLAN_EID_SUPPORT_RATE, ZM_RATE_SET_OFDM);
1988     }
1989
1990     /* DS parameter set */
1991     offset = zfMmAddIeDs(dev, buf, offset);
1992
1993     /* TIM */
1994     offset = zfApAddIeTim(dev, buf, offset, vap);
1995
1996     /* If WLAN Type is not PURE B */
1997     if (wd->ap.wlanType[vap] != ZM_WLAN_TYPE_PURE_B)
1998     {
1999         if ( wd->frequency < 3000 )
2000         {
2001         /* ERP Information */
2002         offset = zfMmAddIeErp(dev, buf, offset);
2003
2004         /* Extended Supported Rates */
2005         offset = zfMmAddIeSupportRate(dev, buf, offset,
2006                                       ZM_WLAN_EID_EXTENDED_RATE, ZM_RATE_SET_OFDM);
2007     }
2008     }
2009
2010     /* TODO : country information */
2011     /* TODO : RSN */
2012     if (wd->ap.wpaSupport[vap] == 1)
2013     {
2014         offset = zfMmAddIeWpa(dev, buf, offset, vap);
2015     }
2016
2017     /* WME Parameters */
2018     if (wd->ap.qosMode == 1)
2019     {
2020         offset = zfApAddIeWmePara(dev, buf, offset, vap);
2021     }
2022
2023     /* HT Capabilities Info */
2024     offset = zfMmAddHTCapability(dev, buf, offset);
2025
2026     /* Extended HT Capabilities Info */
2027     offset = zfMmAddExtendedHTCapability(dev, buf, offset);
2028
2029     /* 1212 : write to beacon fifo */
2030     /* 1221 : write to share memory */
2031     zfHpSendBeacon(dev, buf, offset);
2032
2033     /* Free beacon buffer */
2034     /* TODO: In order to fit the madwifi beacon architecture, we need to
2035        free beacon buffer in the HAL layer.
2036      */
2037
2038     //zfwBufFree(dev, buf, 0);
2039 }
2040
2041
2042 /************************************************************************/
2043 /*                                                                      */
2044 /*    FUNCTION DESCRIPTION                  zfIntrabssForward           */
2045 /*      Called to transmit intra-BSS frame from upper layer.            */
2046 /*                                                                      */
2047 /*    INPUTS                                                            */
2048 /*      dev : device pointer                                            */
2049 /*      buf : buffer pointer                                            */
2050 /*      vap : virtual AP                                                */
2051 /*                                                                      */
2052 /*    OUTPUTS                                                           */
2053 /*      1 : unicast intras-BSS frame                                    */
2054 /*      0 : other frames                                                */
2055 /*                                                                      */
2056 /*    AUTHOR                                                            */
2057 /*      Stephen             ZyDAS Technology Corporation    2005.11     */
2058 /*                                                                      */
2059 /************************************************************************/
2060 u16_t zfIntrabssForward(zdev_t* dev, zbuf_t* buf, u8_t srcVap)
2061 {
2062     u16_t err;
2063     u16_t asocFlag = 0;
2064     u16_t dst[3];
2065     u16_t aid;
2066     u16_t staState;
2067     zbuf_t* txBuf;
2068     u16_t len;
2069     u16_t i;
2070     u16_t temp;
2071     u16_t ret;
2072     u8_t vap = 0;
2073 #ifdef ZM_ENABLE_NATIVE_WIFI
2074     dst[0] = zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A3_OFFSET);
2075     dst[1] = zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A3_OFFSET+2);
2076     dst[2] = zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A3_OFFSET+4);
2077 #else
2078     dst[0] = zmw_rx_buf_readh(dev, buf, 0);
2079     dst[1] = zmw_rx_buf_readh(dev, buf, 2);
2080     dst[2] = zmw_rx_buf_readh(dev, buf, 4);
2081 #endif  // ZM_ENABLE_NATIVE_WIFI
2082
2083     /* Do Intra-BSS forward(data copy) if necessary*/
2084     if ((dst[0]&0x1) != 0x1)
2085     {
2086         aid = zfApGetSTAInfo(dev, dst, &staState, &vap);
2087         if ((aid != 0xffff) && (staState == ZM_STATE_ASOC) && (srcVap == vap))
2088         {
2089             asocFlag = 1;
2090             zm_msg0_rx(ZM_LV_2, "Intra-BSS forward : asoc STA");
2091         }
2092
2093     }
2094     else
2095     {
2096         vap = srcVap;
2097         zm_msg0_rx(ZM_LV_2, "Intra-BSS forward : BCorMC");
2098     }
2099
2100     /* destination address = associated STA or BC/MC */
2101     if ((asocFlag == 1) || ((dst[0]&0x1) == 0x1))
2102     {
2103         /* Allocate frame */
2104         if ((txBuf = zfwBufAllocate(dev, ZM_RX_FRAME_SIZE))
2105                 == NULL)
2106         {
2107             zm_msg0_rx(ZM_LV_1, "Alloc intra-bss buf Fail!");
2108             goto zlAllocError;
2109         }
2110
2111         /* Copy frame */
2112         len = zfwBufGetSize(dev, buf);
2113         for (i=0; i<len; i+=2)
2114         {
2115             temp = zmw_rx_buf_readh(dev, buf, i);
2116             zmw_tx_buf_writeh(dev, txBuf, i, temp);
2117         }
2118         zfwBufSetSize(dev, txBuf, len);
2119
2120 #ifdef ZM_ENABLE_NATIVE_WIFI
2121         /* Tx-A2 = Rx-A1, Tx-A3 = Rx-A2, Tx-A1 = Rx-A3 */
2122         for (i=0; i<6; i+=2)
2123         {
2124             temp = zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A1_OFFSET+i);
2125             zmw_tx_buf_writeh(dev, txBuf, ZM_WLAN_HEADER_A2_OFFSET+i, temp);
2126             temp = zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A2_OFFSET+i);
2127             zmw_tx_buf_writeh(dev, txBuf, ZM_WLAN_HEADER_A3_OFFSET+i, temp);
2128             temp = zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A3_OFFSET+i);
2129             zmw_tx_buf_writeh(dev, txBuf, ZM_WLAN_HEADER_A1_OFFSET+i, temp);
2130         }
2131
2132         #endif
2133
2134         /* Transmit frame */
2135         /* Return error if port is disabled */
2136         if ((err = zfTxPortControl(dev, txBuf, vap)) == ZM_PORT_DISABLED)
2137         {
2138             err = ZM_ERR_TX_PORT_DISABLED;
2139             goto zlTxError;
2140         }
2141
2142 #if 1
2143         /* AP : Buffer frame for power saving STA */
2144         if ((ret = zfApBufferPsFrame(dev, txBuf, vap)) == 0)
2145         {
2146             /* forward frame if not been buffered */
2147             #if 1
2148             /* Put to VTXQ[ac] */
2149             ret = zfPutVtxq(dev, txBuf);
2150             /* Push VTXQ[ac] */
2151             zfPushVtxq(dev);
2152             #else
2153             zfTxSendEth(dev, txBuf, vap, ZM_INTERNAL_ALLOC_BUF, 0);
2154             #endif
2155
2156         }
2157 #endif
2158     }
2159     return asocFlag;
2160
2161 zlTxError:
2162     zfwBufFree(dev, txBuf, 0);
2163 zlAllocError:
2164     return asocFlag;
2165 }
2166
2167 struct zsMicVar* zfApGetRxMicKey(zdev_t* dev, zbuf_t* buf)
2168 {
2169     u8_t sa[6];
2170     u16_t id = 0, macAddr[3];
2171
2172     zmw_get_wlan_dev(dev);
2173
2174     zfCopyFromRxBuffer(dev, buf, sa, ZM_WLAN_HEADER_A2_OFFSET, 6);
2175
2176     macAddr[0] = sa[0] + (sa[1] << 8);
2177     macAddr[1] = sa[2] + (sa[3] << 8);
2178     macAddr[2] = sa[4] + (sa[5] << 8);
2179
2180     if ((id = zfApFindSta(dev, macAddr)) != 0xffff)
2181         return (&wd->ap.staTable[id].rxMicKey);
2182
2183     return NULL;
2184 }
2185
2186 struct zsMicVar* zfApGetTxMicKey(zdev_t* dev, zbuf_t* buf, u8_t* qosType)
2187 {
2188     u8_t da[6];
2189     u16_t id = 0, macAddr[3];
2190
2191     zmw_get_wlan_dev(dev);
2192
2193     zfCopyFromIntTxBuffer(dev, buf, da, 0, 6);
2194
2195     macAddr[0] = da[0] + (da[1] << 8);
2196     macAddr[1] = da[2] + (da[3] << 8);
2197     macAddr[2] = da[4] + (da[5] << 8);
2198
2199     if ((macAddr[0] & 0x1))
2200     {
2201         return (&wd->ap.bcMicKey[0]);
2202     }
2203     else if ((id = zfApFindSta(dev, macAddr)) != 0xffff)
2204     {
2205         *qosType = wd->ap.staTable[id].qosType;
2206         return (&wd->ap.staTable[id].txMicKey);
2207     }
2208
2209     return NULL;
2210 }
2211
2212 u16_t zfApUpdatePsBit(zdev_t* dev, zbuf_t* buf, u8_t* vap, u8_t* uapsdTrig)
2213 {
2214     u16_t staState;
2215     u16_t aid;
2216     u16_t psBit;
2217     u16_t src[3];
2218     u16_t dst[1];
2219     u16_t i;
2220
2221     zmw_get_wlan_dev(dev);
2222
2223     src[0] = zmw_rx_buf_readh(dev, buf, 10);
2224     src[1] = zmw_rx_buf_readh(dev, buf, 12);
2225     src[2] = zmw_rx_buf_readh(dev, buf, 14);
2226
2227     if ((zmw_rx_buf_readb(dev, buf, 1) & 0x3) != 3)
2228     {
2229         /* AP */
2230         dst[0] = zmw_rx_buf_readh(dev, buf, 4);
2231
2232         psBit = (zmw_rx_buf_readb(dev, buf, 1) & 0x10) >> 4;
2233         /* Get AID and update STA PS mode */
2234         aid = zfApGetSTAInfoAndUpdatePs(dev, src, &staState, vap, psBit, uapsdTrig);
2235
2236         /* if STA not associated, send deauth */
2237         if ((aid == 0xffff) || (staState != ZM_STATE_ASOC))
2238         {
2239             if ((dst[0]&0x1)==0)
2240             {
2241                 zfSendMmFrame(dev, ZM_WLAN_FRAME_TYPE_DEAUTH, src, 0x7,
2242                         0, 0);
2243             }
2244
2245             return ZM_ERR_STA_NOT_ASSOCIATED;
2246         }
2247     } /* if ((zmw_rx_buf_readb(dev, buf, 1) & 0x3) != 3) */
2248     else
2249     {
2250         /* WDS */
2251         for (i=0; i<ZM_MAX_WDS_SUPPORT; i++)
2252         {
2253             if ((wd->ap.wds.wdsBitmap & (1<<i)) != 0)
2254             {
2255                 if ((src[0] == wd->ap.wds.macAddr[i][0])
2256                         && (src[1] == wd->ap.wds.macAddr[i][1])
2257                         && (src[2] == wd->ap.wds.macAddr[i][2]))
2258                 {
2259                     *vap = 0x20 + i;
2260                     break;
2261                 }
2262             }
2263         }
2264     }
2265     return ZM_SUCCESS;
2266 }
2267
2268 void zfApProcessPsPoll(zdev_t* dev, zbuf_t* buf)
2269 {
2270     u16_t src[3];
2271     u16_t dst[3];
2272     zbuf_t* psBuf = NULL;
2273     u16_t id;
2274     u8_t moreData = 0;
2275
2276     zmw_get_wlan_dev(dev);
2277
2278     zmw_declare_for_critical_section();
2279
2280     src[0] = zmw_tx_buf_readh(dev, buf, 10);
2281     src[1] = zmw_tx_buf_readh(dev, buf, 12);
2282     src[2] = zmw_tx_buf_readh(dev, buf, 14);
2283
2284     /* Find ps buffer for PsPoll */
2285     zmw_enter_critical_section(dev);
2286     id = wd->ap.uniHead;
2287     while (id != wd->ap.uniTail)
2288     {
2289         psBuf = wd->ap.uniArray[id];
2290
2291         dst[0] = zmw_tx_buf_readh(dev, psBuf, 0);
2292         dst[1] = zmw_tx_buf_readh(dev, psBuf, 2);
2293         dst[2] = zmw_tx_buf_readh(dev, psBuf, 4);
2294
2295         if ((src[0] == dst[0]) && (src[1] == dst[1]) && (src[2] == dst[2]))
2296         {
2297             moreData = zfApRemoveFromPsQueue(dev, id, src);
2298             break;
2299         }
2300         else
2301         {
2302             psBuf = NULL;
2303         }
2304         id = (id + 1) & (ZM_UNI_ARRAY_SIZE - 1);
2305     }
2306     zmw_leave_critical_section(dev);
2307
2308     /* Send ps buffer */
2309     if (psBuf != NULL)
2310     {
2311         /* Send with more data bit */
2312         zfTxSendEth(dev, psBuf, 0, ZM_EXTERNAL_ALLOC_BUF, moreData);
2313     }
2314
2315     return;
2316 }
2317
2318 void zfApSetProtectionMode(zdev_t* dev, u16_t mode)
2319 {
2320     zmw_get_wlan_dev(dev);
2321
2322     if (mode == 0)
2323     {
2324         if (wd->ap.protectionMode != mode)
2325         {
2326             /* Write MAC&PHY registers to disable protection */
2327
2328             wd->ap.protectionMode = mode;
2329         }
2330
2331     }
2332     else
2333     {
2334         if (wd->ap.protectionMode != mode)
2335         {
2336             /* Write MAC&PHY registers to enable protection */
2337
2338             wd->ap.protectionMode = mode;
2339         }
2340     }
2341     return;
2342 }
2343
2344
2345 /************************************************************************/
2346 /*                                                                      */
2347 /*    FUNCTION DESCRIPTION                  zfApSendFailure             */
2348 /*      Send failure.                                                   */
2349 /*                                                                      */
2350 /*    INPUTS                                                            */
2351 /*      dev : device pointer                                            */
2352 /*      addr : receiver address                                         */
2353 /*                                                                      */
2354 /*    OUTPUTS                                                           */
2355 /*      None                                                            */
2356 /*                                                                      */
2357 /*    AUTHOR                                                            */
2358 /*      Stephen Chen        Atheros Communications, INC.    2007.1      */
2359 /*                                                                      */
2360 /************************************************************************/
2361 void zfApSendFailure(zdev_t* dev, u8_t* addr)
2362 {
2363     u16_t id;
2364     u16_t staAddr[3];
2365     zmw_get_wlan_dev(dev);
2366     zmw_declare_for_critical_section();
2367
2368     staAddr[0] = addr[0] + (((u16_t)addr[1])<<8);
2369     staAddr[1] = addr[2] + (((u16_t)addr[3])<<8);
2370     staAddr[2] = addr[4] + (((u16_t)addr[5])<<8);
2371     zmw_enter_critical_section(dev);
2372     if ((id = zfApFindSta(dev, staAddr)) != 0xffff)
2373     {
2374         /* Send failture : Add 3 minutes to inactive time that will */
2375         /*                 will make STA been kicked out soon */
2376         wd->ap.staTable[id].time -= (3*ZM_TICK_PER_MINUTE);
2377     }
2378     zmw_leave_critical_section(dev);
2379 }
2380
2381
2382 void zfApProcessAction(zdev_t* dev, zbuf_t* buf)
2383 {
2384     u8_t category;
2385
2386     //zmw_get_wlan_dev(dev);
2387
2388     //zmw_declare_for_critical_section();
2389
2390     category = zmw_rx_buf_readb(dev, buf, 24);
2391
2392     switch (category)
2393     {
2394     case ZM_WLAN_BLOCK_ACK_ACTION_FRAME:
2395         zfAggBlockAckActionFrame(dev, buf);
2396         break;
2397     default:
2398         break;
2399     }
2400
2401     return;
2402 }