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 "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 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 if (bgep->bge_chip_state == BGE_CHIP_FAULT) { 899 return (EINVAL); 900 } 901 902 /* 903 * The MII/GMII physical layer 802.3 stats are not supported by the 904 * bge optical interface. 905 */ 906 if ((bgep->chipid.flags & CHIP_FLAG_SERDES) && ETHER_STAT_ISMII(stat)) { 907 return (ENOTSUP); 908 } 909 910 if (bgep->chipid.statistic_type == BGE_STAT_BLK) 911 bstp = DMA_VPTR(bgep->statistics); 912 else { 913 bgep->stat_val.ifHCOutOctets += 914 bge_reg_get32(bgep, STAT_IFHCOUT_OCTETS_REG); 915 bgep->stat_val.etherStatsCollisions += 916 bge_reg_get32(bgep, STAT_ETHER_COLLIS_REG); 917 bgep->stat_val.outXonSent += 918 bge_reg_get32(bgep, STAT_OUTXON_SENT_REG); 919 bgep->stat_val.outXoffSent += 920 bge_reg_get32(bgep, STAT_OUTXOFF_SENT_REG); 921 bgep->stat_val.dot3StatsInternalMacTransmitErrors += 922 bge_reg_get32(bgep, STAT_DOT3_INTMACTX_ERR_REG); 923 bgep->stat_val.dot3StatsSingleCollisionFrames += 924 bge_reg_get32(bgep, STAT_DOT3_SCOLLI_FRAME_REG); 925 bgep->stat_val.dot3StatsMultipleCollisionFrames += 926 bge_reg_get32(bgep, STAT_DOT3_MCOLLI_FRAME_REG); 927 bgep->stat_val.dot3StatsDeferredTransmissions += 928 bge_reg_get32(bgep, STAT_DOT3_DEFERED_TX_REG); 929 bgep->stat_val.dot3StatsExcessiveCollisions += 930 bge_reg_get32(bgep, STAT_DOT3_EXCE_COLLI_REG); 931 bgep->stat_val.dot3StatsLateCollisions += 932 bge_reg_get32(bgep, STAT_DOT3_LATE_COLLI_REG); 933 bgep->stat_val.ifHCOutUcastPkts += 934 bge_reg_get32(bgep, STAT_IFHCOUT_UPKGS_REG); 935 bgep->stat_val.ifHCOutMulticastPkts += 936 bge_reg_get32(bgep, STAT_IFHCOUT_MPKGS_REG); 937 bgep->stat_val.ifHCOutBroadcastPkts += 938 bge_reg_get32(bgep, STAT_IFHCOUT_BPKGS_REG); 939 bgep->stat_val.ifHCInOctets += 940 bge_reg_get32(bgep, STAT_IFHCIN_OCTETS_REG); 941 bgep->stat_val.etherStatsFragments += 942 bge_reg_get32(bgep, STAT_ETHER_FRAGMENT_REG); 943 bgep->stat_val.ifHCInUcastPkts += 944 bge_reg_get32(bgep, STAT_IFHCIN_UPKGS_REG); 945 bgep->stat_val.ifHCInMulticastPkts += 946 bge_reg_get32(bgep, STAT_IFHCIN_MPKGS_REG); 947 bgep->stat_val.ifHCInBroadcastPkts += 948 bge_reg_get32(bgep, STAT_IFHCIN_BPKGS_REG); 949 bgep->stat_val.dot3StatsFCSErrors += 950 bge_reg_get32(bgep, STAT_DOT3_FCS_ERR_REG); 951 bgep->stat_val.dot3StatsAlignmentErrors += 952 bge_reg_get32(bgep, STAT_DOT3_ALIGN_ERR_REG); 953 bgep->stat_val.xonPauseFramesReceived += 954 bge_reg_get32(bgep, STAT_XON_PAUSE_RX_REG); 955 bgep->stat_val.xoffPauseFramesReceived += 956 bge_reg_get32(bgep, STAT_XOFF_PAUSE_RX_REG); 957 bgep->stat_val.macControlFramesReceived += 958 bge_reg_get32(bgep, STAT_MAC_CTRL_RX_REG); 959 bgep->stat_val.xoffStateEntered += 960 bge_reg_get32(bgep, STAT_XOFF_STATE_ENTER_REG); 961 bgep->stat_val.dot3StatsFrameTooLongs += 962 bge_reg_get32(bgep, STAT_DOT3_FRAME_TOOLONG_REG); 963 bgep->stat_val.etherStatsJabbers += 964 bge_reg_get32(bgep, STAT_ETHER_JABBERS_REG); 965 bgep->stat_val.etherStatsUndersizePkts += 966 bge_reg_get32(bgep, STAT_ETHER_UNDERSIZE_REG); 967 mutex_enter(bgep->genlock); 968 if (bge_check_acc_handle(bgep, bgep->io_handle) != DDI_FM_OK) { 969 ddi_fm_service_impact(bgep->devinfo, 970 DDI_SERVICE_UNAFFECTED); 971 } 972 mutex_exit(bgep->genlock); 973 } 974 975 switch (stat) { 976 case MAC_STAT_IFSPEED: 977 *val = bgep->param_link_speed * 1000000ull; 978 break; 979 980 case MAC_STAT_MULTIRCV: 981 if (bgep->chipid.statistic_type == BGE_STAT_BLK) 982 *val = bstp->s.ifHCInMulticastPkts; 983 else 984 *val = bgep->stat_val.ifHCInMulticastPkts; 985 break; 986 987 case MAC_STAT_BRDCSTRCV: 988 if (bgep->chipid.statistic_type == BGE_STAT_BLK) 989 *val = bstp->s.ifHCInBroadcastPkts; 990 else 991 *val = bgep->stat_val.ifHCInBroadcastPkts; 992 break; 993 994 case MAC_STAT_MULTIXMT: 995 if (bgep->chipid.statistic_type == BGE_STAT_BLK) 996 *val = bstp->s.ifHCOutMulticastPkts; 997 else 998 *val = bgep->stat_val.ifHCOutMulticastPkts; 999 break; 1000 1001 case MAC_STAT_BRDCSTXMT: 1002 if (bgep->chipid.statistic_type == BGE_STAT_BLK) 1003 *val = bstp->s.ifHCOutBroadcastPkts; 1004 else 1005 *val = bgep->stat_val.ifHCOutBroadcastPkts; 1006 break; 1007 1008 case MAC_STAT_NORCVBUF: 1009 if (bgep->chipid.statistic_type == BGE_STAT_BLK) 1010 *val = bstp->s.ifInDiscards; 1011 else 1012 *val = 0; 1013 break; 1014 1015 case MAC_STAT_IERRORS: 1016 if (bgep->chipid.statistic_type == BGE_STAT_BLK) { 1017 *val = bstp->s.dot3StatsFCSErrors + 1018 bstp->s.dot3StatsAlignmentErrors + 1019 bstp->s.dot3StatsFrameTooLongs + 1020 bstp->s.etherStatsUndersizePkts + 1021 bstp->s.etherStatsJabbers; 1022 } else { 1023 *val = bgep->stat_val.dot3StatsFCSErrors + 1024 bgep->stat_val.dot3StatsAlignmentErrors + 1025 bgep->stat_val.dot3StatsFrameTooLongs + 1026 bgep->stat_val.etherStatsUndersizePkts + 1027 bgep->stat_val.etherStatsJabbers; 1028 } 1029 break; 1030 1031 case MAC_STAT_NOXMTBUF: 1032 if (bgep->chipid.statistic_type == BGE_STAT_BLK) 1033 *val = bstp->s.ifOutDiscards; 1034 else 1035 *val = 0; 1036 break; 1037 1038 case MAC_STAT_OERRORS: 1039 if (bgep->chipid.statistic_type == BGE_STAT_BLK) 1040 *val = bstp->s.ifOutDiscards; 1041 else 1042 *val = 0; 1043 break; 1044 1045 case MAC_STAT_COLLISIONS: 1046 if (bgep->chipid.statistic_type == BGE_STAT_BLK) 1047 *val = bstp->s.etherStatsCollisions; 1048 else 1049 *val = bgep->stat_val.etherStatsCollisions; 1050 break; 1051 1052 case MAC_STAT_RBYTES: 1053 if (bgep->chipid.statistic_type == BGE_STAT_BLK) 1054 *val = bstp->s.ifHCInOctets; 1055 else 1056 *val = bgep->stat_val.ifHCInOctets; 1057 break; 1058 1059 case MAC_STAT_IPACKETS: 1060 if (bgep->chipid.statistic_type == BGE_STAT_BLK) 1061 *val = bstp->s.ifHCInUcastPkts + 1062 bstp->s.ifHCInMulticastPkts + 1063 bstp->s.ifHCInBroadcastPkts; 1064 else 1065 *val = bgep->stat_val.ifHCInUcastPkts + 1066 bgep->stat_val.ifHCInMulticastPkts + 1067 bgep->stat_val.ifHCInBroadcastPkts; 1068 break; 1069 1070 case MAC_STAT_OBYTES: 1071 if (bgep->chipid.statistic_type == BGE_STAT_BLK) 1072 *val = bstp->s.ifHCOutOctets; 1073 else 1074 *val = bgep->stat_val.ifHCOutOctets; 1075 break; 1076 1077 case MAC_STAT_OPACKETS: 1078 if (bgep->chipid.statistic_type == BGE_STAT_BLK) 1079 *val = bstp->s.ifHCOutUcastPkts + 1080 bstp->s.ifHCOutMulticastPkts + 1081 bstp->s.ifHCOutBroadcastPkts; 1082 else 1083 *val = bgep->stat_val.ifHCOutUcastPkts + 1084 bgep->stat_val.ifHCOutMulticastPkts + 1085 bgep->stat_val.ifHCOutBroadcastPkts; 1086 break; 1087 1088 case ETHER_STAT_ALIGN_ERRORS: 1089 if (bgep->chipid.statistic_type == BGE_STAT_BLK) 1090 *val = bstp->s.dot3StatsAlignmentErrors; 1091 else 1092 *val = bgep->stat_val.dot3StatsAlignmentErrors; 1093 break; 1094 1095 case ETHER_STAT_FCS_ERRORS: 1096 if (bgep->chipid.statistic_type == BGE_STAT_BLK) 1097 *val = bstp->s.dot3StatsFCSErrors; 1098 else 1099 *val = bgep->stat_val.dot3StatsFCSErrors; 1100 break; 1101 1102 case ETHER_STAT_FIRST_COLLISIONS: 1103 if (bgep->chipid.statistic_type == BGE_STAT_BLK) 1104 *val = bstp->s.dot3StatsSingleCollisionFrames; 1105 else 1106 *val = bgep->stat_val.dot3StatsSingleCollisionFrames; 1107 break; 1108 1109 case ETHER_STAT_MULTI_COLLISIONS: 1110 if (bgep->chipid.statistic_type == BGE_STAT_BLK) 1111 *val = bstp->s.dot3StatsMultipleCollisionFrames; 1112 else 1113 *val = bgep->stat_val.dot3StatsMultipleCollisionFrames; 1114 break; 1115 1116 case ETHER_STAT_DEFER_XMTS: 1117 if (bgep->chipid.statistic_type == BGE_STAT_BLK) 1118 *val = bstp->s.dot3StatsDeferredTransmissions; 1119 else 1120 *val = bgep->stat_val.dot3StatsDeferredTransmissions; 1121 break; 1122 1123 case ETHER_STAT_TX_LATE_COLLISIONS: 1124 if (bgep->chipid.statistic_type == BGE_STAT_BLK) 1125 *val = bstp->s.dot3StatsLateCollisions; 1126 else 1127 *val = bgep->stat_val.dot3StatsLateCollisions; 1128 break; 1129 1130 case ETHER_STAT_EX_COLLISIONS: 1131 if (bgep->chipid.statistic_type == BGE_STAT_BLK) 1132 *val = bstp->s.dot3StatsExcessiveCollisions; 1133 else 1134 *val = bgep->stat_val.dot3StatsExcessiveCollisions; 1135 break; 1136 1137 case ETHER_STAT_MACXMT_ERRORS: 1138 if (bgep->chipid.statistic_type == BGE_STAT_BLK) 1139 *val = bstp->s.dot3StatsInternalMacTransmitErrors; 1140 else 1141 *val = bgep-> 1142 stat_val.dot3StatsInternalMacTransmitErrors; 1143 break; 1144 1145 case ETHER_STAT_CARRIER_ERRORS: 1146 if (bgep->chipid.statistic_type == BGE_STAT_BLK) 1147 *val = bstp->s.dot3StatsCarrierSenseErrors; 1148 else 1149 *val = 0; 1150 break; 1151 1152 case ETHER_STAT_TOOLONG_ERRORS: 1153 if (bgep->chipid.statistic_type == BGE_STAT_BLK) 1154 *val = bstp->s.dot3StatsFrameTooLongs; 1155 else 1156 *val = bgep->stat_val.dot3StatsFrameTooLongs; 1157 break; 1158 1159 case ETHER_STAT_XCVR_ADDR: 1160 *val = bgep->phy_mii_addr; 1161 break; 1162 1163 case ETHER_STAT_XCVR_ID: 1164 mutex_enter(bgep->genlock); 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 mutex_exit(bgep->genlock); 1173 break; 1174 1175 case ETHER_STAT_XCVR_INUSE: 1176 *val = XCVR_1000T; 1177 break; 1178 1179 case ETHER_STAT_CAP_1000FDX: 1180 *val = 1; 1181 break; 1182 1183 case ETHER_STAT_CAP_1000HDX: 1184 *val = 1; 1185 break; 1186 1187 case ETHER_STAT_CAP_100FDX: 1188 *val = 1; 1189 break; 1190 1191 case ETHER_STAT_CAP_100HDX: 1192 *val = 1; 1193 break; 1194 1195 case ETHER_STAT_CAP_10FDX: 1196 *val = 1; 1197 break; 1198 1199 case ETHER_STAT_CAP_10HDX: 1200 *val = 1; 1201 break; 1202 1203 case ETHER_STAT_CAP_ASMPAUSE: 1204 *val = 1; 1205 break; 1206 1207 case ETHER_STAT_CAP_PAUSE: 1208 *val = 1; 1209 break; 1210 1211 case ETHER_STAT_CAP_AUTONEG: 1212 *val = 1; 1213 break; 1214 1215 case ETHER_STAT_ADV_CAP_1000FDX: 1216 *val = bgep->param_adv_1000fdx; 1217 break; 1218 1219 case ETHER_STAT_ADV_CAP_1000HDX: 1220 *val = bgep->param_adv_1000hdx; 1221 break; 1222 1223 case ETHER_STAT_ADV_CAP_100FDX: 1224 *val = bgep->param_adv_100fdx; 1225 break; 1226 1227 case ETHER_STAT_ADV_CAP_100HDX: 1228 *val = bgep->param_adv_100hdx; 1229 break; 1230 1231 case ETHER_STAT_ADV_CAP_10FDX: 1232 *val = bgep->param_adv_10fdx; 1233 break; 1234 1235 case ETHER_STAT_ADV_CAP_10HDX: 1236 *val = bgep->param_adv_10hdx; 1237 break; 1238 1239 case ETHER_STAT_ADV_CAP_ASMPAUSE: 1240 *val = bgep->param_adv_asym_pause; 1241 break; 1242 1243 case ETHER_STAT_ADV_CAP_PAUSE: 1244 *val = bgep->param_adv_pause; 1245 break; 1246 1247 case ETHER_STAT_ADV_CAP_AUTONEG: 1248 *val = bgep->param_adv_autoneg; 1249 break; 1250 1251 case ETHER_STAT_LP_CAP_1000FDX: 1252 *val = bgep->param_lp_1000fdx; 1253 break; 1254 1255 case ETHER_STAT_LP_CAP_1000HDX: 1256 *val = bgep->param_lp_1000hdx; 1257 break; 1258 1259 case ETHER_STAT_LP_CAP_100FDX: 1260 *val = bgep->param_lp_100fdx; 1261 break; 1262 1263 case ETHER_STAT_LP_CAP_100HDX: 1264 *val = bgep->param_lp_100hdx; 1265 break; 1266 1267 case ETHER_STAT_LP_CAP_10FDX: 1268 *val = bgep->param_lp_10fdx; 1269 break; 1270 1271 case ETHER_STAT_LP_CAP_10HDX: 1272 *val = bgep->param_lp_10hdx; 1273 break; 1274 1275 case ETHER_STAT_LP_CAP_ASMPAUSE: 1276 *val = bgep->param_lp_asym_pause; 1277 break; 1278 1279 case ETHER_STAT_LP_CAP_PAUSE: 1280 *val = bgep->param_lp_pause; 1281 break; 1282 1283 case ETHER_STAT_LP_CAP_AUTONEG: 1284 *val = bgep->param_lp_autoneg; 1285 break; 1286 1287 case ETHER_STAT_LINK_ASMPAUSE: 1288 *val = bgep->param_adv_asym_pause && 1289 bgep->param_lp_asym_pause && 1290 bgep->param_adv_pause != bgep->param_lp_pause; 1291 break; 1292 1293 case ETHER_STAT_LINK_PAUSE: 1294 *val = bgep->param_link_rx_pause; 1295 break; 1296 1297 case ETHER_STAT_LINK_AUTONEG: 1298 *val = bgep->param_link_autoneg; 1299 break; 1300 1301 case ETHER_STAT_LINK_DUPLEX: 1302 *val = bgep->param_link_duplex; 1303 break; 1304 1305 default: 1306 return (ENOTSUP); 1307 } 1308 1309 return (0); 1310 } 1311