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