Hi Rasmus, Andrew, On Wed, 29 May 2019 06:42:53 +0000, Rasmus Villemoes <rasmus.villem...@prevas.dk> wrote: > On 28/05/2019 15.44, Andrew Lunn wrote: > > On Tue, May 28, 2019 at 01:17:10PM +0000, Rasmus Villemoes wrote: > >> Currently, the upper half of a 4-byte STATS_TYPE_PORT statistic ends > >> up in bits 47:32 of the return value, instead of bits 31:16 as they > >> should. > >> > >> Signed-off-by: Rasmus Villemoes <rasmus.villem...@prevas.dk> > > > > Hi Rasmus > > > > Please include a Fixes tag, to indicate where the problem was > > introduced. In this case, i think it was: > > > > Fixes: 6e46e2d821bb ("net: dsa: mv88e6xxx: Fix u64 statistics") > > > > And set the Subject to [PATCH net] to indicate this should be applied > > to the net tree. > > Will do. > > >> diff --git a/drivers/net/dsa/mv88e6xxx/chip.c > >> b/drivers/net/dsa/mv88e6xxx/chip.c > >> index 370434bdbdab..317553d2cb21 100644 > >> --- a/drivers/net/dsa/mv88e6xxx/chip.c > >> +++ b/drivers/net/dsa/mv88e6xxx/chip.c > >> @@ -785,7 +785,7 @@ static uint64_t _mv88e6xxx_get_ethtool_stat(struct > >> mv88e6xxx_chip *chip, > >> err = mv88e6xxx_port_read(chip, port, s->reg + 1, ®); > >> if (err) > >> return U64_MAX; > >> - high = reg; > >> + low |= ((u32)reg) << 16; > >> } > >> break; > >> case STATS_TYPE_BANK1: > > > > What i don't like about this is how the function finishes: > > > > } > > value = (((u64)high) << 32) | low; > > return value; > > } > > > > A better fix might be > > > > - break > > + value = (((u64)high) << 16 | low; > > + return value; > > Why? It's odd to have the u32 "high" sometimes represent the high 32 > bits, sometimes the third 16 bits. It would make it harder to support an > 8-byte STATS_TYPE_PORT statistic. I think the code is much cleaner if > each case is just responsible for providing the upper/lower 32 bits, > then have the common case combine them; . It's just that in the > STATS_TYPE_BANK cases, the 32 bits are assembled from two 16 bit values > by a helper (mv88e6xxx_g1_stats_read), while it is "open-coded" in the > first case.
Here "low" and "high" are u32 and refer to the upper and lower halves of the u64 returned value. For a 4-byte STATS_TYPE_PORT value, the second read refers to the bits 31:16, thus belongs to (the upper half of) the lower half of the 64-bit returned value, i.e. "low". The current return value is correct, as well as your patch. Thanks, Vivien