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