1// SPDX-License-Identifier: GPL-2.0
2/* Copyright (C) 2022 Gerhard Engleder <gerhard@engleder-embedded.com> */
3
4#include <linux/if_vlan.h>
5#include <net/xdp_sock_drv.h>
6
7#include "tsnep.h"
8
9int tsnep_xdp_setup_prog(struct tsnep_adapter *adapter, struct bpf_prog *prog,
10 struct netlink_ext_ack *extack)
11{
12 struct bpf_prog *old_prog;
13
14 old_prog = xchg(&adapter->xdp_prog, prog);
15 if (old_prog)
16 bpf_prog_put(prog: old_prog);
17
18 return 0;
19}
20
21static int tsnep_xdp_enable_pool(struct tsnep_adapter *adapter,
22 struct xsk_buff_pool *pool, u16 queue_id)
23{
24 struct tsnep_queue *queue;
25 int retval;
26
27 if (queue_id >= adapter->num_rx_queues ||
28 queue_id >= adapter->num_tx_queues)
29 return -EINVAL;
30
31 queue = &adapter->queue[queue_id];
32 if (queue->rx->queue_index != queue_id ||
33 queue->tx->queue_index != queue_id) {
34 netdev_err(dev: adapter->netdev,
35 format: "XSK support only for TX/RX queue pairs\n");
36
37 return -EOPNOTSUPP;
38 }
39
40 retval = xsk_pool_dma_map(pool, dev: adapter->dmadev,
41 DMA_ATTR_SKIP_CPU_SYNC);
42 if (retval) {
43 netdev_err(dev: adapter->netdev, format: "failed to map XSK pool\n");
44
45 return retval;
46 }
47
48 retval = tsnep_enable_xsk(queue, pool);
49 if (retval) {
50 xsk_pool_dma_unmap(pool, DMA_ATTR_SKIP_CPU_SYNC);
51
52 return retval;
53 }
54
55 return 0;
56}
57
58static int tsnep_xdp_disable_pool(struct tsnep_adapter *adapter, u16 queue_id)
59{
60 struct xsk_buff_pool *pool;
61 struct tsnep_queue *queue;
62
63 if (queue_id >= adapter->num_rx_queues ||
64 queue_id >= adapter->num_tx_queues)
65 return -EINVAL;
66
67 pool = xsk_get_pool_from_qid(dev: adapter->netdev, queue_id);
68 if (!pool)
69 return -EINVAL;
70
71 queue = &adapter->queue[queue_id];
72
73 tsnep_disable_xsk(queue);
74
75 xsk_pool_dma_unmap(pool, DMA_ATTR_SKIP_CPU_SYNC);
76
77 return 0;
78}
79
80int tsnep_xdp_setup_pool(struct tsnep_adapter *adapter,
81 struct xsk_buff_pool *pool, u16 queue_id)
82{
83 return pool ? tsnep_xdp_enable_pool(adapter, pool, queue_id) :
84 tsnep_xdp_disable_pool(adapter, queue_id);
85}
86

source code of linux/drivers/net/ethernet/engleder/tsnep_xdp.c