summaryrefslogtreecommitdiff
path: root/sys/dev/pci/if_ix.c
diff options
context:
space:
mode:
authorMike Belopuhov <mikeb@cvs.openbsd.org>2012-08-06 21:07:53 +0000
committerMike Belopuhov <mikeb@cvs.openbsd.org>2012-08-06 21:07:53 +0000
commit244cccfed6ad64fc3b8399ca59ada5b2f19a9290 (patch)
tree4b8c542dd4b26bc637f5a84f426db1431f0d49df /sys/dev/pci/if_ix.c
parent082fbc62061b14dfbc3fd5bb7f007bc828afc556 (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.c54
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);