m376(7) — SPECIAL FILES AND DEVICES
NAME
m376 − MVME376 Local Area Network Interface
SYNOPSIS
#include <sys/dlpi.h>
#include <sys/macioctl.h>
fd = open("/dev/m376_c0", O_RDWR);
DESCRIPTION
The MVME376 is a VMEbus Local Area Network Controller for Ethernet and IEEE 802.3 compatible networks. The MVME376 utilizes the on-board combination of an Am7990 Local Area Network Controller (LANCE), an Am7992B Serial Interface Adapter (SIA), and 256Kbytes of dual ported RAM. The m376 device driver supports TCP/IP and OSI protocol stacks. A maximum of 4 (four) boards may be configured in a single system.
The m376 is a STREAMS-based software driver used with the MVME376 Ethernet board. The m376 interface conforms to the Data Link Provider Interface (DLPI). In addition, the m376 driver accepts the MAC management commands specified in the MAC Provider Interface (MPI).
The m376 driver can be opened directly, or indirectly from the clone device driver. During the TCP/IP startup, the m376 device is clone opened and linked to the IP and ARP STREAMS modules via the slink command. From then on, m376 converts all the outgoing packets received from IP/ARP to the format defined by the MVME376 board and then passes these packets to the board. If the OSI-DP package is installed on the system and linked into the kernel, the m376 driver will accept outgoing packets from the DLR (OSI LLC1) module.
Upon receiving incoming packets from the MVME376 board, m376 converts these packets to the STREAMS-based DLPI format messages and passes these packets to the appropriate user (e.g., ARP, IP, or DLR).
The mvme376 namer program creates or deletes the device special files for the m376 driver at boot time. The device special filenames, representing the clone devices, are composed of the string m376_cy, where y is the controller number. Controllers are numbered beginning at 0. The device special filename for the first controller in the system is /dev/m376_c0. If a second MVME376 board exists, then its device filename would be /dev/m376_c1. A third controller would have a device filename of /dev/m376_c2, and so on. The maximum number of controllers allowed by the driver is eight, but the /stand/edt_data file currently supports only four (4) MVME376 boards.
An m376 device special file major device number is the major device number of the clone device driver. An m376 minor device number follows the format described in the intro(7) man page, i.e., bits 17 through 15 contain the controller number, bit 14 is set, and bits 13 through 0 contain the real major number, which is found in the file /etc/master.d/mvme376.
Besides the device special filename, the driver prefix, m376, is also used as part of the Ethernet network interface name by both cenet in the network database file /etc/strcf and ifconfig in the script /etc/inet/rc.inet.
Each m376 device may have up to seven (7) minor devices open simultaneously. If no changes are made to the default /etc/strcf file, slink will, on TCP/IP startup, open minor devices 0 and 1 via the clone device, m376_c0, and link these to IP and ARP, respectively. Users may want to create their own direct-open minor device files (such as /dev/m376_c0d0, /dev/m376_c0d1, ..., /dev/m376_c0d6). Users wishing to access the driver through these direct-open devices instead of the clone device should consider starting with the last device and working their way backwards.
USAGE
STREAM Message Processing
The following are the types of STREAMS messages the driver can process:
M_PROTO/M_PCPROTO
Six DLPI protocol message types are supported: DL_INFO_REQ, DL_UNITDATA_REQ, DL_BIND_REQ, DL_UNBIND_REQ, DL_ENABMULTI_REQ, and DL_DISABMULTI_REQ. Unsupported message types that are received cause an error message of type dl_error_ack_t with dl_errno set to DL_NOTSUPPORTED to be sent back up the stream.
DL_INFO_REQ is a request for driver information. Driver information is passed back up the stream in a message of type dl_info_ack_t with dl_primitive set to DL_INFO_ACK. However, if enough memory is not available for the driver information, an error message of type dl_error_ack_t is sent back up the stream with dl_primitive set to DL_ERROR_ACK.
DL_UNITDATA_REQ is a request to transmit data. The message is in the dl_unitdata_req_t format. The driver will process this message and send data to the appropriate destination address. Most errors that can occur during this message are turned around in the message itself and sent back up stream in a message with dl_primitive set to DL_UDERROR_IND. If enough memory is not available for processing, an error message of type dl_error_ack_t is sent back up the stream with dl_primitive set to DL_ERROR_ACK.
DL_BIND_REQ is a request to bind a service access point (SAP) to the minor device number associated with the current stream. The request message is of type dl_bind_req_t. A SAP type, as long as it is valid, is assumed to be an Ethernet binding if it is not equal to IEEE8023_TYPE. Any Ethernet type can be used as a binding SAP. Only one stream may use IEEE8023_TYPE as a SAP. All IEEE802.3 frames will be sent up this stream. If the OSI-DP package has been installed, the DLR module will bind to this SAP and will receive all 802.3 frames. Once the stream has been bound, an acknowledgement message type dl_bind_ack_t is sent back up the stream. Errors generated during the processing of this message that cause an error message of type dl_error_ack_t to be sent back up the stream are: stream already bound, bad sap value, and cannot allocate memory for acknowledgement.
DL_UNBIND_REQ is a request to unbind the minor device associated with the current stream. Errors generated during message processing that cause an error message of type dl_error_ack_t are: minor device is not bound and cannot allocate enough memory for acknowledgement. An acknowledgement message of type dl_ok_ack_t is generated when the stream has been unbound.
DL_ENABMULTI_REQ is a request to enable a multicast address on a per-stream basis. An individual stream may have a maximum of sixty-four multicast addresses in its table, subject to the following limitation. There may be no more than sixty-four unique addresses for all streams associated with each controller. An acknowledgement message of type dl_ok_ack_t is generated if the request is valid. A message of type dl_error_ack_t is generated with dl_primitive set to DL_BADADDR if the multicast address is invalid or dl_primitive set to DL_TOOMANY if there is no space left in the controller’s multicast table.
DL_DISABMULTI_REQ is a request to disable a multicast address on a per-stream basis. An acknowledgement message of type dl_ok_ack_t is generated if the request is valid. A message of type dl_error_ack_t is generated with dl_primitive set to DL_BADADDR if the multicast address is invalid or dl_primitive set to DL_NOTENAB if the requested address is not currently enabled.
M_IOCTL
ioctl commands are received in messages of type iocblk. Command data, as specified in each command description, must be stored in a connected message block of type M_DATA. Data passed back upstream is always contained in an M_DATA block. All of the ioctl #defines used can be found in the file include/sys/macioctl.h.
A description of user ioctl stream messages can be found under the I_STR command in streamio(7). A sample code extract showing the STREAMS ioctl interface can be found in the STREAMS Mechanism chapter of the Programmer’s Guide: STREAMS.
MACIOC_DUMPSTATS is a request to display the driver software and hardware statistics to the system console. This command does not require an M_DATA block. Since this command uses printf to display the statistics to the screen, it is rather time consuming and will affect system performance. This command should be used as a debugging tool. Users should examine the MACIOC_GETSTATS command (described later) as a better alternative for acquiring driver statistics. Upon receiving the MACIOC_DUMPSTATS command, the driver will display a message showing its controller number and its Ethernet address. The driver will then display all of the software and hardware statistics gathered since driver init time. All statistics are kept as unsigned long values. Note that although the driver keeps track of MIB-II stats (as detailed in the file include/net/if.h), the software statistics shown are a proprietary set. The following tables list the statistics dumped to the console and a definition for each stat:
| SOFTWARE STATISTICS | |
| Name | Description |
| tx_pkts_in | Number of packets sent to the driver for transmit. |
| tx_err_state | Number of tx_pkts_in dropped because the transmit packet’s stream is not in the bound (IDLE) state. |
| tx_err_len | Number of tx_pkts_in dropped due to an invalid message length in the DL_UNITDATA_REQ primitive. |
| tx_err_addr | Number of tx_pkts_in dropped due to an invalid destination DLSAP address length in the DL_UNITDATA_REQ primitive. |
| tx_errors | Total number of tx_pkts_in dropped due to errors, i.e., the sum of all the tx_err_ values. |
| tx_discard_str | Number of tx_pkts_in discarded due to lack of STREAMS buffers. |
| tx_queue_bak | Number of tx_pkts_in placed on write queue because a write queue already exists, i.e., there is a backup. |
| tx_queue_tbd | Number of tx_pkts_in placed on write queue because of a lack of LANCE transmit message descriptors. |
| tx_queue_buf | Number of tx_pkts_in placed on write queue because of a lack of MVME376 buffers. |
| tx_queued | Total number of tx_pkts_in placed on the write queue, i.e., the sum of all the tx_queue_ values. |
| tx_pkts_out | Number of tx_pkts_in sent to the MVME376 board for transmit. This is the number of tx_pkts_in minus the total dropped and discarded packets. |
| tx_mcast | Number of tx_pkts_out w/ a multicast destination. |
| tx_bcast | Number of tx_pkts_out w/ a broadcast destination. |
| SOFTWARE STATISTICS (cont.) | |
| Name | Description |
| rx_pkts_in | Number of packets received from the board by driver (doesn’t include those w/ hardware errors). Also includes any tx_pkts_out that were looped back to the receive-side stream, e.g., broadcast packets. |
| rx_err_len | Number of rx_pkts_in dropped due to invalid length. |
| rx_discard_proto | Number of rx_pkts_in discarded due to an unknown (or unbound) protocol in the Ethernet header type field. |
| rx_discard_str | Number of rx_pkts_in discarded due to lack of STREAMS buffers. |
| rx_discard_flow | Number of rx_pkts_in discarded due to STREAMS flow control on rsrv queue. |
| rx_discard_multi | Number of rx_pkts_in discarded because multicast destination is not this station. |
| rx_discards | Total number of rx_pkts_in discarded, i.e., the sum of all the rx_discard_ values. |
| rx_pkts_out | Number of rx_pkts_in w/o errors or discards that the driver sent up to a consumer. |
| rx_mcast | Number of rx_pkts_out w/ a multicast destination. |
| rx_bcast | Number of rx_pkts_out w/ a broadcast destination. |
| HARDWARE STATISTICS | |
| Name | Description |
| csrintr | Number of interrupts generated by LANCE. |
| csrtint | Number of transmit interrupts generated by LANCE. |
| csrrint | Number of receive interrupts generated by LANCE. |
| txpkts | Number of packets LANCE attempted to transmit. |
| rxpkts | Number of packets LANCE received (includes those w/ hardware errors). |
| txerrs | Number of txpkts that failed due to a hardware error (either tmdbuff, tmduflo, tmdlcol, tmdlcar, or tmdrtry). |
| rxerrs | Number of rxpkts that failed due to a hardware error (either rmdfram, rmdoflo, rmdcrc, or rmdbuff). Note that rxerrs increments only once per packet, even if more than one of these errors occurs on the same packet, such as framing error and CRC error. |
| tmdmore | Number of txpkts where more than one collision was detected for that packet. tmdmore is not an error, and is not counted under txerrs. |
| tmdone | Number of txpkts where exactly one collision was detected for that packet. tmdone is not an error, and is not counted under txerrs. |
| tmddef | Number of txpkts where the LANCE had to defer an attempt to transmit that packet. tmddef is not an error, and is not counted under txerrs. |
| tmdbuff | Number of txerrs where the LANCE does not find the ENP bit set and does not own the next TMD. |
| tmduflo | Number of txerrs where the Silo underflowed. This occurs when the Silo reads data from the MVME376 memory faster than the board can handle. |
| tmdlcol | Number of txerrs where the collision detection circuitry detected a late collision. |
| tmdlcar | Number of txerrs where the LANCE detetced loss of carrier sense. |
| tmdrtry | Number of txerrs where the LANCE attempted to transmit the packet 16 times due to repeated collisions and finally aborted the transmit. |
| HARDWARE STATISTICS (cont.) | |
| Name | Description |
| rmdfram | Number of rxerrs where the received packet contained a non-integral number of octets and there was a CRC error. |
| rmdoflo | Number of rxerrs where the Silo overflowed. This occurs when the Silo writes data to the MVME376 memory faster than the board can handle. |
| rmdcrc | Number of rxerrs where the packet contained a CRC (checksum) error. |
| rmdbuff | Number of rxerrs where the LANCE was data chaining a packet and did not own the next RMD. |
| csrbabl | Number of interrupts generated because the transmitter detected a babble condition. |
| csrcerr | Number of interrupts generated because the transceiver collision test circuitry did not receive a "heartbeat" signal. |
| csrmiss | Number of interrupts generated because the LANCE did not own the next RMD. |
| csrmerr | Number of interrupts generated because the LANCE detected a memory error. |
| csridon | Number of interrupts generated because the LANCE completed initialization. |
| totcol | Total number of collisions detected by the LANCE. This statistic is approximate. Every instance of multiple collisions (see tmdmore above) increments this value by 2, when in fact there could have been anywhere between 2 and 15 collisions, inclusive. |
| m376perr | Number of interrupts handled in which the driver polled for and found an MVME376 parity error. |
MACIOC_GETSTATS is a request to have the driver return one or more statistics to the caller in an M_DATA block. The command requires the caller to send an M_DATA block containing an array of maciocstat structures. The structure (as defined in sys/macioctl.h) is shown below:
struct maciocstat
{
unsigned int code;
unsigned int value;
}
The user must place a statistic’s code in the code field for each maciocstat structure in the array. The driver will place the respective value for that statistic in the value field. It will then return the filled-in structures back to the caller in the same format received. The codes supported by the driver are shown below. The code name field is the name of the #define used in the sys/mvme376.h file. The code value is the numerical value associated with the code name. Examine the sys/macioctl.h file for a discussion on the format of the code value. All but the last two code names relate directly to the statistic names shown under the MACIOC_DUMPSTATS description. Look at that ioctl description for a discussion of all the statistic’s meanings. The last two codes are described here. MACIOCSTAT_EADDRHI and MACIOCSTAT_EADDRLO will return the upper 4 bytes of the controller’s Ethernet Address and the lower 2 bytes of the controller’s Ethernet Address, respectively.
| MACIOC_GETSTATS CODES | |||
| Code Name | Code Value | Code Name | Code Value |
| MACIOCSTAT_TXPKTSIN | 0x0 | MACIOCSTAT_TXERRSTATE | 0x1 |
| MACIOCSTAT_TXERRLEN | 0x2 | MACIOCSTAT_TXERRADDR | 0x3 |
| MACIOCSTAT_TXERRORS | 0x4 | MACIOCSTAT_TXDISCSTR | 0x5 |
| MACIOCSTAT_TXQUEBAK | 0x6 | MACIOCSTAT_TXQUETMD | 0x7 |
| MACIOCSTAT_TXQUEBUF | 0x8 | MACIOCSTAT_TXQUEUED | 0x9 |
| MACIOCSTAT_TXPKTSOUT | 0xa | MACIOCSTAT_TXMCAST | 0xb |
| MACIOCSTAT_TXBCAST | 0xc | MACIOCSTAT_RXPKTSIN | 0xd |
| MACIOCSTAT_RXERRLEN | 0xe | MACIOCSTAT_RXDISCPROTO | 0xf |
| MACIOCSTAT_RXDISCSTR | 0x10 | MACIOCSTAT_RXDISCFLOW | 0x11 |
| MACIOCSTAT_RXDISCMULTI | 0x12 | MACIOCSTAT_RXDISCARDS | 0x13 |
| MACIOCSTAT_RXPKTSOUT | 0x14 | MACIOCSTAT_RXMCAST | 0x15 |
| MACIOCSTAT_RXBCAST | 0x16 | MACIOCSTAT_CSRINTR | 0x17 |
| MACIOCSTAT_CSRTINT | 0x18 | MACIOCSTAT_CSRRINT | 0x19 |
| MACIOCSTAT_TXPKTS | 0x1a | MACIOCSTAT_RXPKTS | 0x1b |
| MACIOCSTAT_TXERRS | 0x1c | MACIOCSTAT_RXERRS | 0x1d |
| MACIOCSTAT_TMDMORE | 0x1e | MACIOCSTAT_TMDONE | 0x1f |
| MACIOCSTAT_TMDDEF | 0x20 | MACIOCSTAT_TMDBUFF | 0x21 |
| MACIOCSTAT_TMDUFLO | 0x22 | MACIOCSTAT_TMDLCOL | 0x23 |
| MACIOCSTAT_TMDLCAR | 0x24 | MACIOCSTAT_TMDRTRY | 0x25 |
| MACIOCSTAT_RMDFRAM | 0x26 | MACIOCSTAT_RMDOFLO | 0x27 |
| MACIOCSTAT_RMDCRC | 0x28 | MACIOCSTAT_RMDBUFF | 0x29 |
| MACIOCSTAT_CSRBABL | 0x2a | MACIOCSTAT_CSRCERR | 0x2b |
| MACIOCSTAT_CSRMISS | 0x2c | MACIOCSTAT_CSRMERR | 0x2d |
| MACIOCSTAT_CSRIDON | 0x2e | MACIOCSTAT_TOTCOL | 0x2f |
| MACIOCSTAT_M376PERR | 0x30 | MACIOCSTAT_EADDRHI | 0x10031 |
| MACIOCSTAT_EADDRLO | 0x10032 | ||
MACDEBUG is a request to set the driver debug level to a new value. The debug level regulates printing of debug messages to the system console. Upon driver initialization, the debug level is set to 0, which means no debug messages are sent to the console. Level 1 displays very high level information only. Level 2 shows more detail, and level 3 displays the most detail. Note that since the messages are displayed via printf, level 3 debugging can create long delays during print time, thus greatly affecting system performance. This command requires an M_DATA block containing an int value representing the new debug level.
MACDELAMCA is a request to delete all multicast table entries on the controller associated with this stream. This command does not require an M_DATA block.
MACDELMCA is a request to delete one multicast address from a multicast table on a per-stream basis. This command requires an M_DATA block of type mc_frame.
MACGETIA is a type of request to return the Ethernet address of the LANCE controller associated with the current queue. This command does not require an M_DATA block.
MACGETMCA is a request to return the entire multicast table for the controller associated with the current queue. This command does not require an M_DATA block.
MACGETSTAT is a request to return a statistic the driver has been gathering. A returned value of −1 indicates the statistic was not available. This command requires an M_DATA block. The data block is an array of structures. Each structure has the following format (see macioctl.h):
struct macstat
{
long name;
long value;
}
A table of number defines and their descriptions follow:
| MACGETSTAT | |
| Name | Description |
| MACSTAT_DEV_TIMEOUTS | total number of device timeouts |
| MACSTAT_XMITED | number of successful transmits |
| MACSTAT_XMITED_DEF | number of deferred transmits |
| MACSTAT_XMITED_1COLL | number of transmits with >=1 collision |
| MACSTAT_COLLISIONS | total number of collisions |
| MACSTAT_NOXMIT_BUFF | total number dropped frames because of no STREAM buffer |
| MACSTAT_NOXMIT_COLL | number of frames dropped due to excess collisions |
| MACSTAT_RECVD | number of frames successfully received |
| MACSTAT_RECVD_CKSUM | number of CRC errors |
| MACSTAT_RECVD_ALIGN | number of frames with alignment errors |
| MACSTAT_NORECV_RES | number of frames dropped because of resource lack |
| MACSTAT_NORECV_LENGTH | number of frames dropped because of bad length |
| MACSTAT_RECVD_MCAST | number of multicast frames received |
| MACSTAT_XMITED_MCAST | number of multicast frames transmitted |
| MACSTAT_NORECV_MCAST | number of multicast frames rejected |
| MACSTAT_NORECV_TYPE | number of frames dropped because of unbound type |
| MACSTAT_NOXMIT_CARRIER | number of times lost carrier |
| MACSTAT_NOXMIT_CTS | number of times lost CTS |
| MACSTAT_DMA_ERRORS | number of DMA errors |
| MACSTAT_RECVD_BCAST | number broadcast frames received |
| MACSTAT_OUT_OF_WINDOW | number of late collisions |
| MACSTAT_XMITED_BCAST | number of broadcast frames transmitted |
MACSETIA is a request to set the Ethernet address for the LANCE controller associated with the current stream. After executing MACSETIA, the networking subsystem must be stopped and then restarted. The address is immediately changed in the LANCE and the non-volatile RAM on the cpu board.
MACSETMCA is a request to add one multicast address to a multicast table on a per-stream basis. This command requires an M_DATA block of type mc_frame. A multicast address must have the least significant bit of byte[0] of the Ethernet address set. An individual stream may have a maximum of sixty-four multicast addresses in its table, subject to the following limitation. There may be no more than sixty-four addresses for all streams associated with each controller.
SIOCGENADDR is a type of request to return the Ethernet address of the LANCE controller associated with the current queue. This command requires an M_DATA block of type struct ifreq.
M_FLUSH
If the command is a read queue flush, the read queue of the driver is flushed and the message is passed back up stream. If the command is a write queue flush, the write queue of the driver is flushed.
FILES
/dev/m376_∗
/usr/include/sys/dlpi.h
/usr/include/sys/macioctl.h
/usr/include/sys/mvme376.h
SEE ALSO
ifconfig(1M), mvme376(1M), slink(1M) edt_data(4), master(4), strcf(4N), arp(7), clone(7), intro(7), ip(7), streamio(7).
Programmer’s Guide: STREAMS
McGrath, G., A STREAMS-based Data Link Provider Interface (DLPI), Version 1.3, AT&T Bell Laboratories, Summit, N.J., February 1989
LT-610 Programmer Guide, Retix, Santa Monica, CA, July 1991