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
46struct fw_isochreq {
47	unsigned char ch:6;
48	unsigned char tag:2;
49};
50
51struct fw_isobufreq {
52	struct fw_bufspec {
53		unsigned int nchunk;
54		unsigned int npacket;
55		unsigned int psize;
56	} tx, rx;
57};
58
59struct fw_addr {
60	uint32_t hi;
61	uint32_t lo;
62};
63
64struct fw_asybindreq {
65	struct fw_addr start;
66	unsigned long len;
67};
68
69struct 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
117struct fw_isohdr {
118	uint32_t hdr[1];
119};
120
121struct 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
142struct 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
248struct 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
259struct 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
276struct fw_devinfo {
277	struct fw_eui64 eui;
278	uint16_t dst;
279	uint16_t status;
280};
281
282#define FW_MAX_DEVLST 70
283struct 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
302union 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
353union 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
405struct 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
414struct fw_speed_map {
415	uint32_t crc:16,
416		 crc_len:16;
417	uint32_t generation;
418	uint8_t  speed[64][64];
419};
420
421struct 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