diff options
author | arybchik <arybchik@FreeBSD.org> | 2015-02-22 19:25:57 +0000 |
---|---|---|
committer | arybchik <arybchik@FreeBSD.org> | 2015-02-22 19:25:57 +0000 |
commit | efd08737732ac70478e1f8d82df8218dae72aed3 (patch) | |
tree | e4468c34147b2238b44c936ea59960d8e7a3ff93 | |
parent | cb28467a38a87643561f22b3c482ed1349ca3c0d (diff) | |
download | FreeBSD-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.c | 6 | ||||
-rw-r--r-- | sys/dev/sfxge/sfxge.h | 1 | ||||
-rw-r--r-- | sys/dev/sfxge/sfxge_port.c | 62 | ||||
-rw-r--r-- | sys/dev/sfxge/sfxge_tx.c | 23 | ||||
-rw-r--r-- | sys/dev/sfxge/sfxge_tx.h | 1 |
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); |