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 (c) 2010-2013, by Broadcom, Inc.
24 * All Rights Reserved.
25 */
26
27 /*
28 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
29 * Use is subject to license terms.
30 */
31
32 #include "bge_impl.h"
33
34 #define BGE_DBG BGE_DBG_STATS /* debug flag for this code */
35
36 /*
37 * Local datatype for defining tables of (Offset, Name) pairs
38 */
39 typedef struct {
40 offset_t index;
41 char *name;
42 } bge_ksindex_t;
43
44
45 /*
46 * Table of Hardware-defined Statistics Block Offsets and Names
47 */
48 #define KS_NAME(s) { KS_ ## s, #s }
49
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),
77
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),
109
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),
133
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),
158
159 { KS_STATS_SIZE, NULL }
160 };
161
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),
190
191 { KS_STAT_REG_SIZE, NULL }
192 };
193
194 static int
bge_statistics_update(kstat_t * ksp,int flag)195 bge_statistics_update(kstat_t *ksp, int flag)
196 {
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;
202
203 if (flag != KSTAT_READ)
204 return (EACCES);
205
206 bgep = ksp->ks_private;
207 if (bgep->chipid.statistic_type == BGE_STAT_BLK)
208 bstp = DMA_VPTR(bgep->statistics);
209
210 knp = ksp->ks_data;
211
212 /*
213 * Transfer the statistics values from the copy that the
214 * chip updates via DMA to the named-kstat structure.
215 *
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 ...
219 */
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);
264 }
265
266 return (0);
267 }
268
269 static const bge_ksindex_t bge_chipid[] = {
270 { 0, "asic_rev" },
271 { 1, "businfo" },
272 { 2, "command" },
273
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" },
281
282 { 10, "flags" },
283 { 11, "chip_type" },
284 { 12, "mbuf_base" },
285 { 13, "mbuf_count" },
286 { 14, "hw_mac_addr" },
287
288 { 15, "&bus_type" },
289 { 16, "&bus_speed" },
290 { 17, "&bus_size" },
291 { 18, "&supported" },
292 { 19, "&interface" },
293
294 { 20, "nvtype" },
295
296 { 21, "asic_rev_prod_id" },
297
298 { -1, NULL }
299 };
300
301 static void
bge_set_char_kstat(kstat_named_t * knp,const char * s)302 bge_set_char_kstat(kstat_named_t *knp, const char *s)
303 {
304 (void) strncpy(knp->value.c, s, sizeof (knp->value.c));
305 }
306
307 static int
bge_chipid_update(kstat_t * ksp,int flag)308 bge_chipid_update(kstat_t *ksp, int flag)
309 {
310 bge_t *bgep;
311 kstat_named_t *knp;
312 uint64_t tmp;
313
314 if (flag != KSTAT_READ)
315 return (EACCES);
316
317 bgep = ksp->ks_private;
318 knp = ksp->ks_data;
319
320 (knp++)->value.ui64 = bgep->chipid.asic_rev;
321 (knp++)->value.ui64 = bgep->chipid.businfo;
322 (knp++)->value.ui64 = bgep->chipid.command;
323
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;
331
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;
337
338 /*
339 * Now we interpret some of the above into readable strings
340 */
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");
348
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");
354
355 (knp++)->value.ui64 =
356 ((bgep->chipid.nvtype == BGE_NVTYPE_NONE) ||
357 (bgep->chipid.nvtype == BGE_NVTYPE_UNKNOWN)) ?
358 0 : bgep->chipid.nvtype;
359
360 (knp++)->value.ui64 = bgep->chipid.asic_rev_prod_id;
361
362 return (0);
363 }
364
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" },
370
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" },
385
386 { 18, "watchdog" },
387 { 19, "chip_resets" },
388 { 20, "dma_misses" },
389 { 21, "update_misses" },
390
391 { 22, "misc_host_config" },
392 { 23, "dma_rw_control" },
393 { 24, "pci_bus_info" },
394
395 { 25, "buff_mgr_status" },
396 { 26, "rcv_init_status" },
397
398 { -1, NULL }
399 };
400
401 static int
bge_driverinfo_update(kstat_t * ksp,int flag)402 bge_driverinfo_update(kstat_t *ksp, int flag)
403 {
404 bge_t *bgep;
405 kstat_named_t *knp;
406 ddi_acc_handle_t handle;
407
408 if (flag != KSTAT_READ)
409 return (EACCES);
410
411 bgep = ksp->ks_private;
412 if (bgep->bge_chip_state == BGE_CHIP_FAULT)
413 return (EIO);
414
415 knp = ksp->ks_data;
416
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;
421
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;
437
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;
442
443 /*
444 * Hold the mutex while accessing the chip registers
445 * just in case the factotum is trying to reset it!
446 */
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);
456 }
457
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);
464 }
465 mutex_exit(bgep->genlock);
466
467 return (0);
468 }
469
470 static const bge_ksindex_t bge_serdes[] = {
471 { 0, "serdes_status" },
472 { 1, "serdes_advert" },
473 { 2, "serdes_lpadv" },
474
475 { -1, NULL }
476 };
477
478 static int
bge_serdes_update(kstat_t * ksp,int flag)479 bge_serdes_update(kstat_t *ksp, int flag)
480 {
481 bge_t *bgep;
482 kstat_named_t *knp;
483
484 if (flag != KSTAT_READ)
485 return (EACCES);
486
487 bgep = ksp->ks_private;
488 knp = ksp->ks_data;
489
490 (knp++)->value.ui64 = bgep->serdes_status;
491 (knp++)->value.ui64 = bgep->serdes_advert;
492 (knp++)->value.ui64 = bgep->serdes_lpadv;
493
494 return (0);
495 }
496
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" },
519
520 { -1, NULL }
521 };
522
523 static int
bge_phydata_update(kstat_t * ksp,int flag)524 bge_phydata_update(kstat_t *ksp, int flag)
525 {
526 bge_t *bgep;
527 kstat_named_t *knp;
528 const bge_ksindex_t *ksip;
529
530 if (flag != KSTAT_READ)
531 return (EACCES);
532
533 bgep = ksp->ks_private;
534 if (bgep->bge_chip_state == BGE_CHIP_FAULT)
535 return (EIO);
536
537 knp = ksp->ks_data;
538
539 /*
540 * Read the PHY registers & update the kstats ...
541 *
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 ...
546 */
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;
553
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;
559
560 case EEE_MODE_REG:
561 knp->value.ui64 = 0;
562 if (bgep->link_state == LINK_STATE_UP)
563 {
564 knp->value.ui64 =
565 (bge_reg_get32(bgep, EEE_MODE_REG) & 0x80) ?
566 1 : 0;
567 }
568 break;
569
570 default:
571 knp->value.ui64 = bge_mii_get16(bgep, ksip->index);
572 break;
573 }
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);
579 }
580 mutex_exit(bgep->genlock);
581 }
582
583 return (0);
584 }
585
586 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))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))
589 {
590 kstat_t *ksp;
591 kstat_named_t *knp;
592 char *np;
593 int type;
594
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);
600
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;
620 }
621 kstat_named_init(knp, np, type);
622 }
623 kstat_install(ksp);
624
625 return (ksp);
626 }
627
628 void
bge_init_kstats(bge_t * bgep,int instance)629 bge_init_kstats(bge_t *bgep, int instance)
630 {
631 kstat_t *ksp;
632
633 BGE_TRACE(("bge_init_kstats($%p, %d)", (void *)bgep, instance));
634
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);
644 }
645
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);
653 }
654
655 bgep->bge_kstats[BGE_KSTAT_CHIPID] = bge_setup_named_kstat(bgep,
656 instance, "chipid", bge_chipid,
657 sizeof (bge_chipid), bge_chipid_update);
658
659 bgep->bge_kstats[BGE_KSTAT_DRIVER] = bge_setup_named_kstat(bgep,
660 instance, "driverinfo", bge_driverinfo,
661 sizeof (bge_driverinfo), bge_driverinfo_update);
662
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);
671
672 }
673
674 void
bge_fini_kstats(bge_t * bgep)675 bge_fini_kstats(bge_t *bgep)
676 {
677 int i;
678
679 BGE_TRACE(("bge_fini_kstats($%p)", (void *)bgep));
680
681 for (i = BGE_KSTAT_COUNT; --i >= 0; )
682 if (bgep->bge_kstats[i] != NULL)
683 kstat_delete(bgep->bge_kstats[i]);
684 }
685
686 int
bge_m_stat(void * arg,uint_t stat,uint64_t * val)687 bge_m_stat(void *arg, uint_t stat, uint64_t *val)
688 {
689 bge_t *bgep = arg;
690 bge_statistics_t *bstp;
691 bge_statistics_reg_t *pstats;
692
693 if (bgep->bge_chip_state != BGE_CHIP_RUNNING) {
694 return (EINVAL);
695 }
696
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);
759 }
760 mutex_exit(bgep->genlock);
761 }
762
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;
768
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;
775
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;
782
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;
789
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;
796
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;
803
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;
817 }
818 break;
819
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;
826
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;
833
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;
840
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;
847
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;
858
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;
865
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;
876
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;
883
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;
890
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;
897
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;
904
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;
911
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;
918
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;
925
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;
932
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;
939
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;
946
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
955
956 case ETHER_STAT_XCVR_ADDR:
957 *val = bgep->phy_mii_addr;
958 break;
959
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);
968 }
969 mutex_exit(bgep->genlock);
970 break;
971
972 case ETHER_STAT_XCVR_INUSE:
973 *val = (uint64_t)bge_phys_media(bgep);
974 break;
975
976 case ETHER_STAT_CAP_1000FDX:
977 *val = 1;
978 break;
979
980 case ETHER_STAT_CAP_1000HDX:
981 *val = 1;
982 break;
983
984 case ETHER_STAT_CAP_100FDX:
985 if (bgep->chipid.flags & CHIP_FLAG_SERDES)
986 *val = 0;
987 else
988 *val = 1;
989 break;
990
991 case ETHER_STAT_CAP_100HDX:
992 if (bgep->chipid.flags & CHIP_FLAG_SERDES)
993 *val = 0;
994 else
995 *val = 1;
996 break;
997
998 case ETHER_STAT_CAP_10FDX:
999 if (bgep->chipid.flags & CHIP_FLAG_SERDES)
1000 *val = 0;
1001 else
1002 *val = 1;
1003 break;
1004
1005 case ETHER_STAT_CAP_10HDX:
1006 if (bgep->chipid.flags & CHIP_FLAG_SERDES)
1007 *val = 0;
1008 else
1009 *val = 1;
1010 break;
1011
1012 case ETHER_STAT_CAP_ASMPAUSE:
1013 *val = 1;
1014 break;
1015
1016 case ETHER_STAT_CAP_PAUSE:
1017 *val = 1;
1018 break;
1019
1020 case ETHER_STAT_CAP_AUTONEG:
1021 *val = 1;
1022 break;
1023
1024 #if (MAC_VERSION > 1)
1025 case ETHER_STAT_CAP_REMFAULT:
1026 *val = 1;
1027 break;
1028 #endif
1029
1030 case ETHER_STAT_ADV_CAP_1000FDX:
1031 *val = bgep->param_adv_1000fdx;
1032 break;
1033
1034 case ETHER_STAT_ADV_CAP_1000HDX:
1035 *val = bgep->param_adv_1000hdx;
1036 break;
1037
1038 case ETHER_STAT_ADV_CAP_100FDX:
1039 *val = bgep->param_adv_100fdx;
1040 break;
1041
1042 case ETHER_STAT_ADV_CAP_100HDX:
1043 *val = bgep->param_adv_100hdx;
1044 break;
1045
1046 case ETHER_STAT_ADV_CAP_10FDX:
1047 *val = bgep->param_adv_10fdx;
1048 break;
1049
1050 case ETHER_STAT_ADV_CAP_10HDX:
1051 *val = bgep->param_adv_10hdx;
1052 break;
1053
1054 case ETHER_STAT_ADV_CAP_ASMPAUSE:
1055 *val = bgep->param_adv_asym_pause;
1056 break;
1057
1058 case ETHER_STAT_ADV_CAP_PAUSE:
1059 *val = bgep->param_adv_pause;
1060 break;
1061
1062 case ETHER_STAT_ADV_CAP_AUTONEG:
1063 *val = bgep->param_adv_autoneg;
1064 break;
1065
1066 #if (MAC_VERSION > 1)
1067 case ETHER_STAT_ADV_REMFAULT:
1068 if (bgep->chipid.flags & CHIP_FLAG_SERDES)
1069 *val = 0;
1070 else {
1071 mutex_enter(bgep->genlock);
1072 *val = bge_mii_get16(bgep, MII_AN_ADVERT) &
1073 MII_AN_ADVERT_REMFAULT ? 1 : 0;
1074 if (bge_check_acc_handle(bgep, bgep->io_handle) !=
1075 DDI_FM_OK) {
1076 ddi_fm_service_impact(bgep->devinfo,
1077 DDI_SERVICE_UNAFFECTED);
1078 }
1079 mutex_exit(bgep->genlock);
1080 }
1081 break;
1082 #endif
1083
1084 case ETHER_STAT_LP_CAP_1000FDX:
1085 *val = bgep->param_lp_1000fdx;
1086 break;
1087
1088 case ETHER_STAT_LP_CAP_1000HDX:
1089 *val = bgep->param_lp_1000hdx;
1090 break;
1091
1092 case ETHER_STAT_LP_CAP_100FDX:
1093 *val = bgep->param_lp_100fdx;
1094 break;
1095
1096 case ETHER_STAT_LP_CAP_100HDX:
1097 *val = bgep->param_lp_100hdx;
1098 break;
1099
1100 case ETHER_STAT_LP_CAP_10FDX:
1101 *val = bgep->param_lp_10fdx;
1102 break;
1103
1104 case ETHER_STAT_LP_CAP_10HDX:
1105 *val = bgep->param_lp_10hdx;
1106 break;
1107
1108 case ETHER_STAT_LP_CAP_ASMPAUSE:
1109 *val = bgep->param_lp_asym_pause;
1110 break;
1111
1112 case ETHER_STAT_LP_CAP_PAUSE:
1113 *val = bgep->param_lp_pause;
1114 break;
1115
1116 case ETHER_STAT_LP_CAP_AUTONEG:
1117 *val = bgep->param_lp_autoneg;
1118 break;
1119
1120 #if (MAC_VERSION > 1)
1121 case ETHER_STAT_LP_REMFAULT:
1122 if (bgep->chipid.flags & CHIP_FLAG_SERDES)
1123 *val = 0;
1124 else {
1125 mutex_enter(bgep->genlock);
1126 *val = bge_mii_get16(bgep, MII_AN_LPABLE) &
1127 MII_AN_ADVERT_REMFAULT ? 1 : 0;
1128 if (bge_check_acc_handle(bgep, bgep->io_handle) !=
1129 DDI_FM_OK) {
1130 ddi_fm_service_impact(bgep->devinfo,
1131 DDI_SERVICE_UNAFFECTED);
1132 }
1133 mutex_exit(bgep->genlock);
1134 }
1135 break;
1136 #endif
1137
1138 case ETHER_STAT_LINK_ASMPAUSE:
1139 *val = bgep->param_adv_asym_pause &&
1140 bgep->param_lp_asym_pause &&
1141 bgep->param_adv_pause != bgep->param_lp_pause;
1142 break;
1143
1144 case ETHER_STAT_LINK_PAUSE:
1145 *val = bgep->param_link_rx_pause;
1146 break;
1147
1148 case ETHER_STAT_LINK_AUTONEG:
1149 *val = bgep->param_link_autoneg;
1150 break;
1151
1152 case ETHER_STAT_LINK_DUPLEX:
1153 *val = (bgep->link_state != LINK_STATE_UNKNOWN) ?
1154 bgep->param_link_duplex : LINK_DUPLEX_UNKNOWN;
1155 break;
1156
1157 default:
1158 return (ENOTSUP);
1159 }
1160
1161 return (0);
1162 }
1163
1164 /*
1165 * Retrieve a value for one of the statistics for a particular rx ring
1166 */
1167 int
bge_rx_ring_stat(mac_ring_driver_t rh,uint_t stat,uint64_t * val)1168 bge_rx_ring_stat(mac_ring_driver_t rh, uint_t stat, uint64_t *val)
1169 {
1170 recv_ring_t *rx_ring = (recv_ring_t *)rh;
1171
1172 switch (stat) {
1173 case MAC_STAT_RBYTES:
1174 *val = rx_ring->rx_bytes;
1175 break;
1176
1177 case MAC_STAT_IPACKETS:
1178 *val = rx_ring->rx_pkts;
1179 break;
1180
1181 default:
1182 *val = 0;
1183 return (ENOTSUP);
1184 }
1185
1186 return (0);
1187 }
1188