summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDamien Bergamini <damien@cvs.openbsd.org>2007-11-27 19:45:45 +0000
committerDamien Bergamini <damien@cvs.openbsd.org>2007-11-27 19:45:45 +0000
commit0bd490a7872454d032e9220b8390edb9429a6d9a (patch)
treed8ded5bd2324e0f00c7556fb46c1cf8eb297ebc4
parent1d1e47fe5d9c6461b1b5b7d8de1bc21472d20e9e (diff)
fix DMA alignment constraints: rings must be aligned on a 256-byte
boundary, "keep warm" page must be aligned on a 4KB boundary. make sure sc->shared->len[x][y] == sc->shared->len[x + 256][y] for all x < 64.
-rw-r--r--sys/dev/pci/if_iwn.c21
-rw-r--r--sys/dev/pci/if_iwnreg.h7
2 files changed, 20 insertions, 8 deletions
diff --git a/sys/dev/pci/if_iwn.c b/sys/dev/pci/if_iwn.c
index 10a85750af3..42ceee3dabb 100644
--- a/sys/dev/pci/if_iwn.c
+++ b/sys/dev/pci/if_iwn.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_iwn.c,v 1.14 2007/11/19 19:35:43 damien Exp $ */
+/* $OpenBSD: if_iwn.c,v 1.15 2007/11/27 19:45:44 damien Exp $ */
/*-
* Copyright (c) 2007
@@ -482,9 +482,9 @@ iwn_free_shared(struct iwn_softc *sc)
int
iwn_alloc_kw(struct iwn_softc *sc)
{
- /* must be aligned on a 16-byte boundary */
+ /* must be aligned on a 4KB boundary */
return iwn_dma_contig_alloc(sc->sc_dmat, &sc->kw_dma, NULL,
- PAGE_SIZE, 16, BUS_DMA_NOWAIT);
+ PAGE_SIZE, PAGE_SIZE, BUS_DMA_NOWAIT);
}
void
@@ -1871,10 +1871,13 @@ iwn_tx_data(struct iwn_softc *sc, struct mbuf *m0, struct ieee80211_node *ni,
}
sc->shared->len[ring->qid][ring->cur] =
htole16(hdrlen + m0->m_pkthdr.len + 8);
-
+ if (ring->cur < IWN_TX_WINDOW) {
+ sc->shared->len[ring->qid][ring->cur + IWN_TX_RING_COUNT] =
+ htole16(hdrlen + m0->m_pkthdr.len + 8);
+ }
ring->queued++;
- /* kick ring */
+ /* kick Tx ring */
ring->cur = (ring->cur + 1) % IWN_TX_RING_COUNT;
IWN_WRITE(sc, IWN_TX_WIDX, ring->qid << 8 | ring->cur);
@@ -2197,6 +2200,10 @@ iwn_cmd(struct iwn_softc *sc, int code, const void *buf, int size, int async)
IWN_SET_DESC_NSEGS(desc, 1);
IWN_SET_DESC_SEG(desc, 0, paddr, 4 + size);
sc->shared->len[ring->qid][ring->cur] = htole16(8);
+ if (ring->cur < IWN_TX_WINDOW) {
+ sc->shared->len[ring->qid][ring->cur + IWN_TX_RING_COUNT] =
+ htole16(8);
+ }
/* kick cmd ring */
ring->cur = (ring->cur + 1) % IWN_TX_RING_COUNT;
@@ -3180,6 +3187,10 @@ iwn_scan(struct iwn_softc *sc, uint16_t flags)
IWN_SET_DESC_SEG(desc, 0, data->map->dm_segs[0].ds_addr,
data->map->dm_segs[0].ds_len);
sc->shared->len[ring->qid][ring->cur] = htole16(8);
+ if (ring->cur < IWN_TX_WINDOW) {
+ sc->shared->len[ring->qid][ring->cur + IWN_TX_RING_COUNT] =
+ htole16(8);
+ }
/* kick cmd ring */
ring->cur = (ring->cur + 1) % IWN_TX_RING_COUNT;
diff --git a/sys/dev/pci/if_iwnreg.h b/sys/dev/pci/if_iwnreg.h
index ccb49cc3e7e..7dba6b8ddf0 100644
--- a/sys/dev/pci/if_iwnreg.h
+++ b/sys/dev/pci/if_iwnreg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_iwnreg.h,v 1.7 2007/11/17 18:50:54 damien Exp $ */
+/* $OpenBSD: if_iwnreg.h,v 1.8 2007/11/27 19:45:44 damien Exp $ */
/*-
* Copyright (c) 2007
@@ -24,9 +24,9 @@
#define IWN_NTXCHAINS 2
/*
- * Rings must be aligned on a 16K boundary.
+ * Rings must be aligned on a 256-byte boundary.
*/
-#define IWN_RING_DMA_ALIGN 0x4000
+#define IWN_RING_DMA_ALIGN 256
/* maximum scatter/gather */
#define IWN_MAX_SCATTER 20
@@ -180,6 +180,7 @@
#define IWN_ENA_L1 (1 << 1)
+#define IWN_TX_WINDOW 64
struct iwn_shared {
uint16_t len[512][IWN_NTXQUEUES]; /* 16KB total */
uint16_t closed_count;