1 GLD(9F)                  Kernel Functions for Drivers                  GLD(9F)
   2 
   3 
   4 
   5 NAME
   6        gld, gld_mac_alloc, gld_mac_free, gld_register, gld_unregister,
   7        gld_recv, gld_sched, gld_intr - Generic LAN Driver service routines
   8 
   9 SYNOPSIS
  10        #include <sys/gld.h>
  11 
  12        gld_mac_info_t *gld_mac_alloc(dev_info_t *dip);
  13 
  14 
  15        void gld_mac_free(gld_mac_info_t *macinfo);
  16 
  17 
  18        int gld_register(dev_info_t *dip, char *name, gld_mac_info_t *macinfo);
  19 
  20 
  21        int gld_unregister(gld_mac_info_t *macinfo);
  22 
  23 
  24        void gld_recv(gld_mac_info_t *macinfo, mblk_t *mp);
  25 
  26 
  27        void gld_sched(gld_mac_info_t *macinfo);
  28 
  29 
  30        uint_t gld_intr(caddr_t);
  31 
  32 
  33        void gld_linkstate(gld_mac_info_t *macinfo, int32_t newstate);
  34 
  35 
  36 INTERFACE LEVEL
  37        Solaris architecture specific (Solaris DDI).
  38 
  39 PARAMETERS
  40        macinfo
  41                     Pointer to a gld_mac_info(9S) structure.
  42 
  43 
  44        dip
  45                     Pointer to dev_info structure.
  46 
  47 
  48        name
  49                     Device interface name.
  50 
  51 
  52        mp
  53                     Pointer to a message block containing a received packet.
  54 
  55 
  56        newstate
  57                     Media link state.
  58 
  59 
  60 DESCRIPTION
  61        gld_mac_alloc() allocates a new gld_mac_info(9S) structure and returns
  62        a pointer to it. Some of the GLD-private elements of the structure may
  63        be initialized before gld_mac_alloc() returns; all other elements are
  64        initialized to zero. The device driver must initialize some structure
  65        members, as described in gld_mac_info(9S), before passing the mac_info
  66        pointer to gld_register().
  67 
  68 
  69        gld_mac_free() frees a gld_mac_info(9S) structure previously allocated
  70        by gld_mac_alloc().
  71 
  72 
  73        gld_register() is called from the device driver's attach(9E) routine,
  74        and is used to link the GLD-based device driver with the GLD framework.
  75        Before calling gld_register() the device driver's attach(9E) routine
  76        must first use gld_mac_alloc() to allocate a gld_mac_info(9S)
  77        structure, and initialize several of its structure elements. See
  78        gld_mac_info(9S) for more information. A successful call to
  79        gld_register() performs the following actions:
  80 
  81            o      links the device-specific driver with the GLD system;
  82 
  83            o      sets the device-specific driver's private data pointer
  84                   (using ddi_set_driver_private(9F)) to point to the macinfo
  85                   structure;
  86 
  87            o      creates the minor device node.
  88 
  89 
  90        The device interface name passed to gld_register() must exactly match
  91        the name of the driver module as it exists in the filesystem.
  92 
  93 
  94        The driver's attach(9E) routine should return DDI_SUCCESS if
  95        gld_register() succeeds. If gld_register() returns DDI_FAILURE, the
  96        attach(9E) routine should deallocate any resources it allocated before
  97        calling gld_register() and then also return DDI_FAILURE.
  98 
  99 
 100        gld_unregister() is called by the device driver's detach(9E) function,
 101        and if successful, performs the following tasks:
 102 
 103            o      ensures the device's interrupts are stopped, calling the
 104                   driver's gldm_stop() routine if necessary;
 105 
 106            o      removes the minor device node;
 107 
 108            o      unlinks the device-specific driver from the GLD system.
 109 
 110 
 111        If gld_unregister() returns DDI_SUCCESS, the detach(9E) routine should
 112        deallocate any data structures allocated in the attach(9E) routine,
 113        using gld_mac_free() to deallocate the macinfo structure, and return
 114        DDI_SUCCESS. If gld_unregister() returns DDI_FAILURE, the driver's
 115        detach(9E) routine must leave the device operational and return
 116        DDI_FAILURE.
 117 
 118 
 119        gld_recv() is called by the driver's interrupt handler to pass a
 120        received packet upstream. The driver must construct and pass a STREAMS
 121        M_DATA message containing the raw packet. gld_recv() determines which
 122        STREAMS queues, if any, should receive a copy of the packet,
 123        duplicating it if necessary. It then formats a DL_UNITDATA_IND message,
 124        if required, and passes the data up all appropriate streams.
 125 
 126 
 127        The driver should avoid holding mutex or other locks during the call to
 128        gld_recv(). In particular, locks that could be taken by a transmit
 129        thread may not be held during a call to gld_recv(): the interrupt
 130        thread that calls gld_recv() may in some cases carry out processing
 131        that includes sending an outgoing packet, resulting in a call to the
 132        driver's gldm_send() routine. If the gldm_send() routine were to try to
 133        acquire a mutex being held by the gldm_intr() routine at the time it
 134        calls gld_recv(), this could result in a panic due to recursive mutex
 135        entry.
 136 
 137 
 138        gld_sched() is called by the device driver to reschedule stalled
 139        outbound packets. Whenever the driver's gldm_send() routine has
 140        returned GLD_NORESOURCES, the driver must later call gld_sched() to
 141        inform the GLD framework that it should retry the packets that
 142        previously could not be sent. gld_sched() should be called as soon as
 143        possible after resources are again available, to ensure that GLD
 144        resumes passing outbound packets to the driver's gldm_send() routine in
 145        a timely way.  (If the driver's gldm_stop() routine is called, the
 146        driver is absolved from this obligation until it later again returns
 147        GLD_NORESOURCES from its gldm_send() routine; however, extra calls to
 148        gld_sched() will not cause incorrect operation.)
 149 
 150 
 151        gld_intr() is GLD's main interrupt handler. Normally it is specified as
 152        the interrupt routine in the device driver's call to ddi_add_intr(9F).
 153        The argument to the interrupt handler (specified as int_handler_arg in
 154        the call to ddi_add_intr(9F)) must be a pointer to the gld_mac_info(9S)
 155        structure. gld_intr() will, when appropriate, call the device driver's
 156        gldm_intr() function, passing that pointer to the gld_mac_info(9S)
 157        structure. However, if the driver uses a high-level interrupt, it must
 158        provide its own high-level interrupt handler, and trigger a soft
 159        interrupt from within that. In this case, gld_intr() may be specified
 160        as the soft interrupt handler in the call to ddi_add_softintr().
 161 
 162 
 163        gld_linkstate() is called by the device driver to notify GLD of changes
 164        in the media link state. The newstate argument should be set to one of
 165        the following:
 166 
 167        GLD_LINKSTATE_DOWN
 168                                  The media link is unavailable.
 169 
 170 
 171        GLD_LINKSTATE_UP
 172                                  The media link is unavailable.
 173 
 174 
 175        GLD_LINKSTATE_UNKNOWN
 176                                  The status of the media link is unknown.
 177 
 178 
 179 
 180        If a driver calls gld_linkstate(), it must also set the
 181        GLD_CAP_LINKSTATE bit in the gldm_capabilities field of the
 182        gld_mac_info(9S) structure.
 183 
 184 RETURN VALUES
 185        gld_mac_alloc() returns a pointer to a new gld_mac_info(9S) structure.
 186 
 187 
 188        gld_register() and gld_unregister() return:
 189 
 190        DDI_SUCCESS
 191                        on success.
 192 
 193 
 194        DDI_FAILURE
 195                        on failure.
 196 
 197 
 198 
 199        gld_intr() returns a value appropriate for an interrupt handler.
 200 
 201 SEE ALSO
 202        gld(7D), gld(9E), gld_mac_info(9S), gld_stats(9S), dlpi(7P),
 203        attach(9E), ddi_add_intr(9F)
 204 
 205 
 206        Writing Device Drivers
 207 
 208 
 209 
 210                                February 15, 2020                       GLD(9F)