aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/e1000e/netdev.c
diff options
context:
space:
mode:
authorJesse Brandeburg <jesse.brandeburg@intel.com>2010-09-29 21:38:49 +0000
committerDavid S. Miller <davem@davemloft.net>2010-09-30 17:59:31 -0700
commit3a3b75860527a11ba5035c6aa576079245d09e2a (patch)
tree0dbd487fe8910a02c39ab4f84da6d16ebe6d29e3 /drivers/net/e1000e/netdev.c
parentixgbe: fix link issues and panic with shared interrupts for 82598 (diff)
downloadlinux-dev-3a3b75860527a11ba5035c6aa576079245d09e2a.tar.xz
linux-dev-3a3b75860527a11ba5035c6aa576079245d09e2a.zip
e1000e: use hardware writeback batching
Most e1000e parts support batching writebacks. The problem with this is that when some of the TADV or TIDV timers are not set, Tx can sit forever. This is solved in this patch with write flushes using the Flush Partial Descriptors (FPD) bit in TIDV and RDTR. This improves bus utilization and removes partial writes on e1000e, particularly from 82571 parts in S5500 chipset based machines. Only ES2LAN and 82571/2 parts are included in this optimization, to reduce testing load. Signed-off-by: Jesse Brandeburg <jesse.brandeburg@intel.com> Tested-by: Emil Tantilov <emil.s.tantilov@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/e1000e/netdev.c')
-rw-r--r--drivers/net/e1000e/netdev.c53
1 files changed, 53 insertions, 0 deletions
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c
index c69563c3ce96..1aa4228e860a 100644
--- a/drivers/net/e1000e/netdev.c
+++ b/drivers/net/e1000e/netdev.c
@@ -2650,6 +2650,26 @@ static void e1000_configure_tx(struct e1000_adapter *adapter)
/* Tx irq moderation */
ew32(TADV, adapter->tx_abs_int_delay);
+ if (adapter->flags2 & FLAG2_DMA_BURST) {
+ u32 txdctl = er32(TXDCTL(0));
+ txdctl &= ~(E1000_TXDCTL_PTHRESH | E1000_TXDCTL_HTHRESH |
+ E1000_TXDCTL_WTHRESH);
+ /*
+ * set up some performance related parameters to encourage the
+ * hardware to use the bus more efficiently in bursts, depends
+ * on the tx_int_delay to be enabled,
+ * wthresh = 5 ==> burst write a cacheline (64 bytes) at a time
+ * hthresh = 1 ==> prefetch when one or more available
+ * pthresh = 0x1f ==> prefetch if internal cache 31 or less
+ * BEWARE: this seems to work but should be considered first if
+ * there are tx hangs or other tx related bugs
+ */
+ txdctl |= E1000_TXDCTL_DMA_BURST_ENABLE;
+ ew32(TXDCTL(0), txdctl);
+ /* erratum work around: set txdctl the same for both queues */
+ ew32(TXDCTL(1), txdctl);
+ }
+
/* Program the Transmit Control Register */
tctl = er32(TCTL);
tctl &= ~E1000_TCTL_CT;
@@ -2872,6 +2892,29 @@ static void e1000_configure_rx(struct e1000_adapter *adapter)
e1e_flush();
msleep(10);
+ if (adapter->flags2 & FLAG2_DMA_BURST) {
+ /*
+ * set the writeback threshold (only takes effect if the RDTR
+ * is set). set GRAN=1 and write back up to 0x4 worth, and
+ * enable prefetching of 0x20 rx descriptors
+ * granularity = 01
+ * wthresh = 04,
+ * hthresh = 04,
+ * pthresh = 0x20
+ */
+ ew32(RXDCTL(0), E1000_RXDCTL_DMA_BURST_ENABLE);
+ ew32(RXDCTL(1), E1000_RXDCTL_DMA_BURST_ENABLE);
+
+ /*
+ * override the delay timers for enabling bursting, only if
+ * the value was not set by the user via module options
+ */
+ if (adapter->rx_int_delay == DEFAULT_RDTR)
+ adapter->rx_int_delay = BURST_RDTR;
+ if (adapter->rx_abs_int_delay == DEFAULT_RADV)
+ adapter->rx_abs_int_delay = BURST_RADV;
+ }
+
/* set the Receive Delay Timer Register */
ew32(RDTR, adapter->rx_int_delay);
@@ -4235,6 +4278,16 @@ link_up:
/* Force detection of hung controller every watchdog period */
adapter->detect_tx_hung = 1;
+ /* flush partial descriptors to memory before detecting tx hang */
+ if (adapter->flags2 & FLAG2_DMA_BURST) {
+ ew32(TIDV, adapter->tx_int_delay | E1000_TIDV_FPD);
+ ew32(RDTR, adapter->rx_int_delay | E1000_RDTR_FPD);
+ /*
+ * no need to flush the writes because the timeout code does
+ * an er32 first thing
+ */
+ }
+
/*
* With 82571 controllers, LAA may be overwritten due to controller
* reset from the other port. Set the appropriate LAA in RAR[0]