diff options
author | Carolyn Wyborny <carolyn.wyborny@intel.com> | 2011-03-11 23:43:54 -0500 |
---|---|---|
committer | Jeff Kirsher <jeffrey.t.kirsher@intel.com> | 2011-03-12 07:09:55 -0500 |
commit | 831ec0b4226cec7ea34f5c4c9810e78aeb2069bf (patch) | |
tree | 3576b08f16304217c5353b5a6aa2fa5ba5350187 | |
parent | 4322e561a93ec7ee034b603a6c610e7be90d4e8a (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.h | 29 | ||||
-rw-r--r-- | drivers/net/igb/e1000_regs.h | 9 | ||||
-rw-r--r-- | drivers/net/igb/igb.h | 6 | ||||
-rw-r--r-- | drivers/net/igb/igb_ethtool.c | 6 | ||||
-rw-r--r-- | drivers/net/igb/igb_main.c | 57 |
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 | } |