From 232b6743e4d12d8383aaf2d632d5ed4cc377419e Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Sat, 2 Jun 2018 22:37:42 +0300 Subject: [PATCH 1/3] sh_eth: make sh_eth_soft_swap() work on ARM Browsing thru the driver disassembly, I noticed that ARM gcc generated no code whatsoever for sh_eth_soft_swap() while building a little-endian kernel -- apparently __LITTLE_ENDIAN__ was not being #define'd, however it got implicitly #define'd when building with the SH gcc (I could only find the explicit #define __LITTLE_ENDIAN that was #include'd when building a little-endian kernel). Luckily, the Ether controller only doing big- endian DMA is encountered on the early SH771x SoCs only and all ARM SoCs implement EDMR.DE and thus set 'sh_eth_cpu_data::hw_swap'. But anyway, we need to fix the #ifdef inside sh_eth_soft_swap() to something that would work on all architectures... Signed-off-by: Sergei Shtylyov Reviewed-by: Geert Uytterhoeven Signed-off-by: David S. Miller --- drivers/net/ethernet/renesas/sh_eth.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/renesas/sh_eth.h b/drivers/net/ethernet/renesas/sh_eth.h index 5dee19b61aeed..d77de7651d8fa 100644 --- a/drivers/net/ethernet/renesas/sh_eth.h +++ b/drivers/net/ethernet/renesas/sh_eth.h @@ -562,7 +562,7 @@ struct sh_eth_private { static inline void sh_eth_soft_swap(char *src, int len) { -#ifdef __LITTLE_ENDIAN__ +#ifdef __LITTLE_ENDIAN u32 *p = (u32 *)src; u32 *maxp; maxp = p + ((len + sizeof(u32) - 1) / sizeof(u32)); From bb2fa4e847d779c0c3eba78c1abbe142134dcc3d Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Sat, 2 Jun 2018 22:38:56 +0300 Subject: [PATCH 2/3] sh_eth: uninline sh_eth_soft_swap() sh_eth_tsu_soft_swap() is called twice by the driver, remove *inline* and move that function from the header to the driver itself to let gcc decide whether to expand it inline or not... Signed-off-by: Sergei Shtylyov Reviewed-by: Geert Uytterhoeven Signed-off-by: David S. Miller --- drivers/net/ethernet/renesas/sh_eth.c | 11 +++++++++++ drivers/net/ethernet/renesas/sh_eth.h | 12 ------------ 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c index d9cadfb1bc4a7..82b03f13243e5 100644 --- a/drivers/net/ethernet/renesas/sh_eth.c +++ b/drivers/net/ethernet/renesas/sh_eth.c @@ -460,6 +460,17 @@ static u32 sh_eth_tsu_read(struct sh_eth_private *mdp, int enum_index) return ioread32(mdp->tsu_addr + offset); } +static void sh_eth_soft_swap(char *src, int len) +{ +#ifdef __LITTLE_ENDIAN + u32 *p = (u32 *)src; + u32 *maxp = p + ((len + sizeof(u32) - 1) / sizeof(u32)); + + for (; p < maxp; p++) + *p = swab32(*p); +#endif +} + static void sh_eth_select_mii(struct net_device *ndev) { struct sh_eth_private *mdp = netdev_priv(ndev); diff --git a/drivers/net/ethernet/renesas/sh_eth.h b/drivers/net/ethernet/renesas/sh_eth.h index d77de7651d8fa..726c55a82dd7b 100644 --- a/drivers/net/ethernet/renesas/sh_eth.h +++ b/drivers/net/ethernet/renesas/sh_eth.h @@ -560,18 +560,6 @@ struct sh_eth_private { unsigned wol_enabled:1; }; -static inline void sh_eth_soft_swap(char *src, int len) -{ -#ifdef __LITTLE_ENDIAN - u32 *p = (u32 *)src; - u32 *maxp; - maxp = p + ((len + sizeof(u32) - 1) / sizeof(u32)); - - for (; p < maxp; p++) - *p = swab32(*p); -#endif -} - static inline void *sh_eth_tsu_get_offset(struct sh_eth_private *mdp, int enum_index) { From 1100149a23a5053de4709dc4ba14ab14bd826562 Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Sat, 2 Jun 2018 22:40:16 +0300 Subject: [PATCH 3/3] sh_eth: use DIV_ROUND_UP() in sh_eth_soft_swap() When initializing 'maxp' in sh_eth_soft_swap(), the buffer length needs to be rounded up -- that's just asking for DIV_ROUND_UP()! Signed-off-by: Sergei Shtylyov Reviewed-by: Geert Uytterhoeven Signed-off-by: David S. Miller --- drivers/net/ethernet/renesas/sh_eth.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c index 82b03f13243e5..e9007b613f17c 100644 --- a/drivers/net/ethernet/renesas/sh_eth.c +++ b/drivers/net/ethernet/renesas/sh_eth.c @@ -464,7 +464,7 @@ static void sh_eth_soft_swap(char *src, int len) { #ifdef __LITTLE_ENDIAN u32 *p = (u32 *)src; - u32 *maxp = p + ((len + sizeof(u32) - 1) / sizeof(u32)); + u32 *maxp = p + DIV_ROUND_UP(len, sizeof(u32)); for (; p < maxp; p++) *p = swab32(*p);