xref: /linux/net/core/devmem.h (revision 28c5c74eeaa0a2aad8b9cd9ede22a4c623f2a7fc)
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 
77*28c5c74eSMina Almasry static inline struct dmabuf_genpool_chunk_owner *
78*28c5c74eSMina Almasry net_iov_owner(const struct net_iov *niov)
79*28c5c74eSMina Almasry {
80*28c5c74eSMina Almasry 	return niov->owner;
81*28c5c74eSMina Almasry }
82*28c5c74eSMina Almasry 
83*28c5c74eSMina Almasry static inline unsigned int net_iov_idx(const struct net_iov *niov)
84*28c5c74eSMina Almasry {
85*28c5c74eSMina Almasry 	return niov - net_iov_owner(niov)->niovs;
86*28c5c74eSMina Almasry }
87*28c5c74eSMina Almasry 
88*28c5c74eSMina Almasry static inline struct net_devmem_dmabuf_binding *
89*28c5c74eSMina Almasry net_iov_binding(const struct net_iov *niov)
90*28c5c74eSMina Almasry {
91*28c5c74eSMina Almasry 	return net_iov_owner(niov)->binding;
92*28c5c74eSMina Almasry }
93*28c5c74eSMina Almasry 
94170aafe3SMina Almasry static inline void
95170aafe3SMina Almasry net_devmem_dmabuf_binding_get(struct net_devmem_dmabuf_binding *binding)
96170aafe3SMina Almasry {
97170aafe3SMina Almasry 	refcount_inc(&binding->ref);
98170aafe3SMina Almasry }
99170aafe3SMina Almasry 
100170aafe3SMina Almasry static inline void
101170aafe3SMina Almasry net_devmem_dmabuf_binding_put(struct net_devmem_dmabuf_binding *binding)
102170aafe3SMina Almasry {
103170aafe3SMina Almasry 	if (!refcount_dec_and_test(&binding->ref))
104170aafe3SMina Almasry 		return;
105170aafe3SMina Almasry 
106170aafe3SMina Almasry 	__net_devmem_dmabuf_binding_free(binding);
107170aafe3SMina Almasry }
108170aafe3SMina Almasry 
109*28c5c74eSMina Almasry struct net_iov *
110*28c5c74eSMina Almasry net_devmem_alloc_dmabuf(struct net_devmem_dmabuf_binding *binding);
111*28c5c74eSMina Almasry void net_devmem_free_dmabuf(struct net_iov *ppiov);
112*28c5c74eSMina Almasry 
113170aafe3SMina Almasry #else
114*28c5c74eSMina Almasry struct net_devmem_dmabuf_binding;
115*28c5c74eSMina Almasry 
116170aafe3SMina Almasry static inline void
117170aafe3SMina Almasry __net_devmem_dmabuf_binding_free(struct net_devmem_dmabuf_binding *binding)
118170aafe3SMina Almasry {
119170aafe3SMina Almasry }
120170aafe3SMina Almasry 
121170aafe3SMina Almasry static inline struct net_devmem_dmabuf_binding *
122170aafe3SMina Almasry net_devmem_bind_dmabuf(struct net_device *dev, unsigned int dmabuf_fd,
123170aafe3SMina Almasry 		       struct netlink_ext_ack *extack)
124170aafe3SMina Almasry {
125170aafe3SMina Almasry 	return ERR_PTR(-EOPNOTSUPP);
126170aafe3SMina Almasry }
127170aafe3SMina Almasry 
128170aafe3SMina Almasry static inline void
129170aafe3SMina Almasry net_devmem_unbind_dmabuf(struct net_devmem_dmabuf_binding *binding)
130170aafe3SMina Almasry {
131170aafe3SMina Almasry }
132170aafe3SMina Almasry 
133170aafe3SMina Almasry static inline int
134170aafe3SMina Almasry net_devmem_bind_dmabuf_to_queue(struct net_device *dev, u32 rxq_idx,
135170aafe3SMina Almasry 				struct net_devmem_dmabuf_binding *binding,
136170aafe3SMina Almasry 				struct netlink_ext_ack *extack)
137170aafe3SMina Almasry 
138170aafe3SMina Almasry {
139170aafe3SMina Almasry 	return -EOPNOTSUPP;
140170aafe3SMina Almasry }
141170aafe3SMina Almasry 
142170aafe3SMina Almasry static inline void dev_dmabuf_uninstall(struct net_device *dev)
143170aafe3SMina Almasry {
144170aafe3SMina Almasry }
145*28c5c74eSMina Almasry 
146*28c5c74eSMina Almasry static inline struct net_iov *
147*28c5c74eSMina Almasry net_devmem_alloc_dmabuf(struct net_devmem_dmabuf_binding *binding)
148*28c5c74eSMina Almasry {
149*28c5c74eSMina Almasry 	return NULL;
150*28c5c74eSMina Almasry }
151*28c5c74eSMina Almasry 
152*28c5c74eSMina Almasry static inline void net_devmem_free_dmabuf(struct net_iov *ppiov)
153*28c5c74eSMina Almasry {
154*28c5c74eSMina Almasry }
155*28c5c74eSMina Almasry 
156170aafe3SMina Almasry #endif
157170aafe3SMina Almasry 
158170aafe3SMina Almasry #endif /* _NET_DEVMEM_H */
159