diff options
author | 2013-03-17 10:17:54 +0000 | |
---|---|---|
committer | 2013-03-17 10:17:54 +0000 | |
commit | 4be0945e7e71b7acd32771d7a689f5a94c53b35f (patch) | |
tree | 690cf0e0a38809c3ebaf1f35c9ac2815251497dd | |
parent | Split out the hardware listed in the page into a table and (diff) | |
download | wireguard-openbsd-4be0945e7e71b7acd32771d7a689f5a94c53b35f.tar.xz wireguard-openbsd-4be0945e7e71b7acd32771d7a689f5a94c53b35f.zip |
- Sync some of the stats counter code to be closer to the FreeBSD code,
but no functional change.
- Add a workaround for BCM5717 / BCM5718 / BCM5719 A0 and BCM5720 A0 chipsets
to not count the interface input drops counter for input errors due to HW
errata.
From FreeBSD
ok sthen@
-rw-r--r-- | sys/dev/pci/if_bge.c | 47 |
1 files changed, 35 insertions, 12 deletions
diff --git a/sys/dev/pci/if_bge.c b/sys/dev/pci/if_bge.c index c22b17082c7..1e193ecc6d5 100644 --- a/sys/dev/pci/if_bge.c +++ b/sys/dev/pci/if_bge.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_bge.c,v 1.323 2013/03/11 01:12:40 dlg Exp $ */ +/* $OpenBSD: if_bge.c,v 1.324 2013/03/17 10:17:54 brad Exp $ */ /* * Copyright (c) 2001 Wind River Systems @@ -3503,13 +3503,38 @@ bge_stats_update_regs(struct bge_softc *sc) { struct ifnet *ifp = &sc->arpcom.ac_if; - ifp->if_collisions += CSR_READ_4(sc, BGE_MAC_STATS + + sc->bge_tx_collisions += CSR_READ_4(sc, BGE_MAC_STATS + offsetof(struct bge_mac_stats_regs, etherStatsCollisions)); - sc->bge_rx_discards += CSR_READ_4(sc, BGE_RXLP_LOCSTAT_IFIN_DROPS); - sc->bge_rx_inerrors += CSR_READ_4(sc, BGE_RXLP_LOCSTAT_IFIN_ERRORS); sc->bge_rx_overruns += CSR_READ_4(sc, BGE_RXLP_LOCSTAT_OUT_OF_BDS); + /* + * XXX + * Unlike other controllers, BGE_RXLP_LOCSTAT_IFIN_DROPS + * counter of BCM5717, BCM5718, BCM5719 A0 and BCM5720 A0 + * includes number of unwanted multicast frames. This comes + * from silicon bug and known workaround to get rough(not + * exact) counter is to enable interrupt on MBUF low water + * attention. This can be accomplished by setting + * BGE_HCCMODE_ATTN bit of BGE_HCC_MODE, + * BGE_BMANMODE_LOMBUF_ATTN bit of BGE_BMAN_MODE and + * BGE_MODECTL_FLOWCTL_ATTN_INTR bit of BGE_MODE_CTL. + * However that change would generate more interrupts and + * there are still possibilities of losing multiple frames + * during BGE_MODECTL_FLOWCTL_ATTN_INTR interrupt handling. + * Given that the workaround still would not get correct + * counter I don't think it's worth to implement it. So + * ignore reading the counter on controllers that have the + * silicon bug. + */ + if (BGE_ASICREV(sc->bge_chipid) != BGE_ASICREV_BCM5717 && + sc->bge_chipid != BGE_CHIPID_BCM5719_A0 && + sc->bge_chipid != BGE_CHIPID_BCM5720_A0) + sc->bge_rx_discards += CSR_READ_4(sc, BGE_RXLP_LOCSTAT_IFIN_DROPS); + + sc->bge_rx_inerrors += CSR_READ_4(sc, BGE_RXLP_LOCSTAT_IFIN_ERRORS); + + ifp->if_collisions = sc->bge_tx_collisions; ifp->if_ierrors = sc->bge_rx_discards + sc->bge_rx_inerrors + sc->bge_rx_overruns; } @@ -3528,18 +3553,16 @@ bge_stats_update(struct bge_softc *sc) ifp->if_collisions += (u_int32_t)(cnt - sc->bge_tx_collisions); sc->bge_tx_collisions = cnt; + cnt = READ_STAT(sc, stats, nicNoMoreRxBDs.bge_addr_lo); + ifp->if_ierrors += (uint32_t)(cnt - sc->bge_rx_overruns); + sc->bge_rx_overruns = cnt; + cnt = READ_STAT(sc, stats, ifInErrors.bge_addr_lo); + ifp->if_ierrors += (uint32_t)(cnt - sc->bge_rx_inerrors); + sc->bge_rx_inerrors = cnt; cnt = READ_STAT(sc, stats, ifInDiscards.bge_addr_lo); ifp->if_ierrors += (u_int32_t)(cnt - sc->bge_rx_discards); sc->bge_rx_discards = cnt; - cnt = READ_STAT(sc, stats, ifInErrors.bge_addr_lo); - ifp->if_ierrors += (u_int32_t)(cnt - sc->bge_rx_inerrors); - sc->bge_rx_inerrors = cnt; - - cnt = READ_STAT(sc, stats, nicNoMoreRxBDs.bge_addr_lo); - ifp->if_ierrors += (u_int32_t)(cnt - sc->bge_rx_overruns); - sc->bge_rx_overruns = cnt; - cnt = READ_STAT(sc, stats, txstats.ifOutDiscards.bge_addr_lo); ifp->if_oerrors += (u_int32_t)(cnt - sc->bge_tx_discards); sc->bge_tx_discards = cnt; |