diff mbox series

[5.10,51/96] net: dsa: microchip: Fix ksz_read64()

Message ID 20210816125436.659359567@linuxfoundation.org
State Superseded
Headers show
Series None | expand

Commit Message

Greg Kroah-Hartman Aug. 16, 2021, 1:02 p.m. UTC
From: Ben Hutchings <ben.hutchings@mind.be>

[ Upstream commit c34f674c8875235725c3ef86147a627f165d23b4 ]

ksz_read64() currently does some dubious byte-swapping on the two
halves of a 64-bit register, and then only returns the high bits.
Replace this with a straightforward expression.

Fixes: e66f840c08a2 ("net: dsa: ksz: Add Microchip KSZ8795 DSA driver")
Signed-off-by: Ben Hutchings <ben.hutchings@mind.be>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/net/dsa/microchip/ksz_common.h | 8 ++------
 1 file changed, 2 insertions(+), 6 deletions(-)

Comments

Pavel Machek Aug. 17, 2021, 5:56 p.m. UTC | #1
Hi!

> [ Upstream commit c34f674c8875235725c3ef86147a627f165d23b4 ]
> 
> ksz_read64() currently does some dubious byte-swapping on the two
> halves of a 64-bit register, and then only returns the high bits.
> Replace this with a straightforward expression.

The code indeed is very strange, but there are just 2 users, and they
will now receive byteswapped values, right? If it worked before, it
will be broken.

Did this get enough testing for -stable?

Is hw little endian or high endian or...? Note that ksz_write64()
still contains the strange code, at least in 5.10.

Best regards,
							Pavel
							
> +++ b/drivers/net/dsa/microchip/ksz_common.h
> @@ -210,12 +210,8 @@ static inline int ksz_read64(struct ksz_device *dev, u32 reg, u64 *val)
>  	int ret;
>  
>  	ret = regmap_bulk_read(dev->regmap[2], reg, value, 2);
> -	if (!ret) {
> -		/* Ick! ToDo: Add 64bit R/W to regmap on 32bit systems */
> -		value[0] = swab32(value[0]);
> -		value[1] = swab32(value[1]);
> -		*val = swab64((u64)*value);
> -	}
> +	if (!ret)
> +		*val = (u64)value[0] << 32 | value[1];
>  
>  	return ret;
>  }
Pavel Machek Aug. 18, 2021, 7:26 p.m. UTC | #2
Hi!

> > > [ Upstream commit c34f674c8875235725c3ef86147a627f165d23b4 ]

> > > 

> > > ksz_read64() currently does some dubious byte-swapping on the two

> > > halves of a 64-bit register, and then only returns the high bits.

> > > Replace this with a straightforward expression.

> > 

> > The code indeed is very strange, but there are just 2 users, and they

> > will now receive byteswapped values, right? If it worked before, it

> > will be broken.

> 

> The old code swaps the bytes within each 32-bit word, attempts to

> concatenate them into a 64-bit word, then swaps the bytes within the

> 64-bit word.  There is no need for byte-swapping, only (on little-

> endian platforms) a word-swap, which is what the new code does.

> 

> > Did this get enough testing for -stable?

> 

> Yes, I actually developed and tested all the ksz8795 changes in 5.10

> before forward-porting to mainline.

> 

> > Is hw little endian or high endian or...?

> 

> The hardware is big-endian and regmap handles any necessary

> byte-swapping for values up to 32 bits.

> 

> > Note that ksz_write64() still contains the strange code, at least in

> > 5.10.

> 

> It's unnecessarily complex, but it does work.


Thanks for the explanations and sorry for the noise. Indeed
ksz_write64() is quite obfuscated, but I can't see a problem.

Best regards,
								Pavel
								
-- 
DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
diff mbox series

Patch

diff --git a/drivers/net/dsa/microchip/ksz_common.h b/drivers/net/dsa/microchip/ksz_common.h
index cf866e48ff66..a51c716ec920 100644
--- a/drivers/net/dsa/microchip/ksz_common.h
+++ b/drivers/net/dsa/microchip/ksz_common.h
@@ -210,12 +210,8 @@  static inline int ksz_read64(struct ksz_device *dev, u32 reg, u64 *val)
 	int ret;
 
 	ret = regmap_bulk_read(dev->regmap[2], reg, value, 2);
-	if (!ret) {
-		/* Ick! ToDo: Add 64bit R/W to regmap on 32bit systems */
-		value[0] = swab32(value[0]);
-		value[1] = swab32(value[1]);
-		*val = swab64((u64)*value);
-	}
+	if (!ret)
+		*val = (u64)value[0] << 32 | value[1];
 
 	return ret;
 }