From 0bd490a7872454d032e9220b8390edb9429a6d9a Mon Sep 17 00:00:00 2001 From: Damien Bergamini Date: Tue, 27 Nov 2007 19:45:45 +0000 Subject: 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. --- sys/dev/pci/if_iwn.c | 21 ++++++++++++++++----- sys/dev/pci/if_iwnreg.h | 7 ++++--- 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; -- cgit v1.2.3