1139749Simp/*-
2113584Ssimokawa * Copyright (c) 2003 Hidetoshi Shimokawa
3103285Sikob * Copyright (c) 1998-2002 Katsushi Kobayashi and Hidetoshi Shimokawa
4103285Sikob * All rights reserved.
5103285Sikob *
6103285Sikob * Redistribution and use in source and binary forms, with or without
7103285Sikob * modification, are permitted provided that the following conditions
8103285Sikob * are met:
9103285Sikob * 1. Redistributions of source code must retain the above copyright
10103285Sikob *    notice, this list of conditions and the following disclaimer.
11103285Sikob * 2. Redistributions in binary form must reproduce the above copyright
12103285Sikob *    notice, this list of conditions and the following disclaimer in the
13103285Sikob *    documentation and/or other materials provided with the distribution.
14103285Sikob * 3. All advertising materials mentioning features or use of this software
15103285Sikob *    must display the acknowledgement as bellow:
16103285Sikob *
17103285Sikob *    This product includes software developed by K. Kobayashi and H. Shimokawa
18103285Sikob *
19103285Sikob * 4. The name of the author may not be used to endorse or promote products
20103285Sikob *    derived from this software without specific prior written permission.
21103285Sikob *
22103285Sikob * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23103285Sikob * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
24103285Sikob * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
25103285Sikob * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
26103285Sikob * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
27103285Sikob * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
28103285Sikob * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29103285Sikob * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
30103285Sikob * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31103285Sikob * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32103285Sikob * POSSIBILITY OF SUCH DAMAGE.
33103285Sikob *
34103285Sikob * $FreeBSD$
35103285Sikob *
36103285Sikob */
37103285Sikob
38103285Sikob#ifndef _FIREWIRE_H
39103285Sikob#define _FIREWIRE_H 1
40103285Sikob
41103285Sikob#define	DEV_DEF  0
42103285Sikob#define	DEV_DV   2
43103285Sikob
44103285Sikobstruct fw_isochreq {
45103285Sikob	unsigned char	ch:6,
46103285Sikob			tag:2;
47103285Sikob};
48103285Sikob
49103285Sikobstruct fw_isobufreq {
50118293Ssimokawa	struct fw_bufspec {
51103285Sikob		unsigned int nchunk;
52103285Sikob		unsigned int npacket;
53103285Sikob		unsigned int psize;
54103285Sikob	} tx, rx;
55103285Sikob};
56103285Sikob
57109801Ssimokawastruct fw_addr {
58129585Sdfr	uint32_t hi;
59129585Sdfr	uint32_t lo;
60103285Sikob};
61103285Sikob
62103285Sikobstruct fw_asybindreq {
63103285Sikob	struct fw_addr start;
64103285Sikob	unsigned long len;
65103285Sikob};
66103285Sikob
67109801Ssimokawastruct fw_reg_req_t {
68129585Sdfr	uint32_t addr;
69129585Sdfr	uint32_t data;
70103285Sikob};
71103285Sikob
72108701Ssimokawa#define MAXREC(x)	(2 << (x))
73103285Sikob#define FWPMAX_S400 (2048 + 20)	/* MAXREC plus space for control data */
74122216Ssimokawa#define FWMAXQUEUE 128
75103285Sikob
76103285Sikob#define	FWLOCALBUS	0xffc0
77103285Sikob
78103285Sikob#define FWTCODE_WREQQ	0
79103285Sikob#define FWTCODE_WREQB	1
80103285Sikob#define FWTCODE_WRES	2
81103285Sikob#define FWTCODE_RREQQ	4
82103285Sikob#define FWTCODE_RREQB	5
83103285Sikob#define FWTCODE_RRESQ	6
84103285Sikob#define FWTCODE_RRESB	7
85103285Sikob#define FWTCODE_CYCS	8
86103285Sikob#define FWTCODE_LREQ	9
87103285Sikob#define FWTCODE_STREAM	0xa
88103285Sikob#define FWTCODE_LRES	0xb
89103285Sikob#define FWTCODE_PHY	0xe
90103285Sikob
91103285Sikob#define	FWRETRY_1	0
92103285Sikob#define	FWRETRY_X	1
93103285Sikob#define	FWRETRY_A	2
94103285Sikob#define	FWRETRY_B	3
95103285Sikob
96103285Sikob#define FWRCODE_COMPLETE	0
97103285Sikob#define FWRCODE_ER_CONFL	4
98103285Sikob#define FWRCODE_ER_DATA		5
99103285Sikob#define FWRCODE_ER_TYPE		6
100103285Sikob#define FWRCODE_ER_ADDR		7
101103285Sikob
102188508Ssbruno/*
103188508Ssbruno * Defined 1394a-2000
104188508Ssbruno * Table 5B-1
105188508Ssbruno */
106103285Sikob#define FWSPD_S100	0
107103285Sikob#define FWSPD_S200	1
108103285Sikob#define FWSPD_S400	2
109188508Ssbruno#define FWSPD_S800	3
110188508Ssbruno#define FWSPD_S1600	4
111188508Ssbruno#define FWSPD_S3200	5
112103285Sikob
113103285Sikob#define	FWP_TL_VALID (1 << 7)
114103285Sikob
115109801Ssimokawastruct fw_isohdr {
116129585Sdfr	uint32_t hdr[1];
117103285Sikob};
118109801Ssimokawa
119109801Ssimokawastruct fw_asyhdr {
120129585Sdfr	uint32_t hdr[4];
121103285Sikob};
122109801Ssimokawa
123113584Ssimokawa#if BYTE_ORDER == BIG_ENDIAN
124129585Sdfr#define BIT4x2(x,y)	 uint8_t  x:4, y:4
125129585Sdfr#define BIT16x2(x,y)	uint32_t x:16, y:16
126113584Ssimokawa#else
127129585Sdfr#define BIT4x2(x,y)	 uint8_t  y:4, x:4
128129585Sdfr#define BIT16x2(x,y)	uint32_t y:16, x:16
129109801Ssimokawa#endif
130109801Ssimokawa
131113584Ssimokawa
132113584Ssimokawa#if BYTE_ORDER == BIG_ENDIAN
133129585Sdfr#define COMMON_HDR(a,b,c,d)	uint32_t a:16,b:8,c:4,d:4
134129585Sdfr#define COMMON_RES(a,b,c,d)	uint32_t a:16,b:4,c:4,d:8
135113584Ssimokawa#else
136129585Sdfr#define COMMON_HDR(a,b,c,d)	uint32_t d:4,c:4,b:8,a:16
137129585Sdfr#define COMMON_RES(a,b,c,d)	uint32_t d:8,c:4,b:4,a:16
138113584Ssimokawa#endif
139113584Ssimokawa
140109801Ssimokawastruct fw_pkt {
141109801Ssimokawa	union {
142129585Sdfr		uint32_t ld[0];
143103285Sikob		struct {
144113584Ssimokawa			COMMON_HDR(, , tcode, );
145109801Ssimokawa		} common;
146103285Sikob		struct {
147113584Ssimokawa			COMMON_HDR(len, chtag, tcode, sy);
148129585Sdfr			uint32_t payload[0];
149109801Ssimokawa		} stream;
150103285Sikob		struct {
151113584Ssimokawa			COMMON_HDR(dst, tlrt, tcode, pri);
152113584Ssimokawa			BIT16x2(src, );
153109801Ssimokawa		} hdr;
154103285Sikob		struct {
155113584Ssimokawa			COMMON_HDR(dst, tlrt, tcode, pri);
156113584Ssimokawa			BIT16x2(src, dest_hi);
157129585Sdfr			uint32_t dest_lo;
158109801Ssimokawa		} rreqq;
159103285Sikob		struct {
160113584Ssimokawa			COMMON_HDR(dst, tlrt, tcode, pri);
161113584Ssimokawa			COMMON_RES(src, rtcode, , );
162129585Sdfr			uint32_t :32;
163109801Ssimokawa		} wres;
164103285Sikob		struct {
165113584Ssimokawa			COMMON_HDR(dst, tlrt, tcode, pri);
166113584Ssimokawa			BIT16x2(src, dest_hi);
167129585Sdfr			uint32_t dest_lo;
168113584Ssimokawa			BIT16x2(len, extcode);
169109801Ssimokawa		} rreqb;
170103285Sikob		struct {
171113584Ssimokawa			COMMON_HDR(dst, tlrt, tcode, pri);
172113584Ssimokawa			BIT16x2(src, dest_hi);
173129585Sdfr			uint32_t dest_lo;
174129585Sdfr			uint32_t data;
175109801Ssimokawa		} wreqq;
176103285Sikob		struct {
177113584Ssimokawa			COMMON_HDR(dst, tlrt, tcode, pri);
178113584Ssimokawa			BIT16x2(src, dest_hi);
179129585Sdfr			uint32_t dest_lo;
180129585Sdfr			uint32_t data;
181109801Ssimokawa		} cyc;
182103285Sikob		struct {
183113584Ssimokawa			COMMON_HDR(dst, tlrt, tcode, pri);
184113584Ssimokawa			COMMON_RES(src, rtcode, , );
185129585Sdfr			uint32_t :32;
186129585Sdfr			uint32_t data;
187109801Ssimokawa		} rresq;
188103285Sikob		struct {
189113584Ssimokawa			COMMON_HDR(dst, tlrt, tcode, pri);
190113584Ssimokawa			BIT16x2(src, dest_hi);
191129585Sdfr			uint32_t dest_lo;
192113584Ssimokawa			BIT16x2(len, extcode);
193129585Sdfr			uint32_t payload[0];
194109801Ssimokawa		} wreqb;
195103285Sikob		struct {
196113584Ssimokawa			COMMON_HDR(dst, tlrt, tcode, pri);
197113584Ssimokawa			BIT16x2(src, dest_hi);
198129585Sdfr			uint32_t dest_lo;
199113584Ssimokawa			BIT16x2(len, extcode);
200129585Sdfr			uint32_t payload[0];
201109801Ssimokawa		} lreq;
202103285Sikob		struct {
203113584Ssimokawa			COMMON_HDR(dst, tlrt, tcode, pri);
204113584Ssimokawa			COMMON_RES(src, rtcode, , );
205129585Sdfr			uint32_t :32;
206113584Ssimokawa			BIT16x2(len, extcode);
207129585Sdfr			uint32_t payload[0];
208109801Ssimokawa		} rresb;
209103285Sikob		struct {
210113584Ssimokawa			COMMON_HDR(dst, tlrt, tcode, pri);
211113584Ssimokawa			COMMON_RES(src, rtcode, , );
212129585Sdfr			uint32_t :32;
213113584Ssimokawa			BIT16x2(len, extcode);
214129585Sdfr			uint32_t payload[0];
215109801Ssimokawa		} lres;
216109801Ssimokawa	} mode;
217103285Sikob};
218109801Ssimokawa
219120660Ssimokawa/*
220120660Ssimokawa * Response code (rtcode)
221120660Ssimokawa */
222120660Ssimokawa/* The node has successfully completed the command. */
223120660Ssimokawa#define	RESP_CMP		0
224120660Ssimokawa/* A resource conflict was detected. The request may be retried. */
225120660Ssimokawa#define	RESP_CONFLICT_ERROR	4
226120660Ssimokawa/* Hardware error, data is unavailable. */
227120660Ssimokawa#define	RESP_DATA_ERROR		5
228120660Ssimokawa/* A field in the request packet header was set to an unsupported or incorrect
229120660Ssimokawa * value, or an invalid transaction was attempted (e.g., a write to a read-only
230120660Ssimokawa * address). */
231120660Ssimokawa#define	RESP_TYPE_ERROR		6
232120660Ssimokawa/* The destination offset field in the request was set to an address not
233120660Ssimokawa * accessible in the destination node. */
234120660Ssimokawa#define	RESP_ADDRESS_ERROR	7
235120660Ssimokawa
236120660Ssimokawa/*
237120660Ssimokawa * Extended transaction code (extcode)
238120660Ssimokawa */
239120660Ssimokawa#define EXTCODE_MASK_SWAP	1
240120660Ssimokawa#define EXTCODE_CMP_SWAP	2
241120660Ssimokawa#define EXTCODE_FETCH_ADD	3
242120660Ssimokawa#define EXTCODE_LITTLE_ADD	4
243120660Ssimokawa#define EXTCODE_BOUNDED_ADD	5
244120660Ssimokawa#define EXTCODE_WRAP_ADD	6
245120660Ssimokawa
246103285Sikobstruct fw_eui64 {
247129585Sdfr	uint32_t hi, lo;
248103285Sikob};
249109814Ssimokawa#define FW_EUI64_BYTE(eui, x) \
250109814Ssimokawa	((((x)<4)?				\
251109814Ssimokawa		((eui)->hi >> (8*(3-(x)))): 	\
252109814Ssimokawa		((eui)->lo >> (8*(7-(x))))	\
253109814Ssimokawa	) & 0xff)
254110193Ssimokawa#define FW_EUI64_EQUAL(x, y) \
255110193Ssimokawa	((x).hi == (y).hi && (x).lo == (y).lo)
256109801Ssimokawa
257103285Sikobstruct fw_asyreq {
258103285Sikob	struct fw_asyreq_t{
259103285Sikob		unsigned char sped;
260103285Sikob		unsigned int type;
261103285Sikob#define FWASREQNODE	0
262103285Sikob#define FWASREQEUI	1
263103285Sikob#define FWASRESTL	2
264103285Sikob#define FWASREQSTREAM	3
265103285Sikob		unsigned short len;
266103285Sikob		union {
267103285Sikob			struct fw_eui64 eui;
268103285Sikob		}dst;
269103285Sikob	}req;
270103285Sikob	struct fw_pkt pkt;
271129585Sdfr	uint32_t data[512];
272103285Sikob};
273109801Ssimokawa
274109814Ssimokawastruct fw_devinfo {
275109814Ssimokawa	struct fw_eui64 eui;
276129585Sdfr	uint16_t dst;
277129585Sdfr	uint16_t status;
278109814Ssimokawa};
279109814Ssimokawa
280109814Ssimokawa#define FW_MAX_DEVLST 70
281103285Sikobstruct fw_devlstreq {
282129585Sdfr	uint16_t n;
283129585Sdfr	uint16_t info_len;
284109814Ssimokawa	struct fw_devinfo dev[FW_MAX_DEVLST];
285103285Sikob};
286109801Ssimokawa
287188585Ssbruno/*
288188585Ssbruno * Defined in IEEE 1394a-2000
289188585Ssbruno * 4.3.4.1
290188585Ssbruno */
291103285Sikob#define FW_SELF_ID_PORT_CONNECTED_TO_CHILD 3
292103285Sikob#define FW_SELF_ID_PORT_CONNECTED_TO_PARENT 2
293103285Sikob#define FW_SELF_ID_PORT_NOT_CONNECTED 1
294103285Sikob#define FW_SELF_ID_PORT_NOT_EXISTS 0
295188726Ssbruno
296188726Ssbruno#define FW_SELF_ID_PAGE0 0
297188726Ssbruno#define FW_SELF_ID_PAGE1 1
298188726Ssbruno
299113584Ssimokawa#if BYTE_ORDER == BIG_ENDIAN
300103285Sikobunion fw_self_id {
301103285Sikob	struct {
302129585Sdfr		uint32_t  id:2,
303113584Ssimokawa			  phy_id:6,
304113584Ssimokawa			  sequel:1,
305113584Ssimokawa			  link_active:1,
306113584Ssimokawa			  gap_count:6,
307113584Ssimokawa			  phy_speed:2,
308188726Ssbruno			  reserved:2,
309113584Ssimokawa			  contender:1,
310113584Ssimokawa			  power_class:3,
311113584Ssimokawa			  port0:2,
312113584Ssimokawa			  port1:2,
313113584Ssimokawa			  port2:2,
314113584Ssimokawa			  initiated_reset:1,
315113584Ssimokawa			  more_packets:1;
316113584Ssimokawa	} p0;
317113584Ssimokawa	struct {
318129585Sdfr		uint32_t
319113584Ssimokawa			  id:2,
320113584Ssimokawa			  phy_id:6,
321113584Ssimokawa			  sequel:1,
322113584Ssimokawa			  sequence_num:3,
323188585Ssbruno			  reserved2:2,
324188585Ssbruno			  port3:2,
325188585Ssbruno			  port4:2,
326188585Ssbruno			  port5:2,
327188585Ssbruno			  port6:2,
328188585Ssbruno			  port7:2,
329188585Ssbruno			  port8:2,
330188585Ssbruno			  port9:2,
331188585Ssbruno			  port10:2,
332188585Ssbruno			  reserved1:1,
333113584Ssimokawa			  more_packets:1;
334113584Ssimokawa	} p1;
335188585Ssbruno	struct {
336188585Ssbruno		uint32_t
337188585Ssbruno			  id:2,
338188585Ssbruno			  phy_id:6,
339188585Ssbruno			  sequel:1,
340188585Ssbruno			  sequence_num:3,
341188585Ssbruno			  :2,
342188585Ssbruno			  port11:2,
343188585Ssbruno			  port12:2,
344188585Ssbruno			  port13:2,
345188585Ssbruno			  port14:2,
346188585Ssbruno			  port15:2,
347188585Ssbruno			  :8;
348188585Ssbruno	} p2;
349113584Ssimokawa};
350113584Ssimokawa#else
351113584Ssimokawaunion fw_self_id {
352113584Ssimokawa	struct {
353129585Sdfr		uint32_t  more_packets:1,
354103285Sikob			  initiated_reset:1,
355103285Sikob			  port2:2,
356103285Sikob			  port1:2,
357103285Sikob			  port0:2,
358103285Sikob			  power_class:3,
359103285Sikob			  contender:1,
360188726Ssbruno			  reserved:2,
361103285Sikob			  phy_speed:2,
362103285Sikob			  gap_count:6,
363103285Sikob			  link_active:1,
364103285Sikob			  sequel:1,
365103285Sikob			  phy_id:6,
366103285Sikob			  id:2;
367103285Sikob	} p0;
368103285Sikob	struct {
369129585Sdfr		uint32_t  more_packets:1,
370103285Sikob			  reserved1:1,
371188585Ssbruno			  port10:2,
372188585Ssbruno			  port9:2,
373188585Ssbruno			  port8:2,
374188585Ssbruno			  port7:2,
375188585Ssbruno			  port6:2,
376188585Ssbruno			  port5:2,
377188585Ssbruno			  port4:2,
378188585Ssbruno			  port3:2,
379103285Sikob			  reserved2:2,
380103285Sikob			  sequence_num:3,
381103285Sikob			  sequel:1,
382103285Sikob			  phy_id:6,
383103285Sikob			  id:2;
384103285Sikob	} p1;
385188585Ssbruno	struct {
386188585Ssbruno		uint32_t
387188585Ssbruno			  reserved3:8,
388188585Ssbruno			  port15:2,
389188585Ssbruno			  port14:2,
390188585Ssbruno			  port13:2,
391188585Ssbruno			  port12:2,
392188585Ssbruno			  port11:2,
393188585Ssbruno			  reserved4:2,
394188585Ssbruno			  sequence_num:3,
395188585Ssbruno			  sequel:1,
396188585Ssbruno			  phy_id:6,
397188585Ssbruno			  id:2;
398188585Ssbruno	} p2;
399103285Sikob};
400109801Ssimokawa#endif
401109801Ssimokawa
402109801Ssimokawa
403103285Sikobstruct fw_topology_map {
404129585Sdfr	uint32_t crc:16,
405129585Sdfr		 crc_len:16;
406129585Sdfr	uint32_t generation;
407129585Sdfr	uint32_t self_id_count:16,
408129585Sdfr		 node_count:16;
409103285Sikob	union fw_self_id self_id[4*64];
410103285Sikob};
411109801Ssimokawa
412103285Sikobstruct fw_speed_map {
413129585Sdfr	uint32_t crc:16,
414129585Sdfr		 crc_len:16;
415129585Sdfr	uint32_t generation;
416129585Sdfr	uint8_t  speed[64][64];
417103285Sikob};
418109801Ssimokawa
419103285Sikobstruct fw_crom_buf {
420103285Sikob	struct fw_eui64 eui;
421169019Ssimokawa	uint32_t len;
422103285Sikob	void *ptr;
423103285Sikob};
424109801Ssimokawa
425103285Sikob/*
426108281Ssimokawa * FireWire specific system requests.
427103285Sikob */
428103285Sikob#define	FW_SSTBUF	_IOWR('S', 86, struct fw_isobufreq)
429103285Sikob#define	FW_GSTBUF	_IOWR('S', 87, struct fw_isobufreq)
430103285Sikob#define	FW_SRSTREAM	_IOWR('S', 88, struct fw_isochreq)
431103285Sikob#define	FW_GRSTREAM	_IOWR('S', 89, struct fw_isochreq)
432103285Sikob#define	FW_STSTREAM	_IOWR('S', 90, struct fw_isochreq)
433103285Sikob#define	FW_GTSTREAM	_IOWR('S', 91, struct fw_isochreq)
434103285Sikob
435103285Sikob#define	FW_ASYREQ	_IOWR('S', 92, struct fw_asyreq)
436103285Sikob#define FW_IBUSRST	_IOR('S', 1, unsigned int)
437103285Sikob#define FW_GDEVLST	_IOWR('S', 2, struct fw_devlstreq)
438103285Sikob#define	FW_SBINDADDR	_IOWR('S', 3, struct fw_asybindreq)
439103285Sikob#define	FW_CBINDADDR	_IOWR('S', 4, struct fw_asybindreq)
440103285Sikob#define	FW_GTPMAP	_IOR('S', 5, struct fw_topology_map)
441103285Sikob#define	FW_GCROM	_IOWR('S', 7, struct fw_crom_buf)
442103285Sikob
443110582Ssimokawa#define	FW_SDEUI64	_IOW('S', 20, struct fw_eui64)
444110582Ssimokawa#define	FW_GDEUI64	_IOR('S', 21, struct fw_eui64)
445110582Ssimokawa
446103285Sikob#define FWOHCI_RDREG	_IOWR('S', 80, struct fw_reg_req_t)
447103285Sikob#define FWOHCI_WRREG	_IOWR('S', 81, struct fw_reg_req_t)
448119118Ssimokawa#define FWOHCI_RDPHYREG	_IOWR('S', 82, struct fw_reg_req_t)
449119118Ssimokawa#define FWOHCI_WRPHYREG	_IOWR('S', 83, struct fw_reg_req_t)
450103285Sikob
451129585Sdfr#define DUMPDMA		_IOWR('S', 82, uint32_t)
452103285Sikob
453103285Sikob#ifdef _KERNEL
454103285Sikob
455103285Sikob#define FWMAXNDMA 0x100 /* 8 bits DMA channel id. in device No. */
456103285Sikob
457127468Ssimokawa#if defined(__DragonFly__) || __FreeBSD_version < 500000
458103285Sikob#define dev2unit(x)	((minor(x) & 0xff) | (minor(x) >> 8))
459103285Sikob#define unit2minor(x)	(((x) & 0xff) | (((x) << 8) & ~0xffff))
460103285Sikob#endif
461103285Sikob
462118455Ssimokawa#define MAKEMINOR(f, u, s)	\
463183397Sed	((f) | (((u) & 0xff) << 8) | (s & 0xff))
464103285Sikob#define DEV2UNIT(x)	((dev2unit(x) & 0xff00) >> 8)
465118293Ssimokawa#define DEV2SUB(x)	(dev2unit(x) & 0xff)
466103285Sikob
467103285Sikob#define FWMEM_FLAG	0x10000
468103285Sikob#define DEV_FWMEM(x)	(dev2unit(x) & FWMEM_FLAG)
469103285Sikob#endif
470103285Sikob#endif
471