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