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);
2488 if ((err = zfHpSend(dev,
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)) != ZM_SUCCESS)
2507 zfwBufFree(dev, buf_info->buf, 0);
2511 #endif //disable BAW
2513 /************************************************************************/
2515 /* FUNCTION DESCRIPTION zfAggTxSendEth */
2516 /* Called to transmit Ethernet frame from upper elayer. */
2519 /* dev : device pointer */
2520 /* buf : buffer pointer */
2521 /* port : WLAN port, 0=>standard, 0x10-0x17=>VAP, 0x20-0x25=>WDS */
2527 /* Stephen, Honda Atheros Communications, Inc. 2006.12 */
2529 /************************************************************************/
2530 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)
2533 //u16_t addrTblSize;
2534 //struct zsAddrTbl addrTbl;
2536 u16_t header[(8+30+2+18)/2]; /* ctr+(4+a1+a2+a3+2+a4)+qos+iv */
2550 u8_t qosType, keyIdx = 0;
2553 zmw_get_wlan_dev(dev);
2555 zmw_declare_for_critical_section();
2557 zm_msg1_tx(ZM_LV_2, "zfTxSendEth(), port=", port);
2559 /* Get IP TOS for QoS AC and IP frag offset */
2560 zfTxGetIpTosAndFrag(dev, buf, &up, &fragOff);
2562 #ifdef ZM_ENABLE_NATIVE_WIFI
2563 if ( wd->wlanMode == ZM_MODE_INFRASTRUCTURE )
2566 da[0] = zmw_tx_buf_readh(dev, buf, 16);
2567 da[1] = zmw_tx_buf_readh(dev, buf, 18);
2568 da[2] = zmw_tx_buf_readh(dev, buf, 20);
2570 sa[0] = zmw_tx_buf_readh(dev, buf, 10);
2571 sa[1] = zmw_tx_buf_readh(dev, buf, 12);
2572 sa[2] = zmw_tx_buf_readh(dev, buf, 14);
2574 else if ( wd->wlanMode == ZM_MODE_IBSS )
2577 da[0] = zmw_tx_buf_readh(dev, buf, 4);
2578 da[1] = zmw_tx_buf_readh(dev, buf, 6);
2579 da[2] = zmw_tx_buf_readh(dev, buf, 8);
2581 sa[0] = zmw_tx_buf_readh(dev, buf, 10);
2582 sa[1] = zmw_tx_buf_readh(dev, buf, 12);
2583 sa[2] = zmw_tx_buf_readh(dev, buf, 14);
2585 else if ( wd->wlanMode == ZM_MODE_AP )
2588 da[0] = zmw_tx_buf_readh(dev, buf, 4);
2589 da[1] = zmw_tx_buf_readh(dev, buf, 6);
2590 da[2] = zmw_tx_buf_readh(dev, buf, 8);
2592 sa[0] = zmw_tx_buf_readh(dev, buf, 16);
2593 sa[1] = zmw_tx_buf_readh(dev, buf, 18);
2594 sa[2] = zmw_tx_buf_readh(dev, buf, 20);
2602 da[0] = zmw_tx_buf_readh(dev, buf, 0);
2603 da[1] = zmw_tx_buf_readh(dev, buf, 2);
2604 da[2] = zmw_tx_buf_readh(dev, buf, 4);
2606 sa[0] = zmw_tx_buf_readh(dev, buf, 6);
2607 sa[1] = zmw_tx_buf_readh(dev, buf, 8);
2608 sa[2] = zmw_tx_buf_readh(dev, buf, 10);
2610 //Decide Key Index in ATOM, No meaning in OTUS--CWYang(m)
2611 if (wd->wlanMode == ZM_MODE_AP)
2613 keyIdx = wd->ap.bcHalKeyIdx[port];
2614 id = zfApFindSta(dev, da);
2617 switch (wd->ap.staTable[id].encryMode)
2621 #ifdef ZM_ENABLE_CENC
2623 #endif //ZM_ENABLE_CENC
2624 keyIdx = wd->ap.staTable[id].keyIdx;
2631 switch (wd->sta.encryMode)
2636 keyIdx = wd->sta.keyId;
2645 #ifdef ZM_ENABLE_CENC
2647 keyIdx = wd->sta.cencKeyId;
2649 #endif //ZM_ENABLE_CENC
2654 removeLen = zfTxGenWlanSnap(dev, buf, snap, &snapLen);
2655 //zm_msg1_tx(ZM_LV_0, "fragOff=", fragOff);
2657 fragLen = wd->fragThreshold;
2658 frameLen = zfwBufGetSize(dev, buf);
2659 frameLen -= removeLen;
2663 if ( (wd->wlanMode == ZM_MODE_INFRASTRUCTURE)&&
2664 (wd->sta.encryMode == ZM_TKIP) )
2666 if ( frameLen > fragLen )
2668 micLen = zfTxGenWlanTail(dev, buf, snap, snapLen, mic);
2672 /* append MIC by HMAC */
2681 if ( frameLen > fragLen )
2683 micLen = zfTxGenWlanTail(dev, buf, snap, snapLen, mic);
2687 /* append MIC by HMAC */
2692 /* Access Category */
2693 if (wd->wlanMode == ZM_MODE_AP)
2695 zfApGetStaQosType(dev, da, &qosType);
2701 else if (wd->wlanMode == ZM_MODE_INFRASTRUCTURE)
2703 if (wd->sta.wmeConnected == 0)
2710 /* TODO : STA QoS control field */
2714 /* Assign sequence number */
2715 zmw_enter_critical_section(dev);
2716 frag.seq[0] = ((wd->seq[zcUpToAc[up&0x7]]++) << 4);
2717 if (aggControl && (ZM_AGG_FIRST_MPDU == aggControl->ampduIndication) ) {
2718 tid_tx->bar_ssn = frag.seq[0];
2720 zm_msg1_agg(ZM_LV_0, "start seq=", tid_tx->bar_ssn >> 4);
2722 //tid_tx->baw_buf[tid_tx->baw_head-1].baw_seq=frag.seq[0];
2723 zmw_leave_critical_section(dev);
2727 frag.bufType[0] = bufType;
2728 frag.flag[0] = flag;
2731 for (i=0; i<fragNum; i++)
2733 /* Create WLAN header(Control Setting + 802.11 header + IV) */
2734 if (up !=0 ) zm_debug_msg1("up not 0, up=",up);
2735 headerLen = zfTxGenWlanHeader(dev, frag.buf[i], header, frag.seq[i],
2736 frag.flag[i], snapLen+micLen, removeLen,
2737 port, da, sa, up, &micLen, snap, snapLen,
2740 /* Get buffer DMA address */
2741 //if ((addrTblSize = zfwBufMapDma(dev, frag.buf[i], &addrTbl)) == 0)
2742 //if ((addrTblSize = zfwMapTxDma(dev, frag.buf[i], &addrTbl)) == 0)
2744 // err = ZM_ERR_BUFFER_DMA_ADDR;
2748 /* Flush buffer on cache */
2749 //zfwBufFlush(dev, frag.buf[i]);
2752 zm_msg1_tx(ZM_LV_0, "headerLen=", headerLen);
2753 zm_msg1_tx(ZM_LV_0, "snapLen=", snapLen);
2754 zm_msg1_tx(ZM_LV_0, "micLen=", micLen);
2755 zm_msg1_tx(ZM_LV_0, "removeLen=", removeLen);
2756 zm_msg1_tx(ZM_LV_0, "addrTblSize=", addrTblSize);
2757 zm_msg1_tx(ZM_LV_0, "frag.bufType[0]=", frag.bufType[0]);
2760 fragLen = zfwBufGetSize(dev, frag.buf[i]);
2761 if ((da[0]&0x1) == 0)
2763 wd->commTally.txUnicastFrm++;
2764 wd->commTally.txUnicastOctets += (fragLen+snapLen);
2766 else if ((da[0]& 0x1))
2768 wd->commTally.txBroadcastFrm++;
2769 wd->commTally.txBroadcastOctets += (fragLen+snapLen);
2773 wd->commTally.txMulticastFrm++;
2774 wd->commTally.txMulticastOctets += (fragLen+snapLen);
2776 wd->ledStruct.txTraffic++;
2778 #if 0 //Who care this?
2779 if ( (i)&&(i == (fragNum-1)) )
2781 wd->trafTally.txDataByteCount -= micLen;
2785 /*if (aggControl->tid_baw && aggControl->aggEnabled) {
2786 struct baw_header_r header_r;
2788 header_r.header = header;
2790 header_r.snap = snap;
2791 header_r.headerLen = headerLen;
2792 header_r.micLen = micLen;
2793 header_r.snapLen = snapLen;
2794 header_r.removeLen = removeLen;
2795 header_r.keyIdx = keyIdx;
2797 BAW->insert(dev, buf, tid_tx->bar_ssn >> 4, aggControl->tid_baw, 0, &header_r);
2800 if ((err = zfHpSend(dev, header, headerLen, snap, snapLen,
2801 mic, micLen, frag.buf[i], removeLen,
2802 frag.bufType[i], zcUpToAc[up&0x7], keyIdx)) != ZM_SUCCESS)
2811 if (frag.bufType[i] == ZM_EXTERNAL_ALLOC_BUF)
2813 zfwBufFree(dev, frag.buf[i], err);
2815 else if (frag.bufType[i] == ZM_INTERNAL_ALLOC_BUF)
2817 zfwBufFree(dev, frag.buf[i], 0);
2823 } /* for (i=0; i<fragNum; i++) */
2829 * zfAggSendADDBA() refers zfSendMmFrame() in cmm.c
2831 u16_t zfAggSendAddbaRequest(zdev_t* dev, u16_t *dst, u16_t ac, u16_t up)
2834 //u16_t addrTblSize;
2835 //struct zsAddrTbl addrTbl;
2839 u16_t header[(24+25+1)/2];
2844 //zmw_get_wlan_dev(dev);
2846 //zmw_declare_for_critical_section();
2850 * TBD : Maximum size of management frame
2852 if ((buf = zfwBufAllocate(dev, 1024)) == NULL)
2854 zm_msg0_mm(ZM_LV_0, "Alloc mm buf Fail!");
2859 * Reserve room for wlan header
2864 * add addba frame body
2866 offset = zfAggSetAddbaFrameBody(dev, buf, offset, ac, up);
2869 zfwBufSetSize(dev, buf, offset);
2874 zfAggGenAddbaHeader(dev, dst, header, offset-hlen, buf, vap, encrypt);
2875 for (i=0; i<(hlen>>1); i++)
2877 zmw_tx_buf_writeh(dev, buf, i*2, header[i]);
2880 /* Get buffer DMA address */
2881 //if ((addrTblSize = zfwBufMapDma(dev, buf, &addrTbl)) == 0)
2882 //if ((addrTblSize = zfwMapTxDma(dev, buf, &addrTbl)) == 0)
2887 //zm_msg2_mm(ZM_LV_2, "offset=", offset);
2888 //zm_msg2_mm(ZM_LV_2, "hlen=", hlen);
2889 //zm_msg2_mm(ZM_LV_2, "addrTblSize=", addrTblSize);
2890 //zm_msg2_mm(ZM_LV_2, "addrTbl.len[0]=", addrTbl.len[0]);
2891 //zm_msg2_mm(ZM_LV_2, "addrTbl.physAddrl[0]=", addrTbl.physAddrl[0]);
2892 //zm_msg2_mm(ZM_LV_2, "buf->data=", buf->data);
2895 if ((err = zfHpSend(dev, NULL, 0, NULL, 0, NULL, 0, buf, 0,
2896 ZM_INTERNAL_ALLOC_BUF, 0, 0xff)) != ZM_SUCCESS)
2901 zfPutVmmq(dev, buf);
2909 u16_t zfAggSetAddbaFrameBody(zdev_t* dev, zbuf_t* buf, u16_t offset, u16_t ac, u16_t up)
2911 u16_t ba_parameter, start_seq;
2913 zmw_get_wlan_dev(dev);
2915 //zmw_declare_for_critical_section();
2917 * ADDBA Request frame body
2923 zmw_tx_buf_writeb(dev, buf, offset++, 3);
2925 * Action details = 0
2927 zmw_tx_buf_writeb(dev, buf, offset++, ZM_WLAN_ADDBA_REQUEST_FRAME);
2929 * Dialog Token = nonzero
2930 * TBD: define how to get dialog token?
2932 zmw_tx_buf_writeb(dev, buf, offset++, 2);
2934 * Block Ack parameter set
2935 * BA policy = 1 for immediate BA, 0 for delayed BA
2936 * TID(4bits) & buffer size(4bits) (TID=up & buffer size=0x80)
2937 * TBD: how to get buffer size?
2938 * ¢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¢{
2939 * ¢x B0 ¢x B1 ¢x B2 B5 ¢x B6 B15 ¢x
2940 * ¢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
2941 * ¢x Reserved ¢x BA policy ¢x TID ¢x Buffer size ¢x
2942 * ¢|¢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¢}
2944 ba_parameter = 1 << 12; // buffer size = 0x40(64)
2945 ba_parameter |= up << 2; // tid = up
2946 ba_parameter |= 2; // ba policy = 1
2947 zmw_tx_buf_writeh(dev, buf, offset, ba_parameter);
2952 zmw_tx_buf_writeh(dev, buf, offset, 0);
2955 * BA starting sequence number
2956 * ¢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¢{
2957 * ¢x B0 B3 ¢x B4 B15 ¢x
2958 * ¢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
2959 * ¢x Frag num(0) ¢x BA starting seq num ¢x
2960 * ¢|¢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¢}
2962 start_seq = ((wd->seq[ac]) << 4) & 0xFFF0;
2963 zmw_tx_buf_writeh(dev, buf, offset, start_seq);
2969 u16_t zfAggGenAddbaHeader(zdev_t* dev, u16_t* dst,
2970 u16_t* header, u16_t len, zbuf_t* buf, u16_t vap, u8_t encrypt)
2972 u8_t hlen = 32; // MAC ctrl + PHY ctrl + 802.11 MM header
2973 //u8_t frameType = ZM_WLAN_FRAME_TYPE_ACTION;
2975 zmw_get_wlan_dev(dev);
2977 zmw_declare_for_critical_section();
2980 * Generate control setting
2982 //bodyLen = zfwBufGetSize(dev, buf);
2983 header[0] = 24+len+4; //Length
2984 header[1] = 0x8; //MAC control, backoff + (ack)
2988 header[2] = 0x0f00; //PHY control L
2989 header[3] = 0x0000; //PHY control H
2992 header[2] = 0x0f01; //PHY control L
2993 header[3] = 0x000B; //PHY control H
2997 * Generate WLAN header
2998 * Frame control frame type and subtype
3000 header[4+0] = ZM_WLAN_FRAME_TYPE_ACTION;
3006 if (wd->wlanMode == ZM_MODE_INFRASTRUCTURE)
3008 header[4+8] = wd->sta.bssid[0];
3009 header[4+9] = wd->sta.bssid[1];
3010 header[4+10] = wd->sta.bssid[2];
3012 else if (wd->wlanMode == ZM_MODE_PSEUDO)
3014 /* Address 3 = 00:00:00:00:00:00 */
3019 else if (wd->wlanMode == ZM_MODE_IBSS)
3021 header[4+8] = wd->sta.bssid[0];
3022 header[4+9] = wd->sta.bssid[1];
3023 header[4+10] = wd->sta.bssid[2];
3025 else if (wd->wlanMode == ZM_MODE_AP)
3027 /* Address 3 = BSSID */
3028 header[4+8] = wd->macAddr[0];
3029 header[4+9] = wd->macAddr[1];
3030 header[4+10] = wd->macAddr[2] + (vap<<8);
3033 /* Address 1 = DA */
3034 header[4+2] = dst[0];
3035 header[4+3] = dst[1];
3036 header[4+4] = dst[2];
3038 /* Address 2 = SA */
3039 header[4+5] = wd->macAddr[0];
3040 header[4+6] = wd->macAddr[1];
3041 if (wd->wlanMode == ZM_MODE_AP)
3043 header[4+7] = wd->macAddr[2] + (vap<<8);
3047 header[4+7] = wd->macAddr[2];
3050 /* Sequence Control */
3051 zmw_enter_critical_section(dev);
3052 header[4+11] = ((wd->mmseq++)<<4);
3053 zmw_leave_critical_section(dev);
3060 u16_t zfAggProcessAction(zdev_t* dev, zbuf_t* buf)
3064 //zmw_get_wlan_dev(dev);
3066 //zmw_declare_for_critical_section();
3068 category = zmw_rx_buf_readb(dev, buf, 24);
3072 case ZM_WLAN_BLOCK_ACK_ACTION_FRAME:
3073 zfAggBlockAckActionFrame(dev, buf);
3082 u16_t zfAggBlockAckActionFrame(zdev_t* dev, zbuf_t* buf)
3086 //zmw_get_wlan_dev(dev);
3088 //zmw_declare_for_critical_section();
3090 action = zmw_rx_buf_readb(dev, buf, 25);
3091 #ifdef ZM_ENABLE_AGGREGATION
3094 case ZM_WLAN_ADDBA_REQUEST_FRAME:
3095 zm_msg0_agg(ZM_LV_0, "Received BA Action frame is ADDBA request");
3096 zfAggRecvAddbaRequest(dev, buf);
3098 case ZM_WLAN_ADDBA_RESPONSE_FRAME:
3099 zm_msg0_agg(ZM_LV_0, "Received BA Action frame is ADDBA response");
3100 zfAggRecvAddbaResponse(dev, buf);
3102 case ZM_WLAN_DELBA_FRAME:
3103 zfAggRecvDelba(dev, buf);
3110 u16_t zfAggRecvAddbaRequest(zdev_t* dev, zbuf_t* buf)
3113 struct aggBaFrameParameter bf;
3115 //zmw_get_wlan_dev(dev);
3117 //zmw_declare_for_critical_section();
3120 bf.dialog = zmw_rx_buf_readb(dev, buf, 26);
3124 bf.ba_parameter = zmw_rx_buf_readh(dev, buf, 27);
3125 bf.ba_policy = (bf.ba_parameter >> 1) & 1;
3126 bf.tid = (bf.ba_parameter >> 2) & 0xF;
3127 bf.buffer_size = (bf.ba_parameter >> 6);
3131 bf.ba_timeout = zmw_rx_buf_readh(dev, buf, 29);
3133 * BA starting sequence number
3135 bf.ba_start_seq = zmw_rx_buf_readh(dev, buf, 31) >> 4;
3139 zm_debug_msg2("Recv ADDBA Req:", zmw_rx_buf_readb(dev,buf,i));
3143 zfAggSendAddbaResponse(dev, &bf);
3145 zfAggAddbaSetTidRx(dev, buf, &bf);
3150 u16_t zfAggAddbaSetTidRx(zdev_t* dev, zbuf_t* buf, struct aggBaFrameParameter *bf)
3152 u16_t i, ac, aid, fragOff;
3156 struct agg_tid_rx *tid_rx = NULL;
3158 zmw_get_wlan_dev(dev);
3160 zmw_declare_for_critical_section();
3162 src[0] = zmw_rx_buf_readh(dev, buf, offset+10);
3163 src[1] = zmw_rx_buf_readh(dev, buf, offset+12);
3164 src[2] = zmw_rx_buf_readh(dev, buf, offset+14);
3165 aid = zfApFindSta(dev, src);
3167 zfTxGetIpTosAndFrag(dev, buf, &up, &fragOff);
3168 ac = zcUpToAc[up&0x7] & 0x3;
3172 for (i=0; i<ZM_AGG_POOL_SIZE ; i++)
3174 if((wd->tid_rx[i]->aid == aid) && (wd->tid_rx[i]->ac == ac))
3176 tid_rx = wd->tid_rx[i];
3183 for (i=0; i<ZM_AGG_POOL_SIZE; i++)
3185 if (wd->tid_rx[i]->aid == ZM_MAX_STA_SUPPORT)
3187 tid_rx = wd->tid_rx[i];
3195 zmw_enter_critical_section(dev);
3199 tid_rx->addBaExchangeStatusCode = ZM_AGG_ADDBA_RESPONSE;
3200 tid_rx->seq_start = bf->ba_start_seq;
3201 tid_rx->baw_head = tid_rx->baw_tail = 0;
3202 tid_rx->sq_exceed_count = tid_rx->sq_behind_count = 0;
3203 zmw_leave_critical_section(dev);
3208 u16_t zfAggRecvAddbaResponse(zdev_t* dev, zbuf_t* buf)
3212 struct aggBaFrameParameter bf;
3214 zmw_get_wlan_dev(dev);
3216 //zmw_declare_for_critical_section();
3218 src[0] = zmw_rx_buf_readh(dev, buf, 10);
3219 src[1] = zmw_rx_buf_readh(dev, buf, 12);
3220 src[2] = zmw_rx_buf_readh(dev, buf, 14);
3222 if (wd->wlanMode == ZM_MODE_AP)
3223 aid = zfApFindSta(dev, src);
3227 bf.dialog = zmw_rx_buf_readb(dev, buf, 26);
3228 bf.status_code = zmw_rx_buf_readh(dev, buf, 27);
3229 if (!bf.status_code)
3231 wd->addbaComplete=1;
3237 bf.ba_parameter = zmw_rx_buf_readh(dev, buf, 29);
3238 bf.ba_policy = (bf.ba_parameter >> 1) & 1;
3239 bf.tid = (bf.ba_parameter >> 2) & 0xF;
3240 bf.buffer_size = (bf.ba_parameter >> 6);
3244 bf.ba_timeout = zmw_rx_buf_readh(dev, buf, 31);
3248 zm_debug_msg2("Recv ADDBA Rsp:", zmw_rx_buf_readb(dev,buf,i));
3252 ac = zcUpToAc[bf.tid&0x7] & 0x3;
3254 //zmw_enter_critical_section(dev);
3256 //wd->aggSta[aid].aggFlag[ac] = 0;
3258 //zmw_leave_critical_section(dev);
3263 u16_t zfAggRecvDelba(zdev_t* dev, zbuf_t* buf)
3265 //zmw_get_wlan_dev(dev);
3267 //zmw_declare_for_critical_section();
3271 u16_t zfAggSendAddbaResponse(zdev_t* dev, struct aggBaFrameParameter *bf)
3274 //u16_t addrTblSize;
3275 //struct zsAddrTbl addrTbl;
3279 u16_t header[(24+25+1)/2];
3285 //zmw_get_wlan_dev(dev);
3287 //zmw_declare_for_critical_section();
3291 * TBD : Maximum size of management frame
3293 if ((buf = zfwBufAllocate(dev, 1024)) == NULL)
3295 zm_msg0_mm(ZM_LV_0, "Alloc mm buf Fail!");
3300 * Reserve room for wlan header
3305 * add addba frame body
3307 offset = zfAggSetAddbaResponseFrameBody(dev, buf, bf, offset);
3310 zfwBufSetSize(dev, buf, offset);
3316 dst[0] = zmw_rx_buf_readh(dev, bf->buf, 10);
3317 dst[1] = zmw_rx_buf_readh(dev, bf->buf, 12);
3318 dst[2] = zmw_rx_buf_readh(dev, bf->buf, 14);
3319 zfAggGenAddbaHeader(dev, dst, header, offset-hlen, buf, vap, encrypt);
3320 for (i=0; i<(hlen>>1); i++)
3322 zmw_tx_buf_writeh(dev, buf, i*2, header[i]);
3325 /* Get buffer DMA address */
3326 //if ((addrTblSize = zfwBufMapDma(dev, buf, &addrTbl)) == 0)
3327 //if ((addrTblSize = zfwMapTxDma(dev, buf, &addrTbl)) == 0)
3332 //zm_msg2_mm(ZM_LV_2, "offset=", offset);
3333 //zm_msg2_mm(ZM_LV_2, "hlen=", hlen);
3334 //zm_msg2_mm(ZM_LV_2, "addrTblSize=", addrTblSize);
3335 //zm_msg2_mm(ZM_LV_2, "addrTbl.len[0]=", addrTbl.len[0]);
3336 //zm_msg2_mm(ZM_LV_2, "addrTbl.physAddrl[0]=", addrTbl.physAddrl[0]);
3337 //zm_msg2_mm(ZM_LV_2, "buf->data=", buf->data);
3340 if ((err = zfHpSend(dev, NULL, 0, NULL, 0, NULL, 0, buf, 0,
3341 ZM_INTERNAL_ALLOC_BUF, 0, 0xff)) != ZM_SUCCESS)
3346 zfPutVmmq(dev, buf);
3350 //zfAggSendAddbaRequest(dev, dst, zcUpToAc[bf->tid&0x7] & 0x3, bf->tid);
3355 u16_t zfAggSetAddbaResponseFrameBody(zdev_t* dev, zbuf_t* buf,
3356 struct aggBaFrameParameter *bf, u16_t offset)
3359 //zmw_get_wlan_dev(dev);
3361 //zmw_declare_for_critical_section();
3363 * ADDBA Request frame body
3369 zmw_tx_buf_writeb(dev, buf, offset++, 3);
3371 * Action details = 0
3373 zmw_tx_buf_writeb(dev, buf, offset++, ZM_WLAN_ADDBA_RESPONSE_FRAME);
3375 * Dialog Token = nonzero
3377 zmw_tx_buf_writeb(dev, buf, offset++, bf->dialog);
3381 zmw_tx_buf_writeh(dev, buf, offset, 0);
3384 * Block Ack parameter set
3385 * BA policy = 1 for immediate BA, 0 for delayed BA
3386 * TID(4bits) & buffer size(4bits) (TID=0x1 & buffer size=0x80)
3387 * TBD: how to get TID number and buffer size?
3388 * ¢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¢{
3389 * ¢x B0 ¢x B1 ¢x B2 B5 ¢x B6 B15 ¢x
3390 * ¢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
3391 * ¢x Reserved ¢x BA policy ¢x TID ¢x Buffer size ¢x
3392 * ¢|¢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¢}
3394 zmw_tx_buf_writeh(dev, buf, offset, bf->ba_parameter);
3399 zmw_tx_buf_writeh(dev, buf, offset, bf->ba_timeout);
3405 void zfAggInvokeBar(zdev_t* dev, TID_TX tid_tx)
3407 struct aggBarControl aggBarControl;
3408 //zmw_get_wlan_dev(dev);
3410 //zmw_declare_for_critical_section();
3411 //bar_control = aggBarControl->tid_info << 12 | aggBarControl->compressed_bitmap << 2
3412 // | aggBarControl->multi_tid << 1 | aggBarControl->bar_ack_policy;
3413 aggBarControl.bar_ack_policy = 0;
3414 aggBarControl.multi_tid = 0;
3415 aggBarControl.compressed_bitmap = 0;
3416 aggBarControl.tid_info = tid_tx->tid;
3417 zfAggSendBar(dev, tid_tx, &aggBarControl);
3423 * zfAggSendBar() refers zfAggSendAddbaRequest()
3425 u16_t zfAggSendBar(zdev_t* dev, TID_TX tid_tx, struct aggBarControl *aggBarControl)
3428 //u16_t addrTblSize;
3429 //struct zsAddrTbl addrTbl;
3432 u16_t hlen = 16+8; /* mac header + control headers*/
3433 u16_t header[(8+24+1)/2];
3438 //zmw_get_wlan_dev(dev);
3440 //zmw_declare_for_critical_section();
3444 * TBD : Maximum size of management frame
3446 if ((buf = zfwBufAllocate(dev, 1024)) == NULL)
3448 zm_msg0_mm(ZM_LV_0, "Alloc mm buf Fail!");
3453 * Reserve room for wlan header
3458 * add addba frame body
3460 offset = zfAggSetBarBody(dev, buf, offset, tid_tx, aggBarControl);
3463 zfwBufSetSize(dev, buf, offset);
3468 zfAggGenBarHeader(dev, tid_tx->dst, header, offset-hlen, buf, vap, encrypt);
3469 for (i=0; i<(hlen>>1); i++)
3471 zmw_tx_buf_writeh(dev, buf, i*2, header[i]);
3474 /* Get buffer DMA address */
3475 //if ((addrTblSize = zfwBufMapDma(dev, buf, &addrTbl)) == 0)
3476 //if ((addrTblSize = zfwMapTxDma(dev, buf, &addrTbl)) == 0)
3481 //zm_msg2_mm(ZM_LV_2, "offset=", offset);
3482 //zm_msg2_mm(ZM_LV_2, "hlen=", hlen);
3483 //zm_msg2_mm(ZM_LV_2, "addrTblSize=", addrTblSize);
3484 //zm_msg2_mm(ZM_LV_2, "addrTbl.len[0]=", addrTbl.len[0]);
3485 //zm_msg2_mm(ZM_LV_2, "addrTbl.physAddrl[0]=", addrTbl.physAddrl[0]);
3486 //zm_msg2_mm(ZM_LV_2, "buf->data=", buf->data);
3489 if ((err = zfHpSend(dev, NULL, 0, NULL, 0, NULL, 0, buf, 0,
3490 ZM_INTERNAL_ALLOC_BUF, 0, 0xff)) != ZM_SUCCESS)
3495 zfPutVmmq(dev, buf);
3503 u16_t zfAggSetBarBody(zdev_t* dev, zbuf_t* buf, u16_t offset, TID_TX tid_tx, struct aggBarControl *aggBarControl)
3505 u16_t bar_control, start_seq;
3507 //zmw_get_wlan_dev(dev);
3509 //zmw_declare_for_critical_section();
3511 * BAR Control frame body
3516 * ¢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¢{
3517 * ¢x B0 ¢x B1 ¢x B2 ¢x B3 B11 ¢x B12 B15 ¢x
3518 * ¢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
3519 * ¢x BAR Ack ¢x Multi-TID ¢x Compressed ¢x Reserved ¢x TID_INFO ¢x
3520 * ¢x Policy ¢x ¢x Bitmap ¢x ¢x ¢x
3521 * ¢|¢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¢}
3523 bar_control = aggBarControl->tid_info << 12 | aggBarControl->compressed_bitmap << 2
3524 | aggBarControl->multi_tid << 1 | aggBarControl->bar_ack_policy;
3526 zmw_tx_buf_writeh(dev, buf, offset, bar_control);
3528 if (0 == aggBarControl->multi_tid) {
3530 * BA starting sequence number
3531 * ¢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¢{
3532 * ¢x B0 B3 ¢x B4 B15 ¢x
3533 * ¢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
3534 * ¢x Frag num(0) ¢x BA starting seq num ¢x
3535 * ¢|¢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¢}
3537 start_seq = (tid_tx->bar_ssn << 4) & 0xFFF0;
3538 zmw_tx_buf_writeh(dev, buf, offset, start_seq);
3541 if (1 == aggBarControl->multi_tid && 1 == aggBarControl->compressed_bitmap) {
3542 /* multi-tid BlockAckReq variant, not implemented*/
3548 u16_t zfAggGenBarHeader(zdev_t* dev, u16_t* dst,
3549 u16_t* header, u16_t len, zbuf_t* buf, u16_t vap, u8_t encrypt)
3551 u8_t hlen = 16+8; // MAC ctrl + PHY ctrl + 802.11 MM header
3552 //u8_t frameType = ZM_WLAN_FRAME_TYPE_ACTION;
3554 zmw_get_wlan_dev(dev);
3556 zmw_declare_for_critical_section();
3559 * Generate control setting
3561 //bodyLen = zfwBufGetSize(dev, buf);
3562 header[0] = 16+len+4; //Length
3563 header[1] = 0x8; //MAC control, backoff + (ack)
3567 header[2] = 0x0f00; //PHY control L
3568 header[3] = 0x0000; //PHY control H
3571 header[2] = 0x0f01; //PHY control L
3572 header[3] = 0x000B; //PHY control H
3576 * Generate WLAN header
3577 * Frame control frame type and subtype
3579 header[4+0] = ZM_WLAN_FRAME_TYPE_BAR;
3585 /* Address 1 = DA */
3586 header[4+2] = dst[0];
3587 header[4+3] = dst[1];
3588 header[4+4] = dst[2];
3590 /* Address 2 = SA */
3591 header[4+5] = wd->macAddr[0];
3592 header[4+6] = wd->macAddr[1];
3593 if (wd->wlanMode == ZM_MODE_AP)
3595 #ifdef ZM_VAPMODE_MULTILE_SSID
3596 header[4+7] = wd->macAddr[2]; //Multiple SSID
3598 header[4+7] = wd->macAddr[2] + (vap<<8); //VAP
3603 header[4+7] = wd->macAddr[2];
3606 /* Sequence Control */
3607 zmw_enter_critical_section(dev);
3608 header[4+11] = ((wd->mmseq++)<<4);
3609 zmw_leave_critical_section(dev);