stmmac_xdp.c (3267B)
1// SPDX-License-Identifier: GPL-2.0 2/* Copyright (c) 2021, Intel Corporation. */ 3 4#include <net/xdp_sock_drv.h> 5 6#include "stmmac.h" 7#include "stmmac_xdp.h" 8 9static int stmmac_xdp_enable_pool(struct stmmac_priv *priv, 10 struct xsk_buff_pool *pool, u16 queue) 11{ 12 struct stmmac_channel *ch = &priv->channel[queue]; 13 bool need_update; 14 u32 frame_size; 15 int err; 16 17 if (queue >= priv->plat->rx_queues_to_use || 18 queue >= priv->plat->tx_queues_to_use) 19 return -EINVAL; 20 21 frame_size = xsk_pool_get_rx_frame_size(pool); 22 /* XDP ZC does not span multiple frame, make sure XSK pool buffer 23 * size can at least store Q-in-Q frame. 24 */ 25 if (frame_size < ETH_FRAME_LEN + VLAN_HLEN * 2) 26 return -EOPNOTSUPP; 27 28 err = xsk_pool_dma_map(pool, priv->device, STMMAC_RX_DMA_ATTR); 29 if (err) { 30 netdev_err(priv->dev, "Failed to map xsk pool\n"); 31 return err; 32 } 33 34 need_update = netif_running(priv->dev) && stmmac_xdp_is_enabled(priv); 35 36 if (need_update) { 37 napi_disable(&ch->rx_napi); 38 napi_disable(&ch->tx_napi); 39 stmmac_disable_rx_queue(priv, queue); 40 stmmac_disable_tx_queue(priv, queue); 41 } 42 43 set_bit(queue, priv->af_xdp_zc_qps); 44 45 if (need_update) { 46 stmmac_enable_rx_queue(priv, queue); 47 stmmac_enable_tx_queue(priv, queue); 48 napi_enable(&ch->rxtx_napi); 49 50 err = stmmac_xsk_wakeup(priv->dev, queue, XDP_WAKEUP_RX); 51 if (err) 52 return err; 53 } 54 55 return 0; 56} 57 58static int stmmac_xdp_disable_pool(struct stmmac_priv *priv, u16 queue) 59{ 60 struct stmmac_channel *ch = &priv->channel[queue]; 61 struct xsk_buff_pool *pool; 62 bool need_update; 63 64 if (queue >= priv->plat->rx_queues_to_use || 65 queue >= priv->plat->tx_queues_to_use) 66 return -EINVAL; 67 68 pool = xsk_get_pool_from_qid(priv->dev, queue); 69 if (!pool) 70 return -EINVAL; 71 72 need_update = netif_running(priv->dev) && stmmac_xdp_is_enabled(priv); 73 74 if (need_update) { 75 napi_disable(&ch->rxtx_napi); 76 stmmac_disable_rx_queue(priv, queue); 77 stmmac_disable_tx_queue(priv, queue); 78 synchronize_rcu(); 79 } 80 81 xsk_pool_dma_unmap(pool, STMMAC_RX_DMA_ATTR); 82 83 clear_bit(queue, priv->af_xdp_zc_qps); 84 85 if (need_update) { 86 stmmac_enable_rx_queue(priv, queue); 87 stmmac_enable_tx_queue(priv, queue); 88 napi_enable(&ch->rx_napi); 89 napi_enable(&ch->tx_napi); 90 } 91 92 return 0; 93} 94 95int stmmac_xdp_setup_pool(struct stmmac_priv *priv, struct xsk_buff_pool *pool, 96 u16 queue) 97{ 98 return pool ? stmmac_xdp_enable_pool(priv, pool, queue) : 99 stmmac_xdp_disable_pool(priv, queue); 100} 101 102int stmmac_xdp_set_prog(struct stmmac_priv *priv, struct bpf_prog *prog, 103 struct netlink_ext_ack *extack) 104{ 105 struct net_device *dev = priv->dev; 106 struct bpf_prog *old_prog; 107 bool need_update; 108 bool if_running; 109 110 if_running = netif_running(dev); 111 112 if (prog && dev->mtu > ETH_DATA_LEN) { 113 /* For now, the driver doesn't support XDP functionality with 114 * jumbo frames so we return error. 115 */ 116 NL_SET_ERR_MSG_MOD(extack, "Jumbo frames not supported"); 117 return -EOPNOTSUPP; 118 } 119 120 need_update = !!priv->xdp_prog != !!prog; 121 if (if_running && need_update) 122 stmmac_xdp_release(dev); 123 124 old_prog = xchg(&priv->xdp_prog, prog); 125 if (old_prog) 126 bpf_prog_put(old_prog); 127 128 /* Disable RX SPH for XDP operation */ 129 priv->sph = priv->sph_cap && !stmmac_xdp_is_enabled(priv); 130 131 if (if_running && need_update) 132 stmmac_xdp_open(dev); 133 134 return 0; 135}