• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /netgear-R7000-V1.0.7.12_1.2.5/components/opensource/linux/linux-2.6.36/drivers/staging/otus/80211core/
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
29extern u8_t zcUpToAc[8];
30const u8_t pri[] = {3,3,2,3,2,1,3,2,1,0};
31
32
33u16_t aggr_count;
34u32_t success_mpdu;
35u32_t total_mpdu;
36
37void 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
153u16_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/************************************************************************/
202TID_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/************************************************************************/
245TID_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/************************************************************************/
317u16_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
401u16_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
433void    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
471void    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
542void    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
564struct 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
586u16_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
642void    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
658TID_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
683u16_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
705void    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/************************************************************************/
878u16_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/************************************************************************/
1031u16_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/************************************************************************/
1074u16_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/************************************************************************/
1125u16_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/************************************************************************/
1285TID_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/************************************************************************/
1336zbuf_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/************************************************************************/
1391u16_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
1427void 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
1460void    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
1486TID_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
1523u16_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
1558struct 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
1580void    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
1591void    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
1609TID_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
1633u16_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/************************************************************************/
1672u16_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
1753u16_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
1799u16_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
1833struct 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
1914u16_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
2056struct 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
2092u16_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
2259u16_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/************************************************************************/
2330u16_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
2362        zmw_enter_critical_section(dev);
2363        tid_rx->seq_start = 0;
2364        tid_rx->baw_head = tid_rx->baw_tail = 0;
2365        tid_rx->aid = ZM_MAX_STA_SUPPORT;
2366        zmw_leave_critical_section(dev);
2367
2368        #ifdef ZM_ENABLE_AGGREGATION
2369        #ifndef ZM_ENABLE_FW_BA_RETRANSMISSION //disable BAW
2370        if (tid_baw->enabled) {
2371            zm_msg1_agg(ZM_LV_0, "Device down, clear BAW queue:", i);
2372            BAW->disable(dev, tid_baw);
2373        }
2374        #endif
2375        #endif
2376        if (1 == wd->aggQPool[i]->aggQEnabled) {
2377            tid_tx = wd->aggQPool[i];
2378            buf = zfAggTxGetVtxq(dev, tid_tx);
2379            while (buf) {
2380                zfwBufFree(dev, buf, 0);
2381                buf = zfAggTxGetVtxq(dev, tid_tx);
2382            }
2383        }
2384
2385        if(destroy) {
2386            zfwMemFree(dev, wd->aggQPool[i], sizeof(struct aggQueue));
2387            zfwMemFree(dev, wd->tid_rx[i], sizeof(struct agg_tid_rx));
2388        }
2389    }
2390    #ifdef ZM_ENABLE_AGGREGATION
2391    #ifndef ZM_ENABLE_FW_BA_RETRANSMISSION //disable BAW
2392    if(destroy) zfwMemFree(dev, BAW, sizeof(struct baw_enabler));
2393    #endif
2394    #endif
2395    return ZM_SUCCESS;
2396}
2397
2398
2399void zfAggRecvBAR(zdev_t* dev, zbuf_t *buf) {
2400    u16_t start_seq, len;
2401    u8_t i, bitmap[8];
2402    len = zfwBufGetSize(dev, buf);
2403    start_seq = zmw_rx_buf_readh(dev, buf, len-2);
2404    DbgPrint("Received a BAR Control frame, start_seq=%d", start_seq>>4);
2405    /* todo: set the bitmap by reordering buffer! */
2406    for (i=0; i<8; i++) bitmap[i]=0;
2407    zfSendBA(dev, start_seq, bitmap);
2408}
2409
2410#ifdef ZM_ENABLE_AGGREGATION
2411#ifndef ZM_ENABLE_FW_BA_RETRANSMISSION     //disable BAW
2412void zfAggTxRetransmit(zdev_t* dev, struct bufInfo *buf_info, struct aggControl *aggControl, TID_TX tid_tx) {
2413    u16_t removeLen;
2414    u16_t err;
2415
2416    zmw_get_wlan_dev(dev);
2417    if (aggControl && (ZM_AGG_FIRST_MPDU == aggControl->ampduIndication) ) {
2418        tid_tx->bar_ssn = buf_info->baw_header->header[15];
2419        aggControl->tid_baw->start_seq = tid_tx->bar_ssn >> 4;
2420        zm_msg1_agg(ZM_LV_0, "start seq=", tid_tx->bar_ssn >> 4);
2421    }
2422    buf_info->baw_header->header[4] |= (1 << 11);
2423    if (aggControl && aggControl->aggEnabled) {
2424        //if (wd->enableAggregation==0 && !(buf_info->baw_header->header[6]&0x1))
2425        //{
2426            //if (((buf_info->baw_header->header[2] & 0x3) == 2))
2427            //{
2428                /* Enable aggregation */
2429                buf_info->baw_header->header[1] |= 0x20;
2430                if (ZM_AGG_LAST_MPDU == aggControl->ampduIndication) {
2431                    buf_info->baw_header->header[1] |= 0x4000;
2432                }
2433                else {
2434                    buf_info->baw_header->header[1] &= ~0x4000;
2435                    //zm_debug_msg0("ZM_AGG_LAST_MPDU");
2436                }
2437            //}
2438            //else {
2439            //    zm_debug_msg1("no aggr, header[2]&0x3 = ",buf_info->baw_header->header[2] & 0x3)
2440            //    aggControl->aggEnabled = 0;
2441            //}
2442        //}
2443        //else {
2444        //    zm_debug_msg1("no aggr, wd->enableAggregation = ", wd->enableAggregation);
2445        //    zm_debug_msg1("no aggr, !header[6]&0x1 = ",!(buf_info->baw_header->header[6]&0x1));
2446        //    aggControl->aggEnabled = 0;
2447        //}
2448    }
2449
2450    /*if (aggControl->tid_baw) {
2451        struct baw_header_r header_r;
2452
2453        header_r.header      = buf_info->baw_header->header;
2454        header_r.mic         = buf_info->baw_header->mic;
2455        header_r.snap        = buf_info->baw_header->snap;
2456        header_r.headerLen   = buf_info->baw_header->headerLen;
2457        header_r.micLen      = buf_info->baw_header->micLen;
2458        header_r.snapLen     = buf_info->baw_header->snapLen;
2459        header_r.removeLen   = buf_info->baw_header->removeLen;
2460        header_r.keyIdx      = buf_info->baw_header->keyIdx;
2461
2462        BAW->insert(dev, buf_info->buf, tid_tx->bar_ssn >> 4, aggControl->tid_baw, buf_info->baw_retransmit, &header_r);
2463    }*/
2464
2465    err = zfHpSend(dev,
2466                    buf_info->baw_header->header,
2467                    buf_info->baw_header->headerLen,
2468                    buf_info->baw_header->snap,
2469                    buf_info->baw_header->snapLen,
2470                    buf_info->baw_header->mic,
2471                    buf_info->baw_header->micLen,
2472                    buf_info->buf,
2473                    buf_info->baw_header->removeLen,
2474                    ZM_EXTERNAL_ALLOC_BUF,
2475                    (u8_t)tid_tx->ac,
2476                    buf_info->baw_header->keyIdx);
2477    if (err != ZM_SUCCESS)
2478    {
2479        goto zlError;
2480    }
2481
2482    return;
2483
2484zlError:
2485    zfwBufFree(dev, buf_info->buf, 0);
2486    return;
2487
2488}
2489#endif //disable BAW
2490#endif
2491/************************************************************************/
2492/*                                                                      */
2493/*    FUNCTION DESCRIPTION                  zfAggTxSendEth              */
2494/*      Called to transmit Ethernet frame from upper elayer.            */
2495/*                                                                      */
2496/*    INPUTS                                                            */
2497/*      dev : device pointer                                            */
2498/*      buf : buffer pointer                                            */
2499/*      port : WLAN port, 0=>standard, 0x10-0x17=>VAP, 0x20-0x25=>WDS   */
2500/*                                                                      */
2501/*    OUTPUTS                                                           */
2502/*      error code                                                      */
2503/*                                                                      */
2504/*    AUTHOR                                                            */
2505/*      Stephen, Honda      Atheros Communications, Inc.    2006.12     */
2506/*                                                                      */
2507/************************************************************************/
2508u16_t zfAggTxSendEth(zdev_t* dev, zbuf_t* buf, u16_t port, u16_t bufType, u8_t flag, struct aggControl *aggControl, TID_TX tid_tx)
2509{
2510    u16_t err;
2511    //u16_t addrTblSize;
2512    //struct zsAddrTbl addrTbl;
2513    u16_t removeLen;
2514    u16_t header[(8+30+2+18)/2];    /* ctr+(4+a1+a2+a3+2+a4)+qos+iv */
2515    u16_t headerLen;
2516    u16_t mic[8/2];
2517    u16_t micLen;
2518    u16_t snap[8/2];
2519    u16_t snapLen;
2520    u16_t fragLen;
2521    u16_t frameLen;
2522    u16_t fragNum;
2523    struct zsFrag frag;
2524    u16_t i, id;
2525    u16_t da[3];
2526    u16_t sa[3];
2527    u8_t up;
2528    u8_t qosType, keyIdx = 0;
2529    u16_t fragOff;
2530
2531    zmw_get_wlan_dev(dev);
2532
2533    zmw_declare_for_critical_section();
2534
2535    zm_msg1_tx(ZM_LV_2, "zfTxSendEth(), port=", port);
2536
2537    /* Get IP TOS for QoS AC and IP frag offset */
2538    zfTxGetIpTosAndFrag(dev, buf, &up, &fragOff);
2539
2540#ifdef ZM_ENABLE_NATIVE_WIFI
2541    if ( wd->wlanMode == ZM_MODE_INFRASTRUCTURE )
2542    {
2543        /* DA */
2544        da[0] = zmw_tx_buf_readh(dev, buf, 16);
2545        da[1] = zmw_tx_buf_readh(dev, buf, 18);
2546        da[2] = zmw_tx_buf_readh(dev, buf, 20);
2547        /* SA */
2548        sa[0] = zmw_tx_buf_readh(dev, buf, 10);
2549        sa[1] = zmw_tx_buf_readh(dev, buf, 12);
2550        sa[2] = zmw_tx_buf_readh(dev, buf, 14);
2551    }
2552    else if ( wd->wlanMode == ZM_MODE_IBSS )
2553    {
2554        /* DA */
2555        da[0] = zmw_tx_buf_readh(dev, buf, 4);
2556        da[1] = zmw_tx_buf_readh(dev, buf, 6);
2557        da[2] = zmw_tx_buf_readh(dev, buf, 8);
2558        /* SA */
2559        sa[0] = zmw_tx_buf_readh(dev, buf, 10);
2560        sa[1] = zmw_tx_buf_readh(dev, buf, 12);
2561        sa[2] = zmw_tx_buf_readh(dev, buf, 14);
2562    }
2563    else if ( wd->wlanMode == ZM_MODE_AP )
2564    {
2565        /* DA */
2566        da[0] = zmw_tx_buf_readh(dev, buf, 4);
2567        da[1] = zmw_tx_buf_readh(dev, buf, 6);
2568        da[2] = zmw_tx_buf_readh(dev, buf, 8);
2569        /* SA */
2570        sa[0] = zmw_tx_buf_readh(dev, buf, 16);
2571        sa[1] = zmw_tx_buf_readh(dev, buf, 18);
2572        sa[2] = zmw_tx_buf_readh(dev, buf, 20);
2573    }
2574    else
2575    {
2576        //
2577    }
2578#else
2579    /* DA */
2580    da[0] = zmw_tx_buf_readh(dev, buf, 0);
2581    da[1] = zmw_tx_buf_readh(dev, buf, 2);
2582    da[2] = zmw_tx_buf_readh(dev, buf, 4);
2583    /* SA */
2584    sa[0] = zmw_tx_buf_readh(dev, buf, 6);
2585    sa[1] = zmw_tx_buf_readh(dev, buf, 8);
2586    sa[2] = zmw_tx_buf_readh(dev, buf, 10);
2587#endif
2588    //Decide Key Index in ATOM, No meaning in OTUS--CWYang(m)
2589    if (wd->wlanMode == ZM_MODE_AP)
2590    {
2591        keyIdx = wd->ap.bcHalKeyIdx[port];
2592        id = zfApFindSta(dev, da);
2593        if (id != 0xffff)
2594        {
2595            switch (wd->ap.staTable[id].encryMode)
2596            {
2597            case ZM_AES:
2598            case ZM_TKIP:
2599#ifdef ZM_ENABLE_CENC
2600            case ZM_CENC:
2601#endif //ZM_ENABLE_CENC
2602                keyIdx = wd->ap.staTable[id].keyIdx;
2603                break;
2604            }
2605        }
2606    }
2607    else
2608    {
2609        switch (wd->sta.encryMode)
2610        {
2611        case ZM_WEP64:
2612        case ZM_WEP128:
2613        case ZM_WEP256:
2614            keyIdx = wd->sta.keyId;
2615            break;
2616        case ZM_AES:
2617        case ZM_TKIP:
2618            if ((da[0]& 0x1))
2619                keyIdx = 5;
2620            else
2621                keyIdx = 4;
2622            break;
2623#ifdef ZM_ENABLE_CENC
2624        case ZM_CENC:
2625            keyIdx = wd->sta.cencKeyId;
2626            break;
2627#endif //ZM_ENABLE_CENC
2628        }
2629    }
2630
2631    /* Create SNAP */
2632    removeLen = zfTxGenWlanSnap(dev, buf, snap, &snapLen);
2633    //zm_msg1_tx(ZM_LV_0, "fragOff=", fragOff);
2634
2635    fragLen = wd->fragThreshold;
2636    frameLen = zfwBufGetSize(dev, buf);
2637    frameLen -= removeLen;
2638
2639    if ( frameLen > fragLen )
2640    {
2641        micLen = zfTxGenWlanTail(dev, buf, snap, snapLen, mic);
2642    }
2643    else
2644    {
2645        /* append MIC by HMAC */
2646        micLen = 0;
2647    }
2648
2649    /* Access Category */
2650    if (wd->wlanMode == ZM_MODE_AP)
2651    {
2652        zfApGetStaQosType(dev, da, &qosType);
2653        if (qosType == 0)
2654        {
2655            up = 0;
2656        }
2657    }
2658    else if (wd->wlanMode == ZM_MODE_INFRASTRUCTURE)
2659    {
2660        if (wd->sta.wmeConnected == 0)
2661        {
2662            up = 0;
2663        }
2664    }
2665    else
2666    {
2667        /* TODO : STA QoS control field */
2668        up = 0;
2669    }
2670
2671    /* Assign sequence number */
2672    zmw_enter_critical_section(dev);
2673    frag.seq[0] = ((wd->seq[zcUpToAc[up&0x7]]++) << 4);
2674    if (aggControl && (ZM_AGG_FIRST_MPDU == aggControl->ampduIndication) ) {
2675        tid_tx->bar_ssn = frag.seq[0];
2676
2677        zm_msg1_agg(ZM_LV_0, "start seq=", tid_tx->bar_ssn >> 4);
2678    }
2679    //tid_tx->baw_buf[tid_tx->baw_head-1].baw_seq=frag.seq[0];
2680    zmw_leave_critical_section(dev);
2681
2682
2683        frag.buf[0] = buf;
2684        frag.bufType[0] = bufType;
2685        frag.flag[0] = flag;
2686        fragNum = 1;
2687
2688    for (i=0; i<fragNum; i++)
2689    {
2690        /* Create WLAN header(Control Setting + 802.11 header + IV) */
2691        if (up !=0 ) zm_debug_msg1("up not 0, up=",up);
2692        headerLen = zfTxGenWlanHeader(dev, frag.buf[i], header, frag.seq[i],
2693                                      frag.flag[i], snapLen+micLen, removeLen,
2694                                      port, da, sa, up, &micLen, snap, snapLen,
2695                                      aggControl);
2696
2697        /* Get buffer DMA address */
2698        //if ((addrTblSize = zfwBufMapDma(dev, frag.buf[i], &addrTbl)) == 0)
2699        //if ((addrTblSize = zfwMapTxDma(dev, frag.buf[i], &addrTbl)) == 0)
2700        //{
2701        //    err = ZM_ERR_BUFFER_DMA_ADDR;
2702        //    goto zlError;
2703        //}
2704
2705        /* Flush buffer on cache */
2706        //zfwBufFlush(dev, frag.buf[i]);
2707
2708
2709        fragLen = zfwBufGetSize(dev, frag.buf[i]);
2710        if ((da[0]&0x1) == 0)
2711        {
2712            wd->commTally.txUnicastFrm++;
2713            wd->commTally.txUnicastOctets += (fragLen+snapLen);
2714        }
2715        else if ((da[0]& 0x1))
2716        {
2717            wd->commTally.txBroadcastFrm++;
2718            wd->commTally.txBroadcastOctets += (fragLen+snapLen);
2719        }
2720        else
2721        {
2722            wd->commTally.txMulticastFrm++;
2723            wd->commTally.txMulticastOctets += (fragLen+snapLen);
2724        }
2725        wd->ledStruct.txTraffic++;
2726
2727
2728        /*if (aggControl->tid_baw && aggControl->aggEnabled) {
2729            struct baw_header_r header_r;
2730
2731            header_r.header      = header;
2732            header_r.mic         = mic;
2733            header_r.snap        = snap;
2734            header_r.headerLen   = headerLen;
2735            header_r.micLen      = micLen;
2736            header_r.snapLen     = snapLen;
2737            header_r.removeLen   = removeLen;
2738            header_r.keyIdx      = keyIdx;
2739
2740            BAW->insert(dev, buf, tid_tx->bar_ssn >> 4, aggControl->tid_baw, 0, &header_r);
2741        }*/
2742
2743        err = zfHpSend(dev, header, headerLen, snap, snapLen,
2744                             mic, micLen, frag.buf[i], removeLen,
2745                             frag.bufType[i], zcUpToAc[up&0x7], keyIdx);
2746        if (err != ZM_SUCCESS)
2747        {
2748            goto zlError;
2749        }
2750
2751
2752        continue;
2753
2754zlError:
2755        if (frag.bufType[i] == ZM_EXTERNAL_ALLOC_BUF)
2756        {
2757            zfwBufFree(dev, frag.buf[i], err);
2758        }
2759        else if (frag.bufType[i] == ZM_INTERNAL_ALLOC_BUF)
2760        {
2761            zfwBufFree(dev, frag.buf[i], 0);
2762        }
2763        else
2764        {
2765            zm_assert(0);
2766        }
2767    } /* for (i=0; i<fragNum; i++) */
2768
2769    return ZM_SUCCESS;
2770}
2771
2772/*
2773 * zfAggSendADDBA() refers zfSendMmFrame() in cmm.c
2774 */
2775u16_t   zfAggSendAddbaRequest(zdev_t* dev, u16_t *dst, u16_t ac, u16_t up)
2776{
2777    zbuf_t* buf;
2778    //u16_t addrTblSize;
2779    //struct zsAddrTbl addrTbl;
2780    //u16_t err;
2781    u16_t offset = 0;
2782    u16_t hlen = 32;
2783    u16_t header[(24+25+1)/2];
2784    u16_t vap = 0;
2785    u16_t i;
2786    u8_t encrypt = 0;
2787
2788    //zmw_get_wlan_dev(dev);
2789
2790    //zmw_declare_for_critical_section();
2791
2792
2793    /*
2794     * TBD : Maximum size of management frame
2795     */
2796    buf = zfwBufAllocate(dev, 1024);
2797    if (buf == NULL)
2798    {
2799        zm_msg0_mm(ZM_LV_0, "Alloc mm buf Fail!");
2800        return ZM_SUCCESS;
2801    }
2802
2803    /*
2804     * Reserve room for wlan header
2805     */
2806    offset = hlen;
2807
2808    /*
2809     * add addba frame body
2810     */
2811    offset = zfAggSetAddbaFrameBody(dev, buf, offset, ac, up);
2812
2813
2814    zfwBufSetSize(dev, buf, offset);
2815
2816    /*
2817     * Copy wlan header
2818     */
2819    zfAggGenAddbaHeader(dev, dst, header, offset-hlen, buf, vap, encrypt);
2820    for (i=0; i<(hlen>>1); i++)
2821    {
2822        zmw_tx_buf_writeh(dev, buf, i*2, header[i]);
2823    }
2824
2825    /* Get buffer DMA address */
2826    //if ((addrTblSize = zfwBufMapDma(dev, buf, &addrTbl)) == 0)
2827    //if ((addrTblSize = zfwMapTxDma(dev, buf, &addrTbl)) == 0)
2828    //{
2829    //    goto zlError;
2830    //}
2831
2832    //zm_msg2_mm(ZM_LV_2, "offset=", offset);
2833    //zm_msg2_mm(ZM_LV_2, "hlen=", hlen);
2834    //zm_msg2_mm(ZM_LV_2, "addrTblSize=", addrTblSize);
2835    //zm_msg2_mm(ZM_LV_2, "addrTbl.len[0]=", addrTbl.len[0]);
2836    //zm_msg2_mm(ZM_LV_2, "addrTbl.physAddrl[0]=", addrTbl.physAddrl[0]);
2837    //zm_msg2_mm(ZM_LV_2, "buf->data=", buf->data);
2838
2839    zfPutVmmq(dev, buf);
2840    zfPushVtxq(dev);
2841
2842    return ZM_SUCCESS;
2843
2844}
2845
2846u16_t   zfAggSetAddbaFrameBody(zdev_t* dev, zbuf_t* buf, u16_t offset, u16_t ac, u16_t up)
2847{
2848    u16_t ba_parameter, start_seq;
2849
2850    zmw_get_wlan_dev(dev);
2851
2852    //zmw_declare_for_critical_section();
2853    /*
2854     * ADDBA Request frame body
2855     */
2856
2857    /*
2858     * Category
2859     */
2860    zmw_tx_buf_writeb(dev, buf, offset++, 3);
2861    /*
2862     * Action details = 0
2863     */
2864    zmw_tx_buf_writeb(dev, buf, offset++, ZM_WLAN_ADDBA_REQUEST_FRAME);
2865    /*
2866     * Dialog Token = nonzero
2867     * TBD: define how to get dialog token?
2868     */
2869    zmw_tx_buf_writeb(dev, buf, offset++, 2);
2870    /*
2871     * Block Ack parameter set
2872     * BA policy = 1 for immediate BA, 0 for delayed BA
2873     * TID(4bits) & buffer size(4bits) (TID=up & buffer size=0x80)
2874     * TBD: how to get buffer size?
2875     * �z�w�w�w�w�w�w�w�w�w�w�s�w�w�w�w�w�w�w�w�w�w�w�s�w�w�w�w�w�w�w�w�s�w�w�w�w�w�w�w�w�w�w�w�w�w�{
2876     * �x    B0    �x    B1     �x B2  B5 �x B6      B15 �x
2877     * �u�w�w�w�w�w�w�w�w�w�w�q�w�w�w�w�w�w�w�w�w�w�w�q�w�w�w�w�w�w�w�w�q�w�w�w�w�w�w�w�w�w�w�w�w�w�t
2878     * �x Reserved �x BA policy �x  TID   �x Buffer size �x
2879     * �|�w�w�w�w�w�w�w�w�w�w�r�w�w�w�w�w�w�w�w�w�w�w�r�w�w�w�w�w�w�w�w�r�w�w�w�w�w�w�w�w�w�w�w�w�w�}
2880     */
2881    ba_parameter = 1 << 12;     // buffer size = 0x40(64)
2882    ba_parameter |= up << 2;    // tid = up
2883    ba_parameter |= 2;          // ba policy = 1
2884    zmw_tx_buf_writeh(dev, buf, offset, ba_parameter);
2885    offset+=2;
2886    /*
2887     * BA timeout value
2888     */
2889    zmw_tx_buf_writeh(dev, buf, offset, 0);
2890    offset+=2;
2891    /*
2892     * BA starting sequence number
2893     * �z�w�w�w�w�w�w�w�w�w�w�w�w�w�s�w�w�w�w�w�w�w�w�w�w�w�w�w�w�w�w�w�w�w�w�w�{
2894     * �x B0       B3 �x B4              B15 �x
2895     * �u�w�w�w�w�w�w�w�w�w�w�w�w�w�q�w�w�w�w�w�w�w�w�w�w�w�w�w�w�w�w�w�w�w�w�w�t
2896     * �x Frag num(0) �x BA starting seq num �x
2897     * �|�w�w�w�w�w�w�w�w�w�w�w�w�w�r�w�w�w�w�w�w�w�w�w�w�w�w�w�w�w�w�w�w�w�w�w�}
2898     */
2899    start_seq = ((wd->seq[ac]) << 4) & 0xFFF0;
2900    zmw_tx_buf_writeh(dev, buf, offset, start_seq);
2901    offset+=2;
2902
2903    return offset;
2904}
2905
2906u16_t zfAggGenAddbaHeader(zdev_t* dev, u16_t* dst,
2907        u16_t* header, u16_t len, zbuf_t* buf, u16_t vap, u8_t encrypt)
2908{
2909    u8_t  hlen = 32;        // MAC ctrl + PHY ctrl + 802.11 MM header
2910    //u8_t frameType = ZM_WLAN_FRAME_TYPE_ACTION;
2911
2912    zmw_get_wlan_dev(dev);
2913
2914    zmw_declare_for_critical_section();
2915
2916    /*
2917     * Generate control setting
2918     */
2919    //bodyLen = zfwBufGetSize(dev, buf);
2920    header[0] = 24+len+4;   //Length
2921    header[1] = 0x8;        //MAC control, backoff + (ack)
2922
2923    /* OFDM 6M */
2924    header[2] = 0x0f01;          //PHY control L
2925    header[3] = 0x000B;          //PHY control H
2926
2927    /*
2928     * Generate WLAN header
2929     * Frame control frame type and subtype
2930     */
2931    header[4+0] = ZM_WLAN_FRAME_TYPE_ACTION;
2932    /*
2933     * Duration
2934     */
2935    header[4+1] = 0;
2936
2937    if (wd->wlanMode == ZM_MODE_INFRASTRUCTURE)
2938    {
2939        header[4+8] = wd->sta.bssid[0];
2940        header[4+9] = wd->sta.bssid[1];
2941        header[4+10] = wd->sta.bssid[2];
2942    }
2943    else if (wd->wlanMode == ZM_MODE_PSEUDO)
2944    {
2945        /* Address 3 = 00:00:00:00:00:00 */
2946        header[4+8] = 0;
2947        header[4+9] = 0;
2948        header[4+10] = 0;
2949    }
2950    else if (wd->wlanMode == ZM_MODE_IBSS)
2951    {
2952        header[4+8] = wd->sta.bssid[0];
2953        header[4+9] = wd->sta.bssid[1];
2954        header[4+10] = wd->sta.bssid[2];
2955    }
2956    else if (wd->wlanMode == ZM_MODE_AP)
2957    {
2958        /* Address 3 = BSSID */
2959        header[4+8] = wd->macAddr[0];
2960        header[4+9] = wd->macAddr[1];
2961        header[4+10] = wd->macAddr[2] + (vap<<8);
2962    }
2963
2964    /* Address 1 = DA */
2965    header[4+2] = dst[0];
2966    header[4+3] = dst[1];
2967    header[4+4] = dst[2];
2968
2969    /* Address 2 = SA */
2970    header[4+5] = wd->macAddr[0];
2971    header[4+6] = wd->macAddr[1];
2972    if (wd->wlanMode == ZM_MODE_AP)
2973    {
2974        header[4+7] = wd->macAddr[2] + (vap<<8);
2975    }
2976    else
2977    {
2978        header[4+7] = wd->macAddr[2];
2979    }
2980
2981    /* Sequence Control */
2982    zmw_enter_critical_section(dev);
2983    header[4+11] = ((wd->mmseq++)<<4);
2984    zmw_leave_critical_section(dev);
2985
2986
2987    return hlen;
2988}
2989
2990
2991u16_t   zfAggProcessAction(zdev_t* dev, zbuf_t* buf)
2992{
2993    u16_t category;
2994
2995    //zmw_get_wlan_dev(dev);
2996
2997    //zmw_declare_for_critical_section();
2998
2999    category = zmw_rx_buf_readb(dev, buf, 24);
3000
3001    switch (category)
3002    {
3003    case ZM_WLAN_BLOCK_ACK_ACTION_FRAME:
3004        zfAggBlockAckActionFrame(dev, buf);
3005        break;
3006
3007    }
3008
3009    return ZM_SUCCESS;
3010}
3011
3012
3013u16_t   zfAggBlockAckActionFrame(zdev_t* dev, zbuf_t* buf)
3014{
3015    u8_t action;
3016
3017    //zmw_get_wlan_dev(dev);
3018
3019    //zmw_declare_for_critical_section();
3020
3021    action = zmw_rx_buf_readb(dev, buf, 25);
3022#ifdef ZM_ENABLE_AGGREGATION
3023    switch (action)
3024    {
3025    case ZM_WLAN_ADDBA_REQUEST_FRAME:
3026        zm_msg0_agg(ZM_LV_0, "Received BA Action frame is ADDBA request");
3027        zfAggRecvAddbaRequest(dev, buf);
3028        break;
3029    case ZM_WLAN_ADDBA_RESPONSE_FRAME:
3030        zm_msg0_agg(ZM_LV_0, "Received BA Action frame is ADDBA response");
3031        zfAggRecvAddbaResponse(dev, buf);
3032        break;
3033    case ZM_WLAN_DELBA_FRAME:
3034        zfAggRecvDelba(dev, buf);
3035        break;
3036    }
3037#endif
3038    return ZM_SUCCESS;
3039}
3040
3041u16_t   zfAggRecvAddbaRequest(zdev_t* dev, zbuf_t* buf)
3042{
3043    //u16_t dialog;
3044    struct aggBaFrameParameter bf;
3045    u16_t i;
3046    //zmw_get_wlan_dev(dev);
3047
3048    //zmw_declare_for_critical_section();
3049
3050    bf.buf = buf;
3051    bf.dialog = zmw_rx_buf_readb(dev, buf, 26);
3052    /*
3053     * ba parameter set
3054     */
3055    bf.ba_parameter = zmw_rx_buf_readh(dev, buf, 27);
3056    bf.ba_policy   = (bf.ba_parameter >> 1) & 1;
3057    bf.tid         = (bf.ba_parameter >> 2) & 0xF;
3058    bf.buffer_size = (bf.ba_parameter >> 6);
3059    /*
3060     * BA timeout value
3061     */
3062    bf.ba_timeout = zmw_rx_buf_readh(dev, buf, 29);
3063    /*
3064     * BA starting sequence number
3065     */
3066    bf.ba_start_seq = zmw_rx_buf_readh(dev, buf, 31) >> 4;
3067
3068    i=26;
3069    while(i < 32) {
3070        zm_debug_msg2("Recv ADDBA Req:", zmw_rx_buf_readb(dev,buf,i));
3071        i++;
3072    }
3073
3074    zfAggSendAddbaResponse(dev, &bf);
3075
3076    zfAggAddbaSetTidRx(dev, buf, &bf);
3077
3078    return ZM_SUCCESS;
3079}
3080
3081u16_t   zfAggAddbaSetTidRx(zdev_t* dev, zbuf_t* buf, struct aggBaFrameParameter *bf)
3082{
3083    u16_t i, ac, aid, fragOff;
3084    u16_t src[3];
3085    u16_t offset = 0;
3086    u8_t  up;
3087    struct agg_tid_rx *tid_rx = NULL;
3088
3089    zmw_get_wlan_dev(dev);
3090
3091    zmw_declare_for_critical_section();
3092
3093    src[0] = zmw_rx_buf_readh(dev, buf, offset+10);
3094    src[1] = zmw_rx_buf_readh(dev, buf, offset+12);
3095    src[2] = zmw_rx_buf_readh(dev, buf, offset+14);
3096    aid = zfApFindSta(dev, src);
3097
3098    zfTxGetIpTosAndFrag(dev, buf, &up, &fragOff);
3099    ac = zcUpToAc[up&0x7] & 0x3;
3100
3101    ac = bf->tid;
3102
3103    for (i=0; i<ZM_AGG_POOL_SIZE ; i++)
3104    {
3105        if((wd->tid_rx[i]->aid == aid) && (wd->tid_rx[i]->ac == ac))
3106        {
3107            tid_rx = wd->tid_rx[i];
3108            break;
3109        }
3110    }
3111
3112    if (!tid_rx)
3113    {
3114        for (i=0; i<ZM_AGG_POOL_SIZE; i++)
3115        {
3116            if (wd->tid_rx[i]->aid == ZM_MAX_STA_SUPPORT)
3117            {
3118                tid_rx = wd->tid_rx[i];
3119                break;
3120            }
3121        }
3122        if (!tid_rx)
3123            return 0;
3124    }
3125
3126    zmw_enter_critical_section(dev);
3127
3128    tid_rx->aid = aid;
3129    tid_rx->ac = ac;
3130    tid_rx->addBaExchangeStatusCode = ZM_AGG_ADDBA_RESPONSE;
3131    tid_rx->seq_start = bf->ba_start_seq;
3132    tid_rx->baw_head = tid_rx->baw_tail = 0;
3133    tid_rx->sq_exceed_count = tid_rx->sq_behind_count = 0;
3134    zmw_leave_critical_section(dev);
3135
3136    return 0;
3137}
3138
3139u16_t   zfAggRecvAddbaResponse(zdev_t* dev, zbuf_t* buf)
3140{
3141    u16_t i,ac, aid=0;
3142    u16_t src[3];
3143    struct aggBaFrameParameter bf;
3144
3145    zmw_get_wlan_dev(dev);
3146
3147    //zmw_declare_for_critical_section();
3148
3149    src[0] = zmw_rx_buf_readh(dev, buf, 10);
3150    src[1] = zmw_rx_buf_readh(dev, buf, 12);
3151    src[2] = zmw_rx_buf_readh(dev, buf, 14);
3152
3153    if (wd->wlanMode == ZM_MODE_AP)
3154        aid = zfApFindSta(dev, src);
3155
3156
3157    bf.buf = buf;
3158    bf.dialog = zmw_rx_buf_readb(dev, buf, 26);
3159    bf.status_code = zmw_rx_buf_readh(dev, buf, 27);
3160    if (!bf.status_code)
3161    {
3162        wd->addbaComplete=1;
3163    }
3164
3165    /*
3166     * ba parameter set
3167     */
3168    bf.ba_parameter = zmw_rx_buf_readh(dev, buf, 29);
3169    bf.ba_policy   = (bf.ba_parameter >> 1) & 1;
3170    bf.tid         = (bf.ba_parameter >> 2) & 0xF;
3171    bf.buffer_size = (bf.ba_parameter >> 6);
3172    /*
3173     * BA timeout value
3174     */
3175    bf.ba_timeout = zmw_rx_buf_readh(dev, buf, 31);
3176
3177    i=26;
3178    while(i < 32) {
3179        zm_debug_msg2("Recv ADDBA Rsp:", zmw_rx_buf_readb(dev,buf,i));
3180        i++;
3181    }
3182
3183    ac = zcUpToAc[bf.tid&0x7] & 0x3;
3184
3185    //zmw_enter_critical_section(dev);
3186
3187    //wd->aggSta[aid].aggFlag[ac] = 0;
3188
3189    //zmw_leave_critical_section(dev);
3190
3191    return ZM_SUCCESS;
3192}
3193
3194u16_t   zfAggRecvDelba(zdev_t* dev, zbuf_t* buf)
3195{
3196    //zmw_get_wlan_dev(dev);
3197
3198    //zmw_declare_for_critical_section();
3199    return ZM_SUCCESS;
3200}
3201
3202u16_t   zfAggSendAddbaResponse(zdev_t* dev, struct aggBaFrameParameter *bf)
3203{
3204    zbuf_t* buf;
3205    //u16_t addrTblSize;
3206    //struct zsAddrTbl addrTbl;
3207    //u16_t err;
3208    u16_t offset = 0;
3209    u16_t hlen = 32;
3210    u16_t header[(24+25+1)/2];
3211    u16_t vap = 0;
3212    u16_t i;
3213    u8_t encrypt = 0;
3214    u16_t dst[3];
3215
3216    //zmw_get_wlan_dev(dev);
3217
3218    //zmw_declare_for_critical_section();
3219
3220
3221    /*
3222     * TBD : Maximum size of management frame
3223     */
3224    buf = zfwBufAllocate(dev, 1024);
3225    if (buf == NULL)
3226    {
3227        zm_msg0_mm(ZM_LV_0, "Alloc mm buf Fail!");
3228        return ZM_SUCCESS;
3229    }
3230
3231    /*
3232     * Reserve room for wlan header
3233     */
3234    offset = hlen;
3235
3236    /*
3237     * add addba frame body
3238     */
3239    offset = zfAggSetAddbaResponseFrameBody(dev, buf, bf, offset);
3240
3241
3242    zfwBufSetSize(dev, buf, offset);
3243
3244    /*
3245     * Copy wlan header
3246     */
3247
3248    dst[0] = zmw_rx_buf_readh(dev, bf->buf, 10);
3249    dst[1] = zmw_rx_buf_readh(dev, bf->buf, 12);
3250    dst[2] = zmw_rx_buf_readh(dev, bf->buf, 14);
3251    zfAggGenAddbaHeader(dev, dst, header, offset-hlen, buf, vap, encrypt);
3252    for (i=0; i<(hlen>>1); i++)
3253    {
3254        zmw_tx_buf_writeh(dev, buf, i*2, header[i]);
3255    }
3256
3257    /* Get buffer DMA address */
3258    //if ((addrTblSize = zfwBufMapDma(dev, buf, &addrTbl)) == 0)
3259    //if ((addrTblSize = zfwMapTxDma(dev, buf, &addrTbl)) == 0)
3260    //{
3261    //    goto zlError;
3262    //}
3263
3264    //zm_msg2_mm(ZM_LV_2, "offset=", offset);
3265    //zm_msg2_mm(ZM_LV_2, "hlen=", hlen);
3266    //zm_msg2_mm(ZM_LV_2, "addrTblSize=", addrTblSize);
3267    //zm_msg2_mm(ZM_LV_2, "addrTbl.len[0]=", addrTbl.len[0]);
3268    //zm_msg2_mm(ZM_LV_2, "addrTbl.physAddrl[0]=", addrTbl.physAddrl[0]);
3269    //zm_msg2_mm(ZM_LV_2, "buf->data=", buf->data);
3270
3271    zfPutVmmq(dev, buf);
3272    zfPushVtxq(dev);
3273
3274    //zfAggSendAddbaRequest(dev, dst, zcUpToAc[bf->tid&0x7] & 0x3, bf->tid);
3275    return ZM_SUCCESS;
3276
3277}
3278
3279u16_t   zfAggSetAddbaResponseFrameBody(zdev_t* dev, zbuf_t* buf,
3280                struct aggBaFrameParameter *bf, u16_t offset)
3281{
3282
3283    //zmw_get_wlan_dev(dev);
3284
3285    //zmw_declare_for_critical_section();
3286    /*
3287     * ADDBA Request frame body
3288     */
3289
3290    /*
3291     * Category
3292     */
3293    zmw_tx_buf_writeb(dev, buf, offset++, 3);
3294    /*
3295     * Action details = 0
3296     */
3297    zmw_tx_buf_writeb(dev, buf, offset++, ZM_WLAN_ADDBA_RESPONSE_FRAME);
3298    /*
3299     * Dialog Token = nonzero
3300     */
3301    zmw_tx_buf_writeb(dev, buf, offset++, bf->dialog);
3302    /*
3303     * Status code
3304     */
3305    zmw_tx_buf_writeh(dev, buf, offset, 0);
3306    offset+=2;
3307    /*
3308     * Block Ack parameter set
3309     * BA policy = 1 for immediate BA, 0 for delayed BA
3310     * TID(4bits) & buffer size(4bits) (TID=0x1 & buffer size=0x80)
3311     * TBD: how to get TID number and buffer size?
3312     * �z�w�w�w�w�w�w�w�w�w�w�s�w�w�w�w�w�w�w�w�w�w�w�s�w�w�w�w�w�w�w�w�s�w�w�w�w�w�w�w�w�w�w�w�w�w�{
3313     * �x    B0    �x    B1     �x B2  B5 �x B6      B15 �x
3314     * �u�w�w�w�w�w�w�w�w�w�w�q�w�w�w�w�w�w�w�w�w�w�w�q�w�w�w�w�w�w�w�w�q�w�w�w�w�w�w�w�w�w�w�w�w�w�t
3315     * �x Reserved �x BA policy �x  TID   �x Buffer size �x
3316     * �|�w�w�w�w�w�w�w�w�w�w�r�w�w�w�w�w�w�w�w�w�w�w�r�w�w�w�w�w�w�w�w�r�w�w�w�w�w�w�w�w�w�w�w�w�w�}
3317     */
3318    zmw_tx_buf_writeh(dev, buf, offset, bf->ba_parameter);
3319    offset+=2;
3320    /*
3321     * BA timeout value
3322     */
3323    zmw_tx_buf_writeh(dev, buf, offset, bf->ba_timeout);
3324    offset+=2;
3325
3326    return offset;
3327}
3328
3329void   zfAggInvokeBar(zdev_t* dev, TID_TX tid_tx)
3330{
3331    struct aggBarControl aggBarControl;
3332    //zmw_get_wlan_dev(dev);
3333
3334    //zmw_declare_for_critical_section();
3335    //bar_control = aggBarControl->tid_info << 12 | aggBarControl->compressed_bitmap << 2
3336    //        | aggBarControl->multi_tid << 1 | aggBarControl->bar_ack_policy;
3337    aggBarControl.bar_ack_policy = 0;
3338    aggBarControl.multi_tid = 0;
3339    aggBarControl.compressed_bitmap = 0;
3340    aggBarControl.tid_info = tid_tx->tid;
3341    zfAggSendBar(dev, tid_tx, &aggBarControl);
3342
3343    return;
3344
3345}
3346/*
3347 * zfAggSendBar() refers zfAggSendAddbaRequest()
3348 */
3349u16_t   zfAggSendBar(zdev_t* dev, TID_TX tid_tx, struct aggBarControl *aggBarControl)
3350{
3351    zbuf_t* buf;
3352    //u16_t addrTblSize;
3353    //struct zsAddrTbl addrTbl;
3354    //u16_t err;
3355    u16_t offset = 0;
3356    u16_t hlen = 16+8;  /* mac header + control headers*/
3357    u16_t header[(8+24+1)/2];
3358    u16_t vap = 0;
3359    u16_t i;
3360    u8_t encrypt = 0;
3361
3362    //zmw_get_wlan_dev(dev);
3363
3364    //zmw_declare_for_critical_section();
3365
3366
3367    /*
3368     * TBD : Maximum size of management frame
3369     */
3370    buf = zfwBufAllocate(dev, 1024);
3371    if (buf == NULL)
3372    {
3373        zm_msg0_mm(ZM_LV_0, "Alloc mm buf Fail!");
3374        return ZM_SUCCESS;
3375    }
3376
3377    /*
3378     * Reserve room for wlan header
3379     */
3380    offset = hlen;
3381
3382    /*
3383     * add addba frame body
3384     */
3385    offset = zfAggSetBarBody(dev, buf, offset, tid_tx, aggBarControl);
3386
3387
3388    zfwBufSetSize(dev, buf, offset);
3389
3390    /*
3391     * Copy wlan header
3392     */
3393    zfAggGenBarHeader(dev, tid_tx->dst, header, offset-hlen, buf, vap, encrypt);
3394    for (i=0; i<(hlen>>1); i++)
3395    {
3396        zmw_tx_buf_writeh(dev, buf, i*2, header[i]);
3397    }
3398
3399    /* Get buffer DMA address */
3400    //if ((addrTblSize = zfwBufMapDma(dev, buf, &addrTbl)) == 0)
3401    //if ((addrTblSize = zfwMapTxDma(dev, buf, &addrTbl)) == 0)
3402    //{
3403    //    goto zlError;
3404    //}
3405
3406    //zm_msg2_mm(ZM_LV_2, "offset=", offset);
3407    //zm_msg2_mm(ZM_LV_2, "hlen=", hlen);
3408    //zm_msg2_mm(ZM_LV_2, "addrTblSize=", addrTblSize);
3409    //zm_msg2_mm(ZM_LV_2, "addrTbl.len[0]=", addrTbl.len[0]);
3410    //zm_msg2_mm(ZM_LV_2, "addrTbl.physAddrl[0]=", addrTbl.physAddrl[0]);
3411    //zm_msg2_mm(ZM_LV_2, "buf->data=", buf->data);
3412
3413    zfPutVmmq(dev, buf);
3414    zfPushVtxq(dev);
3415
3416    return ZM_SUCCESS;
3417
3418}
3419
3420u16_t   zfAggSetBarBody(zdev_t* dev, zbuf_t* buf, u16_t offset, TID_TX tid_tx, struct aggBarControl *aggBarControl)
3421{
3422    u16_t bar_control, start_seq;
3423
3424    //zmw_get_wlan_dev(dev);
3425
3426    //zmw_declare_for_critical_section();
3427    /*
3428     * BAR Control frame body
3429     */
3430
3431    /*
3432     * BAR Control Field
3433     * �z�w�w�w�w�w�w�w�w�w�s�w�w�w�w�w�w�w�w�w�w�w�s�w�w�w�w�w�w�w�w�w�w�w�w�s�w�w�w�w�w�w�w�w�w�w�s�w�w�w�w�w�w�w�w�w�w�{
3434     * �x    B0   �x    B1     �x     B2     �x B3   B11 �x B12  B15 �x
3435     * �u�w�w�w�w�w�w�w�w�w�q�w�w�w�w�w�w�w�w�w�w�w�q�w�w�w�w�w�w�w�w�w�w�w�w�q�w�w�w�w�w�w�w�w�w�w�q�w�w�w�w�w�w�w�w�w�w�t
3436     * �x BAR Ack �x Multi-TID �x Compressed �x Reserved �x TID_INFO �x
3437     * �x  Policy �x           �x   Bitmap   �x          �x          �x
3438     * �|�w�w�w�w�w�w�w�w�w�r�w�w�w�w�w�w�w�w�w�w�w�r�w�w�w�w�w�w�w�w�w�w�w�w�r�w�w�w�w�w�w�w�w�w�w�r�w�w�w�w�w�w�w�w�w�w�}
3439     */
3440    bar_control = aggBarControl->tid_info << 12 | aggBarControl->compressed_bitmap << 2
3441            | aggBarControl->multi_tid << 1 | aggBarControl->bar_ack_policy;
3442
3443    zmw_tx_buf_writeh(dev, buf, offset, bar_control);
3444    offset+=2;
3445    if (0 == aggBarControl->multi_tid) {
3446        /*
3447         * BA starting sequence number
3448         * �z�w�w�w�w�w�w�w�w�w�w�w�w�w�s�w�w�w�w�w�w�w�w�w�w�w�w�w�w�w�w�w�w�w�w�w�{
3449         * �x B0       B3 �x B4              B15 �x
3450         * �u�w�w�w�w�w�w�w�w�w�w�w�w�w�q�w�w�w�w�w�w�w�w�w�w�w�w�w�w�w�w�w�w�w�w�w�t
3451         * �x Frag num(0) �x BA starting seq num �x
3452         * �|�w�w�w�w�w�w�w�w�w�w�w�w�w�r�w�w�w�w�w�w�w�w�w�w�w�w�w�w�w�w�w�w�w�w�w�}
3453         */
3454        start_seq = (tid_tx->bar_ssn << 4) & 0xFFF0;
3455        zmw_tx_buf_writeh(dev, buf, offset, start_seq);
3456        offset+=2;
3457    }
3458    if (1 == aggBarControl->multi_tid && 1 == aggBarControl->compressed_bitmap) {
3459        /* multi-tid BlockAckReq variant, not implemented*/
3460    }
3461
3462    return offset;
3463}
3464
3465u16_t zfAggGenBarHeader(zdev_t* dev, u16_t* dst,
3466        u16_t* header, u16_t len, zbuf_t* buf, u16_t vap, u8_t encrypt)
3467{
3468    u8_t  hlen = 16+8;        // MAC ctrl + PHY ctrl + 802.11 MM header
3469    //u8_t frameType = ZM_WLAN_FRAME_TYPE_ACTION;
3470
3471    zmw_get_wlan_dev(dev);
3472
3473    zmw_declare_for_critical_section();
3474
3475    /*
3476     * Generate control setting
3477     */
3478    //bodyLen = zfwBufGetSize(dev, buf);
3479    header[0] = 16+len+4;   //Length
3480    header[1] = 0x8;        //MAC control, backoff + (ack)
3481
3482    /* CCK 1M */
3483    header[2] = 0x0f00;          //PHY control L
3484    header[3] = 0x0000;          //PHY control H
3485    /*
3486     * Generate WLAN header
3487     * Frame control frame type and subtype
3488     */
3489    header[4+0] = ZM_WLAN_FRAME_TYPE_BAR;
3490    /*
3491     * Duration
3492     */
3493    header[4+1] = 0;
3494
3495    /* Address 1 = DA */
3496    header[4+2] = dst[0];
3497    header[4+3] = dst[1];
3498    header[4+4] = dst[2];
3499
3500    /* Address 2 = SA */
3501    header[4+5] = wd->macAddr[0];
3502    header[4+6] = wd->macAddr[1];
3503    if (wd->wlanMode == ZM_MODE_AP)
3504    {
3505#ifdef ZM_VAPMODE_MULTILE_SSID
3506        header[4+7] = wd->macAddr[2]; //Multiple SSID
3507#else
3508        header[4+7] = wd->macAddr[2] + (vap<<8); //VAP
3509#endif
3510    }
3511    else
3512    {
3513        header[4+7] = wd->macAddr[2];
3514    }
3515
3516    /* Sequence Control */
3517    zmw_enter_critical_section(dev);
3518    header[4+11] = ((wd->mmseq++)<<4);
3519    zmw_leave_critical_section(dev);
3520
3521
3522    return hlen;
3523}
3524