GUI: Fix Tomato RAF theme for all builds. Compilation typo.
[tomato.git] / release / src-rt-6.x.4708 / linux / linux-2.6.36 / drivers / staging / otus / 80211core / cmmap.c
blob1074e8c422e719e0276c230ebf11c4b68132791f
1 /*
2 * Copyright (c) 2007-2008 Atheros Communications Inc.
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.
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.
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"
30 extern const u8_t zcUpToAc[];
32 void zfMmApTimeTick(zdev_t* dev)
34 u32_t now;
35 zmw_get_wlan_dev(dev);
37 //zm_debug_msg1("wd->wlanMode : ", wd->wlanMode);
38 if (wd->wlanMode == ZM_MODE_AP)
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)
45 zfApAgingSta(dev);
47 else if (now == 0x1f)
49 zfQueueAge(dev, wd->ap.uapsdQ, wd->tick, 10000);
51 /* AP : check (wd->ap.protectedObss) and (wd->ap.bStaAssociated) */
52 /* to enable NonErp and Protection mode */
53 else if (now == 0x3f)
55 //zfApProtctionMonitor(dev);
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)
77 u16_t i;
79 zmw_get_wlan_dev(dev);
81 for (i=0; i<ZM_MAX_STA_SUPPORT; i++)
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;
92 return;
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)
115 u16_t i;
117 zmw_get_wlan_dev(dev);
119 for (i=0; i<ZM_MAX_STA_SUPPORT; i++)
121 if (wd->ap.staTable[i].valid == 1)
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]))
127 return i;
131 return 0xffff;
134 u16_t zfApGetSTAInfo(zdev_t* dev, u16_t* addr, u16_t* state, u8_t* vap)
136 u16_t id;
138 zmw_get_wlan_dev(dev);
140 zmw_declare_for_critical_section();
142 zmw_enter_critical_section(dev);
144 id = zfApFindSta(dev, addr);
145 if (id != 0xffff)
147 *vap = wd->ap.staTable[id].vap;
148 *state = wd->ap.staTable[id++].state;
151 zmw_leave_critical_section(dev);
153 return id;
157 void zfApGetStaQosType(zdev_t* dev, u16_t* addr, u8_t* qosType)
159 u16_t id;
161 zmw_get_wlan_dev(dev);
163 zmw_declare_for_critical_section();
165 zmw_enter_critical_section(dev);
167 id = zfApFindSta(dev, addr);
168 if (id != 0xffff)
170 *qosType = wd->ap.staTable[id].qosType;
172 else
174 *qosType = 0;
177 zmw_leave_critical_section(dev);
179 return;
182 void zfApGetStaTxRateAndQosType(zdev_t* dev, u16_t* addr, u32_t* phyCtrl,
183 u8_t* qosType, u16_t* rcProbingFlag)
185 u16_t id;
186 u8_t rate;
188 zmw_get_wlan_dev(dev);
190 zmw_declare_for_critical_section();
192 zmw_enter_critical_section(dev);
194 id = zfApFindSta(dev, addr);
195 if (id != 0xffff)
197 rate = (u8_t)zfRateCtrlGetTxRate(dev, &wd->ap.staTable[id].rcCell, rcProbingFlag);
198 #ifdef ZM_AP_DEBUG
199 //rate = 15;
200 #endif
201 *phyCtrl = zcRateToPhyCtrl[rate];
202 *qosType = wd->ap.staTable[id].qosType;
204 else
206 if (wd->frequency < 3000)
208 /* CCK 1M */
209 //header[2] = 0x0f00; //PHY control L
210 //header[3] = 0x0000; //PHY control H
211 *phyCtrl = 0x00000F00;
213 else
215 /* CCK 6M */
216 //header[2] = 0x0f01; //PHY control L
217 //header[3] = 0x000B; //PHY control H
218 *phyCtrl = 0x000B0F01;
220 *qosType = 0;
223 zmw_leave_critical_section(dev);
225 zm_msg2_mm(ZM_LV_3, "PhyCtrl=", *phyCtrl);
226 return;
229 void zfApGetStaEncryType(zdev_t* dev, u16_t* addr, u8_t* encryType)
231 //struct zsWlanDev* wd = (struct zsWlanDev*) zmw_wlan_dev(dev);
232 u16_t id;
234 zmw_get_wlan_dev(dev);
236 zmw_declare_for_critical_section();
238 zmw_enter_critical_section(dev);
240 id = zfApFindSta(dev, addr);
241 if (id != 0xffff)
243 *encryType = wd->ap.staTable[id].encryMode;
245 else
247 *encryType = ZM_NO_WEP;
250 zmw_leave_critical_section(dev);
252 zm_msg2_mm(ZM_LV_3, "encyrType=", *encryType);
253 return;
256 void zfApGetStaWpaIv(zdev_t* dev, u16_t* addr, u16_t* iv16, u32_t* iv32)
258 //struct zsWlanDev* wd = (struct zsWlanDev*) zmw_wlan_dev(dev);
259 u16_t id;
261 zmw_get_wlan_dev(dev);
263 zmw_declare_for_critical_section();
265 zmw_enter_critical_section(dev);
267 id = zfApFindSta(dev, addr);
268 if (id != 0xffff)
270 *iv16 = wd->ap.staTable[id].iv16;
271 *iv32 = wd->ap.staTable[id].iv32;
273 else
275 *iv16 = 0;
276 *iv32 = 0;
279 zmw_leave_critical_section(dev);
281 zm_msg2_mm(ZM_LV_3, "iv16=", *iv16);
282 zm_msg2_mm(ZM_LV_3, "iv32=", *iv32);
283 return;
286 void zfApSetStaWpaIv(zdev_t* dev, u16_t* addr, u16_t iv16, u32_t iv32)
288 //struct zsWlanDev* wd = (struct zsWlanDev*) zmw_wlan_dev(dev);
289 u16_t id;
291 zmw_get_wlan_dev(dev);
293 zmw_declare_for_critical_section();
295 zmw_enter_critical_section(dev);
297 id = zfApFindSta(dev, addr);
298 if (id != 0xffff)
300 wd->ap.staTable[id].iv16 = iv16;
301 wd->ap.staTable[id].iv32 = iv32;
304 zmw_leave_critical_section(dev);
306 zm_msg2_mm(ZM_LV_3, "iv16=", iv16);
307 zm_msg2_mm(ZM_LV_3, "iv32=", iv32);
308 return;
311 void zfApClearStaKey(zdev_t* dev, u16_t* addr)
313 //struct zsWlanDev* wd = (struct zsWlanDev*) zmw_wlan_dev(dev);
314 u16_t bcAddr[3] = { 0xffff, 0xffff, 0xffff };
315 u16_t id;
317 zmw_get_wlan_dev(dev);
319 if (zfMemoryIsEqual((u8_t*)bcAddr, (u8_t*)addr, sizeof(bcAddr)) == TRUE)
321 /* Turn off group key information */
322 // zfClearKey(dev, 0);
324 else
326 zmw_declare_for_critical_section();
328 zmw_enter_critical_section(dev);
330 id = zfApFindSta(dev, addr);
331 if (id != 0xffff)
333 /* Turn off STA's key information */
334 zfHpRemoveKey(dev, id+1);
336 /* Update STA's Encryption Type */
337 wd->ap.staTable[id].encryMode = ZM_NO_WEP;
339 else
341 zm_msg0_mm(ZM_LV_3, "Can't find STA address\n");
343 zmw_leave_critical_section(dev);
347 #ifdef ZM_ENABLE_CENC
348 void zfApGetStaCencIvAndKeyIdx(zdev_t* dev, u16_t* addr, u32_t *iv, u8_t *keyIdx)
350 //struct zsWlanDev* wd = (struct zsWlanDev*) zmw_wlan_dev(dev);
351 u16_t id;
352 zmw_get_wlan_dev(dev);
353 zmw_declare_for_critical_section();
356 zmw_enter_critical_section(dev);
358 id = zfApFindSta(dev, addr);
359 if (id != 0xffff)
361 *iv++ = wd->ap.staTable[id].txiv[0];
362 *iv++ = wd->ap.staTable[id].txiv[1];
363 *iv++ = wd->ap.staTable[id].txiv[2];
364 *iv = wd->ap.staTable[id].txiv[3];
365 *keyIdx = wd->ap.staTable[id].cencKeyIdx;
367 else
369 *iv++ = 0x5c365c37;
370 *iv++ = 0x5c365c36;
371 *iv++ = 0x5c365c36;
372 *iv = 0x5c365c36;
373 *keyIdx = 0;
376 zmw_leave_critical_section(dev);
377 return;
380 void zfApSetStaCencIv(zdev_t* dev, u16_t* addr, u32_t *iv)
382 //struct zsWlanDev* wd = (struct zsWlanDev*) zmw_wlan_dev(dev);
383 u16_t id;
384 zmw_get_wlan_dev(dev);
385 zmw_declare_for_critical_section();
388 zmw_enter_critical_section(dev);
390 id = zfApFindSta(dev, addr);
391 if (id != 0xffff)
393 wd->ap.staTable[id].txiv[0] = *iv++;
394 wd->ap.staTable[id].txiv[1] = *iv++;
395 wd->ap.staTable[id].txiv[2] = *iv++;
396 wd->ap.staTable[id].txiv[3] = *iv;
399 zmw_leave_critical_section(dev);
401 return;
403 #endif //ZM_ENABLE_CENC
406 /************************************************************************/
407 /* */
408 /* FUNCTION DESCRIPTION zfApFlushBufferedPsFrame */
409 /* Free buffered PS frames. */
410 /* */
411 /* INPUTS */
412 /* dev : device pointer */
413 /* */
414 /* OUTPUTS */
415 /* None */
416 /* */
417 /* AUTHOR */
418 /* Stephen Chen Atheros Communications, INC. 2007.1 */
419 /* */
420 /************************************************************************/
421 void zfApFlushBufferedPsFrame(zdev_t* dev)
423 u16_t emptyFlag;
424 u16_t freeCount;
425 u16_t vap;
426 zbuf_t* psBuf = NULL;
427 zmw_get_wlan_dev(dev);
428 zmw_declare_for_critical_section();
430 freeCount = 0;
431 emptyFlag = 0;
432 while (1)
434 psBuf = NULL;
435 zmw_enter_critical_section(dev);
436 if (wd->ap.uniHead != wd->ap.uniTail)
438 psBuf = wd->ap.uniArray[wd->ap.uniHead];
439 wd->ap.uniHead = (wd->ap.uniHead + 1) & (ZM_UNI_ARRAY_SIZE - 1);
441 else
443 emptyFlag = 1;
445 zmw_leave_critical_section(dev);
447 if (psBuf != NULL)
449 zfwBufFree(dev, psBuf, ZM_ERR_FLUSH_PS_QUEUE);
451 zm_assert(freeCount++ < (ZM_UNI_ARRAY_SIZE*2));
453 if (emptyFlag != 0)
455 break;
459 for (vap=0; vap<ZM_MAX_AP_SUPPORT; vap++)
461 freeCount = 0;
462 emptyFlag = 0;
463 while (1)
465 psBuf = NULL;
466 zmw_enter_critical_section(dev);
467 if (wd->ap.bcmcHead[vap] != wd->ap.bcmcTail[vap])
469 psBuf = wd->ap.bcmcArray[vap][wd->ap.bcmcHead[vap]];
470 wd->ap.bcmcHead[vap] = (wd->ap.bcmcHead[vap] + 1)
471 & (ZM_BCMC_ARRAY_SIZE - 1);
473 else
475 emptyFlag = 1;
477 zmw_leave_critical_section(dev);
479 if (psBuf != NULL)
481 zfwBufFree(dev, psBuf, ZM_ERR_FLUSH_PS_QUEUE);
483 zm_assert(freeCount++ < (ZM_BCMC_ARRAY_SIZE*2));
485 if (emptyFlag != 0)
487 break;
491 return;
495 u16_t zfApBufferPsFrame(zdev_t* dev, zbuf_t* buf, u16_t port)
497 u16_t id;
498 u16_t addr[3];
499 u16_t vap = 0;
500 u8_t up;
501 u16_t fragOff;
502 u8_t ac;
503 u16_t ret;
505 zmw_get_wlan_dev(dev);
507 zmw_declare_for_critical_section();
509 if (port < ZM_MAX_AP_SUPPORT)
511 vap = port;
514 addr[0] = zmw_rx_buf_readh(dev, buf, 0);
515 addr[1] = zmw_rx_buf_readh(dev, buf, 2);
516 addr[2] = zmw_rx_buf_readh(dev, buf, 4);
518 if ((addr[0] & 0x1) == 0x1)
520 if (wd->ap.staPowerSaving > 0)
522 zmw_enter_critical_section(dev);
524 /* Buffer this BC or MC frame */
525 if (((wd->ap.bcmcTail[vap]+1)&(ZM_BCMC_ARRAY_SIZE-1))
526 != wd->ap.bcmcHead[vap])
528 wd->ap.bcmcArray[vap][wd->ap.bcmcTail[vap]++] = buf;
529 wd->ap.bcmcTail[vap] &= (ZM_BCMC_ARRAY_SIZE-1);
530 zmw_leave_critical_section(dev);
532 zm_msg0_tx(ZM_LV_0, "Buffer BCMC");
534 else
536 /* bcmcArray full */
537 zmw_leave_critical_section(dev);
539 zm_msg0_tx(ZM_LV_0, "BCMC buffer full");
541 /* free buffer according to buffer type */
542 zfwBufFree(dev, buf, ZM_ERR_BCMC_PS_BUFFER_UNAVAILABLE);
544 return 1;
547 else
549 zmw_enter_critical_section(dev);
551 id = zfApFindSta(dev, addr);
552 if (id != 0xffff)
554 if (wd->ap.staTable[id].psMode == 1)
557 zfTxGetIpTosAndFrag(dev, buf, &up, &fragOff);
558 ac = zcUpToAc[up&0x7] & 0x3;
560 if ((wd->ap.staTable[id].qosType == 1) &&
561 ((wd->ap.staTable[id].qosInfo & (0x8>>ac)) != 0))
563 ret = zfQueuePutNcs(dev, wd->ap.uapsdQ, buf, wd->tick);
564 zmw_leave_critical_section(dev);
565 if (ret != ZM_SUCCESS)
567 zfwBufFree(dev, buf, ZM_ERR_AP_UAPSD_QUEUE_FULL);
570 else
572 /* Buffer this unicast frame */
573 if (((wd->ap.uniTail+1)&(ZM_UNI_ARRAY_SIZE-1))
574 != wd->ap.uniHead)
576 wd->ap.uniArray[wd->ap.uniTail++] = buf;
577 wd->ap.uniTail &= (ZM_UNI_ARRAY_SIZE-1);
578 zmw_leave_critical_section(dev);
579 zm_msg0_tx(ZM_LV_0, "Buffer UNI");
582 else
584 /* uniArray full */
585 zmw_leave_critical_section(dev);
586 zm_msg0_tx(ZM_LV_0, "UNI buffer full");
587 /* free buffer according to buffer type */
588 zfwBufFree(dev, buf, ZM_ERR_UNI_PS_BUFFER_UNAVAILABLE);
591 return 1;
592 } /* if (wd->ap.staTable[id++].psMode == 1) */
593 } /* if ((id = zfApFindSta(dev, addr)) != 0xffff) */
594 zmw_leave_critical_section(dev);
597 return 0;
600 u16_t zfApGetSTAInfoAndUpdatePs(zdev_t* dev, u16_t* addr, u16_t* state,
601 u8_t* vap, u16_t psMode, u8_t* uapsdTrig)
603 u16_t id;
604 u8_t uapsdStaAwake = 0;
606 zmw_get_wlan_dev(dev);
608 zmw_declare_for_critical_section();
610 zmw_enter_critical_section(dev);
612 #ifdef ZM_AP_DEBUG
613 //psMode=0;
614 #endif
616 id = zfApFindSta(dev, addr);
617 if (id != 0xffff)
619 if (psMode != 0)
621 zm_msg0_mm(ZM_LV_0, "psMode = 1");
622 if (wd->ap.staTable[id].psMode == 0)
624 wd->ap.staPowerSaving++;
626 else
628 if (wd->ap.staTable[id].qosType == 1)
630 zm_msg0_mm(ZM_LV_0, "UAPSD trigger");
631 *uapsdTrig = wd->ap.staTable[id].qosInfo;
635 else
637 if (wd->ap.staTable[id].psMode != 0)
639 wd->ap.staPowerSaving--;
640 if ((wd->ap.staTable[id].qosType == 1) && ((wd->ap.staTable[id].qosInfo&0xf)!=0))
642 uapsdStaAwake = 1;
647 wd->ap.staTable[id].psMode = (u8_t) psMode;
648 wd->ap.staTable[id].time = wd->tick;
649 *vap = wd->ap.staTable[id].vap;
650 *state = wd->ap.staTable[id++].state;
653 zmw_leave_critical_section(dev);
655 if (uapsdStaAwake == 1)
657 zbuf_t* psBuf;
658 u8_t mb;
660 while (1)
662 psBuf = zfQueueGetWithMac(dev, wd->ap.uapsdQ, (u8_t*)addr, &mb);
663 if (psBuf != NULL)
665 zfTxSendEth(dev, psBuf, 0, ZM_EXTERNAL_ALLOC_BUF, 0);
667 else
669 break;
674 return id;
677 /************************************************************************/
678 /* */
679 /* FUNCTION DESCRIPTION zfApGetNewSta */
680 /* Get a new STA from station table. */
681 /* */
682 /* INPUTS */
683 /* dev : device pointer */
684 /* */
685 /* OUTPUTS */
686 /* 0xffff : fail */
687 /* other : STA table index */
688 /* */
689 /* AUTHOR */
690 /* Stephen Chen ZyDAS Technology Corporation 2005.10 */
691 /* */
692 /************************************************************************/
693 u16_t zfApGetNewSta(zdev_t* dev)
695 u16_t i;
697 zmw_get_wlan_dev(dev);
699 for (i=0; i<ZM_MAX_STA_SUPPORT; i++)
701 if (wd->ap.staTable[i].valid == 0)
703 zm_msg2_mm(ZM_LV_0, "zfApGetNewSta=", i);
704 return i;
707 return 0xffff;
711 /************************************************************************/
712 /* */
713 /* FUNCTION DESCRIPTION zfApAddSta */
714 /* Add a STA to station table. */
715 /* */
716 /* INPUTS */
717 /* dev : device pointer */
718 /* addr : STA MAC address */
719 /* state : STA state */
720 /* apId : Virtual AP ID */
721 /* type : 0=>11b, 1=>11g */
722 /* */
723 /* OUTPUTS */
724 /* 0xffff : fail */
725 /* Other : index */
726 /* */
727 /* AUTHOR */
728 /* Stephen Chen ZyDAS Technology Corporation 2005.10 */
729 /* */
730 /************************************************************************/
731 u16_t zfApAddSta(zdev_t* dev, u16_t* addr, u16_t state, u16_t apId, u8_t type,
732 u8_t qosType, u8_t qosInfo)
734 u16_t index;
735 u16_t i;
737 zmw_get_wlan_dev(dev);
739 zmw_declare_for_critical_section();
741 zm_msg1_mm(ZM_LV_0, "STA type=", type);
743 zmw_enter_critical_section(dev);
745 index = zfApFindSta(dev, addr);
746 if (index != 0xffff)
748 zm_msg0_mm(ZM_LV_2, "found");
749 /* Update STA state */
750 if ((state == ZM_STATE_AUTH) || (state == ZM_STATE_PREAUTH))
752 wd->ap.staTable[index].state = state;
753 wd->ap.staTable[index].time = wd->tick;
754 wd->ap.staTable[index].vap = (u8_t)apId;
756 else if (state == ZM_STATE_ASOC)
758 if ((wd->ap.staTable[index].state == ZM_STATE_AUTH))
759 //&& (wd->ap.staTable[index].vap == apId))
761 wd->ap.staTable[index].state = state;
762 wd->ap.staTable[index].time = wd->tick;
763 wd->ap.staTable[index].qosType = qosType;
764 wd->ap.staTable[index].vap = (u8_t)apId;
765 wd->ap.staTable[index].staType = type;
766 wd->ap.staTable[index].qosInfo = qosInfo;
768 if (wd->frequency < 3000)
770 /* Init 11b/g */
771 zfRateCtrlInitCell(dev, &wd->ap.staTable[index].rcCell, type, 1, 1);
773 else
775 /* Init 11a */
776 zfRateCtrlInitCell(dev, &wd->ap.staTable[index].rcCell, type, 0, 1);
779 if (wd->zfcbApConnectNotify != NULL)
781 wd->zfcbApConnectNotify(dev, (u8_t*)addr, apId);
784 else
786 index = 0xffff;
790 else
792 zm_msg0_mm(ZM_LV_2, "Not found");
793 if ((state == ZM_STATE_AUTH) || (state == ZM_STATE_PREAUTH))
795 /* Get a new STA and update state */
796 index = zfApGetNewSta(dev);
797 zm_msg2_mm(ZM_LV_1, "new STA index=", index);
799 if (index != 0xffff)
801 for (i=0; i<3; i++)
803 wd->ap.staTable[index].addr[i] = addr[i];
805 wd->ap.staTable[index].state = state;
806 wd->ap.staTable[index].valid = 1;
807 wd->ap.staTable[index].time = wd->tick;
808 wd->ap.staTable[index].vap = (u8_t)apId;
809 wd->ap.staTable[index].encryMode = ZM_NO_WEP;
814 zmw_leave_critical_section(dev);
816 return index;
820 /************************************************************************/
821 /* */
822 /* FUNCTION DESCRIPTION zfApAgingSta */
823 /* Aging STA in station table. */
824 /* */
825 /* INPUTS */
826 /* dev : device pointer */
827 /* */
828 /* OUTPUTS */
829 /* number of 11b STA in STA table */
830 /* */
831 /* AUTHOR */
832 /* Stephen Chen ZyDAS Technology Corporation 2005.10 */
833 /* */
834 /************************************************************************/
835 void zfApAgingSta(zdev_t* dev)
837 u16_t i;
838 u32_t deltaMs;
839 u16_t addr[3];
840 u16_t txFlag;
841 u16_t psStaCount = 0;
843 zmw_get_wlan_dev(dev);
845 zmw_declare_for_critical_section();
847 wd->ap.gStaAssociated = wd->ap.bStaAssociated = 0;
849 for (i=0; i<ZM_MAX_STA_SUPPORT; i++)
851 txFlag = 0;
852 zmw_enter_critical_section(dev);
853 if (wd->ap.staTable[i].valid == 1)
855 addr[0] = wd->ap.staTable[i].addr[0];
856 addr[1] = wd->ap.staTable[i].addr[1];
857 addr[2] = wd->ap.staTable[i].addr[2];
858 /* millisecond */
859 deltaMs = (u32_t)((u32_t)wd->tick-(u32_t)wd->ap.staTable[i].time)
860 * ZM_MS_PER_TICK;
862 /* preauth */
863 if ((wd->ap.staTable[i].state == ZM_STATE_PREAUTH)
864 && (deltaMs > ZM_PREAUTH_TIMEOUT_MS))
866 /* Aging STA */
867 wd->ap.staTable[i].valid = 0;
868 wd->ap.authSharing = 0;
869 txFlag = 1;
872 /* auth */
873 if ((wd->ap.staTable[i].state == ZM_STATE_AUTH)
874 && (deltaMs > ZM_AUTH_TIMEOUT_MS))
876 /* Aging STA */
877 wd->ap.staTable[i].valid = 0;
878 txFlag = 1;
881 /* asoc */
882 if (wd->ap.staTable[i].state == ZM_STATE_ASOC)
884 if (wd->ap.staTable[i].psMode != 0)
886 psStaCount++;
889 if (deltaMs > ((u32_t)wd->ap.staAgingTimeSec<<10))
891 /* Aging STA */
892 zm_msg1_mm(ZM_LV_0, "Age STA index=", i);
893 wd->ap.staTable[i].valid = 0;
894 txFlag = 1;
896 else if (deltaMs > ((u32_t)wd->ap.staProbingTimeSec<<10))
898 if (wd->ap.staTable[i].psMode == 0)
900 /* Probing non-PS STA */
901 zm_msg1_mm(ZM_LV_0, "Probing STA index=", i);
902 wd->ap.staTable[i].time +=
903 (wd->ap.staProbingTimeSec * ZM_TICK_PER_SECOND);
904 txFlag = 2;
911 zmw_leave_critical_section(dev);
913 if (txFlag == 1)
915 /* Send deauthentication management frame */
916 zfSendMmFrame(dev, ZM_WLAN_FRAME_TYPE_DEAUTH, addr, 4, 0, 0);
918 else if (txFlag == 2)
920 zfSendMmFrame(dev, ZM_WLAN_DATA_FRAME, addr, 0, 0, 0);
925 wd->ap.staPowerSaving = psStaCount;
927 return;
930 void zfApProtctionMonitor(zdev_t* dev)
932 zmw_get_wlan_dev(dev);
934 /* 11b STA associated => nonErp, Protect */
935 if (wd->ap.bStaAssociated > 0)
937 /* Enable NonErp bit in information element */
938 wd->erpElement = ZM_WLAN_NON_ERP_PRESENT_BIT
939 | ZM_WLAN_USE_PROTECTION_BIT;
941 /* Enable protection mode */
942 zfApSetProtectionMode(dev, 1);
945 /* 11b STA not associated, protection OBSS present => Protect */
946 else if (wd->ap.protectedObss > 2) //Threshold
948 if (wd->disableSelfCts == 0)
950 /* Disable NonErp bit in information element */
951 wd->erpElement = ZM_WLAN_USE_PROTECTION_BIT;
953 /* Enable protection mode */
954 zfApSetProtectionMode(dev, 1);
957 else
959 /* Disable NonErp bit in information element */
960 wd->erpElement = 0;
962 /* Disable protection mode */
963 zfApSetProtectionMode(dev, 0);
965 wd->ap.protectedObss = 0;
969 void zfApProcessBeacon(zdev_t* dev, zbuf_t* buf)
971 u16_t offset;
972 u8_t ch;
974 zmw_get_wlan_dev(dev);
976 zm_msg0_mm(ZM_LV_3, "Rx beacon");
978 /* update Non-ERP flag(wd->ap.nonErpObss) */
979 offset = zfFindElement(dev, buf, ZM_WLAN_EID_ERP);
980 if (offset == 0xffff)
982 /* 11b OBSS */
983 wd->ap.protectedObss++;
984 return;
987 ch = zmw_rx_buf_readb(dev, buf, offset+2);
988 if ((ch & ZM_WLAN_USE_PROTECTION_BIT) == ZM_WLAN_USE_PROTECTION_BIT)
990 /* Protected OBSS */
991 wd->ap.protectedObss = 1;
994 return;
998 /************************************************************************/
999 /* */
1000 /* FUNCTION DESCRIPTION zfProcessAuth */
1001 /* Process authenticate management frame. */
1002 /* */
1003 /* INPUTS */
1004 /* dev : device pointer */
1005 /* buf : auth frame buffer */
1006 /* */
1007 /* OUTPUTS */
1008 /* none */
1009 /* */
1010 /* AUTHOR */
1011 /* Stephen Chen ZyDAS Technology Corporation 2005.10 */
1012 /* */
1013 /************************************************************************/
1014 /* Note : AP allows one authenticating STA at a time, does not */
1015 /* support multiple authentication process. Make sure */
1016 /* authentication state machine will not be blocked due */
1017 /* to incompleted authentication handshake. */
1018 void zfApProcessAuth(zdev_t* dev, zbuf_t* buf, u16_t* src, u16_t apId)
1020 u16_t algo, seq, status;
1021 u8_t authSharing;
1022 u16_t ret;
1023 u16_t i;
1024 u8_t challengePassed = 0;
1025 u8_t frameCtrl;
1026 u32_t retAlgoSeq;
1027 u32_t retStatus;
1028 zmw_get_wlan_dev(dev);
1029 zmw_declare_for_critical_section();
1032 frameCtrl = zmw_rx_buf_readb(dev, buf, 1);
1033 /* AP : Auth share 3 */
1034 /* shift for WEP IV */
1035 if ((frameCtrl & 0x40) != 0)
1037 algo = zmw_rx_buf_readh(dev, buf, 28);
1038 seq = zmw_rx_buf_readh(dev, buf, 30);
1039 status = zmw_rx_buf_readh(dev, buf, 32);
1041 else
1043 algo = zmw_rx_buf_readh(dev, buf, 24);
1044 seq = zmw_rx_buf_readh(dev, buf, 26);
1045 status = zmw_rx_buf_readh(dev, buf, 28);
1048 zm_msg2_mm(ZM_LV_0, "Rx Auth, seq=", seq);
1050 /* Set default to authentication algorithm not support */
1051 retAlgoSeq = 0x20000 | algo;
1052 retStatus = 13; /* authentication algorithm not support */
1054 /* AP : Auth open 1 */
1055 if (algo == 0)
1057 if (wd->ap.authAlgo[apId] == 0)
1059 retAlgoSeq = 0x20000;
1060 if (seq == 1)
1062 /* AP : update STA to auth */
1063 ret = zfApAddSta(dev, src, ZM_STATE_AUTH, apId, 0, 0, 0);
1064 if (ret != 0xffff)
1066 /* AP : call zfwAuthNotify() for host to judge */
1067 //zfwAuthNotify(dev, src);
1069 /* AP : response Auth seq=2, success */
1070 retStatus = 0;
1073 else
1075 /* AP : response Auth seq=2, unspecific error */
1076 retStatus = 1;
1079 else
1081 /* AP : response Auth seq=2, sequence number out of expected */
1082 retStatus = 14;
1086 /* AP : Auth share 1 */
1087 else if (algo == 1)
1089 if (wd->ap.authAlgo[apId] == 1)
1091 if (seq == 1)
1093 retAlgoSeq = 0x20001;
1095 /* critical section */
1096 zmw_enter_critical_section(dev);
1097 if (wd->ap.authSharing == 1)
1099 authSharing = 1;
1101 else
1103 authSharing = 0;
1104 wd->ap.authSharing = 1;
1106 /* end of critical section */
1107 zmw_leave_critical_section(dev);
1109 if (authSharing == 1)
1111 /* AP : response Auth seq=2, status = fail */
1112 retStatus = 1;
1114 else
1116 /* AP : update STA to preauth */
1117 zfApAddSta(dev, src, ZM_STATE_PREAUTH, apId, 0, 0, 0);
1119 /* AP : call zfwAuthNotify() for host to judge */
1120 //zfwAuthNotify(dev, src);
1122 /* AP : response Auth seq=2 */
1123 retStatus = 0;
1126 else if (seq == 3)
1128 retAlgoSeq = 0x40001;
1130 if (wd->ap.authSharing == 1)
1132 /* check challenge text */
1133 if (zmw_buf_readh(dev, buf, 30+4) == 0x8010)
1135 for (i=0; i<128; i++)
1137 if (wd->ap.challengeText[i]
1138 != zmw_buf_readb(dev, buf, 32+i+4))
1140 break;
1143 if (i == 128)
1145 challengePassed = 1;
1149 if (challengePassed == 1)
1151 /* AP : update STA to auth */
1152 zfApAddSta(dev, src, ZM_STATE_AUTH, apId, 0, 0, 0);
1154 /* AP : response Auth seq=2 */
1155 retStatus = 0;
1157 else
1159 /* AP : response Auth seq=2, challenge failure */
1160 retStatus = 15;
1162 /* TODO : delete STA */
1165 wd->ap.authSharing = 0;
1168 else
1170 retAlgoSeq = 0x40001;
1171 retStatus = 14;
1176 zfSendMmFrame(dev, ZM_WLAN_FRAME_TYPE_AUTH, src, retAlgoSeq,
1177 retStatus, apId);
1178 return;
1181 void zfApProcessAsocReq(zdev_t* dev, zbuf_t* buf, u16_t* src, u16_t apId)
1183 u16_t aid = 0xffff;
1184 u8_t frameType;
1185 u16_t offset;
1186 u8_t staType = 0;
1187 u8_t qosType = 0;
1188 u8_t qosInfo = 0;
1189 u8_t tmp;
1190 u16_t i, j, k;
1191 u16_t encMode = 0;
1193 zmw_get_wlan_dev(dev);
1194 /* AP : check SSID */
1195 offset = zfFindElement(dev, buf, ZM_WLAN_EID_SSID);
1196 if (offset != 0xffff)
1198 k = 0;
1199 for (j = 0; j < wd->ap.vapNumber; j++)
1201 tmp = zmw_buf_readb(dev, buf, offset+1);
1202 if (tmp
1203 != wd->ap.ssidLen[j])
1205 k++;
1208 if (k == wd->ap.vapNumber)
1210 goto zlDeauth;
1213 k = 0;
1214 for (j = 0; j < wd->ap.vapNumber; j++)
1216 for (i=0; i<wd->ap.ssidLen[j]; i++)
1218 tmp = zmw_buf_readb(dev, buf, offset+2+i);
1219 if (tmp
1220 != wd->ap.ssid[j][i])
1222 break;
1225 if (i == wd->ap.ssidLen[j])
1227 apId = j;
1229 else
1231 k++;
1234 if (k == wd->ap.vapNumber)
1236 goto zlDeauth;
1240 /* TODO : check capability */
1242 /* AP : check support rate */
1243 offset = zfFindElement(dev, buf, ZM_WLAN_EID_EXTENDED_RATE);
1244 if (offset != 0xffff)
1246 /* 11g STA */
1247 staType = 1;
1249 //CWYang(+)
1250 offset = zfFindElement(dev, buf, ZM_WLAN_EID_HT_CAPABILITY);
1251 if (offset != 0xffff)
1253 /* 11n STA */
1254 staType = 2;
1257 /* TODO : do not allow 11b STA to associated in Pure G mode */
1258 if (wd->ap.wlanType[apId] == ZM_WLAN_TYPE_PURE_G && staType == 0)
1260 zfSendMmFrame(dev, ZM_WLAN_FRAME_TYPE_DEAUTH, src, 3, 0, 0);
1261 return;
1264 /* In pure B mode, we set G STA into B mode */
1265 if (wd->ap.wlanType[apId] == ZM_WLAN_TYPE_PURE_B && staType == 1)
1267 staType = 0;
1270 /* AP : check 11i and WPA */
1271 /* AP : check 11h */
1273 /* AP : check WME */
1274 offset = zfFindWifiElement(dev, buf, 2, 0);
1275 if (offset != 0xffff)
1277 /* WME STA */
1278 qosType = 1;
1279 zm_msg0_mm(ZM_LV_0, "WME STA");
1281 if (wd->ap.uapsdEnabled != 0)
1283 qosInfo = zmw_rx_buf_readb(dev, buf, offset+8);
1287 if (wd->ap.wpaSupport[apId] == 1)
1289 offset = zfFindElement(dev, buf, ZM_WLAN_EID_WPA_IE);
1290 if (offset != 0xffff)
1292 /* get WPA IE */
1293 u8_t length = zmw_rx_buf_readb(dev, buf, offset+1);
1294 if (length+2 < ZM_MAX_WPAIE_SIZE)
1296 zfCopyFromRxBuffer(dev, buf, wd->ap.stawpaIe[apId], offset, length+2);
1297 wd->ap.stawpaLen[apId] = length+2;
1298 encMode = 1;
1301 zm_msg1_mm(ZM_LV_0, "WPA Mode zfwAsocNotify, apId=", apId);
1303 /* AP : Call zfwAsocNotify() */
1304 if (wd->zfcbAsocNotify != NULL)
1306 wd->zfcbAsocNotify(dev, src, wd->ap.stawpaIe[apId], wd->ap.stawpaLen[apId], apId);
1309 else
1311 goto zlDeauth;
1314 else if ( (offset = zfFindElement(dev, buf, ZM_WLAN_EID_RSN_IE)) != 0xffff )
1316 /* get RSN IE */
1317 u8_t length = zmw_rx_buf_readb(dev, buf, offset+1);
1318 if (length+2 < ZM_MAX_WPAIE_SIZE)
1320 zfCopyFromRxBuffer(dev, buf, wd->ap.stawpaIe[apId], offset, length+2);
1321 wd->ap.stawpaLen[apId] = length+2;
1322 encMode = 1;
1324 zm_msg1_mm(ZM_LV_0, "RSN Mode zfwAsocNotify, apId=", apId);
1326 /* AP : Call zfwAsocNotify() */
1327 if (wd->zfcbAsocNotify != NULL)
1329 wd->zfcbAsocNotify(dev, src, wd->ap.stawpaIe[apId], wd->ap.stawpaLen[apId], apId);
1332 else
1334 goto zlDeauth;
1337 #ifdef ZM_ENABLE_CENC
1338 else if ( (offset = zfFindElement(dev, buf, ZM_WLAN_EID_CENC_IE)) != 0xffff )
1340 /* get CENC IE */
1341 u8_t length = zmw_rx_buf_readb(dev, buf, offset+1);
1343 if (length+2 < ZM_MAX_WPAIE_SIZE)
1345 zfCopyFromRxBuffer(dev, buf, wd->ap.stawpaIe[apId], offset, length+2);
1346 wd->ap.stawpaLen[apId] = length+2;
1347 encMode = 1;
1349 zm_msg1_mm(ZM_LV_0, "CENC Mode zfwAsocNotify, apId=", apId);
1351 /* AP : Call zfwAsocNotify() */
1352 if (wd->zfcbCencAsocNotify != NULL)
1354 wd->zfcbCencAsocNotify(dev, src, wd->ap.stawpaIe[apId],
1355 wd->ap.stawpaLen[apId], apId);
1358 else
1360 goto zlDeauth;
1363 #endif //ZM_ENABLE_CENC
1364 else
1365 { /* ap is encryption but sta has no wpa/rsn ie */
1366 zfSendMmFrame(dev, ZM_WLAN_FRAME_TYPE_DEAUTH, src, 6, 0, 0);
1367 return;
1370 /* sta has wpa/rsn ie but ap is no encryption */
1371 if ((wd->ap.wpaSupport[apId] == 0) && (encMode == 1))
1373 zfSendMmFrame(dev, ZM_WLAN_FRAME_TYPE_DEAUTH, src, 6, 0, 0);
1374 return;
1377 /* AP : update STA to asoc */
1378 aid = zfApAddSta(dev, src, ZM_STATE_ASOC, apId, staType, qosType, qosInfo);
1380 zfApStoreAsocReqIe(dev, buf, aid);
1382 zlDeauth:
1383 /* AP : send asoc rsp2 */
1384 if (aid != 0xffff)
1386 frameType = zmw_rx_buf_readb(dev, buf, 0);
1388 if (frameType == ZM_WLAN_FRAME_TYPE_ASOCREQ)
1390 zfSendMmFrame(dev, ZM_WLAN_FRAME_TYPE_ASOCRSP, src, 0, aid+1, apId);
1392 else
1394 zfSendMmFrame(dev, ZM_WLAN_FRAME_TYPE_REASOCRSP, src, 0, aid+1, apId);
1397 else
1399 /* TODO : send deauthentication */
1400 zfSendMmFrame(dev, ZM_WLAN_FRAME_TYPE_DEAUTH, src, 6, 0, 0);
1403 return;
1406 void zfApStoreAsocReqIe(zdev_t* dev, zbuf_t* buf, u16_t aid)
1408 //struct zsWlanAssoFrameHeader* pAssoFrame;
1409 //u8_t pBuf[sizeof(struct zsWlanAssoFrameHeader)];
1410 u16_t offset;
1411 u32_t i;
1412 u16_t length;
1413 u8_t *htcap;
1415 zmw_get_wlan_dev(dev);
1417 for (i=0; i<wd->sta.asocRspFrameBodySize; i++)
1419 wd->sta.asocRspFrameBody[i] = zmw_rx_buf_readb(dev, buf, i+24);
1421 /* capability: 2 octets */
1422 offset = 24;
1424 /* Listen interval: 2 octets */
1425 offset = 26;
1427 /* SSID */
1428 offset = 28;
1430 /* supported rates */
1431 offset = zfFindElement(dev, buf, ZM_WLAN_EID_SUPPORT_RATE);
1432 if (offset == 0xffff)
1433 return;
1434 length = zmw_rx_buf_readb(dev, buf, offset + 1);
1436 /* extended supported rates */
1437 offset = zfFindElement(dev, buf, ZM_WLAN_EID_EXTENDED_RATE);
1438 if (offset == 0xffff)
1439 return;
1440 length = zmw_rx_buf_readb(dev, buf, offset + 1);
1442 /* power capability:4 octets */
1443 offset = offset + 2 + length;
1445 /* supported channels: 4 octets */
1446 offset = offset + 2 + 4;
1448 /* RSN */
1450 /* QoS */
1452 /* HT capabilities: 28 octets */
1453 offset = zfFindElement(dev, buf, ZM_WLAN_EID_HT_CAPABILITY);
1454 if (offset != 0xffff) {
1455 /* atheros pre n */
1456 htcap = (u8_t *)&wd->ap.ie[aid].HtCap;
1457 htcap[0] = zmw_rx_buf_readb(dev, buf, offset);
1458 htcap[1] = 26;
1459 for (i=1; i<=26; i++)
1461 htcap[i+1] = zmw_rx_buf_readb(dev, buf, offset + i);
1462 zm_debug_msg2("ASOC: HT Capabilities, htcap=", htcap[i+1]);
1464 return;
1466 else if ((offset = zfFindElement(dev, buf, ZM_WLAN_PREN2_EID_HTCAPABILITY)) != 0xffff) {
1467 /* pre n 2.0 standard */
1468 htcap = (u8_t *)&wd->ap.ie[aid].HtCap;
1469 for (i=0; i<28; i++)
1471 htcap[i] = zmw_rx_buf_readb(dev, buf, offset + i);
1472 zm_debug_msg2("ASOC: HT Capabilities, htcap=", htcap[i]);
1475 else {
1476 /* not 11n AP */
1477 return;
1481 /* supported regulatory classes */
1482 offset = offset + length;
1483 //length = zmw_rx_buf_readb(dev, buf, offset + 1);
1485 u8_t *htcap;
1486 htcap = (u8_t *)&wd->sta.ie.HtInfo;
1487 //zm_debug_msg2("ASOC: HT Capabilities info=", ((u16_t *)htcap)[1]);
1488 //zm_debug_msg2("ASOC: A-MPDU parameters=", htcap[4]);
1489 //zm_debug_msg2("ASOC: Supported MCS set=", ((u32_t *)htcap)[1]>>8);
1494 void zfApProcessAsocRsp(zdev_t* dev, zbuf_t* buf)
1499 void zfApProcessDeauth(zdev_t* dev, zbuf_t* buf, u16_t* src, u16_t apId)
1501 u16_t aid;
1502 zmw_get_wlan_dev(dev);
1503 zmw_declare_for_critical_section();
1505 zmw_enter_critical_section(dev);
1506 /* AP : if SA=associated STA then deauthenticate STA */
1507 aid = zfApFindSta(dev, src);
1508 if (aid != 0xffff)
1510 /* Clear STA table */
1511 wd->ap.staTable[aid].valid = 0;
1512 if (wd->zfcbDisAsocNotify != NULL)
1514 wd->zfcbDisAsocNotify(dev, (u8_t*)src, apId);
1517 zmw_leave_critical_section(dev);
1521 void zfApProcessDisasoc(zdev_t* dev, zbuf_t* buf, u16_t* src, u16_t apId)
1523 u16_t aid;
1524 zmw_get_wlan_dev(dev);
1525 zmw_declare_for_critical_section();
1527 zmw_enter_critical_section(dev);
1528 /* AP : if SA=associated STA then deauthenticate STA */
1529 aid = zfApFindSta(dev, src);
1530 if (aid != 0xffff)
1532 /* Clear STA table */
1533 wd->ap.staTable[aid].valid = 0;
1534 zmw_leave_critical_section(dev);
1535 if (wd->zfcbDisAsocNotify != NULL)
1537 wd->zfcbDisAsocNotify(dev, (u8_t*)src, apId);
1540 zmw_leave_critical_section(dev);
1545 void zfApProcessProbeRsp(zdev_t* dev, zbuf_t* buf, struct zsAdditionInfo* AddInfo)
1549 /************************************************************************/
1550 /* */
1551 /* FUNCTION DESCRIPTION zfApAddIeSsid */
1552 /* Add AP information element SSID to buffer. */
1553 /* */
1554 /* INPUTS */
1555 /* dev : device pointer */
1556 /* buf : buffer to add information element */
1557 /* offset : add information element from this offset */
1558 /* vap : virtual AP ID */
1559 /* */
1560 /* OUTPUTS */
1561 /* buffer offset after adding information element */
1562 /* */
1563 /* AUTHOR */
1564 /* Stephen Chen ZyDAS Technology Corporation 2005.11 */
1565 /* */
1566 /************************************************************************/
1567 u16_t zfApAddIeSsid(zdev_t* dev, zbuf_t* buf, u16_t offset, u16_t vap)
1569 u16_t i;
1571 zmw_get_wlan_dev(dev);
1573 /* Element ID */
1574 zmw_tx_buf_writeb(dev, buf, offset++, ZM_WLAN_EID_SSID);
1576 /* Element Length */
1577 zmw_tx_buf_writeb(dev, buf, offset++, wd->ap.ssidLen[vap]);
1579 /* Information : SSID */
1580 for (i=0; i<wd->ap.ssidLen[vap]; i++)
1582 zmw_tx_buf_writeb(dev, buf, offset++, wd->ap.ssid[vap][i]);
1585 return offset;
1589 /************************************************************************/
1590 /* */
1591 /* FUNCTION DESCRIPTION zfApAddIeTim */
1592 /* Add AP information element TIM to buffer. */
1593 /* */
1594 /* INPUTS */
1595 /* dev : device pointer */
1596 /* buf : buffer to add information element */
1597 /* offset : add information element from this offset */
1598 /* vap : virtual AP ID */
1599 /* */
1600 /* OUTPUTS */
1601 /* buffer offset after adding information element */
1602 /* */
1603 /* AUTHOR */
1604 /* Stephen Chen ZyDAS Technology Corporation 2005.11 */
1605 /* */
1606 /************************************************************************/
1607 u16_t zfApAddIeTim(zdev_t* dev, zbuf_t* buf, u16_t offset, u16_t vap)
1609 u8_t uniBitMap[9];
1610 u16_t highestByte;
1611 u16_t i;
1612 u16_t lenOffset;
1613 u16_t id;
1614 u16_t dst[3];
1615 u16_t aid;
1616 u16_t bitPosition;
1617 u16_t bytePosition;
1618 zbuf_t* psBuf;
1619 zbuf_t* tmpBufArray[ZM_UNI_ARRAY_SIZE];
1620 u16_t tmpBufArraySize = 0;
1622 zmw_get_wlan_dev(dev);
1624 zmw_declare_for_critical_section();
1626 /* Element ID */
1627 zmw_tx_buf_writeb(dev, buf, offset++, ZM_WLAN_EID_TIM);
1629 /* offset of Element Length */
1630 lenOffset = offset++;
1632 /* Information : TIM */
1633 /* DTIM count */
1634 /* TODO : Doesn't work for Virtual AP's case */
1635 wd->CurrentDtimCount++;
1636 if (wd->CurrentDtimCount >= wd->dtim)
1638 wd->CurrentDtimCount = 0;
1640 zmw_tx_buf_writeb(dev, buf, offset++, wd->CurrentDtimCount);
1641 /* DTIM period */
1642 zmw_tx_buf_writeb(dev, buf, offset++, wd->dtim);
1643 /* bitmap offset */
1644 zmw_tx_buf_writeb(dev, buf, offset++, 0);
1646 /* Update BCMC bit */
1647 if (wd->CurrentDtimCount == 0)
1649 zmw_enter_critical_section(dev);
1650 wd->ap.timBcmcBit[vap] = (wd->ap.bcmcTail[vap]!=wd->ap.bcmcHead[vap])?1:0;
1651 zmw_leave_critical_section(dev);
1653 else
1655 wd->ap.timBcmcBit[vap] = 0;
1658 /* Update Unicast bitmap */
1659 /* reset bit map */
1660 for (i=0; i<9; i++)
1662 uniBitMap[i] = 0;
1664 highestByte = 0;
1666 zmw_enter_critical_section(dev);
1668 id = wd->ap.uniHead;
1669 while (id != wd->ap.uniTail)
1671 psBuf = wd->ap.uniArray[id];
1673 /* TODO : Aging PS frame after queuing for more than 10 seconds */
1675 /* get destination STA's aid */
1676 dst[0] = zmw_tx_buf_readh(dev, psBuf, 0);
1677 dst[1] = zmw_tx_buf_readh(dev, psBuf, 2);
1678 dst[2] = zmw_tx_buf_readh(dev, psBuf, 4);
1679 aid = zfApFindSta(dev, dst);
1680 if (aid != 0xffff)
1682 if (wd->ap.staTable[aid].psMode != 0)
1684 zm_msg1_mm(ZM_LV_0, "aid=",aid);
1685 aid++;
1686 zm_assert(aid<=64);
1687 bitPosition = (1 << (aid & 0x7));
1688 bytePosition = (aid >> 3);
1689 uniBitMap[bytePosition] |= bitPosition;
1691 if (bytePosition>highestByte)
1693 highestByte = bytePosition;
1695 id = (id+1) & (ZM_UNI_ARRAY_SIZE-1);
1697 else
1699 zm_msg0_mm(ZM_LV_0, "Send PS frame which STA no longer in PS mode");
1700 /* Send PS frame which STA no longer in PS mode */
1701 zfApRemoveFromPsQueue(dev, id, dst);
1702 tmpBufArray[tmpBufArraySize++] = psBuf;
1705 else
1707 zm_msg0_mm(ZM_LV_0, "Free garbage PS frame");
1708 /* Free garbage PS frame */
1709 zfApRemoveFromPsQueue(dev, id, dst);
1710 zfwBufFree(dev, psBuf, 0);
1714 zmw_leave_critical_section(dev);
1716 zfQueueGenerateUapsdTim(dev, wd->ap.uapsdQ, uniBitMap, &highestByte);
1718 zm_msg1_mm(ZM_LV_3, "bm=",uniBitMap[0]);
1719 zm_msg1_mm(ZM_LV_3, "highestByte=",highestByte);
1720 zm_msg1_mm(ZM_LV_3, "timBcmcBit[]=",wd->ap.timBcmcBit[vap]);
1722 /* bitmap */
1723 zmw_tx_buf_writeb(dev, buf, offset++,
1724 uniBitMap[0] | wd->ap.timBcmcBit[vap]);
1725 for (i=0; i<highestByte; i++)
1727 zmw_tx_buf_writeb(dev, buf, offset++, uniBitMap[i+1]);
1730 /* Element Length */
1731 zmw_tx_buf_writeb(dev, buf, lenOffset, highestByte+4);
1733 for (i=0; i<tmpBufArraySize; i++)
1735 /* Put to VTXQ[ac] */
1736 zfPutVtxq(dev, tmpBufArray[i]);
1738 /* Push VTXQ[ac] */
1739 zfPushVtxq(dev);
1741 return offset;
1746 /************************************************************************/
1747 /* */
1748 /* FUNCTION DESCRIPTION zfApRemoveFromPsQueue */
1749 /* Remove zbuf from PS queue. */
1750 /* */
1751 /* INPUTS */
1752 /* dev : device pointer */
1753 /* id : index in ps queue */
1754 /* */
1755 /* OUTPUTS */
1756 /* more data bit */
1757 /* */
1758 /* AUTHOR */
1759 /* Stephen Chen Atheros Communications, INC. 2007.1 */
1760 /* */
1761 /************************************************************************/
1762 u8_t zfApRemoveFromPsQueue(zdev_t* dev, u16_t id, u16_t* addr)
1764 u16_t dst[3];
1765 u16_t nid;
1766 u8_t moreData = 0;
1767 zmw_get_wlan_dev(dev);
1769 wd->ap.uniTail = (wd->ap.uniTail-1) & (ZM_UNI_ARRAY_SIZE-1);
1770 while (id != wd->ap.uniTail)
1772 nid = (id + 1) & (ZM_UNI_ARRAY_SIZE - 1);
1773 wd->ap.uniArray[id] = wd->ap.uniArray[nid];
1775 /* Search until tail to config more data bit */
1776 dst[0] = zmw_buf_readh(dev, wd->ap.uniArray[id], 0);
1777 dst[1] = zmw_buf_readh(dev, wd->ap.uniArray[id], 2);
1778 dst[2] = zmw_buf_readh(dev, wd->ap.uniArray[id], 4);
1779 if ((addr[0] == dst[0]) && (addr[1] == dst[1])
1780 && (addr[2] == dst[2]))
1782 moreData = 0x20;
1785 id = nid;
1787 return moreData;
1790 /************************************************************************/
1791 /* */
1792 /* FUNCTION DESCRIPTION zfApAddIeWmePara */
1793 /* Add WME Parameter Element to buffer. */
1794 /* */
1795 /* INPUTS */
1796 /* dev : device pointer */
1797 /* buf : buffer to add information element */
1798 /* offset : add information element from this offset */
1799 /* vap : virtual AP ID */
1800 /* */
1801 /* OUTPUTS */
1802 /* buffer offset after adding information element */
1803 /* */
1804 /* AUTHOR */
1805 /* Stephen Chen ZyDAS Technology Corporation 2006.1 */
1806 /* */
1807 /************************************************************************/
1808 u16_t zfApAddIeWmePara(zdev_t* dev, zbuf_t* buf, u16_t offset, u16_t vap)
1810 zmw_get_wlan_dev(dev);
1812 /* Element ID */
1813 zmw_tx_buf_writeb(dev, buf, offset++, ZM_WLAN_EID_WIFI_IE);
1815 /* Element Length */
1816 zmw_tx_buf_writeb(dev, buf, offset++, 24);
1818 /* OUI */
1819 zmw_tx_buf_writeb(dev, buf, offset++, 0x00);
1820 zmw_tx_buf_writeb(dev, buf, offset++, 0x50);
1821 zmw_tx_buf_writeb(dev, buf, offset++, 0xF2);
1822 zmw_tx_buf_writeb(dev, buf, offset++, 0x02);
1823 zmw_tx_buf_writeb(dev, buf, offset++, 0x01);
1824 zmw_tx_buf_writeb(dev, buf, offset++, 0x01);
1826 /* QoS Info */
1827 if (wd->ap.uapsdEnabled)
1829 zmw_tx_buf_writeb(dev, buf, offset++, 0x81);
1831 else
1833 zmw_tx_buf_writeb(dev, buf, offset++, 0x01);
1836 /* Reserved */
1837 zmw_tx_buf_writeb(dev, buf, offset++, 0x00);
1839 /* Best Effort AC parameters */
1840 zmw_tx_buf_writeb(dev, buf, offset++, 0x03);
1841 zmw_tx_buf_writeb(dev, buf, offset++, 0xA4);
1842 zmw_tx_buf_writeb(dev, buf, offset++, 0x00);
1843 zmw_tx_buf_writeb(dev, buf, offset++, 0x00);
1844 /* Backfround AC parameters */
1845 zmw_tx_buf_writeb(dev, buf, offset++, 0x27);
1846 zmw_tx_buf_writeb(dev, buf, offset++, 0xA4);
1847 zmw_tx_buf_writeb(dev, buf, offset++, 0x00);
1848 zmw_tx_buf_writeb(dev, buf, offset++, 0x00);
1849 /* Video AC parameters */
1850 zmw_tx_buf_writeb(dev, buf, offset++, 0x42);
1851 zmw_tx_buf_writeb(dev, buf, offset++, 0x43);
1852 zmw_tx_buf_writeb(dev, buf, offset++, 0x5E);
1853 zmw_tx_buf_writeb(dev, buf, offset++, 0x00);
1854 /* Voice AC parameters */
1855 zmw_tx_buf_writeb(dev, buf, offset++, 0x62);
1856 zmw_tx_buf_writeb(dev, buf, offset++, 0x32);
1857 zmw_tx_buf_writeb(dev, buf, offset++, 0x2F);
1858 zmw_tx_buf_writeb(dev, buf, offset++, 0x00);
1860 return offset;
1864 /************************************************************************/
1865 /* */
1866 /* FUNCTION DESCRIPTION zfApSendBeacon */
1867 /* Sned AP mode beacon. */
1868 /* */
1869 /* INPUTS */
1870 /* dev : device pointer */
1871 /* */
1872 /* OUTPUTS */
1873 /* none */
1874 /* */
1875 /* AUTHOR */
1876 /* Stephen Chen ZyDAS Technology Corporation 2005.11 */
1877 /* */
1878 /************************************************************************/
1879 void zfApSendBeacon(zdev_t* dev)
1881 zbuf_t* buf;
1882 u16_t offset;
1883 u16_t vap;
1884 u16_t seq;
1886 zmw_get_wlan_dev(dev);
1888 zmw_declare_for_critical_section();
1890 wd->ap.beaconCounter++;
1891 if (wd->ap.beaconCounter >= wd->ap.vapNumber)
1893 wd->ap.beaconCounter = 0;
1895 vap = wd->ap.beaconCounter;
1898 zm_msg1_mm(ZM_LV_2, "Send beacon, vap=", vap);
1900 /* TBD : Maximum size of beacon */
1901 buf = zfwBufAllocate(dev, 1024);
1902 if (buf == NULL)
1904 zm_msg0_mm(ZM_LV_0, "Alloc beacon buf Fail!");
1905 return;
1908 offset = 0;
1910 /* wlan header */
1911 /* Frame control */
1912 zmw_tx_buf_writeh(dev, buf, offset, 0x0080);
1913 offset+=2;
1914 /* Duration */
1915 zmw_tx_buf_writeh(dev, buf, offset, 0x0000);
1916 offset+=2;
1917 /* Address 1 */
1918 zmw_tx_buf_writeh(dev, buf, offset, 0xffff);
1919 offset+=2;
1920 zmw_tx_buf_writeh(dev, buf, offset, 0xffff);
1921 offset+=2;
1922 zmw_tx_buf_writeh(dev, buf, offset, 0xffff);
1923 offset+=2;
1924 /* Address 2 */
1925 zmw_tx_buf_writeh(dev, buf, offset, wd->macAddr[0]);
1926 offset+=2;
1927 zmw_tx_buf_writeh(dev, buf, offset, wd->macAddr[1]);
1928 offset+=2;
1929 #ifdef ZM_VAPMODE_MULTILE_SSID
1930 zmw_tx_buf_writeh(dev, buf, offset, wd->macAddr[2]); //Multiple SSID
1931 #else
1932 zmw_tx_buf_writeh(dev, buf, offset, (wd->macAddr[2]+(vap<<8))); //VAP
1933 #endif
1934 offset+=2;
1935 /* Address 3 */
1936 zmw_tx_buf_writeh(dev, buf, offset, wd->macAddr[0]);
1937 offset+=2;
1938 zmw_tx_buf_writeh(dev, buf, offset, wd->macAddr[1]);
1939 offset+=2;
1940 #ifdef ZM_VAPMODE_MULTILE_SSID
1941 zmw_tx_buf_writeh(dev, buf, offset, wd->macAddr[2]); //Multiple SSID
1942 #else
1943 zmw_tx_buf_writeh(dev, buf, offset, (wd->macAddr[2]+(vap<<8))); //VAP
1944 #endif
1945 offset+=2;
1947 /* Sequence number */
1948 zmw_enter_critical_section(dev);
1949 seq = ((wd->mmseq++)<<4);
1950 zmw_leave_critical_section(dev);
1951 zmw_tx_buf_writeh(dev, buf, offset, seq);
1952 offset+=2;
1954 /* 24-31 Time Stamp : hardware will fill this field */
1955 zmw_tx_buf_writeh(dev, buf, offset, 0);
1956 zmw_tx_buf_writeh(dev, buf, offset+2, 0);
1957 zmw_tx_buf_writeh(dev, buf, offset+4, 0);
1958 zmw_tx_buf_writeh(dev, buf, offset+6, 0);
1959 offset+=8;
1961 /* Beacon Interval */
1962 zmw_tx_buf_writeh(dev, buf, offset, wd->beaconInterval);
1963 offset+=2;
1965 /* Capability */
1966 zmw_tx_buf_writeh(dev, buf, offset, wd->ap.capab[vap]);
1967 offset+=2;
1969 /* SSID */
1970 if (wd->ap.hideSsid[vap] == 0)
1972 offset = zfApAddIeSsid(dev, buf, offset, vap);
1974 else
1976 zmw_tx_buf_writeb(dev, buf, offset++, ZM_WLAN_EID_SSID);
1977 zmw_tx_buf_writeb(dev, buf, offset++, 0);
1981 /* Support Rate */
1982 if ( wd->frequency < 3000 )
1984 offset = zfMmAddIeSupportRate(dev, buf, offset,
1985 ZM_WLAN_EID_SUPPORT_RATE, ZM_RATE_SET_CCK);
1987 else
1989 offset = zfMmAddIeSupportRate(dev, buf, offset,
1990 ZM_WLAN_EID_SUPPORT_RATE, ZM_RATE_SET_OFDM);
1993 /* DS parameter set */
1994 offset = zfMmAddIeDs(dev, buf, offset);
1996 /* TIM */
1997 offset = zfApAddIeTim(dev, buf, offset, vap);
1999 /* If WLAN Type is not PURE B */
2000 if (wd->ap.wlanType[vap] != ZM_WLAN_TYPE_PURE_B)
2002 if ( wd->frequency < 3000 )
2004 /* ERP Information */
2005 offset = zfMmAddIeErp(dev, buf, offset);
2007 /* Extended Supported Rates */
2008 offset = zfMmAddIeSupportRate(dev, buf, offset,
2009 ZM_WLAN_EID_EXTENDED_RATE, ZM_RATE_SET_OFDM);
2013 /* TODO : country information */
2014 /* TODO : RSN */
2015 if (wd->ap.wpaSupport[vap] == 1)
2017 offset = zfMmAddIeWpa(dev, buf, offset, vap);
2020 /* WME Parameters */
2021 if (wd->ap.qosMode == 1)
2023 offset = zfApAddIeWmePara(dev, buf, offset, vap);
2026 /* HT Capabilities Info */
2027 offset = zfMmAddHTCapability(dev, buf, offset);
2029 /* Extended HT Capabilities Info */
2030 offset = zfMmAddExtendedHTCapability(dev, buf, offset);
2032 /* 1212 : write to beacon fifo */
2033 /* 1221 : write to share memory */
2034 zfHpSendBeacon(dev, buf, offset);
2036 /* Free beacon buffer */
2037 /* TODO: In order to fit the madwifi beacon architecture, we need to
2038 free beacon buffer in the HAL layer.
2041 //zfwBufFree(dev, buf, 0);
2045 /************************************************************************/
2046 /* */
2047 /* FUNCTION DESCRIPTION zfIntrabssForward */
2048 /* Called to transmit intra-BSS frame from upper layer. */
2049 /* */
2050 /* INPUTS */
2051 /* dev : device pointer */
2052 /* buf : buffer pointer */
2053 /* vap : virtual AP */
2054 /* */
2055 /* OUTPUTS */
2056 /* 1 : unicast intras-BSS frame */
2057 /* 0 : other frames */
2058 /* */
2059 /* AUTHOR */
2060 /* Stephen ZyDAS Technology Corporation 2005.11 */
2061 /* */
2062 /************************************************************************/
2063 u16_t zfIntrabssForward(zdev_t* dev, zbuf_t* buf, u8_t srcVap)
2065 u16_t err;
2066 u16_t asocFlag = 0;
2067 u16_t dst[3];
2068 u16_t aid;
2069 u16_t staState;
2070 zbuf_t* txBuf;
2071 u16_t len;
2072 u16_t i;
2073 u16_t temp;
2074 u16_t ret;
2075 u8_t vap = 0;
2076 #ifdef ZM_ENABLE_NATIVE_WIFI
2077 dst[0] = zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A3_OFFSET);
2078 dst[1] = zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A3_OFFSET+2);
2079 dst[2] = zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A3_OFFSET+4);
2080 #else
2081 dst[0] = zmw_rx_buf_readh(dev, buf, 0);
2082 dst[1] = zmw_rx_buf_readh(dev, buf, 2);
2083 dst[2] = zmw_rx_buf_readh(dev, buf, 4);
2084 #endif // ZM_ENABLE_NATIVE_WIFI
2086 /* Do Intra-BSS forward(data copy) if necessary*/
2087 if ((dst[0]&0x1) != 0x1)
2089 aid = zfApGetSTAInfo(dev, dst, &staState, &vap);
2090 if ((aid != 0xffff) && (staState == ZM_STATE_ASOC) && (srcVap == vap))
2092 asocFlag = 1;
2093 zm_msg0_rx(ZM_LV_2, "Intra-BSS forward : asoc STA");
2097 else
2099 vap = srcVap;
2100 zm_msg0_rx(ZM_LV_2, "Intra-BSS forward : BCorMC");
2103 /* destination address = associated STA or BC/MC */
2104 if ((asocFlag == 1) || ((dst[0]&0x1) == 0x1))
2106 /* Allocate frame */
2107 txBuf = zfwBufAllocate(dev, ZM_RX_FRAME_SIZE);
2108 if (txBuf == NULL)
2110 zm_msg0_rx(ZM_LV_1, "Alloc intra-bss buf Fail!");
2111 goto zlAllocError;
2114 /* Copy frame */
2115 len = zfwBufGetSize(dev, buf);
2116 for (i=0; i<len; i+=2)
2118 temp = zmw_rx_buf_readh(dev, buf, i);
2119 zmw_tx_buf_writeh(dev, txBuf, i, temp);
2121 zfwBufSetSize(dev, txBuf, len);
2123 #ifdef ZM_ENABLE_NATIVE_WIFI
2124 /* Tx-A2 = Rx-A1, Tx-A3 = Rx-A2, Tx-A1 = Rx-A3 */
2125 for (i=0; i<6; i+=2)
2127 temp = zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A1_OFFSET+i);
2128 zmw_tx_buf_writeh(dev, txBuf, ZM_WLAN_HEADER_A2_OFFSET+i, temp);
2129 temp = zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A2_OFFSET+i);
2130 zmw_tx_buf_writeh(dev, txBuf, ZM_WLAN_HEADER_A3_OFFSET+i, temp);
2131 temp = zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A3_OFFSET+i);
2132 zmw_tx_buf_writeh(dev, txBuf, ZM_WLAN_HEADER_A1_OFFSET+i, temp);
2135 #endif
2137 /* Transmit frame */
2138 /* Return error if port is disabled */
2139 err = zfTxPortControl(dev, txBuf, vap);
2140 if (err == ZM_PORT_DISABLED)
2142 err = ZM_ERR_TX_PORT_DISABLED;
2143 goto zlTxError;
2146 /* AP : Buffer frame for power saving STA */
2147 ret = zfApBufferPsFrame(dev, txBuf, vap);
2148 if (ret == 0)
2150 /* forward frame if not been buffered */
2151 /* Put to VTXQ[ac] */
2152 ret = zfPutVtxq(dev, txBuf);
2153 /* Push VTXQ[ac] */
2154 zfPushVtxq(dev);
2158 return asocFlag;
2160 zlTxError:
2161 zfwBufFree(dev, txBuf, 0);
2162 zlAllocError:
2163 return asocFlag;
2166 struct zsMicVar* zfApGetRxMicKey(zdev_t* dev, zbuf_t* buf)
2168 u8_t sa[6];
2169 u16_t id = 0, macAddr[3];
2171 zmw_get_wlan_dev(dev);
2173 zfCopyFromRxBuffer(dev, buf, sa, ZM_WLAN_HEADER_A2_OFFSET, 6);
2175 macAddr[0] = sa[0] + (sa[1] << 8);
2176 macAddr[1] = sa[2] + (sa[3] << 8);
2177 macAddr[2] = sa[4] + (sa[5] << 8);
2179 id = zfApFindSta(dev, macAddr);
2180 if (id != 0xffff)
2181 return (&wd->ap.staTable[id].rxMicKey);
2183 return NULL;
2186 struct zsMicVar* zfApGetTxMicKey(zdev_t* dev, zbuf_t* buf, u8_t* qosType)
2188 u8_t da[6];
2189 u16_t id = 0, macAddr[3];
2191 zmw_get_wlan_dev(dev);
2193 zfCopyFromIntTxBuffer(dev, buf, da, 0, 6);
2195 macAddr[0] = da[0] + (da[1] << 8);
2196 macAddr[1] = da[2] + (da[3] << 8);
2197 macAddr[2] = da[4] + (da[5] << 8);
2199 if ((macAddr[0] & 0x1))
2201 return (&wd->ap.bcMicKey[0]);
2203 else if ((id = zfApFindSta(dev, macAddr)) != 0xffff)
2205 *qosType = wd->ap.staTable[id].qosType;
2206 return (&wd->ap.staTable[id].txMicKey);
2209 return NULL;
2212 u16_t zfApUpdatePsBit(zdev_t* dev, zbuf_t* buf, u8_t* vap, u8_t* uapsdTrig)
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;
2221 zmw_get_wlan_dev(dev);
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);
2227 if ((zmw_rx_buf_readb(dev, buf, 1) & 0x3) != 3)
2229 /* AP */
2230 dst[0] = zmw_rx_buf_readh(dev, buf, 4);
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);
2236 /* if STA not associated, send deauth */
2237 if ((aid == 0xffff) || (staState != ZM_STATE_ASOC))
2239 if ((dst[0]&0x1)==0)
2241 zfSendMmFrame(dev, ZM_WLAN_FRAME_TYPE_DEAUTH, src, 0x7,
2242 0, 0);
2245 return ZM_ERR_STA_NOT_ASSOCIATED;
2247 } /* if ((zmw_rx_buf_readb(dev, buf, 1) & 0x3) != 3) */
2248 else
2250 /* WDS */
2251 for (i=0; i<ZM_MAX_WDS_SUPPORT; i++)
2253 if ((wd->ap.wds.wdsBitmap & (1<<i)) != 0)
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]))
2259 *vap = 0x20 + i;
2260 break;
2265 return ZM_SUCCESS;
2268 void zfApProcessPsPoll(zdev_t* dev, zbuf_t* buf)
2270 u16_t src[3];
2271 u16_t dst[3];
2272 zbuf_t* psBuf = NULL;
2273 u16_t id;
2274 u8_t moreData = 0;
2276 zmw_get_wlan_dev(dev);
2278 zmw_declare_for_critical_section();
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);
2284 /* Find ps buffer for PsPoll */
2285 zmw_enter_critical_section(dev);
2286 id = wd->ap.uniHead;
2287 while (id != wd->ap.uniTail)
2289 psBuf = wd->ap.uniArray[id];
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);
2295 if ((src[0] == dst[0]) && (src[1] == dst[1]) && (src[2] == dst[2]))
2297 moreData = zfApRemoveFromPsQueue(dev, id, src);
2298 break;
2300 else
2302 psBuf = NULL;
2304 id = (id + 1) & (ZM_UNI_ARRAY_SIZE - 1);
2306 zmw_leave_critical_section(dev);
2308 /* Send ps buffer */
2309 if (psBuf != NULL)
2311 /* Send with more data bit */
2312 zfTxSendEth(dev, psBuf, 0, ZM_EXTERNAL_ALLOC_BUF, moreData);
2315 return;
2318 void zfApSetProtectionMode(zdev_t* dev, u16_t mode)
2320 zmw_get_wlan_dev(dev);
2322 if (mode == 0)
2324 if (wd->ap.protectionMode != mode)
2326 /* Write MAC&PHY registers to disable protection */
2328 wd->ap.protectionMode = mode;
2332 else
2334 if (wd->ap.protectionMode != mode)
2336 /* Write MAC&PHY registers to enable protection */
2338 wd->ap.protectionMode = mode;
2341 return;
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)
2363 u16_t id;
2364 u16_t staAddr[3];
2365 zmw_get_wlan_dev(dev);
2366 zmw_declare_for_critical_section();
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 id = zfApFindSta(dev, staAddr);
2373 if (id != 0xffff)
2375 /* Send failture : Add 3 minutes to inactive time that will */
2376 /* will make STA been kicked out soon */
2377 wd->ap.staTable[id].time -= (3*ZM_TICK_PER_MINUTE);
2379 zmw_leave_critical_section(dev);
2383 void zfApProcessAction(zdev_t* dev, zbuf_t* buf)
2385 u8_t category;
2387 //zmw_get_wlan_dev(dev);
2389 //zmw_declare_for_critical_section();
2391 category = zmw_rx_buf_readb(dev, buf, 24);
2393 switch (category)
2395 case ZM_WLAN_BLOCK_ACK_ACTION_FRAME:
2396 zfAggBlockAckActionFrame(dev, buf);
2397 break;
2398 default:
2399 break;
2402 return;