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 id = zfApFindSta(dev, addr);
147 *vap = wd->ap.staTable[id].vap;
148 *state = wd->ap.staTable[id++].state;
151 zmw_leave_critical_section(dev);
157 void zfApGetStaQosType(zdev_t* dev, u16_t* addr, u8_t* qosType)
161 zmw_get_wlan_dev(dev);
163 zmw_declare_for_critical_section();
165 zmw_enter_critical_section(dev);
167 id = zfApFindSta(dev, addr);
170 *qosType = wd->ap.staTable[id].qosType;
177 zmw_leave_critical_section(dev);
182 void zfApGetStaTxRateAndQosType(zdev_t* dev, u16_t* addr, u32_t* phyCtrl,
183 u8_t* qosType, u16_t* rcProbingFlag)
188 zmw_get_wlan_dev(dev);
190 zmw_declare_for_critical_section();
192 zmw_enter_critical_section(dev);
194 id = zfApFindSta(dev, addr);
197 rate = (u8_t)zfRateCtrlGetTxRate(dev, &wd->ap.staTable[id].rcCell, rcProbingFlag);
201 *phyCtrl = zcRateToPhyCtrl[rate];
202 *qosType = wd->ap.staTable[id].qosType;
206 if (wd->frequency < 3000)
209 //header[2] = 0x0f00; //PHY control L
210 //header[3] = 0x0000; //PHY control H
211 *phyCtrl = 0x00000F00;
216 //header[2] = 0x0f01; //PHY control L
217 //header[3] = 0x000B; //PHY control H
218 *phyCtrl = 0x000B0F01;
223 zmw_leave_critical_section(dev);
225 zm_msg2_mm(ZM_LV_3, "PhyCtrl=", *phyCtrl);
229 void zfApGetStaEncryType(zdev_t* dev, u16_t* addr, u8_t* encryType)
231 //struct zsWlanDev* wd = (struct zsWlanDev*) zmw_wlan_dev(dev);
234 zmw_get_wlan_dev(dev);
236 zmw_declare_for_critical_section();
238 zmw_enter_critical_section(dev);
240 id = zfApFindSta(dev, addr);
243 *encryType = wd->ap.staTable[id].encryMode;
247 *encryType = ZM_NO_WEP;
250 zmw_leave_critical_section(dev);
252 zm_msg2_mm(ZM_LV_3, "encyrType=", *encryType);
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);
261 zmw_get_wlan_dev(dev);
263 zmw_declare_for_critical_section();
265 zmw_enter_critical_section(dev);
267 id = zfApFindSta(dev, addr);
270 *iv16 = wd->ap.staTable[id].iv16;
271 *iv32 = wd->ap.staTable[id].iv32;
279 zmw_leave_critical_section(dev);
281 zm_msg2_mm(ZM_LV_3, "iv16=", *iv16);
282 zm_msg2_mm(ZM_LV_3, "iv32=", *iv32);
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);
291 zmw_get_wlan_dev(dev);
293 zmw_declare_for_critical_section();
295 zmw_enter_critical_section(dev);
297 id = zfApFindSta(dev, addr);
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);
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 };
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);
326 zmw_declare_for_critical_section();
328 zmw_enter_critical_section(dev);
330 id = zfApFindSta(dev, addr);
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;
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);
352 zmw_get_wlan_dev(dev);
353 zmw_declare_for_critical_section();
356 zmw_enter_critical_section(dev);
358 id = zfApFindSta(dev, addr);
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;
376 zmw_leave_critical_section(dev);
380 void zfApSetStaCencIv(zdev_t* dev, u16_t* addr, u32_t *iv)
382 //struct zsWlanDev* wd = (struct zsWlanDev*) zmw_wlan_dev(dev);
384 zmw_get_wlan_dev(dev);
385 zmw_declare_for_critical_section();
388 zmw_enter_critical_section(dev);
390 id = zfApFindSta(dev, addr);
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);
403 #endif //ZM_ENABLE_CENC
406 /************************************************************************/
408 /* FUNCTION DESCRIPTION zfApFlushBufferedPsFrame */
409 /* Free buffered PS frames. */
412 /* dev : device pointer */
418 /* Stephen Chen Atheros Communications, INC. 2007.1 */
420 /************************************************************************/
421 void zfApFlushBufferedPsFrame(zdev_t* dev)
426 zbuf_t* psBuf = NULL;
427 zmw_get_wlan_dev(dev);
428 zmw_declare_for_critical_section();
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);
445 zmw_leave_critical_section(dev);
449 zfwBufFree(dev, psBuf, ZM_ERR_FLUSH_PS_QUEUE);
451 zm_assert(freeCount++ < (ZM_UNI_ARRAY_SIZE*2));
459 for (vap=0; vap<ZM_MAX_AP_SUPPORT; vap++)
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);
477 zmw_leave_critical_section(dev);
481 zfwBufFree(dev, psBuf, ZM_ERR_FLUSH_PS_QUEUE);
483 zm_assert(freeCount++ < (ZM_BCMC_ARRAY_SIZE*2));
495 u16_t zfApBufferPsFrame(zdev_t* dev, zbuf_t* buf, u16_t port)
505 zmw_get_wlan_dev(dev);
507 zmw_declare_for_critical_section();
509 if (port < ZM_MAX_AP_SUPPORT)
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");
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);
549 zmw_enter_critical_section(dev);
551 id = zfApFindSta(dev, addr);
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);
572 /* Buffer this unicast frame */
573 if (((wd->ap.uniTail+1)&(ZM_UNI_ARRAY_SIZE-1))
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");
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);
592 } /* if (wd->ap.staTable[id++].psMode == 1) */
593 } /* if ((id = zfApFindSta(dev, addr)) != 0xffff) */
594 zmw_leave_critical_section(dev);
600 u16_t zfApGetSTAInfoAndUpdatePs(zdev_t* dev, u16_t* addr, u16_t* state,
601 u8_t* vap, u16_t psMode, u8_t* uapsdTrig)
604 u8_t uapsdStaAwake = 0;
606 zmw_get_wlan_dev(dev);
608 zmw_declare_for_critical_section();
610 zmw_enter_critical_section(dev);
616 id = zfApFindSta(dev, addr);
621 zm_msg0_mm(ZM_LV_0, "psMode = 1");
622 if (wd->ap.staTable[id].psMode == 0)
624 wd->ap.staPowerSaving++;
628 if (wd->ap.staTable[id].qosType == 1)
630 zm_msg0_mm(ZM_LV_0, "UAPSD trigger");
631 *uapsdTrig = wd->ap.staTable[id].qosInfo;
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))
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)
662 psBuf = zfQueueGetWithMac(dev, wd->ap.uapsdQ, (u8_t*)addr, &mb);
665 zfTxSendEth(dev, psBuf, 0, ZM_EXTERNAL_ALLOC_BUF, 0);
677 /************************************************************************/
679 /* FUNCTION DESCRIPTION zfApGetNewSta */
680 /* Get a new STA from station table. */
683 /* dev : device pointer */
687 /* other : STA table index */
690 /* Stephen Chen ZyDAS Technology Corporation 2005.10 */
692 /************************************************************************/
693 u16_t zfApGetNewSta(zdev_t* dev)
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);
711 /************************************************************************/
713 /* FUNCTION DESCRIPTION zfApAddSta */
714 /* Add a STA to station table. */
717 /* dev : device pointer */
718 /* addr : STA MAC address */
719 /* state : STA state */
720 /* apId : Virtual AP ID */
721 /* type : 0=>11b, 1=>11g */
728 /* Stephen Chen ZyDAS Technology Corporation 2005.10 */
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)
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);
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)
771 zfRateCtrlInitCell(dev, &wd->ap.staTable[index].rcCell, type, 1, 1);
776 zfRateCtrlInitCell(dev, &wd->ap.staTable[index].rcCell, type, 0, 1);
779 if (wd->zfcbApConnectNotify != NULL)
781 wd->zfcbApConnectNotify(dev, (u8_t*)addr, apId);
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);
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);
820 /************************************************************************/
822 /* FUNCTION DESCRIPTION zfApAgingSta */
823 /* Aging STA in station table. */
826 /* dev : device pointer */
829 /* number of 11b STA in STA table */
832 /* Stephen Chen ZyDAS Technology Corporation 2005.10 */
834 /************************************************************************/
835 void zfApAgingSta(zdev_t* dev)
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++)
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];
859 deltaMs = (u32_t)((u32_t)wd->tick-(u32_t)wd->ap.staTable[i].time)
863 if ((wd->ap.staTable[i].state == ZM_STATE_PREAUTH)
864 && (deltaMs > ZM_PREAUTH_TIMEOUT_MS))
867 wd->ap.staTable[i].valid = 0;
868 wd->ap.authSharing = 0;
873 if ((wd->ap.staTable[i].state == ZM_STATE_AUTH)
874 && (deltaMs > ZM_AUTH_TIMEOUT_MS))
877 wd->ap.staTable[i].valid = 0;
882 if (wd->ap.staTable[i].state == ZM_STATE_ASOC)
884 if (wd->ap.staTable[i].psMode != 0)
889 if (deltaMs > ((u32_t)wd->ap.staAgingTimeSec<<10))
892 zm_msg1_mm(ZM_LV_0, "Age STA index=", i);
893 wd->ap.staTable[i].valid = 0;
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);
911 zmw_leave_critical_section(dev);
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;
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);
959 /* Disable NonErp bit in information element */
962 /* Disable protection mode */
963 zfApSetProtectionMode(dev, 0);
965 wd->ap.protectedObss = 0;
969 void zfApProcessBeacon(zdev_t* dev, zbuf_t* buf)
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)
983 wd->ap.protectedObss++;
987 ch = zmw_rx_buf_readb(dev, buf, offset+2);
988 if ((ch & ZM_WLAN_USE_PROTECTION_BIT) == ZM_WLAN_USE_PROTECTION_BIT)
991 wd->ap.protectedObss = 1;
998 /************************************************************************/
1000 /* FUNCTION DESCRIPTION zfProcessAuth */
1001 /* Process authenticate management frame. */
1004 /* dev : device pointer */
1005 /* buf : auth frame buffer */
1011 /* Stephen Chen ZyDAS Technology Corporation 2005.10 */
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;
1024 u8_t challengePassed = 0;
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);
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 */
1057 if (wd->ap.authAlgo[apId] == 0)
1059 retAlgoSeq = 0x20000;
1062 /* AP : update STA to auth */
1063 ret = zfApAddSta(dev, src, ZM_STATE_AUTH, apId, 0, 0, 0);
1066 /* AP : call zfwAuthNotify() for host to judge */
1067 //zfwAuthNotify(dev, src);
1069 /* AP : response Auth seq=2, success */
1075 /* AP : response Auth seq=2, unspecific error */
1081 /* AP : response Auth seq=2, sequence number out of expected */
1086 /* AP : Auth share 1 */
1089 if (wd->ap.authAlgo[apId] == 1)
1093 retAlgoSeq = 0x20001;
1095 /* critical section */
1096 zmw_enter_critical_section(dev);
1097 if (wd->ap.authSharing == 1)
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 */
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 */
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))
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 */
1159 /* AP : response Auth seq=2, challenge failure */
1162 /* TODO : delete STA */
1165 wd->ap.authSharing = 0;
1170 retAlgoSeq = 0x40001;
1176 zfSendMmFrame(dev, ZM_WLAN_FRAME_TYPE_AUTH, src, retAlgoSeq,
1181 void zfApProcessAsocReq(zdev_t* dev, zbuf_t* buf, u16_t* src, u16_t apId)
1193 zmw_get_wlan_dev(dev);
1194 /* AP : check SSID */
1195 offset = zfFindElement(dev, buf, ZM_WLAN_EID_SSID);
1196 if (offset != 0xffff)
1199 for (j = 0; j < wd->ap.vapNumber; j++)
1201 tmp = zmw_buf_readb(dev, buf, offset+1);
1203 != wd->ap.ssidLen[j])
1208 if (k == wd->ap.vapNumber)
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);
1220 != wd->ap.ssid[j][i])
1225 if (i == wd->ap.ssidLen[j])
1234 if (k == wd->ap.vapNumber)
1240 /* TODO : check capability */
1242 /* AP : check support rate */
1243 offset = zfFindElement(dev, buf, ZM_WLAN_EID_EXTENDED_RATE);
1244 if (offset != 0xffff)
1250 offset = zfFindElement(dev, buf, ZM_WLAN_EID_HT_CAPABILITY);
1251 if (offset != 0xffff)
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);
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)
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)
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)
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;
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);
1314 else if ( (offset = zfFindElement(dev, buf, ZM_WLAN_EID_RSN_IE)) != 0xffff )
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;
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);
1337 #ifdef ZM_ENABLE_CENC
1338 else if ( (offset = zfFindElement(dev, buf, ZM_WLAN_EID_CENC_IE)) != 0xffff )
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;
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);
1363 #endif //ZM_ENABLE_CENC
1365 { /* ap is encryption but sta has no wpa/rsn ie */
1366 zfSendMmFrame(dev, ZM_WLAN_FRAME_TYPE_DEAUTH, src, 6, 0, 0);
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);
1377 /* AP : update STA to asoc */
1378 aid = zfApAddSta(dev, src, ZM_STATE_ASOC, apId, staType, qosType, qosInfo);
1380 zfApStoreAsocReqIe(dev, buf, aid);
1383 /* AP : send asoc rsp2 */
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);
1394 zfSendMmFrame(dev, ZM_WLAN_FRAME_TYPE_REASOCRSP, src, 0, aid+1, apId);
1399 /* TODO : send deauthentication */
1400 zfSendMmFrame(dev, ZM_WLAN_FRAME_TYPE_DEAUTH, src, 6, 0, 0);
1406 void zfApStoreAsocReqIe(zdev_t* dev, zbuf_t* buf, u16_t aid)
1408 //struct zsWlanAssoFrameHeader* pAssoFrame;
1409 //u8_t pBuf[sizeof(struct zsWlanAssoFrameHeader)];
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 */
1424 /* Listen interval: 2 octets */
1430 /* supported rates */
1431 offset = zfFindElement(dev, buf, ZM_WLAN_EID_SUPPORT_RATE);
1432 if (offset == 0xffff)
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)
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;
1452 /* HT capabilities: 28 octets */
1453 offset = zfFindElement(dev, buf, ZM_WLAN_EID_HT_CAPABILITY);
1454 if (offset != 0xffff) {
1456 htcap = (u8_t *)&wd->ap.ie[aid].HtCap;
1457 htcap[0] = zmw_rx_buf_readb(dev, buf, offset);
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]);
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]);
1481 /* supported regulatory classes */
1482 offset = offset + length;
1483 //length = zmw_rx_buf_readb(dev, buf, offset + 1);
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)
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);
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)
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);
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)
1548 zmw_get_wlan_dev(dev);
1550 zm_msg0_mm(ZM_LV_0, "Rx probersp");
1552 /* Gather scan result */
1554 //zm_debug_msg1("bssList Count = ", wd->sta.bssList.bssCount);
1555 /* return if not in scanning */
1556 if ((wd->heartBeatNotification & ZM_BSSID_LIST_SCAN)
1557 != ZM_BSSID_LIST_SCAN)
1562 //if ( wd->sta.pUpdateBssList->bssCount == ZM_MAX_BSS )
1563 if ( wd->sta.bssList.bssCount == ZM_MAX_BSS )
1568 zfProcessProbeRsp(dev, buf, AddInfo);
1573 /************************************************************************/
1575 /* FUNCTION DESCRIPTION zfApAddIeSsid */
1576 /* Add AP information element SSID to buffer. */
1579 /* dev : device pointer */
1580 /* buf : buffer to add information element */
1581 /* offset : add information element from this offset */
1582 /* vap : virtual AP ID */
1585 /* buffer offset after adding information element */
1588 /* Stephen Chen ZyDAS Technology Corporation 2005.11 */
1590 /************************************************************************/
1591 u16_t zfApAddIeSsid(zdev_t* dev, zbuf_t* buf, u16_t offset, u16_t vap)
1595 zmw_get_wlan_dev(dev);
1598 zmw_tx_buf_writeb(dev, buf, offset++, ZM_WLAN_EID_SSID);
1600 /* Element Length */
1601 zmw_tx_buf_writeb(dev, buf, offset++, wd->ap.ssidLen[vap]);
1603 /* Information : SSID */
1604 for (i=0; i<wd->ap.ssidLen[vap]; i++)
1606 zmw_tx_buf_writeb(dev, buf, offset++, wd->ap.ssid[vap][i]);
1613 /************************************************************************/
1615 /* FUNCTION DESCRIPTION zfApAddIeTim */
1616 /* Add AP information element TIM to buffer. */
1619 /* dev : device pointer */
1620 /* buf : buffer to add information element */
1621 /* offset : add information element from this offset */
1622 /* vap : virtual AP ID */
1625 /* buffer offset after adding information element */
1628 /* Stephen Chen ZyDAS Technology Corporation 2005.11 */
1630 /************************************************************************/
1631 u16_t zfApAddIeTim(zdev_t* dev, zbuf_t* buf, u16_t offset, u16_t vap)
1643 zbuf_t* tmpBufArray[ZM_UNI_ARRAY_SIZE];
1644 u16_t tmpBufArraySize = 0;
1646 zmw_get_wlan_dev(dev);
1648 zmw_declare_for_critical_section();
1651 zmw_tx_buf_writeb(dev, buf, offset++, ZM_WLAN_EID_TIM);
1653 /* offset of Element Length */
1654 lenOffset = offset++;
1656 /* Information : TIM */
1658 /* TODO : Doesn't work for Virtual AP's case */
1659 wd->CurrentDtimCount++;
1660 if (wd->CurrentDtimCount >= wd->dtim)
1662 wd->CurrentDtimCount = 0;
1664 zmw_tx_buf_writeb(dev, buf, offset++, wd->CurrentDtimCount);
1666 zmw_tx_buf_writeb(dev, buf, offset++, wd->dtim);
1668 zmw_tx_buf_writeb(dev, buf, offset++, 0);
1670 /* Update BCMC bit */
1671 if (wd->CurrentDtimCount == 0)
1673 zmw_enter_critical_section(dev);
1674 wd->ap.timBcmcBit[vap] = (wd->ap.bcmcTail[vap]!=wd->ap.bcmcHead[vap])?1:0;
1675 zmw_leave_critical_section(dev);
1679 wd->ap.timBcmcBit[vap] = 0;
1682 /* Update Unicast bitmap */
1691 zmw_enter_critical_section(dev);
1693 id = wd->ap.uniHead;
1694 while (id != wd->ap.uniTail)
1696 psBuf = wd->ap.uniArray[id];
1698 /* TODO : Aging PS frame after queuing for more than 10 seconds */
1700 /* get destination STA's aid */
1701 dst[0] = zmw_tx_buf_readh(dev, psBuf, 0);
1702 dst[1] = zmw_tx_buf_readh(dev, psBuf, 2);
1703 dst[2] = zmw_tx_buf_readh(dev, psBuf, 4);
1704 aid = zfApFindSta(dev, dst);
1707 if (wd->ap.staTable[aid].psMode != 0)
1709 zm_msg1_mm(ZM_LV_0, "aid=",aid);
1712 bitPosition = (1 << (aid & 0x7));
1713 bytePosition = (aid >> 3);
1714 uniBitMap[bytePosition] |= bitPosition;
1716 if (bytePosition>highestByte)
1718 highestByte = bytePosition;
1720 id = (id+1) & (ZM_UNI_ARRAY_SIZE-1);
1724 zm_msg0_mm(ZM_LV_0, "Send PS frame which STA no longer in PS mode");
1725 /* Send PS frame which STA no longer in PS mode */
1726 zfApRemoveFromPsQueue(dev, id, dst);
1727 tmpBufArray[tmpBufArraySize++] = psBuf;
1732 zm_msg0_mm(ZM_LV_0, "Free garbage PS frame");
1733 /* Free garbage PS frame */
1734 zfApRemoveFromPsQueue(dev, id, dst);
1735 zfwBufFree(dev, psBuf, 0);
1739 zmw_leave_critical_section(dev);
1742 zfQueueGenerateUapsdTim(dev, wd->ap.uapsdQ, uniBitMap, &highestByte);
1744 zm_msg1_mm(ZM_LV_3, "bm=",uniBitMap[0]);
1745 zm_msg1_mm(ZM_LV_3, "highestByte=",highestByte);
1746 zm_msg1_mm(ZM_LV_3, "timBcmcBit[]=",wd->ap.timBcmcBit[vap]);
1749 zmw_tx_buf_writeb(dev, buf, offset++,
1750 uniBitMap[0] | wd->ap.timBcmcBit[vap]);
1751 for (i=0; i<highestByte; i++)
1753 zmw_tx_buf_writeb(dev, buf, offset++, uniBitMap[i+1]);
1756 /* Element Length */
1757 zmw_tx_buf_writeb(dev, buf, lenOffset, highestByte+4);
1759 for (i=0; i<tmpBufArraySize; i++)
1761 /* Put to VTXQ[ac] */
1762 zfPutVtxq(dev, tmpBufArray[i]);
1772 /************************************************************************/
1774 /* FUNCTION DESCRIPTION zfApRemoveFromPsQueue */
1775 /* Remove zbuf from PS queue. */
1778 /* dev : device pointer */
1779 /* id : index in ps queue */
1785 /* Stephen Chen Atheros Communications, INC. 2007.1 */
1787 /************************************************************************/
1788 u8_t zfApRemoveFromPsQueue(zdev_t* dev, u16_t id, u16_t* addr)
1793 zmw_get_wlan_dev(dev);
1795 wd->ap.uniTail = (wd->ap.uniTail-1) & (ZM_UNI_ARRAY_SIZE-1);
1796 while (id != wd->ap.uniTail)
1798 nid = (id + 1) & (ZM_UNI_ARRAY_SIZE - 1);
1799 wd->ap.uniArray[id] = wd->ap.uniArray[nid];
1801 /* Search until tail to config more data bit */
1802 dst[0] = zmw_buf_readh(dev, wd->ap.uniArray[id], 0);
1803 dst[1] = zmw_buf_readh(dev, wd->ap.uniArray[id], 2);
1804 dst[2] = zmw_buf_readh(dev, wd->ap.uniArray[id], 4);
1805 if ((addr[0] == dst[0]) && (addr[1] == dst[1])
1806 && (addr[2] == dst[2]))
1816 /************************************************************************/
1818 /* FUNCTION DESCRIPTION zfApAddIeWmePara */
1819 /* Add WME Parameter Element to buffer. */
1822 /* dev : device pointer */
1823 /* buf : buffer to add information element */
1824 /* offset : add information element from this offset */
1825 /* vap : virtual AP ID */
1828 /* buffer offset after adding information element */
1831 /* Stephen Chen ZyDAS Technology Corporation 2006.1 */
1833 /************************************************************************/
1834 u16_t zfApAddIeWmePara(zdev_t* dev, zbuf_t* buf, u16_t offset, u16_t vap)
1836 zmw_get_wlan_dev(dev);
1839 zmw_tx_buf_writeb(dev, buf, offset++, ZM_WLAN_EID_WIFI_IE);
1841 /* Element Length */
1842 zmw_tx_buf_writeb(dev, buf, offset++, 24);
1845 zmw_tx_buf_writeb(dev, buf, offset++, 0x00);
1846 zmw_tx_buf_writeb(dev, buf, offset++, 0x50);
1847 zmw_tx_buf_writeb(dev, buf, offset++, 0xF2);
1848 zmw_tx_buf_writeb(dev, buf, offset++, 0x02);
1849 zmw_tx_buf_writeb(dev, buf, offset++, 0x01);
1850 zmw_tx_buf_writeb(dev, buf, offset++, 0x01);
1853 if (wd->ap.uapsdEnabled)
1855 zmw_tx_buf_writeb(dev, buf, offset++, 0x81);
1859 zmw_tx_buf_writeb(dev, buf, offset++, 0x01);
1863 zmw_tx_buf_writeb(dev, buf, offset++, 0x00);
1865 /* Best Effort AC parameters */
1866 zmw_tx_buf_writeb(dev, buf, offset++, 0x03);
1867 zmw_tx_buf_writeb(dev, buf, offset++, 0xA4);
1868 zmw_tx_buf_writeb(dev, buf, offset++, 0x00);
1869 zmw_tx_buf_writeb(dev, buf, offset++, 0x00);
1870 /* Backfround AC parameters */
1871 zmw_tx_buf_writeb(dev, buf, offset++, 0x27);
1872 zmw_tx_buf_writeb(dev, buf, offset++, 0xA4);
1873 zmw_tx_buf_writeb(dev, buf, offset++, 0x00);
1874 zmw_tx_buf_writeb(dev, buf, offset++, 0x00);
1875 /* Video AC parameters */
1876 zmw_tx_buf_writeb(dev, buf, offset++, 0x42);
1877 zmw_tx_buf_writeb(dev, buf, offset++, 0x43);
1878 zmw_tx_buf_writeb(dev, buf, offset++, 0x5E);
1879 zmw_tx_buf_writeb(dev, buf, offset++, 0x00);
1880 /* Voice AC parameters */
1881 zmw_tx_buf_writeb(dev, buf, offset++, 0x62);
1882 zmw_tx_buf_writeb(dev, buf, offset++, 0x32);
1883 zmw_tx_buf_writeb(dev, buf, offset++, 0x2F);
1884 zmw_tx_buf_writeb(dev, buf, offset++, 0x00);
1890 /************************************************************************/
1892 /* FUNCTION DESCRIPTION zfApSendBeacon */
1893 /* Sned AP mode beacon. */
1896 /* dev : device pointer */
1902 /* Stephen Chen ZyDAS Technology Corporation 2005.11 */
1904 /************************************************************************/
1905 void zfApSendBeacon(zdev_t* dev)
1912 zmw_get_wlan_dev(dev);
1914 zmw_declare_for_critical_section();
1916 wd->ap.beaconCounter++;
1917 if (wd->ap.beaconCounter >= wd->ap.vapNumber)
1919 wd->ap.beaconCounter = 0;
1921 vap = wd->ap.beaconCounter;
1924 zm_msg1_mm(ZM_LV_2, "Send beacon, vap=", vap);
1926 /* TBD : Maximum size of beacon */
1927 buf = zfwBufAllocate(dev, 1024);
1930 zm_msg0_mm(ZM_LV_0, "Alloc beacon buf Fail!");
1938 zmw_tx_buf_writeh(dev, buf, offset, 0x0080);
1941 zmw_tx_buf_writeh(dev, buf, offset, 0x0000);
1944 zmw_tx_buf_writeh(dev, buf, offset, 0xffff);
1946 zmw_tx_buf_writeh(dev, buf, offset, 0xffff);
1948 zmw_tx_buf_writeh(dev, buf, offset, 0xffff);
1951 zmw_tx_buf_writeh(dev, buf, offset, wd->macAddr[0]);
1953 zmw_tx_buf_writeh(dev, buf, offset, wd->macAddr[1]);
1955 #ifdef ZM_VAPMODE_MULTILE_SSID
1956 zmw_tx_buf_writeh(dev, buf, offset, wd->macAddr[2]); //Multiple SSID
1958 zmw_tx_buf_writeh(dev, buf, offset, (wd->macAddr[2]+(vap<<8))); //VAP
1962 zmw_tx_buf_writeh(dev, buf, offset, wd->macAddr[0]);
1964 zmw_tx_buf_writeh(dev, buf, offset, wd->macAddr[1]);
1966 #ifdef ZM_VAPMODE_MULTILE_SSID
1967 zmw_tx_buf_writeh(dev, buf, offset, wd->macAddr[2]); //Multiple SSID
1969 zmw_tx_buf_writeh(dev, buf, offset, (wd->macAddr[2]+(vap<<8))); //VAP
1973 /* Sequence number */
1974 zmw_enter_critical_section(dev);
1975 seq = ((wd->mmseq++)<<4);
1976 zmw_leave_critical_section(dev);
1977 zmw_tx_buf_writeh(dev, buf, offset, seq);
1980 /* 24-31 Time Stamp : hardware will fill this field */
1981 zmw_tx_buf_writeh(dev, buf, offset, 0);
1982 zmw_tx_buf_writeh(dev, buf, offset+2, 0);
1983 zmw_tx_buf_writeh(dev, buf, offset+4, 0);
1984 zmw_tx_buf_writeh(dev, buf, offset+6, 0);
1987 /* Beacon Interval */
1988 zmw_tx_buf_writeh(dev, buf, offset, wd->beaconInterval);
1992 zmw_tx_buf_writeh(dev, buf, offset, wd->ap.capab[vap]);
1996 if (wd->ap.hideSsid[vap] == 0)
1998 offset = zfApAddIeSsid(dev, buf, offset, vap);
2002 zmw_tx_buf_writeb(dev, buf, offset++, ZM_WLAN_EID_SSID);
2003 zmw_tx_buf_writeb(dev, buf, offset++, 0);
2008 if ( wd->frequency < 3000 )
2010 offset = zfMmAddIeSupportRate(dev, buf, offset,
2011 ZM_WLAN_EID_SUPPORT_RATE, ZM_RATE_SET_CCK);
2015 offset = zfMmAddIeSupportRate(dev, buf, offset,
2016 ZM_WLAN_EID_SUPPORT_RATE, ZM_RATE_SET_OFDM);
2019 /* DS parameter set */
2020 offset = zfMmAddIeDs(dev, buf, offset);
2023 offset = zfApAddIeTim(dev, buf, offset, vap);
2025 /* If WLAN Type is not PURE B */
2026 if (wd->ap.wlanType[vap] != ZM_WLAN_TYPE_PURE_B)
2028 if ( wd->frequency < 3000 )
2030 /* ERP Information */
2031 offset = zfMmAddIeErp(dev, buf, offset);
2033 /* Extended Supported Rates */
2034 offset = zfMmAddIeSupportRate(dev, buf, offset,
2035 ZM_WLAN_EID_EXTENDED_RATE, ZM_RATE_SET_OFDM);
2039 /* TODO : country information */
2041 if (wd->ap.wpaSupport[vap] == 1)
2043 offset = zfMmAddIeWpa(dev, buf, offset, vap);
2046 /* WME Parameters */
2047 if (wd->ap.qosMode == 1)
2049 offset = zfApAddIeWmePara(dev, buf, offset, vap);
2052 /* HT Capabilities Info */
2053 offset = zfMmAddHTCapability(dev, buf, offset);
2055 /* Extended HT Capabilities Info */
2056 offset = zfMmAddExtendedHTCapability(dev, buf, offset);
2058 /* 1212 : write to beacon fifo */
2059 /* 1221 : write to share memory */
2060 zfHpSendBeacon(dev, buf, offset);
2062 /* Free beacon buffer */
2063 /* TODO: In order to fit the madwifi beacon architecture, we need to
2064 free beacon buffer in the HAL layer.
2067 //zfwBufFree(dev, buf, 0);
2071 /************************************************************************/
2073 /* FUNCTION DESCRIPTION zfIntrabssForward */
2074 /* Called to transmit intra-BSS frame from upper layer. */
2077 /* dev : device pointer */
2078 /* buf : buffer pointer */
2079 /* vap : virtual AP */
2082 /* 1 : unicast intras-BSS frame */
2083 /* 0 : other frames */
2086 /* Stephen ZyDAS Technology Corporation 2005.11 */
2088 /************************************************************************/
2089 u16_t zfIntrabssForward(zdev_t* dev, zbuf_t* buf, u8_t srcVap)
2102 #ifdef ZM_ENABLE_NATIVE_WIFI
2103 dst[0] = zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A3_OFFSET);
2104 dst[1] = zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A3_OFFSET+2);
2105 dst[2] = zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A3_OFFSET+4);
2107 dst[0] = zmw_rx_buf_readh(dev, buf, 0);
2108 dst[1] = zmw_rx_buf_readh(dev, buf, 2);
2109 dst[2] = zmw_rx_buf_readh(dev, buf, 4);
2110 #endif // ZM_ENABLE_NATIVE_WIFI
2112 /* Do Intra-BSS forward(data copy) if necessary*/
2113 if ((dst[0]&0x1) != 0x1)
2115 aid = zfApGetSTAInfo(dev, dst, &staState, &vap);
2116 if ((aid != 0xffff) && (staState == ZM_STATE_ASOC) && (srcVap == vap))
2119 zm_msg0_rx(ZM_LV_2, "Intra-BSS forward : asoc STA");
2126 zm_msg0_rx(ZM_LV_2, "Intra-BSS forward : BCorMC");
2129 /* destination address = associated STA or BC/MC */
2130 if ((asocFlag == 1) || ((dst[0]&0x1) == 0x1))
2132 /* Allocate frame */
2133 txBuf = zfwBufAllocate(dev, ZM_RX_FRAME_SIZE);
2136 zm_msg0_rx(ZM_LV_1, "Alloc intra-bss buf Fail!");
2141 len = zfwBufGetSize(dev, buf);
2142 for (i=0; i<len; i+=2)
2144 temp = zmw_rx_buf_readh(dev, buf, i);
2145 zmw_tx_buf_writeh(dev, txBuf, i, temp);
2147 zfwBufSetSize(dev, txBuf, len);
2149 #ifdef ZM_ENABLE_NATIVE_WIFI
2150 /* Tx-A2 = Rx-A1, Tx-A3 = Rx-A2, Tx-A1 = Rx-A3 */
2151 for (i=0; i<6; i+=2)
2153 temp = zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A1_OFFSET+i);
2154 zmw_tx_buf_writeh(dev, txBuf, ZM_WLAN_HEADER_A2_OFFSET+i, temp);
2155 temp = zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A2_OFFSET+i);
2156 zmw_tx_buf_writeh(dev, txBuf, ZM_WLAN_HEADER_A3_OFFSET+i, temp);
2157 temp = zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A3_OFFSET+i);
2158 zmw_tx_buf_writeh(dev, txBuf, ZM_WLAN_HEADER_A1_OFFSET+i, temp);
2163 /* Transmit frame */
2164 /* Return error if port is disabled */
2165 err = zfTxPortControl(dev, txBuf, vap);
2166 if (err == ZM_PORT_DISABLED)
2168 err = ZM_ERR_TX_PORT_DISABLED;
2173 /* AP : Buffer frame for power saving STA */
2174 ret = zfApBufferPsFrame(dev, txBuf, vap);
2177 /* forward frame if not been buffered */
2179 /* Put to VTXQ[ac] */
2180 ret = zfPutVtxq(dev, txBuf);
2184 zfTxSendEth(dev, txBuf, vap, ZM_INTERNAL_ALLOC_BUF, 0);
2193 zfwBufFree(dev, txBuf, 0);
2198 struct zsMicVar* zfApGetRxMicKey(zdev_t* dev, zbuf_t* buf)
2201 u16_t id = 0, macAddr[3];
2203 zmw_get_wlan_dev(dev);
2205 zfCopyFromRxBuffer(dev, buf, sa, ZM_WLAN_HEADER_A2_OFFSET, 6);
2207 macAddr[0] = sa[0] + (sa[1] << 8);
2208 macAddr[1] = sa[2] + (sa[3] << 8);
2209 macAddr[2] = sa[4] + (sa[5] << 8);
2211 id = zfApFindSta(dev, macAddr);
2213 return (&wd->ap.staTable[id].rxMicKey);
2218 struct zsMicVar* zfApGetTxMicKey(zdev_t* dev, zbuf_t* buf, u8_t* qosType)
2221 u16_t id = 0, macAddr[3];
2223 zmw_get_wlan_dev(dev);
2225 zfCopyFromIntTxBuffer(dev, buf, da, 0, 6);
2227 macAddr[0] = da[0] + (da[1] << 8);
2228 macAddr[1] = da[2] + (da[3] << 8);
2229 macAddr[2] = da[4] + (da[5] << 8);
2231 if ((macAddr[0] & 0x1))
2233 return (&wd->ap.bcMicKey[0]);
2235 else if ((id = zfApFindSta(dev, macAddr)) != 0xffff)
2237 *qosType = wd->ap.staTable[id].qosType;
2238 return (&wd->ap.staTable[id].txMicKey);
2244 u16_t zfApUpdatePsBit(zdev_t* dev, zbuf_t* buf, u8_t* vap, u8_t* uapsdTrig)
2253 zmw_get_wlan_dev(dev);
2255 src[0] = zmw_rx_buf_readh(dev, buf, 10);
2256 src[1] = zmw_rx_buf_readh(dev, buf, 12);
2257 src[2] = zmw_rx_buf_readh(dev, buf, 14);
2259 if ((zmw_rx_buf_readb(dev, buf, 1) & 0x3) != 3)
2262 dst[0] = zmw_rx_buf_readh(dev, buf, 4);
2264 psBit = (zmw_rx_buf_readb(dev, buf, 1) & 0x10) >> 4;
2265 /* Get AID and update STA PS mode */
2266 aid = zfApGetSTAInfoAndUpdatePs(dev, src, &staState, vap, psBit, uapsdTrig);
2268 /* if STA not associated, send deauth */
2269 if ((aid == 0xffff) || (staState != ZM_STATE_ASOC))
2271 if ((dst[0]&0x1)==0)
2273 zfSendMmFrame(dev, ZM_WLAN_FRAME_TYPE_DEAUTH, src, 0x7,
2277 return ZM_ERR_STA_NOT_ASSOCIATED;
2279 } /* if ((zmw_rx_buf_readb(dev, buf, 1) & 0x3) != 3) */
2283 for (i=0; i<ZM_MAX_WDS_SUPPORT; i++)
2285 if ((wd->ap.wds.wdsBitmap & (1<<i)) != 0)
2287 if ((src[0] == wd->ap.wds.macAddr[i][0])
2288 && (src[1] == wd->ap.wds.macAddr[i][1])
2289 && (src[2] == wd->ap.wds.macAddr[i][2]))
2300 void zfApProcessPsPoll(zdev_t* dev, zbuf_t* buf)
2304 zbuf_t* psBuf = NULL;
2308 zmw_get_wlan_dev(dev);
2310 zmw_declare_for_critical_section();
2312 src[0] = zmw_tx_buf_readh(dev, buf, 10);
2313 src[1] = zmw_tx_buf_readh(dev, buf, 12);
2314 src[2] = zmw_tx_buf_readh(dev, buf, 14);
2316 /* Find ps buffer for PsPoll */
2317 zmw_enter_critical_section(dev);
2318 id = wd->ap.uniHead;
2319 while (id != wd->ap.uniTail)
2321 psBuf = wd->ap.uniArray[id];
2323 dst[0] = zmw_tx_buf_readh(dev, psBuf, 0);
2324 dst[1] = zmw_tx_buf_readh(dev, psBuf, 2);
2325 dst[2] = zmw_tx_buf_readh(dev, psBuf, 4);
2327 if ((src[0] == dst[0]) && (src[1] == dst[1]) && (src[2] == dst[2]))
2329 moreData = zfApRemoveFromPsQueue(dev, id, src);
2336 id = (id + 1) & (ZM_UNI_ARRAY_SIZE - 1);
2338 zmw_leave_critical_section(dev);
2340 /* Send ps buffer */
2343 /* Send with more data bit */
2344 zfTxSendEth(dev, psBuf, 0, ZM_EXTERNAL_ALLOC_BUF, moreData);
2350 void zfApSetProtectionMode(zdev_t* dev, u16_t mode)
2352 zmw_get_wlan_dev(dev);
2356 if (wd->ap.protectionMode != mode)
2358 /* Write MAC&PHY registers to disable protection */
2360 wd->ap.protectionMode = mode;
2366 if (wd->ap.protectionMode != mode)
2368 /* Write MAC&PHY registers to enable protection */
2370 wd->ap.protectionMode = mode;
2377 /************************************************************************/
2379 /* FUNCTION DESCRIPTION zfApSendFailure */
2383 /* dev : device pointer */
2384 /* addr : receiver address */
2390 /* Stephen Chen Atheros Communications, INC. 2007.1 */
2392 /************************************************************************/
2393 void zfApSendFailure(zdev_t* dev, u8_t* addr)
2397 zmw_get_wlan_dev(dev);
2398 zmw_declare_for_critical_section();
2400 staAddr[0] = addr[0] + (((u16_t)addr[1])<<8);
2401 staAddr[1] = addr[2] + (((u16_t)addr[3])<<8);
2402 staAddr[2] = addr[4] + (((u16_t)addr[5])<<8);
2403 zmw_enter_critical_section(dev);
2404 id = zfApFindSta(dev, staAddr);
2407 /* Send failture : Add 3 minutes to inactive time that will */
2408 /* will make STA been kicked out soon */
2409 wd->ap.staTable[id].time -= (3*ZM_TICK_PER_MINUTE);
2411 zmw_leave_critical_section(dev);
2415 void zfApProcessAction(zdev_t* dev, zbuf_t* buf)
2419 //zmw_get_wlan_dev(dev);
2421 //zmw_declare_for_critical_section();
2423 category = zmw_rx_buf_readb(dev, buf, 24);
2427 case ZM_WLAN_BLOCK_ACK_ACTION_FRAME:
2428 zfAggBlockAckActionFrame(dev, buf);