net: hns3: fix for setting MTU
authorFuyun Liang <liangfuyun1@huawei.com>
Fri, 5 Jan 2018 10:18:19 +0000 (18:18 +0800)
committerDavid S. Miller <davem@davemloft.net>
Mon, 8 Jan 2018 19:06:19 +0000 (14:06 -0500)
When setting MTU, actually what we do is configuring the max frame size
for the hardware. ETH_HLEN、ETH_FCS_LEN and VLAN_HLEN must need to be
considered. And the frame size which is less than the default value
should not be set to the hardware. Because in the hardware, the the max
frame size not only controls the RX packet size, but also controls the
TX packet size. the RX packets whose size are greater than the setting
value will be dropped.

This patch fixes the bug setting a error max frame size to hardware.

Fixes: 46a3df9f9718 ("net: hns3: Add HNS3 Acceleration Engine & Compatibility Layer Support")
Signed-off-by: Fuyun Liang <liangfuyun1@huawei.com>
Signed-off-by: Peng Li <lipeng321@huawei.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h

index f5baba216e48b2a53756725acb19fb5a5704374f..3c3159b2d3bf2677a1fbd4cfd7727cea3702106b 100644 (file)
@@ -556,8 +556,6 @@ struct hclge_config_auto_neg_cmd {
        u8      rsv[20];
 };
 
-#define HCLGE_MAC_MIN_MTU              64
-#define HCLGE_MAC_MAX_MTU              9728
 #define HCLGE_MAC_UPLINK_PORT          0x100
 
 struct hclge_config_max_frm_size_cmd {
index fcda9a24f6725a39199847f7fa7180b6a24cdcaf..f1702db13df95046cececf1d66e07a93c6b2835d 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/netdevice.h>
 #include <linux/pci.h>
 #include <linux/platform_device.h>
+#include <linux/if_vlan.h>
 #include <net/rtnetlink.h>
 #include "hclge_cmd.h"
 #include "hclge_dcb.h"
@@ -4560,16 +4561,21 @@ static int hclge_set_mtu(struct hnae3_handle *handle, int new_mtu)
        struct hclge_config_max_frm_size_cmd *req;
        struct hclge_dev *hdev = vport->back;
        struct hclge_desc desc;
+       int max_frm_size;
        int ret;
 
-       if ((new_mtu < HCLGE_MAC_MIN_MTU) || (new_mtu > HCLGE_MAC_MAX_MTU))
+       max_frm_size = new_mtu + ETH_HLEN + ETH_FCS_LEN + VLAN_HLEN;
+
+       if (max_frm_size < HCLGE_MAC_MIN_FRAME ||
+           max_frm_size > HCLGE_MAC_MAX_FRAME)
                return -EINVAL;
 
-       hdev->mps = new_mtu;
+       max_frm_size = max(max_frm_size, HCLGE_MAC_DEFAULT_FRAME);
+
        hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_CONFIG_MAX_FRM_SIZE, false);
 
        req = (struct hclge_config_max_frm_size_cmd *)desc.data;
-       req->max_frm_size = cpu_to_le16(new_mtu);
+       req->max_frm_size = cpu_to_le16(max_frm_size);
 
        ret = hclge_cmd_send(&hdev->hw, &desc, 1);
        if (ret) {
@@ -4577,6 +4583,8 @@ static int hclge_set_mtu(struct hnae3_handle *handle, int new_mtu)
                return ret;
        }
 
+       hdev->mps = max_frm_size;
+
        return 0;
 }
 
index 50ae13a3fb5461ac6b6a8801b55131c137602a00..83fb195856aa157d942128544fbda510cd5efa26 100644 (file)
 /* CMDQ register bits for RX event(=MBX event) */
 #define HCLGE_VECTOR0_RX_CMDQ_INT_B    1
 
+#define HCLGE_MAC_DEFAULT_FRAME \
+       (ETH_HLEN + ETH_FCS_LEN + VLAN_HLEN + ETH_DATA_LEN)
+#define HCLGE_MAC_MIN_FRAME            64
+#define HCLGE_MAC_MAX_FRAME            9728
+
 enum HCLGE_DEV_STATE {
        HCLGE_STATE_REINITING,
        HCLGE_STATE_DOWN,