I've run in to problems using the msk device where initially it works well 
enough to set DHCP etc. but stops/freezes as soon as any appreciable network 
traffic occurs . There are several threads describing similar symptoms over the 
past two years or more.  I've been following several false leads but have 
finally found a solution (at least it solves my problem).

I'm running a standard FreeBSD 10.1-RELEASE and the NIC is detected as:

mskc0: <Marvell Yukon 88E8057 Gigabit Ethernet> mem 0xfa000000-0xfa003fff irq 
19 at device 0.0 on pci6
msk0: <Marvell Technology Group Ltd. Yukon Ultra 2 Id 0xba Rev 0x00> on mskc0
msk0: Ethernet address: 00:13:77:e9:df:eb
miibus0: <MII bus> on msk0
e1000phy0: <Marvell 88E1149 Gigabit PHY> PHY 0 on miibus0
e1000phy0:  none, 10baseT, 10baseT-FDX, 100baseTX, 100baseTX-FDX, 1000baseT, 
1000baseT-master, 1000baseT-FDX, 1000baseT-FDX-ma
ster, auto, auto-flow

The network worked when using the i386 release, but failed for the amd64 
release (as reported previously) which prompted me to disable 64-bit DMA (the 
patch for this is attached below).  This worked for the first kernel built but 
mysteriously failed when another unrelated part of the kernel was changed (a 
usb driver) and the kernel recompiled.  So identical msk driver code worked in 
one kernel but not the second! This suggested that alignment differences 
between the two kernels were causing the msk driver to fail. Others have 
reported varying behaviour depending on different circumstances.

It transpires that changing just one value in the if_mskreg.h file solved all 
my problems.  Subsequently I have not been able to make it fail under heavy 
network traffic in either 32-bit or 64-bit mode.
I'm working on 10.1-RELEASE source, i.e. if_msk.c revision 262524 and 
if_mskreg.h revision 264442.

Here's the patch to if_mskreg.h
--- if_mskreg.h-orig    2014-11-11 20:02:58.000000000 +0000
+++ if_mskreg.h 2015-04-12 18:47:20.000000000 +0100
@@ -2179,9 +2179,11 @@
  * At first I guessed 8 bytes, the size of a single descriptor, would be
  * required alignment constraints. But, it seems that Yukon II have 4096
  * bytes boundary alignment constraints.
+ * And it seems that the DMA status region for the Yukon Ultra 2 (88E8057)
+ * requires 8192 byte alignment to prevent locking.
  */
 #define MSK_RING_ALIGN 4096
-#define        MSK_STAT_ALIGN  4096
+#define        MSK_STAT_ALIGN  8192


The patches to both files which also implement a MSK_64BIT_DMA_DISABLE flag are 
attached.  Perhaps the developers would consider committing these as it may be 
useful for future debugging.

Gareth.
--- if_mskreg.h-orig	2014-11-11 20:02:58.000000000 +0000
+++ if_mskreg.h	2015-04-12 18:47:20.000000000 +0100
@@ -2179,9 +2179,11 @@
  * At first I guessed 8 bytes, the size of a single descriptor, would be
  * required alignment constraints. But, it seems that Yukon II have 4096
  * bytes boundary alignment constraints.
+ * And it seems that the DMA status region for the Yukon Ultra 2 (88E8057)
+ * requires 8192 byte alignment to prevent locking.
  */
 #define MSK_RING_ALIGN	4096
