net: hns3: implement ndo_features_check ops for hns3 driver

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>
This commit is contained in:
Yunsheng Lin 2019-12-19 14:57:44 +08:00 committed by David S. Miller
parent 44b6b88336
commit 2a7556bb2b

View File

@ -1556,6 +1556,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)
{
@ -1970,6 +2001,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,