1 .\"
   2 .\" This file and its contents are supplied under the terms of the
   3 .\" Common Development and Distribution License ("CDDL"), version 1.0.
   4 .\" You may only use this file in accordance with the terms of version
   5 .\" 1.0 of the CDDL.
   6 .\"
   7 .\" A full copy of the text of the CDDL should have accompanied this
   8 .\" source.  A copy of the CDDL is also available via the Internet at
   9 .\" http://www.illumos.org/license/CDDL.
  10 .\"
  11 .\"
  12 .\" Copyright 2016 Joyent, Inc.
  13 .\"
  14 .Dd February 15, 2020
  15 .Dt MC_GETPROP 9E
  16 .Os
  17 .Sh NAME
  18 .Nm mc_getprop
  19 .Nd get device properties
  20 .Sh SYNOPSIS
  21 .In sys/mac_provider.h
  22 .Ft int
  23 .Fo prefix_m_getprop
  24 .Fa "void *driver"
  25 .Fa "const char *pr_name"
  26 .Fa "mac_prop_id_t pr_num"
  27 .Fa "uint_t pr_valsize"
  28 .Fa "void *pr_val"
  29 .Fc
  30 .Sh INTERFACE LEVEL
  31 illumos DDI specific
  32 .Sh PARAMETERS
  33 .Bl -tag -width Fa
  34 .It Fa driver
  35 A pointer to the driver's private data that was passed in via the
  36 .Sy m_pdata
  37 member of the
  38 .Xr mac_register 9S
  39 structure to the
  40 .Xr mac_register 9F
  41 function.
  42 .It Fa pr_name
  43 A null-terminated string that contains the name of the property.
  44 .It Fa pr_num
  45 A constant that is used to identify the property.
  46 .It Fa pr_valsize
  47 A value that indicates the size in bytes of
  48 .Fa pr_val .
  49 .It Fa pr_val
  50 A pointer to a
  51 .Fa pr_valsize
  52 byte buffer that can store the property.
  53 .El
  54 .Sh DESCRIPTION
  55 The
  56 .Fn mc_getprop
  57 entry point is used to obtain the value of a given device's property and
  58 place it into
  59 .Fa pr_val .
  60 .Pp
  61 When the
  62 .Fn mc_getprop
  63 entry point is called, the driver needs to first identify the property.
  64 The set of possible properties and their meaning is listed in the
  65 .Sx PROPERTIES
  66 section of
  67 .Xr mac 9E .
  68 It should identify the property based on the value of
  69 .Fa pr_num .
  70 Most drivers will use a
  71 .Sy switch
  72 statement and for any property that it supports it should then check if
  73 the value in
  74 .Fa pr_valsize
  75 is sufficient for the property, comparing it to the minimum size
  76 listed for the property in
  77 .Xr mac 9E .
  78 If it is not, then it should return an error.
  79 Otherwise, it should copy the property's value into
  80 .Fa pr_val .
  81 When an unknown or unsupported
  82 property is encountered, generally the
  83 .Sy default
  84 case of the switch statement, the device driver should return an error.
  85 .Pp
  86 The special property
  87 .Sy MAC_PROP_PRIVATE
  88 indicates that this is a device driver specific private property.
  89 The device driver must then look at the value of the
  90 .Fa pr_name
  91 argument and use
  92 .Xr strcmp 9F
  93 on it, comparing it to each of its private (bounded-size) properties to
  94 identify which one it is.
  95 .Pp
  96 At this time, private properties are limited to being string based properties.
  97 If other types of property values are used, they will not be rendered
  98 correctly by
  99 .Xr dladm 1M .
 100 .Pp
 101 The device
 102 driver can access its device soft state by casting the
 103 .Fa device
 104 pointer to the appropriate structure.
 105 As this may be called while other operations are ongoing, the device driver
 106 should employ the appropriate locking while reading the properties.
 107 .Sh CONTEXT
 108 The
 109 .Fn mc_getprop
 110 function is generally called from
 111 .Sy kernel
 112 context.
 113 .Sh RETURN VALUES
 114 Upon successful completion, the device driver should have copied the
 115 value of the property into
 116 .Fa pr_val
 117 and return
 118 .Sy 0 .
 119 Otherwise, a positive error should be returned to indicate failure.
 120 .Sh EXAMPLES
 121 The following example shows how a device driver might structure its
 122 .Fn mc_getprop
 123 entry point.
 124 .Bd -literal
 125 #include <sys/mac_provider.h>
 126 
 127 /*
 128  * Note, this example merely shows the structure of this function.
 129  * Different devices will manage their state in different ways. Like other
 130  * examples, this assumes that the device has state in a structure called
 131  * example_t and that there is a lock which keeps track of that state.
 132  */
 133 static char *example_priv_props[] = {
 134         "_rx_intr_throttle",
 135         "_tx_intr_throttle",
 136         NULL
 137 };
 138 
 139 static int
 140 example_m_getprop_private(example_t *ep, const char *pr_name, uint_t pr_valsize,
 141     void *pr_val)
 142 {
 143         uint32_t val;
 144 
 145         ASSERT(MUTEX_HELD(&ep->ep_lock));
 146         if (strcmp(pr_name, example_priv_props[0] == 0) {
 147                 val = ep->ep_rx_itr;
 148         } else if (strcmp(pr_name, example_priv_props[1] == 0) {
 149                 val = ep->ep_tx_itr;
 150         } else {
 151                 return (ENOTSUP);
 152         }
 153 
 154         /*
 155          * Due to issues in the GLDv3, these must be returned as string
 156          * properties.
 157          */
 158         if (snprintf(pr_val, pr_valsize, "%d", val) >= pr_valsize)
 159                 return (EOVERFLOW);
 160 
 161         return (0);
 162 }
 163 
 164 static int
 165 example_m_getprop(void *arg, const char *pr_name, mac_prop_id_t pr_num,
 166     uint_t pr_valsize, void *pr_val)
 167 {
 168         int ret = 0;
 169         uint64_t speed;
 170         example_t *ep = arg;
 171 
 172         mutex_enter(&ep->ep_lock);
 173 
 174         /*
 175          * This only handles a subset of the properties that exist on the
 176          * system. A proper driver will need to handle more. See mac(9E) for a
 177          * full property list.
 178          */
 179         switch (pr_num) {
 180         case MAC_PROP_DUPLEX:
 181                 if (pr_valsize < sizeof (link_duplex_t)) {
 182                         ret = EOVERFLOW;
 183                         break;
 184                 }
 185                 bcopy(ep->ep_link_duplex, pr_val, sizeof (link_duplex_t));
 186         case MAC_PROP_SPEED:
 187                 if (pr_valsize < sizeof (uint64_t)) {
 188                         ret = EOVERFLOW;
 189                         break;
 190                 }
 191                 /*
 192                  * The link speed is stored in Mbits/s in this driver and is
 193                  * expected in bits/s.
 194                  */
 195                 speed = ep->ep_link_speed * 1000000ULL;
 196                 bcopy(&speed, pr_val, sizeof (speed));
 197                 break;
 198         case MAC_PROP_MTU:
 199                 if (pr_valsize < sizeof (uint32_t)) {
 200                         ret = EOVERFLOW;
 201                         break;
 202                 }
 203                 bcopy(&ep->ep_mtu, pr_val, sizeof (speed));
 204                 break;
 205         case MAC_PROP_PRIVATE:
 206                 ret = example_m_getprop_private(ep, pr_name, pr_valsize,
 207                     pr_val);
 208                 break;
 209         default:
 210                 ret = ENOTSUP;
 211                 break;
 212         }
 213 
 214         mutex_exit(&ep->ep_lock);
 215 
 216         return (ret);
 217 }
 218 .Ed
 219 .Sh ERRORS
 220 The device driver may return one of the following errors.
 221 While this list is not intended to be exhaustive, it is recommended to use one
 222 of these if possible.
 223 .Bl -tag -width Er
 224 .It Er ENOTSUP
 225 This error should be used whenever an unknown or unsupported property is
 226 encountered.
 227 .It Er EOVERFLOW
 228 This error should be used when
 229 .Fa pr_valsize
 230 is smaller than the required size for a given value.
 231 .El
 232 .Sh SEE ALSO
 233 .Xr mac 9E ,
 234 .Xr mac_register 9F ,
 235 .Xr strcmp 9F ,
 236 .Xr mac_register 9S