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.
17 /* Module Name : mm.c */
20 /* This module contains common functions for handle AP */
21 /* management frame. */
26 /************************************************************************/
30 extern const u8_t zcUpToAc[];
32 void zfMmApTimeTick(zdev_t* dev)
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;
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 */
55 //zfApProtctionMonitor(dev);
60 /************************************************************************/
62 /* FUNCTION DESCRIPTION zfApInitStaTbl */
63 /* Init AP's station table. */
66 /* dev : device pointer */
72 /* Stephen Chen ZyDAS Technology Corporation 2005.10 */
74 /************************************************************************/
75 void zfApInitStaTbl(zdev_t* dev)
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;
96 /************************************************************************/
98 /* FUNCTION DESCRIPTION zfApFindSta */
99 /* Find a STA in station table. */
102 /* dev : device pointer */
103 /* addr : Target STA address */
107 /* other : STA table index */
110 /* Stephen Chen ZyDAS Technology Corporation 2005.10 */
112 /************************************************************************/
113 u16_t zfApFindSta(zdev_t* dev, u16_t* addr)
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]))
134 u16_t zfApGetSTAInfo(zdev_t* dev, u16_t* addr, u16_t* state, u8_t* vap)
138 zmw_get_wlan_dev(dev);
140 zmw_declare_for_critical_section();
142 zmw_enter_critical_section(dev);
144 if ((id = zfApFindSta(dev, addr)) != 0xffff)
146 *vap = wd->ap.staTable[id].vap;
147 *state = wd->ap.staTable[id++].state;
150 zmw_leave_critical_section(dev);
156 void zfApGetStaQosType(zdev_t* dev, u16_t* addr, u8_t* qosType)
160 zmw_get_wlan_dev(dev);
162 zmw_declare_for_critical_section();
164 zmw_enter_critical_section(dev);
166 if ((id = zfApFindSta(dev, addr)) != 0xffff)
168 *qosType = wd->ap.staTable[id].qosType;
175 zmw_leave_critical_section(dev);
180 void zfApGetStaTxRateAndQosType(zdev_t* dev, u16_t* addr, u32_t* phyCtrl,
181 u8_t* qosType, u16_t* rcProbingFlag)
186 zmw_get_wlan_dev(dev);
188 zmw_declare_for_critical_section();
190 zmw_enter_critical_section(dev);
192 if ((id = zfApFindSta(dev, addr)) != 0xffff)
194 rate = (u8_t)zfRateCtrlGetTxRate(dev, &wd->ap.staTable[id].rcCell, rcProbingFlag);
198 *phyCtrl = zcRateToPhyCtrl[rate];
199 *qosType = wd->ap.staTable[id].qosType;
203 if (wd->frequency < 3000)
206 //header[2] = 0x0f00; //PHY control L
207 //header[3] = 0x0000; //PHY control H
208 *phyCtrl = 0x00000F00;
213 //header[2] = 0x0f01; //PHY control L
214 //header[3] = 0x000B; //PHY control H
215 *phyCtrl = 0x000B0F01;
220 zmw_leave_critical_section(dev);
222 zm_msg2_mm(ZM_LV_3, "PhyCtrl=", *phyCtrl);
226 void zfApGetStaEncryType(zdev_t* dev, u16_t* addr, u8_t* encryType)
228 //struct zsWlanDev* wd = (struct zsWlanDev*) zmw_wlan_dev(dev);
231 zmw_get_wlan_dev(dev);
233 zmw_declare_for_critical_section();
235 zmw_enter_critical_section(dev);
237 if ((id = zfApFindSta(dev, addr)) != 0xffff)
239 *encryType = wd->ap.staTable[id].encryMode;
243 *encryType = ZM_NO_WEP;
246 zmw_leave_critical_section(dev);
248 zm_msg2_mm(ZM_LV_3, "encyrType=", *encryType);
252 void zfApGetStaWpaIv(zdev_t* dev, u16_t* addr, u16_t* iv16, u32_t* iv32)
254 //struct zsWlanDev* wd = (struct zsWlanDev*) zmw_wlan_dev(dev);
257 zmw_get_wlan_dev(dev);
259 zmw_declare_for_critical_section();
261 zmw_enter_critical_section(dev);
263 if ((id = zfApFindSta(dev, addr)) != 0xffff)
265 *iv16 = wd->ap.staTable[id].iv16;
266 *iv32 = wd->ap.staTable[id].iv32;
274 zmw_leave_critical_section(dev);
276 zm_msg2_mm(ZM_LV_3, "iv16=", *iv16);
277 zm_msg2_mm(ZM_LV_3, "iv32=", *iv32);
281 void zfApSetStaWpaIv(zdev_t* dev, u16_t* addr, u16_t iv16, u32_t iv32)
283 //struct zsWlanDev* wd = (struct zsWlanDev*) zmw_wlan_dev(dev);
286 zmw_get_wlan_dev(dev);
288 zmw_declare_for_critical_section();
290 zmw_enter_critical_section(dev);
292 if ((id = zfApFindSta(dev, addr)) != 0xffff)
294 wd->ap.staTable[id].iv16 = iv16;
295 wd->ap.staTable[id].iv32 = iv32;
298 zmw_leave_critical_section(dev);
300 zm_msg2_mm(ZM_LV_3, "iv16=", iv16);
301 zm_msg2_mm(ZM_LV_3, "iv32=", iv32);
305 void zfApClearStaKey(zdev_t* dev, u16_t* addr)
307 //struct zsWlanDev* wd = (struct zsWlanDev*) zmw_wlan_dev(dev);
308 u16_t bcAddr[3] = { 0xffff, 0xffff, 0xffff };
311 zmw_get_wlan_dev(dev);
313 if (zfMemoryIsEqual((u8_t*)bcAddr, (u8_t*)addr, sizeof(bcAddr)) == TRUE)
315 /* Turn off group key information */
316 // zfClearKey(dev, 0);
320 zmw_declare_for_critical_section();
322 zmw_enter_critical_section(dev);
324 if ((id = zfApFindSta(dev, addr)) != 0xffff)
326 /* Turn off STA's key information */
327 zfHpRemoveKey(dev, id+1);
329 /* Update STA's Encryption Type */
330 wd->ap.staTable[id].encryMode = ZM_NO_WEP;
334 zm_msg0_mm(ZM_LV_3, "Can't find STA address\n");
336 zmw_leave_critical_section(dev);
340 #ifdef ZM_ENABLE_CENC
341 void zfApGetStaCencIvAndKeyIdx(zdev_t* dev, u16_t* addr, u32_t *iv, u8_t *keyIdx)
343 //struct zsWlanDev* wd = (struct zsWlanDev*) zmw_wlan_dev(dev);
345 zmw_get_wlan_dev(dev);
346 zmw_declare_for_critical_section();
349 zmw_enter_critical_section(dev);
351 if ((id = zfApFindSta(dev, addr)) != 0xffff)
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;
368 zmw_leave_critical_section(dev);
372 void zfApSetStaCencIv(zdev_t* dev, u16_t* addr, u32_t *iv)
374 //struct zsWlanDev* wd = (struct zsWlanDev*) zmw_wlan_dev(dev);
376 zmw_get_wlan_dev(dev);
377 zmw_declare_for_critical_section();
380 zmw_enter_critical_section(dev);
382 if ((id = zfApFindSta(dev, addr)) != 0xffff)
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;
390 zmw_leave_critical_section(dev);
394 #endif //ZM_ENABLE_CENC
397 /************************************************************************/
399 /* FUNCTION DESCRIPTION zfApFlushBufferedPsFrame */
400 /* Free buffered PS frames. */
403 /* dev : device pointer */
409 /* Stephen Chen Atheros Communications, INC. 2007.1 */
411 /************************************************************************/
412 void zfApFlushBufferedPsFrame(zdev_t* dev)
417 zbuf_t* psBuf = NULL;
418 zmw_get_wlan_dev(dev);
419 zmw_declare_for_critical_section();
426 zmw_enter_critical_section(dev);
427 if (wd->ap.uniHead != wd->ap.uniTail)
429 psBuf = wd->ap.uniArray[wd->ap.uniHead];
430 wd->ap.uniHead = (wd->ap.uniHead + 1) & (ZM_UNI_ARRAY_SIZE - 1);
436 zmw_leave_critical_section(dev);
440 zfwBufFree(dev, psBuf, ZM_ERR_FLUSH_PS_QUEUE);
442 zm_assert(freeCount++ < (ZM_UNI_ARRAY_SIZE*2));
450 for (vap=0; vap<ZM_MAX_AP_SUPPORT; vap++)
457 zmw_enter_critical_section(dev);
458 if (wd->ap.bcmcHead[vap] != wd->ap.bcmcTail[vap])
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);
468 zmw_leave_critical_section(dev);
472 zfwBufFree(dev, psBuf, ZM_ERR_FLUSH_PS_QUEUE);
474 zm_assert(freeCount++ < (ZM_BCMC_ARRAY_SIZE*2));
486 u16_t zfApBufferPsFrame(zdev_t* dev, zbuf_t* buf, u16_t port)
496 zmw_get_wlan_dev(dev);
498 zmw_declare_for_critical_section();
500 if (port < ZM_MAX_AP_SUPPORT)
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);
509 if ((addr[0] & 0x1) == 0x1)
511 if (wd->ap.staPowerSaving > 0)
513 zmw_enter_critical_section(dev);
515 /* Buffer this BC or MC frame */
516 if (((wd->ap.bcmcTail[vap]+1)&(ZM_BCMC_ARRAY_SIZE-1))
517 != wd->ap.bcmcHead[vap])
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);
523 zm_msg0_tx(ZM_LV_0, "Buffer BCMC");
528 zmw_leave_critical_section(dev);
530 zm_msg0_tx(ZM_LV_0, "BCMC buffer full");
532 /* free buffer according to buffer type */
533 zfwBufFree(dev, buf, ZM_ERR_BCMC_PS_BUFFER_UNAVAILABLE);
540 zmw_enter_critical_section(dev);
542 if ((id = zfApFindSta(dev, addr)) != 0xffff)
544 if (wd->ap.staTable[id].psMode == 1)
547 zfTxGetIpTosAndFrag(dev, buf, &up, &fragOff);
548 ac = zcUpToAc[up&0x7] & 0x3;
550 if ((wd->ap.staTable[id].qosType == 1) &&
551 ((wd->ap.staTable[id].qosInfo & (0x8>>ac)) != 0))
553 ret = zfQueuePutNcs(dev, wd->ap.uapsdQ, buf, wd->tick);
554 zmw_leave_critical_section(dev);
555 if (ret != ZM_SUCCESS)
557 zfwBufFree(dev, buf, ZM_ERR_AP_UAPSD_QUEUE_FULL);
562 /* Buffer this unicast frame */
563 if (((wd->ap.uniTail+1)&(ZM_UNI_ARRAY_SIZE-1))
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");
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);
582 } /* if (wd->ap.staTable[id++].psMode == 1) */
583 } /* if ((id = zfApFindSta(dev, addr)) != 0xffff) */
584 zmw_leave_critical_section(dev);
590 u16_t zfApGetSTAInfoAndUpdatePs(zdev_t* dev, u16_t* addr, u16_t* state,
591 u8_t* vap, u16_t psMode, u8_t* uapsdTrig)
594 u8_t uapsdStaAwake = 0;
596 zmw_get_wlan_dev(dev);
598 zmw_declare_for_critical_section();
600 zmw_enter_critical_section(dev);
606 if ((id = zfApFindSta(dev, addr)) != 0xffff)
610 zm_msg0_mm(ZM_LV_0, "psMode = 1");
611 if (wd->ap.staTable[id].psMode == 0)
613 wd->ap.staPowerSaving++;
617 if (wd->ap.staTable[id].qosType == 1)
619 zm_msg0_mm(ZM_LV_0, "UAPSD trigger");
620 *uapsdTrig = wd->ap.staTable[id].qosInfo;
626 if (wd->ap.staTable[id].psMode != 0)
628 wd->ap.staPowerSaving--;
629 if ((wd->ap.staTable[id].qosType == 1) && ((wd->ap.staTable[id].qosInfo&0xf)!=0))
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;
642 zmw_leave_critical_section(dev);
644 if (uapsdStaAwake == 1)
651 if ((psBuf = zfQueueGetWithMac(dev, wd->ap.uapsdQ, (u8_t*)addr, &mb)) != NULL)
653 zfTxSendEth(dev, psBuf, 0, ZM_EXTERNAL_ALLOC_BUF, 0);
665 /************************************************************************/
667 /* FUNCTION DESCRIPTION zfApGetNewSta */
668 /* Get a new STA from station table. */
671 /* dev : device pointer */
675 /* other : STA table index */
678 /* Stephen Chen ZyDAS Technology Corporation 2005.10 */
680 /************************************************************************/
681 u16_t zfApGetNewSta(zdev_t* dev)
685 zmw_get_wlan_dev(dev);
687 for (i=0; i<ZM_MAX_STA_SUPPORT; i++)
689 if (wd->ap.staTable[i].valid == 0)
691 zm_msg2_mm(ZM_LV_0, "zfApGetNewSta=", i);
699 /************************************************************************/
701 /* FUNCTION DESCRIPTION zfApAddSta */
702 /* Add a STA to station table. */
705 /* dev : device pointer */
706 /* addr : STA MAC address */
707 /* state : STA state */
708 /* apId : Virtual AP ID */
709 /* type : 0=>11b, 1=>11g */
716 /* Stephen Chen ZyDAS Technology Corporation 2005.10 */
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)
725 zmw_get_wlan_dev(dev);
727 zmw_declare_for_critical_section();
729 zm_msg1_mm(ZM_LV_0, "STA type=", type);
731 zmw_enter_critical_section(dev);
733 if ((index = zfApFindSta(dev, addr)) != 0xffff)
735 zm_msg0_mm(ZM_LV_2, "found");
736 /* Update STA state */
737 if ((state == ZM_STATE_AUTH) || (state == ZM_STATE_PREAUTH))
739 wd->ap.staTable[index].state = state;
740 wd->ap.staTable[index].time = wd->tick;
741 wd->ap.staTable[index].vap = (u8_t)apId;
743 else if (state == ZM_STATE_ASOC)
745 if ((wd->ap.staTable[index].state == ZM_STATE_AUTH))
746 //&& (wd->ap.staTable[index].vap == apId))
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;
755 if (wd->frequency < 3000)
758 zfRateCtrlInitCell(dev, &wd->ap.staTable[index].rcCell, type, 1, 1);
763 zfRateCtrlInitCell(dev, &wd->ap.staTable[index].rcCell, type, 0, 1);
766 if (wd->zfcbApConnectNotify != NULL)
768 wd->zfcbApConnectNotify(dev, (u8_t*)addr, apId);
779 zm_msg0_mm(ZM_LV_2, "Not found");
780 if ((state == ZM_STATE_AUTH) || (state == ZM_STATE_PREAUTH))
782 /* Get a new STA and update state */
783 index = zfApGetNewSta(dev);
784 zm_msg2_mm(ZM_LV_1, "new STA index=", index);
790 wd->ap.staTable[index].addr[i] = addr[i];
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;
801 zmw_leave_critical_section(dev);
807 /************************************************************************/
809 /* FUNCTION DESCRIPTION zfApAgingSta */
810 /* Aging STA in station table. */
813 /* dev : device pointer */
816 /* number of 11b STA in STA table */
819 /* Stephen Chen ZyDAS Technology Corporation 2005.10 */
821 /************************************************************************/
822 void zfApAgingSta(zdev_t* dev)
828 u16_t psStaCount = 0;
830 zmw_get_wlan_dev(dev);
832 zmw_declare_for_critical_section();
834 wd->ap.gStaAssociated = wd->ap.bStaAssociated = 0;
836 for (i=0; i<ZM_MAX_STA_SUPPORT; i++)
839 zmw_enter_critical_section(dev);
840 if (wd->ap.staTable[i].valid == 1)
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];
846 deltaMs = (u32_t)((u32_t)wd->tick-(u32_t)wd->ap.staTable[i].time)
850 if ((wd->ap.staTable[i].state == ZM_STATE_PREAUTH)
851 && (deltaMs > ZM_PREAUTH_TIMEOUT_MS))
854 wd->ap.staTable[i].valid = 0;
855 wd->ap.authSharing = 0;
860 if ((wd->ap.staTable[i].state == ZM_STATE_AUTH)
861 && (deltaMs > ZM_AUTH_TIMEOUT_MS))
864 wd->ap.staTable[i].valid = 0;
869 if (wd->ap.staTable[i].state == ZM_STATE_ASOC)
871 if (wd->ap.staTable[i].psMode != 0)
876 if (deltaMs > ((u32_t)wd->ap.staAgingTimeSec<<10))
879 zm_msg1_mm(ZM_LV_0, "Age STA index=", i);
880 wd->ap.staTable[i].valid = 0;
883 else if (deltaMs > ((u32_t)wd->ap.staProbingTimeSec<<10))
885 if (wd->ap.staTable[i].psMode == 0)
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);
898 zmw_leave_critical_section(dev);
902 /* Send deauthentication management frame */
903 zfSendMmFrame(dev, ZM_WLAN_FRAME_TYPE_DEAUTH, addr, 4, 0, 0);
905 else if (txFlag == 2)
907 zfSendMmFrame(dev, ZM_WLAN_DATA_FRAME, addr, 0, 0, 0);
912 wd->ap.staPowerSaving = psStaCount;
917 void zfApProtctionMonitor(zdev_t* dev)
919 zmw_get_wlan_dev(dev);
921 /* 11b STA associated => nonErp, Protect */
922 if (wd->ap.bStaAssociated > 0)
924 /* Enable NonErp bit in information element */
925 wd->erpElement = ZM_WLAN_NON_ERP_PRESENT_BIT
926 | ZM_WLAN_USE_PROTECTION_BIT;
928 /* Enable protection mode */
929 zfApSetProtectionMode(dev, 1);
932 /* 11b STA not associated, protection OBSS present => Protect */
933 else if (wd->ap.protectedObss > 2) //Threshold
935 if (wd->disableSelfCts == 0)
937 /* Disable NonErp bit in information element */
938 wd->erpElement = ZM_WLAN_USE_PROTECTION_BIT;
940 /* Enable protection mode */
941 zfApSetProtectionMode(dev, 1);
946 /* Disable NonErp bit in information element */
949 /* Disable protection mode */
950 zfApSetProtectionMode(dev, 0);
952 wd->ap.protectedObss = 0;
956 void zfApProcessBeacon(zdev_t* dev, zbuf_t* buf)
961 zmw_get_wlan_dev(dev);
963 zm_msg0_mm(ZM_LV_3, "Rx beacon");
965 /* update Non-ERP flag(wd->ap.nonErpObss) */
966 if ((offset = zfFindElement(dev, buf, ZM_WLAN_EID_ERP)) == 0xffff)
969 wd->ap.protectedObss++;
973 ch = zmw_rx_buf_readb(dev, buf, offset+2);
974 if ((ch & ZM_WLAN_USE_PROTECTION_BIT) == ZM_WLAN_USE_PROTECTION_BIT)
977 wd->ap.protectedObss = 1;
984 /************************************************************************/
986 /* FUNCTION DESCRIPTION zfProcessAuth */
987 /* Process authenticate management frame. */
990 /* dev : device pointer */
991 /* buf : auth frame buffer */
997 /* Stephen Chen ZyDAS Technology Corporation 2005.10 */
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)
1006 u16_t algo, seq, status;
1010 u8_t challengePassed = 0;
1014 zmw_get_wlan_dev(dev);
1015 zmw_declare_for_critical_section();
1018 frameCtrl = zmw_rx_buf_readb(dev, buf, 1);
1019 /* AP : Auth share 3 */
1020 /* shift for WEP IV */
1021 if ((frameCtrl & 0x40) != 0)
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);
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);
1034 zm_msg2_mm(ZM_LV_0, "Rx Auth, seq=", seq);
1036 /* Set default to authentication algorithm not support */
1037 retAlgoSeq = 0x20000 | algo;
1038 retStatus = 13; /* authentication algorithm not support */
1040 /* AP : Auth open 1 */
1043 if (wd->ap.authAlgo[apId] == 0)
1045 retAlgoSeq = 0x20000;
1048 /* AP : update STA to auth */
1049 if ((ret = zfApAddSta(dev, src, ZM_STATE_AUTH, apId, 0, 0, 0)) != 0xffff)
1051 /* AP : call zfwAuthNotify() for host to judge */
1052 //zfwAuthNotify(dev, src);
1054 /* AP : response Auth seq=2, success */
1060 /* AP : response Auth seq=2, unspecific error */
1066 /* AP : response Auth seq=2, sequence number out of expected */
1071 /* AP : Auth share 1 */
1074 if (wd->ap.authAlgo[apId] == 1)
1078 retAlgoSeq = 0x20001;
1080 /* critical section */
1081 zmw_enter_critical_section(dev);
1082 if (wd->ap.authSharing == 1)
1089 wd->ap.authSharing = 1;
1091 /* end of critical section */
1092 zmw_leave_critical_section(dev);
1094 if (authSharing == 1)
1096 /* AP : response Auth seq=2, status = fail */
1101 /* AP : update STA to preauth */
1102 zfApAddSta(dev, src, ZM_STATE_PREAUTH, apId, 0, 0, 0);
1104 /* AP : call zfwAuthNotify() for host to judge */
1105 //zfwAuthNotify(dev, src);
1107 /* AP : response Auth seq=2 */
1113 retAlgoSeq = 0x40001;
1115 if (wd->ap.authSharing == 1)
1117 /* check challenge text */
1118 if (zmw_buf_readh(dev, buf, 30+4) == 0x8010)
1120 for (i=0; i<128; i++)
1122 if (wd->ap.challengeText[i]
1123 != zmw_buf_readb(dev, buf, 32+i+4))
1130 challengePassed = 1;
1134 if (challengePassed == 1)
1136 /* AP : update STA to auth */
1137 zfApAddSta(dev, src, ZM_STATE_AUTH, apId, 0, 0, 0);
1139 /* AP : response Auth seq=2 */
1144 /* AP : response Auth seq=2, challenge failure */
1147 /* TODO : delete STA */
1150 wd->ap.authSharing = 0;
1155 retAlgoSeq = 0x40001;
1161 zfSendMmFrame(dev, ZM_WLAN_FRAME_TYPE_AUTH, src, retAlgoSeq,
1166 void zfApProcessAsocReq(zdev_t* dev, zbuf_t* buf, u16_t* src, u16_t apId)
1178 zmw_get_wlan_dev(dev);
1179 /* AP : check SSID */
1180 if ((offset = zfFindElement(dev, buf, ZM_WLAN_EID_SSID)) != 0xffff)
1183 for (j = 0; j < wd->ap.vapNumber; j++)
1185 if ((tmp = zmw_buf_readb(dev, buf, offset+1))
1186 != wd->ap.ssidLen[j])
1191 if (k == wd->ap.vapNumber)
1197 for (j = 0; j < wd->ap.vapNumber; j++)
1199 for (i=0; i<wd->ap.ssidLen[j]; i++)
1201 if ((tmp = zmw_buf_readb(dev, buf, offset+2+i))
1202 != wd->ap.ssid[j][i])
1207 if (i == wd->ap.ssidLen[j])
1216 if (k == wd->ap.vapNumber)
1222 /* TODO : check capability */
1224 /* AP : check support rate */
1225 if ((offset = zfFindElement(dev, buf, ZM_WLAN_EID_EXTENDED_RATE)) != 0xffff)
1231 if ((offset = zfFindElement(dev, buf, ZM_WLAN_EID_HT_CAPABILITY)) != 0xffff)
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)
1240 zfSendMmFrame(dev, ZM_WLAN_FRAME_TYPE_DEAUTH, src, 3, 0, 0);
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)
1250 /* AP : check 11i and WPA */
1251 /* AP : check 11h */
1253 /* AP : check WME */
1254 if ((offset = zfFindWifiElement(dev, buf, 2, 0)) != 0xffff)
1258 zm_msg0_mm(ZM_LV_0, "WME STA");
1260 if (wd->ap.uapsdEnabled != 0)
1262 qosInfo = zmw_rx_buf_readb(dev, buf, offset+8);
1266 if (wd->ap.wpaSupport[apId] == 1)
1268 if ( (offset = zfFindElement(dev, buf, ZM_WLAN_EID_WPA_IE)) != 0xffff )
1271 u8_t length = zmw_rx_buf_readb(dev, buf, offset+1);
1272 if (length+2 < ZM_MAX_WPAIE_SIZE)
1274 zfCopyFromRxBuffer(dev, buf, wd->ap.stawpaIe[apId], offset, length+2);
1275 wd->ap.stawpaLen[apId] = length+2;
1279 zm_msg1_mm(ZM_LV_0, "WPA Mode zfwAsocNotify, apId=", apId);
1281 /* AP : Call zfwAsocNotify() */
1282 if (wd->zfcbAsocNotify != NULL)
1284 wd->zfcbAsocNotify(dev, src, wd->ap.stawpaIe[apId], wd->ap.stawpaLen[apId], apId);
1292 else if ( (offset = zfFindElement(dev, buf, ZM_WLAN_EID_RSN_IE)) != 0xffff )
1295 u8_t length = zmw_rx_buf_readb(dev, buf, offset+1);
1296 if (length+2 < ZM_MAX_WPAIE_SIZE)
1298 zfCopyFromRxBuffer(dev, buf, wd->ap.stawpaIe[apId], offset, length+2);
1299 wd->ap.stawpaLen[apId] = length+2;
1302 zm_msg1_mm(ZM_LV_0, "RSN Mode zfwAsocNotify, apId=", apId);
1304 /* AP : Call zfwAsocNotify() */
1305 if (wd->zfcbAsocNotify != NULL)
1307 wd->zfcbAsocNotify(dev, src, wd->ap.stawpaIe[apId], wd->ap.stawpaLen[apId], apId);
1315 #ifdef ZM_ENABLE_CENC
1316 else if ( (offset = zfFindElement(dev, buf, ZM_WLAN_EID_CENC_IE)) != 0xffff )
1319 u8_t length = zmw_rx_buf_readb(dev, buf, offset+1);
1321 if (length+2 < ZM_MAX_WPAIE_SIZE)
1323 zfCopyFromRxBuffer(dev, buf, wd->ap.stawpaIe[apId], offset, length+2);
1324 wd->ap.stawpaLen[apId] = length+2;
1327 zm_msg1_mm(ZM_LV_0, "CENC Mode zfwAsocNotify, apId=", apId);
1329 /* AP : Call zfwAsocNotify() */
1330 if (wd->zfcbCencAsocNotify != NULL)
1332 wd->zfcbCencAsocNotify(dev, src, wd->ap.stawpaIe[apId],
1333 wd->ap.stawpaLen[apId], apId);
1341 #endif //ZM_ENABLE_CENC
1343 { /* ap is encryption but sta has no wpa/rsn ie */
1344 zfSendMmFrame(dev, ZM_WLAN_FRAME_TYPE_DEAUTH, src, 6, 0, 0);
1348 /* sta has wpa/rsn ie but ap is no encryption */
1349 if ((wd->ap.wpaSupport[apId] == 0) && (encMode == 1))
1351 zfSendMmFrame(dev, ZM_WLAN_FRAME_TYPE_DEAUTH, src, 6, 0, 0);
1355 /* AP : update STA to asoc */
1356 aid = zfApAddSta(dev, src, ZM_STATE_ASOC, apId, staType, qosType, qosInfo);
1358 zfApStoreAsocReqIe(dev, buf, aid);
1361 /* AP : send asoc rsp2 */
1364 frameType = zmw_rx_buf_readb(dev, buf, 0);
1366 if (frameType == ZM_WLAN_FRAME_TYPE_ASOCREQ)
1368 zfSendMmFrame(dev, ZM_WLAN_FRAME_TYPE_ASOCRSP, src, 0, aid+1, apId);
1372 zfSendMmFrame(dev, ZM_WLAN_FRAME_TYPE_REASOCRSP, src, 0, aid+1, apId);
1377 /* TODO : send deauthentication */
1378 zfSendMmFrame(dev, ZM_WLAN_FRAME_TYPE_DEAUTH, src, 6, 0, 0);
1384 void zfApStoreAsocReqIe(zdev_t* dev, zbuf_t* buf, u16_t aid)
1386 //struct zsWlanAssoFrameHeader* pAssoFrame;
1387 //u8_t pBuf[sizeof(struct zsWlanAssoFrameHeader)];
1393 zmw_get_wlan_dev(dev);
1395 for (i=0; i<wd->sta.asocRspFrameBodySize; i++)
1397 wd->sta.asocRspFrameBody[i] = zmw_rx_buf_readb(dev, buf, i+24);
1399 /* capability: 2 octets */
1402 /* Listen interval: 2 octets */
1408 /* supported rates */
1409 if ((offset = zfFindElement(dev, buf, ZM_WLAN_EID_SUPPORT_RATE)) == 0xffff)
1411 length = zmw_rx_buf_readb(dev, buf, offset + 1);
1413 /* extended supported rates */
1414 if ((offset = zfFindElement(dev, buf, ZM_WLAN_EID_EXTENDED_RATE)) == 0xffff)
1416 length = zmw_rx_buf_readb(dev, buf, offset + 1);
1418 /* power capability:4 octets */
1419 offset = offset + 2 + length;
1421 /* supported channels: 4 octets */
1422 offset = offset + 2 + 4;
1428 /* HT capabilities: 28 octets */
1429 if ((offset = zfFindElement(dev, buf, ZM_WLAN_EID_HT_CAPABILITY)) != 0xffff) {
1431 htcap = (u8_t *)&wd->ap.ie[aid].HtCap;
1432 htcap[0] = zmw_rx_buf_readb(dev, buf, offset);
1434 for (i=1; i<=26; i++)
1436 htcap[i+1] = zmw_rx_buf_readb(dev, buf, offset + i);
1437 zm_debug_msg2("ASOC: HT Capabilities, htcap=", htcap[i+1]);
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++)
1446 htcap[i] = zmw_rx_buf_readb(dev, buf, offset + i);
1447 zm_debug_msg2("ASOC: HT Capabilities, htcap=", htcap[i]);
1456 /* supported regulatory classes */
1457 offset = offset + length;
1458 //length = zmw_rx_buf_readb(dev, buf, offset + 1);
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);
1469 void zfApProcessAsocRsp(zdev_t* dev, zbuf_t* buf)
1474 void zfApProcessDeauth(zdev_t* dev, zbuf_t* buf, u16_t* src, u16_t apId)
1477 zmw_get_wlan_dev(dev);
1478 zmw_declare_for_critical_section();
1480 zmw_enter_critical_section(dev);
1481 /* AP : if SA=associated STA then deauthenticate STA */
1482 if ((aid = zfApFindSta(dev, src)) != 0xffff)
1484 /* Clear STA table */
1485 wd->ap.staTable[aid].valid = 0;
1486 if (wd->zfcbDisAsocNotify != NULL)
1488 wd->zfcbDisAsocNotify(dev, (u8_t*)src, apId);
1491 zmw_leave_critical_section(dev);
1495 void zfApProcessDisasoc(zdev_t* dev, zbuf_t* buf, u16_t* src, u16_t apId)
1498 zmw_get_wlan_dev(dev);
1499 zmw_declare_for_critical_section();
1501 zmw_enter_critical_section(dev);
1502 /* AP : if SA=associated STA then deauthenticate STA */
1503 if ((aid = zfApFindSta(dev, src)) != 0xffff)
1505 /* Clear STA table */
1506 wd->ap.staTable[aid].valid = 0;
1507 zmw_leave_critical_section(dev);
1508 if (wd->zfcbDisAsocNotify != NULL)
1510 wd->zfcbDisAsocNotify(dev, (u8_t*)src, apId);
1513 zmw_leave_critical_section(dev);
1518 void zfApProcessProbeRsp(zdev_t* dev, zbuf_t* buf, struct zsAdditionInfo* AddInfo)
1521 zmw_get_wlan_dev(dev);
1523 zm_msg0_mm(ZM_LV_0, "Rx probersp");
1525 /* Gather scan result */
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)
1535 //if ( wd->sta.pUpdateBssList->bssCount == ZM_MAX_BSS )
1536 if ( wd->sta.bssList.bssCount == ZM_MAX_BSS )
1541 zfProcessProbeRsp(dev, buf, AddInfo);
1546 /************************************************************************/
1548 /* FUNCTION DESCRIPTION zfApAddIeSsid */
1549 /* Add AP information element SSID to buffer. */
1552 /* dev : device pointer */
1553 /* buf : buffer to add information element */
1554 /* offset : add information element from this offset */
1555 /* vap : virtual AP ID */
1558 /* buffer offset after adding information element */
1561 /* Stephen Chen ZyDAS Technology Corporation 2005.11 */
1563 /************************************************************************/
1564 u16_t zfApAddIeSsid(zdev_t* dev, zbuf_t* buf, u16_t offset, u16_t vap)
1568 zmw_get_wlan_dev(dev);
1571 zmw_tx_buf_writeb(dev, buf, offset++, ZM_WLAN_EID_SSID);
1573 /* Element Length */
1574 zmw_tx_buf_writeb(dev, buf, offset++, wd->ap.ssidLen[vap]);
1576 /* Information : SSID */
1577 for (i=0; i<wd->ap.ssidLen[vap]; i++)
1579 zmw_tx_buf_writeb(dev, buf, offset++, wd->ap.ssid[vap][i]);
1586 /************************************************************************/
1588 /* FUNCTION DESCRIPTION zfApAddIeTim */
1589 /* Add AP information element TIM to buffer. */
1592 /* dev : device pointer */
1593 /* buf : buffer to add information element */
1594 /* offset : add information element from this offset */
1595 /* vap : virtual AP ID */
1598 /* buffer offset after adding information element */
1601 /* Stephen Chen ZyDAS Technology Corporation 2005.11 */
1603 /************************************************************************/
1604 u16_t zfApAddIeTim(zdev_t* dev, zbuf_t* buf, u16_t offset, u16_t vap)
1616 zbuf_t* tmpBufArray[ZM_UNI_ARRAY_SIZE];
1617 u16_t tmpBufArraySize = 0;
1619 zmw_get_wlan_dev(dev);
1621 zmw_declare_for_critical_section();
1624 zmw_tx_buf_writeb(dev, buf, offset++, ZM_WLAN_EID_TIM);
1626 /* offset of Element Length */
1627 lenOffset = offset++;
1629 /* Information : TIM */
1631 /* TODO : Doesn't work for Virtual AP's case */
1632 wd->CurrentDtimCount++;
1633 if (wd->CurrentDtimCount >= wd->dtim)
1635 wd->CurrentDtimCount = 0;
1637 zmw_tx_buf_writeb(dev, buf, offset++, wd->CurrentDtimCount);
1639 zmw_tx_buf_writeb(dev, buf, offset++, wd->dtim);
1641 zmw_tx_buf_writeb(dev, buf, offset++, 0);
1643 /* Update BCMC bit */
1644 if (wd->CurrentDtimCount == 0)
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);
1652 wd->ap.timBcmcBit[vap] = 0;
1655 /* Update Unicast bitmap */
1664 zmw_enter_critical_section(dev);
1666 id = wd->ap.uniHead;
1667 while (id != wd->ap.uniTail)
1669 psBuf = wd->ap.uniArray[id];
1671 /* TODO : Aging PS frame after queuing for more than 10 seconds */
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)
1679 if (wd->ap.staTable[aid].psMode != 0)
1681 zm_msg1_mm(ZM_LV_0, "aid=",aid);
1684 bitPosition = (1 << (aid & 0x7));
1685 bytePosition = (aid >> 3);
1686 uniBitMap[bytePosition] |= bitPosition;
1688 if (bytePosition>highestByte)
1690 highestByte = bytePosition;
1692 id = (id+1) & (ZM_UNI_ARRAY_SIZE-1);
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;
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);
1711 zmw_leave_critical_section(dev);
1714 zfQueueGenerateUapsdTim(dev, wd->ap.uapsdQ, uniBitMap, &highestByte);
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]);
1721 zmw_tx_buf_writeb(dev, buf, offset++,
1722 uniBitMap[0] | wd->ap.timBcmcBit[vap]);
1723 for (i=0; i<highestByte; i++)
1725 zmw_tx_buf_writeb(dev, buf, offset++, uniBitMap[i+1]);
1728 /* Element Length */
1729 zmw_tx_buf_writeb(dev, buf, lenOffset, highestByte+4);
1731 for (i=0; i<tmpBufArraySize; i++)
1733 /* Put to VTXQ[ac] */
1734 zfPutVtxq(dev, tmpBufArray[i]);
1744 /************************************************************************/
1746 /* FUNCTION DESCRIPTION zfApRemoveFromPsQueue */
1747 /* Remove zbuf from PS queue. */
1750 /* dev : device pointer */
1751 /* id : index in ps queue */
1757 /* Stephen Chen Atheros Communications, INC. 2007.1 */
1759 /************************************************************************/
1760 u8_t zfApRemoveFromPsQueue(zdev_t* dev, u16_t id, u16_t* addr)
1765 zmw_get_wlan_dev(dev);
1767 wd->ap.uniTail = (wd->ap.uniTail-1) & (ZM_UNI_ARRAY_SIZE-1);
1768 while (id != wd->ap.uniTail)
1770 nid = (id + 1) & (ZM_UNI_ARRAY_SIZE - 1);
1771 wd->ap.uniArray[id] = wd->ap.uniArray[nid];
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]))
1788 /************************************************************************/
1790 /* FUNCTION DESCRIPTION zfApAddIeWmePara */
1791 /* Add WME Parameter Element to buffer. */
1794 /* dev : device pointer */
1795 /* buf : buffer to add information element */
1796 /* offset : add information element from this offset */
1797 /* vap : virtual AP ID */
1800 /* buffer offset after adding information element */
1803 /* Stephen Chen ZyDAS Technology Corporation 2006.1 */
1805 /************************************************************************/
1806 u16_t zfApAddIeWmePara(zdev_t* dev, zbuf_t* buf, u16_t offset, u16_t vap)
1808 zmw_get_wlan_dev(dev);
1811 zmw_tx_buf_writeb(dev, buf, offset++, ZM_WLAN_EID_WIFI_IE);
1813 /* Element Length */
1814 zmw_tx_buf_writeb(dev, buf, offset++, 24);
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);
1825 if (wd->ap.uapsdEnabled)
1827 zmw_tx_buf_writeb(dev, buf, offset++, 0x81);
1831 zmw_tx_buf_writeb(dev, buf, offset++, 0x01);
1835 zmw_tx_buf_writeb(dev, buf, offset++, 0x00);
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);
1862 /************************************************************************/
1864 /* FUNCTION DESCRIPTION zfApSendBeacon */
1865 /* Sned AP mode beacon. */
1868 /* dev : device pointer */
1874 /* Stephen Chen ZyDAS Technology Corporation 2005.11 */
1876 /************************************************************************/
1877 void zfApSendBeacon(zdev_t* dev)
1884 zmw_get_wlan_dev(dev);
1886 zmw_declare_for_critical_section();
1888 wd->ap.beaconCounter++;
1889 if (wd->ap.beaconCounter >= wd->ap.vapNumber)
1891 wd->ap.beaconCounter = 0;
1893 vap = wd->ap.beaconCounter;
1896 zm_msg1_mm(ZM_LV_2, "Send beacon, vap=", vap);
1898 /* TBD : Maximum size of beacon */
1899 if ((buf = zfwBufAllocate(dev, 1024)) == NULL)
1901 zm_msg0_mm(ZM_LV_0, "Alloc beacon buf Fail!");
1909 zmw_tx_buf_writeh(dev, buf, offset, 0x0080);
1912 zmw_tx_buf_writeh(dev, buf, offset, 0x0000);
1915 zmw_tx_buf_writeh(dev, buf, offset, 0xffff);
1917 zmw_tx_buf_writeh(dev, buf, offset, 0xffff);
1919 zmw_tx_buf_writeh(dev, buf, offset, 0xffff);
1922 zmw_tx_buf_writeh(dev, buf, offset, wd->macAddr[0]);
1924 zmw_tx_buf_writeh(dev, buf, offset, wd->macAddr[1]);
1926 #ifdef ZM_VAPMODE_MULTILE_SSID
1927 zmw_tx_buf_writeh(dev, buf, offset, wd->macAddr[2]); //Multiple SSID
1929 zmw_tx_buf_writeh(dev, buf, offset, (wd->macAddr[2]+(vap<<8))); //VAP
1933 zmw_tx_buf_writeh(dev, buf, offset, wd->macAddr[0]);
1935 zmw_tx_buf_writeh(dev, buf, offset, wd->macAddr[1]);
1937 #ifdef ZM_VAPMODE_MULTILE_SSID
1938 zmw_tx_buf_writeh(dev, buf, offset, wd->macAddr[2]); //Multiple SSID
1940 zmw_tx_buf_writeh(dev, buf, offset, (wd->macAddr[2]+(vap<<8))); //VAP
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);
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);
1958 /* Beacon Interval */
1959 zmw_tx_buf_writeh(dev, buf, offset, wd->beaconInterval);
1963 zmw_tx_buf_writeh(dev, buf, offset, wd->ap.capab[vap]);
1967 if (wd->ap.hideSsid[vap] == 0)
1969 offset = zfApAddIeSsid(dev, buf, offset, vap);
1973 zmw_tx_buf_writeb(dev, buf, offset++, ZM_WLAN_EID_SSID);
1974 zmw_tx_buf_writeb(dev, buf, offset++, 0);
1979 if ( wd->frequency < 3000 )
1981 offset = zfMmAddIeSupportRate(dev, buf, offset,
1982 ZM_WLAN_EID_SUPPORT_RATE, ZM_RATE_SET_CCK);
1986 offset = zfMmAddIeSupportRate(dev, buf, offset,
1987 ZM_WLAN_EID_SUPPORT_RATE, ZM_RATE_SET_OFDM);
1990 /* DS parameter set */
1991 offset = zfMmAddIeDs(dev, buf, offset);
1994 offset = zfApAddIeTim(dev, buf, offset, vap);
1996 /* If WLAN Type is not PURE B */
1997 if (wd->ap.wlanType[vap] != ZM_WLAN_TYPE_PURE_B)
1999 if ( wd->frequency < 3000 )
2001 /* ERP Information */
2002 offset = zfMmAddIeErp(dev, buf, offset);
2004 /* Extended Supported Rates */
2005 offset = zfMmAddIeSupportRate(dev, buf, offset,
2006 ZM_WLAN_EID_EXTENDED_RATE, ZM_RATE_SET_OFDM);
2010 /* TODO : country information */
2012 if (wd->ap.wpaSupport[vap] == 1)
2014 offset = zfMmAddIeWpa(dev, buf, offset, vap);
2017 /* WME Parameters */
2018 if (wd->ap.qosMode == 1)
2020 offset = zfApAddIeWmePara(dev, buf, offset, vap);
2023 /* HT Capabilities Info */
2024 offset = zfMmAddHTCapability(dev, buf, offset);
2026 /* Extended HT Capabilities Info */
2027 offset = zfMmAddExtendedHTCapability(dev, buf, offset);
2029 /* 1212 : write to beacon fifo */
2030 /* 1221 : write to share memory */
2031 zfHpSendBeacon(dev, buf, offset);
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.
2038 //zfwBufFree(dev, buf, 0);
2042 /************************************************************************/
2044 /* FUNCTION DESCRIPTION zfIntrabssForward */
2045 /* Called to transmit intra-BSS frame from upper layer. */
2048 /* dev : device pointer */
2049 /* buf : buffer pointer */
2050 /* vap : virtual AP */
2053 /* 1 : unicast intras-BSS frame */
2054 /* 0 : other frames */
2057 /* Stephen ZyDAS Technology Corporation 2005.11 */
2059 /************************************************************************/
2060 u16_t zfIntrabssForward(zdev_t* dev, zbuf_t* buf, u8_t srcVap)
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);
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
2083 /* Do Intra-BSS forward(data copy) if necessary*/
2084 if ((dst[0]&0x1) != 0x1)
2086 aid = zfApGetSTAInfo(dev, dst, &staState, &vap);
2087 if ((aid != 0xffff) && (staState == ZM_STATE_ASOC) && (srcVap == vap))
2090 zm_msg0_rx(ZM_LV_2, "Intra-BSS forward : asoc STA");
2097 zm_msg0_rx(ZM_LV_2, "Intra-BSS forward : BCorMC");
2100 /* destination address = associated STA or BC/MC */
2101 if ((asocFlag == 1) || ((dst[0]&0x1) == 0x1))
2103 /* Allocate frame */
2104 if ((txBuf = zfwBufAllocate(dev, ZM_RX_FRAME_SIZE))
2107 zm_msg0_rx(ZM_LV_1, "Alloc intra-bss buf Fail!");
2112 len = zfwBufGetSize(dev, buf);
2113 for (i=0; i<len; i+=2)
2115 temp = zmw_rx_buf_readh(dev, buf, i);
2116 zmw_tx_buf_writeh(dev, txBuf, i, temp);
2118 zfwBufSetSize(dev, txBuf, len);
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)
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);
2134 /* Transmit frame */
2135 /* Return error if port is disabled */
2136 if ((err = zfTxPortControl(dev, txBuf, vap)) == ZM_PORT_DISABLED)
2138 err = ZM_ERR_TX_PORT_DISABLED;
2143 /* AP : Buffer frame for power saving STA */
2144 if ((ret = zfApBufferPsFrame(dev, txBuf, vap)) == 0)
2146 /* forward frame if not been buffered */
2148 /* Put to VTXQ[ac] */
2149 ret = zfPutVtxq(dev, txBuf);
2153 zfTxSendEth(dev, txBuf, vap, ZM_INTERNAL_ALLOC_BUF, 0);
2162 zfwBufFree(dev, txBuf, 0);
2167 struct zsMicVar* zfApGetRxMicKey(zdev_t* dev, zbuf_t* buf)
2170 u16_t id = 0, macAddr[3];
2172 zmw_get_wlan_dev(dev);
2174 zfCopyFromRxBuffer(dev, buf, sa, ZM_WLAN_HEADER_A2_OFFSET, 6);
2176 macAddr[0] = sa[0] + (sa[1] << 8);
2177 macAddr[1] = sa[2] + (sa[3] << 8);
2178 macAddr[2] = sa[4] + (sa[5] << 8);
2180 if ((id = zfApFindSta(dev, macAddr)) != 0xffff)
2181 return (&wd->ap.staTable[id].rxMicKey);
2186 struct zsMicVar* zfApGetTxMicKey(zdev_t* dev, zbuf_t* buf, u8_t* qosType)
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);
2212 u16_t zfApUpdatePsBit(zdev_t* dev, zbuf_t* buf, u8_t* vap, u8_t* uapsdTrig)
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)
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,
2245 return ZM_ERR_STA_NOT_ASSOCIATED;
2247 } /* if ((zmw_rx_buf_readb(dev, buf, 1) & 0x3) != 3) */
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]))
2268 void zfApProcessPsPoll(zdev_t* dev, zbuf_t* buf)
2272 zbuf_t* psBuf = NULL;
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);
2304 id = (id + 1) & (ZM_UNI_ARRAY_SIZE - 1);
2306 zmw_leave_critical_section(dev);
2308 /* Send ps buffer */
2311 /* Send with more data bit */
2312 zfTxSendEth(dev, psBuf, 0, ZM_EXTERNAL_ALLOC_BUF, moreData);
2318 void zfApSetProtectionMode(zdev_t* dev, u16_t mode)
2320 zmw_get_wlan_dev(dev);
2324 if (wd->ap.protectionMode != mode)
2326 /* Write MAC&PHY registers to disable protection */
2328 wd->ap.protectionMode = mode;
2334 if (wd->ap.protectionMode != mode)
2336 /* Write MAC&PHY registers to enable protection */
2338 wd->ap.protectionMode = mode;
2345 /************************************************************************/
2347 /* FUNCTION DESCRIPTION zfApSendFailure */
2351 /* dev : device pointer */
2352 /* addr : receiver address */
2358 /* Stephen Chen Atheros Communications, INC. 2007.1 */
2360 /************************************************************************/
2361 void zfApSendFailure(zdev_t* dev, u8_t* addr)
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 if ((id = zfApFindSta(dev, staAddr)) != 0xffff)
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);
2378 zmw_leave_critical_section(dev);
2382 void zfApProcessAction(zdev_t* dev, zbuf_t* buf)
2386 //zmw_get_wlan_dev(dev);
2388 //zmw_declare_for_critical_section();
2390 category = zmw_rx_buf_readb(dev, buf, 24);
2394 case ZM_WLAN_BLOCK_ACK_ACTION_FRAME:
2395 zfAggBlockAckActionFrame(dev, buf);