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 2010 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
bge_statistics_update(kstat_t * ksp,int flag)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
bge_set_char_kstat(kstat_named_t * knp,const char * s)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
bge_chipid_update(kstat_t * ksp,int flag)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
bge_driverinfo_update(kstat_t * ksp,int flag)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
bge_serdes_update(kstat_t * ksp,int flag)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
bge_phydata_update(kstat_t * ksp,int flag)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 *
bge_setup_named_kstat(bge_t * bgep,int instance,char * name,const bge_ksindex_t * ksip,size_t size,int (* update)(kstat_t *,int))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
bge_init_kstats(bge_t * bgep,int instance)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
bge_fini_kstats(bge_t * bgep)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
bge_m_stat(void * arg,uint_t stat,uint64_t * val)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
1130 /*
1131 * Retrieve a value for one of the statistics for a particular rx ring
1132 */
1133 int
bge_rx_ring_stat(mac_ring_driver_t rh,uint_t stat,uint64_t * val)1134 bge_rx_ring_stat(mac_ring_driver_t rh, uint_t stat, uint64_t *val)
1135 {
1136 recv_ring_t *rx_ring = (recv_ring_t *)rh;
1137
1138 switch (stat) {
1139 case MAC_STAT_RBYTES:
1140 *val = rx_ring->rx_bytes;
1141 break;
1142
1143 case MAC_STAT_IPACKETS:
1144 *val = rx_ring->rx_pkts;
1145 break;
1146
1147 default:
1148 *val = 0;
1149 return (ENOTSUP);
1150 }
1151
1152 return (0);
1153 }
1154