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