]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/dev/xdma/xdma.h
Merge libc++ trunk r338150 (just before the 7.0.0 branch point), and
[FreeBSD/FreeBSD.git] / sys / dev / xdma / xdma.h
1 /*-
2  * Copyright (c) 2016-2018 Ruslan Bukin <br@bsdpad.com>
3  * All rights reserved.
4  *
5  * This software was developed by SRI International and the University of
6  * Cambridge Computer Laboratory under DARPA/AFRL contract FA8750-10-C-0237
7  * ("CTSRD"), as part of the DARPA CRASH research programme.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28  * SUCH DAMAGE.
29  *
30  * $FreeBSD$
31  */
32
33 #ifndef _DEV_XDMA_XDMA_H_
34 #define _DEV_XDMA_XDMA_H_
35
36 #include <sys/proc.h>
37
38 enum xdma_direction {
39         XDMA_MEM_TO_MEM,
40         XDMA_MEM_TO_DEV,
41         XDMA_DEV_TO_MEM,
42         XDMA_DEV_TO_DEV,
43 };
44
45 enum xdma_operation_type {
46         XDMA_MEMCPY,
47         XDMA_CYCLIC,
48         XDMA_FIFO,
49         XDMA_SG,
50 };
51
52 enum xdma_request_type {
53         XR_TYPE_PHYS,
54         XR_TYPE_VIRT,
55         XR_TYPE_MBUF,
56         XR_TYPE_BIO,
57 };
58
59 enum xdma_command {
60         XDMA_CMD_BEGIN,
61         XDMA_CMD_PAUSE,
62         XDMA_CMD_TERMINATE,
63 };
64
65 struct xdma_transfer_status {
66         uint32_t        transferred;
67         int             error;
68 };
69
70 typedef struct xdma_transfer_status xdma_transfer_status_t;
71
72 struct xdma_controller {
73         device_t dev;           /* DMA consumer device_t. */
74         device_t dma_dev;       /* A real DMA device_t. */
75         void *data;             /* OFW MD part. */
76
77         /* List of virtual channels allocated. */
78         TAILQ_HEAD(xdma_channel_list, xdma_channel)     channels;
79 };
80
81 typedef struct xdma_controller xdma_controller_t;
82
83 struct xchan_buf {
84         bus_dmamap_t                    map;
85         uint32_t                        nsegs;
86         uint32_t                        nsegs_left;
87         void                            *cbuf;
88 };
89
90 struct xdma_request {
91         struct mbuf                     *m;
92         struct bio                      *bp;
93         enum xdma_operation_type        operation;
94         enum xdma_request_type          req_type;
95         enum xdma_direction             direction;
96         bus_addr_t                      src_addr;
97         bus_addr_t                      dst_addr;
98         uint8_t                         src_width;
99         uint8_t                         dst_width;
100         bus_size_t                      block_num;
101         bus_size_t                      block_len;
102         xdma_transfer_status_t          status;
103         void                            *user;
104         TAILQ_ENTRY(xdma_request)       xr_next;
105         struct xchan_buf                buf;
106 };
107
108 struct xdma_sglist {
109         bus_addr_t                      src_addr;
110         bus_addr_t                      dst_addr;
111         size_t                          len;
112         uint8_t                         src_width;
113         uint8_t                         dst_width;
114         enum xdma_direction             direction;
115         bool                            first;
116         bool                            last;
117 };
118
119 struct xdma_channel {
120         xdma_controller_t               *xdma;
121
122         uint32_t                        flags;
123 #define XCHAN_BUFS_ALLOCATED            (1 << 0)
124 #define XCHAN_SGLIST_ALLOCATED          (1 << 1)
125 #define XCHAN_CONFIGURED                (1 << 2)
126 #define XCHAN_TYPE_CYCLIC               (1 << 3)
127 #define XCHAN_TYPE_MEMCPY               (1 << 4)
128 #define XCHAN_TYPE_FIFO                 (1 << 5)
129 #define XCHAN_TYPE_SG                   (1 << 6)
130
131         uint32_t                        caps;
132 #define XCHAN_CAP_BUSDMA                (1 << 0)
133 #define XCHAN_CAP_BUSDMA_NOSEG          (1 << 1)
134
135         /* A real hardware driver channel. */
136         void                            *chan;
137
138         /* Interrupt handlers. */
139         TAILQ_HEAD(, xdma_intr_handler) ie_handlers;
140         TAILQ_ENTRY(xdma_channel)       xchan_next;
141
142         struct sx                       sx_lock;
143         struct sx                       sx_qin_lock;
144         struct sx                       sx_qout_lock;
145         struct sx                       sx_bank_lock;
146         struct sx                       sx_proc_lock;
147
148         /* Request queue. */
149         bus_dma_tag_t                   dma_tag_bufs;
150         struct xdma_request             *xr_mem;
151         uint32_t                        xr_num;
152
153         /* Bus dma tag options. */
154         bus_size_t                      maxsegsize;
155         bus_size_t                      maxnsegs;
156         bus_size_t                      alignment;
157         bus_addr_t                      boundary;
158         bus_addr_t                      lowaddr;
159         bus_addr_t                      highaddr;
160
161         struct xdma_sglist              *sg;
162
163         TAILQ_HEAD(, xdma_request)      bank;
164         TAILQ_HEAD(, xdma_request)      queue_in;
165         TAILQ_HEAD(, xdma_request)      queue_out;
166         TAILQ_HEAD(, xdma_request)      processing;
167 };
168
169 typedef struct xdma_channel xdma_channel_t;
170
171 struct xdma_intr_handler {
172         int             (*cb)(void *cb_user, xdma_transfer_status_t *status);
173         void            *cb_user;
174         TAILQ_ENTRY(xdma_intr_handler)  ih_next;
175 };
176
177 static MALLOC_DEFINE(M_XDMA, "xdma", "xDMA framework");
178
179 #define XCHAN_LOCK(xchan)               sx_xlock(&(xchan)->sx_lock)
180 #define XCHAN_UNLOCK(xchan)             sx_xunlock(&(xchan)->sx_lock)
181 #define XCHAN_ASSERT_LOCKED(xchan)      \
182     sx_assert(&(xchan)->sx_lock, SX_XLOCKED)
183
184 #define QUEUE_IN_LOCK(xchan)            sx_xlock(&(xchan)->sx_qin_lock)
185 #define QUEUE_IN_UNLOCK(xchan)          sx_xunlock(&(xchan)->sx_qin_lock)
186 #define QUEUE_IN_ASSERT_LOCKED(xchan)   \
187     sx_assert(&(xchan)->sx_qin_lock, SX_XLOCKED)
188
189 #define QUEUE_OUT_LOCK(xchan)           sx_xlock(&(xchan)->sx_qout_lock)
190 #define QUEUE_OUT_UNLOCK(xchan)         sx_xunlock(&(xchan)->sx_qout_lock)
191 #define QUEUE_OUT_ASSERT_LOCKED(xchan)  \
192     sx_assert(&(xchan)->sx_qout_lock, SX_XLOCKED)
193
194 #define QUEUE_BANK_LOCK(xchan)          sx_xlock(&(xchan)->sx_bank_lock)
195 #define QUEUE_BANK_UNLOCK(xchan)        sx_xunlock(&(xchan)->sx_bank_lock)
196 #define QUEUE_BANK_ASSERT_LOCKED(xchan) \
197     sx_assert(&(xchan)->sx_bank_lock, SX_XLOCKED)
198
199 #define QUEUE_PROC_LOCK(xchan)          sx_xlock(&(xchan)->sx_proc_lock)
200 #define QUEUE_PROC_UNLOCK(xchan)        sx_xunlock(&(xchan)->sx_proc_lock)
201 #define QUEUE_PROC_ASSERT_LOCKED(xchan) \
202     sx_assert(&(xchan)->sx_proc_lock, SX_XLOCKED)
203
204 #define XDMA_SGLIST_MAXLEN      2048
205 #define XDMA_MAX_SEG            128
206
207 /* xDMA controller ops */
208 xdma_controller_t *xdma_ofw_get(device_t dev, const char *prop);
209 int xdma_put(xdma_controller_t *xdma);
210
211 /* xDMA channel ops */
212 xdma_channel_t * xdma_channel_alloc(xdma_controller_t *, uint32_t caps);
213 int xdma_channel_free(xdma_channel_t *);
214 int xdma_request(xdma_channel_t *xchan, struct xdma_request *r);
215
216 /* SG interface */
217 int xdma_prep_sg(xdma_channel_t *, uint32_t,
218     bus_size_t, bus_size_t, bus_size_t, bus_addr_t, bus_addr_t, bus_addr_t);
219 void xdma_channel_free_sg(xdma_channel_t *xchan);
220 int xdma_queue_submit_sg(xdma_channel_t *xchan);
221 void xchan_seg_done(xdma_channel_t *xchan, xdma_transfer_status_t *);
222
223 /* Queue operations */
224 int xdma_dequeue_mbuf(xdma_channel_t *xchan, struct mbuf **m,
225     xdma_transfer_status_t *);
226 int xdma_enqueue_mbuf(xdma_channel_t *xchan, struct mbuf **m, uintptr_t addr,
227     uint8_t, uint8_t, enum xdma_direction dir);
228 int xdma_dequeue_bio(xdma_channel_t *xchan, struct bio **bp,
229     xdma_transfer_status_t *status);
230 int xdma_enqueue_bio(xdma_channel_t *xchan, struct bio **bp, bus_addr_t addr,
231     uint8_t, uint8_t, enum xdma_direction dir);
232 int xdma_dequeue(xdma_channel_t *xchan, void **user,
233     xdma_transfer_status_t *status);
234 int xdma_enqueue(xdma_channel_t *xchan, uintptr_t src, uintptr_t dst,
235     uint8_t, uint8_t, bus_size_t, enum xdma_direction dir, void *);
236 int xdma_queue_submit(xdma_channel_t *xchan);
237
238 /* Mbuf operations */
239 uint32_t xdma_mbuf_defrag(xdma_channel_t *xchan, struct xdma_request *xr);
240 uint32_t xdma_mbuf_chain_count(struct mbuf *m0);
241
242 /* Channel Control */
243 int xdma_control(xdma_channel_t *xchan, enum xdma_command cmd);
244
245 /* Interrupt callback */
246 int xdma_setup_intr(xdma_channel_t *xchan, int (*cb)(void *,
247     xdma_transfer_status_t *), void *arg, void **);
248 int xdma_teardown_intr(xdma_channel_t *xchan, struct xdma_intr_handler *ih);
249 int xdma_teardown_all_intr(xdma_channel_t *xchan);
250 void xdma_callback(struct xdma_channel *xchan, xdma_transfer_status_t *status);
251
252 /* Sglist */
253 int xchan_sglist_alloc(xdma_channel_t *xchan);
254 void xchan_sglist_free(xdma_channel_t *xchan);
255 int xdma_sglist_add(struct xdma_sglist *sg, struct bus_dma_segment *seg,
256     uint32_t nsegs, struct xdma_request *xr);
257
258 /* Requests bank */
259 void xchan_bank_init(xdma_channel_t *xchan);
260 int xchan_bank_free(xdma_channel_t *xchan);
261 struct xdma_request * xchan_bank_get(xdma_channel_t *xchan);
262 int xchan_bank_put(xdma_channel_t *xchan, struct xdma_request *xr);
263
264 #endif /* !_DEV_XDMA_XDMA_H_ */