aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCarolyn Wyborny <carolyn.wyborny@intel.com>2011-03-11 23:43:54 -0500
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>2011-03-12 07:09:55 -0500
commit831ec0b4226cec7ea34f5c4c9810e78aeb2069bf (patch)
tree3576b08f16304217c5353b5a6aa2fa5ba5350187
parent4322e561a93ec7ee034b603a6c610e7be90d4e8a (diff)
igb: Add DMA Coalescing feature to driver
This patch add DMA Coalescing which is a power-saving feature that coalesces DMA writes in order to stay in a low-power state as much as possible. Feature is disabled by default. Signed-off-by: Carolyn Wyborny <carolyn.wyborny@intel.com> Tested-by: Jeff Pieper <jeffrey.e.pieper@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
-rw-r--r--drivers/net/igb/e1000_defines.h29
-rw-r--r--drivers/net/igb/e1000_regs.h9
-rw-r--r--drivers/net/igb/igb.h6
-rw-r--r--drivers/net/igb/igb_ethtool.c6
-rw-r--r--drivers/net/igb/igb_main.c57
5 files changed, 106 insertions, 1 deletions
diff --git a/drivers/net/igb/e1000_defines.h b/drivers/net/igb/e1000_defines.h
index 97969ad8afef..9bb192825893 100644
--- a/drivers/net/igb/e1000_defines.h
+++ b/drivers/net/igb/e1000_defines.h
@@ -287,7 +287,34 @@
287#define E1000_TCTL_COLD 0x003ff000 /* collision distance */ 287#define E1000_TCTL_COLD 0x003ff000 /* collision distance */
288#define E1000_TCTL_RTLC 0x01000000 /* Re-transmit on late collision */ 288#define E1000_TCTL_RTLC 0x01000000 /* Re-transmit on late collision */
289 289
290/* Transmit Arbitration Count */ 290/* DMA Coalescing register fields */
291#define E1000_DMACR_DMACWT_MASK 0x00003FFF /* DMA Coalescing
292 * Watchdog Timer */
293#define E1000_DMACR_DMACTHR_MASK 0x00FF0000 /* DMA Coalescing Receive
294 * Threshold */
295#define E1000_DMACR_DMACTHR_SHIFT 16
296#define E1000_DMACR_DMAC_LX_MASK 0x30000000 /* Lx when no PCIe
297 * transactions */
298#define E1000_DMACR_DMAC_LX_SHIFT 28
299#define E1000_DMACR_DMAC_EN 0x80000000 /* Enable DMA Coalescing */
300
301#define E1000_DMCTXTH_DMCTTHR_MASK 0x00000FFF /* DMA Coalescing Transmit
302 * Threshold */
303
304#define E1000_DMCTLX_TTLX_MASK 0x00000FFF /* Time to LX request */
305
306#define E1000_DMCRTRH_UTRESH_MASK 0x0007FFFF /* Receive Traffic Rate
307 * Threshold */
308#define E1000_DMCRTRH_LRPRCW 0x80000000 /* Rcv packet rate in
309 * current window */
310
311#define E1000_DMCCNT_CCOUNT_MASK 0x01FFFFFF /* DMA Coal Rcv Traffic
312 * Current Cnt */
313
314#define E1000_FCRTC_RTH_COAL_MASK 0x0003FFF0 /* Flow ctrl Rcv Threshold
315 * High val */
316#define E1000_FCRTC_RTH_COAL_SHIFT 4
317#define E1000_PCIEMISC_LX_DECISION 0x00000080 /* Lx power decision */
291 318
292/* SerDes Control */ 319/* SerDes Control */
293#define E1000_SCTL_DISABLE_SERDES_LOOPBACK 0x0400 320#define E1000_SCTL_DISABLE_SERDES_LOOPBACK 0x0400
diff --git a/drivers/net/igb/e1000_regs.h b/drivers/net/igb/e1000_regs.h
index b2f8e593da87..ad77ed510d7c 100644
--- a/drivers/net/igb/e1000_regs.h
+++ b/drivers/net/igb/e1000_regs.h
@@ -106,6 +106,15 @@
106 106
107#define E1000_RQDPC(_n) (0x0C030 + ((_n) * 0x40)) 107#define E1000_RQDPC(_n) (0x0C030 + ((_n) * 0x40))
108 108
109/* DMA Coalescing registers */
110#define E1000_DMACR 0x02508 /* Control Register */
111#define E1000_DMCTXTH 0x03550 /* Transmit Threshold */
112#define E1000_DMCTLX 0x02514 /* Time to Lx Request */
113#define E1000_DMCRTRH 0x05DD0 /* Receive Packet Rate Threshold */
114#define E1000_DMCCNT 0x05DD4 /* Current Rx Count */
115#define E1000_FCRTC 0x02170 /* Flow Control Rx high watermark */
116#define E1000_PCIEMISC 0x05BB8 /* PCIE misc config register */
117
109/* TX Rate Limit Registers */ 118/* TX Rate Limit Registers */
110#define E1000_RTTDQSEL 0x3604 /* Tx Desc Plane Queue Select - WO */ 119#define E1000_RTTDQSEL 0x3604 /* Tx Desc Plane Queue Select - WO */
111#define E1000_RTTBCNRC 0x36B0 /* Tx BCN Rate-Scheduler Config - WO */ 120#define E1000_RTTBCNRC 0x36B0 /* Tx BCN Rate-Scheduler Config - WO */
diff --git a/drivers/net/igb/igb.h b/drivers/net/igb/igb.h
index bbc5ebfe254a..1c687e298d5e 100644
--- a/drivers/net/igb/igb.h
+++ b/drivers/net/igb/igb.h
@@ -333,6 +333,12 @@ struct igb_adapter {
333#define IGB_FLAG_DCA_ENABLED (1 << 1) 333#define IGB_FLAG_DCA_ENABLED (1 << 1)
334#define IGB_FLAG_QUAD_PORT_A (1 << 2) 334#define IGB_FLAG_QUAD_PORT_A (1 << 2)
335#define IGB_FLAG_QUEUE_PAIRS (1 << 3) 335#define IGB_FLAG_QUEUE_PAIRS (1 << 3)
336#define IGB_FLAG_DMAC (1 << 4)
337
338/* DMA Coalescing defines */
339#define IGB_MIN_TXPBSIZE 20408
340#define IGB_TX_BUF_4096 4096
341#define IGB_DMCTLX_DCFLUSH_DIS 0x80000000 /* Disable DMA Coal Flush */
336 342
337#define IGB_82576_TSYNC_SHIFT 19 343#define IGB_82576_TSYNC_SHIFT 19
338#define IGB_82580_TSYNC_SHIFT 24 344#define IGB_82580_TSYNC_SHIFT 24
diff --git a/drivers/net/igb/igb_ethtool.c b/drivers/net/igb/igb_ethtool.c
index df15a915bbea..d976733bbcc2 100644
--- a/drivers/net/igb/igb_ethtool.c
+++ b/drivers/net/igb/igb_ethtool.c
@@ -2009,6 +2009,12 @@ static int igb_set_coalesce(struct net_device *netdev,
2009 if ((adapter->flags & IGB_FLAG_QUEUE_PAIRS) && ec->tx_coalesce_usecs) 2009 if ((adapter->flags & IGB_FLAG_QUEUE_PAIRS) && ec->tx_coalesce_usecs)
2010 return -EINVAL; 2010 return -EINVAL;
2011 2011
2012 /* If ITR is disabled, disable DMAC */
2013 if (ec->rx_coalesce_usecs == 0) {
2014 if (adapter->flags & IGB_FLAG_DMAC)
2015 adapter->flags &= ~IGB_FLAG_DMAC;
2016 }
2017
2012 /* convert to rate of irq's per second */ 2018 /* convert to rate of irq's per second */
2013 if (ec->rx_coalesce_usecs && ec->rx_coalesce_usecs <= 3) 2019 if (ec->rx_coalesce_usecs && ec->rx_coalesce_usecs <= 3)
2014 adapter->rx_itr_setting = ec->rx_coalesce_usecs; 2020 adapter->rx_itr_setting = ec->rx_coalesce_usecs;
diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c
index 8c6af11d93a6..49476f773825 100644
--- a/drivers/net/igb/igb_main.c
+++ b/drivers/net/igb/igb_main.c
@@ -1674,7 +1674,58 @@ void igb_reset(struct igb_adapter *adapter)
1674 1674
1675 if (hw->mac.ops.init_hw(hw)) 1675 if (hw->mac.ops.init_hw(hw))
1676 dev_err(&pdev->dev, "Hardware Error\n"); 1676 dev_err(&pdev->dev, "Hardware Error\n");
1677 if (hw->mac.type > e1000_82580) {
1678 if (adapter->flags & IGB_FLAG_DMAC) {
1679 u32 reg;
1677 1680
1681 /*
1682 * DMA Coalescing high water mark needs to be higher
1683 * than * the * Rx threshold. The Rx threshold is
1684 * currently * pba - 6, so we * should use a high water
1685 * mark of pba * - 4. */
1686 hwm = (pba - 4) << 10;
1687
1688 reg = (((pba-6) << E1000_DMACR_DMACTHR_SHIFT)
1689 & E1000_DMACR_DMACTHR_MASK);
1690
1691 /* transition to L0x or L1 if available..*/
1692 reg |= (E1000_DMACR_DMAC_EN | E1000_DMACR_DMAC_LX_MASK);
1693
1694 /* watchdog timer= +-1000 usec in 32usec intervals */
1695 reg |= (1000 >> 5);
1696 wr32(E1000_DMACR, reg);
1697
1698 /* no lower threshold to disable coalescing(smart fifb)
1699 * -UTRESH=0*/
1700 wr32(E1000_DMCRTRH, 0);
1701
1702 /* set hwm to PBA - 2 * max frame size */
1703 wr32(E1000_FCRTC, hwm);
1704
1705 /*
1706 * This sets the time to wait before requesting tran-
1707 * sition to * low power state to number of usecs needed
1708 * to receive 1 512 * byte frame at gigabit line rate
1709 */
1710 reg = rd32(E1000_DMCTLX);
1711 reg |= IGB_DMCTLX_DCFLUSH_DIS;
1712
1713 /* Delay 255 usec before entering Lx state. */
1714 reg |= 0xFF;
1715 wr32(E1000_DMCTLX, reg);
1716
1717 /* free space in Tx packet buffer to wake from DMAC */
1718 wr32(E1000_DMCTXTH,
1719 (IGB_MIN_TXPBSIZE -
1720 (IGB_TX_BUF_4096 + adapter->max_frame_size))
1721 >> 6);
1722
1723 /* make low power state decision controlled by DMAC */
1724 reg = rd32(E1000_PCIEMISC);
1725 reg |= E1000_PCIEMISC_LX_DECISION;
1726 wr32(E1000_PCIEMISC, reg);
1727 } /* end if IGB_FLAG_DMAC set */
1728 }
1678 if (hw->mac.type == e1000_82580) { 1729 if (hw->mac.type == e1000_82580) {
1679 u32 reg = rd32(E1000_PCIEMISC); 1730 u32 reg = rd32(E1000_PCIEMISC);
1680 wr32(E1000_PCIEMISC, 1731 wr32(E1000_PCIEMISC,
@@ -2157,6 +2208,9 @@ static void __devinit igb_probe_vfs(struct igb_adapter * adapter)
2157 random_ether_addr(mac_addr); 2208 random_ether_addr(mac_addr);
2158 igb_set_vf_mac(adapter, i, mac_addr); 2209 igb_set_vf_mac(adapter, i, mac_addr);
2159 } 2210 }
2211 /* DMA Coalescing is not supported in IOV mode. */
2212 if (adapter->flags & IGB_FLAG_DMAC)
2213 adapter->flags &= ~IGB_FLAG_DMAC;
2160 } 2214 }
2161#endif /* CONFIG_PCI_IOV */ 2215#endif /* CONFIG_PCI_IOV */
2162} 2216}
@@ -2331,6 +2385,9 @@ static int __devinit igb_sw_init(struct igb_adapter *adapter)
2331 /* Explicitly disable IRQ since the NIC can be in any state. */ 2385 /* Explicitly disable IRQ since the NIC can be in any state. */
2332 igb_irq_disable(adapter); 2386 igb_irq_disable(adapter);
2333 2387
2388 if (hw->mac.type == e1000_i350)
2389 adapter->flags &= ~IGB_FLAG_DMAC;
2390
2334 set_bit(__IGB_DOWN, &adapter->state); 2391 set_bit(__IGB_DOWN, &adapter->state);
2335 return 0; 2392 return 0;
2336} 2393}