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
_______________________________________________
[email protected] mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-stable
To unsubscribe, send any mail to "[email protected]"