|
@@ -2769,25 +2769,38 @@ void e1000e_reset(struct e1000_adapter *adapter)
|
|
|
/*
|
|
|
* 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.
|
|
|
* Set it to the lower of:
|
|
|
* - 90% of the Rx FIFO size, and
|
|
|
* - the full Rx FIFO size minus the early receive size (for parts
|
|
|
* 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 ((adapter->flags & FLAG_HAS_ERT) &&
|
|
|
- (adapter->netdev->mtu > ETH_DATA_LEN))
|
|
|
- hwm = min(((pba << 10) * 9 / 10),
|
|
|
- ((pba << 10) - (E1000_ERT_2048 << 3)));
|
|
|
- else
|
|
|
- hwm = min(((pba << 10) * 9 / 10),
|
|
|
- ((pba << 10) - (2 * adapter->max_frame_size)));
|
|
|
+ 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) &&
|
|
|
+ (adapter->netdev->mtu > ETH_DATA_LEN))
|
|
|
+ hwm = min(((pba << 10) * 9 / 10),
|
|
|
+ ((pba << 10) - (E1000_ERT_2048 << 3)));
|
|
|
+ else
|
|
|
+ hwm = min(((pba << 10) * 9 / 10),
|
|
|
+ ((pba << 10) - adapter->max_frame_size));
|
|
|
|
|
|
- fc->high_water = hwm & E1000_FCRTH_RTH; /* 8-byte granularity */
|
|
|
- fc->low_water = (fc->high_water - (2 * adapter->max_frame_size));
|
|
|
- fc->low_water &= E1000_FCRTL_RTL; /* 8-byte granularity */
|
|
|
+ fc->high_water = hwm & E1000_FCRTH_RTH; /* 8-byte granularity */
|
|
|
+ fc->low_water = fc->high_water - 8;
|
|
|
+ }
|
|
|
|
|
|
if (adapter->flags & FLAG_DISABLE_FC_PAUSE_TIME)
|
|
|
fc->pause_time = 0xFFFF;
|
|
@@ -2813,6 +2826,10 @@ void e1000e_reset(struct e1000_adapter *adapter)
|
|
|
if (mac->ops.init_hw(hw))
|
|
|
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);
|
|
|
|
|
|
/* Enable h/w to recognize an 802.1Q VLAN Ethernet packet */
|