MC_PROPINFO(9E) Driver Entry Points MC_PROPINFO(9E)

mc_propinfoget information about a property

#include <sys/mac_provider.h>

void
prefix_m_propinfo(void *driver, const char *pr_name, mac_prop_id_t pr_num, mac_prop_info_handle_t hdl);

illumos DDI specific

driver
A pointer to the driver's private data that was passed in via the 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
The value indicates the property that the device is working with.
hdl
A handle to use with the mac_prop_info(9F) family of routines to indicate the property's metadata.

The () entry point is an optional entry point for networking device drivers that is used to obtain metadata about a property, including its permissions, default value, and information about valid possible values. If the device driver does not implement either of the mc_getprop(9E) or mc_setprop(9E) entry points then it does not need to implement the mc_propinfo() entry point. However, it is highly recommended that these interfaces be implemented in order to give users and administrators of the system access to the properties of the device.

When the () entry point is called, the driver needs to first identify the property. The set of possible properties and their meaning is listed in the section of mac(9E). It should identify the property based on the value of pr_num. Most drivers will use a statement and for any property that it supports it should call the appropriate mac_prop_info(9F) functions to set values and then return. When an unknown or unsupported property is encountered, generally the case of the switch statement, the device driver should simply do nothing and return.

The special property 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.

For each property the driver has three different sets of information that it can fill in. The driver should try to fill in all of these that make sense, if possible.

  1. First, the driver should fill in the permissions of the property with the mac_prop_info_set_perm(9F) function. These permissions indicate what the device driver supports for a given property. For each non-private property, see the property list in mac(9E) to see what the maximum property permissions are. As discussed in mac(9E), a device driver may have more limited permissions than the default. For example, on some SFP-based devices, it may not be possible to change any of the auto-negotiation properties.
  2. The driver should then fill in any default value that it has for a property. This is the value that the device driver sets by default if no other tuning has been performed. There are different functions depending on the type of the default value to call. They are all listed in mac_prop_info(9F).
  3. Finally, a driver may optionally set one or more value ranges. These are used for integer properties such as . The driver may call mac_prop_info_set_range_uint32(9F) to set a series of one or more inclusive ranges that describe valid values for the property. For example, a device that supports jumbo frames up to 9600 bytes would call mac_prop_info_set_range_uint32(9F) to convey that it supports MTUs in the range of 1500-9600 bytes.

If the device driver needs to access its private data, it will be available in the driver argument which it should cast to the appropriate structure. From there, the device driver may need to lock the structure to ensure that access to it is properly serialized.

The mc_propinfo() entry point does not have a return value. Drivers should simply ignore and immediately return when encountering unsupported and unknown properties.

The following example shows how a device driver might structure its mc_propinfo() 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 void
example_m_propinfo(void *arg, const char *pr_name, mac_prop_id_t pr_num,
    mac_prop_info_handle_t prh)
{
	uint8_t value;
	uint_t perm;

	example_t *ep = arg;

	mutex_enter(&ep->ep_lock);

	switch (pr_num) {
	/*
	 * We try to fill in as much information for each property as makes
	 * sense. In some cases, you may only be able to set the permissions.
	 */
	case MAC_PROP_DUPLEX:
	case MAC_PROP_SPEED:
		mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ);
		break;

	/*
	 * The MTU is a good example of a property that has a property range.
	 * The range represents the valid values the MTU can take.
	 */
	case MAC_PROP_MTU:
		mac_prop_info_set_perm(prh, MAC_PROP_PERM_RW);
		mac_prop_info_set_range(prh, ep->ep_min_mtu, ep->ep_max_mtu);
		break;

	/*
	 * The ADV properties represent things that the device supports and
	 * can't be changed by the user. These are good examples of properties
	 * that have a default value and are read-only.
	 */
	case MAC_PROP_ADV_100FDX_CAP:
		mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ);
		value = (ep->ep_link_sup_speeds & EXAMPLE_100FDX) ? 1 : 0;
		mac_prop_info_set_default_uint8(prh, value);
		break;
	case MAC_PROP_ADV_1000FDX_CAP:
		mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ);
		value = (ep->ep_link_sup_speeds & EXAMPLE_1000FDX) ? 1 : 0;
		mac_prop_info_set_default_uint8(prh, value);
		break;
	case MAC_PROP_ADV_10GFDX_CAP:
		mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ);
		value = (ep->ep_link_sup_speeds & EXAMPLE_10GDX) ? 1 : 0;
		mac_prop_info_set_default_uint8(prh, value);
		break;

	/*
	 * The EN properties represent the speeds advertised by the driver. On
	 * baseT (copper) PHYs, we allow them to be set, otherwise we don't.
	 * This driver always advertises it if supported, hence why all of these
	 * default to advertised if the link supports its.
	 */
	case MAC_PROP_EN_100FDX_CAP:
		perm = ep->ep_link_type == EXAMPLE_LINK_COPPER ?
		    MAC_PROP_PERM_RW : MAC_PROP_PERM_READ;
		mac_prop_info_set_perm(prh, perm);
		value = (ep->ep_link_sup_speeds & EXAMPLE_100FDX) ? 1 : 0;
		mac_prop_info_set_default_uint8(prh, value);
		break;
	case MAC_PROP_EN_1000FDX_CAP:
		perm = ep->ep_link_type == EXAMPLE_LINK_COPPER ?
		    MAC_PROP_PERM_RW : MAC_PROP_PERM_READ;
		mac_prop_info_set_perm(prh, perm);
		value = (ep->ep_link_sup_speeds & EXAMPLE_1000FDX) ? 1 : 0;
		mac_prop_info_set_default_uint8(prh, value);
		break;
	case MAC_PROP_EN_10GFDX_CAP:
		perm = ep->ep_link_type == EXAMPLE_LINK_COPPER ?
		    MAC_PROP_PERM_RW : MAC_PROP_PERM_READ;
		mac_prop_info_set_perm(prh, perm);
		value = (ep->ep_link_sup_speeds & EXAMPLE_10GFDX) ? 1 : 0;
		mac_prop_info_set_default_uint8(prh, value);
		break;

	/*
	 * If this device has private properties, then it should compare pr_name
	 * with the device's private properties and then fill in property
	 * information if it recognizes the name.
	 */
	case MAC_PROP_PRIVATE:
		break;

	/*
	 * For unknown properties, there's not much to do. Simply don't call any
	 * of the mac_prop_info(9F) related functions.
	 */
	default:
		break;
	}
	mutex_exit(&ep->ep_lock);
}

mac(9E), mc_getprop(9E), mac_prop_info(9F)

May 31, 2016 OmniOS