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