summaryrefslogtreecommitdiffstats
path: root/sys/dev/e1000/if_igb.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/e1000/if_igb.c')
-rw-r--r--sys/dev/e1000/if_igb.c122
1 files changed, 85 insertions, 37 deletions
diff --git a/sys/dev/e1000/if_igb.c b/sys/dev/e1000/if_igb.c
index cb6c63f..0db4a49 100644
--- a/sys/dev/e1000/if_igb.c
+++ b/sys/dev/e1000/if_igb.c
@@ -1,6 +1,6 @@
/******************************************************************************
- Copyright (c) 2001-2011, Intel Corporation
+ Copyright (c) 2001-2012, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -100,7 +100,7 @@ int igb_display_debug_stats = 0;
/*********************************************************************
* Driver version:
*********************************************************************/
-char igb_driver_version[] = "version - 2.3.1";
+char igb_driver_version[] = "version - 2.3.4";
/*********************************************************************
@@ -150,6 +150,14 @@ static igb_vendor_info_t igb_vendor_info_array[] =
{ 0x8086, E1000_DEV_ID_I350_SERDES, PCI_ANY_ID, PCI_ANY_ID, 0},
{ 0x8086, E1000_DEV_ID_I350_SGMII, PCI_ANY_ID, PCI_ANY_ID, 0},
{ 0x8086, E1000_DEV_ID_I350_VF, PCI_ANY_ID, PCI_ANY_ID, 0},
+ { 0x8086, E1000_DEV_ID_I210_COPPER, PCI_ANY_ID, PCI_ANY_ID, 0},
+ { 0x8086, E1000_DEV_ID_I210_COPPER_IT, PCI_ANY_ID, PCI_ANY_ID, 0},
+ { 0x8086, E1000_DEV_ID_I210_COPPER_OEM1,
+ PCI_ANY_ID, PCI_ANY_ID, 0},
+ { 0x8086, E1000_DEV_ID_I210_FIBER, PCI_ANY_ID, PCI_ANY_ID, 0},
+ { 0x8086, E1000_DEV_ID_I210_SERDES, PCI_ANY_ID, PCI_ANY_ID, 0},
+ { 0x8086, E1000_DEV_ID_I210_SGMII, PCI_ANY_ID, PCI_ANY_ID, 0},
+ { 0x8086, E1000_DEV_ID_I211_COPPER, PCI_ANY_ID, PCI_ANY_ID, 0},
/* required last entry */
{ 0, 0, 0, 0, 0}
};
@@ -580,9 +588,10 @@ igb_attach(device_t dev)
adapter, 0, igb_sysctl_dmac, "I", "DMA Coalesce");
igb_set_sysctl_value(adapter, "eee_disabled",
"enable Energy Efficient Ethernet",
- &adapter->hw.dev_spec._82575.eee_disable,
+ (int *)&adapter->hw.dev_spec._82575.eee_disable,
TRUE);
- e1000_set_eee_i350(&adapter->hw);
+ if (adapter->hw.phy.media_type == e1000_media_type_copper)
+ e1000_set_eee_i350(&adapter->hw);
}
/*
@@ -593,7 +602,9 @@ igb_attach(device_t dev)
e1000_reset_hw(&adapter->hw);
/* Make sure we have a good EEPROM before we read from it */
- if (e1000_validate_nvm_checksum(&adapter->hw) < 0) {
+ if (((adapter->hw.mac.type != e1000_i210) &&
+ (adapter->hw.mac.type != e1000_i211)) &&
+ (e1000_validate_nvm_checksum(&adapter->hw) < 0)) {
/*
** Some PCI-E parts fail the first check due to
** the link being in sleep state, call it again,
@@ -756,6 +767,8 @@ igb_detach(device_t dev)
if (adapter->vlan_detach != NULL)
EVENTHANDLER_DEREGISTER(vlan_unconfig, adapter->vlan_detach);
+ ether_ifdetach(adapter->ifp);
+
callout_drain(&adapter->timer);
#ifdef DEV_NETMAP
@@ -924,7 +937,8 @@ igb_start(struct ifnet *ifp)
return;
}
-#else
+#else /* __FreeBSD_version >= 800000 */
+
/*
** Multiqueue Transmit driver
**
@@ -936,13 +950,11 @@ igb_mq_start(struct ifnet *ifp, struct mbuf *m)
struct igb_queue *que;
struct tx_ring *txr;
int i, err = 0;
- bool moveable = TRUE;
/* Which queue to use */
- if ((m->m_flags & M_FLOWID) != 0) {
+ if ((m->m_flags & M_FLOWID) != 0)
i = m->m_pkthdr.flowid % adapter->num_queues;
- moveable = FALSE;
- } else
+ else
i = curcpu % adapter->num_queues;
txr = &adapter->tx_rings[i];
@@ -953,7 +965,7 @@ igb_mq_start(struct ifnet *ifp, struct mbuf *m)
IGB_TX_UNLOCK(txr);
} else {
err = drbr_enqueue(ifp, txr->br, m);
- taskqueue_enqueue(que->tq, &txr->txq_task);
+ taskqueue_enqueue(que->tq, &que->que_task);
}
return (err);
@@ -1342,8 +1354,8 @@ igb_init_locked(struct adapter *adapter)
}
/* Set Energy Efficient Ethernet */
-
- e1000_set_eee_i350(&adapter->hw);
+ if (adapter->hw.phy.media_type == e1000_media_type_copper)
+ e1000_set_eee_i350(&adapter->hw);
}
static void
@@ -2566,6 +2578,8 @@ igb_configure_queues(struct adapter *adapter)
switch (adapter->hw.mac.type) {
case e1000_82580:
case e1000_i350:
+ case e1000_i210:
+ case e1000_i211:
case e1000_vfadapt:
case e1000_vfadapt_i350:
/* RX entries */
@@ -2764,7 +2778,7 @@ static int
igb_setup_msix(struct adapter *adapter)
{
device_t dev = adapter->dev;
- int rid, want, queues, msgs;
+ int rid, want, queues, msgs, maxqueues;
/* tuneable override */
if (igb_enable_msix == 0)
@@ -2795,16 +2809,29 @@ igb_setup_msix(struct adapter *adapter)
/* Manual override */
if (igb_num_queues != 0)
queues = igb_num_queues;
- if (queues > 8) /* max queues */
- queues = 8;
-
- /* Can have max of 4 queues on 82575 */
- if ((adapter->hw.mac.type == e1000_82575) && (queues > 4))
- queues = 4;
- /* Limit the VF devices to one queue */
- if (adapter->vf_ifp)
- queues = 1;
+ /* Sanity check based on HW */
+ switch (adapter->hw.mac.type) {
+ case e1000_82575:
+ maxqueues = 4;
+ break;
+ case e1000_82576:
+ case e1000_82580:
+ case e1000_i350:
+ maxqueues = 8;
+ break;
+ case e1000_i210:
+ maxqueues = 4;
+ break;
+ case e1000_i211:
+ maxqueues = 2;
+ break;
+ default: /* VF interfaces */
+ maxqueues = 1;
+ break;
+ }
+ if (queues > maxqueues)
+ queues = maxqueues;
/*
** One vector (RX/TX pair) per queue
@@ -2875,6 +2902,9 @@ igb_reset(struct adapter *adapter)
pba = E1000_READ_REG(hw, E1000_RXPBS);
pba = e1000_rxpbs_adjust_82580(pba);
break;
+ case e1000_i210:
+ case e1000_i211:
+ pba = E1000_PBA_34K;
default:
break;
}
@@ -2942,7 +2972,9 @@ igb_reset(struct adapter *adapter)
device_printf(dev, "Hardware Initialization Failed\n");
/* Setup DMA Coalescing */
- if (hw->mac.type == e1000_i350) {
+ if ((hw->mac.type > e1000_82580) &&
+ (hw->mac.type != e1000_i211)) {
+ u32 dmac;
u32 reg = ~E1000_DMACR_DMAC_EN;
if (adapter->dmac == 0) { /* Disabling it */
@@ -2950,26 +2982,36 @@ igb_reset(struct adapter *adapter)
goto reset_out;
}
- hwm = (pba - 4) << 10;
- reg = (((pba-6) << E1000_DMACR_DMACTHR_SHIFT)
- & E1000_DMACR_DMACTHR_MASK);
+ /* Set starting thresholds */
+ E1000_WRITE_REG(hw, E1000_DMCTXTH, 0);
+ E1000_WRITE_REG(hw, E1000_DMCRTRH, 0);
+ hwm = 64 * pba - adapter->max_frame_size / 16;
+ if (hwm < 64 * (pba - 6))
+ hwm = 64 * (pba - 6);
+ reg = E1000_READ_REG(hw, E1000_FCRTC);
+ reg &= ~E1000_FCRTC_RTH_COAL_MASK;
+ reg |= ((hwm << E1000_FCRTC_RTH_COAL_SHIFT)
+ & E1000_FCRTC_RTH_COAL_MASK);
+ E1000_WRITE_REG(hw, E1000_FCRTC, reg);
+
+
+ dmac = pba - adapter->max_frame_size / 512;
+ if (dmac < pba - 10)
+ dmac = pba - 10;
+ reg = E1000_READ_REG(hw, E1000_DMACR);
+ reg &= ~E1000_DMACR_DMACTHR_MASK;
+ reg = ((dmac << E1000_DMACR_DMACTHR_SHIFT)
+ & E1000_DMACR_DMACTHR_MASK);
/* transition to L0x or L1 if available..*/
reg |= (E1000_DMACR_DMAC_EN | E1000_DMACR_DMAC_LX_MASK);
-
/* timer = value in adapter->dmac in 32usec intervals */
reg |= (adapter->dmac >> 5);
E1000_WRITE_REG(hw, E1000_DMACR, reg);
- /* No lower threshold */
- E1000_WRITE_REG(hw, E1000_DMCRTRH, 0);
-
- /* set hwm to PBA - 2 * max frame size */
- E1000_WRITE_REG(hw, E1000_FCRTC, hwm);
-
/* Set the interval before transition */
reg = E1000_READ_REG(hw, E1000_DMCTLX);
- reg |= 0x800000FF; /* 255 usec */
+ reg |= 0x80000004;
E1000_WRITE_REG(hw, E1000_DMCTLX, reg);
/* free space in tx packet buffer to wake from DMA coal */
@@ -2978,9 +3020,15 @@ igb_reset(struct adapter *adapter)
/* make low power state decision controlled by DMA coal */
reg = E1000_READ_REG(hw, E1000_PCIEMISC);
- E1000_WRITE_REG(hw, E1000_PCIEMISC,
- reg | E1000_PCIEMISC_LX_DECISION);
+ reg &= ~E1000_PCIEMISC_LX_DECISION;
+ E1000_WRITE_REG(hw, E1000_PCIEMISC, reg);
device_printf(dev, "DMA Coalescing enabled\n");
+
+ } else if (hw->mac.type == e1000_82580) {
+ u32 reg = E1000_READ_REG(hw, E1000_PCIEMISC);
+ E1000_WRITE_REG(hw, E1000_DMACR, 0);
+ E1000_WRITE_REG(hw, E1000_PCIEMISC,
+ reg & ~E1000_PCIEMISC_LX_DECISION);
}
reset_out:
OpenPOWER on IntegriCloud