diff options
author | David S. Miller <davem@davemloft.net> | 2019-09-07 17:42:52 +0200 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2019-09-07 17:42:52 +0200 |
commit | 06be463368774067d100b237145d9d75db9e05af (patch) | |
tree | 6a34ac0e185e2d790c20526084a2a7dcba57453a | |
parent | 22c63d9c9461b280df608f620ad2d18d984c11a9 (diff) | |
parent | 68622d071e555e1528f3e7807f30f73311c1acae (diff) | |
download | linux-stable-06be463368774067d100b237145d9d75db9e05af.tar.gz linux-stable-06be463368774067d100b237145d9d75db9e05af.tar.bz2 linux-stable-06be463368774067d100b237145d9d75db9e05af.zip |
Merge branch 'hv_netvsc-features'
Haiyang Zhang says:
====================
hv_netvsc: Enable sg as tunable, sync offload settings to VF NIC
This patch set fixes an issue in SG tuning, and sync
offload settings from synthetic NIC to VF NIC.
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/hyperv/hyperv_net.h | 2 | ||||
-rw-r--r-- | drivers/net/hyperv/netvsc_drv.c | 26 | ||||
-rw-r--r-- | drivers/net/hyperv/rndis_filter.c | 1 |
3 files changed, 24 insertions, 5 deletions
diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h index ecc9af050387..670ef682f268 100644 --- a/drivers/net/hyperv/hyperv_net.h +++ b/drivers/net/hyperv/hyperv_net.h @@ -822,7 +822,7 @@ struct nvsp_message { #define NETVSC_SUPPORTED_HW_FEATURES (NETIF_F_RXCSUM | NETIF_F_IP_CSUM | \ NETIF_F_TSO | NETIF_F_IPV6_CSUM | \ - NETIF_F_TSO6 | NETIF_F_LRO) + NETIF_F_TSO6 | NETIF_F_LRO | NETIF_F_SG) #define VRSS_SEND_TAB_SIZE 16 /* must be power of 2 */ #define VRSS_CHANNEL_MAX 64 diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c index 0a6cd2f1111f..39dddcd8b3cb 100644 --- a/drivers/net/hyperv/netvsc_drv.c +++ b/drivers/net/hyperv/netvsc_drv.c @@ -1785,13 +1785,15 @@ static int netvsc_set_features(struct net_device *ndev, netdev_features_t change = features ^ ndev->features; struct net_device_context *ndevctx = netdev_priv(ndev); struct netvsc_device *nvdev = rtnl_dereference(ndevctx->nvdev); + struct net_device *vf_netdev = rtnl_dereference(ndevctx->vf_netdev); struct ndis_offload_params offloads; + int ret = 0; if (!nvdev || nvdev->destroy) return -ENODEV; if (!(change & NETIF_F_LRO)) - return 0; + goto syncvf; memset(&offloads, 0, sizeof(struct ndis_offload_params)); @@ -1803,7 +1805,19 @@ static int netvsc_set_features(struct net_device *ndev, offloads.rsc_ip_v6 = NDIS_OFFLOAD_PARAMETERS_RSC_DISABLED; } - return rndis_filter_set_offload_params(ndev, nvdev, &offloads); + ret = rndis_filter_set_offload_params(ndev, nvdev, &offloads); + + if (ret) + features ^= NETIF_F_LRO; + +syncvf: + if (!vf_netdev) + return ret; + + vf_netdev->wanted_features = features; + netdev_update_features(vf_netdev); + + return ret; } static u32 netvsc_get_msglevel(struct net_device *ndev) @@ -2181,6 +2195,10 @@ static int netvsc_register_vf(struct net_device *vf_netdev) dev_hold(vf_netdev); rcu_assign_pointer(net_device_ctx->vf_netdev, vf_netdev); + + vf_netdev->wanted_features = ndev->features; + netdev_update_features(vf_netdev); + return NOTIFY_OK; } @@ -2313,8 +2331,8 @@ static int netvsc_probe(struct hv_device *dev, /* hw_features computed in rndis_netdev_set_hwcaps() */ net->features = net->hw_features | - NETIF_F_HIGHDMA | NETIF_F_SG | - NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX; + NETIF_F_HIGHDMA | NETIF_F_HW_VLAN_CTAG_TX | + NETIF_F_HW_VLAN_CTAG_RX; net->vlan_features = net->features; netdev_lockdep_set_classes(net); diff --git a/drivers/net/hyperv/rndis_filter.c b/drivers/net/hyperv/rndis_filter.c index 317dbe9356c2..abaf8156d19d 100644 --- a/drivers/net/hyperv/rndis_filter.c +++ b/drivers/net/hyperv/rndis_filter.c @@ -1207,6 +1207,7 @@ static int rndis_netdev_set_hwcaps(struct rndis_device *rndis_device, /* Compute tx offload settings based on hw capabilities */ net->hw_features |= NETIF_F_RXCSUM; + net->hw_features |= NETIF_F_SG; if ((hwcaps.csum.ip4_txcsum & NDIS_TXCSUM_ALL_TCP4) == NDIS_TXCSUM_ALL_TCP4) { /* Can checksum TCP */ |