diff options
author | Mike Belopuhov <mikeb@cvs.openbsd.org> | 2012-08-06 21:07:53 +0000 |
---|---|---|
committer | Mike Belopuhov <mikeb@cvs.openbsd.org> | 2012-08-06 21:07:53 +0000 |
commit | 244cccfed6ad64fc3b8399ca59ada5b2f19a9290 (patch) | |
tree | 4b8c542dd4b26bc637f5a84f426db1431f0d49df /sys/dev/pci/if_ix.c | |
parent | 082fbc62061b14dfbc3fd5bb7f007bc828afc556 (diff) |
Add support for 10Gb ethernet cards based on the Intel X540 chipset.
The code was obtained from FreeBSD and tested on the hardware kindly
donated by Tony Sarendal <tony () polarcap ! org>. Thanks a lot!
ok jsg
Diffstat (limited to 'sys/dev/pci/if_ix.c')
-rw-r--r-- | sys/dev/pci/if_ix.c | 54 |
1 files changed, 47 insertions, 7 deletions
diff --git a/sys/dev/pci/if_ix.c b/sys/dev/pci/if_ix.c index a47bafc34cf..8875590ee4f 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.66 2012/07/29 13:49:03 mikeb Exp $ */ +/* $OpenBSD: if_ix.c,v 1.67 2012/08/06 21:07:52 mikeb Exp $ */ /****************************************************************************** @@ -72,7 +72,8 @@ const struct pci_matchid ixgbe_devices[] = { { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82599_T3_LOM }, { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82599_SFP }, { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82599_SFP_EM }, - { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82599_SFP_FCOE } + { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82599_SFP_FCOE }, + { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_X540T }, #if 0 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82599VF } #endif @@ -253,6 +254,9 @@ ixgbe_attach(struct device *parent, struct device *self, void *aux) error = ixgbe_init_ops_vf(hw); break; #endif + case ixgbe_mac_X540: + error = ixgbe_init_ops_X540(hw); + break; default: error = IXGBE_ERR_DEVICE_NOT_SUPPORTED; break; @@ -689,7 +693,7 @@ ixgbe_init(void *arg) gpie |= IXGBE_SDP1_GPIEN; if (sc->hw.mac.type == ixgbe_mac_82599EB) { - /* Add for Thermal detection */ + /* Add for Module detection */ gpie |= IXGBE_SDP2_GPIEN; /* @@ -699,6 +703,17 @@ ixgbe_init(void *arg) gpie |= 0xf << IXGBE_GPIE_LLI_DELAY_SHIFT; } + if (sc->hw.mac.type == ixgbe_mac_X540) { + /* Thermal Failure Detection */ + gpie |= IXGBE_SDP0_GPIEN; + + /* + * Set LL interval to max to reduce the number of low latency + * interrupts hitting the card when the ring is getting full. + */ + gpie |= 0xf << IXGBE_GPIE_LLI_DELAY_SHIFT; + } + if (sc->msix > 1) { /* Enable Enhanced MSIX mode */ gpie |= IXGBE_GPIE_MSIX_MODE; @@ -947,12 +962,20 @@ ixgbe_legacy_irq(void *arg) /* Check for fan failure */ if ((hw->phy.media_type == ixgbe_media_type_copper) && (reg_eicr & IXGBE_EICR_GPI_SDP1)) { - printf("\n%s: CRITICAL: FAN FAILURE!! " + printf("%s: CRITICAL: FAN FAILURE!! " "REPLACE IMMEDIATELY!!\n", ifp->if_xname); IXGBE_WRITE_REG(&sc->hw, IXGBE_EIMS, IXGBE_EICR_GPI_SDP1); } + /* Check for over temp condition */ + if ((hw->mac.type == ixgbe_mac_X540) && + (reg_eicr & IXGBE_EICR_GPI_SDP0)) { + printf("%s: CRITICAL: OVER TEMP!! " + "PHY IS SHUT DOWN!!\n", ifp->if_xname); + IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_GPI_SDP0); + } + /* Link status change */ if (reg_eicr & IXGBE_EICR_LSC) { timeout_del(&sc->timer); @@ -1001,6 +1024,9 @@ ixgbe_media_status(struct ifnet * ifp, struct ifmediareq * ifmr) ifmr->ifm_status |= IFM_ACTIVE; switch (sc->link_speed) { + case IXGBE_LINK_SPEED_100_FULL: + ifmr->ifm_active |= IFM_100_TX | IFM_FDX; + break; case IXGBE_LINK_SPEED_1GB_FULL: ifmr->ifm_active |= IFM_1000_T | IFM_FDX; break; @@ -1432,6 +1458,11 @@ ixgbe_identify_hardware(struct ix_softc *sc) sc->optics = IFM_AUTO; sc->hw.phy.smart_speed = ixgbe_smart_speed; break; + case PCI_PRODUCT_INTEL_X540T: + sc->hw.mac.type = ixgbe_mac_X540; + sc->optics = IFM_10G_T; + sc->hw.phy.smart_speed = ixgbe_smart_speed; + break; default: sc->optics = IFM_AUTO; break; @@ -1686,8 +1717,13 @@ ixgbe_config_link(struct ix_softc *sc) if (sc->hw.mac.ops.check_link) err = sc->hw.mac.ops.check_link(&sc->hw, &autoneg, &sc->link_up, FALSE); - if (err) - return; + if (err) + return; + if ((!autoneg) && (sc->hw.mac.ops.get_link_capabilities)) + err = sc->hw.mac.ops.get_link_capabilities(&sc->hw, + &autoneg, &negotiate); + if (err) + return; if (sc->hw.mac.ops.setup_link) err = sc->hw.mac.ops.setup_link(&sc->hw, autoneg, negotiate, sc->link_up); @@ -2047,6 +2083,7 @@ ixgbe_initialize_transmit_units(struct ix_softc *sc) txctrl = IXGBE_READ_REG(hw, IXGBE_DCA_TXCTRL(i)); break; case ixgbe_mac_82599EB: + case ixgbe_mac_X540: default: txctrl = IXGBE_READ_REG(hw, IXGBE_DCA_TXCTRL_82599(i)); break; @@ -2057,6 +2094,7 @@ ixgbe_initialize_transmit_units(struct ix_softc *sc) IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL(i), txctrl); break; case ixgbe_mac_82599EB: + case ixgbe_mac_X540: default: IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL_82599(i), txctrl); break; @@ -2064,7 +2102,7 @@ ixgbe_initialize_transmit_units(struct ix_softc *sc) } ifp->if_timer = 0; - if (hw->mac.type == ixgbe_mac_82599EB) { + if (hw->mac.type != ixgbe_mac_82598EB) { uint32_t dmatxctl, rttdcs; dmatxctl = IXGBE_READ_REG(hw, IXGBE_DMATXCTL); dmatxctl |= IXGBE_DMATXCTL_TE; @@ -3230,6 +3268,7 @@ ixgbe_enable_intr(struct ix_softc *sc) mask |= IXGBE_EIMS_GPI_SDP1; else { mask |= IXGBE_EIMS_ECC; + mask |= IXGBE_EIMS_GPI_SDP0; mask |= IXGBE_EIMS_GPI_SDP1; mask |= IXGBE_EIMS_GPI_SDP2; } @@ -3345,6 +3384,7 @@ ixgbe_set_ivar(struct ix_softc *sc, uint8_t entry, uint8_t vector, int8_t type) break; case ixgbe_mac_82599EB: + case ixgbe_mac_X540: if (type == -1) { /* MISC IVAR */ index = (entry & 1) * 8; ivar = IXGBE_READ_REG(hw, IXGBE_IVAR_MISC); |