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 /* 23 * Copyright (c) 2010-2013, by Broadcom, Inc. 24 * All Rights Reserved. 25 */ 26 27 /* 28 * Copyright 2010 Sun Microsystems, Inc. All rights reserved. 29 * Use is subject to license terms. 30 */ 31 32 #include "bge_impl.h" 33 34 #define BGE_DBG BGE_DBG_STATS /* debug flag for this code */ 35 36 /* 37 * Local datatype for defining tables of (Offset, Name) pairs 38 */ 39 typedef struct { 40 offset_t index; 41 char *name; 42 } bge_ksindex_t; 43 44 45 /* 46 * Table of Hardware-defined Statistics Block Offsets and Names 47 */ 48 #define KS_NAME(s) { KS_ ## s, #s } 49 50 static const bge_ksindex_t bge_statistics[] = { 51 KS_NAME(ifHCInOctets), 52 KS_NAME(etherStatsFragments), 53 KS_NAME(ifHCInUcastPkts), 54 KS_NAME(ifHCInMulticastPkts), 55 KS_NAME(ifHCInBroadcastPkts), 56 KS_NAME(dot3StatsFCSErrors), 57 KS_NAME(dot3StatsAlignmentErrors), 58 KS_NAME(xonPauseFramesReceived), 59 KS_NAME(xoffPauseFramesReceived), 60 KS_NAME(macControlFramesReceived), 61 KS_NAME(xoffStateEntered), 62 KS_NAME(dot3StatsFrameTooLongs), 63 KS_NAME(etherStatsJabbers), 64 KS_NAME(etherStatsUndersizePkts), 65 KS_NAME(inRangeLengthError), 66 KS_NAME(outRangeLengthError), 67 KS_NAME(etherStatsPkts64Octets), 68 KS_NAME(etherStatsPkts65to127Octets), 69 KS_NAME(etherStatsPkts128to255Octets), 70 KS_NAME(etherStatsPkts256to511Octets), 71 KS_NAME(etherStatsPkts512to1023Octets), 72 KS_NAME(etherStatsPkts1024to1518Octets), 73 KS_NAME(etherStatsPkts1519to2047Octets), 74 KS_NAME(etherStatsPkts2048to4095Octets), 75 KS_NAME(etherStatsPkts4096to8191Octets), 76 KS_NAME(etherStatsPkts8192to9022Octets), 77 78 KS_NAME(ifHCOutOctets), 79 KS_NAME(etherStatsCollisions), 80 KS_NAME(outXonSent), 81 KS_NAME(outXoffSent), 82 KS_NAME(flowControlDone), 83 KS_NAME(dot3StatsInternalMacTransmitErrors), 84 KS_NAME(dot3StatsSingleCollisionFrames), 85 KS_NAME(dot3StatsMultipleCollisionFrames), 86 KS_NAME(dot3StatsDeferredTransmissions), 87 KS_NAME(dot3StatsExcessiveCollisions), 88 KS_NAME(dot3StatsLateCollisions), 89 KS_NAME(dot3Collided2Times), 90 KS_NAME(dot3Collided3Times), 91 KS_NAME(dot3Collided4Times), 92 KS_NAME(dot3Collided5Times), 93 KS_NAME(dot3Collided6Times), 94 KS_NAME(dot3Collided7Times), 95 KS_NAME(dot3Collided8Times), 96 KS_NAME(dot3Collided9Times), 97 KS_NAME(dot3Collided10Times), 98 KS_NAME(dot3Collided11Times), 99 KS_NAME(dot3Collided12Times), 100 KS_NAME(dot3Collided13Times), 101 KS_NAME(dot3Collided14Times), 102 KS_NAME(dot3Collided15Times), 103 KS_NAME(ifHCOutUcastPkts), 104 KS_NAME(ifHCOutMulticastPkts), 105 KS_NAME(ifHCOutBroadcastPkts), 106 KS_NAME(dot3StatsCarrierSenseErrors), 107 KS_NAME(ifOutDiscards), 108 KS_NAME(ifOutErrors), 109 110 KS_NAME(COSIfHCInPkts_1), 111 KS_NAME(COSIfHCInPkts_2), 112 KS_NAME(COSIfHCInPkts_3), 113 KS_NAME(COSIfHCInPkts_4), 114 KS_NAME(COSIfHCInPkts_5), 115 KS_NAME(COSIfHCInPkts_6), 116 KS_NAME(COSIfHCInPkts_7), 117 KS_NAME(COSIfHCInPkts_8), 118 KS_NAME(COSIfHCInPkts_9), 119 KS_NAME(COSIfHCInPkts_10), 120 KS_NAME(COSIfHCInPkts_11), 121 KS_NAME(COSIfHCInPkts_12), 122 KS_NAME(COSIfHCInPkts_13), 123 KS_NAME(COSIfHCInPkts_14), 124 KS_NAME(COSIfHCInPkts_15), 125 KS_NAME(COSIfHCInPkts_16), 126 KS_NAME(COSFramesDroppedDueToFilters), 127 KS_NAME(nicDmaWriteQueueFull), 128 KS_NAME(nicDmaWriteHighPriQueueFull), 129 KS_NAME(nicNoMoreRxBDs), 130 KS_NAME(ifInDiscards), 131 KS_NAME(ifInErrors), 132 KS_NAME(nicRecvThresholdHit), 133 134 KS_NAME(COSIfHCOutPkts_1), 135 KS_NAME(COSIfHCOutPkts_2), 136 KS_NAME(COSIfHCOutPkts_3), 137 KS_NAME(COSIfHCOutPkts_4), 138 KS_NAME(COSIfHCOutPkts_5), 139 KS_NAME(COSIfHCOutPkts_6), 140 KS_NAME(COSIfHCOutPkts_7), 141 KS_NAME(COSIfHCOutPkts_8), 142 KS_NAME(COSIfHCOutPkts_9), 143 KS_NAME(COSIfHCOutPkts_10), 144 KS_NAME(COSIfHCOutPkts_11), 145 KS_NAME(COSIfHCOutPkts_12), 146 KS_NAME(COSIfHCOutPkts_13), 147 KS_NAME(COSIfHCOutPkts_14), 148 KS_NAME(COSIfHCOutPkts_15), 149 KS_NAME(COSIfHCOutPkts_16), 150 KS_NAME(nicDmaReadQueueFull), 151 KS_NAME(nicDmaReadHighPriQueueFull), 152 KS_NAME(nicSendDataCompQueueFull), 153 KS_NAME(nicRingSetSendProdIndex), 154 KS_NAME(nicRingStatusUpdate), 155 KS_NAME(nicInterrupts), 156 KS_NAME(nicAvoidedInterrupts), 157 KS_NAME(nicSendThresholdHit), 158 159 { KS_STATS_SIZE, NULL } 160 }; 161 162 static const bge_ksindex_t bge_stat_val[] = { 163 KS_NAME(ifHCOutOctets), 164 KS_NAME(etherStatsCollisions), 165 KS_NAME(outXonSent), 166 KS_NAME(outXoffSent), 167 KS_NAME(dot3StatsInternalMacTransmitErrors), 168 KS_NAME(dot3StatsSingleCollisionFrames), 169 KS_NAME(dot3StatsMultipleCollisionFrames), 170 KS_NAME(dot3StatsDeferredTransmissions), 171 KS_NAME(dot3StatsExcessiveCollisions), 172 KS_NAME(dot3StatsLateCollisions), 173 KS_NAME(ifHCOutUcastPkts), 174 KS_NAME(ifHCOutMulticastPkts), 175 KS_NAME(ifHCOutBroadcastPkts), 176 KS_NAME(ifHCInOctets), 177 KS_NAME(etherStatsFragments), 178 KS_NAME(ifHCInUcastPkts), 179 KS_NAME(ifHCInMulticastPkts), 180 KS_NAME(ifHCInBroadcastPkts), 181 KS_NAME(dot3StatsFCSErrors), 182 KS_NAME(dot3StatsAlignmentErrors), 183 KS_NAME(xonPauseFramesReceived), 184 KS_NAME(xoffPauseFramesReceived), 185 KS_NAME(macControlFramesReceived), 186 KS_NAME(xoffStateEntered), 187 KS_NAME(dot3StatsFrameTooLongs), 188 KS_NAME(etherStatsJabbers), 189 KS_NAME(etherStatsUndersizePkts), 190 191 { KS_STAT_REG_SIZE, NULL } 192 }; 193 194 static int 195 bge_statistics_update(kstat_t *ksp, int flag) 196 { 197 bge_t *bgep; 198 bge_statistics_t *bstp; 199 bge_statistics_reg_t *pstats; 200 kstat_named_t *knp; 201 const bge_ksindex_t *ksip; 202 203 if (flag != KSTAT_READ) 204 return (EACCES); 205 206 bgep = ksp->ks_private; 207 if (bgep->chipid.statistic_type == BGE_STAT_BLK) 208 bstp = DMA_VPTR(bgep->statistics); 209 210 knp = ksp->ks_data; 211 212 /* 213 * Transfer the statistics values from the copy that the 214 * chip updates via DMA to the named-kstat structure. 215 * 216 * As above, we don't bother to sync or stop updates to the 217 * statistics, 'cos it doesn't really matter if they're a few 218 * microseconds out of date or less than 100% consistent ... 219 */ 220 if (bgep->chipid.statistic_type == BGE_STAT_BLK) 221 for (ksip = bge_statistics; ksip->name != NULL; ++knp, ++ksip) 222 knp->value.ui64 = bstp->a[ksip->index]; 223 else { 224 pstats = bgep->pstats; 225 (knp++)->value.ui64 = (uint64_t)(pstats->ifHCOutOctets); 226 (knp++)->value.ui64 = (uint64_t)(pstats->etherStatsCollisions); 227 (knp++)->value.ui64 = (uint64_t)(pstats->outXonSent); 228 (knp++)->value.ui64 = (uint64_t)(pstats->outXoffSent); 229 (knp++)->value.ui64 = 230 (uint64_t)(pstats->dot3StatsInternalMacTransmitErrors); 231 (knp++)->value.ui64 = 232 (uint64_t)(pstats->dot3StatsSingleCollisionFrames); 233 (knp++)->value.ui64 = 234 (uint64_t)(pstats->dot3StatsMultipleCollisionFrames); 235 (knp++)->value.ui64 = 236 (uint64_t)(pstats->dot3StatsDeferredTransmissions); 237 (knp++)->value.ui64 = 238 (uint64_t)(pstats->dot3StatsExcessiveCollisions); 239 (knp++)->value.ui64 = 240 (uint64_t)(pstats->dot3StatsLateCollisions); 241 (knp++)->value.ui64 = (uint64_t)(pstats->ifHCOutUcastPkts); 242 (knp++)->value.ui64 = (uint64_t)(pstats->ifHCOutMulticastPkts); 243 (knp++)->value.ui64 = (uint64_t)(pstats->ifHCOutBroadcastPkts); 244 (knp++)->value.ui64 = (uint64_t)(pstats->ifHCInOctets); 245 (knp++)->value.ui64 = (uint64_t)(pstats->etherStatsFragments); 246 (knp++)->value.ui64 = (uint64_t)(pstats->ifHCInUcastPkts); 247 (knp++)->value.ui64 = (uint64_t)(pstats->ifHCInMulticastPkts); 248 (knp++)->value.ui64 = (uint64_t)(pstats->ifHCInBroadcastPkts); 249 (knp++)->value.ui64 = (uint64_t)(pstats->dot3StatsFCSErrors); 250 (knp++)->value.ui64 = 251 (uint64_t)(pstats->dot3StatsAlignmentErrors); 252 (knp++)->value.ui64 = 253 (uint64_t)(pstats->xonPauseFramesReceived); 254 (knp++)->value.ui64 = 255 (uint64_t)(pstats->xoffPauseFramesReceived); 256 (knp++)->value.ui64 = 257 (uint64_t)(pstats->macControlFramesReceived); 258 (knp++)->value.ui64 = (uint64_t)(pstats->xoffStateEntered); 259 (knp++)->value.ui64 = 260 (uint64_t)(pstats->dot3StatsFrameTooLongs); 261 (knp++)->value.ui64 = (uint64_t)(pstats->etherStatsJabbers); 262 (knp++)->value.ui64 = 263 (uint64_t)(pstats->etherStatsUndersizePkts); 264 } 265 266 return (0); 267 } 268 269 static const bge_ksindex_t bge_chipid[] = { 270 { 0, "asic_rev" }, 271 { 1, "businfo" }, 272 { 2, "command" }, 273 274 { 3, "vendor_id" }, 275 { 4, "device_id" }, 276 { 5, "subsystem_vendor_id" }, 277 { 6, "subsystem_device_id" }, 278 { 7, "revision_id" }, 279 { 8, "cache_line_size" }, 280 { 9, "latency_timer" }, 281 282 { 10, "flags" }, 283 { 11, "chip_type" }, 284 { 12, "mbuf_base" }, 285 { 13, "mbuf_count" }, 286 { 14, "hw_mac_addr" }, 287 288 { 15, "&bus_type" }, 289 { 16, "&bus_speed" }, 290 { 17, "&bus_size" }, 291 { 18, "&supported" }, 292 { 19, "&interface" }, 293 294 { 20, "nvtype" }, 295 296 { 21, "asic_rev_prod_id" }, 297 298 { -1, NULL } 299 }; 300 301 static void 302 bge_set_char_kstat(kstat_named_t *knp, const char *s) 303 { 304 (void) strncpy(knp->value.c, s, sizeof (knp->value.c)); 305 } 306 307 static int 308 bge_chipid_update(kstat_t *ksp, int flag) 309 { 310 bge_t *bgep; 311 kstat_named_t *knp; 312 uint64_t tmp; 313 314 if (flag != KSTAT_READ) 315 return (EACCES); 316 317 bgep = ksp->ks_private; 318 knp = ksp->ks_data; 319 320 (knp++)->value.ui64 = bgep->chipid.asic_rev; 321 (knp++)->value.ui64 = bgep->chipid.businfo; 322 (knp++)->value.ui64 = bgep->chipid.command; 323 324 (knp++)->value.ui64 = bgep->chipid.vendor; 325 (knp++)->value.ui64 = bgep->chipid.device; 326 (knp++)->value.ui64 = bgep->chipid.subven; 327 (knp++)->value.ui64 = bgep->chipid.subdev; 328 (knp++)->value.ui64 = bgep->chipid.revision; 329 (knp++)->value.ui64 = bgep->chipid.clsize; 330 (knp++)->value.ui64 = bgep->chipid.latency; 331 332 (knp++)->value.ui64 = bgep->chipid.flags; 333 (knp++)->value.ui64 = bgep->chipid.chip_label; 334 (knp++)->value.ui64 = bgep->chipid.mbuf_base; 335 (knp++)->value.ui64 = bgep->chipid.mbuf_length; 336 (knp++)->value.ui64 = bgep->chipid.hw_mac_addr; 337 338 /* 339 * Now we interpret some of the above into readable strings 340 */ 341 tmp = bgep->chipid.businfo; 342 bge_set_char_kstat(knp++, 343 tmp & PCISTATE_BUS_IS_PCI ? "PCI" : "PCI-X"); 344 bge_set_char_kstat(knp++, 345 tmp & PCISTATE_BUS_IS_FAST ? "fast" : "normal"); 346 bge_set_char_kstat(knp++, 347 tmp & PCISTATE_BUS_IS_32_BIT ? "32 bit" : "64 bit"); 348 349 tmp = bgep->chipid.flags; 350 bge_set_char_kstat(knp++, 351 tmp & CHIP_FLAG_SUPPORTED ? "yes" : "no"); 352 bge_set_char_kstat(knp++, 353 tmp & CHIP_FLAG_SERDES ? "serdes" : "copper"); 354 355 (knp++)->value.ui64 = 356 ((bgep->chipid.nvtype == BGE_NVTYPE_NONE) || 357 (bgep->chipid.nvtype == BGE_NVTYPE_UNKNOWN)) ? 358 0 : bgep->chipid.nvtype; 359 360 (knp++)->value.ui64 = bgep->chipid.asic_rev_prod_id; 361 362 return (0); 363 } 364 365 static const bge_ksindex_t bge_driverinfo[] = { 366 { 0, "rx_buff_addr" }, 367 { 1, "tx_buff_addr" }, 368 { 2, "rx_desc_addr" }, 369 { 3, "tx_desc_addr" }, 370 371 { 4, "tx_desc_free" }, 372 { 5, "tx_array" }, 373 { 6, "tc_next" }, 374 { 7, "tx_next" }, 375 { 8, "txfill_next" }, 376 { 9, "txpkt_next" }, 377 { 10, "tx_bufs" }, 378 { 11, "tx_flow" }, 379 { 12, "tx_resched_needed" }, 380 { 13, "tx_resched" }, 381 { 14, "tx_nobuf" }, 382 { 15, "tx_nobd" }, 383 { 16, "tx_block" }, 384 { 17, "tx_alloc_fail" }, 385 386 { 18, "watchdog" }, 387 { 19, "chip_resets" }, 388 { 20, "dma_misses" }, 389 { 21, "update_misses" }, 390 391 { 22, "misc_host_config" }, 392 { 23, "dma_rw_control" }, 393 { 24, "pci_bus_info" }, 394 395 { 25, "buff_mgr_status" }, 396 { 26, "rcv_init_status" }, 397 398 { -1, NULL } 399 }; 400 401 static int 402 bge_driverinfo_update(kstat_t *ksp, int flag) 403 { 404 bge_t *bgep; 405 kstat_named_t *knp; 406 ddi_acc_handle_t handle; 407 408 if (flag != KSTAT_READ) 409 return (EACCES); 410 411 bgep = ksp->ks_private; 412 if (bgep->bge_chip_state == BGE_CHIP_FAULT) 413 return (EIO); 414 415 knp = ksp->ks_data; 416 417 (knp++)->value.ui64 = bgep->rx_buff[0].cookie.dmac_laddress; 418 (knp++)->value.ui64 = bgep->tx_buff[0].cookie.dmac_laddress; 419 (knp++)->value.ui64 = bgep->rx_desc[0].cookie.dmac_laddress; 420 (knp++)->value.ui64 = bgep->tx_desc.cookie.dmac_laddress; 421 422 (knp++)->value.ui64 = bgep->send[0].tx_free; 423 (knp++)->value.ui64 = bgep->send[0].tx_array; 424 (knp++)->value.ui64 = bgep->send[0].tc_next; 425 (knp++)->value.ui64 = bgep->send[0].tx_next; 426 (knp++)->value.ui64 = bgep->send[0].txfill_next; 427 (knp++)->value.ui64 = bgep->send[0].txpkt_next; 428 (knp++)->value.ui64 = bgep->send[0].txbuf_pop_queue->count + 429 bgep->send[0].txbuf_push_queue->count; 430 (knp++)->value.ui64 = bgep->send[0].tx_flow; 431 (knp++)->value.ui64 = bgep->tx_resched_needed; 432 (knp++)->value.ui64 = bgep->tx_resched; 433 (knp++)->value.ui64 = bgep->send[0].tx_nobuf; 434 (knp++)->value.ui64 = bgep->send[0].tx_nobd; 435 (knp++)->value.ui64 = bgep->send[0].tx_block; 436 (knp++)->value.ui64 = bgep->send[0].tx_alloc_fail; 437 438 (knp++)->value.ui64 = bgep->watchdog; 439 (knp++)->value.ui64 = bgep->chip_resets; 440 (knp++)->value.ui64 = bgep->missed_dmas; 441 (knp++)->value.ui64 = bgep->missed_updates; 442 443 /* 444 * Hold the mutex while accessing the chip registers 445 * just in case the factotum is trying to reset it! 446 */ 447 handle = bgep->cfg_handle; 448 mutex_enter(bgep->genlock); 449 (knp++)->value.ui64 = pci_config_get32(handle, PCI_CONF_BGE_MHCR); 450 (knp++)->value.ui64 = pci_config_get32(handle, PCI_CONF_BGE_PDRWCR); 451 (knp++)->value.ui64 = pci_config_get32(handle, PCI_CONF_BGE_PCISTATE); 452 if (bge_check_acc_handle(bgep, bgep->cfg_handle) != DDI_FM_OK) { 453 ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_DEGRADED); 454 mutex_exit(bgep->genlock); 455 return (EIO); 456 } 457 458 (knp++)->value.ui64 = bge_reg_get32(bgep, BUFFER_MANAGER_STATUS_REG); 459 (knp++)->value.ui64 = bge_reg_get32(bgep, RCV_INITIATOR_STATUS_REG); 460 if (bge_check_acc_handle(bgep, bgep->io_handle) != DDI_FM_OK) { 461 ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_DEGRADED); 462 mutex_exit(bgep->genlock); 463 return (EIO); 464 } 465 mutex_exit(bgep->genlock); 466 467 return (0); 468 } 469 470 static const bge_ksindex_t bge_serdes[] = { 471 { 0, "serdes_status" }, 472 { 1, "serdes_advert" }, 473 { 2, "serdes_lpadv" }, 474 475 { -1, NULL } 476 }; 477 478 static int 479 bge_serdes_update(kstat_t *ksp, int flag) 480 { 481 bge_t *bgep; 482 kstat_named_t *knp; 483 484 if (flag != KSTAT_READ) 485 return (EACCES); 486 487 bgep = ksp->ks_private; 488 knp = ksp->ks_data; 489 490 (knp++)->value.ui64 = bgep->serdes_status; 491 (knp++)->value.ui64 = bgep->serdes_advert; 492 (knp++)->value.ui64 = bgep->serdes_lpadv; 493 494 return (0); 495 } 496 497 static const bge_ksindex_t bge_phydata[] = { 498 { MII_CONTROL, "mii_control" }, 499 { MII_STATUS, "mii_status" }, 500 { MII_PHYIDH, "phy_identifier" }, 501 { MII_AN_ADVERT, "an_advert" }, 502 { MII_AN_LPABLE, "an_lp_ability" }, 503 { MII_AN_EXPANSION, "an_expansion" }, 504 { MII_AN_NXTPGLP, "an_lp_nextpage" }, 505 { MII_MSCONTROL, "gbit_control" }, 506 { MII_MSSTATUS, "gbit_status" }, 507 { MII_EXTSTATUS, "ieee_ext_status" }, 508 { MII_EXT_CONTROL, "phy_ext_control" }, 509 { MII_EXT_STATUS, "phy_ext_status" }, 510 { MII_RCV_ERR_COUNT, "receive_error_count" }, 511 { MII_FALSE_CARR_COUNT, "false_carrier_count" }, 512 { MII_RCV_NOT_OK_COUNT, "receiver_not_ok_count" }, 513 { MII_AUX_CONTROL, "aux_control" }, 514 { MII_AUX_STATUS, "aux_status" }, 515 { MII_INTR_STATUS, "intr_status" }, 516 { MII_INTR_MASK, "intr_mask" }, 517 { MII_HCD_STATUS, "hcd_status" }, 518 { EEE_MODE_REG, "eee" }, 519 520 { -1, NULL } 521 }; 522 523 static int 524 bge_phydata_update(kstat_t *ksp, int flag) 525 { 526 bge_t *bgep; 527 kstat_named_t *knp; 528 const bge_ksindex_t *ksip; 529 530 if (flag != KSTAT_READ) 531 return (EACCES); 532 533 bgep = ksp->ks_private; 534 if (bgep->bge_chip_state == BGE_CHIP_FAULT) 535 return (EIO); 536 537 knp = ksp->ks_data; 538 539 /* 540 * Read the PHY registers & update the kstats ... 541 * 542 * We need to hold the mutex while performing MII reads, but 543 * we don't want to hold it across the entire sequence of reads. 544 * So we grab and release it on each iteration, 'cos it doesn't 545 * really matter if the kstats are less than 100% consistent ... 546 */ 547 for (ksip = bge_phydata; ksip->name != NULL; ++knp, ++ksip) { 548 mutex_enter(bgep->genlock); 549 switch (ksip->index) { 550 case MII_STATUS: 551 knp->value.ui64 = bgep->phy_gen_status; 552 break; 553 554 case MII_PHYIDH: 555 knp->value.ui64 = bge_mii_get16(bgep, MII_PHYIDH); 556 knp->value.ui64 <<= 16; 557 knp->value.ui64 |= bge_mii_get16(bgep, MII_PHYIDL); 558 break; 559 560 case EEE_MODE_REG: 561 knp->value.ui64 = 0; 562 if (bgep->link_state == LINK_STATE_UP) 563 { 564 knp->value.ui64 = 565 (bge_reg_get32(bgep, EEE_MODE_REG) & 0x80) ? 566 1 : 0; 567 } 568 break; 569 570 default: 571 knp->value.ui64 = bge_mii_get16(bgep, ksip->index); 572 break; 573 } 574 if (bge_check_acc_handle(bgep, bgep->io_handle) != DDI_FM_OK) { 575 ddi_fm_service_impact(bgep->devinfo, 576 DDI_SERVICE_DEGRADED); 577 mutex_exit(bgep->genlock); 578 return (EIO); 579 } 580 mutex_exit(bgep->genlock); 581 } 582 583 return (0); 584 } 585 586 static kstat_t * 587 bge_setup_named_kstat(bge_t *bgep, int instance, char *name, 588 const bge_ksindex_t *ksip, size_t size, int (*update)(kstat_t *, int)) 589 { 590 kstat_t *ksp; 591 kstat_named_t *knp; 592 char *np; 593 int type; 594 595 size /= sizeof (bge_ksindex_t); 596 ksp = kstat_create(BGE_DRIVER_NAME, instance, name, "net", 597 KSTAT_TYPE_NAMED, size-1, 0); 598 if (ksp == NULL) 599 return (NULL); 600 601 ksp->ks_private = bgep; 602 ksp->ks_update = update; 603 for (knp = ksp->ks_data; (np = ksip->name) != NULL; ++knp, ++ksip) { 604 switch (*np) { 605 default: 606 type = KSTAT_DATA_UINT64; 607 break; 608 case '%': 609 np += 1; 610 type = KSTAT_DATA_UINT32; 611 break; 612 case '$': 613 np += 1; 614 type = KSTAT_DATA_STRING; 615 break; 616 case '&': 617 np += 1; 618 type = KSTAT_DATA_CHAR; 619 break; 620 } 621 kstat_named_init(knp, np, type); 622 } 623 kstat_install(ksp); 624 625 return (ksp); 626 } 627 628 void 629 bge_init_kstats(bge_t *bgep, int instance) 630 { 631 kstat_t *ksp; 632 633 BGE_TRACE(("bge_init_kstats($%p, %d)", (void *)bgep, instance)); 634 635 if (bgep->chipid.statistic_type == BGE_STAT_BLK) { 636 DMA_ZERO(bgep->statistics); 637 bgep->bge_kstats[BGE_KSTAT_RAW] = ksp = 638 kstat_create(BGE_DRIVER_NAME, instance, 639 "raw_statistics", "net", KSTAT_TYPE_RAW, 640 sizeof (bge_statistics_t), KSTAT_FLAG_VIRTUAL); 641 if (ksp != NULL) { 642 ksp->ks_data = DMA_VPTR(bgep->statistics); 643 kstat_install(ksp); 644 } 645 646 bgep->bge_kstats[BGE_KSTAT_STATS] = bge_setup_named_kstat(bgep, 647 instance, "statistics", bge_statistics, 648 sizeof (bge_statistics), bge_statistics_update); 649 } else { 650 bgep->bge_kstats[BGE_KSTAT_STATS] = bge_setup_named_kstat(bgep, 651 instance, "statistics", bge_stat_val, 652 sizeof (bge_stat_val), bge_statistics_update); 653 } 654 655 bgep->bge_kstats[BGE_KSTAT_CHIPID] = bge_setup_named_kstat(bgep, 656 instance, "chipid", bge_chipid, 657 sizeof (bge_chipid), bge_chipid_update); 658 659 bgep->bge_kstats[BGE_KSTAT_DRIVER] = bge_setup_named_kstat(bgep, 660 instance, "driverinfo", bge_driverinfo, 661 sizeof (bge_driverinfo), bge_driverinfo_update); 662 663 if (bgep->chipid.flags & CHIP_FLAG_SERDES) 664 bgep->bge_kstats[BGE_KSTAT_PHYS] = bge_setup_named_kstat(bgep, 665 instance, "serdes", bge_serdes, 666 sizeof (bge_serdes), bge_serdes_update); 667 else 668 bgep->bge_kstats[BGE_KSTAT_PHYS] = bge_setup_named_kstat(bgep, 669 instance, "phydata", bge_phydata, 670 sizeof (bge_phydata), bge_phydata_update); 671 672 } 673 674 void 675 bge_fini_kstats(bge_t *bgep) 676 { 677 int i; 678 679 BGE_TRACE(("bge_fini_kstats($%p)", (void *)bgep)); 680 681 for (i = BGE_KSTAT_COUNT; --i >= 0; ) 682 if (bgep->bge_kstats[i] != NULL) 683 kstat_delete(bgep->bge_kstats[i]); 684 } 685 686 int 687 bge_m_stat(void *arg, uint_t stat, uint64_t *val) 688 { 689 bge_t *bgep = arg; 690 bge_statistics_t *bstp; 691 bge_statistics_reg_t *pstats; 692 693 if (bgep->bge_chip_state != BGE_CHIP_RUNNING) { 694 return (EINVAL); 695 } 696 697 if (bgep->chipid.statistic_type == BGE_STAT_BLK) 698 bstp = DMA_VPTR(bgep->statistics); 699 else { 700 pstats = bgep->pstats; 701 pstats->ifHCOutOctets += 702 bge_reg_get32(bgep, STAT_IFHCOUT_OCTETS_REG); 703 pstats->etherStatsCollisions += 704 bge_reg_get32(bgep, STAT_ETHER_COLLIS_REG); 705 pstats->outXonSent += 706 bge_reg_get32(bgep, STAT_OUTXON_SENT_REG); 707 pstats->outXoffSent += 708 bge_reg_get32(bgep, STAT_OUTXOFF_SENT_REG); 709 pstats->dot3StatsInternalMacTransmitErrors += 710 bge_reg_get32(bgep, STAT_DOT3_INTMACTX_ERR_REG); 711 pstats->dot3StatsSingleCollisionFrames += 712 bge_reg_get32(bgep, STAT_DOT3_SCOLLI_FRAME_REG); 713 pstats->dot3StatsMultipleCollisionFrames += 714 bge_reg_get32(bgep, STAT_DOT3_MCOLLI_FRAME_REG); 715 pstats->dot3StatsDeferredTransmissions += 716 bge_reg_get32(bgep, STAT_DOT3_DEFERED_TX_REG); 717 pstats->dot3StatsExcessiveCollisions += 718 bge_reg_get32(bgep, STAT_DOT3_EXCE_COLLI_REG); 719 pstats->dot3StatsLateCollisions += 720 bge_reg_get32(bgep, STAT_DOT3_LATE_COLLI_REG); 721 pstats->ifHCOutUcastPkts += 722 bge_reg_get32(bgep, STAT_IFHCOUT_UPKGS_REG); 723 pstats->ifHCOutMulticastPkts += 724 bge_reg_get32(bgep, STAT_IFHCOUT_MPKGS_REG); 725 pstats->ifHCOutBroadcastPkts += 726 bge_reg_get32(bgep, STAT_IFHCOUT_BPKGS_REG); 727 pstats->ifHCInOctets += 728 bge_reg_get32(bgep, STAT_IFHCIN_OCTETS_REG); 729 pstats->etherStatsFragments += 730 bge_reg_get32(bgep, STAT_ETHER_FRAGMENT_REG); 731 pstats->ifHCInUcastPkts += 732 bge_reg_get32(bgep, STAT_IFHCIN_UPKGS_REG); 733 pstats->ifHCInMulticastPkts += 734 bge_reg_get32(bgep, STAT_IFHCIN_MPKGS_REG); 735 pstats->ifHCInBroadcastPkts += 736 bge_reg_get32(bgep, STAT_IFHCIN_BPKGS_REG); 737 pstats->dot3StatsFCSErrors += 738 bge_reg_get32(bgep, STAT_DOT3_FCS_ERR_REG); 739 pstats->dot3StatsAlignmentErrors += 740 bge_reg_get32(bgep, STAT_DOT3_ALIGN_ERR_REG); 741 pstats->xonPauseFramesReceived += 742 bge_reg_get32(bgep, STAT_XON_PAUSE_RX_REG); 743 pstats->xoffPauseFramesReceived += 744 bge_reg_get32(bgep, STAT_XOFF_PAUSE_RX_REG); 745 pstats->macControlFramesReceived += 746 bge_reg_get32(bgep, STAT_MAC_CTRL_RX_REG); 747 pstats->xoffStateEntered += 748 bge_reg_get32(bgep, STAT_XOFF_STATE_ENTER_REG); 749 pstats->dot3StatsFrameTooLongs += 750 bge_reg_get32(bgep, STAT_DOT3_FRAME_TOOLONG_REG); 751 pstats->etherStatsJabbers += 752 bge_reg_get32(bgep, STAT_ETHER_JABBERS_REG); 753 pstats->etherStatsUndersizePkts += 754 bge_reg_get32(bgep, STAT_ETHER_UNDERSIZE_REG); 755 mutex_enter(bgep->genlock); 756 if (bge_check_acc_handle(bgep, bgep->io_handle) != DDI_FM_OK) { 757 ddi_fm_service_impact(bgep->devinfo, 758 DDI_SERVICE_UNAFFECTED); 759 } 760 mutex_exit(bgep->genlock); 761 } 762 763 switch (stat) { 764 case MAC_STAT_IFSPEED: 765 *val = (bgep->link_state != LINK_STATE_UNKNOWN) ? 766 (bgep->param_link_speed * 1000000ull) : 0; 767 break; 768 769 case MAC_STAT_MULTIRCV: 770 if (bgep->chipid.statistic_type == BGE_STAT_BLK) 771 *val = bstp->s.ifHCInMulticastPkts; 772 else 773 *val = pstats->ifHCInMulticastPkts; 774 break; 775 776 case MAC_STAT_BRDCSTRCV: 777 if (bgep->chipid.statistic_type == BGE_STAT_BLK) 778 *val = bstp->s.ifHCInBroadcastPkts; 779 else 780 *val = pstats->ifHCInBroadcastPkts; 781 break; 782 783 case MAC_STAT_MULTIXMT: 784 if (bgep->chipid.statistic_type == BGE_STAT_BLK) 785 *val = bstp->s.ifHCOutMulticastPkts; 786 else 787 *val = pstats->ifHCOutMulticastPkts; 788 break; 789 790 case MAC_STAT_BRDCSTXMT: 791 if (bgep->chipid.statistic_type == BGE_STAT_BLK) 792 *val = bstp->s.ifHCOutBroadcastPkts; 793 else 794 *val = pstats->ifHCOutBroadcastPkts; 795 break; 796 797 case MAC_STAT_NORCVBUF: 798 if (bgep->chipid.statistic_type == BGE_STAT_BLK) 799 *val = bstp->s.ifInDiscards; 800 else 801 *val = 0; 802 break; 803 804 case MAC_STAT_IERRORS: 805 if (bgep->chipid.statistic_type == BGE_STAT_BLK) { 806 *val = bstp->s.dot3StatsFCSErrors + 807 bstp->s.dot3StatsAlignmentErrors + 808 bstp->s.dot3StatsFrameTooLongs + 809 bstp->s.etherStatsUndersizePkts + 810 bstp->s.etherStatsJabbers; 811 } else { 812 *val = pstats->dot3StatsFCSErrors + 813 pstats->dot3StatsAlignmentErrors + 814 pstats->dot3StatsFrameTooLongs + 815 pstats->etherStatsUndersizePkts + 816 pstats->etherStatsJabbers; 817 } 818 break; 819 820 case MAC_STAT_NOXMTBUF: 821 if (bgep->chipid.statistic_type == BGE_STAT_BLK) 822 *val = bstp->s.ifOutDiscards; 823 else 824 *val = 0; 825 break; 826 827 case MAC_STAT_OERRORS: 828 if (bgep->chipid.statistic_type == BGE_STAT_BLK) 829 *val = bstp->s.ifOutDiscards; 830 else 831 *val = 0; 832 break; 833 834 case MAC_STAT_COLLISIONS: 835 if (bgep->chipid.statistic_type == BGE_STAT_BLK) 836 *val = bstp->s.etherStatsCollisions; 837 else 838 *val = pstats->etherStatsCollisions; 839 break; 840 841 case MAC_STAT_RBYTES: 842 if (bgep->chipid.statistic_type == BGE_STAT_BLK) 843 *val = bstp->s.ifHCInOctets; 844 else 845 *val = pstats->ifHCInOctets; 846 break; 847 848 case MAC_STAT_IPACKETS: 849 if (bgep->chipid.statistic_type == BGE_STAT_BLK) 850 *val = bstp->s.ifHCInUcastPkts + 851 bstp->s.ifHCInMulticastPkts + 852 bstp->s.ifHCInBroadcastPkts; 853 else 854 *val = pstats->ifHCInUcastPkts + 855 pstats->ifHCInMulticastPkts + 856 pstats->ifHCInBroadcastPkts; 857 break; 858 859 case MAC_STAT_OBYTES: 860 if (bgep->chipid.statistic_type == BGE_STAT_BLK) 861 *val = bstp->s.ifHCOutOctets; 862 else 863 *val = pstats->ifHCOutOctets; 864 break; 865 866 case MAC_STAT_OPACKETS: 867 if (bgep->chipid.statistic_type == BGE_STAT_BLK) 868 *val = bstp->s.ifHCOutUcastPkts + 869 bstp->s.ifHCOutMulticastPkts + 870 bstp->s.ifHCOutBroadcastPkts; 871 else 872 *val = pstats->ifHCOutUcastPkts + 873 pstats->ifHCOutMulticastPkts + 874 pstats->ifHCOutBroadcastPkts; 875 break; 876 877 case ETHER_STAT_ALIGN_ERRORS: 878 if (bgep->chipid.statistic_type == BGE_STAT_BLK) 879 *val = bstp->s.dot3StatsAlignmentErrors; 880 else 881 *val = pstats->dot3StatsAlignmentErrors; 882 break; 883 884 case ETHER_STAT_FCS_ERRORS: 885 if (bgep->chipid.statistic_type == BGE_STAT_BLK) 886 *val = bstp->s.dot3StatsFCSErrors; 887 else 888 *val = pstats->dot3StatsFCSErrors; 889 break; 890 891 case ETHER_STAT_FIRST_COLLISIONS: 892 if (bgep->chipid.statistic_type == BGE_STAT_BLK) 893 *val = bstp->s.dot3StatsSingleCollisionFrames; 894 else 895 *val = pstats->dot3StatsSingleCollisionFrames; 896 break; 897 898 case ETHER_STAT_MULTI_COLLISIONS: 899 if (bgep->chipid.statistic_type == BGE_STAT_BLK) 900 *val = bstp->s.dot3StatsMultipleCollisionFrames; 901 else 902 *val = pstats->dot3StatsMultipleCollisionFrames; 903 break; 904 905 case ETHER_STAT_DEFER_XMTS: 906 if (bgep->chipid.statistic_type == BGE_STAT_BLK) 907 *val = bstp->s.dot3StatsDeferredTransmissions; 908 else 909 *val = pstats->dot3StatsDeferredTransmissions; 910 break; 911 912 case ETHER_STAT_TX_LATE_COLLISIONS: 913 if (bgep->chipid.statistic_type == BGE_STAT_BLK) 914 *val = bstp->s.dot3StatsLateCollisions; 915 else 916 *val = pstats->dot3StatsLateCollisions; 917 break; 918 919 case ETHER_STAT_EX_COLLISIONS: 920 if (bgep->chipid.statistic_type == BGE_STAT_BLK) 921 *val = bstp->s.dot3StatsExcessiveCollisions; 922 else 923 *val = pstats->dot3StatsExcessiveCollisions; 924 break; 925 926 case ETHER_STAT_MACXMT_ERRORS: 927 if (bgep->chipid.statistic_type == BGE_STAT_BLK) 928 *val = bstp->s.dot3StatsInternalMacTransmitErrors; 929 else 930 *val = bgep->pstats->dot3StatsInternalMacTransmitErrors; 931 break; 932 933 case ETHER_STAT_CARRIER_ERRORS: 934 if (bgep->chipid.statistic_type == BGE_STAT_BLK) 935 *val = bstp->s.dot3StatsCarrierSenseErrors; 936 else 937 *val = 0; 938 break; 939 940 case ETHER_STAT_TOOLONG_ERRORS: 941 if (bgep->chipid.statistic_type == BGE_STAT_BLK) 942 *val = bstp->s.dot3StatsFrameTooLongs; 943 else 944 *val = pstats->dot3StatsFrameTooLongs; 945 break; 946 947 #if (MAC_VERSION > 1) 948 case ETHER_STAT_TOOSHORT_ERRORS: 949 if (bgep->chipid.statistic_type == BGE_STAT_BLK) 950 *val = bstp->s.etherStatsUndersizePkts; 951 else 952 *val = pstats->etherStatsUndersizePkts; 953 break; 954 #endif 955 956 case ETHER_STAT_XCVR_ADDR: 957 *val = bgep->phy_mii_addr; 958 break; 959 960 case ETHER_STAT_XCVR_ID: 961 mutex_enter(bgep->genlock); 962 *val = bge_mii_get16(bgep, MII_PHYIDH); 963 *val <<= 16; 964 *val |= bge_mii_get16(bgep, MII_PHYIDL); 965 if (bge_check_acc_handle(bgep, bgep->io_handle) != DDI_FM_OK) { 966 ddi_fm_service_impact(bgep->devinfo, 967 DDI_SERVICE_UNAFFECTED); 968 } 969 mutex_exit(bgep->genlock); 970 break; 971 972 case ETHER_STAT_XCVR_INUSE: 973 *val = (uint64_t)bge_phys_media(bgep); 974 break; 975 976 case ETHER_STAT_CAP_1000FDX: 977 *val = 1; 978 break; 979 980 case ETHER_STAT_CAP_1000HDX: 981 *val = 1; 982 break; 983 984 case ETHER_STAT_CAP_100FDX: 985 if (bgep->chipid.flags & CHIP_FLAG_SERDES) 986 *val = 0; 987 else 988 *val = 1; 989 break; 990 991 case ETHER_STAT_CAP_100HDX: 992 if (bgep->chipid.flags & CHIP_FLAG_SERDES) 993 *val = 0; 994 else 995 *val = 1; 996 break; 997 998 case ETHER_STAT_CAP_10FDX: 999 if (bgep->chipid.flags & CHIP_FLAG_SERDES) 1000 *val = 0; 1001 else 1002 *val = 1; 1003 break; 1004 1005 case ETHER_STAT_CAP_10HDX: 1006 if (bgep->chipid.flags & CHIP_FLAG_SERDES) 1007 *val = 0; 1008 else 1009 *val = 1; 1010 break; 1011 1012 case ETHER_STAT_CAP_ASMPAUSE: 1013 *val = 1; 1014 break; 1015 1016 case ETHER_STAT_CAP_PAUSE: 1017 *val = 1; 1018 break; 1019 1020 case ETHER_STAT_CAP_AUTONEG: 1021 *val = 1; 1022 break; 1023 1024 #if (MAC_VERSION > 1) 1025 case ETHER_STAT_CAP_REMFAULT: 1026 *val = 1; 1027 break; 1028 #endif 1029 1030 case ETHER_STAT_ADV_CAP_1000FDX: 1031 *val = bgep->param_adv_1000fdx; 1032 break; 1033 1034 case ETHER_STAT_ADV_CAP_1000HDX: 1035 *val = bgep->param_adv_1000hdx; 1036 break; 1037 1038 case ETHER_STAT_ADV_CAP_100FDX: 1039 *val = bgep->param_adv_100fdx; 1040 break; 1041 1042 case ETHER_STAT_ADV_CAP_100HDX: 1043 *val = bgep->param_adv_100hdx; 1044 break; 1045 1046 case ETHER_STAT_ADV_CAP_10FDX: 1047 *val = bgep->param_adv_10fdx; 1048 break; 1049 1050 case ETHER_STAT_ADV_CAP_10HDX: 1051 *val = bgep->param_adv_10hdx; 1052 break; 1053 1054 case ETHER_STAT_ADV_CAP_ASMPAUSE: 1055 *val = bgep->param_adv_asym_pause; 1056 break; 1057 1058 case ETHER_STAT_ADV_CAP_PAUSE: 1059 *val = bgep->param_adv_pause; 1060 break; 1061 1062 case ETHER_STAT_ADV_CAP_AUTONEG: 1063 *val = bgep->param_adv_autoneg; 1064 break; 1065 1066 #if (MAC_VERSION > 1) 1067 case ETHER_STAT_ADV_REMFAULT: 1068 if (bgep->chipid.flags & CHIP_FLAG_SERDES) 1069 *val = 0; 1070 else { 1071 mutex_enter(bgep->genlock); 1072 *val = bge_mii_get16(bgep, MII_AN_ADVERT) & 1073 MII_AN_ADVERT_REMFAULT ? 1 : 0; 1074 if (bge_check_acc_handle(bgep, bgep->io_handle) != 1075 DDI_FM_OK) { 1076 ddi_fm_service_impact(bgep->devinfo, 1077 DDI_SERVICE_UNAFFECTED); 1078 } 1079 mutex_exit(bgep->genlock); 1080 } 1081 break; 1082 #endif 1083 1084 case ETHER_STAT_LP_CAP_1000FDX: 1085 *val = bgep->param_lp_1000fdx; 1086 break; 1087 1088 case ETHER_STAT_LP_CAP_1000HDX: 1089 *val = bgep->param_lp_1000hdx; 1090 break; 1091 1092 case ETHER_STAT_LP_CAP_100FDX: 1093 *val = bgep->param_lp_100fdx; 1094 break; 1095 1096 case ETHER_STAT_LP_CAP_100HDX: 1097 *val = bgep->param_lp_100hdx; 1098 break; 1099 1100 case ETHER_STAT_LP_CAP_10FDX: 1101 *val = bgep->param_lp_10fdx; 1102 break; 1103 1104 case ETHER_STAT_LP_CAP_10HDX: 1105 *val = bgep->param_lp_10hdx; 1106 break; 1107 1108 case ETHER_STAT_LP_CAP_ASMPAUSE: 1109 *val = bgep->param_lp_asym_pause; 1110 break; 1111 1112 case ETHER_STAT_LP_CAP_PAUSE: 1113 *val = bgep->param_lp_pause; 1114 break; 1115 1116 case ETHER_STAT_LP_CAP_AUTONEG: 1117 *val = bgep->param_lp_autoneg; 1118 break; 1119 1120 #if (MAC_VERSION > 1) 1121 case ETHER_STAT_LP_REMFAULT: 1122 if (bgep->chipid.flags & CHIP_FLAG_SERDES) 1123 *val = 0; 1124 else { 1125 mutex_enter(bgep->genlock); 1126 *val = bge_mii_get16(bgep, MII_AN_LPABLE) & 1127 MII_AN_ADVERT_REMFAULT ? 1 : 0; 1128 if (bge_check_acc_handle(bgep, bgep->io_handle) != 1129 DDI_FM_OK) { 1130 ddi_fm_service_impact(bgep->devinfo, 1131 DDI_SERVICE_UNAFFECTED); 1132 } 1133 mutex_exit(bgep->genlock); 1134 } 1135 break; 1136 #endif 1137 1138 case ETHER_STAT_LINK_ASMPAUSE: 1139 *val = bgep->param_adv_asym_pause && 1140 bgep->param_lp_asym_pause && 1141 bgep->param_adv_pause != bgep->param_lp_pause; 1142 break; 1143 1144 case ETHER_STAT_LINK_PAUSE: 1145 *val = bgep->param_link_rx_pause; 1146 break; 1147 1148 case ETHER_STAT_LINK_AUTONEG: 1149 *val = bgep->param_link_autoneg; 1150 break; 1151 1152 case ETHER_STAT_LINK_DUPLEX: 1153 *val = (bgep->link_state != LINK_STATE_UNKNOWN) ? 1154 bgep->param_link_duplex : LINK_DUPLEX_UNKNOWN; 1155 break; 1156 1157 default: 1158 return (ENOTSUP); 1159 } 1160 1161 return (0); 1162 } 1163 1164 /* 1165 * Retrieve a value for one of the statistics for a particular rx ring 1166 */ 1167 int 1168 bge_rx_ring_stat(mac_ring_driver_t rh, uint_t stat, uint64_t *val) 1169 { 1170 recv_ring_t *rx_ring = (recv_ring_t *)rh; 1171 1172 switch (stat) { 1173 case MAC_STAT_RBYTES: 1174 *val = rx_ring->rx_bytes; 1175 break; 1176 1177 case MAC_STAT_IPACKETS: 1178 *val = rx_ring->rx_pkts; 1179 break; 1180 1181 default: 1182 *val = 0; 1183 return (ENOTSUP); 1184 } 1185 1186 return (0); 1187 } 1188