Commit 4a55530f authored by Yoshihiro Shimoda's avatar Yoshihiro Shimoda Committed by David S. Miller
Browse files

net: sh_eth: modify the definitions of register



The previous code cannot handle the ETHER and GETHER both as same time
because the definitions of register was hardcoded.

Signed-off-by: default avatarYoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 201a11c1
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -2,10 +2,16 @@
#define __ASM_SH_ETH_H__

enum {EDMAC_LITTLE_ENDIAN, EDMAC_BIG_ENDIAN};
enum {
	SH_ETH_REG_GIGABIT,
	SH_ETH_REG_FAST_SH4,
	SH_ETH_REG_FAST_SH3_SH2
};

struct sh_eth_plat_data {
	int phy;
	int edmac_endian;
	int register_type;

	unsigned char mac_addr[6];
	unsigned no_ether_link:1;
+163 −163
Original line number Diff line number Diff line
@@ -49,25 +49,23 @@
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 */
		writel(readl(ioaddr + ECMR) | ECMR_DM, ioaddr + ECMR);
		sh_eth_write(ndev, sh_eth_read(ndev, ECMR) | ECMR_DM, ECMR);
	else		/* Half */
		writel(readl(ioaddr + ECMR) & ~ECMR_DM, ioaddr + ECMR);
		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);
	u32 ioaddr = ndev->base_addr;

	switch (mdp->speed) {
	case 10: /* 10BASE */
		writel(readl(ioaddr + ECMR) & ~ECMR_RTM, ioaddr + ECMR);
		sh_eth_write(ndev, sh_eth_read(ndev, ECMR) & ~ECMR_RTM, ECMR);
		break;
	case 100:/* 100BASE */
		writel(readl(ioaddr + ECMR) | ECMR_RTM, ioaddr + ECMR);
		sh_eth_write(ndev, sh_eth_read(ndev, ECMR) | ECMR_RTM, ECMR);
		break;
	default:
		break;
@@ -100,25 +98,23 @@ static struct sh_eth_cpu_data sh_eth_my_cpu_data = {
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 */
		writel(readl(ioaddr + ECMR) | ECMR_DM, ioaddr + ECMR);
		sh_eth_write(ndev, sh_eth_read(ndev, ECMR) | ECMR_DM, ECMR);
	else		/* Half */
		writel(readl(ioaddr + ECMR) & ~ECMR_DM, ioaddr + ECMR);
		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);
	u32 ioaddr = ndev->base_addr;

	switch (mdp->speed) {
	case 10: /* 10BASE */
		writel(0, ioaddr + RTRATE);
		sh_eth_write(ndev, 0, RTRATE);
		break;
	case 100:/* 100BASE */
		writel(1, ioaddr + RTRATE);
		sh_eth_write(ndev, 1, RTRATE);
		break;
	default:
		break;
@@ -156,13 +152,12 @@ static void sh_eth_chip_reset(struct net_device *ndev)

static void sh_eth_reset(struct net_device *ndev)
{
	u32 ioaddr = ndev->base_addr;
	int cnt = 100;

	writel(EDSR_ENALL, ioaddr + EDSR);
	writel(readl(ioaddr + EDMR) | EDMR_SRST, ioaddr + EDMR);
	sh_eth_write(ndev, EDSR_ENALL, EDSR);
	sh_eth_write(ndev, sh_eth_read(ndev, EDMR) | EDMR_SRST, EDMR);
	while (cnt > 0) {
		if (!(readl(ioaddr + EDMR) & 0x3))
		if (!(sh_eth_read(ndev, EDMR) & 0x3))
			break;
		mdelay(1);
		cnt--;
@@ -171,41 +166,39 @@ static void sh_eth_reset(struct net_device *ndev)
		printk(KERN_ERR "Device reset fail\n");

	/* Table Init */
	writel(0x0, ioaddr + TDLAR);
	writel(0x0, ioaddr + TDFAR);
	writel(0x0, ioaddr + TDFXR);
	writel(0x0, ioaddr + TDFFR);
	writel(0x0, ioaddr + RDLAR);
	writel(0x0, ioaddr + RDFAR);
	writel(0x0, ioaddr + RDFXR);
	writel(0x0, ioaddr + RDFFR);
	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);
	u32 ioaddr = ndev->base_addr;

	if (mdp->duplex) /* Full */
		writel(readl(ioaddr + ECMR) | ECMR_DM, ioaddr + ECMR);
		sh_eth_write(ndev, sh_eth_read(ndev, ECMR) | ECMR_DM, ECMR);
	else		/* Half */
		writel(readl(ioaddr + ECMR) & ~ECMR_DM, ioaddr + ECMR);
		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);
	u32 ioaddr = ndev->base_addr;

	switch (mdp->speed) {
	case 10: /* 10BASE */
		writel(GECMR_10, ioaddr + GECMR);
		sh_eth_write(ndev, GECMR_10, GECMR);
		break;
	case 100:/* 100BASE */
		writel(GECMR_100, ioaddr + GECMR);
		sh_eth_write(ndev, GECMR_100, GECMR);
		break;
	case 1000: /* 1000BASE */
		writel(GECMR_1000, ioaddr + GECMR);
		sh_eth_write(ndev, GECMR_1000, GECMR);
		break;
	default:
		break;
@@ -288,11 +281,9 @@ static void sh_eth_set_default_cpu_data(struct sh_eth_cpu_data *cd)
/* Chip Reset */
static void sh_eth_reset(struct net_device *ndev)
{
	u32 ioaddr = ndev->base_addr;

	writel(readl(ioaddr + EDMR) | EDMR_SRST, ioaddr + EDMR);
	sh_eth_write(ndev, sh_eth_read(ndev, EDMR) | EDMR_SRST, EDMR);
	mdelay(3);
	writel(readl(ioaddr + EDMR) & ~EDMR_SRST, ioaddr + EDMR);
	sh_eth_write(ndev, sh_eth_read(ndev, EDMR) & ~EDMR_SRST, EDMR);
}
#endif

@@ -341,13 +332,11 @@ static inline __u32 edmac_to_cpu(struct sh_eth_private *mdp, u32 x)
 */
static void update_mac_address(struct net_device *ndev)
{
	u32 ioaddr = ndev->base_addr;

	writel((ndev->dev_addr[0] << 24) | (ndev->dev_addr[1] << 16) |
		  (ndev->dev_addr[2] << 8) | (ndev->dev_addr[3]),
		  ioaddr + MAHR);
	writel((ndev->dev_addr[4] << 8) | (ndev->dev_addr[5]),
		  ioaddr + MALR);
	sh_eth_write(ndev,
		(ndev->dev_addr[0] << 24) | (ndev->dev_addr[1] << 16) |
		(ndev->dev_addr[2] << 8) | (ndev->dev_addr[3]), MAHR);
	sh_eth_write(ndev,
		(ndev->dev_addr[4] << 8) | (ndev->dev_addr[5]), MALR);
}

/*
@@ -360,17 +349,15 @@ static void update_mac_address(struct net_device *ndev)
 */
static void read_mac_address(struct net_device *ndev, unsigned char *mac)
{
	u32 ioaddr = ndev->base_addr;

	if (mac[0] || mac[1] || mac[2] || mac[3] || mac[4] || mac[5]) {
		memcpy(ndev->dev_addr, mac, 6);
	} else {
		ndev->dev_addr[0] = (readl(ioaddr + MAHR) >> 24);
		ndev->dev_addr[1] = (readl(ioaddr + MAHR) >> 16) & 0xFF;
		ndev->dev_addr[2] = (readl(ioaddr + MAHR) >> 8) & 0xFF;
		ndev->dev_addr[3] = (readl(ioaddr + MAHR) & 0xFF);
		ndev->dev_addr[4] = (readl(ioaddr + MALR) >> 8) & 0xFF;
		ndev->dev_addr[5] = (readl(ioaddr + MALR) & 0xFF);
		ndev->dev_addr[0] = (sh_eth_read(ndev, MAHR) >> 24);
		ndev->dev_addr[1] = (sh_eth_read(ndev, MAHR) >> 16) & 0xFF;
		ndev->dev_addr[2] = (sh_eth_read(ndev, MAHR) >> 8) & 0xFF;
		ndev->dev_addr[3] = (sh_eth_read(ndev, MAHR) & 0xFF);
		ndev->dev_addr[4] = (sh_eth_read(ndev, MALR) >> 8) & 0xFF;
		ndev->dev_addr[5] = (sh_eth_read(ndev, MALR) & 0xFF);
	}
}

@@ -477,7 +464,6 @@ static void sh_eth_ring_free(struct net_device *ndev)
/* format skb and descriptor buffer */
static void sh_eth_ring_format(struct net_device *ndev)
{
	u32 ioaddr = ndev->base_addr;
	struct sh_eth_private *mdp = netdev_priv(ndev);
	int i;
	struct sk_buff *skb;
@@ -513,9 +499,9 @@ static void sh_eth_ring_format(struct net_device *ndev)
		rxdesc->buffer_length = ALIGN(mdp->rx_buf_sz, 16);
		/* Rx descriptor address set */
		if (i == 0) {
			writel(mdp->rx_desc_dma, ioaddr + RDLAR);
			sh_eth_write(ndev, mdp->rx_desc_dma, RDLAR);
#if defined(CONFIG_CPU_SUBTYPE_SH7763)
			writel(mdp->rx_desc_dma, ioaddr + RDFAR);
			sh_eth_write(ndev, mdp->rx_desc_dma, RDFAR);
#endif
		}
	}
@@ -535,9 +521,9 @@ static void sh_eth_ring_format(struct net_device *ndev)
		txdesc->buffer_length = 0;
		if (i == 0) {
			/* Tx descriptor address set */
			writel(mdp->tx_desc_dma, ioaddr + TDLAR);
			sh_eth_write(ndev, mdp->tx_desc_dma, TDLAR);
#if defined(CONFIG_CPU_SUBTYPE_SH7763)
			writel(mdp->tx_desc_dma, ioaddr + TDFAR);
			sh_eth_write(ndev, mdp->tx_desc_dma, TDFAR);
#endif
		}
	}
@@ -620,7 +606,6 @@ static int sh_eth_dev_init(struct net_device *ndev)
{
	int ret = 0;
	struct sh_eth_private *mdp = netdev_priv(ndev);
	u32 ioaddr = ndev->base_addr;
	u_int32_t rx_int_var, tx_int_var;
	u32 val;

@@ -630,71 +615,71 @@ static int sh_eth_dev_init(struct net_device *ndev)
	/* Descriptor format */
	sh_eth_ring_format(ndev);
	if (mdp->cd->rpadir)
		writel(mdp->cd->rpadir_value, ioaddr + RPADIR);
		sh_eth_write(ndev, mdp->cd->rpadir_value, RPADIR);

	/* all sh_eth int mask */
	writel(0, ioaddr + EESIPR);
	sh_eth_write(ndev, 0, EESIPR);

#if defined(__LITTLE_ENDIAN__)
	if (mdp->cd->hw_swap)
		writel(EDMR_EL, ioaddr + EDMR);
		sh_eth_write(ndev, EDMR_EL, EDMR);
	else
#endif
		writel(0, ioaddr + EDMR);
		sh_eth_write(ndev, 0, EDMR);

	/* FIFO size set */
	writel(mdp->cd->fdr_value, ioaddr + FDR);
	writel(0, ioaddr + TFTR);
	sh_eth_write(ndev, mdp->cd->fdr_value, FDR);
	sh_eth_write(ndev, 0, TFTR);

	/* Frame recv control */
	writel(mdp->cd->rmcr_value, ioaddr + RMCR);
	sh_eth_write(ndev, mdp->cd->rmcr_value, RMCR);

	rx_int_var = mdp->rx_int_var = DESC_I_RINT8 | DESC_I_RINT5;
	tx_int_var = mdp->tx_int_var = DESC_I_TINT2;
	writel(rx_int_var | tx_int_var, ioaddr + TRSCER);
	sh_eth_write(ndev, rx_int_var | tx_int_var, TRSCER);

	if (mdp->cd->bculr)
		writel(0x800, ioaddr + BCULR);	/* Burst sycle set */
		sh_eth_write(ndev, 0x800, BCULR);	/* Burst sycle set */

	writel(mdp->cd->fcftr_value, ioaddr + FCFTR);
	sh_eth_write(ndev, mdp->cd->fcftr_value, FCFTR);

	if (!mdp->cd->no_trimd)
		writel(0, ioaddr + TRIMD);
		sh_eth_write(ndev, 0, TRIMD);

	/* Recv frame limit set register */
	writel(RFLR_VALUE, ioaddr + RFLR);
	sh_eth_write(ndev, RFLR_VALUE, RFLR);

	writel(readl(ioaddr + EESR), ioaddr + EESR);
	writel(mdp->cd->eesipr_value, ioaddr + EESIPR);
	sh_eth_write(ndev, sh_eth_read(ndev, EESR), EESR);
	sh_eth_write(ndev, mdp->cd->eesipr_value, EESIPR);

	/* PAUSE Prohibition */
	val = (readl(ioaddr + ECMR) & ECMR_DM) |
	val = (sh_eth_read(ndev, ECMR) & ECMR_DM) |
		ECMR_ZPF | (mdp->duplex ? ECMR_DM : 0) | ECMR_TE | ECMR_RE;

	writel(val, ioaddr + ECMR);
	sh_eth_write(ndev, val, ECMR);

	if (mdp->cd->set_rate)
		mdp->cd->set_rate(ndev);

	/* E-MAC Status Register clear */
	writel(mdp->cd->ecsr_value, ioaddr + ECSR);
	sh_eth_write(ndev, mdp->cd->ecsr_value, ECSR);

	/* E-MAC Interrupt Enable register */
	writel(mdp->cd->ecsipr_value, ioaddr + ECSIPR);
	sh_eth_write(ndev, mdp->cd->ecsipr_value, ECSIPR);

	/* Set MAC address */
	update_mac_address(ndev);

	/* mask reset */
	if (mdp->cd->apr)
		writel(APR_AP, ioaddr + APR);
		sh_eth_write(ndev, APR_AP, APR);
	if (mdp->cd->mpr)
		writel(MPR_MP, ioaddr + MPR);
		sh_eth_write(ndev, MPR_MP, MPR);
	if (mdp->cd->tpauser)
		writel(TPAUSER_UNLIMITED, ioaddr + TPAUSER);
		sh_eth_write(ndev, TPAUSER_UNLIMITED, TPAUSER);

	/* Setting the Rx mode will start the Rx process. */
	writel(EDRRR_R, ioaddr + EDRRR);
	sh_eth_write(ndev, EDRRR_R, EDRRR);

	netif_start_queue(ndev);

@@ -818,38 +803,37 @@ static int sh_eth_rx(struct net_device *ndev)

	/* Restart Rx engine if stopped. */
	/* If we don't need to check status, don't. -KDU */
	if (!(readl(ndev->base_addr + EDRRR) & EDRRR_R))
		writel(EDRRR_R, ndev->base_addr + EDRRR);
	if (!(sh_eth_read(ndev, EDRRR) & EDRRR_R))
		sh_eth_write(ndev, EDRRR_R, EDRRR);

	return 0;
}

static void sh_eth_rcv_snd_disable(u32 ioaddr)
static void sh_eth_rcv_snd_disable(struct net_device *ndev)
{
	/* disable tx and rx */
	writel(readl(ioaddr + ECMR) &
		~(ECMR_RE | ECMR_TE), ioaddr + ECMR);
	sh_eth_write(ndev, sh_eth_read(ndev, ECMR) &
		~(ECMR_RE | ECMR_TE), ECMR);
}

static void sh_eth_rcv_snd_enable(u32 ioaddr)
static void sh_eth_rcv_snd_enable(struct net_device *ndev)
{
	/* enable tx and rx */
	writel(readl(ioaddr + ECMR) |
		(ECMR_RE | ECMR_TE), ioaddr + ECMR);
	sh_eth_write(ndev, sh_eth_read(ndev, ECMR) |
		(ECMR_RE | ECMR_TE), ECMR);
}

/* error control function */
static void sh_eth_error(struct net_device *ndev, int intr_status)
{
	struct sh_eth_private *mdp = netdev_priv(ndev);
	u32 ioaddr = ndev->base_addr;
	u32 felic_stat;
	u32 link_stat;
	u32 mask;

	if (intr_status & EESR_ECI) {
		felic_stat = readl(ioaddr + ECSR);
		writel(felic_stat, ioaddr + ECSR);	/* clear int */
		felic_stat = sh_eth_read(ndev, ECSR);
		sh_eth_write(ndev, felic_stat, ECSR);	/* clear int */
		if (felic_stat & ECSR_ICD)
			mdp->stats.tx_carrier_errors++;
		if (felic_stat & ECSR_LCHNG) {
@@ -860,23 +844,23 @@ static void sh_eth_error(struct net_device *ndev, int intr_status)
				else
					link_stat = PHY_ST_LINK;
			} else {
				link_stat = (readl(ioaddr + PSR));
				link_stat = (sh_eth_read(ndev, PSR));
				if (mdp->ether_link_active_low)
					link_stat = ~link_stat;
			}
			if (!(link_stat & PHY_ST_LINK))
				sh_eth_rcv_snd_disable(ioaddr);
				sh_eth_rcv_snd_disable(ndev);
			else {
				/* Link Up */
				writel(readl(ioaddr + EESIPR) &
					  ~DMAC_M_ECI, ioaddr + EESIPR);
				sh_eth_write(ndev, sh_eth_read(ndev, EESIPR) &
					  ~DMAC_M_ECI, EESIPR);
				/*clear int */
				writel(readl(ioaddr + ECSR),
					  ioaddr + ECSR);
				writel(readl(ioaddr + EESIPR) |
					  DMAC_M_ECI, ioaddr + EESIPR);
				sh_eth_write(ndev, sh_eth_read(ndev, ECSR),
					  ECSR);
				sh_eth_write(ndev, sh_eth_read(ndev, EESIPR) |
					  DMAC_M_ECI, EESIPR);
				/* enable tx and rx */
				sh_eth_rcv_snd_enable(ioaddr);
				sh_eth_rcv_snd_enable(ndev);
			}
		}
	}
@@ -917,8 +901,8 @@ static void sh_eth_error(struct net_device *ndev, int intr_status)
		/* Receive Descriptor Empty int */
		mdp->stats.rx_over_errors++;

		if (readl(ioaddr + EDRRR) ^ EDRRR_R)
			writel(EDRRR_R, ioaddr + EDRRR);
		if (sh_eth_read(ndev, EDRRR) ^ EDRRR_R)
			sh_eth_write(ndev, EDRRR_R, EDRRR);
		if (netif_msg_rx_err(mdp))
			dev_err(&ndev->dev, "Receive Descriptor Empty\n");
	}
@@ -942,7 +926,7 @@ static void sh_eth_error(struct net_device *ndev, int intr_status)
		mask &= ~EESR_ADE;
	if (intr_status & mask) {
		/* Tx error */
		u32 edtrr = readl(ndev->base_addr + EDTRR);
		u32 edtrr = sh_eth_read(ndev, EDTRR);
		/* dmesg */
		dev_err(&ndev->dev, "TX error. status=%8.8x cur_tx=%8.8x ",
				intr_status, mdp->cur_tx);
@@ -954,7 +938,7 @@ static void sh_eth_error(struct net_device *ndev, int intr_status)
		/* SH7712 BUG */
		if (edtrr ^ EDTRR_TRNS) {
			/* tx dma start */
			writel(EDTRR_TRNS, ndev->base_addr + EDTRR);
			sh_eth_write(ndev, EDTRR_TRNS, EDTRR);
		}
		/* wakeup */
		netif_wake_queue(ndev);
@@ -967,18 +951,17 @@ static irqreturn_t sh_eth_interrupt(int irq, void *netdev)
	struct sh_eth_private *mdp = netdev_priv(ndev);
	struct sh_eth_cpu_data *cd = mdp->cd;
	irqreturn_t ret = IRQ_NONE;
	u32 ioaddr, intr_status = 0;
	u32 intr_status = 0;

	ioaddr = ndev->base_addr;
	spin_lock(&mdp->lock);

	/* Get interrpt stat */
	intr_status = readl(ioaddr + EESR);
	intr_status = sh_eth_read(ndev, EESR);
	/* Clear interrupt */
	if (intr_status & (EESR_FRC | EESR_RMAF | EESR_RRF |
			EESR_RTLF | EESR_RTSF | EESR_PRE | EESR_CERF |
			cd->tx_check | cd->eesr_err_check)) {
		writel(intr_status, ioaddr + EESR);
		sh_eth_write(ndev, intr_status, EESR);
		ret = IRQ_HANDLED;
	} else
		goto other_irq;
@@ -1021,7 +1004,6 @@ static void sh_eth_adjust_link(struct net_device *ndev)
{
	struct sh_eth_private *mdp = netdev_priv(ndev);
	struct phy_device *phydev = mdp->phydev;
	u32 ioaddr = ndev->base_addr;
	int new_state = 0;

	if (phydev->link != PHY_DOWN) {
@@ -1039,8 +1021,8 @@ static void sh_eth_adjust_link(struct net_device *ndev)
				mdp->cd->set_rate(ndev);
		}
		if (mdp->link == PHY_DOWN) {
			writel((readl(ioaddr + ECMR) & ~ECMR_TXF)
					| ECMR_DM, ioaddr + ECMR);
			sh_eth_write(ndev, (sh_eth_read(ndev, ECMR) & ~ECMR_TXF)
					| ECMR_DM, ECMR);
			new_state = 1;
			mdp->link = phydev->link;
		}
@@ -1122,12 +1104,11 @@ static int sh_eth_set_settings(struct net_device *ndev,
	struct sh_eth_private *mdp = netdev_priv(ndev);
	unsigned long flags;
	int ret;
	u32 ioaddr = ndev->base_addr;

	spin_lock_irqsave(&mdp->lock, flags);

	/* disable tx and rx */
	sh_eth_rcv_snd_disable(ioaddr);
	sh_eth_rcv_snd_disable(ndev);

	ret = phy_ethtool_sset(mdp->phydev, ecmd);
	if (ret)
@@ -1145,7 +1126,7 @@ error_exit:
	mdelay(1);

	/* enable tx and rx */
	sh_eth_rcv_snd_enable(ioaddr);
	sh_eth_rcv_snd_enable(ndev);

	spin_unlock_irqrestore(&mdp->lock, flags);

@@ -1282,7 +1263,6 @@ out_free_irq:
static void sh_eth_tx_timeout(struct net_device *ndev)
{
	struct sh_eth_private *mdp = netdev_priv(ndev);
	u32 ioaddr = ndev->base_addr;
	struct sh_eth_rxdesc *rxdesc;
	int i;

@@ -1290,7 +1270,7 @@ static void sh_eth_tx_timeout(struct net_device *ndev)

	if (netif_msg_timer(mdp))
		dev_err(&ndev->dev, "%s: transmit timed out, status %8.8x,"
	       " resetting...\n", ndev->name, (int)readl(ioaddr + EESR));
	       " resetting...\n", ndev->name, (int)sh_eth_read(ndev, EESR));

	/* tx_errors count up */
	mdp->stats.tx_errors++;
@@ -1363,8 +1343,8 @@ static int sh_eth_start_xmit(struct sk_buff *skb, struct net_device *ndev)

	mdp->cur_tx++;

	if (!(readl(ndev->base_addr + EDTRR) & EDTRR_TRNS))
		writel(EDTRR_TRNS, ndev->base_addr + EDTRR);
	if (!(sh_eth_read(ndev, EDTRR) & EDTRR_TRNS))
		sh_eth_write(ndev, EDTRR_TRNS, EDTRR);

	return NETDEV_TX_OK;
}
@@ -1373,17 +1353,16 @@ static int sh_eth_start_xmit(struct sk_buff *skb, struct net_device *ndev)
static int sh_eth_close(struct net_device *ndev)
{
	struct sh_eth_private *mdp = netdev_priv(ndev);
	u32 ioaddr = ndev->base_addr;
	int ringsize;

	netif_stop_queue(ndev);

	/* Disable interrupts by clearing the interrupt mask. */
	writel(0x0000, ioaddr + EESIPR);
	sh_eth_write(ndev, 0x0000, EESIPR);

	/* Stop the chip's Tx and Rx processes. */
	writel(0, ioaddr + EDTRR);
	writel(0, ioaddr + EDRRR);
	sh_eth_write(ndev, 0, EDTRR);
	sh_eth_write(ndev, 0, EDRRR);

	/* PHY Disconnect */
	if (mdp->phydev) {
@@ -1414,24 +1393,23 @@ static int sh_eth_close(struct net_device *ndev)
static struct net_device_stats *sh_eth_get_stats(struct net_device *ndev)
{
	struct sh_eth_private *mdp = netdev_priv(ndev);
	u32 ioaddr = ndev->base_addr;

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

	mdp->stats.tx_dropped += readl(ioaddr + TROCR);
	writel(0, ioaddr + TROCR);	/* (write clear) */
	mdp->stats.collisions += readl(ioaddr + CDCR);
	writel(0, ioaddr + CDCR);	/* (write clear) */
	mdp->stats.tx_carrier_errors += readl(ioaddr + LCCR);
	writel(0, ioaddr + LCCR);	/* (write clear) */
	mdp->stats.tx_dropped += sh_eth_read(ndev, TROCR);
	sh_eth_write(ndev, 0, TROCR);	/* (write clear) */
	mdp->stats.collisions += sh_eth_read(ndev, CDCR);
	sh_eth_write(ndev, 0, CDCR);	/* (write clear) */
	mdp->stats.tx_carrier_errors += sh_eth_read(ndev, LCCR);
	sh_eth_write(ndev, 0, LCCR);	/* (write clear) */
#if defined(CONFIG_CPU_SUBTYPE_SH7763)
	mdp->stats.tx_carrier_errors += readl(ioaddr + CERCR);/* CERCR */
	writel(0, ioaddr + CERCR);	/* (write clear) */
	mdp->stats.tx_carrier_errors += readl(ioaddr + CEECR);/* CEECR */
	writel(0, ioaddr + CEECR);	/* (write clear) */
	mdp->stats.tx_carrier_errors += sh_eth_read(ndev, CERCR);/* CERCR */
	sh_eth_write(ndev, 0, CERCR);	/* (write clear) */
	mdp->stats.tx_carrier_errors += sh_eth_read(ndev, CEECR);/* CEECR */
	sh_eth_write(ndev, 0, CEECR);	/* (write clear) */
#else
	mdp->stats.tx_carrier_errors += readl(ioaddr + CNDCR);
	writel(0, ioaddr + CNDCR);	/* (write clear) */
	mdp->stats.tx_carrier_errors += sh_eth_read(ndev, CNDCR);
	sh_eth_write(ndev, 0, CNDCR);	/* (write clear) */
#endif
	pm_runtime_put_sync(&mdp->pdev->dev);

@@ -1458,46 +1436,44 @@ static int sh_eth_do_ioctl(struct net_device *ndev, struct ifreq *rq,
/* Multicast reception directions set */
static void sh_eth_set_multicast_list(struct net_device *ndev)
{
	u32 ioaddr = ndev->base_addr;

	if (ndev->flags & IFF_PROMISC) {
		/* Set promiscuous. */
		writel((readl(ioaddr + ECMR) & ~ECMR_MCT) | ECMR_PRM,
			  ioaddr + ECMR);
		sh_eth_write(ndev, (sh_eth_read(ndev, ECMR) & ~ECMR_MCT) |
				ECMR_PRM, ECMR);
	} else {
		/* Normal, unicast/broadcast-only mode. */
		writel((readl(ioaddr + ECMR) & ~ECMR_PRM) | ECMR_MCT,
			  ioaddr + ECMR);
		sh_eth_write(ndev, (sh_eth_read(ndev, ECMR) & ~ECMR_PRM) |
				ECMR_MCT, ECMR);
	}
}

/* SuperH's TSU register init function */
static void sh_eth_tsu_init(u32 ioaddr)
static void sh_eth_tsu_init(struct sh_eth_private *mdp)
{
	writel(0, ioaddr + TSU_FWEN0);	/* Disable forward(0->1) */
	writel(0, ioaddr + TSU_FWEN1);	/* Disable forward(1->0) */
	writel(0, ioaddr + TSU_FCM);	/* forward fifo 3k-3k */
	writel(0xc, ioaddr + TSU_BSYSL0);
	writel(0xc, ioaddr + TSU_BSYSL1);
	writel(0, ioaddr + TSU_PRISL0);
	writel(0, ioaddr + TSU_PRISL1);
	writel(0, ioaddr + TSU_FWSL0);
	writel(0, ioaddr + TSU_FWSL1);
	writel(TSU_FWSLC_POSTENU | TSU_FWSLC_POSTENL, ioaddr + TSU_FWSLC);
	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 */
	sh_eth_tsu_write(mdp, 0xc, TSU_BSYSL0);
	sh_eth_tsu_write(mdp, 0xc, TSU_BSYSL1);
	sh_eth_tsu_write(mdp, 0, TSU_PRISL0);
	sh_eth_tsu_write(mdp, 0, TSU_PRISL1);
	sh_eth_tsu_write(mdp, 0, TSU_FWSL0);
	sh_eth_tsu_write(mdp, 0, TSU_FWSL1);
	sh_eth_tsu_write(mdp, TSU_FWSLC_POSTENU | TSU_FWSLC_POSTENL, TSU_FWSLC);
#if defined(CONFIG_CPU_SUBTYPE_SH7763)
	writel(0, ioaddr + TSU_QTAG0);	/* Disable QTAG(0->1) */
	writel(0, ioaddr + TSU_QTAG1);	/* Disable QTAG(1->0) */
	sh_eth_tsu_write(mdp, 0, TSU_QTAG0);	/* Disable QTAG(0->1) */
	sh_eth_tsu_write(mdp, 0, TSU_QTAG1);	/* Disable QTAG(1->0) */
#else
	writel(0, ioaddr + TSU_QTAGM0);	/* Disable QTAG(0->1) */
	writel(0, ioaddr + TSU_QTAGM1);	/* Disable QTAG(1->0) */
	sh_eth_tsu_write(mdp, 0, TSU_QTAGM0);	/* Disable QTAG(0->1) */
	sh_eth_tsu_write(mdp, 0, TSU_QTAGM1);	/* Disable QTAG(1->0) */
#endif
	writel(0, ioaddr + TSU_FWSR);	/* all interrupt status clear */
	writel(0, ioaddr + TSU_FWINMK);	/* Disable all interrupt */
	writel(0, ioaddr + TSU_TEN);	/* Disable all CAM entry */
	writel(0, ioaddr + TSU_POST1);	/* Disable CAM entry [ 0- 7] */
	writel(0, ioaddr + TSU_POST2);	/* Disable CAM entry [ 8-15] */
	writel(0, ioaddr + TSU_POST3);	/* Disable CAM entry [16-23] */
	writel(0, ioaddr + TSU_POST4);	/* Disable CAM entry [24-31] */
	sh_eth_tsu_write(mdp, 0, TSU_FWSR);	/* all interrupt status clear */
	sh_eth_tsu_write(mdp, 0, TSU_FWINMK);	/* Disable all interrupt */
	sh_eth_tsu_write(mdp, 0, TSU_TEN);	/* Disable all CAM entry */
	sh_eth_tsu_write(mdp, 0, TSU_POST1);	/* Disable CAM entry [ 0- 7] */
	sh_eth_tsu_write(mdp, 0, TSU_POST2);	/* Disable CAM entry [ 8-15] */
	sh_eth_tsu_write(mdp, 0, TSU_POST3);	/* Disable CAM entry [16-23] */
	sh_eth_tsu_write(mdp, 0, TSU_POST4);	/* Disable CAM entry [24-31] */
}
#endif /* SH_ETH_HAS_TSU */

@@ -1536,7 +1512,7 @@ static int sh_mdio_init(struct net_device *ndev, int id)
	}

	/* bitbang init */
	bitbang->addr = ndev->base_addr + PIR;
	bitbang->addr = ndev->base_addr + mdp->reg_offset[PIR];
	bitbang->mdi_msk = 0x08;
	bitbang->mdo_msk = 0x04;
	bitbang->mmd_msk = 0x02;/* MMD */
@@ -1587,6 +1563,28 @@ out:
	return ret;
}

static const u16 *sh_eth_get_register_offset(int register_type)
{
	const u16 *reg_offset = NULL;

	switch (register_type) {
	case SH_ETH_REG_GIGABIT:
		reg_offset = sh_eth_offset_gigabit;
		break;
	case SH_ETH_REG_FAST_SH4:
		reg_offset = sh_eth_offset_fast_sh4;
		break;
	case SH_ETH_REG_FAST_SH3_SH2:
		reg_offset = sh_eth_offset_fast_sh3_sh2;
		break;
	default:
		printk(KERN_ERR "Unknown register type (%d)\n", register_type);
		break;
	}

	return reg_offset;
}

static const struct net_device_ops sh_eth_netdev_ops = {
	.ndo_open		= sh_eth_open,
	.ndo_stop		= sh_eth_close,
@@ -1657,6 +1655,7 @@ static int sh_eth_drv_probe(struct platform_device *pdev)
	mdp->edmac_endian = pd->edmac_endian;
	mdp->no_ether_link = pd->no_ether_link;
	mdp->ether_link_active_low = pd->ether_link_active_low;
	mdp->reg_offset = sh_eth_get_register_offset(pd->register_type);

	/* set cpu data */
	mdp->cd = &sh_eth_my_cpu_data;
@@ -1682,7 +1681,8 @@ static int sh_eth_drv_probe(struct platform_device *pdev)

#if defined(SH_ETH_HAS_TSU)
		/* TSU init (Init only)*/
		sh_eth_tsu_init(SH_TSU_ADDR);
		mdp->tsu_addr = SH_TSU_ADDR;
		sh_eth_tsu_init(mdp);
#endif
	}