Commit | Line | Data |
---|---|---|
4bd43f50 LR |
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 | |
156 | struct 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 | ||
167 | struct 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 | ||
178 | struct bufInfo { | |
179 | zbuf_t* buf; | |
180 | u8_t baw_retransmit; | |
181 | u32_t timestamp; | |
182 | struct baw_header *baw_header; | |
183 | }; | |
184 | #endif | |
185 | struct 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 | |
196 | struct 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 | ||
205 | struct 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 | ||
217 | struct 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 | |
233 | struct 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 | ||
253 | struct aggSta | |
254 | { | |
255 | u16_t count[ZM_AC]; | |
256 | TID_TX tid_tx[8]; | |
257 | u16_t aggFlag[ZM_AC]; | |
258 | }; | |
259 | ||
260 | struct 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 | ||
275 | struct 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 | ||
284 | struct 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 | ||
297 | struct 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 | ||
305 | struct 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 | ||
319 | struct 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 | */ | |
340 | void zfAggInit(zdev_t* dev); | |
341 | u16_t zfApFindSta(zdev_t* dev, u16_t* addr); | |
342 | u16_t zfAggGetSta(zdev_t* dev, zbuf_t* buf); | |
343 | TID_TX zfAggTxGetQueue(zdev_t* dev, u16_t aid, u16_t tid); | |
344 | TID_TX zfAggTxNewQueue(zdev_t* dev, u16_t aid, u16_t tid, zbuf_t* buf); | |
345 | u16_t zfAggTxEnqueue(zdev_t* dev, zbuf_t* buf, u16_t aid, TID_TX tid_tx); | |
346 | u16_t zfAggTx(zdev_t* dev, zbuf_t* buf, u16_t tid); | |
347 | u16_t zfAggTxReadyCount(zdev_t* dev, u16_t ac); | |
348 | u16_t zfAggTxPartial(zdev_t* dev, u16_t ac, u16_t readycount); | |
349 | u16_t zfAggTxSend(zdev_t* dev, u32_t freeTxd, TID_TX tid_tx); | |
350 | TID_TX zfAggTxGetReadyQueue(zdev_t* dev, u16_t ac); | |
351 | zbuf_t* zfAggTxGetVtxq(zdev_t* dev, TID_TX tid_tx); | |
352 | u16_t zfAggTxDeleteQueue(zdev_t* dev, u16_t qnum); | |
353 | u16_t zfAggScanAndClear(zdev_t* dev, u32_t time); | |
354 | u16_t zfAggClearQueue(zdev_t* dev); | |
355 | void zfAggTxScheduler(zdev_t* dev, u8_t ScanAndClear); | |
356 | ||
357 | /* tid_tx manipulation */ | |
358 | #ifndef ZM_ENABLE_FW_BA_RETRANSMISSION //disable BAW | |
359 | u16_t zfAggTidTxInsertHead(zdev_t* dev, struct bufInfo* buf_info, TID_TX tid_tx); | |
360 | #endif | |
361 | void zfAggDestInsert(zdev_t* dev, u16_t Qtype, u16_t ac, TID_TX tid_tx, void* vtxq); | |
362 | void zfAggDestDelete(zdev_t* dev, u16_t Qtype, TID_TX tid_tx, void* vtxq); | |
363 | void zfAggDestInit(zdev_t* dev); | |
364 | struct dest* zfAggDestGetNext(zdev_t* dev, u16_t ac); | |
365 | u16_t zfAggDestExist(zdev_t* dev, u16_t Qtype, u16_t ac, TID_TX tid_tx, void* vtxq); | |
366 | /* | |
367 | * aggregation rx | |
368 | */ | |
369 | struct agg_tid_rx *zfAggRxEnabled(zdev_t* dev, zbuf_t* buf); | |
370 | u16_t zfAggRx(zdev_t* dev, zbuf_t* buf, struct zsAdditionInfo *addInfo, struct agg_tid_rx *tid_rx); | |
371 | struct agg_tid_rx *zfAggRxGetQueue(zdev_t* dev, zbuf_t* buf); | |
372 | u16_t zfAggRxEnqueue(zdev_t* dev, zbuf_t* buf, struct agg_tid_rx *tid_rx, struct zsAdditionInfo *addInfo); | |
373 | u16_t zfAggRxFlush(zdev_t* dev, u16_t seq_no, struct agg_tid_rx *tid_rx); | |
374 | u16_t zfAggRxFreeBuf(zdev_t* dev, u16_t destroy); | |
375 | u16_t zfAggRxClear(zdev_t* dev, u32_t time); | |
376 | void zfAggRecvBAR(zdev_t* dev, zbuf_t* buf); | |
377 | /* | |
378 | * end of aggregation rx | |
379 | */ | |
380 | ||
381 | /* | |
382 | * ADDBA | |
383 | */ | |
384 | u16_t zfAggSendAddbaRequest(zdev_t* dev, u16_t *dst, u16_t ac, u16_t up); | |
385 | u16_t zfAggSetAddbaFrameBody(zdev_t* dev,zbuf_t* buf, u16_t offset, u16_t ac, u16_t up); | |
386 | u16_t zfAggGenAddbaHeader(zdev_t* dev, u16_t* dst, | |
387 | u16_t* header, u16_t len, zbuf_t* buf, u16_t vap, u8_t encrypt); | |
388 | u16_t zfAggProcessAction(zdev_t* dev, zbuf_t* buf); | |
389 | u16_t zfAggBlockAckActionFrame(zdev_t* dev, zbuf_t* buf); | |
390 | u16_t zfAggRecvAddbaRequest(zdev_t* dev, zbuf_t* buf); | |
391 | u16_t zfAggRecvAddbaResponse(zdev_t* dev, zbuf_t* buf); | |
392 | u16_t zfAggRecvDelba(zdev_t* dev, zbuf_t* buf); | |
393 | u16_t zfAggSendAddbaResponse(zdev_t* dev, struct aggBaFrameParameter *bf); | |
394 | u16_t zfAggSetAddbaResponseFrameBody(zdev_t* dev, zbuf_t* buf, | |
395 | struct aggBaFrameParameter *bf, u16_t offset); | |
396 | u16_t zfAggAddbaSetTidRx(zdev_t* dev, zbuf_t* buf, | |
397 | struct aggBaFrameParameter *bf); | |
398 | /* | |
399 | * zfAggTxSendEth | |
400 | */ | |
401 | 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); | |
402 | ||
403 | /* | |
404 | * statistics functions | |
405 | */ | |
406 | u16_t zfAggTallyReset(zdev_t* dev); | |
407 | ||
408 | u16_t zfAggPrintTally(zdev_t* dev); | |
409 | ||
410 | /* | |
411 | * BAR | |
412 | */ | |
413 | void zfAggInvokeBar(zdev_t* dev, TID_TX tid_tx); | |
414 | u16_t zfAggSendBar(zdev_t* dev, TID_TX tid_tx, struct aggBarControl *aggBarControl); | |
415 | u16_t zfAggSetBarBody(zdev_t* dev, zbuf_t* buf, u16_t offset, TID_TX tid_tx, struct aggBarControl *aggBarControl); | |
416 | u16_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 */ | |
421 | void zfBawCore(zdev_t* dev, u16_t baw_seq, u32_t bitmap, u16_t aggLen); | |
422 | void zfBawInit(zdev_t* dev); | |
423 | TID_BAW zfBawGetNewQ(zdev_t* dev, u16_t start_seq, TID_TX tid_tx); | |
424 | 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); | |
425 | struct bufInfo* zfBawPop(zdev_t* dev, u16_t index, TID_BAW tid_baw); | |
426 | void zfBawEnable(zdev_t* dev, TID_BAW tid_baw, u16_t start_seq); | |
427 | void zfBawDisable(zdev_t* dev, TID_BAW tid_baw); | |
428 | TID_BAW zfBawGetQ(zdev_t* dev, u16_t baw_seq); | |
429 | void zfAggTxRetransmit(zdev_t* dev, struct bufInfo *buf_info, struct aggControl *aggControl, TID_TX tid_tx); | |
430 | #endif | |
431 | /* extern functions */ | |
432 | extern zbuf_t* zfGetVtxq(zdev_t* dev, u8_t ac); | |
433 | ||
434 | #endif /* #ifndef _CAGG_H */ | |
435 |