diff options
author | 2020-09-04 15:18:05 +0000 | |
---|---|---|
committer | 2020-09-04 15:18:05 +0000 | |
commit | 6ece48cc0fee1ba7d98321a0c92c092f0e3dcb8c (patch) | |
tree | 5d7bc6b3096adcab8fbce17e0ea3ce7aa64697fa | |
parent | Replace TAILQ concatenation loop with TAILQ_CONCAT (diff) | |
download | wireguard-openbsd-6ece48cc0fee1ba7d98321a0c92c092f0e3dcb8c.tar.xz wireguard-openbsd-6ece48cc0fee1ba7d98321a0c92c092f0e3dcb8c.zip |
Add kstat to cnmac(4)
This makes various receive and transmit event counters readable. This
additionally replaces the old, and somewhat unusual, way of updating
error counters in ifp.
Most of the hardware counters are 32 bits wide. Hence the code polls
them periodically and adds the values to 64-bit software counters.
The hardware counters are cleared when read.
-rw-r--r-- | sys/arch/octeon/dev/cn30xxgmx.c | 124 | ||||
-rw-r--r-- | sys/arch/octeon/dev/cn30xxgmxvar.h | 16 | ||||
-rw-r--r-- | sys/arch/octeon/dev/cn30xxpip.c | 85 | ||||
-rw-r--r-- | sys/arch/octeon/dev/cn30xxpipreg.h | 16 | ||||
-rw-r--r-- | sys/arch/octeon/dev/cn30xxpipvar.h | 14 | ||||
-rw-r--r-- | sys/arch/octeon/dev/if_cnmac.c | 130 | ||||
-rw-r--r-- | sys/arch/octeon/dev/if_cnmacvar.h | 10 | ||||
-rw-r--r-- | sys/arch/octeon/include/octeonvar.h | 49 |
8 files changed, 353 insertions, 91 deletions
diff --git a/sys/arch/octeon/dev/cn30xxgmx.c b/sys/arch/octeon/dev/cn30xxgmx.c index 4e15633d22e..3ff9d6b848b 100644 --- a/sys/arch/octeon/dev/cn30xxgmx.c +++ b/sys/arch/octeon/dev/cn30xxgmx.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cn30xxgmx.c,v 1.44 2020/07/04 09:00:09 visa Exp $ */ +/* $OpenBSD: cn30xxgmx.c,v 1.45 2020/09/04 15:18:05 visa Exp $ */ /* * Copyright (c) 2007 Internet Initiative Japan, Inc. @@ -433,41 +433,28 @@ cn30xxgmx_link_enable(struct cn30xxgmx_port_softc *sc, int enable) return 0; } -/* XXX RGMII specific */ -int +void cn30xxgmx_stats_init(struct cn30xxgmx_port_softc *sc) { - _GMX_PORT_WR8(sc, GMX0_RX0_STATS_PKTS, 0x0ULL); - _GMX_PORT_WR8(sc, GMX0_RX0_STATS_PKTS_DRP, 0x0ULL); - _GMX_PORT_WR8(sc, GMX0_RX0_STATS_PKTS_BAD, 0x0ULL); - _GMX_PORT_WR8(sc, GMX0_TX0_STAT0, 0x0ULL); - _GMX_PORT_WR8(sc, GMX0_TX0_STAT1, 0x0ULL); - _GMX_PORT_WR8(sc, GMX0_TX0_STAT3, 0x0ULL); - _GMX_PORT_WR8(sc, GMX0_TX0_STAT9, 0x0ULL); - return 0; -} - -int -cn30xxgmx_tx_stats_rd_clr(struct cn30xxgmx_port_softc *sc, int enable) -{ - _GMX_PORT_WR8(sc, GMX0_TX0_STATS_CTL, enable ? 0x1ULL : 0x0ULL); - return 0; -} - -int -cn30xxgmx_rx_stats_rd_clr(struct cn30xxgmx_port_softc *sc, int enable) -{ - _GMX_PORT_WR8(sc, GMX0_RX0_STATS_CTL, enable ? 0x1ULL : 0x0ULL); - return 0; -} - -void -cn30xxgmx_rx_stats_dec_bad(struct cn30xxgmx_port_softc *sc) -{ - uint64_t tmp; - - tmp = _GMX_PORT_RD8(sc, GMX0_RX0_STATS_PKTS_BAD); - _GMX_PORT_WR8(sc, GMX0_RX0_STATS_PKTS_BAD, tmp - 1); + _GMX_PORT_WR8(sc, GMX0_RX0_STATS_CTL, 1); + _GMX_PORT_WR8(sc, GMX0_TX0_STATS_CTL, 1); + + _GMX_PORT_WR8(sc, GMX0_RX0_STATS_PKTS, 0); + _GMX_PORT_WR8(sc, GMX0_RX0_STATS_OCTS, 0); + _GMX_PORT_WR8(sc, GMX0_RX0_STATS_PKTS_CTL, 0); + _GMX_PORT_WR8(sc, GMX0_RX0_STATS_PKTS_DMAC, 0); + _GMX_PORT_WR8(sc, GMX0_RX0_STATS_PKTS_DRP, 0); + _GMX_PORT_WR8(sc, GMX0_RX0_STATS_PKTS_BAD, 0); + _GMX_PORT_WR8(sc, GMX0_TX0_STAT0, 0); + _GMX_PORT_WR8(sc, GMX0_TX0_STAT1, 0); + _GMX_PORT_WR8(sc, GMX0_TX0_STAT2, 0); + _GMX_PORT_WR8(sc, GMX0_TX0_STAT3, 0); + _GMX_PORT_WR8(sc, GMX0_TX0_STAT4, 0); + _GMX_PORT_WR8(sc, GMX0_TX0_STAT5, 0); + _GMX_PORT_WR8(sc, GMX0_TX0_STAT6, 0); + _GMX_PORT_WR8(sc, GMX0_TX0_STAT7, 0); + _GMX_PORT_WR8(sc, GMX0_TX0_STAT8, 0); + _GMX_PORT_WR8(sc, GMX0_TX0_STAT9, 0); } int @@ -1258,23 +1245,60 @@ cn30xxgmx_sgmii_timing(struct cn30xxgmx_port_softc *sc) return 0; } +#if NKSTAT > 0 void -cn30xxgmx_stats(struct cn30xxgmx_port_softc *sc) +cn30xxgmx_kstat_read(struct cn30xxgmx_port_softc *sc, struct kstat_kv *kvs) { - struct ifnet *ifp = &sc->sc_port_ac->ac_if; - uint64_t tmp; - - ifp->if_ierrors += - (uint32_t)_GMX_PORT_RD8(sc, GMX0_RX0_STATS_PKTS_BAD); - ifp->if_iqdrops += + uint64_t val; + + kstat_kv_u64(&kvs[cnmac_stat_rx_totp_gmx]) += + (uint32_t)_GMX_PORT_RD8(sc, GMX0_RX0_STATS_PKTS); + kstat_kv_u64(&kvs[cnmac_stat_rx_toto_gmx]) += + (uint32_t)_GMX_PORT_RD8(sc, GMX0_RX0_STATS_OCTS); + kstat_kv_u64(&kvs[cnmac_stat_rx_ctl]) += + (uint32_t)_GMX_PORT_RD8(sc, GMX0_RX0_STATS_PKTS_CTL); + kstat_kv_u64(&kvs[cnmac_stat_rx_dmac]) += + (uint32_t)_GMX_PORT_RD8(sc, GMX0_RX0_STATS_PKTS_DMAC); + kstat_kv_u64(&kvs[cnmac_stat_rx_drop]) += (uint32_t)_GMX_PORT_RD8(sc, GMX0_RX0_STATS_PKTS_DRP); - tmp = _GMX_PORT_RD8(sc, GMX0_TX0_STAT0); - ifp->if_oerrors += - (uint32_t)tmp + ((uint32_t)(tmp >> 32) * 16); - ifp->if_collisions += ((uint32_t)tmp) * 16; - tmp = _GMX_PORT_RD8(sc, GMX0_TX0_STAT1); - ifp->if_collisions += - ((uint32_t)tmp * 2) + (uint32_t)(tmp >> 32); - tmp = _GMX_PORT_RD8(sc, GMX0_TX0_STAT9); - ifp->if_oerrors += (uint32_t)(tmp >> 32); + kstat_kv_u64(&kvs[cnmac_stat_rx_bad]) += + (uint32_t)_GMX_PORT_RD8(sc, GMX0_RX0_STATS_PKTS_BAD); + + val = _GMX_PORT_RD8(sc, GMX0_TX0_STAT0); + kstat_kv_u64(&kvs[cnmac_stat_tx_coll]) += (uint32_t)val; + kstat_kv_u64(&kvs[cnmac_stat_tx_defer]) += val >> 32; + + val = _GMX_PORT_RD8(sc, GMX0_TX0_STAT1); + kstat_kv_u64(&kvs[cnmac_stat_tx_mcol]) += (uint32_t)val; + kstat_kv_u64(&kvs[cnmac_stat_tx_scol]) += val >> 32; + + kstat_kv_u64(&kvs[cnmac_stat_tx_toto]) += + (uint32_t)_GMX_PORT_RD8(sc, GMX0_TX0_STAT2); + kstat_kv_u64(&kvs[cnmac_stat_tx_totp]) += + (uint32_t)_GMX_PORT_RD8(sc, GMX0_TX0_STAT3); + + val = _GMX_PORT_RD8(sc, GMX0_TX0_STAT4); + kstat_kv_u64(&kvs[cnmac_stat_tx_hmin]) += (uint32_t)val; + kstat_kv_u64(&kvs[cnmac_stat_tx_h64]) += val >> 32; + + val = _GMX_PORT_RD8(sc, GMX0_TX0_STAT5); + kstat_kv_u64(&kvs[cnmac_stat_tx_h127]) += (uint32_t)val; + kstat_kv_u64(&kvs[cnmac_stat_tx_h255]) += val >> 32; + + val = _GMX_PORT_RD8(sc, GMX0_TX0_STAT6); + kstat_kv_u64(&kvs[cnmac_stat_tx_h511]) += (uint32_t)val; + kstat_kv_u64(&kvs[cnmac_stat_tx_h1023]) += val >> 32; + + val = _GMX_PORT_RD8(sc, GMX0_TX0_STAT7); + kstat_kv_u64(&kvs[cnmac_stat_tx_h1518]) += (uint32_t)val; + kstat_kv_u64(&kvs[cnmac_stat_tx_hmax]) += val >> 32; + + val = _GMX_PORT_RD8(sc, GMX0_TX0_STAT8); + kstat_kv_u64(&kvs[cnmac_stat_tx_bcast]) += (uint32_t)val; + kstat_kv_u64(&kvs[cnmac_stat_tx_mcast]) += val >> 32; + + val = _GMX_PORT_RD8(sc, GMX0_TX0_STAT9); + kstat_kv_u64(&kvs[cnmac_stat_tx_ctl]) += (uint32_t)val; + kstat_kv_u64(&kvs[cnmac_stat_tx_uflow]) += val >> 32; } +#endif diff --git a/sys/arch/octeon/dev/cn30xxgmxvar.h b/sys/arch/octeon/dev/cn30xxgmxvar.h index 53ac130d503..a0e0cabab7e 100644 --- a/sys/arch/octeon/dev/cn30xxgmxvar.h +++ b/sys/arch/octeon/dev/cn30xxgmxvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: cn30xxgmxvar.h,v 1.9 2020/07/04 09:00:09 visa Exp $ */ +/* $OpenBSD: cn30xxgmxvar.h,v 1.10 2020/09/04 15:18:05 visa Exp $ */ /* * Copyright (c) 2007 Internet Initiative Japan, Inc. @@ -29,6 +29,7 @@ #ifndef _CN30XXGMXVAR_H_ #define _CN30XXGMXVAR_H_ +#include <sys/kstat.h> #include <sys/socket.h> #include <net/if.h> #include <net/if_media.h> @@ -37,6 +38,8 @@ #include <dev/mii/mii.h> #include <dev/mii/miivar.h> +#include "kstat.h" + #define GMX_MII_PORT 1 #define GMX_GMII_PORT 2 #define GMX_RGMII_PORT 3 @@ -99,10 +102,7 @@ struct cn30xxgmx_attach_args { }; int cn30xxgmx_link_enable(struct cn30xxgmx_port_softc *, int); -int cn30xxgmx_tx_stats_rd_clr(struct cn30xxgmx_port_softc *, int); -int cn30xxgmx_rx_stats_rd_clr(struct cn30xxgmx_port_softc *, int); -void cn30xxgmx_rx_stats_dec_bad(struct cn30xxgmx_port_softc *); -int cn30xxgmx_stats_init(struct cn30xxgmx_port_softc *); +void cn30xxgmx_stats_init(struct cn30xxgmx_port_softc *); void cn30xxgmx_tx_int_enable(struct cn30xxgmx_port_softc *, int); void cn30xxgmx_rx_int_enable(struct cn30xxgmx_port_softc *, int); int cn30xxgmx_rx_frm_ctl_enable(struct cn30xxgmx_port_softc *, @@ -116,10 +116,12 @@ int cn30xxgmx_port_enable(struct cn30xxgmx_port_softc *, int); int cn30xxgmx_reset_speed(struct cn30xxgmx_port_softc *); int cn30xxgmx_reset_flowctl(struct cn30xxgmx_port_softc *); int cn30xxgmx_reset_timing(struct cn30xxgmx_port_softc *); -void cn30xxgmx_stats(struct cn30xxgmx_port_softc *); uint64_t cn30xxgmx_get_rx_int_reg(struct cn30xxgmx_port_softc *sc); uint64_t cn30xxgmx_get_tx_int_reg(struct cn30xxgmx_port_softc *sc); -static inline int cn30xxgmx_link_status(struct cn30xxgmx_port_softc *); +#if NKSTAT > 0 +void cn30xxgmx_kstat_read(struct cn30xxgmx_port_softc *, + struct kstat_kv *); +#endif static inline int cn30xxgmx_link_status(struct cn30xxgmx_port_softc *sc) diff --git a/sys/arch/octeon/dev/cn30xxpip.c b/sys/arch/octeon/dev/cn30xxpip.c index 9094d08af43..f63763409fd 100644 --- a/sys/arch/octeon/dev/cn30xxpip.c +++ b/sys/arch/octeon/dev/cn30xxpip.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cn30xxpip.c,v 1.9 2019/09/22 05:16:05 visa Exp $ */ +/* $OpenBSD: cn30xxpip.c,v 1.10 2020/09/04 15:18:05 visa Exp $ */ /* * Copyright (c) 2007 Internet Initiative Japan, Inc. @@ -64,6 +64,11 @@ cn30xxpip_init(struct cn30xxpip_attach_args *aa, if (status != 0) panic("can't map %s space", "pip register"); + status = bus_space_subregion(sc->sc_regt, sc->sc_regh, + PIP_STAT_BASE(sc->sc_port), PIP_STAT_SIZE, &sc->sc_regh_stat); + if (status != 0) + panic("can't map stat register space"); + *rsc = sc; } @@ -72,6 +77,11 @@ cn30xxpip_init(struct cn30xxpip_attach_args *aa, #define _PIP_WR8(sc, off, v) \ bus_space_write_8((sc)->sc_regt, (sc)->sc_regh, (off), (v)) +#define _PIP_STAT_RD8(sc, off) \ + bus_space_read_8((sc)->sc_regt, (sc)->sc_regh_stat, (off)) +#define _PIP_STAT_WR8(sc, off, v) \ + bus_space_write_8((sc)->sc_regt, (sc)->sc_regh_stat, (off), (v)) + int cn30xxpip_port_config(struct cn30xxpip_softc *sc) { @@ -141,25 +151,66 @@ cn30xxpip_prt_cfg_enable(struct cn30xxpip_softc *sc, uint64_t prt_cfg, } void -cn30xxpip_stats(struct cn30xxpip_softc *sc, struct ifnet *ifp, int gmx_port) +cn30xxpip_stats_init(struct cn30xxpip_softc *sc) +{ + /* XXX */ + _PIP_WR8(sc, PIP_STAT_CTL_OFFSET, 1); + + _PIP_STAT_WR8(sc, PIP_STAT0_PRT, 0); + _PIP_STAT_WR8(sc, PIP_STAT1_PRT, 0); + _PIP_STAT_WR8(sc, PIP_STAT2_PRT, 0); + _PIP_STAT_WR8(sc, PIP_STAT3_PRT, 0); + _PIP_STAT_WR8(sc, PIP_STAT4_PRT, 0); + _PIP_STAT_WR8(sc, PIP_STAT5_PRT, 0); + _PIP_STAT_WR8(sc, PIP_STAT6_PRT, 0); + _PIP_STAT_WR8(sc, PIP_STAT7_PRT, 0); + _PIP_STAT_WR8(sc, PIP_STAT8_PRT, 0); + _PIP_STAT_WR8(sc, PIP_STAT9_PRT, 0); +} + +#if NKSTAT > 0 +void +cn30xxpip_kstat_read(struct cn30xxpip_softc *sc, struct kstat_kv *kvs) { - uint64_t tmp, pkts; - uint64_t pip_stat_ctl; + uint64_t val; + + val = _PIP_STAT_RD8(sc, PIP_STAT0_PRT); + kstat_kv_u64(&kvs[cnmac_stat_rx_qdpo]) += (uint32_t)val; + kstat_kv_u64(&kvs[cnmac_stat_rx_qdpp]) += val >> 32; + + val = _PIP_STAT_RD8(sc, PIP_STAT1_PRT); + kstat_kv_u64(&kvs[cnmac_stat_rx_toto_pip]) += (uint32_t)val; + + val = _PIP_STAT_RD8(sc, PIP_STAT2_PRT); + kstat_kv_u64(&kvs[cnmac_stat_rx_raw]) += (uint32_t)val; + kstat_kv_u64(&kvs[cnmac_stat_rx_totp_pip]) += val >> 32; + + val = _PIP_STAT_RD8(sc, PIP_STAT3_PRT); + kstat_kv_u64(&kvs[cnmac_stat_rx_mcast]) += (uint32_t)val; + kstat_kv_u64(&kvs[cnmac_stat_rx_bcast]) += val >> 32; + + val = _PIP_STAT_RD8(sc, PIP_STAT4_PRT); + kstat_kv_u64(&kvs[cnmac_stat_rx_h64]) += (uint32_t)val; + kstat_kv_u64(&kvs[cnmac_stat_rx_h127]) += val >> 32; + + val = _PIP_STAT_RD8(sc, PIP_STAT5_PRT); + kstat_kv_u64(&kvs[cnmac_stat_rx_h255]) += (uint32_t)val; + kstat_kv_u64(&kvs[cnmac_stat_rx_h511]) += val >> 32; - if (sc == NULL || ifp == NULL) - panic("%s: invalid argument. sc=%p, ifp=%p\n", __func__, - sc, ifp); + val = _PIP_STAT_RD8(sc, PIP_STAT6_PRT); + kstat_kv_u64(&kvs[cnmac_stat_rx_h1023]) += (uint32_t)val; + kstat_kv_u64(&kvs[cnmac_stat_rx_h1518]) += val >> 32; - if (gmx_port < 0 || gmx_port >= GMX_PORT_NUNITS) { - printf("%s: invalid gmx_port %d\n", __func__, gmx_port); - return; - } + val = _PIP_STAT_RD8(sc, PIP_STAT7_PRT); + kstat_kv_u64(&kvs[cnmac_stat_rx_hmax]) += (uint32_t)val; + kstat_kv_u64(&kvs[cnmac_stat_rx_fcs]) += val >> 32; - pip_stat_ctl = _PIP_RD8(sc, PIP_STAT_CTL_OFFSET); - _PIP_WR8(sc, PIP_STAT_CTL_OFFSET, pip_stat_ctl | PIP_STAT_CTL_RDCLR); - tmp = _PIP_RD8(sc, PIP_STAT0_PRT_OFFSET(gmx_port)); - pkts = (tmp & 0xffffffff00000000ULL) >> 32; - ifp->if_iqdrops += pkts; + val = _PIP_STAT_RD8(sc, PIP_STAT8_PRT); + kstat_kv_u64(&kvs[cnmac_stat_rx_undersz]) += (uint32_t)val; + kstat_kv_u64(&kvs[cnmac_stat_rx_frag]) += val >> 32; - _PIP_WR8(sc, PIP_STAT_CTL_OFFSET, pip_stat_ctl); + val = _PIP_STAT_RD8(sc, PIP_STAT9_PRT); + kstat_kv_u64(&kvs[cnmac_stat_rx_oversz]) += (uint32_t)val; + kstat_kv_u64(&kvs[cnmac_stat_rx_jabber]) += val >> 32; } +#endif diff --git a/sys/arch/octeon/dev/cn30xxpipreg.h b/sys/arch/octeon/dev/cn30xxpipreg.h index a51ef25697f..cd1329f4872 100644 --- a/sys/arch/octeon/dev/cn30xxpipreg.h +++ b/sys/arch/octeon/dev/cn30xxpipreg.h @@ -3,7 +3,7 @@ * DONT EDIT THIS FILE */ -/* $OpenBSD: cn30xxpipreg.h,v 1.7 2019/09/22 05:13:59 visa Exp $ */ +/* $OpenBSD: cn30xxpipreg.h,v 1.8 2020/09/04 15:18:05 visa Exp $ */ /* * Copyright (c) 2007 Internet Initiative Japan, Inc. @@ -100,6 +100,20 @@ #define PIP_BASE 0x00011800a0000000ULL #define PIP_SIZE 0x1e50ULL +#define PIP_STAT_SIZE 0x50 +#define PIP_STAT_BASE(i) (0x800 + PIP_STAT_SIZE * (i)) + +#define PIP_STAT0_PRT 0x00 +#define PIP_STAT1_PRT 0x08 +#define PIP_STAT2_PRT 0x10 +#define PIP_STAT3_PRT 0x18 +#define PIP_STAT4_PRT 0x20 +#define PIP_STAT5_PRT 0x28 +#define PIP_STAT6_PRT 0x30 +#define PIP_STAT7_PRT 0x38 +#define PIP_STAT8_PRT 0x40 +#define PIP_STAT9_PRT 0x48 + #define PIP_BIST_STATUS_OFFSET 0x0ULL #define PIP_INT_REG_OFFSET 0x8ULL #define PIP_INT_EN_OFFSET 0x10ULL diff --git a/sys/arch/octeon/dev/cn30xxpipvar.h b/sys/arch/octeon/dev/cn30xxpipvar.h index e15f6ad530f..1b8e1c0a8d1 100644 --- a/sys/arch/octeon/dev/cn30xxpipvar.h +++ b/sys/arch/octeon/dev/cn30xxpipvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: cn30xxpipvar.h,v 1.3 2017/11/05 04:57:28 visa Exp $ */ +/* $OpenBSD: cn30xxpipvar.h,v 1.4 2020/09/04 15:18:05 visa Exp $ */ /* * Copyright (c) 2007 Internet Initiative Japan, Inc. @@ -29,11 +29,16 @@ #ifndef _CN30XXPIPVAR_H_ #define _CN30XXPIPVAR_H_ +#include <sys/kstat.h> + +#include "kstat.h" + /* XXX */ struct cn30xxpip_softc { int sc_port; bus_space_tag_t sc_regt; bus_space_handle_t sc_regh; + bus_space_handle_t sc_regh_stat; int sc_tag_type; int sc_receive_group; size_t sc_ip_offset; @@ -54,7 +59,10 @@ void cn30xxpip_gbl_ctl_debug(struct cn30xxpip_softc *); int cn30xxpip_port_config(struct cn30xxpip_softc *); void cn30xxpip_prt_cfg_enable(struct cn30xxpip_softc *, uint64_t, int); -void cn30xxpip_stats(struct cn30xxpip_softc *, - struct ifnet *, int); +void cn30xxpip_stats_init(struct cn30xxpip_softc *); +#if NKSTAT > 0 +void cn30xxpip_kstat_read(struct cn30xxpip_softc *, + struct kstat_kv *); +#endif #endif /* !_CN30XXPIPVAR_H_ */ diff --git a/sys/arch/octeon/dev/if_cnmac.c b/sys/arch/octeon/dev/if_cnmac.c index c45503c3d7f..52febefc65e 100644 --- a/sys/arch/octeon/dev/if_cnmac.c +++ b/sys/arch/octeon/dev/if_cnmac.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_cnmac.c,v 1.78 2020/08/15 10:44:48 visa Exp $ */ +/* $OpenBSD: if_cnmac.c,v 1.79 2020/09/04 15:18:05 visa Exp $ */ /* * Copyright (c) 2007 Internet Initiative Japan, Inc. @@ -169,6 +169,12 @@ int cnmac_intr(void *); int cnmac_mbuf_alloc(int); +#if NKSTAT > 0 +void cnmac_kstat_attach(struct cnmac_softc *); +int cnmac_kstat_read(struct kstat *); +void cnmac_kstat_tick(struct cnmac_softc *); +#endif + /* device parameters */ int cnmac_param_pko_cmd_w0_n2 = 1; @@ -276,8 +282,6 @@ cnmac_attach(struct device *parent, struct device *self, void *aux) sc->sc_soft_req_thresh = 15/* XXX */; sc->sc_ext_callback_cnt = 0; - cn30xxgmx_stats_init(sc->sc_gmx_port); - task_set(&sc->sc_free_task, cnmac_free_task, sc); timeout_set(&sc->sc_tick_misc_ch, cnmac_tick_misc, sc); timeout_set(&sc->sc_tick_free_ch, cnmac_tick_free, sc); @@ -325,6 +329,10 @@ cnmac_attach(struct device *parent, struct device *self, void *aux) cnmac_buf_init(sc); +#if NKSTAT > 0 + cnmac_kstat_attach(sc); +#endif + sc->sc_ih = octeon_intr_establish(POW_WORKQ_IRQ(sc->sc_powgroup), IPL_NET | IPL_MPSAFE, cnmac_intr, sc, sc->sc_dev.dv_xname); if (sc->sc_ih == NULL) @@ -1001,6 +1009,8 @@ cnmac_init(struct ifnet *ifp) } cnmac_mediachange(ifp); + cn30xxpip_stats_init(sc->sc_pip); + cn30xxgmx_stats_init(sc->sc_gmx_port); cn30xxgmx_set_mac_addr(sc->sc_gmx_port, sc->sc_arpcom.ac_enaddr); cn30xxgmx_set_filter(sc->sc_gmx_port); @@ -1061,9 +1071,6 @@ cnmac_configure(struct cnmac_softc *sc) cn30xxpko_port_enable(sc->sc_pko, 1); cn30xxpow_config(sc->sc_pow, sc->sc_powgroup); - cn30xxgmx_tx_stats_rd_clr(sc->sc_gmx_port, 1); - cn30xxgmx_rx_stats_rd_clr(sc->sc_gmx_port, 1); - cn30xxgmx_port_enable(sc->sc_gmx_port, 1); return 0; @@ -1382,16 +1389,117 @@ void cnmac_tick_misc(void *arg) { struct cnmac_softc *sc = arg; - struct ifnet *ifp = &sc->sc_arpcom.ac_if; int s; s = splnet(); - - cn30xxgmx_stats(sc->sc_gmx_port); - cn30xxpip_stats(sc->sc_pip, ifp, sc->sc_port); mii_tick(&sc->sc_mii); - splx(s); +#if NKSTAT > 0 + cnmac_kstat_tick(sc); +#endif + timeout_add_sec(&sc->sc_tick_misc_ch, 1); } + +#if NKSTAT > 0 +#define KVE(n, t) \ + KSTAT_KV_UNIT_INITIALIZER((n), KSTAT_KV_T_COUNTER64, (t)) + +static const struct kstat_kv cnmac_kstat_tpl[cnmac_stat_count] = { + [cnmac_stat_rx_toto_gmx]= KVE("rx total gmx", KSTAT_KV_U_BYTES), + [cnmac_stat_rx_totp_gmx]= KVE("rx total gmx", KSTAT_KV_U_PACKETS), + [cnmac_stat_rx_toto_pip]= KVE("rx total pip", KSTAT_KV_U_BYTES), + [cnmac_stat_rx_totp_pip]= KVE("rx total pip", KSTAT_KV_U_PACKETS), + [cnmac_stat_rx_h64] = KVE("rx 64B", KSTAT_KV_U_PACKETS), + [cnmac_stat_rx_h127] = KVE("rx 65-127B", KSTAT_KV_U_PACKETS), + [cnmac_stat_rx_h255] = KVE("rx 128-255B", KSTAT_KV_U_PACKETS), + [cnmac_stat_rx_h511] = KVE("rx 256-511B", KSTAT_KV_U_PACKETS), + [cnmac_stat_rx_h1023] = KVE("rx 512-1023B", KSTAT_KV_U_PACKETS), + [cnmac_stat_rx_h1518] = KVE("rx 1024-1518B", KSTAT_KV_U_PACKETS), + [cnmac_stat_rx_hmax] = KVE("rx 1519-maxB", KSTAT_KV_U_PACKETS), + [cnmac_stat_rx_bcast] = KVE("rx bcast", KSTAT_KV_U_PACKETS), + [cnmac_stat_rx_mcast] = KVE("rx mcast", KSTAT_KV_U_PACKETS), + [cnmac_stat_rx_qdpo] = KVE("rx qos drop", KSTAT_KV_U_BYTES), + [cnmac_stat_rx_qdpp] = KVE("rx qos drop", KSTAT_KV_U_PACKETS), + [cnmac_stat_rx_fcs] = KVE("rx fcs err", KSTAT_KV_U_PACKETS), + [cnmac_stat_rx_frag] = KVE("rx fcs undersize",KSTAT_KV_U_PACKETS), + [cnmac_stat_rx_undersz] = KVE("rx undersize", KSTAT_KV_U_PACKETS), + [cnmac_stat_rx_jabber] = KVE("rx jabber", KSTAT_KV_U_PACKETS), + [cnmac_stat_rx_oversz] = KVE("rx oversize", KSTAT_KV_U_PACKETS), + [cnmac_stat_rx_raw] = KVE("rx raw", KSTAT_KV_U_PACKETS), + [cnmac_stat_rx_bad] = KVE("rx bad", KSTAT_KV_U_PACKETS), + [cnmac_stat_rx_drop] = KVE("rx drop", KSTAT_KV_U_PACKETS), + [cnmac_stat_rx_ctl] = KVE("rx control", KSTAT_KV_U_PACKETS), + [cnmac_stat_rx_dmac] = KVE("rx dmac", KSTAT_KV_U_PACKETS), + [cnmac_stat_tx_toto] = KVE("tx total", KSTAT_KV_U_BYTES), + [cnmac_stat_tx_totp] = KVE("tx total", KSTAT_KV_U_PACKETS), + [cnmac_stat_tx_hmin] = KVE("tx min-63B", KSTAT_KV_U_PACKETS), + [cnmac_stat_tx_h64] = KVE("tx 64B", KSTAT_KV_U_PACKETS), + [cnmac_stat_tx_h127] = KVE("tx 65-127B", KSTAT_KV_U_PACKETS), + [cnmac_stat_tx_h255] = KVE("tx 128-255B", KSTAT_KV_U_PACKETS), + [cnmac_stat_tx_h511] = KVE("tx 256-511B", KSTAT_KV_U_PACKETS), + [cnmac_stat_tx_h1023] = KVE("tx 512-1023B", KSTAT_KV_U_PACKETS), + [cnmac_stat_tx_h1518] = KVE("tx 1024-1518B", KSTAT_KV_U_PACKETS), + [cnmac_stat_tx_hmax] = KVE("tx 1519-maxB", KSTAT_KV_U_PACKETS), + [cnmac_stat_tx_bcast] = KVE("tx bcast", KSTAT_KV_U_PACKETS), + [cnmac_stat_tx_mcast] = KVE("tx mcast", KSTAT_KV_U_PACKETS), + [cnmac_stat_tx_coll] = KVE("tx coll", KSTAT_KV_U_PACKETS), + [cnmac_stat_tx_defer] = KVE("tx defer", KSTAT_KV_U_PACKETS), + [cnmac_stat_tx_scol] = KVE("tx scoll", KSTAT_KV_U_PACKETS), + [cnmac_stat_tx_mcol] = KVE("tx mcoll", KSTAT_KV_U_PACKETS), + [cnmac_stat_tx_ctl] = KVE("tx control", KSTAT_KV_U_PACKETS), + [cnmac_stat_tx_uflow] = KVE("tx underflow", KSTAT_KV_U_PACKETS), +}; + +void +cnmac_kstat_attach(struct cnmac_softc *sc) +{ + struct kstat *ks; + struct kstat_kv *kvs; + + mtx_init(&sc->sc_kstat_mtx, IPL_SOFTCLOCK); + + ks = kstat_create(sc->sc_dev.dv_xname, 0, "cnmac-stats", 0, + KSTAT_T_KV, 0); + if (ks == NULL) + return; + + kvs = malloc(sizeof(cnmac_kstat_tpl), M_DEVBUF, M_WAITOK | M_ZERO); + memcpy(kvs, cnmac_kstat_tpl, sizeof(cnmac_kstat_tpl)); + + kstat_set_mutex(ks, &sc->sc_kstat_mtx); + ks->ks_softc = sc; + ks->ks_data = kvs; + ks->ks_datalen = sizeof(cnmac_kstat_tpl); + ks->ks_read = cnmac_kstat_read; + + sc->sc_kstat = ks; + kstat_install(ks); +} + +int +cnmac_kstat_read(struct kstat *ks) +{ + struct cnmac_softc *sc = ks->ks_softc; + struct kstat_kv *kvs = ks->ks_data; + + cn30xxpip_kstat_read(sc->sc_pip, kvs); + cn30xxgmx_kstat_read(sc->sc_gmx_port, kvs); + + getnanouptime(&ks->ks_updated); + + return 0; +} + +void +cnmac_kstat_tick(struct cnmac_softc *sc) +{ + if (sc->sc_kstat == NULL) + return; + if (!mtx_enter_try(&sc->sc_kstat_mtx)) + return; + cnmac_kstat_read(sc->sc_kstat); + mtx_leave(&sc->sc_kstat_mtx); +} +#endif diff --git a/sys/arch/octeon/dev/if_cnmacvar.h b/sys/arch/octeon/dev/if_cnmacvar.h index c161fa08491..99224034bf7 100644 --- a/sys/arch/octeon/dev/if_cnmacvar.h +++ b/sys/arch/octeon/dev/if_cnmacvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: if_cnmacvar.h,v 1.18 2017/11/18 05:53:02 visa Exp $ */ +/* $OpenBSD: if_cnmacvar.h,v 1.19 2020/09/04 15:18:05 visa Exp $ */ /* * Copyright (c) 2007 Internet Initiative Japan, Inc. @@ -26,6 +26,11 @@ * SUCH DAMAGE. */ +#include <sys/kstat.h> +#include <sys/mutex.h> + +#include "kstat.h" + #define IS_MAC_MULTICASTBIT(addr) \ ((addr)[0] & 0x01) @@ -108,4 +113,7 @@ struct cnmac_softc { size_t sc_ip_offset; struct timeval sc_rxerr_log_last; + + struct mutex sc_kstat_mtx; + struct kstat *sc_kstat; }; diff --git a/sys/arch/octeon/include/octeonvar.h b/sys/arch/octeon/include/octeonvar.h index 638a371dbb2..8ad00ddb9eb 100644 --- a/sys/arch/octeon/include/octeonvar.h +++ b/sys/arch/octeon/include/octeonvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: octeonvar.h,v 1.48 2020/06/27 01:01:36 jsg Exp $ */ +/* $OpenBSD: octeonvar.h,v 1.49 2020/09/04 15:18:05 visa Exp $ */ /* $NetBSD: maltavar.h,v 1.3 2002/03/18 10:10:16 simonb Exp $ */ /*- @@ -155,6 +155,53 @@ struct octeon_fau_map { #define OCTEON_POW_GROUP_MAX 16 +enum cnmac_stat { + cnmac_stat_rx_toto_gmx, + cnmac_stat_rx_totp_gmx, + cnmac_stat_rx_toto_pip, + cnmac_stat_rx_totp_pip, + cnmac_stat_rx_h64, + cnmac_stat_rx_h127, + cnmac_stat_rx_h255, + cnmac_stat_rx_h511, + cnmac_stat_rx_h1023, + cnmac_stat_rx_h1518, + cnmac_stat_rx_hmax, + cnmac_stat_rx_bcast, + cnmac_stat_rx_mcast, + cnmac_stat_rx_qdpo, + cnmac_stat_rx_qdpp, + cnmac_stat_rx_fcs, + cnmac_stat_rx_frag, + cnmac_stat_rx_undersz, + cnmac_stat_rx_jabber, + cnmac_stat_rx_oversz, + cnmac_stat_rx_raw, + cnmac_stat_rx_bad, + cnmac_stat_rx_drop, + cnmac_stat_rx_ctl, + cnmac_stat_rx_dmac, + cnmac_stat_tx_toto, + cnmac_stat_tx_totp, + cnmac_stat_tx_hmin, + cnmac_stat_tx_h64, + cnmac_stat_tx_h127, + cnmac_stat_tx_h255, + cnmac_stat_tx_h511, + cnmac_stat_tx_h1023, + cnmac_stat_tx_h1518, + cnmac_stat_tx_hmax, + cnmac_stat_tx_bcast, + cnmac_stat_tx_mcast, + cnmac_stat_tx_coll, + cnmac_stat_tx_defer, + cnmac_stat_tx_scol, + cnmac_stat_tx_mcol, + cnmac_stat_tx_ctl, + cnmac_stat_tx_uflow, + cnmac_stat_count +}; + /* * Octeon board types known to work with OpenBSD/octeon. * NB: BOARD_TYPE_UBIQUITI_E100 is also used by other vendors, but we don't run |