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 */
37108432Ssimokawa
38114215Ssimokawa#define	STATE_CLEAR	0x0000
39114215Ssimokawa#define	STATE_SET	0x0004
40114215Ssimokawa#define	NODE_IDS	0x0008
41114215Ssimokawa#define	RESET_START	0x000c
42114215Ssimokawa#define	SPLIT_TIMEOUT_HI	0x0018
43114215Ssimokawa#define	SPLIT_TIMEOUT_LO	0x001c
44114215Ssimokawa#define	CYCLE_TIME	0x0200
45114215Ssimokawa#define	BUS_TIME	0x0204
46114215Ssimokawa#define	BUSY_TIMEOUT	0x0210
47114215Ssimokawa#define	PRIORITY_BUDGET 0x0218
48114215Ssimokawa#define	BUS_MGR_ID	0x021c
49114215Ssimokawa#define	BANDWIDTH_AV	0x0220
50114215Ssimokawa#define	CHANNELS_AV_HI	0x0224
51114215Ssimokawa#define	CHANNELS_AV_LO	0x0228
52114215Ssimokawa#define	IP_CHANNELS	0x0234
53114215Ssimokawa
54114215Ssimokawa#define	CONF_ROM	0x0400
55114215Ssimokawa
56114215Ssimokawa#define	TOPO_MAP	0x1000
57114215Ssimokawa#define	SPED_MAP	0x2000
58114215Ssimokawa
59108432Ssimokawa#define CSRTYPE_SHIFT	6
60108432Ssimokawa#define CSRTYPE_MASK	(3 << CSRTYPE_SHIFT)
61108432Ssimokawa#define CSRTYPE_I	(0 << CSRTYPE_SHIFT) /* Immediate */
62108432Ssimokawa#define CSRTYPE_C	(1 << CSRTYPE_SHIFT) /* CSR offset */
63108432Ssimokawa#define CSRTYPE_L	(2 << CSRTYPE_SHIFT) /* Leaf */
64108432Ssimokawa#define CSRTYPE_D	(3 << CSRTYPE_SHIFT) /* Directory */
65108432Ssimokawa
66116373Ssimokawa/*
67116373Ssimokawa * CSR keys
68116373Ssimokawa * 00 - 2F: defined by CSR architecture standards.
69116373Ssimokawa * 30 - 37: defined by BUS starndards
70116373Ssimokawa * 38 - 3F: defined by Vendor/Specifier
71116373Ssimokawa */
72108432Ssimokawa#define CSRKEY_MASK	0x3f
73108432Ssimokawa#define CSRKEY_DESC	0x01 /* Descriptor */
74108432Ssimokawa#define CSRKEY_BDINFO	0x02 /* Bus_Dependent_Info */
75108432Ssimokawa#define CSRKEY_VENDOR	0x03 /* Vendor */
76108432Ssimokawa#define CSRKEY_HW	0x04 /* Hardware_Version */
77108432Ssimokawa#define CSRKEY_MODULE	0x07 /* Module */
78108432Ssimokawa#define CSRKEY_NCAP	0x0c /* Node_Capabilities */
79108432Ssimokawa#define CSRKEY_EUI64	0x0d /* EUI_64 */
80108432Ssimokawa#define CSRKEY_UNIT	0x11 /* Unit */
81108432Ssimokawa#define CSRKEY_SPEC	0x12 /* Specifier_ID */
82108432Ssimokawa#define CSRKEY_VER	0x13 /* Version */
83108432Ssimokawa#define CSRKEY_DINFO	0x14 /* Dependent_Info */
84108432Ssimokawa#define CSRKEY_ULOC	0x15 /* Unit_Location */
85108432Ssimokawa#define CSRKEY_MODEL	0x17 /* Model */
86108432Ssimokawa#define CSRKEY_INST	0x18 /* Instance */
87108432Ssimokawa#define CSRKEY_KEYW	0x19 /* Keyword */
88108432Ssimokawa#define CSRKEY_FEAT	0x1a /* Feature */
89108432Ssimokawa#define CSRKEY_EROM	0x1b /* Extended_ROM */
90108432Ssimokawa#define CSRKEY_EKSID	0x1c /* Extended_Key_Specifier_ID */
91108432Ssimokawa#define CSRKEY_EKEY	0x1d /* Extended_Key */
92108432Ssimokawa#define CSRKEY_EDATA	0x1e /* Extended_Data */
93108432Ssimokawa#define CSRKEY_MDESC	0x1f /* Modifiable_Descriptor */
94108432Ssimokawa#define CSRKEY_DID	0x20 /* Directory_ID */
95108432Ssimokawa#define CSRKEY_REV	0x21 /* Revision */
96108432Ssimokawa
97129541Sdfr#define CSRKEY_FIRM_VER	0x3c /* Firmware version */
98113584Ssimokawa#define CSRKEY_UNIT_CH	0x3a /* Unit characteristics */
99113584Ssimokawa#define CSRKEY_COM_SPEC	0x38 /* Command set revision */
100113584Ssimokawa#define CSRKEY_COM_SET	0x39 /* Command set */
101108432Ssimokawa
102113584Ssimokawa#define CROM_UDIR	(CSRTYPE_D | CSRKEY_UNIT)  /* 0x81 Unit directory */
103113584Ssimokawa#define CROM_TEXTLEAF	(CSRTYPE_L | CSRKEY_DESC)  /* 0x81 Text leaf */
104113584Ssimokawa#define CROM_LUN	(CSRTYPE_I | CSRKEY_DINFO) /* 0x14 Logical unit num. */
105113584Ssimokawa#define CROM_MGM	(CSRTYPE_C | CSRKEY_DINFO) /* 0x54 Management agent */
106108432Ssimokawa
107116373Ssimokawa#define CSRVAL_VENDOR_PRIVATE	0xacde48
108113584Ssimokawa#define CSRVAL_1394TA	0x00a02d
109113584Ssimokawa#define CSRVAL_ANSIT10	0x00609e
110113584Ssimokawa#define CSRVAL_IETF	0x00005e
111103285Sikob
112113584Ssimokawa#define CSR_PROTAVC	0x010001
113113584Ssimokawa#define CSR_PROTCAL	0x010002
114113584Ssimokawa#define CSR_PROTEHS	0x010004
115113584Ssimokawa#define CSR_PROTHAVI	0x010008
116113584Ssimokawa#define CSR_PROTCAM104	0x000100
117113584Ssimokawa#define CSR_PROTCAM120	0x000101
118113584Ssimokawa#define CSR_PROTCAM130	0x000102
119113584Ssimokawa#define CSR_PROTDPP	0x0a6be2
120113584Ssimokawa#define CSR_PROTIICP	0x4b661f
121103285Sikob
122113584Ssimokawa#define CSRVAL_T10SBP2	0x010483
123113584Ssimokawa#define CSRVAL_SCSI	0x0104d8
124113584Ssimokawa
125103285Sikobstruct csrreg {
126113584Ssimokawa#if BYTE_ORDER == BIG_ENDIAN
127129585Sdfr	uint32_t key:8,
128129585Sdfr		 val:24;
129113584Ssimokawa#else
130129585Sdfr	uint32_t val:24,
131129585Sdfr		 key:8;
132113584Ssimokawa#endif
133103285Sikob};
134103285Sikobstruct csrhdr {
135113584Ssimokawa#if BYTE_ORDER == BIG_ENDIAN
136129585Sdfr	uint32_t info_len:8,
137129585Sdfr		 crc_len:8,
138129585Sdfr		 crc:16;
139113584Ssimokawa#else
140129585Sdfr	uint32_t crc:16,
141129585Sdfr		 crc_len:8,
142129585Sdfr		 info_len:8;
143113584Ssimokawa#endif
144103285Sikob};
145103285Sikobstruct csrdirectory {
146113584Ssimokawa	BIT16x2(crc_len, crc);
147103285Sikob	struct csrreg entry[0];
148103285Sikob};
149103285Sikobstruct csrtext {
150113584Ssimokawa	BIT16x2(crc_len, crc);
151113584Ssimokawa#if BYTE_ORDER == BIG_ENDIAN
152129585Sdfr	uint32_t spec_type:8,
153129585Sdfr		 spec_id:24;
154113584Ssimokawa#else
155129585Sdfr	uint32_t spec_id:24,
156129585Sdfr		 spec_type:8;
157113584Ssimokawa#endif
158129585Sdfr	uint32_t lang_id;
159129585Sdfr	uint32_t text[0];
160103285Sikob};
161113584Ssimokawa
162113584Ssimokawastruct bus_info {
163113584Ssimokawa#define	CSR_BUS_NAME_IEEE1394	0x31333934
164129585Sdfr	uint32_t bus_name;
165116140Ssimokawa#if BYTE_ORDER == BIG_ENDIAN
166129585Sdfr	uint32_t irmc:1,		/* iso. resource manager capable */
167129585Sdfr		 cmc:1,			/* cycle master capable */
168129585Sdfr		 isc:1,			/* iso. operation support */
169129585Sdfr		 bmc:1,			/* bus manager capable */
170129585Sdfr		 pmc:1,			/* power manager capable */
171129585Sdfr		 :3,
172129585Sdfr		 cyc_clk_acc:8,		/* 0 <= ppm <= 100 */
173129585Sdfr		 max_rec:4,		/* (2 << max_rec) bytes */
174129585Sdfr		 :2,
175129585Sdfr		 max_rom:2,
176129585Sdfr		 generation:4,
177129585Sdfr		 :1,
178129585Sdfr		 link_spd:3;
179116140Ssimokawa#else
180129585Sdfr	uint32_t link_spd:3,
181129585Sdfr		 :1,
182129585Sdfr		 generation:4,
183129585Sdfr		 max_rom:2,
184129585Sdfr		 :2,
185129585Sdfr		 max_rec:4,		/* (2 << max_rec) bytes */
186129585Sdfr		 cyc_clk_acc:8,		/* 0 <= ppm <= 100 */
187129585Sdfr		 :3,
188129585Sdfr		 pmc:1,			/* power manager capable */
189129585Sdfr		 bmc:1,			/* bus manager capable */
190129585Sdfr		 isc:1,			/* iso. operation support */
191129585Sdfr		 cmc:1,			/* cycle master capable */
192129585Sdfr		 irmc:1;		/* iso. resource manager capable */
193116140Ssimokawa#endif
194113584Ssimokawa	struct fw_eui64 eui64;
195103285Sikob};
196116140Ssimokawa/* max_rom */
197116140Ssimokawa#define MAXROM_4	0
198116140Ssimokawa#define MAXROM_64	1
199116140Ssimokawa#define MAXROM_1024	2
200108432Ssimokawa
201108432Ssimokawa#define CROM_MAX_DEPTH	10
202108432Ssimokawastruct crom_ptr {
203108432Ssimokawa	struct csrdirectory *dir;
204108432Ssimokawa	int index;
205108432Ssimokawa};
206108432Ssimokawa
207108432Ssimokawastruct crom_context {
208108432Ssimokawa	int depth;
209108432Ssimokawa	struct crom_ptr stack[CROM_MAX_DEPTH];
210108432Ssimokawa};
211108432Ssimokawa
212129585Sdfrvoid crom_init_context(struct crom_context *, uint32_t *);
213108432Ssimokawastruct csrreg *crom_get(struct crom_context *);
214108432Ssimokawavoid crom_next(struct crom_context *);
215108432Ssimokawavoid crom_parse_text(struct crom_context *, char *, int);
216129585Sdfruint16_t crom_crc(uint32_t *r, int);
217129585Sdfrstruct csrreg *crom_search_key(struct crom_context *, uint8_t);
218129585Sdfrint crom_has_specver(uint32_t *, uint32_t, uint32_t);
219114069Ssimokawa
220136782Ssimokawa#if !defined(_KERNEL) && !defined(_BOOT)
221108432Ssimokawachar *crom_desc(struct crom_context *, char *, int);
222108432Ssimokawa#endif
223113584Ssimokawa
224113584Ssimokawa/* For CROM build */
225136782Ssimokawa#if defined(_KERNEL) || defined(_BOOT) || defined(TEST)
226113584Ssimokawa#define CROM_MAX_CHUNK_LEN 20
227113584Ssimokawastruct crom_src {
228113584Ssimokawa	struct csrhdr hdr;
229113584Ssimokawa	struct bus_info businfo;
230113584Ssimokawa	STAILQ_HEAD(, crom_chunk) chunk_list;
231113584Ssimokawa};
232113584Ssimokawa
233113584Ssimokawastruct crom_chunk {
234113584Ssimokawa	STAILQ_ENTRY(crom_chunk) link;
235113584Ssimokawa	struct crom_chunk *ref_chunk;
236113584Ssimokawa	int ref_index;
237113584Ssimokawa	int offset;
238113584Ssimokawa	struct {
239116433Ssimokawa		BIT16x2(crc_len, crc);
240129585Sdfr		uint32_t buf[CROM_MAX_CHUNK_LEN];
241113584Ssimokawa	} data;
242113584Ssimokawa};
243113584Ssimokawa
244129585Sdfrextern int crom_add_quad(struct crom_chunk *, uint32_t);
245113584Ssimokawaextern int crom_add_entry(struct crom_chunk *, int, int);
246113584Ssimokawaextern int crom_add_chunk(struct crom_src *src, struct crom_chunk *,
247113584Ssimokawa					struct crom_chunk *, int);
248113584Ssimokawaextern int crom_add_simple_text(struct crom_src *src, struct crom_chunk *,
249113584Ssimokawa					struct crom_chunk *, char *);
250129585Sdfrextern int crom_load(struct crom_src *, uint32_t *, int);
251113584Ssimokawa#endif
252