Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Copyright (c) 2010-2011 Atheros Communications Inc.
0003  *
0004  * Permission to use, copy, modify, and/or distribute this software for any
0005  * purpose with or without fee is hereby granted, provided that the above
0006  * copyright notice and this permission notice appear in all copies.
0007  *
0008  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
0009  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
0010  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
0011  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
0012  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
0013  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
0014  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
0015  */
0016 #include <linux/export.h>
0017 #include "hw.h"
0018 #include "ar9003_mac.h"
0019 #include "ar9003_mci.h"
0020 
0021 static void ar9003_hw_rx_enable(struct ath_hw *hw)
0022 {
0023     REG_WRITE(hw, AR_CR, 0);
0024 }
0025 
0026 static void
0027 ar9003_set_txdesc(struct ath_hw *ah, void *ds, struct ath_tx_info *i)
0028 {
0029     struct ar9003_txc *ads = ds;
0030     int checksum = 0;
0031     u32 val, ctl12, ctl17;
0032     u8 desc_len;
0033 
0034     desc_len = ((AR_SREV_9462(ah) || AR_SREV_9565(ah)) ? 0x18 : 0x17);
0035 
0036     val = (ATHEROS_VENDOR_ID << AR_DescId_S) |
0037           (1 << AR_TxRxDesc_S) |
0038           (1 << AR_CtrlStat_S) |
0039           (i->qcu << AR_TxQcuNum_S) | desc_len;
0040 
0041     checksum += val;
0042     WRITE_ONCE(ads->info, val);
0043 
0044     checksum += i->link;
0045     WRITE_ONCE(ads->link, i->link);
0046 
0047     checksum += i->buf_addr[0];
0048     WRITE_ONCE(ads->data0, i->buf_addr[0]);
0049     checksum += i->buf_addr[1];
0050     WRITE_ONCE(ads->data1, i->buf_addr[1]);
0051     checksum += i->buf_addr[2];
0052     WRITE_ONCE(ads->data2, i->buf_addr[2]);
0053     checksum += i->buf_addr[3];
0054     WRITE_ONCE(ads->data3, i->buf_addr[3]);
0055 
0056     checksum += (val = (i->buf_len[0] << AR_BufLen_S) & AR_BufLen);
0057     WRITE_ONCE(ads->ctl3, val);
0058     checksum += (val = (i->buf_len[1] << AR_BufLen_S) & AR_BufLen);
0059     WRITE_ONCE(ads->ctl5, val);
0060     checksum += (val = (i->buf_len[2] << AR_BufLen_S) & AR_BufLen);
0061     WRITE_ONCE(ads->ctl7, val);
0062     checksum += (val = (i->buf_len[3] << AR_BufLen_S) & AR_BufLen);
0063     WRITE_ONCE(ads->ctl9, val);
0064 
0065     checksum = (u16) (((checksum & 0xffff) + (checksum >> 16)) & 0xffff);
0066     WRITE_ONCE(ads->ctl10, checksum);
0067 
0068     if (i->is_first || i->is_last) {
0069         WRITE_ONCE(ads->ctl13, set11nTries(i->rates, 0)
0070             | set11nTries(i->rates, 1)
0071             | set11nTries(i->rates, 2)
0072             | set11nTries(i->rates, 3)
0073             | (i->dur_update ? AR_DurUpdateEna : 0)
0074             | SM(0, AR_BurstDur));
0075 
0076         WRITE_ONCE(ads->ctl14, set11nRate(i->rates, 0)
0077             | set11nRate(i->rates, 1)
0078             | set11nRate(i->rates, 2)
0079             | set11nRate(i->rates, 3));
0080     } else {
0081         WRITE_ONCE(ads->ctl13, 0);
0082         WRITE_ONCE(ads->ctl14, 0);
0083     }
0084 
0085     ads->ctl20 = 0;
0086     ads->ctl21 = 0;
0087     ads->ctl22 = 0;
0088     ads->ctl23 = 0;
0089 
0090     ctl17 = SM(i->keytype, AR_EncrType);
0091     if (!i->is_first) {
0092         WRITE_ONCE(ads->ctl11, 0);
0093         WRITE_ONCE(ads->ctl12, i->is_last ? 0 : AR_TxMore);
0094         WRITE_ONCE(ads->ctl15, 0);
0095         WRITE_ONCE(ads->ctl16, 0);
0096         WRITE_ONCE(ads->ctl17, ctl17);
0097         WRITE_ONCE(ads->ctl18, 0);
0098         WRITE_ONCE(ads->ctl19, 0);
0099         return;
0100     }
0101 
0102     WRITE_ONCE(ads->ctl11, (i->pkt_len & AR_FrameLen)
0103         | (i->flags & ATH9K_TXDESC_VMF ? AR_VirtMoreFrag : 0)
0104         | SM(i->txpower[0], AR_XmitPower0)
0105         | (i->flags & ATH9K_TXDESC_VEOL ? AR_VEOL : 0)
0106         | (i->keyix != ATH9K_TXKEYIX_INVALID ? AR_DestIdxValid : 0)
0107         | (i->flags & ATH9K_TXDESC_LOWRXCHAIN ? AR_LowRxChain : 0)
0108         | (i->flags & ATH9K_TXDESC_CLRDMASK ? AR_ClrDestMask : 0)
0109         | (i->flags & ATH9K_TXDESC_RTSENA ? AR_RTSEnable :
0110            (i->flags & ATH9K_TXDESC_CTSENA ? AR_CTSEnable : 0)));
0111 
0112     ctl12 = (i->keyix != ATH9K_TXKEYIX_INVALID ?
0113          SM(i->keyix, AR_DestIdx) : 0)
0114         | SM(i->type, AR_FrameType)
0115         | (i->flags & ATH9K_TXDESC_NOACK ? AR_NoAck : 0)
0116         | (i->flags & ATH9K_TXDESC_EXT_ONLY ? AR_ExtOnly : 0)
0117         | (i->flags & ATH9K_TXDESC_EXT_AND_CTL ? AR_ExtAndCtl : 0);
0118 
0119     ctl17 |= (i->flags & ATH9K_TXDESC_LDPC ? AR_LDPC : 0);
0120     switch (i->aggr) {
0121     case AGGR_BUF_FIRST:
0122         ctl17 |= SM(i->aggr_len, AR_AggrLen);
0123         fallthrough;
0124     case AGGR_BUF_MIDDLE:
0125         ctl12 |= AR_IsAggr | AR_MoreAggr;
0126         ctl17 |= SM(i->ndelim, AR_PadDelim);
0127         break;
0128     case AGGR_BUF_LAST:
0129         ctl12 |= AR_IsAggr;
0130         break;
0131     case AGGR_BUF_NONE:
0132         break;
0133     }
0134 
0135     val = (i->flags & ATH9K_TXDESC_PAPRD) >> ATH9K_TXDESC_PAPRD_S;
0136     ctl12 |= SM(val, AR_PAPRDChainMask);
0137 
0138     WRITE_ONCE(ads->ctl12, ctl12);
0139     WRITE_ONCE(ads->ctl17, ctl17);
0140 
0141     WRITE_ONCE(ads->ctl15, set11nPktDurRTSCTS(i->rates, 0)
0142         | set11nPktDurRTSCTS(i->rates, 1));
0143 
0144     WRITE_ONCE(ads->ctl16, set11nPktDurRTSCTS(i->rates, 2)
0145         | set11nPktDurRTSCTS(i->rates, 3));
0146 
0147     WRITE_ONCE(ads->ctl18,
0148           set11nRateFlags(i->rates, 0) | set11nChainSel(i->rates, 0)
0149         | set11nRateFlags(i->rates, 1) | set11nChainSel(i->rates, 1)
0150         | set11nRateFlags(i->rates, 2) | set11nChainSel(i->rates, 2)
0151         | set11nRateFlags(i->rates, 3) | set11nChainSel(i->rates, 3)
0152         | SM(i->rtscts_rate, AR_RTSCTSRate));
0153 
0154     WRITE_ONCE(ads->ctl19, AR_Not_Sounding);
0155 
0156     WRITE_ONCE(ads->ctl20, SM(i->txpower[1], AR_XmitPower1));
0157     WRITE_ONCE(ads->ctl21, SM(i->txpower[2], AR_XmitPower2));
0158     WRITE_ONCE(ads->ctl22, SM(i->txpower[3], AR_XmitPower3));
0159 }
0160 
0161 static u16 ar9003_calc_ptr_chksum(struct ar9003_txc *ads)
0162 {
0163     int checksum;
0164 
0165     checksum = ads->info + ads->link
0166         + ads->data0 + ads->ctl3
0167         + ads->data1 + ads->ctl5
0168         + ads->data2 + ads->ctl7
0169         + ads->data3 + ads->ctl9;
0170 
0171     return ((checksum & 0xffff) + (checksum >> 16)) & AR_TxPtrChkSum;
0172 }
0173 
0174 static void ar9003_hw_set_desc_link(void *ds, u32 ds_link)
0175 {
0176     struct ar9003_txc *ads = ds;
0177 
0178     ads->link = ds_link;
0179     ads->ctl10 &= ~AR_TxPtrChkSum;
0180     ads->ctl10 |= ar9003_calc_ptr_chksum(ads);
0181 }
0182 
0183 static bool ar9003_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked,
0184                   u32 *sync_cause_p)
0185 {
0186     u32 isr = 0;
0187     u32 mask2 = 0;
0188     struct ath9k_hw_capabilities *pCap = &ah->caps;
0189     struct ath_common *common = ath9k_hw_common(ah);
0190     u32 sync_cause = 0, async_cause, async_mask = AR_INTR_MAC_IRQ;
0191     bool fatal_int;
0192 
0193     if (ath9k_hw_mci_is_enabled(ah))
0194         async_mask |= AR_INTR_ASYNC_MASK_MCI;
0195 
0196     async_cause = REG_READ(ah, AR_INTR_ASYNC_CAUSE);
0197 
0198     if (async_cause & async_mask) {
0199         if ((REG_READ(ah, AR_RTC_STATUS) & AR_RTC_STATUS_M)
0200                 == AR_RTC_STATUS_ON)
0201             isr = REG_READ(ah, AR_ISR);
0202     }
0203 
0204 
0205     sync_cause = REG_READ(ah, AR_INTR_SYNC_CAUSE) & AR_INTR_SYNC_DEFAULT;
0206 
0207     *masked = 0;
0208 
0209     if (!isr && !sync_cause && !async_cause)
0210         return false;
0211 
0212     if (isr) {
0213         if (isr & AR_ISR_BCNMISC) {
0214             u32 isr2;
0215             isr2 = REG_READ(ah, AR_ISR_S2);
0216 
0217             mask2 |= ((isr2 & AR_ISR_S2_TIM) >>
0218                   MAP_ISR_S2_TIM);
0219             mask2 |= ((isr2 & AR_ISR_S2_DTIM) >>
0220                   MAP_ISR_S2_DTIM);
0221             mask2 |= ((isr2 & AR_ISR_S2_DTIMSYNC) >>
0222                   MAP_ISR_S2_DTIMSYNC);
0223             mask2 |= ((isr2 & AR_ISR_S2_CABEND) >>
0224                   MAP_ISR_S2_CABEND);
0225             mask2 |= ((isr2 & AR_ISR_S2_GTT) <<
0226                   MAP_ISR_S2_GTT);
0227             mask2 |= ((isr2 & AR_ISR_S2_CST) <<
0228                   MAP_ISR_S2_CST);
0229             mask2 |= ((isr2 & AR_ISR_S2_TSFOOR) >>
0230                   MAP_ISR_S2_TSFOOR);
0231             mask2 |= ((isr2 & AR_ISR_S2_BB_WATCHDOG) >>
0232                   MAP_ISR_S2_BB_WATCHDOG);
0233 
0234             if (!(pCap->hw_caps & ATH9K_HW_CAP_RAC_SUPPORTED)) {
0235                 REG_WRITE(ah, AR_ISR_S2, isr2);
0236                 isr &= ~AR_ISR_BCNMISC;
0237             }
0238         }
0239 
0240         if ((pCap->hw_caps & ATH9K_HW_CAP_RAC_SUPPORTED))
0241             isr = REG_READ(ah, AR_ISR_RAC);
0242 
0243         if (isr == 0xffffffff) {
0244             *masked = 0;
0245             return false;
0246         }
0247 
0248         *masked = isr & ATH9K_INT_COMMON;
0249 
0250         if (ah->config.rx_intr_mitigation)
0251             if (isr & (AR_ISR_RXMINTR | AR_ISR_RXINTM))
0252                 *masked |= ATH9K_INT_RXLP;
0253 
0254         if (ah->config.tx_intr_mitigation)
0255             if (isr & (AR_ISR_TXMINTR | AR_ISR_TXINTM))
0256                 *masked |= ATH9K_INT_TX;
0257 
0258         if (isr & (AR_ISR_LP_RXOK | AR_ISR_RXERR))
0259             *masked |= ATH9K_INT_RXLP;
0260 
0261         if (isr & AR_ISR_HP_RXOK)
0262             *masked |= ATH9K_INT_RXHP;
0263 
0264         if (isr & (AR_ISR_TXOK | AR_ISR_TXERR | AR_ISR_TXEOL)) {
0265             *masked |= ATH9K_INT_TX;
0266 
0267             if (!(pCap->hw_caps & ATH9K_HW_CAP_RAC_SUPPORTED)) {
0268                 u32 s0, s1;
0269                 s0 = REG_READ(ah, AR_ISR_S0);
0270                 REG_WRITE(ah, AR_ISR_S0, s0);
0271                 s1 = REG_READ(ah, AR_ISR_S1);
0272                 REG_WRITE(ah, AR_ISR_S1, s1);
0273 
0274                 isr &= ~(AR_ISR_TXOK | AR_ISR_TXERR |
0275                      AR_ISR_TXEOL);
0276             }
0277         }
0278 
0279         if (isr & AR_ISR_GENTMR) {
0280             u32 s5;
0281 
0282             if (pCap->hw_caps & ATH9K_HW_CAP_RAC_SUPPORTED)
0283                 s5 = REG_READ(ah, AR_ISR_S5_S);
0284             else
0285                 s5 = REG_READ(ah, AR_ISR_S5);
0286 
0287             ah->intr_gen_timer_trigger =
0288                 MS(s5, AR_ISR_S5_GENTIMER_TRIG);
0289 
0290             ah->intr_gen_timer_thresh =
0291                 MS(s5, AR_ISR_S5_GENTIMER_THRESH);
0292 
0293             if (ah->intr_gen_timer_trigger)
0294                 *masked |= ATH9K_INT_GENTIMER;
0295 
0296             if (!(pCap->hw_caps & ATH9K_HW_CAP_RAC_SUPPORTED)) {
0297                 REG_WRITE(ah, AR_ISR_S5, s5);
0298                 isr &= ~AR_ISR_GENTMR;
0299             }
0300 
0301         }
0302 
0303         *masked |= mask2;
0304 
0305         if (!(pCap->hw_caps & ATH9K_HW_CAP_RAC_SUPPORTED)) {
0306             REG_WRITE(ah, AR_ISR, isr);
0307 
0308             (void) REG_READ(ah, AR_ISR);
0309         }
0310 
0311         if (*masked & ATH9K_INT_BB_WATCHDOG)
0312             ar9003_hw_bb_watchdog_read(ah);
0313     }
0314 
0315     if (async_cause & AR_INTR_ASYNC_MASK_MCI)
0316         ar9003_mci_get_isr(ah, masked);
0317 
0318     if (sync_cause) {
0319         if (sync_cause_p)
0320             *sync_cause_p = sync_cause;
0321         fatal_int =
0322             (sync_cause &
0323              (AR_INTR_SYNC_HOST1_FATAL | AR_INTR_SYNC_HOST1_PERR))
0324             ? true : false;
0325 
0326         if (fatal_int) {
0327             if (sync_cause & AR_INTR_SYNC_HOST1_FATAL) {
0328                 ath_dbg(common, ANY,
0329                     "received PCI FATAL interrupt\n");
0330             }
0331             if (sync_cause & AR_INTR_SYNC_HOST1_PERR) {
0332                 ath_dbg(common, ANY,
0333                     "received PCI PERR interrupt\n");
0334             }
0335             *masked |= ATH9K_INT_FATAL;
0336         }
0337 
0338         if (sync_cause & AR_INTR_SYNC_RADM_CPL_TIMEOUT) {
0339             REG_WRITE(ah, AR_RC, AR_RC_HOSTIF);
0340             REG_WRITE(ah, AR_RC, 0);
0341             *masked |= ATH9K_INT_FATAL;
0342         }
0343 
0344         if (sync_cause & AR_INTR_SYNC_LOCAL_TIMEOUT)
0345             ath_dbg(common, INTERRUPT,
0346                 "AR_INTR_SYNC_LOCAL_TIMEOUT\n");
0347 
0348         REG_WRITE(ah, AR_INTR_SYNC_CAUSE_CLR, sync_cause);
0349         (void) REG_READ(ah, AR_INTR_SYNC_CAUSE_CLR);
0350 
0351     }
0352     return true;
0353 }
0354 
0355 static int ar9003_hw_proc_txdesc(struct ath_hw *ah, void *ds,
0356                  struct ath_tx_status *ts)
0357 {
0358     struct ar9003_txs *ads;
0359     u32 status;
0360 
0361     ads = &ah->ts_ring[ah->ts_tail];
0362 
0363     status = READ_ONCE(ads->status8);
0364     if ((status & AR_TxDone) == 0)
0365         return -EINPROGRESS;
0366 
0367     ah->ts_tail = (ah->ts_tail + 1) % ah->ts_size;
0368 
0369     if ((MS(ads->ds_info, AR_DescId) != ATHEROS_VENDOR_ID) ||
0370         (MS(ads->ds_info, AR_TxRxDesc) != 1)) {
0371         ath_dbg(ath9k_hw_common(ah), XMIT,
0372             "Tx Descriptor error %x\n", ads->ds_info);
0373         memset(ads, 0, sizeof(*ads));
0374         return -EIO;
0375     }
0376 
0377     ts->ts_rateindex = MS(status, AR_FinalTxIdx);
0378     ts->ts_seqnum = MS(status, AR_SeqNum);
0379     ts->tid = MS(status, AR_TxTid);
0380 
0381     ts->qid = MS(ads->ds_info, AR_TxQcuNum);
0382     ts->desc_id = MS(ads->status1, AR_TxDescId);
0383     ts->ts_tstamp = ads->status4;
0384     ts->ts_status = 0;
0385     ts->ts_flags  = 0;
0386 
0387     if (status & AR_TxOpExceeded)
0388         ts->ts_status |= ATH9K_TXERR_XTXOP;
0389     status = READ_ONCE(ads->status2);
0390     ts->ts_rssi_ctl0 = MS(status, AR_TxRSSIAnt00);
0391     ts->ts_rssi_ctl1 = MS(status, AR_TxRSSIAnt01);
0392     ts->ts_rssi_ctl2 = MS(status, AR_TxRSSIAnt02);
0393     if (status & AR_TxBaStatus) {
0394         ts->ts_flags |= ATH9K_TX_BA;
0395         ts->ba_low = ads->status5;
0396         ts->ba_high = ads->status6;
0397     }
0398 
0399     status = READ_ONCE(ads->status3);
0400     if (status & AR_ExcessiveRetries)
0401         ts->ts_status |= ATH9K_TXERR_XRETRY;
0402     if (status & AR_Filtered)
0403         ts->ts_status |= ATH9K_TXERR_FILT;
0404     if (status & AR_FIFOUnderrun) {
0405         ts->ts_status |= ATH9K_TXERR_FIFO;
0406         ath9k_hw_updatetxtriglevel(ah, true);
0407     }
0408     if (status & AR_TxTimerExpired)
0409         ts->ts_status |= ATH9K_TXERR_TIMER_EXPIRED;
0410     if (status & AR_DescCfgErr)
0411         ts->ts_flags |= ATH9K_TX_DESC_CFG_ERR;
0412     if (status & AR_TxDataUnderrun) {
0413         ts->ts_flags |= ATH9K_TX_DATA_UNDERRUN;
0414         ath9k_hw_updatetxtriglevel(ah, true);
0415     }
0416     if (status & AR_TxDelimUnderrun) {
0417         ts->ts_flags |= ATH9K_TX_DELIM_UNDERRUN;
0418         ath9k_hw_updatetxtriglevel(ah, true);
0419     }
0420     ts->ts_shortretry = MS(status, AR_RTSFailCnt);
0421     ts->ts_longretry = MS(status, AR_DataFailCnt);
0422     ts->ts_virtcol = MS(status, AR_VirtRetryCnt);
0423 
0424     status = READ_ONCE(ads->status7);
0425     ts->ts_rssi = MS(status, AR_TxRSSICombined);
0426     ts->ts_rssi_ext0 = MS(status, AR_TxRSSIAnt10);
0427     ts->ts_rssi_ext1 = MS(status, AR_TxRSSIAnt11);
0428     ts->ts_rssi_ext2 = MS(status, AR_TxRSSIAnt12);
0429 
0430     memset(ads, 0, sizeof(*ads));
0431 
0432     return 0;
0433 }
0434 
0435 static int ar9003_hw_get_duration(struct ath_hw *ah, const void *ds, int index)
0436 {
0437     const struct ar9003_txc *adc = ds;
0438 
0439     switch (index) {
0440     case 0:
0441         return MS(READ_ONCE(adc->ctl15), AR_PacketDur0);
0442     case 1:
0443         return MS(READ_ONCE(adc->ctl15), AR_PacketDur1);
0444     case 2:
0445         return MS(READ_ONCE(adc->ctl16), AR_PacketDur2);
0446     case 3:
0447         return MS(READ_ONCE(adc->ctl16), AR_PacketDur3);
0448     default:
0449         return 0;
0450     }
0451 }
0452 
0453 void ar9003_hw_attach_mac_ops(struct ath_hw *hw)
0454 {
0455     struct ath_hw_ops *ops = ath9k_hw_ops(hw);
0456 
0457     ops->rx_enable = ar9003_hw_rx_enable;
0458     ops->set_desc_link = ar9003_hw_set_desc_link;
0459     ops->get_isr = ar9003_hw_get_isr;
0460     ops->set_txdesc = ar9003_set_txdesc;
0461     ops->proc_txdesc = ar9003_hw_proc_txdesc;
0462     ops->get_duration = ar9003_hw_get_duration;
0463 }
0464 
0465 void ath9k_hw_set_rx_bufsize(struct ath_hw *ah, u16 buf_size)
0466 {
0467     REG_WRITE(ah, AR_DATABUF_SIZE, buf_size & AR_DATABUF_SIZE_MASK);
0468 }
0469 EXPORT_SYMBOL(ath9k_hw_set_rx_bufsize);
0470 
0471 void ath9k_hw_addrxbuf_edma(struct ath_hw *ah, u32 rxdp,
0472                 enum ath9k_rx_qtype qtype)
0473 {
0474     if (qtype == ATH9K_RX_QUEUE_HP)
0475         REG_WRITE(ah, AR_HP_RXDP, rxdp);
0476     else
0477         REG_WRITE(ah, AR_LP_RXDP, rxdp);
0478 }
0479 EXPORT_SYMBOL(ath9k_hw_addrxbuf_edma);
0480 
0481 int ath9k_hw_process_rxdesc_edma(struct ath_hw *ah, struct ath_rx_status *rxs,
0482                  void *buf_addr)
0483 {
0484     struct ar9003_rxs *rxsp = buf_addr;
0485     unsigned int phyerr;
0486 
0487     if ((rxsp->status11 & AR_RxDone) == 0)
0488         return -EINPROGRESS;
0489 
0490     if (MS(rxsp->ds_info, AR_DescId) != 0x168c)
0491         return -EINVAL;
0492 
0493     if ((rxsp->ds_info & (AR_TxRxDesc | AR_CtrlStat)) != 0)
0494         return -EINPROGRESS;
0495 
0496     rxs->rs_status = 0;
0497     rxs->rs_flags =  0;
0498     rxs->enc_flags = 0;
0499     rxs->bw = RATE_INFO_BW_20;
0500 
0501     rxs->rs_datalen = rxsp->status2 & AR_DataLen;
0502     rxs->rs_tstamp =  rxsp->status3;
0503 
0504     /* XXX: Keycache */
0505     rxs->rs_rssi = MS(rxsp->status5, AR_RxRSSICombined);
0506     rxs->rs_rssi_ctl[0] = MS(rxsp->status1, AR_RxRSSIAnt00);
0507     rxs->rs_rssi_ctl[1] = MS(rxsp->status1, AR_RxRSSIAnt01);
0508     rxs->rs_rssi_ctl[2] = MS(rxsp->status1, AR_RxRSSIAnt02);
0509     rxs->rs_rssi_ext[0] = MS(rxsp->status5, AR_RxRSSIAnt10);
0510     rxs->rs_rssi_ext[1] = MS(rxsp->status5, AR_RxRSSIAnt11);
0511     rxs->rs_rssi_ext[2] = MS(rxsp->status5, AR_RxRSSIAnt12);
0512 
0513     if (rxsp->status11 & AR_RxKeyIdxValid)
0514         rxs->rs_keyix = MS(rxsp->status11, AR_KeyIdx);
0515     else
0516         rxs->rs_keyix = ATH9K_RXKEYIX_INVALID;
0517 
0518     rxs->rs_rate = MS(rxsp->status1, AR_RxRate);
0519     rxs->rs_more = (rxsp->status2 & AR_RxMore) ? 1 : 0;
0520 
0521     rxs->rs_firstaggr = (rxsp->status11 & AR_RxFirstAggr) ? 1 : 0;
0522     rxs->rs_isaggr = (rxsp->status11 & AR_RxAggr) ? 1 : 0;
0523     rxs->rs_moreaggr = (rxsp->status11 & AR_RxMoreAggr) ? 1 : 0;
0524     rxs->rs_antenna = (MS(rxsp->status4, AR_RxAntenna) & 0x7);
0525     rxs->enc_flags |= (rxsp->status4 & AR_GI) ? RX_ENC_FLAG_SHORT_GI : 0;
0526     rxs->enc_flags |=
0527         (rxsp->status4 & AR_STBC) ? (1 << RX_ENC_FLAG_STBC_SHIFT) : 0;
0528     rxs->bw = (rxsp->status4 & AR_2040) ? RATE_INFO_BW_40 : RATE_INFO_BW_20;
0529 
0530     rxs->evm0 = rxsp->status6;
0531     rxs->evm1 = rxsp->status7;
0532     rxs->evm2 = rxsp->status8;
0533     rxs->evm3 = rxsp->status9;
0534     rxs->evm4 = (rxsp->status10 & 0xffff);
0535 
0536     if (rxsp->status11 & AR_PreDelimCRCErr)
0537         rxs->rs_flags |= ATH9K_RX_DELIM_CRC_PRE;
0538 
0539     if (rxsp->status11 & AR_PostDelimCRCErr)
0540         rxs->rs_flags |= ATH9K_RX_DELIM_CRC_POST;
0541 
0542     if (rxsp->status11 & AR_DecryptBusyErr)
0543         rxs->rs_flags |= ATH9K_RX_DECRYPT_BUSY;
0544 
0545     if ((rxsp->status11 & AR_RxFrameOK) == 0) {
0546         /*
0547          * AR_CRCErr will bet set to true if we're on the last
0548          * subframe and the AR_PostDelimCRCErr is caught.
0549          * In a way this also gives us a guarantee that when
0550          * (!(AR_CRCErr) && (AR_PostDelimCRCErr)) we cannot
0551          * possibly be reviewing the last subframe. AR_CRCErr
0552          * is the CRC of the actual data.
0553          */
0554         if (rxsp->status11 & AR_CRCErr)
0555             rxs->rs_status |= ATH9K_RXERR_CRC;
0556         else if (rxsp->status11 & AR_DecryptCRCErr)
0557             rxs->rs_status |= ATH9K_RXERR_DECRYPT;
0558         else if (rxsp->status11 & AR_MichaelErr)
0559             rxs->rs_status |= ATH9K_RXERR_MIC;
0560         if (rxsp->status11 & AR_PHYErr) {
0561             phyerr = MS(rxsp->status11, AR_PHYErrCode);
0562             /*
0563              * If we reach a point here where AR_PostDelimCRCErr is
0564              * true it implies we're *not* on the last subframe. In
0565              * in that case that we know already that the CRC of
0566              * the frame was OK, and MAC would send an ACK for that
0567              * subframe, even if we did get a phy error of type
0568              * ATH9K_PHYERR_OFDM_RESTART. This is only applicable
0569              * to frame that are prior to the last subframe.
0570              * The AR_PostDelimCRCErr is the CRC for the MPDU
0571              * delimiter, which contains the 4 reserved bits,
0572              * the MPDU length (12 bits), and follows the MPDU
0573              * delimiter for an A-MPDU subframe (0x4E = 'N' ASCII).
0574              */
0575             if ((phyerr == ATH9K_PHYERR_OFDM_RESTART) &&
0576                 (rxsp->status11 & AR_PostDelimCRCErr)) {
0577                 rxs->rs_phyerr = 0;
0578             } else {
0579                 rxs->rs_status |= ATH9K_RXERR_PHY;
0580                 rxs->rs_phyerr = phyerr;
0581             }
0582         }
0583     }
0584 
0585     if (rxsp->status11 & AR_KeyMiss)
0586         rxs->rs_status |= ATH9K_RXERR_KEYMISS;
0587 
0588     return 0;
0589 }
0590 EXPORT_SYMBOL(ath9k_hw_process_rxdesc_edma);
0591 
0592 void ath9k_hw_reset_txstatus_ring(struct ath_hw *ah)
0593 {
0594     ah->ts_tail = 0;
0595 
0596     memset((void *) ah->ts_ring, 0,
0597         ah->ts_size * sizeof(struct ar9003_txs));
0598 
0599     ath_dbg(ath9k_hw_common(ah), XMIT,
0600         "TS Start 0x%x End 0x%x Virt %p, Size %d\n",
0601         ah->ts_paddr_start, ah->ts_paddr_end,
0602         ah->ts_ring, ah->ts_size);
0603 
0604     REG_WRITE(ah, AR_Q_STATUS_RING_START, ah->ts_paddr_start);
0605     REG_WRITE(ah, AR_Q_STATUS_RING_END, ah->ts_paddr_end);
0606 }
0607 
0608 void ath9k_hw_setup_statusring(struct ath_hw *ah, void *ts_start,
0609                    u32 ts_paddr_start,
0610                    u16 size)
0611 {
0612 
0613     ah->ts_paddr_start = ts_paddr_start;
0614     ah->ts_paddr_end = ts_paddr_start + (size * sizeof(struct ar9003_txs));
0615     ah->ts_size = size;
0616     ah->ts_ring = ts_start;
0617 
0618     ath9k_hw_reset_txstatus_ring(ah);
0619 }
0620 EXPORT_SYMBOL(ath9k_hw_setup_statusring);