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 <almasrymina@google.com>
6170aafe3SMina Almasry * Willem de Bruijn <willemb@google.com>
7170aafe3SMina Almasry * Kaiyuan Zhang <kaiyuanz@google.com>
8170aafe3SMina Almasry *
9170aafe3SMina Almasry */
10170aafe3SMina Almasry #ifndef _NET_DEVMEM_H
11170aafe3SMina Almasry #define _NET_DEVMEM_H
12170aafe3SMina Almasry
13170aafe3SMina Almasry struct netlink_ext_ack;
14170aafe3SMina Almasry
15170aafe3SMina Almasry struct net_devmem_dmabuf_binding {
16170aafe3SMina Almasry struct dma_buf *dmabuf;
17170aafe3SMina Almasry struct dma_buf_attachment *attachment;
18170aafe3SMina Almasry struct sg_table *sgt;
19170aafe3SMina Almasry struct net_device *dev;
20170aafe3SMina Almasry struct gen_pool *chunk_pool;
21170aafe3SMina Almasry
22170aafe3SMina Almasry /* The user holds a ref (via the netlink API) for as long as they want
23170aafe3SMina Almasry * the binding to remain alive. Each page pool using this binding holds
24170aafe3SMina Almasry * a ref to keep the binding alive. Each allocated net_iov holds a
25170aafe3SMina Almasry * ref.
26170aafe3SMina Almasry *
27170aafe3SMina Almasry * The binding undos itself and unmaps the underlying dmabuf once all
28170aafe3SMina Almasry * those refs are dropped and the binding is no longer desired or in
29170aafe3SMina Almasry * use.
30170aafe3SMina Almasry */
31170aafe3SMina Almasry refcount_t ref;
32170aafe3SMina Almasry
33170aafe3SMina Almasry /* The list of bindings currently active. Used for netlink to notify us
34170aafe3SMina Almasry * of the user dropping the bind.
35170aafe3SMina Almasry */
36170aafe3SMina Almasry struct list_head list;
37170aafe3SMina Almasry
38170aafe3SMina Almasry /* rxq's this binding is active on. */
39170aafe3SMina Almasry struct xarray bound_rxqs;
40170aafe3SMina Almasry
41170aafe3SMina Almasry /* ID of this binding. Globally unique to all bindings currently
42170aafe3SMina Almasry * active.
43170aafe3SMina Almasry */
44170aafe3SMina Almasry u32 id;
45170aafe3SMina Almasry };
46170aafe3SMina Almasry
47170aafe3SMina Almasry #if defined(CONFIG_NET_DEVMEM)
48170aafe3SMina Almasry /* Owner of the dma-buf chunks inserted into the gen pool. Each scatterlist
49170aafe3SMina Almasry * entry from the dmabuf is inserted into the genpool as a chunk, and needs
50170aafe3SMina Almasry * this owner struct to keep track of some metadata necessary to create
51170aafe3SMina Almasry * allocations from this chunk.
52170aafe3SMina Almasry */
53170aafe3SMina Almasry struct dmabuf_genpool_chunk_owner {
54170aafe3SMina Almasry /* Offset into the dma-buf where this chunk starts. */
55170aafe3SMina Almasry unsigned long base_virtual;
56170aafe3SMina Almasry
57170aafe3SMina Almasry /* dma_addr of the start of the chunk. */
58170aafe3SMina Almasry dma_addr_t base_dma_addr;
59170aafe3SMina Almasry
60170aafe3SMina Almasry /* Array of net_iovs for this chunk. */
61170aafe3SMina Almasry struct net_iov *niovs;
62170aafe3SMina Almasry size_t num_niovs;
63170aafe3SMina Almasry
64170aafe3SMina Almasry struct net_devmem_dmabuf_binding *binding;
65170aafe3SMina Almasry };
66170aafe3SMina Almasry
67170aafe3SMina Almasry void __net_devmem_dmabuf_binding_free(struct net_devmem_dmabuf_binding *binding);
68170aafe3SMina Almasry struct net_devmem_dmabuf_binding *
69170aafe3SMina Almasry net_devmem_bind_dmabuf(struct net_device *dev, unsigned int dmabuf_fd,
70170aafe3SMina Almasry struct netlink_ext_ack *extack);
71170aafe3SMina Almasry void net_devmem_unbind_dmabuf(struct net_devmem_dmabuf_binding *binding);
72170aafe3SMina Almasry int net_devmem_bind_dmabuf_to_queue(struct net_device *dev, u32 rxq_idx,
73170aafe3SMina Almasry struct net_devmem_dmabuf_binding *binding,
74170aafe3SMina Almasry struct netlink_ext_ack *extack);
75170aafe3SMina Almasry void dev_dmabuf_uninstall(struct net_device *dev);
76170aafe3SMina Almasry
7728c5c74eSMina Almasry static inline struct dmabuf_genpool_chunk_owner *
net_iov_owner(const struct net_iov * niov)7828c5c74eSMina Almasry net_iov_owner(const struct net_iov *niov)
7928c5c74eSMina Almasry {
8028c5c74eSMina Almasry return niov->owner;
8128c5c74eSMina Almasry }
8228c5c74eSMina Almasry
net_iov_idx(const struct net_iov * niov)8328c5c74eSMina Almasry static inline unsigned int net_iov_idx(const struct net_iov *niov)
8428c5c74eSMina Almasry {
8528c5c74eSMina Almasry return niov - net_iov_owner(niov)->niovs;
8628c5c74eSMina Almasry }
8728c5c74eSMina Almasry
8828c5c74eSMina Almasry static inline struct net_devmem_dmabuf_binding *
net_iov_binding(const struct net_iov * niov)8928c5c74eSMina Almasry net_iov_binding(const struct net_iov *niov)
9028c5c74eSMina Almasry {
9128c5c74eSMina Almasry return net_iov_owner(niov)->binding;
9228c5c74eSMina Almasry }
9328c5c74eSMina Almasry
net_iov_virtual_addr(const struct net_iov * niov)94*8f0b3cc9SMina Almasry static inline unsigned long net_iov_virtual_addr(const struct net_iov *niov)
95*8f0b3cc9SMina Almasry {
96*8f0b3cc9SMina Almasry struct dmabuf_genpool_chunk_owner *owner = net_iov_owner(niov);
97*8f0b3cc9SMina Almasry
98*8f0b3cc9SMina Almasry return owner->base_virtual +
99*8f0b3cc9SMina Almasry ((unsigned long)net_iov_idx(niov) << PAGE_SHIFT);
100*8f0b3cc9SMina Almasry }
101*8f0b3cc9SMina Almasry
net_iov_binding_id(const struct net_iov * niov)102*8f0b3cc9SMina Almasry static inline u32 net_iov_binding_id(const struct net_iov *niov)
103*8f0b3cc9SMina Almasry {
104*8f0b3cc9SMina Almasry return net_iov_owner(niov)->binding->id;
105*8f0b3cc9SMina Almasry }
106*8f0b3cc9SMina Almasry
107170aafe3SMina Almasry static inline void
net_devmem_dmabuf_binding_get(struct net_devmem_dmabuf_binding * binding)108170aafe3SMina Almasry net_devmem_dmabuf_binding_get(struct net_devmem_dmabuf_binding *binding)
109170aafe3SMina Almasry {
110170aafe3SMina Almasry refcount_inc(&binding->ref);
111170aafe3SMina Almasry }
112170aafe3SMina Almasry
113170aafe3SMina Almasry static inline void
net_devmem_dmabuf_binding_put(struct net_devmem_dmabuf_binding * binding)114170aafe3SMina Almasry net_devmem_dmabuf_binding_put(struct net_devmem_dmabuf_binding *binding)
115170aafe3SMina Almasry {
116170aafe3SMina Almasry if (!refcount_dec_and_test(&binding->ref))
117170aafe3SMina Almasry return;
118170aafe3SMina Almasry
119170aafe3SMina Almasry __net_devmem_dmabuf_binding_free(binding);
120170aafe3SMina Almasry }
121170aafe3SMina Almasry
12228c5c74eSMina Almasry struct net_iov *
12328c5c74eSMina Almasry net_devmem_alloc_dmabuf(struct net_devmem_dmabuf_binding *binding);
12428c5c74eSMina Almasry void net_devmem_free_dmabuf(struct net_iov *ppiov);
12528c5c74eSMina Almasry
126170aafe3SMina Almasry #else
12728c5c74eSMina Almasry struct net_devmem_dmabuf_binding;
12828c5c74eSMina Almasry
129170aafe3SMina Almasry static inline void
__net_devmem_dmabuf_binding_free(struct net_devmem_dmabuf_binding * binding)130170aafe3SMina Almasry __net_devmem_dmabuf_binding_free(struct net_devmem_dmabuf_binding *binding)
131170aafe3SMina Almasry {
132170aafe3SMina Almasry }
133170aafe3SMina Almasry
134170aafe3SMina 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)135170aafe3SMina Almasry net_devmem_bind_dmabuf(struct net_device *dev, unsigned int dmabuf_fd,
136170aafe3SMina Almasry struct netlink_ext_ack *extack)
137170aafe3SMina Almasry {
138170aafe3SMina Almasry return ERR_PTR(-EOPNOTSUPP);
139170aafe3SMina Almasry }
140170aafe3SMina Almasry
141170aafe3SMina Almasry static inline void
net_devmem_unbind_dmabuf(struct net_devmem_dmabuf_binding * binding)142170aafe3SMina Almasry net_devmem_unbind_dmabuf(struct net_devmem_dmabuf_binding *binding)
143170aafe3SMina Almasry {
144170aafe3SMina Almasry }
145170aafe3SMina Almasry
146170aafe3SMina 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)147170aafe3SMina Almasry net_devmem_bind_dmabuf_to_queue(struct net_device *dev, u32 rxq_idx,
148170aafe3SMina Almasry struct net_devmem_dmabuf_binding *binding,
149170aafe3SMina Almasry struct netlink_ext_ack *extack)
150170aafe3SMina Almasry
151170aafe3SMina Almasry {
152170aafe3SMina Almasry return -EOPNOTSUPP;
153170aafe3SMina Almasry }
154170aafe3SMina Almasry
dev_dmabuf_uninstall(struct net_device * dev)155170aafe3SMina Almasry static inline void dev_dmabuf_uninstall(struct net_device *dev)
156170aafe3SMina Almasry {
157170aafe3SMina Almasry }
15828c5c74eSMina Almasry
15928c5c74eSMina Almasry static inline struct net_iov *
net_devmem_alloc_dmabuf(struct net_devmem_dmabuf_binding * binding)16028c5c74eSMina Almasry net_devmem_alloc_dmabuf(struct net_devmem_dmabuf_binding *binding)
16128c5c74eSMina Almasry {
16228c5c74eSMina Almasry return NULL;
16328c5c74eSMina Almasry }
16428c5c74eSMina Almasry
net_devmem_free_dmabuf(struct net_iov * ppiov)16528c5c74eSMina Almasry static inline void net_devmem_free_dmabuf(struct net_iov *ppiov)
16628c5c74eSMina Almasry {
16728c5c74eSMina Almasry }
16828c5c74eSMina Almasry
net_iov_virtual_addr(const struct net_iov * niov)169*8f0b3cc9SMina Almasry static inline unsigned long net_iov_virtual_addr(const struct net_iov *niov)
170*8f0b3cc9SMina Almasry {
171*8f0b3cc9SMina Almasry return 0;
172*8f0b3cc9SMina Almasry }
173*8f0b3cc9SMina Almasry
net_iov_binding_id(const struct net_iov * niov)174*8f0b3cc9SMina Almasry static inline u32 net_iov_binding_id(const struct net_iov *niov)
175*8f0b3cc9SMina Almasry {
176*8f0b3cc9SMina Almasry return 0;
177*8f0b3cc9SMina Almasry }
178170aafe3SMina Almasry #endif
179170aafe3SMina Almasry
180170aafe3SMina Almasry #endif /* _NET_DEVMEM_H */
181