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 }