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