Commit 38eb394e authored by Bruce Allan's avatar Bruce Allan Committed by David S. Miller

e1000e: partial revert of 3ec2a2b8 plus FC workraround for 82577/8

Commit 3ec2a2b8 broke Tx/Rx when using
jumbo frames on certain parts (i.e. only PAUSE frames could be exchanged
once the high water mark was reached preventing normal packet traffic).
This patch reverts the breakage and sets appropriate high and low water
marks of the Rx FIFO for 82577/82578 which require a workaround due to a
flow control issue in hardware.
Signed-off-by: default avatarBruce Allan <bruce.w.allan@intel.com>
Signed-off-by: default avatarJeff Kirsher <jeffrey.t.kirsher@intel.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 30b76832
...@@ -141,6 +141,8 @@ struct e1000_info; ...@@ -141,6 +141,8 @@ struct e1000_info;
#define HV_TNCRS_UPPER PHY_REG(778, 29) /* Transmit with no CRS */ #define HV_TNCRS_UPPER PHY_REG(778, 29) /* Transmit with no CRS */
#define HV_TNCRS_LOWER PHY_REG(778, 30) #define HV_TNCRS_LOWER PHY_REG(778, 30)
#define E1000_FCRTV_PCH 0x05F40 /* PCH Flow Control Refresh Timer Value */
/* BM PHY Copper Specific Status */ /* BM PHY Copper Specific Status */
#define BM_CS_STATUS 17 #define BM_CS_STATUS 17
#define BM_CS_STATUS_LINK_UP 0x0400 #define BM_CS_STATUS_LINK_UP 0x0400
......
...@@ -3558,6 +3558,7 @@ struct e1000_info e1000_pch_info = { ...@@ -3558,6 +3558,7 @@ struct e1000_info e1000_pch_info = {
| FLAG_HAS_AMT | FLAG_HAS_AMT
| FLAG_HAS_FLASH | FLAG_HAS_FLASH
| FLAG_HAS_JUMBO_FRAMES | FLAG_HAS_JUMBO_FRAMES
| FLAG_DISABLE_FC_PAUSE_TIME /* errata */
| FLAG_APME_IN_WUC, | FLAG_APME_IN_WUC,
.pba = 26, .pba = 26,
.max_hw_frame_size = 4096, .max_hw_frame_size = 4096,
......
...@@ -2769,25 +2769,38 @@ void e1000e_reset(struct e1000_adapter *adapter) ...@@ -2769,25 +2769,38 @@ void e1000e_reset(struct e1000_adapter *adapter)
/* /*
* flow control settings * flow control settings
* *
* The high water mark must be low enough to fit two full frame * The high water mark must be low enough to fit one full frame
* (or the size used for early receive) above it in the Rx FIFO. * (or the size used for early receive) above it in the Rx FIFO.
* Set it to the lower of: * Set it to the lower of:
* - 90% of the Rx FIFO size, and * - 90% of the Rx FIFO size, and
* - the full Rx FIFO size minus the early receive size (for parts * - the full Rx FIFO size minus the early receive size (for parts
* with ERT support assuming ERT set to E1000_ERT_2048), or * with ERT support assuming ERT set to E1000_ERT_2048), or
* - the full Rx FIFO size minus two full frames * - the full Rx FIFO size minus one full frame
*/ */
if (hw->mac.type == e1000_pchlan) {
/*
* Workaround PCH LOM adapter hangs with certain network
* loads. If hangs persist, try disabling Tx flow control.
*/
if (adapter->netdev->mtu > ETH_DATA_LEN) {
fc->high_water = 0x3500;
fc->low_water = 0x1500;
} else {
fc->high_water = 0x5000;
fc->low_water = 0x3000;
}
} else {
if ((adapter->flags & FLAG_HAS_ERT) && if ((adapter->flags & FLAG_HAS_ERT) &&
(adapter->netdev->mtu > ETH_DATA_LEN)) (adapter->netdev->mtu > ETH_DATA_LEN))
hwm = min(((pba << 10) * 9 / 10), hwm = min(((pba << 10) * 9 / 10),
((pba << 10) - (E1000_ERT_2048 << 3))); ((pba << 10) - (E1000_ERT_2048 << 3)));
else else
hwm = min(((pba << 10) * 9 / 10), hwm = min(((pba << 10) * 9 / 10),
((pba << 10) - (2 * adapter->max_frame_size))); ((pba << 10) - adapter->max_frame_size));
fc->high_water = hwm & E1000_FCRTH_RTH; /* 8-byte granularity */ fc->high_water = hwm & E1000_FCRTH_RTH; /* 8-byte granularity */
fc->low_water = (fc->high_water - (2 * adapter->max_frame_size)); fc->low_water = fc->high_water - 8;
fc->low_water &= E1000_FCRTL_RTL; /* 8-byte granularity */ }
if (adapter->flags & FLAG_DISABLE_FC_PAUSE_TIME) if (adapter->flags & FLAG_DISABLE_FC_PAUSE_TIME)
fc->pause_time = 0xFFFF; fc->pause_time = 0xFFFF;
...@@ -2813,6 +2826,10 @@ void e1000e_reset(struct e1000_adapter *adapter) ...@@ -2813,6 +2826,10 @@ void e1000e_reset(struct e1000_adapter *adapter)
if (mac->ops.init_hw(hw)) if (mac->ops.init_hw(hw))
e_err("Hardware Error\n"); e_err("Hardware Error\n");
/* additional part of the flow-control workaround above */
if (hw->mac.type == e1000_pchlan)
ew32(FCRTV_PCH, 0x1000);
e1000_update_mng_vlan(adapter); e1000_update_mng_vlan(adapter);
/* Enable h/w to recognize an 802.1Q VLAN Ethernet packet */ /* Enable h/w to recognize an 802.1Q VLAN Ethernet packet */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment