summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/drivers/net/intel.c25
-rw-r--r--src/drivers/net/intel.h2
2 files changed, 19 insertions, 8 deletions
diff --git a/src/drivers/net/intel.c b/src/drivers/net/intel.c
index 2326bc528..e155b644d 100644
--- a/src/drivers/net/intel.c
+++ b/src/drivers/net/intel.c
@@ -295,14 +295,23 @@ static int intel_reset ( struct intel_nic *intel ) {
writel ( ctrl, intel->regs + INTEL_CTRL );
mdelay ( INTEL_RESET_DELAY_MS );
- /* If link is already up, do not attempt to reset the PHY. On
- * some models (notably ICH), performing a PHY reset seems to
- * drop the link speed to 10Mbps.
+ /* 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.
+ *
+ * Work around this problem by skipping the PHY reset if
+ * either (a) the link is already up, or (b) this particular
+ * NIC is known to be broken.
*/
status = readl ( intel->regs + INTEL_STATUS );
- if ( status & INTEL_STATUS_LU ) {
- DBGC ( intel, "INTEL %p MAC reset (ctrl %08x)\n",
- intel, ctrl );
+ if ( ( intel->flags & INTEL_NO_PHY_RST ) ||
+ ( status & INTEL_STATUS_LU ) ) {
+ DBGC ( intel, "INTEL %p %sMAC reset (ctrl %08x)\n", intel,
+ ( ( intel->flags & INTEL_NO_PHY_RST ) ? "forced " : "" ),
+ ctrl );
return 0;
}
@@ -1029,7 +1038,7 @@ static struct pci_device_id intel_nics[] = {
PCI_ROM ( 0x8086, 0x10f5, "82567lm", "82567LM", 0 ),
PCI_ROM ( 0x8086, 0x10f6, "82574l", "82574L", 0 ),
PCI_ROM ( 0x8086, 0x1501, "82567v-3", "82567V-3", INTEL_PBS_ERRATA ),
- PCI_ROM ( 0x8086, 0x1502, "82579lm", "82579LM", 0 ),
+ PCI_ROM ( 0x8086, 0x1502, "82579lm", "82579LM", INTEL_NO_PHY_RST ),
PCI_ROM ( 0x8086, 0x1503, "82579v", "82579V", 0 ),
PCI_ROM ( 0x8086, 0x150a, "82576ns", "82576NS", 0 ),
PCI_ROM ( 0x8086, 0x150c, "82583v", "82583V", 0 ),
@@ -1057,7 +1066,7 @@ static struct pci_device_id intel_nics[] = {
PCI_ROM ( 0x8086, 0x15a0, "i218lm-2", "I218-LM", 0 ),
PCI_ROM ( 0x8086, 0x15a1, "i218v-2", "I218-V", 0 ),
PCI_ROM ( 0x8086, 0x15a2, "i218lm-3", "I218-LM", 0 ),
- PCI_ROM ( 0x8086, 0x15a3, "i218v-3", "I218-V", 0 ),
+ PCI_ROM ( 0x8086, 0x15a3, "i218v-3", "I218-V", INTEL_NO_PHY_RST ),
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 ce9e3f467..436229ef6 100644
--- a/src/drivers/net/intel.h
+++ b/src/drivers/net/intel.h
@@ -301,6 +301,8 @@ enum intel_flags {
INTEL_PBS_ERRATA = 0x0001,
/** VMware missing interrupt workaround required */
INTEL_VMWARE = 0x0002,
+ /** PHY reset is broken */
+ INTEL_NO_PHY_RST = 0x0004,
};
/**