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; }