diff options
Diffstat (limited to 'drivers/net/e1000e/netdev.c')
-rw-r--r-- | drivers/net/e1000e/netdev.c | 50 |
1 files changed, 33 insertions, 17 deletions
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index 11a527484e18..e546b4ebf155 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c | |||
@@ -2760,25 +2760,38 @@ void e1000e_reset(struct e1000_adapter *adapter) | |||
2760 | /* | 2760 | /* |
2761 | * flow control settings | 2761 | * flow control settings |
2762 | * | 2762 | * |
2763 | * The high water mark must be low enough to fit two full frame | 2763 | * The high water mark must be low enough to fit one full frame |
2764 | * (or the size used for early receive) above it in the Rx FIFO. | 2764 | * (or the size used for early receive) above it in the Rx FIFO. |
2765 | * Set it to the lower of: | 2765 | * Set it to the lower of: |
2766 | * - 90% of the Rx FIFO size, and | 2766 | * - 90% of the Rx FIFO size, and |
2767 | * - the full Rx FIFO size minus the early receive size (for parts | 2767 | * - the full Rx FIFO size minus the early receive size (for parts |
2768 | * with ERT support assuming ERT set to E1000_ERT_2048), or | 2768 | * with ERT support assuming ERT set to E1000_ERT_2048), or |
2769 | * - the full Rx FIFO size minus two full frames | 2769 | * - the full Rx FIFO size minus one full frame |
2770 | */ | 2770 | */ |
2771 | if ((adapter->flags & FLAG_HAS_ERT) && | 2771 | if (hw->mac.type == e1000_pchlan) { |
2772 | (adapter->netdev->mtu > ETH_DATA_LEN)) | 2772 | /* |
2773 | hwm = min(((pba << 10) * 9 / 10), | 2773 | * Workaround PCH LOM adapter hangs with certain network |
2774 | ((pba << 10) - (E1000_ERT_2048 << 3))); | 2774 | * loads. If hangs persist, try disabling Tx flow control. |
2775 | else | 2775 | */ |
2776 | hwm = min(((pba << 10) * 9 / 10), | 2776 | if (adapter->netdev->mtu > ETH_DATA_LEN) { |
2777 | ((pba << 10) - (2 * adapter->max_frame_size))); | 2777 | fc->high_water = 0x3500; |
2778 | fc->low_water = 0x1500; | ||
2779 | } else { | ||
2780 | fc->high_water = 0x5000; | ||
2781 | fc->low_water = 0x3000; | ||
2782 | } | ||
2783 | } else { | ||
2784 | if ((adapter->flags & FLAG_HAS_ERT) && | ||
2785 | (adapter->netdev->mtu > ETH_DATA_LEN)) | ||
2786 | hwm = min(((pba << 10) * 9 / 10), | ||
2787 | ((pba << 10) - (E1000_ERT_2048 << 3))); | ||
2788 | else | ||
2789 | hwm = min(((pba << 10) * 9 / 10), | ||
2790 | ((pba << 10) - adapter->max_frame_size)); | ||
2778 | 2791 | ||
2779 | fc->high_water = hwm & E1000_FCRTH_RTH; /* 8-byte granularity */ | 2792 | fc->high_water = hwm & E1000_FCRTH_RTH; /* 8-byte granularity */ |
2780 | fc->low_water = (fc->high_water - (2 * adapter->max_frame_size)); | 2793 | fc->low_water = fc->high_water - 8; |
2781 | fc->low_water &= E1000_FCRTL_RTL; /* 8-byte granularity */ | 2794 | } |
2782 | 2795 | ||
2783 | if (adapter->flags & FLAG_DISABLE_FC_PAUSE_TIME) | 2796 | if (adapter->flags & FLAG_DISABLE_FC_PAUSE_TIME) |
2784 | fc->pause_time = 0xFFFF; | 2797 | fc->pause_time = 0xFFFF; |
@@ -2804,6 +2817,10 @@ void e1000e_reset(struct e1000_adapter *adapter) | |||
2804 | if (mac->ops.init_hw(hw)) | 2817 | if (mac->ops.init_hw(hw)) |
2805 | e_err("Hardware Error\n"); | 2818 | e_err("Hardware Error\n"); |
2806 | 2819 | ||
2820 | /* additional part of the flow-control workaround above */ | ||
2821 | if (hw->mac.type == e1000_pchlan) | ||
2822 | ew32(FCRTV_PCH, 0x1000); | ||
2823 | |||
2807 | e1000_update_mng_vlan(adapter); | 2824 | e1000_update_mng_vlan(adapter); |
2808 | 2825 | ||
2809 | /* Enable h/w to recognize an 802.1Q VLAN Ethernet packet */ | 2826 | /* Enable h/w to recognize an 802.1Q VLAN Ethernet packet */ |
@@ -3612,7 +3629,7 @@ static void e1000_watchdog_task(struct work_struct *work) | |||
3612 | case SPEED_100: | 3629 | case SPEED_100: |
3613 | txb2b = 0; | 3630 | txb2b = 0; |
3614 | netdev->tx_queue_len = 100; | 3631 | netdev->tx_queue_len = 100; |
3615 | /* maybe add some timeout factor ? */ | 3632 | adapter->tx_timeout_factor = 10; |
3616 | break; | 3633 | break; |
3617 | } | 3634 | } |
3618 | 3635 | ||
@@ -4284,8 +4301,10 @@ static int e1000_change_mtu(struct net_device *netdev, int new_mtu) | |||
4284 | 4301 | ||
4285 | while (test_and_set_bit(__E1000_RESETTING, &adapter->state)) | 4302 | while (test_and_set_bit(__E1000_RESETTING, &adapter->state)) |
4286 | msleep(1); | 4303 | msleep(1); |
4287 | /* e1000e_down has a dependency on max_frame_size */ | 4304 | /* e1000e_down -> e1000e_reset dependent on max_frame_size & mtu */ |
4288 | adapter->max_frame_size = max_frame; | 4305 | adapter->max_frame_size = max_frame; |
4306 | e_info("changing MTU from %d to %d\n", netdev->mtu, new_mtu); | ||
4307 | netdev->mtu = new_mtu; | ||
4289 | if (netif_running(netdev)) | 4308 | if (netif_running(netdev)) |
4290 | e1000e_down(adapter); | 4309 | e1000e_down(adapter); |
4291 | 4310 | ||
@@ -4315,9 +4334,6 @@ static int e1000_change_mtu(struct net_device *netdev, int new_mtu) | |||
4315 | adapter->rx_buffer_len = ETH_FRAME_LEN + VLAN_HLEN | 4334 | adapter->rx_buffer_len = ETH_FRAME_LEN + VLAN_HLEN |
4316 | + ETH_FCS_LEN; | 4335 | + ETH_FCS_LEN; |
4317 | 4336 | ||
4318 | e_info("changing MTU from %d to %d\n", netdev->mtu, new_mtu); | ||
4319 | netdev->mtu = new_mtu; | ||
4320 | |||
4321 | if (netif_running(netdev)) | 4337 | if (netif_running(netdev)) |
4322 | e1000e_up(adapter); | 4338 | e1000e_up(adapter); |
4323 | else | 4339 | else |