Merge commit '06307114472bd8aad5ff18ccdb8e25f128ae6652'
[unleashed.git] / kernel / drivers / net / e1000g / e1000g_stat.c
blobbe22c444ff43efcc93b248316241fc44cb051166
1 /*
2 * This file is provided under a CDDLv1 license. When using or
3 * redistributing this file, you may do so under this license.
4 * In redistributing this file this license must be included
5 * and no other modification of this header file is permitted.
7 * CDDL LICENSE SUMMARY
9 * Copyright(c) 1999 - 2009 Intel Corporation. All rights reserved.
11 * The contents of this file are subject to the terms of Version
12 * 1.0 of the Common Development and Distribution License (the "License").
14 * You should have received a copy of the License with this software.
15 * You can obtain a copy of the License at
16 * http://www.opensolaris.org/os/licensing.
17 * See the License for the specific language governing permissions
18 * and limitations under the License.
22 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
23 * Copyright 2012 David Höppner. All rights reserved.
24 * Use is subject to license terms.
28 * **********************************************************************
29 * *
30 * Module Name: e1000g_stat.c *
31 * *
32 * Abstract: Functions for processing statistics *
33 * *
34 * **********************************************************************
36 #include "e1000g_sw.h"
37 #include "e1000g_debug.h"
39 static int e1000g_update_stats(kstat_t *ksp, int rw);
40 static uint32_t e1000g_read_phy_stat(struct e1000_hw *hw, int reg);
43 * e1000_tbi_adjust_stats
45 * Adjusts statistic counters when a frame is accepted
46 * under the TBI workaround. This function has been
47 * adapted for Solaris from shared code.
49 void
50 e1000_tbi_adjust_stats(struct e1000g *Adapter,
51 uint32_t frame_len, uint8_t *mac_addr)
53 uint32_t carry_bit;
54 p_e1000g_stat_t e1000g_ksp;
56 e1000g_ksp = (p_e1000g_stat_t)Adapter->e1000g_ksp->ks_data;
58 /* First adjust the frame length */
59 frame_len--;
62 * We need to adjust the statistics counters, since the hardware
63 * counters overcount this packet as a CRC error and undercount
64 * the packet as a good packet
66 /* This packet should not be counted as a CRC error */
67 Adapter->fcs_errors--;
68 /* This packet does count as a Good Packet Received */
69 e1000g_ksp->Gprc.value.ul++;
72 * Adjust the Good Octets received counters
74 carry_bit = 0x80000000 & e1000g_ksp->Gorl.value.ul;
75 e1000g_ksp->Gorl.value.ul += frame_len;
77 * If the high bit of Gorcl (the low 32 bits of the Good Octets
78 * Received Count) was one before the addition,
79 * AND it is zero after, then we lost the carry out,
80 * need to add one to Gorch (Good Octets Received Count High).
81 * This could be simplified if all environments supported
82 * 64-bit integers.
84 if (carry_bit && ((e1000g_ksp->Gorl.value.ul & 0x80000000) == 0)) {
85 e1000g_ksp->Gorh.value.ul++;
88 * Is this a broadcast or multicast? Check broadcast first,
89 * since the test for a multicast frame will test positive on
90 * a broadcast frame.
92 if ((mac_addr[0] == (uint8_t)0xff) &&
93 (mac_addr[1] == (uint8_t)0xff)) {
95 * Broadcast packet
97 Adapter->brdcstrcv++;
98 } else if (*mac_addr & 0x01) {
100 * Multicast packet
102 Adapter->multircv++;
105 if (frame_len == Adapter->max_frame_size) {
107 * In this case, the hardware has overcounted the number of
108 * oversize frames.
110 if (Adapter->toolong_errors > 0)
111 Adapter->toolong_errors--;
114 #ifdef E1000G_DEBUG
116 * Adjust the bin counters when the extra byte put the frame in the
117 * wrong bin. Remember that the frame_len was adjusted above.
119 if (frame_len == 64) {
120 e1000g_ksp->Prc64.value.ul++;
121 e1000g_ksp->Prc127.value.ul--;
122 } else if (frame_len == 127) {
123 e1000g_ksp->Prc127.value.ul++;
124 e1000g_ksp->Prc255.value.ul--;
125 } else if (frame_len == 255) {
126 e1000g_ksp->Prc255.value.ul++;
127 e1000g_ksp->Prc511.value.ul--;
128 } else if (frame_len == 511) {
129 e1000g_ksp->Prc511.value.ul++;
130 e1000g_ksp->Prc1023.value.ul--;
131 } else if (frame_len == 1023) {
132 e1000g_ksp->Prc1023.value.ul++;
133 e1000g_ksp->Prc1522.value.ul--;
134 } else if (frame_len == 1522) {
135 e1000g_ksp->Prc1522.value.ul++;
137 #endif
142 * e1000g_update_stats - update driver private kstat counters
144 * This routine will dump and reset the e1000's internal
145 * statistics counters. The current stats dump values will
146 * be sent to the kernel status area.
148 static int
149 e1000g_update_stats(kstat_t *ksp, int rw)
151 struct e1000g *Adapter;
152 struct e1000_hw *hw;
153 p_e1000g_stat_t e1000g_ksp;
154 e1000g_tx_ring_t *tx_ring;
155 e1000g_rx_ring_t *rx_ring;
156 #ifdef E1000G_DEBUG
157 e1000g_rx_data_t *rx_data;
158 #endif
159 uint64_t val;
160 uint32_t low_val, high_val;
162 if (rw == KSTAT_WRITE)
163 return (EACCES);
165 Adapter = (struct e1000g *)ksp->ks_private;
166 ASSERT(Adapter != NULL);
167 e1000g_ksp = (p_e1000g_stat_t)ksp->ks_data;
168 ASSERT(e1000g_ksp != NULL);
169 hw = &Adapter->shared;
171 tx_ring = Adapter->tx_ring;
172 rx_ring = Adapter->rx_ring;
173 #ifdef E1000G_DEBUG
174 rx_data = rx_ring->rx_data;
175 #endif
177 rw_enter(&Adapter->chip_lock, RW_WRITER);
179 e1000g_ksp->reset_count.value.ul = Adapter->reset_count;
181 e1000g_ksp->rx_error.value.ul = rx_ring->stat_error;
182 e1000g_ksp->rx_allocb_fail.value.ul = rx_ring->stat_allocb_fail;
183 e1000g_ksp->rx_size_error.value.ul = rx_ring->stat_size_error;
185 e1000g_ksp->tx_no_swpkt.value.ul = tx_ring->stat_no_swpkt;
186 e1000g_ksp->tx_no_desc.value.ul = tx_ring->stat_no_desc;
187 e1000g_ksp->tx_send_fail.value.ul = tx_ring->stat_send_fail;
188 e1000g_ksp->tx_reschedule.value.ul = tx_ring->stat_reschedule;
189 e1000g_ksp->tx_over_size.value.ul = tx_ring->stat_over_size;
191 #ifdef E1000G_DEBUG
192 e1000g_ksp->rx_none.value.ul = rx_ring->stat_none;
193 e1000g_ksp->rx_multi_desc.value.ul = rx_ring->stat_multi_desc;
194 e1000g_ksp->rx_no_freepkt.value.ul = rx_ring->stat_no_freepkt;
195 if (rx_data != NULL)
196 e1000g_ksp->rx_avail_freepkt.value.ul = rx_data->avail_freepkt;
198 e1000g_ksp->tx_under_size.value.ul = tx_ring->stat_under_size;
199 e1000g_ksp->tx_exceed_frags.value.ul = tx_ring->stat_exceed_frags;
200 e1000g_ksp->tx_empty_frags.value.ul = tx_ring->stat_empty_frags;
201 e1000g_ksp->tx_recycle.value.ul = tx_ring->stat_recycle;
202 e1000g_ksp->tx_recycle_intr.value.ul = tx_ring->stat_recycle_intr;
203 e1000g_ksp->tx_recycle_retry.value.ul = tx_ring->stat_recycle_retry;
204 e1000g_ksp->tx_recycle_none.value.ul = tx_ring->stat_recycle_none;
205 e1000g_ksp->tx_copy.value.ul = tx_ring->stat_copy;
206 e1000g_ksp->tx_bind.value.ul = tx_ring->stat_bind;
207 e1000g_ksp->tx_multi_copy.value.ul = tx_ring->stat_multi_copy;
208 e1000g_ksp->tx_multi_cookie.value.ul = tx_ring->stat_multi_cookie;
209 e1000g_ksp->tx_lack_desc.value.ul = tx_ring->stat_lack_desc;
210 #endif
213 * Standard Stats
215 e1000g_ksp->Mpc.value.ul += E1000_READ_REG(hw, E1000_MPC);
216 e1000g_ksp->Rlec.value.ul += E1000_READ_REG(hw, E1000_RLEC);
217 e1000g_ksp->Xonrxc.value.ul += E1000_READ_REG(hw, E1000_XONRXC);
218 e1000g_ksp->Xontxc.value.ul += E1000_READ_REG(hw, E1000_XONTXC);
219 e1000g_ksp->Xoffrxc.value.ul += E1000_READ_REG(hw, E1000_XOFFRXC);
220 e1000g_ksp->Xofftxc.value.ul += E1000_READ_REG(hw, E1000_XOFFTXC);
221 e1000g_ksp->Fcruc.value.ul += E1000_READ_REG(hw, E1000_FCRUC);
223 if ((hw->mac.type != e1000_ich8lan) &&
224 (hw->mac.type != e1000_ich9lan) &&
225 (hw->mac.type != e1000_ich10lan) &&
226 (hw->mac.type != e1000_pchlan)) {
227 e1000g_ksp->Symerrs.value.ul +=
228 E1000_READ_REG(hw, E1000_SYMERRS);
229 #ifdef E1000G_DEBUG
230 e1000g_ksp->Prc64.value.ul +=
231 E1000_READ_REG(hw, E1000_PRC64);
232 e1000g_ksp->Prc127.value.ul +=
233 E1000_READ_REG(hw, E1000_PRC127);
234 e1000g_ksp->Prc255.value.ul +=
235 E1000_READ_REG(hw, E1000_PRC255);
236 e1000g_ksp->Prc511.value.ul +=
237 E1000_READ_REG(hw, E1000_PRC511);
238 e1000g_ksp->Prc1023.value.ul +=
239 E1000_READ_REG(hw, E1000_PRC1023);
240 e1000g_ksp->Prc1522.value.ul +=
241 E1000_READ_REG(hw, E1000_PRC1522);
243 e1000g_ksp->Ptc64.value.ul +=
244 E1000_READ_REG(hw, E1000_PTC64);
245 e1000g_ksp->Ptc127.value.ul +=
246 E1000_READ_REG(hw, E1000_PTC127);
247 e1000g_ksp->Ptc255.value.ul +=
248 E1000_READ_REG(hw, E1000_PTC255);
249 e1000g_ksp->Ptc511.value.ul +=
250 E1000_READ_REG(hw, E1000_PTC511);
251 e1000g_ksp->Ptc1023.value.ul +=
252 E1000_READ_REG(hw, E1000_PTC1023);
253 e1000g_ksp->Ptc1522.value.ul +=
254 E1000_READ_REG(hw, E1000_PTC1522);
255 #endif
258 e1000g_ksp->Gprc.value.ul += E1000_READ_REG(hw, E1000_GPRC);
259 e1000g_ksp->Gptc.value.ul += E1000_READ_REG(hw, E1000_GPTC);
260 e1000g_ksp->Rfc.value.ul += E1000_READ_REG(hw, E1000_RFC);
261 e1000g_ksp->Tncrs.value.ul += e1000g_read_phy_stat(hw, E1000_TNCRS);
262 e1000g_ksp->Tsctc.value.ul += E1000_READ_REG(hw, E1000_TSCTC);
263 e1000g_ksp->Tsctfc.value.ul += E1000_READ_REG(hw, E1000_TSCTFC);
266 * Adaptive Calculations
268 hw->mac.tx_packet_delta = E1000_READ_REG(hw, E1000_TPT);
269 Adapter->opackets += hw->mac.tx_packet_delta;
272 * The 64-bit register will reset whenever the upper
273 * 32 bits are read. So we need to read the lower
274 * 32 bits first, then read the upper 32 bits.
276 low_val = E1000_READ_REG(hw, E1000_GORCL);
277 high_val = E1000_READ_REG(hw, E1000_GORCH);
278 val = (uint64_t)e1000g_ksp->Gorh.value.ul << 32 |
279 (uint64_t)e1000g_ksp->Gorl.value.ul;
280 val += (uint64_t)high_val << 32 | (uint64_t)low_val;
281 e1000g_ksp->Gorl.value.ul = (uint32_t)val;
282 e1000g_ksp->Gorh.value.ul = (uint32_t)(val >> 32);
284 low_val = E1000_READ_REG(hw, E1000_GOTCL);
285 high_val = E1000_READ_REG(hw, E1000_GOTCH);
286 val = (uint64_t)e1000g_ksp->Goth.value.ul << 32 |
287 (uint64_t)e1000g_ksp->Gotl.value.ul;
288 val += (uint64_t)high_val << 32 | (uint64_t)low_val;
289 e1000g_ksp->Gotl.value.ul = (uint32_t)val;
290 e1000g_ksp->Goth.value.ul = (uint32_t)(val >> 32);
292 low_val = E1000_READ_REG(hw, E1000_TORL);
293 high_val = E1000_READ_REG(hw, E1000_TORH);
294 Adapter->rbytes +=
295 (uint64_t)high_val << 32 | (uint64_t)low_val;
297 low_val = E1000_READ_REG(hw, E1000_TOTL);
298 high_val = E1000_READ_REG(hw, E1000_TOTH);
299 Adapter->obytes +=
300 (uint64_t)high_val << 32 | (uint64_t)low_val;
302 rw_exit(&Adapter->chip_lock);
304 if (e1000g_check_acc_handle(Adapter->osdep.reg_handle) != DDI_FM_OK) {
305 ddi_fm_service_impact(Adapter->dip, DDI_SERVICE_UNAFFECTED);
306 return (EIO);
309 return (0);
313 e1000g_m_stat(void *arg, uint_t stat, uint64_t *val)
315 struct e1000g *Adapter = (struct e1000g *)arg;
316 struct e1000_hw *hw = &Adapter->shared;
317 p_e1000g_stat_t e1000g_ksp;
318 uint32_t low_val, high_val;
320 e1000g_ksp = (p_e1000g_stat_t)Adapter->e1000g_ksp->ks_data;
322 rw_enter(&Adapter->chip_lock, RW_READER);
324 if (Adapter->e1000g_state & E1000G_SUSPENDED) {
325 rw_exit(&Adapter->chip_lock);
326 return (ECANCELED);
329 switch (stat) {
330 case MAC_STAT_IFSPEED:
331 *val = Adapter->link_speed * 1000000ull;
332 break;
334 case MAC_STAT_MULTIRCV:
335 Adapter->multircv +=
336 E1000_READ_REG(hw, E1000_MPRC);
337 *val = Adapter->multircv;
338 break;
340 case MAC_STAT_BRDCSTRCV:
341 Adapter->brdcstrcv +=
342 E1000_READ_REG(hw, E1000_BPRC);
343 *val = Adapter->brdcstrcv;
344 break;
346 case MAC_STAT_MULTIXMT:
347 Adapter->multixmt +=
348 E1000_READ_REG(hw, E1000_MPTC);
349 *val = Adapter->multixmt;
350 break;
352 case MAC_STAT_BRDCSTXMT:
353 Adapter->brdcstxmt +=
354 E1000_READ_REG(hw, E1000_BPTC);
355 *val = Adapter->brdcstxmt;
356 break;
358 case MAC_STAT_NORCVBUF:
359 Adapter->norcvbuf +=
360 E1000_READ_REG(hw, E1000_RNBC);
361 *val = Adapter->norcvbuf;
362 break;
364 case MAC_STAT_IERRORS:
365 Adapter->macrcv_errors +=
366 E1000_READ_REG(hw, E1000_RXERRC);
367 Adapter->align_errors +=
368 E1000_READ_REG(hw, E1000_ALGNERRC);
369 e1000g_ksp->Rlec.value.ul +=
370 E1000_READ_REG(hw, E1000_RLEC);
371 Adapter->fcs_errors +=
372 E1000_READ_REG(hw, E1000_CRCERRS);
373 Adapter->carrier_errors +=
374 E1000_READ_REG(hw, E1000_CEXTERR);
375 *val = Adapter->macrcv_errors +
376 Adapter->align_errors +
377 e1000g_ksp->Rlec.value.ul +
378 Adapter->fcs_errors +
379 Adapter->carrier_errors;
380 break;
382 case MAC_STAT_NOXMTBUF:
383 *val = Adapter->tx_ring->stat_no_desc;
384 break;
386 case MAC_STAT_OERRORS:
387 Adapter->oerrors +=
388 e1000g_read_phy_stat(hw, E1000_ECOL);
389 *val = Adapter->oerrors;
390 break;
392 case MAC_STAT_COLLISIONS:
393 Adapter->collisions +=
394 e1000g_read_phy_stat(hw, E1000_COLC);
395 *val = Adapter->collisions;
396 break;
398 case MAC_STAT_RBYTES:
400 * The 64-bit register will reset whenever the upper
401 * 32 bits are read. So we need to read the lower
402 * 32 bits first, then read the upper 32 bits.
404 low_val = E1000_READ_REG(hw, E1000_TORL);
405 high_val = E1000_READ_REG(hw, E1000_TORH);
406 Adapter->rbytes +=
407 (uint64_t)high_val << 32 | (uint64_t)low_val;
408 *val = Adapter->rbytes;
409 break;
411 case MAC_STAT_IPACKETS:
412 Adapter->ipackets +=
413 E1000_READ_REG(hw, E1000_TPR);
414 *val = Adapter->ipackets;
415 break;
417 case MAC_STAT_OBYTES:
419 * The 64-bit register will reset whenever the upper
420 * 32 bits are read. So we need to read the lower
421 * 32 bits first, then read the upper 32 bits.
423 low_val = E1000_READ_REG(hw, E1000_TOTL);
424 high_val = E1000_READ_REG(hw, E1000_TOTH);
425 Adapter->obytes +=
426 (uint64_t)high_val << 32 | (uint64_t)low_val;
427 *val = Adapter->obytes;
428 break;
430 case MAC_STAT_OPACKETS:
431 Adapter->opackets +=
432 E1000_READ_REG(hw, E1000_TPT);
433 *val = Adapter->opackets;
434 break;
436 case ETHER_STAT_ALIGN_ERRORS:
437 Adapter->align_errors +=
438 E1000_READ_REG(hw, E1000_ALGNERRC);
439 *val = Adapter->align_errors;
440 break;
442 case ETHER_STAT_FCS_ERRORS:
443 Adapter->fcs_errors +=
444 E1000_READ_REG(hw, E1000_CRCERRS);
445 *val = Adapter->fcs_errors;
446 break;
448 case ETHER_STAT_SQE_ERRORS:
449 Adapter->sqe_errors +=
450 E1000_READ_REG(hw, E1000_SEC);
451 *val = Adapter->sqe_errors;
452 break;
454 case ETHER_STAT_CARRIER_ERRORS:
455 Adapter->carrier_errors +=
456 E1000_READ_REG(hw, E1000_CEXTERR);
457 *val = Adapter->carrier_errors;
458 break;
460 case ETHER_STAT_EX_COLLISIONS:
461 Adapter->ex_collisions +=
462 e1000g_read_phy_stat(hw, E1000_ECOL);
463 *val = Adapter->ex_collisions;
464 break;
466 case ETHER_STAT_TX_LATE_COLLISIONS:
467 Adapter->tx_late_collisions +=
468 e1000g_read_phy_stat(hw, E1000_LATECOL);
469 *val = Adapter->tx_late_collisions;
470 break;
472 case ETHER_STAT_DEFER_XMTS:
473 Adapter->defer_xmts +=
474 e1000g_read_phy_stat(hw, E1000_DC);
475 *val = Adapter->defer_xmts;
476 break;
478 case ETHER_STAT_FIRST_COLLISIONS:
479 Adapter->first_collisions +=
480 e1000g_read_phy_stat(hw, E1000_SCC);
481 *val = Adapter->first_collisions;
482 break;
484 case ETHER_STAT_MULTI_COLLISIONS:
485 Adapter->multi_collisions +=
486 e1000g_read_phy_stat(hw, E1000_MCC);
487 *val = Adapter->multi_collisions;
488 break;
490 case ETHER_STAT_MACRCV_ERRORS:
491 Adapter->macrcv_errors +=
492 E1000_READ_REG(hw, E1000_RXERRC);
493 *val = Adapter->macrcv_errors;
494 break;
496 case ETHER_STAT_MACXMT_ERRORS:
497 Adapter->macxmt_errors +=
498 e1000g_read_phy_stat(hw, E1000_ECOL);
499 *val = Adapter->macxmt_errors;
500 break;
502 case ETHER_STAT_TOOLONG_ERRORS:
503 Adapter->toolong_errors +=
504 E1000_READ_REG(hw, E1000_ROC);
505 *val = Adapter->toolong_errors;
506 break;
508 case ETHER_STAT_TOOSHORT_ERRORS:
509 Adapter->tooshort_errors +=
510 E1000_READ_REG(hw, E1000_RUC);
511 *val = Adapter->tooshort_errors;
512 break;
514 case ETHER_STAT_JABBER_ERRORS:
515 Adapter->jabber_errors +=
516 E1000_READ_REG(hw, E1000_RJC);
517 *val = Adapter->jabber_errors;
518 break;
520 case ETHER_STAT_XCVR_ADDR:
521 /* The Internal PHY's MDI address for each MAC is 1 */
522 *val = 1;
523 break;
525 case ETHER_STAT_XCVR_ID:
526 *val = hw->phy.id | hw->phy.revision;
527 break;
529 case ETHER_STAT_XCVR_INUSE:
530 switch (Adapter->link_speed) {
531 case SPEED_1000:
532 *val =
533 (hw->phy.media_type == e1000_media_type_copper) ?
534 XCVR_1000T : XCVR_1000X;
535 break;
536 case SPEED_100:
537 *val =
538 (hw->phy.media_type == e1000_media_type_copper) ?
539 (Adapter->phy_status & MII_SR_100T4_CAPS) ?
540 XCVR_100T4 : XCVR_100T2 : XCVR_100X;
541 break;
542 case SPEED_10:
543 *val = XCVR_10;
544 break;
545 default:
546 *val = XCVR_NONE;
547 break;
549 break;
551 case ETHER_STAT_CAP_1000FDX:
552 *val = Adapter->param_1000fdx_cap;
553 break;
555 case ETHER_STAT_CAP_1000HDX:
556 *val = Adapter->param_1000hdx_cap;
557 break;
559 case ETHER_STAT_CAP_100FDX:
560 *val = Adapter->param_100fdx_cap;
561 break;
563 case ETHER_STAT_CAP_100HDX:
564 *val = Adapter->param_100hdx_cap;
565 break;
567 case ETHER_STAT_CAP_10FDX:
568 *val = Adapter->param_10fdx_cap;
569 break;
571 case ETHER_STAT_CAP_10HDX:
572 *val = Adapter->param_10hdx_cap;
573 break;
575 case ETHER_STAT_CAP_ASMPAUSE:
576 *val = Adapter->param_asym_pause_cap;
577 break;
579 case ETHER_STAT_CAP_PAUSE:
580 *val = Adapter->param_pause_cap;
581 break;
583 case ETHER_STAT_CAP_AUTONEG:
584 *val = Adapter->param_autoneg_cap;
585 break;
587 case ETHER_STAT_ADV_CAP_1000FDX:
588 *val = Adapter->param_adv_1000fdx;
589 break;
591 case ETHER_STAT_ADV_CAP_1000HDX:
592 *val = Adapter->param_adv_1000hdx;
593 break;
595 case ETHER_STAT_ADV_CAP_100FDX:
596 *val = Adapter->param_adv_100fdx;
597 break;
599 case ETHER_STAT_ADV_CAP_100HDX:
600 *val = Adapter->param_adv_100hdx;
601 break;
603 case ETHER_STAT_ADV_CAP_10FDX:
604 *val = Adapter->param_adv_10fdx;
605 break;
607 case ETHER_STAT_ADV_CAP_10HDX:
608 *val = Adapter->param_adv_10hdx;
609 break;
611 case ETHER_STAT_ADV_CAP_ASMPAUSE:
612 *val = Adapter->param_adv_asym_pause;
613 break;
615 case ETHER_STAT_ADV_CAP_PAUSE:
616 *val = Adapter->param_adv_pause;
617 break;
619 case ETHER_STAT_ADV_CAP_AUTONEG:
620 *val = hw->mac.autoneg;
621 break;
623 case ETHER_STAT_LP_CAP_1000FDX:
624 *val = Adapter->param_lp_1000fdx;
625 break;
627 case ETHER_STAT_LP_CAP_1000HDX:
628 *val = Adapter->param_lp_1000hdx;
629 break;
631 case ETHER_STAT_LP_CAP_100FDX:
632 *val = Adapter->param_lp_100fdx;
633 break;
635 case ETHER_STAT_LP_CAP_100HDX:
636 *val = Adapter->param_lp_100hdx;
637 break;
639 case ETHER_STAT_LP_CAP_10FDX:
640 *val = Adapter->param_lp_10fdx;
641 break;
643 case ETHER_STAT_LP_CAP_10HDX:
644 *val = Adapter->param_lp_10hdx;
645 break;
647 case ETHER_STAT_LP_CAP_ASMPAUSE:
648 *val = Adapter->param_lp_asym_pause;
649 break;
651 case ETHER_STAT_LP_CAP_PAUSE:
652 *val = Adapter->param_lp_pause;
653 break;
655 case ETHER_STAT_LP_CAP_AUTONEG:
656 *val = Adapter->param_lp_autoneg;
657 break;
659 case ETHER_STAT_LINK_ASMPAUSE:
660 *val = Adapter->param_asym_pause_cap;
661 break;
663 case ETHER_STAT_LINK_PAUSE:
664 *val = Adapter->param_pause_cap;
665 break;
667 case ETHER_STAT_LINK_AUTONEG:
668 *val = hw->mac.autoneg;
669 break;
671 case ETHER_STAT_LINK_DUPLEX:
672 *val = (Adapter->link_duplex == FULL_DUPLEX) ?
673 LINK_DUPLEX_FULL : LINK_DUPLEX_HALF;
674 break;
676 case ETHER_STAT_CAP_100T4:
677 *val = Adapter->param_100t4_cap;
678 break;
680 case ETHER_STAT_ADV_CAP_100T4:
681 *val = Adapter->param_adv_100t4;
682 break;
684 case ETHER_STAT_LP_CAP_100T4:
685 *val = Adapter->param_lp_100t4;
686 break;
688 default:
689 rw_exit(&Adapter->chip_lock);
690 return (ENOTSUP);
693 rw_exit(&Adapter->chip_lock);
695 if (e1000g_check_acc_handle(Adapter->osdep.reg_handle) != DDI_FM_OK) {
696 ddi_fm_service_impact(Adapter->dip, DDI_SERVICE_UNAFFECTED);
697 return (EIO);
700 return (0);
704 * e1000g_init_stats - initialize kstat data structures
706 * This routine will create and initialize the driver private
707 * statistics counters.
710 e1000g_init_stats(struct e1000g *Adapter)
712 kstat_t *ksp;
713 p_e1000g_stat_t e1000g_ksp;
716 * Create and init kstat
718 ksp = kstat_create(WSNAME, ddi_get_instance(Adapter->dip),
719 "statistics", "net", KSTAT_TYPE_NAMED,
720 sizeof (e1000g_stat_t) / sizeof (kstat_named_t), 0);
722 if (ksp == NULL) {
723 e1000g_log(Adapter, CE_WARN,
724 "Could not create kernel statistics\n");
725 return (DDI_FAILURE);
728 Adapter->e1000g_ksp = ksp; /* Fill in the Adapters ksp */
730 e1000g_ksp = (p_e1000g_stat_t)ksp->ks_data;
733 * Initialize all the statistics
735 kstat_named_init(&e1000g_ksp->reset_count, "Reset Count",
736 KSTAT_DATA_ULONG);
738 kstat_named_init(&e1000g_ksp->rx_error, "Rx Error",
739 KSTAT_DATA_ULONG);
740 kstat_named_init(&e1000g_ksp->rx_allocb_fail, "Rx Allocb Failure",
741 KSTAT_DATA_ULONG);
742 kstat_named_init(&e1000g_ksp->rx_size_error, "Rx Size Error",
743 KSTAT_DATA_ULONG);
745 kstat_named_init(&e1000g_ksp->tx_no_desc, "Tx No Desc",
746 KSTAT_DATA_ULONG);
747 kstat_named_init(&e1000g_ksp->tx_no_swpkt, "Tx No Buffer",
748 KSTAT_DATA_ULONG);
749 kstat_named_init(&e1000g_ksp->tx_send_fail, "Tx Send Failure",
750 KSTAT_DATA_ULONG);
751 kstat_named_init(&e1000g_ksp->tx_over_size, "Tx Pkt Over Size",
752 KSTAT_DATA_ULONG);
753 kstat_named_init(&e1000g_ksp->tx_reschedule, "Tx Reschedule",
754 KSTAT_DATA_ULONG);
756 kstat_named_init(&e1000g_ksp->Mpc, "Recv_Missed_Packets",
757 KSTAT_DATA_ULONG);
758 kstat_named_init(&e1000g_ksp->Symerrs, "Recv_Symbol_Errors",
759 KSTAT_DATA_ULONG);
760 kstat_named_init(&e1000g_ksp->Rlec, "Recv_Length_Errors",
761 KSTAT_DATA_ULONG);
762 kstat_named_init(&e1000g_ksp->Xonrxc, "XONs_Recvd",
763 KSTAT_DATA_ULONG);
764 kstat_named_init(&e1000g_ksp->Xontxc, "XONs_Xmitd",
765 KSTAT_DATA_ULONG);
766 kstat_named_init(&e1000g_ksp->Xoffrxc, "XOFFs_Recvd",
767 KSTAT_DATA_ULONG);
768 kstat_named_init(&e1000g_ksp->Xofftxc, "XOFFs_Xmitd",
769 KSTAT_DATA_ULONG);
770 kstat_named_init(&e1000g_ksp->Fcruc, "Recv_Unsupport_FC_Pkts",
771 KSTAT_DATA_ULONG);
772 #ifdef E1000G_DEBUG
773 kstat_named_init(&e1000g_ksp->Prc64, "Pkts_Recvd_( 64b)",
774 KSTAT_DATA_ULONG);
775 kstat_named_init(&e1000g_ksp->Prc127, "Pkts_Recvd_( 65- 127b)",
776 KSTAT_DATA_ULONG);
777 kstat_named_init(&e1000g_ksp->Prc255, "Pkts_Recvd_( 127- 255b)",
778 KSTAT_DATA_ULONG);
779 kstat_named_init(&e1000g_ksp->Prc511, "Pkts_Recvd_( 256- 511b)",
780 KSTAT_DATA_ULONG);
781 kstat_named_init(&e1000g_ksp->Prc1023, "Pkts_Recvd_( 511-1023b)",
782 KSTAT_DATA_ULONG);
783 kstat_named_init(&e1000g_ksp->Prc1522, "Pkts_Recvd_(1024-1522b)",
784 KSTAT_DATA_ULONG);
785 #endif
786 kstat_named_init(&e1000g_ksp->Gprc, "Good_Pkts_Recvd",
787 KSTAT_DATA_ULONG);
788 kstat_named_init(&e1000g_ksp->Gptc, "Good_Pkts_Xmitd",
789 KSTAT_DATA_ULONG);
790 kstat_named_init(&e1000g_ksp->Gorl, "Good_Octets_Recvd_Lo",
791 KSTAT_DATA_ULONG);
792 kstat_named_init(&e1000g_ksp->Gorh, "Good_Octets_Recvd_Hi",
793 KSTAT_DATA_ULONG);
794 kstat_named_init(&e1000g_ksp->Gotl, "Good_Octets_Xmitd_Lo",
795 KSTAT_DATA_ULONG);
796 kstat_named_init(&e1000g_ksp->Goth, "Good_Octets_Xmitd_Hi",
797 KSTAT_DATA_ULONG);
798 kstat_named_init(&e1000g_ksp->Rfc, "Recv_Frag",
799 KSTAT_DATA_ULONG);
800 #ifdef E1000G_DEBUG
801 kstat_named_init(&e1000g_ksp->Ptc64, "Pkts_Xmitd_( 64b)",
802 KSTAT_DATA_ULONG);
803 kstat_named_init(&e1000g_ksp->Ptc127, "Pkts_Xmitd_( 65- 127b)",
804 KSTAT_DATA_ULONG);
805 kstat_named_init(&e1000g_ksp->Ptc255, "Pkts_Xmitd_( 128- 255b)",
806 KSTAT_DATA_ULONG);
807 kstat_named_init(&e1000g_ksp->Ptc511, "Pkts_Xmitd_( 255- 511b)",
808 KSTAT_DATA_ULONG);
809 kstat_named_init(&e1000g_ksp->Ptc1023, "Pkts_Xmitd_( 512-1023b)",
810 KSTAT_DATA_ULONG);
811 kstat_named_init(&e1000g_ksp->Ptc1522, "Pkts_Xmitd_(1024-1522b)",
812 KSTAT_DATA_ULONG);
813 #endif
814 kstat_named_init(&e1000g_ksp->Tncrs, "Xmit_with_No_CRS",
815 KSTAT_DATA_ULONG);
816 kstat_named_init(&e1000g_ksp->Tsctc, "Xmit_TCP_Seg_Contexts",
817 KSTAT_DATA_ULONG);
818 kstat_named_init(&e1000g_ksp->Tsctfc, "Xmit_TCP_Seg_Contexts_Fail",
819 KSTAT_DATA_ULONG);
821 #ifdef E1000G_DEBUG
822 kstat_named_init(&e1000g_ksp->rx_none, "Rx No Data",
823 KSTAT_DATA_ULONG);
824 kstat_named_init(&e1000g_ksp->rx_multi_desc, "Rx Span Multi Desc",
825 KSTAT_DATA_ULONG);
826 kstat_named_init(&e1000g_ksp->rx_no_freepkt, "Rx Freelist Empty",
827 KSTAT_DATA_ULONG);
828 kstat_named_init(&e1000g_ksp->rx_avail_freepkt, "Rx Freelist Avail",
829 KSTAT_DATA_ULONG);
831 kstat_named_init(&e1000g_ksp->tx_under_size, "Tx Pkt Under Size",
832 KSTAT_DATA_ULONG);
833 kstat_named_init(&e1000g_ksp->tx_exceed_frags, "Tx Exceed Max Frags",
834 KSTAT_DATA_ULONG);
835 kstat_named_init(&e1000g_ksp->tx_empty_frags, "Tx Empty Frags",
836 KSTAT_DATA_ULONG);
837 kstat_named_init(&e1000g_ksp->tx_recycle, "Tx Recycle",
838 KSTAT_DATA_ULONG);
839 kstat_named_init(&e1000g_ksp->tx_recycle_intr, "Tx Recycle Intr",
840 KSTAT_DATA_ULONG);
841 kstat_named_init(&e1000g_ksp->tx_recycle_retry, "Tx Recycle Retry",
842 KSTAT_DATA_ULONG);
843 kstat_named_init(&e1000g_ksp->tx_recycle_none, "Tx Recycled None",
844 KSTAT_DATA_ULONG);
845 kstat_named_init(&e1000g_ksp->tx_copy, "Tx Send Copy",
846 KSTAT_DATA_ULONG);
847 kstat_named_init(&e1000g_ksp->tx_bind, "Tx Send Bind",
848 KSTAT_DATA_ULONG);
849 kstat_named_init(&e1000g_ksp->tx_multi_copy, "Tx Copy Multi Frags",
850 KSTAT_DATA_ULONG);
851 kstat_named_init(&e1000g_ksp->tx_multi_cookie, "Tx Bind Multi Cookies",
852 KSTAT_DATA_ULONG);
853 kstat_named_init(&e1000g_ksp->tx_lack_desc, "Tx Desc Insufficient",
854 KSTAT_DATA_ULONG);
855 #endif
858 * Function to provide kernel stat update on demand
860 ksp->ks_update = e1000g_update_stats;
863 * Pointer into provider's raw statistics
865 ksp->ks_private = (void *)Adapter;
868 * Add kstat to systems kstat chain
870 kstat_install(ksp);
872 return (DDI_SUCCESS);
876 * e1000g_read_phy_stat - read certain PHY statistics
878 * Certain statistics are read from MAC registers on some silicon types
879 * but are read from the PHY on other silicon types. This routine
880 * handles that difference as needed.
882 static uint32_t
883 e1000g_read_phy_stat(struct e1000_hw *hw, int reg)
885 uint16_t phy_low, phy_high;
886 uint32_t val;
888 /* get statistic from PHY in these cases */
889 if ((hw->phy.type == e1000_phy_82578) ||
890 (hw->phy.type == e1000_phy_82577)) {
892 switch (reg) {
893 case E1000_SCC:
894 (void) e1000_read_phy_reg(hw, HV_SCC_UPPER, &phy_high);
895 (void) e1000_read_phy_reg(hw, HV_SCC_LOWER, &phy_low);
896 val = ((uint32_t)phy_high << 16) | (uint32_t)phy_low;
897 break;
899 case E1000_MCC:
900 (void) e1000_read_phy_reg(hw, HV_MCC_UPPER, &phy_high);
901 (void) e1000_read_phy_reg(hw, HV_MCC_LOWER, &phy_low);
902 val = ((uint32_t)phy_high << 16) | (uint32_t)phy_low;
903 break;
905 case E1000_ECOL:
906 (void) e1000_read_phy_reg(hw, HV_ECOL_UPPER, &phy_high);
907 (void) e1000_read_phy_reg(hw, HV_ECOL_LOWER, &phy_low);
908 val = ((uint32_t)phy_high << 16) | (uint32_t)phy_low;
909 break;
911 case E1000_COLC:
912 (void) e1000_read_phy_reg(hw, HV_COLC_UPPER, &phy_high);
913 (void) e1000_read_phy_reg(hw, HV_COLC_LOWER, &phy_low);
914 val = ((uint32_t)phy_high << 16) | (uint32_t)phy_low;
915 break;
917 case E1000_LATECOL:
918 (void) e1000_read_phy_reg(hw, HV_LATECOL_UPPER,
919 &phy_high);
920 (void) e1000_read_phy_reg(hw, HV_LATECOL_LOWER,
921 &phy_low);
922 val = ((uint32_t)phy_high << 16) | (uint32_t)phy_low;
923 break;
925 case E1000_DC:
926 (void) e1000_read_phy_reg(hw, HV_DC_UPPER, &phy_high);
927 (void) e1000_read_phy_reg(hw, HV_DC_LOWER, &phy_low);
928 val = ((uint32_t)phy_high << 16) | (uint32_t)phy_low;
929 break;
931 case E1000_TNCRS:
932 (void) e1000_read_phy_reg(hw, HV_TNCRS_UPPER,
933 &phy_high);
934 (void) e1000_read_phy_reg(hw, HV_TNCRS_LOWER,
935 &phy_low);
936 val = ((uint32_t)phy_high << 16) | (uint32_t)phy_low;
937 break;
939 default:
940 break;
943 /* get statistic from MAC otherwise */
944 } else {
945 val = E1000_READ_REG(hw, reg);
948 return (val);
952 * Retrieve a value for one of the statistics for a particular rx ring
955 e1000g_rx_ring_stat(mac_ring_driver_t rh, uint_t stat, uint64_t *val)
957 e1000g_rx_ring_t *rx_ring = (e1000g_rx_ring_t *)rh;
958 struct e1000g *Adapter = rx_ring->adapter;
959 struct e1000_hw *hw = &Adapter->shared;
960 uint32_t low_val, high_val;
962 rw_enter(&Adapter->chip_lock, RW_READER);
964 if (Adapter->e1000g_state & E1000G_SUSPENDED) {
965 rw_exit(&Adapter->chip_lock);
966 return (ECANCELED);
969 switch (stat) {
970 case MAC_STAT_RBYTES:
972 * The 64-bit register will reset whenever the upper
973 * 32 bits are read. So we need to read the lower
974 * 32 bits first, then read the upper 32 bits.
976 low_val = E1000_READ_REG(hw, E1000_TORL);
977 high_val = E1000_READ_REG(hw, E1000_TORH);
978 Adapter->rbytes +=
979 (uint64_t)high_val << 32 | (uint64_t)low_val;
980 *val = Adapter->rbytes;
981 break;
983 case MAC_STAT_IPACKETS:
984 Adapter->ipackets +=
985 E1000_READ_REG(hw, E1000_TPR);
986 *val = Adapter->ipackets;
987 break;
989 default:
990 *val = 0;
991 rw_exit(&Adapter->chip_lock);
992 return (ENOTSUP);
995 rw_exit(&Adapter->chip_lock);
997 if (e1000g_check_acc_handle(Adapter->osdep.reg_handle) != DDI_FM_OK)
998 ddi_fm_service_impact(Adapter->dip, DDI_SERVICE_UNAFFECTED);
1000 return (0);