MC_GETPROP(9E) Driver Entry Points MC_GETPROP(9E)
NAME
mc_getprop - get device properties
SYNOPSIS
#include <sys/mac_provider.h> int prefix_m_getprop(
void *driver,
const char *pr_name,
mac_prop_id_t pr_num,
uint_t pr_valsize,
void *pr_val);
INTERFACE LEVEL
illumos DDI specific
PARAMETERS
driver A pointer to the driver's private data that was passed in
via the
m_pdata member of the
mac_register(9S) structure
to the
mac_register(9F) function.
pr_name A null-terminated string that contains the name of the
property.
pr_num A constant that is used to identify the property.
pr_valsize A value that indicates the size in bytes of
pr_val.
pr_val A pointer to a
pr_valsize byte buffer that can store the
property.
DESCRIPTION
The
mc_getprop() entry point is used to obtain the value of a given
device's property and place it into
pr_val.
When the
mc_getprop() entry point is called, the driver needs to first
identify the property. The set of possible properties and their
meaning is listed in the
PROPERTIES section of
mac(9E). It should
identify the property based on the value of
pr_num. Most drivers will
use a
switch statement and for any property that it supports it should
then check if the value in
pr_valsize is sufficient for the property,
comparing it to the minimum size listed for the property in
mac(9E).
If it is not, then it should return an error. Otherwise, it should
copy the property's value into
pr_val. When an unknown or unsupported
property is encountered, generally the
default case of the switch
statement, the device driver should return an error.
The special property
MAC_PROP_PRIVATE indicates that this is a device
driver specific private property. The device driver must then look at
the value of the
pr_name argument and use
strcmp(9F) on it, comparing
it to each of its private (bounded-size) properties to identify which
one it is.
At this time, private properties are limited to being string based
properties. If other types of property values are used, they will not
be rendered correctly by
dladm(8).
The device driver can access its device soft state by casting the
device pointer to the appropriate structure. As this may be called
while other operations are ongoing, the device driver should employ the
appropriate locking while reading the properties.
CONTEXT
The
mc_getprop() function is generally called from
kernel context.
RETURN VALUES
Upon successful completion, the device driver should have copied the
value of the property into
pr_val and return
0. Otherwise, a positive
error should be returned to indicate failure.
EXAMPLES
The following example shows how a device driver might structure its
mc_getprop() entry point.
#include <sys/mac_provider.h>
/*
* Note, this example merely shows the structure of this function.
* Different devices will manage their state in different ways. Like other
* examples, this assumes that the device has state in a structure called
* example_t and that there is a lock which keeps track of that state.
*/
static char *example_priv_props[] = {
"_rx_intr_throttle",
"_tx_intr_throttle",
NULL
};
static int
example_m_getprop_private(example_t *ep, const char *pr_name, uint_t pr_valsize,
void *pr_val)
{
uint32_t val;
ASSERT(MUTEX_HELD(&ep->ep_lock));
if (strcmp(pr_name, example_priv_props[0] == 0) {
val = ep->ep_rx_itr;
} else if (strcmp(pr_name, example_priv_props[1] == 0) {
val = ep->ep_tx_itr;
} else {
return (ENOTSUP);
}
/*
* Due to issues in the GLDv3, these must be returned as string
* properties.
*/
if (snprintf(pr_val, pr_valsize, "%d", val) >= pr_valsize)
return (EOVERFLOW);
return (0);
}
static int
example_m_getprop(void *arg, const char *pr_name, mac_prop_id_t pr_num,
uint_t pr_valsize, void *pr_val)
{
int ret = 0;
uint64_t speed;
example_t *ep = arg;
mutex_enter(&ep->ep_lock);
/*
* This only handles a subset of the properties that exist on the
* system. A proper driver will need to handle more. See
mac(9E) for a
* full property list.
*/
switch (pr_num) {
case MAC_PROP_DUPLEX:
if (pr_valsize < sizeof (link_duplex_t)) {
ret = EOVERFLOW;
break;
}
bcopy(ep->ep_link_duplex, pr_val, sizeof (link_duplex_t));
case MAC_PROP_SPEED:
if (pr_valsize < sizeof (uint64_t)) {
ret = EOVERFLOW;
break;
}
/*
* The link speed is stored in Mbits/s in this driver and is
* expected in bits/s.
*/
speed = ep->ep_link_speed * 1000000ULL;
bcopy(&speed, pr_val, sizeof (speed));
break;
case MAC_PROP_MTU:
if (pr_valsize < sizeof (uint32_t)) {
ret = EOVERFLOW;
break;
}
bcopy(&ep->ep_mtu, pr_val, sizeof (speed));
break;
case MAC_PROP_PRIVATE:
ret = example_m_getprop_private(ep, pr_name, pr_valsize,
pr_val);
break;
default:
ret = ENOTSUP;
break;
}
mutex_exit(&ep->ep_lock);
return (ret);
}
ERRORS
The device driver may return one of the following errors. While this
list is not intended to be exhaustive, it is recommended to use one of
these if possible.
ENOTSUP This error should be used whenever an unknown or
unsupported property is encountered.
EOVERFLOW This error should be used when
pr_valsize is smaller
than the required size for a given value.
SEE ALSO
mac(9E),
mac_register(9F),
strcmp(9F),
mac_register(9S)illumos February 15, 2020 illumos