aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/ffec
diff options
context:
space:
mode:
authorIan Lepore <ian@FreeBSD.org>2017-10-28 17:30:49 +0000
committerIan Lepore <ian@FreeBSD.org>2017-10-28 17:30:49 +0000
commit21c4bbedbc71fc9843679168f034fce09625762d (patch)
tree4bdfb24f75662c12c372b3e74cf628b25d3ced6e /sys/dev/ffec
parent0a3df28448404f01d0324811651b94ebd81ddd4a (diff)
Notes
Diffstat (limited to 'sys/dev/ffec')
-rw-r--r--sys/dev/ffec/if_ffec.c17
1 files changed, 15 insertions, 2 deletions
diff --git a/sys/dev/ffec/if_ffec.c b/sys/dev/ffec/if_ffec.c
index 0ba02c8cdc4f..a25394bd961e 100644
--- a/sys/dev/ffec/if_ffec.c
+++ b/sys/dev/ffec/if_ffec.c
@@ -1639,8 +1639,21 @@ ffec_attach(device_t dev)
/* Try to get the MAC address from the hardware before resetting it. */
ffec_get_hwaddr(sc, eaddr);
- /* Reset the hardware. Disables all interrupts. */
- WR4(sc, FEC_ECR_REG, FEC_ECR_RESET);
+ /*
+ * Reset the hardware. Disables all interrupts.
+ *
+ * When the FEC is connected to the AXI bus (indicated by AVB flag), a
+ * MAC reset while a bus transaction is pending can hang the bus.
+ * Instead of resetting, turn off the ENABLE bit, which allows the
+ * hardware to complete any in-progress transfers (appending a bad CRC
+ * to any partial packet) and release the AXI bus. This could probably
+ * be done unconditionally for all hardware variants, but that hasn't
+ * been tested.
+ */
+ if (sc->fectype & FECFLAG_AVB)
+ WR4(sc, FEC_ECR_REG, 0);
+ else
+ WR4(sc, FEC_ECR_REG, FEC_ECR_RESET);
/* Setup interrupt handler. */
error = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_NET | INTR_MPSAFE,