aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorJesse Brandeburg <jesse.brandeburg@intel.com>2010-09-29 17:38:49 -0400
committerDavid S. Miller <davem@davemloft.net>2010-09-30 20:59:31 -0400
commit3a3b75860527a11ba5035c6aa576079245d09e2a (patch)
tree0dbd487fe8910a02c39ab4f84da6d16ebe6d29e3 /drivers
parent6af3b9ebfea38d0a057fbd7bdcecc61ac5662f02 (diff)
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')
-rw-r--r--drivers/net/e1000e/82571.c6
-rw-r--r--drivers/net/e1000e/defines.h2
-rw-r--r--drivers/net/e1000e/e1000.h28
-rw-r--r--drivers/net/e1000e/es2lan.c1
-rw-r--r--drivers/net/e1000e/netdev.c53
-rw-r--r--drivers/net/e1000e/param.c2
6 files changed, 88 insertions, 4 deletions
diff --git a/drivers/net/e1000e/82571.c b/drivers/net/e1000e/82571.c
index d3d4a57e245..ca663f19d7d 100644
--- a/drivers/net/e1000e/82571.c
+++ b/drivers/net/e1000e/82571.c
@@ -1801,7 +1801,8 @@ struct e1000_info e1000_82571_info = {
1801 | FLAG_RESET_OVERWRITES_LAA /* errata */ 1801 | FLAG_RESET_OVERWRITES_LAA /* errata */
1802 | FLAG_TARC_SPEED_MODE_BIT /* errata */ 1802 | FLAG_TARC_SPEED_MODE_BIT /* errata */
1803 | FLAG_APME_CHECK_PORT_B, 1803 | FLAG_APME_CHECK_PORT_B,
1804 .flags2 = FLAG2_DISABLE_ASPM_L1, /* errata 13 */ 1804 .flags2 = FLAG2_DISABLE_ASPM_L1 /* errata 13 */
1805 | FLAG2_DMA_BURST,
1805 .pba = 38, 1806 .pba = 38,
1806 .max_hw_frame_size = DEFAULT_JUMBO, 1807 .max_hw_frame_size = DEFAULT_JUMBO,
1807 .get_variants = e1000_get_variants_82571, 1808 .get_variants = e1000_get_variants_82571,
@@ -1819,7 +1820,8 @@ struct e1000_info e1000_82572_info = {
1819 | FLAG_RX_CSUM_ENABLED 1820 | FLAG_RX_CSUM_ENABLED
1820 | FLAG_HAS_CTRLEXT_ON_LOAD 1821 | FLAG_HAS_CTRLEXT_ON_LOAD
1821 | FLAG_TARC_SPEED_MODE_BIT, /* errata */ 1822 | FLAG_TARC_SPEED_MODE_BIT, /* errata */
1822 .flags2 = FLAG2_DISABLE_ASPM_L1, /* errata 13 */ 1823 .flags2 = FLAG2_DISABLE_ASPM_L1 /* errata 13 */
1824 | FLAG2_DMA_BURST,
1823 .pba = 38, 1825 .pba = 38,
1824 .max_hw_frame_size = DEFAULT_JUMBO, 1826 .max_hw_frame_size = DEFAULT_JUMBO,
1825 .get_variants = e1000_get_variants_82571, 1827 .get_variants = e1000_get_variants_82571,
diff --git a/drivers/net/e1000e/defines.h b/drivers/net/e1000e/defines.h
index 93b3bedae8d..d3f7a9c3f97 100644
--- a/drivers/net/e1000e/defines.h
+++ b/drivers/net/e1000e/defines.h
@@ -446,7 +446,9 @@
446 446
447/* Transmit Descriptor Control */ 447/* Transmit Descriptor Control */
448#define E1000_TXDCTL_PTHRESH 0x0000003F /* TXDCTL Prefetch Threshold */ 448#define E1000_TXDCTL_PTHRESH 0x0000003F /* TXDCTL Prefetch Threshold */
449#define E1000_TXDCTL_HTHRESH 0x00003F00 /* TXDCTL Host Threshold */
449#define E1000_TXDCTL_WTHRESH 0x003F0000 /* TXDCTL Writeback Threshold */ 450#define E1000_TXDCTL_WTHRESH 0x003F0000 /* TXDCTL Writeback Threshold */
451#define E1000_TXDCTL_GRAN 0x01000000 /* TXDCTL Granularity */
450#define E1000_TXDCTL_FULL_TX_DESC_WB 0x01010000 /* GRAN=1, WTHRESH=1 */ 452#define E1000_TXDCTL_FULL_TX_DESC_WB 0x01010000 /* GRAN=1, WTHRESH=1 */
451#define E1000_TXDCTL_MAX_TX_DESC_PREFETCH 0x0100001F /* GRAN=1, PTHRESH=31 */ 453#define E1000_TXDCTL_MAX_TX_DESC_PREFETCH 0x0100001F /* GRAN=1, PTHRESH=31 */
452/* Enable the counting of desc. still to be processed. */ 454/* Enable the counting of desc. still to be processed. */
diff --git a/drivers/net/e1000e/e1000.h b/drivers/net/e1000e/e1000.h
index f9a31c82f87..5ec0af59eea 100644
--- a/drivers/net/e1000e/e1000.h
+++ b/drivers/net/e1000e/e1000.h
@@ -153,6 +153,33 @@ struct e1000_info;
153/* Time to wait before putting the device into D3 if there's no link (in ms). */ 153/* Time to wait before putting the device into D3 if there's no link (in ms). */
154#define LINK_TIMEOUT 100 154#define LINK_TIMEOUT 100
155 155
156#define DEFAULT_RDTR 0
157#define DEFAULT_RADV 8
158#define BURST_RDTR 0x20
159#define BURST_RADV 0x20
160
161/*
162 * in the case of WTHRESH, it appears at least the 82571/2 hardware
163 * writes back 4 descriptors when WTHRESH=5, and 3 descriptors when
164 * WTHRESH=4, and since we want 64 bytes at a time written back, set
165 * it to 5
166 */
167#define E1000_TXDCTL_DMA_BURST_ENABLE \
168 (E1000_TXDCTL_GRAN | /* set descriptor granularity */ \
169 E1000_TXDCTL_COUNT_DESC | \
170 (5 << 16) | /* wthresh must be +1 more than desired */\
171 (1 << 8) | /* hthresh */ \
172 0x1f) /* pthresh */
173
174#define E1000_RXDCTL_DMA_BURST_ENABLE \
175 (0x01000000 | /* set descriptor granularity */ \
176 (4 << 16) | /* set writeback threshold */ \
177 (4 << 8) | /* set prefetch threshold */ \
178 0x20) /* set hthresh */
179
180#define E1000_TIDV_FPD (1 << 31)
181#define E1000_RDTR_FPD (1 << 31)
182
156enum e1000_boards { 183enum e1000_boards {
157 board_82571, 184 board_82571,
158 board_82572, 185 board_82572,
@@ -425,6 +452,7 @@ struct e1000_info {
425#define FLAG2_DISABLE_ASPM_L1 (1 << 3) 452#define FLAG2_DISABLE_ASPM_L1 (1 << 3)
426#define FLAG2_HAS_PHY_STATS (1 << 4) 453#define FLAG2_HAS_PHY_STATS (1 << 4)
427#define FLAG2_HAS_EEE (1 << 5) 454#define FLAG2_HAS_EEE (1 << 5)
455#define FLAG2_DMA_BURST (1 << 6)
428 456
429#define E1000_RX_DESC_PS(R, i) \ 457#define E1000_RX_DESC_PS(R, i) \
430 (&(((union e1000_rx_desc_packet_split *)((R).desc))[i])) 458 (&(((union e1000_rx_desc_packet_split *)((R).desc))[i]))
diff --git a/drivers/net/e1000e/es2lan.c b/drivers/net/e1000e/es2lan.c
index 45aebb4a6fe..24f8ac9cf70 100644
--- a/drivers/net/e1000e/es2lan.c
+++ b/drivers/net/e1000e/es2lan.c
@@ -1494,6 +1494,7 @@ struct e1000_info e1000_es2_info = {
1494 | FLAG_APME_CHECK_PORT_B 1494 | FLAG_APME_CHECK_PORT_B
1495 | FLAG_DISABLE_FC_PAUSE_TIME /* errata */ 1495 | FLAG_DISABLE_FC_PAUSE_TIME /* errata */
1496 | FLAG_TIPG_MEDIUM_FOR_80003ESLAN, 1496 | FLAG_TIPG_MEDIUM_FOR_80003ESLAN,
1497 .flags2 = FLAG2_DMA_BURST,
1497 .pba = 38, 1498 .pba = 38,
1498 .max_hw_frame_size = DEFAULT_JUMBO, 1499 .max_hw_frame_size = DEFAULT_JUMBO,
1499 .get_variants = e1000_get_variants_80003es2lan, 1500 .get_variants = e1000_get_variants_80003es2lan,
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c
index c69563c3ce9..1aa4228e860 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)
2650 /* Tx irq moderation */ 2650 /* Tx irq moderation */
2651 ew32(TADV, adapter->tx_abs_int_delay); 2651 ew32(TADV, adapter->tx_abs_int_delay);
2652 2652
2653 if (adapter->flags2 & FLAG2_DMA_BURST) {
2654 u32 txdctl = er32(TXDCTL(0));
2655 txdctl &= ~(E1000_TXDCTL_PTHRESH | E1000_TXDCTL_HTHRESH |
2656 E1000_TXDCTL_WTHRESH);
2657 /*
2658 * set up some performance related parameters to encourage the
2659 * hardware to use the bus more efficiently in bursts, depends
2660 * on the tx_int_delay to be enabled,
2661 * wthresh = 5 ==> burst write a cacheline (64 bytes) at a time
2662 * hthresh = 1 ==> prefetch when one or more available
2663 * pthresh = 0x1f ==> prefetch if internal cache 31 or less
2664 * BEWARE: this seems to work but should be considered first if
2665 * there are tx hangs or other tx related bugs
2666 */
2667 txdctl |= E1000_TXDCTL_DMA_BURST_ENABLE;
2668 ew32(TXDCTL(0), txdctl);
2669 /* erratum work around: set txdctl the same for both queues */
2670 ew32(TXDCTL(1), txdctl);
2671 }
2672
2653 /* Program the Transmit Control Register */ 2673 /* Program the Transmit Control Register */
2654 tctl = er32(TCTL); 2674 tctl = er32(TCTL);
2655 tctl &= ~E1000_TCTL_CT; 2675 tctl &= ~E1000_TCTL_CT;
@@ -2872,6 +2892,29 @@ static void e1000_configure_rx(struct e1000_adapter *adapter)
2872 e1e_flush(); 2892 e1e_flush();
2873 msleep(10); 2893 msleep(10);
2874 2894
2895 if (adapter->flags2 & FLAG2_DMA_BURST) {
2896 /*
2897 * set the writeback threshold (only takes effect if the RDTR
2898 * is set). set GRAN=1 and write back up to 0x4 worth, and
2899 * enable prefetching of 0x20 rx descriptors
2900 * granularity = 01
2901 * wthresh = 04,
2902 * hthresh = 04,
2903 * pthresh = 0x20
2904 */
2905 ew32(RXDCTL(0), E1000_RXDCTL_DMA_BURST_ENABLE);
2906 ew32(RXDCTL(1), E1000_RXDCTL_DMA_BURST_ENABLE);
2907
2908 /*
2909 * override the delay timers for enabling bursting, only if
2910 * the value was not set by the user via module options
2911 */
2912 if (adapter->rx_int_delay == DEFAULT_RDTR)
2913 adapter->rx_int_delay = BURST_RDTR;
2914 if (adapter->rx_abs_int_delay == DEFAULT_RADV)
2915 adapter->rx_abs_int_delay = BURST_RADV;
2916 }
2917
2875 /* set the Receive Delay Timer Register */ 2918 /* set the Receive Delay Timer Register */
2876 ew32(RDTR, adapter->rx_int_delay); 2919 ew32(RDTR, adapter->rx_int_delay);
2877 2920
@@ -4235,6 +4278,16 @@ link_up:
4235 /* Force detection of hung controller every watchdog period */ 4278 /* Force detection of hung controller every watchdog period */
4236 adapter->detect_tx_hung = 1; 4279 adapter->detect_tx_hung = 1;
4237 4280
4281 /* flush partial descriptors to memory before detecting tx hang */
4282 if (adapter->flags2 & FLAG2_DMA_BURST) {
4283 ew32(TIDV, adapter->tx_int_delay | E1000_TIDV_FPD);
4284 ew32(RDTR, adapter->rx_int_delay | E1000_RDTR_FPD);
4285 /*
4286 * no need to flush the writes because the timeout code does
4287 * an er32 first thing
4288 */
4289 }
4290
4238 /* 4291 /*
4239 * With 82571 controllers, LAA may be overwritten due to controller 4292 * With 82571 controllers, LAA may be overwritten due to controller
4240 * reset from the other port. Set the appropriate LAA in RAR[0] 4293 * reset from the other port. Set the appropriate LAA in RAR[0]
diff --git a/drivers/net/e1000e/param.c b/drivers/net/e1000e/param.c
index 34aeec13bb1..3d36911f77f 100644
--- a/drivers/net/e1000e/param.c
+++ b/drivers/net/e1000e/param.c
@@ -91,7 +91,6 @@ E1000_PARAM(TxAbsIntDelay, "Transmit Absolute Interrupt Delay");
91 * Valid Range: 0-65535 91 * Valid Range: 0-65535
92 */ 92 */
93E1000_PARAM(RxIntDelay, "Receive Interrupt Delay"); 93E1000_PARAM(RxIntDelay, "Receive Interrupt Delay");
94#define DEFAULT_RDTR 0
95#define MAX_RXDELAY 0xFFFF 94#define MAX_RXDELAY 0xFFFF
96#define MIN_RXDELAY 0 95#define MIN_RXDELAY 0
97 96
@@ -101,7 +100,6 @@ E1000_PARAM(RxIntDelay, "Receive Interrupt Delay");
101 * Valid Range: 0-65535 100 * Valid Range: 0-65535
102 */ 101 */
103E1000_PARAM(RxAbsIntDelay, "Receive Absolute Interrupt Delay"); 102E1000_PARAM(RxAbsIntDelay, "Receive Absolute Interrupt Delay");
104#define DEFAULT_RADV 8
105#define MAX_RXABSDELAY 0xFFFF 103#define MAX_RXABSDELAY 0xFFFF
106#define MIN_RXABSDELAY 0 104#define MIN_RXABSDELAY 0
107 105