Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/pci separate TX dma control data and RX dma control ...
details: https://anonhg.NetBSD.org/src/rev/ff19cbdaac20
branches: trunk
changeset: 340964:ff19cbdaac20
user: knakahara <knakahara%NetBSD.org@localhost>
date: Tue Oct 13 08:00:15 2015 +0000
description:
separate TX dma control data and RX dma control data.
ok by msaitoh@n.o
diffstat:
sys/dev/pci/if_wm.c | 245 +++++++++++++++++++++++++++++++++------------------
1 files changed, 160 insertions(+), 85 deletions(-)
diffs (truncated from 382 to 300 lines):
diff -r c989c93649d1 -r ff19cbdaac20 sys/dev/pci/if_wm.c
--- a/sys/dev/pci/if_wm.c Tue Oct 13 07:53:02 2015 +0000
+++ b/sys/dev/pci/if_wm.c Tue Oct 13 08:00:15 2015 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: if_wm.c,v 1.353 2015/10/13 07:53:02 knakahara Exp $ */
+/* $NetBSD: if_wm.c,v 1.354 2015/10/13 08:00:15 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.353 2015/10/13 07:53:02 knakahara Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_wm.c,v 1.354 2015/10/13 08:00:15 knakahara Exp $");
#ifdef _KERNEL_OPT
#include "opt_net_mpsafe.h"
@@ -219,35 +219,13 @@
#define WM_NEXTRX(x) (((x) + 1) & WM_NRXDESC_MASK)
#define WM_PREVRX(x) (((x) - 1) & WM_NRXDESC_MASK)
-/*
- * Control structures are DMA'd to the i82542 chip. We allocate them in
- * a single clump that maps to a single DMA segment to make several things
- * easier.
- */
-struct wm_control_data_82544 {
- /*
- * The receive descriptors.
- */
- wiseman_rxdesc_t wcd_rxdescs[WM_NRXDESC];
-
- /*
- * The transmit descriptors. Put these at the end, because
- * we might use a smaller number of them.
- */
- union {
- wiseman_txdesc_t wcdu_txdescs[WM_NTXDESC_82544];
- nq_txdesc_t wcdu_nq_txdescs[WM_NTXDESC_82544];
- } wdc_u;
-};
-
-struct wm_control_data_82542 {
- wiseman_rxdesc_t wcd_rxdescs[WM_NRXDESC];
- wiseman_txdesc_t wcd_txdescs[WM_NTXDESC_82542];
-};
-
-#define WM_CDOFF(x) offsetof(struct wm_control_data_82544, x)
-#define WM_CDTXOFF(x) WM_CDOFF(wdc_u.wcdu_txdescs[(x)])
-#define WM_CDRXOFF(x) WM_CDOFF(wcd_rxdescs[(x)])
+typedef union txdescs {
+ wiseman_txdesc_t sctxu_txdescs[WM_NTXDESC_82544];
+ nq_txdesc_t sctxu_nq_txdescs[WM_NTXDESC_82544];
+} txdescs_t;
+
+#define WM_CDTXOFF(x) (sizeof(wiseman_txdesc_t) * x)
+#define WM_CDRXOFF(x) (sizeof(wiseman_rxdesc_t) * x)
/*
* Software state for transmit jobs.
@@ -346,17 +324,24 @@
struct wm_txsoft sc_txsoft[WM_TXQUEUELEN_MAX];
struct wm_rxsoft sc_rxsoft[WM_NRXDESC];
- /* Control data structures. */
+ /* TX control data structures. */
int sc_ntxdesc; /* must be a power of two */
- struct wm_control_data_82544 *sc_control_data;
- bus_dmamap_t sc_cddmamap; /* control data DMA map */
- bus_dma_segment_t sc_cd_seg; /* control data segment */
- int sc_cd_rseg; /* real number of control segment */
- size_t sc_cd_size; /* control data size */
-#define sc_cddma sc_cddmamap->dm_segs[0].ds_addr
-#define sc_txdescs sc_control_data->wdc_u.wcdu_txdescs
-#define sc_nq_txdescs sc_control_data->wdc_u.wcdu_nq_txdescs
-#define sc_rxdescs sc_control_data->wcd_rxdescs
+ txdescs_t *sc_txdescs_u;
+ bus_dmamap_t sc_txdesc_dmamap; /* control data DMA map */
+ bus_dma_segment_t sc_txdesc_seg;/* control data segment */
+ int sc_txdesc_rseg; /* real number of control segment */
+ size_t sc_txdesc_size; /* control data size */
+#define sc_txdesc_dma sc_txdesc_dmamap->dm_segs[0].ds_addr
+#define sc_txdescs sc_txdescs_u->sctxu_txdescs
+#define sc_nq_txdescs sc_txdescs_u->sctxu_nq_txdescs
+
+ /* RX control data structures. */
+ wiseman_rxdesc_t *sc_rxdescs;
+ bus_dmamap_t sc_rxdesc_dmamap; /* control data DMA map */
+ bus_dma_segment_t sc_rxdesc_seg;/* control data segment */
+ int sc_rxdesc_rseg; /* real number of control segment */
+ size_t sc_rxdesc_size; /* control data size */
+#define sc_rxdesc_dma sc_rxdesc_dmamap->dm_segs[0].ds_addr
#ifdef WM_EVENT_COUNTERS
/* Event counters. */
@@ -493,8 +478,8 @@
#define ICH8_FLASH_WRITE16(sc, reg, data) \
bus_space_write_2((sc)->sc_flasht, (sc)->sc_flashh, (reg), (data))
-#define WM_CDTXADDR(sc, x) ((sc)->sc_cddma + WM_CDTXOFF((x)))
-#define WM_CDRXADDR(sc, x) ((sc)->sc_cddma + WM_CDRXOFF((x)))
+#define WM_CDTXADDR(sc, x) ((sc)->sc_txdesc_dma + WM_CDTXOFF((x)))
+#define WM_CDRXADDR(sc, x) ((sc)->sc_rxdesc_dma + WM_CDRXOFF((x)))
#define WM_CDTXADDR_LO(sc, x) (WM_CDTXADDR((sc), (x)) & 0xffffffffU)
#define WM_CDTXADDR_HI(sc, x) \
@@ -566,8 +551,10 @@
static void wm_82547_txfifo_stall(void *);
static int wm_82547_txfifo_bugchk(struct wm_softc *, struct mbuf *);
/* DMA related */
-static int wm_alloc_descs(struct wm_softc *);
-static void wm_free_descs(struct wm_softc *);
+static int wm_alloc_tx_descs(struct wm_softc *);
+static void wm_free_tx_descs(struct wm_softc *);
+static int wm_alloc_rx_descs(struct wm_softc *);
+static void wm_free_rx_descs(struct wm_softc *);
static int wm_alloc_tx_buffer(struct wm_softc *);
static void wm_free_tx_buffer(struct wm_softc *);
static int wm_alloc_rx_buffer(struct wm_softc *);
@@ -1346,7 +1333,7 @@
/* If it will wrap around, sync to the end of the ring. */
if ((start + num) > WM_NTXDESC(sc)) {
- bus_dmamap_sync(sc->sc_dmat, sc->sc_cddmamap,
+ bus_dmamap_sync(sc->sc_dmat, sc->sc_txdesc_dmamap,
WM_CDTXOFF(start), sizeof(wiseman_txdesc_t) *
(WM_NTXDESC(sc) - start), ops);
num -= (WM_NTXDESC(sc) - start);
@@ -1354,7 +1341,7 @@
}
/* Now sync whatever is left. */
- bus_dmamap_sync(sc->sc_dmat, sc->sc_cddmamap,
+ bus_dmamap_sync(sc->sc_dmat, sc->sc_txdesc_dmamap,
WM_CDTXOFF(start), sizeof(wiseman_txdesc_t) * num, ops);
}
@@ -1362,7 +1349,7 @@
wm_cdrxsync(struct wm_softc *sc, int start, int ops)
{
- bus_dmamap_sync(sc->sc_dmat, sc->sc_cddmamap,
+ bus_dmamap_sync(sc->sc_dmat, sc->sc_rxdesc_dmamap,
WM_CDRXOFF(start), sizeof(wiseman_rxdesc_t), ops);
}
@@ -5096,7 +5083,7 @@
}
static int
-wm_alloc_descs(struct wm_softc *sc)
+wm_alloc_tx_descs(struct wm_softc *sc)
{
int error;
@@ -5108,40 +5095,43 @@
* memory. So must Rx descriptors. We simplify by allocating
* both sets within the same 4G segment.
*/
- WM_NTXDESC(sc) = sc->sc_type < WM_T_82544 ?
- WM_NTXDESC_82542 : WM_NTXDESC_82544;
- sc->sc_cd_size = sc->sc_type < WM_T_82544 ?
- sizeof(struct wm_control_data_82542) :
- sizeof(struct wm_control_data_82544);
- if ((error = bus_dmamem_alloc(sc->sc_dmat, sc->sc_cd_size, PAGE_SIZE,
- (bus_size_t) 0x100000000ULL, &sc->sc_cd_seg, 1,
- &sc->sc_cd_rseg, 0)) != 0) {
+ if (sc->sc_type < WM_T_82544) {
+ WM_NTXDESC(sc) = WM_NTXDESC_82542;
+ sc->sc_txdesc_size = sizeof(wiseman_txdesc_t) * WM_NTXDESC(sc);
+ } else {
+ WM_NTXDESC(sc) = WM_NTXDESC_82544;
+ sc->sc_txdesc_size = sizeof(txdescs_t);
+ }
+
+ if ((error = bus_dmamem_alloc(sc->sc_dmat, sc->sc_txdesc_size, PAGE_SIZE,
+ (bus_size_t) 0x100000000ULL, &sc->sc_txdesc_seg, 1,
+ &sc->sc_txdesc_rseg, 0)) != 0) {
aprint_error_dev(sc->sc_dev,
- "unable to allocate control data, error = %d\n",
+ "unable to allocate TX control data, error = %d\n",
error);
goto fail_0;
}
- if ((error = bus_dmamem_map(sc->sc_dmat, &sc->sc_cd_seg,
- sc->sc_cd_rseg, sc->sc_cd_size,
- (void **)&sc->sc_control_data, BUS_DMA_COHERENT)) != 0) {
+ if ((error = bus_dmamem_map(sc->sc_dmat, &sc->sc_txdesc_seg,
+ sc->sc_txdesc_rseg, sc->sc_txdesc_size,
+ (void **)&sc->sc_txdescs_u, BUS_DMA_COHERENT)) != 0) {
aprint_error_dev(sc->sc_dev,
- "unable to map control data, error = %d\n", error);
+ "unable to map TX control data, error = %d\n", error);
goto fail_1;
}
- if ((error = bus_dmamap_create(sc->sc_dmat, sc->sc_cd_size, 1,
- sc->sc_cd_size, 0, 0, &sc->sc_cddmamap)) != 0) {
+ if ((error = bus_dmamap_create(sc->sc_dmat, sc->sc_txdesc_size, 1,
+ sc->sc_txdesc_size, 0, 0, &sc->sc_txdesc_dmamap)) != 0) {
aprint_error_dev(sc->sc_dev,
- "unable to create control data DMA map, error = %d\n",
+ "unable to create TX control data DMA map, error = %d\n",
error);
goto fail_2;
}
- if ((error = bus_dmamap_load(sc->sc_dmat, sc->sc_cddmamap,
- sc->sc_control_data, sc->sc_cd_size, NULL, 0)) != 0) {
+ if ((error = bus_dmamap_load(sc->sc_dmat, sc->sc_txdesc_dmamap,
+ sc->sc_txdescs_u, sc->sc_txdesc_size, NULL, 0)) != 0) {
aprint_error_dev(sc->sc_dev,
- "unable to load control data DMA map, error = %d\n",
+ "unable to load TX control data DMA map, error = %d\n",
error);
goto fail_3;
}
@@ -5149,26 +5139,98 @@
return 0;
fail_3:
- bus_dmamap_destroy(sc->sc_dmat, sc->sc_cddmamap);
+ bus_dmamap_destroy(sc->sc_dmat, sc->sc_txdesc_dmamap);
fail_2:
- bus_dmamem_unmap(sc->sc_dmat, (void *)sc->sc_control_data,
- sc->sc_cd_size);
+ bus_dmamem_unmap(sc->sc_dmat, (void *)sc->sc_txdescs_u,
+ sc->sc_txdesc_size);
fail_1:
- bus_dmamem_free(sc->sc_dmat, &sc->sc_cd_seg, sc->sc_cd_rseg);
+ bus_dmamem_free(sc->sc_dmat, &sc->sc_txdesc_seg, sc->sc_txdesc_rseg);
fail_0:
return error;
}
static void
-wm_free_descs(struct wm_softc *sc)
-{
-
- bus_dmamap_unload(sc->sc_dmat, sc->sc_cddmamap);
- bus_dmamap_destroy(sc->sc_dmat, sc->sc_cddmamap);
- bus_dmamem_unmap(sc->sc_dmat, (void *)sc->sc_control_data,
- sc->sc_cd_size);
- bus_dmamem_free(sc->sc_dmat, &sc->sc_cd_seg, sc->sc_cd_rseg);
-}
+wm_free_tx_descs(struct wm_softc *sc)
+{
+
+ bus_dmamap_unload(sc->sc_dmat, sc->sc_txdesc_dmamap);
+ bus_dmamap_destroy(sc->sc_dmat, sc->sc_txdesc_dmamap);
+ bus_dmamem_unmap(sc->sc_dmat, (void *)sc->sc_txdescs_u,
+ sc->sc_txdesc_size);
+ bus_dmamem_free(sc->sc_dmat, &sc->sc_txdesc_seg, sc->sc_txdesc_rseg);
+}
+
+static int
+wm_alloc_rx_descs(struct wm_softc *sc)
+{
+ int error;
+
+ /*
+ * Allocate the control data structures, and create and load the
+ * DMA map for it.
+ *
+ * NOTE: All Tx descriptors must be in the same 4G segment of
+ * memory. So must Rx descriptors. We simplify by allocating
+ * both sets within the same 4G segment.
+ */
+ sc->sc_rxdesc_size = sizeof(wiseman_rxdesc_t) * WM_NRXDESC;
+ if ((error = bus_dmamem_alloc(sc->sc_dmat, sc->sc_rxdesc_size, PAGE_SIZE,
+ (bus_size_t) 0x100000000ULL, &sc->sc_rxdesc_seg, 1,
+ &sc->sc_rxdesc_rseg, 0)) != 0) {
+ aprint_error_dev(sc->sc_dev,
+ "unable to allocate RX control data, error = %d\n",
+ error);
+ goto fail_0;
+ }
+
+ if ((error = bus_dmamem_map(sc->sc_dmat, &sc->sc_rxdesc_seg,
+ sc->sc_rxdesc_rseg, sc->sc_rxdesc_size,
+ (void **)&sc->sc_rxdescs, BUS_DMA_COHERENT)) != 0) {
+ aprint_error_dev(sc->sc_dev,
+ "unable to map RX control data, error = %d\n", error);
+ goto fail_1;
+ }
+
+ if ((error = bus_dmamap_create(sc->sc_dmat, sc->sc_rxdesc_size, 1,
+ sc->sc_rxdesc_size, 0, 0, &sc->sc_rxdesc_dmamap)) != 0) {
+ aprint_error_dev(sc->sc_dev,
+ "unable to create RX control data DMA map, error = %d\n",
+ error);
+ goto fail_2;
+ }
+
+ if ((error = bus_dmamap_load(sc->sc_dmat, sc->sc_rxdesc_dmamap,
+ sc->sc_rxdescs, sc->sc_rxdesc_size, NULL, 0)) != 0) {
+ aprint_error_dev(sc->sc_dev,
+ "unable to load RX control data DMA map, error = %d\n",
Home |
Main Index |
Thread Index |
Old Index