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