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 : cagg.c */
20 /* This module contains A-MPDU aggregation related functions. */
25 /************************************************************************/
29 extern u8_t zcUpToAc
[8];
30 const u8_t pri
[] = {3,3,2,3,2,1,3,2,1,0};
37 void zfAggInit(zdev_t
* dev
)
41 zmw_get_wlan_dev(dev
);
43 zmw_declare_for_critical_section();
45 * reset sta information
48 zmw_enter_critical_section(dev
);
50 wd
->addbaComplete
= 0;
53 for (i
=0; i
<ZM_MAX_STA_SUPPORT
; i
++)
55 for (j
=0; j
<ZM_AC
; j
++)
57 //wd->aggSta[i].aggQNumber[j] = ZM_AGG_POOL_SIZE;
58 wd
->aggSta
[i
].aggFlag
[j
] = wd
->aggSta
[i
].count
[j
] = 0;
59 wd
->aggSta
[i
].tid_tx
[j
] = NULL
;
60 wd
->aggSta
[i
].tid_tx
[j
+1] = NULL
;
66 * reset Tx/Rx aggregation queue information
69 for (i
=0; i
<ZM_AGG_POOL_SIZE
; i
++)
72 * reset tx aggregation queue
74 wd
->aggQPool
[i
] = zfwMemAllocate(dev
, sizeof(struct aggQueue
));
77 zmw_leave_critical_section(dev
);
80 wd
->aggQPool
[i
]->aggHead
= wd
->aggQPool
[i
]->aggTail
=
81 wd
->aggQPool
[i
]->aggQEnabled
= wd
->aggQPool
[i
]->aggReady
=
82 wd
->aggQPool
[i
]->clearFlag
= wd
->aggQPool
[i
]->deleteFlag
= 0;
83 //wd->aggQPool[i]->aggSize = 16;
86 * reset rx aggregation queue
88 wd
->tid_rx
[i
] = zfwMemAllocate(dev
, sizeof(struct agg_tid_rx
));
91 zmw_leave_critical_section(dev
);
94 wd
->tid_rx
[i
]->aid
= ZM_MAX_STA_SUPPORT
;
95 wd
->tid_rx
[i
]->seq_start
= wd
->tid_rx
[i
]->baw_head
= \
96 wd
->tid_rx
[i
]->baw_tail
= 0;
97 wd
->tid_rx
[i
]->sq_exceed_count
= wd
->tid_rx
[i
]->sq_behind_count
= 0;
98 for (j
=0; j
<=ZM_AGG_BAW_SIZE
; j
++)
99 wd
->tid_rx
[i
]->frame
[j
].buf
= 0;
101 * reset ADDBA exchange status code
103 * 1: ADDBA Request sent/received
104 * 2: ACK for ADDBA Request sent/received
105 * 3: ADDBA Response sent/received
106 * 4: ACK for ADDBA Response sent/received
108 wd
->tid_rx
[i
]->addBaExchangeStatusCode
= 0;
111 zmw_leave_critical_section(dev
);
112 zfAggTallyReset(dev
);
113 DESTQ
.init
= zfAggDestInit
;
115 wd
->aggInitiated
= 1;
119 #ifdef ZM_ENABLE_AGGREGATION
120 #ifndef ZM_ENABLE_FW_BA_RETRANSMISSION //disable BAW
121 BAW
= zfwMemAllocate(dev
, sizeof(struct baw_enabler
));
126 BAW
->init
= zfBawInit
;
132 /************************************************************************/
134 /* FUNCTION DESCRIPTION zfAggGetSta */
135 /* return STA AID. */
136 /* take buf as input, use the dest address of buf as index to */
137 /* search STA AID. */
140 /* dev : device pointer */
141 /* buf : buffer for one particular packet */
147 /* Honda ZyDAS Technology Corporation 2006.11 */
149 /************************************************************************/
153 u16_t
zfAggGetSta(zdev_t
* dev
, zbuf_t
* buf
)
158 zmw_get_wlan_dev(dev
);
160 zmw_declare_for_critical_section();
162 dst
[0] = zmw_rx_buf_readh(dev
, buf
, 0);
163 dst
[1] = zmw_rx_buf_readh(dev
, buf
, 2);
164 dst
[2] = zmw_rx_buf_readh(dev
, buf
, 4);
166 zmw_enter_critical_section(dev
);
168 if(wd
->wlanMode
== ZM_MODE_AP
) {
169 id
= zfApFindSta(dev
, dst
);
174 zmw_leave_critical_section(dev
);
176 #if ZM_AGG_FPGA_DEBUG
184 /************************************************************************/
186 /* FUNCTION DESCRIPTION zfAggTxGetQueue */
187 /* return Queue Pool index. */
188 /* take aid as input, look for the queue index associated */
192 /* dev : device pointer */
193 /* aid : associated id */
199 /* Honda ZyDAS Technology Corporation 2006.11 */
201 /************************************************************************/
202 TID_TX
zfAggTxGetQueue(zdev_t
* dev
, u16_t aid
, u16_t tid
)
206 zmw_get_wlan_dev(dev
);
208 //zmw_declare_for_critical_section();
216 //zmw_enter_critical_section(dev);
218 tid_tx
= wd
->aggSta
[aid
].tid_tx
[tid
];
219 if (!tid_tx
) return NULL
;
220 if (0 == tid_tx
->aggQEnabled
)
223 //zmw_leave_critical_section(dev);
228 /************************************************************************/
230 /* FUNCTION DESCRIPTION zfAggTxNewQueue */
231 /* return Queue Pool index. */
232 /* take aid as input, find a new queue for this aid. */
235 /* dev : device pointer */
236 /* aid : associated id */
242 /* Honda ZyDAS Technology Corporation 2006.12 */
244 /************************************************************************/
245 TID_TX
zfAggTxNewQueue(zdev_t
* dev
, u16_t aid
, u16_t tid
, zbuf_t
* buf
)
249 u16_t ac
= zcUpToAc
[tid
&0x7] & 0x3;
250 zmw_get_wlan_dev(dev
);
252 zmw_declare_for_critical_section();
260 zmw_enter_critical_section(dev
);
263 * find one new queue for sta
265 for (i
=0; i
<ZM_AGG_POOL_SIZE
; i
++)
267 if (wd
->aggQPool
[i
]->aggQEnabled
)
275 tid_tx
= wd
->aggQPool
[i
];
276 tid_tx
->aggQEnabled
= 1;
277 tid_tx
->aggQSTA
= aid
;
280 tid_tx
->aggHead
= tid_tx
->aggTail
= tid_tx
->size
= 0;
281 tid_tx
->aggReady
= 0;
282 wd
->aggSta
[aid
].tid_tx
[tid
] = tid_tx
;
283 tid_tx
->dst
[0] = zmw_rx_buf_readh(dev
, buf
, 0);
284 tid_tx
->dst
[1] = zmw_rx_buf_readh(dev
, buf
, 2);
285 tid_tx
->dst
[2] = zmw_rx_buf_readh(dev
, buf
, 4);
290 zmw_leave_critical_section(dev
);
297 /************************************************************************/
299 /* FUNCTION DESCRIPTION zfAggTxEnqueue */
300 /* return Status code ZM_SUCCESS or error code */
301 /* take (aid,ac,qnum,buf) as input */
304 /* dev : device pointer */
305 /* aid : associated id */
306 /* ac : access category */
307 /* qnum: the queue number to which will be enqueued */
308 /* buf : the packet to be queued */
314 /* Honda Atheros Communications, INC. 2006.12 */
316 /************************************************************************/
317 u16_t
zfAggTxEnqueue(zdev_t
* dev
, zbuf_t
* buf
, u16_t aid
, TID_TX tid_tx
)
319 //u16_t qlen, frameLen;
322 zmw_get_wlan_dev(dev
);
324 zmw_declare_for_critical_section();
326 zmw_enter_critical_section(dev
);
328 tid_tx
->size
= zm_agg_qlen(dev
, tid_tx
->aggHead
, tid_tx
->aggTail
);
330 if (tid_tx
->size
< (ZM_AGGQ_SIZE
- 2))
337 * in zfwBufFree will return a ndismsendcomplete
338 * to resolve the synchronize problem in aggregate
341 u8_t sendComplete
= 0;
343 tid_tx
->aggvtxq
[tid_tx
->aggHead
].buf
= buf
;
344 time
= zm_agg_GetTime();
345 tid_tx
->aggvtxq
[tid_tx
->aggHead
].arrivalTime
= time
;
346 tid_tx
->aggvtxq
[tid_tx
->aggHead
].baw_retransmit
= 0;
348 tid_tx
->aggHead
= ((tid_tx
->aggHead
+ 1) & ZM_AGGQ_SIZE_MASK
);
349 tid_tx
->lastArrival
= time
;
351 tid_tx
->size
= zm_agg_qlen(dev
, tid_tx
->aggHead
, tid_tx
->aggTail
);
352 if (buf
&& (tid_tx
->size
< (ZM_AGGQ_SIZE
- 10))) {
353 tid_tx
->complete
= tid_tx
->aggHead
;
356 zmw_leave_critical_section(dev
);
358 if (!DESTQ
.exist(dev
, 0, tid_tx
->ac
, tid_tx
, NULL
)) {
359 DESTQ
.insert(dev
, 0, tid_tx
->ac
, tid_tx
, NULL
);
362 zm_msg1_agg(ZM_LV_0
, "tid_tx->size=", tid_tx
->size
);
363 //zm_debug_msg1("tid_tx->size=", tid_tx->size);
365 if (buf
&& sendComplete
&& wd
->zfcbSendCompleteIndication
) {
366 //zmw_leave_critical_section(dev);
367 wd
->zfcbSendCompleteIndication(dev
, buf
);
370 /*if (tid_tx->size >= 16 && zfHpGetFreeTxdCount(dev) > 20)
371 zfAggTxSend(dev, zfHpGetFreeTxdCount(dev), tid_tx);
377 zm_msg1_agg(ZM_LV_0
, "can't enqueue, tid_tx->size=", tid_tx
->size
);
383 * zm_msg1_agg(ZM_LV_0, "Queue full, qnum = ", qnum);
384 * wd->commTally.txQosDropCount[ac]++;
385 * zfwBufFree(dev, buf, ZM_SUCCESS);
386 * zm_msg1_agg(ZM_LV_1, "Packet discarded, VTXQ full, ac=", ac);
388 * return ZM_ERR_EXCEED_PRIORITY_THRESHOLD;
392 zmw_leave_critical_section(dev
);
394 if (!DESTQ
.exist(dev
, 0, tid_tx
->ac
, tid_tx
, NULL
)) {
395 DESTQ
.insert(dev
, 0, tid_tx
->ac
, tid_tx
, NULL
);
398 return ZM_ERR_EXCEED_PRIORITY_THRESHOLD
;
401 u16_t
zfAggDestExist(zdev_t
* dev
, u16_t Qtype
, u16_t ac
, TID_TX tid_tx
, void* vtxq
) {
404 zmw_get_wlan_dev(dev
);
406 zmw_declare_for_critical_section();
408 zmw_enter_critical_section(dev
);
409 if (!DESTQ
.Head
[ac
]) {
413 dest
= DESTQ
.Head
[ac
];
414 if (dest
->tid_tx
== tid_tx
) {
418 while (dest
->next
!= DESTQ
.Head
[ac
]) {
420 if (dest
->tid_tx
== tid_tx
){
428 zmw_leave_critical_section(dev
);
433 void zfAggDestInsert(zdev_t
* dev
, u16_t Qtype
, u16_t ac
, TID_TX tid_tx
, void* vtxq
)
435 struct dest
* new_dest
;
436 zmw_get_wlan_dev(dev
);
438 zmw_declare_for_critical_section();
440 new_dest
= zfwMemAllocate(dev
, sizeof(struct dest
));
445 new_dest
->Qtype
= Qtype
;
446 new_dest
->tid_tx
= tid_tx
;
448 new_dest
->tid_tx
= tid_tx
;
450 new_dest
->vtxq
= vtxq
;
451 if (!DESTQ
.Head
[ac
]) {
453 zmw_enter_critical_section(dev
);
454 new_dest
->next
= new_dest
;
455 DESTQ
.Head
[ac
] = DESTQ
.dest
[ac
] = new_dest
;
456 zmw_leave_critical_section(dev
);
460 zmw_enter_critical_section(dev
);
461 new_dest
->next
= DESTQ
.dest
[ac
]->next
;
462 DESTQ
.dest
[ac
]->next
= new_dest
;
463 zmw_leave_critical_section(dev
);
471 void zfAggDestDelete(zdev_t
* dev
, u16_t Qtype
, TID_TX tid_tx
, void* vtxq
)
473 struct dest
* dest
, *temp
;
476 zmw_get_wlan_dev(dev
);
478 zmw_declare_for_critical_section();
480 zmw_enter_critical_section(dev
);
482 zmw_leave_critical_section(dev
);
487 //zmw_declare_for_critical_section();
488 for (i
=0; i
<4; i
++) {
489 if (!DESTQ
.Head
[i
]) continue;
490 dest
= DESTQ
.Head
[i
];
494 while (dest
&& (dest
->next
!= DESTQ
.Head
[i
])) {
495 if (Qtype
== 0 && dest
->next
->tid_tx
== tid_tx
){
498 if (Qtype
== 1 && dest
->next
->vtxq
== vtxq
) {
504 if ((Qtype
== 0 && dest
->next
->tid_tx
== tid_tx
) || (Qtype
== 1 && dest
->next
->vtxq
== vtxq
)) {
506 tid_tx
->size
= zm_agg_qlen(dev
, tid_tx
->aggHead
, tid_tx
->aggTail
);
508 zmw_leave_critical_section(dev
);
511 if (!DESTQ
.Head
[i
]) {
517 DESTQ
.Head
[i
] = DESTQ
.dest
[i
] = NULL
;
521 dest
->next
= dest
->next
->next
;
526 {/* do nothing */} //zfwMemFree(dev, temp, sizeof(struct dest));
528 zfwMemFree(dev
, temp
, sizeof(struct dest
));
530 /*zmw_enter_critical_section(dev);
531 if (DESTQ.size[i] > 0)
533 zmw_leave_critical_section(dev);
538 zmw_leave_critical_section(dev
);
542 void zfAggDestInit(zdev_t
* dev
)
545 zmw_get_wlan_dev(dev
);
547 //zmw_declare_for_critical_section();
549 for (i
=0; i
<4; i
++) {
550 //wd->destQ.Head[i].next = wd->destQ.Head[i];
551 //wd->destQ.dest[i] = wd->destQ.Head[i];
553 DESTQ
.Head
[i
] = NULL
;
555 DESTQ
.insert
= zfAggDestInsert
;
556 DESTQ
.delete = zfAggDestDelete
;
557 DESTQ
.init
= zfAggDestInit
;
558 DESTQ
.getNext
= zfAggDestGetNext
;
559 DESTQ
.exist
= zfAggDestExist
;
564 struct dest
* zfAggDestGetNext(zdev_t
* dev
, u16_t ac
)
566 struct dest
*dest
= NULL
;
567 zmw_get_wlan_dev(dev
);
569 zmw_declare_for_critical_section();
571 zmw_enter_critical_section(dev
);
572 if (DESTQ
.dest
[ac
]) {
573 dest
= DESTQ
.dest
[ac
];
574 DESTQ
.dest
[ac
] = DESTQ
.dest
[ac
]->next
;
579 zmw_leave_critical_section(dev
);
584 #ifdef ZM_ENABLE_AGGREGATION
585 #ifndef ZM_ENABLE_FW_BA_RETRANSMISSION //disable BAW
586 u16_t
zfAggTidTxInsertHead(zdev_t
* dev
, struct bufInfo
*buf_info
,TID_TX tid_tx
)
590 struct baw_header
*baw_header
;
592 zmw_get_wlan_dev(dev
);
594 zmw_declare_for_critical_section();
599 zmw_enter_critical_section(dev
);
600 tid_tx
->size
= zm_agg_qlen(dev
, tid_tx
->aggHead
, tid_tx
->aggTail
);
601 zmw_leave_critical_section(dev
);
603 if (tid_tx
->size
>= (ZM_AGGQ_SIZE
- 2)) {
604 zfwBufFree(dev
, buf
, ZM_SUCCESS
);
608 zmw_enter_critical_section(dev
);
609 tid_tx
->aggTail
= (tid_tx
->aggTail
== 0)? ZM_AGGQ_SIZE_MASK
: tid_tx
->aggTail
- 1;
610 tid_tx
->aggvtxq
[tid_tx
->aggTail
].buf
= buf
;
611 //time = zm_agg_GetTime();
612 tid_tx
->aggvtxq
[tid_tx
->aggTail
].arrivalTime
= buf_info
->timestamp
;
613 tid_tx
->aggvtxq
[tid_tx
->aggTail
].baw_retransmit
= buf_info
->baw_retransmit
;
615 baw_header
= &tid_tx
->aggvtxq
[tid_tx
->aggTail
].baw_header
;
616 baw_header
->headerLen
= buf_info
->baw_header
->headerLen
;
617 baw_header
->micLen
= buf_info
->baw_header
->micLen
;
618 baw_header
->snapLen
= buf_info
->baw_header
->snapLen
;
619 baw_header
->removeLen
= buf_info
->baw_header
->removeLen
;
620 baw_header
->keyIdx
= buf_info
->baw_header
->keyIdx
;
621 zfwMemoryCopy((u8_t
*)baw_header
->header
, (u8_t
*)buf_info
->baw_header
->header
, 58);
622 zfwMemoryCopy((u8_t
*)baw_header
->mic
, (u8_t
*)buf_info
->baw_header
->mic
, 8);
623 zfwMemoryCopy((u8_t
*)baw_header
->snap
, (u8_t
*)buf_info
->baw_header
->snap
, 8);
626 tid_tx
->size
= zm_agg_qlen(dev
, tid_tx
->aggHead
, tid_tx
->aggTail
);
627 zmw_leave_critical_section(dev
);
629 //tid_tx->lastArrival = time;
630 if (1 == tid_tx
->size
) {
631 DESTQ
.insert(dev
, 0, tid_tx
->ac
, tid_tx
, NULL
);
635 zm_msg1_agg(ZM_LV_0
, "0xC2:insertHead, tid_tx->size=", tid_tx
->size
);
642 void zfiTxComplete(zdev_t
* dev
)
645 zmw_get_wlan_dev(dev
);
647 //zmw_declare_for_critical_section();
649 if( (wd
->wlanMode
== ZM_MODE_AP
) ||
650 (wd
->wlanMode
== ZM_MODE_INFRASTRUCTURE
&& wd
->sta
.EnableHT
) ||
651 (wd
->wlanMode
== ZM_MODE_PSEUDO
) ) {
652 zfAggTxScheduler(dev
, 0);
658 TID_TX
zfAggTxReady(zdev_t
* dev
) {
661 TID_TX tid_tx
= NULL
;
662 zmw_get_wlan_dev(dev
);
664 zmw_declare_for_critical_section();
666 zmw_enter_critical_section(dev
);
667 for (i
=0; i
<ZM_AGG_POOL_SIZE
; i
++)
669 if (wd
->aggQPool
[i
]->aggQEnabled
)
671 if (wd
->aggQPool
[i
]->size
>= 16) {
672 tid_tx
= wd
->aggQPool
[i
];
679 zmw_leave_critical_section(dev
);
683 u16_t
zfAggValidTidTx(zdev_t
* dev
, TID_TX tid_tx
) {
685 zmw_get_wlan_dev(dev
);
687 zmw_declare_for_critical_section();
689 zmw_enter_critical_section(dev
);
690 for (i
=0; i
<ZM_AGG_POOL_SIZE
; i
++)
692 if (wd
->aggQPool
[i
] == tid_tx
)
700 zmw_leave_critical_section(dev
);
705 void zfAggTxScheduler(zdev_t
* dev
, u8_t ScanAndClear
)
707 TID_TX tid_tx
= NULL
;
711 u32_t txql
, min_txql
;
712 //u16_t aggr_size = 1;
714 zmw_get_wlan_dev(dev
);
716 zmw_declare_for_critical_section();
718 if (!wd
->aggInitiated
)
725 min_txql
= AGG_MIN_TXQL
;
727 if(wd
->txq_threshold
)
728 txq_threshold
= wd
->txq_threshold
;
730 txq_threshold
= AGG_MIN_TXQL
;
732 tid_tx
= zfAggTxReady(dev
);
733 if (tid_tx
) ScanAndClear
= 0;
734 while (zfHpGetFreeTxdCount(dev
) > 20 && (TXQL
< txq_threshold
|| tid_tx
)) {
735 //while (zfHpGetFreeTxdCount(dev) > 20 && (ScanAndClear || tid_tx)) {
736 //while (TXQL < txq_threshold) {
739 s8_t destQ_count
= 0;
740 //while ((zfHpGetFreeTxdCount(dev)) > 32) {
742 //DbgPrint("zfAggTxScheduler: in while loop");
743 for (i
=0; i
<4; i
++) {
744 if (DESTQ
.Head
[i
]) destQ_count
++;
746 if (0 >= destQ_count
) break;
748 zmw_enter_critical_section(dev
);
749 ac
= pri
[DESTQ
.ppri
]; DESTQ
.ppri
= (DESTQ
.ppri
+ 1) % 10;
750 zmw_leave_critical_section(dev
);
752 for (i
=0; i
<10; i
++){
753 if(DESTQ
.Head
[ac
]) break;
755 zmw_enter_critical_section(dev
);
756 ac
= pri
[DESTQ
.ppri
]; DESTQ
.ppri
= (DESTQ
.ppri
+ 1) % 10;
757 zmw_leave_critical_section(dev
);
760 //DbgPrint("zfAggTxScheduler: have dest Q");
761 zmw_enter_critical_section(dev
);
763 zmw_leave_critical_section(dev
);
765 dest
= DESTQ
.getNext(dev
, ac
);
767 zmw_enter_critical_section(dev
);
769 zmw_leave_critical_section(dev
);
771 DbgPrint("bug report! DESTQ.getNext got nothing!");
774 if (dest
->Qtype
== 0) {
775 tid_tx
= dest
->tid_tx
;
777 //DbgPrint("zfAggTxScheduler: have tid_tx Q");
779 if(tid_tx
&& zfAggValidTidTx(dev
, tid_tx
))
780 tid_tx
->size
= zm_agg_qlen(dev
, tid_tx
->aggHead
, tid_tx
->aggTail
);
782 zmw_enter_critical_section(dev
);
784 zmw_leave_critical_section(dev
);
786 tid_tx
= zfAggTxReady(dev
);
790 zmw_enter_critical_section(dev
);
792 zmw_leave_critical_section(dev
);
793 //zmw_enter_critical_section(dev);
794 if (tid_tx
&& !tid_tx
->size
) {
796 //zmw_leave_critical_section(dev);
797 //DESTQ.delete(dev, 0, tid_tx, NULL);
799 else if(wd
->aggState
== 0){
801 //zmw_leave_critical_section(dev);
802 zfAggTxSend(dev
, zfHpGetFreeTxdCount(dev
), tid_tx
);
806 //zmw_leave_critical_section(dev);
812 buf
= zfGetVtxq(dev
, ac
);
813 zm_assert( buf
!= 0 );
815 zfTxSendEth(dev
, buf
, 0, ZM_EXTERNAL_ALLOC_BUF
, 0);
818 /*flush all but < 16 frames in tid_tx to TXQ*/
819 tid_tx
= zfAggTxReady(dev
);
822 /*while ((zfHpGetFreeTxdCount(dev)) > 32) {
823 //while ((zfHpGetFreeTxdCount(dev)) > 32) {
826 for (i=0; i<4; i++) destQ_count += wd->destQ.size[i];
827 if (0 >= destQ_count) break;
829 ac = pri[wd->destQ.ppri]; wd->destQ.ppri = (wd->destQ.ppri + 1) % 10;
830 for (i=0; i<10; i++){
831 if(wd->destQ.size[ac]!=0) break;
832 ac = pri[wd->destQ.ppri]; wd->destQ.ppri = (wd->destQ.ppri + 1) % 10;
835 dest = wd->destQ.getNext(dev, ac);
836 if (dest->Qtype == 0) {
837 tid_tx = dest->tid_tx;
838 tid_tx->size = zm_agg_qlen(dev, tid_tx->aggHead, tid_tx->aggTail);
840 wd->destQ.delete(dev, 0, tid_tx, NULL);
843 else if((wd->aggState == 0) && (tid_tx->size >= 16)){
844 zfAggTxSend(dev, zfHpGetFreeTxdCount(dev), tid_tx);
856 /************************************************************************/
858 /* FUNCTION DESCRIPTION zfAggTx */
859 /* return Status code ZM_SUCCESS or error code */
860 /* management A-MPDU aggregation function, */
861 /* management aggregation queue, calculate arrivalrate, */
862 /* add/delete an aggregation queue of a stream, */
863 /* enqueue packets into responsible aggregate queue. */
864 /* take (dev, buf, ac) as input */
867 /* dev : device pointer */
868 /* buf : packet buff */
869 /* ac : access category */
875 /* Honda Atheros Communications, INC. 2006.12 */
877 /************************************************************************/
878 u16_t
zfAggTx(zdev_t
* dev
, zbuf_t
* buf
, u16_t tid
)
883 //u16_t arrivalrate = 0;
886 zmw_get_wlan_dev(dev
);
888 zmw_declare_for_critical_section();
890 if(!wd
->aggInitiated
)
892 return ZM_ERR_TX_BUFFER_UNAVAILABLE
;
895 aid
= zfAggGetSta(dev
, buf
);
897 //arrivalrate = zfAggTxArrivalRate(dev, aid, tid);
902 * STA not associated, this is a BC/MC or STA->AP packet
905 return ZM_ERR_TX_BUFFER_UNAVAILABLE
;
909 * STA associated, a unicast packet
912 tid_tx
= zfAggTxGetQueue(dev
, aid
, tid
);
914 /*tid_q.tid_tx = tid_tx;
915 wd->destQ.insert = zfAggDestInsert;
916 wd->destQ.insert(dev, 0, tid_q);
921 * this (aid, ac) is aggregated
924 //if (arrivalrate < ZM_AGG_LOW_THRESHOLD)
928 * arrival rate too low
929 * delete this aggregate queue
932 zmw_enter_critical_section(dev
);
934 //wd->aggQPool[qnum]->clearFlag = wd->aggQPool[qnum]->deleteFlag =1;
936 zmw_leave_critical_section(dev
);
940 return zfAggTxEnqueue(dev
, buf
, aid
, tid_tx
);
946 * this (aid, ac) not yet aggregated
950 //if (arrivalrate > ZM_AGG_HIGH_THRESHOLD)
954 * arrivalrate high enough to get a new agg queue
957 tid_tx
= zfAggTxNewQueue(dev
, aid
, tid
, buf
);
959 //zm_msg1_agg(ZM_LV_0, "get new AggQueue qnum = ", tid_tx->);
964 * got a new aggregate queue
967 //zmw_enter_critical_section(dev);
969 //wd->aggSta[aid].aggFlag[ac] = 1;
971 //zmw_leave_critical_section(dev);
974 * add ADDBA functions here
975 * return ZM_ERR_TX_BUFFER_UNAVAILABLE;
979 //zfAggSendAddbaRequest(dev, tid_tx->dst, tid_tx->ac, tid_tx->tid);
980 //zmw_enter_critical_section(dev);
982 //wd->aggSta[aid].aggFlag[ac] = 0;
984 //zmw_leave_critical_section(dev);
986 return zfAggTxEnqueue(dev
, buf
, aid
, tid_tx
);
992 * just can't get a new aggregate queue
995 return ZM_ERR_TX_BUFFER_UNAVAILABLE
;
1001 * arrival rate is not high enough to get a new agg queue
1004 return ZM_ERR_TX_BUFFER_UNAVAILABLE
;
1013 /************************************************************************/
1015 /* FUNCTION DESCRIPTION zfAggTxReadyCount */
1016 /* return counter of ready to aggregate queues. */
1017 /* take (dev, ac) as input, only calculate the ready to aggregate */
1018 /* queues of one particular ac. */
1021 /* dev : device pointer */
1022 /* ac : access category */
1025 /* counter of ready to aggregate queues */
1028 /* Honda Atheros Communications, INC. 2006.12 */
1030 /************************************************************************/
1031 u16_t
zfAggTxReadyCount(zdev_t
* dev
, u16_t ac
)
1034 u16_t readycount
= 0;
1036 zmw_get_wlan_dev(dev
);
1038 zmw_declare_for_critical_section();
1040 zmw_enter_critical_section(dev
);
1042 for (i
=0 ; i
<ZM_AGG_POOL_SIZE
; i
++)
1044 if (wd
->aggQPool
[i
]->aggQEnabled
&& (wd
->aggQPool
[i
]->aggReady
|| \
1045 wd
->aggQPool
[i
]->clearFlag
) && ac
== wd
->aggQPool
[i
]->ac
)
1049 zmw_leave_critical_section(dev
);
1054 /************************************************************************/
1056 /* FUNCTION DESCRIPTION zfAggTxPartial */
1057 /* return the number that Vtxq has to send. */
1058 /* take (dev, ac, readycount) as input, calculate the ratio of */
1059 /* Vtxq length to (Vtxq length + readycount) of a particular ac, */
1060 /* and returns the Vtxq length * the ratio */
1063 /* dev : device pointer */
1064 /* ac : access category */
1065 /* readycount: the number of ready to aggregate queues of this ac */
1068 /* Vtxq length * ratio */
1071 /* Honda Atheros Communications, INC. 2006.12 */
1073 /************************************************************************/
1074 u16_t
zfAggTxPartial(zdev_t
* dev
, u16_t ac
, u16_t readycount
)
1079 zmw_get_wlan_dev(dev
);
1081 zmw_declare_for_critical_section();
1083 zmw_enter_critical_section(dev
);
1085 qlen
= zm_agg_qlen(dev
, wd
->vtxqHead
[ac
], wd
->vtxqTail
[ac
]);
1087 if ((qlen
+ readycount
) > 0)
1089 partial
= (u16_t
)( zm_agg_weight(ac
) * ((u16_t
)qlen
/(qlen
+ \
1097 zmw_leave_critical_section(dev
);
1106 /************************************************************************/
1108 /* FUNCTION DESCRIPTION zfAggTxSend */
1109 /* return sentcount */
1110 /* take (dev, ac, n) as input, n is the number of scheduled agg */
1111 /* queues to be sent of the particular ac. */
1114 /* dev : device pointer */
1115 /* ac : access category */
1116 /* n : the number of scheduled aggregation queues to be sent */
1122 /* Honda Atheros Communications, INC. 2006.12 */
1124 /************************************************************************/
1125 u16_t
zfAggTxSend(zdev_t
* dev
, u32_t freeTxd
, TID_TX tid_tx
)
1130 //u16_t sentcount = 0;
1132 struct aggControl aggControl
;
1136 //TID_BAW tid_baw = NULL;
1137 //struct bufInfo *buf_info;
1139 zmw_get_wlan_dev(dev
);
1141 zmw_declare_for_critical_section();
1143 //while (tid_tx->size > 0)
1145 zmw_enter_critical_section(dev
);
1146 tid_tx
->size
= zm_agg_qlen(dev
, tid_tx
->aggHead
, tid_tx
->aggTail
);
1147 aggLen
= zm_agg_min(16, zm_agg_min(tid_tx
->size
, (u16_t
)(freeTxd
- 2)));
1148 zmw_leave_critical_section(dev
);
1151 * why there have to be 2 free Txd?
1158 buf
= zfAggTxGetVtxq(dev
, tid_tx
);
1160 zfTxSendEth(dev
, buf
, 0, ZM_EXTERNAL_ALLOC_BUF
, 0);
1161 if (tid_tx
->size
== 0) {
1162 //DESTQ.delete(dev, 0, tid_tx, NULL);
1168 * Free Txd queue is big enough to put aggregation
1170 zmw_enter_critical_section(dev
);
1171 if (wd
->aggState
== 1) {
1172 zmw_leave_critical_section(dev
);
1176 zmw_leave_critical_section(dev
);
1179 zm_msg1_agg(ZM_LV_0
, "aggLen=", aggLen
);
1180 tid_tx
->aggFrameSize
= 0;
1181 for (j
=0; j
< aggLen
; j
++) {
1182 buf
= zfAggTxGetVtxq(dev
, tid_tx
);
1184 zmw_enter_critical_section(dev
);
1185 tid_tx
->size
= zm_agg_qlen(dev
, tid_tx
->aggHead
, tid_tx
->aggTail
);
1186 zmw_leave_critical_section(dev
);
1189 //struct aggTally *agg_tal;
1190 u16_t completeIndex
;
1193 aggControl
.ampduIndication
= ZM_AGG_FIRST_MPDU
;
1196 else if ((j
== (aggLen
- 1)) || tid_tx
->size
== 0)
1198 aggControl
.ampduIndication
= ZM_AGG_LAST_MPDU
;
1204 aggControl
.ampduIndication
= ZM_AGG_MIDDLE_MPDU
;
1205 /* the packet is delayed more than 500 ms, drop it */
1208 tid_tx
->aggFrameSize
+= zfwBufGetSize(dev
, buf
);
1209 aggControl
.addbaIndication
= 0;
1210 aggControl
.aggEnabled
= 1;
1213 agg_tal
= &wd
->agg_tal
;
1214 agg_tal
->sent_packets_sum
++;
1218 zfAggTxSendEth(dev
, buf
, 0, ZM_EXTERNAL_ALLOC_BUF
, 0, &aggControl
, tid_tx
);
1220 zmw_enter_critical_section(dev
);
1221 completeIndex
= tid_tx
->complete
;
1222 if(zm_agg_inQ(tid_tx
, tid_tx
->complete
))
1223 zm_agg_plus(tid_tx
->complete
);
1224 zmw_leave_critical_section(dev
);
1226 if(zm_agg_inQ(tid_tx
, completeIndex
) && wd
->zfcbSendCompleteIndication
1227 && tid_tx
->aggvtxq
[completeIndex
].buf
) {
1228 wd
->zfcbSendCompleteIndication(dev
, tid_tx
->aggvtxq
[completeIndex
].buf
);
1229 zm_debug_msg0("in queue complete worked!");
1235 * this aggregation queue is empty
1237 zm_msg1_agg(ZM_LV_0
, "aggLen not reached, but no more frame, j=", j
);
1242 zmw_enter_critical_section(dev
);
1244 zmw_leave_critical_section(dev
);
1246 //zm_acquire_agg_spin_lock(Adapter);
1247 tid_tx
->size
= zm_agg_qlen(dev
, tid_tx
->aggHead
, tid_tx
->aggTail
);
1248 //zm_release_agg_spin_lock(Adapter);
1250 if (tid_tx
->size
== 0) {
1251 //DESTQ.delete(dev, 0, tid_tx, NULL);
1256 //zfAggInvokeBar(dev, tid_tx);
1259 zm_msg1_agg(ZM_LV_0
, "0xC2:sent 1 aggr, aggr_count=", aggr_count
);
1260 zm_msg1_agg(ZM_LV_0
, "0xC2:sent 1 aggr, aggr_size=", j
);
1266 /************************************************************************/
1268 /* FUNCTION DESCRIPTION zfAggTxGetReadyQueue */
1269 /* return the number of the aggregation queue */
1270 /* take (dev, ac) as input, find the agg queue with smallest */
1271 /* arrival time (waited longest) among those ready or clearFlag */
1275 /* dev : device pointer */
1276 /* ac : access category */
1279 /* aggregation queue number */
1282 /* Honda Atheros Communications, INC. 2006.12 */
1284 /************************************************************************/
1285 TID_TX
zfAggTxGetReadyQueue(zdev_t
* dev
, u16_t ac
)
1287 //u16_t qnum = ZM_AGG_POOL_SIZE;
1290 TID_TX tid_tx
= NULL
;
1292 zmw_get_wlan_dev(dev
);
1294 zmw_declare_for_critical_section();
1296 zmw_enter_critical_section(dev
);
1298 for (i
=0 ;i
<ZM_AGG_POOL_SIZE
; i
++)
1300 if (1 == wd
->aggQPool
[i
]->aggQEnabled
&& ac
== wd
->aggQPool
[i
]->ac
&&
1301 (wd
->aggQPool
[i
]->size
> 0))
1303 if (0 == time
|| time
> wd
->aggQPool
[i
]->aggvtxq
[ \
1304 wd
->aggQPool
[i
]->aggHead
].arrivalTime
)
1306 tid_tx
= wd
->aggQPool
[i
];
1307 time
= tid_tx
->aggvtxq
[ tid_tx
->aggHead
].arrivalTime
;
1312 zmw_leave_critical_section(dev
);
1319 /************************************************************************/
1321 /* FUNCTION DESCRIPTION zfAggTxGetVtxq */
1322 /* return an MSDU */
1323 /* take (dev, qnum) as input, return an MSDU out of the agg queue. */
1326 /* dev : device pointer */
1327 /* qnum: queue number */
1333 /* Honda Atheros Communications, INC. 2006.12 */
1335 /************************************************************************/
1336 zbuf_t
* zfAggTxGetVtxq(zdev_t
* dev
, TID_TX tid_tx
)
1340 zmw_declare_for_critical_section();
1342 if (tid_tx
->aggHead
!= tid_tx
->aggTail
)
1344 buf
= tid_tx
->aggvtxq
[ tid_tx
->aggTail
].buf
;
1346 tid_tx
->aggvtxq
[tid_tx
->aggTail
].buf
= NULL
;
1348 zmw_enter_critical_section(dev
);
1349 tid_tx
->aggTail
= ((tid_tx
->aggTail
+ 1) & ZM_AGGQ_SIZE_MASK
);
1350 if(tid_tx
->size
> 0) tid_tx
->size
--;
1351 tid_tx
->size
= zm_agg_qlen(dev
, tid_tx
->aggHead
, tid_tx
->aggTail
);
1353 //tid_tx->aggTail = tid_tx->aggHead = tid_tx->size = 0;
1354 //zm_msg1_agg(ZM_LV_0, "GetVtxq buf == NULL, tid_tx->size=", tid_tx->size);
1356 zmw_leave_critical_section(dev
);
1363 zm_msg1_agg(ZM_LV_0
, "tid_tx->aggHead == tid_tx->aggTail, tid_tx->size=", tid_tx
->size
);
1367 if (zm_agg_qlen(dev
, tid_tx
->aggHead
, tid_tx
->aggTail
) != tid_tx
->size
)
1368 zm_msg1_agg(ZM_LV_0
, "qlen!=tid_tx->size! tid_tx->size=", tid_tx
->size
);
1373 /************************************************************************/
1375 /* FUNCTION DESCRIPTION zfAggTxDeleteQueue */
1376 /* return ZM_SUCCESS (can't fail) */
1377 /* take (dev, qnum) as input, reset (delete) this aggregate queue, */
1378 /* this queue is virtually returned to the aggregate queue pool. */
1381 /* dev : device pointer */
1382 /* qnum: queue number */
1388 /* Honda Atheros Communications, INC. 2006.12 */
1390 /************************************************************************/
1391 u16_t
zfAggTxDeleteQueue(zdev_t
* dev
, u16_t qnum
)
1394 struct aggQueue
*tx_tid
;
1395 struct aggSta
*agg_sta
;
1397 zmw_get_wlan_dev(dev
);
1399 zmw_declare_for_critical_section();
1401 tx_tid
= wd
->aggQPool
[qnum
];
1402 agg_sta
= &wd
->aggSta
[tx_tid
->aggQSTA
];
1406 zmw_enter_critical_section(dev
);
1408 tx_tid
->aggQEnabled
= 0;
1409 tx_tid
->aggHead
= tx_tid
->aggTail
= 0;
1410 tx_tid
->aggReady
= 0;
1411 tx_tid
->clearFlag
= tx_tid
->deleteFlag
= 0;
1413 agg_sta
->count
[ac
] = 0;
1415 agg_sta
->tid_tx
[tid
] = NULL
;
1416 agg_sta
->aggFlag
[ac
] = 0;
1418 zmw_leave_critical_section(dev
);
1420 zm_msg1_agg(ZM_LV_0
, "queue deleted! qnum=", qnum
);
1425 #ifdef ZM_ENABLE_AGGREGATION
1426 #ifndef ZM_ENABLE_FW_BA_RETRANSMISSION //disable BAW
1427 void zfBawCore(zdev_t
* dev
, u16_t baw_seq
, u32_t bitmap
, u16_t aggLen
) {
1431 struct bufInfo
*buf_info
;
1433 zmw_get_wlan_dev(dev
);
1434 //zmw_declare_for_critical_section();
1435 tid_baw
= BAW
->getQ(dev
, baw_seq
);
1437 if (NULL
== tid_baw
)
1440 total_mpdu
+= aggLen
;
1441 for (i
= aggLen
- 1; i
>=0; i
--) {
1442 if (((bitmap
>> i
) & 0x1) == 0) {
1443 buf_info
= BAW
->pop(dev
, i
, tid_baw
);
1444 buf
= buf_info
->buf
;
1446 //wd->zfcbSetBawQ(dev, buf, 0);
1447 zfAggTidTxInsertHead(dev
, buf_info
, tid_baw
->tid_tx
);
1454 BAW
->disable(dev
, tid_baw
);
1455 zfAggTxScheduler(dev
);
1456 zm_debug_msg1("success_mpdu = ", success_mpdu
);
1457 zm_debug_msg1(" total_mpdu = ", total_mpdu
);
1460 void zfBawInit(zdev_t
* dev
) {
1463 zmw_get_wlan_dev(dev
);
1464 //zmw_declare_for_critical_section();
1466 for (i
=0; i
<ZM_BAW_POOL_SIZE
; i
++){
1467 tid_baw
= &BAW
->tid_baw
[i
];
1468 for (j
=0; j
<ZM_VTXQ_SIZE
; j
++) {
1469 tid_baw
->frame
[j
].buf
= NULL
;
1471 tid_baw
->enabled
= tid_baw
->head
= tid_baw
->tail
= tid_baw
->size
= 0;
1472 tid_baw
->start_seq
= 0;
1475 BAW
->core
= zfBawCore
;
1476 BAW
->getNewQ
= zfBawGetNewQ
;
1477 BAW
->insert
= zfBawInsert
;
1478 BAW
->pop
= zfBawPop
;
1479 BAW
->enable
= zfBawEnable
;
1480 BAW
->disable
= zfBawDisable
;
1481 BAW
->getQ
= zfBawGetQ
;
1486 TID_BAW
zfBawGetNewQ(zdev_t
* dev
, u16_t start_seq
, TID_TX tid_tx
) {
1487 TID_BAW tid_baw
=NULL
;
1488 TID_BAW next_baw
=NULL
;
1490 zmw_get_wlan_dev(dev
);
1491 //zmw_declare_for_critical_section();
1494 for (i=0; i<ZM_BAW_POOL_SIZE; i++){
1495 tid_baw = &BAW->tid_baw[i];
1496 if (FALSE == tid_baw->enabled)
1501 tid_baw
= &BAW
->tid_baw
[BAW
->delPoint
];
1503 //if (ZM_BAW_POOL_SIZE == i) {
1505 // u8_t temp = BAW->delPoint;
1506 // tid_baw = &BAW->tid_baw[BAW->delPoint];
1507 // BAW->disable(dev, tid_baw);
1508 // BAW->delPoint = (BAW->delPoint < (ZM_BAW_POOL_SIZE - 1))? (BAW->delPoint + 1): 0;
1509 // temp = BAW->delPoint;
1512 zm_msg1_agg(ZM_LV_0
, "get new tid_baw, index=", i
);
1513 BAW
->delPoint
= (i
< (ZM_BAW_POOL_SIZE
-1))? (i
+ 1): 0;
1514 next_baw
= &BAW
->tid_baw
[BAW
->delPoint
];
1515 if (1 == next_baw
->enabled
) BAW
->disable(dev
, next_baw
);
1517 BAW
->enable(dev
, tid_baw
, start_seq
);
1518 tid_baw
->tid_tx
= tid_tx
;
1523 u16_t
zfBawInsert(zdev_t
* dev
, zbuf_t
* buf
, u16_t baw_seq
, TID_BAW tid_baw
, u8_t baw_retransmit
, struct baw_header_r
*header_r
) {
1527 //zmw_get_wlan_dev(dev);
1528 //zmw_declare_for_critical_section();
1530 if(tid_baw
->size
< (ZM_VTXQ_SIZE
- 1)) {
1531 struct baw_header
*baw_header
= &tid_baw
->frame
[tid_baw
->head
].baw_header
;
1533 baw_header
->headerLen
= header_r
->headerLen
;
1534 baw_header
->micLen
= header_r
->micLen
;
1535 baw_header
->snapLen
= header_r
->snapLen
;
1536 baw_header
->removeLen
= header_r
->removeLen
;
1537 baw_header
->keyIdx
= header_r
->keyIdx
;
1538 zfwMemoryCopy((u8_t
*)baw_header
->header
, (u8_t
*)header_r
->header
, 58);
1539 zfwMemoryCopy((u8_t
*)baw_header
->mic
, (u8_t
*)header_r
->mic
, 8);
1540 zfwMemoryCopy((u8_t
*)baw_header
->snap
, (u8_t
*)header_r
->snap
, 8);
1541 //wd->zfcbSetBawQ(dev, buf, 1);
1542 tid_baw
->frame
[tid_baw
->head
].buf
= buf
;
1543 tid_baw
->frame
[tid_baw
->head
].baw_seq
= baw_seq
;
1544 tid_baw
->frame
[tid_baw
->head
].baw_retransmit
= baw_retransmit
+ 1;
1546 //tid_baw->frame[tid_baw->head].data = pBuf->data;
1551 //wd->zfcbSetBawQ(dev, buf, 0);
1552 zfwBufFree(dev
, buf
, ZM_SUCCESS
);
1558 struct bufInfo
* zfBawPop(zdev_t
* dev
, u16_t index
, TID_BAW tid_baw
) {
1561 struct bufInfo
*buf_info
;
1562 zmw_get_wlan_dev(dev
);
1564 buf_info
= &wd
->buf_info
;
1565 buf_info
->baw_header
= NULL
;
1567 if (NULL
== (buf_info
->buf
= tid_baw
->frame
[index
].buf
))
1570 buf_info
->baw_retransmit
= tid_baw
->frame
[index
].baw_retransmit
;
1571 buf_info
->baw_header
= &tid_baw
->frame
[index
].baw_header
;
1572 buf_info
->timestamp
= tid_baw
->frame
[index
].timestamp
;
1573 //pBuf->data = pBuf->buffer;
1574 //wd->zfcbRestoreBufData(dev, buf);
1575 tid_baw
->frame
[index
].buf
= NULL
;
1580 void zfBawEnable(zdev_t
* dev
, TID_BAW tid_baw
, u16_t start_seq
) {
1583 //zmw_get_wlan_dev(dev);
1584 //zmw_declare_for_critical_section();
1586 tid_baw
->enabled
= TRUE
;
1587 tid_baw
->head
= tid_baw
->tail
= tid_baw
->size
= 0;
1588 tid_baw
->start_seq
= start_seq
;
1591 void zfBawDisable(zdev_t
* dev
, TID_BAW tid_baw
) {
1595 //zmw_get_wlan_dev(dev);
1596 //zmw_declare_for_critical_section();
1597 for (i
=0; i
<ZM_VTXQ_SIZE
; i
++) {
1598 if (tid_baw
->frame
[i
].buf
) {
1600 //wd->zfcbSetBawQ(dev, tid_baw->frame[i].buf, 0);
1601 zfwBufFree(dev
, tid_baw
->frame
[i
].buf
, ZM_SUCCESS
);
1602 tid_baw
->frame
[i
].buf
= NULL
;
1606 tid_baw
->enabled
= FALSE
;
1609 TID_BAW
zfBawGetQ(zdev_t
* dev
, u16_t baw_seq
) {
1610 TID_BAW tid_baw
=NULL
;
1613 zmw_get_wlan_dev(dev
);
1614 //zmw_declare_for_critical_section();
1615 for (i
=0; i
<ZM_BAW_POOL_SIZE
; i
++){
1616 tid_baw
= &BAW
->tid_baw
[i
];
1617 if (TRUE
== tid_baw
->enabled
)
1619 zm_msg1_agg(ZM_LV_0
, "get an old tid_baw, baw_seq=", baw_seq
);
1620 zm_msg1_agg(ZM_LV_0
, "check a tid_baw->start_seq=", tid_baw
->start_seq
);
1621 if(baw_seq
== tid_baw
->start_seq
)
1626 if (ZM_BAW_POOL_SIZE
== i
)
1630 #endif //disable BAW
1633 u16_t
zfAggTallyReset(zdev_t
* dev
)
1635 struct aggTally
* agg_tal
;
1637 zmw_get_wlan_dev(dev
);
1639 //zmw_declare_for_critical_section();
1641 agg_tal
= &wd
->agg_tal
;
1642 agg_tal
->got_packets_sum
= 0;
1643 agg_tal
->got_bytes_sum
= 0;
1644 agg_tal
->sent_bytes_sum
= 0;
1645 agg_tal
->sent_packets_sum
= 0;
1646 agg_tal
->avg_got_packets
= 0;
1647 agg_tal
->avg_got_bytes
= 0;
1648 agg_tal
->avg_sent_packets
= 0;
1649 agg_tal
->avg_sent_bytes
= 0;
1655 /************************************************************************/
1657 /* FUNCTION DESCRIPTION zfAggScanAndClear */
1658 /* If the packets in a queue have waited for too long, clear and */
1659 /* delete this aggregation queue. */
1662 /* dev : device pointer */
1663 /* time : current time */
1669 /* Honda Atheros Communications, INC. 2006.12 */
1671 /************************************************************************/
1672 u16_t
zfAggScanAndClear(zdev_t
* dev
, u32_t time
)
1682 zmw_get_wlan_dev(dev
);
1684 zmw_declare_for_critical_section();
1686 if(!(wd
->state
== ZM_WLAN_STATE_ENABLED
)) return 0;
1687 zfAggTxScheduler(dev
, 1);
1688 tick
= zm_agg_GetTime();
1689 for (i
=0; i
<ZM_AGG_POOL_SIZE
; i
++)
1691 if (!wd
->aggQPool
[i
]) return 0;
1692 if (1 == wd
->aggQPool
[i
]->aggQEnabled
)
1694 tid_tx
= wd
->aggQPool
[i
];
1695 zmw_enter_critical_section(dev
);
1697 head
= tid_tx
->aggHead
;
1698 tail
= tid_tx
->aggTail
;
1700 arrivalTime
= (u32_t
)tid_tx
->aggvtxq
[tid_tx
->aggTail
].arrivalTime
;
1703 if((tick
- arrivalTime
) <= ZM_AGG_CLEAR_TIME
)
1707 else if((tid_tx
->size
= zm_agg_qlen(dev
, tid_tx
->aggHead
, tid_tx
->aggTail
)) > 0)
1710 tid_tx
->clearFlag
= 1;
1712 //zm_msg1_agg(ZM_LV_0, "clear queue tick =", tick);
1713 //zm_msg1_agg(ZM_LV_0, "clear queue arrival =", arrivalTime);
1716 //zmw_leave_critical_section(dev);
1717 //zfAggTxScheduler(dev);
1718 //zmw_enter_critical_section(dev);
1722 if (tid_tx
->size
== 0)
1727 if (tick
- tid_tx
->lastArrival
> ZM_AGG_DELETE_TIME
)
1729 zm_msg1_agg(ZM_LV_0
, "delete queue, idle for n sec. n = ", \
1730 ZM_AGG_DELETE_TIME
/10);
1732 zmw_leave_critical_section(dev
);
1733 zfAggTxDeleteQueue(dev
, i
);
1734 zmw_enter_critical_section(dev
);
1738 zmw_leave_critical_section(dev
);
1742 zfAggRxClear(dev
, time
);
1745 if((wd
->tick
% 100) == 0) {
1746 zfAggPrintTally(dev
);
1753 u16_t
zfAggPrintTally(zdev_t
* dev
)
1755 struct aggTally
* agg_tal
;
1757 zmw_get_wlan_dev(dev
);
1759 //zmw_declare_for_critical_section();
1761 agg_tal
= &wd
->agg_tal
;
1763 if(agg_tal
->got_packets_sum
< 10)
1765 zfAggTallyReset(dev
);
1770 agg_tal
->avg_got_packets
= (agg_tal
->avg_got_packets
* (agg_tal
->time
- 1) +
1771 agg_tal
->got_packets_sum
) / agg_tal
->time
;
1772 agg_tal
->avg_got_bytes
= (agg_tal
->avg_got_bytes
* (agg_tal
->time
- 1) +
1773 agg_tal
->got_bytes_sum
) / agg_tal
->time
;
1774 agg_tal
->avg_sent_packets
= (agg_tal
->avg_sent_packets
* (agg_tal
->time
- 1)
1775 + agg_tal
->sent_packets_sum
) / agg_tal
->time
;
1776 agg_tal
->avg_sent_bytes
= (agg_tal
->avg_sent_bytes
* (agg_tal
->time
- 1) +
1777 agg_tal
->sent_bytes_sum
) / agg_tal
->time
;
1778 zm_msg1_agg(ZM_LV_0
, "got_packets_sum =", agg_tal
->got_packets_sum
);
1779 zm_msg1_agg(ZM_LV_0
, " got_bytes_sum =", agg_tal
->got_bytes_sum
);
1780 zm_msg1_agg(ZM_LV_0
, "sent_packets_sum=", agg_tal
->sent_packets_sum
);
1781 zm_msg1_agg(ZM_LV_0
, " sent_bytes_sum =", agg_tal
->sent_bytes_sum
);
1782 agg_tal
->got_packets_sum
= agg_tal
->got_bytes_sum
=agg_tal
->sent_packets_sum
1783 = agg_tal
->sent_bytes_sum
= 0;
1784 zm_msg1_agg(ZM_LV_0
, "avg_got_packets =", agg_tal
->avg_got_packets
);
1785 zm_msg1_agg(ZM_LV_0
, " avg_got_bytes =", agg_tal
->avg_got_bytes
);
1786 zm_msg1_agg(ZM_LV_0
, "avg_sent_packets=", agg_tal
->avg_sent_packets
);
1787 zm_msg1_agg(ZM_LV_0
, " avg_sent_bytes =", agg_tal
->avg_sent_bytes
);
1788 if ((wd
->commTally
.BA_Fail
== 0) || (wd
->commTally
.Hw_Tx_MPDU
== 0))
1790 zm_msg1_agg(ZM_LV_0
, "Hardware Tx MPDU=", wd
->commTally
.Hw_Tx_MPDU
);
1791 zm_msg1_agg(ZM_LV_0
, " BA Fail number=", wd
->commTally
.BA_Fail
);
1794 zm_msg1_agg(ZM_LV_0
, "1/(BA fail rate)=", wd
->commTally
.Hw_Tx_MPDU
/wd
->commTally
.BA_Fail
);
1799 u16_t
zfAggRxClear(zdev_t
* dev
, u32_t time
)
1802 struct agg_tid_rx
*tid_rx
;
1804 zmw_get_wlan_dev(dev
);
1806 zmw_declare_for_critical_section();
1808 for (i
=0; i
<ZM_AGG_POOL_SIZE
; i
++)
1810 zmw_enter_critical_section(dev
);
1811 tid_rx
= wd
->tid_rx
[i
];
1812 if (tid_rx
->baw_head
!= tid_rx
->baw_tail
)
1814 u16_t j
= tid_rx
->baw_tail
;
1815 while ((j
!= tid_rx
->baw_head
) && !tid_rx
->frame
[j
].buf
) {
1816 j
= (j
+ 1) & ZM_AGG_BAW_MASK
;
1818 if ((j
!= tid_rx
->baw_head
) && (time
- tid_rx
->frame
[j
].arrivalTime
) >
1819 (ZM_AGG_CLEAR_TIME
- 5))
1821 zmw_leave_critical_section(dev
);
1822 zm_msg0_agg(ZM_LV_1
, "queue RxFlush by RxClear");
1823 zfAggRxFlush(dev
, 0, tid_rx
);
1824 zmw_enter_critical_section(dev
);
1827 zmw_leave_critical_section(dev
);
1833 struct agg_tid_rx
* zfAggRxEnabled(zdev_t
* dev
, zbuf_t
* buf
)
1835 u16_t dst0
, src
[3], aid
;
1841 //struct aggSta *agg_sta;
1842 #if ZM_AGG_FPGA_REORDERING
1843 struct agg_tid_rx
*tid_rx
;
1845 zmw_get_wlan_dev(dev
);
1847 //zmw_declare_for_critical_section();
1848 seq_no
= zmw_rx_buf_readh(dev
, buf
, 22) >> 4;
1849 //DbgPrint("Rx seq=%d\n", seq_no);
1850 if (wd
->sta
.EnableHT
== 0)
1855 frameCtrl
= zmw_rx_buf_readb(dev
, buf
, 0);
1856 frameType
= frameCtrl
& 0xf;
1857 frameSubtype
= frameCtrl
& 0xf0;
1860 if (frameType
!= ZM_WLAN_DATA_FRAME
) //non-Qos Data? (frameSubtype&0x80)
1864 #ifdef ZM_ENABLE_PERFORMANCE_EVALUATION
1868 tcp_seq
= zmw_rx_buf_readb(dev
, buf
, 22+36) << 24;
1869 tcp_seq
+= zmw_rx_buf_readb(dev
, buf
, 22+37) << 16;
1870 tcp_seq
+= zmw_rx_buf_readb(dev
, buf
, 22+38) << 8;
1871 tcp_seq
+= zmw_rx_buf_readb(dev
, buf
, 22+39);
1872 ZM_SEQ_DEBUG("In %5d, %12u\n", seq_no
, tcp_seq
);
1876 dst0
= zmw_rx_buf_readh(dev
, buf
, offset
+4);
1878 src
[0] = zmw_rx_buf_readh(dev
, buf
, offset
+10);
1879 src
[1] = zmw_rx_buf_readh(dev
, buf
, offset
+12);
1880 src
[2] = zmw_rx_buf_readh(dev
, buf
, offset
+14);
1882 #if ZM_AGG_FPGA_DEBUG
1885 aid
= zfApFindSta(dev
, src
);
1888 //agg_sta = &wd->aggSta[aid];
1889 //zfTxGetIpTosAndFrag(dev, buf, &up, &fragOff);
1890 //ac = zcUpToAc[up&0x7] & 0x3;
1893 * Filter unicast frame only, aid == 0 is for debug only
1895 if ((dst0
& 0x1) == 0 && aid
== 0)
1897 #if ZM_AGG_FPGA_REORDERING
1898 tid_rx
= zfAggRxGetQueue(dev
, buf
) ;
1903 //if (tid_rx->addBaExchangeStatusCode == ZM_AGG_ADDBA_RESPONSE)
1914 u16_t
zfAggRx(zdev_t
* dev
, zbuf_t
* buf
, struct zsAdditionInfo
*addInfo
, struct agg_tid_rx
*tid_rx
)
1922 zmw_get_wlan_dev(dev
);
1924 zmw_declare_for_critical_section();
1926 ZM_BUFFER_TRACE(dev
, buf
)
1928 ZM_PERFORMANCE_RX_REORDER(dev
);
1930 seq_no
= zmw_rx_buf_readh(dev
, buf
, offset
+22) >> 4;
1932 index
= seq_no
- tid_rx
->seq_start
;
1937 /* zm_msg2_agg(ZM_LV_0, "queue seq = ", seq_no);
1938 * DbgPrint("%s:%s%lxh %s%lxh\n", __func__, "queue seq=", seq_no,
1939 * "; seq_start=", tid_rx->seq_start);
1942 //DbgPrint("seq_no=%d, seq_start=%d\n", seq_no, tid_rx->seq_start);
1944 /* In some APs, we found that it might transmit NULL data whose sequence number
1945 is out or order. In order to avoid this problem, we ignore these NULL data.
1948 frameSubType
= (zmw_rx_buf_readh(dev
, buf
, 0) & 0xF0) >> 4;
1950 /* If this is a NULL data instead of Qos NULL data */
1951 if ((frameSubType
& 0x0C) == 0x04)
1955 seq_diff
= (seq_no
> tid_rx
->seq_start
) ?
1956 seq_no
- tid_rx
->seq_start
: tid_rx
->seq_start
- seq_no
;
1958 if (seq_diff
> ZM_AGG_BAW_SIZE
)
1960 zm_debug_msg0("Free Rx NULL data in zfAggRx");
1962 /* Free Rx buffer */
1963 zfwBufFree(dev
, buf
, 0);
1964 return ZM_ERR_OUT_OF_ORDER_NULL_DATA
;
1969 * sequence number wrap at 4k
1971 if (tid_rx
->seq_start
> seq_no
)
1975 zmw_enter_critical_section(dev
);
1976 if (tid_rx
->seq_start
>= 4096) {
1977 tid_rx
->seq_start
= 0;
1979 zmw_leave_critical_section(dev
);
1983 if (tid_rx
->seq_start
== seq_no
) {
1984 zmw_enter_critical_section(dev
);
1985 if (((tid_rx
->baw_head
- tid_rx
->baw_tail
) & ZM_AGG_BAW_MASK
) > 0) {
1986 //DbgPrint("head=%d, tail=%d", tid_rx->baw_head, tid_rx->baw_tail);
1987 tid_rx
->baw_tail
= (tid_rx
->baw_tail
+ 1) & ZM_AGG_BAW_MASK
;
1989 tid_rx
->seq_start
= (tid_rx
->seq_start
+ 1) & (4096 - 1);
1990 zmw_leave_critical_section(dev
);
1992 ZM_PERFORMANCE_RX_SEQ(dev
, buf
);
1994 if (wd
->zfcbRecv80211
!= NULL
) {
1995 //seq_no = zmw_rx_buf_readh(dev, buf, offset+22) >> 4;
1996 //DbgPrint("Recv indicate seq=%d\n", seq_no);
1997 //DbgPrint("1. seq=%d\n", seq_no);
1999 wd
->zfcbRecv80211(dev
, buf
, addInfo
);
2002 zfiRecv80211(dev
, buf
, addInfo
);
2005 else if (!zfAggRxEnqueue(dev
, buf
, tid_rx
, addInfo
))
2013 while (tid_rx
->baw_head
!= tid_rx
->baw_tail
) {// && tid_rx->frame[tid_rx->baw_tail].buf)
2016 zmw_enter_critical_section(dev
);
2018 tailIndex
= tid_rx
->baw_tail
;
2019 pbuf
= tid_rx
->frame
[tailIndex
].buf
;
2020 tid_rx
->frame
[tailIndex
].buf
= 0;
2023 zmw_leave_critical_section(dev
);
2027 tid_rx
->baw_tail
= (tid_rx
->baw_tail
+ 1) & ZM_AGG_BAW_MASK
;
2028 tid_rx
->seq_start
= (tid_rx
->seq_start
+ 1) & (4096 - 1);
2031 //if(pbuf && tid_rx->baw_size > 0)
2032 // tid_rx->baw_size--;
2034 zmw_leave_critical_section(dev
);
2036 ZM_PERFORMANCE_RX_SEQ(dev
, pbuf
);
2038 if (wd
->zfcbRecv80211
!= NULL
)
2040 //seq_no = zmw_rx_buf_readh(dev, pbuf, offset+22) >> 4;
2041 //DbgPrint("Recv indicate seq=%d\n", seq_no);
2042 //DbgPrint("1. seq=%d\n", seq_no);
2043 wd
->zfcbRecv80211(dev
, pbuf
, addInfo
);
2047 //seq_no = zmw_rx_buf_readh(dev, pbuf, offset+22) >> 4;
2048 //DbgPrint("Recv indicate seq=%d\n", seq_no);
2049 zfiRecv80211(dev
, pbuf
, addInfo
);
2056 struct agg_tid_rx
*zfAggRxGetQueue(zdev_t
* dev
, zbuf_t
* buf
)
2061 struct agg_tid_rx
*tid_rx
= NULL
;
2063 zmw_get_wlan_dev(dev
);
2065 //zmw_declare_for_critical_section();
2067 src
[0] = zmw_rx_buf_readh(dev
, buf
, offset
+10);
2068 src
[1] = zmw_rx_buf_readh(dev
, buf
, offset
+12);
2069 src
[2] = zmw_rx_buf_readh(dev
, buf
, offset
+14);
2070 aid
= zfApFindSta(dev
, src
);
2072 ac
= (zmw_rx_buf_readh(dev
, buf
, 24) & 0xF);
2074 // mark by spin lock debug
2075 //zmw_enter_critical_section(dev);
2077 for (i
=0; i
<ZM_AGG_POOL_SIZE
; i
++)
2079 if((wd
->tid_rx
[i
]->aid
== aid
) && (wd
->tid_rx
[i
]->ac
== ac
))
2081 tid_rx
= wd
->tid_rx
[i
];
2086 // mark by spin lock debug
2087 //zmw_leave_critical_section(dev);
2092 u16_t
zfAggRxEnqueue(zdev_t
* dev
, zbuf_t
* buf
, struct agg_tid_rx
*tid_rx
, struct zsAdditionInfo
*addInfo
)
2094 u16_t seq_no
, offset
= 0;
2097 u8_t bdropframe
= 0;
2099 zmw_get_wlan_dev(dev
);
2101 zmw_declare_for_critical_section();
2103 ZM_BUFFER_TRACE(dev
, buf
)
2105 seq_no
= zmw_rx_buf_readh(dev
, buf
, offset
+22) >> 4;
2106 index
= seq_no
- tid_rx
->seq_start
;
2109 * sequence number wrap at 4k
2110 * -1000: check for duplicate past packet
2113 if (tid_rx
->seq_start
> seq_no
) {
2114 if ((tid_rx
->seq_start
> 3967) && (seq_no
< 128)) {
2116 } else if (tid_rx
->seq_start
- seq_no
> 70) {
2117 zmw_enter_critical_section(dev
);
2118 tid_rx
->sq_behind_count
++;
2119 if (tid_rx
->sq_behind_count
> 3) {
2120 tid_rx
->sq_behind_count
= 0;
2124 zmw_leave_critical_section(dev
);
2129 if (seq_no
- tid_rx
->seq_start
> 70) {
2130 zmw_enter_critical_section(dev
);
2131 tid_rx
->sq_exceed_count
++;
2132 if (tid_rx
->sq_exceed_count
> 3) {
2133 tid_rx
->sq_exceed_count
= 0;
2137 zmw_leave_critical_section(dev
);
2141 if (bdropframe
== 1) {
2142 /*if (wd->zfcbRecv80211 != NULL) {
2143 wd->zfcbRecv80211(dev, buf, addInfo);
2146 zfiRecv80211(dev, buf, addInfo);
2149 ZM_PERFORMANCE_FREE(dev
, buf
);
2151 zfwBufFree(dev
, buf
, 0);
2152 /*zfAggRxFlush(dev, seq_no, tid_rx);
2153 tid_rx->seq_start = seq_no;
2154 index = seq_no - tid_rx->seq_start;
2157 //DbgPrint("Free an old packet, seq_start=%d, seq_no=%d\n", tid_rx->seq_start, seq_no);
2160 * duplicate past packet
2161 * happens only in simulated aggregation environment
2165 zmw_enter_critical_section(dev
);
2166 if (tid_rx
->sq_exceed_count
> 0){
2167 tid_rx
->sq_exceed_count
--;
2170 if (tid_rx
->sq_behind_count
> 0) {
2171 tid_rx
->sq_behind_count
--;
2173 zmw_leave_critical_section(dev
);
2177 zfAggRxFlush(dev
, seq_no
, tid_rx
);
2178 tid_rx
->seq_start
= seq_no
;
2182 //if (index >= (ZM_AGG_BAW_SIZE - 1))
2183 if (index
>= (ZM_AGG_BAW_MASK
))
2188 //DbgPrint("index >= 64, seq_start=%d, seq_no=%d\n", tid_rx->seq_start, seq_no);
2189 zfAggRxFlush(dev
, seq_no
, tid_rx
);
2190 //tid_rx->seq_start = seq_no;
2191 index
= seq_no
- tid_rx
->seq_start
;
2192 if ((tid_rx
->seq_start
> seq_no
) && (tid_rx
->seq_start
> 1000) && (tid_rx
->seq_start
- 1000) > seq_no
)
2194 //index = seq_no - tid_rx->seq_start;
2197 //index = seq_no - tid_rx->seq_start;
2198 while (index
>= (ZM_AGG_BAW_MASK
)) {
2199 //DbgPrint("index >= 64, seq_start=%d, seq_no=%d\n", tid_rx->seq_start, seq_no);
2200 tid_rx
->seq_start
= (tid_rx
->seq_start
+ ZM_AGG_BAW_MASK
) & (4096 - 1);
2201 index
= seq_no
- tid_rx
->seq_start
;
2202 if ((tid_rx
->seq_start
> seq_no
) && (tid_rx
->seq_start
> 1000) && (tid_rx
->seq_start
- 1000) > seq_no
)
2210 q_index
= (tid_rx
->baw_tail
+ index
) & ZM_AGG_BAW_MASK
;
2211 if (tid_rx
->frame
[q_index
].buf
&& (((tid_rx
->baw_head
- tid_rx
->baw_tail
) & ZM_AGG_BAW_MASK
) >
2212 (((q_index
) - tid_rx
->baw_tail
) & ZM_AGG_BAW_MASK
)))
2215 ZM_PERFORMANCE_DUP(dev
, tid_rx
->frame
[q_index
].buf
, buf
);
2216 zfwBufFree(dev
, buf
, 0);
2217 //DbgPrint("Free a duplicate packet, seq_start=%d, seq_no=%d\n", tid_rx->seq_start, seq_no);
2218 //DbgPrint("head=%d, tail=%d", tid_rx->baw_head, tid_rx->baw_tail);
2225 zmw_enter_critical_section(dev
);
2226 if(tid_rx
->frame
[q_index
].buf
) {
2227 zfwBufFree(dev
, tid_rx
->frame
[q_index
].buf
, 0);
2228 tid_rx
->frame
[q_index
].buf
= 0;
2231 tid_rx
->frame
[q_index
].buf
= buf
;
2232 tid_rx
->frame
[q_index
].arrivalTime
= zm_agg_GetTime();
2233 zfwMemoryCopy((void*)&tid_rx
->frame
[q_index
].addInfo
, (void*)addInfo
, sizeof(struct zsAdditionInfo
));
2236 * for debug simulated aggregation only,
2237 * should be done in rx of ADDBA Request
2239 //tid_rx->addInfo = addInfo;
2242 if (((tid_rx
->baw_head
- tid_rx
->baw_tail
) & ZM_AGG_BAW_MASK
) <= index
)
2244 //tid_rx->baw_size = index + 1;
2245 if (((tid_rx
->baw_head
- tid_rx
->baw_tail
) & ZM_AGG_BAW_MASK
) <=
2246 //((q_index + 1) & ZM_AGG_BAW_MASK))
2247 (((q_index
) - tid_rx
->baw_tail
) & ZM_AGG_BAW_MASK
))//tid_rx->baw_size )
2248 tid_rx
->baw_head
= (q_index
+ 1) & ZM_AGG_BAW_MASK
;
2250 zmw_leave_critical_section(dev
);
2255 //DbgPrint("head=%d, tail=%d, start=%d", tid_rx->baw_head, tid_rx->baw_tail, tid_rx->seq_start);
2259 u16_t
zfAggRxFlush(zdev_t
* dev
, u16_t seq_no
, struct agg_tid_rx
*tid_rx
)
2263 struct zsAdditionInfo addInfo
;
2264 zmw_get_wlan_dev(dev
);
2265 zmw_declare_for_critical_section();
2267 ZM_PERFORMANCE_RX_FLUSH(dev
);
2271 zmw_enter_critical_section(dev
);
2272 if (tid_rx
->baw_tail
== tid_rx
->baw_head
) {
2273 zmw_leave_critical_section(dev
);
2277 pbuf
= tid_rx
->frame
[tid_rx
->baw_tail
].buf
;
2278 zfwMemoryCopy((void*)&addInfo
, (void*)&tid_rx
->frame
[tid_rx
->baw_tail
].addInfo
, sizeof(struct zsAdditionInfo
));
2279 tid_rx
->frame
[tid_rx
->baw_tail
].buf
= 0;
2280 //if(pbuf && tid_rx->baw_size > 0) tid_rx->baw_size--;
2281 tid_rx
->baw_tail
= (tid_rx
->baw_tail
+ 1) & ZM_AGG_BAW_MASK
;
2282 tid_rx
->seq_start
= (tid_rx
->seq_start
+ 1) & (4096 - 1);
2283 zmw_leave_critical_section(dev
);
2288 ZM_PERFORMANCE_RX_SEQ(dev
, pbuf
);
2290 if (wd
->zfcbRecv80211
!= NULL
)
2292 seq
= zmw_rx_buf_readh(dev
, pbuf
, 22) >> 4;
2293 //DbgPrint("Recv indicate seq=%d\n", seq);
2294 //DbgPrint("2. seq=%d\n", seq);
2295 wd
->zfcbRecv80211(dev
, pbuf
, &addInfo
);
2299 seq
= zmw_rx_buf_readh(dev
, pbuf
, 22) >> 4;
2300 //DbgPrint("Recv indicate seq=%d\n", seq);
2301 zfiRecv80211(dev
, pbuf
, &addInfo
);
2306 zmw_enter_critical_section(dev
);
2307 tid_rx
->baw_head
= tid_rx
->baw_tail
= 0;
2308 zmw_leave_critical_section(dev
);
2314 /************************************************************************/
2316 /* FUNCTION DESCRIPTION zfAggRxFreeBuf */
2317 /* Frees all queued packets in buffer when the driver is down. */
2318 /* The zfFreeResource() will check if the buffer is all freed. */
2321 /* dev : device pointer */
2327 /* Honda Atheros Communications, INC. 2006.12 */
2329 /************************************************************************/
2330 u16_t
zfAggRxFreeBuf(zdev_t
* dev
, u16_t destroy
)
2334 struct agg_tid_rx
*tid_rx
;
2337 //struct bufInfo *buf_info;
2339 zmw_get_wlan_dev(dev
);
2340 zmw_declare_for_critical_section();
2342 for (i
=0; i
<ZM_AGG_POOL_SIZE
; i
++)
2346 tid_rx
= wd
->tid_rx
[i
];
2348 for(j
=0; j
<= ZM_AGG_BAW_SIZE
; j
++)
2350 zmw_enter_critical_section(dev
);
2351 buf
= tid_rx
->frame
[j
].buf
;
2352 tid_rx
->frame
[j
].buf
= 0;
2353 zmw_leave_critical_section(dev
);
2357 zfwBufFree(dev
, buf
, 0);
2362 if ( tid_rx
->baw_head
!= tid_rx
->baw_tail
)
2364 while (tid_rx
->baw_head
!= tid_rx
->baw_tail
)
2366 buf
= tid_rx
->frame
[tid_rx
->baw_tail
].buf
;
2367 tid_rx
->frame
[tid_rx
->baw_tail
].buf
= 0;
2370 zfwBufFree(dev
, buf
, 0);
2372 zmw_enter_critical_section(dev
);
2373 tid_rx
->frame
[tid_rx
->baw_tail
].buf
= 0;
2374 zmw_leave_critical_section(dev
);
2376 zmw_enter_critical_section(dev
);
2377 //if (tid_rx->baw_size > 0)tid_rx->baw_size--;
2378 tid_rx
->baw_tail
= (tid_rx
->baw_tail
+ 1) & ZM_AGG_BAW_MASK
;
2379 tid_rx
->seq_start
++;
2380 zmw_leave_critical_section(dev
);
2385 zmw_enter_critical_section(dev
);
2386 tid_rx
->seq_start
= 0;
2387 tid_rx
->baw_head
= tid_rx
->baw_tail
= 0;
2388 tid_rx
->aid
= ZM_MAX_STA_SUPPORT
;
2389 zmw_leave_critical_section(dev
);
2391 #ifdef ZM_ENABLE_AGGREGATION
2392 #ifndef ZM_ENABLE_FW_BA_RETRANSMISSION //disable BAW
2393 if (tid_baw
->enabled
) {
2394 zm_msg1_agg(ZM_LV_0
, "Device down, clear BAW queue:", i
);
2395 BAW
->disable(dev
, tid_baw
);
2399 if (1 == wd
->aggQPool
[i
]->aggQEnabled
) {
2400 tid_tx
= wd
->aggQPool
[i
];
2401 buf
= zfAggTxGetVtxq(dev
, tid_tx
);
2403 zfwBufFree(dev
, buf
, 0);
2404 buf
= zfAggTxGetVtxq(dev
, tid_tx
);
2409 zfwMemFree(dev
, wd
->aggQPool
[i
], sizeof(struct aggQueue
));
2410 zfwMemFree(dev
, wd
->tid_rx
[i
], sizeof(struct agg_tid_rx
));
2413 #ifdef ZM_ENABLE_AGGREGATION
2414 #ifndef ZM_ENABLE_FW_BA_RETRANSMISSION //disable BAW
2415 if(destroy
) zfwMemFree(dev
, BAW
, sizeof(struct baw_enabler
));
2422 void zfAggRecvBAR(zdev_t
* dev
, zbuf_t
*buf
) {
2423 u16_t start_seq
, len
;
2425 len
= zfwBufGetSize(dev
, buf
);
2426 start_seq
= zmw_rx_buf_readh(dev
, buf
, len
-2);
2427 DbgPrint("Received a BAR Control frame, start_seq=%d", start_seq
>>4);
2428 /* todo: set the bitmap by reordering buffer! */
2429 for (i
=0; i
<8; i
++) bitmap
[i
]=0;
2430 zfSendBA(dev
, start_seq
, bitmap
);
2433 #ifdef ZM_ENABLE_AGGREGATION
2434 #ifndef ZM_ENABLE_FW_BA_RETRANSMISSION //disable BAW
2435 void zfAggTxRetransmit(zdev_t
* dev
, struct bufInfo
*buf_info
, struct aggControl
*aggControl
, TID_TX tid_tx
) {
2439 zmw_get_wlan_dev(dev
);
2440 if (aggControl
&& (ZM_AGG_FIRST_MPDU
== aggControl
->ampduIndication
) ) {
2441 tid_tx
->bar_ssn
= buf_info
->baw_header
->header
[15];
2442 aggControl
->tid_baw
->start_seq
= tid_tx
->bar_ssn
>> 4;
2443 zm_msg1_agg(ZM_LV_0
, "start seq=", tid_tx
->bar_ssn
>> 4);
2445 buf_info
->baw_header
->header
[4] |= (1 << 11);
2446 if (aggControl
&& aggControl
->aggEnabled
) {
2447 //if (wd->enableAggregation==0 && !(buf_info->baw_header->header[6]&0x1))
2449 //if (((buf_info->baw_header->header[2] & 0x3) == 2))
2451 /* Enable aggregation */
2452 buf_info
->baw_header
->header
[1] |= 0x20;
2453 if (ZM_AGG_LAST_MPDU
== aggControl
->ampduIndication
) {
2454 buf_info
->baw_header
->header
[1] |= 0x4000;
2457 buf_info
->baw_header
->header
[1] &= ~0x4000;
2458 //zm_debug_msg0("ZM_AGG_LAST_MPDU");
2462 // zm_debug_msg1("no aggr, header[2]&0x3 = ",buf_info->baw_header->header[2] & 0x3)
2463 // aggControl->aggEnabled = 0;
2467 // zm_debug_msg1("no aggr, wd->enableAggregation = ", wd->enableAggregation);
2468 // zm_debug_msg1("no aggr, !header[6]&0x1 = ",!(buf_info->baw_header->header[6]&0x1));
2469 // aggControl->aggEnabled = 0;
2473 /*if (aggControl->tid_baw) {
2474 struct baw_header_r header_r;
2476 header_r.header = buf_info->baw_header->header;
2477 header_r.mic = buf_info->baw_header->mic;
2478 header_r.snap = buf_info->baw_header->snap;
2479 header_r.headerLen = buf_info->baw_header->headerLen;
2480 header_r.micLen = buf_info->baw_header->micLen;
2481 header_r.snapLen = buf_info->baw_header->snapLen;
2482 header_r.removeLen = buf_info->baw_header->removeLen;
2483 header_r.keyIdx = buf_info->baw_header->keyIdx;
2485 BAW->insert(dev, buf_info->buf, tid_tx->bar_ssn >> 4, aggControl->tid_baw, buf_info->baw_retransmit, &header_r);
2489 buf_info
->baw_header
->header
,
2490 buf_info
->baw_header
->headerLen
,
2491 buf_info
->baw_header
->snap
,
2492 buf_info
->baw_header
->snapLen
,
2493 buf_info
->baw_header
->mic
,
2494 buf_info
->baw_header
->micLen
,
2496 buf_info
->baw_header
->removeLen
,
2497 ZM_EXTERNAL_ALLOC_BUF
,
2499 buf_info
->baw_header
->keyIdx
);
2500 if (err
!= ZM_SUCCESS
)
2508 zfwBufFree(dev
, buf_info
->buf
, 0);
2512 #endif //disable BAW
2514 /************************************************************************/
2516 /* FUNCTION DESCRIPTION zfAggTxSendEth */
2517 /* Called to transmit Ethernet frame from upper elayer. */
2520 /* dev : device pointer */
2521 /* buf : buffer pointer */
2522 /* port : WLAN port, 0=>standard, 0x10-0x17=>VAP, 0x20-0x25=>WDS */
2528 /* Stephen, Honda Atheros Communications, Inc. 2006.12 */
2530 /************************************************************************/
2531 u16_t
zfAggTxSendEth(zdev_t
* dev
, zbuf_t
* buf
, u16_t port
, u16_t bufType
, u8_t flag
, struct aggControl
*aggControl
, TID_TX tid_tx
)
2534 //u16_t addrTblSize;
2535 //struct zsAddrTbl addrTbl;
2537 u16_t header
[(8+30+2+18)/2]; /* ctr+(4+a1+a2+a3+2+a4)+qos+iv */
2551 u8_t qosType
, keyIdx
= 0;
2554 zmw_get_wlan_dev(dev
);
2556 zmw_declare_for_critical_section();
2558 zm_msg1_tx(ZM_LV_2
, "zfTxSendEth(), port=", port
);
2560 /* Get IP TOS for QoS AC and IP frag offset */
2561 zfTxGetIpTosAndFrag(dev
, buf
, &up
, &fragOff
);
2563 #ifdef ZM_ENABLE_NATIVE_WIFI
2564 if ( wd
->wlanMode
== ZM_MODE_INFRASTRUCTURE
)
2567 da
[0] = zmw_tx_buf_readh(dev
, buf
, 16);
2568 da
[1] = zmw_tx_buf_readh(dev
, buf
, 18);
2569 da
[2] = zmw_tx_buf_readh(dev
, buf
, 20);
2571 sa
[0] = zmw_tx_buf_readh(dev
, buf
, 10);
2572 sa
[1] = zmw_tx_buf_readh(dev
, buf
, 12);
2573 sa
[2] = zmw_tx_buf_readh(dev
, buf
, 14);
2575 else if ( wd
->wlanMode
== ZM_MODE_IBSS
)
2578 da
[0] = zmw_tx_buf_readh(dev
, buf
, 4);
2579 da
[1] = zmw_tx_buf_readh(dev
, buf
, 6);
2580 da
[2] = zmw_tx_buf_readh(dev
, buf
, 8);
2582 sa
[0] = zmw_tx_buf_readh(dev
, buf
, 10);
2583 sa
[1] = zmw_tx_buf_readh(dev
, buf
, 12);
2584 sa
[2] = zmw_tx_buf_readh(dev
, buf
, 14);
2586 else if ( wd
->wlanMode
== ZM_MODE_AP
)
2589 da
[0] = zmw_tx_buf_readh(dev
, buf
, 4);
2590 da
[1] = zmw_tx_buf_readh(dev
, buf
, 6);
2591 da
[2] = zmw_tx_buf_readh(dev
, buf
, 8);
2593 sa
[0] = zmw_tx_buf_readh(dev
, buf
, 16);
2594 sa
[1] = zmw_tx_buf_readh(dev
, buf
, 18);
2595 sa
[2] = zmw_tx_buf_readh(dev
, buf
, 20);
2603 da
[0] = zmw_tx_buf_readh(dev
, buf
, 0);
2604 da
[1] = zmw_tx_buf_readh(dev
, buf
, 2);
2605 da
[2] = zmw_tx_buf_readh(dev
, buf
, 4);
2607 sa
[0] = zmw_tx_buf_readh(dev
, buf
, 6);
2608 sa
[1] = zmw_tx_buf_readh(dev
, buf
, 8);
2609 sa
[2] = zmw_tx_buf_readh(dev
, buf
, 10);
2611 //Decide Key Index in ATOM, No meaning in OTUS--CWYang(m)
2612 if (wd
->wlanMode
== ZM_MODE_AP
)
2614 keyIdx
= wd
->ap
.bcHalKeyIdx
[port
];
2615 id
= zfApFindSta(dev
, da
);
2618 switch (wd
->ap
.staTable
[id
].encryMode
)
2622 #ifdef ZM_ENABLE_CENC
2624 #endif //ZM_ENABLE_CENC
2625 keyIdx
= wd
->ap
.staTable
[id
].keyIdx
;
2632 switch (wd
->sta
.encryMode
)
2637 keyIdx
= wd
->sta
.keyId
;
2646 #ifdef ZM_ENABLE_CENC
2648 keyIdx
= wd
->sta
.cencKeyId
;
2650 #endif //ZM_ENABLE_CENC
2655 removeLen
= zfTxGenWlanSnap(dev
, buf
, snap
, &snapLen
);
2656 //zm_msg1_tx(ZM_LV_0, "fragOff=", fragOff);
2658 fragLen
= wd
->fragThreshold
;
2659 frameLen
= zfwBufGetSize(dev
, buf
);
2660 frameLen
-= removeLen
;
2664 if ( (wd
->wlanMode
== ZM_MODE_INFRASTRUCTURE
)&&
2665 (wd
->sta
.encryMode
== ZM_TKIP
) )
2667 if ( frameLen
> fragLen
)
2669 micLen
= zfTxGenWlanTail(dev
, buf
, snap
, snapLen
, mic
);
2673 /* append MIC by HMAC */
2682 if ( frameLen
> fragLen
)
2684 micLen
= zfTxGenWlanTail(dev
, buf
, snap
, snapLen
, mic
);
2688 /* append MIC by HMAC */
2693 /* Access Category */
2694 if (wd
->wlanMode
== ZM_MODE_AP
)
2696 zfApGetStaQosType(dev
, da
, &qosType
);
2702 else if (wd
->wlanMode
== ZM_MODE_INFRASTRUCTURE
)
2704 if (wd
->sta
.wmeConnected
== 0)
2711 /* TODO : STA QoS control field */
2715 /* Assign sequence number */
2716 zmw_enter_critical_section(dev
);
2717 frag
.seq
[0] = ((wd
->seq
[zcUpToAc
[up
&0x7]]++) << 4);
2718 if (aggControl
&& (ZM_AGG_FIRST_MPDU
== aggControl
->ampduIndication
) ) {
2719 tid_tx
->bar_ssn
= frag
.seq
[0];
2721 zm_msg1_agg(ZM_LV_0
, "start seq=", tid_tx
->bar_ssn
>> 4);
2723 //tid_tx->baw_buf[tid_tx->baw_head-1].baw_seq=frag.seq[0];
2724 zmw_leave_critical_section(dev
);
2728 frag
.bufType
[0] = bufType
;
2729 frag
.flag
[0] = flag
;
2732 for (i
=0; i
<fragNum
; i
++)
2734 /* Create WLAN header(Control Setting + 802.11 header + IV) */
2735 if (up
!=0 ) zm_debug_msg1("up not 0, up=",up
);
2736 headerLen
= zfTxGenWlanHeader(dev
, frag
.buf
[i
], header
, frag
.seq
[i
],
2737 frag
.flag
[i
], snapLen
+micLen
, removeLen
,
2738 port
, da
, sa
, up
, &micLen
, snap
, snapLen
,
2741 /* Get buffer DMA address */
2742 //if ((addrTblSize = zfwBufMapDma(dev, frag.buf[i], &addrTbl)) == 0)
2743 //if ((addrTblSize = zfwMapTxDma(dev, frag.buf[i], &addrTbl)) == 0)
2745 // err = ZM_ERR_BUFFER_DMA_ADDR;
2749 /* Flush buffer on cache */
2750 //zfwBufFlush(dev, frag.buf[i]);
2753 zm_msg1_tx(ZM_LV_0
, "headerLen=", headerLen
);
2754 zm_msg1_tx(ZM_LV_0
, "snapLen=", snapLen
);
2755 zm_msg1_tx(ZM_LV_0
, "micLen=", micLen
);
2756 zm_msg1_tx(ZM_LV_0
, "removeLen=", removeLen
);
2757 zm_msg1_tx(ZM_LV_0
, "addrTblSize=", addrTblSize
);
2758 zm_msg1_tx(ZM_LV_0
, "frag.bufType[0]=", frag
.bufType
[0]);
2761 fragLen
= zfwBufGetSize(dev
, frag
.buf
[i
]);
2762 if ((da
[0]&0x1) == 0)
2764 wd
->commTally
.txUnicastFrm
++;
2765 wd
->commTally
.txUnicastOctets
+= (fragLen
+snapLen
);
2767 else if ((da
[0]& 0x1))
2769 wd
->commTally
.txBroadcastFrm
++;
2770 wd
->commTally
.txBroadcastOctets
+= (fragLen
+snapLen
);
2774 wd
->commTally
.txMulticastFrm
++;
2775 wd
->commTally
.txMulticastOctets
+= (fragLen
+snapLen
);
2777 wd
->ledStruct
.txTraffic
++;
2779 #if 0 //Who care this?
2780 if ( (i
)&&(i
== (fragNum
-1)) )
2782 wd
->trafTally
.txDataByteCount
-= micLen
;
2786 /*if (aggControl->tid_baw && aggControl->aggEnabled) {
2787 struct baw_header_r header_r;
2789 header_r.header = header;
2791 header_r.snap = snap;
2792 header_r.headerLen = headerLen;
2793 header_r.micLen = micLen;
2794 header_r.snapLen = snapLen;
2795 header_r.removeLen = removeLen;
2796 header_r.keyIdx = keyIdx;
2798 BAW->insert(dev, buf, tid_tx->bar_ssn >> 4, aggControl->tid_baw, 0, &header_r);
2801 err
= zfHpSend(dev
, header
, headerLen
, snap
, snapLen
,
2802 mic
, micLen
, frag
.buf
[i
], removeLen
,
2803 frag
.bufType
[i
], zcUpToAc
[up
&0x7], keyIdx
);
2804 if (err
!= ZM_SUCCESS
)
2813 if (frag
.bufType
[i
] == ZM_EXTERNAL_ALLOC_BUF
)
2815 zfwBufFree(dev
, frag
.buf
[i
], err
);
2817 else if (frag
.bufType
[i
] == ZM_INTERNAL_ALLOC_BUF
)
2819 zfwBufFree(dev
, frag
.buf
[i
], 0);
2825 } /* for (i=0; i<fragNum; i++) */
2831 * zfAggSendADDBA() refers zfSendMmFrame() in cmm.c
2833 u16_t
zfAggSendAddbaRequest(zdev_t
* dev
, u16_t
*dst
, u16_t ac
, u16_t up
)
2836 //u16_t addrTblSize;
2837 //struct zsAddrTbl addrTbl;
2841 u16_t header
[(24+25+1)/2];
2846 //zmw_get_wlan_dev(dev);
2848 //zmw_declare_for_critical_section();
2852 * TBD : Maximum size of management frame
2854 buf
= zfwBufAllocate(dev
, 1024);
2857 zm_msg0_mm(ZM_LV_0
, "Alloc mm buf Fail!");
2862 * Reserve room for wlan header
2867 * add addba frame body
2869 offset
= zfAggSetAddbaFrameBody(dev
, buf
, offset
, ac
, up
);
2872 zfwBufSetSize(dev
, buf
, offset
);
2877 zfAggGenAddbaHeader(dev
, dst
, header
, offset
-hlen
, buf
, vap
, encrypt
);
2878 for (i
=0; i
<(hlen
>>1); i
++)
2880 zmw_tx_buf_writeh(dev
, buf
, i
*2, header
[i
]);
2883 /* Get buffer DMA address */
2884 //if ((addrTblSize = zfwBufMapDma(dev, buf, &addrTbl)) == 0)
2885 //if ((addrTblSize = zfwMapTxDma(dev, buf, &addrTbl)) == 0)
2890 //zm_msg2_mm(ZM_LV_2, "offset=", offset);
2891 //zm_msg2_mm(ZM_LV_2, "hlen=", hlen);
2892 //zm_msg2_mm(ZM_LV_2, "addrTblSize=", addrTblSize);
2893 //zm_msg2_mm(ZM_LV_2, "addrTbl.len[0]=", addrTbl.len[0]);
2894 //zm_msg2_mm(ZM_LV_2, "addrTbl.physAddrl[0]=", addrTbl.physAddrl[0]);
2895 //zm_msg2_mm(ZM_LV_2, "buf->data=", buf->data);
2898 err
= zfHpSend(dev
, NULL
, 0, NULL
, 0, NULL
, 0, buf
, 0,
2899 ZM_INTERNAL_ALLOC_BUF
, 0, 0xff);
2900 if (err
!= ZM_SUCCESS
)
2905 zfPutVmmq(dev
, buf
);
2913 u16_t
zfAggSetAddbaFrameBody(zdev_t
* dev
, zbuf_t
* buf
, u16_t offset
, u16_t ac
, u16_t up
)
2915 u16_t ba_parameter
, start_seq
;
2917 zmw_get_wlan_dev(dev
);
2919 //zmw_declare_for_critical_section();
2921 * ADDBA Request frame body
2927 zmw_tx_buf_writeb(dev
, buf
, offset
++, 3);
2929 * Action details = 0
2931 zmw_tx_buf_writeb(dev
, buf
, offset
++, ZM_WLAN_ADDBA_REQUEST_FRAME
);
2933 * Dialog Token = nonzero
2934 * TBD: define how to get dialog token?
2936 zmw_tx_buf_writeb(dev
, buf
, offset
++, 2);
2938 * Block Ack parameter set
2939 * BA policy = 1 for immediate BA, 0 for delayed BA
2940 * TID(4bits) & buffer size(4bits) (TID=up & buffer size=0x80)
2941 * TBD: how to get buffer size?
2942 * ¢z¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢s¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢s¢w¢w¢w¢w¢w¢w¢w¢w¢s¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢{
2943 * ¢x B0 ¢x B1 ¢x B2 B5 ¢x B6 B15 ¢x
2944 * ¢u¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢q¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢q¢w¢w¢w¢w¢w¢w¢w¢w¢q¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢t
2945 * ¢x Reserved ¢x BA policy ¢x TID ¢x Buffer size ¢x
2946 * ¢|¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢r¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢r¢w¢w¢w¢w¢w¢w¢w¢w¢r¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢}
2948 ba_parameter
= 1 << 12; // buffer size = 0x40(64)
2949 ba_parameter
|= up
<< 2; // tid = up
2950 ba_parameter
|= 2; // ba policy = 1
2951 zmw_tx_buf_writeh(dev
, buf
, offset
, ba_parameter
);
2956 zmw_tx_buf_writeh(dev
, buf
, offset
, 0);
2959 * BA starting sequence number
2960 * ¢z¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢s¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢{
2961 * ¢x B0 B3 ¢x B4 B15 ¢x
2962 * ¢u¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢q¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢t
2963 * ¢x Frag num(0) ¢x BA starting seq num ¢x
2964 * ¢|¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢r¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢}
2966 start_seq
= ((wd
->seq
[ac
]) << 4) & 0xFFF0;
2967 zmw_tx_buf_writeh(dev
, buf
, offset
, start_seq
);
2973 u16_t
zfAggGenAddbaHeader(zdev_t
* dev
, u16_t
* dst
,
2974 u16_t
* header
, u16_t len
, zbuf_t
* buf
, u16_t vap
, u8_t encrypt
)
2976 u8_t hlen
= 32; // MAC ctrl + PHY ctrl + 802.11 MM header
2977 //u8_t frameType = ZM_WLAN_FRAME_TYPE_ACTION;
2979 zmw_get_wlan_dev(dev
);
2981 zmw_declare_for_critical_section();
2984 * Generate control setting
2986 //bodyLen = zfwBufGetSize(dev, buf);
2987 header
[0] = 24+len
+4; //Length
2988 header
[1] = 0x8; //MAC control, backoff + (ack)
2992 header
[2] = 0x0f00; //PHY control L
2993 header
[3] = 0x0000; //PHY control H
2996 header
[2] = 0x0f01; //PHY control L
2997 header
[3] = 0x000B; //PHY control H
3001 * Generate WLAN header
3002 * Frame control frame type and subtype
3004 header
[4+0] = ZM_WLAN_FRAME_TYPE_ACTION
;
3010 if (wd
->wlanMode
== ZM_MODE_INFRASTRUCTURE
)
3012 header
[4+8] = wd
->sta
.bssid
[0];
3013 header
[4+9] = wd
->sta
.bssid
[1];
3014 header
[4+10] = wd
->sta
.bssid
[2];
3016 else if (wd
->wlanMode
== ZM_MODE_PSEUDO
)
3018 /* Address 3 = 00:00:00:00:00:00 */
3023 else if (wd
->wlanMode
== ZM_MODE_IBSS
)
3025 header
[4+8] = wd
->sta
.bssid
[0];
3026 header
[4+9] = wd
->sta
.bssid
[1];
3027 header
[4+10] = wd
->sta
.bssid
[2];
3029 else if (wd
->wlanMode
== ZM_MODE_AP
)
3031 /* Address 3 = BSSID */
3032 header
[4+8] = wd
->macAddr
[0];
3033 header
[4+9] = wd
->macAddr
[1];
3034 header
[4+10] = wd
->macAddr
[2] + (vap
<<8);
3037 /* Address 1 = DA */
3038 header
[4+2] = dst
[0];
3039 header
[4+3] = dst
[1];
3040 header
[4+4] = dst
[2];
3042 /* Address 2 = SA */
3043 header
[4+5] = wd
->macAddr
[0];
3044 header
[4+6] = wd
->macAddr
[1];
3045 if (wd
->wlanMode
== ZM_MODE_AP
)
3047 header
[4+7] = wd
->macAddr
[2] + (vap
<<8);
3051 header
[4+7] = wd
->macAddr
[2];
3054 /* Sequence Control */
3055 zmw_enter_critical_section(dev
);
3056 header
[4+11] = ((wd
->mmseq
++)<<4);
3057 zmw_leave_critical_section(dev
);
3064 u16_t
zfAggProcessAction(zdev_t
* dev
, zbuf_t
* buf
)
3068 //zmw_get_wlan_dev(dev);
3070 //zmw_declare_for_critical_section();
3072 category
= zmw_rx_buf_readb(dev
, buf
, 24);
3076 case ZM_WLAN_BLOCK_ACK_ACTION_FRAME
:
3077 zfAggBlockAckActionFrame(dev
, buf
);
3086 u16_t
zfAggBlockAckActionFrame(zdev_t
* dev
, zbuf_t
* buf
)
3090 //zmw_get_wlan_dev(dev);
3092 //zmw_declare_for_critical_section();
3094 action
= zmw_rx_buf_readb(dev
, buf
, 25);
3095 #ifdef ZM_ENABLE_AGGREGATION
3098 case ZM_WLAN_ADDBA_REQUEST_FRAME
:
3099 zm_msg0_agg(ZM_LV_0
, "Received BA Action frame is ADDBA request");
3100 zfAggRecvAddbaRequest(dev
, buf
);
3102 case ZM_WLAN_ADDBA_RESPONSE_FRAME
:
3103 zm_msg0_agg(ZM_LV_0
, "Received BA Action frame is ADDBA response");
3104 zfAggRecvAddbaResponse(dev
, buf
);
3106 case ZM_WLAN_DELBA_FRAME
:
3107 zfAggRecvDelba(dev
, buf
);
3114 u16_t
zfAggRecvAddbaRequest(zdev_t
* dev
, zbuf_t
* buf
)
3117 struct aggBaFrameParameter bf
;
3119 //zmw_get_wlan_dev(dev);
3121 //zmw_declare_for_critical_section();
3124 bf
.dialog
= zmw_rx_buf_readb(dev
, buf
, 26);
3128 bf
.ba_parameter
= zmw_rx_buf_readh(dev
, buf
, 27);
3129 bf
.ba_policy
= (bf
.ba_parameter
>> 1) & 1;
3130 bf
.tid
= (bf
.ba_parameter
>> 2) & 0xF;
3131 bf
.buffer_size
= (bf
.ba_parameter
>> 6);
3135 bf
.ba_timeout
= zmw_rx_buf_readh(dev
, buf
, 29);
3137 * BA starting sequence number
3139 bf
.ba_start_seq
= zmw_rx_buf_readh(dev
, buf
, 31) >> 4;
3143 zm_debug_msg2("Recv ADDBA Req:", zmw_rx_buf_readb(dev
,buf
,i
));
3147 zfAggSendAddbaResponse(dev
, &bf
);
3149 zfAggAddbaSetTidRx(dev
, buf
, &bf
);
3154 u16_t
zfAggAddbaSetTidRx(zdev_t
* dev
, zbuf_t
* buf
, struct aggBaFrameParameter
*bf
)
3156 u16_t i
, ac
, aid
, fragOff
;
3160 struct agg_tid_rx
*tid_rx
= NULL
;
3162 zmw_get_wlan_dev(dev
);
3164 zmw_declare_for_critical_section();
3166 src
[0] = zmw_rx_buf_readh(dev
, buf
, offset
+10);
3167 src
[1] = zmw_rx_buf_readh(dev
, buf
, offset
+12);
3168 src
[2] = zmw_rx_buf_readh(dev
, buf
, offset
+14);
3169 aid
= zfApFindSta(dev
, src
);
3171 zfTxGetIpTosAndFrag(dev
, buf
, &up
, &fragOff
);
3172 ac
= zcUpToAc
[up
&0x7] & 0x3;
3176 for (i
=0; i
<ZM_AGG_POOL_SIZE
; i
++)
3178 if((wd
->tid_rx
[i
]->aid
== aid
) && (wd
->tid_rx
[i
]->ac
== ac
))
3180 tid_rx
= wd
->tid_rx
[i
];
3187 for (i
=0; i
<ZM_AGG_POOL_SIZE
; i
++)
3189 if (wd
->tid_rx
[i
]->aid
== ZM_MAX_STA_SUPPORT
)
3191 tid_rx
= wd
->tid_rx
[i
];
3199 zmw_enter_critical_section(dev
);
3203 tid_rx
->addBaExchangeStatusCode
= ZM_AGG_ADDBA_RESPONSE
;
3204 tid_rx
->seq_start
= bf
->ba_start_seq
;
3205 tid_rx
->baw_head
= tid_rx
->baw_tail
= 0;
3206 tid_rx
->sq_exceed_count
= tid_rx
->sq_behind_count
= 0;
3207 zmw_leave_critical_section(dev
);
3212 u16_t
zfAggRecvAddbaResponse(zdev_t
* dev
, zbuf_t
* buf
)
3216 struct aggBaFrameParameter bf
;
3218 zmw_get_wlan_dev(dev
);
3220 //zmw_declare_for_critical_section();
3222 src
[0] = zmw_rx_buf_readh(dev
, buf
, 10);
3223 src
[1] = zmw_rx_buf_readh(dev
, buf
, 12);
3224 src
[2] = zmw_rx_buf_readh(dev
, buf
, 14);
3226 if (wd
->wlanMode
== ZM_MODE_AP
)
3227 aid
= zfApFindSta(dev
, src
);
3231 bf
.dialog
= zmw_rx_buf_readb(dev
, buf
, 26);
3232 bf
.status_code
= zmw_rx_buf_readh(dev
, buf
, 27);
3233 if (!bf
.status_code
)
3235 wd
->addbaComplete
=1;
3241 bf
.ba_parameter
= zmw_rx_buf_readh(dev
, buf
, 29);
3242 bf
.ba_policy
= (bf
.ba_parameter
>> 1) & 1;
3243 bf
.tid
= (bf
.ba_parameter
>> 2) & 0xF;
3244 bf
.buffer_size
= (bf
.ba_parameter
>> 6);
3248 bf
.ba_timeout
= zmw_rx_buf_readh(dev
, buf
, 31);
3252 zm_debug_msg2("Recv ADDBA Rsp:", zmw_rx_buf_readb(dev
,buf
,i
));
3256 ac
= zcUpToAc
[bf
.tid
&0x7] & 0x3;
3258 //zmw_enter_critical_section(dev);
3260 //wd->aggSta[aid].aggFlag[ac] = 0;
3262 //zmw_leave_critical_section(dev);
3267 u16_t
zfAggRecvDelba(zdev_t
* dev
, zbuf_t
* buf
)
3269 //zmw_get_wlan_dev(dev);
3271 //zmw_declare_for_critical_section();
3275 u16_t
zfAggSendAddbaResponse(zdev_t
* dev
, struct aggBaFrameParameter
*bf
)
3278 //u16_t addrTblSize;
3279 //struct zsAddrTbl addrTbl;
3283 u16_t header
[(24+25+1)/2];
3289 //zmw_get_wlan_dev(dev);
3291 //zmw_declare_for_critical_section();
3295 * TBD : Maximum size of management frame
3297 buf
= zfwBufAllocate(dev
, 1024);
3300 zm_msg0_mm(ZM_LV_0
, "Alloc mm buf Fail!");
3305 * Reserve room for wlan header
3310 * add addba frame body
3312 offset
= zfAggSetAddbaResponseFrameBody(dev
, buf
, bf
, offset
);
3315 zfwBufSetSize(dev
, buf
, offset
);
3321 dst
[0] = zmw_rx_buf_readh(dev
, bf
->buf
, 10);
3322 dst
[1] = zmw_rx_buf_readh(dev
, bf
->buf
, 12);
3323 dst
[2] = zmw_rx_buf_readh(dev
, bf
->buf
, 14);
3324 zfAggGenAddbaHeader(dev
, dst
, header
, offset
-hlen
, buf
, vap
, encrypt
);
3325 for (i
=0; i
<(hlen
>>1); i
++)
3327 zmw_tx_buf_writeh(dev
, buf
, i
*2, header
[i
]);
3330 /* Get buffer DMA address */
3331 //if ((addrTblSize = zfwBufMapDma(dev, buf, &addrTbl)) == 0)
3332 //if ((addrTblSize = zfwMapTxDma(dev, buf, &addrTbl)) == 0)
3337 //zm_msg2_mm(ZM_LV_2, "offset=", offset);
3338 //zm_msg2_mm(ZM_LV_2, "hlen=", hlen);
3339 //zm_msg2_mm(ZM_LV_2, "addrTblSize=", addrTblSize);
3340 //zm_msg2_mm(ZM_LV_2, "addrTbl.len[0]=", addrTbl.len[0]);
3341 //zm_msg2_mm(ZM_LV_2, "addrTbl.physAddrl[0]=", addrTbl.physAddrl[0]);
3342 //zm_msg2_mm(ZM_LV_2, "buf->data=", buf->data);
3345 err
= zfHpSend(dev
, NULL
, 0, NULL
, 0, NULL
, 0, buf
, 0,
3346 ZM_INTERNAL_ALLOC_BUF
, 0, 0xff);
3347 if (err
!= ZM_SUCCESS
)
3352 zfPutVmmq(dev
, buf
);
3356 //zfAggSendAddbaRequest(dev, dst, zcUpToAc[bf->tid&0x7] & 0x3, bf->tid);
3361 u16_t
zfAggSetAddbaResponseFrameBody(zdev_t
* dev
, zbuf_t
* buf
,
3362 struct aggBaFrameParameter
*bf
, u16_t offset
)
3365 //zmw_get_wlan_dev(dev);
3367 //zmw_declare_for_critical_section();
3369 * ADDBA Request frame body
3375 zmw_tx_buf_writeb(dev
, buf
, offset
++, 3);
3377 * Action details = 0
3379 zmw_tx_buf_writeb(dev
, buf
, offset
++, ZM_WLAN_ADDBA_RESPONSE_FRAME
);
3381 * Dialog Token = nonzero
3383 zmw_tx_buf_writeb(dev
, buf
, offset
++, bf
->dialog
);
3387 zmw_tx_buf_writeh(dev
, buf
, offset
, 0);
3390 * Block Ack parameter set
3391 * BA policy = 1 for immediate BA, 0 for delayed BA
3392 * TID(4bits) & buffer size(4bits) (TID=0x1 & buffer size=0x80)
3393 * TBD: how to get TID number and buffer size?
3394 * ¢z¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢s¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢s¢w¢w¢w¢w¢w¢w¢w¢w¢s¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢{
3395 * ¢x B0 ¢x B1 ¢x B2 B5 ¢x B6 B15 ¢x
3396 * ¢u¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢q¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢q¢w¢w¢w¢w¢w¢w¢w¢w¢q¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢t
3397 * ¢x Reserved ¢x BA policy ¢x TID ¢x Buffer size ¢x
3398 * ¢|¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢r¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢r¢w¢w¢w¢w¢w¢w¢w¢w¢r¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢}
3400 zmw_tx_buf_writeh(dev
, buf
, offset
, bf
->ba_parameter
);
3405 zmw_tx_buf_writeh(dev
, buf
, offset
, bf
->ba_timeout
);
3411 void zfAggInvokeBar(zdev_t
* dev
, TID_TX tid_tx
)
3413 struct aggBarControl aggBarControl
;
3414 //zmw_get_wlan_dev(dev);
3416 //zmw_declare_for_critical_section();
3417 //bar_control = aggBarControl->tid_info << 12 | aggBarControl->compressed_bitmap << 2
3418 // | aggBarControl->multi_tid << 1 | aggBarControl->bar_ack_policy;
3419 aggBarControl
.bar_ack_policy
= 0;
3420 aggBarControl
.multi_tid
= 0;
3421 aggBarControl
.compressed_bitmap
= 0;
3422 aggBarControl
.tid_info
= tid_tx
->tid
;
3423 zfAggSendBar(dev
, tid_tx
, &aggBarControl
);
3429 * zfAggSendBar() refers zfAggSendAddbaRequest()
3431 u16_t
zfAggSendBar(zdev_t
* dev
, TID_TX tid_tx
, struct aggBarControl
*aggBarControl
)
3434 //u16_t addrTblSize;
3435 //struct zsAddrTbl addrTbl;
3438 u16_t hlen
= 16+8; /* mac header + control headers*/
3439 u16_t header
[(8+24+1)/2];
3444 //zmw_get_wlan_dev(dev);
3446 //zmw_declare_for_critical_section();
3450 * TBD : Maximum size of management frame
3452 buf
= zfwBufAllocate(dev
, 1024);
3455 zm_msg0_mm(ZM_LV_0
, "Alloc mm buf Fail!");
3460 * Reserve room for wlan header
3465 * add addba frame body
3467 offset
= zfAggSetBarBody(dev
, buf
, offset
, tid_tx
, aggBarControl
);
3470 zfwBufSetSize(dev
, buf
, offset
);
3475 zfAggGenBarHeader(dev
, tid_tx
->dst
, header
, offset
-hlen
, buf
, vap
, encrypt
);
3476 for (i
=0; i
<(hlen
>>1); i
++)
3478 zmw_tx_buf_writeh(dev
, buf
, i
*2, header
[i
]);
3481 /* Get buffer DMA address */
3482 //if ((addrTblSize = zfwBufMapDma(dev, buf, &addrTbl)) == 0)
3483 //if ((addrTblSize = zfwMapTxDma(dev, buf, &addrTbl)) == 0)
3488 //zm_msg2_mm(ZM_LV_2, "offset=", offset);
3489 //zm_msg2_mm(ZM_LV_2, "hlen=", hlen);
3490 //zm_msg2_mm(ZM_LV_2, "addrTblSize=", addrTblSize);
3491 //zm_msg2_mm(ZM_LV_2, "addrTbl.len[0]=", addrTbl.len[0]);
3492 //zm_msg2_mm(ZM_LV_2, "addrTbl.physAddrl[0]=", addrTbl.physAddrl[0]);
3493 //zm_msg2_mm(ZM_LV_2, "buf->data=", buf->data);
3496 err
= zfHpSend(dev
, NULL
, 0, NULL
, 0, NULL
, 0, buf
, 0,
3497 ZM_INTERNAL_ALLOC_BUF
, 0, 0xff);
3498 if (err
!= ZM_SUCCESS
)
3503 zfPutVmmq(dev
, buf
);
3511 u16_t
zfAggSetBarBody(zdev_t
* dev
, zbuf_t
* buf
, u16_t offset
, TID_TX tid_tx
, struct aggBarControl
*aggBarControl
)
3513 u16_t bar_control
, start_seq
;
3515 //zmw_get_wlan_dev(dev);
3517 //zmw_declare_for_critical_section();
3519 * BAR Control frame body
3524 * ¢z¢w¢w¢w¢w¢w¢w¢w¢w¢w¢s¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢s¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢s¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢s¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢{
3525 * ¢x B0 ¢x B1 ¢x B2 ¢x B3 B11 ¢x B12 B15 ¢x
3526 * ¢u¢w¢w¢w¢w¢w¢w¢w¢w¢w¢q¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢q¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢q¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢q¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢t
3527 * ¢x BAR Ack ¢x Multi-TID ¢x Compressed ¢x Reserved ¢x TID_INFO ¢x
3528 * ¢x Policy ¢x ¢x Bitmap ¢x ¢x ¢x
3529 * ¢|¢w¢w¢w¢w¢w¢w¢w¢w¢w¢r¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢r¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢r¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢r¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢}
3531 bar_control
= aggBarControl
->tid_info
<< 12 | aggBarControl
->compressed_bitmap
<< 2
3532 | aggBarControl
->multi_tid
<< 1 | aggBarControl
->bar_ack_policy
;
3534 zmw_tx_buf_writeh(dev
, buf
, offset
, bar_control
);
3536 if (0 == aggBarControl
->multi_tid
) {
3538 * BA starting sequence number
3539 * ¢z¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢s¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢{
3540 * ¢x B0 B3 ¢x B4 B15 ¢x
3541 * ¢u¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢q¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢t
3542 * ¢x Frag num(0) ¢x BA starting seq num ¢x
3543 * ¢|¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢r¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢}
3545 start_seq
= (tid_tx
->bar_ssn
<< 4) & 0xFFF0;
3546 zmw_tx_buf_writeh(dev
, buf
, offset
, start_seq
);
3549 if (1 == aggBarControl
->multi_tid
&& 1 == aggBarControl
->compressed_bitmap
) {
3550 /* multi-tid BlockAckReq variant, not implemented*/
3556 u16_t
zfAggGenBarHeader(zdev_t
* dev
, u16_t
* dst
,
3557 u16_t
* header
, u16_t len
, zbuf_t
* buf
, u16_t vap
, u8_t encrypt
)
3559 u8_t hlen
= 16+8; // MAC ctrl + PHY ctrl + 802.11 MM header
3560 //u8_t frameType = ZM_WLAN_FRAME_TYPE_ACTION;
3562 zmw_get_wlan_dev(dev
);
3564 zmw_declare_for_critical_section();
3567 * Generate control setting
3569 //bodyLen = zfwBufGetSize(dev, buf);
3570 header
[0] = 16+len
+4; //Length
3571 header
[1] = 0x8; //MAC control, backoff + (ack)
3575 header
[2] = 0x0f00; //PHY control L
3576 header
[3] = 0x0000; //PHY control H
3579 header
[2] = 0x0f01; //PHY control L
3580 header
[3] = 0x000B; //PHY control H
3584 * Generate WLAN header
3585 * Frame control frame type and subtype
3587 header
[4+0] = ZM_WLAN_FRAME_TYPE_BAR
;
3593 /* Address 1 = DA */
3594 header
[4+2] = dst
[0];
3595 header
[4+3] = dst
[1];
3596 header
[4+4] = dst
[2];
3598 /* Address 2 = SA */
3599 header
[4+5] = wd
->macAddr
[0];
3600 header
[4+6] = wd
->macAddr
[1];
3601 if (wd
->wlanMode
== ZM_MODE_AP
)
3603 #ifdef ZM_VAPMODE_MULTILE_SSID
3604 header
[4+7] = wd
->macAddr
[2]; //Multiple SSID
3606 header
[4+7] = wd
->macAddr
[2] + (vap
<<8); //VAP
3611 header
[4+7] = wd
->macAddr
[2];
3614 /* Sequence Control */
3615 zmw_enter_critical_section(dev
);
3616 header
[4+11] = ((wd
->mmseq
++)<<4);
3617 zmw_leave_critical_section(dev
);