1 MC_GETPROP(9E)                Driver Entry Points               MC_GETPROP(9E)
   2 
   3 NAME
   4      mc_getprop - get device properties
   5 
   6 SYNOPSIS
   7      #include <sys/mac_provider.h>
   8 
   9      int
  10      prefix_m_getprop(void *driver, const char *pr_name, mac_prop_id_t pr_num,
  11          uint_t pr_valsize, 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 can store the
  29                    property.
  30 
  31 DESCRIPTION
  32      The mc_getprop() entry point is used to obtain the value of a given
  33      device's property and place it into pr_val.
  34 
  35      When the mc_getprop() 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 copy the property's
  43      value into 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 (bounded-size) properties to identify which one it
  51      is.
  52 
  53      At this time, private properties are limited to being string based
  54      properties.  If other types of property values are used, they will not be
  55      rendered correctly by dladm(1M).
  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 reading the properties.
  61 
  62 CONTEXT
  63      The mc_getprop() function is generally called from kernel context.
  64 
  65 RETURN VALUES
  66      Upon successful completion, the device driver should have copied the
  67      value of the property into pr_val and return 0.  Otherwise, a positive
  68      error should be returned to indicate failure.
  69 
  70 EXAMPLES
  71      The following example shows how a device driver might structure its
  72      mc_getprop() entry point.
  73 
  74      #include <sys/mac_provider.h>
  75 
  76      /*
  77       * Note, this example merely shows the structure of this function.
  78       * Different devices will manage their state in different ways. Like other
  79       * examples, this assumes that the device has state in a structure called
  80       * example_t and that there is a lock which keeps track of that state.
  81       */
  82      static char *example_priv_props[] = {
  83              "_rx_intr_throttle",
  84              "_tx_intr_throttle",
  85              NULL
  86      };
  87 
  88      static int
  89      example_m_getprop_private(example_t *ep, const char *pr_name, uint_t pr_valsize,
  90          void *pr_val)
  91      {
  92              uint32_t val;
  93 
  94              ASSERT(MUTEX_HELD(&ep->ep_lock));
  95              if (strcmp(pr_name, example_priv_props[0] == 0) {
  96                      val = ep->ep_rx_itr;
  97              } else if (strcmp(pr_name, example_priv_props[1] == 0) {
  98                      val = ep->ep_tx_itr;
  99              } else {
 100                      return (ENOTSUP);
 101              }
 102 
 103              /*
 104               * Due to issues in the GLDv3, these must be returned as string
 105               * properties.
 106               */
 107              if (snprintf(pr_val, pr_valsize, "%d", val) >= pr_valsize)
 108                      return (EOVERFLOW);
 109 
 110              return (0);
 111      }
 112 
 113      static int
 114      example_m_getprop(void *arg, const char *pr_name, mac_prop_id_t pr_num,
 115          uint_t pr_valsize, void *pr_val)
 116      {
 117              int ret = 0;
 118              uint64_t speed;
 119              example_t *ep = arg;
 120 
 121              mutex_enter(&ep->ep_lock);
 122 
 123              /*
 124               * This only handles a subset of the properties that exist on the
 125               * system. A proper driver will need to handle more. See mac(9E) for a
 126               * full property list.
 127               */
 128              switch (pr_num) {
 129              case MAC_PROP_DUPLEX:
 130                      if (pr_valsize < sizeof (link_duplex_t)) {
 131                              ret = EOVERFLOW;
 132                              break;
 133                      }
 134                      bcopy(ep->ep_link_duplex, pr_val, sizeof (link_duplex_t));
 135              case MAC_PROP_SPEED:
 136                      if (pr_valsize < sizeof (uint64_t)) {
 137                              ret = EOVERFLOW;
 138                              break;
 139                      }
 140                      /*
 141                       * The link speed is stored in Mbits/s in this driver and is
 142                       * expected in bits/s.
 143                       */
 144                      speed = ep->ep_link_speed * 1000000ULL;
 145                      bcopy(&speed, pr_val, sizeof (speed));
 146                      break;
 147              case MAC_PROP_MTU:
 148                      if (pr_valsize < sizeof (uint32_t)) {
 149                              ret = EOVERFLOW;
 150                              break;
 151                      }
 152                      bcopy(&ep->ep_mtu,  pr_val, sizeof (speed));
 153                      break;
 154              case MAC_PROP_PRIVATE:
 155                      ret = example_m_getprop_private(ep, pr_name, pr_valsize,
 156                          pr_val);
 157                      break;
 158              default:
 159                      ret = ENOTSUP;
 160                      break;
 161              }
 162 
 163              mutex_exit(&ep->ep_lock);
 164 
 165              return (ret);
 166      }
 167 
 168 ERRORS
 169      The device driver may return one of the following errors.  While this
 170      list is not intended to be exhaustive, it is recommended to use one of
 171      these if possible.
 172 
 173      ENOTSUP            This error should be used whenever an unknown or
 174                         unsupported property is encountered.
 175 
 176      EOVERFLOW          This error should be used when pr_valsize is smaller
 177                         than the required size for a given value.
 178 
 179 SEE ALSO
 180      mac(9E), mac_register(9F), strcmp(9F), mac_register(9S)
 181 
 182 illumos                        February 15, 2020                       illumos