/* -*-C-*-
 *
 * dcistructs.h - data structures used in the DCI interface
 *
 * Copyright (c) 1995 Acorn Computers Ltd., Cambridge, England
 *
 * :RCS Log discontinued:
 * Revision 1.11  95/10/11  12:17:56  pwain
 * Removed st_net_error from the stats structure.
 * This should have been removed a while back
 * according to Borris.
 *
 * Revision 1.10  95/09/18  13:24:06  kwelton
 * Added definitions for st_link_status (in stats structure) bits.
 *
 * Revision 1.9  95/09/07  13:00:16  kwelton
 * Added two new flags for virtual interfaces.
 *
 * Revision 1.8  95/03/21  14:10:46  kwelton
 * Added copy of Inquire flags to struct dib.  DCI version is now 4.03.
 *
 * Revision 1.7  95/03/16  14:19:39  kwelton
 * Added details of new InternetStatus service call.
 *
 * Revision 1.6  95/03/14  14:44:19  kwelton
 * DCI version is now 4.02
 *
 * Revision 1.5  95/03/01  12:12:31  kwelton
 * A few minor changes, plus the definition of the "standard" stats.
 * structure.
 *
 * Revision 1.4  95/02/03  15:27:47  kwelton
 * Added a new error number: INETERR_FILTERGONE, used by the Filter SWI
 * when a given frame type has already been claimed.
 *
 * Revision 1.3  95/01/24  16:32:26  kwelton
 * Fixed the definition of GETDCI4ERRNO, which should now cope with all
 * errors returned from a SWI.
 *
 * Revision 1.2  95/01/12  21:53:53  kwelton
 * The original scheme of returning UNIX style errors numbers as
 * an offset within an error block broke any application that was
 * looking for specific errors which effectively used to be offset
 * from zero.
 *
 * Revision 1.1  95/01/11  10:19:03  kwelton
 * Initial revision
 *
 */

#if !defined(__sys_dcistructs_h)
#define __sys_dcistructs_h

#define DCIVERSION	403

/*
 * DCI 4 service calls
 */
#define Service_EnumerateNetworkDrivers	0x9b
#define Service_DCIDriverStatus		0x9d
#define Service_DCIFrameTypeFree	0x9e
#define Service_DCIProtocolStatus	0x9f

/*
 * Internet specific service calls and reason codes
 */
#ifndef Service_InternetStatus
#define Service_InternetStatus		0xb0
#endif
#ifndef InternetStatus_AddressChanged
#define InternetStatus_AddressChanged	0x00
#endif
#ifndef InternetStatus_NetMapChanged
#define InternetStatus_NetMapChanged    0x01
#endif
#ifndef InternetStatus_InterfaceUpDown
#define InternetStatus_InterfaceUpDown  0x02
#endif
#ifndef InternetStatus_DynamicBootStart
#define InternetStatus_DynamicBootStart 0x03 /* Not implemented */
#endif
#ifndef InternetStatus_DynamicBootReply
#define InternetStatus_DynamicBootReply 0x04
#endif
#ifndef InternetStatus_DynamicBootOffer
#define InternetStatus_DynamicBootOffer 0x05
#endif
#ifndef InternetStatus_DynamicBootRequest
#define InternetStatus_DynamicBootRequest 0x06 /* Not implemented */
#endif
#ifndef InternetStatus_DynamicBootInform
#define InternetStatus_DynamicBootInform 0x07 /* Not implemented */
#endif
#ifndef InternetStatus_DuplicateIPAddress
#define InternetStatus_DuplicateIPAddress 0x08
#endif

