Commit 73a0d907 authored by Yoshihiro Shimoda's avatar Yoshihiro Shimoda Committed by David S. Miller

net: sh_eth: add support R8A7740

The R8A7740 has a Gigabit Ethernet MAC. This patch supports it.
Signed-off-by: default avatarYoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
Tested-by: default avatarKuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 8b1467a3
......@@ -4,11 +4,11 @@
config SH_ETH
tristate "Renesas SuperH Ethernet support"
depends on SUPERH && \
depends on (SUPERH || ARCH_SHMOBILE) && \
(CPU_SUBTYPE_SH7710 || CPU_SUBTYPE_SH7712 || \
CPU_SUBTYPE_SH7763 || CPU_SUBTYPE_SH7619 || \
CPU_SUBTYPE_SH7724 || CPU_SUBTYPE_SH7734 || \
CPU_SUBTYPE_SH7757)
CPU_SUBTYPE_SH7757 || ARCH_R8A7740)
select CRC32
select NET_CORE
select MII
......@@ -17,4 +17,5 @@ config SH_ETH
---help---
Renesas SuperH Ethernet device driver.
This driver supporting CPUs are:
- SH7619, SH7710, SH7712, SH7724, SH7734, SH7763 and SH7757.
- SH7619, SH7710, SH7712, SH7724, SH7734, SH7763, SH7757,
and R8A7740.
......@@ -386,6 +386,114 @@ static void sh_eth_reset_hw_crc(struct net_device *ndev)
sh_eth_write(ndev, 0x0, CSMR);
}
#elif defined(CONFIG_ARCH_R8A7740)
#define SH_ETH_HAS_TSU 1
static void sh_eth_chip_reset(struct net_device *ndev)
{
struct sh_eth_private *mdp = netdev_priv(ndev);
unsigned long mii;
/* reset device */
sh_eth_tsu_write(mdp, ARSTR_ARSTR, ARSTR);
mdelay(1);
switch (mdp->phy_interface) {
case PHY_INTERFACE_MODE_GMII:
mii = 2;
break;
case PHY_INTERFACE_MODE_MII:
mii = 1;
break;
case PHY_INTERFACE_MODE_RMII:
default:
mii = 0;
break;
}
sh_eth_write(ndev, mii, RMII_MII);
}
static void sh_eth_reset(struct net_device *ndev)
{
int cnt = 100;
sh_eth_write(ndev, EDSR_ENALL, EDSR);
sh_eth_write(ndev, sh_eth_read(ndev, EDMR) | EDMR_SRST_GETHER, EDMR);
while (cnt > 0) {
if (!(sh_eth_read(ndev, EDMR) & 0x3))
break;
mdelay(1);
cnt--;
}
if (cnt == 0)
printk(KERN_ERR "Device reset fail\n");
/* Table Init */
sh_eth_write(ndev, 0x0, TDLAR);
sh_eth_write(ndev, 0x0, TDFAR);
sh_eth_write(ndev, 0x0, TDFXR);
sh_eth_write(ndev, 0x0, TDFFR);
sh_eth_write(ndev, 0x0, RDLAR);
sh_eth_write(ndev, 0x0, RDFAR);
sh_eth_write(ndev, 0x0, RDFXR);
sh_eth_write(ndev, 0x0, RDFFR);
}
static void sh_eth_set_duplex(struct net_device *ndev)
{
struct sh_eth_private *mdp = netdev_priv(ndev);
if (mdp->duplex) /* Full */
sh_eth_write(ndev, sh_eth_read(ndev, ECMR) | ECMR_DM, ECMR);
else /* Half */
sh_eth_write(ndev, sh_eth_read(ndev, ECMR) & ~ECMR_DM, ECMR);
}
static void sh_eth_set_rate(struct net_device *ndev)
{
struct sh_eth_private *mdp = netdev_priv(ndev);
switch (mdp->speed) {
case 10: /* 10BASE */
sh_eth_write(ndev, GECMR_10, GECMR);
break;
case 100:/* 100BASE */
sh_eth_write(ndev, GECMR_100, GECMR);
break;
case 1000: /* 1000BASE */
sh_eth_write(ndev, GECMR_1000, GECMR);
break;
default:
break;
}
}
/* R8A7740 */
static struct sh_eth_cpu_data sh_eth_my_cpu_data = {
.chip_reset = sh_eth_chip_reset,
.set_duplex = sh_eth_set_duplex,
.set_rate = sh_eth_set_rate,
.ecsr_value = ECSR_ICD | ECSR_MPD,
.ecsipr_value = ECSIPR_LCHNGIP | ECSIPR_ICDIP | ECSIPR_MPDIP,
.eesipr_value = DMAC_M_RFRMER | DMAC_M_ECI | 0x003fffff,
.tx_check = EESR_TC1 | EESR_FTC,
.eesr_err_check = EESR_TWB1 | EESR_TWB | EESR_TABT | EESR_RABT | \
EESR_RDE | EESR_RFRMER | EESR_TFE | EESR_TDE | \
EESR_ECI,
.tx_error_check = EESR_TWB1 | EESR_TWB | EESR_TABT | EESR_TDE | \
EESR_TFE,
.apr = 1,
.mpr = 1,
.tpauser = 1,
.bculr = 1,
.hw_swap = 1,
.no_trimd = 1,
.no_ade = 1,
.tsu = 1,
};
#elif defined(CONFIG_CPU_SUBTYPE_SH7619)
#define SH_ETH_RESET_DEFAULT 1
static struct sh_eth_cpu_data sh_eth_my_cpu_data = {
......@@ -443,7 +551,7 @@ static void sh_eth_reset(struct net_device *ndev)
}
#endif
#if defined(CONFIG_CPU_SH4)
#if defined(CONFIG_CPU_SH4) || defined(CONFIG_ARCH_SHMOBILE)
static void sh_eth_set_receive_align(struct sk_buff *skb)
{
int reserve;
......@@ -919,6 +1027,10 @@ static int sh_eth_rx(struct net_device *ndev)
desc_status = edmac_to_cpu(mdp, rxdesc->status);
pkt_len = rxdesc->frame_length;
#if defined(CONFIG_ARCH_R8A7740)
desc_status >>= 16;
#endif
if (--boguscnt < 0)
break;
......
......@@ -372,7 +372,7 @@ static const u16 sh_eth_offset_fast_sh3_sh2[SH_ETH_MAX_REGISTER_OFFSET] = {
};
/* Driver's parameters */
#if defined(CONFIG_CPU_SH4)
#if defined(CONFIG_CPU_SH4) || defined(CONFIG_ARCH_SHMOBILE)
#define SH4_SKB_RX_ALIGN 32
#else
#define SH2_SH3_SKB_RX_ALIGN 2
......@@ -381,7 +381,8 @@ static const u16 sh_eth_offset_fast_sh3_sh2[SH_ETH_MAX_REGISTER_OFFSET] = {
/*
* Register's bits
*/
#if defined(CONFIG_CPU_SUBTYPE_SH7734) || defined(CONFIG_CPU_SUBTYPE_SH7763)
#if defined(CONFIG_CPU_SUBTYPE_SH7734) || defined(CONFIG_CPU_SUBTYPE_SH7763) ||\
defined(CONFIG_ARCH_R8A7740)
/* EDSR */
enum EDSR_BIT {
EDSR_ENT = 0x01, EDSR_ENR = 0x02,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment