xref: /freebsd/sys/dev/firewire/firewire.h (revision eb69d1f144a6fcc765d1b9d44a5ae8082353e70b)
1 /*-
2  * SPDX-License-Identifier: BSD-4-Clause
3  *
4  * Copyright (c) 2003 Hidetoshi Shimokawa
5  * Copyright (c) 1998-2002 Katsushi Kobayashi and Hidetoshi Shimokawa
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  * 3. All advertising materials mentioning features or use of this software
17  *    must display the acknowledgement as bellow:
18  *
19  *    This product includes software developed by K. Kobayashi and H. Shimokawa
20  *
21  * 4. The name of the author may not be used to endorse or promote products
22  *    derived from this software without specific prior written permission.
23  *
24  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
25  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
26  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
27  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
28  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
29  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
30  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
32  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
33  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34  * POSSIBILITY OF SUCH DAMAGE.
35  *
36  * $FreeBSD$
37  *
38  */
39 
40 #ifndef _FIREWIRE_H
41 #define _FIREWIRE_H 1
42 
43 #define	DEV_DEF  0
44 #define	DEV_DV   2
45 
46 struct fw_isochreq {
47 	unsigned char ch:6;
48 	unsigned char tag:2;
49 };
50 
51 struct fw_isobufreq {
52 	struct fw_bufspec {
53 		unsigned int nchunk;
54 		unsigned int npacket;
55 		unsigned int psize;
56 	} tx, rx;
57 };
58 
59 struct fw_addr {
60 	uint32_t hi;
61 	uint32_t lo;
62 };
63 
64 struct fw_asybindreq {
65 	struct fw_addr start;
66 	unsigned long len;
67 };
68 
69 struct fw_reg_req_t {
70 	uint32_t addr;
71 	uint32_t data;
72 };
73 
74 #define MAXREC(x)	(2 << (x))
75 #define FWPMAX_S400 (2048 + 20)	/* MAXREC plus space for control data */
76 #define FWMAXQUEUE 128
77 
78 #define	FWLOCALBUS	0xffc0
79 
80 #define FWTCODE_WREQQ	0
81 #define FWTCODE_WREQB	1
82 #define FWTCODE_WRES	2
83 #define FWTCODE_RREQQ	4
84 #define FWTCODE_RREQB	5
85 #define FWTCODE_RRESQ	6
86 #define FWTCODE_RRESB	7
87 #define FWTCODE_CYCS	8
88 #define FWTCODE_LREQ	9
89 #define FWTCODE_STREAM	0xa
90 #define FWTCODE_LRES	0xb
91 #define FWTCODE_PHY	0xe
92 
93 #define	FWRETRY_1	0
94 #define	FWRETRY_X	1
95 #define	FWRETRY_A	2
96 #define	FWRETRY_B	3
97 
98 #define FWRCODE_COMPLETE	0
99 #define FWRCODE_ER_CONFL	4
100 #define FWRCODE_ER_DATA		5
101 #define FWRCODE_ER_TYPE		6
102 #define FWRCODE_ER_ADDR		7
103 
104 /*
105  * Defined 1394a-2000
106  * Table 5B-1
107  */
108 #define FWSPD_S100	0
109 #define FWSPD_S200	1
110 #define FWSPD_S400	2
111 #define FWSPD_S800	3
112 #define FWSPD_S1600	4
113 #define FWSPD_S3200	5
114 
115 #define	FWP_TL_VALID (1 << 7)
116 
117 struct fw_isohdr {
118 	uint32_t hdr[1];
119 };
120 
121 struct fw_asyhdr {
122 	uint32_t hdr[4];
123 };
124 
125 #if BYTE_ORDER == BIG_ENDIAN
126 #define BIT4x2(x,y)	 uint8_t  x:4, y:4
127 #define BIT16x2(x,y)	uint32_t x:16, y:16
128 #else
129 #define BIT4x2(x,y)	 uint8_t  y:4, x:4
130 #define BIT16x2(x,y)	uint32_t y:16, x:16
131 #endif
132 
133 
134 #if BYTE_ORDER == BIG_ENDIAN
135 #define COMMON_HDR(a,b,c,d)	uint32_t a:16,b:8,c:4,d:4
136 #define COMMON_RES(a,b,c,d)	uint32_t a:16,b:4,c:4,d:8
137 #else
138 #define COMMON_HDR(a,b,c,d)	uint32_t d:4,c:4,b:8,a:16
139 #define COMMON_RES(a,b,c,d)	uint32_t d:8,c:4,b:4,a:16
140 #endif
141 
142 struct fw_pkt {
143 	union {
144 		uint32_t ld[0];
145 		struct {
146 			COMMON_HDR(, , tcode, );
147 		} common;
148 		struct {
149 			COMMON_HDR(len, chtag, tcode, sy);
150 			uint32_t payload[0];
151 		} stream;
152 		struct {
153 			COMMON_HDR(dst, tlrt, tcode, pri);
154 			BIT16x2(src, );
155 		} hdr;
156 		struct {
157 			COMMON_HDR(dst, tlrt, tcode, pri);
158 			BIT16x2(src, dest_hi);
159 			uint32_t dest_lo;
160 		} rreqq;
161 		struct {
162 			COMMON_HDR(dst, tlrt, tcode, pri);
163 			COMMON_RES(src, rtcode, , );
164 			uint32_t :32;
165 		} wres;
166 		struct {
167 			COMMON_HDR(dst, tlrt, tcode, pri);
168 			BIT16x2(src, dest_hi);
169 			uint32_t dest_lo;
170 			BIT16x2(len, extcode);
171 		} rreqb;
172 		struct {
173 			COMMON_HDR(dst, tlrt, tcode, pri);
174 			BIT16x2(src, dest_hi);
175 			uint32_t dest_lo;
176 			uint32_t data;
177 		} wreqq;
178 		struct {
179 			COMMON_HDR(dst, tlrt, tcode, pri);
180 			BIT16x2(src, dest_hi);
181 			uint32_t dest_lo;
182 			uint32_t data;
183 		} cyc;
184 		struct {
185 			COMMON_HDR(dst, tlrt, tcode, pri);
186 			COMMON_RES(src, rtcode, , );
187 			uint32_t :32;
188 			uint32_t data;
189 		} rresq;
190 		struct {
191 			COMMON_HDR(dst, tlrt, tcode, pri);
192 			BIT16x2(src, dest_hi);
193 			uint32_t dest_lo;
194 			BIT16x2(len, extcode);
195 			uint32_t payload[0];
196 		} wreqb;
197 		struct {
198 			COMMON_HDR(dst, tlrt, tcode, pri);
199 			BIT16x2(src, dest_hi);
200 			uint32_t dest_lo;
201 			BIT16x2(len, extcode);
202 			uint32_t payload[0];
203 		} lreq;
204 		struct {
205 			COMMON_HDR(dst, tlrt, tcode, pri);
206 			COMMON_RES(src, rtcode, , );
207 			uint32_t :32;
208 			BIT16x2(len, extcode);
209 			uint32_t payload[0];
210 		} rresb;
211 		struct {
212 			COMMON_HDR(dst, tlrt, tcode, pri);
213 			COMMON_RES(src, rtcode, , );
214 			uint32_t :32;
215 			BIT16x2(len, extcode);
216 			uint32_t payload[0];
217 		} lres;
218 	} mode;
219 };
220 
221 /*
222  * Response code (rtcode)
223  */
224 /* The node has successfully completed the command. */
225 #define	RESP_CMP		0
226 /* A resource conflict was detected. The request may be retried. */
227 #define	RESP_CONFLICT_ERROR	4
228 /* Hardware error, data is unavailable. */
229 #define	RESP_DATA_ERROR		5
230 /* A field in the request packet header was set to an unsupported or incorrect
231  * value, or an invalid transaction was attempted (e.g., a write to a read-only
232  * address). */
233 #define	RESP_TYPE_ERROR		6
234 /* The destination offset field in the request was set to an address not
235  * accessible in the destination node. */
236 #define	RESP_ADDRESS_ERROR	7
237 
238 /*
239  * Extended transaction code (extcode)
240  */
241 #define EXTCODE_MASK_SWAP	1
242 #define EXTCODE_CMP_SWAP	2
243 #define EXTCODE_FETCH_ADD	3
244 #define EXTCODE_LITTLE_ADD	4
245 #define EXTCODE_BOUNDED_ADD	5
246 #define EXTCODE_WRAP_ADD	6
247 
248 struct fw_eui64 {
249 	uint32_t hi, lo;
250 };
251 #define FW_EUI64_BYTE(eui, x) \
252 	((((x) < 4)?				\
253 		((eui)->hi >> (8 * (3 - (x)))): \
254 		((eui)->lo >> (8 * (7 - (x))))	\
255 	) & 0xff)
256 #define FW_EUI64_EQUAL(x, y) \
257 	((x).hi == (y).hi && (x).lo == (y).lo)
258 
259 struct fw_asyreq {
260 	struct fw_asyreq_t {
261 		unsigned char sped;
262 		unsigned int type;
263 #define FWASREQNODE	0
264 #define FWASREQEUI	1
265 #define FWASRESTL	2
266 #define FWASREQSTREAM	3
267 		unsigned short len;
268 		union {
269 			struct fw_eui64 eui;
270 		} dst;
271 	} req;
272 	struct fw_pkt pkt;
273 	uint32_t data[512];
274 };
275 
276 struct fw_devinfo {
277 	struct fw_eui64 eui;
278 	uint16_t dst;
279 	uint16_t status;
280 };
281 
282 #define FW_MAX_DEVLST 70
283 struct fw_devlstreq {
284 	uint16_t n;
285 	uint16_t info_len;
286 	struct fw_devinfo dev[FW_MAX_DEVLST];
287 };
288 
289 /*
290  * Defined in IEEE 1394a-2000
291  * 4.3.4.1
292  */
293 #define FW_SELF_ID_PORT_CONNECTED_TO_CHILD 3
294 #define FW_SELF_ID_PORT_CONNECTED_TO_PARENT 2
295 #define FW_SELF_ID_PORT_NOT_CONNECTED 1
296 #define FW_SELF_ID_PORT_NOT_EXISTS 0
297 
298 #define FW_SELF_ID_PAGE0 0
299 #define FW_SELF_ID_PAGE1 1
300 
301 #if BYTE_ORDER == BIG_ENDIAN
302 union fw_self_id {
303 	struct {
304 		uint32_t  id:2,
305 			  phy_id:6,
306 			  sequel:1,
307 			  link_active:1,
308 			  gap_count:6,
309 			  phy_speed:2,
310 			  reserved:2,
311 			  contender:1,
312 			  power_class:3,
313 			  port0:2,
314 			  port1:2,
315 			  port2:2,
316 			  initiated_reset:1,
317 			  more_packets:1;
318 	} p0;
319 	struct {
320 		uint32_t
321 			  id:2,
322 			  phy_id:6,
323 			  sequel:1,
324 			  sequence_num:3,
325 			  reserved2:2,
326 			  port3:2,
327 			  port4:2,
328 			  port5:2,
329 			  port6:2,
330 			  port7:2,
331 			  port8:2,
332 			  port9:2,
333 			  port10:2,
334 			  reserved1:1,
335 			  more_packets:1;
336 	} p1;
337 	struct {
338 		uint32_t
339 			  id:2,
340 			  phy_id:6,
341 			  sequel:1,
342 			  sequence_num:3,
343 			  :2,
344 			  port11:2,
345 			  port12:2,
346 			  port13:2,
347 			  port14:2,
348 			  port15:2,
349 			  :8;
350 	} p2;
351 };
352 #else
353 union fw_self_id {
354 	struct {
355 		uint32_t  more_packets:1,
356 			  initiated_reset:1,
357 			  port2:2,
358 			  port1:2,
359 			  port0:2,
360 			  power_class:3,
361 			  contender:1,
362 			  reserved:2,
363 			  phy_speed:2,
364 			  gap_count:6,
365 			  link_active:1,
366 			  sequel:1,
367 			  phy_id:6,
368 			  id:2;
369 	} p0;
370 	struct {
371 		uint32_t  more_packets:1,
372 			  reserved1:1,
373 			  port10:2,
374 			  port9:2,
375 			  port8:2,
376 			  port7:2,
377 			  port6:2,
378 			  port5:2,
379 			  port4:2,
380 			  port3:2,
381 			  reserved2:2,
382 			  sequence_num:3,
383 			  sequel:1,
384 			  phy_id:6,
385 			  id:2;
386 	} p1;
387 	struct {
388 		uint32_t
389 			  reserved3:8,
390 			  port15:2,
391 			  port14:2,
392 			  port13:2,
393 			  port12:2,
394 			  port11:2,
395 			  reserved4:2,
396 			  sequence_num:3,
397 			  sequel:1,
398 			  phy_id:6,
399 			  id:2;
400 	} p2;
401 };
402 #endif
403 
404 
405 struct fw_topology_map {
406 	uint32_t crc:16,
407 		 crc_len:16;
408 	uint32_t generation;
409 	uint32_t self_id_count:16,
410 		 node_count:16;
411 	union fw_self_id self_id[4 * 64];
412 };
413 
414 struct fw_speed_map {
415 	uint32_t crc:16,
416 		 crc_len:16;
417 	uint32_t generation;
418 	uint8_t  speed[64][64];
419 };
420 
421 struct fw_crom_buf {
422 	struct fw_eui64 eui;
423 	uint32_t len;
424 	void *ptr;
425 };
426 
427 /*
428  * FireWire specific system requests.
429  */
430 #define	FW_SSTBUF	_IOWR('S', 86, struct fw_isobufreq)
431 #define	FW_GSTBUF	_IOWR('S', 87, struct fw_isobufreq)
432 #define	FW_SRSTREAM	_IOWR('S', 88, struct fw_isochreq)
433 #define	FW_GRSTREAM	_IOWR('S', 89, struct fw_isochreq)
434 #define	FW_STSTREAM	_IOWR('S', 90, struct fw_isochreq)
435 #define	FW_GTSTREAM	_IOWR('S', 91, struct fw_isochreq)
436 
437 #define	FW_ASYREQ	_IOWR('S', 92, struct fw_asyreq)
438 #define FW_IBUSRST	_IOR('S', 1, unsigned int)
439 #define FW_GDEVLST	_IOWR('S', 2, struct fw_devlstreq)
440 #define	FW_SBINDADDR	_IOWR('S', 3, struct fw_asybindreq)
441 #define	FW_CBINDADDR	_IOWR('S', 4, struct fw_asybindreq)
442 #define	FW_GTPMAP	_IOR('S', 5, struct fw_topology_map)
443 #define	FW_GCROM	_IOWR('S', 7, struct fw_crom_buf)
444 
445 #define	FW_SDEUI64	_IOW('S', 20, struct fw_eui64)
446 #define	FW_GDEUI64	_IOR('S', 21, struct fw_eui64)
447 
448 #define FWOHCI_RDREG	_IOWR('S', 80, struct fw_reg_req_t)
449 #define FWOHCI_WRREG	_IOWR('S', 81, struct fw_reg_req_t)
450 #define FWOHCI_RDPHYREG	_IOWR('S', 82, struct fw_reg_req_t)
451 #define FWOHCI_WRPHYREG	_IOWR('S', 83, struct fw_reg_req_t)
452 
453 #define DUMPDMA		_IOWR('S', 82, uint32_t)
454 
455 #ifdef _KERNEL
456 
457 #define FWMAXNDMA 0x100 /* 8 bits DMA channel id. in device No. */
458 
459 #define MAKEMINOR(f, u, s)	\
460 	((f) | (((u) & 0xff) << 8) | (s & 0xff))
461 #define DEV2UNIT(x)	((dev2unit(x) & 0xff00) >> 8)
462 #define DEV2SUB(x)	(dev2unit(x) & 0xff)
463 
464 #define FWMEM_FLAG	0x10000
465 #define DEV_FWMEM(x)	(dev2unit(x) & FWMEM_FLAG)
466 #endif
467 #endif
468