{
        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;