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
);