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)OmniOS July 17, 2023 OmniOS