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 * 7828c5c74eSMina Almasry net_iov_owner(const struct net_iov *niov) 7928c5c74eSMina Almasry { 8028c5c74eSMina Almasry return niov->owner; 8128c5c74eSMina Almasry } 8228c5c74eSMina Almasry 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 * 8928c5c74eSMina Almasry net_iov_binding(const struct net_iov *niov) 9028c5c74eSMina Almasry { 9128c5c74eSMina Almasry return net_iov_owner(niov)->binding; 9228c5c74eSMina Almasry } 9328c5c74eSMina Almasry 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 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 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 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 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 * 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 142170aafe3SMina Almasry net_devmem_unbind_dmabuf(struct net_devmem_dmabuf_binding *binding) 143170aafe3SMina Almasry { 144170aafe3SMina Almasry } 145170aafe3SMina Almasry 146170aafe3SMina Almasry static inline int 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 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 * 16028c5c74eSMina Almasry net_devmem_alloc_dmabuf(struct net_devmem_dmabuf_binding *binding) 16128c5c74eSMina Almasry { 16228c5c74eSMina Almasry return NULL; 16328c5c74eSMina Almasry } 16428c5c74eSMina Almasry 16528c5c74eSMina Almasry static inline void net_devmem_free_dmabuf(struct net_iov *ppiov) 16628c5c74eSMina Almasry { 16728c5c74eSMina Almasry } 16828c5c74eSMina Almasry 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 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