ath9k_hw: Fill descriptor abstrations for AR9003
Signed-off-by: Vasanthakumar Thiagarajan <vasanth@atheros.com> Signed-off-by: Felix Fietkau <nbd@openwrt.org> Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:
parent
b622a720b4
commit
994089db03
@ -168,23 +168,169 @@ static bool ar9003_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked)
|
||||
return true;
|
||||
}
|
||||
|
||||
static u16 ar9003_calc_ptr_chksum(struct ar9003_txc *ads)
|
||||
{
|
||||
int checksum;
|
||||
|
||||
checksum = ads->info + ads->link
|
||||
+ ads->data0 + ads->ctl3
|
||||
+ ads->data1 + ads->ctl5
|
||||
+ ads->data2 + ads->ctl7
|
||||
+ ads->data3 + ads->ctl9;
|
||||
|
||||
return ((checksum & 0xffff) + (checksum >> 16)) & AR_TxPtrChkSum;
|
||||
}
|
||||
|
||||
static void ar9003_hw_fill_txdesc(struct ath_hw *ah, void *ds, u32 seglen,
|
||||
bool is_firstseg, bool is_lastseg,
|
||||
const void *ds0, dma_addr_t buf_addr,
|
||||
unsigned int qcu)
|
||||
{
|
||||
struct ar9003_txc *ads = (struct ar9003_txc *) ds;
|
||||
unsigned int descid = 0;
|
||||
|
||||
ads->info = (ATHEROS_VENDOR_ID << AR_DescId_S) |
|
||||
(1 << AR_TxRxDesc_S) |
|
||||
(1 << AR_CtrlStat_S) |
|
||||
(qcu << AR_TxQcuNum_S) | 0x17;
|
||||
|
||||
ads->data0 = buf_addr;
|
||||
ads->data1 = 0;
|
||||
ads->data2 = 0;
|
||||
ads->data3 = 0;
|
||||
|
||||
ads->ctl3 = (seglen << AR_BufLen_S);
|
||||
ads->ctl3 &= AR_BufLen;
|
||||
|
||||
/* Fill in pointer checksum and descriptor id */
|
||||
ads->ctl10 = ar9003_calc_ptr_chksum(ads);
|
||||
ads->ctl10 |= (descid << AR_TxDescId_S);
|
||||
|
||||
if (is_firstseg) {
|
||||
ads->ctl12 |= (is_lastseg ? 0 : AR_TxMore);
|
||||
} else if (is_lastseg) {
|
||||
ads->ctl11 = 0;
|
||||
ads->ctl12 = 0;
|
||||
ads->ctl13 = AR9003TXC_CONST(ds0)->ctl13;
|
||||
ads->ctl14 = AR9003TXC_CONST(ds0)->ctl14;
|
||||
} else {
|
||||
/* XXX Intermediate descriptor in a multi-descriptor frame.*/
|
||||
ads->ctl11 = 0;
|
||||
ads->ctl12 = AR_TxMore;
|
||||
ads->ctl13 = 0;
|
||||
ads->ctl14 = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static int ar9003_hw_proc_txdesc(struct ath_hw *ah, void *ds,
|
||||
struct ath_tx_status *ts)
|
||||
{
|
||||
struct ar9003_txs *ads;
|
||||
|
||||
ads = &ah->ts_ring[ah->ts_tail];
|
||||
|
||||
if ((ads->status8 & AR_TxDone) == 0)
|
||||
return -EINPROGRESS;
|
||||
|
||||
ah->ts_tail = (ah->ts_tail + 1) % ah->ts_size;
|
||||
|
||||
if ((MS(ads->ds_info, AR_DescId) != ATHEROS_VENDOR_ID) ||
|
||||
(MS(ads->ds_info, AR_TxRxDesc) != 1)) {
|
||||
ath_print(ath9k_hw_common(ah), ATH_DBG_XMIT,
|
||||
"Tx Descriptor error %x\n", ads->ds_info);
|
||||
memset(ads, 0, sizeof(*ads));
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
ts->qid = MS(ads->ds_info, AR_TxQcuNum);
|
||||
ts->desc_id = MS(ads->status1, AR_TxDescId);
|
||||
ts->ts_seqnum = MS(ads->status8, AR_SeqNum);
|
||||
ts->ts_tstamp = ads->status4;
|
||||
ts->ts_status = 0;
|
||||
ts->ts_flags = 0;
|
||||
|
||||
if (ads->status3 & AR_ExcessiveRetries)
|
||||
ts->ts_status |= ATH9K_TXERR_XRETRY;
|
||||
if (ads->status3 & AR_Filtered)
|
||||
ts->ts_status |= ATH9K_TXERR_FILT;
|
||||
if (ads->status3 & AR_FIFOUnderrun) {
|
||||
ts->ts_status |= ATH9K_TXERR_FIFO;
|
||||
ath9k_hw_updatetxtriglevel(ah, true);
|
||||
}
|
||||
if (ads->status8 & AR_TxOpExceeded)
|
||||
ts->ts_status |= ATH9K_TXERR_XTXOP;
|
||||
if (ads->status3 & AR_TxTimerExpired)
|
||||
ts->ts_status |= ATH9K_TXERR_TIMER_EXPIRED;
|
||||
|
||||
if (ads->status3 & AR_DescCfgErr)
|
||||
ts->ts_flags |= ATH9K_TX_DESC_CFG_ERR;
|
||||
if (ads->status3 & AR_TxDataUnderrun) {
|
||||
ts->ts_flags |= ATH9K_TX_DATA_UNDERRUN;
|
||||
ath9k_hw_updatetxtriglevel(ah, true);
|
||||
}
|
||||
if (ads->status3 & AR_TxDelimUnderrun) {
|
||||
ts->ts_flags |= ATH9K_TX_DELIM_UNDERRUN;
|
||||
ath9k_hw_updatetxtriglevel(ah, true);
|
||||
}
|
||||
if (ads->status2 & AR_TxBaStatus) {
|
||||
ts->ts_flags |= ATH9K_TX_BA;
|
||||
ts->ba_low = ads->status5;
|
||||
ts->ba_high = ads->status6;
|
||||
}
|
||||
|
||||
ts->ts_rateindex = MS(ads->status8, AR_FinalTxIdx);
|
||||
|
||||
ts->ts_rssi = MS(ads->status7, AR_TxRSSICombined);
|
||||
ts->ts_rssi_ctl0 = MS(ads->status2, AR_TxRSSIAnt00);
|
||||
ts->ts_rssi_ctl1 = MS(ads->status2, AR_TxRSSIAnt01);
|
||||
ts->ts_rssi_ctl2 = MS(ads->status2, AR_TxRSSIAnt02);
|
||||
ts->ts_rssi_ext0 = MS(ads->status7, AR_TxRSSIAnt10);
|
||||
ts->ts_rssi_ext1 = MS(ads->status7, AR_TxRSSIAnt11);
|
||||
ts->ts_rssi_ext2 = MS(ads->status7, AR_TxRSSIAnt12);
|
||||
ts->ts_shortretry = MS(ads->status3, AR_RTSFailCnt);
|
||||
ts->ts_longretry = MS(ads->status3, AR_DataFailCnt);
|
||||
ts->ts_virtcol = MS(ads->status3, AR_VirtRetryCnt);
|
||||
ts->ts_antenna = 0;
|
||||
|
||||
ts->tid = MS(ads->status8, AR_TxTid);
|
||||
|
||||
memset(ads, 0, sizeof(*ads));
|
||||
|
||||
return 0;
|
||||
}
|
||||
static void ar9003_hw_set11n_txdesc(struct ath_hw *ah, void *ds,
|
||||
u32 pktLen, enum ath9k_pkt_type type, u32 txPower,
|
||||
u32 keyIx, enum ath9k_key_type keyType, u32 flags)
|
||||
{
|
||||
|
||||
static void ar9003_hw_set11n_txdesc(struct ath_hw *ah, void *ds,
|
||||
u32 pktlen, enum ath9k_pkt_type type, u32 txpower,
|
||||
u32 keyIx, enum ath9k_key_type keyType, u32 flags)
|
||||
{
|
||||
struct ar9003_txc *ads = (struct ar9003_txc *) ds;
|
||||
|
||||
txpower += ah->txpower_indexoffset;
|
||||
if (txpower > 63)
|
||||
txpower = 63;
|
||||
|
||||
ads->ctl11 = (pktlen & AR_FrameLen)
|
||||
| (flags & ATH9K_TXDESC_VMF ? AR_VirtMoreFrag : 0)
|
||||
| SM(txpower, AR_XmitPower)
|
||||
| (flags & ATH9K_TXDESC_VEOL ? AR_VEOL : 0)
|
||||
| (flags & ATH9K_TXDESC_CLRDMASK ? AR_ClrDestMask : 0)
|
||||
| (keyIx != ATH9K_TXKEYIX_INVALID ? AR_DestIdxValid : 0)
|
||||
| (flags & ATH9K_TXDESC_LOWRXCHAIN ? AR_LowRxChain : 0);
|
||||
|
||||
ads->ctl12 =
|
||||
(keyIx != ATH9K_TXKEYIX_INVALID ? SM(keyIx, AR_DestIdx) : 0)
|
||||
| SM(type, AR_FrameType)
|
||||
| (flags & ATH9K_TXDESC_NOACK ? AR_NoAck : 0)
|
||||
| (flags & ATH9K_TXDESC_EXT_ONLY ? AR_ExtOnly : 0)
|
||||
| (flags & ATH9K_TXDESC_EXT_AND_CTL ? AR_ExtAndCtl : 0);
|
||||
|
||||
ads->ctl17 = SM(keyType, AR_EncrType);
|
||||
ads->ctl18 = 0;
|
||||
ads->ctl19 = AR_Not_Sounding;
|
||||
|
||||
ads->ctl20 = 0;
|
||||
ads->ctl21 = 0;
|
||||
ads->ctl22 = 0;
|
||||
}
|
||||
|
||||
static void ar9003_hw_set11n_ratescenario(struct ath_hw *ah, void *ds,
|
||||
@ -194,41 +340,119 @@ static void ar9003_hw_set11n_ratescenario(struct ath_hw *ah, void *ds,
|
||||
struct ath9k_11n_rate_series series[],
|
||||
u32 nseries, u32 flags)
|
||||
{
|
||||
struct ar9003_txc *ads = (struct ar9003_txc *) ds;
|
||||
struct ar9003_txc *last_ads = (struct ar9003_txc *) lastds;
|
||||
u_int32_t ctl11;
|
||||
|
||||
if (flags & (ATH9K_TXDESC_RTSENA | ATH9K_TXDESC_CTSENA)) {
|
||||
ctl11 = ads->ctl11;
|
||||
|
||||
if (flags & ATH9K_TXDESC_RTSENA) {
|
||||
ctl11 &= ~AR_CTSEnable;
|
||||
ctl11 |= AR_RTSEnable;
|
||||
} else {
|
||||
ctl11 &= ~AR_RTSEnable;
|
||||
ctl11 |= AR_CTSEnable;
|
||||
}
|
||||
|
||||
ads->ctl11 = ctl11;
|
||||
} else {
|
||||
ads->ctl11 = (ads->ctl11 & ~(AR_RTSEnable | AR_CTSEnable));
|
||||
}
|
||||
|
||||
ads->ctl13 = set11nTries(series, 0)
|
||||
| set11nTries(series, 1)
|
||||
| set11nTries(series, 2)
|
||||
| set11nTries(series, 3)
|
||||
| (durUpdateEn ? AR_DurUpdateEna : 0)
|
||||
| SM(0, AR_BurstDur);
|
||||
|
||||
ads->ctl14 = set11nRate(series, 0)
|
||||
| set11nRate(series, 1)
|
||||
| set11nRate(series, 2)
|
||||
| set11nRate(series, 3);
|
||||
|
||||
ads->ctl15 = set11nPktDurRTSCTS(series, 0)
|
||||
| set11nPktDurRTSCTS(series, 1);
|
||||
|
||||
ads->ctl16 = set11nPktDurRTSCTS(series, 2)
|
||||
| set11nPktDurRTSCTS(series, 3);
|
||||
|
||||
ads->ctl18 = set11nRateFlags(series, 0)
|
||||
| set11nRateFlags(series, 1)
|
||||
| set11nRateFlags(series, 2)
|
||||
| set11nRateFlags(series, 3)
|
||||
| SM(rtsctsRate, AR_RTSCTSRate);
|
||||
ads->ctl19 = AR_Not_Sounding;
|
||||
|
||||
last_ads->ctl13 = ads->ctl13;
|
||||
last_ads->ctl14 = ads->ctl14;
|
||||
}
|
||||
|
||||
static void ar9003_hw_set11n_aggr_first(struct ath_hw *ah, void *ds,
|
||||
u32 aggrLen)
|
||||
{
|
||||
struct ar9003_txc *ads = (struct ar9003_txc *) ds;
|
||||
|
||||
ads->ctl12 |= (AR_IsAggr | AR_MoreAggr);
|
||||
|
||||
ads->ctl17 &= ~AR_AggrLen;
|
||||
ads->ctl17 |= SM(aggrLen, AR_AggrLen);
|
||||
}
|
||||
|
||||
static void ar9003_hw_set11n_aggr_middle(struct ath_hw *ah, void *ds,
|
||||
u32 numDelims)
|
||||
{
|
||||
struct ar9003_txc *ads = (struct ar9003_txc *) ds;
|
||||
unsigned int ctl17;
|
||||
|
||||
ads->ctl12 |= (AR_IsAggr | AR_MoreAggr);
|
||||
|
||||
/*
|
||||
* We use a stack variable to manipulate ctl6 to reduce uncached
|
||||
* read modify, modfiy, write.
|
||||
*/
|
||||
ctl17 = ads->ctl17;
|
||||
ctl17 &= ~AR_PadDelim;
|
||||
ctl17 |= SM(numDelims, AR_PadDelim);
|
||||
ads->ctl17 = ctl17;
|
||||
}
|
||||
|
||||
static void ar9003_hw_set11n_aggr_last(struct ath_hw *ah, void *ds)
|
||||
{
|
||||
struct ar9003_txc *ads = (struct ar9003_txc *) ds;
|
||||
|
||||
ads->ctl12 |= AR_IsAggr;
|
||||
ads->ctl12 &= ~AR_MoreAggr;
|
||||
ads->ctl17 &= ~AR_PadDelim;
|
||||
}
|
||||
|
||||
static void ar9003_hw_clr11n_aggr(struct ath_hw *ah, void *ds)
|
||||
{
|
||||
struct ar9003_txc *ads = (struct ar9003_txc *) ds;
|
||||
|
||||
ads->ctl12 &= (~AR_IsAggr & ~AR_MoreAggr);
|
||||
}
|
||||
|
||||
static void ar9003_hw_set11n_burstduration(struct ath_hw *ah, void *ds,
|
||||
u32 burstDuration)
|
||||
{
|
||||
struct ar9003_txc *ads = (struct ar9003_txc *) ds;
|
||||
|
||||
ads->ctl13 &= ~AR_BurstDur;
|
||||
ads->ctl13 |= SM(burstDuration, AR_BurstDur);
|
||||
|
||||
}
|
||||
|
||||
static void ar9003_hw_set11n_virtualmorefrag(struct ath_hw *ah, void *ds,
|
||||
u32 vmf)
|
||||
u32 vmf)
|
||||
{
|
||||
struct ar9003_txc *ads = (struct ar9003_txc *) ds;
|
||||
|
||||
if (vmf)
|
||||
ads->ctl11 |= AR_VirtMoreFrag;
|
||||
else
|
||||
ads->ctl11 &= ~AR_VirtMoreFrag;
|
||||
}
|
||||
|
||||
void ar9003_hw_attach_mac_ops(struct ath_hw *hw)
|
||||
|
@ -20,7 +20,25 @@
|
||||
#define AR_DescId 0xffff0000
|
||||
#define AR_DescId_S 16
|
||||
#define AR_CtrlStat 0x00004000
|
||||
#define AR_CtrlStat_S 14
|
||||
#define AR_TxRxDesc 0x00008000
|
||||
#define AR_TxRxDesc_S 15
|
||||
#define AR_TxQcuNum 0x00000f00
|
||||
#define AR_TxQcuNum_S 8
|
||||
|
||||
#define AR_BufLen 0x0fff0000
|
||||
#define AR_BufLen_S 16
|
||||
|
||||
#define AR_TxDescId 0xffff0000
|
||||
#define AR_TxDescId_S 16
|
||||
#define AR_TxPtrChkSum 0x0000ffff
|
||||
|
||||
#define AR_TxTid 0xf0000000
|
||||
#define AR_TxTid_S 28
|
||||
|
||||
#define AR_LowRxChain 0x00004000
|
||||
|
||||
#define AR_Not_Sounding 0x20000000
|
||||
|
||||
#define MAP_ISR_S2_CST 6
|
||||
#define MAP_ISR_S2_GTT 6
|
||||
@ -30,6 +48,8 @@
|
||||
#define MAP_ISR_S2_DTIM 7
|
||||
#define MAP_ISR_S2_TSFOOR 4
|
||||
|
||||
#define AR9003TXC_CONST(_ds) ((const struct ar9003_txc *) _ds)
|
||||
|
||||
struct ar9003_rxs {
|
||||
u32 ds_info;
|
||||
u32 status1;
|
||||
|
@ -116,7 +116,10 @@ struct ath_tx_status {
|
||||
int8_t ts_rssi_ext0;
|
||||
int8_t ts_rssi_ext1;
|
||||
int8_t ts_rssi_ext2;
|
||||
u8 pad[3];
|
||||
u8 qid;
|
||||
u16 desc_id;
|
||||
u8 tid;
|
||||
u8 pad[2];
|
||||
u32 ba_low;
|
||||
u32 ba_high;
|
||||
u32 evm0;
|
||||
@ -260,7 +263,7 @@ struct ath_desc {
|
||||
#define ATH9K_TXDESC_EXT_AND_CTL 0x0080
|
||||
#define ATH9K_TXDESC_VMF 0x0100
|
||||
#define ATH9K_TXDESC_FRAG_IS_ON 0x0200
|
||||
#define ATH9K_TXDESC_CAB 0x0400
|
||||
#define ATH9K_TXDESC_LOWRXCHAIN 0x0400
|
||||
|
||||
#define ATH9K_RXDESC_INTREQ 0x0020
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user