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], ac, aid, fragOff;
1843 //struct aggSta *agg_sta;
1844 #if ZM_AGG_FPGA_REORDERING
1845 struct agg_tid_rx *tid_rx;
1847 zmw_get_wlan_dev(dev);
1849 //zmw_declare_for_critical_section();
1850 seq_no = zmw_rx_buf_readh(dev, buf, 22) >> 4;
1851 //DbgPrint("Rx seq=%d\n", seq_no);
1852 if (wd->sta.EnableHT == 0)
1857 frameCtrl = zmw_rx_buf_readb(dev, buf, 0);
1858 frameType = frameCtrl & 0xf;
1859 frameSubtype = frameCtrl & 0xf0;
1862 if (frameType != ZM_WLAN_DATA_FRAME) //non-Qos Data? (frameSubtype&0x80)
1866 #ifdef ZM_ENABLE_PERFORMANCE_EVALUATION
1867 tcp_seq = zmw_rx_buf_readb(dev, buf, 22+36) << 24;
1868 tcp_seq += zmw_rx_buf_readb(dev, buf, 22+37) << 16;
1869 tcp_seq += zmw_rx_buf_readb(dev, buf, 22+38) << 8;
1870 tcp_seq += zmw_rx_buf_readb(dev, buf, 22+39);
1873 ZM_SEQ_DEBUG("In %5d, %12u\n", seq_no, tcp_seq);
1874 dst0 = zmw_rx_buf_readh(dev, buf, offset+4);
1876 src[0] = zmw_rx_buf_readh(dev, buf, offset+10);
1877 src[1] = zmw_rx_buf_readh(dev, buf, offset+12);
1878 src[2] = zmw_rx_buf_readh(dev, buf, offset+14);
1880 #if ZM_AGG_FPGA_DEBUG
1883 aid = zfApFindSta(dev, src);
1886 //agg_sta = &wd->aggSta[aid];
1887 //zfTxGetIpTosAndFrag(dev, buf, &up, &fragOff);
1888 //ac = zcUpToAc[up&0x7] & 0x3;
1891 * Filter unicast frame only, aid == 0 is for debug only
1893 if ((dst0 & 0x1) == 0 && aid == 0)
1895 #if ZM_AGG_FPGA_REORDERING
1896 tid_rx = zfAggRxGetQueue(dev, buf) ;
1901 //if (tid_rx->addBaExchangeStatusCode == ZM_AGG_ADDBA_RESPONSE)
1912 u16_t zfAggRx(zdev_t* dev, zbuf_t* buf, struct zsAdditionInfo *addInfo, struct agg_tid_rx *tid_rx)
1920 zmw_get_wlan_dev(dev);
1922 zmw_declare_for_critical_section();
1924 ZM_BUFFER_TRACE(dev, buf)
1926 ZM_PERFORMANCE_RX_REORDER(dev);
1928 seq_no = zmw_rx_buf_readh(dev, buf, offset+22) >> 4;
1930 index = seq_no - tid_rx->seq_start;
1935 /* zm_msg2_agg(ZM_LV_0, "queue seq = ", seq_no);
1936 * DbgPrint("%s:%s%lxh %s%lxh\n", __func__, "queue seq=", seq_no,
1937 * "; seq_start=", tid_rx->seq_start);
1940 //DbgPrint("seq_no=%d, seq_start=%d\n", seq_no, tid_rx->seq_start);
1942 /* In some APs, we found that it might transmit NULL data whose sequence number
1943 is out or order. In order to avoid this problem, we ignore these NULL data.
1946 frameSubType = (zmw_rx_buf_readh(dev, buf, 0) & 0xF0) >> 4;
1948 /* If this is a NULL data instead of Qos NULL data */
1949 if ((frameSubType & 0x0C) == 0x04)
1953 seq_diff = (seq_no > tid_rx->seq_start) ?
1954 seq_no - tid_rx->seq_start : tid_rx->seq_start - seq_no;
1956 if (seq_diff > ZM_AGG_BAW_SIZE)
1958 zm_debug_msg0("Free Rx NULL data in zfAggRx");
1960 /* Free Rx buffer */
1961 zfwBufFree(dev, buf, 0);
1962 return ZM_ERR_OUT_OF_ORDER_NULL_DATA;
1967 * sequence number wrap at 4k
1969 if (tid_rx->seq_start > seq_no)
1973 zmw_enter_critical_section(dev);
1974 if (tid_rx->seq_start >= 4096) {
1975 tid_rx->seq_start = 0;
1977 zmw_leave_critical_section(dev);
1981 if (tid_rx->seq_start == seq_no) {
1982 zmw_enter_critical_section(dev);
1983 if (((tid_rx->baw_head - tid_rx->baw_tail) & ZM_AGG_BAW_MASK) > 0) {
1984 //DbgPrint("head=%d, tail=%d", tid_rx->baw_head, tid_rx->baw_tail);
1985 tid_rx->baw_tail = (tid_rx->baw_tail + 1) & ZM_AGG_BAW_MASK;
1987 tid_rx->seq_start = (tid_rx->seq_start + 1) & (4096 - 1);
1988 zmw_leave_critical_section(dev);
1990 ZM_PERFORMANCE_RX_SEQ(dev, buf);
1992 if (wd->zfcbRecv80211 != NULL) {
1993 //seq_no = zmw_rx_buf_readh(dev, buf, offset+22) >> 4;
1994 //DbgPrint("Recv indicate seq=%d\n", seq_no);
1995 //DbgPrint("1. seq=%d\n", seq_no);
1997 wd->zfcbRecv80211(dev, buf, addInfo);
2000 zfiRecv80211(dev, buf, addInfo);
2003 else if (!zfAggRxEnqueue(dev, buf, tid_rx, addInfo))
2011 while (tid_rx->baw_head != tid_rx->baw_tail) {// && tid_rx->frame[tid_rx->baw_tail].buf)
2014 zmw_enter_critical_section(dev);
2016 tailIndex = tid_rx->baw_tail;
2017 pbuf = tid_rx->frame[tailIndex].buf;
2018 tid_rx->frame[tailIndex].buf = 0;
2021 zmw_leave_critical_section(dev);
2025 tid_rx->baw_tail = (tid_rx->baw_tail + 1) & ZM_AGG_BAW_MASK;
2026 tid_rx->seq_start = (tid_rx->seq_start + 1) & (4096 - 1);
2029 //if(pbuf && tid_rx->baw_size > 0)
2030 // tid_rx->baw_size--;
2032 zmw_leave_critical_section(dev);
2034 ZM_PERFORMANCE_RX_SEQ(dev, pbuf);
2036 if (wd->zfcbRecv80211 != NULL)
2038 //seq_no = zmw_rx_buf_readh(dev, pbuf, offset+22) >> 4;
2039 //DbgPrint("Recv indicate seq=%d\n", seq_no);
2040 //DbgPrint("1. seq=%d\n", seq_no);
2041 wd->zfcbRecv80211(dev, pbuf, addInfo);
2045 //seq_no = zmw_rx_buf_readh(dev, pbuf, offset+22) >> 4;
2046 //DbgPrint("Recv indicate seq=%d\n", seq_no);
2047 zfiRecv80211(dev, pbuf, addInfo);
2054 struct agg_tid_rx *zfAggRxGetQueue(zdev_t* dev, zbuf_t* buf)
2059 struct agg_tid_rx *tid_rx = NULL;
2061 zmw_get_wlan_dev(dev);
2063 //zmw_declare_for_critical_section();
2065 src[0] = zmw_rx_buf_readh(dev, buf, offset+10);
2066 src[1] = zmw_rx_buf_readh(dev, buf, offset+12);
2067 src[2] = zmw_rx_buf_readh(dev, buf, offset+14);
2068 aid = zfApFindSta(dev, src);
2070 ac = (zmw_rx_buf_readh(dev, buf, 24) & 0xF);
2072 // mark by spin lock debug
2073 //zmw_enter_critical_section(dev);
2075 for (i=0; i<ZM_AGG_POOL_SIZE ; i++)
2077 if((wd->tid_rx[i]->aid == aid) && (wd->tid_rx[i]->ac == ac))
2079 tid_rx = wd->tid_rx[i];
2084 // mark by spin lock debug
2085 //zmw_leave_critical_section(dev);
2090 u16_t zfAggRxEnqueue(zdev_t* dev, zbuf_t* buf, struct agg_tid_rx *tid_rx, struct zsAdditionInfo *addInfo)
2092 u16_t seq_no, offset = 0;
2095 u8_t bdropframe = 0;
2097 zmw_get_wlan_dev(dev);
2099 zmw_declare_for_critical_section();
2101 ZM_BUFFER_TRACE(dev, buf)
2103 seq_no = zmw_rx_buf_readh(dev, buf, offset+22) >> 4;
2104 index = seq_no - tid_rx->seq_start;
2107 * sequence number wrap at 4k
2108 * -1000: check for duplicate past packet
2111 if (tid_rx->seq_start > seq_no) {
2112 if ((tid_rx->seq_start > 3967) && (seq_no < 128)) {
2114 } else if (tid_rx->seq_start - seq_no > 70) {
2115 zmw_enter_critical_section(dev);
2116 tid_rx->sq_behind_count++;
2117 if (tid_rx->sq_behind_count > 3) {
2118 tid_rx->sq_behind_count = 0;
2122 zmw_leave_critical_section(dev);
2127 if (seq_no - tid_rx->seq_start > 70) {
2128 zmw_enter_critical_section(dev);
2129 tid_rx->sq_exceed_count++;
2130 if (tid_rx->sq_exceed_count > 3) {
2131 tid_rx->sq_exceed_count = 0;
2135 zmw_leave_critical_section(dev);
2139 if (bdropframe == 1) {
2140 /*if (wd->zfcbRecv80211 != NULL) {
2141 wd->zfcbRecv80211(dev, buf, addInfo);
2144 zfiRecv80211(dev, buf, addInfo);
2147 ZM_PERFORMANCE_FREE(dev, buf);
2149 zfwBufFree(dev, buf, 0);
2150 /*zfAggRxFlush(dev, seq_no, tid_rx);
2151 tid_rx->seq_start = seq_no;
2152 index = seq_no - tid_rx->seq_start;
2155 //DbgPrint("Free an old packet, seq_start=%d, seq_no=%d\n", tid_rx->seq_start, seq_no);
2158 * duplicate past packet
2159 * happens only in simulated aggregation environment
2163 zmw_enter_critical_section(dev);
2164 if (tid_rx->sq_exceed_count > 0){
2165 tid_rx->sq_exceed_count--;
2168 if (tid_rx->sq_behind_count > 0) {
2169 tid_rx->sq_behind_count--;
2171 zmw_leave_critical_section(dev);
2175 zfAggRxFlush(dev, seq_no, tid_rx);
2176 tid_rx->seq_start = seq_no;
2180 //if (index >= (ZM_AGG_BAW_SIZE - 1))
2181 if (index >= (ZM_AGG_BAW_MASK))
2186 //DbgPrint("index >= 64, seq_start=%d, seq_no=%d\n", tid_rx->seq_start, seq_no);
2187 zfAggRxFlush(dev, seq_no, tid_rx);
2188 //tid_rx->seq_start = seq_no;
2189 index = seq_no - tid_rx->seq_start;
2190 if ((tid_rx->seq_start > seq_no) && (tid_rx->seq_start > 1000) && (tid_rx->seq_start - 1000) > seq_no)
2192 //index = seq_no - tid_rx->seq_start;
2195 //index = seq_no - tid_rx->seq_start;
2196 while (index >= (ZM_AGG_BAW_MASK)) {
2197 //DbgPrint("index >= 64, seq_start=%d, seq_no=%d\n", tid_rx->seq_start, seq_no);
2198 tid_rx->seq_start = (tid_rx->seq_start + ZM_AGG_BAW_MASK) & (4096 - 1);
2199 index = seq_no - tid_rx->seq_start;
2200 if ((tid_rx->seq_start > seq_no) && (tid_rx->seq_start > 1000) && (tid_rx->seq_start - 1000) > seq_no)
2208 q_index = (tid_rx->baw_tail + index) & ZM_AGG_BAW_MASK;
2209 if (tid_rx->frame[q_index].buf && (((tid_rx->baw_head - tid_rx->baw_tail) & ZM_AGG_BAW_MASK) >
2210 (((q_index) - tid_rx->baw_tail) & ZM_AGG_BAW_MASK)))
2213 ZM_PERFORMANCE_DUP(dev, tid_rx->frame[q_index].buf, buf);
2214 zfwBufFree(dev, buf, 0);
2215 //DbgPrint("Free a duplicate packet, seq_start=%d, seq_no=%d\n", tid_rx->seq_start, seq_no);
2216 //DbgPrint("head=%d, tail=%d", tid_rx->baw_head, tid_rx->baw_tail);
2223 zmw_enter_critical_section(dev);
2224 if(tid_rx->frame[q_index].buf) {
2225 zfwBufFree(dev, tid_rx->frame[q_index].buf, 0);
2226 tid_rx->frame[q_index].buf = 0;
2229 tid_rx->frame[q_index].buf = buf;
2230 tid_rx->frame[q_index].arrivalTime = zm_agg_GetTime();
2231 zfwMemoryCopy((void*)&tid_rx->frame[q_index].addInfo, (void*)addInfo, sizeof(struct zsAdditionInfo));
2234 * for debug simulated aggregation only,
2235 * should be done in rx of ADDBA Request
2237 //tid_rx->addInfo = addInfo;
2240 if (((tid_rx->baw_head - tid_rx->baw_tail) & ZM_AGG_BAW_MASK) <= index)
2242 //tid_rx->baw_size = index + 1;
2243 if (((tid_rx->baw_head - tid_rx->baw_tail) & ZM_AGG_BAW_MASK) <=
2244 //((q_index + 1) & ZM_AGG_BAW_MASK))
2245 (((q_index) - tid_rx->baw_tail) & ZM_AGG_BAW_MASK))//tid_rx->baw_size )
2246 tid_rx->baw_head = (q_index + 1) & ZM_AGG_BAW_MASK;
2248 zmw_leave_critical_section(dev);
2253 //DbgPrint("head=%d, tail=%d, start=%d", tid_rx->baw_head, tid_rx->baw_tail, tid_rx->seq_start);
2257 u16_t zfAggRxFlush(zdev_t* dev, u16_t seq_no, struct agg_tid_rx *tid_rx)
2261 struct zsAdditionInfo addInfo;
2262 zmw_get_wlan_dev(dev);
2263 zmw_declare_for_critical_section();
2265 ZM_PERFORMANCE_RX_FLUSH(dev);
2269 zmw_enter_critical_section(dev);
2270 if (tid_rx->baw_tail == tid_rx->baw_head) {
2271 zmw_leave_critical_section(dev);
2275 pbuf = tid_rx->frame[tid_rx->baw_tail].buf;
2276 zfwMemoryCopy((void*)&addInfo, (void*)&tid_rx->frame[tid_rx->baw_tail].addInfo, sizeof(struct zsAdditionInfo));
2277 tid_rx->frame[tid_rx->baw_tail].buf = 0;
2278 //if(pbuf && tid_rx->baw_size > 0) tid_rx->baw_size--;
2279 tid_rx->baw_tail = (tid_rx->baw_tail + 1) & ZM_AGG_BAW_MASK;
2280 tid_rx->seq_start = (tid_rx->seq_start + 1) & (4096 - 1);
2281 zmw_leave_critical_section(dev);
2286 ZM_PERFORMANCE_RX_SEQ(dev, pbuf);
2288 if (wd->zfcbRecv80211 != NULL)
2290 seq = zmw_rx_buf_readh(dev, pbuf, 22) >> 4;
2291 //DbgPrint("Recv indicate seq=%d\n", seq);
2292 //DbgPrint("2. seq=%d\n", seq);
2293 wd->zfcbRecv80211(dev, pbuf, &addInfo);
2297 seq = zmw_rx_buf_readh(dev, pbuf, 22) >> 4;
2298 //DbgPrint("Recv indicate seq=%d\n", seq);
2299 zfiRecv80211(dev, pbuf, &addInfo);
2304 zmw_enter_critical_section(dev);
2305 tid_rx->baw_head = tid_rx->baw_tail = 0;
2306 zmw_leave_critical_section(dev);
2312 /************************************************************************/
2314 /* FUNCTION DESCRIPTION zfAggRxFreeBuf */
2315 /* Frees all queued packets in buffer when the driver is down. */
2316 /* The zfFreeResource() will check if the buffer is all freed. */
2319 /* dev : device pointer */
2325 /* Honda Atheros Communications, INC. 2006.12 */
2327 /************************************************************************/
2328 u16_t zfAggRxFreeBuf(zdev_t* dev, u16_t destroy)
2332 struct agg_tid_rx *tid_rx;
2335 //struct bufInfo *buf_info;
2337 zmw_get_wlan_dev(dev);
2338 zmw_declare_for_critical_section();
2340 for (i=0; i<ZM_AGG_POOL_SIZE; i++)
2344 tid_rx = wd->tid_rx[i];
2346 for(j=0; j <= ZM_AGG_BAW_SIZE; j++)
2348 zmw_enter_critical_section(dev);
2349 buf = tid_rx->frame[j].buf;
2350 tid_rx->frame[j].buf = 0;
2351 zmw_leave_critical_section(dev);
2355 zfwBufFree(dev, buf, 0);
2360 if ( tid_rx->baw_head != tid_rx->baw_tail )
2362 while (tid_rx->baw_head != tid_rx->baw_tail)
2364 buf = tid_rx->frame[tid_rx->baw_tail].buf;
2365 tid_rx->frame[tid_rx->baw_tail].buf = 0;
2368 zfwBufFree(dev, buf, 0);
2370 zmw_enter_critical_section(dev);
2371 tid_rx->frame[tid_rx->baw_tail].buf = 0;
2372 zmw_leave_critical_section(dev);
2374 zmw_enter_critical_section(dev);
2375 //if (tid_rx->baw_size > 0)tid_rx->baw_size--;
2376 tid_rx->baw_tail = (tid_rx->baw_tail + 1) & ZM_AGG_BAW_MASK;
2377 tid_rx->seq_start++;
2378 zmw_leave_critical_section(dev);
2383 zmw_enter_critical_section(dev);
2384 tid_rx->seq_start = 0;
2385 tid_rx->baw_head = tid_rx->baw_tail = 0;
2386 tid_rx->aid = ZM_MAX_STA_SUPPORT;
2387 zmw_leave_critical_section(dev);
2389 #ifdef ZM_ENABLE_AGGREGATION
2390 #ifndef ZM_ENABLE_FW_BA_RETRANSMISSION //disable BAW
2391 if (tid_baw->enabled) {
2392 zm_msg1_agg(ZM_LV_0, "Device down, clear BAW queue:", i);
2393 BAW->disable(dev, tid_baw);
2397 if (1 == wd->aggQPool[i]->aggQEnabled) {
2398 tid_tx = wd->aggQPool[i];
2399 buf = zfAggTxGetVtxq(dev, tid_tx);
2401 zfwBufFree(dev, buf, 0);
2402 buf = zfAggTxGetVtxq(dev, tid_tx);
2407 zfwMemFree(dev, wd->aggQPool[i], sizeof(struct aggQueue));
2408 zfwMemFree(dev, wd->tid_rx[i], sizeof(struct agg_tid_rx));
2411 #ifdef ZM_ENABLE_AGGREGATION
2412 #ifndef ZM_ENABLE_FW_BA_RETRANSMISSION //disable BAW
2413 if(destroy) zfwMemFree(dev, BAW, sizeof(struct baw_enabler));
2420 void zfAggRecvBAR(zdev_t* dev, zbuf_t *buf) {
2421 u16_t start_seq, len;
2423 len = zfwBufGetSize(dev, buf);
2424 start_seq = zmw_rx_buf_readh(dev, buf, len-2);
2425 DbgPrint("Received a BAR Control frame, start_seq=%d", start_seq>>4);
2426 /* todo: set the bitmap by reordering buffer! */
2427 for (i=0; i<8; i++) bitmap[i]=0;
2428 zfSendBA(dev, start_seq, bitmap);
2431 #ifdef ZM_ENABLE_AGGREGATION
2432 #ifndef ZM_ENABLE_FW_BA_RETRANSMISSION //disable BAW
2433 void zfAggTxRetransmit(zdev_t* dev, struct bufInfo *buf_info, struct aggControl *aggControl, TID_TX tid_tx) {
2437 zmw_get_wlan_dev(dev);
2438 if (aggControl && (ZM_AGG_FIRST_MPDU == aggControl->ampduIndication) ) {
2439 tid_tx->bar_ssn = buf_info->baw_header->header[15];
2440 aggControl->tid_baw->start_seq = tid_tx->bar_ssn >> 4;
2441 zm_msg1_agg(ZM_LV_0, "start seq=", tid_tx->bar_ssn >> 4);
2443 buf_info->baw_header->header[4] |= (1 << 11);
2444 if (aggControl && aggControl->aggEnabled) {
2445 //if (wd->enableAggregation==0 && !(buf_info->baw_header->header[6]&0x1))
2447 //if (((buf_info->baw_header->header[2] & 0x3) == 2))
2449 /* Enable aggregation */
2450 buf_info->baw_header->header[1] |= 0x20;
2451 if (ZM_AGG_LAST_MPDU == aggControl->ampduIndication) {
2452 buf_info->baw_header->header[1] |= 0x4000;
2455 buf_info->baw_header->header[1] &= ~0x4000;
2456 //zm_debug_msg0("ZM_AGG_LAST_MPDU");
2460 // zm_debug_msg1("no aggr, header[2]&0x3 = ",buf_info->baw_header->header[2] & 0x3)
2461 // aggControl->aggEnabled = 0;
2465 // zm_debug_msg1("no aggr, wd->enableAggregation = ", wd->enableAggregation);
2466 // zm_debug_msg1("no aggr, !header[6]&0x1 = ",!(buf_info->baw_header->header[6]&0x1));
2467 // aggControl->aggEnabled = 0;
2471 /*if (aggControl->tid_baw) {
2472 struct baw_header_r header_r;
2474 header_r.header = buf_info->baw_header->header;
2475 header_r.mic = buf_info->baw_header->mic;
2476 header_r.snap = buf_info->baw_header->snap;
2477 header_r.headerLen = buf_info->baw_header->headerLen;
2478 header_r.micLen = buf_info->baw_header->micLen;
2479 header_r.snapLen = buf_info->baw_header->snapLen;
2480 header_r.removeLen = buf_info->baw_header->removeLen;
2481 header_r.keyIdx = buf_info->baw_header->keyIdx;
2483 BAW->insert(dev, buf_info->buf, tid_tx->bar_ssn >> 4, aggControl->tid_baw, buf_info->baw_retransmit, &header_r);
2486 if ((err = zfHpSend(dev,
2487 buf_info->baw_header->header,
2488 buf_info->baw_header->headerLen,
2489 buf_info->baw_header->snap,
2490 buf_info->baw_header->snapLen,
2491 buf_info->baw_header->mic,
2492 buf_info->baw_header->micLen,
2494 buf_info->baw_header->removeLen,
2495 ZM_EXTERNAL_ALLOC_BUF,
2497 buf_info->baw_header->keyIdx)) != ZM_SUCCESS)
2505 zfwBufFree(dev, buf_info->buf, 0);
2509 #endif //disable BAW
2511 /************************************************************************/
2513 /* FUNCTION DESCRIPTION zfAggTxSendEth */
2514 /* Called to transmit Ethernet frame from upper elayer. */
2517 /* dev : device pointer */
2518 /* buf : buffer pointer */
2519 /* port : WLAN port, 0=>standard, 0x10-0x17=>VAP, 0x20-0x25=>WDS */
2525 /* Stephen, Honda Atheros Communications, Inc. 2006.12 */
2527 /************************************************************************/
2528 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)
2531 //u16_t addrTblSize;
2532 //struct zsAddrTbl addrTbl;
2534 u16_t header[(8+30+2+18)/2]; /* ctr+(4+a1+a2+a3+2+a4)+qos+iv */
2548 u8_t qosType, keyIdx = 0;
2551 zmw_get_wlan_dev(dev);
2553 zmw_declare_for_critical_section();
2555 zm_msg1_tx(ZM_LV_2, "zfTxSendEth(), port=", port);
2557 /* Get IP TOS for QoS AC and IP frag offset */
2558 zfTxGetIpTosAndFrag(dev, buf, &up, &fragOff);
2560 #ifdef ZM_ENABLE_NATIVE_WIFI
2561 if ( wd->wlanMode == ZM_MODE_INFRASTRUCTURE )
2564 da[0] = zmw_tx_buf_readh(dev, buf, 16);
2565 da[1] = zmw_tx_buf_readh(dev, buf, 18);
2566 da[2] = zmw_tx_buf_readh(dev, buf, 20);
2568 sa[0] = zmw_tx_buf_readh(dev, buf, 10);
2569 sa[1] = zmw_tx_buf_readh(dev, buf, 12);
2570 sa[2] = zmw_tx_buf_readh(dev, buf, 14);
2572 else if ( wd->wlanMode == ZM_MODE_IBSS )
2575 da[0] = zmw_tx_buf_readh(dev, buf, 4);
2576 da[1] = zmw_tx_buf_readh(dev, buf, 6);
2577 da[2] = zmw_tx_buf_readh(dev, buf, 8);
2579 sa[0] = zmw_tx_buf_readh(dev, buf, 10);
2580 sa[1] = zmw_tx_buf_readh(dev, buf, 12);
2581 sa[2] = zmw_tx_buf_readh(dev, buf, 14);
2583 else if ( wd->wlanMode == ZM_MODE_AP )
2586 da[0] = zmw_tx_buf_readh(dev, buf, 4);
2587 da[1] = zmw_tx_buf_readh(dev, buf, 6);
2588 da[2] = zmw_tx_buf_readh(dev, buf, 8);
2590 sa[0] = zmw_tx_buf_readh(dev, buf, 16);
2591 sa[1] = zmw_tx_buf_readh(dev, buf, 18);
2592 sa[2] = zmw_tx_buf_readh(dev, buf, 20);
2600 da[0] = zmw_tx_buf_readh(dev, buf, 0);
2601 da[1] = zmw_tx_buf_readh(dev, buf, 2);
2602 da[2] = zmw_tx_buf_readh(dev, buf, 4);
2604 sa[0] = zmw_tx_buf_readh(dev, buf, 6);
2605 sa[1] = zmw_tx_buf_readh(dev, buf, 8);
2606 sa[2] = zmw_tx_buf_readh(dev, buf, 10);
2608 //Decide Key Index in ATOM, No meaning in OTUS--CWYang(m)
2609 if (wd->wlanMode == ZM_MODE_AP)
2611 keyIdx = wd->ap.bcHalKeyIdx[port];
2612 id = zfApFindSta(dev, da);
2615 switch (wd->ap.staTable[id].encryMode)
2619 #ifdef ZM_ENABLE_CENC
2621 #endif //ZM_ENABLE_CENC
2622 keyIdx = wd->ap.staTable[id].keyIdx;
2629 switch (wd->sta.encryMode)
2634 keyIdx = wd->sta.keyId;
2643 #ifdef ZM_ENABLE_CENC
2645 keyIdx = wd->sta.cencKeyId;
2647 #endif //ZM_ENABLE_CENC
2652 removeLen = zfTxGenWlanSnap(dev, buf, snap, &snapLen);
2653 //zm_msg1_tx(ZM_LV_0, "fragOff=", fragOff);
2655 fragLen = wd->fragThreshold;
2656 frameLen = zfwBufGetSize(dev, buf);
2657 frameLen -= removeLen;
2661 if ( (wd->wlanMode == ZM_MODE_INFRASTRUCTURE)&&
2662 (wd->sta.encryMode == ZM_TKIP) )
2664 if ( frameLen > fragLen )
2666 micLen = zfTxGenWlanTail(dev, buf, snap, snapLen, mic);
2670 /* append MIC by HMAC */
2679 if ( frameLen > fragLen )
2681 micLen = zfTxGenWlanTail(dev, buf, snap, snapLen, mic);
2685 /* append MIC by HMAC */
2690 /* Access Category */
2691 if (wd->wlanMode == ZM_MODE_AP)
2693 zfApGetStaQosType(dev, da, &qosType);
2699 else if (wd->wlanMode == ZM_MODE_INFRASTRUCTURE)
2701 if (wd->sta.wmeConnected == 0)
2708 /* TODO : STA QoS control field */
2712 /* Assign sequence number */
2713 zmw_enter_critical_section(dev);
2714 frag.seq[0] = ((wd->seq[zcUpToAc[up&0x7]]++) << 4);
2715 if (aggControl && (ZM_AGG_FIRST_MPDU == aggControl->ampduIndication) ) {
2716 tid_tx->bar_ssn = frag.seq[0];
2718 zm_msg1_agg(ZM_LV_0, "start seq=", tid_tx->bar_ssn >> 4);
2720 //tid_tx->baw_buf[tid_tx->baw_head-1].baw_seq=frag.seq[0];
2721 zmw_leave_critical_section(dev);
2725 frag.bufType[0] = bufType;
2726 frag.flag[0] = flag;
2729 for (i=0; i<fragNum; i++)
2731 /* Create WLAN header(Control Setting + 802.11 header + IV) */
2732 if (up !=0 ) zm_debug_msg1("up not 0, up=",up);
2733 headerLen = zfTxGenWlanHeader(dev, frag.buf[i], header, frag.seq[i],
2734 frag.flag[i], snapLen+micLen, removeLen,
2735 port, da, sa, up, &micLen, snap, snapLen,
2738 /* Get buffer DMA address */
2739 //if ((addrTblSize = zfwBufMapDma(dev, frag.buf[i], &addrTbl)) == 0)
2740 //if ((addrTblSize = zfwMapTxDma(dev, frag.buf[i], &addrTbl)) == 0)
2742 // err = ZM_ERR_BUFFER_DMA_ADDR;
2746 /* Flush buffer on cache */
2747 //zfwBufFlush(dev, frag.buf[i]);
2750 zm_msg1_tx(ZM_LV_0, "headerLen=", headerLen);
2751 zm_msg1_tx(ZM_LV_0, "snapLen=", snapLen);
2752 zm_msg1_tx(ZM_LV_0, "micLen=", micLen);
2753 zm_msg1_tx(ZM_LV_0, "removeLen=", removeLen);
2754 zm_msg1_tx(ZM_LV_0, "addrTblSize=", addrTblSize);
2755 zm_msg1_tx(ZM_LV_0, "frag.bufType[0]=", frag.bufType[0]);
2758 fragLen = zfwBufGetSize(dev, frag.buf[i]);
2759 if ((da[0]&0x1) == 0)
2761 wd->commTally.txUnicastFrm++;
2762 wd->commTally.txUnicastOctets += (fragLen+snapLen);
2764 else if ((da[0]& 0x1))
2766 wd->commTally.txBroadcastFrm++;
2767 wd->commTally.txBroadcastOctets += (fragLen+snapLen);
2771 wd->commTally.txMulticastFrm++;
2772 wd->commTally.txMulticastOctets += (fragLen+snapLen);
2774 wd->ledStruct.txTraffic++;
2776 #if 0 //Who care this?
2777 if ( (i)&&(i == (fragNum-1)) )
2779 wd->trafTally.txDataByteCount -= micLen;
2783 /*if (aggControl->tid_baw && aggControl->aggEnabled) {
2784 struct baw_header_r header_r;
2786 header_r.header = header;
2788 header_r.snap = snap;
2789 header_r.headerLen = headerLen;
2790 header_r.micLen = micLen;
2791 header_r.snapLen = snapLen;
2792 header_r.removeLen = removeLen;
2793 header_r.keyIdx = keyIdx;
2795 BAW->insert(dev, buf, tid_tx->bar_ssn >> 4, aggControl->tid_baw, 0, &header_r);
2798 if ((err = zfHpSend(dev, header, headerLen, snap, snapLen,
2799 mic, micLen, frag.buf[i], removeLen,
2800 frag.bufType[i], zcUpToAc[up&0x7], keyIdx)) != ZM_SUCCESS)
2809 if (frag.bufType[i] == ZM_EXTERNAL_ALLOC_BUF)
2811 zfwBufFree(dev, frag.buf[i], err);
2813 else if (frag.bufType[i] == ZM_INTERNAL_ALLOC_BUF)
2815 zfwBufFree(dev, frag.buf[i], 0);
2821 } /* for (i=0; i<fragNum; i++) */
2827 * zfAggSendADDBA() refers zfSendMmFrame() in cmm.c
2829 u16_t zfAggSendAddbaRequest(zdev_t* dev, u16_t *dst, u16_t ac, u16_t up)
2832 //u16_t addrTblSize;
2833 //struct zsAddrTbl addrTbl;
2837 u16_t header[(24+25+1)/2];
2842 //zmw_get_wlan_dev(dev);
2844 //zmw_declare_for_critical_section();
2848 * TBD : Maximum size of management frame
2850 if ((buf = zfwBufAllocate(dev, 1024)) == NULL)
2852 zm_msg0_mm(ZM_LV_0, "Alloc mm buf Fail!");
2857 * Reserve room for wlan header
2862 * add addba frame body
2864 offset = zfAggSetAddbaFrameBody(dev, buf, offset, ac, up);
2867 zfwBufSetSize(dev, buf, offset);
2872 zfAggGenAddbaHeader(dev, dst, header, offset-hlen, buf, vap, encrypt);
2873 for (i=0; i<(hlen>>1); i++)
2875 zmw_tx_buf_writeh(dev, buf, i*2, header[i]);
2878 /* Get buffer DMA address */
2879 //if ((addrTblSize = zfwBufMapDma(dev, buf, &addrTbl)) == 0)
2880 //if ((addrTblSize = zfwMapTxDma(dev, buf, &addrTbl)) == 0)
2885 //zm_msg2_mm(ZM_LV_2, "offset=", offset);
2886 //zm_msg2_mm(ZM_LV_2, "hlen=", hlen);
2887 //zm_msg2_mm(ZM_LV_2, "addrTblSize=", addrTblSize);
2888 //zm_msg2_mm(ZM_LV_2, "addrTbl.len[0]=", addrTbl.len[0]);
2889 //zm_msg2_mm(ZM_LV_2, "addrTbl.physAddrl[0]=", addrTbl.physAddrl[0]);
2890 //zm_msg2_mm(ZM_LV_2, "buf->data=", buf->data);
2893 if ((err = zfHpSend(dev, NULL, 0, NULL, 0, NULL, 0, buf, 0,
2894 ZM_INTERNAL_ALLOC_BUF, 0, 0xff)) != ZM_SUCCESS)
2899 zfPutVmmq(dev, buf);
2907 u16_t zfAggSetAddbaFrameBody(zdev_t* dev, zbuf_t* buf, u16_t offset, u16_t ac, u16_t up)
2909 u16_t ba_parameter, start_seq;
2911 zmw_get_wlan_dev(dev);
2913 //zmw_declare_for_critical_section();
2915 * ADDBA Request frame body
2921 zmw_tx_buf_writeb(dev, buf, offset++, 3);
2923 * Action details = 0
2925 zmw_tx_buf_writeb(dev, buf, offset++, ZM_WLAN_ADDBA_REQUEST_FRAME);
2927 * Dialog Token = nonzero
2928 * TBD: define how to get dialog token?
2930 zmw_tx_buf_writeb(dev, buf, offset++, 2);
2932 * Block Ack parameter set
2933 * BA policy = 1 for immediate BA, 0 for delayed BA
2934 * TID(4bits) & buffer size(4bits) (TID=up & buffer size=0x80)
2935 * TBD: how to get buffer size?
2936 * ¢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¢{
2937 * ¢x B0 ¢x B1 ¢x B2 B5 ¢x B6 B15 ¢x
2938 * ¢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
2939 * ¢x Reserved ¢x BA policy ¢x TID ¢x Buffer size ¢x
2940 * ¢|¢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¢}
2942 ba_parameter = 1 << 12; // buffer size = 0x40(64)
2943 ba_parameter |= up << 2; // tid = up
2944 ba_parameter |= 2; // ba policy = 1
2945 zmw_tx_buf_writeh(dev, buf, offset, ba_parameter);
2950 zmw_tx_buf_writeh(dev, buf, offset, 0);
2953 * BA starting sequence number
2954 * ¢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¢{
2955 * ¢x B0 B3 ¢x B4 B15 ¢x
2956 * ¢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
2957 * ¢x Frag num(0) ¢x BA starting seq num ¢x
2958 * ¢|¢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¢}
2960 start_seq = ((wd->seq[ac]) << 4) & 0xFFF0;
2961 zmw_tx_buf_writeh(dev, buf, offset, start_seq);
2967 u16_t zfAggGenAddbaHeader(zdev_t* dev, u16_t* dst,
2968 u16_t* header, u16_t len, zbuf_t* buf, u16_t vap, u8_t encrypt)
2970 u8_t hlen = 32; // MAC ctrl + PHY ctrl + 802.11 MM header
2971 //u8_t frameType = ZM_WLAN_FRAME_TYPE_ACTION;
2973 zmw_get_wlan_dev(dev);
2975 zmw_declare_for_critical_section();
2978 * Generate control setting
2980 //bodyLen = zfwBufGetSize(dev, buf);
2981 header[0] = 24+len+4; //Length
2982 header[1] = 0x8; //MAC control, backoff + (ack)
2986 header[2] = 0x0f00; //PHY control L
2987 header[3] = 0x0000; //PHY control H
2990 header[2] = 0x0f01; //PHY control L
2991 header[3] = 0x000B; //PHY control H
2995 * Generate WLAN header
2996 * Frame control frame type and subtype
2998 header[4+0] = ZM_WLAN_FRAME_TYPE_ACTION;
3004 if (wd->wlanMode == ZM_MODE_INFRASTRUCTURE)
3006 header[4+8] = wd->sta.bssid[0];
3007 header[4+9] = wd->sta.bssid[1];
3008 header[4+10] = wd->sta.bssid[2];
3010 else if (wd->wlanMode == ZM_MODE_PSEUDO)
3012 /* Address 3 = 00:00:00:00:00:00 */
3017 else if (wd->wlanMode == ZM_MODE_IBSS)
3019 header[4+8] = wd->sta.bssid[0];
3020 header[4+9] = wd->sta.bssid[1];
3021 header[4+10] = wd->sta.bssid[2];
3023 else if (wd->wlanMode == ZM_MODE_AP)
3025 /* Address 3 = BSSID */
3026 header[4+8] = wd->macAddr[0];
3027 header[4+9] = wd->macAddr[1];
3028 header[4+10] = wd->macAddr[2] + (vap<<8);
3031 /* Address 1 = DA */
3032 header[4+2] = dst[0];
3033 header[4+3] = dst[1];
3034 header[4+4] = dst[2];
3036 /* Address 2 = SA */
3037 header[4+5] = wd->macAddr[0];
3038 header[4+6] = wd->macAddr[1];
3039 if (wd->wlanMode == ZM_MODE_AP)
3041 header[4+7] = wd->macAddr[2] + (vap<<8);
3045 header[4+7] = wd->macAddr[2];
3048 /* Sequence Control */
3049 zmw_enter_critical_section(dev);
3050 header[4+11] = ((wd->mmseq++)<<4);
3051 zmw_leave_critical_section(dev);
3058 u16_t zfAggProcessAction(zdev_t* dev, zbuf_t* buf)
3062 //zmw_get_wlan_dev(dev);
3064 //zmw_declare_for_critical_section();
3066 category = zmw_rx_buf_readb(dev, buf, 24);
3070 case ZM_WLAN_BLOCK_ACK_ACTION_FRAME:
3071 zfAggBlockAckActionFrame(dev, buf);
3080 u16_t zfAggBlockAckActionFrame(zdev_t* dev, zbuf_t* buf)
3084 //zmw_get_wlan_dev(dev);
3086 //zmw_declare_for_critical_section();
3088 action = zmw_rx_buf_readb(dev, buf, 25);
3089 #ifdef ZM_ENABLE_AGGREGATION
3092 case ZM_WLAN_ADDBA_REQUEST_FRAME:
3093 zm_msg0_agg(ZM_LV_0, "Received BA Action frame is ADDBA request");
3094 zfAggRecvAddbaRequest(dev, buf);
3096 case ZM_WLAN_ADDBA_RESPONSE_FRAME:
3097 zm_msg0_agg(ZM_LV_0, "Received BA Action frame is ADDBA response");
3098 zfAggRecvAddbaResponse(dev, buf);
3100 case ZM_WLAN_DELBA_FRAME:
3101 zfAggRecvDelba(dev, buf);
3108 u16_t zfAggRecvAddbaRequest(zdev_t* dev, zbuf_t* buf)
3111 struct aggBaFrameParameter bf;
3113 //zmw_get_wlan_dev(dev);
3115 //zmw_declare_for_critical_section();
3118 bf.dialog = zmw_rx_buf_readb(dev, buf, 26);
3122 bf.ba_parameter = zmw_rx_buf_readh(dev, buf, 27);
3123 bf.ba_policy = (bf.ba_parameter >> 1) & 1;
3124 bf.tid = (bf.ba_parameter >> 2) & 0xF;
3125 bf.buffer_size = (bf.ba_parameter >> 6);
3129 bf.ba_timeout = zmw_rx_buf_readh(dev, buf, 29);
3131 * BA starting sequence number
3133 bf.ba_start_seq = zmw_rx_buf_readh(dev, buf, 31) >> 4;
3137 zm_debug_msg2("Recv ADDBA Req:", zmw_rx_buf_readb(dev,buf,i));
3141 zfAggSendAddbaResponse(dev, &bf);
3143 zfAggAddbaSetTidRx(dev, buf, &bf);
3148 u16_t zfAggAddbaSetTidRx(zdev_t* dev, zbuf_t* buf, struct aggBaFrameParameter *bf)
3150 u16_t i, ac, aid, fragOff;
3154 struct agg_tid_rx *tid_rx = NULL;
3156 zmw_get_wlan_dev(dev);
3158 zmw_declare_for_critical_section();
3160 src[0] = zmw_rx_buf_readh(dev, buf, offset+10);
3161 src[1] = zmw_rx_buf_readh(dev, buf, offset+12);
3162 src[2] = zmw_rx_buf_readh(dev, buf, offset+14);
3163 aid = zfApFindSta(dev, src);
3165 zfTxGetIpTosAndFrag(dev, buf, &up, &fragOff);
3166 ac = zcUpToAc[up&0x7] & 0x3;
3170 for (i=0; i<ZM_AGG_POOL_SIZE ; i++)
3172 if((wd->tid_rx[i]->aid == aid) && (wd->tid_rx[i]->ac == ac))
3174 tid_rx = wd->tid_rx[i];
3181 for (i=0; i<ZM_AGG_POOL_SIZE; i++)
3183 if (wd->tid_rx[i]->aid == ZM_MAX_STA_SUPPORT)
3185 tid_rx = wd->tid_rx[i];
3193 zmw_enter_critical_section(dev);
3197 tid_rx->addBaExchangeStatusCode = ZM_AGG_ADDBA_RESPONSE;
3198 tid_rx->seq_start = bf->ba_start_seq;
3199 tid_rx->baw_head = tid_rx->baw_tail = 0;
3200 tid_rx->sq_exceed_count = tid_rx->sq_behind_count = 0;
3201 zmw_leave_critical_section(dev);
3206 u16_t zfAggRecvAddbaResponse(zdev_t* dev, zbuf_t* buf)
3210 struct aggBaFrameParameter bf;
3212 zmw_get_wlan_dev(dev);
3214 //zmw_declare_for_critical_section();
3216 src[0] = zmw_rx_buf_readh(dev, buf, 10);
3217 src[1] = zmw_rx_buf_readh(dev, buf, 12);
3218 src[2] = zmw_rx_buf_readh(dev, buf, 14);
3220 if (wd->wlanMode == ZM_MODE_AP)
3221 aid = zfApFindSta(dev, src);
3225 bf.dialog = zmw_rx_buf_readb(dev, buf, 26);
3226 bf.status_code = zmw_rx_buf_readh(dev, buf, 27);
3227 if (!bf.status_code)
3229 wd->addbaComplete=1;
3235 bf.ba_parameter = zmw_rx_buf_readh(dev, buf, 29);
3236 bf.ba_policy = (bf.ba_parameter >> 1) & 1;
3237 bf.tid = (bf.ba_parameter >> 2) & 0xF;
3238 bf.buffer_size = (bf.ba_parameter >> 6);
3242 bf.ba_timeout = zmw_rx_buf_readh(dev, buf, 31);
3246 zm_debug_msg2("Recv ADDBA Rsp:", zmw_rx_buf_readb(dev,buf,i));
3250 ac = zcUpToAc[bf.tid&0x7] & 0x3;
3252 //zmw_enter_critical_section(dev);
3254 //wd->aggSta[aid].aggFlag[ac] = 0;
3256 //zmw_leave_critical_section(dev);
3261 u16_t zfAggRecvDelba(zdev_t* dev, zbuf_t* buf)
3263 //zmw_get_wlan_dev(dev);
3265 //zmw_declare_for_critical_section();
3269 u16_t zfAggSendAddbaResponse(zdev_t* dev, struct aggBaFrameParameter *bf)
3272 //u16_t addrTblSize;
3273 //struct zsAddrTbl addrTbl;
3277 u16_t header[(24+25+1)/2];
3283 //zmw_get_wlan_dev(dev);
3285 //zmw_declare_for_critical_section();
3289 * TBD : Maximum size of management frame
3291 if ((buf = zfwBufAllocate(dev, 1024)) == NULL)
3293 zm_msg0_mm(ZM_LV_0, "Alloc mm buf Fail!");
3298 * Reserve room for wlan header
3303 * add addba frame body
3305 offset = zfAggSetAddbaResponseFrameBody(dev, buf, bf, offset);
3308 zfwBufSetSize(dev, buf, offset);
3314 dst[0] = zmw_rx_buf_readh(dev, bf->buf, 10);
3315 dst[1] = zmw_rx_buf_readh(dev, bf->buf, 12);
3316 dst[2] = zmw_rx_buf_readh(dev, bf->buf, 14);
3317 zfAggGenAddbaHeader(dev, dst, header, offset-hlen, buf, vap, encrypt);
3318 for (i=0; i<(hlen>>1); i++)
3320 zmw_tx_buf_writeh(dev, buf, i*2, header[i]);
3323 /* Get buffer DMA address */
3324 //if ((addrTblSize = zfwBufMapDma(dev, buf, &addrTbl)) == 0)
3325 //if ((addrTblSize = zfwMapTxDma(dev, buf, &addrTbl)) == 0)
3330 //zm_msg2_mm(ZM_LV_2, "offset=", offset);
3331 //zm_msg2_mm(ZM_LV_2, "hlen=", hlen);
3332 //zm_msg2_mm(ZM_LV_2, "addrTblSize=", addrTblSize);
3333 //zm_msg2_mm(ZM_LV_2, "addrTbl.len[0]=", addrTbl.len[0]);
3334 //zm_msg2_mm(ZM_LV_2, "addrTbl.physAddrl[0]=", addrTbl.physAddrl[0]);
3335 //zm_msg2_mm(ZM_LV_2, "buf->data=", buf->data);
3338 if ((err = zfHpSend(dev, NULL, 0, NULL, 0, NULL, 0, buf, 0,
3339 ZM_INTERNAL_ALLOC_BUF, 0, 0xff)) != ZM_SUCCESS)
3344 zfPutVmmq(dev, buf);
3348 //zfAggSendAddbaRequest(dev, dst, zcUpToAc[bf->tid&0x7] & 0x3, bf->tid);
3353 u16_t zfAggSetAddbaResponseFrameBody(zdev_t* dev, zbuf_t* buf,
3354 struct aggBaFrameParameter *bf, u16_t offset)
3357 //zmw_get_wlan_dev(dev);
3359 //zmw_declare_for_critical_section();
3361 * ADDBA Request frame body
3367 zmw_tx_buf_writeb(dev, buf, offset++, 3);
3369 * Action details = 0
3371 zmw_tx_buf_writeb(dev, buf, offset++, ZM_WLAN_ADDBA_RESPONSE_FRAME);
3373 * Dialog Token = nonzero
3375 zmw_tx_buf_writeb(dev, buf, offset++, bf->dialog);
3379 zmw_tx_buf_writeh(dev, buf, offset, 0);
3382 * Block Ack parameter set
3383 * BA policy = 1 for immediate BA, 0 for delayed BA
3384 * TID(4bits) & buffer size(4bits) (TID=0x1 & buffer size=0x80)
3385 * TBD: how to get TID number and buffer size?
3386 * ¢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¢{
3387 * ¢x B0 ¢x B1 ¢x B2 B5 ¢x B6 B15 ¢x
3388 * ¢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
3389 * ¢x Reserved ¢x BA policy ¢x TID ¢x Buffer size ¢x
3390 * ¢|¢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¢}
3392 zmw_tx_buf_writeh(dev, buf, offset, bf->ba_parameter);
3397 zmw_tx_buf_writeh(dev, buf, offset, bf->ba_timeout);
3403 void zfAggInvokeBar(zdev_t* dev, TID_TX tid_tx)
3405 struct aggBarControl aggBarControl;
3406 //zmw_get_wlan_dev(dev);
3408 //zmw_declare_for_critical_section();
3409 //bar_control = aggBarControl->tid_info << 12 | aggBarControl->compressed_bitmap << 2
3410 // | aggBarControl->multi_tid << 1 | aggBarControl->bar_ack_policy;
3411 aggBarControl.bar_ack_policy = 0;
3412 aggBarControl.multi_tid = 0;
3413 aggBarControl.compressed_bitmap = 0;
3414 aggBarControl.tid_info = tid_tx->tid;
3415 zfAggSendBar(dev, tid_tx, &aggBarControl);
3421 * zfAggSendBar() refers zfAggSendAddbaRequest()
3423 u16_t zfAggSendBar(zdev_t* dev, TID_TX tid_tx, struct aggBarControl *aggBarControl)
3426 //u16_t addrTblSize;
3427 //struct zsAddrTbl addrTbl;
3430 u16_t hlen = 16+8; /* mac header + control headers*/
3431 u16_t header[(8+24+1)/2];
3436 //zmw_get_wlan_dev(dev);
3438 //zmw_declare_for_critical_section();
3442 * TBD : Maximum size of management frame
3444 if ((buf = zfwBufAllocate(dev, 1024)) == NULL)
3446 zm_msg0_mm(ZM_LV_0, "Alloc mm buf Fail!");
3451 * Reserve room for wlan header
3456 * add addba frame body
3458 offset = zfAggSetBarBody(dev, buf, offset, tid_tx, aggBarControl);
3461 zfwBufSetSize(dev, buf, offset);
3466 zfAggGenBarHeader(dev, tid_tx->dst, header, offset-hlen, buf, vap, encrypt);
3467 for (i=0; i<(hlen>>1); i++)
3469 zmw_tx_buf_writeh(dev, buf, i*2, header[i]);
3472 /* Get buffer DMA address */
3473 //if ((addrTblSize = zfwBufMapDma(dev, buf, &addrTbl)) == 0)
3474 //if ((addrTblSize = zfwMapTxDma(dev, buf, &addrTbl)) == 0)
3479 //zm_msg2_mm(ZM_LV_2, "offset=", offset);
3480 //zm_msg2_mm(ZM_LV_2, "hlen=", hlen);
3481 //zm_msg2_mm(ZM_LV_2, "addrTblSize=", addrTblSize);
3482 //zm_msg2_mm(ZM_LV_2, "addrTbl.len[0]=", addrTbl.len[0]);
3483 //zm_msg2_mm(ZM_LV_2, "addrTbl.physAddrl[0]=", addrTbl.physAddrl[0]);
3484 //zm_msg2_mm(ZM_LV_2, "buf->data=", buf->data);
3487 if ((err = zfHpSend(dev, NULL, 0, NULL, 0, NULL, 0, buf, 0,
3488 ZM_INTERNAL_ALLOC_BUF, 0, 0xff)) != ZM_SUCCESS)
3493 zfPutVmmq(dev, buf);
3501 u16_t zfAggSetBarBody(zdev_t* dev, zbuf_t* buf, u16_t offset, TID_TX tid_tx, struct aggBarControl *aggBarControl)
3503 u16_t bar_control, start_seq;
3505 //zmw_get_wlan_dev(dev);
3507 //zmw_declare_for_critical_section();
3509 * BAR Control frame body
3514 * ¢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¢{
3515 * ¢x B0 ¢x B1 ¢x B2 ¢x B3 B11 ¢x B12 B15 ¢x
3516 * ¢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
3517 * ¢x BAR Ack ¢x Multi-TID ¢x Compressed ¢x Reserved ¢x TID_INFO ¢x
3518 * ¢x Policy ¢x ¢x Bitmap ¢x ¢x ¢x
3519 * ¢|¢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¢}
3521 bar_control = aggBarControl->tid_info << 12 | aggBarControl->compressed_bitmap << 2
3522 | aggBarControl->multi_tid << 1 | aggBarControl->bar_ack_policy;
3524 zmw_tx_buf_writeh(dev, buf, offset, bar_control);
3526 if (0 == aggBarControl->multi_tid) {
3528 * BA starting sequence number
3529 * ¢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¢{
3530 * ¢x B0 B3 ¢x B4 B15 ¢x
3531 * ¢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
3532 * ¢x Frag num(0) ¢x BA starting seq num ¢x
3533 * ¢|¢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¢}
3535 start_seq = (tid_tx->bar_ssn << 4) & 0xFFF0;
3536 zmw_tx_buf_writeh(dev, buf, offset, start_seq);
3539 if (1 == aggBarControl->multi_tid && 1 == aggBarControl->compressed_bitmap) {
3540 /* multi-tid BlockAckReq variant, not implemented*/
3546 u16_t zfAggGenBarHeader(zdev_t* dev, u16_t* dst,
3547 u16_t* header, u16_t len, zbuf_t* buf, u16_t vap, u8_t encrypt)
3549 u8_t hlen = 16+8; // MAC ctrl + PHY ctrl + 802.11 MM header
3550 //u8_t frameType = ZM_WLAN_FRAME_TYPE_ACTION;
3552 zmw_get_wlan_dev(dev);
3554 zmw_declare_for_critical_section();
3557 * Generate control setting
3559 //bodyLen = zfwBufGetSize(dev, buf);
3560 header[0] = 16+len+4; //Length
3561 header[1] = 0x8; //MAC control, backoff + (ack)
3565 header[2] = 0x0f00; //PHY control L
3566 header[3] = 0x0000; //PHY control H
3569 header[2] = 0x0f01; //PHY control L
3570 header[3] = 0x000B; //PHY control H
3574 * Generate WLAN header
3575 * Frame control frame type and subtype
3577 header[4+0] = ZM_WLAN_FRAME_TYPE_BAR;
3583 /* Address 1 = DA */
3584 header[4+2] = dst[0];
3585 header[4+3] = dst[1];
3586 header[4+4] = dst[2];
3588 /* Address 2 = SA */
3589 header[4+5] = wd->macAddr[0];
3590 header[4+6] = wd->macAddr[1];
3591 if (wd->wlanMode == ZM_MODE_AP)
3593 #ifdef ZM_VAPMODE_MULTILE_SSID
3594 header[4+7] = wd->macAddr[2]; //Multiple SSID
3596 header[4+7] = wd->macAddr[2] + (vap<<8); //VAP
3601 header[4+7] = wd->macAddr[2];
3604 /* Sequence Control */
3605 zmw_enter_critical_section(dev);
3606 header[4+11] = ((wd->mmseq++)<<4);
3607 zmw_leave_critical_section(dev);