summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/drivers/net/intel.c31
-rw-r--r--src/drivers/net/intel.h9
2 files changed, 31 insertions, 9 deletions
diff --git a/src/drivers/net/intel.c b/src/drivers/net/intel.c
index dc511b8a..4cb8a423 100644
--- a/src/drivers/net/intel.c
+++ b/src/drivers/net/intel.c
@@ -635,10 +635,23 @@ void intel_empty_rx ( struct intel_nic *intel ) {
static int intel_open ( struct net_device *netdev ) {
struct intel_nic *intel = netdev->priv;
union intel_receive_address mac;
+ uint32_t fextnvm11;
uint32_t tctl;
uint32_t rctl;
int rc;
+ /* Set undocumented bit in FEXTNVM11 to work around an errata
+ * in i219 devices that will otherwise cause a complete
+ * datapath hang at the next device reset.
+ */
+ if ( intel->flags & INTEL_RST_HANG ) {
+ DBGC ( intel, "INTEL %p WARNING: applying reset hang "
+ "workaround\n", intel );
+ fextnvm11 = readl ( intel->regs + INTEL_FEXTNVM11 );
+ fextnvm11 |= INTEL_FEXTNVM11_WTF;
+ writel ( fextnvm11, intel->regs + INTEL_FEXTNVM11 );
+ }
+
/* Create transmit descriptor ring */
if ( ( rc = intel_create_ring ( intel, &intel->tx ) ) != 0 )
goto err_create_tx;
@@ -1123,20 +1136,20 @@ static struct pci_device_id intel_nics[] = {
PCI_ROM ( 0x8086, 0x153b, "i217v", "I217-V", 0 ),
PCI_ROM ( 0x8086, 0x1559, "i218v", "I218-V", 0),
PCI_ROM ( 0x8086, 0x155a, "i218lm", "I218-LM", 0),
- PCI_ROM ( 0x8086, 0x156f, "i219lm", "I219-LM", 0 ),
- PCI_ROM ( 0x8086, 0x1570, "i219v", "I219-V", INTEL_NO_PHY_RST ),
+ PCI_ROM ( 0x8086, 0x156f, "i219lm", "I219-LM", INTEL_I219 ),
+ PCI_ROM ( 0x8086, 0x1570, "i219v", "I219-V", INTEL_I219 ),
PCI_ROM ( 0x8086, 0x157b, "i210-2", "I210", 0 ),
PCI_ROM ( 0x8086, 0x15a0, "i218lm-2", "I218-LM", INTEL_NO_PHY_RST ),
PCI_ROM ( 0x8086, 0x15a1, "i218v-2", "I218-V", 0 ),
PCI_ROM ( 0x8086, 0x15a2, "i218lm-3", "I218-LM", INTEL_NO_PHY_RST ),
PCI_ROM ( 0x8086, 0x15a3, "i218v-3", "I218-V", INTEL_NO_PHY_RST ),
- PCI_ROM ( 0x8086, 0x15b7, "i219lm-2", "I219-LM (2)", INTEL_NO_PHY_RST ),
- PCI_ROM ( 0x8086, 0x15b8, "i219v-2", "I219-V (2)", 0 ),
- PCI_ROM ( 0x8086, 0x15b9, "i219lm-3", "I219-LM (3)", INTEL_NO_PHY_RST ),
- PCI_ROM ( 0x8086, 0x15d6, "i219v-5", "I219-V (5)", INTEL_NO_PHY_RST ),
- PCI_ROM ( 0x8086, 0x15d7, "i219lm-4", "I219-LM (4)", INTEL_NO_PHY_RST ),
- PCI_ROM ( 0x8086, 0x15d8, "i219v-4", "I219-V (4)", INTEL_NO_PHY_RST ),
- PCI_ROM ( 0x8086, 0x15e3, "i219lm-5", "I219-LM (5)", INTEL_NO_PHY_RST ),
+ PCI_ROM ( 0x8086, 0x15b7, "i219lm-2", "I219-LM (2)", INTEL_I219 ),
+ PCI_ROM ( 0x8086, 0x15b8, "i219v-2", "I219-V (2)", INTEL_I219 ),
+ PCI_ROM ( 0x8086, 0x15b9, "i219lm-3", "I219-LM (3)", INTEL_I219 ),
+ PCI_ROM ( 0x8086, 0x15d6, "i219v-5", "I219-V (5)", INTEL_I219 ),
+ PCI_ROM ( 0x8086, 0x15d7, "i219lm-4", "I219-LM (4)", INTEL_I219 ),
+ PCI_ROM ( 0x8086, 0x15d8, "i219v-4", "I219-V (4)", INTEL_I219 ),
+ PCI_ROM ( 0x8086, 0x15e3, "i219lm-5", "I219-LM (5)", INTEL_I219 ),
PCI_ROM ( 0x8086, 0x294c, "82566dc-2", "82566DC-2", 0 ),
PCI_ROM ( 0x8086, 0x2e6e, "cemedia", "CE Media Processor", 0 ),
};
diff --git a/src/drivers/net/intel.h b/src/drivers/net/intel.h
index 14877687..9d740efc 100644
--- a/src/drivers/net/intel.h
+++ b/src/drivers/net/intel.h
@@ -195,6 +195,10 @@ struct intel_descriptor {
#define INTEL_RAH0 0x05404UL
#define INTEL_RAH0_AV 0x80000000UL /**< Address valid */
+/** Future Extended NVM register 11 */
+#define INTEL_FEXTNVM11 0x05bbcUL
+#define INTEL_FEXTNVM11_WTF 0x00002000UL /**< Don't ask */
+
/** Receive address */
union intel_receive_address {
struct {
@@ -308,8 +312,13 @@ enum intel_flags {
INTEL_NO_PHY_RST = 0x0004,
/** ASDE is broken */
INTEL_NO_ASDE = 0x0008,
+ /** Reset may cause a complete device hang */
+ INTEL_RST_HANG = 0x0010,
};
+/** The i219 has a seriously broken reset mechanism */
+#define INTEL_I219 ( INTEL_NO_PHY_RST | INTEL_RST_HANG )
+
/**
* Dump diagnostic information
*