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