ath9k: Initialize and configure tx status for EDMA
Also add a function to clean up tx status ring. Signed-off-by: Vasanthakumar Thiagarajan <vasanth@atheros.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:
parent
4adfcdedd4
commit
5088c2f1a2
|
@ -114,8 +114,10 @@ enum buffer_type {
|
||||||
#define bf_isretried(bf) (bf->bf_state.bf_type & BUF_RETRY)
|
#define bf_isretried(bf) (bf->bf_state.bf_type & BUF_RETRY)
|
||||||
#define bf_isxretried(bf) (bf->bf_state.bf_type & BUF_XRETRY)
|
#define bf_isxretried(bf) (bf->bf_state.bf_type & BUF_XRETRY)
|
||||||
|
|
||||||
|
#define ATH_TXSTATUS_RING_SIZE 64
|
||||||
|
|
||||||
struct ath_descdma {
|
struct ath_descdma {
|
||||||
struct ath_desc *dd_desc;
|
void *dd_desc;
|
||||||
dma_addr_t dd_desc_paddr;
|
dma_addr_t dd_desc_paddr;
|
||||||
u32 dd_desc_len;
|
u32 dd_desc_len;
|
||||||
struct ath_buf *dd_bufptr;
|
struct ath_buf *dd_bufptr;
|
||||||
|
@ -515,6 +517,8 @@ struct ath_softc {
|
||||||
struct ath_beacon_config cur_beacon_conf;
|
struct ath_beacon_config cur_beacon_conf;
|
||||||
struct delayed_work tx_complete_work;
|
struct delayed_work tx_complete_work;
|
||||||
struct ath_btcoex btcoex;
|
struct ath_btcoex btcoex;
|
||||||
|
|
||||||
|
struct ath_descdma txsdma;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ath_wiphy {
|
struct ath_wiphy {
|
||||||
|
|
|
@ -2093,6 +2093,7 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
|
||||||
pCap->rx_lp_qdepth = ATH9K_HW_RX_LP_QDEPTH;
|
pCap->rx_lp_qdepth = ATH9K_HW_RX_LP_QDEPTH;
|
||||||
pCap->rx_status_len = sizeof(struct ar9003_rxs);
|
pCap->rx_status_len = sizeof(struct ar9003_rxs);
|
||||||
pCap->tx_desc_len = sizeof(struct ar9003_txc);
|
pCap->tx_desc_len = sizeof(struct ar9003_txc);
|
||||||
|
pCap->txs_len = sizeof(struct ar9003_txs);
|
||||||
} else {
|
} else {
|
||||||
pCap->tx_desc_len = sizeof(struct ath_desc);
|
pCap->tx_desc_len = sizeof(struct ath_desc);
|
||||||
}
|
}
|
||||||
|
|
|
@ -209,6 +209,7 @@ struct ath9k_hw_capabilities {
|
||||||
u8 rx_lp_qdepth;
|
u8 rx_lp_qdepth;
|
||||||
u8 rx_status_len;
|
u8 rx_status_len;
|
||||||
u8 tx_desc_len;
|
u8 tx_desc_len;
|
||||||
|
u8 txs_len;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ath9k_ops_config {
|
struct ath9k_ops_config {
|
||||||
|
|
|
@ -2144,6 +2144,41 @@ void ath_tx_tasklet(struct ath_softc *sc)
|
||||||
/* Init, Cleanup */
|
/* Init, Cleanup */
|
||||||
/*****************/
|
/*****************/
|
||||||
|
|
||||||
|
static int ath_txstatus_setup(struct ath_softc *sc, int size)
|
||||||
|
{
|
||||||
|
struct ath_descdma *dd = &sc->txsdma;
|
||||||
|
u8 txs_len = sc->sc_ah->caps.txs_len;
|
||||||
|
|
||||||
|
dd->dd_desc_len = size * txs_len;
|
||||||
|
dd->dd_desc = dma_alloc_coherent(sc->dev, dd->dd_desc_len,
|
||||||
|
&dd->dd_desc_paddr, GFP_KERNEL);
|
||||||
|
if (!dd->dd_desc)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ath_tx_edma_init(struct ath_softc *sc)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
|
||||||
|
err = ath_txstatus_setup(sc, ATH_TXSTATUS_RING_SIZE);
|
||||||
|
if (!err)
|
||||||
|
ath9k_hw_setup_statusring(sc->sc_ah, sc->txsdma.dd_desc,
|
||||||
|
sc->txsdma.dd_desc_paddr,
|
||||||
|
ATH_TXSTATUS_RING_SIZE);
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ath_tx_edma_cleanup(struct ath_softc *sc)
|
||||||
|
{
|
||||||
|
struct ath_descdma *dd = &sc->txsdma;
|
||||||
|
|
||||||
|
dma_free_coherent(sc->dev, dd->dd_desc_len, dd->dd_desc,
|
||||||
|
dd->dd_desc_paddr);
|
||||||
|
}
|
||||||
|
|
||||||
int ath_tx_init(struct ath_softc *sc, int nbufs)
|
int ath_tx_init(struct ath_softc *sc, int nbufs)
|
||||||
{
|
{
|
||||||
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
|
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
|
||||||
|
@ -2160,7 +2195,7 @@ int ath_tx_init(struct ath_softc *sc, int nbufs)
|
||||||
}
|
}
|
||||||
|
|
||||||
error = ath_descdma_setup(sc, &sc->beacon.bdma, &sc->beacon.bbuf,
|
error = ath_descdma_setup(sc, &sc->beacon.bdma, &sc->beacon.bbuf,
|
||||||
"beacon", ATH_BCBUF, 1, 0);
|
"beacon", ATH_BCBUF, 1, 1);
|
||||||
if (error != 0) {
|
if (error != 0) {
|
||||||
ath_print(common, ATH_DBG_FATAL,
|
ath_print(common, ATH_DBG_FATAL,
|
||||||
"Failed to allocate beacon descriptors: %d\n", error);
|
"Failed to allocate beacon descriptors: %d\n", error);
|
||||||
|
@ -2169,6 +2204,12 @@ int ath_tx_init(struct ath_softc *sc, int nbufs)
|
||||||
|
|
||||||
INIT_DELAYED_WORK(&sc->tx_complete_work, ath_tx_complete_poll_work);
|
INIT_DELAYED_WORK(&sc->tx_complete_work, ath_tx_complete_poll_work);
|
||||||
|
|
||||||
|
if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) {
|
||||||
|
error = ath_tx_edma_init(sc);
|
||||||
|
if (error)
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
err:
|
err:
|
||||||
if (error != 0)
|
if (error != 0)
|
||||||
ath_tx_cleanup(sc);
|
ath_tx_cleanup(sc);
|
||||||
|
@ -2183,6 +2224,9 @@ void ath_tx_cleanup(struct ath_softc *sc)
|
||||||
|
|
||||||
if (sc->tx.txdma.dd_desc_len != 0)
|
if (sc->tx.txdma.dd_desc_len != 0)
|
||||||
ath_descdma_cleanup(sc, &sc->tx.txdma, &sc->tx.txbuf);
|
ath_descdma_cleanup(sc, &sc->tx.txdma, &sc->tx.txbuf);
|
||||||
|
|
||||||
|
if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)
|
||||||
|
ath_tx_edma_cleanup(sc);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an)
|
void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an)
|
||||||
|
|
Loading…
Reference in New Issue