-#define	MSK_STAT_ALIGN	4096
+#define	MSK_STAT_ALIGN	8192
 
 /* Rx descriptor data structure */
 struct msk_rx_desc {
--- if_msk.c-orig	2014-11-11 20:02:58.000000000 +0000
+++ if_msk.c	2015-04-12 02:15:12.551005000 +0100
@@ -2164,8 +2164,8 @@
 	error = bus_dma_tag_create(
 		    bus_get_dma_tag(sc->msk_dev),	/* parent */
 		    MSK_STAT_ALIGN, 0,		/* alignment, boundary */
-		    BUS_SPACE_MAXADDR,		/* lowaddr */
-		    BUS_SPACE_MAXADDR,		/* highaddr */
+		    BUS_DMA_TAG_LOWADDR,	/* lowaddr */
+		    BUS_DMA_TAG_HIGHADDR,	/* highaddr */
 		    NULL, NULL,			/* filter, filterarg */
 		    stat_sz,			/* maxsize */
 		    1,				/* nsegments */
@@ -2235,8 +2235,8 @@
 	error = bus_dma_tag_create(
 		    bus_get_dma_tag(sc_if->msk_if_dev),	/* parent */
 		    1, 0,			/* alignment, boundary */
-		    BUS_SPACE_MAXADDR,		/* lowaddr */
-		    BUS_SPACE_MAXADDR,		/* highaddr */
+		    BUS_DMA_TAG_LOWADDR,	/* lowaddr */
+		    BUS_DMA_TAG_HIGHADDR,	/* highaddr */
 		    NULL, NULL,			/* filter, filterarg */
 		    BUS_SPACE_MAXSIZE_32BIT,	/* maxsize */
 		    0,				/* nsegments */
@@ -2252,8 +2252,8 @@
 	/* Create tag for Tx ring. */
 	error = bus_dma_tag_create(sc_if->msk_cdata.msk_parent_tag,/* parent */
 		    MSK_RING_ALIGN, 0,		/* alignment, boundary */
-		    BUS_SPACE_MAXADDR,		/* lowaddr */
-		    BUS_SPACE_MAXADDR,		/* highaddr */
+		    BUS_DMA_TAG_LOWADDR,	/* lowaddr */
+		    BUS_DMA_TAG_HIGHADDR,	/* highaddr */
 		    NULL, NULL,			/* filter, filterarg */
 		    MSK_TX_RING_SZ,		/* maxsize */
 		    1,				/* nsegments */
@@ -2270,8 +2270,8 @@
 	/* Create tag for Rx ring. */
 	error = bus_dma_tag_create(sc_if->msk_cdata.msk_parent_tag,/* parent */
 		    MSK_RING_ALIGN, 0,		/* alignment, boundary */
-		    BUS_SPACE_MAXADDR,		/* lowaddr */
-		    BUS_SPACE_MAXADDR,		/* highaddr */
+		    BUS_DMA_TAG_LOWADDR,	/* lowaddr */
+		    BUS_DMA_TAG_HIGHADDR,	/* highaddr */
 		    NULL, NULL,			/* filter, filterarg */
 		    MSK_RX_RING_SZ,		/* maxsize */
 		    1,				/* nsegments */
@@ -2288,8 +2288,8 @@
 	/* Create tag for Tx buffers. */
 	error = bus_dma_tag_create(sc_if->msk_cdata.msk_parent_tag,/* parent */
 		    1, 0,			/* alignment, boundary */
-		    BUS_SPACE_MAXADDR,		/* lowaddr */
-		    BUS_SPACE_MAXADDR,		/* highaddr */
+		    BUS_DMA_TAG_LOWADDR,	/* lowaddr */
+		    BUS_DMA_TAG_HIGHADDR,	/* highaddr */
 		    NULL, NULL,			/* filter, filterarg */
 		    MSK_TSO_MAXSIZE,		/* maxsize */
 		    MSK_MAXTXSEGS,		/* nsegments */
@@ -2313,8 +2313,8 @@
 	/* Create tag for Rx buffers. */
 	error = bus_dma_tag_create(sc_if->msk_cdata.msk_parent_tag,/* parent */
 		    rxalign, 0,			/* alignment, boundary */
-		    BUS_SPACE_MAXADDR,		/* lowaddr */
-		    BUS_SPACE_MAXADDR,		/* highaddr */
+		    BUS_DMA_TAG_LOWADDR,	/* lowaddr */
+		    BUS_DMA_TAG_HIGHADDR,	/* highaddr */
 		    NULL, NULL,			/* filter, filterarg */
 		    MCLBYTES,			/* maxsize */
 		    1,				/* nsegments */
@@ -2424,8 +2424,8 @@
 	/* Create tag for jumbo Rx ring. */
 	error = bus_dma_tag_create(sc_if->msk_cdata.msk_parent_tag,/* parent */
 		    MSK_RING_ALIGN, 0,		/* alignment, boundary */
-		    BUS_SPACE_MAXADDR,		/* lowaddr */
-		    BUS_SPACE_MAXADDR,		/* highaddr */
+		    BUS_DMA_TAG_LOWADDR,	/* lowaddr */
+		    BUS_DMA_TAG_HIGHADDR,	/* highaddr */
 		    NULL, NULL,			/* filter, filterarg */
 		    MSK_JUMBO_RX_RING_SZ,	/* maxsize */
 		    1,				/* nsegments */
@@ -2449,8 +2449,8 @@
 	/* Create tag for jumbo Rx buffers. */
 	error = bus_dma_tag_create(sc_if->msk_cdata.msk_parent_tag,/* parent */
 		    rxalign, 0,			/* alignment, boundary */
-		    BUS_SPACE_MAXADDR,		/* lowaddr */
-		    BUS_SPACE_MAXADDR,		/* highaddr */
+		    BUS_DMA_TAG_LOWADDR,	/* lowaddr */
+		    BUS_DMA_TAG_HIGHADDR,	/* highaddr */
 		    NULL, NULL,			/* filter, filterarg */
 		    MJUM9BYTES,			/* maxsize */
 		    1,				/* nsegments */
--- if_mskreg.h-orig	2014-11-11 20:02:58.000000000 +0000
+++ if_mskreg.h	2015-04-12 13:17:28.000000000 +0100
@@ -2179,9 +2179,11 @@
  * At first I guessed 8 bytes, the size of a single descriptor, would be
  * required alignment constraints. But, it seems that Yukon II have 4096
  * bytes boundary alignment constraints.
+ * And it seems that the DMA status region for the Yukon Ultra 2 (88E8057)
+ * requires 8192 byte alignment to prevent locking.
  */
 #define MSK_RING_ALIGN	4096
-#define	MSK_STAT_ALIGN	4096
+#define	MSK_STAT_ALIGN	8192
 
 /* Rx descriptor data structure */
 struct msk_rx_desc {
@@ -2327,15 +2329,29 @@
  * allocates 50% more total TX buffers on platforms that support 64bit
  * DMA.
  */
+#undef MSK_64BIT_DMA_DISABLE		/* Define to use 32bit DMA on 64bit hardware */
 #if (BUS_SPACE_MAXADDR > 0xFFFFFFFF)
+#ifndef MSK_64BIT_DMA_DISABLE
 #define	MSK_64BIT_DMA
 #define MSK_TX_RING_CNT		384
 #define MSK_RX_RING_CNT		512
+#define BUS_DMA_TAG_LOWADDR BUS_SPACE_MAXADDR
+#define BUS_DMA_TAG_HIGHADDR BUS_SPACE_MAXADDR
 #else
 #undef	MSK_64BIT_DMA
 #define MSK_TX_RING_CNT		256
 #define MSK_RX_RING_CNT		256
+#define BUS_DMA_TAG_LOWADDR BUS_SPACE_MAXADDR_32BIT
+#define BUS_DMA_TAG_HIGHADDR BUS_SPACE_MAXADDR
 #endif
+#else
+#undef	MSK_64BIT_DMA
+#define MSK_TX_RING_CNT		256
+#define MSK_RX_RING_CNT		256
+#define BUS_DMA_TAG_LOWADDR BUS_SPACE_MAXADDR
+#define BUS_DMA_TAG_HIGHADDR BUS_SPACE_MAXADDR
+#endif
+
 #define	MSK_RX_BUF_ALIGN	8
 #define MSK_JUMBO_RX_RING_CNT	MSK_RX_RING_CNT
 #define MSK_MAXTXSEGS		35
_______________________________________________
freebsd-stable@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-stable
To unsubscribe, send any mail to "freebsd-stable-unsubscr...@freebsd.org"

Reply via email to