xref: /freebsd/sys/dev/dpaa2/dpaa2_buf.h (revision 3caa8d2c58b2787e4c4c64d9ac1831dadd7b0b47)
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause
3  *
4  * Copyright © 2023 Dmitry Salychev
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  * SUCH DAMAGE.
26  */
27 
28 #ifndef	_DPAA2_BUF_H
29 #define	_DPAA2_BUF_H
30 
31 #include <sys/types.h>
32 #include <sys/param.h>
33 #include <sys/malloc.h>
34 #include <sys/lock.h>
35 #include <sys/mutex.h>
36 #include <sys/systm.h>
37 #include <sys/mbuf.h>
38 
39 #include <machine/bus.h>
40 
41 #define DPAA2_RX_BUF_SIZE	(MJUM9BYTES)
42 
43 struct dpaa2_buf {
44 	bus_addr_t		 paddr;
45 	caddr_t			 vaddr;
46 	bus_dma_tag_t		 dmat;
47 	bus_dmamap_t		 dmap;
48 	bus_dma_segment_t	 seg;
49 	int			 nseg;
50 	struct mbuf		*m;
51 	struct dpaa2_buf	*sgt;
52 	void			*opt;
53 };
54 
55 struct dpaa2_bufext_rx {
56 	struct mtx		 dma_mtx;
57 	struct dpaa2_channel	*ch;
58 };
59 
60 #define DPAA2_BUF_INIT_TAGOPT(__buf, __tag, __opt) do {			\
61 	KASSERT((__buf) != NULL, ("%s: buf is NULL", __func__));	\
62 									\
63 	(__buf)->paddr = 0;						\
64 	(__buf)->vaddr = NULL;						\
65 	(__buf)->dmat = (__tag);					\
66 	(__buf)->dmap = NULL;						\
67 	(__buf)->seg.ds_addr = 0;					\
68 	(__buf)->seg.ds_len = 0;					\
69 	(__buf)->nseg = 0;						\
70 	(__buf)->m = NULL;						\
71 	(__buf)->sgt = NULL;						\
72 	(__buf)->opt = (__opt);						\
73 } while(0)
74 #define DPAA2_BUF_INIT(__buf)	DPAA2_BUF_INIT_TAGOPT((__buf), NULL, NULL)
75 
76 #if defined(INVARIANTS)
77 /*
78  * TXPREP/TXREADY macros allow to verify whether Tx buffer is prepared to be
79  * seeded and/or ready to be used for transmission.
80  *
81  * NOTE: Any modification should be carefully analyzed and justified.
82  */
83 #define DPAA2_BUF_ASSERT_TXPREP(__buf) do {				\
84 	struct dpaa2_buf *__sgt = (__buf)->sgt;				\
85 	KASSERT((__sgt) != NULL, ("%s: no S/G table?", __func__));	\
86 									\
87 	KASSERT((__buf)->paddr == 0,    ("%s: paddr set?", __func__));	\
88 	KASSERT((__buf)->vaddr == NULL, ("%s: vaddr set?", __func__));	\
89 	KASSERT((__buf)->dmat  != NULL, ("%s: no DMA tag?", __func__));	\
90 	KASSERT((__buf)->dmap  == NULL, ("%s: DMA map set?", __func__)); \
91 	KASSERT((__buf)->seg.ds_addr == 0, ("%s: already mapped?", __func__)); \
92 	KASSERT((__buf)->seg.ds_len  == 0, ("%s: already mapped?", __func__)); \
93 	KASSERT((__buf)->nseg  == 0,    ("%s: nseg > 0?", __func__));	\
94 	KASSERT((__buf)->m     == NULL, ("%s: mbuf set?", __func__));	\
95 	KASSERT((__buf)->opt   != NULL, ("%s: no Tx ring?", __func__));	\
96 									\
97 	KASSERT((__sgt)->paddr == 0,    ("%s: S/G paddr set?", __func__)); \
98 	KASSERT((__sgt)->vaddr == NULL, ("%s: S/G vaddr set?", __func__)); \
99 	KASSERT((__sgt)->dmat  != NULL, ("%s: no S/G DMA tag?", __func__)); \
100 	KASSERT((__sgt)->dmap  == NULL, ("%s: S/G DMA map set?", __func__)); \
101 	KASSERT((__sgt)->seg.ds_addr == 0, ("%s: S/G mapped?", __func__)); \
102 	KASSERT((__sgt)->seg.ds_len  == 0, ("%s: S/G mapped?", __func__)); \
103 	KASSERT((__sgt)->nseg  == 0,    ("%s: S/G nseg > 0?", __func__)); \
104 	KASSERT((__sgt)->m     == NULL, ("%s: S/G mbuf set?", __func__)); \
105 	KASSERT((__sgt)->opt == (__buf),("%s: buf not linked?", __func__)); \
106 } while(0)
107 #define DPAA2_BUF_ASSERT_TXREADY(__buf) do {				\
108 	struct dpaa2_buf *__sgt = (__buf)->sgt;				\
109 	KASSERT((__sgt) != NULL,        ("%s: no S/G table?", __func__)); \
110 									\
111 	KASSERT((__buf)->paddr == 0,    ("%s: paddr set?", __func__));	\
112 	KASSERT((__buf)->vaddr == NULL, ("%s: vaddr set?", __func__));	\
113 	KASSERT((__buf)->dmat  != NULL, ("%s: no DMA tag?", __func__));	\
114 	KASSERT((__buf)->dmap  != NULL, ("%s: no DMA map?", __func__)); \
115 	KASSERT((__buf)->seg.ds_addr == 0, ("%s: already mapped?", __func__)); \
116 	KASSERT((__buf)->seg.ds_len  == 0, ("%s: already mapped?", __func__)); \
117 	KASSERT((__buf)->nseg  == 0,    ("%s: nseg > 0?", __func__));	\
118 	KASSERT((__buf)->m     == NULL, ("%s: mbuf set?", __func__));	\
119 	KASSERT((__buf)->opt   != NULL, ("%s: no Tx ring?", __func__));	\
120 									\
121 	KASSERT((__sgt)->paddr == 0,    ("%s: S/G paddr set?", __func__)); \
122 	KASSERT((__sgt)->vaddr != NULL, ("%s: no S/G vaddr?", __func__)); \
123 	KASSERT((__sgt)->dmat  != NULL, ("%s: no S/G DMA tag?", __func__)); \
124 	KASSERT((__sgt)->dmap  != NULL, ("%s: no S/G DMA map?", __func__)); \
125 	KASSERT((__sgt)->seg.ds_addr == 0, ("%s: S/G mapped?", __func__)); \
126 	KASSERT((__sgt)->seg.ds_len  == 0, ("%s: S/G mapped?", __func__)); \
127 	KASSERT((__sgt)->nseg  == 0,    ("%s: S/G nseg > 0?", __func__)); \
128 	KASSERT((__sgt)->m     == NULL, ("%s: S/G mbuf set?", __func__)); \
129 	KASSERT((__sgt)->opt == (__buf),("%s: buf not linked?", __func__)); \
130 } while(0)
131 #else /* !INVARIANTS */
132 #define DPAA2_BUF_ASSERT_TXPREP(__buf) do {	\
133 } while(0)
134 #define DPAA2_BUF_ASSERT_TXREADY(__buf) do {	\
135 } while(0)
136 #endif /* INVARIANTS */
137 
138 #if defined(INVARIANTS)
139 /*
140  * RXPREP/RXREADY macros allow to verify whether Rx buffer is prepared to be
141  * seeded and/or ready to be used for reception.
142  *
143  * NOTE: Any modification should be carefully analyzed and justified.
144  */
145 #define DPAA2_BUF_ASSERT_RXPREP(__buf) do {				\
146 	KASSERT((__buf)->paddr == 0,    ("%s: paddr set?", __func__));	\
147 	KASSERT((__buf)->vaddr == NULL, ("%s: vaddr set?", __func__));	\
148 	KASSERT((__buf)->dmat  != NULL, ("%s: no DMA tag?", __func__));	\
149 	/* KASSERT((__buf)->dmap  == NULL, ("%s: DMA map set?", __func__)); */ \
150 	KASSERT((__buf)->seg.ds_addr == 0, ("%s: already mapped?", __func__)); \
151 	KASSERT((__buf)->seg.ds_len  == 0, ("%s: already mapped?", __func__)); \
152 	KASSERT((__buf)->nseg  == 0,    ("%s: nseg > 0?", __func__));	\
153 	KASSERT((__buf)->m     == NULL, ("%s: mbuf set?", __func__));	\
154 	KASSERT((__buf)->sgt   == NULL, ("%s: S/G table set?", __func__)); \
155 	KASSERT((__buf)->opt   != NULL, ("%s: no Rx ext?", __func__));	\
156 } while(0)
157 #define DPAA2_BUF_ASSERT_RXREADY(__buf) do {				\
158 	KASSERT((__buf)->paddr != 0,    ("%s: paddr not set?", __func__)); \
159 	KASSERT((__buf)->vaddr != NULL, ("%s: vaddr not set?", __func__)); \
160 	KASSERT((__buf)->dmat  != NULL, ("%s: no DMA tag?", __func__));	\
161 	KASSERT((__buf)->dmap  != NULL, ("%s: no DMA map?", __func__)); \
162 	KASSERT((__buf)->seg.ds_addr != 0, ("%s: not mapped?", __func__)); \
163 	KASSERT((__buf)->seg.ds_len  != 0, ("%s: not mapped?", __func__)); \
164 	KASSERT((__buf)->nseg  == 1,    ("%s: nseg != 1?", __func__));	\
165 	KASSERT((__buf)->m     != NULL, ("%s: no mbuf?", __func__));	\
166 	KASSERT((__buf)->sgt   == NULL, ("%s: S/G table set?", __func__)); \
167 	KASSERT((__buf)->opt   != NULL, ("%s: no Rx ext?", __func__));	\
168 } while(0)
169 #else /* !INVARIANTS */
170 #define DPAA2_BUF_ASSERT_RXPREP(__buf) do {	\
171 } while(0)
172 #define DPAA2_BUF_ASSERT_RXREADY(__buf) do {	\
173 } while(0)
174 #endif /* INVARIANTS */
175 
176 int dpaa2_buf_seed_pool(device_t, device_t, void *, uint32_t, int);
177 int dpaa2_buf_seed_rxb(device_t, struct dpaa2_buf *, int);
178 int dpaa2_buf_seed_txb(device_t, struct dpaa2_buf *);
179 
180 #endif /* _DPAA2_BUF_H */
181