Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit db893473 authored by Simon Horman's avatar Simon Horman Committed by David S. Miller
Browse files

sh_eth: Add support for r7s72100



The r7s72100 SoC includes a fast ethernet controller.

Signed-off-by: default avatarSimon Horman <horms+renesas@verge.net.au>
Acked-by: default avatarSergei Shtylyov <sergei.shtylyov@cogentembedded.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 504c8ca5
Loading
Loading
Loading
Loading
+117 −7
Original line number Diff line number Diff line
@@ -143,6 +143,65 @@ static const u16 sh_eth_offset_gigabit[SH_ETH_MAX_REGISTER_OFFSET] = {
	[FWALCR1]	= 0x00b4,
};

static const u16 sh_eth_offset_fast_rz[SH_ETH_MAX_REGISTER_OFFSET] = {
	[EDSR]		= 0x0000,
	[EDMR]		= 0x0400,
	[EDTRR]		= 0x0408,
	[EDRRR]		= 0x0410,
	[EESR]		= 0x0428,
	[EESIPR]	= 0x0430,
	[TDLAR]		= 0x0010,
	[TDFAR]		= 0x0014,
	[TDFXR]		= 0x0018,
	[TDFFR]		= 0x001c,
	[RDLAR]		= 0x0030,
	[RDFAR]		= 0x0034,
	[RDFXR]		= 0x0038,
	[RDFFR]		= 0x003c,
	[TRSCER]	= 0x0438,
	[RMFCR]		= 0x0440,
	[TFTR]		= 0x0448,
	[FDR]		= 0x0450,
	[RMCR]		= 0x0458,
	[RPADIR]	= 0x0460,
	[FCFTR]		= 0x0468,
	[CSMR]		= 0x04E4,

	[ECMR]		= 0x0500,
	[RFLR]		= 0x0508,
	[ECSR]		= 0x0510,
	[ECSIPR]	= 0x0518,
	[PIR]		= 0x0520,
	[APR]		= 0x0554,
	[MPR]		= 0x0558,
	[PFTCR]		= 0x055c,
	[PFRCR]		= 0x0560,
	[TPAUSER]	= 0x0564,
	[MAHR]		= 0x05c0,
	[MALR]		= 0x05c8,
	[CEFCR]		= 0x0740,
	[FRECR]		= 0x0748,
	[TSFRCR]	= 0x0750,
	[TLFRCR]	= 0x0758,
	[RFCR]		= 0x0760,
	[MAFCR]		= 0x0778,

	[ARSTR]		= 0x0000,
	[TSU_CTRST]	= 0x0004,
	[TSU_VTAG0]	= 0x0058,
	[TSU_ADSBSY]	= 0x0060,
	[TSU_TEN]	= 0x0064,
	[TSU_ADRH0]	= 0x0100,
	[TSU_ADRL0]	= 0x0104,
	[TSU_ADRH31]	= 0x01f8,
	[TSU_ADRL31]	= 0x01fc,

	[TXNLCR0]	= 0x0080,
	[TXALCR0]	= 0x0084,
	[RXNLCR0]	= 0x0088,
	[RXALCR0]	= 0x008C,
};

static const u16 sh_eth_offset_fast_rcar[SH_ETH_MAX_REGISTER_OFFSET] = {
	[ECMR]		= 0x0300,
	[RFLR]		= 0x0308,
@@ -314,6 +373,11 @@ static bool sh_eth_is_gether(struct sh_eth_private *mdp)
	return mdp->reg_offset == sh_eth_offset_gigabit;
}

static bool sh_eth_is_rz_fast_ether(struct sh_eth_private *mdp)
{
	return mdp->reg_offset == sh_eth_offset_fast_rz;
}

