|
@@ -626,11 +626,18 @@ static netdev_features_t vlan_dev_fix_features(struct net_device *dev,
|
|
|
{
|
|
|
struct net_device *real_dev = vlan_dev_priv(dev)->real_dev;
|
|
|
netdev_features_t old_features = features;
|
|
|
+ netdev_features_t lower_features;
|
|
|
|
|
|
- features = netdev_intersect_features(features, real_dev->vlan_features);
|
|
|
- features |= NETIF_F_RXCSUM;
|
|
|
- features = netdev_intersect_features(features, real_dev->features);
|
|
|
+ lower_features = netdev_intersect_features((real_dev->vlan_features |
|
|
|
+ NETIF_F_RXCSUM),
|
|
|
+ real_dev->features);
|
|
|
|
|
|
+ /* Add HW_CSUM setting to preserve user ability to control
|
|
|
+ * checksum offload on the vlan device.
|
|
|
+ */
|
|
|
+ if (lower_features & (NETIF_F_IP_CSUM|NETIF_F_IPV6_CSUM))
|
|
|
+ lower_features |= NETIF_F_HW_CSUM;
|
|
|
+ features = netdev_intersect_features(features, lower_features);
|
|
|
features |= old_features & (NETIF_F_SOFT_FEATURES | NETIF_F_GSO_SOFTWARE);
|
|
|
features |= NETIF_F_LLTX;
|
|
|
|