/*
Service_InternetStatus 0 (Service Call &B0)
========================

Issued by the Internet module when the address of an interface changes.

On entry
--------
R0 = 0 (subreason code)
R1 = &B0 (reason code)
R2 = interface name (eg "ea0")
R3 -> Driver Information Block for interface

On exit
-------
R0,R1 preserved

Use
---
This service call is issued by the Internet module when an interfaces
address changed. The additional details in R2 and R3 were not supplied
in versions of the Internet module prior to 5.08 (ROL).

You must not claim this service call.

Service_InternetStatus 1 (Service Call &B0)
========================

Issued by the Net module when the net map has changed

On entry
--------
R0 = 1 (subreason code)
R1 = &B0 (reason code)

On exit
-------
R0,R1 preserved

Use
---
This service call is issued by the Net module when it receives new
information about the net map.

You must not claim this service call.

Service_InternetStatus 2 (Service Call &B0)
========================

Issued by the Internet module when an interface goes up or down.

On entry
--------
R0 = 2 (subreason code)
R1 = &B0 (reason code)
R2 = new state (0 = down, 1 = up)
R3 -> interface name (eg "ea0")
R4 -> Driver Information Block for interface

On exit
-------
R0-R4 preserved

Use
---
This service call is issued by the Internet module (version 5.03 or later)
when an interface goes up or down (eg due to an SIOCSIFFLAGS socketioctl()
call).

You must not claim this service call.


Service_InternetStatus 4 (Service Call &B0)
========================

Issued by the Internet module when a BOOTP/DHCP reply has been received.

On entry
--------
R0 = 4 (subreason code)
R1 = &B0 (reason code)
R2 -> interface name (eg "ea0")
R3 -> Driver Information Block for interface
R4 -> DHCP reply message buffer
R5 = size of buffer pointed to by R4

On exit
-------
R0,R2-R5 preserved.
R1 = 0 to claim service call, else preserved.

Use
---
This service call is issued by the Internet module (version 5.28 or later)
when a BOOTP/DHCP reply is received.  You may inspect the contents of the
buffer to extract any configuration information.

If you want to alter information in the buffer you may do so, but you must
then claim the service call by setting R1 to zero on exit.  If the service
call is claimed, the Internet module will reprocess the buffer as if it had
just arrived from the network. Another Service_InternetStatus 4 will arrive
in due course.

You should not normally claim this service call.


Service_InternetStatus 5 (Service Call &B0)
========================

Issued by the DHCP module when it receives a DHCPOFFER message.

On entry
--------
R0 = 5 (subreason code)
R1 = &B0 (reason code)
R2 -> interface name (eg "ea0")
R3 -> Driver Information Block for interface
R4 -> DHCPOFFER message buffer
R5 = size of buffer pointed to by R4

On exit
-------
R0,R2-R5 preserved.
R1 = 0 to claim service call, else preserved.

Use
---

This service call is issued by the DHCPClient module whenever it receives an
offer of an IP address lease which is better than its current best choice
(or if it is the first acceptable offer). You may inspect the buffer, but it
must not be modified.

If clients choose to retain information about offers, they MUST use the
value of OPTION_SERVERIDENTIFIER as an opaque key to identify which offer
has been chosen.

If you claim this service, the DHCPClient module will not accept the offer,
but will wait for another offer to be made.

You should not normally claim this service call.


Service_InternetStatus 8 (Service Call &B0)
========================

Issued by the Internet module when a machine is seen to be using the
same IP address as us.

On entry
--------
R0 = 8 (subreason code)
R1 = &B0 (reason code)
R2 -> interface name (eg "ea0")
R3 -> Driver Information Block for interface
R4 = IP address duplicated (network byte order)
R5 -> hardware address of machine with duplicate IP address

On exit
-------
R0,R2-R5 preserved.
R1 = 0 to claim service call, else preserved.

Use
---
This service call is issued by the Internet module when it detects a machine
using a duplicate IP address. This is normally detected when an incoming ARP
packet is received with our IP address but a different hardware address.

As a probe, whenever an interface is reconfigured, the Internet module sends
out an ARP requst for our IP address to make any such machines reply. That
will then trigger this service call.

Normally, the Internet module will shut down outright as a safety measure if
this happens. However, if this service call is claimed, it will continue
operation. It is expected that anyone claiming this service call should take
appropriate action; for example the DHCP module might remove our IP address,
send a DHCPDECLINE message and go back into the DHCP INIT state.
*/

#ifndef Service_PreReset
# define Service_PreReset		0x45
#endif

#ifndef Service_MessageFileClosed
# define Service_MessageFileClosed	0x5e
#endif

/*
 * official DCI4 error block.
 *
 * the bottom 128 bytes are used to hold UNIX style error
 * numbers, e.g. 12 = ENOMEM, 65 = EHOSTUNREACH.  the top
 * 128 bytes hold various special error numbers
 *
 * 950112 KWelton
 *
 * Of course, the problem with this scheme is that applications
 * are used to the old (pre-DI4) internet modules which returned
 * a limited set of error numbers, offset from zero.  For the time
 * being, SETDCI4ERRNO should also offset numbers from zero,
 * GETDCI4ERRNO can already cope with both offsets.
 *
 * In addition, GETDCI4ERRNO should not convert Internet specific
 * errors to UNIX style error numbers.
 */
#define DCI4ERRORBLOCK		(0x20e00)
#define SPECIFICOFFSET		(0x80)
#define SPECIFICERRORBASE	(DCI4ERRORBLOCK + SPECIFICOFFSET)

#if 0
# define SETDCI4ERRNO(x, y)	((x) = DCI4ERRORBLOCK + ((y) & 0x7f))
# define REALLYSETDCI4ERRNO(x, y) ((x) = DCI4ERRORBLOCK + ((y) & 0x7f))
#else
# define SETDCI4ERRNO(x, y)	((x) = ((y) & 0x7f))
# define REALLYSETDCI4ERRNO(x, y) ((x) = DCI4ERRORBLOCK + ((y) & 0x7f))
#endif

