diff options
author | Vasanthakumar Thiagarajan <vasanth@atheros.com> | 2010-04-15 17:39:34 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2010-04-16 15:43:47 -0400 |
commit | 5088c2f1a2475546d9a79b515bde6d65b8681e51 (patch) | |
tree | 64b925a80e8d8d7e7b0a8824a471646ceaf5bd79 /drivers/net/wireless/ath/ath9k | |
parent | 4adfcdedd4e0c05c1b659da5f2b8bc4e2d4a86df (diff) |
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>
Diffstat (limited to 'drivers/net/wireless/ath/ath9k')
-rw-r--r-- | drivers/net/wireless/ath/ath9k/ath9k.h | 6 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/hw.c | 1 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/hw.h | 1 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/xmit.c | 46 |
4 files changed, 52 insertions, 2 deletions
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index f67be52591d5..2d3e42ad3b05 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h | |||
@@ -114,8 +114,10 @@ enum buffer_type { | |||
114 | #define bf_isretried(bf) (bf->bf_state.bf_type & BUF_RETRY) | 114 | #define bf_isretried(bf) (bf->bf_state.bf_type & BUF_RETRY) |
115 | #define bf_isxretried(bf) (bf->bf_state.bf_type & BUF_XRETRY) | 115 | #define bf_isxretried(bf) (bf->bf_state.bf_type & BUF_XRETRY) |
116 | 116 | ||
117 | #define ATH_TXSTATUS_RING_SIZE 64 | ||
118 | |||
117 | struct ath_descdma { | 119 | struct ath_descdma { |
118 | struct ath_desc *dd_desc; | 120 | void *dd_desc; |
119 | dma_addr_t dd_desc_paddr; | 121 | dma_addr_t dd_desc_paddr; |
120 | u32 dd_desc_len; | 122 | u32 dd_desc_len; |
121 | struct ath_buf *dd_bufptr; | 123 | struct ath_buf *dd_bufptr; |
@@ -515,6 +517,8 @@ struct ath_softc { | |||
515 | struct ath_beacon_config cur_beacon_conf; | 517 | struct ath_beacon_config cur_beacon_conf; |
516 | struct delayed_work tx_complete_work; | 518 | struct delayed_work tx_complete_work; |
517 | struct ath_btcoex btcoex; | 519 | struct ath_btcoex btcoex; |
520 | |||
521 | struct ath_descdma txsdma; | ||
518 | }; | 522 | }; |
519 | 523 | ||
520 | struct ath_wiphy { | 524 | struct ath_wiphy { |
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 1a7cf20d31ea..55f79f5712d4 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c | |||
@@ -2093,6 +2093,7 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah) | |||
2093 | pCap->rx_lp_qdepth = ATH9K_HW_RX_LP_QDEPTH; | 2093 | pCap->rx_lp_qdepth = ATH9K_HW_RX_LP_QDEPTH; |
2094 | pCap->rx_status_len = sizeof(struct ar9003_rxs); | 2094 | pCap->rx_status_len = sizeof(struct ar9003_rxs); |
2095 | pCap->tx_desc_len = sizeof(struct ar9003_txc); | 2095 | pCap->tx_desc_len = sizeof(struct ar9003_txc); |
2096 | pCap->txs_len = sizeof(struct ar9003_txs); | ||
2096 | } else { | 2097 | } else { |
2097 | pCap->tx_desc_len = sizeof(struct ath_desc); | 2098 | pCap->tx_desc_len = sizeof(struct ath_desc); |
2098 | } | 2099 | } |
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index b711ec212abd..9d3796a68920 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h | |||
@@ -209,6 +209,7 @@ struct ath9k_hw_capabilities { | |||
209 | u8 rx_lp_qdepth; | 209 | u8 rx_lp_qdepth; |
210 | u8 rx_status_len; | 210 | u8 rx_status_len; |
211 | u8 tx_desc_len; | 211 | u8 tx_desc_len; |
212 | u8 txs_len; | ||
212 | }; | 213 | }; |
213 | 214 | ||
214 | struct ath9k_ops_config { | 215 | struct ath9k_ops_config { |
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index c32da053c6ed..f9f7445f6652 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c | |||
@@ -2144,6 +2144,41 @@ void ath_tx_tasklet(struct ath_softc *sc) | |||
2144 | /* Init, Cleanup */ | 2144 | /* Init, Cleanup */ |
2145 | /*****************/ | 2145 | /*****************/ |
2146 | 2146 | ||
2147 | static int ath_txstatus_setup(struct ath_softc *sc, int size) | ||
2148 | { | ||
2149 | struct ath_descdma *dd = &sc->txsdma; | ||
2150 | u8 txs_len = sc->sc_ah->caps.txs_len; | ||
2151 | |||
2152 | dd->dd_desc_len = size * txs_len; | ||
2153 | dd->dd_desc = dma_alloc_coherent(sc->dev, dd->dd_desc_len, | ||
2154 | &dd->dd_desc_paddr, GFP_KERNEL); | ||
2155 | if (!dd->dd_desc) | ||
2156 | return -ENOMEM; | ||
2157 | |||
2158 | return 0; | ||
2159 | } | ||
2160 | |||
2161 | static int ath_tx_edma_init(struct ath_softc *sc) | ||
2162 | { | ||
2163 | int err; | ||
2164 | |||
2165 | err = ath_txstatus_setup(sc, ATH_TXSTATUS_RING_SIZE); | ||
2166 | if (!err) | ||
2167 | ath9k_hw_setup_statusring(sc->sc_ah, sc->txsdma.dd_desc, | ||
2168 | sc->txsdma.dd_desc_paddr, | ||
2169 | ATH_TXSTATUS_RING_SIZE); | ||
2170 | |||
2171 | return err; | ||
2172 | } | ||
2173 | |||
2174 | static void ath_tx_edma_cleanup(struct ath_softc *sc) | ||
2175 | { | ||
2176 | struct ath_descdma *dd = &sc->txsdma; | ||
2177 | |||
2178 | dma_free_coherent(sc->dev, dd->dd_desc_len, dd->dd_desc, | ||
2179 | dd->dd_desc_paddr); | ||
2180 | } | ||
2181 | |||
2147 | int ath_tx_init(struct ath_softc *sc, int nbufs) | 2182 | int ath_tx_init(struct ath_softc *sc, int nbufs) |
2148 | { | 2183 | { |
2149 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | 2184 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); |
@@ -2160,7 +2195,7 @@ int ath_tx_init(struct ath_softc *sc, int nbufs) | |||
2160 | } | 2195 | } |
2161 | 2196 | ||
2162 | error = ath_descdma_setup(sc, &sc->beacon.bdma, &sc->beacon.bbuf, | 2197 | error = ath_descdma_setup(sc, &sc->beacon.bdma, &sc->beacon.bbuf, |
2163 | "beacon", ATH_BCBUF, 1, 0); | 2198 | "beacon", ATH_BCBUF, 1, 1); |
2164 | if (error != 0) { | 2199 | if (error != 0) { |
2165 | ath_print(common, ATH_DBG_FATAL, | 2200 | ath_print(common, ATH_DBG_FATAL, |
2166 | "Failed to allocate beacon descriptors: %d\n", error); | 2201 | "Failed to allocate beacon descriptors: %d\n", error); |
@@ -2169,6 +2204,12 @@ int ath_tx_init(struct ath_softc *sc, int nbufs) | |||
2169 | 2204 | ||
2170 | INIT_DELAYED_WORK(&sc->tx_complete_work, ath_tx_complete_poll_work); | 2205 | INIT_DELAYED_WORK(&sc->tx_complete_work, ath_tx_complete_poll_work); |
2171 | 2206 | ||
2207 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) { | ||
2208 | error = ath_tx_edma_init(sc); | ||
2209 | if (error) | ||
2210 | goto err; | ||
2211 | } | ||
2212 | |||
2172 | err: | 2213 | err: |
2173 | if (error != 0) | 2214 | if (error != 0) |
2174 | ath_tx_cleanup(sc); | 2215 | ath_tx_cleanup(sc); |
@@ -2183,6 +2224,9 @@ void ath_tx_cleanup(struct ath_softc *sc) | |||
2183 | 2224 | ||
2184 | if (sc->tx.txdma.dd_desc_len != 0) | 2225 | if (sc->tx.txdma.dd_desc_len != 0) |
2185 | ath_descdma_cleanup(sc, &sc->tx.txdma, &sc->tx.txbuf); | 2226 | ath_descdma_cleanup(sc, &sc->tx.txdma, &sc->tx.txbuf); |
2227 | |||
2228 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) | ||
2229 | ath_tx_edma_cleanup(sc); | ||
2186 | } | 2230 | } |
2187 | 2231 | ||
2188 | void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an) | 2232 | void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an) |