1 MC_SETPROP(9E)                Driver Entry Points               MC_SETPROP(9E)
   2 
   3 NAME
   4      mc_setprop - set device properties
   5 
   6 SYNOPSIS
   7      #include <sys/mac_provider.h>
   8 
   9      int
  10      prefix_m_setprop(void *driver, const char *pr_name, mac_prop_id_t pr_num,
  11          uint_t pr_valsize, const void *pr_val);
  12 
  13 INTERFACE LEVEL
  14      illumos DDI specific
  15 
  16 PARAMETERS
  17      driver        A pointer to the driver's private data that was passed in
  18                    via the m_pdata member of the mac_register(9S) structure to
  19                    the mac_register(9F) function.
  20 
  21      pr_name       A null-terminated string that contains the name of the
  22                    property.
  23 
  24      pr_num        A constant that is used to identify the property.
  25 
  26      pr_valsize    A value that indicates the size in bytes of pr_val.
  27 
  28      pr_val        A pointer to a pr_valsize byte buffer that contains the new
  29                    value of the property.
  30 
  31 DESCRIPTION
  32      The mc_setprop() entry point is used to set the value of a given device's
  33      property from the copy stored in pr_val.
  34 
  35      When the mc_setprop() entry point is called, the driver needs to first
  36      identify the property.  The set of possible properties and their meaning
  37      is listed in the PROPERTIES section of mac(9E).  It should identify the
  38      property based on the value of pr_num.  Most drivers will use a switch
  39      statement and for any property that it supports it should then check if
  40      the value in pr_valsize is sufficient for the property, comparing it to
  41      the minimum size listed for the property in mac(9E).  If it is not, then
  42      it should return an error.  Otherwise, it should update the property
  43      based on the value in pr_val.  When an unknown or unsupported property is
  44      encountered, generally the default case of the switch statement, the
  45      device driver should return an error.
  46 
  47      The special property MAC_PROP_PRIVATE indicates that this is a device
  48      driver specific private property.  The device driver must then look at
  49      the value of the pr_name argument and use strcmp(9F) on it, comparing it
  50      to each of its private properties to identify which one it is.
  51 
  52      Not all properties are supposed to be writable.  Some devices may opt to
  53      not allow a property that is designated as read/write to be set.  When
  54      such a property is encountered, the driver should return the appropriate
  55      error.
  56 
  57      The device driver can access its device soft state by casting the device
  58      pointer to the appropriate structure.  As this may be called while other
  59      operations are ongoing, the device driver should employ the appropriate
  60      locking while writing the properties.
  61 
  62 RETURN VALUES
  63      Upon successful completion, the device driver should have copied the
  64      value of the property into pr_val and return 0.  Otherwise, a positive
  65      error should be returned to indicate failure.
  66 
  67 EXAMPLES
  68      The following examples shows how a device driver might structure its
  69      mc_setprop() entry point.
  70 
  71      #include <sys/mac_provider.h>
  72 
  73      /*
  74       * Note, this example merely shows the structure of this function.
  75       * Different devices will manage their state in different ways. Like other
  76       * examples, this assumes that the device has state in a structure called
  77       * example_t and that there is a lock which keeps track of that state.
  78       *
  79       * For the purpose of this example, we assume that this device supports 100 Mb,
  80       * 1 GB, and 10 Gb full duplex speeds.
  81       */
  82 
  83      static int
  84      example_m_setprop(void *arg, const char *pr_name, mac_prop_id_t pr_num,
  85          uint_t pr_valsize, const void *pr_val)
  86      {
  87              uint32_t new_mtu;
  88              int ret = 0;
  89              example_t *ep = arg;
  90 
  91              mutex_enter(&ep->ep_lock);
  92              switch (pr_num) {
  93              /*
  94               * These represent properties that can never be changed, regardless of
  95               * the type of PHY on the device (copper, fiber, etc.)
  96               */
  97              case MAC_PROP_DUPLEX:
  98              case MAC_PROP_SPEED:
  99              case MAC_PROP_STATUS:
 100              case MAC_PROP_ADV_100FDX_CAP:
 101              case MAC_PROP_ADV_1000FDX_CAP:
 102              case MAC_PROP_ADV_10GFDX_CAP:
 103                      ret = ENOTSUP;
 104                      break;
 105 
 106              /*
 107               * These EN properties are used to control the advertised speeds of the
 108               * device. For this example, we assume that this device does not have a
 109               * copper phy, at which point auto-negotiation and the speeds in
 110               * question cannot be changed. These are called out separately as they
 111               * should be controllable for copper based devices or it may need to be
 112               * conditional depending on the type of phy present.
 113               */
 114              case MAC_PROP_EN_100FDX_CAP:
 115              case MAC_PROP_EN_1000FDX_CAP:
 116              case MAC_PROP_EN_10GFDX_CAP:
 117              case MAC_PROP_AUTONEG:
 118                      ret = ENOTSUP;
 119                      break;
 120 
 121              case MAC_PROP_MTU:
 122                      if (pr_valsize < sizeof (uint32_t)) {
 123                              ret = EOVERFLOW;
 124                              break;
 125                      }
 126                      bcopy(&new_mtu, pr_val, sizeof (uint32_t));
 127 
 128                      if (new_mtu < ep->ep_min_mtu ||
 129                          new_mtu > ep->ep_max_mtu) {
 130                              ret = EINVAL;
 131                              break;
 132                      }
 133 
 134                      /*
 135                       * We first ask MAC to update the MTU before we do anything.
 136                       * This may fail. It returns zero on success. The
 137                       * example_update_mtu function does device specific updates to
 138                       * ensure that the MTU on the device is updated and any internal
 139                       * data structures are up to date.
 140                       */
 141                      ret = mac_maxdsu_update(&ep->ep_mac_hdl, new_mtu);
 142                      if (ret == 0) {
 143                              example_update_mtu(ep, new_mtu);
 144                      }
 145                      break;
 146 
 147              /*
 148               * Devices may have their own private properties. If they do, they
 149               * should not return ENOTSUP, but instead see if it's a property they
 150               * recognize and handle it similar to those above. If it doesn't
 151               * recognize the name, then it should return ENOTSUP.
 152               */
 153              case MAC_PROP_PRIVATE:
 154                      ret = ENOTSUP;
 155                      break;
 156 
 157              default:
 158                      ret = ENOTSUP;
 159                      break;
 160              }
 161              mutex_exit(&ep->ep_lock);
 162 
 163              return (ret);
 164      }
 165 
 166 ERRORS
 167      The device driver may return one of the following errors.  While this
 168      list is not intended to be exhaustive, it is recommended to use one of
 169      these if possible.
 170 
 171      EINVAL             The contents of pr_val are outside the valid range for
 172                         the property.
 173 
 174      ENOTSUP            This error should be used whenever an unknown or
 175                         unsupported property is encountered.  It should also
 176                         be used when the property is not writable.
 177 
 178      EOVERFLOW          This error should be used when pr_valsize is smaller
 179                         than the required size for a given value.
 180 
 181      EBUSY              This error should be used when a property can't be set
 182                         because the device has started.  Note that device
 183                         driver writers are encouraged to design device drivers
 184                         such that this error is not possible.
 185 
 186      ECANCELLED         The device is in a state that does not allow it to
 187                         handle data; for example, it's suspended.
 188 
 189 SEE ALSO
 190      mac(9E), mac_register(9F), strcmp(9F), mac_register(9S)
 191 
 192 illumos                        February 15, 2020                       illumos