aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/dpaa/dpaa_common.h
blob: 8fa43a034ef5418caf0bd8b7f157e55daa1566f0 (plain) (blame)
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