diff options
Diffstat (limited to 'drivers/net/e1000e/netdev.c')
-rw-r--r-- | drivers/net/e1000e/netdev.c | 41 |
1 files changed, 29 insertions, 12 deletions
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index 0687c6aa4e46..a1a5a6f15a65 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c | |||
@@ -2769,25 +2769,38 @@ void e1000e_reset(struct e1000_adapter *adapter) | |||
2769 | /* | 2769 | /* |
2770 | * flow control settings | 2770 | * flow control settings |
2771 | * | 2771 | * |
2772 | * The high water mark must be low enough to fit two full frame | 2772 | * The high water mark must be low enough to fit one full frame |
2773 | * (or the size used for early receive) above it in the Rx FIFO. | 2773 | * (or the size used for early receive) above it in the Rx FIFO. |
2774 | * Set it to the lower of: | 2774 | * Set it to the lower of: |
2775 | * - 90% of the Rx FIFO size, and | 2775 | * - 90% of the Rx FIFO size, and |
2776 | * - the full Rx FIFO size minus the early receive size (for parts | 2776 | * - the full Rx FIFO size minus the early receive size (for parts |
2777 | * with ERT support assuming ERT set to E1000_ERT_2048), or | 2777 | * with ERT support assuming ERT set to E1000_ERT_2048), or |
2778 | * - the full Rx FIFO size minus two full frames | 2778 | * - the full Rx FIFO size minus one full frame |
2779 | */ | 2779 | */ |
2780 | if ((adapter->flags & FLAG_HAS_ERT) && | 2780 | if (hw->mac.type == e1000_pchlan) { |
2781 | (adapter->netdev->mtu > ETH_DATA_LEN)) | 2781 | /* |
2782 | hwm = min(((pba << 10) * 9 / 10), | 2782 | * Workaround PCH LOM adapter hangs with certain network |
2783 | ((pba << 10) - (E1000_ERT_2048 << 3))); | 2783 | * loads. If hangs persist, try disabling Tx flow control. |
2784 | else | 2784 | */ |
2785 | hwm = min(((pba << 10) * 9 / 10), | 2785 | if (adapter->netdev->mtu > ETH_DATA_LEN) { |
2786 | ((pba << 10) - (2 * adapter->max_frame_size))); | 2786 | fc->high_water = 0x3500; |
2787 | fc->low_water = 0x1500; | ||
2788 | } else { | ||
2789 | fc->high_water = 0x5000; | ||
2790 | fc->low_water = 0x3000; | ||
2791 | } | ||
2792 | } else { | ||
2793 | if ((adapter->flags & FLAG_HAS_ERT) && | ||
2794 | (adapter->netdev->mtu > ETH_DATA_LEN)) | ||
2795 | hwm = min(((pba << 10) * 9 / 10), | ||
2796 | ((pba << 10) - (E1000_ERT_2048 << 3))); | ||
2797 | else | ||
2798 | hwm = min(((pba << 10) * 9 / 10), | ||
2799 | ((pba << 10) - adapter->max_frame_size)); | ||
2787 | 2800 | ||
2788 | fc->high_water = hwm & E1000_FCRTH_RTH; /* 8-byte granularity */ | 2801 | fc->high_water = hwm & E1000_FCRTH_RTH; /* 8-byte granularity */ |
2789 | fc->low_water = (fc->high_water - (2 * adapter->max_frame_size)); | 2802 | fc->low_water = fc->high_water - 8; |
2790 | fc->low_water &= E1000_FCRTL_RTL; /* 8-byte granularity */ | 2803 | } |
2791 | 2804 | ||
2792 | if (adapter->flags & FLAG_DISABLE_FC_PAUSE_TIME) | 2805 | if (adapter->flags & FLAG_DISABLE_FC_PAUSE_TIME) |
2793 | fc->pause_time = 0xFFFF; | 2806 | fc->pause_time = 0xFFFF; |
@@ -2813,6 +2826,10 @@ void e1000e_reset(struct e1000_adapter *adapter) | |||
2813 | if (mac->ops.init_hw(hw)) | 2826 | if (mac->ops.init_hw(hw)) |
2814 | e_err("Hardware Error\n"); | 2827 | e_err("Hardware Error\n"); |
2815 | 2828 | ||
2829 | /* additional part of the flow-control workaround above */ | ||
2830 | if (hw->mac.type == e1000_pchlan) | ||
2831 | ew32(FCRTV_PCH, 0x1000); | ||
2832 | |||
2816 | e1000_update_mng_vlan(adapter); | 2833 | e1000_update_mng_vlan(adapter); |
2817 | 2834 | ||
2818 | /* Enable h/w to recognize an 802.1Q VLAN Ethernet packet */ | 2835 | /* Enable h/w to recognize an 802.1Q VLAN Ethernet packet */ |