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
ixgbe_read_tor_value(const struct ixgbe_hw * hw)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
ixgbe_read_qor_value(const struct ixgbe_hw * hw)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
ixgbe_read_qot_value(const struct ixgbe_hw * hw)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
ixgbe_read_got_value(const struct ixgbe_hw * hw)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
ixgbe_read_gor_value(const struct ixgbe_hw * hw)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
ixgbe_update_stats(kstat_t * ks,int rw)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
ixgbe_init_stats(ixgbe_t * ixgbe)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
ixgbe_m_stat(void * arg,uint_t stat,uint64_t * val)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 *val = (uint64_t)ixgbe_phy_to_media(ixgbe);
620 break;
621
622 case ETHER_STAT_CAP_10GFDX:
623 *val = (speeds & IXGBE_LINK_SPEED_10GB_FULL) ? 1 : 0;
624 break;
625
626 case ETHER_STAT_CAP_5000FDX:
627 *val = (speeds & IXGBE_LINK_SPEED_5GB_FULL) ? 1 : 0;
628 break;
629
630 case ETHER_STAT_CAP_2500FDX:
631 *val = (speeds & IXGBE_LINK_SPEED_2_5GB_FULL) ? 1 : 0;
632 break;
633
634 case ETHER_STAT_CAP_1000FDX:
635 *val = (speeds & IXGBE_LINK_SPEED_1GB_FULL) ? 1 : 0;
636 break;
637
638 case ETHER_STAT_CAP_100FDX:
639 *val = (speeds & IXGBE_LINK_SPEED_100_FULL) ? 1 : 0;
640 break;
641
642 case ETHER_STAT_CAP_ASMPAUSE:
643 *val = ixgbe->param_asym_pause_cap;
644 break;
645
646 case ETHER_STAT_CAP_PAUSE:
647 *val = ixgbe->param_pause_cap;
648 break;
649
650 case ETHER_STAT_CAP_AUTONEG:
651 *val = 1;
652 break;
653
654 case ETHER_STAT_ADV_CAP_10GFDX:
655 *val = ixgbe->param_adv_10000fdx_cap;
656 break;
657
658 case ETHER_STAT_ADV_CAP_5000FDX:
659 *val = ixgbe->param_adv_5000fdx_cap;
660 break;
661
662 case ETHER_STAT_ADV_CAP_2500FDX:
663 *val = ixgbe->param_adv_2500fdx_cap;
664 break;
665
666 case ETHER_STAT_ADV_CAP_1000FDX:
667 *val = ixgbe->param_adv_1000fdx_cap;
668 break;
669
670 case ETHER_STAT_ADV_CAP_100FDX:
671 *val = ixgbe->param_adv_100fdx_cap;
672 break;
673
674 case ETHER_STAT_ADV_CAP_ASMPAUSE:
675 *val = ixgbe->param_adv_asym_pause_cap;
676 break;
677
678 case ETHER_STAT_ADV_CAP_PAUSE:
679 *val = ixgbe->param_adv_pause_cap;
680 break;
681
682 case ETHER_STAT_ADV_CAP_AUTONEG:
683 *val = ixgbe->param_adv_autoneg_cap;
684 break;
685
686 case ETHER_STAT_LP_CAP_10GFDX:
687 *val = ixgbe->param_lp_10000fdx_cap;
688 break;
689
690 case ETHER_STAT_LP_CAP_5000FDX:
691 *val = ixgbe->param_lp_5000fdx_cap;
692 break;
693
694 case ETHER_STAT_LP_CAP_2500FDX:
695 *val = ixgbe->param_lp_2500fdx_cap;
696 break;
697
698 case ETHER_STAT_LP_CAP_1000FDX:
699 *val = ixgbe->param_lp_1000fdx_cap;
700 break;
701
702 case ETHER_STAT_LP_CAP_100FDX:
703 *val = ixgbe->param_lp_100fdx_cap;
704 break;
705
706 case ETHER_STAT_LP_CAP_ASMPAUSE:
707 *val = ixgbe->param_lp_asym_pause_cap;
708 break;
709
710 case ETHER_STAT_LP_CAP_PAUSE:
711 *val = ixgbe->param_lp_pause_cap;
712 break;
713
714 case ETHER_STAT_LP_CAP_AUTONEG:
715 *val = ixgbe->param_lp_autoneg_cap;
716 break;
717
718 case ETHER_STAT_LINK_ASMPAUSE:
719 *val = ixgbe->param_asym_pause_cap;
720 break;
721
722 case ETHER_STAT_LINK_PAUSE:
723 *val = ixgbe->param_pause_cap;
724 break;
725
726 case ETHER_STAT_LINK_AUTONEG:
727 *val = ixgbe->param_adv_autoneg_cap;
728 break;
729
730 case ETHER_STAT_LINK_DUPLEX:
731 *val = ixgbe->link_duplex;
732 break;
733
734 case ETHER_STAT_TOOSHORT_ERRORS:
735 ixgbe_ks->ruc.value.ui64 +=
736 IXGBE_READ_REG(hw, IXGBE_RUC);
737 *val = ixgbe_ks->ruc.value.ui64;
738 break;
739
740 case ETHER_STAT_CAP_REMFAULT:
741 *val = ixgbe->param_rem_fault;
742 break;
743
744 case ETHER_STAT_ADV_REMFAULT:
745 *val = ixgbe->param_adv_rem_fault;
746 break;
747
748 case ETHER_STAT_LP_REMFAULT:
749 *val = ixgbe->param_lp_rem_fault;
750 break;
751
752 case ETHER_STAT_JABBER_ERRORS:
753 ixgbe_ks->rjc.value.ui64 +=
754 IXGBE_READ_REG(hw, IXGBE_RJC);
755 *val = ixgbe_ks->rjc.value.ui64;
756 break;
757
758 default:
759 mutex_exit(&ixgbe->gen_lock);
760 return (ENOTSUP);
761 }
762
763 mutex_exit(&ixgbe->gen_lock);
764
765 if (ixgbe_check_acc_handle(ixgbe->osdep.reg_handle) != DDI_FM_OK) {
766 ddi_fm_service_impact(ixgbe->dip, DDI_SERVICE_DEGRADED);
767 return (EIO);
768 }
769
770 return (0);
771 }
772
773 /*
774 * Retrieve a value for one of the statistics for a particular rx ring
775 */
776 int
ixgbe_rx_ring_stat(mac_ring_driver_t rh,uint_t stat,uint64_t * val)777 ixgbe_rx_ring_stat(mac_ring_driver_t rh, uint_t stat, uint64_t *val)
778 {
779 ixgbe_rx_ring_t *rx_ring = (ixgbe_rx_ring_t *)rh;
780 ixgbe_t *ixgbe = rx_ring->ixgbe;
781
782 if (ixgbe->ixgbe_state & IXGBE_SUSPENDED) {
783 return (ECANCELED);
784 }
785
786 switch (stat) {
787 case MAC_STAT_RBYTES:
788 *val = rx_ring->stat_rbytes;
789 break;
790
791 case MAC_STAT_IPACKETS:
792 *val = rx_ring->stat_ipackets;
793 break;
794
795 default:
796 *val = 0;
797 return (ENOTSUP);
798 }
799
800 return (0);
801 }
802
803 /*
804 * Retrieve a value for one of the statistics for a particular tx ring
805 */
806 int
ixgbe_tx_ring_stat(mac_ring_driver_t rh,uint_t stat,uint64_t * val)807 ixgbe_tx_ring_stat(mac_ring_driver_t rh, uint_t stat, uint64_t *val)
808 {
809 ixgbe_tx_ring_t *tx_ring = (ixgbe_tx_ring_t *)rh;
810 ixgbe_t *ixgbe = tx_ring->ixgbe;
811
812 if (ixgbe->ixgbe_state & IXGBE_SUSPENDED) {
813 return (ECANCELED);
814 }
815
816 switch (stat) {
817 case MAC_STAT_OBYTES:
818 *val = tx_ring->stat_obytes;
819 break;
820
821 case MAC_STAT_OPACKETS:
822 *val = tx_ring->stat_opackets;
823 break;
824
825 default:
826 *val = 0;
827 return (ENOTSUP);
828 }
829
830 return (0);
831 }
832