|
@@ -21,6 +21,132 @@ static void ar9003_hw_rx_enable(struct ath_hw *hw)
|
|
REG_WRITE(hw, AR_CR, 0);
|
|
REG_WRITE(hw, AR_CR, 0);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static void
|
|
|
|
+ar9003_set_txdesc(struct ath_hw *ah, void *ds, struct ath_tx_info *i)
|
|
|
|
+{
|
|
|
|
+ struct ar9003_txc *ads = ds;
|
|
|
|
+ int checksum = 0;
|
|
|
|
+ u32 val, ctl12, ctl17;
|
|
|
|
+
|
|
|
|
+ val = (ATHEROS_VENDOR_ID << AR_DescId_S) |
|
|
|
|
+ (1 << AR_TxRxDesc_S) |
|
|
|
|
+ (1 << AR_CtrlStat_S) |
|
|
|
|
+ (i->qcu << AR_TxQcuNum_S) | 0x17;
|
|
|
|
+
|
|
|
|
+ checksum += val;
|
|
|
|
+ ACCESS_ONCE(ads->info) = val;
|
|
|
|
+
|
|
|
|
+ checksum += i->link;
|
|
|
|
+ ACCESS_ONCE(ads->link) = i->link;
|
|
|
|
+
|
|
|
|
+ checksum += i->buf_addr[0];
|
|
|
|
+ ACCESS_ONCE(ads->data0) = i->buf_addr[0];
|
|
|
|
+ checksum += i->buf_addr[1];
|
|
|
|
+ ACCESS_ONCE(ads->data1) = i->buf_addr[1];
|
|
|
|
+ checksum += i->buf_addr[2];
|
|
|
|
+ ACCESS_ONCE(ads->data2) = i->buf_addr[2];
|
|
|
|
+ checksum += i->buf_addr[3];
|
|
|
|
+ ACCESS_ONCE(ads->data3) = i->buf_addr[3];
|
|
|
|
+
|
|
|
|
+ checksum += (val = (i->buf_len[0] << AR_BufLen_S) & AR_BufLen);
|
|
|
|
+ ACCESS_ONCE(ads->ctl3) = val;
|
|
|
|
+ checksum += (val = (i->buf_len[1] << AR_BufLen_S) & AR_BufLen);
|
|
|
|
+ ACCESS_ONCE(ads->ctl5) = val;
|
|
|
|
+ checksum += (val = (i->buf_len[2] << AR_BufLen_S) & AR_BufLen);
|
|
|
|
+ ACCESS_ONCE(ads->ctl7) = val;
|
|
|
|
+ checksum += (val = (i->buf_len[3] << AR_BufLen_S) & AR_BufLen);
|
|
|
|
+ ACCESS_ONCE(ads->ctl9) = val;
|
|
|
|
+
|
|
|
|
+ checksum = (u16) (((checksum & 0xffff) + (checksum >> 16)) & 0xffff);
|
|
|
|
+ ACCESS_ONCE(ads->ctl10) = checksum;
|
|
|
|
+
|
|
|
|
+ if (i->is_first || i->is_last) {
|
|
|
|
+ ACCESS_ONCE(ads->ctl13) = set11nTries(i->rates, 0)
|
|
|
|
+ | set11nTries(i->rates, 1)
|
|
|
|
+ | set11nTries(i->rates, 2)
|
|
|
|
+ | set11nTries(i->rates, 3)
|
|
|
|
+ | (i->dur_update ? AR_DurUpdateEna : 0)
|
|
|
|
+ | SM(0, AR_BurstDur);
|
|
|
|
+
|
|
|
|
+ ACCESS_ONCE(ads->ctl14) = set11nRate(i->rates, 0)
|
|
|
|
+ | set11nRate(i->rates, 1)
|
|
|
|
+ | set11nRate(i->rates, 2)
|
|
|
|
+ | set11nRate(i->rates, 3);
|
|
|
|
+ } else {
|
|
|
|
+ ACCESS_ONCE(ads->ctl13) = 0;
|
|
|
|
+ ACCESS_ONCE(ads->ctl14) = 0;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ ads->ctl20 = 0;
|
|
|
|
+ ads->ctl21 = 0;
|
|
|
|
+ ads->ctl22 = 0;
|
|
|
|
+
|
|
|
|
+ ctl17 = SM(i->keytype, AR_EncrType);
|
|
|
|
+ if (!i->is_first) {
|
|
|
|
+ ACCESS_ONCE(ads->ctl11) = 0;
|
|
|
|
+ ACCESS_ONCE(ads->ctl12) = i->is_last ? 0 : AR_TxMore;
|
|
|
|
+ ACCESS_ONCE(ads->ctl15) = 0;
|
|
|
|
+ ACCESS_ONCE(ads->ctl16) = 0;
|
|
|
|
+ ACCESS_ONCE(ads->ctl17) = ctl17;
|
|
|
|
+ ACCESS_ONCE(ads->ctl18) = 0;
|
|
|
|
+ ACCESS_ONCE(ads->ctl19) = 0;
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ ACCESS_ONCE(ads->ctl11) = (i->pkt_len & AR_FrameLen)
|
|
|
|
+ | (i->flags & ATH9K_TXDESC_VMF ? AR_VirtMoreFrag : 0)
|
|
|
|
+ | SM(i->txpower, AR_XmitPower)
|
|
|
|
+ | (i->flags & ATH9K_TXDESC_VEOL ? AR_VEOL : 0)
|
|
|
|
+ | (i->keyix != ATH9K_TXKEYIX_INVALID ? AR_DestIdxValid : 0)
|
|
|
|
+ | (i->flags & ATH9K_TXDESC_LOWRXCHAIN ? AR_LowRxChain : 0)
|
|
|
|
+ | (i->flags & ATH9K_TXDESC_CLRDMASK ? AR_ClrDestMask : 0)
|
|
|
|
+ | (i->flags & ATH9K_TXDESC_RTSENA ? AR_RTSEnable :
|
|
|
|
+ (i->flags & ATH9K_TXDESC_CTSENA ? AR_CTSEnable : 0));
|
|
|
|
+
|
|
|
|
+ ctl12 = (i->keyix != ATH9K_TXKEYIX_INVALID ?
|
|
|
|
+ SM(i->keyix, AR_DestIdx) : 0)
|
|
|
|
+ | SM(i->type, AR_FrameType)
|
|
|
|
+ | (i->flags & ATH9K_TXDESC_NOACK ? AR_NoAck : 0)
|
|
|
|
+ | (i->flags & ATH9K_TXDESC_EXT_ONLY ? AR_ExtOnly : 0)
|
|
|
|
+ | (i->flags & ATH9K_TXDESC_EXT_AND_CTL ? AR_ExtAndCtl : 0);
|
|
|
|
+
|
|
|
|
+ ctl17 |= (i->flags & ATH9K_TXDESC_LDPC ? AR_LDPC : 0);
|
|
|
|
+ switch (i->aggr) {
|
|
|
|
+ case AGGR_BUF_FIRST:
|
|
|
|
+ ctl17 |= SM(i->aggr_len, AR_AggrLen);
|
|
|
|
+ /* fall through */
|
|
|
|
+ case AGGR_BUF_MIDDLE:
|
|
|
|
+ ctl12 |= AR_IsAggr | AR_MoreAggr;
|
|
|
|
+ ctl17 |= SM(i->ndelim, AR_PadDelim);
|
|
|
|
+ break;
|
|
|
|
+ case AGGR_BUF_LAST:
|
|
|
|
+ ctl12 |= AR_IsAggr;
|
|
|
|
+ break;
|
|
|
|
+ case AGGR_BUF_NONE:
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ val = (i->flags & ATH9K_TXDESC_PAPRD) >> ATH9K_TXDESC_PAPRD_S;
|
|
|
|
+ ctl12 |= SM(val, AR_PAPRDChainMask);
|
|
|
|
+
|
|
|
|
+ ACCESS_ONCE(ads->ctl12) = ctl12;
|
|
|
|
+ ACCESS_ONCE(ads->ctl17) = ctl17;
|
|
|
|
+
|
|
|
|
+ ACCESS_ONCE(ads->ctl15) = set11nPktDurRTSCTS(i->rates, 0)
|
|
|
|
+ | set11nPktDurRTSCTS(i->rates, 1);
|
|
|
|
+
|
|
|
|
+ ACCESS_ONCE(ads->ctl16) = set11nPktDurRTSCTS(i->rates, 2)
|
|
|
|
+ | set11nPktDurRTSCTS(i->rates, 3);
|
|
|
|
+
|
|
|
|
+ ACCESS_ONCE(ads->ctl18) = set11nRateFlags(i->rates, 0)
|
|
|
|
+ | set11nRateFlags(i->rates, 1)
|
|
|
|
+ | set11nRateFlags(i->rates, 2)
|
|
|
|
+ | set11nRateFlags(i->rates, 3)
|
|
|
|
+ | SM(i->rtscts_rate, AR_RTSCTSRate);
|
|
|
|
+
|
|
|
|
+ ACCESS_ONCE(ads->ctl19) = AR_Not_Sounding;
|
|
|
|
+}
|
|
|
|
+
|
|
static u16 ar9003_calc_ptr_chksum(struct ar9003_txc *ads)
|
|
static u16 ar9003_calc_ptr_chksum(struct ar9003_txc *ads)
|
|
{
|
|
{
|
|
int checksum;
|
|
int checksum;
|
|
@@ -471,6 +597,7 @@ void ar9003_hw_attach_mac_ops(struct ath_hw *hw)
|
|
ops->rx_enable = ar9003_hw_rx_enable;
|
|
ops->rx_enable = ar9003_hw_rx_enable;
|
|
ops->set_desc_link = ar9003_hw_set_desc_link;
|
|
ops->set_desc_link = ar9003_hw_set_desc_link;
|
|
ops->get_isr = ar9003_hw_get_isr;
|
|
ops->get_isr = ar9003_hw_get_isr;
|
|
|
|
+ ops->set_txdesc = ar9003_set_txdesc;
|
|
ops->fill_txdesc = ar9003_hw_fill_txdesc;
|
|
ops->fill_txdesc = ar9003_hw_fill_txdesc;
|
|
ops->proc_txdesc = ar9003_hw_proc_txdesc;
|
|
ops->proc_txdesc = ar9003_hw_proc_txdesc;
|
|
ops->set11n_txdesc = ar9003_hw_set11n_txdesc;
|
|
ops->set11n_txdesc = ar9003_hw_set11n_txdesc;
|