]> www.infradead.org Git - users/dwmw2/linux.git/commitdiff
drivers: net: turn on XDP features
authorMarek Majtyka <alardam@gmail.com>
Wed, 1 Feb 2023 10:24:18 +0000 (11:24 +0100)
committerAlexei Starovoitov <ast@kernel.org>
Fri, 3 Feb 2023 04:48:23 +0000 (20:48 -0800)
A summary of the flags being set for various drivers is given below.
Note that XDP_F_REDIRECT_TARGET and XDP_F_FRAG_TARGET are features
that can be turned off and on at runtime. This means that these flags
may be set and unset under RTNL lock protection by the driver. Hence,
READ_ONCE must be used by code loading the flag value.

Also, these flags are not used for synchronization against the availability
of XDP resources on a device. It is merely a hint, and hence the read
may race with the actual teardown of XDP resources on the device. This
may change in the future, e.g. operations taking a reference on the XDP
resources of the driver, and in turn inhibiting turning off this flag.
However, for now, it can only be used as a hint to check whether device
supports becoming a redirection target.

Turn 'hw-offload' feature flag on for:
 - netronome (nfp)
 - netdevsim.

Turn 'native' and 'zerocopy' features flags on for:
 - intel (i40e, ice, ixgbe, igc)
 - mellanox (mlx5).
 - stmmac
 - netronome (nfp)

Turn 'native' features flags on for:
 - amazon (ena)
 - broadcom (bnxt)
 - freescale (dpaa, dpaa2, enetc)
 - funeth
 - intel (igb)
 - marvell (mvneta, mvpp2, octeontx2)
 - mellanox (mlx4)
 - mtk_eth_soc
 - qlogic (qede)
 - sfc
 - socionext (netsec)
 - ti (cpsw)
 - tap
 - tsnep
 - veth
 - xen
 - virtio_net.

Turn 'basic' (tx, pass, aborted and drop) features flags on for:
 - netronome (nfp)
 - cavium (thunder)
 - hyperv.

Turn 'redirect_target' feature flag on for:
 - amanzon (ena)
 - broadcom (bnxt)
 - freescale (dpaa, dpaa2)
 - intel (i40e, ice, igb, ixgbe)
 - ti (cpsw)
 - marvell (mvneta, mvpp2)
 - sfc
 - socionext (netsec)
 - qlogic (qede)
 - mellanox (mlx5)
 - tap
 - veth
 - virtio_net
 - xen

Reviewed-by: Gerhard Engleder <gerhard@engleder-embedded.com>
Reviewed-by: Simon Horman <simon.horman@corigine.com>
Acked-by: Stanislav Fomichev <sdf@google.com>
Acked-by: Jakub Kicinski <kuba@kernel.org>
Co-developed-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Co-developed-by: Lorenzo Bianconi <lorenzo@kernel.org>
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Signed-off-by: Marek Majtyka <alardam@gmail.com>
Link: https://lore.kernel.org/r/3eca9fafb308462f7edb1f58e451d59209aa07eb.1675245258.git.lorenzo@kernel.org
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
40 files changed:
drivers/net/ethernet/amazon/ena/ena_netdev.c
drivers/net/ethernet/aquantia/atlantic/aq_nic.c
drivers/net/ethernet/broadcom/bnxt/bnxt.c
drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c
drivers/net/ethernet/cavium/thunder/nicvf_main.c
drivers/net/ethernet/engleder/tsnep_main.c
drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
drivers/net/ethernet/freescale/enetc/enetc_pf.c
drivers/net/ethernet/fungible/funeth/funeth_main.c
drivers/net/ethernet/intel/i40e/i40e_main.c
drivers/net/ethernet/intel/ice/ice_main.c
drivers/net/ethernet/intel/igb/igb_main.c
drivers/net/ethernet/intel/igc/igc_main.c
drivers/net/ethernet/intel/igc/igc_xdp.c
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
drivers/net/ethernet/marvell/mvneta.c
drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c
drivers/net/ethernet/mediatek/mtk_eth_soc.c
drivers/net/ethernet/mellanox/mlx4/en_netdev.c
drivers/net/ethernet/mellanox/mlx5/core/en_main.c
drivers/net/ethernet/microsoft/mana/mana_en.c
drivers/net/ethernet/netronome/nfp/nfp_net_common.c
drivers/net/ethernet/qlogic/qede/qede_main.c
drivers/net/ethernet/sfc/efx.c
drivers/net/ethernet/sfc/siena/efx.c
drivers/net/ethernet/socionext/netsec.c
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
drivers/net/ethernet/ti/cpsw.c
drivers/net/ethernet/ti/cpsw_new.c
drivers/net/hyperv/netvsc_drv.c
drivers/net/netdevsim/netdev.c
drivers/net/tun.c
drivers/net/veth.c
drivers/net/virtio_net.c
drivers/net/xen-netfront.c
include/net/xdp.h
net/core/xdp.c

index e8ad5ea31affec68303dc089fd0aeccb5fff00f3..d3999db7c6a29d1f6677ca9de4ff197ee28fda4b 100644 (file)
@@ -597,7 +597,9 @@ static int ena_xdp_set(struct net_device *netdev, struct netdev_bpf *bpf)
                                if (rc)
                                        return rc;
                        }
