]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blame - src/patches/suse-2.6.27.25/patches.drivers/staging-add-otus-atheros-wireless-network-driver.patch
Reenabled linux-xen and xen-image build
[people/pmueller/ipfire-2.x.git] / src / patches / suse-2.6.27.25 / patches.drivers / staging-add-otus-atheros-wireless-network-driver.patch
CommitLineData
00e5a55c
BS
1From 6dbf61162153a00ad21537c4153009d8a26df723 Mon Sep 17 00:00:00 2001
2From: Luis R. Rodriguez <lrodriguez@atheros.com>
3Date: Mon, 27 Oct 2008 22:44:22 -0700
4Subject: Staging: add otus Atheros wireless network driver
5Patch-mainline: 2.6.28
6
7From: Luis R. Rodriguez <lrodriguez@atheros.com>
8
9Initial dump of the otus USB wireless network driver.
10It builds properly, but a lot of work needs to be done cleaning
11it up before it can be merged into the wireless driver tree.
12
13Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
14Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
15---
16 drivers/staging/Kconfig | 2
17 drivers/staging/Makefile | 1
18 drivers/staging/otus/80211core/amsdu.c | 134
19 drivers/staging/otus/80211core/cagg.c | 3611 +++++++++++++++
20 drivers/staging/otus/80211core/cagg.h | 435 +
21 drivers/staging/otus/80211core/ccmd.c | 1861 ++++++++
22 drivers/staging/otus/80211core/cfunc.c | 1227 +++++
23 drivers/staging/otus/80211core/cfunc.h | 449 +
24 drivers/staging/otus/80211core/chb.c | 200
25 drivers/staging/otus/80211core/cic.c | 496 ++
26 drivers/staging/otus/80211core/cinit.c | 1911 ++++++++
27 drivers/staging/otus/80211core/cmm.c | 2141 +++++++++
28 drivers/staging/otus/80211core/cmmap.c | 2402 ++++++++++
29 drivers/staging/otus/80211core/cmmsta.c | 5782 +++++++++++++++++++++++++
30 drivers/staging/otus/80211core/coid.c | 2695 +++++++++++
31 drivers/staging/otus/80211core/cprecomp.h | 32
32 drivers/staging/otus/80211core/cpsmgr.c | 731 +++
33 drivers/staging/otus/80211core/cscanmgr.c | 535 ++
34 drivers/staging/otus/80211core/ctkip.c | 598 ++
35 drivers/staging/otus/80211core/ctxrx.c | 4096 +++++++++++++++++
36 drivers/staging/otus/80211core/cwep.c | 299 +
37 drivers/staging/otus/80211core/cwm.c | 131
38 drivers/staging/otus/80211core/cwm.h | 45
39 drivers/staging/otus/80211core/freqctrl.c | 259 +
40 drivers/staging/otus/80211core/ledmgr.c | 557 ++
41 drivers/staging/otus/80211core/performance.c | 431 +
42 drivers/staging/otus/80211core/performance.h | 97
43 drivers/staging/otus/80211core/pub_usb.h | 102
44 drivers/staging/otus/80211core/pub_zfi.h | 821 +++
45 drivers/staging/otus/80211core/pub_zfw.h | 93
46 drivers/staging/otus/80211core/queue.c | 303 +
47 drivers/staging/otus/80211core/queue.h | 37
48 drivers/staging/otus/80211core/ratectrl.c | 874 +++
49 drivers/staging/otus/80211core/ratectrl.h | 37
50 drivers/staging/otus/80211core/struct.h | 1315 +++++
51 drivers/staging/otus/80211core/wlan.h | 595 ++
52 drivers/staging/otus/Kconfig | 32
53 drivers/staging/otus/Makefile | 67
54 drivers/staging/otus/TODO | 9
55 drivers/staging/otus/apdbg.c | 457 +
56 drivers/staging/otus/athr_common.h | 141
57 drivers/staging/otus/hal/hpDKfwu.c | 832 +++
58 drivers/staging/otus/hal/hpani.c | 732 +++
59 drivers/staging/otus/hal/hpani.h | 420 +
60 drivers/staging/otus/hal/hpfw2.c | 1018 ++++
61 drivers/staging/otus/hal/hpfwbu.c | 5269 ++++++++++++++++++++++
62 drivers/staging/otus/hal/hpfwspiu.c | 655 ++
63 drivers/staging/otus/hal/hpfwu.c | 1017 ++++
64 drivers/staging/otus/hal/hpfwu.c.drv_ba_resend | 742 +++
65 drivers/staging/otus/hal/hpfwu_2k.c | 1016 ++++
66 drivers/staging/otus/hal/hpfwu_BA.c | 874 +++
67 drivers/staging/otus/hal/hpfwu_FB50_mdk.c | 721 +++
68 drivers/staging/otus/hal/hpfwu_OTUS_RC.c | 715 +++
69 drivers/staging/otus/hal/hpfwu_txstream.c | 1017 ++++
70 drivers/staging/otus/hal/hpfwuinit.c | 240 +
71 drivers/staging/otus/hal/hpmain.c | 4643 ++++++++++++++++++++
72 drivers/staging/otus/hal/hpreg.c | 2481 ++++++++++
73 drivers/staging/otus/hal/hpreg.h | 524 ++
74 drivers/staging/otus/hal/hprw.c | 1557 ++++++
75 drivers/staging/otus/hal/hpusb.c | 1584 ++++++
76 drivers/staging/otus/hal/hpusb.h | 437 +
77 drivers/staging/otus/hal/otus.ini | 414 +
78 drivers/staging/otus/ioctl.c | 2936 ++++++++++++
79 drivers/staging/otus/oal_dt.h | 60
80 drivers/staging/otus/oal_marc.h | 135
81 drivers/staging/otus/usbdrv.c | 1210 +++++
82 drivers/staging/otus/usbdrv.h | 257 +
83 drivers/staging/otus/wrap_buf.c | 114
84 drivers/staging/otus/wrap_dbg.c | 101
85 drivers/staging/otus/wrap_ev.c | 283 +
86 drivers/staging/otus/wrap_mem.c | 101
87 drivers/staging/otus/wrap_mis.c | 108
88 drivers/staging/otus/wrap_pkt.c | 178
89 drivers/staging/otus/wrap_sec.c | 127
90 drivers/staging/otus/wrap_usb.c | 195
91 drivers/staging/otus/wwrap.c | 1207 +++++
92 drivers/staging/otus/zdcompat.h | 116
93 drivers/staging/otus/zdusb.c | 295 +
94 drivers/staging/otus/zdusb.h | 43
95 79 files changed, 70415 insertions(+)
96
97--- a/drivers/staging/Kconfig
98+++ b/drivers/staging/Kconfig
99@@ -45,4 +45,6 @@ source "drivers/staging/at76_usb/Kconfig
100
101 source "drivers/staging/agnx/Kconfig"
102
103+source "drivers/staging/otus/Kconfig"
104+
105 endif # STAGING
106--- a/drivers/staging/Makefile
107+++ b/drivers/staging/Makefile
108@@ -14,3 +14,4 @@ obj-$(CONFIG_PRISM2_USB) += wlan-ng/
109 obj-$(CONFIG_ECHO) += echo/
110 obj-$(CONFIG_USB_ATMEL) += at76_usb/
111 obj-$(CONFIG_AGNX) += agnx/
112+obj-$(CONFIG_OTUS) += otus/
113--- /dev/null
114+++ b/drivers/staging/otus/80211core/amsdu.c
115@@ -0,0 +1,134 @@
116+/*
117+ * Copyright (c) 2007-2008 Atheros Communications Inc.
118+ *
119+ * Permission to use, copy, modify, and/or distribute this software for any
120+ * purpose with or without fee is hereby granted, provided that the above
121+ * copyright notice and this permission notice appear in all copies.
122+ *
123+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
124+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
125+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
126+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
127+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
128+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
129+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
130+ */
131+
132+#include "cprecomp.h"
133+
134+
135+/************************************************************************/
136+/* */
137+/* FUNCTION DESCRIPTION zfGetAmsduSubFrame */
138+/* Get a subframe from a-MSDU. */
139+/* */
140+/* INPUTS */
141+/* dev : device pointer */
142+/* buf : A-MSDU frame buffer */
143+/* offset : offset of subframe in the A-MSDU */
144+/* */
145+/* OUTPUTS */
146+/* NULL or subframe */
147+/* */
148+/* AUTHOR */
149+/* Stephen Chen Atheros Communications, INC. 2007.2 */
150+/* */
151+/************************************************************************/
152+zbuf_t* zfGetAmsduSubFrame(zdev_t* dev, zbuf_t* buf, u16_t* offset)
153+{
154+ u16_t subframeLen;
155+ u16_t amsduLen = zfwBufGetSize(dev, buf);
156+ zbuf_t* newBuf;
157+
158+ ZM_PERFORMANCE_RX_AMSDU(dev, buf, amsduLen);
159+
160+ /* Verify A-MSDU length */
161+ if (amsduLen < (*offset + 14))
162+ {
163+ return NULL;
164+ }
165+
166+ /* Locate A-MSDU subframe by offset and verify subframe length */
167+ subframeLen = (zmw_buf_readb(dev, buf, *offset + 12) << 8) +
168+ zmw_buf_readb(dev, buf, *offset + 13);
169+ if (subframeLen == 0)
170+ {
171+ return NULL;
172+ }
173+
174+ /* Verify A-MSDU subframe length */
175+ if ((*offset+14+subframeLen) <= amsduLen)
176+ {
177+ /* Allocate a new buffer */
178+ if ((newBuf = zfwBufAllocate(dev, 24+2+subframeLen)) != NULL)
179+ {
180+#ifdef ZM_ENABLE_NATIVE_WIFI
181+ /* Copy and convert subframe to wlan frame format */
182+ /* SHALL NOT INCLUDE QOS and AMSDU header. Ray 20070807 For Vista */
183+ zfRxBufferCopy(dev, newBuf, buf, 0, 0, 24);
184+ zfRxBufferCopy(dev, newBuf, buf, 24, *offset+14, subframeLen);
185+ zfwBufSetSize(dev, newBuf, 24+subframeLen);
186+#else
187+ /* Copy subframe to new buffer */
188+ zfRxBufferCopy(dev, newBuf, buf, 0, *offset, 14+subframeLen);
189+ zfwBufSetSize(dev, newBuf, 14+subframeLen);
190+#endif
191+ /* Update offset */
192+ *offset += (((14+subframeLen)+3) & 0xfffc);
193+
194+ /* Return buffer pointer */
195+ return newBuf;
196+ }
197+ }
198+ return NULL;
199+}
200+
201+
202+/************************************************************************/
203+/* */
204+/* FUNCTION DESCRIPTION zfDeAmsdu */
205+/* De-AMSDU. */
206+/* */
207+/* INPUTS */
208+/* dev : device pointer */
209+/* buf : A-MSDU frame buffer */
210+/* vap : VAP port */
211+/* */
212+/* OUTPUTS */
213+/* None */
214+/* */
215+/* AUTHOR */
216+/* Stephen Chen Atheros Communications, INC. 2007.2 */
217+/* */
218+/************************************************************************/
219+void zfDeAmsdu(zdev_t* dev, zbuf_t* buf, u16_t vap, u8_t encryMode)
220+{
221+ u16_t offset = ZM_SIZE_OF_WLAN_DATA_HEADER+ZM_SIZE_OF_QOS_CTRL;
222+ zbuf_t* subframeBuf;
223+ zmw_get_wlan_dev(dev);
224+
225+ ZM_BUFFER_TRACE(dev, buf)
226+
227+ if (encryMode == ZM_AES || encryMode == ZM_TKIP)
228+ {
229+ offset += (ZM_SIZE_OF_IV + ZM_SIZE_OF_EXT_IV);
230+ }
231+ else if (encryMode == ZM_WEP64 || encryMode == ZM_WEP128)
232+ {
233+ offset += ZM_SIZE_OF_IV;
234+ }
235+
236+ /* Repeatly calling zfGetAmsduSubFrame() until NULL returned */
237+ while ((subframeBuf = zfGetAmsduSubFrame(dev, buf, &offset)) != NULL)
238+ {
239+ wd->commTally.NotifyNDISRxFrmCnt++;
240+ if (wd->zfcbRecvEth != NULL)
241+ {
242+ wd->zfcbRecvEth(dev, subframeBuf, (u8_t)vap);
243+ ZM_PERFORMANCE_RX_MSDU(dev, wd->tick);
244+ }
245+ }
246+ zfwBufFree(dev, buf, 0);
247+
248+ return;
249+}
250--- /dev/null
251+++ b/drivers/staging/otus/80211core/cagg.c
252@@ -0,0 +1,3611 @@
253+/*
254+ * Copyright (c) 2007-2008 Atheros Communications Inc.
255+ *
256+ * Permission to use, copy, modify, and/or distribute this software for any
257+ * purpose with or without fee is hereby granted, provided that the above
258+ * copyright notice and this permission notice appear in all copies.
259+ *
260+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
261+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
262+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
263+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
264+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
265+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
266+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
267+ */
268+/* */
269+/* Module Name : cagg.c */
270+/* */
271+/* Abstract */
272+/* This module contains A-MPDU aggregation related functions. */
273+/* */
274+/* NOTES */
275+/* None */
276+/* */
277+/************************************************************************/
278+
279+#include "cprecomp.h"
280+
281+extern u8_t zcUpToAc[8];
282+const u8_t pri[] = {3,3,2,3,2,1,3,2,1,0};
283+
284+
285+u16_t aggr_count;
286+u32_t success_mpdu;
287+u32_t total_mpdu;
288+
289+void zfAggInit(zdev_t* dev)
290+{
291+ u16_t i,j;
292+
293+ zmw_get_wlan_dev(dev);
294+
295+ zmw_declare_for_critical_section();
296+ /*
297+ * reset sta information
298+ */
299+
300+ zmw_enter_critical_section(dev);
301+ wd->aggInitiated = 0;
302+ wd->addbaComplete = 0;
303+ wd->addbaCount = 0;
304+ wd->reorder = 1;
305+ for (i=0; i<ZM_MAX_STA_SUPPORT; i++)
306+ {
307+ for (j=0; j<ZM_AC; j++)
308+ {
309+ //wd->aggSta[i].aggQNumber[j] = ZM_AGG_POOL_SIZE;
310+ wd->aggSta[i].aggFlag[j] = wd->aggSta[i].count[j] = 0;
311+ wd->aggSta[i].tid_tx[j] = NULL;
312+ wd->aggSta[i].tid_tx[j+1] = NULL;
313+
314+ }
315+ }
316+
317+ /*
318+ * reset Tx/Rx aggregation queue information
319+ */
320+ wd->aggState = 0;
321+ for (i=0; i<ZM_AGG_POOL_SIZE; i++)
322+ {
323+ /*
324+ * reset tx aggregation queue
325+ */
326+ wd->aggQPool[i] = zfwMemAllocate(dev, sizeof(struct aggQueue));
327+ if(!wd->aggQPool[i])
328+ {
329+ zmw_leave_critical_section(dev);
330+ return;
331+ }
332+ wd->aggQPool[i]->aggHead = wd->aggQPool[i]->aggTail =
333+ wd->aggQPool[i]->aggQEnabled = wd->aggQPool[i]->aggReady =
334+ wd->aggQPool[i]->clearFlag = wd->aggQPool[i]->deleteFlag = 0;
335+ //wd->aggQPool[i]->aggSize = 16;
336+
337+ /*
338+ * reset rx aggregation queue
339+ */
340+ wd->tid_rx[i] = zfwMemAllocate(dev, sizeof(struct agg_tid_rx));
341+ if (!wd->tid_rx[i])
342+ {
343+ zmw_leave_critical_section(dev);
344+ return;
345+ }
346+ wd->tid_rx[i]->aid = ZM_MAX_STA_SUPPORT;
347+ wd->tid_rx[i]->seq_start = wd->tid_rx[i]->baw_head = \
348+ wd->tid_rx[i]->baw_tail = 0;
349+ wd->tid_rx[i]->sq_exceed_count = wd->tid_rx[i]->sq_behind_count = 0;
350+ for (j=0; j<=ZM_AGG_BAW_SIZE; j++)
351+ wd->tid_rx[i]->frame[j].buf = 0;
352+ /*
353+ * reset ADDBA exchange status code
354+ * 0: NULL
355+ * 1: ADDBA Request sent/received
356+ * 2: ACK for ADDBA Request sent/received
357+ * 3: ADDBA Response sent/received
358+ * 4: ACK for ADDBA Response sent/received
359+ */
360+ wd->tid_rx[i]->addBaExchangeStatusCode = 0;
361+
362+ }
363+ zmw_leave_critical_section(dev);
364+ zfAggTallyReset(dev);
365+ DESTQ.init = zfAggDestInit;
366+ DESTQ.init(dev);
367+ wd->aggInitiated = 1;
368+ aggr_count = 0;
369+ success_mpdu = 0;
370+ total_mpdu = 0;
371+#ifdef ZM_ENABLE_AGGREGATION
372+#ifndef ZM_ENABLE_FW_BA_RETRANSMISSION //disable BAW
373+ BAW = zfwMemAllocate(dev, sizeof(struct baw_enabler));
374+ if(!BAW)
375+ {
376+ return;
377+ }
378+ BAW->init = zfBawInit;
379+ BAW->init(dev);
380+#endif //disable BAW
381+#endif
382+}
383+
384+/************************************************************************/
385+/* */
386+/* FUNCTION DESCRIPTION zfAggGetSta */
387+/* return STA AID. */
388+/* take buf as input, use the dest address of buf as index to */
389+/* search STA AID. */
390+/* */
391+/* INPUTS */
392+/* dev : device pointer */
393+/* buf : buffer for one particular packet */
394+/* */
395+/* OUTPUTS */
396+/* AID */
397+/* */
398+/* AUTHOR */
399+/* Honda ZyDAS Technology Corporation 2006.11 */
400+/* */
401+/************************************************************************/
402+
403+
404+
405+u16_t zfAggGetSta(zdev_t* dev, zbuf_t* buf)
406+{
407+ u16_t id;
408+ u16_t dst[3];
409+
410+ zmw_get_wlan_dev(dev);
411+
412+ zmw_declare_for_critical_section();
413+
414+ dst[0] = zmw_rx_buf_readh(dev, buf, 0);
415+ dst[1] = zmw_rx_buf_readh(dev, buf, 2);
416+ dst[2] = zmw_rx_buf_readh(dev, buf, 4);
417+
418+ zmw_enter_critical_section(dev);
419+
420+ if(wd->wlanMode == ZM_MODE_AP) {
421+ id = zfApFindSta(dev, dst);
422+ }
423+ else {
424+ id = 0;
425+ }
426+ zmw_leave_critical_section(dev);
427+
428+#if ZM_AGG_FPGA_DEBUG
429+ id = 0;
430+#endif
431+
432+ return id;
433+}
434+
435+
436+/************************************************************************/
437+/* */
438+/* FUNCTION DESCRIPTION zfAggTxGetQueue */
439+/* return Queue Pool index. */
440+/* take aid as input, look for the queue index associated */
441+/* with this aid. */
442+/* */
443+/* INPUTS */
444+/* dev : device pointer */
445+/* aid : associated id */
446+/* */
447+/* OUTPUTS */
448+/* Queue number */
449+/* */
450+/* AUTHOR */
451+/* Honda ZyDAS Technology Corporation 2006.11 */
452+/* */
453+/************************************************************************/
454+TID_TX zfAggTxGetQueue(zdev_t* dev, u16_t aid, u16_t tid)
455+{
456+ //u16_t i;
457+ TID_TX tid_tx;
458+ zmw_get_wlan_dev(dev);
459+
460+ //zmw_declare_for_critical_section();
461+
462+ /*
463+ * not a STA aid
464+ */
465+ if (0xffff == aid)
466+ return NULL;
467+
468+ //zmw_enter_critical_section(dev);
469+
470+ tid_tx = wd->aggSta[aid].tid_tx[tid];
471+ if (!tid_tx) return NULL;
472+ if (0 == tid_tx->aggQEnabled)
473+ return NULL;
474+
475+ //zmw_leave_critical_section(dev);
476+
477+ return tid_tx;
478+}
479+
480+/************************************************************************/
481+/* */
482+/* FUNCTION DESCRIPTION zfAggTxNewQueue */
483+/* return Queue Pool index. */
484+/* take aid as input, find a new queue for this aid. */
485+/* */
486+/* INPUTS */
487+/* dev : device pointer */
488+/* aid : associated id */
489+/* */
490+/* OUTPUTS */
491+/* Queue number */
492+/* */
493+/* AUTHOR */
494+/* Honda ZyDAS Technology Corporation 2006.12 */
495+/* */
496+/************************************************************************/
497+TID_TX zfAggTxNewQueue(zdev_t* dev, u16_t aid, u16_t tid, zbuf_t* buf)
498+{
499+ u16_t i;
500+ TID_TX tid_tx=NULL;
501+ u16_t ac = zcUpToAc[tid&0x7] & 0x3;
502+ zmw_get_wlan_dev(dev);
503+
504+ zmw_declare_for_critical_section();
505+
506+ /*
507+ * not a STA aid
508+ */
509+ if (0xffff == aid)
510+ return NULL;
511+
512+ zmw_enter_critical_section(dev);
513+
514+ /*
515+ * find one new queue for sta
516+ */
517+ for (i=0; i<ZM_AGG_POOL_SIZE; i++)
518+ {
519+ if (wd->aggQPool[i]->aggQEnabled)
520+ {
521+ /*
522+ * this q is enabled
523+ */
524+ }
525+ else
526+ {
527+ tid_tx = wd->aggQPool[i];
528+ tid_tx->aggQEnabled = 1;
529+ tid_tx->aggQSTA = aid;
530+ tid_tx->ac = ac;
531+ tid_tx->tid = tid;
532+ tid_tx->aggHead = tid_tx->aggTail = tid_tx->size = 0;
533+ tid_tx->aggReady = 0;
534+ wd->aggSta[aid].tid_tx[tid] = tid_tx;
535+ tid_tx->dst[0] = zmw_rx_buf_readh(dev, buf, 0);
536+ tid_tx->dst[1] = zmw_rx_buf_readh(dev, buf, 2);
537+ tid_tx->dst[2] = zmw_rx_buf_readh(dev, buf, 4);
538+ break;
539+ }
540+ }
541+
542+ zmw_leave_critical_section(dev);
543+
544+ return tid_tx;
545+}
546+
547+
548+
549+/************************************************************************/
550+/* */
551+/* FUNCTION DESCRIPTION zfAggTxEnqueue */
552+/* return Status code ZM_SUCCESS or error code */
553+/* take (aid,ac,qnum,buf) as input */
554+/* */
555+/* INPUTS */
556+/* dev : device pointer */
557+/* aid : associated id */
558+/* ac : access category */
559+/* qnum: the queue number to which will be enqueued */
560+/* buf : the packet to be queued */
561+/* */
562+/* OUTPUTS */
563+/* status code */
564+/* */
565+/* AUTHOR */
566+/* Honda Atheros Communications, INC. 2006.12 */
567+/* */
568+/************************************************************************/
569+u16_t zfAggTxEnqueue(zdev_t* dev, zbuf_t* buf, u16_t aid, TID_TX tid_tx)
570+{
571+ //u16_t qlen, frameLen;
572+ u32_t time;
573+
574+ zmw_get_wlan_dev(dev);
575+
576+ zmw_declare_for_critical_section();
577+
578+ zmw_enter_critical_section(dev);
579+
580+ tid_tx->size = zm_agg_qlen(dev, tid_tx->aggHead, tid_tx->aggTail);
581+
582+ if (tid_tx->size < (ZM_AGGQ_SIZE - 2))
583+ {
584+ /* Queue not full */
585+
586+
587+ /*
588+ * buffer copy
589+ * in zfwBufFree will return a ndismsendcomplete
590+ * to resolve the synchronize problem in aggregate
591+ */
592+
593+ u8_t sendComplete = 0;
594+
595+ tid_tx->aggvtxq[tid_tx->aggHead].buf = buf;
596+ time = zm_agg_GetTime();
597+ tid_tx->aggvtxq[tid_tx->aggHead].arrivalTime = time;
598+ tid_tx->aggvtxq[tid_tx->aggHead].baw_retransmit = 0;
599+
600+ tid_tx->aggHead = ((tid_tx->aggHead + 1) & ZM_AGGQ_SIZE_MASK);
601+ tid_tx->lastArrival = time;
602+ tid_tx->size++;
603+ tid_tx->size = zm_agg_qlen(dev, tid_tx->aggHead, tid_tx->aggTail);
604+ if (buf && (tid_tx->size < (ZM_AGGQ_SIZE - 10))) {
605+ tid_tx->complete = tid_tx->aggHead;
606+ sendComplete = 1;
607+ }
608+ zmw_leave_critical_section(dev);
609+
610+ if (!DESTQ.exist(dev, 0, tid_tx->ac, tid_tx, NULL)) {
611+ DESTQ.insert(dev, 0, tid_tx->ac, tid_tx, NULL);
612+ }
613+
614+ zm_msg1_agg(ZM_LV_0, "tid_tx->size=", tid_tx->size);
615+ //zm_debug_msg1("tid_tx->size=", tid_tx->size);
616+
617+ if (buf && sendComplete && wd->zfcbSendCompleteIndication) {
618+ //zmw_leave_critical_section(dev);
619+ wd->zfcbSendCompleteIndication(dev, buf);
620+ }
621+
622+ /*if (tid_tx->size >= 16 && zfHpGetFreeTxdCount(dev) > 20)
623+ zfAggTxSend(dev, zfHpGetFreeTxdCount(dev), tid_tx);
624+ */
625+ return ZM_SUCCESS;
626+ }
627+ else
628+ {
629+ zm_msg1_agg(ZM_LV_0, "can't enqueue, tid_tx->size=", tid_tx->size);
630+ /*
631+ * Queue Full
632+ */
633+
634+ /*
635+ * zm_msg1_agg(ZM_LV_0, "Queue full, qnum = ", qnum);
636+ * wd->commTally.txQosDropCount[ac]++;
637+ * zfwBufFree(dev, buf, ZM_SUCCESS);
638+ * zm_msg1_agg(ZM_LV_1, "Packet discarded, VTXQ full, ac=", ac);
639+ *
640+ * return ZM_ERR_EXCEED_PRIORITY_THRESHOLD;
641+ */
642+ }
643+
644+ zmw_leave_critical_section(dev);
645+
646+ if (!DESTQ.exist(dev, 0, tid_tx->ac, tid_tx, NULL)) {
647+ DESTQ.insert(dev, 0, tid_tx->ac, tid_tx, NULL);
648+ }
649+
650+ return ZM_ERR_EXCEED_PRIORITY_THRESHOLD;
651+}
652+
653+u16_t zfAggDestExist(zdev_t* dev, u16_t Qtype, u16_t ac, TID_TX tid_tx, void* vtxq) {
654+ struct dest* dest;
655+ u16_t exist = 0;
656+ zmw_get_wlan_dev(dev);
657+
658+ zmw_declare_for_critical_section();
659+
660+ zmw_enter_critical_section(dev);
661+ if (!DESTQ.Head[ac]) {
662+ exist = 0;
663+ }
664+ else {
665+ dest = DESTQ.Head[ac];
666+ if (dest->tid_tx == tid_tx) {
667+ exist = 1;
668+ }
669+ else {
670+ while (dest->next != DESTQ.Head[ac]) {
671+ dest = dest->next;
672+ if (dest->tid_tx == tid_tx){
673+ exist = 1;
674+ break;
675+ }
676+ }
677+ }
678+ }
679+
680+ zmw_leave_critical_section(dev);
681+
682+ return exist;
683+}
684+
685+void zfAggDestInsert(zdev_t* dev, u16_t Qtype, u16_t ac, TID_TX tid_tx, void* vtxq)
686+{
687+ struct dest* new_dest;
688+ zmw_get_wlan_dev(dev);
689+
690+ zmw_declare_for_critical_section();
691+
692+ new_dest = zfwMemAllocate(dev, sizeof(struct dest));
693+ if(!new_dest)
694+ {
695+ return;
696+ }
697+ new_dest->Qtype = Qtype;
698+ new_dest->tid_tx = tid_tx;
699+ if (0 == Qtype)
700+ new_dest->tid_tx = tid_tx;
701+ else
702+ new_dest->vtxq = vtxq;
703+ if (!DESTQ.Head[ac]) {
704+
705+ zmw_enter_critical_section(dev);
706+ new_dest->next = new_dest;
707+ DESTQ.Head[ac] = DESTQ.dest[ac] = new_dest;
708+ zmw_leave_critical_section(dev);
709+ }
710+ else {
711+
712+ zmw_enter_critical_section(dev);
713+ new_dest->next = DESTQ.dest[ac]->next;
714+ DESTQ.dest[ac]->next = new_dest;
715+ zmw_leave_critical_section(dev);
716+ }
717+
718+
719+ //DESTQ.size[ac]++;
720+ return;
721+}
722+
723+void zfAggDestDelete(zdev_t* dev, u16_t Qtype, TID_TX tid_tx, void* vtxq)
724+{
725+ struct dest* dest, *temp;
726+ u16_t i;
727+
728+ zmw_get_wlan_dev(dev);
729+
730+ zmw_declare_for_critical_section();
731+
732+ zmw_enter_critical_section(dev);
733+ if (wd->destLock) {
734+ zmw_leave_critical_section(dev);
735+ return;
736+ }
737+
738+
739+ //zmw_declare_for_critical_section();
740+ for (i=0; i<4; i++) {
741+ if (!DESTQ.Head[i]) continue;
742+ dest = DESTQ.Head[i];
743+ if (!dest) continue;
744+
745+
746+ while (dest && (dest->next != DESTQ.Head[i])) {
747+ if (Qtype == 0 && dest->next->tid_tx == tid_tx){
748+ break;
749+ }
750+ if (Qtype == 1 && dest->next->vtxq == vtxq) {
751+ break;
752+ }
753+ dest = dest->next;
754+ }
755+
756+ if ((Qtype == 0 && dest->next->tid_tx == tid_tx) || (Qtype == 1 && dest->next->vtxq == vtxq)) {
757+
758+ tid_tx->size = zm_agg_qlen(dev, tid_tx->aggHead, tid_tx->aggTail);
759+ if (tid_tx->size) {
760+ zmw_leave_critical_section(dev);
761+ return;
762+ }
763+ if (!DESTQ.Head[i]) {
764+ temp = NULL;
765+ }
766+ else {
767+ temp = dest->next;
768+ if (temp == dest) {
769+ DESTQ.Head[i] = DESTQ.dest[i] = NULL;
770+ //DESTQ.size[i] = 0;
771+ }
772+ else {
773+ dest->next = dest->next->next;
774+ }
775+ }
776+
777+ if (temp == NULL)
778+ {/* do nothing */} //zfwMemFree(dev, temp, sizeof(struct dest));
779+ else
780+ zfwMemFree(dev, temp, sizeof(struct dest));
781+
782+ /*zmw_enter_critical_section(dev);
783+ if (DESTQ.size[i] > 0)
784+ DESTQ.size[i]--;
785+ zmw_leave_critical_section(dev);
786+ */
787+ }
788+
789+ }
790+ zmw_leave_critical_section(dev);
791+ return;
792+}
793+
794+void zfAggDestInit(zdev_t* dev)
795+{
796+ u16_t i;
797+ zmw_get_wlan_dev(dev);
798+
799+ //zmw_declare_for_critical_section();
800+
801+ for (i=0; i<4; i++) {
802+ //wd->destQ.Head[i].next = wd->destQ.Head[i];
803+ //wd->destQ.dest[i] = wd->destQ.Head[i];
804+ //DESTQ.size[i] = 0;
805+ DESTQ.Head[i] = NULL;
806+ }
807+ DESTQ.insert = zfAggDestInsert;
808+ DESTQ.delete = zfAggDestDelete;
809+ DESTQ.init = zfAggDestInit;
810+ DESTQ.getNext = zfAggDestGetNext;
811+ DESTQ.exist = zfAggDestExist;
812+ DESTQ.ppri = 0;
813+ return;
814+}
815+
816+struct dest* zfAggDestGetNext(zdev_t* dev, u16_t ac)
817+{
818+ struct dest *dest = NULL;
819+ zmw_get_wlan_dev(dev);
820+
821+ zmw_declare_for_critical_section();
822+
823+ zmw_enter_critical_section(dev);
824+ if (DESTQ.dest[ac]) {
825+ dest = DESTQ.dest[ac];
826+ DESTQ.dest[ac] = DESTQ.dest[ac]->next;
827+ }
828+ else {
829+ dest = NULL;
830+ }
831+ zmw_leave_critical_section(dev);
832+
833+ return dest;
834+}
835+
836+#ifdef ZM_ENABLE_AGGREGATION
837+#ifndef ZM_ENABLE_FW_BA_RETRANSMISSION //disable BAW
838+u16_t zfAggTidTxInsertHead(zdev_t* dev, struct bufInfo *buf_info,TID_TX tid_tx)
839+{
840+ zbuf_t* buf;
841+ u32_t time;
842+ struct baw_header *baw_header;
843+
844+ zmw_get_wlan_dev(dev);
845+
846+ zmw_declare_for_critical_section();
847+
848+
849+ buf = buf_info->buf;
850+
851+ zmw_enter_critical_section(dev);
852+ tid_tx->size = zm_agg_qlen(dev, tid_tx->aggHead, tid_tx->aggTail);
853+ zmw_leave_critical_section(dev);
854+
855+ if (tid_tx->size >= (ZM_AGGQ_SIZE - 2)) {
856+ zfwBufFree(dev, buf, ZM_SUCCESS);
857+ return 0;
858+ }
859+
860+ zmw_enter_critical_section(dev);
861+ tid_tx->aggTail = (tid_tx->aggTail == 0)? ZM_AGGQ_SIZE_MASK: tid_tx->aggTail - 1;
862+ tid_tx->aggvtxq[tid_tx->aggTail].buf = buf;
863+ //time = zm_agg_GetTime();
864+ tid_tx->aggvtxq[tid_tx->aggTail].arrivalTime = buf_info->timestamp;
865+ tid_tx->aggvtxq[tid_tx->aggTail].baw_retransmit = buf_info->baw_retransmit;
866+
867+ baw_header = &tid_tx->aggvtxq[tid_tx->aggTail].baw_header;
868+ baw_header->headerLen = buf_info->baw_header->headerLen;
869+ baw_header->micLen = buf_info->baw_header->micLen;
870+ baw_header->snapLen = buf_info->baw_header->snapLen;
871+ baw_header->removeLen = buf_info->baw_header->removeLen;
872+ baw_header->keyIdx = buf_info->baw_header->keyIdx;
873+ zfwMemoryCopy((u8_t *)baw_header->header, (u8_t *)buf_info->baw_header->header, 58);
874+ zfwMemoryCopy((u8_t *)baw_header->mic , (u8_t *)buf_info->baw_header->mic , 8);
875+ zfwMemoryCopy((u8_t *)baw_header->snap , (u8_t *)buf_info->baw_header->snap , 8);
876+
877+ tid_tx->size++;
878+ tid_tx->size = zm_agg_qlen(dev, tid_tx->aggHead, tid_tx->aggTail);
879+ zmw_leave_critical_section(dev);
880+
881+ //tid_tx->lastArrival = time;
882+ if (1 == tid_tx->size) {
883+ DESTQ.insert(dev, 0, tid_tx->ac, tid_tx, NULL);
884+ }
885+
886+
887+ zm_msg1_agg(ZM_LV_0, "0xC2:insertHead, tid_tx->size=", tid_tx->size);
888+
889+ return TRUE;
890+}
891+#endif //disable BAW
892+#endif
893+
894+void zfiTxComplete(zdev_t* dev)
895+{
896+
897+ zmw_get_wlan_dev(dev);
898+
899+ //zmw_declare_for_critical_section();
900+
901+ if( (wd->wlanMode == ZM_MODE_AP) ||
902+ (wd->wlanMode == ZM_MODE_INFRASTRUCTURE && wd->sta.EnableHT) ||
903+ (wd->wlanMode == ZM_MODE_PSEUDO) ) {
904+ zfAggTxScheduler(dev, 0);
905+ }
906+
907+ return;
908+}
909+
910+TID_TX zfAggTxReady(zdev_t* dev) {
911+ //struct dest* dest;
912+ u16_t i;
913+ TID_TX tid_tx = NULL;
914+ zmw_get_wlan_dev(dev);
915+
916+ zmw_declare_for_critical_section();
917+
918+ zmw_enter_critical_section(dev);
919+ for (i=0; i<ZM_AGG_POOL_SIZE; i++)
920+ {
921+ if (wd->aggQPool[i]->aggQEnabled)
922+ {
923+ if (wd->aggQPool[i]->size >= 16) {
924+ tid_tx = wd->aggQPool[i];
925+ break;
926+ }
927+ }
928+ else {
929+ }
930+ }
931+ zmw_leave_critical_section(dev);
932+ return tid_tx;
933+}
934+
935+u16_t zfAggValidTidTx(zdev_t* dev, TID_TX tid_tx) {
936+ u16_t i, valid = 0;
937+ zmw_get_wlan_dev(dev);
938+
939+ zmw_declare_for_critical_section();
940+
941+ zmw_enter_critical_section(dev);
942+ for (i=0; i<ZM_AGG_POOL_SIZE; i++)
943+ {
944+ if (wd->aggQPool[i] == tid_tx)
945+ {
946+ valid = 1;
947+ break;
948+ }
949+ else {
950+ }
951+ }
952+ zmw_leave_critical_section(dev);
953+
954+ return valid;
955+}
956+
957+void zfAggTxScheduler(zdev_t* dev, u8_t ScanAndClear)
958+{
959+ TID_TX tid_tx = NULL;
960+ void* vtxq;
961+ struct dest* dest;
962+ zbuf_t* buf;
963+ u32_t txql, min_txql;
964+ //u16_t aggr_size = 1;
965+ u16_t txq_threshold;
966+ zmw_get_wlan_dev(dev);
967+
968+ zmw_declare_for_critical_section();
969+
970+ if (!wd->aggInitiated)
971+ {
972+ return;
973+ }
974+
975+ /* debug */
976+ txql = TXQL;
977+ min_txql = AGG_MIN_TXQL;
978+
979+ if(wd->txq_threshold)
980+ txq_threshold = wd->txq_threshold;
981+ else
982+ txq_threshold = AGG_MIN_TXQL;
983+
984+ tid_tx = zfAggTxReady(dev);
985+ if (tid_tx) ScanAndClear = 0;
986+ while (zfHpGetFreeTxdCount(dev) > 20 && (TXQL < txq_threshold || tid_tx)) {
987+ //while (zfHpGetFreeTxdCount(dev) > 20 && (ScanAndClear || tid_tx)) {
988+ //while (TXQL < txq_threshold) {
989+ u16_t i;
990+ u8_t ac;
991+ s8_t destQ_count = 0;
992+ //while ((zfHpGetFreeTxdCount(dev)) > 32) {
993+
994+ //DbgPrint("zfAggTxScheduler: in while loop");
995+ for (i=0; i<4; i++) {
996+ if (DESTQ.Head[i]) destQ_count++;
997+ }
998+ if (0 >= destQ_count) break;
999+
1000+ zmw_enter_critical_section(dev);
1001+ ac = pri[DESTQ.ppri]; DESTQ.ppri = (DESTQ.ppri + 1) % 10;
1002+ zmw_leave_critical_section(dev);
1003+
1004+ for (i=0; i<10; i++){
1005+ if(DESTQ.Head[ac]) break;
1006+
1007+ zmw_enter_critical_section(dev);
1008+ ac = pri[DESTQ.ppri]; DESTQ.ppri = (DESTQ.ppri + 1) % 10;
1009+ zmw_leave_critical_section(dev);
1010+ }
1011+ if (i == 10) break;
1012+ //DbgPrint("zfAggTxScheduler: have dest Q");
1013+ zmw_enter_critical_section(dev);
1014+ wd->destLock = 1;
1015+ zmw_leave_critical_section(dev);
1016+
1017+ dest = DESTQ.getNext(dev, ac);
1018+ if (!dest) {
1019+ zmw_enter_critical_section(dev);
1020+ wd->destLock = 0;
1021+ zmw_leave_critical_section(dev);
1022+
1023+ DbgPrint("bug report! DESTQ.getNext got nothing!");
1024+ break;
1025+ }
1026+ if (dest->Qtype == 0) {
1027+ tid_tx = dest->tid_tx;
1028+
1029+ //DbgPrint("zfAggTxScheduler: have tid_tx Q");
1030+
1031+ if(tid_tx && zfAggValidTidTx(dev, tid_tx))
1032+ tid_tx->size = zm_agg_qlen(dev, tid_tx->aggHead, tid_tx->aggTail);
1033+ else {
1034+ zmw_enter_critical_section(dev);
1035+ wd->destLock = 0;
1036+ zmw_leave_critical_section(dev);
1037+
1038+ tid_tx = zfAggTxReady(dev);
1039+ continue;
1040+ }
1041+
1042+ zmw_enter_critical_section(dev);
1043+ wd->destLock = 0;
1044+ zmw_leave_critical_section(dev);
1045+ //zmw_enter_critical_section(dev);
1046+ if (tid_tx && !tid_tx->size) {
1047+
1048+ //zmw_leave_critical_section(dev);
1049+ //DESTQ.delete(dev, 0, tid_tx, NULL);
1050+ }
1051+ else if(wd->aggState == 0){
1052+ //wd->aggState = 1;
1053+ //zmw_leave_critical_section(dev);
1054+ zfAggTxSend(dev, zfHpGetFreeTxdCount(dev), tid_tx);
1055+ //wd->aggState = 0;
1056+ }
1057+ else {
1058+ //zmw_leave_critical_section(dev);
1059+ break;
1060+ }
1061+ }
1062+ else {
1063+ vtxq = dest->vtxq;
1064+ buf = zfGetVtxq(dev, ac);
1065+ zm_assert( buf != 0 );
1066+
1067+ zfTxSendEth(dev, buf, 0, ZM_EXTERNAL_ALLOC_BUF, 0);
1068+
1069+ }
1070+ /*flush all but < 16 frames in tid_tx to TXQ*/
1071+ tid_tx = zfAggTxReady(dev);
1072+ }
1073+
1074+ /*while ((zfHpGetFreeTxdCount(dev)) > 32) {
1075+ //while ((zfHpGetFreeTxdCount(dev)) > 32) {
1076+
1077+ destQ_count = 0;
1078+ for (i=0; i<4; i++) destQ_count += wd->destQ.size[i];
1079+ if (0 >= destQ_count) break;
1080+
1081+ ac = pri[wd->destQ.ppri]; wd->destQ.ppri = (wd->destQ.ppri + 1) % 10;
1082+ for (i=0; i<10; i++){
1083+ if(wd->destQ.size[ac]!=0) break;
1084+ ac = pri[wd->destQ.ppri]; wd->destQ.ppri = (wd->destQ.ppri + 1) % 10;
1085+ }
1086+ if (i == 10) break;
1087+ dest = wd->destQ.getNext(dev, ac);
1088+ if (dest->Qtype == 0) {
1089+ tid_tx = dest->tid_tx;
1090+ tid_tx->size = zm_agg_qlen(dev, tid_tx->aggHead, tid_tx->aggTail);
1091+ if (!tid_tx->size) {
1092+ wd->destQ.delete(dev, 0, tid_tx, NULL);
1093+ break;
1094+ }
1095+ else if((wd->aggState == 0) && (tid_tx->size >= 16)){
1096+ zfAggTxSend(dev, zfHpGetFreeTxdCount(dev), tid_tx);
1097+ }
1098+ else {
1099+ break;
1100+ }
1101+ }
1102+
1103+ }
1104+ */
1105+ return;
1106+}
1107+
1108+/************************************************************************/
1109+/* */
1110+/* FUNCTION DESCRIPTION zfAggTx */
1111+/* return Status code ZM_SUCCESS or error code */
1112+/* management A-MPDU aggregation function, */
1113+/* management aggregation queue, calculate arrivalrate, */
1114+/* add/delete an aggregation queue of a stream, */
1115+/* enqueue packets into responsible aggregate queue. */
1116+/* take (dev, buf, ac) as input */
1117+/* */
1118+/* INPUTS */
1119+/* dev : device pointer */
1120+/* buf : packet buff */
1121+/* ac : access category */
1122+/* */
1123+/* OUTPUTS */
1124+/* status code */
1125+/* */
1126+/* AUTHOR */
1127+/* Honda Atheros Communications, INC. 2006.12 */
1128+/* */
1129+/************************************************************************/
1130+u16_t zfAggTx(zdev_t* dev, zbuf_t* buf, u16_t tid)
1131+{
1132+ u16_t aid;
1133+ //u16_t qnum;
1134+ //u16_t aggflag = 0;
1135+ //u16_t arrivalrate = 0;
1136+ TID_TX tid_tx;
1137+
1138+ zmw_get_wlan_dev(dev);
1139+
1140+ zmw_declare_for_critical_section();
1141+
1142+ if(!wd->aggInitiated)
1143+ {
1144+ return ZM_ERR_TX_BUFFER_UNAVAILABLE;
1145+ }
1146+
1147+ aid = zfAggGetSta(dev, buf);
1148+
1149+ //arrivalrate = zfAggTxArrivalRate(dev, aid, tid);
1150+
1151+ if (0xffff == aid)
1152+ {
1153+ /*
1154+ * STA not associated, this is a BC/MC or STA->AP packet
1155+ */
1156+
1157+ return ZM_ERR_TX_BUFFER_UNAVAILABLE;
1158+ }
1159+
1160+ /*
1161+ * STA associated, a unicast packet
1162+ */
1163+
1164+ tid_tx = zfAggTxGetQueue(dev, aid, tid);
1165+
1166+ /*tid_q.tid_tx = tid_tx;
1167+ wd->destQ.insert = zfAggDestInsert;
1168+ wd->destQ.insert(dev, 0, tid_q);
1169+ */
1170+ if (tid_tx != NULL)
1171+ {
1172+ /*
1173+ * this (aid, ac) is aggregated
1174+ */
1175+
1176+ //if (arrivalrate < ZM_AGG_LOW_THRESHOLD)
1177+ if (0)
1178+ {
1179+ /*
1180+ * arrival rate too low
1181+ * delete this aggregate queue
1182+ */
1183+
1184+ zmw_enter_critical_section(dev);
1185+
1186+ //wd->aggQPool[qnum]->clearFlag = wd->aggQPool[qnum]->deleteFlag =1;
1187+
1188+ zmw_leave_critical_section(dev);
1189+
1190+ }
1191+
1192+ return zfAggTxEnqueue(dev, buf, aid, tid_tx);
1193+
1194+ }
1195+ else
1196+ {
1197+ /*
1198+ * this (aid, ac) not yet aggregated
1199+ * queue not found
1200+ */
1201+
1202+ //if (arrivalrate > ZM_AGG_HIGH_THRESHOLD)
1203+ if (1)
1204+ {
1205+ /*
1206+ * arrivalrate high enough to get a new agg queue
1207+ */
1208+
1209+ tid_tx = zfAggTxNewQueue(dev, aid, tid, buf);
1210+
1211+ //zm_msg1_agg(ZM_LV_0, "get new AggQueue qnum = ", tid_tx->);
1212+
1213+ if (tid_tx)
1214+ {
1215+ /*
1216+ * got a new aggregate queue
1217+ */
1218+
1219+ //zmw_enter_critical_section(dev);
1220+
1221+ //wd->aggSta[aid].aggFlag[ac] = 1;
1222+
1223+ //zmw_leave_critical_section(dev);
1224+
1225+ /*
1226+ * add ADDBA functions here
1227+ * return ZM_ERR_TX_BUFFER_UNAVAILABLE;
1228+ */
1229+
1230+
1231+ //zfAggSendAddbaRequest(dev, tid_tx->dst, tid_tx->ac, tid_tx->tid);
1232+ //zmw_enter_critical_section(dev);
1233+
1234+ //wd->aggSta[aid].aggFlag[ac] = 0;
1235+
1236+ //zmw_leave_critical_section(dev);
1237+
1238+ return zfAggTxEnqueue(dev, buf, aid, tid_tx);
1239+
1240+ }
1241+ else
1242+ {
1243+ /*
1244+ * just can't get a new aggregate queue
1245+ */
1246+
1247+ return ZM_ERR_TX_BUFFER_UNAVAILABLE;
1248+ }
1249+ }
1250+ else
1251+ {
1252+ /*
1253+ * arrival rate is not high enough to get a new agg queue
1254+ */
1255+
1256+ return ZM_ERR_TX_BUFFER_UNAVAILABLE;
1257+ }
1258+ }
1259+
1260+
1261+
1262+}
1263+
1264+
1265+/************************************************************************/
1266+/* */
1267+/* FUNCTION DESCRIPTION zfAggTxReadyCount */
1268+/* return counter of ready to aggregate queues. */
1269+/* take (dev, ac) as input, only calculate the ready to aggregate */
1270+/* queues of one particular ac. */
1271+/* */
1272+/* INPUTS */
1273+/* dev : device pointer */
1274+/* ac : access category */
1275+/* */
1276+/* OUTPUTS */
1277+/* counter of ready to aggregate queues */
1278+/* */
1279+/* AUTHOR */
1280+/* Honda Atheros Communications, INC. 2006.12 */
1281+/* */
1282+/************************************************************************/
1283+u16_t zfAggTxReadyCount(zdev_t* dev, u16_t ac)
1284+{
1285+ u16_t i;
1286+ u16_t readycount = 0;
1287+
1288+ zmw_get_wlan_dev(dev);
1289+
1290+ zmw_declare_for_critical_section();
1291+
1292+ zmw_enter_critical_section(dev);
1293+
1294+ for (i=0 ; i<ZM_AGG_POOL_SIZE; i++)
1295+ {
1296+ if (wd->aggQPool[i]->aggQEnabled && (wd->aggQPool[i]->aggReady || \
1297+ wd->aggQPool[i]->clearFlag) && ac == wd->aggQPool[i]->ac)
1298+ readycount++;
1299+ }
1300+
1301+ zmw_leave_critical_section(dev);
1302+
1303+ return readycount;
1304+}
1305+
1306+/************************************************************************/
1307+/* */
1308+/* FUNCTION DESCRIPTION zfAggTxPartial */
1309+/* return the number that Vtxq has to send. */
1310+/* take (dev, ac, readycount) as input, calculate the ratio of */
1311+/* Vtxq length to (Vtxq length + readycount) of a particular ac, */
1312+/* and returns the Vtxq length * the ratio */
1313+/* */
1314+/* INPUTS */
1315+/* dev : device pointer */
1316+/* ac : access category */
1317+/* readycount: the number of ready to aggregate queues of this ac */
1318+/* */
1319+/* OUTPUTS */
1320+/* Vtxq length * ratio */
1321+/* */
1322+/* AUTHOR */
1323+/* Honda Atheros Communications, INC. 2006.12 */
1324+/* */
1325+/************************************************************************/
1326+u16_t zfAggTxPartial(zdev_t* dev, u16_t ac, u16_t readycount)
1327+{
1328+ u16_t qlen;
1329+ u16_t partial;
1330+
1331+ zmw_get_wlan_dev(dev);
1332+
1333+ zmw_declare_for_critical_section();
1334+
1335+ zmw_enter_critical_section(dev);
1336+
1337+ qlen = zm_agg_qlen(dev, wd->vtxqHead[ac], wd->vtxqTail[ac]);
1338+
1339+ if ((qlen + readycount) > 0)
1340+ {
1341+ partial = (u16_t)( zm_agg_weight(ac) * ((u16_t)qlen/(qlen + \
1342+ readycount)) );
1343+ }
1344+ else
1345+ {
1346+ partial = 0;
1347+ }
1348+
1349+ zmw_leave_critical_section(dev);
1350+
1351+ if (partial > qlen)
1352+ partial = qlen;
1353+
1354+ return partial;
1355+}
1356+
1357+
1358+/************************************************************************/
1359+/* */
1360+/* FUNCTION DESCRIPTION zfAggTxSend */
1361+/* return sentcount */
1362+/* take (dev, ac, n) as input, n is the number of scheduled agg */
1363+/* queues to be sent of the particular ac. */
1364+/* */
1365+/* INPUTS */
1366+/* dev : device pointer */
1367+/* ac : access category */
1368+/* n : the number of scheduled aggregation queues to be sent */
1369+/* */
1370+/* OUTPUTS */
1371+/* sentcount */
1372+/* */
1373+/* AUTHOR */
1374+/* Honda Atheros Communications, INC. 2006.12 */
1375+/* */
1376+/************************************************************************/
1377+u16_t zfAggTxSend(zdev_t* dev, u32_t freeTxd, TID_TX tid_tx)
1378+{
1379+ //u16_t qnum;
1380+ //u16_t qlen;
1381+ u16_t j;
1382+ //u16_t sentcount = 0;
1383+ zbuf_t* buf;
1384+ struct aggControl aggControl;
1385+ u16_t aggLen;
1386+ //zbuf_t* newBuf;
1387+ //u16_t bufLen;
1388+ //TID_BAW tid_baw = NULL;
1389+ //struct bufInfo *buf_info;
1390+
1391+ zmw_get_wlan_dev(dev);
1392+
1393+ zmw_declare_for_critical_section();
1394+
1395+ //while (tid_tx->size > 0)
1396+
1397+ zmw_enter_critical_section(dev);
1398+ tid_tx->size = zm_agg_qlen(dev, tid_tx->aggHead, tid_tx->aggTail);
1399+ aggLen = zm_agg_min(16, zm_agg_min(tid_tx->size, (u16_t)(freeTxd - 2)));
1400+ zmw_leave_critical_section(dev);
1401+
1402+ /*
1403+ * why there have to be 2 free Txd?
1404+ */
1405+ if (aggLen <=0 )
1406+ return 0;
1407+
1408+
1409+ if (aggLen == 1) {
1410+ buf = zfAggTxGetVtxq(dev, tid_tx);
1411+ if (buf)
1412+ zfTxSendEth(dev, buf, 0, ZM_EXTERNAL_ALLOC_BUF, 0);
1413+ if (tid_tx->size == 0) {
1414+ //DESTQ.delete(dev, 0, tid_tx, NULL);
1415+ }
1416+
1417+ return 1;
1418+ }
1419+ /*
1420+ * Free Txd queue is big enough to put aggregation
1421+ */
1422+ zmw_enter_critical_section(dev);
1423+ if (wd->aggState == 1) {
1424+ zmw_leave_critical_section(dev);
1425+ return 0;
1426+ }
1427+ wd->aggState = 1;
1428+ zmw_leave_critical_section(dev);
1429+
1430+
1431+ zm_msg1_agg(ZM_LV_0, "aggLen=", aggLen);
1432+ tid_tx->aggFrameSize = 0;
1433+ for (j=0; j < aggLen; j++) {
1434+ buf = zfAggTxGetVtxq(dev, tid_tx);
1435+
1436+ zmw_enter_critical_section(dev);
1437+ tid_tx->size = zm_agg_qlen(dev, tid_tx->aggHead, tid_tx->aggTail);
1438+ zmw_leave_critical_section(dev);
1439+
1440+ if ( buf ) {
1441+ //struct aggTally *agg_tal;
1442+ u16_t completeIndex;
1443+
1444+ if (0 == j) {
1445+ aggControl.ampduIndication = ZM_AGG_FIRST_MPDU;
1446+
1447+ }
1448+ else if ((j == (aggLen - 1)) || tid_tx->size == 0)
1449+ {
1450+ aggControl.ampduIndication = ZM_AGG_LAST_MPDU;
1451+ //wd->aggState = 0;
1452+
1453+ }
1454+ else
1455+ {
1456+ aggControl.ampduIndication = ZM_AGG_MIDDLE_MPDU;
1457+ /* the packet is delayed more than 500 ms, drop it */
1458+
1459+ }
1460+ tid_tx->aggFrameSize += zfwBufGetSize(dev, buf);
1461+ aggControl.addbaIndication = 0;
1462+ aggControl.aggEnabled = 1;
1463+
1464+#ifdef ZM_AGG_TALLY
1465+ agg_tal = &wd->agg_tal;
1466+ agg_tal->sent_packets_sum++;
1467+
1468+#endif
1469+
1470+ zfAggTxSendEth(dev, buf, 0, ZM_EXTERNAL_ALLOC_BUF, 0, &aggControl, tid_tx);
1471+
1472+ zmw_enter_critical_section(dev);
1473+ completeIndex = tid_tx->complete;
1474+ if(zm_agg_inQ(tid_tx, tid_tx->complete))
1475+ zm_agg_plus(tid_tx->complete);
1476+ zmw_leave_critical_section(dev);
1477+
1478+ if(zm_agg_inQ(tid_tx, completeIndex) && wd->zfcbSendCompleteIndication
1479+ && tid_tx->aggvtxq[completeIndex].buf) {
1480+ wd->zfcbSendCompleteIndication(dev, tid_tx->aggvtxq[completeIndex].buf);
1481+ zm_debug_msg0("in queue complete worked!");
1482+ }
1483+
1484+ }
1485+ else {
1486+ /*
1487+ * this aggregation queue is empty
1488+ */
1489+ zm_msg1_agg(ZM_LV_0, "aggLen not reached, but no more frame, j=", j);
1490+
1491+ break;
1492+ }
1493+ }
1494+ zmw_enter_critical_section(dev);
1495+ wd->aggState = 0;
1496+ zmw_leave_critical_section(dev);
1497+
1498+ //zm_acquire_agg_spin_lock(Adapter);
1499+ tid_tx->size = zm_agg_qlen(dev, tid_tx->aggHead, tid_tx->aggTail);
1500+ //zm_release_agg_spin_lock(Adapter);
1501+
1502+ if (tid_tx->size == 0) {
1503+ //DESTQ.delete(dev, 0, tid_tx, NULL);
1504+ }
1505+
1506+
1507+
1508+ //zfAggInvokeBar(dev, tid_tx);
1509+ if(j>0) {
1510+ aggr_count++;
1511+ zm_msg1_agg(ZM_LV_0, "0xC2:sent 1 aggr, aggr_count=", aggr_count);
1512+ zm_msg1_agg(ZM_LV_0, "0xC2:sent 1 aggr, aggr_size=", j);
1513+ }
1514+ return j;
1515+}
1516+
1517+
1518+/************************************************************************/
1519+/* */
1520+/* FUNCTION DESCRIPTION zfAggTxGetReadyQueue */
1521+/* return the number of the aggregation queue */
1522+/* take (dev, ac) as input, find the agg queue with smallest */
1523+/* arrival time (waited longest) among those ready or clearFlag */
1524+/* set queues. */
1525+/* */
1526+/* INPUTS */
1527+/* dev : device pointer */
1528+/* ac : access category */
1529+/* */
1530+/* OUTPUTS */
1531+/* aggregation queue number */
1532+/* */
1533+/* AUTHOR */
1534+/* Honda Atheros Communications, INC. 2006.12 */
1535+/* */
1536+/************************************************************************/
1537+TID_TX zfAggTxGetReadyQueue(zdev_t* dev, u16_t ac)
1538+{
1539+ //u16_t qnum = ZM_AGG_POOL_SIZE;
1540+ u16_t i;
1541+ u32_t time = 0;
1542+ TID_TX tid_tx = NULL;
1543+
1544+ zmw_get_wlan_dev(dev);
1545+
1546+ zmw_declare_for_critical_section();
1547+
1548+ zmw_enter_critical_section(dev);
1549+
1550+ for (i=0 ;i<ZM_AGG_POOL_SIZE; i++)
1551+ {
1552+ if (1 == wd->aggQPool[i]->aggQEnabled && ac == wd->aggQPool[i]->ac &&
1553+ (wd->aggQPool[i]->size > 0))
1554+ {
1555+ if (0 == time || time > wd->aggQPool[i]->aggvtxq[ \
1556+ wd->aggQPool[i]->aggHead ].arrivalTime)
1557+ {
1558+ tid_tx = wd->aggQPool[i];
1559+ time = tid_tx->aggvtxq[ tid_tx->aggHead ].arrivalTime;
1560+ }
1561+ }
1562+ }
1563+
1564+ zmw_leave_critical_section(dev);
1565+
1566+ return tid_tx;
1567+}
1568+
1569+
1570+
1571+/************************************************************************/
1572+/* */
1573+/* FUNCTION DESCRIPTION zfAggTxGetVtxq */
1574+/* return an MSDU */
1575+/* take (dev, qnum) as input, return an MSDU out of the agg queue. */
1576+/* */
1577+/* INPUTS */
1578+/* dev : device pointer */
1579+/* qnum: queue number */
1580+/* */
1581+/* OUTPUTS */
1582+/* a MSDU */
1583+/* */
1584+/* AUTHOR */
1585+/* Honda Atheros Communications, INC. 2006.12 */
1586+/* */
1587+/************************************************************************/
1588+zbuf_t* zfAggTxGetVtxq(zdev_t* dev, TID_TX tid_tx)
1589+{
1590+ zbuf_t* buf = NULL;
1591+
1592+ zmw_declare_for_critical_section();
1593+
1594+ if (tid_tx->aggHead != tid_tx->aggTail)
1595+ {
1596+ buf = tid_tx->aggvtxq[ tid_tx->aggTail ].buf;
1597+
1598+ tid_tx->aggvtxq[tid_tx->aggTail].buf = NULL;
1599+
1600+ zmw_enter_critical_section(dev);
1601+ tid_tx->aggTail = ((tid_tx->aggTail + 1) & ZM_AGGQ_SIZE_MASK);
1602+ if(tid_tx->size > 0) tid_tx->size--;
1603+ tid_tx->size = zm_agg_qlen(dev, tid_tx->aggHead, tid_tx->aggTail);
1604+ if (NULL == buf) {
1605+ //tid_tx->aggTail = tid_tx->aggHead = tid_tx->size = 0;
1606+ //zm_msg1_agg(ZM_LV_0, "GetVtxq buf == NULL, tid_tx->size=", tid_tx->size);
1607+ }
1608+ zmw_leave_critical_section(dev);
1609+ }
1610+ else
1611+ {
1612+ /*
1613+ * queue is empty
1614+ */
1615+ zm_msg1_agg(ZM_LV_0, "tid_tx->aggHead == tid_tx->aggTail, tid_tx->size=", tid_tx->size);
1616+
1617+ }
1618+
1619+ if (zm_agg_qlen(dev, tid_tx->aggHead, tid_tx->aggTail) != tid_tx->size)
1620+ zm_msg1_agg(ZM_LV_0, "qlen!=tid_tx->size! tid_tx->size=", tid_tx->size);
1621+ return buf;
1622+}
1623+
1624+
1625+/************************************************************************/
1626+/* */
1627+/* FUNCTION DESCRIPTION zfAggTxDeleteQueue */
1628+/* return ZM_SUCCESS (can't fail) */
1629+/* take (dev, qnum) as input, reset (delete) this aggregate queue, */
1630+/* this queue is virtually returned to the aggregate queue pool. */
1631+/* */
1632+/* INPUTS */
1633+/* dev : device pointer */
1634+/* qnum: queue number */
1635+/* */
1636+/* OUTPUTS */
1637+/* ZM_SUCCESS */
1638+/* */
1639+/* AUTHOR */
1640+/* Honda Atheros Communications, INC. 2006.12 */
1641+/* */
1642+/************************************************************************/
1643+u16_t zfAggTxDeleteQueue(zdev_t* dev, u16_t qnum)
1644+{
1645+ u16_t ac, tid;
1646+ struct aggQueue *tx_tid;
1647+ struct aggSta *agg_sta;
1648+
1649+ zmw_get_wlan_dev(dev);
1650+
1651+ zmw_declare_for_critical_section();
1652+
1653+ tx_tid = wd->aggQPool[qnum];
1654+ agg_sta = &wd->aggSta[tx_tid->aggQSTA];
1655+ ac = tx_tid->ac;
1656+ tid = tx_tid->tid;
1657+
1658+ zmw_enter_critical_section(dev);
1659+
1660+ tx_tid->aggQEnabled = 0;
1661+ tx_tid->aggHead = tx_tid->aggTail = 0;
1662+ tx_tid->aggReady = 0;
1663+ tx_tid->clearFlag = tx_tid->deleteFlag = 0;
1664+ tx_tid->size = 0;
1665+ agg_sta->count[ac] = 0;
1666+
1667+ agg_sta->tid_tx[tid] = NULL;
1668+ agg_sta->aggFlag[ac] = 0;
1669+
1670+ zmw_leave_critical_section(dev);
1671+
1672+ zm_msg1_agg(ZM_LV_0, "queue deleted! qnum=", qnum);
1673+
1674+ return ZM_SUCCESS;
1675+}
1676+
1677+#ifdef ZM_ENABLE_AGGREGATION
1678+#ifndef ZM_ENABLE_FW_BA_RETRANSMISSION //disable BAW
1679+void zfBawCore(zdev_t* dev, u16_t baw_seq, u32_t bitmap, u16_t aggLen) {
1680+ TID_BAW tid_baw;
1681+ s16_t i;
1682+ zbuf_t* buf;
1683+ struct bufInfo *buf_info;
1684+
1685+ zmw_get_wlan_dev(dev);
1686+ //zmw_declare_for_critical_section();
1687+ tid_baw = BAW->getQ(dev, baw_seq);
1688+ //tid_baw = NULL;
1689+ if (NULL == tid_baw)
1690+ return;
1691+
1692+ total_mpdu += aggLen;
1693+ for (i = aggLen - 1; i>=0; i--) {
1694+ if (((bitmap >> i) & 0x1) == 0) {
1695+ buf_info = BAW->pop(dev, i, tid_baw);
1696+ buf = buf_info->buf;
1697+ if (buf) {
1698+ //wd->zfcbSetBawQ(dev, buf, 0);
1699+ zfAggTidTxInsertHead(dev, buf_info, tid_baw->tid_tx);
1700+ }
1701+ }
1702+ else {
1703+ success_mpdu++;
1704+ }
1705+ }
1706+ BAW->disable(dev, tid_baw);
1707+ zfAggTxScheduler(dev);
1708+ zm_debug_msg1("success_mpdu = ", success_mpdu);
1709+ zm_debug_msg1(" total_mpdu = ", total_mpdu);
1710+}
1711+
1712+void zfBawInit(zdev_t* dev) {
1713+ TID_BAW tid_baw;
1714+ u16_t i,j;
1715+ zmw_get_wlan_dev(dev);
1716+ //zmw_declare_for_critical_section();
1717+
1718+ for (i=0; i<ZM_BAW_POOL_SIZE; i++){
1719+ tid_baw = &BAW->tid_baw[i];
1720+ for (j=0; j<ZM_VTXQ_SIZE; j++) {
1721+ tid_baw->frame[j].buf = NULL;
1722+ }
1723+ tid_baw->enabled = tid_baw->head = tid_baw->tail = tid_baw->size = 0;
1724+ tid_baw->start_seq = 0;
1725+ }
1726+ BAW->delPoint = 0;
1727+ BAW->core = zfBawCore;
1728+ BAW->getNewQ = zfBawGetNewQ;
1729+ BAW->insert = zfBawInsert;
1730+ BAW->pop = zfBawPop;
1731+ BAW->enable = zfBawEnable;
1732+ BAW->disable = zfBawDisable;
1733+ BAW->getQ = zfBawGetQ;
1734+}
1735+
1736+
1737+
1738+TID_BAW zfBawGetNewQ(zdev_t* dev, u16_t start_seq, TID_TX tid_tx) {
1739+ TID_BAW tid_baw=NULL;
1740+ TID_BAW next_baw=NULL;
1741+ u16_t i;
1742+ zmw_get_wlan_dev(dev);
1743+ //zmw_declare_for_critical_section();
1744+
1745+ /*
1746+ for (i=0; i<ZM_BAW_POOL_SIZE; i++){
1747+ tid_baw = &BAW->tid_baw[i];
1748+ if (FALSE == tid_baw->enabled)
1749+ break;
1750+ }
1751+ */
1752+
1753+ tid_baw = &BAW->tid_baw[BAW->delPoint];
1754+ i = BAW->delPoint;
1755+ //if (ZM_BAW_POOL_SIZE == i) {
1756+ //return NULL;
1757+ // u8_t temp = BAW->delPoint;
1758+ // tid_baw = &BAW->tid_baw[BAW->delPoint];
1759+ // BAW->disable(dev, tid_baw);
1760+ // BAW->delPoint = (BAW->delPoint < (ZM_BAW_POOL_SIZE - 1))? (BAW->delPoint + 1): 0;
1761+ // temp = BAW->delPoint;
1762+ //}
1763+
1764+ zm_msg1_agg(ZM_LV_0, "get new tid_baw, index=", i);
1765+ BAW->delPoint = (i < (ZM_BAW_POOL_SIZE -1))? (i + 1): 0;
1766+ next_baw = &BAW->tid_baw[BAW->delPoint];
1767+ if (1 == next_baw->enabled) BAW->disable(dev, next_baw);
1768+
1769+ BAW->enable(dev, tid_baw, start_seq);
1770+ tid_baw->tid_tx = tid_tx;
1771+
1772+ return tid_baw;
1773+}
1774+
1775+u16_t zfBawInsert(zdev_t* dev, zbuf_t* buf, u16_t baw_seq, TID_BAW tid_baw, u8_t baw_retransmit, struct baw_header_r *header_r) {
1776+ //TID_BAW tid_baw;
1777+ //u16_t bufLen;
1778+
1779+ //zmw_get_wlan_dev(dev);
1780+ //zmw_declare_for_critical_section();
1781+
1782+ if(tid_baw->size < (ZM_VTXQ_SIZE - 1)) {
1783+ struct baw_header *baw_header = &tid_baw->frame[tid_baw->head].baw_header;
1784+
1785+ baw_header->headerLen = header_r->headerLen;
1786+ baw_header->micLen = header_r->micLen;
1787+ baw_header->snapLen = header_r->snapLen;
1788+ baw_header->removeLen = header_r->removeLen;
1789+ baw_header->keyIdx = header_r->keyIdx;
1790+ zfwMemoryCopy((u8_t *)baw_header->header, (u8_t *)header_r->header, 58);
1791+ zfwMemoryCopy((u8_t *)baw_header->mic , (u8_t *)header_r->mic , 8);
1792+ zfwMemoryCopy((u8_t *)baw_header->snap , (u8_t *)header_r->snap , 8);
1793+ //wd->zfcbSetBawQ(dev, buf, 1);
1794+ tid_baw->frame[tid_baw->head].buf = buf;
1795+ tid_baw->frame[tid_baw->head].baw_seq = baw_seq;
1796+ tid_baw->frame[tid_baw->head].baw_retransmit = baw_retransmit + 1;
1797+
1798+ //tid_baw->frame[tid_baw->head].data = pBuf->data;
1799+ tid_baw->head++;
1800+ tid_baw->size++;
1801+ }
1802+ else {
1803+ //wd->zfcbSetBawQ(dev, buf, 0);
1804+ zfwBufFree(dev, buf, ZM_SUCCESS);
1805+ return FALSE;
1806+ }
1807+ return TRUE;
1808+}
1809+
1810+struct bufInfo* zfBawPop(zdev_t* dev, u16_t index, TID_BAW tid_baw) {
1811+ //TID_BAW tid_baw;
1812+ //zbuf_t* buf;
1813+ struct bufInfo *buf_info;
1814+ zmw_get_wlan_dev(dev);
1815+
1816+ buf_info = &wd->buf_info;
1817+ buf_info->baw_header = NULL;
1818+
1819+ if (NULL == (buf_info->buf = tid_baw->frame[index].buf))
1820+ return buf_info;
1821+
1822+ buf_info->baw_retransmit = tid_baw->frame[index].baw_retransmit;
1823+ buf_info->baw_header = &tid_baw->frame[index].baw_header;
1824+ buf_info->timestamp = tid_baw->frame[index].timestamp;
1825+ //pBuf->data = pBuf->buffer;
1826+ //wd->zfcbRestoreBufData(dev, buf);
1827+ tid_baw->frame[index].buf = NULL;
1828+
1829+ return buf_info;
1830+}
1831+
1832+void zfBawEnable(zdev_t* dev, TID_BAW tid_baw, u16_t start_seq) {
1833+ //TID_BAW tid_baw;
1834+
1835+ //zmw_get_wlan_dev(dev);
1836+ //zmw_declare_for_critical_section();
1837+
1838+ tid_baw->enabled = TRUE;
1839+ tid_baw->head = tid_baw->tail = tid_baw->size = 0;
1840+ tid_baw->start_seq = start_seq;
1841+}
1842+
1843+void zfBawDisable(zdev_t* dev, TID_BAW tid_baw) {
1844+ //TID_BAW tid_baw;
1845+ u16_t i;
1846+
1847+ //zmw_get_wlan_dev(dev);
1848+ //zmw_declare_for_critical_section();
1849+ for (i=0; i<ZM_VTXQ_SIZE; i++) {
1850+ if (tid_baw->frame[i].buf) {
1851+
1852+ //wd->zfcbSetBawQ(dev, tid_baw->frame[i].buf, 0);
1853+ zfwBufFree(dev, tid_baw->frame[i].buf, ZM_SUCCESS);
1854+ tid_baw->frame[i].buf = NULL;
1855+ }
1856+ }
1857+
1858+ tid_baw->enabled = FALSE;
1859+}
1860+
1861+TID_BAW zfBawGetQ(zdev_t* dev, u16_t baw_seq) {
1862+ TID_BAW tid_baw=NULL;
1863+ u16_t i;
1864+
1865+ zmw_get_wlan_dev(dev);
1866+ //zmw_declare_for_critical_section();
1867+ for (i=0; i<ZM_BAW_POOL_SIZE; i++){
1868+ tid_baw = &BAW->tid_baw[i];
1869+ if (TRUE == tid_baw->enabled)
1870+ {
1871+ zm_msg1_agg(ZM_LV_0, "get an old tid_baw, baw_seq=", baw_seq);
1872+ zm_msg1_agg(ZM_LV_0, "check a tid_baw->start_seq=", tid_baw->start_seq);
1873+ if(baw_seq == tid_baw->start_seq)
1874+ break;
1875+ }
1876+
1877+ }
1878+ if (ZM_BAW_POOL_SIZE == i)
1879+ return NULL;
1880+ return tid_baw;
1881+}
1882+#endif //disable BAW
1883+#endif
1884+
1885+u16_t zfAggTallyReset(zdev_t* dev)
1886+{
1887+ struct aggTally* agg_tal;
1888+
1889+ zmw_get_wlan_dev(dev);
1890+
1891+ //zmw_declare_for_critical_section();
1892+
1893+ agg_tal = &wd->agg_tal;
1894+ agg_tal->got_packets_sum = 0;
1895+ agg_tal->got_bytes_sum = 0;
1896+ agg_tal->sent_bytes_sum = 0;
1897+ agg_tal->sent_packets_sum = 0;
1898+ agg_tal->avg_got_packets = 0;
1899+ agg_tal->avg_got_bytes = 0;
1900+ agg_tal->avg_sent_packets = 0;
1901+ agg_tal->avg_sent_bytes = 0;
1902+ agg_tal->time = 0;
1903+ return 0;
1904+}
1905+
1906+
1907+/************************************************************************/
1908+/* */
1909+/* FUNCTION DESCRIPTION zfAggScanAndClear */
1910+/* If the packets in a queue have waited for too long, clear and */
1911+/* delete this aggregation queue. */
1912+/* */
1913+/* INPUTS */
1914+/* dev : device pointer */
1915+/* time : current time */
1916+/* */
1917+/* OUTPUTS */
1918+/* ZM_SUCCESS */
1919+/* */
1920+/* AUTHOR */
1921+/* Honda Atheros Communications, INC. 2006.12 */
1922+/* */
1923+/************************************************************************/
1924+u16_t zfAggScanAndClear(zdev_t* dev, u32_t time)
1925+{
1926+ u16_t i;
1927+ u16_t head;
1928+ u16_t tail;
1929+ u32_t tick;
1930+ u32_t arrivalTime;
1931+ //u16_t aid, ac;
1932+ TID_TX tid_tx;
1933+
1934+ zmw_get_wlan_dev(dev);
1935+
1936+ zmw_declare_for_critical_section();
1937+
1938+ if(!(wd->state == ZM_WLAN_STATE_ENABLED)) return 0;
1939+ zfAggTxScheduler(dev, 1);
1940+ tick = zm_agg_GetTime();
1941+ for (i=0; i<ZM_AGG_POOL_SIZE; i++)
1942+ {
1943+ if (!wd->aggQPool[i]) return 0;
1944+ if (1 == wd->aggQPool[i]->aggQEnabled)
1945+ {
1946+ tid_tx = wd->aggQPool[i];
1947+ zmw_enter_critical_section(dev);
1948+
1949+ head = tid_tx->aggHead;
1950+ tail = tid_tx->aggTail;
1951+
1952+ arrivalTime = (u32_t)tid_tx->aggvtxq[tid_tx->aggTail].arrivalTime;
1953+
1954+
1955+ if((tick - arrivalTime) <= ZM_AGG_CLEAR_TIME)
1956+ {
1957+
1958+ }
1959+ else if((tid_tx->size = zm_agg_qlen(dev, tid_tx->aggHead, tid_tx->aggTail)) > 0)
1960+ {
1961+
1962+ tid_tx->clearFlag = 1;
1963+
1964+ //zm_msg1_agg(ZM_LV_0, "clear queue tick =", tick);
1965+ //zm_msg1_agg(ZM_LV_0, "clear queue arrival =", arrivalTime);
1966+
1967+
1968+ //zmw_leave_critical_section(dev);
1969+ //zfAggTxScheduler(dev);
1970+ //zmw_enter_critical_section(dev);
1971+
1972+ }
1973+
1974+ if (tid_tx->size == 0)
1975+ {
1976+ /*
1977+ * queue empty
1978+ */
1979+ if (tick - tid_tx->lastArrival > ZM_AGG_DELETE_TIME)
1980+ {
1981+ zm_msg1_agg(ZM_LV_0, "delete queue, idle for n sec. n = ", \
1982+ ZM_AGG_DELETE_TIME/10);
1983+
1984+ zmw_leave_critical_section(dev);
1985+ zfAggTxDeleteQueue(dev, i);
1986+ zmw_enter_critical_section(dev);
1987+ }
1988+ }
1989+
1990+ zmw_leave_critical_section(dev);
1991+ }
1992+ }
1993+
1994+ zfAggRxClear(dev, time);
1995+
1996+#ifdef ZM_AGG_TALLY
1997+ if((wd->tick % 100) == 0) {
1998+ zfAggPrintTally(dev);
1999+ }
2000+#endif
2001+
2002+ return ZM_SUCCESS;
2003+}
2004+
2005+u16_t zfAggPrintTally(zdev_t* dev)
2006+{
2007+ struct aggTally* agg_tal;
2008+
2009+ zmw_get_wlan_dev(dev);
2010+
2011+ //zmw_declare_for_critical_section();
2012+
2013+ agg_tal = &wd->agg_tal;
2014+
2015+ if(agg_tal->got_packets_sum < 10)
2016+ {
2017+ zfAggTallyReset(dev);
2018+ return 0;
2019+ }
2020+
2021+ agg_tal->time++;
2022+ agg_tal->avg_got_packets = (agg_tal->avg_got_packets * (agg_tal->time - 1) +
2023+ agg_tal->got_packets_sum) / agg_tal->time;
2024+ agg_tal->avg_got_bytes = (agg_tal->avg_got_bytes * (agg_tal->time - 1) +
2025+ agg_tal->got_bytes_sum) / agg_tal->time;
2026+ agg_tal->avg_sent_packets = (agg_tal->avg_sent_packets * (agg_tal->time - 1)
2027+ + agg_tal->sent_packets_sum) / agg_tal->time;
2028+ agg_tal->avg_sent_bytes = (agg_tal->avg_sent_bytes * (agg_tal->time - 1) +
2029+ agg_tal->sent_bytes_sum) / agg_tal->time;
2030+ zm_msg1_agg(ZM_LV_0, "got_packets_sum =", agg_tal->got_packets_sum);
2031+ zm_msg1_agg(ZM_LV_0, " got_bytes_sum =", agg_tal->got_bytes_sum);
2032+ zm_msg1_agg(ZM_LV_0, "sent_packets_sum=", agg_tal->sent_packets_sum);
2033+ zm_msg1_agg(ZM_LV_0, " sent_bytes_sum =", agg_tal->sent_bytes_sum);
2034+ agg_tal->got_packets_sum = agg_tal->got_bytes_sum =agg_tal->sent_packets_sum
2035+ = agg_tal->sent_bytes_sum = 0;
2036+ zm_msg1_agg(ZM_LV_0, "avg_got_packets =", agg_tal->avg_got_packets);
2037+ zm_msg1_agg(ZM_LV_0, " avg_got_bytes =", agg_tal->avg_got_bytes);
2038+ zm_msg1_agg(ZM_LV_0, "avg_sent_packets=", agg_tal->avg_sent_packets);
2039+ zm_msg1_agg(ZM_LV_0, " avg_sent_bytes =", agg_tal->avg_sent_bytes);
2040+ if ((wd->commTally.BA_Fail == 0) || (wd->commTally.Hw_Tx_MPDU == 0))
2041+ {
2042+ zm_msg1_agg(ZM_LV_0, "Hardware Tx MPDU=", wd->commTally.Hw_Tx_MPDU);
2043+ zm_msg1_agg(ZM_LV_0, " BA Fail number=", wd->commTally.BA_Fail);
2044+ }
2045+ else
2046+ zm_msg1_agg(ZM_LV_0, "1/(BA fail rate)=", wd->commTally.Hw_Tx_MPDU/wd->commTally.BA_Fail);
2047+
2048+ return 0;
2049+}
2050+
2051+u16_t zfAggRxClear(zdev_t* dev, u32_t time)
2052+{
2053+ u16_t i;
2054+ struct agg_tid_rx *tid_rx;
2055+
2056+ zmw_get_wlan_dev(dev);
2057+
2058+ zmw_declare_for_critical_section();
2059+
2060+ for (i=0; i<ZM_AGG_POOL_SIZE; i++)
2061+ {
2062+ zmw_enter_critical_section(dev);
2063+ tid_rx = wd->tid_rx[i];
2064+ if (tid_rx->baw_head != tid_rx->baw_tail)
2065+ {
2066+ u16_t j = tid_rx->baw_tail;
2067+ while ((j != tid_rx->baw_head) && !tid_rx->frame[j].buf) {
2068+ j = (j + 1) & ZM_AGG_BAW_MASK;
2069+ }
2070+ if ((j != tid_rx->baw_head) && (time - tid_rx->frame[j].arrivalTime) >
2071+ (ZM_AGG_CLEAR_TIME - 5))
2072+ {
2073+ zmw_leave_critical_section(dev);
2074+ zm_msg0_agg(ZM_LV_1, "queue RxFlush by RxClear");
2075+ zfAggRxFlush(dev, 0, tid_rx);
2076+ zmw_enter_critical_section(dev);
2077+ }
2078+ }
2079+ zmw_leave_critical_section(dev);
2080+ }
2081+
2082+ return ZM_SUCCESS;
2083+}
2084+
2085+struct agg_tid_rx* zfAggRxEnabled(zdev_t* dev, zbuf_t* buf)
2086+{
2087+ u16_t dst0, src[3], ac, aid, fragOff;
2088+ u8_t up;
2089+ u16_t offset = 0;
2090+ u16_t seq_no;
2091+ u16_t frameType;
2092+ u16_t frameCtrl;
2093+ u16_t frameSubtype;
2094+ u32_t tcp_seq;
2095+ //struct aggSta *agg_sta;
2096+#if ZM_AGG_FPGA_REORDERING
2097+ struct agg_tid_rx *tid_rx;
2098+#endif
2099+ zmw_get_wlan_dev(dev);
2100+
2101+ //zmw_declare_for_critical_section();
2102+ seq_no = zmw_rx_buf_readh(dev, buf, 22) >> 4;
2103+ //DbgPrint("Rx seq=%d\n", seq_no);
2104+ if (wd->sta.EnableHT == 0)
2105+ {
2106+ return NULL;
2107+ }
2108+
2109+ frameCtrl = zmw_rx_buf_readb(dev, buf, 0);
2110+ frameType = frameCtrl & 0xf;
2111+ frameSubtype = frameCtrl & 0xf0;
2112+
2113+
2114+ if (frameType != ZM_WLAN_DATA_FRAME) //non-Qos Data? (frameSubtype&0x80)
2115+ {
2116+ return NULL;
2117+ }
2118+#ifdef ZM_ENABLE_PERFORMANCE_EVALUATION
2119+ tcp_seq = zmw_rx_buf_readb(dev, buf, 22+36) << 24;
2120+ tcp_seq += zmw_rx_buf_readb(dev, buf, 22+37) << 16;
2121+ tcp_seq += zmw_rx_buf_readb(dev, buf, 22+38) << 8;
2122+ tcp_seq += zmw_rx_buf_readb(dev, buf, 22+39);
2123+#endif
2124+
2125+ ZM_SEQ_DEBUG("In %5d, %12u\n", seq_no, tcp_seq);
2126+ dst0 = zmw_rx_buf_readh(dev, buf, offset+4);
2127+
2128+ src[0] = zmw_rx_buf_readh(dev, buf, offset+10);
2129+ src[1] = zmw_rx_buf_readh(dev, buf, offset+12);
2130+ src[2] = zmw_rx_buf_readh(dev, buf, offset+14);
2131+
2132+#if ZM_AGG_FPGA_DEBUG
2133+ aid = 0;
2134+#else
2135+ aid = zfApFindSta(dev, src);
2136+#endif
2137+
2138+ //agg_sta = &wd->aggSta[aid];
2139+ //zfTxGetIpTosAndFrag(dev, buf, &up, &fragOff);
2140+ //ac = zcUpToAc[up&0x7] & 0x3;
2141+
2142+ /*
2143+ * Filter unicast frame only, aid == 0 is for debug only
2144+ */
2145+ if ((dst0 & 0x1) == 0 && aid == 0)
2146+ {
2147+#if ZM_AGG_FPGA_REORDERING
2148+ tid_rx = zfAggRxGetQueue(dev, buf) ;
2149+ if(!tid_rx)
2150+ return NULL;
2151+ else
2152+ {
2153+ //if (tid_rx->addBaExchangeStatusCode == ZM_AGG_ADDBA_RESPONSE)
2154+ return tid_rx;
2155+ }
2156+#else
2157+ return NULL;
2158+#endif
2159+ }
2160+
2161+ return NULL;
2162+}
2163+
2164+u16_t zfAggRx(zdev_t* dev, zbuf_t* buf, struct zsAdditionInfo *addInfo, struct agg_tid_rx *tid_rx)
2165+{
2166+ u16_t seq_no;
2167+ s16_t index;
2168+ u16_t offset = 0;
2169+ zbuf_t* pbuf;
2170+ u8_t frameSubType;
2171+
2172+ zmw_get_wlan_dev(dev);
2173+
2174+ zmw_declare_for_critical_section();
2175+
2176+ ZM_BUFFER_TRACE(dev, buf)
2177+
2178+ ZM_PERFORMANCE_RX_REORDER(dev);
2179+
2180+ seq_no = zmw_rx_buf_readh(dev, buf, offset+22) >> 4;
2181+
2182+ index = seq_no - tid_rx->seq_start;
2183+ /*
2184+ * for debug
2185+ */
2186+
2187+ /* zm_msg2_agg(ZM_LV_0, "queue seq = ", seq_no);
2188+ * DbgPrint("%s:%s%lxh %s%lxh\n", __FUNCTION__, "queue seq=", seq_no,
2189+ * "; seq_start=", tid_rx->seq_start);
2190+ */
2191+
2192+ //DbgPrint("seq_no=%d, seq_start=%d\n", seq_no, tid_rx->seq_start);
2193+
2194+ /* In some APs, we found that it might transmit NULL data whose sequence number
2195+ is out or order. In order to avoid this problem, we ignore these NULL data.
2196+ */
2197+
2198+ frameSubType = (zmw_rx_buf_readh(dev, buf, 0) & 0xF0) >> 4;
2199+
2200+ /* If this is a NULL data instead of Qos NULL data */
2201+ if ((frameSubType & 0x0C) == 0x04)
2202+ {
2203+ s16_t seq_diff;
2204+
2205+ seq_diff = (seq_no > tid_rx->seq_start) ?
2206+ seq_no - tid_rx->seq_start : tid_rx->seq_start - seq_no;
2207+
2208+ if (seq_diff > ZM_AGG_BAW_SIZE)
2209+ {
2210+ zm_debug_msg0("Free Rx NULL data in zfAggRx");
2211+
2212+ /* Free Rx buffer */
2213+ zfwBufFree(dev, buf, 0);
2214+ return ZM_ERR_OUT_OF_ORDER_NULL_DATA;
2215+ }
2216+ }
2217+
2218+ /*
2219+ * sequence number wrap at 4k
2220+ */
2221+ if (tid_rx->seq_start > seq_no)
2222+ {
2223+ //index += 4096;
2224+
2225+ zmw_enter_critical_section(dev);
2226+ if (tid_rx->seq_start >= 4096) {
2227+ tid_rx->seq_start = 0;
2228+ }
2229+ zmw_leave_critical_section(dev);
2230+
2231+ }
2232+
2233+ if (tid_rx->seq_start == seq_no) {
2234+ zmw_enter_critical_section(dev);
2235+ if (((tid_rx->baw_head - tid_rx->baw_tail) & ZM_AGG_BAW_MASK) > 0) {
2236+ //DbgPrint("head=%d, tail=%d", tid_rx->baw_head, tid_rx->baw_tail);
2237+ tid_rx->baw_tail = (tid_rx->baw_tail + 1) & ZM_AGG_BAW_MASK;
2238+ }
2239+ tid_rx->seq_start = (tid_rx->seq_start + 1) & (4096 - 1);
2240+ zmw_leave_critical_section(dev);
2241+
2242+ ZM_PERFORMANCE_RX_SEQ(dev, buf);
2243+
2244+ if (wd->zfcbRecv80211 != NULL) {
2245+ //seq_no = zmw_rx_buf_readh(dev, buf, offset+22) >> 4;
2246+ //DbgPrint("Recv indicate seq=%d\n", seq_no);
2247+ //DbgPrint("1. seq=%d\n", seq_no);
2248+
2249+ wd->zfcbRecv80211(dev, buf, addInfo);
2250+ }
2251+ else {
2252+ zfiRecv80211(dev, buf, addInfo);
2253+ }
2254+ }
2255+ else if (!zfAggRxEnqueue(dev, buf, tid_rx, addInfo))
2256+ {
2257+ /*
2258+ * duplicated packet
2259+ */
2260+ return 1;
2261+ }
2262+
2263+ while (tid_rx->baw_head != tid_rx->baw_tail) {// && tid_rx->frame[tid_rx->baw_tail].buf)
2264+ u16_t tailIndex;
2265+
2266+ zmw_enter_critical_section(dev);
2267+
2268+ tailIndex = tid_rx->baw_tail;
2269+ pbuf = tid_rx->frame[tailIndex].buf;
2270+ tid_rx->frame[tailIndex].buf = 0;
2271+ if (!pbuf)
2272+ {
2273+ zmw_leave_critical_section(dev);
2274+ break;
2275+ }
2276+
2277+ tid_rx->baw_tail = (tid_rx->baw_tail + 1) & ZM_AGG_BAW_MASK;
2278+ tid_rx->seq_start = (tid_rx->seq_start + 1) & (4096 - 1);
2279+
2280+
2281+ //if(pbuf && tid_rx->baw_size > 0)
2282+ // tid_rx->baw_size--;
2283+
2284+ zmw_leave_critical_section(dev);
2285+
2286+ ZM_PERFORMANCE_RX_SEQ(dev, pbuf);
2287+
2288+ if (wd->zfcbRecv80211 != NULL)
2289+ {
2290+ //seq_no = zmw_rx_buf_readh(dev, pbuf, offset+22) >> 4;
2291+ //DbgPrint("Recv indicate seq=%d\n", seq_no);
2292+ //DbgPrint("1. seq=%d\n", seq_no);
2293+ wd->zfcbRecv80211(dev, pbuf, addInfo);
2294+ }
2295+ else
2296+ {
2297+ //seq_no = zmw_rx_buf_readh(dev, pbuf, offset+22) >> 4;
2298+ //DbgPrint("Recv indicate seq=%d\n", seq_no);
2299+ zfiRecv80211(dev, pbuf, addInfo);
2300+ }
2301+ }
2302+
2303+ return 1;
2304+}
2305+
2306+struct agg_tid_rx *zfAggRxGetQueue(zdev_t* dev, zbuf_t* buf)
2307+{
2308+ u16_t src[3];
2309+ u16_t aid, ac, i;
2310+ u16_t offset = 0;
2311+ struct agg_tid_rx *tid_rx = NULL;
2312+
2313+ zmw_get_wlan_dev(dev);
2314+
2315+ //zmw_declare_for_critical_section();
2316+
2317+ src[0] = zmw_rx_buf_readh(dev, buf, offset+10);
2318+ src[1] = zmw_rx_buf_readh(dev, buf, offset+12);
2319+ src[2] = zmw_rx_buf_readh(dev, buf, offset+14);
2320+ aid = zfApFindSta(dev, src);
2321+
2322+ ac = (zmw_rx_buf_readh(dev, buf, 24) & 0xF);
2323+
2324+ // mark by spin lock debug
2325+ //zmw_enter_critical_section(dev);
2326+
2327+ for (i=0; i<ZM_AGG_POOL_SIZE ; i++)
2328+ {
2329+ if((wd->tid_rx[i]->aid == aid) && (wd->tid_rx[i]->ac == ac))
2330+ {
2331+ tid_rx = wd->tid_rx[i];
2332+ break;
2333+ }
2334+ }
2335+
2336+ // mark by spin lock debug
2337+ //zmw_leave_critical_section(dev);
2338+ return tid_rx;
2339+}
2340+
2341+
2342+u16_t zfAggRxEnqueue(zdev_t* dev, zbuf_t* buf, struct agg_tid_rx *tid_rx, struct zsAdditionInfo *addInfo)
2343+{
2344+ u16_t seq_no, offset = 0;
2345+ u16_t q_index;
2346+ s16_t index;
2347+ u8_t bdropframe = 0;
2348+
2349+ zmw_get_wlan_dev(dev);
2350+
2351+ zmw_declare_for_critical_section();
2352+
2353+ ZM_BUFFER_TRACE(dev, buf)
2354+
2355+ seq_no = zmw_rx_buf_readh(dev, buf, offset+22) >> 4;
2356+ index = seq_no - tid_rx->seq_start;
2357+
2358+ /*
2359+ * sequence number wrap at 4k
2360+ * -1000: check for duplicate past packet
2361+ */
2362+ bdropframe = 0;
2363+ if (tid_rx->seq_start > seq_no) {
2364+ if ((tid_rx->seq_start > 3967) && (seq_no < 128)) {
2365+ index += 4096;
2366+ } else if (tid_rx->seq_start - seq_no > 70) {
2367+ zmw_enter_critical_section(dev);
2368+ tid_rx->sq_behind_count++;
2369+ if (tid_rx->sq_behind_count > 3) {
2370+ tid_rx->sq_behind_count = 0;
2371+ } else {
2372+ bdropframe = 1;
2373+ }
2374+ zmw_leave_critical_section(dev);
2375+ } else {
2376+ bdropframe = 1;
2377+ }
2378+ } else {
2379+ if (seq_no - tid_rx->seq_start > 70) {
2380+ zmw_enter_critical_section(dev);
2381+ tid_rx->sq_exceed_count++;
2382+ if (tid_rx->sq_exceed_count > 3) {
2383+ tid_rx->sq_exceed_count = 0;
2384+ } else {
2385+ bdropframe = 1;
2386+ }
2387+ zmw_leave_critical_section(dev);
2388+ }
2389+ }
2390+
2391+ if (bdropframe == 1) {
2392+ /*if (wd->zfcbRecv80211 != NULL) {
2393+ wd->zfcbRecv80211(dev, buf, addInfo);
2394+ }
2395+ else {
2396+ zfiRecv80211(dev, buf, addInfo);
2397+ }*/
2398+
2399+ ZM_PERFORMANCE_FREE(dev, buf);
2400+
2401+ zfwBufFree(dev, buf, 0);
2402+ /*zfAggRxFlush(dev, seq_no, tid_rx);
2403+ tid_rx->seq_start = seq_no;
2404+ index = seq_no - tid_rx->seq_start;
2405+ */
2406+
2407+ //DbgPrint("Free an old packet, seq_start=%d, seq_no=%d\n", tid_rx->seq_start, seq_no);
2408+
2409+ /*
2410+ * duplicate past packet
2411+ * happens only in simulated aggregation environment
2412+ */
2413+ return 0;
2414+ } else {
2415+ zmw_enter_critical_section(dev);
2416+ if (tid_rx->sq_exceed_count > 0){
2417+ tid_rx->sq_exceed_count--;
2418+ }
2419+
2420+ if (tid_rx->sq_behind_count > 0) {
2421+ tid_rx->sq_behind_count--;
2422+ }
2423+ zmw_leave_critical_section(dev);
2424+ }
2425+
2426+ if (index < 0) {
2427+ zfAggRxFlush(dev, seq_no, tid_rx);
2428+ tid_rx->seq_start = seq_no;
2429+ index = 0;
2430+ }
2431+
2432+ //if (index >= (ZM_AGG_BAW_SIZE - 1))
2433+ if (index >= (ZM_AGG_BAW_MASK))
2434+ {
2435+ /*
2436+ * queue full
2437+ */
2438+ //DbgPrint("index >= 64, seq_start=%d, seq_no=%d\n", tid_rx->seq_start, seq_no);
2439+ zfAggRxFlush(dev, seq_no, tid_rx);
2440+ //tid_rx->seq_start = seq_no;
2441+ index = seq_no - tid_rx->seq_start;
2442+ if ((tid_rx->seq_start > seq_no) && (tid_rx->seq_start > 1000) && (tid_rx->seq_start - 1000) > seq_no)
2443+ {
2444+ //index = seq_no - tid_rx->seq_start;
2445+ index += 4096;
2446+ }
2447+ //index = seq_no - tid_rx->seq_start;
2448+ while (index >= (ZM_AGG_BAW_MASK)) {
2449+ //DbgPrint("index >= 64, seq_start=%d, seq_no=%d\n", tid_rx->seq_start, seq_no);
2450+ tid_rx->seq_start = (tid_rx->seq_start + ZM_AGG_BAW_MASK) & (4096 - 1);
2451+ index = seq_no - tid_rx->seq_start;
2452+ if ((tid_rx->seq_start > seq_no) && (tid_rx->seq_start > 1000) && (tid_rx->seq_start - 1000) > seq_no)
2453+ {
2454+ index += 4096;
2455+ }
2456+ }
2457+ }
2458+
2459+
2460+ q_index = (tid_rx->baw_tail + index) & ZM_AGG_BAW_MASK;
2461+ if (tid_rx->frame[q_index].buf && (((tid_rx->baw_head - tid_rx->baw_tail) & ZM_AGG_BAW_MASK) >
2462+ (((q_index) - tid_rx->baw_tail) & ZM_AGG_BAW_MASK)))
2463+ {
2464+
2465+ ZM_PERFORMANCE_DUP(dev, tid_rx->frame[q_index].buf, buf);
2466+ zfwBufFree(dev, buf, 0);
2467+ //DbgPrint("Free a duplicate packet, seq_start=%d, seq_no=%d\n", tid_rx->seq_start, seq_no);
2468+ //DbgPrint("head=%d, tail=%d", tid_rx->baw_head, tid_rx->baw_tail);
2469+ /*
2470+ * duplicate packet
2471+ */
2472+ return 0;
2473+ }
2474+
2475+ zmw_enter_critical_section(dev);
2476+ if(tid_rx->frame[q_index].buf) {
2477+ zfwBufFree(dev, tid_rx->frame[q_index].buf, 0);
2478+ tid_rx->frame[q_index].buf = 0;
2479+ }
2480+
2481+ tid_rx->frame[q_index].buf = buf;
2482+ tid_rx->frame[q_index].arrivalTime = zm_agg_GetTime();
2483+ zfwMemoryCopy((void*)&tid_rx->frame[q_index].addInfo, (void*)addInfo, sizeof(struct zsAdditionInfo));
2484+
2485+ /*
2486+ * for debug simulated aggregation only,
2487+ * should be done in rx of ADDBA Request
2488+ */
2489+ //tid_rx->addInfo = addInfo;
2490+
2491+
2492+ if (((tid_rx->baw_head - tid_rx->baw_tail) & ZM_AGG_BAW_MASK) <= index)
2493+ {
2494+ //tid_rx->baw_size = index + 1;
2495+ if (((tid_rx->baw_head - tid_rx->baw_tail) & ZM_AGG_BAW_MASK) <=
2496+ //((q_index + 1) & ZM_AGG_BAW_MASK))
2497+ (((q_index) - tid_rx->baw_tail) & ZM_AGG_BAW_MASK))//tid_rx->baw_size )
2498+ tid_rx->baw_head = (q_index + 1) & ZM_AGG_BAW_MASK;
2499+ }
2500+ zmw_leave_critical_section(dev);
2501+
2502+ /*
2503+ * success
2504+ */
2505+ //DbgPrint("head=%d, tail=%d, start=%d", tid_rx->baw_head, tid_rx->baw_tail, tid_rx->seq_start);
2506+ return 1;
2507+}
2508+
2509+u16_t zfAggRxFlush(zdev_t* dev, u16_t seq_no, struct agg_tid_rx *tid_rx)
2510+{
2511+ zbuf_t* pbuf;
2512+ u16_t seq;
2513+ struct zsAdditionInfo addInfo;
2514+ zmw_get_wlan_dev(dev);
2515+ zmw_declare_for_critical_section();
2516+
2517+ ZM_PERFORMANCE_RX_FLUSH(dev);
2518+
2519+ while (1)
2520+ {
2521+ zmw_enter_critical_section(dev);
2522+ if (tid_rx->baw_tail == tid_rx->baw_head) {
2523+ zmw_leave_critical_section(dev);
2524+ break;
2525+ }
2526+
2527+ pbuf = tid_rx->frame[tid_rx->baw_tail].buf;
2528+ zfwMemoryCopy((void*)&addInfo, (void*)&tid_rx->frame[tid_rx->baw_tail].addInfo, sizeof(struct zsAdditionInfo));
2529+ tid_rx->frame[tid_rx->baw_tail].buf = 0;
2530+ //if(pbuf && tid_rx->baw_size > 0) tid_rx->baw_size--;
2531+ tid_rx->baw_tail = (tid_rx->baw_tail + 1) & ZM_AGG_BAW_MASK;
2532+ tid_rx->seq_start = (tid_rx->seq_start + 1) & (4096 - 1);
2533+ zmw_leave_critical_section(dev);
2534+
2535+ if (pbuf)
2536+ {
2537+
2538+ ZM_PERFORMANCE_RX_SEQ(dev, pbuf);
2539+
2540+ if (wd->zfcbRecv80211 != NULL)
2541+ {
2542+ seq = zmw_rx_buf_readh(dev, pbuf, 22) >> 4;
2543+ //DbgPrint("Recv indicate seq=%d\n", seq);
2544+ //DbgPrint("2. seq=%d\n", seq);
2545+ wd->zfcbRecv80211(dev, pbuf, &addInfo);
2546+ }
2547+ else
2548+ {
2549+ seq = zmw_rx_buf_readh(dev, pbuf, 22) >> 4;
2550+ //DbgPrint("Recv indicate seq=%d\n", seq);
2551+ zfiRecv80211(dev, pbuf, &addInfo);
2552+ }
2553+ }
2554+ }
2555+
2556+ zmw_enter_critical_section(dev);
2557+ tid_rx->baw_head = tid_rx->baw_tail = 0;
2558+ zmw_leave_critical_section(dev);
2559+ return 1;
2560+}
2561+
2562+
2563+
2564+/************************************************************************/
2565+/* */
2566+/* FUNCTION DESCRIPTION zfAggRxFreeBuf */
2567+/* Frees all queued packets in buffer when the driver is down. */
2568+/* The zfFreeResource() will check if the buffer is all freed. */
2569+/* */
2570+/* INPUTS */
2571+/* dev : device pointer */
2572+/* */
2573+/* OUTPUTS */
2574+/* ZM_SUCCESS */
2575+/* */
2576+/* AUTHOR */
2577+/* Honda Atheros Communications, INC. 2006.12 */
2578+/* */
2579+/************************************************************************/
2580+u16_t zfAggRxFreeBuf(zdev_t* dev, u16_t destroy)
2581+{
2582+ u16_t i;
2583+ zbuf_t* buf;
2584+ struct agg_tid_rx *tid_rx;
2585+
2586+ TID_TX tid_tx;
2587+ //struct bufInfo *buf_info;
2588+
2589+ zmw_get_wlan_dev(dev);
2590+ zmw_declare_for_critical_section();
2591+
2592+ for (i=0; i<ZM_AGG_POOL_SIZE; i++)
2593+ {
2594+ u16_t j;
2595+
2596+ tid_rx = wd->tid_rx[i];
2597+
2598+ for(j=0; j <= ZM_AGG_BAW_SIZE; j++)
2599+ {
2600+ zmw_enter_critical_section(dev);
2601+ buf = tid_rx->frame[j].buf;
2602+ tid_rx->frame[j].buf = 0;
2603+ zmw_leave_critical_section(dev);
2604+
2605+ if (buf)
2606+ {
2607+ zfwBufFree(dev, buf, 0);
2608+ }
2609+ }
2610+
2611+ #if 0
2612+ if ( tid_rx->baw_head != tid_rx->baw_tail )
2613+ {
2614+ while (tid_rx->baw_head != tid_rx->baw_tail)
2615+ {
2616+ buf = tid_rx->frame[tid_rx->baw_tail].buf;
2617+ tid_rx->frame[tid_rx->baw_tail].buf = 0;
2618+ if (buf)
2619+ {
2620+ zfwBufFree(dev, buf, 0);
2621+
2622+ zmw_enter_critical_section(dev);
2623+ tid_rx->frame[tid_rx->baw_tail].buf = 0;
2624+ zmw_leave_critical_section(dev);
2625+ }
2626+ zmw_enter_critical_section(dev);
2627+ //if (tid_rx->baw_size > 0)tid_rx->baw_size--;
2628+ tid_rx->baw_tail = (tid_rx->baw_tail + 1) & ZM_AGG_BAW_MASK;
2629+ tid_rx->seq_start++;
2630+ zmw_leave_critical_section(dev);
2631+ }
2632+ }
2633+ #endif
2634+
2635+ zmw_enter_critical_section(dev);
2636+ tid_rx->seq_start = 0;
2637+ tid_rx->baw_head = tid_rx->baw_tail = 0;
2638+ tid_rx->aid = ZM_MAX_STA_SUPPORT;
2639+ zmw_leave_critical_section(dev);
2640+
2641+ #ifdef ZM_ENABLE_AGGREGATION
2642+ #ifndef ZM_ENABLE_FW_BA_RETRANSMISSION //disable BAW
2643+ if (tid_baw->enabled) {
2644+ zm_msg1_agg(ZM_LV_0, "Device down, clear BAW queue:", i);
2645+ BAW->disable(dev, tid_baw);
2646+ }
2647+ #endif
2648+ #endif
2649+ if (1 == wd->aggQPool[i]->aggQEnabled) {
2650+ tid_tx = wd->aggQPool[i];
2651+ buf = zfAggTxGetVtxq(dev, tid_tx);
2652+ while (buf) {
2653+ zfwBufFree(dev, buf, 0);
2654+ buf = zfAggTxGetVtxq(dev, tid_tx);
2655+ }
2656+ }
2657+
2658+ if(destroy) {
2659+ zfwMemFree(dev, wd->aggQPool[i], sizeof(struct aggQueue));
2660+ zfwMemFree(dev, wd->tid_rx[i], sizeof(struct agg_tid_rx));
2661+ }
2662+ }
2663+ #ifdef ZM_ENABLE_AGGREGATION
2664+ #ifndef ZM_ENABLE_FW_BA_RETRANSMISSION //disable BAW
2665+ if(destroy) zfwMemFree(dev, BAW, sizeof(struct baw_enabler));
2666+ #endif
2667+ #endif
2668+ return ZM_SUCCESS;
2669+}
2670+
2671+
2672+void zfAggRecvBAR(zdev_t* dev, zbuf_t *buf) {
2673+ u16_t start_seq, len;
2674+ u8_t i, bitmap[8];
2675+ len = zfwBufGetSize(dev, buf);
2676+ start_seq = zmw_rx_buf_readh(dev, buf, len-2);
2677+ DbgPrint("Received a BAR Control frame, start_seq=%d", start_seq>>4);
2678+ /* todo: set the bitmap by reordering buffer! */
2679+ for (i=0; i<8; i++) bitmap[i]=0;
2680+ zfSendBA(dev, start_seq, bitmap);
2681+}
2682+
2683+#ifdef ZM_ENABLE_AGGREGATION
2684+#ifndef ZM_ENABLE_FW_BA_RETRANSMISSION //disable BAW
2685+void zfAggTxRetransmit(zdev_t* dev, struct bufInfo *buf_info, struct aggControl *aggControl, TID_TX tid_tx) {
2686+ u16_t removeLen;
2687+ u16_t err;
2688+
2689+ zmw_get_wlan_dev(dev);
2690+ if (aggControl && (ZM_AGG_FIRST_MPDU == aggControl->ampduIndication) ) {
2691+ tid_tx->bar_ssn = buf_info->baw_header->header[15];
2692+ aggControl->tid_baw->start_seq = tid_tx->bar_ssn >> 4;
2693+ zm_msg1_agg(ZM_LV_0, "start seq=", tid_tx->bar_ssn >> 4);
2694+ }
2695+ buf_info->baw_header->header[4] |= (1 << 11);
2696+ if (aggControl && aggControl->aggEnabled) {
2697+ //if (wd->enableAggregation==0 && !(buf_info->baw_header->header[6]&0x1))
2698+ //{
2699+ //if (((buf_info->baw_header->header[2] & 0x3) == 2))
2700+ //{
2701+ /* Enable aggregation */
2702+ buf_info->baw_header->header[1] |= 0x20;
2703+ if (ZM_AGG_LAST_MPDU == aggControl->ampduIndication) {
2704+ buf_info->baw_header->header[1] |= 0x4000;
2705+ }
2706+ else {
2707+ buf_info->baw_header->header[1] &= ~0x4000;
2708+ //zm_debug_msg0("ZM_AGG_LAST_MPDU");
2709+ }
2710+ //}
2711+ //else {
2712+ // zm_debug_msg1("no aggr, header[2]&0x3 = ",buf_info->baw_header->header[2] & 0x3)
2713+ // aggControl->aggEnabled = 0;
2714+ //}
2715+ //}
2716+ //else {
2717+ // zm_debug_msg1("no aggr, wd->enableAggregation = ", wd->enableAggregation);
2718+ // zm_debug_msg1("no aggr, !header[6]&0x1 = ",!(buf_info->baw_header->header[6]&0x1));
2719+ // aggControl->aggEnabled = 0;
2720+ //}
2721+ }
2722+
2723+ /*if (aggControl->tid_baw) {
2724+ struct baw_header_r header_r;
2725+
2726+ header_r.header = buf_info->baw_header->header;
2727+ header_r.mic = buf_info->baw_header->mic;
2728+ header_r.snap = buf_info->baw_header->snap;
2729+ header_r.headerLen = buf_info->baw_header->headerLen;
2730+ header_r.micLen = buf_info->baw_header->micLen;
2731+ header_r.snapLen = buf_info->baw_header->snapLen;
2732+ header_r.removeLen = buf_info->baw_header->removeLen;
2733+ header_r.keyIdx = buf_info->baw_header->keyIdx;
2734+
2735+ BAW->insert(dev, buf_info->buf, tid_tx->bar_ssn >> 4, aggControl->tid_baw, buf_info->baw_retransmit, &header_r);
2736+ }*/
2737+
2738+ if ((err = zfHpSend(dev,
2739+ buf_info->baw_header->header,
2740+ buf_info->baw_header->headerLen,
2741+ buf_info->baw_header->snap,
2742+ buf_info->baw_header->snapLen,
2743+ buf_info->baw_header->mic,
2744+ buf_info->baw_header->micLen,
2745+ buf_info->buf,
2746+ buf_info->baw_header->removeLen,
2747+ ZM_EXTERNAL_ALLOC_BUF,
2748+ (u8_t)tid_tx->ac,
2749+ buf_info->baw_header->keyIdx)) != ZM_SUCCESS)
2750+ {
2751+ goto zlError;
2752+ }
2753+
2754+ return;
2755+
2756+zlError:
2757+ zfwBufFree(dev, buf_info->buf, 0);
2758+ return;
2759+
2760+}
2761+#endif //disable BAW
2762+#endif
2763+/************************************************************************/
2764+/* */
2765+/* FUNCTION DESCRIPTION zfAggTxSendEth */
2766+/* Called to transmit Ethernet frame from upper elayer. */
2767+/* */
2768+/* INPUTS */
2769+/* dev : device pointer */
2770+/* buf : buffer pointer */
2771+/* port : WLAN port, 0=>standard, 0x10-0x17=>VAP, 0x20-0x25=>WDS */
2772+/* */
2773+/* OUTPUTS */
2774+/* error code */
2775+/* */
2776+/* AUTHOR */
2777+/* Stephen, Honda Atheros Communications, Inc. 2006.12 */
2778+/* */
2779+/************************************************************************/
2780+u16_t zfAggTxSendEth(zdev_t* dev, zbuf_t* buf, u16_t port, u16_t bufType, u8_t flag, struct aggControl *aggControl, TID_TX tid_tx)
2781+{
2782+ u16_t err;
2783+ //u16_t addrTblSize;
2784+ //struct zsAddrTbl addrTbl;
2785+ u16_t removeLen;
2786+ u16_t header[(8+30+2+18)/2]; /* ctr+(4+a1+a2+a3+2+a4)+qos+iv */
2787+ u16_t headerLen;
2788+ u16_t mic[8/2];
2789+ u16_t micLen;
2790+ u16_t snap[8/2];
2791+ u16_t snapLen;
2792+ u16_t fragLen;
2793+ u16_t frameLen;
2794+ u16_t fragNum;
2795+ struct zsFrag frag;
2796+ u16_t i, id;
2797+ u16_t da[3];
2798+ u16_t sa[3];
2799+ u8_t up;
2800+ u8_t qosType, keyIdx = 0;
2801+ u16_t fragOff;
2802+
2803+ zmw_get_wlan_dev(dev);
2804+
2805+ zmw_declare_for_critical_section();
2806+
2807+ zm_msg1_tx(ZM_LV_2, "zfTxSendEth(), port=", port);
2808+
2809+ /* Get IP TOS for QoS AC and IP frag offset */
2810+ zfTxGetIpTosAndFrag(dev, buf, &up, &fragOff);
2811+
2812+#ifdef ZM_ENABLE_NATIVE_WIFI
2813+ if ( wd->wlanMode == ZM_MODE_INFRASTRUCTURE )
2814+ {
2815+ /* DA */
2816+ da[0] = zmw_tx_buf_readh(dev, buf, 16);
2817+ da[1] = zmw_tx_buf_readh(dev, buf, 18);
2818+ da[2] = zmw_tx_buf_readh(dev, buf, 20);
2819+ /* SA */
2820+ sa[0] = zmw_tx_buf_readh(dev, buf, 10);
2821+ sa[1] = zmw_tx_buf_readh(dev, buf, 12);
2822+ sa[2] = zmw_tx_buf_readh(dev, buf, 14);
2823+ }
2824+ else if ( wd->wlanMode == ZM_MODE_IBSS )
2825+ {
2826+ /* DA */
2827+ da[0] = zmw_tx_buf_readh(dev, buf, 4);
2828+ da[1] = zmw_tx_buf_readh(dev, buf, 6);
2829+ da[2] = zmw_tx_buf_readh(dev, buf, 8);
2830+ /* SA */
2831+ sa[0] = zmw_tx_buf_readh(dev, buf, 10);
2832+ sa[1] = zmw_tx_buf_readh(dev, buf, 12);
2833+ sa[2] = zmw_tx_buf_readh(dev, buf, 14);
2834+ }
2835+ else if ( wd->wlanMode == ZM_MODE_AP )
2836+ {
2837+ /* DA */
2838+ da[0] = zmw_tx_buf_readh(dev, buf, 4);
2839+ da[1] = zmw_tx_buf_readh(dev, buf, 6);
2840+ da[2] = zmw_tx_buf_readh(dev, buf, 8);
2841+ /* SA */
2842+ sa[0] = zmw_tx_buf_readh(dev, buf, 16);
2843+ sa[1] = zmw_tx_buf_readh(dev, buf, 18);
2844+ sa[2] = zmw_tx_buf_readh(dev, buf, 20);
2845+ }
2846+ else
2847+ {
2848+ //
2849+ }
2850+#else
2851+ /* DA */
2852+ da[0] = zmw_tx_buf_readh(dev, buf, 0);
2853+ da[1] = zmw_tx_buf_readh(dev, buf, 2);
2854+ da[2] = zmw_tx_buf_readh(dev, buf, 4);
2855+ /* SA */
2856+ sa[0] = zmw_tx_buf_readh(dev, buf, 6);
2857+ sa[1] = zmw_tx_buf_readh(dev, buf, 8);
2858+ sa[2] = zmw_tx_buf_readh(dev, buf, 10);
2859+#endif
2860+ //Decide Key Index in ATOM, No meaning in OTUS--CWYang(m)
2861+ if (wd->wlanMode == ZM_MODE_AP)
2862+ {
2863+ keyIdx = wd->ap.bcHalKeyIdx[port];
2864+ id = zfApFindSta(dev, da);
2865+ if (id != 0xffff)
2866+ {
2867+ switch (wd->ap.staTable[id].encryMode)
2868+ {
2869+ case ZM_AES:
2870+ case ZM_TKIP:
2871+#ifdef ZM_ENABLE_CENC
2872+ case ZM_CENC:
2873+#endif //ZM_ENABLE_CENC
2874+ keyIdx = wd->ap.staTable[id].keyIdx;
2875+ break;
2876+ }
2877+ }
2878+ }
2879+ else
2880+ {
2881+ switch (wd->sta.encryMode)
2882+ {
2883+ case ZM_WEP64:
2884+ case ZM_WEP128:
2885+ case ZM_WEP256:
2886+ keyIdx = wd->sta.keyId;
2887+ break;
2888+ case ZM_AES:
2889+ case ZM_TKIP:
2890+ if ((da[0]& 0x1))
2891+ keyIdx = 5;
2892+ else
2893+ keyIdx = 4;
2894+ break;
2895+#ifdef ZM_ENABLE_CENC
2896+ case ZM_CENC:
2897+ keyIdx = wd->sta.cencKeyId;
2898+ break;
2899+#endif //ZM_ENABLE_CENC
2900+ }
2901+ }
2902+
2903+ /* Create SNAP */
2904+ removeLen = zfTxGenWlanSnap(dev, buf, snap, &snapLen);
2905+ //zm_msg1_tx(ZM_LV_0, "fragOff=", fragOff);
2906+
2907+ fragLen = wd->fragThreshold;
2908+ frameLen = zfwBufGetSize(dev, buf);
2909+ frameLen -= removeLen;
2910+
2911+#if 0
2912+ /* Create MIC */
2913+ if ( (wd->wlanMode == ZM_MODE_INFRASTRUCTURE)&&
2914+ (wd->sta.encryMode == ZM_TKIP) )
2915+ {
2916+ if ( frameLen > fragLen )
2917+ {
2918+ micLen = zfTxGenWlanTail(dev, buf, snap, snapLen, mic);
2919+ }
2920+ else
2921+ {
2922+ /* append MIC by HMAC */
2923+ micLen = 8;
2924+ }
2925+ }
2926+ else
2927+ {
2928+ micLen = 0;
2929+ }
2930+#else
2931+ if ( frameLen > fragLen )
2932+ {
2933+ micLen = zfTxGenWlanTail(dev, buf, snap, snapLen, mic);
2934+ }
2935+ else
2936+ {
2937+ /* append MIC by HMAC */
2938+ micLen = 0;
2939+ }
2940+#endif
2941+
2942+ /* Access Category */
2943+ if (wd->wlanMode == ZM_MODE_AP)
2944+ {
2945+ zfApGetStaQosType(dev, da, &qosType);
2946+ if (qosType == 0)
2947+ {
2948+ up = 0;
2949+ }
2950+ }
2951+ else if (wd->wlanMode == ZM_MODE_INFRASTRUCTURE)
2952+ {
2953+ if (wd->sta.wmeConnected == 0)
2954+ {
2955+ up = 0;
2956+ }
2957+ }
2958+ else
2959+ {
2960+ /* TODO : STA QoS control field */
2961+ up = 0;
2962+ }
2963+
2964+ /* Assign sequence number */
2965+ zmw_enter_critical_section(dev);
2966+ frag.seq[0] = ((wd->seq[zcUpToAc[up&0x7]]++) << 4);
2967+ if (aggControl && (ZM_AGG_FIRST_MPDU == aggControl->ampduIndication) ) {
2968+ tid_tx->bar_ssn = frag.seq[0];
2969+
2970+ zm_msg1_agg(ZM_LV_0, "start seq=", tid_tx->bar_ssn >> 4);
2971+ }
2972+ //tid_tx->baw_buf[tid_tx->baw_head-1].baw_seq=frag.seq[0];
2973+ zmw_leave_critical_section(dev);
2974+
2975+
2976+ frag.buf[0] = buf;
2977+ frag.bufType[0] = bufType;
2978+ frag.flag[0] = flag;
2979+ fragNum = 1;
2980+
2981+ for (i=0; i<fragNum; i++)
2982+ {
2983+ /* Create WLAN header(Control Setting + 802.11 header + IV) */
2984+ if (up !=0 ) zm_debug_msg1("up not 0, up=",up);
2985+ headerLen = zfTxGenWlanHeader(dev, frag.buf[i], header, frag.seq[i],
2986+ frag.flag[i], snapLen+micLen, removeLen,
2987+ port, da, sa, up, &micLen, snap, snapLen,
2988+ aggControl);
2989+
2990+ /* Get buffer DMA address */
2991+ //if ((addrTblSize = zfwBufMapDma(dev, frag.buf[i], &addrTbl)) == 0)
2992+ //if ((addrTblSize = zfwMapTxDma(dev, frag.buf[i], &addrTbl)) == 0)
2993+ //{
2994+ // err = ZM_ERR_BUFFER_DMA_ADDR;
2995+ // goto zlError;
2996+ //}
2997+
2998+ /* Flush buffer on cache */
2999+ //zfwBufFlush(dev, frag.buf[i]);
3000+
3001+#if 0
3002+ zm_msg1_tx(ZM_LV_0, "headerLen=", headerLen);
3003+ zm_msg1_tx(ZM_LV_0, "snapLen=", snapLen);
3004+ zm_msg1_tx(ZM_LV_0, "micLen=", micLen);
3005+ zm_msg1_tx(ZM_LV_0, "removeLen=", removeLen);
3006+ zm_msg1_tx(ZM_LV_0, "addrTblSize=", addrTblSize);
3007+ zm_msg1_tx(ZM_LV_0, "frag.bufType[0]=", frag.bufType[0]);
3008+#endif
3009+
3010+ fragLen = zfwBufGetSize(dev, frag.buf[i]);
3011+ if ((da[0]&0x1) == 0)
3012+ {
3013+ wd->commTally.txUnicastFrm++;
3014+ wd->commTally.txUnicastOctets += (fragLen+snapLen);
3015+ }
3016+ else if ((da[0]& 0x1))
3017+ {
3018+ wd->commTally.txBroadcastFrm++;
3019+ wd->commTally.txBroadcastOctets += (fragLen+snapLen);
3020+ }
3021+ else
3022+ {
3023+ wd->commTally.txMulticastFrm++;
3024+ wd->commTally.txMulticastOctets += (fragLen+snapLen);
3025+ }
3026+ wd->ledStruct.txTraffic++;
3027+
3028+#if 0 //Who care this?
3029+ if ( (i)&&(i == (fragNum-1)) )
3030+ {
3031+ wd->trafTally.txDataByteCount -= micLen;
3032+ }
3033+#endif
3034+
3035+ /*if (aggControl->tid_baw && aggControl->aggEnabled) {
3036+ struct baw_header_r header_r;
3037+
3038+ header_r.header = header;
3039+ header_r.mic = mic;
3040+ header_r.snap = snap;
3041+ header_r.headerLen = headerLen;
3042+ header_r.micLen = micLen;
3043+ header_r.snapLen = snapLen;
3044+ header_r.removeLen = removeLen;
3045+ header_r.keyIdx = keyIdx;
3046+
3047+ BAW->insert(dev, buf, tid_tx->bar_ssn >> 4, aggControl->tid_baw, 0, &header_r);
3048+ }*/
3049+
3050+ if ((err = zfHpSend(dev, header, headerLen, snap, snapLen,
3051+ mic, micLen, frag.buf[i], removeLen,
3052+ frag.bufType[i], zcUpToAc[up&0x7], keyIdx)) != ZM_SUCCESS)
3053+ {
3054+ goto zlError;
3055+ }
3056+
3057+
3058+ continue;
3059+
3060+zlError:
3061+ if (frag.bufType[i] == ZM_EXTERNAL_ALLOC_BUF)
3062+ {
3063+ zfwBufFree(dev, frag.buf[i], err);
3064+ }
3065+ else if (frag.bufType[i] == ZM_INTERNAL_ALLOC_BUF)
3066+ {
3067+ zfwBufFree(dev, frag.buf[i], 0);
3068+ }
3069+ else
3070+ {
3071+ zm_assert(0);
3072+ }
3073+ } /* for (i=0; i<fragNum; i++) */
3074+
3075+ return ZM_SUCCESS;
3076+}
3077+
3078+/*
3079+ * zfAggSendADDBA() refers zfSendMmFrame() in cmm.c
3080+ */
3081+u16_t zfAggSendAddbaRequest(zdev_t* dev, u16_t *dst, u16_t ac, u16_t up)
3082+{
3083+ zbuf_t* buf;
3084+ //u16_t addrTblSize;
3085+ //struct zsAddrTbl addrTbl;
3086+ //u16_t err;
3087+ u16_t offset = 0;
3088+ u16_t hlen = 32;
3089+ u16_t header[(24+25+1)/2];
3090+ u16_t vap = 0;
3091+ u16_t i;
3092+ u8_t encrypt = 0;
3093+
3094+ //zmw_get_wlan_dev(dev);
3095+
3096+ //zmw_declare_for_critical_section();
3097+
3098+
3099+ /*
3100+ * TBD : Maximum size of managment frame
3101+ */
3102+ if ((buf = zfwBufAllocate(dev, 1024)) == NULL)
3103+ {
3104+ zm_msg0_mm(ZM_LV_0, "Alloc mm buf Fail!");
3105+ return ZM_SUCCESS;
3106+ }
3107+
3108+ /*
3109+ * Reserve room for wlan header
3110+ */
3111+ offset = hlen;
3112+
3113+ /*
3114+ * add addba frame body
3115+ */
3116+ offset = zfAggSetAddbaFrameBody(dev, buf, offset, ac, up);
3117+
3118+
3119+ zfwBufSetSize(dev, buf, offset);
3120+
3121+ /*
3122+ * Copy wlan header
3123+ */
3124+ zfAggGenAddbaHeader(dev, dst, header, offset-hlen, buf, vap, encrypt);
3125+ for (i=0; i<(hlen>>1); i++)
3126+ {
3127+ zmw_tx_buf_writeh(dev, buf, i*2, header[i]);
3128+ }
3129+
3130+ /* Get buffer DMA address */
3131+ //if ((addrTblSize = zfwBufMapDma(dev, buf, &addrTbl)) == 0)
3132+ //if ((addrTblSize = zfwMapTxDma(dev, buf, &addrTbl)) == 0)
3133+ //{
3134+ // goto zlError;
3135+ //}
3136+
3137+ //zm_msg2_mm(ZM_LV_2, "offset=", offset);
3138+ //zm_msg2_mm(ZM_LV_2, "hlen=", hlen);
3139+ //zm_msg2_mm(ZM_LV_2, "addrTblSize=", addrTblSize);
3140+ //zm_msg2_mm(ZM_LV_2, "addrTbl.len[0]=", addrTbl.len[0]);
3141+ //zm_msg2_mm(ZM_LV_2, "addrTbl.physAddrl[0]=", addrTbl.physAddrl[0]);
3142+ //zm_msg2_mm(ZM_LV_2, "buf->data=", buf->data);
3143+
3144+ #if 0
3145+ if ((err = zfHpSend(dev, NULL, 0, NULL, 0, NULL, 0, buf, 0,
3146+ ZM_INTERNAL_ALLOC_BUF, 0, 0xff)) != ZM_SUCCESS)
3147+ {
3148+ goto zlError;
3149+ }
3150+ #else
3151+ zfPutVmmq(dev, buf);
3152+ zfPushVtxq(dev);
3153+ #endif
3154+
3155+ return ZM_SUCCESS;
3156+
3157+}
3158+
3159+u16_t zfAggSetAddbaFrameBody(zdev_t* dev, zbuf_t* buf, u16_t offset, u16_t ac, u16_t up)
3160+{
3161+ u16_t ba_parameter, start_seq;
3162+
3163+ zmw_get_wlan_dev(dev);
3164+
3165+ //zmw_declare_for_critical_section();
3166+ /*
3167+ * ADDBA Request frame body
3168+ */
3169+
3170+ /*
3171+ * Category
3172+ */
3173+ zmw_tx_buf_writeb(dev, buf, offset++, 3);
3174+ /*
3175+ * Action details = 0
3176+ */
3177+ zmw_tx_buf_writeb(dev, buf, offset++, ZM_WLAN_ADDBA_REQUEST_FRAME);
3178+ /*
3179+ * Dialog Token = nonzero
3180+ * TBD: define how to get dialog token?
3181+ */
3182+ zmw_tx_buf_writeb(dev, buf, offset++, 2);
3183+ /*
3184+ * Block Ack parameter set
3185+ * BA policy = 1 for immediate BA, 0 for delayed BA
3186+ * TID(4bits) & buffer size(4bits) (TID=up & buffer size=0x80)
3187+ * TBD: how to get buffer size?
3188