diff options
| author | Yunsheng Lin <linyunsheng@huawei.com> | 2019-12-19 14:57:44 +0800 | 
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2019-12-20 21:20:39 -0800 | 
| commit | 2a7556bb2b7308c6e0fe646c1ddbbf9522bf1120 (patch) | |
| tree | 90c62e81b5faee6bdd334b888aa43e590cbfb71a | |
| parent | 44b6b88336a08be87a02d69f6a4754c86cda97f1 (diff) | |
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>
| -rw-r--r-- | drivers/net/ethernet/hisilicon/hns3/hns3_enet.c | 32 | 
1 files changed, 32 insertions, 0 deletions
| diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c index 5679a0cef975..840a1fbc4d2e 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c @@ -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, | 