+                       xdp_features_set_redirect_target(netdev, false);
                } else if (old_bpf_prog) {
+                       xdp_features_clear_redirect_target(netdev);
                        rc = ena_destroy_and_free_all_xdp_queues(adapter);
                        if (rc)
                                return rc;
@@ -4103,6 +4105,8 @@ static void ena_set_conf_feat_params(struct ena_adapter *adapter,
        /* Set offload features */
        ena_set_dev_offloads(feat, netdev);
 
+       netdev->xdp_features = NETDEV_XDP_ACT_BASIC | NETDEV_XDP_ACT_REDIRECT;
+
        adapter->max_mtu = feat->dev_attr.max_mtu;
        netdev->max_mtu = adapter->max_mtu;
        netdev->min_mtu = ENA_MIN_MTU;
index 06508eebb585369ab412bfe87ee5e1497d1b4424..d6d6d5d37ff3e639a0ab11ec43f7ad66f2441595 100644 (file)
@@ -384,6 +384,11 @@ void aq_nic_ndev_init(struct aq_nic_s *self)
        self->ndev->mtu = aq_nic_cfg->mtu - ETH_HLEN;
        self->ndev->max_mtu = aq_hw_caps->mtu - ETH_FCS_LEN - ETH_HLEN;
 
+       self->ndev->xdp_features = NETDEV_XDP_ACT_BASIC |
+                                  NETDEV_XDP_ACT_REDIRECT |
+                                  NETDEV_XDP_ACT_NDO_XMIT |
+                                  NETDEV_XDP_ACT_RX_SG |
+                                  NETDEV_XDP_ACT_NDO_XMIT_SG;
 }
 
 void aq_nic_set_tx_ring(struct aq_nic_s *self, unsigned int idx,
index 240a7e8a76528ce3615870a5248a453cbd905719..a1b4356dfb6cd99d85e1120675c325139ea32935 100644 (file)
@@ -13686,6 +13686,9 @@ static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 
        netif_set_tso_max_size(dev, GSO_MAX_SIZE);
 
+       dev->xdp_features = NETDEV_XDP_ACT_BASIC | NETDEV_XDP_ACT_REDIRECT |
+                           NETDEV_XDP_ACT_RX_SG;
+
 #ifdef CONFIG_BNXT_SRIOV
        init_waitqueue_head(&bp->sriov_cfg_wait);
 #endif
index 36d5202c0aeec94c19c92f90a3968dcc1e63ba3e..5843c93b1711fe1e36542b5e7b818aac4e551a42 100644 (file)
@@ -422,9 +422,11 @@ static int bnxt_xdp_set(struct bnxt *bp, struct bpf_prog *prog)
 
        if (prog) {
                bnxt_set_rx_skb_mode(bp, true);
+               xdp_features_set_redirect_target(dev, true);
        } else {
                int rx, tx;
 
+               xdp_features_clear_redirect_target(dev);
                bnxt_set_rx_skb_mode(bp, false);
                bnxt_get_max_rings(bp, &rx, &tx, true);
                if (rx > 1) {
index f2f95493ec89ac4bedfb518b1ff45273d8df6716..8b25313c7f6b8fa28d58cbfb50ff46515880c1f0 100644 (file)
@@ -2218,6 +2218,8 @@ static int nicvf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        netdev->netdev_ops = &nicvf_netdev_ops;
        netdev->watchdog_timeo = NICVF_TX_TIMEOUT;
 
+       netdev->xdp_features = NETDEV_XDP_ACT_BASIC;
+
        /* MTU range: 64 - 9200 */
        netdev->min_mtu = NIC_HW_MIN_FRS;
        netdev->max_mtu = NIC_HW_MAX_FRS;
index c3cf427a9409aca387bf663d32672317a695e213..6982aaa928b5b4dcfe39abfae21eeb60b8a6ec8d 100644 (file)
@@ -1926,6 +1926,10 @@ static int tsnep_probe(struct platform_device *pdev)
        netdev->features = NETIF_F_SG;
        netdev->hw_features = netdev->features | NETIF_F_LOOPBACK;
 
+       netdev->xdp_features = NETDEV_XDP_ACT_BASIC | NETDEV_XDP_ACT_REDIRECT |
+                              NETDEV_XDP_ACT_NDO_XMIT |
+                              NETDEV_XDP_ACT_NDO_XMIT_SG;
+
        /* carrier off reporting is important to ethtool even BEFORE open */
        netif_carrier_off(netdev);
 
index 027fff9f7db073e9c8d4a6b0de0138df50ed931c..9318a2554056d739a90b8d21173b705425ace272 100644 (file)
@@ -244,6 +244,10 @@ static int dpaa_netdev_init(struct net_device *net_dev,
        net_dev->features |= net_dev->hw_features;
        net_dev->vlan_features = net_dev->features;
 
+       net_dev->xdp_features = NETDEV_XDP_ACT_BASIC |
+                               NETDEV_XDP_ACT_REDIRECT |
+                               NETDEV_XDP_ACT_NDO_XMIT;
+
        if (is_valid_ether_addr(mac_addr)) {
                memcpy(net_dev->perm_addr, mac_addr, net_dev->addr_len);
                eth_hw_addr_set(net_dev, mac_addr);
index 2e79d18fc3c7add1b3a811c008b8bfb4ab548f67..746ccfde725589ae7a2fd25d4f79a478aa9f8b17 100644 (file)
@@ -4596,6 +4596,10 @@ static int dpaa2_eth_netdev_init(struct net_device *net_dev)
                            NETIF_F_LLTX | NETIF_F_HW_TC | NETIF_F_TSO;
        net_dev->gso_max_segs = DPAA2_ETH_ENQUEUE_MAX_FDS;
        net_dev->hw_features = net_dev->features;
+       net_dev->xdp_features = NETDEV_XDP_ACT_BASIC |
+                               NETDEV_XDP_ACT_REDIRECT |
+                               NETDEV_XDP_ACT_XSK_ZEROCOPY |
+                               NETDEV_XDP_ACT_NDO_XMIT;
 
        if (priv->dpni_attrs.vlan_filter_entries)
                net_dev->hw_features |= NETIF_F_HW_VLAN_CTAG_FILTER;
index 7facc7d5261e1c1f9080298d25d71a74760d2267..6b54071d4eccb203563bfb04d227b6a2cc8f8c2e 100644 (file)
@@ -807,6 +807,9 @@ static void enetc_pf_netdev_setup(struct enetc_si *si, struct net_device *ndev,
                ndev->hw_features |= NETIF_F_RXHASH;
 
        ndev->priv_flags |= IFF_UNICAST_FLT;
+       ndev->xdp_features = NETDEV_XDP_ACT_BASIC | NETDEV_XDP_ACT_REDIRECT |
+                            NETDEV_XDP_ACT_NDO_XMIT | NETDEV_XDP_ACT_RX_SG |
+                            NETDEV_XDP_ACT_NDO_XMIT_SG;
 
        if (si->hw_features & ENETC_SI_F_PSFP && !enetc_psfp_enable(priv)) {
                priv->active_offloads |= ENETC_F_QCI;
index b4cce30e526a079cb7949a34c95ca1490ae23679..df86770731ad5207eac12579c19e6d1aa98cf6e5 100644 (file)
@@ -1160,6 +1160,11 @@ static int fun_xdp_setup(struct net_device *dev, struct netdev_bpf *xdp)
                        WRITE_ONCE(rxqs[i]->xdp_prog, prog);
        }
 
+       if (prog)
+               xdp_features_set_redirect_target(dev, true);
+       else
+               xdp_features_clear_redirect_target(dev);
+
        dev->max_mtu = prog ? XDP_MAX_MTU : FUN_MAX_MTU;
        old_prog = xchg(&fp->xdp_prog, prog);
        if (old_prog)
@@ -1765,6 +1770,7 @@ static int fun_create_netdev(struct fun_ethdev *ed, unsigned int portid)
        netdev->vlan_features = netdev->features & VLAN_FEAT;
        netdev->mpls_features = netdev->vlan_features;
        netdev->hw_enc_features = netdev->hw_features;
+       netdev->xdp_features = NETDEV_XDP_ACT_BASIC | NETDEV_XDP_ACT_REDIRECT;
 
        netdev->min_mtu = ETH_MIN_MTU;
        netdev->max_mtu = FUN_MAX_MTU;
index 53d0083e35dafed776bb2570bf3fa2086df082b4..8a79cc18c4285e93254e800e66a006818bfd5524 100644 (file)
@@ -13339,9 +13339,11 @@ static int i40e_xdp_setup(struct i40e_vsi *vsi, struct bpf_prog *prog,
        old_prog = xchg(&vsi->xdp_prog, prog);
 
        if (need_reset) {
-               if (!prog)
+               if (!prog) {
+                       xdp_features_clear_redirect_target(vsi->netdev);
                        /* Wait until ndo_xsk_wakeup completes. */
                        synchronize_rcu();
+               }
                i40e_reset_and_rebuild(pf, true, true);
        }
 
@@ -13362,11 +13364,13 @@ static int i40e_xdp_setup(struct i40e_vsi *vsi, struct bpf_prog *prog,
        /* Kick start the NAPI context if there is an AF_XDP socket open
         * on that queue id. This so that receiving will start.
         */
-       if (need_reset && prog)
+       if (need_reset && prog) {
                for (i = 0; i < vsi->num_queue_pairs; i++)
                        if (vsi->xdp_rings[i]->xsk_pool)
                                (void)i40e_xsk_wakeup(vsi->netdev, i,
                                                      XDP_WAKEUP_RX);
+               xdp_features_set_redirect_target(vsi->netdev, true);
+       }
 
        return 0;
 }
@@ -13783,6 +13787,8 @@ static int i40e_config_netdev(struct i40e_vsi *vsi)
        netdev->hw_enc_features |= NETIF_F_TSO_MANGLEID;
 
        netdev->features &= ~NETIF_F_HW_TC;
+       netdev->xdp_features = NETDEV_XDP_ACT_BASIC | NETDEV_XDP_ACT_REDIRECT |
+                              NETDEV_XDP_ACT_XSK_ZEROCOPY;
 
        if (vsi->type == I40E_VSI_MAIN) {
                SET_NETDEV_DEV(netdev, &pf->pdev->dev);
index 26a8910a41ff5f35b4154ec3330915c32e7c7283..074b0e6d0e2d1003264bed2fc1269153af9fff4b 100644 (file)
@@ -22,6 +22,7 @@
 #include "ice_eswitch.h"
 #include "ice_tc_lib.h"
 #include "ice_vsi_vlan_ops.h"
+#include <net/xdp_sock_drv.h>
 
 #define DRV_SUMMARY    "Intel(R) Ethernet Connection E800 Series Linux Driver"
 static const char ice_driver_string[] = DRV_SUMMARY;
@@ -2912,11 +2913,13 @@ ice_xdp_setup_prog(struct ice_vsi *vsi, struct bpf_prog *prog,
                        if (xdp_ring_err)
                                NL_SET_ERR_MSG_MOD(extack, "Setting up XDP Tx resources failed");
                }
+               xdp_features_set_redirect_target(vsi->netdev, false);
                /* reallocate Rx queues that are used for zero-copy */
                xdp_ring_err = ice_realloc_zc_buf(vsi, true);
                if (xdp_ring_err)
                        NL_SET_ERR_MSG_MOD(extack, "Setting up XDP Rx resources failed");
        } else if (ice_is_xdp_ena_vsi(vsi) && !prog) {
+               xdp_features_clear_redirect_target(vsi->netdev);
                xdp_ring_err = ice_destroy_xdp_rings(vsi);
                if (xdp_ring_err)
                        NL_SET_ERR_MSG_MOD(extack, "Freeing XDP Tx resources failed");
@@ -3459,6 +3462,8 @@ static int ice_cfg_netdev(struct ice_vsi *vsi)
        np->vsi = vsi;
 
        ice_set_netdev_features(netdev);
+       netdev->xdp_features = NETDEV_XDP_ACT_BASIC | NETDEV_XDP_ACT_REDIRECT |
+                              NETDEV_XDP_ACT_XSK_ZEROCOPY;
 
        ice_set_ops(netdev);
 
index 3c0c35ecea10c716dc7146adee8fcbc358530f1a..0e11a082f7a1b903744306300f0b72eb13f6b213 100644 (file)
@@ -2871,8 +2871,14 @@ static int igb_xdp_setup(struct net_device *dev, struct netdev_bpf *bpf)
                bpf_prog_put(old_prog);
 
        /* bpf is just replaced, RXQ and MTU are already setup */
-       if (!need_reset)
+       if (!need_reset) {
                return 0;
+       } else {
+               if (prog)
+                       xdp_features_set_redirect_target(dev, true);
+               else
+                       xdp_features_clear_redirect_target(dev);
+       }
 
        if (running)
                igb_open(dev);
@@ -3317,6 +3323,7 @@ static int igb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        netdev->priv_flags |= IFF_SUPP_NOFCS;
 
        netdev->priv_flags |= IFF_UNICAST_FLT;
+       netdev->xdp_features = NETDEV_XDP_ACT_BASIC | NETDEV_XDP_ACT_REDIRECT;
 
        /* MTU range: 68 - 9216 */
        netdev->min_mtu = ETH_MIN_MTU;
index e86b15efaeb895f98c1f365a73b80299a0b97434..8b572cd2c350b638a43a39a88e8ef57f17a91c0f 100644 (file)
@@ -6533,6 +6533,9 @@ static int igc_probe(struct pci_dev *pdev,
        netdev->mpls_features |= NETIF_F_HW_CSUM;
        netdev->hw_enc_features |= netdev->vlan_features;
 
+       netdev->xdp_features = NETDEV_XDP_ACT_BASIC | NETDEV_XDP_ACT_REDIRECT |
+                              NETDEV_XDP_ACT_XSK_ZEROCOPY;
+
        /* MTU range: 68 - 9216 */
        netdev->min_mtu = ETH_MIN_MTU;
        netdev->max_mtu = MAX_STD_JUMBO_FRAME_SIZE;
index aeeb34e64610d205cb6d7cd99ac2bf973a2b68c4..e27af72aada8b61cb0ab11dbb44988f53b71626d 100644 (file)
@@ -29,6 +29,11 @@ int igc_xdp_set_prog(struct igc_adapter *adapter, struct bpf_prog *prog,
        if (old_prog)
                bpf_prog_put(old_prog);
 
+       if (prog)
+               xdp_features_set_redirect_target(dev, true);
+       else
+               xdp_features_clear_redirect_target(dev);
+
        if (if_running)
                igc_open(dev);
 
index 43a44c1e1576825cec5d62414233714598a69d7e..af4c12b6059f79ed4a4fb2fa1ce21db902714e21 100644 (file)
@@ -10301,6 +10301,8 @@ static int ixgbe_xdp_setup(struct net_device *dev, struct bpf_prog *prog)
 
                if (err)
                        return -EINVAL;
+               if (!prog)
+                       xdp_features_clear_redirect_target(dev);
        } else {
                for (i = 0; i < adapter->num_rx_queues; i++) {
                        WRITE_ONCE(adapter->rx_ring[i]->xdp_prog,
@@ -10321,6 +10323,7 @@ static int ixgbe_xdp_setup(struct net_device *dev, struct bpf_prog *prog)
                        if (adapter->xdp_ring[i]->xsk_pool)
                                (void)ixgbe_xsk_wakeup(adapter->netdev, i,
                                                       XDP_WAKEUP_RX);
+               xdp_features_set_redirect_target(dev, true);
        }
 
        return 0;
@@ -11018,6 +11021,9 @@ skip_sriov:
        netdev->priv_flags |= IFF_UNICAST_FLT;
        netdev->priv_flags |= IFF_SUPP_NOFCS;
 
+       netdev->xdp_features = NETDEV_XDP_ACT_BASIC | NETDEV_XDP_ACT_REDIRECT |
+                              NETDEV_XDP_ACT_XSK_ZEROCOPY;
+
        /* MTU range: 68 - 9710 */
        netdev->min_mtu = ETH_MIN_MTU;
        netdev->max_mtu = IXGBE_MAX_JUMBO_FRAME_SIZE - (ETH_HLEN + ETH_FCS_LEN);
index ea0a230c11530d0c89f9001b46aeaa1b561a0b2f..a44e4bd561421a5ee398f29464ec591af32c8857 100644 (file)
@@ -4634,6 +4634,7 @@ static int ixgbevf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
                            NETIF_F_HW_VLAN_CTAG_TX;
 
        netdev->priv_flags |= IFF_UNICAST_FLT;
+       netdev->xdp_features = NETDEV_XDP_ACT_BASIC;
 
        /* MTU range: 68 - 1504 or 9710 */
        netdev->min_mtu = ETH_MIN_MTU;
index f8925cac61e46f278eeedffb2a1bcf8eb6fa33e7..dc2989103a776a92260226ee00bc557620e9fe2f 100644 (file)
@@ -5612,6 +5612,9 @@ static int mvneta_probe(struct platform_device *pdev)
                        NETIF_F_TSO | NETIF_F_RXCSUM;
        dev->hw_features |= dev->features;
        dev->vlan_features |= dev->features;
+       dev->xdp_features = NETDEV_XDP_ACT_BASIC | NETDEV_XDP_ACT_REDIRECT |
+                           NETDEV_XDP_ACT_NDO_XMIT | NETDEV_XDP_ACT_RX_SG |
+                           NETDEV_XDP_ACT_NDO_XMIT_SG;
        dev->priv_flags |= IFF_LIVE_ADDR_CHANGE;
        netif_set_tso_max_segs(dev, MVNETA_MAX_TSO_SEGS);
 
index 4da45c5abba5933b1acabef3da07231524854a69..9b4ecbe4f36d41b3855b70243de9e4a4994b0ea7 100644 (file)
@@ -6866,6 +6866,10 @@ static int mvpp2_port_probe(struct platform_device *pdev,
 
        dev->vlan_features |= features;
        netif_set_tso_max_segs(dev, MVPP2_MAX_TSO_SEGS);
+
+       dev->xdp_features = NETDEV_XDP_ACT_BASIC | NETDEV_XDP_ACT_REDIRECT |
+                           NETDEV_XDP_ACT_NDO_XMIT;
+
        dev->priv_flags |= IFF_UNICAST_FLT;
 
        /* MTU range: 68 - 9704 */
index c1ea60bc2630e4d018527609f26e95c3c1c61c06..179433d0a54a61c8e72401960f92e1659fe6eb77 100644 (file)
@@ -2512,10 +2512,13 @@ static int otx2_xdp_setup(struct otx2_nic *pf, struct bpf_prog *prog)
        /* Network stack and XDP shared same rx queues.
         * Use separate tx queues for XDP and network stack.
         */
-       if (pf->xdp_prog)
+       if (pf->xdp_prog) {
                pf->hw.xdp_queues = pf->hw.rx_queues;
-       else
+               xdp_features_set_redirect_target(dev, false);
+       } else {
                pf->hw.xdp_queues = 0;
+               xdp_features_clear_redirect_target(dev);
+       }
 
        pf->hw.tot_tx_queues += pf->hw.xdp_queues;
 
@@ -2878,6 +2881,7 @@ static int otx2_probe(struct pci_dev *pdev, const struct pci_device_id *id)
        netdev->watchdog_timeo = OTX2_TX_TIMEOUT;
 
        netdev->netdev_ops = &otx2_netdev_ops;
+       netdev->xdp_features = NETDEV_XDP_ACT_BASIC | NETDEV_XDP_ACT_REDIRECT;
 
        netdev->min_mtu = OTX2_MIN_MTU;
        netdev->max_mtu = otx2_get_max_mtu(pf);
index 801deac58bf71e3ff7623c2cd80c80645c62628f..ac54b6f2bb5c2848e3f2973b234bd1097ce71ee4 100644 (file)
@@ -4447,6 +4447,12 @@ static int mtk_add_mac(struct mtk_eth *eth, struct device_node *np)
                register_netdevice_notifier(&mac->device_notifier);
        }
 
+       if (mtk_page_pool_enabled(eth))
+               eth->netdev[id]->xdp_features = NETDEV_XDP_ACT_BASIC |
+                                               NETDEV_XDP_ACT_REDIRECT |
+                                               NETDEV_XDP_ACT_NDO_XMIT |
+                                               NETDEV_XDP_ACT_NDO_XMIT_SG;
+
        return 0;
 
 free_netdev:
index af4c4858f397c08b23ceb810ccc768c7d549c3aa..e11bc0ac880e6370e0f3d0fcd680304badd7c54c 100644 (file)
@@ -3416,6 +3416,8 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
                priv->rss_hash_fn = ETH_RSS_HASH_TOP;
        }
 
+       dev->xdp_features = NETDEV_XDP_ACT_BASIC | NETDEV_XDP_ACT_REDIRECT;
+
        /* MTU range: 68 - hw-specific max */
        dev->min_mtu = ETH_MIN_MTU;
        dev->max_mtu = priv->max_mtu;
index 0e87432ec6f1c36ea57ab6946809bba63fd43321..e4996ef04d8691f96e8363afcbba96c345f8369f 100644 (file)
@@ -4780,6 +4780,13 @@ static int mlx5e_xdp_set(struct net_device *netdev, struct bpf_prog *prog)
        if (old_prog)
                bpf_prog_put(old_prog);
 
+       if (reset) {
+               if (prog)
+                       xdp_features_set_redirect_target(netdev, true);
+               else
+                       xdp_features_clear_redirect_target(netdev);
+       }
+
        if (!test_bit(MLX5E_STATE_OPENED, &priv->state) || reset)
                goto unlock;
 
@@ -5175,6 +5182,10 @@ static void mlx5e_build_nic_netdev(struct net_device *netdev)
        netdev->features         |= NETIF_F_HIGHDMA;
        netdev->features         |= NETIF_F_HW_VLAN_STAG_FILTER;
 
+       netdev->xdp_features = NETDEV_XDP_ACT_BASIC | NETDEV_XDP_ACT_REDIRECT |
+                              NETDEV_XDP_ACT_XSK_ZEROCOPY |
+                              NETDEV_XDP_ACT_RX_SG;
+
        netdev->priv_flags       |= IFF_UNICAST_FLT;
 
        netif_set_tso_max_size(netdev, GSO_MAX_SIZE);
index 2f6a048dee9056f99d6fecc6ff03d486bbc440a4..6120f2b6684fb15a94ff371319dcc4067523e1ce 100644 (file)
@@ -2160,6 +2160,8 @@ static int mana_probe_port(struct mana_context *ac, int port_idx,
        ndev->hw_features |= NETIF_F_RXHASH;
        ndev->features = ndev->hw_features;
        ndev->vlan_features = 0;
+       ndev->xdp_features = NETDEV_XDP_ACT_BASIC | NETDEV_XDP_ACT_REDIRECT |
+                            NETDEV_XDP_ACT_NDO_XMIT;
 
        err = register_netdev(ndev);
        if (err) {
index 18fc9971f1c8f268c9ec754fe530b697a39ffb0b..e4825d88556007fea25fd7f29a378d99d8b1d8b8 100644 (file)
@@ -2529,10 +2529,15 @@ static void nfp_net_netdev_init(struct nfp_net *nn)
        netdev->features &= ~NETIF_F_HW_VLAN_STAG_RX;
        nn->dp.ctrl &= ~NFP_NET_CFG_CTRL_RXQINQ;
 
+       netdev->xdp_features = NETDEV_XDP_ACT_BASIC;
+       if (nn->app && nn->app->type->id == NFP_APP_BPF_NIC)
+               netdev->xdp_features |= NETDEV_XDP_ACT_HW_OFFLOAD;
+
        /* Finalise the netdev setup */
        switch (nn->dp.ops->version) {
        case NFP_NFD_VER_NFD3:
                netdev->netdev_ops = &nfp_nfd3_netdev_ops;
+               netdev->xdp_features |= NETDEV_XDP_ACT_XSK_ZEROCOPY;
                break;
        case NFP_NFD_VER_NFDK:
                netdev->netdev_ops = &nfp_nfdk_netdev_ops;
index 953f304b8588c58c35eda919b385621ee2951ba1..b6d999927e8635b36761f1a3be7e2f0ee145eefb 100644 (file)
@@ -892,6 +892,9 @@ static void qede_init_ndev(struct qede_dev *edev)
 
        ndev->hw_features = hw_features;
 
+       ndev->xdp_features = NETDEV_XDP_ACT_BASIC | NETDEV_XDP_ACT_REDIRECT |
+                            NETDEV_XDP_ACT_NDO_XMIT;
+
        /* MTU range: 46 - 9600 */
        ndev->min_mtu = ETH_ZLEN - ETH_HLEN;
        ndev->max_mtu = QEDE_MAX_JUMBO_PACKET_SIZE;
index 0556542d7a6b6446e0d38c8fcd09123b1cd9f23e..18ff8d8cff429ba1d285d8156b5fd72f1576fc68 100644 (file)
@@ -1078,6 +1078,10 @@ static int efx_pci_probe(struct pci_dev *pci_dev,
 
        pci_info(pci_dev, "Solarflare NIC detected\n");
 
+       efx->net_dev->xdp_features = NETDEV_XDP_ACT_BASIC |
+                                    NETDEV_XDP_ACT_REDIRECT |
+                                    NETDEV_XDP_ACT_NDO_XMIT;
+
        if (!efx->type->is_vf)
                efx_probe_vpd_strings(efx);
 
index 60e5b7c8ccf95ded5558bd7d6c90d40b04353a70..a6ef21845224a920d13c41eea43494e4d4ea3531 100644 (file)
@@ -1048,6 +1048,10 @@ static int efx_pci_probe(struct pci_dev *pci_dev,
 
        pci_info(pci_dev, "Solarflare NIC detected\n");
 
+       efx->net_dev->xdp_features = NETDEV_XDP_ACT_BASIC |
+                                    NETDEV_XDP_ACT_REDIRECT |
+                                    NETDEV_XDP_ACT_NDO_XMIT;
+
        if (!efx->type->is_vf)
                efx_probe_vpd_strings(efx);
 
index 9b46579b5a1038b1facfeca0814b6b18e28d241b..2d7347b71c41b238fc5b905f13157f3a521be53c 100644 (file)
@@ -2104,6 +2104,9 @@ static int netsec_probe(struct platform_device *pdev)
                                NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
        ndev->hw_features = ndev->features;
 
+       ndev->xdp_features = NETDEV_XDP_ACT_BASIC | NETDEV_XDP_ACT_REDIRECT |
+                            NETDEV_XDP_ACT_NDO_XMIT;
+
        priv->rx_cksum_offload_flag = true;
 
        ret = netsec_register_mdio(priv, phy_addr);
index b7e5af58ab750e67ebd51ca15a8dff0f20ee6efa..734d84263fd2e0d2738a0ceedf532ad5e1b38b57 100644 (file)
@@ -7150,6 +7150,8 @@ int stmmac_dvr_probe(struct device *device,
 
        ndev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
                            NETIF_F_RXCSUM;
+       ndev->xdp_features = NETDEV_XDP_ACT_BASIC | NETDEV_XDP_ACT_REDIRECT |
+                            NETDEV_XDP_ACT_NDO_XMIT;
 
        ret = stmmac_tc_init(priv, priv);
        if (!ret) {
index 13c9c2d6b79bbada479af66db547a71464ecb325..37f0b62ec5d6a3bc99914fcee1681d9e3ff1bfdb 100644 (file)
@@ -1458,6 +1458,8 @@ static int cpsw_probe_dual_emac(struct cpsw_priv *priv)
        priv_sl2->emac_port = 1;
        cpsw->slaves[1].ndev = ndev;
        ndev->features |= NETIF_F_HW_VLAN_CTAG_FILTER | NETIF_F_HW_VLAN_CTAG_RX;
+       ndev->xdp_features = NETDEV_XDP_ACT_BASIC | NETDEV_XDP_ACT_REDIRECT |
+                            NETDEV_XDP_ACT_NDO_XMIT;
 
        ndev->netdev_ops = &cpsw_netdev_ops;
        ndev->ethtool_ops = &cpsw_ethtool_ops;
@@ -1635,6 +1637,8 @@ static int cpsw_probe(struct platform_device *pdev)
        cpsw->slaves[0].ndev = ndev;
 
        ndev->features |= NETIF_F_HW_VLAN_CTAG_FILTER | NETIF_F_HW_VLAN_CTAG_RX;
+       ndev->xdp_features = NETDEV_XDP_ACT_BASIC | NETDEV_XDP_ACT_REDIRECT |
+                            NETDEV_XDP_ACT_NDO_XMIT;
 
        ndev->netdev_ops = &cpsw_netdev_ops;
        ndev->ethtool_ops = &cpsw_ethtool_ops;
index 83596ec0c7cb9b0527ebff58f43928b36dbcc01f..35128dd45ffceb27a6dafea19a2c9d342feb95c1 100644 (file)
@@ -1405,6 +1405,10 @@ static int cpsw_create_ports(struct cpsw_common *cpsw)
                ndev->features |= NETIF_F_HW_VLAN_CTAG_FILTER |
                                  NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_NETNS_LOCAL | NETIF_F_HW_TC;
 
+               ndev->xdp_features = NETDEV_XDP_ACT_BASIC |
+                                    NETDEV_XDP_ACT_REDIRECT |
+                                    NETDEV_XDP_ACT_NDO_XMIT;
+
                ndev->netdev_ops = &cpsw_netdev_ops;
                ndev->ethtool_ops = &cpsw_ethtool_ops;
                SET_NETDEV_DEV(ndev, dev);
index f9b219e6cd58b69a175294d01ac41f4ab7e03404..a9b139bbdb2cb9910745108e31d59c1661f4f712 100644 (file)
@@ -2559,6 +2559,8 @@ static int netvsc_probe(struct hv_device *dev,
 
        netdev_lockdep_set_classes(net);
 
+       net->xdp_features = NETDEV_XDP_ACT_BASIC | NETDEV_XDP_ACT_REDIRECT;
+
        /* MTU range: 68 - 1500 or 65521 */
        net->min_mtu = NETVSC_MTU_MIN;
        if (nvdev->nvsp_version >= NVSP_PROTOCOL_VERSION_2)
index 6db6a75ff9b9b0f741badca9a45783feef67df8d..35fa1ca986715aec21be2b2d9ccdfb1c51ab7543 100644 (file)
@@ -286,6 +286,7 @@ static void nsim_setup(struct net_device *dev)
                         NETIF_F_TSO;
        dev->hw_features |= NETIF_F_HW_TC;
        dev->max_mtu = ETH_MAX_MTU;
+       dev->xdp_features = NETDEV_XDP_ACT_HW_OFFLOAD;
 }
 
 static int nsim_init_netdevsim(struct netdevsim *ns)
index a7d17c680f4a013d1efa7f452faee5e18d9ed07c..36620afde3732eb43e1d95ff08f83f34538177ae 100644 (file)
@@ -1401,6 +1401,11 @@ static void tun_net_initialize(struct net_device *dev)
 
                eth_hw_addr_random(dev);
 
+               /* Currently tun does not support XDP, only tap does. */
+               dev->xdp_features = NETDEV_XDP_ACT_BASIC |
+                                   NETDEV_XDP_ACT_REDIRECT |
+                                   NETDEV_XDP_ACT_NDO_XMIT;
+
                break;
        }
 
index ba3e05832843f3b186b0e9295d5fa4774def1afe..1bb54de7124d95e4974c158017ac6611a370c4d8 100644 (file)
@@ -1686,6 +1686,10 @@ static void veth_setup(struct net_device *dev)
        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);
+
+       dev->xdp_features = NETDEV_XDP_ACT_BASIC | NETDEV_XDP_ACT_REDIRECT |
+                           NETDEV_XDP_ACT_NDO_XMIT | NETDEV_XDP_ACT_RX_SG |
+                           NETDEV_XDP_ACT_NDO_XMIT_SG;
 }
 
 /*
index 7e1a984301900773f6ac8925b295724cabd7483f..692dff071782d8717042c53de0414a802ef3328d 100644 (file)
@@ -3280,7 +3280,10 @@ static int virtnet_xdp_set(struct net_device *dev, struct bpf_prog *prog,
                        if (i == 0 && !old_prog)
                                virtnet_clear_guest_offloads(vi);
                }
+               if (!old_prog)
+                       xdp_features_set_redirect_target(dev, false);
        } else {
+               xdp_features_clear_redirect_target(dev);
                vi->xdp_enabled = false;
        }
 
@@ -3910,6 +3913,7 @@ static int virtnet_probe(struct virtio_device *vdev)
                dev->hw_features |= NETIF_F_GRO_HW;
 
        dev->vlan_features = dev->features;
+       dev->xdp_features = NETDEV_XDP_ACT_BASIC | NETDEV_XDP_ACT_REDIRECT;
 
        /* MTU range: 68 - 65535 */
        dev->min_mtu = MIN_MTU;
index 12b074286df9daf8b83aa84cb62a2039d5d48019..47d54d8ea59d17a94a9fa08d50d06eee45743bfe 100644 (file)
@@ -1741,6 +1741,8 @@ static struct net_device *xennet_create_dev(struct xenbus_device *dev)
          * negotiate with the backend regarding supported features.
          */
        netdev->features |= netdev->hw_features;
+       netdev->xdp_features = NETDEV_XDP_ACT_BASIC | NETDEV_XDP_ACT_REDIRECT |
+                              NETDEV_XDP_ACT_NDO_XMIT;
 
        netdev->ethtool_ops = &xennet_ethtool_ops;
        netdev->min_mtu = ETH_MIN_MTU;
index 8d1c86914f4c94394d3fd51a3aa3342e4b8635d5..d517bfac937b0a2bda248f594750fbb0c9a082ab 100644 (file)
@@ -428,9 +428,21 @@ MAX_XDP_METADATA_KFUNC,
 #ifdef CONFIG_NET
 u32 bpf_xdp_metadata_kfunc_id(int id);
 bool bpf_dev_bound_kfunc_id(u32 btf_id);
+void xdp_features_set_redirect_target(struct net_device *dev, bool support_sg);
+void xdp_features_clear_redirect_target(struct net_device *dev);
 #else
 static inline u32 bpf_xdp_metadata_kfunc_id(int id) { return 0; }
 static inline bool bpf_dev_bound_kfunc_id(u32 btf_id) { return false; }
+
+static inline void
+xdp_features_set_redirect_target(struct net_device *dev, bool support_sg)
+{
+}
+
+static inline void
+xdp_features_clear_redirect_target(struct net_device *dev)
+{
+}
 #endif
 
 #endif /* __LINUX_NET_XDP_H__ */
index 787fb9f92b36fa2b3ac3267e24c116b4411eb366..26483935b7a40e9261f1fd8455f5bf777f559dbe 100644 (file)
@@ -774,3 +774,21 @@ static int __init xdp_metadata_init(void)
        return register_btf_kfunc_id_set(BPF_PROG_TYPE_XDP, &xdp_metadata_kfunc_set);
 }
 late_initcall(xdp_metadata_init);
+
+void xdp_features_set_redirect_target(struct net_device *dev, bool support_sg)
+{
+       dev->xdp_features |= NETDEV_XDP_ACT_NDO_XMIT;
+       if (support_sg)
+               dev->xdp_features |= NETDEV_XDP_ACT_NDO_XMIT_SG;
+
+       call_netdevice_notifiers(NETDEV_XDP_FEAT_CHANGE, dev);
+}
+EXPORT_SYMBOL_GPL(xdp_features_set_redirect_target);
+
+void xdp_features_clear_redirect_target(struct net_device *dev)
+{
+       dev->xdp_features &= ~(NETDEV_XDP_ACT_NDO_XMIT |
+                              NETDEV_XDP_ACT_NDO_XMIT_SG);
+       call_netdevice_notifiers(NETDEV_XDP_FEAT_CHANGE, dev);
+}
+EXPORT_SYMBOL_GPL(xdp_features_clear_redirect_target);