Browse Source

[intel] Forcibly skip PHY reset on some models

On some models (notably ICH), the PHY reset mechanism appears to be
broken.  In particular, the PHY_CTRL register will be correctly loaded
from NVM but the values will not be propagated to the "OEM bits" PHY
register.  This typically has the effect of dropping the link speed to
10Mbps.

Since the original version of this driver in commit 945e428 ("[intel]
Replace driver for Intel Gigabit NICs"), we have always worked around
this problem by skipping the PHY reset if the link is already up.
Enhance this workaround by explicitly checking for known-broken PCI
IDs.

Reported-by: Robin Smidsrød <robin@smidsrod.no>
Tested-by: Robin Smidsrød <robin@smidsrod.no>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 8 years ago
parent
commit
fff9281b84
2 changed files with 19 additions and 8 deletions
  1. 17
    8
      src/drivers/net/intel.c
  2. 2
    0
      src/drivers/net/intel.h

+ 17
- 8
src/drivers/net/intel.c View File

295
 	writel ( ctrl, intel->regs + INTEL_CTRL );
295
 	writel ( ctrl, intel->regs + INTEL_CTRL );
296
 	mdelay ( INTEL_RESET_DELAY_MS );
296
 	mdelay ( INTEL_RESET_DELAY_MS );
297
 
297
 
298
-	/* If link is already up, do not attempt to reset the PHY.  On
299
-	 * some models (notably ICH), performing a PHY reset seems to
300
-	 * drop the link speed to 10Mbps.
298
+	/* On some models (notably ICH), the PHY reset mechanism
299
+	 * appears to be broken.  In particular, the PHY_CTRL register
300
+	 * will be correctly loaded from NVM but the values will not
301
+	 * be propagated to the "OEM bits" PHY register.  This
302
+	 * typically has the effect of dropping the link speed to
303
+	 * 10Mbps.
304
+	 *
305
+	 * Work around this problem by skipping the PHY reset if
306
+	 * either (a) the link is already up, or (b) this particular
307
+	 * NIC is known to be broken.
301
 	 */
308
 	 */
302
 	status = readl ( intel->regs + INTEL_STATUS );
309
 	status = readl ( intel->regs + INTEL_STATUS );
303
-	if ( status & INTEL_STATUS_LU ) {
304
-		DBGC ( intel, "INTEL %p MAC reset (ctrl %08x)\n",
305
-		       intel, ctrl );
310
+	if ( ( intel->flags & INTEL_NO_PHY_RST ) ||
311
+	     ( status & INTEL_STATUS_LU ) ) {
312
+		DBGC ( intel, "INTEL %p %sMAC reset (ctrl %08x)\n", intel,
313
+		       ( ( intel->flags & INTEL_NO_PHY_RST ) ? "forced " : "" ),
314
+		       ctrl );
306
 		return 0;
315
 		return 0;
307
 	}
316
 	}
308
 
317
 
1029
 	PCI_ROM ( 0x8086, 0x10f5, "82567lm", "82567LM", 0 ),
1038
 	PCI_ROM ( 0x8086, 0x10f5, "82567lm", "82567LM", 0 ),
1030
 	PCI_ROM ( 0x8086, 0x10f6, "82574l", "82574L", 0 ),
1039
 	PCI_ROM ( 0x8086, 0x10f6, "82574l", "82574L", 0 ),
1031
 	PCI_ROM ( 0x8086, 0x1501, "82567v-3", "82567V-3", INTEL_PBS_ERRATA ),
1040
 	PCI_ROM ( 0x8086, 0x1501, "82567v-3", "82567V-3", INTEL_PBS_ERRATA ),
1032
-	PCI_ROM ( 0x8086, 0x1502, "82579lm", "82579LM", 0 ),
1041
+	PCI_ROM ( 0x8086, 0x1502, "82579lm", "82579LM", INTEL_NO_PHY_RST ),
1033
 	PCI_ROM ( 0x8086, 0x1503, "82579v", "82579V", 0 ),
1042
 	PCI_ROM ( 0x8086, 0x1503, "82579v", "82579V", 0 ),
1034
 	PCI_ROM ( 0x8086, 0x150a, "82576ns", "82576NS", 0 ),
1043
 	PCI_ROM ( 0x8086, 0x150a, "82576ns", "82576NS", 0 ),
1035
 	PCI_ROM ( 0x8086, 0x150c, "82583v", "82583V", 0 ),
1044
 	PCI_ROM ( 0x8086, 0x150c, "82583v", "82583V", 0 ),
1057
 	PCI_ROM ( 0x8086, 0x15a0, "i218lm-2", "I218-LM", 0 ),
1066
 	PCI_ROM ( 0x8086, 0x15a0, "i218lm-2", "I218-LM", 0 ),
1058
 	PCI_ROM ( 0x8086, 0x15a1, "i218v-2", "I218-V", 0 ),
1067
 	PCI_ROM ( 0x8086, 0x15a1, "i218v-2", "I218-V", 0 ),
1059
 	PCI_ROM ( 0x8086, 0x15a2, "i218lm-3", "I218-LM", 0 ),
1068
 	PCI_ROM ( 0x8086, 0x15a2, "i218lm-3", "I218-LM", 0 ),
1060
-	PCI_ROM ( 0x8086, 0x15a3, "i218v-3", "I218-V", 0 ),
1069
+	PCI_ROM ( 0x8086, 0x15a3, "i218v-3", "I218-V", INTEL_NO_PHY_RST ),
1061
 	PCI_ROM ( 0x8086, 0x294c, "82566dc-2", "82566DC-2", 0 ),
1070
 	PCI_ROM ( 0x8086, 0x294c, "82566dc-2", "82566DC-2", 0 ),
1062
 	PCI_ROM ( 0x8086, 0x2e6e, "cemedia", "CE Media Processor", 0 ),
1071
 	PCI_ROM ( 0x8086, 0x2e6e, "cemedia", "CE Media Processor", 0 ),
1063
 };
1072
 };

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

301
 	INTEL_PBS_ERRATA = 0x0001,
301
 	INTEL_PBS_ERRATA = 0x0001,
302
 	/** VMware missing interrupt workaround required */
302
 	/** VMware missing interrupt workaround required */
303
 	INTEL_VMWARE = 0x0002,
303
 	INTEL_VMWARE = 0x0002,
304
+	/** PHY reset is broken */
305
+	INTEL_NO_PHY_RST = 0x0004,
304
 };
306
 };
305
 
307
 
306
 /**
308
 /**

Loading…
Cancel
Save