Skip to content

Commit caf552a

Browse files
committed
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
1 parent c4cceb1 commit caf552a

File tree

2 files changed

+19
-21
lines changed

2 files changed

+19
-21
lines changed

sys/dev/neta/if_mvneta.c

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,7 @@ STATIC void sysctl_mvneta_init(struct mvneta_softc *);
186186

187187
/* MIB */
188188
STATIC void mvneta_clear_mib(struct mvneta_softc *);
189+
STATIC uint64_t mvneta_read_mib(struct mvneta_softc *, int);
189190
STATIC void mvneta_update_mib(struct mvneta_softc *);
190191

191192
/* Switch */
@@ -1102,7 +1103,7 @@ STATIC int
11021103
mvneta_initreg(struct ifnet *ifp)
11031104
{
11041105
struct mvneta_softc *sc;
1105-
int q, i;
1106+
int q;
11061107
uint32_t reg;
11071108

11081109
sc = ifp->if_softc;
@@ -1189,14 +1190,7 @@ mvneta_initreg(struct ifnet *ifp)
11891190
MVNETA_WRITE(sc, MVNETA_PXCX, reg);
11901191

11911192
/* clear MIB counter registers(clear by read) */
1192-
for (i = 0; i < nitems(mvneta_mib_list); i++) {
1193-
if (mvneta_mib_list[i].reg64)
1194-
MVNETA_READ_MIB_8(sc, mvneta_mib_list[i].regnum);
1195-
else
1196-
MVNETA_READ_MIB_4(sc, mvneta_mib_list[i].regnum);
1197-
}
1198-
MVNETA_READ(sc, MVNETA_PDFC);
1199-
MVNETA_READ(sc, MVNETA_POFC);
1193+
mvneta_clear_mib(sc);
12001194

12011195
/* Set SDC register except IPGINT bits */
12021196
reg = MVNETA_SDC_RXBSZ_16_64BITWORDS;
@@ -3538,6 +3532,19 @@ sysctl_mvneta_init(struct mvneta_softc *sc)
35383532
/*
35393533
* MIB
35403534
*/
3535+
STATIC uint64_t
3536+
mvneta_read_mib(struct mvneta_softc *sc, int index)
3537+
{
3538+
struct mvneta_mib_def *mib;
3539+
uint64_t val;
3540+
3541+
mib = &mvneta_mib_list[index];
3542+
val = MVNETA_READ_MIB(sc, mib->regnum);
3543+
if (mib->reg64)
3544+
val |= (uint64_t)MVNETA_READ_MIB(sc, mib->regnum + 4) << 32;
3545+
return (val);
3546+
}
3547+
35413548
STATIC void
35423549
mvneta_clear_mib(struct mvneta_softc *sc)
35433550
{
@@ -3546,10 +3553,7 @@ mvneta_clear_mib(struct mvneta_softc *sc)
35463553
KASSERT_SC_MTX(sc);
35473554

35483555
for (i = 0; i < nitems(mvneta_mib_list); i++) {
3549-
if (mvneta_mib_list[i].reg64)
3550-
MVNETA_READ_MIB_8(sc, mvneta_mib_list[i].regnum);
3551-
else
3552-
MVNETA_READ_MIB_4(sc, mvneta_mib_list[i].regnum);
3556+
(void)mvneta_read_mib(sc, i);
35533557
sc->sysctl_mib[i].counter = 0;
35543558
}
35553559
MVNETA_READ(sc, MVNETA_PDFC);
@@ -3569,11 +3573,7 @@ mvneta_update_mib(struct mvneta_softc *sc)
35693573

35703574
for (i = 0; i < nitems(mvneta_mib_list); i++) {
35713575

3572-
if (mvneta_mib_list[i].reg64)
3573-
val = MVNETA_READ_MIB_8(sc, mvneta_mib_list[i].regnum);
3574-
else
3575-
val = MVNETA_READ_MIB_4(sc, mvneta_mib_list[i].regnum);
3576-
3576+
val = mvneta_read_mib(sc, i);
35773577
if (val == 0)
35783578
continue;
35793579

sys/dev/neta/if_mvnetavar.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,10 +69,8 @@
6969
#define MVNETA_WRITE_REGION(sc, reg, val, c) \
7070
bus_write_region_4((sc)->res[0], (reg), (val), (c))
7171

72-
#define MVNETA_READ_MIB_4(sc, reg) \
72+
#define MVNETA_READ_MIB(sc, reg) \
7373
bus_read_4((sc)->res[0], MVNETA_PORTMIB_BASE + (reg))
74-
#define MVNETA_READ_MIB_8(sc, reg) \
75-
bus_read_8((sc)->res[0], MVNETA_PORTMIB_BASE + (reg))
7674

7775
#define MVNETA_IS_LINKUP(sc) \
7876
(MVNETA_READ((sc), MVNETA_PSR) & MVNETA_PSR_LINKUP)

0 commit comments

Comments
 (0)