All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFCv6 PATCH net-next 00/19] net: extend the type of netdev_features_t to bitmap
@ 2022-04-19  2:21 Jian Shen
  2022-04-19  2:21 ` [RFCv6 PATCH net-next 01/19] net: introduce operation helpers for netdev features Jian Shen
                   ` (18 more replies)
  0 siblings, 19 replies; 30+ messages in thread
From: Jian Shen @ 2022-04-19  2:21 UTC (permalink / raw)
  To: davem, kuba, andrew, ecree.xilinx, hkallweit1, alexandr.lobakin,
	saeed, leon
  Cc: netdev, linuxarm, lipeng321

For the prototype of netdev_features_t is u64, and the number
of netdevice feature bits is 64 now. So there is no space to
introduce new feature bit.

This patchset try to solve it by change the prototype of
netdev_features_t from u64 to structure below:
	typedef struct {
		DECLARE_BITMAP(bits, NETDEV_FEATURE_COUNT);
	} netdev_features_t;

With this change, it's necessary to introduce a set of bitmap
operation helpers for netdev features. As the nic drivers are
not supposed to modify netdev_features directly, it also
introduces wrappers helpers to this. [patch 1]

To avoid mistake using NETIF_F_XXX as NETIF_F_XXX_BIT as
input macroes for above helpers, remove all the macroes
of NETIF_F_XXX. [patch 19]

The features group macroes in netdev_features.h are replaced
by a set of const features defined in netdev_features.c. [patch 2-3]
For example:
macro NETIF_F_ALL_TSO is replaced by netdev_all_tso_features

There are some drivers(e.g. sfc) use netdev_features in global
structure initialization. Changed the its netdev_features_t memeber
to netdev_features_t *, and make it prefer to a netdev_features_t
global variables. [patch 4]

As suggestion from Andrew Lunn, I wrote some semantic patches to do the
work(replacing the netdev features operator by helpers). [patch 7-18]
To make the semantic patches simple, I split the complex opreation of
netdev_features to simple logical operation. [patch 5, 6]

With the prototype is no longer u64, the implementation of print interface
for netdev features(%pNF) is changed to bitmap. [patch 19]

The whole work is not complete yet. I just use these changes
on several files(hns3 driver, sfc drivers, net/ethtool, net/core/dev.c),
in order to show how these helpers will be used. I will apply these helpers
to the whole tree later, sofar I want to get more suggestions for this
scheme, any comments would be appreciated.

The former discussion please see [1][2][3][4].

[1]:https://www.spinics.net/lists/netdev/msg769952.html
[2]:https://www.spinics.net/lists/netdev/msg777764.html
[3]:https://lore.kernel.org/netdev/20211107101519.29264-1-shenjian15@huawei.com/T/
[4]:https://www.spinics.net/lists/netdev/msg809293.html


ChangeLog:
V5-V6: suggestions from Jakub Kicinski:
drop the rename for netdev->features
simplify names of some helpers, and move them to a new header file
refine the implement for netdev_features_set_array
V4->V5:
adjust the patch structure, use semantic patch with coccinelle
V3->V4:
rename netdev->features to netdev->active_features
remove helpes for handle first 64 bits
remove __NETIF_F(name) macroes
replace features group macroes with const features
V2->V3:
use structure for bitmap, suggest by Edward Cree
V1->V2:
Extend the prototype from u64 to bitmap, suggest by Andrew Lunn

Jian Shen (19):
  net: introduce operation helpers for netdev features
  net: replace general features macroes with global netdev_features
    variables
  net: replace multiple feature bits with netdev features array
  net: sfc: replace const features initialization with netdev features
    array
  net: simplify the netdev features expression
  net: adjust variables definition for netdev_features_t
  net: use netdev_feature_add helpers
  net: use netdev_features_or helpers
  net: use netdev_features_xor helpers
  net: use netdev_feature_del helpers
  net: use netdev_features_andnot helpers
  net: use netdev_feature_test helpers
  net: use netdev_features_intersects helpers
  net: use netdev_features_and helpers
  net: use netdev_features_subset helpers
  net: use netdev_features_equal helpers
  net: use netdev_features_copy helpers
  net: use netdev_xxx_features helpers
  net: redefine the prototype of netdev_features_t

 .../net/ethernet/hisilicon/hns3/hns3_enet.c   | 108 ++-
 .../ethernet/hisilicon/hns3/hns3_ethtool.c    |   4 +-
 .../net/ethernet/netronome/nfp/nfp_net_repr.c |   1 +
 drivers/net/ethernet/sfc/ef10.c               |  38 +-
 drivers/net/ethernet/sfc/ef100_nic.c          |  48 +-
 drivers/net/ethernet/sfc/ef100_rx.c           |   4 +-
 drivers/net/ethernet/sfc/ef100_tx.c           |   8 +-
 drivers/net/ethernet/sfc/ef10_sriov.c         |   6 +-
 drivers/net/ethernet/sfc/efx.c                |  82 ++-
 drivers/net/ethernet/sfc/efx_common.c         |  31 +-
 drivers/net/ethernet/sfc/falcon/efx.c         |  67 +-
 drivers/net/ethernet/sfc/falcon/efx.h         |   3 +
 drivers/net/ethernet/sfc/falcon/falcon.c      |   4 +-
 drivers/net/ethernet/sfc/falcon/net_driver.h  |   5 +-
 drivers/net/ethernet/sfc/falcon/rx.c          |   4 +-
 drivers/net/ethernet/sfc/farch.c              |   2 +-
 drivers/net/ethernet/sfc/mcdi_filters.c       |  13 +-
 drivers/net/ethernet/sfc/mcdi_port_common.c   |   2 +-
 drivers/net/ethernet/sfc/net_driver.h         |   5 +-
 drivers/net/ethernet/sfc/rx.c                 |   2 +-
 drivers/net/ethernet/sfc/rx_common.c          |   4 +-
 drivers/net/ethernet/sfc/rx_common.h          |   4 +
 drivers/net/ethernet/sfc/siena.c              |   3 +-
 drivers/net/wireguard/device.c                |  10 +-
 include/linux/netdev_features.h               | 193 ++----
 include/linux/netdev_features_helper.h        | 653 ++++++++++++++++++
 include/linux/netdevice.h                     | 109 +--
 lib/vsprintf.c                                |  11 +-
 net/8021q/vlan_dev.c                          |   1 +
 net/core/Makefile                             |   2 +-
 net/core/dev.c                                | 389 +++++++----
 net/core/netdev_features.c                    | 241 +++++++
 net/ethtool/features.c                        |  90 +--
 net/ethtool/ioctl.c                           | 135 ++--
 34 files changed, 1723 insertions(+), 559 deletions(-)
 create mode 100644 include/linux/netdev_features_helper.h
 create mode 100644 net/core/netdev_features.c

-- 
2.33.0


^ permalink raw reply	[flat|nested] 30+ messages in thread

* [RFCv6 PATCH net-next 01/19] net: introduce operation helpers for netdev features
  2022-04-19  2:21 [RFCv6 PATCH net-next 00/19] net: extend the type of netdev_features_t to bitmap Jian Shen
@ 2022-04-19  2:21 ` Jian Shen
  2022-04-19 14:40   ` Alexander Lobakin
  2022-04-19  2:21 ` [RFCv6 PATCH net-next 02/19] net: replace general features macroes with global netdev_features variables Jian Shen
                   ` (17 subsequent siblings)
  18 siblings, 1 reply; 30+ messages in thread
From: Jian Shen @ 2022-04-19  2:21 UTC (permalink / raw)
  To: davem, kuba, andrew, ecree.xilinx, hkallweit1, alexandr.lobakin,
	saeed, leon
  Cc: netdev, linuxarm, lipeng321

Introduce a set of bitmap operation helpers for netdev features,
then we can use them to replace the logical operation with them.
As the nic driversare not supposed to modify netdev_features
directly, it also introduces wrappers helpers to this.

The implementation of these helpers are based on the old prototype
of netdev_features_t is still u64. I will rewrite them on the last
patch, when the prototype changes.

To avoid interdependencies between netdev_features_helper.h and
netdevice.h, put the helpers for testing feature is set in the
netdevice.h, and move advandced helpers like
netdev_get_wanted_features() and netdev_intersect_features() to
netdev_features_helper.h.

Signed-off-by: Jian Shen <shenjian15@huawei.com>
---
 .../net/ethernet/netronome/nfp/nfp_net_repr.c |   1 +
 include/linux/netdev_features.h               |  12 +
 include/linux/netdev_features_helper.h        | 604 ++++++++++++++++++
 include/linux/netdevice.h                     |  45 +-
 net/8021q/vlan_dev.c                          |   1 +
 net/core/dev.c                                |   1 +
 6 files changed, 646 insertions(+), 18 deletions(-)
 create mode 100644 include/linux/netdev_features_helper.h

diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_repr.c b/drivers/net/ethernet/netronome/nfp/nfp_net_repr.c
index ba3fa7eac98d..08f2c54e0a11 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_net_repr.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_net_repr.c
@@ -4,6 +4,7 @@
 #include <linux/etherdevice.h>
 #include <linux/io-64-nonatomic-hi-lo.h>
 #include <linux/lockdep.h>
+#include <linux/netdev_features_helper.h>
 #include <net/dst_metadata.h>
 
 #include "nfpcore/nfp_cpp.h"
diff --git a/include/linux/netdev_features.h b/include/linux/netdev_features.h
index 2c6b9e416225..e2b66fa3d7d6 100644
--- a/include/linux/netdev_features.h
+++ b/include/linux/netdev_features.h
@@ -11,6 +11,18 @@
 
 typedef u64 netdev_features_t;
 
+struct netdev_feature_set {
+	unsigned int cnt;
+	unsigned short feature_bits[];
+};
+
+#define DECLARE_NETDEV_FEATURE_SET(name, features...)		\
+	static unsigned short __##name##_s[] = {features};	\
+	struct netdev_feature_set name = {			\
+		.cnt = ARRAY_SIZE(__##name##_s),		\
+		.feature_bits = {features},			\
+	}
+
 enum {
 	NETIF_F_SG_BIT,			/* Scatter/gather IO. */
 	NETIF_F_IP_CSUM_BIT,		/* Can checksum TCP/UDP over IPv4. */
diff --git a/include/linux/netdev_features_helper.h b/include/linux/netdev_features_helper.h
new file mode 100644
index 000000000000..5cc6368f65e5
--- /dev/null
+++ b/include/linux/netdev_features_helper.h
@@ -0,0 +1,604 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Network device features helpers.
+ */
+#ifndef _LINUX_NETDEV_FEATURES_HELPER_H
+#define _LINUX_NETDEV_FEATURES_HELPER_H
+
+#include <linux/netdevice.h>
+
+static inline void netdev_features_zero(netdev_features_t *dst)
+{
+	*dst = 0;
+}
+
+static inline void netdev_features_fill(netdev_features_t *dst)
+{
+	*dst = ~0ULL;
+}
+
+static inline bool netdev_features_empty(const netdev_features_t src)
+{
+	return src == 0;
+}
+
+/* helpers for netdev features '==' operation */
+static inline bool netdev_features_equal(const netdev_features_t src1,
+					 const netdev_features_t src2)
+{
+	return src1 == src2;
+}
+
+/* active_feature prefer to netdev->features */
+#define netdev_active_features_equal(ndev, __features) \
+		netdev_features_equal(ndev->features, __features)
+
+#define netdev_hw_features_equal(ndev, __features) \
+		netdev_features_equal(ndev->hw_features, __features)
+
+#define netdev_wanted_features_equal(ndev, __features) \
+		netdev_features_equal(ndev->wanted_features, __features)
+
+#define netdev_vlan_features_equal(ndev, __features) \
+		netdev_features_equal(ndev->vlan_features, __features)
+
+#define netdev_hw_enc_features_equal(ndev, __features) \
+		netdev_features_equal(ndev->hw_enc_features, __features)
+
+#define netdev_mpls_features_equal(ndev, __features) \
+		netdev_features_equal(ndev->mpls_features, __features)
+
+#define netdev_gso_partial_features_equal(ndev, __features) \
+		netdev_features_equal(ndev->gso_partial_features, __features)
+
+/* helpers for netdev features '&' operation */
+static inline netdev_features_t
+netdev_features_and(const netdev_features_t a, const netdev_features_t b)
+{
+	return a & b;
+}
+
+#define netdev_active_features_and(ndev, __features) \
+		netdev_features_and(ndev->features, __features)
+
+#define netdev_hw_features_and(ndev, __features) \
+		netdev_features_and(ndev->hw_features, __features)
+
+#define netdev_wanted_features_and(ndev, __features) \
+		netdev_features_and(ndev->wanted_features, __features)
+
+#define netdev_vlan_features_and(ndev, __features) \
+		netdev_features_and(ndev->vlan_features, __features)
+
+#define netdev_hw_enc_features_and(ndev, __features) \
+		netdev_features_and(ndev->hw_enc_features, __features)
+
+#define netdev_mpls_features_and(ndev, __features) \
+		netdev_features_and(ndev->mpls_features, __features)
+
+#define netdev_gso_partial_features_and(ndev, __features) \
+		netdev_features_and(ndev->gso_partial_features, __features)
+
+/* helpers for netdev features '&=' operation */
+static inline void
+netdev_features_mask(netdev_features_t *dst,
+			   const netdev_features_t features)
+{
+	*dst = netdev_features_and(*dst, features);
+}
+
+static inline void
+netdev_active_features_mask(struct net_device *ndev,
+			    const netdev_features_t features)
+{
+	ndev->features = netdev_active_features_and(ndev, features);
+}
+
+static inline void
+netdev_hw_features_mask(struct net_device *ndev,
+			const netdev_features_t features)
+{
+	ndev->hw_features = netdev_hw_features_and(ndev, features);
+}
+
+static inline void
+netdev_wanted_features_mask(struct net_device *ndev,
+			    const netdev_features_t features)
+{
+	ndev->wanted_features = netdev_wanted_features_and(ndev, features);
+}
+
+static inline void
+netdev_vlan_features_mask(struct net_device *ndev,
+			  const netdev_features_t features)
+{
+	ndev->vlan_features = netdev_vlan_features_and(ndev, features);
+}
+
+static inline void
+netdev_hw_enc_features_mask(struct net_device *ndev,
+			    const netdev_features_t features)
+{
+	ndev->hw_enc_features = netdev_hw_enc_features_and(ndev, features);
+}
+
+static inline void
+netdev_mpls_features_mask(struct net_device *ndev,
+			  const netdev_features_t features)
+{
+	ndev->mpls_features = netdev_mpls_features_and(ndev, features);
+}
+
+static inline void
+netdev_gso_partial_features_mask(struct net_device *ndev,
+				 const netdev_features_t features)
+{
+	ndev->gso_partial_features = netdev_mpls_features_and(ndev, features);
+}
+
+/* helpers for netdev features '|' operation */
+static inline netdev_features_t
+netdev_features_or(const netdev_features_t a, const netdev_features_t b)
+{
+	return a | b;
+}
+
+#define netdev_active_features_or(ndev, __features) \
+		netdev_features_or(ndev->features, __features)
+
+#define netdev_hw_features_or(ndev, __features) \
+		netdev_features_or(ndev->hw_features, __features)
+
+#define netdev_wanted_features_or(ndev, __features) \
+		netdev_features_or(ndev->wanted_features, __features)
+
+#define netdev_vlan_features_or(ndev, __features) \
+		netdev_features_or(ndev->vlan_features, __features)
+
+#define netdev_hw_enc_features_or(ndev, __features) \
+		netdev_features_or(ndev->hw_enc_features, __features)
+
+#define netdev_mpls_features_or(ndev, __features) \
+		netdev_features_or(ndev->mpls_features, __features)
+
+#define netdev_gso_partial_features_or(ndev, __features) \
+		netdev_features_or(ndev->gso_partial_features, __features)
+
+/* helpers for netdev features '|=' operation */
+static inline void
+netdev_features_set(netdev_features_t *dst, const netdev_features_t features)
+{
+	*dst = netdev_features_or(*dst, features);
+}
+
+static inline void
+netdev_active_features_set(struct net_device *ndev,
+			   const netdev_features_t features)
+{
+	ndev->features = netdev_active_features_or(ndev, features);
+}
+
+static inline void
+netdev_hw_features_set(struct net_device *ndev,
+		       const netdev_features_t features)
+{
+	ndev->hw_features = netdev_hw_features_or(ndev, features);
+}
+
+static inline void
+netdev_wanted_features_set(struct net_device *ndev,
+			   const netdev_features_t features)
+{
+	ndev->wanted_features = netdev_wanted_features_or(ndev, features);
+}
+
+static inline void
+netdev_vlan_features_set(struct net_device *ndev,
+			 const netdev_features_t features)
+{
+	ndev->vlan_features = netdev_vlan_features_or(ndev, features);
+}
+
+static inline void
+netdev_hw_enc_features_set(struct net_device *ndev,
+			   const netdev_features_t features)
+{
+	ndev->hw_enc_features = netdev_hw_enc_features_or(ndev, features);
+}
+
+static inline void
+netdev_mpls_features_set(struct net_device *ndev,
+			 const netdev_features_t features)
+{
+	ndev->mpls_features = netdev_mpls_features_or(ndev, features);
+}
+
+static inline void
+netdev_gso_partial_features_set(struct net_device *ndev,
+				const netdev_features_t features)
+{
+	ndev->gso_partial_features = netdev_mpls_features_or(ndev, features);
+}
+
+/* helpers for netdev features '^' operation */
+static inline netdev_features_t
+netdev_features_xor(const netdev_features_t a, const netdev_features_t b)
+{
+	return a ^ b;
+}
+
+#define netdev_active_features_xor(ndev, __features) \
+		netdev_features_xor(ndev->features, __features)
+
+#define netdev_hw_features_xor(ndev, __features) \
+		netdev_features_xor(ndev->hw_features, __features)
+
+#define netdev_wanted_features_xor(ndev, __features) \
+		netdev_features_xor(ndev->wanted_features, __features)
+
+#define netdev_vlan_features_xor(ndev, __features) \
+		netdev_features_xor(ndev->vlan_features, __features)
+
+#define netdev_hw_enc_features_xor(ndev, __features) \
+		netdev_features_xor(ndev->hw_enc_features, __features)
+
+#define netdev_mpls_features_xor(ndev, __features) \
+		netdev_features_xor(ndev->mpls_features, __features)
+
+#define netdev_gso_partial_features_xor(ndev, __features) \
+		netdev_features_xor(ndev->gso_partial_features, __features)
+
+/* helpers for netdev features '^=' operation */
+static inline void
+netdev_features_toggle(netdev_features_t *dst, const netdev_features_t features)
+{
+	*dst = netdev_features_xor(*dst, features);
+}
+
+static inline void
+netdev_active_features_toggle(struct net_device *ndev,
+			      const netdev_features_t features)
+{
+	ndev->features = netdev_active_features_xor(ndev, features);
+}
+
+static inline void
+netdev_hw_features_toggle(struct net_device *ndev,
+			      const netdev_features_t features)
+{
+	ndev->hw_features = netdev_hw_features_xor(ndev, features);
+}
+
+static inline void
+netdev_wanted_features_toggle(struct net_device *ndev,
+				  const netdev_features_t features)
+{
+	ndev->wanted_features = netdev_wanted_features_xor(ndev, features);
+}
+
+static inline void
+netdev_vlan_features_toggle(struct net_device *ndev,
+				const netdev_features_t features)
+{
+	ndev->vlan_features = netdev_vlan_features_xor(ndev, features);
+}
+
+static inline void
+netdev_hw_enc_features_toggle(struct net_device *ndev,
+			      const netdev_features_t features)
+{
+	ndev->hw_enc_features = netdev_hw_enc_features_xor(ndev, features);
+}
+
+static inline void
+netdev_mpls_features_toggle(struct net_device *ndev,
+			    const netdev_features_t features)
+{
+	ndev->mpls_features = netdev_mpls_features_xor(ndev, features);
+}
+
+static inline void
+netdev_gso_partial_features_toggle(struct net_device *ndev,
+				   const netdev_features_t features)
+{
+	ndev->gso_partial_features =
+			netdev_gso_partial_features_xor(ndev, features);
+}
+
+/* helpers for netdev features '& ~' operation */
+static inline netdev_features_t
+netdev_features_andnot(const netdev_features_t a, const netdev_features_t b)
+{
+	return a & ~b;
+}
+
+#define netdev_active_features_andnot(ndev, __features) \
+		netdev_features_andnot(ndev->features, __features)
+
+#define netdev_hw_features_andnot(ndev, __features) \
+		netdev_features_andnot(ndev->hw_features, __features)
+
+#define netdev_wanted_features_andnot(ndev, __features) \
+		netdev_features_andnot(ndev->wanted_features, __features)
+
+#define netdev_vlan_features_andnot(ndev, __features) \
+		netdev_features_andnot(ndev->vlan_features, __features)
+
+#define netdev_hw_enc_features_andnot(ndev, __features) \
+		netdev_features_andnot(ndev->hw_enc_features, __features)
+
+#define netdev_mpls_features_andnot(ndev, __features) \
+		netdev_features_andnot(ndev->mpls_features, __features)
+
+#define netdev_gso_partial_features_andnot(ndev, __features) \
+		netdev_features_andnot(ndev->gso_partial_features, __features)
+
+#define netdev_active_features_andnot_r(ndev, __features) \
+		netdev_features_andnot(__features, ndev->features)
+
+#define netdev_hw_features_andnot_r(ndev, __features) \
+		netdev_features_andnot(__features, ndev->hw_features)
+
+#define netdev_wanted_features_andnot_r(ndev, __features) \
+		netdev_features_andnot(__features, ndev->wanted_features)
+
+#define netdev_vlan_features_andnot_r(ndev, __features) \
+		netdev_features_andnot(__features, ndev->vlan_features)
+
+#define netdev_hw_enc_features_andnot_r(ndev, __features) \
+		netdev_features_andnot(__features, ndev->hw_enc_features)
+
+#define netdev_mpls_features_andnot_r(ndev, __features) \
+		netdev_features_andnot(__features, ndev->mpls_features)
+
+#define netdev_gso_partial_features_andnot_r(ndev, __features) \
+		netdev_features_andnot(__features, ndev->gso_partial_features)
+
+static inline void
+netdev_features_clear(netdev_features_t *dst, const netdev_features_t features)
+{
+	*dst = netdev_features_andnot(*dst, features);
+}
+
+static inline void
+netdev_active_features_clear(struct net_device *ndev,
+			     const netdev_features_t features)
+{
+	ndev->features = netdev_active_features_andnot(ndev, features);
+}
+
+static inline void
+netdev_hw_features_clear(struct net_device *ndev,
+			 const netdev_features_t features)
+{
+	ndev->hw_features = netdev_hw_features_andnot(ndev, features);
+}
+
+static inline void
+netdev_wanted_features_clear(struct net_device *ndev,
+			     const netdev_features_t features)
+{
+	ndev->wanted_features = netdev_wanted_features_andnot(ndev, features);
+}
+
+static inline void
+netdev_vlan_features_clear(struct net_device *ndev,
+			   const netdev_features_t features)
+{
+	ndev->vlan_features = netdev_vlan_features_andnot(ndev, features);
+}
+
+static inline void
+netdev_hw_enc_features_clear(struct net_device *ndev,
+			     const netdev_features_t features)
+{
+	ndev->hw_enc_features = netdev_hw_enc_features_andnot(ndev, features);
+}
+
+static inline void
+netdev_mpls_features_clear(struct net_device *ndev,
+			   const netdev_features_t features)
+{
+	ndev->mpls_features = netdev_mpls_features_andnot(ndev, features);
+}
+
+static inline void
+netdev_gso_partial_features_clear(struct net_device *ndev,
+				  const netdev_features_t features)
+{
+	ndev->gso_partial_features =
+		netdev_gso_partial_features_andnot(ndev, features);
+}
+
+/* helpers for netdev features 'set bit' operation */
+static inline void netdev_feature_add(int nr, netdev_features_t *src)
+{
+	*src |= __NETIF_F_BIT(nr);
+}
+
+#define netdev_active_feature_add(ndev, nr) \
+		netdev_feature_add(nr, &ndev->features)
+
+#define netdev_hw_feature_add(ndev, nr) \
+		netdev_feature_add(nr, &ndev->hw_features)
+
+#define netdev_wanted_feature_add(ndev, nr) \
+		netdev_feature_add(nr, &ndev->wanted_features)
+
+#define netdev_vlan_feature_add(ndev, nr) \
+		netdev_feature_add(nr, &ndev->vlan_features)
+
+#define netdev_hw_enc_feature_add(ndev, nr) \
+		netdev_feature_add(nr, &ndev->hw_enc_features)
+
+#define netdev_mpls_feature_add(ndev, nr) \
+		netdev_feature_add(nr, &ndev->mpls_features)
+
+#define netdev_gso_partial_feature_add(ndev, nr) \
+		netdev_feature_add(nr, &ndev->gso_partial_features)
+
+/* helpers for netdev features 'set bit array' operation */
+static inline void
+netdev_features_set_array(const struct netdev_feature_set *set,
+			  netdev_features_t *dst)
+{
+	int i;
+
+	for (i = 0; i < set->cnt; i++)
+		netdev_feature_add(set->feature_bits[i], dst);
+}
+
+#define netdev_active_features_set_array(ndev, set) \
+		netdev_features_set_array(set, &ndev->features)
+
+#define netdev_hw_features_set_array(ndev, set) \
+		netdev_features_set_array(set, &ndev->hw_features)
+
+#define netdev_wanted_features_set_array(ndev, set) \
+		netdev_features_set_array(set, &ndev->wanted_features)
+
+#define netdev_vlan_features_set_array(ndev, set) \
+		netdev_features_set_array(set, &ndev->vlan_features)
+
+#define netdev_hw_enc_features_set_array(ndev, set) \
+		netdev_features_set_array(set, &ndev->hw_enc_features)
+
+#define netdev_mpls_features_set_array(ndev, set) \
+		netdev_features_set_array(set, &ndev->mpls_features)
+
+#define netdev_gso_partial_features_set_array(ndev, set) \
+		netdev_features_set_array(set, &ndev->gso_partial_features)
+
+/* helpers for netdev features 'clear bit' operation */
+static inline void netdev_feature_del(int nr, netdev_features_t *src)
+{
+	*src &= ~__NETIF_F_BIT(nr);
+}
+
+#define netdev_active_feature_del(ndev, nr) \
+		netdev_feature_del(nr, &ndev->features)
+
+#define netdev_hw_feature_del(ndev, nr) \
+		netdev_feature_del(nr, &ndev->hw_features)
+
+#define netdev_wanted_feature_del(ndev, nr) \
+		netdev_feature_del(nr, &ndev->wanted_features)
+
+#define netdev_vlan_feature_del(ndev, nr) \
+		netdev_feature_del(nr, &ndev->vlan_features)
+
+#define netdev_hw_enc_feature_del(ndev, nr) \
+		netdev_feature_del(nr, &ndev->hw_enc_features)
+
+#define netdev_mpls_feature_del(ndev, nr) \
+		netdev_feature_del(nr, &ndev->mpls_features)
+
+#define netdev_gso_partial_feature_del(ndev, nr) \
+		netdev_feature_del(nr, &ndev->gso_partial_features)
+
+static inline bool netdev_features_intersects(const netdev_features_t src1,
+					      const netdev_features_t src2)
+{
+	return (src1 & src2) > 0;
+}
+
+#define netdev_active_features_intersects(ndev, __features) \
+		netdev_features_intersects(ndev->features, __features)
+
+#define netdev_hw_features_intersects(ndev, __features) \
+		netdev_features_intersects(ndev->hw_features, __features)
+
+#define netdev_wanted_features_intersects(ndev, __features) \
+		netdev_features_intersects(ndev->wanted_features, __features)
+
+#define netdev_vlan_features_intersects(ndev, __features) \
+		netdev_features_intersects(ndev->vlan_features, __features)
+
+#define netdev_hw_enc_features_intersects(ndev, __features) \
+		netdev_features_intersects(ndev->hw_enc_features, __features)
+
+#define netdev_mpls_features_intersects(ndev, __features) \
+		netdev_features_intersects(ndev->mpls_features, __features)
+
+#define netdev_gso_partial_features_intersects(ndev, __features) \
+		netdev_features_intersects(ndev->gso_partial_features, __features)
+
+/* helpers for netdev features '=' operation */
+static inline void netdev_active_features_copy(struct net_device *netdev,
+					       const netdev_features_t src)
+{
+	netdev->features = src;
+}
+
+static inline void netdev_hw_features_copy(struct net_device *ndev,
+					   const netdev_features_t src)
+{
+	ndev->hw_features = src;
+}
+
+static inline void netdev_wanted_features_copy(struct net_device *ndev,
+					       const netdev_features_t src)
+{
+	ndev->wanted_features = src;
+}
+
+static inline void netdev_vlan_features_copy(struct net_device *ndev,
+					     const netdev_features_t src)
+{
+	ndev->vlan_features = src;
+}
+
+static inline void netdev_hw_enc_features_copy(struct net_device *ndev,
+					       const netdev_features_t src)
+{
+	ndev->hw_enc_features = src;
+}
+
+static inline void netdev_mpls_features_copy(struct net_device *ndev,
+					     const netdev_features_t src)
+{
+	ndev->mpls_features = src;
+}
+
+static inline void netdev_gso_partial_features_copy(struct net_device *ndev,
+						    const netdev_features_t src)
+{
+	ndev->gso_partial_features = src;
+}
+
+/* helpers for netdev features 'get' operation */
+#define netdev_active_features(ndev)	((ndev)->features)
+#define netdev_hw_features(ndev)	((ndev)->hw_features)
+#define netdev_wanted_features(ndev)	((ndev)->wanted_features)
+#define netdev_vlan_features(ndev)	((ndev)->vlan_features)
+#define netdev_hw_enc_features(ndev)	((ndev)->hw_enc_features)
+#define netdev_mpls_features(ndev)	((ndev)->mpls_features)
+#define netdev_gso_partial_features(ndev)	((ndev)->gso_partial_features)
+
+/* helpers for netdev features 'subset' */
+static inline bool netdev_features_subset(const netdev_features_t src1,
+					  const netdev_features_t src2)
+{
+	return (src1 & src2) == src2;
+}
+
+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)
+			f1 |= (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM);
+		else
+			f2 |= (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM);
+	}
+
+	return f1 & f2;
+}
+
+static inline netdev_features_t
+netdev_get_wanted_features(struct net_device *dev)
+{
+	return (dev->features & ~dev->hw_features) | dev->wanted_features;
+}
+
+#endif
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 7b2a0b739684..a092423653e2 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -2304,6 +2304,33 @@ struct net_device {
 };
 #define to_net_dev(d) container_of(d, struct net_device, dev)
 
+/* helpers for netdev features 'test bit' operation */
+static inline bool netdev_feature_test(int nr, const netdev_features_t src)
+{
+	return (src & __NETIF_F_BIT(nr)) > 0;
+}
+
+#define netdev_active_feature_test(ndev, nr) \
+		netdev_feature_test(nr, ndev->features)
+
+#define netdev_hw_feature_test(ndev, nr) \
+		netdev_feature_test(nr, ndev->hw_features)
+
+#define netdev_wanted_feature_test(ndev, nr) \
+		netdev_feature_test(nr, ndev->wanted_features)
+
+#define netdev_vlan_feature_test(ndev, nr) \
+		netdev_feature_test(nr, ndev->vlan_features)
+
+#define netdev_hw_enc_feature_test(ndev, nr) \
+		netdev_feature_test(nr, ndev->hw_enc_features)
+
+#define netdev_mpls_feature_test(ndev, nr) \
+		netdev_feature_test(nr, ndev->mpls_features)
+
+#define netdev_gso_partial_feature_test(ndev, nr) \
+		netdev_feature_test(nr, ndev->gso_partial_features)
+
 static inline bool netif_elide_gro(const struct net_device *dev)
 {
 	if (!(dev->features & NETIF_F_GRO) || dev->xdp_prog)
@@ -4815,24 +4842,6 @@ const char *netdev_drivername(const struct net_device *dev);
 
 void linkwatch_run_queue(void);
 
-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)
-			f1 |= (NETIF_F_IP_CSUM|NETIF_F_IPV6_CSUM);
-		else
-			f2 |= (NETIF_F_IP_CSUM|NETIF_F_IPV6_CSUM);
-	}
-
-	return f1 & f2;
-}
-
-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 netdev_increment_features(netdev_features_t all,
 	netdev_features_t one, netdev_features_t mask);
 
diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c
index e5d23e75572a..2c9b353f13e8 100644
--- a/net/8021q/vlan_dev.c
+++ b/net/8021q/vlan_dev.c
@@ -24,6 +24,7 @@
 #include <linux/net_tstamp.h>
 #include <linux/etherdevice.h>
 #include <linux/ethtool.h>
+#include <linux/netdev_features_helper.h>
 #include <linux/phy.h>
 #include <net/arp.h>
 
diff --git a/net/core/dev.c b/net/core/dev.c
index d5a362d53b34..4d6b57752eee 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -88,6 +88,7 @@
 #include <linux/interrupt.h>
 #include <linux/if_ether.h>
 #include <linux/netdevice.h>
+#include <linux/netdev_features_helper.h>
 #include <linux/etherdevice.h>
 #include <linux/ethtool.h>
 #include <linux/skbuff.h>
-- 
2.33.0


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [RFCv6 PATCH net-next 02/19] net: replace general features macroes with global netdev_features variables
  2022-04-19  2:21 [RFCv6 PATCH net-next 00/19] net: extend the type of netdev_features_t to bitmap Jian Shen
  2022-04-19  2:21 ` [RFCv6 PATCH net-next 01/19] net: introduce operation helpers for netdev features Jian Shen
@ 2022-04-19  2:21 ` Jian Shen
  2022-04-19 14:49   ` Alexander Lobakin
  2022-04-19  2:21 ` [RFCv6 PATCH net-next 03/19] net: replace multiple feature bits with netdev features array Jian Shen
                   ` (16 subsequent siblings)
  18 siblings, 1 reply; 30+ messages in thread
From: Jian Shen @ 2022-04-19  2:21 UTC (permalink / raw)
  To: davem, kuba, andrew, ecree.xilinx, hkallweit1, alexandr.lobakin,
	saeed, leon
  Cc: netdev, linuxarm, lipeng321

There are many netdev_features bits group used in kernel. The definition
will be illegal when using feature bit more than 64. Replace these macroes
with global netdev_features variables, initialize them when netdev module
init.

Signed-off-by: Jian Shen <shenjian15@huawei.com>
---
 drivers/net/wireguard/device.c  |  10 +-
 include/linux/netdev_features.h | 102 +++++++++-----
 net/core/Makefile               |   2 +-
 net/core/dev.c                  |  87 ++++++++++++
 net/core/netdev_features.c      | 241 ++++++++++++++++++++++++++++++++
 5 files changed, 400 insertions(+), 42 deletions(-)
 create mode 100644 net/core/netdev_features.c

diff --git a/drivers/net/wireguard/device.c b/drivers/net/wireguard/device.c
index 0fad1331303c..bca987ed02c9 100644
--- a/drivers/net/wireguard/device.c
+++ b/drivers/net/wireguard/device.c
@@ -273,9 +273,9 @@ static const struct device_type device_type = { .name = KBUILD_MODNAME };
 static void wg_setup(struct net_device *dev)
 {
 	struct wg_device *wg = netdev_priv(dev);
-	enum { WG_NETDEV_FEATURES = NETIF_F_HW_CSUM | NETIF_F_RXCSUM |
+	netdev_features_t wg_netdev_features = NETIF_F_HW_CSUM | NETIF_F_RXCSUM |
 				    NETIF_F_SG | NETIF_F_GSO |
-				    NETIF_F_GSO_SOFTWARE | NETIF_F_HIGHDMA };
+				    NETIF_F_GSO_SOFTWARE | NETIF_F_HIGHDMA;
 	const int overhead = MESSAGE_MINIMUM_LENGTH + sizeof(struct udphdr) +
 			     max(sizeof(struct ipv6hdr), sizeof(struct iphdr));
 
@@ -289,9 +289,9 @@ static void wg_setup(struct net_device *dev)
 	dev->flags = IFF_POINTOPOINT | IFF_NOARP;
 	dev->priv_flags |= IFF_NO_QUEUE;
 	dev->features |= NETIF_F_LLTX;
-	dev->features |= WG_NETDEV_FEATURES;
-	dev->hw_features |= WG_NETDEV_FEATURES;
-	dev->hw_enc_features |= WG_NETDEV_FEATURES;
+	dev->features |= wg_netdev_features;
+	dev->hw_features |= wg_netdev_features;
+	dev->hw_enc_features |= wg_netdev_features;
 	dev->mtu = ETH_DATA_LEN - overhead;
 	dev->max_mtu = round_down(INT_MAX, MESSAGE_PADDING_MULTIPLE) - overhead;
 
diff --git a/include/linux/netdev_features.h b/include/linux/netdev_features.h
index e2b66fa3d7d6..16b2313e1dec 100644
--- a/include/linux/netdev_features.h
+++ b/include/linux/netdev_features.h
@@ -7,6 +7,7 @@
 
 #include <linux/types.h>
 #include <linux/bitops.h>
+#include <linux/cache.h>
 #include <asm/byteorder.h>
 
 typedef u64 netdev_features_t;
@@ -113,6 +114,55 @@ enum {
 	/**/NETDEV_FEATURE_COUNT
 };
 
+extern netdev_features_t netdev_ethtool_features __ro_after_init;
+extern netdev_features_t netdev_never_change_features __ro_after_init;
+extern netdev_features_t netdev_gso_features_mask __ro_after_init;
+extern netdev_features_t netdev_ip_csum_features __ro_after_init;
+extern netdev_features_t netdev_csum_features_mask __ro_after_init;
+extern netdev_features_t netdev_general_tso_features __ro_after_init;
+extern netdev_features_t netdev_all_tso_features __ro_after_init;
+extern netdev_features_t netdev_tso_ecn_features __ro_after_init;
+extern netdev_features_t netdev_all_fcoe_features __ro_after_init;
+extern netdev_features_t netdev_gso_software_features __ro_after_init;
+extern netdev_features_t netdev_one_for_all_features __ro_after_init;
+extern netdev_features_t netdev_all_for_all_features __ro_after_init;
+extern netdev_features_t netdev_upper_disable_features __ro_after_init;
+extern netdev_features_t netdev_soft_features __ro_after_init;
+extern netdev_features_t netdev_soft_off_features __ro_after_init;
+extern netdev_features_t netdev_all_vlan_features __ro_after_init;
+extern netdev_features_t netdev_rx_vlan_features __ro_after_init;
+extern netdev_features_t netdev_tx_vlan_features __ro_after_init;
+extern netdev_features_t netdev_ctag_vlan_features __ro_after_init;
+extern netdev_features_t netdev_stag_vlan_features __ro_after_init;
+extern netdev_features_t netdev_vlan_filter_features __ro_after_init;
+extern netdev_features_t netdev_gso_encap_all_features __ro_after_init;
+extern netdev_features_t netdev_xfrm_features __ro_after_init;
+extern netdev_features_t netdev_tls_features __ro_after_init;
+extern netdev_features_t netdev_csum_gso_features_mask __ro_after_init;
+extern struct netdev_feature_set netif_f_never_change_feature_set;
+extern struct netdev_feature_set netif_f_gso_feature_set_mask;
+extern struct netdev_feature_set netif_f_ip_csum_feature_set;
+extern struct netdev_feature_set netif_f_csum_feature_set_mask;
+extern struct netdev_feature_set netif_f_general_tso_feature_set;
+extern struct netdev_feature_set netif_f_all_tso_feature_set;
+extern struct netdev_feature_set netif_f_tso_ecn_feature_set;
+extern struct netdev_feature_set netif_f_all_fcoe_feature_set;
+extern struct netdev_feature_set netif_f_gso_soft_feature_set;
+extern struct netdev_feature_set netif_f_one_for_all_feature_set;
+extern struct netdev_feature_set netif_f_all_for_all_feature_set;
+extern struct netdev_feature_set netif_f_upper_disables_feature_set;
+extern struct netdev_feature_set netif_f_soft_feature_set;
+extern struct netdev_feature_set netif_f_soft_off_feature_set;
+extern struct netdev_feature_set netif_f_vlan_feature_set;
+extern struct netdev_feature_set netif_f_tx_vlan_feature_set;
+extern struct netdev_feature_set netif_f_rx_vlan_feature_set;
+extern struct netdev_feature_set netif_f_vlan_filter_feature_set;
+extern struct netdev_feature_set netif_f_ctag_vlan_feature_set;
+extern struct netdev_feature_set netif_f_stag_vlan_feature_set;
+extern struct netdev_feature_set netif_f_gso_encap_feature_set;
+extern struct netdev_feature_set netif_f_xfrm_feature_set;
+extern struct netdev_feature_set netif_f_tls_feature_set;
+
 /* copy'n'paste compression ;) */
 #define __NETIF_F_BIT(bit)	((netdev_features_t)1 << (bit))
 #define __NETIF_F(name)		__NETIF_F_BIT(NETIF_F_##name##_BIT)
@@ -204,73 +254,53 @@ static inline int find_next_netdev_feature(u64 feature, unsigned long start)
 
 /* Features valid for ethtool to change */
 /* = all defined minus driver/device-class-related */
-#define NETIF_F_NEVER_CHANGE	(NETIF_F_VLAN_CHALLENGED | \
-				 NETIF_F_LLTX | NETIF_F_NETNS_LOCAL)
+#define NETIF_F_NEVER_CHANGE	netdev_never_change_features
 
 /* remember that ((t)1 << t_BITS) is undefined in C99 */
-#define NETIF_F_ETHTOOL_BITS	((__NETIF_F_BIT(NETDEV_FEATURE_COUNT - 1) | \
-		(__NETIF_F_BIT(NETDEV_FEATURE_COUNT - 1) - 1)) & \
-		~NETIF_F_NEVER_CHANGE)
+#define NETIF_F_ETHTOOL_BITS	netdev_ethtool_features
 
 /* Segmentation offload feature mask */
-#define NETIF_F_GSO_MASK	(__NETIF_F_BIT(NETIF_F_GSO_LAST + 1) - \
-		__NETIF_F_BIT(NETIF_F_GSO_SHIFT))
+#define NETIF_F_GSO_MASK	netdev_gso_features_mask
 
 /* List of IP checksum features. Note that NETIF_F_HW_CSUM should not be
  * set in features when NETIF_F_IP_CSUM or NETIF_F_IPV6_CSUM are set--
  * this would be contradictory
  */
-#define NETIF_F_CSUM_MASK	(NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | \
-				 NETIF_F_HW_CSUM)
+#define NETIF_F_CSUM_MASK	netdev_csum_features_mask
 
-#define NETIF_F_ALL_TSO 	(NETIF_F_TSO | NETIF_F_TSO6 | \
-				 NETIF_F_TSO_ECN | NETIF_F_TSO_MANGLEID)
+#define NETIF_F_ALL_TSO		netdev_all_tso_features
 
-#define NETIF_F_ALL_FCOE	(NETIF_F_FCOE_CRC | NETIF_F_FCOE_MTU | \
-				 NETIF_F_FSO)
+#define NETIF_F_ALL_FCOE	netdev_all_fcoe_features
 
 /* List of features with software fallbacks. */
-#define NETIF_F_GSO_SOFTWARE	(NETIF_F_ALL_TSO | NETIF_F_GSO_SCTP |	     \
-				 NETIF_F_GSO_UDP_L4 | NETIF_F_GSO_FRAGLIST)
+#define NETIF_F_GSO_SOFTWARE	netdev_gso_software_features
 
 /*
  * If one device supports one of these features, then enable them
  * for all in netdev_increment_features.
  */
-#define NETIF_F_ONE_FOR_ALL	(NETIF_F_GSO_SOFTWARE | NETIF_F_GSO_ROBUST | \
-				 NETIF_F_SG | NETIF_F_HIGHDMA |		\
-				 NETIF_F_FRAGLIST | NETIF_F_VLAN_CHALLENGED)
+#define NETIF_F_ONE_FOR_ALL	netdev_one_for_all_features
 
 /*
  * If one device doesn't support one of these features, then disable it
  * for all in netdev_increment_features.
  */
-#define NETIF_F_ALL_FOR_ALL	(NETIF_F_NOCACHE_COPY | NETIF_F_FSO)
+#define NETIF_F_ALL_FOR_ALL	netdev_all_for_all_features
 
 /*
  * If upper/master device has these features disabled, they must be disabled
  * on all lower/slave devices as well.
  */
-#define NETIF_F_UPPER_DISABLES	NETIF_F_LRO
+#define NETIF_F_UPPER_DISABLES	netdev_upper_disable_features
 
 /* changeable features with no special hardware requirements */
-#define NETIF_F_SOFT_FEATURES	(NETIF_F_GSO | NETIF_F_GRO)
+#define NETIF_F_SOFT_FEATURES	netdev_soft_features
 
 /* Changeable features with no special hardware requirements that defaults to off. */
-#define NETIF_F_SOFT_FEATURES_OFF	(NETIF_F_GRO_FRAGLIST | NETIF_F_GRO_UDP_FWD)
-
-#define NETIF_F_VLAN_FEATURES	(NETIF_F_HW_VLAN_CTAG_FILTER | \
-				 NETIF_F_HW_VLAN_CTAG_RX | \
-				 NETIF_F_HW_VLAN_CTAG_TX | \
-				 NETIF_F_HW_VLAN_STAG_FILTER | \
-				 NETIF_F_HW_VLAN_STAG_RX | \
-				 NETIF_F_HW_VLAN_STAG_TX)
-
-#define NETIF_F_GSO_ENCAP_ALL	(NETIF_F_GSO_GRE |			\
-				 NETIF_F_GSO_GRE_CSUM |			\
-				 NETIF_F_GSO_IPXIP4 |			\
-				 NETIF_F_GSO_IPXIP6 |			\
-				 NETIF_F_GSO_UDP_TUNNEL |		\
-				 NETIF_F_GSO_UDP_TUNNEL_CSUM)
+#define NETIF_F_SOFT_FEATURES_OFF	netdev_soft_off_features
+
+#define NETIF_F_VLAN_FEATURES	netdev_all_vlan_features
+
+#define NETIF_F_GSO_ENCAP_ALL	netdev_gso_encap_all_features
 
 #endif	/* _LINUX_NETDEV_FEATURES_H */
diff --git a/net/core/Makefile b/net/core/Makefile
index a8e4f737692b..9d2127d25d72 100644
--- a/net/core/Makefile
+++ b/net/core/Makefile
@@ -11,7 +11,7 @@ obj-$(CONFIG_SYSCTL) += sysctl_net_core.o
 obj-y		     += dev.o dev_addr_lists.o dst.o netevent.o \
 			neighbour.o rtnetlink.o utils.o link_watch.o filter.o \
 			sock_diag.o dev_ioctl.o tso.o sock_reuseport.o \
-			fib_notifier.o xdp.o flow_offload.o gro.o
+			fib_notifier.o xdp.o flow_offload.o gro.o netdev_features.o
 
 obj-$(CONFIG_NETDEV_ADDR_LIST_TEST) += dev_addr_lists_test.o
 
diff --git a/net/core/dev.c b/net/core/dev.c
index 4d6b57752eee..85bb418e8ef1 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -146,6 +146,7 @@
 #include <linux/sctp.h>
 #include <net/udp_tunnel.h>
 #include <linux/net_namespace.h>
+#include <linux/netdev_features_helper.h>
 #include <linux/indirect_call_wrapper.h>
 #include <net/devlink.h>
 #include <linux/pm_runtime.h>
@@ -11255,6 +11256,90 @@ static struct pernet_operations __net_initdata default_device_ops = {
 	.exit_batch = default_device_exit_batch,
 };
 
+static void netdev_features_init(void)
+{
+	netdev_features_t features;
+
+	netdev_features_set_array(&netif_f_never_change_feature_set,
+				  &netdev_never_change_features);
+
+	netdev_features_set_array(&netif_f_gso_feature_set_mask,
+				  &netdev_gso_features_mask);
+
+	netdev_features_set_array(&netif_f_ip_csum_feature_set,
+				  &netdev_ip_csum_features);
+
+	netdev_features_set_array(&netif_f_csum_feature_set_mask,
+				  &netdev_csum_features_mask);
+
+	netdev_features_set_array(&netif_f_general_tso_feature_set,
+				  &netdev_general_tso_features);
+
+	netdev_features_set_array(&netif_f_all_tso_feature_set,
+				  &netdev_all_tso_features);
+
+	netdev_features_set_array(&netif_f_tso_ecn_feature_set,
+				  &netdev_tso_ecn_features);
+
+	netdev_features_set_array(&netif_f_all_fcoe_feature_set,
+				  &netdev_all_fcoe_features);
+
+	netdev_features_set_array(&netif_f_gso_soft_feature_set,
+				  &netdev_gso_software_features);
+
+	netdev_features_set_array(&netif_f_one_for_all_feature_set,
+				  &netdev_one_for_all_features);
+
+	netdev_features_set_array(&netif_f_all_for_all_feature_set,
+				  &netdev_all_for_all_features);
+
+	netdev_features_set_array(&netif_f_upper_disables_feature_set,
+				  &netdev_upper_disable_features);
+
+	netdev_features_set_array(&netif_f_soft_feature_set,
+				  &netdev_soft_features);
+
+	netdev_features_set_array(&netif_f_soft_off_feature_set,
+				  &netdev_soft_off_features);
+
+	netdev_features_set_array(&netif_f_rx_vlan_feature_set,
+				  &netdev_rx_vlan_features);
+
+	netdev_features_set_array(&netif_f_tx_vlan_feature_set,
+				  &netdev_tx_vlan_features);
+
+	netdev_features_set_array(&netif_f_vlan_filter_feature_set,
+				  &netdev_vlan_filter_features);
+
+	netdev_all_vlan_features = netdev_rx_vlan_features;
+	netdev_features_set(&netdev_all_vlan_features, netdev_tx_vlan_features);
+	netdev_features_set(&netdev_all_vlan_features,
+			    netdev_vlan_filter_features);
+
+	netdev_features_set_array(&netif_f_ctag_vlan_feature_set,
+				  &netdev_ctag_vlan_features);
+
+	netdev_features_set_array(&netif_f_stag_vlan_feature_set,
+				  &netdev_stag_vlan_features);
+
+	netdev_features_set_array(&netif_f_gso_encap_feature_set,
+				  &netdev_gso_encap_all_features);
+
+	netdev_features_set_array(&netif_f_xfrm_feature_set,
+				  &netdev_xfrm_features);
+
+	netdev_features_set_array(&netif_f_tls_feature_set,
+				  &netdev_tls_features);
+
+	netdev_csum_gso_features_mask =
+		netdev_features_or(netdev_gso_software_features,
+				   netdev_csum_features_mask);
+
+	netdev_features_fill(&features);
+	netdev_ethtool_features =
+		netdev_features_andnot(features, netdev_never_change_features);
+}
+
 /*
  *	Initialize the DEV module. At boot time this walks the device list and
  *	unhooks any devices that fail to initialise (normally hardware not
@@ -11285,6 +11370,8 @@ static int __init net_dev_init(void)
 	if (register_pernet_subsys(&netdev_net_ops))
 		goto out;
 
+	netdev_features_init();
+
 	/*
 	 *	Initialise the packet receive queues.
 	 */
diff --git a/net/core/netdev_features.c b/net/core/netdev_features.c
new file mode 100644
index 000000000000..db870038213a
--- /dev/null
+++ b/net/core/netdev_features.c
@@ -0,0 +1,241 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Network device features.
+ */
+
+#include <linux/netdev_features.h>
+#include <linux/netdev_features_helper.h>
+
+netdev_features_t netdev_ethtool_features __ro_after_init;
+EXPORT_SYMBOL_GPL(netdev_ethtool_features);
+
+netdev_features_t netdev_never_change_features __ro_after_init;
+EXPORT_SYMBOL_GPL(netdev_never_change_features);
+
+netdev_features_t netdev_gso_features_mask __ro_after_init;
+EXPORT_SYMBOL_GPL(netdev_gso_features_mask);
+
+netdev_features_t netdev_ip_csum_features __ro_after_init;
+EXPORT_SYMBOL_GPL(netdev_ip_csum_features);
+
+netdev_features_t netdev_csum_features_mask __ro_after_init;
+EXPORT_SYMBOL_GPL(netdev_csum_features_mask);
+
+netdev_features_t netdev_general_tso_features __ro_after_init;
+EXPORT_SYMBOL_GPL(netdev_general_tso_features);
+
+netdev_features_t netdev_all_tso_features __ro_after_init;
+EXPORT_SYMBOL_GPL(netdev_all_tso_features);
+
+netdev_features_t netdev_tso_ecn_features __ro_after_init;
+EXPORT_SYMBOL_GPL(netdev_tso_ecn_features);
+
+netdev_features_t netdev_all_fcoe_features __ro_after_init;
+EXPORT_SYMBOL_GPL(netdev_all_fcoe_features);
+
+netdev_features_t netdev_gso_software_features __ro_after_init;
+EXPORT_SYMBOL_GPL(netdev_gso_software_features);
+
+netdev_features_t netdev_one_for_all_features __ro_after_init;
+EXPORT_SYMBOL_GPL(netdev_one_for_all_features);
+
+netdev_features_t netdev_all_for_all_features __ro_after_init;
+EXPORT_SYMBOL_GPL(netdev_all_for_all_features);
+
+netdev_features_t netdev_upper_disable_features __ro_after_init;
+EXPORT_SYMBOL_GPL(netdev_upper_disable_features);
+
+netdev_features_t netdev_soft_features __ro_after_init;
+EXPORT_SYMBOL_GPL(netdev_soft_features);
+
+netdev_features_t netdev_soft_off_features __ro_after_init;
+EXPORT_SYMBOL_GPL(netdev_soft_off_features);
+
+netdev_features_t netdev_all_vlan_features __ro_after_init;
+EXPORT_SYMBOL_GPL(netdev_all_vlan_features);
+
+netdev_features_t netdev_vlan_filter_features __ro_after_init;
+EXPORT_SYMBOL_GPL(netdev_vlan_filter_features);
+
+netdev_features_t netdev_rx_vlan_features __ro_after_init;
+EXPORT_SYMBOL_GPL(netdev_rx_vlan_features);
+
+netdev_features_t netdev_tx_vlan_features __ro_after_init;
+EXPORT_SYMBOL_GPL(netdev_tx_vlan_features);
+
+netdev_features_t netdev_ctag_vlan_features __ro_after_init;
+EXPORT_SYMBOL_GPL(netdev_ctag_vlan_features);
+
+netdev_features_t netdev_stag_vlan_features __ro_after_init;
+EXPORT_SYMBOL_GPL(netdev_stag_vlan_features);
+
+netdev_features_t netdev_gso_encap_all_features __ro_after_init;
+EXPORT_SYMBOL_GPL(netdev_gso_encap_all_features);
+
+netdev_features_t netdev_xfrm_features __ro_after_init;
+EXPORT_SYMBOL_GPL(netdev_xfrm_features);
+
+netdev_features_t netdev_tls_features __ro_after_init;
+EXPORT_SYMBOL_GPL(netdev_tls_features);
+
+netdev_features_t netdev_csum_gso_features_mask __ro_after_init;
+EXPORT_SYMBOL_GPL(netdev_csum_gso_features_mask);
+
+DECLARE_NETDEV_FEATURE_SET(netif_f_never_change_feature_set,
+			   NETIF_F_VLAN_CHALLENGED_BIT,
+			   NETIF_F_LLTX_BIT,
+			   NETIF_F_NETNS_LOCAL_BIT);
+EXPORT_SYMBOL_GPL(netif_f_never_change_feature_set);
+
+DECLARE_NETDEV_FEATURE_SET(netif_f_gso_feature_set_mask,
+			   NETIF_F_TSO_BIT,
+			   NETIF_F_GSO_ROBUST_BIT,
+			   NETIF_F_TSO_ECN_BIT,
+			   NETIF_F_TSO_MANGLEID_BIT,
+			   NETIF_F_TSO6_BIT,
+			   NETIF_F_FSO_BIT,
+			   NETIF_F_GSO_GRE_BIT,
+			   NETIF_F_GSO_GRE_CSUM_BIT,
+			   NETIF_F_GSO_IPXIP4_BIT,
+			   NETIF_F_GSO_IPXIP6_BIT,
+			   NETIF_F_GSO_UDP_TUNNEL_BIT,
+			   NETIF_F_GSO_UDP_TUNNEL_CSUM_BIT,
+			   NETIF_F_GSO_PARTIAL_BIT,
+			   NETIF_F_GSO_TUNNEL_REMCSUM_BIT,
+			   NETIF_F_GSO_SCTP_BIT,
+			   NETIF_F_GSO_ESP_BIT,
+			   NETIF_F_GSO_UDP_BIT,
+			   NETIF_F_GSO_UDP_L4_BIT,
+			   NETIF_F_GSO_FRAGLIST_BIT);
+EXPORT_SYMBOL_GPL(netif_f_gso_feature_set_mask);
+
+DECLARE_NETDEV_FEATURE_SET(netif_f_ip_csum_feature_set,
+			   NETIF_F_IP_CSUM_BIT,
+			   NETIF_F_IPV6_CSUM_BIT);
+EXPORT_SYMBOL_GPL(netif_f_ip_csum_feature_set);
+
+DECLARE_NETDEV_FEATURE_SET(netif_f_csum_feature_set_mask,
+			   NETIF_F_IP_CSUM_BIT,
+			   NETIF_F_IPV6_CSUM_BIT,
+			   NETIF_F_HW_CSUM_BIT);
+EXPORT_SYMBOL_GPL(netif_f_csum_feature_set_mask);
+
+DECLARE_NETDEV_FEATURE_SET(netif_f_general_tso_feature_set,
+			   NETIF_F_TSO_BIT,
+			   NETIF_F_TSO6_BIT);
+EXPORT_SYMBOL_GPL(netif_f_general_tso_feature_set);
+
+DECLARE_NETDEV_FEATURE_SET(netif_f_all_tso_feature_set,
+			   NETIF_F_TSO_BIT,
+			   NETIF_F_TSO6_BIT,
+			   NETIF_F_TSO_ECN_BIT,
+			   NETIF_F_TSO_MANGLEID_BIT);
+EXPORT_SYMBOL_GPL(netif_f_all_tso_feature_set);
+
+DECLARE_NETDEV_FEATURE_SET(netif_f_tso_ecn_feature_set,
+			   NETIF_F_TSO_ECN_BIT);
+EXPORT_SYMBOL_GPL(netif_f_tso_ecn_feature_set);
+
+DECLARE_NETDEV_FEATURE_SET(netif_f_all_fcoe_feature_set,
+			   NETIF_F_FCOE_CRC_BIT,
+			   NETIF_F_FCOE_MTU_BIT,
+			   NETIF_F_FSO_BIT);
+EXPORT_SYMBOL_GPL(netif_f_all_fcoe_feature_set);
+
+DECLARE_NETDEV_FEATURE_SET(netif_f_gso_soft_feature_set,
+			   NETIF_F_TSO_BIT,
+			   NETIF_F_TSO6_BIT,
+			   NETIF_F_TSO_ECN_BIT,
+			   NETIF_F_TSO_MANGLEID_BIT,
+			   NETIF_F_GSO_SCTP_BIT,
+			   NETIF_F_GSO_UDP_L4_BIT,
+			   NETIF_F_GSO_FRAGLIST_BIT);
+EXPORT_SYMBOL_GPL(netif_f_gso_soft_feature_set);
+
+DECLARE_NETDEV_FEATURE_SET(netif_f_one_for_all_feature_set,
+			   NETIF_F_TSO_BIT,
+			   NETIF_F_TSO6_BIT,
+			   NETIF_F_TSO_ECN_BIT,
+			   NETIF_F_TSO_MANGLEID_BIT,
+			   NETIF_F_GSO_SCTP_BIT,
+			   NETIF_F_GSO_UDP_L4_BIT,
+			   NETIF_F_GSO_FRAGLIST_BIT,
+			   NETIF_F_GSO_ROBUST_BIT,
+			   NETIF_F_SG_BIT,
+			   NETIF_F_HIGHDMA_BIT,
+			   NETIF_F_FRAGLIST_BIT,
+			   NETIF_F_VLAN_CHALLENGED);
+EXPORT_SYMBOL_GPL(netif_f_one_for_all_feature_set);
+
+DECLARE_NETDEV_FEATURE_SET(netif_f_all_for_all_feature_set,
+			   NETIF_F_NOCACHE_COPY_BIT,
+			   NETIF_F_FSO_BIT);
+EXPORT_SYMBOL_GPL(netif_f_all_for_all_feature_set);
+
+DECLARE_NETDEV_FEATURE_SET(netif_f_upper_disables_feature_set,
+			   NETIF_F_LRO_BIT);
+EXPORT_SYMBOL_GPL(netif_f_upper_disables_feature_set);
+
+DECLARE_NETDEV_FEATURE_SET(netif_f_soft_feature_set,
+			   NETIF_F_GSO_BIT,
+			   NETIF_F_GRO_BIT);
+EXPORT_SYMBOL_GPL(netif_f_soft_feature_set);
+
+DECLARE_NETDEV_FEATURE_SET(netif_f_soft_off_feature_set,
+			   NETIF_F_GRO_FRAGLIST_BIT,
+			   NETIF_F_GRO_UDP_FWD_BIT);
+EXPORT_SYMBOL_GPL(netif_f_soft_off_feature_set);
+
+DECLARE_NETDEV_FEATURE_SET(netif_f_vlan_feature_set,
+			   NETIF_F_HW_VLAN_CTAG_FILTER_BIT,
+			   NETIF_F_HW_VLAN_CTAG_RX_BIT,
+			   NETIF_F_HW_VLAN_CTAG_TX_BIT,
+			   NETIF_F_HW_VLAN_STAG_FILTER_BIT,
+			   NETIF_F_HW_VLAN_STAG_RX_BIT,
+			   NETIF_F_HW_VLAN_STAG_TX_BIT);
+EXPORT_SYMBOL_GPL(netif_f_vlan_feature_set);
+
+DECLARE_NETDEV_FEATURE_SET(netif_f_tx_vlan_feature_set,
+			   NETIF_F_HW_VLAN_CTAG_TX_BIT,
+			   NETIF_F_HW_VLAN_STAG_TX_BIT);
+EXPORT_SYMBOL_GPL(netif_f_tx_vlan_feature_set);
+
+DECLARE_NETDEV_FEATURE_SET(netif_f_rx_vlan_feature_set,
+			   NETIF_F_HW_VLAN_CTAG_RX_BIT,
+			   NETIF_F_HW_VLAN_STAG_RX_BIT);
+EXPORT_SYMBOL_GPL(netif_f_rx_vlan_feature_set);
+
+DECLARE_NETDEV_FEATURE_SET(netif_f_vlan_filter_feature_set,
+			   NETIF_F_HW_VLAN_CTAG_FILTER_BIT,
+			   NETIF_F_HW_VLAN_STAG_FILTER_BIT);
+EXPORT_SYMBOL_GPL(netif_f_vlan_filter_feature_set);
+
+DECLARE_NETDEV_FEATURE_SET(netif_f_ctag_vlan_feature_set,
+			   NETIF_F_HW_VLAN_CTAG_TX_BIT,
+			   NETIF_F_HW_VLAN_CTAG_RX_BIT);
+EXPORT_SYMBOL_GPL(netif_f_ctag_vlan_feature_set);
+
+DECLARE_NETDEV_FEATURE_SET(netif_f_stag_vlan_feature_set,
+			   NETIF_F_HW_VLAN_STAG_TX_BIT,
+			   NETIF_F_HW_VLAN_STAG_RX_BIT);
+EXPORT_SYMBOL_GPL(netif_f_stag_vlan_feature_set);
+
+DECLARE_NETDEV_FEATURE_SET(netif_f_gso_encap_feature_set,
+			   NETIF_F_GSO_GRE_BIT,
+			   NETIF_F_GSO_GRE_CSUM_BIT,
+			   NETIF_F_GSO_IPXIP4_BIT,
+			   NETIF_F_GSO_IPXIP6_BIT,
+			   NETIF_F_GSO_UDP_TUNNEL_BIT,
+			   NETIF_F_GSO_UDP_TUNNEL_CSUM_BIT);
+EXPORT_SYMBOL_GPL(netif_f_gso_encap_feature_set);
+
+DECLARE_NETDEV_FEATURE_SET(netif_f_xfrm_feature_set,
+			   NETIF_F_HW_ESP_BIT,
+			   NETIF_F_HW_ESP_TX_CSUM_BIT,
+			   NETIF_F_GSO_ESP_BIT);
+EXPORT_SYMBOL_GPL(netif_f_xfrm_feature_set);
+
+DECLARE_NETDEV_FEATURE_SET(netif_f_tls_feature_set,
+			   NETIF_F_HW_TLS_TX_BIT,
+			   NETIF_F_HW_TLS_RX_BIT);
+EXPORT_SYMBOL_GPL(netif_f_tls_feature_set);
-- 
2.33.0


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [RFCv6 PATCH net-next 03/19] net: replace multiple feature bits with netdev features array
  2022-04-19  2:21 [RFCv6 PATCH net-next 00/19] net: extend the type of netdev_features_t to bitmap Jian Shen
  2022-04-19  2:21 ` [RFCv6 PATCH net-next 01/19] net: introduce operation helpers for netdev features Jian Shen
  2022-04-19  2:21 ` [RFCv6 PATCH net-next 02/19] net: replace general features macroes with global netdev_features variables Jian Shen
@ 2022-04-19  2:21 ` Jian Shen
  2022-04-19  2:21 ` [RFCv6 PATCH net-next 04/19] net: sfc: replace const features initialization " Jian Shen
                   ` (15 subsequent siblings)
  18 siblings, 0 replies; 30+ messages in thread
From: Jian Shen @ 2022-04-19  2:21 UTC (permalink / raw)
  To: davem, kuba, andrew, ecree.xilinx, hkallweit1, alexandr.lobakin,
	saeed, leon
  Cc: netdev, linuxarm, lipeng321

There are many netdev_features bits group used in drivers, replace them
with netdev features array.

Signed-off-by: Jian Shen <shenjian15@huawei.com>
---
 .../net/ethernet/hisilicon/hns3/hns3_enet.c   | 44 ++++++++++++++-----
 drivers/net/ethernet/sfc/ef10.c               | 11 ++++-
 drivers/net/ethernet/sfc/ef100_nic.c          | 24 +++++++---
 drivers/net/ethernet/sfc/efx.c                | 21 ++++++---
 drivers/net/ethernet/sfc/falcon/efx.c         | 10 +++--
 drivers/net/ethernet/sfc/falcon/net_driver.h  |  1 +
 drivers/net/ethernet/sfc/net_driver.h         |  1 +
 net/ethtool/ioctl.c                           | 17 +++++--
 8 files changed, 100 insertions(+), 29 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
index 14dc12c2155d..74ebba5b9bc3 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
@@ -12,6 +12,7 @@
 #include <linux/ip.h>
 #include <linux/ipv6.h>
 #include <linux/module.h>
+#include <linux/netdev_features_helper.h>
 #include <linux/pci.h>
 #include <linux/aer.h>
 #include <linux/skbuff.h>
@@ -3253,23 +3254,46 @@ static struct pci_driver hns3_driver = {
 	.err_handler    = &hns3_err_handler,
 };
 
+DECLARE_NETDEV_FEATURE_SET(hns3_default_feature_set,
+			   NETIF_F_HW_VLAN_CTAG_FILTER_BIT,
+			   NETIF_F_HW_VLAN_CTAG_RX_BIT,
+			   NETIF_F_HW_VLAN_CTAG_TX_BIT,
+			   NETIF_F_RXCSUM_BIT,
+			   NETIF_F_SG_BIT,
+			   NETIF_F_GSO_BIT,
+			   NETIF_F_GRO_BIT,
+			   NETIF_F_TSO_BIT,
+			   NETIF_F_TSO6_BIT,
+			   NETIF_F_GSO_GRE_BIT,
+			   NETIF_F_GSO_GRE_CSUM_BIT,
+			   NETIF_F_GSO_UDP_TUNNEL_BIT,
+			   NETIF_F_SCTP_CRC_BIT,
+			   NETIF_F_FRAGLIST);
+
+DECLARE_NETDEV_FEATURE_SET(hns3_vlan_off_feature_set,
+			   NETIF_F_HW_VLAN_CTAG_FILTER_BIT,
+			   NETIF_F_HW_VLAN_CTAG_RX_BIT,
+			   NETIF_F_HW_VLAN_CTAG_TX_BIT,
+			   NETIF_F_GRO_HW_BIT,
+			   NETIF_F_NTUPLE_BIT,
+			   NETIF_F_HW_TC_BIT);
+
 /* set default feature to hns3 */
 static void hns3_set_default_feature(struct net_device *netdev)
 {
 	struct hnae3_handle *h = hns3_get_handle(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;
 
 	netdev->gso_partial_features |= NETIF_F_GSO_GRE_CSUM;
 
-	netdev->features |= NETIF_F_HW_VLAN_CTAG_FILTER |
-		NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX |
-		NETIF_F_RXCSUM | NETIF_F_SG | NETIF_F_GSO |
-		NETIF_F_GRO | NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_GSO_GRE |
-		NETIF_F_GSO_GRE_CSUM | NETIF_F_GSO_UDP_TUNNEL |
-		NETIF_F_SCTP_CRC | NETIF_F_FRAGLIST;
+	netdev_features_zero(&features);
+	netdev_features_set_array(&hns3_default_feature_set, &features);
+	netdev->features |= features;
 
 	if (ae_dev->dev_version >= HNAE3_DEVICE_VERSION_V2) {
 		netdev->features |= NETIF_F_GRO_HW;
@@ -3296,10 +3320,10 @@ static void hns3_set_default_feature(struct net_device *netdev)
 	if (!test_bit(HNAE3_DEV_SUPPORT_VLAN_FLTR_MDF_B, ae_dev->caps))
 		netdev->hw_features &= ~NETIF_F_HW_VLAN_CTAG_FILTER;
 
-	netdev->vlan_features |= netdev->features &
-		~(NETIF_F_HW_VLAN_CTAG_FILTER | NETIF_F_HW_VLAN_CTAG_TX |
-		  NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_GRO_HW | NETIF_F_NTUPLE |
-		  NETIF_F_HW_TC);
+	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;
 
 	netdev->hw_enc_features |= netdev->vlan_features | NETIF_F_TSO_MANGLEID;
 }
diff --git a/drivers/net/ethernet/sfc/ef10.c b/drivers/net/ethernet/sfc/ef10.c
index 50d535981a35..bb31043902e4 100644
--- a/drivers/net/ethernet/sfc/ef10.c
+++ b/drivers/net/ethernet/sfc/ef10.c
@@ -1301,6 +1301,12 @@ static void efx_ef10_fini_nic(struct efx_nic *efx)
 	nic_data->mc_stats = NULL;
 }
 
+DECLARE_NETDEV_FEATURE_SET(ef10_tso_feature_set,
+			   NETIF_F_GSO_UDP_TUNNEL_BIT,
+			   NETIF_F_GSO_GRE_BIT,
+			   NETIF_F_GSO_UDP_TUNNEL_CSUM_BIT,
+			   NETIF_F_GSO_GRE_CSUM_BIT);
+
 static int efx_ef10_init_nic(struct efx_nic *efx)
 {
 	struct efx_ef10_nic_data *nic_data = efx->nic_data;
@@ -1356,8 +1362,9 @@ static int efx_ef10_init_nic(struct efx_nic *efx)
 	if (efx_has_cap(efx, TX_TSO_V2_ENCAP)) {
 		netdev_features_t encap_tso_features;
 
-		encap_tso_features = NETIF_F_GSO_UDP_TUNNEL | NETIF_F_GSO_GRE |
-			NETIF_F_GSO_UDP_TUNNEL_CSUM | NETIF_F_GSO_GRE_CSUM;
+		netdev_features_zero(&encap_tso_features);
+		netdev_features_set_array(&ef10_tso_feature_set,
+					  &encap_tso_features);
 
 		hw_enc_features |= encap_tso_features | NETIF_F_TSO;
 		efx->net_dev->features |= encap_tso_features;
diff --git a/drivers/net/ethernet/sfc/ef100_nic.c b/drivers/net/ethernet/sfc/ef100_nic.c
index a07cbf45a326..18bf6a33b355 100644
--- a/drivers/net/ethernet/sfc/ef100_nic.c
+++ b/drivers/net/ethernet/sfc/ef100_nic.c
@@ -147,6 +147,15 @@ static int ef100_get_mac_address(struct efx_nic *efx, u8 *mac_address)
 	return 0;
 }
 
+DECLARE_NETDEV_FEATURE_SET(ef100_tso_feature_set,
+			   NETIF_F_TSO_BIT,
+			   NETIF_F_TSO6_BIT,
+			   NETIF_F_GSO_PARTIAL_BIT,
+			   NETIF_F_GSO_UDP_TUNNEL_BIT,
+			   NETIF_F_GSO_UDP_TUNNEL_CSUM_BIT,
+			   NETIF_F_GSO_GRE_BIT,
+			   NETIF_F_GSO_GRE_CSUM_BIT);
+
 static int efx_ef100_init_datapath_caps(struct efx_nic *efx)
 {
 	MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_CAPABILITIES_V7_OUT_LEN);
@@ -185,10 +194,10 @@ static int efx_ef100_init_datapath_caps(struct efx_nic *efx)
 
 	if (efx_ef100_has_cap(nic_data->datapath_caps2, TX_TSO_V3)) {
 		struct net_device *net_dev = efx->net_dev;
-		netdev_features_t tso = NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_GSO_PARTIAL |
-					NETIF_F_GSO_UDP_TUNNEL | NETIF_F_GSO_UDP_TUNNEL_CSUM |
-					NETIF_F_GSO_GRE | NETIF_F_GSO_GRE_CSUM;
+		netdev_features_t tso;
 
+		netdev_features_zero(&tso);
+		netdev_features_set_array(&ef100_tso_feature_set, &tso);
 		net_dev->features |= tso;
 		net_dev->hw_features |= tso;
 		net_dev->hw_enc_features |= tso;
@@ -1105,6 +1114,11 @@ static int ef100_check_design_params(struct efx_nic *efx)
 	return rc;
 }
 
+DECLARE_NETDEV_FEATURE_SET(ef100_vlan_feature_set,
+			   NETIF_F_HW_CSUM_BIT,
+			   NETIF_F_SG_BIT,
+			   NETIF_F_HIGHDMA_BIT);
+
 /*	NIC probe and remove
  */
 static int ef100_probe_main(struct efx_nic *efx)
@@ -1126,8 +1140,8 @@ static int ef100_probe_main(struct efx_nic *efx)
 	net_dev->features |= efx->type->offload_features;
 	net_dev->hw_features |= efx->type->offload_features;
 	net_dev->hw_enc_features |= efx->type->offload_features;
-	net_dev->vlan_features |= NETIF_F_HW_CSUM | NETIF_F_SG |
-				  NETIF_F_HIGHDMA | NETIF_F_ALL_TSO;
+	net_dev->vlan_features |= NETIF_F_ALL_TSO;
+	netdev_vlan_features_set_array(net_dev, &ef100_vlan_feature_set);
 
 	/* Populate design-parameter defaults */
 	nic_data->tso_max_hdr_len = ESE_EF100_DP_GZ_TSO_MAX_HDR_LEN_DEFAULT;
diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c
index 302dc835ac3d..bd76e1c5f879 100644
--- a/drivers/net/ethernet/sfc/efx.c
+++ b/drivers/net/ethernet/sfc/efx.c
@@ -988,6 +988,18 @@ static int efx_pci_probe_main(struct efx_nic *efx)
 	return rc;
 }
 
+DECLARE_NETDEV_FEATURE_SET(efx_active_feature_set,
+			   NETIF_F_SG_BIT,
+			   NETIF_F_TSO_BIT,
+			   NETIF_F_RXCSUM_BIT,
+			   NETIF_F_RXALL_BIT);
+
+DECLARE_NETDEV_FEATURE_SET(efx_vlan_feature_set,
+			   NETIF_F_HW_CSUM_BIT,
+			   NETIF_F_SG_BIT,
+			   NETIF_F_HIGHDMA_BIT,
+			   NETIF_F_RXCSUM_BIT);
+
 static int efx_pci_probe_post_io(struct efx_nic *efx)
 {
 	struct net_device *net_dev = efx->net_dev;
@@ -1004,17 +1016,16 @@ static int efx_pci_probe_post_io(struct efx_nic *efx)
 	}
 
 	/* Determine netdevice features */
-	net_dev->features |= (efx->type->offload_features | NETIF_F_SG |
-			      NETIF_F_TSO | NETIF_F_RXCSUM | NETIF_F_RXALL);
+	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))
 		net_dev->features |= NETIF_F_TSO6;
 	/* Check whether device supports TSO */
 	if (!efx->type->tso_versions || !efx->type->tso_versions(efx))
 		net_dev->features &= ~NETIF_F_ALL_TSO;
 	/* Mask for features that also apply to VLAN devices */
-	net_dev->vlan_features |= (NETIF_F_HW_CSUM | NETIF_F_SG |
-				   NETIF_F_HIGHDMA | NETIF_F_ALL_TSO |
-				   NETIF_F_RXCSUM);
+	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;
 
diff --git a/drivers/net/ethernet/sfc/falcon/efx.c b/drivers/net/ethernet/sfc/falcon/efx.c
index 60c595ef7589..eeae4edf4a47 100644
--- a/drivers/net/ethernet/sfc/falcon/efx.c
+++ b/drivers/net/ethernet/sfc/falcon/efx.c
@@ -2859,6 +2859,12 @@ static int ef4_pci_probe_main(struct ef4_nic *efx)
 	return rc;
 }
 
+DECLARE_NETDEV_FEATURE_SET(efx_vlan_feature_set,
+			   NETIF_F_HW_CSUM_BIT,
+			   NETIF_F_SG_BIT,
+			   NETIF_F_HIGHDMA_BIT,
+			   NETIF_F_RXCSUM_BIT);
+
 /* NIC initialisation
  *
  * This is called at module load (or hotplug insertion,
@@ -2907,9 +2913,7 @@ static int ef4_pci_probe(struct pci_dev *pci_dev,
 	net_dev->features |= (efx->type->offload_features | NETIF_F_SG |
 			      NETIF_F_RXCSUM);
 	/* Mask for features that also apply to VLAN devices */
-	net_dev->vlan_features |= (NETIF_F_HW_CSUM | NETIF_F_SG |
-				   NETIF_F_HIGHDMA | NETIF_F_RXCSUM);
-
+	netdev_vlan_features_set_array(net_dev, &efx_vlan_feature_set);
 	net_dev->hw_features = net_dev->features & ~efx->fixed_features;
 
 	/* Disable VLAN filtering by default.  It may be enforced if
diff --git a/drivers/net/ethernet/sfc/falcon/net_driver.h b/drivers/net/ethernet/sfc/falcon/net_driver.h
index a381cf9ec4f3..e1c7e3098a95 100644
--- a/drivers/net/ethernet/sfc/falcon/net_driver.h
+++ b/drivers/net/ethernet/sfc/falcon/net_driver.h
@@ -26,6 +26,7 @@
 #include <linux/vmalloc.h>
 #include <linux/i2c.h>
 #include <linux/mtd/mtd.h>
+#include <linux/netdev_features_helper.h>
 #include <net/busy_poll.h>
 
 #include "enum.h"
diff --git a/drivers/net/ethernet/sfc/net_driver.h b/drivers/net/ethernet/sfc/net_driver.h
index c75dc75e2857..2407fd4ef785 100644
--- a/drivers/net/ethernet/sfc/net_driver.h
+++ b/drivers/net/ethernet/sfc/net_driver.h
@@ -25,6 +25,7 @@
 #include <linux/rwsem.h>
 #include <linux/vmalloc.h>
 #include <linux/mtd/mtd.h>
+#include <linux/netdev_features_helper.h>
 #include <net/busy_poll.h>
 #include <net/xdp.h>
 
diff --git a/net/ethtool/ioctl.c b/net/ethtool/ioctl.c
index 326e14ee05db..243ee8a0bd18 100644
--- a/net/ethtool/ioctl.c
+++ b/net/ethtool/ioctl.c
@@ -15,6 +15,7 @@
 #include <linux/errno.h>
 #include <linux/ethtool.h>
 #include <linux/netdevice.h>
+#include <linux/netdev_features_helper.h>
 #include <linux/net_tstamp.h>
 #include <linux/phy.h>
 #include <linux/bitops.h>
@@ -288,9 +289,13 @@ static int ethtool_set_one_feature(struct net_device *dev,
 
 #define ETH_ALL_FLAGS    (ETH_FLAG_LRO | ETH_FLAG_RXVLAN | ETH_FLAG_TXVLAN | \
 			  ETH_FLAG_NTUPLE | ETH_FLAG_RXHASH)
-#define ETH_ALL_FEATURES (NETIF_F_LRO | NETIF_F_HW_VLAN_CTAG_RX | \
-			  NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_NTUPLE | \
-			  NETIF_F_RXHASH)
+
+DECLARE_NETDEV_FEATURE_SET(ethtool_all_feature_set,
+			   NETIF_F_LRO_BIT,
+			   NETIF_F_HW_VLAN_CTAG_RX_BIT,
+			   NETIF_F_HW_VLAN_CTAG_TX_BIT,
+			   NETIF_F_NTUPLE_BIT,
+			   NETIF_F_RXHASH_BIT);
 
 static u32 __ethtool_get_flags(struct net_device *dev)
 {
@@ -313,6 +318,7 @@ static u32 __ethtool_get_flags(struct net_device *dev)
 static int __ethtool_set_flags(struct net_device *dev, u32 data)
 {
 	netdev_features_t features = 0, changed;
+	netdev_features_t eth_all_features;
 
 	if (data & ~ETH_ALL_FLAGS)
 		return -EINVAL;
@@ -328,8 +334,11 @@ static int __ethtool_set_flags(struct net_device *dev, u32 data)
 	if (data & ETH_FLAG_RXHASH)
 		features |= NETIF_F_RXHASH;
 
+	netdev_features_zero(&eth_all_features);
+	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;
+	changed = (features ^ dev->features) & eth_all_features;
 	if (changed & ~dev->hw_features)
 		return (changed & dev->hw_features) ? -EINVAL : -EOPNOTSUPP;
 
-- 
2.33.0


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [RFCv6 PATCH net-next 04/19] net: sfc: replace const features initialization with netdev features array
  2022-04-19  2:21 [RFCv6 PATCH net-next 00/19] net: extend the type of netdev_features_t to bitmap Jian Shen
                   ` (2 preceding siblings ...)
  2022-04-19  2:21 ` [RFCv6 PATCH net-next 03/19] net: replace multiple feature bits with netdev features array Jian Shen
@ 2022-04-19  2:21 ` Jian Shen
  2022-04-19  2:21 ` [RFCv6 PATCH net-next 05/19] net: simplify the netdev features expression Jian Shen
                   ` (14 subsequent siblings)
  18 siblings, 0 replies; 30+ messages in thread
From: Jian Shen @ 2022-04-19  2:21 UTC (permalink / raw)
  To: davem, kuba, andrew, ecree.xilinx, hkallweit1, alexandr.lobakin,
	saeed, leon
  Cc: netdev, linuxarm, lipeng321

There are some drivers(e.g. sfc) use netdev_features in global
structure initialization. Changed the its netdev_features_t memeber
to netdev_features_t *, and make it prefer to a netdev_features_t
global variables.

Signed-off-by: Jian Shen <shenjian15@huawei.com>
---
 drivers/net/ethernet/sfc/ef10.c              | 11 +----
 drivers/net/ethernet/sfc/ef100_nic.c         | 15 +++----
 drivers/net/ethernet/sfc/efx.c               | 46 +++++++++++++++++++-
 drivers/net/ethernet/sfc/falcon/efx.c        | 25 ++++++++++-
 drivers/net/ethernet/sfc/falcon/efx.h        |  3 ++
 drivers/net/ethernet/sfc/falcon/falcon.c     |  4 +-
 drivers/net/ethernet/sfc/falcon/net_driver.h |  2 +-
 drivers/net/ethernet/sfc/net_driver.h        |  2 +-
 drivers/net/ethernet/sfc/rx_common.c         |  2 +-
 drivers/net/ethernet/sfc/rx_common.h         |  4 ++
 drivers/net/ethernet/sfc/siena.c             |  3 +-
 11 files changed, 87 insertions(+), 30 deletions(-)

diff --git a/drivers/net/ethernet/sfc/ef10.c b/drivers/net/ethernet/sfc/ef10.c
index bb31043902e4..63fc4c771955 100644
--- a/drivers/net/ethernet/sfc/ef10.c
+++ b/drivers/net/ethernet/sfc/ef10.c
@@ -4021,13 +4021,6 @@ static unsigned int efx_ef10_recycle_ring_size(const struct efx_nic *efx)
 	return ret;
 }
 
-#define EF10_OFFLOAD_FEATURES		\
-	(NETIF_F_IP_CSUM |		\
-	 NETIF_F_HW_VLAN_CTAG_FILTER |	\
-	 NETIF_F_IPV6_CSUM |		\
-	 NETIF_F_RXHASH |		\
-	 NETIF_F_NTUPLE)
-
 const struct efx_nic_type efx_hunt_a0_vf_nic_type = {
 	.is_vf = true,
 	.mem_bar = efx_ef10_vf_mem_bar,
@@ -4128,7 +4121,7 @@ const struct efx_nic_type efx_hunt_a0_vf_nic_type = {
 	.always_rx_scatter = true,
 	.min_interrupt_mode = EFX_INT_MODE_MSIX,
 	.timer_period_max = 1 << ERF_DD_EVQ_IND_TIMER_VAL_WIDTH,
-	.offload_features = EF10_OFFLOAD_FEATURES,
+	.offload_features = &ef10_offload_features,
 	.mcdi_max_ver = 2,
 	.max_rx_ip_filters = EFX_MCDI_FILTER_TBL_ROWS,
 	.hwtstamp_filters = 1 << HWTSTAMP_FILTER_NONE |
@@ -4266,7 +4259,7 @@ const struct efx_nic_type efx_hunt_a0_nic_type = {
 	.option_descriptors = true,
 	.min_interrupt_mode = EFX_INT_MODE_LEGACY,
 	.timer_period_max = 1 << ERF_DD_EVQ_IND_TIMER_VAL_WIDTH,
-	.offload_features = EF10_OFFLOAD_FEATURES,
+	.offload_features = &ef10_offload_features,
 	.mcdi_max_ver = 2,
 	.max_rx_ip_filters = EFX_MCDI_FILTER_TBL_ROWS,
 	.hwtstamp_filters = 1 << HWTSTAMP_FILTER_NONE |
diff --git a/drivers/net/ethernet/sfc/ef100_nic.c b/drivers/net/ethernet/sfc/ef100_nic.c
index 18bf6a33b355..679530f20bd6 100644
--- a/drivers/net/ethernet/sfc/ef100_nic.c
+++ b/drivers/net/ethernet/sfc/ef100_nic.c
@@ -714,16 +714,11 @@ static unsigned int efx_ef100_recycle_ring_size(const struct efx_nic *efx)
 
 /*	NIC level access functions
  */
-#define EF100_OFFLOAD_FEATURES	(NETIF_F_HW_CSUM | NETIF_F_RXCSUM |	\
-	NETIF_F_HIGHDMA | NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_NTUPLE | \
-	NETIF_F_RXHASH | NETIF_F_RXFCS | NETIF_F_TSO_ECN | NETIF_F_RXALL | \
-	NETIF_F_HW_VLAN_CTAG_TX)
-
 const struct efx_nic_type ef100_pf_nic_type = {
 	.revision = EFX_REV_EF100,
 	.is_vf = false,
 	.probe = ef100_probe_pf,
-	.offload_features = EF100_OFFLOAD_FEATURES,
+	.offload_features = &ef100_offload_features,
 	.mcdi_max_ver = 2,
 	.mcdi_request = ef100_mcdi_request,
 	.mcdi_poll_response = ef100_mcdi_poll_response,
@@ -809,7 +804,7 @@ const struct efx_nic_type ef100_vf_nic_type = {
 	.revision = EFX_REV_EF100,
 	.is_vf = true,
 	.probe = ef100_probe_vf,
-	.offload_features = EF100_OFFLOAD_FEATURES,
+	.offload_features = &ef100_offload_features,
 	.mcdi_max_ver = 2,
 	.mcdi_request = ef100_mcdi_request,
 	.mcdi_poll_response = ef100_mcdi_poll_response,
@@ -1137,9 +1132,9 @@ static int ef100_probe_main(struct efx_nic *efx)
 		return -ENOMEM;
 	efx->nic_data = nic_data;
 	nic_data->efx = efx;
-	net_dev->features |= efx->type->offload_features;
-	net_dev->hw_features |= efx->type->offload_features;
-	net_dev->hw_enc_features |= efx->type->offload_features;
+	net_dev->features |= *efx->type->offload_features;
+	net_dev->hw_features |= *efx->type->offload_features;
+	net_dev->hw_enc_features |= *efx->type->offload_features;
 	net_dev->vlan_features |= NETIF_F_ALL_TSO;
 	netdev_vlan_features_set_array(net_dev, &ef100_vlan_feature_set);
 
diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c
index bd76e1c5f879..15a896f397f2 100644
--- a/drivers/net/ethernet/sfc/efx.c
+++ b/drivers/net/ethernet/sfc/efx.c
@@ -1016,9 +1016,9 @@ static int efx_pci_probe_post_io(struct efx_nic *efx)
 	}
 
 	/* Determine netdevice features */
-	net_dev->features |= efx->type->offload_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 | 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))
@@ -1289,6 +1289,46 @@ static struct pci_driver efx_pci_driver = {
 #endif
 };
 
+DECLARE_NETDEV_FEATURE_SET(ef10_offload_feature_set,
+			   NETIF_F_IP_CSUM_BIT,
+			   NETIF_F_HW_VLAN_CTAG_FILTER_BIT,
+			   NETIF_F_IPV6_CSUM_BIT,
+			   NETIF_F_RXHASH_BIT,
+			   NETIF_F_NTUPLE_BIT);
+
+DECLARE_NETDEV_FEATURE_SET(ef100_offload_feature_set,
+			   NETIF_F_HW_CSUM_BIT,
+			   NETIF_F_RXCSUM_BIT,
+			   NETIF_F_HIGHDMA_BIT,
+			   NETIF_F_SG_BIT,
+			   NETIF_F_FRAGLIST_BIT,
+			   NETIF_F_NTUPLE_BIT,
+			   NETIF_F_RXHASH_BIT,
+			   NETIF_F_RXFCS_BIT,
+			   NETIF_F_TSO_ECN_BIT,
+			   NETIF_F_RXALL_BIT,
+			   NETIF_F_HW_VLAN_CTAG_TX_BIT);
+
+DECLARE_NETDEV_FEATURE_SET(siena_offload_feature_set,
+			   NETIF_F_IP_CSUM_BIT,
+			   NETIF_F_IPV6_CSUM_BIT,
+			   NETIF_F_RXHASH_BIT,
+			   NETIF_F_NTUPLE_BIT);
+
+netdev_features_t ef10_offload_features __ro_after_init;
+netdev_features_t ef100_offload_features __ro_after_init;
+netdev_features_t siena_offload_features __ro_after_init;
+
+static void efx_features_init(void)
+{
+	netdev_features_set_array(&ef10_offload_feature_set,
+				  &ef10_offload_features);
+	netdev_features_set_array(&ef100_offload_feature_set,
+				  &ef100_offload_features);
+	netdev_features_set_array(&siena_offload_feature_set,
+				  &siena_offload_features);
+}
+
 /**************************************************************************
  *
  * Kernel module interface
@@ -1323,6 +1363,8 @@ static int __init efx_init_module(void)
 	if (rc < 0)
 		goto err_pci_ef100;
 
+	efx_features_init();
+
 	return 0;
 
  err_pci_ef100:
diff --git a/drivers/net/ethernet/sfc/falcon/efx.c b/drivers/net/ethernet/sfc/falcon/efx.c
index eeae4edf4a47..7d2276aa2bf6 100644
--- a/drivers/net/ethernet/sfc/falcon/efx.c
+++ b/drivers/net/ethernet/sfc/falcon/efx.c
@@ -1694,7 +1694,7 @@ static int ef4_probe_filters(struct ef4_nic *efx)
 		goto out_unlock;
 
 #ifdef CONFIG_RFS_ACCEL
-	if (efx->type->offload_features & NETIF_F_NTUPLE) {
+	if (*efx->type->offload_features & NETIF_F_NTUPLE) {
 		struct ef4_channel *channel;
 		int i, success = 1;
 
@@ -2910,7 +2910,7 @@ static int ef4_pci_probe(struct pci_dev *pci_dev,
 	if (rc)
 		goto fail3;
 
-	net_dev->features |= (efx->type->offload_features | NETIF_F_SG |
+	net_dev->features |= (*efx->type->offload_features | NETIF_F_SG |
 			      NETIF_F_RXCSUM);
 	/* Mask for features that also apply to VLAN devices */
 	netdev_vlan_features_set_array(net_dev, &efx_vlan_feature_set);
@@ -3174,6 +3174,25 @@ static struct pci_driver ef4_pci_driver = {
 	.err_handler	= &ef4_err_handlers,
 };
 
+DECLARE_NETDEV_FEATURE_SET(falcon_b0_offload_feature_set,
+			   NETIF_F_IP_CSUM_BIT,
+			   NETIF_F_RXHASH_BIT,
+			   NETIF_F_NTUPLE_BIT);
+
+DECLARE_NETDEV_FEATURE_SET(falcon_a1_offload_feature_set,
+			   NETIF_F_IP_CSUM_BIT);
+
+netdev_features_t falcon_b0_offload_features __ro_after_init;
+netdev_features_t falcon_a1_offload_features __ro_after_init;
+
+static void ef4_features_init(void)
+{
+	netdev_features_set_array(&falcon_b0_offload_feature_set,
+				  &falcon_b0_offload_features);
+	netdev_features_set_array(&falcon_a1_offload_feature_set,
+				  &falcon_a1_offload_features);
+}
+
 /**************************************************************************
  *
  * Kernel module interface
@@ -3204,6 +3223,8 @@ static int __init ef4_init_module(void)
 	if (rc < 0)
 		goto err_pci;
 
+	ef4_features_init();
+
 	return 0;
 
  err_pci:
diff --git a/drivers/net/ethernet/sfc/falcon/efx.h b/drivers/net/ethernet/sfc/falcon/efx.h
index d3b4646545fa..f31b5c6e02bc 100644
--- a/drivers/net/ethernet/sfc/falcon/efx.h
+++ b/drivers/net/ethernet/sfc/falcon/efx.h
@@ -271,4 +271,7 @@ static inline bool ef4_rwsem_assert_write_locked(struct rw_semaphore *sem)
 	return true;
 }
 
+extern netdev_features_t falcon_b0_offload_features __ro_after_init;
+extern netdev_features_t falcon_a1_offload_features __ro_after_init;
+
 #endif /* EF4_EFX_H */
diff --git a/drivers/net/ethernet/sfc/falcon/falcon.c b/drivers/net/ethernet/sfc/falcon/falcon.c
index 3324a6219a09..fda25f3f8e66 100644
--- a/drivers/net/ethernet/sfc/falcon/falcon.c
+++ b/drivers/net/ethernet/sfc/falcon/falcon.c
@@ -2799,7 +2799,7 @@ const struct ef4_nic_type falcon_a1_nic_type = {
 	.can_rx_scatter = false,
 	.max_interrupt_mode = EF4_INT_MODE_MSI,
 	.timer_period_max =  1 << FRF_AB_TC_TIMER_VAL_WIDTH,
-	.offload_features = NETIF_F_IP_CSUM,
+	.offload_features = &falcon_a1_offload_features,
 };
 
 const struct ef4_nic_type falcon_b0_nic_type = {
@@ -2898,6 +2898,6 @@ const struct ef4_nic_type falcon_b0_nic_type = {
 	.can_rx_scatter = true,
 	.max_interrupt_mode = EF4_INT_MODE_MSIX,
 	.timer_period_max =  1 << FRF_AB_TC_TIMER_VAL_WIDTH,
-	.offload_features = NETIF_F_IP_CSUM | NETIF_F_RXHASH | NETIF_F_NTUPLE,
+	.offload_features = &falcon_b0_offload_features,
 	.max_rx_ip_filters = FR_BZ_RX_FILTER_TBL0_ROWS,
 };
diff --git a/drivers/net/ethernet/sfc/falcon/net_driver.h b/drivers/net/ethernet/sfc/falcon/net_driver.h
index e1c7e3098a95..26aff929c6d2 100644
--- a/drivers/net/ethernet/sfc/falcon/net_driver.h
+++ b/drivers/net/ethernet/sfc/falcon/net_driver.h
@@ -1154,7 +1154,7 @@ struct ef4_nic_type {
 	bool always_rx_scatter;
 	unsigned int max_interrupt_mode;
 	unsigned int timer_period_max;
-	netdev_features_t offload_features;
+	const netdev_features_t *offload_features;
 	unsigned int max_rx_ip_filters;
 };
 
diff --git a/drivers/net/ethernet/sfc/net_driver.h b/drivers/net/ethernet/sfc/net_driver.h
index 2407fd4ef785..6b52f2924bf7 100644
--- a/drivers/net/ethernet/sfc/net_driver.h
+++ b/drivers/net/ethernet/sfc/net_driver.h
@@ -1480,7 +1480,7 @@ struct efx_nic_type {
 	bool option_descriptors;
 	unsigned int min_interrupt_mode;
 	unsigned int timer_period_max;
-	netdev_features_t offload_features;
+	const netdev_features_t *offload_features;
 	int mcdi_max_ver;
 	unsigned int max_rx_ip_filters;
 	u32 hwtstamp_filters;
diff --git a/drivers/net/ethernet/sfc/rx_common.c b/drivers/net/ethernet/sfc/rx_common.c
index 1b22c7be0088..acdc3c84aaaa 100644
--- a/drivers/net/ethernet/sfc/rx_common.c
+++ b/drivers/net/ethernet/sfc/rx_common.c
@@ -796,7 +796,7 @@ int efx_probe_filters(struct efx_nic *efx)
 		goto out_unlock;
 
 #ifdef CONFIG_RFS_ACCEL
-	if (efx->type->offload_features & NETIF_F_NTUPLE) {
+	if (*efx->type->offload_features & NETIF_F_NTUPLE) {
 		struct efx_channel *channel;
 		int i, success = 1;
 
diff --git a/drivers/net/ethernet/sfc/rx_common.h b/drivers/net/ethernet/sfc/rx_common.h
index fbd2769307f9..09b38b0cb401 100644
--- a/drivers/net/ethernet/sfc/rx_common.h
+++ b/drivers/net/ethernet/sfc/rx_common.h
@@ -113,4 +113,8 @@ bool __efx_filter_rfs_expire(struct efx_channel *channel, unsigned int quota);
 int efx_probe_filters(struct efx_nic *efx);
 void efx_remove_filters(struct efx_nic *efx);
 
+extern netdev_features_t ef10_offload_features __ro_after_init;
+extern netdev_features_t ef100_offload_features __ro_after_init;
+extern netdev_features_t siena_offload_features __ro_after_init;
+
 #endif
diff --git a/drivers/net/ethernet/sfc/siena.c b/drivers/net/ethernet/sfc/siena.c
index ce3060e15b54..74e3db5ccb53 100644
--- a/drivers/net/ethernet/sfc/siena.c
+++ b/drivers/net/ethernet/sfc/siena.c
@@ -1095,8 +1095,7 @@ const struct efx_nic_type siena_a0_nic_type = {
 	.option_descriptors = false,
 	.min_interrupt_mode = EFX_INT_MODE_LEGACY,
 	.timer_period_max = 1 << FRF_CZ_TC_TIMER_VAL_WIDTH,
-	.offload_features = (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
-			     NETIF_F_RXHASH | NETIF_F_NTUPLE),
+	.offload_features = &siena_offload_features,
 	.mcdi_max_ver = 1,
 	.max_rx_ip_filters = FR_BZ_RX_FILTER_TBL0_ROWS,
 	.hwtstamp_filters = (1 << HWTSTAMP_FILTER_NONE |
-- 
2.33.0


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [RFCv6 PATCH net-next 05/19] net: simplify the netdev features expression
  2022-04-19  2:21 [RFCv6 PATCH net-next 00/19] net: extend the type of netdev_features_t to bitmap Jian Shen
                   ` (3 preceding siblings ...)
  2022-04-19  2:21 ` [RFCv6 PATCH net-next 04/19] net: sfc: replace const features initialization " Jian Shen
@ 2022-04-19  2:21 ` Jian Shen
  2022-04-19  2:21 ` [RFCv6 PATCH net-next 06/19] net: adjust variables definition for netdev_features_t Jian Shen
                   ` (13 subsequent siblings)
  18 siblings, 0 replies; 30+ messages in thread
From: Jian Shen @ 2022-04-19  2:21 UTC (permalink / raw)
  To: davem, kuba, andrew, ecree.xilinx, hkallweit1, alexandr.lobakin,
	saeed, leon
  Cc: netdev, linuxarm, lipeng321

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>
---
 .../net/ethernet/hisilicon/hns3/hns3_enet.c   | 10 +--
 drivers/net/ethernet/sfc/ef10.c               |  5 +-
 drivers/net/ethernet/sfc/efx.c                |  7 +-
 drivers/net/ethernet/sfc/efx_common.c         | 14 ++--
 drivers/net/ethernet/sfc/falcon/efx.c         | 12 ++--
 include/linux/netdev_features_helper.h        | 14 ++--
 net/core/dev.c                                | 69 ++++++++++++-------
 net/ethtool/features.c                        |  4 +-
 net/ethtool/ioctl.c                           | 47 +++++++++----
 9 files changed, 120 insertions(+), 62 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
index 74ebba5b9bc3..0234d9755a9f 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
@@ -2476,7 +2476,7 @@ static netdev_features_t hns3_features_check(struct sk_buff *skb,
 	 * len of 480 bytes.
 	 */
 	if (len > HNS3_MAX_HDR_LEN)
-		features &= ~(NETIF_F_CSUM_MASK | NETIF_F_GSO_MASK);
+		features &= ~netdev_csum_gso_features_mask;
 
 	return features;
 }
@@ -3308,7 +3308,7 @@ static void hns3_set_default_feature(struct net_device *netdev)
 	if (test_bit(HNAE3_DEV_SUPPORT_HW_TX_CSUM_B, ae_dev->caps))
 		netdev->features |= NETIF_F_HW_CSUM;
 	else
-		netdev->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
+		netdev->features |= netdev_ip_csum_features;
 
 	if (test_bit(HNAE3_DEV_SUPPORT_UDP_TUNNEL_CSUM_B, ae_dev->caps))
 		netdev->features |= NETIF_F_GSO_UDP_TUNNEL_CSUM;
@@ -3323,9 +3323,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/sfc/ef10.c b/drivers/net/ethernet/sfc/ef10.c
index 63fc4c771955..01bc65ba0d31 100644
--- a/drivers/net/ethernet/sfc/ef10.c
+++ b/drivers/net/ethernet/sfc/ef10.c
@@ -1357,7 +1357,7 @@ static int efx_ef10_init_nic(struct efx_nic *efx)
 
 	/* add encapsulated checksum offload features */
 	if (efx_has_cap(efx, VXLAN_NVGRE) && !efx_ef10_is_vf(efx))
-		hw_enc_features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
+		hw_enc_features |= netdev_ip_csum_features;
 	/* add encapsulated TSO features */
 	if (efx_has_cap(efx, TX_TSO_V2_ENCAP)) {
 		netdev_features_t encap_tso_features;
@@ -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 15a896f397f2..a44378ae484a 100644
--- a/drivers/net/ethernet/sfc/efx.c
+++ b/drivers/net/ethernet/sfc/efx.c
@@ -1004,6 +1004,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;
@@ -1018,7 +1019,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))
@@ -1027,7 +1029,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 af37c990217e..815acba14394 100644
--- a/drivers/net/ethernet/sfc/efx_common.c
+++ b/drivers/net/ethernet/sfc/efx_common.c
@@ -212,10 +212,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 = 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;
@@ -224,8 +226,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.
 		 */
@@ -1367,10 +1370,9 @@ 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);
-		if (features & (NETIF_F_GSO_MASK | NETIF_F_CSUM_MASK))
+		if (features & netdev_csum_gso_features_mask)
 			if (!efx_can_encap_offloads(efx, skb))
-				features &= ~(NETIF_F_GSO_MASK |
-					      NETIF_F_CSUM_MASK);
+				features &= ~netdev_csum_gso_features_mask;
 	}
 	return features;
 }
diff --git a/drivers/net/ethernet/sfc/falcon/efx.c b/drivers/net/ethernet/sfc/falcon/efx.c
index 7d2276aa2bf6..665190413841 100644
--- a/drivers/net/ethernet/sfc/falcon/efx.c
+++ b/drivers/net/ethernet/sfc/falcon/efx.c
@@ -2188,17 +2188,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.
 		 */
@@ -2910,8 +2913,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/include/linux/netdev_features_helper.h b/include/linux/netdev_features_helper.h
index 5cc6368f65e5..b68a85d2b982 100644
--- a/include/linux/netdev_features_helper.h
+++ b/include/linux/netdev_features_helper.h
@@ -585,11 +585,14 @@ 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) {
+	netdev_features_t tmp;
+
+	tmp = f1 ^ f2;
+	if (tmp & NETIF_F_HW_CSUM) {
 		if (f1 & NETIF_F_HW_CSUM)
-			f1 |= (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM);
+			f1 |= netdev_ip_csum_features;
 		else
-			f2 |= (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM);
+			f2 |= netdev_ip_csum_features;
 	}
 
 	return f1 & f2;
@@ -598,7 +601,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/core/dev.c b/net/core/dev.c
index 85bb418e8ef1..ccf170a5f151 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -3340,10 +3340,11 @@ struct sk_buff *__skb_gso_segment(struct sk_buff *skb,
 	 * work.
 	 */
 	if (features & NETIF_F_GSO_PARTIAL) {
-		netdev_features_t partial_features = NETIF_F_GSO_ROBUST;
+		netdev_features_t partial_features;
 		struct net_device *dev = skb->dev;
 
-		partial_features |= dev->features & dev->gso_partial_features;
+		partial_features = dev->features & dev->gso_partial_features;
+		partial_features |= NETIF_F_GSO_ROBUST;
 		if (!skb_gso_ok(skb, features | partial_features))
 			features &= ~NETIF_F_GSO_PARTIAL;
 	}
@@ -3432,7 +3433,7 @@ static netdev_features_t harmonize_features(struct sk_buff *skb,
 
 	if (skb->ip_summed != CHECKSUM_NONE &&
 	    !can_checksum_protocol(features, type)) {
-		features &= ~(NETIF_F_CSUM_MASK | NETIF_F_GSO_MASK);
+		features &= ~netdev_csum_gso_features_mask;
 	}
 	if (illegal_highdma(skb->dev, skb))
 		features &= ~NETIF_F_SG;
@@ -3496,6 +3497,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);
@@ -3507,17 +3509,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 |
-						     NETIF_F_HW_VLAN_CTAG_TX |
-						     NETIF_F_HW_VLAN_STAG_TX);
+	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);
 }
@@ -3588,7 +3589,7 @@ int skb_csum_hwoffload_help(struct sk_buff *skb,
 	if (features & NETIF_F_HW_CSUM)
 		return 0;
 
-	if (features & (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM)) {
+	if (features & netdev_ip_csum_features) {
 		switch (skb->csum_offset) {
 		case offsetof(struct tcphdr, check):
 		case offsetof(struct udphdr, check):
@@ -9493,11 +9494,13 @@ 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 & (NETIF_F_IP_CSUM|NETIF_F_IPV6_CSUM))) {
+	    (features & netdev_ip_csum_features)) {
 		netdev_warn(dev, "mixed HW and IP checksum settings.\n");
-		features &= ~(NETIF_F_IP_CSUM|NETIF_F_IPV6_CSUM);
+		features &= ~netdev_ip_csum_features;
 	}
 
 	/* TSO requires that SG is present as well. */
@@ -9524,7 +9527,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. */
@@ -9572,8 +9577,8 @@ static netdev_features_t netdev_fix_features(struct net_device *dev,
 	}
 
 	if (features & NETIF_F_HW_TLS_TX) {
-		bool ip_csum = (features & (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM)) ==
-			(NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM);
+		bool ip_csum = (features & netdev_ip_csum_features) ==
+			netdev_ip_csum_features;
 		bool hw_csum = features & NETIF_F_HW_CSUM;
 
 		if (!ip_csum && !hw_csum) {
@@ -9902,8 +9907,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");
@@ -9920,7 +9925,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) {
@@ -9953,7 +9959,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.
 	 */
@@ -11040,16 +11047,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/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 243ee8a0bd18..b2d500b27a5b 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);
 
-- 
2.33.0


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [RFCv6 PATCH net-next 06/19] net: adjust variables definition for netdev_features_t
  2022-04-19  2:21 [RFCv6 PATCH net-next 00/19] net: extend the type of netdev_features_t to bitmap Jian Shen
                   ` (4 preceding siblings ...)
  2022-04-19  2:21 ` [RFCv6 PATCH net-next 05/19] net: simplify the netdev features expression Jian Shen
@ 2022-04-19  2:21 ` Jian Shen
  2022-04-19  2:21 ` [RFCv6 PATCH net-next 07/19] net: use netdev_feature_add helpers Jian Shen
                   ` (12 subsequent siblings)
  18 siblings, 0 replies; 30+ messages in thread
From: Jian Shen @ 2022-04-19  2:21 UTC (permalink / raw)
  To: davem, kuba, andrew, ecree.xilinx, hkallweit1, alexandr.lobakin,
	saeed, leon
  Cc: netdev, linuxarm, lipeng321

For the prototype of netdev_features_t will be changed to be
structure with bitmap, it's unable to be initialized when
define it. So adjust it.

Signed-off-by: Jian Shen <shenjian15@huawei.com>
---
 drivers/net/ethernet/hisilicon/hns3/hns3_enet.c |  4 +++-
 drivers/net/ethernet/sfc/ef10.c                 |  3 ++-
 drivers/net/ethernet/sfc/efx_common.c           |  3 ++-
 drivers/net/ethernet/sfc/falcon/efx.c           |  3 ++-
 net/core/dev.c                                  | 14 ++++++++++----
 net/ethtool/features.c                          |  4 +++-
 net/ethtool/ioctl.c                             | 14 ++++++++++----
 7 files changed, 32 insertions(+), 13 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
index 0234d9755a9f..34484d599e1b 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
@@ -2405,12 +2405,14 @@ static int hns3_nic_do_ioctl(struct net_device *netdev,
 static int hns3_nic_set_features(struct net_device *netdev,
 				 netdev_features_t features)
 {
-	netdev_features_t changed = netdev->features ^ features;
 	struct hns3_nic_priv *priv = netdev_priv(netdev);
 	struct hnae3_handle *h = priv->ae_handle;
+	netdev_features_t changed;
 	bool enable;
 	int ret;
 
+	changed = netdev->features ^ features;
+
 	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);
diff --git a/drivers/net/ethernet/sfc/ef10.c b/drivers/net/ethernet/sfc/ef10.c
index 01bc65ba0d31..42cc17a1d540 100644
--- a/drivers/net/ethernet/sfc/ef10.c
+++ b/drivers/net/ethernet/sfc/ef10.c
@@ -1310,7 +1310,7 @@ DECLARE_NETDEV_FEATURE_SET(ef10_tso_feature_set,
 static int efx_ef10_init_nic(struct efx_nic *efx)
 {
 	struct efx_ef10_nic_data *nic_data = efx->nic_data;
-	netdev_features_t hw_enc_features = 0;
+	netdev_features_t hw_enc_features;
 	int rc;
 
 	if (nic_data->must_check_datapath_caps) {
@@ -1355,6 +1355,7 @@ static int efx_ef10_init_nic(struct efx_nic *efx)
 		nic_data->must_restore_piobufs = false;
 	}
 
+	netdev_features_zero(&hw_enc_features);
 	/* add encapsulated checksum offload features */
 	if (efx_has_cap(efx, VXLAN_NVGRE) && !efx_ef10_is_vf(efx))
 		hw_enc_features |= netdev_ip_csum_features;
diff --git a/drivers/net/ethernet/sfc/efx_common.c b/drivers/net/ethernet/sfc/efx_common.c
index 815acba14394..4b890e68c5de 100644
--- a/drivers/net/ethernet/sfc/efx_common.c
+++ b/drivers/net/ethernet/sfc/efx_common.c
@@ -367,8 +367,8 @@ void efx_start_monitor(struct efx_nic *efx)
  */
 static void efx_start_datapath(struct efx_nic *efx)
 {
-	netdev_features_t old_features = efx->net_dev->features;
 	bool old_rx_scatter = efx->rx_scatter;
+	netdev_features_t old_features;
 	size_t rx_buf_len;
 
 	/* Calculate the rx buffer allocation parameters required to
@@ -413,6 +413,7 @@ static void efx_start_datapath(struct efx_nic *efx)
 	/* Restore previously fixed features in hw_features and remove
 	 * features which are fixed now
 	 */
+	old_features = efx->net_dev->features;
 	efx->net_dev->hw_features |= efx->net_dev->features;
 	efx->net_dev->hw_features &= ~efx->fixed_features;
 	efx->net_dev->features |= efx->fixed_features;
diff --git a/drivers/net/ethernet/sfc/falcon/efx.c b/drivers/net/ethernet/sfc/falcon/efx.c
index 665190413841..352ae87d901c 100644
--- a/drivers/net/ethernet/sfc/falcon/efx.c
+++ b/drivers/net/ethernet/sfc/falcon/efx.c
@@ -592,8 +592,8 @@ static int ef4_probe_channels(struct ef4_nic *efx)
  */
 static void ef4_start_datapath(struct ef4_nic *efx)
 {
-	netdev_features_t old_features = efx->net_dev->features;
 	bool old_rx_scatter = efx->rx_scatter;
+	netdev_features_t old_features;
 	struct ef4_tx_queue *tx_queue;
 	struct ef4_rx_queue *rx_queue;
 	struct ef4_channel *channel;
@@ -640,6 +640,7 @@ static void ef4_start_datapath(struct ef4_nic *efx)
 	/* Restore previously fixed features in hw_features and remove
 	 * features which are fixed now
 	 */
+	old_features = efx->net_dev->features;
 	efx->net_dev->hw_features |= efx->net_dev->features;
 	efx->net_dev->hw_features &= ~efx->fixed_features;
 	efx->net_dev->features |= efx->fixed_features;
diff --git a/net/core/dev.c b/net/core/dev.c
index ccf170a5f151..48b0a49ebb39 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -3496,9 +3496,11 @@ static netdev_features_t gso_features_check(const struct sk_buff *skb,
 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 features;
 	netdev_features_t tmp;
 
+	features = dev->features;
+
 	if (skb_is_gso(skb))
 		features = gso_features_check(skb, dev, features);
 
@@ -9450,10 +9452,11 @@ static void net_set_todo(struct net_device *dev)
 static netdev_features_t netdev_sync_upper_features(struct net_device *lower,
 	struct net_device *upper, netdev_features_t features)
 {
-	netdev_features_t upper_disables = NETIF_F_UPPER_DISABLES;
+	netdev_features_t upper_disables;
 	netdev_features_t feature;
 	int feature_bit;
 
+	upper_disables = NETIF_F_UPPER_DISABLES;
 	for_each_netdev_feature(upper_disables, feature_bit) {
 		feature = __NETIF_F_BIT(feature_bit);
 		if (!(upper->wanted_features & feature)
@@ -9470,10 +9473,11 @@ static netdev_features_t netdev_sync_upper_features(struct net_device *lower,
 static void netdev_sync_lower_features(struct net_device *upper,
 	struct net_device *lower, netdev_features_t features)
 {
-	netdev_features_t upper_disables = NETIF_F_UPPER_DISABLES;
+	netdev_features_t upper_disables;
 	netdev_features_t feature;
 	int feature_bit;
 
+	upper_disables = NETIF_F_UPPER_DISABLES;
 	for_each_netdev_feature(upper_disables, feature_bit) {
 		feature = __NETIF_F_BIT(feature_bit);
 		if (!(features & feature) && (lower->features & feature)) {
@@ -9645,7 +9649,9 @@ int __netdev_update_features(struct net_device *dev)
 		netdev_sync_lower_features(dev, lower, features);
 
 	if (!err) {
-		netdev_features_t diff = features ^ dev->features;
+		netdev_features_t diff;
+
+		diff = features ^ dev->features;
 
 		if (diff & NETIF_F_RX_UDP_TUNNEL_PORT) {
 			/* udp_tunnel_{get,drop}_rx_info both need
diff --git a/net/ethtool/features.c b/net/ethtool/features.c
index 67a837d44491..2c64183012c1 100644
--- a/net/ethtool/features.c
+++ b/net/ethtool/features.c
@@ -1,5 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 
+#include <linux/netdev_features_helper.h>
 #include "netlink.h"
 #include "common.h"
 #include "bitset.h"
@@ -144,9 +145,10 @@ static netdev_features_t ethnl_bitmap_to_features(unsigned long *src)
 {
 	const unsigned int nft_bits = sizeof(netdev_features_t) * BITS_PER_BYTE;
 	const unsigned int words = BITS_TO_LONGS(NETDEV_FEATURE_COUNT);
-	netdev_features_t ret = 0;
+	netdev_features_t ret;
 	unsigned int i;
 
+	netdev_features_zero(&ret);
 	for (i = 0; i < words; i++)
 		ret |= (netdev_features_t)(src[i]) << (i * BITS_PER_LONG);
 	ret &= ~(netdev_features_t)0 >> (nft_bits - NETDEV_FEATURE_COUNT);
diff --git a/net/ethtool/ioctl.c b/net/ethtool/ioctl.c
index b2d500b27a5b..28164e990201 100644
--- a/net/ethtool/ioctl.c
+++ b/net/ethtool/ioctl.c
@@ -125,7 +125,8 @@ 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 wanted;
+	netdev_features_t valid;
 	netdev_features_t tmp;
 	int i, ret = 0;
 
@@ -139,6 +140,8 @@ static int ethtool_set_features(struct net_device *dev, void __user *useraddr)
 	if (copy_from_user(features, useraddr, sizeof(features)))
 		return -EFAULT;
 
+	netdev_features_zero(&wanted);
+	netdev_features_zero(&valid);
 	for (i = 0; i < ETHTOOL_DEV_FEATURE_WORDS; ++i) {
 		valid |= (netdev_features_t)features[i].valid << (32 * i);
 		wanted |= (netdev_features_t)features[i].requested << (32 * i);
@@ -267,12 +270,13 @@ static netdev_features_t ethtool_get_feature_mask(u32 eth_cmd)
 static int ethtool_get_one_feature(struct net_device *dev,
 	char __user *useraddr, u32 ethcmd)
 {
-	netdev_features_t mask = ethtool_get_feature_mask(ethcmd);
+	netdev_features_t mask;
 	struct ethtool_value edata = {
 		.cmd = ethcmd,
-		.data = !!(dev->features & mask),
 	};
 
+	mask = ethtool_get_feature_mask(ethcmd);
+	edata.data = !!(dev->features & mask);
 	if (copy_to_user(useraddr, &edata, sizeof(edata)))
 		return -EFAULT;
 	return 0;
@@ -332,13 +336,15 @@ static u32 __ethtool_get_flags(struct net_device *dev)
 
 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 features;
+	netdev_features_t changed;
 	netdev_features_t tmp;
 
 	if (data & ~ETH_ALL_FLAGS)
 		return -EINVAL;
 
+	netdev_features_zero(&features);
 	if (data & ETH_FLAG_LRO)
 		features |= NETIF_F_LRO;
 	if (data & ETH_FLAG_RXVLAN)
-- 
2.33.0


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [RFCv6 PATCH net-next 07/19] net: use netdev_feature_add helpers
  2022-04-19  2:21 [RFCv6 PATCH net-next 00/19] net: extend the type of netdev_features_t to bitmap Jian Shen
                   ` (5 preceding siblings ...)
  2022-04-19  2:21 ` [RFCv6 PATCH net-next 06/19] net: adjust variables definition for netdev_features_t Jian Shen
@ 2022-04-19  2:21 ` Jian Shen
  2022-04-19  2:21 ` [RFCv6 PATCH net-next 08/19] net: use netdev_features_or helpers Jian Shen
                   ` (11 subsequent siblings)
  18 siblings, 0 replies; 30+ messages in thread
From: Jian Shen @ 2022-04-19  2:21 UTC (permalink / raw)
  To: davem, kuba, andrew, ecree.xilinx, hkallweit1, alexandr.lobakin,
	saeed, leon
  Cc: netdev, linuxarm, lipeng321

Replace the '|' and '|=' operations of single feature bit by
netdev_features_add helpers.

Signed-off-by: Jian Shen <shenjian15@huawei.com>
---
 .../net/ethernet/hisilicon/hns3/hns3_enet.c   | 17 ++++++------
 drivers/net/ethernet/sfc/ef10.c               |  4 +--
 drivers/net/ethernet/sfc/ef100_nic.c          |  3 ++-
 drivers/net/ethernet/sfc/ef10_sriov.c         |  3 ++-
 drivers/net/ethernet/sfc/efx.c                |  4 +--
 drivers/net/ethernet/sfc/falcon/efx.c         |  6 ++---
 net/core/dev.c                                | 26 +++++++++----------
 net/ethtool/ioctl.c                           | 24 ++++++++---------
 8 files changed, 45 insertions(+), 42 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
index 34484d599e1b..a368fe002295 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
@@ -3291,32 +3291,33 @@ static void hns3_set_default_feature(struct net_device *netdev)
 
 	netdev->priv_flags |= IFF_UNICAST_FLT;
 
-	netdev->gso_partial_features |= NETIF_F_GSO_GRE_CSUM;
+	netdev_gso_partial_feature_add(netdev, NETIF_F_GSO_GRE_CSUM_BIT);
 
 	netdev_features_zero(&features);
 	netdev_features_set_array(&hns3_default_feature_set, &features);
 	netdev->features |= features;
 
 	if (ae_dev->dev_version >= HNAE3_DEVICE_VERSION_V2) {
-		netdev->features |= NETIF_F_GRO_HW;
+		netdev_active_feature_add(netdev, NETIF_F_GRO_HW_BIT);
 
 		if (!(h->flags & HNAE3_SUPPORT_VF))
-			netdev->features |= NETIF_F_NTUPLE;
+			netdev_active_feature_add(netdev, NETIF_F_NTUPLE_BIT);
 	}
 
 	if (test_bit(HNAE3_DEV_SUPPORT_UDP_GSO_B, ae_dev->caps))
-		netdev->features |= NETIF_F_GSO_UDP_L4;
+		netdev_active_feature_add(netdev, NETIF_F_GSO_UDP_L4_BIT);
 
 	if (test_bit(HNAE3_DEV_SUPPORT_HW_TX_CSUM_B, ae_dev->caps))
-		netdev->features |= NETIF_F_HW_CSUM;
+		netdev_active_feature_add(netdev, NETIF_F_HW_CSUM_BIT);
 	else
 		netdev->features |= netdev_ip_csum_features;
 
 	if (test_bit(HNAE3_DEV_SUPPORT_UDP_TUNNEL_CSUM_B, ae_dev->caps))
-		netdev->features |= NETIF_F_GSO_UDP_TUNNEL_CSUM;
+		netdev_active_feature_add(netdev,
+					  NETIF_F_GSO_UDP_TUNNEL_CSUM_BIT);
 
 	if (test_bit(HNAE3_DEV_SUPPORT_FD_FORWARD_TC_B, ae_dev->caps))
-		netdev->features |= NETIF_F_HW_TC;
+		netdev_active_feature_add(netdev, NETIF_F_HW_TC_BIT);
 
 	netdev->hw_features |= netdev->features;
 	if (!test_bit(HNAE3_DEV_SUPPORT_VLAN_FLTR_MDF_B, ae_dev->caps))
@@ -3329,7 +3330,7 @@ static void hns3_set_default_feature(struct net_device *netdev)
 	netdev->vlan_features |= features;
 
 	netdev->hw_enc_features |= netdev->vlan_features;
-	netdev->hw_enc_features |= NETIF_F_TSO_MANGLEID;
+	netdev_hw_enc_feature_add(netdev, NETIF_F_TSO_MANGLEID_BIT);
 }
 
 static int hns3_alloc_buffer(struct hns3_enet_ring *ring,
diff --git a/drivers/net/ethernet/sfc/ef10.c b/drivers/net/ethernet/sfc/ef10.c
index 42cc17a1d540..9c99a820bad1 100644
--- a/drivers/net/ethernet/sfc/ef10.c
+++ b/drivers/net/ethernet/sfc/ef10.c
@@ -627,7 +627,7 @@ static int efx_ef10_probe(struct efx_nic *efx)
 
 	if (nic_data->datapath_caps &
 	    (1 << MC_CMD_GET_CAPABILITIES_OUT_RX_INCLUDE_FCS_LBN))
-		efx->net_dev->hw_features |= NETIF_F_RXFCS;
+		netdev_hw_feature_add(efx->net_dev, NETIF_F_RXFCS_BIT);
 
 	rc = efx_mcdi_port_get_number(efx);
 	if (rc < 0)
@@ -1368,7 +1368,7 @@ static int efx_ef10_init_nic(struct efx_nic *efx)
 					  &encap_tso_features);
 
 		hw_enc_features |= encap_tso_features;
-		hw_enc_features |= NETIF_F_TSO;
+		netdev_feature_add(NETIF_F_TSO_BIT, &hw_enc_features);
 		efx->net_dev->features |= encap_tso_features;
 	}
 	efx->net_dev->hw_enc_features = hw_enc_features;
diff --git a/drivers/net/ethernet/sfc/ef100_nic.c b/drivers/net/ethernet/sfc/ef100_nic.c
index 679530f20bd6..b72be20af1b2 100644
--- a/drivers/net/ethernet/sfc/ef100_nic.c
+++ b/drivers/net/ethernet/sfc/ef100_nic.c
@@ -204,7 +204,8 @@ static int efx_ef100_init_datapath_caps(struct efx_nic *efx)
 		/* EF100 HW can only offload outer checksums if they are UDP,
 		 * so for GRE_CSUM we have to use GSO_PARTIAL.
 		 */
-		net_dev->gso_partial_features |= NETIF_F_GSO_GRE_CSUM;
+		netdev_gso_partial_feature_add(net_dev,
+					       NETIF_F_GSO_GRE_CSUM_BIT);
 	}
 	efx->num_mac_stats = MCDI_WORD(outbuf,
 				       GET_CAPABILITIES_V4_OUT_MAC_STATS_NUM_STATS);
diff --git a/drivers/net/ethernet/sfc/ef10_sriov.c b/drivers/net/ethernet/sfc/ef10_sriov.c
index 7f5aa4a8c451..857e7520461d 100644
--- a/drivers/net/ethernet/sfc/ef10_sriov.c
+++ b/drivers/net/ethernet/sfc/ef10_sriov.c
@@ -243,7 +243,8 @@ static int efx_ef10_vadaptor_alloc_set_features(struct efx_nic *efx)
 
 	if (port_flags &
 	    (1 << MC_CMD_VPORT_ALLOC_IN_FLAG_VLAN_RESTRICT_LBN))
-		efx->fixed_features |= NETIF_F_HW_VLAN_CTAG_FILTER;
+		netdev_feature_add(NETIF_F_HW_VLAN_CTAG_FILTER_BIT,
+				   &efx->fixed_features);
 	else
 		efx->fixed_features &= ~NETIF_F_HW_VLAN_CTAG_FILTER;
 
diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c
index a44378ae484a..1a7fc9295ba0 100644
--- a/drivers/net/ethernet/sfc/efx.c
+++ b/drivers/net/ethernet/sfc/efx.c
@@ -1021,7 +1021,7 @@ static int efx_pci_probe_post_io(struct efx_nic *efx)
 	netdev_active_features_set_array(net_dev, &efx_active_feature_set);
 	if ((*efx->type->offload_features & NETIF_F_IPV6_CSUM) ||
 	    (*efx->type->offload_features & NETIF_F_HW_CSUM))
-		net_dev->features |= NETIF_F_TSO6;
+		netdev_active_feature_add(net_dev, NETIF_F_TSO6_BIT);
 	/* Check whether device supports TSO */
 	if (!efx->type->tso_versions || !efx->type->tso_versions(efx))
 		net_dev->features &= ~NETIF_F_ALL_TSO;
@@ -1073,7 +1073,7 @@ static int efx_pci_probe(struct pci_dev *pci_dev,
 		return -ENOMEM;
 	efx = netdev_priv(net_dev);
 	efx->type = (const struct efx_nic_type *) entry->driver_data;
-	efx->fixed_features |= NETIF_F_HIGHDMA;
+	netdev_feature_add(NETIF_F_HIGHDMA_BIT, &efx->fixed_features);
 
 	pci_set_drvdata(pci_dev, efx);
 	SET_NETDEV_DEV(net_dev, &pci_dev->dev);
diff --git a/drivers/net/ethernet/sfc/falcon/efx.c b/drivers/net/ethernet/sfc/falcon/efx.c
index 352ae87d901c..5d044027e164 100644
--- a/drivers/net/ethernet/sfc/falcon/efx.c
+++ b/drivers/net/ethernet/sfc/falcon/efx.c
@@ -2892,7 +2892,7 @@ static int ef4_pci_probe(struct pci_dev *pci_dev,
 		return -ENOMEM;
 	efx = netdev_priv(net_dev);
 	efx->type = (const struct ef4_nic_type *) entry->driver_data;
-	efx->fixed_features |= NETIF_F_HIGHDMA;
+	netdev_feature_add(NETIF_F_HIGHDMA_BIT, &efx->fixed_features);
 
 	pci_set_drvdata(pci_dev, efx);
 	SET_NETDEV_DEV(net_dev, &pci_dev->dev);
@@ -2915,8 +2915,8 @@ static int ef4_pci_probe(struct pci_dev *pci_dev,
 		goto fail3;
 
 	net_dev->features |= *efx->type->offload_features;
-	net_dev->features |= NETIF_F_SG;
-	net_dev->features |= NETIF_F_RXCSUM;
+	netdev_active_feature_add(net_dev, NETIF_F_SG_BIT);
+	netdev_active_feature_add(net_dev, NETIF_F_RXCSUM_BIT);
 	/* 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/net/core/dev.c b/net/core/dev.c
index 48b0a49ebb39..921f10018fbc 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -3344,7 +3344,7 @@ struct sk_buff *__skb_gso_segment(struct sk_buff *skb,
 		struct net_device *dev = skb->dev;
 
 		partial_features = dev->features & dev->gso_partial_features;
-		partial_features |= NETIF_F_GSO_ROBUST;
+		netdev_feature_add(NETIF_F_GSO_ROBUST_BIT, &partial_features);
 		if (!skb_gso_ok(skb, features | partial_features))
 			features &= ~NETIF_F_GSO_PARTIAL;
 	}
@@ -9936,14 +9936,14 @@ int register_netdevice(struct net_device *dev)
 	dev->features |= NETIF_F_SOFT_FEATURES;
 
 	if (dev->udp_tunnel_nic_info) {
-		dev->features |= NETIF_F_RX_UDP_TUNNEL_PORT;
-		dev->hw_features |= NETIF_F_RX_UDP_TUNNEL_PORT;
+		netdev_active_feature_add(dev, NETIF_F_RX_UDP_TUNNEL_PORT_BIT);
+		netdev_hw_feature_add(dev, NETIF_F_RX_UDP_TUNNEL_PORT_BIT);
 	}
 
 	dev->wanted_features = dev->features & dev->hw_features;
 
 	if (!(dev->flags & IFF_LOOPBACK))
-		dev->hw_features |= NETIF_F_NOCACHE_COPY;
+		netdev_hw_feature_add(dev, NETIF_F_NOCACHE_COPY_BIT);
 
 	/* If IPv4 TCP segmentation offload is supported we should also
 	 * allow the device to enable segmenting the frame with the option
@@ -9951,26 +9951,26 @@ int register_netdevice(struct net_device *dev)
 	 * feature itself but allows the user to enable it later.
 	 */
 	if (dev->hw_features & NETIF_F_TSO)
-		dev->hw_features |= NETIF_F_TSO_MANGLEID;
+		netdev_hw_feature_add(dev, NETIF_F_TSO_MANGLEID_BIT);
 	if (dev->vlan_features & NETIF_F_TSO)
-		dev->vlan_features |= NETIF_F_TSO_MANGLEID;
+		netdev_vlan_feature_add(dev, NETIF_F_TSO_MANGLEID_BIT);
 	if (dev->mpls_features & NETIF_F_TSO)
-		dev->mpls_features |= NETIF_F_TSO_MANGLEID;
+		netdev_mpls_feature_add(dev, NETIF_F_TSO_MANGLEID_BIT);
 	if (dev->hw_enc_features & NETIF_F_TSO)
-		dev->hw_enc_features |= NETIF_F_TSO_MANGLEID;
+		netdev_hw_enc_feature_add(dev, NETIF_F_TSO_MANGLEID_BIT);
 
 	/* Make NETIF_F_HIGHDMA inheritable to VLAN devices.
 	 */
-	dev->vlan_features |= NETIF_F_HIGHDMA;
+	netdev_vlan_feature_add(dev, NETIF_F_HIGHDMA_BIT);
 
 	/* Make NETIF_F_SG inheritable to tunnel devices.
 	 */
-	dev->hw_enc_features |= NETIF_F_SG;
-	dev->hw_enc_features |= NETIF_F_GSO_PARTIAL;
+	netdev_hw_enc_feature_add(dev, NETIF_F_SG_BIT);
+	netdev_hw_enc_feature_add(dev, NETIF_F_GSO_PARTIAL_BIT);
 
 	/* Make NETIF_F_SG inheritable to MPLS.
 	 */
-	dev->mpls_features |= NETIF_F_SG;
+	netdev_mpls_feature_add(dev, NETIF_F_SG_BIT);
 
 	ret = call_netdevice_notifiers(NETDEV_POST_INIT, dev);
 	ret = notifier_to_errno(ret);
@@ -11057,7 +11057,7 @@ netdev_features_t netdev_increment_features(netdev_features_t all,
 
 	if (mask & NETIF_F_HW_CSUM)
 		mask |= NETIF_F_CSUM_MASK;
-	mask |= NETIF_F_VLAN_CHALLENGED;
+	netdev_feature_add(NETIF_F_VLAN_CHALLENGED_BIT, &mask);
 
 	tmp = NETIF_F_ONE_FOR_ALL | NETIF_F_CSUM_MASK;
 	tmp &= one;
diff --git a/net/ethtool/ioctl.c b/net/ethtool/ioctl.c
index 28164e990201..b258379006f1 100644
--- a/net/ethtool/ioctl.c
+++ b/net/ethtool/ioctl.c
@@ -239,28 +239,28 @@ static netdev_features_t ethtool_get_feature_mask(u32 eth_cmd)
 	case ETHTOOL_GTXCSUM:
 	case ETHTOOL_STXCSUM:
 		tmp = NETIF_F_CSUM_MASK;
-		tmp |= NETIF_F_FCOE_CRC;
-		tmp |= NETIF_F_SCTP_CRC;
+		netdev_feature_add(NETIF_F_FCOE_CRC_BIT, &tmp);
+		netdev_feature_add(NETIF_F_SCTP_CRC_BIT, &tmp);
 		return tmp;
 	case ETHTOOL_GRXCSUM:
 	case ETHTOOL_SRXCSUM:
-		tmp |= NETIF_F_RXCSUM;
+		netdev_feature_add(NETIF_F_RXCSUM_BIT, &tmp);
 		return tmp;
 	case ETHTOOL_GSG:
 	case ETHTOOL_SSG:
-		tmp |= NETIF_F_SG;
-		tmp |= NETIF_F_FRAGLIST;
+		netdev_feature_add(NETIF_F_SG_BIT, &tmp);
+		netdev_feature_add(NETIF_F_FRAGLIST_BIT, &tmp);
 		return tmp;
 	case ETHTOOL_GTSO:
 	case ETHTOOL_STSO:
 		return NETIF_F_ALL_TSO;
 	case ETHTOOL_GGSO:
 	case ETHTOOL_SGSO:
-		tmp |= NETIF_F_GSO;
+		netdev_feature_add(NETIF_F_GSO_BIT, &tmp);
 		return tmp;
 	case ETHTOOL_GGRO:
 	case ETHTOOL_SGRO:
-		tmp |= NETIF_F_GRO;
+		netdev_feature_add(NETIF_F_GRO_BIT, &tmp);
 		return tmp;
 	default:
 		BUG();
@@ -346,15 +346,15 @@ static int __ethtool_set_flags(struct net_device *dev, u32 data)
 
 	netdev_features_zero(&features);
 	if (data & ETH_FLAG_LRO)
-		features |= NETIF_F_LRO;
+		netdev_feature_add(NETIF_F_LRO_BIT, &features);
 	if (data & ETH_FLAG_RXVLAN)
-		features |= NETIF_F_HW_VLAN_CTAG_RX;
+		netdev_feature_add(NETIF_F_HW_VLAN_CTAG_RX_BIT, &features);
 	if (data & ETH_FLAG_TXVLAN)
-		features |= NETIF_F_HW_VLAN_CTAG_TX;
+		netdev_feature_add(NETIF_F_HW_VLAN_CTAG_TX_BIT, &features);
 	if (data & ETH_FLAG_NTUPLE)
-		features |= NETIF_F_NTUPLE;
+		netdev_feature_add(NETIF_F_NTUPLE_BIT, &features);
 	if (data & ETH_FLAG_RXHASH)
-		features |= NETIF_F_RXHASH;
+		netdev_feature_add(NETIF_F_RXHASH_BIT, &features);
 
 	netdev_features_zero(&eth_all_features);
 	netdev_features_set_array(&ethtool_all_feature_set, &eth_all_features);
-- 
2.33.0


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [RFCv6 PATCH net-next 08/19] net: use netdev_features_or helpers
  2022-04-19  2:21 [RFCv6 PATCH net-next 00/19] net: extend the type of netdev_features_t to bitmap Jian Shen
                   ` (6 preceding siblings ...)
  2022-04-19  2:21 ` [RFCv6 PATCH net-next 07/19] net: use netdev_feature_add helpers Jian Shen
@ 2022-04-19  2:21 ` Jian Shen
  2022-04-19  2:21 ` [RFCv6 PATCH net-next 09/19] net: use netdev_features_xor helpers Jian Shen
                   ` (10 subsequent siblings)
  18 siblings, 0 replies; 30+ messages in thread
From: Jian Shen @ 2022-04-19  2:21 UTC (permalink / raw)
  To: davem, kuba, andrew, ecree.xilinx, hkallweit1, alexandr.lobakin,
	saeed, leon
  Cc: netdev, linuxarm, lipeng321

Replace the '|' and '|=' operations of features by
netdev_features_or helpers.

Signed-off-by: Jian Shen <shenjian15@huawei.com>
---
 .../net/ethernet/hisilicon/hns3/hns3_enet.c    | 10 +++++-----
 drivers/net/ethernet/sfc/ef10.c                |  6 +++---
 drivers/net/ethernet/sfc/ef100_nic.c           | 14 +++++++-------
 drivers/net/ethernet/sfc/efx.c                 |  8 ++++----
 drivers/net/ethernet/sfc/efx_common.c          |  4 ++--
 drivers/net/ethernet/sfc/falcon/efx.c          |  8 ++++----
 drivers/net/ethernet/sfc/falcon/net_driver.h   |  2 +-
 drivers/net/ethernet/sfc/net_driver.h          |  2 +-
 include/linux/netdev_features_helper.h         |  6 +++---
 net/core/dev.c                                 | 18 +++++++++---------
 net/ethtool/features.c                         |  5 +++--
 net/ethtool/ioctl.c                            | 12 +++++++-----
 12 files changed, 49 insertions(+), 46 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
index a368fe002295..e43b3e8c4f84 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
@@ -3295,7 +3295,7 @@ static void hns3_set_default_feature(struct net_device *netdev)
 
 	netdev_features_zero(&features);
 	netdev_features_set_array(&hns3_default_feature_set, &features);
-	netdev->features |= features;
+	netdev_active_features_set(netdev, features);
 
 	if (ae_dev->dev_version >= HNAE3_DEVICE_VERSION_V2) {
 		netdev_active_feature_add(netdev, NETIF_F_GRO_HW_BIT);
@@ -3310,7 +3310,7 @@ static void hns3_set_default_feature(struct net_device *netdev)
 	if (test_bit(HNAE3_DEV_SUPPORT_HW_TX_CSUM_B, ae_dev->caps))
 		netdev_active_feature_add(netdev, NETIF_F_HW_CSUM_BIT);
 	else
-		netdev->features |= netdev_ip_csum_features;
+		netdev_active_features_set(netdev, netdev_ip_csum_features);
 
 	if (test_bit(HNAE3_DEV_SUPPORT_UDP_TUNNEL_CSUM_B, ae_dev->caps))
 		netdev_active_feature_add(netdev,
@@ -3319,7 +3319,7 @@ static void hns3_set_default_feature(struct net_device *netdev)
 	if (test_bit(HNAE3_DEV_SUPPORT_FD_FORWARD_TC_B, ae_dev->caps))
 		netdev_active_feature_add(netdev, NETIF_F_HW_TC_BIT);
 
-	netdev->hw_features |= netdev->features;
+	netdev_hw_features_set(netdev, netdev->features);
 	if (!test_bit(HNAE3_DEV_SUPPORT_VLAN_FLTR_MDF_B, ae_dev->caps))
 		netdev->hw_features &= ~NETIF_F_HW_VLAN_CTAG_FILTER;
 
@@ -3327,9 +3327,9 @@ static void hns3_set_default_feature(struct net_device *netdev)
 	netdev_features_set_array(&hns3_vlan_off_feature_set,
 				  &vlan_off_features);
 	features = netdev->features & ~vlan_off_features;
-	netdev->vlan_features |= features;
+	netdev_vlan_features_set(netdev, features);
 
-	netdev->hw_enc_features |= netdev->vlan_features;
+	netdev_hw_enc_features_set(netdev, netdev->vlan_features);
 	netdev_hw_enc_feature_add(netdev, NETIF_F_TSO_MANGLEID_BIT);
 }
 
diff --git a/drivers/net/ethernet/sfc/ef10.c b/drivers/net/ethernet/sfc/ef10.c
index 9c99a820bad1..0674565d9ed1 100644
--- a/drivers/net/ethernet/sfc/ef10.c
+++ b/drivers/net/ethernet/sfc/ef10.c
@@ -1358,7 +1358,7 @@ static int efx_ef10_init_nic(struct efx_nic *efx)
 	netdev_features_zero(&hw_enc_features);
 	/* add encapsulated checksum offload features */
 	if (efx_has_cap(efx, VXLAN_NVGRE) && !efx_ef10_is_vf(efx))
-		hw_enc_features |= netdev_ip_csum_features;
+		netdev_features_set(&hw_enc_features, netdev_ip_csum_features);
 	/* add encapsulated TSO features */
 	if (efx_has_cap(efx, TX_TSO_V2_ENCAP)) {
 		netdev_features_t encap_tso_features;
@@ -1367,9 +1367,9 @@ 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;
+		netdev_features_set(&hw_enc_features, encap_tso_features);
 		netdev_feature_add(NETIF_F_TSO_BIT, &hw_enc_features);
-		efx->net_dev->features |= encap_tso_features;
+		netdev_active_features_set(efx->net_dev, encap_tso_features);
 	}
 	efx->net_dev->hw_enc_features = hw_enc_features;
 
diff --git a/drivers/net/ethernet/sfc/ef100_nic.c b/drivers/net/ethernet/sfc/ef100_nic.c
index b72be20af1b2..e32012cae55a 100644
--- a/drivers/net/ethernet/sfc/ef100_nic.c
+++ b/drivers/net/ethernet/sfc/ef100_nic.c
@@ -198,9 +198,9 @@ static int efx_ef100_init_datapath_caps(struct efx_nic *efx)
 
 		netdev_features_zero(&tso);
 		netdev_features_set_array(&ef100_tso_feature_set, &tso);
-		net_dev->features |= tso;
-		net_dev->hw_features |= tso;
-		net_dev->hw_enc_features |= tso;
+		netdev_active_features_set(net_dev, tso);
+		netdev_hw_features_set(net_dev, tso);
+		netdev_hw_enc_features_set(net_dev, tso);
 		/* EF100 HW can only offload outer checksums if they are UDP,
 		 * so for GRE_CSUM we have to use GSO_PARTIAL.
 		 */
@@ -1133,10 +1133,10 @@ static int ef100_probe_main(struct efx_nic *efx)
 		return -ENOMEM;
 	efx->nic_data = nic_data;
 	nic_data->efx = efx;
-	net_dev->features |= *efx->type->offload_features;
-	net_dev->hw_features |= *efx->type->offload_features;
-	net_dev->hw_enc_features |= *efx->type->offload_features;
-	net_dev->vlan_features |= NETIF_F_ALL_TSO;
+	netdev_active_features_set(net_dev, *efx->type->offload_features);
+	netdev_hw_features_set(net_dev, *efx->type->offload_features);
+	netdev_hw_enc_features_set(net_dev, *efx->type->offload_features);
+	netdev_vlan_features_set(net_dev, NETIF_F_ALL_TSO);
 	netdev_vlan_features_set_array(net_dev, &ef100_vlan_feature_set);
 
 	/* Populate design-parameter defaults */
diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c
index 1a7fc9295ba0..e346ad52c9a2 100644
--- a/drivers/net/ethernet/sfc/efx.c
+++ b/drivers/net/ethernet/sfc/efx.c
@@ -1017,7 +1017,7 @@ 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(net_dev, *efx->type->offload_features);
 	netdev_active_features_set_array(net_dev, &efx_active_feature_set);
 	if ((*efx->type->offload_features & NETIF_F_IPV6_CSUM) ||
 	    (*efx->type->offload_features & NETIF_F_HW_CSUM))
@@ -1026,11 +1026,11 @@ static int efx_pci_probe_post_io(struct efx_nic *efx)
 	if (!efx->type->tso_versions || !efx->type->tso_versions(efx))
 		net_dev->features &= ~NETIF_F_ALL_TSO;
 	/* Mask for features that also apply to VLAN devices */
-	net_dev->vlan_features |= NETIF_F_ALL_TSO;
+	netdev_vlan_features_set(net_dev, NETIF_F_ALL_TSO);
 	netdev_vlan_features_set_array(net_dev, &efx_vlan_feature_set);
 
 	tmp = net_dev->features & ~efx->fixed_features;
-	net_dev->hw_features |= tmp;
+	netdev_hw_features_set(net_dev, tmp);
 
 	/* Disable receiving frames with bad FCS, by default. */
 	net_dev->features &= ~NETIF_F_RXALL;
@@ -1040,7 +1040,7 @@ static int efx_pci_probe_post_io(struct efx_nic *efx)
 	 * receive VLAN tagged packets due to vPort restrictions).
 	 */
 	net_dev->features &= ~NETIF_F_HW_VLAN_CTAG_FILTER;
-	net_dev->features |= efx->fixed_features;
+	netdev_active_features_set(net_dev, efx->fixed_features);
 
 	rc = efx_register_netdev(efx);
 	if (!rc)
diff --git a/drivers/net/ethernet/sfc/efx_common.c b/drivers/net/ethernet/sfc/efx_common.c
index 4b890e68c5de..f5536eb00dfc 100644
--- a/drivers/net/ethernet/sfc/efx_common.c
+++ b/drivers/net/ethernet/sfc/efx_common.c
@@ -414,9 +414,9 @@ static void efx_start_datapath(struct efx_nic *efx)
 	 * features which are fixed now
 	 */
 	old_features = efx->net_dev->features;
-	efx->net_dev->hw_features |= efx->net_dev->features;
+	netdev_hw_features_set(efx->net_dev, efx->net_dev->features);
 	efx->net_dev->hw_features &= ~efx->fixed_features;
-	efx->net_dev->features |= efx->fixed_features;
+	netdev_active_features_set(efx->net_dev, efx->fixed_features);
 	if (efx->net_dev->features != old_features)
 		netdev_features_change(efx->net_dev);
 
diff --git a/drivers/net/ethernet/sfc/falcon/efx.c b/drivers/net/ethernet/sfc/falcon/efx.c
index 5d044027e164..d246c5b805a1 100644
--- a/drivers/net/ethernet/sfc/falcon/efx.c
+++ b/drivers/net/ethernet/sfc/falcon/efx.c
@@ -641,9 +641,9 @@ static void ef4_start_datapath(struct ef4_nic *efx)
 	 * features which are fixed now
 	 */
 	old_features = efx->net_dev->features;
-	efx->net_dev->hw_features |= efx->net_dev->features;
+	netdev_hw_features_set(efx->net_dev, efx->net_dev->features);
 	efx->net_dev->hw_features &= ~efx->fixed_features;
-	efx->net_dev->features |= efx->fixed_features;
+	netdev_active_features_set(efx->net_dev, efx->fixed_features);
 	if (efx->net_dev->features != old_features)
 		netdev_features_change(efx->net_dev);
 
@@ -2914,7 +2914,7 @@ static int ef4_pci_probe(struct pci_dev *pci_dev,
 	if (rc)
 		goto fail3;
 
-	net_dev->features |= *efx->type->offload_features;
+	netdev_active_features_set(net_dev, *efx->type->offload_features);
 	netdev_active_feature_add(net_dev, NETIF_F_SG_BIT);
 	netdev_active_feature_add(net_dev, NETIF_F_RXCSUM_BIT);
 	/* Mask for features that also apply to VLAN devices */
@@ -2926,7 +2926,7 @@ static int ef4_pci_probe(struct pci_dev *pci_dev,
 	 * receive VLAN tagged packets due to vPort restrictions).
 	 */
 	net_dev->features &= ~NETIF_F_HW_VLAN_CTAG_FILTER;
-	net_dev->features |= efx->fixed_features;
+	netdev_active_features_set(net_dev, efx->fixed_features);
 
 	rc = ef4_register_netdev(efx);
 	if (rc)
diff --git a/drivers/net/ethernet/sfc/falcon/net_driver.h b/drivers/net/ethernet/sfc/falcon/net_driver.h
index 26aff929c6d2..5365e2d8a975 100644
--- a/drivers/net/ethernet/sfc/falcon/net_driver.h
+++ b/drivers/net/ethernet/sfc/falcon/net_driver.h
@@ -1303,7 +1303,7 @@ static inline netdev_features_t ef4_supported_features(const struct ef4_nic *efx
 {
 	const struct net_device *net_dev = efx->net_dev;
 
-	return net_dev->features | net_dev->hw_features;
+	return netdev_active_features_or(net_dev, net_dev->hw_features);
 }
 
 /* Get the current TX queue insert index. */
diff --git a/drivers/net/ethernet/sfc/net_driver.h b/drivers/net/ethernet/sfc/net_driver.h
index 6b52f2924bf7..bcdcec3d61e1 100644
--- a/drivers/net/ethernet/sfc/net_driver.h
+++ b/drivers/net/ethernet/sfc/net_driver.h
@@ -1688,7 +1688,7 @@ static inline netdev_features_t efx_supported_features(const struct efx_nic *efx
 {
 	const struct net_device *net_dev = efx->net_dev;
 
-	return net_dev->features | net_dev->hw_features;
+	return netdev_active_features_or(net_dev, net_dev->hw_features);
 }
 
 /* Get the current TX queue insert index. */
diff --git a/include/linux/netdev_features_helper.h b/include/linux/netdev_features_helper.h
index b68a85d2b982..0c4363588582 100644
--- a/include/linux/netdev_features_helper.h
+++ b/include/linux/netdev_features_helper.h
@@ -590,9 +590,9 @@ static inline netdev_features_t netdev_intersect_features(netdev_features_t f1,
 	tmp = f1 ^ f2;
 	if (tmp & NETIF_F_HW_CSUM) {
 		if (f1 & NETIF_F_HW_CSUM)
-			f1 |= netdev_ip_csum_features;
+			netdev_features_set(&f1, netdev_ip_csum_features);
 		else
-			f2 |= netdev_ip_csum_features;
+			netdev_features_set(&f2, netdev_ip_csum_features);
 	}
 
 	return f1 & f2;
@@ -604,7 +604,7 @@ netdev_get_wanted_features(struct net_device *dev)
 	netdev_features_t tmp;
 
 	tmp = dev->features & ~dev->hw_features;
-	return dev->wanted_features | tmp;
+	return netdev_wanted_features_or(dev, tmp);
 }
 
 #endif
diff --git a/net/core/dev.c b/net/core/dev.c
index 921f10018fbc..13bb2cd8e2af 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -3345,7 +3345,7 @@ struct sk_buff *__skb_gso_segment(struct sk_buff *skb,
 
 		partial_features = dev->features & dev->gso_partial_features;
 		netdev_feature_add(NETIF_F_GSO_ROBUST_BIT, &partial_features);
-		if (!skb_gso_ok(skb, features | partial_features))
+		if (!skb_gso_ok(skb, netdev_features_or(features, partial_features)))
 			features &= ~NETIF_F_GSO_PARTIAL;
 	}
 
@@ -3512,7 +3512,7 @@ netdev_features_t netif_skb_features(struct sk_buff *skb)
 		features &= dev->hw_enc_features;
 
 	if (skb_vlan_tagged(skb)) {
-		tmp = dev->vlan_features | netdev_tx_vlan_features;
+		tmp = netdev_vlan_features_or(dev, netdev_tx_vlan_features);
 		features = netdev_intersect_features(features, tmp);
 	}
 
@@ -9931,9 +9931,9 @@ 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;
-	dev->hw_features |= NETIF_F_SOFT_FEATURES_OFF;
-	dev->features |= NETIF_F_SOFT_FEATURES;
+	netdev_hw_features_set(dev, NETIF_F_SOFT_FEATURES);
+	netdev_hw_features_set(dev, NETIF_F_SOFT_FEATURES_OFF);
+	netdev_active_features_set(dev, NETIF_F_SOFT_FEATURES);
 
 	if (dev->udp_tunnel_nic_info) {
 		netdev_active_feature_add(dev, NETIF_F_RX_UDP_TUNNEL_PORT_BIT);
@@ -11056,17 +11056,17 @@ netdev_features_t netdev_increment_features(netdev_features_t all,
 	netdev_features_t tmp;
 
 	if (mask & NETIF_F_HW_CSUM)
-		mask |= NETIF_F_CSUM_MASK;
+		netdev_features_set(&mask, NETIF_F_CSUM_MASK);
 	netdev_feature_add(NETIF_F_VLAN_CHALLENGED_BIT, &mask);
 
-	tmp = NETIF_F_ONE_FOR_ALL | NETIF_F_CSUM_MASK;
+	tmp = netdev_features_or(NETIF_F_ONE_FOR_ALL, NETIF_F_CSUM_MASK);
 	tmp &= one;
 	tmp &= mask;
-	all |= tmp;
+	netdev_features_set(&all, tmp);
 
 	netdev_features_fill(&tmp);
 	tmp &= ~NETIF_F_ALL_FOR_ALL;
-	tmp |= one;
+	netdev_features_set(&tmp, one);
 	all &= tmp;
 
 	/* If one device supports hw checksumming, set for all. */
diff --git a/net/ethtool/features.c b/net/ethtool/features.c
index 2c64183012c1..8e753afc0824 100644
--- a/net/ethtool/features.c
+++ b/net/ethtool/features.c
@@ -150,7 +150,8 @@ static netdev_features_t ethnl_bitmap_to_features(unsigned long *src)
 
 	netdev_features_zero(&ret);
 	for (i = 0; i < words; i++)
-		ret |= (netdev_features_t)(src[i]) << (i * BITS_PER_LONG);
+		netdev_features_set(&ret,
+				    (netdev_features_t)(src[i]) << (i * BITS_PER_LONG));
 	ret &= ~(netdev_features_t)0 >> (nft_bits - NETDEV_FEATURE_COUNT);
 	return ret;
 }
@@ -257,7 +258,7 @@ int ethnl_set_features(struct sk_buff *skb, struct genl_info *info)
 	if (!bitmap_equal(req_wanted, old_wanted, NETDEV_FEATURE_COUNT)) {
 		dev->wanted_features &= ~dev->hw_features;
 		tmp = ethnl_bitmap_to_features(req_wanted) & dev->hw_features;
-		dev->wanted_features |= tmp;
+		netdev_wanted_features_set(dev, 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 b258379006f1..d18f305ee691 100644
--- a/net/ethtool/ioctl.c
+++ b/net/ethtool/ioctl.c
@@ -143,8 +143,10 @@ static int ethtool_set_features(struct net_device *dev, void __user *useraddr)
 	netdev_features_zero(&wanted);
 	netdev_features_zero(&valid);
 	for (i = 0; i < ETHTOOL_DEV_FEATURE_WORDS; ++i) {
-		valid |= (netdev_features_t)features[i].valid << (32 * i);
-		wanted |= (netdev_features_t)features[i].requested << (32 * i);
+		netdev_features_set(&valid,
+				    (netdev_features_t)features[i].valid << (32 * i));
+		netdev_features_set(&wanted,
+				    (netdev_features_t)features[i].requested << (32 * i));
 	}
 
 	tmp = valid & ~NETIF_F_ETHTOOL_BITS;
@@ -159,7 +161,7 @@ static int ethtool_set_features(struct net_device *dev, void __user *useraddr)
 
 	dev->wanted_features &= ~valid;
 	tmp = wanted & valid;
-	dev->wanted_features |= tmp;
+	netdev_wanted_features_set(dev, tmp);
 	__netdev_update_features(dev);
 
 	tmp = dev->wanted_features ^ dev->features;
@@ -297,7 +299,7 @@ static int ethtool_set_one_feature(struct net_device *dev,
 		return -EOPNOTSUPP;
 
 	if (edata.data)
-		dev->wanted_features |= mask;
+		netdev_wanted_features_set(dev, mask);
 	else
 		dev->wanted_features &= ~mask;
 
@@ -368,7 +370,7 @@ static int __ethtool_set_flags(struct net_device *dev, u32 data)
 
 	dev->wanted_features &= ~changed;
 	tmp = features & changed;
-	dev->wanted_features |= tmp;
+	netdev_wanted_features_set(dev, tmp);
 
 	__netdev_update_features(dev);
 
-- 
2.33.0


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [RFCv6 PATCH net-next 09/19] net: use netdev_features_xor helpers
  2022-04-19  2:21 [RFCv6 PATCH net-next 00/19] net: extend the type of netdev_features_t to bitmap Jian Shen
                   ` (7 preceding siblings ...)
  2022-04-19  2:21 ` [RFCv6 PATCH net-next 08/19] net: use netdev_features_or helpers Jian Shen
@ 2022-04-19  2:21 ` Jian Shen
  2022-04-19  2:21 ` [RFCv6 PATCH net-next 10/19] net: use netdev_feature_del helpers Jian Shen
                   ` (9 subsequent siblings)
  18 siblings, 0 replies; 30+ messages in thread
From: Jian Shen @ 2022-04-19  2:21 UTC (permalink / raw)
  To: davem, kuba, andrew, ecree.xilinx, hkallweit1, alexandr.lobakin,
	saeed, leon
  Cc: netdev, linuxarm, lipeng321

Replace the '^' operations of features by
netdev_features_xor helpers.

Signed-off-by: Jian Shen <shenjian15@huawei.com>
---
 drivers/net/ethernet/hisilicon/hns3/hns3_enet.c | 2 +-
 drivers/net/ethernet/sfc/efx_common.c           | 2 +-
 drivers/net/ethernet/sfc/falcon/efx.c           | 2 +-
 include/linux/netdev_features_helper.h          | 2 +-
 net/core/dev.c                                  | 2 +-
 net/ethtool/ioctl.c                             | 4 ++--
 6 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
index e43b3e8c4f84..948317f210a4 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;
 
-	changed = netdev->features ^ features;
+	changed = netdev_active_features_xor(netdev, features);
 
 	if (changed & (NETIF_F_GRO_HW) && h->ae_algo->ops->set_gro_en) {
 		enable = !!(features & NETIF_F_GRO_HW);
diff --git a/drivers/net/ethernet/sfc/efx_common.c b/drivers/net/ethernet/sfc/efx_common.c
index f5536eb00dfc..5d3be6c4df54 100644
--- a/drivers/net/ethernet/sfc/efx_common.c
+++ b/drivers/net/ethernet/sfc/efx_common.c
@@ -226,7 +226,7 @@ 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.
 	 */
-	tmp = net_dev->features ^ data;
+	tmp = netdev_active_features_xor(net_dev, data);
 	if (tmp & NETIF_F_HW_VLAN_CTAG_FILTER ||
 	    tmp & NETIF_F_RXFCS) {
 		/* efx_set_rx_mode() will schedule MAC work to update filters
diff --git a/drivers/net/ethernet/sfc/falcon/efx.c b/drivers/net/ethernet/sfc/falcon/efx.c
index d246c5b805a1..b5ce520e8f2f 100644
--- a/drivers/net/ethernet/sfc/falcon/efx.c
+++ b/drivers/net/ethernet/sfc/falcon/efx.c
@@ -2201,7 +2201,7 @@ static int ef4_set_features(struct net_device *net_dev, netdev_features_t data)
 	}
 
 	/* If Rx VLAN filter is changed, update filters via mac_reconfigure */
-	tmp = net_dev->features ^ data;
+	tmp = netdev_active_features_xor(net_dev, 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.
diff --git a/include/linux/netdev_features_helper.h b/include/linux/netdev_features_helper.h
index 0c4363588582..7e2d66a5b803 100644
--- a/include/linux/netdev_features_helper.h
+++ b/include/linux/netdev_features_helper.h
@@ -587,7 +587,7 @@ static inline netdev_features_t netdev_intersect_features(netdev_features_t f1,
 {
 	netdev_features_t tmp;
 
-	tmp = f1 ^ f2;
+	tmp = netdev_features_xor(f1, f2);
 	if (tmp & NETIF_F_HW_CSUM) {
 		if (f1 & NETIF_F_HW_CSUM)
 			netdev_features_set(&f1, netdev_ip_csum_features);
diff --git a/net/core/dev.c b/net/core/dev.c
index 13bb2cd8e2af..076305d33a62 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -9651,7 +9651,7 @@ int __netdev_update_features(struct net_device *dev)
 	if (!err) {
 		netdev_features_t diff;
 
-		diff = features ^ dev->features;
+		diff = netdev_features_xor(features, dev->features);
 
 		if (diff & NETIF_F_RX_UDP_TUNNEL_PORT) {
 			/* udp_tunnel_{get,drop}_rx_info both need
diff --git a/net/ethtool/ioctl.c b/net/ethtool/ioctl.c
index d18f305ee691..4a685224fba9 100644
--- a/net/ethtool/ioctl.c
+++ b/net/ethtool/ioctl.c
@@ -164,7 +164,7 @@ static int ethtool_set_features(struct net_device *dev, void __user *useraddr)
 	netdev_wanted_features_set(dev, tmp);
 	__netdev_update_features(dev);
 
-	tmp = dev->wanted_features ^ dev->features;
+	tmp = netdev_wanted_features_xor(dev, dev->features);
 	if (tmp & valid)
 		ret |= ETHTOOL_F_WISH;
 
@@ -362,7 +362,7 @@ 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 = dev->features ^ features;
+	changed = netdev_active_features_xor(dev, features);
 	changed &= eth_all_features;
 	tmp = changed & ~dev->hw_features;
 	if (tmp)
-- 
2.33.0


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [RFCv6 PATCH net-next 10/19] net: use netdev_feature_del helpers
  2022-04-19  2:21 [RFCv6 PATCH net-next 00/19] net: extend the type of netdev_features_t to bitmap Jian Shen
                   ` (8 preceding siblings ...)
  2022-04-19  2:21 ` [RFCv6 PATCH net-next 09/19] net: use netdev_features_xor helpers Jian Shen
@ 2022-04-19  2:21 ` Jian Shen
  2022-04-19  2:21 ` [RFCv6 PATCH net-next 11/19] net: use netdev_features_andnot helpers Jian Shen
                   ` (8 subsequent siblings)
  18 siblings, 0 replies; 30+ messages in thread
From: Jian Shen @ 2022-04-19  2:21 UTC (permalink / raw)
  To: davem, kuba, andrew, ecree.xilinx, hkallweit1, alexandr.lobakin,
	saeed, leon
  Cc: netdev, linuxarm, lipeng321

Replace the '&~' and '&= ~' operations of single feature bit by
netdev_feature_del helpers.

Signed-off-by: Jian Shen <shenjian15@huawei.com>
---
 .../net/ethernet/hisilicon/hns3/hns3_enet.c   |  2 +-
 drivers/net/ethernet/sfc/ef10_sriov.c         |  3 +-
 drivers/net/ethernet/sfc/efx.c                |  4 +-
 drivers/net/ethernet/sfc/falcon/efx.c         |  2 +-
 drivers/net/ethernet/sfc/mcdi_filters.c       |  9 +++--
 net/core/dev.c                                | 39 ++++++++++---------
 6 files changed, 32 insertions(+), 27 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
index 948317f210a4..fca355329040 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
@@ -3321,7 +3321,7 @@ static void hns3_set_default_feature(struct net_device *netdev)
 
 	netdev_hw_features_set(netdev, netdev->features);
 	if (!test_bit(HNAE3_DEV_SUPPORT_VLAN_FLTR_MDF_B, ae_dev->caps))
-		netdev->hw_features &= ~NETIF_F_HW_VLAN_CTAG_FILTER;
+		netdev_hw_feature_del(netdev, NETIF_F_HW_VLAN_CTAG_FILTER_BIT);
 
 	netdev_features_zero(&vlan_off_features);
 	netdev_features_set_array(&hns3_vlan_off_feature_set,
diff --git a/drivers/net/ethernet/sfc/ef10_sriov.c b/drivers/net/ethernet/sfc/ef10_sriov.c
index 857e7520461d..4bea76d0b833 100644
--- a/drivers/net/ethernet/sfc/ef10_sriov.c
+++ b/drivers/net/ethernet/sfc/ef10_sriov.c
@@ -246,7 +246,8 @@ static int efx_ef10_vadaptor_alloc_set_features(struct efx_nic *efx)
 		netdev_feature_add(NETIF_F_HW_VLAN_CTAG_FILTER_BIT,
 				   &efx->fixed_features);
 	else
-		efx->fixed_features &= ~NETIF_F_HW_VLAN_CTAG_FILTER;
+		netdev_feature_del(NETIF_F_HW_VLAN_CTAG_FILTER_BIT,
+				   &efx->fixed_features);
 
 	return 0;
 
diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c
index e346ad52c9a2..e37007839e2f 100644
--- a/drivers/net/ethernet/sfc/efx.c
+++ b/drivers/net/ethernet/sfc/efx.c
@@ -1033,13 +1033,13 @@ static int efx_pci_probe_post_io(struct efx_nic *efx)
 	netdev_hw_features_set(net_dev, tmp);
 
 	/* Disable receiving frames with bad FCS, by default. */
-	net_dev->features &= ~NETIF_F_RXALL;
+	netdev_active_feature_del(net_dev, NETIF_F_RXALL_BIT);
 
 	/* Disable VLAN filtering by default.  It may be enforced if
 	 * the feature is fixed (i.e. VLAN filters are required to
 	 * receive VLAN tagged packets due to vPort restrictions).
 	 */
-	net_dev->features &= ~NETIF_F_HW_VLAN_CTAG_FILTER;
+	netdev_active_feature_del(net_dev, NETIF_F_HW_VLAN_CTAG_FILTER_BIT);
 	netdev_active_features_set(net_dev, efx->fixed_features);
 
 	rc = efx_register_netdev(efx);
diff --git a/drivers/net/ethernet/sfc/falcon/efx.c b/drivers/net/ethernet/sfc/falcon/efx.c
index b5ce520e8f2f..d2056fbaa3d1 100644
--- a/drivers/net/ethernet/sfc/falcon/efx.c
+++ b/drivers/net/ethernet/sfc/falcon/efx.c
@@ -2925,7 +2925,7 @@ static int ef4_pci_probe(struct pci_dev *pci_dev,
 	 * the feature is fixed (i.e. VLAN filters are required to
 	 * receive VLAN tagged packets due to vPort restrictions).
 	 */
-	net_dev->features &= ~NETIF_F_HW_VLAN_CTAG_FILTER;
+	netdev_active_feature_del(net_dev, NETIF_F_HW_VLAN_CTAG_FILTER_BIT);
 	netdev_active_features_set(net_dev, efx->fixed_features);
 
 	rc = ef4_register_netdev(efx);
diff --git a/drivers/net/ethernet/sfc/mcdi_filters.c b/drivers/net/ethernet/sfc/mcdi_filters.c
index 1523be77b9db..508549db124b 100644
--- a/drivers/net/ethernet/sfc/mcdi_filters.c
+++ b/drivers/net/ethernet/sfc/mcdi_filters.c
@@ -1326,9 +1326,12 @@ int efx_mcdi_filter_table_probe(struct efx_nic *efx, bool multicast_chaining)
 		(EFX_FILTER_MATCH_OUTER_VID | EFX_FILTER_MATCH_LOC_MAC_IG)))) {
 		netif_info(efx, probe, net_dev,
 			   "VLAN filters are not supported in this firmware variant\n");
-		net_dev->features &= ~NETIF_F_HW_VLAN_CTAG_FILTER;
-		efx->fixed_features &= ~NETIF_F_HW_VLAN_CTAG_FILTER;
-		net_dev->hw_features &= ~NETIF_F_HW_VLAN_CTAG_FILTER;
+		netdev_active_feature_del(net_dev,
+					  NETIF_F_HW_VLAN_CTAG_FILTER_BIT);
+		netdev_feature_del(NETIF_F_HW_VLAN_CTAG_FILTER_BIT,
+				   &efx->fixed_features);
+		netdev_hw_feature_del(net_dev,
+				      NETIF_F_HW_VLAN_CTAG_FILTER_BIT);
 	}
 
 	table->entry = vzalloc(array_size(EFX_MCDI_FILTER_TBL_ROWS,
diff --git a/net/core/dev.c b/net/core/dev.c
index 076305d33a62..4ea8231ecdee 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -1583,7 +1583,7 @@ void dev_disable_lro(struct net_device *dev)
 	struct net_device *lower_dev;
 	struct list_head *iter;
 
-	dev->wanted_features &= ~NETIF_F_LRO;
+	netdev_wanted_feature_del(dev, NETIF_F_LRO_BIT);
 	netdev_update_features(dev);
 
 	if (unlikely(dev->features & NETIF_F_LRO))
@@ -1604,7 +1604,7 @@ EXPORT_SYMBOL(dev_disable_lro);
  */
 static void dev_disable_gro_hw(struct net_device *dev)
 {
-	dev->wanted_features &= ~NETIF_F_GRO_HW;
+	netdev_wanted_feature_del(dev, NETIF_F_GRO_HW_BIT);
 	netdev_update_features(dev);
 
 	if (unlikely(dev->features & NETIF_F_GRO_HW))
@@ -3346,7 +3346,7 @@ struct sk_buff *__skb_gso_segment(struct sk_buff *skb,
 		partial_features = dev->features & dev->gso_partial_features;
 		netdev_feature_add(NETIF_F_GSO_ROBUST_BIT, &partial_features);
 		if (!skb_gso_ok(skb, netdev_features_or(features, partial_features)))
-			features &= ~NETIF_F_GSO_PARTIAL;
+			netdev_feature_del(NETIF_F_GSO_PARTIAL_BIT, &features);
 	}
 
 	BUILD_BUG_ON(SKB_GSO_CB_OFFSET +
@@ -3436,7 +3436,7 @@ static netdev_features_t harmonize_features(struct sk_buff *skb,
 		features &= ~netdev_csum_gso_features_mask;
 	}
 	if (illegal_highdma(skb->dev, skb))
-		features &= ~NETIF_F_SG;
+		netdev_feature_del(NETIF_F_SG_BIT, &features);
 
 	return features;
 }
@@ -3487,7 +3487,8 @@ static netdev_features_t gso_features_check(const struct sk_buff *skb,
 				    inner_ip_hdr(skb) : ip_hdr(skb);
 
 		if (!(iph->frag_off & htons(IP_DF)))
-			features &= ~NETIF_F_TSO_MANGLEID;
+			netdev_feature_del(NETIF_F_TSO_MANGLEID_BIT,
+					   &features);
 	}
 
 	return features;
@@ -9516,30 +9517,30 @@ static netdev_features_t netdev_fix_features(struct net_device *dev,
 	if ((features & NETIF_F_TSO) && !(features & NETIF_F_HW_CSUM) &&
 					!(features & NETIF_F_IP_CSUM)) {
 		netdev_dbg(dev, "Dropping TSO features since no CSUM feature.\n");
-		features &= ~NETIF_F_TSO;
-		features &= ~NETIF_F_TSO_ECN;
+		netdev_feature_del(NETIF_F_TSO_BIT, &features);
+		netdev_feature_del(NETIF_F_TSO_ECN_BIT, &features);
 	}
 
 	if ((features & NETIF_F_TSO6) && !(features & NETIF_F_HW_CSUM) &&
 					 !(features & NETIF_F_IPV6_CSUM)) {
 		netdev_dbg(dev, "Dropping TSO6 features since no CSUM feature.\n");
-		features &= ~NETIF_F_TSO6;
+		netdev_feature_del(NETIF_F_TSO6_BIT, &features);
 	}
 
 	/* TSO with IPv4 ID mangling requires IPv4 TSO be enabled */
 	if ((features & NETIF_F_TSO_MANGLEID) && !(features & NETIF_F_TSO))
-		features &= ~NETIF_F_TSO_MANGLEID;
+		netdev_feature_del(NETIF_F_TSO_MANGLEID_BIT, &features);
 
 	/* TSO ECN requires that TSO is present as well. */
 	tmp = NETIF_F_ALL_TSO;
-	tmp &= ~NETIF_F_TSO_ECN;
+	netdev_feature_del(NETIF_F_TSO_ECN_BIT, &tmp);
 	if (!(features & tmp) && (features & NETIF_F_TSO_ECN))
-		features &= ~NETIF_F_TSO_ECN;
+		netdev_feature_del(NETIF_F_TSO_ECN_BIT, &features);
 
 	/* Software GSO depends on SG. */
 	if ((features & NETIF_F_GSO) && !(features & NETIF_F_SG)) {
 		netdev_dbg(dev, "Dropping NETIF_F_GSO since no SG feature.\n");
-		features &= ~NETIF_F_GSO;
+		netdev_feature_del(NETIF_F_GSO_BIT, &features);
 	}
 
 	/* GSO partial features require GSO partial be set */
@@ -9558,7 +9559,7 @@ static netdev_features_t netdev_fix_features(struct net_device *dev,
 		 */
 		if (features & NETIF_F_GRO_HW) {
 			netdev_dbg(dev, "Dropping NETIF_F_GRO_HW since no RXCSUM feature.\n");
-			features &= ~NETIF_F_GRO_HW;
+			netdev_feature_del(NETIF_F_GRO_HW_BIT, &features);
 		}
 	}
 
@@ -9566,18 +9567,18 @@ static netdev_features_t netdev_fix_features(struct net_device *dev,
 	if (features & NETIF_F_RXFCS) {
 		if (features & NETIF_F_LRO) {
 			netdev_dbg(dev, "Dropping LRO feature since RX-FCS is requested.\n");
-			features &= ~NETIF_F_LRO;
+			netdev_feature_del(NETIF_F_LRO_BIT, &features);
 		}
 
 		if (features & NETIF_F_GRO_HW) {
 			netdev_dbg(dev, "Dropping HW-GRO feature since RX-FCS is requested.\n");
-			features &= ~NETIF_F_GRO_HW;
+			netdev_feature_del(NETIF_F_GRO_HW_BIT, &features);
 		}
 	}
 
 	if ((features & NETIF_F_GRO_HW) && (features & NETIF_F_LRO)) {
 		netdev_dbg(dev, "Dropping LRO feature since HW-GRO is requested.\n");
-		features &= ~NETIF_F_LRO;
+		netdev_feature_del(NETIF_F_LRO_BIT, &features);
 	}
 
 	if (features & NETIF_F_HW_TLS_TX) {
@@ -9587,13 +9588,13 @@ static netdev_features_t netdev_fix_features(struct net_device *dev,
 
 		if (!ip_csum && !hw_csum) {
 			netdev_dbg(dev, "Dropping TLS TX HW offload feature since no CSUM feature.\n");
-			features &= ~NETIF_F_HW_TLS_TX;
+			netdev_feature_del(NETIF_F_HW_TLS_TX_BIT, &features);
 		}
 	}
 
 	if ((features & NETIF_F_HW_TLS_RX) && !(features & NETIF_F_RXCSUM)) {
 		netdev_dbg(dev, "Dropping TLS RX HW offload feature since no RXCSUM feature.\n");
-		features &= ~NETIF_F_HW_TLS_RX;
+		netdev_feature_del(NETIF_F_HW_TLS_RX_BIT, &features);
 	}
 
 	return features;
@@ -11072,7 +11073,7 @@ netdev_features_t netdev_increment_features(netdev_features_t all,
 	/* If one device supports hw checksumming, set for all. */
 	if (all & NETIF_F_HW_CSUM) {
 		tmp = NETIF_F_CSUM_MASK;
-		tmp &= ~NETIF_F_HW_CSUM;
+		netdev_feature_del(NETIF_F_HW_CSUM_BIT, &tmp);
 		all &= ~tmp;
 	}
 
-- 
2.33.0


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [RFCv6 PATCH net-next 11/19] net: use netdev_features_andnot helpers
  2022-04-19  2:21 [RFCv6 PATCH net-next 00/19] net: extend the type of netdev_features_t to bitmap Jian Shen
                   ` (9 preceding siblings ...)
  2022-04-19  2:21 ` [RFCv6 PATCH net-next 10/19] net: use netdev_feature_del helpers Jian Shen
@ 2022-04-19  2:21 ` Jian Shen
  2022-04-19  2:21 ` [RFCv6 PATCH net-next 12/19] net: use netdev_feature_test helpers Jian Shen
                   ` (7 subsequent siblings)
  18 siblings, 0 replies; 30+ messages in thread
From: Jian Shen @ 2022-04-19  2:21 UTC (permalink / raw)
  To: davem, kuba, andrew, ecree.xilinx, hkallweit1, alexandr.lobakin,
	saeed, leon
  Cc: netdev, linuxarm, lipeng321

Replace the '& ~' and '&= ~' operations of features by
netdev_features_andnot helpers.

Signed-off-by: Jian Shen <shenjian15@huawei.com>
---
 .../net/ethernet/hisilicon/hns3/hns3_enet.c   |  5 ++--
 drivers/net/ethernet/sfc/efx.c                |  4 ++--
 drivers/net/ethernet/sfc/efx_common.c         |  9 ++++----
 drivers/net/ethernet/sfc/falcon/efx.c         |  7 +++---
 include/linux/netdev_features_helper.h        |  2 +-
 net/core/dev.c                                | 23 ++++++++++---------
 net/ethtool/features.c                        |  2 +-
 net/ethtool/ioctl.c                           | 12 +++++-----
 8 files changed, 34 insertions(+), 30 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
index fca355329040..38706313aa6c 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
@@ -2478,7 +2478,8 @@ static netdev_features_t hns3_features_check(struct sk_buff *skb,
 	 * len of 480 bytes.
 	 */
 	if (len > HNS3_MAX_HDR_LEN)
-		features &= ~netdev_csum_gso_features_mask;
+		netdev_features_clear(&features,
+				      netdev_csum_gso_features_mask);
 
 	return features;
 }
@@ -3326,7 +3327,7 @@ 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);
-	features = netdev->features & ~vlan_off_features;
+	features = netdev_active_features_andnot(netdev, vlan_off_features);
 	netdev_vlan_features_set(netdev, features);
 
 	netdev_hw_enc_features_set(netdev, netdev->vlan_features);
diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c
index e37007839e2f..89c62304b5c3 100644
--- a/drivers/net/ethernet/sfc/efx.c
+++ b/drivers/net/ethernet/sfc/efx.c
@@ -1024,12 +1024,12 @@ static int efx_pci_probe_post_io(struct efx_nic *efx)
 		netdev_active_feature_add(net_dev, NETIF_F_TSO6_BIT);
 	/* Check whether device supports TSO */
 	if (!efx->type->tso_versions || !efx->type->tso_versions(efx))
-		net_dev->features &= ~NETIF_F_ALL_TSO;
+		netdev_active_features_clear(net_dev, NETIF_F_ALL_TSO);
 	/* Mask for features that also apply to VLAN devices */
 	netdev_vlan_features_set(net_dev, NETIF_F_ALL_TSO);
 	netdev_vlan_features_set_array(net_dev, &efx_vlan_feature_set);
 
-	tmp = net_dev->features & ~efx->fixed_features;
+	tmp = netdev_active_features_andnot(net_dev, efx->fixed_features);
 	netdev_hw_features_set(net_dev, tmp);
 
 	/* Disable receiving frames with bad FCS, by default. */
diff --git a/drivers/net/ethernet/sfc/efx_common.c b/drivers/net/ethernet/sfc/efx_common.c
index 5d3be6c4df54..8b95525aad20 100644
--- a/drivers/net/ethernet/sfc/efx_common.c
+++ b/drivers/net/ethernet/sfc/efx_common.c
@@ -216,7 +216,7 @@ int efx_set_features(struct net_device *net_dev, netdev_features_t data)
 	int rc;
 
 	/* If disabling RX n-tuple filtering, clear existing filters */
-	tmp = net_dev->features & ~data;
+	tmp = netdev_active_features_andnot(net_dev, data);
 	if (tmp & NETIF_F_NTUPLE) {
 		rc = efx->type->filter_clear_rx(efx, EFX_FILTER_PRI_MANUAL);
 		if (rc)
@@ -415,7 +415,7 @@ static void efx_start_datapath(struct efx_nic *efx)
 	 */
 	old_features = efx->net_dev->features;
 	netdev_hw_features_set(efx->net_dev, efx->net_dev->features);
-	efx->net_dev->hw_features &= ~efx->fixed_features;
+	netdev_hw_features_clear(efx->net_dev, efx->fixed_features);
 	netdev_active_features_set(efx->net_dev, efx->fixed_features);
 	if (efx->net_dev->features != old_features)
 		netdev_features_change(efx->net_dev);
@@ -1370,10 +1370,11 @@ 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);
+				netdev_features_clear(&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;
+				netdev_features_clear(&features,
+						      netdev_csum_gso_features_mask);
 	}
 	return features;
 }
diff --git a/drivers/net/ethernet/sfc/falcon/efx.c b/drivers/net/ethernet/sfc/falcon/efx.c
index d2056fbaa3d1..921617de3638 100644
--- a/drivers/net/ethernet/sfc/falcon/efx.c
+++ b/drivers/net/ethernet/sfc/falcon/efx.c
@@ -642,7 +642,7 @@ static void ef4_start_datapath(struct ef4_nic *efx)
 	 */
 	old_features = efx->net_dev->features;
 	netdev_hw_features_set(efx->net_dev, efx->net_dev->features);
-	efx->net_dev->hw_features &= ~efx->fixed_features;
+	netdev_hw_features_clear(efx->net_dev, efx->fixed_features);
 	netdev_active_features_set(efx->net_dev, efx->fixed_features);
 	if (efx->net_dev->features != old_features)
 		netdev_features_change(efx->net_dev);
@@ -2193,7 +2193,7 @@ static int ef4_set_features(struct net_device *net_dev, netdev_features_t data)
 	int rc;
 
 	/* If disabling RX n-tuple filtering, clear existing filters */
-	tmp = net_dev->features & ~data;
+	tmp = netdev_active_features_andnot(net_dev, data);
 	if (tmp & NETIF_F_NTUPLE) {
 		rc = efx->type->filter_clear_rx(efx, EF4_FILTER_PRI_MANUAL);
 		if (rc)
@@ -2919,7 +2919,8 @@ static int ef4_pci_probe(struct pci_dev *pci_dev,
 	netdev_active_feature_add(net_dev, NETIF_F_RXCSUM_BIT);
 	/* 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;
+	net_dev->hw_features = netdev_active_features_andnot(net_dev,
+							     efx->fixed_features);
 
 	/* Disable VLAN filtering by default.  It may be enforced if
 	 * the feature is fixed (i.e. VLAN filters are required to
diff --git a/include/linux/netdev_features_helper.h b/include/linux/netdev_features_helper.h
index 7e2d66a5b803..067b90ca3084 100644
--- a/include/linux/netdev_features_helper.h
+++ b/include/linux/netdev_features_helper.h
@@ -603,7 +603,7 @@ netdev_get_wanted_features(struct net_device *dev)
 {
 	netdev_features_t tmp;
 
-	tmp = dev->features & ~dev->hw_features;
+	tmp = netdev_active_features_andnot(dev, dev->hw_features);
 	return netdev_wanted_features_or(dev, tmp);
 }
 
diff --git a/net/core/dev.c b/net/core/dev.c
index 4ea8231ecdee..124d48b5d61a 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -3433,7 +3433,8 @@ static netdev_features_t harmonize_features(struct sk_buff *skb,
 
 	if (skb->ip_summed != CHECKSUM_NONE &&
 	    !can_checksum_protocol(features, type)) {
-		features &= ~netdev_csum_gso_features_mask;
+		netdev_features_clear(&features,
+				      netdev_csum_gso_features_mask);
 	}
 	if (illegal_highdma(skb->dev, skb))
 		netdev_feature_del(NETIF_F_SG_BIT, &features);
@@ -3463,11 +3464,11 @@ static netdev_features_t gso_features_check(const struct sk_buff *skb,
 	u16 gso_segs = skb_shinfo(skb)->gso_segs;
 
 	if (gso_segs > READ_ONCE(dev->gso_max_segs))
-		return features & ~NETIF_F_GSO_MASK;
+		return netdev_features_andnot(features, NETIF_F_GSO_MASK);
 
 	if (!skb_shinfo(skb)->gso_type) {
 		skb_warn_bad_offload(skb);
-		return features & ~NETIF_F_GSO_MASK;
+		return netdev_features_andnot(features, NETIF_F_GSO_MASK);
 	}
 
 	/* Support for GSO partial features requires software
@@ -3477,7 +3478,7 @@ static netdev_features_t gso_features_check(const struct sk_buff *skb,
 	 * segmented the frame.
 	 */
 	if (!(skb_shinfo(skb)->gso_type & SKB_GSO_PARTIAL))
-		features &= ~dev->gso_partial_features;
+		netdev_features_clear(&features, dev->gso_partial_features);
 
 	/* Make sure to clear the IPv4 ID mangling feature if the
 	 * IPv4 header has the potential to be fragmented.
@@ -9464,7 +9465,7 @@ static netdev_features_t netdev_sync_upper_features(struct net_device *lower,
 		    && (features & feature)) {
 			netdev_dbg(lower, "Dropping feature %pNF, upper dev %s has it off.\n",
 				   &feature, upper->name);
-			features &= ~feature;
+			netdev_features_clear(&features, feature);
 		}
 	}
 
@@ -9484,7 +9485,7 @@ static void netdev_sync_lower_features(struct net_device *upper,
 		if (!(features & feature) && (lower->features & feature)) {
 			netdev_dbg(upper, "Disabling feature %pNF on lower dev %s.\n",
 				   &feature, lower->name);
-			lower->wanted_features &= ~feature;
+			netdev_wanted_features_clear(lower, feature);
 			__netdev_update_features(lower);
 
 			if (unlikely(lower->features & feature))
@@ -9505,13 +9506,13 @@ static netdev_features_t netdev_fix_features(struct net_device *dev,
 	if ((features & NETIF_F_HW_CSUM) &&
 	    (features & netdev_ip_csum_features)) {
 		netdev_warn(dev, "mixed HW and IP checksum settings.\n");
-		features &= ~netdev_ip_csum_features;
+		netdev_features_clear(&features, netdev_ip_csum_features);
 	}
 
 	/* TSO requires that SG is present as well. */
 	if ((features & NETIF_F_ALL_TSO) && !(features & NETIF_F_SG)) {
 		netdev_dbg(dev, "Dropping TSO features since no SG feature.\n");
-		features &= ~NETIF_F_ALL_TSO;
+		netdev_features_clear(&features, NETIF_F_ALL_TSO);
 	}
 
 	if ((features & NETIF_F_TSO) && !(features & NETIF_F_HW_CSUM) &&
@@ -9548,7 +9549,7 @@ static netdev_features_t netdev_fix_features(struct net_device *dev,
 	    !(features & NETIF_F_GSO_PARTIAL)) {
 		netdev_dbg(dev,
 			   "Dropping partially supported GSO features since no GSO partial.\n");
-		features &= ~dev->gso_partial_features;
+		netdev_features_clear(&features, dev->gso_partial_features);
 	}
 
 	if (!(features & NETIF_F_RXCSUM)) {
@@ -11066,7 +11067,7 @@ netdev_features_t netdev_increment_features(netdev_features_t all,
 	netdev_features_set(&all, tmp);
 
 	netdev_features_fill(&tmp);
-	tmp &= ~NETIF_F_ALL_FOR_ALL;
+	netdev_features_clear(&tmp, NETIF_F_ALL_FOR_ALL);
 	netdev_features_set(&tmp, one);
 	all &= tmp;
 
@@ -11074,7 +11075,7 @@ netdev_features_t netdev_increment_features(netdev_features_t all,
 	if (all & NETIF_F_HW_CSUM) {
 		tmp = NETIF_F_CSUM_MASK;
 		netdev_feature_del(NETIF_F_HW_CSUM_BIT, &tmp);
-		all &= ~tmp;
+		netdev_features_clear(&all, tmp);
 	}
 
 	return all;
diff --git a/net/ethtool/features.c b/net/ethtool/features.c
index 8e753afc0824..2de4cabf41e0 100644
--- a/net/ethtool/features.c
+++ b/net/ethtool/features.c
@@ -256,7 +256,7 @@ int ethnl_set_features(struct sk_buff *skb, struct genl_info *info)
 	bitmap_andnot(new_wanted, old_wanted, req_mask, NETDEV_FEATURE_COUNT);
 	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;
+		netdev_wanted_features_clear(dev, dev->hw_features);
 		tmp = ethnl_bitmap_to_features(req_wanted) & dev->hw_features;
 		netdev_wanted_features_set(dev, tmp);
 		__netdev_update_features(dev);
diff --git a/net/ethtool/ioctl.c b/net/ethtool/ioctl.c
index 4a685224fba9..3c951a883076 100644
--- a/net/ethtool/ioctl.c
+++ b/net/ethtool/ioctl.c
@@ -149,17 +149,17 @@ static int ethtool_set_features(struct net_device *dev, void __user *useraddr)
 				    (netdev_features_t)features[i].requested << (32 * i));
 	}
 
-	tmp = valid & ~NETIF_F_ETHTOOL_BITS;
+	tmp = netdev_features_andnot(valid, NETIF_F_ETHTOOL_BITS);
 	if (tmp)
 		return -EINVAL;
 
-	tmp = valid & ~dev->hw_features;
+	netdev_hw_features_andnot_r(dev, valid);
 	if (tmp) {
 		valid &= dev->hw_features;
 		ret |= ETHTOOL_F_UNSUPPORTED;
 	}
 
-	dev->wanted_features &= ~valid;
+	netdev_wanted_features_clear(dev, valid);
 	tmp = wanted & valid;
 	netdev_wanted_features_set(dev, tmp);
 	__netdev_update_features(dev);
@@ -301,7 +301,7 @@ static int ethtool_set_one_feature(struct net_device *dev,
 	if (edata.data)
 		netdev_wanted_features_set(dev, mask);
 	else
-		dev->wanted_features &= ~mask;
+		netdev_wanted_features_clear(dev, mask);
 
 	__netdev_update_features(dev);
 
@@ -364,11 +364,11 @@ static int __ethtool_set_flags(struct net_device *dev, u32 data)
 	/* allow changing only bits set in hw_features */
 	changed = netdev_active_features_xor(dev, features);
 	changed &= eth_all_features;
-	tmp = changed & ~dev->hw_features;
+	tmp = netdev_hw_features_andnot_r(dev, changed);
 	if (tmp)
 		return (changed & dev->hw_features) ? -EINVAL : -EOPNOTSUPP;
 
-	dev->wanted_features &= ~changed;
+	netdev_wanted_features_clear(dev, changed);
 	tmp = features & changed;
 	netdev_wanted_features_set(dev, tmp);
 
-- 
2.33.0


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [RFCv6 PATCH net-next 12/19] net: use netdev_feature_test helpers
  2022-04-19  2:21 [RFCv6 PATCH net-next 00/19] net: extend the type of netdev_features_t to bitmap Jian Shen
                   ` (10 preceding siblings ...)
  2022-04-19  2:21 ` [RFCv6 PATCH net-next 11/19] net: use netdev_features_andnot helpers Jian Shen
@ 2022-04-19  2:21 ` Jian Shen
  2022-04-19  2:22 ` [RFCv6 PATCH net-next 13/19] net: use netdev_features_intersects helpers Jian Shen
                   ` (6 subsequent siblings)
  18 siblings, 0 replies; 30+ messages in thread
From: Jian Shen @ 2022-04-19  2:21 UTC (permalink / raw)
  To: davem, kuba, andrew, ecree.xilinx, hkallweit1, alexandr.lobakin,
	saeed, leon
  Cc: netdev, linuxarm, lipeng321

Replace the '&' operations of single feature bit by
netdev_feature_test helpers.

Signed-off-by: Jian Shen <shenjian15@huawei.com>
---
 .../net/ethernet/hisilicon/hns3/hns3_enet.c   | 30 +++---
 .../ethernet/hisilicon/hns3/hns3_ethtool.c    |  4 +-
 drivers/net/ethernet/sfc/ef10.c               |  2 +-
 drivers/net/ethernet/sfc/ef100_rx.c           |  4 +-
 drivers/net/ethernet/sfc/ef100_tx.c           |  8 +-
 drivers/net/ethernet/sfc/efx_common.c         |  6 +-
 drivers/net/ethernet/sfc/falcon/efx.c         |  7 +-
 drivers/net/ethernet/sfc/falcon/rx.c          |  4 +-
 drivers/net/ethernet/sfc/farch.c              |  2 +-
 drivers/net/ethernet/sfc/mcdi_filters.c       |  4 +-
 drivers/net/ethernet/sfc/mcdi_port_common.c   |  2 +-
 drivers/net/ethernet/sfc/rx.c                 |  2 +-
 drivers/net/ethernet/sfc/rx_common.c          |  4 +-
 include/linux/netdev_features_helper.h        |  4 +-
 include/linux/netdevice.h                     | 19 ++--
 net/core/dev.c                                | 93 ++++++++++---------
 net/ethtool/ioctl.c                           | 10 +-
 17 files changed, 111 insertions(+), 94 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
index 38706313aa6c..f872a624faad 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
@@ -1503,7 +1503,8 @@ static int hns3_handle_vtags(struct hns3_enet_ring *tx_ring,
 		return -EINVAL;
 
 	if (skb->protocol == htons(ETH_P_8021Q) &&
-	    !(handle->kinfo.netdev->features & NETIF_F_HW_VLAN_CTAG_TX)) {
+	    !netdev_active_feature_test(handle->kinfo.netdev,
+					NETIF_F_HW_VLAN_CTAG_TX_BIT)) {
 		/* When HW VLAN acceleration is turned off, and the stack
 		 * sets the protocol to 802.1q, the driver just need to
 		 * set the protocol to the encapsulated ethertype.
@@ -2413,36 +2414,41 @@ static int hns3_nic_set_features(struct net_device *netdev,
 
 	changed = netdev_active_features_xor(netdev, features);
 
-	if (changed & (NETIF_F_GRO_HW) && h->ae_algo->ops->set_gro_en) {
-		enable = !!(features & NETIF_F_GRO_HW);
+	if (netdev_feature_test(NETIF_F_GRO_HW_BIT, changed) &&
+	    h->ae_algo->ops->set_gro_en) {
+		enable = netdev_feature_test(NETIF_F_GRO_HW_BIT, features);
 		ret = h->ae_algo->ops->set_gro_en(h, enable);
 		if (ret)
 			return ret;
 	}
 
-	if ((changed & NETIF_F_HW_VLAN_CTAG_RX) &&
+	if (netdev_feature_test(NETIF_F_HW_VLAN_CTAG_RX_BIT, changed) &&
 	    h->ae_algo->ops->enable_hw_strip_rxvtag) {
-		enable = !!(features & NETIF_F_HW_VLAN_CTAG_RX);
+		enable = netdev_feature_test(NETIF_F_HW_VLAN_CTAG_RX_BIT,
+					     features);
 		ret = h->ae_algo->ops->enable_hw_strip_rxvtag(h, enable);
 		if (ret)
 			return ret;
 	}
 
-	if ((changed & NETIF_F_NTUPLE) && h->ae_algo->ops->enable_fd) {
-		enable = !!(features & NETIF_F_NTUPLE);
+	if (netdev_feature_test(NETIF_F_NTUPLE_BIT, changed) &&
+	    h->ae_algo->ops->enable_fd) {
+		enable = netdev_feature_test(NETIF_F_NTUPLE_BIT, features);
 		h->ae_algo->ops->enable_fd(h, enable);
 	}
 
-	if ((netdev->features & NETIF_F_HW_TC) > (features & NETIF_F_HW_TC) &&
+	if (netdev_active_feature_test(netdev, NETIF_F_HW_TC_BIT) &&
+	    !netdev_feature_test(NETIF_F_HW_TC_BIT, features) &&
 	    h->ae_algo->ops->cls_flower_active(h)) {
 		netdev_err(netdev,
 			   "there are offloaded TC filters active, cannot disable HW TC offload");
 		return -EINVAL;
 	}
 
-	if ((changed & NETIF_F_HW_VLAN_CTAG_FILTER) &&
+	if (netdev_feature_test(NETIF_F_HW_VLAN_CTAG_FILTER_BIT, changed) &&
 	    h->ae_algo->ops->enable_vlan_filter) {
-		enable = !!(features & NETIF_F_HW_VLAN_CTAG_FILTER);
+		enable = netdev_feature_test(NETIF_F_HW_VLAN_CTAG_FILTER_BIT,
+					     features);
 		ret = h->ae_algo->ops->enable_vlan_filter(h, enable);
 		if (ret)
 			return ret;
@@ -3905,7 +3911,7 @@ static void hns3_rx_checksum(struct hns3_enet_ring *ring, struct sk_buff *skb,
 
 	skb_checksum_none_assert(skb);
 
-	if (!(netdev->features & NETIF_F_RXCSUM))
+	if (!netdev_active_feature_test(netdev, NETIF_F_RXCSUM_BIT))
 		return;
 
 	if (test_bit(HNS3_NIC_STATE_RXD_ADV_LAYOUT_ENABLE, &priv->state))
@@ -4196,7 +4202,7 @@ static void hns3_handle_rx_vlan_tag(struct hns3_enet_ring *ring,
 	 * ot_vlan_tag in two layer tag case, and stored at vlan_tag
 	 * in one layer tag case.
 	 */
-	if (netdev->features & NETIF_F_HW_VLAN_CTAG_RX) {
+	if (netdev_active_feature_test(netdev, NETIF_F_HW_VLAN_CTAG_RX_BIT)) {
 		u16 vlan_tag;
 
 		if (hns3_parse_vlan_tag(ring, desc, l234info, &vlan_tag))
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c b/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
index f4da77452126..088243621641 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
@@ -339,7 +339,7 @@ static void hns3_selftest_prepare(struct net_device *ndev,
 #if IS_ENABLED(CONFIG_VLAN_8021Q)
 	/* Disable the vlan filter for selftest does not support it */
 	if (h->ae_algo->ops->enable_vlan_filter &&
-	    ndev->features & NETIF_F_HW_VLAN_CTAG_FILTER)
+	    netdev_active_feature_test(ndev, NETIF_F_HW_VLAN_CTAG_FILTER_BIT))
 		h->ae_algo->ops->enable_vlan_filter(h, false);
 #endif
 
@@ -365,7 +365,7 @@ static void hns3_selftest_restore(struct net_device *ndev, bool if_running)
 
 #if IS_ENABLED(CONFIG_VLAN_8021Q)
 	if (h->ae_algo->ops->enable_vlan_filter &&
-	    ndev->features & NETIF_F_HW_VLAN_CTAG_FILTER)
+	    netdev_active_feature_test(ndev, NETIF_F_HW_VLAN_CTAG_FILTER_BIT))
 		h->ae_algo->ops->enable_vlan_filter(h, true);
 #endif
 
diff --git a/drivers/net/ethernet/sfc/ef10.c b/drivers/net/ethernet/sfc/ef10.c
index 0674565d9ed1..bf8274c03176 100644
--- a/drivers/net/ethernet/sfc/ef10.c
+++ b/drivers/net/ethernet/sfc/ef10.c
@@ -2703,7 +2703,7 @@ static u16 efx_ef10_handle_rx_event_errors(struct efx_channel *channel,
 	bool handled = false;
 
 	if (EFX_QWORD_FIELD(*event, ESF_DZ_RX_ECRC_ERR)) {
-		if (!(efx->net_dev->features & NETIF_F_RXALL)) {
+		if (!netdev_active_feature_test(efx->net_dev, NETIF_F_RXALL_BIT)) {
 			if (!efx->loopback_selftest)
 				channel->n_rx_eth_crc_err += n_packets;
 			return EFX_RX_PKT_DISCARD;
diff --git a/drivers/net/ethernet/sfc/ef100_rx.c b/drivers/net/ethernet/sfc/ef100_rx.c
index 85207acf7dee..cebd442c2261 100644
--- a/drivers/net/ethernet/sfc/ef100_rx.c
+++ b/drivers/net/ethernet/sfc/ef100_rx.c
@@ -64,7 +64,7 @@ void __ef100_rx_packet(struct efx_channel *channel)
 	prefix = (u32 *)(eh - ESE_GZ_RX_PKT_PREFIX_LEN);
 
 	if (ef100_has_fcs_error(channel, prefix) &&
-	    unlikely(!(efx->net_dev->features & NETIF_F_RXALL)))
+	    unlikely(!netdev_active_feature_test(efx->net_dev, NETIF_F_RXALL_BIT)))
 		goto out;
 
 	rx_buf->len = le16_to_cpu((__force __le16)PREFIX_FIELD(prefix, LENGTH));
@@ -76,7 +76,7 @@ void __ef100_rx_packet(struct efx_channel *channel)
 		goto out;
 	}
 
-	if (likely(efx->net_dev->features & NETIF_F_RXCSUM)) {
+	if (likely(netdev_active_feature_test(efx->net_dev, NETIF_F_RXCSUM_BIT))) {
 		if (PREFIX_FIELD(prefix, NT_OR_INNER_L3_CLASS) == 1) {
 			++channel->n_rx_ip_hdr_chksum_err;
 		} else {
diff --git a/drivers/net/ethernet/sfc/ef100_tx.c b/drivers/net/ethernet/sfc/ef100_tx.c
index 26ef51d6b542..4a85f53d672a 100644
--- a/drivers/net/ethernet/sfc/ef100_tx.c
+++ b/drivers/net/ethernet/sfc/ef100_tx.c
@@ -61,7 +61,7 @@ static bool ef100_tx_can_tso(struct efx_tx_queue *tx_queue, struct sk_buff *skb)
 
 	if (!skb_is_gso_tcp(skb))
 		return false;
-	if (!(efx->net_dev->features & NETIF_F_TSO))
+	if (!netdev_active_feature_test(efx->net_dev, NETIF_F_TSO_BIT))
 		return false;
 
 	mss = skb_shinfo(skb)->gso_size;
@@ -175,9 +175,9 @@ static void ef100_make_send_desc(struct efx_nic *efx,
 			     ESF_GZ_TX_SEND_LEN, buffer->len,
 			     ESF_GZ_TX_SEND_ADDR, buffer->dma_addr);
 
-	if (likely(efx->net_dev->features & NETIF_F_HW_CSUM))
+	if (likely(netdev_active_feature_test(efx->net_dev, NETIF_F_HW_CSUM_BIT)))
 		ef100_set_tx_csum_partial(skb, buffer, txd);
-	if (efx->net_dev->features & NETIF_F_HW_VLAN_CTAG_TX &&
+	if (netdev_active_feature_test(efx->net_dev, NETIF_F_HW_VLAN_CTAG_TX_BIT) &&
 	    skb && skb_vlan_tag_present(skb))
 		ef100_set_tx_hw_vlan(skb, txd);
 }
@@ -202,7 +202,7 @@ static void ef100_make_tso_desc(struct efx_nic *efx,
 
 	if (skb_shinfo(skb)->gso_type & SKB_GSO_TCP_FIXEDID)
 		mangleid = ESE_GZ_TX_DESC_IP4_ID_NO_OP;
-	if (efx->net_dev->features & NETIF_F_HW_VLAN_CTAG_TX)
+	if (netdev_active_feature_test(efx->net_dev, NETIF_F_HW_VLAN_CTAG_TX_BIT))
 		vlan_enable = skb_vlan_tag_present(skb);
 
 	len = skb->len - buffer->len;
diff --git a/drivers/net/ethernet/sfc/efx_common.c b/drivers/net/ethernet/sfc/efx_common.c
index 8b95525aad20..31363adcf5f1 100644
--- a/drivers/net/ethernet/sfc/efx_common.c
+++ b/drivers/net/ethernet/sfc/efx_common.c
@@ -217,7 +217,7 @@ int efx_set_features(struct net_device *net_dev, netdev_features_t data)
 
 	/* If disabling RX n-tuple filtering, clear existing filters */
 	tmp = netdev_active_features_andnot(net_dev, data);
-	if (tmp & NETIF_F_NTUPLE) {
+	if (netdev_feature_test(NETIF_F_NTUPLE_BIT, tmp)) {
 		rc = efx->type->filter_clear_rx(efx, EFX_FILTER_PRI_MANUAL);
 		if (rc)
 			return rc;
@@ -227,8 +227,8 @@ int efx_set_features(struct net_device *net_dev, netdev_features_t data)
 	 * If rx-fcs is changed, mac_reconfigure updates that too.
 	 */
 	tmp = netdev_active_features_xor(net_dev, data);
-	if (tmp & NETIF_F_HW_VLAN_CTAG_FILTER ||
-	    tmp & NETIF_F_RXFCS) {
+	if (netdev_feature_test(NETIF_F_HW_VLAN_CTAG_FILTER_BIT, tmp) ||
+	    netdev_feature_test(NETIF_F_RXFCS_BIT, tmp)) {
 		/* efx_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/sfc/falcon/efx.c b/drivers/net/ethernet/sfc/falcon/efx.c
index 921617de3638..52d3ced17602 100644
--- a/drivers/net/ethernet/sfc/falcon/efx.c
+++ b/drivers/net/ethernet/sfc/falcon/efx.c
@@ -1695,7 +1695,8 @@ static int ef4_probe_filters(struct ef4_nic *efx)
 		goto out_unlock;
 
 #ifdef CONFIG_RFS_ACCEL
-	if (*efx->type->offload_features & NETIF_F_NTUPLE) {
+	if (netdev_feature_test(NETIF_F_NTUPLE_BIT,
+				*efx->type->offload_features)) {
 		struct ef4_channel *channel;
 		int i, success = 1;
 
@@ -2194,7 +2195,7 @@ static int ef4_set_features(struct net_device *net_dev, netdev_features_t data)
 
 	/* If disabling RX n-tuple filtering, clear existing filters */
 	tmp = netdev_active_features_andnot(net_dev, data);
-	if (tmp & NETIF_F_NTUPLE) {
+	if (netdev_feature_test(NETIF_F_NTUPLE_BIT, tmp)) {
 		rc = efx->type->filter_clear_rx(efx, EF4_FILTER_PRI_MANUAL);
 		if (rc)
 			return rc;
@@ -2202,7 +2203,7 @@ static int ef4_set_features(struct net_device *net_dev, netdev_features_t data)
 
 	/* If Rx VLAN filter is changed, update filters via mac_reconfigure */
 	tmp = netdev_active_features_xor(net_dev, data);
-	if (tmp & NETIF_F_HW_VLAN_CTAG_FILTER) {
+	if (netdev_feature_test(NETIF_F_HW_VLAN_CTAG_FILTER_BIT, tmp)) {
 		/* ef4_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/sfc/falcon/rx.c b/drivers/net/ethernet/sfc/falcon/rx.c
index 0c6cc2191369..2b587735b4ad 100644
--- a/drivers/net/ethernet/sfc/falcon/rx.c
+++ b/drivers/net/ethernet/sfc/falcon/rx.c
@@ -443,7 +443,7 @@ ef4_rx_packet_gro(struct ef4_channel *channel, struct ef4_rx_buffer *rx_buf,
 		return;
 	}
 
-	if (efx->net_dev->features & NETIF_F_RXHASH)
+	if (netdev_active_feature_test(efx->net_dev, NETIF_F_RXHASH_BIT))
 		skb_set_hash(skb, ef4_rx_buf_hash(efx, eh),
 			     PKT_HASH_TYPE_L3);
 	skb->ip_summed = ((rx_buf->flags & EF4_RX_PKT_CSUMMED) ?
@@ -672,7 +672,7 @@ void __ef4_rx_packet(struct ef4_channel *channel)
 		goto out;
 	}
 
-	if (unlikely(!(efx->net_dev->features & NETIF_F_RXCSUM)))
+	if (unlikely(!netdev_active_feature_test(efx->net_dev, NETIF_F_RXCSUM_BIT)))
 		rx_buf->flags &= ~EF4_RX_PKT_CSUMMED;
 
 	if ((rx_buf->flags & EF4_RX_PKT_TCP) && !channel->type->receive_skb)
diff --git a/drivers/net/ethernet/sfc/farch.c b/drivers/net/ethernet/sfc/farch.c
index 148dcd48b58d..061e67724f2e 100644
--- a/drivers/net/ethernet/sfc/farch.c
+++ b/drivers/net/ethernet/sfc/farch.c
@@ -921,7 +921,7 @@ static u16 efx_farch_handle_rx_not_ok(struct efx_rx_queue *rx_queue,
 	(void) rx_ev_other_err;
 #endif
 
-	if (efx->net_dev->features & NETIF_F_RXALL)
+	if (netdev_active_feature_test(efx->net_dev, NETIF_F_RXALL_BIT))
 		/* don't discard frame for CRC error */
 		rx_ev_eth_crc_err = false;
 
diff --git a/drivers/net/ethernet/sfc/mcdi_filters.c b/drivers/net/ethernet/sfc/mcdi_filters.c
index 508549db124b..d0bb15312e28 100644
--- a/drivers/net/ethernet/sfc/mcdi_filters.c
+++ b/drivers/net/ethernet/sfc/mcdi_filters.c
@@ -1343,7 +1343,7 @@ int efx_mcdi_filter_table_probe(struct efx_nic *efx, bool multicast_chaining)
 
 	table->mc_promisc_last = false;
 	table->vlan_filter =
-		!!(efx->net_dev->features & NETIF_F_HW_VLAN_CTAG_FILTER);
+		netdev_active_feature_test(efx->net_dev, NETIF_F_HW_VLAN_CTAG_FILTER_BIT);
 	INIT_LIST_HEAD(&table->vlan_list);
 	init_rwsem(&table->lock);
 
@@ -1760,7 +1760,7 @@ void efx_mcdi_filter_sync_rx_mode(struct efx_nic *efx)
 	 * Do it in advance to avoid conflicts for unicast untagged and
 	 * VLAN 0 tagged filters.
 	 */
-	vlan_filter = !!(net_dev->features & NETIF_F_HW_VLAN_CTAG_FILTER);
+	vlan_filter = netdev_active_feature_test(net_dev, NETIF_F_HW_VLAN_CTAG_FILTER_BIT);
 	if (table->vlan_filter != vlan_filter) {
 		table->vlan_filter = vlan_filter;
 		efx_mcdi_filter_remove_old(efx);
diff --git a/drivers/net/ethernet/sfc/mcdi_port_common.c b/drivers/net/ethernet/sfc/mcdi_port_common.c
index 899cc1671004..52f24c51cdfc 100644
--- a/drivers/net/ethernet/sfc/mcdi_port_common.c
+++ b/drivers/net/ethernet/sfc/mcdi_port_common.c
@@ -1110,7 +1110,7 @@ int efx_mcdi_set_mac(struct efx_nic *efx)
 
 	MCDI_POPULATE_DWORD_1(cmdbytes, SET_MAC_IN_FLAGS,
 			      SET_MAC_IN_FLAG_INCLUDE_FCS,
-			      !!(efx->net_dev->features & NETIF_F_RXFCS));
+			      netdev_active_feature_test(efx->net_dev, NETIF_F_RXFCS_BIT));
 
 	switch (efx->wanted_fc) {
 	case EFX_FC_RX | EFX_FC_TX:
diff --git a/drivers/net/ethernet/sfc/rx.c b/drivers/net/ethernet/sfc/rx.c
index 2375cef577e4..f64ae5623309 100644
--- a/drivers/net/ethernet/sfc/rx.c
+++ b/drivers/net/ethernet/sfc/rx.c
@@ -387,7 +387,7 @@ void __efx_rx_packet(struct efx_channel *channel)
 	if (!efx_do_xdp(efx, channel, rx_buf, &eh))
 		goto out;
 
-	if (unlikely(!(efx->net_dev->features & NETIF_F_RXCSUM)))
+	if (unlikely(!netdev_active_feature_test(efx->net_dev, NETIF_F_RXCSUM_BIT)))
 		rx_buf->flags &= ~EFX_RX_PKT_CSUMMED;
 
 	if ((rx_buf->flags & EFX_RX_PKT_TCP) && !channel->type->receive_skb)
diff --git a/drivers/net/ethernet/sfc/rx_common.c b/drivers/net/ethernet/sfc/rx_common.c
index acdc3c84aaaa..ce0f78135f81 100644
--- a/drivers/net/ethernet/sfc/rx_common.c
+++ b/drivers/net/ethernet/sfc/rx_common.c
@@ -517,7 +517,7 @@ efx_rx_packet_gro(struct efx_channel *channel, struct efx_rx_buffer *rx_buf,
 		return;
 	}
 
-	if (efx->net_dev->features & NETIF_F_RXHASH &&
+	if (netdev_active_feature_test(efx->net_dev, NETIF_F_RXHASH_BIT) &&
 	    efx_rx_buf_hash_valid(efx, eh))
 		skb_set_hash(skb, efx_rx_buf_hash(efx, eh),
 			     PKT_HASH_TYPE_L3);
@@ -796,7 +796,7 @@ int efx_probe_filters(struct efx_nic *efx)
 		goto out_unlock;
 
 #ifdef CONFIG_RFS_ACCEL
-	if (*efx->type->offload_features & NETIF_F_NTUPLE) {
+	if (netdev_feature_test(NETIF_F_NTUPLE_BIT, *efx->type->offload_features)) {
 		struct efx_channel *channel;
 		int i, success = 1;
 
diff --git a/include/linux/netdev_features_helper.h b/include/linux/netdev_features_helper.h
index 067b90ca3084..56bdec209b1c 100644
--- a/include/linux/netdev_features_helper.h
+++ b/include/linux/netdev_features_helper.h
@@ -588,8 +588,8 @@ static inline netdev_features_t netdev_intersect_features(netdev_features_t f1,
 	netdev_features_t tmp;
 
 	tmp = netdev_features_xor(f1, f2);
-	if (tmp & NETIF_F_HW_CSUM) {
-		if (f1 & NETIF_F_HW_CSUM)
+	if (netdev_feature_test(NETIF_F_HW_CSUM_BIT, tmp)) {
+		if (netdev_feature_test(NETIF_F_HW_CSUM_BIT, f1))
 			netdev_features_set(&f1, netdev_ip_csum_features);
 		else
 			netdev_features_set(&f2, netdev_ip_csum_features);
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index a092423653e2..91983aede92c 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -2333,7 +2333,7 @@ static inline bool netdev_feature_test(int nr, const netdev_features_t src)
 
 static inline bool netif_elide_gro(const struct net_device *dev)
 {
-	if (!(dev->features & NETIF_F_GRO) || dev->xdp_prog)
+	if (!netdev_active_feature_test(dev, NETIF_F_GRO_BIT) || dev->xdp_prog)
 		return true;
 	return false;
 }
@@ -4354,7 +4354,7 @@ static inline void netif_tx_unlock_bh(struct net_device *dev)
 }
 
 #define HARD_TX_LOCK(dev, txq, cpu) {			\
-	if ((dev->features & NETIF_F_LLTX) == 0) {	\
+	if (!netdev_active_feature_test(dev, NETIF_F_LLTX_BIT)) {	\
 		__netif_tx_lock(txq, cpu);		\
 	} else {					\
 		__netif_tx_acquire(txq);		\
@@ -4362,12 +4362,12 @@ static inline void netif_tx_unlock_bh(struct net_device *dev)
 }
 
 #define HARD_TX_TRYLOCK(dev, txq)			\
-	(((dev->features & NETIF_F_LLTX) == 0) ?	\
+	(!netdev_active_feature_test(dev, NETIF_F_LLTX_BIT) ?	\
 		__netif_tx_trylock(txq) :		\
 		__netif_tx_acquire(txq))
 
 #define HARD_TX_UNLOCK(dev, txq) {			\
-	if ((dev->features & NETIF_F_LLTX) == 0) {	\
+	if (!netdev_active_feature_test(dev, NETIF_F_LLTX_BIT)) {	\
 		__netif_tx_unlock(txq);			\
 	} else {					\
 		__netif_tx_release(txq);		\
@@ -4768,20 +4768,20 @@ static inline bool can_checksum_protocol(netdev_features_t features,
 					 __be16 protocol)
 {
 	if (protocol == htons(ETH_P_FCOE))
-		return !!(features & NETIF_F_FCOE_CRC);
+		return netdev_feature_test(NETIF_F_FCOE_CRC_BIT, features);
 
 	/* Assume this is an IP checksum (not SCTP CRC) */
 
-	if (features & NETIF_F_HW_CSUM) {
+	if (netdev_feature_test(NETIF_F_HW_CSUM_BIT, features)) {
 		/* Can checksum everything */
 		return true;
 	}
 
 	switch (protocol) {
 	case htons(ETH_P_IP):
-		return !!(features & NETIF_F_IP_CSUM);
+		return netdev_feature_test(NETIF_F_IP_CSUM_BIT, features);
 	case htons(ETH_P_IPV6):
-		return !!(features & NETIF_F_IPV6_CSUM);
+		return netdev_feature_test(NETIF_F_IPV6_CSUM_BIT, features);
 	default:
 		return false;
 	}
@@ -4898,7 +4898,8 @@ static inline bool net_gso_ok(netdev_features_t features, int gso_type)
 static inline bool skb_gso_ok(struct sk_buff *skb, netdev_features_t features)
 {
 	return net_gso_ok(features, skb_shinfo(skb)->gso_type) &&
-	       (!skb_has_frag_list(skb) || (features & NETIF_F_FRAGLIST));
+	       (!skb_has_frag_list(skb) ||
+	       netdev_feature_test(NETIF_F_FRAGLIST_BIT, features));
 }
 
 static inline bool netif_needs_gso(struct sk_buff *skb,
diff --git a/net/core/dev.c b/net/core/dev.c
index 124d48b5d61a..2bcb65722583 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -1586,7 +1586,7 @@ void dev_disable_lro(struct net_device *dev)
 	netdev_wanted_feature_del(dev, NETIF_F_LRO_BIT);
 	netdev_update_features(dev);
 
-	if (unlikely(dev->features & NETIF_F_LRO))
+	if (unlikely(netdev_active_feature_test(dev, NETIF_F_LRO_BIT)))
 		netdev_WARN(dev, "failed to disable LRO!\n");
 
 	netdev_for_each_lower_dev(dev, lower_dev, iter)
@@ -1607,7 +1607,7 @@ static void dev_disable_gro_hw(struct net_device *dev)
 	netdev_wanted_feature_del(dev, NETIF_F_GRO_HW_BIT);
 	netdev_update_features(dev);
 
-	if (unlikely(dev->features & NETIF_F_GRO_HW))
+	if (unlikely(netdev_active_feature_test(dev, NETIF_F_GRO_HW_BIT)))
 		netdev_WARN(dev, "failed to disable GRO_HW!\n");
 }
 
@@ -3339,7 +3339,7 @@ struct sk_buff *__skb_gso_segment(struct sk_buff *skb,
 	 * support segmentation on this frame without needing additional
 	 * work.
 	 */
-	if (features & NETIF_F_GSO_PARTIAL) {
+	if (netdev_feature_test(NETIF_F_GSO_PARTIAL_BIT, features)) {
 		netdev_features_t partial_features;
 		struct net_device *dev = skb->dev;
 
@@ -3389,7 +3389,7 @@ static int illegal_highdma(struct net_device *dev, struct sk_buff *skb)
 #ifdef CONFIG_HIGHMEM
 	int i;
 
-	if (!(dev->features & NETIF_F_HIGHDMA)) {
+	if (!netdev_active_feature_test(dev, NETIF_F_HIGHDMA_BIT)) {
 		for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
 			skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
 
@@ -3587,10 +3587,10 @@ int skb_csum_hwoffload_help(struct sk_buff *skb,
 			    const netdev_features_t features)
 {
 	if (unlikely(skb_csum_is_sctp(skb)))
-		return !!(features & NETIF_F_SCTP_CRC) ? 0 :
+		return netdev_feature_test(NETIF_F_SCTP_CRC_BIT, features) ? 0 :
 			skb_crc32c_csum_help(skb);
 
-	if (features & NETIF_F_HW_CSUM)
+	if (netdev_feature_test(NETIF_F_HW_CSUM_BIT, features))
 		return 0;
 
 	if (features & netdev_ip_csum_features) {
@@ -4343,7 +4343,7 @@ set_rps_cpu(struct net_device *dev, struct sk_buff *skb,
 
 		/* Should we steer this flow to a different hardware queue? */
 		if (!skb_rx_queue_recorded(skb) || !dev->rx_cpu_rmap ||
-		    !(dev->features & NETIF_F_NTUPLE))
+		    !netdev_active_feature_test(dev, NETIF_F_NTUPLE_BIT))
 			goto out;
 		rxq_index = cpu_rmap_lookup_index(dev->rx_cpu_rmap, next_cpu);
 		if (rxq_index == skb_get_rx_queue(skb))
@@ -9503,89 +9503,94 @@ static netdev_features_t netdev_fix_features(struct net_device *dev,
 	netdev_features_t tmp;
 
 	/* Fix illegal checksum combinations */
-	if ((features & NETIF_F_HW_CSUM) &&
+	if (netdev_feature_test(NETIF_F_HW_CSUM_BIT, features) &&
 	    (features & netdev_ip_csum_features)) {
 		netdev_warn(dev, "mixed HW and IP checksum settings.\n");
 		netdev_features_clear(&features, netdev_ip_csum_features);
 	}
 
 	/* TSO requires that SG is present as well. */
-	if ((features & NETIF_F_ALL_TSO) && !(features & NETIF_F_SG)) {
+	if (features & NETIF_F_ALL_TSO && !netdev_feature_test(NETIF_F_SG_BIT, features)) {
 		netdev_dbg(dev, "Dropping TSO features since no SG feature.\n");
 		netdev_features_clear(&features, NETIF_F_ALL_TSO);
 	}
 
-	if ((features & NETIF_F_TSO) && !(features & NETIF_F_HW_CSUM) &&
-					!(features & NETIF_F_IP_CSUM)) {
+	if (netdev_feature_test(NETIF_F_TSO_BIT, features) &&
+	    !netdev_feature_test(NETIF_F_HW_CSUM_BIT, features) &&
+	    !netdev_feature_test(NETIF_F_IP_CSUM_BIT, features)) {
 		netdev_dbg(dev, "Dropping TSO features since no CSUM feature.\n");
 		netdev_feature_del(NETIF_F_TSO_BIT, &features);
 		netdev_feature_del(NETIF_F_TSO_ECN_BIT, &features);
 	}
 
-	if ((features & NETIF_F_TSO6) && !(features & NETIF_F_HW_CSUM) &&
-					 !(features & NETIF_F_IPV6_CSUM)) {
+	if (netdev_feature_test(NETIF_F_TSO6_BIT, features) &&
+	    !netdev_feature_test(NETIF_F_HW_CSUM_BIT, features) &&
+	    !netdev_feature_test(NETIF_F_IPV6_CSUM_BIT, features)) {
 		netdev_dbg(dev, "Dropping TSO6 features since no CSUM feature.\n");
 		netdev_feature_del(NETIF_F_TSO6_BIT, &features);
 	}
 
 	/* TSO with IPv4 ID mangling requires IPv4 TSO be enabled */
-	if ((features & NETIF_F_TSO_MANGLEID) && !(features & NETIF_F_TSO))
+	if (netdev_feature_test(NETIF_F_TSO_MANGLEID_BIT, features) &&
+	    !netdev_feature_test(NETIF_F_TSO_BIT, features))
 		netdev_feature_del(NETIF_F_TSO_MANGLEID_BIT, &features);
 
 	/* TSO ECN requires that TSO is present as well. */
 	tmp = NETIF_F_ALL_TSO;
 	netdev_feature_del(NETIF_F_TSO_ECN_BIT, &tmp);
-	if (!(features & tmp) && (features & NETIF_F_TSO_ECN))
+	if (!(features & tmp) && netdev_feature_test(NETIF_F_TSO_ECN_BIT, features))
 		netdev_feature_del(NETIF_F_TSO_ECN_BIT, &features);
 
 	/* Software GSO depends on SG. */
-	if ((features & NETIF_F_GSO) && !(features & NETIF_F_SG)) {
+	if ((netdev_feature_test(NETIF_F_GSO_BIT, features)) && !(netdev_feature_test(NETIF_F_SG_BIT, features))) {
 		netdev_dbg(dev, "Dropping NETIF_F_GSO since no SG feature.\n");
 		netdev_feature_del(NETIF_F_GSO_BIT, &features);
 	}
 
 	/* GSO partial features require GSO partial be set */
 	if ((features & dev->gso_partial_features) &&
-	    !(features & NETIF_F_GSO_PARTIAL)) {
+	    !netdev_feature_test(NETIF_F_GSO_PARTIAL_BIT, features)) {
 		netdev_dbg(dev,
 			   "Dropping partially supported GSO features since no GSO partial.\n");
 		netdev_features_clear(&features, dev->gso_partial_features);
 	}
 
-	if (!(features & NETIF_F_RXCSUM)) {
+	if (!netdev_feature_test(NETIF_F_RXCSUM_BIT, features)) {
 		/* NETIF_F_GRO_HW implies doing RXCSUM since every packet
 		 * successfully merged by hardware must also have the
 		 * checksum verified by hardware.  If the user does not
 		 * want to enable RXCSUM, logically, we should disable GRO_HW.
 		 */
-		if (features & NETIF_F_GRO_HW) {
+		if (netdev_feature_test(NETIF_F_GRO_HW_BIT, features)) {
 			netdev_dbg(dev, "Dropping NETIF_F_GRO_HW since no RXCSUM feature.\n");
 			netdev_feature_del(NETIF_F_GRO_HW_BIT, &features);
 		}
 	}
 
 	/* LRO/HW-GRO features cannot be combined with RX-FCS */
-	if (features & NETIF_F_RXFCS) {
-		if (features & NETIF_F_LRO) {
+	if (netdev_feature_test(NETIF_F_RXFCS_BIT, features)) {
+		if (netdev_feature_test(NETIF_F_LRO_BIT, features)) {
 			netdev_dbg(dev, "Dropping LRO feature since RX-FCS is requested.\n");
 			netdev_feature_del(NETIF_F_LRO_BIT, &features);
 		}
 
-		if (features & NETIF_F_GRO_HW) {
+		if (netdev_feature_test(NETIF_F_GRO_HW_BIT, features)) {
 			netdev_dbg(dev, "Dropping HW-GRO feature since RX-FCS is requested.\n");
 			netdev_feature_del(NETIF_F_GRO_HW_BIT, &features);
 		}
 	}
 
-	if ((features & NETIF_F_GRO_HW) && (features & NETIF_F_LRO)) {
+	if (netdev_feature_test(NETIF_F_GRO_HW_BIT, features) &&
+	    netdev_feature_test(NETIF_F_LRO_BIT, features)) {
 		netdev_dbg(dev, "Dropping LRO feature since HW-GRO is requested.\n");
 		netdev_feature_del(NETIF_F_LRO_BIT, &features);
 	}
 
-	if (features & NETIF_F_HW_TLS_TX) {
+	if (netdev_feature_test(NETIF_F_HW_TLS_TX_BIT, features)) {
 		bool ip_csum = (features & netdev_ip_csum_features) ==
 			netdev_ip_csum_features;
-		bool hw_csum = features & NETIF_F_HW_CSUM;
+		bool hw_csum = netdev_feature_test(NETIF_F_HW_CSUM_BIT,
+						   features);
 
 		if (!ip_csum && !hw_csum) {
 			netdev_dbg(dev, "Dropping TLS TX HW offload feature since no CSUM feature.\n");
@@ -9593,7 +9598,8 @@ static netdev_features_t netdev_fix_features(struct net_device *dev,
 		}
 	}
 
-	if ((features & NETIF_F_HW_TLS_RX) && !(features & NETIF_F_RXCSUM)) {
+	if (netdev_feature_test(NETIF_F_HW_TLS_RX_BIT, features) &&
+	    !netdev_feature_test(NETIF_F_RXCSUM_BIT, features)) {
 		netdev_dbg(dev, "Dropping TLS RX HW offload feature since no RXCSUM feature.\n");
 		netdev_feature_del(NETIF_F_HW_TLS_RX_BIT, &features);
 	}
@@ -9655,7 +9661,7 @@ int __netdev_update_features(struct net_device *dev)
 
 		diff = netdev_features_xor(features, dev->features);
 
-		if (diff & NETIF_F_RX_UDP_TUNNEL_PORT) {
+		if (netdev_feature_test(NETIF_F_RX_UDP_TUNNEL_PORT_BIT, diff)) {
 			/* udp_tunnel_{get,drop}_rx_info both need
 			 * NETIF_F_RX_UDP_TUNNEL_PORT enabled on the
 			 * device, or they won't do anything.
@@ -9663,7 +9669,8 @@ int __netdev_update_features(struct net_device *dev)
 			 * *before* calling udp_tunnel_get_rx_info,
 			 * but *after* calling udp_tunnel_drop_rx_info.
 			 */
-			if (features & NETIF_F_RX_UDP_TUNNEL_PORT) {
+			if (netdev_feature_test(NETIF_F_RX_UDP_TUNNEL_PORT_BIT,
+						features)) {
 				dev->features = features;
 				udp_tunnel_get_rx_info(dev);
 			} else {
@@ -9671,8 +9678,9 @@ int __netdev_update_features(struct net_device *dev)
 			}
 		}
 
-		if (diff & NETIF_F_HW_VLAN_CTAG_FILTER) {
-			if (features & NETIF_F_HW_VLAN_CTAG_FILTER) {
+		if (netdev_feature_test(NETIF_F_HW_VLAN_CTAG_FILTER_BIT, diff)) {
+			if (netdev_feature_test(NETIF_F_HW_VLAN_CTAG_FILTER_BIT,
+						features)) {
 				dev->features = features;
 				err |= vlan_get_rx_ctag_filter_info(dev);
 			} else {
@@ -9680,8 +9688,9 @@ int __netdev_update_features(struct net_device *dev)
 			}
 		}
 
-		if (diff & NETIF_F_HW_VLAN_STAG_FILTER) {
-			if (features & NETIF_F_HW_VLAN_STAG_FILTER) {
+		if (netdev_feature_test(NETIF_F_HW_VLAN_STAG_FILTER_BIT, diff)) {
+			if (netdev_feature_test(NETIF_F_HW_VLAN_STAG_FILTER_BIT,
+						features)) {
 				dev->features = features;
 				err |= vlan_get_rx_stag_filter_info(dev);
 			} else {
@@ -9915,8 +9924,8 @@ int register_netdevice(struct net_device *dev)
 		}
 	}
 
-	if ((dev->hw_features & NETIF_F_HW_VLAN_CTAG_FILTER ||
-	     dev->features & NETIF_F_HW_VLAN_CTAG_FILTER) &&
+	if ((netdev_hw_feature_test(dev, NETIF_F_HW_VLAN_CTAG_FILTER_BIT) ||
+	     netdev_active_feature_test(dev, NETIF_F_HW_VLAN_CTAG_FILTER_BIT)) &&
 	    (!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");
@@ -9952,13 +9961,13 @@ int register_netdevice(struct net_device *dev)
 	 * of ignoring a static IP ID value.  This doesn't enable the
 	 * feature itself but allows the user to enable it later.
 	 */
-	if (dev->hw_features & NETIF_F_TSO)
+	if (netdev_hw_feature_test(dev, NETIF_F_TSO_BIT))
 		netdev_hw_feature_add(dev, NETIF_F_TSO_MANGLEID_BIT);
-	if (dev->vlan_features & NETIF_F_TSO)
+	if (netdev_vlan_feature_test(dev, NETIF_F_TSO_BIT))
 		netdev_vlan_feature_add(dev, NETIF_F_TSO_MANGLEID_BIT);
-	if (dev->mpls_features & NETIF_F_TSO)
+	if (netdev_mpls_feature_test(dev, NETIF_F_TSO_BIT))
 		netdev_mpls_feature_add(dev, NETIF_F_TSO_MANGLEID_BIT);
-	if (dev->hw_enc_features & NETIF_F_TSO)
+	if (netdev_hw_enc_feature_test(dev, NETIF_F_TSO_BIT))
 		netdev_hw_enc_feature_add(dev, NETIF_F_TSO_MANGLEID_BIT);
 
 	/* Make NETIF_F_HIGHDMA inheritable to VLAN devices.
@@ -10859,7 +10868,7 @@ int __dev_change_net_namespace(struct net_device *dev, struct net *net,
 
 	/* Don't allow namespace local devices to be moved. */
 	err = -EINVAL;
-	if (dev->features & NETIF_F_NETNS_LOCAL)
+	if (netdev_active_feature_test(dev, NETIF_F_NETNS_LOCAL_BIT))
 		goto out;
 
 	/* Ensure the device has been registrered */
@@ -11057,7 +11066,7 @@ netdev_features_t netdev_increment_features(netdev_features_t all,
 {
 	netdev_features_t tmp;
 
-	if (mask & NETIF_F_HW_CSUM)
+	if (netdev_feature_test(NETIF_F_HW_CSUM_BIT, mask))
 		netdev_features_set(&mask, NETIF_F_CSUM_MASK);
 	netdev_feature_add(NETIF_F_VLAN_CHALLENGED_BIT, &mask);
 
@@ -11072,7 +11081,7 @@ netdev_features_t netdev_increment_features(netdev_features_t all,
 	all &= tmp;
 
 	/* If one device supports hw checksumming, set for all. */
-	if (all & NETIF_F_HW_CSUM) {
+	if (netdev_feature_test(NETIF_F_HW_CSUM_BIT, all)) {
 		tmp = NETIF_F_CSUM_MASK;
 		netdev_feature_del(NETIF_F_HW_CSUM_BIT, &tmp);
 		netdev_features_clear(&all, tmp);
@@ -11230,7 +11239,7 @@ static void __net_exit default_device_exit_net(struct net *net)
 		char fb_name[IFNAMSIZ];
 
 		/* Ignore unmoveable devices (i.e. loopback) */
-		if (dev->features & NETIF_F_NETNS_LOCAL)
+		if (netdev_active_feature_test(dev, NETIF_F_NETNS_LOCAL_BIT))
 			continue;
 
 		/* Leave virtual devices for the generic cleanup */
diff --git a/net/ethtool/ioctl.c b/net/ethtool/ioctl.c
index 3c951a883076..77f57fe00160 100644
--- a/net/ethtool/ioctl.c
+++ b/net/ethtool/ioctl.c
@@ -322,15 +322,15 @@ static u32 __ethtool_get_flags(struct net_device *dev)
 {
 	u32 flags = 0;
 
-	if (dev->features & NETIF_F_LRO)
+	if (netdev_active_feature_test(dev, NETIF_F_LRO_BIT))
 		flags |= ETH_FLAG_LRO;
-	if (dev->features & NETIF_F_HW_VLAN_CTAG_RX)
+	if (netdev_active_feature_test(dev, NETIF_F_HW_VLAN_CTAG_RX_BIT))
 		flags |= ETH_FLAG_RXVLAN;
-	if (dev->features & NETIF_F_HW_VLAN_CTAG_TX)
+	if (netdev_active_feature_test(dev, NETIF_F_HW_VLAN_CTAG_TX_BIT))
 		flags |= ETH_FLAG_TXVLAN;
-	if (dev->features & NETIF_F_NTUPLE)
+	if (netdev_active_feature_test(dev, NETIF_F_NTUPLE_BIT))
 		flags |= ETH_FLAG_NTUPLE;
-	if (dev->features & NETIF_F_RXHASH)
+	if (netdev_active_feature_test(dev, NETIF_F_RXHASH_BIT))
 		flags |= ETH_FLAG_RXHASH;
 
 	return flags;
-- 
2.33.0


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [RFCv6 PATCH net-next 13/19] net: use netdev_features_intersects helpers
  2022-04-19  2:21 [RFCv6 PATCH net-next 00/19] net: extend the type of netdev_features_t to bitmap Jian Shen
                   ` (11 preceding siblings ...)
  2022-04-19  2:21 ` [RFCv6 PATCH net-next 12/19] net: use netdev_feature_test helpers Jian Shen
@ 2022-04-19  2:22 ` Jian Shen
  2022-04-19  2:22 ` [RFCv6 PATCH net-next 14/19] net: use netdev_features_and helpers Jian Shen
                   ` (5 subsequent siblings)
  18 siblings, 0 replies; 30+ messages in thread
From: Jian Shen @ 2022-04-19  2:22 UTC (permalink / raw)
  To: davem, kuba, andrew, ecree.xilinx, hkallweit1, alexandr.lobakin,
	saeed, leon
  Cc: netdev, linuxarm, lipeng321

Replace the '(f1 & f2)' operations of features by
netdev_features_intersects helpers.

Signed-off-by: Jian Shen <shenjian15@huawei.com>
---
 drivers/net/ethernet/sfc/efx_common.c |  4 ++--
 net/core/dev.c                        | 21 ++++++++++++---------
 net/ethtool/ioctl.c                   |  6 +++---
 3 files changed, 17 insertions(+), 14 deletions(-)

diff --git a/drivers/net/ethernet/sfc/efx_common.c b/drivers/net/ethernet/sfc/efx_common.c
index 31363adcf5f1..769f3a8b3ff9 100644
--- a/drivers/net/ethernet/sfc/efx_common.c
+++ b/drivers/net/ethernet/sfc/efx_common.c
@@ -1364,14 +1364,14 @@ netdev_features_t efx_features_check(struct sk_buff *skb, struct net_device *dev
 	struct efx_nic *efx = netdev_priv(dev);
 
 	if (skb->encapsulation) {
-		if (features & NETIF_F_GSO_MASK)
+		if (netdev_features_intersects(features, NETIF_F_GSO_MASK))
 			/* Hardware can only do TSO with at most 208 bytes
 			 * of headers.
 			 */
 			if (skb_inner_transport_offset(skb) >
 			    EFX_TSO2_MAX_HDRLEN)
 				netdev_features_clear(&features, NETIF_F_GSO_MASK);
-		if (features & netdev_csum_gso_features_mask)
+		if (netdev_features_intersects(features, netdev_csum_gso_features_mask))
 			if (!efx_can_encap_offloads(efx, skb))
 				netdev_features_clear(&features,
 						      netdev_csum_gso_features_mask);
diff --git a/net/core/dev.c b/net/core/dev.c
index 2bcb65722583..a83c2dcda755 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -3593,7 +3593,7 @@ int skb_csum_hwoffload_help(struct sk_buff *skb,
 	if (netdev_feature_test(NETIF_F_HW_CSUM_BIT, features))
 		return 0;
 
-	if (features & netdev_ip_csum_features) {
+	if (netdev_features_intersects(features, netdev_ip_csum_features)) {
 		switch (skb->csum_offset) {
 		case offsetof(struct tcphdr, check):
 		case offsetof(struct udphdr, check):
@@ -9461,8 +9461,8 @@ static netdev_features_t netdev_sync_upper_features(struct net_device *lower,
 	upper_disables = NETIF_F_UPPER_DISABLES;
 	for_each_netdev_feature(upper_disables, feature_bit) {
 		feature = __NETIF_F_BIT(feature_bit);
-		if (!(upper->wanted_features & feature)
-		    && (features & feature)) {
+		if (!netdev_wanted_features_intersects(upper, feature) &&
+		    netdev_features_intersects(features, feature)) {
 			netdev_dbg(lower, "Dropping feature %pNF, upper dev %s has it off.\n",
 				   &feature, upper->name);
 			netdev_features_clear(&features, feature);
@@ -9482,13 +9482,14 @@ static void netdev_sync_lower_features(struct net_device *upper,
 	upper_disables = NETIF_F_UPPER_DISABLES;
 	for_each_netdev_feature(upper_disables, feature_bit) {
 		feature = __NETIF_F_BIT(feature_bit);
-		if (!(features & feature) && (lower->features & feature)) {
+		if (!netdev_features_intersects(features, feature) &&
+		    netdev_active_features_intersects(lower, feature)) {
 			netdev_dbg(upper, "Disabling feature %pNF on lower dev %s.\n",
 				   &feature, lower->name);
 			netdev_wanted_features_clear(lower, feature);
 			__netdev_update_features(lower);
 
-			if (unlikely(lower->features & feature))
+			if (unlikely(netdev_active_features_intersects(lower, feature)))
 				netdev_WARN(upper, "failed to disable %pNF on %s!\n",
 					    &feature, lower->name);
 			else
@@ -9504,13 +9505,14 @@ static netdev_features_t netdev_fix_features(struct net_device *dev,
 
 	/* Fix illegal checksum combinations */
 	if (netdev_feature_test(NETIF_F_HW_CSUM_BIT, features) &&
-	    (features & netdev_ip_csum_features)) {
+	    netdev_features_intersects(features, netdev_ip_csum_features)) {
 		netdev_warn(dev, "mixed HW and IP checksum settings.\n");
 		netdev_features_clear(&features, netdev_ip_csum_features);
 	}
 
 	/* TSO requires that SG is present as well. */
-	if (features & NETIF_F_ALL_TSO && !netdev_feature_test(NETIF_F_SG_BIT, features)) {
+	if (netdev_features_intersects(features, NETIF_F_ALL_TSO) &&
+	    !netdev_feature_test(NETIF_F_SG_BIT, features)) {
 		netdev_dbg(dev, "Dropping TSO features since no SG feature.\n");
 		netdev_features_clear(&features, NETIF_F_ALL_TSO);
 	}
@@ -9538,7 +9540,8 @@ static netdev_features_t netdev_fix_features(struct net_device *dev,
 	/* TSO ECN requires that TSO is present as well. */
 	tmp = NETIF_F_ALL_TSO;
 	netdev_feature_del(NETIF_F_TSO_ECN_BIT, &tmp);
-	if (!(features & tmp) && netdev_feature_test(NETIF_F_TSO_ECN_BIT, features))
+	if (!netdev_features_intersects(features, tmp) &&
+	    netdev_feature_test(NETIF_F_TSO_ECN_BIT, features))
 		netdev_feature_del(NETIF_F_TSO_ECN_BIT, &features);
 
 	/* Software GSO depends on SG. */
@@ -9548,7 +9551,7 @@ static netdev_features_t netdev_fix_features(struct net_device *dev,
 	}
 
 	/* GSO partial features require GSO partial be set */
-	if ((features & dev->gso_partial_features) &&
+	if (netdev_gso_partial_features_intersects(dev, features) &&
 	    !netdev_feature_test(NETIF_F_GSO_PARTIAL_BIT, features)) {
 		netdev_dbg(dev,
 			   "Dropping partially supported GSO features since no GSO partial.\n");
diff --git a/net/ethtool/ioctl.c b/net/ethtool/ioctl.c
index 77f57fe00160..3fd1aa89de87 100644
--- a/net/ethtool/ioctl.c
+++ b/net/ethtool/ioctl.c
@@ -165,7 +165,7 @@ static int ethtool_set_features(struct net_device *dev, void __user *useraddr)
 	__netdev_update_features(dev);
 
 	tmp = netdev_wanted_features_xor(dev, dev->features);
-	if (tmp & valid)
+	if (netdev_features_intersects(tmp, valid))
 		ret |= ETHTOOL_F_WISH;
 
 	return ret;
@@ -278,7 +278,7 @@ static int ethtool_get_one_feature(struct net_device *dev,
 	};
 
 	mask = ethtool_get_feature_mask(ethcmd);
-	edata.data = !!(dev->features & mask);
+	edata.data = !!netdev_active_features_intersects(dev, mask);
 	if (copy_to_user(useraddr, &edata, sizeof(edata)))
 		return -EFAULT;
 	return 0;
@@ -366,7 +366,7 @@ static int __ethtool_set_flags(struct net_device *dev, u32 data)
 	changed &= eth_all_features;
 	tmp = netdev_hw_features_andnot_r(dev, changed);
 	if (tmp)
-		return (changed & dev->hw_features) ? -EINVAL : -EOPNOTSUPP;
+		return netdev_hw_features_intersects(dev, changed) ? -EINVAL : -EOPNOTSUPP;
 
 	netdev_wanted_features_clear(dev, changed);
 	tmp = features & changed;
-- 
2.33.0


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [RFCv6 PATCH net-next 14/19] net: use netdev_features_and helpers
  2022-04-19  2:21 [RFCv6 PATCH net-next 00/19] net: extend the type of netdev_features_t to bitmap Jian Shen
                   ` (12 preceding siblings ...)
  2022-04-19  2:22 ` [RFCv6 PATCH net-next 13/19] net: use netdev_features_intersects helpers Jian Shen
@ 2022-04-19  2:22 ` Jian Shen
  2022-04-19  2:22 ` [RFCv6 PATCH net-next 15/19] net: use netdev_features_subset helpers Jian Shen
                   ` (4 subsequent siblings)
  18 siblings, 0 replies; 30+ messages in thread
From: Jian Shen @ 2022-04-19  2:22 UTC (permalink / raw)
  To: davem, kuba, andrew, ecree.xilinx, hkallweit1, alexandr.lobakin,
	saeed, leon
  Cc: netdev, linuxarm, lipeng321

Replace the '&' and '&=' operations of features by
netdev_features_and helpers.

Signed-off-by: Jian Shen <shenjian15@huawei.com>
---
 include/linux/netdev_features_helper.h |  2 +-
 net/core/dev.c                         | 18 ++++++++++--------
 net/ethtool/features.c                 |  3 ++-
 net/ethtool/ioctl.c                    | 10 +++++-----
 4 files changed, 18 insertions(+), 15 deletions(-)

diff --git a/include/linux/netdev_features_helper.h b/include/linux/netdev_features_helper.h
index 56bdec209b1c..79fa490b96cf 100644
--- a/include/linux/netdev_features_helper.h
+++ b/include/linux/netdev_features_helper.h
@@ -595,7 +595,7 @@ static inline netdev_features_t netdev_intersect_features(netdev_features_t f1,
 			netdev_features_set(&f2, netdev_ip_csum_features);
 	}
 
-	return f1 & f2;
+	return netdev_features_and(f1, f2);
 }
 
 static inline netdev_features_t
diff --git a/net/core/dev.c b/net/core/dev.c
index a83c2dcda755..7f75084bcaa7 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -3343,7 +3343,8 @@ struct sk_buff *__skb_gso_segment(struct sk_buff *skb,
 		netdev_features_t partial_features;
 		struct net_device *dev = skb->dev;
 
-		partial_features = dev->features & dev->gso_partial_features;
+		partial_features = netdev_active_features_and(dev,
+							      dev->gso_partial_features);
 		netdev_feature_add(NETIF_F_GSO_ROBUST_BIT, &partial_features);
 		if (!skb_gso_ok(skb, netdev_features_or(features, partial_features)))
 			netdev_feature_del(NETIF_F_GSO_PARTIAL_BIT, &features);
@@ -3410,7 +3411,7 @@ static netdev_features_t net_mpls_features(struct sk_buff *skb,
 					   __be16 type)
 {
 	if (eth_p_mpls(type))
-		features &= skb->dev->mpls_features;
+		netdev_features_mask(&features, skb->dev->mpls_features);
 
 	return features;
 }
@@ -3511,7 +3512,7 @@ netdev_features_t netif_skb_features(struct sk_buff *skb)
 	 * features for the netdev
 	 */
 	if (skb->encapsulation)
-		features &= dev->hw_enc_features;
+		netdev_features_mask(&features, dev->hw_enc_features);
 
 	if (skb_vlan_tagged(skb)) {
 		tmp = netdev_vlan_features_or(dev, netdev_tx_vlan_features);
@@ -3522,7 +3523,7 @@ netdev_features_t netif_skb_features(struct sk_buff *skb)
 		tmp = dev->netdev_ops->ndo_features_check(skb, dev, features);
 	else
 		tmp = dflt_features_check(skb, dev, features);
-	features &= tmp;
+	netdev_features_mask(&features, tmp);
 
 	return harmonize_features(skb, features);
 }
@@ -9954,7 +9955,8 @@ int register_netdevice(struct net_device *dev)
 		netdev_hw_feature_add(dev, NETIF_F_RX_UDP_TUNNEL_PORT_BIT);
 	}
 
-	dev->wanted_features = dev->features & dev->hw_features;
+	dev->wanted_features = netdev_active_features_and(dev,
+							  dev->hw_features);
 
 	if (!(dev->flags & IFF_LOOPBACK))
 		netdev_hw_feature_add(dev, NETIF_F_NOCACHE_COPY_BIT);
@@ -11074,14 +11076,14 @@ netdev_features_t netdev_increment_features(netdev_features_t all,
 	netdev_feature_add(NETIF_F_VLAN_CHALLENGED_BIT, &mask);
 
 	tmp = netdev_features_or(NETIF_F_ONE_FOR_ALL, NETIF_F_CSUM_MASK);
-	tmp &= one;
-	tmp &= mask;
+	netdev_features_mask(&tmp, one);
+	netdev_features_mask(&tmp, mask);
 	netdev_features_set(&all, tmp);
 
 	netdev_features_fill(&tmp);
 	netdev_features_clear(&tmp, NETIF_F_ALL_FOR_ALL);
 	netdev_features_set(&tmp, one);
-	all &= tmp;
+	netdev_features_mask(&all, tmp);
 
 	/* If one device supports hw checksumming, set for all. */
 	if (netdev_feature_test(NETIF_F_HW_CSUM_BIT, all)) {
diff --git a/net/ethtool/features.c b/net/ethtool/features.c
index 2de4cabf41e0..c4d7a1f9366a 100644
--- a/net/ethtool/features.c
+++ b/net/ethtool/features.c
@@ -257,7 +257,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)) {
 		netdev_wanted_features_clear(dev, dev->hw_features);
-		tmp = ethnl_bitmap_to_features(req_wanted) & dev->hw_features;
+		tmp = netdev_hw_features_and(dev,
+					     ethnl_bitmap_to_features(req_wanted));
 		netdev_wanted_features_set(dev, tmp);
 		__netdev_update_features(dev);
 	}
diff --git a/net/ethtool/ioctl.c b/net/ethtool/ioctl.c
index 3fd1aa89de87..9275c1b2a7f6 100644
--- a/net/ethtool/ioctl.c
+++ b/net/ethtool/ioctl.c
@@ -155,12 +155,12 @@ static int ethtool_set_features(struct net_device *dev, void __user *useraddr)
 
 	netdev_hw_features_andnot_r(dev, valid);
 	if (tmp) {
-		valid &= dev->hw_features;
+		netdev_features_mask(&valid, dev->hw_features);
 		ret |= ETHTOOL_F_UNSUPPORTED;
 	}
 
 	netdev_wanted_features_clear(dev, valid);
-	tmp = wanted & valid;
+	tmp = netdev_features_and(wanted, valid);
 	netdev_wanted_features_set(dev, tmp);
 	__netdev_update_features(dev);
 
@@ -294,7 +294,7 @@ static int ethtool_set_one_feature(struct net_device *dev,
 		return -EFAULT;
 
 	mask = ethtool_get_feature_mask(ethcmd);
-	mask &= dev->hw_features;
+	netdev_features_mask(&mask, dev->hw_features);
 	if (!mask)
 		return -EOPNOTSUPP;
 
@@ -363,13 +363,13 @@ static int __ethtool_set_flags(struct net_device *dev, u32 data)
 
 	/* allow changing only bits set in hw_features */
 	changed = netdev_active_features_xor(dev, features);
-	changed &= eth_all_features;
+	netdev_features_mask(&changed, eth_all_features);
 	tmp = netdev_hw_features_andnot_r(dev, changed);
 	if (tmp)
 		return netdev_hw_features_intersects(dev, changed) ? -EINVAL : -EOPNOTSUPP;
 
 	netdev_wanted_features_clear(dev, changed);
-	tmp = features & changed;
+	tmp = netdev_features_and(features, changed);
 	netdev_wanted_features_set(dev, tmp);
 
 	__netdev_update_features(dev);
-- 
2.33.0


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [RFCv6 PATCH net-next 15/19] net: use netdev_features_subset helpers
  2022-04-19  2:21 [RFCv6 PATCH net-next 00/19] net: extend the type of netdev_features_t to bitmap Jian Shen
                   ` (13 preceding siblings ...)
  2022-04-19  2:22 ` [RFCv6 PATCH net-next 14/19] net: use netdev_features_and helpers Jian Shen
@ 2022-04-19  2:22 ` Jian Shen
  2022-04-19  2:22 ` [RFCv6 PATCH net-next 16/19] net: use netdev_features_equal helpers Jian Shen
                   ` (3 subsequent siblings)
  18 siblings, 0 replies; 30+ messages in thread
From: Jian Shen @ 2022-04-19  2:22 UTC (permalink / raw)
  To: davem, kuba, andrew, ecree.xilinx, hkallweit1, alexandr.lobakin,
	saeed, leon
  Cc: netdev, linuxarm, lipeng321

Replace the '(f1 & f2) == f2' operations of features by
netdev_features_subset helpers.

Signed-off-by: Jian Shen <shenjian15@huawei.com>
---
 net/core/dev.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/net/core/dev.c b/net/core/dev.c
index 7f75084bcaa7..03e64399c7b4 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -9591,8 +9591,8 @@ static netdev_features_t netdev_fix_features(struct net_device *dev,
 	}
 
 	if (netdev_feature_test(NETIF_F_HW_TLS_TX_BIT, features)) {
-		bool ip_csum = (features & netdev_ip_csum_features) ==
-			netdev_ip_csum_features;
+		bool ip_csum = netdev_features_subset(features,
+						      netdev_ip_csum_features);
 		bool hw_csum = netdev_feature_test(NETIF_F_HW_CSUM_BIT,
 						   features);
 
-- 
2.33.0


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [RFCv6 PATCH net-next 16/19] net: use netdev_features_equal helpers
  2022-04-19  2:21 [RFCv6 PATCH net-next 00/19] net: extend the type of netdev_features_t to bitmap Jian Shen
                   ` (14 preceding siblings ...)
  2022-04-19  2:22 ` [RFCv6 PATCH net-next 15/19] net: use netdev_features_subset helpers Jian Shen
@ 2022-04-19  2:22 ` Jian Shen
  2022-04-19  2:22 ` [RFCv6 PATCH net-next 17/19] net: use netdev_features_copy helpers Jian Shen
                   ` (2 subsequent siblings)
  18 siblings, 0 replies; 30+ messages in thread
From: Jian Shen @ 2022-04-19  2:22 UTC (permalink / raw)
  To: davem, kuba, andrew, ecree.xilinx, hkallweit1, alexandr.lobakin,
	saeed, leon
  Cc: netdev, linuxarm, lipeng321

Replace the '==' and '!=' operations of features by
netdev_features_equal helpers.

Signed-off-by: Jian Shen <shenjian15@huawei.com>
---
 drivers/net/ethernet/sfc/efx_common.c | 2 +-
 drivers/net/ethernet/sfc/falcon/efx.c | 2 +-
 net/core/dev.c                        | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/sfc/efx_common.c b/drivers/net/ethernet/sfc/efx_common.c
index 769f3a8b3ff9..6851f2196041 100644
--- a/drivers/net/ethernet/sfc/efx_common.c
+++ b/drivers/net/ethernet/sfc/efx_common.c
@@ -417,7 +417,7 @@ static void efx_start_datapath(struct efx_nic *efx)
 	netdev_hw_features_set(efx->net_dev, efx->net_dev->features);
 	netdev_hw_features_clear(efx->net_dev, efx->fixed_features);
 	netdev_active_features_set(efx->net_dev, efx->fixed_features);
-	if (efx->net_dev->features != old_features)
+	if (!netdev_active_features_equal(efx->net_dev, old_features))
 		netdev_features_change(efx->net_dev);
 
 	/* RX filters may also have scatter-enabled flags */
diff --git a/drivers/net/ethernet/sfc/falcon/efx.c b/drivers/net/ethernet/sfc/falcon/efx.c
index 52d3ced17602..0bbe83f661d1 100644
--- a/drivers/net/ethernet/sfc/falcon/efx.c
+++ b/drivers/net/ethernet/sfc/falcon/efx.c
@@ -644,7 +644,7 @@ static void ef4_start_datapath(struct ef4_nic *efx)
 	netdev_hw_features_set(efx->net_dev, efx->net_dev->features);
 	netdev_hw_features_clear(efx->net_dev, efx->fixed_features);
 	netdev_active_features_set(efx->net_dev, efx->fixed_features);
-	if (efx->net_dev->features != old_features)
+	if (!netdev_active_features_equal(efx->net_dev, old_features))
 		netdev_features_change(efx->net_dev);
 
 	/* RX filters may also have scatter-enabled flags */
diff --git a/net/core/dev.c b/net/core/dev.c
index 03e64399c7b4..c59f50898444 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -9632,7 +9632,7 @@ int __netdev_update_features(struct net_device *dev)
 	netdev_for_each_upper_dev_rcu(dev, upper, iter)
 		features = netdev_sync_upper_features(dev, upper, features);
 
-	if (dev->features == features)
+	if (netdev_active_features_equal(dev, features))
 		goto sync_lower;
 
 	netdev_dbg(dev, "Features changed: %pNF -> %pNF\n",
-- 
2.33.0


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [RFCv6 PATCH net-next 17/19] net: use netdev_features_copy helpers
  2022-04-19  2:21 [RFCv6 PATCH net-next 00/19] net: extend the type of netdev_features_t to bitmap Jian Shen
                   ` (15 preceding siblings ...)
  2022-04-19  2:22 ` [RFCv6 PATCH net-next 16/19] net: use netdev_features_equal helpers Jian Shen
@ 2022-04-19  2:22 ` Jian Shen
  2022-04-19  2:22 ` [RFCv6 PATCH net-next 18/19] net: use netdev_xxx_features helpers Jian Shen
  2022-04-19  2:22 ` [RFCv6 PATCH net-next 19/19] net: redefine the prototype of netdev_features_t Jian Shen
  18 siblings, 0 replies; 30+ messages in thread
From: Jian Shen @ 2022-04-19  2:22 UTC (permalink / raw)
  To: davem, kuba, andrew, ecree.xilinx, hkallweit1, alexandr.lobakin,
	saeed, leon
  Cc: netdev, linuxarm, lipeng321

Replace the direct assignment for features members of netdev
with netdev_features_copy helpers, for the nic drivers are
not supposed to modify netdev_features directly

Signed-off-by: Jian Shen <shenjian15@huawei.com>
---
 drivers/net/ethernet/hisilicon/hns3/hns3_enet.c |  2 +-
 drivers/net/ethernet/sfc/ef10.c                 |  2 +-
 drivers/net/ethernet/sfc/falcon/efx.c           |  4 ++--
 net/core/dev.c                                  | 12 ++++++------
 4 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
index f872a624faad..06384ec2ac82 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
@@ -2454,7 +2454,7 @@ static int hns3_nic_set_features(struct net_device *netdev,
 			return ret;
 	}
 
-	netdev->features = features;
+	netdev_active_features_copy(netdev, features);
 	return 0;
 }
 
diff --git a/drivers/net/ethernet/sfc/ef10.c b/drivers/net/ethernet/sfc/ef10.c
index bf8274c03176..b718dfae9389 100644
--- a/drivers/net/ethernet/sfc/ef10.c
+++ b/drivers/net/ethernet/sfc/ef10.c
@@ -1371,7 +1371,7 @@ static int efx_ef10_init_nic(struct efx_nic *efx)
 		netdev_feature_add(NETIF_F_TSO_BIT, &hw_enc_features);
 		netdev_active_features_set(efx->net_dev, encap_tso_features);
 	}
-	efx->net_dev->hw_enc_features = hw_enc_features;
+	netdev_hw_enc_features_copy(efx->net_dev, hw_enc_features);
 
 	/* don't fail init if RSS setup doesn't work */
 	rc = efx->type->rx_push_rss_config(efx, false,
diff --git a/drivers/net/ethernet/sfc/falcon/efx.c b/drivers/net/ethernet/sfc/falcon/efx.c
index 0bbe83f661d1..4fc2f06b2781 100644
--- a/drivers/net/ethernet/sfc/falcon/efx.c
+++ b/drivers/net/ethernet/sfc/falcon/efx.c
@@ -2920,8 +2920,8 @@ static int ef4_pci_probe(struct pci_dev *pci_dev,
 	netdev_active_feature_add(net_dev, NETIF_F_RXCSUM_BIT);
 	/* Mask for features that also apply to VLAN devices */
 	netdev_vlan_features_set_array(net_dev, &efx_vlan_feature_set);
-	net_dev->hw_features = netdev_active_features_andnot(net_dev,
-							     efx->fixed_features);
+	netdev_hw_features_copy(net_dev,
+				netdev_active_features_andnot(net_dev, efx->fixed_features));
 
 	/* Disable VLAN filtering by default.  It may be enforced if
 	 * the feature is fixed (i.e. VLAN filters are required to
diff --git a/net/core/dev.c b/net/core/dev.c
index c59f50898444..c7505f126318 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -9675,7 +9675,7 @@ int __netdev_update_features(struct net_device *dev)
 			 */
 			if (netdev_feature_test(NETIF_F_RX_UDP_TUNNEL_PORT_BIT,
 						features)) {
-				dev->features = features;
+				netdev_active_features_copy(dev, features);
 				udp_tunnel_get_rx_info(dev);
 			} else {
 				udp_tunnel_drop_rx_info(dev);
@@ -9685,7 +9685,7 @@ int __netdev_update_features(struct net_device *dev)
 		if (netdev_feature_test(NETIF_F_HW_VLAN_CTAG_FILTER_BIT, diff)) {
 			if (netdev_feature_test(NETIF_F_HW_VLAN_CTAG_FILTER_BIT,
 						features)) {
-				dev->features = features;
+				netdev_active_features_copy(dev, features);
 				err |= vlan_get_rx_ctag_filter_info(dev);
 			} else {
 				vlan_drop_rx_ctag_filter_info(dev);
@@ -9695,14 +9695,14 @@ int __netdev_update_features(struct net_device *dev)
 		if (netdev_feature_test(NETIF_F_HW_VLAN_STAG_FILTER_BIT, diff)) {
 			if (netdev_feature_test(NETIF_F_HW_VLAN_STAG_FILTER_BIT,
 						features)) {
-				dev->features = features;
+				netdev_active_features_copy(dev, features);
 				err |= vlan_get_rx_stag_filter_info(dev);
 			} else {
 				vlan_drop_rx_stag_filter_info(dev);
 			}
 		}
 
-		dev->features = features;
+		netdev_active_features_copy(dev, features);
 	}
 
 	return err < 0 ? 0 : 1;
@@ -9955,8 +9955,8 @@ int register_netdevice(struct net_device *dev)
 		netdev_hw_feature_add(dev, NETIF_F_RX_UDP_TUNNEL_PORT_BIT);
 	}
 
-	dev->wanted_features = netdev_active_features_and(dev,
-							  dev->hw_features);
+	netdev_wanted_features_copy(dev,
+				    netdev_active_features_and(dev, dev->hw_features));
 
 	if (!(dev->flags & IFF_LOOPBACK))
 		netdev_hw_feature_add(dev, NETIF_F_NOCACHE_COPY_BIT);
-- 
2.33.0


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [RFCv6 PATCH net-next 18/19] net: use netdev_xxx_features helpers
  2022-04-19  2:21 [RFCv6 PATCH net-next 00/19] net: extend the type of netdev_features_t to bitmap Jian Shen
                   ` (16 preceding siblings ...)
  2022-04-19  2:22 ` [RFCv6 PATCH net-next 17/19] net: use netdev_features_copy helpers Jian Shen
@ 2022-04-19  2:22 ` Jian Shen
  2022-04-19  2:22 ` [RFCv6 PATCH net-next 19/19] net: redefine the prototype of netdev_features_t Jian Shen
  18 siblings, 0 replies; 30+ messages in thread
From: Jian Shen @ 2022-04-19  2:22 UTC (permalink / raw)
  To: davem, kuba, andrew, ecree.xilinx, hkallweit1, alexandr.lobakin,
	saeed, leon
  Cc: netdev, linuxarm, lipeng321

Replace the direct using for features members of netdev
with netdev_xxx_features helpers, for the nic drivers are
not supposed to modify netdev_features directly.

I'mo not sure for this patch is necessary, just keep the
same rule with others.

Signed-off-by: Jian Shen <shenjian15@huawei.com>
---
 .../net/ethernet/hisilicon/hns3/hns3_enet.c   |  4 +--
 drivers/net/ethernet/sfc/efx_common.c         |  5 ++--
 drivers/net/ethernet/sfc/falcon/efx.c         |  5 ++--
 drivers/net/ethernet/sfc/falcon/net_driver.h  |  2 +-
 drivers/net/ethernet/sfc/net_driver.h         |  2 +-
 include/linux/netdev_features_helper.h        |  2 +-
 net/core/dev.c                                | 26 +++++++++++--------
 net/ethtool/features.c                        | 14 +++++-----
 net/ethtool/ioctl.c                           | 16 ++++++------
 9 files changed, 41 insertions(+), 35 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
index 06384ec2ac82..f1d55fac404c 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
@@ -3326,7 +3326,7 @@ static void hns3_set_default_feature(struct net_device *netdev)
 	if (test_bit(HNAE3_DEV_SUPPORT_FD_FORWARD_TC_B, ae_dev->caps))
 		netdev_active_feature_add(netdev, NETIF_F_HW_TC_BIT);
 
-	netdev_hw_features_set(netdev, netdev->features);
+	netdev_hw_features_set(netdev, netdev_active_features(netdev));
 	if (!test_bit(HNAE3_DEV_SUPPORT_VLAN_FLTR_MDF_B, ae_dev->caps))
 		netdev_hw_feature_del(netdev, NETIF_F_HW_VLAN_CTAG_FILTER_BIT);
 
@@ -3336,7 +3336,7 @@ static void hns3_set_default_feature(struct net_device *netdev)
 	features = netdev_active_features_andnot(netdev, vlan_off_features);
 	netdev_vlan_features_set(netdev, features);
 
-	netdev_hw_enc_features_set(netdev, netdev->vlan_features);
+	netdev_hw_enc_features_set(netdev, netdev_vlan_features(netdev));
 	netdev_hw_enc_feature_add(netdev, NETIF_F_TSO_MANGLEID_BIT);
 }
 
diff --git a/drivers/net/ethernet/sfc/efx_common.c b/drivers/net/ethernet/sfc/efx_common.c
index 6851f2196041..93e7a35ecb7d 100644
--- a/drivers/net/ethernet/sfc/efx_common.c
+++ b/drivers/net/ethernet/sfc/efx_common.c
@@ -413,8 +413,9 @@ static void efx_start_datapath(struct efx_nic *efx)
 	/* Restore previously fixed features in hw_features and remove
 	 * features which are fixed now
 	 */
-	old_features = efx->net_dev->features;
-	netdev_hw_features_set(efx->net_dev, efx->net_dev->features);
+	old_features = netdev_active_features(efx->net_dev);
+	netdev_hw_features_set(efx->net_dev,
+			       netdev_active_features(efx->net_dev));
 	netdev_hw_features_clear(efx->net_dev, efx->fixed_features);
 	netdev_active_features_set(efx->net_dev, efx->fixed_features);
 	if (!netdev_active_features_equal(efx->net_dev, old_features))
diff --git a/drivers/net/ethernet/sfc/falcon/efx.c b/drivers/net/ethernet/sfc/falcon/efx.c
index 4fc2f06b2781..43ed76ed5533 100644
--- a/drivers/net/ethernet/sfc/falcon/efx.c
+++ b/drivers/net/ethernet/sfc/falcon/efx.c
@@ -640,8 +640,9 @@ static void ef4_start_datapath(struct ef4_nic *efx)
 	/* Restore previously fixed features in hw_features and remove
 	 * features which are fixed now
 	 */
-	old_features = efx->net_dev->features;
-	netdev_hw_features_set(efx->net_dev, efx->net_dev->features);
+	old_features = netdev_active_features(efx->net_dev);
+	netdev_hw_features_set(efx->net_dev,
+			       netdev_active_features(efx->net_dev));
 	netdev_hw_features_clear(efx->net_dev, efx->fixed_features);
 	netdev_active_features_set(efx->net_dev, efx->fixed_features);
 	if (!netdev_active_features_equal(efx->net_dev, old_features))
diff --git a/drivers/net/ethernet/sfc/falcon/net_driver.h b/drivers/net/ethernet/sfc/falcon/net_driver.h
index 5365e2d8a975..137b3479135b 100644
--- a/drivers/net/ethernet/sfc/falcon/net_driver.h
+++ b/drivers/net/ethernet/sfc/falcon/net_driver.h
@@ -1303,7 +1303,7 @@ static inline netdev_features_t ef4_supported_features(const struct ef4_nic *efx
 {
 	const struct net_device *net_dev = efx->net_dev;
 
-	return netdev_active_features_or(net_dev, net_dev->hw_features);
+	return netdev_active_features_or(net_dev, netdev_hw_features(net_dev));
 }
 
 /* Get the current TX queue insert index. */
diff --git a/drivers/net/ethernet/sfc/net_driver.h b/drivers/net/ethernet/sfc/net_driver.h
index bcdcec3d61e1..f574e5c99584 100644
--- a/drivers/net/ethernet/sfc/net_driver.h
+++ b/drivers/net/ethernet/sfc/net_driver.h
@@ -1688,7 +1688,7 @@ static inline netdev_features_t efx_supported_features(const struct efx_nic *efx
 {
 	const struct net_device *net_dev = efx->net_dev;
 
-	return netdev_active_features_or(net_dev, net_dev->hw_features);
+	return netdev_active_features_or(net_dev, netdev_hw_features(net_dev));
 }
 
 /* Get the current TX queue insert index. */
diff --git a/include/linux/netdev_features_helper.h b/include/linux/netdev_features_helper.h
index 79fa490b96cf..6b2a9080fdea 100644
--- a/include/linux/netdev_features_helper.h
+++ b/include/linux/netdev_features_helper.h
@@ -603,7 +603,7 @@ netdev_get_wanted_features(struct net_device *dev)
 {
 	netdev_features_t tmp;
 
-	tmp = netdev_active_features_andnot(dev, dev->hw_features);
+	tmp = netdev_active_features_andnot(dev, netdev_hw_features(dev));
 	return netdev_wanted_features_or(dev, tmp);
 }
 
diff --git a/net/core/dev.c b/net/core/dev.c
index c7505f126318..0962935f478e 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -3190,7 +3190,7 @@ static void skb_warn_bad_offload(const struct sk_buff *skb)
 	}
 	skb_dump(KERN_WARNING, skb, false);
 	WARN(1, "%s: caps=(%pNF, %pNF)\n",
-	     name, dev ? &dev->features : &null_features,
+	     name, dev ? &netdev_active_features(dev) : &null_features,
 	     skb->sk ? &skb->sk->sk_route_caps : &null_features);
 }
 
@@ -3344,7 +3344,7 @@ struct sk_buff *__skb_gso_segment(struct sk_buff *skb,
 		struct net_device *dev = skb->dev;
 
 		partial_features = netdev_active_features_and(dev,
-							      dev->gso_partial_features);
+							      netdev_gso_partial_features(dev));
 		netdev_feature_add(NETIF_F_GSO_ROBUST_BIT, &partial_features);
 		if (!skb_gso_ok(skb, netdev_features_or(features, partial_features)))
 			netdev_feature_del(NETIF_F_GSO_PARTIAL_BIT, &features);
@@ -3411,7 +3411,8 @@ static netdev_features_t net_mpls_features(struct sk_buff *skb,
 					   __be16 type)
 {
 	if (eth_p_mpls(type))
-		netdev_features_mask(&features, skb->dev->mpls_features);
+		netdev_features_mask(&features,
+				     netdev_mpls_features(skb->dev));
 
 	return features;
 }
@@ -3479,7 +3480,8 @@ static netdev_features_t gso_features_check(const struct sk_buff *skb,
 	 * segmented the frame.
 	 */
 	if (!(skb_shinfo(skb)->gso_type & SKB_GSO_PARTIAL))
-		netdev_features_clear(&features, dev->gso_partial_features);
+		netdev_features_clear(&features,
+				      netdev_gso_partial_features(dev));
 
 	/* Make sure to clear the IPv4 ID mangling feature if the
 	 * IPv4 header has the potential to be fragmented.
@@ -3502,7 +3504,7 @@ netdev_features_t netif_skb_features(struct sk_buff *skb)
 	netdev_features_t features;
 	netdev_features_t tmp;
 
-	features = dev->features;
+	features = netdev_active_features(dev);
 
 	if (skb_is_gso(skb))
 		features = gso_features_check(skb, dev, features);
@@ -3512,7 +3514,7 @@ netdev_features_t netif_skb_features(struct sk_buff *skb)
 	 * features for the netdev
 	 */
 	if (skb->encapsulation)
-		netdev_features_mask(&features, dev->hw_enc_features);
+		netdev_features_mask(&features, netdev_hw_enc_features(dev));
 
 	if (skb_vlan_tagged(skb)) {
 		tmp = netdev_vlan_features_or(dev, netdev_tx_vlan_features);
@@ -9556,7 +9558,8 @@ static netdev_features_t netdev_fix_features(struct net_device *dev,
 	    !netdev_feature_test(NETIF_F_GSO_PARTIAL_BIT, features)) {
 		netdev_dbg(dev,
 			   "Dropping partially supported GSO features since no GSO partial.\n");
-		netdev_features_clear(&features, dev->gso_partial_features);
+		netdev_features_clear(&features,
+				      netdev_gso_partial_features(dev));
 	}
 
 	if (!netdev_feature_test(NETIF_F_RXCSUM_BIT, features)) {
@@ -9636,7 +9639,7 @@ int __netdev_update_features(struct net_device *dev)
 		goto sync_lower;
 
 	netdev_dbg(dev, "Features changed: %pNF -> %pNF\n",
-		&dev->features, &features);
+		&netdev_active_features(dev), &features);
 
 	if (dev->netdev_ops->ndo_set_features)
 		err = dev->netdev_ops->ndo_set_features(dev, features);
@@ -9646,7 +9649,7 @@ int __netdev_update_features(struct net_device *dev)
 	if (unlikely(err < 0)) {
 		netdev_err(dev,
 			"set_features() failed (%d); wanted %pNF, left %pNF\n",
-			err, &features, &dev->features);
+			err, &features, &netdev_active_features(dev));
 		/* return non-0 since some features might have changed and
 		 * it's better to fire a spurious notification than miss it
 		 */
@@ -9663,7 +9666,8 @@ int __netdev_update_features(struct net_device *dev)
 	if (!err) {
 		netdev_features_t diff;
 
-		diff = netdev_features_xor(features, dev->features);
+		diff = netdev_features_xor(features,
+					   netdev_active_features(dev));
 
 		if (netdev_feature_test(NETIF_F_RX_UDP_TUNNEL_PORT_BIT, diff)) {
 			/* udp_tunnel_{get,drop}_rx_info both need
@@ -9956,7 +9960,7 @@ int register_netdevice(struct net_device *dev)
 	}
 
 	netdev_wanted_features_copy(dev,
-				    netdev_active_features_and(dev, dev->hw_features));
+				    netdev_active_features_and(dev, netdev_hw_features(dev)));
 
 	if (!(dev->flags & IFF_LOOPBACK))
 		netdev_hw_feature_add(dev, NETIF_F_NOCACHE_COPY_BIT);
diff --git a/net/ethtool/features.c b/net/ethtool/features.c
index c4d7a1f9366a..93d56e8921a1 100644
--- a/net/ethtool/features.c
+++ b/net/ethtool/features.c
@@ -42,9 +42,9 @@ static int features_prepare_data(const struct ethnl_req_info *req_base,
 	struct net_device *dev = reply_base->dev;
 	netdev_features_t all_features;
 
-	ethnl_features_to_bitmap32(data->hw, dev->hw_features);
-	ethnl_features_to_bitmap32(data->wanted, dev->wanted_features);
-	ethnl_features_to_bitmap32(data->active, dev->features);
+	ethnl_features_to_bitmap32(data->hw, netdev_hw_features(dev));
+	ethnl_features_to_bitmap32(data->wanted, netdev_wanted_features(dev));
+	ethnl_features_to_bitmap32(data->active, netdev_active_features(dev));
 	ethnl_features_to_bitmap32(data->nochange, NETIF_F_NEVER_CHANGE);
 	all_features = GENMASK_ULL(NETDEV_FEATURE_COUNT - 1, 0);
 	ethnl_features_to_bitmap32(data->all, all_features);
@@ -238,8 +238,8 @@ int ethnl_set_features(struct sk_buff *skb, struct genl_info *info)
 	dev = req_info.dev;
 
 	rtnl_lock();
-	ethnl_features_to_bitmap(old_active, dev->features);
-	ethnl_features_to_bitmap(old_wanted, dev->wanted_features);
+	ethnl_features_to_bitmap(old_active, netdev_active_features(dev));
+	ethnl_features_to_bitmap(old_wanted, netdev_wanted_features(dev));
 	ret = ethnl_parse_bitset(req_wanted, req_mask, NETDEV_FEATURE_COUNT,
 				 tb[ETHTOOL_A_FEATURES_WANTED],
 				 netdev_features_strings, info->extack);
@@ -256,13 +256,13 @@ int ethnl_set_features(struct sk_buff *skb, struct genl_info *info)
 	bitmap_andnot(new_wanted, old_wanted, req_mask, NETDEV_FEATURE_COUNT);
 	bitmap_or(req_wanted, new_wanted, req_wanted, NETDEV_FEATURE_COUNT);
 	if (!bitmap_equal(req_wanted, old_wanted, NETDEV_FEATURE_COUNT)) {
-		netdev_wanted_features_clear(dev, dev->hw_features);
+		netdev_wanted_features_clear(dev, netdev_hw_features(dev));
 		tmp = netdev_hw_features_and(dev,
 					     ethnl_bitmap_to_features(req_wanted));
 		netdev_wanted_features_set(dev, tmp);
 		__netdev_update_features(dev);
 	}
-	ethnl_features_to_bitmap(new_active, dev->features);
+	ethnl_features_to_bitmap(new_active, netdev_active_features(dev));
 	mod = !bitmap_equal(old_active, new_active, NETDEV_FEATURE_COUNT);
 
 	ret = 0;
diff --git a/net/ethtool/ioctl.c b/net/ethtool/ioctl.c
index 9275c1b2a7f6..02c2741c0d6b 100644
--- a/net/ethtool/ioctl.c
+++ b/net/ethtool/ioctl.c
@@ -97,9 +97,9 @@ static int ethtool_get_features(struct net_device *dev, void __user *useraddr)
 	BUILD_BUG_ON(ETHTOOL_DEV_FEATURE_WORDS * sizeof(u32) > sizeof(netdev_features_t));
 
 	for (i = 0; i < ETHTOOL_DEV_FEATURE_WORDS; ++i) {
-		features[i].available = (u32)(dev->hw_features >> (32 * i));
-		features[i].requested = (u32)(dev->wanted_features >> (32 * i));
-		features[i].active = (u32)(dev->features >> (32 * i));
+		features[i].available = (u32)(netdev_hw_features(dev) >> (32 * i));
+		features[i].requested = (u32)(netdev_wanted_features(dev) >> (32 * i));
+		features[i].active = (u32)(netdev_active_features(dev) >> (32 * i));
 		features[i].never_changed =
 			(u32)(NETIF_F_NEVER_CHANGE >> (32 * i));
 	}
@@ -155,7 +155,7 @@ static int ethtool_set_features(struct net_device *dev, void __user *useraddr)
 
 	netdev_hw_features_andnot_r(dev, valid);
 	if (tmp) {
-		netdev_features_mask(&valid, dev->hw_features);
+		netdev_features_mask(&valid, netdev_hw_features(dev));
 		ret |= ETHTOOL_F_UNSUPPORTED;
 	}
 
@@ -164,7 +164,7 @@ static int ethtool_set_features(struct net_device *dev, void __user *useraddr)
 	netdev_wanted_features_set(dev, tmp);
 	__netdev_update_features(dev);
 
-	tmp = netdev_wanted_features_xor(dev, dev->features);
+	tmp = netdev_wanted_features_xor(dev, netdev_active_features(dev));
 	if (netdev_features_intersects(tmp, valid))
 		ret |= ETHTOOL_F_WISH;
 
@@ -294,7 +294,7 @@ static int ethtool_set_one_feature(struct net_device *dev,
 		return -EFAULT;
 
 	mask = ethtool_get_feature_mask(ethcmd);
-	netdev_features_mask(&mask, dev->hw_features);
+	netdev_features_mask(&mask, netdev_hw_features(dev));
 	if (!mask)
 		return -EOPNOTSUPP;
 
@@ -2836,7 +2836,7 @@ __dev_ethtool(struct net *net, struct ifreq *ifr, void __user *useraddr,
 		if (rc < 0)
 			goto out;
 	}
-	old_features = dev->features;
+	old_features = netdev_active_features(dev);
 
 	switch (ethcmd) {
 	case ETHTOOL_GSET:
@@ -3051,7 +3051,7 @@ __dev_ethtool(struct net *net, struct ifreq *ifr, void __user *useraddr,
 	if (dev->ethtool_ops->complete)
 		dev->ethtool_ops->complete(dev);
 
-	if (old_features != dev->features)
+	if (old_features != netdev_active_features(dev))
 		netdev_features_change(dev);
 out:
 	if (dev->dev.parent)
-- 
2.33.0


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [RFCv6 PATCH net-next 19/19] net: redefine the prototype of netdev_features_t
  2022-04-19  2:21 [RFCv6 PATCH net-next 00/19] net: extend the type of netdev_features_t to bitmap Jian Shen
                   ` (17 preceding siblings ...)
  2022-04-19  2:22 ` [RFCv6 PATCH net-next 18/19] net: use netdev_xxx_features helpers Jian Shen
@ 2022-04-19  2:22 ` Jian Shen
  18 siblings, 0 replies; 30+ messages in thread
From: Jian Shen @ 2022-04-19  2:22 UTC (permalink / raw)
  To: davem, kuba, andrew, ecree.xilinx, hkallweit1, alexandr.lobakin,
	saeed, leon
  Cc: netdev, linuxarm, lipeng321

For the prototype of netdev_features_t is u64, and the number
of netdevice feature bits is 64 now. So there is no space to
introduce new feature bit. Change the prototype of netdev_features_t
from u64 to structure below:
	typedef struct {
		DECLARE_BITMAP(bits, NETDEV_FEATURE_COUNT);
	} netdev_features_t;

Rewrite the netdev_features helpers to adapt with new prototype.

To avoid mistake using NETIF_F_XXX as NETIF_F_XXX_BIT as
input macroes for above helpers, remove all the macroes
of NETIF_F_XXX for single feature bit.

With the prototype is no longer u64, the implementation of print
interface for netdev features(%pNF) is changed to bitmap. So
does the implementation of net/ethtool/.

Signed-off-by: Jian Shen <shenjian15@huawei.com>
---
 include/linux/netdev_features.h        |  87 +---------------
 include/linux/netdev_features_helper.h | 133 ++++++++++++++++---------
 include/linux/netdevice.h              |  45 +++++----
 lib/vsprintf.c                         |  11 +-
 net/core/dev.c                         |  30 +++---
 net/ethtool/features.c                 |  84 +++++-----------
 net/ethtool/ioctl.c                    |  31 +++---
 7 files changed, 175 insertions(+), 246 deletions(-)

diff --git a/include/linux/netdev_features.h b/include/linux/netdev_features.h
index 16b2313e1dec..4cc66b017bce 100644
--- a/include/linux/netdev_features.h
+++ b/include/linux/netdev_features.h
@@ -10,8 +10,6 @@
 #include <linux/cache.h>
 #include <asm/byteorder.h>
 
-typedef u64 netdev_features_t;
-
 struct netdev_feature_set {
 	unsigned int cnt;
 	unsigned short feature_bits[];
@@ -163,94 +161,11 @@ extern struct netdev_feature_set netif_f_gso_encap_feature_set;
 extern struct netdev_feature_set netif_f_xfrm_feature_set;
 extern struct netdev_feature_set netif_f_tls_feature_set;
 
-/* copy'n'paste compression ;) */
-#define __NETIF_F_BIT(bit)	((netdev_features_t)1 << (bit))
-#define __NETIF_F(name)		__NETIF_F_BIT(NETIF_F_##name##_BIT)
-
-#define NETIF_F_FCOE_CRC	__NETIF_F(FCOE_CRC)
-#define NETIF_F_FCOE_MTU	__NETIF_F(FCOE_MTU)
-#define NETIF_F_FRAGLIST	__NETIF_F(FRAGLIST)
-#define NETIF_F_FSO		__NETIF_F(FSO)
-#define NETIF_F_GRO		__NETIF_F(GRO)
-#define NETIF_F_GRO_HW		__NETIF_F(GRO_HW)
-#define NETIF_F_GSO		__NETIF_F(GSO)
-#define NETIF_F_GSO_ROBUST	__NETIF_F(GSO_ROBUST)
-#define NETIF_F_HIGHDMA		__NETIF_F(HIGHDMA)
-#define NETIF_F_HW_CSUM		__NETIF_F(HW_CSUM)
-#define NETIF_F_HW_VLAN_CTAG_FILTER __NETIF_F(HW_VLAN_CTAG_FILTER)
-#define NETIF_F_HW_VLAN_CTAG_RX	__NETIF_F(HW_VLAN_CTAG_RX)
-#define NETIF_F_HW_VLAN_CTAG_TX	__NETIF_F(HW_VLAN_CTAG_TX)
-#define NETIF_F_IP_CSUM		__NETIF_F(IP_CSUM)
-#define NETIF_F_IPV6_CSUM	__NETIF_F(IPV6_CSUM)
-#define NETIF_F_LLTX		__NETIF_F(LLTX)
-#define NETIF_F_LOOPBACK	__NETIF_F(LOOPBACK)
-#define NETIF_F_LRO		__NETIF_F(LRO)
-#define NETIF_F_NETNS_LOCAL	__NETIF_F(NETNS_LOCAL)
-#define NETIF_F_NOCACHE_COPY	__NETIF_F(NOCACHE_COPY)
-#define NETIF_F_NTUPLE		__NETIF_F(NTUPLE)
-#define NETIF_F_RXCSUM		__NETIF_F(RXCSUM)
-#define NETIF_F_RXHASH		__NETIF_F(RXHASH)
-#define NETIF_F_SCTP_CRC	__NETIF_F(SCTP_CRC)
-#define NETIF_F_SG		__NETIF_F(SG)
-#define NETIF_F_TSO6		__NETIF_F(TSO6)
-#define NETIF_F_TSO_ECN		__NETIF_F(TSO_ECN)
-#define NETIF_F_TSO		__NETIF_F(TSO)
-#define NETIF_F_VLAN_CHALLENGED	__NETIF_F(VLAN_CHALLENGED)
-#define NETIF_F_RXFCS		__NETIF_F(RXFCS)
-#define NETIF_F_RXALL		__NETIF_F(RXALL)
-#define NETIF_F_GSO_GRE		__NETIF_F(GSO_GRE)
-#define NETIF_F_GSO_GRE_CSUM	__NETIF_F(GSO_GRE_CSUM)
-#define NETIF_F_GSO_IPXIP4	__NETIF_F(GSO_IPXIP4)
-#define NETIF_F_GSO_IPXIP6	__NETIF_F(GSO_IPXIP6)
-#define NETIF_F_GSO_UDP_TUNNEL	__NETIF_F(GSO_UDP_TUNNEL)
-#define NETIF_F_GSO_UDP_TUNNEL_CSUM __NETIF_F(GSO_UDP_TUNNEL_CSUM)
-#define NETIF_F_TSO_MANGLEID	__NETIF_F(TSO_MANGLEID)
-#define NETIF_F_GSO_PARTIAL	 __NETIF_F(GSO_PARTIAL)
-#define NETIF_F_GSO_TUNNEL_REMCSUM __NETIF_F(GSO_TUNNEL_REMCSUM)
-#define NETIF_F_GSO_SCTP	__NETIF_F(GSO_SCTP)
-#define NETIF_F_GSO_ESP		__NETIF_F(GSO_ESP)
-#define NETIF_F_GSO_UDP		__NETIF_F(GSO_UDP)
-#define NETIF_F_HW_VLAN_STAG_FILTER __NETIF_F(HW_VLAN_STAG_FILTER)
-#define NETIF_F_HW_VLAN_STAG_RX	__NETIF_F(HW_VLAN_STAG_RX)
-#define NETIF_F_HW_VLAN_STAG_TX	__NETIF_F(HW_VLAN_STAG_TX)
-#define NETIF_F_HW_L2FW_DOFFLOAD	__NETIF_F(HW_L2FW_DOFFLOAD)
-#define NETIF_F_HW_TC		__NETIF_F(HW_TC)
-#define NETIF_F_HW_ESP		__NETIF_F(HW_ESP)
-#define NETIF_F_HW_ESP_TX_CSUM	__NETIF_F(HW_ESP_TX_CSUM)
-#define	NETIF_F_RX_UDP_TUNNEL_PORT  __NETIF_F(RX_UDP_TUNNEL_PORT)
-#define NETIF_F_HW_TLS_RECORD	__NETIF_F(HW_TLS_RECORD)
-#define NETIF_F_GSO_UDP_L4	__NETIF_F(GSO_UDP_L4)
-#define NETIF_F_HW_TLS_TX	__NETIF_F(HW_TLS_TX)
-#define NETIF_F_HW_TLS_RX	__NETIF_F(HW_TLS_RX)
-#define NETIF_F_GRO_FRAGLIST	__NETIF_F(GRO_FRAGLIST)
-#define NETIF_F_GSO_FRAGLIST	__NETIF_F(GSO_FRAGLIST)
-#define NETIF_F_HW_MACSEC	__NETIF_F(HW_MACSEC)
-#define NETIF_F_GRO_UDP_FWD	__NETIF_F(GRO_UDP_FWD)
-#define NETIF_F_HW_HSR_TAG_INS	__NETIF_F(HW_HSR_TAG_INS)
-#define NETIF_F_HW_HSR_TAG_RM	__NETIF_F(HW_HSR_TAG_RM)
-#define NETIF_F_HW_HSR_FWD	__NETIF_F(HW_HSR_FWD)
-#define NETIF_F_HW_HSR_DUP	__NETIF_F(HW_HSR_DUP)
-
-/* Finds the next feature with the highest number of the range of start till 0.
- */
-static inline int find_next_netdev_feature(u64 feature, unsigned long start)
-{
-	/* like BITMAP_LAST_WORD_MASK() for u64
-	 * this sets the most significant 64 - start to 0.
-	 */
-	feature &= ~0ULL >> (-start & ((sizeof(feature) * 8) - 1));
-
-	return fls64(feature) - 1;
-}
-
 /* This goes for the MSB to the LSB through the set feature bits,
  * mask_addr should be a u64 and bit an int
  */
 #define for_each_netdev_feature(mask_addr, bit)				\
-	for ((bit) = find_next_netdev_feature((mask_addr),		\
-					      NETDEV_FEATURE_COUNT);	\
-	     (bit) >= 0;						\
-	     (bit) = find_next_netdev_feature((mask_addr), (bit) - 1))
+	for_each_set_bit(bit, (unsigned long *)(mask_addr.bits), NETDEV_FEATURE_COUNT)
 
 /* Features valid for ethtool to change */
 /* = all defined minus driver/device-class-related */
diff --git a/include/linux/netdev_features_helper.h b/include/linux/netdev_features_helper.h
index 6b2a9080fdea..43103acc23f4 100644
--- a/include/linux/netdev_features_helper.h
+++ b/include/linux/netdev_features_helper.h
@@ -9,24 +9,24 @@
 
 static inline void netdev_features_zero(netdev_features_t *dst)
 {
-	*dst = 0;
+	bitmap_zero(dst->bits, NETDEV_FEATURE_COUNT);
 }
 
 static inline void netdev_features_fill(netdev_features_t *dst)
 {
-	*dst = ~0ULL;
+	bitmap_fill(dst->bits, NETDEV_FEATURE_COUNT);
 }
 
 static inline bool netdev_features_empty(const netdev_features_t src)
 {
-	return src == 0;
+	return bitmap_empty(src.bits, NETDEV_FEATURE_COUNT);
 }
 
 /* helpers for netdev features '==' operation */
 static inline bool netdev_features_equal(const netdev_features_t src1,
 					 const netdev_features_t src2)
 {
-	return src1 == src2;
+	return bitmap_equal(src1.bits, src2.bits, NETDEV_FEATURE_COUNT);
 }
 
 /* active_feature prefer to netdev->features */
@@ -55,7 +55,10 @@ static inline bool netdev_features_equal(const netdev_features_t src1,
 static inline netdev_features_t
 netdev_features_and(const netdev_features_t a, const netdev_features_t b)
 {
-	return a & b;
+	netdev_features_t dst;
+
+	bitmap_and(dst.bits, a.bits, b.bits, NETDEV_FEATURE_COUNT);
+	return dst;
 }
 
 #define netdev_active_features_and(ndev, __features) \
@@ -84,63 +87,74 @@ static inline void
 netdev_features_mask(netdev_features_t *dst,
 			   const netdev_features_t features)
 {
-	*dst = netdev_features_and(*dst, features);
+	bitmap_and(dst->bits, dst->bits, features.bits, NETDEV_FEATURE_COUNT);
 }
 
 static inline void
 netdev_active_features_mask(struct net_device *ndev,
 			    const netdev_features_t features)
 {
-	ndev->features = netdev_active_features_and(ndev, features);
+	bitmap_and(ndev->features.bits, ndev->features.bits, features.bits,
+		   NETDEV_FEATURE_COUNT);
 }
 
 static inline void
 netdev_hw_features_mask(struct net_device *ndev,
 			const netdev_features_t features)
 {
-	ndev->hw_features = netdev_hw_features_and(ndev, features);
+	bitmap_and(ndev->hw_features.bits, ndev->hw_features.bits,
+		   features.bits, NETDEV_FEATURE_COUNT);
 }
 
 static inline void
 netdev_wanted_features_mask(struct net_device *ndev,
 			    const netdev_features_t features)
 {
-	ndev->wanted_features = netdev_wanted_features_and(ndev, features);
+	bitmap_and(ndev->wanted_features.bits, ndev->wanted_features.bits,
+		   features.bits, NETDEV_FEATURE_COUNT);
 }
 
 static inline void
 netdev_vlan_features_mask(struct net_device *ndev,
 			  const netdev_features_t features)
 {
-	ndev->vlan_features = netdev_vlan_features_and(ndev, features);
+	bitmap_and(ndev->vlan_features.bits, ndev->vlan_features.bits,
+		   features.bits, NETDEV_FEATURE_COUNT);
 }
 
 static inline void
 netdev_hw_enc_features_mask(struct net_device *ndev,
 			    const netdev_features_t features)
 {
-	ndev->hw_enc_features = netdev_hw_enc_features_and(ndev, features);
+	bitmap_and(ndev->hw_enc_features.bits, ndev->hw_enc_features.bits,
+		   features.bits, NETDEV_FEATURE_COUNT);
 }
 
 static inline void
 netdev_mpls_features_mask(struct net_device *ndev,
 			  const netdev_features_t features)
 {
-	ndev->mpls_features = netdev_mpls_features_and(ndev, features);
+	bitmap_and(ndev->mpls_features.bits, ndev->mpls_features.bits,
+		   features.bits, NETDEV_FEATURE_COUNT);
 }
 
 static inline void
 netdev_gso_partial_features_mask(struct net_device *ndev,
 				 const netdev_features_t features)
 {
-	ndev->gso_partial_features = netdev_mpls_features_and(ndev, features);
+	bitmap_and(ndev->gso_partial_features.bits,
+		   ndev->gso_partial_features.bits, features.bits,
+		   NETDEV_FEATURE_COUNT);
 }
 
 /* helpers for netdev features '|' operation */
 static inline netdev_features_t
 netdev_features_or(const netdev_features_t a, const netdev_features_t b)
 {
-	return a | b;
+	netdev_features_t dst;
+
+	bitmap_or(dst.bits, a.bits, b.bits, NETDEV_FEATURE_COUNT);
+	return dst;
 }
 
 #define netdev_active_features_or(ndev, __features) \
@@ -168,63 +182,74 @@ netdev_features_or(const netdev_features_t a, const netdev_features_t b)
 static inline void
 netdev_features_set(netdev_features_t *dst, const netdev_features_t features)
 {
-	*dst = netdev_features_or(*dst, features);
+	bitmap_or(dst->bits, dst->bits, features.bits, NETDEV_FEATURE_COUNT);
 }
 
 static inline void
 netdev_active_features_set(struct net_device *ndev,
 			   const netdev_features_t features)
 {
-	ndev->features = netdev_active_features_or(ndev, features);
+	bitmap_or(ndev->features.bits, ndev->features.bits, features.bits,
+		  NETDEV_FEATURE_COUNT);
 }
 
 static inline void
 netdev_hw_features_set(struct net_device *ndev,
 		       const netdev_features_t features)
 {
-	ndev->hw_features = netdev_hw_features_or(ndev, features);
+	bitmap_or(ndev->hw_features.bits, ndev->hw_features.bits, features.bits,
+		  NETDEV_FEATURE_COUNT);
 }
 
 static inline void
 netdev_wanted_features_set(struct net_device *ndev,
 			   const netdev_features_t features)
 {
-	ndev->wanted_features = netdev_wanted_features_or(ndev, features);
+	bitmap_or(ndev->wanted_features.bits, ndev->wanted_features.bits,
+		  features.bits, NETDEV_FEATURE_COUNT);
 }
 
 static inline void
 netdev_vlan_features_set(struct net_device *ndev,
 			 const netdev_features_t features)
 {
-	ndev->vlan_features = netdev_vlan_features_or(ndev, features);
+	bitmap_or(ndev->vlan_features.bits, ndev->vlan_features.bits,
+		  features.bits, NETDEV_FEATURE_COUNT);
 }
 
 static inline void
 netdev_hw_enc_features_set(struct net_device *ndev,
 			   const netdev_features_t features)
 {
-	ndev->hw_enc_features = netdev_hw_enc_features_or(ndev, features);
+	bitmap_or(ndev->hw_enc_features.bits, ndev->hw_enc_features.bits,
+		  features.bits, NETDEV_FEATURE_COUNT);
 }
 
 static inline void
 netdev_mpls_features_set(struct net_device *ndev,
 			 const netdev_features_t features)
 {
-	ndev->mpls_features = netdev_mpls_features_or(ndev, features);
+	bitmap_or(ndev->mpls_features.bits, ndev->mpls_features.bits,
+		  features.bits, NETDEV_FEATURE_COUNT);
 }
 
 static inline void
 netdev_gso_partial_features_set(struct net_device *ndev,
 				const netdev_features_t features)
 {
-	ndev->gso_partial_features = netdev_mpls_features_or(ndev, features);
+	bitmap_or(ndev->gso_partial_features.bits,
+		  ndev->gso_partial_features.bits, features.bits,
+		  NETDEV_FEATURE_COUNT);
 }
 
 /* helpers for netdev features '^' operation */
 static inline netdev_features_t
 netdev_features_xor(const netdev_features_t a, const netdev_features_t b)
 {
-	return a ^ b;
+	netdev_features_t dst;
+
+	bitmap_xor(dst.bits, a.bits, b.bits, NETDEV_FEATURE_COUNT);
+	return dst;
 }
 
 #define netdev_active_features_xor(ndev, __features) \
@@ -259,57 +284,67 @@ static inline void
 netdev_active_features_toggle(struct net_device *ndev,
 			      const netdev_features_t features)
 {
-	ndev->features = netdev_active_features_xor(ndev, features);
+	bitmap_xor(ndev->features.bits, ndev->features.bits, features.bits,
+		   NETDEV_FEATURE_COUNT);
 }
 
 static inline void
 netdev_hw_features_toggle(struct net_device *ndev,
 			      const netdev_features_t features)
 {
-	ndev->hw_features = netdev_hw_features_xor(ndev, features);
+	bitmap_xor(ndev->hw_features.bits, ndev->hw_features.bits,
+		   features.bits, NETDEV_FEATURE_COUNT);
 }
 
 static inline void
 netdev_wanted_features_toggle(struct net_device *ndev,
 				  const netdev_features_t features)
 {
-	ndev->wanted_features = netdev_wanted_features_xor(ndev, features);
+	bitmap_xor(ndev->wanted_features.bits, ndev->wanted_features.bits,
+		   features.bits, NETDEV_FEATURE_COUNT);
 }
 
 static inline void
 netdev_vlan_features_toggle(struct net_device *ndev,
 				const netdev_features_t features)
 {
-	ndev->vlan_features = netdev_vlan_features_xor(ndev, features);
+	bitmap_xor(ndev->vlan_features.bits, ndev->vlan_features.bits,
+		   features.bits, NETDEV_FEATURE_COUNT);
 }
 
 static inline void
 netdev_hw_enc_features_toggle(struct net_device *ndev,
 			      const netdev_features_t features)
 {
-	ndev->hw_enc_features = netdev_hw_enc_features_xor(ndev, features);
+	bitmap_xor(ndev->hw_enc_features.bits, ndev->hw_enc_features.bits,
+		   features.bits, NETDEV_FEATURE_COUNT);
 }
 
 static inline void
 netdev_mpls_features_toggle(struct net_device *ndev,
 			    const netdev_features_t features)
 {
-	ndev->mpls_features = netdev_mpls_features_xor(ndev, features);
+	bitmap_xor(ndev->mpls_features.bits, ndev->mpls_features.bits,
+		   features.bits, NETDEV_FEATURE_COUNT);
 }
 
 static inline void
 netdev_gso_partial_features_toggle(struct net_device *ndev,
 				   const netdev_features_t features)
 {
-	ndev->gso_partial_features =
-			netdev_gso_partial_features_xor(ndev, features);
+	bitmap_xor(ndev->gso_partial_features.bits,
+		   ndev->gso_partial_features.bits, features.bits,
+		   NETDEV_FEATURE_COUNT);
 }
 
 /* helpers for netdev features '& ~' operation */
 static inline netdev_features_t
 netdev_features_andnot(const netdev_features_t a, const netdev_features_t b)
 {
-	return a & ~b;
+	netdev_features_t dst;
+
+	bitmap_andnot(dst.bits, a.bits, b.bits, NETDEV_FEATURE_COUNT);
+	return dst;
 }
 
 #define netdev_active_features_andnot(ndev, __features) \
@@ -357,63 +392,71 @@ netdev_features_andnot(const netdev_features_t a, const netdev_features_t b)
 static inline void
 netdev_features_clear(netdev_features_t *dst, const netdev_features_t features)
 {
-	*dst = netdev_features_andnot(*dst, features);
+	bitmap_andnot(dst->bits, dst->bits, features.bits,
+		      NETDEV_FEATURE_COUNT);
 }
 
 static inline void
 netdev_active_features_clear(struct net_device *ndev,
 			     const netdev_features_t features)
 {
-	ndev->features = netdev_active_features_andnot(ndev, features);
+	bitmap_andnot(ndev->features.bits, ndev->features.bits, features.bits,
+		      NETDEV_FEATURE_COUNT);
 }
 
 static inline void
 netdev_hw_features_clear(struct net_device *ndev,
 			 const netdev_features_t features)
 {
-	ndev->hw_features = netdev_hw_features_andnot(ndev, features);
+	bitmap_andnot(ndev->features.bits, ndev->features.bits, features.bits,
+		      NETDEV_FEATURE_COUNT);
 }
 
 static inline void
 netdev_wanted_features_clear(struct net_device *ndev,
 			     const netdev_features_t features)
 {
-	ndev->wanted_features = netdev_wanted_features_andnot(ndev, features);
+	bitmap_andnot(ndev->wanted_features.bits, ndev->wanted_features.bits,
+		      features.bits, NETDEV_FEATURE_COUNT);
 }
 
 static inline void
 netdev_vlan_features_clear(struct net_device *ndev,
 			   const netdev_features_t features)
 {
-	ndev->vlan_features = netdev_vlan_features_andnot(ndev, features);
+	bitmap_andnot(ndev->vlan_features.bits, ndev->vlan_features.bits,
+		      features.bits, NETDEV_FEATURE_COUNT);
 }
 
 static inline void
 netdev_hw_enc_features_clear(struct net_device *ndev,
 			     const netdev_features_t features)
 {
-	ndev->hw_enc_features = netdev_hw_enc_features_andnot(ndev, features);
+	bitmap_andnot(ndev->hw_enc_features.bits, ndev->hw_enc_features.bits,
+		      features.bits, NETDEV_FEATURE_COUNT);
 }
 
 static inline void
 netdev_mpls_features_clear(struct net_device *ndev,
 			   const netdev_features_t features)
 {
-	ndev->mpls_features = netdev_mpls_features_andnot(ndev, features);
+	bitmap_andnot(ndev->mpls_features.bits, ndev->mpls_features.bits,
+		      features.bits, NETDEV_FEATURE_COUNT);
 }
 
 static inline void
 netdev_gso_partial_features_clear(struct net_device *ndev,
 				  const netdev_features_t features)
 {
-	ndev->gso_partial_features =
-		netdev_gso_partial_features_andnot(ndev, features);
+	bitmap_andnot(ndev->gso_partial_features.bits,
+		      ndev->gso_partial_features.bits, features.bits,
+		      NETDEV_FEATURE_COUNT);
 }
 
 /* helpers for netdev features 'set bit' operation */
 static inline void netdev_feature_add(int nr, netdev_features_t *src)
 {
-	*src |= __NETIF_F_BIT(nr);
+	__set_bit(nr, src->bits);
 }
 
 #define netdev_active_feature_add(ndev, nr) \
@@ -472,7 +515,7 @@ netdev_features_set_array(const struct netdev_feature_set *set,
 /* helpers for netdev features 'clear bit' operation */
 static inline void netdev_feature_del(int nr, netdev_features_t *src)
 {
-	*src &= ~__NETIF_F_BIT(nr);
+	__clear_bit(nr, src->bits);
 }
 
 #define netdev_active_feature_del(ndev, nr) \
@@ -499,7 +542,7 @@ static inline void netdev_feature_del(int nr, netdev_features_t *src)
 static inline bool netdev_features_intersects(const netdev_features_t src1,
 					      const netdev_features_t src2)
 {
-	return (src1 & src2) > 0;
+	return bitmap_intersects(src1.bits, src2.bits, NETDEV_FEATURE_COUNT);
 }
 
 #define netdev_active_features_intersects(ndev, __features) \
@@ -579,7 +622,7 @@ static inline void netdev_gso_partial_features_copy(struct net_device *ndev,
 static inline bool netdev_features_subset(const netdev_features_t src1,
 					  const netdev_features_t src2)
 {
-	return (src1 & src2) == src2;
+	return bitmap_subset(src1.bits, src2.bits, NETDEV_FEATURE_COUNT);
 }
 
 static inline netdev_features_t netdev_intersect_features(netdev_features_t f1,
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 91983aede92c..0c1a19671c1e 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -4869,30 +4869,31 @@ netdev_features_t netif_skb_features(struct sk_buff *skb);
 
 static inline bool net_gso_ok(netdev_features_t features, int gso_type)
 {
-	netdev_features_t feature = (netdev_features_t)gso_type << NETIF_F_GSO_SHIFT;
+#define GSO_INDEX(x)	((1ULL << (x)) >> NETIF_F_GSO_SHIFT)
+	netdev_features_t feature;
 
 	/* check flags correspondence */
-	BUILD_BUG_ON(SKB_GSO_TCPV4   != (NETIF_F_TSO >> NETIF_F_GSO_SHIFT));
-	BUILD_BUG_ON(SKB_GSO_DODGY   != (NETIF_F_GSO_ROBUST >> NETIF_F_GSO_SHIFT));
-	BUILD_BUG_ON(SKB_GSO_TCP_ECN != (NETIF_F_TSO_ECN >> NETIF_F_GSO_SHIFT));
-	BUILD_BUG_ON(SKB_GSO_TCP_FIXEDID != (NETIF_F_TSO_MANGLEID >> NETIF_F_GSO_SHIFT));
-	BUILD_BUG_ON(SKB_GSO_TCPV6   != (NETIF_F_TSO6 >> NETIF_F_GSO_SHIFT));
-	BUILD_BUG_ON(SKB_GSO_FCOE    != (NETIF_F_FSO >> NETIF_F_GSO_SHIFT));
-	BUILD_BUG_ON(SKB_GSO_GRE     != (NETIF_F_GSO_GRE >> NETIF_F_GSO_SHIFT));
-	BUILD_BUG_ON(SKB_GSO_GRE_CSUM != (NETIF_F_GSO_GRE_CSUM >> NETIF_F_GSO_SHIFT));
-	BUILD_BUG_ON(SKB_GSO_IPXIP4  != (NETIF_F_GSO_IPXIP4 >> NETIF_F_GSO_SHIFT));
-	BUILD_BUG_ON(SKB_GSO_IPXIP6  != (NETIF_F_GSO_IPXIP6 >> NETIF_F_GSO_SHIFT));
-	BUILD_BUG_ON(SKB_GSO_UDP_TUNNEL != (NETIF_F_GSO_UDP_TUNNEL >> NETIF_F_GSO_SHIFT));
-	BUILD_BUG_ON(SKB_GSO_UDP_TUNNEL_CSUM != (NETIF_F_GSO_UDP_TUNNEL_CSUM >> NETIF_F_GSO_SHIFT));
-	BUILD_BUG_ON(SKB_GSO_PARTIAL != (NETIF_F_GSO_PARTIAL >> NETIF_F_GSO_SHIFT));
-	BUILD_BUG_ON(SKB_GSO_TUNNEL_REMCSUM != (NETIF_F_GSO_TUNNEL_REMCSUM >> NETIF_F_GSO_SHIFT));
-	BUILD_BUG_ON(SKB_GSO_SCTP    != (NETIF_F_GSO_SCTP >> NETIF_F_GSO_SHIFT));
-	BUILD_BUG_ON(SKB_GSO_ESP != (NETIF_F_GSO_ESP >> NETIF_F_GSO_SHIFT));
-	BUILD_BUG_ON(SKB_GSO_UDP != (NETIF_F_GSO_UDP >> NETIF_F_GSO_SHIFT));
-	BUILD_BUG_ON(SKB_GSO_UDP_L4 != (NETIF_F_GSO_UDP_L4 >> NETIF_F_GSO_SHIFT));
-	BUILD_BUG_ON(SKB_GSO_FRAGLIST != (NETIF_F_GSO_FRAGLIST >> NETIF_F_GSO_SHIFT));
-
-	return (features & feature) == feature;
+		BUILD_BUG_ON(SKB_GSO_TCPV4   != GSO_INDEX(NETIF_F_TSO_BIT));
+	BUILD_BUG_ON(SKB_GSO_DODGY   != GSO_INDEX(NETIF_F_GSO_ROBUST_BIT));
+	BUILD_BUG_ON(SKB_GSO_TCP_ECN != GSO_INDEX(NETIF_F_TSO_ECN_BIT));
+	BUILD_BUG_ON(SKB_GSO_TCP_FIXEDID != GSO_INDEX(NETIF_F_TSO_MANGLEID_BIT));
+	BUILD_BUG_ON(SKB_GSO_TCPV6   != GSO_INDEX(NETIF_F_TSO6_BIT));
+	BUILD_BUG_ON(SKB_GSO_FCOE    != GSO_INDEX(NETIF_F_FSO_BIT));
+	BUILD_BUG_ON(SKB_GSO_GRE     != GSO_INDEX(NETIF_F_GSO_GRE_BIT));
+	BUILD_BUG_ON(SKB_GSO_GRE_CSUM != GSO_INDEX(NETIF_F_GSO_GRE_CSUM_BIT));
+	BUILD_BUG_ON(SKB_GSO_IPXIP4  != GSO_INDEX(NETIF_F_GSO_IPXIP4_BIT));
+	BUILD_BUG_ON(SKB_GSO_IPXIP6  != GSO_INDEX(NETIF_F_GSO_IPXIP6_BIT));
+	BUILD_BUG_ON(SKB_GSO_UDP_TUNNEL != GSO_INDEX(NETIF_F_GSO_UDP_TUNNEL_BIT));
+	BUILD_BUG_ON(SKB_GSO_UDP_TUNNEL_CSUM != GSO_INDEX(NETIF_F_GSO_UDP_TUNNEL_CSUM_BIT));
+	BUILD_BUG_ON(SKB_GSO_PARTIAL != GSO_INDEX(NETIF_F_GSO_PARTIAL_BIT));
+	BUILD_BUG_ON(SKB_GSO_TUNNEL_REMCSUM != GSO_INDEX(NETIF_F_GSO_TUNNEL_REMCSUM_BIT));
+	BUILD_BUG_ON(SKB_GSO_SCTP    != GSO_INDEX(NETIF_F_GSO_SCTP_BIT));
+	BUILD_BUG_ON(SKB_GSO_ESP != GSO_INDEX(NETIF_F_GSO_ESP_BIT));
+	BUILD_BUG_ON(SKB_GSO_UDP != GSO_INDEX(NETIF_F_GSO_UDP_BIT));
+	BUILD_BUG_ON(SKB_GSO_UDP_L4 != GSO_INDEX(NETIF_F_GSO_UDP_L4_BIT));
+	BUILD_BUG_ON(SKB_GSO_FRAGLIST != GSO_INDEX(NETIF_F_GSO_FRAGLIST_BIT));
+
+	return bitmap_subset(features.bits, feature.bits, NETDEV_FEATURE_COUNT);
 }
 
 static inline bool skb_gso_ok(struct sk_buff *skb, netdev_features_t features)
diff --git a/lib/vsprintf.c b/lib/vsprintf.c
index 40d26a07a133..6660d897b8b4 100644
--- a/lib/vsprintf.c
+++ b/lib/vsprintf.c
@@ -1753,25 +1753,24 @@ char *uuid_string(char *buf, char *end, const u8 *addr,
 }
 
 static noinline_for_stack
-char *netdev_bits(char *buf, char *end, const void *addr,
+char *netdev_bits(char *buf, char *end, void *addr,
 		  struct printf_spec spec,  const char *fmt)
 {
-	unsigned long long num;
-	int size;
+	unsigned long *bitmap;
 
 	if (check_pointer(&buf, end, addr, spec))
 		return buf;
 
 	switch (fmt[1]) {
 	case 'F':
-		num = *(const netdev_features_t *)addr;
-		size = sizeof(netdev_features_t);
+		bitmap = *(netdev_features_t *)addr->bits;
+		spec->field_width = NETDEV_FEATURE_COUNT;
 		break;
 	default:
 		return error_string(buf, end, "(%pN?)", spec);
 	}
 
-	return special_hex_number(buf, end, num, size);
+	return bitmap_string(buf, end, add->bits, spec, fmt);
 }
 
 static noinline_for_stack
diff --git a/net/core/dev.c b/net/core/dev.c
index 0962935f478e..15880102d169 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -9458,17 +9458,15 @@ static netdev_features_t netdev_sync_upper_features(struct net_device *lower,
 	struct net_device *upper, netdev_features_t features)
 {
 	netdev_features_t upper_disables;
-	netdev_features_t feature;
 	int feature_bit;
 
 	upper_disables = NETIF_F_UPPER_DISABLES;
 	for_each_netdev_feature(upper_disables, feature_bit) {
-		feature = __NETIF_F_BIT(feature_bit);
-		if (!netdev_wanted_features_intersects(upper, feature) &&
-		    netdev_features_intersects(features, feature)) {
-			netdev_dbg(lower, "Dropping feature %pNF, upper dev %s has it off.\n",
-				   &feature, upper->name);
-			netdev_features_clear(&features, feature);
+		if (!netdev_wanted_feature_test(feature_bit, upper) &&
+		    netdev_feature_test(feature_bit, features)) {
+			netdev_dbg(lower, "Dropping feature bit %d, upper dev %s has it off.\n",
+				   feature_bit, upper->name);
+			netdev_feature_del(feature_bit, &features);
 		}
 	}
 
@@ -9479,22 +9477,20 @@ static void netdev_sync_lower_features(struct net_device *upper,
 	struct net_device *lower, netdev_features_t features)
 {
 	netdev_features_t upper_disables;
-	netdev_features_t feature;
 	int feature_bit;
 
 	upper_disables = NETIF_F_UPPER_DISABLES;
 	for_each_netdev_feature(upper_disables, feature_bit) {
-		feature = __NETIF_F_BIT(feature_bit);
-		if (!netdev_features_intersects(features, feature) &&
-		    netdev_active_features_intersects(lower, feature)) {
-			netdev_dbg(upper, "Disabling feature %pNF on lower dev %s.\n",
-				   &feature, lower->name);
-			netdev_wanted_features_clear(lower, feature);
+		if (!netdev_feature_test(feature_bit, features) &&
+		    netdev_active_feature_test(lower, feature_bit)) {
+			netdev_dbg(upper, "Disabling feature bit %d on lower dev %s.\n",
+				   feature_bit, lower->name);
+			netdev_wanted_feature_del(lower, feature_bit);
 			__netdev_update_features(lower);
 
-			if (unlikely(netdev_active_features_intersects(lower, feature)))
-				netdev_WARN(upper, "failed to disable %pNF on %s!\n",
-					    &feature, lower->name);
+			if (unlikely(netdev_active_feature_test(lower, feature_bit)))
+				netdev_WARN(upper, "failed to disable feature bit %d on %s!\n",
+					    feature_bit, lower->name);
 			else
 				netdev_features_change(lower);
 		}
diff --git a/net/ethtool/features.c b/net/ethtool/features.c
index 93d56e8921a1..37a6144dd2fb 100644
--- a/net/ethtool/features.c
+++ b/net/ethtool/features.c
@@ -28,10 +28,7 @@ const struct nla_policy ethnl_features_get_policy[] = {
 
 static void ethnl_features_to_bitmap32(u32 *dest, netdev_features_t src)
 {
-	unsigned int i;
-
-	for (i = 0; i < ETHTOOL_DEV_FEATURE_WORDS; i++)
-		dest[i] = src >> (32 * i);
+	bitmap_to_arr32(dest, src.bits, ETHTOOL_DEV_FEATURE_WORDS);
 }
 
 static int features_prepare_data(const struct ethnl_req_info *req_base,
@@ -132,30 +129,6 @@ const struct nla_policy ethnl_features_set_policy[] = {
 	[ETHTOOL_A_FEATURES_WANTED]	= { .type = NLA_NESTED },
 };
 
-static void ethnl_features_to_bitmap(unsigned long *dest, netdev_features_t val)
-{
-	const unsigned int words = BITS_TO_LONGS(NETDEV_FEATURE_COUNT);
-	unsigned int i;
-
-	for (i = 0; i < words; i++)
-		dest[i] = (unsigned long)(val >> (i * BITS_PER_LONG));
-}
-
-static netdev_features_t ethnl_bitmap_to_features(unsigned long *src)
-{
-	const unsigned int nft_bits = sizeof(netdev_features_t) * BITS_PER_BYTE;
-	const unsigned int words = BITS_TO_LONGS(NETDEV_FEATURE_COUNT);
-	netdev_features_t ret;
-	unsigned int i;
-
-	netdev_features_zero(&ret);
-	for (i = 0; i < words; i++)
-		netdev_features_set(&ret,
-				    (netdev_features_t)(src[i]) << (i * BITS_PER_LONG));
-	ret &= ~(netdev_features_t)0 >> (nft_bits - NETDEV_FEATURE_COUNT);
-	return ret;
-}
-
 static int features_send_reply(struct net_device *dev, struct genl_info *info,
 			       const unsigned long *wanted,
 			       const unsigned long *wanted_mask,
@@ -212,18 +185,17 @@ static int features_send_reply(struct net_device *dev, struct genl_info *info,
 
 int ethnl_set_features(struct sk_buff *skb, struct genl_info *info)
 {
-	DECLARE_BITMAP(wanted_diff_mask, NETDEV_FEATURE_COUNT);
-	DECLARE_BITMAP(active_diff_mask, NETDEV_FEATURE_COUNT);
-	DECLARE_BITMAP(old_active, NETDEV_FEATURE_COUNT);
-	DECLARE_BITMAP(old_wanted, NETDEV_FEATURE_COUNT);
-	DECLARE_BITMAP(new_active, NETDEV_FEATURE_COUNT);
-	DECLARE_BITMAP(new_wanted, NETDEV_FEATURE_COUNT);
-	DECLARE_BITMAP(req_wanted, NETDEV_FEATURE_COUNT);
-	DECLARE_BITMAP(req_mask, NETDEV_FEATURE_COUNT);
 	struct ethnl_req_info req_info = {};
 	struct nlattr **tb = info->attrs;
+	netdev_features_t wanted_diff_mask;
+	netdev_features_t active_diff_mask;
+	netdev_features_t old_active;
+	netdev_features_t old_wanted;
+	netdev_features_t new_active;
+	netdev_features_t new_wanted;
+	netdev_features_t req_wanted;
+	netdev_features_t req_mask;
 	struct net_device *dev;
-	netdev_features_t tmp;
 	bool mod;
 	int ret;
 
@@ -238,47 +210,43 @@ int ethnl_set_features(struct sk_buff *skb, struct genl_info *info)
 	dev = req_info.dev;
 
 	rtnl_lock();
-	ethnl_features_to_bitmap(old_active, netdev_active_features(dev));
-	ethnl_features_to_bitmap(old_wanted, netdev_wanted_features(dev));
+	old_active = netdev_active_features(dev);
+	old_wanted = netdev_wanted_features(dev);
 	ret = ethnl_parse_bitset(req_wanted, req_mask, NETDEV_FEATURE_COUNT,
 				 tb[ETHTOOL_A_FEATURES_WANTED],
 				 netdev_features_strings, info->extack);
 	if (ret < 0)
 		goto out_rtnl;
-	if (ethnl_bitmap_to_features(req_mask) & ~NETIF_F_ETHTOOL_BITS) {
+	if (!netdev_features_subset(NETIF_F_ETHTOOL_BITS, req_mask)) {
 		GENL_SET_ERR_MSG(info, "attempt to change non-ethtool features");
 		ret = -EINVAL;
 		goto out_rtnl;
 	}
 
 	/* set req_wanted bits not in req_mask from old_wanted */
-	bitmap_and(req_wanted, req_wanted, req_mask, NETDEV_FEATURE_COUNT);
-	bitmap_andnot(new_wanted, old_wanted, req_mask, NETDEV_FEATURE_COUNT);
-	bitmap_or(req_wanted, new_wanted, req_wanted, NETDEV_FEATURE_COUNT);
-	if (!bitmap_equal(req_wanted, old_wanted, NETDEV_FEATURE_COUNT)) {
+	netdev_features_set(&req_wanted, req_mask);
+	new_wanted = netdev_features_andnot(old_wanted, req_mask);
+	netdev_features_set(&req_wanted, new_wanted);
+	if (!netdev_features_equal(req_wanted, old_wanted)) {
+		netdev_features_t tmp;
+
 		netdev_wanted_features_clear(dev, netdev_hw_features(dev));
-		tmp = netdev_hw_features_and(dev,
-					     ethnl_bitmap_to_features(req_wanted));
+		tmp = netdev_hw_features_and(dev, req_wanted);
 		netdev_wanted_features_set(dev, tmp);
 		__netdev_update_features(dev);
 	}
-	ethnl_features_to_bitmap(new_active, netdev_active_features(dev));
-	mod = !bitmap_equal(old_active, new_active, NETDEV_FEATURE_COUNT);
+	new_active = netdev_active_features(dev);
+	mod = !netdev_features_equal(old_active, new_active);
 
 	ret = 0;
 	if (!(req_info.flags & ETHTOOL_FLAG_OMIT_REPLY)) {
 		bool compact = req_info.flags & ETHTOOL_FLAG_COMPACT_BITSETS;
 
-		bitmap_xor(wanted_diff_mask, req_wanted, new_active,
-			   NETDEV_FEATURE_COUNT);
-		bitmap_xor(active_diff_mask, old_active, new_active,
-			   NETDEV_FEATURE_COUNT);
-		bitmap_and(wanted_diff_mask, wanted_diff_mask, req_mask,
-			   NETDEV_FEATURE_COUNT);
-		bitmap_and(req_wanted, req_wanted, wanted_diff_mask,
-			   NETDEV_FEATURE_COUNT);
-		bitmap_and(new_active, new_active, active_diff_mask,
-			   NETDEV_FEATURE_COUNT);
+		wanted_diff_mask = netdev_features_xor(req_wanted, new_active);
+		active_diff_mask = netdev_features_xor(old_active, new_active);
+		netdev_features_mask(&wanted_diff_mask, req_mask);
+		netdev_features_mask(&req_wanted, wanted_diff_mask);
+		netdev_features_mask(&new_active, active_diff_mask);
 
 		ret = features_send_reply(dev, info, req_wanted,
 					  wanted_diff_mask, new_active,
diff --git a/net/ethtool/ioctl.c b/net/ethtool/ioctl.c
index 02c2741c0d6b..c4725c4e7f0f 100644
--- a/net/ethtool/ioctl.c
+++ b/net/ethtool/ioctl.c
@@ -89,6 +89,10 @@ static int ethtool_get_features(struct net_device *dev, void __user *useraddr)
 		.size = ETHTOOL_DEV_FEATURE_WORDS,
 	};
 	struct ethtool_get_features_block features[ETHTOOL_DEV_FEATURE_WORDS];
+	u32 never_changed_arr[ETHTOOL_DEV_FEATURE_WORDS];
+	u32 wanted_arr[ETHTOOL_DEV_FEATURE_WORDS];
+	u32 active_arr[ETHTOOL_DEV_FEATURE_WORDS];
+	u32 hw_arr[ETHTOOL_DEV_FEATURE_WORDS];
 	u32 __user *sizeaddr;
 	u32 copy_size;
 	int i;
@@ -96,12 +100,15 @@ static int ethtool_get_features(struct net_device *dev, void __user *useraddr)
 	/* in case feature bits run out again */
 	BUILD_BUG_ON(ETHTOOL_DEV_FEATURE_WORDS * sizeof(u32) > sizeof(netdev_features_t));
 
+	bitmap_to_arr32(hw_arr, netdev_hw_features(dev), NETDEV_FEATURE_COUNT);
+	bitmap_to_arr32(wanted_arr, netdev_wanted_features(dev), NETDEV_FEATURE_COUNT);
+	bitmap_to_arr32(active_arr, netdev_active_features(dev), NETDEV_FEATURE_COUNT);
+	bitmap_to_arr32(never_changed_arr, NETIF_F_NEVER_CHANGE, NETDEV_FEATURE_COUNT);
 	for (i = 0; i < ETHTOOL_DEV_FEATURE_WORDS; ++i) {
-		features[i].available = (u32)(netdev_hw_features(dev) >> (32 * i));
-		features[i].requested = (u32)(netdev_wanted_features(dev) >> (32 * i));
-		features[i].active = (u32)(netdev_active_features(dev) >> (32 * i));
-		features[i].never_changed =
-			(u32)(NETIF_F_NEVER_CHANGE >> (32 * i));
+		features[i].available = hw_arr[i];
+		features[i].requested = wanted_arr[i];
+		features[i].active = active_arr[i];
+		features[i].never_changed = never_changed_arr[i];
 	}
 
 	sizeaddr = useraddr + offsetof(struct ethtool_gfeatures, size);
@@ -125,6 +132,8 @@ 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];
+	u32 wanted_arr[ETHTOOL_DEV_FEATURE_WORDS];
+	u32 valid_arr[ETHTOOL_DEV_FEATURE_WORDS];
 	netdev_features_t wanted;
 	netdev_features_t valid;
 	netdev_features_t tmp;
@@ -140,14 +149,12 @@ static int ethtool_set_features(struct net_device *dev, void __user *useraddr)
 	if (copy_from_user(features, useraddr, sizeof(features)))
 		return -EFAULT;
 
-	netdev_features_zero(&wanted);
-	netdev_features_zero(&valid);
 	for (i = 0; i < ETHTOOL_DEV_FEATURE_WORDS; ++i) {
-		netdev_features_set(&valid,
-				    (netdev_features_t)features[i].valid << (32 * i));
-		netdev_features_set(&wanted,
-				    (netdev_features_t)features[i].requested << (32 * i));
+		valid_arr[i] = features[i].valid;
+		wanted_arr[i] = features[i].requested;
 	}
+	bitmap_from_arr32(valid.bits, valid_arr, NETDEV_FEATURE_COUNT);
+	bitmap_from_arr32(wanted.bits, wanted_arr, NETDEV_FEATURE_COUNT);
 
 	tmp = netdev_features_andnot(valid, NETIF_F_ETHTOOL_BITS);
 	if (tmp)
@@ -365,7 +372,7 @@ static int __ethtool_set_flags(struct net_device *dev, u32 data)
 	changed = netdev_active_features_xor(dev, features);
 	netdev_features_mask(&changed, eth_all_features);
 	tmp = netdev_hw_features_andnot_r(dev, changed);
-	if (tmp)
+	if (!netdev_features_empty(tmp))
 		return netdev_hw_features_intersects(dev, changed) ? -EINVAL : -EOPNOTSUPP;
 
 	netdev_wanted_features_clear(dev, changed);
-- 
2.33.0


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* Re: [RFCv6 PATCH net-next 01/19] net: introduce operation helpers for netdev features
  2022-04-19  2:21 ` [RFCv6 PATCH net-next 01/19] net: introduce operation helpers for netdev features Jian Shen
@ 2022-04-19 14:40   ` Alexander Lobakin
  2022-04-20  9:24     ` shenjian (K)
  0 siblings, 1 reply; 30+ messages in thread
From: Alexander Lobakin @ 2022-04-19 14:40 UTC (permalink / raw)
  To: Jian Shen
  Cc: Alexander Lobakin, davem, kuba, andrew, ecree.xilinx, hkallweit1,
	saeed, leon, netdev, linuxarm, lipeng321

From: Jian Shen <shenjian15@huawei.com>
Date: Tue, 19 Apr 2022 10:21:48 +0800

> Introduce a set of bitmap operation helpers for netdev features,
> then we can use them to replace the logical operation with them.
> As the nic driversare not supposed to modify netdev_features
> directly, it also introduces wrappers helpers to this.
> 
> The implementation of these helpers are based on the old prototype
> of netdev_features_t is still u64. I will rewrite them on the last
> patch, when the prototype changes.
> 
> To avoid interdependencies between netdev_features_helper.h and
> netdevice.h, put the helpers for testing feature is set in the
> netdevice.h, and move advandced helpers like
> netdev_get_wanted_features() and netdev_intersect_features() to
> netdev_features_helper.h.
> 
> Signed-off-by: Jian Shen <shenjian15@huawei.com>
> ---
>  .../net/ethernet/netronome/nfp/nfp_net_repr.c |   1 +
>  include/linux/netdev_features.h               |  12 +
>  include/linux/netdev_features_helper.h        | 604 ++++++++++++++++++
>  include/linux/netdevice.h                     |  45 +-
>  net/8021q/vlan_dev.c                          |   1 +
>  net/core/dev.c                                |   1 +
>  6 files changed, 646 insertions(+), 18 deletions(-)
>  create mode 100644 include/linux/netdev_features_helper.h
> 
> diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_repr.c b/drivers/net/ethernet/netronome/nfp/nfp_net_repr.c
> index ba3fa7eac98d..08f2c54e0a11 100644
> --- a/drivers/net/ethernet/netronome/nfp/nfp_net_repr.c
> +++ b/drivers/net/ethernet/netronome/nfp/nfp_net_repr.c
> @@ -4,6 +4,7 @@
>  #include <linux/etherdevice.h>
>  #include <linux/io-64-nonatomic-hi-lo.h>
>  #include <linux/lockdep.h>
> +#include <linux/netdev_features_helper.h>
>  #include <net/dst_metadata.h>
>  
>  #include "nfpcore/nfp_cpp.h"
> diff --git a/include/linux/netdev_features.h b/include/linux/netdev_features.h
> index 2c6b9e416225..e2b66fa3d7d6 100644
> --- a/include/linux/netdev_features.h
> +++ b/include/linux/netdev_features.h
> @@ -11,6 +11,18 @@
>  
>  typedef u64 netdev_features_t;
>  
> +struct netdev_feature_set {
> +	unsigned int cnt;
> +	unsigned short feature_bits[];
> +};
> +
> +#define DECLARE_NETDEV_FEATURE_SET(name, features...)		\
> +	static unsigned short __##name##_s[] = {features};	\
> +	struct netdev_feature_set name = {			\

I suggest using `const` here. Those sets are needed only to
initialize bitmaps, that's it. They are not supposed to be
modified. This would be one more hardening here to avoid some weird
usages of sets, and also would place them in .rodata instead of just
.data.

Function                                     old     new   delta
main                                          35      33      -2
Total: Before=78, After=76, chg -2.56%
add/remove: 0/2 grow/shrink: 0/0 up/down: 0/-14 (-14)
Data                                         old     new   delta
arr1                                           6       -      -6
arr2                                           8       -      -8
Total: Before=15, After=1, chg -93.33%
add/remove: 2/0 grow/shrink: 0/0 up/down: 14/0 (14)
RO Data                                      old     new   delta
arr1                                           -       8      +8
arr2                                           -       6      +6
Total: Before=36, After=50, chg +38.89%

As you can see, there's a 2-byte code optimization. And that was
just a simpliest oneliner. The gains will be much bigger from the
real usages.

> +		.cnt = ARRAY_SIZE(__##name##_s),		\
> +		.feature_bits = {features},			\
> +	}

The problem with the current macro is that it doesn't allow to
declare feature sets as static. Because the temporary array for
counting the number of bits goes first, and doing

static DECLARE_NETDEV_FEATURE_SET();

wouldn't change anything.
But we want to have most feature sets static as they will be needed
only inside one file. Making every of them global would hurt
optimization.

At the end, I came to

#define DECLARE_NETDEV_FEATURE_SET(name, features...)			\
	const struct netdev_feature_set name = {			\
		.feature_bits = { features },				\
		.cnt = sizeof((u16 []){ features }) / sizeof(u16),	\
	}

because ARRAY_SIZE() can be taken only from a variable, not from
a compound literal.
But this one is actually OK. We don't need ARRAY_SIZE() in here
since we define an unnamed array of an explicit type that we know
for sure inline. So there's no chance to do it wrong as long as
the @features argument is correct.

The ability to make it static is important. For example, when I
marked them both static, I got

add/remove: 0/0 grow/shrink: 0/0 up/down: 0/0 (0)
Function                                     old     new   delta
Total: Before=76, After=76, chg +0.00%
add/remove: 0/0 grow/shrink: 0/0 up/down: 0/0 (0)
Data                                         old     new   delta
Total: Before=1, After=1, chg +0.00%
add/remove: 0/2 grow/shrink: 0/0 up/down: 0/-14 (-14)
RO Data                                      old     new   delta
arr1                                           6       -      -6
arr2                                           8       -      -8
Total: Before=50, After=36, chg -28.00%

i.e. both of the sets were removed, because my main() was:

	printf("cnt1: %u, cnt2: %u\n", arr1.cnt, arr2.cnt);

The compiler saw that I don't use them, except for printing values
which are actually compile-time constants, and wiped them.
Previously, they were global so it didn't have a clue if they're
used anywhere else.
This was a simple stupid example, but it will bring a lot more value
in real use cases. So please consider my variant :D

> +
>  enum {
>  	NETIF_F_SG_BIT,			/* Scatter/gather IO. */
>  	NETIF_F_IP_CSUM_BIT,		/* Can checksum TCP/UDP over IPv4. */

--- 8< ---

> -- 
> 2.33.0

Thanks,
Al

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [RFCv6 PATCH net-next 02/19] net: replace general features macroes with global netdev_features variables
  2022-04-19  2:21 ` [RFCv6 PATCH net-next 02/19] net: replace general features macroes with global netdev_features variables Jian Shen
@ 2022-04-19 14:49   ` Alexander Lobakin
  2022-04-20  9:54     ` shenjian (K)
  0 siblings, 1 reply; 30+ messages in thread
From: Alexander Lobakin @ 2022-04-19 14:49 UTC (permalink / raw)
  To: Jian Shen
  Cc: Alexander Lobakin, davem, kuba, andrew, ecree.xilinx, hkallweit1,
	saeed, leon, netdev, linuxarm, lipeng321

From: Jian Shen <shenjian15@huawei.com>
Date: Tue, 19 Apr 2022 10:21:49 +0800

> There are many netdev_features bits group used in kernel. The definition
> will be illegal when using feature bit more than 64. Replace these macroes
> with global netdev_features variables, initialize them when netdev module
> init.
> 
> Signed-off-by: Jian Shen <shenjian15@huawei.com>
> ---
>  drivers/net/wireguard/device.c  |  10 +-
>  include/linux/netdev_features.h | 102 +++++++++-----
>  net/core/Makefile               |   2 +-
>  net/core/dev.c                  |  87 ++++++++++++
>  net/core/netdev_features.c      | 241 ++++++++++++++++++++++++++++++++
>  5 files changed, 400 insertions(+), 42 deletions(-)
>  create mode 100644 net/core/netdev_features.c
> 

--- 8< ---

> diff --git a/net/core/dev.c b/net/core/dev.c
> index 4d6b57752eee..85bb418e8ef1 100644
> --- a/net/core/dev.c
> +++ b/net/core/dev.c
> @@ -146,6 +146,7 @@
>  #include <linux/sctp.h>
>  #include <net/udp_tunnel.h>
>  #include <linux/net_namespace.h>
> +#include <linux/netdev_features_helper.h>
>  #include <linux/indirect_call_wrapper.h>
>  #include <net/devlink.h>
>  #include <linux/pm_runtime.h>
> @@ -11255,6 +11256,90 @@ static struct pernet_operations __net_initdata default_device_ops = {
>  	.exit_batch = default_device_exit_batch,
>  };
>  
> +static void netdev_features_init(void)

It is an initialization function, so it must be marked as __init.

> +{
> +	netdev_features_t features;
> +
> +	netdev_features_set_array(&netif_f_never_change_feature_set,
> +				  &netdev_never_change_features);
> +
> +	netdev_features_set_array(&netif_f_gso_feature_set_mask,

I'm not sure it does make sense to have an empty newline between
each call. I'd leave newlines only between the "regular" blocks
and the "multi-call" blocks, I mean, stuff like VLAN, GSO and
@netdev_ethtool_features.

> +				  &netdev_gso_features_mask);
> +
> +	netdev_features_set_array(&netif_f_ip_csum_feature_set,
> +				  &netdev_ip_csum_features);
> +
> +	netdev_features_set_array(&netif_f_csum_feature_set_mask,
> +				  &netdev_csum_features_mask);
> +
> +	netdev_features_set_array(&netif_f_general_tso_feature_set,
> +				  &netdev_general_tso_features);
> +
> +	netdev_features_set_array(&netif_f_all_tso_feature_set,
> +				  &netdev_all_tso_features);
> +
> +	netdev_features_set_array(&netif_f_tso_ecn_feature_set,
> +				  &netdev_tso_ecn_features);
> +
> +	netdev_features_set_array(&netif_f_all_fcoe_feature_set,
> +				  &netdev_all_fcoe_features);
> +
> +	netdev_features_set_array(&netif_f_gso_soft_feature_set,
> +				  &netdev_gso_software_features);
> +
> +	netdev_features_set_array(&netif_f_one_for_all_feature_set,
> +				  &netdev_one_for_all_features);
> +
> +	netdev_features_set_array(&netif_f_all_for_all_feature_set,
> +				  &netdev_all_for_all_features);
> +
> +	netdev_features_set_array(&netif_f_upper_disables_feature_set,
> +				  &netdev_upper_disable_features);
> +
> +	netdev_features_set_array(&netif_f_soft_feature_set,
> +				  &netdev_soft_features);
> +
> +	netdev_features_set_array(&netif_f_soft_off_feature_set,
> +				  &netdev_soft_off_features);
> +
> +	netdev_features_set_array(&netif_f_rx_vlan_feature_set,
> +				  &netdev_rx_vlan_features);
> +
> +	netdev_features_set_array(&netif_f_tx_vlan_feature_set,
> +				  &netdev_tx_vlan_features);
> +
> +	netdev_features_set_array(&netif_f_vlan_filter_feature_set,
> +				  &netdev_vlan_filter_features);
> +
> +	netdev_all_vlan_features = netdev_rx_vlan_features;
> +	netdev_features_set(&netdev_all_vlan_features, netdev_tx_vlan_features);
> +	netdev_features_set(&netdev_all_vlan_features,
> +			    netdev_vlan_filter_features);
> +
> +	netdev_features_set_array(&netif_f_ctag_vlan_feature_set,
> +				  &netdev_ctag_vlan_features);
> +
> +	netdev_features_set_array(&netif_f_stag_vlan_feature_set,
> +				  &netdev_stag_vlan_features);
> +
> +	netdev_features_set_array(&netif_f_gso_encap_feature_set,
> +				  &netdev_gso_encap_all_features);
> +
> +	netdev_features_set_array(&netif_f_xfrm_feature_set,
> +				  &netdev_xfrm_features);
> +
> +	netdev_features_set_array(&netif_f_tls_feature_set,
> +				  &netdev_tls_features);
> +
> +	netdev_csum_gso_features_mask =
> +		netdev_features_or(netdev_gso_software_features,
> +				   netdev_csum_features_mask);
> +
> +	netdev_features_fill(&features);
> +	netdev_ethtool_features =
> +		netdev_features_andnot(features, netdev_never_change_features);
> +}
> +
>  /*
>   *	Initialize the DEV module. At boot time this walks the device list and
>   *	unhooks any devices that fail to initialise (normally hardware not

--- 8< ---

> -- 
> 2.33.0

Thanks,
Al

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [RFCv6 PATCH net-next 01/19] net: introduce operation helpers for netdev features
  2022-04-19 14:40   ` Alexander Lobakin
@ 2022-04-20  9:24     ` shenjian (K)
  0 siblings, 0 replies; 30+ messages in thread
From: shenjian (K) @ 2022-04-20  9:24 UTC (permalink / raw)
  To: Alexander Lobakin
  Cc: davem, kuba, andrew, ecree.xilinx, hkallweit1, saeed, leon,
	netdev, linuxarm, lipeng321


在 2022/4/19 22:40, Alexander Lobakin 写道:
> From: Jian Shen <shenjian15@huawei.com>
> Date: Tue, 19 Apr 2022 10:21:48 +0800
>
>> Introduce a set of bitmap operation helpers for netdev features,
>> then we can use them to replace the logical operation with them.
>> As the nic driversare not supposed to modify netdev_features
>> directly, it also introduces wrappers helpers to this.
>>
>> The implementation of these helpers are based on the old prototype
>> of netdev_features_t is still u64. I will rewrite them on the last
>> patch, when the prototype changes.
>>
>> To avoid interdependencies between netdev_features_helper.h and
>> netdevice.h, put the helpers for testing feature is set in the
>> netdevice.h, and move advandced helpers like
>> netdev_get_wanted_features() and netdev_intersect_features() to
>> netdev_features_helper.h.
>>
>> Signed-off-by: Jian Shen <shenjian15@huawei.com>
>> ---
>>   .../net/ethernet/netronome/nfp/nfp_net_repr.c |   1 +
>>   include/linux/netdev_features.h               |  12 +
>>   include/linux/netdev_features_helper.h        | 604 ++++++++++++++++++
>>   include/linux/netdevice.h                     |  45 +-
>>   net/8021q/vlan_dev.c                          |   1 +
>>   net/core/dev.c                                |   1 +
>>   6 files changed, 646 insertions(+), 18 deletions(-)
>>   create mode 100644 include/linux/netdev_features_helper.h
>>
>> diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_repr.c b/drivers/net/ethernet/netronome/nfp/nfp_net_repr.c
>> index ba3fa7eac98d..08f2c54e0a11 100644
>> --- a/drivers/net/ethernet/netronome/nfp/nfp_net_repr.c
>> +++ b/drivers/net/ethernet/netronome/nfp/nfp_net_repr.c
>> @@ -4,6 +4,7 @@
>>   #include <linux/etherdevice.h>
>>   #include <linux/io-64-nonatomic-hi-lo.h>
>>   #include <linux/lockdep.h>
>> +#include <linux/netdev_features_helper.h>
>>   #include <net/dst_metadata.h>
>>   
>>   #include "nfpcore/nfp_cpp.h"
>> diff --git a/include/linux/netdev_features.h b/include/linux/netdev_features.h
>> index 2c6b9e416225..e2b66fa3d7d6 100644
>> --- a/include/linux/netdev_features.h
>> +++ b/include/linux/netdev_features.h
>> @@ -11,6 +11,18 @@
>>   
>>   typedef u64 netdev_features_t;
>>   
>> +struct netdev_feature_set {
>> +	unsigned int cnt;
>> +	unsigned short feature_bits[];
>> +};
>> +
>> +#define DECLARE_NETDEV_FEATURE_SET(name, features...)		\
>> +	static unsigned short __##name##_s[] = {features};	\
>> +	struct netdev_feature_set name = {			\
> I suggest using `const` here. Those sets are needed only to
> initialize bitmaps, that's it. They are not supposed to be
> modified. This would be one more hardening here to avoid some weird
> usages of sets, and also would place them in .rodata instead of just
> .data.
>
> Function                                     old     new   delta
> main                                          35      33      -2
> Total: Before=78, After=76, chg -2.56%
> add/remove: 0/2 grow/shrink: 0/0 up/down: 0/-14 (-14)
> Data                                         old     new   delta
> arr1                                           6       -      -6
> arr2                                           8       -      -8
> Total: Before=15, After=1, chg -93.33%
> add/remove: 2/0 grow/shrink: 0/0 up/down: 14/0 (14)
> RO Data                                      old     new   delta
> arr1                                           -       8      +8
> arr2                                           -       6      +6
> Total: Before=36, After=50, chg +38.89%
>
> As you can see, there's a 2-byte code optimization. And that was
> just a simpliest oneliner. The gains will be much bigger from the
> real usages.
thanks, will add it.


>> +		.cnt = ARRAY_SIZE(__##name##_s),		\
>> +		.feature_bits = {features},			\
>> +	}
> The problem with the current macro is that it doesn't allow to
> declare feature sets as static. Because the temporary array for
> counting the number of bits goes first, and doing
>
> static DECLARE_NETDEV_FEATURE_SET();
>
> wouldn't change anything.
Yes, it bothered me.

> But we want to have most feature sets static as they will be needed
> only inside one file. Making every of them global would hurt
> optimization.
>
> At the end, I came to
>
> #define DECLARE_NETDEV_FEATURE_SET(name, features...)			\
> 	const struct netdev_feature_set name = {			\
> 		.feature_bits = { features },				\
> 		.cnt = sizeof((u16 []){ features }) / sizeof(u16),	\
> 	}
>
> because ARRAY_SIZE() can be taken only from a variable, not from
> a compound literal.
> But this one is actually OK. We don't need ARRAY_SIZE() in here
> since we define an unnamed array of an explicit type that we know
> for sure inline. So there's no chance to do it wrong as long as
> the @features argument is correct.
>
> The ability to make it static is important. For example, when I
> marked them both static, I got
>
> add/remove: 0/0 grow/shrink: 0/0 up/down: 0/0 (0)
> Function                                     old     new   delta
> Total: Before=76, After=76, chg +0.00%
> add/remove: 0/0 grow/shrink: 0/0 up/down: 0/0 (0)
> Data                                         old     new   delta
> Total: Before=1, After=1, chg +0.00%
> add/remove: 0/2 grow/shrink: 0/0 up/down: 0/-14 (-14)
> RO Data                                      old     new   delta
> arr1                                           6       -      -6
> arr2                                           8       -      -8
> Total: Before=50, After=36, chg -28.00%
>
> i.e. both of the sets were removed, because my main() was:
>
> 	printf("cnt1: %u, cnt2: %u\n", arr1.cnt, arr2.cnt);
>
> The compiler saw that I don't use them, except for printing values
> which are actually compile-time constants, and wiped them.
> Previously, they were global so it didn't have a clue if they're
> used anywhere else.
> This was a simple stupid example, but it will bring a lot more value
> in real use cases. So please consider my variant :D

Make sense. I will fix it.

Thanks a lot!


>> +
>>   enum {
>>   	NETIF_F_SG_BIT,			/* Scatter/gather IO. */
>>   	NETIF_F_IP_CSUM_BIT,		/* Can checksum TCP/UDP over IPv4. */
> --- 8< ---
>
>> -- 
>> 2.33.0
> Thanks,
> Al
> .
>


^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [RFCv6 PATCH net-next 02/19] net: replace general features macroes with global netdev_features variables
  2022-04-19 14:49   ` Alexander Lobakin
@ 2022-04-20  9:54     ` shenjian (K)
  2022-07-20 15:09       ` Alexander Lobakin
                         ` (2 more replies)
  0 siblings, 3 replies; 30+ messages in thread
From: shenjian (K) @ 2022-04-20  9:54 UTC (permalink / raw)
  To: Alexander Lobakin
  Cc: davem, kuba, andrew, ecree.xilinx, hkallweit1, saeed, leon,
	netdev, linuxarm, lipeng321



在 2022/4/19 22:49, Alexander Lobakin 写道:
> From: Jian Shen <shenjian15@huawei.com>
> Date: Tue, 19 Apr 2022 10:21:49 +0800
>
>> There are many netdev_features bits group used in kernel. The definition
>> will be illegal when using feature bit more than 64. Replace these macroes
>> with global netdev_features variables, initialize them when netdev module
>> init.
>>
>> Signed-off-by: Jian Shen <shenjian15@huawei.com>
>> ---
>>   drivers/net/wireguard/device.c  |  10 +-
>>   include/linux/netdev_features.h | 102 +++++++++-----
>>   net/core/Makefile               |   2 +-
>>   net/core/dev.c                  |  87 ++++++++++++
>>   net/core/netdev_features.c      | 241 ++++++++++++++++++++++++++++++++
>>   5 files changed, 400 insertions(+), 42 deletions(-)
>>   create mode 100644 net/core/netdev_features.c
>>
> --- 8< ---
>
>> diff --git a/net/core/dev.c b/net/core/dev.c
>> index 4d6b57752eee..85bb418e8ef1 100644
>> --- a/net/core/dev.c
>> +++ b/net/core/dev.c
>> @@ -146,6 +146,7 @@
>>   #include <linux/sctp.h>
>>   #include <net/udp_tunnel.h>
>>   #include <linux/net_namespace.h>
>> +#include <linux/netdev_features_helper.h>
>>   #include <linux/indirect_call_wrapper.h>
>>   #include <net/devlink.h>
>>   #include <linux/pm_runtime.h>
>> @@ -11255,6 +11256,90 @@ static struct pernet_operations __net_initdata default_device_ops = {
>>   	.exit_batch = default_device_exit_batch,
>>   };
>>   
>> +static void netdev_features_init(void)
> It is an initialization function, so it must be marked as __init.
right, I will add it, thanks!

>> +{
>> +	netdev_features_t features;
>> +
>> +	netdev_features_set_array(&netif_f_never_change_feature_set,
>> +				  &netdev_never_change_features);
>> +
>> +	netdev_features_set_array(&netif_f_gso_feature_set_mask,
> I'm not sure it does make sense to have an empty newline between
> each call. I'd leave newlines only between the "regular" blocks
> and the "multi-call" blocks, I mean, stuff like VLAN, GSO and
> @netdev_ethtool_features.
At first, I added empty newline per call for the it used three lines.
Now the new call just use two lines, I will remove some unnecessary
blank lines.

Thanks!

>> +				  &netdev_gso_features_mask);
>> +
>> +	netdev_features_set_array(&netif_f_ip_csum_feature_set,
>> +				  &netdev_ip_csum_features);
>> +
>> +	netdev_features_set_array(&netif_f_csum_feature_set_mask,
>> +				  &netdev_csum_features_mask);
>> +
>> +	netdev_features_set_array(&netif_f_general_tso_feature_set,
>> +				  &netdev_general_tso_features);
>> +
>> +	netdev_features_set_array(&netif_f_all_tso_feature_set,
>> +				  &netdev_all_tso_features);
>> +
>> +	netdev_features_set_array(&netif_f_tso_ecn_feature_set,
>> +				  &netdev_tso_ecn_features);
>> +
>> +	netdev_features_set_array(&netif_f_all_fcoe_feature_set,
>> +				  &netdev_all_fcoe_features);
>> +
>> +	netdev_features_set_array(&netif_f_gso_soft_feature_set,
>> +				  &netdev_gso_software_features);
>> +
>> +	netdev_features_set_array(&netif_f_one_for_all_feature_set,
>> +				  &netdev_one_for_all_features);
>> +
>> +	netdev_features_set_array(&netif_f_all_for_all_feature_set,
>> +				  &netdev_all_for_all_features);
>> +
>> +	netdev_features_set_array(&netif_f_upper_disables_feature_set,
>> +				  &netdev_upper_disable_features);
>> +
>> +	netdev_features_set_array(&netif_f_soft_feature_set,
>> +				  &netdev_soft_features);
>> +
>> +	netdev_features_set_array(&netif_f_soft_off_feature_set,
>> +				  &netdev_soft_off_features);
>> +
>> +	netdev_features_set_array(&netif_f_rx_vlan_feature_set,
>> +				  &netdev_rx_vlan_features);
>> +
>> +	netdev_features_set_array(&netif_f_tx_vlan_feature_set,
>> +				  &netdev_tx_vlan_features);
>> +
>> +	netdev_features_set_array(&netif_f_vlan_filter_feature_set,
>> +				  &netdev_vlan_filter_features);
>> +
>> +	netdev_all_vlan_features = netdev_rx_vlan_features;
>> +	netdev_features_set(&netdev_all_vlan_features, netdev_tx_vlan_features);
>> +	netdev_features_set(&netdev_all_vlan_features,
>> +			    netdev_vlan_filter_features);
>> +
>> +	netdev_features_set_array(&netif_f_ctag_vlan_feature_set,
>> +				  &netdev_ctag_vlan_features);
>> +
>> +	netdev_features_set_array(&netif_f_stag_vlan_feature_set,
>> +				  &netdev_stag_vlan_features);
>> +
>> +	netdev_features_set_array(&netif_f_gso_encap_feature_set,
>> +				  &netdev_gso_encap_all_features);
>> +
>> +	netdev_features_set_array(&netif_f_xfrm_feature_set,
>> +				  &netdev_xfrm_features);
>> +
>> +	netdev_features_set_array(&netif_f_tls_feature_set,
>> +				  &netdev_tls_features);
>> +
>> +	netdev_csum_gso_features_mask =
>> +		netdev_features_or(netdev_gso_software_features,
>> +				   netdev_csum_features_mask);
>> +
>> +	netdev_features_fill(&features);
>> +	netdev_ethtool_features =
>> +		netdev_features_andnot(features, netdev_never_change_features);
>> +}
>> +
>>   /*
>>    *	Initialize the DEV module. At boot time this walks the device list and
>>    *	unhooks any devices that fail to initialise (normally hardware not
> --- 8< ---
>
>> -- 
>> 2.33.0
> Thanks,
> Al
>
> .
>


^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [RFCv6 PATCH net-next 02/19] net: replace general features macroes with global netdev_features variables
  2022-04-20  9:54     ` shenjian (K)
@ 2022-07-20 15:09       ` Alexander Lobakin
  2022-07-21  1:15         ` shenjian (K)
  2022-07-20 15:10       ` Alexander Lobakin
  2022-07-20 15:13       ` Alexander Lobakin
  2 siblings, 1 reply; 30+ messages in thread
From: Alexander Lobakin @ 2022-07-20 15:09 UTC (permalink / raw)
  To: shenjian (K)
  Cc: Alexander Lobakin, davem, kuba, andrew, ecree.xilinx, hkallweit1,
	saeed, leon, netdev, linuxarm, lipeng321, Maciej Fijalkowski,
	Michal Swiatkowski

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset="us-ascii"; format=flowed, Size: 5613 bytes --]

From: shenjian (K) <shenjian15@huawei.com>
Date: Wed, 20 Apr 2022 17:54:13 +0800

> 在 2022/4/19 22:49, Alexander Lobakin 写道:
> > From: Jian Shen <shenjian15@huawei.com>
> > Date: Tue, 19 Apr 2022 10:21:49 +0800
> >
> >> There are many netdev_features bits group used in kernel. The definition
> >> will be illegal when using feature bit more than 64. Replace these macroes
> >> with global netdev_features variables, initialize them when netdev module
> >> init.
> >>
> >> Signed-off-by: Jian Shen <shenjian15@huawei.com>
> >> ---
> >>   drivers/net/wireguard/device.c  |  10 +-
> >>   include/linux/netdev_features.h | 102 +++++++++-----
> >>   net/core/Makefile               |   2 +-
> >>   net/core/dev.c                  |  87 ++++++++++++
> >>   net/core/netdev_features.c      | 241 ++++++++++++++++++++++++++++++++
> >>   5 files changed, 400 insertions(+), 42 deletions(-)
> >>   create mode 100644 net/core/netdev_features.c
> >>
> > --- 8< ---
> >
> >> diff --git a/net/core/dev.c b/net/core/dev.c
> >> index 4d6b57752eee..85bb418e8ef1 100644
> >> --- a/net/core/dev.c
> >> +++ b/net/core/dev.c
> >> @@ -146,6 +146,7 @@
> >>   #include <linux/sctp.h>
> >>   #include <net/udp_tunnel.h>
> >>   #include <linux/net_namespace.h>
> >> +#include <linux/netdev_features_helper.h>
> >>   #include <linux/indirect_call_wrapper.h>
> >>   #include <net/devlink.h>
> >>   #include <linux/pm_runtime.h>
> >> @@ -11255,6 +11256,90 @@ static struct pernet_operations __net_initdata default_device_ops = {
> >>   	.exit_batch = default_device_exit_batch,
> >>   };
> >>   
> >> +static void netdev_features_init(void)
> > It is an initialization function, so it must be marked as __init.
> right, I will add it, thanks!
> 
> >> +{
> >> +	netdev_features_t features;
> >> +
> >> +	netdev_features_set_array(&netif_f_never_change_feature_set,
> >> +				  &netdev_never_change_features);
> >> +
> >> +	netdev_features_set_array(&netif_f_gso_feature_set_mask,
> > I'm not sure it does make sense to have an empty newline between
> > each call. I'd leave newlines only between the "regular" blocks
> > and the "multi-call" blocks, I mean, stuff like VLAN, GSO and
> > @netdev_ethtool_features.
> At first, I added empty newline per call for the it used three lines.
> Now the new call just use two lines, I will remove some unnecessary
> blank lines.
> 
> Thanks!

I see no news regarding the conversion since the end of April, maybe
I could pick it and finish if nobody objects? I'll preserve the
original authorship for sure.

> 
> >> +				  &netdev_gso_features_mask);
> >> +
> >> +	netdev_features_set_array(&netif_f_ip_csum_feature_set,
> >> +				  &netdev_ip_csum_features);
> >> +
> >> +	netdev_features_set_array(&netif_f_csum_feature_set_mask,
> >> +				  &netdev_csum_features_mask);
> >> +
> >> +	netdev_features_set_array(&netif_f_general_tso_feature_set,
> >> +				  &netdev_general_tso_features);
> >> +
> >> +	netdev_features_set_array(&netif_f_all_tso_feature_set,
> >> +				  &netdev_all_tso_features);
> >> +
> >> +	netdev_features_set_array(&netif_f_tso_ecn_feature_set,
> >> +				  &netdev_tso_ecn_features);
> >> +
> >> +	netdev_features_set_array(&netif_f_all_fcoe_feature_set,
> >> +				  &netdev_all_fcoe_features);
> >> +
> >> +	netdev_features_set_array(&netif_f_gso_soft_feature_set,
> >> +				  &netdev_gso_software_features);
> >> +
> >> +	netdev_features_set_array(&netif_f_one_for_all_feature_set,
> >> +				  &netdev_one_for_all_features);
> >> +
> >> +	netdev_features_set_array(&netif_f_all_for_all_feature_set,
> >> +				  &netdev_all_for_all_features);
> >> +
> >> +	netdev_features_set_array(&netif_f_upper_disables_feature_set,
> >> +				  &netdev_upper_disable_features);
> >> +
> >> +	netdev_features_set_array(&netif_f_soft_feature_set,
> >> +				  &netdev_soft_features);
> >> +
> >> +	netdev_features_set_array(&netif_f_soft_off_feature_set,
> >> +				  &netdev_soft_off_features);
> >> +
> >> +	netdev_features_set_array(&netif_f_rx_vlan_feature_set,
> >> +				  &netdev_rx_vlan_features);
> >> +
> >> +	netdev_features_set_array(&netif_f_tx_vlan_feature_set,
> >> +				  &netdev_tx_vlan_features);
> >> +
> >> +	netdev_features_set_array(&netif_f_vlan_filter_feature_set,
> >> +				  &netdev_vlan_filter_features);
> >> +
> >> +	netdev_all_vlan_features = netdev_rx_vlan_features;
> >> +	netdev_features_set(&netdev_all_vlan_features, netdev_tx_vlan_features);
> >> +	netdev_features_set(&netdev_all_vlan_features,
> >> +			    netdev_vlan_filter_features);
> >> +
> >> +	netdev_features_set_array(&netif_f_ctag_vlan_feature_set,
> >> +				  &netdev_ctag_vlan_features);
> >> +
> >> +	netdev_features_set_array(&netif_f_stag_vlan_feature_set,
> >> +				  &netdev_stag_vlan_features);
> >> +
> >> +	netdev_features_set_array(&netif_f_gso_encap_feature_set,
> >> +				  &netdev_gso_encap_all_features);
> >> +
> >> +	netdev_features_set_array(&netif_f_xfrm_feature_set,
> >> +				  &netdev_xfrm_features);
> >> +
> >> +	netdev_features_set_array(&netif_f_tls_feature_set,
> >> +				  &netdev_tls_features);
> >> +
> >> +	netdev_csum_gso_features_mask =
> >> +		netdev_features_or(netdev_gso_software_features,
> >> +				   netdev_csum_features_mask);
> >> +
> >> +	netdev_features_fill(&features);
> >> +	netdev_ethtool_features =
> >> +		netdev_features_andnot(features, netdev_never_change_features);
> >> +}
> >> +
> >>   /*
> >>    *	Initialize the DEV module. At boot time this walks the device list and
> >>    *	unhooks any devices that fail to initialise (normally hardware not
> > --- 8< ---
> >
> >> -- 
> >> 2.33.0
> > Thanks,
> > Al
> >
> > .
> >

Thanks,
Olek

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [RFCv6 PATCH net-next 02/19] net: replace general features macroes with global netdev_features variables
  2022-04-20  9:54     ` shenjian (K)
  2022-07-20 15:09       ` Alexander Lobakin
@ 2022-07-20 15:10       ` Alexander Lobakin
  2022-07-20 15:13       ` Alexander Lobakin
  2 siblings, 0 replies; 30+ messages in thread
From: Alexander Lobakin @ 2022-07-20 15:10 UTC (permalink / raw)
  To: shenjian (K)
  Cc: Alexander Lobakin, davem, kuba, andrew, ecree.xilinx, hkallweit1,
	saeed, leon, netdev, linuxarm, lipeng321, Maciej Fijalkowski,
	Michal Swiatkowski

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset="us-ascii"; format=flowed, Size: 5613 bytes --]

From: shenjian (K) <shenjian15@huawei.com>
Date: Wed, 20 Apr 2022 17:54:13 +0800

> 在 2022/4/19 22:49, Alexander Lobakin 写道:
> > From: Jian Shen <shenjian15@huawei.com>
> > Date: Tue, 19 Apr 2022 10:21:49 +0800
> >
> >> There are many netdev_features bits group used in kernel. The definition
> >> will be illegal when using feature bit more than 64. Replace these macroes
> >> with global netdev_features variables, initialize them when netdev module
> >> init.
> >>
> >> Signed-off-by: Jian Shen <shenjian15@huawei.com>
> >> ---
> >>   drivers/net/wireguard/device.c  |  10 +-
> >>   include/linux/netdev_features.h | 102 +++++++++-----
> >>   net/core/Makefile               |   2 +-
> >>   net/core/dev.c                  |  87 ++++++++++++
> >>   net/core/netdev_features.c      | 241 ++++++++++++++++++++++++++++++++
> >>   5 files changed, 400 insertions(+), 42 deletions(-)
> >>   create mode 100644 net/core/netdev_features.c
> >>
> > --- 8< ---
> >
> >> diff --git a/net/core/dev.c b/net/core/dev.c
> >> index 4d6b57752eee..85bb418e8ef1 100644
> >> --- a/net/core/dev.c
> >> +++ b/net/core/dev.c
> >> @@ -146,6 +146,7 @@
> >>   #include <linux/sctp.h>
> >>   #include <net/udp_tunnel.h>
> >>   #include <linux/net_namespace.h>
> >> +#include <linux/netdev_features_helper.h>
> >>   #include <linux/indirect_call_wrapper.h>
> >>   #include <net/devlink.h>
> >>   #include <linux/pm_runtime.h>
> >> @@ -11255,6 +11256,90 @@ static struct pernet_operations __net_initdata default_device_ops = {
> >>   	.exit_batch = default_device_exit_batch,
> >>   };
> >>   
> >> +static void netdev_features_init(void)
> > It is an initialization function, so it must be marked as __init.
> right, I will add it, thanks!
> 
> >> +{
> >> +	netdev_features_t features;
> >> +
> >> +	netdev_features_set_array(&netif_f_never_change_feature_set,
> >> +				  &netdev_never_change_features);
> >> +
> >> +	netdev_features_set_array(&netif_f_gso_feature_set_mask,
> > I'm not sure it does make sense to have an empty newline between
> > each call. I'd leave newlines only between the "regular" blocks
> > and the "multi-call" blocks, I mean, stuff like VLAN, GSO and
> > @netdev_ethtool_features.
> At first, I added empty newline per call for the it used three lines.
> Now the new call just use two lines, I will remove some unnecessary
> blank lines.
> 
> Thanks!

I see no news regarding the conversion since the end of April, maybe
I could pick it and finish if nobody objects? I'll preserve the
original authorship for sure.

> 
> >> +				  &netdev_gso_features_mask);
> >> +
> >> +	netdev_features_set_array(&netif_f_ip_csum_feature_set,
> >> +				  &netdev_ip_csum_features);
> >> +
> >> +	netdev_features_set_array(&netif_f_csum_feature_set_mask,
> >> +				  &netdev_csum_features_mask);
> >> +
> >> +	netdev_features_set_array(&netif_f_general_tso_feature_set,
> >> +				  &netdev_general_tso_features);
> >> +
> >> +	netdev_features_set_array(&netif_f_all_tso_feature_set,
> >> +				  &netdev_all_tso_features);
> >> +
> >> +	netdev_features_set_array(&netif_f_tso_ecn_feature_set,
> >> +				  &netdev_tso_ecn_features);
> >> +
> >> +	netdev_features_set_array(&netif_f_all_fcoe_feature_set,
> >> +				  &netdev_all_fcoe_features);
> >> +
> >> +	netdev_features_set_array(&netif_f_gso_soft_feature_set,
> >> +				  &netdev_gso_software_features);
> >> +
> >> +	netdev_features_set_array(&netif_f_one_for_all_feature_set,
> >> +				  &netdev_one_for_all_features);
> >> +
> >> +	netdev_features_set_array(&netif_f_all_for_all_feature_set,
> >> +				  &netdev_all_for_all_features);
> >> +
> >> +	netdev_features_set_array(&netif_f_upper_disables_feature_set,
> >> +				  &netdev_upper_disable_features);
> >> +
> >> +	netdev_features_set_array(&netif_f_soft_feature_set,
> >> +				  &netdev_soft_features);
> >> +
> >> +	netdev_features_set_array(&netif_f_soft_off_feature_set,
> >> +				  &netdev_soft_off_features);
> >> +
> >> +	netdev_features_set_array(&netif_f_rx_vlan_feature_set,
> >> +				  &netdev_rx_vlan_features);
> >> +
> >> +	netdev_features_set_array(&netif_f_tx_vlan_feature_set,
> >> +				  &netdev_tx_vlan_features);
> >> +
> >> +	netdev_features_set_array(&netif_f_vlan_filter_feature_set,
> >> +				  &netdev_vlan_filter_features);
> >> +
> >> +	netdev_all_vlan_features = netdev_rx_vlan_features;
> >> +	netdev_features_set(&netdev_all_vlan_features, netdev_tx_vlan_features);
> >> +	netdev_features_set(&netdev_all_vlan_features,
> >> +			    netdev_vlan_filter_features);
> >> +
> >> +	netdev_features_set_array(&netif_f_ctag_vlan_feature_set,
> >> +				  &netdev_ctag_vlan_features);
> >> +
> >> +	netdev_features_set_array(&netif_f_stag_vlan_feature_set,
> >> +				  &netdev_stag_vlan_features);
> >> +
> >> +	netdev_features_set_array(&netif_f_gso_encap_feature_set,
> >> +				  &netdev_gso_encap_all_features);
> >> +
> >> +	netdev_features_set_array(&netif_f_xfrm_feature_set,
> >> +				  &netdev_xfrm_features);
> >> +
> >> +	netdev_features_set_array(&netif_f_tls_feature_set,
> >> +				  &netdev_tls_features);
> >> +
> >> +	netdev_csum_gso_features_mask =
> >> +		netdev_features_or(netdev_gso_software_features,
> >> +				   netdev_csum_features_mask);
> >> +
> >> +	netdev_features_fill(&features);
> >> +	netdev_ethtool_features =
> >> +		netdev_features_andnot(features, netdev_never_change_features);
> >> +}
> >> +
> >>   /*
> >>    *	Initialize the DEV module. At boot time this walks the device list and
> >>    *	unhooks any devices that fail to initialise (normally hardware not
> > --- 8< ---
> >
> >> -- 
> >> 2.33.0
> > Thanks,
> > Al
> >
> > .
> >

Thanks,
Olek

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [RFCv6 PATCH net-next 02/19] net: replace general features macroes with global netdev_features variables
  2022-04-20  9:54     ` shenjian (K)
  2022-07-20 15:09       ` Alexander Lobakin
  2022-07-20 15:10       ` Alexander Lobakin
@ 2022-07-20 15:13       ` Alexander Lobakin
  2 siblings, 0 replies; 30+ messages in thread
From: Alexander Lobakin @ 2022-07-20 15:13 UTC (permalink / raw)
  To: shenjian (K)
  Cc: Alexander Lobakin, davem, kuba, andrew, ecree.xilinx, hkallweit1,
	saeed, leon, netdev, linuxarm, lipeng321, Maciej Fijalkowski,
	Michal Swiatkowski

From: shenjian (K) <shenjian15@huawei.com>
Date: Wed, 20 Apr 2022 17:54:13 +0800

> 在 2022/4/19 22:49, Alexander Lobakin 写道:
> > From: Jian Shen <shenjian15@huawei.com>
> > Date: Tue, 19 Apr 2022 10:21:49 +0800
> >
> >> There are many netdev_features bits group used in kernel. The definition
> >> will be illegal when using feature bit more than 64. Replace these macroes
> >> with global netdev_features variables, initialize them when netdev module
> >> init.
> >>
> >> Signed-off-by: Jian Shen <shenjian15@huawei.com>
> >> ---
> >>   drivers/net/wireguard/device.c  |  10 +-
> >>   include/linux/netdev_features.h | 102 +++++++++-----
> >>   net/core/Makefile               |   2 +-
> >>   net/core/dev.c                  |  87 ++++++++++++
> >>   net/core/netdev_features.c      | 241 ++++++++++++++++++++++++++++++++
> >>   5 files changed, 400 insertions(+), 42 deletions(-)
> >>   create mode 100644 net/core/netdev_features.c
> >>
> > --- 8< ---
> >
> >> diff --git a/net/core/dev.c b/net/core/dev.c
> >> index 4d6b57752eee..85bb418e8ef1 100644
> >> --- a/net/core/dev.c
> >> +++ b/net/core/dev.c
> >> @@ -146,6 +146,7 @@
> >>   #include <linux/sctp.h>
> >>   #include <net/udp_tunnel.h>
> >>   #include <linux/net_namespace.h>
> >> +#include <linux/netdev_features_helper.h>
> >>   #include <linux/indirect_call_wrapper.h>
> >>   #include <net/devlink.h>
> >>   #include <linux/pm_runtime.h>
> >> @@ -11255,6 +11256,90 @@ static struct pernet_operations __net_initdata default_device_ops = {
> >>   	.exit_batch = default_device_exit_batch,
> >>   };
> >>   
> >> +static void netdev_features_init(void)
> > It is an initialization function, so it must be marked as __init.
> right, I will add it, thanks!
> 
> >> +{
> >> +	netdev_features_t features;
> >> +
> >> +	netdev_features_set_array(&netif_f_never_change_feature_set,
> >> +				  &netdev_never_change_features);
> >> +
> >> +	netdev_features_set_array(&netif_f_gso_feature_set_mask,
> > I'm not sure it does make sense to have an empty newline between
> > each call. I'd leave newlines only between the "regular" blocks
> > and the "multi-call" blocks, I mean, stuff like VLAN, GSO and
> > @netdev_ethtool_features.
> At first, I added empty newline per call for the it used three lines.
> Now the new call just use two lines, I will remove some unnecessary
> blank lines.
> 
> Thanks!

(sorry for the triple mail, at first References got screwed, then
 encoding =\)

I see no news regarding the conversion since the end of April, maybe
I could pick it and finish if nobody objects? I'll preserve the
original authorship for sure.

> 
> >> +				  &netdev_gso_features_mask);
> >> +
> >> +	netdev_features_set_array(&netif_f_ip_csum_feature_set,
> >> +				  &netdev_ip_csum_features);
> >> +
> >> +	netdev_features_set_array(&netif_f_csum_feature_set_mask,
> >> +				  &netdev_csum_features_mask);
> >> +
> >> +	netdev_features_set_array(&netif_f_general_tso_feature_set,
> >> +				  &netdev_general_tso_features);
> >> +
> >> +	netdev_features_set_array(&netif_f_all_tso_feature_set,
> >> +				  &netdev_all_tso_features);
> >> +
> >> +	netdev_features_set_array(&netif_f_tso_ecn_feature_set,
> >> +				  &netdev_tso_ecn_features);
> >> +
> >> +	netdev_features_set_array(&netif_f_all_fcoe_feature_set,
> >> +				  &netdev_all_fcoe_features);
> >> +
> >> +	netdev_features_set_array(&netif_f_gso_soft_feature_set,
> >> +				  &netdev_gso_software_features);
> >> +
> >> +	netdev_features_set_array(&netif_f_one_for_all_feature_set,
> >> +				  &netdev_one_for_all_features);
> >> +
> >> +	netdev_features_set_array(&netif_f_all_for_all_feature_set,
> >> +				  &netdev_all_for_all_features);
> >> +
> >> +	netdev_features_set_array(&netif_f_upper_disables_feature_set,
> >> +				  &netdev_upper_disable_features);
> >> +
> >> +	netdev_features_set_array(&netif_f_soft_feature_set,
> >> +				  &netdev_soft_features);
> >> +
> >> +	netdev_features_set_array(&netif_f_soft_off_feature_set,
> >> +				  &netdev_soft_off_features);
> >> +
> >> +	netdev_features_set_array(&netif_f_rx_vlan_feature_set,
> >> +				  &netdev_rx_vlan_features);
> >> +
> >> +	netdev_features_set_array(&netif_f_tx_vlan_feature_set,
> >> +				  &netdev_tx_vlan_features);
> >> +
> >> +	netdev_features_set_array(&netif_f_vlan_filter_feature_set,
> >> +				  &netdev_vlan_filter_features);
> >> +
> >> +	netdev_all_vlan_features = netdev_rx_vlan_features;
> >> +	netdev_features_set(&netdev_all_vlan_features, netdev_tx_vlan_features);
> >> +	netdev_features_set(&netdev_all_vlan_features,
> >> +			    netdev_vlan_filter_features);
> >> +
> >> +	netdev_features_set_array(&netif_f_ctag_vlan_feature_set,
> >> +				  &netdev_ctag_vlan_features);
> >> +
> >> +	netdev_features_set_array(&netif_f_stag_vlan_feature_set,
> >> +				  &netdev_stag_vlan_features);
> >> +
> >> +	netdev_features_set_array(&netif_f_gso_encap_feature_set,
> >> +				  &netdev_gso_encap_all_features);
> >> +
> >> +	netdev_features_set_array(&netif_f_xfrm_feature_set,
> >> +				  &netdev_xfrm_features);
> >> +
> >> +	netdev_features_set_array(&netif_f_tls_feature_set,
> >> +				  &netdev_tls_features);
> >> +
> >> +	netdev_csum_gso_features_mask =
> >> +		netdev_features_or(netdev_gso_software_features,
> >> +				   netdev_csum_features_mask);
> >> +
> >> +	netdev_features_fill(&features);
> >> +	netdev_ethtool_features =
> >> +		netdev_features_andnot(features, netdev_never_change_features);
> >> +}
> >> +
> >>   /*
> >>    *	Initialize the DEV module. At boot time this walks the device list and
> >>    *	unhooks any devices that fail to initialise (normally hardware not
> > --- 8< ---
> >
> >> -- 
> >> 2.33.0
> > Thanks,
> > Al
> >
> > .
> >

Thanks,
Olek

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [RFCv6 PATCH net-next 02/19] net: replace general features macroes with global netdev_features variables
  2022-07-20 15:09       ` Alexander Lobakin
@ 2022-07-21  1:15         ` shenjian (K)
  2022-07-21 14:57           ` Alexander Lobakin
  0 siblings, 1 reply; 30+ messages in thread
From: shenjian (K) @ 2022-07-21  1:15 UTC (permalink / raw)
  To: Alexander Lobakin
  Cc: davem, kuba, andrew, ecree.xilinx, hkallweit1, saeed, leon,
	netdev, linuxarm, lipeng321, Maciej Fijalkowski,
	Michal Swiatkowski



在 2022/7/20 23:09, Alexander Lobakin 写道:
> From: shenjian (K) <shenjian15@huawei.com>
> Date: Wed, 20 Apr 2022 17:54:13 +0800
>
>> 在 2022/4/19 22:49, Alexander Lobakin 写道:
>> > From: Jian Shen <shenjian15@huawei.com>
>> > Date: Tue, 19 Apr 2022 10:21:49 +0800
>> >
>> >> There are many netdev_features bits group used in kernel. The 
>> definition
>> >> will be illegal when using feature bit more than 64. Replace these 
>> macroes
>> >> with global netdev_features variables, initialize them when netdev 
>> module
>> >> init.
>> >>
>> >> Signed-off-by: Jian Shen <shenjian15@huawei.com>
>> >> ---
>> >>   drivers/net/wireguard/device.c  |  10 +-
>> >>   include/linux/netdev_features.h | 102 +++++++++-----
>> >>   net/core/Makefile               |   2 +-
>> >>   net/core/dev.c                  |  87 ++++++++++++
>> >>   net/core/netdev_features.c      | 241 
>> ++++++++++++++++++++++++++++++++
>> >>   5 files changed, 400 insertions(+), 42 deletions(-)
>> >>   create mode 100644 net/core/netdev_features.c
>> >>
>> > --- 8< ---
>> >
>> >> diff --git a/net/core/dev.c b/net/core/dev.c
>> >> index 4d6b57752eee..85bb418e8ef1 100644
>> >> --- a/net/core/dev.c
>> >> +++ b/net/core/dev.c
>> >> @@ -146,6 +146,7 @@
>> >>   #include <linux/sctp.h>
>> >>   #include <net/udp_tunnel.h>
>> >>   #include <linux/net_namespace.h>
>> >> +#include <linux/netdev_features_helper.h>
>> >>   #include <linux/indirect_call_wrapper.h>
>> >>   #include <net/devlink.h>
>> >>   #include <linux/pm_runtime.h>
>> >> @@ -11255,6 +11256,90 @@ static struct pernet_operations 
>> __net_initdata default_device_ops = {
>> >>       .exit_batch = default_device_exit_batch,
>> >>   };
>> >>   >> +static void netdev_features_init(void)
>> > It is an initialization function, so it must be marked as __init.
>> right, I will add it, thanks!
>>
>> >> +{
>> >> +    netdev_features_t features;
>> >> +
>> >> + netdev_features_set_array(&netif_f_never_change_feature_set,
>> >> +                  &netdev_never_change_features);
>> >> +
>> >> + netdev_features_set_array(&netif_f_gso_feature_set_mask,
>> > I'm not sure it does make sense to have an empty newline between
>> > each call. I'd leave newlines only between the "regular" blocks
>> > and the "multi-call" blocks, I mean, stuff like VLAN, GSO and
>> > @netdev_ethtool_features.
>> At first, I added empty newline per call for the it used three lines.
>> Now the new call just use two lines, I will remove some unnecessary
>> blank lines.
>>
>> Thanks!
>
> I see no news regarding the conversion since the end of April, maybe
> I could pick it and finish if nobody objects? I'll preserve the
> original authorship for sure.
>
Hi, Alexander

Sorry for late to finish the whole patchset with treewide changes, but 
I'm still working on it.
And most of the convertsions have been completed. I will send to new 
patchset in two weeks.

Jian

>>
>> >> +                  &netdev_gso_features_mask);
>> >> +
>> >> + netdev_features_set_array(&netif_f_ip_csum_feature_set,
>> >> +                  &netdev_ip_csum_features);
>> >> +
>> >> + netdev_features_set_array(&netif_f_csum_feature_set_mask,
>> >> +                  &netdev_csum_features_mask);
>> >> +
>> >> + netdev_features_set_array(&netif_f_general_tso_feature_set,
>> >> +                  &netdev_general_tso_features);
>> >> +
>> >> + netdev_features_set_array(&netif_f_all_tso_feature_set,
>> >> +                  &netdev_all_tso_features);
>> >> +
>> >> + netdev_features_set_array(&netif_f_tso_ecn_feature_set,
>> >> +                  &netdev_tso_ecn_features);
>> >> +
>> >> + netdev_features_set_array(&netif_f_all_fcoe_feature_set,
>> >> +                  &netdev_all_fcoe_features);
>> >> +
>> >> + netdev_features_set_array(&netif_f_gso_soft_feature_set,
>> >> +                  &netdev_gso_software_features);
>> >> +
>> >> + netdev_features_set_array(&netif_f_one_for_all_feature_set,
>> >> +                  &netdev_one_for_all_features);
>> >> +
>> >> + netdev_features_set_array(&netif_f_all_for_all_feature_set,
>> >> +                  &netdev_all_for_all_features);
>> >> +
>> >> + netdev_features_set_array(&netif_f_upper_disables_feature_set,
>> >> +                  &netdev_upper_disable_features);
>> >> +
>> >> + netdev_features_set_array(&netif_f_soft_feature_set,
>> >> +                  &netdev_soft_features);
>> >> +
>> >> + netdev_features_set_array(&netif_f_soft_off_feature_set,
>> >> +                  &netdev_soft_off_features);
>> >> +
>> >> + netdev_features_set_array(&netif_f_rx_vlan_feature_set,
>> >> +                  &netdev_rx_vlan_features);
>> >> +
>> >> + netdev_features_set_array(&netif_f_tx_vlan_feature_set,
>> >> +                  &netdev_tx_vlan_features);
>> >> +
>> >> + netdev_features_set_array(&netif_f_vlan_filter_feature_set,
>> >> +                  &netdev_vlan_filter_features);
>> >> +
>> >> +    netdev_all_vlan_features = netdev_rx_vlan_features;
>> >> +    netdev_features_set(&netdev_all_vlan_features, 
>> netdev_tx_vlan_features);
>> >> +    netdev_features_set(&netdev_all_vlan_features,
>> >> +                netdev_vlan_filter_features);
>> >> +
>> >> + netdev_features_set_array(&netif_f_ctag_vlan_feature_set,
>> >> +                  &netdev_ctag_vlan_features);
>> >> +
>> >> + netdev_features_set_array(&netif_f_stag_vlan_feature_set,
>> >> +                  &netdev_stag_vlan_features);
>> >> +
>> >> + netdev_features_set_array(&netif_f_gso_encap_feature_set,
>> >> +                  &netdev_gso_encap_all_features);
>> >> +
>> >> + netdev_features_set_array(&netif_f_xfrm_feature_set,
>> >> +                  &netdev_xfrm_features);
>> >> +
>> >> + netdev_features_set_array(&netif_f_tls_feature_set,
>> >> +                  &netdev_tls_features);
>> >> +
>> >> +    netdev_csum_gso_features_mask =
>> >> + netdev_features_or(netdev_gso_software_features,
>> >> +                   netdev_csum_features_mask);
>> >> +
>> >> +    netdev_features_fill(&features);
>> >> +    netdev_ethtool_features =
>> >> +        netdev_features_andnot(features, 
>> netdev_never_change_features);
>> >> +}
>> >> +
>> >>   /*
>> >>    *    Initialize the DEV module. At boot time this walks the 
>> device list and
>> >>    *    unhooks any devices that fail to initialise (normally 
>> hardware not
>> > --- 8< ---
>> >
>> >> -- >> 2.33.0
>> > Thanks,
>> > Al
>> >
>> > .
>> >
>
> Thanks,
> Olek
>
> .
>


^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [RFCv6 PATCH net-next 02/19] net: replace general features macroes with global netdev_features variables
  2022-07-21  1:15         ` shenjian (K)
@ 2022-07-21 14:57           ` Alexander Lobakin
  2022-07-21 15:21             ` shenjian (K)
  0 siblings, 1 reply; 30+ messages in thread
From: Alexander Lobakin @ 2022-07-21 14:57 UTC (permalink / raw)
  To: shenjian (K)
  Cc: Alexander Lobakin, davem, kuba, andrew, ecree.xilinx, hkallweit1,
	saeed, leon, netdev, linuxarm, lipeng321, Maciej Fijalkowski,
	Michal Swiatkowski

From: shenjian (K) <shenjian15@huawei.com>
Date: Thu, 21 Jul 2022 09:15:59 +0800

> 在 2022/7/20 23:09, Alexander Lobakin 写道:
> > From: shenjian (K) <shenjian15@huawei.com>
> > Date: Wed, 20 Apr 2022 17:54:13 +0800
> >
> >> 在 2022/4/19 22:49, Alexander Lobakin 写道:
> >> > From: Jian Shen <shenjian15@huawei.com>
> >> > Date: Tue, 19 Apr 2022 10:21:49 +0800
> >> >
> >> >> There are many netdev_features bits group used in kernel. The 
> >> definition
> >> >> will be illegal when using feature bit more than 64. Replace these 
> >> macroes
> >> >> with global netdev_features variables, initialize them when netdev 
> >> module
> >> >> init.
> >> >>
> >> >> Signed-off-by: Jian Shen <shenjian15@huawei.com>
> >> >> ---
> >> >>   drivers/net/wireguard/device.c  |  10 +-
> >> >>   include/linux/netdev_features.h | 102 +++++++++-----
> >> >>   net/core/Makefile               |   2 +-
> >> >>   net/core/dev.c                  |  87 ++++++++++++
> >> >>   net/core/netdev_features.c      | 241 
> >> ++++++++++++++++++++++++++++++++
> >> >>   5 files changed, 400 insertions(+), 42 deletions(-)
> >> >>   create mode 100644 net/core/netdev_features.c
> >> >>
> >> > --- 8< ---
> >> >
> >> >> diff --git a/net/core/dev.c b/net/core/dev.c
> >> >> index 4d6b57752eee..85bb418e8ef1 100644
> >> >> --- a/net/core/dev.c
> >> >> +++ b/net/core/dev.c
> >> >> @@ -146,6 +146,7 @@
> >> >>   #include <linux/sctp.h>
> >> >>   #include <net/udp_tunnel.h>
> >> >>   #include <linux/net_namespace.h>
> >> >> +#include <linux/netdev_features_helper.h>
> >> >>   #include <linux/indirect_call_wrapper.h>
> >> >>   #include <net/devlink.h>
> >> >>   #include <linux/pm_runtime.h>
> >> >> @@ -11255,6 +11256,90 @@ static struct pernet_operations 
> >> __net_initdata default_device_ops = {
> >> >>       .exit_batch = default_device_exit_batch,
> >> >>   };
> >> >>   >> +static void netdev_features_init(void)
> >> > It is an initialization function, so it must be marked as __init.
> >> right, I will add it, thanks!
> >>
> >> >> +{
> >> >> +    netdev_features_t features;
> >> >> +
> >> >> + netdev_features_set_array(&netif_f_never_change_feature_set,
> >> >> +                  &netdev_never_change_features);
> >> >> +
> >> >> + netdev_features_set_array(&netif_f_gso_feature_set_mask,
> >> > I'm not sure it does make sense to have an empty newline between
> >> > each call. I'd leave newlines only between the "regular" blocks
> >> > and the "multi-call" blocks, I mean, stuff like VLAN, GSO and
> >> > @netdev_ethtool_features.
> >> At first, I added empty newline per call for the it used three lines.
> >> Now the new call just use two lines, I will remove some unnecessary
> >> blank lines.
> >>
> >> Thanks!
> >
> > I see no news regarding the conversion since the end of April, maybe
> > I could pick it and finish if nobody objects? I'll preserve the
> > original authorship for sure.
> >
> Hi, Alexander
> 
> Sorry for late to finish the whole patchset with treewide changes, but 
> I'm still working on it.
> And most of the convertsions have been completed. I will send to new 
> patchset in two weeks.

Oh okay, I was only worried that it could be abandoned for some
reason. Great to hear it's almost done, 120+ drivers is not
something quick or exciting :)
I'll start reviewing the series, at least its "core" part, as soon
as it hits netdev ML. Thanks!

> 
> Jian
> 
> >>
> >> >> +                  &netdev_gso_features_mask);

[...]

> > Thanks,
> > Olek
> >
> > .
> >
> 

Olek

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [RFCv6 PATCH net-next 02/19] net: replace general features macroes with global netdev_features variables
  2022-07-21 14:57           ` Alexander Lobakin
@ 2022-07-21 15:21             ` shenjian (K)
  0 siblings, 0 replies; 30+ messages in thread
From: shenjian (K) @ 2022-07-21 15:21 UTC (permalink / raw)
  To: Alexander Lobakin
  Cc: davem, kuba, andrew, ecree.xilinx, hkallweit1, saeed, leon,
	netdev, linuxarm, lipeng321, Maciej Fijalkowski,
	Michal Swiatkowski



在 2022/7/21 22:57, Alexander Lobakin 写道:
> From: shenjian (K) <shenjian15@huawei.com>
> Date: Thu, 21 Jul 2022 09:15:59 +0800
>
>> 在 2022/7/20 23:09, Alexander Lobakin 写道:
>>> From: shenjian (K) <shenjian15@huawei.com>
>>> Date: Wed, 20 Apr 2022 17:54:13 +0800
>>>
>>>> 在 2022/4/19 22:49, Alexander Lobakin 写道:
>>>>> From: Jian Shen <shenjian15@huawei.com>
>>>>> Date: Tue, 19 Apr 2022 10:21:49 +0800
>>>>>
>>>>>> There are many netdev_features bits group used in kernel. The
>>>> definition
>>>>>> will be illegal when using feature bit more than 64. Replace these
>>>> macroes
>>>>>> with global netdev_features variables, initialize them when netdev
>>>> module
>>>>>> init.
>>>>>>
>>>>>> Signed-off-by: Jian Shen <shenjian15@huawei.com>
>>>>>> ---
>>>>>>     drivers/net/wireguard/device.c  |  10 +-
>>>>>>     include/linux/netdev_features.h | 102 +++++++++-----
>>>>>>     net/core/Makefile               |   2 +-
>>>>>>     net/core/dev.c                  |  87 ++++++++++++
>>>>>>     net/core/netdev_features.c      | 241
>>>> ++++++++++++++++++++++++++++++++
>>>>>>     5 files changed, 400 insertions(+), 42 deletions(-)
>>>>>>     create mode 100644 net/core/netdev_features.c
>>>>>>
>>>>> --- 8< ---
>>>>>
>>>>>> diff --git a/net/core/dev.c b/net/core/dev.c
>>>>>> index 4d6b57752eee..85bb418e8ef1 100644
>>>>>> --- a/net/core/dev.c
>>>>>> +++ b/net/core/dev.c
>>>>>> @@ -146,6 +146,7 @@
>>>>>>     #include <linux/sctp.h>
>>>>>>     #include <net/udp_tunnel.h>
>>>>>>     #include <linux/net_namespace.h>
>>>>>> +#include <linux/netdev_features_helper.h>
>>>>>>     #include <linux/indirect_call_wrapper.h>
>>>>>>     #include <net/devlink.h>
>>>>>>     #include <linux/pm_runtime.h>
>>>>>> @@ -11255,6 +11256,90 @@ static struct pernet_operations
>>>> __net_initdata default_device_ops = {
>>>>>>         .exit_batch = default_device_exit_batch,
>>>>>>     };
>>>>>>     >> +static void netdev_features_init(void)
>>>>> It is an initialization function, so it must be marked as __init.
>>>> right, I will add it, thanks!
>>>>
>>>>>> +{
>>>>>> +    netdev_features_t features;
>>>>>> +
>>>>>> + netdev_features_set_array(&netif_f_never_change_feature_set,
>>>>>> +                  &netdev_never_change_features);
>>>>>> +
>>>>>> + netdev_features_set_array(&netif_f_gso_feature_set_mask,
>>>>> I'm not sure it does make sense to have an empty newline between
>>>>> each call. I'd leave newlines only between the "regular" blocks
>>>>> and the "multi-call" blocks, I mean, stuff like VLAN, GSO and
>>>>> @netdev_ethtool_features.
>>>> At first, I added empty newline per call for the it used three lines.
>>>> Now the new call just use two lines, I will remove some unnecessary
>>>> blank lines.
>>>>
>>>> Thanks!
>>> I see no news regarding the conversion since the end of April, maybe
>>> I could pick it and finish if nobody objects? I'll preserve the
>>> original authorship for sure.
>>>
>> Hi, Alexander
>>
>> Sorry for late to finish the whole patchset with treewide changes, but
>> I'm still working on it.
>> And most of the convertsions have been completed. I will send to new
>> patchset in two weeks.
> Oh okay, I was only worried that it could be abandoned for some
> reason. Great to hear it's almost done, 120+ drivers is not
> something quick or exciting :)
Thanks, I will speed up efforts.

> I'll start reviewing the series, at least its "core" part, as soon
> as it hits netdev ML. Thanks!
Yes, It's need sufficient review, I want to get as many as possible 
advices for it.
Thanks!

>> Jian
>>
>>>>>> +                  &netdev_gso_features_mask);
> [...]
>
>>> Thanks,
>>> Olek
>>>
>>> .
>>>
> Olek
>
> .
>


^ permalink raw reply	[flat|nested] 30+ messages in thread

end of thread, other threads:[~2022-07-21 15:21 UTC | newest]

Thread overview: 30+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-04-19  2:21 [RFCv6 PATCH net-next 00/19] net: extend the type of netdev_features_t to bitmap Jian Shen
2022-04-19  2:21 ` [RFCv6 PATCH net-next 01/19] net: introduce operation helpers for netdev features Jian Shen
2022-04-19 14:40   ` Alexander Lobakin
2022-04-20  9:24     ` shenjian (K)
2022-04-19  2:21 ` [RFCv6 PATCH net-next 02/19] net: replace general features macroes with global netdev_features variables Jian Shen
2022-04-19 14:49   ` Alexander Lobakin
2022-04-20  9:54     ` shenjian (K)
2022-07-20 15:09       ` Alexander Lobakin
2022-07-21  1:15         ` shenjian (K)
2022-07-21 14:57           ` Alexander Lobakin
2022-07-21 15:21             ` shenjian (K)
2022-07-20 15:10       ` Alexander Lobakin
2022-07-20 15:13       ` Alexander Lobakin
2022-04-19  2:21 ` [RFCv6 PATCH net-next 03/19] net: replace multiple feature bits with netdev features array Jian Shen
2022-04-19  2:21 ` [RFCv6 PATCH net-next 04/19] net: sfc: replace const features initialization " Jian Shen
2022-04-19  2:21 ` [RFCv6 PATCH net-next 05/19] net: simplify the netdev features expression Jian Shen
2022-04-19  2:21 ` [RFCv6 PATCH net-next 06/19] net: adjust variables definition for netdev_features_t Jian Shen
2022-04-19  2:21 ` [RFCv6 PATCH net-next 07/19] net: use netdev_feature_add helpers Jian Shen
2022-04-19  2:21 ` [RFCv6 PATCH net-next 08/19] net: use netdev_features_or helpers Jian Shen
2022-04-19  2:21 ` [RFCv6 PATCH net-next 09/19] net: use netdev_features_xor helpers Jian Shen
2022-04-19  2:21 ` [RFCv6 PATCH net-next 10/19] net: use netdev_feature_del helpers Jian Shen
2022-04-19  2:21 ` [RFCv6 PATCH net-next 11/19] net: use netdev_features_andnot helpers Jian Shen
2022-04-19  2:21 ` [RFCv6 PATCH net-next 12/19] net: use netdev_feature_test helpers Jian Shen
2022-04-19  2:22 ` [RFCv6 PATCH net-next 13/19] net: use netdev_features_intersects helpers Jian Shen
2022-04-19  2:22 ` [RFCv6 PATCH net-next 14/19] net: use netdev_features_and helpers Jian Shen
2022-04-19  2:22 ` [RFCv6 PATCH net-next 15/19] net: use netdev_features_subset helpers Jian Shen
2022-04-19  2:22 ` [RFCv6 PATCH net-next 16/19] net: use netdev_features_equal helpers Jian Shen
2022-04-19  2:22 ` [RFCv6 PATCH net-next 17/19] net: use netdev_features_copy helpers Jian Shen
2022-04-19  2:22 ` [RFCv6 PATCH net-next 18/19] net: use netdev_xxx_features helpers Jian Shen
2022-04-19  2:22 ` [RFCv6 PATCH net-next 19/19] net: redefine the prototype of netdev_features_t Jian Shen

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.