Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /* Copyright (c) 2021, Intel Corporation. */
0003 
0004 #include <net/xdp_sock_drv.h>
0005 
0006 #include "stmmac.h"
0007 #include "stmmac_xdp.h"
0008 
0009 static int stmmac_xdp_enable_pool(struct stmmac_priv *priv,
0010                   struct xsk_buff_pool *pool, u16 queue)
0011 {
0012     struct stmmac_channel *ch = &priv->channel[queue];
0013     bool need_update;
0014     u32 frame_size;
0015     int err;
0016 
0017     if (queue >= priv->plat->rx_queues_to_use ||
0018         queue >= priv->plat->tx_queues_to_use)
0019         return -EINVAL;
0020 
0021     frame_size = xsk_pool_get_rx_frame_size(pool);
0022     /* XDP ZC does not span multiple frame, make sure XSK pool buffer
0023      * size can at least store Q-in-Q frame.
0024      */
0025     if (frame_size < ETH_FRAME_LEN + VLAN_HLEN * 2)
0026         return -EOPNOTSUPP;
0027 
0028     err = xsk_pool_dma_map(pool, priv->device, STMMAC_RX_DMA_ATTR);
0029     if (err) {
0030         netdev_err(priv->dev, "Failed to map xsk pool\n");
0031         return err;
0032     }
0033 
0034     need_update = netif_running(priv->dev) && stmmac_xdp_is_enabled(priv);
0035 
0036     if (need_update) {
0037         napi_disable(&ch->rx_napi);
0038         napi_disable(&ch->tx_napi);
0039         stmmac_disable_rx_queue(priv, queue);
0040         stmmac_disable_tx_queue(priv, queue);
0041     }
0042 
0043     set_bit(queue, priv->af_xdp_zc_qps);
0044 
0045     if (need_update) {
0046         stmmac_enable_rx_queue(priv, queue);
0047         stmmac_enable_tx_queue(priv, queue);
0048         napi_enable(&ch->rxtx_napi);
0049 
0050         err = stmmac_xsk_wakeup(priv->dev, queue, XDP_WAKEUP_RX);
0051         if (err)
0052             return err;
0053     }
0054 
0055     return 0;
0056 }
0057 
0058 static int stmmac_xdp_disable_pool(struct stmmac_priv *priv, u16 queue)
0059 {
0060     struct stmmac_channel *ch = &priv->channel[queue];
0061     struct xsk_buff_pool *pool;
0062     bool need_update;
0063 
0064     if (queue >= priv->plat->rx_queues_to_use ||
0065         queue >= priv->plat->tx_queues_to_use)
0066         return -EINVAL;
0067 
0068     pool = xsk_get_pool_from_qid(priv->dev, queue);
0069     if (!pool)
0070         return -EINVAL;
0071 
0072     need_update = netif_running(priv->dev) && stmmac_xdp_is_enabled(priv);
0073 
0074     if (need_update) {
0075         napi_disable(&ch->rxtx_napi);
0076         stmmac_disable_rx_queue(priv, queue);
0077         stmmac_disable_tx_queue(priv, queue);
0078         synchronize_rcu();
0079     }
0080 
0081     xsk_pool_dma_unmap(pool, STMMAC_RX_DMA_ATTR);
0082 
0083     clear_bit(queue, priv->af_xdp_zc_qps);
0084 
0085     if (need_update) {
0086         stmmac_enable_rx_queue(priv, queue);
0087         stmmac_enable_tx_queue(priv, queue);
0088         napi_enable(&ch->rx_napi);
0089         napi_enable(&ch->tx_napi);
0090     }
0091 
0092     return 0;
0093 }
0094 
0095 int stmmac_xdp_setup_pool(struct stmmac_priv *priv, struct xsk_buff_pool *pool,
0096               u16 queue)
0097 {
0098     return pool ? stmmac_xdp_enable_pool(priv, pool, queue) :
0099               stmmac_xdp_disable_pool(priv, queue);
0100 }
0101 
0102 int stmmac_xdp_set_prog(struct stmmac_priv *priv, struct bpf_prog *prog,
0103             struct netlink_ext_ack *extack)
0104 {
0105     struct net_device *dev = priv->dev;
0106     struct bpf_prog *old_prog;
0107     bool need_update;
0108     bool if_running;
0109 
0110     if_running = netif_running(dev);
0111 
0112     if (prog && dev->mtu > ETH_DATA_LEN) {
0113         /* For now, the driver doesn't support XDP functionality with
0114          * jumbo frames so we return error.
0115          */
0116         NL_SET_ERR_MSG_MOD(extack, "Jumbo frames not supported");
0117         return -EOPNOTSUPP;
0118     }
0119 
0120     need_update = !!priv->xdp_prog != !!prog;
0121     if (if_running && need_update)
0122         stmmac_xdp_release(dev);
0123 
0124     old_prog = xchg(&priv->xdp_prog, prog);
0125     if (old_prog)
0126         bpf_prog_put(old_prog);
0127 
0128     /* Disable RX SPH for XDP operation */
0129     priv->sph = priv->sph_cap && !stmmac_xdp_is_enabled(priv);
0130 
0131     if (if_running && need_update)
0132         stmmac_xdp_open(dev);
0133 
0134     return 0;
0135 }