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