xref: /freebsd/sys/dev/ioat/ioat_internal.h (revision 9e3bbf26a9a1fad9d718cd990fc7ac8401906c13)
1e974f91cSConrad Meyer /*-
2e974f91cSConrad Meyer  * Copyright (C) 2012 Intel Corporation
3e974f91cSConrad Meyer  * All rights reserved.
4e974f91cSConrad Meyer  *
5e974f91cSConrad Meyer  * Redistribution and use in source and binary forms, with or without
6e974f91cSConrad Meyer  * modification, are permitted provided that the following conditions
7e974f91cSConrad Meyer  * are met:
8e974f91cSConrad Meyer  * 1. Redistributions of source code must retain the above copyright
9e974f91cSConrad Meyer  *    notice, this list of conditions and the following disclaimer.
10e974f91cSConrad Meyer  * 2. Redistributions in binary form must reproduce the above copyright
11e974f91cSConrad Meyer  *    notice, this list of conditions and the following disclaimer in the
12e974f91cSConrad Meyer  *    documentation and/or other materials provided with the distribution.
13e974f91cSConrad Meyer  *
14e974f91cSConrad Meyer  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15e974f91cSConrad Meyer  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16e974f91cSConrad Meyer  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17e974f91cSConrad Meyer  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18e974f91cSConrad Meyer  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19e974f91cSConrad Meyer  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20e974f91cSConrad Meyer  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21e974f91cSConrad Meyer  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22e974f91cSConrad Meyer  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23e974f91cSConrad Meyer  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24e974f91cSConrad Meyer  * SUCH DAMAGE.
25e974f91cSConrad Meyer  */
26e974f91cSConrad Meyer 
27e974f91cSConrad Meyer __FBSDID("$FreeBSD$");
28e974f91cSConrad Meyer 
29e974f91cSConrad Meyer #ifndef __IOAT_INTERNAL_H__
30e974f91cSConrad Meyer #define __IOAT_INTERNAL_H__
31e974f91cSConrad Meyer 
32e974f91cSConrad Meyer #define	DEVICE2SOFTC(dev)	((struct ioat_softc *) device_get_softc(dev))
3343fc1847SConrad Meyer #define	KTR_IOAT		KTR_SPARE3
34e974f91cSConrad Meyer 
35e974f91cSConrad Meyer #define	ioat_read_chancnt(ioat) \
36e974f91cSConrad Meyer 	ioat_read_1((ioat), IOAT_CHANCNT_OFFSET)
37e974f91cSConrad Meyer 
38e974f91cSConrad Meyer #define	ioat_read_xfercap(ioat) \
39b81eee4aSConrad Meyer 	(ioat_read_1((ioat), IOAT_XFERCAP_OFFSET) & IOAT_XFERCAP_VALID_MASK)
40e974f91cSConrad Meyer 
41e974f91cSConrad Meyer #define	ioat_write_intrctrl(ioat, value) \
42e974f91cSConrad Meyer 	ioat_write_1((ioat), IOAT_INTRCTRL_OFFSET, (value))
43e974f91cSConrad Meyer 
44e974f91cSConrad Meyer #define	ioat_read_cbver(ioat) \
45e974f91cSConrad Meyer 	(ioat_read_1((ioat), IOAT_CBVER_OFFSET) & 0xFF)
46e974f91cSConrad Meyer 
47e974f91cSConrad Meyer #define	ioat_read_dmacapability(ioat) \
48e974f91cSConrad Meyer 	ioat_read_4((ioat), IOAT_DMACAPABILITY_OFFSET)
49e974f91cSConrad Meyer 
50e974f91cSConrad Meyer #define	ioat_write_chanctrl(ioat, value) \
51e974f91cSConrad Meyer 	ioat_write_2((ioat), IOAT_CHANCTRL_OFFSET, (value))
52e974f91cSConrad Meyer 
53e974f91cSConrad Meyer static __inline uint64_t
54e974f91cSConrad Meyer ioat_bus_space_read_8_lower_first(bus_space_tag_t tag,
55e974f91cSConrad Meyer     bus_space_handle_t handle, bus_size_t offset)
56e974f91cSConrad Meyer {
57e974f91cSConrad Meyer 	return (bus_space_read_4(tag, handle, offset) |
58e974f91cSConrad Meyer 	    ((uint64_t)bus_space_read_4(tag, handle, offset + 4)) << 32);
59e974f91cSConrad Meyer }
60e974f91cSConrad Meyer 
61e974f91cSConrad Meyer static __inline void
62e974f91cSConrad Meyer ioat_bus_space_write_8_lower_first(bus_space_tag_t tag,
63e974f91cSConrad Meyer     bus_space_handle_t handle, bus_size_t offset, uint64_t val)
64e974f91cSConrad Meyer {
65e974f91cSConrad Meyer 	bus_space_write_4(tag, handle, offset, val);
66e974f91cSConrad Meyer 	bus_space_write_4(tag, handle, offset + 4, val >> 32);
67e974f91cSConrad Meyer }
68e974f91cSConrad Meyer 
69f3e30f97SConrad Meyer #ifdef __i386__
70e974f91cSConrad Meyer #define ioat_bus_space_read_8 ioat_bus_space_read_8_lower_first
71e974f91cSConrad Meyer #define ioat_bus_space_write_8 ioat_bus_space_write_8_lower_first
72e974f91cSConrad Meyer #else
73e974f91cSConrad Meyer #define ioat_bus_space_read_8(tag, handle, offset) \
74e974f91cSConrad Meyer 	bus_space_read_8((tag), (handle), (offset))
75e974f91cSConrad Meyer #define ioat_bus_space_write_8(tag, handle, offset, val) \
76e974f91cSConrad Meyer 	bus_space_write_8((tag), (handle), (offset), (val))
77e974f91cSConrad Meyer #endif
78e974f91cSConrad Meyer 
79e974f91cSConrad Meyer #define ioat_read_1(ioat, offset) \
80e974f91cSConrad Meyer 	bus_space_read_1((ioat)->pci_bus_tag, (ioat)->pci_bus_handle, \
81e974f91cSConrad Meyer 	    (offset))
82e974f91cSConrad Meyer 
83e974f91cSConrad Meyer #define ioat_read_2(ioat, offset) \
84e974f91cSConrad Meyer 	bus_space_read_2((ioat)->pci_bus_tag, (ioat)->pci_bus_handle, \
85e974f91cSConrad Meyer 	    (offset))
86e974f91cSConrad Meyer 
87e974f91cSConrad Meyer #define ioat_read_4(ioat, offset) \
88e974f91cSConrad Meyer 	bus_space_read_4((ioat)->pci_bus_tag, (ioat)->pci_bus_handle, \
89e974f91cSConrad Meyer 	    (offset))
90e974f91cSConrad Meyer 
91e974f91cSConrad Meyer #define ioat_read_8(ioat, offset) \
92e974f91cSConrad Meyer 	ioat_bus_space_read_8((ioat)->pci_bus_tag, (ioat)->pci_bus_handle, \
93e974f91cSConrad Meyer 	    (offset))
94e974f91cSConrad Meyer 
95e974f91cSConrad Meyer #define ioat_read_double_4(ioat, offset) \
96e974f91cSConrad Meyer 	ioat_bus_space_read_8_lower_first((ioat)->pci_bus_tag, \
97e974f91cSConrad Meyer 	    (ioat)->pci_bus_handle, (offset))
98e974f91cSConrad Meyer 
99e974f91cSConrad Meyer #define ioat_write_1(ioat, offset, value) \
100e974f91cSConrad Meyer 	bus_space_write_1((ioat)->pci_bus_tag, (ioat)->pci_bus_handle, \
101e974f91cSConrad Meyer 	    (offset), (value))
102e974f91cSConrad Meyer 
103e974f91cSConrad Meyer #define ioat_write_2(ioat, offset, value) \
104e974f91cSConrad Meyer 	bus_space_write_2((ioat)->pci_bus_tag, (ioat)->pci_bus_handle, \
105e974f91cSConrad Meyer 	    (offset), (value))
106e974f91cSConrad Meyer 
107e974f91cSConrad Meyer #define ioat_write_4(ioat, offset, value) \
108e974f91cSConrad Meyer 	bus_space_write_4((ioat)->pci_bus_tag, (ioat)->pci_bus_handle, \
109e974f91cSConrad Meyer 	    (offset), (value))
110e974f91cSConrad Meyer 
111e974f91cSConrad Meyer #define ioat_write_8(ioat, offset, value) \
112e974f91cSConrad Meyer 	ioat_bus_space_write_8((ioat)->pci_bus_tag, (ioat)->pci_bus_handle, \
113e974f91cSConrad Meyer 	    (offset), (value))
114e974f91cSConrad Meyer 
115e974f91cSConrad Meyer #define ioat_write_double_4(ioat, offset, value) \
116e974f91cSConrad Meyer 	ioat_bus_space_write_8_lower_first((ioat)->pci_bus_tag, \
117e974f91cSConrad Meyer 	    (ioat)->pci_bus_handle, (offset), (value))
118e974f91cSConrad Meyer 
119e974f91cSConrad Meyer MALLOC_DECLARE(M_IOAT);
120e974f91cSConrad Meyer 
121e974f91cSConrad Meyer SYSCTL_DECL(_hw_ioat);
122e974f91cSConrad Meyer 
1231c25420eSConrad Meyer extern int g_ioat_debug_level;
124e974f91cSConrad Meyer 
125*9e3bbf26SConrad Meyer struct generic_dma_control {
126*9e3bbf26SConrad Meyer 	uint32_t int_enable:1;
127*9e3bbf26SConrad Meyer 	uint32_t src_snoop_disable:1;
128*9e3bbf26SConrad Meyer 	uint32_t dest_snoop_disable:1;
129*9e3bbf26SConrad Meyer 	uint32_t completion_update:1;
130*9e3bbf26SConrad Meyer 	uint32_t fence:1;
131*9e3bbf26SConrad Meyer 	uint32_t reserved1:1;
132*9e3bbf26SConrad Meyer 	uint32_t src_page_break:1;
133*9e3bbf26SConrad Meyer 	uint32_t dest_page_break:1;
134*9e3bbf26SConrad Meyer 	uint32_t bundle:1;
135*9e3bbf26SConrad Meyer 	uint32_t dest_dca:1;
136*9e3bbf26SConrad Meyer 	uint32_t hint:1;
137*9e3bbf26SConrad Meyer 	uint32_t reserved2:13;
138*9e3bbf26SConrad Meyer 	uint32_t op:8;
139*9e3bbf26SConrad Meyer };
140*9e3bbf26SConrad Meyer 
141*9e3bbf26SConrad Meyer struct ioat_generic_hw_descriptor {
142*9e3bbf26SConrad Meyer 	uint32_t size;
143*9e3bbf26SConrad Meyer 	union {
144*9e3bbf26SConrad Meyer 		uint32_t control_raw;
145*9e3bbf26SConrad Meyer 		struct generic_dma_control control_generic;
146*9e3bbf26SConrad Meyer 	} u;
147*9e3bbf26SConrad Meyer 	uint64_t src_addr;
148*9e3bbf26SConrad Meyer 	uint64_t dest_addr;
149*9e3bbf26SConrad Meyer 	uint64_t next;
150*9e3bbf26SConrad Meyer 	uint64_t reserved[4];
151*9e3bbf26SConrad Meyer };
152*9e3bbf26SConrad Meyer 
153e974f91cSConrad Meyer struct ioat_dma_hw_descriptor {
154e974f91cSConrad Meyer 	uint32_t size;
155e974f91cSConrad Meyer 	union {
156e974f91cSConrad Meyer 		uint32_t control_raw;
157*9e3bbf26SConrad Meyer 		struct generic_dma_control control_generic;
158e974f91cSConrad Meyer 		struct {
159e974f91cSConrad Meyer 			uint32_t int_enable:1;
160e974f91cSConrad Meyer 			uint32_t src_snoop_disable:1;
161e974f91cSConrad Meyer 			uint32_t dest_snoop_disable:1;
162e974f91cSConrad Meyer 			uint32_t completion_update:1;
163e974f91cSConrad Meyer 			uint32_t fence:1;
164e974f91cSConrad Meyer 			uint32_t null:1;
165e974f91cSConrad Meyer 			uint32_t src_page_break:1;
166e974f91cSConrad Meyer 			uint32_t dest_page_break:1;
167e974f91cSConrad Meyer 			uint32_t bundle:1;
168e974f91cSConrad Meyer 			uint32_t dest_dca:1;
169e974f91cSConrad Meyer 			uint32_t hint:1;
170e974f91cSConrad Meyer 			uint32_t reserved:13;
171e974f91cSConrad Meyer 			#define IOAT_OP_COPY 0x00
172e974f91cSConrad Meyer 			uint32_t op:8;
173e974f91cSConrad Meyer 		} control;
174e974f91cSConrad Meyer 	} u;
175e974f91cSConrad Meyer 	uint64_t src_addr;
176e974f91cSConrad Meyer 	uint64_t dest_addr;
177e974f91cSConrad Meyer 	uint64_t next;
178e974f91cSConrad Meyer 	uint64_t reserved;
179e974f91cSConrad Meyer 	uint64_t reserved2;
180e974f91cSConrad Meyer 	uint64_t user1;
181e974f91cSConrad Meyer 	uint64_t user2;
182e974f91cSConrad Meyer };
183e974f91cSConrad Meyer 
184e974f91cSConrad Meyer struct ioat_fill_hw_descriptor {
185e974f91cSConrad Meyer 	uint32_t size;
186e974f91cSConrad Meyer 	union {
187e974f91cSConrad Meyer 		uint32_t control_raw;
188*9e3bbf26SConrad Meyer 		struct generic_dma_control control_generic;
189e974f91cSConrad Meyer 		struct {
190e974f91cSConrad Meyer 			uint32_t int_enable:1;
191e974f91cSConrad Meyer 			uint32_t reserved:1;
192e974f91cSConrad Meyer 			uint32_t dest_snoop_disable:1;
193e974f91cSConrad Meyer 			uint32_t completion_update:1;
194e974f91cSConrad Meyer 			uint32_t fence:1;
195e974f91cSConrad Meyer 			uint32_t reserved2:2;
196e974f91cSConrad Meyer 			uint32_t dest_page_break:1;
197e974f91cSConrad Meyer 			uint32_t bundle:1;
198e974f91cSConrad Meyer 			uint32_t reserved3:15;
199e974f91cSConrad Meyer 			#define IOAT_OP_FILL 0x01
200e974f91cSConrad Meyer 			uint32_t op:8;
201e974f91cSConrad Meyer 		} control;
202e974f91cSConrad Meyer 	} u;
203e974f91cSConrad Meyer 	uint64_t src_data;
204e974f91cSConrad Meyer 	uint64_t dest_addr;
205e974f91cSConrad Meyer 	uint64_t next;
206e974f91cSConrad Meyer 	uint64_t reserved;
207e974f91cSConrad Meyer 	uint64_t next_dest_addr;
208e974f91cSConrad Meyer 	uint64_t user1;
209e974f91cSConrad Meyer 	uint64_t user2;
210e974f91cSConrad Meyer };
211e974f91cSConrad Meyer 
212e974f91cSConrad Meyer struct ioat_xor_hw_descriptor {
213e974f91cSConrad Meyer 	uint32_t size;
214e974f91cSConrad Meyer 	union {
215e974f91cSConrad Meyer 		uint32_t control_raw;
216*9e3bbf26SConrad Meyer 		struct generic_dma_control control_generic;
217e974f91cSConrad Meyer 		struct {
218e974f91cSConrad Meyer 			uint32_t int_enable:1;
219e974f91cSConrad Meyer 			uint32_t src_snoop_disable:1;
220e974f91cSConrad Meyer 			uint32_t dest_snoop_disable:1;
221e974f91cSConrad Meyer 			uint32_t completion_update:1;
222e974f91cSConrad Meyer 			uint32_t fence:1;
223e974f91cSConrad Meyer 			uint32_t src_count:3;
224e974f91cSConrad Meyer 			uint32_t bundle:1;
225e974f91cSConrad Meyer 			uint32_t dest_dca:1;
226e974f91cSConrad Meyer 			uint32_t hint:1;
227e974f91cSConrad Meyer 			uint32_t reserved:13;
228e974f91cSConrad Meyer 			#define IOAT_OP_XOR 0x87
229e974f91cSConrad Meyer 			#define IOAT_OP_XOR_VAL 0x88
230e974f91cSConrad Meyer 			uint32_t op:8;
231e974f91cSConrad Meyer 		} control;
232e974f91cSConrad Meyer 	} u;
233e974f91cSConrad Meyer 	uint64_t src_addr;
234e974f91cSConrad Meyer 	uint64_t dest_addr;
235e974f91cSConrad Meyer 	uint64_t next;
236e974f91cSConrad Meyer 	uint64_t src_addr2;
237e974f91cSConrad Meyer 	uint64_t src_addr3;
238e974f91cSConrad Meyer 	uint64_t src_addr4;
239e974f91cSConrad Meyer 	uint64_t src_addr5;
240e974f91cSConrad Meyer };
241e974f91cSConrad Meyer 
242e974f91cSConrad Meyer struct ioat_xor_ext_hw_descriptor {
243e974f91cSConrad Meyer 	uint64_t src_addr6;
244e974f91cSConrad Meyer 	uint64_t src_addr7;
245e974f91cSConrad Meyer 	uint64_t src_addr8;
246e974f91cSConrad Meyer 	uint64_t next;
247e974f91cSConrad Meyer 	uint64_t reserved[4];
248e974f91cSConrad Meyer };
249e974f91cSConrad Meyer 
250e974f91cSConrad Meyer struct ioat_pq_hw_descriptor {
251e974f91cSConrad Meyer 	uint32_t size;
252e974f91cSConrad Meyer 	union {
253e974f91cSConrad Meyer 		uint32_t control_raw;
254*9e3bbf26SConrad Meyer 		struct generic_dma_control control_generic;
255e974f91cSConrad Meyer 		struct {
256e974f91cSConrad Meyer 			uint32_t int_enable:1;
257e974f91cSConrad Meyer 			uint32_t src_snoop_disable:1;
258e974f91cSConrad Meyer 			uint32_t dest_snoop_disable:1;
259e974f91cSConrad Meyer 			uint32_t completion_update:1;
260e974f91cSConrad Meyer 			uint32_t fence:1;
261e974f91cSConrad Meyer 			uint32_t src_count:3;
262e974f91cSConrad Meyer 			uint32_t bundle:1;
263e974f91cSConrad Meyer 			uint32_t dest_dca:1;
264e974f91cSConrad Meyer 			uint32_t hint:1;
265e974f91cSConrad Meyer 			uint32_t p_disable:1;
266e974f91cSConrad Meyer 			uint32_t q_disable:1;
267e974f91cSConrad Meyer 			uint32_t reserved:11;
268e974f91cSConrad Meyer 			#define IOAT_OP_PQ 0x89
269e974f91cSConrad Meyer 			#define IOAT_OP_PQ_VAL 0x8a
270e974f91cSConrad Meyer 			uint32_t op:8;
271e974f91cSConrad Meyer 		} control;
272e974f91cSConrad Meyer 	} u;
273e974f91cSConrad Meyer 	uint64_t src_addr;
274e974f91cSConrad Meyer 	uint64_t p_addr;
275e974f91cSConrad Meyer 	uint64_t next;
276e974f91cSConrad Meyer 	uint64_t src_addr2;
277e974f91cSConrad Meyer 	uint64_t src_addr3;
278e974f91cSConrad Meyer 	uint8_t  coef[8];
279e974f91cSConrad Meyer 	uint64_t q_addr;
280e974f91cSConrad Meyer };
281e974f91cSConrad Meyer 
282e974f91cSConrad Meyer struct ioat_pq_ext_hw_descriptor {
283e974f91cSConrad Meyer 	uint64_t src_addr4;
284e974f91cSConrad Meyer 	uint64_t src_addr5;
285e974f91cSConrad Meyer 	uint64_t src_addr6;
286e974f91cSConrad Meyer 	uint64_t next;
287e974f91cSConrad Meyer 	uint64_t src_addr7;
288e974f91cSConrad Meyer 	uint64_t src_addr8;
289e974f91cSConrad Meyer 	uint64_t reserved[2];
290e974f91cSConrad Meyer };
291e974f91cSConrad Meyer 
292e974f91cSConrad Meyer struct ioat_pq_update_hw_descriptor {
293e974f91cSConrad Meyer 	uint32_t size;
294e974f91cSConrad Meyer 	union {
295e974f91cSConrad Meyer 		uint32_t control_raw;
296*9e3bbf26SConrad Meyer 		struct generic_dma_control control_generic;
297e974f91cSConrad Meyer 		struct {
298e974f91cSConrad Meyer 			uint32_t int_enable:1;
299e974f91cSConrad Meyer 			uint32_t src_snoop_disable:1;
300e974f91cSConrad Meyer 			uint32_t dest_snoop_disable:1;
301e974f91cSConrad Meyer 			uint32_t completion_update:1;
302e974f91cSConrad Meyer 			uint32_t fence:1;
303e974f91cSConrad Meyer 			uint32_t src_cnt:3;
304e974f91cSConrad Meyer 			uint32_t bundle:1;
305e974f91cSConrad Meyer 			uint32_t dest_dca:1;
306e974f91cSConrad Meyer 			uint32_t hint:1;
307e974f91cSConrad Meyer 			uint32_t p_disable:1;
308e974f91cSConrad Meyer 			uint32_t q_disable:1;
309e974f91cSConrad Meyer 			uint32_t reserved:3;
310e974f91cSConrad Meyer 			uint32_t coef:8;
311e974f91cSConrad Meyer 			#define IOAT_OP_PQ_UP 0x8b
312e974f91cSConrad Meyer 			uint32_t op:8;
313e974f91cSConrad Meyer 		} control;
314e974f91cSConrad Meyer 	} u;
315e974f91cSConrad Meyer 	uint64_t src_addr;
316e974f91cSConrad Meyer 	uint64_t p_addr;
317e974f91cSConrad Meyer 	uint64_t next;
318e974f91cSConrad Meyer 	uint64_t src_addr2;
319e974f91cSConrad Meyer 	uint64_t p_src;
320e974f91cSConrad Meyer 	uint64_t q_src;
321e974f91cSConrad Meyer 	uint64_t q_addr;
322e974f91cSConrad Meyer };
323e974f91cSConrad Meyer 
324e974f91cSConrad Meyer struct ioat_raw_hw_descriptor {
325e974f91cSConrad Meyer 	uint64_t field[8];
326e974f91cSConrad Meyer };
327e974f91cSConrad Meyer 
328e974f91cSConrad Meyer struct bus_dmadesc {
329e974f91cSConrad Meyer 	bus_dmaengine_callback_t callback_fn;
330e974f91cSConrad Meyer 	void			 *callback_arg;
331e974f91cSConrad Meyer };
332e974f91cSConrad Meyer 
333e974f91cSConrad Meyer struct ioat_descriptor {
334e974f91cSConrad Meyer 	struct bus_dmadesc	bus_dmadesc;
335e974f91cSConrad Meyer 	union {
336*9e3bbf26SConrad Meyer 		struct ioat_generic_hw_descriptor	*generic;
337e974f91cSConrad Meyer 		struct ioat_dma_hw_descriptor		*dma;
338e974f91cSConrad Meyer 		struct ioat_fill_hw_descriptor		*fill;
339e974f91cSConrad Meyer 		struct ioat_xor_hw_descriptor		*xor;
340e974f91cSConrad Meyer 		struct ioat_xor_ext_hw_descriptor	*xor_ext;
341e974f91cSConrad Meyer 		struct ioat_pq_hw_descriptor		*pq;
342e974f91cSConrad Meyer 		struct ioat_pq_ext_hw_descriptor	*pq_ext;
343e974f91cSConrad Meyer 		struct ioat_raw_hw_descriptor		*raw;
344e974f91cSConrad Meyer 	} u;
345e974f91cSConrad Meyer 	uint32_t		id;
346e974f91cSConrad Meyer 	uint32_t		length;
347e974f91cSConrad Meyer 	enum validate_flags	*validate_result;
348e974f91cSConrad Meyer 	bus_addr_t		hw_desc_bus_addr;
349e974f91cSConrad Meyer };
350e974f91cSConrad Meyer 
351466b3540SConrad Meyer enum ioat_ref_kind {
352466b3540SConrad Meyer 	IOAT_DMAENGINE_REF = 0,
353466b3540SConrad Meyer 	IOAT_ACTIVE_DESCR_REF,
354466b3540SConrad Meyer 	IOAT_NUM_REF_KINDS
355466b3540SConrad Meyer };
356466b3540SConrad Meyer 
357e974f91cSConrad Meyer /* One of these per allocated PCI device. */
358e974f91cSConrad Meyer struct ioat_softc {
359e974f91cSConrad Meyer 	bus_dmaengine_t		dmaengine;
360e974f91cSConrad Meyer #define	to_ioat_softc(_dmaeng)						\
361e974f91cSConrad Meyer ({									\
362e974f91cSConrad Meyer 	bus_dmaengine_t *_p = (_dmaeng);				\
363e974f91cSConrad Meyer 	(struct ioat_softc *)((char *)_p -				\
364e974f91cSConrad Meyer 	    offsetof(struct ioat_softc, dmaengine));			\
365e974f91cSConrad Meyer })
366e974f91cSConrad Meyer 
367e974f91cSConrad Meyer 	int			version;
368e974f91cSConrad Meyer 
369e974f91cSConrad Meyer 	struct mtx		submit_lock;
370e974f91cSConrad Meyer 	device_t		device;
371e974f91cSConrad Meyer 	bus_space_tag_t		pci_bus_tag;
372e974f91cSConrad Meyer 	bus_space_handle_t	pci_bus_handle;
373e974f91cSConrad Meyer 	int			pci_resource_id;
374e974f91cSConrad Meyer 	struct resource		*pci_resource;
375e974f91cSConrad Meyer 	uint32_t		max_xfer_size;
376e974f91cSConrad Meyer 
377e974f91cSConrad Meyer 	struct resource		*res;
378e974f91cSConrad Meyer 	int			rid;
379e974f91cSConrad Meyer 	void			*tag;
380e974f91cSConrad Meyer 
381e974f91cSConrad Meyer 	bus_dma_tag_t		hw_desc_tag;
382e974f91cSConrad Meyer 	bus_dmamap_t		hw_desc_map;
383e974f91cSConrad Meyer 
384e974f91cSConrad Meyer 	bus_dma_tag_t		comp_update_tag;
385e974f91cSConrad Meyer 	bus_dmamap_t		comp_update_map;
386e974f91cSConrad Meyer 	uint64_t		*comp_update;
387e974f91cSConrad Meyer 	bus_addr_t		comp_update_bus_addr;
388e974f91cSConrad Meyer 
389e974f91cSConrad Meyer 	struct callout		timer;
390e974f91cSConrad Meyer 
391e974f91cSConrad Meyer 	boolean_t		is_resize_pending;
392e974f91cSConrad Meyer 	boolean_t		is_completion_pending;
393e974f91cSConrad Meyer 	boolean_t		is_reset_pending;
394e974f91cSConrad Meyer 	boolean_t		is_channel_running;
395e974f91cSConrad Meyer 
396e974f91cSConrad Meyer 	uint32_t		head;
397e974f91cSConrad Meyer 	uint32_t		tail;
398bf8553eaSConrad Meyer 	uint32_t		hw_head;
399e974f91cSConrad Meyer 	uint32_t		ring_size_order;
400e974f91cSConrad Meyer 	bus_addr_t		last_seen;
401e974f91cSConrad Meyer 
402e974f91cSConrad Meyer 	struct ioat_descriptor	**ring;
403e974f91cSConrad Meyer 
404e974f91cSConrad Meyer 	struct mtx		cleanup_lock;
405466b3540SConrad Meyer 	volatile uint32_t	refcnt;
406466b3540SConrad Meyer #ifdef INVARIANTS
407466b3540SConrad Meyer 	volatile uint32_t	refkinds[IOAT_NUM_REF_KINDS];
408466b3540SConrad Meyer #endif
409e974f91cSConrad Meyer };
410e974f91cSConrad Meyer 
4117afbb263SConrad Meyer void ioat_test_attach(void);
4127afbb263SConrad Meyer void ioat_test_detach(void);
4137afbb263SConrad Meyer 
414e974f91cSConrad Meyer static inline uint64_t
415e974f91cSConrad Meyer ioat_get_chansts(struct ioat_softc *ioat)
416e974f91cSConrad Meyer {
417e974f91cSConrad Meyer 	uint64_t status;
418e974f91cSConrad Meyer 
419e974f91cSConrad Meyer 	if (ioat->version >= IOAT_VER_3_3)
420e974f91cSConrad Meyer 		status = ioat_read_8(ioat, IOAT_CHANSTS_OFFSET);
421e974f91cSConrad Meyer 	else
422e974f91cSConrad Meyer 		/* Must read lower 4 bytes before upper 4 bytes. */
423e974f91cSConrad Meyer 		status = ioat_read_double_4(ioat, IOAT_CHANSTS_OFFSET);
424e974f91cSConrad Meyer 	return (status);
425e974f91cSConrad Meyer }
426e974f91cSConrad Meyer 
427e974f91cSConrad Meyer static inline void
428e974f91cSConrad Meyer ioat_write_chancmp(struct ioat_softc *ioat, uint64_t addr)
429e974f91cSConrad Meyer {
430e974f91cSConrad Meyer 
431e974f91cSConrad Meyer 	if (ioat->version >= IOAT_VER_3_3)
432e974f91cSConrad Meyer 		ioat_write_8(ioat, IOAT_CHANCMP_OFFSET_LOW, addr);
433e974f91cSConrad Meyer 	else
434e974f91cSConrad Meyer 		ioat_write_double_4(ioat, IOAT_CHANCMP_OFFSET_LOW, addr);
435e974f91cSConrad Meyer }
436e974f91cSConrad Meyer 
437e974f91cSConrad Meyer static inline void
438e974f91cSConrad Meyer ioat_write_chainaddr(struct ioat_softc *ioat, uint64_t addr)
439e974f91cSConrad Meyer {
440e974f91cSConrad Meyer 
441e974f91cSConrad Meyer 	if (ioat->version >= IOAT_VER_3_3)
442e974f91cSConrad Meyer 		ioat_write_8(ioat, IOAT_CHAINADDR_OFFSET_LOW, addr);
443e974f91cSConrad Meyer 	else
444e974f91cSConrad Meyer 		ioat_write_double_4(ioat, IOAT_CHAINADDR_OFFSET_LOW, addr);
445e974f91cSConrad Meyer }
446e974f91cSConrad Meyer 
447e974f91cSConrad Meyer static inline boolean_t
448e974f91cSConrad Meyer is_ioat_active(uint64_t status)
449e974f91cSConrad Meyer {
450e974f91cSConrad Meyer 	return ((status & IOAT_CHANSTS_STATUS) == IOAT_CHANSTS_ACTIVE);
451e974f91cSConrad Meyer }
452e974f91cSConrad Meyer 
453e974f91cSConrad Meyer static inline boolean_t
454e974f91cSConrad Meyer is_ioat_idle(uint64_t status)
455e974f91cSConrad Meyer {
456e974f91cSConrad Meyer 	return ((status & IOAT_CHANSTS_STATUS) == IOAT_CHANSTS_IDLE);
457e974f91cSConrad Meyer }
458e974f91cSConrad Meyer 
459e974f91cSConrad Meyer static inline boolean_t
460e974f91cSConrad Meyer is_ioat_halted(uint64_t status)
461e974f91cSConrad Meyer {
462e974f91cSConrad Meyer 	return ((status & IOAT_CHANSTS_STATUS) == IOAT_CHANSTS_HALTED);
463e974f91cSConrad Meyer }
464e974f91cSConrad Meyer 
465e974f91cSConrad Meyer static inline boolean_t
466e974f91cSConrad Meyer is_ioat_suspended(uint64_t status)
467e974f91cSConrad Meyer {
468e974f91cSConrad Meyer 	return ((status & IOAT_CHANSTS_STATUS) == IOAT_CHANSTS_SUSPENDED);
469e974f91cSConrad Meyer }
470e974f91cSConrad Meyer 
471e974f91cSConrad Meyer static inline void
472e974f91cSConrad Meyer ioat_suspend(struct ioat_softc *ioat)
473e974f91cSConrad Meyer {
474e974f91cSConrad Meyer 	ioat_write_1(ioat, IOAT_CHANCMD_OFFSET, IOAT_CHANCMD_SUSPEND);
475e974f91cSConrad Meyer }
476e974f91cSConrad Meyer 
477e974f91cSConrad Meyer static inline void
478e974f91cSConrad Meyer ioat_reset(struct ioat_softc *ioat)
479e974f91cSConrad Meyer {
480e974f91cSConrad Meyer 	ioat_write_1(ioat, IOAT_CHANCMD_OFFSET, IOAT_CHANCMD_RESET);
481e974f91cSConrad Meyer }
482e974f91cSConrad Meyer 
483e974f91cSConrad Meyer static inline boolean_t
484e974f91cSConrad Meyer ioat_reset_pending(struct ioat_softc *ioat)
485e974f91cSConrad Meyer {
486e974f91cSConrad Meyer 	uint8_t cmd;
487e974f91cSConrad Meyer 
488e974f91cSConrad Meyer 	cmd = ioat_read_1(ioat, IOAT_CHANCMD_OFFSET);
489e974f91cSConrad Meyer 	return ((cmd & IOAT_CHANCMD_RESET) != 0);
490e974f91cSConrad Meyer }
491e974f91cSConrad Meyer 
492e974f91cSConrad Meyer #endif /* __IOAT_INTERNAL_H__ */
493