Browse Source

[intel] Work around broken reset mechanism in i219 devices

The i219 appears to have a seriously broken reset mechanism.  After
any transmit or receive activity, resetting the card will break both
the transmit and receive datapaths until the next PCI bus reset.

The Linux and BSD drivers include a convoluted workaround authored by
Intel which involves setting a bit in the undocumented FEXTNVM11
register, then transmitting a dummy 512-byte packet containing garbage
data, then reconfiguring the receive descriptor prefetch thresholds
and temporarily reenabling the receive datapath.  The comments in the
Intel fix do not even remotely match what the code actually does, and
the code accidentally leaves the transmitter enabled after use.

Experimentation suggests that an equivalent fix is to simply set the
undocumented bit in FEXTNVM11 before enabling the transmit or receive
descriptor rings.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 6 years ago
parent
commit
546dd51de8
2 changed files with 31 additions and 9 deletions
  1. 22
    9
      src/drivers/net/intel.c
  2. 9
    0
      src/drivers/net/intel.h

+ 22
- 9
src/drivers/net/intel.c View File

635
 static int intel_open ( struct net_device *netdev ) {
635
 static int intel_open ( struct net_device *netdev ) {
636
 	struct intel_nic *intel = netdev->priv;
636
 	struct intel_nic *intel = netdev->priv;
637
 	union intel_receive_address mac;
637
 	union intel_receive_address mac;
638
+	uint32_t fextnvm11;
638
 	uint32_t tctl;
639
 	uint32_t tctl;
639
 	uint32_t rctl;
640
 	uint32_t rctl;
640
 	int rc;
641
 	int rc;
641
 
642
 
643
+	/* Set undocumented bit in FEXTNVM11 to work around an errata
644
+	 * in i219 devices that will otherwise cause a complete
645
+	 * datapath hang at the next device reset.
646
+	 */
647
+	if ( intel->flags & INTEL_RST_HANG ) {
648
+		DBGC ( intel, "INTEL %p WARNING: applying reset hang "
649
+		       "workaround\n", intel );
650
+		fextnvm11 = readl ( intel->regs + INTEL_FEXTNVM11 );
651
+		fextnvm11 |= INTEL_FEXTNVM11_WTF;
652
+		writel ( fextnvm11, intel->regs + INTEL_FEXTNVM11 );
653
+	}
654
+
642
 	/* Create transmit descriptor ring */
655
 	/* Create transmit descriptor ring */
643
 	if ( ( rc = intel_create_ring ( intel, &intel->tx ) ) != 0 )
656
 	if ( ( rc = intel_create_ring ( intel, &intel->tx ) ) != 0 )
644
 		goto err_create_tx;
657
 		goto err_create_tx;
1123
 	PCI_ROM ( 0x8086, 0x153b, "i217v", "I217-V", 0 ),
1136
 	PCI_ROM ( 0x8086, 0x153b, "i217v", "I217-V", 0 ),
1124
 	PCI_ROM ( 0x8086, 0x1559, "i218v", "I218-V", 0),
1137
 	PCI_ROM ( 0x8086, 0x1559, "i218v", "I218-V", 0),
1125
 	PCI_ROM ( 0x8086, 0x155a, "i218lm", "I218-LM", 0),
1138
 	PCI_ROM ( 0x8086, 0x155a, "i218lm", "I218-LM", 0),
1126
-	PCI_ROM ( 0x8086, 0x156f, "i219lm", "I219-LM", 0 ),
1127
-	PCI_ROM ( 0x8086, 0x1570, "i219v", "I219-V", INTEL_NO_PHY_RST ),
1139
+	PCI_ROM ( 0x8086, 0x156f, "i219lm", "I219-LM", INTEL_I219 ),
1140
+	PCI_ROM ( 0x8086, 0x1570, "i219v", "I219-V", INTEL_I219 ),
1128
 	PCI_ROM ( 0x8086, 0x157b, "i210-2", "I210", 0 ),
1141
 	PCI_ROM ( 0x8086, 0x157b, "i210-2", "I210", 0 ),
1129
 	PCI_ROM ( 0x8086, 0x15a0, "i218lm-2", "I218-LM", INTEL_NO_PHY_RST ),
1142
 	PCI_ROM ( 0x8086, 0x15a0, "i218lm-2", "I218-LM", INTEL_NO_PHY_RST ),
1130
 	PCI_ROM ( 0x8086, 0x15a1, "i218v-2", "I218-V", 0 ),
1143
 	PCI_ROM ( 0x8086, 0x15a1, "i218v-2", "I218-V", 0 ),
1131
 	PCI_ROM ( 0x8086, 0x15a2, "i218lm-3", "I218-LM", INTEL_NO_PHY_RST ),
1144
 	PCI_ROM ( 0x8086, 0x15a2, "i218lm-3", "I218-LM", INTEL_NO_PHY_RST ),
1132
 	PCI_ROM ( 0x8086, 0x15a3, "i218v-3", "I218-V", INTEL_NO_PHY_RST ),
1145
 	PCI_ROM ( 0x8086, 0x15a3, "i218v-3", "I218-V", INTEL_NO_PHY_RST ),
1133
-	PCI_ROM ( 0x8086, 0x15b7, "i219lm-2", "I219-LM (2)", INTEL_NO_PHY_RST ),
1134
-	PCI_ROM ( 0x8086, 0x15b8, "i219v-2", "I219-V (2)", 0 ),
1135
-	PCI_ROM ( 0x8086, 0x15b9, "i219lm-3", "I219-LM (3)", INTEL_NO_PHY_RST ),
1136
-	PCI_ROM ( 0x8086, 0x15d6, "i219v-5", "I219-V (5)", INTEL_NO_PHY_RST ),
1137
-	PCI_ROM ( 0x8086, 0x15d7, "i219lm-4", "I219-LM (4)", INTEL_NO_PHY_RST ),
1138
-	PCI_ROM ( 0x8086, 0x15d8, "i219v-4", "I219-V (4)", INTEL_NO_PHY_RST ),
1139
-	PCI_ROM ( 0x8086, 0x15e3, "i219lm-5", "I219-LM (5)", INTEL_NO_PHY_RST ),
1146
+	PCI_ROM ( 0x8086, 0x15b7, "i219lm-2", "I219-LM (2)", INTEL_I219 ),
1147
+	PCI_ROM ( 0x8086, 0x15b8, "i219v-2", "I219-V (2)", INTEL_I219 ),
1148
+	PCI_ROM ( 0x8086, 0x15b9, "i219lm-3", "I219-LM (3)", INTEL_I219 ),
1149
+	PCI_ROM ( 0x8086, 0x15d6, "i219v-5", "I219-V (5)", INTEL_I219 ),
1150
+	PCI_ROM ( 0x8086, 0x15d7, "i219lm-4", "I219-LM (4)", INTEL_I219 ),
1151
+	PCI_ROM ( 0x8086, 0x15d8, "i219v-4", "I219-V (4)", INTEL_I219 ),
1152
+	PCI_ROM ( 0x8086, 0x15e3, "i219lm-5", "I219-LM (5)", INTEL_I219 ),
1140
 	PCI_ROM ( 0x8086, 0x294c, "82566dc-2", "82566DC-2", 0 ),
1153
 	PCI_ROM ( 0x8086, 0x294c, "82566dc-2", "82566DC-2", 0 ),
1141
 	PCI_ROM ( 0x8086, 0x2e6e, "cemedia", "CE Media Processor", 0 ),
1154
 	PCI_ROM ( 0x8086, 0x2e6e, "cemedia", "CE Media Processor", 0 ),
1142
 };
1155
 };

