4bd43f507c
Initial dump of the otus USB wireless network driver. It builds properly, but a lot of work needs to be done cleaning it up before it can be merged into the wireless driver tree. Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
436 lines
15 KiB
C
436 lines
15 KiB
C
/*
|
|
* Copyright (c) 2007-2008 Atheros Communications Inc.
|
|
*
|
|
* Permission to use, copy, modify, and/or distribute this software for any
|
|
* purpose with or without fee is hereby granted, provided that the above
|
|
* copyright notice and this permission notice appear in all copies.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
*/
|
|
/* */
|
|
/* Module Name : cagg.h */
|
|
/* */
|
|
/* Abstract */
|
|
/* This module contains A-MPDU aggregation relatived functions. */
|
|
/* */
|
|
/* NOTES */
|
|
/* None */
|
|
/* */
|
|
/****************************************************************************/
|
|
/*Revision History: */
|
|
/* Who When What */
|
|
/* -------- -------- ----------------------------------------------*/
|
|
/* */
|
|
/* Honda 12-4-06 created */
|
|
/* */
|
|
/****************************************************************************/
|
|
|
|
#ifndef _CAGG_H
|
|
#define _CAGG_H
|
|
|
|
|
|
/*
|
|
* the aggregation functions flag, 0 if don't do aggregate
|
|
*/
|
|
|
|
#define ZM_AGG_FPGA_DEBUG 1
|
|
#define ZM_AGG_FPGA_REORDERING 1
|
|
|
|
#ifndef ZM_AGG_TALLY
|
|
//#define ZM_AGG_TALLY
|
|
#endif
|
|
/*
|
|
* Aggregate control
|
|
*/
|
|
|
|
|
|
#define ZM_AGG_POOL_SIZE 20
|
|
#define ZM_BAW_POOL_SIZE 32
|
|
#define ZM_AGGQ_SIZE 64
|
|
#define ZM_AGGQ_SIZE_MASK (ZM_AGGQ_SIZE-1)
|
|
#define ZM_AGG_LOW_THRESHOLD 1
|
|
#define ZM_AGG_HIGH_THRESHOLD 5
|
|
|
|
/*
|
|
* number of access categories (ac)
|
|
*/
|
|
#define ZM_AC 4
|
|
/*
|
|
* the timer to clear aggregation queue, unit: 1 tick
|
|
* if the packet is too old (current time - arrival time)
|
|
* the packet and the aggregate queue will be cleared
|
|
*/
|
|
#define ZM_AGG_CLEAR_TIME 10
|
|
/*
|
|
* delete the queue if idle for ZM_DELETE_TIME
|
|
* unit: 10ms
|
|
*/
|
|
#define ZM_AGG_DELETE_TIME 10000
|
|
|
|
/*
|
|
* block ack window size
|
|
*/
|
|
#define ZM_AGG_BAW_SIZE 64
|
|
#define ZM_AGG_BAW_MASK (ZM_AGG_BAW_SIZE-1)
|
|
/*
|
|
* originator ADDBA Resquest receiver
|
|
* |----------------------------->|
|
|
* 1| ACK |1
|
|
* |<-----------------------------|
|
|
* 2| ADDBA Response |2
|
|
* |<-----------------------------|
|
|
* 3| ACK |3
|
|
* |----------------------------->|
|
|
* 4 4
|
|
*/
|
|
#define ZM_AGG_ADDBA_REQUEST 1
|
|
#define ZM_AGG_ADDBA_REQUEST_ACK 2
|
|
#define ZM_AGG_ADDBA_RESPONSE 3
|
|
#define ZM_AGG_ADDBA_RESPONSE_ACK 4
|
|
|
|
#define ZM_AGG_SINGLE_MPDU 00
|
|
#define ZM_AGG_FIRST_MPDU 01
|
|
#define ZM_AGG_MIDDLE_MPDU 11
|
|
#define ZM_AGG_LAST_MPDU 10
|
|
/*
|
|
* end of Aggregate control
|
|
*/
|
|
|
|
#define TID_TX struct aggQueue*
|
|
#define TID_BAW struct baw_q*
|
|
#define BAW wd->baw_enabler
|
|
#define DESTQ wd->destQ
|
|
|
|
/*
|
|
* Queue access
|
|
*/
|
|
#define zm_agg_qlen(dev, head, tail) ((head - tail) & ZM_AGGQ_SIZE_MASK)
|
|
#define zm_agg_inQ(tid_tx, pt) ((((pt - tid_tx->aggTail) & ZM_AGGQ_SIZE_MASK) < \
|
|
((tid_tx->aggHead - tid_tx->aggTail) & ZM_AGGQ_SIZE_MASK))? TRUE:FALSE)
|
|
#define zm_agg_plus(pt) pt = (pt + 1) & ZM_AGGQ_SIZE_MASK
|
|
#define zm_agg_min(A, B) ((A>B)? B:A)
|
|
#define zm_agg_GetTime() wd->tick
|
|
#define TXQL (zfHpGetMaxTxdCount(dev) - zfHpGetFreeTxdCount(dev))
|
|
|
|
/* don't change AGG_MIN_TXQL easily, this might cause BAW BSOD */
|
|
#define AGG_MIN_TXQL 2
|
|
/*
|
|
* consider tcp,udp,ac(1234)
|
|
*/
|
|
#define zm_agg_dynamic_threshold(dev, ar) ((ar > 16)? 11: \
|
|
(ar > 12)? 8: \
|
|
(ar > 8)? 5: \
|
|
(ar > 4)? 2:1)
|
|
#define zm_agg_weight(ac) ((3 == ac)? 4: \
|
|
(2 == ac)? 3: \
|
|
(0 == ac)? 2:1)
|
|
/*
|
|
* the required free queue ratio per ac
|
|
*/
|
|
|
|
#define zm_agg_ratio(ac) ((3 == ac)? 3: \
|
|
(2 == ac)? (zfHpGetMaxTxdCount(dev)*1/4): \
|
|
(0 == ac)? (zfHpGetMaxTxdCount(dev)*2/4): \
|
|
(zfHpGetMaxTxdCount(dev)*3/4))
|
|
|
|
//#define zm_agg_ratio(ac) 3
|
|
/*
|
|
* end of Queue access
|
|
*/
|
|
|
|
#define ZM_AGGMSG_LEV ZM_LV_3
|
|
#define zm_msg0_agg(lv, msg) if (ZM_AGGMSG_LEV >= lv) \
|
|
{zm_debug_msg0(msg);}
|
|
#define zm_msg1_agg(lv, msg, val) if (ZM_AGGMSG_LEV >= lv) \
|
|
{zm_debug_msg1(msg, val);}
|
|
#define zm_msg2_agg(lv, msg, val) if (ZM_AGGMSG_LEV >= lv) \
|
|
{zm_debug_msg2(msg, val);}
|
|
|
|
#ifndef ZM_ENABLE_FW_BA_RETRANSMISSION //disable BAW
|
|
struct baw_header_r {
|
|
u16_t *header;
|
|
u16_t *mic;
|
|
u16_t *snap;
|
|
u16_t headerLen;
|
|
u16_t micLen;
|
|
u16_t snapLen;
|
|
u16_t removeLen;
|
|
u8_t keyIdx;
|
|
};
|
|
|
|
struct baw_header {
|
|
u16_t header[29];//[(8+30+2+18)/2]; 58 bytes /* ctr+(4+a1+a2+a3+2+a4)+qos+iv */
|
|
u16_t headerLen;
|
|
u16_t mic[4]; //[8/2]; 8 bytes
|
|
u16_t micLen;
|
|
u16_t snap[4]; //[8/2]; 8 bytes
|
|
u16_t snapLen;
|
|
u16_t removeLen;
|
|
u8_t keyIdx;
|
|
};
|
|
|
|
struct bufInfo {
|
|
zbuf_t* buf;
|
|
u8_t baw_retransmit;
|
|
u32_t timestamp;
|
|
struct baw_header *baw_header;
|
|
};
|
|
#endif
|
|
struct aggElement
|
|
{
|
|
zbuf_t* buf;
|
|
u32_t arrivalTime;
|
|
u8_t baw_retransmit;
|
|
struct zsAdditionInfo addInfo;
|
|
//struct baw_header baw_header;
|
|
};
|
|
|
|
|
|
#ifndef ZM_ENABLE_FW_BA_RETRANSMISSION //disable BAW
|
|
struct baw_buf
|
|
{
|
|
zbuf_t* buf;
|
|
u16_t baw_seq;
|
|
u32_t timestamp;
|
|
u8_t baw_retransmit;
|
|
struct baw_header baw_header;
|
|
};
|
|
|
|
struct baw_q {
|
|
struct baw_buf frame[ZM_VTXQ_SIZE];
|
|
u16_t enabled;
|
|
u16_t start_seq;
|
|
u16_t head;
|
|
u16_t tail;
|
|
u16_t size;
|
|
TID_TX tid_tx;
|
|
|
|
//struct baw_header *baw_header;
|
|
};
|
|
|
|
struct baw_enabler
|
|
{
|
|
struct baw_q tid_baw[ZM_BAW_POOL_SIZE];
|
|
u8_t delPoint;
|
|
void (*core)(zdev_t* dev, u16_t baw_seq, u32_t bitmap, u16_t aggLen);
|
|
//void (*core);
|
|
void (*init)(zdev_t* dev);
|
|
TID_BAW (*getNewQ)(zdev_t* dev, u16_t start_seq, TID_TX tid_tx);
|
|
TID_BAW (*getQ)(zdev_t* dev, u16_t baw_seq);
|
|
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);
|
|
struct bufInfo* (*pop)(zdev_t* dev, u16_t index, TID_BAW tid_baw);
|
|
void (*enable)(zdev_t* dev, TID_BAW tid_baw, u16_t start_seq);
|
|
void (*disable)(zdev_t* dev, TID_BAW tid_baw);
|
|
|
|
};
|
|
#endif
|
|
struct aggQueue
|
|
{
|
|
struct aggElement aggvtxq[ZM_AGGQ_SIZE];
|
|
u16_t aggHead;
|
|
u16_t aggTail;
|
|
s16_t size;
|
|
u16_t aggQSTA;
|
|
u16_t aggQEnabled;
|
|
u16_t ac;
|
|
u16_t tid;
|
|
u16_t aggReady;
|
|
u16_t clearFlag;
|
|
u16_t deleteFlag;
|
|
u32_t lastArrival;
|
|
u16_t aggFrameSize;
|
|
u16_t bar_ssn; /* starting sequence number in BAR */
|
|
u16_t dst[3];
|
|
u16_t complete; /* complete indication pointer */
|
|
};
|
|
|
|
struct aggSta
|
|
{
|
|
u16_t count[ZM_AC];
|
|
TID_TX tid_tx[8];
|
|
u16_t aggFlag[ZM_AC];
|
|
};
|
|
|
|
struct agg_tid_rx
|
|
{
|
|
u16_t aid;
|
|
u16_t ac;
|
|
u16_t addBaExchangeStatusCode;
|
|
//struct zsAdditionInfo *addInfo;
|
|
u16_t seq_start; /* first seq expected next */
|
|
u16_t baw_head; /* head of valid block ack window */
|
|
u16_t baw_tail; /* tail of valid block ack window */
|
|
//u16_t free_count; /* block ack window size */
|
|
u8_t sq_exceed_count;
|
|
u8_t sq_behind_count;
|
|
struct aggElement frame[ZM_AGG_BAW_SIZE + 1]; /* out-of-order rx frames */
|
|
};
|
|
|
|
struct aggControl
|
|
{
|
|
u16_t aggEnabled;
|
|
u16_t ampduIndication;
|
|
u16_t addbaIndication;
|
|
//TID_BAW tid_baw;
|
|
u32_t timestamp;
|
|
};
|
|
|
|
struct aggBaFrameParameter
|
|
{
|
|
zbuf_t* buf;
|
|
u16_t ba_parameter;
|
|
u8_t dialog;
|
|
u16_t ba_policy;
|
|
u16_t tid;
|
|
u16_t buffer_size;
|
|
u16_t ba_timeout;
|
|
u16_t ba_start_seq;
|
|
u16_t status_code;
|
|
};
|
|
|
|
struct aggBarControl
|
|
{
|
|
u16_t bar_ack_policy ;
|
|
u16_t multi_tid ;
|
|
u16_t compressed_bitmap ;
|
|
u16_t tid_info ;
|
|
};
|
|
|
|
struct aggTally
|
|
{
|
|
u32_t got_packets_sum;
|
|
u32_t got_bytes_sum;
|
|
u32_t sent_packets_sum;
|
|
u32_t sent_bytes_sum;
|
|
u32_t avg_got_packets;
|
|
u32_t avg_got_bytes;
|
|
u32_t avg_sent_packets;
|
|
u32_t avg_sent_bytes;
|
|
u16_t time;
|
|
};
|
|
|
|
|
|
struct destQ {
|
|
struct dest{
|
|
u16_t Qtype : 1; /* 0 aggr, 1 vtxq */
|
|
TID_TX tid_tx;
|
|
void* vtxq;
|
|
|
|
struct dest* next;
|
|
} *dest[4];
|
|
struct dest* Head[4];
|
|
//s16_t size[4];
|
|
u16_t ppri;
|
|
void (*insert)(zdev_t* dev, u16_t Qtype, u16_t ac, TID_TX tid_tx, void* vtxq);
|
|
void (*delete)(zdev_t* dev, u16_t Qtype, TID_TX tid_tx, void* vtxq);
|
|
void (*init)(zdev_t* dev);
|
|
struct dest* (*getNext)(zdev_t* dev, u16_t ac);
|
|
u16_t (*exist)(zdev_t* dev, u16_t Qtype, u16_t ac, TID_TX tid_tx, void* vtxq);
|
|
//void (*scan)(zdev_t* dev);
|
|
};
|
|
/*
|
|
* aggregation tx
|
|
*/
|
|
void zfAggInit(zdev_t* dev);
|
|
u16_t zfApFindSta(zdev_t* dev, u16_t* addr);
|
|
u16_t zfAggGetSta(zdev_t* dev, zbuf_t* buf);
|
|
TID_TX zfAggTxGetQueue(zdev_t* dev, u16_t aid, u16_t tid);
|
|
TID_TX zfAggTxNewQueue(zdev_t* dev, u16_t aid, u16_t tid, zbuf_t* buf);
|
|
u16_t zfAggTxEnqueue(zdev_t* dev, zbuf_t* buf, u16_t aid, TID_TX tid_tx);
|
|
u16_t zfAggTx(zdev_t* dev, zbuf_t* buf, u16_t tid);
|
|
u16_t zfAggTxReadyCount(zdev_t* dev, u16_t ac);
|
|
u16_t zfAggTxPartial(zdev_t* dev, u16_t ac, u16_t readycount);
|
|
u16_t zfAggTxSend(zdev_t* dev, u32_t freeTxd, TID_TX tid_tx);
|
|
TID_TX zfAggTxGetReadyQueue(zdev_t* dev, u16_t ac);
|
|
zbuf_t* zfAggTxGetVtxq(zdev_t* dev, TID_TX tid_tx);
|
|
u16_t zfAggTxDeleteQueue(zdev_t* dev, u16_t qnum);
|
|
u16_t zfAggScanAndClear(zdev_t* dev, u32_t time);
|
|
u16_t zfAggClearQueue(zdev_t* dev);
|
|
void zfAggTxScheduler(zdev_t* dev, u8_t ScanAndClear);
|
|
|
|
/* tid_tx manipulation */
|
|
#ifndef ZM_ENABLE_FW_BA_RETRANSMISSION //disable BAW
|
|
u16_t zfAggTidTxInsertHead(zdev_t* dev, struct bufInfo* buf_info, TID_TX tid_tx);
|
|
#endif
|
|
void zfAggDestInsert(zdev_t* dev, u16_t Qtype, u16_t ac, TID_TX tid_tx, void* vtxq);
|
|
void zfAggDestDelete(zdev_t* dev, u16_t Qtype, TID_TX tid_tx, void* vtxq);
|
|
void zfAggDestInit(zdev_t* dev);
|
|
struct dest* zfAggDestGetNext(zdev_t* dev, u16_t ac);
|
|
u16_t zfAggDestExist(zdev_t* dev, u16_t Qtype, u16_t ac, TID_TX tid_tx, void* vtxq);
|
|
/*
|
|
* aggregation rx
|
|
*/
|
|
struct agg_tid_rx *zfAggRxEnabled(zdev_t* dev, zbuf_t* buf);
|
|
u16_t zfAggRx(zdev_t* dev, zbuf_t* buf, struct zsAdditionInfo *addInfo, struct agg_tid_rx *tid_rx);
|
|
struct agg_tid_rx *zfAggRxGetQueue(zdev_t* dev, zbuf_t* buf);
|
|
u16_t zfAggRxEnqueue(zdev_t* dev, zbuf_t* buf, struct agg_tid_rx *tid_rx, struct zsAdditionInfo *addInfo);
|
|
u16_t zfAggRxFlush(zdev_t* dev, u16_t seq_no, struct agg_tid_rx *tid_rx);
|
|
u16_t zfAggRxFreeBuf(zdev_t* dev, u16_t destroy);
|
|
u16_t zfAggRxClear(zdev_t* dev, u32_t time);
|
|
void zfAggRecvBAR(zdev_t* dev, zbuf_t* buf);
|
|
/*
|
|
* end of aggregation rx
|
|
*/
|
|
|
|
/*
|
|
* ADDBA
|
|
*/
|
|
u16_t zfAggSendAddbaRequest(zdev_t* dev, u16_t *dst, u16_t ac, u16_t up);
|
|
u16_t zfAggSetAddbaFrameBody(zdev_t* dev,zbuf_t* buf, u16_t offset, u16_t ac, u16_t up);
|
|
u16_t zfAggGenAddbaHeader(zdev_t* dev, u16_t* dst,
|
|
u16_t* header, u16_t len, zbuf_t* buf, u16_t vap, u8_t encrypt);
|
|
u16_t zfAggProcessAction(zdev_t* dev, zbuf_t* buf);
|
|
u16_t zfAggBlockAckActionFrame(zdev_t* dev, zbuf_t* buf);
|
|
u16_t zfAggRecvAddbaRequest(zdev_t* dev, zbuf_t* buf);
|
|
u16_t zfAggRecvAddbaResponse(zdev_t* dev, zbuf_t* buf);
|
|
u16_t zfAggRecvDelba(zdev_t* dev, zbuf_t* buf);
|
|
u16_t zfAggSendAddbaResponse(zdev_t* dev, struct aggBaFrameParameter *bf);
|
|
u16_t zfAggSetAddbaResponseFrameBody(zdev_t* dev, zbuf_t* buf,
|
|
struct aggBaFrameParameter *bf, u16_t offset);
|
|
u16_t zfAggAddbaSetTidRx(zdev_t* dev, zbuf_t* buf,
|
|
struct aggBaFrameParameter *bf);
|
|
/*
|
|
* zfAggTxSendEth
|
|
*/
|
|
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);
|
|
|
|
/*
|
|
* statistics functions
|
|
*/
|
|
u16_t zfAggTallyReset(zdev_t* dev);
|
|
|
|
u16_t zfAggPrintTally(zdev_t* dev);
|
|
|
|
/*
|
|
* BAR
|
|
*/
|
|
void zfAggInvokeBar(zdev_t* dev, TID_TX tid_tx);
|
|
u16_t zfAggSendBar(zdev_t* dev, TID_TX tid_tx, struct aggBarControl *aggBarControl);
|
|
u16_t zfAggSetBarBody(zdev_t* dev, zbuf_t* buf, u16_t offset, TID_TX tid_tx, struct aggBarControl *aggBarControl);
|
|
u16_t zfAggGenBarHeader(zdev_t* dev, u16_t* dst,
|
|
u16_t* header, u16_t len, zbuf_t* buf, u16_t vap, u8_t encrypt);
|
|
|
|
#ifndef ZM_ENABLE_FW_BA_RETRANSMISSION //disable BAW
|
|
/* BAW BA retransmission */
|
|
void zfBawCore(zdev_t* dev, u16_t baw_seq, u32_t bitmap, u16_t aggLen);
|
|
void zfBawInit(zdev_t* dev);
|
|
TID_BAW zfBawGetNewQ(zdev_t* dev, u16_t start_seq, TID_TX tid_tx);
|
|
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);
|
|
struct bufInfo* zfBawPop(zdev_t* dev, u16_t index, TID_BAW tid_baw);
|
|
void zfBawEnable(zdev_t* dev, TID_BAW tid_baw, u16_t start_seq);
|
|
void zfBawDisable(zdev_t* dev, TID_BAW tid_baw);
|
|
TID_BAW zfBawGetQ(zdev_t* dev, u16_t baw_seq);
|
|
void zfAggTxRetransmit(zdev_t* dev, struct bufInfo *buf_info, struct aggControl *aggControl, TID_TX tid_tx);
|
|
#endif
|
|
/* extern functions */
|
|
extern zbuf_t* zfGetVtxq(zdev_t* dev, u8_t ac);
|
|
|
|
#endif /* #ifndef _CAGG_H */
|
|
|