diff options
Diffstat (limited to 'sys/dev/pci/if_wpi.c')
-rw-r--r-- | sys/dev/pci/if_wpi.c | 66 |
1 files changed, 65 insertions, 1 deletions
diff --git a/sys/dev/pci/if_wpi.c b/sys/dev/pci/if_wpi.c index 191a9eb7ac7..3cdbf8af0ed 100644 --- a/sys/dev/pci/if_wpi.c +++ b/sys/dev/pci/if_wpi.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_wpi.c,v 1.73 2008/11/22 08:23:52 brad Exp $ */ +/* $OpenBSD: if_wpi.c,v 1.74 2008/11/25 17:06:26 damien Exp $ */ /*- * Copyright (c) 2006-2008 @@ -562,6 +562,7 @@ wpi_dma_contig_alloc(bus_dma_tag_t tag, struct wpi_dma_info *dma, void **kvap, goto fail; memset(dma->vaddr, 0, size); + bus_dmamap_sync(tag, dma->map, 0, size, BUS_DMASYNC_PREWRITE); dma->paddr = dma->map->dm_segs[0].ds_addr; if (kvap != NULL) @@ -578,6 +579,8 @@ wpi_dma_contig_free(struct wpi_dma_info *dma) { if (dma->map != NULL) { if (dma->vaddr != NULL) { + bus_dmamap_sync(dma->tag, dma->map, 0, dma->size, + BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); bus_dmamap_unload(dma->tag, dma->map); bus_dmamem_unmap(dma->tag, dma->vaddr, dma->size); bus_dmamem_free(dma->tag, &dma->seg, 1); @@ -785,6 +788,8 @@ wpi_alloc_tx_ring(struct wpi_softc *sc, struct wpi_tx_ring *ring, int qid) /* Update shared area with ring's physical address. */ sc->shared->txbase[qid] = htole32(ring->desc_dma.paddr); + bus_dmamap_sync(sc->sc_dmat, sc->shared_dma.map, 0, + sizeof (struct wpi_shared), BUS_DMASYNC_PREWRITE); /* * We only use rings 0 through 4 (4 EDCA + cmd) so there is no need @@ -846,6 +851,8 @@ wpi_reset_tx_ring(struct wpi_softc *sc, struct wpi_tx_ring *ring) struct wpi_tx_data *data = &ring->data[i]; if (data->m != NULL) { + bus_dmamap_sync(sc->sc_dmat, data->map, 0, + data->map->dm_mapsize, BUS_DMASYNC_POSTWRITE); bus_dmamap_unload(sc->sc_dmat, data->map); m_freem(data->m); data->m = NULL; @@ -870,6 +877,8 @@ wpi_free_tx_ring(struct wpi_softc *sc, struct wpi_tx_ring *ring) struct wpi_tx_data *data = &ring->data[i]; if (data->m != NULL) { + bus_dmamap_sync(sc->sc_dmat, data->map, 0, + data->map->dm_mapsize, BUS_DMASYNC_POSTWRITE); bus_dmamap_unload(sc->sc_dmat, data->map); m_freem(data->m); } @@ -1203,6 +1212,9 @@ wpi_rx_done(struct wpi_softc *sc, struct wpi_rx_desc *desc, uint32_t flags; stat = (struct wpi_rx_stat *)(desc + 1); + bus_dmamap_sync(sc->sc_dmat, ring->buf_dma.map, + (caddr_t)stat - ring->buf_dma.vaddr, WPI_RBUF_SIZE, + BUS_DMASYNC_POSTREAD); if (stat->len > WPI_STAT_MAXLEN) { printf("%s: invalid RX statistic header\n", @@ -1365,6 +1377,8 @@ wpi_tx_done(struct wpi_softc *sc, struct wpi_rx_desc *desc) ifp->if_opackets++; /* Unmap and free mbuf. */ + bus_dmamap_sync(sc->sc_dmat, data->map, 0, data->map->dm_mapsize, + BUS_DMASYNC_POSTWRITE); bus_dmamap_unload(sc->sc_dmat, data->map); m_freem(data->m); data->m = NULL; @@ -1394,6 +1408,8 @@ wpi_cmd_done(struct wpi_softc *sc, struct wpi_rx_desc *desc) /* If the command was mapped in an mbuf, free it. */ if (data->m != NULL) { + bus_dmamap_sync(sc->sc_dmat, data->map, 0, + data->map->dm_mapsize, BUS_DMASYNC_POSTWRITE); bus_dmamap_unload(sc->sc_dmat, data->map); m_freem(data->m); data->m = NULL; @@ -1408,11 +1424,18 @@ wpi_notif_intr(struct wpi_softc *sc) struct ifnet *ifp = &ic->ic_if; uint32_t hw; + bus_dmamap_sync(sc->sc_dmat, sc->shared_dma.map, 0, + sizeof (struct wpi_shared), BUS_DMASYNC_POSTREAD); + hw = letoh32(sc->shared->next); while (sc->rxq.cur != hw) { struct wpi_rx_data *data = &sc->rxq.data[sc->rxq.cur]; struct wpi_rx_desc *desc = (void *)data->m->m_ext.ext_buf; + bus_dmamap_sync(sc->sc_dmat, sc->rxq.buf_dma.map, + (caddr_t)desc - sc->rxq.buf_dma.vaddr, sizeof (*desc), + BUS_DMASYNC_POSTREAD); + DPRINTFN(4, ("rx notification qid=%x idx=%d flags=%x type=%d " "len=%d\n", desc->qid, desc->idx, desc->flags, desc->type, letoh32(desc->len))); @@ -1437,6 +1460,9 @@ wpi_notif_intr(struct wpi_softc *sc) (struct wpi_ucode_info *)(desc + 1); /* The microcontroller is ready. */ + bus_dmamap_sync(sc->sc_dmat, sc->rxq.buf_dma.map, + (caddr_t)uc - sc->rxq.buf_dma.vaddr, + sizeof (*uc), BUS_DMASYNC_POSTREAD); DPRINTF(("microcode alive notification version %x " "alive %x\n", letoh32(uc->version), letoh32(uc->valid))); @@ -1456,6 +1482,9 @@ wpi_notif_intr(struct wpi_softc *sc) uint32_t *status = (uint32_t *)(desc + 1); /* Enabled/disabled notification. */ + bus_dmamap_sync(sc->sc_dmat, sc->rxq.buf_dma.map, + (caddr_t)status - sc->rxq.buf_dma.vaddr, + sizeof (*status), BUS_DMASYNC_POSTREAD); DPRINTF(("state changed to %x\n", letoh32(*status))); if (letoh32(*status) & 1) { @@ -1474,6 +1503,9 @@ wpi_notif_intr(struct wpi_softc *sc) struct wpi_start_scan *scan = (struct wpi_start_scan *)(desc + 1); + bus_dmamap_sync(sc->sc_dmat, sc->rxq.buf_dma.map, + (caddr_t)scan - sc->rxq.buf_dma.vaddr, + sizeof (*scan), BUS_DMASYNC_POSTREAD); DPRINTFN(2, ("scanning channel %d status %x\n", scan->chan, letoh32(scan->status))); @@ -1486,6 +1518,9 @@ wpi_notif_intr(struct wpi_softc *sc) struct wpi_stop_scan *scan = (struct wpi_stop_scan *)(desc + 1); + bus_dmamap_sync(sc->sc_dmat, sc->rxq.buf_dma.map, + (caddr_t)scan - sc->rxq.buf_dma.vaddr, + sizeof (*scan), BUS_DMASYNC_POSTREAD); DPRINTF(("scan finished nchan=%d status=%d chan=%d\n", scan->nchan, scan->status, scan->chan)); @@ -1866,6 +1901,15 @@ wpi_tx(struct wpi_softc *sc, struct mbuf *m, struct ieee80211_node *ni) htole32(data->map->dm_segs[i - 1].ds_len); } + bus_dmamap_sync(sc->sc_dmat, data->map, 0, data->map->dm_mapsize, + BUS_DMASYNC_PREWRITE); + bus_dmamap_sync(sc->sc_dmat, ring->cmd_dma.map, + (caddr_t)cmd - ring->cmd_dma.vaddr, sizeof (*cmd), + BUS_DMASYNC_PREWRITE); + bus_dmamap_sync(sc->sc_dmat, ring->desc_dma.map, + (caddr_t)desc - ring->desc_dma.vaddr, sizeof (*desc), + BUS_DMASYNC_PREWRITE); + /* Kick TX ring. */ ring->cur = (ring->cur + 1) % WPI_TX_RING_COUNT; WPI_WRITE(sc, WPI_HBUS_TARG_WRPTR, ring->qid << 8 | ring->cur); @@ -2078,6 +2122,18 @@ wpi_cmd(struct wpi_softc *sc, int code, const void *buf, int size, int async) desc->segs[0].addr = htole32(paddr); desc->segs[0].len = htole32(totlen); + if (size > sizeof cmd->data) { + bus_dmamap_sync(sc->sc_dmat, data->map, 0, totlen, + BUS_DMASYNC_PREWRITE); + } else { + bus_dmamap_sync(sc->sc_dmat, ring->cmd_dma.map, + (caddr_t)cmd - ring->cmd_dma.vaddr, totlen, + BUS_DMASYNC_PREWRITE); + } + bus_dmamap_sync(sc->sc_dmat, ring->desc_dma.map, + (caddr_t)desc - ring->desc_dma.vaddr, sizeof (*desc), + BUS_DMASYNC_PREWRITE); + /* Kick command ring. */ ring->cur = (ring->cur + 1) % WPI_TX_RING_COUNT; WPI_WRITE(sc, WPI_HBUS_TARG_WRPTR, ring->qid << 8 | ring->cur); @@ -2870,8 +2926,12 @@ wpi_load_firmware(struct wpi_softc *sc) /* Copy initialization sections into pre-allocated DMA-safe memory. */ memcpy(dma->vaddr, fw->init.data, fw->init.datasz); + bus_dmamap_sync(sc->sc_dmat, dma->map, 0, fw->init.datasz, + BUS_DMASYNC_PREWRITE); memcpy(dma->vaddr + WPI_FW_DATA_MAXSZ, fw->init.text, fw->init.textsz); + bus_dmamap_sync(sc->sc_dmat, dma->map, WPI_FW_DATA_MAXSZ, + fw->init.textsz, BUS_DMASYNC_PREWRITE); /* Tell adapter where to find initialization sections. */ if ((error = wpi_nic_lock(sc)) != 0) @@ -2902,8 +2962,12 @@ wpi_load_firmware(struct wpi_softc *sc) /* Copy runtime sections into pre-allocated DMA-safe memory. */ memcpy(dma->vaddr, fw->main.data, fw->main.datasz); + bus_dmamap_sync(sc->sc_dmat, dma->map, 0, fw->main.datasz, + BUS_DMASYNC_PREWRITE); memcpy(dma->vaddr + WPI_FW_DATA_MAXSZ, fw->main.text, fw->main.textsz); + bus_dmamap_sync(sc->sc_dmat, dma->map, WPI_FW_DATA_MAXSZ, + fw->main.textsz, BUS_DMASYNC_PREWRITE); /* Tell adapter where to find runtime sections. */ if ((error = wpi_nic_lock(sc)) != 0) |