xref: /freebsd/sys/dev/dpaa/dpaa_common.h (revision b4a465e566a1850e232b454efe99e05c1ea93f67)
1 /*
2  * Copyright (c) 2026 Justin Hibbits
3  *
4  * SPDX-License-Identifier: BSD-2-Clause
5  */
6 
7 #ifndef	DPAA_COMMON_H
8 #define	DPAA_COMMON_H
9 
10 #include <machine/atomic.h>
11 
12 int	dpaa_map_private_memory(device_t dev, int idx, const char *compat,
13     vm_paddr_t *addrp, size_t *sizep);
14 
15 struct dpaa_fd {
16 	uint64_t liodn:8;
17 	uint64_t bpid:8;
18 	uint64_t eliodn:4;
19 	uint64_t _rsvd1:4;
20 	uint64_t addr:40;
21 	uint32_t format:3;
22 	uint32_t offset:9;
23 	uint32_t length:20;
24 	uint32_t cmd_stat;
25 } __packed;
26 
27 #define	DPAA_FD_FORMAT_SHORT_SBSF	0
28 #define	DPAA_FD_FORMAT_COMPOUND		1
29 #define	DPAA_FD_FORMAT_LONG_SBSF	2
30 #define	DPAA_FD_FORMAT_SHORT_MBSF	4
31 #define	DPAA_FD_FORMAT_LONG_MBSF	6
32 
33 #define	DPAA_FD_RX_STATUS_DCL4C		0x10000000
34 #define	DPAA_FD_RX_STATUS_DME		0x01000000
35 #define	DPAA_FD_RX_STATUS_IPRE_M	0x00300000
36 #define	DPAA_FD_RX_STATUS_FPE		0x00080000
37 #define	DPAA_FD_RX_STATUS_FSE		0x00040000
38 #define	DPAA_FD_RX_STATUS_DIS		0x00020000
39 #define	DPAA_FD_RX_STATUS_EOF		0x00008000
40 #define	DPAA_FD_RX_STATUS_NSS		0x00004000
41 #define	DPAA_FD_RX_STATUS_KSO		0x00002000
42 #define	DPAA_FD_RX_STATUS_FCL_M		0x00000c00
43 #define	DPAA_FD_RX_STATUS_IPP		0x00000200
44 #define	DPAA_FD_RX_STATUS_FLM		0x00000100
45 #define	DPAA_FD_RX_STATUS_PTE		0x00000080
46 #define	DPAA_FD_RX_STATUS_ISP		0x00000040
47 #define	DPAA_FD_RX_STATUS_PHE		0x00000020
48 #define	DPAA_FD_RX_STATUS_FRDR		0x00000010
49 #define	DPAA_FD_RX_STATUS_BLE		0x00000008
50 #define	DPAA_FD_RX_STATUS_L4CV		0x00000004
51 #define	DPAA_FD_RX_STATUS_IPR		0x00000001
52 
53 #define	DPAA_FD_TX_CMD_RPD		0x40000000
54 #define	DPAA_FD_TX_CMD_DTC		0x10000000
55 #define	DPAA_FD_TX_STATUS_UFD		0x04000000
56 #define	DPAA_FD_TX_STATUS_LGE		0x02000000
57 #define	DPAA_FD_TX_STATUS_DME		0x01000000
58 
59 /* Most of the above are error flags, but some aren't */
60 #define	DPAA_FD_CMD_STAT_ERR_M		0x010ce3e8
61 #define	DPAA_FD_TX_STAT_ERR_M		0x03000000
62 
63 #define	DPAA_FD_GET_ADDR(fd)	((void *)PHYS_TO_DMAP(fd->addr))
64 
65 struct dpaa_sgte {
66 	uint64_t addr;
67 	uint32_t extension:1;
68 	uint32_t final:1;
69 	uint32_t length:30;
70 	uint16_t bpid;
71 	uint16_t offset;
72 } __packed;
73 struct qman_fqr;
74 
75 
76 #define	DPAA_NUM_OF_SG_TABLE_ENTRY	16
77 
78 /*
79  * Ring API infrastructure
80  *
81  * BMan and QMan both use cache-enabled rings.  Abstract this away to a more
82  * generalized interface to reduce code copying.
83  *
84  * Requirements:
85  * - Before calling <ring>_init() the ring base (ring->ring) must be initialized
86  *   to the base of the ring.
87  */
88 #define	DPAA_RING_DECLARE(pfx)			\
89 	struct pfx##_ring {			\
90 		struct pfx##_entry *ring;	\
91 		struct pfx##_entry *cursor;	\
92 		uint8_t vbit;			\
93 		uint8_t	avail;			\
94 		uint8_t ci;			\
95 		uint8_t	ithresh;		\
96 	}
97 
98 /*
99  * Ring functions:
100  *
101  * ring_cyc_diff() -- get the (circular) difference of `l - f`
102  * ring_ring_init() -- Set up the ring structures. Portal must be
103  *                     initialized beforehand, and ring->ring must be nonzero.
104  * ring_CARRYCLEAR() -- stealth math to do circular roll-over
105  * ring_INC() -- Increment the cursor within the ring
106  * ring_update() -- Update ring entry availability count
107  * ring_start() -- Reserve the next entry in the ring if available.
108  * ring_commit() -- Commit the reserved ring entry by setting the verb and
109  *                  AVB bit
110  */
111 #define	DPAA_RING(pfx,sz,pi_e,ci_e,pi_i,ci_i)				\
112 static inline int							\
113 pfx##_cyc_diff(uint8_t size, uint8_t f, uint8_t l)			\
114 {									\
115 	if (f <= l)							\
116 		return (uint8_t)(l - f);				\
117 	return (uint8_t)(l + size - f);					\
118 }									\
119 static inline void							\
120 pfx##_ring_init(struct pfx##_ring *ring, struct dpaa_portal_softc *portal)\
121 {									\
122 	uint32_t pi = *(uint32_t*)(portal->sc_ci_va + pi_i) & (sz - 1);	\
123 	uint32_t ci = *(uint32_t*)(portal->sc_ci_va + ci_i);		\
124 	ring->ci = ci & (sz - 1);					\
125 	ring->vbit = !!(ci & sz) << 7;					\
126 	ring->cursor = ring->ring + pi;					\
127 	ring->avail = sz - 1 - pfx##_cyc_diff(sz, ring->ci, pi);	\
128 }									\
129 static inline void *							\
130 pfx##_CARRYCLEAR(struct pfx##_entry *p)					\
131 {									\
132 	return ((void *)((uintptr_t)p & (~(uintptr_t)(sz << 6))));	\
133 }									\
134 static inline void							\
135 pfx##_INC(struct pfx##_ring *ring)					\
136 {									\
137 	struct pfx##_entry *partial = ring->cursor + 1;			\
138 	ring->cursor = pfx##_CARRYCLEAR(partial);			\
139 	if (partial != ring->cursor)					\
140 		ring->vbit ^= 0x80;					\
141 }									\
142 static inline uint8_t							\
143 pfx##_update(struct pfx##_ring *ring, struct dpaa_portal_softc *portal)	\
144 {									\
145 	uint8_t diff, old_ci = ring->ci;				\
146 	ring->ci = *(uint32_t*)(portal->sc_ci_va + ci_i) & (sz - 1);	\
147 	diff = pfx##_cyc_diff(sz, old_ci, ring->ci);			\
148 	ring->avail += diff;						\
149 	return (diff);							\
150 }									\
151 static inline struct pfx##_entry * __unused				\
152 pfx##_start(struct pfx##_ring *ring, struct dpaa_portal_softc *portal)	\
153 {									\
154 	if (ring->avail <= 1) {						\
155 		pfx##_update(ring, portal);				\
156 		if (ring->avail == 0)					\
157 			return (NULL);					\
158 	}								\
159 	dpaa_zero_line(ring->cursor);					\
160 	return (ring->cursor);						\
161 }									\
162 static inline void __unused						\
163 pfx##_commit(struct pfx##_ring *ring, uint8_t verb)			\
164 {									\
165 	struct pfx##_entry *entry = ring->cursor;			\
166 	dpaa_lw_barrier();						\
167 	entry->verb = verb | ring->vbit;				\
168 	dpaa_flush_line(entry);						\
169 	pfx##_INC(ring);						\
170 	ring->avail--;							\
171 } struct hack
172 
173 #ifdef	__powerpc__
174 static inline void
175 dpaa_flush_line(void *line)
176 {
177 	__asm __volatile ("dcbf 0, %0" :: "r"(line) : "memory");
178 }
179 
180 static inline void
181 dpaa_zero_line(void *line)
182 {
183 	__asm __volatile ("dcbz 0, %0" :: "r"(line) : "memory");
184 }
185 
186 static inline void
187 dpaa_touch_line(void *line)
188 {
189 	__asm __volatile ("dcbt 0, %0" :: "r"(line) : "memory");
190 }
191 
192 static inline void
193 dpaa_lw_barrier(void)
194 {
195 	powerpc_lwsync();
196 }
197 #endif
198 
199 #endif
200