Module Name: src
Committed By: martin
Date: Tue Jan 28 11:09:27 UTC 2020
Modified Files:
src/sys/dev/pci/ixgbe [netbsd-9]: ixgbe.c ixgbe_82598.c ixgbe_82599.c
ixgbe_phy.c ixgbe_type.h ixgbe_x550.c
Log Message:
Pull up following revision(s) (requested by msaitoh in ticket #664):
sys/dev/pci/ixgbe/ixgbe_82598.c: revision 1.13
sys/dev/pci/ixgbe/ixgbe.c: revision 1.219
sys/dev/pci/ixgbe/ixgbe_phy.c: revision 1.20
sys/dev/pci/ixgbe/ixgbe_x550.c: revision 1.17
sys/dev/pci/ixgbe/ixgbe_82599.c: revision 1.22
sys/dev/pci/ixgbe/ixgbe_type.h: revision 1.44
Add recovery code for unsupported SFP+.
Before this commit:
If an unsupported SFP module is inserted before booting, the driver attach
failed and there was no way to recover form it without rebooting or
detaching/reattaching driver (drvctl -d && drvctl -r pciN).
After this commit:
We can automatically recover any time by replacing it with a supported
module.
To generate a diff of this commit:
cvs rdiff -u -r1.199.2.9 -r1.199.2.10 src/sys/dev/pci/ixgbe/ixgbe.c
cvs rdiff -u -r1.12.8.1 -r1.12.8.2 src/sys/dev/pci/ixgbe/ixgbe_82598.c
cvs rdiff -u -r1.21 -r1.21.4.1 src/sys/dev/pci/ixgbe/ixgbe_82599.c
cvs rdiff -u -r1.18.4.1 -r1.18.4.2 src/sys/dev/pci/ixgbe/ixgbe_phy.c
cvs rdiff -u -r1.41.2.1 -r1.41.2.2 src/sys/dev/pci/ixgbe/ixgbe_type.h
cvs rdiff -u -r1.15.2.1 -r1.15.2.2 src/sys/dev/pci/ixgbe/ixgbe_x550.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/dev/pci/ixgbe/ixgbe.c
diff -u src/sys/dev/pci/ixgbe/ixgbe.c:1.199.2.9 src/sys/dev/pci/ixgbe/ixgbe.c:1.199.2.10
--- src/sys/dev/pci/ixgbe/ixgbe.c:1.199.2.9 Sun Jan 26 11:03:17 2020
+++ src/sys/dev/pci/ixgbe/ixgbe.c Tue Jan 28 11:09:27 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: ixgbe.c,v 1.199.2.9 2020/01/26 11:03:17 martin Exp $ */
+/* $NetBSD: ixgbe.c,v 1.199.2.10 2020/01/28 11:09:27 martin Exp $ */
/******************************************************************************
@@ -776,6 +776,7 @@ ixgbe_attach(device_t parent, device_t d
pcireg_t id, subid;
const ixgbe_vendor_info_t *ent;
struct pci_attach_args *pa = aux;
+ bool unsupported_sfp = false;
const char *str;
char buf[256];
@@ -959,8 +960,8 @@ ixgbe_attach(device_t parent, device_t d
error = IXGBE_SUCCESS;
} else if (error == IXGBE_ERR_SFP_NOT_SUPPORTED) {
aprint_error_dev(dev, "Unsupported SFP+ module detected!\n");
- error = EIO;
- goto err_late;
+ unsupported_sfp = true;
+ error = IXGBE_SUCCESS;
} else if (error) {
aprint_error_dev(dev, "Hardware initialization failed\n");
error = EIO;
@@ -1129,13 +1130,6 @@ ixgbe_attach(device_t parent, device_t d
"please contact your Intel or hardware representative "
"who provided you with this hardware.\n");
break;
- case IXGBE_ERR_SFP_NOT_SUPPORTED:
- aprint_error_dev(dev, "Unsupported SFP+ Module\n");
- error = EIO;
- goto err_late;
- case IXGBE_ERR_SFP_NOT_PRESENT:
- aprint_error_dev(dev, "No SFP+ Module found\n");
- /* falls thru */
default:
break;
}
@@ -1168,16 +1162,22 @@ ixgbe_attach(device_t parent, device_t d
oui, model, rev);
}
- /* Enable the optics for 82599 SFP+ fiber */
- ixgbe_enable_tx_laser(hw);
-
/* Enable EEE power saving */
if (adapter->feat_cap & IXGBE_FEATURE_EEE)
hw->mac.ops.setup_eee(hw,
adapter->feat_en & IXGBE_FEATURE_EEE);
/* Enable power to the phy. */
- ixgbe_set_phy_power(hw, TRUE);
+ if (!unsupported_sfp) {
+ /* Enable the optics for 82599 SFP+ fiber */
+ ixgbe_enable_tx_laser(hw);
+
+ /*
+ * XXX Currently, ixgbe_set_phy_power() supports only copper
+ * PHY, so it's not required to test with !unsupported_sfp.
+ */
+ ixgbe_set_phy_power(hw, TRUE);
+ }
/* Initialize statistics */
ixgbe_update_stats_counters(adapter);
@@ -3896,6 +3896,7 @@ ixgbe_init_locked(struct adapter *adapte
u32 txdctl, mhadd;
u32 rxdctl, rxctrl;
u32 ctrl_ext;
+ bool unsupported_sfp = false;
int i, j, err;
/* XXX check IFF_UP and IFF_RUNNING, power-saving state! */
@@ -3903,6 +3904,7 @@ ixgbe_init_locked(struct adapter *adapte
KASSERT(mutex_owned(&adapter->core_mtx));
INIT_DEBUGOUT("ixgbe_init_locked: begin");
+ hw->need_unsupported_sfp_recovery = false;
hw->adapter_stopped = FALSE;
ixgbe_stop_adapter(hw);
callout_stop(&adapter->timer);
@@ -4076,12 +4078,14 @@ ixgbe_init_locked(struct adapter *adapte
*/
if (hw->phy.type == ixgbe_phy_none) {
err = hw->phy.ops.identify(hw);
- if (err == IXGBE_ERR_SFP_NOT_SUPPORTED) {
- device_printf(dev,
- "Unsupported SFP+ module type was detected.\n");
- return;
- }
- }
+ if (err == IXGBE_ERR_SFP_NOT_SUPPORTED)
+ unsupported_sfp = true;
+ } else if (hw->phy.type == ixgbe_phy_sfp_unsupported)
+ unsupported_sfp = true;
+
+ if (unsupported_sfp)
+ device_printf(dev,
+ "Unsupported SFP+ module type was detected.\n");
/* Set moderation on the Link interrupt */
ixgbe_eitr_write(adapter, adapter->vector, IXGBE_LINK_ITR);
@@ -4092,10 +4096,12 @@ ixgbe_init_locked(struct adapter *adapte
adapter->feat_en & IXGBE_FEATURE_EEE);
/* Enable power to the phy. */
- ixgbe_set_phy_power(hw, TRUE);
+ if (!unsupported_sfp) {
+ ixgbe_set_phy_power(hw, TRUE);
- /* Config/Enable Link */
- ixgbe_config_link(adapter);
+ /* Config/Enable Link */
+ ixgbe_config_link(adapter);
+ }
/* Hardware Packet Buffer & Flow Control setup */
ixgbe_config_delay_values(adapter);
@@ -4631,15 +4637,28 @@ ixgbe_handle_mod(void *context)
goto out;
}
- if (hw->mac.type == ixgbe_mac_82598EB)
- err = hw->phy.ops.reset(hw);
- else
- err = hw->mac.ops.setup_sfp(hw);
-
- if (err == IXGBE_ERR_SFP_NOT_SUPPORTED) {
- device_printf(dev,
- "Setup failure - unsupported SFP+ module type.\n");
- goto out;
+ if (hw->need_unsupported_sfp_recovery) {
+ device_printf(dev, "Recovering from unsupported SFP\n");
+ /*
+ * We could recover the status by calling setup_sfp(),
+ * setup_link() and some others. It's complex and might not
+ * work correctly on some unknown cases. To avoid such type of
+ * problem, call ixgbe_init_locked(). It's simple and safe
+ * approach.
+ */
+ ixgbe_init_locked(adapter);
+ } else {
+ if (hw->mac.type == ixgbe_mac_82598EB)
+ err = hw->phy.ops.reset(hw);
+ else {
+ err = hw->mac.ops.setup_sfp(hw);
+ hw->phy.sfp_setup_needed = FALSE;
+ }
+ if (err == IXGBE_ERR_SFP_NOT_SUPPORTED) {
+ device_printf(dev,
+ "Setup failure - unsupported SFP+ module type.\n");
+ goto out;
+ }
}
softint_schedule(adapter->msf_si);
out:
Index: src/sys/dev/pci/ixgbe/ixgbe_82598.c
diff -u src/sys/dev/pci/ixgbe/ixgbe_82598.c:1.12.8.1 src/sys/dev/pci/ixgbe/ixgbe_82598.c:1.12.8.2
--- src/sys/dev/pci/ixgbe/ixgbe_82598.c:1.12.8.1 Sun Jan 26 11:03:17 2020
+++ src/sys/dev/pci/ixgbe/ixgbe_82598.c Tue Jan 28 11:09:27 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: ixgbe_82598.c,v 1.12.8.1 2020/01/26 11:03:17 martin Exp $ */
+/* $NetBSD: ixgbe_82598.c,v 1.12.8.2 2020/01/28 11:09:27 martin Exp $ */
/******************************************************************************
SPDX-License-Identifier: BSD-3-Clause
@@ -866,9 +866,8 @@ static s32 ixgbe_reset_hw_82598(struct i
/* Init PHY and function pointers, perform SFP setup */
phy_status = hw->phy.ops.init(hw);
- if (phy_status == IXGBE_ERR_SFP_NOT_SUPPORTED)
- goto reset_hw_out;
- if (phy_status == IXGBE_ERR_SFP_NOT_PRESENT)
+ if ((phy_status == IXGBE_ERR_SFP_NOT_SUPPORTED) ||
+ (phy_status == IXGBE_ERR_SFP_NOT_PRESENT))
goto mac_reset_top;
hw->phy.ops.reset(hw);
Index: src/sys/dev/pci/ixgbe/ixgbe_82599.c
diff -u src/sys/dev/pci/ixgbe/ixgbe_82599.c:1.21 src/sys/dev/pci/ixgbe/ixgbe_82599.c:1.21.4.1
--- src/sys/dev/pci/ixgbe/ixgbe_82599.c:1.21 Thu Dec 6 13:25:02 2018
+++ src/sys/dev/pci/ixgbe/ixgbe_82599.c Tue Jan 28 11:09:27 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: ixgbe_82599.c,v 1.21 2018/12/06 13:25:02 msaitoh Exp $ */
+/* $NetBSD: ixgbe_82599.c,v 1.21.4.1 2020/01/28 11:09:27 martin Exp $ */
/******************************************************************************
SPDX-License-Identifier: BSD-3-Clause
@@ -1041,6 +1041,7 @@ s32 ixgbe_reset_hw_82599(struct ixgbe_hw
{
ixgbe_link_speed link_speed;
s32 status;
+ s32 phy_status = IXGBE_SUCCESS;
u32 ctrl = 0;
u32 i, autoc, autoc2;
u32 curr_lms;
@@ -1059,28 +1060,29 @@ s32 ixgbe_reset_hw_82599(struct ixgbe_hw
/* PHY ops must be identified and initialized prior to reset */
/* Identify PHY and related function pointers */
- status = hw->phy.ops.init(hw);
+ phy_status = hw->phy.ops.init(hw);
- if (status == IXGBE_ERR_SFP_NOT_SUPPORTED)
- goto reset_hw_out;
+ if (phy_status == IXGBE_ERR_SFP_NOT_SUPPORTED)
+ goto mac_reset_top;
/* Setup SFP module if there is one present. */
if (hw->phy.sfp_setup_needed) {
- status = hw->mac.ops.setup_sfp(hw);
+ phy_status = hw->mac.ops.setup_sfp(hw);
hw->phy.sfp_setup_needed = FALSE;
}
- if (status == IXGBE_ERR_SFP_NOT_SUPPORTED)
- goto reset_hw_out;
+ if (phy_status == IXGBE_ERR_SFP_NOT_SUPPORTED)
+ goto mac_reset_top;
/* Reset PHY */
if (hw->phy.reset_disable == FALSE && hw->phy.ops.reset != NULL)
hw->phy.ops.reset(hw);
+mac_reset_top:
/* remember AUTOC from before we reset */
curr_lms = IXGBE_READ_REG(hw, IXGBE_AUTOC) & IXGBE_AUTOC_LMS_MASK;
-mac_reset_top:
+mac_reset_retry:
/*
* Issue global reset to the MAC. Needs to be SW reset if link is up.
* If link reset is used when link is up, it might reset the PHY when
@@ -1120,7 +1122,7 @@ mac_reset_top:
*/
if (hw->mac.flags & IXGBE_FLAGS_DOUBLE_RESET_REQUIRED) {
hw->mac.flags &= ~IXGBE_FLAGS_DOUBLE_RESET_REQUIRED;
- goto mac_reset_top;
+ goto mac_reset_retry;
}
/*
@@ -1208,6 +1210,9 @@ mac_reset_top:
&hw->mac.wwpn_prefix);
reset_hw_out:
+ if (phy_status != IXGBE_SUCCESS)
+ status = phy_status;
+
return status;
}
Index: src/sys/dev/pci/ixgbe/ixgbe_phy.c
diff -u src/sys/dev/pci/ixgbe/ixgbe_phy.c:1.18.4.1 src/sys/dev/pci/ixgbe/ixgbe_phy.c:1.18.4.2
--- src/sys/dev/pci/ixgbe/ixgbe_phy.c:1.18.4.1 Sun Jan 26 11:03:17 2020
+++ src/sys/dev/pci/ixgbe/ixgbe_phy.c Tue Jan 28 11:09:27 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: ixgbe_phy.c,v 1.18.4.1 2020/01/26 11:03:17 martin Exp $ */
+/* $NetBSD: ixgbe_phy.c,v 1.18.4.2 2020/01/28 11:09:27 martin Exp $ */
/******************************************************************************
SPDX-License-Identifier: BSD-3-Clause
@@ -1585,6 +1585,8 @@ s32 ixgbe_identify_sfp_module_generic(st
}
out:
+ if (hw->phy.type == ixgbe_phy_sfp_unsupported)
+ hw->need_unsupported_sfp_recovery = true;
return status;
err_read_i2c_eeprom:
@@ -1838,6 +1840,8 @@ s32 ixgbe_identify_qsfp_module_generic(s
}
out:
+ if (hw->phy.type == ixgbe_phy_sfp_unsupported)
+ hw->need_unsupported_sfp_recovery = true;
return status;
err_read_i2c_eeprom:
Index: src/sys/dev/pci/ixgbe/ixgbe_type.h
diff -u src/sys/dev/pci/ixgbe/ixgbe_type.h:1.41.2.1 src/sys/dev/pci/ixgbe/ixgbe_type.h:1.41.2.2
--- src/sys/dev/pci/ixgbe/ixgbe_type.h:1.41.2.1 Thu Sep 26 19:07:22 2019
+++ src/sys/dev/pci/ixgbe/ixgbe_type.h Tue Jan 28 11:09:27 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: ixgbe_type.h,v 1.41.2.1 2019/09/26 19:07:22 martin Exp $ */
+/* $NetBSD: ixgbe_type.h,v 1.41.2.2 2020/01/28 11:09:27 martin Exp $ */
/******************************************************************************
SPDX-License-Identifier: BSD-3-Clause
@@ -4263,6 +4263,7 @@ struct ixgbe_hw {
bool allow_unsupported_sfp;
bool wol_enabled;
bool need_crosstalk_fix;
+ bool need_unsupported_sfp_recovery;
};
#define ixgbe_call_func(hw, func, params, error) \
Index: src/sys/dev/pci/ixgbe/ixgbe_x550.c
diff -u src/sys/dev/pci/ixgbe/ixgbe_x550.c:1.15.2.1 src/sys/dev/pci/ixgbe/ixgbe_x550.c:1.15.2.2
--- src/sys/dev/pci/ixgbe/ixgbe_x550.c:1.15.2.1 Thu Sep 26 19:07:22 2019
+++ src/sys/dev/pci/ixgbe/ixgbe_x550.c Tue Jan 28 11:09:27 2020
@@ -2604,6 +2604,7 @@ s32 ixgbe_reset_hw_X550em(struct ixgbe_h
{
ixgbe_link_speed link_speed;
s32 status;
+ s32 phy_status = IXGBE_SUCCESS;
u32 ctrl = 0;
u32 i;
bool link_up = FALSE;
@@ -2623,16 +2624,16 @@ s32 ixgbe_reset_hw_X550em(struct ixgbe_h
ixgbe_set_mdio_speed(hw);
/* PHY ops must be identified and initialized prior to reset */
- status = hw->phy.ops.init(hw);
+ phy_status = hw->phy.ops.init(hw);
- if (status)
+ if (phy_status)
DEBUGOUT1("Failed to initialize PHY ops, STATUS = %d\n",
status);
- if (status == IXGBE_ERR_SFP_NOT_SUPPORTED ||
- status == IXGBE_ERR_PHY_ADDR_INVALID) {
+ if (phy_status == IXGBE_ERR_SFP_NOT_SUPPORTED ||
+ phy_status == IXGBE_ERR_PHY_ADDR_INVALID) {
DEBUGOUT("Returning from reset HW due to PHY init failure\n");
- return status;
+ goto mac_reset_top;
}
/* start the external PHY */
@@ -2647,12 +2648,12 @@ s32 ixgbe_reset_hw_X550em(struct ixgbe_h
/* Setup SFP module if there is one present. */
if (hw->phy.sfp_setup_needed) {
- status = hw->mac.ops.setup_sfp(hw);
+ phy_status = hw->mac.ops.setup_sfp(hw);
hw->phy.sfp_setup_needed = FALSE;
}
- if (status == IXGBE_ERR_SFP_NOT_SUPPORTED)
- return status;
+ if (phy_status == IXGBE_ERR_SFP_NOT_SUPPORTED)
+ goto mac_reset_top;
/* Reset PHY */
if (!hw->phy.reset_disable && hw->phy.ops.reset) {
@@ -2726,6 +2727,9 @@ mac_reset_top:
if (status != IXGBE_SUCCESS)
DEBUGOUT1("Reset HW failed, STATUS = %d\n", status);
+ if (phy_status != IXGBE_SUCCESS)
+ status = phy_status;
+
return status;
}