Hi,

I would like to collect some reports on whether or not this change
helps with hot-(re)plugging SFP+ modules.  In theory if a different
type of an SFP+ module is inserted we should re-initialize the PHY
and reset our media configuration.  This should matter when a fiber
optics module is replacing a direct attach (TWINAX) one or an
10GbaseLR module is inserted instead of a 10GbaseSR (if both are
known to work with the card when plugged before a cold boot).

Of primary interest are X520 (82599) devices, however users with
X557 SFP+ cards are encouraged to test as well.

>From FreeBSD:
https://svnweb.freebsd.org/base/head/sys/dev/ixgbe/if_ix.c?revision=293334&view=markup


diff --git sys/dev/pci/if_ix.c sys/dev/pci/if_ix.c
index fd2f72a..0a788fc 100644
--- sys/dev/pci/if_ix.c
+++ sys/dev/pci/if_ix.c
@@ -1700,17 +1700,11 @@ ixgbe_config_link(struct ix_softc *sc)
 {
        uint32_t        autoneg, err = 0;
        bool            negotiate;
 
        if (ixgbe_is_sfp(&sc->hw)) {
-               if (sc->hw.phy.multispeed_fiber) {
-                       sc->hw.mac.ops.setup_sfp(&sc->hw);
-                       if (sc->hw.mac.ops.enable_tx_laser)
-                               sc->hw.mac.ops.enable_tx_laser(&sc->hw);
-                       ixgbe_handle_msf(sc);
-               } else
-                       ixgbe_handle_mod(sc);
+               ixgbe_handle_mod(sc);
        } else {
                if (sc->hw.mac.ops.check_link)
                        err = sc->hw.mac.ops.check_link(&sc->hw, &autoneg,
                            &sc->link_up, FALSE);
                if (err)
@@ -3239,12 +3233,32 @@ ixgbe_configure_ivars(struct ix_softc *sc)
  */
 void
 ixgbe_handle_mod(struct ix_softc *sc)
 {
        struct ixgbe_hw *hw = &sc->hw;
+       enum ixgbe_phy_type orig_type = hw->phy.type;
        uint32_t err;
 
+       /* Check to see if the PHY type changed */
+       if (hw->phy.ops.identify) {
+               hw->phy.type = ixgbe_phy_unknown;
+               hw->phy.ops.identify(hw);
+       }
+
+       if (hw->phy.type != orig_type) {
+               if (hw->phy.type == ixgbe_phy_none) {
+                       hw->phy.sfp_type = ixgbe_sfp_type_unknown;
+                       goto out;
+               }
+
+               /* Try to do the initialization that was skipped before */
+               if (hw->phy.ops.init)
+                       hw->phy.ops.init(hw);
+               if (hw->phy.ops.reset)
+                       hw->phy.ops.reset(hw);
+       }
+
        err = hw->phy.ops.identify_sfp(hw);
        if (err == IXGBE_ERR_SFP_NOT_SUPPORTED) {
                printf("%s: Unsupported SFP+ module type was detected!\n",
                    sc->dev.dv_xname);
                return;
@@ -3253,13 +3267,18 @@ ixgbe_handle_mod(struct ix_softc *sc)
        if (err == IXGBE_ERR_SFP_NOT_SUPPORTED) {
                printf("%s: Setup failure - unsupported SFP+ module type!\n",
                    sc->dev.dv_xname);
                return;
        }
+ out:
        /* Set the optics type so system reports correctly */
        ixgbe_setup_optics(sc);
 
+       ifmedia_delete_instance(&sc->media, IFM_INST_ANY);
+       ixgbe_add_media_types(sc);
+       ifmedia_set(&sc->media, IFM_ETHER | IFM_AUTO);
+
        ixgbe_handle_msf(sc);
 }
 
 
 /*

Reply via email to