diff options
author | Mike Belopuhov <mikeb@cvs.openbsd.org> | 2012-12-17 12:28:07 +0000 |
---|---|---|
committer | Mike Belopuhov <mikeb@cvs.openbsd.org> | 2012-12-17 12:28:07 +0000 |
commit | 2d6d4888ea7c26b1484ca0bb1b4bb717df8dd64d (patch) | |
tree | 7b168049f97fdc0b29c0a13b3447fe53b449e567 /sys/dev/pci/if_ix.c | |
parent | 434b2ece723b0cb2c2c3312eb5592e3c0591dc6a (diff) |
Implement SFP+ module hot-plug support for 82599 obtained
from FreeBSD. This also adds untested and hence disabled
support for multispeed fiber interrupts. With input from
and ok jsg.
Diffstat (limited to 'sys/dev/pci/if_ix.c')
-rw-r--r-- | sys/dev/pci/if_ix.c | 81 |
1 files changed, 74 insertions, 7 deletions
diff --git a/sys/dev/pci/if_ix.c b/sys/dev/pci/if_ix.c index f018465cad2..2cb1969dab3 100644 --- a/sys/dev/pci/if_ix.c +++ b/sys/dev/pci/if_ix.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_ix.c,v 1.79 2012/12/17 12:03:16 mikeb Exp $ */ +/* $OpenBSD: if_ix.c,v 1.80 2012/12/17 12:28:06 mikeb Exp $ */ /****************************************************************************** @@ -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 *); @@ -931,12 +933,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)) { @@ -961,6 +957,32 @@ 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 + /* + * XXX: Processing of SDP1 (multispeed fiber) interrupts is + * disabled due to the lack of testing + */ + 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" */ @@ -3382,6 +3404,51 @@ 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; + } + /* Set the optics type so system reports correctly */ + ixgbe_setup_optics(sc); + + 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; + + autoneg = hw->phy.autoneg_advertised; + 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); +} + /********************************************************************** * * Update the board statistics counters. |