]> git.proxmox.com Git - mirror_ubuntu-focal-kernel.git/commitdiff
net: hns3: implement ndo_features_check ops for hns3 driver
authorYunsheng Lin <linyunsheng@huawei.com>
Thu, 19 Dec 2019 06:57:44 +0000 (14:57 +0800)
committerSeth Forshee <seth.forshee@canonical.com>
Wed, 26 Feb 2020 02:57:37 +0000 (20:57 -0600)
BugLink: https://launchpad.net/bugs/1859261
The function netif_skb_features() will disable the TSO feature
by using dflt_features_check() if the driver does not implement
ndo_features_check ops, which may cause performance degradation
problem when hns3 hardware can do multiple tagged TSO.

Also, the HNS3 hardware only supports checksum on the SKB with
a max header len of 480 bytes, so remove the checksum and TSO
related features when the header len is over 480 bytes.

Signed-off-by: Yunsheng Lin <linyunsheng@huawei.com>
Signed-off-by: Huazhong Tan <tanhuazhong@huawei.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
(cherry picked from commit 2a7556bb2b7308c6e0fe646c1ddbbf9522bf1120)
Signed-off-by: Ike Panhc <ike.pan@canonical.com>
Signed-off-by: Seth Forshee <seth.forshee@canonical.com>
drivers/net/ethernet/hisilicon/hns3/hns3_enet.c

index 88999496e4b940452e2dce30c1aed38796b84b29..cd0e313e6826a13e4aefa11c9613254a48db0364 100644 (file)
@@ -1562,6 +1562,37 @@ static int hns3_nic_set_features(struct net_device *netdev,
        return 0;
 }
 
+static netdev_features_t hns3_features_check(struct sk_buff *skb,
+                                            struct net_device *dev,
+                                            netdev_features_t features)
+{
+#define HNS3_MAX_HDR_LEN       480U
+#define HNS3_MAX_L4_HDR_LEN    60U
+
+       size_t len;
+
+       if (skb->ip_summed != CHECKSUM_PARTIAL)
+               return features;
+
+       if (skb->encapsulation)
+               len = skb_inner_transport_header(skb) - skb->data;
+       else
+               len = skb_transport_header(skb) - skb->data;
+
+       /* Assume L4 is 60 byte as TCP is the only protocol with a
+        * a flexible value, and it's max len is 60 bytes.
+        */
+       len += HNS3_MAX_L4_HDR_LEN;
+
+       /* Hardware only supports checksum on the skb with a max header
+        * len of 480 bytes.
+        */
+       if (len > HNS3_MAX_HDR_LEN)
+               features &= ~(NETIF_F_CSUM_MASK | NETIF_F_GSO_MASK);
+
+       return features;
+}
+
 static void hns3_nic_get_stats64(struct net_device *netdev,
                                 struct rtnl_link_stats64 *stats)
 {
@@ -1976,6 +2007,7 @@ static const struct net_device_ops hns3_nic_netdev_ops = {
        .ndo_do_ioctl           = hns3_nic_do_ioctl,
        .ndo_change_mtu         = hns3_nic_change_mtu,
        .ndo_set_features       = hns3_nic_set_features,
+       .ndo_features_check     = hns3_features_check,
        .ndo_get_stats64        = hns3_nic_get_stats64,
        .ndo_setup_tc           = hns3_nic_setup_tc,
        .ndo_set_rx_mode        = hns3_nic_set_rx_mode,