MC_SETPROP(9E) Driver Entry Points MC_SETPROP(9E)
NAME
mc_setprop - set device properties
SYNOPSIS
#include <sys/mac_provider.h> int prefix_m_setprop(
void *driver,
const char *pr_name,
mac_prop_id_t pr_num,
uint_t pr_valsize,
const 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 contains the
new value of the property.
DESCRIPTION
The
mc_setprop() entry point is used to set the value of a given
device's property from the copy stored in
pr_val.
When the
mc_setprop() 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
update the property based on the value in
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 properties to identify which one it is.
Not all properties are supposed to be writable. Some devices may opt
to not allow a property that is designated as read/write to be set.
When such a property is encountered, the driver should return the
appropriate error.
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 writing the properties.
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 examples shows how a device driver might structure its
mc_setprop() 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.
*
* For the purpose of this example, we assume that this device supports 100 Mb,
* 1 GB, and 10 Gb full duplex speeds.
*/
static int
example_m_setprop(void *arg, const char *pr_name, mac_prop_id_t pr_num,
uint_t pr_valsize, const void *pr_val)
{
uint32_t new_mtu;
int ret = 0;
example_t *ep = arg;
mutex_enter(&ep->ep_lock);
switch (pr_num) {
/*
* These represent properties that can never be changed, regardless of
* the type of PHY on the device (copper, fiber, etc.)
*/
case MAC_PROP_DUPLEX:
case MAC_PROP_SPEED:
case MAC_PROP_STATUS:
case MAC_PROP_ADV_100FDX_CAP:
case MAC_PROP_ADV_1000FDX_CAP:
case MAC_PROP_ADV_10GFDX_CAP:
ret = ENOTSUP;
break;
/*
* These EN properties are used to control the advertised speeds of the
* device. For this example, we assume that this device does not have a
* copper phy, at which point auto-negotiation and the speeds in
* question cannot be changed. These are called out separately as they
* should be controllable for copper based devices or it may need to be
* conditional depending on the type of phy present.
*/
case MAC_PROP_EN_100FDX_CAP:
case MAC_PROP_EN_1000FDX_CAP:
case MAC_PROP_EN_10GFDX_CAP:
case MAC_PROP_AUTONEG:
ret = ENOTSUP;
break;
case MAC_PROP_MTU:
if (pr_valsize < sizeof (uint32_t)) {
ret = EOVERFLOW;
break;
}
bcopy(&new_mtu, pr_val, sizeof (uint32_t));
if (new_mtu < ep->ep_min_mtu ||
new_mtu > ep->ep_max_mtu) {
ret = EINVAL;
break;
}
/*
* We first ask MAC to update the MTU before we do anything.
* This may fail. It returns zero on success. The
* example_update_mtu function does device specific updates to
* ensure that the MTU on the device is updated and any internal
* data structures are up to date.
*/
ret = mac_maxdsu_update(&ep->ep_mac_hdl, new_mtu);
if (ret == 0) {
example_update_mtu(ep, new_mtu);
}
break;
/*
* Devices may have their own private properties. If they do, they
* should not return ENOTSUP, but instead see if it's a property they
* recognize and handle it similar to those above. If it doesn't
* recognize the name, then it should return ENOTSUP.
*/
case MAC_PROP_PRIVATE:
ret = ENOTSUP;
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.
EINVAL The contents of
pr_val are outside the valid range
for the property.
ENOTSUP This error should be used whenever an unknown or
unsupported property is encountered. It should also
be used when the property is not writable.
EOVERFLOW This error should be used when
pr_valsize is smaller
than the required size for a given value.
EBUSY This error should be used when a property can't be
set because the device has started. Note that
device driver writers are encouraged to design
device drivers such that this error is not possible.
ECANCELLED The device is in a state that does not allow it to
handle data; for example, it's suspended.
SEE ALSO
mac(9E),
mac_register(9F),
strcmp(9F),
mac_register(9S)illumos February 15, 2020 illumos