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