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. [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. Serveal macroes remained temporarily by some precompile dependency.[patch 36]
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~9]
Also, there are many feature group(e.g. NETIF_F_CSUM_MASK | NETIF_F_GSO_MASK) are used by several drivers, replaces them with global netdev features variables, in order to simple the expressions.[patch 10~13]
As suggestion from Andrew Lunn, I wrote some semantic patches to do the work(replacing the netdev features operator by helpers). To make the semantic patches simple, I split the complex expressions of netdev_features to simple logical operation. [patch 14~15]
For the prototype of netdev_features_t is no longer u64, so it's incorrect to assigne 0 to it, use netdev_empty_features intead. [patch 16]
Some drivers defines macroes and functions wich use NETIF_F_XXX as parameter. For all the macroes NETIF_F_XXX will be removed at last, so change these macroes and functions to use NETIF_F_XXX_BIT. [patch 17~23]
With above preparation, then apply the semantic patches to do the expression transition. For example, replace expression "ndev->hw_features |= NETIF_F_TSO;" by "netdev_hw_feature_set(ndev, NETIF_F_TSO_BIT)". [patch 24~35]
With the prototype is no longer u64, the implementation of print interface for netdev features(%pNF) is changed to bitmap. [patch 36]
I removed the netdev_features_copy and netdev_xxx_features() helpers in this patchset. It make the expressions being more complex. For example, expression "dev->features = dev->hw_features", it's too ugly to use "netdev_active_features_copy(dev, netdev_hw_features(hw))". I will try to find better way for this, avoiding the nic drivers to modify netdev_features directly.
The former discussion please see [1][2][3][4][5].
[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/... [4]:https://www.spinics.net/lists/netdev/msg809293.html [5]:https://www.spinics.net/lists/netdev/msg814349.html
ChangeLog: V6->V7: Add netdev_feature_change helpers, remove netdev_features_copy and netdev_xxx_features helpers. Complete the treewide netdev features changes. Suggestions from Alexander Lobakin: refine the definition of DECLARE_NETDEV_FEATURE_SET, and remove useless blank lines. 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 (36): net: introduce operation helpers for netdev features net: replace general features macroes with global netdev_features variables net: replace multiple feature bits with DECLARE_NETDEV_FEATURE_SET net: sfc: replace const features initialization with DECLARE_NETDEV_FEATURE_SET net: atlantic: replace const features initialization with NETDEV_FEATURE_SET iwlwifi: replace const features initialization with NETDEV_FEATURE_SET net: ethernet: mtk_eth_soc: replace const features initialization with NETDEV_FEATURE_SET ravb: replace const features initialization with NETDEV_FEATURE_SET test_bpf: replace const features initialization with NETDEV_FEATURE_SET treewide: replace NETIF_F_CSUM_MASK | NETIF_F_GSO_MASK by netdev_csum_gso_features_mask treewide: replace NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM by netdev_ip_csum_features treewide: replace NETIF_F_TSO | NETIF_F_TSO6 by netdev_general_tso_features treewide: replace VLAN tag feature array by const vlan features net: simplify the netdev features expressions for xxx_gso_segment treewide: simplify the netdev features expression treewide: use replace features '0' by netdev_empty_features treewide: adjust features initialization net: mlx4: adjust the net device feature relative macroes net: mlx5e: adjust net device feature relative macroes net: mlxsw: adjust input parameter for function mlxsw_sp_handle_feature net: iavf: adjust net device features relative macroes net: core: adjust netdev_sync_xxx_features net: adjust the build check for net_gso_ok() treewide: use netdev_feature_add helpers treewide: use netdev_features_or/set helpers treewide: use netdev_feature_change helpers treewide: use netdev_feature_del helpers treewide: use netdev_features_andnot and netdev_features_clear helpers treewide: use netdev_features_xor helpers treewide: use netdev_feature_test helpers treewide: use netdev_features_intersects helpers net: use netdev_features_and and netdev_features_mask helpers treewide: use netdev_features_subset helpers treewide: use netdev_features_equal helpers treewide: use netdev_features_empty helpers net: redefine the prototype of netdev_features_t
arch/um/drivers/vector_kern.c | 9 +- arch/um/drivers/vector_transports.c | 49 +- drivers/firewire/net.c | 4 +- drivers/hsi/clients/ssi_protocol.c | 2 +- drivers/infiniband/hw/hfi1/vnic_main.c | 4 +- drivers/infiniband/ulp/ipoib/ipoib.h | 1 + drivers/infiniband/ulp/ipoib/ipoib_cm.c | 2 +- drivers/infiniband/ulp/ipoib/ipoib_ib.c | 2 +- drivers/infiniband/ulp/ipoib/ipoib_main.c | 21 +- drivers/infiniband/ulp/ipoib/ipoib_verbs.c | 2 +- drivers/misc/sgi-xp/xpnet.c | 3 +- drivers/net/amt.c | 20 +- drivers/net/bareudp.c | 25 +- drivers/net/bonding/bond_main.c | 101 ++- drivers/net/bonding/bond_options.c | 9 +- drivers/net/caif/caif_serial.c | 2 +- drivers/net/can/dev/dev.c | 4 +- drivers/net/dsa/xrs700x/xrs700x.c | 15 +- drivers/net/dummy.c | 19 +- drivers/net/ethernet/3com/3c59x.c | 10 +- drivers/net/ethernet/3com/typhoon.c | 20 +- drivers/net/ethernet/adaptec/starfire.c | 12 +- drivers/net/ethernet/aeroflex/greth.c | 15 +- drivers/net/ethernet/alacritech/slicoss.c | 6 +- drivers/net/ethernet/alteon/acenic.c | 12 +- drivers/net/ethernet/altera/altera_tse_main.c | 10 +- drivers/net/ethernet/amazon/ena/ena_netdev.c | 49 +- drivers/net/ethernet/amd/amd8111e.c | 3 +- drivers/net/ethernet/amd/xgbe/xgbe-dev.c | 14 +- drivers/net/ethernet/amd/xgbe/xgbe-drv.c | 56 +- drivers/net/ethernet/amd/xgbe/xgbe-main.c | 69 +- drivers/net/ethernet/apm/xgene-v2/main.c | 4 +- drivers/net/ethernet/apm/xgene-v2/main.h | 1 + .../net/ethernet/apm/xgene/xgene_enet_main.c | 21 +- .../ethernet/aquantia/atlantic/aq_filters.c | 8 +- .../net/ethernet/aquantia/atlantic/aq_hw.h | 2 +- .../ethernet/aquantia/atlantic/aq_macsec.c | 2 +- .../ethernet/aquantia/atlantic/aq_macsec.h | 1 + .../net/ethernet/aquantia/atlantic/aq_main.c | 89 ++- .../net/ethernet/aquantia/atlantic/aq_nic.c | 29 +- .../net/ethernet/aquantia/atlantic/aq_nic.h | 6 +- .../net/ethernet/aquantia/atlantic/aq_ring.c | 3 +- .../aquantia/atlantic/hw_atl/hw_atl_a0.c | 8 +- .../aquantia/atlantic/hw_atl/hw_atl_b0.c | 17 +- .../aquantia/atlantic/hw_atl2/hw_atl2.c | 15 +- drivers/net/ethernet/asix/ax88796c_main.c | 29 +- drivers/net/ethernet/atheros/alx/main.c | 19 +- drivers/net/ethernet/atheros/atl1c/atl1c.h | 1 + .../net/ethernet/atheros/atl1c/atl1c_main.c | 34 +- drivers/net/ethernet/atheros/atl1e/atl1e.h | 1 + .../net/ethernet/atheros/atl1e/atl1e_main.c | 39 +- drivers/net/ethernet/atheros/atlx/atl1.c | 24 +- drivers/net/ethernet/atheros/atlx/atl2.c | 19 +- drivers/net/ethernet/atheros/atlx/atlx.c | 13 +- drivers/net/ethernet/broadcom/b44.c | 3 +- drivers/net/ethernet/broadcom/bcmsysport.c | 34 +- drivers/net/ethernet/broadcom/bgmac.c | 9 +- drivers/net/ethernet/broadcom/bnx2.c | 50 +- .../net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | 49 +- .../net/ethernet/broadcom/bnx2x/bnx2x_main.c | 115 ++- drivers/net/ethernet/broadcom/bnxt/bnxt.c | 158 ++-- drivers/net/ethernet/broadcom/bnxt/bnxt.h | 6 +- drivers/net/ethernet/broadcom/bnxt/bnxt_tc.c | 4 +- drivers/net/ethernet/broadcom/bnxt/bnxt_vfr.c | 3 +- drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c | 5 +- .../net/ethernet/broadcom/genet/bcmgenet.c | 16 +- drivers/net/ethernet/broadcom/tg3.c | 49 +- drivers/net/ethernet/brocade/bna/bnad.c | 51 +- drivers/net/ethernet/cadence/macb_main.c | 62 +- drivers/net/ethernet/calxeda/xgmac.c | 25 +- .../net/ethernet/cavium/liquidio/lio_core.c | 4 +- .../net/ethernet/cavium/liquidio/lio_main.c | 137 ++-- .../ethernet/cavium/liquidio/lio_vf_main.c | 114 +-- .../ethernet/cavium/liquidio/octeon_network.h | 4 +- .../net/ethernet/cavium/thunder/nicvf_main.c | 51 +- .../ethernet/cavium/thunder/nicvf_queues.c | 2 +- drivers/net/ethernet/chelsio/cxgb/cxgb2.c | 46 +- drivers/net/ethernet/chelsio/cxgb/sge.c | 8 +- .../net/ethernet/chelsio/cxgb3/cxgb3_main.c | 67 +- drivers/net/ethernet/chelsio/cxgb3/sge.c | 6 +- drivers/net/ethernet/chelsio/cxgb4/cxgb4.h | 1 + .../net/ethernet/chelsio/cxgb4/cxgb4_fcoe.c | 16 +- .../net/ethernet/chelsio/cxgb4/cxgb4_main.c | 102 ++- .../net/ethernet/chelsio/cxgb4/cxgb4_tc_u32.h | 2 +- drivers/net/ethernet/chelsio/cxgb4/sge.c | 8 +- .../ethernet/chelsio/cxgb4vf/cxgb4vf_main.c | 56 +- drivers/net/ethernet/chelsio/cxgb4vf/sge.c | 4 +- .../chelsio/inline_crypto/chtls/chtls_main.c | 2 +- drivers/net/ethernet/cirrus/ep93xx_eth.c | 7 +- drivers/net/ethernet/cisco/enic/enic_main.c | 62 +- drivers/net/ethernet/cortina/gemini.c | 29 +- drivers/net/ethernet/davicom/dm9000.c | 20 +- drivers/net/ethernet/davicom/dm9051.c | 2 +- drivers/net/ethernet/dnet.c | 3 +- drivers/net/ethernet/ec_bhf.c | 2 +- drivers/net/ethernet/emulex/benet/be_main.c | 64 +- drivers/net/ethernet/engleder/tsnep_main.c | 4 +- drivers/net/ethernet/ethoc.c | 3 +- drivers/net/ethernet/faraday/ftgmac100.c | 40 +- .../net/ethernet/freescale/dpaa/dpaa_eth.c | 25 +- .../net/ethernet/freescale/dpaa2/dpaa2-eth.c | 43 +- .../ethernet/freescale/dpaa2/dpaa2-switch.c | 10 +- .../ethernet/freescale/dpaa2/dpaa2-switch.h | 1 + drivers/net/ethernet/freescale/enetc/enetc.c | 26 +- .../net/ethernet/freescale/enetc/enetc_pf.c | 59 +- .../net/ethernet/freescale/enetc/enetc_vf.c | 42 +- drivers/net/ethernet/freescale/fec_main.c | 25 +- .../ethernet/freescale/fs_enet/fs_enet-main.c | 2 +- drivers/net/ethernet/freescale/gianfar.c | 40 +- .../net/ethernet/freescale/gianfar_ethtool.c | 7 +- .../ethernet/fungible/funeth/funeth_ktls.c | 5 +- .../ethernet/fungible/funeth/funeth_main.c | 55 +- .../net/ethernet/fungible/funeth/funeth_rx.c | 4 +- drivers/net/ethernet/google/gve/gve_adminq.c | 5 +- drivers/net/ethernet/google/gve/gve_main.c | 26 +- drivers/net/ethernet/google/gve/gve_rx.c | 4 +- drivers/net/ethernet/google/gve/gve_rx_dqo.c | 4 +- drivers/net/ethernet/hisilicon/hix5hd2_gmac.c | 8 +- drivers/net/ethernet/hisilicon/hns/hns_enet.c | 62 +- .../net/ethernet/hisilicon/hns3/hns3_enet.c | 101 ++- .../ethernet/hisilicon/hns3/hns3_ethtool.c | 4 +- .../net/ethernet/huawei/hinic/hinic_main.c | 86 +- drivers/net/ethernet/huawei/hinic/hinic_rx.c | 4 +- drivers/net/ethernet/ibm/ehea/ehea_main.c | 34 +- drivers/net/ethernet/ibm/emac/core.c | 10 +- drivers/net/ethernet/ibm/ibmveth.c | 58 +- drivers/net/ethernet/ibm/ibmvnic.c | 48 +- drivers/net/ethernet/intel/e100.c | 20 +- drivers/net/ethernet/intel/e1000/e1000.h | 1 + drivers/net/ethernet/intel/e1000/e1000_main.c | 71 +- drivers/net/ethernet/intel/e1000e/netdev.c | 109 +-- drivers/net/ethernet/intel/fm10k/fm10k.h | 1 + drivers/net/ethernet/intel/fm10k/fm10k_main.c | 6 +- .../net/ethernet/intel/fm10k/fm10k_netdev.c | 51 +- drivers/net/ethernet/intel/fm10k/fm10k_pci.c | 10 +- .../net/ethernet/intel/i40e/i40e_debugfs.c | 12 +- drivers/net/ethernet/intel/i40e/i40e_main.c | 133 ++-- drivers/net/ethernet/intel/i40e/i40e_txrx.c | 6 +- drivers/net/ethernet/intel/iavf/iavf.h | 1 + drivers/net/ethernet/intel/iavf/iavf_main.c | 231 +++--- drivers/net/ethernet/intel/iavf/iavf_txrx.c | 8 +- .../net/ethernet/intel/iavf/iavf_virtchnl.c | 4 +- drivers/net/ethernet/intel/ice/ice.h | 1 + drivers/net/ethernet/intel/ice/ice_main.c | 220 +++--- drivers/net/ethernet/intel/ice/ice_repr.c | 2 +- drivers/net/ethernet/intel/ice/ice_tc_lib.c | 2 +- drivers/net/ethernet/intel/ice/ice_txrx_lib.c | 8 +- drivers/net/ethernet/intel/igb/igb_ethtool.c | 2 +- drivers/net/ethernet/intel/igb/igb_main.c | 141 ++-- drivers/net/ethernet/intel/igbvf/netdev.c | 93 ++- drivers/net/ethernet/intel/igc/igc_ethtool.c | 2 +- drivers/net/ethernet/intel/igc/igc_mac.c | 1 + drivers/net/ethernet/intel/igc/igc_main.c | 127 +-- drivers/net/ethernet/intel/ixgb/ixgb_main.c | 38 +- drivers/net/ethernet/intel/ixgbe/ixgbe.h | 1 + .../net/ethernet/intel/ixgbe/ixgbe_dcb_nl.c | 2 +- .../net/ethernet/intel/ixgbe/ixgbe_ethtool.c | 2 +- drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.c | 6 +- drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c | 2 +- drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 231 +++--- .../net/ethernet/intel/ixgbe/ixgbe_sriov.c | 4 +- drivers/net/ethernet/intel/ixgbevf/ipsec.c | 17 +- drivers/net/ethernet/intel/ixgbevf/ixgbevf.h | 1 + .../net/ethernet/intel/ixgbevf/ixgbevf_main.c | 115 +-- drivers/net/ethernet/jme.c | 50 +- drivers/net/ethernet/marvell/mv643xx_eth.c | 13 +- drivers/net/ethernet/marvell/mvneta.c | 21 +- .../net/ethernet/marvell/mvpp2/mvpp2_main.c | 61 +- .../ethernet/marvell/octeon_ep/octep_main.c | 6 +- .../marvell/octeontx2/nic/otx2_common.c | 27 +- .../marvell/octeontx2/nic/otx2_ethtool.c | 4 +- .../ethernet/marvell/octeontx2/nic/otx2_pf.c | 56 +- .../marvell/octeontx2/nic/otx2_txrx.c | 6 +- .../ethernet/marvell/octeontx2/nic/otx2_vf.c | 32 +- .../ethernet/marvell/prestera/prestera_main.c | 4 +- drivers/net/ethernet/marvell/skge.c | 15 +- drivers/net/ethernet/marvell/sky2.c | 66 +- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 74 +- drivers/net/ethernet/mediatek/mtk_eth_soc.h | 12 +- .../net/ethernet/mellanox/mlx4/en_ethtool.c | 4 +- drivers/net/ethernet/mellanox/mlx4/en_main.c | 7 +- .../net/ethernet/mellanox/mlx4/en_netdev.c | 170 ++-- .../net/ethernet/mellanox/mlx4/en_resources.c | 4 +- drivers/net/ethernet/mellanox/mlx4/en_rx.c | 14 +- drivers/net/ethernet/mellanox/mlx4/mlx4_en.h | 5 +- .../mellanox/mlx5/core/en_accel/ipsec.c | 16 +- .../mellanox/mlx5/core/en_accel/ipsec_rxtx.h | 4 +- .../mellanox/mlx5/core/en_accel/ktls.c | 10 +- .../net/ethernet/mellanox/mlx5/core/en_arfs.c | 4 +- .../ethernet/mellanox/mlx5/core/en_ethtool.c | 2 +- .../net/ethernet/mellanox/mlx5/core/en_fs.c | 2 +- .../net/ethernet/mellanox/mlx5/core/en_main.c | 215 ++--- .../net/ethernet/mellanox/mlx5/core/en_rep.c | 22 +- .../net/ethernet/mellanox/mlx5/core/en_rx.c | 8 +- .../net/ethernet/mellanox/mlx5/core/en_tc.c | 2 +- .../ethernet/mellanox/mlx5/core/ipoib/ipoib.c | 22 +- .../net/ethernet/mellanox/mlxsw/spectrum.c | 37 +- drivers/net/ethernet/micrel/ksz884x.c | 15 +- drivers/net/ethernet/microchip/lan743x_main.c | 9 +- .../ethernet/microchip/lan966x/lan966x_fdma.c | 2 +- .../ethernet/microchip/lan966x/lan966x_main.c | 6 +- .../ethernet/microchip/sparx5/sparx5_fdma.c | 2 +- drivers/net/ethernet/microsoft/mana/mana_en.c | 21 +- drivers/net/ethernet/mscc/ocelot.c | 2 +- drivers/net/ethernet/mscc/ocelot_net.c | 23 +- .../net/ethernet/myricom/myri10ge/myri10ge.c | 36 +- drivers/net/ethernet/natsemi/ns83820.c | 11 +- drivers/net/ethernet/neterion/s2io.c | 34 +- .../net/ethernet/netronome/nfp/crypto/tls.c | 8 +- drivers/net/ethernet/netronome/nfp/nfd3/dp.c | 4 +- drivers/net/ethernet/netronome/nfp/nfdk/dp.c | 4 +- drivers/net/ethernet/netronome/nfp/nfp_net.h | 1 + .../ethernet/netronome/nfp/nfp_net_common.c | 109 +-- .../net/ethernet/netronome/nfp/nfp_net_repr.c | 48 +- drivers/net/ethernet/netronome/nfp/nfp_port.c | 3 +- drivers/net/ethernet/ni/nixge.c | 4 +- drivers/net/ethernet/nvidia/forcedeth.c | 57 +- .../ethernet/oki-semi/pch_gbe/pch_gbe_main.c | 14 +- .../ethernet/oki-semi/pch_gbe/pch_gbe_param.c | 4 +- drivers/net/ethernet/pasemi/pasemi_mac.c | 11 +- .../net/ethernet/pensando/ionic/ionic_lif.c | 110 +-- .../net/ethernet/pensando/ionic/ionic_txrx.c | 6 +- .../ethernet/qlogic/netxen/netxen_nic_init.c | 4 +- .../ethernet/qlogic/netxen/netxen_nic_main.c | 50 +- .../net/ethernet/qlogic/qede/qede_ethtool.c | 3 +- .../net/ethernet/qlogic/qede/qede_filter.c | 8 +- drivers/net/ethernet/qlogic/qede/qede_fp.c | 6 +- drivers/net/ethernet/qlogic/qede/qede_main.c | 81 +- drivers/net/ethernet/qlogic/qla3xxx.c | 9 +- .../net/ethernet/qlogic/qlcnic/qlcnic_hw.c | 57 +- .../net/ethernet/qlogic/qlcnic/qlcnic_io.c | 2 +- .../net/ethernet/qlogic/qlcnic/qlcnic_main.c | 52 +- drivers/net/ethernet/qualcomm/emac/emac-mac.c | 4 +- drivers/net/ethernet/qualcomm/emac/emac.c | 27 +- .../ethernet/qualcomm/rmnet/rmnet_map_data.c | 7 +- .../net/ethernet/qualcomm/rmnet/rmnet_vnd.c | 14 +- drivers/net/ethernet/realtek/8139cp.c | 38 +- drivers/net/ethernet/realtek/8139too.c | 26 +- drivers/net/ethernet/realtek/r8169_main.c | 70 +- drivers/net/ethernet/renesas/ravb.h | 4 +- drivers/net/ethernet/renesas/ravb_main.c | 39 +- drivers/net/ethernet/renesas/sh_eth.c | 20 +- drivers/net/ethernet/rocker/rocker_main.c | 4 +- .../net/ethernet/samsung/sxgbe/sxgbe_common.h | 7 +- .../net/ethernet/samsung/sxgbe/sxgbe_main.c | 24 +- drivers/net/ethernet/sfc/ef10.c | 35 +- drivers/net/ethernet/sfc/ef100_netdev.c | 15 +- drivers/net/ethernet/sfc/ef100_nic.c | 33 +- drivers/net/ethernet/sfc/ef100_rep.c | 4 +- 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 | 72 +- drivers/net/ethernet/sfc/efx_common.c | 28 +- drivers/net/ethernet/sfc/falcon/efx.c | 62 +- 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/mcdi_filters.c | 15 +- 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 | 5 +- drivers/net/ethernet/sfc/rx_common.h | 4 + drivers/net/ethernet/sfc/siena/efx.c | 56 +- drivers/net/ethernet/sfc/siena/efx.h | 2 + drivers/net/ethernet/sfc/siena/efx_common.c | 28 +- drivers/net/ethernet/sfc/siena/farch.c | 2 +- .../net/ethernet/sfc/siena/mcdi_port_common.c | 2 +- drivers/net/ethernet/sfc/siena/net_driver.h | 5 +- drivers/net/ethernet/sfc/siena/rx.c | 2 +- drivers/net/ethernet/sfc/siena/rx_common.c | 4 +- drivers/net/ethernet/sfc/siena/siena.c | 3 +- drivers/net/ethernet/sfc/siena/tx_common.c | 2 +- drivers/net/ethernet/sfc/tx_common.c | 2 +- drivers/net/ethernet/sgi/ioc3-eth.c | 15 +- drivers/net/ethernet/silan/sc92031.c | 11 +- drivers/net/ethernet/socionext/netsec.c | 13 +- drivers/net/ethernet/socionext/sni_ave.c | 7 +- .../net/ethernet/stmicro/stmmac/dwmac4_core.c | 2 +- .../net/ethernet/stmicro/stmmac/stmmac_main.c | 53 +- .../stmicro/stmmac/stmmac_selftests.c | 4 +- drivers/net/ethernet/sun/cassini.c | 9 +- drivers/net/ethernet/sun/ldmvsw.c | 7 +- drivers/net/ethernet/sun/niu.c | 16 +- drivers/net/ethernet/sun/sungem.c | 13 +- drivers/net/ethernet/sun/sunhme.c | 15 +- drivers/net/ethernet/sun/sunvnet.c | 10 +- drivers/net/ethernet/sun/sunvnet_common.c | 4 +- .../net/ethernet/synopsys/dwc-xlgmac-common.c | 27 +- drivers/net/ethernet/synopsys/dwc-xlgmac-hw.c | 14 +- .../net/ethernet/synopsys/dwc-xlgmac-net.c | 30 +- drivers/net/ethernet/synopsys/dwc-xlgmac.h | 1 + drivers/net/ethernet/tehuti/tehuti.c | 27 +- drivers/net/ethernet/tehuti/tehuti.h | 1 + drivers/net/ethernet/ti/am65-cpsw-nuss.c | 23 +- drivers/net/ethernet/ti/cpsw.c | 7 +- drivers/net/ethernet/ti/cpsw_new.c | 11 +- drivers/net/ethernet/ti/netcp_core.c | 6 +- drivers/net/ethernet/toshiba/ps3_gelic_net.c | 13 +- drivers/net/ethernet/toshiba/spider_net.c | 11 +- drivers/net/ethernet/tundra/tsi108_eth.c | 3 +- drivers/net/ethernet/via/via-rhine.c | 11 +- drivers/net/ethernet/via/via-velocity.c | 19 +- .../net/ethernet/wangxun/txgbe/txgbe_main.c | 3 +- drivers/net/ethernet/wiznet/w5100.c | 3 +- drivers/net/ethernet/wiznet/w5300.c | 3 +- drivers/net/ethernet/xilinx/ll_temac_main.c | 6 +- .../net/ethernet/xilinx/xilinx_axienet_main.c | 8 +- drivers/net/fjes/fjes_main.c | 3 +- drivers/net/geneve.c | 24 +- drivers/net/gtp.c | 2 +- drivers/net/hamradio/bpqether.c | 4 +- drivers/net/hyperv/hyperv_net.h | 5 +- drivers/net/hyperv/netvsc_bpf.c | 2 +- drivers/net/hyperv/netvsc_drv.c | 32 +- drivers/net/hyperv/rndis_filter.c | 27 +- drivers/net/ifb.c | 27 +- drivers/net/ipa/ipa_modem.c | 4 +- drivers/net/ipvlan/ipvlan_main.c | 83 +- drivers/net/ipvlan/ipvtap.c | 12 +- drivers/net/loopback.c | 25 +- drivers/net/macsec.c | 41 +- drivers/net/macvlan.c | 88 ++- drivers/net/macvtap.c | 12 +- drivers/net/net_failover.c | 37 +- drivers/net/netdevsim/ipsec.c | 13 +- drivers/net/netdevsim/netdev.c | 19 +- drivers/net/netdevsim/netdevsim.h | 1 + drivers/net/nlmon.c | 11 +- drivers/net/ntb_netdev.c | 4 +- drivers/net/ppp/ppp_generic.c | 3 +- drivers/net/rionet.c | 4 +- drivers/net/tap.c | 40 +- drivers/net/team/team.c | 67 +- drivers/net/thunderbolt.c | 14 +- drivers/net/tun.c | 57 +- drivers/net/usb/aqc111.c | 62 +- drivers/net/usb/aqc111.h | 14 - drivers/net/usb/ax88179_178a.c | 23 +- drivers/net/usb/cdc-phonet.c | 3 +- drivers/net/usb/cdc_mbim.c | 4 +- drivers/net/usb/lan78xx.c | 34 +- drivers/net/usb/r8152.c | 81 +- drivers/net/usb/smsc75xx.c | 18 +- drivers/net/usb/smsc95xx.c | 17 +- drivers/net/veth.c | 72 +- drivers/net/virtio_net.c | 59 +- drivers/net/vmxnet3/vmxnet3_drv.c | 82 +- drivers/net/vmxnet3/vmxnet3_ethtool.c | 93 ++- drivers/net/vmxnet3/vmxnet3_int.h | 1 + drivers/net/vrf.c | 20 +- drivers/net/vsockmon.c | 11 +- drivers/net/vxlan/vxlan_core.c | 24 +- drivers/net/wireguard/device.c | 24 +- drivers/net/wireless/ath/ath10k/mac.c | 7 +- drivers/net/wireless/ath/ath11k/mac.c | 4 +- drivers/net/wireless/ath/ath6kl/core.h | 1 + drivers/net/wireless/ath/ath6kl/main.c | 16 +- drivers/net/wireless/ath/ath6kl/txrx.c | 4 +- drivers/net/wireless/ath/wil6210/netdev.c | 16 +- .../broadcom/brcm80211/brcmfmac/core.c | 5 +- drivers/net/wireless/intel/iwlwifi/cfg/1000.c | 2 + drivers/net/wireless/intel/iwlwifi/cfg/2000.c | 4 + .../net/wireless/intel/iwlwifi/cfg/22000.c | 4 +- drivers/net/wireless/intel/iwlwifi/cfg/5000.c | 3 + drivers/net/wireless/intel/iwlwifi/cfg/6000.c | 7 + drivers/net/wireless/intel/iwlwifi/cfg/7000.c | 1 + drivers/net/wireless/intel/iwlwifi/cfg/8000.c | 2 +- drivers/net/wireless/intel/iwlwifi/cfg/9000.c | 2 +- .../net/wireless/intel/iwlwifi/dvm/mac80211.c | 8 +- .../net/wireless/intel/iwlwifi/iwl-config.h | 15 +- drivers/net/wireless/intel/iwlwifi/iwl-drv.c | 33 + .../net/wireless/intel/iwlwifi/mvm/mac80211.c | 15 +- drivers/net/wireless/intel/iwlwifi/mvm/mvm.h | 8 + drivers/net/wireless/intel/iwlwifi/mvm/ops.c | 28 + drivers/net/wireless/intel/iwlwifi/mvm/rx.c | 2 +- drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c | 2 +- drivers/net/wireless/intel/iwlwifi/mvm/tx.c | 11 +- .../net/wireless/mediatek/mt76/mt7615/init.c | 4 +- .../net/wireless/mediatek/mt76/mt7915/init.c | 4 +- .../net/wireless/mediatek/mt76/mt7921/init.c | 4 +- drivers/net/wwan/t7xx/t7xx_netdev.c | 16 +- drivers/net/xen-netback/interface.c | 27 +- drivers/net/xen-netfront.c | 42 +- drivers/s390/net/qeth_core_main.c | 109 +-- drivers/s390/net/qeth_l2_main.c | 34 +- drivers/s390/net/qeth_l3_main.c | 37 +- drivers/scsi/fcoe/fcoe.c | 12 +- drivers/staging/octeon/ethernet.c | 9 +- drivers/staging/qlge/qlge_main.c | 47 +- drivers/usb/gadget/function/f_phonet.c | 3 +- include/linux/if_vlan.h | 14 +- include/linux/netdev_features.h | 221 +++--- include/linux/netdev_features_helper.h | 742 ++++++++++++++++++ include/linux/netdevice.h | 110 +-- include/linux/skbuff.h | 4 +- include/net/bonding.h | 5 +- include/net/ip_tunnels.h | 2 +- include/net/net_failover.h | 8 +- include/net/pkt_cls.h | 2 +- include/net/sock.h | 5 +- include/net/udp.h | 7 +- include/net/udp_tunnel.h | 8 +- include/net/vxlan.h | 2 +- lib/test_bpf.c | 42 +- lib/vsprintf.c | 11 +- net/8021q/vlan.c | 6 +- net/8021q/vlan.h | 18 +- net/8021q/vlan_core.c | 4 +- net/8021q/vlan_dev.c | 42 +- net/batman-adv/soft-interface.c | 9 +- net/bridge/br_device.c | 27 +- net/bridge/br_if.c | 2 +- net/core/Makefile | 2 +- net/core/dev.c | 350 ++++++--- net/core/netdev_features.c | 281 +++++++ net/core/pktgen.c | 6 +- net/core/skbuff.c | 9 +- net/core/skmsg.c | 2 +- net/core/sock.c | 14 +- net/dccp/ipv4.c | 2 +- net/dccp/ipv6.c | 8 +- net/dsa/slave.c | 26 +- net/ethtool/features.c | 95 +-- net/ethtool/ioctl.c | 133 ++-- net/hsr/hsr_device.c | 21 +- net/hsr/hsr_forward.c | 8 +- net/hsr/hsr_framereg.c | 2 +- net/hsr/hsr_slave.c | 2 +- net/ieee802154/6lowpan/core.c | 3 +- net/ieee802154/core.c | 15 +- net/ipv4/af_inet.c | 4 +- net/ipv4/esp4_offload.c | 22 +- net/ipv4/gre_offload.c | 6 +- net/ipv4/ip_gre.c | 31 +- net/ipv4/ip_output.c | 19 +- net/ipv4/ip_tunnel.c | 3 +- net/ipv4/ip_vti.c | 3 +- net/ipv4/ipip.c | 21 +- net/ipv4/ipmr.c | 2 +- net/ipv4/tcp.c | 8 +- net/ipv4/tcp_ipv4.c | 2 +- net/ipv4/tcp_offload.c | 3 +- net/ipv4/udp_offload.c | 20 +- net/ipv6/af_inet6.c | 2 +- net/ipv6/esp6_offload.c | 16 +- net/ipv6/inet6_connection_sock.c | 2 +- net/ipv6/ip6_gre.c | 21 +- net/ipv6/ip6_offload.c | 2 +- net/ipv6/ip6_output.c | 15 +- net/ipv6/ip6_tunnel.c | 23 +- net/ipv6/ip6mr.c | 3 +- net/ipv6/sit.c | 23 +- net/ipv6/tcp_ipv6.c | 2 +- net/ipv6/udp_offload.c | 2 +- net/l2tp/l2tp_eth.c | 2 +- net/mac80211/ieee80211_i.h | 13 +- net/mac80211/iface.c | 9 +- net/mac80211/main.c | 28 +- net/mac80211/tx.c | 2 +- net/mpls/mpls_gso.c | 3 +- net/netfilter/ipvs/ip_vs_proto_sctp.c | 2 +- net/netfilter/nfnetlink_queue.c | 2 +- net/nsh/nsh.c | 5 +- net/openvswitch/datapath.c | 7 +- net/openvswitch/vport-internal_dev.c | 21 +- net/phonet/pep-gprs.c | 4 +- net/sched/sch_cake.c | 2 +- net/sched/sch_netem.c | 2 +- net/sched/sch_taprio.c | 2 +- net/sched/sch_tbf.c | 3 +- net/sctp/offload.c | 12 +- net/sctp/output.c | 2 +- net/sunrpc/sunrpc.h | 2 +- net/tls/tls_device.c | 8 +- net/wireless/core.c | 15 +- net/xfrm/xfrm_device.c | 26 +- net/xfrm/xfrm_interface.c | 18 +- net/xfrm/xfrm_output.c | 5 +- 481 files changed, 8105 insertions(+), 4331 deletions(-) create mode 100644 include/linux/netdev_features_helper.h create mode 100644 net/core/netdev_features.c
Introduce a set of bitmap operation helpers for netdev features, then we can use them to replace the logical operation with them.
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 | 11 + include/linux/netdev_features_helper.h | 707 ++++++++++++++++++ include/linux/netdevice.h | 45 +- net/8021q/vlan_dev.c | 1 + net/core/dev.c | 1 + 6 files changed, 748 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 8b77582bdfa0..912d08923e64 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 7c2d77d75a88..9d434b4e6e6e 100644 --- a/include/linux/netdev_features.h +++ b/include/linux/netdev_features.h @@ -11,6 +11,17 @@
typedef u64 netdev_features_t;
+struct netdev_feature_set { + unsigned int cnt; + unsigned short feature_bits[]; +}; + +#define DECLARE_NETDEV_FEATURE_SET(name, features...) \ + const struct netdev_feature_set name = { \ + .cnt = sizeof((unsigned short[]){ features }) / sizeof(unsigned short), \ + .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..5423927d139b --- /dev/null +++ b/include/linux/netdev_features_helper.h @@ -0,0 +1,707 @@ +/* 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; +} + +/* active_feature prefer to netdev->features */ +#define netdev_active_features_zero(ndev) \ + netdev_features_zero(&ndev->features) + +#define netdev_hw_features_zero(ndev) \ + netdev_features_zero(&ndev->hw_features) + +#define netdev_wanted_features_zero(ndev) \ + netdev_features_zero(&ndev->wanted_features) + +#define netdev_vlan_features_zero(ndev) \ + netdev_features_zero(&ndev->vlan_features) + +#define netdev_hw_enc_features_zero(ndev) \ + netdev_features_zero(&ndev->hw_enc_features) + +#define netdev_mpls_features_zero(ndev) \ + netdev_features_zero(&ndev->mpls_features) + +#define netdev_gso_partial_features_zero(ndev) \ + netdev_features_zero(&ndev->gso_partial_features) + +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; +} + +#define netdev_active_features_empty(ndev) \ + netdev_features_empty(ndev->features) + +#define netdev_hw_features_empty(ndev) \ + netdev_features_empty(ndev->hw_features) + +#define netdev_wanted_features_empty(ndev) \ + netdev_features_empty(ndev->wanted_features) + +#define netdev_vlan_features_empty(ndev) \ + netdev_features_empty(ndev->vlan_features) + +#define netdev_hw_enc_features_empty(ndev) \ + netdev_features_empty(ndev->hw_enc_features) + +#define netdev_mpls_features_empty(ndev) \ + netdev_features_empty(ndev->mpls_features) + +#define netdev_gso_partial_features_empty(ndev) \ + netdev_features_empty(ndev->gso_partial_features) + +/* helpers for netdev features '==' operation */ +static inline bool netdev_features_equal(const netdev_features_t src1, + const netdev_features_t src2) +{ + return src1 == src2; +} + +#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); +} + +static inline void netdev_feature_change(int nr, netdev_features_t *src) +{ + if (*src & __NETIF_F_BIT(nr)) + *src &= ~(__NETIF_F_BIT(nr)); + else + *src |= __NETIF_F_BIT(nr); +} + +#define netdev_active_feature_change(ndev, nr) \ + netdev_feature_change(nr, &ndev->features) + +#define netdev_hw_feature_change(ndev, nr) \ + netdev_feature_change(nr, &ndev->hw_features) + +#define netdev_wanted_feature_change(ndev, nr) \ + netdev_feature_change(nr, &ndev->wanted_features) + +#define netdev_vlan_feature_change(ndev, nr) \ + netdev_feature_change(nr, &ndev->vlan_features) + +#define netdev_hw_enc_feature_change(ndev, nr) \ + netdev_feature_change(nr, &ndev->hw_enc_features) + +#define netdev_mpls_feature_change(ndev, nr) \ + netdev_feature_change(nr, &ndev->mpls_features) + +#define netdev_gso_partial_feature_change(ndev, nr) \ + netdev_feature_change(nr, &ndev->gso_partial_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) + +/* helpers for netdev features 'clear bit array' operation */ +static inline void +netdev_features_clear_array(const struct netdev_feature_set *set, + netdev_features_t *dst) +{ + int i; + + for (i = 0; i < set->cnt; i++) + netdev_feature_del(set->feature_bits[i], dst); +} + +#define netdev_active_features_clear_array(ndev, set) \ + netdev_features_clear_array(set, &ndev->features) + +#define netdev_hw_features_clear_array(ndev, set) \ + netdev_features_clear_array(set, &ndev->hw_features) + +#define netdev_wanted_features_clear_array(ndev, set) \ + netdev_features_clear_array(set, &ndev->wanted_features) + +#define netdev_vlan_features_clear_array(ndev, set) \ + netdev_features_clear_array(set, &ndev->vlan_features) + +#define netdev_hw_enc_features_clear_array(ndev, set) \ + netdev_features_clear_array(set, &ndev->hw_enc_features) + +#define netdev_mpls_features_clear_array(ndev, set) \ + netdev_features_set_array(set, &ndev->mpls_features) + +#define netdev_gso_partial_features_clear_array(ndev, set) \ + netdev_features_clear_array(set, &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 1a3cb93c3dcc..1bd5dcbc884d 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -2335,6 +2335,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) @@ -4832,24 +4859,6 @@ extern const struct kobj_ns_type_operations net_ns_type_operations;
const char *netdev_drivername(const struct net_device *dev);
-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 035812b0461c..64ca07daf4ee 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 716df64fcfa5..45e80c84497f 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>
Reviewed-by: Jie Wang wangjie125@huawei.com
On 2022/7/30 18:17, Jian Shen wrote:
Introduce a set of bitmap operation helpers for netdev features, then we can use them to replace the logical operation with them.
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 | 11 + include/linux/netdev_features_helper.h | 707 ++++++++++++++++++ include/linux/netdevice.h | 45 +- net/8021q/vlan_dev.c | 1 + net/core/dev.c | 1 + 6 files changed, 748 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 8b77582bdfa0..912d08923e64 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 7c2d77d75a88..9d434b4e6e6e 100644 --- a/include/linux/netdev_features.h +++ b/include/linux/netdev_features.h @@ -11,6 +11,17 @@
typedef u64 netdev_features_t;
+struct netdev_feature_set {
- unsigned int cnt;
- unsigned short feature_bits[];
+};
+#define DECLARE_NETDEV_FEATURE_SET(name, features...) \
- const struct netdev_feature_set name = { \
.cnt = sizeof((unsigned short[]){ features }) / sizeof(unsigned short), \
.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..5423927d139b --- /dev/null +++ b/include/linux/netdev_features_helper.h @@ -0,0 +1,707 @@ +/* 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;
+}
+/* active_feature prefer to netdev->features */ +#define netdev_active_features_zero(ndev) \
netdev_features_zero(&ndev->features)
+#define netdev_hw_features_zero(ndev) \
netdev_features_zero(&ndev->hw_features)
+#define netdev_wanted_features_zero(ndev) \
netdev_features_zero(&ndev->wanted_features)
+#define netdev_vlan_features_zero(ndev) \
netdev_features_zero(&ndev->vlan_features)
+#define netdev_hw_enc_features_zero(ndev) \
netdev_features_zero(&ndev->hw_enc_features)
+#define netdev_mpls_features_zero(ndev) \
netdev_features_zero(&ndev->mpls_features)
+#define netdev_gso_partial_features_zero(ndev) \
netdev_features_zero(&ndev->gso_partial_features)
+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;
+}
+#define netdev_active_features_empty(ndev) \
netdev_features_empty(ndev->features)
+#define netdev_hw_features_empty(ndev) \
netdev_features_empty(ndev->hw_features)
+#define netdev_wanted_features_empty(ndev) \
netdev_features_empty(ndev->wanted_features)
+#define netdev_vlan_features_empty(ndev) \
netdev_features_empty(ndev->vlan_features)
+#define netdev_hw_enc_features_empty(ndev) \
netdev_features_empty(ndev->hw_enc_features)
+#define netdev_mpls_features_empty(ndev) \
netdev_features_empty(ndev->mpls_features)
+#define netdev_gso_partial_features_empty(ndev) \
netdev_features_empty(ndev->gso_partial_features)
+/* helpers for netdev features '==' operation */ +static inline bool netdev_features_equal(const netdev_features_t src1,
const netdev_features_t src2)
+{
- return src1 == src2;
+}
+#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);
+}
+static inline void netdev_feature_change(int nr, netdev_features_t *src) +{
- if (*src & __NETIF_F_BIT(nr))
*src &= ~(__NETIF_F_BIT(nr));
- else
*src |= __NETIF_F_BIT(nr);
+}
+#define netdev_active_feature_change(ndev, nr) \
netdev_feature_change(nr, &ndev->features)
+#define netdev_hw_feature_change(ndev, nr) \
netdev_feature_change(nr, &ndev->hw_features)
+#define netdev_wanted_feature_change(ndev, nr) \
netdev_feature_change(nr, &ndev->wanted_features)
+#define netdev_vlan_feature_change(ndev, nr) \
netdev_feature_change(nr, &ndev->vlan_features)
+#define netdev_hw_enc_feature_change(ndev, nr) \
netdev_feature_change(nr, &ndev->hw_enc_features)
+#define netdev_mpls_feature_change(ndev, nr) \
netdev_feature_change(nr, &ndev->mpls_features)
+#define netdev_gso_partial_feature_change(ndev, nr) \
netdev_feature_change(nr, &ndev->gso_partial_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)
+/* helpers for netdev features 'clear bit array' operation */ +static inline void +netdev_features_clear_array(const struct netdev_feature_set *set,
netdev_features_t *dst)
+{
- int i;
- for (i = 0; i < set->cnt; i++)
netdev_feature_del(set->feature_bits[i], dst);
+}
+#define netdev_active_features_clear_array(ndev, set) \
netdev_features_clear_array(set, &ndev->features)
+#define netdev_hw_features_clear_array(ndev, set) \
netdev_features_clear_array(set, &ndev->hw_features)
+#define netdev_wanted_features_clear_array(ndev, set) \
netdev_features_clear_array(set, &ndev->wanted_features)
+#define netdev_vlan_features_clear_array(ndev, set) \
netdev_features_clear_array(set, &ndev->vlan_features)
+#define netdev_hw_enc_features_clear_array(ndev, set) \
netdev_features_clear_array(set, &ndev->hw_enc_features)
+#define netdev_mpls_features_clear_array(ndev, set) \
netdev_features_set_array(set, &ndev->mpls_features)
+#define netdev_gso_partial_features_clear_array(ndev, set) \
netdev_features_clear_array(set, &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 1a3cb93c3dcc..1bd5dcbc884d 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -2335,6 +2335,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) @@ -4832,24 +4859,6 @@ extern const struct kobj_ns_type_operations net_ns_type_operations;
const char *netdev_drivername(const struct net_device *dev);
-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 035812b0461c..64ca07daf4ee 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 716df64fcfa5..45e80c84497f 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>
Reviewed-by: Guangbin Huang huangguangbin2@huawei.com
On 2022/7/30 18:17, Jian Shen wrote:
Introduce a set of bitmap operation helpers for netdev features, then we can use them to replace the logical operation with them.
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 | 11 + include/linux/netdev_features_helper.h | 707 ++++++++++++++++++ include/linux/netdevice.h | 45 +- net/8021q/vlan_dev.c | 1 + net/core/dev.c | 1 + 6 files changed, 748 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 8b77582bdfa0..912d08923e64 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 7c2d77d75a88..9d434b4e6e6e 100644 --- a/include/linux/netdev_features.h +++ b/include/linux/netdev_features.h @@ -11,6 +11,17 @@
typedef u64 netdev_features_t;
+struct netdev_feature_set {
- unsigned int cnt;
- unsigned short feature_bits[];
+};
+#define DECLARE_NETDEV_FEATURE_SET(name, features...) \
- const struct netdev_feature_set name = { \
.cnt = sizeof((unsigned short[]){ features }) / sizeof(unsigned short), \
.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..5423927d139b --- /dev/null +++ b/include/linux/netdev_features_helper.h @@ -0,0 +1,707 @@ +/* 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;
+}
+/* active_feature prefer to netdev->features */ +#define netdev_active_features_zero(ndev) \
netdev_features_zero(&ndev->features)
+#define netdev_hw_features_zero(ndev) \
netdev_features_zero(&ndev->hw_features)
+#define netdev_wanted_features_zero(ndev) \
netdev_features_zero(&ndev->wanted_features)
+#define netdev_vlan_features_zero(ndev) \
netdev_features_zero(&ndev->vlan_features)
+#define netdev_hw_enc_features_zero(ndev) \
netdev_features_zero(&ndev->hw_enc_features)
+#define netdev_mpls_features_zero(ndev) \
netdev_features_zero(&ndev->mpls_features)
+#define netdev_gso_partial_features_zero(ndev) \
netdev_features_zero(&ndev->gso_partial_features)
+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;
+}
+#define netdev_active_features_empty(ndev) \
netdev_features_empty(ndev->features)
+#define netdev_hw_features_empty(ndev) \
netdev_features_empty(ndev->hw_features)
+#define netdev_wanted_features_empty(ndev) \
netdev_features_empty(ndev->wanted_features)
+#define netdev_vlan_features_empty(ndev) \
netdev_features_empty(ndev->vlan_features)
+#define netdev_hw_enc_features_empty(ndev) \
netdev_features_empty(ndev->hw_enc_features)
+#define netdev_mpls_features_empty(ndev) \
netdev_features_empty(ndev->mpls_features)
+#define netdev_gso_partial_features_empty(ndev) \
netdev_features_empty(ndev->gso_partial_features)
+/* helpers for netdev features '==' operation */ +static inline bool netdev_features_equal(const netdev_features_t src1,
const netdev_features_t src2)
+{
- return src1 == src2;
+}
+#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);
+}
+static inline void netdev_feature_change(int nr, netdev_features_t *src) +{
- if (*src & __NETIF_F_BIT(nr))
*src &= ~(__NETIF_F_BIT(nr));
- else
*src |= __NETIF_F_BIT(nr);
+}
+#define netdev_active_feature_change(ndev, nr) \
netdev_feature_change(nr, &ndev->features)
+#define netdev_hw_feature_change(ndev, nr) \
netdev_feature_change(nr, &ndev->hw_features)
+#define netdev_wanted_feature_change(ndev, nr) \
netdev_feature_change(nr, &ndev->wanted_features)
+#define netdev_vlan_feature_change(ndev, nr) \
netdev_feature_change(nr, &ndev->vlan_features)
+#define netdev_hw_enc_feature_change(ndev, nr) \
netdev_feature_change(nr, &ndev->hw_enc_features)
+#define netdev_mpls_feature_change(ndev, nr) \
netdev_feature_change(nr, &ndev->mpls_features)
+#define netdev_gso_partial_feature_change(ndev, nr) \
netdev_feature_change(nr, &ndev->gso_partial_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)
+/* helpers for netdev features 'clear bit array' operation */ +static inline void +netdev_features_clear_array(const struct netdev_feature_set *set,
netdev_features_t *dst)
+{
- int i;
- for (i = 0; i < set->cnt; i++)
netdev_feature_del(set->feature_bits[i], dst);
+}
+#define netdev_active_features_clear_array(ndev, set) \
netdev_features_clear_array(set, &ndev->features)
+#define netdev_hw_features_clear_array(ndev, set) \
netdev_features_clear_array(set, &ndev->hw_features)
+#define netdev_wanted_features_clear_array(ndev, set) \
netdev_features_clear_array(set, &ndev->wanted_features)
+#define netdev_vlan_features_clear_array(ndev, set) \
netdev_features_clear_array(set, &ndev->vlan_features)
+#define netdev_hw_enc_features_clear_array(ndev, set) \
netdev_features_clear_array(set, &ndev->hw_enc_features)
+#define netdev_mpls_features_clear_array(ndev, set) \
netdev_features_set_array(set, &ndev->mpls_features)
+#define netdev_gso_partial_features_clear_array(ndev, set) \
netdev_features_clear_array(set, &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 1a3cb93c3dcc..1bd5dcbc884d 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -2335,6 +2335,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)
@@ -4832,24 +4859,6 @@ extern const struct kobj_ns_type_operations net_ns_type_operations;
const char *netdev_drivername(const struct net_device *dev);
-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 035812b0461c..64ca07daf4ee 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 716df64fcfa5..45e80c84497f 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>
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/hyperv/hyperv_net.h | 5 +- include/linux/netdev_features.h | 111 +++++++++---- net/core/Makefile | 2 +- net/core/dev.c | 83 ++++++++++ net/core/netdev_features.c | 281 ++++++++++++++++++++++++++++++++ 5 files changed, 441 insertions(+), 41 deletions(-) create mode 100644 net/core/netdev_features.c
diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h index 25b38a374e3c..6336ed81fb8c 100644 --- a/drivers/net/hyperv/hyperv_net.h +++ b/drivers/net/hyperv/hyperv_net.h @@ -873,10 +873,7 @@ struct nvsp_message { #define NETVSC_RECEIVE_BUFFER_ID 0xcafe #define NETVSC_SEND_BUFFER_ID 0
-#define NETVSC_SUPPORTED_HW_FEATURES (NETIF_F_RXCSUM | NETIF_F_IP_CSUM | \ - NETIF_F_TSO | NETIF_F_IPV6_CSUM | \ - NETIF_F_TSO6 | NETIF_F_LRO | \ - NETIF_F_SG | NETIF_F_RXHASH) +#define NETVSC_SUPPORTED_HW_FEATURES netvsc_supported_hw_features
#define VRSS_SEND_TAB_SIZE 16 /* must be power of 2 */ #define VRSS_CHANNEL_MAX 64 diff --git a/include/linux/netdev_features.h b/include/linux/netdev_features.h index 9d434b4e6e6e..a005c781fabf 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; @@ -112,6 +113,64 @@ 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_offload_features __ro_after_init; +extern netdev_features_t netdev_stag_vlan_offload_features __ro_after_init; +extern netdev_features_t netdev_vlan_offload_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_multi_tags_features_mask __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 netdev_features_t netdev_empty_features __ro_after_init; +extern netdev_features_t netvsc_supported_hw_features __ro_after_init; +extern const struct netdev_feature_set netif_f_never_change_feature_set; +extern const struct netdev_feature_set netif_f_gso_feature_set_mask; +extern const struct netdev_feature_set netif_f_ip_csum_feature_set; +extern const struct netdev_feature_set netif_f_csum_feature_set_mask; +extern const struct netdev_feature_set netif_f_general_tso_feature_set; +extern const struct netdev_feature_set netif_f_all_tso_feature_set; +extern const struct netdev_feature_set netif_f_tso_ecn_feature_set; +extern const struct netdev_feature_set netif_f_all_fcoe_feature_set; +extern const struct netdev_feature_set netif_f_gso_soft_feature_set; +extern const struct netdev_feature_set netif_f_one_for_all_feature_set; +extern const struct netdev_feature_set netif_f_all_for_all_feature_set; +extern const struct netdev_feature_set netif_f_upper_disables_feature_set; +extern const struct netdev_feature_set netif_f_soft_feature_set; +extern const struct netdev_feature_set netif_f_soft_off_feature_set; +extern const struct netdev_feature_set netif_f_tx_vlan_feature_set; +extern const struct netdev_feature_set netif_f_rx_vlan_feature_set; +extern const struct netdev_feature_set netif_f_vlan_filter_feature_set; +extern const struct netdev_feature_set netif_f_ctag_vlan_feature_set; +extern const struct netdev_feature_set netif_f_stag_vlan_feature_set; +extern const struct netdev_feature_set netif_f_ctag_vlan_offload_feature_set; +extern const struct netdev_feature_set netif_f_stag_vlan_offload_feature_set; +extern const struct netdev_feature_set netif_f_multi_tags_feature_set_mask; +extern const struct netdev_feature_set netif_f_gso_encap_feature_set; +extern const struct netdev_feature_set netif_f_xfrm_feature_set; +extern const struct netdev_feature_set netif_f_tls_feature_set; +extern const struct netdev_feature_set netvsc_supported_hw_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) @@ -203,73 +262,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 e8ce3bd283a6..360a101584c8 100644 --- a/net/core/Makefile +++ b/net/core/Makefile @@ -12,7 +12,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 45e80c84497f..f7d6dfefa8a4 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> @@ -11362,6 +11363,86 @@ static struct pernet_operations __net_initdata default_device_ops = { .exit_batch = default_device_exit_batch, };
+static void __init netdev_features_init(void) +{ + netdev_features_t features; + + 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_gso_feature_set_mask, + &netdev_gso_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_gso_encap_feature_set, + &netdev_gso_encap_all_features); + + netdev_csum_gso_features_mask = + netdev_features_or(netdev_gso_software_features, + netdev_csum_features_mask); + + 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_features_or(netdev_rx_vlan_features, + netdev_tx_vlan_features); + netdev_features_set_array(&netif_f_ctag_vlan_offload_feature_set, + &netdev_ctag_vlan_offload_features); + netdev_features_set_array(&netif_f_stag_vlan_offload_feature_set, + &netdev_stag_vlan_offload_features); + netdev_vlan_offload_features = + netdev_features_or(netdev_ctag_vlan_offload_features, + netdev_stag_vlan_offload_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_multi_tags_feature_set_mask, + &netdev_multi_tags_features_mask); + + 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_features_set_array(&netif_f_never_change_feature_set, + &netdev_never_change_features); + netdev_features_fill(&features); + netdev_ethtool_features = + netdev_features_andnot(features, netdev_never_change_features); + + netdev_features_zero(&netdev_empty_features); + + netdev_features_set_array(&netvsc_supported_hw_feature_set, + &netvsc_supported_hw_features); +} + /* * Initialize the DEV module. At boot time this walks the device list and * unhooks any devices that fail to initialise (normally hardware not @@ -11392,6 +11473,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..158c750ea7a2 --- /dev/null +++ b/net/core/netdev_features.c @@ -0,0 +1,281 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Network device features. + */ + +#include <linux/netdev_features.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_offload_features __ro_after_init; +EXPORT_SYMBOL_GPL(netdev_ctag_vlan_offload_features); + +netdev_features_t netdev_stag_vlan_offload_features __ro_after_init; +EXPORT_SYMBOL_GPL(netdev_stag_vlan_offload_features); + +netdev_features_t netdev_vlan_offload_features __ro_after_init; +EXPORT_SYMBOL_GPL(netdev_vlan_offload_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_multi_tags_features_mask __ro_after_init; +EXPORT_SYMBOL_GPL(netdev_multi_tags_features_mask); + +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); + +netdev_features_t netdev_empty_features __ro_after_init; +EXPORT_SYMBOL_GPL(netdev_empty_features); + +netdev_features_t netvsc_supported_hw_features __ro_after_init; +EXPORT_SYMBOL_GPL(netvsc_supported_hw_features); + +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_BIT); +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_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_offload_feature_set, + NETIF_F_HW_VLAN_CTAG_TX_BIT, + NETIF_F_HW_VLAN_CTAG_RX_BIT); +EXPORT_SYMBOL_GPL(netif_f_ctag_vlan_offload_feature_set); + +DECLARE_NETDEV_FEATURE_SET(netif_f_stag_vlan_offload_feature_set, + NETIF_F_HW_VLAN_STAG_TX_BIT, + NETIF_F_HW_VLAN_STAG_RX_BIT); +EXPORT_SYMBOL_GPL(netif_f_stag_vlan_offload_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, + NETIF_F_HW_VLAN_CTAG_FILTER_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, + NETIF_F_HW_VLAN_STAG_FILTER_BIT); +EXPORT_SYMBOL_GPL(netif_f_stag_vlan_feature_set); + +DECLARE_NETDEV_FEATURE_SET(netif_f_multi_tags_feature_set_mask, + NETIF_F_SG_BIT, + NETIF_F_HIGHDMA_BIT, + NETIF_F_HW_CSUM_BIT, + NETIF_F_FRAGLIST_BIT, + NETIF_F_HW_VLAN_CTAG_TX_BIT, + NETIF_F_HW_VLAN_STAG_TX_BIT); +EXPORT_SYMBOL_GPL(netif_f_multi_tags_feature_set_mask); + +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); + +DECLARE_NETDEV_FEATURE_SET(netvsc_supported_hw_feature_set, + NETIF_F_RXCSUM_BIT, + NETIF_F_IP_CSUM_BIT, + NETIF_F_TSO_BIT, + NETIF_F_IPV6_CSUM_BIT, + NETIF_F_TSO6_BIT, + NETIF_F_LRO_BIT, + NETIF_F_SG_BIT, + NETIF_F_RXHASH_BIT); +EXPORT_SYMBOL_GPL(netvsc_supported_hw_feature_set);
Reviewed-by: Guangbin Huang huangguangbin2@huawei.com
On 2022/7/30 18:17, Jian Shen wrote:
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/hyperv/hyperv_net.h | 5 +- include/linux/netdev_features.h | 111 +++++++++---- net/core/Makefile | 2 +- net/core/dev.c | 83 ++++++++++ net/core/netdev_features.c | 281 ++++++++++++++++++++++++++++++++ 5 files changed, 441 insertions(+), 41 deletions(-) create mode 100644 net/core/netdev_features.c
diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h index 25b38a374e3c..6336ed81fb8c 100644 --- a/drivers/net/hyperv/hyperv_net.h +++ b/drivers/net/hyperv/hyperv_net.h @@ -873,10 +873,7 @@ struct nvsp_message { #define NETVSC_RECEIVE_BUFFER_ID 0xcafe #define NETVSC_SEND_BUFFER_ID 0
-#define NETVSC_SUPPORTED_HW_FEATURES (NETIF_F_RXCSUM | NETIF_F_IP_CSUM | \
NETIF_F_TSO | NETIF_F_IPV6_CSUM | \
NETIF_F_TSO6 | NETIF_F_LRO | \
NETIF_F_SG | NETIF_F_RXHASH)
+#define NETVSC_SUPPORTED_HW_FEATURES netvsc_supported_hw_features
#define VRSS_SEND_TAB_SIZE 16 /* must be power of 2 */ #define VRSS_CHANNEL_MAX 64 diff --git a/include/linux/netdev_features.h b/include/linux/netdev_features.h index 9d434b4e6e6e..a005c781fabf 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; @@ -112,6 +113,64 @@ 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_offload_features __ro_after_init; +extern netdev_features_t netdev_stag_vlan_offload_features __ro_after_init; +extern netdev_features_t netdev_vlan_offload_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_multi_tags_features_mask __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 netdev_features_t netdev_empty_features __ro_after_init; +extern netdev_features_t netvsc_supported_hw_features __ro_after_init; +extern const struct netdev_feature_set netif_f_never_change_feature_set; +extern const struct netdev_feature_set netif_f_gso_feature_set_mask; +extern const struct netdev_feature_set netif_f_ip_csum_feature_set; +extern const struct netdev_feature_set netif_f_csum_feature_set_mask; +extern const struct netdev_feature_set netif_f_general_tso_feature_set; +extern const struct netdev_feature_set netif_f_all_tso_feature_set; +extern const struct netdev_feature_set netif_f_tso_ecn_feature_set; +extern const struct netdev_feature_set netif_f_all_fcoe_feature_set; +extern const struct netdev_feature_set netif_f_gso_soft_feature_set; +extern const struct netdev_feature_set netif_f_one_for_all_feature_set; +extern const struct netdev_feature_set netif_f_all_for_all_feature_set; +extern const struct netdev_feature_set netif_f_upper_disables_feature_set; +extern const struct netdev_feature_set netif_f_soft_feature_set; +extern const struct netdev_feature_set netif_f_soft_off_feature_set; +extern const struct netdev_feature_set netif_f_tx_vlan_feature_set; +extern const struct netdev_feature_set netif_f_rx_vlan_feature_set; +extern const struct netdev_feature_set netif_f_vlan_filter_feature_set; +extern const struct netdev_feature_set netif_f_ctag_vlan_feature_set; +extern const struct netdev_feature_set netif_f_stag_vlan_feature_set; +extern const struct netdev_feature_set netif_f_ctag_vlan_offload_feature_set; +extern const struct netdev_feature_set netif_f_stag_vlan_offload_feature_set; +extern const struct netdev_feature_set netif_f_multi_tags_feature_set_mask; +extern const struct netdev_feature_set netif_f_gso_encap_feature_set; +extern const struct netdev_feature_set netif_f_xfrm_feature_set; +extern const struct netdev_feature_set netif_f_tls_feature_set; +extern const struct netdev_feature_set netvsc_supported_hw_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)
@@ -203,73 +262,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 e8ce3bd283a6..360a101584c8 100644 --- a/net/core/Makefile +++ b/net/core/Makefile @@ -12,7 +12,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 45e80c84497f..f7d6dfefa8a4 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> @@ -11362,6 +11363,86 @@ static struct pernet_operations __net_initdata default_device_ops = { .exit_batch = default_device_exit_batch, };
+static void __init netdev_features_init(void) +{
- netdev_features_t features;
- 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_gso_feature_set_mask,
&netdev_gso_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_gso_encap_feature_set,
&netdev_gso_encap_all_features);
- netdev_csum_gso_features_mask =
netdev_features_or(netdev_gso_software_features,
netdev_csum_features_mask);
- 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_features_or(netdev_rx_vlan_features,
netdev_tx_vlan_features);
- netdev_features_set_array(&netif_f_ctag_vlan_offload_feature_set,
&netdev_ctag_vlan_offload_features);
- netdev_features_set_array(&netif_f_stag_vlan_offload_feature_set,
&netdev_stag_vlan_offload_features);
- netdev_vlan_offload_features =
netdev_features_or(netdev_ctag_vlan_offload_features,
netdev_stag_vlan_offload_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_multi_tags_feature_set_mask,
&netdev_multi_tags_features_mask);
- 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_features_set_array(&netif_f_never_change_feature_set,
&netdev_never_change_features);
- netdev_features_fill(&features);
- netdev_ethtool_features =
netdev_features_andnot(features, netdev_never_change_features);
- netdev_features_zero(&netdev_empty_features);
- netdev_features_set_array(&netvsc_supported_hw_feature_set,
&netvsc_supported_hw_features);
+}
- /*
- Initialize the DEV module. At boot time this walks the device list and
- unhooks any devices that fail to initialise (normally hardware not
@@ -11392,6 +11473,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..158c750ea7a2 --- /dev/null +++ b/net/core/netdev_features.c @@ -0,0 +1,281 @@ +// SPDX-License-Identifier: GPL-2.0 +/*
- Network device features.
- */
+#include <linux/netdev_features.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_offload_features __ro_after_init; +EXPORT_SYMBOL_GPL(netdev_ctag_vlan_offload_features);
+netdev_features_t netdev_stag_vlan_offload_features __ro_after_init; +EXPORT_SYMBOL_GPL(netdev_stag_vlan_offload_features);
+netdev_features_t netdev_vlan_offload_features __ro_after_init; +EXPORT_SYMBOL_GPL(netdev_vlan_offload_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_multi_tags_features_mask __ro_after_init; +EXPORT_SYMBOL_GPL(netdev_multi_tags_features_mask);
+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);
+netdev_features_t netdev_empty_features __ro_after_init; +EXPORT_SYMBOL_GPL(netdev_empty_features);
+netdev_features_t netvsc_supported_hw_features __ro_after_init; +EXPORT_SYMBOL_GPL(netvsc_supported_hw_features);
+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_BIT);
+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_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_offload_feature_set,
NETIF_F_HW_VLAN_CTAG_TX_BIT,
NETIF_F_HW_VLAN_CTAG_RX_BIT);
+EXPORT_SYMBOL_GPL(netif_f_ctag_vlan_offload_feature_set);
+DECLARE_NETDEV_FEATURE_SET(netif_f_stag_vlan_offload_feature_set,
NETIF_F_HW_VLAN_STAG_TX_BIT,
NETIF_F_HW_VLAN_STAG_RX_BIT);
+EXPORT_SYMBOL_GPL(netif_f_stag_vlan_offload_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,
NETIF_F_HW_VLAN_CTAG_FILTER_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,
NETIF_F_HW_VLAN_STAG_FILTER_BIT);
+EXPORT_SYMBOL_GPL(netif_f_stag_vlan_feature_set);
+DECLARE_NETDEV_FEATURE_SET(netif_f_multi_tags_feature_set_mask,
NETIF_F_SG_BIT,
NETIF_F_HIGHDMA_BIT,
NETIF_F_HW_CSUM_BIT,
NETIF_F_FRAGLIST_BIT,
NETIF_F_HW_VLAN_CTAG_TX_BIT,
NETIF_F_HW_VLAN_STAG_TX_BIT);
+EXPORT_SYMBOL_GPL(netif_f_multi_tags_feature_set_mask);
+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);
+DECLARE_NETDEV_FEATURE_SET(netvsc_supported_hw_feature_set,
NETIF_F_RXCSUM_BIT,
NETIF_F_IP_CSUM_BIT,
NETIF_F_TSO_BIT,
NETIF_F_IPV6_CSUM_BIT,
NETIF_F_TSO6_BIT,
NETIF_F_LRO_BIT,
NETIF_F_SG_BIT,
NETIF_F_RXHASH_BIT);
+EXPORT_SYMBOL_GPL(netvsc_supported_hw_feature_set);
On 2022/7/30 18:17, Jian Shen wrote:
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/hyperv/hyperv_net.h | 5 +- include/linux/netdev_features.h | 111 +++++++++---- net/core/Makefile | 2 +- net/core/dev.c | 83 ++++++++++ net/core/netdev_features.c | 281 ++++++++++++++++++++++++++++++++ 5 files changed, 441 insertions(+), 41 deletions(-) create mode 100644 net/core/netdev_features.c
diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h index 25b38a374e3c..6336ed81fb8c 100644 --- a/drivers/net/hyperv/hyperv_net.h +++ b/drivers/net/hyperv/hyperv_net.h @@ -873,10 +873,7 @@ struct nvsp_message { #define NETVSC_RECEIVE_BUFFER_ID 0xcafe #define NETVSC_SEND_BUFFER_ID 0
-#define NETVSC_SUPPORTED_HW_FEATURES (NETIF_F_RXCSUM | NETIF_F_IP_CSUM | \
NETIF_F_TSO | NETIF_F_IPV6_CSUM | \
NETIF_F_TSO6 | NETIF_F_LRO | \
NETIF_F_SG | NETIF_F_RXHASH)
+#define NETVSC_SUPPORTED_HW_FEATURES netvsc_supported_hw_features
#define VRSS_SEND_TAB_SIZE 16 /* must be power of 2 */ #define VRSS_CHANNEL_MAX 64 diff --git a/include/linux/netdev_features.h b/include/linux/netdev_features.h index 9d434b4e6e6e..a005c781fabf 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; @@ -112,6 +113,64 @@ 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_offload_features __ro_after_init; +extern netdev_features_t netdev_stag_vlan_offload_features __ro_after_init; +extern netdev_features_t netdev_vlan_offload_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_multi_tags_features_mask __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 netdev_features_t netdev_empty_features __ro_after_init; +extern netdev_features_t netvsc_supported_hw_features __ro_after_init; +extern const struct netdev_feature_set netif_f_never_change_feature_set; +extern const struct netdev_feature_set netif_f_gso_feature_set_mask; +extern const struct netdev_feature_set netif_f_ip_csum_feature_set; +extern const struct netdev_feature_set netif_f_csum_feature_set_mask; +extern const struct netdev_feature_set netif_f_general_tso_feature_set; +extern const struct netdev_feature_set netif_f_all_tso_feature_set; +extern const struct netdev_feature_set netif_f_tso_ecn_feature_set; +extern const struct netdev_feature_set netif_f_all_fcoe_feature_set; +extern const struct netdev_feature_set netif_f_gso_soft_feature_set; +extern const struct netdev_feature_set netif_f_one_for_all_feature_set; +extern const struct netdev_feature_set netif_f_all_for_all_feature_set; +extern const struct netdev_feature_set netif_f_upper_disables_feature_set; +extern const struct netdev_feature_set netif_f_soft_feature_set; +extern const struct netdev_feature_set netif_f_soft_off_feature_set; +extern const struct netdev_feature_set netif_f_tx_vlan_feature_set; +extern const struct netdev_feature_set netif_f_rx_vlan_feature_set; +extern const struct netdev_feature_set netif_f_vlan_filter_feature_set; +extern const struct netdev_feature_set netif_f_ctag_vlan_feature_set; +extern const struct netdev_feature_set netif_f_stag_vlan_feature_set; +extern const struct netdev_feature_set netif_f_ctag_vlan_offload_feature_set; +extern const struct netdev_feature_set netif_f_stag_vlan_offload_feature_set; +extern const struct netdev_feature_set netif_f_multi_tags_feature_set_mask; +extern const struct netdev_feature_set netif_f_gso_encap_feature_set; +extern const struct netdev_feature_set netif_f_xfrm_feature_set; +extern const struct netdev_feature_set netif_f_tls_feature_set; +extern const struct netdev_feature_set netvsc_supported_hw_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) @@ -203,73 +262,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 e8ce3bd283a6..360a101584c8 100644 --- a/net/core/Makefile +++ b/net/core/Makefile @@ -12,7 +12,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 45e80c84497f..f7d6dfefa8a4 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>
The net/core/dev.c file of patch 1 have included linux/netdev_features_helper.h.
#include <linux/indirect_call_wrapper.h> #include <net/devlink.h> #include <linux/pm_runtime.h> @@ -11362,6 +11363,86 @@ static struct pernet_operations __net_initdata default_device_ops = { .exit_batch = default_device_exit_batch, };
+static void __init netdev_features_init(void) +{
- netdev_features_t features;
- 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_gso_feature_set_mask,
&netdev_gso_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_gso_encap_feature_set,
&netdev_gso_encap_all_features);
- netdev_csum_gso_features_mask =
netdev_features_or(netdev_gso_software_features,
netdev_csum_features_mask);
- 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_features_or(netdev_rx_vlan_features,
netdev_tx_vlan_features);
- netdev_features_set_array(&netif_f_ctag_vlan_offload_feature_set,
&netdev_ctag_vlan_offload_features);
- netdev_features_set_array(&netif_f_stag_vlan_offload_feature_set,
&netdev_stag_vlan_offload_features);
- netdev_vlan_offload_features =
netdev_features_or(netdev_ctag_vlan_offload_features,
netdev_stag_vlan_offload_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_multi_tags_feature_set_mask,
&netdev_multi_tags_features_mask);
- 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_features_set_array(&netif_f_never_change_feature_set,
&netdev_never_change_features);
- netdev_features_fill(&features);
- netdev_ethtool_features =
netdev_features_andnot(features, netdev_never_change_features);
- netdev_features_zero(&netdev_empty_features);
- netdev_features_set_array(&netvsc_supported_hw_feature_set,
&netvsc_supported_hw_features);
+}
/*
- Initialize the DEV module. At boot time this walks the device list and
- unhooks any devices that fail to initialise (normally hardware not
@@ -11392,6 +11473,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..158c750ea7a2 --- /dev/null +++ b/net/core/netdev_features.c @@ -0,0 +1,281 @@ +// SPDX-License-Identifier: GPL-2.0 +/*
- Network device features.
- */
+#include <linux/netdev_features.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_offload_features __ro_after_init; +EXPORT_SYMBOL_GPL(netdev_ctag_vlan_offload_features);
+netdev_features_t netdev_stag_vlan_offload_features __ro_after_init; +EXPORT_SYMBOL_GPL(netdev_stag_vlan_offload_features);
+netdev_features_t netdev_vlan_offload_features __ro_after_init; +EXPORT_SYMBOL_GPL(netdev_vlan_offload_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_multi_tags_features_mask __ro_after_init; +EXPORT_SYMBOL_GPL(netdev_multi_tags_features_mask);
+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);
+netdev_features_t netdev_empty_features __ro_after_init; +EXPORT_SYMBOL_GPL(netdev_empty_features);
+netdev_features_t netvsc_supported_hw_features __ro_after_init; +EXPORT_SYMBOL_GPL(netvsc_supported_hw_features);
+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_BIT);
+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_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_offload_feature_set,
NETIF_F_HW_VLAN_CTAG_TX_BIT,
NETIF_F_HW_VLAN_CTAG_RX_BIT);
+EXPORT_SYMBOL_GPL(netif_f_ctag_vlan_offload_feature_set);
+DECLARE_NETDEV_FEATURE_SET(netif_f_stag_vlan_offload_feature_set,
NETIF_F_HW_VLAN_STAG_TX_BIT,
NETIF_F_HW_VLAN_STAG_RX_BIT);
+EXPORT_SYMBOL_GPL(netif_f_stag_vlan_offload_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,
NETIF_F_HW_VLAN_CTAG_FILTER_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,
NETIF_F_HW_VLAN_STAG_FILTER_BIT);
+EXPORT_SYMBOL_GPL(netif_f_stag_vlan_feature_set);
+DECLARE_NETDEV_FEATURE_SET(netif_f_multi_tags_feature_set_mask,
NETIF_F_SG_BIT,
NETIF_F_HIGHDMA_BIT,
NETIF_F_HW_CSUM_BIT,
NETIF_F_FRAGLIST_BIT,
NETIF_F_HW_VLAN_CTAG_TX_BIT,
NETIF_F_HW_VLAN_STAG_TX_BIT);
+EXPORT_SYMBOL_GPL(netif_f_multi_tags_feature_set_mask);
+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);
+DECLARE_NETDEV_FEATURE_SET(netvsc_supported_hw_feature_set,
NETIF_F_RXCSUM_BIT,
NETIF_F_IP_CSUM_BIT,
NETIF_F_TSO_BIT,
NETIF_F_IPV6_CSUM_BIT,
NETIF_F_TSO6_BIT,
NETIF_F_LRO_BIT,
NETIF_F_SG_BIT,
NETIF_F_RXHASH_BIT);
+EXPORT_SYMBOL_GPL(netvsc_supported_hw_feature_set);
+static void __init netdev_features_init(void) +{
- netdev_features_t features;
- 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_gso_feature_set_mask,
&netdev_gso_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_gso_encap_feature_set,
&netdev_gso_encap_all_features);
- netdev_csum_gso_features_mask =
netdev_features_or(netdev_gso_software_features,
netdev_csum_features_mask);
According to patch 10, I think here should be netdev_csum_gso_features_mask = netdev_features_or(netdev_gso_features_mask, netdev_csum_features_mask);
在 2022/8/4 22:09, huangguangbin (A) 写道:
+static void __init netdev_features_init(void) +{ + netdev_features_t features;
+ 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_gso_feature_set_mask,
+ &netdev_gso_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_gso_encap_feature_set,
+ &netdev_gso_encap_all_features);
+ netdev_csum_gso_features_mask = + netdev_features_or(netdev_gso_software_features, + netdev_csum_features_mask);
According to patch 10, I think here should be netdev_csum_gso_features_mask = netdev_features_or(netdev_gso_features_mask, netdev_csum_features_mask);
yes, will fixes it, thanks
.
There are many netdev_features bits group used in drivers, replace them with DECLARE_NETDEV_FEATURE_SET, prepare to remove all the NETIF_F_XXX macroes.
Signed-off-by: Jian Shen shenjian15@huawei.com --- arch/um/drivers/vector_transports.c | 49 +++++-- drivers/infiniband/ulp/ipoib/ipoib.h | 1 + drivers/infiniband/ulp/ipoib/ipoib_main.c | 8 +- drivers/net/amt.c | 16 ++- drivers/net/bareudp.c | 21 ++- drivers/net/bonding/bond_main.c | 48 +++++-- drivers/net/dsa/xrs700x/xrs700x.c | 15 +- drivers/net/dummy.c | 11 +- drivers/net/ethernet/3com/typhoon.c | 18 ++- drivers/net/ethernet/aeroflex/greth.c | 9 +- drivers/net/ethernet/alteon/acenic.c | 10 +- drivers/net/ethernet/amazon/ena/ena_netdev.c | 13 +- drivers/net/ethernet/amd/xgbe/xgbe-main.c | 59 ++++---- .../net/ethernet/apm/xgene/xgene_enet_main.c | 12 +- .../net/ethernet/aquantia/atlantic/aq_nic.c | 14 +- drivers/net/ethernet/asix/ax88796c_main.c | 21 ++- drivers/net/ethernet/atheros/alx/main.c | 15 +- drivers/net/ethernet/atheros/atl1c/atl1c.h | 1 + .../net/ethernet/atheros/atl1c/atl1c_main.c | 14 +- drivers/net/ethernet/atheros/atl1e/atl1e.h | 1 + .../net/ethernet/atheros/atl1e/atl1e_main.c | 10 +- drivers/net/ethernet/atheros/atlx/atl1.c | 22 ++- drivers/net/ethernet/broadcom/bcmsysport.c | 24 +++- drivers/net/ethernet/broadcom/bgmac.c | 9 +- drivers/net/ethernet/broadcom/bnx2.c | 14 +- .../net/ethernet/broadcom/bnx2x/bnx2x_main.c | 83 ++++++++--- drivers/net/ethernet/broadcom/bnxt/bnxt.c | 54 +++++-- .../net/ethernet/broadcom/genet/bcmgenet.c | 10 +- drivers/net/ethernet/brocade/bna/bnad.c | 39 +++-- drivers/net/ethernet/calxeda/xgmac.c | 15 +- .../net/ethernet/cavium/liquidio/lio_main.c | 42 ++++-- .../ethernet/cavium/liquidio/lio_vf_main.c | 40 ++++-- .../ethernet/cavium/liquidio/octeon_network.h | 4 +- .../net/ethernet/cavium/thunder/nicvf_main.c | 27 +++- drivers/net/ethernet/chelsio/cxgb/cxgb2.c | 19 ++- .../net/ethernet/chelsio/cxgb3/cxgb3_main.c | 29 +++- .../net/ethernet/chelsio/cxgb4/cxgb4_main.c | 68 ++++++--- .../ethernet/chelsio/cxgb4vf/cxgb4vf_main.c | 39 ++++- drivers/net/ethernet/cirrus/ep93xx_eth.c | 7 +- drivers/net/ethernet/cisco/enic/enic_main.c | 19 ++- drivers/net/ethernet/cortina/gemini.c | 22 ++- drivers/net/ethernet/emulex/benet/be_main.c | 47 ++++-- drivers/net/ethernet/faraday/ftgmac100.c | 13 +- .../net/ethernet/freescale/dpaa/dpaa_eth.c | 14 +- .../net/ethernet/freescale/dpaa2/dpaa2-eth.c | 17 ++- .../ethernet/freescale/dpaa2/dpaa2-switch.c | 10 +- .../ethernet/freescale/dpaa2/dpaa2-switch.h | 1 + .../net/ethernet/freescale/enetc/enetc_pf.c | 42 ++++-- .../net/ethernet/freescale/enetc/enetc_vf.c | 40 ++++-- drivers/net/ethernet/freescale/fec_main.c | 11 +- drivers/net/ethernet/freescale/gianfar.c | 18 ++- .../ethernet/fungible/funeth/funeth_main.c | 48 +++++-- drivers/net/ethernet/google/gve/gve_main.c | 21 +-- drivers/net/ethernet/hisilicon/hns/hns_enet.c | 51 +++++-- .../net/ethernet/hisilicon/hns3/hns3_enet.c | 40 ++++-- .../net/ethernet/huawei/hinic/hinic_main.c | 37 +++-- drivers/net/ethernet/ibm/ehea/ehea_main.c | 34 +++-- drivers/net/ethernet/ibm/emac/core.c | 7 +- drivers/net/ethernet/ibm/ibmveth.c | 11 +- drivers/net/ethernet/ibm/ibmvnic.c | 8 +- drivers/net/ethernet/intel/e1000/e1000.h | 1 + drivers/net/ethernet/intel/e1000/e1000_main.c | 33 +++-- drivers/net/ethernet/intel/e1000e/netdev.c | 46 ++++-- .../net/ethernet/intel/fm10k/fm10k_netdev.c | 37 +++-- drivers/net/ethernet/intel/i40e/i40e_main.c | 75 +++++----- drivers/net/ethernet/intel/iavf/iavf.h | 1 + drivers/net/ethernet/intel/iavf/iavf_main.c | 43 +++--- drivers/net/ethernet/intel/ice/ice.h | 1 + drivers/net/ethernet/intel/ice/ice_main.c | 64 ++++++--- drivers/net/ethernet/intel/igb/igb_main.c | 74 ++++++---- drivers/net/ethernet/intel/igbvf/netdev.c | 76 ++++++---- drivers/net/ethernet/intel/igc/igc_mac.c | 1 + drivers/net/ethernet/intel/igc/igc_main.c | 77 ++++++---- drivers/net/ethernet/intel/ixgb/ixgb_main.c | 15 +- drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 134 +++++++++++------- drivers/net/ethernet/intel/ixgbevf/ipsec.c | 15 +- drivers/net/ethernet/intel/ixgbevf/ixgbevf.h | 1 + .../net/ethernet/intel/ixgbevf/ixgbevf_main.c | 87 +++++++----- drivers/net/ethernet/jme.c | 34 +++-- drivers/net/ethernet/marvell/mv643xx_eth.c | 9 +- drivers/net/ethernet/marvell/mvneta.c | 12 +- .../net/ethernet/marvell/mvpp2/mvpp2_main.c | 19 ++- .../ethernet/marvell/octeontx2/nic/otx2_pf.c | 17 ++- .../ethernet/marvell/octeontx2/nic/otx2_vf.c | 17 ++- drivers/net/ethernet/marvell/skge.c | 9 +- drivers/net/ethernet/marvell/sky2.c | 19 ++- drivers/net/ethernet/mellanox/mlx4/en_main.c | 1 + .../net/ethernet/mellanox/mlx4/en_netdev.c | 75 ++++++---- .../ethernet/mellanox/mlx5/core/ipoib/ipoib.c | 20 +-- .../net/ethernet/mellanox/mlxsw/spectrum.c | 16 ++- drivers/net/ethernet/micrel/ksz884x.c | 9 +- drivers/net/ethernet/microchip/lan743x_main.c | 9 +- drivers/net/ethernet/microsoft/mana/mana_en.c | 15 +- drivers/net/ethernet/mscc/ocelot_net.c | 14 +- .../net/ethernet/myricom/myri10ge/myri10ge.c | 11 +- drivers/net/ethernet/neterion/s2io.c | 24 +++- drivers/net/ethernet/nvidia/forcedeth.c | 10 +- .../ethernet/oki-semi/pch_gbe/pch_gbe_main.c | 10 +- drivers/net/ethernet/pasemi/pasemi_mac.c | 11 +- .../net/ethernet/pensando/ionic/ionic_lif.c | 23 +-- .../ethernet/qlogic/netxen/netxen_nic_main.c | 11 +- drivers/net/ethernet/qlogic/qede/qede_main.c | 50 +++++-- .../net/ethernet/qlogic/qlcnic/qlcnic_hw.c | 29 ++-- .../net/ethernet/qlogic/qlcnic/qlcnic_main.c | 34 +++-- drivers/net/ethernet/qualcomm/emac/emac.c | 23 ++- .../net/ethernet/qualcomm/rmnet/rmnet_vnd.c | 12 +- drivers/net/ethernet/realtek/8139cp.c | 23 ++- drivers/net/ethernet/realtek/8139too.c | 8 +- drivers/net/ethernet/realtek/r8169_main.c | 18 ++- .../net/ethernet/samsung/sxgbe/sxgbe_main.c | 15 +- drivers/net/ethernet/sfc/ef10.c | 11 +- drivers/net/ethernet/sfc/ef100_netdev.c | 9 +- drivers/net/ethernet/sfc/ef100_nic.c | 15 +- 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 + drivers/net/ethernet/sfc/siena/efx.c | 22 ++- drivers/net/ethernet/sgi/ioc3-eth.c | 13 +- drivers/net/ethernet/silan/sc92031.c | 11 +- drivers/net/ethernet/socionext/netsec.c | 11 +- .../net/ethernet/stmicro/stmmac/stmmac_main.c | 11 +- drivers/net/ethernet/sun/ldmvsw.c | 7 +- drivers/net/ethernet/sun/niu.c | 9 +- drivers/net/ethernet/sun/sungem.c | 9 +- drivers/net/ethernet/sun/sunvnet.c | 10 +- drivers/net/ethernet/tehuti/tehuti.c | 25 +++- drivers/net/ethernet/tehuti/tehuti.h | 1 + drivers/net/ethernet/ti/am65-cpsw-nuss.c | 13 +- drivers/net/ethernet/ti/cpsw_new.c | 11 +- drivers/net/ethernet/via/via-velocity.c | 19 ++- drivers/net/geneve.c | 20 ++- drivers/net/hyperv/netvsc_drv.c | 11 +- drivers/net/ifb.c | 20 ++- drivers/net/ipvlan/ipvlan_main.c | 58 ++++++-- drivers/net/ipvlan/ipvtap.c | 12 +- drivers/net/loopback.c | 25 ++-- drivers/net/macsec.c | 22 ++- drivers/net/macvlan.c | 56 ++++++-- drivers/net/macvtap.c | 12 +- drivers/net/net_failover.c | 13 ++ drivers/net/netdevsim/ipsec.c | 13 +- drivers/net/netdevsim/netdev.c | 14 +- drivers/net/netdevsim/netdevsim.h | 1 + drivers/net/nlmon.c | 11 +- drivers/net/tap.c | 18 ++- drivers/net/team/team.c | 31 +++- drivers/net/thunderbolt.c | 11 +- drivers/net/tun.c | 28 +++- drivers/net/usb/aqc111.c | 38 ++++- drivers/net/usb/aqc111.h | 14 -- drivers/net/usb/ax88179_178a.c | 11 +- drivers/net/usb/lan78xx.c | 8 +- drivers/net/usb/r8152.c | 53 +++++-- drivers/net/usb/smsc75xx.c | 10 +- drivers/net/veth.c | 27 ++-- drivers/net/vmxnet3/vmxnet3_drv.c | 36 +++-- drivers/net/vmxnet3/vmxnet3_ethtool.c | 35 +++-- drivers/net/vmxnet3/vmxnet3_int.h | 1 + drivers/net/vrf.c | 12 +- drivers/net/vsockmon.c | 11 +- drivers/net/vxlan/vxlan_core.c | 20 ++- drivers/net/wireguard/device.c | 20 ++- drivers/net/wireless/ath/wil6210/netdev.c | 14 +- drivers/net/xen-netback/interface.c | 14 +- drivers/net/xen-netfront.c | 20 ++- drivers/s390/net/qeth_l3_main.c | 13 +- drivers/staging/qlge/qlge_main.c | 21 +-- include/net/bonding.h | 5 +- include/net/net_failover.h | 8 +- net/8021q/vlan_dev.c | 15 +- net/batman-adv/soft-interface.c | 9 +- net/bridge/br_device.c | 25 +++- net/ethtool/ioctl.c | 17 ++- net/hsr/hsr_device.c | 13 +- net/ipv4/ip_gre.c | 19 +-- net/ipv4/ipip.c | 19 ++- net/ipv6/ip6_gre.c | 15 +- net/ipv6/ip6_tunnel.c | 19 ++- net/ipv6/sit.c | 18 ++- net/mac80211/ieee80211_i.h | 13 +- net/mac80211/main.c | 24 ++++ net/openvswitch/vport-internal_dev.c | 13 +- net/xfrm/xfrm_interface.c | 16 ++- 184 files changed, 2913 insertions(+), 1139 deletions(-)
diff --git a/arch/um/drivers/vector_transports.c b/arch/um/drivers/vector_transports.c index 0794d23f07cb..bf43b554e5f2 100644 --- a/arch/um/drivers/vector_transports.c +++ b/arch/um/drivers/vector_transports.c @@ -397,6 +397,35 @@ static int build_l2tpv3_transport_data(struct vector_private *vp) return 0; }
+static DECLARE_NETDEV_FEATURE_SET(raw_hw_feature_set, + NETIF_F_TSO_BIT, + NETIF_F_GRO_BIT); +static DECLARE_NETDEV_FEATURE_SET(raw_feature_set, + NETIF_F_RXCSUM_BIT, + NETIF_F_HW_CSUM_BIT, + NETIF_F_TSO_BIT, + NETIF_F_GRO_BIT); +static DECLARE_NETDEV_FEATURE_SET(hybrid_hw_feature_set, + NETIF_F_TSO_BIT, + NETIF_F_GSO_BIT, + NETIF_F_GRO_BIT); +static DECLARE_NETDEV_FEATURE_SET(hybrid_feature_set, + NETIF_F_RXCSUM_BIT, + NETIF_F_HW_CSUM_BIT, + NETIF_F_TSO_BIT, + NETIF_F_GSO_BIT, + NETIF_F_GRO_BIT); +static DECLARE_NETDEV_FEATURE_SET(tap_hw_feature_set, + NETIF_F_TSO_BIT, + NETIF_F_GSO_BIT, + NETIF_F_GRO_BIT); +static DECLARE_NETDEV_FEATURE_SET(tap_feature_set, + NETIF_F_RXCSUM_BIT, + NETIF_F_HW_CSUM_BIT, + NETIF_F_TSO_BIT, + NETIF_F_GSO_BIT, + NETIF_F_GRO_BIT); + static int build_raw_transport_data(struct vector_private *vp) { if (uml_raw_enable_vnet_headers(vp->fds->rx_fd)) { @@ -406,10 +435,8 @@ static int build_raw_transport_data(struct vector_private *vp) vp->verify_header = &raw_verify_header; vp->header_size = sizeof(struct virtio_net_hdr); vp->rx_header_size = sizeof(struct virtio_net_hdr); - vp->dev->hw_features |= (NETIF_F_TSO | NETIF_F_GRO); - vp->dev->features |= - (NETIF_F_RXCSUM | NETIF_F_HW_CSUM | - NETIF_F_TSO | NETIF_F_GRO); + netdev_hw_features_set_array(vp->dev, &raw_hw_feature_set); + netdev_active_features_set_array(vp->dev, &raw_feature_set); netdev_info( vp->dev, "raw: using vnet headers for tso and tx/rx checksum" @@ -425,11 +452,8 @@ static int build_hybrid_transport_data(struct vector_private *vp) vp->verify_header = &raw_verify_header; vp->header_size = sizeof(struct virtio_net_hdr); vp->rx_header_size = sizeof(struct virtio_net_hdr); - vp->dev->hw_features |= - (NETIF_F_TSO | NETIF_F_GSO | NETIF_F_GRO); - vp->dev->features |= - (NETIF_F_RXCSUM | NETIF_F_HW_CSUM | - NETIF_F_TSO | NETIF_F_GSO | NETIF_F_GRO); + netdev_hw_features_set_array(vp->dev, &hybrid_hw_feature_set); + netdev_active_features_set_array(vp->dev, &hybrid_feature_set); netdev_info( vp->dev, "tap/raw hybrid: using vnet headers for tso and tx/rx checksum" @@ -450,11 +474,8 @@ static int build_tap_transport_data(struct vector_private *vp) vp->verify_header = &raw_verify_header; vp->header_size = sizeof(struct virtio_net_hdr); vp->rx_header_size = sizeof(struct virtio_net_hdr); - vp->dev->hw_features |= - (NETIF_F_TSO | NETIF_F_GSO | NETIF_F_GRO); - vp->dev->features |= - (NETIF_F_RXCSUM | NETIF_F_HW_CSUM | - NETIF_F_TSO | NETIF_F_GSO | NETIF_F_GRO); + netdev_hw_features_set_array(vp->dev, &tap_hw_feature_set); + netdev_active_features_set_array(vp->dev, &tap_feature_set); netdev_info( vp->dev, "tap: using vnet headers for tso and tx/rx checksum" diff --git a/drivers/infiniband/ulp/ipoib/ipoib.h b/drivers/infiniband/ulp/ipoib/ipoib.h index 35e9c8a330e2..8f0cbaa4afdc 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib.h +++ b/drivers/infiniband/ulp/ipoib/ipoib.h @@ -38,6 +38,7 @@ #include <linux/list.h> #include <linux/skbuff.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/workqueue.h> #include <linux/kref.h> #include <linux/if_infiniband.h> diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c index 2a8961b685c2..4d917762352f 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_main.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c @@ -2104,6 +2104,10 @@ static const struct net_device_ops ipoib_netdev_default_pf = { .ndo_stop = ipoib_ib_dev_stop_default, };
+static DECLARE_NETDEV_FEATURE_SET(ipoib_feature_set, + NETIF_F_VLAN_CHALLENGED_BIT, + NETIF_F_HIGHDMA_BIT); + void ipoib_setup_common(struct net_device *dev) { dev->header_ops = &ipoib_header_ops; @@ -2119,8 +2123,8 @@ void ipoib_setup_common(struct net_device *dev) dev->addr_len = INFINIBAND_ALEN; dev->type = ARPHRD_INFINIBAND; dev->tx_queue_len = ipoib_sendq_size * 2; - dev->features = (NETIF_F_VLAN_CHALLENGED | - NETIF_F_HIGHDMA); + netdev_active_features_zero(dev); + netdev_active_features_set_array(dev, &ipoib_feature_set); netif_keep_dst(dev);
memcpy(dev->broadcast, ipv4_bcast_addr, INFINIBAND_ALEN); diff --git a/drivers/net/amt.c b/drivers/net/amt.c index 9a247eb7679c..ec8d6d6fda9c 100644 --- a/drivers/net/amt.c +++ b/drivers/net/amt.c @@ -9,6 +9,7 @@ #include <linux/jhash.h> #include <linux/if_tunnel.h> #include <linux/net.h> +#include <linux/netdev_features_helper.h> #include <linux/igmp.h> #include <linux/workqueue.h> #include <net/sch_generic.h> @@ -3095,6 +3096,15 @@ static const struct net_device_ops amt_netdev_ops = { .ndo_get_stats64 = dev_get_tstats64, };
+static DECLARE_NETDEV_FEATURE_SET(amt_feature_set, + NETIF_F_LLTX_BIT, + NETIF_F_NETNS_LOCAL_BIT); +static DECLARE_NETDEV_FEATURE_SET(amt_hw_feature_set, + NETIF_F_SG_BIT, + NETIF_F_HW_CSUM_BIT, + NETIF_F_FRAGLIST_BIT, + NETIF_F_RXCSUM_BIT); + static void amt_link_setup(struct net_device *dev) { dev->netdev_ops = &amt_netdev_ops; @@ -3107,12 +3117,10 @@ static void amt_link_setup(struct net_device *dev) dev->hard_header_len = 0; dev->addr_len = 0; dev->priv_flags |= IFF_NO_QUEUE; - dev->features |= NETIF_F_LLTX; dev->features |= NETIF_F_GSO_SOFTWARE; - dev->features |= NETIF_F_NETNS_LOCAL; - dev->hw_features |= NETIF_F_SG | NETIF_F_HW_CSUM; - dev->hw_features |= NETIF_F_FRAGLIST | NETIF_F_RXCSUM; + netdev_active_features_set_array(dev, &amt_feature_set); dev->hw_features |= NETIF_F_GSO_SOFTWARE; + netdev_active_features_set_array(dev, &amt_hw_feature_set); eth_hw_addr_random(dev); eth_zero_addr(dev->broadcast); ether_setup(dev); diff --git a/drivers/net/bareudp.c b/drivers/net/bareudp.c index 683203f87ae2..08b11ed436ad 100644 --- a/drivers/net/bareudp.c +++ b/drivers/net/bareudp.c @@ -11,6 +11,7 @@ #include <linux/module.h> #include <linux/etherdevice.h> #include <linux/hash.h> +#include <linux/netdev_features_helper.h> #include <net/dst_metadata.h> #include <net/gro_cells.h> #include <net/rtnetlink.h> @@ -536,18 +537,28 @@ static const struct device_type bareudp_type = { .name = "bareudp", };
+static DECLARE_NETDEV_FEATURE_SET(bareudp_feature_set, + NETIF_F_SG_BIT, + NETIF_F_HW_CSUM_BIT, + NETIF_F_FRAGLIST_BIT, + NETIF_F_RXCSUM_BIT, + NETIF_F_LLTX_BIT); + +static DECLARE_NETDEV_FEATURE_SET(bareudp_hw_feature_set, + NETIF_F_SG_BIT, + NETIF_F_HW_CSUM_BIT, + NETIF_F_FRAGLIST_BIT, + NETIF_F_RXCSUM_BIT); + /* Initialize the device structure. */ static void bareudp_setup(struct net_device *dev) { dev->netdev_ops = &bareudp_netdev_ops; dev->needs_free_netdev = true; SET_NETDEV_DEVTYPE(dev, &bareudp_type); - dev->features |= NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_FRAGLIST; - dev->features |= NETIF_F_RXCSUM; - dev->features |= NETIF_F_LLTX; + netdev_active_features_set_array(dev, &bareudp_feature_set); dev->features |= NETIF_F_GSO_SOFTWARE; - dev->hw_features |= NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_FRAGLIST; - dev->hw_features |= NETIF_F_RXCSUM; + netdev_hw_features_set_array(dev, &bareudp_hw_feature_set); dev->hw_features |= NETIF_F_GSO_SOFTWARE; dev->hard_header_len = 0; dev->addr_len = 0; diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index e75acb14d066..a7783abec601 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -59,6 +59,7 @@ #include <linux/uaccess.h> #include <linux/errno.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/inetdevice.h> #include <linux/igmp.h> #include <linux/etherdevice.h> @@ -254,6 +255,25 @@ static const struct flow_dissector_key flow_keys_bonding_keys[] = {
static struct flow_dissector flow_keys_bonding __read_mostly;
+static DECLARE_NETDEV_FEATURE_SET(bond_vlan_feature_set, + NETIF_F_HW_CSUM_BIT, + NETIF_F_SG_BIT, + NETIF_F_FRAGLIST_BIT, + NETIF_F_HIGHDMA_BIT, + NETIF_F_LRO_BIT); + +static DECLARE_NETDEV_FEATURE_SET(bond_enc_feature_set, + NETIF_F_HW_CSUM_BIT, + NETIF_F_SG_BIT, + NETIF_F_RXCSUM_BIT); + +static DECLARE_NETDEV_FEATURE_SET(bond_mpls_feature_set, + NETIF_F_HW_CSUM_BIT, + NETIF_F_SG_BIT); + +static netdev_features_t bond_vlan_features __ro_after_init; +static netdev_features_t bond_enc_features __ro_after_init; +static netdev_features_t bond_mpls_features __ro_after_init; /*-------------------------- Forward declarations ---------------------------*/
static int bond_init(struct net_device *bond_dev); @@ -1421,16 +1441,11 @@ static netdev_features_t bond_fix_features(struct net_device *dev, return features; }
-#define BOND_VLAN_FEATURES (NETIF_F_HW_CSUM | NETIF_F_SG | \ - NETIF_F_FRAGLIST | NETIF_F_GSO_SOFTWARE | \ - NETIF_F_HIGHDMA | NETIF_F_LRO) +#define BOND_VLAN_FEATURES bond_vlan_features
-#define BOND_ENC_FEATURES (NETIF_F_HW_CSUM | NETIF_F_SG | \ - NETIF_F_RXCSUM | NETIF_F_GSO_SOFTWARE) - -#define BOND_MPLS_FEATURES (NETIF_F_HW_CSUM | NETIF_F_SG | \ - NETIF_F_GSO_SOFTWARE) +#define BOND_ENC_FEATURES bond_enc_features
+#define BOND_MPLS_FEATURES bond_mpls_features
static void bond_compute_features(struct bonding *bond) { @@ -6195,6 +6210,21 @@ static int bond_check_params(struct bond_params *params) return 0; }
+static void __init bond_netdev_features_init(void) +{ + bond_vlan_features = NETIF_F_GSO_SOFTWARE; + netdev_features_set_array(&bond_vlan_feature_set, + &bond_vlan_features); + + bond_enc_features = NETIF_F_GSO_SOFTWARE; + netdev_features_set_array(&bond_enc_feature_set, + &bond_enc_features); + + bond_mpls_features = NETIF_F_GSO_SOFTWARE; + netdev_features_set_array(&bond_mpls_feature_set, + &bond_mpls_features); +} + /* Called from registration process */ static int bond_init(struct net_device *bond_dev) { @@ -6355,6 +6385,8 @@ static int __init bonding_init(void) ARRAY_SIZE(flow_keys_bonding_keys));
register_netdevice_notifier(&bond_netdev_notifier); + + bond_netdev_features_init(); out: return res; err: diff --git a/drivers/net/dsa/xrs700x/xrs700x.c b/drivers/net/dsa/xrs700x/xrs700x.c index 3887ed33c5fe..c989138e7761 100644 --- a/drivers/net/dsa/xrs700x/xrs700x.c +++ b/drivers/net/dsa/xrs700x/xrs700x.c @@ -9,15 +9,18 @@ #include <linux/if_bridge.h> #include <linux/of_device.h> #include <linux/netdev_features.h> +#include <linux/netdev_features_helper.h> #include <linux/if_hsr.h> #include "xrs700x.h" #include "xrs700x_reg.h"
#define XRS700X_MIB_INTERVAL msecs_to_jiffies(3000)
-#define XRS7000X_SUPPORTED_HSR_FEATURES \ - (NETIF_F_HW_HSR_TAG_INS | NETIF_F_HW_HSR_TAG_RM | \ - NETIF_F_HW_HSR_FWD | NETIF_F_HW_HSR_DUP) +static DECLARE_NETDEV_FEATURE_SET(xrs7000x_hsr_feature_set, + NETIF_F_HW_HSR_TAG_INS_BIT, + NETIF_F_HW_HSR_TAG_RM_BIT, + NETIF_F_HW_HSR_FWD_BIT, + NETIF_F_HW_HSR_FWD_BIT);
#define XRS7003E_ID 0x100 #define XRS7003F_ID 0x101 @@ -632,7 +635,8 @@ static int xrs700x_hsr_join(struct dsa_switch *ds, int port, hsr_pair[1] = partner->index; for (i = 0; i < ARRAY_SIZE(hsr_pair); i++) { slave = dsa_to_port(ds, hsr_pair[i])->slave; - slave->features |= XRS7000X_SUPPORTED_HSR_FEATURES; + netdev_active_features_set_array(slave, + &xrs7000x_hsr_feature_set); }
return 0; @@ -686,7 +690,8 @@ static int xrs700x_hsr_leave(struct dsa_switch *ds, int port, hsr_pair[1] = partner->index; for (i = 0; i < ARRAY_SIZE(hsr_pair); i++) { slave = dsa_to_port(ds, hsr_pair[i])->slave; - slave->features &= ~XRS7000X_SUPPORTED_HSR_FEATURES; + netdev_active_features_clear_array(slave, + &xrs7000x_hsr_feature_set); }
return 0; diff --git a/drivers/net/dummy.c b/drivers/net/dummy.c index f82ad7419508..6f176774efbd 100644 --- a/drivers/net/dummy.c +++ b/drivers/net/dummy.c @@ -32,6 +32,7 @@ #include <linux/module.h> #include <linux/kernel.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/etherdevice.h> #include <linux/ethtool.h> #include <linux/init.h> @@ -110,6 +111,13 @@ static const struct ethtool_ops dummy_ethtool_ops = { .get_ts_info = ethtool_op_get_ts_info, };
+static DECLARE_NETDEV_FEATURE_SET(dummy_feature_set, + NETIF_F_SG_BIT, + NETIF_F_FRAGLIST_BIT, + NETIF_F_HW_CSUM_BIT, + NETIF_F_HIGHDMA_BIT, + NETIF_F_LLTX_BIT); + static void dummy_setup(struct net_device *dev) { ether_setup(dev); @@ -123,9 +131,8 @@ static void dummy_setup(struct net_device *dev) dev->flags |= IFF_NOARP; dev->flags &= ~IFF_MULTICAST; dev->priv_flags |= IFF_LIVE_ADDR_CHANGE | IFF_NO_QUEUE; - dev->features |= NETIF_F_SG | NETIF_F_FRAGLIST; + netdev_active_features_set_array(dev, &dummy_feature_set); dev->features |= NETIF_F_GSO_SOFTWARE; - dev->features |= NETIF_F_HW_CSUM | NETIF_F_HIGHDMA | NETIF_F_LLTX; dev->features |= NETIF_F_GSO_ENCAP_ALL; dev->hw_features |= dev->features; dev->hw_enc_features |= dev->features; diff --git a/drivers/net/ethernet/3com/typhoon.c b/drivers/net/ethernet/3com/typhoon.c index cad4f354cc76..cb7a4bb5cf74 100644 --- a/drivers/net/ethernet/3com/typhoon.c +++ b/drivers/net/ethernet/3com/typhoon.c @@ -108,6 +108,7 @@ static const int multicast_filter_limit = 32; #include <linux/interrupt.h> #include <linux/pci.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/etherdevice.h> #include <linux/skbuff.h> #include <linux/mm.h> @@ -2286,6 +2287,15 @@ static const struct net_device_ops typhoon_netdev_ops = { .ndo_set_mac_address = eth_mac_addr, };
+static DECLARE_NETDEV_FEATURE_SET(typhoon_hw_feature_set, + NETIF_F_SG_BIT, + NETIF_F_IP_CSUM_BIT, + NETIF_F_TSO_BIT, + NETIF_F_HW_VLAN_CTAG_TX_BIT); +static DECLARE_NETDEV_FEATURE_SET(typhoon_feature_set, + NETIF_F_HW_VLAN_CTAG_RX_BIT, + NETIF_F_RXCSUM_BIT); + static int typhoon_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) { @@ -2476,10 +2486,10 @@ typhoon_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) * on the current 3XP firmware -- it does not respect the offload * settings -- so we only allow the user to toggle the TX processing. */ - dev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO | - NETIF_F_HW_VLAN_CTAG_TX; - dev->features = dev->hw_features | - NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_RXCSUM; + netdev_hw_features_zero(dev); + netdev_hw_features_set_array(dev, &typhoon_hw_feature_set); + dev->features = dev->hw_features; + netdev_active_features_set_array(dev, &typhoon_feature_set);
err = register_netdev(dev); if (err < 0) { diff --git a/drivers/net/ethernet/aeroflex/greth.c b/drivers/net/ethernet/aeroflex/greth.c index 447dc64a17e5..dca85429a0ea 100644 --- a/drivers/net/ethernet/aeroflex/greth.c +++ b/drivers/net/ethernet/aeroflex/greth.c @@ -1336,6 +1336,11 @@ static int greth_mdio_init(struct greth_private *greth) return ret; }
+static DECLARE_NETDEV_FEATURE_SET(greth_hw_feature_set, + NETIF_F_SG_BIT, + NETIF_F_IP_CSUM_BIT, + NETIF_F_RXCSUM_BIT); + /* Initialize the GRETH MAC */ static int greth_of_probe(struct platform_device *ofdev) { @@ -1483,8 +1488,8 @@ static int greth_of_probe(struct platform_device *ofdev) GRETH_REGSAVE(regs->status, 0xFF);
if (greth->gbit_mac) { - dev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | - NETIF_F_RXCSUM; + netdev_hw_features_zero(dev); + netdev_hw_features_set_array(dev, &greth_hw_feature_set); dev->features = dev->hw_features | NETIF_F_HIGHDMA; greth_netdev_ops.ndo_start_xmit = greth_start_xmit_gbit; } diff --git a/drivers/net/ethernet/alteon/acenic.c b/drivers/net/ethernet/alteon/acenic.c index 22fe98555b24..4a16e176248c 100644 --- a/drivers/net/ethernet/alteon/acenic.c +++ b/drivers/net/ethernet/alteon/acenic.c @@ -55,6 +55,7 @@ #include <linux/dma-mapping.h> #include <linux/kernel.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/etherdevice.h> #include <linux/skbuff.h> #include <linux/delay.h> @@ -451,6 +452,12 @@ static const struct net_device_ops ace_netdev_ops = { .ndo_change_mtu = ace_change_mtu, };
+static DECLARE_NETDEV_FEATURE_SET(acenic_feature_set, + NETIF_F_SG_BIT, + NETIF_F_IP_CSUM_BIT, + NETIF_F_HW_VLAN_CTAG_TX_BIT, + NETIF_F_HW_VLAN_CTAG_RX_BIT); + static int acenic_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) { @@ -469,8 +476,7 @@ static int acenic_probe_one(struct pci_dev *pdev, ap->pdev = pdev; ap->name = pci_name(pdev);
- dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM; - dev->features |= NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX; + netdev_active_features_set_array(dev, &acenic_feature_set);
dev->watchdog_timeo = 5*HZ; dev->min_mtu = 0; diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.c b/drivers/net/ethernet/amazon/ena/ena_netdev.c index 6a356a6cee15..ab102769965f 100644 --- a/drivers/net/ethernet/amazon/ena/ena_netdev.c +++ b/drivers/net/ethernet/amazon/ena/ena_netdev.c @@ -11,6 +11,7 @@ #include <linux/ethtool.h> #include <linux/kernel.h> #include <linux/module.h> +#include <linux/netdev_features_helper.h> #include <linux/numa.h> #include <linux/pci.h> #include <linux/utsname.h> @@ -4010,6 +4011,11 @@ static u32 ena_calc_max_io_queue_num(struct pci_dev *pdev, return max_num_io_queues; }
+static DECLARE_NETDEV_FEATURE_SET(ena_feature_set, + NETIF_F_SG_BIT, + NETIF_F_RXHASH_BIT, + NETIF_F_HIGHDMA_BIT); + static void ena_set_dev_offloads(struct ena_com_dev_get_features_ctx *feat, struct net_device *netdev) { @@ -4041,11 +4047,8 @@ static void ena_set_dev_offloads(struct ena_com_dev_get_features_ctx *feat, ENA_ADMIN_FEATURE_OFFLOAD_DESC_RX_L4_IPV6_CSUM_MASK) dev_features |= NETIF_F_RXCSUM;
- netdev->features = - dev_features | - NETIF_F_SG | - NETIF_F_RXHASH | - NETIF_F_HIGHDMA; + netdev->features = dev_features; + netdev_active_features_set_array(netdev, &ena_feature_set);
netdev->hw_features |= netdev->features; netdev->vlan_features |= netdev->features; diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-main.c b/drivers/net/ethernet/amd/xgbe/xgbe-main.c index 0e8698928e4d..a5c4fb8aa676 100644 --- a/drivers/net/ethernet/amd/xgbe/xgbe-main.c +++ b/drivers/net/ethernet/amd/xgbe/xgbe-main.c @@ -118,6 +118,7 @@ #include <linux/device.h> #include <linux/spinlock.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/etherdevice.h> #include <linux/io.h> #include <linux/notifier.h> @@ -259,6 +260,34 @@ void xgbe_set_counts(struct xgbe_prv_data *pdata) } }
+static DECLARE_NETDEV_FEATURE_SET(xgbe_hw_feature_set, + NETIF_F_SG_BIT, + NETIF_F_IP_CSUM_BIT, + NETIF_F_IPV6_CSUM_BIT, + NETIF_F_RXCSUM_BIT, + NETIF_F_TSO_BIT, + NETIF_F_TSO6_BIT, + NETIF_F_GRO_BIT, + NETIF_F_HW_VLAN_CTAG_RX_BIT, + NETIF_F_HW_VLAN_CTAG_TX_BIT, + NETIF_F_HW_VLAN_CTAG_FILTER_BIT); +static DECLARE_NETDEV_FEATURE_SET(xgbe_hw_enc_feature_set, + NETIF_F_SG_BIT, + NETIF_F_IP_CSUM_BIT, + NETIF_F_IPV6_CSUM_BIT, + NETIF_F_RXCSUM_BIT, + NETIF_F_TSO_BIT, + NETIF_F_TSO6_BIT, + NETIF_F_GRO_BIT, + NETIF_F_GSO_UDP_TUNNEL_BIT, + NETIF_F_GSO_UDP_TUNNEL_CSUM_BIT); +static DECLARE_NETDEV_FEATURE_SET(xgbe_vlan_feature_set, + NETIF_F_SG_BIT, + NETIF_F_IP_CSUM_BIT, + NETIF_F_IPV6_CSUM_BIT, + NETIF_F_TSO_BIT, + NETIF_F_TSO6_BIT); + int xgbe_config_netdev(struct xgbe_prv_data *pdata) { struct net_device *netdev = pdata->netdev; @@ -342,30 +371,16 @@ int xgbe_config_netdev(struct xgbe_prv_data *pdata) #endif
/* Set device features */ - netdev->hw_features = NETIF_F_SG | - NETIF_F_IP_CSUM | - NETIF_F_IPV6_CSUM | - NETIF_F_RXCSUM | - NETIF_F_TSO | - NETIF_F_TSO6 | - NETIF_F_GRO | - NETIF_F_HW_VLAN_CTAG_RX | - NETIF_F_HW_VLAN_CTAG_TX | - NETIF_F_HW_VLAN_CTAG_FILTER; + netdev_hw_features_zero(netdev); + netdev_hw_features_set_array(netdev, &xgbe_hw_feature_set);
if (pdata->hw_feat.rss) netdev->hw_features |= NETIF_F_RXHASH;
if (pdata->hw_feat.vxn) { - netdev->hw_enc_features = NETIF_F_SG | - NETIF_F_IP_CSUM | - NETIF_F_IPV6_CSUM | - NETIF_F_RXCSUM | - NETIF_F_TSO | - NETIF_F_TSO6 | - NETIF_F_GRO | - NETIF_F_GSO_UDP_TUNNEL | - NETIF_F_GSO_UDP_TUNNEL_CSUM; + netdev_hw_enc_features_zero(netdev); + netdev_hw_enc_features_set_array(netdev, + &xgbe_hw_enc_feature_set);
netdev->hw_features |= NETIF_F_GSO_UDP_TUNNEL | NETIF_F_GSO_UDP_TUNNEL_CSUM; @@ -373,11 +388,7 @@ int xgbe_config_netdev(struct xgbe_prv_data *pdata) netdev->udp_tunnel_nic_info = xgbe_get_udp_tunnel_info(); }
- netdev->vlan_features |= NETIF_F_SG | - NETIF_F_IP_CSUM | - NETIF_F_IPV6_CSUM | - NETIF_F_TSO | - NETIF_F_TSO6; + netdev_vlan_features_set_array(netdev, &xgbe_vlan_feature_set);
netdev->features |= netdev->hw_features; pdata->netdev_features = netdev->features; diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_main.c b/drivers/net/ethernet/apm/xgene/xgene_enet_main.c index 53dc8d5fede8..49a35bd4c16d 100644 --- a/drivers/net/ethernet/apm/xgene/xgene_enet_main.c +++ b/drivers/net/ethernet/apm/xgene/xgene_enet_main.c @@ -8,6 +8,7 @@ */
#include <linux/gpio.h> +#include <linux/netdev_features_helper.h> #include "xgene_enet_main.h" #include "xgene_enet_hw.h" #include "xgene_enet_sgmac.h" @@ -2012,6 +2013,12 @@ static const struct of_device_id xgene_enet_of_match[] = {
MODULE_DEVICE_TABLE(of, xgene_enet_of_match);
+static DECLARE_NETDEV_FEATURE_SET(xgene_vlan_feature_set, + NETIF_F_IP_CSUM_BIT, + NETIF_F_GSO_BIT, + NETIF_F_GRO_BIT, + NETIF_F_SG_BIT); + static int xgene_enet_probe(struct platform_device *pdev) { struct net_device *ndev; @@ -2034,10 +2041,7 @@ static int xgene_enet_probe(struct platform_device *pdev) platform_set_drvdata(pdev, pdata); ndev->netdev_ops = &xgene_ndev_ops; xgene_enet_set_ethtool_ops(ndev); - ndev->features |= NETIF_F_IP_CSUM | - NETIF_F_GSO | - NETIF_F_GRO | - NETIF_F_SG; + netdev_active_features_set_array(ndev, &xgene_vlan_feature_set);
of_id = of_match_device(xgene_enet_of_match, &pdev->dev); if (of_id) { diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c index e11cc29d3264..2a726e6213b4 100644 --- a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c +++ b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c @@ -20,6 +20,7 @@
#include <linux/moduleparam.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/etherdevice.h> #include <linux/timer.h> #include <linux/cpu.h> @@ -368,6 +369,15 @@ int aq_nic_ndev_register(struct aq_nic_s *self) return err; }
+static DECLARE_NETDEV_FEATURE_SET(aq_nic_vlan_feature_set, + NETIF_F_HW_CSUM_BIT, + NETIF_F_RXCSUM_BIT, + NETIF_F_RXHASH_BIT, + NETIF_F_SG_BIT, + NETIF_F_LRO_BIT, + NETIF_F_TSO_BIT, + NETIF_F_TSO6_BIT); + void aq_nic_ndev_init(struct aq_nic_s *self) { const struct aq_hw_caps_s *aq_hw_caps = self->aq_nic_cfg.aq_hw_caps; @@ -375,9 +385,7 @@ void aq_nic_ndev_init(struct aq_nic_s *self)
self->ndev->hw_features |= aq_hw_caps->hw_features; self->ndev->features = aq_hw_caps->hw_features; - self->ndev->vlan_features |= NETIF_F_HW_CSUM | NETIF_F_RXCSUM | - NETIF_F_RXHASH | NETIF_F_SG | - NETIF_F_LRO | NETIF_F_TSO | NETIF_F_TSO6; + netdev_vlan_features_set_array(self->ndev, &aq_nic_vlan_feature_set); self->ndev->gso_partial_features = NETIF_F_GSO_UDP_L4; self->ndev->priv_flags = aq_hw_caps->hw_priv_flags; self->ndev->priv_flags |= IFF_LIVE_ADDR_CHANGE; diff --git a/drivers/net/ethernet/asix/ax88796c_main.c b/drivers/net/ethernet/asix/ax88796c_main.c index 6ba5b024a7be..9309d371b8da 100644 --- a/drivers/net/ethernet/asix/ax88796c_main.c +++ b/drivers/net/ethernet/asix/ax88796c_main.c @@ -19,6 +19,7 @@ #include <linux/minmax.h> #include <linux/module.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/of.h> #include <linux/phy.h> #include <linux/skbuff.h> @@ -33,6 +34,11 @@ static int msg_enable = NETIF_MSG_PROBE | static const char *no_regs_list = "80018001,e1918001,8001a001,fc0d0000"; unsigned long ax88796c_no_regs_mask[AX88796C_REGDUMP_LEN / (sizeof(unsigned long) * 8)];
+static DECLARE_NETDEV_FEATURE_SET(ax88796c_feature_set, + NETIF_F_RXCSUM_BIT, + NETIF_F_HW_CSUM_BIT); +static netdev_features_t ax88796c_features __ro_after_init; + module_param(msg_enable, int, 0444); MODULE_PARM_DESC(msg_enable, "Message mask (see linux/netdevice.h for bitmap)");
@@ -920,12 +926,12 @@ ax88796c_set_features(struct net_device *ndev, netdev_features_t features) struct ax88796c_device *ax_local = to_ax88796c_device(ndev); netdev_features_t changed = features ^ ndev->features;
- if (!(changed & (NETIF_F_RXCSUM | NETIF_F_HW_CSUM))) + if (!(changed & ax88796c_features)) return 0;
ndev->features = features;
- if (changed & (NETIF_F_RXCSUM | NETIF_F_HW_CSUM)) + if (changed & ax88796c_features) ax88796c_set_csums(ax_local);
return 0; @@ -1023,8 +1029,8 @@ static int ax88796c_probe(struct spi_device *spi) ndev->irq = spi->irq; ndev->netdev_ops = &ax88796c_netdev_ops; ndev->ethtool_ops = &ax88796c_ethtool_ops; - ndev->hw_features |= NETIF_F_HW_CSUM | NETIF_F_RXCSUM; - ndev->features |= NETIF_F_HW_CSUM | NETIF_F_RXCSUM; + ndev->hw_features |= ax88796c_features; + ndev->features |= ax88796c_features; ndev->needed_headroom = TX_OVERHEAD; ndev->needed_tailroom = TX_EOP_SIZE;
@@ -1138,6 +1144,11 @@ static struct spi_driver ax88796c_spi_driver = { .id_table = asix_id, };
+static void __init ax88796c_features_init(void) +{ + netdev_features_set_array(&ax88796c_feature_set, &ax88796c_features); +} + static __init int ax88796c_spi_init(void) { int ret; @@ -1150,6 +1161,8 @@ static __init int ax88796c_spi_init(void) pr_err("Invalid bitmap description, masking all registers\n"); }
+ ax88796c_features_init(); + return spi_register_driver(&ax88796c_spi_driver); }
diff --git a/drivers/net/ethernet/atheros/alx/main.c b/drivers/net/ethernet/atheros/alx/main.c index a89b93cb4e26..7f5cb50f4b66 100644 --- a/drivers/net/ethernet/atheros/alx/main.c +++ b/drivers/net/ethernet/atheros/alx/main.c @@ -42,6 +42,7 @@ #include <linux/aer.h> #include <linux/bitops.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/etherdevice.h> #include <net/ip6_checksum.h> #include <linux/crc32.h> @@ -1712,6 +1713,13 @@ static const struct net_device_ops alx_netdev_ops = { #endif };
+static DECLARE_NETDEV_FEATURE_SET(alx_hw_feature_set, + NETIF_F_SG_BIT, + NETIF_F_HW_CSUM_BIT, + NETIF_F_RXCSUM_BIT, + NETIF_F_TSO_BIT, + NETIF_F_TSO6_BIT); + static int alx_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { struct net_device *netdev; @@ -1821,11 +1829,8 @@ static int alx_probe(struct pci_dev *pdev, const struct pci_device_id *ent) } }
- netdev->hw_features = NETIF_F_SG | - NETIF_F_HW_CSUM | - NETIF_F_RXCSUM | - NETIF_F_TSO | - NETIF_F_TSO6; + netdev_hw_features_zero(netdev); + netdev_hw_features_set_array(netdev, &alx_hw_feature_set);
if (alx_get_perm_macaddr(hw, hw->perm_addr)) { dev_warn(&pdev->dev, diff --git a/drivers/net/ethernet/atheros/atl1c/atl1c.h b/drivers/net/ethernet/atheros/atl1c/atl1c.h index 43d821fe7a54..6a1f8191a336 100644 --- a/drivers/net/ethernet/atheros/atl1c/atl1c.h +++ b/drivers/net/ethernet/atheros/atl1c/atl1c.h @@ -15,6 +15,7 @@ #include <linux/module.h> #include <linux/pci.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/etherdevice.h> #include <linux/skbuff.h> #include <linux/ioport.h> diff --git a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c index be4b1f8eef29..220253cec3c2 100644 --- a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c +++ b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c @@ -2618,6 +2618,13 @@ static const struct net_device_ops atl1c_netdev_ops = { #endif };
+static DECLARE_NETDEV_FEATURE_SET(atl1c_hw_feature_set, + NETIF_F_SG_BIT, + NETIF_F_HW_CSUM_BIT, + NETIF_F_HW_VLAN_CTAG_RX_BIT, + NETIF_F_TSO_BIT, + NETIF_F_TSO6_BIT); + static int atl1c_init_netdev(struct net_device *netdev, struct pci_dev *pdev) { SET_NETDEV_DEV(netdev, &pdev->dev); @@ -2629,11 +2636,8 @@ static int atl1c_init_netdev(struct net_device *netdev, struct pci_dev *pdev) atl1c_set_ethtool_ops(netdev);
/* TODO: add when ready */ - netdev->hw_features = NETIF_F_SG | - NETIF_F_HW_CSUM | - NETIF_F_HW_VLAN_CTAG_RX | - NETIF_F_TSO | - NETIF_F_TSO6; + netdev_hw_features_zero(netdev); + netdev_hw_features_set_array(netdev, &atl1c_hw_feature_set); netdev->features = netdev->hw_features | NETIF_F_HW_VLAN_CTAG_TX; return 0; diff --git a/drivers/net/ethernet/atheros/atl1e/atl1e.h b/drivers/net/ethernet/atheros/atl1e/atl1e.h index 9fcad783c939..007eef2cc9fc 100644 --- a/drivers/net/ethernet/atheros/atl1e/atl1e.h +++ b/drivers/net/ethernet/atheros/atl1e/atl1e.h @@ -16,6 +16,7 @@ #include <linux/module.h> #include <linux/pci.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/etherdevice.h> #include <linux/skbuff.h> #include <linux/ioport.h> diff --git a/drivers/net/ethernet/atheros/atl1e/atl1e_main.c b/drivers/net/ethernet/atheros/atl1e/atl1e_main.c index 57a51fb7746c..0aaca5a1f87c 100644 --- a/drivers/net/ethernet/atheros/atl1e/atl1e_main.c +++ b/drivers/net/ethernet/atheros/atl1e/atl1e_main.c @@ -2255,6 +2255,12 @@ static const struct net_device_ops atl1e_netdev_ops = {
};
+static DECLARE_NETDEV_FEATURE_SET(atl1e_hw_feature_set, + NETIF_F_SG_BIT, + NETIF_F_HW_CSUM_BIT, + NETIF_F_TSO_BIT, + NETIF_F_HW_VLAN_CTAG_RX_BIT); + static int atl1e_init_netdev(struct net_device *netdev, struct pci_dev *pdev) { SET_NETDEV_DEV(netdev, &pdev->dev); @@ -2269,8 +2275,8 @@ static int atl1e_init_netdev(struct net_device *netdev, struct pci_dev *pdev) (ETH_HLEN + ETH_FCS_LEN + VLAN_HLEN); atl1e_set_ethtool_ops(netdev);
- netdev->hw_features = NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_TSO | - NETIF_F_HW_VLAN_CTAG_RX; + netdev_hw_features_zero(netdev); + netdev_hw_features_set_array(netdev, &atl1e_hw_feature_set); netdev->features = netdev->hw_features | NETIF_F_HW_VLAN_CTAG_TX; /* not enabled by default */ netdev->hw_features |= NETIF_F_RXALL | NETIF_F_RXFCS; diff --git a/drivers/net/ethernet/atheros/atlx/atl1.c b/drivers/net/ethernet/atheros/atlx/atl1.c index ff1fe09abf9f..c46d3e7ae89f 100644 --- a/drivers/net/ethernet/atheros/atlx/atl1.c +++ b/drivers/net/ethernet/atheros/atlx/atl1.c @@ -49,6 +49,7 @@ #include <linux/module.h> #include <linux/net.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/pci.h> #include <linux/pci_ids.h> #include <linux/pm.h> @@ -2891,6 +2892,18 @@ static const struct net_device_ops atl1_netdev_ops = { #endif };
+static DECLARE_NETDEV_FEATURE_SET(atl1_feature_set, + NETIF_F_HW_CSUM_BIT, + NETIF_F_SG_BIT, + NETIF_F_HW_VLAN_CTAG_TX_BIT, + NETIF_F_HW_VLAN_CTAG_RX_BIT); + +static DECLARE_NETDEV_FEATURE_SET(atl1_hw_feature_set, + NETIF_F_HW_CSUM_BIT, + NETIF_F_SG_BIT, + NETIF_F_TSO_BIT, + NETIF_F_HW_VLAN_CTAG_RX_BIT); + /** * atl1_probe - Device Initialization Routine * @pdev: PCI device information struct @@ -2987,12 +3000,11 @@ static int atl1_probe(struct pci_dev *pdev, const struct pci_device_id *ent) if (err) goto err_common;
- netdev->features = NETIF_F_HW_CSUM; - netdev->features |= NETIF_F_SG; - netdev->features |= (NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX); + netdev_active_features_zero(netdev); + netdev_active_features_set_array(netdev, &atl1_feature_set);
- netdev->hw_features = NETIF_F_HW_CSUM | NETIF_F_SG | NETIF_F_TSO | - NETIF_F_HW_VLAN_CTAG_RX; + netdev_hw_features_zero(netdev); + netdev_hw_features_set_array(netdev, &atl1_hw_feature_set);
/* is this valid? see atl1_setup_mac_ctrl() */ netdev->features |= NETIF_F_RXCSUM; diff --git a/drivers/net/ethernet/broadcom/bcmsysport.c b/drivers/net/ethernet/broadcom/bcmsysport.c index 47fc8e6963d5..05a0c169e418 100644 --- a/drivers/net/ethernet/broadcom/bcmsysport.c +++ b/drivers/net/ethernet/broadcom/bcmsysport.c @@ -12,6 +12,7 @@ #include <linux/module.h> #include <linux/kernel.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/dsa/brcm.h> #include <linux/etherdevice.h> #include <linux/platform_device.h> @@ -153,17 +154,25 @@ static void bcm_sysport_set_rx_csum(struct net_device *dev, rxchk_writel(priv, reg, RXCHK_CONTROL); }
+static DECLARE_NETDEV_FEATURE_SET(bcm_sysport_tx_csum_feature_set, + NETIF_F_IP_CSUM_BIT, + NETIF_F_IPV6_CSUM_BIT, + NETIF_F_HW_VLAN_CTAG_TX_BIT); + static void bcm_sysport_set_tx_csum(struct net_device *dev, netdev_features_t wanted) { struct bcm_sysport_priv *priv = netdev_priv(dev); + netdev_features_t tx_csum_features; u32 reg;
+ netdev_features_zero(&tx_csum_features); + netdev_features_set_array(&bcm_sysport_tx_csum_feature_set, + &tx_csum_features); /* Hardware transmit checksum requires us to enable the Transmit status * block prepended to the packet contents */ - priv->tsb_en = !!(wanted & (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | - NETIF_F_HW_VLAN_CTAG_TX)); + priv->tsb_en = !!(wanted & tx_csum_features); reg = tdma_readl(priv, TDMA_CONTROL); if (priv->tsb_en) reg |= tdma_control_bit(priv, TSB_EN); @@ -2453,6 +2462,13 @@ static const struct of_device_id bcm_sysport_of_match[] = { }; MODULE_DEVICE_TABLE(of, bcm_sysport_of_match);
+DECLARE_NETDEV_FEATURE_SET(bcm_feature_set, + NETIF_F_RXCSUM_BIT, + NETIF_F_HIGHDMA_BIT, + NETIF_F_IP_CSUM_BIT, + NETIF_F_IPV6_CSUM_BIT, + NETIF_F_HW_VLAN_CTAG_TX_BIT); + static int bcm_sysport_probe(struct platform_device *pdev) { const struct bcm_sysport_hw_params *params; @@ -2566,9 +2582,7 @@ static int bcm_sysport_probe(struct platform_device *pdev) dev->netdev_ops = &bcm_sysport_netdev_ops; netif_napi_add(dev, &priv->napi, bcm_sysport_poll, 64);
- dev->features |= NETIF_F_RXCSUM | NETIF_F_HIGHDMA | - NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | - NETIF_F_HW_VLAN_CTAG_TX; + netdev_active_features_set_array(dev, &bcm_feature_set); dev->hw_features |= dev->features; dev->vlan_features |= dev->features; dev->max_mtu = UMAC_MAX_MTU_SIZE; diff --git a/drivers/net/ethernet/broadcom/bgmac.c b/drivers/net/ethernet/broadcom/bgmac.c index 2dfc1e32bbb3..523cadd48669 100644 --- a/drivers/net/ethernet/broadcom/bgmac.c +++ b/drivers/net/ethernet/broadcom/bgmac.c @@ -13,6 +13,7 @@ #include <linux/etherdevice.h> #include <linux/interrupt.h> #include <linux/bcm47xx_nvram.h> +#include <linux/netdev_features_helper.h> #include <linux/phy.h> #include <linux/phy_fixed.h> #include <net/dsa.h> @@ -1485,6 +1486,11 @@ struct bgmac *bgmac_alloc(struct device *dev) } EXPORT_SYMBOL_GPL(bgmac_alloc);
+static DECLARE_NETDEV_FEATURE_SET(bgmac_feature_set, + NETIF_F_SG_BIT, + NETIF_F_IP_CSUM_BIT, + NETIF_F_IPV6_CSUM_BIT); + int bgmac_enet_probe(struct bgmac *bgmac) { struct net_device *net_dev = bgmac->net_dev; @@ -1535,7 +1541,8 @@ int bgmac_enet_probe(struct bgmac *bgmac) goto err_dma_free; }
- net_dev->features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM; + netdev_active_features_zero(net_dev); + netdev_active_features_set_array(net_dev, &bgmac_feature_set); net_dev->hw_features = net_dev->features; net_dev->vlan_features = net_dev->features;
diff --git a/drivers/net/ethernet/broadcom/bnx2.c b/drivers/net/ethernet/broadcom/bnx2.c index b97ed9b5f685..0e779e5dee9a 100644 --- a/drivers/net/ethernet/broadcom/bnx2.c +++ b/drivers/net/ethernet/broadcom/bnx2.c @@ -25,6 +25,7 @@ #include <linux/interrupt.h> #include <linux/pci.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/etherdevice.h> #include <linux/skbuff.h> #include <linux/dma-mapping.h> @@ -8544,6 +8545,14 @@ static const struct net_device_ops bnx2_netdev_ops = { #endif };
+static DECLARE_NETDEV_FEATURE_SET(bnx2_hw_feature_set, + NETIF_F_IP_CSUM_BIT, + NETIF_F_SG_BIT, + NETIF_F_TSO_BIT, + NETIF_F_TSO_ECN_BIT, + NETIF_F_RXHASH_BIT, + NETIF_F_RXCSUM_BIT); + static int bnx2_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) { @@ -8580,9 +8589,8 @@ bnx2_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
eth_hw_addr_set(dev, bp->mac_addr);
- dev->hw_features = NETIF_F_IP_CSUM | NETIF_F_SG | - NETIF_F_TSO | NETIF_F_TSO_ECN | - NETIF_F_RXHASH | NETIF_F_RXCSUM; + netdev_hw_features_zero(dev); + netdev_hw_features_set_array(dev, &bnx2_hw_feature_set);
if (BNX2_CHIP(bp) == BNX2_CHIP_5709) dev->hw_features |= NETIF_F_IPV6_CSUM | NETIF_F_TSO6; diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index 962253db25b8..845d31294667 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c @@ -32,6 +32,7 @@ #include <linux/aer.h> #include <linux/init.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/etherdevice.h> #include <linux/skbuff.h> #include <linux/dma-mapping.h> @@ -13045,6 +13046,55 @@ static void bnx2x_disable_pcie_error_reporting(struct bnx2x *bp) } }
+static DECLARE_NETDEV_FEATURE_SET(bnx2x_hw_feature_set, + NETIF_F_SG_BIT, + NETIF_F_IP_CSUM_BIT, + NETIF_F_IPV6_CSUM_BIT, + NETIF_F_TSO_BIT, + NETIF_F_TSO_ECN_BIT, + NETIF_F_TSO6_BIT, + NETIF_F_RXCSUM_BIT, + NETIF_F_LRO_BIT, + NETIF_F_GRO_BIT, + NETIF_F_GRO_HW_BIT, + NETIF_F_RXHASH_BIT, + NETIF_F_HW_VLAN_CTAG_TX_BIT); + +static DECLARE_NETDEV_FEATURE_SET(bnx2x_hw_gso_feature_set, + NETIF_F_GSO_GRE_BIT, + NETIF_F_GSO_GRE_CSUM_BIT, + NETIF_F_GSO_IPXIP4_BIT, + NETIF_F_GSO_UDP_TUNNEL_BIT, + NETIF_F_GSO_UDP_TUNNEL_CSUM_BIT, + NETIF_F_GSO_PARTIAL_BIT); + +static DECLARE_NETDEV_FEATURE_SET(bnx2x_hw_enc_feature_set, + NETIF_F_IP_CSUM_BIT, + NETIF_F_IPV6_CSUM_BIT, + NETIF_F_SG_BIT, + NETIF_F_TSO_BIT, + NETIF_F_TSO_ECN_BIT, + NETIF_F_TSO6_BIT, + NETIF_F_GSO_IPXIP4_BIT, + NETIF_F_GSO_GRE_BIT, + NETIF_F_GSO_GRE_CSUM_BIT, + NETIF_F_GSO_UDP_TUNNEL_BIT, + NETIF_F_GSO_UDP_TUNNEL_CSUM_BIT, + NETIF_F_GSO_PARTIAL_BIT); + +static DECLARE_NETDEV_FEATURE_SET(bnx2x_gso_partial_feature_set, + NETIF_F_GSO_GRE_CSUM_BIT, + NETIF_F_GSO_UDP_TUNNEL_CSUM_BIT); + +static DECLARE_NETDEV_FEATURE_SET(bnx2x_vlan_feature_set, + NETIF_F_SG_BIT, + NETIF_F_IP_CSUM_BIT, + NETIF_F_IPV6_CSUM_BIT, + NETIF_F_TSO_BIT, + NETIF_F_TSO_ECN_BIT, + NETIF_F_TSO6_BIT, + NETIF_F_HIGHDMA_BIT); + static int bnx2x_init_dev(struct bnx2x *bp, struct pci_dev *pdev, struct net_device *dev, unsigned long board_type) { @@ -13197,34 +13247,23 @@ static int bnx2x_init_dev(struct bnx2x *bp, struct pci_dev *pdev,
dev->priv_flags |= IFF_UNICAST_FLT;
- dev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | - NETIF_F_TSO | NETIF_F_TSO_ECN | NETIF_F_TSO6 | - NETIF_F_RXCSUM | NETIF_F_LRO | NETIF_F_GRO | NETIF_F_GRO_HW | - NETIF_F_RXHASH | NETIF_F_HW_VLAN_CTAG_TX; + netdev_hw_features_zero(dev); + netdev_hw_features_set_array(dev, &bnx2x_hw_feature_set); if (!chip_is_e1x) { - dev->hw_features |= NETIF_F_GSO_GRE | NETIF_F_GSO_GRE_CSUM | - NETIF_F_GSO_IPXIP4 | - NETIF_F_GSO_UDP_TUNNEL | - NETIF_F_GSO_UDP_TUNNEL_CSUM | - NETIF_F_GSO_PARTIAL; - - dev->hw_enc_features = - NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | NETIF_F_SG | - NETIF_F_TSO | NETIF_F_TSO_ECN | NETIF_F_TSO6 | - NETIF_F_GSO_IPXIP4 | - NETIF_F_GSO_GRE | NETIF_F_GSO_GRE_CSUM | - NETIF_F_GSO_UDP_TUNNEL | NETIF_F_GSO_UDP_TUNNEL_CSUM | - NETIF_F_GSO_PARTIAL; - - dev->gso_partial_features = NETIF_F_GSO_GRE_CSUM | - NETIF_F_GSO_UDP_TUNNEL_CSUM; + netdev_hw_features_set_array(dev, &bnx2x_hw_gso_feature_set); + + netdev_hw_enc_features_zero(dev); + netdev_hw_enc_features_set_array(dev, &bnx2x_hw_enc_feature_set); + + netdev_gso_partial_features_zero(dev); + netdev_gso_partial_features_set_array(dev, &bnx2x_gso_partial_feature_set);
if (IS_PF(bp)) dev->udp_tunnel_nic_info = &bnx2x_udp_tunnels; }
- dev->vlan_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | - NETIF_F_TSO | NETIF_F_TSO_ECN | NETIF_F_TSO6 | NETIF_F_HIGHDMA; + netdev_vlan_features_zero(dev); + netdev_vlan_features_set_array(dev, &bnx2x_vlan_feature_set);
if (IS_PF(bp)) { if (chip_is_e1x) diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c index ba0f1ffac507..825bf829b36a 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c @@ -20,6 +20,7 @@ #include <linux/interrupt.h> #include <linux/pci.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/etherdevice.h> #include <linux/skbuff.h> #include <linux/dma-mapping.h> @@ -13517,6 +13518,38 @@ void bnxt_print_device_info(struct bnxt *bp) pcie_print_link_status(bp->pdev); }
+static DECLARE_NETDEV_FEATURE_SET(bnxt_hw_feature_set, + NETIF_F_IP_CSUM_BIT, + NETIF_F_IPV6_CSUM_BIT, + NETIF_F_SG_BIT, + NETIF_F_TSO_BIT, + NETIF_F_TSO6_BIT, + NETIF_F_GSO_UDP_TUNNEL_BIT, + NETIF_F_GSO_GRE_BIT, + NETIF_F_GSO_IPXIP4_BIT, + NETIF_F_GSO_UDP_TUNNEL_CSUM_BIT, + NETIF_F_GSO_GRE_CSUM_BIT, + NETIF_F_GSO_PARTIAL_BIT, + NETIF_F_RXHASH_BIT, + NETIF_F_RXCSUM_BIT, + NETIF_F_GRO_BIT); + +static DECLARE_NETDEV_FEATURE_SET(bnxt_hw_enc_feature_set, + NETIF_F_IP_CSUM_BIT, + NETIF_F_IPV6_CSUM_BIT, + NETIF_F_SG_BIT, + NETIF_F_TSO_BIT, + NETIF_F_TSO6_BIT, + NETIF_F_GSO_UDP_TUNNEL_BIT, + NETIF_F_GSO_GRE_BIT, + NETIF_F_GSO_UDP_TUNNEL_CSUM_BIT, + NETIF_F_GSO_GRE_CSUM_BIT, + NETIF_F_GSO_IPXIP4_BIT, + NETIF_F_GSO_PARTIAL_BIT); +static DECLARE_NETDEV_FEATURE_SET(bnxt_gso_partial_feature_set, + NETIF_F_GSO_UDP_TUNNEL_CSUM_BIT, + NETIF_F_GSO_GRE_CSUM_BIT); + static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) { struct net_device *dev; @@ -13594,27 +13627,18 @@ static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) goto init_err_pci_clean; }
- dev->hw_features = NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | NETIF_F_SG | - NETIF_F_TSO | NETIF_F_TSO6 | - NETIF_F_GSO_UDP_TUNNEL | NETIF_F_GSO_GRE | - NETIF_F_GSO_IPXIP4 | - NETIF_F_GSO_UDP_TUNNEL_CSUM | NETIF_F_GSO_GRE_CSUM | - NETIF_F_GSO_PARTIAL | NETIF_F_RXHASH | - NETIF_F_RXCSUM | NETIF_F_GRO; + netdev_hw_features_zero(dev); + netdev_hw_features_set_array(dev, &bnxt_hw_feature_set);
if (BNXT_SUPPORTS_TPA(bp)) dev->hw_features |= NETIF_F_LRO;
- dev->hw_enc_features = - NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | NETIF_F_SG | - NETIF_F_TSO | NETIF_F_TSO6 | - NETIF_F_GSO_UDP_TUNNEL | NETIF_F_GSO_GRE | - NETIF_F_GSO_UDP_TUNNEL_CSUM | NETIF_F_GSO_GRE_CSUM | - NETIF_F_GSO_IPXIP4 | NETIF_F_GSO_PARTIAL; + netdev_hw_enc_features_zero(dev); + netdev_hw_enc_features_set_array(dev, &bnxt_hw_enc_feature_set); dev->udp_tunnel_nic_info = &bnxt_udp_tunnels;
- dev->gso_partial_features = NETIF_F_GSO_UDP_TUNNEL_CSUM | - NETIF_F_GSO_GRE_CSUM; + netdev_gso_partial_features_zero(dev); + netdev_gso_partial_features_set_array(dev, &bnxt_gso_partial_feature_set); dev->vlan_features = dev->hw_features | NETIF_F_HIGHDMA; if (bp->fw_cap & BNXT_FW_CAP_VLAN_RX_STRIP) dev->hw_features |= BNXT_HW_FEATURE_VLAN_ALL_RX; diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c index 8309fb993cdb..0d41ae12e262 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c @@ -28,6 +28,7 @@ #include <linux/mii.h> #include <linux/ethtool.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/inetdevice.h> #include <linux/etherdevice.h> #include <linux/skbuff.h> @@ -3969,6 +3970,12 @@ static const struct of_device_id bcmgenet_match[] = { }; MODULE_DEVICE_TABLE(of, bcmgenet_match);
+static DECLARE_NETDEV_FEATURE_SET(bcmgenet_feature_set, + NETIF_F_SG_BIT, + NETIF_F_HIGHDMA_BIT, + NETIF_F_HW_CSUM_BIT, + NETIF_F_RXCSUM_BIT); + static int bcmgenet_probe(struct platform_device *pdev) { struct bcmgenet_platform_data *pd = pdev->dev.platform_data; @@ -4025,8 +4032,7 @@ static int bcmgenet_probe(struct platform_device *pdev) priv->msg_enable = netif_msg_init(-1, GENET_MSG_DEFAULT);
/* Set default features */ - dev->features |= NETIF_F_SG | NETIF_F_HIGHDMA | NETIF_F_HW_CSUM | - NETIF_F_RXCSUM; + netdev_active_features_set_array(dev, &bcmgenet_feature_set); dev->hw_features |= dev->features; dev->vlan_features |= dev->features;
diff --git a/drivers/net/ethernet/brocade/bna/bnad.c b/drivers/net/ethernet/brocade/bna/bnad.c index 29dd0f93d6c0..786df1e64947 100644 --- a/drivers/net/ethernet/brocade/bna/bnad.c +++ b/drivers/net/ethernet/brocade/bna/bnad.c @@ -10,6 +10,7 @@ */ #include <linux/bitops.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/skbuff.h> #include <linux/etherdevice.h> #include <linux/in.h> @@ -3417,22 +3418,40 @@ static const struct net_device_ops bnad_netdev_ops = { #endif };
+static DECLARE_NETDEV_FEATURE_SET(bnad_hw_feature_set, + NETIF_F_SG_BIT, + NETIF_F_RXCSUM_BIT, + NETIF_F_IP_CSUM_BIT, + NETIF_F_IPV6_CSUM_BIT, + NETIF_F_TSO_BIT, + NETIF_F_TSO6_BIT, + NETIF_F_HW_VLAN_CTAG_TX_BIT, + NETIF_F_HW_VLAN_CTAG_RX_BIT); + +static DECLARE_NETDEV_FEATURE_SET(bnad_vlan_feature_set, + NETIF_F_SG_BIT, + NETIF_F_HIGHDMA_BIT, + NETIF_F_IP_CSUM_BIT, + NETIF_F_IPV6_CSUM_BIT, + NETIF_F_TSO_BIT, + NETIF_F_TSO6_BIT); + +static DECLARE_NETDEV_FEATURE_SET(bnad_feature_set, + NETIF_F_HW_VLAN_CTAG_FILTER_BIT, + NETIF_F_HIGHDMA_BIT); + static void bnad_netdev_init(struct bnad *bnad) { struct net_device *netdev = bnad->netdev;
- netdev->hw_features = NETIF_F_SG | NETIF_F_RXCSUM | - NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | - NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_HW_VLAN_CTAG_TX | - NETIF_F_HW_VLAN_CTAG_RX; - - netdev->vlan_features = NETIF_F_SG | NETIF_F_HIGHDMA | - NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | - NETIF_F_TSO | NETIF_F_TSO6; + netdev_hw_features_zero(netdev); + netdev_hw_features_set_array(netdev, &bnad_hw_feature_set); + netdev_vlan_features_zero(netdev); + netdev_vlan_features_set_array(netdev, &bnad_vlan_feature_set);
- netdev->features |= netdev->hw_features | NETIF_F_HW_VLAN_CTAG_FILTER | - NETIF_F_HIGHDMA; + netdev->features |= netdev->hw_features; + netdev_active_features_set_array(netdev, &bnad_feature_set);
netdev->mem_start = bnad->mmio_start; netdev->mem_end = bnad->mmio_start + bnad->mmio_len - 1; diff --git a/drivers/net/ethernet/calxeda/xgmac.c b/drivers/net/ethernet/calxeda/xgmac.c index 1281d1565ef8..415f61527650 100644 --- a/drivers/net/ethernet/calxeda/xgmac.c +++ b/drivers/net/ethernet/calxeda/xgmac.c @@ -14,6 +14,7 @@ #include <linux/if.h> #include <linux/crc32.h> #include <linux/dma-mapping.h> +#include <linux/netdev_features_helper.h> #include <linux/slab.h>
/* XGMAC Register definitions */ @@ -1682,6 +1683,14 @@ static const struct ethtool_ops xgmac_ethtool_ops = { .get_link_ksettings = xgmac_ethtool_get_link_ksettings, };
+static DECLARE_NETDEV_FEATURE_SET(xgmac_hw_feature_set, + NETIF_F_SG_BIT, + NETIF_F_HIGHDMA_BIT); +static DECLARE_NETDEV_FEATURE_SET(xgmac_csum_feature_set, + NETIF_F_IP_CSUM_BIT, + NETIF_F_IPV6_CSUM_BIT, + NETIF_F_RXCSUM_BIT); + /** * xgmac_probe * @pdev: platform device pointer @@ -1774,10 +1783,10 @@ static int xgmac_probe(struct platform_device *pdev) if (device_can_wakeup(priv->device)) priv->wolopts = WAKE_MAGIC; /* Magic Frame as default */
- ndev->hw_features = NETIF_F_SG | NETIF_F_HIGHDMA; + netdev_hw_features_zero(ndev); + netdev_hw_features_set_array(ndev, &xgmac_hw_feature_set); if (readl(priv->base + XGMAC_DMA_HW_FEATURE) & DMA_HW_FEAT_TXCOESEL) - ndev->hw_features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | - NETIF_F_RXCSUM; + netdev_hw_features_set_array(ndev, &xgmac_csum_feature_set); ndev->features |= ndev->hw_features; ndev->priv_flags |= IFF_UNICAST_FLT;
diff --git a/drivers/net/ethernet/cavium/liquidio/lio_main.c b/drivers/net/ethernet/cavium/liquidio/lio_main.c index bee35ce60171..9c9c8dee0c7b 100644 --- a/drivers/net/ethernet/cavium/liquidio/lio_main.c +++ b/drivers/net/ethernet/cavium/liquidio/lio_main.c @@ -19,6 +19,7 @@ #include <linux/interrupt.h> #include <linux/pci.h> #include <linux/firmware.h> +#include <linux/netdev_features_helper.h> #include <net/vxlan.h> #include <linux/kthread.h> #include "liquidio_common.h" @@ -3317,6 +3318,27 @@ static int lio_nic_info(struct octeon_recv_info *recv_info, void *buf) return 0; }
+static DECLARE_NETDEV_FEATURE_SET(liquidio_feature_set, + NETIF_F_HIGHDMA_BIT, + NETIF_F_IP_CSUM_BIT, + NETIF_F_IPV6_CSUM_BIT, + NETIF_F_SG_BIT, + NETIF_F_RXCSUM_BIT, + NETIF_F_GRO_BIT, + NETIF_F_TSO_BIT, + NETIF_F_TSO6_BIT, + NETIF_F_LRO_BIT); +static DECLARE_NETDEV_FEATURE_SET(liquidio_enc_feature_set, + NETIF_F_IP_CSUM_BIT, + NETIF_F_IPV6_CSUM_BIT, + NETIF_F_GSO_UDP_TUNNEL_BIT, + NETIF_F_HW_CSUM_BIT, + NETIF_F_SG_BIT, + NETIF_F_RXCSUM_BIT, + NETIF_F_TSO_BIT, + NETIF_F_TSO6_BIT, + NETIF_F_LRO_BIT); + /** * setup_nic_devices - Setup network interfaces * @octeon_dev: octeon device @@ -3555,26 +3577,18 @@ static int setup_nic_devices(struct octeon_device *octeon_dev)
if (OCTEON_CN23XX_PF(octeon_dev) || OCTEON_CN6XXX(octeon_dev)) { - lio->dev_capability = NETIF_F_HIGHDMA - | NETIF_F_IP_CSUM - | NETIF_F_IPV6_CSUM - | NETIF_F_SG | NETIF_F_RXCSUM - | NETIF_F_GRO - | NETIF_F_TSO | NETIF_F_TSO6 - | NETIF_F_LRO; + netdev_features_zero(&lio->dev_capability); + netdev_features_set_array(&liquidio_feature_set, + &lio->dev_capability); } netif_set_tso_max_size(netdev, OCTNIC_GSO_MAX_SIZE);
/* Copy of transmit encapsulation capabilities: * TSO, TSO6, Checksums for this device */ - lio->enc_dev_capability = NETIF_F_IP_CSUM - | NETIF_F_IPV6_CSUM - | NETIF_F_GSO_UDP_TUNNEL - | NETIF_F_HW_CSUM | NETIF_F_SG - | NETIF_F_RXCSUM - | NETIF_F_TSO | NETIF_F_TSO6 - | NETIF_F_LRO; + netdev_features_zero(&lio->enc_dev_capability); + netdev_features_set_array(&liquidio_enc_feature_set, + &lio->enc_dev_capability);
netdev->hw_enc_features = (lio->enc_dev_capability & ~NETIF_F_LRO); diff --git a/drivers/net/ethernet/cavium/liquidio/lio_vf_main.c b/drivers/net/ethernet/cavium/liquidio/lio_vf_main.c index ac196883f07e..9e0c176ea7af 100644 --- a/drivers/net/ethernet/cavium/liquidio/lio_vf_main.c +++ b/drivers/net/ethernet/cavium/liquidio/lio_vf_main.c @@ -18,6 +18,7 @@ #include <linux/module.h> #include <linux/interrupt.h> #include <linux/pci.h> +#include <linux/netdev_features_helper.h> #include <net/vxlan.h> #include "liquidio_common.h" #include "octeon_droq.h" @@ -1926,6 +1927,27 @@ static int lio_nic_info(struct octeon_recv_info *recv_info, void *buf) return 0; }
+static DECLARE_NETDEV_FEATURE_SET(lio_feature_set, + NETIF_F_HIGHDMA_BIT, + NETIF_F_IP_CSUM_BIT, + NETIF_F_IPV6_CSUM_BIT, + NETIF_F_SG_BIT, + NETIF_F_RXCSUM_BIT, + NETIF_F_TSO_BIT, + NETIF_F_TSO6_BIT, + NETIF_F_GRO_BIT, + NETIF_F_LRO_BIT); +static DECLARE_NETDEV_FEATURE_SET(lio_enc_feature_set, + NETIF_F_IP_CSUM_BIT, + NETIF_F_IPV6_CSUM_BIT, + NETIF_F_GSO_UDP_TUNNEL_BIT, + NETIF_F_HW_CSUM_BIT, + NETIF_F_SG_BIT, + NETIF_F_RXCSUM_BIT, + NETIF_F_TSO_BIT, + NETIF_F_TSO6_BIT, + NETIF_F_LRO_BIT); + /** * setup_nic_devices - Setup network interfaces * @octeon_dev: octeon device @@ -2088,24 +2110,16 @@ static int setup_nic_devices(struct octeon_device *octeon_dev)
lio->msg_enable = netif_msg_init(debug, DEFAULT_MSG_ENABLE);
- lio->dev_capability = NETIF_F_HIGHDMA - | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM - | NETIF_F_SG | NETIF_F_RXCSUM - | NETIF_F_TSO | NETIF_F_TSO6 - | NETIF_F_GRO - | NETIF_F_LRO; + netdev_features_zero(&lio->dev_capability); + netdev_features_set_array(&lio_feature_set, &lio->dev_capability); netif_set_tso_max_size(netdev, OCTNIC_GSO_MAX_SIZE);
/* Copy of transmit encapsulation capabilities: * TSO, TSO6, Checksums for this device */ - lio->enc_dev_capability = NETIF_F_IP_CSUM - | NETIF_F_IPV6_CSUM - | NETIF_F_GSO_UDP_TUNNEL - | NETIF_F_HW_CSUM | NETIF_F_SG - | NETIF_F_RXCSUM - | NETIF_F_TSO | NETIF_F_TSO6 - | NETIF_F_LRO; + netdev_features_zero(&lio->enc_dev_capability); + netdev_features_set_array(&lio_enc_feature_set, + &lio->enc_dev_capability);
netdev->hw_enc_features = (lio->enc_dev_capability & ~NETIF_F_LRO); diff --git a/drivers/net/ethernet/cavium/liquidio/octeon_network.h b/drivers/net/ethernet/cavium/liquidio/octeon_network.h index ebe56bd8849b..61e5e5782f5b 100644 --- a/drivers/net/ethernet/cavium/liquidio/octeon_network.h +++ b/drivers/net/ethernet/cavium/liquidio/octeon_network.h @@ -147,13 +147,13 @@ struct lio { u32 msg_enable;
/** Copy of Interface capabilities: TSO, TSO6, LRO, Chescksums . */ - u64 dev_capability; + netdev_features_t dev_capability;
/* Copy of transmit encapsulation capabilities: * TSO, TSO6, Checksums for this device for Kernel * 3.10.0 onwards */ - u64 enc_dev_capability; + netdev_features_t enc_dev_capability;
/** Copy of beacaon reg in phy */ u32 phy_beacon_val; diff --git a/drivers/net/ethernet/cavium/thunder/nicvf_main.c b/drivers/net/ethernet/cavium/thunder/nicvf_main.c index 768ea426d49f..c6923ecabb63 100644 --- a/drivers/net/ethernet/cavium/thunder/nicvf_main.c +++ b/drivers/net/ethernet/cavium/thunder/nicvf_main.c @@ -7,6 +7,7 @@ #include <linux/interrupt.h> #include <linux/pci.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/if_vlan.h> #include <linux/etherdevice.h> #include <linux/ethtool.h> @@ -2092,6 +2093,22 @@ static const struct net_device_ops nicvf_netdev_ops = { .ndo_set_rx_mode = nicvf_set_rx_mode, };
+static DECLARE_NETDEV_FEATURE_SET(nicvf_hw_feature_set, + NETIF_F_RXCSUM_BIT, + NETIF_F_SG_BIT, + NETIF_F_TSO_BIT, + NETIF_F_GRO_BIT, + NETIF_F_TSO6_BIT, + NETIF_F_IP_CSUM_BIT, + NETIF_F_IPV6_CSUM_BIT, + NETIF_F_HW_VLAN_CTAG_RX_BIT); +static DECLARE_NETDEV_FEATURE_SET(nicvf_vlan_feature_set, + NETIF_F_SG_BIT, + NETIF_F_IP_CSUM_BIT, + NETIF_F_IPV6_CSUM_BIT, + NETIF_F_TSO_BIT, + NETIF_F_TSO6_BIT); + static int nicvf_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { struct device *dev = &pdev->dev; @@ -2203,18 +2220,16 @@ static int nicvf_probe(struct pci_dev *pdev, const struct pci_device_id *ent) if (err) goto err_unregister_interrupts;
- netdev->hw_features = (NETIF_F_RXCSUM | NETIF_F_SG | - NETIF_F_TSO | NETIF_F_GRO | NETIF_F_TSO6 | - NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | - NETIF_F_HW_VLAN_CTAG_RX); + netdev_hw_features_zero(netdev); + netdev_hw_features_set_array(netdev, &nicvf_hw_feature_set);
netdev->hw_features |= NETIF_F_RXHASH;
netdev->features |= netdev->hw_features; netdev->hw_features |= NETIF_F_LOOPBACK;
- netdev->vlan_features = NETIF_F_SG | NETIF_F_IP_CSUM | - NETIF_F_IPV6_CSUM | NETIF_F_TSO | NETIF_F_TSO6; + netdev_vlan_features_zero(netdev); + netdev_hw_features_set_array(netdev, &nicvf_vlan_feature_set);
netdev->netdev_ops = &nicvf_netdev_ops; netdev->watchdog_timeo = NICVF_TX_TIMEOUT; diff --git a/drivers/net/ethernet/chelsio/cxgb/cxgb2.c b/drivers/net/ethernet/chelsio/cxgb/cxgb2.c index f4054d2553ea..44404b711e09 100644 --- a/drivers/net/ethernet/chelsio/cxgb/cxgb2.c +++ b/drivers/net/ethernet/chelsio/cxgb/cxgb2.c @@ -39,6 +39,7 @@ #include <linux/module.h> #include <linux/pci.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/etherdevice.h> #include <linux/if_vlan.h> #include <linux/mii.h> @@ -942,6 +943,18 @@ static const struct net_device_ops cxgb_netdev_ops = { #endif };
+static DECLARE_NETDEV_FEATURE_SET(cxgb_hw_feature_set, + NETIF_F_SG_BIT, + NETIF_F_IP_CSUM_BIT, + NETIF_F_RXCSUM_BIT); + +static DECLARE_NETDEV_FEATURE_SET(cxgb_feature_set, + NETIF_F_SG_BIT, + NETIF_F_IP_CSUM_BIT, + NETIF_F_RXCSUM_BIT, + NETIF_F_LLTX_BIT, + NETIF_F_HIGHDMA_BIT); + static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent) { unsigned long mmio_start, mmio_len; @@ -1031,10 +1044,8 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent) netdev->mem_start = mmio_start; netdev->mem_end = mmio_start + mmio_len - 1; netdev->ml_priv = adapter; - netdev->hw_features |= NETIF_F_SG | NETIF_F_IP_CSUM | - NETIF_F_RXCSUM; - netdev->features |= NETIF_F_SG | NETIF_F_IP_CSUM | - NETIF_F_RXCSUM | NETIF_F_LLTX | NETIF_F_HIGHDMA; + netdev_hw_features_set_array(netdev, &cxgb_hw_feature_set); + netdev_active_features_set_array(netdev, &cxgb_feature_set);
if (vlan_tso_capable(adapter)) { netdev->features |= diff --git a/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c b/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c index 174b1e156669..80f65f491b3f 100644 --- a/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c +++ b/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c @@ -37,6 +37,7 @@ #include <linux/pci.h> #include <linux/dma-mapping.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/etherdevice.h> #include <linux/if_vlan.h> #include <linux/mdio.h> @@ -3199,15 +3200,29 @@ static void cxgb3_init_iscsi_mac(struct net_device *dev) pi->iscsic.mac_addr[3] |= 0x80; }
-#define TSO_FLAGS (NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_TSO_ECN) -#define VLAN_FEAT (NETIF_F_SG | NETIF_F_IP_CSUM | TSO_FLAGS | \ - NETIF_F_IPV6_CSUM | NETIF_F_HIGHDMA) +static DECLARE_NETDEV_FEATURE_SET(cxgb_vlan_feature_set, + NETIF_F_SG_BIT, + NETIF_F_IP_CSUM_BIT, + NETIF_F_TSO_BIT, + NETIF_F_TSO6_BIT, + NETIF_F_TSO_ECN_BIT, + NETIF_F_IPV6_CSUM_BIT, + NETIF_F_HIGHDMA_BIT); + +static DECLARE_NETDEV_FEATURE_SET(cxgb_hw_feature_set, + NETIF_F_SG_BIT, + NETIF_F_IP_CSUM_BIT, + NETIF_F_TSO_BIT, + NETIF_F_RXCSUM_BIT, + NETIF_F_HW_VLAN_CTAG_RX_BIT); + static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent) { int i, err; resource_size_t mmio_start, mmio_len; const struct adapter_info *ai; struct adapter *adapter = NULL; + netdev_features_t vlan_feat; struct port_info *pi;
if (!cxgb3_wq) { @@ -3303,11 +3318,13 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent) netdev->irq = pdev->irq; netdev->mem_start = mmio_start; netdev->mem_end = mmio_start + mmio_len - 1; - netdev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | - NETIF_F_TSO | NETIF_F_RXCSUM | NETIF_F_HW_VLAN_CTAG_RX; + netdev_hw_features_zero(netdev); + netdev_hw_features_set_array(netdev, &cxgb_hw_feature_set); netdev->features |= netdev->hw_features | NETIF_F_HW_VLAN_CTAG_TX; - netdev->vlan_features |= netdev->features & VLAN_FEAT; + netdev_features_zero(&vlan_feat); + netdev_features_set_array(&cxgb_vlan_feature_set, &vlan_feat); + netdev->vlan_features |= netdev->features & vlan_feat;
netdev->features |= NETIF_F_HIGHDMA;
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c index d0061921529f..f40e6964de89 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c @@ -50,6 +50,7 @@ #include <linux/moduleparam.h> #include <linux/mutex.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/pci.h> #include <linux/aer.h> #include <linux/rtnetlink.h> @@ -6205,10 +6206,41 @@ static void free_some_resources(struct adapter *adapter) t4_fw_bye(adapter, adapter->pf); }
-#define TSO_FLAGS (NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_TSO_ECN | \ - NETIF_F_GSO_UDP_L4) -#define VLAN_FEAT (NETIF_F_SG | NETIF_F_IP_CSUM | TSO_FLAGS | \ - NETIF_F_GRO | NETIF_F_IPV6_CSUM | NETIF_F_HIGHDMA) +static DECLARE_NETDEV_FEATURE_SET(cxgb4_tso_feature_set, + NETIF_F_TSO_BIT, + NETIF_F_TSO6_BIT, + NETIF_F_TSO_ECN_BIT); +static DECLARE_NETDEV_FEATURE_SET(cxgb4_vlan_feature_set, + NETIF_F_SG_BIT, + NETIF_F_IP_CSUM_BIT, + NETIF_F_GRO_BIT, + NETIF_F_IPV6_CSUM_BIT, + NETIF_F_HIGHDMA_BIT); +static DECLARE_NETDEV_FEATURE_SET(cxgb4_hw_feature_set, + NETIF_F_SG_BIT, + NETIF_F_IP_CSUM_BIT, + NETIF_F_IPV6_CSUM_BIT, + NETIF_F_RXCSUM_BIT, + NETIF_F_RXHASH_BIT, + NETIF_F_GRO_BIT, + NETIF_F_HW_VLAN_CTAG_TX_BIT, + NETIF_F_HW_VLAN_CTAG_RX_BIT, + NETIF_F_HW_TC_BIT, + NETIF_F_NTUPLE_BIT, + NETIF_F_HIGHDMA_BIT); +static DECLARE_NETDEV_FEATURE_SET(cxgb4_hw_enc_feature_set, + NETIF_F_IP_CSUM_BIT, + NETIF_F_IPV6_CSUM_BIT, + NETIF_F_RXCSUM_BIT, + NETIF_F_GSO_UDP_TUNNEL_BIT, + NETIF_F_GSO_UDP_TUNNEL_CSUM_BIT, + NETIF_F_TSO_BIT, + NETIF_F_TSO6_BIT); +static DECLARE_NETDEV_FEATURE_SET(cxgb4_new_hw_feature_set, + NETIF_F_GSO_UDP_TUNNEL_BIT, + NETIF_F_GSO_UDP_TUNNEL_CSUM_BIT, + NETIF_F_HW_TLS_RECORD_BIT); + #define SEGMENT_SIZE 128
static int t4_get_chip_type(struct adapter *adap, int ver) @@ -6598,6 +6630,8 @@ static const struct xfrmdev_ops cxgb4_xfrmdev_ops = {
static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent) { + netdev_features_t vlan_features; + netdev_features_t tso_features; struct net_device *netdev; struct adapter *adapter; static int adap_idx = 1; @@ -6809,30 +6843,26 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent) pi->port_id = i; netdev->irq = pdev->irq;
- netdev->hw_features = NETIF_F_SG | TSO_FLAGS | - NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | - NETIF_F_RXCSUM | NETIF_F_RXHASH | NETIF_F_GRO | - NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX | - NETIF_F_HW_TC | NETIF_F_NTUPLE | NETIF_F_HIGHDMA; + netdev_features_zero(&tso_features); + netdev_features_set_array(&cxgb4_tso_feature_set, &tso_features); + netdev->hw_features = tso_features; + netdev_hw_features_set_array(netdev, &cxgb4_hw_feature_set);
if (chip_ver > CHELSIO_T5) { - netdev->hw_enc_features |= NETIF_F_IP_CSUM | - NETIF_F_IPV6_CSUM | - NETIF_F_RXCSUM | - NETIF_F_GSO_UDP_TUNNEL | - NETIF_F_GSO_UDP_TUNNEL_CSUM | - NETIF_F_TSO | NETIF_F_TSO6; + netdev_hw_enc_features_set_array(netdev, + &cxgb4_hw_enc_feature_set);
- netdev->hw_features |= NETIF_F_GSO_UDP_TUNNEL | - NETIF_F_GSO_UDP_TUNNEL_CSUM | - NETIF_F_HW_TLS_RECORD; + netdev_hw_features_set_array(netdev, + &cxgb4_new_hw_feature_set);
if (adapter->rawf_cnt) netdev->udp_tunnel_nic_info = &cxgb_udp_tunnels; }
netdev->features |= netdev->hw_features; - netdev->vlan_features = netdev->features & VLAN_FEAT; + vlan_features = tso_features; + netdev_features_set_array(&cxgb4_vlan_feature_set, &vlan_features); + netdev->vlan_features = netdev->features & vlan_features; #if IS_ENABLED(CONFIG_CHELSIO_TLS_DEVICE) if (pi->adapter->params.crypto & FW_CAPS_CONFIG_TLS_HW) { netdev->hw_features |= NETIF_F_HW_TLS_TX; diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c index c2822e635f89..2d6e1b42b36b 100644 --- a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c @@ -41,6 +41,7 @@ #include <linux/pci.h> #include <linux/dma-mapping.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/etherdevice.h> #include <linux/debugfs.h> #include <linux/ethtool.h> @@ -1921,9 +1922,26 @@ static void cxgb4vf_get_wol(struct net_device *dev, /* * TCP Segmentation Offload flags which we support. */ -#define TSO_FLAGS (NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_TSO_ECN) -#define VLAN_FEAT (NETIF_F_SG | NETIF_F_IP_CSUM | TSO_FLAGS | \ - NETIF_F_GRO | NETIF_F_IPV6_CSUM | NETIF_F_HIGHDMA) +static DECLARE_NETDEV_FEATURE_SET(cxgb4vf_tso_feature_set, + NETIF_F_TSO_BIT, + NETIF_F_TSO6_BIT, + NETIF_F_TSO_ECN_BIT); + +static DECLARE_NETDEV_FEATURE_SET(cxgb4vf_vlan_feature_set, + NETIF_F_SG_BIT, + NETIF_F_IP_CSUM_BIT, + NETIF_F_GRO_BIT, + NETIF_F_IPV6_CSUM_BIT, + NETIF_F_HIGHDMA_BIT); + +static DECLARE_NETDEV_FEATURE_SET(cxgb4vf_hw_feature_set, + NETIF_F_SG_BIT, + NETIF_F_GRO_BIT, + NETIF_F_IP_CSUM_BIT, + NETIF_F_IPV6_CSUM_BIT, + NETIF_F_RXCSUM_BIT, + NETIF_F_HW_VLAN_CTAG_TX_BIT, + NETIF_F_HW_VLAN_CTAG_RX_BIT);
static const struct ethtool_ops cxgb4vf_ethtool_ops = { .supported_coalesce_params = ETHTOOL_COALESCE_RX_USECS | @@ -2895,6 +2913,8 @@ static unsigned int cxgb4vf_get_port_mask(struct adapter *adapter) static int cxgb4vf_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { + netdev_features_t vlan_features; + netdev_features_t tso_features; struct adapter *adapter; struct net_device *netdev; struct port_info *pi; @@ -3067,11 +3087,16 @@ static int cxgb4vf_pci_probe(struct pci_dev *pdev, pi->xact_addr_filt = -1; netdev->irq = pdev->irq;
- netdev->hw_features = NETIF_F_SG | TSO_FLAGS | NETIF_F_GRO | - NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | NETIF_F_RXCSUM | - NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX; + netdev_features_zero(&tso_features); + netdev_features_set_array(&cxgb4vf_tso_feature_set, + &tso_features); + netdev->hw_features = tso_features; + netdev_hw_features_set_array(netdev, &cxgb4vf_hw_feature_set); netdev->features = netdev->hw_features | NETIF_F_HIGHDMA; - netdev->vlan_features = netdev->features & VLAN_FEAT; + vlan_features = tso_features; + netdev_features_set_array(&cxgb4vf_vlan_feature_set, + &vlan_features); + netdev->vlan_features = netdev->features & vlan_features;
netdev->priv_flags |= IFF_UNICAST_FLT; netdev->min_mtu = 81; diff --git a/drivers/net/ethernet/cirrus/ep93xx_eth.c b/drivers/net/ethernet/cirrus/ep93xx_eth.c index 21ba6e893072..8d631b2cba23 100644 --- a/drivers/net/ethernet/cirrus/ep93xx_eth.c +++ b/drivers/net/ethernet/cirrus/ep93xx_eth.c @@ -11,6 +11,7 @@ #include <linux/module.h> #include <linux/kernel.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/mii.h> #include <linux/etherdevice.h> #include <linux/ethtool.h> @@ -738,6 +739,10 @@ static const struct net_device_ops ep93xx_netdev_ops = { .ndo_set_mac_address = eth_mac_addr, };
+static DECLARE_NETDEV_FEATURE_SET(ep93xx_feature_set, + NETIF_F_SG_BIT, + NETIF_F_HW_CSUM_BIT); + static struct net_device *ep93xx_dev_alloc(struct ep93xx_eth_data *data) { struct net_device *dev; @@ -751,7 +756,7 @@ static struct net_device *ep93xx_dev_alloc(struct ep93xx_eth_data *data) dev->ethtool_ops = &ep93xx_ethtool_ops; dev->netdev_ops = &ep93xx_netdev_ops;
- dev->features |= NETIF_F_SG | NETIF_F_HW_CSUM; + netdev_active_features_set_array(dev, &ep93xx_feature_set);
return dev; } diff --git a/drivers/net/ethernet/cisco/enic/enic_main.c b/drivers/net/ethernet/cisco/enic/enic_main.c index 372fb7b3a282..276fa370ce50 100644 --- a/drivers/net/ethernet/cisco/enic/enic_main.c +++ b/drivers/net/ethernet/cisco/enic/enic_main.c @@ -27,6 +27,7 @@ #include <linux/workqueue.h> #include <linux/pci.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/etherdevice.h> #include <linux/if.h> #include <linux/if_ether.h> @@ -2665,6 +2666,15 @@ static void enic_iounmap(struct enic *enic) iounmap(enic->bar[i].vaddr); }
+static DECLARE_NETDEV_FEATURE_SET(enic_hw_enc_feature_set, + NETIF_F_RXCSUM_BIT, + NETIF_F_TSO_BIT, + NETIF_F_TSO6_BIT, + NETIF_F_TSO_ECN_BIT, + NETIF_F_GSO_UDP_TUNNEL_BIT, + NETIF_F_HW_CSUM_BIT, + NETIF_F_GSO_UDP_TUNNEL_CSUM_BIT); + static int enic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { struct device *dev = &pdev->dev; @@ -2904,13 +2914,8 @@ static int enic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) u64 patch_level; u64 a1 = 0;
- netdev->hw_enc_features |= NETIF_F_RXCSUM | - NETIF_F_TSO | - NETIF_F_TSO6 | - NETIF_F_TSO_ECN | - NETIF_F_GSO_UDP_TUNNEL | - NETIF_F_HW_CSUM | - NETIF_F_GSO_UDP_TUNNEL_CSUM; + netdev_hw_enc_features_set_array(netdev, + &enic_hw_enc_feature_set); netdev->hw_features |= netdev->hw_enc_features; /* get bit mask from hw about supported offload bit level * BIT(0) = fw supports patch_level 0 diff --git a/drivers/net/ethernet/cortina/gemini.c b/drivers/net/ethernet/cortina/gemini.c index 9e6de2f968fa..d2b0296b426a 100644 --- a/drivers/net/ethernet/cortina/gemini.c +++ b/drivers/net/ethernet/cortina/gemini.c @@ -36,6 +36,7 @@ #include <linux/ethtool.h> #include <linux/tcp.h> #include <linux/u64_stats_sync.h> +#include <linux/netdev_features_helper.h>
#include <linux/in.h> #include <linux/ip.h> @@ -78,9 +79,16 @@ MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)"); GMAC0_SWTQ00_FIN_INT_BIT) #define GMAC0_IRQ4_8 (GMAC0_MIB_INT_BIT | GMAC0_RX_OVERRUN_INT_BIT)
-#define GMAC_OFFLOAD_FEATURES (NETIF_F_SG | NETIF_F_IP_CSUM | \ - NETIF_F_IPV6_CSUM | NETIF_F_RXCSUM | \ - NETIF_F_TSO | NETIF_F_TSO_ECN | NETIF_F_TSO6) +static DECLARE_NETDEV_FEATURE_SET(gmac_offload_feature_set, + NETIF_F_SG_BIT, + NETIF_F_IP_CSUM_BIT, + NETIF_F_IPV6_CSUM_BIT, + NETIF_F_RXCSUM_BIT, + NETIF_F_TSO_BIT, + NETIF_F_TSO_ECN_BIT, + NETIF_F_TSO6_BIT); +static netdev_features_t gmac_offload_features __ro_after_init; +#define GMAC_OFFLOAD_FEATURES gmac_offload_features
/** * struct gmac_queue_page - page buffer per-page info @@ -2610,6 +2618,12 @@ static struct platform_driver gemini_ethernet_driver = { .remove = gemini_ethernet_remove, };
+static void __init gmac_netdev_features_init(void) +{ + netdev_features_set_array(&gmac_offload_feature_set, + &gmac_offload_features); +} + static int __init gemini_ethernet_module_init(void) { int ret; @@ -2624,6 +2638,8 @@ static int __init gemini_ethernet_module_init(void) return ret; }
+ gmac_netdev_features_init(); + return 0; } module_init(gemini_ethernet_module_init); diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c index 414362febbb9..964e7d6111df 100644 --- a/drivers/net/ethernet/emulex/benet/be_main.c +++ b/drivers/net/ethernet/emulex/benet/be_main.c @@ -18,6 +18,7 @@ #include <asm/div64.h> #include <linux/aer.h> #include <linux/if_bridge.h> +#include <linux/netdev_features_helper.h> #include <net/busy_poll.h> #include <net/vxlan.h>
@@ -3967,6 +3968,13 @@ static void be_cancel_err_detection(struct be_adapter *adapter) } }
+DECLARE_NETDEV_FEATURE_SET(be_hw_enc_feature_set, + NETIF_F_IP_CSUM_BIT, + NETIF_F_IPV6_CSUM_BIT, + NETIF_F_TSO_BIT, + NETIF_F_TSO6_BIT, + NETIF_F_GSO_UDP_TUNNEL_BIT); + /* VxLAN offload Notes: * * The stack defines tunnel offload flags (hw_enc_features) for IP and doesn't @@ -3999,9 +4007,7 @@ static int be_vxlan_set_port(struct net_device *netdev, unsigned int table, } adapter->vxlan_port = ti->port;
- netdev->hw_enc_features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | - NETIF_F_TSO | NETIF_F_TSO6 | - NETIF_F_GSO_UDP_TUNNEL; + netdev_hw_enc_features_set_array(netdev, &be_hw_enc_feature_set);
dev_info(dev, "Enabled VxLAN offloads for UDP port %d\n", be16_to_cpu(ti->port)); @@ -5182,23 +5188,40 @@ static const struct net_device_ops be_netdev_ops = { .ndo_get_phys_port_id = be_get_phys_port_id, };
+static DECLARE_NETDEV_FEATURE_SET(be_hw_feature_set, + NETIF_F_SG_BIT, + NETIF_F_TSO_BIT, + NETIF_F_TSO6_BIT, + NETIF_F_GSO_UDP_TUNNEL_BIT, + NETIF_F_IP_CSUM_BIT, + NETIF_F_IPV6_CSUM_BIT, + NETIF_F_RXCSUM_BIT, + NETIF_F_HW_VLAN_CTAG_TX_BIT); + +static DECLARE_NETDEV_FEATURE_SET(be_feature_set, + NETIF_F_HW_VLAN_CTAG_RX_BIT, + NETIF_F_HW_VLAN_CTAG_FILTER_BIT, + NETIF_F_HIGHDMA_BIT); + +static DECLARE_NETDEV_FEATURE_SET(be_vlan_feature_set, + NETIF_F_SG_BIT, + NETIF_F_TSO_BIT, + NETIF_F_TSO6_BIT, + NETIF_F_IP_CSUM_BIT, + NETIF_F_IPV6_CSUM_BIT); + static void be_netdev_init(struct net_device *netdev) { struct be_adapter *adapter = netdev_priv(netdev);
- netdev->hw_features |= NETIF_F_SG | NETIF_F_TSO | NETIF_F_TSO6 | - NETIF_F_GSO_UDP_TUNNEL | - NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | NETIF_F_RXCSUM | - NETIF_F_HW_VLAN_CTAG_TX; + netdev_hw_features_set_array(netdev, &be_hw_feature_set); if ((be_if_cap_flags(adapter) & BE_IF_FLAGS_RSS)) netdev->hw_features |= NETIF_F_RXHASH;
- netdev->features |= netdev->hw_features | - NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_HW_VLAN_CTAG_FILTER | - NETIF_F_HIGHDMA; + netdev->features |= netdev->hw_features; + netdev_active_features_set_array(netdev, &be_feature_set);
- netdev->vlan_features |= NETIF_F_SG | NETIF_F_TSO | NETIF_F_TSO6 | - NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM; + netdev_vlan_features_set_array(netdev, &be_vlan_feature_set);
netdev->priv_flags |= IFF_UNICAST_FLT;
diff --git a/drivers/net/ethernet/faraday/ftgmac100.c b/drivers/net/ethernet/faraday/ftgmac100.c index c03663785a8d..8c95ad9df5e5 100644 --- a/drivers/net/ethernet/faraday/ftgmac100.c +++ b/drivers/net/ethernet/faraday/ftgmac100.c @@ -1777,6 +1777,14 @@ static bool ftgmac100_has_child_node(struct device_node *np, const char *name) return ret; }
+static DECLARE_NETDEV_FEATURE_SET(ftgmac100_hw_feature_set, + NETIF_F_RXCSUM_BIT, + NETIF_F_HW_CSUM_BIT, + NETIF_F_GRO_BIT, + NETIF_F_SG_BIT, + NETIF_F_HW_VLAN_CTAG_RX_BIT, + NETIF_F_HW_VLAN_CTAG_TX_BIT); + static int ftgmac100_probe(struct platform_device *pdev) { struct resource *res; @@ -1931,9 +1939,8 @@ static int ftgmac100_probe(struct platform_device *pdev) priv->tx_q_entries = priv->new_tx_q_entries = DEF_TX_QUEUE_ENTRIES;
/* Base feature set */ - netdev->hw_features = NETIF_F_RXCSUM | NETIF_F_HW_CSUM | - NETIF_F_GRO | NETIF_F_SG | NETIF_F_HW_VLAN_CTAG_RX | - NETIF_F_HW_VLAN_CTAG_TX; + netdev_hw_features_zero(netdev); + netdev_hw_features_set_array(netdev, &ftgmac100_hw_feature_set);
if (priv->use_ncsi) netdev->hw_features |= NETIF_F_HW_VLAN_CTAG_FILTER; diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c index 45634579adb6..545e2b1afad7 100644 --- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c +++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c @@ -20,6 +20,7 @@ #include <linux/udp.h> #include <linux/tcp.h> #include <linux/net.h> +#include <linux/netdev_features_helper.h> #include <linux/skbuff.h> #include <linux/etherdevice.h> #include <linux/if_ether.h> @@ -197,6 +198,14 @@ static int dpaa_rx_extra_headroom; #define dpaa_get_max_mtu() \ (dpaa_max_frm - (VLAN_ETH_HLEN + ETH_FCS_LEN))
+static DECLARE_NETDEV_FEATURE_SET(dpaa_hw_feature_set, + NETIF_F_IP_CSUM_BIT, + NETIF_F_IPV6_CSUM_BIT, + NETIF_F_LLTX_BIT, + NETIF_F_RXHASH_BIT, + NETIF_F_SG_BIT, + NETIF_F_HIGHDMA_BIT); + static int dpaa_netdev_init(struct net_device *net_dev, const struct net_device_ops *dpaa_ops, u16 tx_timeout) @@ -224,10 +233,7 @@ static int dpaa_netdev_init(struct net_device *net_dev, net_dev->min_mtu = ETH_MIN_MTU; net_dev->max_mtu = dpaa_get_max_mtu();
- net_dev->hw_features |= (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | - NETIF_F_LLTX | NETIF_F_RXHASH); - - net_dev->hw_features |= NETIF_F_SG | NETIF_F_HIGHDMA; + netdev_hw_features_set_array(net_dev, &dpaa_hw_feature_set); /* The kernels enables GSO automatically, if we declare NETIF_F_SG. * For conformity, we'll still declare GSO explicitly. */ diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c index cd9ec80522e7..d3c51e1a7c82 100644 --- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c +++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c @@ -9,6 +9,7 @@ #include <linux/of_net.h> #include <linux/interrupt.h> #include <linux/msi.h> +#include <linux/netdev_features_helper.h> #include <linux/kthread.h> #include <linux/iommu.h> #include <linux/fsl/mc.h> @@ -4327,6 +4328,16 @@ static int dpaa2_eth_set_mac_addr(struct dpaa2_eth_priv *priv) return 0; }
+static DECLARE_NETDEV_FEATURE_SET(dpaa2_feature_set, + NETIF_F_RXCSUM_BIT, + NETIF_F_IP_CSUM_BIT, + NETIF_F_IPV6_CSUM_BIT, + NETIF_F_SG_BIT, + NETIF_F_HIGHDMA_BIT, + NETIF_F_LLTX_BIT, + NETIF_F_HW_TC_BIT, + NETIF_F_TSO_BIT); + static int dpaa2_eth_netdev_init(struct net_device *net_dev) { struct device *dev = net_dev->dev.parent; @@ -4388,10 +4399,8 @@ static int dpaa2_eth_netdev_init(struct net_device *net_dev) net_dev->priv_flags &= ~not_supported;
/* Features */ - net_dev->features = NETIF_F_RXCSUM | - NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | - NETIF_F_SG | NETIF_F_HIGHDMA | - NETIF_F_LLTX | NETIF_F_HW_TC | NETIF_F_TSO; + netdev_active_features_zero(net_dev); + netdev_active_features_set_array(net_dev, &dpaa2_feature_set); net_dev->gso_max_segs = DPAA2_ETH_ENQUEUE_MAX_FDS; net_dev->hw_features = net_dev->features;
diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c index e507e9065214..87ae011633ba 100644 --- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c +++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c @@ -3238,6 +3238,11 @@ static int dpaa2_switch_remove(struct fsl_mc_device *sw_dev) return 0; }
+static DECLARE_NETDEV_FEATURE_SET(dpaa2_feature_set, + NETIF_F_HW_VLAN_CTAG_FILTER_BIT, + NETIF_F_HW_VLAN_STAG_FILTER_BIT, + NETIF_F_HW_TC_BIT); + static int dpaa2_switch_probe_port(struct ethsw_core *ethsw, u16 port_idx) { @@ -3280,9 +3285,8 @@ static int dpaa2_switch_probe_port(struct ethsw_core *ethsw, /* The DPAA2 switch's ingress path depends on the VLAN table, * thus we are not able to disable VLAN filtering. */ - port_netdev->features = NETIF_F_HW_VLAN_CTAG_FILTER | - NETIF_F_HW_VLAN_STAG_FILTER | - NETIF_F_HW_TC; + netdev_active_features_zero(port_netdev); + netdev_active_features_set_array(port_netdev, &dpaa2_feature_set);
err = dpaa2_switch_port_init(port_priv, port_idx); if (err) diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.h b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.h index 0002dca4d417..e7d92ac769e9 100644 --- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.h +++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.h @@ -11,6 +11,7 @@ #define __ETHSW_H
#include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/etherdevice.h> #include <linux/rtnetlink.h> #include <linux/if_vlan.h> diff --git a/drivers/net/ethernet/freescale/enetc/enetc_pf.c b/drivers/net/ethernet/freescale/enetc/enetc_pf.c index c4a0e836d4f0..b8daac778c64 100644 --- a/drivers/net/ethernet/freescale/enetc/enetc_pf.c +++ b/drivers/net/ethernet/freescale/enetc/enetc_pf.c @@ -4,6 +4,7 @@ #include <asm/unaligned.h> #include <linux/mdio.h> #include <linux/module.h> +#include <linux/netdev_features_helper.h> #include <linux/fsl/enetc_mdio.h> #include <linux/of_platform.h> #include <linux/of_mdio.h> @@ -744,6 +745,31 @@ static const struct net_device_ops enetc_ndev_ops = { .ndo_xdp_xmit = enetc_xdp_xmit, };
+static DECLARE_NETDEV_FEATURE_SET(enetc_hw_feature_set, + NETIF_F_SG_BIT, + NETIF_F_RXCSUM_BIT, + NETIF_F_HW_VLAN_CTAG_TX_BIT, + NETIF_F_HW_VLAN_CTAG_RX_BIT, + NETIF_F_HW_VLAN_CTAG_FILTER_BIT, + NETIF_F_LOOPBACK_BIT, + NETIF_F_HW_CSUM_BIT, + NETIF_F_TSO_BIT, + NETIF_F_TSO6_BIT); +static DECLARE_NETDEV_FEATURE_SET(enetc_feature_set, + NETIF_F_HIGHDMA_BIT, + NETIF_F_SG_BIT, + NETIF_F_RXCSUM_BIT, + NETIF_F_HW_VLAN_CTAG_TX_BIT, + NETIF_F_HW_VLAN_CTAG_RX_BIT, + NETIF_F_HW_CSUM_BIT, + NETIF_F_TSO_BIT, + NETIF_F_TSO6_BIT); +static DECLARE_NETDEV_FEATURE_SET(enetc_vlan_feature_set, + NETIF_F_SG_BIT, + NETIF_F_HW_CSUM_BIT, + NETIF_F_TSO_BIT, + NETIF_F_TSO6_BIT); + static void enetc_pf_netdev_setup(struct enetc_si *si, struct net_device *ndev, const struct net_device_ops *ndev_ops) { @@ -761,16 +787,12 @@ static void enetc_pf_netdev_setup(struct enetc_si *si, struct net_device *ndev, ndev->watchdog_timeo = 5 * HZ; ndev->max_mtu = ENETC_MAX_MTU;
- ndev->hw_features = NETIF_F_SG | NETIF_F_RXCSUM | - NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX | - NETIF_F_HW_VLAN_CTAG_FILTER | NETIF_F_LOOPBACK | - NETIF_F_HW_CSUM | NETIF_F_TSO | NETIF_F_TSO6; - ndev->features = NETIF_F_HIGHDMA | NETIF_F_SG | NETIF_F_RXCSUM | - NETIF_F_HW_VLAN_CTAG_TX | - NETIF_F_HW_VLAN_CTAG_RX | - NETIF_F_HW_CSUM | NETIF_F_TSO | NETIF_F_TSO6; - ndev->vlan_features = NETIF_F_SG | NETIF_F_HW_CSUM | - NETIF_F_TSO | NETIF_F_TSO6; + netdev_hw_features_zero(ndev); + netdev_hw_features_set_array(ndev, &enetc_hw_feature_set); + netdev_active_features_zero(ndev); + netdev_active_features_set_array(ndev, &enetc_feature_set); + netdev_vlan_features_zero(ndev); + netdev_vlan_features_set_array(ndev, &enetc_vlan_feature_set);
if (si->num_rss) ndev->hw_features |= NETIF_F_RXHASH; diff --git a/drivers/net/ethernet/freescale/enetc/enetc_vf.c b/drivers/net/ethernet/freescale/enetc/enetc_vf.c index 17924305afa2..a4eab1e1e590 100644 --- a/drivers/net/ethernet/freescale/enetc/enetc_vf.c +++ b/drivers/net/ethernet/freescale/enetc/enetc_vf.c @@ -2,6 +2,7 @@ /* Copyright 2017-2019 NXP */
#include <linux/module.h> +#include <linux/netdev_features_helper.h> #include "enetc.h"
#define ENETC_DRV_NAME_STR "ENETC VF driver" @@ -103,6 +104,29 @@ static const struct net_device_ops enetc_ndev_ops = { .ndo_setup_tc = enetc_setup_tc, };
+static DECLARE_NETDEV_FEATURE_SET(enetc_vf_hw_feature_set, + NETIF_F_SG_BIT, + NETIF_F_RXCSUM_BIT, + NETIF_F_HW_VLAN_CTAG_TX_BIT, + NETIF_F_HW_VLAN_CTAG_RX_BIT, + NETIF_F_HW_CSUM_BIT, + NETIF_F_TSO_BIT, + NETIF_F_TSO6_BIT); +static DECLARE_NETDEV_FEATURE_SET(enetc_vf_feature_set, + NETIF_F_HIGHDMA_BIT, + NETIF_F_SG_BIT, + NETIF_F_RXCSUM_BIT, + NETIF_F_HW_VLAN_CTAG_TX_BIT, + NETIF_F_HW_VLAN_CTAG_RX_BIT, + NETIF_F_HW_CSUM_BIT, + NETIF_F_TSO_BIT, + NETIF_F_TSO6_BIT); +static DECLARE_NETDEV_FEATURE_SET(enetc_vf_vlan_feature_set, + NETIF_F_SG_BIT, + NETIF_F_HW_CSUM_BIT, + NETIF_F_TSO_BIT, + NETIF_F_TSO6_BIT); + static void enetc_vf_netdev_setup(struct enetc_si *si, struct net_device *ndev, const struct net_device_ops *ndev_ops) { @@ -120,16 +144,12 @@ static void enetc_vf_netdev_setup(struct enetc_si *si, struct net_device *ndev, ndev->watchdog_timeo = 5 * HZ; ndev->max_mtu = ENETC_MAX_MTU;
- ndev->hw_features = NETIF_F_SG | NETIF_F_RXCSUM | - NETIF_F_HW_VLAN_CTAG_TX | - NETIF_F_HW_VLAN_CTAG_RX | - NETIF_F_HW_CSUM | NETIF_F_TSO | NETIF_F_TSO6; - ndev->features = NETIF_F_HIGHDMA | NETIF_F_SG | NETIF_F_RXCSUM | - NETIF_F_HW_VLAN_CTAG_TX | - NETIF_F_HW_VLAN_CTAG_RX | - NETIF_F_HW_CSUM | NETIF_F_TSO | NETIF_F_TSO6; - ndev->vlan_features = NETIF_F_SG | NETIF_F_HW_CSUM | - NETIF_F_TSO | NETIF_F_TSO6; + netdev_hw_features_zero(ndev); + netdev_hw_features_set_array(ndev, &enetc_vf_hw_feature_set); + netdev_active_features_zero(ndev); + netdev_active_features_set_array(ndev, &enetc_vf_feature_set); + netdev_vlan_features_zero(ndev); + netdev_vlan_features_set_array(ndev, &enetc_vf_vlan_feature_set);
if (si->num_rss) ndev->hw_features |= NETIF_F_RXHASH; diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c index e8e2aa1e7f01..49850ee91d4e 100644 --- a/drivers/net/ethernet/freescale/fec_main.c +++ b/drivers/net/ethernet/freescale/fec_main.c @@ -33,6 +33,7 @@ #include <linux/interrupt.h> #include <linux/delay.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/etherdevice.h> #include <linux/skbuff.h> #include <linux/in.h> @@ -3465,6 +3466,13 @@ static const unsigned short offset_des_active_txq[] = { FEC_X_DES_ACTIVE_0, FEC_X_DES_ACTIVE_1, FEC_X_DES_ACTIVE_2 };
+static DECLARE_NETDEV_FEATURE_SET(fec_feature_set, + NETIF_F_IP_CSUM_BIT, + NETIF_F_IPV6_CSUM_BIT, + NETIF_F_RXCSUM_BIT, + NETIF_F_SG_BIT, + NETIF_F_TSO_BIT); + /* * XXX: We need to clean up on failure exits here. * @@ -3569,8 +3577,7 @@ static int fec_enet_init(struct net_device *ndev) netif_set_tso_max_segs(ndev, FEC_MAX_TSO_SEGS);
/* enable hw accelerator */ - ndev->features |= (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM - | NETIF_F_RXCSUM | NETIF_F_SG | NETIF_F_TSO); + netdev_active_features_set_array(ndev, &fec_feature_set); fep->csum_flags |= FLAG_RX_CSUM_ENABLED; }
diff --git a/drivers/net/ethernet/freescale/gianfar.c b/drivers/net/ethernet/freescale/gianfar.c index e7bf1524b68e..72a1842794a7 100644 --- a/drivers/net/ethernet/freescale/gianfar.c +++ b/drivers/net/ethernet/freescale/gianfar.c @@ -67,6 +67,7 @@ #include <linux/interrupt.h> #include <linux/delay.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/etherdevice.h> #include <linux/skbuff.h> #include <linux/if_vlan.h> @@ -3191,6 +3192,16 @@ static const struct net_device_ops gfar_netdev_ops = { #endif };
+static DECLARE_NETDEV_FEATURE_SET(gfar_hw_feature_set, + NETIF_F_IP_CSUM_BIT, + NETIF_F_SG_BIT, + NETIF_F_RXCSUM_BIT); +static DECLARE_NETDEV_FEATURE_SET(gfar_feature_set, + NETIF_F_IP_CSUM_BIT, + NETIF_F_SG_BIT, + NETIF_F_RXCSUM_BIT, + NETIF_F_HIGHDMA_BIT); + /* Set up the ethernet device structure, private data, * and anything else we need before we start */ @@ -3239,10 +3250,9 @@ static int gfar_probe(struct platform_device *ofdev) }
if (priv->device_flags & FSL_GIANFAR_DEV_HAS_CSUM) { - dev->hw_features = NETIF_F_IP_CSUM | NETIF_F_SG | - NETIF_F_RXCSUM; - dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG | - NETIF_F_RXCSUM | NETIF_F_HIGHDMA; + netdev_hw_features_zero(dev); + netdev_hw_features_set_array(dev, &gfar_hw_feature_set); + netdev_active_features_set_array(dev, &gfar_feature_set); }
if (priv->device_flags & FSL_GIANFAR_DEV_HAS_VLAN) { diff --git a/drivers/net/ethernet/fungible/funeth/funeth_main.c b/drivers/net/ethernet/fungible/funeth/funeth_main.c index f247b7ad3a88..537daf19f7f6 100644 --- a/drivers/net/ethernet/fungible/funeth/funeth_main.c +++ b/drivers/net/ethernet/fungible/funeth/funeth_main.c @@ -9,6 +9,7 @@ #include <linux/if_vlan.h> #include <linux/module.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/pci.h> #include <linux/rtnetlink.h> #include <linux/inetdevice.h> @@ -1354,14 +1355,6 @@ static const struct net_device_ops fun_netdev_ops = { .ndo_get_devlink_port = fun_get_devlink_port, };
-#define GSO_ENCAP_FLAGS (NETIF_F_GSO_GRE | NETIF_F_GSO_IPXIP4 | \ - NETIF_F_GSO_IPXIP6 | NETIF_F_GSO_UDP_TUNNEL | \ - NETIF_F_GSO_UDP_TUNNEL_CSUM) -#define TSO_FLAGS (NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_TSO_ECN | \ - NETIF_F_GSO_UDP_L4) -#define VLAN_FEAT (NETIF_F_SG | NETIF_F_HW_CSUM | TSO_FLAGS | \ - GSO_ENCAP_FLAGS | NETIF_F_HIGHDMA) - static void fun_dflt_rss_indir(struct funeth_priv *fp, unsigned int nrx) { unsigned int i; @@ -1708,9 +1701,35 @@ int fun_change_num_queues(struct net_device *dev, unsigned int ntx, return err; }
+static DECLARE_NETDEV_FEATURE_SET(fun_hw_feature_set, + NETIF_F_SG_BIT, + NETIF_F_RXHASH_BIT, + NETIF_F_RXCSUM_BIT); + +static DECLARE_NETDEV_FEATURE_SET(fun_gso_encap_feature_set, + NETIF_F_GSO_GRE_BIT, + NETIF_F_GSO_IPXIP4_BIT, + NETIF_F_GSO_IPXIP6_BIT, + NETIF_F_GSO_UDP_TUNNEL_BIT, + NETIF_F_GSO_UDP_TUNNEL_CSUM_BIT); + +static DECLARE_NETDEV_FEATURE_SET(fun_tso_feature_set, + NETIF_F_TSO_BIT, + NETIF_F_TSO6_BIT, + NETIF_F_TSO_ECN_BIT, + NETIF_F_GSO_UDP_L4_BIT); + +static DECLARE_NETDEV_FEATURE_SET(fun_vlan_feature_set, + NETIF_F_SG_BIT, + NETIF_F_HW_CSUM_BIT, + NETIF_F_HIGHDMA_BIT); + static int fun_create_netdev(struct fun_ethdev *ed, unsigned int portid) { + netdev_features_t gso_encap_flags = netdev_empty_features; + netdev_features_t tso_flags = netdev_empty_features; struct fun_dev *fdev = &ed->fdev; + netdev_features_t vlan_feat; struct net_device *netdev; struct funeth_priv *fp; unsigned int ntx, nrx; @@ -1763,14 +1782,19 @@ static int fun_create_netdev(struct fun_ethdev *ed, unsigned int portid) SET_NETDEV_DEV(netdev, fdev->dev); netdev->netdev_ops = &fun_netdev_ops;
- netdev->hw_features = NETIF_F_SG | NETIF_F_RXHASH | NETIF_F_RXCSUM; + netdev_features_set_array(&fun_gso_encap_feature_set, &gso_encap_flags); + netdev_features_set_array(&fun_tso_feature_set, &tso_flags); + vlan_feat = gso_encap_flags | tso_flags; + netdev_features_set_array(&fun_vlan_feature_set, &vlan_feat); + + netdev_hw_features_set_array(netdev, &fun_hw_feature_set); if (fp->port_caps & FUN_PORT_CAP_OFFLOADS) - netdev->hw_features |= NETIF_F_HW_CSUM | TSO_FLAGS; + netdev->hw_features |= NETIF_F_HW_CSUM | tso_flags; if (fp->port_caps & FUN_PORT_CAP_ENCAP_OFFLOADS) - netdev->hw_features |= GSO_ENCAP_FLAGS; + netdev->hw_features |= gso_encap_flags;
netdev->features |= netdev->hw_features | NETIF_F_HIGHDMA; - netdev->vlan_features = netdev->features & VLAN_FEAT; + netdev->vlan_features = netdev->features & vlan_feat; netdev->mpls_features = netdev->vlan_features; netdev->hw_enc_features = netdev->hw_features;
diff --git a/drivers/net/ethernet/google/gve/gve_main.c b/drivers/net/ethernet/google/gve/gve_main.c index 6cafee55efc3..357e2d9cd740 100644 --- a/drivers/net/ethernet/google/gve/gve_main.c +++ b/drivers/net/ethernet/google/gve/gve_main.c @@ -8,6 +8,7 @@ #include <linux/etherdevice.h> #include <linux/interrupt.h> #include <linux/module.h> +#include <linux/netdev_features_helper.h> #include <linux/pci.h> #include <linux/sched.h> #include <linux/timer.h> @@ -1528,6 +1529,16 @@ static void gve_write_version(u8 __iomem *driver_version_register) writeb('\n', driver_version_register); }
+static DECLARE_NETDEV_FEATURE_SET(gve_hw_feature_set, + NETIF_F_HIGHDMA_BIT, + NETIF_F_SG_BIT, + NETIF_F_HW_CSUM_BIT, + NETIF_F_TSO_BIT, + NETIF_F_TSO6_BIT, + NETIF_F_TSO_ECN_BIT, + NETIF_F_RXCSUM_BIT, + NETIF_F_RXHASH_BIT); + static int gve_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { int max_tx_queues, max_rx_queues; @@ -1588,14 +1599,8 @@ static int gve_probe(struct pci_dev *pdev, const struct pci_device_id *ent) * Features might be set in other locations as well (such as * `gve_adminq_describe_device`). */ - dev->hw_features = NETIF_F_HIGHDMA; - dev->hw_features |= NETIF_F_SG; - dev->hw_features |= NETIF_F_HW_CSUM; - dev->hw_features |= NETIF_F_TSO; - dev->hw_features |= NETIF_F_TSO6; - dev->hw_features |= NETIF_F_TSO_ECN; - dev->hw_features |= NETIF_F_RXCSUM; - dev->hw_features |= NETIF_F_RXHASH; + netdev_hw_features_zero(dev); + netdev_hw_features_set_array(dev, &gve_hw_feature_set); dev->features = dev->hw_features; dev->watchdog_timeo = 5 * HZ; dev->min_mtu = ETH_MIN_MTU; diff --git a/drivers/net/ethernet/hisilicon/hns/hns_enet.c b/drivers/net/ethernet/hisilicon/hns/hns_enet.c index d94cc8c6681f..c7556817e6a4 100644 --- a/drivers/net/ethernet/hisilicon/hns/hns_enet.c +++ b/drivers/net/ethernet/hisilicon/hns/hns_enet.c @@ -13,6 +13,7 @@ #include <linux/ipv6.h> #include <linux/irq.h> #include <linux/module.h> +#include <linux/netdev_features_helper.h> #include <linux/phy.h> #include <linux/platform_device.h> #include <linux/skbuff.h> @@ -1791,6 +1792,11 @@ static int hns_nic_set_features(struct net_device *netdev, return 0; }
+static DECLARE_NETDEV_FEATURE_SET(hns_v1_off_feature_set, + NETIF_F_TSO_BIT, + NETIF_F_TSO6_BIT, + NETIF_F_HW_VLAN_CTAG_FILTER_BIT); + static netdev_features_t hns_nic_fix_features( struct net_device *netdev, netdev_features_t features) { @@ -1798,8 +1804,7 @@ static netdev_features_t hns_nic_fix_features(
switch (priv->enet_ver) { case AE_VERSION_1: - features &= ~(NETIF_F_TSO | NETIF_F_TSO6 | - NETIF_F_HW_VLAN_CTAG_FILTER); + netdev_features_clear_array(&hns_v1_off_feature_set, &features); break; default: break; @@ -2240,6 +2245,34 @@ static int hns_nic_notifier_action(struct notifier_block *nb, return 0; }
+static DECLARE_NETDEV_FEATURE_SET(hns_feature_set, + NETIF_F_IP_CSUM_BIT, + NETIF_F_IPV6_CSUM_BIT, + NETIF_F_RXCSUM_BIT, + NETIF_F_SG_BIT, + NETIF_F_GSO_BIT, + NETIF_F_GRO_BIT); +static DECLARE_NETDEV_FEATURE_SET(hns_vlan_feature_set, + NETIF_F_IP_CSUM_BIT, + NETIF_F_IPV6_CSUM_BIT, + NETIF_F_RXCSUM_BIT, + NETIF_F_SG_BIT, + NETIF_F_GSO_BIT, + NETIF_F_GRO_BIT); +static DECLARE_NETDEV_FEATURE_SET(hns_hw_feature_set, + NETIF_F_IP_CSUM_BIT, + NETIF_F_IPV6_CSUM_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); +static DECLARE_NETDEV_FEATURE_SET(hns_v2_feature_set, + NETIF_F_TSO_BIT, + NETIF_F_TSO6_BIT, + NETIF_F_NTUPLE_BIT); + static int hns_nic_dev_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; @@ -2323,21 +2356,15 @@ static int hns_nic_dev_probe(struct platform_device *pdev) ndev->netdev_ops = &hns_nic_netdev_ops; hns_ethtool_set_ops(ndev);
- ndev->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | - NETIF_F_RXCSUM | NETIF_F_SG | NETIF_F_GSO | - NETIF_F_GRO; - ndev->vlan_features |= - NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | NETIF_F_RXCSUM; - ndev->vlan_features |= NETIF_F_SG | NETIF_F_GSO | NETIF_F_GRO; + netdev_active_features_set_array(ndev, &hns_feature_set); + netdev_vlan_features_set_array(ndev, &hns_vlan_feature_set);
/* MTU range: 68 - 9578 (v1) or 9706 (v2) */ ndev->min_mtu = MAC_MIN_MTU; switch (priv->enet_ver) { case AE_VERSION_2: - ndev->features |= NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_NTUPLE; - ndev->hw_features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | - NETIF_F_RXCSUM | NETIF_F_SG | NETIF_F_GSO | - NETIF_F_GRO | NETIF_F_TSO | NETIF_F_TSO6; + netdev_active_features_set_array(ndev, &hns_v2_feature_set); + netdev_hw_features_set_array(ndev, &hns_hw_feature_set); ndev->vlan_features |= NETIF_F_TSO | NETIF_F_TSO6; ndev->max_mtu = MAC_MAX_MTU_V2 - (ETH_HLEN + ETH_FCS_LEN + VLAN_HLEN); diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c index 35d70041b9e8..df3f46d7f217 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,42 @@ static struct pci_driver hns3_driver = { .err_handler = &hns3_err_handler, };
+static 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_BIT); +static 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->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_active_features_set_array(netdev, &hns3_default_feature_set);
if (ae_dev->dev_version >= HNAE3_DEVICE_VERSION_V2) { netdev->features |= NETIF_F_GRO_HW; @@ -3296,10 +3316,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/huawei/hinic/hinic_main.c b/drivers/net/ethernet/huawei/hinic/hinic_main.c index c23ee2ddbce3..b8db3b423a5b 100644 --- a/drivers/net/ethernet/huawei/hinic/hinic_main.c +++ b/drivers/net/ethernet/huawei/hinic/hinic_main.c @@ -13,6 +13,7 @@ #include <linux/types.h> #include <linux/etherdevice.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/slab.h> #include <linux/if_vlan.h> #include <linux/semaphore.h> @@ -916,21 +917,41 @@ static const struct net_device_ops hinicvf_netdev_ops = { .ndo_set_features = hinic_set_features, };
+static DECLARE_NETDEV_FEATURE_SET(hinic_hw_feature_set, + NETIF_F_SG_BIT, + NETIF_F_HIGHDMA_BIT, + NETIF_F_IP_CSUM_BIT, + NETIF_F_IPV6_CSUM_BIT, + NETIF_F_TSO_BIT, + NETIF_F_TSO6_BIT, + NETIF_F_RXCSUM_BIT, + NETIF_F_LRO_BIT, + NETIF_F_HW_VLAN_CTAG_TX_BIT, + NETIF_F_HW_VLAN_CTAG_RX_BIT, + NETIF_F_GSO_UDP_TUNNEL_BIT, + NETIF_F_GSO_UDP_TUNNEL_CSUM_BIT); +static DECLARE_NETDEV_FEATURE_SET(hinic_hw_enc_feature_set, + NETIF_F_IP_CSUM_BIT, + NETIF_F_IPV6_CSUM_BIT, + NETIF_F_SCTP_CRC_BIT, + NETIF_F_SG_BIT, + NETIF_F_TSO_BIT, + NETIF_F_TSO6_BIT, + NETIF_F_TSO_ECN_BIT, + NETIF_F_GSO_UDP_TUNNEL_BIT, + NETIF_F_GSO_UDP_TUNNEL_CSUM_BIT); + static void netdev_features_init(struct net_device *netdev) { - netdev->hw_features = NETIF_F_SG | NETIF_F_HIGHDMA | NETIF_F_IP_CSUM | - NETIF_F_IPV6_CSUM | NETIF_F_TSO | NETIF_F_TSO6 | - NETIF_F_RXCSUM | NETIF_F_LRO | - NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX | - NETIF_F_GSO_UDP_TUNNEL | NETIF_F_GSO_UDP_TUNNEL_CSUM; + netdev_hw_features_zero(netdev); + netdev_hw_features_set_array(netdev, &hinic_hw_feature_set);
netdev->vlan_features = netdev->hw_features;
netdev->features = netdev->hw_features | NETIF_F_HW_VLAN_CTAG_FILTER;
- netdev->hw_enc_features = NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | NETIF_F_SCTP_CRC | - NETIF_F_SG | NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_TSO_ECN | - NETIF_F_GSO_UDP_TUNNEL_CSUM | NETIF_F_GSO_UDP_TUNNEL; + netdev_hw_enc_features_zero(netdev); + netdev_hw_enc_features_set_array(netdev, &hinic_hw_enc_feature_set); }
static void hinic_refresh_nic_cfg(struct hinic_dev *nic_dev) diff --git a/drivers/net/ethernet/ibm/ehea/ehea_main.c b/drivers/net/ethernet/ibm/ehea/ehea_main.c index 5dc302880f5f..cc520574a710 100644 --- a/drivers/net/ethernet/ibm/ehea/ehea_main.c +++ b/drivers/net/ethernet/ibm/ehea/ehea_main.c @@ -2936,6 +2936,26 @@ static const struct net_device_ops ehea_netdev_ops = { .ndo_tx_timeout = ehea_tx_watchdog, };
+static DECLARE_NETDEV_FEATURE_SET(ehea_hw_feature_set, + NETIF_F_SG_BIT, + NETIF_F_TSO_BIT, + NETIF_F_IP_CSUM_BIT, + NETIF_F_HW_VLAN_CTAG_TX_BIT); +static DECLARE_NETDEV_FEATURE_SET(ehea_feature_set, + NETIF_F_SG_BIT, + NETIF_F_TSO_BIT, + NETIF_F_HIGHDMA_BIT, + NETIF_F_IP_CSUM_BIT, + NETIF_F_HW_VLAN_CTAG_TX_BIT, + NETIF_F_HW_VLAN_CTAG_RX_BIT, + NETIF_F_HW_VLAN_CTAG_FILTER_BIT, + NETIF_F_RXCSUM_BIT); +static DECLARE_NETDEV_FEATURE_SET(ehea_vlan_feature_set, + NETIF_F_SG_BIT, + NETIF_F_TSO_BIT, + NETIF_F_HIGHDMA_BIT, + NETIF_F_IP_CSUM_BIT); + static struct ehea_port *ehea_setup_single_port(struct ehea_adapter *adapter, u32 logical_port_id, struct device_node *dn) @@ -2993,14 +3013,12 @@ static struct ehea_port *ehea_setup_single_port(struct ehea_adapter *adapter, dev->netdev_ops = &ehea_netdev_ops; ehea_set_ethtool_ops(dev);
- dev->hw_features = NETIF_F_SG | NETIF_F_TSO | - NETIF_F_IP_CSUM | NETIF_F_HW_VLAN_CTAG_TX; - dev->features = NETIF_F_SG | NETIF_F_TSO | - NETIF_F_HIGHDMA | NETIF_F_IP_CSUM | - NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX | - NETIF_F_HW_VLAN_CTAG_FILTER | NETIF_F_RXCSUM; - dev->vlan_features = NETIF_F_SG | NETIF_F_TSO | NETIF_F_HIGHDMA | - NETIF_F_IP_CSUM; + netdev_hw_features_zero(dev); + netdev_hw_features_set_array(dev, &ehea_hw_feature_set); + netdev_active_features_zero(dev); + netdev_active_features_set_array(dev, &ehea_feature_set); + netdev_vlan_features_zero(dev); + netdev_vlan_features_set_array(dev, &ehea_vlan_feature_set); dev->watchdog_timeo = EHEA_WATCH_DOG_TIMEOUT;
/* MTU range: 68 - 9022 */ diff --git a/drivers/net/ethernet/ibm/emac/core.c b/drivers/net/ethernet/ibm/emac/core.c index fbea9f7efe8c..6b026ba0f262 100644 --- a/drivers/net/ethernet/ibm/emac/core.c +++ b/drivers/net/ethernet/ibm/emac/core.c @@ -3032,6 +3032,10 @@ static const struct net_device_ops emac_gige_netdev_ops = { .ndo_change_mtu = emac_change_mtu, };
+static DECLARE_NETDEV_FEATURE_SET(emac_hw_feature_set, + NETIF_F_IP_CSUM_BIT, + NETIF_F_SG_BIT); + static int emac_probe(struct platform_device *ofdev) { struct net_device *ndev; @@ -3171,7 +3175,8 @@ static int emac_probe(struct platform_device *ofdev) goto err_detach_tah;
if (dev->tah_dev) { - ndev->hw_features = NETIF_F_IP_CSUM | NETIF_F_SG; + netdev_hw_features_zero(ndev); + netdev_hw_features_set_array(ndev, &emac_hw_feature_set); ndev->features |= ndev->hw_features | NETIF_F_RXCSUM; } ndev->watchdog_timeo = 5 * HZ; diff --git a/drivers/net/ethernet/ibm/ibmveth.c b/drivers/net/ethernet/ibm/ibmveth.c index 5c6a04d29f5b..b45b7ff892ef 100644 --- a/drivers/net/ethernet/ibm/ibmveth.c +++ b/drivers/net/ethernet/ibm/ibmveth.c @@ -1623,6 +1623,11 @@ static const struct net_device_ops ibmveth_netdev_ops = { #endif };
+static DECLARE_NETDEV_FEATURE_SET(ibmveth_hw_feature_set, + NETIF_F_IP_CSUM_BIT, + NETIF_F_IPV6_CSUM_BIT, + NETIF_F_RXCSUM_BIT); + static int ibmveth_probe(struct vio_dev *dev, const struct vio_device_id *id) { int rc, i, mac_len; @@ -1681,10 +1686,8 @@ static int ibmveth_probe(struct vio_dev *dev, const struct vio_device_id *id) netdev->ethtool_ops = &netdev_ethtool_ops; SET_NETDEV_DEV(netdev, &dev->dev); netdev->hw_features = NETIF_F_SG; - if (vio_get_attribute(dev, "ibm,illan-options", NULL) != NULL) { - netdev->hw_features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | - NETIF_F_RXCSUM; - } + if (vio_get_attribute(dev, "ibm,illan-options", NULL) != NULL) + netdev_hw_features_set_array(netdev, &ibmveth_hw_feature_set);
netdev->features |= netdev->hw_features;
diff --git a/drivers/net/ethernet/ibm/ibmvnic.c b/drivers/net/ethernet/ibm/ibmvnic.c index 5ab7c0f81e9a..c0ae18a2b601 100644 --- a/drivers/net/ethernet/ibm/ibmvnic.c +++ b/drivers/net/ethernet/ibm/ibmvnic.c @@ -4831,6 +4831,11 @@ static void send_query_ip_offload(struct ibmvnic_adapter *adapter) ibmvnic_send_crq(adapter, &crq); }
+static DECLARE_NETDEV_FEATURE_SET(ibmvnic_hw_feature_set, + NETIF_F_SG_BIT, + NETIF_F_GSO_BIT, + NETIF_F_GRO_BIT); + static void send_control_ip_offload(struct ibmvnic_adapter *adapter) { struct ibmvnic_control_ip_offload_buffer *ctrl_buf = &adapter->ip_offload_ctrl; @@ -4870,7 +4875,8 @@ static void send_control_ip_offload(struct ibmvnic_adapter *adapter) adapter->netdev->hw_features = 0; }
- adapter->netdev->hw_features = NETIF_F_SG | NETIF_F_GSO | NETIF_F_GRO; + netdev_hw_features_zero(adapter->netdev); + netdev_hw_features_set_array(adapter->netdev, &ibmvnic_hw_feature_set);
if (buf->tcp_ipv4_chksum || buf->udp_ipv4_chksum) adapter->netdev->hw_features |= NETIF_F_IP_CSUM; diff --git a/drivers/net/ethernet/intel/e1000/e1000.h b/drivers/net/ethernet/intel/e1000/e1000.h index 4817eb13ca6f..86bc74be959f 100644 --- a/drivers/net/ethernet/intel/e1000/e1000.h +++ b/drivers/net/ethernet/intel/e1000/e1000.h @@ -16,6 +16,7 @@ #include <linux/pci.h> #include <linux/kernel.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/etherdevice.h> #include <linux/skbuff.h> #include <linux/delay.h> diff --git a/drivers/net/ethernet/intel/e1000/e1000_main.c b/drivers/net/ethernet/intel/e1000/e1000_main.c index 23299fc56199..07670cabf19f 100644 --- a/drivers/net/ethernet/intel/e1000/e1000_main.c +++ b/drivers/net/ethernet/intel/e1000/e1000_main.c @@ -907,6 +907,22 @@ static int e1000_init_hw_struct(struct e1000_adapter *adapter, return 0; }
+static DECLARE_NETDEV_FEATURE_SET(e1000_hw_feature_set, + NETIF_F_SG_BIT, + NETIF_F_HW_CSUM_BIT, + NETIF_F_HW_VLAN_CTAG_RX_BIT); +static DECLARE_NETDEV_FEATURE_SET(e1000_feature_set, + NETIF_F_HW_VLAN_CTAG_TX_BIT, + NETIF_F_HW_VLAN_CTAG_FILTER_BIT); +static DECLARE_NETDEV_FEATURE_SET(e1000_hw_rx_feature_set, + NETIF_F_RXCSUM_BIT, + NETIF_F_RXALL_BIT, + NETIF_F_RXFCS_BIT); +static DECLARE_NETDEV_FEATURE_SET(e1000_vlan_feature_set, + NETIF_F_TSO_BIT, + NETIF_F_HW_CSUM_BIT, + NETIF_F_SG_BIT); + /** * e1000_probe - Device Initialization Routine * @pdev: PCI device information struct @@ -1035,11 +1051,10 @@ static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *ent) }
if (hw->mac_type >= e1000_82543) { - netdev->hw_features = NETIF_F_SG | - NETIF_F_HW_CSUM | - NETIF_F_HW_VLAN_CTAG_RX; - netdev->features = NETIF_F_HW_VLAN_CTAG_TX | - NETIF_F_HW_VLAN_CTAG_FILTER; + netdev_hw_features_zero(netdev); + netdev_hw_features_set_array(netdev, &e1000_hw_feature_set); + netdev_active_features_zero(netdev); + netdev_active_features_set_array(netdev, &e1000_feature_set); }
if ((hw->mac_type >= e1000_82544) && @@ -1049,18 +1064,14 @@ static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *ent) netdev->priv_flags |= IFF_SUPP_NOFCS;
netdev->features |= netdev->hw_features; - netdev->hw_features |= (NETIF_F_RXCSUM | - NETIF_F_RXALL | - NETIF_F_RXFCS); + netdev_hw_features_set_array(netdev, &e1000_hw_rx_feature_set);
if (pci_using_dac) { netdev->features |= NETIF_F_HIGHDMA; netdev->vlan_features |= NETIF_F_HIGHDMA; }
- netdev->vlan_features |= (NETIF_F_TSO | - NETIF_F_HW_CSUM | - NETIF_F_SG); + netdev_vlan_features_set_array(netdev, &e1000_vlan_feature_set);
/* Do not set IFF_UNICAST_FLT for VMWare's 82545EM */ if (hw->device_id != E1000_DEV_ID_82545EM_COPPER || diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c index 70d933f52e93..3ed52967efd6 100644 --- a/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/drivers/net/ethernet/intel/e1000e/netdev.c @@ -11,6 +11,7 @@ #include <linux/pagemap.h> #include <linux/delay.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/interrupt.h> #include <linux/tcp.h> #include <linux/ipv6.h> @@ -7311,18 +7312,27 @@ static netdev_features_t e1000_fix_features(struct net_device *netdev, return features; }
+static DECLARE_NETDEV_FEATURE_SET(e1000_changable_feature_set, + NETIF_F_HW_VLAN_CTAG_RX_BIT, + NETIF_F_HW_VLAN_CTAG_TX_BIT, + NETIF_F_RXCSUM_BIT, + NETIF_F_RXHASH_BIT, + NETIF_F_RXFCS_BIT, + NETIF_F_RXALL_BIT); + static int e1000_set_features(struct net_device *netdev, netdev_features_t features) { struct e1000_adapter *adapter = netdev_priv(netdev); netdev_features_t changed = features ^ netdev->features; + netdev_features_t changeable;
if (changed & (NETIF_F_TSO | NETIF_F_TSO6)) adapter->flags |= FLAG_TSO_FORCE;
- if (!(changed & (NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_HW_VLAN_CTAG_TX | - NETIF_F_RXCSUM | NETIF_F_RXHASH | NETIF_F_RXFCS | - NETIF_F_RXALL))) + netdev_features_zero(&changeable); + netdev_features_set_array(&e1000_changable_feature_set, &changeable); + if (!(changed & changeable)) return 0;
if (changed & NETIF_F_RXFCS) { @@ -7371,6 +7381,21 @@ static const struct net_device_ops e1000e_netdev_ops = { .ndo_features_check = passthru_features_check, };
+static DECLARE_NETDEV_FEATURE_SET(e1000_feature_set, + NETIF_F_SG_BIT, + NETIF_F_HW_VLAN_CTAG_RX_BIT, + NETIF_F_HW_VLAN_CTAG_TX_BIT, + NETIF_F_TSO_BIT, + NETIF_F_TSO6_BIT, + NETIF_F_RXHASH_BIT, + NETIF_F_RXCSUM_BIT, + NETIF_F_HW_CSUM_BIT); +static DECLARE_NETDEV_FEATURE_SET(e1000_vlan_feature_set, + NETIF_F_SG_BIT, + NETIF_F_TSO_BIT, + NETIF_F_TSO6_BIT, + NETIF_F_HW_CSUM_BIT); + /** * e1000_probe - Device Initialization Routine * @pdev: PCI device information struct @@ -7523,14 +7548,8 @@ static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *ent) "PHY reset is blocked due to SOL/IDER session.\n");
/* Set initial default active device features */ - netdev->features = (NETIF_F_SG | - NETIF_F_HW_VLAN_CTAG_RX | - NETIF_F_HW_VLAN_CTAG_TX | - NETIF_F_TSO | - NETIF_F_TSO6 | - NETIF_F_RXHASH | - NETIF_F_RXCSUM | - NETIF_F_HW_CSUM); + netdev_active_features_zero(netdev); + netdev_active_features_set_array(netdev, &e1000_feature_set);
/* Set user-changeable features (subset of all device features) */ netdev->hw_features = netdev->features; @@ -7541,10 +7560,7 @@ static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *ent) if (adapter->flags & FLAG_HAS_HW_VLAN_FILTER) netdev->features |= NETIF_F_HW_VLAN_CTAG_FILTER;
- netdev->vlan_features |= (NETIF_F_SG | - NETIF_F_TSO | - NETIF_F_TSO6 | - NETIF_F_HW_CSUM); + netdev_vlan_features_set_array(netdev, &e1000_vlan_feature_set);
netdev->priv_flags |= IFF_UNICAST_FLT;
diff --git a/drivers/net/ethernet/intel/fm10k/fm10k_netdev.c b/drivers/net/ethernet/intel/fm10k/fm10k_netdev.c index 2cca9e84e31e..a42148582779 100644 --- a/drivers/net/ethernet/intel/fm10k/fm10k_netdev.c +++ b/drivers/net/ethernet/intel/fm10k/fm10k_netdev.c @@ -5,6 +5,7 @@ #include <linux/vmalloc.h> #include <net/udp_tunnel.h> #include <linux/if_macvlan.h> +#include <linux/netdev_features_helper.h>
/** * fm10k_setup_tx_resources - allocate Tx resources (Descriptors) @@ -1536,6 +1537,24 @@ static const struct net_device_ops fm10k_netdev_ops = { .ndo_features_check = fm10k_features_check, };
+static DECLARE_NETDEV_FEATURE_SET(fm10k_feature_set, + NETIF_F_IP_CSUM_BIT, + NETIF_F_IPV6_CSUM_BIT, + NETIF_F_SG_BIT, + NETIF_F_TSO_BIT, + NETIF_F_TSO6_BIT, + NETIF_F_TSO_ECN_BIT, + NETIF_F_RXHASH_BIT, + NETIF_F_RXCSUM_BIT); +static DECLARE_NETDEV_FEATURE_SET(fm10k_hw_enc_feature_set, + NETIF_F_IP_CSUM_BIT, + NETIF_F_TSO_BIT, + NETIF_F_TSO6_BIT, + NETIF_F_TSO_ECN_BIT, + NETIF_F_GSO_UDP_TUNNEL_BIT, + NETIF_F_IPV6_CSUM_BIT, + NETIF_F_SG_BIT); + #define DEFAULT_DEBUG_LEVEL_SHIFT 3
struct net_device *fm10k_alloc_netdev(const struct fm10k_info *info) @@ -1557,24 +1576,12 @@ struct net_device *fm10k_alloc_netdev(const struct fm10k_info *info) interface->msg_enable = BIT(DEFAULT_DEBUG_LEVEL_SHIFT) - 1;
/* configure default features */ - dev->features |= NETIF_F_IP_CSUM | - NETIF_F_IPV6_CSUM | - NETIF_F_SG | - NETIF_F_TSO | - NETIF_F_TSO6 | - NETIF_F_TSO_ECN | - NETIF_F_RXHASH | - NETIF_F_RXCSUM; + netdev_active_features_set_array(dev, &fm10k_feature_set);
/* Only the PF can support VXLAN and NVGRE tunnel offloads */ if (info->mac == fm10k_mac_pf) { - dev->hw_enc_features = NETIF_F_IP_CSUM | - NETIF_F_TSO | - NETIF_F_TSO6 | - NETIF_F_TSO_ECN | - NETIF_F_GSO_UDP_TUNNEL | - NETIF_F_IPV6_CSUM | - NETIF_F_SG; + netdev_hw_enc_features_zero(dev); + netdev_hw_enc_features_set_array(dev, &fm10k_hw_enc_feature_set);
dev->features |= NETIF_F_GSO_UDP_TUNNEL;
diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index b36bf9c3e1e4..69ac22c7e800 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -7,6 +7,7 @@ #include <linux/bpf.h> #include <generated/utsrelease.h> #include <linux/crash_dump.h> +#include <linux/netdev_features_helper.h>
/* Local includes */ #include "i40e.h" @@ -13616,6 +13617,37 @@ static const struct net_device_ops i40e_netdev_ops = { .ndo_dfwd_del_station = i40e_fwd_del, };
+static DECLARE_NETDEV_FEATURE_SET(i40e_hw_enc_feature_set, + NETIF_F_SG_BIT, + NETIF_F_HW_CSUM_BIT, + NETIF_F_HIGHDMA_BIT, + NETIF_F_TSO_BIT, + NETIF_F_TSO_ECN_BIT, + NETIF_F_TSO6_BIT, + NETIF_F_GSO_GRE_BIT, + NETIF_F_GSO_GRE_CSUM_BIT, + NETIF_F_GSO_PARTIAL_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_UDP_L4_BIT, + NETIF_F_SCTP_CRC_BIT, + NETIF_F_RXHASH_BIT, + NETIF_F_RXCSUM_BIT); +static DECLARE_NETDEV_FEATURE_SET(i40e_gso_partial_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); +static DECLARE_NETDEV_FEATURE_SET(i40e_mpls_feature_set, + NETIF_F_SG_BIT, + NETIF_F_HW_CSUM_BIT, + NETIF_F_TSO_BIT, + NETIF_F_TSO6_BIT); + /** * i40e_config_netdev - Setup the netdev flags * @vsi: the VSI being configured @@ -13631,6 +13663,7 @@ static int i40e_config_netdev(struct i40e_vsi *vsi) u8 broadcast[ETH_ALEN]; u8 mac_addr[ETH_ALEN]; int etherdev_size; + netdev_features_t gso_partial_features; netdev_features_t hw_enc_features; netdev_features_t hw_features;
@@ -13643,25 +13676,8 @@ static int i40e_config_netdev(struct i40e_vsi *vsi) np = netdev_priv(netdev); np->vsi = vsi;
- hw_enc_features = NETIF_F_SG | - NETIF_F_HW_CSUM | - NETIF_F_HIGHDMA | - NETIF_F_SOFT_FEATURES | - NETIF_F_TSO | - NETIF_F_TSO_ECN | - NETIF_F_TSO6 | - NETIF_F_GSO_GRE | - NETIF_F_GSO_GRE_CSUM | - NETIF_F_GSO_PARTIAL | - NETIF_F_GSO_IPXIP4 | - NETIF_F_GSO_IPXIP6 | - NETIF_F_GSO_UDP_TUNNEL | - NETIF_F_GSO_UDP_TUNNEL_CSUM | - NETIF_F_GSO_UDP_L4 | - NETIF_F_SCTP_CRC | - NETIF_F_RXHASH | - NETIF_F_RXCSUM | - 0; + hw_enc_features = NETIF_F_SOFT_FEATURES; + netdev_features_set_array(&i40e_hw_enc_feature_set, &hw_enc_features);
if (!(pf->hw_features & I40E_HW_OUTER_UDP_CSUM_CAPABLE)) netdev->gso_partial_features |= NETIF_F_GSO_UDP_TUNNEL_CSUM; @@ -13675,22 +13691,15 @@ static int i40e_config_netdev(struct i40e_vsi *vsi) /* record features VLANs can make use of */ netdev->vlan_features |= hw_enc_features | NETIF_F_TSO_MANGLEID;
-#define I40E_GSO_PARTIAL_FEATURES (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) - - netdev->gso_partial_features = I40E_GSO_PARTIAL_FEATURES; + netdev_features_zero(&gso_partial_features); + netdev_features_set_array(&i40e_gso_partial_feature_set, + &gso_partial_features); + netdev->gso_partial_features = gso_partial_features; netdev->features |= NETIF_F_GSO_PARTIAL | - I40E_GSO_PARTIAL_FEATURES; + gso_partial_features;
- netdev->mpls_features |= NETIF_F_SG; - netdev->mpls_features |= NETIF_F_HW_CSUM; - netdev->mpls_features |= NETIF_F_TSO; - netdev->mpls_features |= NETIF_F_TSO6; - netdev->mpls_features |= I40E_GSO_PARTIAL_FEATURES; + netdev_mpls_features_set_array(netdev, &i40e_mpls_feature_set); + netdev->mpls_features |= gso_partial_features;
/* enable macvlan offloads */ netdev->hw_features |= NETIF_F_HW_L2FW_DOFFLOAD; diff --git a/drivers/net/ethernet/intel/iavf/iavf.h b/drivers/net/ethernet/intel/iavf/iavf.h index 69703801d1b0..feb048cdcea9 100644 --- a/drivers/net/ethernet/intel/iavf/iavf.h +++ b/drivers/net/ethernet/intel/iavf/iavf.h @@ -8,6 +8,7 @@ #include <linux/pci.h> #include <linux/aer.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/vmalloc.h> #include <linux/interrupt.h> #include <linux/ethtool.h> diff --git a/drivers/net/ethernet/intel/iavf/iavf_main.c b/drivers/net/ethernet/intel/iavf/iavf_main.c index e78c38d02432..47048014a1c4 100644 --- a/drivers/net/ethernet/intel/iavf/iavf_main.c +++ b/drivers/net/ethernet/intel/iavf/iavf_main.c @@ -4543,6 +4543,26 @@ static int iavf_check_reset_complete(struct iavf_hw *hw) return -EBUSY; }
+static DECLARE_NETDEV_FEATURE_SET(iavf_hw_enc_feature_set, + NETIF_F_SG_BIT, + NETIF_F_IP_CSUM_BIT, + NETIF_F_IPV6_CSUM_BIT, + NETIF_F_HIGHDMA_BIT, + NETIF_F_TSO_BIT, + NETIF_F_TSO_ECN_BIT, + NETIF_F_TSO6_BIT, + NETIF_F_SCTP_CRC_BIT, + NETIF_F_RXHASH_BIT, + NETIF_F_RXCSUM_BIT); +static DECLARE_NETDEV_FEATURE_SET(iavf_gso_feature_set, + NETIF_F_GSO_UDP_TUNNEL_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_CSUM_BIT, + NETIF_F_GSO_PARTIAL_BIT); + /** * iavf_process_config - Process the config information we got from the PF * @adapter: board private structure @@ -4558,31 +4578,14 @@ int iavf_process_config(struct iavf_adapter *adapter) netdev_features_t hw_enc_features; netdev_features_t hw_features;
- hw_enc_features = NETIF_F_SG | - NETIF_F_IP_CSUM | - NETIF_F_IPV6_CSUM | - NETIF_F_HIGHDMA | - NETIF_F_SOFT_FEATURES | - NETIF_F_TSO | - NETIF_F_TSO_ECN | - NETIF_F_TSO6 | - NETIF_F_SCTP_CRC | - NETIF_F_RXHASH | - NETIF_F_RXCSUM | - 0; + hw_enc_features = NETIF_F_SOFT_FEATURES; + netdev_features_set_array(&iavf_hw_enc_feature_set, &hw_enc_features);
/* advertise to stack only if offloads for encapsulated packets is * supported */ if (vfres->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_ENCAP) { - hw_enc_features |= NETIF_F_GSO_UDP_TUNNEL | - NETIF_F_GSO_GRE | - NETIF_F_GSO_GRE_CSUM | - NETIF_F_GSO_IPXIP4 | - NETIF_F_GSO_IPXIP6 | - NETIF_F_GSO_UDP_TUNNEL_CSUM | - NETIF_F_GSO_PARTIAL | - 0; + netdev_features_set_array(&iavf_gso_feature_set, &hw_enc_features);
if (!(vfres->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_ENCAP_CSUM)) diff --git a/drivers/net/ethernet/intel/ice/ice.h b/drivers/net/ethernet/intel/ice/ice.h index 36b440b1aaff..6ecbe4369f5a 100644 --- a/drivers/net/ethernet/intel/ice/ice.h +++ b/drivers/net/ethernet/intel/ice/ice.h @@ -10,6 +10,7 @@ #include <linux/module.h> #include <linux/firmware.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/compiler.h> #include <linux/etherdevice.h> #include <linux/skbuff.h> diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c index 29914eedb3e6..9a8aa40b703e 100644 --- a/drivers/net/ethernet/intel/ice/ice_main.c +++ b/drivers/net/ethernet/intel/ice/ice_main.c @@ -3293,6 +3293,36 @@ static void ice_set_ops(struct net_device *netdev) ice_set_ethtool_ops(netdev); }
+static DECLARE_NETDEV_FEATURE_SET(ice_safe_mode_feature_set, + NETIF_F_SG_BIT, + NETIF_F_HIGHDMA_BIT); +static DECLARE_NETDEV_FEATURE_SET(ice_dflt_feature_set, + NETIF_F_SG_BIT, + NETIF_F_HIGHDMA_BIT, + NETIF_F_NTUPLE_BIT, + NETIF_F_RXHASH_BIT); +static DECLARE_NETDEV_FEATURE_SET(ice_csumo_feature_set, + NETIF_F_RXCSUM_BIT, + NETIF_F_IP_CSUM_BIT, + NETIF_F_SCTP_CRC_BIT, + NETIF_F_IPV6_CSUM_BIT); +static DECLARE_NETDEV_FEATURE_SET(ice_tso_feature_set, + NETIF_F_TSO_BIT, + NETIF_F_TSO_ECN_BIT, + NETIF_F_TSO6_BIT, + NETIF_F_GSO_GRE_BIT, + NETIF_F_GSO_UDP_TUNNEL_BIT, + NETIF_F_GSO_GRE_CSUM_BIT, + NETIF_F_GSO_UDP_TUNNEL_CSUM_BIT, + NETIF_F_GSO_PARTIAL_BIT, + NETIF_F_GSO_IPXIP4_BIT, + NETIF_F_GSO_IPXIP6_BIT, + NETIF_F_GSO_UDP_L4_BIT); +static DECLARE_NETDEV_FEATURE_SET(ice_mpls_feature_set, + NETIF_F_HW_CSUM_BIT, + NETIF_F_TSO_BIT, + NETIF_F_TSO6_BIT); + /** * ice_set_netdev_features - set features for the given netdev * @netdev: netdev instance @@ -3308,20 +3338,18 @@ static void ice_set_netdev_features(struct net_device *netdev)
if (ice_is_safe_mode(pf)) { /* safe mode */ - netdev->features = NETIF_F_SG | NETIF_F_HIGHDMA; + netdev_active_features_zero(netdev); + netdev_active_features_set_array(netdev, + &ice_safe_mode_feature_set); netdev->hw_features = netdev->features; return; }
- dflt_features = NETIF_F_SG | - NETIF_F_HIGHDMA | - NETIF_F_NTUPLE | - NETIF_F_RXHASH; + netdev_features_zero(&dflt_features); + netdev_features_set_array(&ice_dflt_feature_set, &dflt_features);
- csumo_features = NETIF_F_RXCSUM | - NETIF_F_IP_CSUM | - NETIF_F_SCTP_CRC | - NETIF_F_IPV6_CSUM; + netdev_features_zero(&csumo_features); + netdev_features_set_array(&ice_csumo_feature_set, &csumo_features);
vlano_features = NETIF_F_HW_VLAN_CTAG_FILTER | NETIF_F_HW_VLAN_CTAG_TX | @@ -3331,17 +3359,8 @@ static void ice_set_netdev_features(struct net_device *netdev) if (is_dvm_ena) vlano_features |= NETIF_F_HW_VLAN_STAG_FILTER;
- tso_features = NETIF_F_TSO | - NETIF_F_TSO_ECN | - NETIF_F_TSO6 | - NETIF_F_GSO_GRE | - NETIF_F_GSO_UDP_TUNNEL | - NETIF_F_GSO_GRE_CSUM | - NETIF_F_GSO_UDP_TUNNEL_CSUM | - NETIF_F_GSO_PARTIAL | - NETIF_F_GSO_IPXIP4 | - NETIF_F_GSO_IPXIP6 | - NETIF_F_GSO_UDP_L4; + netdev_features_zero(&tso_features); + netdev_features_set_array(&ice_tso_feature_set, &tso_features);
netdev->gso_partial_features |= NETIF_F_GSO_UDP_TUNNEL_CSUM | NETIF_F_GSO_GRE_CSUM; @@ -3350,9 +3369,8 @@ static void ice_set_netdev_features(struct net_device *netdev) vlano_features | tso_features;
/* add support for HW_CSUM on packets with MPLS header */ - netdev->mpls_features = NETIF_F_HW_CSUM | - NETIF_F_TSO | - NETIF_F_TSO6; + netdev_mpls_features_zero(netdev); + netdev_mpls_features_set_array(netdev, &ice_mpls_feature_set);
/* enable features */ netdev->features |= netdev->hw_features; diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c index d8b836a85cc3..2fd8d8c94305 100644 --- a/drivers/net/ethernet/intel/igb/igb_main.c +++ b/drivers/net/ethernet/intel/igb/igb_main.c @@ -10,6 +10,7 @@ #include <linux/vmalloc.h> #include <linux/pagemap.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/ipv6.h> #include <linux/slab.h> #include <net/checksum.h> @@ -2500,6 +2501,20 @@ static int igb_ndo_fdb_add(struct ndmsg *ndm, struct nlattr *tb[], return ndo_dflt_fdb_add(ndm, tb, dev, addr, vid, flags); }
+static DECLARE_NETDEV_FEATURE_SET(igb_l2_disable_feature_set, + NETIF_F_HW_CSUM_BIT, + NETIF_F_SCTP_CRC_BIT, + NETIF_F_GSO_UDP_L4_BIT, + NETIF_F_HW_VLAN_CTAG_TX_BIT, + NETIF_F_TSO_BIT, + NETIF_F_TSO6_BIT); +static DECLARE_NETDEV_FEATURE_SET(igb_l3_disable_feature_set, + NETIF_F_HW_CSUM_BIT, + NETIF_F_SCTP_CRC_BIT, + NETIF_F_GSO_UDP_L4_BIT, + NETIF_F_TSO_BIT, + NETIF_F_TSO6_BIT); + #define IGB_MAX_MAC_HDR_LEN 127 #define IGB_MAX_NETWORK_HDR_LEN 511
@@ -2511,21 +2526,18 @@ igb_features_check(struct sk_buff *skb, struct net_device *dev,
/* Make certain the headers can be described by a context descriptor */ mac_hdr_len = skb_network_header(skb) - skb->data; - if (unlikely(mac_hdr_len > IGB_MAX_MAC_HDR_LEN)) - return features & ~(NETIF_F_HW_CSUM | - NETIF_F_SCTP_CRC | - NETIF_F_GSO_UDP_L4 | - NETIF_F_HW_VLAN_CTAG_TX | - NETIF_F_TSO | - NETIF_F_TSO6); + if (unlikely(mac_hdr_len > IGB_MAX_MAC_HDR_LEN)) { + netdev_features_clear_array(&igb_l2_disable_feature_set, + &features); + return features; + }
network_hdr_len = skb_checksum_start(skb) - skb_network_header(skb); - if (unlikely(network_hdr_len > IGB_MAX_NETWORK_HDR_LEN)) - return features & ~(NETIF_F_HW_CSUM | - NETIF_F_SCTP_CRC | - NETIF_F_GSO_UDP_L4 | - NETIF_F_TSO | - NETIF_F_TSO6); + if (unlikely(network_hdr_len > IGB_MAX_NETWORK_HDR_LEN)) { + netdev_features_clear_array(&igb_l3_disable_feature_set, + &features); + return features; + }
/* We can only support IPV4 TSO in tunnels if we can mangle the * inner IP ID field, so strip TSO if MANGLEID is not supported. @@ -3144,6 +3156,21 @@ static s32 igb_init_i2c(struct igb_adapter *adapter) return status; }
+static DECLARE_NETDEV_FEATURE_SET(igb_feature_set, + NETIF_F_SG_BIT, + NETIF_F_TSO_BIT, + NETIF_F_TSO6_BIT, + NETIF_F_RXHASH_BIT, + NETIF_F_RXCSUM_BIT, + NETIF_F_HW_CSUM_BIT); +static DECLARE_NETDEV_FEATURE_SET(igb_gso_partial_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); + /** * igb_probe - Device Initialization Routine * @pdev: PCI device information struct @@ -3164,6 +3191,7 @@ static int igb_probe(struct pci_dev *pdev, const struct pci_device_id *ent) s32 ret_val; static int global_quad_port_a; /* global quad port a indication */ const struct e1000_info *ei = igb_info_tbl[ent->driver_data]; + netdev_features_t gso_partial_features; u8 part_str[E1000_PBANUM_LENGTH]; int err;
@@ -3268,12 +3296,7 @@ static int igb_probe(struct pci_dev *pdev, const struct pci_device_id *ent) * set by igb_sw_init so we should use an or instead of an * assignment. */ - netdev->features |= NETIF_F_SG | - NETIF_F_TSO | - NETIF_F_TSO6 | - NETIF_F_RXHASH | - NETIF_F_RXCSUM | - NETIF_F_HW_CSUM; + netdev_active_features_set_array(netdev, &igb_feature_set);
if (hw->mac.type >= e1000_82576) netdev->features |= NETIF_F_SCTP_CRC | NETIF_F_GSO_UDP_L4; @@ -3281,15 +3304,10 @@ static int igb_probe(struct pci_dev *pdev, const struct pci_device_id *ent) if (hw->mac.type >= e1000_i350) netdev->features |= NETIF_F_HW_TC;
-#define IGB_GSO_PARTIAL_FEATURES (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) - - netdev->gso_partial_features = IGB_GSO_PARTIAL_FEATURES; - netdev->features |= NETIF_F_GSO_PARTIAL | IGB_GSO_PARTIAL_FEATURES; + netdev_features_zero(&gso_partial_features); + netdev_features_set_array(&igb_feature_set, &gso_partial_features); + netdev->gso_partial_features = gso_partial_features; + netdev->features |= NETIF_F_GSO_PARTIAL | gso_partial_features;
/* copy netdev features into list of user selectable features */ netdev->hw_features |= netdev->features | diff --git a/drivers/net/ethernet/intel/igbvf/netdev.c b/drivers/net/ethernet/intel/igbvf/netdev.c index f4e91db89fe5..362e26df28b0 100644 --- a/drivers/net/ethernet/intel/igbvf/netdev.c +++ b/drivers/net/ethernet/intel/igbvf/netdev.c @@ -11,6 +11,7 @@ #include <linux/pagemap.h> #include <linux/delay.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/tcp.h> #include <linux/ipv6.h> #include <linux/slab.h> @@ -2615,6 +2616,18 @@ static int igbvf_set_features(struct net_device *netdev, return 0; }
+static DECLARE_NETDEV_FEATURE_SET(igbvf_l2_disable_feature_set, + NETIF_F_HW_CSUM_BIT, + NETIF_F_SCTP_CRC_BIT, + NETIF_F_HW_VLAN_CTAG_TX_BIT, + NETIF_F_TSO_BIT, + NETIF_F_TSO6_BIT); +static DECLARE_NETDEV_FEATURE_SET(igbvf_l3_disable_feature_set, + NETIF_F_HW_CSUM_BIT, + NETIF_F_SCTP_CRC_BIT, + NETIF_F_TSO_BIT, + NETIF_F_TSO6_BIT); + #define IGBVF_MAX_MAC_HDR_LEN 127 #define IGBVF_MAX_NETWORK_HDR_LEN 511
@@ -2626,19 +2639,18 @@ igbvf_features_check(struct sk_buff *skb, struct net_device *dev,
/* Make certain the headers can be described by a context descriptor */ mac_hdr_len = skb_network_header(skb) - skb->data; - if (unlikely(mac_hdr_len > IGBVF_MAX_MAC_HDR_LEN)) - return features & ~(NETIF_F_HW_CSUM | - NETIF_F_SCTP_CRC | - NETIF_F_HW_VLAN_CTAG_TX | - NETIF_F_TSO | - NETIF_F_TSO6); + if (unlikely(mac_hdr_len > IGBVF_MAX_MAC_HDR_LEN)) { + netdev_features_clear_array(&igbvf_l2_disable_feature_set, + &features); + return features; + }
network_hdr_len = skb_checksum_start(skb) - skb_network_header(skb); - if (unlikely(network_hdr_len > IGBVF_MAX_NETWORK_HDR_LEN)) - return features & ~(NETIF_F_HW_CSUM | - NETIF_F_SCTP_CRC | - NETIF_F_TSO | - NETIF_F_TSO6); + if (unlikely(network_hdr_len > IGBVF_MAX_NETWORK_HDR_LEN)) { + netdev_features_clear_array(&igbvf_l3_disable_feature_set, + &features); + return features; + }
/* We can only support IPV4 TSO in tunnels if we can mangle the * inner IP ID field, so strip TSO if MANGLEID is not supported. @@ -2667,6 +2679,21 @@ static const struct net_device_ops igbvf_netdev_ops = { .ndo_features_check = igbvf_features_check, };
+static DECLARE_NETDEV_FEATURE_SET(igbvf_hw_feature_set, + NETIF_F_SG_BIT, + NETIF_F_TSO_BIT, + NETIF_F_TSO6_BIT, + NETIF_F_RXCSUM_BIT, + NETIF_F_HW_CSUM_BIT, + NETIF_F_SCTP_CRC_BIT); +static DECLARE_NETDEV_FEATURE_SET(igbvf_gso_partial_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); + /** * igbvf_probe - Device Initialization Routine * @pdev: PCI device information struct @@ -2684,6 +2711,7 @@ static int igbvf_probe(struct pci_dev *pdev, const struct pci_device_id *ent) struct igbvf_adapter *adapter; struct e1000_hw *hw; const struct igbvf_info *ei = igbvf_info_tbl[ent->driver_data]; + netdev_features_t gso_partial_features; static int cards_found; int err;
@@ -2758,23 +2786,15 @@ static int igbvf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
adapter->bd_number = cards_found++;
- netdev->hw_features = NETIF_F_SG | - NETIF_F_TSO | - NETIF_F_TSO6 | - NETIF_F_RXCSUM | - NETIF_F_HW_CSUM | - NETIF_F_SCTP_CRC; - -#define IGBVF_GSO_PARTIAL_FEATURES (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) - - netdev->gso_partial_features = IGBVF_GSO_PARTIAL_FEATURES; - netdev->hw_features |= NETIF_F_GSO_PARTIAL | - IGBVF_GSO_PARTIAL_FEATURES; + netdev_hw_features_zero(netdev); + netdev_hw_features_set_array(netdev, &igbvf_hw_feature_set); + + netdev_features_zero(&gso_partial_features); + netdev_features_set_array(&igbvf_gso_partial_feature_set, + &gso_partial_features); + + netdev->gso_partial_features = gso_partial_features; + netdev->hw_features |= NETIF_F_GSO_PARTIAL | gso_partial_features;
netdev->features = netdev->hw_features | NETIF_F_HIGHDMA;
diff --git a/drivers/net/ethernet/intel/igc/igc_mac.c b/drivers/net/ethernet/intel/igc/igc_mac.c index a5c4b19d71a2..79e65b35ab3d 100644 --- a/drivers/net/ethernet/intel/igc/igc_mac.c +++ b/drivers/net/ethernet/intel/igc/igc_mac.c @@ -3,6 +3,7 @@
#include <linux/pci.h> #include <linux/delay.h> +#include <linux/netdev_features_helper.h>
#include "igc_mac.h" #include "igc_hw.h" diff --git a/drivers/net/ethernet/intel/igc/igc_main.c b/drivers/net/ethernet/intel/igc/igc_main.c index ebff0e04045d..e5b97822e191 100644 --- a/drivers/net/ethernet/intel/igc/igc_main.c +++ b/drivers/net/ethernet/intel/igc/igc_main.c @@ -9,6 +9,7 @@ #include <linux/udp.h> #include <linux/ip.h> #include <linux/pm_runtime.h> +#include <linux/netdev_features_helper.h> #include <net/pkt_sched.h> #include <linux/bpf_trace.h> #include <net/xdp_sock_drv.h> @@ -4973,6 +4974,18 @@ static int igc_set_features(struct net_device *netdev, return 1; }
+static DECLARE_NETDEV_FEATURE_SET(igc_l2_disable_feature_set, + NETIF_F_HW_CSUM_BIT, + NETIF_F_SCTP_CRC_BIT, + NETIF_F_HW_VLAN_CTAG_TX_BIT, + NETIF_F_TSO_BIT, + NETIF_F_TSO6_BIT); +static DECLARE_NETDEV_FEATURE_SET(igc_l3_disable_feature_set, + NETIF_F_HW_CSUM_BIT, + NETIF_F_SCTP_CRC_BIT, + NETIF_F_TSO_BIT, + NETIF_F_TSO6_BIT); + static netdev_features_t igc_features_check(struct sk_buff *skb, struct net_device *dev, netdev_features_t features) @@ -4981,19 +4994,18 @@ igc_features_check(struct sk_buff *skb, struct net_device *dev,
/* Make certain the headers can be described by a context descriptor */ mac_hdr_len = skb_network_header(skb) - skb->data; - if (unlikely(mac_hdr_len > IGC_MAX_MAC_HDR_LEN)) - return features & ~(NETIF_F_HW_CSUM | - NETIF_F_SCTP_CRC | - NETIF_F_HW_VLAN_CTAG_TX | - NETIF_F_TSO | - NETIF_F_TSO6); + if (unlikely(mac_hdr_len > IGC_MAX_MAC_HDR_LEN)) { + netdev_features_clear_array(&igc_l2_disable_feature_set, + &features); + return features; + }
network_hdr_len = skb_checksum_start(skb) - skb_network_header(skb); - if (unlikely(network_hdr_len > IGC_MAX_NETWORK_HDR_LEN)) - return features & ~(NETIF_F_HW_CSUM | - NETIF_F_SCTP_CRC | - NETIF_F_TSO | - NETIF_F_TSO6); + if (unlikely(network_hdr_len > IGC_MAX_NETWORK_HDR_LEN)) { + netdev_features_clear_array(&igc_l3_disable_feature_set, + &features); + return features; + }
/* We can only support IPv4 TSO in tunnels if we can mangle the * inner IP ID field, so strip TSO if MANGLEID is not supported. @@ -6201,6 +6213,23 @@ u32 igc_rd32(struct igc_hw *hw, u32 reg) return value; }
+static DECLARE_NETDEV_FEATURE_SET(igc_feature_set, + NETIF_F_SG_BIT, + NETIF_F_TSO_BIT, + NETIF_F_TSO6_BIT, + NETIF_F_TSO_ECN_BIT, + NETIF_F_RXCSUM_BIT, + NETIF_F_HW_CSUM_BIT, + NETIF_F_SCTP_CRC_BIT, + NETIF_F_HW_TC_BIT); +static DECLARE_NETDEV_FEATURE_SET(igc_gso_partial_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); + /** * igc_probe - Device Initialization Routine * @pdev: PCI device information struct @@ -6219,6 +6248,7 @@ static int igc_probe(struct pci_dev *pdev, struct net_device *netdev; struct igc_hw *hw; const struct igc_info *ei = igc_info_tbl[ent->driver_data]; + netdev_features_t gso_partial_features; int err;
err = pci_enable_device_mem(pdev); @@ -6299,24 +6329,13 @@ static int igc_probe(struct pci_dev *pdev, goto err_sw_init;
/* Add supported features to the features list*/ - netdev->features |= NETIF_F_SG; - netdev->features |= NETIF_F_TSO; - netdev->features |= NETIF_F_TSO6; - netdev->features |= NETIF_F_TSO_ECN; - netdev->features |= NETIF_F_RXCSUM; - netdev->features |= NETIF_F_HW_CSUM; - netdev->features |= NETIF_F_SCTP_CRC; - netdev->features |= NETIF_F_HW_TC; - -#define IGC_GSO_PARTIAL_FEATURES (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) - - netdev->gso_partial_features = IGC_GSO_PARTIAL_FEATURES; - netdev->features |= NETIF_F_GSO_PARTIAL | IGC_GSO_PARTIAL_FEATURES; + netdev_active_features_set_array(netdev, &igc_feature_set); + + netdev_features_zero(&gso_partial_features); + netdev_features_set_array(&igc_gso_partial_feature_set, + &gso_partial_features); + netdev->gso_partial_features = gso_partial_features; + netdev->features |= NETIF_F_GSO_PARTIAL | gso_partial_features;
/* setup the private structure */ err = igc_sw_init(adapter); diff --git a/drivers/net/ethernet/intel/ixgb/ixgb_main.c b/drivers/net/ethernet/intel/ixgb/ixgb_main.c index 45be9a1ab6af..c3ae375f04dd 100644 --- a/drivers/net/ethernet/intel/ixgb/ixgb_main.c +++ b/drivers/net/ethernet/intel/ixgb/ixgb_main.c @@ -3,6 +3,7 @@
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+#include <linux/netdev_features_helper.h> #include <linux/prefetch.h> #include "ixgb.h"
@@ -343,6 +344,13 @@ static const struct net_device_ops ixgb_netdev_ops = { .ndo_set_features = ixgb_set_features, };
+static DECLARE_NETDEV_FEATURE_SET(ixgb_hw_feature_set, + NETIF_F_SG_BIT, + NETIF_F_TSO_BIT, + NETIF_F_HW_CSUM_BIT, + NETIF_F_HW_VLAN_CTAG_TX_BIT, + NETIF_F_HW_VLAN_CTAG_RX_BIT); + /** * ixgb_probe - Device Initialization Routine * @pdev: PCI device information struct @@ -428,11 +436,8 @@ ixgb_probe(struct pci_dev *pdev, const struct pci_device_id *ent) if (err) goto err_sw_init;
- netdev->hw_features = NETIF_F_SG | - NETIF_F_TSO | - NETIF_F_HW_CSUM | - NETIF_F_HW_VLAN_CTAG_TX | - NETIF_F_HW_VLAN_CTAG_RX; + netdev_hw_features_zero(netdev); + netdev_hw_features_set_array(netdev, &ixgb_hw_feature_set); netdev->features = netdev->hw_features | NETIF_F_HW_VLAN_CTAG_FILTER; netdev->hw_features |= NETIF_F_RXCSUM; diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c index d1e430b8c8aa..98db7c46e89c 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c @@ -5,6 +5,7 @@ #include <linux/module.h> #include <linux/pci.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/vmalloc.h> #include <linux/string.h> #include <linux/in.h> @@ -10210,6 +10211,20 @@ static void ixgbe_fwd_del(struct net_device *pdev, void *priv) kfree(accel); }
+static DECLARE_NETDEV_FEATURE_SET(ixgbe_l2_disable_feature_set, + NETIF_F_HW_CSUM_BIT, + NETIF_F_SCTP_CRC_BIT, + NETIF_F_GSO_UDP_L4_BIT, + NETIF_F_HW_VLAN_CTAG_TX_BIT, + NETIF_F_TSO_BIT, + NETIF_F_TSO6_BIT); +static DECLARE_NETDEV_FEATURE_SET(ixgbe_l3_disable_feature_set, + NETIF_F_HW_CSUM_BIT, + NETIF_F_SCTP_CRC_BIT, + NETIF_F_GSO_UDP_L4_BIT, + NETIF_F_TSO_BIT, + NETIF_F_TSO6_BIT); + #define IXGBE_MAX_MAC_HDR_LEN 127 #define IXGBE_MAX_NETWORK_HDR_LEN 511
@@ -10221,21 +10236,18 @@ ixgbe_features_check(struct sk_buff *skb, struct net_device *dev,
/* Make certain the headers can be described by a context descriptor */ mac_hdr_len = skb_network_header(skb) - skb->data; - if (unlikely(mac_hdr_len > IXGBE_MAX_MAC_HDR_LEN)) - return features & ~(NETIF_F_HW_CSUM | - NETIF_F_SCTP_CRC | - NETIF_F_GSO_UDP_L4 | - NETIF_F_HW_VLAN_CTAG_TX | - NETIF_F_TSO | - NETIF_F_TSO6); + if (unlikely(mac_hdr_len > IXGBE_MAX_MAC_HDR_LEN)) { + netdev_features_clear_array(&ixgbe_l2_disable_feature_set, + &features); + return features; + }
network_hdr_len = skb_checksum_start(skb) - skb_network_header(skb); - if (unlikely(network_hdr_len > IXGBE_MAX_NETWORK_HDR_LEN)) - return features & ~(NETIF_F_HW_CSUM | - NETIF_F_SCTP_CRC | - NETIF_F_GSO_UDP_L4 | - NETIF_F_TSO | - NETIF_F_TSO6); + if (unlikely(network_hdr_len > IXGBE_MAX_NETWORK_HDR_LEN)) { + netdev_features_clear_array(&ixgbe_l3_disable_feature_set, + &features); + return features; + }
/* We can only support IPV4 TSO in tunnels if we can mangle the * inner IP ID field, so strip TSO if MANGLEID is not supported. @@ -10755,6 +10767,47 @@ static void ixgbe_set_fw_version(struct ixgbe_adapter *adapter) "0x%08x", nvm_ver.etk_id); }
+static DECLARE_NETDEV_FEATURE_SET(ixgbe_feature_set, + NETIF_F_SG_BIT, + NETIF_F_TSO_BIT, + NETIF_F_TSO6_BIT, + NETIF_F_RXHASH_BIT, + NETIF_F_RXCSUM_BIT, + NETIF_F_HW_CSUM_BIT); +static DECLARE_NETDEV_FEATURE_SET(ixgbe_gso_partial_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); +#ifdef CONFIG_IXGBE_IPSEC +static DECLARE_NETDEV_FEATURE_SET(ixgbe_esp_feature_set, + NETIF_F_HW_ESP_BIT, + NETIF_F_HW_ESP_TX_CSUM_BIT, + NETIF_F_GSO_ESP_BIT); +#endif +static DECLARE_NETDEV_FEATURE_SET(ixgbe_hw_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_RXALL_BIT, + NETIF_F_HW_L2FW_DOFFLOAD_BIT); +static DECLARE_NETDEV_FEATURE_SET(ixgbe_mpls_feature_set, + NETIF_F_SG_BIT, + NETIF_F_TSO_BIT, + NETIF_F_TSO6_BIT, + NETIF_F_HW_CSUM_BIT); +#ifdef IXGBE_FCOE +static DECLARE_NETDEV_FEATURE_SET(ixgbe_fcoe_feature_set, + NETIF_F_FSO_BIT, + NETIF_F_FCOE_CRC_BIT); +static DECLARE_NETDEV_FEATURE_SET(ixgbe_vlan_fcoe_feature_set, + NETIF_F_FSO_BIT, + NETIF_F_FCOE_CRC_BIT, + NETIF_F_FCOE_MTU_BIT); +#endif + /** * ixgbe_probe - Device Initialization Routine * @pdev: PCI device information struct @@ -10772,6 +10825,7 @@ static int ixgbe_probe(struct pci_dev *pdev, const struct pci_device_id *ent) struct ixgbe_adapter *adapter = NULL; struct ixgbe_hw *hw; const struct ixgbe_info *ii = ixgbe_info_tbl[ent->driver_data]; + netdev_features_t gso_partial_features; unsigned int indices = MAX_TX_QUEUES; u8 part_str[IXGBE_PBANUM_LENGTH]; int i, err, expected_gts; @@ -10958,42 +11012,27 @@ static int ixgbe_probe(struct pci_dev *pdev, const struct pci_device_id *ent) skip_sriov:
#endif - netdev->features = NETIF_F_SG | - NETIF_F_TSO | - NETIF_F_TSO6 | - NETIF_F_RXHASH | - NETIF_F_RXCSUM | - NETIF_F_HW_CSUM; - -#define IXGBE_GSO_PARTIAL_FEATURES (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) - - netdev->gso_partial_features = IXGBE_GSO_PARTIAL_FEATURES; + netdev_active_features_zero(netdev); + netdev_active_features_set_array(netdev, &ixgbe_feature_set); + + netdev_features_zero(&gso_partial_features); + netdev_features_set_array(&ixgbe_gso_partial_feature_set, + &gso_partial_features); + + netdev->gso_partial_features = gso_partial_features; netdev->features |= NETIF_F_GSO_PARTIAL | - IXGBE_GSO_PARTIAL_FEATURES; + gso_partial_features;
if (hw->mac.type >= ixgbe_mac_82599EB) netdev->features |= NETIF_F_SCTP_CRC | NETIF_F_GSO_UDP_L4;
#ifdef CONFIG_IXGBE_IPSEC -#define IXGBE_ESP_FEATURES (NETIF_F_HW_ESP | \ - NETIF_F_HW_ESP_TX_CSUM | \ - NETIF_F_GSO_ESP) - if (adapter->ipsec) - netdev->features |= IXGBE_ESP_FEATURES; + netdev_active_features_set_array(netdev, &ixgbe_esp_feature_set); #endif /* copy netdev features into list of user selectable features */ - netdev->hw_features |= netdev->features | - NETIF_F_HW_VLAN_CTAG_FILTER | - NETIF_F_HW_VLAN_CTAG_RX | - NETIF_F_HW_VLAN_CTAG_TX | - NETIF_F_RXALL | - NETIF_F_HW_L2FW_DOFFLOAD; + netdev->hw_features |= netdev->features; + netdev_hw_features_set_array(netdev, &ixgbe_hw_feature_set);
if (hw->mac.type >= ixgbe_mac_82599EB) netdev->hw_features |= NETIF_F_NTUPLE | @@ -11003,11 +11042,8 @@ static int ixgbe_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
netdev->vlan_features |= netdev->features | NETIF_F_TSO_MANGLEID; netdev->hw_enc_features |= netdev->vlan_features; - netdev->mpls_features |= NETIF_F_SG | - NETIF_F_TSO | - NETIF_F_TSO6 | - NETIF_F_HW_CSUM; - netdev->mpls_features |= IXGBE_GSO_PARTIAL_FEATURES; + netdev_mpls_features_set_array(netdev, &ixgbe_mpls_feature_set); + netdev->mpls_features |= gso_partial_features;
/* set this bit last since it cannot be part of vlan_features */ netdev->features |= NETIF_F_HW_VLAN_CTAG_FILTER | @@ -11040,12 +11076,8 @@ static int ixgbe_probe(struct pci_dev *pdev, const struct pci_device_id *ent) fcoe_l = min_t(int, IXGBE_FCRETA_SIZE, num_online_cpus()); adapter->ring_feature[RING_F_FCOE].limit = fcoe_l;
- netdev->features |= NETIF_F_FSO | - NETIF_F_FCOE_CRC; - - netdev->vlan_features |= NETIF_F_FSO | - NETIF_F_FCOE_CRC | - NETIF_F_FCOE_MTU; + netdev_active_features_set_array(netdev, &ixgbe_fcoe_feature_set); + netdev_vlan_features_set_array(netdev, &ixgbe_vlan_fcoe_feature_set); } #endif /* IXGBE_FCOE */ if (adapter->flags2 & IXGBE_FLAG2_RSC_CAPABLE) diff --git a/drivers/net/ethernet/intel/ixgbevf/ipsec.c b/drivers/net/ethernet/intel/ixgbevf/ipsec.c index 9984ebc62d78..82341ac13e62 100644 --- a/drivers/net/ethernet/intel/ixgbevf/ipsec.c +++ b/drivers/net/ethernet/intel/ixgbevf/ipsec.c @@ -612,6 +612,11 @@ void ixgbevf_ipsec_rx(struct ixgbevf_ring *rx_ring, adapter->rx_ipsec++; }
+static DECLARE_NETDEV_FEATURE_SET(ixgbevf_esp_feature_set, + NETIF_F_HW_ESP_BIT, + NETIF_F_HW_ESP_TX_CSUM_BIT, + NETIF_F_GSO_ESP_BIT); + /** * ixgbevf_init_ipsec_offload - initialize registers for IPsec operation * @adapter: board private structure @@ -651,12 +656,10 @@ void ixgbevf_init_ipsec_offload(struct ixgbevf_adapter *adapter)
adapter->netdev->xfrmdev_ops = &ixgbevf_xfrmdev_ops;
-#define IXGBEVF_ESP_FEATURES (NETIF_F_HW_ESP | \ - NETIF_F_HW_ESP_TX_CSUM | \ - NETIF_F_GSO_ESP) - - adapter->netdev->features |= IXGBEVF_ESP_FEATURES; - adapter->netdev->hw_enc_features |= IXGBEVF_ESP_FEATURES; + netdev_active_features_set_array(adapter->netdev, + &ixgbevf_esp_feature_set); + netdev_hw_enc_features_set_array(adapter->netdev, + &ixgbevf_esp_feature_set);
return;
diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h b/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h index 149c733fcc2b..29bad7b3f573 100644 --- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h +++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h @@ -9,6 +9,7 @@ #include <linux/timer.h> #include <linux/io.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/if_vlan.h> #include <linux/u64_stats_sync.h> #include <net/xdp.h> diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c index 2f12fbe229c1..095159721a96 100644 --- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c +++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c @@ -12,6 +12,7 @@ #include <linux/module.h> #include <linux/pci.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/vmalloc.h> #include <linux/string.h> #include <linux/in.h> @@ -4396,6 +4397,18 @@ static void ixgbevf_get_stats(struct net_device *netdev, rcu_read_unlock(); }
+static DECLARE_NETDEV_FEATURE_SET(ixgbevf_l2_disable_feature_set, + NETIF_F_HW_CSUM_BIT, + NETIF_F_SCTP_CRC_BIT, + NETIF_F_HW_VLAN_CTAG_TX_BIT, + NETIF_F_TSO_BIT, + NETIF_F_TSO6_BIT); +static DECLARE_NETDEV_FEATURE_SET(ixgbevf_l3_disable_feature_set, + NETIF_F_HW_CSUM_BIT, + NETIF_F_SCTP_CRC_BIT, + NETIF_F_TSO_BIT, + NETIF_F_TSO6_BIT); + #define IXGBEVF_MAX_MAC_HDR_LEN 127 #define IXGBEVF_MAX_NETWORK_HDR_LEN 511
@@ -4407,19 +4420,18 @@ ixgbevf_features_check(struct sk_buff *skb, struct net_device *dev,
/* Make certain the headers can be described by a context descriptor */ mac_hdr_len = skb_network_header(skb) - skb->data; - if (unlikely(mac_hdr_len > IXGBEVF_MAX_MAC_HDR_LEN)) - return features & ~(NETIF_F_HW_CSUM | - NETIF_F_SCTP_CRC | - NETIF_F_HW_VLAN_CTAG_TX | - NETIF_F_TSO | - NETIF_F_TSO6); + if (unlikely(mac_hdr_len > IXGBEVF_MAX_MAC_HDR_LEN)) { + netdev_features_clear_array(&ixgbevf_l2_disable_feature_set, + &features); + return features; + }
network_hdr_len = skb_checksum_start(skb) - skb_network_header(skb); - if (unlikely(network_hdr_len > IXGBEVF_MAX_NETWORK_HDR_LEN)) - return features & ~(NETIF_F_HW_CSUM | - NETIF_F_SCTP_CRC | - NETIF_F_TSO | - NETIF_F_TSO6); + if (unlikely(network_hdr_len > IXGBEVF_MAX_NETWORK_HDR_LEN)) { + netdev_features_clear_array(&ixgbevf_l3_disable_feature_set, + &features); + return features; + }
/* We can only support IPV4 TSO in tunnels if we can mangle the * inner IP ID field, so strip TSO if MANGLEID is not supported. @@ -4504,6 +4516,26 @@ static void ixgbevf_assign_netdev_ops(struct net_device *dev) dev->watchdog_timeo = 5 * HZ; }
+static DECLARE_NETDEV_FEATURE_SET(ixgbevf_hw_feature_set, + NETIF_F_SG_BIT, + NETIF_F_TSO_BIT, + NETIF_F_TSO6_BIT, + NETIF_F_RXCSUM_BIT, + NETIF_F_HW_CSUM_BIT, + NETIF_F_SCTP_CRC_BIT); +static DECLARE_NETDEV_FEATURE_SET(ixgbevf_gso_partial_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); +static DECLARE_NETDEV_FEATURE_SET(ixgbevf_mpls_feature_set, + NETIF_F_SG_BIT, + NETIF_F_TSO_BIT, + NETIF_F_TSO6_BIT, + NETIF_F_HW_CSUM_BIT); + /** * ixgbevf_probe - Device Initialization Routine * @pdev: PCI device information struct @@ -4521,6 +4553,7 @@ static int ixgbevf_probe(struct pci_dev *pdev, const struct pci_device_id *ent) struct ixgbevf_adapter *adapter = NULL; struct ixgbe_hw *hw = NULL; const struct ixgbevf_info *ii = ixgbevf_info_tbl[ent->driver_data]; + netdev_features_t gso_partial_features; bool disable_dev = false; int err;
@@ -4593,32 +4626,22 @@ static int ixgbevf_probe(struct pci_dev *pdev, const struct pci_device_id *ent) goto err_sw_init; }
- netdev->hw_features = NETIF_F_SG | - NETIF_F_TSO | - NETIF_F_TSO6 | - NETIF_F_RXCSUM | - NETIF_F_HW_CSUM | - NETIF_F_SCTP_CRC; - -#define IXGBEVF_GSO_PARTIAL_FEATURES (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) - - netdev->gso_partial_features = IXGBEVF_GSO_PARTIAL_FEATURES; + netdev_hw_features_zero(netdev); + netdev_hw_features_set_array(netdev, &ixgbevf_hw_feature_set); + + netdev_features_zero(&gso_partial_features); + netdev_features_set_array(&ixgbevf_gso_partial_feature_set, + &gso_partial_features); + netdev->gso_partial_features = gso_partial_features; netdev->hw_features |= NETIF_F_GSO_PARTIAL | - IXGBEVF_GSO_PARTIAL_FEATURES; + gso_partial_features;
netdev->features = netdev->hw_features | NETIF_F_HIGHDMA;
netdev->vlan_features |= netdev->features | NETIF_F_TSO_MANGLEID; - netdev->mpls_features |= NETIF_F_SG | - NETIF_F_TSO | - NETIF_F_TSO6 | - NETIF_F_HW_CSUM; - netdev->mpls_features |= IXGBEVF_GSO_PARTIAL_FEATURES; + + netdev_mpls_features_set_array(netdev, &ixgbevf_mpls_feature_set); + netdev->mpls_features |= gso_partial_features; netdev->hw_enc_features |= netdev->vlan_features;
/* set this bit last since it cannot be part of vlan_features */ diff --git a/drivers/net/ethernet/jme.c b/drivers/net/ethernet/jme.c index f43d6616bc0d..6db2f01468c5 100644 --- a/drivers/net/ethernet/jme.c +++ b/drivers/net/ethernet/jme.c @@ -15,6 +15,7 @@ #include <linux/kernel.h> #include <linux/pci.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/etherdevice.h> #include <linux/ethtool.h> #include <linux/mii.h> @@ -2901,6 +2902,22 @@ static const struct net_device_ops jme_netdev_ops = { #endif };
+static DECLARE_NETDEV_FEATURE_SET(jme_hw_feature_set, + NETIF_F_IP_CSUM_BIT, + NETIF_F_IPV6_CSUM_BIT, + NETIF_F_SG_BIT, + NETIF_F_TSO_BIT, + NETIF_F_TSO6_BIT, + NETIF_F_RXCSUM_BIT); +static DECLARE_NETDEV_FEATURE_SET(jme_feature_set, + NETIF_F_IP_CSUM_BIT, + NETIF_F_IPV6_CSUM_BIT, + NETIF_F_SG_BIT, + NETIF_F_TSO_BIT, + NETIF_F_TSO6_BIT, + NETIF_F_HW_VLAN_CTAG_TX_BIT, + NETIF_F_HW_VLAN_CTAG_RX_BIT); + static int jme_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) @@ -2955,19 +2972,10 @@ jme_init_one(struct pci_dev *pdev, netdev->netdev_ops = &jme_netdev_ops; netdev->ethtool_ops = &jme_ethtool_ops; netdev->watchdog_timeo = TX_TIMEOUT; - netdev->hw_features = NETIF_F_IP_CSUM | - NETIF_F_IPV6_CSUM | - NETIF_F_SG | - NETIF_F_TSO | - NETIF_F_TSO6 | - NETIF_F_RXCSUM; - netdev->features = NETIF_F_IP_CSUM | - NETIF_F_IPV6_CSUM | - NETIF_F_SG | - NETIF_F_TSO | - NETIF_F_TSO6 | - NETIF_F_HW_VLAN_CTAG_TX | - NETIF_F_HW_VLAN_CTAG_RX; + netdev_hw_features_zero(netdev); + netdev_hw_features_set_array(netdev, &jme_hw_feature_set); + netdev_active_features_zero(netdev); + netdev_active_features_set_array(netdev, &jme_feature_set); if (using_dac) netdev->features |= NETIF_F_HIGHDMA;
diff --git a/drivers/net/ethernet/marvell/mv643xx_eth.c b/drivers/net/ethernet/marvell/mv643xx_eth.c index b6be0552a6c1..e43fa3a2af17 100644 --- a/drivers/net/ethernet/marvell/mv643xx_eth.c +++ b/drivers/net/ethernet/marvell/mv643xx_eth.c @@ -38,6 +38,7 @@ #include <linux/ethtool.h> #include <linux/platform_device.h> #include <linux/module.h> +#include <linux/netdev_features_helper.h> #include <linux/kernel.h> #include <linux/spinlock.h> #include <linux/workqueue.h> @@ -3086,6 +3087,11 @@ static const struct net_device_ops mv643xx_eth_netdev_ops = { #endif };
+static DECLARE_NETDEV_FEATURE_SET(mv643xx_feature_set, + NETIF_F_SG_BIT, + NETIF_F_IP_CSUM_BIT, + NETIF_F_TSO_BIT); + static int mv643xx_eth_probe(struct platform_device *pdev) { struct mv643xx_eth_platform_data *pd; @@ -3200,7 +3206,8 @@ static int mv643xx_eth_probe(struct platform_device *pdev) dev->watchdog_timeo = 2 * HZ; dev->base_addr = 0;
- dev->features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO; + netdev_active_features_zero(dev); + netdev_active_features_set_array(dev, &mv643xx_feature_set); dev->vlan_features = dev->features;
dev->features |= NETIF_F_RXCSUM; diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c index 0caa2df87c04..b097a857fe4e 100644 --- a/drivers/net/ethernet/marvell/mvneta.c +++ b/drivers/net/ethernet/marvell/mvneta.c @@ -22,6 +22,7 @@ #include <linux/mbus.h> #include <linux/module.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/of.h> #include <linux/of_address.h> #include <linux/of_irq.h> @@ -5377,6 +5378,13 @@ static int mvneta_port_power_up(struct mvneta_port *pp, int phy_mode) return 0; }
+static DECLARE_NETDEV_FEATURE_SET(mvneta_feature_set, + NETIF_F_SG_BIT, + NETIF_F_IP_CSUM_BIT, + NETIF_F_IPV6_CSUM_BIT, + NETIF_F_TSO_BIT, + NETIF_F_RXCSUM_BIT); + /* Device initialization routine */ static int mvneta_probe(struct platform_device *pdev) { @@ -5612,8 +5620,8 @@ static int mvneta_probe(struct platform_device *pdev) } }
- dev->features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | - NETIF_F_TSO | NETIF_F_RXCSUM; + netdev_active_features_zero(dev); + netdev_active_features_set_array(dev, &mvneta_feature_set); dev->hw_features |= dev->features; dev->vlan_features |= dev->features; dev->priv_flags |= IFF_LIVE_ADDR_CHANGE; diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c index b84128b549b4..38c5ab6a5126 100644 --- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c +++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c @@ -10,6 +10,7 @@ #include <linux/acpi.h> #include <linux/kernel.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/etherdevice.h> #include <linux/platform_device.h> #include <linux/skbuff.h> @@ -6653,6 +6654,16 @@ static bool mvpp2_use_acpi_compat_mode(struct fwnode_handle *port_fwnode) !fwnode_get_named_child_node(port_fwnode, "fixed-link")); }
+static DECLARE_NETDEV_FEATURE_SET(mvpp2_feature_set, + NETIF_F_SG_BIT, + NETIF_F_IP_CSUM_BIT, + NETIF_F_IPV6_CSUM_BIT, + NETIF_F_TSO_BIT); +static DECLARE_NETDEV_FEATURE_SET(mvpp2_hw_feature_set, + NETIF_F_RXCSUM_BIT, + NETIF_F_GRO_BIT, + NETIF_F_HW_VLAN_CTAG_FILTER_BIT); + /* Ports initialization */ static int mvpp2_port_probe(struct platform_device *pdev, struct fwnode_handle *port_fwnode, @@ -6846,11 +6857,11 @@ static int mvpp2_port_probe(struct platform_device *pdev, } }
- features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | - NETIF_F_TSO; + netdev_features_zero(&features); + netdev_features_set_array(&mvpp2_feature_set, &features); dev->features = features | NETIF_F_RXCSUM; - dev->hw_features |= features | NETIF_F_RXCSUM | NETIF_F_GRO | - NETIF_F_HW_VLAN_CTAG_FILTER; + dev->hw_features |= features; + netdev_hw_features_set_array(dev, &mvpp2_hw_feature_set);
if (mvpp22_rss_is_supported(port)) { dev->hw_features |= NETIF_F_RXHASH; diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c index 9376d0e62914..a228447cbb2e 100644 --- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c +++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c @@ -15,6 +15,7 @@ #include <net/ip.h> #include <linux/bpf.h> #include <linux/bpf_trace.h> +#include <linux/netdev_features_helper.h>
#include "otx2_reg.h" #include "otx2_common.h" @@ -2550,6 +2551,16 @@ static void otx2_sriov_vfcfg_cleanup(struct otx2_nic *pf) } }
+static DECLARE_NETDEV_FEATURE_SET(otx2_hw_feature_set, + NETIF_F_RXCSUM_BIT, + NETIF_F_IP_CSUM_BIT, + NETIF_F_IPV6_CSUM_BIT, + NETIF_F_RXHASH_BIT, + NETIF_F_SG_BIT, + NETIF_F_TSO_BIT, + NETIF_F_TSO6_BIT, + NETIF_F_GSO_UDP_L4_BIT); + static int otx2_probe(struct pci_dev *pdev, const struct pci_device_id *id) { struct device *dev = &pdev->dev; @@ -2692,10 +2703,8 @@ static int otx2_probe(struct pci_dev *pdev, const struct pci_device_id *id) */ pf->iommu_domain = iommu_get_domain_for_dev(dev);
- netdev->hw_features = (NETIF_F_RXCSUM | NETIF_F_IP_CSUM | - NETIF_F_IPV6_CSUM | NETIF_F_RXHASH | - NETIF_F_SG | NETIF_F_TSO | NETIF_F_TSO6 | - NETIF_F_GSO_UDP_L4); + netdev_hw_features_zero(netdev); + netdev_hw_features_set_array(netdev, &otx2_hw_feature_set); netdev->features |= netdev->hw_features;
err = otx2_mcam_flow_init(pf); diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_vf.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_vf.c index 86653bb8e403..08c82c0d41a4 100644 --- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_vf.c +++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_vf.c @@ -7,6 +7,7 @@
#include <linux/etherdevice.h> #include <linux/module.h> +#include <linux/netdev_features_helper.h> #include <linux/pci.h> #include <linux/net_tstamp.h>
@@ -520,6 +521,16 @@ static int otx2vf_realloc_msix_vectors(struct otx2_nic *vf) return otx2vf_register_mbox_intr(vf, false); }
+static DECLARE_NETDEV_FEATURE_SET(otx2vf_hw_feature_set, + NETIF_F_RXCSUM_BIT, + NETIF_F_IP_CSUM_BIT, + NETIF_F_IPV6_CSUM_BIT, + NETIF_F_RXHASH_BIT, + NETIF_F_SG_BIT, + NETIF_F_TSO_BIT, + NETIF_F_TSO6_BIT, + NETIF_F_GSO_UDP_L4_BIT); + static int otx2vf_probe(struct pci_dev *pdev, const struct pci_device_id *id) { int num_vec = pci_msix_vec_count(pdev); @@ -637,10 +648,8 @@ static int otx2vf_probe(struct pci_dev *pdev, const struct pci_device_id *id) /* Assign default mac address */ otx2_get_mac_from_af(netdev);
- netdev->hw_features = NETIF_F_RXCSUM | NETIF_F_IP_CSUM | - NETIF_F_IPV6_CSUM | NETIF_F_RXHASH | - NETIF_F_SG | NETIF_F_TSO | NETIF_F_TSO6 | - NETIF_F_GSO_UDP_L4; + netdev_hw_features_zero(netdev); + netdev_hw_features_set_array(netdev, &otx2vf_hw_feature_set); netdev->features = netdev->hw_features; /* Support TSO on tag interface */ netdev->vlan_features |= netdev->features; diff --git a/drivers/net/ethernet/marvell/skge.c b/drivers/net/ethernet/marvell/skge.c index c1e985416c0e..8bdac1c90c0c 100644 --- a/drivers/net/ethernet/marvell/skge.c +++ b/drivers/net/ethernet/marvell/skge.c @@ -18,6 +18,7 @@ #include <linux/module.h> #include <linux/moduleparam.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/etherdevice.h> #include <linux/ethtool.h> #include <linux/pci.h> @@ -3806,6 +3807,10 @@ static const struct net_device_ops skge_netdev_ops = { #endif };
+static DECLARE_NETDEV_FEATURE_SET(skge_hw_feature_set, + NETIF_F_IP_CSUM_BIT, + NETIF_F_SG_BIT, + NETIF_F_RXCSUM_BIT);
/* Initialize network device */ static struct net_device *skge_devinit(struct skge_hw *hw, int port, @@ -3860,8 +3865,8 @@ static struct net_device *skge_devinit(struct skge_hw *hw, int port, if (is_genesis(hw)) timer_setup(&skge->link_timer, xm_link_timer, 0); else { - dev->hw_features = NETIF_F_IP_CSUM | NETIF_F_SG | - NETIF_F_RXCSUM; + netdev_hw_features_zero(dev); + netdev_hw_features_set_array(dev, &skge_hw_feature_set); dev->features |= dev->hw_features; }
diff --git a/drivers/net/ethernet/marvell/sky2.c b/drivers/net/ethernet/marvell/sky2.c index bbea5458000b..e3b3b2c7aff3 100644 --- a/drivers/net/ethernet/marvell/sky2.c +++ b/drivers/net/ethernet/marvell/sky2.c @@ -16,6 +16,7 @@ #include <linux/kernel.h> #include <linux/module.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/dma-mapping.h> #include <linux/etherdevice.h> #include <linux/ethtool.h> @@ -1398,7 +1399,10 @@ static int sky2_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) return err; }
-#define SKY2_VLAN_OFFLOADS (NETIF_F_IP_CSUM | NETIF_F_SG | NETIF_F_TSO) +static DECLARE_NETDEV_FEATURE_SET(sky2_vlan_feature_set, + NETIF_F_IP_CSUM_BIT, + NETIF_F_SG_BIT, + NETIF_F_TSO_BIT);
static void sky2_vlan_mode(struct net_device *dev, netdev_features_t features) { @@ -1417,13 +1421,13 @@ static void sky2_vlan_mode(struct net_device *dev, netdev_features_t features) sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T), TX_VLAN_TAG_ON);
- dev->vlan_features |= SKY2_VLAN_OFFLOADS; + netdev_vlan_features_set_array(dev, &sky2_vlan_feature_set); } else { sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T), TX_VLAN_TAG_OFF);
/* Can't do transmit offload of vlan without hw vlan */ - dev->vlan_features &= ~SKY2_VLAN_OFFLOADS; + netdev_vlan_features_clear_array(dev, &sky2_vlan_feature_set); } }
@@ -4587,6 +4591,11 @@ static const struct net_device_ops sky2_netdev_ops[2] = { }, };
+static DECLARE_NETDEV_FEATURE_SET(sky2_hw_feature_set, + NETIF_F_IP_CSUM_BIT, + NETIF_F_SG_BIT, + NETIF_F_TSO_BIT); + /* Initialize network device */ static struct net_device *sky2_init_netdev(struct sky2_hw *hw, unsigned port, int highmem, int wol) @@ -4634,7 +4643,7 @@ static struct net_device *sky2_init_netdev(struct sky2_hw *hw, unsigned port,
sky2->port = port;
- dev->hw_features |= NETIF_F_IP_CSUM | NETIF_F_SG | NETIF_F_TSO; + netdev_hw_features_set_array(dev, &sky2_hw_feature_set);
if (highmem) dev->features |= NETIF_F_HIGHDMA; @@ -4646,7 +4655,7 @@ static struct net_device *sky2_init_netdev(struct sky2_hw *hw, unsigned port, if (!(hw->flags & SKY2_HW_VLAN_BROKEN)) { dev->hw_features |= NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX; - dev->vlan_features |= SKY2_VLAN_OFFLOADS; + netdev_vlan_features_set_array(dev, &sky2_vlan_feature_set); }
dev->features |= dev->hw_features; diff --git a/drivers/net/ethernet/mellanox/mlx4/en_main.c b/drivers/net/ethernet/mellanox/mlx4/en_main.c index f1259bdb1a29..edde15669886 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_main.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_main.c @@ -35,6 +35,7 @@ #include <linux/module.h> #include <linux/delay.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/slab.h>
#include <linux/mlx4/driver.h> diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c index ca4b93a01034..594a650b6bdc 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c @@ -39,6 +39,7 @@ #include <linux/delay.h> #include <linux/slab.h> #include <linux/hash.h> +#include <linux/netdev_features_helper.h> #include <net/ip.h> #include <net/vxlan.h> #include <net/devlink.h> @@ -3155,6 +3156,41 @@ void mlx4_en_set_stats_bitmap(struct mlx4_dev *dev, last_i += NUM_PHY_STATS; }
+static DECLARE_NETDEV_FEATURE_SET(mlx4_gso_feature_set, + NETIF_F_GSO_UDP_TUNNEL_BIT, + NETIF_F_GSO_UDP_TUNNEL_CSUM_BIT, + NETIF_F_GSO_PARTIAL_BIT); +static DECLARE_NETDEV_FEATURE_SET(mlx4_hw_enc_feature_set, + NETIF_F_IP_CSUM_BIT, + NETIF_F_IPV6_CSUM_BIT, + NETIF_F_RXCSUM_BIT, + NETIF_F_TSO_BIT, + NETIF_F_TSO6_BIT, + NETIF_F_GSO_UDP_TUNNEL_BIT, + NETIF_F_GSO_UDP_TUNNEL_CSUM_BIT, + NETIF_F_GSO_PARTIAL_BIT); +static DECLARE_NETDEV_FEATURE_SET(mlx4_feature_set, + NETIF_F_HIGHDMA_BIT, + NETIF_F_HW_VLAN_CTAG_TX_BIT, + NETIF_F_HW_VLAN_CTAG_RX_BIT, + NETIF_F_HW_VLAN_CTAG_FILTER_BIT); +static DECLARE_NETDEV_FEATURE_SET(mlx4_hw_feature_set1, + NETIF_F_SG_BIT, + NETIF_F_IP_CSUM_BIT, + NETIF_F_IPV6_CSUM_BIT); +static DECLARE_NETDEV_FEATURE_SET(mlx4_hw_feature_set2, + NETIF_F_RXCSUM_BIT, + NETIF_F_RXHASH_BIT); +static DECLARE_NETDEV_FEATURE_SET(mlx4_hw_feature_set3, + NETIF_F_LOOPBACK_BIT, + NETIF_F_HW_VLAN_CTAG_TX_BIT, + NETIF_F_HW_VLAN_CTAG_RX_BIT); +static DECLARE_NETDEV_FEATURE_SET(mlx4_vlan_tag_feature_set, + NETIF_F_HW_VLAN_CTAG_TX_BIT, + NETIF_F_HW_VLAN_CTAG_RX_BIT, + NETIF_F_HW_VLAN_STAG_TX_BIT, + NETIF_F_HW_VLAN_STAG_RX_BIT); + int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port, struct mlx4_en_port_profile *prof) { @@ -3322,37 +3358,28 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port, /* * Set driver features */ - dev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM; + netdev_hw_features_zero(dev); + netdev_hw_features_set_array(dev, &mlx4_hw_feature_set1); if (mdev->LSO_support) dev->hw_features |= NETIF_F_TSO | NETIF_F_TSO6;
if (mdev->dev->caps.tunnel_offload_mode == MLX4_TUNNEL_OFFLOAD_MODE_VXLAN) { - dev->hw_features |= NETIF_F_GSO_UDP_TUNNEL | - NETIF_F_GSO_UDP_TUNNEL_CSUM | - NETIF_F_GSO_PARTIAL; - dev->features |= NETIF_F_GSO_UDP_TUNNEL | - NETIF_F_GSO_UDP_TUNNEL_CSUM | - NETIF_F_GSO_PARTIAL; + netdev_hw_features_set_array(dev, &mlx4_gso_feature_set); + netdev_active_features_set_array(dev, &mlx4_gso_feature_set); dev->gso_partial_features = NETIF_F_GSO_UDP_TUNNEL_CSUM; - dev->hw_enc_features = NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | - NETIF_F_RXCSUM | - NETIF_F_TSO | NETIF_F_TSO6 | - NETIF_F_GSO_UDP_TUNNEL | - NETIF_F_GSO_UDP_TUNNEL_CSUM | - NETIF_F_GSO_PARTIAL; + netdev_hw_enc_features_zero(dev); + netdev_hw_enc_features_set_array(dev, &mlx4_hw_enc_feature_set);
dev->udp_tunnel_nic_info = &mlx4_udp_tunnels; }
dev->vlan_features = dev->hw_features;
- dev->hw_features |= NETIF_F_RXCSUM | NETIF_F_RXHASH; - dev->features = dev->hw_features | NETIF_F_HIGHDMA | - NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX | - NETIF_F_HW_VLAN_CTAG_FILTER; - dev->hw_features |= NETIF_F_LOOPBACK | - NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX; + netdev_hw_features_set_array(dev, &mlx4_hw_feature_set2); + dev->features = dev->hw_features; + netdev_active_features_set_array(dev, &mlx4_feature_set); + netdev_hw_features_set_array(dev, &mlx4_hw_feature_set3);
if (!(mdev->dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_SKIP_OUTER_VLAN)) { dev->features |= NETIF_F_HW_VLAN_STAG_RX | @@ -3372,14 +3399,8 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port, err = mlx4_get_is_vlan_offload_disabled(mdev->dev, port, &vlan_offload_disabled); if (!err && vlan_offload_disabled) { - dev->hw_features &= ~(NETIF_F_HW_VLAN_CTAG_TX | - NETIF_F_HW_VLAN_CTAG_RX | - NETIF_F_HW_VLAN_STAG_TX | - NETIF_F_HW_VLAN_STAG_RX); - dev->features &= ~(NETIF_F_HW_VLAN_CTAG_TX | - NETIF_F_HW_VLAN_CTAG_RX | - NETIF_F_HW_VLAN_STAG_TX | - NETIF_F_HW_VLAN_STAG_RX); + netdev_hw_features_clear_array(dev, &mlx4_vlan_tag_feature_set); + netdev_active_features_clear_array(dev, &mlx4_vlan_tag_feature_set); } } else { if (mdev->dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_PHV_EN && diff --git a/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib.c b/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib.c index 0a99a020a3b2..766abe31749b 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib.c @@ -31,6 +31,7 @@ */
#include <rdma/ib_verbs.h> +#include <linux/netdev_features_helper.h> #include <linux/mlx5/fs.h> #include "en.h" #include "en/params.h" @@ -72,6 +73,16 @@ static void mlx5i_build_nic_params(struct mlx5_core_dev *mdev, params->tunneled_offload_en = false; }
+static DECLARE_NETDEV_FEATURE_SET(mlx5i_hw_feature_set, + NETIF_F_SG_BIT, + NETIF_F_IP_CSUM_BIT, + NETIF_F_IPV6_CSUM_BIT, + NETIF_F_GRO_BIT, + NETIF_F_TSO_BIT, + NETIF_F_TSO6_BIT, + NETIF_F_RXCSUM_BIT, + NETIF_F_RXHASH_BIT); + /* Called directly after IPoIB netdevice was created to initialize SW structs */ int mlx5i_init(struct mlx5_core_dev *mdev, struct net_device *netdev) { @@ -87,14 +98,7 @@ int mlx5i_init(struct mlx5_core_dev *mdev, struct net_device *netdev) mlx5e_timestamp_init(priv);
/* netdev init */ - netdev->hw_features |= NETIF_F_SG; - netdev->hw_features |= NETIF_F_IP_CSUM; - netdev->hw_features |= NETIF_F_IPV6_CSUM; - netdev->hw_features |= NETIF_F_GRO; - netdev->hw_features |= NETIF_F_TSO; - netdev->hw_features |= NETIF_F_TSO6; - netdev->hw_features |= NETIF_F_RXCSUM; - netdev->hw_features |= NETIF_F_RXHASH; + netdev_hw_features_set_array(netdev, &mlx5i_hw_feature_set);
netdev->netdev_ops = &mlx5i_netdev_ops; netdev->ethtool_ops = &mlx5i_ethtool_ops; diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c index 1e240cdd9cbd..a38ed21cfbdf 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c @@ -6,6 +6,7 @@ #include <linux/types.h> #include <linux/pci.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/etherdevice.h> #include <linux/ethtool.h> #include <linux/slab.h> @@ -1596,6 +1597,16 @@ static int mlxsw_sp_port_label_info_get(struct mlxsw_sp *mlxsw_sp, return 0; }
+static DECLARE_NETDEV_FEATURE_SET(mlxsw_feature_set, + NETIF_F_NETNS_LOCAL_BIT, + NETIF_F_LLTX_BIT, + NETIF_F_SG_BIT, + NETIF_F_HW_VLAN_CTAG_FILTER_BIT, + NETIF_F_HW_TC_BIT); +static DECLARE_NETDEV_FEATURE_SET(mlxsw_hw_feature_set, + NETIF_F_HW_TC_BIT, + NETIF_F_LOOPBACK_BIT); + static int mlxsw_sp_port_create(struct mlxsw_sp *mlxsw_sp, u16 local_port, bool split, struct mlxsw_sp_port_mapping *port_mapping) @@ -1682,9 +1693,8 @@ static int mlxsw_sp_port_create(struct mlxsw_sp *mlxsw_sp, u16 local_port,
netif_carrier_off(dev);
- dev->features |= NETIF_F_NETNS_LOCAL | NETIF_F_LLTX | NETIF_F_SG | - NETIF_F_HW_VLAN_CTAG_FILTER | NETIF_F_HW_TC; - dev->hw_features |= NETIF_F_HW_TC | NETIF_F_LOOPBACK; + netdev_active_features_set_array(dev, &mlxsw_feature_set); + netdev_hw_features_set_array(dev, &mlxsw_hw_feature_set);
dev->min_mtu = 0; dev->max_mtu = ETH_MAX_MTU; diff --git a/drivers/net/ethernet/micrel/ksz884x.c b/drivers/net/ethernet/micrel/ksz884x.c index 2b3eb5ed8233..07b6d0124d1a 100644 --- a/drivers/net/ethernet/micrel/ksz884x.c +++ b/drivers/net/ethernet/micrel/ksz884x.c @@ -26,6 +26,7 @@ #include <linux/sched.h> #include <linux/slab.h> #include <linux/micrel_phy.h> +#include <linux/netdev_features_helper.h>
/* DMA Registers */ @@ -6686,6 +6687,11 @@ static int stp; */ static int fast_aging;
+static DECLARE_NETDEV_FEATURE_SET(ksz_hw_feature_set, + NETIF_F_IP_CSUM_BIT, + NETIF_F_SG_BIT, + NETIF_F_RXCSUM_BIT); + /** * netdev_init - initialize network device. * @dev: Network device. @@ -6705,7 +6711,8 @@ static int __init netdev_init(struct net_device *dev) /* 500 ms timeout */ dev->watchdog_timeo = HZ / 2;
- dev->hw_features = NETIF_F_IP_CSUM | NETIF_F_SG | NETIF_F_RXCSUM; + netdev_hw_features_zero(dev); + netdev_hw_features_set_array(dev, &ksz_hw_feature_set);
/* * Hardware does not really support IPv6 checksum generation, but diff --git a/drivers/net/ethernet/microchip/lan743x_main.c b/drivers/net/ethernet/microchip/lan743x_main.c index a9a1dea6d731..5f429b54bc30 100644 --- a/drivers/net/ethernet/microchip/lan743x_main.c +++ b/drivers/net/ethernet/microchip/lan743x_main.c @@ -4,6 +4,7 @@ #include <linux/module.h> #include <linux/pci.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/etherdevice.h> #include <linux/crc32.h> #include <linux/microchipphy.h> @@ -3323,6 +3324,11 @@ static int lan743x_mdiobus_init(struct lan743x_adapter *adapter) return ret; }
+static DECLARE_NETDEV_FEATURE_SET(lan743x_hw_feature_set, + NETIF_F_SG_BIT, + NETIF_F_TSO_BIT, + NETIF_F_HW_CSUM_BIT); + /* lan743x_pcidev_probe - Device Initialization Routine * @pdev: PCI device information struct * @id: entry in lan743x_pci_tbl @@ -3383,7 +3389,8 @@ static int lan743x_pcidev_probe(struct pci_dev *pdev,
adapter->netdev->netdev_ops = &lan743x_netdev_ops; adapter->netdev->ethtool_ops = &lan743x_ethtool_ops; - adapter->netdev->features = NETIF_F_SG | NETIF_F_TSO | NETIF_F_HW_CSUM; + netdev_active_features_zero(adapter->netdev); + netdev_active_features_set_array(adapter->netdev, &lan743x_hw_feature_set); adapter->netdev->hw_features = adapter->netdev->features;
/* carrier off reporting is important to ethtool even BEFORE open */ diff --git a/drivers/net/ethernet/microsoft/mana/mana_en.c b/drivers/net/ethernet/microsoft/mana/mana_en.c index 9259a74eca40..d2a424573d89 100644 --- a/drivers/net/ethernet/microsoft/mana/mana_en.c +++ b/drivers/net/ethernet/microsoft/mana/mana_en.c @@ -2039,6 +2039,15 @@ int mana_detach(struct net_device *ndev, bool from_close) return 0; }
+static DECLARE_NETDEV_FEATURE_SET(mana_hw_feature_set, + NETIF_F_SG_BIT, + NETIF_F_IP_CSUM_BIT, + NETIF_F_IPV6_CSUM_BIT, + NETIF_F_RXCSUM_BIT, + NETIF_F_TSO_BIT, + NETIF_F_TSO6_BIT, + NETIF_F_RXHASH_BIT); + static int mana_probe_port(struct mana_context *ac, int port_idx, struct net_device **ndev_storage) { @@ -2081,10 +2090,8 @@ static int mana_probe_port(struct mana_context *ac, int port_idx,
netdev_lockdep_set_classes(ndev);
- ndev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM; - ndev->hw_features |= NETIF_F_RXCSUM; - ndev->hw_features |= NETIF_F_TSO | NETIF_F_TSO6; - ndev->hw_features |= NETIF_F_RXHASH; + netdev_hw_features_zero(ndev); + netdev_hw_features_set_array(ndev, &mana_hw_feature_set); ndev->features = ndev->hw_features; ndev->vlan_features = 0;
diff --git a/drivers/net/ethernet/mscc/ocelot_net.c b/drivers/net/ethernet/mscc/ocelot_net.c index 5e6136e80282..0f88dac6920a 100644 --- a/drivers/net/ethernet/mscc/ocelot_net.c +++ b/drivers/net/ethernet/mscc/ocelot_net.c @@ -10,6 +10,7 @@
#include <linux/dsa/ocelot.h> #include <linux/if_bridge.h> +#include <linux/netdev_features_helper.h> #include <linux/of_net.h> #include <linux/phy/phy.h> #include <net/pkt_cls.h> @@ -1809,6 +1810,14 @@ static int ocelot_port_phylink_create(struct ocelot *ocelot, int port, return 0; }
+static DECLARE_NETDEV_FEATURE_SET(ocelot_hw_feature_set, + NETIF_F_HW_VLAN_CTAG_FILTER_BIT, + NETIF_F_RXFCS_BIT, + NETIF_F_HW_TC_BIT); +static DECLARE_NETDEV_FEATURE_SET(ocelot_feature_set, + NETIF_F_HW_VLAN_CTAG_FILTER_BIT, + NETIF_F_HW_TC_BIT); + int ocelot_probe_port(struct ocelot *ocelot, int port, struct regmap *target, struct device_node *portnp) { @@ -1833,9 +1842,8 @@ int ocelot_probe_port(struct ocelot *ocelot, int port, struct regmap *target, dev->ethtool_ops = &ocelot_ethtool_ops; dev->max_mtu = OCELOT_JUMBO_MTU;
- dev->hw_features |= NETIF_F_HW_VLAN_CTAG_FILTER | NETIF_F_RXFCS | - NETIF_F_HW_TC; - dev->features |= NETIF_F_HW_VLAN_CTAG_FILTER | NETIF_F_HW_TC; + netdev_hw_features_set_array(dev, &ocelot_hw_feature_set); + netdev_active_features_set_array(dev, &ocelot_feature_set);
err = of_get_ethdev_address(portnp, dev); if (err) diff --git a/drivers/net/ethernet/myricom/myri10ge/myri10ge.c b/drivers/net/ethernet/myricom/myri10ge/myri10ge.c index 971dde8c3286..cffe22b5f5f3 100644 --- a/drivers/net/ethernet/myricom/myri10ge/myri10ge.c +++ b/drivers/net/ethernet/myricom/myri10ge/myri10ge.c @@ -42,6 +42,7 @@
#include <linux/tcp.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/skbuff.h> #include <linux/string.h> #include <linux/module.h> @@ -243,7 +244,7 @@ struct myri10ge_priv { unsigned long serial_number; int vendor_specific_offset; int fw_multicast_support; - u32 features; + netdev_features_t features; u32 max_tso6; u32 read_dma; u32 write_dma; @@ -681,13 +682,19 @@ static int myri10ge_adopt_running_firmware(struct myri10ge_priv *mgp) return status; }
+static DECLARE_NETDEV_FEATURE_SET(myri10ge_feature_set, + NETIF_F_SG_BIT, + NETIF_F_HW_CSUM_BIT, + NETIF_F_TSO_BIT); + static int myri10ge_get_firmware_capabilities(struct myri10ge_priv *mgp) { struct myri10ge_cmd cmd; int status;
/* probe for IPv6 TSO support */ - mgp->features = NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_TSO; + netdev_features_zero(&mgp->features); + netdev_features_set_array(&myri10ge_feature_set, &mgp->features); status = myri10ge_send_cmd(mgp, MXGEFW_CMD_GET_MAX_TSO6_HDR_SIZE, &cmd, 0); if (status == 0) { diff --git a/drivers/net/ethernet/neterion/s2io.c b/drivers/net/ethernet/neterion/s2io.c index 30f955efa830..79dd414f6e36 100644 --- a/drivers/net/ethernet/neterion/s2io.c +++ b/drivers/net/ethernet/neterion/s2io.c @@ -60,6 +60,7 @@ #include <linux/dma-mapping.h> #include <linux/kernel.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/etherdevice.h> #include <linux/mdio.h> #include <linux/skbuff.h> @@ -7638,6 +7639,19 @@ static const struct net_device_ops s2io_netdev_ops = { #endif };
+static DECLARE_NETDEV_FEATURE_SET(s2io_hw_feature_set, + NETIF_F_SG_BIT, + NETIF_F_IP_CSUM_BIT, + NETIF_F_TSO_BIT, + NETIF_F_TSO6_BIT, + NETIF_F_RXCSUM_BIT, + NETIF_F_LRO_BIT, + NETIF_F_SG_BIT); +static DECLARE_NETDEV_FEATURE_SET(s2io_feature_set, + NETIF_F_HW_VLAN_CTAG_TX_BIT, + NETIF_F_HW_VLAN_CTAG_RX_BIT, + NETIF_F_HIGHDMA_BIT); + /** * s2io_init_nic - Initialization of the adapter . * @pdev : structure containing the PCI related information of the device. @@ -7853,12 +7867,10 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) /* Driver entry points */ dev->netdev_ops = &s2io_netdev_ops; dev->ethtool_ops = &netdev_ethtool_ops; - dev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | - NETIF_F_TSO | NETIF_F_TSO6 | - NETIF_F_RXCSUM | NETIF_F_LRO; - dev->features |= dev->hw_features | - NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX | - NETIF_F_HIGHDMA; + netdev_hw_features_zero(dev); + netdev_hw_features_set_array(dev, &s2io_hw_feature_set); + dev->features |= dev->hw_features; + netdev_active_features_set_array(dev, &s2io_feature_set); dev->watchdog_timeo = WATCH_DOG_TIMEOUT; INIT_WORK(&sp->rst_timer_task, s2io_restart_nic); INIT_WORK(&sp->set_link_task, s2io_set_link); diff --git a/drivers/net/ethernet/nvidia/forcedeth.c b/drivers/net/ethernet/nvidia/forcedeth.c index 5116badaf091..71c5363084e6 100644 --- a/drivers/net/ethernet/nvidia/forcedeth.c +++ b/drivers/net/ethernet/nvidia/forcedeth.c @@ -37,6 +37,7 @@ #include <linux/pci.h> #include <linux/interrupt.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/etherdevice.h> #include <linux/delay.h> #include <linux/sched.h> @@ -5706,6 +5707,12 @@ static const struct net_device_ops nv_netdev_ops_optimized = { #endif };
+static DECLARE_NETDEV_FEATURE_SET(nv_hw_feature_set, + NETIF_F_IP_CSUM_BIT, + NETIF_F_SG_BIT, + NETIF_F_TSO_BIT, + NETIF_F_RXCSUM_BIT); + static int nv_probe(struct pci_dev *pci_dev, const struct pci_device_id *id) { struct net_device *dev; @@ -5811,8 +5818,7 @@ static int nv_probe(struct pci_dev *pci_dev, const struct pci_device_id *id)
if (id->driver_data & DEV_HAS_CHECKSUM) { np->txrxctl_bits |= NVREG_TXRXCTL_RXCHECK; - dev->hw_features |= NETIF_F_IP_CSUM | NETIF_F_SG | - NETIF_F_TSO | NETIF_F_RXCSUM; + netdev_hw_features_set_array(dev, &nv_hw_feature_set); }
np->vlanctl_bits = 0; diff --git a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c index 46da937ad27f..8213d2300ff4 100644 --- a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c +++ b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c @@ -13,6 +13,7 @@ #include <linux/gpio/machine.h> #include <linux/iopoll.h> #include <linux/module.h> +#include <linux/netdev_features_helper.h> #include <linux/net_tstamp.h> #include <linux/ptp_classify.h> #include <linux/ptp_pch.h> @@ -2463,6 +2464,11 @@ static void pch_gbe_remove(struct pci_dev *pdev) free_netdev(netdev); }
+static DECLARE_NETDEV_FEATURE_SET(pch_gbe_hw_feature_set, + NETIF_F_RXCSUM_BIT, + NETIF_F_IP_CSUM_BIT, + NETIF_F_IPV6_CSUM_BIT); + static int pch_gbe_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id) { @@ -2518,8 +2524,8 @@ static int pch_gbe_probe(struct pci_dev *pdev, netdev->watchdog_timeo = PCH_GBE_WATCHDOG_PERIOD; netif_napi_add(netdev, &adapter->napi, pch_gbe_napi_poll, NAPI_POLL_WEIGHT); - netdev->hw_features = NETIF_F_RXCSUM | - NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM; + netdev_hw_features_zero(netdev); + netdev_hw_features_set_array(netdev, &pch_gbe_hw_feature_set); netdev->features = netdev->hw_features; pch_gbe_set_ethtool_ops(netdev);
diff --git a/drivers/net/ethernet/pasemi/pasemi_mac.c b/drivers/net/ethernet/pasemi/pasemi_mac.c index f0ace3a0e85c..55437fd2de69 100644 --- a/drivers/net/ethernet/pasemi/pasemi_mac.c +++ b/drivers/net/ethernet/pasemi/pasemi_mac.c @@ -1672,6 +1672,13 @@ static const struct net_device_ops pasemi_netdev_ops = { #endif };
+static DECLARE_NETDEV_FEATURE_SET(pasemi_feature_set, + NETIF_F_IP_CSUM_BIT, + NETIF_F_LLTX_BIT, + NETIF_F_SG_BIT, + NETIF_F_HIGHDMA_BIT, + NETIF_F_GSO_BIT); + static int pasemi_mac_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { @@ -1699,8 +1706,8 @@ pasemi_mac_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
netif_napi_add(dev, &mac->napi, pasemi_mac_poll, 64);
- dev->features = NETIF_F_IP_CSUM | NETIF_F_LLTX | NETIF_F_SG | - NETIF_F_HIGHDMA | NETIF_F_GSO; + netdev_active_features_zero(dev); + netdev_active_features_set_array(dev, &pasemi_feature_set);
mac->dma_pdev = pci_get_device(PCI_VENDOR_ID_PASEMI, 0xa007, NULL); if (!mac->dma_pdev) { diff --git a/drivers/net/ethernet/pensando/ionic/ionic_lif.c b/drivers/net/ethernet/pensando/ionic/ionic_lif.c index f3568901eb91..3c7e7ea695bf 100644 --- a/drivers/net/ethernet/pensando/ionic/ionic_lif.c +++ b/drivers/net/ethernet/pensando/ionic/ionic_lif.c @@ -5,6 +5,7 @@ #include <linux/printk.h> #include <linux/dynamic_debug.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/etherdevice.h> #include <linux/if_vlan.h> #include <linux/rtnetlink.h> @@ -1479,6 +1480,17 @@ static int ionic_set_nic_features(struct ionic_lif *lif, return 0; }
+static DECLARE_NETDEV_FEATURE_SET(ionic_feature_set, + NETIF_F_HW_VLAN_CTAG_TX_BIT, + NETIF_F_HW_VLAN_CTAG_RX_BIT, + NETIF_F_HW_VLAN_CTAG_FILTER_BIT, + NETIF_F_SG_BIT, + NETIF_F_HW_CSUM_BIT, + NETIF_F_RXCSUM_BIT, + NETIF_F_TSO_BIT, + NETIF_F_TSO6_BIT, + NETIF_F_TSO_ECN_BIT); + static int ionic_init_nic_features(struct ionic_lif *lif) { struct net_device *netdev = lif->netdev; @@ -1486,15 +1498,8 @@ static int ionic_init_nic_features(struct ionic_lif *lif) int err;
/* set up what we expect to support by default */ - features = NETIF_F_HW_VLAN_CTAG_TX | - NETIF_F_HW_VLAN_CTAG_RX | - NETIF_F_HW_VLAN_CTAG_FILTER | - NETIF_F_SG | - NETIF_F_HW_CSUM | - NETIF_F_RXCSUM | - NETIF_F_TSO | - NETIF_F_TSO6 | - NETIF_F_TSO_ECN; + netdev_features_zero(&features); + netdev_features_set_array(&ionic_feature_set, &features);
if (lif->nxqs > 1) features |= NETIF_F_RXHASH; diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c b/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c index 4e6f00af17d9..72cbf78344b5 100644 --- a/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c +++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c @@ -5,6 +5,7 @@ * All rights reserved. */
+#include <linux/netdev_features_helper.h> #include <linux/slab.h> #include <linux/vmalloc.h> #include <linux/interrupt.h> @@ -1327,6 +1328,12 @@ netxen_nic_reset_context(struct netxen_adapter *adapter) return err; }
+static DECLARE_NETDEV_FEATURE_SET(netxen_hw_feature_set, + NETIF_F_SG_BIT, + NETIF_F_IP_CSUM_BIT, + NETIF_F_TSO_BIT, + NETIF_F_RXCSUM_BIT); + static int netxen_setup_netdev(struct netxen_adapter *adapter, struct net_device *netdev) @@ -1347,8 +1354,8 @@ netxen_setup_netdev(struct netxen_adapter *adapter,
netdev->ethtool_ops = &netxen_nic_ethtool_ops;
- netdev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO | - NETIF_F_RXCSUM; + netdev_hw_features_zero(netdev); + netdev_hw_features_set_array(netdev, &netxen_hw_feature_set);
if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) netdev->hw_features |= NETIF_F_IPV6_CSUM | NETIF_F_TSO6; diff --git a/drivers/net/ethernet/qlogic/qede/qede_main.c b/drivers/net/ethernet/qlogic/qede/qede_main.c index f56b679adb4b..04af61f4122a 100644 --- a/drivers/net/ethernet/qlogic/qede/qede_main.c +++ b/drivers/net/ethernet/qlogic/qede/qede_main.c @@ -20,6 +20,7 @@ #include <asm/param.h> #include <linux/io.h> #include <linux/netdev_features.h> +#include <linux/netdev_features_helper.h> #include <linux/udp.h> #include <linux/tcp.h> #include <net/udp_tunnel.h> @@ -820,6 +821,35 @@ static struct qede_dev *qede_alloc_etherdev(struct qed_dev *cdev, return edev; }
+static DECLARE_NETDEV_FEATURE_SET(qede_hw_feature_set, + NETIF_F_GRO_BIT, + NETIF_F_GRO_HW_BIT, + NETIF_F_SG_BIT, + NETIF_F_IP_CSUM_BIT, + NETIF_F_IPV6_CSUM_BIT, + NETIF_F_TSO_BIT, + NETIF_F_TSO6_BIT, + NETIF_F_HW_TC_BIT); +static DECLARE_NETDEV_FEATURE_SET(qede_hw_enc_feature_set, + NETIF_F_IP_CSUM_BIT, + NETIF_F_IPV6_CSUM_BIT, + NETIF_F_SG_BIT, + NETIF_F_TSO_BIT, + NETIF_F_TSO_ECN_BIT, + NETIF_F_TSO6_BIT, + NETIF_F_RXCSUM_BIT); +static DECLARE_NETDEV_FEATURE_SET(qede_vlan_feature_set, + NETIF_F_RXHASH_BIT, + NETIF_F_RXCSUM_BIT, + NETIF_F_HIGHDMA_BIT); +static DECLARE_NETDEV_FEATURE_SET(qede_feature_set, + NETIF_F_RXHASH_BIT, + NETIF_F_RXCSUM_BIT, + NETIF_F_HW_VLAN_CTAG_RX_BIT, + NETIF_F_HIGHDMA_BIT, + NETIF_F_HW_VLAN_CTAG_FILTER_BIT, + NETIF_F_HW_VLAN_CTAG_TX_BIT); + static void qede_init_ndev(struct qede_dev *edev) { struct net_device *ndev = edev->ndev; @@ -850,9 +880,8 @@ static void qede_init_ndev(struct qede_dev *edev) ndev->priv_flags |= IFF_UNICAST_FLT;
/* user-changeble features */ - hw_features = NETIF_F_GRO | NETIF_F_GRO_HW | NETIF_F_SG | - NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | - NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_HW_TC; + netdev_features_zero(&hw_features); + netdev_features_set_array(&qede_hw_feature_set, &hw_features);
if (edev->dev_info.common.b_arfs_capable) hw_features |= NETIF_F_NTUPLE; @@ -863,10 +892,8 @@ static void qede_init_ndev(struct qede_dev *edev)
if (udp_tunnel_enable || edev->dev_info.common.gre_enable) { hw_features |= NETIF_F_TSO_ECN; - ndev->hw_enc_features = NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | - NETIF_F_SG | NETIF_F_TSO | - NETIF_F_TSO_ECN | NETIF_F_TSO6 | - NETIF_F_RXCSUM; + netdev_hw_enc_features_zero(ndev); + netdev_hw_enc_features_set_array(ndev, &qede_hw_enc_feature_set); }
if (udp_tunnel_enable) { @@ -884,11 +911,10 @@ static void qede_init_ndev(struct qede_dev *edev) NETIF_F_GSO_GRE_CSUM); }
- ndev->vlan_features = hw_features | NETIF_F_RXHASH | NETIF_F_RXCSUM | - NETIF_F_HIGHDMA; - ndev->features = hw_features | NETIF_F_RXHASH | NETIF_F_RXCSUM | - NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_HIGHDMA | - NETIF_F_HW_VLAN_CTAG_FILTER | NETIF_F_HW_VLAN_CTAG_TX; + ndev->vlan_features = hw_features; + netdev_vlan_features_set_array(ndev, &qede_vlan_feature_set); + ndev->features = hw_features; + netdev_active_features_set_array(ndev, &qede_feature_set);
ndev->hw_features = hw_features;
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c index 4b8bc46f55c2..2401cbc015f0 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c @@ -7,6 +7,7 @@ #include <linux/slab.h> #include <net/ip.h> #include <linux/bitops.h> +#include <linux/netdev_features_helper.h>
#include "qlcnic.h" #include "qlcnic_hdr.h" @@ -1020,14 +1021,24 @@ int qlcnic_change_mtu(struct net_device *netdev, int mtu) return rc; }
+static DECLARE_NETDEV_FEATURE_SET(qlcnic_csum_feature_set, + NETIF_F_RXCSUM_BIT, + NETIF_F_IP_CSUM_BIT, + NETIF_F_IPV6_CSUM_BIT); +static DECLARE_NETDEV_FEATURE_SET(qlcnic_changable_feature_set, + NETIF_F_RXCSUM_BIT, + NETIF_F_IP_CSUM_BIT, + NETIF_F_IPV6_CSUM_BIT, + NETIF_F_TSO_BIT, + NETIF_F_TSO6_BIT); + static netdev_features_t qlcnic_process_flags(struct qlcnic_adapter *adapter, netdev_features_t features) { u32 offload_flags = adapter->offload_flags;
if (offload_flags & BIT_0) { - features |= NETIF_F_RXCSUM | NETIF_F_IP_CSUM | - NETIF_F_IPV6_CSUM; + netdev_features_set_array(&qlcnic_csum_feature_set, &features); adapter->rx_csum = 1; if (QLCNIC_IS_TSO_CAPABLE(adapter)) { if (!(offload_flags & BIT_1)) @@ -1041,9 +1052,7 @@ static netdev_features_t qlcnic_process_flags(struct qlcnic_adapter *adapter, features |= NETIF_F_TSO6; } } else { - features &= ~(NETIF_F_RXCSUM | - NETIF_F_IP_CSUM | - NETIF_F_IPV6_CSUM); + netdev_features_clear_array(&qlcnic_csum_feature_set, &features);
if (QLCNIC_IS_TSO_CAPABLE(adapter)) features &= ~(NETIF_F_TSO | NETIF_F_TSO6); @@ -1057,6 +1066,7 @@ netdev_features_t qlcnic_fix_features(struct net_device *netdev, netdev_features_t features) { struct qlcnic_adapter *adapter = netdev_priv(netdev); + netdev_features_t changeable; netdev_features_t changed;
if (qlcnic_82xx_check(adapter) && @@ -1065,11 +1075,10 @@ netdev_features_t qlcnic_fix_features(struct net_device *netdev, features = qlcnic_process_flags(adapter, features); } else { changed = features ^ netdev->features; - features ^= changed & (NETIF_F_RXCSUM | - NETIF_F_IP_CSUM | - NETIF_F_IPV6_CSUM | - NETIF_F_TSO | - NETIF_F_TSO6); + netdev_features_zero(&changeable); + netdev_features_set_array(&qlcnic_changable_feature_set, + &changeable); + features ^= changed & changeable; } }
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c index 28476b982bab..f8c043914d6a 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c @@ -14,6 +14,7 @@ #include <linux/inetdevice.h> #include <linux/aer.h> #include <linux/log2.h> +#include <linux/netdev_features_helper.h> #include <linux/pci.h> #include <net/vxlan.h>
@@ -2258,6 +2259,25 @@ static int qlcnic_set_real_num_queues(struct qlcnic_adapter *adapter, return err; }
+static DECLARE_NETDEV_FEATURE_SET(qlcnic_feature_set, + NETIF_F_SG_BIT, + NETIF_F_IP_CSUM_BIT, + NETIF_F_RXCSUM_BIT, + NETIF_F_IPV6_CSUM_BIT, + NETIF_F_GRO_BIT, + NETIF_F_HW_VLAN_CTAG_RX_BIT, + NETIF_F_HIGHDMA_BIT); +static DECLARE_NETDEV_FEATURE_SET(qlcnic_vlan_feature_set, + NETIF_F_SG_BIT, + NETIF_F_IP_CSUM_BIT, + NETIF_F_IPV6_CSUM_BIT, + NETIF_F_HIGHDMA_BIT); +static DECLARE_NETDEV_FEATURE_SET(qlcnic_hw_enc_feature_set, + NETIF_F_IP_CSUM_BIT, + NETIF_F_GSO_UDP_TUNNEL_BIT, + NETIF_F_TSO_BIT, + NETIF_F_TSO6_BIT); + int qlcnic_setup_netdev(struct qlcnic_adapter *adapter, struct net_device *netdev) { @@ -2276,11 +2296,8 @@ qlcnic_setup_netdev(struct qlcnic_adapter *adapter, struct net_device *netdev) netdev->ethtool_ops = (qlcnic_sriov_vf_check(adapter)) ? &qlcnic_sriov_vf_ethtool_ops : &qlcnic_ethtool_ops;
- netdev->features |= (NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_RXCSUM | - NETIF_F_IPV6_CSUM | NETIF_F_GRO | - NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_HIGHDMA); - netdev->vlan_features |= (NETIF_F_SG | NETIF_F_IP_CSUM | - NETIF_F_IPV6_CSUM | NETIF_F_HIGHDMA); + netdev_active_features_set_array(netdev, &qlcnic_feature_set); + netdev_vlan_features_set_array(netdev, &qlcnic_vlan_feature_set);
if (QLCNIC_IS_TSO_CAPABLE(adapter)) { netdev->features |= (NETIF_F_TSO | NETIF_F_TSO6); @@ -2300,10 +2317,9 @@ qlcnic_setup_netdev(struct qlcnic_adapter *adapter, struct net_device *netdev) netdev->features |= NETIF_F_GSO_UDP_TUNNEL;
/* encapsulation Tx offload supported by Adapter */ - netdev->hw_enc_features = NETIF_F_IP_CSUM | - NETIF_F_GSO_UDP_TUNNEL | - NETIF_F_TSO | - NETIF_F_TSO6; + netdev_vlan_features_zero(netdev); + netdev_vlan_features_set_array(netdev, + &qlcnic_hw_enc_feature_set); }
if (qlcnic_encap_rx_offload(adapter)) { diff --git a/drivers/net/ethernet/qualcomm/emac/emac.c b/drivers/net/ethernet/qualcomm/emac/emac.c index a55c52696d49..c302d50324fb 100644 --- a/drivers/net/ethernet/qualcomm/emac/emac.c +++ b/drivers/net/ethernet/qualcomm/emac/emac.c @@ -9,6 +9,7 @@ #include <linux/interrupt.h> #include <linux/io.h> #include <linux/module.h> +#include <linux/netdev_features_helper.h> #include <linux/of.h> #include <linux/of_net.h> #include <linux/of_device.h> @@ -590,6 +591,20 @@ static const struct acpi_device_id emac_acpi_match[] = { MODULE_DEVICE_TABLE(acpi, emac_acpi_match); #endif
+static DECLARE_NETDEV_FEATURE_SET(emac_feature_set, + NETIF_F_SG_BIT, + NETIF_F_HW_CSUM_BIT, + NETIF_F_RXCSUM_BIT, + NETIF_F_TSO_BIT, + NETIF_F_TSO6_BIT, + NETIF_F_HW_VLAN_CTAG_RX_BIT, + NETIF_F_HW_VLAN_CTAG_TX_BIT); +static DECLARE_NETDEV_FEATURE_SET(emac_vlan_feature_set, + NETIF_F_SG_BIT, + NETIF_F_HW_CSUM_BIT, + NETIF_F_TSO_BIT, + NETIF_F_TSO6_BIT); + static int emac_probe(struct platform_device *pdev) { struct net_device *netdev; @@ -665,13 +680,11 @@ static int emac_probe(struct platform_device *pdev) }
/* set hw features */ - netdev->features = NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_RXCSUM | - NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_HW_VLAN_CTAG_RX | - NETIF_F_HW_VLAN_CTAG_TX; + netdev_active_features_zero(netdev); + netdev_active_features_set_array(netdev, &emac_feature_set); netdev->hw_features = netdev->features;
- netdev->vlan_features |= NETIF_F_SG | NETIF_F_HW_CSUM | - NETIF_F_TSO | NETIF_F_TSO6; + netdev_vlan_features_set_array(netdev, &emac_vlan_feature_set);
/* MTU range: 46 - 9194 */ netdev->min_mtu = EMAC_MIN_ETH_FRAME_SIZE - diff --git a/drivers/net/ethernet/qualcomm/rmnet/rmnet_vnd.c b/drivers/net/ethernet/qualcomm/rmnet/rmnet_vnd.c index 1b2119b1d48a..92215121428f 100644 --- a/drivers/net/ethernet/qualcomm/rmnet/rmnet_vnd.c +++ b/drivers/net/ethernet/qualcomm/rmnet/rmnet_vnd.c @@ -7,6 +7,7 @@ #include <linux/etherdevice.h> #include <linux/ethtool.h> #include <linux/if_arp.h> +#include <linux/netdev_features_helper.h> #include <net/pkt_sched.h> #include "rmnet_config.h" #include "rmnet_handlers.h" @@ -243,6 +244,12 @@ void rmnet_vnd_setup(struct net_device *rmnet_dev) eth_random_addr(rmnet_dev->perm_addr); }
+static DECLARE_NETDEV_FEATURE_SET(rmnet_hw_feature_set, + NETIF_F_RXCSUM_BIT, + NETIF_F_IP_CSUM_BIT, + NETIF_F_IPV6_CSUM_BIT, + NETIF_F_SG_BIT); + /* Exposed API */
int rmnet_vnd_newlink(u8 id, struct net_device *rmnet_dev, @@ -261,9 +268,8 @@ int rmnet_vnd_newlink(u8 id, struct net_device *rmnet_dev, return -EBUSY; }
- rmnet_dev->hw_features = NETIF_F_RXCSUM; - rmnet_dev->hw_features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM; - rmnet_dev->hw_features |= NETIF_F_SG; + netdev_hw_features_zero(rmnet_dev); + netdev_hw_features_set_array(rmnet_dev, &rmnet_hw_feature_set);
priv->real_dev = real_dev;
diff --git a/drivers/net/ethernet/realtek/8139cp.c b/drivers/net/ethernet/realtek/8139cp.c index e0feeec13da6..c5c2e491d251 100644 --- a/drivers/net/ethernet/realtek/8139cp.c +++ b/drivers/net/ethernet/realtek/8139cp.c @@ -58,6 +58,7 @@ #include <linux/kernel.h> #include <linux/compiler.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/etherdevice.h> #include <linux/init.h> #include <linux/interrupt.h> @@ -1883,6 +1884,18 @@ static const struct net_device_ops cp_netdev_ops = { #endif };
+static DECLARE_NETDEV_FEATURE_SET(cp_default_feature_set, + NETIF_F_SG_BIT, + NETIF_F_IP_CSUM_BIT, + NETIF_F_TSO_BIT, + NETIF_F_HW_VLAN_CTAG_TX_BIT, + NETIF_F_HW_VLAN_CTAG_RX_BIT); +static DECLARE_NETDEV_FEATURE_SET(cp_vlan_feature_set, + NETIF_F_SG_BIT, + NETIF_F_IP_CSUM_BIT, + NETIF_F_TSO_BIT, + NETIF_F_HIGHDMA_BIT); + static int cp_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) { struct net_device *dev; @@ -1990,16 +2003,14 @@ static int cp_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) dev->ethtool_ops = &cp_ethtool_ops; dev->watchdog_timeo = TX_TIMEOUT;
- dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO | - NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX; + netdev_active_features_set_array(dev, &cp_default_feature_set);
if (pci_using_dac) dev->features |= NETIF_F_HIGHDMA;
- dev->hw_features |= NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO | - NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX; - dev->vlan_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO | - NETIF_F_HIGHDMA; + netdev_hw_features_set_array(dev, &cp_default_feature_set); + netdev_vlan_features_zero(dev); + netdev_vlan_features_set_array(dev, &cp_vlan_feature_set);
/* MTU range: 60 - 4096 */ dev->min_mtu = CP_MIN_MTU; diff --git a/drivers/net/ethernet/realtek/8139too.c b/drivers/net/ethernet/realtek/8139too.c index 15b40fd93cd2..3844a0f418ec 100644 --- a/drivers/net/ethernet/realtek/8139too.c +++ b/drivers/net/ethernet/realtek/8139too.c @@ -102,6 +102,7 @@ #include <linux/init.h> #include <linux/interrupt.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/etherdevice.h> #include <linux/rtnetlink.h> #include <linux/delay.h> @@ -940,6 +941,11 @@ static const struct net_device_ops rtl8139_netdev_ops = { .ndo_set_features = rtl8139_set_features, };
+static DECLARE_NETDEV_FEATURE_SET(rtl8139_feature_set, + NETIF_F_SG_BIT, + NETIF_F_HW_CSUM_BIT, + NETIF_F_HIGHDMA_BIT); + static int rtl8139_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) { @@ -1008,7 +1014,7 @@ static int rtl8139_init_one(struct pci_dev *pdev, * through the use of skb_copy_and_csum_dev we enable these * features */ - dev->features |= NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_HIGHDMA; + netdev_active_features_set_array(dev, &rtl8139_feature_set); dev->vlan_features = dev->features;
dev->hw_features |= NETIF_F_RXALL; diff --git a/drivers/net/ethernet/realtek/r8169_main.c b/drivers/net/ethernet/realtek/r8169_main.c index 1b7fdb4f056b..b999f129490c 100644 --- a/drivers/net/ethernet/realtek/r8169_main.c +++ b/drivers/net/ethernet/realtek/r8169_main.c @@ -12,6 +12,7 @@ #include <linux/module.h> #include <linux/pci.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/etherdevice.h> #include <linux/clk.h> #include <linux/delay.h> @@ -5298,6 +5299,16 @@ static bool rtl_aspm_is_safe(struct rtl8169_private *tp) return false; }
+static DECLARE_NETDEV_FEATURE_SET(rtl_hw_feature_set, + NETIF_F_IP_CSUM_BIT, + NETIF_F_RXCSUM_BIT, + NETIF_F_HW_VLAN_CTAG_TX_BIT, + NETIF_F_HW_VLAN_CTAG_RX_BIT); +static DECLARE_NETDEV_FEATURE_SET(rtl_vlan_feature_set, + NETIF_F_SG_BIT, + NETIF_F_IP_CSUM_BIT, + NETIF_F_TSO_BIT); + static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) { struct rtl8169_private *tp; @@ -5415,9 +5426,10 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
netif_napi_add(dev, &tp->napi, rtl8169_poll, NAPI_POLL_WEIGHT);
- dev->hw_features = NETIF_F_IP_CSUM | NETIF_F_RXCSUM | - NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX; - dev->vlan_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO; + netdev_hw_features_zero(dev); + netdev_hw_features_set_array(dev, &rtl_hw_feature_set); + netdev_vlan_features_zero(dev); + netdev_vlan_features_set_array(dev, &rtl_vlan_feature_set); dev->priv_flags |= IFF_LIVE_ADDR_CHANGE;
/* diff --git a/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c b/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c index a1c10b61269b..30af142820c6 100644 --- a/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c +++ b/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c @@ -25,6 +25,7 @@ #include <linux/module.h> #include <linux/net_tstamp.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/phy.h> #include <linux/platform_device.h> #include <linux/prefetch.h> @@ -2050,6 +2051,15 @@ static int sxgbe_sw_reset(void __iomem *addr) return 0; }
+static DECLARE_NETDEV_FEATURE_SET(sxgbe_hw_feature_set, + NETIF_F_SG_BIT, + NETIF_F_IP_CSUM_BIT, + NETIF_F_IPV6_CSUM_BIT, + NETIF_F_RXCSUM_BIT, + NETIF_F_TSO_BIT, + NETIF_F_TSO6_BIT, + NETIF_F_GRO_BIT); + /** * sxgbe_drv_probe * @device: device pointer @@ -2105,9 +2115,8 @@ struct sxgbe_priv_data *sxgbe_drv_probe(struct device *device,
ndev->netdev_ops = &sxgbe_netdev_ops;
- ndev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | - NETIF_F_RXCSUM | NETIF_F_TSO | NETIF_F_TSO6 | - NETIF_F_GRO; + netdev_hw_features_zero(ndev); + netdev_hw_features_set_array(ndev, &sxgbe_hw_feature_set); ndev->features |= ndev->hw_features | NETIF_F_HIGHDMA; ndev->watchdog_timeo = msecs_to_jiffies(TX_TIMEO);
diff --git a/drivers/net/ethernet/sfc/ef10.c b/drivers/net/ethernet/sfc/ef10.c index ab979fd11133..0a44a0beed4e 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; }
+static 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_netdev.c b/drivers/net/ethernet/sfc/ef100_netdev.c index 9e65de1ab889..4aadf6928102 100644 --- a/drivers/net/ethernet/sfc/ef100_netdev.c +++ b/drivers/net/ethernet/sfc/ef100_netdev.c @@ -341,6 +341,11 @@ void ef100_remove_netdev(struct efx_probe_data *probe_data) efx->state = STATE_PROBED; }
+static DECLARE_NETDEV_FEATURE_SET(ef100_vlan_feature_set, + NETIF_F_HW_CSUM_BIT, + NETIF_F_SG_BIT, + NETIF_F_HIGHDMA_BIT); + int ef100_probe_netdev(struct efx_probe_data *probe_data) { struct efx_nic *efx = &probe_data->efx; @@ -366,8 +371,8 @@ int ef100_probe_netdev(struct efx_probe_data *probe_data) 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); netif_set_tso_max_segs(net_dev, ESE_EF100_DP_GZ_TSO_MAX_HDR_NUM_SEGS_DEFAULT); efx->mdio.dev = net_dev; diff --git a/drivers/net/ethernet/sfc/ef100_nic.c b/drivers/net/ethernet/sfc/ef100_nic.c index 4625d35269e6..b7d655d551da 100644 --- a/drivers/net/ethernet/sfc/ef100_nic.c +++ b/drivers/net/ethernet/sfc/ef100_nic.c @@ -148,6 +148,15 @@ static int ef100_get_mac_address(struct efx_nic *efx, u8 *mac_address) return 0; }
+static 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); + int efx_ef100_init_datapath_caps(struct efx_nic *efx) { MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_CAPABILITIES_V7_OUT_LEN); @@ -186,10 +195,10 @@ 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; diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c index 153d68e29b8b..3baebaabdf32 100644 --- a/drivers/net/ethernet/sfc/efx.c +++ b/drivers/net/ethernet/sfc/efx.c @@ -985,6 +985,18 @@ static int efx_pci_probe_main(struct efx_nic *efx) return rc; }
+static DECLARE_NETDEV_FEATURE_SET(efx_active_feature_set, + NETIF_F_SG_BIT, + NETIF_F_TSO_BIT, + NETIF_F_RXCSUM_BIT, + NETIF_F_RXALL_BIT); + +static 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; @@ -1001,17 +1013,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 a63f40b09856..0240c7f5843a 100644 --- a/drivers/net/ethernet/sfc/falcon/efx.c +++ b/drivers/net/ethernet/sfc/falcon/efx.c @@ -2853,6 +2853,12 @@ static int ef4_pci_probe_main(struct ef4_nic *efx) return rc; }
+static 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, @@ -2901,9 +2907,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 a2c7139f2b32..8ee0cc45e8ad 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 4cde54cf77b9..f24919747711 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/drivers/net/ethernet/sfc/siena/efx.c b/drivers/net/ethernet/sfc/siena/efx.c index 63d999e63960..050e1b0ad0cb 100644 --- a/drivers/net/ethernet/sfc/siena/efx.c +++ b/drivers/net/ethernet/sfc/siena/efx.c @@ -9,6 +9,7 @@ #include <linux/module.h> #include <linux/pci.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/etherdevice.h> #include <linux/delay.h> #include <linux/notifier.h> @@ -967,6 +968,18 @@ static int efx_pci_probe_main(struct efx_nic *efx) return rc; }
+static DECLARE_NETDEV_FEATURE_SET(efx_active_feature_set, + NETIF_F_SG_BIT, + NETIF_F_TSO_BIT, + NETIF_F_RXCSUM_BIT, + NETIF_F_RXALL_BIT); + +static 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; @@ -983,17 +996,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/sgi/ioc3-eth.c b/drivers/net/ethernet/sgi/ioc3-eth.c index e2d009866a7b..84227eb0e3a4 100644 --- a/drivers/net/ethernet/sgi/ioc3-eth.c +++ b/drivers/net/ethernet/sgi/ioc3-eth.c @@ -825,6 +825,13 @@ static const struct net_device_ops ioc3_netdev_ops = { .ndo_set_mac_address = ioc3_set_mac_address, };
+static DECLARE_NETDEV_FEATURE_SET(ioc_hw_feature_set, + NETIF_F_IP_CSUM_BIT, + NETIF_F_RXCSUM_BIT); +static DECLARE_NETDEV_FEATURE_SET(ioc_feature_set, + NETIF_F_IP_CSUM_BIT, + NETIF_F_HIGHDMA_BIT); + static int ioc3eth_probe(struct platform_device *pdev) { u32 sw_physid1, sw_physid2, vendor, model, rev; @@ -926,8 +933,10 @@ static int ioc3eth_probe(struct platform_device *pdev) dev->watchdog_timeo = 5 * HZ; dev->netdev_ops = &ioc3_netdev_ops; dev->ethtool_ops = &ioc3_ethtool_ops; - dev->hw_features = NETIF_F_IP_CSUM | NETIF_F_RXCSUM; - dev->features = NETIF_F_IP_CSUM | NETIF_F_HIGHDMA; + netdev_hw_features_zero(dev); + netdev_hw_features_set_array(dev, &ioc_hw_feature_set); + netdev_active_features_zero(dev); + netdev_active_features_set_array(dev, &ioc_feature_set);
sw_physid1 = ioc3_mdio_read(dev, ip->mii.phy_id, MII_PHYSID1); sw_physid2 = ioc3_mdio_read(dev, ip->mii.phy_id, MII_PHYSID2); diff --git a/drivers/net/ethernet/silan/sc92031.c b/drivers/net/ethernet/silan/sc92031.c index ff4197f5e46d..65b0b8574698 100644 --- a/drivers/net/ethernet/silan/sc92031.c +++ b/drivers/net/ethernet/silan/sc92031.c @@ -30,6 +30,7 @@ #include <linux/pci.h> #include <linux/dma-mapping.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/etherdevice.h> #include <linux/ethtool.h> #include <linux/mii.h> @@ -1394,6 +1395,12 @@ static const struct net_device_ops sc92031_netdev_ops = { #endif };
+static DECLARE_NETDEV_FEATURE_SET(sc92031_feature_set, + NETIF_F_SG_BIT, + NETIF_F_HIGHDMA_BIT, + NETIF_F_IP_CSUM_BIT, + NETIF_F_IPV6_CSUM_BIT); + static int sc92031_probe(struct pci_dev *pdev, const struct pci_device_id *id) { int err; @@ -1437,8 +1444,8 @@ static int sc92031_probe(struct pci_dev *pdev, const struct pci_device_id *id) SET_NETDEV_DEV(dev, &pdev->dev);
/* faked with skb_copy_and_csum_dev */ - dev->features = NETIF_F_SG | NETIF_F_HIGHDMA | - NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM; + netdev_active_features_zero(dev); + netdev_active_features_set_array(dev, &sc92031_feature_set);
dev->netdev_ops = &sc92031_netdev_ops; dev->watchdog_timeo = TX_TIMEOUT; diff --git a/drivers/net/ethernet/socionext/netsec.c b/drivers/net/ethernet/socionext/netsec.c index b0c5a44785fa..67fba95978b4 100644 --- a/drivers/net/ethernet/socionext/netsec.c +++ b/drivers/net/ethernet/socionext/netsec.c @@ -10,6 +10,7 @@ #include <linux/etherdevice.h> #include <linux/interrupt.h> #include <linux/io.h> +#include <linux/netdev_features_helper.h> #include <linux/netlink.h> #include <linux/bpf.h> #include <linux/bpf_trace.h> @@ -1975,6 +1976,13 @@ static int netsec_register_mdio(struct netsec_priv *priv, u32 phy_addr) return ret; }
+static DECLARE_NETDEV_FEATURE_SET(netsec_feature_set, + NETIF_F_HIGHDMA_BIT, + NETIF_F_RXCSUM_BIT, + NETIF_F_GSO_BIT, + NETIF_F_IP_CSUM_BIT, + NETIF_F_IPV6_CSUM_BIT); + static int netsec_probe(struct platform_device *pdev) { struct resource *mmio_res, *eeprom_res; @@ -2098,8 +2106,7 @@ static int netsec_probe(struct platform_device *pdev) ndev->netdev_ops = &netsec_netdev_ops; ndev->ethtool_ops = &netsec_ethtool_ops;
- ndev->features |= NETIF_F_HIGHDMA | NETIF_F_RXCSUM | NETIF_F_GSO | - NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM; + netdev_active_features_set_array(ndev, &netsec_feature_set); ndev->hw_features = ndev->features;
priv->rx_cksum_offload_flag = true; diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index 070b5ef165eb..23b80ddad54d 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -35,6 +35,7 @@ #include <linux/debugfs.h> #include <linux/seq_file.h> #endif /* CONFIG_DEBUG_FS */ +#include <linux/netdev_features_helper.h> #include <linux/net_tstamp.h> #include <linux/phylink.h> #include <linux/udp.h> @@ -7026,6 +7027,12 @@ void stmmac_fpe_handshake(struct stmmac_priv *priv, bool enable) } }
+static DECLARE_NETDEV_FEATURE_SET(stmmac_hw_feature_set, + NETIF_F_SG_BIT, + NETIF_F_IP_CSUM_BIT, + NETIF_F_IPV6_CSUM_BIT, + NETIF_F_RXCSUM_BIT); + /** * stmmac_dvr_probe * @device: device pointer @@ -7132,8 +7139,8 @@ int stmmac_dvr_probe(struct device *device,
ndev->netdev_ops = &stmmac_netdev_ops;
- ndev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | - NETIF_F_RXCSUM; + netdev_hw_features_zero(ndev); + netdev_hw_features_set_array(ndev, &stmmac_hw_feature_set);
ret = stmmac_tc_init(priv, priv); if (!ret) { diff --git a/drivers/net/ethernet/sun/ldmvsw.c b/drivers/net/ethernet/sun/ldmvsw.c index 0cd8493b810f..49fa25fa045b 100644 --- a/drivers/net/ethernet/sun/ldmvsw.c +++ b/drivers/net/ethernet/sun/ldmvsw.c @@ -223,6 +223,10 @@ static struct vnet *vsw_get_vnet(struct mdesc_handle *hp, return vp; }
+static DECLARE_NETDEV_FEATURE_SET(vsw_hw_feature_set, + NETIF_F_HW_CSUM_BIT, + NETIF_F_SG_BIT); + static struct net_device *vsw_alloc_netdev(u8 hwaddr[], struct vio_dev *vdev, u64 handle, @@ -246,7 +250,8 @@ static struct net_device *vsw_alloc_netdev(u8 hwaddr[], dev->ethtool_ops = &vsw_ethtool_ops; dev->watchdog_timeo = VSW_TX_TIMEOUT;
- dev->hw_features = NETIF_F_HW_CSUM | NETIF_F_SG; + netdev_hw_features_zero(dev); + netdev_hw_features_set_array(dev, &vsw_hw_feature_set); dev->features = dev->hw_features;
/* MTU range: 68 - 65535 */ diff --git a/drivers/net/ethernet/sun/niu.c b/drivers/net/ethernet/sun/niu.c index df70df29deea..f7fa28ba5d53 100644 --- a/drivers/net/ethernet/sun/niu.c +++ b/drivers/net/ethernet/sun/niu.c @@ -12,6 +12,7 @@ #include <linux/pci.h> #include <linux/dma-mapping.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/ethtool.h> #include <linux/etherdevice.h> #include <linux/platform_device.h> @@ -9733,9 +9734,15 @@ static void niu_device_announce(struct niu *np) } }
+static DECLARE_NETDEV_FEATURE_SET(niu_hw_feature_set, + NETIF_F_SG_BIT, + NETIF_F_HW_CSUM_BIT, + NETIF_F_RXHASH_BIT); + static void niu_set_basic_features(struct net_device *dev) { - dev->hw_features = NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_RXHASH; + netdev_hw_features_zero(dev); + netdev_hw_features_set_array(dev, &niu_hw_feature_set); dev->features |= dev->hw_features | NETIF_F_RXCSUM; }
diff --git a/drivers/net/ethernet/sun/sungem.c b/drivers/net/ethernet/sun/sungem.c index a14591b41acb..42a7a6a5926f 100644 --- a/drivers/net/ethernet/sun/sungem.c +++ b/drivers/net/ethernet/sun/sungem.c @@ -29,6 +29,7 @@ #include <linux/pci.h> #include <linux/dma-mapping.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/etherdevice.h> #include <linux/skbuff.h> #include <linux/mii.h> @@ -2843,6 +2844,11 @@ static const struct net_device_ops gem_netdev_ops = { #endif };
+static DECLARE_NETDEV_FEATURE_SET(gem_hw_feature_set, + NETIF_F_SG_BIT, + NETIF_F_HW_CSUM_BIT, + NETIF_F_RXCSUM_BIT); + static int gem_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) { unsigned long gemreg_base, gemreg_len; @@ -2989,7 +2995,8 @@ static int gem_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) pci_set_drvdata(pdev, dev);
/* We can do scatter/gather and HW checksum */ - dev->hw_features = NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_RXCSUM; + netdev_hw_features_zero(dev); + netdev_hw_features_set_array(dev, &gem_hw_feature_set); dev->features = dev->hw_features; if (pci_using_dac) dev->features |= NETIF_F_HIGHDMA; diff --git a/drivers/net/ethernet/sun/sunvnet.c b/drivers/net/ethernet/sun/sunvnet.c index da8119625cf3..0552fe23a397 100644 --- a/drivers/net/ethernet/sun/sunvnet.c +++ b/drivers/net/ethernet/sun/sunvnet.c @@ -281,6 +281,12 @@ static const struct net_device_ops vnet_ops = { #endif };
+static DECLARE_NETDEV_FEATURE_SET(vnet_hw_feature_set, + NETIF_F_TSO_BIT, + NETIF_F_GSO_BIT, + NETIF_F_HW_CSUM_BIT, + NETIF_F_SG_BIT); + static struct vnet *vnet_new(const u64 *local_mac, struct vio_dev *vdev) { @@ -314,8 +320,8 @@ static struct vnet *vnet_new(const u64 *local_mac, dev->ethtool_ops = &vnet_ethtool_ops; dev->watchdog_timeo = VNET_TX_TIMEOUT;
- dev->hw_features = NETIF_F_TSO | NETIF_F_GSO | NETIF_F_ALL_TSO | - NETIF_F_HW_CSUM | NETIF_F_SG; + dev->hw_features = NETIF_F_ALL_TSO; + netdev_hw_features_set_array(dev, &vnet_hw_feature_set); dev->features = dev->hw_features;
/* MTU range: 68 - 65535 */ diff --git a/drivers/net/ethernet/tehuti/tehuti.c b/drivers/net/ethernet/tehuti/tehuti.c index 985073eba3bd..fd89439791ce 100644 --- a/drivers/net/ethernet/tehuti/tehuti.c +++ b/drivers/net/ethernet/tehuti/tehuti.c @@ -1862,6 +1862,21 @@ static const struct net_device_ops bdx_netdev_ops = { .ndo_vlan_rx_kill_vid = bdx_vlan_rx_kill_vid, };
+static DECLARE_NETDEV_FEATURE_SET(bdx_feature_set, + NETIF_F_IP_CSUM_BIT, + NETIF_F_SG_BIT, + NETIF_F_TSO_BIT, + NETIF_F_HW_VLAN_CTAG_TX_BIT, + NETIF_F_HW_VLAN_CTAG_RX_BIT, + NETIF_F_HW_VLAN_CTAG_FILTER_BIT, + NETIF_F_RXCSUM_BIT, + NETIF_F_HIGHDMA_BIT); +static DECLARE_NETDEV_FEATURE_SET(bdx_hw_feature_set, + NETIF_F_IP_CSUM_BIT, + NETIF_F_SG_BIT, + NETIF_F_TSO_BIT, + NETIF_F_HW_VLAN_CTAG_TX_BIT); + /** * bdx_probe - Device Initialization Routine * @pdev: PCI device information struct @@ -1976,13 +1991,11 @@ bdx_probe(struct pci_dev *pdev, const struct pci_device_id *ent) /* these fields are used for info purposes only * so we can have them same for all ports of the board */ ndev->if_port = port; - ndev->features = NETIF_F_IP_CSUM | NETIF_F_SG | NETIF_F_TSO | - NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX | - NETIF_F_HW_VLAN_CTAG_FILTER | NETIF_F_RXCSUM | - NETIF_F_HIGHDMA; + netdev_active_features_zero(ndev); + netdev_active_features_set_array(ndev, &bdx_feature_set);
- ndev->hw_features = NETIF_F_IP_CSUM | NETIF_F_SG | - NETIF_F_TSO | NETIF_F_HW_VLAN_CTAG_TX; + netdev_hw_features_zero(ndev); + netdev_hw_features_set_array(ndev, &bdx_hw_feature_set);
/************** priv ****************/ priv = nic->priv[port] = netdev_priv(ndev); diff --git a/drivers/net/ethernet/tehuti/tehuti.h b/drivers/net/ethernet/tehuti/tehuti.h index 909e7296cecf..eef81f973233 100644 --- a/drivers/net/ethernet/tehuti/tehuti.h +++ b/drivers/net/ethernet/tehuti/tehuti.h @@ -10,6 +10,7 @@ #include <linux/module.h> #include <linux/kernel.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/etherdevice.h> #include <linux/pci.h> #include <linux/delay.h> diff --git a/drivers/net/ethernet/ti/am65-cpsw-nuss.c b/drivers/net/ethernet/ti/am65-cpsw-nuss.c index f4a6b590a1e3..b390983861d8 100644 --- a/drivers/net/ethernet/ti/am65-cpsw-nuss.c +++ b/drivers/net/ethernet/ti/am65-cpsw-nuss.c @@ -14,6 +14,7 @@ #include <linux/kmemleak.h> #include <linux/module.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/net_tstamp.h> #include <linux/of.h> #include <linux/of_mdio.h> @@ -1932,6 +1933,12 @@ static void am65_cpsw_nuss_phylink_cleanup(struct am65_cpsw_common *common) } }
+static DECLARE_NETDEV_FEATURE_SET(am65_cpsw_hw_feature_set, + NETIF_F_SG_BIT, + NETIF_F_RXCSUM_BIT, + NETIF_F_HW_CSUM_BIT, + NETIF_F_HW_TC_BIT); + static int am65_cpsw_nuss_init_port_ndev(struct am65_cpsw_common *common, u32 port_idx) { @@ -1966,10 +1973,8 @@ am65_cpsw_nuss_init_port_ndev(struct am65_cpsw_common *common, u32 port_idx)
port->ndev->min_mtu = AM65_CPSW_MIN_PACKET_SIZE; port->ndev->max_mtu = AM65_CPSW_MAX_PACKET_SIZE; - port->ndev->hw_features = NETIF_F_SG | - NETIF_F_RXCSUM | - NETIF_F_HW_CSUM | - NETIF_F_HW_TC; + netdev_hw_features_zero(port->ndev); + netdev_hw_features_set_array(port->ndev, &am65_cpsw_hw_feature_set); port->ndev->features = port->ndev->hw_features | NETIF_F_HW_VLAN_CTAG_FILTER; port->ndev->vlan_features |= NETIF_F_SG; diff --git a/drivers/net/ethernet/ti/cpsw_new.c b/drivers/net/ethernet/ti/cpsw_new.c index 353e58b22c51..fb9ba01138f1 100644 --- a/drivers/net/ethernet/ti/cpsw_new.c +++ b/drivers/net/ethernet/ti/cpsw_new.c @@ -13,6 +13,7 @@ #include <linux/interrupt.h> #include <linux/if_ether.h> #include <linux/etherdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/net_tstamp.h> #include <linux/phy.h> #include <linux/phy/phy.h> @@ -1359,6 +1360,12 @@ static void cpsw_remove_dt(struct cpsw_common *cpsw) } }
+static DECLARE_NETDEV_FEATURE_SET(cpsw_feature_set, + NETIF_F_HW_VLAN_CTAG_FILTER_BIT, + NETIF_F_HW_VLAN_CTAG_RX_BIT, + NETIF_F_NETNS_LOCAL_BIT, + NETIF_F_HW_TC_BIT); + static int cpsw_create_ports(struct cpsw_common *cpsw) { struct cpsw_platform_data *data = &cpsw->data; @@ -1403,9 +1410,7 @@ static int cpsw_create_ports(struct cpsw_common *cpsw)
cpsw->slaves[i].ndev = ndev;
- ndev->features |= NETIF_F_HW_VLAN_CTAG_FILTER | - NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_NETNS_LOCAL | NETIF_F_HW_TC; - + netdev_active_features_set_array(ndev, &cpsw_feature_set); ndev->netdev_ops = &cpsw_netdev_ops; ndev->ethtool_ops = &cpsw_ethtool_ops; SET_NETDEV_DEV(ndev, dev); diff --git a/drivers/net/ethernet/via/via-velocity.c b/drivers/net/ethernet/via/via-velocity.c index ff0c102cb578..06ac16f37bf5 100644 --- a/drivers/net/ethernet/via/via-velocity.c +++ b/drivers/net/ethernet/via/via-velocity.c @@ -45,6 +45,7 @@ #include <linux/pci.h> #include <linux/kernel.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/etherdevice.h> #include <linux/skbuff.h> #include <linux/delay.h> @@ -2748,6 +2749,16 @@ static u32 velocity_get_link(struct net_device *dev) return BYTE_REG_BITS_IS_ON(PHYSR0_LINKGD, ®s->PHYSR0) ? 1 : 0; }
+static DECLARE_NETDEV_FEATURE_SET(velocity_hw_feature_set, + NETIF_F_IP_CSUM_BIT, + NETIF_F_SG_BIT, + NETIF_F_HW_VLAN_CTAG_TX_BIT); +static DECLARE_NETDEV_FEATURE_SET(velocity_feature_set, + NETIF_F_HW_VLAN_CTAG_TX_BIT, + NETIF_F_HW_VLAN_CTAG_FILTER_BIT, + NETIF_F_HW_VLAN_CTAG_RX_BIT, + NETIF_F_IP_CSUM_BIT); + /** * velocity_probe - set up discovered velocity device * @dev: PCI device @@ -2848,11 +2859,9 @@ static int velocity_probe(struct device *dev, int irq, netdev->ethtool_ops = &velocity_ethtool_ops; netif_napi_add(netdev, &vptr->napi, velocity_poll, NAPI_POLL_WEIGHT);
- netdev->hw_features = NETIF_F_IP_CSUM | NETIF_F_SG | - NETIF_F_HW_VLAN_CTAG_TX; - netdev->features |= NETIF_F_HW_VLAN_CTAG_TX | - NETIF_F_HW_VLAN_CTAG_FILTER | NETIF_F_HW_VLAN_CTAG_RX | - NETIF_F_IP_CSUM; + netdev_hw_features_zero(netdev); + netdev_hw_features_set_array(netdev, &velocity_hw_feature_set); + netdev_active_features_set_array(netdev, &velocity_feature_set);
/* MTU range: 64 - 9000 */ netdev->min_mtu = VELOCITY_MIN_MTU; diff --git a/drivers/net/geneve.c b/drivers/net/geneve.c index 2495a5719e1c..75bc68eba7f7 100644 --- a/drivers/net/geneve.c +++ b/drivers/net/geneve.c @@ -12,6 +12,7 @@ #include <linux/module.h> #include <linux/etherdevice.h> #include <linux/hash.h> +#include <linux/netdev_features_helper.h> #include <net/ipv6_stubs.h> #include <net/dst_metadata.h> #include <net/gro_cells.h> @@ -1233,6 +1234,18 @@ static void geneve_offload_rx_ports(struct net_device *dev, bool push) rcu_read_unlock(); }
+static DECLARE_NETDEV_FEATURE_SET(geneve_feature_set, + NETIF_F_LLTX_BIT, + NETIF_F_SG_BIT, + NETIF_F_HW_CSUM_BIT, + NETIF_F_FRAGLIST_BIT, + NETIF_F_RXCSUM_BIT); +static DECLARE_NETDEV_FEATURE_SET(geneve_hw_feature_set, + NETIF_F_SG_BIT, + NETIF_F_HW_CSUM_BIT, + NETIF_F_FRAGLIST_BIT, + NETIF_F_RXCSUM_BIT); + /* Initialize the device structure. */ static void geneve_setup(struct net_device *dev) { @@ -1244,13 +1257,10 @@ static void geneve_setup(struct net_device *dev)
SET_NETDEV_DEVTYPE(dev, &geneve_type);
- dev->features |= NETIF_F_LLTX; - dev->features |= NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_FRAGLIST; - dev->features |= NETIF_F_RXCSUM; + netdev_active_features_set_array(dev, &geneve_feature_set); dev->features |= NETIF_F_GSO_SOFTWARE;
- dev->hw_features |= NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_FRAGLIST; - dev->hw_features |= NETIF_F_RXCSUM; + netdev_hw_features_set_array(dev, &geneve_hw_feature_set); dev->hw_features |= NETIF_F_GSO_SOFTWARE;
/* MTU range: 68 - (something less than 65535) */ diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c index 15ebd5426604..6bf8d63132a1 100644 --- a/drivers/net/hyperv/netvsc_drv.c +++ b/drivers/net/hyperv/netvsc_drv.c @@ -17,6 +17,7 @@ #include <linux/io.h> #include <linux/delay.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/inetdevice.h> #include <linux/etherdevice.h> #include <linux/pci.h> @@ -2450,6 +2451,11 @@ static int netvsc_unregister_vf(struct net_device *vf_netdev) return NOTIFY_OK; }
+static DECLARE_NETDEV_FEATURE_SET(netvsc_feature_set, + NETIF_F_HIGHDMA_BIT, + NETIF_F_HW_VLAN_CTAG_TX_BIT, + NETIF_F_HW_VLAN_CTAG_RX_BIT); + static int netvsc_probe(struct hv_device *dev, const struct hv_vmbus_device_id *dev_id) { @@ -2533,9 +2539,8 @@ static int netvsc_probe(struct hv_device *dev, schedule_work(&nvdev->subchan_work);
/* hw_features computed in rndis_netdev_set_hwcaps() */ - net->features = net->hw_features | - NETIF_F_HIGHDMA | NETIF_F_HW_VLAN_CTAG_TX | - NETIF_F_HW_VLAN_CTAG_RX; + net->features = net->hw_features; + netdev_active_features_set_array(net, &netvsc_feature_set); net->vlan_features = net->features;
netdev_lockdep_set_classes(net); diff --git a/drivers/net/ifb.c b/drivers/net/ifb.c index 1c64d5347b8e..92ffd1b9849b 100644 --- a/drivers/net/ifb.c +++ b/drivers/net/ifb.c @@ -27,6 +27,7 @@ #include <linux/module.h> #include <linux/kernel.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/ethtool.h> #include <linux/etherdevice.h> #include <linux/init.h> @@ -288,10 +289,13 @@ static const struct ethtool_ops ifb_ethtool_ops = { .get_ethtool_stats = ifb_get_ethtool_stats, };
-#define IFB_FEATURES (NETIF_F_HW_CSUM | NETIF_F_SG | NETIF_F_FRAGLIST | \ - NETIF_F_GSO_SOFTWARE | NETIF_F_GSO_ENCAP_ALL | \ - NETIF_F_HIGHDMA | NETIF_F_HW_VLAN_CTAG_TX | \ - NETIF_F_HW_VLAN_STAG_TX) +static DECLARE_NETDEV_FEATURE_SET(ifb_feature_set, + NETIF_F_HW_CSUM_BIT, + NETIF_F_SG_BIT, + NETIF_F_FRAGLIST_BIT, + NETIF_F_HIGHDMA_BIT, + NETIF_F_HW_VLAN_CTAG_TX_BIT, + NETIF_F_HW_VLAN_STAG_TX_BIT);
static void ifb_dev_free(struct net_device *dev) { @@ -309,6 +313,8 @@ static void ifb_dev_free(struct net_device *dev)
static void ifb_setup(struct net_device *dev) { + netdev_features_t ifb_features; + /* Initialize the device structure. */ dev->netdev_ops = &ifb_netdev_ops; dev->ethtool_ops = &ifb_ethtool_ops; @@ -317,10 +323,12 @@ static void ifb_setup(struct net_device *dev) ether_setup(dev); dev->tx_queue_len = TX_Q_LIMIT;
- dev->features |= IFB_FEATURES; + ifb_features = NETIF_F_GSO_SOFTWARE | NETIF_F_GSO_ENCAP_ALL; + netdev_features_set_array(&ifb_feature_set, &ifb_features); + dev->features |= ifb_features; dev->hw_features |= dev->features; dev->hw_enc_features |= dev->features; - dev->vlan_features |= IFB_FEATURES & ~(NETIF_F_HW_VLAN_CTAG_TX | + dev->vlan_features |= ifb_features & ~(NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_STAG_TX);
dev->flags |= IFF_NOARP; diff --git a/drivers/net/ipvlan/ipvlan_main.c b/drivers/net/ipvlan/ipvlan_main.c index 49ba8a50dfb1..b0d7a484fd39 100644 --- a/drivers/net/ipvlan/ipvlan_main.c +++ b/drivers/net/ipvlan/ipvlan_main.c @@ -3,9 +3,14 @@ */
#include <linux/ethtool.h> +#include <linux/netdev_features_helper.h>
#include "ipvlan.h"
+static netdev_features_t ipvlan_offload_features __ro_after_init; +static netdev_features_t ipvlan_always_on_features __ro_after_init; +static netdev_features_t ipvlan_features __ro_after_init; + static int ipvlan_set_port_mode(struct ipvl_port *port, u16 nval, struct netlink_ext_ack *extack) { @@ -107,18 +112,30 @@ static void ipvlan_port_destroy(struct net_device *dev) kfree(port); }
-#define IPVLAN_ALWAYS_ON_OFLOADS \ - (NETIF_F_SG | NETIF_F_HW_CSUM | \ - NETIF_F_GSO_ROBUST | NETIF_F_GSO_SOFTWARE | NETIF_F_GSO_ENCAP_ALL) - -#define IPVLAN_ALWAYS_ON \ - (IPVLAN_ALWAYS_ON_OFLOADS | NETIF_F_LLTX | NETIF_F_VLAN_CHALLENGED) - -#define IPVLAN_FEATURES \ - (NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_HIGHDMA | NETIF_F_FRAGLIST | \ - NETIF_F_GSO | NETIF_F_ALL_TSO | NETIF_F_GSO_ROBUST | \ - NETIF_F_GRO | NETIF_F_RXCSUM | \ - NETIF_F_HW_VLAN_CTAG_FILTER | NETIF_F_HW_VLAN_STAG_FILTER) +static DECLARE_NETDEV_FEATURE_SET(ipvlan_on_offload_feature_set, + NETIF_F_SG_BIT, + NETIF_F_HW_CSUM_BIT, + NETIF_F_GSO_ROBUST_BIT); + +static DECLARE_NETDEV_FEATURE_SET(ipvlan_always_on_feature_set, + NETIF_F_LLTX_BIT, + NETIF_F_VLAN_CHALLENGED_BIT); + +static DECLARE_NETDEV_FEATURE_SET(ipvlan_feature_set, + NETIF_F_SG_BIT, + NETIF_F_HW_CSUM_BIT, + NETIF_F_HIGHDMA_BIT, + NETIF_F_FRAGLIST_BIT, + NETIF_F_GSO_BIT, + NETIF_F_GSO_ROBUST_BIT, + NETIF_F_GRO_BIT, + NETIF_F_RXCSUM_BIT, + NETIF_F_HW_VLAN_CTAG_FILTER_BIT, + NETIF_F_HW_VLAN_STAG_FILTER_BIT); + +#define IPVLAN_FEATURES ipvlan_features +#define IPVLAN_ALWAYS_ON_OFLOADS ipvlan_offload_features +#define IPVLAN_ALWAYS_ON ipvlan_always_on_features
/* NETIF_F_GSO_ENCAP_ALL NETIF_F_GSO_SOFTWARE Newly added */
@@ -1018,6 +1035,21 @@ static struct notifier_block ipvlan_addr6_vtor_notifier_block __read_mostly = { }; #endif
+static void __init ipvlan_features_init(void) +{ + ipvlan_offload_features = NETIF_F_GSO_SOFTWARE | NETIF_F_GSO_ENCAP_ALL; + netdev_features_set_array(&ipvlan_on_offload_feature_set, + &ipvlan_offload_features); + + ipvlan_always_on_features = ipvlan_offload_features; + netdev_features_set_array(&ipvlan_always_on_feature_set, + &ipvlan_always_on_features); + + ipvlan_features = NETIF_F_ALL_TSO; + netdev_features_set_array(&ipvlan_feature_set, + &ipvlan_features); +} + static int __init ipvlan_init_module(void) { int err; @@ -1042,6 +1074,8 @@ static int __init ipvlan_init_module(void) goto error; }
+ ipvlan_features_init(); + return 0; error: unregister_inetaddr_notifier(&ipvlan_addr4_notifier_block); diff --git a/drivers/net/ipvlan/ipvtap.c b/drivers/net/ipvlan/ipvtap.c index ef02f2cf5ce1..c6d95576ad40 100644 --- a/drivers/net/ipvlan/ipvtap.c +++ b/drivers/net/ipvlan/ipvtap.c @@ -18,14 +18,18 @@ #include <linux/idr.h> #include <linux/fs.h> #include <linux/uio.h> +#include <linux/netdev_features_helper.h>
#include <net/net_namespace.h> #include <net/rtnetlink.h> #include <net/sock.h> #include <linux/virtio_net.h>
-#define TUN_OFFLOADS (NETIF_F_HW_CSUM | NETIF_F_TSO_ECN | NETIF_F_TSO | \ - NETIF_F_TSO6) +static DECLARE_NETDEV_FEATURE_SET(tun_offload_feature_set, + NETIF_F_HW_CSUM_BIT, + NETIF_F_TSO_ECN_BIT, + NETIF_F_TSO_BIT, + NETIF_F_TSO6_BIT);
static dev_t ipvtap_major; static struct cdev ipvtap_cdev; @@ -86,7 +90,9 @@ static int ipvtap_newlink(struct net *src_net, struct net_device *dev, /* Since macvlan supports all offloads by default, make * tap support all offloads also. */ - vlantap->tap.tap_features = TUN_OFFLOADS; + netdev_features_zero(&vlantap->tap.tap_features); + netdev_features_set_array(&tun_offload_feature_set, + &vlantap->tap.tap_features); vlantap->tap.count_tx_dropped = ipvtap_count_tx_dropped; vlantap->tap.update_features = ipvtap_update_features; vlantap->tap.count_rx_dropped = ipvtap_count_rx_dropped; diff --git a/drivers/net/loopback.c b/drivers/net/loopback.c index 14e8d04cb434..308c8674e3ad 100644 --- a/drivers/net/loopback.c +++ b/drivers/net/loopback.c @@ -41,6 +41,7 @@
#include <linux/inet.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/etherdevice.h> #include <linux/skbuff.h> #include <linux/ethtool.h> @@ -160,6 +161,18 @@ static const struct net_device_ops loopback_ops = { .ndo_set_mac_address = eth_mac_addr, };
+static DECLARE_NETDEV_FEATURE_SET(lp_feature_set, + NETIF_F_SG_BIT, + NETIF_F_FRAGLIST_BIT, + NETIF_F_HW_CSUM_BIT, + NETIF_F_RXCSUM_BIT, + NETIF_F_SCTP_CRC_BIT, + NETIF_F_HIGHDMA_BIT, + NETIF_F_LLTX_BIT, + NETIF_F_NETNS_LOCAL_BIT, + NETIF_F_VLAN_CHALLENGED_BIT, + NETIF_F_LOOPBACK_BIT); + static void gen_lo_setup(struct net_device *dev, unsigned int mtu, const struct ethtool_ops *eth_ops, @@ -176,16 +189,8 @@ static void gen_lo_setup(struct net_device *dev, dev->priv_flags |= IFF_LIVE_ADDR_CHANGE | IFF_NO_QUEUE; netif_keep_dst(dev); dev->hw_features = NETIF_F_GSO_SOFTWARE; - dev->features = NETIF_F_SG | NETIF_F_FRAGLIST - | NETIF_F_GSO_SOFTWARE - | NETIF_F_HW_CSUM - | NETIF_F_RXCSUM - | NETIF_F_SCTP_CRC - | NETIF_F_HIGHDMA - | NETIF_F_LLTX - | NETIF_F_NETNS_LOCAL - | NETIF_F_VLAN_CHALLENGED - | NETIF_F_LOOPBACK; + dev->features = NETIF_F_GSO_SOFTWARE; + netdev_active_features_set_array(dev, &lp_feature_set); dev->ethtool_ops = eth_ops; dev->header_ops = hdr_ops; dev->netdev_ops = dev_ops; diff --git a/drivers/net/macsec.c b/drivers/net/macsec.c index f1683ce6b561..fe7557170595 100644 --- a/drivers/net/macsec.c +++ b/drivers/net/macsec.c @@ -12,6 +12,7 @@ #include <crypto/aead.h> #include <linux/etherdevice.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/rtnetlink.h> #include <linux/refcount.h> #include <net/genetlink.h> @@ -3420,15 +3421,20 @@ static netdev_tx_t macsec_start_xmit(struct sk_buff *skb, return ret; }
-#define SW_MACSEC_FEATURES \ - (NETIF_F_SG | NETIF_F_HIGHDMA | NETIF_F_FRAGLIST) +static netdev_features_t macsec_real_dev_features_mask __ro_after_init; +static netdev_features_t sw_macsec_features __ro_after_init; +static DECLARE_NETDEV_FEATURE_SET(sw_macsec_feature_set, + NETIF_F_SG_BIT, + NETIF_F_HIGHDMA_BIT, + NETIF_F_FRAGLIST_BIT); +#define SW_MACSEC_FEATURES sw_macsec_features
/* If h/w offloading is enabled, use real device features save for * VLAN_FEATURES - they require additional ops * HW_MACSEC - no reason to report it */ #define REAL_DEV_FEATURES(dev) \ - ((dev)->features & ~(NETIF_F_VLAN_FEATURES | NETIF_F_HW_MACSEC)) + ((dev)->features & ~sw_macsec_features)
static int macsec_dev_init(struct net_device *dev) { @@ -4351,6 +4357,14 @@ static struct notifier_block macsec_notifier = { .notifier_call = macsec_notify, };
+static void __init macsec_features_init(void) +{ + netdev_features_set_array(&sw_macsec_feature_set, &sw_macsec_features); + + macsec_real_dev_features_mask = NETIF_F_VLAN_FEATURES; + macsec_real_dev_features_mask |= NETIF_F_HW_MACSEC; +} + static int __init macsec_init(void) { int err; @@ -4368,6 +4382,8 @@ static int __init macsec_init(void) if (err) goto rtnl;
+ macsec_features_init(); + return 0;
rtnl: diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c index 1080d6ebff63..d9a20c0341c6 100644 --- a/drivers/net/macvlan.c +++ b/drivers/net/macvlan.c @@ -19,6 +19,7 @@ #include <linux/rculist.h> #include <linux/notifier.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/etherdevice.h> #include <linux/net_tstamp.h> #include <linux/ethtool.h> @@ -67,6 +68,10 @@ struct macvlan_skb_cb {
#define MACVLAN_SKB_CB(__skb) ((struct macvlan_skb_cb *)&((__skb)->cb[0]))
+static netdev_features_t macvlan_offload_features __ro_after_init; +static netdev_features_t macvlan_always_on_features __ro_after_init; +static netdev_features_t macvlan_features __ro_after_init; + static void macvlan_port_destroy(struct net_device *dev); static void update_port_bc_queue_len(struct macvlan_port *port);
@@ -868,17 +873,30 @@ static int macvlan_eth_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) */ static struct lock_class_key macvlan_netdev_addr_lock_key;
-#define ALWAYS_ON_OFFLOADS \ - (NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_GSO_SOFTWARE | \ - NETIF_F_GSO_ROBUST | NETIF_F_GSO_ENCAP_ALL) - -#define ALWAYS_ON_FEATURES (ALWAYS_ON_OFFLOADS | NETIF_F_LLTX) - -#define MACVLAN_FEATURES \ - (NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_HIGHDMA | NETIF_F_FRAGLIST | \ - NETIF_F_GSO | NETIF_F_TSO | NETIF_F_LRO | \ - NETIF_F_TSO_ECN | NETIF_F_TSO6 | NETIF_F_GRO | NETIF_F_RXCSUM | \ - NETIF_F_HW_VLAN_CTAG_FILTER | NETIF_F_HW_VLAN_STAG_FILTER) +static DECLARE_NETDEV_FEATURE_SET(macvlan_on_offload_feature_set, + NETIF_F_SG_BIT, + NETIF_F_HW_CSUM_BIT, + NETIF_F_GSO_ROBUST_BIT); +static DECLARE_NETDEV_FEATURE_SET(macvlan_always_on_feature_set, + NETIF_F_LLTX_BIT); +static DECLARE_NETDEV_FEATURE_SET(macvlan_feature_set, + NETIF_F_SG_BIT, + NETIF_F_HW_CSUM_BIT, + NETIF_F_HIGHDMA_BIT, + NETIF_F_FRAGLIST_BIT, + NETIF_F_GSO_BIT, + NETIF_F_TSO_BIT, + NETIF_F_LRO_BIT, + NETIF_F_TSO_ECN_BIT, + NETIF_F_TSO6_BIT, + NETIF_F_GRO_BIT, + NETIF_F_RXCSUM_BIT, + NETIF_F_HW_VLAN_CTAG_FILTER_BIT, + NETIF_F_HW_VLAN_STAG_FILTER_BIT); + +#define MACVLAN_FEATURES macvlan_features +#define ALWAYS_ON_OFFLOADS macvlan_offload_features +#define ALWAYS_ON_FEATURES macvlan_always_on_features
#define MACVLAN_STATE_MASK \ ((1<<__LINK_STATE_NOCARRIER) | (1<<__LINK_STATE_DORMANT)) @@ -1813,6 +1831,20 @@ static struct notifier_block macvlan_notifier_block __read_mostly = { .notifier_call = macvlan_device_event, };
+static void __init macvlan_features_init(void) +{ + macvlan_offload_features = NETIF_F_GSO_SOFTWARE | NETIF_F_GSO_ENCAP_ALL; + netdev_features_set_array(&macvlan_on_offload_feature_set, + &macvlan_offload_features); + + macvlan_always_on_features = macvlan_offload_features; + netdev_features_set_array(&macvlan_always_on_feature_set, + &macvlan_always_on_features); + + netdev_features_set_array(&macvlan_feature_set, + &macvlan_features); +} + static int __init macvlan_init_module(void) { int err; @@ -1822,6 +1854,8 @@ static int __init macvlan_init_module(void) err = macvlan_link_register(&macvlan_link_ops); if (err < 0) goto err1; + + macvlan_features_init(); return 0; err1: unregister_netdevice_notifier(&macvlan_notifier_block); diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c index cecf8c63096c..03ee8c8f9ee7 100644 --- a/drivers/net/macvtap.c +++ b/drivers/net/macvtap.c @@ -18,6 +18,7 @@ #include <linux/idr.h> #include <linux/fs.h> #include <linux/uio.h> +#include <linux/netdev_features_helper.h>
#include <net/net_namespace.h> #include <net/rtnetlink.h> @@ -49,8 +50,11 @@ static struct class macvtap_class = { }; static struct cdev macvtap_cdev;
-#define TUN_OFFLOADS (NETIF_F_HW_CSUM | NETIF_F_TSO_ECN | NETIF_F_TSO | \ - NETIF_F_TSO6) +static DECLARE_NETDEV_FEATURE_SET(tun_offload_feature_set, + NETIF_F_HW_CSUM_BIT, + NETIF_F_TSO_ECN_BIT, + NETIF_F_TSO_BIT, + NETIF_F_TSO6_BIT);
static void macvtap_count_tx_dropped(struct tap_dev *tap) { @@ -90,7 +94,9 @@ static int macvtap_newlink(struct net *src_net, struct net_device *dev, /* Since macvlan supports all offloads by default, make * tap support all offloads also. */ - vlantap->tap.tap_features = TUN_OFFLOADS; + netdev_features_zero(&vlantap->tap.tap_features); + netdev_features_set_array(&tun_offload_feature_set, + &vlantap->tap.tap_features);
/* Register callbacks for rx/tx drops accounting and updating * net_device features diff --git a/drivers/net/net_failover.c b/drivers/net/net_failover.c index 21a0435c02de..6d6a6781fcc9 100644 --- a/drivers/net/net_failover.c +++ b/drivers/net/net_failover.c @@ -27,6 +27,19 @@ #include <uapi/linux/if_arp.h> #include <net/net_failover.h>
+static netdev_features_t failover_vlan_features __ro_after_init; +static netdev_features_t failover_enc_features __ro_after_init; +static DECLARE_NETDEV_FEATURE_SET(failover_vlan_feature_set, + NETIF_F_HIGHDMA_BIT, + NETIF_F_SG_BIT, + NETIF_F_FRAGLIST_BIT, + NETIF_F_HIGHDMA_BIT, + NETIF_F_LRO_BIT); +static DECLARE_NETDEV_FEATURE_SET(failover_enc_feature_set, + NETIF_F_HW_CSUM_BIT, + NETIF_F_SG_BIT, + NETIF_F_RXCSUM_BIT); + static bool net_failover_xmit_ready(struct net_device *dev) { return netif_running(dev) && netif_carrier_ok(dev); diff --git a/drivers/net/netdevsim/ipsec.c b/drivers/net/netdevsim/ipsec.c index 386336a38f34..ad0b5bf06f49 100644 --- a/drivers/net/netdevsim/ipsec.c +++ b/drivers/net/netdevsim/ipsec.c @@ -272,16 +272,17 @@ bool nsim_ipsec_tx(struct netdevsim *ns, struct sk_buff *skb) return true; }
+static DECLARE_NETDEV_FEATURE_SET(nsim_esp_feature_set, + NETIF_F_HW_ESP_BIT, + NETIF_F_HW_ESP_TX_CSUM_BIT, + NETIF_F_GSO_ESP_BIT); + void nsim_ipsec_init(struct netdevsim *ns) { ns->netdev->xfrmdev_ops = &nsim_xfrmdev_ops;
-#define NSIM_ESP_FEATURES (NETIF_F_HW_ESP | \ - NETIF_F_HW_ESP_TX_CSUM | \ - NETIF_F_GSO_ESP) - - ns->netdev->features |= NSIM_ESP_FEATURES; - ns->netdev->hw_enc_features |= NSIM_ESP_FEATURES; + netdev_active_features_set_array(ns->netdev, &nsim_esp_feature_set); + netdev_hw_enc_features_set_array(ns->netdev, &nsim_esp_feature_set);
ns->ipsec.pfile = debugfs_create_file("ipsec", 0400, ns->nsim_dev_port->ddir, ns, diff --git a/drivers/net/netdevsim/netdev.c b/drivers/net/netdevsim/netdev.c index e470e3398abc..ad687b14dda3 100644 --- a/drivers/net/netdevsim/netdev.c +++ b/drivers/net/netdevsim/netdev.c @@ -18,6 +18,7 @@ #include <linux/kernel.h> #include <linux/module.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/slab.h> #include <net/netlink.h> #include <net/pkt_cls.h> @@ -278,6 +279,13 @@ static const struct net_device_ops nsim_vf_netdev_ops = { .ndo_get_devlink_port = nsim_get_devlink_port, };
+static DECLARE_NETDEV_FEATURE_SET(nsim_feature_set, + NETIF_F_HIGHDMA_BIT, + NETIF_F_SG_BIT, + NETIF_F_FRAGLIST_BIT, + NETIF_F_HW_CSUM_BIT, + NETIF_F_TSO_BIT); + static void nsim_setup(struct net_device *dev) { ether_setup(dev); @@ -288,11 +296,7 @@ static void nsim_setup(struct net_device *dev) dev->flags &= ~IFF_MULTICAST; dev->priv_flags |= IFF_LIVE_ADDR_CHANGE | IFF_NO_QUEUE; - dev->features |= NETIF_F_HIGHDMA | - NETIF_F_SG | - NETIF_F_FRAGLIST | - NETIF_F_HW_CSUM | - NETIF_F_TSO; + netdev_active_features_set_array(dev, &nsim_feature_set); dev->hw_features |= NETIF_F_HW_TC; dev->max_mtu = ETH_MAX_MTU; } diff --git a/drivers/net/netdevsim/netdevsim.h b/drivers/net/netdevsim/netdevsim.h index 7d8ed8d8df5c..cf020a685530 100644 --- a/drivers/net/netdevsim/netdevsim.h +++ b/drivers/net/netdevsim/netdevsim.h @@ -19,6 +19,7 @@ #include <linux/kernel.h> #include <linux/list.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/u64_stats_sync.h> #include <net/devlink.h> #include <net/udp_tunnel.h> diff --git a/drivers/net/nlmon.c b/drivers/net/nlmon.c index 5e19a6839dea..2ccfaf04b429 100644 --- a/drivers/net/nlmon.c +++ b/drivers/net/nlmon.c @@ -3,6 +3,7 @@ #include <linux/module.h> #include <linux/kernel.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/netlink.h> #include <net/net_namespace.h> #include <linux/if_arp.h> @@ -80,6 +81,12 @@ static const struct net_device_ops nlmon_ops = { .ndo_get_stats64 = nlmon_get_stats64, };
+static DECLARE_NETDEV_FEATURE_SET(nlmon_feature_set, + NETIF_F_SG_BIT, + NETIF_F_FRAGLIST_BIT, + NETIF_F_HIGHDMA_BIT, + NETIF_F_LLTX_BIT); + static void nlmon_setup(struct net_device *dev) { dev->type = ARPHRD_NETLINK; @@ -89,8 +96,8 @@ static void nlmon_setup(struct net_device *dev) dev->ethtool_ops = &nlmon_ethtool_ops; dev->needs_free_netdev = true;
- dev->features = NETIF_F_SG | NETIF_F_FRAGLIST | - NETIF_F_HIGHDMA | NETIF_F_LLTX; + netdev_active_features_zero(dev); + netdev_active_features_set_array(dev, &nlmon_feature_set); dev->flags = IFF_NOARP;
/* That's rather a softlimit here, which, of course, diff --git a/drivers/net/tap.c b/drivers/net/tap.c index c3d42062559d..7b1c1e724c43 100644 --- a/drivers/net/tap.c +++ b/drivers/net/tap.c @@ -17,6 +17,7 @@ #include <linux/idr.h> #include <linux/fs.h> #include <linux/uio.h> +#include <linux/netdev_features_helper.h>
#include <net/net_namespace.h> #include <net/rtnetlink.h> @@ -116,8 +117,13 @@ struct major_info {
static const struct proto_ops tap_socket_ops;
-#define RX_OFFLOADS (NETIF_F_GRO | NETIF_F_LRO) -#define TAP_FEATURES (NETIF_F_GSO | NETIF_F_SG | NETIF_F_FRAGLIST) +static DECLARE_NETDEV_FEATURE_SET(tap_rx_offload_feature_set, + NETIF_F_GRO_BIT, + NETIF_F_LRO_BIT); +static DECLARE_NETDEV_FEATURE_SET(tap_feature_set, + NETIF_F_GSO_BIT, + NETIF_F_SG_BIT, + NETIF_F_FRAGLIST_BIT);
static struct tap_dev *tap_dev_get_rcu(const struct net_device *dev) { @@ -321,7 +327,7 @@ rx_handler_result_t tap_handle_frame(struct sk_buff **pskb) struct net_device *dev = skb->dev; struct tap_dev *tap; struct tap_queue *q; - netdev_features_t features = TAP_FEATURES; + netdev_features_t features; enum skb_drop_reason drop_reason;
tap = tap_dev_get_rcu(dev); @@ -334,6 +340,8 @@ rx_handler_result_t tap_handle_frame(struct sk_buff **pskb)
skb_push(skb, ETH_HLEN);
+ netdev_features_zero(&features); + netdev_features_set_array(&tap_feature_set, &features); /* Apply the forward feature mask so that we perform segmentation * according to users wishes. This only works if VNET_HDR is * enabled. @@ -966,9 +974,9 @@ static int set_offload(struct tap_queue *q, unsigned long arg) * user-space will not receive TSO frames. */ if (feature_mask & (NETIF_F_TSO | NETIF_F_TSO6)) - features |= RX_OFFLOADS; + netdev_features_set_array(&tap_rx_offload_feature_set, &features); else - features &= ~RX_OFFLOADS; + netdev_features_clear_array(&tap_rx_offload_feature_set, &features);
/* tap_features are the same as features on tun/tap and * reflect user expectations. diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c index aac133a1e27a..452d414dff62 100644 --- a/drivers/net/team/team.c +++ b/drivers/net/team/team.c @@ -15,6 +15,7 @@ #include <linux/ctype.h> #include <linux/notifier.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/netpoll.h> #include <linux/if_vlan.h> #include <linux/if_arp.h> @@ -980,12 +981,20 @@ static void team_port_disable(struct team *team, team_lower_state_changed(port); }
-#define TEAM_VLAN_FEATURES (NETIF_F_HW_CSUM | NETIF_F_SG | \ - NETIF_F_FRAGLIST | NETIF_F_GSO_SOFTWARE | \ - NETIF_F_HIGHDMA | NETIF_F_LRO) - -#define TEAM_ENC_FEATURES (NETIF_F_HW_CSUM | NETIF_F_SG | \ - NETIF_F_RXCSUM | NETIF_F_GSO_SOFTWARE) +static DECLARE_NETDEV_FEATURE_SET(team_vlan_feature_set, + NETIF_F_HW_CSUM_BIT, + NETIF_F_SG_BIT, + NETIF_F_FRAGLIST_BIT, + NETIF_F_HIGHDMA_BIT, + NETIF_F_LRO_BIT); +static DECLARE_NETDEV_FEATURE_SET(team_enc_feature_set, + NETIF_F_HW_CSUM_BIT, + NETIF_F_SG_BIT, + NETIF_F_RXCSUM_BIT); +static netdev_features_t team_vlan_features __ro_after_init; +static netdev_features_t team_enc_features __ro_after_init; +#define TEAM_VLAN_FEATURES team_vlan_features +#define TEAM_ENC_FEATURES team_enc_features
static void __team_compute_features(struct team *team) { @@ -2875,6 +2884,13 @@ static void team_nl_fini(void) genl_unregister_family(&team_nl_family); }
+static void __init team_features_init(void) +{ + team_vlan_features = NETIF_F_GSO_SOFTWARE; + netdev_features_set_array(&team_vlan_feature_set, &team_vlan_features); + team_enc_features = NETIF_F_GSO_SOFTWARE; + netdev_features_set_array(&team_enc_feature_set, &team_enc_features); +}
/****************** * Change checkers @@ -3031,7 +3047,6 @@ static struct notifier_block team_notifier_block __read_mostly = { .notifier_call = team_device_event, };
- /*********************** * Module init and exit ***********************/ @@ -3050,6 +3065,8 @@ static int __init team_module_init(void) if (err) goto err_nl_init;
+ team_features_init(); + return 0;
err_nl_init: diff --git a/drivers/net/thunderbolt.c b/drivers/net/thunderbolt.c index ff5d0e98a088..baed53386606 100644 --- a/drivers/net/thunderbolt.c +++ b/drivers/net/thunderbolt.c @@ -14,6 +14,7 @@ #include <linux/jhash.h> #include <linux/module.h> #include <linux/etherdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/rtnetlink.h> #include <linux/sizes.h> #include <linux/thunderbolt.h> @@ -1217,6 +1218,12 @@ static void tbnet_generate_mac(struct net_device *dev) eth_hw_addr_set(dev, addr); }
+static DECLARE_NETDEV_FEATURE_SET(tbnet_hw_feature_set, + NETIF_F_SG_BIT, + NETIF_F_GRO_BIT, + NETIF_F_IP_CSUM_BIT, + NETIF_F_IPV6_CSUM_BIT); + static int tbnet_probe(struct tb_service *svc, const struct tb_service_id *id) { struct tb_xdomain *xd = tb_service_parent(svc); @@ -1259,8 +1266,8 @@ static int tbnet_probe(struct tb_service *svc, const struct tb_service_id *id) * we need to announce support for most of the offloading * features here. */ - dev->hw_features = NETIF_F_SG | NETIF_F_ALL_TSO | NETIF_F_GRO | - NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM; + dev->hw_features = NETIF_F_ALL_TSO; + netdev_hw_features_set_array(dev, &tbnet_hw_feature_set); dev->features = dev->hw_features | NETIF_F_HIGHDMA; dev->hard_header_len += sizeof(struct thunderbolt_ip_frame_header);
diff --git a/drivers/net/tun.c b/drivers/net/tun.c index 259b2b84b2b3..d34d930a3029 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c @@ -43,6 +43,7 @@ #include <linux/init.h> #include <linux/skbuff.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/etherdevice.h> #include <linux/miscdevice.h> #include <linux/ethtool.h> @@ -171,6 +172,19 @@ struct tun_prog { struct bpf_prog *prog; };
+static netdev_features_t tun_user_features __ro_after_init; +static DECLARE_NETDEV_FEATURE_SET(tun_user_feature_set, + NETIF_F_HW_CSUM_BIT, + NETIF_F_TSO_ECN_BIT, + NETIF_F_TSO_BIT, + NETIF_F_TSO6_BIT); +static DECLARE_NETDEV_FEATURE_SET(tun_hw_feature_set, + NETIF_F_SG_BIT, + NETIF_F_FRAGLIST_BIT, + NETIF_F_HW_VLAN_CTAG_TX_BIT, + NETIF_F_HW_VLAN_STAG_TX_BIT); +#define TUN_USER_FEATURES tun_user_features + /* Since the socket were moved to tun_file, to preserve the behavior of persist * device, socket filter, sndbuf and vnet header size were restore when the * file were attached to a persist device. @@ -184,8 +198,6 @@ struct tun_struct {
struct net_device *dev; netdev_features_t set_features; -#define TUN_USER_FEATURES (NETIF_F_HW_CSUM|NETIF_F_TSO_ECN|NETIF_F_TSO| \ - NETIF_F_TSO6)
int align; int vnet_hdr_sz; @@ -989,9 +1001,8 @@ static int tun_net_init(struct net_device *dev)
tun_flow_init(tun);
- dev->hw_features = NETIF_F_SG | NETIF_F_FRAGLIST | - TUN_USER_FEATURES | NETIF_F_HW_VLAN_CTAG_TX | - NETIF_F_HW_VLAN_STAG_TX; + dev->hw_features = TUN_USER_FEATURES; + netdev_hw_features_set_array(dev, &tun_hw_feature_set); dev->features = dev->hw_features | NETIF_F_LLTX; dev->vlan_features = dev->features & ~(NETIF_F_HW_VLAN_CTAG_TX | @@ -3668,6 +3679,11 @@ static struct notifier_block tun_notifier_block __read_mostly = { .notifier_call = tun_device_event, };
+static void __init tun_features_init(void) +{ + netdev_features_set_array(&tun_user_feature_set, &tun_user_features); +} + static int __init tun_init(void) { int ret = 0; @@ -3692,6 +3708,8 @@ static int __init tun_init(void) goto err_notifier; }
+ tun_features_init(); + return 0;
err_notifier: diff --git a/drivers/net/usb/aqc111.c b/drivers/net/usb/aqc111.c index 3020e81159d0..d55be54264f8 100644 --- a/drivers/net/usb/aqc111.c +++ b/drivers/net/usb/aqc111.c @@ -9,6 +9,7 @@
#include <linux/module.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/ethtool.h> #include <linux/mii.h> #include <linux/usb.h> @@ -22,6 +23,31 @@
#define DRIVER_NAME "aqc111"
+/* Feature. ********************************************/ +DECLARE_NETDEV_FEATURE_SET(aq_support_feature_set, + NETIF_F_SG_BIT, + NETIF_F_IP_CSUM_BIT, + NETIF_F_IPV6_CSUM_BIT, + NETIF_F_RXCSUM_BIT, + NETIF_F_TSO_BIT, + NETIF_F_HW_VLAN_CTAG_TX_BIT, + NETIF_F_HW_VLAN_CTAG_RX_BIT); + +DECLARE_NETDEV_FEATURE_SET(aq_support_hw_feature_set, + NETIF_F_SG_BIT, + NETIF_F_IP_CSUM_BIT, + NETIF_F_IPV6_CSUM_BIT, + NETIF_F_RXCSUM_BIT, + NETIF_F_TSO_BIT, + NETIF_F_HW_VLAN_CTAG_FILTER_BIT); + +DECLARE_NETDEV_FEATURE_SET(aq_support_vlan_feature_set, + NETIF_F_SG_BIT, + NETIF_F_IP_CSUM_BIT, + NETIF_F_IPV6_CSUM_BIT, + NETIF_F_RXCSUM_BIT, + NETIF_F_TSO_BIT); + static int aqc111_read_cmd_nopm(struct usbnet *dev, u8 cmd, u16 value, u16 index, u16 size, void *data) { @@ -731,9 +757,9 @@ static int aqc111_bind(struct usbnet *dev, struct usb_interface *intf) if (usb_device_no_sg_constraint(dev->udev)) dev->can_dma_sg = 1;
- dev->net->hw_features |= AQ_SUPPORT_HW_FEATURE; - dev->net->features |= AQ_SUPPORT_FEATURE; - dev->net->vlan_features |= AQ_SUPPORT_VLAN_FEATURE; + netdev_hw_features_set_array(dev->net, &aq_support_hw_feature_set); + netdev_active_features_set_array(dev->net, &aq_support_feature_set); + netdev_vlan_features_set_array(dev->net, &aq_support_vlan_feature_set);
netif_set_tso_max_size(dev->net, 65535);
@@ -996,9 +1022,9 @@ static int aqc111_reset(struct usbnet *dev) if (usb_device_no_sg_constraint(dev->udev)) dev->can_dma_sg = 1;
- dev->net->hw_features |= AQ_SUPPORT_HW_FEATURE; - dev->net->features |= AQ_SUPPORT_FEATURE; - dev->net->vlan_features |= AQ_SUPPORT_VLAN_FEATURE; + netdev_hw_features_set_array(dev->net, &aq_support_hw_feature_set); + netdev_active_features_set_array(dev->net, &aq_support_feature_set); + netdev_vlan_features_set_array(dev->net, &aq_support_vlan_feature_set);
/* Power up ethernet PHY */ aqc111_data->phy_cfg = AQ_PHY_POWER_EN; diff --git a/drivers/net/usb/aqc111.h b/drivers/net/usb/aqc111.h index b562db4da337..ebc23df8295f 100644 --- a/drivers/net/usb/aqc111.h +++ b/drivers/net/usb/aqc111.h @@ -24,20 +24,6 @@ #define AQ_USB_PHY_SET_TIMEOUT 10000 #define AQ_USB_SET_TIMEOUT 4000
-/* Feature. ********************************************/ -#define AQ_SUPPORT_FEATURE (NETIF_F_SG | NETIF_F_IP_CSUM |\ - NETIF_F_IPV6_CSUM | NETIF_F_RXCSUM |\ - NETIF_F_TSO | NETIF_F_HW_VLAN_CTAG_TX |\ - NETIF_F_HW_VLAN_CTAG_RX) - -#define AQ_SUPPORT_HW_FEATURE (NETIF_F_SG | NETIF_F_IP_CSUM |\ - NETIF_F_IPV6_CSUM | NETIF_F_RXCSUM |\ - NETIF_F_TSO | NETIF_F_HW_VLAN_CTAG_FILTER) - -#define AQ_SUPPORT_VLAN_FEATURE (NETIF_F_SG | NETIF_F_IP_CSUM |\ - NETIF_F_IPV6_CSUM | NETIF_F_RXCSUM |\ - NETIF_F_TSO) - /* SFR Reg. ********************************************/
#define SFR_GENERAL_STATUS 0x03 diff --git a/drivers/net/usb/ax88179_178a.c b/drivers/net/usb/ax88179_178a.c index 3b0e8f93e3c8..27fcb75dcba3 100644 --- a/drivers/net/usb/ax88179_178a.c +++ b/drivers/net/usb/ax88179_178a.c @@ -13,6 +13,7 @@ #include <linux/usb/usbnet.h> #include <uapi/linux/mdio.h> #include <linux/mdio.h> +#include <linux/netdev_features_helper.h>
#define AX88179_PHY_ID 0x03 #define AX_EEPROM_LEN 0x100 @@ -1265,6 +1266,13 @@ static void ax88179_get_mac_addr(struct usbnet *dev) dev->net->dev_addr); }
+DECLARE_NETDEV_FEATURE_SET(ax88179_feature_set, + NETIF_F_SG_BIT, + NETIF_F_IP_CSUM_BIT, + NETIF_F_IPV6_CSUM_BIT, + NETIF_F_RXCSUM_BIT, + NETIF_F_TSO_BIT); + static int ax88179_bind(struct usbnet *dev, struct usb_interface *intf) { struct ax88179_data *ax179_data; @@ -1291,8 +1299,7 @@ static int ax88179_bind(struct usbnet *dev, struct usb_interface *intf) dev->mii.phy_id = 0x03; dev->mii.supports_gmii = 1;
- dev->net->features |= NETIF_F_SG | NETIF_F_IP_CSUM | - NETIF_F_IPV6_CSUM | NETIF_F_RXCSUM | NETIF_F_TSO; + netdev_active_features_set_array(dev->net, &ax88179_feature_set);
dev->net->hw_features |= dev->net->features;
diff --git a/drivers/net/usb/lan78xx.c b/drivers/net/usb/lan78xx.c index 3226ab33afae..b3c01bee9504 100644 --- a/drivers/net/usb/lan78xx.c +++ b/drivers/net/usb/lan78xx.c @@ -25,6 +25,7 @@ #include <linux/irq.h> #include <linux/irqchip/chained_irq.h> #include <linux/microchipphy.h> +#include <linux/netdev_features_helper.h> #include <linux/phy_fixed.h> #include <linux/of_mdio.h> #include <linux/of_net.h> @@ -3430,6 +3431,11 @@ lan78xx_start_xmit(struct sk_buff *skb, struct net_device *net) return NETDEV_TX_OK; }
+static DECLARE_NETDEV_FEATURE_SET(lan78xx_tso_feature_set, + NETIF_F_TSO_BIT, + NETIF_F_TSO6_BIT, + NETIF_F_SG_BIT); + static int lan78xx_bind(struct lan78xx_net *dev, struct usb_interface *intf) { struct lan78xx_priv *pdata = NULL; @@ -3465,7 +3471,7 @@ static int lan78xx_bind(struct lan78xx_net *dev, struct usb_interface *intf) dev->net->features |= NETIF_F_RXCSUM;
if (DEFAULT_TSO_CSUM_ENABLE) - dev->net->features |= NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_SG; + netdev_active_features_set_array(dev->net, &lan78xx_tso_feature_set);
if (DEFAULT_VLAN_RX_OFFLOAD) dev->net->features |= NETIF_F_HW_VLAN_CTAG_RX; diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c index 0f6efaabaa32..5e11eaab71f5 100644 --- a/drivers/net/usb/r8152.c +++ b/drivers/net/usb/r8152.c @@ -7,6 +7,7 @@ #include <linux/slab.h> #include <linux/module.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/etherdevice.h> #include <linux/mii.h> #include <linux/ethtool.h> @@ -2095,6 +2096,11 @@ static struct tx_agg *r8152_get_tx_agg(struct r8152 *tp) return agg; }
+static DECLARE_NETDEV_FEATURE_SET(r8152_csum_feature_set, + NETIF_F_SG_BIT, + NETIF_F_IPV6_CSUM_BIT, + NETIF_F_TSO6_BIT); + /* r8152_csum_workaround() * The hw limits the value of the transport offset. When the offset is out of * range, calculate the checksum by sw. @@ -2107,7 +2113,7 @@ static void r8152_csum_workaround(struct r8152 *tp, struct sk_buff *skb, struct sk_buff *segs, *seg, *next; struct sk_buff_head seg_list;
- features &= ~(NETIF_F_SG | NETIF_F_IPV6_CSUM | NETIF_F_TSO6); + netdev_features_clear_array(&r8152_csum_feature_set, &features); segs = skb_gso_segment(skb, features); if (IS_ERR(segs) || !segs) goto drop; @@ -9576,6 +9582,35 @@ u8 rtl8152_get_version(struct usb_interface *intf) } EXPORT_SYMBOL_GPL(rtl8152_get_version);
+static DECLARE_NETDEV_FEATURE_SET(r8152_feature_set, + NETIF_F_RXCSUM_BIT, + NETIF_F_IP_CSUM_BIT, + NETIF_F_SG_BIT, + NETIF_F_TSO_BIT, + NETIF_F_FRAGLIST_BIT, + NETIF_F_IPV6_CSUM_BIT, + NETIF_F_TSO6_BIT, + NETIF_F_HW_VLAN_CTAG_RX_BIT, + NETIF_F_HW_VLAN_CTAG_TX_BIT); +static DECLARE_NETDEV_FEATURE_SET(r8152_hw_feature_set, + NETIF_F_RXCSUM_BIT, + NETIF_F_IP_CSUM_BIT, + NETIF_F_SG_BIT, + NETIF_F_TSO_BIT, + NETIF_F_FRAGLIST_BIT, + NETIF_F_IPV6_CSUM_BIT, + NETIF_F_TSO6_BIT, + NETIF_F_HW_VLAN_CTAG_RX_BIT, + NETIF_F_HW_VLAN_CTAG_TX_BIT); +static DECLARE_NETDEV_FEATURE_SET(r8152_vlan_feature_set, + NETIF_F_SG_BIT, + NETIF_F_IP_CSUM_BIT, + NETIF_F_TSO_BIT, + NETIF_F_HIGHDMA_BIT, + NETIF_F_FRAGLIST_BIT, + NETIF_F_IPV6_CSUM_BIT, + NETIF_F_TSO6_BIT); + static bool rtl8152_supports_lenovo_macpassthru(struct usb_device *udev) { int parent_vendor_id = le16_to_cpu(udev->parent->descriptor.idVendor); @@ -9662,17 +9697,11 @@ static int rtl8152_probe(struct usb_interface *intf, netdev->netdev_ops = &rtl8152_netdev_ops; netdev->watchdog_timeo = RTL8152_TX_TIMEOUT;
- netdev->features |= NETIF_F_RXCSUM | NETIF_F_IP_CSUM | NETIF_F_SG | - NETIF_F_TSO | NETIF_F_FRAGLIST | NETIF_F_IPV6_CSUM | - NETIF_F_TSO6 | NETIF_F_HW_VLAN_CTAG_RX | - NETIF_F_HW_VLAN_CTAG_TX; - netdev->hw_features = NETIF_F_RXCSUM | NETIF_F_IP_CSUM | NETIF_F_SG | - NETIF_F_TSO | NETIF_F_FRAGLIST | - NETIF_F_IPV6_CSUM | NETIF_F_TSO6 | - NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_HW_VLAN_CTAG_TX; - netdev->vlan_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO | - NETIF_F_HIGHDMA | NETIF_F_FRAGLIST | - NETIF_F_IPV6_CSUM | NETIF_F_TSO6; + netdev_active_features_set_array(netdev, &r8152_feature_set); + netdev_hw_features_zero(netdev); + netdev_hw_features_set_array(netdev, &r8152_hw_feature_set); + netdev_vlan_features_zero(netdev); + netdev_vlan_features_set_array(netdev, &r8152_vlan_feature_set);
if (tp->version == RTL_VER_01) { netdev->features &= ~NETIF_F_RXCSUM; diff --git a/drivers/net/usb/smsc75xx.c b/drivers/net/usb/smsc75xx.c index 95de452ff4da..34b79291e159 100644 --- a/drivers/net/usb/smsc75xx.c +++ b/drivers/net/usb/smsc75xx.c @@ -8,6 +8,7 @@ #include <linux/module.h> #include <linux/kmod.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/etherdevice.h> #include <linux/ethtool.h> #include <linux/mii.h> @@ -1445,6 +1446,11 @@ static const struct net_device_ops smsc75xx_netdev_ops = { .ndo_set_features = smsc75xx_set_features, };
+static DECLARE_NETDEV_FEATURE_SET(smsc75xx_hw_feature_set, + NETIF_F_IP_CSUM_BIT, + NETIF_F_IPV6_CSUM_BIT, + NETIF_F_RXCSUM_BIT); + static int smsc75xx_bind(struct usbnet *dev, struct usb_interface *intf) { struct smsc75xx_priv *pdata = NULL; @@ -1478,8 +1484,8 @@ static int smsc75xx_bind(struct usbnet *dev, struct usb_interface *intf) if (DEFAULT_RX_CSUM_ENABLE) dev->net->features |= NETIF_F_RXCSUM;
- dev->net->hw_features = NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | - NETIF_F_RXCSUM; + netdev_hw_features_zero(dev->net); + netdev_hw_features_set_array(dev->net, &smsc75xx_hw_feature_set);
ret = smsc75xx_wait_ready(dev, 0); if (ret < 0) { diff --git a/drivers/net/veth.c b/drivers/net/veth.c index 2cb833b3006a..6de15832dafe 100644 --- a/drivers/net/veth.c +++ b/drivers/net/veth.c @@ -10,6 +10,7 @@ */
#include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/slab.h> #include <linux/ethtool.h> #include <linux/etherdevice.h> @@ -1620,14 +1621,22 @@ static const struct net_device_ops veth_netdev_ops = { .ndo_get_peer_dev = veth_peer_dev, };
-#define VETH_FEATURES (NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_HW_CSUM | \ - NETIF_F_RXCSUM | NETIF_F_SCTP_CRC | NETIF_F_HIGHDMA | \ - NETIF_F_GSO_SOFTWARE | NETIF_F_GSO_ENCAP_ALL | \ - NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX | \ - NETIF_F_HW_VLAN_STAG_TX | NETIF_F_HW_VLAN_STAG_RX ) +static DECLARE_NETDEV_FEATURE_SET(veth_feature_set, + NETIF_F_SG_BIT, + NETIF_F_FRAGLIST_BIT, + NETIF_F_HW_CSUM_BIT, + NETIF_F_RXCSUM_BIT, + NETIF_F_SCTP_CRC_BIT, + NETIF_F_HIGHDMA_BIT, + NETIF_F_HW_VLAN_CTAG_TX_BIT, + NETIF_F_HW_VLAN_CTAG_RX_BIT, + NETIF_F_HW_VLAN_STAG_TX_BIT, + NETIF_F_HW_VLAN_STAG_RX_BIT);
static void veth_setup(struct net_device *dev) { + netdev_features_t veth_features; + ether_setup(dev);
dev->priv_flags &= ~IFF_TX_SKB_SHARING; @@ -1637,8 +1646,10 @@ static void veth_setup(struct net_device *dev)
dev->netdev_ops = &veth_netdev_ops; dev->ethtool_ops = &veth_ethtool_ops; + veth_features = NETIF_F_GSO_SOFTWARE | NETIF_F_GSO_ENCAP_ALL; + netdev_features_set_array(&veth_feature_set, &veth_features); dev->features |= NETIF_F_LLTX; - dev->features |= VETH_FEATURES; + dev->features |= veth_features; dev->vlan_features = dev->features & ~(NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_STAG_TX | @@ -1648,8 +1659,8 @@ static void veth_setup(struct net_device *dev) dev->priv_destructor = veth_dev_free; dev->max_mtu = ETH_MAX_MTU;
- dev->hw_features = VETH_FEATURES; - dev->hw_enc_features = VETH_FEATURES; + dev->hw_features = veth_features; + dev->hw_enc_features = veth_features; dev->mpls_features = NETIF_F_HW_CSUM | NETIF_F_GSO_SOFTWARE; netif_set_tso_max_size(dev, GSO_MAX_SIZE); } diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c index 53b3b241e027..b2f3fb5a29d5 100644 --- a/drivers/net/vmxnet3/vmxnet3_drv.c +++ b/drivers/net/vmxnet3/vmxnet3_drv.c @@ -3301,26 +3301,42 @@ vmxnet3_change_mtu(struct net_device *netdev, int new_mtu) return err; }
+static DECLARE_NETDEV_FEATURE_SET(vmxnet3_hw_feature_set, + NETIF_F_SG_BIT, + NETIF_F_RXCSUM_BIT, + NETIF_F_HW_CSUM_BIT, + NETIF_F_HW_VLAN_CTAG_TX_BIT, + NETIF_F_HW_VLAN_CTAG_RX_BIT, + NETIF_F_TSO_BIT, + NETIF_F_TSO6_BIT, + NETIF_F_LRO_BIT, + NETIF_F_HIGHDMA_BIT); +static DECLARE_NETDEV_FEATURE_SET(vmxnet3_hw_enc_feature_set, + NETIF_F_SG_BIT, + NETIF_F_RXCSUM_BIT, + NETIF_F_HW_CSUM_BIT, + NETIF_F_HW_VLAN_CTAG_TX_BIT, + NETIF_F_HW_VLAN_CTAG_RX_BIT, + NETIF_F_TSO_BIT, + NETIF_F_TSO6_BIT, + NETIF_F_LRO_BIT, + NETIF_F_GSO_UDP_TUNNEL_BIT, + NETIF_F_GSO_UDP_TUNNEL_CSUM_BIT);
static void vmxnet3_declare_features(struct vmxnet3_adapter *adapter) { struct net_device *netdev = adapter->netdev;
- netdev->hw_features = NETIF_F_SG | NETIF_F_RXCSUM | - NETIF_F_HW_CSUM | NETIF_F_HW_VLAN_CTAG_TX | - NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_TSO | NETIF_F_TSO6 | - NETIF_F_LRO | NETIF_F_HIGHDMA; + netdev_hw_features_zero(netdev); + netdev_hw_features_set_array(netdev, &vmxnet3_hw_feature_set);
if (VMXNET3_VERSION_GE_4(adapter)) { netdev->hw_features |= NETIF_F_GSO_UDP_TUNNEL | NETIF_F_GSO_UDP_TUNNEL_CSUM; - - netdev->hw_enc_features = NETIF_F_SG | NETIF_F_RXCSUM | - NETIF_F_HW_CSUM | NETIF_F_HW_VLAN_CTAG_TX | - NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_TSO | NETIF_F_TSO6 | - NETIF_F_LRO | NETIF_F_GSO_UDP_TUNNEL | - NETIF_F_GSO_UDP_TUNNEL_CSUM; + netdev_hw_enc_features_zero(netdev); + netdev_hw_enc_features_set_array(netdev, + &vmxnet3_hw_enc_feature_set); }
if (VMXNET3_VERSION_GE_7(adapter)) { diff --git a/drivers/net/vmxnet3/vmxnet3_ethtool.c b/drivers/net/vmxnet3/vmxnet3_ethtool.c index e2034adc3a1a..25b3243a9630 100644 --- a/drivers/net/vmxnet3/vmxnet3_ethtool.c +++ b/drivers/net/vmxnet3/vmxnet3_ethtool.c @@ -298,15 +298,35 @@ netdev_features_t vmxnet3_features_check(struct sk_buff *skb, return features; }
+static DECLARE_NETDEV_FEATURE_SET(vmxnet3_hw_enc_feature_set, + NETIF_F_SG_BIT, + NETIF_F_RXCSUM_BIT, + NETIF_F_HW_CSUM_BIT, + NETIF_F_HW_VLAN_CTAG_TX_BIT, + NETIF_F_HW_VLAN_CTAG_RX_BIT, + NETIF_F_TSO_BIT, + NETIF_F_TSO6_BIT, + NETIF_F_LRO_BIT); + +static DECLARE_NETDEV_FEATURE_SET(vmxnet3_hw_enc_feature_set2, + NETIF_F_SG_BIT, + NETIF_F_RXCSUM_BIT, + NETIF_F_HW_CSUM_BIT, + NETIF_F_HW_VLAN_CTAG_TX_BIT, + NETIF_F_HW_VLAN_CTAG_RX_BIT, + NETIF_F_TSO_BIT, + NETIF_F_TSO6_BIT, + NETIF_F_LRO_BIT, + NETIF_F_GSO_UDP_TUNNEL_BIT, + NETIF_F_GSO_UDP_TUNNEL_CSUM_BIT); + static void vmxnet3_enable_encap_offloads(struct net_device *netdev, netdev_features_t features) { struct vmxnet3_adapter *adapter = netdev_priv(netdev);
if (VMXNET3_VERSION_GE_4(adapter)) { - netdev->hw_enc_features |= NETIF_F_SG | NETIF_F_RXCSUM | - NETIF_F_HW_CSUM | NETIF_F_HW_VLAN_CTAG_TX | - NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_TSO | NETIF_F_TSO6 | - NETIF_F_LRO; + netdev_hw_enc_features_set_array(netdev, + &vmxnet3_hw_enc_feature_set); if (features & NETIF_F_GSO_UDP_TUNNEL) netdev->hw_enc_features |= NETIF_F_GSO_UDP_TUNNEL; if (features & NETIF_F_GSO_UDP_TUNNEL_CSUM) @@ -364,11 +384,8 @@ static void vmxnet3_disable_encap_offloads(struct net_device *netdev) struct vmxnet3_adapter *adapter = netdev_priv(netdev);
if (VMXNET3_VERSION_GE_4(adapter)) { - netdev->hw_enc_features &= ~(NETIF_F_SG | NETIF_F_RXCSUM | - NETIF_F_HW_CSUM | NETIF_F_HW_VLAN_CTAG_TX | - NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_TSO | NETIF_F_TSO6 | - NETIF_F_LRO | NETIF_F_GSO_UDP_TUNNEL | - NETIF_F_GSO_UDP_TUNNEL_CSUM); + netdev_hw_enc_features_clear_array(netdev, + &vmxnet3_hw_enc_feature_set2); } if (VMXNET3_VERSION_GE_7(adapter)) { unsigned long flags; diff --git a/drivers/net/vmxnet3/vmxnet3_int.h b/drivers/net/vmxnet3/vmxnet3_int.h index 3367db23aa13..d42f997efa4a 100644 --- a/drivers/net/vmxnet3/vmxnet3_int.h +++ b/drivers/net/vmxnet3/vmxnet3_int.h @@ -31,6 +31,7 @@ #include <linux/ethtool.h> #include <linux/delay.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/pci.h> #include <linux/compiler.h> #include <linux/slab.h> diff --git a/drivers/net/vrf.c b/drivers/net/vrf.c index 5df7a0abc39d..7ad145f832cc 100644 --- a/drivers/net/vrf.c +++ b/drivers/net/vrf.c @@ -13,6 +13,7 @@ #include <linux/module.h> #include <linux/kernel.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/etherdevice.h> #include <linux/ip.h> #include <linux/init.h> @@ -1664,6 +1665,14 @@ static int vrf_add_fib_rules(const struct net_device *dev) return err; }
+static DECLARE_NETDEV_FEATURE_SET(vrf_offload_feature_set, + NETIF_F_RXCSUM_BIT, + NETIF_F_HW_CSUM_BIT, + NETIF_F_SCTP_CRC_BIT, + NETIF_F_SG_BIT, + NETIF_F_FRAGLIST_BIT, + NETIF_F_HIGHDMA_BIT); + static void vrf_setup(struct net_device *dev) { ether_setup(dev); @@ -1688,8 +1697,7 @@ static void vrf_setup(struct net_device *dev)
/* enable offload features */ dev->features |= NETIF_F_GSO_SOFTWARE; - dev->features |= NETIF_F_RXCSUM | NETIF_F_HW_CSUM | NETIF_F_SCTP_CRC; - dev->features |= NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_HIGHDMA; + netdev_active_features_set_array(dev, &vrf_offload_feature_set);
dev->hw_features = dev->features; dev->hw_enc_features = dev->features; diff --git a/drivers/net/vsockmon.c b/drivers/net/vsockmon.c index b1bb1b04b664..a5cee59ea872 100644 --- a/drivers/net/vsockmon.c +++ b/drivers/net/vsockmon.c @@ -3,6 +3,7 @@ #include <linux/module.h> #include <linux/kernel.h> #include <linux/if_arp.h> +#include <linux/netdev_features_helper.h> #include <net/rtnetlink.h> #include <net/sock.h> #include <net/af_vsock.h> @@ -97,6 +98,12 @@ static const struct ethtool_ops vsockmon_ethtool_ops = { .get_link = always_on, };
+static DECLARE_NETDEV_FEATURE_SET(vsockmon_feature_set, + NETIF_F_SG_BIT, + NETIF_F_FRAGLIST_BIT, + NETIF_F_HIGHDMA_BIT, + NETIF_F_LLTX_BIT); + static void vsockmon_setup(struct net_device *dev) { dev->type = ARPHRD_VSOCKMON; @@ -106,8 +113,8 @@ static void vsockmon_setup(struct net_device *dev) dev->ethtool_ops = &vsockmon_ethtool_ops; dev->needs_free_netdev = true;
- dev->features = NETIF_F_SG | NETIF_F_FRAGLIST | - NETIF_F_HIGHDMA | NETIF_F_LLTX; + netdev_active_features_zero(dev); + netdev_active_features_set_array(dev, &vsockmon_feature_set);
dev->flags = IFF_NOARP;
diff --git a/drivers/net/vxlan/vxlan_core.c b/drivers/net/vxlan/vxlan_core.c index 8b0710b576c2..4892c212ff1a 100644 --- a/drivers/net/vxlan/vxlan_core.c +++ b/drivers/net/vxlan/vxlan_core.c @@ -15,6 +15,7 @@ #include <linux/igmp.h> #include <linux/if_ether.h> #include <linux/ethtool.h> +#include <linux/netdev_features_helper.h> #include <net/arp.h> #include <net/ndisc.h> #include <net/gro.h> @@ -3150,6 +3151,18 @@ static void vxlan_offload_rx_ports(struct net_device *dev, bool push) spin_unlock(&vn->sock_lock); }
+static DECLARE_NETDEV_FEATURE_SET(vxlan_feature_set, + NETIF_F_LLTX_BIT, + NETIF_F_SG_BIT, + NETIF_F_HW_CSUM_BIT, + NETIF_F_FRAGLIST_BIT, + NETIF_F_RXCSUM_BIT); +static DECLARE_NETDEV_FEATURE_SET(vxlan_hw_feature_set, + NETIF_F_SG_BIT, + NETIF_F_HW_CSUM_BIT, + NETIF_F_FRAGLIST_BIT, + NETIF_F_RXCSUM_BIT); + /* Initialize the device structure. */ static void vxlan_setup(struct net_device *dev) { @@ -3162,14 +3175,11 @@ static void vxlan_setup(struct net_device *dev) dev->needs_free_netdev = true; SET_NETDEV_DEVTYPE(dev, &vxlan_type);
- dev->features |= NETIF_F_LLTX; - dev->features |= NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_FRAGLIST; - dev->features |= NETIF_F_RXCSUM; + netdev_active_features_set_array(dev, &vxlan_feature_set); dev->features |= NETIF_F_GSO_SOFTWARE;
dev->vlan_features = dev->features; - dev->hw_features |= NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_FRAGLIST; - dev->hw_features |= NETIF_F_RXCSUM; + netdev_hw_features_set_array(dev, &vxlan_hw_feature_set); dev->hw_features |= NETIF_F_GSO_SOFTWARE; netif_keep_dst(dev); dev->priv_flags |= IFF_NO_QUEUE | IFF_CHANGE_PROTO_DOWN; diff --git a/drivers/net/wireguard/device.c b/drivers/net/wireguard/device.c index aa9a7a5970fd..aeed694110d4 100644 --- a/drivers/net/wireguard/device.c +++ b/drivers/net/wireguard/device.c @@ -15,6 +15,7 @@ #include <linux/rtnetlink.h> #include <linux/inet.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/inetdevice.h> #include <linux/if_arp.h> #include <linux/icmp.h> @@ -271,14 +272,19 @@ static void wg_destruct(struct net_device *dev)
static const struct device_type device_type = { .name = KBUILD_MODNAME };
+static DECLARE_NETDEV_FEATURE_SET(wg_feature_set, + NETIF_F_HW_CSUM_BIT, + NETIF_F_RXCSUM_BIT, + NETIF_F_SG_BIT, + NETIF_F_GSO_BIT, + NETIF_F_HIGHDMA_BIT); + 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 | - NETIF_F_SG | NETIF_F_GSO | - NETIF_F_GSO_SOFTWARE | NETIF_F_HIGHDMA }; const int overhead = MESSAGE_MINIMUM_LENGTH + sizeof(struct udphdr) + max(sizeof(struct ipv6hdr), sizeof(struct iphdr)); + netdev_features_t wg_netdev_features;
dev->netdev_ops = &netdev_ops; dev->header_ops = &ip_tunnel_header_ops; @@ -290,9 +296,11 @@ 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; + wg_netdev_features = NETIF_F_GSO_SOFTWARE; + netdev_features_set_array(&wg_feature_set, &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/drivers/net/wireless/ath/wil6210/netdev.c b/drivers/net/wireless/ath/wil6210/netdev.c index 87a88f26233e..c2012c4e0084 100644 --- a/drivers/net/wireless/ath/wil6210/netdev.c +++ b/drivers/net/wireless/ath/wil6210/netdev.c @@ -5,6 +5,7 @@ */
#include <linux/etherdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/rtnetlink.h> #include "wil6210.h" #include "txrx.h" @@ -294,6 +295,14 @@ static u8 wil_vif_find_free_mid(struct wil6210_priv *wil) return U8_MAX; }
+static DECLARE_NETDEV_FEATURE_SET(wil_hw_feature_set, + NETIF_F_HW_CSUM_BIT, + NETIF_F_RXCSUM_BIT, + NETIF_F_SG_BIT, + NETIF_F_GRO_BIT, + NETIF_F_TSO_BIT, + NETIF_F_TSO6_BIT); + struct wil6210_vif * wil_vif_alloc(struct wil6210_priv *wil, const char *name, unsigned char name_assign_type, enum nl80211_iftype iftype) @@ -335,9 +344,8 @@ wil_vif_alloc(struct wil6210_priv *wil, const char *name, ndev->netdev_ops = &wil_netdev_ops; wil_set_ethtoolops(ndev); ndev->ieee80211_ptr = wdev; - ndev->hw_features = NETIF_F_HW_CSUM | NETIF_F_RXCSUM | - NETIF_F_SG | NETIF_F_GRO | - NETIF_F_TSO | NETIF_F_TSO6; + netdev_hw_features_zero(ndev); + netdev_hw_features_set_array(ndev, &wil_hw_feature_set);
ndev->features |= ndev->hw_features; SET_NETDEV_DEV(ndev, wiphy_dev(wdev->wiphy)); diff --git a/drivers/net/xen-netback/interface.c b/drivers/net/xen-netback/interface.c index fb32ae82d9b0..989328168e1c 100644 --- a/drivers/net/xen-netback/interface.c +++ b/drivers/net/xen-netback/interface.c @@ -33,6 +33,7 @@ #include <linux/kthread.h> #include <linux/sched/task.h> #include <linux/ethtool.h> +#include <linux/netdev_features_helper.h> #include <linux/rtnetlink.h> #include <linux/if_vlan.h> #include <linux/vmalloc.h> @@ -476,6 +477,14 @@ static const struct net_device_ops xenvif_netdev_ops = { .ndo_validate_addr = eth_validate_addr, };
+static DECLARE_NETDEV_FEATURE_SET(xenvif_hw_feature_set, + NETIF_F_SG_BIT, + NETIF_F_IP_CSUM_BIT, + NETIF_F_IPV6_CSUM_BIT, + NETIF_F_TSO_BIT, + NETIF_F_TSO6_BIT, + NETIF_F_FRAGLIST_BIT); + struct xenvif *xenvif_alloc(struct device *parent, domid_t domid, unsigned int handle) { @@ -522,9 +531,8 @@ struct xenvif *xenvif_alloc(struct device *parent, domid_t domid, INIT_LIST_HEAD(&vif->fe_mcast_addr);
dev->netdev_ops = &xenvif_netdev_ops; - dev->hw_features = NETIF_F_SG | - NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | - NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_FRAGLIST; + netdev_hw_features_zero(dev); + netdev_hw_features_set_array(dev, &xenvif_hw_feature_set); dev->features = dev->hw_features | NETIF_F_RXCSUM; dev->ethtool_ops = &xenvif_ethtool_ops;
diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c index 27a11cc08c61..d4833794cec0 100644 --- a/drivers/net/xen-netfront.c +++ b/drivers/net/xen-netfront.c @@ -34,6 +34,7 @@ #include <linux/module.h> #include <linux/kernel.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/etherdevice.h> #include <linux/skbuff.h> #include <linux/ethtool.h> @@ -1703,6 +1704,16 @@ static void xennet_free_netdev(struct net_device *netdev) free_netdev(netdev); }
+static DECLARE_NETDEV_FEATURE_SET(xennet_feature_set, + NETIF_F_IP_CSUM_BIT, + NETIF_F_RXCSUM_BIT, + NETIF_F_GSO_ROBUST_BIT); +static DECLARE_NETDEV_FEATURE_SET(xennet_hw_feature_set, + NETIF_F_SG_BIT, + NETIF_F_IPV6_CSUM_BIT, + NETIF_F_TSO_BIT, + NETIF_F_TSO6_BIT); + static struct net_device *xennet_create_dev(struct xenbus_device *dev) { int err; @@ -1728,11 +1739,10 @@ static struct net_device *xennet_create_dev(struct xenbus_device *dev)
netdev->netdev_ops = &xennet_netdev_ops;
- netdev->features = NETIF_F_IP_CSUM | NETIF_F_RXCSUM | - NETIF_F_GSO_ROBUST; - netdev->hw_features = NETIF_F_SG | - NETIF_F_IPV6_CSUM | - NETIF_F_TSO | NETIF_F_TSO6; + netdev_active_features_zero(netdev); + netdev_active_features_set_array(netdev, &xennet_feature_set); + netdev_hw_features_zero(netdev); + netdev_hw_features_set_array(netdev, &xennet_hw_feature_set);
/* * Assume that all hw features are available for now. This set diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c index 8d44bce0477a..8628599ed692 100644 --- a/drivers/s390/net/qeth_l3_main.c +++ b/drivers/s390/net/qeth_l3_main.c @@ -1854,6 +1854,11 @@ static const struct net_device_ops qeth_l3_osa_netdev_ops = { .ndo_neigh_setup = qeth_l3_neigh_setup, };
+static DECLARE_NETDEV_FEATURE_SET(qeth_l3_feature_set, + NETIF_F_TSO_BIT, + NETIF_F_RXCSUM_BIT, + NETIF_F_IP_CSUM_BIT); + static int qeth_l3_setup_netdev(struct qeth_card *card) { struct net_device *dev = card->dev; @@ -1868,10 +1873,10 @@ static int qeth_l3_setup_netdev(struct qeth_card *card)
if (!IS_VM_NIC(card)) { card->dev->features |= NETIF_F_SG; - card->dev->hw_features |= NETIF_F_TSO | - NETIF_F_RXCSUM | NETIF_F_IP_CSUM; - card->dev->vlan_features |= NETIF_F_TSO | - NETIF_F_RXCSUM | NETIF_F_IP_CSUM; + netdev_hw_features_set_array(card->dev, + &qeth_l3_feature_set); + netdev_vlan_features_set_array(card->dev, + &qeth_l3_feature_set); }
if (qeth_is_supported6(card, IPA_OUTBOUND_CHECKSUM_V6)) { diff --git a/drivers/staging/qlge/qlge_main.c b/drivers/staging/qlge/qlge_main.c index 6cd7fc9589c3..a3576a11443d 100644 --- a/drivers/staging/qlge/qlge_main.c +++ b/drivers/staging/qlge/qlge_main.c @@ -31,6 +31,7 @@ #include <linux/if_arp.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/if_vlan.h> @@ -4533,6 +4534,16 @@ static void qlge_timer(struct timer_list *t)
static const struct devlink_ops qlge_devlink_ops;
+static DECLARE_NETDEV_FEATURE_SET(qlge_hw_feature_set, + NETIF_F_SG_BIT, + NETIF_F_IP_CSUM_BIT, + NETIF_F_TSO_BIT, + NETIF_F_TSO_ECN_BIT, + NETIF_F_HW_VLAN_CTAG_TX_BIT, + NETIF_F_HW_VLAN_CTAG_RX_BIT, + NETIF_F_HW_VLAN_CTAG_FILTER_BIT, + NETIF_F_RXCSUM_BIT); + static int qlge_probe(struct pci_dev *pdev, const struct pci_device_id *pci_entry) { @@ -4567,14 +4578,8 @@ static int qlge_probe(struct pci_dev *pdev, goto netdev_free;
SET_NETDEV_DEV(ndev, &pdev->dev); - ndev->hw_features = NETIF_F_SG | - NETIF_F_IP_CSUM | - NETIF_F_TSO | - NETIF_F_TSO_ECN | - NETIF_F_HW_VLAN_CTAG_TX | - NETIF_F_HW_VLAN_CTAG_RX | - NETIF_F_HW_VLAN_CTAG_FILTER | - NETIF_F_RXCSUM; + netdev_hw_features_zero(ndev); + netdev_hw_features_set_array(ndev, &qlge_hw_feature_set); ndev->features = ndev->hw_features; ndev->vlan_features = ndev->hw_features; /* vlan gets same features (except vlan filter) */ diff --git a/include/net/bonding.h b/include/net/bonding.h index 6e78d657aa05..cfad04d40bf2 100644 --- a/include/net/bonding.h +++ b/include/net/bonding.h @@ -89,10 +89,9 @@ #define bond_for_each_slave_rcu(bond, pos, iter) \ netdev_for_each_lower_private_rcu((bond)->dev, pos, iter)
-#define BOND_XFRM_FEATURES (NETIF_F_HW_ESP | NETIF_F_HW_ESP_TX_CSUM | \ - NETIF_F_GSO_ESP) +#define BOND_XFRM_FEATURES netdev_xfrm_features
-#define BOND_TLS_FEATURES (NETIF_F_HW_TLS_TX | NETIF_F_HW_TLS_RX) +#define BOND_TLS_FEATURES netdev_tls_features
#ifdef CONFIG_NET_POLL_CONTROLLER extern atomic_t netpoll_block_tx; diff --git a/include/net/net_failover.h b/include/net/net_failover.h index b12a1c469d1c..781d1de8a190 100644 --- a/include/net/net_failover.h +++ b/include/net/net_failover.h @@ -30,11 +30,7 @@ struct net_failover_info { struct failover *net_failover_create(struct net_device *standby_dev); void net_failover_destroy(struct failover *failover);
-#define FAILOVER_VLAN_FEATURES (NETIF_F_HW_CSUM | NETIF_F_SG | \ - NETIF_F_FRAGLIST | NETIF_F_ALL_TSO | \ - NETIF_F_HIGHDMA | NETIF_F_LRO) - -#define FAILOVER_ENC_FEATURES (NETIF_F_HW_CSUM | NETIF_F_SG | \ - NETIF_F_RXCSUM | NETIF_F_ALL_TSO) +#define FAILOVER_VLAN_FEATURES failover_vlan_features +#define FAILOVER_ENC_FEATURES failover_enc_features
#endif /* _NET_FAILOVER_H */ diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c index 64ca07daf4ee..75d12ff0d146 100644 --- a/net/8021q/vlan_dev.c +++ b/net/8021q/vlan_dev.c @@ -550,6 +550,13 @@ static struct device_type vlan_type = {
static const struct net_device_ops vlan_netdev_ops;
+static DECLARE_NETDEV_FEATURE_SET(vlan_hw_feature_set, + NETIF_F_HW_CSUM_BIT, + NETIF_F_SG_BIT, + NETIF_F_FRAGLIST_BIT, + NETIF_F_HIGHDMA_BIT, + NETIF_F_SCTP_CRC_BIT); + static int vlan_dev_init(struct net_device *dev) { struct vlan_dev_priv *vlan = vlan_dev_priv(dev); @@ -567,11 +574,9 @@ static int vlan_dev_init(struct net_device *dev) if (vlan->flags & VLAN_FLAG_BRIDGE_BINDING) dev->state |= (1 << __LINK_STATE_NOCARRIER);
- dev->hw_features = NETIF_F_HW_CSUM | NETIF_F_SG | - NETIF_F_FRAGLIST | NETIF_F_GSO_SOFTWARE | - NETIF_F_GSO_ENCAP_ALL | - NETIF_F_HIGHDMA | NETIF_F_SCTP_CRC | - NETIF_F_ALL_FCOE; + dev->hw_features = NETIF_F_GSO_SOFTWARE | NETIF_F_GSO_ENCAP_ALL; + dev->hw_features |= NETIF_F_ALL_FCOE; + netdev_hw_features_set_array(dev, &vlan_hw_feature_set);
dev->features |= dev->hw_features | NETIF_F_LLTX; netif_inherit_tso_max(dev, real_dev); diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c index 0f5c0679b55a..1a958b279489 100644 --- a/net/batman-adv/soft-interface.c +++ b/net/batman-adv/soft-interface.c @@ -24,6 +24,7 @@ #include <linux/list.h> #include <linux/lockdep.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/netlink.h> #include <linux/percpu.h> #include <linux/random.h> @@ -992,6 +993,11 @@ static void batadv_softif_free(struct net_device *dev) rcu_barrier(); }
+static DECLARE_NETDEV_FEATURE_SET(batadv_feature_set, + NETIF_F_HW_VLAN_CTAG_FILTER_BIT, + NETIF_F_NETNS_LOCAL_BIT, + NETIF_F_LLTX_BIT); + /** * batadv_softif_init_early() - early stage initialization of soft interface * @dev: registered network device to modify @@ -1003,8 +1009,7 @@ static void batadv_softif_init_early(struct net_device *dev) dev->netdev_ops = &batadv_netdev_ops; dev->needs_free_netdev = true; dev->priv_destructor = batadv_softif_free; - dev->features |= NETIF_F_HW_VLAN_CTAG_FILTER | NETIF_F_NETNS_LOCAL; - dev->features |= NETIF_F_LLTX; + netdev_active_features_set_array(dev, &batadv_feature_set); dev->priv_flags |= IFF_NO_QUEUE;
/* can't call min_mtu, because the needed variables diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c index 58a4f70e01e3..8f78e6d297b8 100644 --- a/net/bridge/br_device.c +++ b/net/bridge/br_device.c @@ -9,6 +9,7 @@
#include <linux/kernel.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/netpoll.h> #include <linux/etherdevice.h> #include <linux/ethtool.h> @@ -18,8 +19,11 @@ #include <linux/uaccess.h> #include "br_private.h"
-#define COMMON_FEATURES (NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_HIGHDMA | \ - NETIF_F_GSO_MASK | NETIF_F_HW_CSUM) +static DECLARE_NETDEV_FEATURE_SET(br_common_feature_set, + NETIF_F_SG_BIT, + NETIF_F_FRAGLIST_BIT, + NETIF_F_HIGHDMA_BIT, + NETIF_F_HW_CSUM_BIT);
const struct nf_br_ops __rcu *nf_br_ops __read_mostly; EXPORT_SYMBOL_GPL(nf_br_ops); @@ -479,9 +483,16 @@ static struct device_type br_type = { .name = "bridge", };
+static DECLARE_NETDEV_FEATURE_SET(br_feature_set, + NETIF_F_LLTX_BIT, + NETIF_F_NETNS_LOCAL_BIT, + NETIF_F_HW_VLAN_CTAG_TX_BIT, + NETIF_F_HW_VLAN_STAG_TX_BIT); + void br_dev_setup(struct net_device *dev) { struct net_bridge *br = netdev_priv(dev); + netdev_features_t common_features;
eth_hw_addr_random(dev); ether_setup(dev); @@ -492,11 +503,13 @@ void br_dev_setup(struct net_device *dev) SET_NETDEV_DEVTYPE(dev, &br_type); dev->priv_flags = IFF_EBRIDGE | IFF_NO_QUEUE;
- dev->features = COMMON_FEATURES | NETIF_F_LLTX | NETIF_F_NETNS_LOCAL | - NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_STAG_TX; - dev->hw_features = COMMON_FEATURES | NETIF_F_HW_VLAN_CTAG_TX | + common_features = NETIF_F_GSO_MASK; + netdev_features_set_array(&br_common_feature_set, &common_features); + dev->features = common_features; + netdev_active_features_set_array(dev, &br_feature_set); + dev->hw_features = common_features | NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_STAG_TX; - dev->vlan_features = COMMON_FEATURES; + dev->vlan_features = common_features;
br->dev = dev; spin_lock_init(&br->lock); diff --git a/net/ethtool/ioctl.c b/net/ethtool/ioctl.c index 6a7308de192d..2ed9277a873e 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) + +static 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(ð_all_features); + netdev_features_set_array(ðtool_all_feature_set, ð_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;
diff --git a/net/hsr/hsr_device.c b/net/hsr/hsr_device.c index 6ffef47e9be5..ab1c4dfa25b7 100644 --- a/net/hsr/hsr_device.c +++ b/net/hsr/hsr_device.c @@ -8,6 +8,7 @@ */
#include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/skbuff.h> #include <linux/etherdevice.h> #include <linux/rtnetlink.h> @@ -435,6 +436,13 @@ static struct hsr_proto_ops prp_ops = { .update_san_info = prp_update_san_info, };
+static DECLARE_NETDEV_FEATURE_SET(hsr_hw_feature_set, + NETIF_F_SG_BIT, + NETIF_F_FRAGLIST_BIT, + NETIF_F_HIGHDMA_BIT, + NETIF_F_HW_CSUM_BIT, + NETIF_F_HW_VLAN_CTAG_TX_BIT); + void hsr_dev_setup(struct net_device *dev) { eth_hw_addr_random(dev); @@ -448,9 +456,8 @@ void hsr_dev_setup(struct net_device *dev)
dev->needs_free_netdev = true;
- dev->hw_features = NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_HIGHDMA | - NETIF_F_GSO_MASK | NETIF_F_HW_CSUM | - NETIF_F_HW_VLAN_CTAG_TX; + dev->hw_features = NETIF_F_GSO_MASK; + netdev_hw_features_set_array(dev, &hsr_hw_feature_set);
dev->features = dev->hw_features;
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index 5c58e21f724e..fbdf3713245f 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c @@ -15,6 +15,7 @@ #include <linux/uaccess.h> #include <linux/skbuff.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/in.h> #include <linux/tcp.h> #include <linux/udp.h> @@ -935,10 +936,11 @@ static const struct net_device_ops ipgre_netdev_ops = { .ndo_tunnel_ctl = ipgre_tunnel_ctl, };
-#define GRE_FEATURES (NETIF_F_SG | \ - NETIF_F_FRAGLIST | \ - NETIF_F_HIGHDMA | \ - NETIF_F_HW_CSUM) +static DECLARE_NETDEV_FEATURE_SET(gre_feature_set, + NETIF_F_SG_BIT, + NETIF_F_FRAGLIST_BIT, + NETIF_F_HIGHDMA_BIT, + NETIF_F_HW_CSUM_BIT);
static void ipgre_tunnel_setup(struct net_device *dev) { @@ -959,8 +961,9 @@ static void __gre_tunnel_init(struct net_device *dev) tunnel->hlen = tunnel->tun_hlen + tunnel->encap_hlen; dev->needed_headroom = tunnel->hlen + sizeof(tunnel->parms.iph);
- dev->features |= GRE_FEATURES | NETIF_F_LLTX; - dev->hw_features |= GRE_FEATURES; + netdev_active_features_set_array(dev, &gre_feature_set); + netdev_active_feature_add(dev, NETIF_F_LLTX_BIT); + netdev_hw_features_set_array(dev, &gre_feature_set);
flags = tunnel->parms.o_flags;
@@ -1300,8 +1303,8 @@ static int erspan_tunnel_init(struct net_device *dev) tunnel->hlen = tunnel->tun_hlen + tunnel->encap_hlen + erspan_hdr_len(tunnel->erspan_ver);
- dev->features |= GRE_FEATURES; - dev->hw_features |= GRE_FEATURES; + netdev_active_features_set_array(dev, &gre_feature_set); + netdev_hw_features_set_array(dev, &gre_feature_set); dev->priv_flags |= IFF_LIVE_ADDR_CHANGE; netif_keep_dst(dev);
diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c index 123ea63a04cb..66b2deb4ddff 100644 --- a/net/ipv4/ipip.c +++ b/net/ipv4/ipip.c @@ -94,6 +94,7 @@ #include <linux/uaccess.h> #include <linux/skbuff.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/in.h> #include <linux/tcp.h> #include <linux/udp.h> @@ -354,14 +355,16 @@ static const struct net_device_ops ipip_netdev_ops = { .ndo_tunnel_ctl = ipip_tunnel_ctl, };
-#define IPIP_FEATURES (NETIF_F_SG | \ - NETIF_F_FRAGLIST | \ - NETIF_F_HIGHDMA | \ - NETIF_F_GSO_SOFTWARE | \ - NETIF_F_HW_CSUM) +static DECLARE_NETDEV_FEATURE_SET(ipip_feature_set, + NETIF_F_SG_BIT, + NETIF_F_FRAGLIST_BIT, + NETIF_F_HIGHDMA_BIT, + NETIF_F_HW_CSUM_BIT);
static void ipip_tunnel_setup(struct net_device *dev) { + netdev_features_t ipip_features; + dev->netdev_ops = &ipip_netdev_ops; dev->header_ops = &ip_tunnel_header_ops;
@@ -371,8 +374,10 @@ static void ipip_tunnel_setup(struct net_device *dev) dev->features |= NETIF_F_LLTX; netif_keep_dst(dev);
- dev->features |= IPIP_FEATURES; - dev->hw_features |= IPIP_FEATURES; + ipip_features = NETIF_F_GSO_SOFTWARE; + netdev_features_set_array(&ipip_feature_set, &ipip_features); + dev->features |= ipip_features; + dev->hw_features |= ipip_features; ip_tunnel_setup(dev, ipip_net_id); }
diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c index 80cb50d459e4..b91a001077af 100644 --- a/net/ipv6/ip6_gre.c +++ b/net/ipv6/ip6_gre.c @@ -15,6 +15,7 @@ #include <linux/uaccess.h> #include <linux/skbuff.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/in.h> #include <linux/tcp.h> #include <linux/udp.h> @@ -1464,18 +1465,20 @@ static void ip6gre_tunnel_setup(struct net_device *dev) eth_random_addr(dev->perm_addr); }
-#define GRE6_FEATURES (NETIF_F_SG | \ - NETIF_F_FRAGLIST | \ - NETIF_F_HIGHDMA | \ - NETIF_F_HW_CSUM) +static DECLARE_NETDEV_FEATURE_SET(gre_feature_set, + NETIF_F_SG_BIT, + NETIF_F_FRAGLIST_BIT, + NETIF_F_HIGHDMA_BIT, + NETIF_F_HW_CSUM_BIT);
static void ip6gre_tnl_init_features(struct net_device *dev) { struct ip6_tnl *nt = netdev_priv(dev); __be16 flags;
- dev->features |= GRE6_FEATURES | NETIF_F_LLTX; - dev->hw_features |= GRE6_FEATURES; + netdev_active_features_set_array(dev, &gre_feature_set); + netdev_active_feature_add(dev, NETIF_F_LLTX_BIT); + netdev_hw_features_set_array(dev, &gre_feature_set);
flags = nt->parms.o_flags;
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c index 3fda5634578c..da8eccfd1849 100644 --- a/net/ipv6/ip6_tunnel.c +++ b/net/ipv6/ip6_tunnel.c @@ -27,6 +27,7 @@ #include <linux/net.h> #include <linux/in6.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/if_arp.h> #include <linux/icmpv6.h> #include <linux/init.h> @@ -1813,11 +1814,11 @@ static const struct net_device_ops ip6_tnl_netdev_ops = { .ndo_get_iflink = ip6_tnl_get_iflink, };
-#define IPXIPX_FEATURES (NETIF_F_SG | \ - NETIF_F_FRAGLIST | \ - NETIF_F_HIGHDMA | \ - NETIF_F_GSO_SOFTWARE | \ - NETIF_F_HW_CSUM) +static DECLARE_NETDEV_FEATURE_SET(ipxipx_feature_set, + NETIF_F_SG_BIT, + NETIF_F_FRAGLIST_BIT, + NETIF_F_HIGHDMA_BIT, + NETIF_F_HW_CSUM_BIT);
/** * ip6_tnl_dev_setup - setup virtual tunnel device @@ -1829,6 +1830,8 @@ static const struct net_device_ops ip6_tnl_netdev_ops = {
static void ip6_tnl_dev_setup(struct net_device *dev) { + netdev_features_t ipxipx_features; + dev->netdev_ops = &ip6_tnl_netdev_ops; dev->header_ops = &ip_tunnel_header_ops; dev->needs_free_netdev = true; @@ -1840,8 +1843,10 @@ static void ip6_tnl_dev_setup(struct net_device *dev) dev->features |= NETIF_F_LLTX; netif_keep_dst(dev);
- dev->features |= IPXIPX_FEATURES; - dev->hw_features |= IPXIPX_FEATURES; + ipxipx_features = NETIF_F_GSO_SOFTWARE; + netdev_features_set_array(&ipxipx_feature_set, &ipxipx_features); + dev->features |= ipxipx_features; + dev->hw_features |= ipxipx_features;
/* This perm addr will be used as interface identifier by IPv6 */ dev->addr_assign_type = NET_ADDR_RANDOM; diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c index 6b73b7a5f175..9e4c02fd379c 100644 --- a/net/ipv6/sit.c +++ b/net/ipv6/sit.c @@ -24,6 +24,7 @@ #include <linux/net.h> #include <linux/in6.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/if_arp.h> #include <linux/icmp.h> #include <linux/slab.h> @@ -1407,16 +1408,17 @@ static void ipip6_dev_free(struct net_device *dev) free_percpu(dev->tstats); }
-#define SIT_FEATURES (NETIF_F_SG | \ - NETIF_F_FRAGLIST | \ - NETIF_F_HIGHDMA | \ - NETIF_F_GSO_SOFTWARE | \ - NETIF_F_HW_CSUM) +static DECLARE_NETDEV_FEATURE_SET(sit_feature_set, + NETIF_F_SG_BIT, + NETIF_F_FRAGLIST_BIT, + NETIF_F_HIGHDMA_BIT, + NETIF_F_HW_CSUM_BIT);
static void ipip6_tunnel_setup(struct net_device *dev) { struct ip_tunnel *tunnel = netdev_priv(dev); int t_hlen = tunnel->hlen + sizeof(struct iphdr); + netdev_features_t sit_features;
dev->netdev_ops = &ipip6_netdev_ops; dev->header_ops = &ip_tunnel_header_ops; @@ -1430,9 +1432,11 @@ static void ipip6_tunnel_setup(struct net_device *dev) dev->flags = IFF_NOARP; netif_keep_dst(dev); dev->addr_len = 4; + sit_features = NETIF_F_GSO_SOFTWARE; + netdev_features_set_array(&sit_feature_set, &sit_features); dev->features |= NETIF_F_LLTX; - dev->features |= SIT_FEATURES; - dev->hw_features |= SIT_FEATURES; + dev->features |= sit_features; + dev->hw_features |= sit_features; }
static int ipip6_tunnel_init(struct net_device *dev) diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index e192e1ec0261..c40217911ff4 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -17,6 +17,7 @@ #include <linux/interrupt.h> #include <linux/list.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/skbuff.h> #include <linux/workqueue.h> #include <linux/types.h> @@ -1902,13 +1903,13 @@ int ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev, /* color change handling */ void ieee80211_color_change_finalize_work(struct work_struct *work);
+extern netdev_features_t mac80211_tx_features __ro_after_init; +extern netdev_features_t mac80211_rx_features __ro_after_init; +extern netdev_features_t mac80211_supported_features __ro_after_init; /* interface handling */ -#define MAC80211_SUPPORTED_FEATURES_TX (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | \ - NETIF_F_HW_CSUM | NETIF_F_SG | \ - NETIF_F_HIGHDMA | NETIF_F_GSO_SOFTWARE) -#define MAC80211_SUPPORTED_FEATURES_RX (NETIF_F_RXCSUM) -#define MAC80211_SUPPORTED_FEATURES (MAC80211_SUPPORTED_FEATURES_TX | \ - MAC80211_SUPPORTED_FEATURES_RX) +#define MAC80211_SUPPORTED_FEATURES_TX mac80211_rx_features +#define MAC80211_SUPPORTED_FEATURES_RX mac80211_rx_features +#define MAC80211_SUPPORTED_FEATURES mac80211_supported_features
int ieee80211_iface_init(void); void ieee80211_iface_exit(void); diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 5b1c47ed0cc0..00d8f3bce563 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c @@ -33,6 +33,18 @@ #include "led.h" #include "debugfs.h"
+static DECLARE_NETDEV_FEATURE_SET(mac80211_tx_feature_set, + NETIF_F_IP_CSUM_BIT, + NETIF_F_IPV6_CSUM_BIT, + NETIF_F_HW_CSUM_BIT, + NETIF_F_SG_BIT, + NETIF_F_HIGHDMA_BIT); +static DECLARE_NETDEV_FEATURE_SET(mac80211_rx_feature_set, + NETIF_F_RXCSUM_BIT); +netdev_features_t mac80211_tx_features __ro_after_init; +netdev_features_t mac80211_rx_features __ro_after_init; +netdev_features_t mac80211_supported_features __ro_after_init; + void ieee80211_configure_filter(struct ieee80211_local *local) { u64 mc; @@ -1527,6 +1539,16 @@ void ieee80211_free_hw(struct ieee80211_hw *hw) } EXPORT_SYMBOL(ieee80211_free_hw);
+static void __init ieee80211_features_init(void) +{ + mac80211_tx_features = NETIF_F_GSO_SOFTWARE; + netdev_features_set_array(&mac80211_tx_feature_set, + &mac80211_tx_features); + netdev_features_set_array(&mac80211_rx_feature_set, + &mac80211_rx_features); + mac80211_supported_features = mac80211_tx_features | mac80211_rx_features; +} + static int __init ieee80211_init(void) { struct sk_buff *skb; @@ -1544,6 +1566,8 @@ static int __init ieee80211_init(void) if (ret) goto err_netdev;
+ ieee80211_features_init(); + return 0; err_netdev: rc80211_minstrel_exit(); diff --git a/net/openvswitch/vport-internal_dev.c b/net/openvswitch/vport-internal_dev.c index 5b2ee9c1c00b..1e401624908b 100644 --- a/net/openvswitch/vport-internal_dev.c +++ b/net/openvswitch/vport-internal_dev.c @@ -6,6 +6,7 @@ #include <linux/if_vlan.h> #include <linux/kernel.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/etherdevice.h> #include <linux/ethtool.h> #include <linux/skbuff.h> @@ -92,6 +93,13 @@ static struct rtnl_link_ops internal_dev_link_ops __read_mostly = { .kind = "openvswitch", };
+static DECLARE_NETDEV_FEATURE_SET(ovs_feature_set, + NETIF_F_LLTX_BIT, + NETIF_F_SG_BIT, + NETIF_F_FRAGLIST_BIT, + NETIF_F_HIGHDMA_BIT, + NETIF_F_HW_CSUM_BIT); + static void do_setup(struct net_device *netdev) { ether_setup(netdev); @@ -108,9 +116,8 @@ static void do_setup(struct net_device *netdev) netdev->ethtool_ops = &internal_dev_ethtool_ops; netdev->rtnl_link_ops = &internal_dev_link_ops;
- netdev->features = NETIF_F_LLTX | NETIF_F_SG | NETIF_F_FRAGLIST | - NETIF_F_HIGHDMA | NETIF_F_HW_CSUM | - NETIF_F_GSO_SOFTWARE | NETIF_F_GSO_ENCAP_ALL; + netdev->features = NETIF_F_GSO_SOFTWARE | NETIF_F_GSO_ENCAP_ALL; + netdev_active_features_set_array(netdev, &ovs_feature_set);
netdev->vlan_features = netdev->features; netdev->hw_enc_features = netdev->features; diff --git a/net/xfrm/xfrm_interface.c b/net/xfrm/xfrm_interface.c index 5113fa0fbcee..d80bff81b346 100644 --- a/net/xfrm/xfrm_interface.c +++ b/net/xfrm/xfrm_interface.c @@ -20,6 +20,7 @@ #include <linux/net.h> #include <linux/in6.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/if_link.h> #include <linux/if_arp.h> #include <linux/icmpv6.h> @@ -572,15 +573,16 @@ static void xfrmi_dev_setup(struct net_device *dev) eth_broadcast_addr(dev->broadcast); }
-#define XFRMI_FEATURES (NETIF_F_SG | \ - NETIF_F_FRAGLIST | \ - NETIF_F_GSO_SOFTWARE | \ - NETIF_F_HW_CSUM) +static DECLARE_NETDEV_FEATURE_SET(xfrmi_feature_set, + NETIF_F_SG_BIT, + NETIF_F_FRAGLIST_BIT, + NETIF_F_HW_CSUM_BIT);
static int xfrmi_dev_init(struct net_device *dev) { struct xfrm_if *xi = netdev_priv(dev); struct net_device *phydev = __dev_get_by_index(xi->net, xi->p.link); + netdev_features_t xfrmi_features; int err;
dev->tstats = netdev_alloc_pcpu_stats(struct pcpu_sw_netstats); @@ -593,9 +595,11 @@ static int xfrmi_dev_init(struct net_device *dev) return err; }
+ xfrmi_features = NETIF_F_GSO_SOFTWARE; + netdev_features_set_array(&xfrmi_feature_set, &xfrmi_features); dev->features |= NETIF_F_LLTX; - dev->features |= XFRMI_FEATURES; - dev->hw_features |= XFRMI_FEATURES; + dev->features |= xfrmi_features; + dev->hw_features |= xfrmi_features;
if (phydev) { dev->needed_headroom = phydev->needed_headroom;
On 2022/7/30 18:17, Jian Shen wrote:
There are many netdev_features bits group used in drivers, replace them with DECLARE_NETDEV_FEATURE_SET, prepare to remove all the NETIF_F_XXX macroes.
Signed-off-by: Jian Shen shenjian15@huawei.com
arch/um/drivers/vector_transports.c | 49 +++++-- drivers/infiniband/ulp/ipoib/ipoib.h | 1 + drivers/infiniband/ulp/ipoib/ipoib_main.c | 8 +- drivers/net/amt.c | 16 ++- drivers/net/bareudp.c | 21 ++- drivers/net/bonding/bond_main.c | 48 +++++-- drivers/net/dsa/xrs700x/xrs700x.c | 15 +- drivers/net/dummy.c | 11 +- drivers/net/ethernet/3com/typhoon.c | 18 ++- drivers/net/ethernet/aeroflex/greth.c | 9 +- drivers/net/ethernet/alteon/acenic.c | 10 +- drivers/net/ethernet/amazon/ena/ena_netdev.c | 13 +- drivers/net/ethernet/amd/xgbe/xgbe-main.c | 59 ++++---- .../net/ethernet/apm/xgene/xgene_enet_main.c | 12 +- .../net/ethernet/aquantia/atlantic/aq_nic.c | 14 +- drivers/net/ethernet/asix/ax88796c_main.c | 21 ++- drivers/net/ethernet/atheros/alx/main.c | 15 +- drivers/net/ethernet/atheros/atl1c/atl1c.h | 1 + .../net/ethernet/atheros/atl1c/atl1c_main.c | 14 +- drivers/net/ethernet/atheros/atl1e/atl1e.h | 1 + .../net/ethernet/atheros/atl1e/atl1e_main.c | 10 +- drivers/net/ethernet/atheros/atlx/atl1.c | 22 ++- drivers/net/ethernet/broadcom/bcmsysport.c | 24 +++- drivers/net/ethernet/broadcom/bgmac.c | 9 +- drivers/net/ethernet/broadcom/bnx2.c | 14 +- .../net/ethernet/broadcom/bnx2x/bnx2x_main.c | 83 ++++++++--- drivers/net/ethernet/broadcom/bnxt/bnxt.c | 54 +++++-- .../net/ethernet/broadcom/genet/bcmgenet.c | 10 +- drivers/net/ethernet/brocade/bna/bnad.c | 39 +++-- drivers/net/ethernet/calxeda/xgmac.c | 15 +- .../net/ethernet/cavium/liquidio/lio_main.c | 42 ++++-- .../ethernet/cavium/liquidio/lio_vf_main.c | 40 ++++-- .../ethernet/cavium/liquidio/octeon_network.h | 4 +- .../net/ethernet/cavium/thunder/nicvf_main.c | 27 +++- drivers/net/ethernet/chelsio/cxgb/cxgb2.c | 19 ++- .../net/ethernet/chelsio/cxgb3/cxgb3_main.c | 29 +++- .../net/ethernet/chelsio/cxgb4/cxgb4_main.c | 68 ++++++--- .../ethernet/chelsio/cxgb4vf/cxgb4vf_main.c | 39 ++++- drivers/net/ethernet/cirrus/ep93xx_eth.c | 7 +- drivers/net/ethernet/cisco/enic/enic_main.c | 19 ++- drivers/net/ethernet/cortina/gemini.c | 22 ++- drivers/net/ethernet/emulex/benet/be_main.c | 47 ++++-- drivers/net/ethernet/faraday/ftgmac100.c | 13 +- .../net/ethernet/freescale/dpaa/dpaa_eth.c | 14 +- .../net/ethernet/freescale/dpaa2/dpaa2-eth.c | 17 ++- .../ethernet/freescale/dpaa2/dpaa2-switch.c | 10 +- .../ethernet/freescale/dpaa2/dpaa2-switch.h | 1 + .../net/ethernet/freescale/enetc/enetc_pf.c | 42 ++++-- .../net/ethernet/freescale/enetc/enetc_vf.c | 40 ++++-- drivers/net/ethernet/freescale/fec_main.c | 11 +- drivers/net/ethernet/freescale/gianfar.c | 18 ++- .../ethernet/fungible/funeth/funeth_main.c | 48 +++++-- drivers/net/ethernet/google/gve/gve_main.c | 21 +-- drivers/net/ethernet/hisilicon/hns/hns_enet.c | 51 +++++-- .../net/ethernet/hisilicon/hns3/hns3_enet.c | 40 ++++-- .../net/ethernet/huawei/hinic/hinic_main.c | 37 +++-- drivers/net/ethernet/ibm/ehea/ehea_main.c | 34 +++-- drivers/net/ethernet/ibm/emac/core.c | 7 +- drivers/net/ethernet/ibm/ibmveth.c | 11 +- drivers/net/ethernet/ibm/ibmvnic.c | 8 +- drivers/net/ethernet/intel/e1000/e1000.h | 1 + drivers/net/ethernet/intel/e1000/e1000_main.c | 33 +++-- drivers/net/ethernet/intel/e1000e/netdev.c | 46 ++++-- .../net/ethernet/intel/fm10k/fm10k_netdev.c | 37 +++-- drivers/net/ethernet/intel/i40e/i40e_main.c | 75 +++++----- drivers/net/ethernet/intel/iavf/iavf.h | 1 + drivers/net/ethernet/intel/iavf/iavf_main.c | 43 +++--- drivers/net/ethernet/intel/ice/ice.h | 1 + drivers/net/ethernet/intel/ice/ice_main.c | 64 ++++++--- drivers/net/ethernet/intel/igb/igb_main.c | 74 ++++++---- drivers/net/ethernet/intel/igbvf/netdev.c | 76 ++++++---- drivers/net/ethernet/intel/igc/igc_mac.c | 1 + drivers/net/ethernet/intel/igc/igc_main.c | 77 ++++++---- drivers/net/ethernet/intel/ixgb/ixgb_main.c | 15 +- drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 134 +++++++++++------- drivers/net/ethernet/intel/ixgbevf/ipsec.c | 15 +- drivers/net/ethernet/intel/ixgbevf/ixgbevf.h | 1 + .../net/ethernet/intel/ixgbevf/ixgbevf_main.c | 87 +++++++----- drivers/net/ethernet/jme.c | 34 +++-- drivers/net/ethernet/marvell/mv643xx_eth.c | 9 +- drivers/net/ethernet/marvell/mvneta.c | 12 +- .../net/ethernet/marvell/mvpp2/mvpp2_main.c | 19 ++- .../ethernet/marvell/octeontx2/nic/otx2_pf.c | 17 ++- .../ethernet/marvell/octeontx2/nic/otx2_vf.c | 17 ++- drivers/net/ethernet/marvell/skge.c | 9 +- drivers/net/ethernet/marvell/sky2.c | 19 ++- drivers/net/ethernet/mellanox/mlx4/en_main.c | 1 + .../net/ethernet/mellanox/mlx4/en_netdev.c | 75 ++++++---- .../ethernet/mellanox/mlx5/core/ipoib/ipoib.c | 20 +-- .../net/ethernet/mellanox/mlxsw/spectrum.c | 16 ++- drivers/net/ethernet/micrel/ksz884x.c | 9 +- drivers/net/ethernet/microchip/lan743x_main.c | 9 +- drivers/net/ethernet/microsoft/mana/mana_en.c | 15 +- drivers/net/ethernet/mscc/ocelot_net.c | 14 +- .../net/ethernet/myricom/myri10ge/myri10ge.c | 11 +- drivers/net/ethernet/neterion/s2io.c | 24 +++- drivers/net/ethernet/nvidia/forcedeth.c | 10 +- .../ethernet/oki-semi/pch_gbe/pch_gbe_main.c | 10 +- drivers/net/ethernet/pasemi/pasemi_mac.c | 11 +- .../net/ethernet/pensando/ionic/ionic_lif.c | 23 +-- .../ethernet/qlogic/netxen/netxen_nic_main.c | 11 +- drivers/net/ethernet/qlogic/qede/qede_main.c | 50 +++++-- .../net/ethernet/qlogic/qlcnic/qlcnic_hw.c | 29 ++-- .../net/ethernet/qlogic/qlcnic/qlcnic_main.c | 34 +++-- drivers/net/ethernet/qualcomm/emac/emac.c | 23 ++- .../net/ethernet/qualcomm/rmnet/rmnet_vnd.c | 12 +- drivers/net/ethernet/realtek/8139cp.c | 23 ++- drivers/net/ethernet/realtek/8139too.c | 8 +- drivers/net/ethernet/realtek/r8169_main.c | 18 ++- .../net/ethernet/samsung/sxgbe/sxgbe_main.c | 15 +- drivers/net/ethernet/sfc/ef10.c | 11 +- drivers/net/ethernet/sfc/ef100_netdev.c | 9 +- drivers/net/ethernet/sfc/ef100_nic.c | 15 +- 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 + drivers/net/ethernet/sfc/siena/efx.c | 22 ++- drivers/net/ethernet/sgi/ioc3-eth.c | 13 +- drivers/net/ethernet/silan/sc92031.c | 11 +- drivers/net/ethernet/socionext/netsec.c | 11 +- .../net/ethernet/stmicro/stmmac/stmmac_main.c | 11 +- drivers/net/ethernet/sun/ldmvsw.c | 7 +- drivers/net/ethernet/sun/niu.c | 9 +- drivers/net/ethernet/sun/sungem.c | 9 +- drivers/net/ethernet/sun/sunvnet.c | 10 +- drivers/net/ethernet/tehuti/tehuti.c | 25 +++- drivers/net/ethernet/tehuti/tehuti.h | 1 + drivers/net/ethernet/ti/am65-cpsw-nuss.c | 13 +- drivers/net/ethernet/ti/cpsw_new.c | 11 +- drivers/net/ethernet/via/via-velocity.c | 19 ++- drivers/net/geneve.c | 20 ++- drivers/net/hyperv/netvsc_drv.c | 11 +- drivers/net/ifb.c | 20 ++- drivers/net/ipvlan/ipvlan_main.c | 58 ++++++-- drivers/net/ipvlan/ipvtap.c | 12 +- drivers/net/loopback.c | 25 ++-- drivers/net/macsec.c | 22 ++- drivers/net/macvlan.c | 56 ++++++-- drivers/net/macvtap.c | 12 +- drivers/net/net_failover.c | 13 ++ drivers/net/netdevsim/ipsec.c | 13 +- drivers/net/netdevsim/netdev.c | 14 +- drivers/net/netdevsim/netdevsim.h | 1 + drivers/net/nlmon.c | 11 +- drivers/net/tap.c | 18 ++- drivers/net/team/team.c | 31 +++- drivers/net/thunderbolt.c | 11 +- drivers/net/tun.c | 28 +++- drivers/net/usb/aqc111.c | 38 ++++- drivers/net/usb/aqc111.h | 14 -- drivers/net/usb/ax88179_178a.c | 11 +- drivers/net/usb/lan78xx.c | 8 +- drivers/net/usb/r8152.c | 53 +++++-- drivers/net/usb/smsc75xx.c | 10 +- drivers/net/veth.c | 27 ++-- drivers/net/vmxnet3/vmxnet3_drv.c | 36 +++-- drivers/net/vmxnet3/vmxnet3_ethtool.c | 35 +++-- drivers/net/vmxnet3/vmxnet3_int.h | 1 + drivers/net/vrf.c | 12 +- drivers/net/vsockmon.c | 11 +- drivers/net/vxlan/vxlan_core.c | 20 ++- drivers/net/wireguard/device.c | 20 ++- drivers/net/wireless/ath/wil6210/netdev.c | 14 +- drivers/net/xen-netback/interface.c | 14 +- drivers/net/xen-netfront.c | 20 ++- drivers/s390/net/qeth_l3_main.c | 13 +- drivers/staging/qlge/qlge_main.c | 21 +-- include/net/bonding.h | 5 +- include/net/net_failover.h | 8 +- net/8021q/vlan_dev.c | 15 +- net/batman-adv/soft-interface.c | 9 +- net/bridge/br_device.c | 25 +++- net/ethtool/ioctl.c | 17 ++- net/hsr/hsr_device.c | 13 +- net/ipv4/ip_gre.c | 19 +-- net/ipv4/ipip.c | 19 ++- net/ipv6/ip6_gre.c | 15 +- net/ipv6/ip6_tunnel.c | 19 ++- net/ipv6/sit.c | 18 ++- net/mac80211/ieee80211_i.h | 13 +- net/mac80211/main.c | 24 ++++ net/openvswitch/vport-internal_dev.c | 13 +- net/xfrm/xfrm_interface.c | 16 ++- 184 files changed, 2913 insertions(+), 1139 deletions(-)
diff --git a/arch/um/drivers/vector_transports.c b/arch/um/drivers/vector_transports.c index 0794d23f07cb..bf43b554e5f2 100644 --- a/arch/um/drivers/vector_transports.c +++ b/arch/um/drivers/vector_transports.c @@ -397,6 +397,35 @@ static int build_l2tpv3_transport_data(struct vector_private *vp) return 0; }
+static DECLARE_NETDEV_FEATURE_SET(raw_hw_feature_set,
NETIF_F_TSO_BIT,
NETIF_F_GRO_BIT);
+static DECLARE_NETDEV_FEATURE_SET(raw_feature_set,
NETIF_F_RXCSUM_BIT,
NETIF_F_HW_CSUM_BIT,
NETIF_F_TSO_BIT,
NETIF_F_GRO_BIT);
+static DECLARE_NETDEV_FEATURE_SET(hybrid_hw_feature_set,
NETIF_F_TSO_BIT,
NETIF_F_GSO_BIT,
NETIF_F_GRO_BIT);
+static DECLARE_NETDEV_FEATURE_SET(hybrid_feature_set,
NETIF_F_RXCSUM_BIT,
NETIF_F_HW_CSUM_BIT,
NETIF_F_TSO_BIT,
NETIF_F_GSO_BIT,
NETIF_F_GRO_BIT);
+static DECLARE_NETDEV_FEATURE_SET(tap_hw_feature_set,
NETIF_F_TSO_BIT,
NETIF_F_GSO_BIT,
NETIF_F_GRO_BIT);
+static DECLARE_NETDEV_FEATURE_SET(tap_feature_set,
NETIF_F_RXCSUM_BIT,
NETIF_F_HW_CSUM_BIT,
NETIF_F_TSO_BIT,
NETIF_F_GSO_BIT,
NETIF_F_GRO_BIT);
- static int build_raw_transport_data(struct vector_private *vp) { if (uml_raw_enable_vnet_headers(vp->fds->rx_fd)) {
@@ -406,10 +435,8 @@ static int build_raw_transport_data(struct vector_private *vp) vp->verify_header = &raw_verify_header; vp->header_size = sizeof(struct virtio_net_hdr); vp->rx_header_size = sizeof(struct virtio_net_hdr);
vp->dev->hw_features |= (NETIF_F_TSO | NETIF_F_GRO);
vp->dev->features |=
(NETIF_F_RXCSUM | NETIF_F_HW_CSUM |
NETIF_F_TSO | NETIF_F_GRO);
netdev_hw_features_set_array(vp->dev, &raw_hw_feature_set);
netdev_info( vp->dev, "raw: using vnet headers for tso and tx/rx checksum"netdev_active_features_set_array(vp->dev, &raw_feature_set);
@@ -425,11 +452,8 @@ static int build_hybrid_transport_data(struct vector_private *vp) vp->verify_header = &raw_verify_header; vp->header_size = sizeof(struct virtio_net_hdr); vp->rx_header_size = sizeof(struct virtio_net_hdr);
vp->dev->hw_features |=
(NETIF_F_TSO | NETIF_F_GSO | NETIF_F_GRO);
vp->dev->features |=
(NETIF_F_RXCSUM | NETIF_F_HW_CSUM |
NETIF_F_TSO | NETIF_F_GSO | NETIF_F_GRO);
netdev_hw_features_set_array(vp->dev, &hybrid_hw_feature_set);
netdev_info( vp->dev, "tap/raw hybrid: using vnet headers for tso and tx/rx checksum"netdev_active_features_set_array(vp->dev, &hybrid_feature_set);
@@ -450,11 +474,8 @@ static int build_tap_transport_data(struct vector_private *vp) vp->verify_header = &raw_verify_header; vp->header_size = sizeof(struct virtio_net_hdr); vp->rx_header_size = sizeof(struct virtio_net_hdr);
vp->dev->hw_features |=
(NETIF_F_TSO | NETIF_F_GSO | NETIF_F_GRO);
vp->dev->features |=
(NETIF_F_RXCSUM | NETIF_F_HW_CSUM |
NETIF_F_TSO | NETIF_F_GSO | NETIF_F_GRO);
netdev_hw_features_set_array(vp->dev, &tap_hw_feature_set);
netdev_info( vp->dev, "tap: using vnet headers for tso and tx/rx checksum"netdev_active_features_set_array(vp->dev, &tap_feature_set);
diff --git a/drivers/infiniband/ulp/ipoib/ipoib.h b/drivers/infiniband/ulp/ipoib/ipoib.h index 35e9c8a330e2..8f0cbaa4afdc 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib.h +++ b/drivers/infiniband/ulp/ipoib/ipoib.h @@ -38,6 +38,7 @@ #include <linux/list.h> #include <linux/skbuff.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/workqueue.h> #include <linux/kref.h> #include <linux/if_infiniband.h> diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c index 2a8961b685c2..4d917762352f 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_main.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c @@ -2104,6 +2104,10 @@ static const struct net_device_ops ipoib_netdev_default_pf = { .ndo_stop = ipoib_ib_dev_stop_default, };
+static DECLARE_NETDEV_FEATURE_SET(ipoib_feature_set,
NETIF_F_VLAN_CHALLENGED_BIT,
NETIF_F_HIGHDMA_BIT);
- void ipoib_setup_common(struct net_device *dev) { dev->header_ops = &ipoib_header_ops;
@@ -2119,8 +2123,8 @@ void ipoib_setup_common(struct net_device *dev) dev->addr_len = INFINIBAND_ALEN; dev->type = ARPHRD_INFINIBAND; dev->tx_queue_len = ipoib_sendq_size * 2;
- dev->features = (NETIF_F_VLAN_CHALLENGED |
NETIF_F_HIGHDMA);
netdev_active_features_zero(dev);
netdev_active_features_set_array(dev, &ipoib_feature_set); netif_keep_dst(dev);
memcpy(dev->broadcast, ipv4_bcast_addr, INFINIBAND_ALEN);
diff --git a/drivers/net/amt.c b/drivers/net/amt.c index 9a247eb7679c..ec8d6d6fda9c 100644 --- a/drivers/net/amt.c +++ b/drivers/net/amt.c @@ -9,6 +9,7 @@ #include <linux/jhash.h> #include <linux/if_tunnel.h> #include <linux/net.h> +#include <linux/netdev_features_helper.h> #include <linux/igmp.h> #include <linux/workqueue.h> #include <net/sch_generic.h> @@ -3095,6 +3096,15 @@ static const struct net_device_ops amt_netdev_ops = { .ndo_get_stats64 = dev_get_tstats64, };
+static DECLARE_NETDEV_FEATURE_SET(amt_feature_set,
NETIF_F_LLTX_BIT,
NETIF_F_NETNS_LOCAL_BIT);
+static DECLARE_NETDEV_FEATURE_SET(amt_hw_feature_set,
NETIF_F_SG_BIT,
NETIF_F_HW_CSUM_BIT,
NETIF_F_FRAGLIST_BIT,
NETIF_F_RXCSUM_BIT);
- static void amt_link_setup(struct net_device *dev) { dev->netdev_ops = &amt_netdev_ops;
@@ -3107,12 +3117,10 @@ static void amt_link_setup(struct net_device *dev) dev->hard_header_len = 0; dev->addr_len = 0; dev->priv_flags |= IFF_NO_QUEUE;
- dev->features |= NETIF_F_LLTX; dev->features |= NETIF_F_GSO_SOFTWARE;
- dev->features |= NETIF_F_NETNS_LOCAL;
- dev->hw_features |= NETIF_F_SG | NETIF_F_HW_CSUM;
- dev->hw_features |= NETIF_F_FRAGLIST | NETIF_F_RXCSUM;
- netdev_active_features_set_array(dev, &amt_feature_set); dev->hw_features |= NETIF_F_GSO_SOFTWARE;
- netdev_active_features_set_array(dev, &amt_hw_feature_set);
Here should use netdev_hw_features_set_array()
eth_hw_addr_random(dev); eth_zero_addr(dev->broadcast); ether_setup(dev); diff --git a/drivers/net/bareudp.c b/drivers/net/bareudp.c index 683203f87ae2..08b11ed436ad 100644 --- a/drivers/net/bareudp.c +++ b/drivers/net/bareudp.c @@ -11,6 +11,7 @@ #include <linux/module.h> #include <linux/etherdevice.h> #include <linux/hash.h> +#include <linux/netdev_features_helper.h> #include <net/dst_metadata.h> #include <net/gro_cells.h> #include <net/rtnetlink.h> @@ -536,18 +537,28 @@ static const struct device_type bareudp_type = { .name = "bareudp", };
+static DECLARE_NETDEV_FEATURE_SET(bareudp_feature_set,
NETIF_F_SG_BIT,
NETIF_F_HW_CSUM_BIT,
NETIF_F_FRAGLIST_BIT,
NETIF_F_RXCSUM_BIT,
NETIF_F_LLTX_BIT);
+static DECLARE_NETDEV_FEATURE_SET(bareudp_hw_feature_set,
NETIF_F_SG_BIT,
NETIF_F_HW_CSUM_BIT,
NETIF_F_FRAGLIST_BIT,
NETIF_F_RXCSUM_BIT);
- /* Initialize the device structure. */ static void bareudp_setup(struct net_device *dev) { dev->netdev_ops = &bareudp_netdev_ops; dev->needs_free_netdev = true; SET_NETDEV_DEVTYPE(dev, &bareudp_type);
- dev->features |= NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_FRAGLIST;
- dev->features |= NETIF_F_RXCSUM;
- dev->features |= NETIF_F_LLTX;
- netdev_active_features_set_array(dev, &bareudp_feature_set); dev->features |= NETIF_F_GSO_SOFTWARE;
- dev->hw_features |= NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_FRAGLIST;
- dev->hw_features |= NETIF_F_RXCSUM;
- netdev_hw_features_set_array(dev, &bareudp_hw_feature_set); dev->hw_features |= NETIF_F_GSO_SOFTWARE; dev->hard_header_len = 0; dev->addr_len = 0;
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index e75acb14d066..a7783abec601 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -59,6 +59,7 @@ #include <linux/uaccess.h> #include <linux/errno.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/inetdevice.h> #include <linux/igmp.h> #include <linux/etherdevice.h> @@ -254,6 +255,25 @@ static const struct flow_dissector_key flow_keys_bonding_keys[] = {
static struct flow_dissector flow_keys_bonding __read_mostly;
+static DECLARE_NETDEV_FEATURE_SET(bond_vlan_feature_set,
NETIF_F_HW_CSUM_BIT,
NETIF_F_SG_BIT,
NETIF_F_FRAGLIST_BIT,
NETIF_F_HIGHDMA_BIT,
NETIF_F_LRO_BIT);
+static DECLARE_NETDEV_FEATURE_SET(bond_enc_feature_set,
NETIF_F_HW_CSUM_BIT,
NETIF_F_SG_BIT,
NETIF_F_RXCSUM_BIT);
+static DECLARE_NETDEV_FEATURE_SET(bond_mpls_feature_set,
NETIF_F_HW_CSUM_BIT,
NETIF_F_SG_BIT);
+static netdev_features_t bond_vlan_features __ro_after_init; +static netdev_features_t bond_enc_features __ro_after_init; +static netdev_features_t bond_mpls_features __ro_after_init; /*-------------------------- Forward declarations ---------------------------*/
static int bond_init(struct net_device *bond_dev); @@ -1421,16 +1441,11 @@ static netdev_features_t bond_fix_features(struct net_device *dev, return features; }
-#define BOND_VLAN_FEATURES (NETIF_F_HW_CSUM | NETIF_F_SG | \
NETIF_F_FRAGLIST | NETIF_F_GSO_SOFTWARE | \
NETIF_F_HIGHDMA | NETIF_F_LRO)
+#define BOND_VLAN_FEATURES bond_vlan_features
-#define BOND_ENC_FEATURES (NETIF_F_HW_CSUM | NETIF_F_SG | \
NETIF_F_RXCSUM | NETIF_F_GSO_SOFTWARE)
-#define BOND_MPLS_FEATURES (NETIF_F_HW_CSUM | NETIF_F_SG | \
NETIF_F_GSO_SOFTWARE)
+#define BOND_ENC_FEATURES bond_enc_features
+#define BOND_MPLS_FEATURES bond_mpls_features
static void bond_compute_features(struct bonding *bond) { @@ -6195,6 +6210,21 @@ static int bond_check_params(struct bond_params *params) return 0; }
+static void __init bond_netdev_features_init(void) +{
- bond_vlan_features = NETIF_F_GSO_SOFTWARE;
- netdev_features_set_array(&bond_vlan_feature_set,
&bond_vlan_features);
- bond_enc_features = NETIF_F_GSO_SOFTWARE;
- netdev_features_set_array(&bond_enc_feature_set,
&bond_enc_features);
- bond_mpls_features = NETIF_F_GSO_SOFTWARE;
- netdev_features_set_array(&bond_mpls_feature_set,
&bond_mpls_features);
+}
- /* Called from registration process */ static int bond_init(struct net_device *bond_dev) {
@@ -6355,6 +6385,8 @@ static int __init bonding_init(void) ARRAY_SIZE(flow_keys_bonding_keys));
register_netdevice_notifier(&bond_netdev_notifier);
- bond_netdev_features_init(); out: return res; err:
diff --git a/drivers/net/dsa/xrs700x/xrs700x.c b/drivers/net/dsa/xrs700x/xrs700x.c index 3887ed33c5fe..c989138e7761 100644 --- a/drivers/net/dsa/xrs700x/xrs700x.c +++ b/drivers/net/dsa/xrs700x/xrs700x.c @@ -9,15 +9,18 @@ #include <linux/if_bridge.h> #include <linux/of_device.h> #include <linux/netdev_features.h> +#include <linux/netdev_features_helper.h> #include <linux/if_hsr.h> #include "xrs700x.h" #include "xrs700x_reg.h"
#define XRS700X_MIB_INTERVAL msecs_to_jiffies(3000)
-#define XRS7000X_SUPPORTED_HSR_FEATURES \
- (NETIF_F_HW_HSR_TAG_INS | NETIF_F_HW_HSR_TAG_RM | \
NETIF_F_HW_HSR_FWD | NETIF_F_HW_HSR_DUP)
+static DECLARE_NETDEV_FEATURE_SET(xrs7000x_hsr_feature_set,
NETIF_F_HW_HSR_TAG_INS_BIT,
NETIF_F_HW_HSR_TAG_RM_BIT,
NETIF_F_HW_HSR_FWD_BIT,
NETIF_F_HW_HSR_FWD_BIT);
Two NETIF_F_HW_HSR_FWD_BIT here.
#define XRS7003E_ID 0x100 #define XRS7003F_ID 0x101 @@ -632,7 +635,8 @@ static int xrs700x_hsr_join(struct dsa_switch *ds, int port, hsr_pair[1] = partner->index; for (i = 0; i < ARRAY_SIZE(hsr_pair); i++) { slave = dsa_to_port(ds, hsr_pair[i])->slave;
slave->features |= XRS7000X_SUPPORTED_HSR_FEATURES;
netdev_active_features_set_array(slave,
&xrs7000x_hsr_feature_set);
}
return 0;
@@ -686,7 +690,8 @@ static int xrs700x_hsr_leave(struct dsa_switch *ds, int port, hsr_pair[1] = partner->index; for (i = 0; i < ARRAY_SIZE(hsr_pair); i++) { slave = dsa_to_port(ds, hsr_pair[i])->slave;
slave->features &= ~XRS7000X_SUPPORTED_HSR_FEATURES;
netdev_active_features_clear_array(slave,
&xrs7000x_hsr_feature_set);
}
return 0;
diff --git a/drivers/net/dummy.c b/drivers/net/dummy.c index f82ad7419508..6f176774efbd 100644 --- a/drivers/net/dummy.c +++ b/drivers/net/dummy.c @@ -32,6 +32,7 @@ #include <linux/module.h> #include <linux/kernel.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/etherdevice.h> #include <linux/ethtool.h> #include <linux/init.h> @@ -110,6 +111,13 @@ static const struct ethtool_ops dummy_ethtool_ops = { .get_ts_info = ethtool_op_get_ts_info, };
+static DECLARE_NETDEV_FEATURE_SET(dummy_feature_set,
NETIF_F_SG_BIT,
NETIF_F_FRAGLIST_BIT,
NETIF_F_HW_CSUM_BIT,
NETIF_F_HIGHDMA_BIT,
NETIF_F_LLTX_BIT);
- static void dummy_setup(struct net_device *dev) { ether_setup(dev);
@@ -123,9 +131,8 @@ static void dummy_setup(struct net_device *dev) dev->flags |= IFF_NOARP; dev->flags &= ~IFF_MULTICAST; dev->priv_flags |= IFF_LIVE_ADDR_CHANGE | IFF_NO_QUEUE;
- dev->features |= NETIF_F_SG | NETIF_F_FRAGLIST;
- netdev_active_features_set_array(dev, &dummy_feature_set); dev->features |= NETIF_F_GSO_SOFTWARE;
- dev->features |= NETIF_F_HW_CSUM | NETIF_F_HIGHDMA | NETIF_F_LLTX; dev->features |= NETIF_F_GSO_ENCAP_ALL; dev->hw_features |= dev->features; dev->hw_enc_features |= dev->features;
diff --git a/drivers/net/ethernet/3com/typhoon.c b/drivers/net/ethernet/3com/typhoon.c index cad4f354cc76..cb7a4bb5cf74 100644 --- a/drivers/net/ethernet/3com/typhoon.c +++ b/drivers/net/ethernet/3com/typhoon.c @@ -108,6 +108,7 @@ static const int multicast_filter_limit = 32; #include <linux/interrupt.h> #include <linux/pci.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/etherdevice.h> #include <linux/skbuff.h> #include <linux/mm.h> @@ -2286,6 +2287,15 @@ static const struct net_device_ops typhoon_netdev_ops = { .ndo_set_mac_address = eth_mac_addr, };
+static DECLARE_NETDEV_FEATURE_SET(typhoon_hw_feature_set,
NETIF_F_SG_BIT,
NETIF_F_IP_CSUM_BIT,
NETIF_F_TSO_BIT,
NETIF_F_HW_VLAN_CTAG_TX_BIT);
+static DECLARE_NETDEV_FEATURE_SET(typhoon_feature_set,
NETIF_F_HW_VLAN_CTAG_RX_BIT,
NETIF_F_RXCSUM_BIT);
- static int typhoon_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) {
@@ -2476,10 +2486,10 @@ typhoon_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) * on the current 3XP firmware -- it does not respect the offload * settings -- so we only allow the user to toggle the TX processing. */
- dev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO |
NETIF_F_HW_VLAN_CTAG_TX;
- dev->features = dev->hw_features |
NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_RXCSUM;
netdev_hw_features_zero(dev);
netdev_hw_features_set_array(dev, &typhoon_hw_feature_set);
dev->features = dev->hw_features;
netdev_active_features_set_array(dev, &typhoon_feature_set);
err = register_netdev(dev); if (err < 0) {
diff --git a/drivers/net/ethernet/aeroflex/greth.c b/drivers/net/ethernet/aeroflex/greth.c index 447dc64a17e5..dca85429a0ea 100644 --- a/drivers/net/ethernet/aeroflex/greth.c +++ b/drivers/net/ethernet/aeroflex/greth.c @@ -1336,6 +1336,11 @@ static int greth_mdio_init(struct greth_private *greth) return ret; }
+static DECLARE_NETDEV_FEATURE_SET(greth_hw_feature_set,
NETIF_F_SG_BIT,
NETIF_F_IP_CSUM_BIT,
NETIF_F_RXCSUM_BIT);
- /* Initialize the GRETH MAC */ static int greth_of_probe(struct platform_device *ofdev) {
@@ -1483,8 +1488,8 @@ static int greth_of_probe(struct platform_device *ofdev) GRETH_REGSAVE(regs->status, 0xFF);
if (greth->gbit_mac) {
dev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM |
NETIF_F_RXCSUM;
netdev_hw_features_zero(dev);
dev->features = dev->hw_features | NETIF_F_HIGHDMA; greth_netdev_ops.ndo_start_xmit = greth_start_xmit_gbit; }netdev_hw_features_set_array(dev, &greth_hw_feature_set);
diff --git a/drivers/net/ethernet/alteon/acenic.c b/drivers/net/ethernet/alteon/acenic.c index 22fe98555b24..4a16e176248c 100644 --- a/drivers/net/ethernet/alteon/acenic.c +++ b/drivers/net/ethernet/alteon/acenic.c @@ -55,6 +55,7 @@ #include <linux/dma-mapping.h> #include <linux/kernel.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/etherdevice.h> #include <linux/skbuff.h> #include <linux/delay.h> @@ -451,6 +452,12 @@ static const struct net_device_ops ace_netdev_ops = { .ndo_change_mtu = ace_change_mtu, };
+static DECLARE_NETDEV_FEATURE_SET(acenic_feature_set,
NETIF_F_SG_BIT,
NETIF_F_IP_CSUM_BIT,
NETIF_F_HW_VLAN_CTAG_TX_BIT,
NETIF_F_HW_VLAN_CTAG_RX_BIT);
- static int acenic_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) {
@@ -469,8 +476,7 @@ static int acenic_probe_one(struct pci_dev *pdev, ap->pdev = pdev; ap->name = pci_name(pdev);
- dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM;
- dev->features |= NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX;
netdev_active_features_set_array(dev, &acenic_feature_set);
dev->watchdog_timeo = 5*HZ; dev->min_mtu = 0;
diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.c b/drivers/net/ethernet/amazon/ena/ena_netdev.c index 6a356a6cee15..ab102769965f 100644 --- a/drivers/net/ethernet/amazon/ena/ena_netdev.c +++ b/drivers/net/ethernet/amazon/ena/ena_netdev.c @@ -11,6 +11,7 @@ #include <linux/ethtool.h> #include <linux/kernel.h> #include <linux/module.h> +#include <linux/netdev_features_helper.h> #include <linux/numa.h> #include <linux/pci.h> #include <linux/utsname.h> @@ -4010,6 +4011,11 @@ static u32 ena_calc_max_io_queue_num(struct pci_dev *pdev, return max_num_io_queues; }
+static DECLARE_NETDEV_FEATURE_SET(ena_feature_set,
NETIF_F_SG_BIT,
NETIF_F_RXHASH_BIT,
NETIF_F_HIGHDMA_BIT);
- static void ena_set_dev_offloads(struct ena_com_dev_get_features_ctx *feat, struct net_device *netdev) {
@@ -4041,11 +4047,8 @@ static void ena_set_dev_offloads(struct ena_com_dev_get_features_ctx *feat, ENA_ADMIN_FEATURE_OFFLOAD_DESC_RX_L4_IPV6_CSUM_MASK) dev_features |= NETIF_F_RXCSUM;
- netdev->features =
dev_features |
NETIF_F_SG |
NETIF_F_RXHASH |
NETIF_F_HIGHDMA;
netdev->features = dev_features;
netdev_active_features_set_array(netdev, &ena_feature_set);
netdev->hw_features |= netdev->features; netdev->vlan_features |= netdev->features;
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-main.c b/drivers/net/ethernet/amd/xgbe/xgbe-main.c index 0e8698928e4d..a5c4fb8aa676 100644 --- a/drivers/net/ethernet/amd/xgbe/xgbe-main.c +++ b/drivers/net/ethernet/amd/xgbe/xgbe-main.c @@ -118,6 +118,7 @@ #include <linux/device.h> #include <linux/spinlock.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/etherdevice.h> #include <linux/io.h> #include <linux/notifier.h> @@ -259,6 +260,34 @@ void xgbe_set_counts(struct xgbe_prv_data *pdata) } }
+static DECLARE_NETDEV_FEATURE_SET(xgbe_hw_feature_set,
NETIF_F_SG_BIT,
NETIF_F_IP_CSUM_BIT,
NETIF_F_IPV6_CSUM_BIT,
NETIF_F_RXCSUM_BIT,
NETIF_F_TSO_BIT,
NETIF_F_TSO6_BIT,
NETIF_F_GRO_BIT,
NETIF_F_HW_VLAN_CTAG_RX_BIT,
NETIF_F_HW_VLAN_CTAG_TX_BIT,
NETIF_F_HW_VLAN_CTAG_FILTER_BIT);
+static DECLARE_NETDEV_FEATURE_SET(xgbe_hw_enc_feature_set,
NETIF_F_SG_BIT,
NETIF_F_IP_CSUM_BIT,
NETIF_F_IPV6_CSUM_BIT,
NETIF_F_RXCSUM_BIT,
NETIF_F_TSO_BIT,
NETIF_F_TSO6_BIT,
NETIF_F_GRO_BIT,
NETIF_F_GSO_UDP_TUNNEL_BIT,
NETIF_F_GSO_UDP_TUNNEL_CSUM_BIT);
+static DECLARE_NETDEV_FEATURE_SET(xgbe_vlan_feature_set,
NETIF_F_SG_BIT,
NETIF_F_IP_CSUM_BIT,
NETIF_F_IPV6_CSUM_BIT,
NETIF_F_TSO_BIT,
NETIF_F_TSO6_BIT);
- int xgbe_config_netdev(struct xgbe_prv_data *pdata) { struct net_device *netdev = pdata->netdev;
@@ -342,30 +371,16 @@ int xgbe_config_netdev(struct xgbe_prv_data *pdata) #endif
/* Set device features */
- netdev->hw_features = NETIF_F_SG |
NETIF_F_IP_CSUM |
NETIF_F_IPV6_CSUM |
NETIF_F_RXCSUM |
NETIF_F_TSO |
NETIF_F_TSO6 |
NETIF_F_GRO |
NETIF_F_HW_VLAN_CTAG_RX |
NETIF_F_HW_VLAN_CTAG_TX |
NETIF_F_HW_VLAN_CTAG_FILTER;
netdev_hw_features_zero(netdev);
netdev_hw_features_set_array(netdev, &xgbe_hw_feature_set);
if (pdata->hw_feat.rss) netdev->hw_features |= NETIF_F_RXHASH;
if (pdata->hw_feat.vxn) {
netdev->hw_enc_features = NETIF_F_SG |
NETIF_F_IP_CSUM |
NETIF_F_IPV6_CSUM |
NETIF_F_RXCSUM |
NETIF_F_TSO |
NETIF_F_TSO6 |
NETIF_F_GRO |
NETIF_F_GSO_UDP_TUNNEL |
NETIF_F_GSO_UDP_TUNNEL_CSUM;
netdev_hw_enc_features_zero(netdev);
netdev_hw_enc_features_set_array(netdev,
&xgbe_hw_enc_feature_set);
netdev->hw_features |= NETIF_F_GSO_UDP_TUNNEL | NETIF_F_GSO_UDP_TUNNEL_CSUM;
@@ -373,11 +388,7 @@ int xgbe_config_netdev(struct xgbe_prv_data *pdata) netdev->udp_tunnel_nic_info = xgbe_get_udp_tunnel_info(); }
- netdev->vlan_features |= NETIF_F_SG |
NETIF_F_IP_CSUM |
NETIF_F_IPV6_CSUM |
NETIF_F_TSO |
NETIF_F_TSO6;
netdev_vlan_features_set_array(netdev, &xgbe_vlan_feature_set);
netdev->features |= netdev->hw_features; pdata->netdev_features = netdev->features;
diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_main.c b/drivers/net/ethernet/apm/xgene/xgene_enet_main.c index 53dc8d5fede8..49a35bd4c16d 100644 --- a/drivers/net/ethernet/apm/xgene/xgene_enet_main.c +++ b/drivers/net/ethernet/apm/xgene/xgene_enet_main.c @@ -8,6 +8,7 @@ */
#include <linux/gpio.h> +#include <linux/netdev_features_helper.h> #include "xgene_enet_main.h" #include "xgene_enet_hw.h" #include "xgene_enet_sgmac.h" @@ -2012,6 +2013,12 @@ static const struct of_device_id xgene_enet_of_match[] = {
MODULE_DEVICE_TABLE(of, xgene_enet_of_match);
+static DECLARE_NETDEV_FEATURE_SET(xgene_vlan_feature_set,
NETIF_F_IP_CSUM_BIT,
NETIF_F_GSO_BIT,
NETIF_F_GRO_BIT,
NETIF_F_SG_BIT);
- static int xgene_enet_probe(struct platform_device *pdev) { struct net_device *ndev;
@@ -2034,10 +2041,7 @@ static int xgene_enet_probe(struct platform_device *pdev) platform_set_drvdata(pdev, pdata); ndev->netdev_ops = &xgene_ndev_ops; xgene_enet_set_ethtool_ops(ndev);
- ndev->features |= NETIF_F_IP_CSUM |
NETIF_F_GSO |
NETIF_F_GRO |
NETIF_F_SG;
netdev_active_features_set_array(ndev, &xgene_vlan_feature_set);
of_id = of_match_device(xgene_enet_of_match, &pdev->dev); if (of_id) {
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c index e11cc29d3264..2a726e6213b4 100644 --- a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c +++ b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c @@ -20,6 +20,7 @@
#include <linux/moduleparam.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/etherdevice.h> #include <linux/timer.h> #include <linux/cpu.h> @@ -368,6 +369,15 @@ int aq_nic_ndev_register(struct aq_nic_s *self) return err; }
+static DECLARE_NETDEV_FEATURE_SET(aq_nic_vlan_feature_set,
NETIF_F_HW_CSUM_BIT,
NETIF_F_RXCSUM_BIT,
NETIF_F_RXHASH_BIT,
NETIF_F_SG_BIT,
NETIF_F_LRO_BIT,
NETIF_F_TSO_BIT,
NETIF_F_TSO6_BIT);
- void aq_nic_ndev_init(struct aq_nic_s *self) { const struct aq_hw_caps_s *aq_hw_caps = self->aq_nic_cfg.aq_hw_caps;
@@ -375,9 +385,7 @@ void aq_nic_ndev_init(struct aq_nic_s *self)
self->ndev->hw_features |= aq_hw_caps->hw_features; self->ndev->features = aq_hw_caps->hw_features;
- self->ndev->vlan_features |= NETIF_F_HW_CSUM | NETIF_F_RXCSUM |
NETIF_F_RXHASH | NETIF_F_SG |
NETIF_F_LRO | NETIF_F_TSO | NETIF_F_TSO6;
- netdev_vlan_features_set_array(self->ndev, &aq_nic_vlan_feature_set); self->ndev->gso_partial_features = NETIF_F_GSO_UDP_L4; self->ndev->priv_flags = aq_hw_caps->hw_priv_flags; self->ndev->priv_flags |= IFF_LIVE_ADDR_CHANGE;
diff --git a/drivers/net/ethernet/asix/ax88796c_main.c b/drivers/net/ethernet/asix/ax88796c_main.c index 6ba5b024a7be..9309d371b8da 100644 --- a/drivers/net/ethernet/asix/ax88796c_main.c +++ b/drivers/net/ethernet/asix/ax88796c_main.c @@ -19,6 +19,7 @@ #include <linux/minmax.h> #include <linux/module.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/of.h> #include <linux/phy.h> #include <linux/skbuff.h> @@ -33,6 +34,11 @@ static int msg_enable = NETIF_MSG_PROBE | static const char *no_regs_list = "80018001,e1918001,8001a001,fc0d0000"; unsigned long ax88796c_no_regs_mask[AX88796C_REGDUMP_LEN / (sizeof(unsigned long) * 8)];
+static DECLARE_NETDEV_FEATURE_SET(ax88796c_feature_set,
NETIF_F_RXCSUM_BIT,
NETIF_F_HW_CSUM_BIT);
+static netdev_features_t ax88796c_features __ro_after_init;
- module_param(msg_enable, int, 0444); MODULE_PARM_DESC(msg_enable, "Message mask (see linux/netdevice.h for bitmap)");
@@ -920,12 +926,12 @@ ax88796c_set_features(struct net_device *ndev, netdev_features_t features) struct ax88796c_device *ax_local = to_ax88796c_device(ndev); netdev_features_t changed = features ^ ndev->features;
- if (!(changed & (NETIF_F_RXCSUM | NETIF_F_HW_CSUM)))
if (!(changed & ax88796c_features)) return 0;
ndev->features = features;
- if (changed & (NETIF_F_RXCSUM | NETIF_F_HW_CSUM))
if (changed & ax88796c_features) ax88796c_set_csums(ax_local);
return 0;
@@ -1023,8 +1029,8 @@ static int ax88796c_probe(struct spi_device *spi) ndev->irq = spi->irq; ndev->netdev_ops = &ax88796c_netdev_ops; ndev->ethtool_ops = &ax88796c_ethtool_ops;
- ndev->hw_features |= NETIF_F_HW_CSUM | NETIF_F_RXCSUM;
- ndev->features |= NETIF_F_HW_CSUM | NETIF_F_RXCSUM;
- ndev->hw_features |= ax88796c_features;
- ndev->features |= ax88796c_features; ndev->needed_headroom = TX_OVERHEAD; ndev->needed_tailroom = TX_EOP_SIZE;
@@ -1138,6 +1144,11 @@ static struct spi_driver ax88796c_spi_driver = { .id_table = asix_id, };
+static void __init ax88796c_features_init(void) +{
- netdev_features_set_array(&ax88796c_feature_set, &ax88796c_features);
+}
- static __init int ax88796c_spi_init(void) { int ret;
@@ -1150,6 +1161,8 @@ static __init int ax88796c_spi_init(void) pr_err("Invalid bitmap description, masking all registers\n"); }
- ax88796c_features_init();
- return spi_register_driver(&ax88796c_spi_driver); }
diff --git a/drivers/net/ethernet/atheros/alx/main.c b/drivers/net/ethernet/atheros/alx/main.c index a89b93cb4e26..7f5cb50f4b66 100644 --- a/drivers/net/ethernet/atheros/alx/main.c +++ b/drivers/net/ethernet/atheros/alx/main.c @@ -42,6 +42,7 @@ #include <linux/aer.h> #include <linux/bitops.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/etherdevice.h> #include <net/ip6_checksum.h> #include <linux/crc32.h> @@ -1712,6 +1713,13 @@ static const struct net_device_ops alx_netdev_ops = { #endif };
+static DECLARE_NETDEV_FEATURE_SET(alx_hw_feature_set,
NETIF_F_SG_BIT,
NETIF_F_HW_CSUM_BIT,
NETIF_F_RXCSUM_BIT,
NETIF_F_TSO_BIT,
NETIF_F_TSO6_BIT);
- static int alx_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { struct net_device *netdev;
@@ -1821,11 +1829,8 @@ static int alx_probe(struct pci_dev *pdev, const struct pci_device_id *ent) } }
- netdev->hw_features = NETIF_F_SG |
NETIF_F_HW_CSUM |
NETIF_F_RXCSUM |
NETIF_F_TSO |
NETIF_F_TSO6;
netdev_hw_features_zero(netdev);
netdev_hw_features_set_array(netdev, &alx_hw_feature_set);
if (alx_get_perm_macaddr(hw, hw->perm_addr)) { dev_warn(&pdev->dev,
diff --git a/drivers/net/ethernet/atheros/atl1c/atl1c.h b/drivers/net/ethernet/atheros/atl1c/atl1c.h index 43d821fe7a54..6a1f8191a336 100644 --- a/drivers/net/ethernet/atheros/atl1c/atl1c.h +++ b/drivers/net/ethernet/atheros/atl1c/atl1c.h @@ -15,6 +15,7 @@ #include <linux/module.h> #include <linux/pci.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/etherdevice.h> #include <linux/skbuff.h> #include <linux/ioport.h> diff --git a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c index be4b1f8eef29..220253cec3c2 100644 --- a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c +++ b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c @@ -2618,6 +2618,13 @@ static const struct net_device_ops atl1c_netdev_ops = { #endif };
+static DECLARE_NETDEV_FEATURE_SET(atl1c_hw_feature_set,
NETIF_F_SG_BIT,
NETIF_F_HW_CSUM_BIT,
NETIF_F_HW_VLAN_CTAG_RX_BIT,
NETIF_F_TSO_BIT,
NETIF_F_TSO6_BIT);
- static int atl1c_init_netdev(struct net_device *netdev, struct pci_dev *pdev) { SET_NETDEV_DEV(netdev, &pdev->dev);
@@ -2629,11 +2636,8 @@ static int atl1c_init_netdev(struct net_device *netdev, struct pci_dev *pdev) atl1c_set_ethtool_ops(netdev);
/* TODO: add when ready */
- netdev->hw_features = NETIF_F_SG |
NETIF_F_HW_CSUM |
NETIF_F_HW_VLAN_CTAG_RX |
NETIF_F_TSO |
NETIF_F_TSO6;
- netdev_hw_features_zero(netdev);
- netdev_hw_features_set_array(netdev, &atl1c_hw_feature_set); netdev->features = netdev->hw_features | NETIF_F_HW_VLAN_CTAG_TX; return 0;
diff --git a/drivers/net/ethernet/atheros/atl1e/atl1e.h b/drivers/net/ethernet/atheros/atl1e/atl1e.h index 9fcad783c939..007eef2cc9fc 100644 --- a/drivers/net/ethernet/atheros/atl1e/atl1e.h +++ b/drivers/net/ethernet/atheros/atl1e/atl1e.h @@ -16,6 +16,7 @@ #include <linux/module.h> #include <linux/pci.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/etherdevice.h> #include <linux/skbuff.h> #include <linux/ioport.h> diff --git a/drivers/net/ethernet/atheros/atl1e/atl1e_main.c b/drivers/net/ethernet/atheros/atl1e/atl1e_main.c index 57a51fb7746c..0aaca5a1f87c 100644 --- a/drivers/net/ethernet/atheros/atl1e/atl1e_main.c +++ b/drivers/net/ethernet/atheros/atl1e/atl1e_main.c @@ -2255,6 +2255,12 @@ static const struct net_device_ops atl1e_netdev_ops = {
};
+static DECLARE_NETDEV_FEATURE_SET(atl1e_hw_feature_set,
NETIF_F_SG_BIT,
NETIF_F_HW_CSUM_BIT,
NETIF_F_TSO_BIT,
NETIF_F_HW_VLAN_CTAG_RX_BIT);
- static int atl1e_init_netdev(struct net_device *netdev, struct pci_dev *pdev) { SET_NETDEV_DEV(netdev, &pdev->dev);
@@ -2269,8 +2275,8 @@ static int atl1e_init_netdev(struct net_device *netdev, struct pci_dev *pdev) (ETH_HLEN + ETH_FCS_LEN + VLAN_HLEN); atl1e_set_ethtool_ops(netdev);
- netdev->hw_features = NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_TSO |
NETIF_F_HW_VLAN_CTAG_RX;
- netdev_hw_features_zero(netdev);
- netdev_hw_features_set_array(netdev, &atl1e_hw_feature_set); netdev->features = netdev->hw_features | NETIF_F_HW_VLAN_CTAG_TX; /* not enabled by default */ netdev->hw_features |= NETIF_F_RXALL | NETIF_F_RXFCS;
diff --git a/drivers/net/ethernet/atheros/atlx/atl1.c b/drivers/net/ethernet/atheros/atlx/atl1.c index ff1fe09abf9f..c46d3e7ae89f 100644 --- a/drivers/net/ethernet/atheros/atlx/atl1.c +++ b/drivers/net/ethernet/atheros/atlx/atl1.c @@ -49,6 +49,7 @@ #include <linux/module.h> #include <linux/net.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/pci.h> #include <linux/pci_ids.h> #include <linux/pm.h> @@ -2891,6 +2892,18 @@ static const struct net_device_ops atl1_netdev_ops = { #endif };
+static DECLARE_NETDEV_FEATURE_SET(atl1_feature_set,
NETIF_F_HW_CSUM_BIT,
NETIF_F_SG_BIT,
NETIF_F_HW_VLAN_CTAG_TX_BIT,
NETIF_F_HW_VLAN_CTAG_RX_BIT);
+static DECLARE_NETDEV_FEATURE_SET(atl1_hw_feature_set,
NETIF_F_HW_CSUM_BIT,
NETIF_F_SG_BIT,
NETIF_F_TSO_BIT,
NETIF_F_HW_VLAN_CTAG_RX_BIT);
- /**
- atl1_probe - Device Initialization Routine
- @pdev: PCI device information struct
@@ -2987,12 +3000,11 @@ static int atl1_probe(struct pci_dev *pdev, const struct pci_device_id *ent) if (err) goto err_common;
- netdev->features = NETIF_F_HW_CSUM;
- netdev->features |= NETIF_F_SG;
- netdev->features |= (NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX);
- netdev_active_features_zero(netdev);
- netdev_active_features_set_array(netdev, &atl1_feature_set);
- netdev->hw_features = NETIF_F_HW_CSUM | NETIF_F_SG | NETIF_F_TSO |
NETIF_F_HW_VLAN_CTAG_RX;
netdev_hw_features_zero(netdev);
netdev_hw_features_set_array(netdev, &atl1_hw_feature_set);
/* is this valid? see atl1_setup_mac_ctrl() */ netdev->features |= NETIF_F_RXCSUM;
diff --git a/drivers/net/ethernet/broadcom/bcmsysport.c b/drivers/net/ethernet/broadcom/bcmsysport.c index 47fc8e6963d5..05a0c169e418 100644 --- a/drivers/net/ethernet/broadcom/bcmsysport.c +++ b/drivers/net/ethernet/broadcom/bcmsysport.c @@ -12,6 +12,7 @@ #include <linux/module.h> #include <linux/kernel.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/dsa/brcm.h> #include <linux/etherdevice.h> #include <linux/platform_device.h> @@ -153,17 +154,25 @@ static void bcm_sysport_set_rx_csum(struct net_device *dev, rxchk_writel(priv, reg, RXCHK_CONTROL); }
+static DECLARE_NETDEV_FEATURE_SET(bcm_sysport_tx_csum_feature_set,
NETIF_F_IP_CSUM_BIT,
NETIF_F_IPV6_CSUM_BIT,
NETIF_F_HW_VLAN_CTAG_TX_BIT);
static void bcm_sysport_set_tx_csum(struct net_device *dev, netdev_features_t wanted) { struct bcm_sysport_priv *priv = netdev_priv(dev);
netdev_features_t tx_csum_features; u32 reg;
netdev_features_zero(&tx_csum_features);
netdev_features_set_array(&bcm_sysport_tx_csum_feature_set,
&tx_csum_features);
/* Hardware transmit checksum requires us to enable the Transmit status
- block prepended to the packet contents
*/
- priv->tsb_en = !!(wanted & (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
NETIF_F_HW_VLAN_CTAG_TX));
- priv->tsb_en = !!(wanted & tx_csum_features); reg = tdma_readl(priv, TDMA_CONTROL); if (priv->tsb_en) reg |= tdma_control_bit(priv, TSB_EN);
@@ -2453,6 +2462,13 @@ static const struct of_device_id bcm_sysport_of_match[] = { }; MODULE_DEVICE_TABLE(of, bcm_sysport_of_match);
+DECLARE_NETDEV_FEATURE_SET(bcm_feature_set,
NETIF_F_RXCSUM_BIT,
NETIF_F_HIGHDMA_BIT,
NETIF_F_IP_CSUM_BIT,
NETIF_F_IPV6_CSUM_BIT,
NETIF_F_HW_VLAN_CTAG_TX_BIT);
- static int bcm_sysport_probe(struct platform_device *pdev) { const struct bcm_sysport_hw_params *params;
@@ -2566,9 +2582,7 @@ static int bcm_sysport_probe(struct platform_device *pdev) dev->netdev_ops = &bcm_sysport_netdev_ops; netif_napi_add(dev, &priv->napi, bcm_sysport_poll, 64);
- dev->features |= NETIF_F_RXCSUM | NETIF_F_HIGHDMA |
NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
NETIF_F_HW_VLAN_CTAG_TX;
- netdev_active_features_set_array(dev, &bcm_feature_set); dev->hw_features |= dev->features; dev->vlan_features |= dev->features; dev->max_mtu = UMAC_MAX_MTU_SIZE;
diff --git a/drivers/net/ethernet/broadcom/bgmac.c b/drivers/net/ethernet/broadcom/bgmac.c index 2dfc1e32bbb3..523cadd48669 100644 --- a/drivers/net/ethernet/broadcom/bgmac.c +++ b/drivers/net/ethernet/broadcom/bgmac.c @@ -13,6 +13,7 @@ #include <linux/etherdevice.h> #include <linux/interrupt.h> #include <linux/bcm47xx_nvram.h> +#include <linux/netdev_features_helper.h> #include <linux/phy.h> #include <linux/phy_fixed.h> #include <net/dsa.h> @@ -1485,6 +1486,11 @@ struct bgmac *bgmac_alloc(struct device *dev) } EXPORT_SYMBOL_GPL(bgmac_alloc);
+static DECLARE_NETDEV_FEATURE_SET(bgmac_feature_set,
NETIF_F_SG_BIT,
NETIF_F_IP_CSUM_BIT,
NETIF_F_IPV6_CSUM_BIT);
- int bgmac_enet_probe(struct bgmac *bgmac) { struct net_device *net_dev = bgmac->net_dev;
@@ -1535,7 +1541,8 @@ int bgmac_enet_probe(struct bgmac *bgmac) goto err_dma_free; }
- net_dev->features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
- netdev_active_features_zero(net_dev);
- netdev_active_features_set_array(net_dev, &bgmac_feature_set); net_dev->hw_features = net_dev->features; net_dev->vlan_features = net_dev->features;
diff --git a/drivers/net/ethernet/broadcom/bnx2.c b/drivers/net/ethernet/broadcom/bnx2.c index b97ed9b5f685..0e779e5dee9a 100644 --- a/drivers/net/ethernet/broadcom/bnx2.c +++ b/drivers/net/ethernet/broadcom/bnx2.c @@ -25,6 +25,7 @@ #include <linux/interrupt.h> #include <linux/pci.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/etherdevice.h> #include <linux/skbuff.h> #include <linux/dma-mapping.h> @@ -8544,6 +8545,14 @@ static const struct net_device_ops bnx2_netdev_ops = { #endif };
+static DECLARE_NETDEV_FEATURE_SET(bnx2_hw_feature_set,
NETIF_F_IP_CSUM_BIT,
NETIF_F_SG_BIT,
NETIF_F_TSO_BIT,
NETIF_F_TSO_ECN_BIT,
NETIF_F_RXHASH_BIT,
NETIF_F_RXCSUM_BIT);
- static int bnx2_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) {
@@ -8580,9 +8589,8 @@ bnx2_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
eth_hw_addr_set(dev, bp->mac_addr);
- dev->hw_features = NETIF_F_IP_CSUM | NETIF_F_SG |
NETIF_F_TSO | NETIF_F_TSO_ECN |
NETIF_F_RXHASH | NETIF_F_RXCSUM;
netdev_hw_features_zero(dev);
netdev_hw_features_set_array(dev, &bnx2_hw_feature_set);
if (BNX2_CHIP(bp) == BNX2_CHIP_5709) dev->hw_features |= NETIF_F_IPV6_CSUM | NETIF_F_TSO6;
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index 962253db25b8..845d31294667 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c @@ -32,6 +32,7 @@ #include <linux/aer.h> #include <linux/init.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/etherdevice.h> #include <linux/skbuff.h> #include <linux/dma-mapping.h> @@ -13045,6 +13046,55 @@ static void bnx2x_disable_pcie_error_reporting(struct bnx2x *bp) } }
+static DECLARE_NETDEV_FEATURE_SET(bnx2x_hw_feature_set,
NETIF_F_SG_BIT,
NETIF_F_IP_CSUM_BIT,
NETIF_F_IPV6_CSUM_BIT,
NETIF_F_TSO_BIT,
NETIF_F_TSO_ECN_BIT,
NETIF_F_TSO6_BIT,
NETIF_F_RXCSUM_BIT,
NETIF_F_LRO_BIT,
NETIF_F_GRO_BIT,
NETIF_F_GRO_HW_BIT,
NETIF_F_RXHASH_BIT,
NETIF_F_HW_VLAN_CTAG_TX_BIT);
+static DECLARE_NETDEV_FEATURE_SET(bnx2x_hw_gso_feature_set,
NETIF_F_GSO_GRE_BIT,
NETIF_F_GSO_GRE_CSUM_BIT,
NETIF_F_GSO_IPXIP4_BIT,
NETIF_F_GSO_UDP_TUNNEL_BIT,
NETIF_F_GSO_UDP_TUNNEL_CSUM_BIT,
NETIF_F_GSO_PARTIAL_BIT);
+static DECLARE_NETDEV_FEATURE_SET(bnx2x_hw_enc_feature_set,
NETIF_F_IP_CSUM_BIT,
NETIF_F_IPV6_CSUM_BIT,
NETIF_F_SG_BIT,
NETIF_F_TSO_BIT,
NETIF_F_TSO_ECN_BIT,
NETIF_F_TSO6_BIT,
NETIF_F_GSO_IPXIP4_BIT,
NETIF_F_GSO_GRE_BIT,
NETIF_F_GSO_GRE_CSUM_BIT,
NETIF_F_GSO_UDP_TUNNEL_BIT,
NETIF_F_GSO_UDP_TUNNEL_CSUM_BIT,
NETIF_F_GSO_PARTIAL_BIT);
+static DECLARE_NETDEV_FEATURE_SET(bnx2x_gso_partial_feature_set,
NETIF_F_GSO_GRE_CSUM_BIT,
NETIF_F_GSO_UDP_TUNNEL_CSUM_BIT);
+static DECLARE_NETDEV_FEATURE_SET(bnx2x_vlan_feature_set,
NETIF_F_SG_BIT,
NETIF_F_IP_CSUM_BIT,
NETIF_F_IPV6_CSUM_BIT,
NETIF_F_TSO_BIT,
NETIF_F_TSO_ECN_BIT,
NETIF_F_TSO6_BIT,
NETIF_F_HIGHDMA_BIT);
- static int bnx2x_init_dev(struct bnx2x *bp, struct pci_dev *pdev, struct net_device *dev, unsigned long board_type) {
@@ -13197,34 +13247,23 @@ static int bnx2x_init_dev(struct bnx2x *bp, struct pci_dev *pdev,
dev->priv_flags |= IFF_UNICAST_FLT;
- dev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
NETIF_F_TSO | NETIF_F_TSO_ECN | NETIF_F_TSO6 |
NETIF_F_RXCSUM | NETIF_F_LRO | NETIF_F_GRO | NETIF_F_GRO_HW |
NETIF_F_RXHASH | NETIF_F_HW_VLAN_CTAG_TX;
- netdev_hw_features_zero(dev);
- netdev_hw_features_set_array(dev, &bnx2x_hw_feature_set); if (!chip_is_e1x) {
dev->hw_features |= NETIF_F_GSO_GRE | NETIF_F_GSO_GRE_CSUM |
NETIF_F_GSO_IPXIP4 |
NETIF_F_GSO_UDP_TUNNEL |
NETIF_F_GSO_UDP_TUNNEL_CSUM |
NETIF_F_GSO_PARTIAL;
dev->hw_enc_features =
NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | NETIF_F_SG |
NETIF_F_TSO | NETIF_F_TSO_ECN | NETIF_F_TSO6 |
NETIF_F_GSO_IPXIP4 |
NETIF_F_GSO_GRE | NETIF_F_GSO_GRE_CSUM |
NETIF_F_GSO_UDP_TUNNEL | NETIF_F_GSO_UDP_TUNNEL_CSUM |
NETIF_F_GSO_PARTIAL;
dev->gso_partial_features = NETIF_F_GSO_GRE_CSUM |
NETIF_F_GSO_UDP_TUNNEL_CSUM;
netdev_hw_features_set_array(dev, &bnx2x_hw_gso_feature_set);
netdev_hw_enc_features_zero(dev);
netdev_hw_enc_features_set_array(dev, &bnx2x_hw_enc_feature_set);
netdev_gso_partial_features_zero(dev);
netdev_gso_partial_features_set_array(dev, &bnx2x_gso_partial_feature_set);
if (IS_PF(bp)) dev->udp_tunnel_nic_info = &bnx2x_udp_tunnels; }
- dev->vlan_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
NETIF_F_TSO | NETIF_F_TSO_ECN | NETIF_F_TSO6 | NETIF_F_HIGHDMA;
netdev_vlan_features_zero(dev);
netdev_vlan_features_set_array(dev, &bnx2x_vlan_feature_set);
if (IS_PF(bp)) { if (chip_is_e1x)
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c index ba0f1ffac507..825bf829b36a 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c @@ -20,6 +20,7 @@ #include <linux/interrupt.h> #include <linux/pci.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/etherdevice.h> #include <linux/skbuff.h> #include <linux/dma-mapping.h> @@ -13517,6 +13518,38 @@ void bnxt_print_device_info(struct bnxt *bp) pcie_print_link_status(bp->pdev); }
+static DECLARE_NETDEV_FEATURE_SET(bnxt_hw_feature_set,
NETIF_F_IP_CSUM_BIT,
NETIF_F_IPV6_CSUM_BIT,
NETIF_F_SG_BIT,
NETIF_F_TSO_BIT,
NETIF_F_TSO6_BIT,
NETIF_F_GSO_UDP_TUNNEL_BIT,
NETIF_F_GSO_GRE_BIT,
NETIF_F_GSO_IPXIP4_BIT,
NETIF_F_GSO_UDP_TUNNEL_CSUM_BIT,
NETIF_F_GSO_GRE_CSUM_BIT,
NETIF_F_GSO_PARTIAL_BIT,
NETIF_F_RXHASH_BIT,
NETIF_F_RXCSUM_BIT,
NETIF_F_GRO_BIT);
+static DECLARE_NETDEV_FEATURE_SET(bnxt_hw_enc_feature_set,
NETIF_F_IP_CSUM_BIT,
NETIF_F_IPV6_CSUM_BIT,
NETIF_F_SG_BIT,
NETIF_F_TSO_BIT,
NETIF_F_TSO6_BIT,
NETIF_F_GSO_UDP_TUNNEL_BIT,
NETIF_F_GSO_GRE_BIT,
NETIF_F_GSO_UDP_TUNNEL_CSUM_BIT,
NETIF_F_GSO_GRE_CSUM_BIT,
NETIF_F_GSO_IPXIP4_BIT,
NETIF_F_GSO_PARTIAL_BIT);
+static DECLARE_NETDEV_FEATURE_SET(bnxt_gso_partial_feature_set,
NETIF_F_GSO_UDP_TUNNEL_CSUM_BIT,
NETIF_F_GSO_GRE_CSUM_BIT);
- static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) { struct net_device *dev;
@@ -13594,27 +13627,18 @@ static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) goto init_err_pci_clean; }
- dev->hw_features = NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | NETIF_F_SG |
NETIF_F_TSO | NETIF_F_TSO6 |
NETIF_F_GSO_UDP_TUNNEL | NETIF_F_GSO_GRE |
NETIF_F_GSO_IPXIP4 |
NETIF_F_GSO_UDP_TUNNEL_CSUM | NETIF_F_GSO_GRE_CSUM |
NETIF_F_GSO_PARTIAL | NETIF_F_RXHASH |
NETIF_F_RXCSUM | NETIF_F_GRO;
netdev_hw_features_zero(dev);
netdev_hw_features_set_array(dev, &bnxt_hw_feature_set);
if (BNXT_SUPPORTS_TPA(bp)) dev->hw_features |= NETIF_F_LRO;
- dev->hw_enc_features =
NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | NETIF_F_SG |
NETIF_F_TSO | NETIF_F_TSO6 |
NETIF_F_GSO_UDP_TUNNEL | NETIF_F_GSO_GRE |
NETIF_F_GSO_UDP_TUNNEL_CSUM | NETIF_F_GSO_GRE_CSUM |
NETIF_F_GSO_IPXIP4 | NETIF_F_GSO_PARTIAL;
- netdev_hw_enc_features_zero(dev);
- netdev_hw_enc_features_set_array(dev, &bnxt_hw_enc_feature_set); dev->udp_tunnel_nic_info = &bnxt_udp_tunnels;
- dev->gso_partial_features = NETIF_F_GSO_UDP_TUNNEL_CSUM |
NETIF_F_GSO_GRE_CSUM;
- netdev_gso_partial_features_zero(dev);
- netdev_gso_partial_features_set_array(dev, &bnxt_gso_partial_feature_set); dev->vlan_features = dev->hw_features | NETIF_F_HIGHDMA; if (bp->fw_cap & BNXT_FW_CAP_VLAN_RX_STRIP) dev->hw_features |= BNXT_HW_FEATURE_VLAN_ALL_RX;
diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c index 8309fb993cdb..0d41ae12e262 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c @@ -28,6 +28,7 @@ #include <linux/mii.h> #include <linux/ethtool.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/inetdevice.h> #include <linux/etherdevice.h> #include <linux/skbuff.h> @@ -3969,6 +3970,12 @@ static const struct of_device_id bcmgenet_match[] = { }; MODULE_DEVICE_TABLE(of, bcmgenet_match);
+static DECLARE_NETDEV_FEATURE_SET(bcmgenet_feature_set,
NETIF_F_SG_BIT,
NETIF_F_HIGHDMA_BIT,
NETIF_F_HW_CSUM_BIT,
NETIF_F_RXCSUM_BIT);
- static int bcmgenet_probe(struct platform_device *pdev) { struct bcmgenet_platform_data *pd = pdev->dev.platform_data;
@@ -4025,8 +4032,7 @@ static int bcmgenet_probe(struct platform_device *pdev) priv->msg_enable = netif_msg_init(-1, GENET_MSG_DEFAULT);
/* Set default features */
- dev->features |= NETIF_F_SG | NETIF_F_HIGHDMA | NETIF_F_HW_CSUM |
NETIF_F_RXCSUM;
- netdev_active_features_set_array(dev, &bcmgenet_feature_set); dev->hw_features |= dev->features; dev->vlan_features |= dev->features;
diff --git a/drivers/net/ethernet/brocade/bna/bnad.c b/drivers/net/ethernet/brocade/bna/bnad.c index 29dd0f93d6c0..786df1e64947 100644 --- a/drivers/net/ethernet/brocade/bna/bnad.c +++ b/drivers/net/ethernet/brocade/bna/bnad.c @@ -10,6 +10,7 @@ */ #include <linux/bitops.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/skbuff.h> #include <linux/etherdevice.h> #include <linux/in.h> @@ -3417,22 +3418,40 @@ static const struct net_device_ops bnad_netdev_ops = { #endif };
+static DECLARE_NETDEV_FEATURE_SET(bnad_hw_feature_set,
NETIF_F_SG_BIT,
NETIF_F_RXCSUM_BIT,
NETIF_F_IP_CSUM_BIT,
NETIF_F_IPV6_CSUM_BIT,
NETIF_F_TSO_BIT,
NETIF_F_TSO6_BIT,
NETIF_F_HW_VLAN_CTAG_TX_BIT,
NETIF_F_HW_VLAN_CTAG_RX_BIT);
+static DECLARE_NETDEV_FEATURE_SET(bnad_vlan_feature_set,
NETIF_F_SG_BIT,
NETIF_F_HIGHDMA_BIT,
NETIF_F_IP_CSUM_BIT,
NETIF_F_IPV6_CSUM_BIT,
NETIF_F_TSO_BIT,
NETIF_F_TSO6_BIT);
+static DECLARE_NETDEV_FEATURE_SET(bnad_feature_set,
NETIF_F_HW_VLAN_CTAG_FILTER_BIT,
NETIF_F_HIGHDMA_BIT);
- static void bnad_netdev_init(struct bnad *bnad) { struct net_device *netdev = bnad->netdev;
- netdev->hw_features = NETIF_F_SG | NETIF_F_RXCSUM |
NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_HW_VLAN_CTAG_TX |
NETIF_F_HW_VLAN_CTAG_RX;
- netdev->vlan_features = NETIF_F_SG | NETIF_F_HIGHDMA |
NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
NETIF_F_TSO | NETIF_F_TSO6;
- netdev_hw_features_zero(netdev);
- netdev_hw_features_set_array(netdev, &bnad_hw_feature_set);
- netdev_vlan_features_zero(netdev);
- netdev_vlan_features_set_array(netdev, &bnad_vlan_feature_set);
- netdev->features |= netdev->hw_features | NETIF_F_HW_VLAN_CTAG_FILTER |
NETIF_F_HIGHDMA;
netdev->features |= netdev->hw_features;
netdev_active_features_set_array(netdev, &bnad_feature_set);
netdev->mem_start = bnad->mmio_start; netdev->mem_end = bnad->mmio_start + bnad->mmio_len - 1;
diff --git a/drivers/net/ethernet/calxeda/xgmac.c b/drivers/net/ethernet/calxeda/xgmac.c index 1281d1565ef8..415f61527650 100644 --- a/drivers/net/ethernet/calxeda/xgmac.c +++ b/drivers/net/ethernet/calxeda/xgmac.c @@ -14,6 +14,7 @@ #include <linux/if.h> #include <linux/crc32.h> #include <linux/dma-mapping.h> +#include <linux/netdev_features_helper.h> #include <linux/slab.h>
/* XGMAC Register definitions */ @@ -1682,6 +1683,14 @@ static const struct ethtool_ops xgmac_ethtool_ops = { .get_link_ksettings = xgmac_ethtool_get_link_ksettings, };
+static DECLARE_NETDEV_FEATURE_SET(xgmac_hw_feature_set,
NETIF_F_SG_BIT,
NETIF_F_HIGHDMA_BIT);
+static DECLARE_NETDEV_FEATURE_SET(xgmac_csum_feature_set,
NETIF_F_IP_CSUM_BIT,
NETIF_F_IPV6_CSUM_BIT,
NETIF_F_RXCSUM_BIT);
- /**
- xgmac_probe
- @pdev: platform device pointer
@@ -1774,10 +1783,10 @@ static int xgmac_probe(struct platform_device *pdev) if (device_can_wakeup(priv->device)) priv->wolopts = WAKE_MAGIC; /* Magic Frame as default */
- ndev->hw_features = NETIF_F_SG | NETIF_F_HIGHDMA;
- netdev_hw_features_zero(ndev);
- netdev_hw_features_set_array(ndev, &xgmac_hw_feature_set); if (readl(priv->base + XGMAC_DMA_HW_FEATURE) & DMA_HW_FEAT_TXCOESEL)
ndev->hw_features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
NETIF_F_RXCSUM;
ndev->features |= ndev->hw_features; ndev->priv_flags |= IFF_UNICAST_FLT;netdev_hw_features_set_array(ndev, &xgmac_csum_feature_set);
diff --git a/drivers/net/ethernet/cavium/liquidio/lio_main.c b/drivers/net/ethernet/cavium/liquidio/lio_main.c index bee35ce60171..9c9c8dee0c7b 100644 --- a/drivers/net/ethernet/cavium/liquidio/lio_main.c +++ b/drivers/net/ethernet/cavium/liquidio/lio_main.c @@ -19,6 +19,7 @@ #include <linux/interrupt.h> #include <linux/pci.h> #include <linux/firmware.h> +#include <linux/netdev_features_helper.h> #include <net/vxlan.h> #include <linux/kthread.h> #include "liquidio_common.h" @@ -3317,6 +3318,27 @@ static int lio_nic_info(struct octeon_recv_info *recv_info, void *buf) return 0; }
+static DECLARE_NETDEV_FEATURE_SET(liquidio_feature_set,
NETIF_F_HIGHDMA_BIT,
NETIF_F_IP_CSUM_BIT,
NETIF_F_IPV6_CSUM_BIT,
NETIF_F_SG_BIT,
NETIF_F_RXCSUM_BIT,
NETIF_F_GRO_BIT,
NETIF_F_TSO_BIT,
NETIF_F_TSO6_BIT,
NETIF_F_LRO_BIT);
+static DECLARE_NETDEV_FEATURE_SET(liquidio_enc_feature_set,
NETIF_F_IP_CSUM_BIT,
NETIF_F_IPV6_CSUM_BIT,
NETIF_F_GSO_UDP_TUNNEL_BIT,
NETIF_F_HW_CSUM_BIT,
NETIF_F_SG_BIT,
NETIF_F_RXCSUM_BIT,
NETIF_F_TSO_BIT,
NETIF_F_TSO6_BIT,
NETIF_F_LRO_BIT);
- /**
- setup_nic_devices - Setup network interfaces
- @octeon_dev: octeon device
@@ -3555,26 +3577,18 @@ static int setup_nic_devices(struct octeon_device *octeon_dev)
if (OCTEON_CN23XX_PF(octeon_dev) || OCTEON_CN6XXX(octeon_dev)) {
lio->dev_capability = NETIF_F_HIGHDMA
| NETIF_F_IP_CSUM
| NETIF_F_IPV6_CSUM
| NETIF_F_SG | NETIF_F_RXCSUM
| NETIF_F_GRO
| NETIF_F_TSO | NETIF_F_TSO6
| NETIF_F_LRO;
netdev_features_zero(&lio->dev_capability);
netdev_features_set_array(&liquidio_feature_set,
&lio->dev_capability);
} netif_set_tso_max_size(netdev, OCTNIC_GSO_MAX_SIZE);
/* Copy of transmit encapsulation capabilities:
- TSO, TSO6, Checksums for this device
*/
lio->enc_dev_capability = NETIF_F_IP_CSUM
| NETIF_F_IPV6_CSUM
| NETIF_F_GSO_UDP_TUNNEL
| NETIF_F_HW_CSUM | NETIF_F_SG
| NETIF_F_RXCSUM
| NETIF_F_TSO | NETIF_F_TSO6
| NETIF_F_LRO;
netdev_features_zero(&lio->enc_dev_capability);
netdev_features_set_array(&liquidio_enc_feature_set,
&lio->enc_dev_capability);
netdev->hw_enc_features = (lio->enc_dev_capability & ~NETIF_F_LRO);
diff --git a/drivers/net/ethernet/cavium/liquidio/lio_vf_main.c b/drivers/net/ethernet/cavium/liquidio/lio_vf_main.c index ac196883f07e..9e0c176ea7af 100644 --- a/drivers/net/ethernet/cavium/liquidio/lio_vf_main.c +++ b/drivers/net/ethernet/cavium/liquidio/lio_vf_main.c @@ -18,6 +18,7 @@ #include <linux/module.h> #include <linux/interrupt.h> #include <linux/pci.h> +#include <linux/netdev_features_helper.h> #include <net/vxlan.h> #include "liquidio_common.h" #include "octeon_droq.h" @@ -1926,6 +1927,27 @@ static int lio_nic_info(struct octeon_recv_info *recv_info, void *buf) return 0; }
+static DECLARE_NETDEV_FEATURE_SET(lio_feature_set,
NETIF_F_HIGHDMA_BIT,
NETIF_F_IP_CSUM_BIT,
NETIF_F_IPV6_CSUM_BIT,
NETIF_F_SG_BIT,
NETIF_F_RXCSUM_BIT,
NETIF_F_TSO_BIT,
NETIF_F_TSO6_BIT,
NETIF_F_GRO_BIT,
NETIF_F_LRO_BIT);
+static DECLARE_NETDEV_FEATURE_SET(lio_enc_feature_set,
NETIF_F_IP_CSUM_BIT,
NETIF_F_IPV6_CSUM_BIT,
NETIF_F_GSO_UDP_TUNNEL_BIT,
NETIF_F_HW_CSUM_BIT,
NETIF_F_SG_BIT,
NETIF_F_RXCSUM_BIT,
NETIF_F_TSO_BIT,
NETIF_F_TSO6_BIT,
NETIF_F_LRO_BIT);
- /**
- setup_nic_devices - Setup network interfaces
- @octeon_dev: octeon device
@@ -2088,24 +2110,16 @@ static int setup_nic_devices(struct octeon_device *octeon_dev)
lio->msg_enable = netif_msg_init(debug, DEFAULT_MSG_ENABLE);
lio->dev_capability = NETIF_F_HIGHDMA
| NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM
| NETIF_F_SG | NETIF_F_RXCSUM
| NETIF_F_TSO | NETIF_F_TSO6
| NETIF_F_GRO
| NETIF_F_LRO;
netdev_features_zero(&lio->dev_capability);
netdev_features_set_array(&lio_feature_set, &lio->dev_capability);
netif_set_tso_max_size(netdev, OCTNIC_GSO_MAX_SIZE);
/* Copy of transmit encapsulation capabilities:
- TSO, TSO6, Checksums for this device
*/
lio->enc_dev_capability = NETIF_F_IP_CSUM
| NETIF_F_IPV6_CSUM
| NETIF_F_GSO_UDP_TUNNEL
| NETIF_F_HW_CSUM | NETIF_F_SG
| NETIF_F_RXCSUM
| NETIF_F_TSO | NETIF_F_TSO6
| NETIF_F_LRO;
netdev_features_zero(&lio->enc_dev_capability);
netdev_features_set_array(&lio_enc_feature_set,
&lio->enc_dev_capability);
netdev->hw_enc_features = (lio->enc_dev_capability & ~NETIF_F_LRO);
diff --git a/drivers/net/ethernet/cavium/liquidio/octeon_network.h b/drivers/net/ethernet/cavium/liquidio/octeon_network.h index ebe56bd8849b..61e5e5782f5b 100644 --- a/drivers/net/ethernet/cavium/liquidio/octeon_network.h +++ b/drivers/net/ethernet/cavium/liquidio/octeon_network.h @@ -147,13 +147,13 @@ struct lio { u32 msg_enable;
/** Copy of Interface capabilities: TSO, TSO6, LRO, Chescksums . */
- u64 dev_capability;
netdev_features_t dev_capability;
/* Copy of transmit encapsulation capabilities:
- TSO, TSO6, Checksums for this device for Kernel
- 3.10.0 onwards
*/
- u64 enc_dev_capability;
netdev_features_t enc_dev_capability;
/** Copy of beacaon reg in phy */ u32 phy_beacon_val;
diff --git a/drivers/net/ethernet/cavium/thunder/nicvf_main.c b/drivers/net/ethernet/cavium/thunder/nicvf_main.c index 768ea426d49f..c6923ecabb63 100644 --- a/drivers/net/ethernet/cavium/thunder/nicvf_main.c +++ b/drivers/net/ethernet/cavium/thunder/nicvf_main.c @@ -7,6 +7,7 @@ #include <linux/interrupt.h> #include <linux/pci.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/if_vlan.h> #include <linux/etherdevice.h> #include <linux/ethtool.h> @@ -2092,6 +2093,22 @@ static const struct net_device_ops nicvf_netdev_ops = { .ndo_set_rx_mode = nicvf_set_rx_mode, };
+static DECLARE_NETDEV_FEATURE_SET(nicvf_hw_feature_set,
NETIF_F_RXCSUM_BIT,
NETIF_F_SG_BIT,
NETIF_F_TSO_BIT,
NETIF_F_GRO_BIT,
NETIF_F_TSO6_BIT,
NETIF_F_IP_CSUM_BIT,
NETIF_F_IPV6_CSUM_BIT,
NETIF_F_HW_VLAN_CTAG_RX_BIT);
+static DECLARE_NETDEV_FEATURE_SET(nicvf_vlan_feature_set,
NETIF_F_SG_BIT,
NETIF_F_IP_CSUM_BIT,
NETIF_F_IPV6_CSUM_BIT,
NETIF_F_TSO_BIT,
NETIF_F_TSO6_BIT);
- static int nicvf_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { struct device *dev = &pdev->dev;
@@ -2203,18 +2220,16 @@ static int nicvf_probe(struct pci_dev *pdev, const struct pci_device_id *ent) if (err) goto err_unregister_interrupts;
- netdev->hw_features = (NETIF_F_RXCSUM | NETIF_F_SG |
NETIF_F_TSO | NETIF_F_GRO | NETIF_F_TSO6 |
NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
NETIF_F_HW_VLAN_CTAG_RX);
netdev_hw_features_zero(netdev);
netdev_hw_features_set_array(netdev, &nicvf_hw_feature_set);
netdev->hw_features |= NETIF_F_RXHASH;
netdev->features |= netdev->hw_features; netdev->hw_features |= NETIF_F_LOOPBACK;
- netdev->vlan_features = NETIF_F_SG | NETIF_F_IP_CSUM |
NETIF_F_IPV6_CSUM | NETIF_F_TSO | NETIF_F_TSO6;
netdev_vlan_features_zero(netdev);
netdev_hw_features_set_array(netdev, &nicvf_vlan_feature_set);
netdev->netdev_ops = &nicvf_netdev_ops; netdev->watchdog_timeo = NICVF_TX_TIMEOUT;
diff --git a/drivers/net/ethernet/chelsio/cxgb/cxgb2.c b/drivers/net/ethernet/chelsio/cxgb/cxgb2.c index f4054d2553ea..44404b711e09 100644 --- a/drivers/net/ethernet/chelsio/cxgb/cxgb2.c +++ b/drivers/net/ethernet/chelsio/cxgb/cxgb2.c @@ -39,6 +39,7 @@ #include <linux/module.h> #include <linux/pci.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/etherdevice.h> #include <linux/if_vlan.h> #include <linux/mii.h> @@ -942,6 +943,18 @@ static const struct net_device_ops cxgb_netdev_ops = { #endif };
+static DECLARE_NETDEV_FEATURE_SET(cxgb_hw_feature_set,
NETIF_F_SG_BIT,
NETIF_F_IP_CSUM_BIT,
NETIF_F_RXCSUM_BIT);
+static DECLARE_NETDEV_FEATURE_SET(cxgb_feature_set,
NETIF_F_SG_BIT,
NETIF_F_IP_CSUM_BIT,
NETIF_F_RXCSUM_BIT,
NETIF_F_LLTX_BIT,
NETIF_F_HIGHDMA_BIT);
- static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent) { unsigned long mmio_start, mmio_len;
@@ -1031,10 +1044,8 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent) netdev->mem_start = mmio_start; netdev->mem_end = mmio_start + mmio_len - 1; netdev->ml_priv = adapter;
netdev->hw_features |= NETIF_F_SG | NETIF_F_IP_CSUM |
NETIF_F_RXCSUM;
netdev->features |= NETIF_F_SG | NETIF_F_IP_CSUM |
NETIF_F_RXCSUM | NETIF_F_LLTX | NETIF_F_HIGHDMA;
netdev_hw_features_set_array(netdev, &cxgb_hw_feature_set);
netdev_active_features_set_array(netdev, &cxgb_feature_set);
if (vlan_tso_capable(adapter)) { netdev->features |=
diff --git a/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c b/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c index 174b1e156669..80f65f491b3f 100644 --- a/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c +++ b/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c @@ -37,6 +37,7 @@ #include <linux/pci.h> #include <linux/dma-mapping.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/etherdevice.h> #include <linux/if_vlan.h> #include <linux/mdio.h> @@ -3199,15 +3200,29 @@ static void cxgb3_init_iscsi_mac(struct net_device *dev) pi->iscsic.mac_addr[3] |= 0x80; }
-#define TSO_FLAGS (NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_TSO_ECN) -#define VLAN_FEAT (NETIF_F_SG | NETIF_F_IP_CSUM | TSO_FLAGS | \
NETIF_F_IPV6_CSUM | NETIF_F_HIGHDMA)
+static DECLARE_NETDEV_FEATURE_SET(cxgb_vlan_feature_set,
NETIF_F_SG_BIT,
NETIF_F_IP_CSUM_BIT,
NETIF_F_TSO_BIT,
NETIF_F_TSO6_BIT,
NETIF_F_TSO_ECN_BIT,
NETIF_F_IPV6_CSUM_BIT,
NETIF_F_HIGHDMA_BIT);
+static DECLARE_NETDEV_FEATURE_SET(cxgb_hw_feature_set,
NETIF_F_SG_BIT,
NETIF_F_IP_CSUM_BIT,
NETIF_F_TSO_BIT,
NETIF_F_RXCSUM_BIT,
NETIF_F_HW_VLAN_CTAG_RX_BIT);
static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent) { int i, err; resource_size_t mmio_start, mmio_len; const struct adapter_info *ai; struct adapter *adapter = NULL;
netdev_features_t vlan_feat; struct port_info *pi;
if (!cxgb3_wq) {
@@ -3303,11 +3318,13 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent) netdev->irq = pdev->irq; netdev->mem_start = mmio_start; netdev->mem_end = mmio_start + mmio_len - 1;
netdev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM |
NETIF_F_TSO | NETIF_F_RXCSUM | NETIF_F_HW_VLAN_CTAG_RX;
netdev_hw_features_zero(netdev);
netdev->features |= netdev->hw_features | NETIF_F_HW_VLAN_CTAG_TX;netdev_hw_features_set_array(netdev, &cxgb_hw_feature_set);
netdev->vlan_features |= netdev->features & VLAN_FEAT;
netdev_features_zero(&vlan_feat);
netdev_features_set_array(&cxgb_vlan_feature_set, &vlan_feat);
netdev->vlan_features |= netdev->features & vlan_feat;
netdev->features |= NETIF_F_HIGHDMA;
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c index d0061921529f..f40e6964de89 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c @@ -50,6 +50,7 @@ #include <linux/moduleparam.h> #include <linux/mutex.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/pci.h> #include <linux/aer.h> #include <linux/rtnetlink.h> @@ -6205,10 +6206,41 @@ static void free_some_resources(struct adapter *adapter) t4_fw_bye(adapter, adapter->pf); }
-#define TSO_FLAGS (NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_TSO_ECN | \
NETIF_F_GSO_UDP_L4)
-#define VLAN_FEAT (NETIF_F_SG | NETIF_F_IP_CSUM | TSO_FLAGS | \
NETIF_F_GRO | NETIF_F_IPV6_CSUM | NETIF_F_HIGHDMA)
+static DECLARE_NETDEV_FEATURE_SET(cxgb4_tso_feature_set,
NETIF_F_TSO_BIT,
NETIF_F_TSO6_BIT,
NETIF_F_TSO_ECN_BIT);
+static DECLARE_NETDEV_FEATURE_SET(cxgb4_vlan_feature_set,
NETIF_F_SG_BIT,
NETIF_F_IP_CSUM_BIT,
NETIF_F_GRO_BIT,
NETIF_F_IPV6_CSUM_BIT,
NETIF_F_HIGHDMA_BIT);
+static DECLARE_NETDEV_FEATURE_SET(cxgb4_hw_feature_set,
NETIF_F_SG_BIT,
NETIF_F_IP_CSUM_BIT,
NETIF_F_IPV6_CSUM_BIT,
NETIF_F_RXCSUM_BIT,
NETIF_F_RXHASH_BIT,
NETIF_F_GRO_BIT,
NETIF_F_HW_VLAN_CTAG_TX_BIT,
NETIF_F_HW_VLAN_CTAG_RX_BIT,
NETIF_F_HW_TC_BIT,
NETIF_F_NTUPLE_BIT,
NETIF_F_HIGHDMA_BIT);
+static DECLARE_NETDEV_FEATURE_SET(cxgb4_hw_enc_feature_set,
NETIF_F_IP_CSUM_BIT,
NETIF_F_IPV6_CSUM_BIT,
NETIF_F_RXCSUM_BIT,
NETIF_F_GSO_UDP_TUNNEL_BIT,
NETIF_F_GSO_UDP_TUNNEL_CSUM_BIT,
NETIF_F_TSO_BIT,
NETIF_F_TSO6_BIT);
+static DECLARE_NETDEV_FEATURE_SET(cxgb4_new_hw_feature_set,
NETIF_F_GSO_UDP_TUNNEL_BIT,
NETIF_F_GSO_UDP_TUNNEL_CSUM_BIT,
NETIF_F_HW_TLS_RECORD_BIT);
#define SEGMENT_SIZE 128
static int t4_get_chip_type(struct adapter *adap, int ver)
@@ -6598,6 +6630,8 @@ static const struct xfrmdev_ops cxgb4_xfrmdev_ops = {
static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent) {
- netdev_features_t vlan_features;
- netdev_features_t tso_features; struct net_device *netdev; struct adapter *adapter; static int adap_idx = 1;
@@ -6809,30 +6843,26 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent) pi->port_id = i; netdev->irq = pdev->irq;
netdev->hw_features = NETIF_F_SG | TSO_FLAGS |
NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
NETIF_F_RXCSUM | NETIF_F_RXHASH | NETIF_F_GRO |
NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX |
NETIF_F_HW_TC | NETIF_F_NTUPLE | NETIF_F_HIGHDMA;
netdev_features_zero(&tso_features);
netdev_features_set_array(&cxgb4_tso_feature_set, &tso_features);
netdev->hw_features = tso_features;
netdev_hw_features_set_array(netdev, &cxgb4_hw_feature_set);
if (chip_ver > CHELSIO_T5) {
netdev->hw_enc_features |= NETIF_F_IP_CSUM |
NETIF_F_IPV6_CSUM |
NETIF_F_RXCSUM |
NETIF_F_GSO_UDP_TUNNEL |
NETIF_F_GSO_UDP_TUNNEL_CSUM |
NETIF_F_TSO | NETIF_F_TSO6;
netdev_hw_enc_features_set_array(netdev,
&cxgb4_hw_enc_feature_set);
netdev->hw_features |= NETIF_F_GSO_UDP_TUNNEL |
NETIF_F_GSO_UDP_TUNNEL_CSUM |
NETIF_F_HW_TLS_RECORD;
netdev_hw_features_set_array(netdev,
&cxgb4_new_hw_feature_set); if (adapter->rawf_cnt) netdev->udp_tunnel_nic_info = &cxgb_udp_tunnels;
}
netdev->features |= netdev->hw_features;
netdev->vlan_features = netdev->features & VLAN_FEAT;
vlan_features = tso_features;
netdev_features_set_array(&cxgb4_vlan_feature_set, &vlan_features);
#if IS_ENABLED(CONFIG_CHELSIO_TLS_DEVICE) if (pi->adapter->params.crypto & FW_CAPS_CONFIG_TLS_HW) { netdev->hw_features |= NETIF_F_HW_TLS_TX;netdev->vlan_features = netdev->features & vlan_features;
diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c index c2822e635f89..2d6e1b42b36b 100644 --- a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c @@ -41,6 +41,7 @@ #include <linux/pci.h> #include <linux/dma-mapping.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/etherdevice.h> #include <linux/debugfs.h> #include <linux/ethtool.h> @@ -1921,9 +1922,26 @@ static void cxgb4vf_get_wol(struct net_device *dev, /*
- TCP Segmentation Offload flags which we support.
*/ -#define TSO_FLAGS (NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_TSO_ECN) -#define VLAN_FEAT (NETIF_F_SG | NETIF_F_IP_CSUM | TSO_FLAGS | \
NETIF_F_GRO | NETIF_F_IPV6_CSUM | NETIF_F_HIGHDMA)
+static DECLARE_NETDEV_FEATURE_SET(cxgb4vf_tso_feature_set,
NETIF_F_TSO_BIT,
NETIF_F_TSO6_BIT,
NETIF_F_TSO_ECN_BIT);
+static DECLARE_NETDEV_FEATURE_SET(cxgb4vf_vlan_feature_set,
NETIF_F_SG_BIT,
NETIF_F_IP_CSUM_BIT,
NETIF_F_GRO_BIT,
NETIF_F_IPV6_CSUM_BIT,
NETIF_F_HIGHDMA_BIT);
+static DECLARE_NETDEV_FEATURE_SET(cxgb4vf_hw_feature_set,
NETIF_F_SG_BIT,
NETIF_F_GRO_BIT,
NETIF_F_IP_CSUM_BIT,
NETIF_F_IPV6_CSUM_BIT,
NETIF_F_RXCSUM_BIT,
NETIF_F_HW_VLAN_CTAG_TX_BIT,
NETIF_F_HW_VLAN_CTAG_RX_BIT);
static const struct ethtool_ops cxgb4vf_ethtool_ops = { .supported_coalesce_params = ETHTOOL_COALESCE_RX_USECS |
@@ -2895,6 +2913,8 @@ static unsigned int cxgb4vf_get_port_mask(struct adapter *adapter) static int cxgb4vf_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) {
- netdev_features_t vlan_features;
- netdev_features_t tso_features; struct adapter *adapter; struct net_device *netdev; struct port_info *pi;
@@ -3067,11 +3087,16 @@ static int cxgb4vf_pci_probe(struct pci_dev *pdev, pi->xact_addr_filt = -1; netdev->irq = pdev->irq;
netdev->hw_features = NETIF_F_SG | TSO_FLAGS | NETIF_F_GRO |
NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | NETIF_F_RXCSUM |
NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX;
netdev_features_zero(&tso_features);
netdev_features_set_array(&cxgb4vf_tso_feature_set,
&tso_features);
netdev->hw_features = tso_features;
netdev->features = netdev->hw_features | NETIF_F_HIGHDMA;netdev_hw_features_set_array(netdev, &cxgb4vf_hw_feature_set);
netdev->vlan_features = netdev->features & VLAN_FEAT;
vlan_features = tso_features;
netdev_features_set_array(&cxgb4vf_vlan_feature_set,
&vlan_features);
netdev->vlan_features = netdev->features & vlan_features;
netdev->priv_flags |= IFF_UNICAST_FLT; netdev->min_mtu = 81;
diff --git a/drivers/net/ethernet/cirrus/ep93xx_eth.c b/drivers/net/ethernet/cirrus/ep93xx_eth.c index 21ba6e893072..8d631b2cba23 100644 --- a/drivers/net/ethernet/cirrus/ep93xx_eth.c +++ b/drivers/net/ethernet/cirrus/ep93xx_eth.c @@ -11,6 +11,7 @@ #include <linux/module.h> #include <linux/kernel.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/mii.h> #include <linux/etherdevice.h> #include <linux/ethtool.h> @@ -738,6 +739,10 @@ static const struct net_device_ops ep93xx_netdev_ops = { .ndo_set_mac_address = eth_mac_addr, };
+static DECLARE_NETDEV_FEATURE_SET(ep93xx_feature_set,
NETIF_F_SG_BIT,
NETIF_F_HW_CSUM_BIT);
- static struct net_device *ep93xx_dev_alloc(struct ep93xx_eth_data *data) { struct net_device *dev;
@@ -751,7 +756,7 @@ static struct net_device *ep93xx_dev_alloc(struct ep93xx_eth_data *data) dev->ethtool_ops = &ep93xx_ethtool_ops; dev->netdev_ops = &ep93xx_netdev_ops;
- dev->features |= NETIF_F_SG | NETIF_F_HW_CSUM;
netdev_active_features_set_array(dev, &ep93xx_feature_set);
return dev; }
diff --git a/drivers/net/ethernet/cisco/enic/enic_main.c b/drivers/net/ethernet/cisco/enic/enic_main.c index 372fb7b3a282..276fa370ce50 100644 --- a/drivers/net/ethernet/cisco/enic/enic_main.c +++ b/drivers/net/ethernet/cisco/enic/enic_main.c @@ -27,6 +27,7 @@ #include <linux/workqueue.h> #include <linux/pci.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/etherdevice.h> #include <linux/if.h> #include <linux/if_ether.h> @@ -2665,6 +2666,15 @@ static void enic_iounmap(struct enic *enic) iounmap(enic->bar[i].vaddr); }
+static DECLARE_NETDEV_FEATURE_SET(enic_hw_enc_feature_set,
NETIF_F_RXCSUM_BIT,
NETIF_F_TSO_BIT,
NETIF_F_TSO6_BIT,
NETIF_F_TSO_ECN_BIT,
NETIF_F_GSO_UDP_TUNNEL_BIT,
NETIF_F_HW_CSUM_BIT,
NETIF_F_GSO_UDP_TUNNEL_CSUM_BIT);
- static int enic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { struct device *dev = &pdev->dev;
@@ -2904,13 +2914,8 @@ static int enic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) u64 patch_level; u64 a1 = 0;
netdev->hw_enc_features |= NETIF_F_RXCSUM |
NETIF_F_TSO |
NETIF_F_TSO6 |
NETIF_F_TSO_ECN |
NETIF_F_GSO_UDP_TUNNEL |
NETIF_F_HW_CSUM |
NETIF_F_GSO_UDP_TUNNEL_CSUM;
netdev_hw_enc_features_set_array(netdev,
netdev->hw_features |= netdev->hw_enc_features; /* get bit mask from hw about supported offload bit level&enic_hw_enc_feature_set);
- BIT(0) = fw supports patch_level 0
diff --git a/drivers/net/ethernet/cortina/gemini.c b/drivers/net/ethernet/cortina/gemini.c index 9e6de2f968fa..d2b0296b426a 100644 --- a/drivers/net/ethernet/cortina/gemini.c +++ b/drivers/net/ethernet/cortina/gemini.c @@ -36,6 +36,7 @@ #include <linux/ethtool.h> #include <linux/tcp.h> #include <linux/u64_stats_sync.h> +#include <linux/netdev_features_helper.h>
#include <linux/in.h> #include <linux/ip.h> @@ -78,9 +79,16 @@ MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)"); GMAC0_SWTQ00_FIN_INT_BIT) #define GMAC0_IRQ4_8 (GMAC0_MIB_INT_BIT | GMAC0_RX_OVERRUN_INT_BIT)
-#define GMAC_OFFLOAD_FEATURES (NETIF_F_SG | NETIF_F_IP_CSUM | \
NETIF_F_IPV6_CSUM | NETIF_F_RXCSUM | \
NETIF_F_TSO | NETIF_F_TSO_ECN | NETIF_F_TSO6)
+static DECLARE_NETDEV_FEATURE_SET(gmac_offload_feature_set,
NETIF_F_SG_BIT,
NETIF_F_IP_CSUM_BIT,
NETIF_F_IPV6_CSUM_BIT,
NETIF_F_RXCSUM_BIT,
NETIF_F_TSO_BIT,
NETIF_F_TSO_ECN_BIT,
NETIF_F_TSO6_BIT);
+static netdev_features_t gmac_offload_features __ro_after_init; +#define GMAC_OFFLOAD_FEATURES gmac_offload_features
/**
- struct gmac_queue_page - page buffer per-page info
@@ -2610,6 +2618,12 @@ static struct platform_driver gemini_ethernet_driver = { .remove = gemini_ethernet_remove, };
+static void __init gmac_netdev_features_init(void) +{
- netdev_features_set_array(&gmac_offload_feature_set,
&gmac_offload_features);
+}
- static int __init gemini_ethernet_module_init(void) { int ret;
@@ -2624,6 +2638,8 @@ static int __init gemini_ethernet_module_init(void) return ret; }
- gmac_netdev_features_init();
- return 0; } module_init(gemini_ethernet_module_init);
diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c index 414362febbb9..964e7d6111df 100644 --- a/drivers/net/ethernet/emulex/benet/be_main.c +++ b/drivers/net/ethernet/emulex/benet/be_main.c @@ -18,6 +18,7 @@ #include <asm/div64.h> #include <linux/aer.h> #include <linux/if_bridge.h> +#include <linux/netdev_features_helper.h> #include <net/busy_poll.h> #include <net/vxlan.h>
@@ -3967,6 +3968,13 @@ static void be_cancel_err_detection(struct be_adapter *adapter) } }
+DECLARE_NETDEV_FEATURE_SET(be_hw_enc_feature_set,
NETIF_F_IP_CSUM_BIT,
NETIF_F_IPV6_CSUM_BIT,
NETIF_F_TSO_BIT,
NETIF_F_TSO6_BIT,
NETIF_F_GSO_UDP_TUNNEL_BIT);
- /* VxLAN offload Notes:
- The stack defines tunnel offload flags (hw_enc_features) for IP and doesn't
@@ -3999,9 +4007,7 @@ static int be_vxlan_set_port(struct net_device *netdev, unsigned int table, } adapter->vxlan_port = ti->port;
- netdev->hw_enc_features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
NETIF_F_TSO | NETIF_F_TSO6 |
NETIF_F_GSO_UDP_TUNNEL;
netdev_hw_enc_features_set_array(netdev, &be_hw_enc_feature_set);
dev_info(dev, "Enabled VxLAN offloads for UDP port %d\n", be16_to_cpu(ti->port));
@@ -5182,23 +5188,40 @@ static const struct net_device_ops be_netdev_ops = { .ndo_get_phys_port_id = be_get_phys_port_id, };
+static DECLARE_NETDEV_FEATURE_SET(be_hw_feature_set,
NETIF_F_SG_BIT,
NETIF_F_TSO_BIT,
NETIF_F_TSO6_BIT,
NETIF_F_GSO_UDP_TUNNEL_BIT,
NETIF_F_IP_CSUM_BIT,
NETIF_F_IPV6_CSUM_BIT,
NETIF_F_RXCSUM_BIT,
NETIF_F_HW_VLAN_CTAG_TX_BIT);
+static DECLARE_NETDEV_FEATURE_SET(be_feature_set,
NETIF_F_HW_VLAN_CTAG_RX_BIT,
NETIF_F_HW_VLAN_CTAG_FILTER_BIT,
NETIF_F_HIGHDMA_BIT);
+static DECLARE_NETDEV_FEATURE_SET(be_vlan_feature_set,
NETIF_F_SG_BIT,
NETIF_F_TSO_BIT,
NETIF_F_TSO6_BIT,
NETIF_F_IP_CSUM_BIT,
NETIF_F_IPV6_CSUM_BIT);
- static void be_netdev_init(struct net_device *netdev) { struct be_adapter *adapter = netdev_priv(netdev);
- netdev->hw_features |= NETIF_F_SG | NETIF_F_TSO | NETIF_F_TSO6 |
NETIF_F_GSO_UDP_TUNNEL |
NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | NETIF_F_RXCSUM |
NETIF_F_HW_VLAN_CTAG_TX;
- netdev_hw_features_set_array(netdev, &be_hw_feature_set); if ((be_if_cap_flags(adapter) & BE_IF_FLAGS_RSS)) netdev->hw_features |= NETIF_F_RXHASH;
- netdev->features |= netdev->hw_features |
NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_HW_VLAN_CTAG_FILTER |
NETIF_F_HIGHDMA;
- netdev->features |= netdev->hw_features;
- netdev_active_features_set_array(netdev, &be_feature_set);
- netdev->vlan_features |= NETIF_F_SG | NETIF_F_TSO | NETIF_F_TSO6 |
NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
netdev_vlan_features_set_array(netdev, &be_vlan_feature_set);
netdev->priv_flags |= IFF_UNICAST_FLT;
diff --git a/drivers/net/ethernet/faraday/ftgmac100.c b/drivers/net/ethernet/faraday/ftgmac100.c index c03663785a8d..8c95ad9df5e5 100644 --- a/drivers/net/ethernet/faraday/ftgmac100.c +++ b/drivers/net/ethernet/faraday/ftgmac100.c @@ -1777,6 +1777,14 @@ static bool ftgmac100_has_child_node(struct device_node *np, const char *name) return ret; }
+static DECLARE_NETDEV_FEATURE_SET(ftgmac100_hw_feature_set,
NETIF_F_RXCSUM_BIT,
NETIF_F_HW_CSUM_BIT,
NETIF_F_GRO_BIT,
NETIF_F_SG_BIT,
NETIF_F_HW_VLAN_CTAG_RX_BIT,
NETIF_F_HW_VLAN_CTAG_TX_BIT);
- static int ftgmac100_probe(struct platform_device *pdev) { struct resource *res;
@@ -1931,9 +1939,8 @@ static int ftgmac100_probe(struct platform_device *pdev) priv->tx_q_entries = priv->new_tx_q_entries = DEF_TX_QUEUE_ENTRIES;
/* Base feature set */
- netdev->hw_features = NETIF_F_RXCSUM | NETIF_F_HW_CSUM |
NETIF_F_GRO | NETIF_F_SG | NETIF_F_HW_VLAN_CTAG_RX |
NETIF_F_HW_VLAN_CTAG_TX;
netdev_hw_features_zero(netdev);
netdev_hw_features_set_array(netdev, &ftgmac100_hw_feature_set);
if (priv->use_ncsi) netdev->hw_features |= NETIF_F_HW_VLAN_CTAG_FILTER;
diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c index 45634579adb6..545e2b1afad7 100644 --- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c +++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c @@ -20,6 +20,7 @@ #include <linux/udp.h> #include <linux/tcp.h> #include <linux/net.h> +#include <linux/netdev_features_helper.h> #include <linux/skbuff.h> #include <linux/etherdevice.h> #include <linux/if_ether.h> @@ -197,6 +198,14 @@ static int dpaa_rx_extra_headroom; #define dpaa_get_max_mtu() \ (dpaa_max_frm - (VLAN_ETH_HLEN + ETH_FCS_LEN))
+static DECLARE_NETDEV_FEATURE_SET(dpaa_hw_feature_set,
NETIF_F_IP_CSUM_BIT,
NETIF_F_IPV6_CSUM_BIT,
NETIF_F_LLTX_BIT,
NETIF_F_RXHASH_BIT,
NETIF_F_SG_BIT,
NETIF_F_HIGHDMA_BIT);
- static int dpaa_netdev_init(struct net_device *net_dev, const struct net_device_ops *dpaa_ops, u16 tx_timeout)
@@ -224,10 +233,7 @@ static int dpaa_netdev_init(struct net_device *net_dev, net_dev->min_mtu = ETH_MIN_MTU; net_dev->max_mtu = dpaa_get_max_mtu();
- net_dev->hw_features |= (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
NETIF_F_LLTX | NETIF_F_RXHASH);
- net_dev->hw_features |= NETIF_F_SG | NETIF_F_HIGHDMA;
- netdev_hw_features_set_array(net_dev, &dpaa_hw_feature_set); /* The kernels enables GSO automatically, if we declare NETIF_F_SG.
*/
- For conformity, we'll still declare GSO explicitly.
diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c index cd9ec80522e7..d3c51e1a7c82 100644 --- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c +++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c @@ -9,6 +9,7 @@ #include <linux/of_net.h> #include <linux/interrupt.h> #include <linux/msi.h> +#include <linux/netdev_features_helper.h> #include <linux/kthread.h> #include <linux/iommu.h> #include <linux/fsl/mc.h> @@ -4327,6 +4328,16 @@ static int dpaa2_eth_set_mac_addr(struct dpaa2_eth_priv *priv) return 0; }
+static DECLARE_NETDEV_FEATURE_SET(dpaa2_feature_set,
NETIF_F_RXCSUM_BIT,
NETIF_F_IP_CSUM_BIT,
NETIF_F_IPV6_CSUM_BIT,
NETIF_F_SG_BIT,
NETIF_F_HIGHDMA_BIT,
NETIF_F_LLTX_BIT,
NETIF_F_HW_TC_BIT,
NETIF_F_TSO_BIT);
- static int dpaa2_eth_netdev_init(struct net_device *net_dev) { struct device *dev = net_dev->dev.parent;
@@ -4388,10 +4399,8 @@ static int dpaa2_eth_netdev_init(struct net_device *net_dev) net_dev->priv_flags &= ~not_supported;
/* Features */
- net_dev->features = NETIF_F_RXCSUM |
NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
NETIF_F_SG | NETIF_F_HIGHDMA |
NETIF_F_LLTX | NETIF_F_HW_TC | NETIF_F_TSO;
- netdev_active_features_zero(net_dev);
- netdev_active_features_set_array(net_dev, &dpaa2_feature_set); net_dev->gso_max_segs = DPAA2_ETH_ENQUEUE_MAX_FDS; net_dev->hw_features = net_dev->features;
diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c index e507e9065214..87ae011633ba 100644 --- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c +++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c @@ -3238,6 +3238,11 @@ static int dpaa2_switch_remove(struct fsl_mc_device *sw_dev) return 0; }
+static DECLARE_NETDEV_FEATURE_SET(dpaa2_feature_set,
NETIF_F_HW_VLAN_CTAG_FILTER_BIT,
NETIF_F_HW_VLAN_STAG_FILTER_BIT,
NETIF_F_HW_TC_BIT);
- static int dpaa2_switch_probe_port(struct ethsw_core *ethsw, u16 port_idx) {
@@ -3280,9 +3285,8 @@ static int dpaa2_switch_probe_port(struct ethsw_core *ethsw, /* The DPAA2 switch's ingress path depends on the VLAN table, * thus we are not able to disable VLAN filtering. */
- port_netdev->features = NETIF_F_HW_VLAN_CTAG_FILTER |
NETIF_F_HW_VLAN_STAG_FILTER |
NETIF_F_HW_TC;
netdev_active_features_zero(port_netdev);
netdev_active_features_set_array(port_netdev, &dpaa2_feature_set);
err = dpaa2_switch_port_init(port_priv, port_idx); if (err)
diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.h b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.h index 0002dca4d417..e7d92ac769e9 100644 --- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.h +++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.h @@ -11,6 +11,7 @@ #define __ETHSW_H
#include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/etherdevice.h> #include <linux/rtnetlink.h> #include <linux/if_vlan.h> diff --git a/drivers/net/ethernet/freescale/enetc/enetc_pf.c b/drivers/net/ethernet/freescale/enetc/enetc_pf.c index c4a0e836d4f0..b8daac778c64 100644 --- a/drivers/net/ethernet/freescale/enetc/enetc_pf.c +++ b/drivers/net/ethernet/freescale/enetc/enetc_pf.c @@ -4,6 +4,7 @@ #include <asm/unaligned.h> #include <linux/mdio.h> #include <linux/module.h> +#include <linux/netdev_features_helper.h> #include <linux/fsl/enetc_mdio.h> #include <linux/of_platform.h> #include <linux/of_mdio.h> @@ -744,6 +745,31 @@ static const struct net_device_ops enetc_ndev_ops = { .ndo_xdp_xmit = enetc_xdp_xmit, };
+static DECLARE_NETDEV_FEATURE_SET(enetc_hw_feature_set,
NETIF_F_SG_BIT,
NETIF_F_RXCSUM_BIT,
NETIF_F_HW_VLAN_CTAG_TX_BIT,
NETIF_F_HW_VLAN_CTAG_RX_BIT,
NETIF_F_HW_VLAN_CTAG_FILTER_BIT,
NETIF_F_LOOPBACK_BIT,
NETIF_F_HW_CSUM_BIT,
NETIF_F_TSO_BIT,
NETIF_F_TSO6_BIT);
+static DECLARE_NETDEV_FEATURE_SET(enetc_feature_set,
NETIF_F_HIGHDMA_BIT,
NETIF_F_SG_BIT,
NETIF_F_RXCSUM_BIT,
NETIF_F_HW_VLAN_CTAG_TX_BIT,
NETIF_F_HW_VLAN_CTAG_RX_BIT,
NETIF_F_HW_CSUM_BIT,
NETIF_F_TSO_BIT,
NETIF_F_TSO6_BIT);
+static DECLARE_NETDEV_FEATURE_SET(enetc_vlan_feature_set,
NETIF_F_SG_BIT,
NETIF_F_HW_CSUM_BIT,
NETIF_F_TSO_BIT,
NETIF_F_TSO6_BIT);
- static void enetc_pf_netdev_setup(struct enetc_si *si, struct net_device *ndev, const struct net_device_ops *ndev_ops) {
@@ -761,16 +787,12 @@ static void enetc_pf_netdev_setup(struct enetc_si *si, struct net_device *ndev, ndev->watchdog_timeo = 5 * HZ; ndev->max_mtu = ENETC_MAX_MTU;
- ndev->hw_features = NETIF_F_SG | NETIF_F_RXCSUM |
NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX |
NETIF_F_HW_VLAN_CTAG_FILTER | NETIF_F_LOOPBACK |
NETIF_F_HW_CSUM | NETIF_F_TSO | NETIF_F_TSO6;
- ndev->features = NETIF_F_HIGHDMA | NETIF_F_SG | NETIF_F_RXCSUM |
NETIF_F_HW_VLAN_CTAG_TX |
NETIF_F_HW_VLAN_CTAG_RX |
NETIF_F_HW_CSUM | NETIF_F_TSO | NETIF_F_TSO6;
- ndev->vlan_features = NETIF_F_SG | NETIF_F_HW_CSUM |
NETIF_F_TSO | NETIF_F_TSO6;
netdev_hw_features_zero(ndev);
netdev_hw_features_set_array(ndev, &enetc_hw_feature_set);
netdev_active_features_zero(ndev);
netdev_active_features_set_array(ndev, &enetc_feature_set);
netdev_vlan_features_zero(ndev);
netdev_vlan_features_set_array(ndev, &enetc_vlan_feature_set);
if (si->num_rss) ndev->hw_features |= NETIF_F_RXHASH;
diff --git a/drivers/net/ethernet/freescale/enetc/enetc_vf.c b/drivers/net/ethernet/freescale/enetc/enetc_vf.c index 17924305afa2..a4eab1e1e590 100644 --- a/drivers/net/ethernet/freescale/enetc/enetc_vf.c +++ b/drivers/net/ethernet/freescale/enetc/enetc_vf.c @@ -2,6 +2,7 @@ /* Copyright 2017-2019 NXP */
#include <linux/module.h> +#include <linux/netdev_features_helper.h> #include "enetc.h"
#define ENETC_DRV_NAME_STR "ENETC VF driver" @@ -103,6 +104,29 @@ static const struct net_device_ops enetc_ndev_ops = { .ndo_setup_tc = enetc_setup_tc, };
+static DECLARE_NETDEV_FEATURE_SET(enetc_vf_hw_feature_set,
NETIF_F_SG_BIT,
NETIF_F_RXCSUM_BIT,
NETIF_F_HW_VLAN_CTAG_TX_BIT,
NETIF_F_HW_VLAN_CTAG_RX_BIT,
NETIF_F_HW_CSUM_BIT,
NETIF_F_TSO_BIT,
NETIF_F_TSO6_BIT);
+static DECLARE_NETDEV_FEATURE_SET(enetc_vf_feature_set,
NETIF_F_HIGHDMA_BIT,
NETIF_F_SG_BIT,
NETIF_F_RXCSUM_BIT,
NETIF_F_HW_VLAN_CTAG_TX_BIT,
NETIF_F_HW_VLAN_CTAG_RX_BIT,
NETIF_F_HW_CSUM_BIT,
NETIF_F_TSO_BIT,
NETIF_F_TSO6_BIT);
+static DECLARE_NETDEV_FEATURE_SET(enetc_vf_vlan_feature_set,
NETIF_F_SG_BIT,
NETIF_F_HW_CSUM_BIT,
NETIF_F_TSO_BIT,
NETIF_F_TSO6_BIT);
- static void enetc_vf_netdev_setup(struct enetc_si *si, struct net_device *ndev, const struct net_device_ops *ndev_ops) {
@@ -120,16 +144,12 @@ static void enetc_vf_netdev_setup(struct enetc_si *si, struct net_device *ndev, ndev->watchdog_timeo = 5 * HZ; ndev->max_mtu = ENETC_MAX_MTU;
- ndev->hw_features = NETIF_F_SG | NETIF_F_RXCSUM |
NETIF_F_HW_VLAN_CTAG_TX |
NETIF_F_HW_VLAN_CTAG_RX |
NETIF_F_HW_CSUM | NETIF_F_TSO | NETIF_F_TSO6;
- ndev->features = NETIF_F_HIGHDMA | NETIF_F_SG | NETIF_F_RXCSUM |
NETIF_F_HW_VLAN_CTAG_TX |
NETIF_F_HW_VLAN_CTAG_RX |
NETIF_F_HW_CSUM | NETIF_F_TSO | NETIF_F_TSO6;
- ndev->vlan_features = NETIF_F_SG | NETIF_F_HW_CSUM |
NETIF_F_TSO | NETIF_F_TSO6;
netdev_hw_features_zero(ndev);
netdev_hw_features_set_array(ndev, &enetc_vf_hw_feature_set);
netdev_active_features_zero(ndev);
netdev_active_features_set_array(ndev, &enetc_vf_feature_set);
netdev_vlan_features_zero(ndev);
netdev_vlan_features_set_array(ndev, &enetc_vf_vlan_feature_set);
if (si->num_rss) ndev->hw_features |= NETIF_F_RXHASH;
diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c index e8e2aa1e7f01..49850ee91d4e 100644 --- a/drivers/net/ethernet/freescale/fec_main.c +++ b/drivers/net/ethernet/freescale/fec_main.c @@ -33,6 +33,7 @@ #include <linux/interrupt.h> #include <linux/delay.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/etherdevice.h> #include <linux/skbuff.h> #include <linux/in.h> @@ -3465,6 +3466,13 @@ static const unsigned short offset_des_active_txq[] = { FEC_X_DES_ACTIVE_0, FEC_X_DES_ACTIVE_1, FEC_X_DES_ACTIVE_2 };
+static DECLARE_NETDEV_FEATURE_SET(fec_feature_set,
NETIF_F_IP_CSUM_BIT,
NETIF_F_IPV6_CSUM_BIT,
NETIF_F_RXCSUM_BIT,
NETIF_F_SG_BIT,
NETIF_F_TSO_BIT);
- /*
- XXX: We need to clean up on failure exits here.
@@ -3569,8 +3577,7 @@ static int fec_enet_init(struct net_device *ndev) netif_set_tso_max_segs(ndev, FEC_MAX_TSO_SEGS);
/* enable hw accelerator */
ndev->features |= (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM
| NETIF_F_RXCSUM | NETIF_F_SG | NETIF_F_TSO);
fep->csum_flags |= FLAG_RX_CSUM_ENABLED; }netdev_active_features_set_array(ndev, &fec_feature_set);
diff --git a/drivers/net/ethernet/freescale/gianfar.c b/drivers/net/ethernet/freescale/gianfar.c index e7bf1524b68e..72a1842794a7 100644 --- a/drivers/net/ethernet/freescale/gianfar.c +++ b/drivers/net/ethernet/freescale/gianfar.c @@ -67,6 +67,7 @@ #include <linux/interrupt.h> #include <linux/delay.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/etherdevice.h> #include <linux/skbuff.h> #include <linux/if_vlan.h> @@ -3191,6 +3192,16 @@ static const struct net_device_ops gfar_netdev_ops = { #endif };
+static DECLARE_NETDEV_FEATURE_SET(gfar_hw_feature_set,
NETIF_F_IP_CSUM_BIT,
NETIF_F_SG_BIT,
NETIF_F_RXCSUM_BIT);
+static DECLARE_NETDEV_FEATURE_SET(gfar_feature_set,
NETIF_F_IP_CSUM_BIT,
NETIF_F_SG_BIT,
NETIF_F_RXCSUM_BIT,
NETIF_F_HIGHDMA_BIT);
- /* Set up the ethernet device structure, private data,
*/
- and anything else we need before we start
@@ -3239,10 +3250,9 @@ static int gfar_probe(struct platform_device *ofdev) }
if (priv->device_flags & FSL_GIANFAR_DEV_HAS_CSUM) {
dev->hw_features = NETIF_F_IP_CSUM | NETIF_F_SG |
NETIF_F_RXCSUM;
dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG |
NETIF_F_RXCSUM | NETIF_F_HIGHDMA;
netdev_hw_features_zero(dev);
netdev_hw_features_set_array(dev, &gfar_hw_feature_set);
netdev_active_features_set_array(dev, &gfar_feature_set);
}
if (priv->device_flags & FSL_GIANFAR_DEV_HAS_VLAN) {
diff --git a/drivers/net/ethernet/fungible/funeth/funeth_main.c b/drivers/net/ethernet/fungible/funeth/funeth_main.c index f247b7ad3a88..537daf19f7f6 100644 --- a/drivers/net/ethernet/fungible/funeth/funeth_main.c +++ b/drivers/net/ethernet/fungible/funeth/funeth_main.c @@ -9,6 +9,7 @@ #include <linux/if_vlan.h> #include <linux/module.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/pci.h> #include <linux/rtnetlink.h> #include <linux/inetdevice.h> @@ -1354,14 +1355,6 @@ static const struct net_device_ops fun_netdev_ops = { .ndo_get_devlink_port = fun_get_devlink_port, };
-#define GSO_ENCAP_FLAGS (NETIF_F_GSO_GRE | NETIF_F_GSO_IPXIP4 | \
NETIF_F_GSO_IPXIP6 | NETIF_F_GSO_UDP_TUNNEL | \
NETIF_F_GSO_UDP_TUNNEL_CSUM)
-#define TSO_FLAGS (NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_TSO_ECN | \
NETIF_F_GSO_UDP_L4)
-#define VLAN_FEAT (NETIF_F_SG | NETIF_F_HW_CSUM | TSO_FLAGS | \
GSO_ENCAP_FLAGS | NETIF_F_HIGHDMA)
- static void fun_dflt_rss_indir(struct funeth_priv *fp, unsigned int nrx) { unsigned int i;
@@ -1708,9 +1701,35 @@ int fun_change_num_queues(struct net_device *dev, unsigned int ntx, return err; }
+static DECLARE_NETDEV_FEATURE_SET(fun_hw_feature_set,
NETIF_F_SG_BIT,
NETIF_F_RXHASH_BIT,
NETIF_F_RXCSUM_BIT);
+static DECLARE_NETDEV_FEATURE_SET(fun_gso_encap_feature_set,
NETIF_F_GSO_GRE_BIT,
NETIF_F_GSO_IPXIP4_BIT,
NETIF_F_GSO_IPXIP6_BIT,
NETIF_F_GSO_UDP_TUNNEL_BIT,
NETIF_F_GSO_UDP_TUNNEL_CSUM_BIT);
+static DECLARE_NETDEV_FEATURE_SET(fun_tso_feature_set,
NETIF_F_TSO_BIT,
NETIF_F_TSO6_BIT,
NETIF_F_TSO_ECN_BIT,
NETIF_F_GSO_UDP_L4_BIT);
+static DECLARE_NETDEV_FEATURE_SET(fun_vlan_feature_set,
NETIF_F_SG_BIT,
NETIF_F_HW_CSUM_BIT,
NETIF_F_HIGHDMA_BIT);
- static int fun_create_netdev(struct fun_ethdev *ed, unsigned int portid) {
- netdev_features_t gso_encap_flags = netdev_empty_features;
- netdev_features_t tso_flags = netdev_empty_features; struct fun_dev *fdev = &ed->fdev;
- netdev_features_t vlan_feat; struct net_device *netdev; struct funeth_priv *fp; unsigned int ntx, nrx;
@@ -1763,14 +1782,19 @@ static int fun_create_netdev(struct fun_ethdev *ed, unsigned int portid) SET_NETDEV_DEV(netdev, fdev->dev); netdev->netdev_ops = &fun_netdev_ops;
- netdev->hw_features = NETIF_F_SG | NETIF_F_RXHASH | NETIF_F_RXCSUM;
- netdev_features_set_array(&fun_gso_encap_feature_set, &gso_encap_flags);
- netdev_features_set_array(&fun_tso_feature_set, &tso_flags);
- vlan_feat = gso_encap_flags | tso_flags;
- netdev_features_set_array(&fun_vlan_feature_set, &vlan_feat);
- netdev_hw_features_set_array(netdev, &fun_hw_feature_set); if (fp->port_caps & FUN_PORT_CAP_OFFLOADS)
netdev->hw_features |= NETIF_F_HW_CSUM | TSO_FLAGS;
if (fp->port_caps & FUN_PORT_CAP_ENCAP_OFFLOADS)netdev->hw_features |= NETIF_F_HW_CSUM | tso_flags;
netdev->hw_features |= GSO_ENCAP_FLAGS;
netdev->hw_features |= gso_encap_flags;
netdev->features |= netdev->hw_features | NETIF_F_HIGHDMA;
- netdev->vlan_features = netdev->features & VLAN_FEAT;
- netdev->vlan_features = netdev->features & vlan_feat; netdev->mpls_features = netdev->vlan_features; netdev->hw_enc_features = netdev->hw_features;
diff --git a/drivers/net/ethernet/google/gve/gve_main.c b/drivers/net/ethernet/google/gve/gve_main.c index 6cafee55efc3..357e2d9cd740 100644 --- a/drivers/net/ethernet/google/gve/gve_main.c +++ b/drivers/net/ethernet/google/gve/gve_main.c @@ -8,6 +8,7 @@ #include <linux/etherdevice.h> #include <linux/interrupt.h> #include <linux/module.h> +#include <linux/netdev_features_helper.h> #include <linux/pci.h> #include <linux/sched.h> #include <linux/timer.h> @@ -1528,6 +1529,16 @@ static void gve_write_version(u8 __iomem *driver_version_register) writeb('\n', driver_version_register); }
+static DECLARE_NETDEV_FEATURE_SET(gve_hw_feature_set,
NETIF_F_HIGHDMA_BIT,
NETIF_F_SG_BIT,
NETIF_F_HW_CSUM_BIT,
NETIF_F_TSO_BIT,
NETIF_F_TSO6_BIT,
NETIF_F_TSO_ECN_BIT,
NETIF_F_RXCSUM_BIT,
NETIF_F_RXHASH_BIT);
- static int gve_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { int max_tx_queues, max_rx_queues;
@@ -1588,14 +1599,8 @@ static int gve_probe(struct pci_dev *pdev, const struct pci_device_id *ent) * Features might be set in other locations as well (such as * `gve_adminq_describe_device`). */
- dev->hw_features = NETIF_F_HIGHDMA;
- dev->hw_features |= NETIF_F_SG;
- dev->hw_features |= NETIF_F_HW_CSUM;
- dev->hw_features |= NETIF_F_TSO;
- dev->hw_features |= NETIF_F_TSO6;
- dev->hw_features |= NETIF_F_TSO_ECN;
- dev->hw_features |= NETIF_F_RXCSUM;
- dev->hw_features |= NETIF_F_RXHASH;
- netdev_hw_features_zero(dev);
- netdev_hw_features_set_array(dev, &gve_hw_feature_set); dev->features = dev->hw_features; dev->watchdog_timeo = 5 * HZ; dev->min_mtu = ETH_MIN_MTU;
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_enet.c b/drivers/net/ethernet/hisilicon/hns/hns_enet.c index d94cc8c6681f..c7556817e6a4 100644 --- a/drivers/net/ethernet/hisilicon/hns/hns_enet.c +++ b/drivers/net/ethernet/hisilicon/hns/hns_enet.c @@ -13,6 +13,7 @@ #include <linux/ipv6.h> #include <linux/irq.h> #include <linux/module.h> +#include <linux/netdev_features_helper.h> #include <linux/phy.h> #include <linux/platform_device.h> #include <linux/skbuff.h> @@ -1791,6 +1792,11 @@ static int hns_nic_set_features(struct net_device *netdev, return 0; }
+static DECLARE_NETDEV_FEATURE_SET(hns_v1_off_feature_set,
NETIF_F_TSO_BIT,
NETIF_F_TSO6_BIT,
NETIF_F_HW_VLAN_CTAG_FILTER_BIT);
- static netdev_features_t hns_nic_fix_features( struct net_device *netdev, netdev_features_t features) {
@@ -1798,8 +1804,7 @@ static netdev_features_t hns_nic_fix_features(
switch (priv->enet_ver) { case AE_VERSION_1:
features &= ~(NETIF_F_TSO | NETIF_F_TSO6 |
NETIF_F_HW_VLAN_CTAG_FILTER);
break; default: break;netdev_features_clear_array(&hns_v1_off_feature_set, &features);
@@ -2240,6 +2245,34 @@ static int hns_nic_notifier_action(struct notifier_block *nb, return 0; }
+static DECLARE_NETDEV_FEATURE_SET(hns_feature_set,
NETIF_F_IP_CSUM_BIT,
NETIF_F_IPV6_CSUM_BIT,
NETIF_F_RXCSUM_BIT,
NETIF_F_SG_BIT,
NETIF_F_GSO_BIT,
NETIF_F_GRO_BIT);
+static DECLARE_NETDEV_FEATURE_SET(hns_vlan_feature_set,
NETIF_F_IP_CSUM_BIT,
NETIF_F_IPV6_CSUM_BIT,
NETIF_F_RXCSUM_BIT,
NETIF_F_SG_BIT,
NETIF_F_GSO_BIT,
NETIF_F_GRO_BIT);
+static DECLARE_NETDEV_FEATURE_SET(hns_hw_feature_set,
NETIF_F_IP_CSUM_BIT,
NETIF_F_IPV6_CSUM_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);
+static DECLARE_NETDEV_FEATURE_SET(hns_v2_feature_set,
NETIF_F_TSO_BIT,
NETIF_F_TSO6_BIT,
NETIF_F_NTUPLE_BIT);
- static int hns_nic_dev_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev;
@@ -2323,21 +2356,15 @@ static int hns_nic_dev_probe(struct platform_device *pdev) ndev->netdev_ops = &hns_nic_netdev_ops; hns_ethtool_set_ops(ndev);
- ndev->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
NETIF_F_RXCSUM | NETIF_F_SG | NETIF_F_GSO |
NETIF_F_GRO;
- ndev->vlan_features |=
NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | NETIF_F_RXCSUM;
- ndev->vlan_features |= NETIF_F_SG | NETIF_F_GSO | NETIF_F_GRO;
netdev_active_features_set_array(ndev, &hns_feature_set);
netdev_vlan_features_set_array(ndev, &hns_vlan_feature_set);
/* MTU range: 68 - 9578 (v1) or 9706 (v2) */ ndev->min_mtu = MAC_MIN_MTU; switch (priv->enet_ver) { case AE_VERSION_2:
ndev->features |= NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_NTUPLE;
ndev->hw_features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
NETIF_F_RXCSUM | NETIF_F_SG | NETIF_F_GSO |
NETIF_F_GRO | NETIF_F_TSO | NETIF_F_TSO6;
netdev_active_features_set_array(ndev, &hns_v2_feature_set);
ndev->vlan_features |= NETIF_F_TSO | NETIF_F_TSO6; ndev->max_mtu = MAC_MAX_MTU_V2 - (ETH_HLEN + ETH_FCS_LEN + VLAN_HLEN);netdev_hw_features_set_array(ndev, &hns_hw_feature_set);
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c index 35d70041b9e8..df3f46d7f217 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,42 @@ static struct pci_driver hns3_driver = { .err_handler = &hns3_err_handler, };
+static 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_BIT);
+static 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->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_active_features_set_array(netdev, &hns3_default_feature_set);
if (ae_dev->dev_version >= HNAE3_DEVICE_VERSION_V2) { netdev->features |= NETIF_F_GRO_HW;
@@ -3296,10 +3316,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/huawei/hinic/hinic_main.c b/drivers/net/ethernet/huawei/hinic/hinic_main.c index c23ee2ddbce3..b8db3b423a5b 100644 --- a/drivers/net/ethernet/huawei/hinic/hinic_main.c +++ b/drivers/net/ethernet/huawei/hinic/hinic_main.c @@ -13,6 +13,7 @@ #include <linux/types.h> #include <linux/etherdevice.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/slab.h> #include <linux/if_vlan.h> #include <linux/semaphore.h> @@ -916,21 +917,41 @@ static const struct net_device_ops hinicvf_netdev_ops = { .ndo_set_features = hinic_set_features, };
+static DECLARE_NETDEV_FEATURE_SET(hinic_hw_feature_set,
NETIF_F_SG_BIT,
NETIF_F_HIGHDMA_BIT,
NETIF_F_IP_CSUM_BIT,
NETIF_F_IPV6_CSUM_BIT,
NETIF_F_TSO_BIT,
NETIF_F_TSO6_BIT,
NETIF_F_RXCSUM_BIT,
NETIF_F_LRO_BIT,
NETIF_F_HW_VLAN_CTAG_TX_BIT,
NETIF_F_HW_VLAN_CTAG_RX_BIT,
NETIF_F_GSO_UDP_TUNNEL_BIT,
NETIF_F_GSO_UDP_TUNNEL_CSUM_BIT);
+static DECLARE_NETDEV_FEATURE_SET(hinic_hw_enc_feature_set,
NETIF_F_IP_CSUM_BIT,
NETIF_F_IPV6_CSUM_BIT,
NETIF_F_SCTP_CRC_BIT,
NETIF_F_SG_BIT,
NETIF_F_TSO_BIT,
NETIF_F_TSO6_BIT,
NETIF_F_TSO_ECN_BIT,
NETIF_F_GSO_UDP_TUNNEL_BIT,
NETIF_F_GSO_UDP_TUNNEL_CSUM_BIT);
- static void netdev_features_init(struct net_device *netdev) {
- netdev->hw_features = NETIF_F_SG | NETIF_F_HIGHDMA | NETIF_F_IP_CSUM |
NETIF_F_IPV6_CSUM | NETIF_F_TSO | NETIF_F_TSO6 |
NETIF_F_RXCSUM | NETIF_F_LRO |
NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX |
NETIF_F_GSO_UDP_TUNNEL | NETIF_F_GSO_UDP_TUNNEL_CSUM;
netdev_hw_features_zero(netdev);
netdev_hw_features_set_array(netdev, &hinic_hw_feature_set);
netdev->vlan_features = netdev->hw_features;
netdev->features = netdev->hw_features | NETIF_F_HW_VLAN_CTAG_FILTER;
- netdev->hw_enc_features = NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | NETIF_F_SCTP_CRC |
NETIF_F_SG | NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_TSO_ECN |
NETIF_F_GSO_UDP_TUNNEL_CSUM | NETIF_F_GSO_UDP_TUNNEL;
netdev_hw_enc_features_zero(netdev);
netdev_hw_enc_features_set_array(netdev, &hinic_hw_enc_feature_set); }
static void hinic_refresh_nic_cfg(struct hinic_dev *nic_dev)
diff --git a/drivers/net/ethernet/ibm/ehea/ehea_main.c b/drivers/net/ethernet/ibm/ehea/ehea_main.c index 5dc302880f5f..cc520574a710 100644 --- a/drivers/net/ethernet/ibm/ehea/ehea_main.c +++ b/drivers/net/ethernet/ibm/ehea/ehea_main.c @@ -2936,6 +2936,26 @@ static const struct net_device_ops ehea_netdev_ops = { .ndo_tx_timeout = ehea_tx_watchdog, };
+static DECLARE_NETDEV_FEATURE_SET(ehea_hw_feature_set,
NETIF_F_SG_BIT,
NETIF_F_TSO_BIT,
NETIF_F_IP_CSUM_BIT,
NETIF_F_HW_VLAN_CTAG_TX_BIT);
+static DECLARE_NETDEV_FEATURE_SET(ehea_feature_set,
NETIF_F_SG_BIT,
NETIF_F_TSO_BIT,
NETIF_F_HIGHDMA_BIT,
NETIF_F_IP_CSUM_BIT,
NETIF_F_HW_VLAN_CTAG_TX_BIT,
NETIF_F_HW_VLAN_CTAG_RX_BIT,
NETIF_F_HW_VLAN_CTAG_FILTER_BIT,
NETIF_F_RXCSUM_BIT);
+static DECLARE_NETDEV_FEATURE_SET(ehea_vlan_feature_set,
NETIF_F_SG_BIT,
NETIF_F_TSO_BIT,
NETIF_F_HIGHDMA_BIT,
NETIF_F_IP_CSUM_BIT);
- static struct ehea_port *ehea_setup_single_port(struct ehea_adapter *adapter, u32 logical_port_id, struct device_node *dn)
@@ -2993,14 +3013,12 @@ static struct ehea_port *ehea_setup_single_port(struct ehea_adapter *adapter, dev->netdev_ops = &ehea_netdev_ops; ehea_set_ethtool_ops(dev);
- dev->hw_features = NETIF_F_SG | NETIF_F_TSO |
NETIF_F_IP_CSUM | NETIF_F_HW_VLAN_CTAG_TX;
- dev->features = NETIF_F_SG | NETIF_F_TSO |
NETIF_F_HIGHDMA | NETIF_F_IP_CSUM |
NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX |
NETIF_F_HW_VLAN_CTAG_FILTER | NETIF_F_RXCSUM;
- dev->vlan_features = NETIF_F_SG | NETIF_F_TSO | NETIF_F_HIGHDMA |
NETIF_F_IP_CSUM;
netdev_hw_features_zero(dev);
netdev_hw_features_set_array(dev, &ehea_hw_feature_set);
netdev_active_features_zero(dev);
netdev_active_features_set_array(dev, &ehea_feature_set);
netdev_vlan_features_zero(dev);
netdev_vlan_features_set_array(dev, &ehea_vlan_feature_set); dev->watchdog_timeo = EHEA_WATCH_DOG_TIMEOUT;
/* MTU range: 68 - 9022 */
diff --git a/drivers/net/ethernet/ibm/emac/core.c b/drivers/net/ethernet/ibm/emac/core.c index fbea9f7efe8c..6b026ba0f262 100644 --- a/drivers/net/ethernet/ibm/emac/core.c +++ b/drivers/net/ethernet/ibm/emac/core.c @@ -3032,6 +3032,10 @@ static const struct net_device_ops emac_gige_netdev_ops = { .ndo_change_mtu = emac_change_mtu, };
+static DECLARE_NETDEV_FEATURE_SET(emac_hw_feature_set,
NETIF_F_IP_CSUM_BIT,
NETIF_F_SG_BIT);
- static int emac_probe(struct platform_device *ofdev) { struct net_device *ndev;
@@ -3171,7 +3175,8 @@ static int emac_probe(struct platform_device *ofdev) goto err_detach_tah;
if (dev->tah_dev) {
ndev->hw_features = NETIF_F_IP_CSUM | NETIF_F_SG;
netdev_hw_features_zero(ndev);
ndev->features |= ndev->hw_features | NETIF_F_RXCSUM; } ndev->watchdog_timeo = 5 * HZ;netdev_hw_features_set_array(ndev, &emac_hw_feature_set);
diff --git a/drivers/net/ethernet/ibm/ibmveth.c b/drivers/net/ethernet/ibm/ibmveth.c index 5c6a04d29f5b..b45b7ff892ef 100644 --- a/drivers/net/ethernet/ibm/ibmveth.c +++ b/drivers/net/ethernet/ibm/ibmveth.c @@ -1623,6 +1623,11 @@ static const struct net_device_ops ibmveth_netdev_ops = { #endif };
+static DECLARE_NETDEV_FEATURE_SET(ibmveth_hw_feature_set,
NETIF_F_IP_CSUM_BIT,
NETIF_F_IPV6_CSUM_BIT,
NETIF_F_RXCSUM_BIT);
- static int ibmveth_probe(struct vio_dev *dev, const struct vio_device_id *id) { int rc, i, mac_len;
@@ -1681,10 +1686,8 @@ static int ibmveth_probe(struct vio_dev *dev, const struct vio_device_id *id) netdev->ethtool_ops = &netdev_ethtool_ops; SET_NETDEV_DEV(netdev, &dev->dev); netdev->hw_features = NETIF_F_SG;
- if (vio_get_attribute(dev, "ibm,illan-options", NULL) != NULL) {
netdev->hw_features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
NETIF_F_RXCSUM;
- }
if (vio_get_attribute(dev, "ibm,illan-options", NULL) != NULL)
netdev_hw_features_set_array(netdev, &ibmveth_hw_feature_set);
netdev->features |= netdev->hw_features;
diff --git a/drivers/net/ethernet/ibm/ibmvnic.c b/drivers/net/ethernet/ibm/ibmvnic.c index 5ab7c0f81e9a..c0ae18a2b601 100644 --- a/drivers/net/ethernet/ibm/ibmvnic.c +++ b/drivers/net/ethernet/ibm/ibmvnic.c @@ -4831,6 +4831,11 @@ static void send_query_ip_offload(struct ibmvnic_adapter *adapter) ibmvnic_send_crq(adapter, &crq); }
+static DECLARE_NETDEV_FEATURE_SET(ibmvnic_hw_feature_set,
NETIF_F_SG_BIT,
NETIF_F_GSO_BIT,
NETIF_F_GRO_BIT);
- static void send_control_ip_offload(struct ibmvnic_adapter *adapter) { struct ibmvnic_control_ip_offload_buffer *ctrl_buf = &adapter->ip_offload_ctrl;
@@ -4870,7 +4875,8 @@ static void send_control_ip_offload(struct ibmvnic_adapter *adapter) adapter->netdev->hw_features = 0; }
- adapter->netdev->hw_features = NETIF_F_SG | NETIF_F_GSO | NETIF_F_GRO;
netdev_hw_features_zero(adapter->netdev);
netdev_hw_features_set_array(adapter->netdev, &ibmvnic_hw_feature_set);
if (buf->tcp_ipv4_chksum || buf->udp_ipv4_chksum) adapter->netdev->hw_features |= NETIF_F_IP_CSUM;
diff --git a/drivers/net/ethernet/intel/e1000/e1000.h b/drivers/net/ethernet/intel/e1000/e1000.h index 4817eb13ca6f..86bc74be959f 100644 --- a/drivers/net/ethernet/intel/e1000/e1000.h +++ b/drivers/net/ethernet/intel/e1000/e1000.h @@ -16,6 +16,7 @@ #include <linux/pci.h> #include <linux/kernel.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/etherdevice.h> #include <linux/skbuff.h> #include <linux/delay.h> diff --git a/drivers/net/ethernet/intel/e1000/e1000_main.c b/drivers/net/ethernet/intel/e1000/e1000_main.c index 23299fc56199..07670cabf19f 100644 --- a/drivers/net/ethernet/intel/e1000/e1000_main.c +++ b/drivers/net/ethernet/intel/e1000/e1000_main.c @@ -907,6 +907,22 @@ static int e1000_init_hw_struct(struct e1000_adapter *adapter, return 0; }
+static DECLARE_NETDEV_FEATURE_SET(e1000_hw_feature_set,
NETIF_F_SG_BIT,
NETIF_F_HW_CSUM_BIT,
NETIF_F_HW_VLAN_CTAG_RX_BIT);
+static DECLARE_NETDEV_FEATURE_SET(e1000_feature_set,
NETIF_F_HW_VLAN_CTAG_TX_BIT,
NETIF_F_HW_VLAN_CTAG_FILTER_BIT);
+static DECLARE_NETDEV_FEATURE_SET(e1000_hw_rx_feature_set,
NETIF_F_RXCSUM_BIT,
NETIF_F_RXALL_BIT,
NETIF_F_RXFCS_BIT);
+static DECLARE_NETDEV_FEATURE_SET(e1000_vlan_feature_set,
NETIF_F_TSO_BIT,
NETIF_F_HW_CSUM_BIT,
NETIF_F_SG_BIT);
- /**
- e1000_probe - Device Initialization Routine
- @pdev: PCI device information struct
@@ -1035,11 +1051,10 @@ static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *ent) }
if (hw->mac_type >= e1000_82543) {
netdev->hw_features = NETIF_F_SG |
NETIF_F_HW_CSUM |
NETIF_F_HW_VLAN_CTAG_RX;
netdev->features = NETIF_F_HW_VLAN_CTAG_TX |
NETIF_F_HW_VLAN_CTAG_FILTER;
netdev_hw_features_zero(netdev);
netdev_hw_features_set_array(netdev, &e1000_hw_feature_set);
netdev_active_features_zero(netdev);
netdev_active_features_set_array(netdev, &e1000_feature_set);
}
if ((hw->mac_type >= e1000_82544) &&
@@ -1049,18 +1064,14 @@ static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *ent) netdev->priv_flags |= IFF_SUPP_NOFCS;
netdev->features |= netdev->hw_features;
- netdev->hw_features |= (NETIF_F_RXCSUM |
NETIF_F_RXALL |
NETIF_F_RXFCS);
netdev_hw_features_set_array(netdev, &e1000_hw_rx_feature_set);
if (pci_using_dac) { netdev->features |= NETIF_F_HIGHDMA; netdev->vlan_features |= NETIF_F_HIGHDMA; }
- netdev->vlan_features |= (NETIF_F_TSO |
NETIF_F_HW_CSUM |
NETIF_F_SG);
netdev_vlan_features_set_array(netdev, &e1000_vlan_feature_set);
/* Do not set IFF_UNICAST_FLT for VMWare's 82545EM */ if (hw->device_id != E1000_DEV_ID_82545EM_COPPER ||
diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c index 70d933f52e93..3ed52967efd6 100644 --- a/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/drivers/net/ethernet/intel/e1000e/netdev.c @@ -11,6 +11,7 @@ #include <linux/pagemap.h> #include <linux/delay.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/interrupt.h> #include <linux/tcp.h> #include <linux/ipv6.h> @@ -7311,18 +7312,27 @@ static netdev_features_t e1000_fix_features(struct net_device *netdev, return features; }
+static DECLARE_NETDEV_FEATURE_SET(e1000_changable_feature_set,
NETIF_F_HW_VLAN_CTAG_RX_BIT,
NETIF_F_HW_VLAN_CTAG_TX_BIT,
NETIF_F_RXCSUM_BIT,
NETIF_F_RXHASH_BIT,
NETIF_F_RXFCS_BIT,
NETIF_F_RXALL_BIT);
static int e1000_set_features(struct net_device *netdev, netdev_features_t features) { struct e1000_adapter *adapter = netdev_priv(netdev); netdev_features_t changed = features ^ netdev->features;
netdev_features_t changeable;
if (changed & (NETIF_F_TSO | NETIF_F_TSO6)) adapter->flags |= FLAG_TSO_FORCE;
- if (!(changed & (NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_HW_VLAN_CTAG_TX |
NETIF_F_RXCSUM | NETIF_F_RXHASH | NETIF_F_RXFCS |
NETIF_F_RXALL)))
netdev_features_zero(&changeable);
netdev_features_set_array(&e1000_changable_feature_set, &changeable);
if (!(changed & changeable)) return 0;
if (changed & NETIF_F_RXFCS) {
@@ -7371,6 +7381,21 @@ static const struct net_device_ops e1000e_netdev_ops = { .ndo_features_check = passthru_features_check, };
+static DECLARE_NETDEV_FEATURE_SET(e1000_feature_set,
NETIF_F_SG_BIT,
NETIF_F_HW_VLAN_CTAG_RX_BIT,
NETIF_F_HW_VLAN_CTAG_TX_BIT,
NETIF_F_TSO_BIT,
NETIF_F_TSO6_BIT,
NETIF_F_RXHASH_BIT,
NETIF_F_RXCSUM_BIT,
NETIF_F_HW_CSUM_BIT);
+static DECLARE_NETDEV_FEATURE_SET(e1000_vlan_feature_set,
NETIF_F_SG_BIT,
NETIF_F_TSO_BIT,
NETIF_F_TSO6_BIT,
NETIF_F_HW_CSUM_BIT);
- /**
- e1000_probe - Device Initialization Routine
- @pdev: PCI device information struct
@@ -7523,14 +7548,8 @@ static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *ent) "PHY reset is blocked due to SOL/IDER session.\n");
/* Set initial default active device features */
- netdev->features = (NETIF_F_SG |
NETIF_F_HW_VLAN_CTAG_RX |
NETIF_F_HW_VLAN_CTAG_TX |
NETIF_F_TSO |
NETIF_F_TSO6 |
NETIF_F_RXHASH |
NETIF_F_RXCSUM |
NETIF_F_HW_CSUM);
netdev_active_features_zero(netdev);
netdev_active_features_set_array(netdev, &e1000_feature_set);
/* Set user-changeable features (subset of all device features) */ netdev->hw_features = netdev->features;
@@ -7541,10 +7560,7 @@ static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *ent) if (adapter->flags & FLAG_HAS_HW_VLAN_FILTER) netdev->features |= NETIF_F_HW_VLAN_CTAG_FILTER;
- netdev->vlan_features |= (NETIF_F_SG |
NETIF_F_TSO |
NETIF_F_TSO6 |
NETIF_F_HW_CSUM);
netdev_vlan_features_set_array(netdev, &e1000_vlan_feature_set);
netdev->priv_flags |= IFF_UNICAST_FLT;
diff --git a/drivers/net/ethernet/intel/fm10k/fm10k_netdev.c b/drivers/net/ethernet/intel/fm10k/fm10k_netdev.c index 2cca9e84e31e..a42148582779 100644 --- a/drivers/net/ethernet/intel/fm10k/fm10k_netdev.c +++ b/drivers/net/ethernet/intel/fm10k/fm10k_netdev.c @@ -5,6 +5,7 @@ #include <linux/vmalloc.h> #include <net/udp_tunnel.h> #include <linux/if_macvlan.h> +#include <linux/netdev_features_helper.h>
/**
- fm10k_setup_tx_resources - allocate Tx resources (Descriptors)
@@ -1536,6 +1537,24 @@ static const struct net_device_ops fm10k_netdev_ops = { .ndo_features_check = fm10k_features_check, };
+static DECLARE_NETDEV_FEATURE_SET(fm10k_feature_set,
NETIF_F_IP_CSUM_BIT,
NETIF_F_IPV6_CSUM_BIT,
NETIF_F_SG_BIT,
NETIF_F_TSO_BIT,
NETIF_F_TSO6_BIT,
NETIF_F_TSO_ECN_BIT,
NETIF_F_RXHASH_BIT,
NETIF_F_RXCSUM_BIT);
+static DECLARE_NETDEV_FEATURE_SET(fm10k_hw_enc_feature_set,
NETIF_F_IP_CSUM_BIT,
NETIF_F_TSO_BIT,
NETIF_F_TSO6_BIT,
NETIF_F_TSO_ECN_BIT,
NETIF_F_GSO_UDP_TUNNEL_BIT,
NETIF_F_IPV6_CSUM_BIT,
NETIF_F_SG_BIT);
#define DEFAULT_DEBUG_LEVEL_SHIFT 3
struct net_device *fm10k_alloc_netdev(const struct fm10k_info *info)
@@ -1557,24 +1576,12 @@ struct net_device *fm10k_alloc_netdev(const struct fm10k_info *info) interface->msg_enable = BIT(DEFAULT_DEBUG_LEVEL_SHIFT) - 1;
/* configure default features */
- dev->features |= NETIF_F_IP_CSUM |
NETIF_F_IPV6_CSUM |
NETIF_F_SG |
NETIF_F_TSO |
NETIF_F_TSO6 |
NETIF_F_TSO_ECN |
NETIF_F_RXHASH |
NETIF_F_RXCSUM;
netdev_active_features_set_array(dev, &fm10k_feature_set);
/* Only the PF can support VXLAN and NVGRE tunnel offloads */ if (info->mac == fm10k_mac_pf) {
dev->hw_enc_features = NETIF_F_IP_CSUM |
NETIF_F_TSO |
NETIF_F_TSO6 |
NETIF_F_TSO_ECN |
NETIF_F_GSO_UDP_TUNNEL |
NETIF_F_IPV6_CSUM |
NETIF_F_SG;
netdev_hw_enc_features_zero(dev);
netdev_hw_enc_features_set_array(dev, &fm10k_hw_enc_feature_set);
dev->features |= NETIF_F_GSO_UDP_TUNNEL;
diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index b36bf9c3e1e4..69ac22c7e800 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -7,6 +7,7 @@ #include <linux/bpf.h> #include <generated/utsrelease.h> #include <linux/crash_dump.h> +#include <linux/netdev_features_helper.h>
/* Local includes */ #include "i40e.h" @@ -13616,6 +13617,37 @@ static const struct net_device_ops i40e_netdev_ops = { .ndo_dfwd_del_station = i40e_fwd_del, };
+static DECLARE_NETDEV_FEATURE_SET(i40e_hw_enc_feature_set,
NETIF_F_SG_BIT,
NETIF_F_HW_CSUM_BIT,
NETIF_F_HIGHDMA_BIT,
NETIF_F_TSO_BIT,
NETIF_F_TSO_ECN_BIT,
NETIF_F_TSO6_BIT,
NETIF_F_GSO_GRE_BIT,
NETIF_F_GSO_GRE_CSUM_BIT,
NETIF_F_GSO_PARTIAL_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_UDP_L4_BIT,
NETIF_F_SCTP_CRC_BIT,
NETIF_F_RXHASH_BIT,
NETIF_F_RXCSUM_BIT);
+static DECLARE_NETDEV_FEATURE_SET(i40e_gso_partial_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);
+static DECLARE_NETDEV_FEATURE_SET(i40e_mpls_feature_set,
NETIF_F_SG_BIT,
NETIF_F_HW_CSUM_BIT,
NETIF_F_TSO_BIT,
NETIF_F_TSO6_BIT);
- /**
- i40e_config_netdev - Setup the netdev flags
- @vsi: the VSI being configured
@@ -13631,6 +13663,7 @@ static int i40e_config_netdev(struct i40e_vsi *vsi) u8 broadcast[ETH_ALEN]; u8 mac_addr[ETH_ALEN]; int etherdev_size;
- netdev_features_t gso_partial_features; netdev_features_t hw_enc_features; netdev_features_t hw_features;
@@ -13643,25 +13676,8 @@ static int i40e_config_netdev(struct i40e_vsi *vsi) np = netdev_priv(netdev); np->vsi = vsi;
- hw_enc_features = NETIF_F_SG |
NETIF_F_HW_CSUM |
NETIF_F_HIGHDMA |
NETIF_F_SOFT_FEATURES |
NETIF_F_TSO |
NETIF_F_TSO_ECN |
NETIF_F_TSO6 |
NETIF_F_GSO_GRE |
NETIF_F_GSO_GRE_CSUM |
NETIF_F_GSO_PARTIAL |
NETIF_F_GSO_IPXIP4 |
NETIF_F_GSO_IPXIP6 |
NETIF_F_GSO_UDP_TUNNEL |
NETIF_F_GSO_UDP_TUNNEL_CSUM |
NETIF_F_GSO_UDP_L4 |
NETIF_F_SCTP_CRC |
NETIF_F_RXHASH |
NETIF_F_RXCSUM |
0;
hw_enc_features = NETIF_F_SOFT_FEATURES;
netdev_features_set_array(&i40e_hw_enc_feature_set, &hw_enc_features);
if (!(pf->hw_features & I40E_HW_OUTER_UDP_CSUM_CAPABLE)) netdev->gso_partial_features |= NETIF_F_GSO_UDP_TUNNEL_CSUM;
@@ -13675,22 +13691,15 @@ static int i40e_config_netdev(struct i40e_vsi *vsi) /* record features VLANs can make use of */ netdev->vlan_features |= hw_enc_features | NETIF_F_TSO_MANGLEID;
-#define I40E_GSO_PARTIAL_FEATURES (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)
- netdev->gso_partial_features = I40E_GSO_PARTIAL_FEATURES;
- netdev_features_zero(&gso_partial_features);
- netdev_features_set_array(&i40e_gso_partial_feature_set,
&gso_partial_features);
- netdev->gso_partial_features = gso_partial_features; netdev->features |= NETIF_F_GSO_PARTIAL |
I40E_GSO_PARTIAL_FEATURES;
gso_partial_features;
- netdev->mpls_features |= NETIF_F_SG;
- netdev->mpls_features |= NETIF_F_HW_CSUM;
- netdev->mpls_features |= NETIF_F_TSO;
- netdev->mpls_features |= NETIF_F_TSO6;
- netdev->mpls_features |= I40E_GSO_PARTIAL_FEATURES;
netdev_mpls_features_set_array(netdev, &i40e_mpls_feature_set);
netdev->mpls_features |= gso_partial_features;
/* enable macvlan offloads */ netdev->hw_features |= NETIF_F_HW_L2FW_DOFFLOAD;
diff --git a/drivers/net/ethernet/intel/iavf/iavf.h b/drivers/net/ethernet/intel/iavf/iavf.h index 69703801d1b0..feb048cdcea9 100644 --- a/drivers/net/ethernet/intel/iavf/iavf.h +++ b/drivers/net/ethernet/intel/iavf/iavf.h @@ -8,6 +8,7 @@ #include <linux/pci.h> #include <linux/aer.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/vmalloc.h> #include <linux/interrupt.h> #include <linux/ethtool.h> diff --git a/drivers/net/ethernet/intel/iavf/iavf_main.c b/drivers/net/ethernet/intel/iavf/iavf_main.c index e78c38d02432..47048014a1c4 100644 --- a/drivers/net/ethernet/intel/iavf/iavf_main.c +++ b/drivers/net/ethernet/intel/iavf/iavf_main.c @@ -4543,6 +4543,26 @@ static int iavf_check_reset_complete(struct iavf_hw *hw) return -EBUSY; }
+static DECLARE_NETDEV_FEATURE_SET(iavf_hw_enc_feature_set,
NETIF_F_SG_BIT,
NETIF_F_IP_CSUM_BIT,
NETIF_F_IPV6_CSUM_BIT,
NETIF_F_HIGHDMA_BIT,
NETIF_F_TSO_BIT,
NETIF_F_TSO_ECN_BIT,
NETIF_F_TSO6_BIT,
NETIF_F_SCTP_CRC_BIT,
NETIF_F_RXHASH_BIT,
NETIF_F_RXCSUM_BIT);
+static DECLARE_NETDEV_FEATURE_SET(iavf_gso_feature_set,
NETIF_F_GSO_UDP_TUNNEL_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_CSUM_BIT,
NETIF_F_GSO_PARTIAL_BIT);
- /**
- iavf_process_config - Process the config information we got from the PF
- @adapter: board private structure
@@ -4558,31 +4578,14 @@ int iavf_process_config(struct iavf_adapter *adapter) netdev_features_t hw_enc_features; netdev_features_t hw_features;
- hw_enc_features = NETIF_F_SG |
NETIF_F_IP_CSUM |
NETIF_F_IPV6_CSUM |
NETIF_F_HIGHDMA |
NETIF_F_SOFT_FEATURES |
NETIF_F_TSO |
NETIF_F_TSO_ECN |
NETIF_F_TSO6 |
NETIF_F_SCTP_CRC |
NETIF_F_RXHASH |
NETIF_F_RXCSUM |
0;
hw_enc_features = NETIF_F_SOFT_FEATURES;
netdev_features_set_array(&iavf_hw_enc_feature_set, &hw_enc_features);
/* advertise to stack only if offloads for encapsulated packets is
- supported
*/ if (vfres->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_ENCAP) {
hw_enc_features |= NETIF_F_GSO_UDP_TUNNEL |
NETIF_F_GSO_GRE |
NETIF_F_GSO_GRE_CSUM |
NETIF_F_GSO_IPXIP4 |
NETIF_F_GSO_IPXIP6 |
NETIF_F_GSO_UDP_TUNNEL_CSUM |
NETIF_F_GSO_PARTIAL |
0;
netdev_features_set_array(&iavf_gso_feature_set, &hw_enc_features);
if (!(vfres->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_ENCAP_CSUM))
diff --git a/drivers/net/ethernet/intel/ice/ice.h b/drivers/net/ethernet/intel/ice/ice.h index 36b440b1aaff..6ecbe4369f5a 100644 --- a/drivers/net/ethernet/intel/ice/ice.h +++ b/drivers/net/ethernet/intel/ice/ice.h @@ -10,6 +10,7 @@ #include <linux/module.h> #include <linux/firmware.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/compiler.h> #include <linux/etherdevice.h> #include <linux/skbuff.h> diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c index 29914eedb3e6..9a8aa40b703e 100644 --- a/drivers/net/ethernet/intel/ice/ice_main.c +++ b/drivers/net/ethernet/intel/ice/ice_main.c @@ -3293,6 +3293,36 @@ static void ice_set_ops(struct net_device *netdev) ice_set_ethtool_ops(netdev); }
+static DECLARE_NETDEV_FEATURE_SET(ice_safe_mode_feature_set,
NETIF_F_SG_BIT,
NETIF_F_HIGHDMA_BIT);
+static DECLARE_NETDEV_FEATURE_SET(ice_dflt_feature_set,
NETIF_F_SG_BIT,
NETIF_F_HIGHDMA_BIT,
NETIF_F_NTUPLE_BIT,
NETIF_F_RXHASH_BIT);
+static DECLARE_NETDEV_FEATURE_SET(ice_csumo_feature_set,
NETIF_F_RXCSUM_BIT,
NETIF_F_IP_CSUM_BIT,
NETIF_F_SCTP_CRC_BIT,
NETIF_F_IPV6_CSUM_BIT);
+static DECLARE_NETDEV_FEATURE_SET(ice_tso_feature_set,
NETIF_F_TSO_BIT,
NETIF_F_TSO_ECN_BIT,
NETIF_F_TSO6_BIT,
NETIF_F_GSO_GRE_BIT,
NETIF_F_GSO_UDP_TUNNEL_BIT,
NETIF_F_GSO_GRE_CSUM_BIT,
NETIF_F_GSO_UDP_TUNNEL_CSUM_BIT,
NETIF_F_GSO_PARTIAL_BIT,
NETIF_F_GSO_IPXIP4_BIT,
NETIF_F_GSO_IPXIP6_BIT,
NETIF_F_GSO_UDP_L4_BIT);
+static DECLARE_NETDEV_FEATURE_SET(ice_mpls_feature_set,
NETIF_F_HW_CSUM_BIT,
NETIF_F_TSO_BIT,
NETIF_F_TSO6_BIT);
- /**
- ice_set_netdev_features - set features for the given netdev
- @netdev: netdev instance
@@ -3308,20 +3338,18 @@ static void ice_set_netdev_features(struct net_device *netdev)
if (ice_is_safe_mode(pf)) { /* safe mode */
netdev->features = NETIF_F_SG | NETIF_F_HIGHDMA;
netdev_active_features_zero(netdev);
netdev_active_features_set_array(netdev,
netdev->hw_features = netdev->features; return; }&ice_safe_mode_feature_set);
- dflt_features = NETIF_F_SG |
NETIF_F_HIGHDMA |
NETIF_F_NTUPLE |
NETIF_F_RXHASH;
- netdev_features_zero(&dflt_features);
- netdev_features_set_array(&ice_dflt_feature_set, &dflt_features);
- csumo_features = NETIF_F_RXCSUM |
NETIF_F_IP_CSUM |
NETIF_F_SCTP_CRC |
NETIF_F_IPV6_CSUM;
netdev_features_zero(&csumo_features);
netdev_features_set_array(&ice_csumo_feature_set, &csumo_features);
vlano_features = NETIF_F_HW_VLAN_CTAG_FILTER | NETIF_F_HW_VLAN_CTAG_TX |
@@ -3331,17 +3359,8 @@ static void ice_set_netdev_features(struct net_device *netdev) if (is_dvm_ena) vlano_features |= NETIF_F_HW_VLAN_STAG_FILTER;
- tso_features = NETIF_F_TSO |
NETIF_F_TSO_ECN |
NETIF_F_TSO6 |
NETIF_F_GSO_GRE |
NETIF_F_GSO_UDP_TUNNEL |
NETIF_F_GSO_GRE_CSUM |
NETIF_F_GSO_UDP_TUNNEL_CSUM |
NETIF_F_GSO_PARTIAL |
NETIF_F_GSO_IPXIP4 |
NETIF_F_GSO_IPXIP6 |
NETIF_F_GSO_UDP_L4;
netdev_features_zero(&tso_features);
netdev_features_set_array(&ice_tso_feature_set, &tso_features);
netdev->gso_partial_features |= NETIF_F_GSO_UDP_TUNNEL_CSUM | NETIF_F_GSO_GRE_CSUM;
@@ -3350,9 +3369,8 @@ static void ice_set_netdev_features(struct net_device *netdev) vlano_features | tso_features;
/* add support for HW_CSUM on packets with MPLS header */
- netdev->mpls_features = NETIF_F_HW_CSUM |
NETIF_F_TSO |
NETIF_F_TSO6;
netdev_mpls_features_zero(netdev);
netdev_mpls_features_set_array(netdev, &ice_mpls_feature_set);
/* enable features */ netdev->features |= netdev->hw_features;
diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c index d8b836a85cc3..2fd8d8c94305 100644 --- a/drivers/net/ethernet/intel/igb/igb_main.c +++ b/drivers/net/ethernet/intel/igb/igb_main.c @@ -10,6 +10,7 @@ #include <linux/vmalloc.h> #include <linux/pagemap.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/ipv6.h> #include <linux/slab.h> #include <net/checksum.h> @@ -2500,6 +2501,20 @@ static int igb_ndo_fdb_add(struct ndmsg *ndm, struct nlattr *tb[], return ndo_dflt_fdb_add(ndm, tb, dev, addr, vid, flags); }
+static DECLARE_NETDEV_FEATURE_SET(igb_l2_disable_feature_set,
NETIF_F_HW_CSUM_BIT,
NETIF_F_SCTP_CRC_BIT,
NETIF_F_GSO_UDP_L4_BIT,
NETIF_F_HW_VLAN_CTAG_TX_BIT,
NETIF_F_TSO_BIT,
NETIF_F_TSO6_BIT);
+static DECLARE_NETDEV_FEATURE_SET(igb_l3_disable_feature_set,
NETIF_F_HW_CSUM_BIT,
NETIF_F_SCTP_CRC_BIT,
NETIF_F_GSO_UDP_L4_BIT,
NETIF_F_TSO_BIT,
NETIF_F_TSO6_BIT);
- #define IGB_MAX_MAC_HDR_LEN 127 #define IGB_MAX_NETWORK_HDR_LEN 511
@@ -2511,21 +2526,18 @@ igb_features_check(struct sk_buff *skb, struct net_device *dev,
/* Make certain the headers can be described by a context descriptor */ mac_hdr_len = skb_network_header(skb) - skb->data;
- if (unlikely(mac_hdr_len > IGB_MAX_MAC_HDR_LEN))
return features & ~(NETIF_F_HW_CSUM |
NETIF_F_SCTP_CRC |
NETIF_F_GSO_UDP_L4 |
NETIF_F_HW_VLAN_CTAG_TX |
NETIF_F_TSO |
NETIF_F_TSO6);
if (unlikely(mac_hdr_len > IGB_MAX_MAC_HDR_LEN)) {
netdev_features_clear_array(&igb_l2_disable_feature_set,
&features);
return features;
}
network_hdr_len = skb_checksum_start(skb) - skb_network_header(skb);
- if (unlikely(network_hdr_len > IGB_MAX_NETWORK_HDR_LEN))
return features & ~(NETIF_F_HW_CSUM |
NETIF_F_SCTP_CRC |
NETIF_F_GSO_UDP_L4 |
NETIF_F_TSO |
NETIF_F_TSO6);
if (unlikely(network_hdr_len > IGB_MAX_NETWORK_HDR_LEN)) {
netdev_features_clear_array(&igb_l3_disable_feature_set,
&features);
return features;
}
/* We can only support IPV4 TSO in tunnels if we can mangle the
- inner IP ID field, so strip TSO if MANGLEID is not supported.
@@ -3144,6 +3156,21 @@ static s32 igb_init_i2c(struct igb_adapter *adapter) return status; }
+static DECLARE_NETDEV_FEATURE_SET(igb_feature_set,
NETIF_F_SG_BIT,
NETIF_F_TSO_BIT,
NETIF_F_TSO6_BIT,
NETIF_F_RXHASH_BIT,
NETIF_F_RXCSUM_BIT,
NETIF_F_HW_CSUM_BIT);
+static DECLARE_NETDEV_FEATURE_SET(igb_gso_partial_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);
- /**
- igb_probe - Device Initialization Routine
- @pdev: PCI device information struct
@@ -3164,6 +3191,7 @@ static int igb_probe(struct pci_dev *pdev, const struct pci_device_id *ent) s32 ret_val; static int global_quad_port_a; /* global quad port a indication */ const struct e1000_info *ei = igb_info_tbl[ent->driver_data];
- netdev_features_t gso_partial_features; u8 part_str[E1000_PBANUM_LENGTH]; int err;
@@ -3268,12 +3296,7 @@ static int igb_probe(struct pci_dev *pdev, const struct pci_device_id *ent) * set by igb_sw_init so we should use an or instead of an * assignment. */
- netdev->features |= NETIF_F_SG |
NETIF_F_TSO |
NETIF_F_TSO6 |
NETIF_F_RXHASH |
NETIF_F_RXCSUM |
NETIF_F_HW_CSUM;
netdev_active_features_set_array(netdev, &igb_feature_set);
if (hw->mac.type >= e1000_82576) netdev->features |= NETIF_F_SCTP_CRC | NETIF_F_GSO_UDP_L4;
@@ -3281,15 +3304,10 @@ static int igb_probe(struct pci_dev *pdev, const struct pci_device_id *ent) if (hw->mac.type >= e1000_i350) netdev->features |= NETIF_F_HW_TC;
-#define IGB_GSO_PARTIAL_FEATURES (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)
- netdev->gso_partial_features = IGB_GSO_PARTIAL_FEATURES;
- netdev->features |= NETIF_F_GSO_PARTIAL | IGB_GSO_PARTIAL_FEATURES;
netdev_features_zero(&gso_partial_features);
netdev_features_set_array(&igb_feature_set, &gso_partial_features);
netdev->gso_partial_features = gso_partial_features;
netdev->features |= NETIF_F_GSO_PARTIAL | gso_partial_features;
/* copy netdev features into list of user selectable features */ netdev->hw_features |= netdev->features |
diff --git a/drivers/net/ethernet/intel/igbvf/netdev.c b/drivers/net/ethernet/intel/igbvf/netdev.c index f4e91db89fe5..362e26df28b0 100644 --- a/drivers/net/ethernet/intel/igbvf/netdev.c +++ b/drivers/net/ethernet/intel/igbvf/netdev.c @@ -11,6 +11,7 @@ #include <linux/pagemap.h> #include <linux/delay.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/tcp.h> #include <linux/ipv6.h> #include <linux/slab.h> @@ -2615,6 +2616,18 @@ static int igbvf_set_features(struct net_device *netdev, return 0; }
+static DECLARE_NETDEV_FEATURE_SET(igbvf_l2_disable_feature_set,
NETIF_F_HW_CSUM_BIT,
NETIF_F_SCTP_CRC_BIT,
NETIF_F_HW_VLAN_CTAG_TX_BIT,
NETIF_F_TSO_BIT,
NETIF_F_TSO6_BIT);
+static DECLARE_NETDEV_FEATURE_SET(igbvf_l3_disable_feature_set,
NETIF_F_HW_CSUM_BIT,
NETIF_F_SCTP_CRC_BIT,
NETIF_F_TSO_BIT,
NETIF_F_TSO6_BIT);
- #define IGBVF_MAX_MAC_HDR_LEN 127 #define IGBVF_MAX_NETWORK_HDR_LEN 511
@@ -2626,19 +2639,18 @@ igbvf_features_check(struct sk_buff *skb, struct net_device *dev,
/* Make certain the headers can be described by a context descriptor */ mac_hdr_len = skb_network_header(skb) - skb->data;
- if (unlikely(mac_hdr_len > IGBVF_MAX_MAC_HDR_LEN))
return features & ~(NETIF_F_HW_CSUM |
NETIF_F_SCTP_CRC |
NETIF_F_HW_VLAN_CTAG_TX |
NETIF_F_TSO |
NETIF_F_TSO6);
if (unlikely(mac_hdr_len > IGBVF_MAX_MAC_HDR_LEN)) {
netdev_features_clear_array(&igbvf_l2_disable_feature_set,
&features);
return features;
}
network_hdr_len = skb_checksum_start(skb) - skb_network_header(skb);
- if (unlikely(network_hdr_len > IGBVF_MAX_NETWORK_HDR_LEN))
return features & ~(NETIF_F_HW_CSUM |
NETIF_F_SCTP_CRC |
NETIF_F_TSO |
NETIF_F_TSO6);
if (unlikely(network_hdr_len > IGBVF_MAX_NETWORK_HDR_LEN)) {
netdev_features_clear_array(&igbvf_l3_disable_feature_set,
&features);
return features;
}
/* We can only support IPV4 TSO in tunnels if we can mangle the
- inner IP ID field, so strip TSO if MANGLEID is not supported.
@@ -2667,6 +2679,21 @@ static const struct net_device_ops igbvf_netdev_ops = { .ndo_features_check = igbvf_features_check, };
+static DECLARE_NETDEV_FEATURE_SET(igbvf_hw_feature_set,
NETIF_F_SG_BIT,
NETIF_F_TSO_BIT,
NETIF_F_TSO6_BIT,
NETIF_F_RXCSUM_BIT,
NETIF_F_HW_CSUM_BIT,
NETIF_F_SCTP_CRC_BIT);
+static DECLARE_NETDEV_FEATURE_SET(igbvf_gso_partial_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);
- /**
- igbvf_probe - Device Initialization Routine
- @pdev: PCI device information struct
@@ -2684,6 +2711,7 @@ static int igbvf_probe(struct pci_dev *pdev, const struct pci_device_id *ent) struct igbvf_adapter *adapter; struct e1000_hw *hw; const struct igbvf_info *ei = igbvf_info_tbl[ent->driver_data];
- netdev_features_t gso_partial_features; static int cards_found; int err;
@@ -2758,23 +2786,15 @@ static int igbvf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
adapter->bd_number = cards_found++;
- netdev->hw_features = NETIF_F_SG |
NETIF_F_TSO |
NETIF_F_TSO6 |
NETIF_F_RXCSUM |
NETIF_F_HW_CSUM |
NETIF_F_SCTP_CRC;
-#define IGBVF_GSO_PARTIAL_FEATURES (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)
- netdev->gso_partial_features = IGBVF_GSO_PARTIAL_FEATURES;
- netdev->hw_features |= NETIF_F_GSO_PARTIAL |
IGBVF_GSO_PARTIAL_FEATURES;
netdev_hw_features_zero(netdev);
netdev_hw_features_set_array(netdev, &igbvf_hw_feature_set);
netdev_features_zero(&gso_partial_features);
netdev_features_set_array(&igbvf_gso_partial_feature_set,
&gso_partial_features);
netdev->gso_partial_features = gso_partial_features;
netdev->hw_features |= NETIF_F_GSO_PARTIAL | gso_partial_features;
netdev->features = netdev->hw_features | NETIF_F_HIGHDMA;
diff --git a/drivers/net/ethernet/intel/igc/igc_mac.c b/drivers/net/ethernet/intel/igc/igc_mac.c index a5c4b19d71a2..79e65b35ab3d 100644 --- a/drivers/net/ethernet/intel/igc/igc_mac.c +++ b/drivers/net/ethernet/intel/igc/igc_mac.c @@ -3,6 +3,7 @@
#include <linux/pci.h> #include <linux/delay.h> +#include <linux/netdev_features_helper.h>
#include "igc_mac.h" #include "igc_hw.h" diff --git a/drivers/net/ethernet/intel/igc/igc_main.c b/drivers/net/ethernet/intel/igc/igc_main.c index ebff0e04045d..e5b97822e191 100644 --- a/drivers/net/ethernet/intel/igc/igc_main.c +++ b/drivers/net/ethernet/intel/igc/igc_main.c @@ -9,6 +9,7 @@ #include <linux/udp.h> #include <linux/ip.h> #include <linux/pm_runtime.h> +#include <linux/netdev_features_helper.h> #include <net/pkt_sched.h> #include <linux/bpf_trace.h> #include <net/xdp_sock_drv.h> @@ -4973,6 +4974,18 @@ static int igc_set_features(struct net_device *netdev, return 1; }
+static DECLARE_NETDEV_FEATURE_SET(igc_l2_disable_feature_set,
NETIF_F_HW_CSUM_BIT,
NETIF_F_SCTP_CRC_BIT,
NETIF_F_HW_VLAN_CTAG_TX_BIT,
NETIF_F_TSO_BIT,
NETIF_F_TSO6_BIT);
+static DECLARE_NETDEV_FEATURE_SET(igc_l3_disable_feature_set,
NETIF_F_HW_CSUM_BIT,
NETIF_F_SCTP_CRC_BIT,
NETIF_F_TSO_BIT,
NETIF_F_TSO6_BIT);
- static netdev_features_t igc_features_check(struct sk_buff *skb, struct net_device *dev, netdev_features_t features)
@@ -4981,19 +4994,18 @@ igc_features_check(struct sk_buff *skb, struct net_device *dev,
/* Make certain the headers can be described by a context descriptor */ mac_hdr_len = skb_network_header(skb) - skb->data;
- if (unlikely(mac_hdr_len > IGC_MAX_MAC_HDR_LEN))
return features & ~(NETIF_F_HW_CSUM |
NETIF_F_SCTP_CRC |
NETIF_F_HW_VLAN_CTAG_TX |
NETIF_F_TSO |
NETIF_F_TSO6);
if (unlikely(mac_hdr_len > IGC_MAX_MAC_HDR_LEN)) {
netdev_features_clear_array(&igc_l2_disable_feature_set,
&features);
return features;
}
network_hdr_len = skb_checksum_start(skb) - skb_network_header(skb);
- if (unlikely(network_hdr_len > IGC_MAX_NETWORK_HDR_LEN))
return features & ~(NETIF_F_HW_CSUM |
NETIF_F_SCTP_CRC |
NETIF_F_TSO |
NETIF_F_TSO6);
if (unlikely(network_hdr_len > IGC_MAX_NETWORK_HDR_LEN)) {
netdev_features_clear_array(&igc_l3_disable_feature_set,
&features);
return features;
}
/* We can only support IPv4 TSO in tunnels if we can mangle the
- inner IP ID field, so strip TSO if MANGLEID is not supported.
@@ -6201,6 +6213,23 @@ u32 igc_rd32(struct igc_hw *hw, u32 reg) return value; }
+static DECLARE_NETDEV_FEATURE_SET(igc_feature_set,
NETIF_F_SG_BIT,
NETIF_F_TSO_BIT,
NETIF_F_TSO6_BIT,
NETIF_F_TSO_ECN_BIT,
NETIF_F_RXCSUM_BIT,
NETIF_F_HW_CSUM_BIT,
NETIF_F_SCTP_CRC_BIT,
NETIF_F_HW_TC_BIT);
+static DECLARE_NETDEV_FEATURE_SET(igc_gso_partial_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);
- /**
- igc_probe - Device Initialization Routine
- @pdev: PCI device information struct
@@ -6219,6 +6248,7 @@ static int igc_probe(struct pci_dev *pdev, struct net_device *netdev; struct igc_hw *hw; const struct igc_info *ei = igc_info_tbl[ent->driver_data];
netdev_features_t gso_partial_features; int err;
err = pci_enable_device_mem(pdev);
@@ -6299,24 +6329,13 @@ static int igc_probe(struct pci_dev *pdev, goto err_sw_init;
/* Add supported features to the features list*/
- netdev->features |= NETIF_F_SG;
- netdev->features |= NETIF_F_TSO;
- netdev->features |= NETIF_F_TSO6;
- netdev->features |= NETIF_F_TSO_ECN;
- netdev->features |= NETIF_F_RXCSUM;
- netdev->features |= NETIF_F_HW_CSUM;
- netdev->features |= NETIF_F_SCTP_CRC;
- netdev->features |= NETIF_F_HW_TC;
-#define IGC_GSO_PARTIAL_FEATURES (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)
- netdev->gso_partial_features = IGC_GSO_PARTIAL_FEATURES;
- netdev->features |= NETIF_F_GSO_PARTIAL | IGC_GSO_PARTIAL_FEATURES;
netdev_active_features_set_array(netdev, &igc_feature_set);
netdev_features_zero(&gso_partial_features);
netdev_features_set_array(&igc_gso_partial_feature_set,
&gso_partial_features);
netdev->gso_partial_features = gso_partial_features;
netdev->features |= NETIF_F_GSO_PARTIAL | gso_partial_features;
/* setup the private structure */ err = igc_sw_init(adapter);
diff --git a/drivers/net/ethernet/intel/ixgb/ixgb_main.c b/drivers/net/ethernet/intel/ixgb/ixgb_main.c index 45be9a1ab6af..c3ae375f04dd 100644 --- a/drivers/net/ethernet/intel/ixgb/ixgb_main.c +++ b/drivers/net/ethernet/intel/ixgb/ixgb_main.c @@ -3,6 +3,7 @@
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+#include <linux/netdev_features_helper.h> #include <linux/prefetch.h> #include "ixgb.h"
@@ -343,6 +344,13 @@ static const struct net_device_ops ixgb_netdev_ops = { .ndo_set_features = ixgb_set_features, };
+static DECLARE_NETDEV_FEATURE_SET(ixgb_hw_feature_set,
NETIF_F_SG_BIT,
NETIF_F_TSO_BIT,
NETIF_F_HW_CSUM_BIT,
NETIF_F_HW_VLAN_CTAG_TX_BIT,
NETIF_F_HW_VLAN_CTAG_RX_BIT);
- /**
- ixgb_probe - Device Initialization Routine
- @pdev: PCI device information struct
@@ -428,11 +436,8 @@ ixgb_probe(struct pci_dev *pdev, const struct pci_device_id *ent) if (err) goto err_sw_init;
- netdev->hw_features = NETIF_F_SG |
NETIF_F_TSO |
NETIF_F_HW_CSUM |
NETIF_F_HW_VLAN_CTAG_TX |
NETIF_F_HW_VLAN_CTAG_RX;
- netdev_hw_features_zero(netdev);
- netdev_hw_features_set_array(netdev, &ixgb_hw_feature_set); netdev->features = netdev->hw_features | NETIF_F_HW_VLAN_CTAG_FILTER; netdev->hw_features |= NETIF_F_RXCSUM;
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c index d1e430b8c8aa..98db7c46e89c 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c @@ -5,6 +5,7 @@ #include <linux/module.h> #include <linux/pci.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/vmalloc.h> #include <linux/string.h> #include <linux/in.h> @@ -10210,6 +10211,20 @@ static void ixgbe_fwd_del(struct net_device *pdev, void *priv) kfree(accel); }
+static DECLARE_NETDEV_FEATURE_SET(ixgbe_l2_disable_feature_set,
NETIF_F_HW_CSUM_BIT,
NETIF_F_SCTP_CRC_BIT,
NETIF_F_GSO_UDP_L4_BIT,
NETIF_F_HW_VLAN_CTAG_TX_BIT,
NETIF_F_TSO_BIT,
NETIF_F_TSO6_BIT);
+static DECLARE_NETDEV_FEATURE_SET(ixgbe_l3_disable_feature_set,
NETIF_F_HW_CSUM_BIT,
NETIF_F_SCTP_CRC_BIT,
NETIF_F_GSO_UDP_L4_BIT,
NETIF_F_TSO_BIT,
NETIF_F_TSO6_BIT);
- #define IXGBE_MAX_MAC_HDR_LEN 127 #define IXGBE_MAX_NETWORK_HDR_LEN 511
@@ -10221,21 +10236,18 @@ ixgbe_features_check(struct sk_buff *skb, struct net_device *dev,
/* Make certain the headers can be described by a context descriptor */ mac_hdr_len = skb_network_header(skb) - skb->data;
- if (unlikely(mac_hdr_len > IXGBE_MAX_MAC_HDR_LEN))
return features & ~(NETIF_F_HW_CSUM |
NETIF_F_SCTP_CRC |
NETIF_F_GSO_UDP_L4 |
NETIF_F_HW_VLAN_CTAG_TX |
NETIF_F_TSO |
NETIF_F_TSO6);
if (unlikely(mac_hdr_len > IXGBE_MAX_MAC_HDR_LEN)) {
netdev_features_clear_array(&ixgbe_l2_disable_feature_set,
&features);
return features;
}
network_hdr_len = skb_checksum_start(skb) - skb_network_header(skb);
- if (unlikely(network_hdr_len > IXGBE_MAX_NETWORK_HDR_LEN))
return features & ~(NETIF_F_HW_CSUM |
NETIF_F_SCTP_CRC |
NETIF_F_GSO_UDP_L4 |
NETIF_F_TSO |
NETIF_F_TSO6);
if (unlikely(network_hdr_len > IXGBE_MAX_NETWORK_HDR_LEN)) {
netdev_features_clear_array(&ixgbe_l3_disable_feature_set,
&features);
return features;
}
/* We can only support IPV4 TSO in tunnels if we can mangle the
- inner IP ID field, so strip TSO if MANGLEID is not supported.
@@ -10755,6 +10767,47 @@ static void ixgbe_set_fw_version(struct ixgbe_adapter *adapter) "0x%08x", nvm_ver.etk_id); }
+static DECLARE_NETDEV_FEATURE_SET(ixgbe_feature_set,
NETIF_F_SG_BIT,
NETIF_F_TSO_BIT,
NETIF_F_TSO6_BIT,
NETIF_F_RXHASH_BIT,
NETIF_F_RXCSUM_BIT,
NETIF_F_HW_CSUM_BIT);
+static DECLARE_NETDEV_FEATURE_SET(ixgbe_gso_partial_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);
+#ifdef CONFIG_IXGBE_IPSEC +static DECLARE_NETDEV_FEATURE_SET(ixgbe_esp_feature_set,
NETIF_F_HW_ESP_BIT,
NETIF_F_HW_ESP_TX_CSUM_BIT,
NETIF_F_GSO_ESP_BIT);
+#endif +static DECLARE_NETDEV_FEATURE_SET(ixgbe_hw_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_RXALL_BIT,
NETIF_F_HW_L2FW_DOFFLOAD_BIT);
+static DECLARE_NETDEV_FEATURE_SET(ixgbe_mpls_feature_set,
NETIF_F_SG_BIT,
NETIF_F_TSO_BIT,
NETIF_F_TSO6_BIT,
NETIF_F_HW_CSUM_BIT);
+#ifdef IXGBE_FCOE +static DECLARE_NETDEV_FEATURE_SET(ixgbe_fcoe_feature_set,
NETIF_F_FSO_BIT,
NETIF_F_FCOE_CRC_BIT);
+static DECLARE_NETDEV_FEATURE_SET(ixgbe_vlan_fcoe_feature_set,
NETIF_F_FSO_BIT,
NETIF_F_FCOE_CRC_BIT,
NETIF_F_FCOE_MTU_BIT);
+#endif
- /**
- ixgbe_probe - Device Initialization Routine
- @pdev: PCI device information struct
@@ -10772,6 +10825,7 @@ static int ixgbe_probe(struct pci_dev *pdev, const struct pci_device_id *ent) struct ixgbe_adapter *adapter = NULL; struct ixgbe_hw *hw; const struct ixgbe_info *ii = ixgbe_info_tbl[ent->driver_data];
- netdev_features_t gso_partial_features; unsigned int indices = MAX_TX_QUEUES; u8 part_str[IXGBE_PBANUM_LENGTH]; int i, err, expected_gts;
@@ -10958,42 +11012,27 @@ static int ixgbe_probe(struct pci_dev *pdev, const struct pci_device_id *ent) skip_sriov:
#endif
- netdev->features = NETIF_F_SG |
NETIF_F_TSO |
NETIF_F_TSO6 |
NETIF_F_RXHASH |
NETIF_F_RXCSUM |
NETIF_F_HW_CSUM;
-#define IXGBE_GSO_PARTIAL_FEATURES (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)
- netdev->gso_partial_features = IXGBE_GSO_PARTIAL_FEATURES;
- netdev_active_features_zero(netdev);
- netdev_active_features_set_array(netdev, &ixgbe_feature_set);
- netdev_features_zero(&gso_partial_features);
- netdev_features_set_array(&ixgbe_gso_partial_feature_set,
&gso_partial_features);
- netdev->gso_partial_features = gso_partial_features; netdev->features |= NETIF_F_GSO_PARTIAL |
IXGBE_GSO_PARTIAL_FEATURES;
gso_partial_features;
if (hw->mac.type >= ixgbe_mac_82599EB) netdev->features |= NETIF_F_SCTP_CRC | NETIF_F_GSO_UDP_L4;
#ifdef CONFIG_IXGBE_IPSEC
-#define IXGBE_ESP_FEATURES (NETIF_F_HW_ESP | \
NETIF_F_HW_ESP_TX_CSUM | \
NETIF_F_GSO_ESP)
- if (adapter->ipsec)
netdev->features |= IXGBE_ESP_FEATURES;
#endif /* copy netdev features into list of user selectable features */netdev_active_features_set_array(netdev, &ixgbe_esp_feature_set);
- netdev->hw_features |= netdev->features |
NETIF_F_HW_VLAN_CTAG_FILTER |
NETIF_F_HW_VLAN_CTAG_RX |
NETIF_F_HW_VLAN_CTAG_TX |
NETIF_F_RXALL |
NETIF_F_HW_L2FW_DOFFLOAD;
netdev->hw_features |= netdev->features;
netdev_hw_features_set_array(netdev, &ixgbe_hw_feature_set);
if (hw->mac.type >= ixgbe_mac_82599EB) netdev->hw_features |= NETIF_F_NTUPLE |
@@ -11003,11 +11042,8 @@ static int ixgbe_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
netdev->vlan_features |= netdev->features | NETIF_F_TSO_MANGLEID; netdev->hw_enc_features |= netdev->vlan_features;
- netdev->mpls_features |= NETIF_F_SG |
NETIF_F_TSO |
NETIF_F_TSO6 |
NETIF_F_HW_CSUM;
- netdev->mpls_features |= IXGBE_GSO_PARTIAL_FEATURES;
netdev_mpls_features_set_array(netdev, &ixgbe_mpls_feature_set);
netdev->mpls_features |= gso_partial_features;
/* set this bit last since it cannot be part of vlan_features */ netdev->features |= NETIF_F_HW_VLAN_CTAG_FILTER |
@@ -11040,12 +11076,8 @@ static int ixgbe_probe(struct pci_dev *pdev, const struct pci_device_id *ent) fcoe_l = min_t(int, IXGBE_FCRETA_SIZE, num_online_cpus()); adapter->ring_feature[RING_F_FCOE].limit = fcoe_l;
netdev->features |= NETIF_F_FSO |
NETIF_F_FCOE_CRC;
netdev->vlan_features |= NETIF_F_FSO |
NETIF_F_FCOE_CRC |
NETIF_F_FCOE_MTU;
netdev_active_features_set_array(netdev, &ixgbe_fcoe_feature_set);
} #endif /* IXGBE_FCOE */ if (adapter->flags2 & IXGBE_FLAG2_RSC_CAPABLE)netdev_vlan_features_set_array(netdev, &ixgbe_vlan_fcoe_feature_set);
diff --git a/drivers/net/ethernet/intel/ixgbevf/ipsec.c b/drivers/net/ethernet/intel/ixgbevf/ipsec.c index 9984ebc62d78..82341ac13e62 100644 --- a/drivers/net/ethernet/intel/ixgbevf/ipsec.c +++ b/drivers/net/ethernet/intel/ixgbevf/ipsec.c @@ -612,6 +612,11 @@ void ixgbevf_ipsec_rx(struct ixgbevf_ring *rx_ring, adapter->rx_ipsec++; }
+static DECLARE_NETDEV_FEATURE_SET(ixgbevf_esp_feature_set,
NETIF_F_HW_ESP_BIT,
NETIF_F_HW_ESP_TX_CSUM_BIT,
NETIF_F_GSO_ESP_BIT);
- /**
- ixgbevf_init_ipsec_offload - initialize registers for IPsec operation
- @adapter: board private structure
@@ -651,12 +656,10 @@ void ixgbevf_init_ipsec_offload(struct ixgbevf_adapter *adapter)
adapter->netdev->xfrmdev_ops = &ixgbevf_xfrmdev_ops;
-#define IXGBEVF_ESP_FEATURES (NETIF_F_HW_ESP | \
NETIF_F_HW_ESP_TX_CSUM | \
NETIF_F_GSO_ESP)
- adapter->netdev->features |= IXGBEVF_ESP_FEATURES;
- adapter->netdev->hw_enc_features |= IXGBEVF_ESP_FEATURES;
netdev_active_features_set_array(adapter->netdev,
&ixgbevf_esp_feature_set);
netdev_hw_enc_features_set_array(adapter->netdev,
&ixgbevf_esp_feature_set);
return;
diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h b/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h index 149c733fcc2b..29bad7b3f573 100644 --- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h +++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h @@ -9,6 +9,7 @@ #include <linux/timer.h> #include <linux/io.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/if_vlan.h> #include <linux/u64_stats_sync.h> #include <net/xdp.h> diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c index 2f12fbe229c1..095159721a96 100644 --- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c +++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c @@ -12,6 +12,7 @@ #include <linux/module.h> #include <linux/pci.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/vmalloc.h> #include <linux/string.h> #include <linux/in.h> @@ -4396,6 +4397,18 @@ static void ixgbevf_get_stats(struct net_device *netdev, rcu_read_unlock(); }
+static DECLARE_NETDEV_FEATURE_SET(ixgbevf_l2_disable_feature_set,
NETIF_F_HW_CSUM_BIT,
NETIF_F_SCTP_CRC_BIT,
NETIF_F_HW_VLAN_CTAG_TX_BIT,
NETIF_F_TSO_BIT,
NETIF_F_TSO6_BIT);
+static DECLARE_NETDEV_FEATURE_SET(ixgbevf_l3_disable_feature_set,
NETIF_F_HW_CSUM_BIT,
NETIF_F_SCTP_CRC_BIT,
NETIF_F_TSO_BIT,
NETIF_F_TSO6_BIT);
- #define IXGBEVF_MAX_MAC_HDR_LEN 127 #define IXGBEVF_MAX_NETWORK_HDR_LEN 511
@@ -4407,19 +4420,18 @@ ixgbevf_features_check(struct sk_buff *skb, struct net_device *dev,
/* Make certain the headers can be described by a context descriptor */ mac_hdr_len = skb_network_header(skb) - skb->data;
- if (unlikely(mac_hdr_len > IXGBEVF_MAX_MAC_HDR_LEN))
return features & ~(NETIF_F_HW_CSUM |
NETIF_F_SCTP_CRC |
NETIF_F_HW_VLAN_CTAG_TX |
NETIF_F_TSO |
NETIF_F_TSO6);
if (unlikely(mac_hdr_len > IXGBEVF_MAX_MAC_HDR_LEN)) {
netdev_features_clear_array(&ixgbevf_l2_disable_feature_set,
&features);
return features;
}
network_hdr_len = skb_checksum_start(skb) - skb_network_header(skb);
- if (unlikely(network_hdr_len > IXGBEVF_MAX_NETWORK_HDR_LEN))
return features & ~(NETIF_F_HW_CSUM |
NETIF_F_SCTP_CRC |
NETIF_F_TSO |
NETIF_F_TSO6);
if (unlikely(network_hdr_len > IXGBEVF_MAX_NETWORK_HDR_LEN)) {
netdev_features_clear_array(&ixgbevf_l3_disable_feature_set,
&features);
return features;
}
/* We can only support IPV4 TSO in tunnels if we can mangle the
- inner IP ID field, so strip TSO if MANGLEID is not supported.
@@ -4504,6 +4516,26 @@ static void ixgbevf_assign_netdev_ops(struct net_device *dev) dev->watchdog_timeo = 5 * HZ; }
+static DECLARE_NETDEV_FEATURE_SET(ixgbevf_hw_feature_set,
NETIF_F_SG_BIT,
NETIF_F_TSO_BIT,
NETIF_F_TSO6_BIT,
NETIF_F_RXCSUM_BIT,
NETIF_F_HW_CSUM_BIT,
NETIF_F_SCTP_CRC_BIT);
+static DECLARE_NETDEV_FEATURE_SET(ixgbevf_gso_partial_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);
+static DECLARE_NETDEV_FEATURE_SET(ixgbevf_mpls_feature_set,
NETIF_F_SG_BIT,
NETIF_F_TSO_BIT,
NETIF_F_TSO6_BIT,
NETIF_F_HW_CSUM_BIT);
- /**
- ixgbevf_probe - Device Initialization Routine
- @pdev: PCI device information struct
@@ -4521,6 +4553,7 @@ static int ixgbevf_probe(struct pci_dev *pdev, const struct pci_device_id *ent) struct ixgbevf_adapter *adapter = NULL; struct ixgbe_hw *hw = NULL; const struct ixgbevf_info *ii = ixgbevf_info_tbl[ent->driver_data];
- netdev_features_t gso_partial_features; bool disable_dev = false; int err;
@@ -4593,32 +4626,22 @@ static int ixgbevf_probe(struct pci_dev *pdev, const struct pci_device_id *ent) goto err_sw_init; }
- netdev->hw_features = NETIF_F_SG |
NETIF_F_TSO |
NETIF_F_TSO6 |
NETIF_F_RXCSUM |
NETIF_F_HW_CSUM |
NETIF_F_SCTP_CRC;
-#define IXGBEVF_GSO_PARTIAL_FEATURES (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)
- netdev->gso_partial_features = IXGBEVF_GSO_PARTIAL_FEATURES;
- netdev_hw_features_zero(netdev);
- netdev_hw_features_set_array(netdev, &ixgbevf_hw_feature_set);
- netdev_features_zero(&gso_partial_features);
- netdev_features_set_array(&ixgbevf_gso_partial_feature_set,
&gso_partial_features);
- netdev->gso_partial_features = gso_partial_features; netdev->hw_features |= NETIF_F_GSO_PARTIAL |
IXGBEVF_GSO_PARTIAL_FEATURES;
gso_partial_features;
netdev->features = netdev->hw_features | NETIF_F_HIGHDMA;
netdev->vlan_features |= netdev->features | NETIF_F_TSO_MANGLEID;
- netdev->mpls_features |= NETIF_F_SG |
NETIF_F_TSO |
NETIF_F_TSO6 |
NETIF_F_HW_CSUM;
- netdev->mpls_features |= IXGBEVF_GSO_PARTIAL_FEATURES;
netdev_mpls_features_set_array(netdev, &ixgbevf_mpls_feature_set);
netdev->mpls_features |= gso_partial_features; netdev->hw_enc_features |= netdev->vlan_features;
/* set this bit last since it cannot be part of vlan_features */
diff --git a/drivers/net/ethernet/jme.c b/drivers/net/ethernet/jme.c index f43d6616bc0d..6db2f01468c5 100644 --- a/drivers/net/ethernet/jme.c +++ b/drivers/net/ethernet/jme.c @@ -15,6 +15,7 @@ #include <linux/kernel.h> #include <linux/pci.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/etherdevice.h> #include <linux/ethtool.h> #include <linux/mii.h> @@ -2901,6 +2902,22 @@ static const struct net_device_ops jme_netdev_ops = { #endif };
+static DECLARE_NETDEV_FEATURE_SET(jme_hw_feature_set,
NETIF_F_IP_CSUM_BIT,
NETIF_F_IPV6_CSUM_BIT,
NETIF_F_SG_BIT,
NETIF_F_TSO_BIT,
NETIF_F_TSO6_BIT,
NETIF_F_RXCSUM_BIT);
+static DECLARE_NETDEV_FEATURE_SET(jme_feature_set,
NETIF_F_IP_CSUM_BIT,
NETIF_F_IPV6_CSUM_BIT,
NETIF_F_SG_BIT,
NETIF_F_TSO_BIT,
NETIF_F_TSO6_BIT,
NETIF_F_HW_VLAN_CTAG_TX_BIT,
NETIF_F_HW_VLAN_CTAG_RX_BIT);
- static int jme_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
@@ -2955,19 +2972,10 @@ jme_init_one(struct pci_dev *pdev, netdev->netdev_ops = &jme_netdev_ops; netdev->ethtool_ops = &jme_ethtool_ops; netdev->watchdog_timeo = TX_TIMEOUT;
- netdev->hw_features = NETIF_F_IP_CSUM |
NETIF_F_IPV6_CSUM |
NETIF_F_SG |
NETIF_F_TSO |
NETIF_F_TSO6 |
NETIF_F_RXCSUM;
- netdev->features = NETIF_F_IP_CSUM |
NETIF_F_IPV6_CSUM |
NETIF_F_SG |
NETIF_F_TSO |
NETIF_F_TSO6 |
NETIF_F_HW_VLAN_CTAG_TX |
NETIF_F_HW_VLAN_CTAG_RX;
- netdev_hw_features_zero(netdev);
- netdev_hw_features_set_array(netdev, &jme_hw_feature_set);
- netdev_active_features_zero(netdev);
- netdev_active_features_set_array(netdev, &jme_feature_set); if (using_dac) netdev->features |= NETIF_F_HIGHDMA;
diff --git a/drivers/net/ethernet/marvell/mv643xx_eth.c b/drivers/net/ethernet/marvell/mv643xx_eth.c index b6be0552a6c1..e43fa3a2af17 100644 --- a/drivers/net/ethernet/marvell/mv643xx_eth.c +++ b/drivers/net/ethernet/marvell/mv643xx_eth.c @@ -38,6 +38,7 @@ #include <linux/ethtool.h> #include <linux/platform_device.h> #include <linux/module.h> +#include <linux/netdev_features_helper.h> #include <linux/kernel.h> #include <linux/spinlock.h> #include <linux/workqueue.h> @@ -3086,6 +3087,11 @@ static const struct net_device_ops mv643xx_eth_netdev_ops = { #endif };
+static DECLARE_NETDEV_FEATURE_SET(mv643xx_feature_set,
NETIF_F_SG_BIT,
NETIF_F_IP_CSUM_BIT,
NETIF_F_TSO_BIT);
- static int mv643xx_eth_probe(struct platform_device *pdev) { struct mv643xx_eth_platform_data *pd;
@@ -3200,7 +3206,8 @@ static int mv643xx_eth_probe(struct platform_device *pdev) dev->watchdog_timeo = 2 * HZ; dev->base_addr = 0;
- dev->features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO;
netdev_active_features_zero(dev);
netdev_active_features_set_array(dev, &mv643xx_feature_set); dev->vlan_features = dev->features;
dev->features |= NETIF_F_RXCSUM;
diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c index 0caa2df87c04..b097a857fe4e 100644 --- a/drivers/net/ethernet/marvell/mvneta.c +++ b/drivers/net/ethernet/marvell/mvneta.c @@ -22,6 +22,7 @@ #include <linux/mbus.h> #include <linux/module.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/of.h> #include <linux/of_address.h> #include <linux/of_irq.h> @@ -5377,6 +5378,13 @@ static int mvneta_port_power_up(struct mvneta_port *pp, int phy_mode) return 0; }
+static DECLARE_NETDEV_FEATURE_SET(mvneta_feature_set,
NETIF_F_SG_BIT,
NETIF_F_IP_CSUM_BIT,
NETIF_F_IPV6_CSUM_BIT,
NETIF_F_TSO_BIT,
NETIF_F_RXCSUM_BIT);
- /* Device initialization routine */ static int mvneta_probe(struct platform_device *pdev) {
@@ -5612,8 +5620,8 @@ static int mvneta_probe(struct platform_device *pdev) } }
- dev->features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
NETIF_F_TSO | NETIF_F_RXCSUM;
- netdev_active_features_zero(dev);
- netdev_active_features_set_array(dev, &mvneta_feature_set); dev->hw_features |= dev->features; dev->vlan_features |= dev->features; dev->priv_flags |= IFF_LIVE_ADDR_CHANGE;
diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c index b84128b549b4..38c5ab6a5126 100644 --- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c +++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c @@ -10,6 +10,7 @@ #include <linux/acpi.h> #include <linux/kernel.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/etherdevice.h> #include <linux/platform_device.h> #include <linux/skbuff.h> @@ -6653,6 +6654,16 @@ static bool mvpp2_use_acpi_compat_mode(struct fwnode_handle *port_fwnode) !fwnode_get_named_child_node(port_fwnode, "fixed-link")); }
+static DECLARE_NETDEV_FEATURE_SET(mvpp2_feature_set,
NETIF_F_SG_BIT,
NETIF_F_IP_CSUM_BIT,
NETIF_F_IPV6_CSUM_BIT,
NETIF_F_TSO_BIT);
+static DECLARE_NETDEV_FEATURE_SET(mvpp2_hw_feature_set,
NETIF_F_RXCSUM_BIT,
NETIF_F_GRO_BIT,
NETIF_F_HW_VLAN_CTAG_FILTER_BIT);
- /* Ports initialization */ static int mvpp2_port_probe(struct platform_device *pdev, struct fwnode_handle *port_fwnode,
@@ -6846,11 +6857,11 @@ static int mvpp2_port_probe(struct platform_device *pdev, } }
- features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
NETIF_F_TSO;
- netdev_features_zero(&features);
- netdev_features_set_array(&mvpp2_feature_set, &features); dev->features = features | NETIF_F_RXCSUM;
- dev->hw_features |= features | NETIF_F_RXCSUM | NETIF_F_GRO |
NETIF_F_HW_VLAN_CTAG_FILTER;
dev->hw_features |= features;
netdev_hw_features_set_array(dev, &mvpp2_hw_feature_set);
if (mvpp22_rss_is_supported(port)) { dev->hw_features |= NETIF_F_RXHASH;
diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c index 9376d0e62914..a228447cbb2e 100644 --- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c +++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c @@ -15,6 +15,7 @@ #include <net/ip.h> #include <linux/bpf.h> #include <linux/bpf_trace.h> +#include <linux/netdev_features_helper.h>
#include "otx2_reg.h" #include "otx2_common.h" @@ -2550,6 +2551,16 @@ static void otx2_sriov_vfcfg_cleanup(struct otx2_nic *pf) } }
+static DECLARE_NETDEV_FEATURE_SET(otx2_hw_feature_set,
NETIF_F_RXCSUM_BIT,
NETIF_F_IP_CSUM_BIT,
NETIF_F_IPV6_CSUM_BIT,
NETIF_F_RXHASH_BIT,
NETIF_F_SG_BIT,
NETIF_F_TSO_BIT,
NETIF_F_TSO6_BIT,
NETIF_F_GSO_UDP_L4_BIT);
- static int otx2_probe(struct pci_dev *pdev, const struct pci_device_id *id) { struct device *dev = &pdev->dev;
@@ -2692,10 +2703,8 @@ static int otx2_probe(struct pci_dev *pdev, const struct pci_device_id *id) */ pf->iommu_domain = iommu_get_domain_for_dev(dev);
- netdev->hw_features = (NETIF_F_RXCSUM | NETIF_F_IP_CSUM |
NETIF_F_IPV6_CSUM | NETIF_F_RXHASH |
NETIF_F_SG | NETIF_F_TSO | NETIF_F_TSO6 |
NETIF_F_GSO_UDP_L4);
netdev_hw_features_zero(netdev);
netdev_hw_features_set_array(netdev, &otx2_hw_feature_set); netdev->features |= netdev->hw_features;
err = otx2_mcam_flow_init(pf);
diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_vf.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_vf.c index 86653bb8e403..08c82c0d41a4 100644 --- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_vf.c +++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_vf.c @@ -7,6 +7,7 @@
#include <linux/etherdevice.h> #include <linux/module.h> +#include <linux/netdev_features_helper.h> #include <linux/pci.h> #include <linux/net_tstamp.h>
@@ -520,6 +521,16 @@ static int otx2vf_realloc_msix_vectors(struct otx2_nic *vf) return otx2vf_register_mbox_intr(vf, false); }
+static DECLARE_NETDEV_FEATURE_SET(otx2vf_hw_feature_set,
NETIF_F_RXCSUM_BIT,
NETIF_F_IP_CSUM_BIT,
NETIF_F_IPV6_CSUM_BIT,
NETIF_F_RXHASH_BIT,
NETIF_F_SG_BIT,
NETIF_F_TSO_BIT,
NETIF_F_TSO6_BIT,
NETIF_F_GSO_UDP_L4_BIT);
- static int otx2vf_probe(struct pci_dev *pdev, const struct pci_device_id *id) { int num_vec = pci_msix_vec_count(pdev);
@@ -637,10 +648,8 @@ static int otx2vf_probe(struct pci_dev *pdev, const struct pci_device_id *id) /* Assign default mac address */ otx2_get_mac_from_af(netdev);
- netdev->hw_features = NETIF_F_RXCSUM | NETIF_F_IP_CSUM |
NETIF_F_IPV6_CSUM | NETIF_F_RXHASH |
NETIF_F_SG | NETIF_F_TSO | NETIF_F_TSO6 |
NETIF_F_GSO_UDP_L4;
- netdev_hw_features_zero(netdev);
- netdev_hw_features_set_array(netdev, &otx2vf_hw_feature_set); netdev->features = netdev->hw_features; /* Support TSO on tag interface */ netdev->vlan_features |= netdev->features;
diff --git a/drivers/net/ethernet/marvell/skge.c b/drivers/net/ethernet/marvell/skge.c index c1e985416c0e..8bdac1c90c0c 100644 --- a/drivers/net/ethernet/marvell/skge.c +++ b/drivers/net/ethernet/marvell/skge.c @@ -18,6 +18,7 @@ #include <linux/module.h> #include <linux/moduleparam.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/etherdevice.h> #include <linux/ethtool.h> #include <linux/pci.h> @@ -3806,6 +3807,10 @@ static const struct net_device_ops skge_netdev_ops = { #endif };
+static DECLARE_NETDEV_FEATURE_SET(skge_hw_feature_set,
NETIF_F_IP_CSUM_BIT,
NETIF_F_SG_BIT,
NETIF_F_RXCSUM_BIT);
/* Initialize network device */ static struct net_device *skge_devinit(struct skge_hw *hw, int port,
@@ -3860,8 +3865,8 @@ static struct net_device *skge_devinit(struct skge_hw *hw, int port, if (is_genesis(hw)) timer_setup(&skge->link_timer, xm_link_timer, 0); else {
dev->hw_features = NETIF_F_IP_CSUM | NETIF_F_SG |
NETIF_F_RXCSUM;
netdev_hw_features_zero(dev);
dev->features |= dev->hw_features; }netdev_hw_features_set_array(dev, &skge_hw_feature_set);
diff --git a/drivers/net/ethernet/marvell/sky2.c b/drivers/net/ethernet/marvell/sky2.c index bbea5458000b..e3b3b2c7aff3 100644 --- a/drivers/net/ethernet/marvell/sky2.c +++ b/drivers/net/ethernet/marvell/sky2.c @@ -16,6 +16,7 @@ #include <linux/kernel.h> #include <linux/module.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/dma-mapping.h> #include <linux/etherdevice.h> #include <linux/ethtool.h> @@ -1398,7 +1399,10 @@ static int sky2_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) return err; }
-#define SKY2_VLAN_OFFLOADS (NETIF_F_IP_CSUM | NETIF_F_SG | NETIF_F_TSO) +static DECLARE_NETDEV_FEATURE_SET(sky2_vlan_feature_set,
NETIF_F_IP_CSUM_BIT,
NETIF_F_SG_BIT,
NETIF_F_TSO_BIT);
static void sky2_vlan_mode(struct net_device *dev, netdev_features_t features) {
@@ -1417,13 +1421,13 @@ static void sky2_vlan_mode(struct net_device *dev, netdev_features_t features) sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T), TX_VLAN_TAG_ON);
dev->vlan_features |= SKY2_VLAN_OFFLOADS;
netdev_vlan_features_set_array(dev, &sky2_vlan_feature_set);
} else { sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T), TX_VLAN_TAG_OFF);
/* Can't do transmit offload of vlan without hw vlan */
dev->vlan_features &= ~SKY2_VLAN_OFFLOADS;
} }netdev_vlan_features_clear_array(dev, &sky2_vlan_feature_set);
@@ -4587,6 +4591,11 @@ static const struct net_device_ops sky2_netdev_ops[2] = { }, };
+static DECLARE_NETDEV_FEATURE_SET(sky2_hw_feature_set,
NETIF_F_IP_CSUM_BIT,
NETIF_F_SG_BIT,
NETIF_F_TSO_BIT);
- /* Initialize network device */ static struct net_device *sky2_init_netdev(struct sky2_hw *hw, unsigned port, int highmem, int wol)
@@ -4634,7 +4643,7 @@ static struct net_device *sky2_init_netdev(struct sky2_hw *hw, unsigned port,
sky2->port = port;
- dev->hw_features |= NETIF_F_IP_CSUM | NETIF_F_SG | NETIF_F_TSO;
netdev_hw_features_set_array(dev, &sky2_hw_feature_set);
if (highmem) dev->features |= NETIF_F_HIGHDMA;
@@ -4646,7 +4655,7 @@ static struct net_device *sky2_init_netdev(struct sky2_hw *hw, unsigned port, if (!(hw->flags & SKY2_HW_VLAN_BROKEN)) { dev->hw_features |= NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX;
dev->vlan_features |= SKY2_VLAN_OFFLOADS;
netdev_vlan_features_set_array(dev, &sky2_vlan_feature_set);
}
dev->features |= dev->hw_features;
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_main.c b/drivers/net/ethernet/mellanox/mlx4/en_main.c index f1259bdb1a29..edde15669886 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_main.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_main.c @@ -35,6 +35,7 @@ #include <linux/module.h> #include <linux/delay.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/slab.h>
#include <linux/mlx4/driver.h> diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c index ca4b93a01034..594a650b6bdc 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c @@ -39,6 +39,7 @@ #include <linux/delay.h> #include <linux/slab.h> #include <linux/hash.h> +#include <linux/netdev_features_helper.h> #include <net/ip.h> #include <net/vxlan.h> #include <net/devlink.h> @@ -3155,6 +3156,41 @@ void mlx4_en_set_stats_bitmap(struct mlx4_dev *dev, last_i += NUM_PHY_STATS; }
+static DECLARE_NETDEV_FEATURE_SET(mlx4_gso_feature_set,
NETIF_F_GSO_UDP_TUNNEL_BIT,
NETIF_F_GSO_UDP_TUNNEL_CSUM_BIT,
NETIF_F_GSO_PARTIAL_BIT);
+static DECLARE_NETDEV_FEATURE_SET(mlx4_hw_enc_feature_set,
NETIF_F_IP_CSUM_BIT,
NETIF_F_IPV6_CSUM_BIT,
NETIF_F_RXCSUM_BIT,
NETIF_F_TSO_BIT,
NETIF_F_TSO6_BIT,
NETIF_F_GSO_UDP_TUNNEL_BIT,
NETIF_F_GSO_UDP_TUNNEL_CSUM_BIT,
NETIF_F_GSO_PARTIAL_BIT);
+static DECLARE_NETDEV_FEATURE_SET(mlx4_feature_set,
NETIF_F_HIGHDMA_BIT,
NETIF_F_HW_VLAN_CTAG_TX_BIT,
NETIF_F_HW_VLAN_CTAG_RX_BIT,
NETIF_F_HW_VLAN_CTAG_FILTER_BIT);
+static DECLARE_NETDEV_FEATURE_SET(mlx4_hw_feature_set1,
NETIF_F_SG_BIT,
NETIF_F_IP_CSUM_BIT,
NETIF_F_IPV6_CSUM_BIT);
+static DECLARE_NETDEV_FEATURE_SET(mlx4_hw_feature_set2,
NETIF_F_RXCSUM_BIT,
NETIF_F_RXHASH_BIT);
+static DECLARE_NETDEV_FEATURE_SET(mlx4_hw_feature_set3,
NETIF_F_LOOPBACK_BIT,
NETIF_F_HW_VLAN_CTAG_TX_BIT,
NETIF_F_HW_VLAN_CTAG_RX_BIT);
+static DECLARE_NETDEV_FEATURE_SET(mlx4_vlan_tag_feature_set,
NETIF_F_HW_VLAN_CTAG_TX_BIT,
NETIF_F_HW_VLAN_CTAG_RX_BIT,
NETIF_F_HW_VLAN_STAG_TX_BIT,
NETIF_F_HW_VLAN_STAG_RX_BIT);
- int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port, struct mlx4_en_port_profile *prof) {
@@ -3322,37 +3358,28 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port, /* * Set driver features */
- dev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
netdev_hw_features_zero(dev);
netdev_hw_features_set_array(dev, &mlx4_hw_feature_set1); if (mdev->LSO_support) dev->hw_features |= NETIF_F_TSO | NETIF_F_TSO6;
if (mdev->dev->caps.tunnel_offload_mode == MLX4_TUNNEL_OFFLOAD_MODE_VXLAN) {
dev->hw_features |= NETIF_F_GSO_UDP_TUNNEL |
NETIF_F_GSO_UDP_TUNNEL_CSUM |
NETIF_F_GSO_PARTIAL;
dev->features |= NETIF_F_GSO_UDP_TUNNEL |
NETIF_F_GSO_UDP_TUNNEL_CSUM |
NETIF_F_GSO_PARTIAL;
netdev_hw_features_set_array(dev, &mlx4_gso_feature_set);
dev->gso_partial_features = NETIF_F_GSO_UDP_TUNNEL_CSUM;netdev_active_features_set_array(dev, &mlx4_gso_feature_set);
dev->hw_enc_features = NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
NETIF_F_RXCSUM |
NETIF_F_TSO | NETIF_F_TSO6 |
NETIF_F_GSO_UDP_TUNNEL |
NETIF_F_GSO_UDP_TUNNEL_CSUM |
NETIF_F_GSO_PARTIAL;
netdev_hw_enc_features_zero(dev);
netdev_hw_enc_features_set_array(dev, &mlx4_hw_enc_feature_set);
dev->udp_tunnel_nic_info = &mlx4_udp_tunnels; }
dev->vlan_features = dev->hw_features;
- dev->hw_features |= NETIF_F_RXCSUM | NETIF_F_RXHASH;
- dev->features = dev->hw_features | NETIF_F_HIGHDMA |
NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX |
NETIF_F_HW_VLAN_CTAG_FILTER;
- dev->hw_features |= NETIF_F_LOOPBACK |
NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX;
netdev_hw_features_set_array(dev, &mlx4_hw_feature_set2);
dev->features = dev->hw_features;
netdev_active_features_set_array(dev, &mlx4_feature_set);
netdev_hw_features_set_array(dev, &mlx4_hw_feature_set3);
if (!(mdev->dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_SKIP_OUTER_VLAN)) { dev->features |= NETIF_F_HW_VLAN_STAG_RX |
@@ -3372,14 +3399,8 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port, err = mlx4_get_is_vlan_offload_disabled(mdev->dev, port, &vlan_offload_disabled); if (!err && vlan_offload_disabled) {
dev->hw_features &= ~(NETIF_F_HW_VLAN_CTAG_TX |
NETIF_F_HW_VLAN_CTAG_RX |
NETIF_F_HW_VLAN_STAG_TX |
NETIF_F_HW_VLAN_STAG_RX);
dev->features &= ~(NETIF_F_HW_VLAN_CTAG_TX |
NETIF_F_HW_VLAN_CTAG_RX |
NETIF_F_HW_VLAN_STAG_TX |
NETIF_F_HW_VLAN_STAG_RX);
netdev_hw_features_clear_array(dev, &mlx4_vlan_tag_feature_set);
} } else { if (mdev->dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_PHV_EN &&netdev_active_features_clear_array(dev, &mlx4_vlan_tag_feature_set);
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib.c b/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib.c index 0a99a020a3b2..766abe31749b 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib.c @@ -31,6 +31,7 @@ */
#include <rdma/ib_verbs.h> +#include <linux/netdev_features_helper.h> #include <linux/mlx5/fs.h> #include "en.h" #include "en/params.h" @@ -72,6 +73,16 @@ static void mlx5i_build_nic_params(struct mlx5_core_dev *mdev, params->tunneled_offload_en = false; }
+static DECLARE_NETDEV_FEATURE_SET(mlx5i_hw_feature_set,
NETIF_F_SG_BIT,
NETIF_F_IP_CSUM_BIT,
NETIF_F_IPV6_CSUM_BIT,
NETIF_F_GRO_BIT,
NETIF_F_TSO_BIT,
NETIF_F_TSO6_BIT,
NETIF_F_RXCSUM_BIT,
NETIF_F_RXHASH_BIT);
- /* Called directly after IPoIB netdevice was created to initialize SW structs */ int mlx5i_init(struct mlx5_core_dev *mdev, struct net_device *netdev) {
@@ -87,14 +98,7 @@ int mlx5i_init(struct mlx5_core_dev *mdev, struct net_device *netdev) mlx5e_timestamp_init(priv);
/* netdev init */
- netdev->hw_features |= NETIF_F_SG;
- netdev->hw_features |= NETIF_F_IP_CSUM;
- netdev->hw_features |= NETIF_F_IPV6_CSUM;
- netdev->hw_features |= NETIF_F_GRO;
- netdev->hw_features |= NETIF_F_TSO;
- netdev->hw_features |= NETIF_F_TSO6;
- netdev->hw_features |= NETIF_F_RXCSUM;
- netdev->hw_features |= NETIF_F_RXHASH;
netdev_hw_features_set_array(netdev, &mlx5i_hw_feature_set);
netdev->netdev_ops = &mlx5i_netdev_ops; netdev->ethtool_ops = &mlx5i_ethtool_ops;
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c index 1e240cdd9cbd..a38ed21cfbdf 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c @@ -6,6 +6,7 @@ #include <linux/types.h> #include <linux/pci.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/etherdevice.h> #include <linux/ethtool.h> #include <linux/slab.h> @@ -1596,6 +1597,16 @@ static int mlxsw_sp_port_label_info_get(struct mlxsw_sp *mlxsw_sp, return 0; }
+static DECLARE_NETDEV_FEATURE_SET(mlxsw_feature_set,
NETIF_F_NETNS_LOCAL_BIT,
NETIF_F_LLTX_BIT,
NETIF_F_SG_BIT,
NETIF_F_HW_VLAN_CTAG_FILTER_BIT,
NETIF_F_HW_TC_BIT);
+static DECLARE_NETDEV_FEATURE_SET(mlxsw_hw_feature_set,
NETIF_F_HW_TC_BIT,
NETIF_F_LOOPBACK_BIT);
- static int mlxsw_sp_port_create(struct mlxsw_sp *mlxsw_sp, u16 local_port, bool split, struct mlxsw_sp_port_mapping *port_mapping)
@@ -1682,9 +1693,8 @@ static int mlxsw_sp_port_create(struct mlxsw_sp *mlxsw_sp, u16 local_port,
netif_carrier_off(dev);
- dev->features |= NETIF_F_NETNS_LOCAL | NETIF_F_LLTX | NETIF_F_SG |
NETIF_F_HW_VLAN_CTAG_FILTER | NETIF_F_HW_TC;
- dev->hw_features |= NETIF_F_HW_TC | NETIF_F_LOOPBACK;
netdev_active_features_set_array(dev, &mlxsw_feature_set);
netdev_hw_features_set_array(dev, &mlxsw_hw_feature_set);
dev->min_mtu = 0; dev->max_mtu = ETH_MAX_MTU;
diff --git a/drivers/net/ethernet/micrel/ksz884x.c b/drivers/net/ethernet/micrel/ksz884x.c index 2b3eb5ed8233..07b6d0124d1a 100644 --- a/drivers/net/ethernet/micrel/ksz884x.c +++ b/drivers/net/ethernet/micrel/ksz884x.c @@ -26,6 +26,7 @@ #include <linux/sched.h> #include <linux/slab.h> #include <linux/micrel_phy.h> +#include <linux/netdev_features_helper.h>
/* DMA Registers */ @@ -6686,6 +6687,11 @@ static int stp; */ static int fast_aging;
+static DECLARE_NETDEV_FEATURE_SET(ksz_hw_feature_set,
NETIF_F_IP_CSUM_BIT,
NETIF_F_SG_BIT,
NETIF_F_RXCSUM_BIT);
- /**
- netdev_init - initialize network device.
- @dev: Network device.
@@ -6705,7 +6711,8 @@ static int __init netdev_init(struct net_device *dev) /* 500 ms timeout */ dev->watchdog_timeo = HZ / 2;
- dev->hw_features = NETIF_F_IP_CSUM | NETIF_F_SG | NETIF_F_RXCSUM;
netdev_hw_features_zero(dev);
netdev_hw_features_set_array(dev, &ksz_hw_feature_set);
/*
- Hardware does not really support IPv6 checksum generation, but
diff --git a/drivers/net/ethernet/microchip/lan743x_main.c b/drivers/net/ethernet/microchip/lan743x_main.c index a9a1dea6d731..5f429b54bc30 100644 --- a/drivers/net/ethernet/microchip/lan743x_main.c +++ b/drivers/net/ethernet/microchip/lan743x_main.c @@ -4,6 +4,7 @@ #include <linux/module.h> #include <linux/pci.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/etherdevice.h> #include <linux/crc32.h> #include <linux/microchipphy.h> @@ -3323,6 +3324,11 @@ static int lan743x_mdiobus_init(struct lan743x_adapter *adapter) return ret; }
+static DECLARE_NETDEV_FEATURE_SET(lan743x_hw_feature_set,
NETIF_F_SG_BIT,
NETIF_F_TSO_BIT,
NETIF_F_HW_CSUM_BIT);
- /* lan743x_pcidev_probe - Device Initialization Routine
- @pdev: PCI device information struct
- @id: entry in lan743x_pci_tbl
@@ -3383,7 +3389,8 @@ static int lan743x_pcidev_probe(struct pci_dev *pdev,
adapter->netdev->netdev_ops = &lan743x_netdev_ops; adapter->netdev->ethtool_ops = &lan743x_ethtool_ops;
- adapter->netdev->features = NETIF_F_SG | NETIF_F_TSO | NETIF_F_HW_CSUM;
netdev_active_features_zero(adapter->netdev);
netdev_active_features_set_array(adapter->netdev, &lan743x_hw_feature_set); adapter->netdev->hw_features = adapter->netdev->features;
/* carrier off reporting is important to ethtool even BEFORE open */
diff --git a/drivers/net/ethernet/microsoft/mana/mana_en.c b/drivers/net/ethernet/microsoft/mana/mana_en.c index 9259a74eca40..d2a424573d89 100644 --- a/drivers/net/ethernet/microsoft/mana/mana_en.c +++ b/drivers/net/ethernet/microsoft/mana/mana_en.c @@ -2039,6 +2039,15 @@ int mana_detach(struct net_device *ndev, bool from_close) return 0; }
+static DECLARE_NETDEV_FEATURE_SET(mana_hw_feature_set,
NETIF_F_SG_BIT,
NETIF_F_IP_CSUM_BIT,
NETIF_F_IPV6_CSUM_BIT,
NETIF_F_RXCSUM_BIT,
NETIF_F_TSO_BIT,
NETIF_F_TSO6_BIT,
NETIF_F_RXHASH_BIT);
- static int mana_probe_port(struct mana_context *ac, int port_idx, struct net_device **ndev_storage) {
@@ -2081,10 +2090,8 @@ static int mana_probe_port(struct mana_context *ac, int port_idx,
netdev_lockdep_set_classes(ndev);
- ndev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
- ndev->hw_features |= NETIF_F_RXCSUM;
- ndev->hw_features |= NETIF_F_TSO | NETIF_F_TSO6;
- ndev->hw_features |= NETIF_F_RXHASH;
- netdev_hw_features_zero(ndev);
- netdev_hw_features_set_array(ndev, &mana_hw_feature_set); ndev->features = ndev->hw_features; ndev->vlan_features = 0;
diff --git a/drivers/net/ethernet/mscc/ocelot_net.c b/drivers/net/ethernet/mscc/ocelot_net.c index 5e6136e80282..0f88dac6920a 100644 --- a/drivers/net/ethernet/mscc/ocelot_net.c +++ b/drivers/net/ethernet/mscc/ocelot_net.c @@ -10,6 +10,7 @@
#include <linux/dsa/ocelot.h> #include <linux/if_bridge.h> +#include <linux/netdev_features_helper.h> #include <linux/of_net.h> #include <linux/phy/phy.h> #include <net/pkt_cls.h> @@ -1809,6 +1810,14 @@ static int ocelot_port_phylink_create(struct ocelot *ocelot, int port, return 0; }
+static DECLARE_NETDEV_FEATURE_SET(ocelot_hw_feature_set,
NETIF_F_HW_VLAN_CTAG_FILTER_BIT,
NETIF_F_RXFCS_BIT,
NETIF_F_HW_TC_BIT);
+static DECLARE_NETDEV_FEATURE_SET(ocelot_feature_set,
NETIF_F_HW_VLAN_CTAG_FILTER_BIT,
NETIF_F_HW_TC_BIT);
- int ocelot_probe_port(struct ocelot *ocelot, int port, struct regmap *target, struct device_node *portnp) {
@@ -1833,9 +1842,8 @@ int ocelot_probe_port(struct ocelot *ocelot, int port, struct regmap *target, dev->ethtool_ops = &ocelot_ethtool_ops; dev->max_mtu = OCELOT_JUMBO_MTU;
- dev->hw_features |= NETIF_F_HW_VLAN_CTAG_FILTER | NETIF_F_RXFCS |
NETIF_F_HW_TC;
- dev->features |= NETIF_F_HW_VLAN_CTAG_FILTER | NETIF_F_HW_TC;
netdev_hw_features_set_array(dev, &ocelot_hw_feature_set);
netdev_active_features_set_array(dev, &ocelot_feature_set);
err = of_get_ethdev_address(portnp, dev); if (err)
diff --git a/drivers/net/ethernet/myricom/myri10ge/myri10ge.c b/drivers/net/ethernet/myricom/myri10ge/myri10ge.c index 971dde8c3286..cffe22b5f5f3 100644 --- a/drivers/net/ethernet/myricom/myri10ge/myri10ge.c +++ b/drivers/net/ethernet/myricom/myri10ge/myri10ge.c @@ -42,6 +42,7 @@
#include <linux/tcp.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/skbuff.h> #include <linux/string.h> #include <linux/module.h> @@ -243,7 +244,7 @@ struct myri10ge_priv { unsigned long serial_number; int vendor_specific_offset; int fw_multicast_support;
- u32 features;
- netdev_features_t features; u32 max_tso6; u32 read_dma; u32 write_dma;
@@ -681,13 +682,19 @@ static int myri10ge_adopt_running_firmware(struct myri10ge_priv *mgp) return status; }
+static DECLARE_NETDEV_FEATURE_SET(myri10ge_feature_set,
NETIF_F_SG_BIT,
NETIF_F_HW_CSUM_BIT,
NETIF_F_TSO_BIT);
static int myri10ge_get_firmware_capabilities(struct myri10ge_priv *mgp) { struct myri10ge_cmd cmd; int status;
/* probe for IPv6 TSO support */
- mgp->features = NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_TSO;
- netdev_features_zero(&mgp->features);
- netdev_features_set_array(&myri10ge_feature_set, &mgp->features); status = myri10ge_send_cmd(mgp, MXGEFW_CMD_GET_MAX_TSO6_HDR_SIZE, &cmd, 0); if (status == 0) {
diff --git a/drivers/net/ethernet/neterion/s2io.c b/drivers/net/ethernet/neterion/s2io.c index 30f955efa830..79dd414f6e36 100644 --- a/drivers/net/ethernet/neterion/s2io.c +++ b/drivers/net/ethernet/neterion/s2io.c @@ -60,6 +60,7 @@ #include <linux/dma-mapping.h> #include <linux/kernel.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/etherdevice.h> #include <linux/mdio.h> #include <linux/skbuff.h> @@ -7638,6 +7639,19 @@ static const struct net_device_ops s2io_netdev_ops = { #endif };
+static DECLARE_NETDEV_FEATURE_SET(s2io_hw_feature_set,
NETIF_F_SG_BIT,
NETIF_F_IP_CSUM_BIT,
NETIF_F_TSO_BIT,
NETIF_F_TSO6_BIT,
NETIF_F_RXCSUM_BIT,
NETIF_F_LRO_BIT,
NETIF_F_SG_BIT);
+static DECLARE_NETDEV_FEATURE_SET(s2io_feature_set,
NETIF_F_HW_VLAN_CTAG_TX_BIT,
NETIF_F_HW_VLAN_CTAG_RX_BIT,
NETIF_F_HIGHDMA_BIT);
- /**
- s2io_init_nic - Initialization of the adapter .
- @pdev : structure containing the PCI related information of the device.
@@ -7853,12 +7867,10 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) /* Driver entry points */ dev->netdev_ops = &s2io_netdev_ops; dev->ethtool_ops = &netdev_ethtool_ops;
- dev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM |
NETIF_F_TSO | NETIF_F_TSO6 |
NETIF_F_RXCSUM | NETIF_F_LRO;
- dev->features |= dev->hw_features |
NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX |
NETIF_F_HIGHDMA;
- netdev_hw_features_zero(dev);
- netdev_hw_features_set_array(dev, &s2io_hw_feature_set);
- dev->features |= dev->hw_features;
- netdev_active_features_set_array(dev, &s2io_feature_set); dev->watchdog_timeo = WATCH_DOG_TIMEOUT; INIT_WORK(&sp->rst_timer_task, s2io_restart_nic); INIT_WORK(&sp->set_link_task, s2io_set_link);
diff --git a/drivers/net/ethernet/nvidia/forcedeth.c b/drivers/net/ethernet/nvidia/forcedeth.c index 5116badaf091..71c5363084e6 100644 --- a/drivers/net/ethernet/nvidia/forcedeth.c +++ b/drivers/net/ethernet/nvidia/forcedeth.c @@ -37,6 +37,7 @@ #include <linux/pci.h> #include <linux/interrupt.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/etherdevice.h> #include <linux/delay.h> #include <linux/sched.h> @@ -5706,6 +5707,12 @@ static const struct net_device_ops nv_netdev_ops_optimized = { #endif };
+static DECLARE_NETDEV_FEATURE_SET(nv_hw_feature_set,
NETIF_F_IP_CSUM_BIT,
NETIF_F_SG_BIT,
NETIF_F_TSO_BIT,
NETIF_F_RXCSUM_BIT);
- static int nv_probe(struct pci_dev *pci_dev, const struct pci_device_id *id) { struct net_device *dev;
@@ -5811,8 +5818,7 @@ static int nv_probe(struct pci_dev *pci_dev, const struct pci_device_id *id)
if (id->driver_data & DEV_HAS_CHECKSUM) { np->txrxctl_bits |= NVREG_TXRXCTL_RXCHECK;
dev->hw_features |= NETIF_F_IP_CSUM | NETIF_F_SG |
NETIF_F_TSO | NETIF_F_RXCSUM;
netdev_hw_features_set_array(dev, &nv_hw_feature_set);
}
np->vlanctl_bits = 0;
diff --git a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c index 46da937ad27f..8213d2300ff4 100644 --- a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c +++ b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c @@ -13,6 +13,7 @@ #include <linux/gpio/machine.h> #include <linux/iopoll.h> #include <linux/module.h> +#include <linux/netdev_features_helper.h> #include <linux/net_tstamp.h> #include <linux/ptp_classify.h> #include <linux/ptp_pch.h> @@ -2463,6 +2464,11 @@ static void pch_gbe_remove(struct pci_dev *pdev) free_netdev(netdev); }
+static DECLARE_NETDEV_FEATURE_SET(pch_gbe_hw_feature_set,
NETIF_F_RXCSUM_BIT,
NETIF_F_IP_CSUM_BIT,
NETIF_F_IPV6_CSUM_BIT);
- static int pch_gbe_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id) {
@@ -2518,8 +2524,8 @@ static int pch_gbe_probe(struct pci_dev *pdev, netdev->watchdog_timeo = PCH_GBE_WATCHDOG_PERIOD; netif_napi_add(netdev, &adapter->napi, pch_gbe_napi_poll, NAPI_POLL_WEIGHT);
- netdev->hw_features = NETIF_F_RXCSUM |
NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
- netdev_hw_features_zero(netdev);
- netdev_hw_features_set_array(netdev, &pch_gbe_hw_feature_set); netdev->features = netdev->hw_features; pch_gbe_set_ethtool_ops(netdev);
diff --git a/drivers/net/ethernet/pasemi/pasemi_mac.c b/drivers/net/ethernet/pasemi/pasemi_mac.c index f0ace3a0e85c..55437fd2de69 100644 --- a/drivers/net/ethernet/pasemi/pasemi_mac.c +++ b/drivers/net/ethernet/pasemi/pasemi_mac.c @@ -1672,6 +1672,13 @@ static const struct net_device_ops pasemi_netdev_ops = { #endif };
+static DECLARE_NETDEV_FEATURE_SET(pasemi_feature_set,
NETIF_F_IP_CSUM_BIT,
NETIF_F_LLTX_BIT,
NETIF_F_SG_BIT,
NETIF_F_HIGHDMA_BIT,
NETIF_F_GSO_BIT);
- static int pasemi_mac_probe(struct pci_dev *pdev, const struct pci_device_id *ent) {
@@ -1699,8 +1706,8 @@ pasemi_mac_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
netif_napi_add(dev, &mac->napi, pasemi_mac_poll, 64);
- dev->features = NETIF_F_IP_CSUM | NETIF_F_LLTX | NETIF_F_SG |
NETIF_F_HIGHDMA | NETIF_F_GSO;
netdev_active_features_zero(dev);
netdev_active_features_set_array(dev, &pasemi_feature_set);
mac->dma_pdev = pci_get_device(PCI_VENDOR_ID_PASEMI, 0xa007, NULL); if (!mac->dma_pdev) {
diff --git a/drivers/net/ethernet/pensando/ionic/ionic_lif.c b/drivers/net/ethernet/pensando/ionic/ionic_lif.c index f3568901eb91..3c7e7ea695bf 100644 --- a/drivers/net/ethernet/pensando/ionic/ionic_lif.c +++ b/drivers/net/ethernet/pensando/ionic/ionic_lif.c @@ -5,6 +5,7 @@ #include <linux/printk.h> #include <linux/dynamic_debug.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/etherdevice.h> #include <linux/if_vlan.h> #include <linux/rtnetlink.h> @@ -1479,6 +1480,17 @@ static int ionic_set_nic_features(struct ionic_lif *lif, return 0; }
+static DECLARE_NETDEV_FEATURE_SET(ionic_feature_set,
NETIF_F_HW_VLAN_CTAG_TX_BIT,
NETIF_F_HW_VLAN_CTAG_RX_BIT,
NETIF_F_HW_VLAN_CTAG_FILTER_BIT,
NETIF_F_SG_BIT,
NETIF_F_HW_CSUM_BIT,
NETIF_F_RXCSUM_BIT,
NETIF_F_TSO_BIT,
NETIF_F_TSO6_BIT,
NETIF_F_TSO_ECN_BIT);
- static int ionic_init_nic_features(struct ionic_lif *lif) { struct net_device *netdev = lif->netdev;
@@ -1486,15 +1498,8 @@ static int ionic_init_nic_features(struct ionic_lif *lif) int err;
/* set up what we expect to support by default */
- features = NETIF_F_HW_VLAN_CTAG_TX |
NETIF_F_HW_VLAN_CTAG_RX |
NETIF_F_HW_VLAN_CTAG_FILTER |
NETIF_F_SG |
NETIF_F_HW_CSUM |
NETIF_F_RXCSUM |
NETIF_F_TSO |
NETIF_F_TSO6 |
NETIF_F_TSO_ECN;
netdev_features_zero(&features);
netdev_features_set_array(&ionic_feature_set, &features);
if (lif->nxqs > 1) features |= NETIF_F_RXHASH;
diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c b/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c index 4e6f00af17d9..72cbf78344b5 100644 --- a/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c +++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c @@ -5,6 +5,7 @@
- All rights reserved.
*/
+#include <linux/netdev_features_helper.h> #include <linux/slab.h> #include <linux/vmalloc.h> #include <linux/interrupt.h> @@ -1327,6 +1328,12 @@ netxen_nic_reset_context(struct netxen_adapter *adapter) return err; }
+static DECLARE_NETDEV_FEATURE_SET(netxen_hw_feature_set,
NETIF_F_SG_BIT,
NETIF_F_IP_CSUM_BIT,
NETIF_F_TSO_BIT,
NETIF_F_RXCSUM_BIT);
- static int netxen_setup_netdev(struct netxen_adapter *adapter, struct net_device *netdev)
@@ -1347,8 +1354,8 @@ netxen_setup_netdev(struct netxen_adapter *adapter,
netdev->ethtool_ops = &netxen_nic_ethtool_ops;
- netdev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO |
NETIF_F_RXCSUM;
netdev_hw_features_zero(netdev);
netdev_hw_features_set_array(netdev, &netxen_hw_feature_set);
if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) netdev->hw_features |= NETIF_F_IPV6_CSUM | NETIF_F_TSO6;
diff --git a/drivers/net/ethernet/qlogic/qede/qede_main.c b/drivers/net/ethernet/qlogic/qede/qede_main.c index f56b679adb4b..04af61f4122a 100644 --- a/drivers/net/ethernet/qlogic/qede/qede_main.c +++ b/drivers/net/ethernet/qlogic/qede/qede_main.c @@ -20,6 +20,7 @@ #include <asm/param.h> #include <linux/io.h> #include <linux/netdev_features.h> +#include <linux/netdev_features_helper.h> #include <linux/udp.h> #include <linux/tcp.h> #include <net/udp_tunnel.h> @@ -820,6 +821,35 @@ static struct qede_dev *qede_alloc_etherdev(struct qed_dev *cdev, return edev; }
+static DECLARE_NETDEV_FEATURE_SET(qede_hw_feature_set,
NETIF_F_GRO_BIT,
NETIF_F_GRO_HW_BIT,
NETIF_F_SG_BIT,
NETIF_F_IP_CSUM_BIT,
NETIF_F_IPV6_CSUM_BIT,
NETIF_F_TSO_BIT,
NETIF_F_TSO6_BIT,
NETIF_F_HW_TC_BIT);
+static DECLARE_NETDEV_FEATURE_SET(qede_hw_enc_feature_set,
NETIF_F_IP_CSUM_BIT,
NETIF_F_IPV6_CSUM_BIT,
NETIF_F_SG_BIT,
NETIF_F_TSO_BIT,
NETIF_F_TSO_ECN_BIT,
NETIF_F_TSO6_BIT,
NETIF_F_RXCSUM_BIT);
+static DECLARE_NETDEV_FEATURE_SET(qede_vlan_feature_set,
NETIF_F_RXHASH_BIT,
NETIF_F_RXCSUM_BIT,
NETIF_F_HIGHDMA_BIT);
+static DECLARE_NETDEV_FEATURE_SET(qede_feature_set,
NETIF_F_RXHASH_BIT,
NETIF_F_RXCSUM_BIT,
NETIF_F_HW_VLAN_CTAG_RX_BIT,
NETIF_F_HIGHDMA_BIT,
NETIF_F_HW_VLAN_CTAG_FILTER_BIT,
NETIF_F_HW_VLAN_CTAG_TX_BIT);
- static void qede_init_ndev(struct qede_dev *edev) { struct net_device *ndev = edev->ndev;
@@ -850,9 +880,8 @@ static void qede_init_ndev(struct qede_dev *edev) ndev->priv_flags |= IFF_UNICAST_FLT;
/* user-changeble features */
- hw_features = NETIF_F_GRO | NETIF_F_GRO_HW | NETIF_F_SG |
NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_HW_TC;
netdev_features_zero(&hw_features);
netdev_features_set_array(&qede_hw_feature_set, &hw_features);
if (edev->dev_info.common.b_arfs_capable) hw_features |= NETIF_F_NTUPLE;
@@ -863,10 +892,8 @@ static void qede_init_ndev(struct qede_dev *edev)
if (udp_tunnel_enable || edev->dev_info.common.gre_enable) { hw_features |= NETIF_F_TSO_ECN;
ndev->hw_enc_features = NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
NETIF_F_SG | NETIF_F_TSO |
NETIF_F_TSO_ECN | NETIF_F_TSO6 |
NETIF_F_RXCSUM;
netdev_hw_enc_features_zero(ndev);
netdev_hw_enc_features_set_array(ndev, &qede_hw_enc_feature_set);
}
if (udp_tunnel_enable) {
@@ -884,11 +911,10 @@ static void qede_init_ndev(struct qede_dev *edev) NETIF_F_GSO_GRE_CSUM); }
- ndev->vlan_features = hw_features | NETIF_F_RXHASH | NETIF_F_RXCSUM |
NETIF_F_HIGHDMA;
- ndev->features = hw_features | NETIF_F_RXHASH | NETIF_F_RXCSUM |
NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_HIGHDMA |
NETIF_F_HW_VLAN_CTAG_FILTER | NETIF_F_HW_VLAN_CTAG_TX;
ndev->vlan_features = hw_features;
netdev_vlan_features_set_array(ndev, &qede_vlan_feature_set);
ndev->features = hw_features;
netdev_active_features_set_array(ndev, &qede_feature_set);
ndev->hw_features = hw_features;
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c index 4b8bc46f55c2..2401cbc015f0 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c @@ -7,6 +7,7 @@ #include <linux/slab.h> #include <net/ip.h> #include <linux/bitops.h> +#include <linux/netdev_features_helper.h>
#include "qlcnic.h" #include "qlcnic_hdr.h" @@ -1020,14 +1021,24 @@ int qlcnic_change_mtu(struct net_device *netdev, int mtu) return rc; }
+static DECLARE_NETDEV_FEATURE_SET(qlcnic_csum_feature_set,
NETIF_F_RXCSUM_BIT,
NETIF_F_IP_CSUM_BIT,
NETIF_F_IPV6_CSUM_BIT);
+static DECLARE_NETDEV_FEATURE_SET(qlcnic_changable_feature_set,
NETIF_F_RXCSUM_BIT,
NETIF_F_IP_CSUM_BIT,
NETIF_F_IPV6_CSUM_BIT,
NETIF_F_TSO_BIT,
NETIF_F_TSO6_BIT);
static netdev_features_t qlcnic_process_flags(struct qlcnic_adapter *adapter, netdev_features_t features) { u32 offload_flags = adapter->offload_flags;
if (offload_flags & BIT_0) {
features |= NETIF_F_RXCSUM | NETIF_F_IP_CSUM |
NETIF_F_IPV6_CSUM;
adapter->rx_csum = 1; if (QLCNIC_IS_TSO_CAPABLE(adapter)) { if (!(offload_flags & BIT_1))netdev_features_set_array(&qlcnic_csum_feature_set, &features);
@@ -1041,9 +1052,7 @@ static netdev_features_t qlcnic_process_flags(struct qlcnic_adapter *adapter, features |= NETIF_F_TSO6; } } else {
features &= ~(NETIF_F_RXCSUM |
NETIF_F_IP_CSUM |
NETIF_F_IPV6_CSUM);
netdev_features_clear_array(&qlcnic_csum_feature_set, &features);
if (QLCNIC_IS_TSO_CAPABLE(adapter)) features &= ~(NETIF_F_TSO | NETIF_F_TSO6);
@@ -1057,6 +1066,7 @@ netdev_features_t qlcnic_fix_features(struct net_device *netdev, netdev_features_t features) { struct qlcnic_adapter *adapter = netdev_priv(netdev);
netdev_features_t changeable; netdev_features_t changed;
if (qlcnic_82xx_check(adapter) &&
@@ -1065,11 +1075,10 @@ netdev_features_t qlcnic_fix_features(struct net_device *netdev, features = qlcnic_process_flags(adapter, features); } else { changed = features ^ netdev->features;
features ^= changed & (NETIF_F_RXCSUM |
NETIF_F_IP_CSUM |
NETIF_F_IPV6_CSUM |
NETIF_F_TSO |
NETIF_F_TSO6);
netdev_features_zero(&changeable);
netdev_features_set_array(&qlcnic_changable_feature_set,
&changeable);
} }features ^= changed & changeable;
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c index 28476b982bab..f8c043914d6a 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c @@ -14,6 +14,7 @@ #include <linux/inetdevice.h> #include <linux/aer.h> #include <linux/log2.h> +#include <linux/netdev_features_helper.h> #include <linux/pci.h> #include <net/vxlan.h>
@@ -2258,6 +2259,25 @@ static int qlcnic_set_real_num_queues(struct qlcnic_adapter *adapter, return err; }
+static DECLARE_NETDEV_FEATURE_SET(qlcnic_feature_set,
NETIF_F_SG_BIT,
NETIF_F_IP_CSUM_BIT,
NETIF_F_RXCSUM_BIT,
NETIF_F_IPV6_CSUM_BIT,
NETIF_F_GRO_BIT,
NETIF_F_HW_VLAN_CTAG_RX_BIT,
NETIF_F_HIGHDMA_BIT);
+static DECLARE_NETDEV_FEATURE_SET(qlcnic_vlan_feature_set,
NETIF_F_SG_BIT,
NETIF_F_IP_CSUM_BIT,
NETIF_F_IPV6_CSUM_BIT,
NETIF_F_HIGHDMA_BIT);
+static DECLARE_NETDEV_FEATURE_SET(qlcnic_hw_enc_feature_set,
NETIF_F_IP_CSUM_BIT,
NETIF_F_GSO_UDP_TUNNEL_BIT,
NETIF_F_TSO_BIT,
NETIF_F_TSO6_BIT);
- int qlcnic_setup_netdev(struct qlcnic_adapter *adapter, struct net_device *netdev) {
@@ -2276,11 +2296,8 @@ qlcnic_setup_netdev(struct qlcnic_adapter *adapter, struct net_device *netdev) netdev->ethtool_ops = (qlcnic_sriov_vf_check(adapter)) ? &qlcnic_sriov_vf_ethtool_ops : &qlcnic_ethtool_ops;
- netdev->features |= (NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_RXCSUM |
NETIF_F_IPV6_CSUM | NETIF_F_GRO |
NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_HIGHDMA);
- netdev->vlan_features |= (NETIF_F_SG | NETIF_F_IP_CSUM |
NETIF_F_IPV6_CSUM | NETIF_F_HIGHDMA);
netdev_active_features_set_array(netdev, &qlcnic_feature_set);
netdev_vlan_features_set_array(netdev, &qlcnic_vlan_feature_set);
if (QLCNIC_IS_TSO_CAPABLE(adapter)) { netdev->features |= (NETIF_F_TSO | NETIF_F_TSO6);
@@ -2300,10 +2317,9 @@ qlcnic_setup_netdev(struct qlcnic_adapter *adapter, struct net_device *netdev) netdev->features |= NETIF_F_GSO_UDP_TUNNEL;
/* encapsulation Tx offload supported by Adapter */
netdev->hw_enc_features = NETIF_F_IP_CSUM |
NETIF_F_GSO_UDP_TUNNEL |
NETIF_F_TSO |
NETIF_F_TSO6;
netdev_vlan_features_zero(netdev);
netdev_vlan_features_set_array(netdev,
&qlcnic_hw_enc_feature_set);
}
if (qlcnic_encap_rx_offload(adapter)) {
diff --git a/drivers/net/ethernet/qualcomm/emac/emac.c b/drivers/net/ethernet/qualcomm/emac/emac.c index a55c52696d49..c302d50324fb 100644 --- a/drivers/net/ethernet/qualcomm/emac/emac.c +++ b/drivers/net/ethernet/qualcomm/emac/emac.c @@ -9,6 +9,7 @@ #include <linux/interrupt.h> #include <linux/io.h> #include <linux/module.h> +#include <linux/netdev_features_helper.h> #include <linux/of.h> #include <linux/of_net.h> #include <linux/of_device.h> @@ -590,6 +591,20 @@ static const struct acpi_device_id emac_acpi_match[] = { MODULE_DEVICE_TABLE(acpi, emac_acpi_match); #endif
+static DECLARE_NETDEV_FEATURE_SET(emac_feature_set,
NETIF_F_SG_BIT,
NETIF_F_HW_CSUM_BIT,
NETIF_F_RXCSUM_BIT,
NETIF_F_TSO_BIT,
NETIF_F_TSO6_BIT,
NETIF_F_HW_VLAN_CTAG_RX_BIT,
NETIF_F_HW_VLAN_CTAG_TX_BIT);
+static DECLARE_NETDEV_FEATURE_SET(emac_vlan_feature_set,
NETIF_F_SG_BIT,
NETIF_F_HW_CSUM_BIT,
NETIF_F_TSO_BIT,
NETIF_F_TSO6_BIT);
- static int emac_probe(struct platform_device *pdev) { struct net_device *netdev;
@@ -665,13 +680,11 @@ static int emac_probe(struct platform_device *pdev) }
/* set hw features */
- netdev->features = NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_RXCSUM |
NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_HW_VLAN_CTAG_RX |
NETIF_F_HW_VLAN_CTAG_TX;
- netdev_active_features_zero(netdev);
- netdev_active_features_set_array(netdev, &emac_feature_set); netdev->hw_features = netdev->features;
- netdev->vlan_features |= NETIF_F_SG | NETIF_F_HW_CSUM |
NETIF_F_TSO | NETIF_F_TSO6;
netdev_vlan_features_set_array(netdev, &emac_vlan_feature_set);
/* MTU range: 46 - 9194 */ netdev->min_mtu = EMAC_MIN_ETH_FRAME_SIZE -
diff --git a/drivers/net/ethernet/qualcomm/rmnet/rmnet_vnd.c b/drivers/net/ethernet/qualcomm/rmnet/rmnet_vnd.c index 1b2119b1d48a..92215121428f 100644 --- a/drivers/net/ethernet/qualcomm/rmnet/rmnet_vnd.c +++ b/drivers/net/ethernet/qualcomm/rmnet/rmnet_vnd.c @@ -7,6 +7,7 @@ #include <linux/etherdevice.h> #include <linux/ethtool.h> #include <linux/if_arp.h> +#include <linux/netdev_features_helper.h> #include <net/pkt_sched.h> #include "rmnet_config.h" #include "rmnet_handlers.h" @@ -243,6 +244,12 @@ void rmnet_vnd_setup(struct net_device *rmnet_dev) eth_random_addr(rmnet_dev->perm_addr); }
+static DECLARE_NETDEV_FEATURE_SET(rmnet_hw_feature_set,
NETIF_F_RXCSUM_BIT,
NETIF_F_IP_CSUM_BIT,
NETIF_F_IPV6_CSUM_BIT,
NETIF_F_SG_BIT);
/* Exposed API */
int rmnet_vnd_newlink(u8 id, struct net_device *rmnet_dev,
@@ -261,9 +268,8 @@ int rmnet_vnd_newlink(u8 id, struct net_device *rmnet_dev, return -EBUSY; }
- rmnet_dev->hw_features = NETIF_F_RXCSUM;
- rmnet_dev->hw_features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
- rmnet_dev->hw_features |= NETIF_F_SG;
netdev_hw_features_zero(rmnet_dev);
netdev_hw_features_set_array(rmnet_dev, &rmnet_hw_feature_set);
priv->real_dev = real_dev;
diff --git a/drivers/net/ethernet/realtek/8139cp.c b/drivers/net/ethernet/realtek/8139cp.c index e0feeec13da6..c5c2e491d251 100644 --- a/drivers/net/ethernet/realtek/8139cp.c +++ b/drivers/net/ethernet/realtek/8139cp.c @@ -58,6 +58,7 @@ #include <linux/kernel.h> #include <linux/compiler.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/etherdevice.h> #include <linux/init.h> #include <linux/interrupt.h> @@ -1883,6 +1884,18 @@ static const struct net_device_ops cp_netdev_ops = { #endif };
+static DECLARE_NETDEV_FEATURE_SET(cp_default_feature_set,
NETIF_F_SG_BIT,
NETIF_F_IP_CSUM_BIT,
NETIF_F_TSO_BIT,
NETIF_F_HW_VLAN_CTAG_TX_BIT,
NETIF_F_HW_VLAN_CTAG_RX_BIT);
+static DECLARE_NETDEV_FEATURE_SET(cp_vlan_feature_set,
NETIF_F_SG_BIT,
NETIF_F_IP_CSUM_BIT,
NETIF_F_TSO_BIT,
NETIF_F_HIGHDMA_BIT);
- static int cp_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) { struct net_device *dev;
@@ -1990,16 +2003,14 @@ static int cp_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) dev->ethtool_ops = &cp_ethtool_ops; dev->watchdog_timeo = TX_TIMEOUT;
- dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO |
NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX;
netdev_active_features_set_array(dev, &cp_default_feature_set);
if (pci_using_dac) dev->features |= NETIF_F_HIGHDMA;
- dev->hw_features |= NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO |
NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX;
- dev->vlan_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO |
NETIF_F_HIGHDMA;
netdev_hw_features_set_array(dev, &cp_default_feature_set);
netdev_vlan_features_zero(dev);
netdev_vlan_features_set_array(dev, &cp_vlan_feature_set);
/* MTU range: 60 - 4096 */ dev->min_mtu = CP_MIN_MTU;
diff --git a/drivers/net/ethernet/realtek/8139too.c b/drivers/net/ethernet/realtek/8139too.c index 15b40fd93cd2..3844a0f418ec 100644 --- a/drivers/net/ethernet/realtek/8139too.c +++ b/drivers/net/ethernet/realtek/8139too.c @@ -102,6 +102,7 @@ #include <linux/init.h> #include <linux/interrupt.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/etherdevice.h> #include <linux/rtnetlink.h> #include <linux/delay.h> @@ -940,6 +941,11 @@ static const struct net_device_ops rtl8139_netdev_ops = { .ndo_set_features = rtl8139_set_features, };
+static DECLARE_NETDEV_FEATURE_SET(rtl8139_feature_set,
NETIF_F_SG_BIT,
NETIF_F_HW_CSUM_BIT,
NETIF_F_HIGHDMA_BIT);
- static int rtl8139_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) {
@@ -1008,7 +1014,7 @@ static int rtl8139_init_one(struct pci_dev *pdev, * through the use of skb_copy_and_csum_dev we enable these * features */
- dev->features |= NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_HIGHDMA;
netdev_active_features_set_array(dev, &rtl8139_feature_set); dev->vlan_features = dev->features;
dev->hw_features |= NETIF_F_RXALL;
diff --git a/drivers/net/ethernet/realtek/r8169_main.c b/drivers/net/ethernet/realtek/r8169_main.c index 1b7fdb4f056b..b999f129490c 100644 --- a/drivers/net/ethernet/realtek/r8169_main.c +++ b/drivers/net/ethernet/realtek/r8169_main.c @@ -12,6 +12,7 @@ #include <linux/module.h> #include <linux/pci.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/etherdevice.h> #include <linux/clk.h> #include <linux/delay.h> @@ -5298,6 +5299,16 @@ static bool rtl_aspm_is_safe(struct rtl8169_private *tp) return false; }
+static DECLARE_NETDEV_FEATURE_SET(rtl_hw_feature_set,
NETIF_F_IP_CSUM_BIT,
NETIF_F_RXCSUM_BIT,
NETIF_F_HW_VLAN_CTAG_TX_BIT,
NETIF_F_HW_VLAN_CTAG_RX_BIT);
+static DECLARE_NETDEV_FEATURE_SET(rtl_vlan_feature_set,
NETIF_F_SG_BIT,
NETIF_F_IP_CSUM_BIT,
NETIF_F_TSO_BIT);
- static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) { struct rtl8169_private *tp;
@@ -5415,9 +5426,10 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
netif_napi_add(dev, &tp->napi, rtl8169_poll, NAPI_POLL_WEIGHT);
- dev->hw_features = NETIF_F_IP_CSUM | NETIF_F_RXCSUM |
NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX;
- dev->vlan_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO;
netdev_hw_features_zero(dev);
netdev_hw_features_set_array(dev, &rtl_hw_feature_set);
netdev_vlan_features_zero(dev);
netdev_vlan_features_set_array(dev, &rtl_vlan_feature_set); dev->priv_flags |= IFF_LIVE_ADDR_CHANGE;
/*
diff --git a/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c b/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c index a1c10b61269b..30af142820c6 100644 --- a/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c +++ b/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c @@ -25,6 +25,7 @@ #include <linux/module.h> #include <linux/net_tstamp.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/phy.h> #include <linux/platform_device.h> #include <linux/prefetch.h> @@ -2050,6 +2051,15 @@ static int sxgbe_sw_reset(void __iomem *addr) return 0; }
+static DECLARE_NETDEV_FEATURE_SET(sxgbe_hw_feature_set,
NETIF_F_SG_BIT,
NETIF_F_IP_CSUM_BIT,
NETIF_F_IPV6_CSUM_BIT,
NETIF_F_RXCSUM_BIT,
NETIF_F_TSO_BIT,
NETIF_F_TSO6_BIT,
NETIF_F_GRO_BIT);
- /**
- sxgbe_drv_probe
- @device: device pointer
@@ -2105,9 +2115,8 @@ struct sxgbe_priv_data *sxgbe_drv_probe(struct device *device,
ndev->netdev_ops = &sxgbe_netdev_ops;
- ndev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
NETIF_F_RXCSUM | NETIF_F_TSO | NETIF_F_TSO6 |
NETIF_F_GRO;
- netdev_hw_features_zero(ndev);
- netdev_hw_features_set_array(ndev, &sxgbe_hw_feature_set); ndev->features |= ndev->hw_features | NETIF_F_HIGHDMA; ndev->watchdog_timeo = msecs_to_jiffies(TX_TIMEO);
diff --git a/drivers/net/ethernet/sfc/ef10.c b/drivers/net/ethernet/sfc/ef10.c index ab979fd11133..0a44a0beed4e 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; }
+static 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_netdev.c b/drivers/net/ethernet/sfc/ef100_netdev.c index 9e65de1ab889..4aadf6928102 100644 --- a/drivers/net/ethernet/sfc/ef100_netdev.c +++ b/drivers/net/ethernet/sfc/ef100_netdev.c @@ -341,6 +341,11 @@ void ef100_remove_netdev(struct efx_probe_data *probe_data) efx->state = STATE_PROBED; }
+static DECLARE_NETDEV_FEATURE_SET(ef100_vlan_feature_set,
NETIF_F_HW_CSUM_BIT,
NETIF_F_SG_BIT,
NETIF_F_HIGHDMA_BIT);
- int ef100_probe_netdev(struct efx_probe_data *probe_data) { struct efx_nic *efx = &probe_data->efx;
@@ -366,8 +371,8 @@ int ef100_probe_netdev(struct efx_probe_data *probe_data) 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); netif_set_tso_max_segs(net_dev, ESE_EF100_DP_GZ_TSO_MAX_HDR_NUM_SEGS_DEFAULT); efx->mdio.dev = net_dev;
diff --git a/drivers/net/ethernet/sfc/ef100_nic.c b/drivers/net/ethernet/sfc/ef100_nic.c index 4625d35269e6..b7d655d551da 100644 --- a/drivers/net/ethernet/sfc/ef100_nic.c +++ b/drivers/net/ethernet/sfc/ef100_nic.c @@ -148,6 +148,15 @@ static int ef100_get_mac_address(struct efx_nic *efx, u8 *mac_address) return 0; }
+static 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);
- int efx_ef100_init_datapath_caps(struct efx_nic *efx) { MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_CAPABILITIES_V7_OUT_LEN);
@@ -186,10 +195,10 @@ 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;
diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c index 153d68e29b8b..3baebaabdf32 100644 --- a/drivers/net/ethernet/sfc/efx.c +++ b/drivers/net/ethernet/sfc/efx.c @@ -985,6 +985,18 @@ static int efx_pci_probe_main(struct efx_nic *efx) return rc; }
+static DECLARE_NETDEV_FEATURE_SET(efx_active_feature_set,
NETIF_F_SG_BIT,
NETIF_F_TSO_BIT,
NETIF_F_RXCSUM_BIT,
NETIF_F_RXALL_BIT);
+static 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;
@@ -1001,17 +1013,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 a63f40b09856..0240c7f5843a 100644 --- a/drivers/net/ethernet/sfc/falcon/efx.c +++ b/drivers/net/ethernet/sfc/falcon/efx.c @@ -2853,6 +2853,12 @@ static int ef4_pci_probe_main(struct ef4_nic *efx) return rc; }
+static 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,
@@ -2901,9 +2907,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 a2c7139f2b32..8ee0cc45e8ad 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 4cde54cf77b9..f24919747711 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/drivers/net/ethernet/sfc/siena/efx.c b/drivers/net/ethernet/sfc/siena/efx.c index 63d999e63960..050e1b0ad0cb 100644 --- a/drivers/net/ethernet/sfc/siena/efx.c +++ b/drivers/net/ethernet/sfc/siena/efx.c @@ -9,6 +9,7 @@ #include <linux/module.h> #include <linux/pci.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/etherdevice.h> #include <linux/delay.h> #include <linux/notifier.h> @@ -967,6 +968,18 @@ static int efx_pci_probe_main(struct efx_nic *efx) return rc; }
+static DECLARE_NETDEV_FEATURE_SET(efx_active_feature_set,
NETIF_F_SG_BIT,
NETIF_F_TSO_BIT,
NETIF_F_RXCSUM_BIT,
NETIF_F_RXALL_BIT);
+static 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;
@@ -983,17 +996,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/sgi/ioc3-eth.c b/drivers/net/ethernet/sgi/ioc3-eth.c index e2d009866a7b..84227eb0e3a4 100644 --- a/drivers/net/ethernet/sgi/ioc3-eth.c +++ b/drivers/net/ethernet/sgi/ioc3-eth.c @@ -825,6 +825,13 @@ static const struct net_device_ops ioc3_netdev_ops = { .ndo_set_mac_address = ioc3_set_mac_address, };
+static DECLARE_NETDEV_FEATURE_SET(ioc_hw_feature_set,
NETIF_F_IP_CSUM_BIT,
NETIF_F_RXCSUM_BIT);
+static DECLARE_NETDEV_FEATURE_SET(ioc_feature_set,
NETIF_F_IP_CSUM_BIT,
NETIF_F_HIGHDMA_BIT);
- static int ioc3eth_probe(struct platform_device *pdev) { u32 sw_physid1, sw_physid2, vendor, model, rev;
@@ -926,8 +933,10 @@ static int ioc3eth_probe(struct platform_device *pdev) dev->watchdog_timeo = 5 * HZ; dev->netdev_ops = &ioc3_netdev_ops; dev->ethtool_ops = &ioc3_ethtool_ops;
- dev->hw_features = NETIF_F_IP_CSUM | NETIF_F_RXCSUM;
- dev->features = NETIF_F_IP_CSUM | NETIF_F_HIGHDMA;
netdev_hw_features_zero(dev);
netdev_hw_features_set_array(dev, &ioc_hw_feature_set);
netdev_active_features_zero(dev);
netdev_active_features_set_array(dev, &ioc_feature_set);
sw_physid1 = ioc3_mdio_read(dev, ip->mii.phy_id, MII_PHYSID1); sw_physid2 = ioc3_mdio_read(dev, ip->mii.phy_id, MII_PHYSID2);
diff --git a/drivers/net/ethernet/silan/sc92031.c b/drivers/net/ethernet/silan/sc92031.c index ff4197f5e46d..65b0b8574698 100644 --- a/drivers/net/ethernet/silan/sc92031.c +++ b/drivers/net/ethernet/silan/sc92031.c @@ -30,6 +30,7 @@ #include <linux/pci.h> #include <linux/dma-mapping.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/etherdevice.h> #include <linux/ethtool.h> #include <linux/mii.h> @@ -1394,6 +1395,12 @@ static const struct net_device_ops sc92031_netdev_ops = { #endif };
+static DECLARE_NETDEV_FEATURE_SET(sc92031_feature_set,
NETIF_F_SG_BIT,
NETIF_F_HIGHDMA_BIT,
NETIF_F_IP_CSUM_BIT,
NETIF_F_IPV6_CSUM_BIT);
- static int sc92031_probe(struct pci_dev *pdev, const struct pci_device_id *id) { int err;
@@ -1437,8 +1444,8 @@ static int sc92031_probe(struct pci_dev *pdev, const struct pci_device_id *id) SET_NETDEV_DEV(dev, &pdev->dev);
/* faked with skb_copy_and_csum_dev */
- dev->features = NETIF_F_SG | NETIF_F_HIGHDMA |
NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
netdev_active_features_zero(dev);
netdev_active_features_set_array(dev, &sc92031_feature_set);
dev->netdev_ops = &sc92031_netdev_ops; dev->watchdog_timeo = TX_TIMEOUT;
diff --git a/drivers/net/ethernet/socionext/netsec.c b/drivers/net/ethernet/socionext/netsec.c index b0c5a44785fa..67fba95978b4 100644 --- a/drivers/net/ethernet/socionext/netsec.c +++ b/drivers/net/ethernet/socionext/netsec.c @@ -10,6 +10,7 @@ #include <linux/etherdevice.h> #include <linux/interrupt.h> #include <linux/io.h> +#include <linux/netdev_features_helper.h> #include <linux/netlink.h> #include <linux/bpf.h> #include <linux/bpf_trace.h> @@ -1975,6 +1976,13 @@ static int netsec_register_mdio(struct netsec_priv *priv, u32 phy_addr) return ret; }
+static DECLARE_NETDEV_FEATURE_SET(netsec_feature_set,
NETIF_F_HIGHDMA_BIT,
NETIF_F_RXCSUM_BIT,
NETIF_F_GSO_BIT,
NETIF_F_IP_CSUM_BIT,
NETIF_F_IPV6_CSUM_BIT);
- static int netsec_probe(struct platform_device *pdev) { struct resource *mmio_res, *eeprom_res;
@@ -2098,8 +2106,7 @@ static int netsec_probe(struct platform_device *pdev) ndev->netdev_ops = &netsec_netdev_ops; ndev->ethtool_ops = &netsec_ethtool_ops;
- ndev->features |= NETIF_F_HIGHDMA | NETIF_F_RXCSUM | NETIF_F_GSO |
NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
netdev_active_features_set_array(ndev, &netsec_feature_set); ndev->hw_features = ndev->features;
priv->rx_cksum_offload_flag = true;
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index 070b5ef165eb..23b80ddad54d 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -35,6 +35,7 @@ #include <linux/debugfs.h> #include <linux/seq_file.h> #endif /* CONFIG_DEBUG_FS */ +#include <linux/netdev_features_helper.h> #include <linux/net_tstamp.h> #include <linux/phylink.h> #include <linux/udp.h> @@ -7026,6 +7027,12 @@ void stmmac_fpe_handshake(struct stmmac_priv *priv, bool enable) } }
+static DECLARE_NETDEV_FEATURE_SET(stmmac_hw_feature_set,
NETIF_F_SG_BIT,
NETIF_F_IP_CSUM_BIT,
NETIF_F_IPV6_CSUM_BIT,
NETIF_F_RXCSUM_BIT);
- /**
- stmmac_dvr_probe
- @device: device pointer
@@ -7132,8 +7139,8 @@ int stmmac_dvr_probe(struct device *device,
ndev->netdev_ops = &stmmac_netdev_ops;
- ndev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
NETIF_F_RXCSUM;
netdev_hw_features_zero(ndev);
netdev_hw_features_set_array(ndev, &stmmac_hw_feature_set);
ret = stmmac_tc_init(priv, priv); if (!ret) {
diff --git a/drivers/net/ethernet/sun/ldmvsw.c b/drivers/net/ethernet/sun/ldmvsw.c index 0cd8493b810f..49fa25fa045b 100644 --- a/drivers/net/ethernet/sun/ldmvsw.c +++ b/drivers/net/ethernet/sun/ldmvsw.c @@ -223,6 +223,10 @@ static struct vnet *vsw_get_vnet(struct mdesc_handle *hp, return vp; }
+static DECLARE_NETDEV_FEATURE_SET(vsw_hw_feature_set,
NETIF_F_HW_CSUM_BIT,
NETIF_F_SG_BIT);
- static struct net_device *vsw_alloc_netdev(u8 hwaddr[], struct vio_dev *vdev, u64 handle,
@@ -246,7 +250,8 @@ static struct net_device *vsw_alloc_netdev(u8 hwaddr[], dev->ethtool_ops = &vsw_ethtool_ops; dev->watchdog_timeo = VSW_TX_TIMEOUT;
- dev->hw_features = NETIF_F_HW_CSUM | NETIF_F_SG;
netdev_hw_features_zero(dev);
netdev_hw_features_set_array(dev, &vsw_hw_feature_set); dev->features = dev->hw_features;
/* MTU range: 68 - 65535 */
diff --git a/drivers/net/ethernet/sun/niu.c b/drivers/net/ethernet/sun/niu.c index df70df29deea..f7fa28ba5d53 100644 --- a/drivers/net/ethernet/sun/niu.c +++ b/drivers/net/ethernet/sun/niu.c @@ -12,6 +12,7 @@ #include <linux/pci.h> #include <linux/dma-mapping.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/ethtool.h> #include <linux/etherdevice.h> #include <linux/platform_device.h> @@ -9733,9 +9734,15 @@ static void niu_device_announce(struct niu *np) } }
+static DECLARE_NETDEV_FEATURE_SET(niu_hw_feature_set,
NETIF_F_SG_BIT,
NETIF_F_HW_CSUM_BIT,
NETIF_F_RXHASH_BIT);
- static void niu_set_basic_features(struct net_device *dev) {
- dev->hw_features = NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_RXHASH;
- netdev_hw_features_zero(dev);
- netdev_hw_features_set_array(dev, &niu_hw_feature_set); dev->features |= dev->hw_features | NETIF_F_RXCSUM; }
diff --git a/drivers/net/ethernet/sun/sungem.c b/drivers/net/ethernet/sun/sungem.c index a14591b41acb..42a7a6a5926f 100644 --- a/drivers/net/ethernet/sun/sungem.c +++ b/drivers/net/ethernet/sun/sungem.c @@ -29,6 +29,7 @@ #include <linux/pci.h> #include <linux/dma-mapping.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/etherdevice.h> #include <linux/skbuff.h> #include <linux/mii.h> @@ -2843,6 +2844,11 @@ static const struct net_device_ops gem_netdev_ops = { #endif };
+static DECLARE_NETDEV_FEATURE_SET(gem_hw_feature_set,
NETIF_F_SG_BIT,
NETIF_F_HW_CSUM_BIT,
NETIF_F_RXCSUM_BIT);
- static int gem_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) { unsigned long gemreg_base, gemreg_len;
@@ -2989,7 +2995,8 @@ static int gem_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) pci_set_drvdata(pdev, dev);
/* We can do scatter/gather and HW checksum */
- dev->hw_features = NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_RXCSUM;
- netdev_hw_features_zero(dev);
- netdev_hw_features_set_array(dev, &gem_hw_feature_set); dev->features = dev->hw_features; if (pci_using_dac) dev->features |= NETIF_F_HIGHDMA;
diff --git a/drivers/net/ethernet/sun/sunvnet.c b/drivers/net/ethernet/sun/sunvnet.c index da8119625cf3..0552fe23a397 100644 --- a/drivers/net/ethernet/sun/sunvnet.c +++ b/drivers/net/ethernet/sun/sunvnet.c @@ -281,6 +281,12 @@ static const struct net_device_ops vnet_ops = { #endif };
+static DECLARE_NETDEV_FEATURE_SET(vnet_hw_feature_set,
NETIF_F_TSO_BIT,
NETIF_F_GSO_BIT,
NETIF_F_HW_CSUM_BIT,
NETIF_F_SG_BIT);
- static struct vnet *vnet_new(const u64 *local_mac, struct vio_dev *vdev) {
@@ -314,8 +320,8 @@ static struct vnet *vnet_new(const u64 *local_mac, dev->ethtool_ops = &vnet_ethtool_ops; dev->watchdog_timeo = VNET_TX_TIMEOUT;
- dev->hw_features = NETIF_F_TSO | NETIF_F_GSO | NETIF_F_ALL_TSO |
NETIF_F_HW_CSUM | NETIF_F_SG;
dev->hw_features = NETIF_F_ALL_TSO;
netdev_hw_features_set_array(dev, &vnet_hw_feature_set); dev->features = dev->hw_features;
/* MTU range: 68 - 65535 */
diff --git a/drivers/net/ethernet/tehuti/tehuti.c b/drivers/net/ethernet/tehuti/tehuti.c index 985073eba3bd..fd89439791ce 100644 --- a/drivers/net/ethernet/tehuti/tehuti.c +++ b/drivers/net/ethernet/tehuti/tehuti.c @@ -1862,6 +1862,21 @@ static const struct net_device_ops bdx_netdev_ops = { .ndo_vlan_rx_kill_vid = bdx_vlan_rx_kill_vid, };
+static DECLARE_NETDEV_FEATURE_SET(bdx_feature_set,
NETIF_F_IP_CSUM_BIT,
NETIF_F_SG_BIT,
NETIF_F_TSO_BIT,
NETIF_F_HW_VLAN_CTAG_TX_BIT,
NETIF_F_HW_VLAN_CTAG_RX_BIT,
NETIF_F_HW_VLAN_CTAG_FILTER_BIT,
NETIF_F_RXCSUM_BIT,
NETIF_F_HIGHDMA_BIT);
+static DECLARE_NETDEV_FEATURE_SET(bdx_hw_feature_set,
NETIF_F_IP_CSUM_BIT,
NETIF_F_SG_BIT,
NETIF_F_TSO_BIT,
NETIF_F_HW_VLAN_CTAG_TX_BIT);
- /**
- bdx_probe - Device Initialization Routine
- @pdev: PCI device information struct
@@ -1976,13 +1991,11 @@ bdx_probe(struct pci_dev *pdev, const struct pci_device_id *ent) /* these fields are used for info purposes only * so we can have them same for all ports of the board */ ndev->if_port = port;
ndev->features = NETIF_F_IP_CSUM | NETIF_F_SG | NETIF_F_TSO |
NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX |
NETIF_F_HW_VLAN_CTAG_FILTER | NETIF_F_RXCSUM |
NETIF_F_HIGHDMA;
netdev_active_features_zero(ndev);
netdev_active_features_set_array(ndev, &bdx_feature_set);
ndev->hw_features = NETIF_F_IP_CSUM | NETIF_F_SG |
NETIF_F_TSO | NETIF_F_HW_VLAN_CTAG_TX;
netdev_hw_features_zero(ndev);
netdev_hw_features_set_array(ndev, &bdx_hw_feature_set);
/************** priv ****************/ priv = nic->priv[port] = netdev_priv(ndev);
diff --git a/drivers/net/ethernet/tehuti/tehuti.h b/drivers/net/ethernet/tehuti/tehuti.h index 909e7296cecf..eef81f973233 100644 --- a/drivers/net/ethernet/tehuti/tehuti.h +++ b/drivers/net/ethernet/tehuti/tehuti.h @@ -10,6 +10,7 @@ #include <linux/module.h> #include <linux/kernel.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/etherdevice.h> #include <linux/pci.h> #include <linux/delay.h> diff --git a/drivers/net/ethernet/ti/am65-cpsw-nuss.c b/drivers/net/ethernet/ti/am65-cpsw-nuss.c index f4a6b590a1e3..b390983861d8 100644 --- a/drivers/net/ethernet/ti/am65-cpsw-nuss.c +++ b/drivers/net/ethernet/ti/am65-cpsw-nuss.c @@ -14,6 +14,7 @@ #include <linux/kmemleak.h> #include <linux/module.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/net_tstamp.h> #include <linux/of.h> #include <linux/of_mdio.h> @@ -1932,6 +1933,12 @@ static void am65_cpsw_nuss_phylink_cleanup(struct am65_cpsw_common *common) } }
+static DECLARE_NETDEV_FEATURE_SET(am65_cpsw_hw_feature_set,
NETIF_F_SG_BIT,
NETIF_F_RXCSUM_BIT,
NETIF_F_HW_CSUM_BIT,
NETIF_F_HW_TC_BIT);
- static int am65_cpsw_nuss_init_port_ndev(struct am65_cpsw_common *common, u32 port_idx) {
@@ -1966,10 +1973,8 @@ am65_cpsw_nuss_init_port_ndev(struct am65_cpsw_common *common, u32 port_idx)
port->ndev->min_mtu = AM65_CPSW_MIN_PACKET_SIZE; port->ndev->max_mtu = AM65_CPSW_MAX_PACKET_SIZE;
- port->ndev->hw_features = NETIF_F_SG |
NETIF_F_RXCSUM |
NETIF_F_HW_CSUM |
NETIF_F_HW_TC;
- netdev_hw_features_zero(port->ndev);
- netdev_hw_features_set_array(port->ndev, &am65_cpsw_hw_feature_set); port->ndev->features = port->ndev->hw_features | NETIF_F_HW_VLAN_CTAG_FILTER; port->ndev->vlan_features |= NETIF_F_SG;
diff --git a/drivers/net/ethernet/ti/cpsw_new.c b/drivers/net/ethernet/ti/cpsw_new.c index 353e58b22c51..fb9ba01138f1 100644 --- a/drivers/net/ethernet/ti/cpsw_new.c +++ b/drivers/net/ethernet/ti/cpsw_new.c @@ -13,6 +13,7 @@ #include <linux/interrupt.h> #include <linux/if_ether.h> #include <linux/etherdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/net_tstamp.h> #include <linux/phy.h> #include <linux/phy/phy.h> @@ -1359,6 +1360,12 @@ static void cpsw_remove_dt(struct cpsw_common *cpsw) } }
+static DECLARE_NETDEV_FEATURE_SET(cpsw_feature_set,
NETIF_F_HW_VLAN_CTAG_FILTER_BIT,
NETIF_F_HW_VLAN_CTAG_RX_BIT,
NETIF_F_NETNS_LOCAL_BIT,
NETIF_F_HW_TC_BIT);
- static int cpsw_create_ports(struct cpsw_common *cpsw) { struct cpsw_platform_data *data = &cpsw->data;
@@ -1403,9 +1410,7 @@ static int cpsw_create_ports(struct cpsw_common *cpsw)
cpsw->slaves[i].ndev = ndev;
ndev->features |= NETIF_F_HW_VLAN_CTAG_FILTER |
NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_NETNS_LOCAL | NETIF_F_HW_TC;
ndev->netdev_ops = &cpsw_netdev_ops; ndev->ethtool_ops = &cpsw_ethtool_ops; SET_NETDEV_DEV(ndev, dev);netdev_active_features_set_array(ndev, &cpsw_feature_set);
diff --git a/drivers/net/ethernet/via/via-velocity.c b/drivers/net/ethernet/via/via-velocity.c index ff0c102cb578..06ac16f37bf5 100644 --- a/drivers/net/ethernet/via/via-velocity.c +++ b/drivers/net/ethernet/via/via-velocity.c @@ -45,6 +45,7 @@ #include <linux/pci.h> #include <linux/kernel.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/etherdevice.h> #include <linux/skbuff.h> #include <linux/delay.h> @@ -2748,6 +2749,16 @@ static u32 velocity_get_link(struct net_device *dev) return BYTE_REG_BITS_IS_ON(PHYSR0_LINKGD, ®s->PHYSR0) ? 1 : 0; }
+static DECLARE_NETDEV_FEATURE_SET(velocity_hw_feature_set,
NETIF_F_IP_CSUM_BIT,
NETIF_F_SG_BIT,
NETIF_F_HW_VLAN_CTAG_TX_BIT);
+static DECLARE_NETDEV_FEATURE_SET(velocity_feature_set,
NETIF_F_HW_VLAN_CTAG_TX_BIT,
NETIF_F_HW_VLAN_CTAG_FILTER_BIT,
NETIF_F_HW_VLAN_CTAG_RX_BIT,
NETIF_F_IP_CSUM_BIT);
- /**
- velocity_probe - set up discovered velocity device
- @dev: PCI device
@@ -2848,11 +2859,9 @@ static int velocity_probe(struct device *dev, int irq, netdev->ethtool_ops = &velocity_ethtool_ops; netif_napi_add(netdev, &vptr->napi, velocity_poll, NAPI_POLL_WEIGHT);
- netdev->hw_features = NETIF_F_IP_CSUM | NETIF_F_SG |
NETIF_F_HW_VLAN_CTAG_TX;
- netdev->features |= NETIF_F_HW_VLAN_CTAG_TX |
NETIF_F_HW_VLAN_CTAG_FILTER | NETIF_F_HW_VLAN_CTAG_RX |
NETIF_F_IP_CSUM;
netdev_hw_features_zero(netdev);
netdev_hw_features_set_array(netdev, &velocity_hw_feature_set);
netdev_active_features_set_array(netdev, &velocity_feature_set);
/* MTU range: 64 - 9000 */ netdev->min_mtu = VELOCITY_MIN_MTU;
diff --git a/drivers/net/geneve.c b/drivers/net/geneve.c index 2495a5719e1c..75bc68eba7f7 100644 --- a/drivers/net/geneve.c +++ b/drivers/net/geneve.c @@ -12,6 +12,7 @@ #include <linux/module.h> #include <linux/etherdevice.h> #include <linux/hash.h> +#include <linux/netdev_features_helper.h> #include <net/ipv6_stubs.h> #include <net/dst_metadata.h> #include <net/gro_cells.h> @@ -1233,6 +1234,18 @@ static void geneve_offload_rx_ports(struct net_device *dev, bool push) rcu_read_unlock(); }
+static DECLARE_NETDEV_FEATURE_SET(geneve_feature_set,
NETIF_F_LLTX_BIT,
NETIF_F_SG_BIT,
NETIF_F_HW_CSUM_BIT,
NETIF_F_FRAGLIST_BIT,
NETIF_F_RXCSUM_BIT);
+static DECLARE_NETDEV_FEATURE_SET(geneve_hw_feature_set,
NETIF_F_SG_BIT,
NETIF_F_HW_CSUM_BIT,
NETIF_F_FRAGLIST_BIT,
NETIF_F_RXCSUM_BIT);
- /* Initialize the device structure. */ static void geneve_setup(struct net_device *dev) {
@@ -1244,13 +1257,10 @@ static void geneve_setup(struct net_device *dev)
SET_NETDEV_DEVTYPE(dev, &geneve_type);
- dev->features |= NETIF_F_LLTX;
- dev->features |= NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_FRAGLIST;
- dev->features |= NETIF_F_RXCSUM;
- netdev_active_features_set_array(dev, &geneve_feature_set); dev->features |= NETIF_F_GSO_SOFTWARE;
- dev->hw_features |= NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_FRAGLIST;
- dev->hw_features |= NETIF_F_RXCSUM;
netdev_hw_features_set_array(dev, &geneve_hw_feature_set); dev->hw_features |= NETIF_F_GSO_SOFTWARE;
/* MTU range: 68 - (something less than 65535) */
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c index 15ebd5426604..6bf8d63132a1 100644 --- a/drivers/net/hyperv/netvsc_drv.c +++ b/drivers/net/hyperv/netvsc_drv.c @@ -17,6 +17,7 @@ #include <linux/io.h> #include <linux/delay.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/inetdevice.h> #include <linux/etherdevice.h> #include <linux/pci.h> @@ -2450,6 +2451,11 @@ static int netvsc_unregister_vf(struct net_device *vf_netdev) return NOTIFY_OK; }
+static DECLARE_NETDEV_FEATURE_SET(netvsc_feature_set,
NETIF_F_HIGHDMA_BIT,
NETIF_F_HW_VLAN_CTAG_TX_BIT,
NETIF_F_HW_VLAN_CTAG_RX_BIT);
- static int netvsc_probe(struct hv_device *dev, const struct hv_vmbus_device_id *dev_id) {
@@ -2533,9 +2539,8 @@ static int netvsc_probe(struct hv_device *dev, schedule_work(&nvdev->subchan_work);
/* hw_features computed in rndis_netdev_set_hwcaps() */
- net->features = net->hw_features |
NETIF_F_HIGHDMA | NETIF_F_HW_VLAN_CTAG_TX |
NETIF_F_HW_VLAN_CTAG_RX;
net->features = net->hw_features;
netdev_active_features_set_array(net, &netvsc_feature_set); net->vlan_features = net->features;
netdev_lockdep_set_classes(net);
diff --git a/drivers/net/ifb.c b/drivers/net/ifb.c index 1c64d5347b8e..92ffd1b9849b 100644 --- a/drivers/net/ifb.c +++ b/drivers/net/ifb.c @@ -27,6 +27,7 @@ #include <linux/module.h> #include <linux/kernel.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/ethtool.h> #include <linux/etherdevice.h> #include <linux/init.h> @@ -288,10 +289,13 @@ static const struct ethtool_ops ifb_ethtool_ops = { .get_ethtool_stats = ifb_get_ethtool_stats, };
-#define IFB_FEATURES (NETIF_F_HW_CSUM | NETIF_F_SG | NETIF_F_FRAGLIST | \
NETIF_F_GSO_SOFTWARE | NETIF_F_GSO_ENCAP_ALL | \
NETIF_F_HIGHDMA | NETIF_F_HW_VLAN_CTAG_TX | \
NETIF_F_HW_VLAN_STAG_TX)
+static DECLARE_NETDEV_FEATURE_SET(ifb_feature_set,
NETIF_F_HW_CSUM_BIT,
NETIF_F_SG_BIT,
NETIF_F_FRAGLIST_BIT,
NETIF_F_HIGHDMA_BIT,
NETIF_F_HW_VLAN_CTAG_TX_BIT,
NETIF_F_HW_VLAN_STAG_TX_BIT);
static void ifb_dev_free(struct net_device *dev) {
@@ -309,6 +313,8 @@ static void ifb_dev_free(struct net_device *dev)
static void ifb_setup(struct net_device *dev) {
- netdev_features_t ifb_features;
- /* Initialize the device structure. */ dev->netdev_ops = &ifb_netdev_ops; dev->ethtool_ops = &ifb_ethtool_ops;
@@ -317,10 +323,12 @@ static void ifb_setup(struct net_device *dev) ether_setup(dev); dev->tx_queue_len = TX_Q_LIMIT;
- dev->features |= IFB_FEATURES;
- ifb_features = NETIF_F_GSO_SOFTWARE | NETIF_F_GSO_ENCAP_ALL;
- netdev_features_set_array(&ifb_feature_set, &ifb_features);
- dev->features |= ifb_features; dev->hw_features |= dev->features; dev->hw_enc_features |= dev->features;
- dev->vlan_features |= IFB_FEATURES & ~(NETIF_F_HW_VLAN_CTAG_TX |
dev->vlan_features |= ifb_features & ~(NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_STAG_TX);
dev->flags |= IFF_NOARP;
diff --git a/drivers/net/ipvlan/ipvlan_main.c b/drivers/net/ipvlan/ipvlan_main.c index 49ba8a50dfb1..b0d7a484fd39 100644 --- a/drivers/net/ipvlan/ipvlan_main.c +++ b/drivers/net/ipvlan/ipvlan_main.c @@ -3,9 +3,14 @@ */
#include <linux/ethtool.h> +#include <linux/netdev_features_helper.h>
#include "ipvlan.h"
+static netdev_features_t ipvlan_offload_features __ro_after_init; +static netdev_features_t ipvlan_always_on_features __ro_after_init; +static netdev_features_t ipvlan_features __ro_after_init;
- static int ipvlan_set_port_mode(struct ipvl_port *port, u16 nval, struct netlink_ext_ack *extack) {
@@ -107,18 +112,30 @@ static void ipvlan_port_destroy(struct net_device *dev) kfree(port); }
-#define IPVLAN_ALWAYS_ON_OFLOADS \
- (NETIF_F_SG | NETIF_F_HW_CSUM | \
NETIF_F_GSO_ROBUST | NETIF_F_GSO_SOFTWARE | NETIF_F_GSO_ENCAP_ALL)
-#define IPVLAN_ALWAYS_ON \
- (IPVLAN_ALWAYS_ON_OFLOADS | NETIF_F_LLTX | NETIF_F_VLAN_CHALLENGED)
-#define IPVLAN_FEATURES \
- (NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_HIGHDMA | NETIF_F_FRAGLIST | \
NETIF_F_GSO | NETIF_F_ALL_TSO | NETIF_F_GSO_ROBUST | \
NETIF_F_GRO | NETIF_F_RXCSUM | \
NETIF_F_HW_VLAN_CTAG_FILTER | NETIF_F_HW_VLAN_STAG_FILTER)
+static DECLARE_NETDEV_FEATURE_SET(ipvlan_on_offload_feature_set,
NETIF_F_SG_BIT,
NETIF_F_HW_CSUM_BIT,
NETIF_F_GSO_ROBUST_BIT);
+static DECLARE_NETDEV_FEATURE_SET(ipvlan_always_on_feature_set,
NETIF_F_LLTX_BIT,
NETIF_F_VLAN_CHALLENGED_BIT);
+static DECLARE_NETDEV_FEATURE_SET(ipvlan_feature_set,
NETIF_F_SG_BIT,
NETIF_F_HW_CSUM_BIT,
NETIF_F_HIGHDMA_BIT,
NETIF_F_FRAGLIST_BIT,
NETIF_F_GSO_BIT,
NETIF_F_GSO_ROBUST_BIT,
NETIF_F_GRO_BIT,
NETIF_F_RXCSUM_BIT,
NETIF_F_HW_VLAN_CTAG_FILTER_BIT,
NETIF_F_HW_VLAN_STAG_FILTER_BIT);
+#define IPVLAN_FEATURES ipvlan_features +#define IPVLAN_ALWAYS_ON_OFLOADS ipvlan_offload_features +#define IPVLAN_ALWAYS_ON ipvlan_always_on_features
/* NETIF_F_GSO_ENCAP_ALL NETIF_F_GSO_SOFTWARE Newly added */
@@ -1018,6 +1035,21 @@ static struct notifier_block ipvlan_addr6_vtor_notifier_block __read_mostly = { }; #endif
+static void __init ipvlan_features_init(void) +{
- ipvlan_offload_features = NETIF_F_GSO_SOFTWARE | NETIF_F_GSO_ENCAP_ALL;
- netdev_features_set_array(&ipvlan_on_offload_feature_set,
&ipvlan_offload_features);
- ipvlan_always_on_features = ipvlan_offload_features;
- netdev_features_set_array(&ipvlan_always_on_feature_set,
&ipvlan_always_on_features);
- ipvlan_features = NETIF_F_ALL_TSO;
- netdev_features_set_array(&ipvlan_feature_set,
&ipvlan_features);
+}
- static int __init ipvlan_init_module(void) { int err;
@@ -1042,6 +1074,8 @@ static int __init ipvlan_init_module(void) goto error; }
- ipvlan_features_init();
- return 0; error: unregister_inetaddr_notifier(&ipvlan_addr4_notifier_block);
diff --git a/drivers/net/ipvlan/ipvtap.c b/drivers/net/ipvlan/ipvtap.c index ef02f2cf5ce1..c6d95576ad40 100644 --- a/drivers/net/ipvlan/ipvtap.c +++ b/drivers/net/ipvlan/ipvtap.c @@ -18,14 +18,18 @@ #include <linux/idr.h> #include <linux/fs.h> #include <linux/uio.h> +#include <linux/netdev_features_helper.h>
#include <net/net_namespace.h> #include <net/rtnetlink.h> #include <net/sock.h> #include <linux/virtio_net.h>
-#define TUN_OFFLOADS (NETIF_F_HW_CSUM | NETIF_F_TSO_ECN | NETIF_F_TSO | \
NETIF_F_TSO6)
+static DECLARE_NETDEV_FEATURE_SET(tun_offload_feature_set,
NETIF_F_HW_CSUM_BIT,
NETIF_F_TSO_ECN_BIT,
NETIF_F_TSO_BIT,
NETIF_F_TSO6_BIT);
static dev_t ipvtap_major; static struct cdev ipvtap_cdev;
@@ -86,7 +90,9 @@ static int ipvtap_newlink(struct net *src_net, struct net_device *dev, /* Since macvlan supports all offloads by default, make * tap support all offloads also. */
- vlantap->tap.tap_features = TUN_OFFLOADS;
- netdev_features_zero(&vlantap->tap.tap_features);
- netdev_features_set_array(&tun_offload_feature_set,
vlantap->tap.count_tx_dropped = ipvtap_count_tx_dropped; vlantap->tap.update_features = ipvtap_update_features; vlantap->tap.count_rx_dropped = ipvtap_count_rx_dropped;&vlantap->tap.tap_features);
diff --git a/drivers/net/loopback.c b/drivers/net/loopback.c index 14e8d04cb434..308c8674e3ad 100644 --- a/drivers/net/loopback.c +++ b/drivers/net/loopback.c @@ -41,6 +41,7 @@
#include <linux/inet.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/etherdevice.h> #include <linux/skbuff.h> #include <linux/ethtool.h> @@ -160,6 +161,18 @@ static const struct net_device_ops loopback_ops = { .ndo_set_mac_address = eth_mac_addr, };
+static DECLARE_NETDEV_FEATURE_SET(lp_feature_set,
NETIF_F_SG_BIT,
NETIF_F_FRAGLIST_BIT,
NETIF_F_HW_CSUM_BIT,
NETIF_F_RXCSUM_BIT,
NETIF_F_SCTP_CRC_BIT,
NETIF_F_HIGHDMA_BIT,
NETIF_F_LLTX_BIT,
NETIF_F_NETNS_LOCAL_BIT,
NETIF_F_VLAN_CHALLENGED_BIT,
NETIF_F_LOOPBACK_BIT);
- static void gen_lo_setup(struct net_device *dev, unsigned int mtu, const struct ethtool_ops *eth_ops,
@@ -176,16 +189,8 @@ static void gen_lo_setup(struct net_device *dev, dev->priv_flags |= IFF_LIVE_ADDR_CHANGE | IFF_NO_QUEUE; netif_keep_dst(dev); dev->hw_features = NETIF_F_GSO_SOFTWARE;
- dev->features = NETIF_F_SG | NETIF_F_FRAGLIST
| NETIF_F_GSO_SOFTWARE
| NETIF_F_HW_CSUM
| NETIF_F_RXCSUM
| NETIF_F_SCTP_CRC
| NETIF_F_HIGHDMA
| NETIF_F_LLTX
| NETIF_F_NETNS_LOCAL
| NETIF_F_VLAN_CHALLENGED
| NETIF_F_LOOPBACK;
- dev->features = NETIF_F_GSO_SOFTWARE;
- netdev_active_features_set_array(dev, &lp_feature_set); dev->ethtool_ops = eth_ops; dev->header_ops = hdr_ops; dev->netdev_ops = dev_ops;
diff --git a/drivers/net/macsec.c b/drivers/net/macsec.c index f1683ce6b561..fe7557170595 100644 --- a/drivers/net/macsec.c +++ b/drivers/net/macsec.c @@ -12,6 +12,7 @@ #include <crypto/aead.h> #include <linux/etherdevice.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/rtnetlink.h> #include <linux/refcount.h> #include <net/genetlink.h> @@ -3420,15 +3421,20 @@ static netdev_tx_t macsec_start_xmit(struct sk_buff *skb, return ret; }
-#define SW_MACSEC_FEATURES \
- (NETIF_F_SG | NETIF_F_HIGHDMA | NETIF_F_FRAGLIST)
+static netdev_features_t macsec_real_dev_features_mask __ro_after_init; +static netdev_features_t sw_macsec_features __ro_after_init; +static DECLARE_NETDEV_FEATURE_SET(sw_macsec_feature_set,
NETIF_F_SG_BIT,
NETIF_F_HIGHDMA_BIT,
NETIF_F_FRAGLIST_BIT);
+#define SW_MACSEC_FEATURES sw_macsec_features
/* If h/w offloading is enabled, use real device features save for
- VLAN_FEATURES - they require additional ops
- HW_MACSEC - no reason to report it
*/ #define REAL_DEV_FEATURES(dev) \
- ((dev)->features & ~(NETIF_F_VLAN_FEATURES | NETIF_F_HW_MACSEC))
- ((dev)->features & ~sw_macsec_features)
Here should be ((dev)->features & ~macsec_real_dev_features_mask) ?
static int macsec_dev_init(struct net_device *dev) { @@ -4351,6 +4357,14 @@ static struct notifier_block macsec_notifier = { .notifier_call = macsec_notify, };
+static void __init macsec_features_init(void) +{
- netdev_features_set_array(&sw_macsec_feature_set, &sw_macsec_features);
- macsec_real_dev_features_mask = NETIF_F_VLAN_FEATURES;
- macsec_real_dev_features_mask |= NETIF_F_HW_MACSEC;
+}
- static int __init macsec_init(void) { int err;
@@ -4368,6 +4382,8 @@ static int __init macsec_init(void) if (err) goto rtnl;
macsec_features_init();
return 0;
rtnl:
diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c index 1080d6ebff63..d9a20c0341c6 100644 --- a/drivers/net/macvlan.c +++ b/drivers/net/macvlan.c @@ -19,6 +19,7 @@ #include <linux/rculist.h> #include <linux/notifier.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/etherdevice.h> #include <linux/net_tstamp.h> #include <linux/ethtool.h> @@ -67,6 +68,10 @@ struct macvlan_skb_cb {
#define MACVLAN_SKB_CB(__skb) ((struct macvlan_skb_cb *)&((__skb)->cb[0]))
+static netdev_features_t macvlan_offload_features __ro_after_init; +static netdev_features_t macvlan_always_on_features __ro_after_init; +static netdev_features_t macvlan_features __ro_after_init;
- static void macvlan_port_destroy(struct net_device *dev); static void update_port_bc_queue_len(struct macvlan_port *port);
@@ -868,17 +873,30 @@ static int macvlan_eth_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) */ static struct lock_class_key macvlan_netdev_addr_lock_key;
-#define ALWAYS_ON_OFFLOADS \
- (NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_GSO_SOFTWARE | \
NETIF_F_GSO_ROBUST | NETIF_F_GSO_ENCAP_ALL)
-#define ALWAYS_ON_FEATURES (ALWAYS_ON_OFFLOADS | NETIF_F_LLTX)
-#define MACVLAN_FEATURES \
- (NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_HIGHDMA | NETIF_F_FRAGLIST | \
NETIF_F_GSO | NETIF_F_TSO | NETIF_F_LRO | \
NETIF_F_TSO_ECN | NETIF_F_TSO6 | NETIF_F_GRO | NETIF_F_RXCSUM | \
NETIF_F_HW_VLAN_CTAG_FILTER | NETIF_F_HW_VLAN_STAG_FILTER)
+static DECLARE_NETDEV_FEATURE_SET(macvlan_on_offload_feature_set,
NETIF_F_SG_BIT,
NETIF_F_HW_CSUM_BIT,
NETIF_F_GSO_ROBUST_BIT);
+static DECLARE_NETDEV_FEATURE_SET(macvlan_always_on_feature_set,
NETIF_F_LLTX_BIT);
+static DECLARE_NETDEV_FEATURE_SET(macvlan_feature_set,
NETIF_F_SG_BIT,
NETIF_F_HW_CSUM_BIT,
NETIF_F_HIGHDMA_BIT,
NETIF_F_FRAGLIST_BIT,
NETIF_F_GSO_BIT,
NETIF_F_TSO_BIT,
NETIF_F_LRO_BIT,
NETIF_F_TSO_ECN_BIT,
NETIF_F_TSO6_BIT,
NETIF_F_GRO_BIT,
NETIF_F_RXCSUM_BIT,
NETIF_F_HW_VLAN_CTAG_FILTER_BIT,
NETIF_F_HW_VLAN_STAG_FILTER_BIT);
+#define MACVLAN_FEATURES macvlan_features +#define ALWAYS_ON_OFFLOADS macvlan_offload_features +#define ALWAYS_ON_FEATURES macvlan_always_on_features
#define MACVLAN_STATE_MASK \ ((1<<__LINK_STATE_NOCARRIER) | (1<<__LINK_STATE_DORMANT)) @@ -1813,6 +1831,20 @@ static struct notifier_block macvlan_notifier_block __read_mostly = { .notifier_call = macvlan_device_event, };
+static void __init macvlan_features_init(void) +{
- macvlan_offload_features = NETIF_F_GSO_SOFTWARE | NETIF_F_GSO_ENCAP_ALL;
- netdev_features_set_array(&macvlan_on_offload_feature_set,
&macvlan_offload_features);
- macvlan_always_on_features = macvlan_offload_features;
- netdev_features_set_array(&macvlan_always_on_feature_set,
&macvlan_always_on_features);
- netdev_features_set_array(&macvlan_feature_set,
&macvlan_features);
+}
- static int __init macvlan_init_module(void) { int err;
@@ -1822,6 +1854,8 @@ static int __init macvlan_init_module(void) err = macvlan_link_register(&macvlan_link_ops); if (err < 0) goto err1;
- macvlan_features_init(); return 0; err1: unregister_netdevice_notifier(&macvlan_notifier_block);
diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c index cecf8c63096c..03ee8c8f9ee7 100644 --- a/drivers/net/macvtap.c +++ b/drivers/net/macvtap.c @@ -18,6 +18,7 @@ #include <linux/idr.h> #include <linux/fs.h> #include <linux/uio.h> +#include <linux/netdev_features_helper.h>
#include <net/net_namespace.h> #include <net/rtnetlink.h> @@ -49,8 +50,11 @@ static struct class macvtap_class = { }; static struct cdev macvtap_cdev;
-#define TUN_OFFLOADS (NETIF_F_HW_CSUM | NETIF_F_TSO_ECN | NETIF_F_TSO | \
NETIF_F_TSO6)
+static DECLARE_NETDEV_FEATURE_SET(tun_offload_feature_set,
NETIF_F_HW_CSUM_BIT,
NETIF_F_TSO_ECN_BIT,
NETIF_F_TSO_BIT,
NETIF_F_TSO6_BIT);
static void macvtap_count_tx_dropped(struct tap_dev *tap) {
@@ -90,7 +94,9 @@ static int macvtap_newlink(struct net *src_net, struct net_device *dev, /* Since macvlan supports all offloads by default, make * tap support all offloads also. */
- vlantap->tap.tap_features = TUN_OFFLOADS;
netdev_features_zero(&vlantap->tap.tap_features);
netdev_features_set_array(&tun_offload_feature_set,
&vlantap->tap.tap_features);
/* Register callbacks for rx/tx drops accounting and updating
- net_device features
diff --git a/drivers/net/net_failover.c b/drivers/net/net_failover.c index 21a0435c02de..6d6a6781fcc9 100644 --- a/drivers/net/net_failover.c +++ b/drivers/net/net_failover.c @@ -27,6 +27,19 @@ #include <uapi/linux/if_arp.h> #include <net/net_failover.h>
+static netdev_features_t failover_vlan_features __ro_after_init; +static netdev_features_t failover_enc_features __ro_after_init; +static DECLARE_NETDEV_FEATURE_SET(failover_vlan_feature_set,
NETIF_F_HIGHDMA_BIT,
NETIF_F_SG_BIT,
NETIF_F_FRAGLIST_BIT,
NETIF_F_HIGHDMA_BIT,
NETIF_F_LRO_BIT);
+static DECLARE_NETDEV_FEATURE_SET(failover_enc_feature_set,
NETIF_F_HW_CSUM_BIT,
NETIF_F_SG_BIT,
NETIF_F_RXCSUM_BIT);
Why no use failover_vlan_feature_set and failover_enc_feature_set?
static bool net_failover_xmit_ready(struct net_device *dev) { return netif_running(dev) && netif_carrier_ok(dev); diff --git a/drivers/net/netdevsim/ipsec.c b/drivers/net/netdevsim/ipsec.c index 386336a38f34..ad0b5bf06f49 100644 --- a/drivers/net/netdevsim/ipsec.c +++ b/drivers/net/netdevsim/ipsec.c @@ -272,16 +272,17 @@ bool nsim_ipsec_tx(struct netdevsim *ns, struct sk_buff *skb) return true; }
+static DECLARE_NETDEV_FEATURE_SET(nsim_esp_feature_set,
NETIF_F_HW_ESP_BIT,
NETIF_F_HW_ESP_TX_CSUM_BIT,
NETIF_F_GSO_ESP_BIT);
- void nsim_ipsec_init(struct netdevsim *ns) { ns->netdev->xfrmdev_ops = &nsim_xfrmdev_ops;
-#define NSIM_ESP_FEATURES (NETIF_F_HW_ESP | \
NETIF_F_HW_ESP_TX_CSUM | \
NETIF_F_GSO_ESP)
- ns->netdev->features |= NSIM_ESP_FEATURES;
- ns->netdev->hw_enc_features |= NSIM_ESP_FEATURES;
netdev_active_features_set_array(ns->netdev, &nsim_esp_feature_set);
netdev_hw_enc_features_set_array(ns->netdev, &nsim_esp_feature_set);
ns->ipsec.pfile = debugfs_create_file("ipsec", 0400, ns->nsim_dev_port->ddir, ns,
diff --git a/drivers/net/netdevsim/netdev.c b/drivers/net/netdevsim/netdev.c index e470e3398abc..ad687b14dda3 100644 --- a/drivers/net/netdevsim/netdev.c +++ b/drivers/net/netdevsim/netdev.c @@ -18,6 +18,7 @@ #include <linux/kernel.h> #include <linux/module.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/slab.h> #include <net/netlink.h> #include <net/pkt_cls.h> @@ -278,6 +279,13 @@ static const struct net_device_ops nsim_vf_netdev_ops = { .ndo_get_devlink_port = nsim_get_devlink_port, };
+static DECLARE_NETDEV_FEATURE_SET(nsim_feature_set,
NETIF_F_HIGHDMA_BIT,
NETIF_F_SG_BIT,
NETIF_F_FRAGLIST_BIT,
NETIF_F_HW_CSUM_BIT,
NETIF_F_TSO_BIT);
- static void nsim_setup(struct net_device *dev) { ether_setup(dev);
@@ -288,11 +296,7 @@ static void nsim_setup(struct net_device *dev) dev->flags &= ~IFF_MULTICAST; dev->priv_flags |= IFF_LIVE_ADDR_CHANGE | IFF_NO_QUEUE;
- dev->features |= NETIF_F_HIGHDMA |
NETIF_F_SG |
NETIF_F_FRAGLIST |
NETIF_F_HW_CSUM |
NETIF_F_TSO;
- netdev_active_features_set_array(dev, &nsim_feature_set); dev->hw_features |= NETIF_F_HW_TC; dev->max_mtu = ETH_MAX_MTU; }
diff --git a/drivers/net/netdevsim/netdevsim.h b/drivers/net/netdevsim/netdevsim.h index 7d8ed8d8df5c..cf020a685530 100644 --- a/drivers/net/netdevsim/netdevsim.h +++ b/drivers/net/netdevsim/netdevsim.h @@ -19,6 +19,7 @@ #include <linux/kernel.h> #include <linux/list.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/u64_stats_sync.h> #include <net/devlink.h> #include <net/udp_tunnel.h> diff --git a/drivers/net/nlmon.c b/drivers/net/nlmon.c index 5e19a6839dea..2ccfaf04b429 100644 --- a/drivers/net/nlmon.c +++ b/drivers/net/nlmon.c @@ -3,6 +3,7 @@ #include <linux/module.h> #include <linux/kernel.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/netlink.h> #include <net/net_namespace.h> #include <linux/if_arp.h> @@ -80,6 +81,12 @@ static const struct net_device_ops nlmon_ops = { .ndo_get_stats64 = nlmon_get_stats64, };
+static DECLARE_NETDEV_FEATURE_SET(nlmon_feature_set,
NETIF_F_SG_BIT,
NETIF_F_FRAGLIST_BIT,
NETIF_F_HIGHDMA_BIT,
NETIF_F_LLTX_BIT);
- static void nlmon_setup(struct net_device *dev) { dev->type = ARPHRD_NETLINK;
@@ -89,8 +96,8 @@ static void nlmon_setup(struct net_device *dev) dev->ethtool_ops = &nlmon_ethtool_ops; dev->needs_free_netdev = true;
- dev->features = NETIF_F_SG | NETIF_F_FRAGLIST |
NETIF_F_HIGHDMA | NETIF_F_LLTX;
netdev_active_features_zero(dev);
netdev_active_features_set_array(dev, &nlmon_feature_set); dev->flags = IFF_NOARP;
/* That's rather a softlimit here, which, of course,
diff --git a/drivers/net/tap.c b/drivers/net/tap.c index c3d42062559d..7b1c1e724c43 100644 --- a/drivers/net/tap.c +++ b/drivers/net/tap.c @@ -17,6 +17,7 @@ #include <linux/idr.h> #include <linux/fs.h> #include <linux/uio.h> +#include <linux/netdev_features_helper.h>
#include <net/net_namespace.h> #include <net/rtnetlink.h> @@ -116,8 +117,13 @@ struct major_info {
static const struct proto_ops tap_socket_ops;
-#define RX_OFFLOADS (NETIF_F_GRO | NETIF_F_LRO) -#define TAP_FEATURES (NETIF_F_GSO | NETIF_F_SG | NETIF_F_FRAGLIST) +static DECLARE_NETDEV_FEATURE_SET(tap_rx_offload_feature_set,
NETIF_F_GRO_BIT,
NETIF_F_LRO_BIT);
+static DECLARE_NETDEV_FEATURE_SET(tap_feature_set,
NETIF_F_GSO_BIT,
NETIF_F_SG_BIT,
NETIF_F_FRAGLIST_BIT);
static struct tap_dev *tap_dev_get_rcu(const struct net_device *dev) {
@@ -321,7 +327,7 @@ rx_handler_result_t tap_handle_frame(struct sk_buff **pskb) struct net_device *dev = skb->dev; struct tap_dev *tap; struct tap_queue *q;
- netdev_features_t features = TAP_FEATURES;
netdev_features_t features; enum skb_drop_reason drop_reason;
tap = tap_dev_get_rcu(dev);
@@ -334,6 +340,8 @@ rx_handler_result_t tap_handle_frame(struct sk_buff **pskb)
skb_push(skb, ETH_HLEN);
- netdev_features_zero(&features);
- netdev_features_set_array(&tap_feature_set, &features); /* Apply the forward feature mask so that we perform segmentation
- according to users wishes. This only works if VNET_HDR is
- enabled.
@@ -966,9 +974,9 @@ static int set_offload(struct tap_queue *q, unsigned long arg) * user-space will not receive TSO frames. */ if (feature_mask & (NETIF_F_TSO | NETIF_F_TSO6))
features |= RX_OFFLOADS;
elsenetdev_features_set_array(&tap_rx_offload_feature_set, &features);
features &= ~RX_OFFLOADS;
netdev_features_clear_array(&tap_rx_offload_feature_set, &features);
/* tap_features are the same as features on tun/tap and
- reflect user expectations.
diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c index aac133a1e27a..452d414dff62 100644 --- a/drivers/net/team/team.c +++ b/drivers/net/team/team.c @@ -15,6 +15,7 @@ #include <linux/ctype.h> #include <linux/notifier.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/netpoll.h> #include <linux/if_vlan.h> #include <linux/if_arp.h> @@ -980,12 +981,20 @@ static void team_port_disable(struct team *team, team_lower_state_changed(port); }
-#define TEAM_VLAN_FEATURES (NETIF_F_HW_CSUM | NETIF_F_SG | \
NETIF_F_FRAGLIST | NETIF_F_GSO_SOFTWARE | \
NETIF_F_HIGHDMA | NETIF_F_LRO)
-#define TEAM_ENC_FEATURES (NETIF_F_HW_CSUM | NETIF_F_SG | \
NETIF_F_RXCSUM | NETIF_F_GSO_SOFTWARE)
+static DECLARE_NETDEV_FEATURE_SET(team_vlan_feature_set,
NETIF_F_HW_CSUM_BIT,
NETIF_F_SG_BIT,
NETIF_F_FRAGLIST_BIT,
NETIF_F_HIGHDMA_BIT,
NETIF_F_LRO_BIT);
+static DECLARE_NETDEV_FEATURE_SET(team_enc_feature_set,
NETIF_F_HW_CSUM_BIT,
NETIF_F_SG_BIT,
NETIF_F_RXCSUM_BIT);
+static netdev_features_t team_vlan_features __ro_after_init; +static netdev_features_t team_enc_features __ro_after_init; +#define TEAM_VLAN_FEATURES team_vlan_features +#define TEAM_ENC_FEATURES team_enc_features
static void __team_compute_features(struct team *team) { @@ -2875,6 +2884,13 @@ static void team_nl_fini(void) genl_unregister_family(&team_nl_family); }
+static void __init team_features_init(void) +{
- team_vlan_features = NETIF_F_GSO_SOFTWARE;
- netdev_features_set_array(&team_vlan_feature_set, &team_vlan_features);
- team_enc_features = NETIF_F_GSO_SOFTWARE;
- netdev_features_set_array(&team_enc_feature_set, &team_enc_features);
+}
/******************
- Change checkers
@@ -3031,7 +3047,6 @@ static struct notifier_block team_notifier_block __read_mostly = { .notifier_call = team_device_event, };
- /***********************
***********************/
- Module init and exit
@@ -3050,6 +3065,8 @@ static int __init team_module_init(void) if (err) goto err_nl_init;
team_features_init();
return 0;
err_nl_init:
diff --git a/drivers/net/thunderbolt.c b/drivers/net/thunderbolt.c index ff5d0e98a088..baed53386606 100644 --- a/drivers/net/thunderbolt.c +++ b/drivers/net/thunderbolt.c @@ -14,6 +14,7 @@ #include <linux/jhash.h> #include <linux/module.h> #include <linux/etherdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/rtnetlink.h> #include <linux/sizes.h> #include <linux/thunderbolt.h> @@ -1217,6 +1218,12 @@ static void tbnet_generate_mac(struct net_device *dev) eth_hw_addr_set(dev, addr); }
+static DECLARE_NETDEV_FEATURE_SET(tbnet_hw_feature_set,
NETIF_F_SG_BIT,
NETIF_F_GRO_BIT,
NETIF_F_IP_CSUM_BIT,
NETIF_F_IPV6_CSUM_BIT);
- static int tbnet_probe(struct tb_service *svc, const struct tb_service_id *id) { struct tb_xdomain *xd = tb_service_parent(svc);
@@ -1259,8 +1266,8 @@ static int tbnet_probe(struct tb_service *svc, const struct tb_service_id *id) * we need to announce support for most of the offloading * features here. */
- dev->hw_features = NETIF_F_SG | NETIF_F_ALL_TSO | NETIF_F_GRO |
NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
- dev->hw_features = NETIF_F_ALL_TSO;
- netdev_hw_features_set_array(dev, &tbnet_hw_feature_set); dev->features = dev->hw_features | NETIF_F_HIGHDMA; dev->hard_header_len += sizeof(struct thunderbolt_ip_frame_header);
diff --git a/drivers/net/tun.c b/drivers/net/tun.c index 259b2b84b2b3..d34d930a3029 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c @@ -43,6 +43,7 @@ #include <linux/init.h> #include <linux/skbuff.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/etherdevice.h> #include <linux/miscdevice.h> #include <linux/ethtool.h> @@ -171,6 +172,19 @@ struct tun_prog { struct bpf_prog *prog; };
+static netdev_features_t tun_user_features __ro_after_init; +static DECLARE_NETDEV_FEATURE_SET(tun_user_feature_set,
NETIF_F_HW_CSUM_BIT,
NETIF_F_TSO_ECN_BIT,
NETIF_F_TSO_BIT,
NETIF_F_TSO6_BIT);
+static DECLARE_NETDEV_FEATURE_SET(tun_hw_feature_set,
NETIF_F_SG_BIT,
NETIF_F_FRAGLIST_BIT,
NETIF_F_HW_VLAN_CTAG_TX_BIT,
NETIF_F_HW_VLAN_STAG_TX_BIT);
+#define TUN_USER_FEATURES tun_user_features
- /* Since the socket were moved to tun_file, to preserve the behavior of persist
- device, socket filter, sndbuf and vnet header size were restore when the
- file were attached to a persist device.
@@ -184,8 +198,6 @@ struct tun_struct {
struct net_device *dev; netdev_features_t set_features; -#define TUN_USER_FEATURES (NETIF_F_HW_CSUM|NETIF_F_TSO_ECN|NETIF_F_TSO| \
NETIF_F_TSO6)
int align; int vnet_hdr_sz;
@@ -989,9 +1001,8 @@ static int tun_net_init(struct net_device *dev)
tun_flow_init(tun);
- dev->hw_features = NETIF_F_SG | NETIF_F_FRAGLIST |
TUN_USER_FEATURES | NETIF_F_HW_VLAN_CTAG_TX |
NETIF_F_HW_VLAN_STAG_TX;
- dev->hw_features = TUN_USER_FEATURES;
- netdev_hw_features_set_array(dev, &tun_hw_feature_set); dev->features = dev->hw_features | NETIF_F_LLTX; dev->vlan_features = dev->features & ~(NETIF_F_HW_VLAN_CTAG_TX |
@@ -3668,6 +3679,11 @@ static struct notifier_block tun_notifier_block __read_mostly = { .notifier_call = tun_device_event, };
+static void __init tun_features_init(void) +{
- netdev_features_set_array(&tun_user_feature_set, &tun_user_features);
+}
- static int __init tun_init(void) { int ret = 0;
@@ -3692,6 +3708,8 @@ static int __init tun_init(void) goto err_notifier; }
tun_features_init();
return 0;
err_notifier:
diff --git a/drivers/net/usb/aqc111.c b/drivers/net/usb/aqc111.c index 3020e81159d0..d55be54264f8 100644 --- a/drivers/net/usb/aqc111.c +++ b/drivers/net/usb/aqc111.c @@ -9,6 +9,7 @@
#include <linux/module.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/ethtool.h> #include <linux/mii.h> #include <linux/usb.h> @@ -22,6 +23,31 @@
#define DRIVER_NAME "aqc111"
+/* Feature. ********************************************/ +DECLARE_NETDEV_FEATURE_SET(aq_support_feature_set,
NETIF_F_SG_BIT,
NETIF_F_IP_CSUM_BIT,
NETIF_F_IPV6_CSUM_BIT,
NETIF_F_RXCSUM_BIT,
NETIF_F_TSO_BIT,
NETIF_F_HW_VLAN_CTAG_TX_BIT,
NETIF_F_HW_VLAN_CTAG_RX_BIT);
+DECLARE_NETDEV_FEATURE_SET(aq_support_hw_feature_set,
NETIF_F_SG_BIT,
NETIF_F_IP_CSUM_BIT,
NETIF_F_IPV6_CSUM_BIT,
NETIF_F_RXCSUM_BIT,
NETIF_F_TSO_BIT,
NETIF_F_HW_VLAN_CTAG_FILTER_BIT);
+DECLARE_NETDEV_FEATURE_SET(aq_support_vlan_feature_set,
NETIF_F_SG_BIT,
NETIF_F_IP_CSUM_BIT,
NETIF_F_IPV6_CSUM_BIT,
NETIF_F_RXCSUM_BIT,
NETIF_F_TSO_BIT);
- static int aqc111_read_cmd_nopm(struct usbnet *dev, u8 cmd, u16 value, u16 index, u16 size, void *data) {
@@ -731,9 +757,9 @@ static int aqc111_bind(struct usbnet *dev, struct usb_interface *intf) if (usb_device_no_sg_constraint(dev->udev)) dev->can_dma_sg = 1;
- dev->net->hw_features |= AQ_SUPPORT_HW_FEATURE;
- dev->net->features |= AQ_SUPPORT_FEATURE;
- dev->net->vlan_features |= AQ_SUPPORT_VLAN_FEATURE;
netdev_hw_features_set_array(dev->net, &aq_support_hw_feature_set);
netdev_active_features_set_array(dev->net, &aq_support_feature_set);
netdev_vlan_features_set_array(dev->net, &aq_support_vlan_feature_set);
netif_set_tso_max_size(dev->net, 65535);
@@ -996,9 +1022,9 @@ static int aqc111_reset(struct usbnet *dev) if (usb_device_no_sg_constraint(dev->udev)) dev->can_dma_sg = 1;
- dev->net->hw_features |= AQ_SUPPORT_HW_FEATURE;
- dev->net->features |= AQ_SUPPORT_FEATURE;
- dev->net->vlan_features |= AQ_SUPPORT_VLAN_FEATURE;
netdev_hw_features_set_array(dev->net, &aq_support_hw_feature_set);
netdev_active_features_set_array(dev->net, &aq_support_feature_set);
netdev_vlan_features_set_array(dev->net, &aq_support_vlan_feature_set);
/* Power up ethernet PHY */ aqc111_data->phy_cfg = AQ_PHY_POWER_EN;
diff --git a/drivers/net/usb/aqc111.h b/drivers/net/usb/aqc111.h index b562db4da337..ebc23df8295f 100644 --- a/drivers/net/usb/aqc111.h +++ b/drivers/net/usb/aqc111.h @@ -24,20 +24,6 @@ #define AQ_USB_PHY_SET_TIMEOUT 10000 #define AQ_USB_SET_TIMEOUT 4000
-/* Feature. ********************************************/ -#define AQ_SUPPORT_FEATURE (NETIF_F_SG | NETIF_F_IP_CSUM |\
NETIF_F_IPV6_CSUM | NETIF_F_RXCSUM |\
NETIF_F_TSO | NETIF_F_HW_VLAN_CTAG_TX |\
NETIF_F_HW_VLAN_CTAG_RX)
-#define AQ_SUPPORT_HW_FEATURE (NETIF_F_SG | NETIF_F_IP_CSUM |\
NETIF_F_IPV6_CSUM | NETIF_F_RXCSUM |\
NETIF_F_TSO | NETIF_F_HW_VLAN_CTAG_FILTER)
-#define AQ_SUPPORT_VLAN_FEATURE (NETIF_F_SG | NETIF_F_IP_CSUM |\
NETIF_F_IPV6_CSUM | NETIF_F_RXCSUM |\
NETIF_F_TSO)
/* SFR Reg. ********************************************/
#define SFR_GENERAL_STATUS 0x03
diff --git a/drivers/net/usb/ax88179_178a.c b/drivers/net/usb/ax88179_178a.c index 3b0e8f93e3c8..27fcb75dcba3 100644 --- a/drivers/net/usb/ax88179_178a.c +++ b/drivers/net/usb/ax88179_178a.c @@ -13,6 +13,7 @@ #include <linux/usb/usbnet.h> #include <uapi/linux/mdio.h> #include <linux/mdio.h> +#include <linux/netdev_features_helper.h>
#define AX88179_PHY_ID 0x03 #define AX_EEPROM_LEN 0x100 @@ -1265,6 +1266,13 @@ static void ax88179_get_mac_addr(struct usbnet *dev) dev->net->dev_addr); }
+DECLARE_NETDEV_FEATURE_SET(ax88179_feature_set,
NETIF_F_SG_BIT,
NETIF_F_IP_CSUM_BIT,
NETIF_F_IPV6_CSUM_BIT,
NETIF_F_RXCSUM_BIT,
NETIF_F_TSO_BIT);
- static int ax88179_bind(struct usbnet *dev, struct usb_interface *intf) { struct ax88179_data *ax179_data;
@@ -1291,8 +1299,7 @@ static int ax88179_bind(struct usbnet *dev, struct usb_interface *intf) dev->mii.phy_id = 0x03; dev->mii.supports_gmii = 1;
- dev->net->features |= NETIF_F_SG | NETIF_F_IP_CSUM |
NETIF_F_IPV6_CSUM | NETIF_F_RXCSUM | NETIF_F_TSO;
netdev_active_features_set_array(dev->net, &ax88179_feature_set);
dev->net->hw_features |= dev->net->features;
diff --git a/drivers/net/usb/lan78xx.c b/drivers/net/usb/lan78xx.c index 3226ab33afae..b3c01bee9504 100644 --- a/drivers/net/usb/lan78xx.c +++ b/drivers/net/usb/lan78xx.c @@ -25,6 +25,7 @@ #include <linux/irq.h> #include <linux/irqchip/chained_irq.h> #include <linux/microchipphy.h> +#include <linux/netdev_features_helper.h> #include <linux/phy_fixed.h> #include <linux/of_mdio.h> #include <linux/of_net.h> @@ -3430,6 +3431,11 @@ lan78xx_start_xmit(struct sk_buff *skb, struct net_device *net) return NETDEV_TX_OK; }
+static DECLARE_NETDEV_FEATURE_SET(lan78xx_tso_feature_set,
NETIF_F_TSO_BIT,
NETIF_F_TSO6_BIT,
NETIF_F_SG_BIT);
- static int lan78xx_bind(struct lan78xx_net *dev, struct usb_interface *intf) { struct lan78xx_priv *pdata = NULL;
@@ -3465,7 +3471,7 @@ static int lan78xx_bind(struct lan78xx_net *dev, struct usb_interface *intf) dev->net->features |= NETIF_F_RXCSUM;
if (DEFAULT_TSO_CSUM_ENABLE)
dev->net->features |= NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_SG;
netdev_active_features_set_array(dev->net, &lan78xx_tso_feature_set);
if (DEFAULT_VLAN_RX_OFFLOAD) dev->net->features |= NETIF_F_HW_VLAN_CTAG_RX;
diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c index 0f6efaabaa32..5e11eaab71f5 100644 --- a/drivers/net/usb/r8152.c +++ b/drivers/net/usb/r8152.c @@ -7,6 +7,7 @@ #include <linux/slab.h> #include <linux/module.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/etherdevice.h> #include <linux/mii.h> #include <linux/ethtool.h> @@ -2095,6 +2096,11 @@ static struct tx_agg *r8152_get_tx_agg(struct r8152 *tp) return agg; }
+static DECLARE_NETDEV_FEATURE_SET(r8152_csum_feature_set,
NETIF_F_SG_BIT,
NETIF_F_IPV6_CSUM_BIT,
NETIF_F_TSO6_BIT);
- /* r8152_csum_workaround()
- The hw limits the value of the transport offset. When the offset is out of
- range, calculate the checksum by sw.
@@ -2107,7 +2113,7 @@ static void r8152_csum_workaround(struct r8152 *tp, struct sk_buff *skb, struct sk_buff *segs, *seg, *next; struct sk_buff_head seg_list;
features &= ~(NETIF_F_SG | NETIF_F_IPV6_CSUM | NETIF_F_TSO6);
segs = skb_gso_segment(skb, features); if (IS_ERR(segs) || !segs) goto drop;netdev_features_clear_array(&r8152_csum_feature_set, &features);
@@ -9576,6 +9582,35 @@ u8 rtl8152_get_version(struct usb_interface *intf) } EXPORT_SYMBOL_GPL(rtl8152_get_version);
+static DECLARE_NETDEV_FEATURE_SET(r8152_feature_set,
NETIF_F_RXCSUM_BIT,
NETIF_F_IP_CSUM_BIT,
NETIF_F_SG_BIT,
NETIF_F_TSO_BIT,
NETIF_F_FRAGLIST_BIT,
NETIF_F_IPV6_CSUM_BIT,
NETIF_F_TSO6_BIT,
NETIF_F_HW_VLAN_CTAG_RX_BIT,
NETIF_F_HW_VLAN_CTAG_TX_BIT);
+static DECLARE_NETDEV_FEATURE_SET(r8152_hw_feature_set,
NETIF_F_RXCSUM_BIT,
NETIF_F_IP_CSUM_BIT,
NETIF_F_SG_BIT,
NETIF_F_TSO_BIT,
NETIF_F_FRAGLIST_BIT,
NETIF_F_IPV6_CSUM_BIT,
NETIF_F_TSO6_BIT,
NETIF_F_HW_VLAN_CTAG_RX_BIT,
NETIF_F_HW_VLAN_CTAG_TX_BIT);
+static DECLARE_NETDEV_FEATURE_SET(r8152_vlan_feature_set,
NETIF_F_SG_BIT,
NETIF_F_IP_CSUM_BIT,
NETIF_F_TSO_BIT,
NETIF_F_HIGHDMA_BIT,
NETIF_F_FRAGLIST_BIT,
NETIF_F_IPV6_CSUM_BIT,
NETIF_F_TSO6_BIT);
- static bool rtl8152_supports_lenovo_macpassthru(struct usb_device *udev) { int parent_vendor_id = le16_to_cpu(udev->parent->descriptor.idVendor);
@@ -9662,17 +9697,11 @@ static int rtl8152_probe(struct usb_interface *intf, netdev->netdev_ops = &rtl8152_netdev_ops; netdev->watchdog_timeo = RTL8152_TX_TIMEOUT;
- netdev->features |= NETIF_F_RXCSUM | NETIF_F_IP_CSUM | NETIF_F_SG |
NETIF_F_TSO | NETIF_F_FRAGLIST | NETIF_F_IPV6_CSUM |
NETIF_F_TSO6 | NETIF_F_HW_VLAN_CTAG_RX |
NETIF_F_HW_VLAN_CTAG_TX;
- netdev->hw_features = NETIF_F_RXCSUM | NETIF_F_IP_CSUM | NETIF_F_SG |
NETIF_F_TSO | NETIF_F_FRAGLIST |
NETIF_F_IPV6_CSUM | NETIF_F_TSO6 |
NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_HW_VLAN_CTAG_TX;
- netdev->vlan_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO |
NETIF_F_HIGHDMA | NETIF_F_FRAGLIST |
NETIF_F_IPV6_CSUM | NETIF_F_TSO6;
netdev_active_features_set_array(netdev, &r8152_feature_set);
netdev_hw_features_zero(netdev);
netdev_hw_features_set_array(netdev, &r8152_hw_feature_set);
netdev_vlan_features_zero(netdev);
netdev_vlan_features_set_array(netdev, &r8152_vlan_feature_set);
if (tp->version == RTL_VER_01) { netdev->features &= ~NETIF_F_RXCSUM;
diff --git a/drivers/net/usb/smsc75xx.c b/drivers/net/usb/smsc75xx.c index 95de452ff4da..34b79291e159 100644 --- a/drivers/net/usb/smsc75xx.c +++ b/drivers/net/usb/smsc75xx.c @@ -8,6 +8,7 @@ #include <linux/module.h> #include <linux/kmod.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/etherdevice.h> #include <linux/ethtool.h> #include <linux/mii.h> @@ -1445,6 +1446,11 @@ static const struct net_device_ops smsc75xx_netdev_ops = { .ndo_set_features = smsc75xx_set_features, };
+static DECLARE_NETDEV_FEATURE_SET(smsc75xx_hw_feature_set,
NETIF_F_IP_CSUM_BIT,
NETIF_F_IPV6_CSUM_BIT,
NETIF_F_RXCSUM_BIT);
- static int smsc75xx_bind(struct usbnet *dev, struct usb_interface *intf) { struct smsc75xx_priv *pdata = NULL;
@@ -1478,8 +1484,8 @@ static int smsc75xx_bind(struct usbnet *dev, struct usb_interface *intf) if (DEFAULT_RX_CSUM_ENABLE) dev->net->features |= NETIF_F_RXCSUM;
- dev->net->hw_features = NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
NETIF_F_RXCSUM;
netdev_hw_features_zero(dev->net);
netdev_hw_features_set_array(dev->net, &smsc75xx_hw_feature_set);
ret = smsc75xx_wait_ready(dev, 0); if (ret < 0) {
diff --git a/drivers/net/veth.c b/drivers/net/veth.c index 2cb833b3006a..6de15832dafe 100644 --- a/drivers/net/veth.c +++ b/drivers/net/veth.c @@ -10,6 +10,7 @@ */
#include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/slab.h> #include <linux/ethtool.h> #include <linux/etherdevice.h> @@ -1620,14 +1621,22 @@ static const struct net_device_ops veth_netdev_ops = { .ndo_get_peer_dev = veth_peer_dev, };
-#define VETH_FEATURES (NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_HW_CSUM | \
NETIF_F_RXCSUM | NETIF_F_SCTP_CRC | NETIF_F_HIGHDMA | \
NETIF_F_GSO_SOFTWARE | NETIF_F_GSO_ENCAP_ALL | \
NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX | \
NETIF_F_HW_VLAN_STAG_TX | NETIF_F_HW_VLAN_STAG_RX )
+static DECLARE_NETDEV_FEATURE_SET(veth_feature_set,
NETIF_F_SG_BIT,
NETIF_F_FRAGLIST_BIT,
NETIF_F_HW_CSUM_BIT,
NETIF_F_RXCSUM_BIT,
NETIF_F_SCTP_CRC_BIT,
NETIF_F_HIGHDMA_BIT,
NETIF_F_HW_VLAN_CTAG_TX_BIT,
NETIF_F_HW_VLAN_CTAG_RX_BIT,
NETIF_F_HW_VLAN_STAG_TX_BIT,
NETIF_F_HW_VLAN_STAG_RX_BIT);
static void veth_setup(struct net_device *dev) {
netdev_features_t veth_features;
ether_setup(dev);
dev->priv_flags &= ~IFF_TX_SKB_SHARING;
@@ -1637,8 +1646,10 @@ static void veth_setup(struct net_device *dev)
dev->netdev_ops = &veth_netdev_ops; dev->ethtool_ops = &veth_ethtool_ops;
- veth_features = NETIF_F_GSO_SOFTWARE | NETIF_F_GSO_ENCAP_ALL;
- netdev_features_set_array(&veth_feature_set, &veth_features); dev->features |= NETIF_F_LLTX;
- dev->features |= VETH_FEATURES;
- dev->features |= veth_features; dev->vlan_features = dev->features & ~(NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_STAG_TX |
@@ -1648,8 +1659,8 @@ static void veth_setup(struct net_device *dev) dev->priv_destructor = veth_dev_free; dev->max_mtu = ETH_MAX_MTU;
- dev->hw_features = VETH_FEATURES;
- dev->hw_enc_features = VETH_FEATURES;
- dev->hw_features = veth_features;
- dev->hw_enc_features = veth_features; dev->mpls_features = NETIF_F_HW_CSUM | NETIF_F_GSO_SOFTWARE; netif_set_tso_max_size(dev, GSO_MAX_SIZE); }
diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c index 53b3b241e027..b2f3fb5a29d5 100644 --- a/drivers/net/vmxnet3/vmxnet3_drv.c +++ b/drivers/net/vmxnet3/vmxnet3_drv.c @@ -3301,26 +3301,42 @@ vmxnet3_change_mtu(struct net_device *netdev, int new_mtu) return err; }
+static DECLARE_NETDEV_FEATURE_SET(vmxnet3_hw_feature_set,
NETIF_F_SG_BIT,
NETIF_F_RXCSUM_BIT,
NETIF_F_HW_CSUM_BIT,
NETIF_F_HW_VLAN_CTAG_TX_BIT,
NETIF_F_HW_VLAN_CTAG_RX_BIT,
NETIF_F_TSO_BIT,
NETIF_F_TSO6_BIT,
NETIF_F_LRO_BIT,
NETIF_F_HIGHDMA_BIT);
+static DECLARE_NETDEV_FEATURE_SET(vmxnet3_hw_enc_feature_set,
NETIF_F_SG_BIT,
NETIF_F_RXCSUM_BIT,
NETIF_F_HW_CSUM_BIT,
NETIF_F_HW_VLAN_CTAG_TX_BIT,
NETIF_F_HW_VLAN_CTAG_RX_BIT,
NETIF_F_TSO_BIT,
NETIF_F_TSO6_BIT,
NETIF_F_LRO_BIT,
NETIF_F_GSO_UDP_TUNNEL_BIT,
NETIF_F_GSO_UDP_TUNNEL_CSUM_BIT);
static void vmxnet3_declare_features(struct vmxnet3_adapter *adapter) { struct net_device *netdev = adapter->netdev;
- netdev->hw_features = NETIF_F_SG | NETIF_F_RXCSUM |
NETIF_F_HW_CSUM | NETIF_F_HW_VLAN_CTAG_TX |
NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_TSO | NETIF_F_TSO6 |
NETIF_F_LRO | NETIF_F_HIGHDMA;
netdev_hw_features_zero(netdev);
netdev_hw_features_set_array(netdev, &vmxnet3_hw_feature_set);
if (VMXNET3_VERSION_GE_4(adapter)) { netdev->hw_features |= NETIF_F_GSO_UDP_TUNNEL | NETIF_F_GSO_UDP_TUNNEL_CSUM;
netdev->hw_enc_features = NETIF_F_SG | NETIF_F_RXCSUM |
NETIF_F_HW_CSUM | NETIF_F_HW_VLAN_CTAG_TX |
NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_TSO | NETIF_F_TSO6 |
NETIF_F_LRO | NETIF_F_GSO_UDP_TUNNEL |
NETIF_F_GSO_UDP_TUNNEL_CSUM;
netdev_hw_enc_features_zero(netdev);
netdev_hw_enc_features_set_array(netdev,
&vmxnet3_hw_enc_feature_set);
}
if (VMXNET3_VERSION_GE_7(adapter)) {
diff --git a/drivers/net/vmxnet3/vmxnet3_ethtool.c b/drivers/net/vmxnet3/vmxnet3_ethtool.c index e2034adc3a1a..25b3243a9630 100644 --- a/drivers/net/vmxnet3/vmxnet3_ethtool.c +++ b/drivers/net/vmxnet3/vmxnet3_ethtool.c @@ -298,15 +298,35 @@ netdev_features_t vmxnet3_features_check(struct sk_buff *skb, return features; }
+static DECLARE_NETDEV_FEATURE_SET(vmxnet3_hw_enc_feature_set,
NETIF_F_SG_BIT,
NETIF_F_RXCSUM_BIT,
NETIF_F_HW_CSUM_BIT,
NETIF_F_HW_VLAN_CTAG_TX_BIT,
NETIF_F_HW_VLAN_CTAG_RX_BIT,
NETIF_F_TSO_BIT,
NETIF_F_TSO6_BIT,
NETIF_F_LRO_BIT);
+static DECLARE_NETDEV_FEATURE_SET(vmxnet3_hw_enc_feature_set2,
NETIF_F_SG_BIT,
NETIF_F_RXCSUM_BIT,
NETIF_F_HW_CSUM_BIT,
NETIF_F_HW_VLAN_CTAG_TX_BIT,
NETIF_F_HW_VLAN_CTAG_RX_BIT,
NETIF_F_TSO_BIT,
NETIF_F_TSO6_BIT,
NETIF_F_LRO_BIT,
NETIF_F_GSO_UDP_TUNNEL_BIT,
NETIF_F_GSO_UDP_TUNNEL_CSUM_BIT);
static void vmxnet3_enable_encap_offloads(struct net_device *netdev, netdev_features_t features) { struct vmxnet3_adapter *adapter = netdev_priv(netdev);
if (VMXNET3_VERSION_GE_4(adapter)) {
netdev->hw_enc_features |= NETIF_F_SG | NETIF_F_RXCSUM |
NETIF_F_HW_CSUM | NETIF_F_HW_VLAN_CTAG_TX |
NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_TSO | NETIF_F_TSO6 |
NETIF_F_LRO;
netdev_hw_enc_features_set_array(netdev,
if (features & NETIF_F_GSO_UDP_TUNNEL) netdev->hw_enc_features |= NETIF_F_GSO_UDP_TUNNEL; if (features & NETIF_F_GSO_UDP_TUNNEL_CSUM)&vmxnet3_hw_enc_feature_set);
@@ -364,11 +384,8 @@ static void vmxnet3_disable_encap_offloads(struct net_device *netdev) struct vmxnet3_adapter *adapter = netdev_priv(netdev);
if (VMXNET3_VERSION_GE_4(adapter)) {
netdev->hw_enc_features &= ~(NETIF_F_SG | NETIF_F_RXCSUM |
NETIF_F_HW_CSUM | NETIF_F_HW_VLAN_CTAG_TX |
NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_TSO | NETIF_F_TSO6 |
NETIF_F_LRO | NETIF_F_GSO_UDP_TUNNEL |
NETIF_F_GSO_UDP_TUNNEL_CSUM);
netdev_hw_enc_features_clear_array(netdev,
} if (VMXNET3_VERSION_GE_7(adapter)) { unsigned long flags;&vmxnet3_hw_enc_feature_set2);
diff --git a/drivers/net/vmxnet3/vmxnet3_int.h b/drivers/net/vmxnet3/vmxnet3_int.h index 3367db23aa13..d42f997efa4a 100644 --- a/drivers/net/vmxnet3/vmxnet3_int.h +++ b/drivers/net/vmxnet3/vmxnet3_int.h @@ -31,6 +31,7 @@ #include <linux/ethtool.h> #include <linux/delay.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/pci.h> #include <linux/compiler.h> #include <linux/slab.h> diff --git a/drivers/net/vrf.c b/drivers/net/vrf.c index 5df7a0abc39d..7ad145f832cc 100644 --- a/drivers/net/vrf.c +++ b/drivers/net/vrf.c @@ -13,6 +13,7 @@ #include <linux/module.h> #include <linux/kernel.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/etherdevice.h> #include <linux/ip.h> #include <linux/init.h> @@ -1664,6 +1665,14 @@ static int vrf_add_fib_rules(const struct net_device *dev) return err; }
+static DECLARE_NETDEV_FEATURE_SET(vrf_offload_feature_set,
NETIF_F_RXCSUM_BIT,
NETIF_F_HW_CSUM_BIT,
NETIF_F_SCTP_CRC_BIT,
NETIF_F_SG_BIT,
NETIF_F_FRAGLIST_BIT,
NETIF_F_HIGHDMA_BIT);
- static void vrf_setup(struct net_device *dev) { ether_setup(dev);
@@ -1688,8 +1697,7 @@ static void vrf_setup(struct net_device *dev)
/* enable offload features */ dev->features |= NETIF_F_GSO_SOFTWARE;
- dev->features |= NETIF_F_RXCSUM | NETIF_F_HW_CSUM | NETIF_F_SCTP_CRC;
- dev->features |= NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_HIGHDMA;
netdev_active_features_set_array(dev, &vrf_offload_feature_set);
dev->hw_features = dev->features; dev->hw_enc_features = dev->features;
diff --git a/drivers/net/vsockmon.c b/drivers/net/vsockmon.c index b1bb1b04b664..a5cee59ea872 100644 --- a/drivers/net/vsockmon.c +++ b/drivers/net/vsockmon.c @@ -3,6 +3,7 @@ #include <linux/module.h> #include <linux/kernel.h> #include <linux/if_arp.h> +#include <linux/netdev_features_helper.h> #include <net/rtnetlink.h> #include <net/sock.h> #include <net/af_vsock.h> @@ -97,6 +98,12 @@ static const struct ethtool_ops vsockmon_ethtool_ops = { .get_link = always_on, };
+static DECLARE_NETDEV_FEATURE_SET(vsockmon_feature_set,
NETIF_F_SG_BIT,
NETIF_F_FRAGLIST_BIT,
NETIF_F_HIGHDMA_BIT,
NETIF_F_LLTX_BIT);
- static void vsockmon_setup(struct net_device *dev) { dev->type = ARPHRD_VSOCKMON;
@@ -106,8 +113,8 @@ static void vsockmon_setup(struct net_device *dev) dev->ethtool_ops = &vsockmon_ethtool_ops; dev->needs_free_netdev = true;
- dev->features = NETIF_F_SG | NETIF_F_FRAGLIST |
NETIF_F_HIGHDMA | NETIF_F_LLTX;
netdev_active_features_zero(dev);
netdev_active_features_set_array(dev, &vsockmon_feature_set);
dev->flags = IFF_NOARP;
diff --git a/drivers/net/vxlan/vxlan_core.c b/drivers/net/vxlan/vxlan_core.c index 8b0710b576c2..4892c212ff1a 100644 --- a/drivers/net/vxlan/vxlan_core.c +++ b/drivers/net/vxlan/vxlan_core.c @@ -15,6 +15,7 @@ #include <linux/igmp.h> #include <linux/if_ether.h> #include <linux/ethtool.h> +#include <linux/netdev_features_helper.h> #include <net/arp.h> #include <net/ndisc.h> #include <net/gro.h> @@ -3150,6 +3151,18 @@ static void vxlan_offload_rx_ports(struct net_device *dev, bool push) spin_unlock(&vn->sock_lock); }
+static DECLARE_NETDEV_FEATURE_SET(vxlan_feature_set,
NETIF_F_LLTX_BIT,
NETIF_F_SG_BIT,
NETIF_F_HW_CSUM_BIT,
NETIF_F_FRAGLIST_BIT,
NETIF_F_RXCSUM_BIT);
+static DECLARE_NETDEV_FEATURE_SET(vxlan_hw_feature_set,
NETIF_F_SG_BIT,
NETIF_F_HW_CSUM_BIT,
NETIF_F_FRAGLIST_BIT,
NETIF_F_RXCSUM_BIT);
- /* Initialize the device structure. */ static void vxlan_setup(struct net_device *dev) {
@@ -3162,14 +3175,11 @@ static void vxlan_setup(struct net_device *dev) dev->needs_free_netdev = true; SET_NETDEV_DEVTYPE(dev, &vxlan_type);
- dev->features |= NETIF_F_LLTX;
- dev->features |= NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_FRAGLIST;
- dev->features |= NETIF_F_RXCSUM;
netdev_active_features_set_array(dev, &vxlan_feature_set); dev->features |= NETIF_F_GSO_SOFTWARE;
dev->vlan_features = dev->features;
- dev->hw_features |= NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_FRAGLIST;
- dev->hw_features |= NETIF_F_RXCSUM;
- netdev_hw_features_set_array(dev, &vxlan_hw_feature_set); dev->hw_features |= NETIF_F_GSO_SOFTWARE; netif_keep_dst(dev); dev->priv_flags |= IFF_NO_QUEUE | IFF_CHANGE_PROTO_DOWN;
diff --git a/drivers/net/wireguard/device.c b/drivers/net/wireguard/device.c index aa9a7a5970fd..aeed694110d4 100644 --- a/drivers/net/wireguard/device.c +++ b/drivers/net/wireguard/device.c @@ -15,6 +15,7 @@ #include <linux/rtnetlink.h> #include <linux/inet.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/inetdevice.h> #include <linux/if_arp.h> #include <linux/icmp.h> @@ -271,14 +272,19 @@ static void wg_destruct(struct net_device *dev)
static const struct device_type device_type = { .name = KBUILD_MODNAME };
+static DECLARE_NETDEV_FEATURE_SET(wg_feature_set,
NETIF_F_HW_CSUM_BIT,
NETIF_F_RXCSUM_BIT,
NETIF_F_SG_BIT,
NETIF_F_GSO_BIT,
NETIF_F_HIGHDMA_BIT);
- 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 |
NETIF_F_SG | NETIF_F_GSO |
const int overhead = MESSAGE_MINIMUM_LENGTH + sizeof(struct udphdr) + max(sizeof(struct ipv6hdr), sizeof(struct iphdr));NETIF_F_GSO_SOFTWARE | NETIF_F_HIGHDMA };
netdev_features_t wg_netdev_features;
dev->netdev_ops = &netdev_ops; dev->header_ops = &ip_tunnel_header_ops;
@@ -290,9 +296,11 @@ 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;
- wg_netdev_features = NETIF_F_GSO_SOFTWARE;
- netdev_features_set_array(&wg_feature_set, &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/drivers/net/wireless/ath/wil6210/netdev.c b/drivers/net/wireless/ath/wil6210/netdev.c index 87a88f26233e..c2012c4e0084 100644 --- a/drivers/net/wireless/ath/wil6210/netdev.c +++ b/drivers/net/wireless/ath/wil6210/netdev.c @@ -5,6 +5,7 @@ */
#include <linux/etherdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/rtnetlink.h> #include "wil6210.h" #include "txrx.h" @@ -294,6 +295,14 @@ static u8 wil_vif_find_free_mid(struct wil6210_priv *wil) return U8_MAX; }
+static DECLARE_NETDEV_FEATURE_SET(wil_hw_feature_set,
NETIF_F_HW_CSUM_BIT,
NETIF_F_RXCSUM_BIT,
NETIF_F_SG_BIT,
NETIF_F_GRO_BIT,
NETIF_F_TSO_BIT,
NETIF_F_TSO6_BIT);
- struct wil6210_vif * wil_vif_alloc(struct wil6210_priv *wil, const char *name, unsigned char name_assign_type, enum nl80211_iftype iftype)
@@ -335,9 +344,8 @@ wil_vif_alloc(struct wil6210_priv *wil, const char *name, ndev->netdev_ops = &wil_netdev_ops; wil_set_ethtoolops(ndev); ndev->ieee80211_ptr = wdev;
- ndev->hw_features = NETIF_F_HW_CSUM | NETIF_F_RXCSUM |
NETIF_F_SG | NETIF_F_GRO |
NETIF_F_TSO | NETIF_F_TSO6;
netdev_hw_features_zero(ndev);
netdev_hw_features_set_array(ndev, &wil_hw_feature_set);
ndev->features |= ndev->hw_features; SET_NETDEV_DEV(ndev, wiphy_dev(wdev->wiphy));
diff --git a/drivers/net/xen-netback/interface.c b/drivers/net/xen-netback/interface.c index fb32ae82d9b0..989328168e1c 100644 --- a/drivers/net/xen-netback/interface.c +++ b/drivers/net/xen-netback/interface.c @@ -33,6 +33,7 @@ #include <linux/kthread.h> #include <linux/sched/task.h> #include <linux/ethtool.h> +#include <linux/netdev_features_helper.h> #include <linux/rtnetlink.h> #include <linux/if_vlan.h> #include <linux/vmalloc.h> @@ -476,6 +477,14 @@ static const struct net_device_ops xenvif_netdev_ops = { .ndo_validate_addr = eth_validate_addr, };
+static DECLARE_NETDEV_FEATURE_SET(xenvif_hw_feature_set,
NETIF_F_SG_BIT,
NETIF_F_IP_CSUM_BIT,
NETIF_F_IPV6_CSUM_BIT,
NETIF_F_TSO_BIT,
NETIF_F_TSO6_BIT,
NETIF_F_FRAGLIST_BIT);
- struct xenvif *xenvif_alloc(struct device *parent, domid_t domid, unsigned int handle) {
@@ -522,9 +531,8 @@ struct xenvif *xenvif_alloc(struct device *parent, domid_t domid, INIT_LIST_HEAD(&vif->fe_mcast_addr);
dev->netdev_ops = &xenvif_netdev_ops;
- dev->hw_features = NETIF_F_SG |
NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_FRAGLIST;
- netdev_hw_features_zero(dev);
- netdev_hw_features_set_array(dev, &xenvif_hw_feature_set); dev->features = dev->hw_features | NETIF_F_RXCSUM; dev->ethtool_ops = &xenvif_ethtool_ops;
diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c index 27a11cc08c61..d4833794cec0 100644 --- a/drivers/net/xen-netfront.c +++ b/drivers/net/xen-netfront.c @@ -34,6 +34,7 @@ #include <linux/module.h> #include <linux/kernel.h> #include <linux/netdevice.h> +#include <linux/netdev_features_helper.h> #include <linux/etherdevice.h> #include <linux/skbuff.h> #include <linux/ethtool.h> @@ -1703,6 +1704,16 @@ static void xennet_free_netdev(struct net_device *netdev) free_netdev(netdev); }
+static DECLARE_NETDEV_FEATURE_SET(xennet_feature_set,
NETIF_F_IP_CSUM_BIT,
NETIF_F_RXCSUM_BIT,
NETIF_F_GSO_ROBUST_BIT);
+static DECLARE_NETDEV_FEATURE_SET(xennet_hw_feature_set,
NETIF_F_SG_BIT,
NETIF_F_IPV6_CSUM_BIT,
NETIF_F_TSO_BIT,
NETIF_F_TSO6_BIT);
- static struct net_device *xennet_create_dev(struct xenbus_device *dev) { int err;
@@ -1728,11 +1739,10 @@ static struct net_device *xennet_create_dev(struct xenbus_device *dev)
netdev->netdev_ops = &xennet_netdev_ops;
- netdev->features = NETIF_F_IP_CSUM | NETIF_F_RXCSUM |
NETIF_F_GSO_ROBUST;
- netdev->hw_features = NETIF_F_SG |
NETIF_F_IPV6_CSUM |
NETIF_F_TSO | NETIF_F_TSO6;
netdev_active_features_zero(netdev);
netdev_active_features_set_array(netdev, &xennet_feature_set);
netdev_hw_features_zero(netdev);
netdev_hw_features_set_array(netdev, &xennet_hw_feature_set);
/* * Assume that all hw features are available for now. This set
diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c index 8d44bce0477a..8628599ed692 100644 --- a/drivers/s390/net/qeth_l3_main.c +++ b/drivers/s390/net/qeth_l3_main.c @@ -1854,6 +1854,11 @@ static const struct net_device_ops qeth_l3_osa_netdev_ops = { .ndo_neigh_setup = qeth_l3_neigh_setup, };
+static DECLARE_NETDEV_FEATURE_SET(qeth_l3_feature_set,
NETIF_F_TSO_BIT,
NETIF_F_RXCSUM_BIT,
NETIF_F_IP_CSUM_BIT);
- static int qeth_l3_setup_netdev(struct qeth_card *card) { struct net_device *dev = card->dev;
@@ -1868,10 +1873,10 @@ static int qeth_l3_setup_netdev(struct qeth_card *card)
if (!IS_VM_NIC(card)) { card->dev->features |= NETIF_F_SG;
card->dev->hw_features |= NETIF_F_TSO |
NETIF_F_RXCSUM | NETIF_F_IP_CSUM;
card->dev->vlan_features |= NETIF_F_TSO |
NETIF_F_RXCSUM | NETIF_F_IP_CSUM;
netdev_hw_features_set_array(card->dev,
&qeth_l3_feature_set);
netdev_vlan_features_set_array(card->dev,
&qeth_l3_feature_set);
}
if (qeth_is_supported6(card, IPA_OUTBOUND_CHECKSUM_V6)) {
diff --git a/drivers/staging/qlge/qlge_main.c b/drivers/staging/qlge/qlge_main.c index 6cd7fc9589c3..a3576a11443d 100644 --- a/drivers/staging/qlge/qlge_main.c +++ b/drivers/staging/qlge/qlge_main.c @@ -31,6 +31,7 @@ #include <linux/if_arp.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/if_vlan.h> @@ -4533,6 +4534,16 @@ static void qlge_timer(struct timer_list *t)
static const struct devlink_ops qlge_devlink_ops;
+static DECLARE_NETDEV_FEATURE_SET(qlge_hw_feature_set,
NETIF_F_SG_BIT,
NETIF_F_IP_CSUM_BIT,
NETIF_F_TSO_BIT,
NETIF_F_TSO_ECN_BIT,
NETIF_F_HW_VLAN_CTAG_TX_BIT,
NETIF_F_HW_VLAN_CTAG_RX_BIT,
NETIF_F_HW_VLAN_CTAG_FILTER_BIT,
NETIF_F_RXCSUM_BIT);
- static int qlge_probe(struct pci_dev *pdev, const struct pci_device_id *pci_entry) {
@@ -4567,14 +4578,8 @@ static int qlge_probe(struct pci_dev *pdev, goto netdev_free;
SET_NETDEV_DEV(ndev, &pdev->dev);
- ndev->hw_features = NETIF_F_SG |
NETIF_F_IP_CSUM |
NETIF_F_TSO |
NETIF_F_TSO_ECN |
NETIF_F_HW_VLAN_CTAG_TX |
NETIF_F_HW_VLAN_CTAG_RX |
NETIF_F_HW_VLAN_CTAG_FILTER |
NETIF_F_RXCSUM;
- netdev_hw_features_zero(ndev);
- netdev_hw_features_set_array(ndev, &qlge_hw_feature_set); ndev->features = ndev->hw_features; ndev->vlan_features = ndev->hw_features; /* vlan gets same features (except vlan filter) */
diff --git a/include/net/bonding.h b/include/net/bonding.h index 6e78d657aa05..cfad04d40bf2 100644 --- a/include/net/bonding.h +++ b/include/net/bonding.h @@ -89,10 +89,9 @@ #define bond_for_each_slave_rcu(bond, pos, iter) \ netdev_for_each_lower_private_rcu((bond)->dev, pos, iter)
-#define BOND_XFRM_FEATURES (NETIF_F_HW_ESP | NETIF_F_HW_ESP_TX_CSUM | \
NETIF_F_GSO_ESP)
+#define BOND_XFRM_FEATURES netdev_xfrm_features
-#define BOND_TLS_FEATURES (NETIF_F_HW_TLS_TX | NETIF_F_HW_TLS_RX) +#define BOND_TLS_FEATURES netdev_tls_features
#ifdef CONFIG_NET_POLL_CONTROLLER extern atomic_t netpoll_block_tx; diff --git a/include/net/net_failover.h b/include/net/net_failover.h index b12a1c469d1c..781d1de8a190 100644 --- a/include/net/net_failover.h +++ b/include/net/net_failover.h @@ -30,11 +30,7 @@ struct net_failover_info { struct failover *net_failover_create(struct net_device *standby_dev); void net_failover_destroy(struct failover *failover);
-#define FAILOVER_VLAN_FEATURES (NETIF_F_HW_CSUM | NETIF_F_SG | \
NETIF_F_FRAGLIST | NETIF_F_ALL_TSO | \
NETIF_F_HIGHDMA | NETIF_F_LRO)
-#define FAILOVER_ENC_FEATURES (NETIF_F_HW_CSUM | NETIF_F_SG | \
NETIF_F_RXCSUM | NETIF_F_ALL_TSO)
+#define FAILOVER_VLAN_FEATURES failover_vlan_features +#define FAILOVER_ENC_FEATURES failover_enc_features
#endif /* _NET_FAILOVER_H */ diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c index 64ca07daf4ee..75d12ff0d146 100644 --- a/net/8021q/vlan_dev.c +++ b/net/8021q/vlan_dev.c @@ -550,6 +550,13 @@ static struct device_type vlan_type = {
static const struct net_device_ops