/* Copyright 1997 Acorn Computers Ltd
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/* -*-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	407

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

/*
 * 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
#endif
#ifndef InternetStatus_DynamicBootReply
#define InternetStatus_DynamicBootReply 0x04
#endif
#ifndef InternetStatus_DynamicBootOffer
#define InternetStatus_DynamicBootOffer 0x05
#endif
#ifndef InternetStatus_DynamicBootRequest
#define InternetStatus_DynamicBootRequest 0x06
#endif
#ifndef InternetStatus_DynamicBootInform
#define InternetStatus_DynamicBootInform 0x07
#endif
#ifndef InternetStatus_DuplicateIPAddress
#define InternetStatus_DuplicateIPAddress 0x08
#endif
#ifndef InternetStatus_MediaStatusChanged
#define InternetStatus_MediaStatusChanged 0x09
#endif

/*
 * official DCI4 error block.
 *
 * the bottom 128 numbers are used to hold UNIX style error
 * numbers, e.g. 12 = ENOMEM, 65 = EHOSTUNREACH.  the top
 * 128 numbers hold various special error numbers
 *
 * 950112 KWelton
 *
 * Of course, the problem with this scheme is that applications
 * are used to the old (pre-DCI4) 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 1
# 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)

/*
 * 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_EnumerateNetworkDrivers
 */
typedef struct slot
{
    unsigned int sl_slotid:8,
                 sl_minor:8,
                 sl_pcmciaslot:5,
                 sl_mbz:11;
#define DIB_SLOT_PODULE(n)    (0 +((n) & 0xF))	/* Podules = 0-7 and NIC = 8 */
#define DIB_SLOT_PCI(n)       (16+((n) & 0xF))
#define DIB_SLOT_USB_BUS(n)   (32+((n) & 0xF))	/* sl_minor = device number on that bus */
#define DIB_SLOT_PARALLEL     128		/* IEE1284, sl_minor = 0's based port */
#define DIB_SLOT_SERIAL       129		/* EIA232, sl_minor = 0's based port */
#define DIB_SLOT_ECONET       130
#define DIB_SLOT_PCMCIA       131		/* sl_pcmciaslot = function on that interface */
#define DIB_SLOT_SDIO         132		/* sl_pcmciaslot = function on that interface */
#define DIB_SLOT_SYS_BUS      133		/* sl_minor = bits 16-23 of HAL device locn */
#define DIB_SLOT_PERI_BUS     134		/* sl_minor = bits 16-23 of HAL device locn */
} 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;

/*
 * reasons to driver and protocol status service calls
 */
#define DCIDRIVER_STARTING	0
#define DCIDRIVER_DYING		1
#define DCIPROTOCOL_STARTING	0
#define DCIPROTOCOL_DYING	1

/*
 * 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;
    unsigned int   rx_cksum;
} 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 supplies standard statistics */
#define INQ_HASESTATS	(1 << 9)	/* i/f supplies 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 */
#define INQ_FASTIPSUM	(1 << 13)	/* i/f can IP checksum in hardware */
#define INQ_1STRESERVED	(1 << 14)	/* 1st reserved flag bit */

/*
 * 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	(1 << 2)	/* 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_IPSUM_NOT_REQD	(0 << 3)
#define FILTER_IPSUM_IN_RXHDR	(1 << 3)
#define FILTER_1STRESERVED	(1 << 4)

/*
 * 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
#define ST_TYPE_1000BASESX		20 /* 1000BaseSX Multi-mode Fibre */
#define ST_TYPE_1000BASET		21 /* 1000BaseT 4 pair cat 5 */
#define ST_TYPE_1000BASELX		22 /* 1000BaseLX Fibre */
#define ST_TYPE_1000BASECX		23 /* 1000BaseCX Short-Haul Copper */
#define ST_TYPE_80211_2G4		24 /* 802.11b/g/n/ax */
#define ST_TYPE_80211_3G7		25 /* 802.11y */
#define ST_TYPE_80211_4G9		26 /* 802.11j */
#define ST_TYPE_80211_5G		27 /* 802.11a/j/n/ac/ax */
#define ST_TYPE_80211_5G9		28 /* 802.11p */
#define ST_TYPE_80211_6G		29 /* 802.11ax */

/*
 * 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 */