+ 9
- 0
src/drivers/net/intel.h View File

195
 #define INTEL_RAH0 0x05404UL
195
 #define INTEL_RAH0 0x05404UL
196
 #define INTEL_RAH0_AV		0x80000000UL	/**< Address valid */
196
 #define INTEL_RAH0_AV		0x80000000UL	/**< Address valid */
197
 
197
 
198
+/** Future Extended NVM register 11 */
199
+#define INTEL_FEXTNVM11 0x05bbcUL
200
+#define INTEL_FEXTNVM11_WTF	0x00002000UL	/**< Don't ask */
201
+
198
 /** Receive address */
202
 /** Receive address */
199
 union intel_receive_address {
203
 union intel_receive_address {
200
 	struct {
204
 	struct {
308
 	INTEL_NO_PHY_RST = 0x0004,
312
 	INTEL_NO_PHY_RST = 0x0004,
309
 	/** ASDE is broken */
313
 	/** ASDE is broken */
310
 	INTEL_NO_ASDE = 0x0008,
314
 	INTEL_NO_ASDE = 0x0008,
315
+	/** Reset may cause a complete device hang */
316
+	INTEL_RST_HANG = 0x0010,
311
 };
317
 };
312
 
318
 
319
+/** The i219 has a seriously broken reset mechanism */
320
+#define INTEL_I219 ( INTEL_NO_PHY_RST | INTEL_RST_HANG )
321
+
313
 /**
322
 /**
314
  * Dump diagnostic information
323
  * Dump diagnostic information
315
  *
324
  *

Loading…
Cancel
Save