Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Copyright (c) 2008-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 
0017 #include "hw.h"
0018 #include <linux/export.h>
0019 
0020 #define AR_BufLen           0x00000fff
0021 
0022 static void ar9002_hw_rx_enable(struct ath_hw *ah)
0023 {
0024     REG_WRITE(ah, AR_CR, AR_CR_RXE);
0025 }
0026 
0027 static void ar9002_hw_set_desc_link(void *ds, u32 ds_link)
0028 {
0029     ((struct ath_desc*) ds)->ds_link = ds_link;
0030 }
0031 
0032 static bool ar9002_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked,
0033                   u32 *sync_cause_p)
0034 {
0035     u32 isr = 0;
0036     u32 mask2 = 0;
0037     struct ath9k_hw_capabilities *pCap = &ah->caps;
0038     u32 sync_cause = 0;
0039     bool fatal_int = false;
0040     struct ath_common *common = ath9k_hw_common(ah);
0041 
0042     if (!AR_SREV_9100(ah)) {
0043         if (REG_READ(ah, AR_INTR_ASYNC_CAUSE) & AR_INTR_MAC_IRQ) {
0044             if ((REG_READ(ah, AR_RTC_STATUS) & AR_RTC_STATUS_M)
0045                 == AR_RTC_STATUS_ON) {
0046                 isr = REG_READ(ah, AR_ISR);
0047             }
0048         }
0049 
0050         sync_cause = REG_READ(ah, AR_INTR_SYNC_CAUSE) &
0051             AR_INTR_SYNC_DEFAULT;
0052 
0053         *masked = 0;
0054 
0055         if (!isr && !sync_cause)
0056             return false;
0057     } else {
0058         *masked = 0;
0059         isr = REG_READ(ah, AR_ISR);
0060     }
0061 
0062     if (isr) {
0063         if (isr & AR_ISR_BCNMISC) {
0064             u32 isr2;
0065             isr2 = REG_READ(ah, AR_ISR_S2);
0066             if (isr2 & AR_ISR_S2_TIM)
0067                 mask2 |= ATH9K_INT_TIM;
0068             if (isr2 & AR_ISR_S2_DTIM)
0069                 mask2 |= ATH9K_INT_DTIM;
0070             if (isr2 & AR_ISR_S2_DTIMSYNC)
0071                 mask2 |= ATH9K_INT_DTIMSYNC;
0072             if (isr2 & (AR_ISR_S2_CABEND))
0073                 mask2 |= ATH9K_INT_CABEND;
0074             if (isr2 & AR_ISR_S2_GTT)
0075                 mask2 |= ATH9K_INT_GTT;
0076             if (isr2 & AR_ISR_S2_CST)
0077                 mask2 |= ATH9K_INT_CST;
0078             if (isr2 & AR_ISR_S2_TSFOOR)
0079                 mask2 |= ATH9K_INT_TSFOOR;
0080 
0081             if (!(pCap->hw_caps & ATH9K_HW_CAP_RAC_SUPPORTED)) {
0082                 REG_WRITE(ah, AR_ISR_S2, isr2);
0083                 isr &= ~AR_ISR_BCNMISC;
0084             }
0085         }
0086 
0087         if (pCap->hw_caps & ATH9K_HW_CAP_RAC_SUPPORTED)
0088             isr = REG_READ(ah, AR_ISR_RAC);
0089 
0090         if (isr == 0xffffffff) {
0091             *masked = 0;
0092             return false;
0093         }
0094 
0095         *masked = isr & ATH9K_INT_COMMON;
0096 
0097         if (isr & (AR_ISR_RXMINTR | AR_ISR_RXINTM |
0098                AR_ISR_RXOK | AR_ISR_RXERR))
0099             *masked |= ATH9K_INT_RX;
0100 
0101         if (isr &
0102             (AR_ISR_TXOK | AR_ISR_TXDESC | AR_ISR_TXERR |
0103              AR_ISR_TXEOL)) {
0104             u32 s0_s, s1_s;
0105 
0106             *masked |= ATH9K_INT_TX;
0107 
0108             if (pCap->hw_caps & ATH9K_HW_CAP_RAC_SUPPORTED) {
0109                 s0_s = REG_READ(ah, AR_ISR_S0_S);
0110                 s1_s = REG_READ(ah, AR_ISR_S1_S);
0111             } else {
0112                 s0_s = REG_READ(ah, AR_ISR_S0);
0113                 REG_WRITE(ah, AR_ISR_S0, s0_s);
0114                 s1_s = REG_READ(ah, AR_ISR_S1);
0115                 REG_WRITE(ah, AR_ISR_S1, s1_s);
0116 
0117                 isr &= ~(AR_ISR_TXOK |
0118                      AR_ISR_TXDESC |
0119                      AR_ISR_TXERR |
0120                      AR_ISR_TXEOL);
0121             }
0122 
0123             ah->intr_txqs = MS(s0_s, AR_ISR_S0_QCU_TXOK);
0124             ah->intr_txqs |= MS(s0_s, AR_ISR_S0_QCU_TXDESC);
0125             ah->intr_txqs |= MS(s1_s, AR_ISR_S1_QCU_TXERR);
0126             ah->intr_txqs |= MS(s1_s, AR_ISR_S1_QCU_TXEOL);
0127         }
0128 
0129         if (isr & AR_ISR_RXORN) {
0130             ath_dbg(common, INTERRUPT,
0131                 "receive FIFO overrun interrupt\n");
0132         }
0133 
0134         *masked |= mask2;
0135     }
0136 
0137     if (!AR_SREV_9100(ah) && (isr & AR_ISR_GENTMR)) {
0138         u32 s5_s;
0139 
0140         if (pCap->hw_caps & ATH9K_HW_CAP_RAC_SUPPORTED) {
0141             s5_s = REG_READ(ah, AR_ISR_S5_S);
0142         } else {
0143             s5_s = REG_READ(ah, AR_ISR_S5);
0144         }
0145 
0146         ah->intr_gen_timer_trigger =
0147                 MS(s5_s, AR_ISR_S5_GENTIMER_TRIG);
0148 
0149         ah->intr_gen_timer_thresh =
0150             MS(s5_s, AR_ISR_S5_GENTIMER_THRESH);
0151 
0152         if (ah->intr_gen_timer_trigger)
0153             *masked |= ATH9K_INT_GENTIMER;
0154 
0155         if ((s5_s & AR_ISR_S5_TIM_TIMER) &&
0156             !(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP))
0157             *masked |= ATH9K_INT_TIM_TIMER;
0158 
0159         if (!(pCap->hw_caps & ATH9K_HW_CAP_RAC_SUPPORTED)) {
0160             REG_WRITE(ah, AR_ISR_S5, s5_s);
0161             isr &= ~AR_ISR_GENTMR;
0162         }
0163     }
0164 
0165     if (!(pCap->hw_caps & ATH9K_HW_CAP_RAC_SUPPORTED)) {
0166         REG_WRITE(ah, AR_ISR, isr);
0167         REG_READ(ah, AR_ISR);
0168     }
0169 
0170     if (AR_SREV_9100(ah))
0171         return true;
0172 
0173     if (sync_cause) {
0174         if (sync_cause_p)
0175             *sync_cause_p = sync_cause;
0176         fatal_int =
0177             (sync_cause &
0178              (AR_INTR_SYNC_HOST1_FATAL | AR_INTR_SYNC_HOST1_PERR))
0179             ? true : false;
0180 
0181         if (fatal_int) {
0182             if (sync_cause & AR_INTR_SYNC_HOST1_FATAL) {
0183                 ath_dbg(common, ANY,
0184                     "received PCI FATAL interrupt\n");
0185             }
0186             if (sync_cause & AR_INTR_SYNC_HOST1_PERR) {
0187                 ath_dbg(common, ANY,
0188                     "received PCI PERR interrupt\n");
0189             }
0190             *masked |= ATH9K_INT_FATAL;
0191         }
0192         if (sync_cause & AR_INTR_SYNC_RADM_CPL_TIMEOUT) {
0193             ath_dbg(common, INTERRUPT,
0194                 "AR_INTR_SYNC_RADM_CPL_TIMEOUT\n");
0195             REG_WRITE(ah, AR_RC, AR_RC_HOSTIF);
0196             REG_WRITE(ah, AR_RC, 0);
0197             *masked |= ATH9K_INT_FATAL;
0198         }
0199         if (sync_cause & AR_INTR_SYNC_LOCAL_TIMEOUT) {
0200             ath_dbg(common, INTERRUPT,
0201                 "AR_INTR_SYNC_LOCAL_TIMEOUT\n");
0202         }
0203 
0204         REG_WRITE(ah, AR_INTR_SYNC_CAUSE_CLR, sync_cause);
0205         (void) REG_READ(ah, AR_INTR_SYNC_CAUSE_CLR);
0206     }
0207 
0208     return true;
0209 }
0210 
0211 static void
0212 ar9002_set_txdesc(struct ath_hw *ah, void *ds, struct ath_tx_info *i)
0213 {
0214     struct ar5416_desc *ads = AR5416DESC(ds);
0215     u32 ctl1, ctl6;
0216 
0217     ads->ds_txstatus0 = ads->ds_txstatus1 = 0;
0218     ads->ds_txstatus2 = ads->ds_txstatus3 = 0;
0219     ads->ds_txstatus4 = ads->ds_txstatus5 = 0;
0220     ads->ds_txstatus6 = ads->ds_txstatus7 = 0;
0221     ads->ds_txstatus8 = ads->ds_txstatus9 = 0;
0222 
0223     WRITE_ONCE(ads->ds_link, i->link);
0224     WRITE_ONCE(ads->ds_data, i->buf_addr[0]);
0225 
0226     ctl1 = i->buf_len[0] | (i->is_last ? 0 : AR_TxMore);
0227     ctl6 = SM(i->keytype, AR_EncrType);
0228 
0229     if (AR_SREV_9285(ah)) {
0230         ads->ds_ctl8 = 0;
0231         ads->ds_ctl9 = 0;
0232         ads->ds_ctl10 = 0;
0233         ads->ds_ctl11 = 0;
0234     }
0235 
0236     if ((i->is_first || i->is_last) &&
0237         i->aggr != AGGR_BUF_MIDDLE && i->aggr != AGGR_BUF_LAST) {
0238         WRITE_ONCE(ads->ds_ctl2, set11nTries(i->rates, 0)
0239             | set11nTries(i->rates, 1)
0240             | set11nTries(i->rates, 2)
0241             | set11nTries(i->rates, 3)
0242             | (i->dur_update ? AR_DurUpdateEna : 0)
0243             | SM(0, AR_BurstDur));
0244 
0245         WRITE_ONCE(ads->ds_ctl3, set11nRate(i->rates, 0)
0246             | set11nRate(i->rates, 1)
0247             | set11nRate(i->rates, 2)
0248             | set11nRate(i->rates, 3));
0249     } else {
0250         WRITE_ONCE(ads->ds_ctl2, 0);
0251         WRITE_ONCE(ads->ds_ctl3, 0);
0252     }
0253 
0254     if (!i->is_first) {
0255         WRITE_ONCE(ads->ds_ctl0, 0);
0256         WRITE_ONCE(ads->ds_ctl1, ctl1);
0257         WRITE_ONCE(ads->ds_ctl6, ctl6);
0258         return;
0259     }
0260 
0261     ctl1 |= (i->keyix != ATH9K_TXKEYIX_INVALID ? SM(i->keyix, AR_DestIdx) : 0)
0262         | SM(i->type, AR_FrameType)
0263         | (i->flags & ATH9K_TXDESC_NOACK ? AR_NoAck : 0)
0264         | (i->flags & ATH9K_TXDESC_EXT_ONLY ? AR_ExtOnly : 0)
0265         | (i->flags & ATH9K_TXDESC_EXT_AND_CTL ? AR_ExtAndCtl : 0);
0266 
0267     switch (i->aggr) {
0268     case AGGR_BUF_FIRST:
0269         ctl6 |= SM(i->aggr_len, AR_AggrLen);
0270         fallthrough;
0271     case AGGR_BUF_MIDDLE:
0272         ctl1 |= AR_IsAggr | AR_MoreAggr;
0273         ctl6 |= SM(i->ndelim, AR_PadDelim);
0274         break;
0275     case AGGR_BUF_LAST:
0276         ctl1 |= AR_IsAggr;
0277         break;
0278     case AGGR_BUF_NONE:
0279         break;
0280     }
0281 
0282     WRITE_ONCE(ads->ds_ctl0, (i->pkt_len & AR_FrameLen)
0283         | (i->flags & ATH9K_TXDESC_VMF ? AR_VirtMoreFrag : 0)
0284         | SM(i->txpower[0], AR_XmitPower0)
0285         | (i->flags & ATH9K_TXDESC_VEOL ? AR_VEOL : 0)
0286         | (i->flags & ATH9K_TXDESC_INTREQ ? AR_TxIntrReq : 0)
0287         | (i->keyix != ATH9K_TXKEYIX_INVALID ? AR_DestIdxValid : 0)
0288         | (i->flags & ATH9K_TXDESC_CLRDMASK ? AR_ClrDestMask : 0)
0289         | (i->flags & ATH9K_TXDESC_RTSENA ? AR_RTSEnable :
0290            (i->flags & ATH9K_TXDESC_CTSENA ? AR_CTSEnable : 0)));
0291 
0292     WRITE_ONCE(ads->ds_ctl1, ctl1);
0293     WRITE_ONCE(ads->ds_ctl6, ctl6);
0294 
0295     if (i->aggr == AGGR_BUF_MIDDLE || i->aggr == AGGR_BUF_LAST)
0296         return;
0297 
0298     WRITE_ONCE(ads->ds_ctl4, set11nPktDurRTSCTS(i->rates, 0)
0299         | set11nPktDurRTSCTS(i->rates, 1));
0300 
0301     WRITE_ONCE(ads->ds_ctl5, set11nPktDurRTSCTS(i->rates, 2)
0302         | set11nPktDurRTSCTS(i->rates, 3));
0303 
0304     WRITE_ONCE(ads->ds_ctl7,
0305           set11nRateFlags(i->rates, 0) | set11nChainSel(i->rates, 0)
0306         | set11nRateFlags(i->rates, 1) | set11nChainSel(i->rates, 1)
0307         | set11nRateFlags(i->rates, 2) | set11nChainSel(i->rates, 2)
0308         | set11nRateFlags(i->rates, 3) | set11nChainSel(i->rates, 3)
0309         | SM(i->rtscts_rate, AR_RTSCTSRate));
0310 
0311     WRITE_ONCE(ads->ds_ctl9, SM(i->txpower[1], AR_XmitPower1));
0312     WRITE_ONCE(ads->ds_ctl10, SM(i->txpower[2], AR_XmitPower2));
0313     WRITE_ONCE(ads->ds_ctl11, SM(i->txpower[3], AR_XmitPower3));
0314 }
0315 
0316 static int ar9002_hw_proc_txdesc(struct ath_hw *ah, void *ds,
0317                  struct ath_tx_status *ts)
0318 {
0319     struct ar5416_desc *ads = AR5416DESC(ds);
0320     u32 status;
0321 
0322     status = READ_ONCE(ads->ds_txstatus9);
0323     if ((status & AR_TxDone) == 0)
0324         return -EINPROGRESS;
0325 
0326     ts->ts_tstamp = ads->AR_SendTimestamp;
0327     ts->ts_status = 0;
0328     ts->ts_flags = 0;
0329 
0330     if (status & AR_TxOpExceeded)
0331         ts->ts_status |= ATH9K_TXERR_XTXOP;
0332     ts->tid = MS(status, AR_TxTid);
0333     ts->ts_rateindex = MS(status, AR_FinalTxIdx);
0334     ts->ts_seqnum = MS(status, AR_SeqNum);
0335 
0336     status = READ_ONCE(ads->ds_txstatus0);
0337     ts->ts_rssi_ctl0 = MS(status, AR_TxRSSIAnt00);
0338     ts->ts_rssi_ctl1 = MS(status, AR_TxRSSIAnt01);
0339     ts->ts_rssi_ctl2 = MS(status, AR_TxRSSIAnt02);
0340     if (status & AR_TxBaStatus) {
0341         ts->ts_flags |= ATH9K_TX_BA;
0342         ts->ba_low = ads->AR_BaBitmapLow;
0343         ts->ba_high = ads->AR_BaBitmapHigh;
0344     }
0345 
0346     status = READ_ONCE(ads->ds_txstatus1);
0347     if (status & AR_FrmXmitOK)
0348         ts->ts_status |= ATH9K_TX_ACKED;
0349     else {
0350         if (status & AR_ExcessiveRetries)
0351             ts->ts_status |= ATH9K_TXERR_XRETRY;
0352         if (status & AR_Filtered)
0353             ts->ts_status |= ATH9K_TXERR_FILT;
0354         if (status & AR_FIFOUnderrun) {
0355             ts->ts_status |= ATH9K_TXERR_FIFO;
0356             ath9k_hw_updatetxtriglevel(ah, true);
0357         }
0358     }
0359     if (status & AR_TxTimerExpired)
0360         ts->ts_status |= ATH9K_TXERR_TIMER_EXPIRED;
0361     if (status & AR_DescCfgErr)
0362         ts->ts_flags |= ATH9K_TX_DESC_CFG_ERR;
0363     if (status & AR_TxDataUnderrun) {
0364         ts->ts_flags |= ATH9K_TX_DATA_UNDERRUN;
0365         ath9k_hw_updatetxtriglevel(ah, true);
0366     }
0367     if (status & AR_TxDelimUnderrun) {
0368         ts->ts_flags |= ATH9K_TX_DELIM_UNDERRUN;
0369         ath9k_hw_updatetxtriglevel(ah, true);
0370     }
0371     ts->ts_shortretry = MS(status, AR_RTSFailCnt);
0372     ts->ts_longretry = MS(status, AR_DataFailCnt);
0373     ts->ts_virtcol = MS(status, AR_VirtRetryCnt);
0374 
0375     status = READ_ONCE(ads->ds_txstatus5);
0376     ts->ts_rssi = MS(status, AR_TxRSSICombined);
0377     ts->ts_rssi_ext0 = MS(status, AR_TxRSSIAnt10);
0378     ts->ts_rssi_ext1 = MS(status, AR_TxRSSIAnt11);
0379     ts->ts_rssi_ext2 = MS(status, AR_TxRSSIAnt12);
0380 
0381     ts->evm0 = ads->AR_TxEVM0;
0382     ts->evm1 = ads->AR_TxEVM1;
0383     ts->evm2 = ads->AR_TxEVM2;
0384 
0385     return 0;
0386 }
0387 
0388 static int ar9002_hw_get_duration(struct ath_hw *ah, const void *ds, int index)
0389 {
0390     struct ar5416_desc *ads = AR5416DESC(ds);
0391 
0392     switch (index) {
0393     case 0:
0394         return MS(READ_ONCE(ads->ds_ctl4), AR_PacketDur0);
0395     case 1:
0396         return MS(READ_ONCE(ads->ds_ctl4), AR_PacketDur1);
0397     case 2:
0398         return MS(READ_ONCE(ads->ds_ctl5), AR_PacketDur2);
0399     case 3:
0400         return MS(READ_ONCE(ads->ds_ctl5), AR_PacketDur3);
0401     default:
0402         return -1;
0403     }
0404 }
0405 
0406 void ath9k_hw_setuprxdesc(struct ath_hw *ah, struct ath_desc *ds,
0407               u32 size, u32 flags)
0408 {
0409     struct ar5416_desc *ads = AR5416DESC(ds);
0410 
0411     ads->ds_ctl1 = size & AR_BufLen;
0412     if (flags & ATH9K_RXDESC_INTREQ)
0413         ads->ds_ctl1 |= AR_RxIntrReq;
0414 
0415     memset(&ads->u.rx, 0, sizeof(ads->u.rx));
0416 }
0417 EXPORT_SYMBOL(ath9k_hw_setuprxdesc);
0418 
0419 void ar9002_hw_attach_mac_ops(struct ath_hw *ah)
0420 {
0421     struct ath_hw_ops *ops = ath9k_hw_ops(ah);
0422 
0423     ops->rx_enable = ar9002_hw_rx_enable;
0424     ops->set_desc_link = ar9002_hw_set_desc_link;
0425     ops->get_isr = ar9002_hw_get_isr;
0426     ops->set_txdesc = ar9002_set_txdesc;
0427     ops->proc_txdesc = ar9002_hw_proc_txdesc;
0428     ops->get_duration = ar9002_hw_get_duration;
0429 }