Module Name: src Committed By: knakahara Date: Wed May 18 06:55:52 UTC 2016
Modified Files: src/sys/dev/pci: if_wm.c Log Message: fix unmatched dma sync size for NEWQUEUE. This bug would have caused wm_nq_tx_offload() not to work. To generate a diff of this commit: cvs rdiff -u -r1.397 -r1.398 src/sys/dev/pci/if_wm.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/dev/pci/if_wm.c diff -u src/sys/dev/pci/if_wm.c:1.397 src/sys/dev/pci/if_wm.c:1.398 --- src/sys/dev/pci/if_wm.c:1.397 Wed May 11 04:37:09 2016 +++ src/sys/dev/pci/if_wm.c Wed May 18 06:55:51 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: if_wm.c,v 1.397 2016/05/11 04:37:09 msaitoh Exp $ */ +/* $NetBSD: if_wm.c,v 1.398 2016/05/18 06:55:51 knakahara Exp $ */ /* * Copyright (c) 2001, 2002, 2003, 2004 Wasabi Systems, Inc. @@ -83,7 +83,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: if_wm.c,v 1.397 2016/05/11 04:37:09 msaitoh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: if_wm.c,v 1.398 2016/05/18 06:55:51 knakahara Exp $"); #ifdef _KERNEL_OPT #include "opt_net_mpsafe.h" @@ -188,7 +188,7 @@ int wm_debug = WM_DEBUG_TX | WM_DEBUG_RX #define WM_NTXDESC_82544 4096 #define WM_NTXDESC(txq) ((txq)->txq_ndesc) #define WM_NTXDESC_MASK(txq) (WM_NTXDESC(txq) - 1) -#define WM_TXDESCSIZE(txq) (WM_NTXDESC(txq) * sizeof(wiseman_txdesc_t)) +#define WM_TXDESCS_SIZE(txq) (WM_NTXDESC(txq) * (txq)->txq_descsize) #define WM_NEXTTX(txq, x) (((x) + 1) & WM_NTXDESC_MASK(txq)) #define WM_NEXTTXS(txq, x) (((x) + 1) & WM_TXQUEUELEN_MASK(txq)) @@ -210,7 +210,7 @@ typedef union txdescs { nq_txdesc_t sctxu_nq_txdescs[WM_NTXDESC_82544]; } txdescs_t; -#define WM_CDTXOFF(x) (sizeof(wiseman_txdesc_t) * x) +#define WM_CDTXOFF(txq, x) ((txq)->txq_descsize * (x)) #define WM_CDRXOFF(x) (sizeof(wiseman_rxdesc_t) * x) /* @@ -263,11 +263,12 @@ struct wm_txqueue { /* TX control data structures. */ int txq_ndesc; /* must be a power of two */ + size_t txq_descsize; /* a tx descriptor size */ txdescs_t *txq_descs_u; bus_dmamap_t txq_desc_dmamap; /* control data DMA map */ bus_dma_segment_t txq_desc_seg; /* control data segment */ int txq_desc_rseg; /* real number of control segment */ - size_t txq_desc_size; /* control data size */ + size_t txq_descs_size; /* control data size */ #define txq_desc_dma txq_desc_dmamap->dm_segs[0].ds_addr #define txq_descs txq_descs_u->sctxu_txdescs #define txq_nq_descs txq_descs_u->sctxu_nq_txdescs @@ -509,7 +510,7 @@ do { \ bus_space_write_2((sc)->sc_flasht, (sc)->sc_flashh, \ (reg) + sc->sc_flashreg_offset, (data)) -#define WM_CDTXADDR(txq, x) ((txq)->txq_desc_dma + WM_CDTXOFF((x))) +#define WM_CDTXADDR(txq, x) ((txq)->txq_desc_dma + WM_CDTXOFF((txq), (x))) #define WM_CDRXADDR(rxq, x) ((rxq)->rxq_desc_dma + WM_CDRXOFF((x))) #define WM_CDTXADDR_LO(txq, x) (WM_CDTXADDR((txq), (x)) & 0xffffffffU) @@ -1384,7 +1385,7 @@ wm_cdtxsync(struct wm_txqueue *txq, int /* If it will wrap around, sync to the end of the ring. */ if ((start + num) > WM_NTXDESC(txq)) { bus_dmamap_sync(sc->sc_dmat, txq->txq_desc_dmamap, - WM_CDTXOFF(start), sizeof(wiseman_txdesc_t) * + WM_CDTXOFF(txq, start), txq->txq_descsize * (WM_NTXDESC(txq) - start), ops); num -= (WM_NTXDESC(txq) - start); start = 0; @@ -1392,7 +1393,7 @@ wm_cdtxsync(struct wm_txqueue *txq, int /* Now sync whatever is left. */ bus_dmamap_sync(sc->sc_dmat, txq->txq_desc_dmamap, - WM_CDTXOFF(start), sizeof(wiseman_txdesc_t) * num, ops); + WM_CDTXOFF(txq, start), txq->txq_descsize * num, ops); } static inline void @@ -5358,13 +5359,17 @@ wm_alloc_tx_descs(struct wm_softc *sc, s */ if (sc->sc_type < WM_T_82544) { WM_NTXDESC(txq) = WM_NTXDESC_82542; - txq->txq_desc_size = sizeof(wiseman_txdesc_t) *WM_NTXDESC(txq); + txq->txq_descs_size = sizeof(wiseman_txdesc_t) *WM_NTXDESC(txq); } else { WM_NTXDESC(txq) = WM_NTXDESC_82544; - txq->txq_desc_size = sizeof(txdescs_t); + txq->txq_descs_size = sizeof(txdescs_t); } + if ((sc->sc_flags & WM_F_NEWQUEUE) != 0) + txq->txq_descsize = sizeof(nq_txdesc_t); + else + txq->txq_descsize = sizeof(wiseman_txdesc_t); - if ((error = bus_dmamem_alloc(sc->sc_dmat, txq->txq_desc_size, + if ((error = bus_dmamem_alloc(sc->sc_dmat, txq->txq_descs_size, PAGE_SIZE, (bus_size_t) 0x100000000ULL, &txq->txq_desc_seg, 1, &txq->txq_desc_rseg, 0)) != 0) { aprint_error_dev(sc->sc_dev, @@ -5374,15 +5379,15 @@ wm_alloc_tx_descs(struct wm_softc *sc, s } if ((error = bus_dmamem_map(sc->sc_dmat, &txq->txq_desc_seg, - txq->txq_desc_rseg, txq->txq_desc_size, + txq->txq_desc_rseg, txq->txq_descs_size, (void **)&txq->txq_descs_u, BUS_DMA_COHERENT)) != 0) { aprint_error_dev(sc->sc_dev, "unable to map TX control data, error = %d\n", error); goto fail_1; } - if ((error = bus_dmamap_create(sc->sc_dmat, txq->txq_desc_size, 1, - txq->txq_desc_size, 0, 0, &txq->txq_desc_dmamap)) != 0) { + if ((error = bus_dmamap_create(sc->sc_dmat, txq->txq_descs_size, 1, + txq->txq_descs_size, 0, 0, &txq->txq_desc_dmamap)) != 0) { aprint_error_dev(sc->sc_dev, "unable to create TX control data DMA map, error = %d\n", error); @@ -5390,7 +5395,7 @@ wm_alloc_tx_descs(struct wm_softc *sc, s } if ((error = bus_dmamap_load(sc->sc_dmat, txq->txq_desc_dmamap, - txq->txq_descs_u, txq->txq_desc_size, NULL, 0)) != 0) { + txq->txq_descs_u, txq->txq_descs_size, NULL, 0)) != 0) { aprint_error_dev(sc->sc_dev, "unable to load TX control data DMA map, error = %d\n", error); @@ -5403,7 +5408,7 @@ wm_alloc_tx_descs(struct wm_softc *sc, s bus_dmamap_destroy(sc->sc_dmat, txq->txq_desc_dmamap); fail_2: bus_dmamem_unmap(sc->sc_dmat, (void *)txq->txq_descs_u, - txq->txq_desc_size); + txq->txq_descs_size); fail_1: bus_dmamem_free(sc->sc_dmat, &txq->txq_desc_seg, txq->txq_desc_rseg); fail_0: @@ -5417,7 +5422,7 @@ wm_free_tx_descs(struct wm_softc *sc, st bus_dmamap_unload(sc->sc_dmat, txq->txq_desc_dmamap); bus_dmamap_destroy(sc->sc_dmat, txq->txq_desc_dmamap); bus_dmamem_unmap(sc->sc_dmat, (void *)txq->txq_descs_u, - txq->txq_desc_size); + txq->txq_descs_size); bus_dmamem_free(sc->sc_dmat, &txq->txq_desc_seg, txq->txq_desc_rseg); } @@ -5717,7 +5722,7 @@ wm_init_tx_descs(struct wm_softc *sc __u KASSERT(WM_TX_LOCKED(txq)); /* Initialize the transmit descriptor ring. */ - memset(txq->txq_descs, 0, WM_TXDESCSIZE(txq)); + memset(txq->txq_descs, 0, WM_TXDESCS_SIZE(txq)); wm_cdtxsync(txq, 0, WM_NTXDESC(txq), BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); txq->txq_free = WM_NTXDESC(txq); @@ -5733,7 +5738,7 @@ wm_init_tx_regs(struct wm_softc *sc, str if (sc->sc_type < WM_T_82543) { CSR_WRITE(sc, WMREG_OLD_TDBAH, WM_CDTXADDR_HI(txq, 0)); CSR_WRITE(sc, WMREG_OLD_TDBAL, WM_CDTXADDR_LO(txq, 0)); - CSR_WRITE(sc, WMREG_OLD_TDLEN, WM_TXDESCSIZE(txq)); + CSR_WRITE(sc, WMREG_OLD_TDLEN, WM_TXDESCS_SIZE(txq)); CSR_WRITE(sc, WMREG_OLD_TDH, 0); CSR_WRITE(sc, WMREG_OLD_TDT, 0); CSR_WRITE(sc, WMREG_OLD_TIDV, 128); @@ -5742,7 +5747,7 @@ wm_init_tx_regs(struct wm_softc *sc, str CSR_WRITE(sc, WMREG_TDBAH(qid), WM_CDTXADDR_HI(txq, 0)); CSR_WRITE(sc, WMREG_TDBAL(qid), WM_CDTXADDR_LO(txq, 0)); - CSR_WRITE(sc, WMREG_TDLEN(qid), WM_TXDESCSIZE(txq)); + CSR_WRITE(sc, WMREG_TDLEN(qid), WM_TXDESCS_SIZE(txq)); CSR_WRITE(sc, WMREG_TDH(qid), 0); if ((sc->sc_flags & WM_F_NEWQUEUE) != 0)