Skip to content

Commit

Permalink
net: sh_eth: add support R8A7740
Browse files Browse the repository at this point in the history
The R8A7740 has a Gigabit Ethernet MAC. This patch supports it.

Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
Tested-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Yoshihiro Shimoda authored and David S. Miller committed Apr 5, 2012
1 parent 8b1467a commit 73a0d90
Show file tree
Hide file tree
Showing 3 changed files with 120 additions and 6 deletions.
7 changes: 4 additions & 3 deletions drivers/net/ethernet/renesas/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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.
114 changes: 113 additions & 1 deletion drivers/net/ethernet/renesas/sh_eth.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 = {
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;

Expand Down
5 changes: 3 additions & 2 deletions drivers/net/ethernet/renesas/sh_eth.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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,
Expand Down

0 comments on commit 73a0d90

Please sign in to comment.