Module Name: src Committed By: martin Date: Sun Sep 1 11:12:45 UTC 2019
Modified Files: src/sys/dev/pci/ixgbe [netbsd-9]: ixgbe.c ixv.c Log Message: Pull up following revision(s) (requested by msaitoh in ticket #134): sys/dev/pci/ixgbe/ixgbe.c: revision 1.202 sys/dev/pci/ixgbe/ixgbe.c: revision 1.203 sys/dev/pci/ixgbe/ixgbe.c: revision 1.204 sys/dev/pci/ixgbe/ixv.c: revision 1.128 Simplify ix{gbe,v}_[un]register_vlan() API suggested by knakahara. The API was the same as FreeBSD's pre-iflib's. They use iflib now and it's not required for us to keep the old API. X550EM supports QSFP, so check ixgbe_media_type_fiber_qsfp too. An interrupt might not arrive when a module is inserted. When an link status change interrupt occurred and the driver still regard SFP as unplugged, link becomes up and the real media type is unknown. e.g: % ifconfig -m ixg0 (snip) media: Ethernet autoselect (autoselect rxpause,txpause) status: active supported Ethernet media: media none media autoselect (snip) To resolve this problem, when an link status change interrupt occurred and the driver still regard SFP as unplugged, issue the module softint before issuing LSC interrupt. To generate a diff of this commit: cvs rdiff -u -r1.199.2.1 -r1.199.2.2 src/sys/dev/pci/ixgbe/ixgbe.c cvs rdiff -u -r1.125.2.1 -r1.125.2.2 src/sys/dev/pci/ixgbe/ixv.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.1 src/sys/dev/pci/ixgbe/ixgbe.c:1.199.2.2 --- src/sys/dev/pci/ixgbe/ixgbe.c:1.199.2.1 Sun Sep 1 11:07:05 2019 +++ src/sys/dev/pci/ixgbe/ixgbe.c Sun Sep 1 11:12:45 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: ixgbe.c,v 1.199.2.1 2019/09/01 11:07:05 martin Exp $ */ +/* $NetBSD: ixgbe.c,v 1.199.2.2 2019/09/01 11:12:45 martin Exp $ */ /****************************************************************************** @@ -222,8 +222,8 @@ static void ixgbe_eitr_write(struct adap static void ixgbe_setup_vlan_hw_tagging(struct adapter *); static void ixgbe_setup_vlan_hw_support(struct adapter *); static int ixgbe_vlan_cb(struct ethercom *, uint16_t, bool); -static int ixgbe_register_vlan(void *, struct ifnet *, u16); -static int ixgbe_unregister_vlan(void *, struct ifnet *, u16); +static int ixgbe_register_vlan(struct adapter *, u16); +static int ixgbe_unregister_vlan(struct adapter *, u16); static void ixgbe_add_device_sysctls(struct adapter *); static void ixgbe_add_hw_stats(struct adapter *); @@ -1489,6 +1489,8 @@ ixgbe_is_sfp(struct ixgbe_hw *hw) return (TRUE); return (FALSE); case ixgbe_mac_82599EB: + case ixgbe_mac_X550EM_x: + case ixgbe_mac_X550EM_a: switch (hw->mac.ops.get_media_type(hw)) { case ixgbe_media_type_fiber: case ixgbe_media_type_fiber_qsfp: @@ -1496,11 +1498,6 @@ ixgbe_is_sfp(struct ixgbe_hw *hw) default: return (FALSE); } - case ixgbe_mac_X550EM_x: - case ixgbe_mac_X550EM_a: - if (hw->mac.ops.get_media_type(hw) == ixgbe_media_type_fiber) - return (TRUE); - return (FALSE); default: return (FALSE); } @@ -2310,9 +2307,9 @@ ixgbe_vlan_cb(struct ethercom *ec, uint1 int rv; if (set) - rv = ixgbe_register_vlan(ifp->if_softc, ifp, vid); + rv = ixgbe_register_vlan(adapter, vid); else - rv = ixgbe_unregister_vlan(ifp->if_softc, ifp, vid); + rv = ixgbe_unregister_vlan(adapter, vid); if (rv != 0) return rv; @@ -2336,15 +2333,11 @@ ixgbe_vlan_cb(struct ethercom *ec, uint1 * VFTA, init will repopulate the real table. ************************************************************************/ static int -ixgbe_register_vlan(void *arg, struct ifnet *ifp, u16 vtag) +ixgbe_register_vlan(struct adapter *adapter, u16 vtag) { - struct adapter *adapter = ifp->if_softc; u16 index, bit; int error; - if (ifp->if_softc != arg) /* Not our event */ - return EINVAL; - if ((vtag == 0) || (vtag > 4095)) /* Invalid */ return EINVAL; @@ -2367,15 +2360,11 @@ ixgbe_register_vlan(void *arg, struct if * Run via vlan unconfig EVENT, remove our entry in the soft vfta. ************************************************************************/ static int -ixgbe_unregister_vlan(void *arg, struct ifnet *ifp, u16 vtag) +ixgbe_unregister_vlan(struct adapter *adapter, u16 vtag) { - struct adapter *adapter = ifp->if_softc; u16 index, bit; int error; - if (ifp->if_softc != arg) - return EINVAL; - if ((vtag == 0) || (vtag > 4095)) /* Invalid */ return EINVAL; @@ -3124,6 +3113,34 @@ ixgbe_msix_link(void *arg) /* Clear interrupt with write */ IXGBE_WRITE_REG(hw, IXGBE_EICR, eicr); + if (ixgbe_is_sfp(hw)) { + /* Pluggable optics-related interrupt */ + if (hw->mac.type >= ixgbe_mac_X540) + eicr_mask = IXGBE_EICR_GPI_SDP0_X540; + else + eicr_mask = IXGBE_EICR_GPI_SDP2_BY_MAC(hw); + + /* + * An interrupt might not arrive when a module is inserted. + * When an link status change interrupt occurred and the driver + * still regard SFP as unplugged, issue the module softint + * and then issue LSC interrupt. + */ + if ((eicr & eicr_mask) + || ((hw->phy.sfp_type == ixgbe_sfp_type_not_present) + && (eicr & IXGBE_EICR_LSC))) { + IXGBE_WRITE_REG(hw, IXGBE_EICR, eicr_mask); + softint_schedule(adapter->mod_si); + } + + if ((hw->mac.type == ixgbe_mac_82599EB) && + (eicr & IXGBE_EICR_GPI_SDP1_BY_MAC(hw))) { + IXGBE_WRITE_REG(hw, IXGBE_EICR, + IXGBE_EICR_GPI_SDP1_BY_MAC(hw)); + softint_schedule(adapter->msf_si); + } + } + /* Link status change */ if (eicr & IXGBE_EICR_LSC) { IXGBE_WRITE_REG(hw, IXGBE_EIMC, IXGBE_EIMC_LSC); @@ -3182,26 +3199,6 @@ ixgbe_msix_link(void *arg) softint_schedule(adapter->mbx_si); } - if (ixgbe_is_sfp(hw)) { - /* Pluggable optics-related interrupt */ - if (hw->mac.type >= ixgbe_mac_X540) - eicr_mask = IXGBE_EICR_GPI_SDP0_X540; - else - eicr_mask = IXGBE_EICR_GPI_SDP2_BY_MAC(hw); - - if (eicr & eicr_mask) { - IXGBE_WRITE_REG(hw, IXGBE_EICR, eicr_mask); - softint_schedule(adapter->mod_si); - } - - if ((hw->mac.type == ixgbe_mac_82599EB) && - (eicr & IXGBE_EICR_GPI_SDP1_BY_MAC(hw))) { - IXGBE_WRITE_REG(hw, IXGBE_EICR, - IXGBE_EICR_GPI_SDP1_BY_MAC(hw)); - softint_schedule(adapter->msf_si); - } - } - /* Check for fan failure */ if (adapter->feat_en & IXGBE_FEATURE_FAN_FAIL) { ixgbe_check_fan_failure(adapter, eicr, TRUE); Index: src/sys/dev/pci/ixgbe/ixv.c diff -u src/sys/dev/pci/ixgbe/ixv.c:1.125.2.1 src/sys/dev/pci/ixgbe/ixv.c:1.125.2.2 --- src/sys/dev/pci/ixgbe/ixv.c:1.125.2.1 Sun Sep 1 11:07:05 2019 +++ src/sys/dev/pci/ixgbe/ixv.c Sun Sep 1 11:12:45 2019 @@ -1,4 +1,4 @@ -/*$NetBSD: ixv.c,v 1.125.2.1 2019/09/01 11:07:05 martin Exp $*/ +/*$NetBSD: ixv.c,v 1.125.2.2 2019/09/01 11:12:45 martin Exp $*/ /****************************************************************************** @@ -123,8 +123,8 @@ static void ixv_eitr_write(struct adapte static void ixv_setup_vlan_tagging(struct adapter *); static int ixv_setup_vlan_support(struct adapter *); static int ixv_vlan_cb(struct ethercom *, uint16_t, bool); -static int ixv_register_vlan(void *, struct ifnet *, u16); -static int ixv_unregister_vlan(void *, struct ifnet *, u16); +static int ixv_register_vlan(struct adapter *, u16); +static int ixv_unregister_vlan(struct adapter *, u16); static void ixv_add_device_sysctls(struct adapter *); static void ixv_save_stats(struct adapter *); @@ -2058,9 +2058,9 @@ ixv_vlan_cb(struct ethercom *ec, uint16_ int rv; if (set) - rv = ixv_register_vlan(ifp->if_softc, ifp, vid); + rv = ixv_register_vlan(adapter, vid); else - rv = ixv_unregister_vlan(ifp->if_softc, ifp, vid); + rv = ixv_unregister_vlan(adapter, vid); if (rv != 0) return rv; @@ -2084,16 +2084,12 @@ ixv_vlan_cb(struct ethercom *ec, uint16_ * will repopulate the real table. ************************************************************************/ static int -ixv_register_vlan(void *arg, struct ifnet *ifp, u16 vtag) +ixv_register_vlan(struct adapter *adapter, u16 vtag) { - struct adapter *adapter = ifp->if_softc; struct ixgbe_hw *hw = &adapter->hw; u16 index, bit; int error; - if (ifp->if_softc != arg) /* Not our event */ - return EINVAL; - if ((vtag == 0) || (vtag > 4095)) /* Invalid */ return EINVAL; IXGBE_CORE_LOCK(adapter); @@ -2118,16 +2114,12 @@ ixv_register_vlan(void *arg, struct ifne * in the soft vfta. ************************************************************************/ static int -ixv_unregister_vlan(void *arg, struct ifnet *ifp, u16 vtag) +ixv_unregister_vlan(struct adapter *adapter, u16 vtag) { - struct adapter *adapter = ifp->if_softc; struct ixgbe_hw *hw = &adapter->hw; u16 index, bit; int error; - if (ifp->if_softc != arg) - return EINVAL; - if ((vtag == 0) || (vtag > 4095)) /* Invalid */ return EINVAL;