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 } 1295