GUI: Fix Tomato RAF theme for all builds. Compilation typo.
[tomato.git] / release / src-rt-6.x.4708 / linux / linux-2.6.36 / drivers / staging / otus / 80211core / cagg.c
blob84b1e977104f0a0c3d8a294c8259ab2dcab47953
1 /*
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.
16 /* */
17 /* Module Name : cagg.c */
18 /* */
19 /* Abstract */
20 /* This module contains A-MPDU aggregation related functions. */
21 /* */
22 /* NOTES */
23 /* None */
24 /* */
25 /************************************************************************/
27 #include "cprecomp.h"
29 extern u8_t zcUpToAc[8];
30 const u8_t pri[] = {3,3,2,3,2,1,3,2,1,0};
33 u16_t aggr_count;
34 u32_t success_mpdu;
35 u32_t total_mpdu;
37 void zfAggInit(zdev_t* dev)
39 u16_t i,j;
41 zmw_get_wlan_dev(dev);
43 zmw_declare_for_critical_section();
45 * reset sta information
48 zmw_enter_critical_section(dev);
49 wd->aggInitiated = 0;
50 wd->addbaComplete = 0;
51 wd->addbaCount = 0;
52 wd->reorder = 1;
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
68 wd->aggState = 0;
69 for (i=0; i<ZM_AGG_POOL_SIZE; i++)
72 * reset tx aggregation queue
74 wd->aggQPool[i] = zfwMemAllocate(dev, sizeof(struct aggQueue));
75 if(!wd->aggQPool[i])
77 zmw_leave_critical_section(dev);
78 return;
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));
89 if (!wd->tid_rx[i])
91 zmw_leave_critical_section(dev);
92 return;
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
102 * 0: NULL
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;
114 DESTQ.init(dev);
115 wd->aggInitiated = 1;
116 aggr_count = 0;
117 success_mpdu = 0;
118 total_mpdu = 0;
119 #ifdef ZM_ENABLE_AGGREGATION
120 #ifndef ZM_ENABLE_FW_BA_RETRANSMISSION //disable BAW
121 BAW = zfwMemAllocate(dev, sizeof(struct baw_enabler));
122 if(!BAW)
124 return;
126 BAW->init = zfBawInit;
127 BAW->init(dev);
128 #endif //disable BAW
129 #endif
132 /************************************************************************/
133 /* */
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. */
138 /* */
139 /* INPUTS */
140 /* dev : device pointer */
141 /* buf : buffer for one particular packet */
142 /* */
143 /* OUTPUTS */
144 /* AID */
145 /* */
146 /* AUTHOR */
147 /* Honda ZyDAS Technology Corporation 2006.11 */
148 /* */
149 /************************************************************************/
153 u16_t zfAggGetSta(zdev_t* dev, zbuf_t* buf)
155 u16_t id;
156 u16_t dst[3];
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);
171 else {
172 id = 0;
174 zmw_leave_critical_section(dev);
176 #if ZM_AGG_FPGA_DEBUG
177 id = 0;
178 #endif
180 return id;
184 /************************************************************************/
185 /* */
186 /* FUNCTION DESCRIPTION zfAggTxGetQueue */
187 /* return Queue Pool index. */
188 /* take aid as input, look for the queue index associated */
189 /* with this aid. */
190 /* */
191 /* INPUTS */
192 /* dev : device pointer */
193 /* aid : associated id */
194 /* */
195 /* OUTPUTS */
196 /* Queue number */
197 /* */
198 /* AUTHOR */
199 /* Honda ZyDAS Technology Corporation 2006.11 */
200 /* */
201 /************************************************************************/
202 TID_TX zfAggTxGetQueue(zdev_t* dev, u16_t aid, u16_t tid)
204 //u16_t i;
205 TID_TX tid_tx;
206 zmw_get_wlan_dev(dev);
208 //zmw_declare_for_critical_section();
211 * not a STA aid
213 if (0xffff == aid)
214 return NULL;
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)
221 return NULL;
223 //zmw_leave_critical_section(dev);
225 return tid_tx;
228 /************************************************************************/
229 /* */
230 /* FUNCTION DESCRIPTION zfAggTxNewQueue */
231 /* return Queue Pool index. */
232 /* take aid as input, find a new queue for this aid. */
233 /* */
234 /* INPUTS */
235 /* dev : device pointer */
236 /* aid : associated id */
237 /* */
238 /* OUTPUTS */
239 /* Queue number */
240 /* */
241 /* AUTHOR */
242 /* Honda ZyDAS Technology Corporation 2006.12 */
243 /* */
244 /************************************************************************/
245 TID_TX zfAggTxNewQueue(zdev_t* dev, u16_t aid, u16_t tid, zbuf_t* buf)
247 u16_t i;
248 TID_TX tid_tx=NULL;
249 u16_t ac = zcUpToAc[tid&0x7] & 0x3;
250 zmw_get_wlan_dev(dev);
252 zmw_declare_for_critical_section();
255 * not a STA aid
257 if (0xffff == aid)
258 return NULL;
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)
270 * this q is enabled
273 else
275 tid_tx = wd->aggQPool[i];
276 tid_tx->aggQEnabled = 1;
277 tid_tx->aggQSTA = aid;
278 tid_tx->ac = ac;
279 tid_tx->tid = tid;
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);
286 break;
290 zmw_leave_critical_section(dev);
292 return tid_tx;
297 /************************************************************************/
298 /* */
299 /* FUNCTION DESCRIPTION zfAggTxEnqueue */
300 /* return Status code ZM_SUCCESS or error code */
301 /* take (aid,ac,qnum,buf) as input */
302 /* */
303 /* INPUTS */
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 */
309 /* */
310 /* OUTPUTS */
311 /* status code */
312 /* */
313 /* AUTHOR */
314 /* Honda Atheros Communications, INC. 2006.12 */
315 /* */
316 /************************************************************************/
317 u16_t zfAggTxEnqueue(zdev_t* dev, zbuf_t* buf, u16_t aid, TID_TX tid_tx)
319 //u16_t qlen, frameLen;
320 u32_t time;
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))
332 /* Queue not full */
336 * buffer copy
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;
350 tid_tx->size++;
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;
354 sendComplete = 1;
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);
373 return ZM_SUCCESS;
375 else
377 zm_msg1_agg(ZM_LV_0, "can't enqueue, tid_tx->size=", tid_tx->size);
379 * Queue Full
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) {
402 struct dest* dest;
403 u16_t exist = 0;
404 zmw_get_wlan_dev(dev);
406 zmw_declare_for_critical_section();
408 zmw_enter_critical_section(dev);
409 if (!DESTQ.Head[ac]) {
410 exist = 0;
412 else {
413 dest = DESTQ.Head[ac];
414 if (dest->tid_tx == tid_tx) {
415 exist = 1;
417 else {
418 while (dest->next != DESTQ.Head[ac]) {
419 dest = dest->next;
420 if (dest->tid_tx == tid_tx){
421 exist = 1;
422 break;
428 zmw_leave_critical_section(dev);
430 return exist;
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));
441 if(!new_dest)
443 return;
445 new_dest->Qtype = Qtype;
446 new_dest->tid_tx = tid_tx;
447 if (0 == Qtype)
448 new_dest->tid_tx = tid_tx;
449 else
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);
458 else {
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);
467 //DESTQ.size[ac]++;
468 return;
471 void zfAggDestDelete(zdev_t* dev, u16_t Qtype, TID_TX tid_tx, void* vtxq)
473 struct dest* dest, *temp;
474 u16_t i;
476 zmw_get_wlan_dev(dev);
478 zmw_declare_for_critical_section();
480 zmw_enter_critical_section(dev);
481 if (wd->destLock) {
482 zmw_leave_critical_section(dev);
483 return;
487 //zmw_declare_for_critical_section();
488 for (i=0; i<4; i++) {
489 if (!DESTQ.Head[i]) continue;
490 dest = DESTQ.Head[i];
491 if (!dest) continue;
494 while (dest && (dest->next != DESTQ.Head[i])) {
495 if (Qtype == 0 && dest->next->tid_tx == tid_tx){
496 break;
498 if (Qtype == 1 && dest->next->vtxq == vtxq) {
499 break;
501 dest = dest->next;
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);
507 if (tid_tx->size) {
508 zmw_leave_critical_section(dev);
509 return;
511 if (!DESTQ.Head[i]) {
512 temp = NULL;
514 else {
515 temp = dest->next;
516 if (temp == dest) {
517 DESTQ.Head[i] = DESTQ.dest[i] = NULL;
518 //DESTQ.size[i] = 0;
520 else {
521 dest->next = dest->next->next;
525 if (temp == NULL)
526 {/* do nothing */} //zfwMemFree(dev, temp, sizeof(struct dest));
527 else
528 zfwMemFree(dev, temp, sizeof(struct dest));
530 /*zmw_enter_critical_section(dev);
531 if (DESTQ.size[i] > 0)
532 DESTQ.size[i]--;
533 zmw_leave_critical_section(dev);
538 zmw_leave_critical_section(dev);
539 return;
542 void zfAggDestInit(zdev_t* dev)
544 u16_t i;
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];
552 //DESTQ.size[i] = 0;
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;
560 DESTQ.ppri = 0;
561 return;
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;
576 else {
577 dest = NULL;
579 zmw_leave_critical_section(dev);
581 return dest;
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)
588 zbuf_t* buf;
589 u32_t time;
590 struct baw_header *baw_header;
592 zmw_get_wlan_dev(dev);
594 zmw_declare_for_critical_section();
597 buf = buf_info->buf;
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);
605 return 0;
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);
625 tid_tx->size++;
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);
637 return TRUE;
639 #endif //disable BAW
640 #endif
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);
655 return;
658 TID_TX zfAggTxReady(zdev_t* dev) {
659 //struct dest* dest;
660 u16_t i;
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];
673 break;
676 else {
679 zmw_leave_critical_section(dev);
680 return tid_tx;
683 u16_t zfAggValidTidTx(zdev_t* dev, TID_TX tid_tx) {
684 u16_t i, valid = 0;
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)
694 valid = 1;
695 break;
697 else {
700 zmw_leave_critical_section(dev);
702 return valid;
705 void zfAggTxScheduler(zdev_t* dev, u8_t ScanAndClear)
707 TID_TX tid_tx = NULL;
708 void* vtxq;
709 struct dest* dest;
710 zbuf_t* buf;
711 u32_t txql, min_txql;
712 //u16_t aggr_size = 1;
713 u16_t txq_threshold;
714 zmw_get_wlan_dev(dev);
716 zmw_declare_for_critical_section();
718 if (!wd->aggInitiated)
720 return;
723 /* debug */
724 txql = TXQL;
725 min_txql = AGG_MIN_TXQL;
727 if(wd->txq_threshold)
728 txq_threshold = wd->txq_threshold;
729 else
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) {
737 u16_t i;
738 u8_t ac;
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);
759 if (i == 10) break;
760 //DbgPrint("zfAggTxScheduler: have dest Q");
761 zmw_enter_critical_section(dev);
762 wd->destLock = 1;
763 zmw_leave_critical_section(dev);
765 dest = DESTQ.getNext(dev, ac);
766 if (!dest) {
767 zmw_enter_critical_section(dev);
768 wd->destLock = 0;
769 zmw_leave_critical_section(dev);
771 DbgPrint("bug report! DESTQ.getNext got nothing!");
772 break;
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);
781 else {
782 zmw_enter_critical_section(dev);
783 wd->destLock = 0;
784 zmw_leave_critical_section(dev);
786 tid_tx = zfAggTxReady(dev);
787 continue;
790 zmw_enter_critical_section(dev);
791 wd->destLock = 0;
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){
800 //wd->aggState = 1;
801 //zmw_leave_critical_section(dev);
802 zfAggTxSend(dev, zfHpGetFreeTxdCount(dev), tid_tx);
803 //wd->aggState = 0;
805 else {
806 //zmw_leave_critical_section(dev);
807 break;
810 else {
811 vtxq = dest->vtxq;
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) {
825 destQ_count = 0;
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;
834 if (i == 10) break;
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);
839 if (!tid_tx->size) {
840 wd->destQ.delete(dev, 0, tid_tx, NULL);
841 break;
843 else if((wd->aggState == 0) && (tid_tx->size >= 16)){
844 zfAggTxSend(dev, zfHpGetFreeTxdCount(dev), tid_tx);
846 else {
847 break;
853 return;
856 /************************************************************************/
857 /* */
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 */
865 /* */
866 /* INPUTS */
867 /* dev : device pointer */
868 /* buf : packet buff */
869 /* ac : access category */
870 /* */
871 /* OUTPUTS */
872 /* status code */
873 /* */
874 /* AUTHOR */
875 /* Honda Atheros Communications, INC. 2006.12 */
876 /* */
877 /************************************************************************/
878 u16_t zfAggTx(zdev_t* dev, zbuf_t* buf, u16_t tid)
880 u16_t aid;
881 //u16_t qnum;
882 //u16_t aggflag = 0;
883 //u16_t arrivalrate = 0;
884 TID_TX tid_tx;
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);
899 if (0xffff == aid)
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);
918 if (tid_tx != NULL)
921 * this (aid, ac) is aggregated
924 //if (arrivalrate < ZM_AGG_LOW_THRESHOLD)
925 if (0)
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);
943 else
946 * this (aid, ac) not yet aggregated
947 * queue not found
950 //if (arrivalrate > ZM_AGG_HIGH_THRESHOLD)
951 if (1)
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->);
961 if (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);
989 else
992 * just can't get a new aggregate queue
995 return ZM_ERR_TX_BUFFER_UNAVAILABLE;
998 else
1001 * arrival rate is not high enough to get a new agg queue
1004 return ZM_ERR_TX_BUFFER_UNAVAILABLE;
1013 /************************************************************************/
1014 /* */
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. */
1019 /* */
1020 /* INPUTS */
1021 /* dev : device pointer */
1022 /* ac : access category */
1023 /* */
1024 /* OUTPUTS */
1025 /* counter of ready to aggregate queues */
1026 /* */
1027 /* AUTHOR */
1028 /* Honda Atheros Communications, INC. 2006.12 */
1029 /* */
1030 /************************************************************************/
1031 u16_t zfAggTxReadyCount(zdev_t* dev, u16_t ac)
1033 u16_t i;
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)
1046 readycount++;
1049 zmw_leave_critical_section(dev);
1051 return readycount;
1054 /************************************************************************/
1055 /* */
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 */
1061 /* */
1062 /* INPUTS */
1063 /* dev : device pointer */
1064 /* ac : access category */
1065 /* readycount: the number of ready to aggregate queues of this ac */
1066 /* */
1067 /* OUTPUTS */
1068 /* Vtxq length * ratio */
1069 /* */
1070 /* AUTHOR */
1071 /* Honda Atheros Communications, INC. 2006.12 */
1072 /* */
1073 /************************************************************************/
1074 u16_t zfAggTxPartial(zdev_t* dev, u16_t ac, u16_t readycount)
1076 u16_t qlen;
1077 u16_t partial;
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 + \
1090 readycount)) );
1092 else
1094 partial = 0;
1097 zmw_leave_critical_section(dev);
1099 if (partial > qlen)
1100 partial = qlen;
1102 return partial;
1106 /************************************************************************/
1107 /* */
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. */
1112 /* */
1113 /* INPUTS */
1114 /* dev : device pointer */
1115 /* ac : access category */
1116 /* n : the number of scheduled aggregation queues to be sent */
1117 /* */
1118 /* OUTPUTS */
1119 /* sentcount */
1120 /* */
1121 /* AUTHOR */
1122 /* Honda Atheros Communications, INC. 2006.12 */
1123 /* */
1124 /************************************************************************/
1125 u16_t zfAggTxSend(zdev_t* dev, u32_t freeTxd, TID_TX tid_tx)
1127 //u16_t qnum;
1128 //u16_t qlen;
1129 u16_t j;
1130 //u16_t sentcount = 0;
1131 zbuf_t* buf;
1132 struct aggControl aggControl;
1133 u16_t aggLen;
1134 //zbuf_t* newBuf;
1135 //u16_t bufLen;
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?
1153 if (aggLen <=0 )
1154 return 0;
1157 if (aggLen == 1) {
1158 buf = zfAggTxGetVtxq(dev, tid_tx);
1159 if (buf)
1160 zfTxSendEth(dev, buf, 0, ZM_EXTERNAL_ALLOC_BUF, 0);
1161 if (tid_tx->size == 0) {
1162 //DESTQ.delete(dev, 0, tid_tx, NULL);
1165 return 1;
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);
1173 return 0;
1175 wd->aggState = 1;
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);
1188 if ( buf ) {
1189 //struct aggTally *agg_tal;
1190 u16_t completeIndex;
1192 if (0 == j) {
1193 aggControl.ampduIndication = ZM_AGG_FIRST_MPDU;
1196 else if ((j == (aggLen - 1)) || tid_tx->size == 0)
1198 aggControl.ampduIndication = ZM_AGG_LAST_MPDU;
1199 //wd->aggState = 0;
1202 else
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;
1212 #ifdef ZM_AGG_TALLY
1213 agg_tal = &wd->agg_tal;
1214 agg_tal->sent_packets_sum++;
1216 #endif
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!");
1233 else {
1235 * this aggregation queue is empty
1237 zm_msg1_agg(ZM_LV_0, "aggLen not reached, but no more frame, j=", j);
1239 break;
1242 zmw_enter_critical_section(dev);
1243 wd->aggState = 0;
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);
1257 if(j>0) {
1258 aggr_count++;
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);
1262 return j;
1266 /************************************************************************/
1267 /* */
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 */
1272 /* set queues. */
1273 /* */
1274 /* INPUTS */
1275 /* dev : device pointer */
1276 /* ac : access category */
1277 /* */
1278 /* OUTPUTS */
1279 /* aggregation queue number */
1280 /* */
1281 /* AUTHOR */
1282 /* Honda Atheros Communications, INC. 2006.12 */
1283 /* */
1284 /************************************************************************/
1285 TID_TX zfAggTxGetReadyQueue(zdev_t* dev, u16_t ac)
1287 //u16_t qnum = ZM_AGG_POOL_SIZE;
1288 u16_t i;
1289 u32_t time = 0;
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);
1314 return tid_tx;
1319 /************************************************************************/
1320 /* */
1321 /* FUNCTION DESCRIPTION zfAggTxGetVtxq */
1322 /* return an MSDU */
1323 /* take (dev, qnum) as input, return an MSDU out of the agg queue. */
1324 /* */
1325 /* INPUTS */
1326 /* dev : device pointer */
1327 /* qnum: queue number */
1328 /* */
1329 /* OUTPUTS */
1330 /* a MSDU */
1331 /* */
1332 /* AUTHOR */
1333 /* Honda Atheros Communications, INC. 2006.12 */
1334 /* */
1335 /************************************************************************/
1336 zbuf_t* zfAggTxGetVtxq(zdev_t* dev, TID_TX tid_tx)
1338 zbuf_t* buf = NULL;
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);
1352 if (NULL == buf) {
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);
1358 else
1361 * queue is empty
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);
1369 return buf;
1373 /************************************************************************/
1374 /* */
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. */
1379 /* */
1380 /* INPUTS */
1381 /* dev : device pointer */
1382 /* qnum: queue number */
1383 /* */
1384 /* OUTPUTS */
1385 /* ZM_SUCCESS */
1386 /* */
1387 /* AUTHOR */
1388 /* Honda Atheros Communications, INC. 2006.12 */
1389 /* */
1390 /************************************************************************/
1391 u16_t zfAggTxDeleteQueue(zdev_t* dev, u16_t qnum)
1393 u16_t ac, tid;
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];
1403 ac = tx_tid->ac;
1404 tid = tx_tid->tid;
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;
1412 tx_tid->size = 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);
1422 return ZM_SUCCESS;
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) {
1428 TID_BAW tid_baw;
1429 s16_t i;
1430 zbuf_t* buf;
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);
1436 //tid_baw = NULL;
1437 if (NULL == tid_baw)
1438 return;
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;
1445 if (buf) {
1446 //wd->zfcbSetBawQ(dev, buf, 0);
1447 zfAggTidTxInsertHead(dev, buf_info, tid_baw->tid_tx);
1450 else {
1451 success_mpdu++;
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) {
1461 TID_BAW tid_baw;
1462 u16_t i,j;
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;
1474 BAW->delPoint = 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;
1489 u16_t i;
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)
1497 break;
1501 tid_baw = &BAW->tid_baw[BAW->delPoint];
1502 i = BAW->delPoint;
1503 //if (ZM_BAW_POOL_SIZE == i) {
1504 //return NULL;
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;
1520 return tid_baw;
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) {
1524 //TID_BAW tid_baw;
1525 //u16_t bufLen;
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;
1547 tid_baw->head++;
1548 tid_baw->size++;
1550 else {
1551 //wd->zfcbSetBawQ(dev, buf, 0);
1552 zfwBufFree(dev, buf, ZM_SUCCESS);
1553 return FALSE;
1555 return TRUE;
1558 struct bufInfo* zfBawPop(zdev_t* dev, u16_t index, TID_BAW tid_baw) {
1559 //TID_BAW tid_baw;
1560 //zbuf_t* buf;
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))
1568 return buf_info;
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;
1577 return buf_info;
1580 void zfBawEnable(zdev_t* dev, TID_BAW tid_baw, u16_t start_seq) {
1581 //TID_BAW tid_baw;
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) {
1592 //TID_BAW tid_baw;
1593 u16_t i;
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;
1611 u16_t i;
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)
1622 break;
1626 if (ZM_BAW_POOL_SIZE == i)
1627 return NULL;
1628 return tid_baw;
1630 #endif //disable BAW
1631 #endif
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;
1650 agg_tal->time = 0;
1651 return 0;
1655 /************************************************************************/
1656 /* */
1657 /* FUNCTION DESCRIPTION zfAggScanAndClear */
1658 /* If the packets in a queue have waited for too long, clear and */
1659 /* delete this aggregation queue. */
1660 /* */
1661 /* INPUTS */
1662 /* dev : device pointer */
1663 /* time : current time */
1664 /* */
1665 /* OUTPUTS */
1666 /* ZM_SUCCESS */
1667 /* */
1668 /* AUTHOR */
1669 /* Honda Atheros Communications, INC. 2006.12 */
1670 /* */
1671 /************************************************************************/
1672 u16_t zfAggScanAndClear(zdev_t* dev, u32_t time)
1674 u16_t i;
1675 u16_t head;
1676 u16_t tail;
1677 u32_t tick;
1678 u32_t arrivalTime;
1679 //u16_t aid, ac;
1680 TID_TX tid_tx;
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)
1725 * queue empty
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);
1744 #ifdef ZM_AGG_TALLY
1745 if((wd->tick % 100) == 0) {
1746 zfAggPrintTally(dev);
1748 #endif
1750 return ZM_SUCCESS;
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);
1766 return 0;
1769 agg_tal->time++;
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);
1793 else
1794 zm_msg1_agg(ZM_LV_0, "1/(BA fail rate)=", wd->commTally.Hw_Tx_MPDU/wd->commTally.BA_Fail);
1796 return 0;
1799 u16_t zfAggRxClear(zdev_t* dev, u32_t time)
1801 u16_t i;
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);
1830 return ZM_SUCCESS;
1833 struct agg_tid_rx* zfAggRxEnabled(zdev_t* dev, zbuf_t* buf)
1835 u16_t dst0, src[3], aid;
1836 u16_t offset = 0;
1837 u16_t seq_no;
1838 u16_t frameType;
1839 u16_t frameCtrl;
1840 u16_t frameSubtype;
1841 //struct aggSta *agg_sta;
1842 #if ZM_AGG_FPGA_REORDERING
1843 struct agg_tid_rx *tid_rx;
1844 #endif
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)
1852 return NULL;
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)
1862 return NULL;
1864 #ifdef ZM_ENABLE_PERFORMANCE_EVALUATION
1866 u32_t tcp_seq;
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);
1874 #endif
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
1883 aid = 0;
1884 #else
1885 aid = zfApFindSta(dev, src);
1886 #endif
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) ;
1899 if(!tid_rx)
1900 return NULL;
1901 else
1903 //if (tid_rx->addBaExchangeStatusCode == ZM_AGG_ADDBA_RESPONSE)
1904 return tid_rx;
1906 #else
1907 return NULL;
1908 #endif
1911 return NULL;
1914 u16_t zfAggRx(zdev_t* dev, zbuf_t* buf, struct zsAdditionInfo *addInfo, struct agg_tid_rx *tid_rx)
1916 u16_t seq_no;
1917 s16_t index;
1918 u16_t offset = 0;
1919 zbuf_t* pbuf;
1920 u8_t frameSubType;
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;
1934 * for debug
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)
1953 s16_t seq_diff;
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)
1973 //index += 4096;
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);
2001 else {
2002 zfiRecv80211(dev, buf, addInfo);
2005 else if (!zfAggRxEnqueue(dev, buf, tid_rx, addInfo))
2008 * duplicated packet
2010 return 1;
2013 while (tid_rx->baw_head != tid_rx->baw_tail) {// && tid_rx->frame[tid_rx->baw_tail].buf)
2014 u16_t tailIndex;
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;
2021 if (!pbuf)
2023 zmw_leave_critical_section(dev);
2024 break;
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);
2045 else
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);
2053 return 1;
2056 struct agg_tid_rx *zfAggRxGetQueue(zdev_t* dev, zbuf_t* buf)
2058 u16_t src[3];
2059 u16_t aid, ac, i;
2060 u16_t offset = 0;
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];
2082 break;
2086 // mark by spin lock debug
2087 //zmw_leave_critical_section(dev);
2088 return tid_rx;
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;
2095 u16_t q_index;
2096 s16_t index;
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
2112 bdropframe = 0;
2113 if (tid_rx->seq_start > seq_no) {
2114 if ((tid_rx->seq_start > 3967) && (seq_no < 128)) {
2115 index += 4096;
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;
2121 } else {
2122 bdropframe = 1;
2124 zmw_leave_critical_section(dev);
2125 } else {
2126 bdropframe = 1;
2128 } else {
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;
2134 } else {
2135 bdropframe = 1;
2137 zmw_leave_critical_section(dev);
2141 if (bdropframe == 1) {
2142 /*if (wd->zfcbRecv80211 != NULL) {
2143 wd->zfcbRecv80211(dev, buf, addInfo);
2145 else {
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
2163 return 0;
2164 } else {
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);
2176 if (index < 0) {
2177 zfAggRxFlush(dev, seq_no, tid_rx);
2178 tid_rx->seq_start = seq_no;
2179 index = 0;
2182 //if (index >= (ZM_AGG_BAW_SIZE - 1))
2183 if (index >= (ZM_AGG_BAW_MASK))
2186 * queue full
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;
2195 index += 4096;
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)
2204 index += 4096;
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);
2220 * duplicate packet
2222 return 0;
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);
2253 * success
2255 //DbgPrint("head=%d, tail=%d, start=%d", tid_rx->baw_head, tid_rx->baw_tail, tid_rx->seq_start);
2256 return 1;
2259 u16_t zfAggRxFlush(zdev_t* dev, u16_t seq_no, struct agg_tid_rx *tid_rx)
2261 zbuf_t* pbuf;
2262 u16_t seq;
2263 struct zsAdditionInfo addInfo;
2264 zmw_get_wlan_dev(dev);
2265 zmw_declare_for_critical_section();
2267 ZM_PERFORMANCE_RX_FLUSH(dev);
2269 while (1)
2271 zmw_enter_critical_section(dev);
2272 if (tid_rx->baw_tail == tid_rx->baw_head) {
2273 zmw_leave_critical_section(dev);
2274 break;
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);
2285 if (pbuf)
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);
2297 else
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);
2309 return 1;
2314 /************************************************************************/
2315 /* */
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. */
2319 /* */
2320 /* INPUTS */
2321 /* dev : device pointer */
2322 /* */
2323 /* OUTPUTS */
2324 /* ZM_SUCCESS */
2325 /* */
2326 /* AUTHOR */
2327 /* Honda Atheros Communications, INC. 2006.12 */
2328 /* */
2329 /************************************************************************/
2330 u16_t zfAggRxFreeBuf(zdev_t* dev, u16_t destroy)
2332 u16_t i;
2333 zbuf_t* buf;
2334 struct agg_tid_rx *tid_rx;
2336 TID_TX tid_tx;
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++)
2344 u16_t j;
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);
2355 if (buf)
2357 zfwBufFree(dev, buf, 0);
2362 zmw_enter_critical_section(dev);
2363 tid_rx->seq_start = 0;
2364 tid_rx->baw_head = tid_rx->baw_tail = 0;
2365 tid_rx->aid = ZM_MAX_STA_SUPPORT;
2366 zmw_leave_critical_section(dev);
2368 #ifdef ZM_ENABLE_AGGREGATION
2369 #ifndef ZM_ENABLE_FW_BA_RETRANSMISSION //disable BAW
2370 if (tid_baw->enabled) {
2371 zm_msg1_agg(ZM_LV_0, "Device down, clear BAW queue:", i);
2372 BAW->disable(dev, tid_baw);
2374 #endif
2375 #endif
2376 if (1 == wd->aggQPool[i]->aggQEnabled) {
2377 tid_tx = wd->aggQPool[i];
2378 buf = zfAggTxGetVtxq(dev, tid_tx);
2379 while (buf) {
2380 zfwBufFree(dev, buf, 0);
2381 buf = zfAggTxGetVtxq(dev, tid_tx);
2385 if(destroy) {
2386 zfwMemFree(dev, wd->aggQPool[i], sizeof(struct aggQueue));
2387 zfwMemFree(dev, wd->tid_rx[i], sizeof(struct agg_tid_rx));
2390 #ifdef ZM_ENABLE_AGGREGATION
2391 #ifndef ZM_ENABLE_FW_BA_RETRANSMISSION //disable BAW
2392 if(destroy) zfwMemFree(dev, BAW, sizeof(struct baw_enabler));
2393 #endif
2394 #endif
2395 return ZM_SUCCESS;
2399 void zfAggRecvBAR(zdev_t* dev, zbuf_t *buf) {
2400 u16_t start_seq, len;
2401 u8_t i, bitmap[8];
2402 len = zfwBufGetSize(dev, buf);
2403 start_seq = zmw_rx_buf_readh(dev, buf, len-2);
2404 DbgPrint("Received a BAR Control frame, start_seq=%d", start_seq>>4);
2405 /* todo: set the bitmap by reordering buffer! */
2406 for (i=0; i<8; i++) bitmap[i]=0;
2407 zfSendBA(dev, start_seq, bitmap);
2410 #ifdef ZM_ENABLE_AGGREGATION
2411 #ifndef ZM_ENABLE_FW_BA_RETRANSMISSION //disable BAW
2412 void zfAggTxRetransmit(zdev_t* dev, struct bufInfo *buf_info, struct aggControl *aggControl, TID_TX tid_tx) {
2413 u16_t removeLen;
2414 u16_t err;
2416 zmw_get_wlan_dev(dev);
2417 if (aggControl && (ZM_AGG_FIRST_MPDU == aggControl->ampduIndication) ) {
2418 tid_tx->bar_ssn = buf_info->baw_header->header[15];
2419 aggControl->tid_baw->start_seq = tid_tx->bar_ssn >> 4;
2420 zm_msg1_agg(ZM_LV_0, "start seq=", tid_tx->bar_ssn >> 4);
2422 buf_info->baw_header->header[4] |= (1 << 11);
2423 if (aggControl && aggControl->aggEnabled) {
2424 //if (wd->enableAggregation==0 && !(buf_info->baw_header->header[6]&0x1))
2426 //if (((buf_info->baw_header->header[2] & 0x3) == 2))
2428 /* Enable aggregation */
2429 buf_info->baw_header->header[1] |= 0x20;
2430 if (ZM_AGG_LAST_MPDU == aggControl->ampduIndication) {
2431 buf_info->baw_header->header[1] |= 0x4000;
2433 else {
2434 buf_info->baw_header->header[1] &= ~0x4000;
2435 //zm_debug_msg0("ZM_AGG_LAST_MPDU");
2438 //else {
2439 // zm_debug_msg1("no aggr, header[2]&0x3 = ",buf_info->baw_header->header[2] & 0x3)
2440 // aggControl->aggEnabled = 0;
2443 //else {
2444 // zm_debug_msg1("no aggr, wd->enableAggregation = ", wd->enableAggregation);
2445 // zm_debug_msg1("no aggr, !header[6]&0x1 = ",!(buf_info->baw_header->header[6]&0x1));
2446 // aggControl->aggEnabled = 0;
2450 /*if (aggControl->tid_baw) {
2451 struct baw_header_r header_r;
2453 header_r.header = buf_info->baw_header->header;
2454 header_r.mic = buf_info->baw_header->mic;
2455 header_r.snap = buf_info->baw_header->snap;
2456 header_r.headerLen = buf_info->baw_header->headerLen;
2457 header_r.micLen = buf_info->baw_header->micLen;
2458 header_r.snapLen = buf_info->baw_header->snapLen;
2459 header_r.removeLen = buf_info->baw_header->removeLen;
2460 header_r.keyIdx = buf_info->baw_header->keyIdx;
2462 BAW->insert(dev, buf_info->buf, tid_tx->bar_ssn >> 4, aggControl->tid_baw, buf_info->baw_retransmit, &header_r);
2465 err = zfHpSend(dev,
2466 buf_info->baw_header->header,
2467 buf_info->baw_header->headerLen,
2468 buf_info->baw_header->snap,
2469 buf_info->baw_header->snapLen,
2470 buf_info->baw_header->mic,
2471 buf_info->baw_header->micLen,
2472 buf_info->buf,
2473 buf_info->baw_header->removeLen,
2474 ZM_EXTERNAL_ALLOC_BUF,
2475 (u8_t)tid_tx->ac,
2476 buf_info->baw_header->keyIdx);
2477 if (err != ZM_SUCCESS)
2479 goto zlError;
2482 return;
2484 zlError:
2485 zfwBufFree(dev, buf_info->buf, 0);
2486 return;
2489 #endif //disable BAW
2490 #endif
2491 /************************************************************************/
2492 /* */
2493 /* FUNCTION DESCRIPTION zfAggTxSendEth */
2494 /* Called to transmit Ethernet frame from upper elayer. */
2495 /* */
2496 /* INPUTS */
2497 /* dev : device pointer */
2498 /* buf : buffer pointer */
2499 /* port : WLAN port, 0=>standard, 0x10-0x17=>VAP, 0x20-0x25=>WDS */
2500 /* */
2501 /* OUTPUTS */
2502 /* error code */
2503 /* */
2504 /* AUTHOR */
2505 /* Stephen, Honda Atheros Communications, Inc. 2006.12 */
2506 /* */
2507 /************************************************************************/
2508 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)
2510 u16_t err;
2511 //u16_t addrTblSize;
2512 //struct zsAddrTbl addrTbl;
2513 u16_t removeLen;
2514 u16_t header[(8+30+2+18)/2]; /* ctr+(4+a1+a2+a3+2+a4)+qos+iv */
2515 u16_t headerLen;
2516 u16_t mic[8/2];
2517 u16_t micLen;
2518 u16_t snap[8/2];
2519 u16_t snapLen;
2520 u16_t fragLen;
2521 u16_t frameLen;
2522 u16_t fragNum;
2523 struct zsFrag frag;
2524 u16_t i, id;
2525 u16_t da[3];
2526 u16_t sa[3];
2527 u8_t up;
2528 u8_t qosType, keyIdx = 0;
2529 u16_t fragOff;
2531 zmw_get_wlan_dev(dev);
2533 zmw_declare_for_critical_section();
2535 zm_msg1_tx(ZM_LV_2, "zfTxSendEth(), port=", port);
2537 /* Get IP TOS for QoS AC and IP frag offset */
2538 zfTxGetIpTosAndFrag(dev, buf, &up, &fragOff);
2540 #ifdef ZM_ENABLE_NATIVE_WIFI
2541 if ( wd->wlanMode == ZM_MODE_INFRASTRUCTURE )
2543 /* DA */
2544 da[0] = zmw_tx_buf_readh(dev, buf, 16);
2545 da[1] = zmw_tx_buf_readh(dev, buf, 18);
2546 da[2] = zmw_tx_buf_readh(dev, buf, 20);
2547 /* SA */
2548 sa[0] = zmw_tx_buf_readh(dev, buf, 10);
2549 sa[1] = zmw_tx_buf_readh(dev, buf, 12);
2550 sa[2] = zmw_tx_buf_readh(dev, buf, 14);
2552 else if ( wd->wlanMode == ZM_MODE_IBSS )
2554 /* DA */
2555 da[0] = zmw_tx_buf_readh(dev, buf, 4);
2556 da[1] = zmw_tx_buf_readh(dev, buf, 6);
2557 da[2] = zmw_tx_buf_readh(dev, buf, 8);
2558 /* SA */
2559 sa[0] = zmw_tx_buf_readh(dev, buf, 10);
2560 sa[1] = zmw_tx_buf_readh(dev, buf, 12);
2561 sa[2] = zmw_tx_buf_readh(dev, buf, 14);
2563 else if ( wd->wlanMode == ZM_MODE_AP )
2565 /* DA */
2566 da[0] = zmw_tx_buf_readh(dev, buf, 4);
2567 da[1] = zmw_tx_buf_readh(dev, buf, 6);
2568 da[2] = zmw_tx_buf_readh(dev, buf, 8);
2569 /* SA */
2570 sa[0] = zmw_tx_buf_readh(dev, buf, 16);
2571 sa[1] = zmw_tx_buf_readh(dev, buf, 18);
2572 sa[2] = zmw_tx_buf_readh(dev, buf, 20);
2574 else
2578 #else
2579 /* DA */
2580 da[0] = zmw_tx_buf_readh(dev, buf, 0);
2581 da[1] = zmw_tx_buf_readh(dev, buf, 2);
2582 da[2] = zmw_tx_buf_readh(dev, buf, 4);
2583 /* SA */
2584 sa[0] = zmw_tx_buf_readh(dev, buf, 6);
2585 sa[1] = zmw_tx_buf_readh(dev, buf, 8);
2586 sa[2] = zmw_tx_buf_readh(dev, buf, 10);
2587 #endif
2588 //Decide Key Index in ATOM, No meaning in OTUS--CWYang(m)
2589 if (wd->wlanMode == ZM_MODE_AP)
2591 keyIdx = wd->ap.bcHalKeyIdx[port];
2592 id = zfApFindSta(dev, da);
2593 if (id != 0xffff)
2595 switch (wd->ap.staTable[id].encryMode)
2597 case ZM_AES:
2598 case ZM_TKIP:
2599 #ifdef ZM_ENABLE_CENC
2600 case ZM_CENC:
2601 #endif //ZM_ENABLE_CENC
2602 keyIdx = wd->ap.staTable[id].keyIdx;
2603 break;
2607 else
2609 switch (wd->sta.encryMode)
2611 case ZM_WEP64:
2612 case ZM_WEP128:
2613 case ZM_WEP256:
2614 keyIdx = wd->sta.keyId;
2615 break;
2616 case ZM_AES:
2617 case ZM_TKIP:
2618 if ((da[0]& 0x1))
2619 keyIdx = 5;
2620 else
2621 keyIdx = 4;
2622 break;
2623 #ifdef ZM_ENABLE_CENC
2624 case ZM_CENC:
2625 keyIdx = wd->sta.cencKeyId;
2626 break;
2627 #endif //ZM_ENABLE_CENC
2631 /* Create SNAP */
2632 removeLen = zfTxGenWlanSnap(dev, buf, snap, &snapLen);
2633 //zm_msg1_tx(ZM_LV_0, "fragOff=", fragOff);
2635 fragLen = wd->fragThreshold;
2636 frameLen = zfwBufGetSize(dev, buf);
2637 frameLen -= removeLen;
2639 if ( frameLen > fragLen )
2641 micLen = zfTxGenWlanTail(dev, buf, snap, snapLen, mic);
2643 else
2645 /* append MIC by HMAC */
2646 micLen = 0;
2649 /* Access Category */
2650 if (wd->wlanMode == ZM_MODE_AP)
2652 zfApGetStaQosType(dev, da, &qosType);
2653 if (qosType == 0)
2655 up = 0;
2658 else if (wd->wlanMode == ZM_MODE_INFRASTRUCTURE)
2660 if (wd->sta.wmeConnected == 0)
2662 up = 0;
2665 else
2667 /* TODO : STA QoS control field */
2668 up = 0;
2671 /* Assign sequence number */
2672 zmw_enter_critical_section(dev);
2673 frag.seq[0] = ((wd->seq[zcUpToAc[up&0x7]]++) << 4);
2674 if (aggControl && (ZM_AGG_FIRST_MPDU == aggControl->ampduIndication) ) {
2675 tid_tx->bar_ssn = frag.seq[0];
2677 zm_msg1_agg(ZM_LV_0, "start seq=", tid_tx->bar_ssn >> 4);
2679 //tid_tx->baw_buf[tid_tx->baw_head-1].baw_seq=frag.seq[0];
2680 zmw_leave_critical_section(dev);
2683 frag.buf[0] = buf;
2684 frag.bufType[0] = bufType;
2685 frag.flag[0] = flag;
2686 fragNum = 1;
2688 for (i=0; i<fragNum; i++)
2690 /* Create WLAN header(Control Setting + 802.11 header + IV) */
2691 if (up !=0 ) zm_debug_msg1("up not 0, up=",up);
2692 headerLen = zfTxGenWlanHeader(dev, frag.buf[i], header, frag.seq[i],
2693 frag.flag[i], snapLen+micLen, removeLen,
2694 port, da, sa, up, &micLen, snap, snapLen,
2695 aggControl);
2697 /* Get buffer DMA address */
2698 //if ((addrTblSize = zfwBufMapDma(dev, frag.buf[i], &addrTbl)) == 0)
2699 //if ((addrTblSize = zfwMapTxDma(dev, frag.buf[i], &addrTbl)) == 0)
2701 // err = ZM_ERR_BUFFER_DMA_ADDR;
2702 // goto zlError;
2705 /* Flush buffer on cache */
2706 //zfwBufFlush(dev, frag.buf[i]);
2709 fragLen = zfwBufGetSize(dev, frag.buf[i]);
2710 if ((da[0]&0x1) == 0)
2712 wd->commTally.txUnicastFrm++;
2713 wd->commTally.txUnicastOctets += (fragLen+snapLen);
2715 else if ((da[0]& 0x1))
2717 wd->commTally.txBroadcastFrm++;
2718 wd->commTally.txBroadcastOctets += (fragLen+snapLen);
2720 else
2722 wd->commTally.txMulticastFrm++;
2723 wd->commTally.txMulticastOctets += (fragLen+snapLen);
2725 wd->ledStruct.txTraffic++;
2728 /*if (aggControl->tid_baw && aggControl->aggEnabled) {
2729 struct baw_header_r header_r;
2731 header_r.header = header;
2732 header_r.mic = mic;
2733 header_r.snap = snap;
2734 header_r.headerLen = headerLen;
2735 header_r.micLen = micLen;
2736 header_r.snapLen = snapLen;
2737 header_r.removeLen = removeLen;
2738 header_r.keyIdx = keyIdx;
2740 BAW->insert(dev, buf, tid_tx->bar_ssn >> 4, aggControl->tid_baw, 0, &header_r);
2743 err = zfHpSend(dev, header, headerLen, snap, snapLen,
2744 mic, micLen, frag.buf[i], removeLen,
2745 frag.bufType[i], zcUpToAc[up&0x7], keyIdx);
2746 if (err != ZM_SUCCESS)
2748 goto zlError;
2752 continue;
2754 zlError:
2755 if (frag.bufType[i] == ZM_EXTERNAL_ALLOC_BUF)
2757 zfwBufFree(dev, frag.buf[i], err);
2759 else if (frag.bufType[i] == ZM_INTERNAL_ALLOC_BUF)
2761 zfwBufFree(dev, frag.buf[i], 0);
2763 else
2765 zm_assert(0);
2767 } /* for (i=0; i<fragNum; i++) */
2769 return ZM_SUCCESS;
2773 * zfAggSendADDBA() refers zfSendMmFrame() in cmm.c
2775 u16_t zfAggSendAddbaRequest(zdev_t* dev, u16_t *dst, u16_t ac, u16_t up)
2777 zbuf_t* buf;
2778 //u16_t addrTblSize;
2779 //struct zsAddrTbl addrTbl;
2780 //u16_t err;
2781 u16_t offset = 0;
2782 u16_t hlen = 32;
2783 u16_t header[(24+25+1)/2];
2784 u16_t vap = 0;
2785 u16_t i;
2786 u8_t encrypt = 0;
2788 //zmw_get_wlan_dev(dev);
2790 //zmw_declare_for_critical_section();
2794 * TBD : Maximum size of management frame
2796 buf = zfwBufAllocate(dev, 1024);
2797 if (buf == NULL)
2799 zm_msg0_mm(ZM_LV_0, "Alloc mm buf Fail!");
2800 return ZM_SUCCESS;
2804 * Reserve room for wlan header
2806 offset = hlen;
2809 * add addba frame body
2811 offset = zfAggSetAddbaFrameBody(dev, buf, offset, ac, up);
2814 zfwBufSetSize(dev, buf, offset);
2817 * Copy wlan header
2819 zfAggGenAddbaHeader(dev, dst, header, offset-hlen, buf, vap, encrypt);
2820 for (i=0; i<(hlen>>1); i++)
2822 zmw_tx_buf_writeh(dev, buf, i*2, header[i]);
2825 /* Get buffer DMA address */
2826 //if ((addrTblSize = zfwBufMapDma(dev, buf, &addrTbl)) == 0)
2827 //if ((addrTblSize = zfwMapTxDma(dev, buf, &addrTbl)) == 0)
2829 // goto zlError;
2832 //zm_msg2_mm(ZM_LV_2, "offset=", offset);
2833 //zm_msg2_mm(ZM_LV_2, "hlen=", hlen);
2834 //zm_msg2_mm(ZM_LV_2, "addrTblSize=", addrTblSize);
2835 //zm_msg2_mm(ZM_LV_2, "addrTbl.len[0]=", addrTbl.len[0]);
2836 //zm_msg2_mm(ZM_LV_2, "addrTbl.physAddrl[0]=", addrTbl.physAddrl[0]);
2837 //zm_msg2_mm(ZM_LV_2, "buf->data=", buf->data);
2839 zfPutVmmq(dev, buf);
2840 zfPushVtxq(dev);
2842 return ZM_SUCCESS;
2846 u16_t zfAggSetAddbaFrameBody(zdev_t* dev, zbuf_t* buf, u16_t offset, u16_t ac, u16_t up)
2848 u16_t ba_parameter, start_seq;
2850 zmw_get_wlan_dev(dev);
2852 //zmw_declare_for_critical_section();
2854 * ADDBA Request frame body
2858 * Category
2860 zmw_tx_buf_writeb(dev, buf, offset++, 3);
2862 * Action details = 0
2864 zmw_tx_buf_writeb(dev, buf, offset++, ZM_WLAN_ADDBA_REQUEST_FRAME);
2866 * Dialog Token = nonzero
2867 * TBD: define how to get dialog token?
2869 zmw_tx_buf_writeb(dev, buf, offset++, 2);
2871 * Block Ack parameter set
2872 * BA policy = 1 for immediate BA, 0 for delayed BA
2873 * TID(4bits) & buffer size(4bits) (TID=up & buffer size=0x80)
2874 * TBD: how to get buffer size?
2875 * ¢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¢{
2876 * ¢x B0 ¢x B1 ¢x B2 B5 ¢x B6 B15 ¢x
2877 * ¢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
2878 * ¢x Reserved ¢x BA policy ¢x TID ¢x Buffer size ¢x
2879 * ¢|¢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¢}
2881 ba_parameter = 1 << 12; // buffer size = 0x40(64)
2882 ba_parameter |= up << 2; // tid = up
2883 ba_parameter |= 2; // ba policy = 1
2884 zmw_tx_buf_writeh(dev, buf, offset, ba_parameter);
2885 offset+=2;
2887 * BA timeout value
2889 zmw_tx_buf_writeh(dev, buf, offset, 0);
2890 offset+=2;
2892 * BA starting sequence number
2893 * ¢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¢{
2894 * ¢x B0 B3 ¢x B4 B15 ¢x
2895 * ¢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
2896 * ¢x Frag num(0) ¢x BA starting seq num ¢x
2897 * ¢|¢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¢}
2899 start_seq = ((wd->seq[ac]) << 4) & 0xFFF0;
2900 zmw_tx_buf_writeh(dev, buf, offset, start_seq);
2901 offset+=2;
2903 return offset;
2906 u16_t zfAggGenAddbaHeader(zdev_t* dev, u16_t* dst,
2907 u16_t* header, u16_t len, zbuf_t* buf, u16_t vap, u8_t encrypt)
2909 u8_t hlen = 32; // MAC ctrl + PHY ctrl + 802.11 MM header
2910 //u8_t frameType = ZM_WLAN_FRAME_TYPE_ACTION;
2912 zmw_get_wlan_dev(dev);
2914 zmw_declare_for_critical_section();
2917 * Generate control setting
2919 //bodyLen = zfwBufGetSize(dev, buf);
2920 header[0] = 24+len+4; //Length
2921 header[1] = 0x8; //MAC control, backoff + (ack)
2923 /* OFDM 6M */
2924 header[2] = 0x0f01; //PHY control L
2925 header[3] = 0x000B; //PHY control H
2928 * Generate WLAN header
2929 * Frame control frame type and subtype
2931 header[4+0] = ZM_WLAN_FRAME_TYPE_ACTION;
2933 * Duration
2935 header[4+1] = 0;
2937 if (wd->wlanMode == ZM_MODE_INFRASTRUCTURE)
2939 header[4+8] = wd->sta.bssid[0];
2940 header[4+9] = wd->sta.bssid[1];
2941 header[4+10] = wd->sta.bssid[2];
2943 else if (wd->wlanMode == ZM_MODE_PSEUDO)
2945 /* Address 3 = 00:00:00:00:00:00 */
2946 header[4+8] = 0;
2947 header[4+9] = 0;
2948 header[4+10] = 0;
2950 else if (wd->wlanMode == ZM_MODE_IBSS)
2952 header[4+8] = wd->sta.bssid[0];
2953 header[4+9] = wd->sta.bssid[1];
2954 header[4+10] = wd->sta.bssid[2];
2956 else if (wd->wlanMode == ZM_MODE_AP)
2958 /* Address 3 = BSSID */
2959 header[4+8] = wd->macAddr[0];
2960 header[4+9] = wd->macAddr[1];
2961 header[4+10] = wd->macAddr[2] + (vap<<8);
2964 /* Address 1 = DA */
2965 header[4+2] = dst[0];
2966 header[4+3] = dst[1];
2967 header[4+4] = dst[2];
2969 /* Address 2 = SA */
2970 header[4+5] = wd->macAddr[0];
2971 header[4+6] = wd->macAddr[1];
2972 if (wd->wlanMode == ZM_MODE_AP)
2974 header[4+7] = wd->macAddr[2] + (vap<<8);
2976 else
2978 header[4+7] = wd->macAddr[2];
2981 /* Sequence Control */
2982 zmw_enter_critical_section(dev);
2983 header[4+11] = ((wd->mmseq++)<<4);
2984 zmw_leave_critical_section(dev);
2987 return hlen;
2991 u16_t zfAggProcessAction(zdev_t* dev, zbuf_t* buf)
2993 u16_t category;
2995 //zmw_get_wlan_dev(dev);
2997 //zmw_declare_for_critical_section();
2999 category = zmw_rx_buf_readb(dev, buf, 24);
3001 switch (category)
3003 case ZM_WLAN_BLOCK_ACK_ACTION_FRAME:
3004 zfAggBlockAckActionFrame(dev, buf);
3005 break;
3009 return ZM_SUCCESS;
3013 u16_t zfAggBlockAckActionFrame(zdev_t* dev, zbuf_t* buf)
3015 u8_t action;
3017 //zmw_get_wlan_dev(dev);
3019 //zmw_declare_for_critical_section();
3021 action = zmw_rx_buf_readb(dev, buf, 25);
3022 #ifdef ZM_ENABLE_AGGREGATION
3023 switch (action)
3025 case ZM_WLAN_ADDBA_REQUEST_FRAME:
3026 zm_msg0_agg(ZM_LV_0, "Received BA Action frame is ADDBA request");
3027 zfAggRecvAddbaRequest(dev, buf);
3028 break;
3029 case ZM_WLAN_ADDBA_RESPONSE_FRAME:
3030 zm_msg0_agg(ZM_LV_0, "Received BA Action frame is ADDBA response");
3031 zfAggRecvAddbaResponse(dev, buf);
3032 break;
3033 case ZM_WLAN_DELBA_FRAME:
3034 zfAggRecvDelba(dev, buf);
3035 break;
3037 #endif
3038 return ZM_SUCCESS;
3041 u16_t zfAggRecvAddbaRequest(zdev_t* dev, zbuf_t* buf)
3043 //u16_t dialog;
3044 struct aggBaFrameParameter bf;
3045 u16_t i;
3046 //zmw_get_wlan_dev(dev);
3048 //zmw_declare_for_critical_section();
3050 bf.buf = buf;
3051 bf.dialog = zmw_rx_buf_readb(dev, buf, 26);
3053 * ba parameter set
3055 bf.ba_parameter = zmw_rx_buf_readh(dev, buf, 27);
3056 bf.ba_policy = (bf.ba_parameter >> 1) & 1;
3057 bf.tid = (bf.ba_parameter >> 2) & 0xF;
3058 bf.buffer_size = (bf.ba_parameter >> 6);
3060 * BA timeout value
3062 bf.ba_timeout = zmw_rx_buf_readh(dev, buf, 29);
3064 * BA starting sequence number
3066 bf.ba_start_seq = zmw_rx_buf_readh(dev, buf, 31) >> 4;
3068 i=26;
3069 while(i < 32) {
3070 zm_debug_msg2("Recv ADDBA Req:", zmw_rx_buf_readb(dev,buf,i));
3071 i++;
3074 zfAggSendAddbaResponse(dev, &bf);
3076 zfAggAddbaSetTidRx(dev, buf, &bf);
3078 return ZM_SUCCESS;
3081 u16_t zfAggAddbaSetTidRx(zdev_t* dev, zbuf_t* buf, struct aggBaFrameParameter *bf)
3083 u16_t i, ac, aid, fragOff;
3084 u16_t src[3];
3085 u16_t offset = 0;
3086 u8_t up;
3087 struct agg_tid_rx *tid_rx = NULL;
3089 zmw_get_wlan_dev(dev);
3091 zmw_declare_for_critical_section();
3093 src[0] = zmw_rx_buf_readh(dev, buf, offset+10);
3094 src[1] = zmw_rx_buf_readh(dev, buf, offset+12);
3095 src[2] = zmw_rx_buf_readh(dev, buf, offset+14);
3096 aid = zfApFindSta(dev, src);
3098 zfTxGetIpTosAndFrag(dev, buf, &up, &fragOff);
3099 ac = zcUpToAc[up&0x7] & 0x3;
3101 ac = bf->tid;
3103 for (i=0; i<ZM_AGG_POOL_SIZE ; i++)
3105 if((wd->tid_rx[i]->aid == aid) && (wd->tid_rx[i]->ac == ac))
3107 tid_rx = wd->tid_rx[i];
3108 break;
3112 if (!tid_rx)
3114 for (i=0; i<ZM_AGG_POOL_SIZE; i++)
3116 if (wd->tid_rx[i]->aid == ZM_MAX_STA_SUPPORT)
3118 tid_rx = wd->tid_rx[i];
3119 break;
3122 if (!tid_rx)
3123 return 0;
3126 zmw_enter_critical_section(dev);
3128 tid_rx->aid = aid;
3129 tid_rx->ac = ac;
3130 tid_rx->addBaExchangeStatusCode = ZM_AGG_ADDBA_RESPONSE;
3131 tid_rx->seq_start = bf->ba_start_seq;
3132 tid_rx->baw_head = tid_rx->baw_tail = 0;
3133 tid_rx->sq_exceed_count = tid_rx->sq_behind_count = 0;
3134 zmw_leave_critical_section(dev);
3136 return 0;
3139 u16_t zfAggRecvAddbaResponse(zdev_t* dev, zbuf_t* buf)
3141 u16_t i,ac, aid=0;
3142 u16_t src[3];
3143 struct aggBaFrameParameter bf;
3145 zmw_get_wlan_dev(dev);
3147 //zmw_declare_for_critical_section();
3149 src[0] = zmw_rx_buf_readh(dev, buf, 10);
3150 src[1] = zmw_rx_buf_readh(dev, buf, 12);
3151 src[2] = zmw_rx_buf_readh(dev, buf, 14);
3153 if (wd->wlanMode == ZM_MODE_AP)
3154 aid = zfApFindSta(dev, src);
3157 bf.buf = buf;
3158 bf.dialog = zmw_rx_buf_readb(dev, buf, 26);
3159 bf.status_code = zmw_rx_buf_readh(dev, buf, 27);
3160 if (!bf.status_code)
3162 wd->addbaComplete=1;
3166 * ba parameter set
3168 bf.ba_parameter = zmw_rx_buf_readh(dev, buf, 29);
3169 bf.ba_policy = (bf.ba_parameter >> 1) & 1;
3170 bf.tid = (bf.ba_parameter >> 2) & 0xF;
3171 bf.buffer_size = (bf.ba_parameter >> 6);
3173 * BA timeout value
3175 bf.ba_timeout = zmw_rx_buf_readh(dev, buf, 31);
3177 i=26;
3178 while(i < 32) {
3179 zm_debug_msg2("Recv ADDBA Rsp:", zmw_rx_buf_readb(dev,buf,i));
3180 i++;
3183 ac = zcUpToAc[bf.tid&0x7] & 0x3;
3185 //zmw_enter_critical_section(dev);
3187 //wd->aggSta[aid].aggFlag[ac] = 0;
3189 //zmw_leave_critical_section(dev);
3191 return ZM_SUCCESS;
3194 u16_t zfAggRecvDelba(zdev_t* dev, zbuf_t* buf)
3196 //zmw_get_wlan_dev(dev);
3198 //zmw_declare_for_critical_section();
3199 return ZM_SUCCESS;
3202 u16_t zfAggSendAddbaResponse(zdev_t* dev, struct aggBaFrameParameter *bf)
3204 zbuf_t* buf;
3205 //u16_t addrTblSize;
3206 //struct zsAddrTbl addrTbl;
3207 //u16_t err;
3208 u16_t offset = 0;
3209 u16_t hlen = 32;
3210 u16_t header[(24+25+1)/2];
3211 u16_t vap = 0;
3212 u16_t i;
3213 u8_t encrypt = 0;
3214 u16_t dst[3];
3216 //zmw_get_wlan_dev(dev);
3218 //zmw_declare_for_critical_section();
3222 * TBD : Maximum size of management frame
3224 buf = zfwBufAllocate(dev, 1024);
3225 if (buf == NULL)
3227 zm_msg0_mm(ZM_LV_0, "Alloc mm buf Fail!");
3228 return ZM_SUCCESS;
3232 * Reserve room for wlan header
3234 offset = hlen;
3237 * add addba frame body
3239 offset = zfAggSetAddbaResponseFrameBody(dev, buf, bf, offset);
3242 zfwBufSetSize(dev, buf, offset);
3245 * Copy wlan header
3248 dst[0] = zmw_rx_buf_readh(dev, bf->buf, 10);
3249 dst[1] = zmw_rx_buf_readh(dev, bf->buf, 12);
3250 dst[2] = zmw_rx_buf_readh(dev, bf->buf, 14);
3251 zfAggGenAddbaHeader(dev, dst, header, offset-hlen, buf, vap, encrypt);
3252 for (i=0; i<(hlen>>1); i++)
3254 zmw_tx_buf_writeh(dev, buf, i*2, header[i]);
3257 /* Get buffer DMA address */
3258 //if ((addrTblSize = zfwBufMapDma(dev, buf, &addrTbl)) == 0)
3259 //if ((addrTblSize = zfwMapTxDma(dev, buf, &addrTbl)) == 0)
3261 // goto zlError;
3264 //zm_msg2_mm(ZM_LV_2, "offset=", offset);
3265 //zm_msg2_mm(ZM_LV_2, "hlen=", hlen);
3266 //zm_msg2_mm(ZM_LV_2, "addrTblSize=", addrTblSize);
3267 //zm_msg2_mm(ZM_LV_2, "addrTbl.len[0]=", addrTbl.len[0]);
3268 //zm_msg2_mm(ZM_LV_2, "addrTbl.physAddrl[0]=", addrTbl.physAddrl[0]);
3269 //zm_msg2_mm(ZM_LV_2, "buf->data=", buf->data);
3271 zfPutVmmq(dev, buf);
3272 zfPushVtxq(dev);
3274 //zfAggSendAddbaRequest(dev, dst, zcUpToAc[bf->tid&0x7] & 0x3, bf->tid);
3275 return ZM_SUCCESS;
3279 u16_t zfAggSetAddbaResponseFrameBody(zdev_t* dev, zbuf_t* buf,
3280 struct aggBaFrameParameter *bf, u16_t offset)
3283 //zmw_get_wlan_dev(dev);
3285 //zmw_declare_for_critical_section();
3287 * ADDBA Request frame body
3291 * Category
3293 zmw_tx_buf_writeb(dev, buf, offset++, 3);
3295 * Action details = 0
3297 zmw_tx_buf_writeb(dev, buf, offset++, ZM_WLAN_ADDBA_RESPONSE_FRAME);
3299 * Dialog Token = nonzero
3301 zmw_tx_buf_writeb(dev, buf, offset++, bf->dialog);
3303 * Status code
3305 zmw_tx_buf_writeh(dev, buf, offset, 0);
3306 offset+=2;
3308 * Block Ack parameter set
3309 * BA policy = 1 for immediate BA, 0 for delayed BA
3310 * TID(4bits) & buffer size(4bits) (TID=0x1 & buffer size=0x80)
3311 * TBD: how to get TID number and buffer size?
3312 * ¢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¢{
3313 * ¢x B0 ¢x B1 ¢x B2 B5 ¢x B6 B15 ¢x
3314 * ¢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
3315 * ¢x Reserved ¢x BA policy ¢x TID ¢x Buffer size ¢x
3316 * ¢|¢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¢}
3318 zmw_tx_buf_writeh(dev, buf, offset, bf->ba_parameter);
3319 offset+=2;
3321 * BA timeout value
3323 zmw_tx_buf_writeh(dev, buf, offset, bf->ba_timeout);
3324 offset+=2;
3326 return offset;
3329 void zfAggInvokeBar(zdev_t* dev, TID_TX tid_tx)
3331 struct aggBarControl aggBarControl;
3332 //zmw_get_wlan_dev(dev);
3334 //zmw_declare_for_critical_section();
3335 //bar_control = aggBarControl->tid_info << 12 | aggBarControl->compressed_bitmap << 2
3336 // | aggBarControl->multi_tid << 1 | aggBarControl->bar_ack_policy;
3337 aggBarControl.bar_ack_policy = 0;
3338 aggBarControl.multi_tid = 0;
3339 aggBarControl.compressed_bitmap = 0;
3340 aggBarControl.tid_info = tid_tx->tid;
3341 zfAggSendBar(dev, tid_tx, &aggBarControl);
3343 return;
3347 * zfAggSendBar() refers zfAggSendAddbaRequest()
3349 u16_t zfAggSendBar(zdev_t* dev, TID_TX tid_tx, struct aggBarControl *aggBarControl)
3351 zbuf_t* buf;
3352 //u16_t addrTblSize;
3353 //struct zsAddrTbl addrTbl;
3354 //u16_t err;
3355 u16_t offset = 0;
3356 u16_t hlen = 16+8; /* mac header + control headers*/
3357 u16_t header[(8+24+1)/2];
3358 u16_t vap = 0;
3359 u16_t i;
3360 u8_t encrypt = 0;
3362 //zmw_get_wlan_dev(dev);
3364 //zmw_declare_for_critical_section();
3368 * TBD : Maximum size of management frame
3370 buf = zfwBufAllocate(dev, 1024);
3371 if (buf == NULL)
3373 zm_msg0_mm(ZM_LV_0, "Alloc mm buf Fail!");
3374 return ZM_SUCCESS;
3378 * Reserve room for wlan header
3380 offset = hlen;
3383 * add addba frame body
3385 offset = zfAggSetBarBody(dev, buf, offset, tid_tx, aggBarControl);
3388 zfwBufSetSize(dev, buf, offset);
3391 * Copy wlan header
3393 zfAggGenBarHeader(dev, tid_tx->dst, header, offset-hlen, buf, vap, encrypt);
3394 for (i=0; i<(hlen>>1); i++)
3396 zmw_tx_buf_writeh(dev, buf, i*2, header[i]);
3399 /* Get buffer DMA address */
3400 //if ((addrTblSize = zfwBufMapDma(dev, buf, &addrTbl)) == 0)
3401 //if ((addrTblSize = zfwMapTxDma(dev, buf, &addrTbl)) == 0)
3403 // goto zlError;
3406 //zm_msg2_mm(ZM_LV_2, "offset=", offset);
3407 //zm_msg2_mm(ZM_LV_2, "hlen=", hlen);
3408 //zm_msg2_mm(ZM_LV_2, "addrTblSize=", addrTblSize);
3409 //zm_msg2_mm(ZM_LV_2, "addrTbl.len[0]=", addrTbl.len[0]);
3410 //zm_msg2_mm(ZM_LV_2, "addrTbl.physAddrl[0]=", addrTbl.physAddrl[0]);
3411 //zm_msg2_mm(ZM_LV_2, "buf->data=", buf->data);
3413 zfPutVmmq(dev, buf);
3414 zfPushVtxq(dev);
3416 return ZM_SUCCESS;
3420 u16_t zfAggSetBarBody(zdev_t* dev, zbuf_t* buf, u16_t offset, TID_TX tid_tx, struct aggBarControl *aggBarControl)
3422 u16_t bar_control, start_seq;
3424 //zmw_get_wlan_dev(dev);
3426 //zmw_declare_for_critical_section();
3428 * BAR Control frame body
3432 * BAR Control Field
3433 * ¢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¢{
3434 * ¢x B0 ¢x B1 ¢x B2 ¢x B3 B11 ¢x B12 B15 ¢x
3435 * ¢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
3436 * ¢x BAR Ack ¢x Multi-TID ¢x Compressed ¢x Reserved ¢x TID_INFO ¢x
3437 * ¢x Policy ¢x ¢x Bitmap ¢x ¢x ¢x
3438 * ¢|¢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¢}
3440 bar_control = aggBarControl->tid_info << 12 | aggBarControl->compressed_bitmap << 2
3441 | aggBarControl->multi_tid << 1 | aggBarControl->bar_ack_policy;
3443 zmw_tx_buf_writeh(dev, buf, offset, bar_control);
3444 offset+=2;
3445 if (0 == aggBarControl->multi_tid) {
3447 * BA starting sequence number
3448 * ¢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¢{
3449 * ¢x B0 B3 ¢x B4 B15 ¢x
3450 * ¢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
3451 * ¢x Frag num(0) ¢x BA starting seq num ¢x
3452 * ¢|¢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¢}
3454 start_seq = (tid_tx->bar_ssn << 4) & 0xFFF0;
3455 zmw_tx_buf_writeh(dev, buf, offset, start_seq);
3456 offset+=2;
3458 if (1 == aggBarControl->multi_tid && 1 == aggBarControl->compressed_bitmap) {
3459 /* multi-tid BlockAckReq variant, not implemented*/
3462 return offset;
3465 u16_t zfAggGenBarHeader(zdev_t* dev, u16_t* dst,
3466 u16_t* header, u16_t len, zbuf_t* buf, u16_t vap, u8_t encrypt)
3468 u8_t hlen = 16+8; // MAC ctrl + PHY ctrl + 802.11 MM header
3469 //u8_t frameType = ZM_WLAN_FRAME_TYPE_ACTION;
3471 zmw_get_wlan_dev(dev);
3473 zmw_declare_for_critical_section();
3476 * Generate control setting
3478 //bodyLen = zfwBufGetSize(dev, buf);
3479 header[0] = 16+len+4; //Length
3480 header[1] = 0x8; //MAC control, backoff + (ack)
3482 /* CCK 1M */
3483 header[2] = 0x0f00; //PHY control L
3484 header[3] = 0x0000; //PHY control H
3486 * Generate WLAN header
3487 * Frame control frame type and subtype
3489 header[4+0] = ZM_WLAN_FRAME_TYPE_BAR;
3491 * Duration
3493 header[4+1] = 0;
3495 /* Address 1 = DA */
3496 header[4+2] = dst[0];
3497 header[4+3] = dst[1];
3498 header[4+4] = dst[2];
3500 /* Address 2 = SA */
3501 header[4+5] = wd->macAddr[0];
3502 header[4+6] = wd->macAddr[1];
3503 if (wd->wlanMode == ZM_MODE_AP)
3505 #ifdef ZM_VAPMODE_MULTILE_SSID
3506 header[4+7] = wd->macAddr[2]; //Multiple SSID
3507 #else
3508 header[4+7] = wd->macAddr[2] + (vap<<8); //VAP
3509 #endif
3511 else
3513 header[4+7] = wd->macAddr[2];
3516 /* Sequence Control */
3517 zmw_enter_critical_section(dev);
3518 header[4+11] = ((wd->mmseq++)<<4);
3519 zmw_leave_critical_section(dev);
3522 return hlen;