[PATCH] net: sh_eth: Cleanup the driver to remove most

Magnus Damm damm at opensource.se
Fri Jul 11 14:39:32 CEST 2025


From: Magnus Damm <damm at opensource.se>

Cleanup the sh_eth.c and sh_eth.h files to get rid of #ifdefs and
replace with DT compat string checks where appropriate.

In the sh_eth driver the offset tables (such as sh_eth_offset_rz[])
are so far used to determine the location of the registers, but with
this patch the offset table is now also used to determine during run
time if registers are are present or not. This is expected to work for
all registers except EDSR.

The functions sh_eth_reg_present() and sh_eth_write_if_present() may be
used to check if a register is present and also perform a conditional
write only in case the register is present.

In the patch sh_eth_offset_rz[] is reworked to try to make it match
the RZ/A1 datasheet. The somewhat funny ordering is there to make it
match the documentation. The code has been ping tested on RZ/A1 Genmai
so the reworked offset table at least shows some sign of correctness.

The RZ/A1 and RZ/A2 cases are switched over from TYPE_RZ to TYPE_GETHER,
however the sh_eth_reg_offs() function (formerly sh_eth_reg_addr()) has
been reworked to follow a certain order that prioritizes CONFIG_RZA1 and
CONFIG_RZA2 over the gigabit offset table. This ordering also applies to
plenty of the bit definition #ifdefs in sh_eth.h.

Please note that sh_eth_is_gether() does not care about the offset table,
it returns true on RZ even though different offset tables are used. Right
now it is used to determine if the device comes with a self-clearing reset
bit or not.

This means that RZ/A1 and RZ/A2 are similar to devices with GETHER in many
ways but with different offset tables and also no gigabit support.

Also some recently introduced #ifdef gets reworked to instead use
run time matching on DT compat string "renesas,gether-r8a77980".

Signed-off-by: Magnus Damm <damm at opensource.se>
---

 Written on top of u-boot master 6bb0679377abb01a82db1ce69b5bf1d40aa02ace
 and
 [PATCH v3 7/9] net: sh_eth: Adjust RZ/A1, add RZ/A2 support
 also 5f520875bdf has been reverted to work around build issues

 drivers/net/sh_eth.c |  167 ++++++++++++++++++++++++--------------------------
 drivers/net/sh_eth.h |  115 +++++++++++++++++++++-------------
 2 files changed, 155 insertions(+), 127 deletions(-)

--- 0004/drivers/net/sh_eth.c
+++ work/drivers/net/sh_eth.c	2025-07-11 20:31:22.438699670 +0900
@@ -29,6 +29,8 @@
 
 #include "sh_eth.h"
 
