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
)
1549 /************************************************************************/
1551 /* FUNCTION DESCRIPTION zfApAddIeSsid */
1552 /* Add AP information element SSID to buffer. */
1555 /* dev : device pointer */
1556 /* buf : buffer to add information element */
1557 /* offset : add information element from this offset */
1558 /* vap : virtual AP ID */
1561 /* buffer offset after adding information element */
1564 /* Stephen Chen ZyDAS Technology Corporation 2005.11 */
1566 /************************************************************************/
1567 u16_t
zfApAddIeSsid(zdev_t
* dev
, zbuf_t
* buf
, u16_t offset
, u16_t vap
)
1571 zmw_get_wlan_dev(dev
);
1574 zmw_tx_buf_writeb(dev
, buf
, offset
++, ZM_WLAN_EID_SSID
);
1576 /* Element Length */
1577 zmw_tx_buf_writeb(dev
, buf
, offset
++, wd
->ap
.ssidLen
[vap
]);
1579 /* Information : SSID */
1580 for (i
=0; i
<wd
->ap
.ssidLen
[vap
]; i
++)
1582 zmw_tx_buf_writeb(dev
, buf
, offset
++, wd
->ap
.ssid
[vap
][i
]);
1589 /************************************************************************/
1591 /* FUNCTION DESCRIPTION zfApAddIeTim */
1592 /* Add AP information element TIM to buffer. */
1595 /* dev : device pointer */
1596 /* buf : buffer to add information element */
1597 /* offset : add information element from this offset */
1598 /* vap : virtual AP ID */
1601 /* buffer offset after adding information element */
1604 /* Stephen Chen ZyDAS Technology Corporation 2005.11 */
1606 /************************************************************************/
1607 u16_t
zfApAddIeTim(zdev_t
* dev
, zbuf_t
* buf
, u16_t offset
, u16_t vap
)
1619 zbuf_t
* tmpBufArray
[ZM_UNI_ARRAY_SIZE
];
1620 u16_t tmpBufArraySize
= 0;
1622 zmw_get_wlan_dev(dev
);
1624 zmw_declare_for_critical_section();
1627 zmw_tx_buf_writeb(dev
, buf
, offset
++, ZM_WLAN_EID_TIM
);
1629 /* offset of Element Length */
1630 lenOffset
= offset
++;
1632 /* Information : TIM */
1634 /* TODO : Doesn't work for Virtual AP's case */
1635 wd
->CurrentDtimCount
++;
1636 if (wd
->CurrentDtimCount
>= wd
->dtim
)
1638 wd
->CurrentDtimCount
= 0;
1640 zmw_tx_buf_writeb(dev
, buf
, offset
++, wd
->CurrentDtimCount
);
1642 zmw_tx_buf_writeb(dev
, buf
, offset
++, wd
->dtim
);
1644 zmw_tx_buf_writeb(dev
, buf
, offset
++, 0);
1646 /* Update BCMC bit */
1647 if (wd
->CurrentDtimCount
== 0)
1649 zmw_enter_critical_section(dev
);
1650 wd
->ap
.timBcmcBit
[vap
] = (wd
->ap
.bcmcTail
[vap
]!=wd
->ap
.bcmcHead
[vap
])?1:0;
1651 zmw_leave_critical_section(dev
);
1655 wd
->ap
.timBcmcBit
[vap
] = 0;
1658 /* Update Unicast bitmap */
1666 zmw_enter_critical_section(dev
);
1668 id
= wd
->ap
.uniHead
;
1669 while (id
!= wd
->ap
.uniTail
)
1671 psBuf
= wd
->ap
.uniArray
[id
];
1673 /* TODO : Aging PS frame after queuing for more than 10 seconds */
1675 /* get destination STA's aid */
1676 dst
[0] = zmw_tx_buf_readh(dev
, psBuf
, 0);
1677 dst
[1] = zmw_tx_buf_readh(dev
, psBuf
, 2);
1678 dst
[2] = zmw_tx_buf_readh(dev
, psBuf
, 4);
1679 aid
= zfApFindSta(dev
, dst
);
1682 if (wd
->ap
.staTable
[aid
].psMode
!= 0)
1684 zm_msg1_mm(ZM_LV_0
, "aid=",aid
);
1687 bitPosition
= (1 << (aid
& 0x7));
1688 bytePosition
= (aid
>> 3);
1689 uniBitMap
[bytePosition
] |= bitPosition
;
1691 if (bytePosition
>highestByte
)
1693 highestByte
= bytePosition
;
1695 id
= (id
+1) & (ZM_UNI_ARRAY_SIZE
-1);
1699 zm_msg0_mm(ZM_LV_0
, "Send PS frame which STA no longer in PS mode");
1700 /* Send PS frame which STA no longer in PS mode */
1701 zfApRemoveFromPsQueue(dev
, id
, dst
);
1702 tmpBufArray
[tmpBufArraySize
++] = psBuf
;
1707 zm_msg0_mm(ZM_LV_0
, "Free garbage PS frame");
1708 /* Free garbage PS frame */
1709 zfApRemoveFromPsQueue(dev
, id
, dst
);
1710 zfwBufFree(dev
, psBuf
, 0);
1714 zmw_leave_critical_section(dev
);
1716 zfQueueGenerateUapsdTim(dev
, wd
->ap
.uapsdQ
, uniBitMap
, &highestByte
);
1718 zm_msg1_mm(ZM_LV_3
, "bm=",uniBitMap
[0]);
1719 zm_msg1_mm(ZM_LV_3
, "highestByte=",highestByte
);
1720 zm_msg1_mm(ZM_LV_3
, "timBcmcBit[]=",wd
->ap
.timBcmcBit
[vap
]);
1723 zmw_tx_buf_writeb(dev
, buf
, offset
++,
1724 uniBitMap
[0] | wd
->ap
.timBcmcBit
[vap
]);
1725 for (i
=0; i
<highestByte
; i
++)
1727 zmw_tx_buf_writeb(dev
, buf
, offset
++, uniBitMap
[i
+1]);
1730 /* Element Length */
1731 zmw_tx_buf_writeb(dev
, buf
, lenOffset
, highestByte
+4);
1733 for (i
=0; i
<tmpBufArraySize
; i
++)
1735 /* Put to VTXQ[ac] */
1736 zfPutVtxq(dev
, tmpBufArray
[i
]);
1746 /************************************************************************/
1748 /* FUNCTION DESCRIPTION zfApRemoveFromPsQueue */
1749 /* Remove zbuf from PS queue. */
1752 /* dev : device pointer */
1753 /* id : index in ps queue */
1759 /* Stephen Chen Atheros Communications, INC. 2007.1 */
1761 /************************************************************************/
1762 u8_t
zfApRemoveFromPsQueue(zdev_t
* dev
, u16_t id
, u16_t
* addr
)
1767 zmw_get_wlan_dev(dev
);
1769 wd
->ap
.uniTail
= (wd
->ap
.uniTail
-1) & (ZM_UNI_ARRAY_SIZE
-1);
1770 while (id
!= wd
->ap
.uniTail
)
1772 nid
= (id
+ 1) & (ZM_UNI_ARRAY_SIZE
- 1);
1773 wd
->ap
.uniArray
[id
] = wd
->ap
.uniArray
[nid
];
1775 /* Search until tail to config more data bit */
1776 dst
[0] = zmw_buf_readh(dev
, wd
->ap
.uniArray
[id
], 0);
1777 dst
[1] = zmw_buf_readh(dev
, wd
->ap
.uniArray
[id
], 2);
1778 dst
[2] = zmw_buf_readh(dev
, wd
->ap
.uniArray
[id
], 4);
1779 if ((addr
[0] == dst
[0]) && (addr
[1] == dst
[1])
1780 && (addr
[2] == dst
[2]))
1790 /************************************************************************/
1792 /* FUNCTION DESCRIPTION zfApAddIeWmePara */
1793 /* Add WME Parameter Element to buffer. */
1796 /* dev : device pointer */
1797 /* buf : buffer to add information element */
1798 /* offset : add information element from this offset */
1799 /* vap : virtual AP ID */
1802 /* buffer offset after adding information element */
1805 /* Stephen Chen ZyDAS Technology Corporation 2006.1 */
1807 /************************************************************************/
1808 u16_t
zfApAddIeWmePara(zdev_t
* dev
, zbuf_t
* buf
, u16_t offset
, u16_t vap
)
1810 zmw_get_wlan_dev(dev
);
1813 zmw_tx_buf_writeb(dev
, buf
, offset
++, ZM_WLAN_EID_WIFI_IE
);
1815 /* Element Length */
1816 zmw_tx_buf_writeb(dev
, buf
, offset
++, 24);
1819 zmw_tx_buf_writeb(dev
, buf
, offset
++, 0x00);
1820 zmw_tx_buf_writeb(dev
, buf
, offset
++, 0x50);
1821 zmw_tx_buf_writeb(dev
, buf
, offset
++, 0xF2);
1822 zmw_tx_buf_writeb(dev
, buf
, offset
++, 0x02);
1823 zmw_tx_buf_writeb(dev
, buf
, offset
++, 0x01);
1824 zmw_tx_buf_writeb(dev
, buf
, offset
++, 0x01);
1827 if (wd
->ap
.uapsdEnabled
)
1829 zmw_tx_buf_writeb(dev
, buf
, offset
++, 0x81);
1833 zmw_tx_buf_writeb(dev
, buf
, offset
++, 0x01);
1837 zmw_tx_buf_writeb(dev
, buf
, offset
++, 0x00);
1839 /* Best Effort AC parameters */
1840 zmw_tx_buf_writeb(dev
, buf
, offset
++, 0x03);
1841 zmw_tx_buf_writeb(dev
, buf
, offset
++, 0xA4);
1842 zmw_tx_buf_writeb(dev
, buf
, offset
++, 0x00);
1843 zmw_tx_buf_writeb(dev
, buf
, offset
++, 0x00);
1844 /* Backfround AC parameters */
1845 zmw_tx_buf_writeb(dev
, buf
, offset
++, 0x27);
1846 zmw_tx_buf_writeb(dev
, buf
, offset
++, 0xA4);
1847 zmw_tx_buf_writeb(dev
, buf
, offset
++, 0x00);
1848 zmw_tx_buf_writeb(dev
, buf
, offset
++, 0x00);
1849 /* Video AC parameters */
1850 zmw_tx_buf_writeb(dev
, buf
, offset
++, 0x42);
1851 zmw_tx_buf_writeb(dev
, buf
, offset
++, 0x43);
1852 zmw_tx_buf_writeb(dev
, buf
, offset
++, 0x5E);
1853 zmw_tx_buf_writeb(dev
, buf
, offset
++, 0x00);
1854 /* Voice AC parameters */
1855 zmw_tx_buf_writeb(dev
, buf
, offset
++, 0x62);
1856 zmw_tx_buf_writeb(dev
, buf
, offset
++, 0x32);
1857 zmw_tx_buf_writeb(dev
, buf
, offset
++, 0x2F);
1858 zmw_tx_buf_writeb(dev
, buf
, offset
++, 0x00);
1864 /************************************************************************/
1866 /* FUNCTION DESCRIPTION zfApSendBeacon */
1867 /* Sned AP mode beacon. */
1870 /* dev : device pointer */
1876 /* Stephen Chen ZyDAS Technology Corporation 2005.11 */
1878 /************************************************************************/
1879 void zfApSendBeacon(zdev_t
* dev
)
1886 zmw_get_wlan_dev(dev
);
1888 zmw_declare_for_critical_section();
1890 wd
->ap
.beaconCounter
++;
1891 if (wd
->ap
.beaconCounter
>= wd
->ap
.vapNumber
)
1893 wd
->ap
.beaconCounter
= 0;
1895 vap
= wd
->ap
.beaconCounter
;
1898 zm_msg1_mm(ZM_LV_2
, "Send beacon, vap=", vap
);
1900 /* TBD : Maximum size of beacon */
1901 buf
= zfwBufAllocate(dev
, 1024);
1904 zm_msg0_mm(ZM_LV_0
, "Alloc beacon buf Fail!");
1912 zmw_tx_buf_writeh(dev
, buf
, offset
, 0x0080);
1915 zmw_tx_buf_writeh(dev
, buf
, offset
, 0x0000);
1918 zmw_tx_buf_writeh(dev
, buf
, offset
, 0xffff);
1920 zmw_tx_buf_writeh(dev
, buf
, offset
, 0xffff);
1922 zmw_tx_buf_writeh(dev
, buf
, offset
, 0xffff);
1925 zmw_tx_buf_writeh(dev
, buf
, offset
, wd
->macAddr
[0]);
1927 zmw_tx_buf_writeh(dev
, buf
, offset
, wd
->macAddr
[1]);
1929 #ifdef ZM_VAPMODE_MULTILE_SSID
1930 zmw_tx_buf_writeh(dev
, buf
, offset
, wd
->macAddr
[2]); //Multiple SSID
1932 zmw_tx_buf_writeh(dev
, buf
, offset
, (wd
->macAddr
[2]+(vap
<<8))); //VAP
1936 zmw_tx_buf_writeh(dev
, buf
, offset
, wd
->macAddr
[0]);
1938 zmw_tx_buf_writeh(dev
, buf
, offset
, wd
->macAddr
[1]);
1940 #ifdef ZM_VAPMODE_MULTILE_SSID
1941 zmw_tx_buf_writeh(dev
, buf
, offset
, wd
->macAddr
[2]); //Multiple SSID
1943 zmw_tx_buf_writeh(dev
, buf
, offset
, (wd
->macAddr
[2]+(vap
<<8))); //VAP
1947 /* Sequence number */
1948 zmw_enter_critical_section(dev
);
1949 seq
= ((wd
->mmseq
++)<<4);
1950 zmw_leave_critical_section(dev
);
1951 zmw_tx_buf_writeh(dev
, buf
, offset
, seq
);
1954 /* 24-31 Time Stamp : hardware will fill this field */
1955 zmw_tx_buf_writeh(dev
, buf
, offset
, 0);
1956 zmw_tx_buf_writeh(dev
, buf
, offset
+2, 0);
1957 zmw_tx_buf_writeh(dev
, buf
, offset
+4, 0);
1958 zmw_tx_buf_writeh(dev
, buf
, offset
+6, 0);
1961 /* Beacon Interval */
1962 zmw_tx_buf_writeh(dev
, buf
, offset
, wd
->beaconInterval
);
1966 zmw_tx_buf_writeh(dev
, buf
, offset
, wd
->ap
.capab
[vap
]);
1970 if (wd
->ap
.hideSsid
[vap
] == 0)
1972 offset
= zfApAddIeSsid(dev
, buf
, offset
, vap
);
1976 zmw_tx_buf_writeb(dev
, buf
, offset
++, ZM_WLAN_EID_SSID
);
1977 zmw_tx_buf_writeb(dev
, buf
, offset
++, 0);
1982 if ( wd
->frequency
< 3000 )
1984 offset
= zfMmAddIeSupportRate(dev
, buf
, offset
,
1985 ZM_WLAN_EID_SUPPORT_RATE
, ZM_RATE_SET_CCK
);
1989 offset
= zfMmAddIeSupportRate(dev
, buf
, offset
,
1990 ZM_WLAN_EID_SUPPORT_RATE
, ZM_RATE_SET_OFDM
);
1993 /* DS parameter set */
1994 offset
= zfMmAddIeDs(dev
, buf
, offset
);
1997 offset
= zfApAddIeTim(dev
, buf
, offset
, vap
);
1999 /* If WLAN Type is not PURE B */
2000 if (wd
->ap
.wlanType
[vap
] != ZM_WLAN_TYPE_PURE_B
)
2002 if ( wd
->frequency
< 3000 )
2004 /* ERP Information */
2005 offset
= zfMmAddIeErp(dev
, buf
, offset
);
2007 /* Extended Supported Rates */
2008 offset
= zfMmAddIeSupportRate(dev
, buf
, offset
,
2009 ZM_WLAN_EID_EXTENDED_RATE
, ZM_RATE_SET_OFDM
);
2013 /* TODO : country information */
2015 if (wd
->ap
.wpaSupport
[vap
] == 1)
2017 offset
= zfMmAddIeWpa(dev
, buf
, offset
, vap
);
2020 /* WME Parameters */
2021 if (wd
->ap
.qosMode
== 1)
2023 offset
= zfApAddIeWmePara(dev
, buf
, offset
, vap
);
2026 /* HT Capabilities Info */
2027 offset
= zfMmAddHTCapability(dev
, buf
, offset
);
2029 /* Extended HT Capabilities Info */
2030 offset
= zfMmAddExtendedHTCapability(dev
, buf
, offset
);
2032 /* 1212 : write to beacon fifo */
2033 /* 1221 : write to share memory */
2034 zfHpSendBeacon(dev
, buf
, offset
);
2036 /* Free beacon buffer */
2037 /* TODO: In order to fit the madwifi beacon architecture, we need to
2038 free beacon buffer in the HAL layer.
2041 //zfwBufFree(dev, buf, 0);
2045 /************************************************************************/
2047 /* FUNCTION DESCRIPTION zfIntrabssForward */
2048 /* Called to transmit intra-BSS frame from upper layer. */
2051 /* dev : device pointer */
2052 /* buf : buffer pointer */
2053 /* vap : virtual AP */
2056 /* 1 : unicast intras-BSS frame */
2057 /* 0 : other frames */
2060 /* Stephen ZyDAS Technology Corporation 2005.11 */
2062 /************************************************************************/
2063 u16_t
zfIntrabssForward(zdev_t
* dev
, zbuf_t
* buf
, u8_t srcVap
)
2076 #ifdef ZM_ENABLE_NATIVE_WIFI
2077 dst
[0] = zmw_rx_buf_readh(dev
, buf
, ZM_WLAN_HEADER_A3_OFFSET
);
2078 dst
[1] = zmw_rx_buf_readh(dev
, buf
, ZM_WLAN_HEADER_A3_OFFSET
+2);
2079 dst
[2] = zmw_rx_buf_readh(dev
, buf
, ZM_WLAN_HEADER_A3_OFFSET
+4);
2081 dst
[0] = zmw_rx_buf_readh(dev
, buf
, 0);
2082 dst
[1] = zmw_rx_buf_readh(dev
, buf
, 2);
2083 dst
[2] = zmw_rx_buf_readh(dev
, buf
, 4);
2084 #endif // ZM_ENABLE_NATIVE_WIFI
2086 /* Do Intra-BSS forward(data copy) if necessary*/
2087 if ((dst
[0]&0x1) != 0x1)
2089 aid
= zfApGetSTAInfo(dev
, dst
, &staState
, &vap
);
2090 if ((aid
!= 0xffff) && (staState
== ZM_STATE_ASOC
) && (srcVap
== vap
))
2093 zm_msg0_rx(ZM_LV_2
, "Intra-BSS forward : asoc STA");
2100 zm_msg0_rx(ZM_LV_2
, "Intra-BSS forward : BCorMC");
2103 /* destination address = associated STA or BC/MC */
2104 if ((asocFlag
== 1) || ((dst
[0]&0x1) == 0x1))
2106 /* Allocate frame */
2107 txBuf
= zfwBufAllocate(dev
, ZM_RX_FRAME_SIZE
);
2110 zm_msg0_rx(ZM_LV_1
, "Alloc intra-bss buf Fail!");
2115 len
= zfwBufGetSize(dev
, buf
);
2116 for (i
=0; i
<len
; i
+=2)
2118 temp
= zmw_rx_buf_readh(dev
, buf
, i
);
2119 zmw_tx_buf_writeh(dev
, txBuf
, i
, temp
);
2121 zfwBufSetSize(dev
, txBuf
, len
);
2123 #ifdef ZM_ENABLE_NATIVE_WIFI
2124 /* Tx-A2 = Rx-A1, Tx-A3 = Rx-A2, Tx-A1 = Rx-A3 */
2125 for (i
=0; i
<6; i
+=2)
2127 temp
= zmw_rx_buf_readh(dev
, buf
, ZM_WLAN_HEADER_A1_OFFSET
+i
);
2128 zmw_tx_buf_writeh(dev
, txBuf
, ZM_WLAN_HEADER_A2_OFFSET
+i
, temp
);
2129 temp
= zmw_rx_buf_readh(dev
, buf
, ZM_WLAN_HEADER_A2_OFFSET
+i
);
2130 zmw_tx_buf_writeh(dev
, txBuf
, ZM_WLAN_HEADER_A3_OFFSET
+i
, temp
);
2131 temp
= zmw_rx_buf_readh(dev
, buf
, ZM_WLAN_HEADER_A3_OFFSET
+i
);
2132 zmw_tx_buf_writeh(dev
, txBuf
, ZM_WLAN_HEADER_A1_OFFSET
+i
, temp
);
2137 /* Transmit frame */
2138 /* Return error if port is disabled */
2139 err
= zfTxPortControl(dev
, txBuf
, vap
);
2140 if (err
== ZM_PORT_DISABLED
)
2142 err
= ZM_ERR_TX_PORT_DISABLED
;
2146 /* AP : Buffer frame for power saving STA */
2147 ret
= zfApBufferPsFrame(dev
, txBuf
, vap
);
2150 /* forward frame if not been buffered */
2151 /* Put to VTXQ[ac] */
2152 ret
= zfPutVtxq(dev
, txBuf
);
2161 zfwBufFree(dev
, txBuf
, 0);
2166 struct zsMicVar
* zfApGetRxMicKey(zdev_t
* dev
, zbuf_t
* buf
)
2169 u16_t id
= 0, macAddr
[3];
2171 zmw_get_wlan_dev(dev
);
2173 zfCopyFromRxBuffer(dev
, buf
, sa
, ZM_WLAN_HEADER_A2_OFFSET
, 6);
2175 macAddr
[0] = sa
[0] + (sa
[1] << 8);
2176 macAddr
[1] = sa
[2] + (sa
[3] << 8);
2177 macAddr
[2] = sa
[4] + (sa
[5] << 8);
2179 id
= zfApFindSta(dev
, macAddr
);
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 id
= zfApFindSta(dev
, staAddr
);
2375 /* Send failture : Add 3 minutes to inactive time that will */
2376 /* will make STA been kicked out soon */
2377 wd
->ap
.staTable
[id
].time
-= (3*ZM_TICK_PER_MINUTE
);
2379 zmw_leave_critical_section(dev
);
2383 void zfApProcessAction(zdev_t
* dev
, zbuf_t
* buf
)
2387 //zmw_get_wlan_dev(dev);
2389 //zmw_declare_for_critical_section();
2391 category
= zmw_rx_buf_readb(dev
, buf
, 24);
2395 case ZM_WLAN_BLOCK_ACK_ACTION_FRAME
:
2396 zfAggBlockAckActionFrame(dev
, buf
);