static void sh_eth_select_mii(struct net_device *ndev)
{
	u32 value = 0x0;
@@ -697,6 +761,38 @@ static struct sh_eth_cpu_data r8a7740_data = {
	.shift_rd0	= 1,
};

/* R7S72100 */
static struct sh_eth_cpu_data r7s72100_data = {
	.chip_reset	= sh_eth_chip_reset,
	.set_duplex	= sh_eth_set_duplex,

	.register_type	= SH_ETH_REG_FAST_RZ,

	.ecsr_value	= ECSR_ICD,
	.ecsipr_value	= ECSIPR_ICDIP,
	.eesipr_value	= 0xff7f009f,

	.tx_check	= EESR_TC1 | EESR_FTC,
	.eesr_err_check	= EESR_TWB1 | EESR_TWB | EESR_TABT | EESR_RABT |
			  EESR_RFE | EESR_RDE | EESR_RFRMER | EESR_TFE |
			  EESR_TDE | EESR_ECI,
	.fdr_value	= 0x0000070f,
	.rmcr_value	= RMCR_RNC,

	.no_psr		= 1,
	.apr		= 1,
	.mpr		= 1,
	.tpauser	= 1,
	.hw_swap	= 1,
	.rpadir		= 1,
	.rpadir_value   = 2 << 16,
	.no_trimd	= 1,
	.no_ade		= 1,
	.hw_crc		= 1,
	.tsu		= 1,
	.shift_rd0	= 1,
};

static struct sh_eth_cpu_data sh7619_data = {
	.register_type	= SH_ETH_REG_FAST_SH3_SH2,

@@ -763,7 +859,7 @@ static int sh_eth_reset(struct net_device *ndev)
	struct sh_eth_private *mdp = netdev_priv(ndev);
	int ret = 0;

	if (sh_eth_is_gether(mdp)) {
	if (sh_eth_is_gether(mdp) || sh_eth_is_rz_fast_ether(mdp)) {
		sh_eth_write(ndev, EDSR_ENALL, EDSR);
		sh_eth_write(ndev, sh_eth_read(ndev, EDMR) | EDMR_SRST_GETHER,
			     EDMR);
@@ -874,7 +970,7 @@ static void read_mac_address(struct net_device *ndev, unsigned char *mac)

static unsigned long sh_eth_get_edtrr_trns(struct sh_eth_private *mdp)
{
	if (sh_eth_is_gether(mdp))
	if (sh_eth_is_gether(mdp) || sh_eth_is_rz_fast_ether(mdp))
		return EDTRR_TRNS_GETHER;
	else
		return EDTRR_TRNS_ETHER;
@@ -1037,7 +1133,8 @@ static void sh_eth_ring_format(struct net_device *ndev)
		/* Rx descriptor address set */
		if (i == 0) {
			sh_eth_write(ndev, mdp->rx_desc_dma, RDLAR);
			if (sh_eth_is_gether(mdp))
			if (sh_eth_is_gether(mdp) ||
			    sh_eth_is_rz_fast_ether(mdp))
				sh_eth_write(ndev, mdp->rx_desc_dma, RDFAR);
		}
	}
@@ -1058,7 +1155,8 @@ static void sh_eth_ring_format(struct net_device *ndev)
		if (i == 0) {
			/* Tx descriptor address set */
			sh_eth_write(ndev, mdp->tx_desc_dma, TDLAR);
			if (sh_eth_is_gether(mdp))
			if (sh_eth_is_gether(mdp) ||
			    sh_eth_is_rz_fast_ether(mdp))
				sh_eth_write(ndev, mdp->tx_desc_dma, TDFAR);
		}
	}
@@ -1305,9 +1403,9 @@ static int sh_eth_rx(struct net_device *ndev, u32 intr_status, int *quota)

		/* In case of almost all GETHER/ETHERs, the Receive Frame State
		 * (RFS) bits in the Receive Descriptor 0 are from bit 9 to
		 * bit 0. However, in case of the R8A7740's GETHER, the RFS
		 * bits are from bit 25 to bit 16. So, the driver needs right
		 * shifting by 16.
		 * bit 0. However, in case of the R8A7740, R8A779x, and
		 * R7S72100 the RFS bits are from bit 25 to bit 16. So, the
		 * driver needs right shifting by 16.
		 */
		if (mdp->cd->shift_rd0)
			desc_status >>= 16;
@@ -2057,6 +2155,9 @@ static struct net_device_stats *sh_eth_get_stats(struct net_device *ndev)
{
	struct sh_eth_private *mdp = netdev_priv(ndev);

	if (sh_eth_is_rz_fast_ether(mdp))
		return &ndev->stats;

	pm_runtime_get_sync(&mdp->pdev->dev);

	ndev->stats.tx_dropped += sh_eth_read(ndev, TROCR);
@@ -2438,6 +2539,11 @@ static int sh_eth_vlan_rx_kill_vid(struct net_device *ndev,
/* SuperH's TSU register init function */
static void sh_eth_tsu_init(struct sh_eth_private *mdp)
{
	if (sh_eth_is_rz_fast_ether(mdp)) {
		sh_eth_tsu_write(mdp, 0, TSU_TEN); /* Disable all CAM entry */
		return;
	}

	sh_eth_tsu_write(mdp, 0, TSU_FWEN0);	/* Disable forward(0->1) */
	sh_eth_tsu_write(mdp, 0, TSU_FWEN1);	/* Disable forward(1->0) */
	sh_eth_tsu_write(mdp, 0, TSU_FCM);	/* forward fifo 3k-3k */
@@ -2557,6 +2663,9 @@ static const u16 *sh_eth_get_register_offset(int register_type)
	case SH_ETH_REG_GIGABIT:
		reg_offset = sh_eth_offset_gigabit;
		break;
	case SH_ETH_REG_FAST_RZ:
		reg_offset = sh_eth_offset_fast_rz;
		break;
	case SH_ETH_REG_FAST_RCAR:
		reg_offset = sh_eth_offset_fast_rcar;
		break;
@@ -2795,6 +2904,7 @@ static struct platform_device_id sh_eth_id_table[] = {
	{ "sh7757-ether", (kernel_ulong_t)&sh7757_data },
	{ "sh7757-gether", (kernel_ulong_t)&sh7757_data_giga },
	{ "sh7763-gether", (kernel_ulong_t)&sh7763_data },
	{ "r7s72100-ether", (kernel_ulong_t)&r7s72100_data },
	{ "r8a7740-gether", (kernel_ulong_t)&r8a7740_data },
	{ "r8a777x-ether", (kernel_ulong_t)&r8a777x_data },
	{ "r8a7790-ether", (kernel_ulong_t)&r8a779x_data },
+2 −1
Original line number Diff line number Diff line
@@ -155,6 +155,7 @@ enum {

enum {
	SH_ETH_REG_GIGABIT,
	SH_ETH_REG_FAST_RZ,
	SH_ETH_REG_FAST_RCAR,
	SH_ETH_REG_FAST_SH4,
	SH_ETH_REG_FAST_SH3_SH2
@@ -169,7 +170,7 @@ enum {

/* Register's bits
 */
/* EDSR : sh7734, sh7757, sh7763, and r8a7740 only */
/* EDSR : sh7734, sh7757, sh7763, r8a7740, and r7s72100 only */
enum EDSR_BIT {
	EDSR_ENT = 0x01, EDSR_ENR = 0x02,
};