summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorarybchik <arybchik@FreeBSD.org>2015-02-22 19:25:57 +0000
committerarybchik <arybchik@FreeBSD.org>2015-02-22 19:25:57 +0000
commitefd08737732ac70478e1f8d82df8218dae72aed3 (patch)
treee4468c34147b2238b44c936ea59960d8e7a3ff93
parentcb28467a38a87643561f22b3c482ed1349ca3c0d (diff)
downloadFreeBSD-src-efd08737732ac70478e1f8d82df8218dae72aed3.zip
FreeBSD-src-efd08737732ac70478e1f8d82df8218dae72aed3.tar.gz
sfxge: implement if_get_counter callback
Sponsored by: Solarflare Communications, Inc. Approved by: gnn (mentor)
-rw-r--r--sys/dev/sfxge/sfxge.c6
-rw-r--r--sys/dev/sfxge/sfxge.h1
-rw-r--r--sys/dev/sfxge/sfxge_port.c62
-rw-r--r--sys/dev/sfxge/sfxge_tx.c23
-rw-r--r--sys/dev/sfxge/sfxge_tx.h1
5 files changed, 91 insertions, 2 deletions
diff --git a/sys/dev/sfxge/sfxge.c b/sys/dev/sfxge/sfxge.c
index 7f4ce95..6206099 100644
--- a/sys/dev/sfxge/sfxge.c
+++ b/sys/dev/sfxge/sfxge.c
@@ -61,10 +61,10 @@ __FBSDID("$FreeBSD$");
#define SFXGE_CAP (IFCAP_VLAN_MTU | \
IFCAP_HWCSUM | IFCAP_VLAN_HWCSUM | IFCAP_TSO | \
IFCAP_JUMBO_MTU | IFCAP_LRO | \
- IFCAP_VLAN_HWTSO | IFCAP_LINKSTATE)
+ IFCAP_VLAN_HWTSO | IFCAP_LINKSTATE | IFCAP_HWSTATS)
#define SFXGE_CAP_ENABLE SFXGE_CAP
#define SFXGE_CAP_FIXED (IFCAP_VLAN_MTU | IFCAP_HWCSUM | IFCAP_VLAN_HWCSUM | \
- IFCAP_JUMBO_MTU | IFCAP_LINKSTATE)
+ IFCAP_JUMBO_MTU | IFCAP_LINKSTATE | IFCAP_HWSTATS)
MALLOC_DEFINE(M_SFXGE, "sfxge", "Solarflare 10GigE driver");
@@ -343,6 +343,8 @@ sfxge_ifnet_init(struct ifnet *ifp, struct sfxge_softc *sc)
mtx_init(&sc->tx_lock, sc->tx_lock_name, NULL, MTX_DEF);
#endif
+ ifp->if_get_counter = sfxge_get_counter;
+
if ((rc = sfxge_port_ifmedia_init(sc)) != 0)
goto fail;
diff --git a/sys/dev/sfxge/sfxge.h b/sys/dev/sfxge/sfxge.h
index 55b40bb..40f8f49 100644
--- a/sys/dev/sfxge/sfxge.h
+++ b/sys/dev/sfxge/sfxge.h
@@ -324,6 +324,7 @@ extern void sfxge_mac_link_update(struct sfxge_softc *sc,
efx_link_mode_t mode);
extern int sfxge_mac_filter_set(struct sfxge_softc *sc);
extern int sfxge_port_ifmedia_init(struct sfxge_softc *sc);
+extern uint64_t sfxge_get_counter(struct ifnet *ifp, ift_counter c);
#define SFXGE_MAX_MTU (9 * 1024)
diff --git a/sys/dev/sfxge/sfxge_port.c b/sys/dev/sfxge/sfxge_port.c
index 4953c92..a4cb812 100644
--- a/sys/dev/sfxge/sfxge_port.c
+++ b/sys/dev/sfxge/sfxge_port.c
@@ -85,6 +85,68 @@ out:
return (rc);
}
+uint64_t
+sfxge_get_counter(struct ifnet *ifp, ift_counter c)
+{
+ struct sfxge_softc *sc = ifp->if_softc;
+ uint64_t *mac_stats;
+ uint64_t val;
+
+ SFXGE_PORT_LOCK(&sc->port);
+
+ /* Ignore error and use old values */
+ (void)sfxge_mac_stat_update(sc);
+
+ mac_stats = (uint64_t *)sc->port.mac_stats.decode_buf;
+
+ switch (c) {
+ case IFCOUNTER_IPACKETS:
+ val = mac_stats[EFX_MAC_RX_PKTS];
+ break;
+ case IFCOUNTER_IERRORS:
+ val = mac_stats[EFX_MAC_RX_ERRORS];
+ break;
+ case IFCOUNTER_OPACKETS:
+ val = mac_stats[EFX_MAC_TX_PKTS];
+ break;
+ case IFCOUNTER_OERRORS:
+ val = mac_stats[EFX_MAC_TX_ERRORS];
+ break;
+ case IFCOUNTER_COLLISIONS:
+ val = mac_stats[EFX_MAC_TX_SGL_COL_PKTS] +
+ mac_stats[EFX_MAC_TX_MULT_COL_PKTS] +
+ mac_stats[EFX_MAC_TX_EX_COL_PKTS] +
+ mac_stats[EFX_MAC_TX_LATE_COL_PKTS];
+ break;
+ case IFCOUNTER_IBYTES:
+ val = mac_stats[EFX_MAC_RX_OCTETS];
+ break;
+ case IFCOUNTER_OBYTES:
+ val = mac_stats[EFX_MAC_TX_OCTETS];
+ break;
+ case IFCOUNTER_OMCASTS:
+ val = mac_stats[EFX_MAC_TX_MULTICST_PKTS] +
+ mac_stats[EFX_MAC_TX_BRDCST_PKTS];
+ break;
+ case IFCOUNTER_OQDROPS:
+ SFXGE_PORT_UNLOCK(&sc->port);
+ return (sfxge_tx_get_drops(sc));
+ case IFCOUNTER_IMCASTS:
+ /* if_imcasts is maintained in net/if_ethersubr.c */
+ case IFCOUNTER_IQDROPS:
+ /* if_iqdrops is maintained in net/if_ethersubr.c */
+ case IFCOUNTER_NOPROTO:
+ /* if_noproto is maintained in net/if_ethersubr.c */
+ default:
+ SFXGE_PORT_UNLOCK(&sc->port);
+ return (if_get_counter_default(ifp, c));
+ }
+
+ SFXGE_PORT_UNLOCK(&sc->port);
+
+ return (val);
+}
+
static int
sfxge_mac_stat_handler(SYSCTL_HANDLER_ARGS)
{
diff --git a/sys/dev/sfxge/sfxge_tx.c b/sys/dev/sfxge/sfxge_tx.c
index 13a83f8..a7263c8 100644
--- a/sys/dev/sfxge/sfxge_tx.c
+++ b/sys/dev/sfxge/sfxge_tx.c
@@ -1566,6 +1566,29 @@ sfxge_tx_stat_init(struct sfxge_softc *sc)
}
}
+uint64_t
+sfxge_tx_get_drops(struct sfxge_softc *sc)
+{
+ unsigned int index;
+ uint64_t drops = 0;
+ struct sfxge_txq *txq;
+
+ /* Sum across all TX queues */
+ for (index = 0; index < sc->txq_count; index++) {
+ txq = sc->txq[index];
+ /*
+ * In theory, txq->put_overflow and txq->netdown_drops
+ * should use atomic operation and other should be
+ * obtained under txq lock, but it is just statistics.
+ */
+ drops += txq->drops + txq->get_overflow +
+ txq->get_non_tcp_overflow +
+ txq->put_overflow + txq->netdown_drops +
+ txq->tso_pdrop_too_many + txq->tso_pdrop_no_rsrc;
+ }
+ return (drops);
+}
+
void
sfxge_tx_fini(struct sfxge_softc *sc)
{
diff --git a/sys/dev/sfxge/sfxge_tx.h b/sys/dev/sfxge/sfxge_tx.h
index 3965ffd..c7a8c12 100644
--- a/sys/dev/sfxge/sfxge_tx.h
+++ b/sys/dev/sfxge/sfxge_tx.h
@@ -217,6 +217,7 @@ struct sfxge_txq {
struct sfxge_evq;
extern int sfxge_tx_packet_add(struct sfxge_txq *, struct mbuf *);
+extern uint64_t sfxge_tx_get_drops(struct sfxge_softc *sc);
extern int sfxge_tx_init(struct sfxge_softc *sc);
extern void sfxge_tx_fini(struct sfxge_softc *sc);
OpenPOWER on IntegriCloud