MAC_REGISTER(9F)        Kernel Functions for Drivers        MAC_REGISTER(9F)
NAME
     mac_register, 
mac_unregister - register and unregister a device driver
     from the MAC framework
SYNOPSIS
     #include <sys/mac_provider.h>     int     mac_register(
mac_register_t *mregp, 
mac_handle_t *mhp);     
int     mac_unregister(
mac_handle_t mh);
INTERFACE LEVEL
     illumos DDI specific
PARAMETERS
     mregp         A pointer to a 
mac_register(9S) structure allocated by
                   calling 
mac_alloc(9F) and filled in by the device driver.     
mhp           A pointer to a driver-backed handle to the MAC framework.     
mh            The driver-backed handle to the MAC framework.
DESCRIPTION
     The 
mac_register() function is used to register an instance of a device
     driver with the 
mac(9E) framework.  Upon successfully calling the     
mac_register() function, the device will start having its     
mac_callbacks(9S) entry points called.  The device driver should call
     this function during it's 
attach(9E) entry point after the device has
     been configured and is set up.  For a more detailed explanation of the
     exact steps that the device driver should take and where in the
     sequence of a driver's 
attach(9E) entry point this function should be
     called, see the 
Registering with MAC section of 
mac(9E).
     The driver should provide a pointer to a 
mac_handle_t structure as the
     second argument to the 
mac_register() function.  This handle will be
     used when the device driver needs to interact with the framework in
     various ways throughout its life.  It is also where the driver gets the     
mh argument for calling the 
mac_unregister() function.  It is
     recommended that the device driver keep the handle around in its soft
     state structure for a given instance.
     If the call to the 
mac_register() function fails, the device driver
     should unwind its 
attach(9E) entry point, tear down everything that it
     initialized, and ultimately return an error from its 
attach(9E) entry
     point.
     If the 
attach(9E) routine fails for some reason after the call to the     
mac_register() function has succeeded, then the driver should call the     
mac_unregister() function as part of unwinding all of its state.
     When a driver is in its 
detach(9E) entry point, it should call the     
mac_unregister() function immediately after draining any of its
     transmit and receive resources that might have been given to the rest
     of the operating system through DMA binding.  See the 
MBLKS AND DMA     section of 
mac(9E) for more information.  This should be done before
     the driver does any tearing down.  The call to the 
mac_unregister()
     function may fail.  This may happen because the networking stack is
     still using the device.  In such a case, the driver should fail the
     call to 
detach(9E) and return 
DDI_FAILURE.
CONTEXT
     The 
mac_register() function is generally only called from a driver's     
attach(9E) entry point.  The 
mac_unregister() function is generally
     only called from a driver's 
attach(9E) and 
detach(9E) entry point.
     However, both functions may be called from either 
user or 
kernel     context.
RETURN VALUES
     Upon successful completion, the 
mac_register() and 
mac_unregister()
     functions both return 
0.  Otherwise, they return an error number.
EXAMPLES
     The following example shows how a device driver might call the     
mac_register() function.
     #include <sys/mac_provider.h>
     #include <sys/mac_ether.h>
     /*
      * The call to 
mac_register(9F) generally comes from the context of
      * 
attach(9E). This function encapsulates setting up and initializing
      * the mac_register_t structure and should be assumed to be called from
      * attach.
      *
      * The exact set of callbacks and private properties will vary based
      * upon the driver.
      */
     static char *example_priv_props[] = {
             "_rx_intr_throttle",
             "_tx_intr_throttle",
             NULL
     };
     static mac_callbacks_t example_m_callbacks = {
             .mc_callbacks = MC_GETCAPAB | MC_SETPROP | MC_GETPROP | MC_PROPINFO |
                 MC_IOCTL,
             .mc_start = example_m_start,
             .mc_stop = example_m_stop,
             .mc_setpromisc = example_m_setpromisc,
             .mc_multicst = example_m_multicst,
             .mc_unicst = example_m_unicst,
             .mc_tx = example_m_tx,
             .mc_ioctl = example_m_ioctl,
             .mc_getcapab = example_m_getcapab,
             .mc_getprop = example_m_getprop,
             .mc_setprop = example_m_setprop,
             .mc_propinfo = example_m_propinfo
     };
     static boolean_t
     example_register_mac(example_t *ep)
     {
             int status;
             mac_register_t *mac;
             mac = mac_alloc(MAC_VERSION);
             if (mac == NULL)
                     return (B_FALSE);
             mac->m_type_ident = MAC_PLUGIN_IDENT_ETHER;
             mac->m_driver = ep;
             mac->m_dip = ep->ep_dev_info;
             mac->m_src_addr = ep->ep_mac_addr;
             mac->m_callbacks = &example_m_callbacks;
             mac->m_min_sdu = 0;
             mac->m_max_sdu = ep->ep_sdu;
             mac->m_margin = VLAN_TAGSZ;
             mac->m_priv_props = example_priv_props;
             status = mac_register(mac, &ep->ep_mac_hdl);
             mac_free(mac);
             return (status == 0);
     }
ERRORS
     The 
mac_register() function may fail if:
     EEXIST             A driver with the same name and instance already
                        exists.
     EINVAL             There was something invalid with the device's
                        registration information.  Some of the following
                        reasons may apply, this list is not exhaustive:                        
+o   The 
mac_init_ops(9F) function was not called.                        
+o   The specified mac plugin does not exist.                        
+o   An invalid minor number was used.                        
+o   The default unicast source address was
                            incorrect.                        
+o   The plugin specific private data was incorrect
                            or missing.                        
+o   Plugin specific data was provided when none is
                            required.                        
+o   Required callback functions are not specified.                        
+o   The system was unable to properly create minor
                            nodes.
     ENOSPC             The 
mac(9E) framework was unable to allocate a minor
                        number for the device as they have all been
                        exhausted.
     The 
mac_unregister() function will fail if:
     EBUSY              The device is still in use.
     ENOTEMPTY          The flow table is not empty.
     Note the set of errors for both the 
mac_register() and 
mac_unregister()
     functions are not set in stone and may be expanded in future revisions.
     In general, all errors should be handled by the device driver in
     similar ways for these functions.
SEE ALSO
     attach(9E), 
detach(9E), 
mac(9E), 
mac_alloc(9F), 
mac_init_ops(9F),     
mac_callbacks(9S), 
mac_register(9S)illumos                         July 17, 2023                        illumos