Module Name:    src
Committed By:   martin
Date:           Tue Aug 11 17:14:21 UTC 2020

Modified Files:
        src/sys/dev/ic [netbsd-9]: dwc_gmac.c dwc_gmac_reg.h
        src/sys/kern [netbsd-9]: uipc_mbuf.c

Log Message:
Pull up following revision(s) (requested by mrg in ticket #1045):

        sys/kern/uipc_mbuf.c: revision 1.235
        sys/dev/ic/dwc_gmac.c: revision 1.70
        sys/dev/ic/dwc_gmac_reg.h: revision 1.20
        sys/dev/ic/dwc_gmac.c: revision 1.66
        sys/dev/ic/dwc_gmac.c: revision 1.67
        sys/dev/ic/dwc_gmac.c: revision 1.68

awge: fix issue that caused rx packets to be corrupt with DIAGNOSTIC kernel

It seems the hardware can only reliably do rx DMA to addresses that are
dcache size aligned. This is hinted at by some GMAC data sheets but hard to
find an authoritative source.

on non-DIAGNOSTIC kernels we always implicitly get MCLBYTES-aligned mbuf
data pointers, but with the reintroduction of POOL_REDZONE for DIAGNOSTIC
we can get 8-byte alignment due to redzone padding. So align rx pointers to
64 bytes which should be good for both arm32 and aarch64.
While here change some bus_dmamap_load() to bus_dmamap_load_mbuf() and add
one missing bus_dmamap_sync(). Also fixes the code to not assume that
MCLBYTES == AWGE_MAX_PACKET. User may override MCLSHIFT in kernel config.
correct pointer arithmetics

mcl_cache: align items to COHERENCY_UNIT

Because we do cache incoherent DMA to/from mbufs we cannot safely share
share cache lines with adjacent items that may be concurrently accessed.

awge: drop redundant m_adj(). Handled via uipc_mbuf.c r1.235 instead.

Mask all the MMC counter interrupts if the MMC module is present.


To generate a diff of this commit:
cvs rdiff -u -r1.64 -r1.64.2.1 src/sys/dev/ic/dwc_gmac.c
cvs rdiff -u -r1.19 -r1.19.4.1 src/sys/dev/ic/dwc_gmac_reg.h
cvs rdiff -u -r1.232 -r1.232.4.1 src/sys/kern/uipc_mbuf.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/ic/dwc_gmac.c
diff -u src/sys/dev/ic/dwc_gmac.c:1.64 src/sys/dev/ic/dwc_gmac.c:1.64.2.1
--- src/sys/dev/ic/dwc_gmac.c:1.64	Sun Jul 21 08:24:32 2019
+++ src/sys/dev/ic/dwc_gmac.c	Tue Aug 11 17:14:21 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: dwc_gmac.c,v 1.64 2019/07/21 08:24:32 mrg Exp $ */
+/* $NetBSD: dwc_gmac.c,v 1.64.2.1 2020/08/11 17:14:21 martin Exp $ */
 
 /*-
  * Copyright (c) 2013, 2014 The NetBSD Foundation, Inc.
@@ -41,7 +41,7 @@
 
 #include <sys/cdefs.h>
 
-__KERNEL_RCSID(1, "$NetBSD: dwc_gmac.c,v 1.64 2019/07/21 08:24:32 mrg Exp $");
+__KERNEL_RCSID(1, "$NetBSD: dwc_gmac.c,v 1.64.2.1 2020/08/11 17:14:21 martin Exp $");
 
 /* #define	DWC_GMAC_DEBUG	1 */
 
@@ -254,6 +254,16 @@ dwc_gmac_attach(struct dwc_gmac_softc *s
 	} else {
 		sc->sc_descm = &desc_methods_standard;
 	}
+	if (hwft & GMAC_DMA_FEAT_RMON) {
+		uint32_t val;
+
+		/* Mask all MMC interrupts */
+		val = 0xffffffff;
+		bus_space_write_4(sc->sc_bst, sc->sc_bsh,
+		    GMAC_MMC_RX_INT_MSK, val);
+		bus_space_write_4(sc->sc_bst, sc->sc_bsh,
+		    GMAC_MMC_TX_INT_MSK, val);
+	}
 
 	/*
 	 * Allocate Tx and Rx rings
@@ -499,15 +509,22 @@ dwc_gmac_alloc_rx_ring(struct dwc_gmac_s
 			error = ENOMEM;
 			goto fail;
 		}
+		data->rd_m->m_len = data->rd_m->m_pkthdr.len
+		    = data->rd_m->m_ext.ext_size;
+		if (data->rd_m->m_len > AWGE_MAX_PACKET) {
+			data->rd_m->m_len = data->rd_m->m_pkthdr.len
+			    = AWGE_MAX_PACKET;
+		}
 
-		error = bus_dmamap_load(sc->sc_dmat, data->rd_map,
-		    mtod(data->rd_m, void *), MCLBYTES, NULL,
-		    BUS_DMA_READ | BUS_DMA_NOWAIT);
+		error = bus_dmamap_load_mbuf(sc->sc_dmat, data->rd_map,
+		    data->rd_m, BUS_DMA_READ | BUS_DMA_NOWAIT);
 		if (error != 0) {
 			aprint_error_dev(sc->sc_dev,
 			    "could not load rx buf DMA map #%d", i);
 			goto fail;
 		}
+		bus_dmamap_sync(sc->sc_dmat, data->rd_map, 0,
+		    data->rd_map->dm_mapsize, BUS_DMASYNC_PREREAD);
 		physaddr = data->rd_map->dm_segs[0].ds_addr;
 
 		desc = &sc->sc_rxq.r_desc[i];
@@ -516,7 +533,7 @@ dwc_gmac_alloc_rx_ring(struct dwc_gmac_s
 		desc->ddesc_next = htole32(ring->r_physaddr
 		    + next * sizeof(*desc));
 		sc->sc_descm->rx_init_flags(desc);
-		sc->sc_descm->rx_set_len(desc, AWGE_MAX_PACKET);
+		sc->sc_descm->rx_set_len(desc, data->rd_m->m_len);
 		sc->sc_descm->rx_set_owned_by_dev(desc);
 	}
 
@@ -538,13 +555,15 @@ dwc_gmac_reset_rx_ring(struct dwc_gmac_s
 	struct dwc_gmac_rx_ring *ring)
 {
 	struct dwc_gmac_dev_dmadesc *desc;
+	struct dwc_gmac_rx_data *data;
 	int i;
 
 	mutex_enter(&ring->r_mtx);
 	for (i = 0; i < AWGE_RX_RING_COUNT; i++) {
 		desc = &sc->sc_rxq.r_desc[i];
+		data = &sc->sc_rxq.r_data[i];
 		sc->sc_descm->rx_init_flags(desc);
-		sc->sc_descm->rx_set_len(desc, AWGE_MAX_PACKET);
+		sc->sc_descm->rx_set_len(desc, data->rd_m->m_len);
 		sc->sc_descm->rx_set_owned_by_dev(desc);
 	}
 
@@ -1264,6 +1283,10 @@ dwc_gmac_rx_intr(struct dwc_gmac_softc *
 			ifp->if_ierrors++;
 			goto skip;
 		}
+		mnew->m_len = mnew->m_pkthdr.len = mnew->m_ext.ext_size;
+		if (mnew->m_len > AWGE_MAX_PACKET) {
+			mnew->m_len = mnew->m_pkthdr.len = AWGE_MAX_PACKET;
+		}
 
 		/* unload old DMA map */
 		bus_dmamap_sync(sc->sc_dmat, data->rd_map, 0,
@@ -1271,15 +1294,13 @@ dwc_gmac_rx_intr(struct dwc_gmac_softc *
 		bus_dmamap_unload(sc->sc_dmat, data->rd_map);
 
 		/* and reload with new mbuf */
-		error = bus_dmamap_load(sc->sc_dmat, data->rd_map,
-		    mtod(mnew, void*), MCLBYTES, NULL,
-		    BUS_DMA_READ | BUS_DMA_NOWAIT);
+		error = bus_dmamap_load_mbuf(sc->sc_dmat, data->rd_map,
+		    mnew, BUS_DMA_READ | BUS_DMA_NOWAIT);
 		if (error != 0) {
 			m_freem(mnew);
 			/* try to reload old mbuf */
-			error = bus_dmamap_load(sc->sc_dmat, data->rd_map,
-			    mtod(data->rd_m, void*), MCLBYTES, NULL,
-			    BUS_DMA_READ | BUS_DMA_NOWAIT);
+			error = bus_dmamap_load_mbuf(sc->sc_dmat, data->rd_map,
+			    data->rd_m, BUS_DMA_READ | BUS_DMA_NOWAIT);
 			if (error != 0) {
 				panic("%s: could not load old rx mbuf",
 				    device_xname(sc->sc_dev));
@@ -1308,7 +1329,7 @@ skip:
 		    data->rd_map->dm_mapsize, BUS_DMASYNC_PREREAD);
 
 		sc->sc_descm->rx_init_flags(desc);
-		sc->sc_descm->rx_set_len(desc, AWGE_MAX_PACKET);
+		sc->sc_descm->rx_set_len(desc, data->rd_m->m_len);
 		sc->sc_descm->rx_set_owned_by_dev(desc);
 
 		bus_dmamap_sync(sc->sc_dmat, sc->sc_dma_ring_map,

Index: src/sys/dev/ic/dwc_gmac_reg.h
diff -u src/sys/dev/ic/dwc_gmac_reg.h:1.19 src/sys/dev/ic/dwc_gmac_reg.h:1.19.4.1
--- src/sys/dev/ic/dwc_gmac_reg.h:1.19	Mon Oct  8 17:09:31 2018
+++ src/sys/dev/ic/dwc_gmac_reg.h	Tue Aug 11 17:14:21 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: dwc_gmac_reg.h,v 1.19 2018/10/08 17:09:31 martin Exp $ */
+/* $NetBSD: dwc_gmac_reg.h,v 1.19.4.1 2020/08/11 17:14:21 martin Exp $ */
 
 /*-
  * Copyright (c) 2013, 2014 The NetBSD Foundation, Inc.
@@ -79,6 +79,46 @@
 #define	AWIN_GMAC_MAC_FLOWCTRL_TFE	__BIT(1)
 #define	AWIN_GMAC_MAC_FLOWCTRL_BUSY	__BIT(0)
 
+#define	GMAC_MMC_CTRL			0x0100	/* MMC control */
+#define	GMAC_MMC_RX_INTR		0x0104	/* MMC RX interrupt */
+#define	GMAC_MMC_TX_INTR		0x0108	/* MMC TX interrupt */
+#define	GMAC_MMC_RX_INT_MSK		0x010c	/* MMC RX interrupt mask */
+#define	GMAC_MMC_TX_INT_MSK		0x0110	/* MMC TX interrupt mask */
+#define	GMAC_MMC_TXOCTETCNT_GB		0x0114	/* TX octet good+bad */
+#define	GMAC_MMC_TXFRMCNT_GB		0x0118	/* TX frame good+bad */
+#define	GMAC_MMC_TXUNDFLWERR		0x0148	/* TX underflow */
+#define	GMAC_MMC_TXCARERR		0x0160	/* TX carrier error */
+#define	GMAC_MMC_TXOCTETCNT_G		0x0164	/* TX octet good */
+#define	GMAC_MMC_TXFRMCNT_G		0x0168	/* TX frame good */
+#define	GMAC_MMC_RXFRMCNT_GB		0x0180	/* RX frame good+bad */
+#define	GMAC_MMC_RXOCTETCNT_GB		0x0184	/* RX octet good+bad */
+#define	GMAC_MMC_RXOCTETCNT_G		0x0188	/* RX octet good */
+#define	GMAC_MMC_RXMCFRMCNT_G		0x0190	/* RX mcast frame good */
+#define	GMAC_MMC_RXCRCERR		0x0194	/* RX CRC error */
+#define	GMAC_MMC_RXLENERR		0x01c8	/* RX length error */
+#define	GMAC_MMC_RXFIFOOVRFLW		0x01d4	/* RX FIFO overflow */
+#define	GMAC_MMC_IPC_INT_MSK		0x0200	/* RX csum offload intr mask */
+#define	GMAC_MMC_IPC_INTR		0x0208	/* RX csum offload interrupt */
+#define	GMAC_MMC_RXIPV4GFRM		0x0210	/* RX IPv4 good frame */
+#define	GMAC_MMC_RXIPV4HDERRFRM		0x0214	/* RX IPv4 header error */
+#define	GMAC_MMC_RXIPV6GFRM		0x0224	/* RX IPv6 good frame */
+#define	GMAC_MMC_RXIPV6HDERRFRM		0x0228	/* RX IPv6 header error */
+#define	GMAC_MMC_RXUDPERRFRM		0x0234	/* RX UDP csum error frame */
+#define	GMAC_MMC_RXTCPERRFRM		0x023c	/* RX TCP csum error frame */
+#define	GMAC_MMC_RXICMPERRFRM		0x0244	/* RX ICMP csum error frame */
+#define	GMAC_MMC_RXIPV4HDERROCT		0x0254	/* RX IPv4 header error octets */
+#define	GMAC_MMC_RXIPV6HDERROCT		0x0268	/* RX IPv6 header error octets */
+#define	GMAC_MMC_RXUDPERROCT		0x0274	/* RX UDP error octets */
+#define	GMAC_MMC_RXTCPERROCT		0x027c	/* RX TCP error octets */
+#define	GMAC_MMC_RXICMPERROCT		0x0280	/* RX ICMP error octets */
+
+#define	GMAC_MMC_CTRL_FHP		__BIT(5) /* Full-Half preset */
+#define	GMAC_MMC_CTRL_CP		__BIT(4) /* Counters preset */
+#define	GMAC_MMC_CTRL_MCF		__BIT(3) /* MMC counter freeze */
+#define	GMAC_MMC_CTRL_ROR		__BIT(2) /* reset on read */
+#define	GMAC_MMC_CTRL_CSR		__BIT(1) /* Counter stop rollover */
+#define	GMAC_MMC_CTRL_CR		__BIT(0) /* Counters reset */
+
 #define	AWIN_GMAC_DMA_BUSMODE		0x1000
 #define	AWIN_GMAC_DMA_TXPOLL		0x1004
 #define	AWIN_GMAC_DMA_RXPOLL		0x1008
@@ -128,7 +168,12 @@
 						        burst len */
 #define	GMAC_BUSMODE_RESET		__BIT(0)
 
-#define	AWIN_GMAC_MII_IRQ		__BIT(0)
+#define	AWIN_GMAC_MRCOIS		__BIT(7) /* MMC RX csum offload intr */
+#define	AWIN_GMAC_MTIS			__BIT(6) /* MMC TX interrupt */
+#define	AWIN_GMAC_MRIS			__BIT(3) /* MMC RX interrupt */
+#define	AWIN_GMAC_MIS			__BIT(4) /* MMC interrupt */
+#define	AWIN_GMAC_PIS			__BIT(3) /* PMT interrupt */
+#define	AWIN_GMAC_MII_IRQ		__BIT(0) /* RGMII interrupt */
 
 
 #define	GMAC_DMA_OP_DISABLECSDROP	__BIT(26) /* disable dropping of
@@ -146,6 +191,7 @@
 #define	GMAC_DMA_OP_RTC			__BITS(4,3) /* RX thres control */
 #define	GMAC_DMA_OP_RXSTART		__BIT(1)  /* start RX DMA engine */
 
+#define	GMAC_DMA_INT_MMC		__BIT(27) /* MMC interrupt */
 #define	GMAC_DMA_INT_NIE		__BIT(16) /* Normal/Summary */
 #define	GMAC_DMA_INT_AIE		__BIT(15) /* Abnormal/Summary */
 #define	GMAC_DMA_INT_ERE		__BIT(14) /* Early receive */
@@ -165,6 +211,7 @@
 #define	GMAC_DMA_INT_MASK	__BITS(0,16)	  /* all possible intr bits */
 
 #define GMAC_DMA_FEAT_ENHANCED_DESC	__BIT(24)
+#define GMAC_DMA_FEAT_RMON		__BIT(11) /* MMC */
 
 struct dwc_gmac_dev_dmadesc {
 	uint32_t ddesc_status0;		/* Status / TDES0 */

Index: src/sys/kern/uipc_mbuf.c
diff -u src/sys/kern/uipc_mbuf.c:1.232 src/sys/kern/uipc_mbuf.c:1.232.4.1
--- src/sys/kern/uipc_mbuf.c:1.232	Thu Jan 17 02:47:15 2019
+++ src/sys/kern/uipc_mbuf.c	Tue Aug 11 17:14:21 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: uipc_mbuf.c,v 1.232 2019/01/17 02:47:15 knakahara Exp $	*/
+/*	$NetBSD: uipc_mbuf.c,v 1.232.4.1 2020/08/11 17:14:21 martin Exp $	*/
 
 /*
  * Copyright (c) 1999, 2001, 2018 The NetBSD Foundation, Inc.
@@ -62,7 +62,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uipc_mbuf.c,v 1.232 2019/01/17 02:47:15 knakahara Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uipc_mbuf.c,v 1.232.4.1 2020/08/11 17:14:21 martin Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_mbuftrace.h"
@@ -188,8 +188,8 @@ mbinit(void)
 	    NULL, IPL_VM, mb_ctor, NULL, NULL);
 	KASSERT(mb_cache != NULL);
 
-	mcl_cache = pool_cache_init(mclbytes, 0, 0, 0, "mclpl", NULL,
-	    IPL_VM, NULL, NULL, NULL);
+	mcl_cache = pool_cache_init(mclbytes, COHERENCY_UNIT, 0, 0, "mclpl",
+	    NULL, IPL_VM, NULL, NULL, NULL);
 	KASSERT(mcl_cache != NULL);
 
 	pool_cache_set_drain_hook(mb_cache, mb_drain, NULL);

Reply via email to