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, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2005 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_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 int 175 bge_statistics_update(kstat_t *ksp, int flag) 176 { 177 bge_t *bgep; 178 bge_statistics_t *bstp; 179 kstat_named_t *knp; 180 const bge_ksindex_t *ksip; 181 182 if (flag != KSTAT_READ) 183 return (EACCES); 184 185 bgep = ksp->ks_private; 186 bstp = DMA_VPTR(bgep->statistics); 187 knp = ksp->ks_data; 188 189 /* 190 * Transfer the statistics values from the copy that the 191 * chip updates via DMA to the named-kstat structure. 192 * 193 * As above, we don't bother to sync or stop updates to the 194 * statistics, 'cos it doesn't really matter if they're a few 195 * microsends out of date or less than 100% consistent ... 196 */ 197 for (ksip = bge_statistics; ksip->name != NULL; ++knp, ++ksip) 198 knp->value.ui64 = bstp->a[ksip->index]; 199 200 return (0); 201 } 202 203 static int 204 bge_params_update(kstat_t *ksp, int flag) 205 { 206 bge_t *bgep; 207 kstat_named_t *knp; 208 int i; 209 210 if (flag != KSTAT_READ) 211 return (EACCES); 212 213 bgep = ksp->ks_private; 214 for (knp = ksp->ks_data, i = 0; i < PARAM_COUNT; ++knp, ++i) 215 knp->value.ui64 = bgep->nd_params[i].ndp_val; 216 217 return (0); 218 } 219 220 static const bge_ksindex_t bge_chipid[] = { 221 { 0, "asic_rev" }, 222 { 1, "businfo" }, 223 { 2, "command" }, 224 225 { 3, "vendor_id" }, 226 { 4, "device_id" }, 227 { 5, "subsystem_vendor_id" }, 228 { 6, "subsystem_device_id" }, 229 { 7, "revision_id" }, 230 { 8, "cache_line_size" }, 231 { 9, "latency_timer" }, 232 233 { 10, "flags" }, 234 { 11, "chip_type" }, 235 { 12, "mbuf_base" }, 236 { 13, "mbuf_count" }, 237 { 14, "hw_mac_addr" }, 238 239 { 15, "&bus_type" }, 240 { 16, "&bus_speed" }, 241 { 17, "&bus_size" }, 242 { 18, "&supported" }, 243 { 19, "&interface" }, 244 245 { -1, NULL } 246 }; 247 248 static void 249 bge_set_char_kstat(kstat_named_t *knp, const char *s) 250 { 251 (void) strncpy(knp->value.c, s, sizeof (knp->value.c)); 252 } 253 254 static int 255 bge_chipid_update(kstat_t *ksp, int flag) 256 { 257 bge_t *bgep; 258 kstat_named_t *knp; 259 uint64_t tmp; 260 261 if (flag != KSTAT_READ) 262 return (EACCES); 263 264 bgep = ksp->ks_private; 265 knp = ksp->ks_data; 266 267 (knp++)->value.ui64 = bgep->chipid.asic_rev; 268 (knp++)->value.ui64 = bgep->chipid.businfo; 269 (knp++)->value.ui64 = bgep->chipid.command; 270 271 (knp++)->value.ui64 = bgep->chipid.vendor; 272 (knp++)->value.ui64 = bgep->chipid.device; 273 (knp++)->value.ui64 = bgep->chipid.subven; 274 (knp++)->value.ui64 = bgep->chipid.subdev; 275 (knp++)->value.ui64 = bgep->chipid.revision; 276 (knp++)->value.ui64 = bgep->chipid.clsize; 277 (knp++)->value.ui64 = bgep->chipid.latency; 278 279 (knp++)->value.ui64 = bgep->chipid.flags; 280 (knp++)->value.ui64 = bgep->chipid.chip_label; 281 (knp++)->value.ui64 = bgep->chipid.mbuf_base; 282 (knp++)->value.ui64 = bgep->chipid.mbuf_length; 283 (knp++)->value.ui64 = bgep->chipid.hw_mac_addr; 284 285 /* 286 * Now we interpret some of the above into readable strings 287 */ 288 tmp = bgep->chipid.businfo; 289 bge_set_char_kstat(knp++, 290 tmp & PCISTATE_BUS_IS_PCI ? "PCI" : "PCI-X"); 291 bge_set_char_kstat(knp++, 292 tmp & PCISTATE_BUS_IS_FAST ? "fast" : "normal"); 293 bge_set_char_kstat(knp++, 294 tmp & PCISTATE_BUS_IS_32_BIT ? "32 bit" : "64 bit"); 295 296 tmp = bgep->chipid.flags; 297 bge_set_char_kstat(knp++, 298 tmp & CHIP_FLAG_SUPPORTED ? "yes" : "no"); 299 bge_set_char_kstat(knp++, 300 tmp & CHIP_FLAG_SERDES ? "serdes" : "copper"); 301 302 return (0); 303 } 304 305 static const bge_ksindex_t bge_driverinfo[] = { 306 { 0, "rx_buff_addr" }, 307 { 1, "tx_buff_addr" }, 308 { 2, "rx_desc_addr" }, 309 { 3, "tx_desc_addr" }, 310 311 { 4, "tx_desc_free" }, 312 { 5, "resched_needed" }, 313 { 6, "watchdog" }, 314 { 7, "chip_resets" }, 315 { 8, "dma_misses" }, 316 317 { 9, "misc_host_config" }, 318 { 10, "dma_rw_control" }, 319 { 11, "pci_bus_info" }, 320 321 { 12, "buff_mgr_status" }, 322 { 13, "rcv_init_status" }, 323 324 { -1, NULL } 325 }; 326 327 static int 328 bge_driverinfo_update(kstat_t *ksp, int flag) 329 { 330 bge_t *bgep; 331 kstat_named_t *knp; 332 ddi_acc_handle_t handle; 333 334 if (flag != KSTAT_READ) 335 return (EACCES); 336 337 bgep = ksp->ks_private; 338 knp = ksp->ks_data; 339 340 (knp++)->value.ui64 = bgep->rx_buff[0].cookie.dmac_laddress; 341 (knp++)->value.ui64 = bgep->tx_buff[0].cookie.dmac_laddress; 342 (knp++)->value.ui64 = bgep->rx_desc[0].cookie.dmac_laddress; 343 (knp++)->value.ui64 = bgep->tx_desc.cookie.dmac_laddress; 344 345 (knp++)->value.ui64 = bgep->send[0].tx_free; 346 (knp++)->value.ui64 = bgep->resched_needed; 347 (knp++)->value.ui64 = bgep->watchdog; 348 (knp++)->value.ui64 = bgep->chip_resets; 349 (knp++)->value.ui64 = bgep->missed_dmas; 350 351 /* 352 * Hold the mutex while accessing the chip registers 353 * just in case the factotum is trying to reset it! 354 */ 355 handle = bgep->cfg_handle; 356 mutex_enter(bgep->genlock); 357 (knp++)->value.ui64 = pci_config_get32(handle, PCI_CONF_BGE_MHCR); 358 (knp++)->value.ui64 = pci_config_get32(handle, PCI_CONF_BGE_PDRWCR); 359 (knp++)->value.ui64 = pci_config_get32(handle, PCI_CONF_BGE_PCISTATE); 360 361 (knp++)->value.ui64 = bge_reg_get32(bgep, BUFFER_MANAGER_STATUS_REG); 362 (knp++)->value.ui64 = bge_reg_get32(bgep, RCV_INITIATOR_STATUS_REG); 363 mutex_exit(bgep->genlock); 364 365 return (0); 366 } 367 368 static const bge_ksindex_t bge_mii_kstats[] = { 369 { 0, "%xcvr_addr" }, 370 { 1, "%xcvr_id" }, 371 { 2, "%xcvr_inuse" }, 372 373 { 3, "%cap_1000fdx" }, 374 { 4, "%cap_1000hdx" }, 375 { 5, "%cap_100fdx" }, 376 { 6, "%cap_100hdx" }, 377 { 7, "%cap_10fdx" }, 378 { 8, "%cap_10hdx" }, 379 { 9, "%cap_asmpause" }, 380 { 10, "%cap_pause" }, 381 { 11, "%cap_rem_fault" }, 382 { 12, "%cap_autoneg" }, 383 384 { 13, "%adv_cap_1000fdx" }, 385 { 14, "%adv_cap_1000hdx" }, 386 { 15, "%adv_cap_100fdx" }, 387 { 16, "%adv_cap_100hdx" }, 388 { 17, "%adv_cap_10fdx" }, 389 { 18, "%adv_cap_10hdx" }, 390 { 19, "%adv_cap_asmpause" }, 391 { 20, "%adv_cap_pause" }, 392 { 21, "%adv_rem_fault" }, 393 { 22, "%adv_cap_autoneg" }, 394 395 { 23, "%lp_cap_1000fdx" }, 396 { 24, "%lp_cap_1000hdx" }, 397 { 25, "%lp_cap_100fdx" }, 398 { 26, "%lp_cap_100hdx" }, 399 { 27, "%lp_cap_10fdx" }, 400 { 28, "%lp_cap_10hdx" }, 401 { 29, "%lp_cap_asmpause" }, 402 { 30, "%lp_cap_pause" }, 403 { 31, "%lp_rem_fault" }, 404 { 32, "%lp_cap_autoneg" }, 405 406 { 33, "%link_asmpause" }, 407 { 34, "%link_pause" }, 408 { 35, "%link_duplex" }, 409 { 36, "%link_up" }, 410 411 { -1, NULL } 412 }; 413 414 /* 415 * Derive and publish the standard "mii" kstats. 416 * 417 * The information required is somewhat scattered: some is already held 418 * in driver softstate, some is available in the MII registers, and some 419 * has to be computed from combinations of both ... 420 */ 421 static int 422 bge_mii_update(kstat_t *ksp, int flag) 423 { 424 bge_t *bgep; 425 kstat_named_t *knp; 426 uint16_t anlpar; 427 uint16_t anar; 428 uint32_t xcvr_id; 429 uint32_t xcvr_inuse; 430 boolean_t asym_pause; 431 432 if (flag != KSTAT_READ) 433 return (EACCES); 434 435 bgep = ksp->ks_private; 436 knp = ksp->ks_data; 437 438 /* 439 * Read all the relevant PHY registers 440 */ 441 mutex_enter(bgep->genlock); 442 anlpar = bge_mii_get16(bgep, MII_AN_LPABLE); 443 anar = bge_mii_get16(bgep, MII_AN_ADVERT); 444 445 /* 446 * Derive PHY characterisation parameters 447 */ 448 xcvr_id = bge_mii_get16(bgep, MII_PHYIDH); 449 xcvr_id <<= 16; 450 xcvr_id |= bge_mii_get16(bgep, MII_PHYIDL); 451 mutex_exit(bgep->genlock); 452 453 switch (bgep->param_link_speed) { 454 case 1000: 455 if (bgep->chipid.flags & CHIP_FLAG_SERDES) 456 xcvr_inuse = XCVR_TYPE_1000BASE_X; 457 else 458 xcvr_inuse = XCVR_TYPE_1000BASE_T; 459 break; 460 461 case 100: 462 xcvr_inuse = XCVR_TYPE_100BASE_X; 463 break; 464 465 case 10: 466 xcvr_inuse = XCVR_TYPE_10BASE_T; 467 break; 468 469 default: 470 xcvr_inuse = XCVR_TYPE_UNDEFINED; 471 break; 472 } 473 474 /* 475 * Other miscellaneous transformations ... 476 */ 477 asym_pause = bgep->param_link_rx_pause != bgep->param_link_tx_pause; 478 479 /* 480 * All required values are now available; assign them to the 481 * actual kstats, in the sequence defined by the table above. 482 */ 483 (knp++)->value.ui32 = bgep->phy_mii_addr; 484 (knp++)->value.ui32 = xcvr_id; 485 (knp++)->value.ui32 = xcvr_inuse; 486 487 /* 488 * Our capabilities 489 */ 490 (knp++)->value.ui32 = bgep->nd_params[PARAM_1000FDX_CAP].ndp_val; 491 (knp++)->value.ui32 = bgep->nd_params[PARAM_1000HDX_CAP].ndp_val; 492 (knp++)->value.ui32 = bgep->nd_params[PARAM_100FDX_CAP].ndp_val; 493 (knp++)->value.ui32 = bgep->nd_params[PARAM_100HDX_CAP].ndp_val; 494 (knp++)->value.ui32 = bgep->nd_params[PARAM_10FDX_CAP].ndp_val; 495 (knp++)->value.ui32 = bgep->nd_params[PARAM_10HDX_CAP].ndp_val; 496 (knp++)->value.ui32 = bgep->nd_params[PARAM_ASYM_PAUSE_CAP].ndp_val; 497 (knp++)->value.ui32 = bgep->nd_params[PARAM_PAUSE_CAP].ndp_val; 498 (knp++)->value.ui32 = B_TRUE; 499 (knp++)->value.ui32 = bgep->nd_params[PARAM_AUTONEG_CAP].ndp_val; 500 501 /* 502 * Our *advertised* capabilities 503 */ 504 (knp++)->value.ui32 = bgep->param_adv_1000fdx; 505 (knp++)->value.ui32 = bgep->param_adv_1000hdx; 506 (knp++)->value.ui32 = bgep->param_adv_100fdx; 507 (knp++)->value.ui32 = bgep->param_adv_100hdx; 508 (knp++)->value.ui32 = bgep->param_adv_10fdx; 509 (knp++)->value.ui32 = bgep->param_adv_10hdx; 510 (knp++)->value.ui32 = bgep->param_adv_asym_pause; 511 (knp++)->value.ui32 = bgep->param_adv_pause; 512 (knp++)->value.ui32 = (anar & MII_AN_ADVERT_REMFAULT) ? 1 : 0; 513 (knp++)->value.ui32 = bgep->param_adv_autoneg; 514 515 /* 516 * Link Partner's advertised capabilities 517 */ 518 (knp++)->value.ui32 = bgep->param_lp_1000fdx; 519 (knp++)->value.ui32 = bgep->param_lp_1000hdx; 520 (knp++)->value.ui32 = bgep->param_lp_100fdx; 521 (knp++)->value.ui32 = bgep->param_lp_100hdx; 522 (knp++)->value.ui32 = bgep->param_lp_10fdx; 523 (knp++)->value.ui32 = bgep->param_lp_10hdx; 524 (knp++)->value.ui32 = bgep->param_lp_asym_pause; 525 (knp++)->value.ui32 = bgep->param_lp_pause; 526 (knp++)->value.ui32 = (anlpar & MII_AN_ADVERT_REMFAULT) ? 1 : 0; 527 (knp++)->value.ui32 = bgep->param_lp_autoneg; 528 529 /* 530 * Current operating modes 531 */ 532 (knp++)->value.ui32 = asym_pause; 533 (knp++)->value.ui32 = bgep->param_link_rx_pause; 534 (knp++)->value.ui32 = bgep->param_link_duplex; 535 (knp++)->value.ui32 = bgep->param_link_up; 536 537 return (0); 538 } 539 540 static const bge_ksindex_t bge_serdes[] = { 541 { 0, "serdes_status" }, 542 { 1, "serdes_advert" }, 543 { 2, "serdes_lpadv" }, 544 545 { -1, NULL } 546 }; 547 548 static int 549 bge_serdes_update(kstat_t *ksp, int flag) 550 { 551 bge_t *bgep; 552 kstat_named_t *knp; 553 554 if (flag != KSTAT_READ) 555 return (EACCES); 556 557 bgep = ksp->ks_private; 558 knp = ksp->ks_data; 559 560 (knp++)->value.ui64 = bgep->serdes_status; 561 (knp++)->value.ui64 = bgep->serdes_advert; 562 (knp++)->value.ui64 = bgep->serdes_lpadv; 563 564 return (0); 565 } 566 567 static const bge_ksindex_t bge_phydata[] = { 568 { MII_CONTROL, "mii_control" }, 569 { MII_STATUS, "mii_status" }, 570 { MII_PHYIDH, "phy_identifier" }, 571 { MII_AN_ADVERT, "an_advert" }, 572 { MII_AN_LPABLE, "an_lp_ability" }, 573 { MII_AN_EXPANSION, "an_expansion" }, 574 { MII_AN_LPNXTPG, "an_lp_nextpage" }, 575 { MII_1000BASE_T_CONTROL, "gbit_control" }, 576 { MII_1000BASE_T_STATUS, "gbit_status" }, 577 { MII_IEEE_EXT_STATUS, "ieee_ext_status" }, 578 { MII_EXT_CONTROL, "phy_ext_control" }, 579 { MII_EXT_STATUS, "phy_ext_status" }, 580 { MII_RCV_ERR_COUNT, "receive_error_count" }, 581 { MII_FALSE_CARR_COUNT, "false_carrier_count" }, 582 { MII_RCV_NOT_OK_COUNT, "receiver_not_ok_count" }, 583 { MII_AUX_CONTROL, "aux_control" }, 584 { MII_AUX_STATUS, "aux_status" }, 585 { MII_INTR_STATUS, "intr_status" }, 586 { MII_INTR_MASK, "intr_mask" }, 587 { MII_HCD_STATUS, "hcd_status" }, 588 589 { -1, NULL } 590 }; 591 592 static int 593 bge_phydata_update(kstat_t *ksp, int flag) 594 { 595 bge_t *bgep; 596 kstat_named_t *knp; 597 const bge_ksindex_t *ksip; 598 599 if (flag != KSTAT_READ) 600 return (EACCES); 601 602 bgep = ksp->ks_private; 603 knp = ksp->ks_data; 604 605 /* 606 * Read the PHY registers & update the kstats ... 607 * 608 * We need to hold the mutex while performing MII reads, but 609 * we don't want to hold it across the entire sequence of reads. 610 * So we grab and release it on each iteration, 'cos it doesn't 611 * really matter if the kstats are less than 100% consistent ... 612 */ 613 for (ksip = bge_phydata; ksip->name != NULL; ++knp, ++ksip) { 614 mutex_enter(bgep->genlock); 615 switch (ksip->index) { 616 case MII_STATUS: 617 knp->value.ui64 = bgep->phy_gen_status; 618 break; 619 620 case MII_PHYIDH: 621 knp->value.ui64 = bge_mii_get16(bgep, MII_PHYIDH); 622 knp->value.ui64 <<= 16; 623 knp->value.ui64 |= bge_mii_get16(bgep, MII_PHYIDL); 624 break; 625 626 default: 627 knp->value.ui64 = bge_mii_get16(bgep, ksip->index); 628 break; 629 } 630 mutex_exit(bgep->genlock); 631 } 632 633 return (0); 634 } 635 636 static kstat_t * 637 bge_setup_named_kstat(bge_t *bgep, int instance, char *name, 638 const bge_ksindex_t *ksip, size_t size, int (*update)(kstat_t *, int)) 639 { 640 kstat_t *ksp; 641 kstat_named_t *knp; 642 char *np; 643 int type; 644 645 size /= sizeof (bge_ksindex_t); 646 ksp = kstat_create(BGE_DRIVER_NAME, instance, name, "net", 647 KSTAT_TYPE_NAMED, size-1, KSTAT_FLAG_PERSISTENT); 648 if (ksp == NULL) 649 return (NULL); 650 651 ksp->ks_private = bgep; 652 ksp->ks_update = update; 653 for (knp = ksp->ks_data; (np = ksip->name) != NULL; ++knp, ++ksip) { 654 switch (*np) { 655 default: 656 type = KSTAT_DATA_UINT64; 657 break; 658 case '%': 659 np += 1; 660 type = KSTAT_DATA_UINT32; 661 break; 662 case '$': 663 np += 1; 664 type = KSTAT_DATA_STRING; 665 break; 666 case '&': 667 np += 1; 668 type = KSTAT_DATA_CHAR; 669 break; 670 } 671 kstat_named_init(knp, np, type); 672 } 673 kstat_install(ksp); 674 675 return (ksp); 676 } 677 678 /* 679 * Create kstats corresponding to NDD parameters 680 */ 681 static kstat_t * 682 bge_setup_params_kstat(bge_t *bgep, int instance, char *name, 683 int (*update)(kstat_t *, int)) 684 { 685 kstat_t *ksp; 686 kstat_named_t *knp; 687 int i; 688 689 ksp = kstat_create(BGE_DRIVER_NAME, instance, name, "net", 690 KSTAT_TYPE_NAMED, PARAM_COUNT, KSTAT_FLAG_PERSISTENT); 691 if (ksp != NULL) { 692 ksp->ks_private = bgep; 693 ksp->ks_update = update; 694 for (knp = ksp->ks_data, i = 0; i < PARAM_COUNT; ++knp, ++i) 695 kstat_named_init(knp, bgep->nd_params[i].ndp_name+1, 696 KSTAT_DATA_UINT64); 697 kstat_install(ksp); 698 } 699 700 return (ksp); 701 } 702 703 void 704 bge_init_kstats(bge_t *bgep, int instance) 705 { 706 kstat_t *ksp; 707 708 BGE_TRACE(("bge_init_kstats($%p, %d)", (void *)bgep, instance)); 709 710 DMA_ZERO(bgep->statistics); 711 bgep->bge_kstats[BGE_KSTAT_RAW] = ksp = kstat_create(BGE_DRIVER_NAME, 712 instance, "raw_statistics", "net", KSTAT_TYPE_RAW, 713 sizeof (bge_statistics_t), KSTAT_FLAG_VIRTUAL); 714 if (ksp != NULL) { 715 ksp->ks_data = DMA_VPTR(bgep->statistics); 716 kstat_install(ksp); 717 } 718 719 bgep->bge_kstats[BGE_KSTAT_STATS] = bge_setup_named_kstat(bgep, 720 instance, "statistics", bge_statistics, 721 sizeof (bge_statistics), bge_statistics_update); 722 723 bgep->bge_kstats[BGE_KSTAT_CHIPID] = bge_setup_named_kstat(bgep, 724 instance, "chipid", bge_chipid, 725 sizeof (bge_chipid), bge_chipid_update); 726 727 bgep->bge_kstats[BGE_KSTAT_DRIVER] = bge_setup_named_kstat(bgep, 728 instance, "driverinfo", bge_driverinfo, 729 sizeof (bge_driverinfo), bge_driverinfo_update); 730 731 bgep->bge_kstats[BGE_KSTAT_MII] = bge_setup_named_kstat(bgep, 732 instance, "mii", bge_mii_kstats, 733 sizeof (bge_mii_kstats), bge_mii_update); 734 735 if (bgep->chipid.flags & CHIP_FLAG_SERDES) 736 bgep->bge_kstats[BGE_KSTAT_PHYS] = bge_setup_named_kstat(bgep, 737 instance, "serdes", bge_serdes, 738 sizeof (bge_serdes), bge_serdes_update); 739 else 740 bgep->bge_kstats[BGE_KSTAT_PHYS] = bge_setup_named_kstat(bgep, 741 instance, "phydata", bge_phydata, 742 sizeof (bge_phydata), bge_phydata_update); 743 744 bgep->bge_kstats[BGE_KSTAT_PARAMS] = bge_setup_params_kstat(bgep, 745 instance, "parameters", bge_params_update); 746 } 747 748 void 749 bge_fini_kstats(bge_t *bgep) 750 { 751 int i; 752 753 BGE_TRACE(("bge_fini_kstats($%p)", (void *)bgep)); 754 755 for (i = BGE_KSTAT_COUNT; --i >= 0; ) 756 if (bgep->bge_kstats[i] != NULL) 757 kstat_delete(bgep->bge_kstats[i]); 758 } 759 760 uint64_t 761 bge_m_stat(void *arg, enum mac_stat stat) 762 { 763 bge_t *bgep = arg; 764 bge_statistics_t *bstp = DMA_VPTR(bgep->statistics); 765 uint64_t val; 766 767 switch (stat) { 768 case MAC_STAT_IFSPEED: 769 val = bgep->param_link_speed * 1000000ull; 770 break; 771 772 case MAC_STAT_MULTIRCV: 773 val = bstp->s.ifHCInMulticastPkts; 774 break; 775 776 case MAC_STAT_BRDCSTRCV: 777 val = bstp->s.ifHCInBroadcastPkts; 778 break; 779 780 case MAC_STAT_MULTIXMT: 781 val = bstp->s.ifHCOutMulticastPkts; 782 break; 783 784 case MAC_STAT_BRDCSTXMT: 785 val = bstp->s.ifHCOutBroadcastPkts; 786 break; 787 788 case MAC_STAT_NORCVBUF: 789 val = bstp->s.ifInDiscards; 790 break; 791 792 case MAC_STAT_IERRORS: 793 val = bstp->s.ifInErrors; 794 break; 795 796 case MAC_STAT_NOXMTBUF: 797 val = bstp->s.ifOutDiscards; 798 break; 799 800 case MAC_STAT_OERRORS: 801 val = bstp->s.ifOutErrors; 802 break; 803 804 case MAC_STAT_COLLISIONS: 805 val = bstp->s.etherStatsCollisions; 806 break; 807 808 case MAC_STAT_RBYTES: 809 val = bstp->s.ifHCInOctets; 810 break; 811 812 case MAC_STAT_IPACKETS: 813 val = bstp->s.ifHCInUcastPkts + 814 bstp->s.ifHCInMulticastPkts + 815 bstp->s.ifHCInBroadcastPkts; 816 break; 817 818 case MAC_STAT_OBYTES: 819 val = bstp->s.ifHCOutOctets; 820 break; 821 822 case MAC_STAT_OPACKETS: 823 val = bstp->s.ifHCOutUcastPkts + 824 bstp->s.ifHCOutMulticastPkts + 825 bstp->s.ifHCOutBroadcastPkts; 826 break; 827 828 case MAC_STAT_ALIGN_ERRORS: 829 val = bstp->s.dot3StatsAlignmentErrors; 830 break; 831 832 case MAC_STAT_FCS_ERRORS: 833 val = bstp->s.dot3StatsFCSErrors; 834 break; 835 836 case MAC_STAT_FIRST_COLLISIONS: 837 val = bstp->s.dot3StatsSingleCollisionFrames; 838 break; 839 840 case MAC_STAT_MULTI_COLLISIONS: 841 val = bstp->s.dot3StatsMultipleCollisionFrames; 842 break; 843 844 case MAC_STAT_DEFER_XMTS: 845 val = bstp->s.dot3StatsDeferredTransmissions; 846 break; 847 848 case MAC_STAT_TX_LATE_COLLISIONS: 849 val = bstp->s.dot3StatsLateCollisions; 850 break; 851 852 case MAC_STAT_EX_COLLISIONS: 853 val = bstp->s.dot3StatsExcessiveCollisions; 854 break; 855 856 case MAC_STAT_MACXMT_ERRORS: 857 val = bstp->s.dot3StatsInternalMacTransmitErrors; 858 break; 859 860 case MAC_STAT_CARRIER_ERRORS: 861 val = bstp->s.dot3StatsCarrierSenseErrors; 862 break; 863 864 case MAC_STAT_TOOLONG_ERRORS: 865 val = bstp->s.dot3StatsFrameTooLongs; 866 break; 867 868 case MAC_STAT_XCVR_ADDR: 869 val = bgep->phy_mii_addr; 870 break; 871 872 case MAC_STAT_XCVR_ID: 873 mutex_enter(bgep->genlock); 874 val = bge_mii_get16(bgep, MII_PHYIDH); 875 val <<= 16; 876 val |= bge_mii_get16(bgep, MII_PHYIDL); 877 mutex_exit(bgep->genlock); 878 break; 879 880 case MAC_STAT_XCVR_INUSE: 881 val = XCVR_1000T; 882 break; 883 884 case MAC_STAT_CAP_1000FDX: 885 val = 1; 886 break; 887 888 case MAC_STAT_CAP_1000HDX: 889 val = 1; 890 break; 891 892 case MAC_STAT_CAP_100FDX: 893 val = 1; 894 break; 895 896 case MAC_STAT_CAP_100HDX: 897 val = 1; 898 break; 899 900 case MAC_STAT_CAP_10FDX: 901 val = 1; 902 break; 903 904 case MAC_STAT_CAP_10HDX: 905 val = 1; 906 break; 907 908 case MAC_STAT_CAP_ASMPAUSE: 909 val = 1; 910 break; 911 912 case MAC_STAT_CAP_PAUSE: 913 val = 1; 914 break; 915 916 case MAC_STAT_CAP_AUTONEG: 917 val = 1; 918 break; 919 920 case MAC_STAT_ADV_CAP_1000FDX: 921 val = bgep->param_adv_1000fdx; 922 break; 923 924 case MAC_STAT_ADV_CAP_1000HDX: 925 val = bgep->param_adv_1000hdx; 926 break; 927 928 case MAC_STAT_ADV_CAP_100FDX: 929 val = bgep->param_adv_100fdx; 930 break; 931 932 case MAC_STAT_ADV_CAP_100HDX: 933 val = bgep->param_adv_100hdx; 934 break; 935 936 case MAC_STAT_ADV_CAP_10FDX: 937 val = bgep->param_adv_10fdx; 938 break; 939 940 case MAC_STAT_ADV_CAP_10HDX: 941 val = bgep->param_adv_10hdx; 942 break; 943 944 case MAC_STAT_ADV_CAP_ASMPAUSE: 945 val = bgep->param_adv_asym_pause; 946 break; 947 948 case MAC_STAT_ADV_CAP_PAUSE: 949 val = bgep->param_adv_pause; 950 break; 951 952 case MAC_STAT_ADV_CAP_AUTONEG: 953 val = bgep->param_adv_autoneg; 954 break; 955 956 case MAC_STAT_LP_CAP_1000FDX: 957 val = bgep->param_lp_1000fdx; 958 break; 959 960 case MAC_STAT_LP_CAP_1000HDX: 961 val = bgep->param_lp_1000hdx; 962 break; 963 964 case MAC_STAT_LP_CAP_100FDX: 965 val = bgep->param_lp_100fdx; 966 break; 967 968 case MAC_STAT_LP_CAP_100HDX: 969 val = bgep->param_lp_100hdx; 970 break; 971 972 case MAC_STAT_LP_CAP_10FDX: 973 val = bgep->param_lp_10fdx; 974 break; 975 976 case MAC_STAT_LP_CAP_10HDX: 977 val = bgep->param_lp_10hdx; 978 break; 979 980 case MAC_STAT_LP_CAP_ASMPAUSE: 981 val = bgep->param_lp_asym_pause; 982 break; 983 984 case MAC_STAT_LP_CAP_PAUSE: 985 val = bgep->param_lp_pause; 986 break; 987 988 case MAC_STAT_LP_CAP_AUTONEG: 989 val = bgep->param_lp_autoneg; 990 break; 991 992 case MAC_STAT_LINK_ASMPAUSE: 993 val = bgep->param_adv_asym_pause && 994 bgep->param_lp_asym_pause && 995 bgep->param_adv_pause != bgep->param_lp_pause; 996 break; 997 998 case MAC_STAT_LINK_PAUSE: 999 val = bgep->param_link_rx_pause; 1000 break; 1001 1002 case MAC_STAT_LINK_AUTONEG: 1003 val = bgep->param_link_autoneg; 1004 break; 1005 1006 case MAC_STAT_LINK_DUPLEX: 1007 val = bgep->param_link_duplex; 1008 break; 1009 1010 #ifdef DEBUG 1011 default: 1012 /* 1013 * Shouldn't reach here... 1014 */ 1015 cmn_err(CE_PANIC, 1016 "bge_m_stat: unrecognized parameter value = %d", 1017 stat); 1018 #endif 1019 } 1020 1021 return (val); 1022 } 1023