Commit 380af9e3 authored by Yoshihiro Shimoda's avatar Yoshihiro Shimoda Committed by David S. Miller

net: sh_eth: CPU dependency code collect to "struct sh_eth_cpu_data"

This improves readability by collecting CPU dependency code.
Signed-off-by: default avatarYoshihiro Shimoda <shimoda.yoshihiro@renesas.com>
Signed-off-by: default avatarNobuhiro Iwamatsu <iwamatsu.nobuhiro@renesas.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 862df497
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* SuperH Ethernet device driver * SuperH Ethernet device driver
* *
* Copyright (C) 2006-2008 Nobuhiro Iwamatsu * Copyright (C) 2006-2008 Nobuhiro Iwamatsu
* Copyright (C) 2008 Renesas Solutions Corp. * Copyright (C) 2008-2009 Renesas Solutions Corp.
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License, * under the terms and conditions of the GNU General Public License,
...@@ -33,6 +33,176 @@ ...@@ -33,6 +33,176 @@
#include "sh_eth.h" #include "sh_eth.h"
/* There is CPU dependent code */
#if defined(CONFIG_CPU_SUBTYPE_SH7763)
#define SH_ETH_HAS_TSU 1
static void sh_eth_chip_reset(struct net_device *ndev)
{
/* reset device */
ctrl_outl(ARSTR_ARSTR, ARSTR);
mdelay(1);
}
static void sh_eth_reset(struct net_device *ndev)
{
u32 ioaddr = ndev->base_addr;
int cnt = 100;
ctrl_outl(EDSR_ENALL, ioaddr + EDSR);
ctrl_outl(ctrl_inl(ioaddr + EDMR) | EDMR_SRST, ioaddr + EDMR);
while (cnt > 0) {
if (!(ctrl_inl(ioaddr + EDMR) & 0x3))
break;
mdelay(1);
cnt--;
}
if (cnt < 0)
printk(KERN_ERR "Device reset fail\n");
/* Table Init */
ctrl_outl(0x0, ioaddr + TDLAR);
ctrl_outl(0x0, ioaddr + TDFAR);
ctrl_outl(0x0, ioaddr + TDFXR);
ctrl_outl(0x0, ioaddr + TDFFR);
ctrl_outl(0x0, ioaddr + RDLAR);
ctrl_outl(0x0, ioaddr + RDFAR);
ctrl_outl(0x0, ioaddr + RDFXR);
ctrl_outl(0x0, ioaddr + RDFFR);
}
static void sh_eth_set_duplex(struct net_device *ndev)
{
struct sh_eth_private *mdp = netdev_priv(ndev);
u32 ioaddr = ndev->base_addr;
if (mdp->duplex) /* Full */
ctrl_outl(ctrl_inl(ioaddr + ECMR) | ECMR_DM, ioaddr + ECMR);
else /* Half */
ctrl_outl(ctrl_inl(ioaddr + ECMR) & ~ECMR_DM, ioaddr + ECMR);
}
static void sh_eth_set_rate(struct net_device *ndev)
{
struct sh_eth_private *mdp = netdev_priv(ndev);
u32 ioaddr = ndev->base_addr;
switch (mdp->speed) {
case 10: /* 10BASE */
ctrl_outl(GECMR_10, ioaddr + GECMR);
break;
case 100:/* 100BASE */
ctrl_outl(GECMR_100, ioaddr + GECMR);
break;
case 1000: /* 1000BASE */
ctrl_outl(GECMR_1000, ioaddr + GECMR);
break;
default:
break;
}
}
/* sh7763 */
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,
.rpadir = 1,
.no_trimd = 1,
.no_ade = 1,
};
#elif defined(CONFIG_CPU_SUBTYPE_SH7619)
#define SH_ETH_RESET_DEFAULT 1
static struct sh_eth_cpu_data sh_eth_my_cpu_data = {
.eesipr_value = DMAC_M_RFRMER | DMAC_M_ECI | 0x003fffff,
.apr = 1,
.mpr = 1,
.tpauser = 1,
.hw_swap = 1,
};
#elif defined(CONFIG_CPU_SUBTYPE_SH7710) || defined(CONFIG_CPU_SUBTYPE_SH7712)
#define SH_ETH_RESET_DEFAULT 1
#define SH_ETH_HAS_TSU 1
static struct sh_eth_cpu_data sh_eth_my_cpu_data = {
.eesipr_value = DMAC_M_RFRMER | DMAC_M_ECI | 0x003fffff,
};
#endif
static void sh_eth_set_default_cpu_data(struct sh_eth_cpu_data *cd)
{
if (!cd->ecsr_value)
cd->ecsr_value = DEFAULT_ECSR_INIT;
if (!cd->ecsipr_value)
cd->ecsipr_value = DEFAULT_ECSIPR_INIT;
if (!cd->fcftr_value)
cd->fcftr_value = DEFAULT_FIFO_F_D_RFF | \
DEFAULT_FIFO_F_D_RFD;
if (!cd->fdr_value)
cd->fdr_value = DEFAULT_FDR_INIT;
if (!cd->rmcr_value)
cd->rmcr_value = DEFAULT_RMCR_VALUE;
if (!cd->tx_check)
cd->tx_check = DEFAULT_TX_CHECK;
if (!cd->eesr_err_check)
cd->eesr_err_check = DEFAULT_EESR_ERR_CHECK;
if (!cd->tx_error_check)
cd->tx_error_check = DEFAULT_TX_ERROR_CHECK;
}
#if defined(SH_ETH_RESET_DEFAULT)
/* Chip Reset */
static void sh_eth_reset(struct net_device *ndev)
{
u32 ioaddr = ndev->base_addr;
ctrl_outl(ctrl_inl(ioaddr + EDMR) | EDMR_SRST, ioaddr + EDMR);
mdelay(3);
ctrl_outl(ctrl_inl(ioaddr + EDMR) & ~EDMR_SRST, ioaddr + EDMR);
}
#endif
#if defined(CONFIG_CPU_SH4)
static void sh_eth_set_receive_align(struct sk_buff *skb)
{
int reserve;
reserve = SH4_SKB_RX_ALIGN - ((u32)skb->data & (SH4_SKB_RX_ALIGN - 1));
if (reserve)
skb_reserve(skb, reserve);
}
#else
static void sh_eth_set_receive_align(struct sk_buff *skb)
{
skb_reserve(skb, SH2_SH3_SKB_RX_ALIGN);
}
#endif
/* CPU <-> EDMAC endian convert */ /* CPU <-> EDMAC endian convert */
static inline __u32 cpu_to_edmac(struct sh_eth_private *mdp, u32 x) static inline __u32 cpu_to_edmac(struct sh_eth_private *mdp, u32 x)
{ {
...@@ -165,41 +335,6 @@ static struct mdiobb_ops bb_ops = { ...@@ -165,41 +335,6 @@ static struct mdiobb_ops bb_ops = {
.get_mdio_data = sh_get_mdio, .get_mdio_data = sh_get_mdio,
}; };
/* Chip Reset */
static void sh_eth_reset(struct net_device *ndev)
{
u32 ioaddr = ndev->base_addr;
#if defined(CONFIG_CPU_SUBTYPE_SH7763)
int cnt = 100;
ctrl_outl(EDSR_ENALL, ioaddr + EDSR);
ctrl_outl(ctrl_inl(ioaddr + EDMR) | EDMR_SRST, ioaddr + EDMR);
while (cnt > 0) {
if (!(ctrl_inl(ioaddr + EDMR) & 0x3))
break;
mdelay(1);
cnt--;
}
if (cnt < 0)
printk(KERN_ERR "Device reset fail\n");
/* Table Init */
ctrl_outl(0x0, ioaddr + TDLAR);
ctrl_outl(0x0, ioaddr + TDFAR);
ctrl_outl(0x0, ioaddr + TDFXR);
ctrl_outl(0x0, ioaddr + TDFFR);
ctrl_outl(0x0, ioaddr + RDLAR);
ctrl_outl(0x0, ioaddr + RDFAR);
ctrl_outl(0x0, ioaddr + RDFXR);
ctrl_outl(0x0, ioaddr + RDFFR);
#else
ctrl_outl(ctrl_inl(ioaddr + EDMR) | EDMR_SRST, ioaddr + EDMR);
mdelay(3);
ctrl_outl(ctrl_inl(ioaddr + EDMR) & ~EDMR_SRST, ioaddr + EDMR);
#endif
}
/* free skb and descriptor buffer */ /* free skb and descriptor buffer */
static void sh_eth_ring_free(struct net_device *ndev) static void sh_eth_ring_free(struct net_device *ndev)
{ {
...@@ -228,7 +363,7 @@ static void sh_eth_ring_free(struct net_device *ndev) ...@@ -228,7 +363,7 @@ static void sh_eth_ring_free(struct net_device *ndev)
/* format skb and descriptor buffer */ /* format skb and descriptor buffer */
static void sh_eth_ring_format(struct net_device *ndev) static void sh_eth_ring_format(struct net_device *ndev)
{ {
u32 ioaddr = ndev->base_addr, reserve = 0; u32 ioaddr = ndev->base_addr;
struct sh_eth_private *mdp = netdev_priv(ndev); struct sh_eth_private *mdp = netdev_priv(ndev);
int i; int i;
struct sk_buff *skb; struct sk_buff *skb;
...@@ -253,14 +388,8 @@ static void sh_eth_ring_format(struct net_device *ndev) ...@@ -253,14 +388,8 @@ static void sh_eth_ring_format(struct net_device *ndev)
dma_map_single(&ndev->dev, skb->tail, mdp->rx_buf_sz, dma_map_single(&ndev->dev, skb->tail, mdp->rx_buf_sz,
DMA_FROM_DEVICE); DMA_FROM_DEVICE);
skb->dev = ndev; /* Mark as being used by this device. */ skb->dev = ndev; /* Mark as being used by this device. */
#if defined(CONFIG_CPU_SUBTYPE_SH7763) sh_eth_set_receive_align(skb);
reserve = SH7763_SKB_ALIGN
- ((uint32_t)skb->data & (SH7763_SKB_ALIGN-1));
if (reserve)
skb_reserve(skb, reserve);
#else
skb_reserve(skb, RX_OFFSET);
#endif
/* RX descriptor */ /* RX descriptor */
rxdesc = &mdp->rx_ring[i]; rxdesc = &mdp->rx_ring[i];
rxdesc->addr = virt_to_phys(PTR_ALIGN(skb->data, 4)); rxdesc->addr = virt_to_phys(PTR_ALIGN(skb->data, 4));
...@@ -321,7 +450,7 @@ static int sh_eth_ring_init(struct net_device *ndev) ...@@ -321,7 +450,7 @@ static int sh_eth_ring_init(struct net_device *ndev)
mdp->rx_skbuff = kmalloc(sizeof(*mdp->rx_skbuff) * RX_RING_SIZE, mdp->rx_skbuff = kmalloc(sizeof(*mdp->rx_skbuff) * RX_RING_SIZE,
GFP_KERNEL); GFP_KERNEL);
if (!mdp->rx_skbuff) { if (!mdp->rx_skbuff) {
printk(KERN_ERR "%s: Cannot allocate Rx skb\n", ndev->name); dev_err(&ndev->dev, "Cannot allocate Rx skb\n");
ret = -ENOMEM; ret = -ENOMEM;
return ret; return ret;
} }
...@@ -329,7 +458,7 @@ static int sh_eth_ring_init(struct net_device *ndev) ...@@ -329,7 +458,7 @@ static int sh_eth_ring_init(struct net_device *ndev)
mdp->tx_skbuff = kmalloc(sizeof(*mdp->tx_skbuff) * TX_RING_SIZE, mdp->tx_skbuff = kmalloc(sizeof(*mdp->tx_skbuff) * TX_RING_SIZE,
GFP_KERNEL); GFP_KERNEL);
if (!mdp->tx_skbuff) { if (!mdp->tx_skbuff) {
printk(KERN_ERR "%s: Cannot allocate Tx skb\n", ndev->name); dev_err(&ndev->dev, "Cannot allocate Tx skb\n");
ret = -ENOMEM; ret = -ENOMEM;
goto skb_ring_free; goto skb_ring_free;
} }
...@@ -340,8 +469,8 @@ static int sh_eth_ring_init(struct net_device *ndev) ...@@ -340,8 +469,8 @@ static int sh_eth_ring_init(struct net_device *ndev)
GFP_KERNEL); GFP_KERNEL);
if (!mdp->rx_ring) { if (!mdp->rx_ring) {
printk(KERN_ERR "%s: Cannot allocate Rx Ring (size %d bytes)\n", dev_err(&ndev->dev, "Cannot allocate Rx Ring (size %d bytes)\n",
ndev->name, rx_ringsize); rx_ringsize);
ret = -ENOMEM; ret = -ENOMEM;
goto desc_ring_free; goto desc_ring_free;
} }
...@@ -353,8 +482,8 @@ static int sh_eth_ring_init(struct net_device *ndev) ...@@ -353,8 +482,8 @@ static int sh_eth_ring_init(struct net_device *ndev)
mdp->tx_ring = dma_alloc_coherent(NULL, tx_ringsize, &mdp->tx_desc_dma, mdp->tx_ring = dma_alloc_coherent(NULL, tx_ringsize, &mdp->tx_desc_dma,
GFP_KERNEL); GFP_KERNEL);
if (!mdp->tx_ring) { if (!mdp->tx_ring) {
printk(KERN_ERR "%s: Cannot allocate Tx Ring (size %d bytes)\n", dev_err(&ndev->dev, "Cannot allocate Tx Ring (size %d bytes)\n",
ndev->name, tx_ringsize); tx_ringsize);
ret = -ENOMEM; ret = -ENOMEM;
goto desc_ring_free; goto desc_ring_free;
} }
...@@ -384,44 +513,43 @@ static int sh_eth_dev_init(struct net_device *ndev) ...@@ -384,44 +513,43 @@ static int sh_eth_dev_init(struct net_device *ndev)
/* Descriptor format */ /* Descriptor format */
sh_eth_ring_format(ndev); sh_eth_ring_format(ndev);
ctrl_outl(RPADIR_INIT, ioaddr + RPADIR); if (mdp->cd->rpadir)
ctrl_outl(mdp->cd->rpadir_value, ioaddr + RPADIR);
/* all sh_eth int mask */ /* all sh_eth int mask */
ctrl_outl(0, ioaddr + EESIPR); ctrl_outl(0, ioaddr + EESIPR);
#if defined(CONFIG_CPU_SUBTYPE_SH7763) #if defined(__LITTLE_ENDIAN__)
if (mdp->cd->hw_swap)
ctrl_outl(EDMR_EL, ioaddr + EDMR); ctrl_outl(EDMR_EL, ioaddr + EDMR);
#else else
ctrl_outl(0, ioaddr + EDMR); /* Endian change */
#endif #endif
ctrl_outl(0, ioaddr + EDMR);
/* FIFO size set */ /* FIFO size set */
ctrl_outl((FIFO_SIZE_T | FIFO_SIZE_R), ioaddr + FDR); ctrl_outl(mdp->cd->fdr_value, ioaddr + FDR);
ctrl_outl(0, ioaddr + TFTR); ctrl_outl(0, ioaddr + TFTR);
/* Frame recv control */ /* Frame recv control */
ctrl_outl(0, ioaddr + RMCR); ctrl_outl(mdp->cd->rmcr_value, ioaddr + RMCR);
rx_int_var = mdp->rx_int_var = DESC_I_RINT8 | DESC_I_RINT5; rx_int_var = mdp->rx_int_var = DESC_I_RINT8 | DESC_I_RINT5;
tx_int_var = mdp->tx_int_var = DESC_I_TINT2; tx_int_var = mdp->tx_int_var = DESC_I_TINT2;
ctrl_outl(rx_int_var | tx_int_var, ioaddr + TRSCER); ctrl_outl(rx_int_var | tx_int_var, ioaddr + TRSCER);
#if defined(CONFIG_CPU_SUBTYPE_SH7763) if (mdp->cd->bculr)
/* Burst sycle set */ ctrl_outl(0x800, ioaddr + BCULR); /* Burst sycle set */
ctrl_outl(0x800, ioaddr + BCULR);
#endif
ctrl_outl((FIFO_F_D_RFF | FIFO_F_D_RFD), ioaddr + FCFTR); ctrl_outl(mdp->cd->fcftr_value, ioaddr + FCFTR);
#if !defined(CONFIG_CPU_SUBTYPE_SH7763) if (!mdp->cd->no_trimd)
ctrl_outl(0, ioaddr + TRIMD); ctrl_outl(0, ioaddr + TRIMD);
#endif
/* Recv frame limit set register */ /* Recv frame limit set register */
ctrl_outl(RFLR_VALUE, ioaddr + RFLR); ctrl_outl(RFLR_VALUE, ioaddr + RFLR);
ctrl_outl(ctrl_inl(ioaddr + EESR), ioaddr + EESR); ctrl_outl(ctrl_inl(ioaddr + EESR), ioaddr + EESR);
ctrl_outl((DMAC_M_RFRMER | DMAC_M_ECI | 0x003fffff), ioaddr + EESIPR); ctrl_outl(mdp->cd->eesipr_value, ioaddr + EESIPR);
/* PAUSE Prohibition */ /* PAUSE Prohibition */
val = (ctrl_inl(ioaddr + ECMR) & ECMR_DM) | val = (ctrl_inl(ioaddr + ECMR) & ECMR_DM) |
...@@ -429,24 +557,25 @@ static int sh_eth_dev_init(struct net_device *ndev) ...@@ -429,24 +557,25 @@ static int sh_eth_dev_init(struct net_device *ndev)
ctrl_outl(val, ioaddr + ECMR); ctrl_outl(val, ioaddr + ECMR);
if (mdp->cd->set_rate)
mdp->cd->set_rate(ndev);
/* E-MAC Status Register clear */ /* E-MAC Status Register clear */
ctrl_outl(ECSR_INIT, ioaddr + ECSR); ctrl_outl(mdp->cd->ecsr_value, ioaddr + ECSR);
/* E-MAC Interrupt Enable register */ /* E-MAC Interrupt Enable register */
ctrl_outl(ECSIPR_INIT, ioaddr + ECSIPR); ctrl_outl(mdp->cd->ecsipr_value, ioaddr + ECSIPR);
/* Set MAC address */ /* Set MAC address */
update_mac_address(ndev); update_mac_address(ndev);
/* mask reset */ /* mask reset */
#if defined(CONFIG_CPU_SUBTYPE_SH7710) || defined(CONFIG_CPU_SUBTYPE_SH7763) if (mdp->cd->apr)
ctrl_outl(APR_AP, ioaddr + APR); ctrl_outl(APR_AP, ioaddr + APR);
if (mdp->cd->mpr)
ctrl_outl(MPR_MP, ioaddr + MPR); ctrl_outl(MPR_MP, ioaddr + MPR);
if (mdp->cd->tpauser)
ctrl_outl(TPAUSER_UNLIMITED, ioaddr + TPAUSER); ctrl_outl(TPAUSER_UNLIMITED, ioaddr + TPAUSER);
#endif
#if defined(CONFIG_CPU_SUBTYPE_SH7710)
ctrl_outl(BCFR_UNLIMITED, ioaddr + BCFR);
#endif
/* Setting the Rx mode will start the Rx process. */ /* Setting the Rx mode will start the Rx process. */
ctrl_outl(EDRRR_R, ioaddr + EDRRR); ctrl_outl(EDRRR_R, ioaddr + EDRRR);
...@@ -495,7 +624,7 @@ static int sh_eth_rx(struct net_device *ndev) ...@@ -495,7 +624,7 @@ static int sh_eth_rx(struct net_device *ndev)
int boguscnt = (mdp->dirty_rx + RX_RING_SIZE) - mdp->cur_rx; int boguscnt = (mdp->dirty_rx + RX_RING_SIZE) - mdp->cur_rx;
struct sk_buff *skb; struct sk_buff *skb;
u16 pkt_len = 0; u16 pkt_len = 0;
u32 desc_status, reserve = 0; u32 desc_status;
rxdesc = &mdp->rx_ring[entry]; rxdesc = &mdp->rx_ring[entry];
while (!(rxdesc->status & cpu_to_edmac(mdp, RD_RACT))) { while (!(rxdesc->status & cpu_to_edmac(mdp, RD_RACT))) {
...@@ -524,7 +653,9 @@ static int sh_eth_rx(struct net_device *ndev) ...@@ -524,7 +653,9 @@ static int sh_eth_rx(struct net_device *ndev)
if (desc_status & RD_RFS10) if (desc_status & RD_RFS10)
mdp->stats.rx_over_errors++; mdp->stats.rx_over_errors++;
} else { } else {
swaps(phys_to_virt(ALIGN(rxdesc->addr, 4)), if (!mdp->cd->hw_swap)
sh_eth_soft_swap(
phys_to_virt(ALIGN(rxdesc->addr, 4)),
pkt_len + 2); pkt_len + 2);
skb = mdp->rx_skbuff[entry]; skb = mdp->rx_skbuff[entry];
mdp->rx_skbuff[entry] = NULL; mdp->rx_skbuff[entry] = NULL;
...@@ -554,14 +685,8 @@ static int sh_eth_rx(struct net_device *ndev) ...@@ -554,14 +685,8 @@ static int sh_eth_rx(struct net_device *ndev)
dma_map_single(&ndev->dev, skb->tail, mdp->rx_buf_sz, dma_map_single(&ndev->dev, skb->tail, mdp->rx_buf_sz,
DMA_FROM_DEVICE); DMA_FROM_DEVICE);
skb->dev = ndev; skb->dev = ndev;
#if defined(CONFIG_CPU_SUBTYPE_SH7763) sh_eth_set_receive_align(skb);
reserve = SH7763_SKB_ALIGN
- ((uint32_t)skb->data & (SH7763_SKB_ALIGN-1));
if (reserve)
skb_reserve(skb, reserve);
#else
skb_reserve(skb, RX_OFFSET);
#endif
skb->ip_summed = CHECKSUM_NONE; skb->ip_summed = CHECKSUM_NONE;
rxdesc->addr = virt_to_phys(PTR_ALIGN(skb->data, 4)); rxdesc->addr = virt_to_phys(PTR_ALIGN(skb->data, 4));
} }
...@@ -587,6 +712,8 @@ static void sh_eth_error(struct net_device *ndev, int intr_status) ...@@ -587,6 +712,8 @@ static void sh_eth_error(struct net_device *ndev, int intr_status)
struct sh_eth_private *mdp = netdev_priv(ndev); struct sh_eth_private *mdp = netdev_priv(ndev);
u32 ioaddr = ndev->base_addr; u32 ioaddr = ndev->base_addr;
u32 felic_stat; u32 felic_stat;
u32 link_stat;
u32 mask;
if (intr_status & EESR_ECI) { if (intr_status & EESR_ECI) {
felic_stat = ctrl_inl(ioaddr + ECSR); felic_stat = ctrl_inl(ioaddr + ECSR);
...@@ -595,7 +722,14 @@ static void sh_eth_error(struct net_device *ndev, int intr_status) ...@@ -595,7 +722,14 @@ static void sh_eth_error(struct net_device *ndev, int intr_status)
mdp->stats.tx_carrier_errors++; mdp->stats.tx_carrier_errors++;
if (felic_stat & ECSR_LCHNG) { if (felic_stat & ECSR_LCHNG) {
/* Link Changed */ /* Link Changed */
u32 link_stat = (ctrl_inl(ioaddr + PSR)); if (mdp->cd->no_psr) {
if (mdp->link == PHY_DOWN)
link_stat = 0;
else
link_stat = PHY_ST_LINK;
} else {
link_stat = (ctrl_inl(ioaddr + PSR));
}
if (!(link_stat & PHY_ST_LINK)) { if (!(link_stat & PHY_ST_LINK)) {
/* Link Down : disable tx and rx */ /* Link Down : disable tx and rx */
ctrl_outl(ctrl_inl(ioaddr + ECMR) & ctrl_outl(ctrl_inl(ioaddr + ECMR) &
...@@ -627,17 +761,15 @@ static void sh_eth_error(struct net_device *ndev, int intr_status) ...@@ -627,17 +761,15 @@ static void sh_eth_error(struct net_device *ndev, int intr_status)
if (intr_status & EESR_RFRMER) { if (intr_status & EESR_RFRMER) {
/* Receive Frame Overflow int */ /* Receive Frame Overflow int */
mdp->stats.rx_frame_errors++; mdp->stats.rx_frame_errors++;
printk(KERN_ERR "Receive Frame Overflow\n"); dev_err(&ndev->dev, "Receive Frame Overflow\n");
} }
} }
#if !defined(CONFIG_CPU_SUBTYPE_SH7763)
if (intr_status & EESR_ADE) { if (!mdp->cd->no_ade) {
if (intr_status & EESR_TDE) { if (intr_status & EESR_ADE && intr_status & EESR_TDE &&
if (intr_status & EESR_TFE) intr_status & EESR_TFE)
mdp->stats.tx_fifo_errors++; mdp->stats.tx_fifo_errors++;
} }
}
#endif
if (intr_status & EESR_RDE) { if (intr_status & EESR_RDE) {
/* Receive Descriptor Empty int */ /* Receive Descriptor Empty int */
...@@ -645,24 +777,24 @@ static void sh_eth_error(struct net_device *ndev, int intr_status) ...@@ -645,24 +777,24 @@ static void sh_eth_error(struct net_device *ndev, int intr_status)
if (ctrl_inl(ioaddr + EDRRR) ^ EDRRR_R) if (ctrl_inl(ioaddr + EDRRR) ^ EDRRR_R)
ctrl_outl(EDRRR_R, ioaddr + EDRRR); ctrl_outl(EDRRR_R, ioaddr + EDRRR);
printk(KERN_ERR "Receive Descriptor Empty\n"); dev_err(&ndev->dev, "Receive Descriptor Empty\n");
} }
if (intr_status & EESR_RFE) { if (intr_status & EESR_RFE) {
/* Receive FIFO Overflow int */ /* Receive FIFO Overflow int */
mdp->stats.rx_fifo_errors++; mdp->stats.rx_fifo_errors++;
printk(KERN_ERR "Receive FIFO Overflow\n"); dev_err(&ndev->dev, "Receive FIFO Overflow\n");
} }
if (intr_status & (EESR_TWB | EESR_TABT |
#if !defined(CONFIG_CPU_SUBTYPE_SH7763) mask = EESR_TWB | EESR_TABT | EESR_ADE | EESR_TDE | EESR_TFE;
EESR_ADE | if (mdp->cd->no_ade)
#endif mask &= ~EESR_ADE;
EESR_TDE | EESR_TFE)) { if (intr_status & mask) {
/* Tx error */ /* Tx error */
u32 edtrr = ctrl_inl(ndev->base_addr + EDTRR); u32 edtrr = ctrl_inl(ndev->base_addr + EDTRR);
/* dmesg */ /* dmesg */
printk(KERN_ERR "%s:TX error. status=%8.8x cur_tx=%8.8x ", dev_err(&ndev->dev, "TX error. status=%8.8x cur_tx=%8.8x ",
ndev->name, intr_status, mdp->cur_tx); intr_status, mdp->cur_tx);
printk(KERN_ERR "dirty_tx=%8.8x state=%8.8x EDTRR=%8.8x.\n", dev_err(&ndev->dev, "dirty_tx=%8.8x state=%8.8x EDTRR=%8.8x.\n",
mdp->dirty_tx, (u32) ndev->state, edtrr); mdp->dirty_tx, (u32) ndev->state, edtrr);
/* dirty buffer free */ /* dirty buffer free */
sh_eth_txfree(ndev); sh_eth_txfree(ndev);
...@@ -681,6 +813,7 @@ static irqreturn_t sh_eth_interrupt(int irq, void *netdev) ...@@ -681,6 +813,7 @@ static irqreturn_t sh_eth_interrupt(int irq, void *netdev)
{ {
struct net_device *ndev = netdev; struct net_device *ndev = netdev;
struct sh_eth_private *mdp = netdev_priv(ndev); struct sh_eth_private *mdp = netdev_priv(ndev);
struct sh_eth_cpu_data *cd = mdp->cd;
irqreturn_t ret = IRQ_NONE; irqreturn_t ret = IRQ_NONE;
u32 ioaddr, boguscnt = RX_RING_SIZE; u32 ioaddr, boguscnt = RX_RING_SIZE;
u32 intr_status = 0; u32 intr_status = 0;
...@@ -693,7 +826,7 @@ static irqreturn_t sh_eth_interrupt(int irq, void *netdev) ...@@ -693,7 +826,7 @@ static irqreturn_t sh_eth_interrupt(int irq, void *netdev)
/* Clear interrupt */ /* Clear interrupt */
if (intr_status & (EESR_FRC | EESR_RMAF | EESR_RRF | if (intr_status & (EESR_FRC | EESR_RMAF | EESR_RRF |
EESR_RTLF | EESR_RTSF | EESR_PRE | EESR_CERF | EESR_RTLF | EESR_RTSF | EESR_PRE | EESR_CERF |
TX_CHECK | EESR_ERR_CHECK)) { cd->tx_check | cd->eesr_err_check)) {
ctrl_outl(intr_status, ioaddr + EESR); ctrl_outl(intr_status, ioaddr + EESR);
ret = IRQ_HANDLED; ret = IRQ_HANDLED;
} else } else
...@@ -710,12 +843,12 @@ static irqreturn_t sh_eth_interrupt(int irq, void *netdev) ...@@ -710,12 +843,12 @@ static irqreturn_t sh_eth_interrupt(int irq, void *netdev)
} }
/* Tx Check */ /* Tx Check */
if (intr_status & TX_CHECK) { if (intr_status & cd->tx_check) {
sh_eth_txfree(ndev); sh_eth_txfree(ndev);
netif_wake_queue(ndev); netif_wake_queue(ndev);
} }
if (intr_status & EESR_ERR_CHECK) if (intr_status & cd->eesr_err_check)
sh_eth_error(ndev, intr_status); sh_eth_error(ndev, intr_status);
if (--boguscnt < 0) { if (--boguscnt < 0) {
...@@ -750,32 +883,15 @@ static void sh_eth_adjust_link(struct net_device *ndev) ...@@ -750,32 +883,15 @@ static void sh_eth_adjust_link(struct net_device *ndev)
if (phydev->duplex != mdp->duplex) { if (phydev->duplex != mdp->duplex) {
new_state = 1; new_state = 1;
mdp->duplex = phydev->duplex; mdp->duplex = phydev->duplex;
#if defined(CONFIG_CPU_SUBTYPE_SH7763) if (mdp->cd->set_duplex)
if (mdp->duplex) { /* FULL */ mdp->cd->set_duplex(ndev);
ctrl_outl(ctrl_inl(ioaddr + ECMR) | ECMR_DM,
ioaddr + ECMR);
} else { /* Half */
ctrl_outl(ctrl_inl(ioaddr + ECMR) & ~ECMR_DM,
ioaddr + ECMR);
}
#endif
} }
if (phydev->speed != mdp->speed) { if (phydev->speed != mdp->speed) {
new_state = 1; new_state = 1;
mdp->speed = phydev->speed; mdp->speed = phydev->speed;
#if defined(CONFIG_CPU_SUBTYPE_SH7763) if (mdp->cd->set_rate)
switch (mdp->speed) { mdp->cd->set_rate(ndev);
case 10: /* 10BASE */
ctrl_outl(GECMR_10, ioaddr + GECMR); break;
case 100:/* 100BASE */
ctrl_outl(GECMR_100, ioaddr + GECMR); break;
case 1000: /* 1000BASE */
ctrl_outl(GECMR_1000, ioaddr + GECMR); break;
default:
break;
}
#endif
} }
if (mdp->link == PHY_DOWN) { if (mdp->link == PHY_DOWN) {
ctrl_outl((ctrl_inl(ioaddr + ECMR) & ~ECMR_TXF) ctrl_outl((ctrl_inl(ioaddr + ECMR) & ~ECMR_TXF)
...@@ -815,6 +931,7 @@ static int sh_eth_phy_init(struct net_device *ndev) ...@@ -815,6 +931,7 @@ static int sh_eth_phy_init(struct net_device *ndev)
dev_err(&ndev->dev, "phy_connect failed\n"); dev_err(&ndev->dev, "phy_connect failed\n");
return PTR_ERR(phydev); return PTR_ERR(phydev);
} }
dev_info(&ndev->dev, "attached phy %i to driver %s\n", dev_info(&ndev->dev, "attached phy %i to driver %s\n",
phydev->addr, phydev->drv->name); phydev->addr, phydev->drv->name);
...@@ -854,7 +971,7 @@ static int sh_eth_open(struct net_device *ndev) ...@@ -854,7 +971,7 @@ static int sh_eth_open(struct net_device *ndev)
#endif #endif
ndev->name, ndev); ndev->name, ndev);
if (ret) { if (ret) {
printk(KERN_ERR "Can not assign IRQ number to %s\n", CARDNAME); dev_err(&ndev->dev, "Can not assign IRQ number\n");
return ret; return ret;
} }
...@@ -951,7 +1068,9 @@ static int sh_eth_start_xmit(struct sk_buff *skb, struct net_device *ndev) ...@@ -951,7 +1068,9 @@ static int sh_eth_start_xmit(struct sk_buff *skb, struct net_device *ndev)
txdesc = &mdp->tx_ring[entry]; txdesc = &mdp->tx_ring[entry];
txdesc->addr = virt_to_phys(skb->data); txdesc->addr = virt_to_phys(skb->data);
/* soft swap. */ /* soft swap. */
swaps(phys_to_virt(ALIGN(txdesc->addr, 4)), skb->len + 2); if (!mdp->cd->hw_swap)
sh_eth_soft_swap(phys_to_virt(ALIGN(txdesc->addr, 4)),
skb->len + 2);
/* write back */ /* write back */
__flush_purge_region(skb->data, skb->len); __flush_purge_region(skb->data, skb->len);
if (skb->len < ETHERSMALL) if (skb->len < ETHERSMALL)
...@@ -1053,7 +1172,7 @@ static int sh_eth_do_ioctl(struct net_device *ndev, struct ifreq *rq, ...@@ -1053,7 +1172,7 @@ static int sh_eth_do_ioctl(struct net_device *ndev, struct ifreq *rq,
return phy_mii_ioctl(phydev, if_mii(rq), cmd); return phy_mii_ioctl(phydev, if_mii(rq), cmd);
} }
#if defined(SH_ETH_HAS_TSU)
/* Multicast reception directions set */ /* Multicast reception directions set */
static void sh_eth_set_multicast_list(struct net_device *ndev) static void sh_eth_set_multicast_list(struct net_device *ndev)
{ {
...@@ -1098,6 +1217,7 @@ static void sh_eth_tsu_init(u32 ioaddr) ...@@ -1098,6 +1217,7 @@ static void sh_eth_tsu_init(u32 ioaddr)
ctrl_outl(0, ioaddr + TSU_POST3); /* Disable CAM entry [16-23] */ ctrl_outl(0, ioaddr + TSU_POST3); /* Disable CAM entry [16-23] */
ctrl_outl(0, ioaddr + TSU_POST4); /* Disable CAM entry [24-31] */ ctrl_outl(0, ioaddr + TSU_POST4); /* Disable CAM entry [24-31] */
} }
#endif /* SH_ETH_HAS_TSU */
/* MDIO bus release function */ /* MDIO bus release function */
static int sh_mdio_release(struct net_device *ndev) static int sh_mdio_release(struct net_device *ndev)
...@@ -1187,7 +1307,9 @@ static const struct net_device_ops sh_eth_netdev_ops = { ...@@ -1187,7 +1307,9 @@ static const struct net_device_ops sh_eth_netdev_ops = {
.ndo_stop = sh_eth_close, .ndo_stop = sh_eth_close,
.ndo_start_xmit = sh_eth_start_xmit, .ndo_start_xmit = sh_eth_start_xmit,
.ndo_get_stats = sh_eth_get_stats, .ndo_get_stats = sh_eth_get_stats,
#if defined(SH_ETH_HAS_TSU)
.ndo_set_multicast_list = sh_eth_set_multicast_list, .ndo_set_multicast_list = sh_eth_set_multicast_list,
#endif
.ndo_tx_timeout = sh_eth_tx_timeout, .ndo_tx_timeout = sh_eth_tx_timeout,
.ndo_do_ioctl = sh_eth_do_ioctl, .ndo_do_ioctl = sh_eth_do_ioctl,
.ndo_validate_addr = eth_validate_addr, .ndo_validate_addr = eth_validate_addr,
...@@ -1213,7 +1335,7 @@ static int sh_eth_drv_probe(struct platform_device *pdev) ...@@ -1213,7 +1335,7 @@ static int sh_eth_drv_probe(struct platform_device *pdev)
ndev = alloc_etherdev(sizeof(struct sh_eth_private)); ndev = alloc_etherdev(sizeof(struct sh_eth_private));
if (!ndev) { if (!ndev) {
printk(KERN_ERR "%s: could not allocate device.\n", CARDNAME); dev_err(&pdev->dev, "Could not allocate device.\n");
ret = -ENOMEM; ret = -ENOMEM;
goto out; goto out;
} }
...@@ -1246,6 +1368,10 @@ static int sh_eth_drv_probe(struct platform_device *pdev) ...@@ -1246,6 +1368,10 @@ static int sh_eth_drv_probe(struct platform_device *pdev)
/* EDMAC endian */ /* EDMAC endian */
mdp->edmac_endian = pd->edmac_endian; mdp->edmac_endian = pd->edmac_endian;
/* set cpu data */
mdp->cd = &sh_eth_my_cpu_data;
sh_eth_set_default_cpu_data(mdp->cd);
/* set function */ /* set function */
ndev->netdev_ops = &sh_eth_netdev_ops; ndev->netdev_ops = &sh_eth_netdev_ops;
ndev->watchdog_timeo = TX_TIMEOUT; ndev->watchdog_timeo = TX_TIMEOUT;
...@@ -1258,13 +1384,10 @@ static int sh_eth_drv_probe(struct platform_device *pdev) ...@@ -1258,13 +1384,10 @@ static int sh_eth_drv_probe(struct platform_device *pdev)
/* First device only init */ /* First device only init */
if (!devno) { if (!devno) {
#if defined(ARSTR) if (mdp->cd->chip_reset)
/* reset device */ mdp->cd->chip_reset(ndev);
ctrl_outl(ARSTR_ARSTR, ARSTR);
mdelay(1);
#endif
#if defined(SH_TSU_ADDR) #if defined(SH_ETH_HAS_TSU)
/* TSU init (Init only)*/ /* TSU init (Init only)*/
sh_eth_tsu_init(SH_TSU_ADDR); sh_eth_tsu_init(SH_TSU_ADDR);
#endif #endif
...@@ -1281,8 +1404,8 @@ static int sh_eth_drv_probe(struct platform_device *pdev) ...@@ -1281,8 +1404,8 @@ static int sh_eth_drv_probe(struct platform_device *pdev)
goto out_unregister; goto out_unregister;
/* pritnt device infomation */ /* pritnt device infomation */
printk(KERN_INFO "%s: %s at 0x%x, ", pr_info("Base address at 0x%x, ",
ndev->name, CARDNAME, (u32) ndev->base_addr); (u32)ndev->base_addr);
for (i = 0; i < 5; i++) for (i = 0; i < 5; i++)
printk("%02X:", ndev->dev_addr[i]); printk("%02X:", ndev->dev_addr[i]);
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* SuperH Ethernet device driver * SuperH Ethernet device driver
* *
* Copyright (C) 2006-2008 Nobuhiro Iwamatsu * Copyright (C) 2006-2008 Nobuhiro Iwamatsu
* Copyright (C) 2008 Renesas Solutions Corp. * Copyright (C) 2008-2009 Renesas Solutions Corp.
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License, * under the terms and conditions of the GNU General Public License,
...@@ -39,9 +39,7 @@ ...@@ -39,9 +39,7 @@
#define ETHERSMALL 60 #define ETHERSMALL 60
#define PKT_BUF_SZ 1538 #define PKT_BUF_SZ 1538
#ifdef CONFIG_CPU_SUBTYPE_SH7763 #if defined(CONFIG_CPU_SUBTYPE_SH7763)
#define SH7763_SKB_ALIGN 32
/* Chip Base Address */ /* Chip Base Address */
# define SH_TSU_ADDR 0xFEE01800 # define SH_TSU_ADDR 0xFEE01800
# define ARSTR SH_TSU_ADDR # define ARSTR SH_TSU_ADDR
...@@ -143,8 +141,8 @@ ...@@ -143,8 +141,8 @@
# define FWNLCR1 0xB0 # define FWNLCR1 0xB0
# define FWALCR1 0x40 # define FWALCR1 0x40
#else /* CONFIG_CPU_SUBTYPE_SH7763 */ #else /* #elif defined(CONFIG_CPU_SUBTYPE_SH7763) */
# define RX_OFFSET 2 /* skb offset */ /* This section is SH3 or SH2 */
#ifndef CONFIG_CPU_SUBTYPE_SH7619 #ifndef CONFIG_CPU_SUBTYPE_SH7619
/* Chip base address */ /* Chip base address */
# define SH_TSU_ADDR 0xA7000804 # define SH_TSU_ADDR 0xA7000804
...@@ -243,6 +241,30 @@ ...@@ -243,6 +241,30 @@
#endif /* CONFIG_CPU_SUBTYPE_SH7763 */ #endif /* CONFIG_CPU_SUBTYPE_SH7763 */
/* There are avoid compile error... */
#if !defined(BCULR)
#define BCULR 0x0fc
#endif
#if !defined(TRIMD)
#define TRIMD 0x0fc
#endif
#if !defined(APR)
#define APR 0x0fc
#endif
#if !defined(MPR)
#define MPR 0x0fc
#endif
#if !defined(TPAUSER)
#define TPAUSER 0x0fc
#endif
/* Driver's parameters */
#if defined(CONFIG_CPU_SH4)
#define SH4_SKB_RX_ALIGN 32
#else
#define SH2_SH3_SKB_RX_ALIGN 2
#endif
/* /*
* Register's bits * Register's bits
*/ */
...@@ -261,11 +283,10 @@ enum GECMR_BIT { ...@@ -261,11 +283,10 @@ enum GECMR_BIT {
/* EDMR */ /* EDMR */
enum DMAC_M_BIT { enum DMAC_M_BIT {
EDMR_EL = 0x40, /* Litte endian */
EDMR_DL1 = 0x20, EDMR_DL0 = 0x10, EDMR_DL1 = 0x20, EDMR_DL0 = 0x10,
#ifdef CONFIG_CPU_SUBTYPE_SH7763 #ifdef CONFIG_CPU_SUBTYPE_SH7763
EDMR_SRST = 0x03, EDMR_SRST = 0x03,
EMDR_DESC_R = 0x30, /* Descriptor reserve size */
EDMR_EL = 0x40, /* Litte endian */
#else /* CONFIG_CPU_SUBTYPE_SH7763 */ #else /* CONFIG_CPU_SUBTYPE_SH7763 */
EDMR_SRST = 0x01, EDMR_SRST = 0x01,
#endif #endif
...@@ -307,47 +328,43 @@ enum PHY_STATUS_BIT { PHY_ST_LINK = 0x01, }; ...@@ -307,47 +328,43 @@ enum PHY_STATUS_BIT { PHY_ST_LINK = 0x01, };
/* EESR */ /* EESR */
enum EESR_BIT { enum EESR_BIT {
#ifndef CONFIG_CPU_SUBTYPE_SH7763 EESR_TWB1 = 0x80000000,
EESR_TWB = 0x40000000, EESR_TWB = 0x40000000, /* same as TWB0 */
#else
EESR_TWB = 0xC0000000,
EESR_TC1 = 0x20000000, EESR_TC1 = 0x20000000,
EESR_TUC = 0x10000000, EESR_TUC = 0x10000000,
EESR_ROC = 0x80000000, EESR_ROC = 0x08000000,
#endif
EESR_TABT = 0x04000000, EESR_TABT = 0x04000000,
EESR_RABT = 0x02000000, EESR_RFRMER = 0x01000000, EESR_RABT = 0x02000000,
#ifndef CONFIG_CPU_SUBTYPE_SH7763 EESR_RFRMER = 0x01000000, /* same as RFCOF */
EESR_ADE = 0x00800000, EESR_ADE = 0x00800000,
#endif
EESR_ECI = 0x00400000, EESR_ECI = 0x00400000,
EESR_FTC = 0x00200000, EESR_TDE = 0x00100000, EESR_FTC = 0x00200000, /* same as TC or TC0 */
EESR_TFE = 0x00080000, EESR_FRC = 0x00040000, EESR_TDE = 0x00100000,
EESR_RDE = 0x00020000, EESR_RFE = 0x00010000, EESR_TFE = 0x00080000, /* same as TFUF */
#ifndef CONFIG_CPU_SUBTYPE_SH7763 EESR_FRC = 0x00040000, /* same as FR */
EESR_RDE = 0x00020000,
EESR_RFE = 0x00010000,
EESR_CND = 0x00000800, EESR_CND = 0x00000800,
#endif
EESR_DLC = 0x00000400, EESR_DLC = 0x00000400,
EESR_CD = 0x00000200, EESR_RTO = 0x00000100, EESR_CD = 0x00000200,
EESR_RMAF = 0x00000080, EESR_CEEF = 0x00000040, EESR_RTO = 0x00000100,
EESR_CELF = 0x00000020, EESR_RRF = 0x00000010, EESR_RMAF = 0x00000080,
EESR_RTLF = 0x00000008, EESR_RTSF = 0x00000004, EESR_CEEF = 0x00000040,
EESR_PRE = 0x00000002, EESR_CERF = 0x00000001, EESR_CELF = 0x00000020,
}; EESR_RRF = 0x00000010,
EESR_RTLF = 0x00000008,
EESR_RTSF = 0x00000004,
#ifdef CONFIG_CPU_SUBTYPE_SH7763 EESR_PRE = 0x00000002,
# define TX_CHECK (EESR_TC1 | EESR_FTC) EESR_CERF = 0x00000001,
# define EESR_ERR_CHECK (EESR_TWB | EESR_TABT | EESR_RABT | EESR_RDE \ };
| EESR_RFRMER | EESR_TFE | EESR_TDE | EESR_ECI)
# define TX_ERROR_CEHCK (EESR_TWB | EESR_TABT | EESR_TDE | EESR_TFE) #define DEFAULT_TX_CHECK (EESR_FTC | EESR_CND | EESR_DLC | EESR_CD | \
EESR_RTO)
#else #define DEFAULT_EESR_ERR_CHECK (EESR_TWB | EESR_TABT | EESR_RABT | \
# define TX_CHECK (EESR_FTC | EESR_CND | EESR_DLC | EESR_CD | EESR_RTO) EESR_RDE | EESR_RFRMER | EESR_ADE | \
# define EESR_ERR_CHECK (EESR_TWB | EESR_TABT | EESR_RABT | EESR_RDE \ EESR_TFE | EESR_TDE | EESR_ECI)
| EESR_RFRMER | EESR_ADE | EESR_TFE | EESR_TDE | EESR_ECI) #define DEFAULT_TX_ERROR_CHECK (EESR_TWB | EESR_TABT | EESR_ADE | EESR_TDE | \
# define TX_ERROR_CEHCK (EESR_TWB | EESR_TABT | EESR_ADE | EESR_TDE | EESR_TFE) EESR_TFE)
#endif
/* EESIPR */ /* EESIPR */
enum DMAC_IM_BIT { enum DMAC_IM_BIT {
...@@ -386,12 +403,8 @@ enum FCFTR_BIT { ...@@ -386,12 +403,8 @@ enum FCFTR_BIT {
FCFTR_RFF0 = 0x00010000, FCFTR_RFD2 = 0x00000004, FCFTR_RFF0 = 0x00010000, FCFTR_RFD2 = 0x00000004,
FCFTR_RFD1 = 0x00000002, FCFTR_RFD0 = 0x00000001, FCFTR_RFD1 = 0x00000002, FCFTR_RFD0 = 0x00000001,
}; };
#define FIFO_F_D_RFF (FCFTR_RFF2|FCFTR_RFF1|FCFTR_RFF0) #define DEFAULT_FIFO_F_D_RFF (FCFTR_RFF2 | FCFTR_RFF1 | FCFTR_RFF0)
#ifndef CONFIG_CPU_SUBTYPE_SH7619 #define DEFAULT_FIFO_F_D_RFD (FCFTR_RFD2 | FCFTR_RFD1 | FCFTR_RFD0)
#define FIFO_F_D_RFD (FCFTR_RFD2|FCFTR_RFD1|FCFTR_RFD0)
#else
#define FIFO_F_D_RFD (FCFTR_RFD0)
#endif
/* Transfer descriptor bit */ /* Transfer descriptor bit */
enum TD_STS_BIT { enum TD_STS_BIT {
...@@ -404,60 +417,38 @@ enum TD_STS_BIT { ...@@ -404,60 +417,38 @@ enum TD_STS_BIT {
#define TD_TFP (TD_TFP1|TD_TFP0) #define TD_TFP (TD_TFP1|TD_TFP0)
/* RMCR */ /* RMCR */
enum RECV_RST_BIT { RMCR_RST = 0x01, }; #define DEFAULT_RMCR_VALUE 0x00000000
/* ECMR */ /* ECMR */
enum FELIC_MODE_BIT { enum FELIC_MODE_BIT {
#ifdef CONFIG_CPU_SUBTYPE_SH7763
ECMR_TRCCM = 0x04000000, ECMR_RCSC = 0x00800000, ECMR_TRCCM = 0x04000000, ECMR_RCSC = 0x00800000,
ECMR_DPAD = 0x00200000, ECMR_RZPF = 0x00100000, ECMR_DPAD = 0x00200000, ECMR_RZPF = 0x00100000,
#endif
ECMR_ZPF = 0x00080000, ECMR_PFR = 0x00040000, ECMR_RXF = 0x00020000, ECMR_ZPF = 0x00080000, ECMR_PFR = 0x00040000, ECMR_RXF = 0x00020000,
ECMR_TXF = 0x00010000, ECMR_MCT = 0x00002000, ECMR_PRCEF = 0x00001000, ECMR_TXF = 0x00010000, ECMR_MCT = 0x00002000, ECMR_PRCEF = 0x00001000,
ECMR_PMDE = 0x00000200, ECMR_RE = 0x00000040, ECMR_TE = 0x00000020, ECMR_PMDE = 0x00000200, ECMR_RE = 0x00000040, ECMR_TE = 0x00000020,
ECMR_ILB = 0x00000008, ECMR_ELB = 0x00000004, ECMR_DM = 0x00000002, ECMR_ILB = 0x00000008, ECMR_ELB = 0x00000004,
ECMR_PRM = 0x00000001, ECMR_DM = 0x00000002, ECMR_PRM = 0x00000001,
}; };
#ifdef CONFIG_CPU_SUBTYPE_SH7763
#define ECMR_CHG_DM (ECMR_TRCCM | ECMR_RZPF | ECMR_ZPF |\
ECMR_PFR | ECMR_RXF | ECMR_TXF | ECMR_MCT)
#elif CONFIG_CPU_SUBTYPE_SH7619
#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
/* ECSR */ /* ECSR */
enum ECSR_STATUS_BIT { enum ECSR_STATUS_BIT {
#ifndef CONFIG_CPU_SUBTYPE_SH7763
ECSR_BRCRX = 0x20, ECSR_PSRTO = 0x10, ECSR_BRCRX = 0x20, ECSR_PSRTO = 0x10,
#endif
ECSR_LCHNG = 0x04, ECSR_LCHNG = 0x04,
ECSR_MPD = 0x02, ECSR_ICD = 0x01, ECSR_MPD = 0x02, ECSR_ICD = 0x01,
}; };
#ifdef CONFIG_CPU_SUBTYPE_SH7763 #define DEFAULT_ECSR_INIT (ECSR_BRCRX | ECSR_PSRTO | ECSR_LCHNG | \
# define ECSR_INIT (ECSR_ICD | ECSIPR_MPDIP) ECSR_ICD | ECSIPR_MPDIP)
#else
# define ECSR_INIT (ECSR_BRCRX | ECSR_PSRTO | \
ECSR_LCHNG | ECSR_ICD | ECSIPR_MPDIP)
#endif
/* ECSIPR */ /* ECSIPR */
enum ECSIPR_STATUS_MASK_BIT { enum ECSIPR_STATUS_MASK_BIT {
#ifndef CONFIG_CPU_SUBTYPE_SH7763
ECSIPR_BRCRXIP = 0x20, ECSIPR_PSRTOIP = 0x10, ECSIPR_BRCRXIP = 0x20, ECSIPR_PSRTOIP = 0x10,
#endif
ECSIPR_LCHNGIP = 0x04, ECSIPR_LCHNGIP = 0x04,
ECSIPR_MPDIP = 0x02, ECSIPR_ICDIP = 0x01, ECSIPR_MPDIP = 0x02, ECSIPR_ICDIP = 0x01,
}; };
#ifdef CONFIG_CPU_SUBTYPE_SH7763 #define DEFAULT_ECSIPR_INIT (ECSIPR_BRCRXIP | ECSIPR_PSRTOIP | \
# define ECSIPR_INIT (ECSIPR_LCHNGIP | ECSIPR_ICDIP | ECSIPR_MPDIP) ECSIPR_LCHNGIP | ECSIPR_ICDIP | ECSIPR_MPDIP)
#else
# define ECSIPR_INIT (ECSIPR_BRCRXIP | ECSIPR_PSRTOIP | ECSIPR_LCHNGIP | \
ECSIPR_ICDIP | ECSIPR_MPDIP)
#endif
/* APR */ /* APR */
enum APR_BIT { enum APR_BIT {
...@@ -483,23 +474,12 @@ enum RPADIR_BIT { ...@@ -483,23 +474,12 @@ enum RPADIR_BIT {
RPADIR_PADR = 0x0003f, RPADIR_PADR = 0x0003f,
}; };
#if defined(CONFIG_CPU_SUBTYPE_SH7763)
# define RPADIR_INIT (0x00)
#else
# define RPADIR_INIT (RPADIR_PADS1)
#endif
/* RFLR */ /* RFLR */
#define RFLR_VALUE 0x1000 #define RFLR_VALUE 0x1000
/* FDR */ /* FDR */
enum FIFO_SIZE_BIT { #define DEFAULT_FDR_INIT 0x00000707
#ifndef CONFIG_CPU_SUBTYPE_SH7619
FIFO_SIZE_T = 0x00000700, FIFO_SIZE_R = 0x00000007,
#else
FIFO_SIZE_T = 0x00000100, FIFO_SIZE_R = 0x00000001,
#endif
};
enum phy_offsets { enum phy_offsets {
PHY_CTRL = 0, PHY_STAT = 1, PHY_IDT1 = 2, PHY_IDT2 = 3, PHY_CTRL = 0, PHY_STAT = 1, PHY_IDT1 = 2, PHY_IDT2 = 3,
PHY_ANA = 4, PHY_ANL = 5, PHY_ANE = 6, PHY_ANA = 4, PHY_ANL = 5, PHY_ANE = 6,
...@@ -633,7 +613,43 @@ struct sh_eth_rxdesc { ...@@ -633,7 +613,43 @@ struct sh_eth_rxdesc {
u32 pad0; /* padding data */ u32 pad0; /* padding data */
} __attribute__((aligned(2), packed)); } __attribute__((aligned(2), packed));
/* This structure is used by each CPU dependency handling. */
struct sh_eth_cpu_data {
/* optional functions */
void (*chip_reset)(struct net_device *ndev);
void (*set_duplex)(struct net_device *ndev);
void (*set_rate)(struct net_device *ndev);
/* mandatory initialize value */
unsigned long eesipr_value;
/* optional initialize value */
unsigned long ecsr_value;
unsigned long ecsipr_value;
unsigned long fdr_value;
unsigned long fcftr_value;
unsigned long rpadir_value;
unsigned long rmcr_value;
/* interrupt checking mask */
unsigned long tx_check;
unsigned long eesr_err_check;
unsigned long tx_error_check;
/* hardware features */
unsigned no_psr:1; /* EtherC DO NOT have PSR */
unsigned apr:1; /* EtherC have APR */
unsigned mpr:1; /* EtherC have MPR */
unsigned tpauser:1; /* EtherC have TPAUSER */
unsigned bculr:1; /* EtherC have BCULR */
unsigned hw_swap:1; /* E-DMAC have DE bit in EDMR */
unsigned rpadir:1; /* E-DMAC have RPADIR */
unsigned no_trimd:1; /* E-DMAC DO NOT have TRIMD */
unsigned no_ade:1; /* E-DMAC DO NOT have ADE bit in EESR */
};
struct sh_eth_private { struct sh_eth_private {
struct sh_eth_cpu_data *cd;
dma_addr_t rx_desc_dma; dma_addr_t rx_desc_dma;
dma_addr_t tx_desc_dma; dma_addr_t tx_desc_dma;
struct sh_eth_rxdesc *rx_ring; struct sh_eth_rxdesc *rx_ring;
...@@ -661,11 +677,7 @@ struct sh_eth_private { ...@@ -661,11 +677,7 @@ struct sh_eth_private {
struct net_device_stats tsu_stats; /* TSU forward status */ struct net_device_stats tsu_stats; /* TSU forward status */
}; };
#ifdef CONFIG_CPU_SUBTYPE_SH7763 static inline void sh_eth_soft_swap(char *src, int len)
/* SH7763 has endian control register */
#define swaps(x, y)
#else
static void swaps(char *src, int len)
{ {
#ifdef __LITTLE_ENDIAN__ #ifdef __LITTLE_ENDIAN__
u32 *p = (u32 *)src; u32 *p = (u32 *)src;
...@@ -676,5 +688,5 @@ static void swaps(char *src, int len) ...@@ -676,5 +688,5 @@ static void swaps(char *src, int len)
*p = swab32(*p); *p = swab32(*p);
#endif #endif
} }
#endif /* CONFIG_CPU_SUBTYPE_SH7763 */
#endif #endif /* #ifndef __SH_ETH_H__ */
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