#define GETDCI4ERRNO(x)		((((x) & ~0xff) != DCI4ERRORBLOCK) ? \
				 (x) : \
				 (((x) & 0xff) < SPECIFICOFFSET) ? \
				 ((x) & 0x7f) : (x))

/*
 * define Internet specific errors
 */
#define INETERR_IFBAD		(SPECIFICERRORBASE + 0)
#define INETERR_MMBAD		(SPECIFICERRORBASE + 1)
#define INETERR_NOMM		(SPECIFICERRORBASE + 2)
#define INETERR_PANICED		(SPECIFICERRORBASE + 3)
#define INETERR_BADCLI		(SPECIFICERRORBASE + 4)
#define INETERR_MLCFAIL		(SPECIFICERRORBASE + 5)
#define INETERR_TXBLOCKED	(SPECIFICERRORBASE + 6)
#define INETERR_FILTERGONE	(SPECIFICERRORBASE + 7)
#define INETERR_INVALIDSWI	0x1e6

/*
 * offsets into driver's SWI chunk
 */
#define DCI4Version		0
#define DCI4Inquire		1
#define DCI4GetNetworkMTU	2
#define DCI4SetNetworkMTU	3
#define DCI4Transmit		4
#define DCI4Filter		5
#define DCI4Stats		6
#define DCI4MulticastRequest	7

/*
 * network slot for Service_FindNetworkDriver
 */
typedef struct slot
{
    unsigned int sl_slotid:8,
		 sl_minor:8,
		 sl_pcmciaslot:5,
		 sl_mbz:11;
} Slot, *SlotRef;

/*
 * Driver Information Block
 */
typedef struct dib
{
    unsigned int   dib_swibase;		/* base of driver's SWI chunk */
    unsigned char *dib_name;		/* pointer to name of driver */
    unsigned int   dib_unit;		/* unit number */
    unsigned char *dib_address;		/* interface's h/w address */
    unsigned char *dib_module;		/* title of driver module */
    unsigned char *dib_location;	/* description of interface position */
    Slot           dib_slot;		/* physical location of interface */
    unsigned int   dib_inquire;		/* copy of flags from Inquire SWI */
} Dib, *DibRef;

/*
 * struct to chain Driver Information Blocks
 */
typedef struct chaindib
{
    struct chaindib *chd_next;
    struct dib      *chd_dib;
} ChDib, *ChDibRef;

/*
 * structure of header passed into Rx frame handler
 */
typedef struct
{
    void          *rx_ptr;
    unsigned int   rx_tag;
    unsigned char  rx_src_addr[6], _spad[2];
    unsigned char  rx_dst_addr[6], _dpad[2];
    unsigned int   rx_frame_type;
    unsigned int   rx_error_level;
} RxHdr, *RxHdrRef;

/*
 * returned flag bits for Inquire SWI
 */
#define INQ_MULTICAST	(1 << 0)	/* multicast reception supported */
#define INQ_PROMISCUOUS	(1 << 1)	/* promiscuous reception supported */
#define INQ_CANREFLECT	(1 << 2)	/* i/f receives its own packets */
#define INQ_STATIONNO	(1 << 3)	/* station number is required */
#define INQ_RXERRORS	(1 << 4)	/* i/f can receive erroneous packets */
#define INQ_HWADDRVALID	(1 << 5)	/* i/f has a hardware address */
#define INQ_SOFTHWADDR	(1 << 6)	/* i/f can alter hardware address */
#define INQ_POINTOPOINT (1 << 7)	/* i/f is a point to point link */
#define INQ_HASSTATS	(1 << 8)	/* i/f supplys standard statistics */
#define INQ_HASESTATS	(1 << 9)	/* i/f supplys extended statistics */
#define INQ_VIRTUAL	(1 << 10)	/* this is a virtual i/f */
#define INQ_SWVIRTUAL	(1 << 11)	/* this is a software virtual i/f */
#define INQ_FILTERMCAST	(1 << 12)	/* i/f filters multicasts */

/*
 * flags for Transmit SWI
 */
#define TX_OWNSOURCE	(0 << 0)	/* use default MAC address */
#define TX_FAKESOURCE	(1 << 0)	/* use user supplied MAC address */
#define TX_DRIVERSDATA	(0 << 1)	/* driver gains ownership of mbufs */
#define TX_PROTOSDATA	(1 << 1)	/* protocol retains mbuf ownership */
#define TX_1STRESERVED	(2 << 1)	/* 1st reserved flag bit */

/*
 * levels for Filter SWI
 */
#define FRMLVL_E2SPECIFIC	1
#define FRMLVL_E2SINK		2
#define FRMLVL_E2MONITOR	3
#define FRMLVL_IEEE		4

