diff --git a/sys/dev/bfe/if_bfe.c b/sys/dev/bfe/if_bfe.c index 26d92bc346ea..fb95eba22eb2 100644 --- a/sys/dev/bfe/if_bfe.c +++ b/sys/dev/bfe/if_bfe.c @@ -39,6 +39,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include @@ -125,6 +126,7 @@ static int bfe_dma_alloc (struct bfe_softc *); static void bfe_dma_free (struct bfe_softc *sc); static void bfe_dma_map (void *, bus_dma_segment_t *, int, int); static void bfe_cam_write (struct bfe_softc *, u_char *, int); +static int sysctl_bfe_stats (SYSCTL_HANDLER_ARGS); static device_method_t bfe_methods[] = { /* Device interface */ @@ -473,6 +475,11 @@ bfe_attach(device_t dev) goto fail; } + SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), + SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, + "stats", CTLTYPE_INT | CTLFLAG_RW, sc, 0, sysctl_bfe_stats, + "I", "Statistics"); + /* Set up ifnet structure */ ifp = sc->bfe_ifp = if_alloc(IFT_ETHER); if (ifp == NULL) { @@ -877,7 +884,7 @@ bfe_pci_setup(struct bfe_softc *sc, u_int32_t cores) static void bfe_clear_stats(struct bfe_softc *sc) { - u_long reg; + uint32_t reg; BFE_LOCK_ASSERT(sc); @@ -1082,6 +1089,8 @@ bfe_set_rx_mode(struct bfe_softc *sc) u_int32_t val; int i = 0; + BFE_LOCK_ASSERT(sc); + val = CSR_READ_4(sc, BFE_RXCONF); if (ifp->if_flags & IFF_PROMISC) @@ -1241,17 +1250,89 @@ bfe_setupphy(struct bfe_softc *sc) static void bfe_stats_update(struct bfe_softc *sc) { - u_long reg; - u_int32_t *val; + struct bfe_hw_stats *stats; + struct ifnet *ifp; + uint32_t mib[BFE_MIB_CNT]; + uint32_t reg, *val; - val = &sc->bfe_hwstats.tx_good_octets; - for (reg = BFE_TX_GOOD_O; reg <= BFE_TX_PAUSE; reg += 4) { - *val++ += CSR_READ_4(sc, reg); - } - val = &sc->bfe_hwstats.rx_good_octets; - for (reg = BFE_RX_GOOD_O; reg <= BFE_RX_NPAUSE; reg += 4) { - *val++ += CSR_READ_4(sc, reg); - } + BFE_LOCK_ASSERT(sc); + + val = mib; + CSR_WRITE_4(sc, BFE_MIB_CTRL, BFE_MIB_CLR_ON_READ); + for (reg = BFE_TX_GOOD_O; reg <= BFE_TX_PAUSE; reg += 4) + *val++ = CSR_READ_4(sc, reg); + for (reg = BFE_RX_GOOD_O; reg <= BFE_RX_NPAUSE; reg += 4) + *val++ = CSR_READ_4(sc, reg); + + ifp = sc->bfe_ifp; + stats = &sc->bfe_stats; + /* Tx stat. */ + stats->tx_good_octets += mib[MIB_TX_GOOD_O]; + stats->tx_good_frames += mib[MIB_TX_GOOD_P]; + stats->tx_octets += mib[MIB_TX_O]; + stats->tx_frames += mib[MIB_TX_P]; + stats->tx_bcast_frames += mib[MIB_TX_BCAST]; + stats->tx_mcast_frames += mib[MIB_TX_MCAST]; + stats->tx_pkts_64 += mib[MIB_TX_64]; + stats->tx_pkts_65_127 += mib[MIB_TX_65_127]; + stats->tx_pkts_128_255 += mib[MIB_TX_128_255]; + stats->tx_pkts_256_511 += mib[MIB_TX_256_511]; + stats->tx_pkts_512_1023 += mib[MIB_TX_512_1023]; + stats->tx_pkts_1024_max += mib[MIB_TX_1024_MAX]; + stats->tx_jabbers += mib[MIB_TX_JABBER]; + stats->tx_oversize_frames += mib[MIB_TX_OSIZE]; + stats->tx_frag_frames += mib[MIB_TX_FRAG]; + stats->tx_underruns += mib[MIB_TX_URUNS]; + stats->tx_colls += mib[MIB_TX_TCOLS]; + stats->tx_single_colls += mib[MIB_TX_SCOLS]; + stats->tx_multi_colls += mib[MIB_TX_MCOLS]; + stats->tx_excess_colls += mib[MIB_TX_ECOLS]; + stats->tx_late_colls += mib[MIB_TX_LCOLS]; + stats->tx_deferrals += mib[MIB_TX_DEFERED]; + stats->tx_carrier_losts += mib[MIB_TX_CLOST]; + stats->tx_pause_frames += mib[MIB_TX_PAUSE]; + /* Rx stat. */ + stats->rx_good_octets += mib[MIB_RX_GOOD_O]; + stats->rx_good_frames += mib[MIB_RX_GOOD_P]; + stats->rx_octets += mib[MIB_RX_O]; + stats->rx_frames += mib[MIB_RX_P]; + stats->rx_bcast_frames += mib[MIB_RX_BCAST]; + stats->rx_mcast_frames += mib[MIB_RX_MCAST]; + stats->rx_pkts_64 += mib[MIB_RX_64]; + stats->rx_pkts_65_127 += mib[MIB_RX_65_127]; + stats->rx_pkts_128_255 += mib[MIB_RX_128_255]; + stats->rx_pkts_256_511 += mib[MIB_RX_256_511]; + stats->rx_pkts_512_1023 += mib[MIB_RX_512_1023]; + stats->rx_pkts_1024_max += mib[MIB_RX_1024_MAX]; + stats->rx_jabbers += mib[MIB_RX_JABBER]; + stats->rx_oversize_frames += mib[MIB_RX_OSIZE]; + stats->rx_frag_frames += mib[MIB_RX_FRAG]; + stats->rx_missed_frames += mib[MIB_RX_MISS]; + stats->rx_crc_align_errs += mib[MIB_RX_CRCA]; + stats->rx_runts += mib[MIB_RX_USIZE]; + stats->rx_crc_errs += mib[MIB_RX_CRC]; + stats->rx_align_errs += mib[MIB_RX_ALIGN]; + stats->rx_symbol_errs += mib[MIB_RX_SYM]; + stats->rx_pause_frames += mib[MIB_RX_PAUSE]; + stats->rx_control_frames += mib[MIB_RX_NPAUSE]; + + /* Update counters in ifnet. */ + ifp->if_opackets += (u_long)mib[MIB_TX_GOOD_P]; + ifp->if_collisions += (u_long)mib[MIB_TX_TCOLS]; + ifp->if_oerrors += (u_long)mib[MIB_TX_URUNS] + + (u_long)mib[MIB_TX_ECOLS] + + (u_long)mib[MIB_TX_DEFERED] + + (u_long)mib[MIB_TX_CLOST]; + + ifp->if_ipackets += (u_long)mib[MIB_RX_GOOD_P]; + + ifp->if_ierrors += mib[MIB_RX_JABBER] + + mib[MIB_RX_MISS] + + mib[MIB_RX_CRCA] + + mib[MIB_RX_USIZE] + + mib[MIB_RX_CRC] + + mib[MIB_RX_ALIGN] + + mib[MIB_RX_SYM]; } static void @@ -1283,7 +1364,6 @@ bfe_txeof(struct bfe_softc *sc) BUS_DMASYNC_POSTWRITE); bus_dmamap_unload(sc->bfe_txmbuf_tag, r->bfe_map); - ifp->if_opackets++; m_freem(r->bfe_mbuf); r->bfe_mbuf = NULL; } @@ -1343,9 +1423,6 @@ bfe_rxeof(struct bfe_softc *sc) /* flag an error and try again */ if ((len > ETHER_MAX_LEN+32) || (flags & BFE_RX_FLAG_ERRORS)) { - ifp->if_ierrors++; - if (flags & BFE_RX_FLAG_SERR) - ifp->if_collisions++; m_freem(m); continue; } @@ -1354,7 +1431,6 @@ bfe_rxeof(struct bfe_softc *sc) m_adj(m, BFE_RX_OFFSET); m->m_len = m->m_pkthdr.len = len; - ifp->if_ipackets++; m->m_pkthdr.rcvif = ifp; BFE_UNLOCK(sc); (*ifp->if_input)(ifp, m); @@ -1373,7 +1449,7 @@ bfe_intr(void *xsc) { struct bfe_softc *sc = xsc; struct ifnet *ifp; - u_int32_t istat, flag; + u_int32_t istat; ifp = sc->bfe_ifp; @@ -1396,6 +1472,14 @@ bfe_intr(void *xsc) return; } + /* A packet was received */ + if (istat & BFE_ISTAT_RX) + bfe_rxeof(sc); + + /* A packet was sent */ + if (istat & BFE_ISTAT_TX) + bfe_txeof(sc); + if (istat & BFE_ISTAT_ERRORS) { if (istat & BFE_ISTAT_DSCE) { @@ -1412,27 +1496,10 @@ bfe_intr(void *xsc) BFE_UNLOCK(sc); return; } - - flag = CSR_READ_4(sc, BFE_DMATX_STAT); - if (flag & BFE_STAT_EMASK) - ifp->if_oerrors++; - - flag = CSR_READ_4(sc, BFE_DMARX_STAT); - if (flag & BFE_RX_FLAG_ERRORS) - ifp->if_ierrors++; - ifp->if_drv_flags &= ~IFF_DRV_RUNNING; bfe_init_locked(sc); } - /* A packet was received */ - if (istat & BFE_ISTAT_RX) - bfe_rxeof(sc); - - /* A packet was sent */ - if (istat & BFE_ISTAT_TX) - bfe_txeof(sc); - /* We have packets pending, fire them out */ if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) bfe_start_locked(ifp); @@ -1805,3 +1872,103 @@ bfe_stop(struct bfe_softc *sc) bfe_tx_ring_free(sc); bfe_rx_ring_free(sc); } + +static int +sysctl_bfe_stats(SYSCTL_HANDLER_ARGS) +{ + struct bfe_softc *sc; + struct bfe_hw_stats *stats; + int error, result; + + result = -1; + error = sysctl_handle_int(oidp, &result, 0, req); + + if (error != 0 || req->newptr == NULL) + return (error); + + if (result != 1) + return (error); + + sc = (struct bfe_softc *)arg1; + stats = &sc->bfe_stats; + + printf("%s statistics:\n", device_get_nameunit(sc->bfe_dev)); + printf("Transmit good octets : %ju\n", + (uintmax_t)stats->tx_good_octets); + printf("Transmit good frames : %ju\n", + (uintmax_t)stats->tx_good_frames); + printf("Transmit octets : %ju\n", + (uintmax_t)stats->tx_octets); + printf("Transmit frames : %ju\n", + (uintmax_t)stats->tx_frames); + printf("Transmit broadcast frames : %ju\n", + (uintmax_t)stats->tx_bcast_frames); + printf("Transmit multicast frames : %ju\n", + (uintmax_t)stats->tx_mcast_frames); + printf("Transmit frames 64 bytes : %ju\n", + (uint64_t)stats->tx_pkts_64); + printf("Transmit frames 65 to 127 bytes : %ju\n", + (uint64_t)stats->tx_pkts_65_127); + printf("Transmit frames 128 to 255 bytes : %ju\n", + (uint64_t)stats->tx_pkts_128_255); + printf("Transmit frames 256 to 511 bytes : %ju\n", + (uint64_t)stats->tx_pkts_256_511); + printf("Transmit frames 512 to 1023 bytes : %ju\n", + (uint64_t)stats->tx_pkts_512_1023); + printf("Transmit frames 1024 to max bytes : %ju\n", + (uint64_t)stats->tx_pkts_1024_max); + printf("Transmit jabber errors : %u\n", stats->tx_jabbers); + printf("Transmit oversized frames : %ju\n", + (uint64_t)stats->tx_oversize_frames); + printf("Transmit fragmented frames : %ju\n", + (uint64_t)stats->tx_frag_frames); + printf("Transmit underruns : %u\n", stats->tx_colls); + printf("Transmit total collisions : %u\n", stats->tx_single_colls); + printf("Transmit single collisions : %u\n", stats->tx_single_colls); + printf("Transmit multiple collisions : %u\n", stats->tx_multi_colls); + printf("Transmit excess collisions : %u\n", stats->tx_excess_colls); + printf("Transmit late collisions : %u\n", stats->tx_late_colls); + printf("Transmit deferrals : %u\n", stats->tx_deferrals); + printf("Transmit carrier losts : %u\n", stats->tx_carrier_losts); + printf("Transmit pause frames : %u\n", stats->tx_pause_frames); + + printf("Receive good octets : %ju\n", + (uintmax_t)stats->rx_good_octets); + printf("Receive good frames : %ju\n", + (uintmax_t)stats->rx_good_frames); + printf("Receive octets : %ju\n", + (uintmax_t)stats->rx_octets); + printf("Receive frames : %ju\n", + (uintmax_t)stats->rx_frames); + printf("Receive broadcast frames : %ju\n", + (uintmax_t)stats->rx_bcast_frames); + printf("Receive multicast frames : %ju\n", + (uintmax_t)stats->rx_mcast_frames); + printf("Receive frames 64 bytes : %ju\n", + (uint64_t)stats->rx_pkts_64); + printf("Receive frames 65 to 127 bytes : %ju\n", + (uint64_t)stats->rx_pkts_65_127); + printf("Receive frames 128 to 255 bytes : %ju\n", + (uint64_t)stats->rx_pkts_128_255); + printf("Receive frames 256 to 511 bytes : %ju\n", + (uint64_t)stats->rx_pkts_256_511); + printf("Receive frames 512 to 1023 bytes : %ju\n", + (uint64_t)stats->rx_pkts_512_1023); + printf("Receive frames 1024 to max bytes : %ju\n", + (uint64_t)stats->rx_pkts_1024_max); + printf("Receive jabber errors : %u\n", stats->rx_jabbers); + printf("Receive oversized frames : %ju\n", + (uint64_t)stats->rx_oversize_frames); + printf("Receive fragmented frames : %ju\n", + (uint64_t)stats->rx_frag_frames); + printf("Receive missed frames : %u\n", stats->rx_missed_frames); + printf("Receive CRC align errors : %u\n", stats->rx_crc_align_errs); + printf("Receive undersized frames : %u\n", stats->rx_runts); + printf("Receive CRC errors : %u\n", stats->rx_crc_errs); + printf("Receive align errors : %u\n", stats->rx_align_errs); + printf("Receive symbol errors : %u\n", stats->rx_symbol_errs); + printf("Receive pause frames : %u\n", stats->rx_pause_frames); + printf("Receive control frames : %u\n", stats->rx_control_frames); + + return (error); +} diff --git a/sys/dev/bfe/if_bfereg.h b/sys/dev/bfe/if_bfereg.h index 672d2572770a..b50627edbf89 100644 --- a/sys/dev/bfe/if_bfereg.h +++ b/sys/dev/bfe/if_bfereg.h @@ -479,25 +479,105 @@ struct bfe_rxheader { u_int16_t pad[12]; }; -struct bfe_hw_stats { - u_int32_t tx_good_octets, tx_good_pkts, tx_octets; - u_int32_t tx_pkts, tx_broadcast_pkts, tx_multicast_pkts; - u_int32_t tx_len_64, tx_len_65_to_127, tx_len_128_to_255; - u_int32_t tx_len_256_to_511, tx_len_512_to_1023, tx_len_1024_to_max; - u_int32_t tx_jabber_pkts, tx_oversize_pkts, tx_fragment_pkts; - u_int32_t tx_underruns, tx_total_cols, tx_single_cols; - u_int32_t tx_multiple_cols, tx_excessive_cols, tx_late_cols; - u_int32_t tx_defered, tx_carrier_lost, tx_pause_pkts; - u_int32_t __pad1[8]; +#define MIB_TX_GOOD_O 0 +#define MIB_TX_GOOD_P 1 +#define MIB_TX_O 2 +#define MIB_TX_P 3 +#define MIB_TX_BCAST 4 +#define MIB_TX_MCAST 5 +#define MIB_TX_64 6 +#define MIB_TX_65_127 7 +#define MIB_TX_128_255 8 +#define MIB_TX_256_511 9 +#define MIB_TX_512_1023 10 +#define MIB_TX_1024_MAX 11 +#define MIB_TX_JABBER 12 +#define MIB_TX_OSIZE 13 +#define MIB_TX_FRAG 14 +#define MIB_TX_URUNS 15 +#define MIB_TX_TCOLS 16 +#define MIB_TX_SCOLS 17 +#define MIB_TX_MCOLS 18 +#define MIB_TX_ECOLS 19 +#define MIB_TX_LCOLS 20 +#define MIB_TX_DEFERED 21 +#define MIB_TX_CLOST 22 +#define MIB_TX_PAUSE 23 +#define MIB_RX_GOOD_O 24 +#define MIB_RX_GOOD_P 25 +#define MIB_RX_O 26 +#define MIB_RX_P 27 +#define MIB_RX_BCAST 28 +#define MIB_RX_MCAST 29 +#define MIB_RX_64 30 +#define MIB_RX_65_127 31 +#define MIB_RX_128_255 32 +#define MIB_RX_256_511 33 +#define MIB_RX_512_1023 34 +#define MIB_RX_1024_MAX 35 +#define MIB_RX_JABBER 36 +#define MIB_RX_OSIZE 37 +#define MIB_RX_FRAG 38 +#define MIB_RX_MISS 39 +#define MIB_RX_CRCA 40 +#define MIB_RX_USIZE 41 +#define MIB_RX_CRC 42 +#define MIB_RX_ALIGN 43 +#define MIB_RX_SYM 44 +#define MIB_RX_PAUSE 45 +#define MIB_RX_NPAUSE 46 - u_int32_t rx_good_octets, rx_good_pkts, rx_octets; - u_int32_t rx_pkts, rx_broadcast_pkts, rx_multicast_pkts; - u_int32_t rx_len_64, rx_len_65_to_127, rx_len_128_to_255; - u_int32_t rx_len_256_to_511, rx_len_512_to_1023, rx_len_1024_to_max; - u_int32_t rx_jabber_pkts, rx_oversize_pkts, rx_fragment_pkts; - u_int32_t rx_missed_pkts, rx_crc_align_errs, rx_undersize; - u_int32_t rx_crc_errs, rx_align_errs, rx_symbol_errs; - u_int32_t rx_pause_pkts, rx_nonpause_pkts; +#define BFE_MIB_CNT (MIB_RX_NPAUSE - MIB_TX_GOOD_O + 1) + +struct bfe_hw_stats { + uint64_t tx_good_octets; + uint64_t tx_good_frames; + uint64_t tx_octets; + uint64_t tx_frames; + uint64_t tx_bcast_frames; + uint64_t tx_mcast_frames; + uint64_t tx_pkts_64; + uint64_t tx_pkts_65_127; + uint64_t tx_pkts_128_255; + uint64_t tx_pkts_256_511; + uint64_t tx_pkts_512_1023; + uint64_t tx_pkts_1024_max; + uint32_t tx_jabbers; + uint64_t tx_oversize_frames; + uint64_t tx_frag_frames; + uint32_t tx_underruns; + uint32_t tx_colls; + uint32_t tx_single_colls; + uint32_t tx_multi_colls; + uint32_t tx_excess_colls; + uint32_t tx_late_colls; + uint32_t tx_deferrals; + uint32_t tx_carrier_losts; + uint32_t tx_pause_frames; + + uint64_t rx_good_octets; + uint64_t rx_good_frames; + uint64_t rx_octets; + uint64_t rx_frames; + uint64_t rx_bcast_frames; + uint64_t rx_mcast_frames; + uint64_t rx_pkts_64; + uint64_t rx_pkts_65_127; + uint64_t rx_pkts_128_255; + uint64_t rx_pkts_256_511; + uint64_t rx_pkts_512_1023; + uint64_t rx_pkts_1024_max; + uint32_t rx_jabbers; + uint64_t rx_oversize_frames; + uint64_t rx_frag_frames; + uint32_t rx_missed_frames; + uint32_t rx_crc_align_errs; + uint32_t rx_runts; + uint32_t rx_crc_errs; + uint32_t rx_align_errs; + uint32_t rx_symbol_errs; + uint32_t rx_pause_frames; + uint32_t rx_control_frames; }; struct bfe_softc @@ -515,7 +595,7 @@ struct bfe_softc struct resource *bfe_irq; struct resource *bfe_res; struct callout bfe_stat_co; - struct bfe_hw_stats bfe_hwstats; + struct bfe_hw_stats bfe_stats; struct bfe_desc *bfe_tx_list, *bfe_rx_list; struct bfe_tx_data bfe_tx_ring[BFE_TX_LIST_CNT]; /* XXX */ struct bfe_rx_data bfe_rx_ring[BFE_RX_LIST_CNT]; /* XXX */