+DECLARE_GLOBAL_DATA_PTR;
+
 static void flush_cache_wback(void *addr, unsigned long len)
 {
 	flush_dcache_range((unsigned long)addr,
@@ -142,34 +144,34 @@ static void sh_eth_recv_finish(struct sh
 
 static int sh_eth_reset(struct sh_eth_info *port_info)
 {
-#if defined(SH_ETH_TYPE_GETHER) || defined(SH_ETH_TYPE_RZ)
 	int ret = 0, i;
-#if !defined(CONFIG_RZA2)
-	/* Start e-dmac transmitter and receiver */
-	sh_eth_write(port_info, EDSR_ENALL, EDSR);
-#endif
-	/* Perform a software reset and wait for it to complete */
-	sh_eth_write(port_info, EDMR_SRST, EDMR);
-	for (i = 0; i < TIMEOUT_CNT; i++) {
-		if (!(sh_eth_read(port_info, EDMR) & EDMR_SRST))
-			break;
-		udelay(1000);
-	}
 
-	if (i == TIMEOUT_CNT) {
-		printf(SHETHER_NAME  ": Software reset timeout\n");
-		ret = -EIO;
+	if (sh_eth_is_gether(port_info)) {
+		/* Start e-dmac transmitter and receiver */
+		sh_eth_write(port_info, EDSR_ENALL, EDSR);
+
+		/* Perform a software reset and wait for it to complete */
+		sh_eth_write(port_info, EDMR_SRST, EDMR);
+		for (i = 0; i < TIMEOUT_CNT; i++) {
+			if (!(sh_eth_read(port_info, EDMR) & EDMR_SRST))
+				break;
+			udelay(1000);
+		}
+
+		if (i == TIMEOUT_CNT) {
+			printf(SHETHER_NAME  ": Software reset timeout\n");
+			ret = -EIO;
+		}
+	} else {
+		/* no self-clearing bit */
+		sh_eth_write(port_info,
+			     sh_eth_read(port_info, EDMR) | EDMR_SRST, EDMR);
+		mdelay(3);
+		sh_eth_write(port_info,
+			     sh_eth_read(port_info, EDMR) & ~EDMR_SRST, EDMR);
 	}
 
 	return ret;
-#else
-	sh_eth_write(port_info, sh_eth_read(port_info, EDMR) | EDMR_SRST, EDMR);
-	mdelay(3);
-	sh_eth_write(port_info,
-		     sh_eth_read(port_info, EDMR) & ~EDMR_SRST, EDMR);
-
-	return 0;
-#endif
 }
 
 static int sh_eth_tx_desc_init(struct sh_eth_info *port_info)
@@ -213,13 +215,11 @@ static int sh_eth_tx_desc_init(struct sh
 	 * addresses
 	 */
 	sh_eth_write(port_info, ADDR_TO_PHY(port_info->tx_desc_base), TDLAR);
-#if defined(SH_ETH_TYPE_GETHER) || defined(SH_ETH_TYPE_RZ)
-	sh_eth_write(port_info, ADDR_TO_PHY(port_info->tx_desc_base), TDFAR);
-#if !defined(CONFIG_RZA2)
-	sh_eth_write(port_info, ADDR_TO_PHY(cur_tx_desc), TDFXR);
-	sh_eth_write(port_info, 0x01, TDFFR);/* Last discriptor bit */
-#endif
-#endif
+	sh_eth_write_if_present(port_info,
+				ADDR_TO_PHY(port_info->tx_desc_base),
+				TDFAR);
+	sh_eth_write_if_present(port_info, ADDR_TO_PHY(cur_tx_desc), TDFXR);
+	sh_eth_write_if_present(port_info, 0x01, TDFFR);/* Last desc bit */
 
 err:
 	return ret;
@@ -282,13 +282,11 @@ static int sh_eth_rx_desc_init(struct sh
 
 	/* Point the controller to the rx descriptor list */
 	sh_eth_write(port_info, ADDR_TO_PHY(port_info->rx_desc_base), RDLAR);
-#if defined(SH_ETH_TYPE_GETHER) || defined(SH_ETH_TYPE_RZ)
-	sh_eth_write(port_info, ADDR_TO_PHY(port_info->rx_desc_base), RDFAR);
-#if !defined(CONFIG_RZA2)
-	sh_eth_write(port_info, ADDR_TO_PHY(cur_rx_desc), RDFXR);
-	sh_eth_write(port_info, RDFFR_RDLF, RDFFR);
-#endif
-#endif
+	sh_eth_write_if_present(port_info,
+				ADDR_TO_PHY(port_info->rx_desc_base),
+				RDFAR);
+	sh_eth_write_if_present(port_info, ADDR_TO_PHY(cur_rx_desc), RDFXR);
+	sh_eth_write_if_present(port_info, RDFFR_RDLF, RDFFR);
 
 	return ret;
 
@@ -353,7 +351,9 @@ static void sh_eth_write_hwaddr(struct s
 	sh_eth_write(port_info, val, MALR);
 }
 
-static void sh_eth_mac_regs_config(struct sh_eth_info *port_info, unsigned char *mac)
+static void sh_eth_mac_regs_config(struct sh_eth_info *port_info,
+				   unsigned char *mac,
+				   int node)
 {
 	unsigned long edmr;
 
@@ -361,9 +361,11 @@ static void sh_eth_mac_regs_config(struc
 	edmr = sh_eth_read(port_info, EDMR);
 	edmr &= ~EMDR_DESC_R;
 	edmr |= EMDR_DESC | EDMR_EL;
-#if defined(CONFIG_R8A77980)
-	edmr |= EDMR_NBST;
-#endif
+
+	if (fdt_node_check_compatible(gd->fdt_blob, node,
+				      "renesas,gether-r8a77980") == 0)
+		edmr |= EDMR_NBST;
+
 	sh_eth_write(port_info, edmr, EDMR);
 
 	sh_eth_write(port_info, 0, EESIPR);
@@ -371,9 +373,7 @@ static void sh_eth_mac_regs_config(struc
 	sh_eth_write(port_info, 0, TFTR);
 	sh_eth_write(port_info, (FIFO_SIZE_T | FIFO_SIZE_R), FDR);
 	sh_eth_write(port_info, RMCR_RST, RMCR);
-#if defined(SH_ETH_TYPE_GETHER) || defined(SH_ETH_TYPE_RZ)
-	sh_eth_write(port_info, 0, RPADIR);
-#endif
+	sh_eth_write_if_present(port_info, 0, RPADIR);
 	sh_eth_write(port_info, (FIFO_F_D_RFF | FIFO_F_D_RFD), FCFTR);
 
 	/* Configure e-mac registers */
@@ -383,66 +383,61 @@ static void sh_eth_mac_regs_config(struc
 	sh_eth_write_hwaddr(port_info, mac);
 
 	sh_eth_write(port_info, RFLR_RFL_MIN, RFLR);
-#if defined(SH_ETH_TYPE_GETHER)
-	sh_eth_write(port_info, 0, PIPR);
-#endif
-#if defined(SH_ETH_TYPE_GETHER) || defined(SH_ETH_TYPE_RZ)
-	sh_eth_write(port_info, APR_AP, APR);
-	sh_eth_write(port_info, MPR_MP, MPR);
-	sh_eth_write(port_info, TPAUSER_TPAUSE, TPAUSER);
-#endif
 
-#if defined(CONFIG_CPU_SH7734) || defined(CONFIG_R8A7740)
-	sh_eth_write(port_info, CONFIG_SH_ETHER_SH7734_MII, RMII_MII);
-#elif defined(CONFIG_RCAR_GEN2) || defined(CONFIG_R8A77980)
-	sh_eth_write(port_info, sh_eth_read(port_info, RMIIMR) | 0x1, RMIIMR);
+	sh_eth_write_if_present(port_info, 0, PIPR);
+	sh_eth_write_if_present(port_info, APR_AP, APR);
+	sh_eth_write_if_present(port_info, MPR_MP, MPR);
+	sh_eth_write_if_present(port_info, TPAUSER_TPAUSE, TPAUSER);
+
+#ifdef CONFIG_SH_ETHER_SH7734_MII
+	sh_eth_write_if_present(port_info,
+				CONFIG_SH_ETHER_SH7734_MII,
+				RMII_MII);
 #endif
+	if (sh_eth_reg_present(port_info, RMIIMR))
+		sh_eth_write(port_info,
+			     sh_eth_read(port_info, RMIIMR) | 0x1,
+			     RMIIMR);
 }
 
 static int sh_eth_phy_regs_config(struct sh_eth_info *port_info)
 {
 	struct phy_device *phy = port_info->phydev;
 	int ret = 0;
-	u32 val = 0;
+	u32 val = ECMR_CHG_DM | ECMR_RE | ECMR_TE;
 
 	/* Set the transfer speed */
 	if (phy->speed == 100) {
 		printf(SHETHER_NAME ": 100Base/");
-#if defined(SH_ETH_TYPE_GETHER)
-		sh_eth_write(port_info, GECMR_100B, GECMR);
-#elif defined(CONFIG_CPU_SH7757) || defined(CONFIG_CPU_SH7752)
-		sh_eth_write(port_info, 1, RTRATE);
-#elif defined(CONFIG_RCAR_GEN2) || defined(CONFIG_R8A77980) || defined(CONFIG_RZA2)
-		val = ECMR_RTM;
-#endif
+		if (sh_eth_reg_present(port_info, GECMR) ||
+		    sh_eth_reg_present(port_info, RTRATE)) {
+			sh_eth_write_if_present(port_info, GECMR_100B, GECMR);
+			sh_eth_write_if_present(port_info, 1, RTRATE);
+		} else {
+			val |= ECMR_RTM;
+		}
 	} else if (phy->speed == 10) {
 		printf(SHETHER_NAME ": 10Base/");
-#if defined(SH_ETH_TYPE_GETHER)
-		sh_eth_write(port_info, GECMR_10B, GECMR);
-#elif defined(CONFIG_CPU_SH7757) || defined(CONFIG_CPU_SH7752)
-		sh_eth_write(port_info, 0, RTRATE);
-#endif
-	}
-#if defined(SH_ETH_TYPE_GETHER)
-	else if (phy->speed == 1000) {
+		sh_eth_write_if_present(port_info, GECMR_10B, GECMR);
+		sh_eth_write_if_present(port_info, 0, RTRATE);
+	} else if ((phy->speed == 1000) &&
+		 sh_eth_reg_present(port_info, GECMR)) {
 		printf(SHETHER_NAME ": 1000Base/");
 		sh_eth_write(port_info, GECMR_1000B, GECMR);
+	} else {
+		ret = -EINVAL;
 	}
-#endif
 
 	/* Check if full duplex mode is supported by the phy */
 	if (phy->duplex) {
 		printf("Full\n");
-		sh_eth_write(port_info,
-			     val | (ECMR_CHG_DM | ECMR_RE | ECMR_TE | ECMR_DM),
-			     ECMR);
+		val |= ECMR_DM;
 	} else {
 		printf("Half\n");
-		sh_eth_write(port_info,
-			     val | (ECMR_CHG_DM | ECMR_RE | ECMR_TE),
-			     ECMR);
 	}
 
+	sh_eth_write(port_info, val, ECMR);
+
 	return ret;
 }
 
@@ -460,7 +455,9 @@ static void sh_eth_stop(struct sh_eth_in
 	sh_eth_write(port_info, ~EDRRR_R, EDRRR);
 }
 
-static int sh_eth_init_common(struct sh_eth_info *port_info, unsigned char *mac)
+static int sh_eth_init_common(struct sh_eth_info *port_info,
+			      unsigned char *mac,
+			      int node)
 {
 	int ret = 0;
 
@@ -472,7 +469,7 @@ static int sh_eth_init_common(struct sh_
 	if (ret)
 		return ret;
 
-	sh_eth_mac_regs_config(port_info, mac);
+	sh_eth_mac_regs_config(port_info, mac, node);
 
 	return 0;
 }
@@ -584,7 +581,8 @@ static int sh_ether_start(struct udevice
 	struct sh_eth_info *port_info = &priv->port_info;
 	int ret;
 
-	ret = sh_eth_init_common(port_info, pdata->enetaddr);
+	ret = sh_eth_init_common(port_info, pdata->enetaddr,
+				 dev_of_offset(dev));
 	if (ret)
 		return ret;
 
@@ -729,7 +727,7 @@ static int sh_ether_probe(struct udevice
 #ifdef BASE_IO_ADDR
 	port_info->iobase = (void __iomem *)(uintptr_t)BASE_IO_ADDR;
 #else
-	port_info->iobase = (void __iomem *)pdata->iobase;
+	port_info->iobase = (void __iomem *)pdata->iobase; /* from DT */
 #endif
 
 #if CONFIG_IS_ENABLED(CLK)
@@ -738,7 +736,8 @@ static int sh_ether_probe(struct udevice
 		goto err_mdio_register;
 #endif
 
-	ret = sh_eth_init_common(port_info, pdata->enetaddr);
+	ret = sh_eth_init_common(port_info, pdata->enetaddr,
+				 dev_of_offset(udev));
 	if (ret)
 		goto err_phy_config;
 
--- 0004/drivers/net/sh_eth.h
+++ work/drivers/net/sh_eth.h	2025-07-11 20:46:28.154019272 +0900
@@ -213,7 +213,7 @@ static const u16 sh_eth_offset_gigabit[S
 };
 
 static const u16 sh_eth_offset_rz[SH_ETH_MAX_REGISTER_OFFSET] = {
-	[EDSR]	= 0x0000,
+	[EDSR]	= 0x0000, /* EDSR0 @ 0xE8203000 */
 	[EDMR]	= 0x0400,
 	[EDTRR]	= 0x0408,
 	[EDRRR]	= 0x0410,
@@ -236,34 +236,37 @@ static const u16 sh_eth_offset_rz[SH_ETH
 	[FCFTR]	= 0x0468,
 	[CSMR] = 0x04E4,
 
-	[ECMR]	= 0x0500,
+	[ECMR]	= 0x0500, /* ECMR0 @ 0xE8203500 */
 	[ECSR]	= 0x0510,
 	[ECSIPR]	= 0x0518,
 	[PIR]	= 0x0520,
-	[PSR]	= 0x0528,
-	[PIPR]	= 0x052c,
-	[RFLR]	= 0x0508,
-	[APR]	= 0x0554,
-	[MPR]	= 0x0558,
-	[PFTCR]	= 0x055c,
-	[PFRCR]	= 0x0560,
-	[TPAUSER]	= 0x0564,
-	[GECMR]	= 0x05b0,
-	[BCULR]	= 0x05b4,
 	[MAHR]	= 0x05c0,
 	[MALR]	= 0x05c8,
-	[TROCR]	= 0x0700,
-	[CDCR]	= 0x0708,
-	[LCCR]	= 0x0710,
+	[RFLR]	= 0x0508,
 	[CEFCR]	= 0x0740,
 	[FRECR]	= 0x0748,
 	[TSFRCR]	= 0x0750,
 	[TLFRCR]	= 0x0758,
 	[RFCR]	= 0x0760,
-	[CERCR]	= 0x0768,
-	[CEECR]	= 0x0770,
 	[MAFCR]	= 0x0778,
-	[RMII_MII] =  0x0790,
+	[APR]	= 0x0554,
+	[MPR]	= 0x0558,
+	[TPAUSER]	= 0x0564,
+	[PFTCR]	= 0x055c,
+	[PFRCR]	= 0x0560,
+
+	// according to RZ/A1H Group, RZ/A1M Group Users Manual: Hardware
+	// Rev.6.00 Jan 2021, the following registers do not exist
+	//[PSR]	= 0x0528,
+	//[PIPR]	= 0x052c,
+	//[GECMR]	= 0x05b0,
+	//[BCULR]	= 0x05b4,
+	//[TROCR]	= 0x0700,
+	//[CDCR]	= 0x0708,
+	//[LCCR]	= 0x0710,
+	//[CERCR]	= 0x0768,
+	//[CEECR]	= 0x0770,
+	//[RMII_MII] =  0x0790,
 };
 
 static const u16 sh_eth_offset_fast_sh4[SH_ETH_MAX_REGISTER_OFFSET] = {
@@ -340,9 +343,9 @@ static const u16 sh_eth_offset_fast_sh4[
 #define SH_ETH_TYPE_ETHER
 #define BASE_IO_ADDR	0xEE700200
 #elif defined(CONFIG_RZA1)
-#define SH_ETH_TYPE_RZ
+#define SH_ETH_TYPE_GETHER
 #elif defined(CONFIG_RZA2)
-#define SH_ETH_TYPE_RZ
+#define SH_ETH_TYPE_GETHER
 #elif defined(CONFIG_R8A77980)
 #define SH_ETH_TYPE_GETHER
 #define BASE_IO_ADDR	0xE7400000
@@ -352,7 +355,7 @@ static const u16 sh_eth_offset_fast_sh4[
  * Register's bits
  * Copy from Linux driver source code
  */
-#if defined(SH_ETH_TYPE_GETHER) || defined(CONFIG_RZA1)
+#if defined(SH_ETH_TYPE_GETHER)
 /* EDSR */
 enum EDSR_BIT {
 	EDSR_ENT = 0x01, EDSR_ENR = 0x02,
@@ -364,12 +367,12 @@ enum EDSR_BIT {
 enum DMAC_M_BIT {
 	EDMR_NBST	= 0x80, /* DMA transfer burst mode */
 	EDMR_DL1 = 0x20, EDMR_DL0 = 0x10,
-#if defined(SH_ETH_TYPE_GETHER) || defined(CONFIG_RZA1)
-	EDMR_SRST	= 0x03, /* Receive/Send reset */
+#if defined(SH_ETH_TYPE_ETHER) || defined(CONFIG_RZA2)
+	EDMR_SRST	= 0x01,
 	EMDR_DESC_R	= 0x30, /* Descriptor reserve size */
 	EDMR_EL		= 0x40, /* Litte endian */
-#elif defined(SH_ETH_TYPE_ETHER) || defined(CONFIG_RZA2)
-	EDMR_SRST	= 0x01,
+#elif defined(SH_ETH_TYPE_GETHER)
+	EDMR_SRST	= 0x03, /* Receive/Send reset */
 	EMDR_DESC_R	= 0x30, /* Descriptor reserve size */
 	EDMR_EL		= 0x40, /* Litte endian */
 #else
@@ -390,7 +393,7 @@ enum DMAC_M_BIT {
 
 /* EDTRR */
 enum DMAC_T_BIT {
-#if defined(SH_ETH_TYPE_GETHER) || defined(CONFIG_RZA1)
+#if defined(SH_ETH_TYPE_GETHER)
 	EDTRR_TRNS = 0x03,
 #else
 	EDTRR_TRNS = 0x01,
@@ -463,7 +466,7 @@ enum EESR_BIT {
 	EESR_PRE  = 0x00000002, EESR_CERF = 0x00000001,
 };
 
-#if defined(SH_ETH_TYPE_GETHER) || defined(SH_ETH_TYPE_RZ)
+#if defined(SH_ETH_TYPE_GETHER)
 # define TX_CHECK (EESR_TC1 | EESR_FTC)
 # define EESR_ERR_CHECK	(EESR_TWB | EESR_TABT | EESR_RABT | EESR_RDE \
 		| EESR_RFRMER | EESR_TFE | EESR_TDE | EESR_ECI)
@@ -523,8 +526,7 @@ enum FCFTR_BIT {
 
 /* Transfer descriptor bit */
 enum TD_STS_BIT {
-#if defined(SH_ETH_TYPE_GETHER) || defined(SH_ETH_TYPE_ETHER) || \
-	defined(SH_ETH_TYPE_RZ)
+#if defined(SH_ETH_TYPE_GETHER) || defined(SH_ETH_TYPE_ETHER)
 	TD_TACT = 0x80000000,
 #else
 	TD_TACT = 0x7fffffff,
@@ -540,7 +542,7 @@ enum TD_STS_BIT {
 enum RECV_RST_BIT { RMCR_RST = 0x01, };
 /* ECMR */
 enum FELIC_MODE_BIT {
-#if defined(SH_ETH_TYPE_GETHER) || defined(CONFIG_RZA1)
+#if defined(SH_ETH_TYPE_GETHER)
 	ECMR_TRCCM = 0x04000000, ECMR_RCSC = 0x00800000,
 	ECMR_DPAD = 0x00200000, ECMR_RZPF = 0x00100000,
 #endif
@@ -551,17 +553,17 @@ enum FELIC_MODE_BIT {
 	ECMR_PRM = 0x00000001,
 #ifdef CONFIG_CPU_SH7724
 	ECMR_RTM = 0x00000010,
-#elif defined(CONFIG_RCAR_GEN2) || defined (CONFIG_R8A77980) || defined(CONFIG_RZA2)
+#else
 	ECMR_RTM = 0x00000004,
 #endif
 
 };
 
-#if defined(SH_ETH_TYPE_GETHER) || defined(CONFIG_RZA1)
+#if defined(SH_ETH_TYPE_ETHER) || defined(CONFIG_RZA2)
+#define ECMR_CHG_DM (ECMR_ZPF | ECMR_PFR | ECMR_RXF | ECMR_TXF)
+#elif defined(SH_ETH_TYPE_GETHER)
 #define ECMR_CHG_DM (ECMR_TRCCM | ECMR_RZPF | ECMR_ZPF | ECMR_PFR | \
 			ECMR_RXF | ECMR_TXF | ECMR_MCT)
-#elif defined(SH_ETH_TYPE_ETHER) || defined(CONFIG_RZA2)
-#define ECMR_CHG_DM (ECMR_ZPF | ECMR_PFR | ECMR_RXF | ECMR_TXF)
 #else
 #define ECMR_CHG_DM	(ECMR_ZPF | ECMR_PFR | ECMR_RXF | ECMR_TXF | ECMR_MCT)
 #endif
@@ -575,7 +577,7 @@ enum ECSR_STATUS_BIT {
 	ECSR_MPD = 0x02, ECSR_ICD = 0x01,
 };
 
-#if defined(SH_ETH_TYPE_GETHER) || defined(SH_ETH_TYPE_RZ)
+#if defined(SH_ETH_TYPE_GETHER)
 # define ECSR_INIT (ECSR_ICD | ECSIPR_MPDIP)
 #else
 # define ECSR_INIT (ECSR_BRCRX | ECSR_PSRTO | \
@@ -596,7 +598,7 @@ enum ECSIPR_STATUS_MASK_BIT {
 	ECSIPR_ICDIP = 0x01,
 };
 
-#if defined(SH_ETH_TYPE_GETHER) || defined(SH_ETH_TYPE_RZ)
+#if defined(SH_ETH_TYPE_GETHER)
 # define ECSIPR_INIT (ECSIPR_LCHNGIP | ECSIPR_ICDIP | ECSIPR_MPDIP)
 #else
 # define ECSIPR_INIT (ECSIPR_BRCRXIP | ECSIPR_PSRTOIP | ECSIPR_LCHNGIP | \
@@ -627,7 +629,7 @@ enum RPADIR_BIT {
 	RPADIR_PADR = 0x0003f,
 };
 
-#if defined(SH_ETH_TYPE_GETHER) || defined(SH_ETH_TYPE_RZ)
+#if defined(SH_ETH_TYPE_GETHER)
 # define RPADIR_INIT (0x00)
 #else
 # define RPADIR_INIT (RPADIR_PADS1)
@@ -638,19 +640,39 @@ enum FIFO_SIZE_BIT {
 	FIFO_SIZE_T = 0x00000700, FIFO_SIZE_R = 0x00000007,
 };
 
-static inline unsigned long sh_eth_reg_addr(struct sh_eth_info *port,
+static inline unsigned long sh_eth_reg_offs(struct sh_eth_info *port,
 					    int enum_index)
 {
-#if defined(SH_ETH_TYPE_GETHER)
-	const u16 *reg_offset = sh_eth_offset_gigabit;
+	/* order is important here, RZA1/RZA2 are also TYPE_GETHER */
+#if defined(CONFIG_RZA1)
+	const u16 *reg_offset = sh_eth_offset_rz;
 #elif defined(SH_ETH_TYPE_ETHER) || defined(CONFIG_RZA2)
 	const u16 *reg_offset = sh_eth_offset_fast_sh4;
-#elif defined(CONFIG_RZA1)
-	const u16 *reg_offset = sh_eth_offset_rz;
+#elif defined(SH_ETH_TYPE_GETHER)
+	const u16 *reg_offset = sh_eth_offset_gigabit;
 #else
 #error
 #endif
-	return (unsigned long)port->iobase + reg_offset[enum_index];
+	return reg_offset[enum_index];
+}
+
+static inline unsigned long sh_eth_reg_addr(struct sh_eth_info *port, int idx)
+{
+	return (unsigned long)port->iobase + sh_eth_reg_offs(port, idx);
+}
+
+static inline int sh_eth_reg_present(struct sh_eth_info *port, int idx)
+{
+	return !!sh_eth_reg_offs(port, idx);
+}
+
+static inline int sh_eth_is_gether(struct sh_eth_info *port)
+{
+#if defined(SH_ETH_TYPE_GETHER)
+	return 1;
+#else
+	return 0;
+#endif
 }
 
 static inline void sh_eth_write(struct sh_eth_info *port, unsigned long data,
@@ -659,6 +681,13 @@ static inline void sh_eth_write(struct s
 	outl(data, sh_eth_reg_addr(port, enum_index));
 }
 
+static inline void sh_eth_write_if_present(struct sh_eth_info *port,
+					   unsigned long data, int enum_index)
+{
+	if (sh_eth_reg_present(port, enum_index))
+		outl(data, sh_eth_reg_addr(port, enum_index));
+}
+
 static inline unsigned long sh_eth_read(struct sh_eth_info *port,
 					int enum_index)
 {


More information about the U-Boot mailing list