Driver Entry Points gld(9E)
NAME
gld, gldmreset, gldmstart, gldmstop, gldmsetmacaddr,
gldmsetmulticast, gldmsetpromiscuous, gldmsend,
gldmintr, gldmgetstats, gldmioctl - Generic LAN Driver
entry points
SYNOPSIS
#include
int prefixreset(gldmacinfot *macinfo);
int prefixstart(gldmacinfot *macinfo);
int prefixstop(gldmacinfot *
macinfo);
int prefixsetmacaddr(gldmacinfot *
macinfo, unsigned char *macaddr);
int prefixsetmulticast(gldmacinfot *
macinfo, unsigned char *multicastaddr,
int multiflag);
int prefixsetpromiscuous(gldmacinfot *macinfo,
int promiscflag);
int prefixsend(gldmacinfot *macinfo,
mblkt *mp);
uintt prefixintr(gldmacinfot *macinfo);
int prefixgetstats(gldmacinfot *macinfo,
struct gldstats *stats);
int prefixioctl(gldmacinfot *macinfo,
queuet *q, mblkt *mp);
INTERFACE LEVEL
Solaris architecture specific (Solaris DI).
PARAMETERS
SunOS 5.11 Last change: 3 Jan 2001 1
Driver Entry Points gld(9E)
macinfo Pointer to a gldmacinfo(9S) structure.
macaddr Pointer to the beginning of a character
array containing a valid MAC address. The
array will be of the length specified by
the driver in the gldmaddrlen element of
the gldmacinfo(9S) structure.
multicastaddr Pointer to the beginning of a character
array containing a multicast, group, or
functional address. The array will be of
the length specified by the driver in the
gldmaddrlen element of the
gldmacinfo(9S) structure.
multiflag A flag indicating whether reception of the
multicast address is to be enabled or dis-
abled. This argument is specified as
GLDMULTIENABLE or GLDMULTIDISABLE.
promiscflag A flag indicating what type of promiscuous
mode, if any, is to be enabled. This argu-
ment is specified as GLDMACPROMISCPHYS,
GLDMACPROMISCMULTI, or
GLDMACPROMISCNONE.
mp Pointer to a STREAMS message block con-
taining the packet to be transmitted or
the ioctl to be executed.
stats Pointer to a gldstats(9S) structure to be
filled in with the current values of
statistics counters.
q Pointer to the queue(9S) structure to be
used in the reply to the ioctl.
DESCRIPTION
These entry points must be implemented by a device-specific
network driver designed to interface with the Generic LAN
Driver (GLD).
SunOS 5.11 Last change: 3 Jan 2001 2
Driver Entry Points gld(9E)
As described in gld(7D), the main data structure for commun-
ication between the device-specific driver and the GLD
module is the gldmacinfo(9S) structure. Some of the ele-
ments in that structure are function pointers to the entry
points described here. The device-specific driver must, in
its attach(9E) routine, initialize these function pointers
before calling gldregister().
gldmreset() resets the hardware to its initial state.
gldmstart() enables the device to generate interrupts and
prepares the driver to call gldrecv() for delivering
received data packets to GLD.
gldmstop() disables the device from generating any inter-
rupts and stops the driver from calling gldrecv() for
delivering data packets to GLD. GLD depends on the
gldmstop() routine to ensure that the device will no longer
interrupt, and it must do so without fail.
gldmsetmacaddr() sets the physical address that the
hardware is to use for receiving data. This function should
program the device to the passed MAC address macaddr.
gldmsetmulticast() enables and disables device-level
reception of specific multicast addresses. If the third
argument multiflag is set to GLDMULTIENABLE, then the
function sets the interface to receive packets with the mul-
ticast address pointed to by the second argument; if multi-
flag is set to GLDMULTIDISABLE, the driver is allowed to
disable reception of the specified multicast address.
This function is called whenever GLD wants to enable or dis-
able reception of a multicast, group, or functional address.
GLD makes no assumptions about how the device does multicast
support and calls this function to enable or disable a
specific multicast address. Some devices may use a hash
algorithm and a bitmask to enable collections of multicast
addresses; this is allowed, and GLD will filter out any
superfluous packets that are not required. If disabling an
address could result in disabling more than one address at
the device level, it is the responsibility of the device
driver to keep whatever information it needs to avoid disa-
bling an address that GLD has enabled but not disabled.
SunOS 5.11 Last change: 3 Jan 2001 3
Driver Entry Points gld(9E)
gldmsetmulticast() will not be called to enable a particu-
lar multicast address that is already enabled, nor to dis-
able an address that is not currently enabled. GLD keeps
track of multiple requests for the same multicast address
and only calls the driver's entry point when the first
request to enable, or the last request to disable a particu-
lar multicast address is made.
gldmsetpromiscuous() enables and disables promiscuous
mode. This function is called whenever GLD wants to enable
or disable the reception of all packets on the medium, or
all multicast packets on the medium. If the second argument
promiscflag is set to the value of GLDMACPROMISCPHYS,
then the function enables physical-level promiscuous mode,
resulting in the reception of all packets on the medium. If
promiscflag is set to GLDMACPROMISCMULTI, then reception
of all multicast packets will be enabled. If promiscflag is
set to GLDMACPROMISCNONE, then promiscuous mode is dis-
abled.
In the case of a request for promiscuous multicast mode,
drivers for devices that have no multicast-only promiscuous
mode must set the device to physical promiscuous mode to
ensure that all multicast packets are received. In this case
the routine should return GLDSUCES. The GLD software will
filter out any superfluous packets that are not required.
For forward compatibility, gldmsetpromiscuous() routines
should treat any unrecognized values for promiscflag as
though they were GLDMACPROMISCPHYS.
gldmsend() queues a packet to the device for transmission.
This routine is passed a STREAMS message containing the
packet to be sent. The message may comprise multiple message
blocks, and the send routine must chain through all the mes-
sage blocks in the message to access the entire packet to be
sent. The driver should be prepared to handle and skip over
any zero-length message continuation blocks in the chain.
The driver should check to ensure that the packet does not
exceed the maximum allowable packet size, and must pad the
packet, if necessary, to the minimum allowable packet size.
If the send routine successfully transmits or queues the
packet, it should return GLDSUCES.
The send routine should return GLDNORESOURCES if it cannot
immediately accept the packet for transmission; in this case
GLD will retry it later. If gldmsend() ever returns
SunOS 5.11 Last change: 3 Jan 2001 4
Driver Entry Points gld(9E)
GLDNORESOURCES, the driver must, at a later time when
resources have become available, call gldsched() to inform
GLD that it should retry packets that the driver previously
failed to queue for transmission. (If the driver's
gldmstop() routine is called, the driver is absolved from
this obligation until it later again returns GLDNORESOURCES
from its gldmsend() routine; however, extra calls to
gldsched() will not cause incorrect operation.)
If the driver's send routine returns GLDSUCES, then the
driver is responsible for freeing the message when the
driver and the hardware no longer need it. If the send rou-
tine copied the message into the device, or into a private
buffer, then the send routine may free the message after the
copy is made. If the hardware uses DMA to read the data
directly out of the message data blocks, then the driver
must not free the message until the hardware has completed
reading the data. In this case the driver will probably free
the message in the interrupt routine, or in a buffer-reclaim
operation at the beginning of a future send operation. If
the send routine returns anything other than GLDSUCES,
then the driver must not free the message.
gldmintr() is called when the device might have inter-
rupted. Since it is possible to share interrupts with other
devices, the driver must check the device status to deter-
mine whether it actually caused an interrupt. If the device
that the driver controls did not cause the interrupt, then
this routine must return DINTRUNCLAIMED. Otherwise it
must service the interrupt and should return
DINTRCLAIMED. If the interrupt was caused by successful
receipt of a packet, this routine should put the received
packet into a STREAMS message of type MDATA and pass that
message to gldrecv().
gldrecv() will pass the inbound packet upstream to the
appropriate next layer of the network protocol stack. It is
important to correctly set the brptr and bwptr members of
the STREAMS message before calling gldrecv().
The driver should avoid holding mutex or other locks during
the call to gldrecv(). In particular, locks that could be
taken by a transmit thread may not be held during a call to
gldrecv(): the interrupt thread that calls gldrecv() may
in some cases carry out processing that includes sending an
outgoing packet, resulting in a call to the driver's
gldmsend() routine. If the gldmsend() routine were to try
to acquire a mutex being held by the gldmintr() routine at
SunOS 5.11 Last change: 3 Jan 2001 5
Driver Entry Points gld(9E)
the time it calls gldrecv(), this could result in a panic
due to recursive mutex entry.
The interrupt code should increment statistics counters for
any errors. This includes failure to allocate a buffer
needed for the received data and any hardware-specific
errors such as CRC errors or framing errors.
gldmgetstats() gathers statistics from the hardware and/or
driver private counters, and updates the gldstats(9S)
structure pointed to by stats. This routine is called by GLD
when it gets a request for statistics, and provides the
mechanism by which GLD acquires device dependent statistics
from the driver before composing its reply to the statistics
request. See gldstats(9S) and gld(7D) for a description of
the defined statistics counters.
gldmioctl() implements any device-specific ioctl commands.
This element may be specified as NUL if the driver does not
implement any ioctl functions. The driver is responsible for
converting the message block into an ioctl reply message and
calling the qreply(9F) function before returning
GLDSUCES. This function should always return GLDSUCES;
any errors the driver may wish to report should be returned
via the message passed to qreply(9F). If the gldmioctl ele-
ment is specified as NUL, GLD will return a message of type
MIOCNAK with an error of EINVAL.
RETURN VALUES
gldmintr() must return:
DINTRCLAIMED if and only if the device definitely
interrupted.
DINTRUNCLAIMED if the device did not interrupt.
The other functions must return:
GLDSUCES on success. gldmstop() and
gldmioctl() should always return this
value.
GLDNORESOURCES if there are insufficient resources to
carry out the request at this time.
Only gldmsetmacaddr(),
SunOS 5.11 Last change: 3 Jan 2001 6
Driver Entry Points gld(9E)
gldmsetmulticast(),
gldmsetpromiscuous(), and gldmsend()
may return this value.
GLDNOLINK if gldmsend() is called when there is
no physical connection to a network or
link partner.
GLDNOTSUPORTED if the requested function is not sup-
ported. Only gldmsetmacaddr(),
gldmsetmulticast(), and
gldmsetpromiscuous() may return this
value.
GLDBADARG if the function detected an unsuitable
argument, for example, a bad multicast
address, a bad MAC address, or a bad
packet or packet length.
GLDFAILURE on hardware failure.
SEE ALSO
gld(7D), gld(9F), gldmacinfo(9S), gldstats(9S), dlpi(7P),
attach(9E), ddiaddintr(9F)
Writing Device Drivers
SunOS 5.11 Last change: 3 Jan 2001 7
|