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