#define ADDRLVL_SPECIFIC	0
#define ADDRLVL_NORMAL		1
#define ADDRLVL_MULTICAST	2
#define ADDRLVL_PROMISCUOUS	3

#define ERRLVL_NO_ERRORS	0
#define ERRLVL_ERRORS		1

/*
 * macros for manipulating subfields within frame type
 */
#define GET_FRAMETYPE(x)	((x) & 0xffff)
#define SET_FRAMETYPE(x, y)	((x) = ((x) & 0xffff0000) | ((y) & 0xffff))
#define GET_FRAMELEVEL(x)	(((unsigned int)(x)) >> 16)
#define SET_FRAMELEVEL(x, y)	((x) = ((x) & 0x0000ffff) | ((y) << 16))

/*
 * flags for MulticastRequest SWI
 */
#define MULTICAST_ADDR_REQ	(0 << 0)
#define MULTICAST_ADDR_REL	(1 << 0)
#define MULTICAST_SPECIFIC_ADDR	(0 << 1)
#define MULTICAST_ALL_ADDR	(1 << 1)
#define MULTICAST_1STRESERVED	(1 << 2)

/*
 * flags for Filter SWI
 */
#define FILTER_CLAIM		(0 << 0)
#define FILTER_RELEASE		(1 << 0)
#define FILTER_UNSAFE_OK	(0 << 1)
#define FILTER_NO_UNSAFE	(1 << 1)
#define FILTER_ALL_MCAST	(0 << 2)
#define FILTER_SPECIFIC_MCAST	(1 << 2)
#define FILTER_1STRESERVED	(1 << 3)

/*
 * definitions for stats interface types
 */
#define ST_TYPE_10BASE5			1
#define ST_TYPE_10BASE2			2
#define ST_TYPE_10BASET			3
#define ST_TYPE_10BASE5N2		4
#define ST_TYPE_10BASE2NT		5
#define ST_TYPE_RSQUELCH10BASET		6
#define ST_TYPE_ACORNECONET		7
#define ST_TYPE_SERIAL			8
#define ST_TYPE_PARALLEL		9
#define ST_TYPE_10BASE5N2NT		10
#define ST_TYPE_10BASEFX		11
#define ST_TYPE_100BASETX		12
#define ST_TYPE_100BASEVG		13
#define ST_TYPE_100BASET4		14
#define ST_TYPE_100BASEFX		15
#define ST_TYPE_ATM25_6			16
#define ST_TYPE_ATM155			17
#define ST_TYPE_ATMPLUSRELAY            18
#define ST_TYPE_ATMFLANE                19

/*
 * stats. link status bits
 */
#define ST_STATUS_OK			(1 << 0)
#define ST_STATUS_ACTIVE		(1 << 1)
#define ST_STATUS_RXMASK		(3 << 2)
#define ST_STATUS_DIRECT		(0 << 2)
#define ST_STATUS_BROADCAST		(1 << 2)
#define ST_STATUS_MULTICAST		(2 << 2)
#define ST_STATUS_PROMISCUOUS		(3 << 2)
#define ST_STATUS_HALF_DUPLEX		(0 << 4)
#define ST_STATUS_FULL_DUPLEX		(1 << 4)

/*
 * stats. link polarity bits
 */
#define ST_LINK_POLARITY_INCORRECT	(0 << 0)
#define ST_LINK_POLARITY_CORRECT	(1 << 0)

/*
 * structure for returning device driver statistics
 */
struct stats
{
    /*
     * general information
     */
    unsigned char st_interface_type;
    unsigned char st_link_status;
    unsigned char st_link_polarity;
    unsigned char st_blank1;
    unsigned long st_link_failures;
    unsigned long st_network_collisions;

    /*
     * transmit statistics
     */
    unsigned long st_collisions;
    unsigned long st_excess_collisions;
    unsigned long st_heartbeat_failures;
    unsigned long st_not_listening;
#if 0
    unsigned long st_net_error;
#endif
    unsigned long st_tx_frames;
    unsigned long st_tx_bytes;
    unsigned long st_tx_general_errors;
    unsigned char st_last_dest_addr[8];

    /*
     * receive statistics
     */
    unsigned long st_crc_failures;
    unsigned long st_frame_alignment_errors;
    unsigned long st_dropped_frames;
    unsigned long st_runt_frames;
    unsigned long st_overlong_frames;
    unsigned long st_jabbers;
    unsigned long st_late_events;
    unsigned long st_unwanted_frames;
    unsigned long st_rx_frames;
    unsigned long st_rx_bytes;
    unsigned long st_rx_general_errors;
    unsigned char st_last_src_addr[8];
};

#endif /* !defined(__sys_dci4structs_h) */

/* EOF dcistructs.h */
