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