• 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.h                                                    */
18/*                                                                          */
19/*  Abstract                                                                */
20/*      This module contains A-MPDU aggregation relatived functions.        */
21/*                                                                          */
22/*  NOTES                                                                   */
23/*      None                                                                */
24/*                                                                          */
25/****************************************************************************/
26/*Revision History:                                                         */
27/*    Who         When        What                                          */
28/*    --------    --------    ----------------------------------------------*/
29/*                                                                          */
30/*    Honda       12-4-06     created                                       */
31/*                                                                          */
32/****************************************************************************/
33
34#ifndef _CAGG_H
35#define _CAGG_H
36
37
38/*
39 * the aggregation functions flag, 0 if don't do aggregate
40 */
41
42#define ZM_AGG_FPGA_DEBUG                   1
43#define ZM_AGG_FPGA_REORDERING              1
44
45#ifndef ZM_AGG_TALLY
46//#define ZM_AGG_TALLY
47#endif
48/*
49 * Aggregate control
50 */
51
52
53#define ZM_AGG_POOL_SIZE                    20
54#define ZM_BAW_POOL_SIZE                    32
55#define ZM_AGGQ_SIZE                        64
56#define ZM_AGGQ_SIZE_MASK                   (ZM_AGGQ_SIZE-1)
57#define ZM_AGG_LOW_THRESHOLD                1
58#define ZM_AGG_HIGH_THRESHOLD               5
59
60/*
61 * number of access categories (ac)
62 */
63#define ZM_AC                               4
64/*
65 * the timer to clear aggregation queue, unit: 1 tick
66 * if the packet is too old (current time - arrival time)
67 * the packet and the aggregate queue will be cleared
68 */
69#define ZM_AGG_CLEAR_TIME                   10
70/*
71 * delete the queue if idle for ZM_DELETE_TIME
72 * unit: 10ms
73 */
74#define ZM_AGG_DELETE_TIME                  10000
75
76/*
77 * block ack window size
78 */
79#define ZM_AGG_BAW_SIZE                     64
80#define ZM_AGG_BAW_MASK                     (ZM_AGG_BAW_SIZE-1)
81/*
82 * originator     ADDBA Resquest    receiver
83 *      |----------------------------->|
84 *     1|          ACK                 |1
85 *      |<-----------------------------|
86 *     2|         ADDBA Response       |2
87 *      |<-----------------------------|
88 *     3|          ACK                 |3
89 *      |----------------------------->|
90 *     4                                4
91 */
92#define ZM_AGG_ADDBA_REQUEST                1
93#define ZM_AGG_ADDBA_REQUEST_ACK            2
94#define ZM_AGG_ADDBA_RESPONSE               3
95#define ZM_AGG_ADDBA_RESPONSE_ACK           4
96
97#define ZM_AGG_SINGLE_MPDU                  00
98#define ZM_AGG_FIRST_MPDU                   01
99#define ZM_AGG_MIDDLE_MPDU                  11
100#define ZM_AGG_LAST_MPDU                    10
101/*
102 * end of Aggregate control
103 */
104
105#define TID_TX  struct aggQueue*
106#define TID_BAW struct baw_q*
107#define BAW wd->baw_enabler
108#define DESTQ wd->destQ
109
110/*
111 * Queue access
112 */
113#define zm_agg_qlen(dev, head, tail) ((head - tail) & ZM_AGGQ_SIZE_MASK)
114#define zm_agg_inQ(tid_tx, pt) ((((pt - tid_tx->aggTail) & ZM_AGGQ_SIZE_MASK) < \
115        ((tid_tx->aggHead - tid_tx->aggTail) & ZM_AGGQ_SIZE_MASK))? TRUE:FALSE)
116#define zm_agg_plus(pt) pt = (pt + 1) & ZM_AGGQ_SIZE_MASK
117#define zm_agg_min(A, B) ((A>B)? B:A)
118#define zm_agg_GetTime() wd->tick
119#define TXQL (zfHpGetMaxTxdCount(dev) - zfHpGetFreeTxdCount(dev))
120
121/* don't change AGG_MIN_TXQL easily, this might cause BAW BSOD */
122#define AGG_MIN_TXQL                        2
123/*
124 * consider tcp,udp,ac(1234)
125 */
126#define zm_agg_dynamic_threshold(dev, ar)   ((ar > 16)? 11: \
127                                             (ar > 12)? 8: \
128                                             (ar > 8)? 5: \
129                                             (ar > 4)? 2:1)
130#define zm_agg_weight(ac)   ((3 == ac)? 4: \
131                             (2 == ac)? 3: \
132                             (0 == ac)? 2:1)
133/*
134 * the required free queue ratio per ac
135 */
136
137#define zm_agg_ratio(ac)    ((3 == ac)? 3: \
138                             (2 == ac)? (zfHpGetMaxTxdCount(dev)*1/4): \
139                             (0 == ac)? (zfHpGetMaxTxdCount(dev)*2/4): \
140                                        (zfHpGetMaxTxdCount(dev)*3/4))
141
142//#define zm_agg_ratio(ac)    3
143/*
144 * end of Queue access
145 */
146
147#define ZM_AGGMSG_LEV    ZM_LV_3
148#define zm_msg0_agg(lv, msg) if (ZM_AGGMSG_LEV >= lv) \
149        {zm_debug_msg0(msg);}
150#define zm_msg1_agg(lv, msg, val) if (ZM_AGGMSG_LEV >= lv) \
151        {zm_debug_msg1(msg, val);}
152#define zm_msg2_agg(lv, msg, val) if (ZM_AGGMSG_LEV >= lv) \
153        {zm_debug_msg2(msg, val);}
154
155#ifndef ZM_ENABLE_FW_BA_RETRANSMISSION     //disable BAW
156struct baw_header_r {
157    u16_t       *header;
158    u16_t       *mic;
159    u16_t       *snap;
160    u16_t       headerLen;
161    u16_t       micLen;
162    u16_t       snapLen;
163    u16_t       removeLen;
164    u8_t        keyIdx;
165};
166
167struct baw_header {
168    u16_t       header[29];//[(8+30+2+18)/2];  58 bytes  /* ctr+(4+a1+a2+a3+2+a4)+qos+iv */
169    u16_t       headerLen;
170    u16_t       mic[4]; //[8/2]; 8 bytes
171    u16_t       micLen;
172    u16_t       snap[4]; //[8/2]; 8 bytes
173    u16_t       snapLen;
174    u16_t       removeLen;
175    u8_t        keyIdx;
176};
177
178struct bufInfo {
179    zbuf_t*     buf;
180    u8_t        baw_retransmit;
181    u32_t       timestamp;
182    struct baw_header   *baw_header;
183};
184#endif
185struct aggElement
186{
187    zbuf_t*     buf;
188    u32_t       arrivalTime;
189    u8_t        baw_retransmit;
190    struct zsAdditionInfo addInfo;
191    //struct baw_header  baw_header;
192};
193
194
195#ifndef ZM_ENABLE_FW_BA_RETRANSMISSION     //disable BAW
196struct baw_buf
197{
198    zbuf_t*     buf;
199    u16_t       baw_seq;
200    u32_t       timestamp;
201    u8_t        baw_retransmit;
202    struct baw_header baw_header;
203};
204
205struct baw_q {
206    struct baw_buf  frame[ZM_VTXQ_SIZE];
207    u16_t       enabled;
208    u16_t       start_seq;
209    u16_t       head;
210    u16_t       tail;
211    u16_t       size;
212    TID_TX      tid_tx;
213
214    //struct baw_header *baw_header;
215};
216
217struct baw_enabler
218{
219    struct baw_q    tid_baw[ZM_BAW_POOL_SIZE];
220    u8_t    delPoint;
221    void    (*core)(zdev_t* dev, u16_t baw_seq, u32_t bitmap, u16_t aggLen);
222    //void    (*core);
223    void    (*init)(zdev_t* dev);
224    TID_BAW (*getNewQ)(zdev_t* dev, u16_t start_seq, TID_TX tid_tx);
225    TID_BAW (*getQ)(zdev_t* dev, u16_t baw_seq);
226    u16_t   (*insert)(zdev_t* dev, zbuf_t* buf, u16_t baw_seq, TID_BAW tid_baw, u8_t baw_retransmit, struct baw_header_r *header_r);
227    struct bufInfo* (*pop)(zdev_t* dev, u16_t index, TID_BAW tid_baw);
228    void    (*enable)(zdev_t* dev, TID_BAW tid_baw, u16_t start_seq);
229    void    (*disable)(zdev_t* dev, TID_BAW tid_baw);
230
231};
232#endif
233struct aggQueue
234{
235    struct      aggElement  aggvtxq[ZM_AGGQ_SIZE];
236    u16_t       aggHead;
237    u16_t       aggTail;
238    s16_t       size;
239    u16_t       aggQSTA;
240    u16_t       aggQEnabled;
241    u16_t       ac;
242    u16_t       tid;
243    u16_t       aggReady;
244    u16_t       clearFlag;
245    u16_t       deleteFlag;
246    u32_t       lastArrival;
247    u16_t       aggFrameSize;
248    u16_t       bar_ssn;    /* starting sequence number in BAR */
249    u16_t       dst[3];
250    u16_t       complete;     /* complete indication pointer */
251};
252
253struct aggSta
254{
255    u16_t       count[ZM_AC];
256    TID_TX      tid_tx[8];
257    u16_t       aggFlag[ZM_AC];
258};
259
260struct agg_tid_rx
261{
262    u16_t       aid;
263    u16_t       ac;
264    u16_t       addBaExchangeStatusCode;
265    //struct zsAdditionInfo *addInfo;
266    u16_t       seq_start;		/* first seq expected next */
267    u16_t       baw_head;		/* head of valid block ack window */
268    u16_t       baw_tail;		/* tail of valid block ack window */
269    //u16_t       free_count;		/* block ack window size	*/
270    u8_t        sq_exceed_count;
271    u8_t        sq_behind_count;
272    struct aggElement frame[ZM_AGG_BAW_SIZE + 1]; /* out-of-order rx frames */
273};
274
275struct aggControl
276{
277    u16_t       aggEnabled;
278    u16_t       ampduIndication;
279    u16_t       addbaIndication;
280    //TID_BAW     tid_baw;
281    u32_t       timestamp;
282};
283
284struct aggBaFrameParameter
285{
286    zbuf_t*     buf;
287    u16_t       ba_parameter;
288    u8_t        dialog;
289    u16_t       ba_policy;
290    u16_t       tid;
291    u16_t       buffer_size;
292    u16_t       ba_timeout;
293    u16_t       ba_start_seq;
294    u16_t       status_code;
295};
296
297struct aggBarControl
298{
299    u16_t       bar_ack_policy      ;
300    u16_t       multi_tid           ;
301    u16_t       compressed_bitmap   ;
302    u16_t       tid_info            ;
303};
304
305struct aggTally
306{
307    u32_t       got_packets_sum;
308    u32_t       got_bytes_sum;
309    u32_t       sent_packets_sum;
310    u32_t       sent_bytes_sum;
311    u32_t       avg_got_packets;
312    u32_t       avg_got_bytes;
313    u32_t       avg_sent_packets;
314    u32_t       avg_sent_bytes;
315    u16_t       time;
316};
317
318
319struct destQ {
320    struct dest{
321        u16_t   Qtype : 1; /* 0 aggr, 1 vtxq */
322        TID_TX  tid_tx;
323        void*   vtxq;
324
325        struct dest* next;
326    } *dest[4];
327    struct dest* Head[4];
328    //s16_t   size[4];
329    u16_t   ppri;
330    void    (*insert)(zdev_t* dev, u16_t Qtype, u16_t ac, TID_TX tid_tx, void* vtxq);
331    void    (*delete)(zdev_t* dev, u16_t Qtype, TID_TX tid_tx, void* vtxq);
332    void    (*init)(zdev_t* dev);
333    struct dest* (*getNext)(zdev_t* dev, u16_t ac);
334    u16_t   (*exist)(zdev_t* dev, u16_t Qtype, u16_t ac, TID_TX tid_tx, void* vtxq);
335    //void    (*scan)(zdev_t* dev);
336};
337/*
338 * aggregation tx
339 */
340void    zfAggInit(zdev_t* dev);
341u16_t   zfApFindSta(zdev_t* dev, u16_t* addr);
342u16_t   zfAggGetSta(zdev_t* dev, zbuf_t* buf);
343TID_TX  zfAggTxGetQueue(zdev_t* dev, u16_t aid, u16_t tid);
344TID_TX  zfAggTxNewQueue(zdev_t* dev, u16_t aid, u16_t tid, zbuf_t* buf);
345u16_t   zfAggTxEnqueue(zdev_t* dev, zbuf_t* buf, u16_t aid, TID_TX tid_tx);
346u16_t   zfAggTx(zdev_t* dev, zbuf_t* buf, u16_t tid);
347u16_t   zfAggTxReadyCount(zdev_t* dev, u16_t ac);
348u16_t   zfAggTxPartial(zdev_t* dev, u16_t ac, u16_t readycount);
349u16_t   zfAggTxSend(zdev_t* dev, u32_t freeTxd, TID_TX tid_tx);
350TID_TX  zfAggTxGetReadyQueue(zdev_t* dev, u16_t ac);
351zbuf_t* zfAggTxGetVtxq(zdev_t* dev, TID_TX tid_tx);
352u16_t   zfAggTxDeleteQueue(zdev_t* dev, u16_t qnum);
353u16_t   zfAggScanAndClear(zdev_t* dev, u32_t time);
354u16_t   zfAggClearQueue(zdev_t* dev);
355void    zfAggTxScheduler(zdev_t* dev, u8_t ScanAndClear);
356
357/* tid_tx manipulation */
358#ifndef ZM_ENABLE_FW_BA_RETRANSMISSION     //disable BAW
359u16_t   zfAggTidTxInsertHead(zdev_t* dev, struct bufInfo* buf_info, TID_TX tid_tx);
360#endif
361void    zfAggDestInsert(zdev_t* dev, u16_t Qtype, u16_t ac, TID_TX tid_tx, void* vtxq);
362void    zfAggDestDelete(zdev_t* dev, u16_t Qtype, TID_TX tid_tx, void* vtxq);
363void    zfAggDestInit(zdev_t* dev);
364struct dest* zfAggDestGetNext(zdev_t* dev, u16_t ac);
365u16_t   zfAggDestExist(zdev_t* dev, u16_t Qtype, u16_t ac, TID_TX tid_tx, void* vtxq);
366/*
367 * aggregation rx
368 */
369struct agg_tid_rx *zfAggRxEnabled(zdev_t* dev, zbuf_t* buf);
370u16_t   zfAggRx(zdev_t* dev, zbuf_t* buf, struct zsAdditionInfo *addInfo, struct agg_tid_rx *tid_rx);
371struct agg_tid_rx *zfAggRxGetQueue(zdev_t* dev, zbuf_t* buf);
372u16_t   zfAggRxEnqueue(zdev_t* dev, zbuf_t* buf, struct agg_tid_rx *tid_rx, struct zsAdditionInfo *addInfo);
373u16_t   zfAggRxFlush(zdev_t* dev, u16_t seq_no, struct agg_tid_rx *tid_rx);
374u16_t   zfAggRxFreeBuf(zdev_t* dev, u16_t destroy);
375u16_t   zfAggRxClear(zdev_t* dev, u32_t time);
376void    zfAggRecvBAR(zdev_t* dev, zbuf_t* buf);
377/*
378 * end of aggregation rx
379 */
380
381/*
382 * ADDBA
383 */
384u16_t   zfAggSendAddbaRequest(zdev_t* dev, u16_t *dst, u16_t ac, u16_t up);
385u16_t   zfAggSetAddbaFrameBody(zdev_t* dev,zbuf_t* buf, u16_t offset, u16_t ac, u16_t up);
386u16_t   zfAggGenAddbaHeader(zdev_t* dev, u16_t* dst,
387                u16_t* header, u16_t len, zbuf_t* buf, u16_t vap, u8_t encrypt);
388u16_t   zfAggProcessAction(zdev_t* dev, zbuf_t* buf);
389u16_t   zfAggBlockAckActionFrame(zdev_t* dev, zbuf_t* buf);
390u16_t   zfAggRecvAddbaRequest(zdev_t* dev, zbuf_t* buf);
391u16_t   zfAggRecvAddbaResponse(zdev_t* dev, zbuf_t* buf);
392u16_t   zfAggRecvDelba(zdev_t* dev, zbuf_t* buf);
393u16_t   zfAggSendAddbaResponse(zdev_t* dev, struct aggBaFrameParameter *bf);
394u16_t   zfAggSetAddbaResponseFrameBody(zdev_t* dev, zbuf_t* buf,
395                struct aggBaFrameParameter *bf, u16_t offset);
396u16_t   zfAggAddbaSetTidRx(zdev_t* dev, zbuf_t* buf,
397                struct aggBaFrameParameter *bf);
398/*
399 * zfAggTxSendEth
400 */
401u16_t zfAggTxSendEth(zdev_t* dev, zbuf_t* buf, u16_t port, u16_t bufType, u8_t flag, struct aggControl *aggControl, TID_TX tid_tx);
402
403/*
404 * statistics functions
405 */
406u16_t zfAggTallyReset(zdev_t* dev);
407
408u16_t   zfAggPrintTally(zdev_t* dev);
409
410/*
411 * BAR
412 */
413void    zfAggInvokeBar(zdev_t* dev, TID_TX tid_tx);
414u16_t   zfAggSendBar(zdev_t* dev, TID_TX tid_tx, struct aggBarControl *aggBarControl);
415u16_t   zfAggSetBarBody(zdev_t* dev, zbuf_t* buf, u16_t offset, TID_TX tid_tx, struct aggBarControl *aggBarControl);
416u16_t   zfAggGenBarHeader(zdev_t* dev, u16_t* dst,
417                u16_t* header, u16_t len, zbuf_t* buf, u16_t vap, u8_t encrypt);
418
419#ifndef ZM_ENABLE_FW_BA_RETRANSMISSION     //disable BAW
420/* BAW BA retransmission */
421void    zfBawCore(zdev_t* dev, u16_t baw_seq, u32_t bitmap, u16_t aggLen);
422void    zfBawInit(zdev_t* dev);
423TID_BAW zfBawGetNewQ(zdev_t* dev, u16_t start_seq, TID_TX tid_tx);
424u16_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);
425struct bufInfo* zfBawPop(zdev_t* dev, u16_t index, TID_BAW tid_baw);
426void    zfBawEnable(zdev_t* dev, TID_BAW tid_baw, u16_t start_seq);
427void    zfBawDisable(zdev_t* dev, TID_BAW tid_baw);
428TID_BAW zfBawGetQ(zdev_t* dev, u16_t baw_seq);
429void zfAggTxRetransmit(zdev_t* dev, struct bufInfo *buf_info, struct aggControl *aggControl, TID_TX tid_tx);
430#endif
431/* extern functions */
432extern zbuf_t* zfGetVtxq(zdev_t* dev, u8_t ac);
433
434#endif /* #ifndef _CAGG_H */
435