home *** CD-ROM | disk | FTP | other *** search
- Driver Control Interface
- ========================
-
- Version 3 August 1992
- CONFIDENTIAL
-
-
- 1. Introduction
- ---------------
-
- This note describes the interface between a protocol module and a
- device driver module used by the protocol. The interface will enable
- multiple protocol stacks to control multiple different device drivers
- simulataneously, if required.
-
- The interface is optimised in its detail to handle device drivers for
- Ethernet. Drivers for other types of network will need to emulate Ethernet
- in these details at this interface and map "virtual Ethernet" values into
- real values meaningful to the actual connected network.
-
- Specifically:
-
- i) physical network addresses are 48 bit quantities.
-
- ii) the values of physical network frames "owned" by protocol modules
- are expressed as Ethernet frame type values. Example:
-
- Internet owns three types of physical frame, namely frames
- containing IP, ARP and Reverse ARP protocol messages. The
- driver module will be informed via the values &800, &806 and
- &8035 respectively.
-
- iii) At startup, driver modules must set the variable
-
- Inet$EtherType
-
- to the text string name of the controlled physical interface type
- ("et", "en", etc), with the suffix '0' (e.g "et0", "en0" etc).
- This is for compatibility with Acorn AUN and TCP/IP software.
- The name part is the same string referred to in the Driver
- Information Block.
-
-
- 2. Service calls
- ----------------
-
- When loaded, a network interface driver module will perform various
- internal and hardware initialisation functions. It will then announce
- its presence via the service call Service_NetworkDriverStatus (0) and
- wait for a protocol module, such as Internet, to search for device
- drivers controlling interfaces which the protocol wishes to access.
- This is done via the service call Service_FindNetworkDriver. Subsequently,
- if a protocol module terminates it will notify associated driver
- modules via Service_ProtocolDying. A terminating driver module issues
- Service_NetworkDriverStatus (1).
-
-
- Service_FindNetworkDriver (Service call &84)
-
- On entry: R1 = &84 (reason code)
- R2 = pointer to name of driver sought ("et", "en", etc),
- or zero, or -1.
- R3 = pointer to "Protocol Information Block" describing
- this protocol, or zero.
- R4 = slot number, if R2 = -1 and R3 = 0
-
- On exit: All registers preserved (if not claimed)
-
- If claimed:
- R1 = 0
- R2 preserved
- R3 = pointer to "Driver Information Block" describing
- available driver
-
- Use: Service_FindNetworkDriver makes a logical connection between
- a protocol module and a driver module, enabling information
- about each other to be exchanged.
-
- Service_FindNetworkDriver may also be used to find out whether
- a driver module is present, without making a logical connection.
- In this case R2 and R3 are zero on entry. Exit register values
- are the same if claimed by a driver module.
-
- Service_FindNetworkDriver may also be used to find out which
- driver module controls the device located in a given backplane
- slot. In this case R2 is -1, R3 is zero and R4 contains the
- slot number (0 - 3) on entry. Exit register values are the same
- if claimed by a driver module.
-
-
- Service_ProtocolDying (Service call &83)
-
- On entry: R1 = &83 (reason code)
- R2 = ID of exiting protocol
-
- On exit: All registers preserved to pass on
-
- Use: Service_ProtocolDying is issued by a protocol module
- to notify driver modules that the protocol is exiting.
- The protocol ID is the same value as previously passed
- to the driver in pib.pib_sccall. Driver modules must
- never claim this service call.
-
-
- Service_NetworkDriverStatus (Service call &8b)
-
- On entry: R1 = &8b (reason code)
- R2 = status (0 = starting, 1 = terminating)
- R3 = pointer to "Driver Information Block" describing
- this driver
-
- On exit: All registers preserved. This service call should not be
- claimed.
-
- Use: Service_NetworkDriverStatus is issued by a network driver
- module to indicate that it is starting up or terminating.
-
-
- Protocol Information Block
- --------------------------
-
- struct pib {
- char pib_frtypecnt;
- unsigned short pib_frtype[6];
- int pib_rxevent;
- struct mbuf **pib_freeq;
- int pib_sccall;
- struct mbuf **pib_lfreeq;
- };
-
- pib_frtypecnt
-
- Number of valid fields in pib_frtype[].
-
- pib_frtype[]
-
- Array of physical frame type values which are "owned"
- by this protocol. The driver module will route all
- incoming frames with these types to this module, via
- an event sequence governed by pib_rxevent.
-
- pib_rxevent
-
- Number of RISC OS event to generate when an incoming frame
- of the correct type is received. This mechanism is used to
- pass incoming frames into the correct protocol module.
-
- pib_freeq
-
- Address of free list of "small" data buffers owned by this
- protocol module but available to the driver module
- to store data associated with incoming frames of the
- correct type. [Note: driver modules must never themselves
- free data buffers obtained from this list.]
-
- pib_sccall
-
- ID for this protocol which will be included in
- Service_ProtocolDying on module termination. Internet = 1.
-
- pib_lfreeq
-
- Address of free list of "large" data buffers owned by this
- protocol module but available to the driver module
- to store data associated with incoming frames of the
- correct type. These buffers should be large enough to
- accomodate a full Ethernet frame. There may only be a
- small number available so a driver module should be
- prepared to "fall back" on small buffers if no large
- buffer is available. [Note: driver modules must never
- themselves free data buffers obtained from this list.]
-
-
- Driver Information Block
- ------------------------
-
- struct dib {
- char *dib_name;
- int dib_units;
- int dib_swibase;
- char *dib_address[4];
- char *dib_module;
- };
-
- dib_name
-
- Pointer to text string name of physical interface type
- controlled by this driver module ("et", "en", "ec", etc).
-
- dib_units
-
- Number of accessible physical interfaces present of the
- type controlled by this driver module.
-
- dib_swibase
-
- Base of SWI block owned by this driver module.
-
- dib_address[]
-
- Pointers to physical addresses of interface cards. Each address
- is a 48 bit (6 byte) quantity. [The array size 4 is pragmatic]
-
- dib_module
-
- Pointer to title of driver module (e.g. "Ether3")
-
- Once the startup sequence is complete, the protocol module will communicate
- with the driver module via SWI calls, and the driver module will interrupt
- the protocol module with events to indicate received frames.
-
-
- 3. SWI calls
- ------------
-
- The following set of SWI calls enable a protocol module to pass data and
- control commands to a device driver module. Each different driver will
- own a unique chunk of SWI numbers whose base is passed to a protocol
- module at startup time via the Driver Information Block. SWI numbers
- offset sequentially from the SWI chunk base will correspond functionally
- to the commands described below.
-
- SWI_NetworkIfStart (SWI &(dib_swibase + 0))
-
- Start a physical interface unit controlled by the owner of dib_swibase.
-
- On entry: R0 = unit number (0 - 3)
-
- On exit: registers preserved
-
- Use: Called by protocol module to start interface
- and enable subsequent I/O.
-
-
- SWI_NetworkIfUp (SWI &(dib_swibase + 1))
-
- Restart a physical interface unit.
-
- On entry: R0 = unit number (0 - 3)
-
- On exit: registers preserved
-
- Use: Called by protocol module to restart interface and
- reenable subsequent I/O, after an earlier call of
- SWI_NetworkIfDown.
-
-
- SWI_NetworkIfDown (SWI &(dib_swibase + 2))
-
- Disable a physical interface unit.
-
- On entry: R0 = unit number (0 - 3)
-
- On exit: registers preserved
-
- Use: Called by protocol module to disable indicated interface
- and disallow subsequent I/O.
-
-
- SWI_NetworkIfSend (SWI &(dib_swibase + 3))
-
- Transmit data via a physical interface unit.
-
- On entry: R1 = unit number (0 - 3)
- R2 = frame type
- R3 = pointer to destination physical address;
- 48 bit (6 byte) quantity
- R4 = pointer to message buffer chain containing
- transmit data.
- R5 = event number to call on completion or error
- (or zero for no event required)
-
- On exit: registers preserved
-
- Use: Called by protocol module to transmit data, held in
- a chain of buffers. The destination physical
- address and a frame type value identifying the
- sending protocol are specified. If the protocol
- module wishes to be notified via an event about the
- status of the transmission (beyond any error value
- which may be passed back directly on SWI exit) then
- the event number (> 0) will be specified.
-
- If R5 = 0 then the protocol module may assume that
- it can free the associated mbuf chain immediately
- on return from the SWI call, otherwise it must wait
- for the event to occur before freeing the mbufs.
-
- See SWI_TxEventRequired below.
-
-
- SWI_DCIVersion (SWI &(dib_swibase + 4))
-
- Return version number of DCI specification implemented.
-
- On entry: No parameters passed
-
- On exit: R0 = Version number integer
- current version = 3
-
- Use: Called by protocol module to ensure that a
- device driver module implements the version of
- DCI interface compatible with itself.
-
-
- SWI_NetworkMTU (SWI &(dib_swibase + 5))
-
- Return physical MTU of supported network
-
- On entry: No parameters passed
-
- On exit: R0 = MTU or zero
-
- Use: Called by protocol module to find out the
- MTU of the underlying network, for example to
- enable efficient fragmentation of datagrams.
- Default (R0 = 0) is ETHERNET MTU (1500 octets).
-
-
- SWI_TxEventRequired (SWI &(dib_swibase + 6))
-
- Return wether device driver requires an event value of TX
-
- On entry: No parameters passed
-
- On exit: R0 = 1 tx event number required
- 0 tx event number not required
-
- Use: Called by protocol module to find out wether
- the transmission strategy used by the device
- driver module requires the protocol module to
- supply a txevent value with every transmission
- SWI call (SWI_NetworkIfSend) - i.e transmission
- synchronous to SWI_NetworkIfSend cannot be
- guaranteed on request. (NB This may impact on
- performance optimisations within the protocol
- module.)
-
-
- 4. Events
- ---------
-
- An event may be generated by a driver module to indicate that
- a data transmission request has been processed or that a frame
- has been received from the network. Different event numbers are
- owned by different protocol modules, and are supplied to driver
- modules via SWI_NetworkIfSend (for tx) and Service_FindNetworkDriver
- (for rx) calls.
-
- TX Event
- --------
-
- On entry to event handler:
-
- R0 = tx event number (specified by protocol module)
- R1 = pointer to data buffer chain containing
- tx data
- R2 = pointer to name of interface controlled by
- this driver ("ea", "en", etc)
- R3 = physical unit number (0 - 3)
- R4 = error number (driver specific) or zero = ok
-
- A transmission event does not necessarily imply that a frame has been
- successfully transmitted and received by the target host, merely that
- the local operation has been completed - either with or without a
- detected hardware error - and so the protocol module may free the
- addressed message buffer chain. A protocol module has the option
- of requesting an event or no event with each SWI call to transmit data
- (see above).
-
- RX Event
- --------
-
- On entry to event handler:
-
- R0 = rx event number (protocol specified)
- R1 = pointer to data buffer chain containing
- rx data
- R2 = pointer to name of interface controlled by
- this driver ("ea", "en", etc)
- R3 = physical unit number (0 - 3)
- R4 = rx frame type
-
- A receive event means that an incoming frame "addressed" (via the frame
- type field) to a protocol module has been received and stored within
- the addressed data buffers obtained for this purpose from the protocol
- module's freelist. Once the event is generated, the driver module must
- forget about the associated data buffers. These will be received by the
- protocol module's event handler and in due course returned by the protocol
- module to its own freelist. Data buffers comprising an individual frame
- are chained together via the m_next field (see below).
-
- If the frame type field is zero, then the driver module intends that
- the protocol module should free the returned data buffers immediately
- (ie reception aborted).
-
- The first buffer in each frame chain does not contain frame data. The
- first four bytes contains a pointer to a Driver Information Block describing
- this driver. The next six bytes contain the 48-bit physical address of the
- source of the received frame.
-
-
- 5. Data buffers
- ---------------
-
- Data passes across the interface between the protocol and driver modules
- in "mbufs". These are the similar to the data structure as used internally
- within the BSD UNIX kernel, and also within the RISC OS Internet module,
- for handling network data. Mbufs are aligned on 128 byte boundaries and
- can either store internally up to 112 data bytes, or else reference
- an external block of data. The format is:
-
- #define MSIZE 128
- #define MMINOFF 12
- #define MTAIL 4
- #define MLEN (MSIZE-MMINOFF-MTAIL)
-
- struct mbuf {
- struct mbuf *m_next; /* next buffer in chain */
- u_long m_off; /* offset of data */
- short m_len; /* amount of data */
- char m_type; /* mbuf type */
- char m_indir; /* data is indirect */
- union {
- u_char mun_dat[MLEN]; /* data storage */
- char *mun_datp; /* indirect data pointer */
- } m_un;
- struct mbuf *m_act; /* must be zero */
- };
-
- #define m_dat m_un.mun_dat
- #define m_datp m_un.mun_datp
-
- If the data is indirect then the device driver module must make no
- assumptions about the actual locations of the referenced data.
-