summaryrefslogtreecommitdiffstats
path: root/sys/dev/e1000/if_lem.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/e1000/if_lem.c')
-rw-r--r--sys/dev/e1000/if_lem.c104
1 files changed, 30 insertions, 74 deletions
diff --git a/sys/dev/e1000/if_lem.c b/sys/dev/e1000/if_lem.c
index 4ade180..882bd3c 100644
--- a/sys/dev/e1000/if_lem.c
+++ b/sys/dev/e1000/if_lem.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
@@ -85,7 +85,7 @@
/*********************************************************************
* Legacy Em Driver version:
*********************************************************************/
-char lem_driver_version[] = "1.0.4";
+char lem_driver_version[] = "1.0.5";
/*********************************************************************
* PCI Device ID Table
@@ -239,16 +239,12 @@ static void lem_enable_wakeup(device_t);
static int lem_enable_phy_wakeup(struct adapter *);
static void lem_led_func(void *, int);
-#define EM_LEGACY_IRQ /* slightly faster, at least in qemu */
-#ifdef EM_LEGACY_IRQ
static void lem_intr(void *);
-#else /* FAST IRQ */
static int lem_irq_fast(void *);
static void lem_handle_rxtx(void *context, int pending);
static void lem_handle_link(void *context, int pending);
static void lem_add_rx_process_limit(struct adapter *, const char *,
const char *, int *, int);
-#endif /* ~EM_LEGACY_IRQ */
#ifdef DEVICE_POLLING
static poll_handler_t lem_poll;
@@ -305,11 +301,13 @@ TUNABLE_INT("hw.em.txd", &lem_txd);
TUNABLE_INT("hw.em.smart_pwr_down", &lem_smart_pwr_down);
TUNABLE_INT("hw.em.sbp", &lem_debug_sbp);
-#ifndef EM_LEGACY_IRQ
+/* Interrupt style - default to fast */
+static int lem_use_legacy_irq = 0;
+TUNABLE_INT("hw.em.use_legacy_irq", &lem_use_legacy_irq);
+
/* How many packets rxeof tries to clean at a time */
static int lem_rx_process_limit = 100;
TUNABLE_INT("hw.em.rx_process_limit", &lem_rx_process_limit);
-#endif
/* Flow control setting - default to FULL */
static int lem_fc_setting = e1000_fc_full;
@@ -451,12 +449,10 @@ lem_attach(device_t dev)
lem_tx_abs_int_delay_dflt);
}
-#ifndef EM_LEGACY_IRQ
/* Sysctls for limiting the amount of work done in the taskqueue */
lem_add_rx_process_limit(adapter, "rx_processing_limit",
"max number of rx packets to process", &adapter->rx_process_limit,
lem_rx_process_limit);
-#endif
/* Sysctl for setting the interface flow control */
lem_set_flow_cntrl(adapter, "flow_control",
@@ -1198,22 +1194,6 @@ lem_init_locked(struct adapter *adapter)
callout_reset(&adapter->timer, hz, lem_local_timer, adapter);
e1000_clear_hw_cntrs_base_generic(&adapter->hw);
- /* MSI/X configuration for 82574 */
- if (adapter->hw.mac.type == e1000_82574) {
- int tmp;
- tmp = E1000_READ_REG(&adapter->hw, E1000_CTRL_EXT);
- tmp |= E1000_CTRL_EXT_PBA_CLR;
- E1000_WRITE_REG(&adapter->hw, E1000_CTRL_EXT, tmp);
- /*
- ** Set the IVAR - interrupt vector routing.
- ** Each nibble represents a vector, high bit
- ** is enable, other 3 bits are the MSIX table
- ** entry, we map RXQ0 to 0, TXQ0 to 1, and
- ** Link (other) to 2, hence the magic number.
- */
- E1000_WRITE_REG(&adapter->hw, E1000_IVAR, 0x800A0908);
- }
-
#ifdef DEVICE_POLLING
/*
* Only enable interrupts if we are not polling, make sure
@@ -1282,7 +1262,6 @@ lem_poll(struct ifnet *ifp, enum poll_cmd cmd, int count)
}
#endif /* DEVICE_POLLING */
-#ifdef EM_LEGACY_IRQ
/*********************************************************************
*
* Legacy Interrupt Service routine
@@ -1296,7 +1275,8 @@ lem_intr(void *arg)
u32 reg_icr;
- if (ifp->if_capenable & IFCAP_POLLING)
+ if ((ifp->if_capenable & IFCAP_POLLING) ||
+ ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0))
return;
EM_CORE_LOCK(adapter);
@@ -1304,11 +1284,10 @@ lem_intr(void *arg)
if (reg_icr & E1000_ICR_RXO)
adapter->rx_overruns++;
- if ((reg_icr == 0xffffffff) || (reg_icr == 0))
- goto out;
-
- if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
- goto out;
+ if ((reg_icr == 0xffffffff) || (reg_icr == 0)) {
+ EM_CORE_UNLOCK(adapter);
+ return;
+ }
if (reg_icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) {
callout_stop(&adapter->timer);
@@ -1318,23 +1297,22 @@ lem_intr(void *arg)
lem_tx_purge(adapter);
callout_reset(&adapter->timer, hz,
lem_local_timer, adapter);
- goto out;
+ EM_CORE_UNLOCK(adapter);
+ return;
}
- EM_TX_LOCK(adapter);
+ EM_CORE_UNLOCK(adapter);
lem_rxeof(adapter, -1, NULL);
+
+ EM_TX_LOCK(adapter);
lem_txeof(adapter);
if (ifp->if_drv_flags & IFF_DRV_RUNNING &&
!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
lem_start_locked(ifp);
EM_TX_UNLOCK(adapter);
-
-out:
- EM_CORE_UNLOCK(adapter);
return;
}
-#else /* EM_FAST_IRQ, then fast interrupt routines only */
static void
lem_handle_link(void *context, int pending)
@@ -1418,7 +1396,6 @@ lem_irq_fast(void *arg)
adapter->rx_overruns++;
return FILTER_HANDLED;
}
-#endif /* ~EM_LEGACY_IRQ */
/*********************************************************************
@@ -2215,19 +2192,21 @@ lem_allocate_irq(struct adapter *adapter)
return (ENXIO);
}
-#ifdef EM_LEGACY_IRQ
- /* We do Legacy setup */
- if ((error = bus_setup_intr(dev, adapter->res[0],
- INTR_TYPE_NET | INTR_MPSAFE, NULL, lem_intr, adapter,
- &adapter->tag[0])) != 0) {
- device_printf(dev, "Failed to register interrupt handler");
- return (error);
+ /* Do Legacy setup? */
+ if (lem_use_legacy_irq) {
+ if ((error = bus_setup_intr(dev, adapter->res[0],
+ INTR_TYPE_NET | INTR_MPSAFE, NULL, lem_intr, adapter,
+ &adapter->tag[0])) != 0) {
+ device_printf(dev,
+ "Failed to register interrupt handler");
+ return (error);
+ }
+ return (0);
}
-#else /* FAST_IRQ */
/*
- * Try allocating a fast interrupt and the associated deferred
- * processing contexts.
+ * Use a Fast interrupt and the associated
+ * deferred processing contexts.
*/
TASK_INIT(&adapter->rxtx_task, 0, lem_handle_rxtx, adapter);
TASK_INIT(&adapter->link_task, 0, lem_handle_link, adapter);
@@ -2244,7 +2223,6 @@ lem_allocate_irq(struct adapter *adapter)
adapter->tq = NULL;
return (error);
}
-#endif /* EM_LEGACY_IRQ */
return (0);
}
@@ -3302,20 +3280,6 @@ lem_initialize_receive_unit(struct adapter *adapter)
E1000_WRITE_REG(&adapter->hw, E1000_ITR, DEFAULT_ITR);
}
- /*
- ** When using MSIX interrupts we need to throttle
- ** using the EITR register (82574 only)
- */
- if (adapter->msix)
- for (int i = 0; i < 4; i++)
- E1000_WRITE_REG(&adapter->hw,
- E1000_EITR_82574(i), DEFAULT_ITR);
-
- /* Disable accelerated ackknowledge */
- if (adapter->hw.mac.type == e1000_82574)
- E1000_WRITE_REG(&adapter->hw,
- E1000_RFCTL, E1000_RFCTL_ACK_DIS);
-
/* Setup the Base and Length of the Rx Descriptor Ring */
bus_addr = adapter->rxdma.dma_paddr;
E1000_WRITE_REG(&adapter->hw, E1000_RDLEN(0),
@@ -3835,10 +3799,6 @@ lem_enable_intr(struct adapter *adapter)
struct e1000_hw *hw = &adapter->hw;
u32 ims_mask = IMS_ENABLE_MASK;
- if (adapter->msix) {
- E1000_WRITE_REG(hw, EM_EIAC, EM_MSIX_MASK);
- ims_mask |= EM_MSIX_MASK;
- }
E1000_WRITE_REG(hw, E1000_IMS, ims_mask);
}
@@ -3847,9 +3807,7 @@ lem_disable_intr(struct adapter *adapter)
{
struct e1000_hw *hw = &adapter->hw;
- if (adapter->msix)
- E1000_WRITE_REG(hw, EM_EIAC, 0);
- E1000_WRITE_REG(&adapter->hw, E1000_IMC, 0xffffffff);
+ E1000_WRITE_REG(hw, E1000_IMC, 0xffffffff);
}
/*
@@ -4683,7 +4641,6 @@ lem_set_flow_cntrl(struct adapter *adapter, const char *name,
OID_AUTO, name, CTLTYPE_INT|CTLFLAG_RW, limit, value, description);
}
-#ifndef EM_LEGACY_IRQ
static void
lem_add_rx_process_limit(struct adapter *adapter, const char *name,
const char *description, int *limit, int value)
@@ -4693,4 +4650,3 @@ lem_add_rx_process_limit(struct adapter *adapter, const char *name,
SYSCTL_CHILDREN(device_get_sysctl_tree(adapter->dev)),
OID_AUTO, name, CTLTYPE_INT|CTLFLAG_RW, limit, value, description);
}
-#endif
OpenPOWER on IntegriCloud