1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
  23  * Use is subject to license terms.
  24  * Copyright 2018 Joyent, Inc.
  25  */
  26 
  27 /*
  28  * MAC Services Module
  29  */
  30 
  31 #include <sys/types.h>
  32 #include <sys/sysmacros.h>
  33 #include <sys/stream.h>
  34 #include <sys/kstat.h>
  35 #include <sys/mac.h>
  36 #include <sys/mac_impl.h>
  37 #include <sys/mac_client_impl.h>
  38 #include <sys/mac_stat.h>
  39 #include <sys/mac_soft_ring.h>
  40 #include <sys/vlan.h>
  41 
  42 #define MAC_KSTAT_NAME  "mac"
  43 #define MAC_KSTAT_CLASS "net"
  44 
  45 enum mac_stat {
  46         MAC_STAT_LCL,
  47         MAC_STAT_LCLBYTES,
  48         MAC_STAT_INTRS,
  49         MAC_STAT_INTRBYTES,
  50         MAC_STAT_POLLS,
  51         MAC_STAT_POLLBYTES,
  52         MAC_STAT_RXSDROPS,
  53         MAC_STAT_CHU10,
  54         MAC_STAT_CH10T50,
  55         MAC_STAT_CHO50,
  56         MAC_STAT_BLOCK,
  57         MAC_STAT_UNBLOCK,
  58         MAC_STAT_TXSDROPS,
  59         MAC_STAT_TX_ERRORS,
  60         MAC_STAT_MACSPOOFED,
  61         MAC_STAT_IPSPOOFED,
  62         MAC_STAT_DHCPSPOOFED,
  63         MAC_STAT_RESTRICTED,
  64         MAC_STAT_DHCPDROPPED,
  65         MAC_STAT_MULTIRCVBYTES,
  66         MAC_STAT_BRDCSTRCVBYTES,
  67         MAC_STAT_MULTIXMTBYTES,
  68         MAC_STAT_BRDCSTXMTBYTES
  69 };
  70 
  71 static mac_stat_info_t  i_mac_si[] = {
  72         { MAC_STAT_IFSPEED,     "ifspeed",      KSTAT_DATA_UINT64,      0 },
  73         { MAC_STAT_MULTIRCV,    "multircv",     KSTAT_DATA_UINT32,      0 },
  74         { MAC_STAT_BRDCSTRCV,   "brdcstrcv",    KSTAT_DATA_UINT32,      0 },
  75         { MAC_STAT_MULTIXMT,    "multixmt",     KSTAT_DATA_UINT32,      0 },
  76         { MAC_STAT_BRDCSTXMT,   "brdcstxmt",    KSTAT_DATA_UINT32,      0 },
  77         { MAC_STAT_NORCVBUF,    "norcvbuf",     KSTAT_DATA_UINT32,      0 },
  78         { MAC_STAT_IERRORS,     "ierrors",      KSTAT_DATA_UINT32,      0 },
  79         { MAC_STAT_UNKNOWNS,    "unknowns",     KSTAT_DATA_UINT32,      0 },
  80         { MAC_STAT_NOXMTBUF,    "noxmtbuf",     KSTAT_DATA_UINT32,      0 },
  81         { MAC_STAT_OERRORS,     "oerrors",      KSTAT_DATA_UINT32,      0 },
  82         { MAC_STAT_COLLISIONS,  "collisions",   KSTAT_DATA_UINT32,      0 },
  83         { MAC_STAT_UNDERFLOWS,  "uflo",         KSTAT_DATA_UINT32,      0 },
  84         { MAC_STAT_OVERFLOWS,   "oflo",         KSTAT_DATA_UINT32,      0 },
  85         { MAC_STAT_RBYTES,      "rbytes",       KSTAT_DATA_UINT32,      0 },
  86         { MAC_STAT_IPACKETS,    "ipackets",     KSTAT_DATA_UINT32,      0 },
  87         { MAC_STAT_OBYTES,      "obytes",       KSTAT_DATA_UINT32,      0 },
  88         { MAC_STAT_OPACKETS,    "opackets",     KSTAT_DATA_UINT32,      0 },
  89         { MAC_STAT_RBYTES,      "rbytes64",     KSTAT_DATA_UINT64,      0 },
  90         { MAC_STAT_IPACKETS,    "ipackets64",   KSTAT_DATA_UINT64,      0 },
  91         { MAC_STAT_OBYTES,      "obytes64",     KSTAT_DATA_UINT64,      0 },
  92         { MAC_STAT_OPACKETS,    "opackets64",   KSTAT_DATA_UINT64,      0 }
  93 };
  94 #define MAC_NKSTAT \
  95         (sizeof (i_mac_si) / sizeof (mac_stat_info_t))
  96 
  97 static mac_stat_info_t  i_mac_mod_si[] = {
  98         { MAC_STAT_LINK_STATE,  "link_state",   KSTAT_DATA_UINT32,
  99             (uint64_t)LINK_STATE_UNKNOWN },
 100         { MAC_STAT_LINK_UP,     "link_up",      KSTAT_DATA_UINT32,      0 },
 101         { MAC_STAT_PROMISC,     "promisc",      KSTAT_DATA_UINT32,      0 }
 102 };
 103 #define MAC_MOD_NKSTAT \
 104         (sizeof (i_mac_mod_si) / sizeof (mac_stat_info_t))
 105 
 106 #define MAC_MOD_KSTAT_OFFSET    0
 107 #define MAC_KSTAT_OFFSET        MAC_MOD_KSTAT_OFFSET + MAC_MOD_NKSTAT
 108 #define MAC_TYPE_KSTAT_OFFSET   MAC_KSTAT_OFFSET + MAC_NKSTAT
 109 
 110 /*
 111  * Definitions for per rx ring statistics
 112  */
 113 static mac_stat_info_t  i_mac_rx_ring_si[] = {
 114         { MAC_STAT_RBYTES,      "rbytes",       KSTAT_DATA_UINT64,      0},
 115         { MAC_STAT_IPACKETS,    "ipackets",     KSTAT_DATA_UINT64,      0},
 116         { MAC_STAT_HDROPS,      "hdrops",       KSTAT_DATA_UINT64,      0}
 117 };
 118 #define MAC_RX_RING_NKSTAT \
 119         (sizeof (i_mac_rx_ring_si) / sizeof (mac_stat_info_t))
 120 
 121 /*
 122  * Definitions for per tx ring statistics
 123  */
 124 static mac_stat_info_t  i_mac_tx_ring_si[] = {
 125         { MAC_STAT_OBYTES,      "obytes",       KSTAT_DATA_UINT64,      0},
 126         { MAC_STAT_OPACKETS,    "opackets",     KSTAT_DATA_UINT64,      0}
 127 };
 128 #define MAC_TX_RING_NKSTAT \
 129         (sizeof (i_mac_tx_ring_si) / sizeof (mac_stat_info_t))
 130 
 131 
 132 /*
 133  * Definitions for per software lane tx statistics
 134  */
 135 static mac_stat_info_t  i_mac_tx_swlane_si[] = {
 136         { MAC_STAT_OBYTES,      "obytes",       KSTAT_DATA_UINT64,      0},
 137         { MAC_STAT_OPACKETS,    "opackets",     KSTAT_DATA_UINT64,      0},
 138         { MAC_STAT_OERRORS,     "oerrors",      KSTAT_DATA_UINT64,      0},
 139         { MAC_STAT_BLOCK,       "blockcnt",     KSTAT_DATA_UINT64,      0},
 140         { MAC_STAT_UNBLOCK,     "unblockcnt",   KSTAT_DATA_UINT64,      0},
 141         { MAC_STAT_TXSDROPS,    "txsdrops",     KSTAT_DATA_UINT64,      0}
 142 };
 143 #define MAC_TX_SWLANE_NKSTAT \
 144         (sizeof (i_mac_tx_swlane_si) / sizeof (mac_stat_info_t))
 145 
 146 /*
 147  * Definitions for per software lane rx statistics
 148  */
 149 static mac_stat_info_t  i_mac_rx_swlane_si[] = {
 150         { MAC_STAT_IPACKETS,    "ipackets",     KSTAT_DATA_UINT64,      0},
 151         { MAC_STAT_RBYTES,      "rbytes",       KSTAT_DATA_UINT64,      0},
 152         { MAC_STAT_LCL,         "local",        KSTAT_DATA_UINT64,      0},
 153         { MAC_STAT_LCLBYTES,    "localbytes",   KSTAT_DATA_UINT64,      0},
 154         { MAC_STAT_INTRS,       "intrs",        KSTAT_DATA_UINT64,      0},
 155         { MAC_STAT_INTRBYTES,   "intrbytes",    KSTAT_DATA_UINT64,      0},
 156         { MAC_STAT_RXSDROPS,    "rxsdrops",     KSTAT_DATA_UINT64,      0}
 157 };
 158 #define MAC_RX_SWLANE_NKSTAT \
 159         (sizeof (i_mac_rx_swlane_si) / sizeof (mac_stat_info_t))
 160 
 161 /*
 162  * Definitions for per hardware lane rx statistics
 163  */
 164 static mac_stat_info_t  i_mac_rx_hwlane_si[] = {
 165         { MAC_STAT_IPACKETS,    "ipackets",     KSTAT_DATA_UINT64,      0},
 166         { MAC_STAT_RBYTES,      "rbytes",       KSTAT_DATA_UINT64,      0},
 167         { MAC_STAT_INTRS,       "intrs",        KSTAT_DATA_UINT64,      0},
 168         { MAC_STAT_INTRBYTES,   "intrbytes",    KSTAT_DATA_UINT64,      0},
 169         { MAC_STAT_POLLS,       "polls",        KSTAT_DATA_UINT64,      0},
 170         { MAC_STAT_POLLBYTES,   "pollbytes",    KSTAT_DATA_UINT64,      0},
 171         { MAC_STAT_RXSDROPS,    "rxsdrops",     KSTAT_DATA_UINT64,      0},
 172         { MAC_STAT_CHU10,       "chainunder10", KSTAT_DATA_UINT64,      0},
 173         { MAC_STAT_CH10T50,     "chain10to50",  KSTAT_DATA_UINT64,      0},
 174         { MAC_STAT_CHO50,       "chainover50",  KSTAT_DATA_UINT64,      0}
 175 };
 176 #define MAC_RX_HWLANE_NKSTAT \
 177         (sizeof (i_mac_rx_hwlane_si) / sizeof (mac_stat_info_t))
 178 
 179 /*
 180  * Definitions for misc statistics
 181  */
 182 static mac_stat_info_t  i_mac_misc_si[] = {
 183         { MAC_STAT_MULTIRCV,    "multircv",     KSTAT_DATA_UINT64,      0},
 184         { MAC_STAT_BRDCSTRCV,   "brdcstrcv",    KSTAT_DATA_UINT64,      0},
 185         { MAC_STAT_MULTIXMT,    "multixmt",     KSTAT_DATA_UINT64,      0},
 186         { MAC_STAT_BRDCSTXMT,   "brdcstxmt",    KSTAT_DATA_UINT64,      0},
 187         { MAC_STAT_MULTIRCVBYTES, "multircvbytes",   KSTAT_DATA_UINT64, 0},
 188         { MAC_STAT_BRDCSTRCVBYTES, "brdcstrcvbytes", KSTAT_DATA_UINT64, 0},
 189         { MAC_STAT_MULTIXMTBYTES,  "multixmtbytes",  KSTAT_DATA_UINT64, 0},
 190         { MAC_STAT_BRDCSTXMTBYTES, "brdcstxmtbytes", KSTAT_DATA_UINT64, 0},
 191         { MAC_STAT_TX_ERRORS,   "txerrors",     KSTAT_DATA_UINT64,      0},
 192         { MAC_STAT_MACSPOOFED,  "macspoofed",   KSTAT_DATA_UINT64,      0},
 193         { MAC_STAT_IPSPOOFED,   "ipspoofed",    KSTAT_DATA_UINT64,      0},
 194         { MAC_STAT_DHCPSPOOFED, "dhcpspoofed",  KSTAT_DATA_UINT64,      0},
 195         { MAC_STAT_RESTRICTED,  "restricted",   KSTAT_DATA_UINT64,      0},
 196         { MAC_STAT_DHCPDROPPED, "dhcpdropped",  KSTAT_DATA_UINT64,      0},
 197         { MAC_STAT_IPACKETS,    "ipackets",     KSTAT_DATA_UINT64,      0},
 198         { MAC_STAT_RBYTES,      "rbytes",       KSTAT_DATA_UINT64,      0},
 199         { MAC_STAT_LCL,         "local",        KSTAT_DATA_UINT64,      0},
 200         { MAC_STAT_LCLBYTES,    "localbytes",   KSTAT_DATA_UINT64,      0},
 201         { MAC_STAT_INTRS,       "intrs",        KSTAT_DATA_UINT64,      0},
 202         { MAC_STAT_INTRBYTES,   "intrbytes",    KSTAT_DATA_UINT64,      0},
 203         { MAC_STAT_POLLS,       "polls",        KSTAT_DATA_UINT64,      0},
 204         { MAC_STAT_POLLBYTES,   "pollbytes",    KSTAT_DATA_UINT64,      0},
 205         { MAC_STAT_RXSDROPS,    "rxsdrops",     KSTAT_DATA_UINT64,      0},
 206         { MAC_STAT_CHU10,       "chainunder10", KSTAT_DATA_UINT64,      0},
 207         { MAC_STAT_CH10T50,     "chain10to50",  KSTAT_DATA_UINT64,      0},
 208         { MAC_STAT_CHO50,       "chainover50",  KSTAT_DATA_UINT64,      0},
 209         { MAC_STAT_OBYTES,      "obytes",       KSTAT_DATA_UINT64,      0},
 210         { MAC_STAT_OPACKETS,    "opackets",     KSTAT_DATA_UINT64,      0},
 211         { MAC_STAT_OERRORS,     "oerrors",      KSTAT_DATA_UINT64,      0},
 212         { MAC_STAT_BLOCK,       "blockcnt",     KSTAT_DATA_UINT64,      0},
 213         { MAC_STAT_UNBLOCK,     "unblockcnt",   KSTAT_DATA_UINT64,      0},
 214         { MAC_STAT_TXSDROPS,    "txsdrops",     KSTAT_DATA_UINT64,      0}
 215 };
 216 #define MAC_SUMMARY_NKSTAT \
 217         (sizeof (i_mac_misc_si) / sizeof (mac_stat_info_t))
 218 
 219 /*
 220  * Definitions for per hardware lane tx statistics
 221  */
 222 static mac_stat_info_t  i_mac_tx_hwlane_si[] = {
 223         { MAC_STAT_OBYTES,      "obytes",       KSTAT_DATA_UINT64,      0},
 224         { MAC_STAT_OPACKETS,    "opackets",     KSTAT_DATA_UINT64,      0},
 225         { MAC_STAT_OERRORS,     "oerrors",      KSTAT_DATA_UINT64,      0},
 226         { MAC_STAT_BLOCK,       "blockcnt",     KSTAT_DATA_UINT64,      0},
 227         { MAC_STAT_UNBLOCK,     "unblockcnt",   KSTAT_DATA_UINT64,      0},
 228         { MAC_STAT_TXSDROPS,    "txsdrops",     KSTAT_DATA_UINT64,      0}
 229 };
 230 #define MAC_TX_HWLANE_NKSTAT \
 231         (sizeof (i_mac_tx_hwlane_si) / sizeof (mac_stat_info_t))
 232 
 233 /*
 234  * Definitions for per fanout rx statistics
 235  */
 236 static mac_stat_info_t  i_mac_rx_fanout_si[] = {
 237         { MAC_STAT_RBYTES,      "rbytes",       KSTAT_DATA_UINT64,      0},
 238         { MAC_STAT_IPACKETS,    "ipackets",     KSTAT_DATA_UINT64,      0},
 239 };
 240 #define MAC_RX_FANOUT_NKSTAT \
 241         (sizeof (i_mac_rx_fanout_si) / sizeof (mac_stat_info_t))
 242 
 243 /*
 244  * Private functions.
 245  */
 246 
 247 typedef struct {
 248         uint_t  si_offset;
 249 } stat_info_t;
 250 
 251 #define RX_SRS_STAT_OFF(f)      (offsetof(mac_rx_stats_t, f))
 252 static stat_info_t rx_srs_stats_list[] = {
 253         {RX_SRS_STAT_OFF(mrs_lclbytes)},
 254         {RX_SRS_STAT_OFF(mrs_lclcnt)},
 255         {RX_SRS_STAT_OFF(mrs_pollcnt)},
 256         {RX_SRS_STAT_OFF(mrs_pollbytes)},
 257         {RX_SRS_STAT_OFF(mrs_intrcnt)},
 258         {RX_SRS_STAT_OFF(mrs_intrbytes)},
 259         {RX_SRS_STAT_OFF(mrs_sdrops)},
 260         {RX_SRS_STAT_OFF(mrs_chaincntundr10)},
 261         {RX_SRS_STAT_OFF(mrs_chaincnt10to50)},
 262         {RX_SRS_STAT_OFF(mrs_chaincntover50)},
 263         {RX_SRS_STAT_OFF(mrs_ierrors)}
 264 };
 265 #define RX_SRS_STAT_SIZE                \
 266         (sizeof (rx_srs_stats_list) / sizeof (stat_info_t))
 267 
 268 #define TX_SOFTRING_STAT_OFF(f) (offsetof(mac_tx_stats_t, f))
 269 static stat_info_t tx_softring_stats_list[] = {
 270         {TX_SOFTRING_STAT_OFF(mts_obytes)},
 271         {TX_SOFTRING_STAT_OFF(mts_opackets)},
 272         {TX_SOFTRING_STAT_OFF(mts_oerrors)},
 273         {TX_SOFTRING_STAT_OFF(mts_blockcnt)},
 274         {TX_SOFTRING_STAT_OFF(mts_unblockcnt)},
 275         {TX_SOFTRING_STAT_OFF(mts_sdrops)},
 276 };
 277 #define TX_SOFTRING_STAT_SIZE           \
 278         (sizeof (tx_softring_stats_list) / sizeof (stat_info_t))
 279 
 280 static void
 281 i_mac_add_stats(void *sum, void *op1, void *op2,
 282     stat_info_t stats_list[], uint_t size)
 283 {
 284         int     i;
 285 
 286         for (i = 0; i < size; i++) {
 287                 uint64_t *op1_val = (uint64_t *)
 288                     ((uchar_t *)op1 + stats_list[i].si_offset);
 289                 uint64_t *op2_val = (uint64_t *)
 290                     ((uchar_t *)op2 + stats_list[i].si_offset);
 291                 uint64_t *sum_val = (uint64_t *)
 292                     ((uchar_t *)sum + stats_list[i].si_offset);
 293 
 294                 *sum_val =  *op1_val + *op2_val;
 295         }
 296 }
 297 
 298 static int
 299 i_mac_driver_stat_update(kstat_t *ksp, int rw)
 300 {
 301         mac_impl_t      *mip = ksp->ks_private;
 302         kstat_named_t   *knp = ksp->ks_data;
 303         uint_t          i;
 304         uint64_t        val;
 305         mac_stat_info_t *msi;
 306         uint_t          msi_index;
 307 
 308         if (rw != KSTAT_READ)
 309                 return (EACCES);
 310 
 311         for (i = 0; i < mip->mi_kstat_count; i++, msi_index++) {
 312                 if (i == MAC_MOD_KSTAT_OFFSET) {
 313                         msi_index = 0;
 314                         msi = i_mac_mod_si;
 315                 } else if (i == MAC_KSTAT_OFFSET) {
 316                         msi_index = 0;
 317                         msi = i_mac_si;
 318                 } else if (i == MAC_TYPE_KSTAT_OFFSET) {
 319                         msi_index = 0;
 320                         msi = mip->mi_type->mt_stats;
 321                 }
 322 
 323                 val = mac_stat_get((mac_handle_t)mip, msi[msi_index].msi_stat);
 324                 switch (msi[msi_index].msi_type) {
 325                 case KSTAT_DATA_UINT64:
 326                         knp->value.ui64 = val;
 327                         break;
 328                 case KSTAT_DATA_UINT32:
 329                         knp->value.ui32 = (uint32_t)val;
 330                         break;
 331                 default:
 332                         ASSERT(B_FALSE);
 333                         break;
 334                 }
 335 
 336                 knp++;
 337         }
 338 
 339         return (0);
 340 }
 341 
 342 static void
 343 i_mac_kstat_init(kstat_named_t *knp, mac_stat_info_t *si, uint_t count)
 344 {
 345         int i;
 346         for (i = 0; i < count; i++) {
 347                 kstat_named_init(knp, si[i].msi_name, si[i].msi_type);
 348                 knp++;
 349         }
 350 }
 351 
 352 static int
 353 i_mac_stat_update(kstat_t *ksp, int rw, uint64_t (*fn)(void *, uint_t),
 354     mac_stat_info_t *msi, uint_t count)
 355 {
 356         kstat_named_t   *knp = ksp->ks_data;
 357         uint_t          i;
 358         uint64_t        val;
 359 
 360         if (rw != KSTAT_READ)
 361                 return (EACCES);
 362 
 363         for (i = 0; i < count; i++) {
 364                 val = fn(ksp->ks_private, msi[i].msi_stat);
 365 
 366                 switch (msi[i].msi_type) {
 367                 case KSTAT_DATA_UINT64:
 368                         knp->value.ui64 = val;
 369                         break;
 370                 case KSTAT_DATA_UINT32:
 371                         knp->value.ui32 = (uint32_t)val;
 372                         break;
 373                 default:
 374                         ASSERT(B_FALSE);
 375                         break;
 376                 }
 377                 knp++;
 378         }
 379         return (0);
 380 }
 381 
 382 /*
 383  * Create kstat with given name - statname, update function - fn
 384  * and initialize it with given names - init_stat_info
 385  */
 386 static kstat_t *
 387 i_mac_stat_create(void *handle, const char *modname, const char *statname,
 388     int (*fn) (kstat_t *, int),
 389     mac_stat_info_t *init_stat_info, uint_t count)
 390 {
 391         kstat_t         *ksp;
 392         kstat_named_t   *knp;
 393 
 394         ksp = kstat_create(modname, 0, statname, "net",
 395             KSTAT_TYPE_NAMED, count, 0);
 396 
 397         if (ksp == NULL)
 398                 return (NULL);
 399 
 400         ksp->ks_update = fn;
 401         ksp->ks_private = handle;
 402 
 403         knp = (kstat_named_t *)ksp->ks_data;
 404         i_mac_kstat_init(knp, init_stat_info, count);
 405         kstat_install(ksp);
 406 
 407         return (ksp);
 408 }
 409 
 410 /*
 411  * Per rx ring statistics
 412  */
 413 uint64_t
 414 mac_rx_ring_stat_get(void *handle, uint_t stat)
 415 {
 416         mac_ring_t              *ring = (mac_ring_t *)handle;
 417         uint64_t                val = 0;
 418 
 419         /*
 420          * XXX Every ring-capable driver must implement an entry point to
 421          * query per ring statistics. CR 6893122 tracks this work item.
 422          * Once this bug is fixed, the framework should fail registration
 423          * for a driver that does not implement this entry point and
 424          * assert ring->mr_stat != NULL here.
 425          */
 426         if (ring->mr_stat != NULL)
 427                 ring->mr_stat(ring->mr_driver, stat, &val);
 428 
 429         return (val);
 430 }
 431 
 432 static int
 433 i_mac_rx_ring_stat_update(kstat_t *ksp, int rw)
 434 {
 435         return (i_mac_stat_update(ksp, rw, mac_rx_ring_stat_get,
 436             i_mac_rx_ring_si, MAC_RX_RING_NKSTAT));
 437 }
 438 
 439 static void
 440 i_mac_rx_ring_stat_create(mac_ring_t *ring, const char *modname,
 441     const char *statname)
 442 {
 443         kstat_t         *ksp;
 444 
 445         ksp = i_mac_stat_create(ring, modname, statname,
 446             i_mac_rx_ring_stat_update, i_mac_rx_ring_si, MAC_RX_RING_NKSTAT);
 447 
 448         ring->mr_ksp = ksp;
 449 }
 450 
 451 /*
 452  * Per tx ring statistics
 453  */
 454 uint64_t
 455 mac_tx_ring_stat_get(void *handle, uint_t stat)
 456 {
 457         mac_ring_t              *ring = (mac_ring_t *)handle;
 458         uint64_t                val = 0;
 459 
 460         /*
 461          * XXX Every ring-capable driver must implement an entry point to
 462          * query per ring statistics. CR 6893122 tracks this work item.
 463          * Once this bug is fixed, the framework should fail registration
 464          * for a driver that does not implement this entry point and
 465          * assert ring->mr_stat != NULL here.
 466          */
 467         if (ring->mr_stat != NULL)
 468                 ring->mr_stat(ring->mr_driver, stat, &val);
 469 
 470         return (val);
 471 }
 472 
 473 static int
 474 i_mac_tx_ring_stat_update(kstat_t *ksp, int rw)
 475 {
 476         return (i_mac_stat_update(ksp, rw, mac_tx_ring_stat_get,
 477             i_mac_tx_ring_si, MAC_TX_RING_NKSTAT));
 478 }
 479 
 480 static void
 481 i_mac_tx_ring_stat_create(mac_ring_t *ring, const char *modname,
 482     const char *statname)
 483 {
 484         kstat_t         *ksp;
 485 
 486         ksp = i_mac_stat_create(ring, modname, statname,
 487             i_mac_tx_ring_stat_update, i_mac_tx_ring_si, MAC_TX_RING_NKSTAT);
 488 
 489         ring->mr_ksp = ksp;
 490 }
 491 
 492 /*
 493  * Per software lane tx statistics
 494  */
 495 static uint64_t
 496 i_mac_tx_swlane_stat_get(void *handle, uint_t stat)
 497 {
 498         mac_soft_ring_set_t *mac_srs = (mac_soft_ring_set_t *)handle;
 499         mac_tx_stats_t *mac_tx_stat = &mac_srs->srs_tx.st_stat;
 500 
 501         switch (stat) {
 502         case MAC_STAT_OBYTES:
 503                 return (mac_tx_stat->mts_obytes);
 504 
 505         case MAC_STAT_OPACKETS:
 506                 return (mac_tx_stat->mts_opackets);
 507 
 508         case MAC_STAT_OERRORS:
 509                 return (mac_tx_stat->mts_oerrors);
 510 
 511         case MAC_STAT_BLOCK:
 512                 return (mac_tx_stat->mts_blockcnt);
 513 
 514         case MAC_STAT_UNBLOCK:
 515                 return (mac_tx_stat->mts_unblockcnt);
 516 
 517         case MAC_STAT_TXSDROPS:
 518                 return (mac_tx_stat->mts_sdrops);
 519 
 520         default:
 521                 return (0);
 522         }
 523 }
 524 
 525 static int
 526 i_mac_tx_swlane_stat_update(kstat_t *ksp, int rw)
 527 {
 528         return (i_mac_stat_update(ksp, rw, i_mac_tx_swlane_stat_get,
 529             i_mac_tx_swlane_si, MAC_TX_SWLANE_NKSTAT));
 530 }
 531 
 532 static void
 533 i_mac_tx_swlane_stat_create(mac_soft_ring_set_t *mac_srs, const char *modname,
 534     const char *statname)
 535 {
 536         kstat_t         *ksp;
 537 
 538         ksp = i_mac_stat_create(mac_srs, modname, statname,
 539             i_mac_tx_swlane_stat_update, i_mac_tx_swlane_si,
 540             MAC_TX_SWLANE_NKSTAT);
 541 
 542         mac_srs->srs_ksp = ksp;
 543 }
 544 
 545 /*
 546  * Per software lane rx statistics
 547  */
 548 static uint64_t
 549 i_mac_rx_swlane_stat_get(void *handle, uint_t stat)
 550 {
 551         mac_soft_ring_set_t     *mac_srs = (mac_soft_ring_set_t *)handle;
 552         mac_rx_stats_t          *mac_rx_stat = &mac_srs->srs_rx.sr_stat;
 553 
 554         switch (stat) {
 555         case MAC_STAT_IPACKETS:
 556                 return (mac_rx_stat->mrs_intrcnt +
 557                     mac_rx_stat->mrs_lclcnt);
 558 
 559         case MAC_STAT_RBYTES:
 560                 return (mac_rx_stat->mrs_intrbytes +
 561                     mac_rx_stat->mrs_lclbytes);
 562 
 563         case MAC_STAT_LCL:
 564                 return (mac_rx_stat->mrs_lclcnt);
 565 
 566         case MAC_STAT_LCLBYTES:
 567                 return (mac_rx_stat->mrs_lclbytes);
 568 
 569         case MAC_STAT_INTRS:
 570                 return (mac_rx_stat->mrs_intrcnt);
 571 
 572         case MAC_STAT_INTRBYTES:
 573                 return (mac_rx_stat->mrs_intrbytes);
 574 
 575         case MAC_STAT_RXSDROPS:
 576                 return (mac_rx_stat->mrs_sdrops);
 577 
 578         default:
 579                 return (0);
 580         }
 581 }
 582 
 583 static int
 584 i_mac_rx_swlane_stat_update(kstat_t *ksp, int rw)
 585 {
 586         return (i_mac_stat_update(ksp, rw, i_mac_rx_swlane_stat_get,
 587             i_mac_rx_swlane_si, MAC_RX_SWLANE_NKSTAT));
 588 }
 589 
 590 static void
 591 i_mac_rx_swlane_stat_create(mac_soft_ring_set_t *mac_srs, const char *modname,
 592     const char *statname)
 593 {
 594         kstat_t         *ksp;
 595 
 596         ksp = i_mac_stat_create(mac_srs, modname, statname,
 597             i_mac_rx_swlane_stat_update, i_mac_rx_swlane_si,
 598             MAC_RX_SWLANE_NKSTAT);
 599 
 600         mac_srs->srs_ksp = ksp;
 601 }
 602 
 603 
 604 /*
 605  * Per hardware lane rx statistics
 606  */
 607 static uint64_t
 608 i_mac_rx_hwlane_stat_get(void *handle, uint_t stat)
 609 {
 610         mac_soft_ring_set_t     *mac_srs = (mac_soft_ring_set_t *)handle;
 611         mac_rx_stats_t          *mac_rx_stat = &mac_srs->srs_rx.sr_stat;
 612 
 613         switch (stat) {
 614         case MAC_STAT_IPACKETS:
 615                 return (mac_rx_stat->mrs_intrcnt +
 616                     mac_rx_stat->mrs_pollcnt);
 617 
 618         case MAC_STAT_RBYTES:
 619                 return (mac_rx_stat->mrs_intrbytes +
 620                     mac_rx_stat->mrs_pollbytes);
 621 
 622         case MAC_STAT_INTRS:
 623                 return (mac_rx_stat->mrs_intrcnt);
 624 
 625         case MAC_STAT_INTRBYTES:
 626                 return (mac_rx_stat->mrs_intrbytes);
 627 
 628         case MAC_STAT_POLLS:
 629                 return (mac_rx_stat->mrs_pollcnt);
 630 
 631         case MAC_STAT_POLLBYTES:
 632                 return (mac_rx_stat->mrs_pollbytes);
 633 
 634         case MAC_STAT_RXSDROPS:
 635                 return (mac_rx_stat->mrs_sdrops);
 636 
 637         case MAC_STAT_CHU10:
 638                 return (mac_rx_stat->mrs_chaincntundr10);
 639 
 640         case MAC_STAT_CH10T50:
 641                 return (mac_rx_stat->mrs_chaincnt10to50);
 642 
 643         case MAC_STAT_CHO50:
 644                 return (mac_rx_stat->mrs_chaincntover50);
 645 
 646         default:
 647                 return (0);
 648         }
 649 }
 650 
 651 static int
 652 i_mac_rx_hwlane_stat_update(kstat_t *ksp, int rw)
 653 {
 654         return (i_mac_stat_update(ksp, rw, i_mac_rx_hwlane_stat_get,
 655             i_mac_rx_hwlane_si, MAC_RX_HWLANE_NKSTAT));
 656 }
 657 
 658 static void
 659 i_mac_rx_hwlane_stat_create(mac_soft_ring_set_t *mac_srs, const char *modname,
 660     const char *statname)
 661 {
 662         kstat_t         *ksp;
 663 
 664         ksp = i_mac_stat_create(mac_srs, modname, statname,
 665             i_mac_rx_hwlane_stat_update, i_mac_rx_hwlane_si,
 666             MAC_RX_HWLANE_NKSTAT);
 667 
 668         mac_srs->srs_ksp = ksp;
 669 }
 670 
 671 
 672 /*
 673  * Misc statistics
 674  *
 675  * Counts for
 676  *      - Multicast/broadcast Rx/Tx counts
 677  *      - Tx errors
 678  */
 679 static uint64_t
 680 i_mac_misc_stat_get(void *handle, uint_t stat)
 681 {
 682         flow_entry_t            *flent = handle;
 683         mac_client_impl_t       *mcip = flent->fe_mcip;
 684         mac_misc_stats_t        *mac_misc_stat = &mcip->mci_misc_stat;
 685         mac_rx_stats_t          *mac_rx_stat;
 686         mac_tx_stats_t          *mac_tx_stat;
 687 
 688         mac_rx_stat = &mac_misc_stat->mms_defunctrxlanestats;
 689         mac_tx_stat = &mac_misc_stat->mms_defuncttxlanestats;
 690 
 691         switch (stat) {
 692         case MAC_STAT_MULTIRCV:
 693                 return (mac_misc_stat->mms_multircv);
 694 
 695         case MAC_STAT_BRDCSTRCV:
 696                 return (mac_misc_stat->mms_brdcstrcv);
 697 
 698         case MAC_STAT_MULTIXMT:
 699                 return (mac_misc_stat->mms_multixmt);
 700 
 701         case MAC_STAT_BRDCSTXMT:
 702                 return (mac_misc_stat->mms_brdcstxmt);
 703 
 704         case MAC_STAT_MULTIRCVBYTES:
 705                 return (mac_misc_stat->mms_multircvbytes);
 706 
 707         case MAC_STAT_BRDCSTRCVBYTES:
 708                 return (mac_misc_stat->mms_brdcstrcvbytes);
 709 
 710         case MAC_STAT_MULTIXMTBYTES:
 711                 return (mac_misc_stat->mms_multixmtbytes);
 712 
 713         case MAC_STAT_BRDCSTXMTBYTES:
 714                 return (mac_misc_stat->mms_brdcstxmtbytes);
 715 
 716         case MAC_STAT_TX_ERRORS:
 717                 return (mac_misc_stat->mms_txerrors);
 718 
 719         case MAC_STAT_MACSPOOFED:
 720                 return (mac_misc_stat->mms_macspoofed);
 721 
 722         case MAC_STAT_IPSPOOFED:
 723                 return (mac_misc_stat->mms_ipspoofed);
 724 
 725         case MAC_STAT_DHCPSPOOFED:
 726                 return (mac_misc_stat->mms_dhcpspoofed);
 727 
 728         case MAC_STAT_RESTRICTED:
 729                 return (mac_misc_stat->mms_restricted);
 730 
 731         case MAC_STAT_DHCPDROPPED:
 732                 return (mac_misc_stat->mms_dhcpdropped);
 733 
 734         case MAC_STAT_IPACKETS:
 735                 return (mac_rx_stat->mrs_intrcnt +
 736                     mac_rx_stat->mrs_pollcnt);
 737 
 738         case MAC_STAT_RBYTES:
 739                 return (mac_rx_stat->mrs_intrbytes +
 740                     mac_rx_stat->mrs_pollbytes);
 741 
 742         case MAC_STAT_LCL:
 743                 return (mac_rx_stat->mrs_lclcnt);
 744 
 745         case MAC_STAT_LCLBYTES:
 746                 return (mac_rx_stat->mrs_lclbytes);
 747 
 748         case MAC_STAT_INTRS:
 749                 return (mac_rx_stat->mrs_intrcnt);
 750 
 751         case MAC_STAT_INTRBYTES:
 752                 return (mac_rx_stat->mrs_intrbytes);
 753 
 754         case MAC_STAT_POLLS:
 755                 return (mac_rx_stat->mrs_pollcnt);
 756 
 757         case MAC_STAT_POLLBYTES:
 758                 return (mac_rx_stat->mrs_pollbytes);
 759 
 760         case MAC_STAT_RXSDROPS:
 761                 return (mac_rx_stat->mrs_sdrops);
 762 
 763         case MAC_STAT_CHU10:
 764                 return (mac_rx_stat->mrs_chaincntundr10);
 765 
 766         case MAC_STAT_CH10T50:
 767                 return (mac_rx_stat->mrs_chaincnt10to50);
 768 
 769         case MAC_STAT_CHO50:
 770                 return (mac_rx_stat->mrs_chaincntover50);
 771 
 772         case MAC_STAT_OBYTES:
 773                 return (mac_tx_stat->mts_obytes);
 774 
 775         case MAC_STAT_OPACKETS:
 776                 return (mac_tx_stat->mts_opackets);
 777 
 778         case MAC_STAT_OERRORS:
 779                 return (mac_tx_stat->mts_oerrors);
 780 
 781         case MAC_STAT_BLOCK:
 782                 return (mac_tx_stat->mts_blockcnt);
 783 
 784         case MAC_STAT_UNBLOCK:
 785                 return (mac_tx_stat->mts_unblockcnt);
 786 
 787         case MAC_STAT_TXSDROPS:
 788                 return (mac_tx_stat->mts_sdrops);
 789 
 790         default:
 791                 return (0);
 792         }
 793 }
 794 
 795 static int
 796 i_mac_misc_stat_update(kstat_t *ksp, int rw)
 797 {
 798         return (i_mac_stat_update(ksp, rw, i_mac_misc_stat_get,
 799             i_mac_misc_si, MAC_SUMMARY_NKSTAT));
 800 }
 801 
 802 static void
 803 i_mac_misc_stat_create(flow_entry_t *flent, const char *modname,
 804     const char *statname)
 805 {
 806         kstat_t         *ksp;
 807 
 808         ksp = i_mac_stat_create(flent, modname, statname,
 809             i_mac_misc_stat_update, i_mac_misc_si,
 810             MAC_SUMMARY_NKSTAT);
 811 
 812         flent->fe_misc_stat_ksp = ksp;
 813 }
 814 
 815 /*
 816  * Per hardware lane tx statistics
 817  */
 818 static uint64_t
 819 i_mac_tx_hwlane_stat_get(void *handle, uint_t stat)
 820 {
 821         mac_soft_ring_t *ringp = (mac_soft_ring_t *)handle;
 822         mac_tx_stats_t  *mac_tx_stat = &ringp->s_st_stat;
 823 
 824         switch (stat) {
 825         case MAC_STAT_OBYTES:
 826                 return (mac_tx_stat->mts_obytes);
 827 
 828         case MAC_STAT_OPACKETS:
 829                 return (mac_tx_stat->mts_opackets);
 830 
 831         case MAC_STAT_OERRORS:
 832                 return (mac_tx_stat->mts_oerrors);
 833 
 834         case MAC_STAT_BLOCK:
 835                 return (mac_tx_stat->mts_blockcnt);
 836 
 837         case MAC_STAT_UNBLOCK:
 838                 return (mac_tx_stat->mts_unblockcnt);
 839 
 840         case MAC_STAT_TXSDROPS:
 841                 return (mac_tx_stat->mts_sdrops);
 842 
 843         default:
 844                 return (0);
 845         }
 846 }
 847 
 848 static int
 849 i_mac_tx_hwlane_stat_update(kstat_t *ksp, int rw)
 850 {
 851         return (i_mac_stat_update(ksp, rw, i_mac_tx_hwlane_stat_get,
 852             i_mac_tx_hwlane_si, MAC_TX_HWLANE_NKSTAT));
 853 }
 854 
 855 static void
 856 i_mac_tx_hwlane_stat_create(mac_soft_ring_t *ringp, const char *modname,
 857     const char *statname)
 858 {
 859         kstat_t         *ksp;
 860 
 861         ksp = i_mac_stat_create(ringp, modname, statname,
 862             i_mac_tx_hwlane_stat_update, i_mac_tx_hwlane_si,
 863             MAC_TX_HWLANE_NKSTAT);
 864 
 865         ringp->s_ring_ksp = ksp;
 866 }
 867 
 868 /*
 869  * Per fanout rx statistics
 870  */
 871 static uint64_t
 872 i_mac_rx_fanout_stat_get(void *handle, uint_t stat)
 873 {
 874         mac_soft_ring_t         *tcp_ringp = (mac_soft_ring_t *)handle;
 875         mac_soft_ring_t         *udp_ringp = NULL, *oth_ringp = NULL;
 876         mac_soft_ring_set_t     *mac_srs = tcp_ringp->s_ring_set;
 877         int                     index;
 878         uint64_t                val;
 879 
 880         mutex_enter(&mac_srs->srs_lock);
 881         /* Extract corresponding udp and oth ring pointers */
 882         for (index = 0; mac_srs->srs_tcp_soft_rings[index] != NULL; index++) {
 883                 if (mac_srs->srs_tcp_soft_rings[index] == tcp_ringp) {
 884                         udp_ringp = mac_srs->srs_udp_soft_rings[index];
 885                         oth_ringp = mac_srs->srs_oth_soft_rings[index];
 886                         break;
 887                 }
 888         }
 889 
 890         ASSERT((udp_ringp != NULL) && (oth_ringp != NULL));
 891 
 892         switch (stat) {
 893         case MAC_STAT_RBYTES:
 894                 val = (tcp_ringp->s_ring_total_rbytes) +
 895                     (udp_ringp->s_ring_total_rbytes) +
 896                     (oth_ringp->s_ring_total_rbytes);
 897                 break;
 898 
 899         case MAC_STAT_IPACKETS:
 900                 val = (tcp_ringp->s_ring_total_inpkt) +
 901                     (udp_ringp->s_ring_total_inpkt) +
 902                     (oth_ringp->s_ring_total_inpkt);
 903                 break;
 904 
 905         default:
 906                 val = 0;
 907                 break;
 908         }
 909         mutex_exit(&mac_srs->srs_lock);
 910         return (val);
 911 }
 912 
 913 static int
 914 i_mac_rx_fanout_stat_update(kstat_t *ksp, int rw)
 915 {
 916         return (i_mac_stat_update(ksp, rw, i_mac_rx_fanout_stat_get,
 917             i_mac_rx_fanout_si, MAC_RX_FANOUT_NKSTAT));
 918 }
 919 
 920 static void
 921 i_mac_rx_fanout_stat_create(mac_soft_ring_t *ringp, const char *modname,
 922     const char *statname)
 923 {
 924         kstat_t         *ksp;
 925 
 926         ksp = i_mac_stat_create(ringp, modname, statname,
 927             i_mac_rx_fanout_stat_update, i_mac_rx_fanout_si,
 928             MAC_RX_FANOUT_NKSTAT);
 929 
 930         ringp->s_ring_ksp = ksp;
 931 }
 932 
 933 /*
 934  * Exported functions.
 935  */
 936 
 937 /*
 938  * Create the "mac" kstat.  The "mac" kstat is comprised of three kinds of
 939  * statistics: statistics maintained by the mac module itself, generic mac
 940  * statistics maintained by the driver, and MAC-type specific statistics
 941  * also maintained by the driver.
 942  */
 943 void
 944 mac_driver_stat_create(mac_impl_t *mip)
 945 {
 946         kstat_t         *ksp;
 947         kstat_named_t   *knp;
 948         uint_t          count;
 949         major_t         major = getmajor(mip->mi_phy_dev);
 950 
 951         count = MAC_MOD_NKSTAT + MAC_NKSTAT + mip->mi_type->mt_statcount;
 952         ksp = kstat_create((const char *)ddi_major_to_name(major),
 953             getminor(mip->mi_phy_dev) - 1, MAC_KSTAT_NAME,
 954             MAC_KSTAT_CLASS, KSTAT_TYPE_NAMED, count, 0);
 955         if (ksp == NULL)
 956                 return;
 957 
 958         ksp->ks_update = i_mac_driver_stat_update;
 959         ksp->ks_private = mip;
 960         mip->mi_ksp = ksp;
 961         mip->mi_kstat_count = count;
 962 
 963         knp = (kstat_named_t *)ksp->ks_data;
 964         i_mac_kstat_init(knp, i_mac_mod_si, MAC_MOD_NKSTAT);
 965         knp += MAC_MOD_NKSTAT;
 966         i_mac_kstat_init(knp, i_mac_si, MAC_NKSTAT);
 967         if (mip->mi_type->mt_statcount > 0) {
 968                 knp += MAC_NKSTAT;
 969                 i_mac_kstat_init(knp, mip->mi_type->mt_stats,
 970                     mip->mi_type->mt_statcount);
 971         }
 972 
 973         kstat_install(ksp);
 974 }
 975 
 976 /*ARGSUSED*/
 977 void
 978 mac_driver_stat_delete(mac_impl_t *mip)
 979 {
 980         if (mip->mi_ksp != NULL) {
 981                 kstat_delete(mip->mi_ksp);
 982                 mip->mi_ksp = NULL;
 983                 mip->mi_kstat_count = 0;
 984         }
 985 }
 986 
 987 uint64_t
 988 mac_driver_stat_default(mac_impl_t *mip, uint_t stat)
 989 {
 990         uint_t  stat_index;
 991 
 992         if (IS_MAC_STAT(stat)) {
 993                 stat_index = stat - MAC_STAT_MIN;
 994                 ASSERT(stat_index < MAC_NKSTAT);
 995                 return (i_mac_si[stat_index].msi_default);
 996         }
 997         ASSERT(IS_MACTYPE_STAT(stat));
 998         stat_index = stat - MACTYPE_STAT_MIN;
 999         ASSERT(stat_index < mip->mi_type->mt_statcount);
1000         return (mip->mi_type->mt_stats[stat_index].msi_default);
1001 }
1002 
1003 void
1004 mac_ring_stat_create(mac_ring_t *ring)
1005 {
1006         mac_impl_t      *mip = ring->mr_mip;
1007         mac_group_t     *grp = (mac_group_t *)ring->mr_gh;
1008         char            statname[MAXNAMELEN];
1009         char            modname[MAXNAMELEN];
1010 
1011         if (mip->mi_state_flags & MIS_IS_AGGR) {
1012                 (void) strlcpy(modname, mip->mi_clients_list->mci_name,
1013                     MAXNAMELEN);
1014         } else
1015                 (void) strlcpy(modname, mip->mi_name, MAXNAMELEN);
1016 
1017         switch (ring->mr_type) {
1018         case MAC_RING_TYPE_RX:
1019                 (void) snprintf(statname, sizeof (statname),
1020                     "mac_rx_ring_%d_%d", grp->mrg_index, ring->mr_index);
1021                 i_mac_rx_ring_stat_create(ring, modname, statname);
1022                 break;
1023 
1024         case MAC_RING_TYPE_TX:
1025                 (void) snprintf(statname, sizeof (statname), "mac_tx_ring%d",
1026                     ring->mr_index);
1027                 i_mac_tx_ring_stat_create(ring, modname, statname);
1028                 break;
1029 
1030         default:
1031                 ASSERT(B_FALSE);
1032                 break;
1033         }
1034 }
1035 
1036 void
1037 mac_srs_stat_create(mac_soft_ring_set_t *mac_srs)
1038 {
1039         flow_entry_t    *flent = mac_srs->srs_flent;
1040         char            statname[MAXNAMELEN];
1041         boolean_t       is_tx_srs;
1042 
1043         /* No hardware/software lanes for user defined flows */
1044         if ((flent->fe_type & FLOW_USER) != 0)
1045                 return;
1046 
1047         is_tx_srs = ((mac_srs->srs_type & SRST_TX) != 0);
1048 
1049         if (is_tx_srs) {
1050                 mac_srs_tx_t    *srs_tx = &mac_srs->srs_tx;
1051                 mac_ring_t      *ring = srs_tx->st_arg2;
1052 
1053                 if (ring != NULL) {
1054                         (void) snprintf(statname, sizeof (statname),
1055                             "mac_tx_hwlane%d", ring->mr_index);
1056                 } else {
1057                         (void) snprintf(statname, sizeof (statname),
1058                             "mac_tx_swlane0");
1059                 }
1060                 i_mac_tx_swlane_stat_create(mac_srs, flent->fe_flow_name,
1061                     statname);
1062         } else {
1063                 mac_ring_t      *ring = mac_srs->srs_ring;
1064 
1065                 if (ring == NULL) {
1066                         (void) snprintf(statname, sizeof (statname),
1067                             "mac_rx_swlane0");
1068                         i_mac_rx_swlane_stat_create(mac_srs,
1069                             flent->fe_flow_name, statname);
1070                 } else {
1071                         (void) snprintf(statname, sizeof (statname),
1072                             "mac_rx_hwlane%d", ring->mr_index);
1073                         i_mac_rx_hwlane_stat_create(mac_srs,
1074                             flent->fe_flow_name, statname);
1075                 }
1076         }
1077 }
1078 
1079 void
1080 mac_misc_stat_create(flow_entry_t *flent)
1081 {
1082         char    statname[MAXNAMELEN];
1083 
1084         /* No misc stats for user defined or mcast/bcast flows */
1085         if (((flent->fe_type & FLOW_USER) != 0) ||
1086             ((flent->fe_type & FLOW_MCAST) != 0))
1087                 return;
1088 
1089         (void) snprintf(statname, sizeof (statname), "mac_misc_stat");
1090         i_mac_misc_stat_create(flent, flent->fe_flow_name, statname);
1091 }
1092 
1093 void
1094 mac_soft_ring_stat_create(mac_soft_ring_t *ringp)
1095 {
1096         mac_soft_ring_set_t     *mac_srs = ringp->s_ring_set;
1097         flow_entry_t            *flent = ringp->s_ring_mcip->mci_flent;
1098         mac_ring_t              *ring = (mac_ring_t *)ringp->s_ring_tx_arg2;
1099         boolean_t               is_tx_srs;
1100         char                    statname[MAXNAMELEN];
1101 
1102         /* No hardware/software lanes for user defined flows */
1103         if ((flent->fe_type & FLOW_USER) != 0)
1104                 return;
1105 
1106         is_tx_srs = ((mac_srs->srs_type & SRST_TX) != 0);
1107         if (is_tx_srs) {        /* tx side hardware lane */
1108                 ASSERT(ring != NULL);
1109                 (void) snprintf(statname, sizeof (statname), "mac_tx_hwlane%d",
1110                     ring->mr_index);
1111                 i_mac_tx_hwlane_stat_create(ringp, flent->fe_flow_name,
1112                     statname);
1113         } else {                /* rx side fanout */
1114                                 /* Maintain single stat for (tcp, udp, oth) */
1115                 if (ringp->s_ring_type & ST_RING_TCP) {
1116                         int                     index;
1117                         mac_soft_ring_t         *softring;
1118 
1119                         for (index = 0, softring = mac_srs->srs_soft_ring_head;
1120                             softring != NULL;
1121                             index++, softring = softring->s_ring_next) {
1122                                 if (softring == ringp)
1123                                         break;
1124                         }
1125 
1126                         if (mac_srs->srs_ring == NULL) {
1127                                 (void) snprintf(statname, sizeof (statname),
1128                                     "mac_rx_swlane0_fanout%d", index/3);
1129                         } else {
1130                                 (void) snprintf(statname, sizeof (statname),
1131                                     "mac_rx_hwlane%d_fanout%d",
1132                                     mac_srs->srs_ring->mr_index, index/3);
1133                         }
1134                         i_mac_rx_fanout_stat_create(ringp, flent->fe_flow_name,
1135                             statname);
1136                 }
1137         }
1138 }
1139 
1140 void
1141 mac_ring_stat_delete(mac_ring_t *ring)
1142 {
1143         if (ring->mr_ksp != NULL) {
1144                 kstat_delete(ring->mr_ksp);
1145                 ring->mr_ksp = NULL;
1146         }
1147 }
1148 
1149 void
1150 mac_srs_stat_delete(mac_soft_ring_set_t *mac_srs)
1151 {
1152         boolean_t       is_tx_srs;
1153 
1154         is_tx_srs = ((mac_srs->srs_type & SRST_TX) != 0);
1155         if (!is_tx_srs) {
1156                 /*
1157                  * Rx ring has been taken away. Before destroying corresponding
1158                  * SRS, save the stats recorded by that SRS.
1159                  */
1160                 mac_client_impl_t       *mcip = mac_srs->srs_mcip;
1161                 mac_misc_stats_t        *mac_misc_stat = &mcip->mci_misc_stat;
1162                 mac_rx_stats_t          *mac_rx_stat = &mac_srs->srs_rx.sr_stat;
1163 
1164                 i_mac_add_stats(&mac_misc_stat->mms_defunctrxlanestats,
1165                     mac_rx_stat, &mac_misc_stat->mms_defunctrxlanestats,
1166                     rx_srs_stats_list, RX_SRS_STAT_SIZE);
1167         }
1168 
1169         if (mac_srs->srs_ksp != NULL) {
1170                 kstat_delete(mac_srs->srs_ksp);
1171                 mac_srs->srs_ksp = NULL;
1172         }
1173 }
1174 
1175 void
1176 mac_misc_stat_delete(flow_entry_t *flent)
1177 {
1178         if (flent->fe_misc_stat_ksp != NULL) {
1179                 kstat_delete(flent->fe_misc_stat_ksp);
1180                 flent->fe_misc_stat_ksp = NULL;
1181         }
1182 }
1183 
1184 void
1185 mac_soft_ring_stat_delete(mac_soft_ring_t *ringp)
1186 {
1187         mac_soft_ring_set_t     *mac_srs = ringp->s_ring_set;
1188         boolean_t               is_tx_srs;
1189 
1190         is_tx_srs = ((mac_srs->srs_type & SRST_TX) != 0);
1191         if (is_tx_srs) {
1192                 /*
1193                  * Tx ring has been taken away. Before destroying corresponding
1194                  * soft ring, save the stats recorded by that soft ring.
1195                  */
1196                 mac_client_impl_t       *mcip = mac_srs->srs_mcip;
1197                 mac_misc_stats_t        *mac_misc_stat = &mcip->mci_misc_stat;
1198                 mac_tx_stats_t          *mac_tx_stat = &ringp->s_st_stat;
1199 
1200                 i_mac_add_stats(&mac_misc_stat->mms_defuncttxlanestats,
1201                     mac_tx_stat, &mac_misc_stat->mms_defuncttxlanestats,
1202                     tx_softring_stats_list, TX_SOFTRING_STAT_SIZE);
1203         }
1204 
1205         if (ringp->s_ring_ksp) {
1206                 kstat_delete(ringp->s_ring_ksp);
1207                 ringp->s_ring_ksp = NULL;
1208         }
1209 }
1210 
1211 void
1212 mac_pseudo_ring_stat_rename(mac_impl_t *mip)
1213 {
1214         mac_group_t     *group;
1215         mac_ring_t      *ring;
1216 
1217         /* Recreate pseudo rx ring kstats */
1218         for (group = mip->mi_rx_groups; group != NULL;
1219             group = group->mrg_next) {
1220                 for (ring = group->mrg_rings; ring != NULL;
1221                     ring = ring->mr_next) {
1222                         mac_ring_stat_delete(ring);
1223                         mac_ring_stat_create(ring);
1224                 }
1225         }
1226 
1227         /* Recreate pseudo tx ring kstats */
1228         for (group = mip->mi_tx_groups; group != NULL;
1229             group = group->mrg_next) {
1230                 for (ring = group->mrg_rings; ring != NULL;
1231                     ring = ring->mr_next) {
1232                         mac_ring_stat_delete(ring);
1233                         mac_ring_stat_create(ring);
1234                 }
1235         }
1236 }
1237 
1238 void
1239 mac_stat_rename(mac_client_impl_t *mcip)
1240 {
1241         flow_entry_t            *flent = mcip->mci_flent;
1242         mac_soft_ring_set_t     *mac_srs;
1243         mac_soft_ring_t         *ringp;
1244         int                     i, j;
1245 
1246         ASSERT(flent != NULL);
1247 
1248         /* Recreate rx SRSes kstats */
1249         for (i = 0; i < flent->fe_rx_srs_cnt; i++) {
1250                 mac_srs = (mac_soft_ring_set_t *)flent->fe_rx_srs[i];
1251                 mac_srs_stat_delete(mac_srs);
1252                 mac_srs_stat_create(mac_srs);
1253 
1254                 /* Recreate rx fanout kstats */
1255                 for (j = 0; j < mac_srs->srs_tcp_ring_count; j++) {
1256                         ringp = mac_srs->srs_tcp_soft_rings[j];
1257                         mac_soft_ring_stat_delete(ringp);
1258                         mac_soft_ring_stat_create(ringp);
1259                 }
1260         }
1261 
1262         /* Recreate tx SRS kstats */
1263         mac_srs = (mac_soft_ring_set_t *)flent->fe_tx_srs;
1264         mac_srs_stat_delete(mac_srs);
1265         mac_srs_stat_create(mac_srs);
1266 
1267         /* Recreate tx sofring kstats */
1268         for (ringp = mac_srs->srs_soft_ring_head; ringp;
1269             ringp = ringp->s_ring_next) {
1270                 mac_soft_ring_stat_delete(ringp);
1271                 mac_soft_ring_stat_create(ringp);
1272         }
1273 
1274         /* Recreate misc kstats */
1275         mac_misc_stat_delete(flent);
1276         mac_misc_stat_create(flent);
1277 }
1278 
1279 void
1280 mac_tx_srs_stat_recreate(mac_soft_ring_set_t *tx_srs, boolean_t add_stats)
1281 {
1282         mac_client_impl_t       *mcip = tx_srs->srs_mcip;
1283         mac_misc_stats_t        *mac_misc_stat = &mcip->mci_misc_stat;
1284         mac_tx_stats_t          *mac_tx_stat = &tx_srs->srs_tx.st_stat;
1285 
1286         if (add_stats) {
1287                 /* Add the stats to cumulative stats */
1288                 i_mac_add_stats(&mac_misc_stat->mms_defuncttxlanestats,
1289                     mac_tx_stat, &mac_misc_stat->mms_defuncttxlanestats,
1290                     tx_softring_stats_list, TX_SOFTRING_STAT_SIZE);
1291         }
1292 
1293         bzero(mac_tx_stat, sizeof (mac_tx_stats_t));
1294         mac_srs_stat_delete(tx_srs);
1295         mac_srs_stat_create(tx_srs);
1296 }