Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ericvh...
[pandora-kernel.git] / drivers / staging / otus / 80211core / cagg.c
1 /*
2  * Copyright (c) 2007-2008 Atheros Communications Inc.
3  *
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.
7  *
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.
15  */
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 /************************************************************************/
26
27 #include "cprecomp.h"
28
29 extern u8_t zcUpToAc[8];
30 const u8_t pri[] = {3,3,2,3,2,1,3,2,1,0};
31
32
33 u16_t aggr_count;
34 u32_t success_mpdu;
35 u32_t total_mpdu;
36
37 void zfAggInit(zdev_t* dev)
38 {
39     u16_t i,j;
40
41     zmw_get_wlan_dev(dev);
42
43     zmw_declare_for_critical_section();
44     /*
45      * reset sta information
46      */
47
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++)
54     {
55         for (j=0; j<ZM_AC; j++)
56         {
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;
61
62         }
63     }
64
65     /*
66      * reset Tx/Rx aggregation queue information
67      */
68     wd->aggState = 0;
69     for (i=0; i<ZM_AGG_POOL_SIZE; i++)
70     {
71         /*
72          * reset tx aggregation queue
73          */
74         wd->aggQPool[i] = zfwMemAllocate(dev, sizeof(struct aggQueue));
75         if(!wd->aggQPool[i])
76         {
77             zmw_leave_critical_section(dev);
78             return;
79         }
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;
84
85         /*
86          * reset rx aggregation queue
87          */
88         wd->tid_rx[i] = zfwMemAllocate(dev, sizeof(struct agg_tid_rx));
89         if (!wd->tid_rx[i])
90         {
91             zmw_leave_critical_section(dev);
92             return;
93         }
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;
100         /*
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
107          */
108         wd->tid_rx[i]->addBaExchangeStatusCode = 0;
109
110     }
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)
123     {
124         return;
125     }
126     BAW->init = zfBawInit;
127     BAW->init(dev);
128 #endif //disable BAW
129 #endif
130 }
131
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 /************************************************************************/
150
151
152
153 u16_t zfAggGetSta(zdev_t* dev, zbuf_t* buf)
154 {
155     u16_t id;
156     u16_t dst[3];
157
158     zmw_get_wlan_dev(dev);
159
160     zmw_declare_for_critical_section();
161
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);
165
166     zmw_enter_critical_section(dev);
167
168     if(wd->wlanMode == ZM_MODE_AP) {
169         id = zfApFindSta(dev, dst);
170     }
171     else {
172         id = 0;
173     }
174     zmw_leave_critical_section(dev);
175
176 #if ZM_AGG_FPGA_DEBUG
177     id = 0;
178 #endif
179
180     return id;
181 }
182
183
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)
203 {
204     //u16_t   i;
205     TID_TX  tid_tx;
206     zmw_get_wlan_dev(dev);
207
208     //zmw_declare_for_critical_section();
209
210     /*
211      * not a STA aid
212      */
213     if (0xffff == aid)
214         return NULL;
215
216     //zmw_enter_critical_section(dev);
217
218     tid_tx = wd->aggSta[aid].tid_tx[tid];
219     if (!tid_tx) return NULL;
220     if (0 == tid_tx->aggQEnabled)
221         return NULL;
222
223     //zmw_leave_critical_section(dev);
224
225     return tid_tx;
226 }
227
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)
246 {
247     u16_t   i;
248     TID_TX  tid_tx=NULL;
249     u16_t   ac = zcUpToAc[tid&0x7] & 0x3;
250     zmw_get_wlan_dev(dev);
251
252     zmw_declare_for_critical_section();
253
254     /*
255      * not a STA aid
256      */
257     if (0xffff == aid)
258         return NULL;
259
260     zmw_enter_critical_section(dev);
261
262     /*
263      * find one new queue for sta
264      */
265     for (i=0; i<ZM_AGG_POOL_SIZE; i++)
266     {
267         if (wd->aggQPool[i]->aggQEnabled)
268         {
269                 /*
270                  * this q is enabled
271                  */
272         }
273         else
274         {
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;
287         }
288     }
289
290     zmw_leave_critical_section(dev);
291
292     return tid_tx;
293 }
294
295
296
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)
318 {
319     //u16_t   qlen, frameLen;
320     u32_t   time;
321
322     zmw_get_wlan_dev(dev);
323
324     zmw_declare_for_critical_section();
325
326     zmw_enter_critical_section(dev);
327
328     tid_tx->size = zm_agg_qlen(dev, tid_tx->aggHead, tid_tx->aggTail);
329
330     if (tid_tx->size < (ZM_AGGQ_SIZE - 2))
331     {
332         /* Queue not full */
333
334
335         /*
336          * buffer copy
337          * in zfwBufFree will return a ndismsendcomplete
338          * to resolve the synchronize problem in aggregate
339          */
340
341         u8_t    sendComplete = 0;
342
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;
347
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;
355         }
356         zmw_leave_critical_section(dev);
357
358         if (!DESTQ.exist(dev, 0, tid_tx->ac, tid_tx, NULL)) {
359             DESTQ.insert(dev, 0, tid_tx->ac, tid_tx, NULL);
360         }
361
362         zm_msg1_agg(ZM_LV_0, "tid_tx->size=", tid_tx->size);
363         //zm_debug_msg1("tid_tx->size=", tid_tx->size);
364
365         if (buf && sendComplete && wd->zfcbSendCompleteIndication) {
366             //zmw_leave_critical_section(dev);
367             wd->zfcbSendCompleteIndication(dev, buf);
368         }
369
370         /*if (tid_tx->size >= 16 && zfHpGetFreeTxdCount(dev) > 20)
371             zfAggTxSend(dev, zfHpGetFreeTxdCount(dev), tid_tx);
372         */
373         return ZM_SUCCESS;
374     }
375     else
376     {
377         zm_msg1_agg(ZM_LV_0, "can't enqueue, tid_tx->size=", tid_tx->size);
378         /*
379          * Queue Full
380          */
381
382         /*
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);
387          *
388          * return ZM_ERR_EXCEED_PRIORITY_THRESHOLD;
389          */
390     }
391
392     zmw_leave_critical_section(dev);
393
394     if (!DESTQ.exist(dev, 0, tid_tx->ac, tid_tx, NULL)) {
395             DESTQ.insert(dev, 0, tid_tx->ac, tid_tx, NULL);
396     }
397
398     return ZM_ERR_EXCEED_PRIORITY_THRESHOLD;
399 }
400
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);
405
406     zmw_declare_for_critical_section();
407
408     zmw_enter_critical_section(dev);
409     if (!DESTQ.Head[ac]) {
410         exist = 0;
411     }
412     else {
413         dest = DESTQ.Head[ac];
414         if (dest->tid_tx == tid_tx) {
415             exist = 1;
416         }
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;
423                 }
424             }
425         }
426     }
427
428     zmw_leave_critical_section(dev);
429
430     return exist;
431 }
432
433 void    zfAggDestInsert(zdev_t* dev, u16_t Qtype, u16_t ac, TID_TX tid_tx, void* vtxq)
434 {
435     struct dest* new_dest;
436     zmw_get_wlan_dev(dev);
437
438     zmw_declare_for_critical_section();
439
440     new_dest = zfwMemAllocate(dev, sizeof(struct dest));
441     if(!new_dest)
442     {
443         return;
444     }
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]) {
452
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);
457     }
458     else {
459
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);
464     }
465
466
467     //DESTQ.size[ac]++;
468     return;
469 }
470
471 void    zfAggDestDelete(zdev_t* dev, u16_t Qtype, TID_TX tid_tx, void* vtxq)
472 {
473     struct dest* dest, *temp;
474     u16_t   i;
475
476     zmw_get_wlan_dev(dev);
477
478     zmw_declare_for_critical_section();
479
480     zmw_enter_critical_section(dev);
481     if (wd->destLock) {
482         zmw_leave_critical_section(dev);
483         return;
484     }
485
486
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;
492
493
494         while (dest && (dest->next != DESTQ.Head[i])) {
495             if (Qtype == 0 && dest->next->tid_tx == tid_tx){
496                 break;
497             }
498             if (Qtype == 1 && dest->next->vtxq == vtxq) {
499                 break;
500             }
501             dest = dest->next;
502         }
503
504         if ((Qtype == 0 && dest->next->tid_tx == tid_tx) || (Qtype == 1 && dest->next->vtxq == vtxq)) {
505
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;
510             }
511             if (!DESTQ.Head[i]) {
512                 temp = NULL;
513             }
514             else {
515                 temp = dest->next;
516                 if (temp == dest) {
517                     DESTQ.Head[i] = DESTQ.dest[i] = NULL;
518                     //DESTQ.size[i] = 0;
519                 }
520                 else {
521                     dest->next = dest->next->next;
522                 }
523             }
524
525             if (temp == NULL)
526                 {/* do nothing */} //zfwMemFree(dev, temp, sizeof(struct dest));
527             else
528                 zfwMemFree(dev, temp, sizeof(struct dest));
529
530             /*zmw_enter_critical_section(dev);
531             if (DESTQ.size[i] > 0)
532                 DESTQ.size[i]--;
533             zmw_leave_critical_section(dev);
534             */
535         }
536
537     }
538     zmw_leave_critical_section(dev);
539     return;
540 }
541
542 void    zfAggDestInit(zdev_t* dev)
543 {
544     u16_t i;
545     zmw_get_wlan_dev(dev);
546
547     //zmw_declare_for_critical_section();
548
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;
554     }
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;
562 }
563
564 struct dest* zfAggDestGetNext(zdev_t* dev, u16_t ac)
565 {
566     struct dest *dest = NULL;
567     zmw_get_wlan_dev(dev);
568
569     zmw_declare_for_critical_section();
570
571     zmw_enter_critical_section(dev);
572     if (DESTQ.dest[ac]) {
573         dest = DESTQ.dest[ac];
574         DESTQ.dest[ac] = DESTQ.dest[ac]->next;
575     }
576     else {
577         dest = NULL;
578     }
579     zmw_leave_critical_section(dev);
580
581     return dest;
582 }
583
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)
587 {
588     zbuf_t* buf;
589     u32_t time;
590     struct baw_header *baw_header;
591
592     zmw_get_wlan_dev(dev);
593
594     zmw_declare_for_critical_section();
595
596
597     buf = buf_info->buf;
598
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);
602
603     if (tid_tx->size >= (ZM_AGGQ_SIZE - 2)) {
604         zfwBufFree(dev, buf, ZM_SUCCESS);
605         return 0;
606     }
607
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;
614
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);
624
625     tid_tx->size++;
626     tid_tx->size = zm_agg_qlen(dev, tid_tx->aggHead, tid_tx->aggTail);
627     zmw_leave_critical_section(dev);
628
629     //tid_tx->lastArrival = time;
630     if (1 == tid_tx->size) {
631         DESTQ.insert(dev, 0, tid_tx->ac, tid_tx, NULL);
632     }
633
634
635     zm_msg1_agg(ZM_LV_0, "0xC2:insertHead, tid_tx->size=", tid_tx->size);
636
637     return TRUE;
638 }
639 #endif //disable BAW
640 #endif
641
642 void    zfiTxComplete(zdev_t* dev)
643 {
644
645     zmw_get_wlan_dev(dev);
646
647     //zmw_declare_for_critical_section();
648
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);
653     }
654
655     return;
656 }
657
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);
663
664     zmw_declare_for_critical_section();
665
666     zmw_enter_critical_section(dev);
667     for (i=0; i<ZM_AGG_POOL_SIZE; i++)
668     {
669         if (wd->aggQPool[i]->aggQEnabled)
670         {
671             if (wd->aggQPool[i]->size >= 16) {
672                 tid_tx = wd->aggQPool[i];
673                 break;
674             }
675         }
676         else {
677         }
678     }
679     zmw_leave_critical_section(dev);
680     return tid_tx;
681 }
682
683 u16_t   zfAggValidTidTx(zdev_t* dev, TID_TX tid_tx) {
684     u16_t   i, valid = 0;
685     zmw_get_wlan_dev(dev);
686
687     zmw_declare_for_critical_section();
688
689     zmw_enter_critical_section(dev);
690     for (i=0; i<ZM_AGG_POOL_SIZE; i++)
691     {
692         if (wd->aggQPool[i] == tid_tx)
693         {
694             valid = 1;
695             break;
696         }
697         else {
698         }
699     }
700     zmw_leave_critical_section(dev);
701
702     return valid;
703 }
704
705 void    zfAggTxScheduler(zdev_t* dev, u8_t ScanAndClear)
706 {
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);
715
716     zmw_declare_for_critical_section();
717
718     if (!wd->aggInitiated)
719     {
720         return;
721     }
722
723     /* debug */
724     txql = TXQL;
725     min_txql = AGG_MIN_TXQL;
726
727     if(wd->txq_threshold)
728         txq_threshold = wd->txq_threshold;
729     else
730         txq_threshold = AGG_MIN_TXQL;
731
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) {
741
742         //DbgPrint("zfAggTxScheduler: in while loop");
743         for (i=0; i<4; i++) {
744             if (DESTQ.Head[i]) destQ_count++;
745         }
746         if (0 >= destQ_count) break;
747
748         zmw_enter_critical_section(dev);
749         ac = pri[DESTQ.ppri]; DESTQ.ppri = (DESTQ.ppri + 1) % 10;
750         zmw_leave_critical_section(dev);
751
752         for (i=0; i<10; i++){
753             if(DESTQ.Head[ac]) break;
754
755             zmw_enter_critical_section(dev);
756             ac = pri[DESTQ.ppri]; DESTQ.ppri = (DESTQ.ppri + 1) % 10;
757             zmw_leave_critical_section(dev);
758         }
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);
764
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);
770
771             DbgPrint("bug report! DESTQ.getNext got nothing!");
772             break;
773         }
774         if (dest->Qtype == 0) {
775             tid_tx = dest->tid_tx;
776
777             //DbgPrint("zfAggTxScheduler: have tid_tx Q");
778
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);
785
786                 tid_tx = zfAggTxReady(dev);
787                 continue;
788             }
789
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) {
795
796                 //zmw_leave_critical_section(dev);
797                 //DESTQ.delete(dev, 0, tid_tx, NULL);
798             }
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;
804             }
805             else {
806                 //zmw_leave_critical_section(dev);
807                 break;
808             }
809         }
810         else {
811             vtxq = dest->vtxq;
812             buf = zfGetVtxq(dev, ac);
813             zm_assert( buf != 0 );
814
815             zfTxSendEth(dev, buf, 0, ZM_EXTERNAL_ALLOC_BUF, 0);
816
817         }
818         /*flush all but < 16 frames in tid_tx to TXQ*/
819         tid_tx = zfAggTxReady(dev);
820     }
821
822     /*while ((zfHpGetFreeTxdCount(dev)) > 32) {
823     //while ((zfHpGetFreeTxdCount(dev)) > 32) {
824
825         destQ_count = 0;
826         for (i=0; i<4; i++) destQ_count += wd->destQ.size[i];
827         if (0 >= destQ_count) break;
828
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;
833         }
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;
842             }
843             else if((wd->aggState == 0) && (tid_tx->size >= 16)){
844                 zfAggTxSend(dev, zfHpGetFreeTxdCount(dev), tid_tx);
845             }
846             else {
847                 break;
848             }
849         }
850
851     }
852     */
853     return;
854 }
855
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)
879 {
880     u16_t aid;
881     //u16_t qnum;
882     //u16_t aggflag = 0;
883     //u16_t arrivalrate = 0;
884     TID_TX tid_tx;
885
886     zmw_get_wlan_dev(dev);
887
888     zmw_declare_for_critical_section();
889
890     if(!wd->aggInitiated)
891     {
892         return ZM_ERR_TX_BUFFER_UNAVAILABLE;
893     }
894
895     aid = zfAggGetSta(dev, buf);
896
897     //arrivalrate = zfAggTxArrivalRate(dev, aid, tid);
898
899     if (0xffff == aid)
900     {
901         /*
902          * STA not associated, this is a BC/MC or STA->AP packet
903          */
904
905         return ZM_ERR_TX_BUFFER_UNAVAILABLE;
906     }
907
908     /*
909      * STA associated, a unicast packet
910      */
911
912     tid_tx = zfAggTxGetQueue(dev, aid, tid);
913
914     /*tid_q.tid_tx = tid_tx;
915     wd->destQ.insert = zfAggDestInsert;
916     wd->destQ.insert(dev, 0, tid_q);
917     */
918     if (tid_tx != NULL)
919     {
920         /*
921          * this (aid, ac) is aggregated
922          */
923
924         //if (arrivalrate < ZM_AGG_LOW_THRESHOLD)
925         if (0)
926         {
927             /*
928              * arrival rate too low
929              * delete this aggregate queue
930              */
931
932             zmw_enter_critical_section(dev);
933
934             //wd->aggQPool[qnum]->clearFlag = wd->aggQPool[qnum]->deleteFlag =1;
935
936             zmw_leave_critical_section(dev);
937
938         }
939
940         return zfAggTxEnqueue(dev, buf, aid, tid_tx);
941
942     }
943     else
944     {
945         /*
946          * this (aid, ac) not yet aggregated
947          * queue not found
948          */
949
950         //if (arrivalrate > ZM_AGG_HIGH_THRESHOLD)
951         if (1)
952         {
953             /*
954              * arrivalrate high enough to get a new agg queue
955              */
956
957             tid_tx = zfAggTxNewQueue(dev, aid, tid, buf);
958
959             //zm_msg1_agg(ZM_LV_0, "get new AggQueue qnum = ", tid_tx->);
960
961             if (tid_tx)
962             {
963                 /*
964                  * got a new aggregate queue
965                  */
966
967                 //zmw_enter_critical_section(dev);
968
969                 //wd->aggSta[aid].aggFlag[ac] = 1;
970
971                 //zmw_leave_critical_section(dev);
972
973                 /*
974                  * add ADDBA functions here
975                  * return ZM_ERR_TX_BUFFER_UNAVAILABLE;
976                  */
977
978
979                 //zfAggSendAddbaRequest(dev, tid_tx->dst, tid_tx->ac, tid_tx->tid);
980                 //zmw_enter_critical_section(dev);
981
982                 //wd->aggSta[aid].aggFlag[ac] = 0;
983
984                 //zmw_leave_critical_section(dev);
985
986                 return zfAggTxEnqueue(dev, buf, aid, tid_tx);
987
988             }
989             else
990             {
991                 /*
992                  * just can't get a new aggregate queue
993                  */
994
995                 return ZM_ERR_TX_BUFFER_UNAVAILABLE;
996             }
997         }
998         else
999         {
1000             /*
1001              * arrival rate is not high enough to get a new agg queue
1002              */
1003
1004             return ZM_ERR_TX_BUFFER_UNAVAILABLE;
1005         }
1006     }
1007
1008
1009
1010 }
1011
1012
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)
1032 {
1033     u16_t i;
1034     u16_t readycount = 0;
1035
1036     zmw_get_wlan_dev(dev);
1037
1038     zmw_declare_for_critical_section();
1039
1040     zmw_enter_critical_section(dev);
1041
1042     for (i=0 ; i<ZM_AGG_POOL_SIZE; i++)
1043     {
1044         if (wd->aggQPool[i]->aggQEnabled && (wd->aggQPool[i]->aggReady || \
1045                 wd->aggQPool[i]->clearFlag) && ac == wd->aggQPool[i]->ac)
1046             readycount++;
1047     }
1048
1049     zmw_leave_critical_section(dev);
1050
1051     return readycount;
1052 }
1053
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)
1075 {
1076     u16_t qlen;
1077     u16_t partial;
1078
1079     zmw_get_wlan_dev(dev);
1080
1081     zmw_declare_for_critical_section();
1082
1083     zmw_enter_critical_section(dev);
1084
1085     qlen = zm_agg_qlen(dev, wd->vtxqHead[ac], wd->vtxqTail[ac]);
1086
1087     if ((qlen + readycount) > 0)
1088     {
1089         partial = (u16_t)( zm_agg_weight(ac) * ((u16_t)qlen/(qlen + \
1090                         readycount)) );
1091     }
1092     else
1093     {
1094         partial = 0;
1095     }
1096
1097     zmw_leave_critical_section(dev);
1098
1099     if (partial > qlen)
1100         partial = qlen;
1101
1102     return partial;
1103 }
1104
1105
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)
1126 {
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;
1138
1139     zmw_get_wlan_dev(dev);
1140
1141     zmw_declare_for_critical_section();
1142
1143     //while (tid_tx->size > 0)
1144
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);
1149
1150             /*
1151              * why there have to be 2 free Txd?
1152              */
1153     if (aggLen <=0 )
1154         return 0;
1155
1156
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);
1163         }
1164
1165         return 1;
1166     }
1167                 /*
1168                  * Free Txd queue is big enough to put aggregation
1169                  */
1170     zmw_enter_critical_section(dev);
1171     if (wd->aggState == 1) {
1172         zmw_leave_critical_section(dev);
1173         return 0;
1174     }
1175     wd->aggState = 1;
1176     zmw_leave_critical_section(dev);
1177
1178
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);
1183
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);
1187
1188         if ( buf ) {
1189             //struct aggTally *agg_tal;
1190             u16_t completeIndex;
1191
1192             if (0 == j) {
1193                 aggControl.ampduIndication = ZM_AGG_FIRST_MPDU;
1194
1195             }
1196             else if ((j == (aggLen - 1)) || tid_tx->size == 0)
1197             {
1198                 aggControl.ampduIndication = ZM_AGG_LAST_MPDU;
1199                 //wd->aggState = 0;
1200
1201             }
1202             else
1203             {
1204                 aggControl.ampduIndication = ZM_AGG_MIDDLE_MPDU;
1205                 /* the packet is delayed more than 500 ms, drop it */
1206
1207             }
1208             tid_tx->aggFrameSize += zfwBufGetSize(dev, buf);
1209             aggControl.addbaIndication = 0;
1210             aggControl.aggEnabled = 1;
1211
1212 #ifdef ZM_AGG_TALLY
1213             agg_tal = &wd->agg_tal;
1214             agg_tal->sent_packets_sum++;
1215
1216 #endif
1217
1218             zfAggTxSendEth(dev, buf, 0, ZM_EXTERNAL_ALLOC_BUF, 0, &aggControl, tid_tx);
1219
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);
1225
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!");
1230             }
1231
1232         }
1233         else {
1234             /*
1235              * this aggregation queue is empty
1236              */
1237             zm_msg1_agg(ZM_LV_0, "aggLen not reached, but no more frame, j=", j);
1238
1239             break;
1240         }
1241     }
1242     zmw_enter_critical_section(dev);
1243     wd->aggState = 0;
1244     zmw_leave_critical_section(dev);
1245
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);
1249
1250     if (tid_tx->size == 0) {
1251         //DESTQ.delete(dev, 0, tid_tx, NULL);
1252     }
1253
1254
1255
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);
1261     }
1262     return j;
1263 }
1264
1265
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)
1286 {
1287     //u16_t       qnum = ZM_AGG_POOL_SIZE;
1288     u16_t       i;
1289     u32_t       time = 0;
1290     TID_TX      tid_tx = NULL;
1291
1292     zmw_get_wlan_dev(dev);
1293
1294     zmw_declare_for_critical_section();
1295
1296     zmw_enter_critical_section(dev);
1297
1298     for (i=0 ;i<ZM_AGG_POOL_SIZE; i++)
1299     {
1300         if (1 == wd->aggQPool[i]->aggQEnabled && ac == wd->aggQPool[i]->ac &&
1301                 (wd->aggQPool[i]->size > 0))
1302         {
1303             if (0 == time || time > wd->aggQPool[i]->aggvtxq[ \
1304                             wd->aggQPool[i]->aggHead ].arrivalTime)
1305             {
1306                 tid_tx = wd->aggQPool[i];
1307                 time = tid_tx->aggvtxq[ tid_tx->aggHead ].arrivalTime;
1308             }
1309         }
1310     }
1311
1312     zmw_leave_critical_section(dev);
1313
1314     return tid_tx;
1315 }
1316
1317
1318
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)
1337 {
1338     zbuf_t* buf = NULL;
1339
1340     zmw_declare_for_critical_section();
1341
1342     if (tid_tx->aggHead != tid_tx->aggTail)
1343     {
1344         buf = tid_tx->aggvtxq[ tid_tx->aggTail ].buf;
1345
1346         tid_tx->aggvtxq[tid_tx->aggTail].buf = NULL;
1347
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);
1355         }
1356         zmw_leave_critical_section(dev);
1357     }
1358     else
1359     {
1360         /*
1361          * queue is empty
1362          */
1363         zm_msg1_agg(ZM_LV_0, "tid_tx->aggHead == tid_tx->aggTail, tid_tx->size=", tid_tx->size);
1364
1365     }
1366
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;
1370 }
1371
1372
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)
1392 {
1393     u16_t ac, tid;
1394     struct aggQueue *tx_tid;
1395     struct aggSta   *agg_sta;
1396
1397     zmw_get_wlan_dev(dev);
1398
1399     zmw_declare_for_critical_section();
1400
1401     tx_tid = wd->aggQPool[qnum];
1402     agg_sta = &wd->aggSta[tx_tid->aggQSTA];
1403     ac = tx_tid->ac;
1404     tid = tx_tid->tid;
1405
1406     zmw_enter_critical_section(dev);
1407
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;
1414
1415     agg_sta->tid_tx[tid] = NULL;
1416     agg_sta->aggFlag[ac] = 0;
1417
1418     zmw_leave_critical_section(dev);
1419
1420     zm_msg1_agg(ZM_LV_0, "queue deleted! qnum=", qnum);
1421
1422     return ZM_SUCCESS;
1423 }
1424
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;
1432
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;
1439
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);
1448             }
1449         }
1450         else {
1451             success_mpdu++;
1452         }
1453     }
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);
1458 }
1459
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();
1465
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;
1470         }
1471         tid_baw->enabled = tid_baw->head = tid_baw->tail = tid_baw->size = 0;
1472         tid_baw->start_seq = 0;
1473     }
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;
1482 }
1483
1484
1485
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();
1492
1493     /*
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;
1498     }
1499     */
1500
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;
1510     //}
1511
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);
1516
1517     BAW->enable(dev, tid_baw, start_seq);
1518     tid_baw->tid_tx = tid_tx;
1519
1520     return tid_baw;
1521 }
1522
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;
1526
1527     //zmw_get_wlan_dev(dev);
1528     //zmw_declare_for_critical_section();
1529
1530     if(tid_baw->size < (ZM_VTXQ_SIZE - 1)) {
1531         struct baw_header *baw_header = &tid_baw->frame[tid_baw->head].baw_header;
1532
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;
1545
1546         //tid_baw->frame[tid_baw->head].data = pBuf->data;
1547         tid_baw->head++;
1548         tid_baw->size++;
1549     }
1550     else {
1551         //wd->zfcbSetBawQ(dev, buf, 0);
1552         zfwBufFree(dev, buf, ZM_SUCCESS);
1553         return FALSE;
1554     }
1555     return TRUE;
1556 }
1557
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);
1563
1564     buf_info = &wd->buf_info;
1565     buf_info->baw_header = NULL;
1566
1567     if (NULL == (buf_info->buf = tid_baw->frame[index].buf))
1568         return buf_info;
1569
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;
1576
1577     return buf_info;
1578 }
1579
1580 void    zfBawEnable(zdev_t* dev, TID_BAW tid_baw, u16_t start_seq) {
1581     //TID_BAW tid_baw;
1582
1583     //zmw_get_wlan_dev(dev);
1584     //zmw_declare_for_critical_section();
1585
1586     tid_baw->enabled = TRUE;
1587     tid_baw->head = tid_baw->tail = tid_baw->size = 0;
1588     tid_baw->start_seq = start_seq;
1589 }
1590
1591 void    zfBawDisable(zdev_t* dev, TID_BAW tid_baw) {
1592     //TID_BAW tid_baw;
1593     u16_t i;
1594
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) {
1599
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;
1603         }
1604     }
1605
1606     tid_baw->enabled = FALSE;
1607 }
1608
1609 TID_BAW zfBawGetQ(zdev_t* dev, u16_t baw_seq) {
1610     TID_BAW tid_baw=NULL;
1611     u16_t i;
1612
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)
1618         {
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;
1623         }
1624
1625     }
1626     if (ZM_BAW_POOL_SIZE == i)
1627         return NULL;
1628     return tid_baw;
1629 }
1630 #endif //disable BAW
1631 #endif
1632
1633 u16_t zfAggTallyReset(zdev_t* dev)
1634 {
1635     struct aggTally* agg_tal;
1636
1637     zmw_get_wlan_dev(dev);
1638
1639     //zmw_declare_for_critical_section();
1640
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;
1652 }
1653
1654
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)
1673 {
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;
1681
1682     zmw_get_wlan_dev(dev);
1683
1684     zmw_declare_for_critical_section();
1685
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++)
1690     {
1691         if (!wd->aggQPool[i]) return 0;
1692         if (1 == wd->aggQPool[i]->aggQEnabled)
1693         {
1694             tid_tx = wd->aggQPool[i];
1695             zmw_enter_critical_section(dev);
1696
1697             head = tid_tx->aggHead;
1698             tail = tid_tx->aggTail;
1699
1700             arrivalTime = (u32_t)tid_tx->aggvtxq[tid_tx->aggTail].arrivalTime;
1701
1702
1703             if((tick - arrivalTime) <= ZM_AGG_CLEAR_TIME)
1704             {
1705
1706             }
1707             else if((tid_tx->size = zm_agg_qlen(dev, tid_tx->aggHead, tid_tx->aggTail)) > 0)
1708             {
1709
1710                 tid_tx->clearFlag = 1;
1711
1712                 //zm_msg1_agg(ZM_LV_0, "clear queue    tick =", tick);
1713                 //zm_msg1_agg(ZM_LV_0, "clear queue arrival =", arrivalTime);
1714
1715
1716                 //zmw_leave_critical_section(dev);
1717                 //zfAggTxScheduler(dev);
1718                 //zmw_enter_critical_section(dev);
1719
1720             }
1721
1722             if (tid_tx->size == 0)
1723             {
1724                 /*
1725                  * queue empty
1726                  */
1727                 if (tick - tid_tx->lastArrival > ZM_AGG_DELETE_TIME)
1728                 {
1729                     zm_msg1_agg(ZM_LV_0, "delete queue, idle for n sec. n = ", \
1730                             ZM_AGG_DELETE_TIME/10);
1731
1732                     zmw_leave_critical_section(dev);
1733                     zfAggTxDeleteQueue(dev, i);
1734                     zmw_enter_critical_section(dev);
1735                 }
1736             }
1737
1738             zmw_leave_critical_section(dev);
1739         }
1740     }
1741
1742         zfAggRxClear(dev, time);
1743
1744 #ifdef ZM_AGG_TALLY
1745     if((wd->tick % 100) == 0) {
1746         zfAggPrintTally(dev);
1747     }
1748 #endif
1749
1750     return ZM_SUCCESS;
1751 }
1752
1753 u16_t   zfAggPrintTally(zdev_t* dev)
1754 {
1755     struct aggTally* agg_tal;
1756
1757     zmw_get_wlan_dev(dev);
1758
1759     //zmw_declare_for_critical_section();
1760
1761     agg_tal = &wd->agg_tal;
1762
1763     if(agg_tal->got_packets_sum < 10)
1764     {
1765         zfAggTallyReset(dev);
1766         return 0;
1767     }
1768
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))
1789     {
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);
1792     }
1793     else
1794         zm_msg1_agg(ZM_LV_0, "1/(BA fail rate)=", wd->commTally.Hw_Tx_MPDU/wd->commTally.BA_Fail);
1795
1796     return 0;
1797 }
1798
1799 u16_t zfAggRxClear(zdev_t* dev, u32_t time)
1800 {
1801     u16_t   i;
1802     struct agg_tid_rx *tid_rx;
1803
1804     zmw_get_wlan_dev(dev);
1805
1806     zmw_declare_for_critical_section();
1807
1808     for (i=0; i<ZM_AGG_POOL_SIZE; i++)
1809     {
1810         zmw_enter_critical_section(dev);
1811         tid_rx = wd->tid_rx[i];
1812         if (tid_rx->baw_head != tid_rx->baw_tail)
1813         {
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;
1817             }
1818             if ((j != tid_rx->baw_head) && (time - tid_rx->frame[j].arrivalTime) >
1819                     (ZM_AGG_CLEAR_TIME - 5))
1820             {
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);
1825             }
1826         }
1827         zmw_leave_critical_section(dev);
1828     }
1829
1830     return ZM_SUCCESS;
1831 }
1832
1833 struct agg_tid_rx* zfAggRxEnabled(zdev_t* dev, zbuf_t* buf)
1834 {
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);
1846
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)
1851     {
1852         return NULL;
1853     }
1854
1855     frameCtrl = zmw_rx_buf_readb(dev, buf, 0);
1856     frameType = frameCtrl & 0xf;
1857     frameSubtype = frameCtrl & 0xf0;
1858
1859
1860     if (frameType != ZM_WLAN_DATA_FRAME) //non-Qos Data? (frameSubtype&0x80)
1861     {
1862         return NULL;
1863     }
1864 #ifdef ZM_ENABLE_PERFORMANCE_EVALUATION
1865     {
1866         u32_t tcp_seq;
1867
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);
1873     }
1874 #endif
1875
1876     dst0 = zmw_rx_buf_readh(dev, buf, offset+4);
1877
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);
1881
1882 #if ZM_AGG_FPGA_DEBUG
1883     aid = 0;
1884 #else
1885     aid = zfApFindSta(dev, src);
1886 #endif
1887
1888     //agg_sta = &wd->aggSta[aid];
1889     //zfTxGetIpTosAndFrag(dev, buf, &up, &fragOff);
1890     //ac = zcUpToAc[up&0x7] & 0x3;
1891
1892     /*
1893      * Filter unicast frame only, aid == 0 is for debug only
1894      */
1895     if ((dst0 & 0x1) == 0 && aid == 0)
1896     {
1897 #if ZM_AGG_FPGA_REORDERING
1898         tid_rx = zfAggRxGetQueue(dev, buf) ;
1899         if(!tid_rx)
1900             return NULL;
1901         else
1902         {
1903             //if (tid_rx->addBaExchangeStatusCode == ZM_AGG_ADDBA_RESPONSE)
1904             return tid_rx;
1905         }
1906 #else
1907         return NULL;
1908 #endif
1909     }
1910
1911     return NULL;
1912 }
1913
1914 u16_t zfAggRx(zdev_t* dev, zbuf_t* buf, struct zsAdditionInfo *addInfo, struct agg_tid_rx *tid_rx)
1915 {
1916     u16_t   seq_no;
1917     s16_t   index;
1918     u16_t   offset = 0;
1919     zbuf_t* pbuf;
1920     u8_t    frameSubType;
1921
1922     zmw_get_wlan_dev(dev);
1923
1924     zmw_declare_for_critical_section();
1925
1926     ZM_BUFFER_TRACE(dev, buf)
1927
1928     ZM_PERFORMANCE_RX_REORDER(dev);
1929
1930     seq_no = zmw_rx_buf_readh(dev, buf, offset+22) >> 4;
1931
1932     index = seq_no - tid_rx->seq_start;
1933     /*
1934      * for debug
1935      */
1936
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);
1940      */
1941
1942     //DbgPrint("seq_no=%d, seq_start=%d\n", seq_no, tid_rx->seq_start);
1943
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.
1946      */
1947
1948     frameSubType = (zmw_rx_buf_readh(dev, buf, 0) & 0xF0) >> 4;
1949
1950     /* If this is a NULL data instead of Qos NULL data */
1951     if ((frameSubType & 0x0C) == 0x04)
1952     {
1953         s16_t seq_diff;
1954
1955         seq_diff = (seq_no > tid_rx->seq_start) ?
1956                        seq_no - tid_rx->seq_start : tid_rx->seq_start - seq_no;
1957
1958         if (seq_diff > ZM_AGG_BAW_SIZE)
1959         {
1960             zm_debug_msg0("Free Rx NULL data in zfAggRx");
1961
1962             /* Free Rx buffer */
1963             zfwBufFree(dev, buf, 0);
1964             return ZM_ERR_OUT_OF_ORDER_NULL_DATA;
1965         }
1966     }
1967
1968     /*
1969      * sequence number wrap at 4k
1970      */
1971     if (tid_rx->seq_start > seq_no)
1972     {
1973         //index += 4096;
1974
1975         zmw_enter_critical_section(dev);
1976         if (tid_rx->seq_start >= 4096) {
1977             tid_rx->seq_start = 0;
1978         }
1979         zmw_leave_critical_section(dev);
1980
1981     }
1982
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;
1988         }
1989         tid_rx->seq_start = (tid_rx->seq_start + 1) & (4096 - 1);
1990         zmw_leave_critical_section(dev);
1991
1992         ZM_PERFORMANCE_RX_SEQ(dev, buf);
1993
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);
1998
1999             wd->zfcbRecv80211(dev, buf, addInfo);
2000         }
2001         else {
2002             zfiRecv80211(dev, buf, addInfo);
2003         }
2004     }
2005     else if (!zfAggRxEnqueue(dev, buf, tid_rx, addInfo))
2006     {
2007         /*
2008          * duplicated packet
2009          */
2010         return 1;
2011     }
2012
2013     while (tid_rx->baw_head != tid_rx->baw_tail) {// && tid_rx->frame[tid_rx->baw_tail].buf)
2014         u16_t tailIndex;
2015
2016         zmw_enter_critical_section(dev);
2017
2018         tailIndex = tid_rx->baw_tail;
2019         pbuf = tid_rx->frame[tailIndex].buf;
2020         tid_rx->frame[tailIndex].buf = 0;
2021         if (!pbuf)
2022         {
2023             zmw_leave_critical_section(dev);
2024             break;
2025         }
2026
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);
2029
2030
2031         //if(pbuf && tid_rx->baw_size > 0)
2032         //    tid_rx->baw_size--;
2033
2034         zmw_leave_critical_section(dev);
2035
2036         ZM_PERFORMANCE_RX_SEQ(dev, pbuf);
2037
2038         if (wd->zfcbRecv80211 != NULL)
2039         {
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);
2044         }
2045         else
2046         {
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);
2050         }
2051     }
2052
2053     return 1;
2054 }
2055
2056 struct agg_tid_rx *zfAggRxGetQueue(zdev_t* dev, zbuf_t* buf)
2057 {
2058     u16_t   src[3];
2059     u16_t   aid, ac, i;
2060     u16_t   offset = 0;
2061     struct agg_tid_rx *tid_rx = NULL;
2062
2063     zmw_get_wlan_dev(dev);
2064
2065     //zmw_declare_for_critical_section();
2066
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);
2071
2072     ac = (zmw_rx_buf_readh(dev, buf, 24) & 0xF);
2073
2074     // mark by spin lock debug
2075     //zmw_enter_critical_section(dev);
2076
2077     for (i=0; i<ZM_AGG_POOL_SIZE ; i++)
2078     {
2079         if((wd->tid_rx[i]->aid == aid) && (wd->tid_rx[i]->ac == ac))
2080         {
2081             tid_rx = wd->tid_rx[i];
2082             break;
2083         }
2084     }
2085
2086     // mark by spin lock debug
2087     //zmw_leave_critical_section(dev);
2088     return tid_rx;
2089 }
2090
2091
2092 u16_t   zfAggRxEnqueue(zdev_t* dev, zbuf_t* buf, struct agg_tid_rx *tid_rx, struct zsAdditionInfo *addInfo)
2093 {
2094     u16_t seq_no, offset = 0;
2095     u16_t q_index;
2096     s16_t index;
2097     u8_t  bdropframe = 0;
2098
2099     zmw_get_wlan_dev(dev);
2100
2101     zmw_declare_for_critical_section();
2102
2103     ZM_BUFFER_TRACE(dev, buf)
2104
2105     seq_no = zmw_rx_buf_readh(dev, buf, offset+22) >> 4;
2106     index  = seq_no - tid_rx->seq_start;
2107
2108     /*
2109      * sequence number wrap at 4k
2110      * -1000: check for duplicate past packet
2111      */
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;
2123             }
2124             zmw_leave_critical_section(dev);
2125         } else {
2126             bdropframe = 1;
2127         }
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;
2136             }
2137             zmw_leave_critical_section(dev);
2138         }
2139     }
2140
2141     if (bdropframe == 1) {
2142         /*if (wd->zfcbRecv80211 != NULL) {
2143             wd->zfcbRecv80211(dev, buf, addInfo);
2144         }
2145         else {
2146             zfiRecv80211(dev, buf, addInfo);
2147         }*/
2148
2149         ZM_PERFORMANCE_FREE(dev, buf);
2150
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;
2155         */
2156
2157         //DbgPrint("Free an old packet, seq_start=%d, seq_no=%d\n", tid_rx->seq_start, seq_no);
2158
2159         /*
2160          * duplicate past packet
2161          * happens only in simulated aggregation environment
2162          */
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--;
2168         }
2169
2170         if (tid_rx->sq_behind_count > 0) {
2171             tid_rx->sq_behind_count--;
2172         }
2173         zmw_leave_critical_section(dev);
2174     }
2175
2176     if (index < 0) {
2177         zfAggRxFlush(dev, seq_no, tid_rx);
2178         tid_rx->seq_start = seq_no;
2179         index = 0;
2180     }
2181
2182     //if (index >= (ZM_AGG_BAW_SIZE - 1))
2183     if (index >= (ZM_AGG_BAW_MASK))
2184     {
2185         /*
2186          * queue full
2187          */
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)
2193         {
2194         //index = seq_no - tid_rx->seq_start;
2195             index += 4096;
2196         }
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)
2203             {
2204                 index += 4096;
2205             }
2206         }
2207     }
2208
2209
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)))
2213     {
2214
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);
2219         /*
2220          * duplicate packet
2221          */
2222         return 0;
2223     }
2224
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;
2229     }
2230
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));
2234
2235     /*
2236      * for debug simulated aggregation only,
2237      * should be done in rx of ADDBA Request
2238      */
2239     //tid_rx->addInfo = addInfo;
2240
2241
2242     if (((tid_rx->baw_head - tid_rx->baw_tail) & ZM_AGG_BAW_MASK) <= index)
2243     {
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;
2249     }
2250     zmw_leave_critical_section(dev);
2251
2252     /*
2253      * success
2254      */
2255     //DbgPrint("head=%d, tail=%d, start=%d", tid_rx->baw_head, tid_rx->baw_tail, tid_rx->seq_start);
2256     return 1;
2257 }
2258
2259 u16_t zfAggRxFlush(zdev_t* dev, u16_t seq_no, struct agg_tid_rx *tid_rx)
2260 {
2261     zbuf_t* pbuf;
2262     u16_t   seq;
2263     struct zsAdditionInfo addInfo;
2264     zmw_get_wlan_dev(dev);
2265     zmw_declare_for_critical_section();
2266
2267     ZM_PERFORMANCE_RX_FLUSH(dev);
2268
2269     while (1)
2270     {
2271         zmw_enter_critical_section(dev);
2272         if (tid_rx->baw_tail == tid_rx->baw_head) {
2273             zmw_leave_critical_section(dev);
2274             break;
2275         }
2276
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);
2284
2285         if (pbuf)
2286         {
2287
2288             ZM_PERFORMANCE_RX_SEQ(dev, pbuf);
2289
2290             if (wd->zfcbRecv80211 != NULL)
2291             {
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);
2296             }
2297             else
2298             {
2299                 seq = zmw_rx_buf_readh(dev, pbuf, 22) >> 4;
2300                 //DbgPrint("Recv indicate seq=%d\n", seq);
2301                 zfiRecv80211(dev, pbuf, &addInfo);
2302             }
2303         }
2304     }
2305
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;
2310 }
2311
2312
2313
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)
2331 {
2332     u16_t   i;
2333     zbuf_t* buf;
2334     struct agg_tid_rx *tid_rx;
2335
2336     TID_TX  tid_tx;
2337     //struct bufInfo *buf_info;
2338
2339     zmw_get_wlan_dev(dev);
2340     zmw_declare_for_critical_section();
2341
2342     for (i=0; i<ZM_AGG_POOL_SIZE; i++)
2343     {
2344         u16_t j;
2345
2346         tid_rx = wd->tid_rx[i];
2347
2348         for(j=0; j <= ZM_AGG_BAW_SIZE; j++)
2349         {
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);
2354
2355             if (buf)
2356             {
2357                 zfwBufFree(dev, buf, 0);
2358             }
2359         }
2360
2361         #if 0
2362         if ( tid_rx->baw_head != tid_rx->baw_tail )
2363         {
2364             while (tid_rx->baw_head != tid_rx->baw_tail)
2365             {
2366                 buf = tid_rx->frame[tid_rx->baw_tail].buf;
2367                 tid_rx->frame[tid_rx->baw_tail].buf = 0;
2368                 if (buf)
2369                 {
2370                     zfwBufFree(dev, buf, 0);
2371
2372                     zmw_enter_critical_section(dev);
2373                     tid_rx->frame[tid_rx->baw_tail].buf = 0;
2374                     zmw_leave_critical_section(dev);
2375                 }
2376                 zmw_enter_critical_section(dev);
2377                 //if (tid_rx->baw_size > 0)tid_rx->baw_size--;
2378                 tid_rx->baw_tail = (tid_rx->baw_tail + 1) & ZM_AGG_BAW_MASK;
2379                 tid_rx->seq_start++;
2380                 zmw_leave_critical_section(dev);
2381             }
2382         }
2383         #endif
2384
2385         zmw_enter_critical_section(dev);
2386         tid_rx->seq_start = 0;
2387         tid_rx->baw_head = tid_rx->baw_tail = 0;
2388         tid_rx->aid = ZM_MAX_STA_SUPPORT;
2389         zmw_leave_critical_section(dev);
2390
2391         #ifdef ZM_ENABLE_AGGREGATION
2392         #ifndef ZM_ENABLE_FW_BA_RETRANSMISSION //disable BAW
2393         if (tid_baw->enabled) {
2394             zm_msg1_agg(ZM_LV_0, "Device down, clear BAW queue:", i);
2395             BAW->disable(dev, tid_baw);
2396         }
2397         #endif
2398         #endif
2399         if (1 == wd->aggQPool[i]->aggQEnabled) {
2400             tid_tx = wd->aggQPool[i];
2401             buf = zfAggTxGetVtxq(dev, tid_tx);
2402             while (buf) {
2403                 zfwBufFree(dev, buf, 0);
2404                 buf = zfAggTxGetVtxq(dev, tid_tx);
2405             }
2406         }
2407
2408         if(destroy) {
2409             zfwMemFree(dev, wd->aggQPool[i], sizeof(struct aggQueue));
2410             zfwMemFree(dev, wd->tid_rx[i], sizeof(struct agg_tid_rx));
2411         }
2412     }
2413     #ifdef ZM_ENABLE_AGGREGATION
2414     #ifndef ZM_ENABLE_FW_BA_RETRANSMISSION //disable BAW
2415     if(destroy) zfwMemFree(dev, BAW, sizeof(struct baw_enabler));
2416     #endif
2417     #endif
2418     return ZM_SUCCESS;
2419 }
2420
2421
2422 void zfAggRecvBAR(zdev_t* dev, zbuf_t *buf) {
2423     u16_t start_seq, len;
2424     u8_t i, bitmap[8];
2425     len = zfwBufGetSize(dev, buf);
2426     start_seq = zmw_rx_buf_readh(dev, buf, len-2);
2427     DbgPrint("Received a BAR Control frame, start_seq=%d", start_seq>>4);
2428     /* todo: set the bitmap by reordering buffer! */
2429     for (i=0; i<8; i++) bitmap[i]=0;
2430     zfSendBA(dev, start_seq, bitmap);
2431 }
2432
2433 #ifdef ZM_ENABLE_AGGREGATION
2434 #ifndef ZM_ENABLE_FW_BA_RETRANSMISSION //disable BAW
2435 void zfAggTxRetransmit(zdev_t* dev, struct bufInfo *buf_info, struct aggControl *aggControl, TID_TX tid_tx) {
2436     u16_t removeLen;
2437     u16_t err;
2438
2439     zmw_get_wlan_dev(dev);
2440     if (aggControl && (ZM_AGG_FIRST_MPDU == aggControl->ampduIndication) ) {
2441         tid_tx->bar_ssn = buf_info->baw_header->header[15];
2442         aggControl->tid_baw->start_seq = tid_tx->bar_ssn >> 4;
2443         zm_msg1_agg(ZM_LV_0, "start seq=", tid_tx->bar_ssn >> 4);
2444     }
2445     buf_info->baw_header->header[4] |= (1 << 11);
2446     if (aggControl && aggControl->aggEnabled) {
2447         //if (wd->enableAggregation==0 && !(buf_info->baw_header->header[6]&0x1))
2448         //{
2449             //if (((buf_info->baw_header->header[2] & 0x3) == 2))
2450             //{
2451                 /* Enable aggregation */
2452                 buf_info->baw_header->header[1] |= 0x20;
2453                 if (ZM_AGG_LAST_MPDU == aggControl->ampduIndication) {
2454                     buf_info->baw_header->header[1] |= 0x4000;
2455                 }
2456                 else {
2457                     buf_info->baw_header->header[1] &= ~0x4000;
2458                     //zm_debug_msg0("ZM_AGG_LAST_MPDU");
2459                 }
2460             //}
2461             //else {
2462             //    zm_debug_msg1("no aggr, header[2]&0x3 = ",buf_info->baw_header->header[2] & 0x3)
2463             //    aggControl->aggEnabled = 0;
2464             //}
2465         //}
2466         //else {
2467         //    zm_debug_msg1("no aggr, wd->enableAggregation = ", wd->enableAggregation);
2468         //    zm_debug_msg1("no aggr, !header[6]&0x1 = ",!(buf_info->baw_header->header[6]&0x1));
2469         //    aggControl->aggEnabled = 0;
2470         //}
2471     }
2472
2473     /*if (aggControl->tid_baw) {
2474         struct baw_header_r header_r;
2475
2476         header_r.header      = buf_info->baw_header->header;
2477         header_r.mic         = buf_info->baw_header->mic;
2478         header_r.snap        = buf_info->baw_header->snap;
2479         header_r.headerLen   = buf_info->baw_header->headerLen;
2480         header_r.micLen      = buf_info->baw_header->micLen;
2481         header_r.snapLen     = buf_info->baw_header->snapLen;
2482         header_r.removeLen   = buf_info->baw_header->removeLen;
2483         header_r.keyIdx      = buf_info->baw_header->keyIdx;
2484
2485         BAW->insert(dev, buf_info->buf, tid_tx->bar_ssn >> 4, aggControl->tid_baw, buf_info->baw_retransmit, &header_r);
2486     }*/
2487
2488     err = zfHpSend(dev,
2489                     buf_info->baw_header->header,
2490                     buf_info->baw_header->headerLen,
2491                     buf_info->baw_header->snap,
2492                     buf_info->baw_header->snapLen,
2493                     buf_info->baw_header->mic,
2494                     buf_info->baw_header->micLen,
2495                     buf_info->buf,
2496                     buf_info->baw_header->removeLen,
2497                     ZM_EXTERNAL_ALLOC_BUF,
2498                     (u8_t)tid_tx->ac,
2499                     buf_info->baw_header->keyIdx);
2500     if (err != ZM_SUCCESS)
2501     {
2502         goto zlError;
2503     }
2504
2505     return;
2506
2507 zlError:
2508     zfwBufFree(dev, buf_info->buf, 0);
2509     return;
2510
2511 }
2512 #endif //disable BAW
2513 #endif
2514 /************************************************************************/
2515 /*                                                                      */
2516 /*    FUNCTION DESCRIPTION                  zfAggTxSendEth              */
2517 /*      Called to transmit Ethernet frame from upper elayer.            */
2518 /*                                                                      */
2519 /*    INPUTS                                                            */
2520 /*      dev : device pointer                                            */
2521 /*      buf : buffer pointer                                            */
2522 /*      port : WLAN port, 0=>standard, 0x10-0x17=>VAP, 0x20-0x25=>WDS   */
2523 /*                                                                      */
2524 /*    OUTPUTS                                                           */
2525 /*      error code                                                      */
2526 /*                                                                      */
2527 /*    AUTHOR                                                            */
2528 /*      Stephen, Honda      Atheros Communications, Inc.    2006.12     */
2529 /*                                                                      */
2530 /************************************************************************/
2531 u16_t zfAggTxSendEth(zdev_t* dev, zbuf_t* buf, u16_t port, u16_t bufType, u8_t flag, struct aggControl *aggControl, TID_TX tid_tx)
2532 {
2533     u16_t err;
2534     //u16_t addrTblSize;
2535     //struct zsAddrTbl addrTbl;
2536     u16_t removeLen;
2537     u16_t header[(8+30+2+18)/2];    /* ctr+(4+a1+a2+a3+2+a4)+qos+iv */
2538     u16_t headerLen;
2539     u16_t mic[8/2];
2540     u16_t micLen;
2541     u16_t snap[8/2];
2542     u16_t snapLen;
2543     u16_t fragLen;
2544     u16_t frameLen;
2545     u16_t fragNum;
2546     struct zsFrag frag;
2547     u16_t i, id;
2548     u16_t da[3];
2549     u16_t sa[3];
2550     u8_t up;
2551     u8_t qosType, keyIdx = 0;
2552     u16_t fragOff;
2553
2554     zmw_get_wlan_dev(dev);
2555
2556     zmw_declare_for_critical_section();
2557
2558     zm_msg1_tx(ZM_LV_2, "zfTxSendEth(), port=", port);
2559
2560     /* Get IP TOS for QoS AC and IP frag offset */
2561     zfTxGetIpTosAndFrag(dev, buf, &up, &fragOff);
2562
2563 #ifdef ZM_ENABLE_NATIVE_WIFI
2564     if ( wd->wlanMode == ZM_MODE_INFRASTRUCTURE )
2565     {
2566         /* DA */
2567         da[0] = zmw_tx_buf_readh(dev, buf, 16);
2568         da[1] = zmw_tx_buf_readh(dev, buf, 18);
2569         da[2] = zmw_tx_buf_readh(dev, buf, 20);
2570         /* SA */
2571         sa[0] = zmw_tx_buf_readh(dev, buf, 10);
2572         sa[1] = zmw_tx_buf_readh(dev, buf, 12);
2573         sa[2] = zmw_tx_buf_readh(dev, buf, 14);
2574     }
2575     else if ( wd->wlanMode == ZM_MODE_IBSS )
2576     {
2577         /* DA */
2578         da[0] = zmw_tx_buf_readh(dev, buf, 4);
2579         da[1] = zmw_tx_buf_readh(dev, buf, 6);
2580         da[2] = zmw_tx_buf_readh(dev, buf, 8);
2581         /* SA */
2582         sa[0] = zmw_tx_buf_readh(dev, buf, 10);
2583         sa[1] = zmw_tx_buf_readh(dev, buf, 12);
2584         sa[2] = zmw_tx_buf_readh(dev, buf, 14);
2585     }
2586     else if ( wd->wlanMode == ZM_MODE_AP )
2587     {
2588         /* DA */
2589         da[0] = zmw_tx_buf_readh(dev, buf, 4);
2590         da[1] = zmw_tx_buf_readh(dev, buf, 6);
2591         da[2] = zmw_tx_buf_readh(dev, buf, 8);
2592         /* SA */
2593         sa[0] = zmw_tx_buf_readh(dev, buf, 16);
2594         sa[1] = zmw_tx_buf_readh(dev, buf, 18);
2595         sa[2] = zmw_tx_buf_readh(dev, buf, 20);
2596     }
2597     else
2598     {
2599         //
2600     }
2601 #else
2602     /* DA */
2603     da[0] = zmw_tx_buf_readh(dev, buf, 0);
2604     da[1] = zmw_tx_buf_readh(dev, buf, 2);
2605     da[2] = zmw_tx_buf_readh(dev, buf, 4);
2606     /* SA */
2607     sa[0] = zmw_tx_buf_readh(dev, buf, 6);
2608     sa[1] = zmw_tx_buf_readh(dev, buf, 8);
2609     sa[2] = zmw_tx_buf_readh(dev, buf, 10);
2610 #endif
2611     //Decide Key Index in ATOM, No meaning in OTUS--CWYang(m)
2612     if (wd->wlanMode == ZM_MODE_AP)
2613     {
2614         keyIdx = wd->ap.bcHalKeyIdx[port];
2615         id = zfApFindSta(dev, da);
2616         if (id != 0xffff)
2617         {
2618             switch (wd->ap.staTable[id].encryMode)
2619             {
2620             case ZM_AES:
2621             case ZM_TKIP:
2622 #ifdef ZM_ENABLE_CENC
2623             case ZM_CENC:
2624 #endif //ZM_ENABLE_CENC
2625                 keyIdx = wd->ap.staTable[id].keyIdx;
2626                 break;
2627             }
2628         }
2629     }
2630     else
2631     {
2632         switch (wd->sta.encryMode)
2633         {
2634         case ZM_WEP64:
2635         case ZM_WEP128:
2636         case ZM_WEP256:
2637             keyIdx = wd->sta.keyId;
2638             break;
2639         case ZM_AES:
2640         case ZM_TKIP:
2641             if ((da[0]& 0x1))
2642                 keyIdx = 5;
2643             else
2644                 keyIdx = 4;
2645             break;
2646 #ifdef ZM_ENABLE_CENC
2647         case ZM_CENC:
2648             keyIdx = wd->sta.cencKeyId;
2649             break;
2650 #endif //ZM_ENABLE_CENC
2651         }
2652     }
2653
2654     /* Create SNAP */
2655     removeLen = zfTxGenWlanSnap(dev, buf, snap, &snapLen);
2656     //zm_msg1_tx(ZM_LV_0, "fragOff=", fragOff);
2657
2658     fragLen = wd->fragThreshold;
2659     frameLen = zfwBufGetSize(dev, buf);
2660     frameLen -= removeLen;
2661
2662 #if 0
2663     /* Create MIC */
2664     if ( (wd->wlanMode == ZM_MODE_INFRASTRUCTURE)&&
2665          (wd->sta.encryMode == ZM_TKIP) )
2666     {
2667         if ( frameLen > fragLen )
2668         {
2669             micLen = zfTxGenWlanTail(dev, buf, snap, snapLen, mic);
2670         }
2671         else
2672         {
2673             /* append MIC by HMAC */
2674             micLen = 8;
2675         }
2676     }
2677     else
2678     {
2679         micLen = 0;
2680     }
2681 #else
2682     if ( frameLen > fragLen )
2683     {
2684         micLen = zfTxGenWlanTail(dev, buf, snap, snapLen, mic);
2685     }
2686     else
2687     {
2688         /* append MIC by HMAC */
2689         micLen = 0;
2690     }
2691 #endif
2692
2693     /* Access Category */
2694     if (wd->wlanMode == ZM_MODE_AP)
2695     {
2696         zfApGetStaQosType(dev, da, &qosType);
2697         if (qosType == 0)
2698         {
2699             up = 0;
2700         }
2701     }
2702     else if (wd->wlanMode == ZM_MODE_INFRASTRUCTURE)
2703     {
2704         if (wd->sta.wmeConnected == 0)
2705         {
2706             up = 0;
2707         }
2708     }
2709     else
2710     {
2711         /* TODO : STA QoS control field */
2712         up = 0;
2713     }
2714
2715     /* Assign sequence number */
2716     zmw_enter_critical_section(dev);
2717     frag.seq[0] = ((wd->seq[zcUpToAc[up&0x7]]++) << 4);
2718     if (aggControl && (ZM_AGG_FIRST_MPDU == aggControl->ampduIndication) ) {
2719         tid_tx->bar_ssn = frag.seq[0];
2720
2721         zm_msg1_agg(ZM_LV_0, "start seq=", tid_tx->bar_ssn >> 4);
2722     }
2723     //tid_tx->baw_buf[tid_tx->baw_head-1].baw_seq=frag.seq[0];
2724     zmw_leave_critical_section(dev);
2725
2726
2727         frag.buf[0] = buf;
2728         frag.bufType[0] = bufType;
2729         frag.flag[0] = flag;
2730         fragNum = 1;
2731
2732     for (i=0; i<fragNum; i++)
2733     {
2734         /* Create WLAN header(Control Setting + 802.11 header + IV) */
2735         if (up !=0 ) zm_debug_msg1("up not 0, up=",up);
2736         headerLen = zfTxGenWlanHeader(dev, frag.buf[i], header, frag.seq[i],
2737                                       frag.flag[i], snapLen+micLen, removeLen,
2738                                       port, da, sa, up, &micLen, snap, snapLen,
2739                                       aggControl);
2740
2741         /* Get buffer DMA address */
2742         //if ((addrTblSize = zfwBufMapDma(dev, frag.buf[i], &addrTbl)) == 0)
2743         //if ((addrTblSize = zfwMapTxDma(dev, frag.buf[i], &addrTbl)) == 0)
2744         //{
2745         //    err = ZM_ERR_BUFFER_DMA_ADDR;
2746         //    goto zlError;
2747         //}
2748
2749         /* Flush buffer on cache */
2750         //zfwBufFlush(dev, frag.buf[i]);
2751
2752 #if 0
2753         zm_msg1_tx(ZM_LV_0, "headerLen=", headerLen);
2754         zm_msg1_tx(ZM_LV_0, "snapLen=", snapLen);
2755         zm_msg1_tx(ZM_LV_0, "micLen=", micLen);
2756         zm_msg1_tx(ZM_LV_0, "removeLen=", removeLen);
2757         zm_msg1_tx(ZM_LV_0, "addrTblSize=", addrTblSize);
2758         zm_msg1_tx(ZM_LV_0, "frag.bufType[0]=", frag.bufType[0]);
2759 #endif
2760
2761         fragLen = zfwBufGetSize(dev, frag.buf[i]);
2762         if ((da[0]&0x1) == 0)
2763         {
2764             wd->commTally.txUnicastFrm++;
2765             wd->commTally.txUnicastOctets += (fragLen+snapLen);
2766         }
2767         else if ((da[0]& 0x1))
2768         {
2769             wd->commTally.txBroadcastFrm++;
2770             wd->commTally.txBroadcastOctets += (fragLen+snapLen);
2771         }
2772         else
2773         {
2774             wd->commTally.txMulticastFrm++;
2775             wd->commTally.txMulticastOctets += (fragLen+snapLen);
2776         }
2777         wd->ledStruct.txTraffic++;
2778
2779 #if 0 //Who care this?
2780         if ( (i)&&(i == (fragNum-1)) )
2781         {
2782             wd->trafTally.txDataByteCount -= micLen;
2783         }
2784 #endif
2785
2786         /*if (aggControl->tid_baw && aggControl->aggEnabled) {
2787             struct baw_header_r header_r;
2788
2789             header_r.header      = header;
2790             header_r.mic         = mic;
2791             header_r.snap        = snap;
2792             header_r.headerLen   = headerLen;
2793             header_r.micLen      = micLen;
2794             header_r.snapLen     = snapLen;
2795             header_r.removeLen   = removeLen;
2796             header_r.keyIdx      = keyIdx;
2797
2798             BAW->insert(dev, buf, tid_tx->bar_ssn >> 4, aggControl->tid_baw, 0, &header_r);
2799         }*/
2800
2801         err = zfHpSend(dev, header, headerLen, snap, snapLen,
2802                              mic, micLen, frag.buf[i], removeLen,
2803                              frag.bufType[i], zcUpToAc[up&0x7], keyIdx);
2804         if (err != ZM_SUCCESS)
2805         {
2806             goto zlError;
2807         }
2808
2809
2810         continue;
2811
2812 zlError:
2813         if (frag.bufType[i] == ZM_EXTERNAL_ALLOC_BUF)
2814         {
2815             zfwBufFree(dev, frag.buf[i], err);
2816         }
2817         else if (frag.bufType[i] == ZM_INTERNAL_ALLOC_BUF)
2818         {
2819             zfwBufFree(dev, frag.buf[i], 0);
2820         }
2821         else
2822         {
2823             zm_assert(0);
2824         }
2825     } /* for (i=0; i<fragNum; i++) */
2826
2827     return ZM_SUCCESS;
2828 }
2829
2830 /*
2831  * zfAggSendADDBA() refers zfSendMmFrame() in cmm.c
2832  */
2833 u16_t   zfAggSendAddbaRequest(zdev_t* dev, u16_t *dst, u16_t ac, u16_t up)
2834 {
2835     zbuf_t* buf;
2836     //u16_t addrTblSize;
2837     //struct zsAddrTbl addrTbl;
2838     //u16_t err;
2839     u16_t offset = 0;
2840     u16_t hlen = 32;
2841     u16_t header[(24+25+1)/2];
2842     u16_t vap = 0;
2843     u16_t i;
2844     u8_t encrypt = 0;
2845
2846     //zmw_get_wlan_dev(dev);
2847
2848     //zmw_declare_for_critical_section();
2849
2850
2851     /*
2852      * TBD : Maximum size of management frame
2853      */
2854     buf = zfwBufAllocate(dev, 1024);
2855     if (buf == NULL)
2856     {
2857         zm_msg0_mm(ZM_LV_0, "Alloc mm buf Fail!");
2858         return ZM_SUCCESS;
2859     }
2860
2861     /*
2862      * Reserve room for wlan header
2863      */
2864     offset = hlen;
2865
2866     /*
2867      * add addba frame body
2868      */
2869     offset = zfAggSetAddbaFrameBody(dev, buf, offset, ac, up);
2870
2871
2872     zfwBufSetSize(dev, buf, offset);
2873
2874     /*
2875      * Copy wlan header
2876      */
2877     zfAggGenAddbaHeader(dev, dst, header, offset-hlen, buf, vap, encrypt);
2878     for (i=0; i<(hlen>>1); i++)
2879     {
2880         zmw_tx_buf_writeh(dev, buf, i*2, header[i]);
2881     }
2882
2883     /* Get buffer DMA address */
2884     //if ((addrTblSize = zfwBufMapDma(dev, buf, &addrTbl)) == 0)
2885     //if ((addrTblSize = zfwMapTxDma(dev, buf, &addrTbl)) == 0)
2886     //{
2887     //    goto zlError;
2888     //}
2889
2890     //zm_msg2_mm(ZM_LV_2, "offset=", offset);
2891     //zm_msg2_mm(ZM_LV_2, "hlen=", hlen);
2892     //zm_msg2_mm(ZM_LV_2, "addrTblSize=", addrTblSize);
2893     //zm_msg2_mm(ZM_LV_2, "addrTbl.len[0]=", addrTbl.len[0]);
2894     //zm_msg2_mm(ZM_LV_2, "addrTbl.physAddrl[0]=", addrTbl.physAddrl[0]);
2895     //zm_msg2_mm(ZM_LV_2, "buf->data=", buf->data);
2896
2897     #if 0
2898     err = zfHpSend(dev, NULL, 0, NULL, 0, NULL, 0, buf, 0,
2899                    ZM_INTERNAL_ALLOC_BUF, 0, 0xff);
2900     if (err != ZM_SUCCESS)
2901     {
2902         goto zlError;
2903     }
2904     #else
2905     zfPutVmmq(dev, buf);
2906     zfPushVtxq(dev);
2907     #endif
2908
2909     return ZM_SUCCESS;
2910
2911 }
2912
2913 u16_t   zfAggSetAddbaFrameBody(zdev_t* dev, zbuf_t* buf, u16_t offset, u16_t ac, u16_t up)
2914 {
2915     u16_t ba_parameter, start_seq;
2916
2917     zmw_get_wlan_dev(dev);
2918
2919     //zmw_declare_for_critical_section();
2920     /*
2921      * ADDBA Request frame body
2922      */
2923
2924     /*
2925      * Category
2926      */
2927     zmw_tx_buf_writeb(dev, buf, offset++, 3);
2928     /*
2929      * Action details = 0
2930      */
2931     zmw_tx_buf_writeb(dev, buf, offset++, ZM_WLAN_ADDBA_REQUEST_FRAME);
2932     /*
2933      * Dialog Token = nonzero
2934      * TBD: define how to get dialog token?
2935      */
2936     zmw_tx_buf_writeb(dev, buf, offset++, 2);
2937     /*
2938      * Block Ack parameter set
2939      * BA policy = 1 for immediate BA, 0 for delayed BA
2940      * TID(4bits) & buffer size(4bits) (TID=up & buffer size=0x80)
2941      * TBD: how to get buffer size?
2942      * ¢z¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢s¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢s¢w¢w¢w¢w¢w¢w¢w¢w¢s¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢{
2943      * ¢x    B0    ¢x    B1     ¢x B2  B5 ¢x B6      B15 ¢x
2944      * ¢u¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢q¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢q¢w¢w¢w¢w¢w¢w¢w¢w¢q¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢t
2945      * ¢x Reserved ¢x BA policy ¢x  TID   ¢x Buffer size ¢x
2946      * ¢|¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢r¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢r¢w¢w¢w¢w¢w¢w¢w¢w¢r¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢}
2947      */
2948     ba_parameter = 1 << 12;     // buffer size = 0x40(64)
2949     ba_parameter |= up << 2;    // tid = up
2950     ba_parameter |= 2;          // ba policy = 1
2951     zmw_tx_buf_writeh(dev, buf, offset, ba_parameter);
2952     offset+=2;
2953     /*
2954      * BA timeout value
2955      */
2956     zmw_tx_buf_writeh(dev, buf, offset, 0);
2957     offset+=2;
2958     /*
2959      * BA starting sequence number
2960      * ¢z¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢s¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢{
2961      * ¢x B0       B3 ¢x B4              B15 ¢x
2962      * ¢u¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢q¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢t
2963      * ¢x Frag num(0) ¢x BA starting seq num ¢x
2964      * ¢|¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢r¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢}
2965      */
2966     start_seq = ((wd->seq[ac]) << 4) & 0xFFF0;
2967     zmw_tx_buf_writeh(dev, buf, offset, start_seq);
2968     offset+=2;
2969
2970     return offset;
2971 }
2972
2973 u16_t zfAggGenAddbaHeader(zdev_t* dev, u16_t* dst,
2974         u16_t* header, u16_t len, zbuf_t* buf, u16_t vap, u8_t encrypt)
2975 {
2976     u8_t  hlen = 32;        // MAC ctrl + PHY ctrl + 802.11 MM header
2977     //u8_t frameType = ZM_WLAN_FRAME_TYPE_ACTION;
2978
2979     zmw_get_wlan_dev(dev);
2980
2981     zmw_declare_for_critical_section();
2982
2983     /*
2984      * Generate control setting
2985      */
2986     //bodyLen = zfwBufGetSize(dev, buf);
2987     header[0] = 24+len+4;   //Length
2988     header[1] = 0x8;        //MAC control, backoff + (ack)
2989
2990 #if 0
2991     /* CCK 1M */
2992     header[2] = 0x0f00;          //PHY control L
2993     header[3] = 0x0000;          //PHY control H
2994 #else
2995     /* OFDM 6M */
2996     header[2] = 0x0f01;          //PHY control L
2997     header[3] = 0x000B;          //PHY control H
2998 #endif
2999
3000     /*
3001      * Generate WLAN header
3002      * Frame control frame type and subtype
3003      */
3004     header[4+0] = ZM_WLAN_FRAME_TYPE_ACTION;
3005     /*
3006      * Duration
3007      */
3008     header[4+1] = 0;
3009
3010     if (wd->wlanMode == ZM_MODE_INFRASTRUCTURE)
3011     {
3012         header[4+8] = wd->sta.bssid[0];
3013         header[4+9] = wd->sta.bssid[1];
3014         header[4+10] = wd->sta.bssid[2];
3015     }
3016     else if (wd->wlanMode == ZM_MODE_PSEUDO)
3017     {
3018         /* Address 3 = 00:00:00:00:00:00 */
3019         header[4+8] = 0;
3020         header[4+9] = 0;
3021         header[4+10] = 0;
3022     }
3023     else if (wd->wlanMode == ZM_MODE_IBSS)
3024     {
3025         header[4+8] = wd->sta.bssid[0];
3026         header[4+9] = wd->sta.bssid[1];
3027         header[4+10] = wd->sta.bssid[2];
3028     }
3029     else if (wd->wlanMode == ZM_MODE_AP)
3030     {
3031         /* Address 3 = BSSID */
3032         header[4+8] = wd->macAddr[0];
3033         header[4+9] = wd->macAddr[1];
3034         header[4+10] = wd->macAddr[2] + (vap<<8);
3035     }
3036
3037     /* Address 1 = DA */
3038     header[4+2] = dst[0];
3039     header[4+3] = dst[1];
3040     header[4+4] = dst[2];
3041
3042     /* Address 2 = SA */
3043     header[4+5] = wd->macAddr[0];
3044     header[4+6] = wd->macAddr[1];
3045     if (wd->wlanMode == ZM_MODE_AP)
3046     {
3047         header[4+7] = wd->macAddr[2] + (vap<<8);
3048     }
3049     else
3050     {
3051         header[4+7] = wd->macAddr[2];
3052     }
3053
3054     /* Sequence Control */
3055     zmw_enter_critical_section(dev);
3056     header[4+11] = ((wd->mmseq++)<<4);
3057     zmw_leave_critical_section(dev);
3058
3059
3060     return hlen;
3061 }
3062
3063
3064 u16_t   zfAggProcessAction(zdev_t* dev, zbuf_t* buf)
3065 {
3066     u16_t category;
3067
3068     //zmw_get_wlan_dev(dev);
3069
3070     //zmw_declare_for_critical_section();
3071
3072     category = zmw_rx_buf_readb(dev, buf, 24);
3073
3074     switch (category)
3075     {
3076     case ZM_WLAN_BLOCK_ACK_ACTION_FRAME:
3077         zfAggBlockAckActionFrame(dev, buf);
3078         break;
3079
3080     }
3081
3082     return ZM_SUCCESS;
3083 }
3084
3085
3086 u16_t   zfAggBlockAckActionFrame(zdev_t* dev, zbuf_t* buf)
3087 {
3088     u8_t action;
3089
3090     //zmw_get_wlan_dev(dev);
3091
3092     //zmw_declare_for_critical_section();
3093
3094     action = zmw_rx_buf_readb(dev, buf, 25);
3095 #ifdef ZM_ENABLE_AGGREGATION
3096     switch (action)
3097     {
3098     case ZM_WLAN_ADDBA_REQUEST_FRAME:
3099         zm_msg0_agg(ZM_LV_0, "Received BA Action frame is ADDBA request");
3100         zfAggRecvAddbaRequest(dev, buf);
3101         break;
3102     case ZM_WLAN_ADDBA_RESPONSE_FRAME:
3103         zm_msg0_agg(ZM_LV_0, "Received BA Action frame is ADDBA response");
3104         zfAggRecvAddbaResponse(dev, buf);
3105         break;
3106     case ZM_WLAN_DELBA_FRAME:
3107         zfAggRecvDelba(dev, buf);
3108         break;
3109     }
3110 #endif
3111     return ZM_SUCCESS;
3112 }
3113
3114 u16_t   zfAggRecvAddbaRequest(zdev_t* dev, zbuf_t* buf)
3115 {
3116     //u16_t dialog;
3117     struct aggBaFrameParameter bf;
3118     u16_t i;
3119     //zmw_get_wlan_dev(dev);
3120
3121     //zmw_declare_for_critical_section();
3122
3123     bf.buf = buf;
3124     bf.dialog = zmw_rx_buf_readb(dev, buf, 26);
3125     /*
3126      * ba parameter set
3127      */
3128     bf.ba_parameter = zmw_rx_buf_readh(dev, buf, 27);
3129     bf.ba_policy   = (bf.ba_parameter >> 1) & 1;
3130     bf.tid         = (bf.ba_parameter >> 2) & 0xF;
3131     bf.buffer_size = (bf.ba_parameter >> 6);
3132     /*
3133      * BA timeout value
3134      */
3135     bf.ba_timeout = zmw_rx_buf_readh(dev, buf, 29);
3136     /*
3137      * BA starting sequence number
3138      */
3139     bf.ba_start_seq = zmw_rx_buf_readh(dev, buf, 31) >> 4;
3140
3141     i=26;
3142     while(i < 32) {
3143         zm_debug_msg2("Recv ADDBA Req:", zmw_rx_buf_readb(dev,buf,i));
3144         i++;
3145     }
3146
3147     zfAggSendAddbaResponse(dev, &bf);
3148
3149     zfAggAddbaSetTidRx(dev, buf, &bf);
3150
3151     return ZM_SUCCESS;
3152 }
3153
3154 u16_t   zfAggAddbaSetTidRx(zdev_t* dev, zbuf_t* buf, struct aggBaFrameParameter *bf)
3155 {
3156     u16_t i, ac, aid, fragOff;
3157     u16_t src[3];
3158     u16_t offset = 0;
3159     u8_t  up;
3160     struct agg_tid_rx *tid_rx = NULL;
3161
3162     zmw_get_wlan_dev(dev);
3163
3164     zmw_declare_for_critical_section();
3165
3166     src[0] = zmw_rx_buf_readh(dev, buf, offset+10);
3167     src[1] = zmw_rx_buf_readh(dev, buf, offset+12);
3168     src[2] = zmw_rx_buf_readh(dev, buf, offset+14);
3169     aid = zfApFindSta(dev, src);
3170
3171     zfTxGetIpTosAndFrag(dev, buf, &up, &fragOff);
3172     ac = zcUpToAc[up&0x7] & 0x3;
3173
3174     ac = bf->tid;
3175
3176     for (i=0; i<ZM_AGG_POOL_SIZE ; i++)
3177     {
3178         if((wd->tid_rx[i]->aid == aid) && (wd->tid_rx[i]->ac == ac))
3179         {
3180             tid_rx = wd->tid_rx[i];
3181             break;
3182         }
3183     }
3184
3185     if (!tid_rx)
3186     {
3187         for (i=0; i<ZM_AGG_POOL_SIZE; i++)
3188         {
3189             if (wd->tid_rx[i]->aid == ZM_MAX_STA_SUPPORT)
3190             {
3191                 tid_rx = wd->tid_rx[i];
3192                 break;
3193             }
3194         }
3195         if (!tid_rx)
3196             return 0;
3197     }
3198
3199     zmw_enter_critical_section(dev);
3200
3201     tid_rx->aid = aid;
3202     tid_rx->ac = ac;
3203     tid_rx->addBaExchangeStatusCode = ZM_AGG_ADDBA_RESPONSE;
3204     tid_rx->seq_start = bf->ba_start_seq;
3205     tid_rx->baw_head = tid_rx->baw_tail = 0;
3206     tid_rx->sq_exceed_count = tid_rx->sq_behind_count = 0;
3207     zmw_leave_critical_section(dev);
3208
3209     return 0;
3210 }
3211
3212 u16_t   zfAggRecvAddbaResponse(zdev_t* dev, zbuf_t* buf)
3213 {
3214     u16_t i,ac, aid=0;
3215     u16_t src[3];
3216     struct aggBaFrameParameter bf;
3217
3218     zmw_get_wlan_dev(dev);
3219
3220     //zmw_declare_for_critical_section();
3221
3222     src[0] = zmw_rx_buf_readh(dev, buf, 10);
3223     src[1] = zmw_rx_buf_readh(dev, buf, 12);
3224     src[2] = zmw_rx_buf_readh(dev, buf, 14);
3225
3226     if (wd->wlanMode == ZM_MODE_AP)
3227         aid = zfApFindSta(dev, src);
3228
3229
3230     bf.buf = buf;
3231     bf.dialog = zmw_rx_buf_readb(dev, buf, 26);
3232     bf.status_code = zmw_rx_buf_readh(dev, buf, 27);
3233     if (!bf.status_code)
3234     {
3235         wd->addbaComplete=1;
3236     }
3237
3238     /*
3239      * ba parameter set
3240      */
3241     bf.ba_parameter = zmw_rx_buf_readh(dev, buf, 29);
3242     bf.ba_policy   = (bf.ba_parameter >> 1) & 1;
3243     bf.tid         = (bf.ba_parameter >> 2) & 0xF;
3244     bf.buffer_size = (bf.ba_parameter >> 6);
3245     /*
3246      * BA timeout value
3247      */
3248     bf.ba_timeout = zmw_rx_buf_readh(dev, buf, 31);
3249
3250     i=26;
3251     while(i < 32) {
3252         zm_debug_msg2("Recv ADDBA Rsp:", zmw_rx_buf_readb(dev,buf,i));
3253         i++;
3254     }
3255
3256     ac = zcUpToAc[bf.tid&0x7] & 0x3;
3257
3258     //zmw_enter_critical_section(dev);
3259
3260     //wd->aggSta[aid].aggFlag[ac] = 0;
3261
3262     //zmw_leave_critical_section(dev);
3263
3264     return ZM_SUCCESS;
3265 }
3266
3267 u16_t   zfAggRecvDelba(zdev_t* dev, zbuf_t* buf)
3268 {
3269     //zmw_get_wlan_dev(dev);
3270
3271     //zmw_declare_for_critical_section();
3272     return ZM_SUCCESS;
3273 }
3274
3275 u16_t   zfAggSendAddbaResponse(zdev_t* dev, struct aggBaFrameParameter *bf)
3276 {
3277     zbuf_t* buf;
3278     //u16_t addrTblSize;
3279     //struct zsAddrTbl addrTbl;
3280     //u16_t err;
3281     u16_t offset = 0;
3282     u16_t hlen = 32;
3283     u16_t header[(24+25+1)/2];
3284     u16_t vap = 0;
3285     u16_t i;
3286     u8_t encrypt = 0;
3287     u16_t dst[3];
3288
3289     //zmw_get_wlan_dev(dev);
3290
3291     //zmw_declare_for_critical_section();
3292
3293
3294     /*
3295      * TBD : Maximum size of management frame
3296      */
3297     buf = zfwBufAllocate(dev, 1024);
3298     if (buf == NULL)
3299     {
3300         zm_msg0_mm(ZM_LV_0, "Alloc mm buf Fail!");
3301         return ZM_SUCCESS;
3302     }
3303
3304     /*
3305      * Reserve room for wlan header
3306      */
3307     offset = hlen;
3308
3309     /*
3310      * add addba frame body
3311      */
3312     offset = zfAggSetAddbaResponseFrameBody(dev, buf, bf, offset);
3313
3314
3315     zfwBufSetSize(dev, buf, offset);
3316
3317     /*
3318      * Copy wlan header
3319      */
3320
3321     dst[0] = zmw_rx_buf_readh(dev, bf->buf, 10);
3322     dst[1] = zmw_rx_buf_readh(dev, bf->buf, 12);
3323     dst[2] = zmw_rx_buf_readh(dev, bf->buf, 14);
3324     zfAggGenAddbaHeader(dev, dst, header, offset-hlen, buf, vap, encrypt);
3325     for (i=0; i<(hlen>>1); i++)
3326     {
3327         zmw_tx_buf_writeh(dev, buf, i*2, header[i]);
3328     }
3329
3330     /* Get buffer DMA address */
3331     //if ((addrTblSize = zfwBufMapDma(dev, buf, &addrTbl)) == 0)
3332     //if ((addrTblSize = zfwMapTxDma(dev, buf, &addrTbl)) == 0)
3333     //{
3334     //    goto zlError;
3335     //}
3336
3337     //zm_msg2_mm(ZM_LV_2, "offset=", offset);
3338     //zm_msg2_mm(ZM_LV_2, "hlen=", hlen);
3339     //zm_msg2_mm(ZM_LV_2, "addrTblSize=", addrTblSize);
3340     //zm_msg2_mm(ZM_LV_2, "addrTbl.len[0]=", addrTbl.len[0]);
3341     //zm_msg2_mm(ZM_LV_2, "addrTbl.physAddrl[0]=", addrTbl.physAddrl[0]);
3342     //zm_msg2_mm(ZM_LV_2, "buf->data=", buf->data);
3343
3344     #if 0
3345     err = zfHpSend(dev, NULL, 0, NULL, 0, NULL, 0, buf, 0,
3346                    ZM_INTERNAL_ALLOC_BUF, 0, 0xff);
3347     if (err != ZM_SUCCESS)
3348     {
3349         goto zlError;
3350     }
3351     #else
3352     zfPutVmmq(dev, buf);
3353     zfPushVtxq(dev);
3354     #endif
3355
3356     //zfAggSendAddbaRequest(dev, dst, zcUpToAc[bf->tid&0x7] & 0x3, bf->tid);
3357     return ZM_SUCCESS;
3358
3359 }
3360
3361 u16_t   zfAggSetAddbaResponseFrameBody(zdev_t* dev, zbuf_t* buf,
3362                 struct aggBaFrameParameter *bf, u16_t offset)
3363 {
3364
3365     //zmw_get_wlan_dev(dev);
3366
3367     //zmw_declare_for_critical_section();
3368     /*
3369      * ADDBA Request frame body
3370      */
3371
3372     /*
3373      * Category
3374      */
3375     zmw_tx_buf_writeb(dev, buf, offset++, 3);
3376     /*
3377      * Action details = 0
3378      */
3379     zmw_tx_buf_writeb(dev, buf, offset++, ZM_WLAN_ADDBA_RESPONSE_FRAME);
3380     /*
3381      * Dialog Token = nonzero
3382      */
3383     zmw_tx_buf_writeb(dev, buf, offset++, bf->dialog);
3384     /*
3385      * Status code
3386      */
3387     zmw_tx_buf_writeh(dev, buf, offset, 0);
3388     offset+=2;
3389     /*
3390      * Block Ack parameter set
3391      * BA policy = 1 for immediate BA, 0 for delayed BA
3392      * TID(4bits) & buffer size(4bits) (TID=0x1 & buffer size=0x80)
3393      * TBD: how to get TID number and buffer size?
3394      * ¢z¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢s¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢s¢w¢w¢w¢w¢w¢w¢w¢w¢s¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢{
3395      * ¢x    B0    ¢x    B1     ¢x B2  B5 ¢x B6      B15 ¢x
3396      * ¢u¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢q¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢q¢w¢w¢w¢w¢w¢w¢w¢w¢q¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢t
3397      * ¢x Reserved ¢x BA policy ¢x  TID   ¢x Buffer size ¢x
3398      * ¢|¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢r¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢r¢w¢w¢w¢w¢w¢w¢w¢w¢r¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢}
3399      */
3400     zmw_tx_buf_writeh(dev, buf, offset, bf->ba_parameter);
3401     offset+=2;
3402     /*
3403      * BA timeout value
3404      */
3405     zmw_tx_buf_writeh(dev, buf, offset, bf->ba_timeout);
3406     offset+=2;
3407
3408     return offset;
3409 }
3410
3411 void   zfAggInvokeBar(zdev_t* dev, TID_TX tid_tx)
3412 {
3413     struct aggBarControl aggBarControl;
3414     //zmw_get_wlan_dev(dev);
3415
3416     //zmw_declare_for_critical_section();
3417     //bar_control = aggBarControl->tid_info << 12 | aggBarControl->compressed_bitmap << 2
3418     //        | aggBarControl->multi_tid << 1 | aggBarControl->bar_ack_policy;
3419     aggBarControl.bar_ack_policy = 0;
3420     aggBarControl.multi_tid = 0;
3421     aggBarControl.compressed_bitmap = 0;
3422     aggBarControl.tid_info = tid_tx->tid;
3423     zfAggSendBar(dev, tid_tx, &aggBarControl);
3424
3425     return;
3426
3427 }
3428 /*
3429  * zfAggSendBar() refers zfAggSendAddbaRequest()
3430  */
3431 u16_t   zfAggSendBar(zdev_t* dev, TID_TX tid_tx, struct aggBarControl *aggBarControl)
3432 {
3433     zbuf_t* buf;
3434     //u16_t addrTblSize;
3435     //struct zsAddrTbl addrTbl;
3436     //u16_t err;
3437     u16_t offset = 0;
3438     u16_t hlen = 16+8;  /* mac header + control headers*/
3439     u16_t header[(8+24+1)/2];
3440     u16_t vap = 0;
3441     u16_t i;
3442     u8_t encrypt = 0;
3443
3444     //zmw_get_wlan_dev(dev);
3445
3446     //zmw_declare_for_critical_section();
3447
3448
3449     /*
3450      * TBD : Maximum size of management frame
3451      */
3452     buf = zfwBufAllocate(dev, 1024);
3453     if (buf == NULL)
3454     {
3455         zm_msg0_mm(ZM_LV_0, "Alloc mm buf Fail!");
3456         return ZM_SUCCESS;
3457     }
3458
3459     /*
3460      * Reserve room for wlan header
3461      */
3462     offset = hlen;
3463
3464     /*
3465      * add addba frame body
3466      */
3467     offset = zfAggSetBarBody(dev, buf, offset, tid_tx, aggBarControl);
3468
3469
3470     zfwBufSetSize(dev, buf, offset);
3471
3472     /*
3473      * Copy wlan header
3474      */
3475     zfAggGenBarHeader(dev, tid_tx->dst, header, offset-hlen, buf, vap, encrypt);
3476     for (i=0; i<(hlen>>1); i++)
3477     {
3478         zmw_tx_buf_writeh(dev, buf, i*2, header[i]);
3479     }
3480
3481     /* Get buffer DMA address */
3482     //if ((addrTblSize = zfwBufMapDma(dev, buf, &addrTbl)) == 0)
3483     //if ((addrTblSize = zfwMapTxDma(dev, buf, &addrTbl)) == 0)
3484     //{
3485     //    goto zlError;
3486     //}
3487
3488     //zm_msg2_mm(ZM_LV_2, "offset=", offset);
3489     //zm_msg2_mm(ZM_LV_2, "hlen=", hlen);
3490     //zm_msg2_mm(ZM_LV_2, "addrTblSize=", addrTblSize);
3491     //zm_msg2_mm(ZM_LV_2, "addrTbl.len[0]=", addrTbl.len[0]);
3492     //zm_msg2_mm(ZM_LV_2, "addrTbl.physAddrl[0]=", addrTbl.physAddrl[0]);
3493     //zm_msg2_mm(ZM_LV_2, "buf->data=", buf->data);
3494
3495     #if 0
3496     err = zfHpSend(dev, NULL, 0, NULL, 0, NULL, 0, buf, 0,
3497                    ZM_INTERNAL_ALLOC_BUF, 0, 0xff);
3498     if (err != ZM_SUCCESS)
3499     {
3500         goto zlError;
3501     }
3502     #else
3503     zfPutVmmq(dev, buf);
3504     zfPushVtxq(dev);
3505     #endif
3506
3507     return ZM_SUCCESS;
3508
3509 }
3510
3511 u16_t   zfAggSetBarBody(zdev_t* dev, zbuf_t* buf, u16_t offset, TID_TX tid_tx, struct aggBarControl *aggBarControl)
3512 {
3513     u16_t bar_control, start_seq;
3514
3515     //zmw_get_wlan_dev(dev);
3516
3517     //zmw_declare_for_critical_section();
3518     /*
3519      * BAR Control frame body
3520      */
3521
3522     /*
3523      * BAR Control Field
3524      * ¢z¢w¢w¢w¢w¢w¢w¢w¢w¢w¢s¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢s¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢s¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢s¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢{
3525      * ¢x    B0   ¢x    B1     ¢x     B2     ¢x B3   B11 ¢x B12  B15 ¢x
3526      * ¢u¢w¢w¢w¢w¢w¢w¢w¢w¢w¢q¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢q¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢q¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢q¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢t
3527      * ¢x BAR Ack ¢x Multi-TID ¢x Compressed ¢x Reserved ¢x TID_INFO ¢x
3528      * ¢x  Policy ¢x           ¢x   Bitmap   ¢x          ¢x          ¢x
3529      * ¢|¢w¢w¢w¢w¢w¢w¢w¢w¢w¢r¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢r¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢r¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢r¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢}
3530      */
3531     bar_control = aggBarControl->tid_info << 12 | aggBarControl->compressed_bitmap << 2
3532             | aggBarControl->multi_tid << 1 | aggBarControl->bar_ack_policy;
3533
3534     zmw_tx_buf_writeh(dev, buf, offset, bar_control);
3535     offset+=2;
3536     if (0 == aggBarControl->multi_tid) {
3537         /*
3538          * BA starting sequence number
3539          * ¢z¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢s¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢{
3540          * ¢x B0       B3 ¢x B4              B15 ¢x
3541          * ¢u¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢q¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢t
3542          * ¢x Frag num(0) ¢x BA starting seq num ¢x
3543          * ¢|¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢r¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢}
3544          */
3545         start_seq = (tid_tx->bar_ssn << 4) & 0xFFF0;
3546         zmw_tx_buf_writeh(dev, buf, offset, start_seq);
3547         offset+=2;
3548     }
3549     if (1 == aggBarControl->multi_tid && 1 == aggBarControl->compressed_bitmap) {
3550         /* multi-tid BlockAckReq variant, not implemented*/
3551     }
3552
3553     return offset;
3554 }
3555
3556 u16_t zfAggGenBarHeader(zdev_t* dev, u16_t* dst,
3557         u16_t* header, u16_t len, zbuf_t* buf, u16_t vap, u8_t encrypt)
3558 {
3559     u8_t  hlen = 16+8;        // MAC ctrl + PHY ctrl + 802.11 MM header
3560     //u8_t frameType = ZM_WLAN_FRAME_TYPE_ACTION;
3561
3562     zmw_get_wlan_dev(dev);
3563
3564     zmw_declare_for_critical_section();
3565
3566     /*
3567      * Generate control setting
3568      */
3569     //bodyLen = zfwBufGetSize(dev, buf);
3570     header[0] = 16+len+4;   //Length
3571     header[1] = 0x8;        //MAC control, backoff + (ack)
3572
3573 #if 1
3574     /* CCK 1M */
3575     header[2] = 0x0f00;          //PHY control L
3576     header[3] = 0x0000;          //PHY control H
3577 #else
3578     /* CCK 6M */
3579     header[2] = 0x0f01;          //PHY control L
3580     header[3] = 0x000B;          //PHY control H
3581
3582 #endif
3583     /*
3584      * Generate WLAN header
3585      * Frame control frame type and subtype
3586      */
3587     header[4+0] = ZM_WLAN_FRAME_TYPE_BAR;
3588     /*
3589      * Duration
3590      */
3591     header[4+1] = 0;
3592
3593     /* Address 1 = DA */
3594     header[4+2] = dst[0];
3595     header[4+3] = dst[1];
3596     header[4+4] = dst[2];
3597
3598     /* Address 2 = SA */
3599     header[4+5] = wd->macAddr[0];
3600     header[4+6] = wd->macAddr[1];
3601     if (wd->wlanMode == ZM_MODE_AP)
3602     {
3603 #ifdef ZM_VAPMODE_MULTILE_SSID
3604         header[4+7] = wd->macAddr[2]; //Multiple SSID
3605 #else
3606         header[4+7] = wd->macAddr[2] + (vap<<8); //VAP
3607 #endif
3608     }
3609     else
3610     {
3611         header[4+7] = wd->macAddr[2];
3612     }
3613
3614     /* Sequence Control */
3615     zmw_enter_critical_section(dev);
3616     header[4+11] = ((wd->mmseq++)<<4);
3617     zmw_leave_critical_section(dev);
3618
3619
3620     return hlen;
3621 }