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