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) 2007-2010 Intel Corporation. All rights reserved.
24 */
25
26 /*
27 * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
28 * Copyright 2012 Nexenta Systems, Inc. All rights reserved.
29 * Copyright 2016 OmniTI Computer Consulting, Inc. All rights reserved.
30 * Copyright 2019 Joyent, Inc.
31 */
32
33 #include "ixgbe_sw.h"
34
35 /*
36 * The 82598 controller lacks a high/low register for the various
37 * octet counters, but the common code also lacks a definition for
38 * these older registers. In these cases, the high register address
39 * maps to the appropriate address in the 82598 controller.
40 */
41 #define IXGBE_TOR IXGBE_TORH
42 #define IXGBE_GOTC IXGBE_GOTCH
43 #define IXGBE_GORC IXGBE_GORCH
44
45 /*
46 * Read total octets received.
47 */
48 static uint64_t
49 ixgbe_read_tor_value(const struct ixgbe_hw *hw)
50 {
51 uint64_t tor = 0;
52 uint64_t hi = 0, lo = 0;
53
54 switch (hw->mac.type) {
55 case ixgbe_mac_82598EB:
56 tor = IXGBE_READ_REG(hw, IXGBE_TOR);
57 break;
58
59 default:
60 lo = IXGBE_READ_REG(hw, IXGBE_TORL);
61 hi = IXGBE_READ_REG(hw, IXGBE_TORH) & 0xF;
62 tor = (hi << 32) + lo;
63 break;
64 }
65
66 return (tor);
67 }
68
69 /*
70 * Read queue octets received.
71 */
72 static uint64_t
73 ixgbe_read_qor_value(const struct ixgbe_hw *hw)
74 {
75 uint64_t qor = 0;
76 uint64_t hi = 0, lo = 0;
77
78 switch (hw->mac.type) {
79 case ixgbe_mac_82598EB:
80 qor = IXGBE_READ_REG(hw, IXGBE_QBRC(0));
81 break;
82
83 default:
84 lo = IXGBE_READ_REG(hw, IXGBE_QBRC_L(0));
85 hi = IXGBE_READ_REG(hw, IXGBE_QBRC_H(0)) & 0xF;
86 qor = (hi << 32) + lo;
87 break;
88 }
89
90 return (qor);
91 }
92
93 /*
94 * Read queue octets transmitted.
95 */
96 static uint64_t
97 ixgbe_read_qot_value(const struct ixgbe_hw *hw)
98 {
99 uint64_t qot = 0;
100 uint64_t hi = 0, lo = 0;
101
102 switch (hw->mac.type) {
103 case ixgbe_mac_82598EB:
104 qot = IXGBE_READ_REG(hw, IXGBE_QBTC(0));
105 break;
106
107 default:
108 lo = IXGBE_READ_REG(hw, IXGBE_QBTC_L(0));
109 hi = IXGBE_READ_REG(hw, IXGBE_QBTC_H(0)) & 0xF;
110 qot = (hi << 32) + lo;
111 break;
112 }
113
114 return (qot);
115 }
116
117 /*
118 * Read good octets transmitted.
119 */
120 static uint64_t
121 ixgbe_read_got_value(const struct ixgbe_hw *hw)
122 {
123 uint64_t got = 0;
124 uint64_t hi = 0, lo = 0;
125
126 switch (hw->mac.type) {
127 case ixgbe_mac_82598EB:
128 got = IXGBE_READ_REG(hw, IXGBE_GOTC);
129 break;
130
131 default:
132 lo = IXGBE_READ_REG(hw, IXGBE_GOTCL);
133 hi = IXGBE_READ_REG(hw, IXGBE_GOTCH) & 0xF;
134 got = (hi << 32) + lo;
135 break;
136 }
137
138 return (got);
139 }
140
141 /*
142 * Read good octets received.
143 */
144 static uint64_t
145 ixgbe_read_gor_value(const struct ixgbe_hw *hw)
146 {
147 uint64_t gor = 0;
148 uint64_t hi = 0, lo = 0;
149
150 switch (hw->mac.type) {
151 case ixgbe_mac_82598EB:
152 gor = IXGBE_READ_REG(hw, IXGBE_GORC);
153 break;
154
155 default:
156 lo = IXGBE_READ_REG(hw, IXGBE_GORCL);
157 hi = IXGBE_READ_REG(hw, IXGBE_GORCH) & 0xF;
158 gor = (hi << 32) + lo;
159 break;
160 }
161
162 return (gor);
163 }
164
165 /*
166 * Update driver private statistics.
167 */
168 static int
169 ixgbe_update_stats(kstat_t *ks, int rw)
170 {
171 ixgbe_t *ixgbe;
172 struct ixgbe_hw *hw;
173 ixgbe_stat_t *ixgbe_ks;
174 int i;
175
176 if (rw == KSTAT_WRITE)
177 return (EACCES);
178
179 ixgbe = (ixgbe_t *)ks->ks_private;
180 ixgbe_ks = (ixgbe_stat_t *)ks->ks_data;
181 hw = &ixgbe->hw;
182
183 mutex_enter(&ixgbe->gen_lock);
184
185 /*
186 * Basic information
187 */
188 ixgbe_ks->link_speed.value.ui64 = ixgbe->link_speed;
189 ixgbe_ks->reset_count.value.ui64 = ixgbe->reset_count;
190 ixgbe_ks->lroc.value.ui64 = ixgbe->lro_pkt_count;
191
192 ixgbe_ks->rx_frame_error.value.ui64 = 0;
193 ixgbe_ks->rx_cksum_error.value.ui64 = 0;
194 ixgbe_ks->rx_exceed_pkt.value.ui64 = 0;
195 for (i = 0; i < ixgbe->num_rx_rings; i++) {
196 ixgbe_ks->rx_frame_error.value.ui64 +=
197 ixgbe->rx_rings[i].stat_frame_error;
198 ixgbe_ks->rx_cksum_error.value.ui64 +=
199 ixgbe->rx_rings[i].stat_cksum_error;
200 ixgbe_ks->rx_exceed_pkt.value.ui64 +=
201 ixgbe->rx_rings[i].stat_exceed_pkt;
202 }
203
204 ixgbe_ks->tx_overload.value.ui64 = 0;
205 ixgbe_ks->tx_fail_no_tbd.value.ui64 = 0;
206 ixgbe_ks->tx_fail_no_tcb.value.ui64 = 0;
207 ixgbe_ks->tx_fail_dma_bind.value.ui64 = 0;
208 ixgbe_ks->tx_reschedule.value.ui64 = 0;
209 ixgbe_ks->tx_break_tbd_limit.value.ui64 = 0;
210 ixgbe_ks->tx_lso_header_fail.value.ui64 = 0;
211 for (i = 0; i < ixgbe->num_tx_rings; i++) {
212 ixgbe_ks->tx_overload.value.ui64 +=
213 ixgbe->tx_rings[i].stat_overload;
214 ixgbe_ks->tx_fail_no_tbd.value.ui64 +=
215 ixgbe->tx_rings[i].stat_fail_no_tbd;
216 ixgbe_ks->tx_fail_no_tcb.value.ui64 +=
217 ixgbe->tx_rings[i].stat_fail_no_tcb;
218 ixgbe_ks->tx_fail_dma_bind.value.ui64 +=
219 ixgbe->tx_rings[i].stat_fail_dma_bind;
220 ixgbe_ks->tx_reschedule.value.ui64 +=
221 ixgbe->tx_rings[i].stat_reschedule;
222 ixgbe_ks->tx_break_tbd_limit.value.ui64 +=
223 ixgbe->tx_rings[i].stat_break_tbd_limit;
224 ixgbe_ks->tx_lso_header_fail.value.ui64 +=
225 ixgbe->tx_rings[i].stat_lso_header_fail;
226 }
227
228 /*
229 * Hardware calculated statistics.
230 */
231 ixgbe_ks->gprc.value.ui64 += IXGBE_READ_REG(hw, IXGBE_GPRC);
232 ixgbe_ks->gptc.value.ui64 += IXGBE_READ_REG(hw, IXGBE_GPTC);
233 ixgbe_ks->gor.value.ui64 += ixgbe_read_gor_value(hw);
234 ixgbe_ks->got.value.ui64 += ixgbe_read_got_value(hw);
235 ixgbe_ks->qpr.value.ui64 += IXGBE_READ_REG(hw, IXGBE_QPRC(0));
236 ixgbe_ks->qpt.value.ui64 += IXGBE_READ_REG(hw, IXGBE_QPTC(0));
237 ixgbe_ks->qor.value.ui64 += ixgbe_read_qor_value(hw);
238 ixgbe_ks->qot.value.ui64 += ixgbe_read_qot_value(hw);
239 ixgbe_ks->tor.value.ui64 += ixgbe_read_tor_value(hw);
240 ixgbe_ks->tot.value.ui64 = ixgbe_ks->got.value.ui64;
241
242 ixgbe_ks->prc64.value.ul += IXGBE_READ_REG(hw, IXGBE_PRC64);
243 ixgbe_ks->prc127.value.ul += IXGBE_READ_REG(hw, IXGBE_PRC127);
244 ixgbe_ks->prc255.value.ul += IXGBE_READ_REG(hw, IXGBE_PRC255);
245 ixgbe_ks->prc511.value.ul += IXGBE_READ_REG(hw, IXGBE_PRC511);
246 ixgbe_ks->prc1023.value.ul += IXGBE_READ_REG(hw, IXGBE_PRC1023);
247 ixgbe_ks->prc1522.value.ul += IXGBE_READ_REG(hw, IXGBE_PRC1522);
248 ixgbe_ks->ptc64.value.ul += IXGBE_READ_REG(hw, IXGBE_PTC64);
249 ixgbe_ks->ptc127.value.ul += IXGBE_READ_REG(hw, IXGBE_PTC127);
250 ixgbe_ks->ptc255.value.ul += IXGBE_READ_REG(hw, IXGBE_PTC255);
251 ixgbe_ks->ptc511.value.ul += IXGBE_READ_REG(hw, IXGBE_PTC511);
252 ixgbe_ks->ptc1023.value.ul += IXGBE_READ_REG(hw, IXGBE_PTC1023);
253 ixgbe_ks->ptc1522.value.ul += IXGBE_READ_REG(hw, IXGBE_PTC1522);
254
255 ixgbe_ks->mspdc.value.ui64 += IXGBE_READ_REG(hw, IXGBE_MSPDC);
256 for (i = 0; i < 8; i++)
257 ixgbe_ks->mpc.value.ui64 += IXGBE_READ_REG(hw, IXGBE_MPC(i));
258 ixgbe_ks->mlfc.value.ui64 += IXGBE_READ_REG(hw, IXGBE_MLFC);
259 ixgbe_ks->mrfc.value.ui64 += IXGBE_READ_REG(hw, IXGBE_MRFC);
260 ixgbe_ks->rlec.value.ui64 += IXGBE_READ_REG(hw, IXGBE_RLEC);
261 ixgbe_ks->lxontxc.value.ui64 += IXGBE_READ_REG(hw, IXGBE_LXONTXC);
262 switch (hw->mac.type) {
263 case ixgbe_mac_82598EB:
264 ixgbe_ks->lxonrxc.value.ui64 += IXGBE_READ_REG(hw,
265 IXGBE_LXONRXC);
266 break;
267
268 case ixgbe_mac_82599EB:
269 case ixgbe_mac_X540:
270 case ixgbe_mac_X550:
271 case ixgbe_mac_X550EM_x:
272 case ixgbe_mac_X550EM_a:
273 ixgbe_ks->lxonrxc.value.ui64 += IXGBE_READ_REG(hw,
274 IXGBE_LXONRXCNT);
275 break;
276
277 default:
278 break;
279 }
280 ixgbe_ks->lxofftxc.value.ui64 += IXGBE_READ_REG(hw, IXGBE_LXOFFTXC);
281 switch (hw->mac.type) {
282 case ixgbe_mac_82598EB:
283 ixgbe_ks->lxoffrxc.value.ui64 += IXGBE_READ_REG(hw,
284 IXGBE_LXOFFRXC);
285 break;
286
287 case ixgbe_mac_82599EB:
288 case ixgbe_mac_X540:
289 case ixgbe_mac_X550:
290 case ixgbe_mac_X550EM_x:
291 case ixgbe_mac_X550EM_a:
292 ixgbe_ks->lxoffrxc.value.ui64 += IXGBE_READ_REG(hw,
293 IXGBE_LXOFFRXCNT);
294 break;
295
296 default:
297 break;
298 }
299 ixgbe_ks->ruc.value.ui64 += IXGBE_READ_REG(hw, IXGBE_RUC);
300 ixgbe_ks->rfc.value.ui64 += IXGBE_READ_REG(hw, IXGBE_RFC);
301 ixgbe_ks->roc.value.ui64 += IXGBE_READ_REG(hw, IXGBE_ROC);
302 ixgbe_ks->rjc.value.ui64 += IXGBE_READ_REG(hw, IXGBE_RJC);
303
304 mutex_exit(&ixgbe->gen_lock);
305
306 if (ixgbe_check_acc_handle(ixgbe->osdep.reg_handle) != DDI_FM_OK)
307 ddi_fm_service_impact(ixgbe->dip, DDI_SERVICE_UNAFFECTED);
308
309 return (0);
310 }
311
312 /*
313 * Create and initialize the driver private statistics.
314 */
315 int
316 ixgbe_init_stats(ixgbe_t *ixgbe)
317 {
318 kstat_t *ks;
319 ixgbe_stat_t *ixgbe_ks;
320
321 /*
322 * Create and init kstat
323 */
324 ks = kstat_create(MODULE_NAME, ddi_get_instance(ixgbe->dip),
325 "statistics", "net", KSTAT_TYPE_NAMED,
326 sizeof (ixgbe_stat_t) / sizeof (kstat_named_t), 0);
327
328 if (ks == NULL) {
329 ixgbe_error(ixgbe,
330 "Could not create kernel statistics");
331 return (IXGBE_FAILURE);
332 }
333
334 ixgbe->ixgbe_ks = ks;
335
336 ixgbe_ks = (ixgbe_stat_t *)ks->ks_data;
337
338 /*
339 * Initialize all the statistics.
340 */
341 kstat_named_init(&ixgbe_ks->link_speed, "link_speed",
342 KSTAT_DATA_UINT64);
343 kstat_named_init(&ixgbe_ks->reset_count, "reset_count",
344 KSTAT_DATA_UINT64);
345
346 kstat_named_init(&ixgbe_ks->rx_frame_error, "rx_frame_error",
347 KSTAT_DATA_UINT64);
348 kstat_named_init(&ixgbe_ks->rx_cksum_error, "rx_cksum_error",
349 KSTAT_DATA_UINT64);
350 kstat_named_init(&ixgbe_ks->rx_exceed_pkt, "rx_exceed_pkt",
351 KSTAT_DATA_UINT64);
352 kstat_named_init(&ixgbe_ks->tx_overload, "tx_overload",
353 KSTAT_DATA_UINT64);
354 kstat_named_init(&ixgbe_ks->tx_fail_no_tbd, "tx_fail_no_tbd",
355 KSTAT_DATA_UINT64);
356 kstat_named_init(&ixgbe_ks->tx_fail_no_tcb, "tx_fail_no_tcb",
357 KSTAT_DATA_UINT64);
358 kstat_named_init(&ixgbe_ks->tx_fail_dma_bind, "tx_fail_dma_bind",
359 KSTAT_DATA_UINT64);
360 kstat_named_init(&ixgbe_ks->tx_reschedule, "tx_reschedule",
361 KSTAT_DATA_UINT64);
362 kstat_named_init(&ixgbe_ks->tx_break_tbd_limit, "tx_break_tbd_limit",
363 KSTAT_DATA_UINT64);
364 kstat_named_init(&ixgbe_ks->tx_lso_header_fail, "tx_lso_header_fail",
365 KSTAT_DATA_UINT64);
366
367 kstat_named_init(&ixgbe_ks->gprc, "good_pkts_recvd",
368 KSTAT_DATA_UINT64);
369 kstat_named_init(&ixgbe_ks->gptc, "good_pkts_xmitd",
370 KSTAT_DATA_UINT64);
371 kstat_named_init(&ixgbe_ks->gor, "good_octets_recvd",
372 KSTAT_DATA_UINT64);
373 kstat_named_init(&ixgbe_ks->got, "good_octets_xmitd",
374 KSTAT_DATA_UINT64);
375 kstat_named_init(&ixgbe_ks->qor, "queue_octets_recvd",
376 KSTAT_DATA_UINT64);
377 kstat_named_init(&ixgbe_ks->qot, "queue_octets_xmitd",
378 KSTAT_DATA_UINT64);
379 kstat_named_init(&ixgbe_ks->qpr, "queue_pkts_recvd",
380 KSTAT_DATA_UINT64);
381 kstat_named_init(&ixgbe_ks->qpt, "queue_pkts_xmitd",
382 KSTAT_DATA_UINT64);
383 kstat_named_init(&ixgbe_ks->prc64, "pkts_recvd_( 64b)",
384 KSTAT_DATA_UINT64);
385 kstat_named_init(&ixgbe_ks->prc127, "pkts_recvd_( 65- 127b)",
386 KSTAT_DATA_UINT64);
387 kstat_named_init(&ixgbe_ks->prc255, "pkts_recvd_( 127- 255b)",
388 KSTAT_DATA_UINT64);
389 kstat_named_init(&ixgbe_ks->prc511, "pkts_recvd_( 256- 511b)",
390 KSTAT_DATA_UINT64);
391 kstat_named_init(&ixgbe_ks->prc1023, "pkts_recvd_( 511-1023b)",
392 KSTAT_DATA_UINT64);
393 kstat_named_init(&ixgbe_ks->prc1522, "pkts_recvd_(1024-1522b)",
394 KSTAT_DATA_UINT64);
395 kstat_named_init(&ixgbe_ks->ptc64, "pkts_xmitd_( 64b)",
396 KSTAT_DATA_UINT64);
397 kstat_named_init(&ixgbe_ks->ptc127, "pkts_xmitd_( 65- 127b)",
398 KSTAT_DATA_UINT64);
399 kstat_named_init(&ixgbe_ks->ptc255, "pkts_xmitd_( 128- 255b)",
400 KSTAT_DATA_UINT64);
401 kstat_named_init(&ixgbe_ks->ptc511, "pkts_xmitd_( 255- 511b)",
402 KSTAT_DATA_UINT64);
403 kstat_named_init(&ixgbe_ks->ptc1023, "pkts_xmitd_( 512-1023b)",
404 KSTAT_DATA_UINT64);
405 kstat_named_init(&ixgbe_ks->ptc1522, "pkts_xmitd_(1024-1522b)",
406 KSTAT_DATA_UINT64);
407
408 kstat_named_init(&ixgbe_ks->mspdc, "mac_short_packet_discard",
409 KSTAT_DATA_UINT64);
410 kstat_named_init(&ixgbe_ks->mpc, "missed_packets",
411 KSTAT_DATA_UINT64);
412 kstat_named_init(&ixgbe_ks->mlfc, "mac_local_fault",
413 KSTAT_DATA_UINT64);
414 kstat_named_init(&ixgbe_ks->mrfc, "mac_remote_fault",
415 KSTAT_DATA_UINT64);
416 kstat_named_init(&ixgbe_ks->rlec, "recv_length_err",
417 KSTAT_DATA_UINT64);
418 kstat_named_init(&ixgbe_ks->lxontxc, "link_xon_xmitd",
419 KSTAT_DATA_UINT64);
420 kstat_named_init(&ixgbe_ks->lxonrxc, "link_xon_recvd",
421 KSTAT_DATA_UINT64);
422 kstat_named_init(&ixgbe_ks->lxofftxc, "link_xoff_xmitd",
423 KSTAT_DATA_UINT64);
424 kstat_named_init(&ixgbe_ks->lxoffrxc, "link_xoff_recvd",
425 KSTAT_DATA_UINT64);
426 kstat_named_init(&ixgbe_ks->ruc, "recv_undersize",
427 KSTAT_DATA_UINT64);
428 kstat_named_init(&ixgbe_ks->rfc, "recv_fragment",
429 KSTAT_DATA_UINT64);
430 kstat_named_init(&ixgbe_ks->roc, "recv_oversize",
431 KSTAT_DATA_UINT64);
432 kstat_named_init(&ixgbe_ks->rjc, "recv_jabber",
433 KSTAT_DATA_UINT64);
434 kstat_named_init(&ixgbe_ks->rnbc, "recv_no_buffer",
435 KSTAT_DATA_UINT64);
436 kstat_named_init(&ixgbe_ks->lroc, "lro_pkt_count",
437 KSTAT_DATA_UINT64);
438
439 kstat_named_init(&ixgbe_ks->dev_gone, "device_gone",
440 KSTAT_DATA_UINT64);
441 /*
442 * Function to provide kernel stat update on demand
443 */
444 ks->ks_update = ixgbe_update_stats;
445
446 ks->ks_private = (void *)ixgbe;
447
448 /*
449 * Add kstat to systems kstat chain
450 */
451 kstat_install(ks);
452
453 return (IXGBE_SUCCESS);
454 }
455
456 /*
457 * Retrieve a value for one of the statistics.
458 */
459 int
460 ixgbe_m_stat(void *arg, uint_t stat, uint64_t *val)
461 {
462 ixgbe_t *ixgbe = (ixgbe_t *)arg;
463 struct ixgbe_hw *hw = &ixgbe->hw;
464 ixgbe_stat_t *ixgbe_ks;
465 int i;
466 ixgbe_link_speed speeds = 0;
467
468 ixgbe_ks = (ixgbe_stat_t *)ixgbe->ixgbe_ks->ks_data;
469
470 mutex_enter(&ixgbe->gen_lock);
471
472 /*
473 * We cannot always rely on the common code maintaining
474 * hw->phy.speeds_supported, therefore we fall back to use the recorded
475 * supported speeds which were obtained during instance init in
476 * ixgbe_init_params().
477 */
478 speeds = hw->phy.speeds_supported;
479 if (speeds == 0)
480 speeds = ixgbe->speeds_supported;
481
482 if (ixgbe->ixgbe_state & IXGBE_SUSPENDED) {
483 mutex_exit(&ixgbe->gen_lock);
484 return (ECANCELED);
485 }
486
487 switch (stat) {
488 case MAC_STAT_IFSPEED:
489 *val = ixgbe->link_speed * 1000000ull;
490 break;
491
492 case MAC_STAT_MULTIRCV:
493 ixgbe_ks->mprc.value.ui64 +=
494 IXGBE_READ_REG(hw, IXGBE_MPRC);
495 *val = ixgbe_ks->mprc.value.ui64;
496 break;
497
498 case MAC_STAT_BRDCSTRCV:
499 ixgbe_ks->bprc.value.ui64 +=
500 IXGBE_READ_REG(hw, IXGBE_BPRC);
501 *val = ixgbe_ks->bprc.value.ui64;
502 break;
503
504 case MAC_STAT_MULTIXMT:
505 ixgbe_ks->mptc.value.ui64 +=
506 IXGBE_READ_REG(hw, IXGBE_MPTC);
507 *val = ixgbe_ks->mptc.value.ui64;
508 break;
509
510 case MAC_STAT_BRDCSTXMT:
511 ixgbe_ks->bptc.value.ui64 +=
512 IXGBE_READ_REG(hw, IXGBE_BPTC);
513 *val = ixgbe_ks->bptc.value.ui64;
514 break;
515
516 case MAC_STAT_NORCVBUF:
517 /*
518 * The QPRDC[0] register maps to the same kstat as the
519 * old RNBC register because they have equivalent
520 * semantics.
521 */
522 if (hw->mac.type == ixgbe_mac_82598EB) {
523 for (i = 0; i < 8; i++) {
524 ixgbe_ks->rnbc.value.ui64 +=
525 IXGBE_READ_REG(hw, IXGBE_RNBC(i));
526 }
527 } else {
528 ixgbe_ks->rnbc.value.ui64 +=
529 IXGBE_READ_REG(hw, IXGBE_QPRDC(0));
530 }
531
532 *val = ixgbe_ks->rnbc.value.ui64;
533 break;
534
535 case MAC_STAT_IERRORS:
536 ixgbe_ks->crcerrs.value.ui64 +=
537 IXGBE_READ_REG(hw, IXGBE_CRCERRS);
538 ixgbe_ks->illerrc.value.ui64 +=
539 IXGBE_READ_REG(hw, IXGBE_ILLERRC);
540 ixgbe_ks->errbc.value.ui64 +=
541 IXGBE_READ_REG(hw, IXGBE_ERRBC);
542 ixgbe_ks->rlec.value.ui64 +=
543 IXGBE_READ_REG(hw, IXGBE_RLEC);
544 *val = ixgbe_ks->crcerrs.value.ui64 +
545 ixgbe_ks->illerrc.value.ui64 +
546 ixgbe_ks->errbc.value.ui64 +
547 ixgbe_ks->rlec.value.ui64;
548 break;
549
550 case MAC_STAT_RBYTES:
551 ixgbe_ks->tor.value.ui64 += ixgbe_read_tor_value(hw);
552 *val = ixgbe_ks->tor.value.ui64;
553 break;
554
555 case MAC_STAT_OBYTES:
556 /*
557 * The controller does not provide a Total Octets
558 * Transmitted statistic. The closest thing we have is
559 * Good Octets Transmitted. This makes sense, as what
560 * does it mean to transmit a packet if it didn't
561 * actually transmit.
562 */
563 ixgbe_ks->got.value.ui64 += ixgbe_read_got_value(hw);
564 ixgbe_ks->tot.value.ui64 = ixgbe_ks->got.value.ui64;
565 *val = ixgbe_ks->tot.value.ui64;
566 break;
567
568 case MAC_STAT_IPACKETS:
569 ixgbe_ks->tpr.value.ui64 +=
570 IXGBE_READ_REG(hw, IXGBE_TPR);
571 *val = ixgbe_ks->tpr.value.ui64;
572 break;
573
574 case MAC_STAT_OPACKETS:
575 ixgbe_ks->tpt.value.ui64 +=
576 IXGBE_READ_REG(hw, IXGBE_TPT);
577 *val = ixgbe_ks->tpt.value.ui64;
578 break;
579
580 /* RFC 1643 stats */
581 case ETHER_STAT_FCS_ERRORS:
582 ixgbe_ks->crcerrs.value.ui64 +=
583 IXGBE_READ_REG(hw, IXGBE_CRCERRS);
584 *val = ixgbe_ks->crcerrs.value.ui64;
585 break;
586
587 case ETHER_STAT_TOOLONG_ERRORS:
588 ixgbe_ks->roc.value.ui64 +=
589 IXGBE_READ_REG(hw, IXGBE_ROC);
590 *val = ixgbe_ks->roc.value.ui64;
591 break;
592
593 case ETHER_STAT_MACRCV_ERRORS:
594 ixgbe_ks->crcerrs.value.ui64 +=
595 IXGBE_READ_REG(hw, IXGBE_CRCERRS);
596 ixgbe_ks->illerrc.value.ui64 +=
597 IXGBE_READ_REG(hw, IXGBE_ILLERRC);
598 ixgbe_ks->errbc.value.ui64 +=
599 IXGBE_READ_REG(hw, IXGBE_ERRBC);
600 ixgbe_ks->rlec.value.ui64 +=
601 IXGBE_READ_REG(hw, IXGBE_RLEC);
602 *val = ixgbe_ks->crcerrs.value.ui64 +
603 ixgbe_ks->illerrc.value.ui64 +
604 ixgbe_ks->errbc.value.ui64 +
605 ixgbe_ks->rlec.value.ui64;
606 break;
607
608 /* MII/GMII stats */
609 case ETHER_STAT_XCVR_ADDR:
610 /* The Internal PHY's MDI address for each MAC is 1 */
611 *val = 1;
612 break;
613
614 case ETHER_STAT_XCVR_ID:
615 *val = hw->phy.id;
616 break;
617
618 case ETHER_STAT_XCVR_INUSE:
619 switch (ixgbe->link_speed) {
620 case IXGBE_LINK_SPEED_1GB_FULL:
621 *val =
622 (hw->phy.media_type == ixgbe_media_type_copper) ?
623 XCVR_1000T : XCVR_1000X;
624 break;
625 case IXGBE_LINK_SPEED_100_FULL:
626 *val = (hw->phy.media_type == ixgbe_media_type_copper) ?
627 XCVR_100T2 : XCVR_100X;
628 break;
629 default:
630 *val = XCVR_NONE;
631 break;
632 }
633 break;
634
635 case ETHER_STAT_CAP_10GFDX:
636 *val = (speeds & IXGBE_LINK_SPEED_10GB_FULL) ? 1 : 0;
637 break;
638
639 case ETHER_STAT_CAP_5000FDX:
640 *val = (speeds & IXGBE_LINK_SPEED_5GB_FULL) ? 1 : 0;
641 break;
642
643 case ETHER_STAT_CAP_2500FDX:
644 *val = (speeds & IXGBE_LINK_SPEED_2_5GB_FULL) ? 1 : 0;
645 break;
646
647 case ETHER_STAT_CAP_1000FDX:
648 *val = (speeds & IXGBE_LINK_SPEED_1GB_FULL) ? 1 : 0;
649 break;
650
651 case ETHER_STAT_CAP_100FDX:
652 *val = (speeds & IXGBE_LINK_SPEED_100_FULL) ? 1 : 0;
653 break;
654
655 case ETHER_STAT_CAP_ASMPAUSE:
656 *val = ixgbe->param_asym_pause_cap;
657 break;
658
659 case ETHER_STAT_CAP_PAUSE:
660 *val = ixgbe->param_pause_cap;
661 break;
662
663 case ETHER_STAT_CAP_AUTONEG:
664 *val = 1;
665 break;
666
667 case ETHER_STAT_ADV_CAP_10GFDX:
668 *val = ixgbe->param_adv_10000fdx_cap;
669 break;
670
671 case ETHER_STAT_ADV_CAP_5000FDX:
672 *val = ixgbe->param_adv_5000fdx_cap;
673 break;
674
675 case ETHER_STAT_ADV_CAP_2500FDX:
676 *val = ixgbe->param_adv_2500fdx_cap;
677 break;
678
679 case ETHER_STAT_ADV_CAP_1000FDX:
680 *val = ixgbe->param_adv_1000fdx_cap;
681 break;
682
683 case ETHER_STAT_ADV_CAP_100FDX:
684 *val = ixgbe->param_adv_100fdx_cap;
685 break;
686
687 case ETHER_STAT_ADV_CAP_ASMPAUSE:
688 *val = ixgbe->param_adv_asym_pause_cap;
689 break;
690
691 case ETHER_STAT_ADV_CAP_PAUSE:
692 *val = ixgbe->param_adv_pause_cap;
693 break;
694
695 case ETHER_STAT_ADV_CAP_AUTONEG:
696 *val = ixgbe->param_adv_autoneg_cap;
697 break;
698
699 case ETHER_STAT_LP_CAP_10GFDX:
700 *val = ixgbe->param_lp_10000fdx_cap;
701 break;
702
703 case ETHER_STAT_LP_CAP_5000FDX:
704 *val = ixgbe->param_lp_5000fdx_cap;
705 break;
706
707 case ETHER_STAT_LP_CAP_2500FDX:
708 *val = ixgbe->param_lp_2500fdx_cap;
709 break;
710
711 case ETHER_STAT_LP_CAP_1000FDX:
712 *val = ixgbe->param_lp_1000fdx_cap;
713 break;
714
715 case ETHER_STAT_LP_CAP_100FDX:
716 *val = ixgbe->param_lp_100fdx_cap;
717 break;
718
719 case ETHER_STAT_LP_CAP_ASMPAUSE:
720 *val = ixgbe->param_lp_asym_pause_cap;
721 break;
722
723 case ETHER_STAT_LP_CAP_PAUSE:
724 *val = ixgbe->param_lp_pause_cap;
725 break;
726
727 case ETHER_STAT_LP_CAP_AUTONEG:
728 *val = ixgbe->param_lp_autoneg_cap;
729 break;
730
731 case ETHER_STAT_LINK_ASMPAUSE:
732 *val = ixgbe->param_asym_pause_cap;
733 break;
734
735 case ETHER_STAT_LINK_PAUSE:
736 *val = ixgbe->param_pause_cap;
737 break;
738
739 case ETHER_STAT_LINK_AUTONEG:
740 *val = ixgbe->param_adv_autoneg_cap;
741 break;
742
743 case ETHER_STAT_LINK_DUPLEX:
744 *val = ixgbe->link_duplex;
745 break;
746
747 case ETHER_STAT_TOOSHORT_ERRORS:
748 ixgbe_ks->ruc.value.ui64 +=
749 IXGBE_READ_REG(hw, IXGBE_RUC);
750 *val = ixgbe_ks->ruc.value.ui64;
751 break;
752
753 case ETHER_STAT_CAP_REMFAULT:
754 *val = ixgbe->param_rem_fault;
755 break;
756
757 case ETHER_STAT_ADV_REMFAULT:
758 *val = ixgbe->param_adv_rem_fault;
759 break;
760
761 case ETHER_STAT_LP_REMFAULT:
762 *val = ixgbe->param_lp_rem_fault;
763 break;
764
765 case ETHER_STAT_JABBER_ERRORS:
766 ixgbe_ks->rjc.value.ui64 +=
767 IXGBE_READ_REG(hw, IXGBE_RJC);
768 *val = ixgbe_ks->rjc.value.ui64;
769 break;
770
771 default:
772 mutex_exit(&ixgbe->gen_lock);
773 return (ENOTSUP);
774 }
775
776 mutex_exit(&ixgbe->gen_lock);
777
778 if (ixgbe_check_acc_handle(ixgbe->osdep.reg_handle) != DDI_FM_OK) {
779 ddi_fm_service_impact(ixgbe->dip, DDI_SERVICE_DEGRADED);
780 return (EIO);
781 }
782
783 return (0);
784 }
785
786 /*
787 * Retrieve a value for one of the statistics for a particular rx ring
788 */
789 int
790 ixgbe_rx_ring_stat(mac_ring_driver_t rh, uint_t stat, uint64_t *val)
791 {
792 ixgbe_rx_ring_t *rx_ring = (ixgbe_rx_ring_t *)rh;
793 ixgbe_t *ixgbe = rx_ring->ixgbe;
794
795 if (ixgbe->ixgbe_state & IXGBE_SUSPENDED) {
796 return (ECANCELED);
797 }
798
799 switch (stat) {
800 case MAC_STAT_RBYTES:
801 *val = rx_ring->stat_rbytes;
802 break;
803
804 case MAC_STAT_IPACKETS:
805 *val = rx_ring->stat_ipackets;
806 break;
807
808 default:
809 *val = 0;
810 return (ENOTSUP);
811 }
812
813 return (0);
814 }
815
816 /*
817 * Retrieve a value for one of the statistics for a particular tx ring
818 */
819 int
820 ixgbe_tx_ring_stat(mac_ring_driver_t rh, uint_t stat, uint64_t *val)
821 {
822 ixgbe_tx_ring_t *tx_ring = (ixgbe_tx_ring_t *)rh;
823 ixgbe_t *ixgbe = tx_ring->ixgbe;
824
825 if (ixgbe->ixgbe_state & IXGBE_SUSPENDED) {
826 return (ECANCELED);
827 }
828
829 switch (stat) {
830 case MAC_STAT_OBYTES:
831 *val = tx_ring->stat_obytes;
832 break;
833
834 case MAC_STAT_OPACKETS:
835 *val = tx_ring->stat_opackets;
836 break;
837
838 default:
839 *val = 0;
840 return (ENOTSUP);
841 }
842
843 return (0);
844 }