netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Jian Shen <shenjian15@huawei.com>
To: <davem@davemloft.net>, <kuba@kernel.org>, <andrew@lunn.ch>,
	<ecree.xilinx@gmail.com>, <hkallweit1@gmail.com>,
	<alexandr.lobakin@intel.com>, <saeed@kernel.org>,
	<leon@kernel.org>
Cc: <netdev@vger.kernel.org>, <linuxarm@openeuler.org>
Subject: [RFCv7 PATCH net-next 15/36] treewide: simplify the netdev features expression
Date: Wed, 10 Aug 2022 11:06:03 +0800	[thread overview]
Message-ID: <20220810030624.34711-16-shenjian15@huawei.com> (raw)
In-Reply-To: <20220810030624.34711-1-shenjian15@huawei.com>

To make the semantic patches simple, split the complex opreation of
netdev_features to simple ones, and replace some feature macroes with
global netdev features variables.

Signed-off-by: Jian Shen <shenjian15@huawei.com>
---
 drivers/infiniband/ulp/ipoib/ipoib_main.c     |  9 ++--
 drivers/net/bonding/bond_main.c               | 10 ++--
 drivers/net/ethernet/3com/3c59x.c             |  3 +-
 drivers/net/ethernet/adaptec/starfire.c       |  9 ++--
 drivers/net/ethernet/aeroflex/greth.c         |  3 +-
 drivers/net/ethernet/altera/altera_tse_main.c |  3 +-
 drivers/net/ethernet/amd/xgbe/xgbe-drv.c      |  3 +-
 drivers/net/ethernet/amd/xgbe/xgbe-main.c     |  4 +-
 drivers/net/ethernet/apm/xgene-v2/main.c      |  4 +-
 .../net/ethernet/apm/xgene/xgene_enet_main.c  |  3 +-
 .../net/ethernet/atheros/atl1c/atl1c_main.c   |  5 +-
 .../net/ethernet/atheros/atl1e/atl1e_main.c   |  6 ++-
 drivers/net/ethernet/broadcom/bnx2.c          | 16 ++++--
 .../net/ethernet/broadcom/bnx2x/bnx2x_cmn.c   |  6 ++-
 .../net/ethernet/broadcom/bnx2x/bnx2x_main.c  |  9 ++--
 drivers/net/ethernet/broadcom/bnxt/bnxt.c     | 24 ++++++---
 drivers/net/ethernet/broadcom/tg3.c           |  4 +-
 drivers/net/ethernet/cadence/macb_main.c      | 21 +++++---
 .../net/ethernet/cavium/liquidio/lio_main.c   | 10 ++--
 .../ethernet/cavium/liquidio/lio_vf_main.c    | 10 ++--
 .../net/ethernet/chelsio/cxgb3/cxgb3_main.c   |  7 +--
 .../net/ethernet/chelsio/cxgb4/cxgb4_main.c   |  6 ++-
 .../ethernet/chelsio/cxgb4vf/cxgb4vf_main.c   |  3 +-
 drivers/net/ethernet/cisco/enic/enic_main.c   |  6 ++-
 drivers/net/ethernet/cortina/gemini.c         |  3 +-
 drivers/net/ethernet/davicom/dm9000.c         |  3 +-
 drivers/net/ethernet/faraday/ftgmac100.c      |  6 ++-
 drivers/net/ethernet/freescale/gianfar.c      |  3 +-
 .../net/ethernet/freescale/gianfar_ethtool.c  |  3 +-
 .../ethernet/fungible/funeth/funeth_main.c    |  9 ++--
 drivers/net/ethernet/hisilicon/hix5hd2_gmac.c |  3 +-
 .../net/ethernet/hisilicon/hns3/hns3_enet.c   |  9 ++--
 .../net/ethernet/huawei/hinic/hinic_main.c    |  3 +-
 drivers/net/ethernet/ibm/emac/core.c          |  3 +-
 drivers/net/ethernet/ibm/ibmveth.c            |  8 +--
 drivers/net/ethernet/ibm/ibmvnic.c            |  8 +--
 drivers/net/ethernet/intel/e100.c             |  2 +-
 drivers/net/ethernet/intel/e1000/e1000_main.c |  2 +-
 drivers/net/ethernet/intel/i40e/i40e_main.c   | 16 +++---
 drivers/net/ethernet/intel/iavf/iavf_main.c   |  9 ++--
 drivers/net/ethernet/intel/ice/ice_main.c     | 27 ++++++----
 drivers/net/ethernet/intel/igb/igb_main.c     | 14 +++--
 drivers/net/ethernet/intel/igbvf/netdev.c     |  9 ++--
 drivers/net/ethernet/intel/igc/igc_main.c     |  8 +--
 drivers/net/ethernet/intel/ixgb/ixgb_main.c   |  6 +--
 drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 29 ++++++-----
 .../net/ethernet/intel/ixgbevf/ixgbevf_main.c | 10 ++--
 drivers/net/ethernet/jme.c                    |  6 ++-
 drivers/net/ethernet/marvell/mvneta.c         |  3 +-
 .../net/ethernet/marvell/mvpp2/mvpp2_main.c   |  3 +-
 .../ethernet/marvell/octeontx2/nic/otx2_pf.c  |  3 +-
 .../ethernet/marvell/prestera/prestera_main.c |  3 +-
 drivers/net/ethernet/marvell/sky2.c           |  4 +-
 .../net/ethernet/mellanox/mlx4/en_netdev.c    |  4 +-
 .../net/ethernet/mellanox/mlx5/core/en_main.c | 36 ++++++-------
 drivers/net/ethernet/mscc/ocelot_net.c        |  2 +-
 .../net/ethernet/myricom/myri10ge/myri10ge.c  |  9 ++--
 drivers/net/ethernet/neterion/s2io.c          |  4 +-
 .../ethernet/netronome/nfp/nfp_net_common.c   |  7 +--
 .../net/ethernet/netronome/nfp/nfp_net_repr.c |  6 ++-
 drivers/net/ethernet/netronome/nfp/nfp_port.c |  2 +-
 drivers/net/ethernet/nvidia/forcedeth.c       |  2 +-
 .../net/ethernet/pensando/ionic/ionic_lif.c   |  3 +-
 .../ethernet/qlogic/netxen/netxen_nic_main.c  | 10 ++--
 drivers/net/ethernet/qlogic/qede/qede_main.c  | 15 +++---
 drivers/net/ethernet/qlogic/qla3xxx.c         |  6 ++-
 .../net/ethernet/qlogic/qlcnic/qlcnic_hw.c    |  3 +-
 drivers/net/ethernet/realtek/8139cp.c         |  3 +-
 drivers/net/ethernet/realtek/8139too.c        |  2 +-
 drivers/net/ethernet/realtek/r8169_main.c     |  9 ++--
 drivers/net/ethernet/rocker/rocker_main.c     |  3 +-
 .../net/ethernet/samsung/sxgbe/sxgbe_main.c   |  3 +-
 drivers/net/ethernet/sfc/ef10.c               |  3 +-
 drivers/net/ethernet/sfc/efx.c                |  7 ++-
 drivers/net/ethernet/sfc/efx_common.c         | 11 ++--
 drivers/net/ethernet/sfc/falcon/efx.c         | 12 +++--
 drivers/net/ethernet/sfc/siena/efx.c          |  3 +-
 drivers/net/ethernet/sfc/siena/efx_common.c   |  7 +--
 drivers/net/ethernet/socionext/sni_ave.c      |  6 ++-
 .../net/ethernet/stmicro/stmmac/stmmac_main.c |  3 +-
 drivers/net/ethernet/sun/cassini.c            |  6 ++-
 drivers/net/ethernet/sun/niu.c                |  3 +-
 drivers/net/ethernet/sun/sunhme.c             | 12 +++--
 drivers/net/ethernet/ti/am65-cpsw-nuss.c      |  4 +-
 drivers/net/ethernet/ti/cpsw.c                |  6 ++-
 drivers/net/ethernet/toshiba/ps3_gelic_net.c  |  3 +-
 drivers/net/ethernet/toshiba/spider_net.c     |  6 ++-
 drivers/net/ethernet/via/via-rhine.c          |  6 ++-
 drivers/net/hyperv/rndis_filter.c             |  7 ++-
 drivers/net/ifb.c                             |  3 +-
 drivers/net/ipvlan/ipvlan_main.c              |  9 +++-
 drivers/net/macsec.c                          | 10 ++--
 drivers/net/macvlan.c                         | 13 +++--
 drivers/net/netdevsim/netdev.c                |  2 +-
 drivers/net/team/team.c                       |  6 +--
 drivers/net/tun.c                             |  8 ++-
 drivers/net/usb/cdc_mbim.c                    |  3 +-
 drivers/net/usb/smsc95xx.c                    |  3 +-
 drivers/net/veth.c                            |  6 ++-
 drivers/net/virtio_net.c                      | 16 ++++--
 drivers/net/vmxnet3/vmxnet3_drv.c             | 11 ++--
 drivers/net/vmxnet3/vmxnet3_ethtool.c         | 18 ++++---
 drivers/net/wireless/ath/ath6kl/main.c        |  9 ++--
 .../net/wireless/intel/iwlwifi/dvm/mac80211.c |  6 ++-
 .../net/wireless/intel/iwlwifi/mvm/mac80211.c |  6 ++-
 drivers/net/wireless/intel/iwlwifi/mvm/tx.c   |  5 +-
 drivers/net/xen-netback/interface.c           |  3 +-
 drivers/staging/octeon/ethernet.c             |  6 ++-
 include/linux/netdev_features_helper.h        |  7 ++-
 net/8021q/vlan.h                              | 17 ++++---
 net/8021q/vlan_dev.c                          | 14 +++--
 net/core/dev.c                                | 51 +++++++++++++------
 net/core/pktgen.c                             |  6 ++-
 net/core/skbuff.c                             |  2 +-
 net/core/sock.c                               |  3 +-
 net/dccp/ipv6.c                               |  5 +-
 net/dsa/slave.c                               |  9 ++--
 net/ethtool/features.c                        |  4 +-
 net/ethtool/ioctl.c                           | 47 ++++++++++++-----
 net/ipv4/esp4_offload.c                       | 16 +++---
 net/ipv4/ip_output.c                          |  3 +-
 net/ipv4/udp_offload.c                        |  6 +--
 net/ipv6/esp6_offload.c                       | 14 ++---
 net/ipv6/ip6_output.c                         |  3 +-
 net/mac80211/iface.c                          |  6 ++-
 net/openvswitch/vport-internal_dev.c          |  3 +-
 net/tls/tls_device.c                          |  2 +-
 net/xfrm/xfrm_device.c                        | 10 ++--
 128 files changed, 641 insertions(+), 363 deletions(-)

diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c
index 4d917762352f..b69b918b2c39 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_main.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c
@@ -218,8 +218,10 @@ static netdev_features_t ipoib_fix_features(struct net_device *dev, netdev_featu
 {
 	struct ipoib_dev_priv *priv = ipoib_priv(dev);
 
-	if (test_bit(IPOIB_FLAG_ADMIN_CM, &priv->flags))
-		features &= ~(NETIF_F_IP_CSUM | NETIF_F_TSO);
+	if (test_bit(IPOIB_FLAG_ADMIN_CM, &priv->flags)) {
+		features &= ~NETIF_F_IP_CSUM;
+		features &= ~NETIF_F_TSO;
+	}
 
 	return features;
 }
@@ -1853,7 +1855,8 @@ static void ipoib_set_dev_features(struct ipoib_dev_priv *priv)
 	priv->kernel_caps = priv->ca->attrs.kernel_cap_flags;
 
 	if (priv->hca_caps & IB_DEVICE_UD_IP_CSUM) {
-		priv->dev->hw_features |= NETIF_F_IP_CSUM | NETIF_F_RXCSUM;
+		priv->dev->hw_features |= NETIF_F_IP_CSUM;
+		priv->dev->hw_features |= NETIF_F_RXCSUM;
 
 		if (priv->kernel_caps & IBK_UD_TSO)
 			priv->dev->hw_features |= NETIF_F_TSO;
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index ca23f18fa7fc..edbeaac3f678 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -1498,8 +1498,8 @@ static void bond_compute_features(struct bonding *bond)
 
 done:
 	bond_dev->vlan_features = vlan_features;
-	bond_dev->hw_enc_features = enc_features | NETIF_F_GSO_ENCAP_ALL |
-				    netdev_tx_vlan_features;
+	bond_dev->hw_enc_features = enc_features | NETIF_F_GSO_ENCAP_ALL;
+	bond_dev->hw_enc_features |= netdev_tx_vlan_features;
 #ifdef CONFIG_XFRM_OFFLOAD
 	bond_dev->hw_enc_features |= xfrm_features;
 #endif /* CONFIG_XFRM_OFFLOAD */
@@ -5765,9 +5765,9 @@ void bond_setup(struct net_device *bond_dev)
 	/* Don't allow bond devices to change network namespaces. */
 	bond_dev->features |= NETIF_F_NETNS_LOCAL;
 
-	bond_dev->hw_features = BOND_VLAN_FEATURES |
-				NETIF_F_HW_VLAN_CTAG_RX |
-				NETIF_F_HW_VLAN_CTAG_FILTER;
+	bond_dev->hw_features = BOND_VLAN_FEATURES;
+	bond_dev->hw_features |= NETIF_F_HW_VLAN_CTAG_RX;
+	bond_dev->hw_features |= NETIF_F_HW_VLAN_CTAG_FILTER;
 
 	bond_dev->hw_features |= NETIF_F_GSO_ENCAP_ALL;
 	bond_dev->features |= bond_dev->hw_features;
diff --git a/drivers/net/ethernet/3com/3c59x.c b/drivers/net/ethernet/3com/3c59x.c
index ccf07667aa5e..900435ea2c10 100644
--- a/drivers/net/ethernet/3com/3c59x.c
+++ b/drivers/net/ethernet/3com/3c59x.c
@@ -1448,7 +1448,8 @@ static int vortex_probe1(struct device *gendev, void __iomem *ioaddr, int irq,
 		if (card_idx < MAX_UNITS &&
 		    ((hw_checksums[card_idx] == -1 && (vp->drv_flags & HAS_HWCKSM)) ||
 				hw_checksums[card_idx] == 1)) {
-			dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG;
+			dev->features |= NETIF_F_IP_CSUM;
+			dev->features |= NETIF_F_SG;
 		}
 	} else
 		dev->netdev_ops =  &vortex_netdev_ops;
diff --git a/drivers/net/ethernet/adaptec/starfire.c b/drivers/net/ethernet/adaptec/starfire.c
index 8f0a6b9c518e..f19be1f78848 100644
--- a/drivers/net/ethernet/adaptec/starfire.c
+++ b/drivers/net/ethernet/adaptec/starfire.c
@@ -684,12 +684,15 @@ static int starfire_init_one(struct pci_dev *pdev,
 
 #ifdef ZEROCOPY
 	/* Starfire can do TCP/UDP checksumming */
-	if (enable_hw_cksum)
-		dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG;
+	if (enable_hw_cksum) {
+		dev->features |= NETIF_F_IP_CSUM;
+		dev->features |= NETIF_F_SG;
+	}
 #endif /* ZEROCOPY */
 
 #ifdef VLAN_SUPPORT
-	dev->features |= NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_HW_VLAN_CTAG_FILTER;
+	dev->features |= NETIF_F_HW_VLAN_CTAG_RX;
+	dev->features |= NETIF_F_HW_VLAN_CTAG_FILTER;
 #endif /* VLAN_RX_KILL_VID */
 #ifdef ADDR_64BITS
 	dev->features |= NETIF_F_HIGHDMA;
diff --git a/drivers/net/ethernet/aeroflex/greth.c b/drivers/net/ethernet/aeroflex/greth.c
index dca85429a0ea..8a2c87778e96 100644
--- a/drivers/net/ethernet/aeroflex/greth.c
+++ b/drivers/net/ethernet/aeroflex/greth.c
@@ -1490,7 +1490,8 @@ static int greth_of_probe(struct platform_device *ofdev)
 	if (greth->gbit_mac) {
 		netdev_hw_features_zero(dev);
 		netdev_hw_features_set_array(dev, &greth_hw_feature_set);
-		dev->features = dev->hw_features | NETIF_F_HIGHDMA;
+		dev->features = dev->hw_features;
+		dev->features |= NETIF_F_HIGHDMA;
 		greth_netdev_ops.ndo_start_xmit = greth_start_xmit_gbit;
 	}
 
diff --git a/drivers/net/ethernet/altera/altera_tse_main.c b/drivers/net/ethernet/altera/altera_tse_main.c
index 8c5828582c21..6dea777c8b98 100644
--- a/drivers/net/ethernet/altera/altera_tse_main.c
+++ b/drivers/net/ethernet/altera/altera_tse_main.c
@@ -1557,7 +1557,8 @@ static int altera_tse_probe(struct platform_device *pdev)
 	 * so it is turned off
 	 */
 	ndev->hw_features &= ~NETIF_F_SG;
-	ndev->features |= ndev->hw_features | NETIF_F_HIGHDMA;
+	ndev->features |= ndev->hw_features;
+	ndev->features |=  NETIF_F_HIGHDMA;
 
 	/* VLAN offloading of tagging, stripping and filtering is not
 	 * supported by hardware, but driver will accommodate the
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c
index 135c6e95b6f1..ce0e2fa3eb63 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c
@@ -2183,7 +2183,8 @@ static netdev_features_t xgbe_fix_features(struct net_device *netdev,
 	struct xgbe_prv_data *pdata = netdev_priv(netdev);
 	netdev_features_t vxlan_base;
 
-	vxlan_base = NETIF_F_GSO_UDP_TUNNEL | NETIF_F_RX_UDP_TUNNEL_PORT;
+	vxlan_base = NETIF_F_GSO_UDP_TUNNEL;
+	vxlan_base |= NETIF_F_RX_UDP_TUNNEL_PORT;
 
 	if (!pdata->hw_feat.vxn)
 		return features;
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-main.c b/drivers/net/ethernet/amd/xgbe/xgbe-main.c
index a5c4fb8aa676..f08f983cc13a 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe-main.c
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-main.c
@@ -382,8 +382,8 @@ int xgbe_config_netdev(struct xgbe_prv_data *pdata)
 		netdev_hw_enc_features_set_array(netdev,
 						 &xgbe_hw_enc_feature_set);
 
-		netdev->hw_features |= NETIF_F_GSO_UDP_TUNNEL |
-				       NETIF_F_GSO_UDP_TUNNEL_CSUM;
+		netdev->hw_features |= NETIF_F_GSO_UDP_TUNNEL;
+		netdev->hw_features |= NETIF_F_GSO_UDP_TUNNEL_CSUM;
 
 		netdev->udp_tunnel_nic_info = xgbe_get_udp_tunnel_info();
 	}
diff --git a/drivers/net/ethernet/apm/xgene-v2/main.c b/drivers/net/ethernet/apm/xgene-v2/main.c
index d022b6db9e06..739110c9f836 100644
--- a/drivers/net/ethernet/apm/xgene-v2/main.c
+++ b/drivers/net/ethernet/apm/xgene-v2/main.c
@@ -648,8 +648,8 @@ static int xge_probe(struct platform_device *pdev)
 	platform_set_drvdata(pdev, pdata);
 	ndev->netdev_ops = &xgene_ndev_ops;
 
-	ndev->features |= NETIF_F_GSO |
-			  NETIF_F_GRO;
+	ndev->features |= NETIF_F_GSO;
+	ndev->features |= NETIF_F_GRO;
 
 	ret = xge_get_resources(pdata);
 	if (ret)
diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_main.c b/drivers/net/ethernet/apm/xgene/xgene_enet_main.c
index 49a35bd4c16d..65bba455a69f 100644
--- a/drivers/net/ethernet/apm/xgene/xgene_enet_main.c
+++ b/drivers/net/ethernet/apm/xgene/xgene_enet_main.c
@@ -2069,7 +2069,8 @@ static int xgene_enet_probe(struct platform_device *pdev)
 	spin_lock_init(&pdata->mac_lock);
 
 	if (pdata->phy_mode == PHY_INTERFACE_MODE_XGMII) {
-		ndev->features |= NETIF_F_TSO | NETIF_F_RXCSUM;
+		ndev->features |= NETIF_F_TSO;
+		ndev->features |= NETIF_F_RXCSUM;
 		spin_lock_init(&pdata->mss_lock);
 	}
 	ndev->hw_features = ndev->features;
diff --git a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
index 1d54ee4f6147..a9c7b29aadf8 100644
--- a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
+++ b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
@@ -2638,8 +2638,9 @@ static int atl1c_init_netdev(struct net_device *netdev, struct pci_dev *pdev)
 	/* TODO: add when ready */
 	netdev_hw_features_zero(netdev);
 	netdev_hw_features_set_array(netdev, &atl1c_hw_feature_set);
-	netdev->features =	netdev->hw_features	|
-				NETIF_F_HW_VLAN_CTAG_TX;
+	netdev->features = netdev->hw_features;
+	netdev->features |= NETIF_F_HW_VLAN_CTAG_TX;
+
 	return 0;
 }
 
diff --git a/drivers/net/ethernet/atheros/atl1e/atl1e_main.c b/drivers/net/ethernet/atheros/atl1e/atl1e_main.c
index 0aaca5a1f87c..d615afd95091 100644
--- a/drivers/net/ethernet/atheros/atl1e/atl1e_main.c
+++ b/drivers/net/ethernet/atheros/atl1e/atl1e_main.c
@@ -2277,9 +2277,11 @@ static int atl1e_init_netdev(struct net_device *netdev, struct pci_dev *pdev)
 
 	netdev_hw_features_zero(netdev);
 	netdev_hw_features_set_array(netdev, &atl1e_hw_feature_set);
-	netdev->features = netdev->hw_features | NETIF_F_HW_VLAN_CTAG_TX;
+	netdev->features = netdev->hw_features;
+	netdev->features |= NETIF_F_HW_VLAN_CTAG_TX;
 	/* not enabled by default */
-	netdev->hw_features |= NETIF_F_RXALL | NETIF_F_RXFCS;
+	netdev->hw_features |= NETIF_F_RXALL;
+	netdev->hw_features |= NETIF_F_RXFCS;
 	return 0;
 }
 
diff --git a/drivers/net/ethernet/broadcom/bnx2.c b/drivers/net/ethernet/broadcom/bnx2.c
index 4a03b8c9f37a..bd548249c2f2 100644
--- a/drivers/net/ethernet/broadcom/bnx2.c
+++ b/drivers/net/ethernet/broadcom/bnx2.c
@@ -7754,10 +7754,14 @@ bnx2_set_features(struct net_device *dev, netdev_features_t features)
 	struct bnx2 *bp = netdev_priv(dev);
 
 	/* TSO with VLAN tag won't work with current firmware */
-	if (features & NETIF_F_HW_VLAN_CTAG_TX)
-		dev->vlan_features |= (dev->hw_features & NETIF_F_ALL_TSO);
-	else
+	if (features & NETIF_F_HW_VLAN_CTAG_TX) {
+		netdev_features_t tso;
+
+		tso = dev->hw_features & NETIF_F_ALL_TSO;
+		dev->vlan_features |= tso;
+	} else {
 		dev->vlan_features &= ~NETIF_F_ALL_TSO;
+	}
 
 	if ((!!(features & NETIF_F_HW_VLAN_CTAG_RX) !=
 	    !!(bp->rx_mode & BNX2_EMAC_RX_MODE_KEEP_VLAN_TAG)) &&
@@ -8592,8 +8596,10 @@ bnx2_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 	netdev_hw_features_zero(dev);
 	netdev_hw_features_set_array(dev, &bnx2_hw_feature_set);
 
-	if (BNX2_CHIP(bp) == BNX2_CHIP_5709)
-		dev->hw_features |= NETIF_F_IPV6_CSUM | NETIF_F_TSO6;
+	if (BNX2_CHIP(bp) == BNX2_CHIP_5709) {
+		dev->hw_features |= NETIF_F_IPV6_CSUM;
+		dev->hw_features |= NETIF_F_TSO6;
+	}
 
 	dev->vlan_features = dev->hw_features;
 	dev->hw_features |= netdev_ctag_vlan_offload_features;
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
index 712b5595bc39..e68d77d9ae50 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
@@ -4912,12 +4912,14 @@ netdev_features_t bnx2x_fix_features(struct net_device *dev,
 		 */
 		if (!(features & NETIF_F_RXCSUM) && !bp->disable_tpa) {
 			features &= ~NETIF_F_RXCSUM;
-			features |= dev->features & NETIF_F_RXCSUM;
+			if (dev->features & NETIF_F_RXCSUM)
+				features |= NETIF_F_RXCSUM;
 		}
 
 		if (changed & NETIF_F_LOOPBACK) {
 			features &= ~NETIF_F_LOOPBACK;
-			features |= dev->features & NETIF_F_LOOPBACK;
+			if (dev->features & NETIF_F_LOOPBACK)
+				features |= NETIF_F_LOOPBACK;
 		}
 	}
 
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
index 845d31294667..1986fde63919 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
@@ -12350,8 +12350,10 @@ static int bnx2x_init_bp(struct bnx2x *bp)
 
 	/* Set TPA flags */
 	if (bp->disable_tpa) {
-		bp->dev->hw_features &= ~(NETIF_F_LRO | NETIF_F_GRO_HW);
-		bp->dev->features &= ~(NETIF_F_LRO | NETIF_F_GRO_HW);
+		bp->dev->hw_features &= ~NETIF_F_LRO;
+		bp->dev->hw_features &= ~NETIF_F_GRO_HW;
+		bp->dev->features &= ~NETIF_F_LRO;
+		bp->dev->features &= ~NETIF_F_GRO_HW;
 	}
 
 	if (CHIP_IS_E1(bp))
@@ -13275,7 +13277,8 @@ static int bnx2x_init_dev(struct bnx2x *bp, struct pci_dev *pdev,
 	 * getting a response to CHANNEL_TLV_ACQUIRE from PF.
 	 */
 
-	dev->features |= dev->hw_features | NETIF_F_HW_VLAN_CTAG_RX;
+	dev->features |= dev->hw_features;
+	dev->features |= NETIF_F_HW_VLAN_CTAG_RX;
 	dev->features |= NETIF_F_HIGHDMA;
 	if (dev->features & NETIF_F_LRO)
 		dev->features &= ~NETIF_F_GRO_HW;
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
index 37e2018fd875..150630a2b207 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
@@ -11179,11 +11179,15 @@ static netdev_features_t bnxt_fix_features(struct net_device *dev,
 	if ((features & NETIF_F_NTUPLE) && !bnxt_rfs_capable(bp))
 		features &= ~NETIF_F_NTUPLE;
 
-	if (bp->flags & BNXT_FLAG_NO_AGG_RINGS)
-		features &= ~(NETIF_F_LRO | NETIF_F_GRO_HW);
+	if (bp->flags & BNXT_FLAG_NO_AGG_RINGS) {
+		features &= ~NETIF_F_LRO;
+		features &= ~NETIF_F_GRO_HW;
+	}
 
-	if (!(bp->flags & BNXT_FLAG_TPA))
-		features &= ~(NETIF_F_LRO | NETIF_F_GRO_HW);
+	if (!(bp->flags & BNXT_FLAG_TPA)) {
+		features &= ~NETIF_F_LRO;
+		features &= ~NETIF_F_GRO_HW;
+	}
 
 	if (!(features & NETIF_F_GRO))
 		features &= ~NETIF_F_GRO_HW;
@@ -13271,8 +13275,10 @@ static int bnxt_get_dflt_rings(struct bnxt *bp, int *max_rx, int *max_tx,
 			return rc;
 		}
 		bp->flags |= BNXT_FLAG_NO_AGG_RINGS;
-		bp->dev->hw_features &= ~(NETIF_F_LRO | NETIF_F_GRO_HW);
-		bp->dev->features &= ~(NETIF_F_LRO | NETIF_F_GRO_HW);
+		bp->dev->hw_features &= ~NETIF_F_LRO;
+		bp->dev->hw_features &= ~NETIF_F_GRO_HW;
+		bp->dev->features &= ~NETIF_F_LRO;
+		bp->dev->features &= ~NETIF_F_GRO_HW;
 		bnxt_set_ring_params(bp);
 	}
 
@@ -13639,14 +13645,16 @@ static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 
 	netdev_gso_partial_features_zero(dev);
 	netdev_gso_partial_features_set_array(dev, &bnxt_gso_partial_feature_set);
-	dev->vlan_features = dev->hw_features | NETIF_F_HIGHDMA;
+	dev->vlan_features = dev->hw_features;
+	dev->vlan_features |= NETIF_F_HIGHDMA;
 	if (bp->fw_cap & BNXT_FW_CAP_VLAN_RX_STRIP)
 		dev->hw_features |= BNXT_HW_FEATURE_VLAN_ALL_RX;
 	if (bp->fw_cap & BNXT_FW_CAP_VLAN_TX_INSERT)
 		dev->hw_features |= BNXT_HW_FEATURE_VLAN_ALL_TX;
 	if (BNXT_SUPPORTS_TPA(bp))
 		dev->hw_features |= NETIF_F_GRO_HW;
-	dev->features |= dev->hw_features | NETIF_F_HIGHDMA;
+	dev->features |= dev->hw_features;
+	dev->features |= NETIF_F_HIGHDMA;
 	if (dev->features & NETIF_F_GRO_HW)
 		dev->features &= ~NETIF_F_LRO;
 	dev->priv_flags |= IFF_UNICAST_FLT;
diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c
index 3a7bb3db4e47..72a9b1f38cab 100644
--- a/drivers/net/ethernet/broadcom/tg3.c
+++ b/drivers/net/ethernet/broadcom/tg3.c
@@ -17725,7 +17725,9 @@ static int tg3_init_one(struct pci_dev *pdev,
 	 * to hardware bugs.
 	 */
 	if (tg3_chip_rev_id(tp) != CHIPREV_ID_5700_B0) {
-		features |= NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_RXCSUM;
+		features |= NETIF_F_SG;
+		features |= NETIF_F_IP_CSUM;
+		features |= NETIF_F_RXCSUM;
 
 		if (tg3_flag(tp, 5755_PLUS))
 			features |= NETIF_F_IPV6_CSUM;
diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c
index 494fe961a49d..4cac5e3a1929 100644
--- a/drivers/net/ethernet/cadence/macb_main.c
+++ b/drivers/net/ethernet/cadence/macb_main.c
@@ -82,7 +82,6 @@ struct sifive_fu540_macb_mgmt {
 #define GEM_MAX_TX_LEN		(unsigned int)(0x3FC0)
 
 #define GEM_MTU_MIN_SIZE	ETH_MIN_MTU
-#define MACB_NETIF_LSO		NETIF_F_TSO
 
 #define MACB_WOL_HAS_MAGIC_PACKET	(0x1 << 0)
 #define MACB_WOL_ENABLED		(0x1 << 1)
@@ -2148,8 +2147,10 @@ static netdev_features_t macb_features_check(struct sk_buff *skb,
 	 * When software supplies two or more payload buffers all payload buffers
 	 * apart from the last must be a multiple of 8 bytes in size.
 	 */
-	if (!IS_ALIGNED(skb_headlen(skb) - hdrlen, MACB_TX_LEN_ALIGN))
-		return features & ~MACB_NETIF_LSO;
+	if (!IS_ALIGNED(skb_headlen(skb) - hdrlen, MACB_TX_LEN_ALIGN)) {
+		features &= ~NETIF_F_TSO;
+		return features;
+	}
 
 	nr_frags = skb_shinfo(skb)->nr_frags;
 	/* No need to check last fragment */
@@ -2157,8 +2158,10 @@ static netdev_features_t macb_features_check(struct sk_buff *skb,
 	for (f = 0; f < nr_frags; f++) {
 		const skb_frag_t *frag = &skb_shinfo(skb)->frags[f];
 
-		if (!IS_ALIGNED(skb_frag_size(frag), MACB_TX_LEN_ALIGN))
-			return features & ~MACB_NETIF_LSO;
+		if (!IS_ALIGNED(skb_frag_size(frag), MACB_TX_LEN_ALIGN)) {
+			features &= ~NETIF_F_TSO;
+			return features;
+		}
 	}
 	return features;
 }
@@ -4052,11 +4055,13 @@ static int macb_init(struct platform_device *pdev)
 
 	/* Check LSO capability */
 	if (GEM_BFEXT(PBUF_LSO, gem_readl(bp, DCFG6)))
-		dev->hw_features |= MACB_NETIF_LSO;
+		dev->hw_features |= NETIF_F_TSO;
 
 	/* Checksum offload is only available on gem with packet buffer */
-	if (macb_is_gem(bp) && !(bp->caps & MACB_CAPS_FIFO_MODE))
-		dev->hw_features |= NETIF_F_HW_CSUM | NETIF_F_RXCSUM;
+	if (macb_is_gem(bp) && !(bp->caps & MACB_CAPS_FIFO_MODE)) {
+		dev->hw_features |= NETIF_F_HW_CSUM;
+		dev->hw_features |= NETIF_F_RXCSUM;
+	}
 	if (bp->caps & MACB_CAPS_SG_DISABLED)
 		dev->hw_features &= ~NETIF_F_SG;
 	dev->features = dev->hw_features;
diff --git a/drivers/net/ethernet/cavium/liquidio/lio_main.c b/drivers/net/ethernet/cavium/liquidio/lio_main.c
index b5a963c9dc03..3271b8e9b392 100644
--- a/drivers/net/ethernet/cavium/liquidio/lio_main.c
+++ b/drivers/net/ethernet/cavium/liquidio/lio_main.c
@@ -3590,8 +3590,8 @@ static int setup_nic_devices(struct octeon_device *octeon_dev)
 		netdev_features_set_array(&liquidio_enc_feature_set,
 					  &lio->enc_dev_capability);
 
-		netdev->hw_enc_features = (lio->enc_dev_capability &
-					   ~NETIF_F_LRO);
+		netdev->hw_enc_features = lio->enc_dev_capability;
+		netdev->hw_enc_features &= ~NETIF_F_LRO;
 
 		netdev->udp_tunnel_nic_info = &liquidio_udp_tunnels;
 
@@ -3601,12 +3601,12 @@ static int setup_nic_devices(struct octeon_device *octeon_dev)
 		/* Add any unchangeable hw features */
 		lio->dev_capability |= netdev_ctag_vlan_features;
 
-		netdev->features = (lio->dev_capability & ~NETIF_F_LRO);
+		netdev->features = lio->dev_capability;
+		netdev->features &= ~NETIF_F_LRO;
 
 		netdev->hw_features = lio->dev_capability;
 		/*HW_VLAN_RX and HW_VLAN_FILTER is always on*/
-		netdev->hw_features = netdev->hw_features &
-			~NETIF_F_HW_VLAN_CTAG_RX;
+		netdev->hw_features &= ~NETIF_F_HW_VLAN_CTAG_RX;
 
 		/* MTU range: 68 - 16000 */
 		netdev->min_mtu = LIO_MIN_MTU_SIZE;
diff --git a/drivers/net/ethernet/cavium/liquidio/lio_vf_main.c b/drivers/net/ethernet/cavium/liquidio/lio_vf_main.c
index 23524066fa9a..688a6c4931b9 100644
--- a/drivers/net/ethernet/cavium/liquidio/lio_vf_main.c
+++ b/drivers/net/ethernet/cavium/liquidio/lio_vf_main.c
@@ -1850,9 +1850,10 @@ static netdev_features_t liquidio_fix_features(struct net_device *netdev,
 static int liquidio_set_features(struct net_device *netdev,
 				 netdev_features_t features)
 {
+	netdev_features_t changed = netdev->features ^ features;
 	struct lio *lio = netdev_priv(netdev);
 
-	if (!((netdev->features ^ features) & NETIF_F_LRO))
+	if (!(changed & NETIF_F_LRO))
 		return 0;
 
 	if ((features & NETIF_F_LRO) && (lio->dev_capability & NETIF_F_LRO))
@@ -2121,15 +2122,16 @@ static int setup_nic_devices(struct octeon_device *octeon_dev)
 		netdev_features_set_array(&lio_enc_feature_set,
 					  &lio->enc_dev_capability);
 
-		netdev->hw_enc_features =
-		    (lio->enc_dev_capability & ~NETIF_F_LRO);
+		netdev->hw_enc_features = lio->enc_dev_capability;
+		netdev->hw_enc_features &= ~NETIF_F_LRO;
 		netdev->udp_tunnel_nic_info = &liquidio_udp_tunnels;
 
 		netdev->vlan_features = lio->dev_capability;
 		/* Add any unchangeable hw features */
 		lio->dev_capability |= netdev_ctag_vlan_features;
 
-		netdev->features = (lio->dev_capability & ~NETIF_F_LRO);
+		netdev->features = lio->dev_capability;
+		netdev->features &= ~NETIF_F_LRO;
 
 		netdev->hw_features = lio->dev_capability;
 		netdev->hw_features &= ~NETIF_F_HW_VLAN_CTAG_RX;
diff --git a/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c b/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c
index 80f65f491b3f..7bbec0a182c3 100644
--- a/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c
+++ b/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c
@@ -3320,11 +3320,12 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 		netdev->mem_end = mmio_start + mmio_len - 1;
 		netdev_hw_features_zero(netdev);
 		netdev_hw_features_set_array(netdev, &cxgb_hw_feature_set);
-		netdev->features |= netdev->hw_features |
-				    NETIF_F_HW_VLAN_CTAG_TX;
+		netdev->features |= netdev->hw_features;
+		netdev->features |= NETIF_F_HW_VLAN_CTAG_TX;
 		netdev_features_zero(&vlan_feat);
 		netdev_features_set_array(&cxgb_vlan_feature_set, &vlan_feat);
-		netdev->vlan_features |= netdev->features & vlan_feat;
+		vlan_feat &= netdev->features;
+		netdev->vlan_features |= vlan_feat;
 
 		netdev->features |= NETIF_F_HIGHDMA;
 
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
index 7e61049247b9..4df2af4c2e05 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
@@ -1283,8 +1283,10 @@ static int cxgb_set_features(struct net_device *dev, netdev_features_t features)
 	err = t4_set_rxmode(pi->adapter, pi->adapter->mbox, pi->viid,
 			    pi->viid_mirror, -1, -1, -1, -1,
 			    !!(features & NETIF_F_HW_VLAN_CTAG_RX), true);
-	if (unlikely(err))
-		dev->features = features ^ NETIF_F_HW_VLAN_CTAG_RX;
+	if (unlikely(err)) {
+		dev->features = features;
+		dev->features ^= NETIF_F_HW_VLAN_CTAG_RX;
+	}
 	return err;
 }
 
diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c
index 2d6e1b42b36b..0d1d361fc246 100644
--- a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c
+++ b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c
@@ -3092,7 +3092,8 @@ static int cxgb4vf_pci_probe(struct pci_dev *pdev,
 					  &tso_features);
 		netdev->hw_features = tso_features;
 		netdev_hw_features_set_array(netdev, &cxgb4vf_hw_feature_set);
-		netdev->features = netdev->hw_features | NETIF_F_HIGHDMA;
+		netdev->features = netdev->hw_features;
+		netdev->features |= NETIF_F_HIGHDMA;
 		vlan_features = tso_features;
 		netdev_features_set_array(&cxgb4vf_vlan_feature_set,
 					  &vlan_features);
diff --git a/drivers/net/ethernet/cisco/enic/enic_main.c b/drivers/net/ethernet/cisco/enic/enic_main.c
index 061375f34d5d..4f851d446716 100644
--- a/drivers/net/ethernet/cisco/enic/enic_main.c
+++ b/drivers/net/ethernet/cisco/enic/enic_main.c
@@ -2901,8 +2901,10 @@ static int enic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 		enic->loop_tag = enic->config.loop_tag;
 		dev_info(dev, "loopback tag=0x%04x\n", enic->loop_tag);
 	}
-	if (ENIC_SETTING(enic, TXCSUM))
-		netdev->hw_features |= NETIF_F_SG | NETIF_F_HW_CSUM;
+	if (ENIC_SETTING(enic, TXCSUM)) {
+		netdev->hw_features |= NETIF_F_SG;
+		netdev->hw_features |= NETIF_F_HW_CSUM;
+	}
 	if (ENIC_SETTING(enic, TSO)) {
 		netdev->hw_features |= netdev_general_tso_features;
 		netdev->hw_features |= NETIF_F_TSO_ECN;
diff --git a/drivers/net/ethernet/cortina/gemini.c b/drivers/net/ethernet/cortina/gemini.c
index d2b0296b426a..dcadafd7cdaa 100644
--- a/drivers/net/ethernet/cortina/gemini.c
+++ b/drivers/net/ethernet/cortina/gemini.c
@@ -2471,7 +2471,8 @@ static int gemini_ethernet_port_probe(struct platform_device *pdev)
 	gmac_clear_hw_stats(netdev);
 
 	netdev->hw_features = GMAC_OFFLOAD_FEATURES;
-	netdev->features |= GMAC_OFFLOAD_FEATURES | NETIF_F_GRO;
+	netdev->features |= GMAC_OFFLOAD_FEATURES;
+	netdev->features |= NETIF_F_GRO;
 	/* We can handle jumbo frames up to 10236 bytes so, let's accept
 	 * payloads of 10236 bytes minus VLAN and ethernet header
 	 */
diff --git a/drivers/net/ethernet/davicom/dm9000.c b/drivers/net/ethernet/davicom/dm9000.c
index 0985ab216566..363490713825 100644
--- a/drivers/net/ethernet/davicom/dm9000.c
+++ b/drivers/net/ethernet/davicom/dm9000.c
@@ -1644,7 +1644,8 @@ dm9000_probe(struct platform_device *pdev)
 
 	/* dm9000a/b are capable of hardware checksum offload */
 	if (db->type == TYPE_DM9000A || db->type == TYPE_DM9000B) {
-		ndev->hw_features = NETIF_F_RXCSUM | NETIF_F_IP_CSUM;
+		ndev->hw_features = NETIF_F_RXCSUM;
+		ndev->hw_features |= NETIF_F_IP_CSUM;
 		ndev->features |= ndev->hw_features;
 	}
 
diff --git a/drivers/net/ethernet/faraday/ftgmac100.c b/drivers/net/ethernet/faraday/ftgmac100.c
index 8c95ad9df5e5..3cdc5d827f14 100644
--- a/drivers/net/ethernet/faraday/ftgmac100.c
+++ b/drivers/net/ethernet/faraday/ftgmac100.c
@@ -1953,8 +1953,10 @@ static int ftgmac100_probe(struct platform_device *pdev)
 	if (priv->use_ncsi && of_device_is_compatible(np, "aspeed,ast2600-mac"))
 		netdev->hw_features &= ~NETIF_F_HW_CSUM;
 
-	if (np && of_get_property(np, "no-hw-checksum", NULL))
-		netdev->hw_features &= ~(NETIF_F_HW_CSUM | NETIF_F_RXCSUM);
+	if (np && of_get_property(np, "no-hw-checksum", NULL)) {
+		netdev->hw_features &= ~NETIF_F_HW_CSUM;
+		netdev->hw_features &= ~NETIF_F_RXCSUM;
+	}
 	netdev->features |= netdev->hw_features;
 
 	/* register network device */
diff --git a/drivers/net/ethernet/freescale/gianfar.c b/drivers/net/ethernet/freescale/gianfar.c
index d9b1928d1987..dcf30e6dd012 100644
--- a/drivers/net/ethernet/freescale/gianfar.c
+++ b/drivers/net/ethernet/freescale/gianfar.c
@@ -161,7 +161,8 @@ static void gfar_rx_offload_en(struct gfar_private *priv)
 	/* set this when rx hw offload (TOE) functions are being used */
 	priv->uses_rxfcb = 0;
 
-	if (priv->ndev->features & (NETIF_F_RXCSUM | NETIF_F_HW_VLAN_CTAG_RX))
+	if (priv->ndev->features & NETIF_F_RXCSUM ||
+	    priv->ndev->features & NETIF_F_HW_VLAN_CTAG_RX)
 		priv->uses_rxfcb = 1;
 
 	if (priv->hwts_rx_en || priv->rx_filer_enable)
diff --git a/drivers/net/ethernet/freescale/gianfar_ethtool.c b/drivers/net/ethernet/freescale/gianfar_ethtool.c
index b4b1b7b7143f..8c541070ffe0 100644
--- a/drivers/net/ethernet/freescale/gianfar_ethtool.c
+++ b/drivers/net/ethernet/freescale/gianfar_ethtool.c
@@ -511,7 +511,8 @@ int gfar_set_features(struct net_device *dev, netdev_features_t features)
 	struct gfar_private *priv = netdev_priv(dev);
 	int err = 0;
 
-	if (!(changed & (netdev_ctag_vlan_offload_features | NETIF_F_RXCSUM)))
+	if (!(changed & netdev_ctag_vlan_offload_features) &&
+	    !(changed & NETIF_F_RXCSUM))
 		return 0;
 
 	while (test_and_set_bit_lock(GFAR_RESETTING, &priv->state))
diff --git a/drivers/net/ethernet/fungible/funeth/funeth_main.c b/drivers/net/ethernet/fungible/funeth/funeth_main.c
index 537daf19f7f6..4bfc6dab65f4 100644
--- a/drivers/net/ethernet/fungible/funeth/funeth_main.c
+++ b/drivers/net/ethernet/fungible/funeth/funeth_main.c
@@ -1788,12 +1788,15 @@ static int fun_create_netdev(struct fun_ethdev *ed, unsigned int portid)
 	netdev_features_set_array(&fun_vlan_feature_set, &vlan_feat);
 
 	netdev_hw_features_set_array(netdev, &fun_hw_feature_set);
-	if (fp->port_caps & FUN_PORT_CAP_OFFLOADS)
-		netdev->hw_features |= NETIF_F_HW_CSUM | tso_flags;
+	if (fp->port_caps & FUN_PORT_CAP_OFFLOADS) {
+		netdev->hw_features |= NETIF_F_HW_CSUM;
+		netdev->hw_features |= tso_flags;
+	}
 	if (fp->port_caps & FUN_PORT_CAP_ENCAP_OFFLOADS)
 		netdev->hw_features |= gso_encap_flags;
 
-	netdev->features |= netdev->hw_features | NETIF_F_HIGHDMA;
+	netdev->features |= netdev->hw_features;
+	netdev->features |= NETIF_F_HIGHDMA;
 	netdev->vlan_features = netdev->features & vlan_feat;
 	netdev->mpls_features = netdev->vlan_features;
 	netdev->hw_enc_features = netdev->hw_features;
diff --git a/drivers/net/ethernet/hisilicon/hix5hd2_gmac.c b/drivers/net/ethernet/hisilicon/hix5hd2_gmac.c
index d7e62eca050f..69579d94f4d5 100644
--- a/drivers/net/ethernet/hisilicon/hix5hd2_gmac.c
+++ b/drivers/net/ethernet/hisilicon/hix5hd2_gmac.c
@@ -1236,7 +1236,8 @@ static int hix5hd2_dev_probe(struct platform_device *pdev)
 	if (HAS_CAP_TSO(priv->hw_cap))
 		ndev->hw_features |= NETIF_F_SG;
 
-	ndev->features |= ndev->hw_features | NETIF_F_HIGHDMA;
+	ndev->features |= ndev->hw_features;
+	ndev->features |= NETIF_F_HIGHDMA;
 	ndev->vlan_features |= ndev->features;
 
 	ret = hix5hd2_init_hw_desc_queue(priv);
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
index 3213322fcb08..c59026807723 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
@@ -2411,7 +2411,7 @@ static int hns3_nic_set_features(struct net_device *netdev,
 	bool enable;
 	int ret;
 
-	if (changed & (NETIF_F_GRO_HW) && h->ae_algo->ops->set_gro_en) {
+	if (changed & NETIF_F_GRO_HW && h->ae_algo->ops->set_gro_en) {
 		enable = !!(features & NETIF_F_GRO_HW);
 		ret = h->ae_algo->ops->set_gro_en(h, enable);
 		if (ret)
@@ -3284,6 +3284,7 @@ static void hns3_set_default_feature(struct net_device *netdev)
 	struct pci_dev *pdev = h->pdev;
 	struct hnae3_ae_dev *ae_dev = pci_get_drvdata(pdev);
 	netdev_features_t vlan_off_features;
+	netdev_features_t features;
 
 	netdev->priv_flags |= IFF_UNICAST_FLT;
 
@@ -3319,9 +3320,11 @@ static void hns3_set_default_feature(struct net_device *netdev)
 	netdev_features_zero(&vlan_off_features);
 	netdev_features_set_array(&hns3_vlan_off_feature_set,
 				  &vlan_off_features);
-	netdev->vlan_features |= netdev->features & ~vlan_off_features;
+	features = netdev->features & ~vlan_off_features;
+	netdev->vlan_features |= features;
 
-	netdev->hw_enc_features |= netdev->vlan_features | NETIF_F_TSO_MANGLEID;
+	netdev->hw_enc_features |= netdev->vlan_features;
+	netdev->hw_enc_features |= NETIF_F_TSO_MANGLEID;
 }
 
 static int hns3_alloc_buffer(struct hns3_enet_ring *ring,
diff --git a/drivers/net/ethernet/huawei/hinic/hinic_main.c b/drivers/net/ethernet/huawei/hinic/hinic_main.c
index b8db3b423a5b..80d14a014d2d 100644
--- a/drivers/net/ethernet/huawei/hinic/hinic_main.c
+++ b/drivers/net/ethernet/huawei/hinic/hinic_main.c
@@ -948,7 +948,8 @@ static void netdev_features_init(struct net_device *netdev)
 
 	netdev->vlan_features = netdev->hw_features;
 
-	netdev->features = netdev->hw_features | NETIF_F_HW_VLAN_CTAG_FILTER;
+	netdev->features = netdev->hw_features;
+	netdev->features |= NETIF_F_HW_VLAN_CTAG_FILTER;
 
 	netdev_hw_enc_features_zero(netdev);
 	netdev_hw_enc_features_set_array(netdev, &hinic_hw_enc_feature_set);
diff --git a/drivers/net/ethernet/ibm/emac/core.c b/drivers/net/ethernet/ibm/emac/core.c
index 6b026ba0f262..17b5e0806aa6 100644
--- a/drivers/net/ethernet/ibm/emac/core.c
+++ b/drivers/net/ethernet/ibm/emac/core.c
@@ -3177,7 +3177,8 @@ static int emac_probe(struct platform_device *ofdev)
 	if (dev->tah_dev) {
 		netdev_hw_features_zero(ndev);
 		netdev_hw_features_set_array(ndev, &emac_hw_feature_set);
-		ndev->features |= ndev->hw_features | NETIF_F_RXCSUM;
+		ndev->features |= ndev->hw_features;
+		ndev->features |= NETIF_F_RXCSUM;
 	}
 	ndev->watchdog_timeo = 5 * HZ;
 	if (emac_phy_supports_gige(dev->phy_mode)) {
diff --git a/drivers/net/ethernet/ibm/ibmveth.c b/drivers/net/ethernet/ibm/ibmveth.c
index 32ad4087a43d..3533ae7c92f7 100644
--- a/drivers/net/ethernet/ibm/ibmveth.c
+++ b/drivers/net/ethernet/ibm/ibmveth.c
@@ -906,10 +906,10 @@ static int ibmveth_set_features(struct net_device *dev,
 
 	if (rx_csum != adapter->rx_csum) {
 		rc1 = ibmveth_set_csum_offload(dev, rx_csum);
-		if (rc1 && !adapter->rx_csum)
-			dev->features =
-				features & ~(NETIF_F_CSUM_MASK |
-					     NETIF_F_RXCSUM);
+		if (rc1 && !adapter->rx_csum) {
+			dev->features = features & ~NETIF_F_CSUM_MASK;
+			dev->features &= ~NETIF_F_RXCSUM;
+		}
 	}
 
 	if (large_send != adapter->large_send) {
diff --git a/drivers/net/ethernet/ibm/ibmvnic.c b/drivers/net/ethernet/ibm/ibmvnic.c
index 43f12a96cf90..598f5b9d9025 100644
--- a/drivers/net/ethernet/ibm/ibmvnic.c
+++ b/drivers/net/ethernet/ibm/ibmvnic.c
@@ -4900,10 +4900,10 @@ static void send_control_ip_offload(struct ibmvnic_adapter *adapter)
 		/* disable features no longer supported */
 		adapter->netdev->features &= adapter->netdev->hw_features;
 		/* turn on features now supported if previously enabled */
-		tmp = (old_hw_features ^ adapter->netdev->hw_features) &
-			adapter->netdev->hw_features;
-		adapter->netdev->features |=
-				tmp & adapter->netdev->wanted_features;
+		tmp = old_hw_features ^ adapter->netdev->hw_features;
+		tmp &= adapter->netdev->hw_features;
+		tmp &= adapter->netdev->wanted_features;
+		adapter->netdev->features |= tmp;
 	}
 
 	memset(&crq, 0, sizeof(crq));
diff --git a/drivers/net/ethernet/intel/e100.c b/drivers/net/ethernet/intel/e100.c
index 11a884aa5082..2809f6c0f69a 100644
--- a/drivers/net/ethernet/intel/e100.c
+++ b/drivers/net/ethernet/intel/e100.c
@@ -2805,7 +2805,7 @@ static int e100_set_features(struct net_device *netdev,
 	struct nic *nic = netdev_priv(netdev);
 	netdev_features_t changed = features ^ netdev->features;
 
-	if (!(changed & (NETIF_F_RXFCS | NETIF_F_RXALL)))
+	if (!(changed & NETIF_F_RXFCS && changed & NETIF_F_RXALL))
 		return 0;
 
 	netdev->features = features;
diff --git a/drivers/net/ethernet/intel/e1000/e1000_main.c b/drivers/net/ethernet/intel/e1000/e1000_main.c
index 07670cabf19f..9564fdef837d 100644
--- a/drivers/net/ethernet/intel/e1000/e1000_main.c
+++ b/drivers/net/ethernet/intel/e1000/e1000_main.c
@@ -810,7 +810,7 @@ static int e1000_set_features(struct net_device *netdev,
 	if (changed & NETIF_F_HW_VLAN_CTAG_RX)
 		e1000_vlan_mode(netdev, features);
 
-	if (!(changed & (NETIF_F_RXCSUM | NETIF_F_RXALL)))
+	if (!(changed & NETIF_F_RXCSUM && changed & NETIF_F_RXALL))
 		return 0;
 
 	netdev->features = features;
diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c
index b905eced9d91..d7d628af7435 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_main.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
@@ -13689,14 +13689,15 @@ static int i40e_config_netdev(struct i40e_vsi *vsi)
 	netdev->hw_enc_features |= hw_enc_features;
 
 	/* record features VLANs can make use of */
-	netdev->vlan_features |= hw_enc_features | NETIF_F_TSO_MANGLEID;
+	netdev->vlan_features |= hw_enc_features;
+	netdev->vlan_features |= NETIF_F_TSO_MANGLEID;
 
 	netdev_features_zero(&gso_partial_features);
 	netdev_features_set_array(&i40e_gso_partial_feature_set,
 				  &gso_partial_features);
 	netdev->gso_partial_features = gso_partial_features;
-	netdev->features |= NETIF_F_GSO_PARTIAL |
-			    gso_partial_features;
+	netdev->features |= NETIF_F_GSO_PARTIAL;
+	netdev->features |= gso_partial_features;
 
 	netdev_mpls_features_set_array(netdev, &i40e_mpls_feature_set);
 	netdev->mpls_features |= gso_partial_features;
@@ -13706,12 +13707,15 @@ static int i40e_config_netdev(struct i40e_vsi *vsi)
 
 	hw_features = hw_enc_features | netdev_ctag_vlan_offload_features;
 
-	if (!(pf->flags & I40E_FLAG_MFP_ENABLED))
-		hw_features |= NETIF_F_NTUPLE | NETIF_F_HW_TC;
+	if (!(pf->flags & I40E_FLAG_MFP_ENABLED)) {
+		hw_features |= NETIF_F_NTUPLE;
+		hw_features |= NETIF_F_HW_TC;
+	}
 
 	netdev->hw_features |= hw_features;
 
-	netdev->features |= hw_features | NETIF_F_HW_VLAN_CTAG_FILTER;
+	netdev->features |= hw_features;
+	netdev->features |= NETIF_F_HW_VLAN_CTAG_FILTER;
 	netdev->hw_enc_features |= NETIF_F_TSO_MANGLEID;
 
 	netdev->features &= ~NETIF_F_HW_TC;
diff --git a/drivers/net/ethernet/intel/iavf/iavf_main.c b/drivers/net/ethernet/intel/iavf/iavf_main.c
index efbd889eea1a..95dd5a16b553 100644
--- a/drivers/net/ethernet/intel/iavf/iavf_main.c
+++ b/drivers/net/ethernet/intel/iavf/iavf_main.c
@@ -4631,7 +4631,8 @@ int iavf_process_config(struct iavf_adapter *adapter)
 		netdev->hw_enc_features |= hw_enc_features;
 	}
 	/* record features VLANs can make use of */
-	netdev->vlan_features |= hw_enc_features | NETIF_F_TSO_MANGLEID;
+	netdev->vlan_features |= hw_enc_features;
+	netdev->vlan_features |= NETIF_F_TSO_MANGLEID;
 
 	/* Write features and hw_features separately to avoid polluting
 	 * with, or dropping, features that are set when we registered.
@@ -4647,10 +4648,12 @@ int iavf_process_config(struct iavf_adapter *adapter)
 	if (vfres->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_USO)
 		hw_features |= NETIF_F_GSO_UDP_L4;
 
-	netdev->hw_features |= hw_features | hw_vlan_features;
+	netdev->hw_features |= hw_features;
+	netdev->hw_features |= hw_vlan_features;
 	vlan_features = iavf_get_netdev_vlan_features(adapter);
 
-	netdev->features |= hw_features | vlan_features;
+	netdev->features |= hw_features;
+	netdev->features |= vlan_features;
 
 	if (vfres->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_VLAN)
 		netdev->features |= NETIF_F_HW_VLAN_CTAG_FILTER;
diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c
index 5c9333da4dfc..107caaac78ea 100644
--- a/drivers/net/ethernet/intel/ice/ice_main.c
+++ b/drivers/net/ethernet/intel/ice/ice_main.c
@@ -3360,11 +3360,12 @@ static void ice_set_netdev_features(struct net_device *netdev)
 	netdev_features_zero(&tso_features);
 	netdev_features_set_array(&ice_tso_feature_set, &tso_features);
 
-	netdev->gso_partial_features |= NETIF_F_GSO_UDP_TUNNEL_CSUM |
-					NETIF_F_GSO_GRE_CSUM;
+	netdev->gso_partial_features |= NETIF_F_GSO_UDP_TUNNEL_CSUM;
+	netdev->gso_partial_features |= NETIF_F_GSO_GRE_CSUM;
 	/* set features that user can change */
-	netdev->hw_features = dflt_features | csumo_features |
-			      vlano_features | tso_features;
+	netdev->hw_features = dflt_features | csumo_features;
+	netdev->hw_features |= vlano_features;
+	netdev->hw_features |= tso_features;
 
 	/* add support for HW_CSUM on packets with MPLS header */
 	netdev_mpls_features_zero(netdev);
@@ -3377,10 +3378,12 @@ static void ice_set_netdev_features(struct net_device *netdev)
 	netdev->hw_features |= NETIF_F_LOOPBACK;
 
 	/* encap and VLAN devices inherit default, csumo and tso features */
-	netdev->hw_enc_features |= dflt_features | csumo_features |
-				   tso_features;
-	netdev->vlan_features |= dflt_features | csumo_features |
-				 tso_features;
+	netdev->hw_enc_features |= dflt_features;
+	netdev->hw_enc_features |= csumo_features;
+	netdev->hw_enc_features |= tso_features;
+	netdev->vlan_features |= dflt_features;
+	netdev->vlan_features |= csumo_features;
+	netdev->vlan_features |= tso_features;
 
 	/* advertise support but don't enable by default since only one type of
 	 * VLAN offload can be enabled at a time (i.e. CTAG or STAG). When one
@@ -5897,14 +5900,15 @@ ice_set_vlan_filtering_features(struct ice_vsi *vsi, netdev_features_t features)
 static int
 ice_set_vlan_features(struct net_device *netdev, netdev_features_t features)
 {
-	netdev_features_t current_vlan_features, requested_vlan_features;
+	netdev_features_t current_vlan_features, requested_vlan_features, diff;
 	struct ice_netdev_priv *np = netdev_priv(netdev);
 	struct ice_vsi *vsi = np->vsi;
 	int err;
 
 	current_vlan_features = netdev->features & NETIF_VLAN_OFFLOAD_FEATURES;
 	requested_vlan_features = features & NETIF_VLAN_OFFLOAD_FEATURES;
-	if (current_vlan_features ^ requested_vlan_features) {
+	diff = current_vlan_features ^ requested_vlan_features;
+	if (diff) {
 		err = ice_set_vlan_offload_features(vsi, features);
 		if (err)
 			return err;
@@ -5913,7 +5917,8 @@ ice_set_vlan_features(struct net_device *netdev, netdev_features_t features)
 	current_vlan_features = netdev->features &
 		NETIF_VLAN_FILTERING_FEATURES;
 	requested_vlan_features = features & NETIF_VLAN_FILTERING_FEATURES;
-	if (current_vlan_features ^ requested_vlan_features) {
+	diff = current_vlan_features ^ requested_vlan_features;
+	if (diff) {
 		err = ice_set_vlan_filtering_features(vsi, features);
 		if (err)
 			return err;
diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c
index 578663a47c93..3d0af1c6d13e 100644
--- a/drivers/net/ethernet/intel/igb/igb_main.c
+++ b/drivers/net/ethernet/intel/igb/igb_main.c
@@ -2455,7 +2455,7 @@ static int igb_set_features(struct net_device *netdev,
 	if (changed & NETIF_F_HW_VLAN_CTAG_RX)
 		igb_vlan_mode(netdev, features);
 
-	if (!(changed & (NETIF_F_RXALL | NETIF_F_NTUPLE)))
+	if (!(changed & NETIF_F_RXALL) && !(changed & NETIF_F_NTUPLE))
 		return 0;
 
 	if (!(features & NETIF_F_NTUPLE)) {
@@ -3298,8 +3298,10 @@ static int igb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 	 */
 	netdev_active_features_set_array(netdev, &igb_feature_set);
 
-	if (hw->mac.type >= e1000_82576)
-		netdev->features |= NETIF_F_SCTP_CRC | NETIF_F_GSO_UDP_L4;
+	if (hw->mac.type >= e1000_82576) {
+		netdev->features |= NETIF_F_SCTP_CRC;
+		netdev->features |= NETIF_F_GSO_UDP_L4;
+	}
 
 	if (hw->mac.type >= e1000_i350)
 		netdev->features |= NETIF_F_HW_TC;
@@ -3307,7 +3309,8 @@ static int igb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 	netdev_features_zero(&gso_partial_features);
 	netdev_features_set_array(&igb_feature_set, &gso_partial_features);
 	netdev->gso_partial_features = gso_partial_features;
-	netdev->features |= NETIF_F_GSO_PARTIAL | gso_partial_features;
+	netdev->features |= NETIF_F_GSO_PARTIAL;
+	netdev->features |= gso_partial_features;
 
 	/* copy netdev features into list of user selectable features */
 	netdev->hw_features |= netdev->features;
@@ -3319,7 +3322,8 @@ static int igb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 
 	netdev->features |= NETIF_F_HIGHDMA;
 
-	netdev->vlan_features |= netdev->features | NETIF_F_TSO_MANGLEID;
+	netdev->vlan_features |= netdev->features;
+	netdev->vlan_features |= NETIF_F_TSO_MANGLEID;
 	netdev->mpls_features |= NETIF_F_HW_CSUM;
 	netdev->hw_enc_features |= netdev->vlan_features;
 
diff --git a/drivers/net/ethernet/intel/igbvf/netdev.c b/drivers/net/ethernet/intel/igbvf/netdev.c
index 07c725474e32..6994f573fadf 100644
--- a/drivers/net/ethernet/intel/igbvf/netdev.c
+++ b/drivers/net/ethernet/intel/igbvf/netdev.c
@@ -2794,11 +2794,14 @@ static int igbvf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 				  &gso_partial_features);
 
 	netdev->gso_partial_features = gso_partial_features;
-	netdev->hw_features |= NETIF_F_GSO_PARTIAL | gso_partial_features;
+	netdev->hw_features |= NETIF_F_GSO_PARTIAL;
+	netdev->hw_features |= gso_partial_features;
 
-	netdev->features = netdev->hw_features | NETIF_F_HIGHDMA;
+	netdev->features = netdev->hw_features;
+	netdev->features |= NETIF_F_HIGHDMA;
 
-	netdev->vlan_features |= netdev->features | NETIF_F_TSO_MANGLEID;
+	netdev->vlan_features |= netdev->features;
+	netdev->vlan_features |= NETIF_F_TSO_MANGLEID;
 	netdev->mpls_features |= NETIF_F_HW_CSUM;
 	netdev->hw_enc_features |= netdev->vlan_features;
 
diff --git a/drivers/net/ethernet/intel/igc/igc_main.c b/drivers/net/ethernet/intel/igc/igc_main.c
index e5b97822e191..805243e7c4cb 100644
--- a/drivers/net/ethernet/intel/igc/igc_main.c
+++ b/drivers/net/ethernet/intel/igc/igc_main.c
@@ -4958,7 +4958,7 @@ static int igc_set_features(struct net_device *netdev,
 		igc_vlan_mode(netdev, features);
 
 	/* Add VLAN support */
-	if (!(changed & (NETIF_F_RXALL | NETIF_F_NTUPLE)))
+	if (!(changed & NETIF_F_RXALL) && !(changed & NETIF_F_NTUPLE))
 		return 0;
 
 	if (!(features & NETIF_F_NTUPLE))
@@ -6335,7 +6335,8 @@ static int igc_probe(struct pci_dev *pdev,
 	netdev_features_set_array(&igc_gso_partial_feature_set,
 				  &gso_partial_features);
 	netdev->gso_partial_features = gso_partial_features;
-	netdev->features |= NETIF_F_GSO_PARTIAL | gso_partial_features;
+	netdev->features |= NETIF_F_GSO_PARTIAL;
+	netdev->features |= gso_partial_features;
 
 	/* setup the private structure */
 	err = igc_sw_init(adapter);
@@ -6350,7 +6351,8 @@ static int igc_probe(struct pci_dev *pdev,
 
 	netdev->features |= NETIF_F_HIGHDMA;
 
-	netdev->vlan_features |= netdev->features | NETIF_F_TSO_MANGLEID;
+	netdev->vlan_features |= netdev->features;
+	netdev->vlan_features |= NETIF_F_TSO_MANGLEID;
 	netdev->mpls_features |= NETIF_F_HW_CSUM;
 	netdev->hw_enc_features |= netdev->vlan_features;
 
diff --git a/drivers/net/ethernet/intel/ixgb/ixgb_main.c b/drivers/net/ethernet/intel/ixgb/ixgb_main.c
index c3ae375f04dd..d23b7a10d62f 100644
--- a/drivers/net/ethernet/intel/ixgb/ixgb_main.c
+++ b/drivers/net/ethernet/intel/ixgb/ixgb_main.c
@@ -313,7 +313,7 @@ ixgb_set_features(struct net_device *netdev, netdev_features_t features)
 	struct ixgb_adapter *adapter = netdev_priv(netdev);
 	netdev_features_t changed = features ^ netdev->features;
 
-	if (!(changed & (NETIF_F_RXCSUM|NETIF_F_HW_VLAN_CTAG_RX)))
+	if (!(changed & NETIF_F_RXCSUM) && !(changed & NETIF_F_HW_VLAN_CTAG_RX))
 		return 0;
 
 	adapter->rx_csum = !!(features & NETIF_F_RXCSUM);
@@ -438,8 +438,8 @@ ixgb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 
 	netdev_hw_features_zero(netdev);
 	netdev_hw_features_set_array(netdev, &ixgb_hw_feature_set);
-	netdev->features = netdev->hw_features |
-			   NETIF_F_HW_VLAN_CTAG_FILTER;
+	netdev->features = netdev->hw_features;
+	netdev->features |= NETIF_F_HW_VLAN_CTAG_FILTER;
 	netdev->hw_features |= NETIF_F_RXCSUM;
 
 	netdev->features |= NETIF_F_HIGHDMA;
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index db008c8281ed..0b6b5cfa84df 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -8828,7 +8828,8 @@ netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *skb,
 #ifdef IXGBE_FCOE
 	/* setup tx offload for FCoE */
 	if ((protocol == htons(ETH_P_FCOE)) &&
-	    (tx_ring->netdev->features & (NETIF_F_FSO | NETIF_F_FCOE_CRC))) {
+	    (tx_ring->netdev->features & NETIF_F_FSO ||
+	     tx_ring->netdev->features & NETIF_F_FCOE_CRC)) {
 		tso = ixgbe_fso(tx_ring, first, &hdr_len);
 		if (tso < 0)
 			goto out_drop;
@@ -9884,7 +9885,7 @@ static int ixgbe_set_features(struct net_device *netdev,
 		    adapter->rx_itr_setting > IXGBE_MIN_RSC_ITR) {
 			adapter->flags2 |= IXGBE_FLAG2_RSC_ENABLED;
 			need_reset = true;
-		} else if ((changed ^ features) & NETIF_F_LRO) {
+		} else if ((changed & NETIF_F_LRO) != (features & NETIF_F_LRO)) {
 			e_info(probe, "rx-usecs set too low, "
 			       "disabling RSC\n");
 		}
@@ -9930,8 +9931,8 @@ static int ixgbe_set_features(struct net_device *netdev,
 		ixgbe_reset_l2fw_offload(adapter);
 	else if (need_reset)
 		ixgbe_do_reset(netdev);
-	else if (changed & (NETIF_F_HW_VLAN_CTAG_RX |
-			    NETIF_F_HW_VLAN_CTAG_FILTER))
+	else if (changed & NETIF_F_HW_VLAN_CTAG_RX ||
+		 changed & NETIF_F_HW_VLAN_CTAG_FILTER)
 		ixgbe_set_rx_mode(netdev);
 
 	return 1;
@@ -11020,11 +11021,13 @@ static int ixgbe_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 				  &gso_partial_features);
 
 	netdev->gso_partial_features = gso_partial_features;
-	netdev->features |= NETIF_F_GSO_PARTIAL |
-			    gso_partial_features;
+	netdev->features |= NETIF_F_GSO_PARTIAL;
+	netdev->features |= gso_partial_features;
 
-	if (hw->mac.type >= ixgbe_mac_82599EB)
-		netdev->features |= NETIF_F_SCTP_CRC | NETIF_F_GSO_UDP_L4;
+	if (hw->mac.type >= ixgbe_mac_82599EB) {
+		netdev->features |= NETIF_F_SCTP_CRC;
+		netdev->features |= NETIF_F_GSO_UDP_L4;
+	}
 
 #ifdef CONFIG_IXGBE_IPSEC
 	if (adapter->ipsec)
@@ -11034,13 +11037,15 @@ static int ixgbe_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 	netdev->hw_features |= netdev->features;
 	netdev_hw_features_set_array(netdev, &ixgbe_hw_feature_set);
 
-	if (hw->mac.type >= ixgbe_mac_82599EB)
-		netdev->hw_features |= NETIF_F_NTUPLE |
-				       NETIF_F_HW_TC;
+	if (hw->mac.type >= ixgbe_mac_82599EB) {
+		netdev->hw_features |= NETIF_F_NTUPLE;
+		netdev->hw_features |= NETIF_F_HW_TC;
+	}
 
 	netdev->features |= NETIF_F_HIGHDMA;
 
-	netdev->vlan_features |= netdev->features | NETIF_F_TSO_MANGLEID;
+	netdev->vlan_features |= netdev->features;
+	netdev->vlan_features |= NETIF_F_TSO_MANGLEID;
 	netdev->hw_enc_features |= netdev->vlan_features;
 	netdev_mpls_features_set_array(netdev, &ixgbe_mpls_feature_set);
 	netdev->mpls_features |= gso_partial_features;
diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
index d46ab40b2b98..db20be0b4fb1 100644
--- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
+++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
@@ -4633,12 +4633,14 @@ static int ixgbevf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 	netdev_features_set_array(&ixgbevf_gso_partial_feature_set,
 				  &gso_partial_features);
 	netdev->gso_partial_features = gso_partial_features;
-	netdev->hw_features |= NETIF_F_GSO_PARTIAL |
-			       gso_partial_features;
+	netdev->hw_features |= NETIF_F_GSO_PARTIAL;
+	netdev->hw_features |= gso_partial_features;
 
-	netdev->features = netdev->hw_features | NETIF_F_HIGHDMA;
+	netdev->features = netdev->hw_features;
+	netdev->features |= NETIF_F_HIGHDMA;
 
-	netdev->vlan_features |= netdev->features | NETIF_F_TSO_MANGLEID;
+	netdev->vlan_features |= netdev->features;
+	netdev->vlan_features |= NETIF_F_TSO_MANGLEID;
 
 	netdev_mpls_features_set_array(netdev, &ixgbevf_mpls_feature_set);
 	netdev->mpls_features |= gso_partial_features;
diff --git a/drivers/net/ethernet/jme.c b/drivers/net/ethernet/jme.c
index 6db2f01468c5..96f2402f6cb4 100644
--- a/drivers/net/ethernet/jme.c
+++ b/drivers/net/ethernet/jme.c
@@ -2664,8 +2664,10 @@ jme_set_msglevel(struct net_device *netdev, u32 value)
 static netdev_features_t
 jme_fix_features(struct net_device *netdev, netdev_features_t features)
 {
-	if (netdev->mtu > 1900)
-		features &= ~(NETIF_F_ALL_TSO | NETIF_F_CSUM_MASK);
+	if (netdev->mtu > 1900) {
+		features &= ~NETIF_F_ALL_TSO;
+		features &= ~NETIF_F_CSUM_MASK;
+	}
 	return features;
 }
 
diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c
index b097a857fe4e..3b9c7257622d 100644
--- a/drivers/net/ethernet/marvell/mvneta.c
+++ b/drivers/net/ethernet/marvell/mvneta.c
@@ -3848,7 +3848,8 @@ static netdev_features_t mvneta_fix_features(struct net_device *dev,
 	struct mvneta_port *pp = netdev_priv(dev);
 
 	if (pp->tx_csum_limit && dev->mtu > pp->tx_csum_limit) {
-		features &= ~(NETIF_F_IP_CSUM | NETIF_F_TSO);
+		features &= ~NETIF_F_IP_CSUM;
+		features &= ~NETIF_F_TSO;
 		netdev_info(dev,
 			    "Disable IP checksum for MTU greater than %dB\n",
 			    pp->tx_csum_limit);
diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
index d693c6580e27..8aa5dd6cce91 100644
--- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
+++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
@@ -6858,7 +6858,8 @@ static int mvpp2_port_probe(struct platform_device *pdev,
 
 	netdev_features_zero(&features);
 	netdev_features_set_array(&mvpp2_feature_set, &features);
-	dev->features = features | NETIF_F_RXCSUM;
+	dev->features = features;
+	dev->features |= NETIF_F_RXCSUM;
 	dev->hw_features |= features;
 	netdev_hw_features_set_array(dev, &mvpp2_hw_feature_set);
 
diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c
index 172c715415fa..888fb6dde97b 100644
--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c
+++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c
@@ -2728,7 +2728,8 @@ static int otx2_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 	if (pf->flags & OTX2_FLAG_TC_FLOWER_SUPPORT)
 		netdev->hw_features |= NETIF_F_HW_TC;
 
-	netdev->hw_features |= NETIF_F_LOOPBACK | NETIF_F_RXALL;
+	netdev->hw_features |= NETIF_F_LOOPBACK;
+	netdev->hw_features |= NETIF_F_RXALL;
 
 	netif_set_tso_max_segs(netdev, OTX2_MAX_GSO_SEGS);
 	netdev->watchdog_timeo = OTX2_TX_TIMEOUT;
diff --git a/drivers/net/ethernet/marvell/prestera/prestera_main.c b/drivers/net/ethernet/marvell/prestera/prestera_main.c
index ede3e53b9790..23dde8129492 100644
--- a/drivers/net/ethernet/marvell/prestera/prestera_main.c
+++ b/drivers/net/ethernet/marvell/prestera/prestera_main.c
@@ -622,7 +622,8 @@ static int prestera_port_create(struct prestera_switch *sw, u32 id)
 	if (err)
 		goto err_dl_port_register;
 
-	dev->features |= NETIF_F_NETNS_LOCAL | NETIF_F_HW_TC;
+	dev->features |= NETIF_F_NETNS_LOCAL;
+	dev->features |= NETIF_F_HW_TC;
 	dev->netdev_ops = &prestera_netdev_ops;
 	dev->ethtool_ops = &prestera_ethtool_ops;
 	SET_NETDEV_DEV(dev, sw->dev->dev);
diff --git a/drivers/net/ethernet/marvell/sky2.c b/drivers/net/ethernet/marvell/sky2.c
index c9a4b1db43eb..98574f083375 100644
--- a/drivers/net/ethernet/marvell/sky2.c
+++ b/drivers/net/ethernet/marvell/sky2.c
@@ -4316,7 +4316,9 @@ static netdev_features_t sky2_fix_features(struct net_device *dev,
 	 */
 	if (dev->mtu > ETH_DATA_LEN && hw->chip_id == CHIP_ID_YUKON_EC_U) {
 		netdev_info(dev, "checksum offload not possible with jumbo frames\n");
-		features &= ~(NETIF_F_TSO | NETIF_F_SG | NETIF_F_CSUM_MASK);
+		features &= ~NETIF_F_TSO;
+		features &= ~NETIF_F_SG;
+		features &= ~NETIF_F_CSUM_MASK;
 	}
 
 	/* Some hardware requires receive checksum for RSS to work. */
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
index 019dbd5ae79f..c73fcb4a15f3 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
@@ -3382,8 +3382,8 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
 	netdev_hw_features_set_array(dev, &mlx4_hw_feature_set3);
 
 	if (!(mdev->dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_SKIP_OUTER_VLAN)) {
-		dev->features |= NETIF_F_HW_VLAN_STAG_RX |
-			NETIF_F_HW_VLAN_STAG_FILTER;
+		dev->features |= NETIF_F_HW_VLAN_STAG_RX;
+		dev->features |= NETIF_F_HW_VLAN_STAG_FILTER;
 		dev->hw_features |= NETIF_F_HW_VLAN_STAG_RX;
 	}
 
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
index c32468f81500..3c8d059c8484 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
@@ -4921,31 +4921,31 @@ static void mlx5e_build_nic_netdev(struct net_device *netdev)
 	}
 
 	if (mlx5_vxlan_allowed(mdev->vxlan) || mlx5_geneve_tx_allowed(mdev)) {
-		netdev->hw_features     |= NETIF_F_GSO_UDP_TUNNEL |
-					   NETIF_F_GSO_UDP_TUNNEL_CSUM;
-		netdev->hw_enc_features |= NETIF_F_GSO_UDP_TUNNEL |
-					   NETIF_F_GSO_UDP_TUNNEL_CSUM;
+		netdev->hw_features     |= NETIF_F_GSO_UDP_TUNNEL;
+		netdev->hw_features     |= NETIF_F_GSO_UDP_TUNNEL_CSUM;
+		netdev->hw_enc_features |= NETIF_F_GSO_UDP_TUNNEL;
+		netdev->hw_enc_features |= NETIF_F_GSO_UDP_TUNNEL_CSUM;
 		netdev->gso_partial_features = NETIF_F_GSO_UDP_TUNNEL_CSUM;
-		netdev->vlan_features |= NETIF_F_GSO_UDP_TUNNEL |
-					 NETIF_F_GSO_UDP_TUNNEL_CSUM;
+		netdev->vlan_features |= NETIF_F_GSO_UDP_TUNNEL;
+		netdev->vlan_features |= NETIF_F_GSO_UDP_TUNNEL_CSUM;
 	}
 
 	if (mlx5e_tunnel_proto_supported_tx(mdev, IPPROTO_GRE)) {
-		netdev->hw_features     |= NETIF_F_GSO_GRE |
-					   NETIF_F_GSO_GRE_CSUM;
-		netdev->hw_enc_features |= NETIF_F_GSO_GRE |
-					   NETIF_F_GSO_GRE_CSUM;
-		netdev->gso_partial_features |= NETIF_F_GSO_GRE |
-						NETIF_F_GSO_GRE_CSUM;
+		netdev->hw_features     |= NETIF_F_GSO_GRE;
+		netdev->hw_features     |= NETIF_F_GSO_GRE_CSUM;
+		netdev->hw_enc_features |= NETIF_F_GSO_GRE;
+		netdev->hw_enc_features |= NETIF_F_GSO_GRE_CSUM;
+		netdev->gso_partial_features |= NETIF_F_GSO_GRE;
+		netdev->gso_partial_features |= NETIF_F_GSO_GRE_CSUM;
 	}
 
 	if (mlx5e_tunnel_proto_supported_tx(mdev, IPPROTO_IPIP)) {
-		netdev->hw_features |= NETIF_F_GSO_IPXIP4 |
-				       NETIF_F_GSO_IPXIP6;
-		netdev->hw_enc_features |= NETIF_F_GSO_IPXIP4 |
-					   NETIF_F_GSO_IPXIP6;
-		netdev->gso_partial_features |= NETIF_F_GSO_IPXIP4 |
-						NETIF_F_GSO_IPXIP6;
+		netdev->hw_features |= NETIF_F_GSO_IPXIP4;
+		netdev->hw_features |= NETIF_F_GSO_IPXIP6;
+		netdev->hw_enc_features |= NETIF_F_GSO_IPXIP4;
+		netdev->hw_enc_features |= NETIF_F_GSO_IPXIP6;
+		netdev->gso_partial_features |= NETIF_F_GSO_IPXIP4;
+		netdev->gso_partial_features |= NETIF_F_GSO_IPXIP6;
 	}
 
 	netdev->gso_partial_features             |= NETIF_F_GSO_UDP_L4;
diff --git a/drivers/net/ethernet/mscc/ocelot_net.c b/drivers/net/ethernet/mscc/ocelot_net.c
index 0f88dac6920a..353a25f001e7 100644
--- a/drivers/net/ethernet/mscc/ocelot_net.c
+++ b/drivers/net/ethernet/mscc/ocelot_net.c
@@ -843,7 +843,7 @@ static int ocelot_set_features(struct net_device *dev,
 	struct ocelot *ocelot = priv->port.ocelot;
 	int port = priv->port.index;
 
-	if ((dev->features & NETIF_F_HW_TC) > (features & NETIF_F_HW_TC) &&
+	if ((dev->features & NETIF_F_HW_TC) && !(features & NETIF_F_HW_TC) &&
 	    priv->tc.offload_cnt) {
 		netdev_err(dev,
 			   "Cannot disable HW TC offload while offloads active\n");
diff --git a/drivers/net/ethernet/myricom/myri10ge/myri10ge.c b/drivers/net/ethernet/myricom/myri10ge/myri10ge.c
index e1a5e80e1704..2a4e49122b5c 100644
--- a/drivers/net/ethernet/myricom/myri10ge/myri10ge.c
+++ b/drivers/net/ethernet/myricom/myri10ge/myri10ge.c
@@ -1289,8 +1289,7 @@ myri10ge_vlan_rx(struct net_device *dev, void *addr, struct sk_buff *skb)
 	va = addr;
 	va += MXGEFW_PAD;
 	veh = (struct vlan_ethhdr *)va;
-	if ((dev->features & NETIF_F_HW_VLAN_CTAG_RX) ==
-	    NETIF_F_HW_VLAN_CTAG_RX &&
+	if ((dev->features & NETIF_F_HW_VLAN_CTAG_RX) &&
 	    veh->h_vlan_proto == htons(ETH_P_8021Q)) {
 		/* fixup csum if needed */
 		if (skb->ip_summed == CHECKSUM_COMPLETE) {
@@ -3868,12 +3867,14 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 	netdev->mtu = myri10ge_initial_mtu;
 
 	netdev->netdev_ops = &myri10ge_netdev_ops;
-	netdev->hw_features = mgp->features | NETIF_F_RXCSUM;
+	netdev->hw_features = mgp->features;
+	netdev->hw_features |= NETIF_F_RXCSUM;
 
 	/* fake NETIF_F_HW_VLAN_CTAG_RX for good GRO performance */
 	netdev->hw_features |= NETIF_F_HW_VLAN_CTAG_RX;
 
-	netdev->features = netdev->hw_features | NETIF_F_HIGHDMA;
+	netdev->features = netdev->hw_features;
+	netdev->features |= NETIF_F_HIGHDMA;
 
 	netdev->vlan_features |= mgp->features;
 	if (mgp->fw_ver_tiny < 37)
diff --git a/drivers/net/ethernet/neterion/s2io.c b/drivers/net/ethernet/neterion/s2io.c
index 79dd414f6e36..8b3def9866d0 100644
--- a/drivers/net/ethernet/neterion/s2io.c
+++ b/drivers/net/ethernet/neterion/s2io.c
@@ -6571,9 +6571,9 @@ static void s2io_ethtool_get_strings(struct net_device *dev,
 static int s2io_set_features(struct net_device *dev, netdev_features_t features)
 {
 	struct s2io_nic *sp = netdev_priv(dev);
-	netdev_features_t changed = (features ^ dev->features) & NETIF_F_LRO;
+	netdev_features_t changed = features ^ dev->features;
 
-	if (changed && netif_running(dev)) {
+	if (changed & NETIF_F_LRO && netif_running(dev)) {
 		int rc;
 
 		s2io_stop_all_tx_queue(sp);
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
index bcf89fe69cc4..29611221990f 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
@@ -2374,9 +2374,10 @@ static void nfp_net_netdev_init(struct nfp_net *nn)
 		netdev->hw_features |= NETIF_F_RXHASH;
 	if (nn->cap & NFP_NET_CFG_CTRL_VXLAN) {
 		if (nn->cap & NFP_NET_CFG_CTRL_LSO) {
-			netdev->hw_features |= NETIF_F_GSO_UDP_TUNNEL |
-					       NETIF_F_GSO_UDP_TUNNEL_CSUM |
-					       NETIF_F_GSO_PARTIAL;
+			netdev->hw_features |= NETIF_F_GSO_UDP_TUNNEL;
+			netdev->hw_features |= NETIF_F_GSO_UDP_TUNNEL_CSUM;
+			netdev->hw_features |= NETIF_F_GSO_PARTIAL;
+
 			netdev->gso_partial_features = NETIF_F_GSO_UDP_TUNNEL_CSUM;
 		}
 		netdev->udp_tunnel_nic_info = &nfp_udp_tunnels;
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_repr.c b/drivers/net/ethernet/netronome/nfp/nfp_net_repr.c
index 3e670133e27a..48da1da1c704 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_net_repr.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_net_repr.c
@@ -240,6 +240,7 @@ nfp_repr_fix_features(struct net_device *netdev, netdev_features_t features)
 	netdev_features_t old_features = features;
 	netdev_features_t lower_features;
 	struct net_device *lower_dev;
+	netdev_features_t tmp;
 
 	lower_dev = repr->dst->u.port_info.lower_dev;
 
@@ -248,7 +249,10 @@ nfp_repr_fix_features(struct net_device *netdev, netdev_features_t features)
 		lower_features |= NETIF_F_HW_CSUM;
 
 	features = netdev_intersect_features(features, lower_features);
-	features |= old_features & (NETIF_F_SOFT_FEATURES | NETIF_F_HW_TC);
+	tmp = NETIF_F_SOFT_FEATURES;
+	tmp |= NETIF_F_HW_TC;
+	tmp &= old_features;
+	features |= tmp;
 	features |= NETIF_F_LLTX;
 
 	return features;
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_port.c b/drivers/net/ethernet/netronome/nfp/nfp_port.c
index 4f2308570dcf..c224707f763f 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_port.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_port.c
@@ -66,7 +66,7 @@ int nfp_port_set_features(struct net_device *netdev, netdev_features_t features)
 	if (!port)
 		return 0;
 
-	if ((netdev->features & NETIF_F_HW_TC) > (features & NETIF_F_HW_TC) &&
+	if ((netdev->features & NETIF_F_HW_TC) && !(features & NETIF_F_HW_TC) &&
 	    port->tc_offload_cnt) {
 		netdev_err(netdev, "Cannot disable HW TC offload while offloads active\n");
 		return -EBUSY;
diff --git a/drivers/net/ethernet/nvidia/forcedeth.c b/drivers/net/ethernet/nvidia/forcedeth.c
index 5b957cdc118e..a8a8d59dd008 100644
--- a/drivers/net/ethernet/nvidia/forcedeth.c
+++ b/drivers/net/ethernet/nvidia/forcedeth.c
@@ -6124,7 +6124,7 @@ static int nv_probe(struct pci_dev *pci_dev, const struct pci_device_id *id)
 
 	dev_info(&pci_dev->dev, "%s%s%s%s%s%s%s%s%s%s%sdesc-v%u\n",
 		 dev->features & NETIF_F_HIGHDMA ? "highdma " : "",
-		 dev->features & (NETIF_F_IP_CSUM | NETIF_F_SG) ?
+		 (dev->features & NETIF_F_IP_CSUM || dev->features & NETIF_F_SG) ?
 			"csum " : "",
 		 dev->features & netdev_ctag_vlan_offload_features ?
 			"vlan " : "",
diff --git a/drivers/net/ethernet/pensando/ionic/ionic_lif.c b/drivers/net/ethernet/pensando/ionic/ionic_lif.c
index 4f2511f763dd..8459002574fc 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_lif.c
+++ b/drivers/net/ethernet/pensando/ionic/ionic_lif.c
@@ -1547,7 +1547,8 @@ static int ionic_init_nic_features(struct ionic_lif *lif)
 
 	netdev->hw_features |= netdev->hw_enc_features;
 	netdev->features |= netdev->hw_features;
-	netdev->vlan_features |= netdev->features & ~NETIF_F_VLAN_FEATURES;
+	features = netdev->features & ~NETIF_F_VLAN_FEATURES;
+	netdev->vlan_features |= features;
 
 	netdev->priv_flags |= IFF_UNICAST_FLT |
 			      IFF_LIVE_ADDR_CHANGE;
diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c b/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c
index 993d0ee6db01..1c3b06599b37 100644
--- a/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c
+++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c
@@ -536,9 +536,11 @@ static int netxen_set_features(struct net_device *dev,
 	netdev_features_t features)
 {
 	struct netxen_adapter *adapter = netdev_priv(dev);
+	netdev_features_t changed;
 	int hw_lro;
 
-	if (!((dev->features ^ features) & NETIF_F_LRO))
+	changed = dev->features ^ features;
+	if (!(changed & NETIF_F_LRO))
 		return 0;
 
 	hw_lro = (features & NETIF_F_LRO) ? NETXEN_NIC_LRO_ENABLED
@@ -1357,8 +1359,10 @@ netxen_setup_netdev(struct netxen_adapter *adapter,
 	netdev_hw_features_zero(netdev);
 	netdev_hw_features_set_array(netdev, &netxen_hw_feature_set);
 
-	if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
-		netdev->hw_features |= NETIF_F_IPV6_CSUM | NETIF_F_TSO6;
+	if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
+		netdev->hw_features |= NETIF_F_IPV6_CSUM;
+		netdev->hw_features |= NETIF_F_TSO6;
+	}
 
 	netdev->vlan_features |= netdev->hw_features;
 
diff --git a/drivers/net/ethernet/qlogic/qede/qede_main.c b/drivers/net/ethernet/qlogic/qede/qede_main.c
index 04af61f4122a..b37a045f09d6 100644
--- a/drivers/net/ethernet/qlogic/qede/qede_main.c
+++ b/drivers/net/ethernet/qlogic/qede/qede_main.c
@@ -897,18 +897,19 @@ static void qede_init_ndev(struct qede_dev *edev)
 	}
 
 	if (udp_tunnel_enable) {
-		hw_features |= (NETIF_F_GSO_UDP_TUNNEL |
-				NETIF_F_GSO_UDP_TUNNEL_CSUM);
-		ndev->hw_enc_features |= (NETIF_F_GSO_UDP_TUNNEL |
-					  NETIF_F_GSO_UDP_TUNNEL_CSUM);
+		hw_features |= NETIF_F_GSO_UDP_TUNNEL;
+		hw_features |= NETIF_F_GSO_UDP_TUNNEL_CSUM;
+		ndev->hw_enc_features |= NETIF_F_GSO_UDP_TUNNEL;
+		ndev->hw_enc_features |= NETIF_F_GSO_UDP_TUNNEL_CSUM;
 
 		qede_set_udp_tunnels(edev);
 	}
 
 	if (edev->dev_info.common.gre_enable) {
-		hw_features |= (NETIF_F_GSO_GRE | NETIF_F_GSO_GRE_CSUM);
-		ndev->hw_enc_features |= (NETIF_F_GSO_GRE |
-					  NETIF_F_GSO_GRE_CSUM);
+		hw_features |= NETIF_F_GSO_GRE;
+		hw_features |= NETIF_F_GSO_GRE_CSUM;
+		ndev->hw_enc_features |= NETIF_F_GSO_GRE;
+		ndev->hw_enc_features |= NETIF_F_GSO_GRE_CSUM;
 	}
 
 	ndev->vlan_features = hw_features;
diff --git a/drivers/net/ethernet/qlogic/qla3xxx.c b/drivers/net/ethernet/qlogic/qla3xxx.c
index 06f4d9a9e938..fe823b03736b 100644
--- a/drivers/net/ethernet/qlogic/qla3xxx.c
+++ b/drivers/net/ethernet/qlogic/qla3xxx.c
@@ -3795,8 +3795,10 @@ static int ql3xxx_probe(struct pci_dev *pdev,
 	qdev->msg_enable = netif_msg_init(debug, default_msg);
 
 	ndev->features |= NETIF_F_HIGHDMA;
-	if (qdev->device_id == QL3032_DEVICE_ID)
-		ndev->features |= NETIF_F_IP_CSUM | NETIF_F_SG;
+	if (qdev->device_id == QL3032_DEVICE_ID) {
+		ndev->features |= NETIF_F_IP_CSUM;
+		ndev->features |= NETIF_F_SG;
+	}
 
 	qdev->mem_map_registers = pci_ioremap_bar(pdev, 1);
 	if (!qdev->mem_map_registers) {
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c
index 7039925bc566..9bb1b9d53d96 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c
@@ -1078,7 +1078,8 @@ netdev_features_t qlcnic_fix_features(struct net_device *netdev,
 			netdev_features_zero(&changeable);
 			netdev_features_set_array(&qlcnic_changable_feature_set,
 						  &changeable);
-			features ^= changed & changeable;
+			changed &= changeable;
+			features ^= changed;
 		}
 	}
 
diff --git a/drivers/net/ethernet/realtek/8139cp.c b/drivers/net/ethernet/realtek/8139cp.c
index c5c2e491d251..1a4e97594238 100644
--- a/drivers/net/ethernet/realtek/8139cp.c
+++ b/drivers/net/ethernet/realtek/8139cp.c
@@ -1461,10 +1461,11 @@ static void cp_set_msglevel(struct net_device *dev, u32 value)
 
 static int cp_set_features(struct net_device *dev, netdev_features_t features)
 {
+	netdev_features_t changed = dev->features ^ features;
 	struct cp_private *cp = netdev_priv(dev);
 	unsigned long flags;
 
-	if (!((dev->features ^ features) & NETIF_F_RXCSUM))
+	if (!(changed & NETIF_F_RXCSUM))
 		return 0;
 
 	spin_lock_irqsave(&cp->lock, flags);
diff --git a/drivers/net/ethernet/realtek/8139too.c b/drivers/net/ethernet/realtek/8139too.c
index 3844a0f418ec..fb4437f4ae35 100644
--- a/drivers/net/ethernet/realtek/8139too.c
+++ b/drivers/net/ethernet/realtek/8139too.c
@@ -905,7 +905,7 @@ static int rtl8139_set_features(struct net_device *dev, netdev_features_t featur
 	netdev_features_t changed = features ^ dev->features;
 	void __iomem *ioaddr = tp->mmio_addr;
 
-	if (!(changed & (NETIF_F_RXALL)))
+	if (!(changed & NETIF_F_RXALL))
 		return 0;
 
 	spin_lock_irqsave(&tp->lock, flags);
diff --git a/drivers/net/ethernet/realtek/r8169_main.c b/drivers/net/ethernet/realtek/r8169_main.c
index 55f67e0c1280..ef8b13d342f5 100644
--- a/drivers/net/ethernet/realtek/r8169_main.c
+++ b/drivers/net/ethernet/realtek/r8169_main.c
@@ -1446,8 +1446,10 @@ static netdev_features_t rtl8169_fix_features(struct net_device *dev,
 		features &= ~NETIF_F_ALL_TSO;
 
 	if (dev->mtu > ETH_DATA_LEN &&
-	    tp->mac_version > RTL_GIGA_MAC_VER_06)
-		features &= ~(NETIF_F_CSUM_MASK | NETIF_F_ALL_TSO);
+	    tp->mac_version > RTL_GIGA_MAC_VER_06) {
+		features &= ~NETIF_F_CSUM_MASK;
+		features &= ~NETIF_F_ALL_TSO;
+	}
 
 	return features;
 }
@@ -5456,7 +5458,8 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 		netif_set_tso_max_size(dev, RTL_GSO_MAX_SIZE_V2);
 		netif_set_tso_max_segs(dev, RTL_GSO_MAX_SEGS_V2);
 	} else {
-		dev->hw_features |= NETIF_F_SG | NETIF_F_TSO;
+		dev->hw_features |= NETIF_F_SG;
+		dev->hw_features |= NETIF_F_TSO;
 		netif_set_tso_max_size(dev, RTL_GSO_MAX_SIZE_V1);
 		netif_set_tso_max_segs(dev, RTL_GSO_MAX_SEGS_V1);
 	}
diff --git a/drivers/net/ethernet/rocker/rocker_main.c b/drivers/net/ethernet/rocker/rocker_main.c
index fc83ec23bd1d..2a16201ce0cf 100644
--- a/drivers/net/ethernet/rocker/rocker_main.c
+++ b/drivers/net/ethernet/rocker/rocker_main.c
@@ -2578,7 +2578,8 @@ static int rocker_probe_port(struct rocker *rocker, unsigned int port_number)
 		       NAPI_POLL_WEIGHT);
 	rocker_carrier_init(rocker_port);
 
-	dev->features |= NETIF_F_NETNS_LOCAL | NETIF_F_SG;
+	dev->features |= NETIF_F_NETNS_LOCAL;
+	dev->features |= NETIF_F_SG;
 
 	/* MTU range: 68 - 9000 */
 	dev->min_mtu = ROCKER_PORT_MIN_MTU;
diff --git a/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c b/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c
index 30af142820c6..7963a9aeafe0 100644
--- a/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c
+++ b/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c
@@ -2117,7 +2117,8 @@ struct sxgbe_priv_data *sxgbe_drv_probe(struct device *device,
 
 	netdev_hw_features_zero(ndev);
 	netdev_hw_features_set_array(ndev, &sxgbe_hw_feature_set);
-	ndev->features |= ndev->hw_features | NETIF_F_HIGHDMA;
+	ndev->features |= ndev->hw_features;
+	ndev->features |= NETIF_F_HIGHDMA;
 	ndev->watchdog_timeo = msecs_to_jiffies(TX_TIMEO);
 
 	/* assign filtering support */
diff --git a/drivers/net/ethernet/sfc/ef10.c b/drivers/net/ethernet/sfc/ef10.c
index 064d6f224af8..dd8e278f8d8d 100644
--- a/drivers/net/ethernet/sfc/ef10.c
+++ b/drivers/net/ethernet/sfc/ef10.c
@@ -1366,7 +1366,8 @@ static int efx_ef10_init_nic(struct efx_nic *efx)
 		netdev_features_set_array(&ef10_tso_feature_set,
 					  &encap_tso_features);
 
-		hw_enc_features |= encap_tso_features | NETIF_F_TSO;
+		hw_enc_features |= encap_tso_features;
+		hw_enc_features |= NETIF_F_TSO;
 		efx->net_dev->features |= encap_tso_features;
 	}
 	efx->net_dev->hw_enc_features = hw_enc_features;
diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c
index 897a0113e257..4c802cd087fc 100644
--- a/drivers/net/ethernet/sfc/efx.c
+++ b/drivers/net/ethernet/sfc/efx.c
@@ -1001,6 +1001,7 @@ static int efx_pci_probe_post_io(struct efx_nic *efx)
 {
 	struct net_device *net_dev = efx->net_dev;
 	int rc = efx_pci_probe_main(efx);
+	netdev_features_t tmp;
 
 	if (rc)
 		return rc;
@@ -1015,7 +1016,8 @@ static int efx_pci_probe_post_io(struct efx_nic *efx)
 	/* Determine netdevice features */
 	net_dev->features |= *efx->type->offload_features;
 	netdev_active_features_set_array(net_dev, &efx_active_feature_set);
-	if (*efx->type->offload_features & (NETIF_F_IPV6_CSUM | NETIF_F_HW_CSUM))
+	if ((*efx->type->offload_features & NETIF_F_IPV6_CSUM) ||
+	    (*efx->type->offload_features & NETIF_F_HW_CSUM))
 		net_dev->features |= NETIF_F_TSO6;
 	/* Check whether device supports TSO */
 	if (!efx->type->tso_versions || !efx->type->tso_versions(efx))
@@ -1024,7 +1026,8 @@ static int efx_pci_probe_post_io(struct efx_nic *efx)
 	net_dev->vlan_features |= NETIF_F_ALL_TSO;
 	netdev_vlan_features_set_array(net_dev, &efx_vlan_feature_set);
 
-	net_dev->hw_features |= net_dev->features & ~efx->fixed_features;
+	tmp = net_dev->features & ~efx->fixed_features;
+	net_dev->hw_features |= tmp;
 
 	/* Disable receiving frames with bad FCS, by default. */
 	net_dev->features &= ~NETIF_F_RXALL;
diff --git a/drivers/net/ethernet/sfc/efx_common.c b/drivers/net/ethernet/sfc/efx_common.c
index b6e0e4855821..c3a29d4169c9 100644
--- a/drivers/net/ethernet/sfc/efx_common.c
+++ b/drivers/net/ethernet/sfc/efx_common.c
@@ -213,10 +213,12 @@ void efx_set_rx_mode(struct net_device *net_dev)
 int efx_set_features(struct net_device *net_dev, netdev_features_t data)
 {
 	struct efx_nic *efx = efx_netdev_priv(net_dev);
+	netdev_features_t tmp;
 	int rc;
 
 	/* If disabling RX n-tuple filtering, clear existing filters */
-	if (net_dev->features & ~data & NETIF_F_NTUPLE) {
+	tmp = net_dev->features & ~data;
+	if (tmp & NETIF_F_NTUPLE) {
 		rc = efx->type->filter_clear_rx(efx, EFX_FILTER_PRI_MANUAL);
 		if (rc)
 			return rc;
@@ -225,8 +227,9 @@ int efx_set_features(struct net_device *net_dev, netdev_features_t data)
 	/* If Rx VLAN filter is changed, update filters via mac_reconfigure.
 	 * If rx-fcs is changed, mac_reconfigure updates that too.
 	 */
-	if ((net_dev->features ^ data) & (NETIF_F_HW_VLAN_CTAG_FILTER |
-					  NETIF_F_RXFCS)) {
+	tmp = net_dev->features ^ data;
+	if (tmp & NETIF_F_HW_VLAN_CTAG_FILTER ||
+	    tmp & NETIF_F_RXFCS) {
 		/* efx_set_rx_mode() will schedule MAC work to update filters
 		 * when a new features are finally set in net_dev.
 		 */
@@ -1364,7 +1367,7 @@ netdev_features_t efx_features_check(struct sk_buff *skb, struct net_device *dev
 			 */
 			if (skb_inner_transport_offset(skb) >
 			    EFX_TSO2_MAX_HDRLEN)
-				features &= ~(NETIF_F_GSO_MASK);
+				features &= ~NETIF_F_GSO_MASK;
 		if (features & netdev_csum_gso_features_mask)
 			if (!efx_can_encap_offloads(efx, skb))
 				features &= ~netdev_csum_gso_features_mask;
diff --git a/drivers/net/ethernet/sfc/falcon/efx.c b/drivers/net/ethernet/sfc/falcon/efx.c
index 8692dc18efff..0b6dbd33410e 100644
--- a/drivers/net/ethernet/sfc/falcon/efx.c
+++ b/drivers/net/ethernet/sfc/falcon/efx.c
@@ -2182,17 +2182,20 @@ static void ef4_set_rx_mode(struct net_device *net_dev)
 static int ef4_set_features(struct net_device *net_dev, netdev_features_t data)
 {
 	struct ef4_nic *efx = netdev_priv(net_dev);
+	netdev_features_t tmp;
 	int rc;
 
 	/* If disabling RX n-tuple filtering, clear existing filters */
-	if (net_dev->features & ~data & NETIF_F_NTUPLE) {
+	tmp = net_dev->features & ~data;
+	if (tmp & NETIF_F_NTUPLE) {
 		rc = efx->type->filter_clear_rx(efx, EF4_FILTER_PRI_MANUAL);
 		if (rc)
 			return rc;
 	}
 
 	/* If Rx VLAN filter is changed, update filters via mac_reconfigure */
-	if ((net_dev->features ^ data) & NETIF_F_HW_VLAN_CTAG_FILTER) {
+	tmp = net_dev->features ^ data;
+	if (tmp & NETIF_F_HW_VLAN_CTAG_FILTER) {
 		/* ef4_set_rx_mode() will schedule MAC work to update filters
 		 * when a new features are finally set in net_dev.
 		 */
@@ -2904,8 +2907,9 @@ static int ef4_pci_probe(struct pci_dev *pci_dev,
 	if (rc)
 		goto fail3;
 
-	net_dev->features |= (*efx->type->offload_features | NETIF_F_SG |
-			      NETIF_F_RXCSUM);
+	net_dev->features |= *efx->type->offload_features;
+	net_dev->features |= NETIF_F_SG;
+	net_dev->features |= NETIF_F_RXCSUM;
 	/* Mask for features that also apply to VLAN devices */
 	netdev_vlan_features_set_array(net_dev, &efx_vlan_feature_set);
 	net_dev->hw_features = net_dev->features & ~efx->fixed_features;
diff --git a/drivers/net/ethernet/sfc/siena/efx.c b/drivers/net/ethernet/sfc/siena/efx.c
index 4829f66a47e7..6887ba4c9806 100644
--- a/drivers/net/ethernet/sfc/siena/efx.c
+++ b/drivers/net/ethernet/sfc/siena/efx.c
@@ -998,7 +998,8 @@ static int efx_pci_probe_post_io(struct efx_nic *efx)
 	/* Determine netdevice features */
 	net_dev->features |= *efx->type->offload_features;
 	netdev_active_features_set_array(net_dev, &efx_active_feature_set);
-	if (*efx->type->offload_features & (NETIF_F_IPV6_CSUM | NETIF_F_HW_CSUM))
+	if ((*efx->type->offload_features & NETIF_F_IPV6_CSUM) ||
+	    (*efx->type->offload_features & NETIF_F_HW_CSUM))
 		net_dev->features |= NETIF_F_TSO6;
 	/* Check whether device supports TSO */
 	if (!efx->type->tso_versions || !efx->type->tso_versions(efx))
diff --git a/drivers/net/ethernet/sfc/siena/efx_common.c b/drivers/net/ethernet/sfc/siena/efx_common.c
index ef00f1d87876..4c0f915dba82 100644
--- a/drivers/net/ethernet/sfc/siena/efx_common.c
+++ b/drivers/net/ethernet/sfc/siena/efx_common.c
@@ -212,10 +212,11 @@ void efx_siena_set_rx_mode(struct net_device *net_dev)
 int efx_siena_set_features(struct net_device *net_dev, netdev_features_t data)
 {
 	struct efx_nic *efx = netdev_priv(net_dev);
+	netdev_features_t features;
 	int rc;
 
 	/* If disabling RX n-tuple filtering, clear existing filters */
-	if (net_dev->features & ~data & NETIF_F_NTUPLE) {
+	if ((net_dev->features & NETIF_F_NTUPLE) && !(data & NETIF_F_NTUPLE)) {
 		rc = efx->type->filter_clear_rx(efx, EFX_FILTER_PRI_MANUAL);
 		if (rc)
 			return rc;
@@ -224,8 +225,8 @@ int efx_siena_set_features(struct net_device *net_dev, netdev_features_t data)
 	/* If Rx VLAN filter is changed, update filters via mac_reconfigure.
 	 * If rx-fcs is changed, mac_reconfigure updates that too.
 	 */
-	if ((net_dev->features ^ data) & (NETIF_F_HW_VLAN_CTAG_FILTER |
-					  NETIF_F_RXFCS)) {
+	features = net_dev->features ^ data;
+	if ((features & NETIF_F_HW_VLAN_CTAG_FILTER) || (features & NETIF_F_RXFCS)) {
 		/* efx_siena_set_rx_mode() will schedule MAC work to update filters
 		 * when a new features are finally set in net_dev.
 		 */
diff --git a/drivers/net/ethernet/socionext/sni_ave.c b/drivers/net/ethernet/socionext/sni_ave.c
index f0c8de2c6075..c3aead3d052b 100644
--- a/drivers/net/ethernet/socionext/sni_ave.c
+++ b/drivers/net/ethernet/socionext/sni_ave.c
@@ -1594,8 +1594,10 @@ static int ave_probe(struct platform_device *pdev)
 	ndev->ethtool_ops = &ave_ethtool_ops;
 	SET_NETDEV_DEV(ndev, dev);
 
-	ndev->features    |= (NETIF_F_IP_CSUM | NETIF_F_RXCSUM);
-	ndev->hw_features |= (NETIF_F_IP_CSUM | NETIF_F_RXCSUM);
+	ndev->features    |= NETIF_F_IP_CSUM;
+	ndev->features    |= NETIF_F_RXCSUM;
+	ndev->hw_features |= NETIF_F_IP_CSUM;
+	ndev->hw_features |= NETIF_F_RXCSUM;
 
 	ndev->max_mtu = AVE_MAX_ETHFRAME - (ETH_HLEN + ETH_FCS_LEN);
 
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 6ddacc6a7f7a..8f227d5f2199 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -7194,7 +7194,8 @@ int stmmac_dvr_probe(struct device *device,
 		}
 	}
 
-	ndev->features |= ndev->hw_features | NETIF_F_HIGHDMA;
+	ndev->features |= ndev->hw_features;
+	ndev->features |= NETIF_F_HIGHDMA;
 	ndev->watchdog_timeo = msecs_to_jiffies(watchdog);
 #ifdef STMMAC_VLAN_TAG_USED
 	/* Both mac100 and gmac support receive VLAN tag detection */
diff --git a/drivers/net/ethernet/sun/cassini.c b/drivers/net/ethernet/sun/cassini.c
index 0b08b0e085e8..bf899125b1ef 100644
--- a/drivers/net/ethernet/sun/cassini.c
+++ b/drivers/net/ethernet/sun/cassini.c
@@ -5056,8 +5056,10 @@ static int cas_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 	dev->dma = 0;
 
 	/* Cassini features. */
-	if ((cp->cas_flags & CAS_FLAG_NO_HW_CSUM) == 0)
-		dev->features |= NETIF_F_HW_CSUM | NETIF_F_SG;
+	if ((cp->cas_flags & CAS_FLAG_NO_HW_CSUM) == 0) {
+		dev->features |= NETIF_F_HW_CSUM;
+		dev->features |= NETIF_F_SG;
+	}
 
 	dev->features |= NETIF_F_HIGHDMA;
 
diff --git a/drivers/net/ethernet/sun/niu.c b/drivers/net/ethernet/sun/niu.c
index f7fa28ba5d53..6a37026e02b6 100644
--- a/drivers/net/ethernet/sun/niu.c
+++ b/drivers/net/ethernet/sun/niu.c
@@ -9743,7 +9743,8 @@ static void niu_set_basic_features(struct net_device *dev)
 {
 	netdev_hw_features_zero(dev);
 	netdev_hw_features_set_array(dev, &niu_hw_feature_set);
-	dev->features |= dev->hw_features | NETIF_F_RXCSUM;
+	dev->features |= dev->hw_features;
+	dev->features |= NETIF_F_RXCSUM;
 }
 
 static int niu_pci_init_one(struct pci_dev *pdev,
diff --git a/drivers/net/ethernet/sun/sunhme.c b/drivers/net/ethernet/sun/sunhme.c
index 8594ee839628..f8868f79ee95 100644
--- a/drivers/net/ethernet/sun/sunhme.c
+++ b/drivers/net/ethernet/sun/sunhme.c
@@ -2784,8 +2784,10 @@ static int happy_meal_sbus_probe_one(struct platform_device *op, int is_qfe)
 	dev->ethtool_ops = &hme_ethtool_ops;
 
 	/* Happy Meal can do it all... */
-	dev->hw_features = NETIF_F_SG | NETIF_F_HW_CSUM;
-	dev->features |= dev->hw_features | NETIF_F_RXCSUM;
+	dev->hw_features = NETIF_F_SG;
+	dev->hw_features |= NETIF_F_HW_CSUM;
+	dev->features |= dev->hw_features;
+	dev->features |= NETIF_F_RXCSUM;
 
 	hp->irq = op->archdata.irqs[0];
 
@@ -3104,8 +3106,10 @@ static int happy_meal_pci_probe(struct pci_dev *pdev,
 	dev->ethtool_ops = &hme_ethtool_ops;
 
 	/* Happy Meal can do it all... */
-	dev->hw_features = NETIF_F_SG | NETIF_F_HW_CSUM;
-	dev->features |= dev->hw_features | NETIF_F_RXCSUM;
+	dev->hw_features = NETIF_F_SG;
+	dev->hw_features |= NETIF_F_HW_CSUM;
+	dev->features |= dev->hw_features;
+	dev->features |= NETIF_F_RXCSUM;
 
 #if defined(CONFIG_SBUS) && defined(CONFIG_PCI)
 	/* Hook up PCI register/descriptor accessors. */
diff --git a/drivers/net/ethernet/ti/am65-cpsw-nuss.c b/drivers/net/ethernet/ti/am65-cpsw-nuss.c
index b390983861d8..2347a3df30cd 100644
--- a/drivers/net/ethernet/ti/am65-cpsw-nuss.c
+++ b/drivers/net/ethernet/ti/am65-cpsw-nuss.c
@@ -1975,8 +1975,8 @@ am65_cpsw_nuss_init_port_ndev(struct am65_cpsw_common *common, u32 port_idx)
 	port->ndev->max_mtu = AM65_CPSW_MAX_PACKET_SIZE;
 	netdev_hw_features_zero(port->ndev);
 	netdev_hw_features_set_array(port->ndev, &am65_cpsw_hw_feature_set);
-	port->ndev->features = port->ndev->hw_features |
-			       NETIF_F_HW_VLAN_CTAG_FILTER;
+	port->ndev->features = port->ndev->hw_features;
+	port->ndev->features |= NETIF_F_HW_VLAN_CTAG_FILTER;
 	port->ndev->vlan_features |=  NETIF_F_SG;
 	port->ndev->netdev_ops = &am65_cpsw_nuss_netdev_ops;
 	port->ndev->ethtool_ops = &am65_cpsw_ethtool_ops_slave;
diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c
index ed66c4d4d830..7e12c6a77d30 100644
--- a/drivers/net/ethernet/ti/cpsw.c
+++ b/drivers/net/ethernet/ti/cpsw.c
@@ -1456,7 +1456,8 @@ static int cpsw_probe_dual_emac(struct cpsw_priv *priv)
 
 	priv_sl2->emac_port = 1;
 	cpsw->slaves[1].ndev = ndev;
-	ndev->features |= NETIF_F_HW_VLAN_CTAG_FILTER | NETIF_F_HW_VLAN_CTAG_RX;
+	ndev->features |= NETIF_F_HW_VLAN_CTAG_FILTER;
+	ndev->features |= NETIF_F_HW_VLAN_CTAG_RX;
 
 	ndev->netdev_ops = &cpsw_netdev_ops;
 	ndev->ethtool_ops = &cpsw_ethtool_ops;
@@ -1633,7 +1634,8 @@ static int cpsw_probe(struct platform_device *pdev)
 
 	cpsw->slaves[0].ndev = ndev;
 
-	ndev->features |= NETIF_F_HW_VLAN_CTAG_FILTER | NETIF_F_HW_VLAN_CTAG_RX;
+	ndev->features |= NETIF_F_HW_VLAN_CTAG_FILTER;
+	ndev->features |= NETIF_F_HW_VLAN_CTAG_RX;
 
 	ndev->netdev_ops = &cpsw_netdev_ops;
 	ndev->ethtool_ops = &cpsw_ethtool_ops;
diff --git a/drivers/net/ethernet/toshiba/ps3_gelic_net.c b/drivers/net/ethernet/toshiba/ps3_gelic_net.c
index 3dbfb1b20649..5def0b3bf8ef 100644
--- a/drivers/net/ethernet/toshiba/ps3_gelic_net.c
+++ b/drivers/net/ethernet/toshiba/ps3_gelic_net.c
@@ -1461,7 +1461,8 @@ int gelic_net_setup_netdev(struct net_device *netdev, struct gelic_card *card)
 	int status;
 	u64 v1, v2;
 
-	netdev->hw_features = NETIF_F_IP_CSUM | NETIF_F_RXCSUM;
+	netdev->hw_features = NETIF_F_IP_CSUM;
+	netdev->hw_features |= NETIF_F_RXCSUM;
 
 	netdev->features = NETIF_F_IP_CSUM;
 	if (GELIC_CARD_RX_CSUM_DEFAULT)
diff --git a/drivers/net/ethernet/toshiba/spider_net.c b/drivers/net/ethernet/toshiba/spider_net.c
index bc4914c758ad..e2e0e18fcdc8 100644
--- a/drivers/net/ethernet/toshiba/spider_net.c
+++ b/drivers/net/ethernet/toshiba/spider_net.c
@@ -2275,10 +2275,12 @@ spider_net_setup_netdev(struct spider_net_card *card)
 
 	spider_net_setup_netdev_ops(netdev);
 
-	netdev->hw_features = NETIF_F_RXCSUM | NETIF_F_IP_CSUM;
+	netdev->hw_features = NETIF_F_RXCSUM;
+	netdev->hw_features |= NETIF_F_IP_CSUM;
 	if (SPIDER_NET_RX_CSUM_DEFAULT)
 		netdev->features |= NETIF_F_RXCSUM;
-	netdev->features |= NETIF_F_IP_CSUM | NETIF_F_LLTX;
+	netdev->features |= NETIF_F_IP_CSUM;
+	netdev->features |= NETIF_F_LLTX;
 	/* some time: NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX |
 	 *		NETIF_F_HW_VLAN_CTAG_FILTER
 	 */
diff --git a/drivers/net/ethernet/via/via-rhine.c b/drivers/net/ethernet/via/via-rhine.c
index 1d795114c264..3c8631f9925d 100644
--- a/drivers/net/ethernet/via/via-rhine.c
+++ b/drivers/net/ethernet/via/via-rhine.c
@@ -967,8 +967,10 @@ static int rhine_init_one_common(struct device *hwdev, u32 quirks,
 
 	netif_napi_add(dev, &rp->napi, rhine_napipoll, 64);
 
-	if (rp->quirks & rqRhineI)
-		dev->features |= NETIF_F_SG|NETIF_F_HW_CSUM;
+	if (rp->quirks & rqRhineI) {
+		dev->features |= NETIF_F_SG;
+		dev->features |= NETIF_F_HW_CSUM;
+	}
 
 	if (rp->quirks & rqMgmt)
 		dev->features |= netdev_ctag_vlan_features;
diff --git a/drivers/net/hyperv/rndis_filter.c b/drivers/net/hyperv/rndis_filter.c
index 6da36cb8af80..456563b6b242 100644
--- a/drivers/net/hyperv/rndis_filter.c
+++ b/drivers/net/hyperv/rndis_filter.c
@@ -15,6 +15,7 @@
 #include <linux/io.h>
 #include <linux/if_ether.h>
 #include <linux/netdevice.h>
+#include <linux/netdev_features_helper.h>
 #include <linux/if_vlan.h>
 #include <linux/nls.h>
 #include <linux/vmalloc.h>
@@ -1350,6 +1351,7 @@ static int rndis_netdev_set_hwcaps(struct rndis_device *rndis_device,
 	struct ndis_offload hwcaps;
 	struct ndis_offload_params offloads;
 	unsigned int gso_max_size = GSO_LEGACY_MAX_SIZE;
+	netdev_features_t features;
 	int ret;
 
 	/* Find HW offload capabilities */
@@ -1429,7 +1431,10 @@ static int rndis_netdev_set_hwcaps(struct rndis_device *rndis_device,
 	/* In case some hw_features disappeared we need to remove them from
 	 * net->features list as they're no longer supported.
 	 */
-	net->features &= ~NETVSC_SUPPORTED_HW_FEATURES | net->hw_features;
+	netdev_features_fill(&features);
+	features &= ~NETVSC_SUPPORTED_HW_FEATURES;
+	features |= net->hw_features;
+	net->features &= features;
 
 	netif_set_tso_max_size(net, gso_max_size);
 
diff --git a/drivers/net/ifb.c b/drivers/net/ifb.c
index 656a54a9f6e8..370f3fa59587 100644
--- a/drivers/net/ifb.c
+++ b/drivers/net/ifb.c
@@ -328,7 +328,8 @@ static void ifb_setup(struct net_device *dev)
 	dev->features |= ifb_features;
 	dev->hw_features |= dev->features;
 	dev->hw_enc_features |= dev->features;
-	dev->vlan_features |= ifb_features & ~netdev_tx_vlan_features;
+	ifb_features &= ~netdev_tx_vlan_features;
+	dev->vlan_features |= ifb_features;
 
 	dev->flags |= IFF_NOARP;
 	dev->flags &= ~IFF_MULTICAST;
diff --git a/drivers/net/ipvlan/ipvlan_main.c b/drivers/net/ipvlan/ipvlan_main.c
index b0d7a484fd39..0078ecfe8838 100644
--- a/drivers/net/ipvlan/ipvlan_main.c
+++ b/drivers/net/ipvlan/ipvlan_main.c
@@ -254,13 +254,18 @@ static netdev_features_t ipvlan_fix_features(struct net_device *dev,
 					     netdev_features_t features)
 {
 	struct ipvl_dev *ipvlan = netdev_priv(dev);
+	netdev_features_t tmp;
 
 	features |= NETIF_F_ALL_FOR_ALL;
-	features &= (ipvlan->sfeatures | ~IPVLAN_FEATURES);
+	netdev_features_fill(&tmp);
+	tmp &= ~IPVLAN_FEATURES;
+	tmp |= ipvlan->sfeatures;
+	features &= tmp;
 	features = netdev_increment_features(ipvlan->phy_dev->features,
 					     features, features);
 	features |= IPVLAN_ALWAYS_ON;
-	features &= (IPVLAN_FEATURES | IPVLAN_ALWAYS_ON);
+	tmp = IPVLAN_FEATURES | IPVLAN_ALWAYS_ON;
+	features &= tmp;
 
 	return features;
 }
diff --git a/drivers/net/macsec.c b/drivers/net/macsec.c
index ca7f01d33483..41e17d737d33 100644
--- a/drivers/net/macsec.c
+++ b/drivers/net/macsec.c
@@ -3456,7 +3456,8 @@ static int macsec_dev_init(struct net_device *dev)
 		dev->features = REAL_DEV_FEATURES(real_dev);
 	} else {
 		dev->features = real_dev->features & SW_MACSEC_FEATURES;
-		dev->features |= NETIF_F_LLTX | NETIF_F_GSO_SOFTWARE;
+		dev->features |= NETIF_F_LLTX;
+		dev->features |= NETIF_F_GSO_SOFTWARE;
 	}
 
 	dev->needed_headroom = real_dev->needed_headroom +
@@ -3488,12 +3489,15 @@ static netdev_features_t macsec_fix_features(struct net_device *dev,
 {
 	struct macsec_dev *macsec = macsec_priv(dev);
 	struct net_device *real_dev = macsec->real_dev;
+	netdev_features_t tmp;
 
 	if (macsec_is_offloaded(macsec))
 		return REAL_DEV_FEATURES(real_dev);
 
-	features &= (real_dev->features & SW_MACSEC_FEATURES) |
-		    NETIF_F_GSO_SOFTWARE | NETIF_F_SOFT_FEATURES;
+	tmp = real_dev->features & SW_MACSEC_FEATURES;
+	tmp |= NETIF_F_GSO_SOFTWARE;
+	tmp |= NETIF_F_SOFT_FEATURES;
+	features &= tmp;
 	features |= NETIF_F_LLTX;
 
 	return features;
diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c
index d9a20c0341c6..aac040522ee9 100644
--- a/drivers/net/macvlan.c
+++ b/drivers/net/macvlan.c
@@ -1099,15 +1099,22 @@ static netdev_features_t macvlan_fix_features(struct net_device *dev,
 	struct macvlan_dev *vlan = netdev_priv(dev);
 	netdev_features_t lowerdev_features = vlan->lowerdev->features;
 	netdev_features_t mask;
+	netdev_features_t tmp;
 
 	features |= NETIF_F_ALL_FOR_ALL;
-	features &= (vlan->set_features | ~MACVLAN_FEATURES);
+	netdev_features_fill(&tmp);
+	tmp &= ~MACVLAN_FEATURES;
+	tmp |= vlan->set_features;
+	features &= tmp;
 	mask = features;
 
-	lowerdev_features &= (features | ~NETIF_F_LRO);
+	tmp = features;
+	tmp &= ~NETIF_F_LRO;
+	lowerdev_features &= tmp;
 	features = netdev_increment_features(lowerdev_features, features, mask);
 	features |= ALWAYS_ON_FEATURES;
-	features &= (ALWAYS_ON_FEATURES | MACVLAN_FEATURES);
+	tmp = ALWAYS_ON_FEATURES | MACVLAN_FEATURES;
+	features &= tmp;
 
 	return features;
 }
diff --git a/drivers/net/netdevsim/netdev.c b/drivers/net/netdevsim/netdev.c
index ad687b14dda3..d501c7c58f70 100644
--- a/drivers/net/netdevsim/netdev.c
+++ b/drivers/net/netdevsim/netdev.c
@@ -233,7 +233,7 @@ nsim_set_features(struct net_device *dev, netdev_features_t features)
 {
 	struct netdevsim *ns = netdev_priv(dev);
 
-	if ((dev->features & NETIF_F_HW_TC) > (features & NETIF_F_HW_TC))
+	if ((dev->features & NETIF_F_HW_TC) && !(features & NETIF_F_HW_TC))
 		return nsim_bpf_disable_tc(ns);
 
 	return 0;
diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c
index eec3c8112d3f..4c999e18d4a1 100644
--- a/drivers/net/team/team.c
+++ b/drivers/net/team/team.c
@@ -2184,9 +2184,9 @@ static void team_setup(struct net_device *dev)
 	/* Don't allow team devices to change network namespaces. */
 	dev->features |= NETIF_F_NETNS_LOCAL;
 
-	dev->hw_features = TEAM_VLAN_FEATURES |
-			   NETIF_F_HW_VLAN_CTAG_RX |
-			   NETIF_F_HW_VLAN_CTAG_FILTER;
+	dev->hw_features = TEAM_VLAN_FEATURES;
+	dev->hw_features |= NETIF_F_HW_VLAN_CTAG_RX;
+	dev->hw_features |= NETIF_F_HW_VLAN_CTAG_FILTER;
 
 	dev->hw_features |= NETIF_F_GSO_ENCAP_ALL;
 	dev->features |= dev->hw_features;
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index 194757bbd2b3..322956768815 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -1003,7 +1003,8 @@ static int tun_net_init(struct net_device *dev)
 
 	dev->hw_features = TUN_USER_FEATURES;
 	netdev_hw_features_set_array(dev, &tun_hw_feature_set);
-	dev->features = dev->hw_features | NETIF_F_LLTX;
+	dev->features = dev->hw_features;
+	dev->features |= NETIF_F_LLTX;
 	dev->vlan_features = dev->features & ~netdev_tx_vlan_features;
 
 	tun->flags = (tun->flags & ~TUN_FEATURES) |
@@ -1174,8 +1175,11 @@ static netdev_features_t tun_net_fix_features(struct net_device *dev,
 	netdev_features_t features)
 {
 	struct tun_struct *tun = netdev_priv(dev);
+	netdev_features_t tmp1, tmp2;
 
-	return (features & tun->set_features) | (features & ~TUN_USER_FEATURES);
+	tmp1 = features & tun->set_features;
+	tmp2 = features & ~TUN_USER_FEATURES;
+	return tmp1 | tmp2;
 }
 
 static void tun_set_headroom(struct net_device *dev, int new_hr)
diff --git a/drivers/net/usb/cdc_mbim.c b/drivers/net/usb/cdc_mbim.c
index c89639381eca..29451eb7263b 100644
--- a/drivers/net/usb/cdc_mbim.c
+++ b/drivers/net/usb/cdc_mbim.c
@@ -185,7 +185,8 @@ static int cdc_mbim_bind(struct usbnet *dev, struct usb_interface *intf)
 	dev->net->flags |= IFF_NOARP;
 
 	/* no need to put the VLAN tci in the packet headers */
-	dev->net->features |= NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_FILTER;
+	dev->net->features |= NETIF_F_HW_VLAN_CTAG_TX;
+	dev->net->features |= NETIF_F_HW_VLAN_CTAG_FILTER;
 
 	/* monitor VLAN additions and removals */
 	dev->net->netdev_ops = &cdc_mbim_netdev_ops;
diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c
index bfb58c91db04..10cf0a68980e 100644
--- a/drivers/net/usb/smsc95xx.c
+++ b/drivers/net/usb/smsc95xx.c
@@ -1085,7 +1085,8 @@ static int smsc95xx_bind(struct usbnet *dev, struct usb_interface *intf)
 	if (DEFAULT_RX_CSUM_ENABLE)
 		dev->net->features |= NETIF_F_RXCSUM;
 
-	dev->net->hw_features = NETIF_F_IP_CSUM | NETIF_F_RXCSUM;
+	dev->net->hw_features = NETIF_F_IP_CSUM;
+	dev->net->hw_features |= NETIF_F_RXCSUM;
 	set_bit(EVENT_NO_IP_ALIGN, &dev->flags);
 
 	smsc95xx_init_mac_address(dev);
diff --git a/drivers/net/veth.c b/drivers/net/veth.c
index 5978baef9695..805056a246cc 100644
--- a/drivers/net/veth.c
+++ b/drivers/net/veth.c
@@ -307,7 +307,8 @@ static bool veth_skb_is_eligible_for_gro(const struct net_device *dev,
 {
 	return !(dev->features & NETIF_F_ALL_TSO) ||
 		(skb->destructor == sock_wfree &&
-		 rcv->features & (NETIF_F_GRO_FRAGLIST | NETIF_F_GRO_UDP_FWD));
+		 (rcv->features & NETIF_F_GRO_FRAGLIST ||
+		  rcv->features & NETIF_F_GRO_UDP_FWD));
 }
 
 static netdev_tx_t veth_xmit(struct sk_buff *skb, struct net_device *dev)
@@ -1657,7 +1658,8 @@ static void veth_setup(struct net_device *dev)
 
 	dev->hw_features = veth_features;
 	dev->hw_enc_features = veth_features;
-	dev->mpls_features = NETIF_F_HW_CSUM | NETIF_F_GSO_SOFTWARE;
+	dev->mpls_features = NETIF_F_GSO_SOFTWARE;
+	dev->mpls_features |= NETIF_F_HW_CSUM;
 	netif_set_tso_max_size(dev, GSO_MAX_SIZE);
 }
 
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index c40d80f25809..3d8f4da73bd7 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -3510,9 +3510,12 @@ static int virtnet_probe(struct virtio_device *vdev)
 	/* Do we support "hardware" checksums? */
 	if (virtio_has_feature(vdev, VIRTIO_NET_F_CSUM)) {
 		/* This opens up the world of extra features. */
-		dev->hw_features |= NETIF_F_HW_CSUM | NETIF_F_SG;
-		if (csum)
-			dev->features |= NETIF_F_HW_CSUM | NETIF_F_SG;
+		dev->hw_features |= NETIF_F_HW_CSUM;
+		dev->hw_features |= NETIF_F_SG;
+		if (csum) {
+			dev->features |= NETIF_F_HW_CSUM;
+			dev->features |= NETIF_F_SG;
+		}
 
 		if (virtio_has_feature(vdev, VIRTIO_NET_F_GSO)) {
 			dev->hw_features |= netdev_general_tso_features;
@@ -3528,8 +3531,11 @@ static int virtnet_probe(struct virtio_device *vdev)
 
 		dev->features |= NETIF_F_GSO_ROBUST;
 
-		if (gso)
-			dev->features |= dev->hw_features & NETIF_F_ALL_TSO;
+		if (gso) {
+			netdev_features_t tmp = dev->hw_features & NETIF_F_ALL_TSO;
+
+			dev->features |= tmp;
+		}
 		/* (!csum && gso) case will be fixed by register_netdev() */
 	}
 	if (virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_CSUM))
diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c
index ede0a87ca982..9f8a074eab03 100644
--- a/drivers/net/vmxnet3/vmxnet3_drv.c
+++ b/drivers/net/vmxnet3/vmxnet3_drv.c
@@ -2592,8 +2592,8 @@ vmxnet3_setup_driver_shared(struct vmxnet3_adapter *adapter)
 	if (adapter->netdev->features & NETIF_F_HW_VLAN_CTAG_RX)
 		devRead->misc.uptFeatures |= UPT1_F_RXVLAN;
 
-	if (adapter->netdev->features & (NETIF_F_GSO_UDP_TUNNEL |
-					 NETIF_F_GSO_UDP_TUNNEL_CSUM))
+	if (adapter->netdev->features & NETIF_F_GSO_UDP_TUNNEL ||
+	    adapter->netdev->features & NETIF_F_GSO_UDP_TUNNEL_CSUM)
 		devRead->misc.uptFeatures |= UPT1_F_RXINNEROFLD;
 
 	devRead->misc.mtu = cpu_to_le32(adapter->netdev->mtu);
@@ -3332,8 +3332,8 @@ vmxnet3_declare_features(struct vmxnet3_adapter *adapter)
 	netdev_hw_features_set_array(netdev, &vmxnet3_hw_feature_set);
 
 	if (VMXNET3_VERSION_GE_4(adapter)) {
-		netdev->hw_features |= NETIF_F_GSO_UDP_TUNNEL |
-				NETIF_F_GSO_UDP_TUNNEL_CSUM;
+		netdev->hw_features |= NETIF_F_GSO_UDP_TUNNEL;
+		netdev->hw_features |= NETIF_F_GSO_UDP_TUNNEL_CSUM;
 		netdev_hw_enc_features_zero(netdev);
 		netdev_hw_enc_features_set_array(netdev,
 						 &vmxnet3_hw_enc_feature_set);
@@ -3389,7 +3389,8 @@ vmxnet3_declare_features(struct vmxnet3_adapter *adapter)
 
 	netdev->vlan_features = netdev->hw_features &
 				~netdev_ctag_vlan_offload_features;
-	netdev->features = netdev->hw_features | NETIF_F_HW_VLAN_CTAG_FILTER;
+	netdev->features = netdev->hw_features;
+	netdev->features |= NETIF_F_HW_VLAN_CTAG_FILTER;
 }
 
 
diff --git a/drivers/net/vmxnet3/vmxnet3_ethtool.c b/drivers/net/vmxnet3/vmxnet3_ethtool.c
index abc2aeb0559e..3ed93302084a 100644
--- a/drivers/net/vmxnet3/vmxnet3_ethtool.c
+++ b/drivers/net/vmxnet3/vmxnet3_ethtool.c
@@ -410,12 +410,18 @@ int vmxnet3_set_features(struct net_device *netdev, netdev_features_t features)
 	struct vmxnet3_adapter *adapter = netdev_priv(netdev);
 	unsigned long flags;
 	netdev_features_t changed = features ^ netdev->features;
-	netdev_features_t tun_offload_mask = NETIF_F_GSO_UDP_TUNNEL |
-					     NETIF_F_GSO_UDP_TUNNEL_CSUM;
-	u8 udp_tun_enabled = (netdev->features & tun_offload_mask) != 0;
-
-	if (changed & (NETIF_F_RXCSUM | NETIF_F_LRO |
-		       NETIF_F_HW_VLAN_CTAG_RX | tun_offload_mask)) {
+	netdev_features_t tun_offload_mask;
+	u8 udp_tun_enabled;
+
+	netdev_features_zero(&tun_offload_mask);
+	tun_offload_mask |= NETIF_F_GSO_UDP_TUNNEL;
+	tun_offload_mask |= NETIF_F_GSO_UDP_TUNNEL_CSUM;
+	udp_tun_enabled = (netdev->features & tun_offload_mask) != 0;
+
+	if (changed & NETIF_F_RXCSUM ||
+	    changed & NETIF_F_LRO ||
+	    changed & NETIF_F_HW_VLAN_CTAG_RX ||
+	    changed & tun_offload_mask) {
 		if (features & NETIF_F_RXCSUM)
 			adapter->shared->devRead.misc.uptFeatures |=
 			UPT1_F_RXCSUM;
diff --git a/drivers/net/wireless/ath/ath6kl/main.c b/drivers/net/wireless/ath/ath6kl/main.c
index d3aa9e7a37c2..8c57cd413e79 100644
--- a/drivers/net/wireless/ath/ath6kl/main.c
+++ b/drivers/net/wireless/ath/ath6kl/main.c
@@ -1143,7 +1143,8 @@ static int ath6kl_set_features(struct net_device *dev,
 							 vif->fw_vif_idx,
 							 ar->rx_meta_ver, 0, 0);
 		if (err) {
-			dev->features = features | NETIF_F_RXCSUM;
+			dev->features = features;
+			dev->features |= NETIF_F_RXCSUM;
 			return err;
 		}
 	}
@@ -1304,8 +1305,10 @@ void init_netdev(struct net_device *dev)
 					ATH6KL_HTC_ALIGN_BYTES, 4);
 
 	if (!test_bit(ATH6KL_FW_CAPABILITY_NO_IP_CHECKSUM,
-		      ar->fw_capabilities))
-		dev->hw_features |= NETIF_F_IP_CSUM | NETIF_F_RXCSUM;
+		      ar->fw_capabilities)) {
+		dev->hw_features |= NETIF_F_IP_CSUM;
+		dev->hw_features |= NETIF_F_RXCSUM;
+	}
 
 	return;
 }
diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/dvm/mac80211.c
index f4070fddc8c7..5f0bba0cfdf6 100644
--- a/drivers/net/wireless/intel/iwlwifi/dvm/mac80211.c
+++ b/drivers/net/wireless/intel/iwlwifi/dvm/mac80211.c
@@ -96,8 +96,10 @@ int iwlagn_mac_setup_register(struct iwl_priv *priv,
 	ieee80211_hw_set(hw, SUPPORT_FAST_XMIT);
 	ieee80211_hw_set(hw, WANT_MONITOR_VIF);
 
-	if (priv->trans->max_skb_frags)
-		hw->netdev_features = NETIF_F_HIGHDMA | NETIF_F_SG;
+	if (priv->trans->max_skb_frags) {
+		hw->netdev_features = NETIF_F_HIGHDMA;
+		hw->netdev_features |= NETIF_F_SG;
+	}
 
 	hw->offchannel_tx_hw_queue = IWL_AUX_QUEUE;
 	hw->radiotap_mcs_details |= IEEE80211_RADIOTAP_MCS_HAVE_FMT;
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
index 9a5abb7958b6..5fbeb262a90b 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
@@ -318,8 +318,10 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
 	if (mvm->trans->num_rx_queues > 1)
 		ieee80211_hw_set(hw, USES_RSS);
 
-	if (mvm->trans->max_skb_frags)
-		hw->netdev_features = NETIF_F_HIGHDMA | NETIF_F_SG;
+	if (mvm->trans->max_skb_frags) {
+		hw->netdev_features = NETIF_F_HIGHDMA;
+		hw->netdev_features |= NETIF_F_SG;
+	}
 
 	hw->queues = IEEE80211_NUM_ACS;
 	hw->offchannel_tx_hw_queue = IWL_MVM_OFFCHANNEL_QUEUE;
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
index f9e08b339e0c..3283c346fbe7 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
@@ -887,9 +887,12 @@ static int iwl_mvm_tx_tso(struct iwl_mvm *mvm, struct sk_buff *skb,
 	unsigned int mss = skb_shinfo(skb)->gso_size;
 	unsigned int num_subframes, tcp_payload_len, subf_len, max_amsdu_len;
 	u16 snap_ip_tcp, pad;
-	netdev_features_t netdev_flags = NETIF_F_CSUM_MASK | NETIF_F_SG;
+	netdev_features_t netdev_flags;
 	u8 tid;
 
+	netdev_flags = NETIF_F_CSUM_MASK;
+	netdev_flags |= NETIF_F_SG;
+
 	snap_ip_tcp = 8 + skb_transport_header(skb) - skb_network_header(skb) +
 		tcp_hdrlen(skb);
 
diff --git a/drivers/net/xen-netback/interface.c b/drivers/net/xen-netback/interface.c
index 989328168e1c..8c37a65d8d06 100644
--- a/drivers/net/xen-netback/interface.c
+++ b/drivers/net/xen-netback/interface.c
@@ -533,7 +533,8 @@ struct xenvif *xenvif_alloc(struct device *parent, domid_t domid,
 	dev->netdev_ops	= &xenvif_netdev_ops;
 	netdev_hw_features_zero(dev);
 	netdev_hw_features_set_array(dev, &xenvif_hw_feature_set);
-	dev->features = dev->hw_features | NETIF_F_RXCSUM;
+	dev->features = dev->hw_features;
+	dev->features |= NETIF_F_RXCSUM;
 	dev->ethtool_ops = &xenvif_ethtool_ops;
 
 	dev->tx_queue_len = XENVIF_QUEUE_LENGTH;
diff --git a/drivers/staging/octeon/ethernet.c b/drivers/staging/octeon/ethernet.c
index f662739137b5..0811ff9452f7 100644
--- a/drivers/staging/octeon/ethernet.c
+++ b/drivers/staging/octeon/ethernet.c
@@ -421,8 +421,10 @@ int cvm_oct_common_init(struct net_device *dev)
 	    (always_use_pow || strstr(pow_send_list, dev->name)))
 		priv->queue = -1;
 
-	if (priv->queue != -1)
-		dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM;
+	if (priv->queue != -1) {
+		dev->features |= NETIF_F_SG;
+		dev->features |= NETIF_F_IP_CSUM;
+	}
 
 	/* We do our own locking, Linux doesn't need to */
 	dev->features |= NETIF_F_LLTX;
diff --git a/include/linux/netdev_features_helper.h b/include/linux/netdev_features_helper.h
index e096786e4b7a..772401f25a81 100644
--- a/include/linux/netdev_features_helper.h
+++ b/include/linux/netdev_features_helper.h
@@ -688,7 +688,7 @@ static inline bool netdev_features_subset(const netdev_features_t src1,
 static inline netdev_features_t netdev_intersect_features(netdev_features_t f1,
 							  netdev_features_t f2)
 {
-	if ((f1 ^ f2) & NETIF_F_HW_CSUM) {
+	if ((f1 & NETIF_F_HW_CSUM) != (f2 & NETIF_F_HW_CSUM)) {
 		if (f1 & NETIF_F_HW_CSUM)
 			f1 |= netdev_ip_csum_features;
 		else
@@ -701,7 +701,10 @@ static inline netdev_features_t netdev_intersect_features(netdev_features_t f1,
 static inline netdev_features_t
 netdev_get_wanted_features(struct net_device *dev)
 {
-	return (dev->features & ~dev->hw_features) | dev->wanted_features;
+	netdev_features_t tmp;
+
+	tmp = dev->features & ~dev->hw_features;
+	return dev->wanted_features | tmp;
 }
 
 #endif
diff --git a/net/8021q/vlan.h b/net/8021q/vlan.h
index 5eaf38875554..60b5e401e346 100644
--- a/net/8021q/vlan.h
+++ b/net/8021q/vlan.h
@@ -5,6 +5,7 @@
 #include <linux/if_vlan.h>
 #include <linux/u64_stats_sync.h>
 #include <linux/list.h>
+#include <linux/netdev_features_helper.h>
 
 /* if this changes, algorithm will have to be reworked because this
  * depends on completely exhausting the VLAN identifier space.  Thus
@@ -107,13 +108,17 @@ static inline netdev_features_t vlan_tnl_features(struct net_device *real_dev)
 {
 	netdev_features_t ret;
 
-	ret = real_dev->hw_enc_features &
-	      (NETIF_F_CSUM_MASK | NETIF_F_GSO_SOFTWARE |
-	       NETIF_F_GSO_ENCAP_ALL);
+	ret = NETIF_F_CSUM_MASK | NETIF_F_GSO_SOFTWARE;
+	ret |= NETIF_F_GSO_ENCAP_ALL;
+	ret &= real_dev->hw_enc_features;
 
-	if ((ret & NETIF_F_GSO_ENCAP_ALL) && (ret & NETIF_F_CSUM_MASK))
-		return (ret & ~NETIF_F_CSUM_MASK) | NETIF_F_HW_CSUM;
-	return 0;
+	if ((ret & NETIF_F_GSO_ENCAP_ALL) && (ret & NETIF_F_CSUM_MASK)) {
+		ret &= ~NETIF_F_CSUM_MASK;
+		ret |= NETIF_F_HW_CSUM;
+		return ret;
+	}
+	netdev_features_zero(&ret);
+	return ret;
 }
 
 #define vlan_group_for_each_dev(grp, i, dev) \
diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c
index 3af719812f00..ab2847fa938d 100644
--- a/net/8021q/vlan_dev.c
+++ b/net/8021q/vlan_dev.c
@@ -578,7 +578,8 @@ static int vlan_dev_init(struct net_device *dev)
 	dev->hw_features |= NETIF_F_ALL_FCOE;
 	netdev_hw_features_set_array(dev, &vlan_hw_feature_set);
 
-	dev->features |= dev->hw_features | NETIF_F_LLTX;
+	dev->features |= dev->hw_features;
+	dev->features |= NETIF_F_LLTX;
 	netif_inherit_tso_max(dev, real_dev);
 	if (dev->features & NETIF_F_VLAN_FEATURES)
 		netdev_warn(real_dev, "VLAN features are set incorrectly.  Q-in-Q configurations may not work correctly.\n");
@@ -652,10 +653,11 @@ 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;
+	netdev_features_t tmp;
 
-	lower_features = netdev_intersect_features((real_dev->vlan_features |
-						    NETIF_F_RXCSUM),
-						   real_dev->features);
+	tmp = real_dev->vlan_features;
+	tmp |= NETIF_F_RXCSUM;
+	lower_features = netdev_intersect_features(tmp, real_dev->features);
 
 	/* Add HW_CSUM setting to preserve user ability to control
 	 * checksum offload on the vlan device.
@@ -663,7 +665,9 @@ static netdev_features_t vlan_dev_fix_features(struct net_device *dev,
 	if (lower_features & netdev_ip_csum_features)
 		lower_features |= NETIF_F_HW_CSUM;
 	features = netdev_intersect_features(features, lower_features);
-	features |= old_features & (NETIF_F_SOFT_FEATURES | NETIF_F_GSO_SOFTWARE);
+	tmp = NETIF_F_SOFT_FEATURES | NETIF_F_GSO_SOFTWARE;
+	tmp &= old_features;
+	features |= tmp;
 	features |= NETIF_F_LLTX;
 
 	return features;
diff --git a/net/core/dev.c b/net/core/dev.c
index 7a57d8b4f307..2a0f31c66dea 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -3552,6 +3552,7 @@ netdev_features_t netif_skb_features(struct sk_buff *skb)
 {
 	struct net_device *dev = skb->dev;
 	netdev_features_t features = dev->features;
+	netdev_features_t tmp;
 
 	if (skb_is_gso(skb))
 		features = gso_features_check(skb, dev, features);
@@ -3563,16 +3564,16 @@ netdev_features_t netif_skb_features(struct sk_buff *skb)
 	if (skb->encapsulation)
 		features &= dev->hw_enc_features;
 
-	if (skb_vlan_tagged(skb))
-		features = netdev_intersect_features(features,
-						     dev->vlan_features |
-						     netdev_tx_vlan_features);
+	if (skb_vlan_tagged(skb)) {
+		tmp = dev->vlan_features | netdev_tx_vlan_features;
+		features = netdev_intersect_features(features, tmp);
+	}
 
 	if (dev->netdev_ops->ndo_features_check)
-		features &= dev->netdev_ops->ndo_features_check(skb, dev,
-								features);
+		tmp = dev->netdev_ops->ndo_features_check(skb, dev, features);
 	else
-		features &= dflt_features_check(skb, dev, features);
+		tmp = dflt_features_check(skb, dev, features);
+	features &= tmp;
 
 	return harmonize_features(skb, features);
 }
@@ -9606,6 +9607,8 @@ static void netdev_sync_lower_features(struct net_device *upper,
 static netdev_features_t netdev_fix_features(struct net_device *dev,
 	netdev_features_t features)
 {
+	netdev_features_t tmp;
+
 	/* Fix illegal checksum combinations */
 	if ((features & NETIF_F_HW_CSUM) &&
 	    (features & netdev_ip_csum_features)) {
@@ -9637,7 +9640,9 @@ static netdev_features_t netdev_fix_features(struct net_device *dev,
 		features &= ~NETIF_F_TSO_MANGLEID;
 
 	/* TSO ECN requires that TSO is present as well. */
-	if ((features & NETIF_F_ALL_TSO) == NETIF_F_TSO_ECN)
+	tmp = NETIF_F_ALL_TSO;
+	tmp &= ~NETIF_F_TSO_ECN;
+	if (!(features & tmp) && (features & NETIF_F_TSO_ECN))
 		features &= ~NETIF_F_TSO_ECN;
 
 	/* Software GSO depends on SG. */
@@ -10007,8 +10012,8 @@ int register_netdevice(struct net_device *dev)
 		}
 	}
 
-	if (((dev->hw_features | dev->features) &
-	     NETIF_F_HW_VLAN_CTAG_FILTER) &&
+	if ((dev->hw_features & NETIF_F_HW_VLAN_CTAG_FILTER ||
+	     dev->features & NETIF_F_HW_VLAN_CTAG_FILTER) &&
 	    (!dev->netdev_ops->ndo_vlan_rx_add_vid ||
 	     !dev->netdev_ops->ndo_vlan_rx_kill_vid)) {
 		netdev_WARN(dev, "Buggy VLAN acceleration in driver!\n");
@@ -10025,7 +10030,8 @@ int register_netdevice(struct net_device *dev)
 	/* Transfer changeable features to wanted_features and enable
 	 * software offloads (GSO and GRO).
 	 */
-	dev->hw_features |= (NETIF_F_SOFT_FEATURES | NETIF_F_SOFT_FEATURES_OFF);
+	dev->hw_features |= NETIF_F_SOFT_FEATURES;
+	dev->hw_features |= NETIF_F_SOFT_FEATURES_OFF;
 	dev->features |= NETIF_F_SOFT_FEATURES;
 
 	if (dev->udp_tunnel_nic_info) {
@@ -10058,7 +10064,8 @@ int register_netdevice(struct net_device *dev)
 
 	/* Make NETIF_F_SG inheritable to tunnel devices.
 	 */
-	dev->hw_enc_features |= NETIF_F_SG | NETIF_F_GSO_PARTIAL;
+	dev->hw_enc_features |= NETIF_F_SG;
+	dev->hw_enc_features |= NETIF_F_GSO_PARTIAL;
 
 	/* Make NETIF_F_SG inheritable to MPLS.
 	 */
@@ -11147,16 +11154,28 @@ static int dev_cpu_dead(unsigned int oldcpu)
 netdev_features_t netdev_increment_features(netdev_features_t all,
 	netdev_features_t one, netdev_features_t mask)
 {
+	netdev_features_t tmp;
+
 	if (mask & NETIF_F_HW_CSUM)
 		mask |= NETIF_F_CSUM_MASK;
 	mask |= NETIF_F_VLAN_CHALLENGED;
 
-	all |= one & (NETIF_F_ONE_FOR_ALL | NETIF_F_CSUM_MASK) & mask;
-	all &= one | ~NETIF_F_ALL_FOR_ALL;
+	tmp = NETIF_F_ONE_FOR_ALL | NETIF_F_CSUM_MASK;
+	tmp &= one;
+	tmp &= mask;
+	all |= tmp;
+
+	netdev_features_fill(&tmp);
+	tmp &= ~NETIF_F_ALL_FOR_ALL;
+	tmp |= one;
+	all &= tmp;
 
 	/* If one device supports hw checksumming, set for all. */
-	if (all & NETIF_F_HW_CSUM)
-		all &= ~(NETIF_F_CSUM_MASK & ~NETIF_F_HW_CSUM);
+	if (all & NETIF_F_HW_CSUM) {
+		tmp = NETIF_F_CSUM_MASK;
+		tmp &= ~NETIF_F_HW_CSUM;
+		all &= ~tmp;
+	}
 
 	return all;
 }
diff --git a/net/core/pktgen.c b/net/core/pktgen.c
index 88906ba6d9a7..198d94f2e8f0 100644
--- a/net/core/pktgen.c
+++ b/net/core/pktgen.c
@@ -2963,7 +2963,8 @@ static struct sk_buff *fill_packet_ipv4(struct net_device *odev,
 
 	if (!(pkt_dev->flags & F_UDPCSUM)) {
 		skb->ip_summed = CHECKSUM_NONE;
-	} else if (odev->features & (NETIF_F_HW_CSUM | NETIF_F_IP_CSUM)) {
+	} else if (odev->features & NETIF_F_HW_CSUM ||
+		   odev->features & NETIF_F_IP_CSUM) {
 		skb->ip_summed = CHECKSUM_PARTIAL;
 		skb->csum = 0;
 		udp4_hwcsum(skb, iph->saddr, iph->daddr);
@@ -3098,7 +3099,8 @@ static struct sk_buff *fill_packet_ipv6(struct net_device *odev,
 
 	if (!(pkt_dev->flags & F_UDPCSUM)) {
 		skb->ip_summed = CHECKSUM_NONE;
-	} else if (odev->features & (NETIF_F_HW_CSUM | NETIF_F_IPV6_CSUM)) {
+	} else if (odev->features & NETIF_F_HW_CSUM ||
+		   odev->features & NETIF_F_IPV6_CSUM) {
 		skb->ip_summed = CHECKSUM_PARTIAL;
 		skb->csum_start = skb_transport_header(skb) - skb->head;
 		skb->csum_offset = offsetof(struct udphdr, check);
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 974bbbbe7138..955d7640dde6 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -4312,7 +4312,7 @@ struct sk_buff *skb_segment(struct sk_buff *head_skb,
 		unsigned short gso_size = skb_shinfo(head_skb)->gso_size;
 
 		/* Update type to add partial and then remove dodgy if set */
-		type |= (features & NETIF_F_GSO_PARTIAL) / NETIF_F_GSO_PARTIAL * SKB_GSO_PARTIAL;
+		type |= (features & NETIF_F_GSO_PARTIAL) ? 0 : SKB_GSO_PARTIAL;
 		type &= ~SKB_GSO_DODGY;
 
 		/* Update GSO info and prepare to start updating headers on
diff --git a/net/core/sock.c b/net/core/sock.c
index 4cb957d934a2..3127552e8989 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -2326,7 +2326,8 @@ void sk_setup_caps(struct sock *sk, struct dst_entry *dst)
 		if (dst->header_len && !xfrm_dst_offload_ok(dst)) {
 			sk->sk_route_caps &= ~NETIF_F_GSO_MASK;
 		} else {
-			sk->sk_route_caps |= NETIF_F_SG | NETIF_F_HW_CSUM;
+			sk->sk_route_caps |= NETIF_F_SG;
+			sk->sk_route_caps |= NETIF_F_HW_CSUM;
 			/* pairs with the WRITE_ONCE() in netif_set_gso_max_size() */
 			sk->sk_gso_max_size = READ_ONCE(dst->dev->gso_max_size);
 			sk_trim_gso_size(sk);
diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c
index fd44638ec16b..53fa477d20ab 100644
--- a/net/dccp/ipv6.c
+++ b/net/dccp/ipv6.c
@@ -489,8 +489,9 @@ static struct sock *dccp_v6_request_recv_sock(const struct sock *sk,
 	 */
 
 	ip6_dst_store(newsk, dst, NULL, NULL);
-	newsk->sk_route_caps = dst->dev->features & ~(NETIF_F_IP_CSUM |
-						      NETIF_F_TSO);
+	newsk->sk_route_caps = dst->dev->features;
+	newsk->sk_route_caps &= ~NETIF_F_IP_CSUM;
+	newsk->sk_route_caps &= ~NETIF_F_TSO;
 	newdp6 = (struct dccp6_sock *)newsk;
 	newinet = inet_sk(newsk);
 	newinet->pinet6 = &newdp6->inet6;
diff --git a/net/dsa/slave.c b/net/dsa/slave.c
index ad6a6663feeb..a7e831bc5632 100644
--- a/net/dsa/slave.c
+++ b/net/dsa/slave.c
@@ -2287,11 +2287,14 @@ void dsa_slave_setup_tagger(struct net_device *slave)
 
 	p->xmit = cpu_dp->tag_ops->xmit;
 
-	slave->features = master->vlan_features | NETIF_F_HW_TC;
+	slave->features = master->vlan_features;
+	slave->features |= NETIF_F_HW_TC;
 	slave->hw_features |= NETIF_F_HW_TC;
 	slave->features |= NETIF_F_LLTX;
-	if (slave->needed_tailroom)
-		slave->features &= ~(NETIF_F_SG | NETIF_F_FRAGLIST);
+	if (slave->needed_tailroom) {
+		slave->features &= ~NETIF_F_SG;
+		slave->features &= ~NETIF_F_FRAGLIST;
+	}
 	if (ds->needs_standalone_vlan_filtering)
 		slave->features |= NETIF_F_HW_VLAN_CTAG_FILTER;
 }
diff --git a/net/ethtool/features.c b/net/ethtool/features.c
index 55d449a2d3fc..67a837d44491 100644
--- a/net/ethtool/features.c
+++ b/net/ethtool/features.c
@@ -220,6 +220,7 @@ int ethnl_set_features(struct sk_buff *skb, struct genl_info *info)
 	struct ethnl_req_info req_info = {};
 	struct nlattr **tb = info->attrs;
 	struct net_device *dev;
+	netdev_features_t tmp;
 	bool mod;
 	int ret;
 
@@ -253,7 +254,8 @@ int ethnl_set_features(struct sk_buff *skb, struct genl_info *info)
 	bitmap_or(req_wanted, new_wanted, req_wanted, NETDEV_FEATURE_COUNT);
 	if (!bitmap_equal(req_wanted, old_wanted, NETDEV_FEATURE_COUNT)) {
 		dev->wanted_features &= ~dev->hw_features;
-		dev->wanted_features |= ethnl_bitmap_to_features(req_wanted) & dev->hw_features;
+		tmp = ethnl_bitmap_to_features(req_wanted) & dev->hw_features;
+		dev->wanted_features |= tmp;
 		__netdev_update_features(dev);
 	}
 	ethnl_features_to_bitmap(new_active, dev->features);
diff --git a/net/ethtool/ioctl.c b/net/ethtool/ioctl.c
index 2ed9277a873e..8f32e4f06bfb 100644
--- a/net/ethtool/ioctl.c
+++ b/net/ethtool/ioctl.c
@@ -126,6 +126,7 @@ static int ethtool_set_features(struct net_device *dev, void __user *useraddr)
 	struct ethtool_sfeatures cmd;
 	struct ethtool_set_features_block features[ETHTOOL_DEV_FEATURE_WORDS];
 	netdev_features_t wanted = 0, valid = 0;
+	netdev_features_t tmp;
 	int i, ret = 0;
 
 	if (copy_from_user(&cmd, useraddr, sizeof(cmd)))
@@ -143,19 +144,23 @@ static int ethtool_set_features(struct net_device *dev, void __user *useraddr)
 		wanted |= (netdev_features_t)features[i].requested << (32 * i);
 	}
 
-	if (valid & ~NETIF_F_ETHTOOL_BITS)
+	tmp = valid & ~NETIF_F_ETHTOOL_BITS;
+	if (tmp)
 		return -EINVAL;
 
-	if (valid & ~dev->hw_features) {
+	tmp = valid & ~dev->hw_features;
+	if (tmp) {
 		valid &= dev->hw_features;
 		ret |= ETHTOOL_F_UNSUPPORTED;
 	}
 
 	dev->wanted_features &= ~valid;
-	dev->wanted_features |= wanted & valid;
+	tmp = wanted & valid;
+	dev->wanted_features |= tmp;
 	__netdev_update_features(dev);
 
-	if ((dev->wanted_features ^ dev->features) & valid)
+	tmp = dev->wanted_features ^ dev->features;
+	if (tmp & valid)
 		ret |= ETHTOOL_F_WISH;
 
 	return ret;
@@ -222,28 +227,38 @@ static void __ethtool_get_strings(struct net_device *dev,
 
 static netdev_features_t ethtool_get_feature_mask(u32 eth_cmd)
 {
+	netdev_features_t tmp;
+
 	/* feature masks of legacy discrete ethtool ops */
 
+	netdev_features_zero(&tmp);
 	switch (eth_cmd) {
 	case ETHTOOL_GTXCSUM:
 	case ETHTOOL_STXCSUM:
-		return NETIF_F_CSUM_MASK | NETIF_F_FCOE_CRC |
-		       NETIF_F_SCTP_CRC;
+		tmp = NETIF_F_CSUM_MASK;
+		tmp |= NETIF_F_FCOE_CRC;
+		tmp |= NETIF_F_SCTP_CRC;
+		return tmp;
 	case ETHTOOL_GRXCSUM:
 	case ETHTOOL_SRXCSUM:
-		return NETIF_F_RXCSUM;
+		tmp |= NETIF_F_RXCSUM;
+		return tmp;
 	case ETHTOOL_GSG:
 	case ETHTOOL_SSG:
-		return NETIF_F_SG | NETIF_F_FRAGLIST;
+		tmp |= NETIF_F_SG;
+		tmp |= NETIF_F_FRAGLIST;
+		return tmp;
 	case ETHTOOL_GTSO:
 	case ETHTOOL_STSO:
 		return NETIF_F_ALL_TSO;
 	case ETHTOOL_GGSO:
 	case ETHTOOL_SGSO:
-		return NETIF_F_GSO;
+		tmp |= NETIF_F_GSO;
+		return tmp;
 	case ETHTOOL_GGRO:
 	case ETHTOOL_SGRO:
-		return NETIF_F_GRO;
+		tmp |= NETIF_F_GRO;
+		return tmp;
 	default:
 		BUG();
 	}
@@ -319,6 +334,7 @@ static int __ethtool_set_flags(struct net_device *dev, u32 data)
 {
 	netdev_features_t features = 0, changed;
 	netdev_features_t eth_all_features;
+	netdev_features_t tmp;
 
 	if (data & ~ETH_ALL_FLAGS)
 		return -EINVAL;
@@ -338,12 +354,15 @@ static int __ethtool_set_flags(struct net_device *dev, u32 data)
 	netdev_features_set_array(&ethtool_all_feature_set, &eth_all_features);
 
 	/* allow changing only bits set in hw_features */
-	changed = (features ^ dev->features) & eth_all_features;
-	if (changed & ~dev->hw_features)
+	changed = dev->features ^ features;
+	changed &= eth_all_features;
+	tmp = changed & ~dev->hw_features;
+	if (tmp)
 		return (changed & dev->hw_features) ? -EINVAL : -EOPNOTSUPP;
 
-	dev->wanted_features =
-		(dev->wanted_features & ~changed) | (features & changed);
+	dev->wanted_features &= ~changed;
+	tmp = features & changed;
+	dev->wanted_features |= tmp;
 
 	__netdev_update_features(dev);
 
diff --git a/net/ipv4/esp4_offload.c b/net/ipv4/esp4_offload.c
index 935026f4c807..2931b3385bc9 100644
--- a/net/ipv4/esp4_offload.c
+++ b/net/ipv4/esp4_offload.c
@@ -218,13 +218,15 @@ static struct sk_buff *esp4_gso_segment(struct sk_buff *skb,
 	skb->encap_hdr_csum = 1;
 
 	if ((!(skb->dev->gso_partial_features & NETIF_F_HW_ESP) &&
-	     !(features & NETIF_F_HW_ESP)) || x->xso.dev != skb->dev)
-		esp_features = features & ~(NETIF_F_SG | NETIF_F_CSUM_MASK |
-					    NETIF_F_SCTP_CRC);
-	else if (!(features & NETIF_F_HW_ESP_TX_CSUM) &&
-		 !(skb->dev->gso_partial_features & NETIF_F_HW_ESP_TX_CSUM))
-		esp_features = features & ~(NETIF_F_CSUM_MASK |
-					    NETIF_F_SCTP_CRC);
+	     !(features & NETIF_F_HW_ESP)) || x->xso.dev != skb->dev) {
+		esp_features = features & ~NETIF_F_CSUM_MASK;
+		esp_features &= ~NETIF_F_SG;
+		esp_features &= ~NETIF_F_SCTP_CRC;
+	} else if (!(features & NETIF_F_HW_ESP_TX_CSUM) &&
+		 !(skb->dev->gso_partial_features & NETIF_F_HW_ESP_TX_CSUM)) {
+		esp_features = features & ~NETIF_F_CSUM_MASK;
+		esp_features  &= ~NETIF_F_SCTP_CRC;
+	}
 
 	xo->flags |= XFRM_GSO_SEGMENT;
 
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index d7bd1daf022b..9ca2620de9ea 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -1012,7 +1012,8 @@ static int __ip_append_data(struct sock *sk,
 	 */
 	if (transhdrlen &&
 	    length + fragheaderlen <= mtu &&
-	    rt->dst.dev->features & (NETIF_F_HW_CSUM | NETIF_F_IP_CSUM) &&
+	    (rt->dst.dev->features & NETIF_F_HW_CSUM ||
+	     rt->dst.dev->features & NETIF_F_IP_CSUM) &&
 	    (!(flags & MSG_MORE) || cork->gso_size) &&
 	    (!exthdrlen || (rt->dst.dev->features & NETIF_F_HW_ESP_TX_CSUM)))
 		csummode = CHECKSUM_PARTIAL;
diff --git a/net/ipv4/udp_offload.c b/net/ipv4/udp_offload.c
index 6d1a4bec2614..0486dbe58390 100644
--- a/net/ipv4/udp_offload.c
+++ b/net/ipv4/udp_offload.c
@@ -64,9 +64,9 @@ static struct sk_buff *__skb_udp_tunnel_segment(struct sk_buff *skb,
 	/* Try to offload checksum if possible */
 	offload_csum = !!(need_csum &&
 			  !need_ipsec &&
-			  (skb->dev->features &
-			   (is_ipv6 ? (NETIF_F_HW_CSUM | NETIF_F_IPV6_CSUM) :
-				      (NETIF_F_HW_CSUM | NETIF_F_IP_CSUM))));
+			  (skb->dev->features & NETIF_F_HW_CSUM ||
+			   (is_ipv6 ? (skb->dev->features & NETIF_F_IPV6_CSUM) :
+				      (skb->dev->features & NETIF_F_IP_CSUM))));
 
 	features &= skb->dev->hw_enc_features;
 	if (need_csum)
diff --git a/net/ipv6/esp6_offload.c b/net/ipv6/esp6_offload.c
index 3a293838a91d..95b5c26abad5 100644
--- a/net/ipv6/esp6_offload.c
+++ b/net/ipv6/esp6_offload.c
@@ -256,12 +256,14 @@ static struct sk_buff *esp6_gso_segment(struct sk_buff *skb,
 
 	skb->encap_hdr_csum = 1;
 
-	if (!(features & NETIF_F_HW_ESP) || x->xso.dev != skb->dev)
-		esp_features = features & ~(NETIF_F_SG | NETIF_F_CSUM_MASK |
-					    NETIF_F_SCTP_CRC);
-	else if (!(features & NETIF_F_HW_ESP_TX_CSUM))
-		esp_features = features & ~(NETIF_F_CSUM_MASK |
-					    NETIF_F_SCTP_CRC);
+	if (!(features & NETIF_F_HW_ESP) || x->xso.dev != skb->dev) {
+		esp_features = features & ~NETIF_F_CSUM_MASK;
+		esp_features &= ~NETIF_F_SG;
+		esp_features &= ~NETIF_F_SCTP_CRC;
+	} else if (!(features & NETIF_F_HW_ESP_TX_CSUM)) {
+		esp_features = features & ~NETIF_F_CSUM_MASK;
+		esp_features  &= ~NETIF_F_SCTP_CRC;
+	}
 
 	xo->flags |= XFRM_GSO_SEGMENT;
 
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index 897ca4f9b791..f8fca2a3af3a 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -1539,7 +1539,8 @@ static int __ip6_append_data(struct sock *sk,
 	    headersize == sizeof(struct ipv6hdr) &&
 	    length <= mtu - headersize &&
 	    (!(flags & MSG_MORE) || cork->gso_size) &&
-	    rt->dst.dev->features & (NETIF_F_IPV6_CSUM | NETIF_F_HW_CSUM))
+	    (rt->dst.dev->features & NETIF_F_IPV6_CSUM ||
+	     rt->dst.dev->features & NETIF_F_HW_CSUM))
 		csummode = CHECKSUM_PARTIAL;
 
 	if ((flags & MSG_ZEROCOPY) && length) {
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index 95b58c5cac07..bd0c2073828c 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -2391,13 +2391,15 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name,
 	ieee80211_setup_sdata(sdata, type);
 
 	if (ndev) {
+		netdev_features_t tmp;
+
 		ndev->ieee80211_ptr->use_4addr = params->use_4addr;
 		if (type == NL80211_IFTYPE_STATION)
 			sdata->u.mgd.use_4addr = params->use_4addr;
 
 		ndev->features |= local->hw.netdev_features;
-		ndev->hw_features |= ndev->features &
-					MAC80211_SUPPORTED_FEATURES_TX;
+		tmp = ndev->features & MAC80211_SUPPORTED_FEATURES_TX;
+		ndev->hw_features |= tmp;
 
 		netdev_set_default_ethtool_ops(ndev, &ieee80211_ethtool_ops);
 
diff --git a/net/openvswitch/vport-internal_dev.c b/net/openvswitch/vport-internal_dev.c
index 0459fe97ddd9..522457207275 100644
--- a/net/openvswitch/vport-internal_dev.c
+++ b/net/openvswitch/vport-internal_dev.c
@@ -122,7 +122,8 @@ static void do_setup(struct net_device *netdev)
 	netdev->vlan_features = netdev->features;
 	netdev->hw_enc_features = netdev->features;
 	netdev->features |= netdev_tx_vlan_features;
-	netdev->hw_features = netdev->features & ~NETIF_F_LLTX;
+	netdev->hw_features = netdev->features;
+	netdev->hw_features &= ~NETIF_F_LLTX;
 
 	eth_hw_addr_random(netdev);
 }
diff --git a/net/tls/tls_device.c b/net/tls/tls_device.c
index e3e6cf75aa03..7e57a67ecce3 100644
--- a/net/tls/tls_device.c
+++ b/net/tls/tls_device.c
@@ -1403,7 +1403,7 @@ static int tls_dev_event(struct notifier_block *this, unsigned long event,
 	struct net_device *dev = netdev_notifier_info_to_dev(ptr);
 
 	if (!dev->tlsdev_ops &&
-	    !(dev->features & (NETIF_F_HW_TLS_RX | NETIF_F_HW_TLS_TX)))
+	    !(dev->features & netdev_tls_features))
 		return NOTIFY_DONE;
 
 	switch (event) {
diff --git a/net/xfrm/xfrm_device.c b/net/xfrm/xfrm_device.c
index 96ffd287ae9a..06b94053097e 100644
--- a/net/xfrm/xfrm_device.c
+++ b/net/xfrm/xfrm_device.c
@@ -112,8 +112,11 @@ struct sk_buff *validate_xmit_xfrm(struct sk_buff *skb, netdev_features_t featur
 	if (!xo || (xo->flags & XFRM_XMIT))
 		return skb;
 
-	if (!(features & NETIF_F_HW_ESP))
-		esp_features = features & ~(NETIF_F_SG | NETIF_F_CSUM_MASK);
+	if (!(features & NETIF_F_HW_ESP)) {
+		esp_features = features;
+		esp_features &= ~NETIF_F_SG;
+		esp_features &= ~NETIF_F_CSUM_MASK;
+	}
 
 	sp = skb_sec_path(skb);
 	x = sp->xvec[sp->len - 1];
@@ -379,7 +382,8 @@ static int xfrm_api_check(struct net_device *dev)
 	       dev->xfrmdev_ops->xdo_dev_state_delete)))
 		return NOTIFY_BAD;
 #else
-	if (dev->features & (NETIF_F_HW_ESP | NETIF_F_HW_ESP_TX_CSUM))
+	if (dev->features & NETIF_F_HW_ESP ||
+	    dev->features & NETIF_F_HW_ESP_TX_CSUM)
 		return NOTIFY_BAD;
 #endif
 
-- 
2.33.0


  parent reply	other threads:[~2022-08-10  3:14 UTC|newest]

Thread overview: 59+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-08-10  3:05 [RFCv7 PATCH net-next 00/36] net: extend the type of netdev_features_t to bitmap Jian Shen
2022-08-10  3:05 ` [RFCv7 PATCH net-next 01/36] net: introduce operation helpers for netdev features Jian Shen
2022-08-10  9:43   ` Alexander Lobakin
2022-08-10 11:32     ` shenjian (K)
2022-08-11 10:49       ` Alexander Lobakin
2022-08-12  2:39         ` shenjian (K)
2022-08-10  3:05 ` [RFCv7 PATCH net-next 02/36] net: replace general features macroes with global netdev_features variables Jian Shen
2022-08-10  9:58   ` Alexander Lobakin
2022-08-10 12:01     ` shenjian (K)
2022-08-11 11:05       ` Alexander Lobakin
2022-08-12 10:58         ` shenjian (K)
2022-08-10  3:05 ` [RFCv7 PATCH net-next 03/36] net: replace multiple feature bits with DECLARE_NETDEV_FEATURE_SET Jian Shen
2022-08-10 10:37   ` Alexander Lobakin
2022-08-10 12:15     ` shenjian (K)
2022-08-10  3:05 ` [RFCv7 PATCH net-next 04/36] net: sfc: replace const features initialization " Jian Shen
2022-08-10  3:05 ` [RFCv7 PATCH net-next 05/36] net: atlantic: replace const features initialization with NETDEV_FEATURE_SET Jian Shen
2022-08-10  3:05 ` [RFCv7 PATCH net-next 06/36] iwlwifi: " Jian Shen
2022-08-10  3:05 ` [RFCv7 PATCH net-next 07/36] net: ethernet: mtk_eth_soc: " Jian Shen
2022-08-10  3:05 ` [RFCv7 PATCH net-next 08/36] ravb: " Jian Shen
2022-08-10  3:05 ` [RFCv7 PATCH net-next 09/36] test_bpf: " Jian Shen
2022-08-10  3:05 ` [RFCv7 PATCH net-next 10/36] treewide: replace NETIF_F_CSUM_MASK | NETIF_F_GSO_MASK by netdev_csum_gso_features_mask Jian Shen
2022-08-10  3:05 ` [RFCv7 PATCH net-next 11/36] treewide: replace NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM by netdev_ip_csum_features Jian Shen
2022-08-10  3:06 ` [RFCv7 PATCH net-next 12/36] treewide: replace NETIF_F_TSO | NETIF_F_TSO6 by netdev_general_tso_features Jian Shen
2022-08-10  3:06 ` [RFCv7 PATCH net-next 13/36] treewide: replace VLAN tag feature array by const vlan features Jian Shen
2022-08-10  3:06 ` [RFCv7 PATCH net-next 14/36] net: simplify the netdev features expressions for xxx_gso_segment Jian Shen
2022-08-10  3:06 ` Jian Shen [this message]
2022-08-10  3:06 ` [RFCv7 PATCH net-next 16/36] treewide: use replace features '0' by netdev_empty_features Jian Shen
2022-08-10 10:48   ` Alexander Lobakin
2022-08-10 12:25     ` shenjian (K)
2022-08-11 12:35       ` Alexander Lobakin
2022-08-10  3:06 ` [RFCv7 PATCH net-next 17/36] treewide: adjust features initialization Jian Shen
2022-08-10 10:58   ` Alexander Lobakin
2022-08-10 14:06     ` shenjian (K)
2022-08-10  3:06 ` [RFCv7 PATCH net-next 18/36] net: mlx4: adjust the net device feature relative macroes Jian Shen
2022-08-10  3:06 ` [RFCv7 PATCH net-next 19/36] net: mlx5e: adjust " Jian Shen
2022-08-10  3:06 ` [RFCv7 PATCH net-next 20/36] net: mlxsw: adjust input parameter for function mlxsw_sp_handle_feature Jian Shen
2022-08-10  3:06 ` [RFCv7 PATCH net-next 21/36] net: iavf: adjust net device features relative macroes Jian Shen
2022-08-10  3:06 ` [RFCv7 PATCH net-next 22/36] net: core: adjust netdev_sync_xxx_features Jian Shen
2022-08-10  3:06 ` [RFCv7 PATCH net-next 23/36] net: adjust the build check for net_gso_ok() Jian Shen
2022-08-10 11:09   ` Alexander Lobakin
2022-08-10 14:41     ` shenjian (K)
2022-08-10  3:06 ` [RFCv7 PATCH net-next 24/36] treewide: use netdev_feature_add helpers Jian Shen
2022-08-10  3:06 ` [RFCv7 PATCH net-next 25/36] treewide: use netdev_features_or/set helpers Jian Shen
2022-08-10  3:06 ` [RFCv7 PATCH net-next 26/36] treewide: use netdev_feature_change helpers Jian Shen
2022-08-10  3:06 ` [RFCv7 PATCH net-next 27/36] treewide: use netdev_feature_del helpers Jian Shen
2022-08-10  3:06 ` [RFCv7 PATCH net-next 28/36] treewide: use netdev_features_andnot and netdev_features_clear helpers Jian Shen
2022-08-10  3:06 ` [RFCv7 PATCH net-next 29/36] treewide: use netdev_features_xor helpers Jian Shen
2022-08-10  3:06 ` [RFCv7 PATCH net-next 30/36] treewide: use netdev_feature_test helpers Jian Shen
2022-08-10  3:06 ` [RFCv7 PATCH net-next 31/36] treewide: use netdev_features_intersects helpers Jian Shen
2022-08-10  3:06 ` [RFCv7 PATCH net-next 32/36] net: use netdev_features_and and netdev_features_mask helpers Jian Shen
2022-08-10  3:06 ` [RFCv7 PATCH net-next 33/36] treewide: use netdev_features_subset helpers Jian Shen
2022-08-10  3:06 ` [RFCv7 PATCH net-next 34/36] treewide: use netdev_features_equal helpers Jian Shen
2022-08-10  3:06 ` [RFCv7 PATCH net-next 35/36] treewide: use netdev_features_empty helpers Jian Shen
2022-08-10  3:06 ` [RFCv7 PATCH net-next 36/36] net: redefine the prototype of netdev_features_t Jian Shen
2022-08-10 11:35   ` Alexander Lobakin
     [not found]     ` <3df89822-7dec-c01e-0df9-15b8e6f7d4e5@huawei.com>
2022-08-11 13:07       ` Alexander Lobakin
2022-08-11 15:13         ` Jakub Kicinski
2022-08-12 11:43           ` shenjian (K)
2022-08-12 11:30         ` shenjian (K)

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220810030624.34711-16-shenjian15@huawei.com \
    --to=shenjian15@huawei.com \
    --cc=alexandr.lobakin@intel.com \
    --cc=andrew@lunn.ch \
    --cc=davem@davemloft.net \
    --cc=ecree.xilinx@gmail.com \
    --cc=hkallweit1@gmail.com \
    --cc=kuba@kernel.org \
    --cc=leon@kernel.org \
    --cc=linuxarm@openeuler.org \
    --cc=netdev@vger.kernel.org \
    --cc=saeed@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).