From patchwork Mon Oct 26 03:40:57 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Toshiaki Makita X-Patchwork-Id: 535683 X-Patchwork-Delegate: jeffrey.t.kirsher@intel.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from fraxinus.osuosl.org (smtp4.osuosl.org [140.211.166.137]) by ozlabs.org (Postfix) with ESMTP id 8538C141357 for ; Mon, 26 Oct 2015 14:41:38 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by fraxinus.osuosl.org (Postfix) with ESMTP id 8D96B876FF; Mon, 26 Oct 2015 03:41:37 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from fraxinus.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id qhj-3mWe2BO6; Mon, 26 Oct 2015 03:41:36 +0000 (UTC) Received: from ash.osuosl.org (ash.osuosl.org [140.211.166.34]) by fraxinus.osuosl.org (Postfix) with ESMTP id 3CD5687732; Mon, 26 Oct 2015 03:41:35 +0000 (UTC) X-Original-To: intel-wired-lan@lists.osuosl.org Delivered-To: intel-wired-lan@lists.osuosl.org Received: from fraxinus.osuosl.org (smtp4.osuosl.org [140.211.166.137]) by ash.osuosl.org (Postfix) with ESMTP id D27781C11D6 for ; Mon, 26 Oct 2015 03:41:33 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by fraxinus.osuosl.org (Postfix) with ESMTP id CE77C872D3 for ; Mon, 26 Oct 2015 03:41:33 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from fraxinus.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id h1YnZh7v8900 for ; Mon, 26 Oct 2015 03:41:32 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from tama500.ecl.ntt.co.jp (tama500.ecl.ntt.co.jp [129.60.39.148]) by fraxinus.osuosl.org (Postfix) with ESMTP id DCCA7873E5 for ; Mon, 26 Oct 2015 03:41:31 +0000 (UTC) Received: from vc2.ecl.ntt.co.jp (vc2.ecl.ntt.co.jp [129.60.86.154]) by tama500.ecl.ntt.co.jp (8.13.8/8.13.8) with ESMTP id t9Q3fR74003095; Mon, 26 Oct 2015 12:41:27 +0900 Received: from vc2.ecl.ntt.co.jp (localhost [127.0.0.1]) by vc2.ecl.ntt.co.jp (Postfix) with ESMTP id 03F3C5F631; Mon, 26 Oct 2015 12:41:27 +0900 (JST) Received: from imail3.m.ecl.ntt.co.jp (imail3.m.ecl.ntt.co.jp [129.60.5.248]) by vc2.ecl.ntt.co.jp (Postfix) with ESMTP id E5BE65F592; Mon, 26 Oct 2015 12:41:26 +0900 (JST) Received: from ubuntu-vm-makita ([129.60.241.200]) by imail3.m.ecl.ntt.co.jp (8.13.8/8.13.8) with ESMTP id t9Q3fOfO018936; Mon, 26 Oct 2015 12:41:26 +0900 Received: by ubuntu-vm-makita (Postfix, from userid 1000) id 2DEA91E0062; Mon, 26 Oct 2015 12:41:22 +0900 (JST) From: Toshiaki Makita To: "David S . Miller" Date: Mon, 26 Oct 2015 12:40:57 +0900 Message-Id: <1445830859-4651-3-git-send-email-makita.toshiaki@lab.ntt.co.jp> X-Mailer: git-send-email 1.8.1.2 In-Reply-To: <1445830859-4651-1-git-send-email-makita.toshiaki@lab.ntt.co.jp> References: <1445830859-4651-1-git-send-email-makita.toshiaki@lab.ntt.co.jp> X-TM-AS-MML: disable Cc: netdev@vger.kernel.org, Vlad Yasevich , toshiaki.makita1@gmail.com, Stephen Hemminger , intel-wired-lan@lists.osuosl.org, Toshiaki Makita , Patrick McHardy Subject: [Intel-wired-lan] [PATCH v2 net-next 2/4] e1000e: Add ndo_enc_hdr_len X-BeenThere: intel-wired-lan@lists.osuosl.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: Intel Wired Ethernet Linux Kernel Driver Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: intel-wired-lan-bounces@lists.osuosl.org Sender: "Intel-wired-lan" e1000e has 4 bytes additional room for vlan header, so set default enc_hdr_len to 4. Note that e1000e uses mtu to validate frame size in some places, which are needed to be modified to use max_frame_size as extra header room became variable. Signed-off-by: Toshiaki Makita --- drivers/net/ethernet/intel/e1000e/netdev.c | 82 ++++++++++++++++++++++-------- 1 file changed, 60 insertions(+), 22 deletions(-) diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c index 0a854a4..61ce986 100644 --- a/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/drivers/net/ethernet/intel/e1000e/netdev.c @@ -3046,7 +3046,7 @@ static void e1000_setup_rctl(struct e1000_adapter *adapter) if (hw->mac.type >= e1000_pch2lan) { s32 ret_val; - if (adapter->netdev->mtu > ETH_DATA_LEN) + if (adapter->max_frame_size > VLAN_ETH_FRAME_LEN + ETH_FCS_LEN) ret_val = e1000_lv_jumbo_workaround_ich8lan(hw, true); else ret_val = e1000_lv_jumbo_workaround_ich8lan(hw, false); @@ -3066,7 +3066,7 @@ static void e1000_setup_rctl(struct e1000_adapter *adapter) rctl &= ~E1000_RCTL_SBP; /* Enable Long Packet receive */ - if (adapter->netdev->mtu <= ETH_DATA_LEN) + if (adapter->max_frame_size <= VLAN_ETH_FRAME_LEN + ETH_FCS_LEN) rctl &= ~E1000_RCTL_LPE; else rctl |= E1000_RCTL_LPE; @@ -3286,7 +3286,7 @@ static void e1000_configure_rx(struct e1000_adapter *adapter) /* With jumbo frames, excessive C-state transition latencies result * in dropped transactions. */ - if (adapter->netdev->mtu > ETH_DATA_LEN) { + if (adapter->max_frame_size > VLAN_ETH_FRAME_LEN + ETH_FCS_LEN) { u32 lat = ((er32(PBA) & E1000_PBA_RXA_MASK) * 1024 - adapter->max_frame_size) * 8 / 1000; @@ -3978,7 +3978,8 @@ void e1000e_reset(struct e1000_adapter *adapter) switch (hw->mac.type) { case e1000_ich9lan: case e1000_ich10lan: - if (adapter->netdev->mtu > ETH_DATA_LEN) { + if (adapter->max_frame_size > VLAN_ETH_FRAME_LEN + + ETH_FCS_LEN) { pba = 14; ew32(PBA, pba); fc->high_water = 0x2800; @@ -3997,7 +3998,8 @@ void e1000e_reset(struct e1000_adapter *adapter) /* Workaround PCH LOM adapter hangs with certain network * loads. If hangs persist, try disabling Tx flow control. */ - if (adapter->netdev->mtu > ETH_DATA_LEN) { + if (adapter->max_frame_size > VLAN_ETH_FRAME_LEN + + ETH_FCS_LEN) { fc->high_water = 0x3500; fc->low_water = 0x1500; } else { @@ -4011,7 +4013,8 @@ void e1000e_reset(struct e1000_adapter *adapter) case e1000_pch_spt: fc->refresh_time = 0x0400; - if (adapter->netdev->mtu <= ETH_DATA_LEN) { + if (adapter->max_frame_size <= VLAN_ETH_FRAME_LEN + + ETH_FCS_LEN) { fc->high_water = 0x05C20; fc->low_water = 0x05048; fc->pause_time = 0x0650; @@ -4247,7 +4250,7 @@ void e1000e_down(struct e1000_adapter *adapter, bool reset) /* Disable Si errata workaround on PCHx for jumbo frame flow */ if ((hw->mac.type >= e1000_pch2lan) && - (adapter->netdev->mtu > ETH_DATA_LEN) && + (adapter->max_frame_size > VLAN_ETH_FRAME_LEN + ETH_FCS_LEN) && e1000_lv_jumbo_workaround_ich8lan(hw, false)) e_dbg("failed to disable jumbo frame workaround mode\n"); @@ -4346,7 +4349,8 @@ static int e1000_sw_init(struct e1000_adapter *adapter) adapter->rx_buffer_len = VLAN_ETH_FRAME_LEN + ETH_FCS_LEN; adapter->rx_ps_bsize0 = 128; - adapter->max_frame_size = netdev->mtu + VLAN_ETH_HLEN + ETH_FCS_LEN; + adapter->max_frame_size = netdev->mtu + netdev->enc_hdr_len + + ETH_HLEN + ETH_FCS_LEN; adapter->min_frame_size = ETH_ZLEN + ETH_FCS_LEN; adapter->tx_ring_count = E1000_DEFAULT_TXD; adapter->rx_ring_count = E1000_DEFAULT_RXD; @@ -5920,17 +5924,10 @@ struct rtnl_link_stats64 *e1000e_get_stats64(struct net_device *netdev, return stats; } -/** - * e1000_change_mtu - Change the Maximum Transfer Unit - * @netdev: network interface device structure - * @new_mtu: new value for maximum frame size - * - * Returns 0 on success, negative on failure - **/ -static int e1000_change_mtu(struct net_device *netdev, int new_mtu) +static int e1000_change_max_frame(struct net_device *netdev, int max_frame, + int new_mtu) { struct e1000_adapter *adapter = netdev_priv(netdev); - int max_frame = new_mtu + VLAN_ETH_HLEN + ETH_FCS_LEN; /* Jumbo frame support */ if ((max_frame > (VLAN_ETH_FRAME_LEN + ETH_FCS_LEN)) && @@ -5940,7 +5937,7 @@ static int e1000_change_mtu(struct net_device *netdev, int new_mtu) } /* Supported frame sizes */ - if ((new_mtu < (VLAN_ETH_ZLEN + ETH_FCS_LEN)) || + if ((new_mtu && new_mtu < (VLAN_ETH_ZLEN + ETH_FCS_LEN)) || (max_frame > adapter->max_hw_frame_size)) { e_err("Unsupported MTU setting\n"); return -EINVAL; @@ -5949,7 +5946,7 @@ static int e1000_change_mtu(struct net_device *netdev, int new_mtu) /* Jumbo frame workaround on 82579 and newer requires CRC be stripped */ if ((adapter->hw.mac.type >= e1000_pch2lan) && !(adapter->flags2 & FLAG2_CRC_STRIPPING) && - (new_mtu > ETH_DATA_LEN)) { + (max_frame > VLAN_ETH_FRAME_LEN + ETH_FCS_LEN)) { e_err("Jumbo Frames not supported on this device when CRC stripping is disabled.\n"); return -EINVAL; } @@ -5957,9 +5954,14 @@ static int e1000_change_mtu(struct net_device *netdev, int new_mtu) while (test_and_set_bit(__E1000_RESETTING, &adapter->state)) usleep_range(1000, 2000); /* e1000e_down -> e1000e_reset dependent on max_frame_size & mtu */ + if (new_mtu) { + e_info("changing MTU from %d to %d\n", netdev->mtu, new_mtu); + netdev->mtu = new_mtu; + } else { + e_info("changing max frame size from %d to %d\n", + adapter->max_frame_size, max_frame); + } adapter->max_frame_size = max_frame; - e_info("changing MTU from %d to %d\n", netdev->mtu, new_mtu); - netdev->mtu = new_mtu; pm_runtime_get_sync(netdev->dev.parent); @@ -5995,6 +5997,20 @@ static int e1000_change_mtu(struct net_device *netdev, int new_mtu) return 0; } +/** + * e1000_change_mtu - Change the Maximum Transfer Unit + * @netdev: network interface device structure + * @new_mtu: new value for maximum frame size + * + * Returns 0 on success, negative on failure + **/ +static int e1000_change_mtu(struct net_device *netdev, int new_mtu) +{ + int max_frame = new_mtu + netdev->enc_hdr_len + ETH_HLEN + ETH_FCS_LEN; + + return e1000_change_max_frame(netdev, max_frame, new_mtu); +} + static int e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd) { @@ -6889,7 +6905,8 @@ static netdev_features_t e1000_fix_features(struct net_device *netdev, struct e1000_hw *hw = &adapter->hw; /* Jumbo frame workaround on 82579 and newer requires CRC be stripped */ - if ((hw->mac.type >= e1000_pch2lan) && (netdev->mtu > ETH_DATA_LEN)) + if (hw->mac.type >= e1000_pch2lan && + adapter->max_frame_size > VLAN_ETH_FRAME_LEN + ETH_FCS_LEN) features &= ~NETIF_F_RXFCS; return features; @@ -6933,6 +6950,24 @@ static int e1000_set_features(struct net_device *netdev, return 0; } +/** + * e1000_enc_hdr_len - Expand encapsulation header room + * @netdev: network interface device structure + * @new_mtu: new value for maximum encapsulation header length + * + * Returns 0 on success, negative on failure + **/ +static int e1000_enc_hdr_len(struct net_device *netdev, int new_len) +{ + struct e1000_adapter *adapter = netdev_priv(netdev); + int max_frame = netdev->mtu + new_len + ETH_HLEN + ETH_FCS_LEN; + + if (max_frame <= adapter->max_frame_size) + return 0; + + return e1000_change_max_frame(netdev, max_frame, 0); +} + static const struct net_device_ops e1000e_netdev_ops = { .ndo_open = e1000_open, .ndo_stop = e1000_close, @@ -6953,6 +6988,7 @@ static const struct net_device_ops e1000e_netdev_ops = { .ndo_set_features = e1000_set_features, .ndo_fix_features = e1000_fix_features, .ndo_features_check = passthru_features_check, + .ndo_enc_hdr_len = e1000_enc_hdr_len, }; /** @@ -7075,6 +7111,8 @@ static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *ent) netdev->mem_start = mmio_start; netdev->mem_end = mmio_start + mmio_len; + netdev->enc_hdr_len = VLAN_HLEN; + adapter->bd_number = cards_found++; e1000e_check_options(adapter);