You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
ath9k: Add Rx EDMA support
Signed-off-by: Felix Fietkau <nbd@openwrt.org> Signed-off-by: Vasanthakumar Thiagarajan <vasanth@atheros.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:
committed by
John W. Linville
parent
c38d4d2eb9
commit
b5c80475ab
@@ -72,6 +72,9 @@ int ath9k_hw_process_rxdesc_edma(struct ath_hw *ah, struct ath_rx_status *rxs,
|
||||
if ((rxsp->ds_info & (AR_TxRxDesc | AR_CtrlStat)) != 0)
|
||||
return -EINPROGRESS;
|
||||
|
||||
if (!rxs)
|
||||
return 0;
|
||||
|
||||
rxs->rs_status = 0;
|
||||
rxs->rs_flags = 0;
|
||||
|
||||
|
||||
@@ -223,6 +223,12 @@ struct ath_tx {
|
||||
struct ath_descdma txdma;
|
||||
};
|
||||
|
||||
struct ath_rx_edma {
|
||||
struct sk_buff_head rx_fifo;
|
||||
struct sk_buff_head rx_buffers;
|
||||
u32 rx_fifo_hwsize;
|
||||
};
|
||||
|
||||
struct ath_rx {
|
||||
u8 defant;
|
||||
u8 rxotherant;
|
||||
@@ -232,6 +238,8 @@ struct ath_rx {
|
||||
spinlock_t rxbuflock;
|
||||
struct list_head rxbuf;
|
||||
struct ath_descdma rxdma;
|
||||
struct ath_buf *rx_bufptr;
|
||||
struct ath_rx_edma rx_edma[ATH9K_RX_QUEUE_MAX];
|
||||
};
|
||||
|
||||
int ath_startrecv(struct ath_softc *sc);
|
||||
@@ -240,7 +248,7 @@ void ath_flushrecv(struct ath_softc *sc);
|
||||
u32 ath_calcrxfilter(struct ath_softc *sc);
|
||||
int ath_rx_init(struct ath_softc *sc, int nbufs);
|
||||
void ath_rx_cleanup(struct ath_softc *sc);
|
||||
int ath_rx_tasklet(struct ath_softc *sc, int flush);
|
||||
int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp);
|
||||
struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype);
|
||||
void ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq);
|
||||
int ath_tx_setup(struct ath_softc *sc, int haltype);
|
||||
|
||||
@@ -246,6 +246,8 @@ struct ath9k_ops_config {
|
||||
enum ath9k_int {
|
||||
ATH9K_INT_RX = 0x00000001,
|
||||
ATH9K_INT_RXDESC = 0x00000002,
|
||||
ATH9K_INT_RXHP = 0x00000001,
|
||||
ATH9K_INT_RXLP = 0x00000002,
|
||||
ATH9K_INT_RXNOFRM = 0x00000008,
|
||||
ATH9K_INT_RXEOL = 0x00000010,
|
||||
ATH9K_INT_RXORN = 0x00000020,
|
||||
|
||||
@@ -401,6 +401,7 @@ void ath9k_tasklet(unsigned long data)
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
|
||||
u32 status = sc->intrstatus;
|
||||
u32 rxmask;
|
||||
|
||||
ath9k_ps_wakeup(sc);
|
||||
|
||||
@@ -410,9 +411,21 @@ void ath9k_tasklet(unsigned long data)
|
||||
return;
|
||||
}
|
||||
|
||||
if (status & (ATH9K_INT_RX | ATH9K_INT_RXEOL | ATH9K_INT_RXORN)) {
|
||||
if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)
|
||||
rxmask = (ATH9K_INT_RXHP | ATH9K_INT_RXLP | ATH9K_INT_RXEOL |
|
||||
ATH9K_INT_RXORN);
|
||||
else
|
||||
rxmask = (ATH9K_INT_RX | ATH9K_INT_RXEOL | ATH9K_INT_RXORN);
|
||||
|
||||
if (status & rxmask) {
|
||||
spin_lock_bh(&sc->rx.rxflushlock);
|
||||
ath_rx_tasklet(sc, 0);
|
||||
|
||||
/* Check for high priority Rx first */
|
||||
if ((ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) &&
|
||||
(status & ATH9K_INT_RXHP))
|
||||
ath_rx_tasklet(sc, 0, true);
|
||||
|
||||
ath_rx_tasklet(sc, 0, false);
|
||||
spin_unlock_bh(&sc->rx.rxflushlock);
|
||||
}
|
||||
|
||||
@@ -445,6 +458,8 @@ irqreturn_t ath_isr(int irq, void *dev)
|
||||
ATH9K_INT_RXORN | \
|
||||
ATH9K_INT_RXEOL | \
|
||||
ATH9K_INT_RX | \
|
||||
ATH9K_INT_RXLP | \
|
||||
ATH9K_INT_RXHP | \
|
||||
ATH9K_INT_TX | \
|
||||
ATH9K_INT_BMISS | \
|
||||
ATH9K_INT_CST | \
|
||||
@@ -496,7 +511,8 @@ irqreturn_t ath_isr(int irq, void *dev)
|
||||
* If a FATAL or RXORN interrupt is received, we have to reset the
|
||||
* chip immediately.
|
||||
*/
|
||||
if (status & (ATH9K_INT_FATAL | ATH9K_INT_RXORN))
|
||||
if ((status & ATH9K_INT_FATAL) || ((status & ATH9K_INT_RXORN) &&
|
||||
!(ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)))
|
||||
goto chip_reset;
|
||||
|
||||
if (status & ATH9K_INT_SWBA)
|
||||
@@ -505,6 +521,13 @@ irqreturn_t ath_isr(int irq, void *dev)
|
||||
if (status & ATH9K_INT_TXURN)
|
||||
ath9k_hw_updatetxtriglevel(ah, true);
|
||||
|
||||
if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) {
|
||||
if (status & ATH9K_INT_RXEOL) {
|
||||
ah->imask &= ~(ATH9K_INT_RXEOL | ATH9K_INT_RXORN);
|
||||
ath9k_hw_set_interrupts(ah, ah->imask);
|
||||
}
|
||||
}
|
||||
|
||||
if (status & ATH9K_INT_MIB) {
|
||||
/*
|
||||
* Disable interrupts until we service the MIB
|
||||
@@ -1162,9 +1185,14 @@ static int ath9k_start(struct ieee80211_hw *hw)
|
||||
}
|
||||
|
||||
/* Setup our intr mask. */
|
||||
ah->imask = ATH9K_INT_RX | ATH9K_INT_TX
|
||||
| ATH9K_INT_RXEOL | ATH9K_INT_RXORN
|
||||
| ATH9K_INT_FATAL | ATH9K_INT_GLOBAL;
|
||||
ah->imask = ATH9K_INT_TX | ATH9K_INT_RXEOL |
|
||||
ATH9K_INT_RXORN | ATH9K_INT_FATAL |
|
||||
ATH9K_INT_GLOBAL;
|
||||
|
||||
if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)
|
||||
ah->imask |= ATH9K_INT_RXHP | ATH9K_INT_RXLP;
|
||||
else
|
||||
ah->imask |= ATH9K_INT_RX;
|
||||
|
||||
if (ah->caps.hw_caps & ATH9K_HW_CAP_GTT)
|
||||
ah->imask |= ATH9K_INT_GTT;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user