first this allows you to connect the sfp+ cable after boot
and correctly identify and use it, secondly it allows you
(supposedly as i've only tested two different types of
direct attach cables, i.e. different phys) to switch between
copper and fiber w/o rebooting.

SDP1 interrupt processing is not enabled because i can't
test it.

code from the intel driver (except for handling the "bad" hp
cable correctly -- and that's "b" not "a" for those who have
any idea what i'm talking about).

OK?

diff --git sys/dev/pci/if_ix.c sys/dev/pci/if_ix.c
index 8c3f817..414d54f 100644
--- sys/dev/pci/if_ix.c
+++ sys/dev/pci/if_ix.c
@@ -145,6 +145,8 @@ void        ixgbe_setup_vlan_hw_support(struct ix_softc *);
 /* Support for pluggable optic modules */
 int    ixgbe_sfp_probe(struct ix_softc *);
 void   ixgbe_setup_optics(struct ix_softc *);
+void   ixgbe_handle_mod(struct ix_softc *);
+void   ixgbe_handle_msf(struct ix_softc *);
 
 /* Legacy (single vector interrupt handler */
 int    ixgbe_legacy_irq(void *);
@@ -928,12 +930,6 @@ ixgbe_legacy_irq(void *arg)
                return (0);
        }
 
-       if (ifp->if_flags & IFF_RUNNING) {
-               ixgbe_rxeof(que);
-               ixgbe_txeof(txr);
-               refill = 1;
-       }
-
        /* Check for fan failure */
        if ((hw->phy.media_type == ixgbe_media_type_copper) &&
            (reg_eicr & IXGBE_EICR_GPI_SDP1)) {
@@ -958,6 +954,28 @@ ixgbe_legacy_irq(void *arg)
                timeout_add_sec(&sc->timer, 1);
        }
 
+       if (hw->mac.type != ixgbe_mac_82598EB) {
+               if (reg_eicr & IXGBE_EICR_GPI_SDP2) {
+                       /* Clear the interrupt */
+                       IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_GPI_SDP2);
+                       ixgbe_handle_mod(sc);
+               }
+#if 0
+               else if ((hw->phy.media_type != ixgbe_media_type_copper) &&
+                   (reg_eicr & IXGBE_EICR_GPI_SDP1)) {
+                       /* Clear the interrupt */
+                       IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_GPI_SDP1);
+                       ixgbe_handle_msf(sc);
+               }
+#endif
+       }
+
+       if (ifp->if_flags & IFF_RUNNING) {
+               ixgbe_rxeof(que);
+               ixgbe_txeof(txr);
+               refill = 1;
+       }
+
        if (refill) {
                if (ixgbe_rxfill(que->rxr)) {
                        /* Advance the Rx Queue "Tail Pointer" */
@@ -3408,6 +3426,53 @@ out:
        return (result);
 }
 
+/*
+ * SFP module interrupts handler
+ */
+void
+ixgbe_handle_mod(struct ix_softc *sc)
+{
+       struct ixgbe_hw *hw = &sc->hw;
+       uint32_t err;
+
+       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;
+       }
+       err = hw->mac.ops.setup_sfp(hw);
+       if (err == IXGBE_ERR_SFP_NOT_SUPPORTED) {
+               printf("%s: Setup failure - unsupported SFP+ module type!\n",
+                   sc->dev.dv_xname);
+               return;
+       }
+       return (ixgbe_handle_msf(sc));
+}
+
+
+/*
+ * MSF (multispeed fiber) interrupts handler
+ */
+void
+ixgbe_handle_msf(struct ix_softc *sc)
+{
+       struct ixgbe_hw *hw = &sc->hw;
+       uint32_t autoneg;
+       int negotiate;
+
+       /* XXX: must be changeable in ixgbe_media_change */
+       autoneg = IXGBE_LINK_SPEED_100_FULL |
+                 IXGBE_LINK_SPEED_1GB_FULL |
+                 IXGBE_LINK_SPEED_10GB_FULL;
+       if ((!autoneg) && (hw->mac.ops.get_link_capabilities))
+               hw->mac.ops.get_link_capabilities(hw, &autoneg, &negotiate);
+       if (hw->mac.ops.setup_link)
+               hw->mac.ops.setup_link(hw, autoneg, negotiate, TRUE);
+       /* Set the optics type so system reports correctly */
+       ixgbe_setup_optics(sc);
+}
+
 /**********************************************************************
  *
  *  Update the board statistics counters.
diff --git sys/dev/pci/ixgbe_82599.c sys/dev/pci/ixgbe_82599.c
index 350ddc7..e91579d 100644
--- sys/dev/pci/ixgbe_82599.c
+++ sys/dev/pci/ixgbe_82599.c
@@ -1350,6 +1350,11 @@ sfp_check:
                        physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_SR;
                else if (comp_codes_10g & IXGBE_SFF_10GBASELR_CAPABLE)
                        physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_LR;
+               else if (comp_codes_10g &
+                   (IXGBE_SFF_DA_PASSIVE_CABLE | IXGBE_SFF_DA_BAD_HP_CABLE))
+                       physical_layer = IXGBE_PHYSICAL_LAYER_SFP_PLUS_CU;
+               else if (comp_codes_10g & IXGBE_SFF_DA_ACTIVE_CABLE)
+                       physical_layer = IXGBE_PHYSICAL_LAYER_SFP_ACTIVE_DA;
                else if (comp_codes_1g & IXGBE_SFF_1GBASET_CAPABLE)
                        physical_layer = IXGBE_PHYSICAL_LAYER_1000BASE_T;
                break;

Reply via email to