1170aafe3SMina Almasry /* SPDX-License-Identifier: GPL-2.0-or-later */
2170aafe3SMina Almasry /*
3170aafe3SMina Almasry * Device memory TCP support
4170aafe3SMina Almasry *
5170aafe3SMina Almasry * Authors: Mina Almasry <[email protected]>
6170aafe3SMina Almasry * Willem de Bruijn <[email protected]>
7170aafe3SMina Almasry * Kaiyuan Zhang <[email protected]>
8170aafe3SMina Almasry *
9170aafe3SMina Almasry */
10170aafe3SMina Almasry #ifndef _NET_DEVMEM_H
11170aafe3SMina Almasry #define _NET_DEVMEM_H
12170aafe3SMina Almasry
137d60fa9eSPavel Begunkov #include <net/netmem.h>
147d60fa9eSPavel Begunkov
15170aafe3SMina Almasry struct netlink_ext_ack;
16170aafe3SMina Almasry
17170aafe3SMina Almasry struct net_devmem_dmabuf_binding {
18170aafe3SMina Almasry struct dma_buf *dmabuf;
19170aafe3SMina Almasry struct dma_buf_attachment *attachment;
20170aafe3SMina Almasry struct sg_table *sgt;
21170aafe3SMina Almasry struct net_device *dev;
22170aafe3SMina Almasry struct gen_pool *chunk_pool;
23*0afc44d8STaehee Yoo /* Protect dev */
24*0afc44d8STaehee Yoo struct mutex lock;
25170aafe3SMina Almasry
26170aafe3SMina Almasry /* The user holds a ref (via the netlink API) for as long as they want
27170aafe3SMina Almasry * the binding to remain alive. Each page pool using this binding holds
28170aafe3SMina Almasry * a ref to keep the binding alive. Each allocated net_iov holds a
29170aafe3SMina Almasry * ref.
30170aafe3SMina Almasry *
31170aafe3SMina Almasry * The binding undos itself and unmaps the underlying dmabuf once all
32170aafe3SMina Almasry * those refs are dropped and the binding is no longer desired or in
33170aafe3SMina Almasry * use.
34170aafe3SMina Almasry */
35170aafe3SMina Almasry refcount_t ref;
36170aafe3SMina Almasry
37170aafe3SMina Almasry /* The list of bindings currently active. Used for netlink to notify us
38170aafe3SMina Almasry * of the user dropping the bind.
39170aafe3SMina Almasry */
40170aafe3SMina Almasry struct list_head list;
41170aafe3SMina Almasry
42170aafe3SMina Almasry /* rxq's this binding is active on. */
43170aafe3SMina Almasry struct xarray bound_rxqs;
44170aafe3SMina Almasry
45170aafe3SMina Almasry /* ID of this binding. Globally unique to all bindings currently
46170aafe3SMina Almasry * active.
47170aafe3SMina Almasry */
48170aafe3SMina Almasry u32 id;
49170aafe3SMina Almasry };
50170aafe3SMina Almasry
51170aafe3SMina Almasry #if defined(CONFIG_NET_DEVMEM)
52170aafe3SMina Almasry /* Owner of the dma-buf chunks inserted into the gen pool. Each scatterlist
53170aafe3SMina Almasry * entry from the dmabuf is inserted into the genpool as a chunk, and needs
54170aafe3SMina Almasry * this owner struct to keep track of some metadata necessary to create
55170aafe3SMina Almasry * allocations from this chunk.
56170aafe3SMina Almasry */
57170aafe3SMina Almasry struct dmabuf_genpool_chunk_owner {
587d60fa9eSPavel Begunkov struct net_iov_area area;
597d60fa9eSPavel Begunkov struct net_devmem_dmabuf_binding *binding;
60170aafe3SMina Almasry
61170aafe3SMina Almasry /* dma_addr of the start of the chunk. */
62170aafe3SMina Almasry dma_addr_t base_dma_addr;
63170aafe3SMina Almasry };
64170aafe3SMina Almasry
65170aafe3SMina Almasry void __net_devmem_dmabuf_binding_free(struct net_devmem_dmabuf_binding *binding);
66170aafe3SMina Almasry struct net_devmem_dmabuf_binding *
67170aafe3SMina Almasry net_devmem_bind_dmabuf(struct net_device *dev, unsigned int dmabuf_fd,
68170aafe3SMina Almasry struct netlink_ext_ack *extack);
69170aafe3SMina Almasry void net_devmem_unbind_dmabuf(struct net_devmem_dmabuf_binding *binding);
70170aafe3SMina Almasry int net_devmem_bind_dmabuf_to_queue(struct net_device *dev, u32 rxq_idx,
71170aafe3SMina Almasry struct net_devmem_dmabuf_binding *binding,
72170aafe3SMina Almasry struct netlink_ext_ack *extack);
73170aafe3SMina Almasry
7428c5c74eSMina Almasry static inline struct dmabuf_genpool_chunk_owner *
net_devmem_iov_to_chunk_owner(const struct net_iov * niov)757d60fa9eSPavel Begunkov net_devmem_iov_to_chunk_owner(const struct net_iov *niov)
7628c5c74eSMina Almasry {
777d60fa9eSPavel Begunkov struct net_iov_area *owner = net_iov_owner(niov);
7828c5c74eSMina Almasry
797d60fa9eSPavel Begunkov return container_of(owner, struct dmabuf_genpool_chunk_owner, area);
8028c5c74eSMina Almasry }
8128c5c74eSMina Almasry
8228c5c74eSMina Almasry static inline struct net_devmem_dmabuf_binding *
net_devmem_iov_binding(const struct net_iov * niov)83297d389eSPavel Begunkov net_devmem_iov_binding(const struct net_iov *niov)
8428c5c74eSMina Almasry {
857d60fa9eSPavel Begunkov return net_devmem_iov_to_chunk_owner(niov)->binding;
8628c5c74eSMina Almasry }
8728c5c74eSMina Almasry
net_devmem_iov_binding_id(const struct net_iov * niov)88297d389eSPavel Begunkov static inline u32 net_devmem_iov_binding_id(const struct net_iov *niov)
89297d389eSPavel Begunkov {
90297d389eSPavel Begunkov return net_devmem_iov_binding(niov)->id;
91297d389eSPavel Begunkov }
92297d389eSPavel Begunkov
net_iov_virtual_addr(const struct net_iov * niov)938f0b3cc9SMina Almasry static inline unsigned long net_iov_virtual_addr(const struct net_iov *niov)
948f0b3cc9SMina Almasry {
957d60fa9eSPavel Begunkov struct net_iov_area *owner = net_iov_owner(niov);
968f0b3cc9SMina Almasry
978f0b3cc9SMina Almasry return owner->base_virtual +
988f0b3cc9SMina Almasry ((unsigned long)net_iov_idx(niov) << PAGE_SHIFT);
998f0b3cc9SMina Almasry }
1008f0b3cc9SMina Almasry
101170aafe3SMina Almasry static inline void
net_devmem_dmabuf_binding_get(struct net_devmem_dmabuf_binding * binding)102170aafe3SMina Almasry net_devmem_dmabuf_binding_get(struct net_devmem_dmabuf_binding *binding)
103170aafe3SMina Almasry {
104170aafe3SMina Almasry refcount_inc(&binding->ref);
105170aafe3SMina Almasry }
106170aafe3SMina Almasry
107170aafe3SMina Almasry static inline void
net_devmem_dmabuf_binding_put(struct net_devmem_dmabuf_binding * binding)108170aafe3SMina Almasry net_devmem_dmabuf_binding_put(struct net_devmem_dmabuf_binding *binding)
109170aafe3SMina Almasry {
110170aafe3SMina Almasry if (!refcount_dec_and_test(&binding->ref))
111170aafe3SMina Almasry return;
112170aafe3SMina Almasry
113170aafe3SMina Almasry __net_devmem_dmabuf_binding_free(binding);
114170aafe3SMina Almasry }
115170aafe3SMina Almasry
11628c5c74eSMina Almasry struct net_iov *
11728c5c74eSMina Almasry net_devmem_alloc_dmabuf(struct net_devmem_dmabuf_binding *binding);
11828c5c74eSMina Almasry void net_devmem_free_dmabuf(struct net_iov *ppiov);
11928c5c74eSMina Almasry
12069e39537SPavel Begunkov bool net_is_devmem_iov(struct net_iov *niov);
12169e39537SPavel Begunkov
122170aafe3SMina Almasry #else
12328c5c74eSMina Almasry struct net_devmem_dmabuf_binding;
12428c5c74eSMina Almasry
125170aafe3SMina Almasry static inline void
__net_devmem_dmabuf_binding_free(struct net_devmem_dmabuf_binding * binding)126170aafe3SMina Almasry __net_devmem_dmabuf_binding_free(struct net_devmem_dmabuf_binding *binding)
127170aafe3SMina Almasry {
128170aafe3SMina Almasry }
129170aafe3SMina Almasry
130170aafe3SMina Almasry static inline struct net_devmem_dmabuf_binding *
net_devmem_bind_dmabuf(struct net_device * dev,unsigned int dmabuf_fd,struct netlink_ext_ack * extack)131170aafe3SMina Almasry net_devmem_bind_dmabuf(struct net_device *dev, unsigned int dmabuf_fd,
132170aafe3SMina Almasry struct netlink_ext_ack *extack)
133170aafe3SMina Almasry {
134170aafe3SMina Almasry return ERR_PTR(-EOPNOTSUPP);
135170aafe3SMina Almasry }
136170aafe3SMina Almasry
137170aafe3SMina Almasry static inline void
net_devmem_unbind_dmabuf(struct net_devmem_dmabuf_binding * binding)138170aafe3SMina Almasry net_devmem_unbind_dmabuf(struct net_devmem_dmabuf_binding *binding)
139170aafe3SMina Almasry {
140170aafe3SMina Almasry }
141170aafe3SMina Almasry
142170aafe3SMina Almasry static inline int
net_devmem_bind_dmabuf_to_queue(struct net_device * dev,u32 rxq_idx,struct net_devmem_dmabuf_binding * binding,struct netlink_ext_ack * extack)143170aafe3SMina Almasry net_devmem_bind_dmabuf_to_queue(struct net_device *dev, u32 rxq_idx,
144170aafe3SMina Almasry struct net_devmem_dmabuf_binding *binding,
145170aafe3SMina Almasry struct netlink_ext_ack *extack)
146170aafe3SMina Almasry
147170aafe3SMina Almasry {
148170aafe3SMina Almasry return -EOPNOTSUPP;
149170aafe3SMina Almasry }
150170aafe3SMina Almasry
15128c5c74eSMina Almasry static inline struct net_iov *
net_devmem_alloc_dmabuf(struct net_devmem_dmabuf_binding * binding)15228c5c74eSMina Almasry net_devmem_alloc_dmabuf(struct net_devmem_dmabuf_binding *binding)
15328c5c74eSMina Almasry {
15428c5c74eSMina Almasry return NULL;
15528c5c74eSMina Almasry }
15628c5c74eSMina Almasry
net_devmem_free_dmabuf(struct net_iov * ppiov)15728c5c74eSMina Almasry static inline void net_devmem_free_dmabuf(struct net_iov *ppiov)
15828c5c74eSMina Almasry {
15928c5c74eSMina Almasry }
16028c5c74eSMina Almasry
net_iov_virtual_addr(const struct net_iov * niov)1618f0b3cc9SMina Almasry static inline unsigned long net_iov_virtual_addr(const struct net_iov *niov)
1628f0b3cc9SMina Almasry {
1638f0b3cc9SMina Almasry return 0;
1648f0b3cc9SMina Almasry }
1658f0b3cc9SMina Almasry
net_devmem_iov_binding_id(const struct net_iov * niov)166297d389eSPavel Begunkov static inline u32 net_devmem_iov_binding_id(const struct net_iov *niov)
1678f0b3cc9SMina Almasry {
1688f0b3cc9SMina Almasry return 0;
1698f0b3cc9SMina Almasry }
17069e39537SPavel Begunkov
net_is_devmem_iov(struct net_iov * niov)17169e39537SPavel Begunkov static inline bool net_is_devmem_iov(struct net_iov *niov)
17269e39537SPavel Begunkov {
17369e39537SPavel Begunkov return false;
17469e39537SPavel Begunkov }
175170aafe3SMina Almasry #endif
176170aafe3SMina Almasry
177170aafe3SMina Almasry #endif /* _NET_DEVMEM_H */
178