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