Implement hardware MAC statistics counter support. The counters
could be accessed with dev.ste.0.stats sysctl node.
This commit is contained in:
parent
84918f5bc8
commit
8657caa66b
@ -125,8 +125,10 @@ static int ste_rxeof(struct ste_softc *, int);
|
||||
static void ste_rxfilter(struct ste_softc *);
|
||||
static void ste_start(struct ifnet *);
|
||||
static void ste_start_locked(struct ifnet *);
|
||||
static void ste_stats_clear(struct ste_softc *);
|
||||
static void ste_stats_update(struct ste_softc *);
|
||||
static void ste_stop(struct ste_softc *);
|
||||
static void ste_sysctl_node(struct ste_softc *);
|
||||
static void ste_tick(void *);
|
||||
static void ste_txeoc(struct ste_softc *);
|
||||
static void ste_txeof(struct ste_softc *);
|
||||
@ -922,17 +924,75 @@ ste_txeof(struct ste_softc *sc)
|
||||
sc->ste_timer = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
ste_stats_clear(struct ste_softc *sc)
|
||||
{
|
||||
|
||||
STE_LOCK_ASSERT(sc);
|
||||
|
||||
/* Rx stats. */
|
||||
CSR_READ_2(sc, STE_STAT_RX_OCTETS_LO);
|
||||
CSR_READ_2(sc, STE_STAT_RX_OCTETS_HI);
|
||||
CSR_READ_2(sc, STE_STAT_RX_FRAMES);
|
||||
CSR_READ_1(sc, STE_STAT_RX_BCAST);
|
||||
CSR_READ_1(sc, STE_STAT_RX_MCAST);
|
||||
CSR_READ_1(sc, STE_STAT_RX_LOST);
|
||||
/* Tx stats. */
|
||||
CSR_READ_2(sc, STE_STAT_TX_OCTETS_LO);
|
||||
CSR_READ_2(sc, STE_STAT_TX_OCTETS_HI);
|
||||
CSR_READ_2(sc, STE_STAT_TX_FRAMES);
|
||||
CSR_READ_1(sc, STE_STAT_TX_BCAST);
|
||||
CSR_READ_1(sc, STE_STAT_TX_MCAST);
|
||||
CSR_READ_1(sc, STE_STAT_CARRIER_ERR);
|
||||
CSR_READ_1(sc, STE_STAT_SINGLE_COLLS);
|
||||
CSR_READ_1(sc, STE_STAT_MULTI_COLLS);
|
||||
CSR_READ_1(sc, STE_STAT_LATE_COLLS);
|
||||
CSR_READ_1(sc, STE_STAT_TX_DEFER);
|
||||
CSR_READ_1(sc, STE_STAT_TX_EXDEFER);
|
||||
CSR_READ_1(sc, STE_STAT_TX_ABORT);
|
||||
}
|
||||
|
||||
static void
|
||||
ste_stats_update(struct ste_softc *sc)
|
||||
{
|
||||
struct ifnet *ifp;
|
||||
struct ste_hw_stats *stats;
|
||||
uint32_t val;
|
||||
|
||||
STE_LOCK_ASSERT(sc);
|
||||
|
||||
ifp = sc->ste_ifp;
|
||||
ifp->if_collisions += CSR_READ_1(sc, STE_LATE_COLLS)
|
||||
+ CSR_READ_1(sc, STE_MULTI_COLLS)
|
||||
+ CSR_READ_1(sc, STE_SINGLE_COLLS);
|
||||
stats = &sc->ste_stats;
|
||||
/* Rx stats. */
|
||||
val = (uint32_t)CSR_READ_2(sc, STE_STAT_RX_OCTETS_LO) |
|
||||
((uint32_t)CSR_READ_2(sc, STE_STAT_RX_OCTETS_HI)) << 16;
|
||||
val &= 0x000FFFFF;
|
||||
stats->rx_bytes += val;
|
||||
stats->rx_frames += CSR_READ_2(sc, STE_STAT_RX_FRAMES);
|
||||
stats->rx_bcast_frames += CSR_READ_1(sc, STE_STAT_RX_BCAST);
|
||||
stats->rx_mcast_frames += CSR_READ_1(sc, STE_STAT_RX_MCAST);
|
||||
stats->rx_lost_frames += CSR_READ_1(sc, STE_STAT_RX_LOST);
|
||||
/* Tx stats. */
|
||||
val = (uint32_t)CSR_READ_2(sc, STE_STAT_TX_OCTETS_LO) |
|
||||
((uint32_t)CSR_READ_2(sc, STE_STAT_TX_OCTETS_HI)) << 16;
|
||||
val &= 0x000FFFFF;
|
||||
stats->tx_bytes += val;
|
||||
stats->tx_frames += CSR_READ_2(sc, STE_STAT_TX_FRAMES);
|
||||
stats->tx_bcast_frames += CSR_READ_1(sc, STE_STAT_TX_BCAST);
|
||||
stats->tx_mcast_frames += CSR_READ_1(sc, STE_STAT_TX_MCAST);
|
||||
stats->tx_carrsense_errs += CSR_READ_1(sc, STE_STAT_CARRIER_ERR);
|
||||
val = CSR_READ_1(sc, STE_STAT_SINGLE_COLLS);
|
||||
stats->tx_single_colls += val;
|
||||
ifp->if_collisions += val;
|
||||
val = CSR_READ_1(sc, STE_STAT_MULTI_COLLS);
|
||||
stats->tx_multi_colls += val;
|
||||
ifp->if_collisions += val;
|
||||
val += CSR_READ_1(sc, STE_STAT_LATE_COLLS);
|
||||
stats->tx_late_colls += val;
|
||||
ifp->if_collisions += val;
|
||||
stats->tx_frames_defered += CSR_READ_1(sc, STE_STAT_TX_DEFER);
|
||||
stats->tx_excess_defers += CSR_READ_1(sc, STE_STAT_TX_EXDEFER);
|
||||
stats->tx_abort += CSR_READ_1(sc, STE_STAT_TX_ABORT);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1032,6 +1092,7 @@ ste_attach(device_t dev)
|
||||
error = ENXIO;;
|
||||
goto fail;
|
||||
}
|
||||
ste_sysctl_node(sc);
|
||||
|
||||
if ((error = ste_dma_alloc(sc)) != 0)
|
||||
goto fail;
|
||||
@ -1625,6 +1686,8 @@ ste_init_locked(struct ste_softc *sc)
|
||||
|
||||
/* Enable stats counters. */
|
||||
STE_SETBIT2(sc, STE_MACCTL1, STE_MACCTL1_STATS_ENABLE);
|
||||
/* Clear stats counters. */
|
||||
ste_stats_clear(sc);
|
||||
|
||||
CSR_WRITE_2(sc, STE_ISR, 0xFFFF);
|
||||
#ifdef DEVICE_POLLING
|
||||
@ -2013,3 +2076,70 @@ ste_shutdown(device_t dev)
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
#define STE_SYSCTL_STAT_ADD32(c, h, n, p, d) \
|
||||
SYSCTL_ADD_UINT(c, h, OID_AUTO, n, CTLFLAG_RD, p, 0, d)
|
||||
#define STE_SYSCTL_STAT_ADD64(c, h, n, p, d) \
|
||||
SYSCTL_ADD_QUAD(c, h, OID_AUTO, n, CTLFLAG_RD, p, d)
|
||||
|
||||
static void
|
||||
ste_sysctl_node(struct ste_softc *sc)
|
||||
{
|
||||
struct sysctl_ctx_list *ctx;
|
||||
struct sysctl_oid_list *child, *parent;
|
||||
struct sysctl_oid *tree;
|
||||
struct ste_hw_stats *stats;
|
||||
|
||||
stats = &sc->ste_stats;
|
||||
ctx = device_get_sysctl_ctx(sc->ste_dev);
|
||||
child = SYSCTL_CHILDREN(device_get_sysctl_tree(sc->ste_dev));
|
||||
|
||||
tree = SYSCTL_ADD_NODE(ctx, child, OID_AUTO, "stats", CTLFLAG_RD,
|
||||
NULL, "STE statistics");
|
||||
parent = SYSCTL_CHILDREN(tree);
|
||||
|
||||
/* Rx statistics. */
|
||||
tree = SYSCTL_ADD_NODE(ctx, parent, OID_AUTO, "rx", CTLFLAG_RD,
|
||||
NULL, "Rx MAC statistics");
|
||||
child = SYSCTL_CHILDREN(tree);
|
||||
STE_SYSCTL_STAT_ADD64(ctx, child, "good_octets",
|
||||
&stats->rx_bytes, "Good octets");
|
||||
STE_SYSCTL_STAT_ADD32(ctx, child, "good_frames",
|
||||
&stats->rx_frames, "Good frames");
|
||||
STE_SYSCTL_STAT_ADD32(ctx, child, "good_bcast_frames",
|
||||
&stats->rx_bcast_frames, "Good broadcast frames");
|
||||
STE_SYSCTL_STAT_ADD32(ctx, child, "good_mcast_frames",
|
||||
&stats->rx_mcast_frames, "Good multicast frames");
|
||||
STE_SYSCTL_STAT_ADD32(ctx, child, "lost_frames",
|
||||
&stats->rx_lost_frames, "Lost frames");
|
||||
|
||||
/* Tx statistics. */
|
||||
tree = SYSCTL_ADD_NODE(ctx, parent, OID_AUTO, "tx", CTLFLAG_RD,
|
||||
NULL, "Tx MAC statistics");
|
||||
child = SYSCTL_CHILDREN(tree);
|
||||
STE_SYSCTL_STAT_ADD64(ctx, child, "good_octets",
|
||||
&stats->tx_bytes, "Good octets");
|
||||
STE_SYSCTL_STAT_ADD32(ctx, child, "good_frames",
|
||||
&stats->tx_frames, "Good frames");
|
||||
STE_SYSCTL_STAT_ADD32(ctx, child, "good_bcast_frames",
|
||||
&stats->tx_bcast_frames, "Good broadcast frames");
|
||||
STE_SYSCTL_STAT_ADD32(ctx, child, "good_mcast_frames",
|
||||
&stats->tx_mcast_frames, "Good multicast frames");
|
||||
STE_SYSCTL_STAT_ADD32(ctx, child, "carrier_errs",
|
||||
&stats->tx_carrsense_errs, "Carrier sense errors");
|
||||
STE_SYSCTL_STAT_ADD32(ctx, child, "single_colls",
|
||||
&stats->tx_single_colls, "Single collisions");
|
||||
STE_SYSCTL_STAT_ADD32(ctx, child, "multi_colls",
|
||||
&stats->tx_multi_colls, "Multiple collisions");
|
||||
STE_SYSCTL_STAT_ADD32(ctx, child, "late_colls",
|
||||
&stats->tx_late_colls, "Late collisions");
|
||||
STE_SYSCTL_STAT_ADD32(ctx, child, "defers",
|
||||
&stats->tx_frames_defered, "Frames with deferrals");
|
||||
STE_SYSCTL_STAT_ADD32(ctx, child, "excess_defers",
|
||||
&stats->tx_excess_defers, "Frames with excessive derferrals");
|
||||
STE_SYSCTL_STAT_ADD32(ctx, child, "abort",
|
||||
&stats->tx_abort, "Aborted frames due to Excessive collisions");
|
||||
}
|
||||
|
||||
#undef STE_SYSCTL_STAT_ADD32
|
||||
#undef STE_SYSCTL_STAT_ADD64
|
||||
|
@ -92,11 +92,25 @@
|
||||
#define STE_MAR1 0x62
|
||||
#define STE_MAR2 0x64
|
||||
#define STE_MAR3 0x66
|
||||
#define STE_STATS 0x68
|
||||
|
||||
#define STE_LATE_COLLS 0x75
|
||||
#define STE_MULTI_COLLS 0x76
|
||||
#define STE_SINGLE_COLLS 0x77
|
||||
#define STE_STAT_RX_OCTETS_LO 0x68
|
||||
#define STE_STAT_RX_OCTETS_HI 0x6A
|
||||
#define STE_STAT_TX_OCTETS_LO 0x6C
|
||||
#define STE_STAT_TX_OCTETS_HI 0x6E
|
||||
#define STE_STAT_TX_FRAMES 0x70
|
||||
#define STE_STAT_RX_FRAMES 0x72
|
||||
#define STE_STAT_CARRIER_ERR 0x74
|
||||
#define STE_STAT_LATE_COLLS 0x75
|
||||
#define STE_STAT_MULTI_COLLS 0x76
|
||||
#define STE_STAT_SINGLE_COLLS 0x77
|
||||
#define STE_STAT_TX_DEFER 0x78
|
||||
#define STE_STAT_RX_LOST 0x79
|
||||
#define STE_STAT_TX_EXDEFER 0x7A
|
||||
#define STE_STAT_TX_ABORT 0x7B
|
||||
#define STE_STAT_TX_BCAST 0x7C
|
||||
#define STE_STAT_RX_BCAST 0x7D
|
||||
#define STE_STAT_TX_MCAST 0x7E
|
||||
#define STE_STAT_RX_MCAST 0x7F
|
||||
|
||||
#define STE_DMACTL_RXDMA_STOPPED 0x00000001
|
||||
#define STE_DMACTL_TXDMA_CMPREQ 0x00000002
|
||||
@ -388,24 +402,23 @@
|
||||
#define STE_PME_EN 0x0010
|
||||
#define STE_PME_STATUS 0x8000
|
||||
|
||||
|
||||
struct ste_stats {
|
||||
uint32_t ste_rx_bytes;
|
||||
uint32_t ste_tx_bytes;
|
||||
uint16_t ste_tx_frames;
|
||||
uint16_t ste_rx_frames;
|
||||
uint8_t ste_carrsense_errs;
|
||||
uint8_t ste_late_colls;
|
||||
uint8_t ste_multi_colls;
|
||||
uint8_t ste_single_colls;
|
||||
uint8_t ste_tx_frames_defered;
|
||||
uint8_t ste_rx_lost_frames;
|
||||
uint8_t ste_tx_excess_defers;
|
||||
uint8_t ste_tx_abort_excess_colls;
|
||||
uint8_t ste_tx_bcast_frames;
|
||||
uint8_t ste_rx_bcast_frames;
|
||||
uint8_t ste_tx_mcast_frames;
|
||||
uint8_t ste_rx_mcast_frames;
|
||||
struct ste_hw_stats {
|
||||
uint64_t rx_bytes;
|
||||
uint32_t rx_frames;
|
||||
uint32_t rx_bcast_frames;
|
||||
uint32_t rx_mcast_frames;
|
||||
uint32_t rx_lost_frames;
|
||||
uint64_t tx_bytes;
|
||||
uint32_t tx_frames;
|
||||
uint32_t tx_bcast_frames;
|
||||
uint32_t tx_mcast_frames;
|
||||
uint32_t tx_carrsense_errs;
|
||||
uint32_t tx_single_colls;
|
||||
uint32_t tx_multi_colls;
|
||||
uint32_t tx_late_colls;
|
||||
uint32_t tx_frames_defered;
|
||||
uint32_t tx_excess_defers;
|
||||
uint32_t tx_abort;
|
||||
};
|
||||
|
||||
struct ste_frag {
|
||||
@ -566,6 +579,7 @@ struct ste_softc {
|
||||
struct ste_list_data ste_ldata;
|
||||
struct ste_chain_data ste_cdata;
|
||||
struct callout ste_callout;
|
||||
struct ste_hw_stats ste_stats;
|
||||
struct mtx ste_mtx;
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user