Extending the SANA-II network driver specification
by Olaf Barthel
(Last updated 02-Mar-2003)
The years have gone by without any substantial changes to the SANA-II standard being made. With good reason, since there was no apparent need to push the envelope and extend the driver specification. The last proposed change came 1997 from Holger Kruse, who suggested that commands should be added to control multicast packet reception for ranges of addresses rather than individual addresses.
I've been working on a TCP/IP stack and PPP drivers to go with them for a while and found that there were some things that SANA-II did specifically not address, and which ought to be covered by it. In other areas clarification was needed. Also, discussions I had with Harald Frank suggested that the extensions made by Heinz Wrobel and Stefan Sticht in the SANA-IIR3 specification could need extending.
The following text tries to tie all issues together and will conclude by listing problems which I think still need attention (or in other words, I didn't find a solution myself). Wherever possible, I have tried to provide a rationale for the changes I propose.
Please feel free to comment; you can contact me through the e-mail address given in the headline of this document. Note that the issues discussed in this document are just a list of proposed changes. No such features are part of any SANA-II specifications, although I'd like to claim that I have tried to implement the majority of the changes listed below in my own software.
This is a revised version of the original document I put together around October 14, 2001. For a list of changes that have been made since, please see section 10 ('Changes'). This document has been updated and enhanced several times, in response to discussions with Heinz Wrobel.
S2_GETPEERADDRESS
I propose a command with the following semantics:
NAME S2_GETPEERADDRESS -- Obtain the addresses used by the peer (server) and the client of a point-to-point connection. FUNCTION Obtain the address used by the peer of a point-to-point connection and the address assigned to the local driver. IO REQUEST ios2_Command - S2_GETPEERADDRESS ios2_Flags - Supported flags are: SANA2IOB_QUICK ios2_BufferManagement - Magic cookie as returned when opening the driver with a struct IOSana2Req RESULTS ios2_Req.io_Error - Zero if successful; non-zero otherwise ios2_WireError - More specific error number ios2_SrcAddr - Address assigned to the local driver ios2_DstAddr - Address used by the peer NOTES The size of the address returned by S2_GETPEERADDRESS must not be different from the size returned by the S2_DEVICEQUERY command. For example, if a 32 bit IPv4 address was advertized, the driver must not return a 128 bit IPv6 address instead. If the driver is unable to return the local driver address (ios2_SrcAddr) or the peer's address (ios2_DstAddr) it must fill the respective address fields with zeroes. It is legal for a driver to respond to the S2_GETPEERADDRESS command with two zero addresses (both ios2_SrcAddr and ios2_DstAddr filled with zeroes).
I propose that the following command number should be assigned:
#define S2_GETPEERADDRESS 0xC002
This command may be useful beyond the typical application (PPP) described above.
S2_GETDNSADDRESS
I propose a command with the following semantics:
NAME S2_GETDNSADDRESS -- Obtain the addresses of the primary and secondary domain name servers. FUNCTION Obtain the addresses of the domain name servers available to the client using this driver's address. IO REQUEST ios2_Command - S2_GETDNSADDRESS ios2_Flags - Supported flags are: SANA2IOB_QUICK ios2_BufferManagement - Magic cookie as returned when opening the driver with a struct IOSana2Req RESULTS ios2_Req.io_Error - Zero if successful; non-zero otherwise ios2_WireError - More specific error number ios2_SrcAddr - Address of primary domain name server ios2_DstAddr - Address of secondary domain name server NOTES The size of the address returned by S2_GETPEERADDRESS must not be different from the size as returned by the S2_DEVICEQUERY command. For example, if a 32 bit IPv4 address was advertized, the driver must not return a 128 bit IPv6 address instead. If the driver is unable to return the primary domain name server address (ios2_SrcAddr) or the secondary domain name server address (ios2_DstAddr) it must fill the respective address fields with zeroes. It is legal for a driver to respond to the S2_GETDNSADDRESS command with two zero addresses (both ios2_SrcAddr and ios2_DstAddr filled with zeroes).
I propose that the following command number should be assigned:
#define S2_GETDNSADDRESS 0xC003
This command may be useful beyond the typical application (PPP) described above.
S2_GETEXTENDEDGLOBALSTATS
S2_GETGLOBALSTATS
) which should be common to all kinds of networking devices.
Statistics that are particular to a certain device type are intended to be
returned through the S2_GETSPECIALSTATS
command. I feel that these mechanisms
both fail to cater well enough for dial-up or session-oriented networking
applications such as PPP or PPPoE. Since the data structure used by
S2_GETGLOBALSTATS
is of a fixed size and not intended to accomodate for new
fields, I propose to introduce a new command which uses a different data
structure, as follows:
struct Sana2ExtDeviceStats { ULONG s2xds_Length; ULONG s2xds_Actual; S2QUAD s2xds_PacketsReceived; S2QUAD s2xds_PacketsSent; S2QUAD s2xds_BadData; S2QUAD s2xds_Overruns; S2QUAD s2xds_UnknownTypesReceived; S2QUAD s2xds_Reconfigurations; struct timeval s2xds_LastStart; struct timeval s2xds_LastConnected; struct timeval s2xds_LastDisconnected; struct timeval s2xds_TimeConnected; };
Before I proceed to explain what purposes the individual members serve, a few
words on the S2QUAD
type, which is defined as follows:
typedef struct { ULONG s2q_High; ULONG s2q_Low; } S2QUAD;
In other words, the S2QUAD
type stands for an unsigned 64 bit big endian
integer, as expressed in ISO 'C' terms.
The structure members have the following purposes:
s2xds_Length
sizeof(struct Sana2ExtDeviceStats)
.
Smaller values are permitted, but these must not be smaller than 8
(which covers the s2xds_Length
and s2xds_Actual
members). A driver which
finds an s2xds_Length
< 8 must treat this as an error and reject the
command with ios2_Req.io_Error
=IOERR_BADLENGTH
.
s2xds_Actual
s2xds_Length
.
s2xds_PacketsReceived
s2xds_PacketsSent
s2xds_BadData
s2xds_Overruns
s2xds_UnknownTypesReceived
s2xds_Reconfigurations
s2xds_LastStart
s2xds_LastConnected
s2xds_LastConnected
must be set to zero
if the unit never managed to make a connection.
s2xds_LastDisconnected
s2xds_LastDisconnected
must be set to zero if the unit never
disconnected.
s2xds_TimeConnected
If this unit is not currently connected, then s2xds_TimeConnected
must be set to zero. This means in particular that when the connection
is lost, s2xds_TimeConnected
must be immediately set to zero and
s2xds_LastDisconnected
must be filled in so that client software
can query how long the unit was connected by subtracting
s2xds_LastConnected
from s2xds_LastDisconnected
.
If this unit is currently connected, s2xds_TimeConnected
must
never be zero; if necessary, set s2xds_TimeConnected.tv_secs=0
and
s2xds_TimeConnected.tv_micros=1
.
If s2xds_TimeConnected
is zero, check s2xds_LastConnected
and
s2xds_LastDisconnected
; if the latter two are not zero, you can
calculate the previous connection time by subtracting
s2xds_LastConnected
from s2xds_LastDisconnected
.
Sana2ExtDeviceStats
data structure
suggest that there is a difference between the underlying networking media
(the link layer) and the state of the protocol that is running on top of it.
With drivers for networking hardware such as Ethernet there was no difference
between these two, but for protocols like SLIP, PPP or PPPoE there is a
difference. The difference is in that a session or connection may exist for a
certain time whereas the protocol running inside that session may be switched
'online' later. The primary purpose of the s2xds_LastConnected
,
s2xds_LastDisconnected
and s2xds_TimeConnected
fields is to allow for cost
accounting and traffic monitoring (so that, for example, a driver may be
disconnected after it has been idle for a while) to be written.I propose a command with the following semantics:
NAME S2_GETEXTENDEDGLOBALSTATS -- Get interface accumulated statistics; updated version. FUNCTION This command causes the device driver to retrieve various global runtime statistics for this network interface. The format of the data returned is as follows: struct Sana2ExtDeviceStats { ULONG s2xds_Length; ULONG s2xds_Actual; S2QUAD s2xds_PacketsReceived; S2QUAD s2xds_PacketsSent; S2QUAD s2xds_BadData; S2QUAD s2xds_Overruns; S2QUAD s2xds_UnknownTypesReceived; S2QUAD s2xds_Reconfigurations; struct timeval s2xds_LastStart; struct timeval s2xds_LastConnected; struct timeval s2xds_LastDisconnected; struct timeval s2xds_TimeConnected; }; IO REQUEST ios2_Command - S2_GETEXTENDEDGLOBALSTATS ios2_StatData - Pointer to Sana2ExtDeviceStats structure to fill in ios2_BufferManagement - Magic cookie as returned when opening the driver with a struct IOSana2Req RESULTS ios2_Req.io_Error - Zero if successful; non-zero otherwise ios2_WireError - More specific error number
I propose that the following command number should be assigned:
#define S2_GETEXTENDEDGLOBALSTATS 0xC004
S2_CONNECT
To bridge this gap, I propose a new command which will make a driver connect to its link layer and go online, which uses the following data structure:
struct Sana2Connection { ULONG s2c_Size; struct MinList s2c_Options; struct Hook s2c_ErrorHook; struct Hook s2c_ConnectHook; struct Hook s2c_DisconnectHook; STRPTR s2c_Login; STRPTR s2c_Password; };
The individual structure members have the following purposes:
s2c_Size
ios2_Req.io_Error
=IOERR_BADLENGTH
.
The purpose of s2c_Size
is to allow for future expansion during which
the structure may grow in size.
s2c_Options
struct Sana2ConnectionOption { struct MinNode s2co_MinNode; STRPTR s2co_Name; STRPTR s2co_Value; };
The s2co_Name
and s2co_Value
entries point to NUL
-terminated
strings, which contain the name and the value of a parameter. Note that
for numeric values, the respective number will be encoded in a text
string. A number of parameters are reserved, which are listed later in
this text.
s2c_ErrorHook
error_hook_func(hook,reserved,message); A0 A2 A1 VOID error_hook_func(struct Hook *hook,APTR reserved, STRPTR message);
The reserved
parameter must be NULL
. The message
parameter points to
a NUL
-terminated string. It must not be NULL
.
Because the hook function may have to allocate memory, it must not be called from interrupt code.
s2c_ConnectHook
success = connect_hook_func(hook,reserved,s2cm); D0 A0 A2 A1 BOOL connect_hook_func(struct Hook *hook,APTR reserved, struct Sana2ConnectionMessage *s2cm);
The reserved
parameter must be NULL
. The s2cm
parameter points to
a data structure, as follows:
struct Sana2ConnectionMessage { ULONG s2cm_Size; struct Sana2Connection * s2cm_Connection; struct IORequest * s2cm_Request[2]; LONG s2cm_RequestType; };
In this structure, the members have the following purposes:
s2cm_Size
s2cm_Size
is to allow for
future expansion, which may cause the size of this
structure to grow.
s2cm_Connection
Sana2Connection
structure
which the hook that was invoked with the
Sana2ConnectionMessage
is embedded in.
s2cm_Request
NULL
and they must refer to
different I/O requests, it is not permitted to pass
the same request twice.The dialer can use these requests for communicating with the modem, but it is also permitted to clone these requests by creating new I/O requests of the same size, copying the original contents and filling in different reply ports.
There is a danger in that the hook code may not
receive the right kind of I/O request, which is
why the s2cm_RequestType
field identifies the
kind of device the requests were created for.
When the hook function returns, it must make sure that none of the I/O requests are still pending, i.e. asynchronous I/O must have been stopped.
s2cm_RequestType
s2cm_Request
were created for. Possible
values for this entry come from the New Style
Device specification, e.g. NSDEVTYPE_SERIAL
for
a serial.device
-like device or NSDEVTYPE_SANA2
for a networking driver.
The hook function must return TRUE
if the connection could
be established, and FALSE
otherwise. Note that it is not
sufficient to just return FALSE
in case of failure. Your code
must have called the s2c_ErrorHook
with an explanation why
things went wrong first.
s2c_DisconnectHook
S2_CONNECT
when the connection could
not be established (the s2c_ConnectHook
returned FALSE
),
or by S2_DISCONNECT
, shortly before the link level device
is to be closed. The hook function is invoked with the
following parameters:
disconnect_hook_func(hook,reserved,s2cm); A0 A2 A1 VOID disconnect_hook_func(struct Hook *hook,APTR reserved, struct Sana2ConnectionMessage *s2cm);
The reserved
parameter must be NULL
. The s2cm
parameter points to
a data structure, as was described for the s2c_ConnectHook
.
s2c_Login
s2c_Password
NULL
or contain pointers to NUL
-terminated strings. If s2c_Login
is NULL
,
then both login and password must be assumed to be empty. If s2c_Login
is not NULL
and s2c_Password
is NULL
, then the password must be assumed
to be empty.
While this list of parameters may suggest that the command described above can be used solely with the PPP protocol, do not let that put you off. This list is merely the starting point, but it is not set in stone that it cannot be extended.
The names of the parameters are not case sensitive. As the names suggest, the name space itself is hierarchic in construction, i.e. everything related to the PPP protocol bears a name starting with the letters 'ppp' with the dot '.' separating the individual items. By this rule, ppp.async refers to options that concern asynchronous PPP and ppp.ethernet to options that concern PPP over Ethernet wire.
To add your own parameter, register it with the maintainer of the SANA-II standard or prefix its name with the letters 'x-'. For example, to use your own kind of 'ppp.ethernet.connecttimeout' parameter, change the name of the last component like this: ppp.ethernet.x-connecttimeout. No officially-registered parameter will ever begin with the prefix 'x-'.
The command should work as follows:
Sana2Connection
data structure,
initialize the s2c_Size
, s2c_Options
, s2c_ErrorHook
,
s2c_ConnectHook
, s2c_DisconnectHook
, s2c_Login
and
s2c_Password
fields.
s2c_Options
list. The client must make sure that
the syntax of the parameters conforms to the specifications
described above.
Sana2Connection
data structure is placed
in the ios2_Data
member of an IOSana2Req
, the command
is set to S2_CONNECT
and the request is sent via DoIO()
or SendIO()
.
s2c_Options
list, as provided in the
data structure pointed to by the ios2_Data
member of the
request. Unknown options are ignored, options whose values
do not conform to the syntax specification are rejected;
this is done by calling the s2c_ErrorHook
with an error
message referring to the option in question and by
returning the IOSana2Req
with an error code of
S2ERR_BAD_ARGUMENT
and wire error code of
S2WERR_INVALID_OPTION
.
s2c_ErrorHook
is called with an error
message referring to the option in question and the
IOSana2Req
is returned with an error code of S2ERR_BAD_ARGUMENT
and wire error code of S2WERR_MISSING_OPTION
.
s2c_ErrorHook
is called with an error message referring to
the problem and the IOSana2Req
is returned with an appropriate
error code.
s2c_ConnectHook
callback. Some drivers may require this, such as asynchronous
PPP, some may not, such as PPPoE. The purpose of the hook function
is to give the client a chance to perform modem initializations
and connect to the peer. If the s2c_ConnectHook
cannot perform
its duties, it has to invoke the s2c_ErrorHook
with an error
message and eventually return FALSE
. If FALSE
is returned, the
driver must invoke the s2c_DisconnectHook
, reverse any
initializations it had made and eventually returned the
IOSana2Req
with an appropriate error code. If the s2c_ConnectHook
returned TRUE
, then the driver must proceed with the actions
that require that the link layer is operational. A protocol
negotiation may follow, which, if successful, will make the
driver return the IOSana2Req
with an error code of zero,
indicating success. If successful, the SANA-II events
S2EVENT_CONNECT
and S2EVENT_ONLINE
must be sent.
Sana2Connection
structure
and the option nodes in the s2c_Options
list. This is because
the driver may have to invoke the s2c_DisconnectHook
hook due
to the connection shutting down on its own accord.
The connect and disconnect hook functions must not be called from interrupt
code. For each hook only a Task
calling context of unknown priority must be
assumed. Also, stack space is provided only to call exec.library
and
utility.library
functions. The callback shall not place excessive data on the
stack. Stack space should be considered limited.
I propose a command with the following semantics:
NAME S2_CONNECT -- Establish a link layer connection and go online. FUNCTION This command is for use by networking devices which require a special link layer device to transmit their data, such as an asynchronous serial line and need to know about the configuration parameters necessary to open the connection. IO REQUEST ios2_Command - S2_CONNECT ios2_Data - Pointer to Sana2Connection structure ios2_BufferManagement - Magic cookie as returned when opening the driver with a struct IOSana2Req RESULTS ios2_Req.io_Error - Zero if successful; non-zero otherwise ios2_WireError - More specific error number NOTES If successful, this command implies S2_ONLINE, i.e. the link layer is allocated and used by the driver. The contents of the Sana2Connection structure must be valid until the connection is eventually shut down. The driver will need to cache it, so it must not be deallocated or otherwise modified. Note that S2_ONLINE does not necessarily imply S2_CONNECT, if the S2_CONNECT command is listed as supported by the driver via NSCMD_DEVICEQUERY. If S2_CONNECT is not listed as supported, S2_ONLINE obviously implies connect functionality. S2_CONNECT/S2_DISCONNECT do not nest. SEE ALSO S2_DISCONNECT
I propose that the following command number should be assigned:
#define S2_CONNECT 0xC005
S2_DISCONNECT
S2_CONNECT
in that it tears down a connection. It
uses the same Sana2Connection
structure and hooks, but most of these members
are ignored.The command should work as follows:
Sana2Connection
data structure,
initialize the s2c_Size
, s2c_Options
, s2c_ErrorHook
,
s2c_ConnectHook
, s2c_DisconnectHook
, s2c_Login
and
s2c_Password
fields. The s2c_Options
, s2c_ConnectHook
,
s2c_Login
and s2c_Password
fields will be ignored, but
the client should play things safe.
Sana2Connection
data structure is placed
in the ios2_Data
member of an IOSana2Req
, the command
is set to S2_DISCONNECT
and the request is sent via DoIO()
or SendIO()
.
s2c_DisconnectHook
may be invoked with the proper parameters.
Some drivers, such as for asynchronous PPP, will need the hook
to tell the modem to hang up the line. Some drivers, such as for
PPPoE, may not need this hook and thus ignore it.
IOSana2Req
is returned with an error code of zero, indicating
success. The SANA-II event S2EVENT_DISCONNECT
must be sent,
and, if necessary, S2EVENT_OFFLINE
.
The connect and disconnect hook functions must not be called from interrupt
code. For each hook only a Task
calling context of unknown priority must be
assumed. Also, stack space is provided only to call exec.library
and
utility.library
functions. The callback shall not place excessive data on the
stack. Stack space should be considered limited.
I propose a command with the following semantics:
NAME S2_DISCONNECT -- Go offline and close a link layer connection previously established with S2_CONNECT. FUNCTION This command complements the S2_CONNECT command in that it reverses the steps taken to establish a link layer connection. IO REQUEST ios2_Command - S2_DISCONNECT ios2_Data - Pointer to Sana2Connection structure ios2_BufferManagement - Magic cookie as returned when opening the driver with a struct IOSana2Req RESULTS ios2_Req.io_Error - Zero if successful; non-zero otherwise ios2_WireError - More specific error number NOTES If successful, this command implies S2_OFFLINE, i.e. the link layer is deallocated. The driver must ignore the S2_DISCONNECT command and recover gracefully if the S2_CONNECT was never sent or returned with an error. The contents of the Sana2Connection structure are valid only until the device driver has processed the command and returned the IOSana2Req. Any data the driver may need to retain beyond that point of time must be copied. Once the S2_DISCONNECT command has returned, it is safe to dispose of the Sana2Connection structure provided at S2_CONNECT time. Note that S2_OFFLINE does not necessarily imply S2_DISCONNECT, if the S2_DISCONNECT command is listed as supported by the driver via NSCMD_DEVICEQUERY. If S2_DISCONNECT is not listed as supported, S2_OFFLINE obviously implies disconnect functionality. S2_CONNECT/S2_DISCONNECT do not nest. SEE ALSO S2_CONNECT
I propose that the following command number should be assigned:
#define S2_DISCONNECT 0xC006
S2_SAMPLE_THROUGHPUT
struct Sana2ThroughputStats { ULONG s2ts_Length; ULONG s2ts_Actual; struct Task * s2ts_NotifyTask; ULONG s2ts_NotifyMask; struct timeval s2ts_StartTime; struct timeval s2ts_EndTime; S2QUAD s2ts_BytesSent; S2QUAD s2ts_BytesReceived; S2QUAD s2ts_Updates; };
Before I proceed to explain what purposes the individual members serve, a few
words on the S2QUAD
type, which is defined as follows:
typedef struct { ULONG s2q_High; ULONG s2q_Low; } S2QUAD;
In other words, the S2QUAD
type stands for an unsigned 64 bit big endian
integer, as expressed in ISO 'C' terms.
The structure members have the following purposes:
s2ts_Length
sizeof(struct Sana2ThroughputStats)
.
Smaller values are permitted, but these must
not be smaller than 8 (which covers the
s2ts_Length
and s2ts_Actual
members). A
driver which finds an s2ts_Length
< 8 must
treat this as an error and reject the command
with ios2_Req.io_Error
=IOERR_BADLENGTH
.
s2ts_Actual
s2ts_Length
.
s2ts_NotifyTask
Task
to notify whenever the contents of
this data structure change. This must be NULL
if no notification is desired.
Note: This feature should be used carefully, as
so much data may arrive that the driver
will almost be constantly signalling this
Task
that a change has taken place.
It is recommend that periodic polling be used, such as to update displays of a link monitoring program.
s2ts_NotifyMask
Task
whose address is found in s2ts_NotifyTask
(via Signal(s2ts->s2ts_NotifyTask,s2ts->s2ts_NotifyMask);
).
This must be zero if no notification is desired.
s2ts_StartTime
s2ts_EndTime
s2ts_BytesSent
s2ts_BytesReceived
s2ts_Updates
A driver implementing this command should take care to update the members
s2ts_EndTime
, s2ts_BytesSent
, s2ts_BytesReceived
and s2ts_Updates
atomically each time changes are made.
I propose a command with the following semantics:
NAME S2_SAMPLE_THROUGHPUT -- Obtain accurate information on driver data throughput. FUNCTION This command installs a data structure which is updated every time data is sent or received by the driver. This command must be sent via SendIO() or BeginIO(); until the associated I/O request is recalled using AbortIO(), the device unit will continue to update the Sana2ThroughputStats structure in real time. IO REQUEST ios2_Command - S2_SAMPLE_THROUGHPUT ios2_StatData - Pointer to Sana2ThroughputStats structure to fill in ios2_BufferManagement - Magic cookie as returned when opening the driver with a struct IOSana2Req RESULTS ios2_Req.io_Error - Zero if successful; non-zero otherwise NOTES If this device driver does not understand this command, it will immediately return the IOSana2Req with ios2_Req.io_Error set to IOERR_NOCMD. Otherwise, the request will remain queued until it is removed with AbortIO() later.
I propose that the following command number should be assigned:
#define S2_SAMPLE_THROUGHPUT 0xC007
S2_ONLINE
and S2_OFFLINE
This proposal introduces two new commands (S2_CONNECT
and S2_DISCONNECT
)
which are somewhat related to the S2_ONLINE
and S2_OFFLINE
commands. How
this relation works out shall be explained below. Note that the following text
assumes that both the S2_CONNECT
/S2_DISCONNECT
and S2_ONLINE
/S2_OFFLINE
command pairs are implemented.
S2_CONNECT
implies S2_ONLINE
and, if successful, may report
S2EVENT_ONLINE
and S2EVENT_CONNECT
events. If the unit is currently
disconnected, but still online, only the S2EVENT_CONNECT
event shall be sent.
Invoking the S2_CONNECT
command on a driver which is already connected must
be rejected with ios2_Req.io_Error=S2ERR_BAD_STATE
and
ios2_WireError=S2WERR_UNIT_CONNECTED
.
S2_DISCONNECT
implies S2_OFFLINE
and, if successful, may report
S2EVENT_OFFLINE
and S2EVENT_DISCONNECT
events. If the unit is curently
connected and offline, then only the S2EVENT_DISCONNECT
event shall be sent.
Invoking the S2_DISCONNECT
command on a driver which is already disconnected
must be rejected with ios2_Req.io_Error=S2ERR_BAD_STATE
and
ios2_WireError=S2WERR_UNIT_DISCONNECTED
.
S2_OFFLINE
may be used after the S2_CONNECT
has successfully connected the
unit. In this case the driver will release control over the link layer and
report the S2EVENT_OFFLINE
event. The connection established using the
S2_CONNECT
will, however, persist.
S2_ONLINE
may be used after S2_CONNECT
has successfully connected the unit
and the S2_OFFLINE
was used. In this case the driver will again try to
obtain control over the link layer and report the S2EVENT_ONLINE
event if
successful.
If the S2_CONNECT
command was never successfully executed, then the commands
S2_ONLINE
and S2_OFFLINE
must be rejected with
ios2_Req.io_Error=S2ERR_BAD_STATE
and ios2_WireError=S2WERR_UNIT_DISCONNECTED
.
S2_DEVICEQUERY
The Sana2DeviceQuery
structure filled in by the S2_DEVICEQUERY
command
provides for information on the device's properties, including the maximum
transmission unit (MTU) that may be used. What is not specifically covered is
the 'raw' MTU a device may offer. In this context 'raw' means the number of
bytes that are available for reading and writing when using the SANA2IOB_RAW
flag with a CMD_READ
/CMD_WRITE
request on a device that supports these access
methods. Currently, software developers can only make assumptions on how many bytes might
comprise the 'raw' MTU by checking the Sana2DeviceQuery.HardwareType
member
and hoping that the driver supports raw CMD_READ
/CMD_WRITE
access.
I propose that the S2_DEVICEQUERY
command and the associated Sana2DeviceQuery
structure are extended to allow for the raw MTU to be queried. The new
Sana2DeviceQuery
structure would look like this:
struct Sana2DeviceQuery { /* ** Standard information */ ULONG SizeAvailable; /* bytes available */ ULONG SizeSupplied; /* bytes supplied */ LONG DevQueryFormat; /* this is type 0 */ LONG DeviceLevel; /* this document is level 0 */ /* ** Common information */ UWORD AddrFieldSize; /* address size in bits */ ULONG MTU; /* maximum packet data size */ LONG bps; /* line rate (bits/sec) */ LONG HardwareType; /* what the wire is */ ULONG RawMTU; /* maximum raw packet data size */ /* ** Format specific information */ };
The RawMTU
member is new. Devices which do not know and support this structure
member may fill in the Sana2DeviceQuery
structure only up to and including the
HardwareType
member.
Devices which know and support the RawMTU
member must fill it with a
well-defined value. For Amiga Ethernet drivers, that value would be 1514,
which is the standard MTU value of 1500 bytes plus the size of the Ethernet
frame header, as per RFC894 (six bytes for the destination address, six bytes for the source
address and two bytes for the frame type; the eight byte preamble and the
terminating four byte CRC value are typically not under the control of the
driver). Drivers which do not support raw read or write access must set the
RawMTU
member to zero.
If the RawMTU
member is not provided, all bets are off and the application
software must fall back to making estimates based upon the hardware type and
the raw frame types it wishes to read and write. Ultimatively, the driver
itself must decide whether it can accept raw read and write commands (or has
to reject them with S2ERR_NOT_SUPPORTED
) and whether the raw packet size is
still covered by the underlying hardware MTU (or must be rejected with
S2ERR_MTU_EXCEEDED
).
A word of warning: a little testing with various Ethernet hardware drivers has
revealed that the A2065 driver a2065.device
does not handle the
S2_DEVICEQUERY
command properly if the Sana2DeviceQuery
structure provided is larger than 30 bytes. In other words, the command will
fail if the proposed RawMTU
member is present in the query data
structure to be filled in.
S2EVENT_CONFIGCHANGED
The SANA-II standard does not cover protocols or devices which can change
their properties during operation, such as the hardware address of the
underlying driver. For drivers such as those which implement the proposed
S2_GETPEERADDRESS
and S2_GETDNSADDRESS
commands it is vital that such changes
can take place and be noticed by the client software. For this purpose I
propose that a new event type is introduced, to be used with the SANA-II
S2_ONEVENT
command, using the following definition:
#define S2EVENT_CONFIGCHANGED (1L<<8)
This event should be triggered whenever client-visible configuration
information changes, as can be queried via the S2_DEVICEQUERY
,
S2_GETSTATIONADDRESS
, S2_GETSPECIALSTATS
, S2_GETGLOBALSTATS
, S2_GETPEERADDRESS
and S2_GETDNSADDRESS
commands. Here is a short list of what could change:
S2_DEVICEQUERY
AddrFieldSize
, MTU
, BPS
S2_GETSTATIONADDRESS
ios2_SrcAddr
S2_GETGLOBALSTATS
Reconfigurations
, LastStart
S2_GETPEERADDRESS
ios2_SrcAddr
, ios2_DstAddr
S2_GETDNSADDRESS
ios2_SrcAddr
, ios2_DstAddr
The purpose of this event is not to post a notification whenever another byte or event counter has changed so that a monitoring program may update its display. The purpose is to convey to the client software that an important device configuration option has changed and that it is supposed to react and adapt to it. For example, a TCP/IP stack may, upon learning that a device's IP address has changed, rebuild its routing table.
Since the S2EVENT_CONFIGCHANGED
event may arrive at any time and does not
indicate what exactly has changed, application software should query the
information it expects to change during its life time, and keep a copy of it
around for later reference. When the S2EVENT_CONFIGCHANGED
event arrives, it
can compare the contents of the copy against the current state of affairs and
act according to the differences it finds.
S2EVENT_CONNECT
This event is a counterpart to S2EVENT_ONLINE
, and is associated with the
S2_CONNECT
command. I propose the following semantics:
#define S2EVENT_CONNECT (1L<<9) /* Driver has opened session */
The event is to be sent when the driver has successfully established a link layer connection.
S2EVENT_DISCONNECT
This event is a counterpart to S2EVENT_OFFLINE
, and is associated with the
S2_DISCONNECT
command. I propose the following semantics:
#define S2EVENT_DISCONNECT (1L<<10) /* Driver has closed session */
The event is to be sent when the driver has closed the link layer connection
previously established by the S2_CONNECT
command.
S2WERR_UNIT_DISCONNECTED
This error code is a counterpart to S2WERR_UNIT_OFFLINE
. It indicates that the
associated command could not be executed because the link layer is not
connected.
I propose the following semantics:
#define S2WERR_UNIT_DISCONNECTED 19 /* unit is currently not connected */
S2WERR_UNIT_CONNECTED
This error code is a counterpart to S2WERR_UNIT_ONLINE
. It indicates that the
associated command could not be executed because the link layer is already
connected.
I propose the following semantics:
#define S2WERR_UNIT_CONNECTED 20 /* unit is currently connected */
S2WERR_INVALID_OPTION
This error code indicates that an option, such as passed by the S2_CONNECT
command, is not acceptable. The option's value may be out of range or may not
match the syntax specifications. To indicate which option that may be, a
different mechanism must be used; a simple indication that something was wrong
is not sufficient.
I propose the following semantics:
#define S2WERR_INVALID_OPTION 21 /* invalid option rejected */
S2WERR_MISSING_OPTION
This error code indicates that a mandatory option, such as passed by the
S2_CONNECT
command, is not present. To indicate which option that may be, a
different mechanism must be used; a simple indication that something was wrong
is not sufficient.
I propose the following semantics:
#define S2WERR_MISSING_OPTION 22 /* a mandatory option is missing */
S2WERR_AUTHENTICATION_FAILED
Some drivers run protocols that require them to authenticate to a server. That process may fail. This wire error code is to indicate this fact.
I propose the following semantics:
#define S2WERR_AUTHENTICATION_FAILED 23 /* could not log in */
S2_DMACopyToBuff64
and S2_DMACopyFromBuff64
These two callbacks are identical in operation to the S2_DMACopyToBuff32
and
S2_DMACopyFromBuff32
callbacks, as specified in the SANA-IIR3 standard. The
difference is in that the memory region DMA is to take place in must be
aligned to a 64 bit boundary and must be large enough to hold data that is a
multiple of 64 bits in size. The purpose of these hooks is to allow for 64
bit aligned PCI DMA accesses to take place.
I propose that the following numbers should be assigned:
#define S2_DMACopyFromBuff64 (S2_Dummy + 11)#define S2_DMACopyToBuff64 (S2_Dummy + 10)
S2_Log
A driver may want to report an important event for the user to see. Adding a
log message to a file or opening a window to display a message in may not be
the optimum approach as the user may be unaware of the context into which the
message belongs. It may be advisable for the driver to use the message
reporting and logging facilities used by the client software that uses its
services, such as a TCP/IP stack. The S2_Log
callback hook is intended to
provide for such a link. If present, the driver must use this callback hook
rather than whatever logging methods it implements itself. Note that unlike
the other SANA-II callbacks, this is a regular hook, as to be invoked using
utility.library
/CallHookPkt()
. The hook function is invoked using the
following parameters:
log_hook_function(hook,reserved,message) A0 A2 A1 void log_hook_function(struct hook * hook,APTR reserved, struct S2LogMessage * message);
The reserved
parameter must be set to NULL
. The S2LogMessage
structure passed
as the third parameter looks like this:
struct S2LogMessage { LONG s2lm_Size; ULONG s2lm_Priority; STRPTR s2lm_Name; STRPTR s2lm_Message; };
The individual structure members serve the following functions:
s2lm_Size
S2LogMessage
structure, in bytes. The idea is to
extend this data structure in the future, and the size stored
in here tells you how long the structure is. The size must
always be >= 16.
s2lm_Priority
syslog()
mechanism):
#define S2LOG_Emergency 0
#define S2LOG_Alert 1
#define S2LOG_Critical 2
#define S2LOG_Error 3
#define S2LOG_Warning 4
#define S2LOG_Notice 5
#define S2LOG_Information 6
#define S2LOG_Debug 7
s2lm_Name
NUL
-terminated string which identifies
the source of this message. This can be NULL
in which
case the name is treated as being unknown.
s2lm_Message
NUL
-terminated string which contains the
log message. The text should not contain any formatting
characters such as line feeds or carriage returns.
The s2lm_Message
member must never be NULL
.All error messages issued by the device driver should use the current system locale wherever this is possible. The purpose of an error message is, after all, to assist the user in recovering from the error. Which may be difficult if the user does not even know the language in which the message is written.
The log message string is valid until the log hook function returns. If the driver needs to retain the message any longer, it must make a copy of it.
Since the client software into which the log hook calls may have to allocate
memory to hold and display the log message, the log hook must not be called
from interrupt code. The log hook shall not Wait()
and it shall assume only
a Task
calling context of unknown priority. dos.library
functions may not
be called. Also, stack space is provided only to call exec.library
and
utility.library
functions. The callback shall not place excessive data on
the stack. Stack space should be considered limited and the callback
should be designed to be fast and short.
This hook is installed at OpenDevice()
time, which means that the hook is used
for the unit that was opened, and not just for the I/O request it was opened
with. The hook must remain installed until the I/O request that installed it
is eventually used to close the device. When this happens, the device should
fall back to use no log hook at all. No nesting is permitted or required.
I propose that the following number should be assigned:
#define S2_Log (S2_Dummy + 12)
This is an attempt to clarify part of the specification and to lay down a few rules that every SANA-II driver should follow in addition to the requirements described in the existing specifications. Here is what I propose:
S2_BROADCAST
command.
Likewise, if no multicast mechanism is supported, the
S2_MULTICAST
must not be implemented either.
IOERR_NOCMD
error code. Commands that are implemented, but which cannot
perform the requested services, must be rejected with the
S2ERR_NOT_SUPPORTED
error code. The difference between the
two cases is in when the decision is made whether a command
can be handled or not. Which commands should return IOERR_NOCMD
is decided upon at the time the driver is designed and implemented.
At this stage the implementor knows for sure which capabilities the
driver will have and which it will not have. Commands which the
driver will never be able to execute will be made to return the
IOERR_NOCMD
error code. If the decision whether a command can be
executed is made only at run time, by evaluating the conditions
under which a command can be executed, then the error code
S2ERR_NOT_SUPPORTED
should be returned in case of failure.
struct IOStdReq
. This is necessary for the NewStyleDevices
query command to work. In the command dispatcher, the driver
must verify that all SANA-II commands are invoked with a
proper size struct IOSana2Req
I/O request. If the
I/O request is shorter (as can be verified by looking at
the embedded Message's mn_Length
member), the command must
be rejected with ios2_Req.io_Error=IOERR_BADLENGTH
.
NSCMD_DEVICEQUERY
command, in conformance with the NSD specification 1.6 or
newer. The motivation for this is to have a mechanism
available for probing the capabilities of the driver, and
the supported command set can provide for vital clues. In
this context, the absence of the S2_BROADCAST
command would
suggest that the driver cannot send or receive broadcast
messages.
S2_CONFIGINTERFACE
command may silently ignore
the command (returning it without setting an error condition)
and even pretend that it can be configured more than once.
S2_DEVICEQUERY
, S2_GETSPECIALSTATS
and
S2_GETGLOBALSTATS
commands a driver may return information
that is not entirely correct if it has to go online before
it can provide for the correct data. For example, the
maximum transmission unit for PPP is a number in the
range of [1..1500] which is negotiated during the
protocol configuration process. It is unlikely that numbers
greater than 1500 will be used, yet it is still not
impossible. Since the actual number will be known only after
the driver has configured the protocol, the MTU value returned
before the session was opened can differ from the MTU value
valid after it has been opened. A driver should therefore
attempt to return 'safe' defaults in place of information
that is unavailable at the time it is queried. The 'safe' values
shall be set up to allow the driver to work even if the protocol
stack is not aware of later changes to those values. Beware of
zero-length buffer sizes or time intervals that may cause client
software to perform zero-length memory allocations or divisions
by zero.
To simplify client software configuration, drivers may treat packet type 2048 as equivalent to the packet number associated with IP frames. This association is permitted only if it does not introduce ambiguity. For example, this association would not be permitted if the driver would receive and transmit IP packets in two different frame types or if the driver already associates packet type 2048 with non-IP packets.
Sana2DeviceQuery
structure in the future?
The current layout separates standard, common and
format specific information, but there is no hint as to where
which each section starts and where the next begins. Now that
there is a proposal to add a new field to the common section,
how would you add fields to the format specific section?
Changes since 24-Dec-2002:
Sana2Connection
data structure used by the S2_CONNECT
command now must remain valid until the S2_DISCONNECT
command
is sent (see section 2.4).
Changes since 01-May-2002:
ppp.async.readrequests
and ppp.async.eof
configuration keywords.
Changes since 04-Jan-2002:
ppp.dummyremoteaddress
and ppp.ethernet.ac
configuration keywords.
Changes since 10-Dec-2001:
<devices/sana2.h>
header file to the appendix.
S2_DMACopyToBuff64
and S2_DMACopyFromBuff64
hooks
refers to bits and not to bytes.
Changes since 19-Nov-2001:
ppp.idletimeout
,
ppp.peeridletimeout
, ppp.sendid
).
Sana2ExtDeviceStats
structure.
S2QUAD
type is a big endian integer.
S2_CONNECT
/S2_DISCONNECT
and
S2_ONLINE
/S2_OFFLINE
commands.
Sana2DeviceQuery.RawMTU
field,
clarifying what is included in the the Ethernet RawMTU
.
<devices/sana2.h>
header file. Note that there is
no equivalent "devices/sana2.i"
header file yet.
Changes since 12-Nov-2001:
S2_GETPEERADDRESS
, S2_GETDNSADDRESS
,
S2_GETEXTENDEDGLOBALSTATS
, S2_CONNECT
, S2_DISCONNECT
and
S2_SAMPLE_THROUGHPUT
to be NSD-compliant. Also assigned a new
number to the S2_SAMPLE_THROUGHPUT
command.
Sana2DeviceQuery
structure.
Changes since 03-Nov-2001:
S2_GETNEWGLOBALSTATS
to S2_GETEXTENDEDGLOBALSTATS
(see
section 2.3).
S2_GETEXTENDEDGLOBALSTATS
now uses 64 bit quantities for
the s2xds_PacketsReceived
, s2xds_PacketsSent
, s2xds_BadData
,
s2xds_Overruns
, s2xds_UnknownTypesReceived
and
s2xds_Reconfigurations
counters.
S2_SAMPLE_THROUGHPUT
command was modified to use
64 bit integers for all members of the Sana2ThroughputStats
structure.
ios2_BufferManagement
field.
ios2_Error
have been replaced with
ios2_Req.io_Error
.
IOERR_NOCMD
/S2ERR_NOT_SUPPORTED
error
codes is clarified.
S2_CONNECT
and S2_DISCONNECT
commands now specifically mention
the life time of the data they have to deal with.
Changes since 14-Oct-2001:
S2_CONNECT
and S2_DISCONNECT
commands.
S2EVENT_CONNECT
and S2EVENT_DISCONNECT
events.
S2_CONNECT
/S2_DISCONNECT
from section 7
("Unsolved problems").
<devices/sana2.h>
header file
Attached below you will find the updated <devices/sana2.h>
header file,
which includes corrections and definitions for all the proposed changes:
#ifndef SANA2_SANA2DEVICE_H #define SANA2_SANA2DEVICE_H 1 /* ** $Filename$ ** $Revision: 1.1 $ ** $Date: 2005-06-09 08:46:16 $ ** ** Structure definitions for SANA-II devices. ** ** (C) Copyright 1991-2002 Amiga, Inc. ** All Rights Reserved */ #ifndef EXEC_TYPES_H #include <exec/types.h> #endif #ifndef EXEC_PORTS_H #include <exec/ports.h> #endif #ifndef EXEC_IO_H #include <exec/io.h> #endif #ifndef EXEC_TASKS_H #include <exec/tasks.h> #endif #ifndef EXEC_ERRORS_H #include <exec/errors.h> #endif #ifndef DEVICES_TIMER_H #include <devices/timer.h> #endif #ifndef UTILITY_TAGITEM_H #include <utility/tagitem.h> #endif #ifndef UTILITY_HOOKS_H #include <utility/hooks.h> #endif #define SANA2_MAX_ADDR_BITS (128) #define SANA2_MAX_ADDR_BYTES ((SANA2_MAX_ADDR_BITS+7)/8) struct IOSana2Req { struct IORequest ios2_Req; ULONG ios2_WireError; /* wire type specific error */ ULONG ios2_PacketType; /* packet type */ UBYTE ios2_SrcAddr[SANA2_MAX_ADDR_BYTES]; /* source address */ UBYTE ios2_DstAddr[SANA2_MAX_ADDR_BYTES]; /* dest address */ ULONG ios2_DataLength; /* length of packet data */ APTR ios2_Data; /* packet data */ APTR ios2_StatData; /* statistics data pointer */ APTR ios2_BufferManagement; /* see SANA-II OpenDevice adoc */ }; /* ** Defines for the io_Flags field */ #define SANA2IOB_RAW (7) /* raw packet IO requested */ #define SANA2IOB_BCAST (6) /* broadcast packet (received) */ #define SANA2IOB_MCAST (5) /* multicast packet (received) */ #define SANA2IOB_QUICK (IOB_QUICK) /* quick IO requested (0) */ #define SANA2IOF_RAW (1<<SANA2IOB_RAW) #define SANA2IOF_BCAST (1<<SANA2IOB_BCAST) #define SANA2IOF_MCAST (1<<SANA2IOB_MCAST) #define SANA2IOF_QUICK (IOF_QUICK) /* ** Defines for OpenDevice() flags */ #define SANA2OPB_MINE (0) /* exclusive access requested */ #define SANA2OPB_PROM (1) /* promiscuous mode requested */ #define SANA2OPF_MINE (1<<SANA2OPB_MINE) #define SANA2OPF_PROM (1<<SANA2OPB_PROM) /* ** Defines for OpenDevice() tags */ #define S2_Dummy (TAG_USER + 0xB0000) #define S2_CopyToBuff (S2_Dummy + 1) #define S2_CopyFromBuff (S2_Dummy + 2) #define S2_PacketFilter (S2_Dummy + 3) #define S2_CopyToBuff16 (S2_Dummy + 4) #define S2_CopyFromBuff16 (S2_Dummy + 5) #define S2_CopyToBuff32 (S2_Dummy + 6) #define S2_CopyFromBuff32 (S2_Dummy + 7) #define S2_DMACopyToBuff32 (S2_Dummy + 8) #define S2_DMACopyFromBuff32 (S2_Dummy + 9) #define S2_DMACopyToBuff64 (S2_Dummy + 10) #define S2_DMACopyFromBuff64 (S2_Dummy + 11) #define S2_Log (S2_Dummy + 12) /* ** Filled in by 'S2_DEVICEQUERY' */ struct Sana2DeviceQuery { /* ** Standard information */ ULONG SizeAvailable; /* bytes available */ ULONG SizeSupplied; /* bytes supplied */ ULONG DevQueryFormat; /* this is type 0 */ ULONG DeviceLevel; /* this document is level 0 */ /* ** Common information */ UWORD AddrFieldSize; /* address size in bits */ ULONG MTU; /* maximum packet data size */ ULONG BPS; /* line rate (bits/sec) */ ULONG HardwareType; /* what the wire is (see below) */ ULONG RawMTU; /* maximum raw packet data size */ /* ** Format specific information */ }; /* ** Defined Hardware types ** ** If your hardware type is not listed below contact Amiga to get ** a new type number added for your hardware. */ #define S2WireType_Ethernet 1 #define S2WireType_IEEE802 6 #define S2WireType_Arcnet 7 #define S2WireType_LocalTalk 11 #define S2WireType_DyLAN 12 #define S2WireType_AmokNet 200 /* Amiga Floppy Port hardware */ #define S2WireType_Liana 202 /* Village Tronic parallel port hw */ #define S2WireType_PPP 253 #define S2WireType_SLIP 254 #define S2WireType_CSLIP 255 /* Compressed SLIP */ #define S2WireType_PLIP 420 /* SLIP over a parallel port */ /* ** Filled in by 'S2_GETTYPESTATS' */ struct Sana2PacketTypeStats { ULONG PacketsSent; /* transmitted count */ ULONG PacketsReceived; /* received count */ ULONG BytesSent; /* bytes transmitted count */ ULONG BytesReceived; /* bytes received count */ ULONG PacketsDropped; /* packets dropped count */ }; /* ** Filled in by 'S2_GETSPECIALSTATS' */ struct Sana2SpecialStatRecord { ULONG Type; /* statistic identifier */ ULONG Count; /* the statistic */ STRPTR String; /* statistic name */ }; struct Sana2SpecialStatHeader { ULONG RecordCountMax; /* room available */ ULONG RecordCountSupplied; /* number supplied */ /* struct Sana2SpecialStatRecord[RecordCountMax]; */ }; /* ** Filled in by 'S2_GETGLOBALSTATS' */ struct Sana2DeviceStats { ULONG PacketsReceived; /* received count */ ULONG PacketsSent; /* transmitted count */ ULONG BadData; /* bad packets received */ ULONG Overruns; /* hardware miss count */ ULONG Unused; /* Unused field */ ULONG UnknownTypesReceived; /* orphan count */ ULONG Reconfigurations; /* network reconfigurations */ struct timeval LastStart; /* time of last online */ }; /* ** A 64 bit big endian integer in ISO 'C' terms. */ typedef struct { ULONG s2q_High; ULONG s2q_Low; } S2QUAD; /* ** Revised version, filled in by 'S2_GETEXTENDEDGLOBALSTATS' */ struct Sana2ExtDeviceStats { ULONG s2xds_Length; ULONG s2xds_Actual; S2QUAD s2xds_PacketsReceived; S2QUAD s2xds_PacketsSent; S2QUAD s2xds_BadData; S2QUAD s2xds_Overruns; S2QUAD s2xds_UnknownTypesReceived; S2QUAD s2xds_Reconfigurations; struct timeval s2xds_LastStart; struct timeval s2xds_LastConnected; struct timeval s2xds_LastDisconnected; struct timeval s2xds_TimeConnected; }; /* ** Used by 'S2_CONNECT' and 'S2_DISCONNECT' */ struct Sana2Connection { ULONG s2c_Size; struct MinList s2c_Options; struct Hook s2c_ErrorHook; struct Hook s2c_ConnectHook; struct Hook s2c_DisconnectHook; STRPTR s2c_Login; STRPTR s2c_Password; }; struct Sana2ConnectionOption { struct MinNode s2co_MinNode; STRPTR s2co_Name; STRPTR s2co_Value; }; struct Sana2ConnectionMessage { ULONG s2cm_Size; struct Sana2Connection * s2cm_Connection; struct IORequest * s2cm_Request[2]; LONG s2cm_RequestType; }; /* ** Used by 'S2_SAMPLE_THROUGHPUT' */ struct Sana2ThroughputStats { ULONG s2ts_Length; ULONG s2ts_Actual; struct Task * s2ts_NotifyTask; ULONG s2ts_NotifyMask; struct timeval s2ts_StartTime; struct timeval s2ts_EndTime; S2QUAD s2ts_BytesSent; S2QUAD s2ts_BytesReceived; S2QUAD s2ts_Updates; }; /* ** Used by the 'S2_Log' callback hook */ struct S2LogMessage { LONG s2lm_Size; ULONG s2lm_Priority; STRPTR s2lm_Name; STRPTR s2lm_Message; }; /* ** Log priority levels used by the 'S2_Log' callback hook */ #define S2LOG_Emergency 0 /* A panic condition */ #define S2LOG_Alert 1 /* A condition that should be corrected immediately */ #define S2LOG_Critical 2 /* Critical conditions */ #define S2LOG_Error 3 /* A plain error */ #define S2LOG_Warning 4 /* A warning message */ #define S2LOG_Notice 5 /* Conditions that are not error conditions, but should possibly be handled specially */ #define S2LOG_Information 6 /* An informational message */ #define S2LOG_Debug 7 /* Generated only in debugging mode */ /* ** Device Commands */ #define S2_START (CMD_NONSTD) /* First old style command */ #define S2_DEVICEQUERY (S2_START+ 0) #define S2_GETSTATIONADDRESS (S2_START+ 1) #define S2_CONFIGINTERFACE (S2_START+ 2) #define S2_ADDMULTICASTADDRESS (S2_START+ 5) #define S2_DELMULTICASTADDRESS (S2_START+ 6) #define S2_MULTICAST (S2_START+ 7) #define S2_BROADCAST (S2_START+ 8) #define S2_TRACKTYPE (S2_START+ 9) #define S2_UNTRACKTYPE (S2_START+10) #define S2_GETTYPESTATS (S2_START+11) #define S2_GETSPECIALSTATS (S2_START+12) #define S2_GETGLOBALSTATS (S2_START+13) #define S2_ONEVENT (S2_START+14) #define S2_READORPHAN (S2_START+15) #define S2_ONLINE (S2_START+16) #define S2_OFFLINE (S2_START+17) #define S2_END (S2_START+18) /* Last old style command */ /* ** New style commands introduced in 1997 and beyond */ #define S2_ADDMULTICASTADDRESSES 0xC000 #define S2_DELMULTICASTADDRESSES 0xC001 #define S2_GETPEERADDRESS 0xC002 #define S2_GETDNSADDRESS 0xC003 #define S2_GETEXTENDEDGLOBALSTATS 0xC004 #define S2_CONNECT 0xC005 #define S2_DISCONNECT 0xC006 #define S2_SAMPLE_THROUGHPUT 0xC007 /* ** Defined errors for io_Error (see also <exec/errors.h>) */ #define S2ERR_NO_ERROR 0 /* peachy-keen */ #define S2ERR_NO_RESOURCES 1 /* resource allocation failure */ #define S2ERR_BAD_ARGUMENT 3 /* garbage somewhere */ #define S2ERR_BAD_STATE 4 /* inappropriate state */ #define S2ERR_BAD_ADDRESS 5 /* who? */ #define S2ERR_MTU_EXCEEDED 6 /* too much to chew */ #define S2ERR_NOT_SUPPORTED 8 /* hardware can't support cmd */ #define S2ERR_SOFTWARE 9 /* software error detected */ #define S2ERR_OUTOFSERVICE 10 /* driver is OFFLINE */ #define S2ERR_TX_FAILURE 11 /* Transmission attempt failed */ /* ** From <exec/errors.h> ** ** IOERR_OPENFAIL (-1) * device/unit failed to open * ** IOERR_ABORTED (-2) * request terminated early [after AbortIO()] * ** IOERR_NOCMD (-3) * command not supported by device * ** IOERR_BADLENGTH (-4) * not a valid length (usually IO_LENGTH) * ** IOERR_BADADDRESS (-5) * invalid address (misaligned or bad range) * ** IOERR_UNITBUSY (-6) * device opens ok, but requested unit is busy * ** IOERR_SELFTEST (-7) * hardware failed self-test * */ /* ** Defined errors for ios2_WireError */ #define S2WERR_GENERIC_ERROR 0 /* no specific info available */ #define S2WERR_NOT_CONFIGURED 1 /* unit not configured */ #define S2WERR_UNIT_ONLINE 2 /* unit is currently online */ #define S2WERR_UNIT_OFFLINE 3 /* unit is currently offline */ #define S2WERR_ALREADY_TRACKED 4 /* protocol already tracked */ #define S2WERR_NOT_TRACKED 5 /* protocol not tracked */ #define S2WERR_BUFF_ERROR 6 /* buff mgt func returned error */ #define S2WERR_SRC_ADDRESS 7 /* source address problem */ #define S2WERR_DST_ADDRESS 8 /* destination address problem */ #define S2WERR_BAD_BROADCAST 9 /* broadcast address problem */ #define S2WERR_BAD_MULTICAST 10 /* multicast address problem */ #define S2WERR_MULTICAST_FULL 11 /* multicast address list full */ #define S2WERR_BAD_EVENT 12 /* unsupported event class */ #define S2WERR_BAD_STATDATA 13 /* statdata failed sanity check */ /*** THERE IS NO WIRE ERROR CODE 14 ***/ #define S2WERR_IS_CONFIGURED 15 /* attempt to config twice */ #define S2WERR_NULL_POINTER 16 /* null pointer detected */ #define S2WERR_TOO_MANY_RETRIES 17 /* tx failed - too many retries */ #define S2WERR_RCVREL_HDW_ERR 18 /* Driver fixable HW error */ #define S2WERR_UNIT_DISCONNECTED 19 /* unit is currently not connected */ #define S2WERR_UNIT_CONNECTED 20 /* unit is currently connected */ #define S2WERR_INVALID_OPTION 21 /* invalid option rejected */ #define S2WERR_MISSING_OPTION 22 /* a mandatory option is missing */ #define S2WERR_AUTHENTICATION_FAILED 23 /* could not log in */ /* ** For our dsylexic friends */ #define S2WERR_TOO_MANY_RETIRES S2WERR_TOO_MANY_RETRIES /* ** Defined events */ #define S2EVENT_ERROR (1L<< 0) /* error catch all */ #define S2EVENT_TX (1L<< 1) /* transmitter error catch all */ #define S2EVENT_RX (1L<< 2) /* receiver error catch all */ #define S2EVENT_ONLINE (1L<< 3) /* unit is in service */ #define S2EVENT_OFFLINE (1L<< 4) /* unit is not in service */ #define S2EVENT_BUFF (1L<< 5) /* buff mgt function error */ #define S2EVENT_HARDWARE (1L<< 6) /* hardware error catch all */ #define S2EVENT_SOFTWARE (1L<< 7) /* software error catch all */ #define S2EVENT_CONFIGCHANGED (1L<< 8) /* driver configuration changed */ #define S2EVENT_CONNECT (1L<< 9) /* driver has opened session */ #define S2EVENT_DISCONNECT (1L<<10) /* driver has closed session */ #endif /* SANA2_SANA2DEVICE_H */