aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ixgbe
diff options
context:
space:
mode:
authorJohn Fastabend <john.r.fastabend@intel.com>2010-11-16 22:26:44 -0500
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>2010-11-16 22:26:44 -0500
commit16b61beb39f2446460f93c08d4d263dc24f22dd8 (patch)
tree3901c6f9d786c934f971cffb65dc4fb8577044c8 /drivers/net/ixgbe
parent66c87bd50ddae681ebedfda0d75e6e73ecd29ce7 (diff)
ixgbe: DCB set PFC high and low water marks per data sheet specs
Currently the high and low water marks for PFC are being set conservatively for jumbo frames. This means the RX buffers are being underutilized in the default 1500 MTU. This patch fixes this so that the water marks are set as described in the data sheet considering the MTU size. The equation used is, RTT * 1.44 + MTU * 1.44 + MTU Where RTT is the round trip time and MTU is the max frame size in KB. To avoid floating point arithmetic FC_HIGH_WATER is defined ((((RTT + MTU) * 144) + 99) / 100) + MTU This changes how the hardware field fc.low_water and fc.high_water are used. With this change they are no longer storing the actual low water and high water markers but are storing the required head room in the buffer. This simplifies the logic and we do not need to account for the size of the buffer when setting the thresholds. Testing with iperf and 16 threads showed a slight uptick in throughput over a single traffic class .1-.2Gbps and a reduction in pause frames. Without the patch a 30 second run would show ~10-15 pause frames being transmitted with the patch ~2-5 are seen. Test were run back to back with 82599. Note RXPBSIZE is in KB and low and high water marks fields are also in KB. However the FCRT* registers are 32B granularity and right shifted 5 into the register, (((rx_pbsize - water_mark) * 1024) / 32) << 5 is the most explicit conversion here we simplify (rx_pbsize - water_mark) * 32 << 5 = (rx_pbsize - water_mark) << 10 This patch updates the PFC thresholds and legacy FC thresholds. Signed-off-by: John Fastabend <john.r.fastabend@intel.com> Tested-by: Ross Brattain <ross.b.brattain@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Diffstat (limited to 'drivers/net/ixgbe')
-rw-r--r--drivers/net/ixgbe/ixgbe.h2
-rw-r--r--drivers/net/ixgbe/ixgbe_82598.c21
-rw-r--r--drivers/net/ixgbe/ixgbe_common.c43
-rw-r--r--drivers/net/ixgbe/ixgbe_dcb_82598.c12
-rw-r--r--drivers/net/ixgbe/ixgbe_dcb_82599.c12
-rw-r--r--drivers/net/ixgbe/ixgbe_main.c9
-rw-r--r--drivers/net/ixgbe/ixgbe_type.h8
7 files changed, 48 insertions, 59 deletions
diff --git a/drivers/net/ixgbe/ixgbe.h b/drivers/net/ixgbe/ixgbe.h
index 018e143612b2..4f98486d8c2c 100644
--- a/drivers/net/ixgbe/ixgbe.h
+++ b/drivers/net/ixgbe/ixgbe.h
@@ -61,10 +61,8 @@
61#define IXGBE_MIN_RXD 64 61#define IXGBE_MIN_RXD 64
62 62
63/* flow control */ 63/* flow control */
64#define IXGBE_DEFAULT_FCRTL 0x10000
65#define IXGBE_MIN_FCRTL 0x40 64#define IXGBE_MIN_FCRTL 0x40
66#define IXGBE_MAX_FCRTL 0x7FF80 65#define IXGBE_MAX_FCRTL 0x7FF80
67#define IXGBE_DEFAULT_FCRTH 0x20000
68#define IXGBE_MIN_FCRTH 0x600 66#define IXGBE_MIN_FCRTH 0x600
69#define IXGBE_MAX_FCRTH 0x7FFF0 67#define IXGBE_MAX_FCRTH 0x7FFF0
70#define IXGBE_DEFAULT_FCPAUSE 0xFFFF 68#define IXGBE_DEFAULT_FCPAUSE 0xFFFF
diff --git a/drivers/net/ixgbe/ixgbe_82598.c b/drivers/net/ixgbe/ixgbe_82598.c
index 9c02d6014cc4..25b20f93190a 100644
--- a/drivers/net/ixgbe/ixgbe_82598.c
+++ b/drivers/net/ixgbe/ixgbe_82598.c
@@ -357,6 +357,7 @@ static s32 ixgbe_fc_enable_82598(struct ixgbe_hw *hw, s32 packetbuf_num)
357 u32 fctrl_reg; 357 u32 fctrl_reg;
358 u32 rmcs_reg; 358 u32 rmcs_reg;
359 u32 reg; 359 u32 reg;
360 u32 rx_pba_size;
360 u32 link_speed = 0; 361 u32 link_speed = 0;
361 bool link_up; 362 bool link_up;
362 363
@@ -459,16 +460,18 @@ static s32 ixgbe_fc_enable_82598(struct ixgbe_hw *hw, s32 packetbuf_num)
459 460
460 /* Set up and enable Rx high/low water mark thresholds, enable XON. */ 461 /* Set up and enable Rx high/low water mark thresholds, enable XON. */
461 if (hw->fc.current_mode & ixgbe_fc_tx_pause) { 462 if (hw->fc.current_mode & ixgbe_fc_tx_pause) {
462 if (hw->fc.send_xon) { 463 rx_pba_size = IXGBE_READ_REG(hw, IXGBE_RXPBSIZE(packetbuf_num));
463 IXGBE_WRITE_REG(hw, IXGBE_FCRTL(packetbuf_num), 464 rx_pba_size >>= IXGBE_RXPBSIZE_SHIFT;
464 (hw->fc.low_water | IXGBE_FCRTL_XONE)); 465
465 } else { 466 reg = (rx_pba_size - hw->fc.low_water) << 6;
466 IXGBE_WRITE_REG(hw, IXGBE_FCRTL(packetbuf_num), 467 if (hw->fc.send_xon)
467 hw->fc.low_water); 468 reg |= IXGBE_FCRTL_XONE;
468 } 469 IXGBE_WRITE_REG(hw, IXGBE_FCRTL(packetbuf_num), reg);
470
471 reg = (rx_pba_size - hw->fc.high_water) << 10;
472 reg |= IXGBE_FCRTH_FCEN;
469 473
470 IXGBE_WRITE_REG(hw, IXGBE_FCRTH(packetbuf_num), 474 IXGBE_WRITE_REG(hw, IXGBE_FCRTH(packetbuf_num), reg);
471 (hw->fc.high_water | IXGBE_FCRTH_FCEN));
472 } 475 }
473 476
474 /* Configure pause time (2 TCs per register) */ 477 /* Configure pause time (2 TCs per register) */
diff --git a/drivers/net/ixgbe/ixgbe_common.c b/drivers/net/ixgbe/ixgbe_common.c
index e3eca1316389..62aa2be199f1 100644
--- a/drivers/net/ixgbe/ixgbe_common.c
+++ b/drivers/net/ixgbe/ixgbe_common.c
@@ -1595,6 +1595,7 @@ s32 ixgbe_fc_enable_generic(struct ixgbe_hw *hw, s32 packetbuf_num)
1595 u32 mflcn_reg, fccfg_reg; 1595 u32 mflcn_reg, fccfg_reg;
1596 u32 reg; 1596 u32 reg;
1597 u32 rx_pba_size; 1597 u32 rx_pba_size;
1598 u32 fcrtl, fcrth;
1598 1599
1599#ifdef CONFIG_DCB 1600#ifdef CONFIG_DCB
1600 if (hw->fc.requested_mode == ixgbe_fc_pfc) 1601 if (hw->fc.requested_mode == ixgbe_fc_pfc)
@@ -1671,41 +1672,21 @@ s32 ixgbe_fc_enable_generic(struct ixgbe_hw *hw, s32 packetbuf_num)
1671 IXGBE_WRITE_REG(hw, IXGBE_MFLCN, mflcn_reg); 1672 IXGBE_WRITE_REG(hw, IXGBE_MFLCN, mflcn_reg);
1672 IXGBE_WRITE_REG(hw, IXGBE_FCCFG, fccfg_reg); 1673 IXGBE_WRITE_REG(hw, IXGBE_FCCFG, fccfg_reg);
1673 1674
1674 reg = IXGBE_READ_REG(hw, IXGBE_MTQC); 1675 rx_pba_size = IXGBE_READ_REG(hw, IXGBE_RXPBSIZE(packetbuf_num));
1675 /* Thresholds are different for link flow control when in DCB mode */ 1676 rx_pba_size >>= IXGBE_RXPBSIZE_SHIFT;
1676 if (reg & IXGBE_MTQC_RT_ENA) {
1677 rx_pba_size = IXGBE_READ_REG(hw, IXGBE_RXPBSIZE(packetbuf_num));
1678 1677
1679 /* Always disable XON for LFC when in DCB mode */ 1678 fcrth = (rx_pba_size - hw->fc.high_water) << 10;
1680 reg = (rx_pba_size >> 5) & 0xFFE0; 1679 fcrtl = (rx_pba_size - hw->fc.low_water) << 10;
1681 IXGBE_WRITE_REG(hw, IXGBE_FCRTL_82599(packetbuf_num), reg);
1682 1680
1683 reg = (rx_pba_size >> 2) & 0xFFE0; 1681 if (hw->fc.current_mode & ixgbe_fc_tx_pause) {
1684 if (hw->fc.current_mode & ixgbe_fc_tx_pause) 1682 fcrth |= IXGBE_FCRTH_FCEN;
1685 reg |= IXGBE_FCRTH_FCEN; 1683 if (hw->fc.send_xon)
1686 IXGBE_WRITE_REG(hw, IXGBE_FCRTH_82599(packetbuf_num), reg); 1684 fcrtl |= IXGBE_FCRTL_XONE;
1687 } else {
1688 /*
1689 * Set up and enable Rx high/low water mark thresholds,
1690 * enable XON.
1691 */
1692 if (hw->fc.current_mode & ixgbe_fc_tx_pause) {
1693 if (hw->fc.send_xon) {
1694 IXGBE_WRITE_REG(hw,
1695 IXGBE_FCRTL_82599(packetbuf_num),
1696 (hw->fc.low_water |
1697 IXGBE_FCRTL_XONE));
1698 } else {
1699 IXGBE_WRITE_REG(hw,
1700 IXGBE_FCRTL_82599(packetbuf_num),
1701 hw->fc.low_water);
1702 }
1703
1704 IXGBE_WRITE_REG(hw, IXGBE_FCRTH_82599(packetbuf_num),
1705 (hw->fc.high_water | IXGBE_FCRTH_FCEN));
1706 }
1707 } 1685 }
1708 1686
1687 IXGBE_WRITE_REG(hw, IXGBE_FCRTH_82599(packetbuf_num), fcrth);
1688 IXGBE_WRITE_REG(hw, IXGBE_FCRTL_82599(packetbuf_num), fcrtl);
1689
1709 /* Configure pause time (2 TCs per register) */ 1690 /* Configure pause time (2 TCs per register) */
1710 reg = IXGBE_READ_REG(hw, IXGBE_FCTTV(packetbuf_num / 2)); 1691 reg = IXGBE_READ_REG(hw, IXGBE_FCTTV(packetbuf_num / 2));
1711 if ((packetbuf_num & 1) == 0) 1692 if ((packetbuf_num & 1) == 0)
diff --git a/drivers/net/ixgbe/ixgbe_dcb_82598.c b/drivers/net/ixgbe/ixgbe_dcb_82598.c
index 50288bcadc59..9a5e89c12e05 100644
--- a/drivers/net/ixgbe/ixgbe_dcb_82598.c
+++ b/drivers/net/ixgbe/ixgbe_dcb_82598.c
@@ -256,21 +256,17 @@ s32 ixgbe_dcb_config_pfc_82598(struct ixgbe_hw *hw,
256 * for each traffic class. 256 * for each traffic class.
257 */ 257 */
258 for (i = 0; i < MAX_TRAFFIC_CLASS; i++) { 258 for (i = 0; i < MAX_TRAFFIC_CLASS; i++) {
259 if (dcb_config->rx_pba_cfg == pba_equal) { 259 rx_pba_size = IXGBE_READ_REG(hw, IXGBE_RXPBSIZE(i));
260 rx_pba_size = IXGBE_RXPBSIZE_64KB; 260 rx_pba_size >>= IXGBE_RXPBSIZE_SHIFT;
261 } else { 261 reg = (rx_pba_size - hw->fc.low_water) << 10;
262 rx_pba_size = (i < 4) ? IXGBE_RXPBSIZE_80KB
263 : IXGBE_RXPBSIZE_48KB;
264 }
265 262
266 reg = ((rx_pba_size >> 5) & 0xFFF0);
267 if (dcb_config->tc_config[i].dcb_pfc == pfc_enabled_tx || 263 if (dcb_config->tc_config[i].dcb_pfc == pfc_enabled_tx ||
268 dcb_config->tc_config[i].dcb_pfc == pfc_enabled_full) 264 dcb_config->tc_config[i].dcb_pfc == pfc_enabled_full)
269 reg |= IXGBE_FCRTL_XONE; 265 reg |= IXGBE_FCRTL_XONE;
270 266
271 IXGBE_WRITE_REG(hw, IXGBE_FCRTL(i), reg); 267 IXGBE_WRITE_REG(hw, IXGBE_FCRTL(i), reg);
272 268
273 reg = ((rx_pba_size >> 2) & 0xFFF0); 269 reg = (rx_pba_size - hw->fc.high_water) << 10;
274 if (dcb_config->tc_config[i].dcb_pfc == pfc_enabled_tx || 270 if (dcb_config->tc_config[i].dcb_pfc == pfc_enabled_tx ||
275 dcb_config->tc_config[i].dcb_pfc == pfc_enabled_full) 271 dcb_config->tc_config[i].dcb_pfc == pfc_enabled_full)
276 reg |= IXGBE_FCRTH_FCEN; 272 reg |= IXGBE_FCRTH_FCEN;
diff --git a/drivers/net/ixgbe/ixgbe_dcb_82599.c b/drivers/net/ixgbe/ixgbe_dcb_82599.c
index 05f224715073..374e1f74d0f5 100644
--- a/drivers/net/ixgbe/ixgbe_dcb_82599.c
+++ b/drivers/net/ixgbe/ixgbe_dcb_82599.c
@@ -251,19 +251,17 @@ s32 ixgbe_dcb_config_pfc_82599(struct ixgbe_hw *hw,
251 251
252 /* Configure PFC Tx thresholds per TC */ 252 /* Configure PFC Tx thresholds per TC */
253 for (i = 0; i < MAX_TRAFFIC_CLASS; i++) { 253 for (i = 0; i < MAX_TRAFFIC_CLASS; i++) {
254 if (dcb_config->rx_pba_cfg == pba_equal) 254 rx_pba_size = IXGBE_READ_REG(hw, IXGBE_RXPBSIZE(i));
255 rx_pba_size = IXGBE_RXPBSIZE_64KB; 255 rx_pba_size >>= IXGBE_RXPBSIZE_SHIFT;
256 else 256
257 rx_pba_size = (i < 4) ? IXGBE_RXPBSIZE_80KB 257 reg = (rx_pba_size - hw->fc.low_water) << 10;
258 : IXGBE_RXPBSIZE_48KB;
259 258
260 reg = ((rx_pba_size >> 5) & 0xFFE0);
261 if (dcb_config->tc_config[i].dcb_pfc == pfc_enabled_full || 259 if (dcb_config->tc_config[i].dcb_pfc == pfc_enabled_full ||
262 dcb_config->tc_config[i].dcb_pfc == pfc_enabled_tx) 260 dcb_config->tc_config[i].dcb_pfc == pfc_enabled_tx)
263 reg |= IXGBE_FCRTL_XONE; 261 reg |= IXGBE_FCRTL_XONE;
264 IXGBE_WRITE_REG(hw, IXGBE_FCRTL_82599(i), reg); 262 IXGBE_WRITE_REG(hw, IXGBE_FCRTL_82599(i), reg);
265 263
266 reg = ((rx_pba_size >> 2) & 0xFFE0); 264 reg = (rx_pba_size - hw->fc.high_water) << 10;
267 if (dcb_config->tc_config[i].dcb_pfc == pfc_enabled_full || 265 if (dcb_config->tc_config[i].dcb_pfc == pfc_enabled_full ||
268 dcb_config->tc_config[i].dcb_pfc == pfc_enabled_tx) 266 dcb_config->tc_config[i].dcb_pfc == pfc_enabled_tx)
269 reg |= IXGBE_FCRTH_FCEN; 267 reg |= IXGBE_FCRTH_FCEN;
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c
index a137f9dbaacd..f374207e14b4 100644
--- a/drivers/net/ixgbe/ixgbe_main.c
+++ b/drivers/net/ixgbe/ixgbe_main.c
@@ -4854,6 +4854,7 @@ static int __devinit ixgbe_sw_init(struct ixgbe_adapter *adapter)
4854 int j; 4854 int j;
4855 struct tc_configuration *tc; 4855 struct tc_configuration *tc;
4856#endif 4856#endif
4857 int max_frame = dev->mtu + ETH_HLEN + ETH_FCS_LEN;
4857 4858
4858 /* PCI config space info */ 4859 /* PCI config space info */
4859 4860
@@ -4930,8 +4931,8 @@ static int __devinit ixgbe_sw_init(struct ixgbe_adapter *adapter)
4930#ifdef CONFIG_DCB 4931#ifdef CONFIG_DCB
4931 adapter->last_lfc_mode = hw->fc.current_mode; 4932 adapter->last_lfc_mode = hw->fc.current_mode;
4932#endif 4933#endif
4933 hw->fc.high_water = IXGBE_DEFAULT_FCRTH; 4934 hw->fc.high_water = FC_HIGH_WATER(max_frame);
4934 hw->fc.low_water = IXGBE_DEFAULT_FCRTL; 4935 hw->fc.low_water = FC_LOW_WATER(max_frame);
4935 hw->fc.pause_time = IXGBE_DEFAULT_FCPAUSE; 4936 hw->fc.pause_time = IXGBE_DEFAULT_FCPAUSE;
4936 hw->fc.send_xon = true; 4937 hw->fc.send_xon = true;
4937 hw->fc.disable_fc_autoneg = false; 4938 hw->fc.disable_fc_autoneg = false;
@@ -5193,6 +5194,7 @@ static void ixgbe_free_all_rx_resources(struct ixgbe_adapter *adapter)
5193static int ixgbe_change_mtu(struct net_device *netdev, int new_mtu) 5194static int ixgbe_change_mtu(struct net_device *netdev, int new_mtu)
5194{ 5195{
5195 struct ixgbe_adapter *adapter = netdev_priv(netdev); 5196 struct ixgbe_adapter *adapter = netdev_priv(netdev);
5197 struct ixgbe_hw *hw = &adapter->hw;
5196 int max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN; 5198 int max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN;
5197 5199
5198 /* MTU < 68 is an error and causes problems on some kernels */ 5200 /* MTU < 68 is an error and causes problems on some kernels */
@@ -5203,6 +5205,9 @@ static int ixgbe_change_mtu(struct net_device *netdev, int new_mtu)
5203 /* must set new MTU before calling down or up */ 5205 /* must set new MTU before calling down or up */
5204 netdev->mtu = new_mtu; 5206 netdev->mtu = new_mtu;
5205 5207
5208 hw->fc.high_water = FC_HIGH_WATER(max_frame);
5209 hw->fc.low_water = FC_LOW_WATER(max_frame);
5210
5206 if (netif_running(netdev)) 5211 if (netif_running(netdev))
5207 ixgbe_reinit_locked(adapter); 5212 ixgbe_reinit_locked(adapter);
5208 5213
diff --git a/drivers/net/ixgbe/ixgbe_type.h b/drivers/net/ixgbe/ixgbe_type.h
index d3cc6ce7c973..96dea7731e68 100644
--- a/drivers/net/ixgbe/ixgbe_type.h
+++ b/drivers/net/ixgbe/ixgbe_type.h
@@ -2113,6 +2113,14 @@ typedef u32 ixgbe_physical_layer;
2113#define IXGBE_PHYSICAL_LAYER_10GBASE_XAUI 0x1000 2113#define IXGBE_PHYSICAL_LAYER_10GBASE_XAUI 0x1000
2114#define IXGBE_PHYSICAL_LAYER_SFP_ACTIVE_DA 0x2000 2114#define IXGBE_PHYSICAL_LAYER_SFP_ACTIVE_DA 0x2000
2115 2115
2116/* Flow Control Macros */
2117#define PAUSE_RTT 8
2118#define PAUSE_MTU(MTU) ((MTU + 1024 - 1) / 1024)
2119
2120#define FC_HIGH_WATER(MTU) ((((PAUSE_RTT + PAUSE_MTU(MTU)) * 144) + 99) / 100 +\
2121 PAUSE_MTU(MTU))
2122#define FC_LOW_WATER(MTU) (2 * (2 * PAUSE_MTU(MTU) + PAUSE_RTT))
2123
2116/* Software ATR hash keys */ 2124/* Software ATR hash keys */
2117#define IXGBE_ATR_BUCKET_HASH_KEY 0xE214AD3D 2125#define IXGBE_ATR_BUCKET_HASH_KEY 0xE214AD3D
2118#define IXGBE_ATR_SIGNATURE_HASH_KEY 0x14364D17 2126#define IXGBE_ATR_SIGNATURE_HASH_KEY 0x14364D17