|
@@ -233,31 +233,37 @@ static int ath9k_reg_notifier(struct wiphy *wiphy,
|
|
|
*/
|
|
|
int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd,
|
|
|
struct list_head *head, const char *name,
|
|
|
- int nbuf, int ndesc)
|
|
|
+ int nbuf, int ndesc, bool is_tx)
|
|
|
{
|
|
|
#define DS2PHYS(_dd, _ds) \
|
|
|
((_dd)->dd_desc_paddr + ((caddr_t)(_ds) - (caddr_t)(_dd)->dd_desc))
|
|
|
#define ATH_DESC_4KB_BOUND_CHECK(_daddr) ((((_daddr) & 0xFFF) > 0xF7F) ? 1 : 0)
|
|
|
#define ATH_DESC_4KB_BOUND_NUM_SKIPPED(_len) ((_len) / 4096)
|
|
|
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
|
|
|
- struct ath_desc *ds;
|
|
|
+ u8 *ds;
|
|
|
struct ath_buf *bf;
|
|
|
- int i, bsize, error;
|
|
|
+ int i, bsize, error, desc_len;
|
|
|
|
|
|
ath_print(common, ATH_DBG_CONFIG, "%s DMA: %u buffers %u desc/buf\n",
|
|
|
name, nbuf, ndesc);
|
|
|
|
|
|
INIT_LIST_HEAD(head);
|
|
|
+
|
|
|
+ if (is_tx)
|
|
|
+ desc_len = sc->sc_ah->caps.tx_desc_len;
|
|
|
+ else
|
|
|
+ desc_len = sizeof(struct ath_desc);
|
|
|
+
|
|
|
/* ath_desc must be a multiple of DWORDs */
|
|
|
- if ((sizeof(struct ath_desc) % 4) != 0) {
|
|
|
+ if ((desc_len % 4) != 0) {
|
|
|
ath_print(common, ATH_DBG_FATAL,
|
|
|
"ath_desc not DWORD aligned\n");
|
|
|
- BUG_ON((sizeof(struct ath_desc) % 4) != 0);
|
|
|
+ BUG_ON((desc_len % 4) != 0);
|
|
|
error = -ENOMEM;
|
|
|
goto fail;
|
|
|
}
|
|
|
|
|
|
- dd->dd_desc_len = sizeof(struct ath_desc) * nbuf * ndesc;
|
|
|
+ dd->dd_desc_len = desc_len * nbuf * ndesc;
|
|
|
|
|
|
/*
|
|
|
* Need additional DMA memory because we can't use
|
|
@@ -270,7 +276,7 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd,
|
|
|
u32 dma_len;
|
|
|
|
|
|
while (ndesc_skipped) {
|
|
|
- dma_len = ndesc_skipped * sizeof(struct ath_desc);
|
|
|
+ dma_len = ndesc_skipped * desc_len;
|
|
|
dd->dd_desc_len += dma_len;
|
|
|
|
|
|
ndesc_skipped = ATH_DESC_4KB_BOUND_NUM_SKIPPED(dma_len);
|
|
@@ -284,7 +290,7 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd,
|
|
|
error = -ENOMEM;
|
|
|
goto fail;
|
|
|
}
|
|
|
- ds = dd->dd_desc;
|
|
|
+ ds = (u8 *) dd->dd_desc;
|
|
|
ath_print(common, ATH_DBG_CONFIG, "%s DMA map: %p (%u) -> %llx (%u)\n",
|
|
|
name, ds, (u32) dd->dd_desc_len,
|
|
|
ito64(dd->dd_desc_paddr), /*XXX*/(u32) dd->dd_desc_len);
|
|
@@ -298,7 +304,7 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd,
|
|
|
}
|
|
|
dd->dd_bufptr = bf;
|
|
|
|
|
|
- for (i = 0; i < nbuf; i++, bf++, ds += ndesc) {
|
|
|
+ for (i = 0; i < nbuf; i++, bf++, ds += (desc_len * ndesc)) {
|
|
|
bf->bf_desc = ds;
|
|
|
bf->bf_daddr = DS2PHYS(dd, ds);
|
|
|
|
|
@@ -314,7 +320,7 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd,
|
|
|
((caddr_t) dd->dd_desc +
|
|
|
dd->dd_desc_len));
|
|
|
|
|
|
- ds += ndesc;
|
|
|
+ ds += (desc_len * ndesc);
|
|
|
bf->bf_desc = ds;
|
|
|
bf->bf_daddr = DS2PHYS(dd, ds);
|
|
|
}
|