Module Name: src
Committed By: yamaguchi
Date: Thu Jan 9 02:43:45 UTC 2020
Modified Files:
src/sys/dev/pci: if_ixl.c
Log Message:
ixl(4) supports in-chip statistic counters per port
To generate a diff of this commit:
cvs rdiff -u -r1.16 -r1.17 src/sys/dev/pci/if_ixl.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/dev/pci/if_ixl.c
diff -u src/sys/dev/pci/if_ixl.c:1.16 src/sys/dev/pci/if_ixl.c:1.17
--- src/sys/dev/pci/if_ixl.c:1.16 Wed Jan 8 09:12:11 2020
+++ src/sys/dev/pci/if_ixl.c Thu Jan 9 02:43:45 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: if_ixl.c,v 1.16 2020/01/08 09:12:11 yamaguchi Exp $ */
+/* $NetBSD: if_ixl.c,v 1.17 2020/01/09 02:43:45 yamaguchi Exp $ */
/*
* Copyright (c) 2013-2015, Intel Corporation
@@ -485,6 +485,82 @@ struct ixl_product {
unsigned int product_id;
};
+struct ixl_stats_counters {
+ bool isc_has_offset;
+ struct evcnt isc_crc_errors;
+ uint64_t isc_crc_errors_offset;
+ struct evcnt isc_illegal_bytes;
+ uint64_t isc_illegal_bytes_offset;
+ struct evcnt isc_rx_bytes;
+ uint64_t isc_rx_bytes_offset;
+ struct evcnt isc_rx_discards;
+ uint64_t isc_rx_discards_offset;
+ struct evcnt isc_rx_unicast;
+ uint64_t isc_rx_unicast_offset;
+ struct evcnt isc_rx_multicast;
+ uint64_t isc_rx_multicast_offset;
+ struct evcnt isc_rx_broadcast;
+ uint64_t isc_rx_broadcast_offset;
+ struct evcnt isc_rx_size_64;
+ uint64_t isc_rx_size_64_offset;
+ struct evcnt isc_rx_size_127;
+ uint64_t isc_rx_size_127_offset;
+ struct evcnt isc_rx_size_255;
+ uint64_t isc_rx_size_255_offset;
+ struct evcnt isc_rx_size_511;
+ uint64_t isc_rx_size_511_offset;
+ struct evcnt isc_rx_size_1023;
+ uint64_t isc_rx_size_1023_offset;
+ struct evcnt isc_rx_size_1522;
+ uint64_t isc_rx_size_1522_offset;
+ struct evcnt isc_rx_size_big;
+ uint64_t isc_rx_size_big_offset;
+ struct evcnt isc_rx_undersize;
+ uint64_t isc_rx_undersize_offset;
+ struct evcnt isc_rx_oversize;
+ uint64_t isc_rx_oversize_offset;
+ struct evcnt isc_rx_fragments;
+ uint64_t isc_rx_fragments_offset;
+ struct evcnt isc_rx_jabber;
+ uint64_t isc_rx_jabber_offset;
+ struct evcnt isc_tx_bytes;
+ uint64_t isc_tx_bytes_offset;
+ struct evcnt isc_tx_dropped_link_down;
+ uint64_t isc_tx_dropped_link_down_offset;
+ struct evcnt isc_tx_unicast;
+ uint64_t isc_tx_unicast_offset;
+ struct evcnt isc_tx_multicast;
+ uint64_t isc_tx_multicast_offset;
+ struct evcnt isc_tx_broadcast;
+ uint64_t isc_tx_broadcast_offset;
+ struct evcnt isc_tx_size_64;
+ uint64_t isc_tx_size_64_offset;
+ struct evcnt isc_tx_size_127;
+ uint64_t isc_tx_size_127_offset;
+ struct evcnt isc_tx_size_255;
+ uint64_t isc_tx_size_255_offset;
+ struct evcnt isc_tx_size_511;
+ uint64_t isc_tx_size_511_offset;
+ struct evcnt isc_tx_size_1023;
+ uint64_t isc_tx_size_1023_offset;
+ struct evcnt isc_tx_size_1522;
+ uint64_t isc_tx_size_1522_offset;
+ struct evcnt isc_tx_size_big;
+ uint64_t isc_tx_size_big_offset;
+ struct evcnt isc_mac_local_faults;
+ uint64_t isc_mac_local_faults_offset;
+ struct evcnt isc_mac_remote_faults;
+ uint64_t isc_mac_remote_faults_offset;
+ struct evcnt isc_link_xon_rx;
+ uint64_t isc_link_xon_rx_offset;
+ struct evcnt isc_link_xon_tx;
+ uint64_t isc_link_xon_tx_offset;
+ struct evcnt isc_link_xoff_rx;
+ uint64_t isc_link_xoff_rx_offset;
+ struct evcnt isc_link_xoff_tx;
+ uint64_t isc_link_xoff_tx_offset;
+};
+
/*
* Locking notes:
* + a field in ixl_tx_ring is protected by txr_lock (a spin mutex), and
@@ -508,9 +584,15 @@ struct ixl_softc {
bool sc_attached;
bool sc_dead;
bool sc_rxctl_atq;
+ uint32_t sc_port;
struct sysctllog *sc_sysctllog;
struct workqueue *sc_workq;
struct workqueue *sc_workq_txrx;
+ int sc_stats_intval;
+ callout_t sc_stats_callout;
+ struct ixl_work sc_stats_task;
+ struct ixl_stats_counters
+ sc_stats_counters;
uint8_t sc_enaddr[ETHER_ADDR_LEN];
struct ifmedia sc_media;
uint64_t sc_media_status;
@@ -613,6 +695,9 @@ do { \
#define DDPRINTF(sc, fmt, args...) __nothing
#endif
#define IXL_NOMSIX false
+#ifndef IXL_STATS_INTERVAL_MSEC
+#define IXL_STATS_INTERVAL_MSEC 10000
+#endif
static enum i40e_mac_type
ixl_mactype(pci_product_id_t);
@@ -742,6 +827,8 @@ static int ixl_setup_interrupts(struct i
static void ixl_teardown_interrupts(struct ixl_softc *);
static int ixl_setup_stats(struct ixl_softc *);
static void ixl_teardown_stats(struct ixl_softc *);
+static void ixl_stats_callout(void *);
+static void ixl_stats_update(void *);
static int ixl_setup_sysctls(struct ixl_softc *);
static void ixl_teardown_sysctls(struct ixl_softc *);
static int ixl_queue_pairs_alloc(struct ixl_softc *);
@@ -973,7 +1060,8 @@ ixl_attach(device_t parent, device_t sel
port = ixl_rd(sc, I40E_PFGEN_PORTNUM);
port &= I40E_PFGEN_PORTNUM_PORT_NUM_MASK;
port >>= I40E_PFGEN_PORTNUM_PORT_NUM_SHIFT;
- aprint_normal(": port %u", port);
+ sc->sc_port = port;
+ aprint_normal(": port %u", sc->sc_port);
ari = ixl_rd(sc, I40E_GLPCI_CAPSUP);
ari &= I40E_GLPCI_CAPSUP_ARI_EN_MASK;
@@ -1261,6 +1349,10 @@ ixl_attach(device_t parent, device_t sel
sc->sc_tx_intr_process_limit = IXL_TX_INTR_PROCESS_LIMIT;
sc->sc_rx_intr_process_limit = IXL_RX_INTR_PROCESS_LIMIT;
+ ixl_stats_update(sc);
+ sc->sc_stats_counters.isc_has_offset = true;
+ callout_schedule(&sc->sc_stats_callout, mstohz(sc->sc_stats_intval));
+
if (pmf_device_register(self, NULL, NULL) != true)
aprint_debug_dev(self, "couldn't establish power handler\n");
sc->sc_attached = true;
@@ -1328,6 +1420,9 @@ ixl_detach(device_t self, int flags)
ixl_disable_other_intr(sc);
+ callout_stop(&sc->sc_stats_callout);
+ ixl_work_wait(sc->sc_workq, &sc->sc_stats_task);
+
/* wait for ATQ handler */
mutex_enter(&sc->sc_atq_lock);
mutex_exit(&sc->sc_atq_lock);
@@ -5447,6 +5542,7 @@ ixl_setup_stats(struct ixl_softc *sc)
struct ixl_queue_pair *qp;
struct ixl_tx_ring *txr;
struct ixl_rx_ring *rxr;
+ struct ixl_stats_counters *isc;
unsigned int i;
for (i = 0; i < sc->sc_nqueue_pairs_max; i++) {
@@ -5491,6 +5587,90 @@ ixl_setup_stats(struct ixl_softc *sc)
evcnt_attach_dynamic(&sc->sc_event_crit_err, EVCNT_TYPE_MISC,
NULL, device_xname(sc->sc_dev), "Critical error");
+ isc = &sc->sc_stats_counters;
+ evcnt_attach_dynamic(&isc->isc_crc_errors, EVCNT_TYPE_MISC,
+ NULL, device_xname(sc->sc_dev), "CRC errors");
+ evcnt_attach_dynamic(&isc->isc_illegal_bytes, EVCNT_TYPE_MISC,
+ NULL, device_xname(sc->sc_dev), "Illegal bytes");
+ evcnt_attach_dynamic(&isc->isc_mac_local_faults, EVCNT_TYPE_MISC,
+ NULL, device_xname(sc->sc_dev), "Mac local faults");
+ evcnt_attach_dynamic(&isc->isc_mac_remote_faults, EVCNT_TYPE_MISC,
+ NULL, device_xname(sc->sc_dev), "Mac remote faults");
+ evcnt_attach_dynamic(&isc->isc_link_xon_rx, EVCNT_TYPE_MISC,
+ NULL, device_xname(sc->sc_dev), "Rx xon");
+ evcnt_attach_dynamic(&isc->isc_link_xon_tx, EVCNT_TYPE_MISC,
+ NULL, device_xname(sc->sc_dev), "Tx xon");
+ evcnt_attach_dynamic(&isc->isc_link_xoff_rx, EVCNT_TYPE_MISC,
+ NULL, device_xname(sc->sc_dev), "Rx xoff");
+ evcnt_attach_dynamic(&isc->isc_link_xoff_tx, EVCNT_TYPE_MISC,
+ NULL, device_xname(sc->sc_dev), "Tx xoff");
+ evcnt_attach_dynamic(&isc->isc_rx_fragments, EVCNT_TYPE_MISC,
+ NULL, device_xname(sc->sc_dev), "Rx fragments");
+ evcnt_attach_dynamic(&isc->isc_rx_jabber, EVCNT_TYPE_MISC,
+ NULL, device_xname(sc->sc_dev), "Rx jabber");
+
+ evcnt_attach_dynamic(&isc->isc_rx_size_64, EVCNT_TYPE_MISC,
+ NULL, device_xname(sc->sc_dev), "Rx size 64");
+ evcnt_attach_dynamic(&isc->isc_rx_size_127, EVCNT_TYPE_MISC,
+ NULL, device_xname(sc->sc_dev), "Rx size 127");
+ evcnt_attach_dynamic(&isc->isc_rx_size_255, EVCNT_TYPE_MISC,
+ NULL, device_xname(sc->sc_dev), "Rx size 255");
+ evcnt_attach_dynamic(&isc->isc_rx_size_511, EVCNT_TYPE_MISC,
+ NULL, device_xname(sc->sc_dev), "Rx size 511");
+ evcnt_attach_dynamic(&isc->isc_rx_size_1023, EVCNT_TYPE_MISC,
+ NULL, device_xname(sc->sc_dev), "Rx size 1023");
+ evcnt_attach_dynamic(&isc->isc_rx_size_1522, EVCNT_TYPE_MISC,
+ NULL, device_xname(sc->sc_dev), "Rx size 1522");
+ evcnt_attach_dynamic(&isc->isc_rx_size_big, EVCNT_TYPE_MISC,
+ NULL, device_xname(sc->sc_dev), "Rx jumbo packets");
+ evcnt_attach_dynamic(&isc->isc_rx_undersize, EVCNT_TYPE_MISC,
+ NULL, device_xname(sc->sc_dev), "Rx under size");
+ evcnt_attach_dynamic(&isc->isc_rx_oversize, EVCNT_TYPE_MISC,
+ NULL, device_xname(sc->sc_dev), "Rx over size");
+
+ evcnt_attach_dynamic(&isc->isc_rx_bytes, EVCNT_TYPE_MISC,
+ NULL, device_xname(sc->sc_dev), "Rx bytes / port");
+ evcnt_attach_dynamic(&isc->isc_rx_discards, EVCNT_TYPE_MISC,
+ NULL, device_xname(sc->sc_dev), "Rx discards / port");
+ evcnt_attach_dynamic(&isc->isc_rx_unicast, EVCNT_TYPE_MISC,
+ NULL, device_xname(sc->sc_dev), "Rx unicast / port");
+ evcnt_attach_dynamic(&isc->isc_rx_multicast, EVCNT_TYPE_MISC,
+ NULL, device_xname(sc->sc_dev), "Rx multicast / port");
+ evcnt_attach_dynamic(&isc->isc_rx_broadcast, EVCNT_TYPE_MISC,
+ NULL, device_xname(sc->sc_dev), "Rx broadcast / port");
+
+ evcnt_attach_dynamic(&isc->isc_tx_size_64, EVCNT_TYPE_MISC,
+ NULL, device_xname(sc->sc_dev), "Tx size 64");
+ evcnt_attach_dynamic(&isc->isc_tx_size_127, EVCNT_TYPE_MISC,
+ NULL, device_xname(sc->sc_dev), "Tx size 127");
+ evcnt_attach_dynamic(&isc->isc_tx_size_255, EVCNT_TYPE_MISC,
+ NULL, device_xname(sc->sc_dev), "Tx size 255");
+ evcnt_attach_dynamic(&isc->isc_tx_size_511, EVCNT_TYPE_MISC,
+ NULL, device_xname(sc->sc_dev), "Tx size 511");
+ evcnt_attach_dynamic(&isc->isc_tx_size_1023, EVCNT_TYPE_MISC,
+ NULL, device_xname(sc->sc_dev), "Tx size 1023");
+ evcnt_attach_dynamic(&isc->isc_tx_size_1522, EVCNT_TYPE_MISC,
+ NULL, device_xname(sc->sc_dev), "Tx size 1522");
+ evcnt_attach_dynamic(&isc->isc_tx_size_big, EVCNT_TYPE_MISC,
+ NULL, device_xname(sc->sc_dev), "Tx jumbo packets");
+
+ evcnt_attach_dynamic(&isc->isc_tx_bytes, EVCNT_TYPE_MISC,
+ NULL, device_xname(sc->sc_dev), "Tx bytes / port");
+ evcnt_attach_dynamic(&isc->isc_tx_dropped_link_down, EVCNT_TYPE_MISC,
+ NULL, device_xname(sc->sc_dev),
+ "Tx dropped due to link down / port");
+ evcnt_attach_dynamic(&isc->isc_tx_unicast, EVCNT_TYPE_MISC,
+ NULL, device_xname(sc->sc_dev), "Tx unicast / port");
+ evcnt_attach_dynamic(&isc->isc_tx_multicast, EVCNT_TYPE_MISC,
+ NULL, device_xname(sc->sc_dev), "Tx multicast / port");
+ evcnt_attach_dynamic(&isc->isc_tx_broadcast, EVCNT_TYPE_MISC,
+ NULL, device_xname(sc->sc_dev), "Tx broadcast / port");
+
+ sc->sc_stats_intval = IXL_STATS_INTERVAL_MSEC;
+ callout_init(&sc->sc_stats_callout, CALLOUT_MPSAFE);
+ callout_setfunc(&sc->sc_stats_callout, ixl_stats_callout, sc);
+ ixl_work_set(&sc->sc_stats_task, ixl_stats_update, sc);
+
return 0;
}
@@ -5499,6 +5679,7 @@ ixl_teardown_stats(struct ixl_softc *sc)
{
struct ixl_tx_ring *txr;
struct ixl_rx_ring *rxr;
+ struct ixl_stats_counters *isc;
unsigned int i;
for (i = 0; i < sc->sc_nqueue_pairs_max; i++) {
@@ -5519,11 +5700,286 @@ ixl_teardown_stats(struct ixl_softc *sc)
evcnt_detach(&rxr->rxr_defer);
}
+ isc = &sc->sc_stats_counters;
+ evcnt_detach(&isc->isc_crc_errors);
+ evcnt_detach(&isc->isc_illegal_bytes);
+ evcnt_detach(&isc->isc_mac_local_faults);
+ evcnt_detach(&isc->isc_mac_remote_faults);
+ evcnt_detach(&isc->isc_link_xon_rx);
+ evcnt_detach(&isc->isc_link_xon_tx);
+ evcnt_detach(&isc->isc_link_xoff_rx);
+ evcnt_detach(&isc->isc_link_xoff_tx);
+ evcnt_detach(&isc->isc_rx_fragments);
+ evcnt_detach(&isc->isc_rx_jabber);
+ evcnt_detach(&isc->isc_rx_bytes);
+ evcnt_detach(&isc->isc_rx_discards);
+ evcnt_detach(&isc->isc_rx_unicast);
+ evcnt_detach(&isc->isc_rx_multicast);
+ evcnt_detach(&isc->isc_rx_broadcast);
+ evcnt_detach(&isc->isc_rx_size_64);
+ evcnt_detach(&isc->isc_rx_size_127);
+ evcnt_detach(&isc->isc_rx_size_255);
+ evcnt_detach(&isc->isc_rx_size_511);
+ evcnt_detach(&isc->isc_rx_size_1023);
+ evcnt_detach(&isc->isc_rx_size_1522);
+ evcnt_detach(&isc->isc_rx_size_big);
+ evcnt_detach(&isc->isc_rx_undersize);
+ evcnt_detach(&isc->isc_rx_oversize);
+ evcnt_detach(&isc->isc_tx_bytes);
+ evcnt_detach(&isc->isc_tx_dropped_link_down);
+ evcnt_detach(&isc->isc_tx_unicast);
+ evcnt_detach(&isc->isc_tx_multicast);
+ evcnt_detach(&isc->isc_tx_broadcast);
+ evcnt_detach(&isc->isc_tx_size_64);
+ evcnt_detach(&isc->isc_tx_size_127);
+ evcnt_detach(&isc->isc_tx_size_255);
+ evcnt_detach(&isc->isc_tx_size_511);
+ evcnt_detach(&isc->isc_tx_size_1023);
+ evcnt_detach(&isc->isc_tx_size_1522);
+ evcnt_detach(&isc->isc_tx_size_big);
+
evcnt_detach(&sc->sc_event_atq);
evcnt_detach(&sc->sc_event_link);
evcnt_detach(&sc->sc_event_ecc_err);
evcnt_detach(&sc->sc_event_pci_exception);
evcnt_detach(&sc->sc_event_crit_err);
+
+ callout_destroy(&sc->sc_stats_callout);
+}
+
+static void
+ixl_stats_callout(void *xsc)
+{
+ struct ixl_softc *sc = xsc;
+
+ ixl_work_add(sc->sc_workq, &sc->sc_stats_task);
+ callout_schedule(&sc->sc_stats_callout, mstohz(sc->sc_stats_intval));
+}
+
+static uint64_t
+ixl_stat_delta(struct ixl_softc *sc, uint32_t reg_hi, uint32_t reg_lo,
+ uint64_t *offset, bool has_offset)
+{
+ uint64_t value, delta;
+ int bitwidth;
+
+ bitwidth = reg_hi == 0 ? 32 : 48;
+
+ value = ixl_rd(sc, reg_lo);
+
+ if (bitwidth > 32) {
+ value |= ((uint64_t)ixl_rd(sc, reg_hi) << 32);
+ }
+
+ if (__predict_true(has_offset)) {
+ delta = value;
+ if (value < *offset)
+ delta += ((uint64_t)1 << bitwidth);
+ delta -= *offset;
+ } else {
+ delta = 0;
+ }
+ atomic_swap_64(offset, value);
+
+ return delta;
+}
+
+static void
+ixl_stats_update(void *xsc)
+{
+ struct ixl_softc *sc = xsc;
+ struct ixl_stats_counters *isc;
+ uint64_t delta;
+
+ isc = &sc->sc_stats_counters;
+
+ /* errors */
+ delta = ixl_stat_delta(sc,
+ 0, I40E_GLPRT_CRCERRS(sc->sc_port),
+ &isc->isc_crc_errors_offset, isc->isc_has_offset);
+ atomic_add_64(&isc->isc_crc_errors.ev_count, delta);
+
+ delta = ixl_stat_delta(sc,
+ 0, I40E_GLPRT_ILLERRC(sc->sc_port),
+ &isc->isc_illegal_bytes_offset, isc->isc_has_offset);
+ atomic_add_64(&isc->isc_illegal_bytes.ev_count, delta);
+
+ /* rx */
+ delta = ixl_stat_delta(sc,
+ I40E_GLPRT_GORCH(sc->sc_port), I40E_GLPRT_GORCL(sc->sc_port),
+ &isc->isc_rx_bytes_offset, isc->isc_has_offset);
+ atomic_add_64(&isc->isc_rx_bytes.ev_count, delta);
+
+ delta = ixl_stat_delta(sc,
+ 0, I40E_GLPRT_RDPC(sc->sc_port),
+ &isc->isc_rx_discards_offset, isc->isc_has_offset);
+ atomic_add_64(&isc->isc_rx_discards.ev_count, delta);
+
+ delta = ixl_stat_delta(sc,
+ I40E_GLPRT_UPRCH(sc->sc_port), I40E_GLPRT_UPRCL(sc->sc_port),
+ &isc->isc_rx_unicast_offset, isc->isc_has_offset);
+ atomic_add_64(&isc->isc_rx_unicast.ev_count, delta);
+
+ delta = ixl_stat_delta(sc,
+ I40E_GLPRT_MPRCH(sc->sc_port), I40E_GLPRT_MPRCL(sc->sc_port),
+ &isc->isc_rx_multicast_offset, isc->isc_has_offset);
+ atomic_add_64(&isc->isc_rx_multicast.ev_count, delta);
+
+ delta = ixl_stat_delta(sc,
+ I40E_GLPRT_BPRCH(sc->sc_port), I40E_GLPRT_BPRCL(sc->sc_port),
+ &isc->isc_rx_broadcast_offset, isc->isc_has_offset);
+ atomic_add_64(&isc->isc_rx_broadcast.ev_count, delta);
+
+ /* Packet size stats rx */
+ delta = ixl_stat_delta(sc,
+ I40E_GLPRT_PRC64H(sc->sc_port), I40E_GLPRT_PRC64L(sc->sc_port),
+ &isc->isc_rx_size_64_offset, isc->isc_has_offset);
+ atomic_add_64(&isc->isc_rx_size_64.ev_count, delta);
+
+ delta = ixl_stat_delta(sc,
+ I40E_GLPRT_PRC127H(sc->sc_port), I40E_GLPRT_PRC127L(sc->sc_port),
+ &isc->isc_rx_size_127_offset, isc->isc_has_offset);
+ atomic_add_64(&isc->isc_rx_size_127.ev_count, delta);
+
+ delta = ixl_stat_delta(sc,
+ I40E_GLPRT_PRC255H(sc->sc_port), I40E_GLPRT_PRC255L(sc->sc_port),
+ &isc->isc_rx_size_255_offset, isc->isc_has_offset);
+ atomic_add_64(&isc->isc_rx_size_255.ev_count, delta);
+
+ delta = ixl_stat_delta(sc,
+ I40E_GLPRT_PRC511H(sc->sc_port), I40E_GLPRT_PRC511L(sc->sc_port),
+ &isc->isc_rx_size_511_offset, isc->isc_has_offset);
+ atomic_add_64(&isc->isc_rx_size_511.ev_count, delta);
+
+ delta = ixl_stat_delta(sc,
+ I40E_GLPRT_PRC1023H(sc->sc_port), I40E_GLPRT_PRC1023L(sc->sc_port),
+ &isc->isc_rx_size_1023_offset, isc->isc_has_offset);
+ atomic_add_64(&isc->isc_rx_size_1023.ev_count, delta);
+
+ delta = ixl_stat_delta(sc,
+ I40E_GLPRT_PRC1522H(sc->sc_port), I40E_GLPRT_PRC1522L(sc->sc_port),
+ &isc->isc_rx_size_1522_offset, isc->isc_has_offset);
+ atomic_add_64(&isc->isc_rx_size_1522.ev_count, delta);
+
+ delta = ixl_stat_delta(sc,
+ I40E_GLPRT_PRC9522H(sc->sc_port), I40E_GLPRT_PRC9522L(sc->sc_port),
+ &isc->isc_rx_size_big_offset, isc->isc_has_offset);
+ atomic_add_64(&isc->isc_rx_size_big.ev_count, delta);
+
+ delta = ixl_stat_delta(sc,
+ 0, I40E_GLPRT_RUC(sc->sc_port),
+ &isc->isc_rx_undersize_offset, isc->isc_has_offset);
+ atomic_add_64(&isc->isc_rx_undersize.ev_count, delta);
+
+ delta = ixl_stat_delta(sc,
+ 0, I40E_GLPRT_ROC(sc->sc_port),
+ &isc->isc_rx_oversize_offset, isc->isc_has_offset);
+ atomic_add_64(&isc->isc_rx_oversize.ev_count, delta);
+
+ /* tx */
+ delta = ixl_stat_delta(sc,
+ I40E_GLPRT_GOTCH(sc->sc_port), I40E_GLPRT_GOTCL(sc->sc_port),
+ &isc->isc_tx_bytes_offset, isc->isc_has_offset);
+ atomic_add_64(&isc->isc_tx_bytes.ev_count, delta);
+
+ delta = ixl_stat_delta(sc,
+ 0, I40E_GLPRT_TDOLD(sc->sc_port),
+ &isc->isc_tx_dropped_link_down_offset, isc->isc_has_offset);
+ atomic_add_64(&isc->isc_tx_dropped_link_down.ev_count, delta);
+
+ delta = ixl_stat_delta(sc,
+ I40E_GLPRT_UPTCH(sc->sc_port), I40E_GLPRT_UPTCL(sc->sc_port),
+ &isc->isc_tx_unicast_offset, isc->isc_has_offset);
+ atomic_add_64(&isc->isc_tx_unicast.ev_count, delta);
+
+ delta = ixl_stat_delta(sc,
+ I40E_GLPRT_MPTCH(sc->sc_port), I40E_GLPRT_MPTCL(sc->sc_port),
+ &isc->isc_tx_multicast_offset, isc->isc_has_offset);
+ atomic_add_64(&isc->isc_tx_multicast.ev_count, delta);
+
+ delta = ixl_stat_delta(sc,
+ I40E_GLPRT_BPTCH(sc->sc_port), I40E_GLPRT_BPTCL(sc->sc_port),
+ &isc->isc_tx_broadcast_offset, isc->isc_has_offset);
+ atomic_add_64(&isc->isc_tx_broadcast.ev_count, delta);
+
+ /* Packet size stats tx */
+ delta = ixl_stat_delta(sc,
+ I40E_GLPRT_PTC64L(sc->sc_port), I40E_GLPRT_PTC64L(sc->sc_port),
+ &isc->isc_tx_size_64_offset, isc->isc_has_offset);
+ atomic_add_64(&isc->isc_tx_size_64.ev_count, delta);
+
+ delta = ixl_stat_delta(sc,
+ I40E_GLPRT_PTC127H(sc->sc_port), I40E_GLPRT_PTC127L(sc->sc_port),
+ &isc->isc_tx_size_127_offset, isc->isc_has_offset);
+ atomic_add_64(&isc->isc_tx_size_127.ev_count, delta);
+
+ delta = ixl_stat_delta(sc,
+ I40E_GLPRT_PTC255H(sc->sc_port), I40E_GLPRT_PTC255L(sc->sc_port),
+ &isc->isc_tx_size_255_offset, isc->isc_has_offset);
+ atomic_add_64(&isc->isc_tx_size_255.ev_count, delta);
+
+ delta = ixl_stat_delta(sc,
+ I40E_GLPRT_PTC511H(sc->sc_port), I40E_GLPRT_PTC511L(sc->sc_port),
+ &isc->isc_tx_size_511_offset, isc->isc_has_offset);
+ atomic_add_64(&isc->isc_tx_size_511.ev_count, delta);
+
+ delta = ixl_stat_delta(sc,
+ I40E_GLPRT_PTC1023H(sc->sc_port), I40E_GLPRT_PTC1023L(sc->sc_port),
+ &isc->isc_tx_size_1023_offset, isc->isc_has_offset);
+ atomic_add_64(&isc->isc_tx_size_1023.ev_count, delta);
+
+ delta = ixl_stat_delta(sc,
+ I40E_GLPRT_PTC1522H(sc->sc_port), I40E_GLPRT_PTC1522L(sc->sc_port),
+ &isc->isc_tx_size_1522_offset, isc->isc_has_offset);
+ atomic_add_64(&isc->isc_tx_size_1522.ev_count, delta);
+
+ delta = ixl_stat_delta(sc,
+ I40E_GLPRT_PTC9522H(sc->sc_port), I40E_GLPRT_PTC9522L(sc->sc_port),
+ &isc->isc_tx_size_big_offset, isc->isc_has_offset);
+ atomic_add_64(&isc->isc_tx_size_big.ev_count, delta);
+
+ /* mac faults */
+ delta = ixl_stat_delta(sc,
+ 0, I40E_GLPRT_MLFC(sc->sc_port),
+ &isc->isc_mac_local_faults_offset, isc->isc_has_offset);
+ atomic_add_64(&isc->isc_mac_local_faults.ev_count, delta);
+
+ delta = ixl_stat_delta(sc,
+ 0, I40E_GLPRT_MRFC(sc->sc_port),
+ &isc->isc_mac_remote_faults_offset, isc->isc_has_offset);
+ atomic_add_64(&isc->isc_mac_remote_faults.ev_count, delta);
+
+ /* Flow control (LFC) stats */
+ delta = ixl_stat_delta(sc,
+ 0, I40E_GLPRT_LXONRXC(sc->sc_port),
+ &isc->isc_link_xon_rx_offset, isc->isc_has_offset);
+ atomic_add_64(&isc->isc_link_xon_rx.ev_count, delta);
+
+ delta = ixl_stat_delta(sc,
+ 0, I40E_GLPRT_LXONTXC(sc->sc_port),
+ &isc->isc_link_xon_tx_offset, isc->isc_has_offset);
+ atomic_add_64(&isc->isc_link_xon_tx.ev_count, delta);
+
+ delta = ixl_stat_delta(sc,
+ 0, I40E_GLPRT_LXOFFRXC(sc->sc_port),
+ &isc->isc_link_xoff_rx_offset, isc->isc_has_offset);
+ atomic_add_64(&isc->isc_link_xoff_rx.ev_count, delta);
+
+ delta = ixl_stat_delta(sc,
+ 0, I40E_GLPRT_LXOFFTXC(sc->sc_port),
+ &isc->isc_link_xoff_tx_offset, isc->isc_has_offset);
+ atomic_add_64(&isc->isc_link_xoff_tx.ev_count, delta);
+
+ /* fragments */
+ delta = ixl_stat_delta(sc,
+ 0, I40E_GLPRT_RFC(sc->sc_port),
+ &isc->isc_rx_fragments_offset, isc->isc_has_offset);
+ atomic_add_64(&isc->isc_rx_fragments.ev_count, delta);
+
+ delta = ixl_stat_delta(sc,
+ 0, I40E_GLPRT_RJC(sc->sc_port),
+ &isc->isc_rx_jabber_offset, isc->isc_has_offset);
+ atomic_add_64(&isc->isc_rx_jabber.ev_count, delta);
}
static int
@@ -5551,6 +6007,11 @@ ixl_setup_sysctls(struct ixl_softc *sc)
if (error)
goto out;
+ error = sysctl_createv(log, 0, &rnode, NULL,
+ CTLFLAG_READONLY, CTLTYPE_INT, "stats_interval",
+ SYSCTL_DESCR("Statistics collection interval in milliseconds"),
+ NULL, 0, &sc->sc_stats_intval, 0, CTL_CREATE, CTL_EOL);
+
error = sysctl_createv(log, 0, &rnode, &rxnode,
0, CTLTYPE_NODE, "rx",
SYSCTL_DESCR("ixl information and settings for Rx"),