Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5088c2f1 authored by Vasanthakumar Thiagarajan's avatar Vasanthakumar Thiagarajan Committed by John W. Linville
Browse files

ath9k: Initialize and configure tx status for EDMA



Also add a function to clean up tx status ring.

Signed-off-by: default avatarVasanthakumar Thiagarajan <vasanth@atheros.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 4adfcded
Loading
Loading
Loading
Loading
+5 −1
Original line number Diff line number Diff line
@@ -114,8 +114,10 @@ enum buffer_type {
#define bf_isretried(bf)	(bf->bf_state.bf_type & BUF_RETRY)
#define bf_isxretried(bf)	(bf->bf_state.bf_type & BUF_XRETRY)

#define ATH_TXSTATUS_RING_SIZE 64

struct ath_descdma {
	struct ath_desc *dd_desc;
	void *dd_desc;
	dma_addr_t dd_desc_paddr;
	u32 dd_desc_len;
	struct ath_buf *dd_bufptr;
@@ -515,6 +517,8 @@ struct ath_softc {
	struct ath_beacon_config cur_beacon_conf;
	struct delayed_work tx_complete_work;
	struct ath_btcoex btcoex;

	struct ath_descdma txsdma;
};

struct ath_wiphy {
+1 −0
Original line number Diff line number Diff line
@@ -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_status_len = sizeof(struct ar9003_rxs);
		pCap->tx_desc_len = sizeof(struct ar9003_txc);
		pCap->txs_len = sizeof(struct ar9003_txs);
	} else {
		pCap->tx_desc_len = sizeof(struct ath_desc);
	}
+1 −0
Original line number Diff line number Diff line
@@ -209,6 +209,7 @@ struct ath9k_hw_capabilities {
	u8 rx_lp_qdepth;
	u8 rx_status_len;
	u8 tx_desc_len;
	u8 txs_len;
};

struct ath9k_ops_config {
+45 −1
Original line number Diff line number Diff line
@@ -2144,6 +2144,41 @@ void ath_tx_tasklet(struct ath_softc *sc)
/* 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)
{
	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,
				  "beacon", ATH_BCBUF, 1, 0);
				  "beacon", ATH_BCBUF, 1, 1);
	if (error != 0) {
		ath_print(common, ATH_DBG_FATAL,
			  "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);

	if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) {
		error = ath_tx_edma_init(sc);
		if (error)
			goto err;
	}

err:
	if (error != 0)
		ath_tx_cleanup(sc);
@@ -2183,6 +2224,9 @@ void ath_tx_cleanup(struct ath_softc *sc)

	if (sc->tx.txdma.dd_desc_len != 0)
		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)