mvneta: Fix 64-bit MIB reads
It appears we must read MIB values as 2 4-byte words, lower address first. A single 8-byte MIB read returns the value with the lower 4 bytes copied into the upper 4 bytes, resulting in bogus byte counter values. Reviewed by: mw MFC after: 2 weeks Sponsored by: Rubicon Communications, LLC (Netgate) Differential Revision: https://reviews.freebsd.org/D27870
This commit is contained in:
parent
c4cceb1d0d
commit
caf552a607
@ -186,6 +186,7 @@ STATIC void sysctl_mvneta_init(struct mvneta_softc *);
|
|||||||
|
|
||||||
/* MIB */
|
/* MIB */
|
||||||
STATIC void mvneta_clear_mib(struct mvneta_softc *);
|
STATIC void mvneta_clear_mib(struct mvneta_softc *);
|
||||||
|
STATIC uint64_t mvneta_read_mib(struct mvneta_softc *, int);
|
||||||
STATIC void mvneta_update_mib(struct mvneta_softc *);
|
STATIC void mvneta_update_mib(struct mvneta_softc *);
|
||||||
|
|
||||||
/* Switch */
|
/* Switch */
|
||||||
@ -1102,7 +1103,7 @@ STATIC int
|
|||||||
mvneta_initreg(struct ifnet *ifp)
|
mvneta_initreg(struct ifnet *ifp)
|
||||||
{
|
{
|
||||||
struct mvneta_softc *sc;
|
struct mvneta_softc *sc;
|
||||||
int q, i;
|
int q;
|
||||||
uint32_t reg;
|
uint32_t reg;
|
||||||
|
|
||||||
sc = ifp->if_softc;
|
sc = ifp->if_softc;
|
||||||
@ -1189,14 +1190,7 @@ mvneta_initreg(struct ifnet *ifp)
|
|||||||
MVNETA_WRITE(sc, MVNETA_PXCX, reg);
|
MVNETA_WRITE(sc, MVNETA_PXCX, reg);
|
||||||
|
|
||||||
/* clear MIB counter registers(clear by read) */
|
/* clear MIB counter registers(clear by read) */
|
||||||
for (i = 0; i < nitems(mvneta_mib_list); i++) {
|
mvneta_clear_mib(sc);
|
||||||
if (mvneta_mib_list[i].reg64)
|
|
||||||
MVNETA_READ_MIB_8(sc, mvneta_mib_list[i].regnum);
|
|
||||||
else
|
|
||||||
MVNETA_READ_MIB_4(sc, mvneta_mib_list[i].regnum);
|
|
||||||
}
|
|
||||||
MVNETA_READ(sc, MVNETA_PDFC);
|
|
||||||
MVNETA_READ(sc, MVNETA_POFC);
|
|
||||||
|
|
||||||
/* Set SDC register except IPGINT bits */
|
/* Set SDC register except IPGINT bits */
|
||||||
reg = MVNETA_SDC_RXBSZ_16_64BITWORDS;
|
reg = MVNETA_SDC_RXBSZ_16_64BITWORDS;
|
||||||
@ -3538,6 +3532,19 @@ sysctl_mvneta_init(struct mvneta_softc *sc)
|
|||||||
/*
|
/*
|
||||||
* MIB
|
* MIB
|
||||||
*/
|
*/
|
||||||
|
STATIC uint64_t
|
||||||
|
mvneta_read_mib(struct mvneta_softc *sc, int index)
|
||||||
|
{
|
||||||
|
struct mvneta_mib_def *mib;
|
||||||
|
uint64_t val;
|
||||||
|
|
||||||
|
mib = &mvneta_mib_list[index];
|
||||||
|
val = MVNETA_READ_MIB(sc, mib->regnum);
|
||||||
|
if (mib->reg64)
|
||||||
|
val |= (uint64_t)MVNETA_READ_MIB(sc, mib->regnum + 4) << 32;
|
||||||
|
return (val);
|
||||||
|
}
|
||||||
|
|
||||||
STATIC void
|
STATIC void
|
||||||
mvneta_clear_mib(struct mvneta_softc *sc)
|
mvneta_clear_mib(struct mvneta_softc *sc)
|
||||||
{
|
{
|
||||||
@ -3546,10 +3553,7 @@ mvneta_clear_mib(struct mvneta_softc *sc)
|
|||||||
KASSERT_SC_MTX(sc);
|
KASSERT_SC_MTX(sc);
|
||||||
|
|
||||||
for (i = 0; i < nitems(mvneta_mib_list); i++) {
|
for (i = 0; i < nitems(mvneta_mib_list); i++) {
|
||||||
if (mvneta_mib_list[i].reg64)
|
(void)mvneta_read_mib(sc, i);
|
||||||
MVNETA_READ_MIB_8(sc, mvneta_mib_list[i].regnum);
|
|
||||||
else
|
|
||||||
MVNETA_READ_MIB_4(sc, mvneta_mib_list[i].regnum);
|
|
||||||
sc->sysctl_mib[i].counter = 0;
|
sc->sysctl_mib[i].counter = 0;
|
||||||
}
|
}
|
||||||
MVNETA_READ(sc, MVNETA_PDFC);
|
MVNETA_READ(sc, MVNETA_PDFC);
|
||||||
@ -3569,11 +3573,7 @@ mvneta_update_mib(struct mvneta_softc *sc)
|
|||||||
|
|
||||||
for (i = 0; i < nitems(mvneta_mib_list); i++) {
|
for (i = 0; i < nitems(mvneta_mib_list); i++) {
|
||||||
|
|
||||||
if (mvneta_mib_list[i].reg64)
|
val = mvneta_read_mib(sc, i);
|
||||||
val = MVNETA_READ_MIB_8(sc, mvneta_mib_list[i].regnum);
|
|
||||||
else
|
|
||||||
val = MVNETA_READ_MIB_4(sc, mvneta_mib_list[i].regnum);
|
|
||||||
|
|
||||||
if (val == 0)
|
if (val == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -69,10 +69,8 @@
|
|||||||
#define MVNETA_WRITE_REGION(sc, reg, val, c) \
|
#define MVNETA_WRITE_REGION(sc, reg, val, c) \
|
||||||
bus_write_region_4((sc)->res[0], (reg), (val), (c))
|
bus_write_region_4((sc)->res[0], (reg), (val), (c))
|
||||||
|
|
||||||
#define MVNETA_READ_MIB_4(sc, reg) \
|
#define MVNETA_READ_MIB(sc, reg) \
|
||||||
bus_read_4((sc)->res[0], MVNETA_PORTMIB_BASE + (reg))
|
bus_read_4((sc)->res[0], MVNETA_PORTMIB_BASE + (reg))
|
||||||
#define MVNETA_READ_MIB_8(sc, reg) \
|
|
||||||
bus_read_8((sc)->res[0], MVNETA_PORTMIB_BASE + (reg))
|
|
||||||
|
|
||||||
#define MVNETA_IS_LINKUP(sc) \
|
#define MVNETA_IS_LINKUP(sc) \
|
||||||
(MVNETA_READ((sc), MVNETA_PSR) & MVNETA_PSR_LINKUP)
|
(MVNETA_READ((sc), MVNETA_PSR) & MVNETA_PSR_LINKUP)
|
||||||
|
Loading…
Reference in New Issue
Block a user