1/*
2 * Copyright (c) 1998-2001 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License").  You may not use this file except in compliance with the
9 * License.  Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
11 *
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
17 * License for the specific language governing rights and limitations
18 * under the License.
19 *
20 * @APPLE_LICENSE_HEADER_END@
21 */
22#ifndef _IOKIT_IOFWIPDEFINITIONS_H
23#define _IOKIT_IOFWIPDEFINITIONS_H
24
25#include "IOFWController.h"
26
27struct FWUnsignedWideStruct{
28    UInt32	hi;
29    UInt32	lo;
30};
31
32typedef struct FWUnsignedWideStruct FWUnsignedWide;
33
34/* All the different platforms (and their development environments) have
35 slightly different type definition capitalization conventions, etc. This
36 section regularizes all that so that our source code may use uniform names */
37#define UNSIGNED	unsigned
38#define UWIDE		FWUnsignedWide
39
40/* Macros for convenience */
41#undef LAST
42#define LAST(array) ((sizeof(array) / sizeof(array[0])) - 1)
43
44#define BIT_SET(x)	(1 << x)
45
46/* Well known IPv4 & IPv6 multicast addresses */
47const UInt8 IPv4KnownMcastAddresses[5] =	{0x01, 0x00, 0x5E, 0x00, 0xE0};
48
49/* IPv6 well know multicast addresses Scope ID 0xFF 1, 2, 4, 5, 8, D */
50/* Solicited Multicast address FF 02::0:01:FFXX:XXXX */
51
52/*
53 * Miscellanaeous constants from IEEE Std 1394a-2000, ISO/IEC 13213:1994
54 * and RFC 2734.
55 */
56#define DEFAULT_BROADCAST_CHANNEL	31
57#define GASP_TAG					3
58#define LOCAL_BUS_ID				0x3FF
59
60#define ETHER_TYPE_MCAP				0x8861
61
62#define IP1394_SPEC_ID				0x00005E     /* Specifier_ID and ... */
63#define IP1394_VERSION				0x000001     /* ... Version values for unit directory */
64#define IP1394v6_VERSION			0x000002	/* ... Version values for unit directory */
65
66
67#define IPV4_ADDR_SIZE				4            /* Four octets (xxx.xxx.xxx.xxx) */
68#define IPV4_HDR_SIZE				20           /* Minimum size from RFC 791 */
69
70#define FW_M_BCAST		0x10
71#define FW_M_MCAST		0x20
72#define FW_M_UCAST		0x40
73#define FW_M_PKTHDR		0x02
74
75/* Encapsulation headers defined by RFC 2734. Unfragmented datagrams use a
76 short (one quadlet) encapsulation header that specifies the Ether type while
77 the headers for datagram fragments are two quadlets and contain total datagram
78 size and the position of the fragment within the datagram. When a datagram is
79 fragmented, the Ether type is present in the first fragment, only */
80
81typedef struct {                    /* Unfragmented encapsulation header*/
82   UInt16 reserved;                 /* Always zero for unfragmented datagram */
83   UInt16 etherType;                /* See RFC 1700 */
84} IP1394_UNFRAG_HDR;
85
86typedef struct {                    /* IP1394 encapsulation header */
87   UInt16 datagramSize;             /* Total size of the datagram, less one */
88   UInt16 fragmentOffset;           /* Second and subsequent fragments */
89   UInt16 dgl;                      /* Datagram label */
90   UInt16 reserved;
91} IP1394_FRAG_HDR;
92
93typedef union {
94   IP1394_UNFRAG_HDR singleFragment;
95   IP1394_FRAG_HDR fragment;
96} IP1394_ENCAP_HDR;
97
98/* NOTE: The link fragment type (lf) field is not shown above. It is the most
99 significant two bits of the encapsulation header, with values as follows. */
100typedef enum
101{
102	UNFRAGMENTED = 0,
103	FIRST_FRAGMENT,
104	LAST_FRAGMENT,
105	INTERIOR_FRAGMENT
106} FragmentType;
107
108/* IEEE Std 1394a-2000 defines a global asynchronous stream packet (GASP)
109 format that is used by RFC 2734 for the broadcast and multicast datagrams
110 and also for ARP and MCAP. The two-quadlet GASP header and its components
111 are specified below, along with an entire packet structure (as specified by
112 RFC 2734). */
113
114typedef struct {
115   UInt8 specifierID[3];      /* 24-bit RID (0x 00 005E) */
116   UInt8 version[3];          /* 24-bit version (0x00 00001) */
117} GASP_ID;
118
119typedef struct {
120   UInt16  sourceID;           /* 16-bit node ID of sender */
121   GASP_ID gaspID;
122} GASP_HDR;
123
124
125/* In those cases where the entire GASP is sent or received, firewire services automatically
126 alters the endian-ness of the first quadlet (packet header) while leaving the
127 data payload as is. This means that code that interprets that quadlet has to
128 account for the endian orientation of the CPU on which it executes. Hence
129 there are two flavors of the GASP type, one for big- and the other for
130 little-endian. */
131
132#if (BYTE_ORDER == BIG_ENDIAN)
133typedef struct {
134   UInt16	dataLength;
135   UInt8	channel;            /* Plus tag (in two most significant bits) */
136   UInt8	tCode;              /* Plus sy (in four least significant bits) */
137   GASP_HDR gaspHdr;			/* Two-quadlet GASP header */
138   IP1394_UNFRAG_HDR ip1394Hdr; /* Fragmentation not permitted! */
139} GASP;
140#else
141typedef struct {
142   UInt8	tCode;              /* Plus sy (in four least significant bits) */
143   UInt8	channel;            /* Plus tag (in two most significant bits) */
144   UInt16	dataLength;
145   GASP_HDR gaspHdr;			/* Two-quadlet GASP header */
146   IP1394_UNFRAG_HDR ip1394Hdr; /* Fragmentation not permitted! */
147} GASP;
148#endif
149
150/* ARP message format defined by RFC 2734. When transmitted, it is preceded by
151 an encapsulation header (one quadlet), whichis itself preceded by a GASP
152 header (two quadlets). */
153
154typedef struct {
155   UInt16	hardwareType;        /* Constant 0x0018 for Serial Bus */
156   UInt16	protocolType;        /* Constant 0x0800 for Serial Bus ARP */
157   UInt8	hwAddrLen;           /* "Hardware address" length */
158   UInt8	ipAddrLen;           /* IPv4 address length */
159   UInt16	opcode;              /* ARP request or response */
160   UWIDE	senderUniqueID;      /* EUI-64 from sender's bus information block */
161   UInt8	senderMaxRec;        /* Maximum payload (2 ** senderMaxRec) */
162   UInt8	sspd;                /* Maximum speed */
163   UInt16	senderUnicastFifoHi; /* Most significant 16 bits of FIFO address */
164   UInt32	senderUnicastFifoLo; /* Least significant 32 bits of FIFO address */
165   UInt32	senderIpAddress;     /* Sender's IPv4 address */
166   UInt32	targetIpAddress;     /* In ARP request, sought-after IPv4 address */
167} IP1394_ARP;
168
169/* NDP message format defined by RFC 3146. */
170struct ip1394_ndp {
171   UInt8	type;					/* type = 1 or 2 */
172   UInt8	len;					/* len in units of 8 octets */
173   UInt8	lladdr[kIOFWAddressSize];	/* EUI-64 from sender's bus information block */
174   UInt8	senderMaxRec;			/* Maximum payload (2 ** senderMaxRec) */
175   UInt8	sspd;					/* Maximum speed */
176   UInt16	senderUnicastFifoHi;	/* Most significant 16 bits of FIFO address */
177   UInt32	senderUnicastFifoLo;	/* Least significant 32 bits of FIFO address */
178   UInt8	reserved[6];			/* reserved by the RFC 3146 */
179} __attribute__((__packed__));
180
181typedef struct ip1394_ndp IP1394_NDP;
182
183#define ARP_HDW_TYPE			24       /* ARP hrd type assigned by IANA */
184
185/* The senderUniqueID, senderMaxRec, sspd and senderUnicastFifo fields in the
186 ARP message collectively make a link-level "hardware" aaddress for IP394. This
187 address is used in other contexts and its structure is given below. */
188
189typedef struct {              /* IP1394 "hardware" address */
190   UWIDE	eui64;            /* Node's EUI-64 (from bus information block) */
191   UInt8	maxRec;           /* Maximum asynchronous payload */
192   UInt8	spd;              /* Maximum speed */
193   UInt16	unicastFifoHi;    /* Most significant bits of unicast FIFO address */
194   UInt32	unicastFifoLo;    /* Least significant bits of unicast FIFO address */
195} IP1394_HDW_ADDR;
196
197/* Multicast channel allocation protocol (MCAP) message format defined by
198 RFC 2734. When transmitted, it is preceded by an encapsulation header (one
199 quadlet), whichis itself preceded by a GASP header (two quadlets). */
200
201typedef struct {
202   UInt8	length;             /* Total size of descriptor (bytes) */
203   UInt8	type;               /* Constant one (1) for MCAST_DESCR */
204   UInt16	reserved1;
205   UInt8	expiration;         /* For advertisements, lifespan remaining */
206   UInt8	channel;            /* Channel number for the group */
207   UInt8	speed;              /* Transmission speed for the group */
208   UInt8	reserved2;
209   UInt32	bandwidth;          /* Not yet utilized */
210   UInt32	groupAddress;		/* IPv4 multicast address */
211} MCAST_DESCR;
212
213#define MCAST_TYPE			1	/* IPv4 MCAST type */
214
215typedef struct {
216   UInt16	length;             /* Total length of MCAP message, in bytes */
217   UInt8	reserved;
218   UInt8	opcode;             /* Advertise or solicit */
219   MCAST_DESCR groupDescr[0];	/* Zero or more instances of MCAST_DESCR */
220} IP1394_MCAP;
221
222#define MCAP_ADVERTISE		0
223#define MCAP_SOLICIT		1
224
225/* The IP1394 code requires a stable "handle" to represent an internal
226 address (used analogously to Ethernet MAC addresses) for each IP address in
227 the ARP cache. The handle is twelve bytes long and has a different form for
228 unicast addresses (reachable via Serial Bus block write requests) and multi-
229 cast addresses (reachable via asynchronous stream packets) */
230
231typedef struct {				/* IP1394 "hardware" address */
232   void*	deviceID;			/* Stable reference to unit architecture */
233   UInt8	maxRec;             /* Maximum asynchronous payload */
234   UInt8	spd;                /* Maximum speed */
235   UInt16	unicastFifoHi;      /* Upper 16 bits of unicast FIFO address */
236   UInt32	unicastFifoLo;      /* Lower 32 bits of unicast FIFO address */
237} TNF_UNICAST_HANDLE;
238
239typedef struct {				/* IP1394 "hardware" address */
240   UInt32	deviceID;			/* Always zero */
241   UInt8	maxRec;				/* Maximum asynchronous payload */
242   UInt8	spd;				/* Maximum speed */
243   UInt8	reserved;
244   UInt8	channel;			/* Channel number for GASP transmit / receive */
245   UInt32	groupAddress;		/* Distinguish groups that share channel */
246} TNF_MULTICAST_HANDLE;
247
248typedef union {
249   TNF_UNICAST_HANDLE	unicast;
250   TNF_MULTICAST_HANDLE multicast;
251} TNF_HANDLE;
252
253struct arp_packet {
254	GASP_HDR gaspHdr;
255	IP1394_UNFRAG_HDR ip1394Hdr;
256	IP1394_ARP arp;
257};
258
259
260struct mcap_packet {
261	GASP_HDR gaspHdr;
262	IP1394_UNFRAG_HDR ip1394Hdr;
263	IP1394_MCAP mcap;
264};
265
266#if defined(__BIG_ENDIAN__)
267typedef struct {
268	UInt16 size;
269	UInt8  tag:2;
270	UInt8  chan:6;
271	UInt8  tcode:4;
272	UInt8  sy:4;
273} ISOC_DATA_PKT;
274#elif defined(__LITTLE_ENDIAN__)
275typedef struct {
276	UInt8  sy:4;
277	UInt8  tcode:4;
278	UInt8  chan:6;
279	UInt8  tag:2;
280	UInt16 size;
281} ISOC_DATA_PKT;
282#else
283#error host endian unknown
284#endif
285
286/* Multicast Address resolution block (ARB) contains all of the information necessary to
287 map, in either direction, between an IPv4 address and a link-level "hardware"
288 address
289 rfc2373 - section 2.7.2 notes that 32 bits are enough to identify unique IPv6 multicast
290		   addresses.
291 */
292
293class MARB : public OSObject		/* Used by both ARP 1394 and MCAP */
294{
295	OSDeclareDefaultStructors(MARB);
296public:
297	TNF_HANDLE	handle;         /* Pseudo "hardware" address used internally */
298};
299
300/* Address resolution block (ARB) contains all of the information necessary to
301 map, in either direction, between an IPv4 address and a link-level "hardware"
302 address */
303
304class ARB : public OSObject		/* Used by both ARP 1394 and MCAP */
305{
306	OSDeclareDefaultStructors(ARB);
307public:
308	UWIDE		eui64;          /* EUI-64 obtained from ARP response */
309	UInt8		fwaddr[kIOFWAddressSize];
310	TNF_HANDLE	handle;         /* Pseudo "hardware" address used internally */
311	bool		itsMac;   		/* Indicates whether the destination Macintosh or not */
312};
313
314/* Device reference block (DRB) correlates an EUI-64 with a IOFireWireNub
315 reference ID acquired with a kGUIDType parameter. A pointer to the LCB is
316 also part of the structure---because the address of a DRB is passed to a
317 bus reset notification procedure which in turn needs to reference the
318 relevant LCB. Note also the inclusion of a timer field; because node
319 removals may be temporary, the IP1394 code does NOT dispose of the device
320 reference as soon as the node disappears. Instead, an expiration timer is
321 started. If the device has not reappeared within the specified number of
322 seconds, then the device reference ID is released. */
323
324class DRB : public OSObject
325{
326	OSDeclareDefaultStructors(DRB);
327public:
328	UWIDE		eui64;			/* EUI-64 of the IP-capable device */
329	UInt8		fwaddr[kIOFWAddressSize];
330	void*		deviceID;		/* Stable "handle" for the IP-capable device */
331	UInt16		maxPayload;		/* Maximum payload and... */
332	IOFWSpeed	maxSpeed;		/* ...speed to device in current topology */
333	bool		itsMac;			/* Indicates whether the destination Macintosh or not */
334};
335
336/* Multicast control block (MCB) permits the management of multicast channel
337 assignments, whether we are the owner or simply one of the participants in
338 the multicast group. */
339
340class MCB : public OSObject
341{
342	OSDeclareDefaultStructors(MCB);
343public:
344   UInt32	ownerNodeID;         /* Channel owner (it may be us!) */
345   UInt32	groupCount;          /* IP address groups active (this channel )*/
346   OSObject *asyncStreamID;
347   UInt8	channel;             /* Redundant (but makes debug easier) */
348   UInt8	expiration;          /* Seconds remaining in valid channel mapping */
349   UInt8	nextTransmit;        /* Seconds 'til MCAP advertisement transmitted */
350   UInt8	finalWarning;        /* Channel deallocation warning messages */
351};
352
353#define MCAP_UNOWNED 0        /* No channel owner */
354
355/* Reassembly control block (RCB) tracks the progress of the entire datagram
356 as fragments arrive. The algorithm is simple---primitive even---but adequate
357 for the unconfirmed nature of IP datagrams. When one of the fragments first
358 arrives, an MBUF adequate to hold the entire datagram is allocated and the
359 fragment is copied to its correct location; the residual count is decremented.
360 This process repeats with successive fragments until residual is zero. */
361class RCB : public IOCommand
362{
363	OSDeclareDefaultStructors(RCB);
364
365private:
366    void free();
367
368public:
369	UInt16	sourceID;           /* Saved from LK_DATA.indication */
370	UInt16	dgl;                /* Obtained from the fragment header */
371	UInt16	etherType;          /* Saved from first fraagment header */
372	UInt16	datagramSize;       /* Total size of the reassembled datagram */
373	UInt16	residual;           /* Bytes still outstanding */
374	UInt32  timer;				/* If nonzero, decrement and release upon zero */
375	mbuf_t	mBuf;				/* MBUF eventually passed to OS code */
376
377	void reinit(UInt16 id, UInt16 label, UInt16 etherType, UInt16 size, mbuf_t m);
378};
379
380/* End of the type definitions for the miscellaneous control structures */
381
382/* Link control block (LCB) used to maintain context for IOFireWireIP routines for a
383 single link instance. The ARP and MCAP caches are also referenced by this
384 structure. */
385typedef struct lcb /* Link Control Block (LCB) for each link */
386{
387   IP1394_HDW_ADDR	ownHardwareAddress; /* Our external address on Serial Bus */
388   UInt16			ownMaxPayload;      /* From this link's bus information block */
389   UInt16			ownMaxSpeed;        /* Link/PHY hardware capability */
390   UInt16			ownNodeID;          /* Management information, only */
391   UInt16			maxBroadcastPayload;/* Updated when topology changes */
392   IOFWSpeed		maxBroadcastSpeed;  /* Ditto */
393   UInt16			datagramLabel;
394   UInt32			busGeneration;      /* Current as of most recent bus reset */
395} LCB;
396
397#endif /* _IOKIT_IOFWIPDEFINITIONS_H */
398