Implemented ioctl Functions
GLD implements the ioctl ioc_cmd function described below. If GLD receives an ioctl command that it does not recognize, it passes it to the device-specific driver's gldm_ioctl() routine, as described in gld(9E).
The DLIOCRAW ioctl function is used by some DLPI applications, most notably the snoop(1M) command. The DLIOCRAW command puts the Stream into a raw mode, which causes the driver to pass full MAC-level incoming packets upstream in M_DATA messages instead of transforming them into the DL_UNITDATA_IND form that is normally used for reporting incoming packets. Packet SAP filtering is still performed on Streams that are in raw mode. If a Stream user wants to receive all incoming packets, it must also select the appropriate promiscuous mode or modes. After successfully selecting raw mode, the application is also allowed to send fully formatted packets to the driver as M_DATA messages for transmission. DLIOCRAW takes no arguments. Once enabled, the Stream remains in this mode until closed.
GLD Driver Requirements
GLD-based drivers must include the header file <sys/gld.h>.
GLD-based drivers must be linked with the -N"misc/gld" option:
%ld -r -N"misc/gld" xx.o -o xx |
GLD implements the open(9E) and close(9E) functions and the required STREAMS put(9E) and srv(9E) functions on behalf of the device-specific driver. GLD also implements the getinfo(9E) function for the driver.
The mi_idname element of the module_info(9S) structure is a string specifying the name of the driver. This must exactly match the name of the driver module as it exists in the file system.
The read-side qinit(9S) structure should specify the following elements:
qi_putp | NULL |
qi_srvp | gld_rsrv |
qi_qopen | gld_open |
qi_qclose | gld_close |
The write-side qinit(9S) structure should specify these elements:
qi_putp | gld_wput |
qi_srvp | gld_wsrv |
qi_qopen | NULL |
qi_qclose | NULL |
The devo_getinfo element of the dev_ops(9S) structure should specify gld_getinfo as the getinfo(9E) routine.
The driver's attach(9E) function does all the work of associating the hardware-specific device driver with the GLD facility and preparing the device and driver for use.
The attach(9E) function allocates a gld_mac_info(9S) (``macinfo'') structure using gld_mac_alloc(). The driver usually needs to save more information per device than is defined in the macinfo structure. It should allocate the additional required data structure and save a pointer to it in the gldm_private member of the gld_mac_info(9S) structure.
The attach(9E) routine must initialize the macinfo structure as described in gld_mac_info(9S) and then call gld_register() to link the driver with the GLD module. The driver should map registers if necessary and be fully initialized and prepared to accept interrupts before calling gld_register(). The attach(9E) function should add interrupts but not enable the device to generate them. The driver should reset the hardware before calling gld_register() to ensure it is quiescent. The device must not be started or put into a state where it might generate an interrupt before gld_register() is called. That will be done later when GLD calls the driver's gldm_start() entry point, described in the gld(9E) man page. After gld_register() succeeds, the gld(9E) entry points might be called by GLD at any time.
The attach(9E) routine should return DDI_SUCCESS if gld_register() succeeds. If gld_register() fails, it returns DDI_FAILURE, and the attach(9E) routine should deallocate any resources it allocated before calling gld_register() and then also return DDI_FAILURE. Under no circumstances should a failed macinfo structure be reused; it should be deallocated using gld_mac_free().
The detach(9E)function should attempt to unregister the driver from GLD by calling gld_unregister() (described in gld(9F) man page). The detach(9E) routine can get a pointer to the needed gld_mac_info(9S) structure from the device's private data using ddi_get_driver_private(9F). gld_unregister() checks certain conditions that could require that the driver not be detached. If the checks fail, gld_unregister() returns DDI_FAILURE, in which case the driver's detach(9E) routine must leave the device operational and return DDI_FAILURE.
If the checks succeed, gld_unregister() ensures that the device interrupts are stopped (calling the driver's gldm_stop() routine if necessary), unlinks the driver from the GLD framework, and returns DDI_SUCCESS. In this case, the detach(9E) routine should remove interrupts, deallocate any data structures allocated in the attach(9E) routine (using gld_mac_free() to deallocate the macinfo structure), and return DDI_SUCCESS. The routine must remove the interrupt before calling gld_mac_free().
Network Statistics
Solaris network drivers must implement statistics variables. GLD itself tallies some network statistics, but other statistics must be counted by each GLD-based driver. GLD provides support for GLD-based drivers to report a standard set of network driver statistics. Statistics are reported by GLD using the kstat(7D) and kstat(9S) mechanisms. The DL_GET_STATISTICS_REQ DLPI command can also be used to retrieve the current statistics counters. All statistics are maintained as unsigned, and all are 32 bits unless otherwise noted.
GLD maintains and reports the following statistics.
rbytes64 | Total bytes successfully received on the interface (64 bits) |
rbytes | Total bytes successfully received on the interface |
obytes64 | Total bytes requested to be transmitted on the interface (64 bits) |
obytes | Total bytes requested to be transmitted on the interface |
ipackets64 | Total packets successfully received on the interface (64 bits) |
ipackets | Total packets successfully received on the interface |
opackets64 | Total packets requested to be transmitted on the interface (64 bits) |
opackets | Total packets requested to be transmitted on the interface |
multircv | Multicast packets successfully received, including group and functional addresses (long) |
multixmt | Multicast packets requested to be transmitted, including group and functional addresses (long) |
brdcstrcv | Broadcast packets successfully received (long) |
brdcstxmt | Broadcast packets requested to be transmitted (long) |
unknowns | Valid received packets not accepted by any Stream (long) |
noxmtbuf | Packets discarded on output because transmit buffer was busy, or no buffer could be allocated for transmit (long) |
blocked | Number of times a received packet could not be put up a Stream because the queue was flow-controlled (long) |
xmtretry | Times transmit was retried after having been delayed due to lack of resources (long) |
promisc | Current ``promiscuous'' state of the interface (string) |
The device-dependent driver counts the following statistics, keeping track of them in a private per-instance structure. When GLD is asked to report statistics, it calls the driver's gldm_get_stats() entry point (as described in the gldm_get_stats(9E) man page) to update the device-specific statistics in the gld_stats(9S) structure. GLD then reports the updated statistics using the named statistics variables shown below.
ifspeed | Current estimated bandwidth of the interface in bits per second (64 bits) |
media | Current media type in use by the device (string) |
intr | Times interrupt handler was called and claimed the interrupt (long) |
norcvbuf | Number of times a valid incoming packet was known to have been discarded because no buffer could be allocated for receive (long) |
ierrors | Total packets received that could not be processed because they contained errors (long) |
oerrors | Total packets that were not successfully transmitted because of errors (long) |
missed | Packets known to have been dropped by the hardware on receive (long) |
uflo | Times FIFO underflowed on transmit (long) |
oflo | Times receiver overflowed during receive (long) |
The following group of statistics applies to networks of type DL_ETHER. These statistics are maintained by device-specific drivers of that type, as shown previously.