sh_eth: Move the Renesas SuperH driver
authorJeff Kirsher <jeffrey.t.kirsher@intel.com>
Sat, 25 Jun 2011 10:53:13 +0000 (03:53 -0700)
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>
Sat, 13 Aug 2011 06:47:36 +0000 (23:47 -0700)
Move the Renesas driver into drivers/net/ethernet/renesas/ and make
the necessary Kconfig and Makefile changes.

CC: Yoshihiro Shimoda <yoshihiro.shirmoda.uh@renesas.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
drivers/net/Kconfig
drivers/net/Makefile
drivers/net/ethernet/Kconfig
drivers/net/ethernet/Makefile
drivers/net/ethernet/renesas/Kconfig [new file with mode: 0644]
drivers/net/ethernet/renesas/Makefile [new file with mode: 0644]
drivers/net/ethernet/renesas/sh_eth.c [new file with mode: 0644]
drivers/net/ethernet/renesas/sh_eth.h [new file with mode: 0644]
drivers/net/sh_eth.c [deleted file]
drivers/net/sh_eth.h [deleted file]

index 572ddf226f12b2aea19075b6543141d751a643a2..c83a1c0f0d456641f88af29d9ea41ef6ab0501d3 100644 (file)
@@ -221,21 +221,6 @@ menuconfig NET_ETHERNET
 
 if NET_ETHERNET
 
-config SH_ETH
-       tristate "Renesas SuperH Ethernet support"
-       depends on SUPERH && \
-               (CPU_SUBTYPE_SH7710 || CPU_SUBTYPE_SH7712 || \
-                CPU_SUBTYPE_SH7763 || CPU_SUBTYPE_SH7619 || \
-                CPU_SUBTYPE_SH7724 || CPU_SUBTYPE_SH7757)
-       select CRC32
-       select MII
-       select MDIO_BITBANG
-       select PHYLIB
-       help
-         Renesas SuperH Ethernet device driver.
-         This driver supporting CPUs are:
-               - SH7710, SH7712, SH7763, SH7619, SH7724, and SH7757.
-
 config NET_PCI
        bool "EISA, VLB, PCI and on board controllers"
        depends on ISA || EISA || PCI
index 8fa5b601c6b4725c1fbd8f41d8f89617b7e0e850..620abd76e0b5257bdbb5bb3bdd7ea8753f78d6fa 100644 (file)
@@ -18,7 +18,6 @@ obj-$(CONFIG_ROADRUNNER) += rrunner.o
 
 obj-$(CONFIG_SKFP) += skfp/
 obj-$(CONFIG_RIONET) += rionet.o
-obj-$(CONFIG_SH_ETH) += sh_eth.o
 
 #
 # end link order section
index 6e3619649f5f02789ce11724435854d8ce5ecb3c..df8940d0a7c83069ad522aa2b9f6ee558c485706 100644 (file)
@@ -133,6 +133,7 @@ source "drivers/net/ethernet/pasemi/Kconfig"
 source "drivers/net/ethernet/qlogic/Kconfig"
 source "drivers/net/ethernet/racal/Kconfig"
 source "drivers/net/ethernet/realtek/Kconfig"
+source "drivers/net/ethernet/renesas/Kconfig"
 source "drivers/net/ethernet/rdc/Kconfig"
 
 config S6GMAC
index c274820ec29ba17965b4b3eb2e6048fbdda8d626..09f26b64a76a68e10a6baccab769e8edfac86191 100644 (file)
@@ -53,6 +53,7 @@ obj-$(CONFIG_NET_VENDOR_PASEMI) += pasemi/
 obj-$(CONFIG_NET_VENDOR_QLOGIC) += qlogic/
 obj-$(CONFIG_NET_VENDOR_RACAL) += racal/
 obj-$(CONFIG_NET_VENDOR_REALTEK) += realtek/
+obj-$(CONFIG_SH_ETH) += renesas/
 obj-$(CONFIG_NET_VENDOR_RDC) += rdc/
 obj-$(CONFIG_S6GMAC) += s6gmac.o
 obj-$(CONFIG_NET_VENDOR_SEEQ) += seeq/
diff --git a/drivers/net/ethernet/renesas/Kconfig b/drivers/net/ethernet/renesas/Kconfig
new file mode 100644 (file)
index 0000000..f57ae23
--- /dev/null
@@ -0,0 +1,18 @@
+#
+# Renesas device configuration
+#
+
+config SH_ETH
+       tristate "Renesas SuperH Ethernet support"
+       depends on SUPERH && \
+               (CPU_SUBTYPE_SH7710 || CPU_SUBTYPE_SH7712 || \
+                CPU_SUBTYPE_SH7763 || CPU_SUBTYPE_SH7619 || \
+                CPU_SUBTYPE_SH7724 || CPU_SUBTYPE_SH7757)
+       select CRC32
+       select MII
+       select MDIO_BITBANG
+       select PHYLIB
+       ---help---
+         Renesas SuperH Ethernet device driver.
+         This driver supporting CPUs are:
+               - SH7710, SH7712, SH7763, SH7619, SH7724, and SH7757.
diff --git a/drivers/net/ethernet/renesas/Makefile b/drivers/net/ethernet/renesas/Makefile
new file mode 100644 (file)
index 0000000..1c278a8
--- /dev/null
@@ -0,0 +1,5 @@
+#
+# Makefile for the Renesas device drivers.
+#
+
+obj-$(CONFIG_SH_ETH) += sh_eth.o
diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c
new file mode 100644 (file)
index 0000000..ad35c21
--- /dev/null
@@ -0,0 +1,1959 @@
+/*
+ *  SuperH Ethernet device driver
+ *
+ *  Copyright (C) 2006-2008 Nobuhiro Iwamatsu
+ *  Copyright (C) 2008-2009 Renesas Solutions Corp.
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms and conditions of the GNU General Public License,
+ *  version 2, as published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ *  more details.
+ *  You should have received a copy of the GNU General Public License along with
+ *  this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *  The full GNU General Public License is included in this distribution in
+ *  the file called "COPYING".
+ */
+
+#include <linux/init.h>
+#include <linux/dma-mapping.h>
+#include <linux/etherdevice.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/mdio-bitbang.h>
+#include <linux/netdevice.h>
+#include <linux/phy.h>
+#include <linux/cache.h>
+#include <linux/io.h>
+#include <linux/pm_runtime.h>
+#include <linux/slab.h>
+#include <linux/ethtool.h>
+
+#include "sh_eth.h"
+
+#define SH_ETH_DEF_MSG_ENABLE \
+               (NETIF_MSG_LINK | \
+               NETIF_MSG_TIMER | \
+               NETIF_MSG_RX_ERR| \
+               NETIF_MSG_TX_ERR)
+
+/* There is CPU dependent code */
+#if defined(CONFIG_CPU_SUBTYPE_SH7724)
+#define SH_ETH_RESET_DEFAULT   1
+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, sh_eth_read(ndev, ECMR) & ~ECMR_RTM, ECMR);
+               break;
+       case 100:/* 100BASE */
+               sh_eth_write(ndev, sh_eth_read(ndev, ECMR) | ECMR_RTM, ECMR);
+               break;
+       default:
+               break;
+       }
+}
+
+/* SH7724 */
+static struct sh_eth_cpu_data sh_eth_my_cpu_data = {
+       .set_duplex     = sh_eth_set_duplex,
+       .set_rate       = sh_eth_set_rate,
+
+       .ecsr_value     = ECSR_PSRTO | ECSR_LCHNG | ECSR_ICD,
+       .ecsipr_value   = ECSIPR_PSRTOIP | ECSIPR_LCHNGIP | ECSIPR_ICDIP,
+       .eesipr_value   = DMAC_M_RFRMER | DMAC_M_ECI | 0x01ff009f,
+
+       .tx_check       = EESR_FTC | EESR_CND | EESR_DLC | EESR_CD | EESR_RTO,
+       .eesr_err_check = EESR_TWB | EESR_TABT | EESR_RABT | EESR_RDE |
+                         EESR_RFRMER | EESR_TFE | EESR_TDE | EESR_ECI,
+       .tx_error_check = EESR_TWB | EESR_TABT | EESR_TDE | EESR_TFE,
+
+       .apr            = 1,
+       .mpr            = 1,
+       .tpauser        = 1,
+       .hw_swap        = 1,
+       .rpadir         = 1,
+       .rpadir_value   = 0x00020000, /* NET_IP_ALIGN assumed to be 2 */
+};
+#elif defined(CONFIG_CPU_SUBTYPE_SH7757)
+#define SH_ETH_HAS_BOTH_MODULES        1
+#define SH_ETH_HAS_TSU 1
+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, 0, RTRATE);
+               break;
+       case 100:/* 100BASE */
+               sh_eth_write(ndev, 1, RTRATE);
+               break;
+       default:
+               break;
+       }
+}
+
+/* SH7757 */
+static struct sh_eth_cpu_data sh_eth_my_cpu_data = {
+       .set_duplex             = sh_eth_set_duplex,
+       .set_rate               = sh_eth_set_rate,
+
+       .eesipr_value   = DMAC_M_RFRMER | DMAC_M_ECI | 0x003fffff,
+       .rmcr_value     = 0x00000001,
+
+       .tx_check       = EESR_FTC | EESR_CND | EESR_DLC | EESR_CD | EESR_RTO,
+       .eesr_err_check = EESR_TWB | EESR_TABT | EESR_RABT | EESR_RDE |
+                         EESR_RFRMER | EESR_TFE | EESR_TDE | EESR_ECI,
+       .tx_error_check = EESR_TWB | EESR_TABT | EESR_TDE | EESR_TFE,
+
+       .apr            = 1,
+       .mpr            = 1,
+       .tpauser        = 1,
+       .hw_swap        = 1,
+       .no_ade         = 1,
+       .rpadir         = 1,
+       .rpadir_value   = 2 << 16,
+};
+
+#define SH_GIGA_ETH_BASE       0xfee00000
+#define GIGA_MALR(port)                (SH_GIGA_ETH_BASE + 0x800 * (port) + 0x05c8)
+#define GIGA_MAHR(port)                (SH_GIGA_ETH_BASE + 0x800 * (port) + 0x05c0)
+static void sh_eth_chip_reset_giga(struct net_device *ndev)
+{
+       int i;
+       unsigned long mahr[2], malr[2];
+
+       /* save MAHR and MALR */
+       for (i = 0; i < 2; i++) {
+               malr[i] = readl(GIGA_MALR(i));
+               mahr[i] = readl(GIGA_MAHR(i));
+       }
+
+       /* reset device */
+       writel(ARSTR_ARSTR, SH_GIGA_ETH_BASE + 0x1800);
+       mdelay(1);
+
+       /* restore MAHR and MALR */
+       for (i = 0; i < 2; i++) {
+               writel(malr[i], GIGA_MALR(i));
+               writel(mahr[i], GIGA_MAHR(i));
+       }
+}
+
+static int sh_eth_is_gether(struct sh_eth_private *mdp);
+static void sh_eth_reset(struct net_device *ndev)
+{
+       struct sh_eth_private *mdp = netdev_priv(ndev);
+       int cnt = 100;
+
+       if (sh_eth_is_gether(mdp)) {
+               sh_eth_write(ndev, 0x03, 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);
+       } else {
+               sh_eth_write(ndev, sh_eth_read(ndev, EDMR) | EDMR_SRST_ETHER,
+                               EDMR);
+               mdelay(3);
+               sh_eth_write(ndev, sh_eth_read(ndev, EDMR) & ~EDMR_SRST_ETHER,
+                               EDMR);
+       }
+}
+
+static void sh_eth_set_duplex_giga(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_giga(struct net_device *ndev)
+{
+       struct sh_eth_private *mdp = netdev_priv(ndev);
+
+       switch (mdp->speed) {
+       case 10: /* 10BASE */
+               sh_eth_write(ndev, 0x00000000, GECMR);
+               break;
+       case 100:/* 100BASE */
+               sh_eth_write(ndev, 0x00000010, GECMR);
+               break;
+       case 1000: /* 1000BASE */
+               sh_eth_write(ndev, 0x00000020, GECMR);
+               break;
+       default:
+               break;
+       }
+}
+
+/* SH7757(GETHERC) */
+static struct sh_eth_cpu_data sh_eth_my_cpu_data_giga = {
+       .chip_reset     = sh_eth_chip_reset_giga,
+       .set_duplex     = sh_eth_set_duplex_giga,
+       .set_rate       = sh_eth_set_rate_giga,
+
+       .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,
+       .fdr_value      = 0x0000072f,
+       .rmcr_value     = 0x00000001,
+
+       .apr            = 1,
+       .mpr            = 1,
+       .tpauser        = 1,
+       .bculr          = 1,
+       .hw_swap        = 1,
+       .rpadir         = 1,
+       .rpadir_value   = 2 << 16,
+       .no_trimd       = 1,
+       .no_ade         = 1,
+};
+
+static struct sh_eth_cpu_data *sh_eth_get_cpu_data(struct sh_eth_private *mdp)
+{
+       if (sh_eth_is_gether(mdp))
+               return &sh_eth_my_cpu_data_giga;
+       else
+               return &sh_eth_my_cpu_data;
+}
+
+#elif defined(CONFIG_CPU_SUBTYPE_SH7763)
+#define SH_ETH_HAS_TSU 1
+static void sh_eth_chip_reset(struct net_device *ndev)
+{
+       struct sh_eth_private *mdp = netdev_priv(ndev);
+
+       /* reset device */
+       sh_eth_tsu_write(mdp, ARSTR_ARSTR, ARSTR);
+       mdelay(1);
+}
+
+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;
+       }
+}
+
+/* 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,
+       .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 = {
+       .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,
+       .tsu            = 1,
+};
+#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)
+{
+       sh_eth_write(ndev, sh_eth_read(ndev, EDMR) | EDMR_SRST_ETHER, EDMR);
+       mdelay(3);
+       sh_eth_write(ndev, sh_eth_read(ndev, EDMR) & ~EDMR_SRST_ETHER, 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 */
+static inline __u32 cpu_to_edmac(struct sh_eth_private *mdp, u32 x)
+{
+       switch (mdp->edmac_endian) {
+       case EDMAC_LITTLE_ENDIAN:
+               return cpu_to_le32(x);
+       case EDMAC_BIG_ENDIAN:
+               return cpu_to_be32(x);
+       }
+       return x;
+}
+
+static inline __u32 edmac_to_cpu(struct sh_eth_private *mdp, u32 x)
+{
+       switch (mdp->edmac_endian) {
+       case EDMAC_LITTLE_ENDIAN:
+               return le32_to_cpu(x);
+       case EDMAC_BIG_ENDIAN:
+               return be32_to_cpu(x);
+       }
+       return x;
+}
+
+/*
+ * Program the hardware MAC address from dev->dev_addr.
+ */
+static void update_mac_address(struct net_device *ndev)
+{
+       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);
+}
+
+/*
+ * Get MAC address from SuperH MAC address register
+ *
+ * SuperH's Ethernet device doesn't have 'ROM' to MAC address.
+ * This driver get MAC address that use by bootloader(U-boot or sh-ipl+g).
+ * When you want use this device, you must set MAC address in bootloader.
+ *
+ */
+static void read_mac_address(struct net_device *ndev, unsigned char *mac)
+{
+       if (mac[0] || mac[1] || mac[2] || mac[3] || mac[4] || mac[5]) {
+               memcpy(ndev->dev_addr, mac, 6);
+       } else {
+               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);
+       }
+}
+
+static int sh_eth_is_gether(struct sh_eth_private *mdp)
+{
+       if (mdp->reg_offset == sh_eth_offset_gigabit)
+               return 1;
+       else
+               return 0;
+}
+
+static unsigned long sh_eth_get_edtrr_trns(struct sh_eth_private *mdp)
+{
+       if (sh_eth_is_gether(mdp))
+               return EDTRR_TRNS_GETHER;
+       else
+               return EDTRR_TRNS_ETHER;
+}
+
+struct bb_info {
+       void (*set_gate)(unsigned long addr);
+       struct mdiobb_ctrl ctrl;
+       u32 addr;
+       u32 mmd_msk;/* MMD */
+       u32 mdo_msk;
+       u32 mdi_msk;
+       u32 mdc_msk;
+};
+
+/* PHY bit set */
+static void bb_set(u32 addr, u32 msk)
+{
+       writel(readl(addr) | msk, addr);
+}
+
+/* PHY bit clear */
+static void bb_clr(u32 addr, u32 msk)
+{
+       writel((readl(addr) & ~msk), addr);
+}
+
+/* PHY bit read */
+static int bb_read(u32 addr, u32 msk)
+{
+       return (readl(addr) & msk) != 0;
+}
+
+/* Data I/O pin control */
+static void sh_mmd_ctrl(struct mdiobb_ctrl *ctrl, int bit)
+{
+       struct bb_info *bitbang = container_of(ctrl, struct bb_info, ctrl);
+
+       if (bitbang->set_gate)
+               bitbang->set_gate(bitbang->addr);
+
+       if (bit)
+               bb_set(bitbang->addr, bitbang->mmd_msk);
+       else
+               bb_clr(bitbang->addr, bitbang->mmd_msk);
+}
+
+/* Set bit data*/
+static void sh_set_mdio(struct mdiobb_ctrl *ctrl, int bit)
+{
+       struct bb_info *bitbang = container_of(ctrl, struct bb_info, ctrl);
+
+       if (bitbang->set_gate)
+               bitbang->set_gate(bitbang->addr);
+
+       if (bit)
+               bb_set(bitbang->addr, bitbang->mdo_msk);
+       else
+               bb_clr(bitbang->addr, bitbang->mdo_msk);
+}
+
+/* Get bit data*/
+static int sh_get_mdio(struct mdiobb_ctrl *ctrl)
+{
+       struct bb_info *bitbang = container_of(ctrl, struct bb_info, ctrl);
+
+       if (bitbang->set_gate)
+               bitbang->set_gate(bitbang->addr);
+
+       return bb_read(bitbang->addr, bitbang->mdi_msk);
+}
+
+/* MDC pin control */
+static void sh_mdc_ctrl(struct mdiobb_ctrl *ctrl, int bit)
+{
+       struct bb_info *bitbang = container_of(ctrl, struct bb_info, ctrl);
+
+       if (bitbang->set_gate)
+               bitbang->set_gate(bitbang->addr);
+
+       if (bit)
+               bb_set(bitbang->addr, bitbang->mdc_msk);
+       else
+               bb_clr(bitbang->addr, bitbang->mdc_msk);
+}
+
+/* mdio bus control struct */
+static struct mdiobb_ops bb_ops = {
+       .owner = THIS_MODULE,
+       .set_mdc = sh_mdc_ctrl,
+       .set_mdio_dir = sh_mmd_ctrl,
+       .set_mdio_data = sh_set_mdio,
+       .get_mdio_data = sh_get_mdio,
+};
+
+/* free skb and descriptor buffer */
+static void sh_eth_ring_free(struct net_device *ndev)
+{
+       struct sh_eth_private *mdp = netdev_priv(ndev);
+       int i;
+
+       /* Free Rx skb ringbuffer */
+       if (mdp->rx_skbuff) {
+               for (i = 0; i < RX_RING_SIZE; i++) {
+                       if (mdp->rx_skbuff[i])
+                               dev_kfree_skb(mdp->rx_skbuff[i]);
+               }
+       }
+       kfree(mdp->rx_skbuff);
+
+       /* Free Tx skb ringbuffer */
+       if (mdp->tx_skbuff) {
+               for (i = 0; i < TX_RING_SIZE; i++) {
+                       if (mdp->tx_skbuff[i])
+                               dev_kfree_skb(mdp->tx_skbuff[i]);
+               }
+       }
+       kfree(mdp->tx_skbuff);
+}
+
+/* format skb and descriptor buffer */
+static void sh_eth_ring_format(struct net_device *ndev)
+{
+       struct sh_eth_private *mdp = netdev_priv(ndev);
+       int i;
+       struct sk_buff *skb;
+       struct sh_eth_rxdesc *rxdesc = NULL;
+       struct sh_eth_txdesc *txdesc = NULL;
+       int rx_ringsize = sizeof(*rxdesc) * RX_RING_SIZE;
+       int tx_ringsize = sizeof(*txdesc) * TX_RING_SIZE;
+
+       mdp->cur_rx = mdp->cur_tx = 0;
+       mdp->dirty_rx = mdp->dirty_tx = 0;
+
+       memset(mdp->rx_ring, 0, rx_ringsize);
+
+       /* build Rx ring buffer */
+       for (i = 0; i < RX_RING_SIZE; i++) {
+               /* skb */
+               mdp->rx_skbuff[i] = NULL;
+               skb = dev_alloc_skb(mdp->rx_buf_sz);
+               mdp->rx_skbuff[i] = skb;
+               if (skb == NULL)
+                       break;
+               dma_map_single(&ndev->dev, skb->tail, mdp->rx_buf_sz,
+                               DMA_FROM_DEVICE);
+               skb->dev = ndev; /* Mark as being used by this device. */
+               sh_eth_set_receive_align(skb);
+
+               /* RX descriptor */
+               rxdesc = &mdp->rx_ring[i];
+               rxdesc->addr = virt_to_phys(PTR_ALIGN(skb->data, 4));
+               rxdesc->status = cpu_to_edmac(mdp, RD_RACT | RD_RFP);
+
+               /* The size of the buffer is 16 byte boundary. */
+               rxdesc->buffer_length = ALIGN(mdp->rx_buf_sz, 16);
+               /* Rx descriptor address set */
+               if (i == 0) {
+                       sh_eth_write(ndev, mdp->rx_desc_dma, RDLAR);
+                       if (sh_eth_is_gether(mdp))
+                               sh_eth_write(ndev, mdp->rx_desc_dma, RDFAR);
+               }
+       }
+
+       mdp->dirty_rx = (u32) (i - RX_RING_SIZE);
+
+       /* Mark the last entry as wrapping the ring. */
+       rxdesc->status |= cpu_to_edmac(mdp, RD_RDEL);
+
+       memset(mdp->tx_ring, 0, tx_ringsize);
+
+       /* build Tx ring buffer */
+       for (i = 0; i < TX_RING_SIZE; i++) {
+               mdp->tx_skbuff[i] = NULL;
+               txdesc = &mdp->tx_ring[i];
+               txdesc->status = cpu_to_edmac(mdp, TD_TFP);
+               txdesc->buffer_length = 0;
+               if (i == 0) {
+                       /* Tx descriptor address set */
+                       sh_eth_write(ndev, mdp->tx_desc_dma, TDLAR);
+                       if (sh_eth_is_gether(mdp))
+                               sh_eth_write(ndev, mdp->tx_desc_dma, TDFAR);
+               }
+       }
+
+       txdesc->status |= cpu_to_edmac(mdp, TD_TDLE);
+}
+
+/* Get skb and descriptor buffer */
+static int sh_eth_ring_init(struct net_device *ndev)
+{
+       struct sh_eth_private *mdp = netdev_priv(ndev);
+       int rx_ringsize, tx_ringsize, ret = 0;
+
+       /*
+        * +26 gets the maximum ethernet encapsulation, +7 & ~7 because the
+        * card needs room to do 8 byte alignment, +2 so we can reserve
+        * the first 2 bytes, and +16 gets room for the status word from the
+        * card.
+        */
+       mdp->rx_buf_sz = (ndev->mtu <= 1492 ? PKT_BUF_SZ :
+                         (((ndev->mtu + 26 + 7) & ~7) + 2 + 16));
+       if (mdp->cd->rpadir)
+               mdp->rx_buf_sz += NET_IP_ALIGN;
+
+       /* Allocate RX and TX skb rings */
+       mdp->rx_skbuff = kmalloc(sizeof(*mdp->rx_skbuff) * RX_RING_SIZE,
+                               GFP_KERNEL);
+       if (!mdp->rx_skbuff) {
+               dev_err(&ndev->dev, "Cannot allocate Rx skb\n");
+               ret = -ENOMEM;
+               return ret;
+       }
+
+       mdp->tx_skbuff = kmalloc(sizeof(*mdp->tx_skbuff) * TX_RING_SIZE,
+                               GFP_KERNEL);
+       if (!mdp->tx_skbuff) {
+               dev_err(&ndev->dev, "Cannot allocate Tx skb\n");
+               ret = -ENOMEM;
+               goto skb_ring_free;
+       }
+
+       /* Allocate all Rx descriptors. */
+       rx_ringsize = sizeof(struct sh_eth_rxdesc) * RX_RING_SIZE;
+       mdp->rx_ring = dma_alloc_coherent(NULL, rx_ringsize, &mdp->rx_desc_dma,
+                       GFP_KERNEL);
+
+       if (!mdp->rx_ring) {
+               dev_err(&ndev->dev, "Cannot allocate Rx Ring (size %d bytes)\n",
+                       rx_ringsize);
+               ret = -ENOMEM;
+               goto desc_ring_free;
+       }
+
+       mdp->dirty_rx = 0;
+
+       /* Allocate all Tx descriptors. */
+       tx_ringsize = sizeof(struct sh_eth_txdesc) * TX_RING_SIZE;
+       mdp->tx_ring = dma_alloc_coherent(NULL, tx_ringsize, &mdp->tx_desc_dma,
+                       GFP_KERNEL);
+       if (!mdp->tx_ring) {
+               dev_err(&ndev->dev, "Cannot allocate Tx Ring (size %d bytes)\n",
+                       tx_ringsize);
+               ret = -ENOMEM;
+               goto desc_ring_free;
+       }
+       return ret;
+
+desc_ring_free:
+       /* free DMA buffer */
+       dma_free_coherent(NULL, rx_ringsize, mdp->rx_ring, mdp->rx_desc_dma);
+
+skb_ring_free:
+       /* Free Rx and Tx skb ring buffer */
+       sh_eth_ring_free(ndev);
+
+       return ret;
+}
+
+static int sh_eth_dev_init(struct net_device *ndev)
+{
+       int ret = 0;
+       struct sh_eth_private *mdp = netdev_priv(ndev);
+       u_int32_t rx_int_var, tx_int_var;
+       u32 val;
+
+       /* Soft Reset */
+       sh_eth_reset(ndev);
+
+       /* Descriptor format */
+       sh_eth_ring_format(ndev);
+       if (mdp->cd->rpadir)
+               sh_eth_write(ndev, mdp->cd->rpadir_value, RPADIR);
+
+       /* all sh_eth int mask */
+       sh_eth_write(ndev, 0, EESIPR);
+
+#if defined(__LITTLE_ENDIAN__)
+       if (mdp->cd->hw_swap)
+               sh_eth_write(ndev, EDMR_EL, EDMR);
+       else
+#endif
+               sh_eth_write(ndev, 0, EDMR);
+
+       /* FIFO size set */
+       sh_eth_write(ndev, mdp->cd->fdr_value, FDR);
+       sh_eth_write(ndev, 0, TFTR);
+
+       /* Frame recv control */
+       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;
+       sh_eth_write(ndev, rx_int_var | tx_int_var, TRSCER);
+
+       if (mdp->cd->bculr)
+               sh_eth_write(ndev, 0x800, BCULR);       /* Burst sycle set */
+
+       sh_eth_write(ndev, mdp->cd->fcftr_value, FCFTR);
+
+       if (!mdp->cd->no_trimd)
+               sh_eth_write(ndev, 0, TRIMD);
+
+       /* Recv frame limit set register */
+       sh_eth_write(ndev, RFLR_VALUE, RFLR);
+
+       sh_eth_write(ndev, sh_eth_read(ndev, EESR), EESR);
+       sh_eth_write(ndev, mdp->cd->eesipr_value, EESIPR);
+
+       /* PAUSE Prohibition */
+       val = (sh_eth_read(ndev, ECMR) & ECMR_DM) |
+               ECMR_ZPF | (mdp->duplex ? ECMR_DM : 0) | ECMR_TE | ECMR_RE;
+
+       sh_eth_write(ndev, val, ECMR);
+
+       if (mdp->cd->set_rate)
+               mdp->cd->set_rate(ndev);
+
+       /* E-MAC Status Register clear */
+       sh_eth_write(ndev, mdp->cd->ecsr_value, ECSR);
+
+       /* E-MAC Interrupt Enable register */
+       sh_eth_write(ndev, mdp->cd->ecsipr_value, ECSIPR);
+
+       /* Set MAC address */
+       update_mac_address(ndev);
+
+       /* mask reset */
+       if (mdp->cd->apr)
+               sh_eth_write(ndev, APR_AP, APR);
+       if (mdp->cd->mpr)
+               sh_eth_write(ndev, MPR_MP, MPR);
+       if (mdp->cd->tpauser)
+               sh_eth_write(ndev, TPAUSER_UNLIMITED, TPAUSER);
+
+       /* Setting the Rx mode will start the Rx process. */
+       sh_eth_write(ndev, EDRRR_R, EDRRR);
+
+       netif_start_queue(ndev);
+
+       return ret;
+}
+
+/* free Tx skb function */
+static int sh_eth_txfree(struct net_device *ndev)
+{
+       struct sh_eth_private *mdp = netdev_priv(ndev);
+       struct sh_eth_txdesc *txdesc;
+       int freeNum = 0;
+       int entry = 0;
+
+       for (; mdp->cur_tx - mdp->dirty_tx > 0; mdp->dirty_tx++) {
+               entry = mdp->dirty_tx % TX_RING_SIZE;
+               txdesc = &mdp->tx_ring[entry];
+               if (txdesc->status & cpu_to_edmac(mdp, TD_TACT))
+                       break;
+               /* Free the original skb. */
+               if (mdp->tx_skbuff[entry]) {
+                       dma_unmap_single(&ndev->dev, txdesc->addr,
+                                        txdesc->buffer_length, DMA_TO_DEVICE);
+                       dev_kfree_skb_irq(mdp->tx_skbuff[entry]);
+                       mdp->tx_skbuff[entry] = NULL;
+                       freeNum++;
+               }
+               txdesc->status = cpu_to_edmac(mdp, TD_TFP);
+               if (entry >= TX_RING_SIZE - 1)
+                       txdesc->status |= cpu_to_edmac(mdp, TD_TDLE);
+
+               mdp->stats.tx_packets++;
+               mdp->stats.tx_bytes += txdesc->buffer_length;
+       }
+       return freeNum;
+}
+
+/* Packet receive function */
+static int sh_eth_rx(struct net_device *ndev)
+{
+       struct sh_eth_private *mdp = netdev_priv(ndev);
+       struct sh_eth_rxdesc *rxdesc;
+
+       int entry = mdp->cur_rx % RX_RING_SIZE;
+       int boguscnt = (mdp->dirty_rx + RX_RING_SIZE) - mdp->cur_rx;
+       struct sk_buff *skb;
+       u16 pkt_len = 0;
+       u32 desc_status;
+
+       rxdesc = &mdp->rx_ring[entry];
+       while (!(rxdesc->status & cpu_to_edmac(mdp, RD_RACT))) {
+               desc_status = edmac_to_cpu(mdp, rxdesc->status);
+               pkt_len = rxdesc->frame_length;
+
+               if (--boguscnt < 0)
+                       break;
+
+               if (!(desc_status & RDFEND))
+                       mdp->stats.rx_length_errors++;
+
+               if (desc_status & (RD_RFS1 | RD_RFS2 | RD_RFS3 | RD_RFS4 |
+                                  RD_RFS5 | RD_RFS6 | RD_RFS10)) {
+                       mdp->stats.rx_errors++;
+                       if (desc_status & RD_RFS1)
+                               mdp->stats.rx_crc_errors++;
+                       if (desc_status & RD_RFS2)
+                               mdp->stats.rx_frame_errors++;
+                       if (desc_status & RD_RFS3)
+                               mdp->stats.rx_length_errors++;
+                       if (desc_status & RD_RFS4)
+                               mdp->stats.rx_length_errors++;
+                       if (desc_status & RD_RFS6)
+                               mdp->stats.rx_missed_errors++;
+                       if (desc_status & RD_RFS10)
+                               mdp->stats.rx_over_errors++;
+               } else {
+                       if (!mdp->cd->hw_swap)
+                               sh_eth_soft_swap(
+                                       phys_to_virt(ALIGN(rxdesc->addr, 4)),
+                                       pkt_len + 2);
+                       skb = mdp->rx_skbuff[entry];
+                       mdp->rx_skbuff[entry] = NULL;
+                       if (mdp->cd->rpadir)
+                               skb_reserve(skb, NET_IP_ALIGN);
+                       skb_put(skb, pkt_len);
+                       skb->protocol = eth_type_trans(skb, ndev);
+                       netif_rx(skb);
+                       mdp->stats.rx_packets++;
+                       mdp->stats.rx_bytes += pkt_len;
+               }
+               rxdesc->status |= cpu_to_edmac(mdp, RD_RACT);
+               entry = (++mdp->cur_rx) % RX_RING_SIZE;
+               rxdesc = &mdp->rx_ring[entry];
+       }
+
+       /* Refill the Rx ring buffers. */
+       for (; mdp->cur_rx - mdp->dirty_rx > 0; mdp->dirty_rx++) {
+               entry = mdp->dirty_rx % RX_RING_SIZE;
+               rxdesc = &mdp->rx_ring[entry];
+               /* The size of the buffer is 16 byte boundary. */
+               rxdesc->buffer_length = ALIGN(mdp->rx_buf_sz, 16);
+
+               if (mdp->rx_skbuff[entry] == NULL) {
+                       skb = dev_alloc_skb(mdp->rx_buf_sz);
+                       mdp->rx_skbuff[entry] = skb;
+                       if (skb == NULL)
+                               break;  /* Better luck next round. */
+                       dma_map_single(&ndev->dev, skb->tail, mdp->rx_buf_sz,
+                                       DMA_FROM_DEVICE);
+                       skb->dev = ndev;
+                       sh_eth_set_receive_align(skb);
+
+                       skb_checksum_none_assert(skb);
+                       rxdesc->addr = virt_to_phys(PTR_ALIGN(skb->data, 4));
+               }
+               if (entry >= RX_RING_SIZE - 1)
+                       rxdesc->status |=
+                               cpu_to_edmac(mdp, RD_RACT | RD_RFP | RD_RDEL);
+               else
+                       rxdesc->status |=
+                               cpu_to_edmac(mdp, RD_RACT | RD_RFP);
+       }
+
+       /* Restart Rx engine if stopped. */
+       /* If we don't need to check status, don't. -KDU */
+       if (!(sh_eth_read(ndev, EDRRR) & EDRRR_R))
+               sh_eth_write(ndev, EDRRR_R, EDRRR);
+
+       return 0;
+}
+
+static void sh_eth_rcv_snd_disable(struct net_device *ndev)
+{
+       /* disable tx and rx */
+       sh_eth_write(ndev, sh_eth_read(ndev, ECMR) &
+               ~(ECMR_RE | ECMR_TE), ECMR);
+}
+
+static void sh_eth_rcv_snd_enable(struct net_device *ndev)
+{
+       /* enable tx and rx */
+       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 felic_stat;
+       u32 link_stat;
+       u32 mask;
+
+       if (intr_status & EESR_ECI) {
+               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) {
+                       /* Link Changed */
+                       if (mdp->cd->no_psr || mdp->no_ether_link) {
+                               if (mdp->link == PHY_DOWN)
+                                       link_stat = 0;
+                               else
+                                       link_stat = PHY_ST_LINK;
+                       } else {
+                               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(ndev);
+                       else {
+                               /* Link Up */
+                               sh_eth_write(ndev, sh_eth_read(ndev, EESIPR) &
+                                         ~DMAC_M_ECI, EESIPR);
+                               /*clear int */
+                               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(ndev);
+                       }
+               }
+       }
+
+       if (intr_status & EESR_TWB) {
+               /* Write buck end. unused write back interrupt */
+               if (intr_status & EESR_TABT)    /* Transmit Abort int */
+                       mdp->stats.tx_aborted_errors++;
+                       if (netif_msg_tx_err(mdp))
+                               dev_err(&ndev->dev, "Transmit Abort\n");
+       }
+
+       if (intr_status & EESR_RABT) {
+               /* Receive Abort int */
+               if (intr_status & EESR_RFRMER) {
+                       /* Receive Frame Overflow int */
+                       mdp->stats.rx_frame_errors++;
+                       if (netif_msg_rx_err(mdp))
+                               dev_err(&ndev->dev, "Receive Abort\n");
+               }
+       }
+
+       if (intr_status & EESR_TDE) {
+               /* Transmit Descriptor Empty int */
+               mdp->stats.tx_fifo_errors++;
+               if (netif_msg_tx_err(mdp))
+                       dev_err(&ndev->dev, "Transmit Descriptor Empty\n");
+       }
+
+       if (intr_status & EESR_TFE) {
+               /* FIFO under flow */
+               mdp->stats.tx_fifo_errors++;
+               if (netif_msg_tx_err(mdp))
+                       dev_err(&ndev->dev, "Transmit FIFO Under flow\n");
+       }
+
+       if (intr_status & EESR_RDE) {
+               /* Receive Descriptor Empty int */
+               mdp->stats.rx_over_errors++;
+
+               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");
+       }
+
+       if (intr_status & EESR_RFE) {
+               /* Receive FIFO Overflow int */
+               mdp->stats.rx_fifo_errors++;
+               if (netif_msg_rx_err(mdp))
+                       dev_err(&ndev->dev, "Receive FIFO Overflow\n");
+       }
+
+       if (!mdp->cd->no_ade && (intr_status & EESR_ADE)) {
+               /* Address Error */
+               mdp->stats.tx_fifo_errors++;
+               if (netif_msg_tx_err(mdp))
+                       dev_err(&ndev->dev, "Address Error\n");
+       }
+
+       mask = EESR_TWB | EESR_TABT | EESR_ADE | EESR_TDE | EESR_TFE;
+       if (mdp->cd->no_ade)
+               mask &= ~EESR_ADE;
+       if (intr_status & mask) {
+               /* Tx error */
+               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);
+               dev_err(&ndev->dev, "dirty_tx=%8.8x state=%8.8x EDTRR=%8.8x.\n",
+                               mdp->dirty_tx, (u32) ndev->state, edtrr);
+               /* dirty buffer free */
+               sh_eth_txfree(ndev);
+
+               /* SH7712 BUG */
+               if (edtrr ^ sh_eth_get_edtrr_trns(mdp)) {
+                       /* tx dma start */
+                       sh_eth_write(ndev, sh_eth_get_edtrr_trns(mdp), EDTRR);
+               }
+               /* wakeup */
+               netif_wake_queue(ndev);
+       }
+}
+
+static irqreturn_t sh_eth_interrupt(int irq, void *netdev)
+{
+       struct net_device *ndev = netdev;
+       struct sh_eth_private *mdp = netdev_priv(ndev);
+       struct sh_eth_cpu_data *cd = mdp->cd;
+       irqreturn_t ret = IRQ_NONE;
+       u32 intr_status = 0;
+
+       spin_lock(&mdp->lock);
+
+       /* Get interrpt stat */
+       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)) {
+               sh_eth_write(ndev, intr_status, EESR);
+               ret = IRQ_HANDLED;
+       } else
+               goto other_irq;
+
+       if (intr_status & (EESR_FRC | /* Frame recv*/
+                       EESR_RMAF | /* Multi cast address recv*/
+                       EESR_RRF  | /* Bit frame recv */
+                       EESR_RTLF | /* Long frame recv*/
+                       EESR_RTSF | /* short frame recv */
+                       EESR_PRE  | /* PHY-LSI recv error */
+                       EESR_CERF)){ /* recv frame CRC error */
+               sh_eth_rx(ndev);
+       }
+
+       /* Tx Check */
+       if (intr_status & cd->tx_check) {
+               sh_eth_txfree(ndev);
+               netif_wake_queue(ndev);
+       }
+
+       if (intr_status & cd->eesr_err_check)
+               sh_eth_error(ndev, intr_status);
+
+other_irq:
+       spin_unlock(&mdp->lock);
+
+       return ret;
+}
+
+static void sh_eth_timer(unsigned long data)
+{
+       struct net_device *ndev = (struct net_device *)data;
+       struct sh_eth_private *mdp = netdev_priv(ndev);
+
+       mod_timer(&mdp->timer, jiffies + (10 * HZ));
+}
+
+/* PHY state control function */
+static void sh_eth_adjust_link(struct net_device *ndev)
+{
+       struct sh_eth_private *mdp = netdev_priv(ndev);
+       struct phy_device *phydev = mdp->phydev;
+       int new_state = 0;
+
+       if (phydev->link != PHY_DOWN) {
+               if (phydev->duplex != mdp->duplex) {
+                       new_state = 1;
+                       mdp->duplex = phydev->duplex;
+                       if (mdp->cd->set_duplex)
+                               mdp->cd->set_duplex(ndev);
+               }
+
+               if (phydev->speed != mdp->speed) {
+                       new_state = 1;
+                       mdp->speed = phydev->speed;
+                       if (mdp->cd->set_rate)
+                               mdp->cd->set_rate(ndev);
+               }
+               if (mdp->link == PHY_DOWN) {
+                       sh_eth_write(ndev,
+                               (sh_eth_read(ndev, ECMR) & ~ECMR_TXF), ECMR);
+                       new_state = 1;
+                       mdp->link = phydev->link;
+               }
+       } else if (mdp->link) {
+               new_state = 1;
+               mdp->link = PHY_DOWN;
+               mdp->speed = 0;
+               mdp->duplex = -1;
+       }
+
+       if (new_state && netif_msg_link(mdp))
+               phy_print_status(phydev);
+}
+
+/* PHY init function */
+static int sh_eth_phy_init(struct net_device *ndev)
+{
+       struct sh_eth_private *mdp = netdev_priv(ndev);
+       char phy_id[MII_BUS_ID_SIZE + 3];
+       struct phy_device *phydev = NULL;
+
+       snprintf(phy_id, sizeof(phy_id), PHY_ID_FMT,
+               mdp->mii_bus->id , mdp->phy_id);
+
+       mdp->link = PHY_DOWN;
+       mdp->speed = 0;
+       mdp->duplex = -1;
+
+       /* Try connect to PHY */
+       phydev = phy_connect(ndev, phy_id, sh_eth_adjust_link,
+                               0, mdp->phy_interface);
+       if (IS_ERR(phydev)) {
+               dev_err(&ndev->dev, "phy_connect failed\n");
+               return PTR_ERR(phydev);
+       }
+
+       dev_info(&ndev->dev, "attached phy %i to driver %s\n",
+               phydev->addr, phydev->drv->name);
+
+       mdp->phydev = phydev;
+
+       return 0;
+}
+
+/* PHY control start function */
+static int sh_eth_phy_start(struct net_device *ndev)
+{
+       struct sh_eth_private *mdp = netdev_priv(ndev);
+       int ret;
+
+       ret = sh_eth_phy_init(ndev);
+       if (ret)
+               return ret;
+
+       /* reset phy - this also wakes it from PDOWN */
+       phy_write(mdp->phydev, MII_BMCR, BMCR_RESET);
+       phy_start(mdp->phydev);
+
+       return 0;
+}
+
+static int sh_eth_get_settings(struct net_device *ndev,
+                       struct ethtool_cmd *ecmd)
+{
+       struct sh_eth_private *mdp = netdev_priv(ndev);
+       unsigned long flags;
+       int ret;
+
+       spin_lock_irqsave(&mdp->lock, flags);
+       ret = phy_ethtool_gset(mdp->phydev, ecmd);
+       spin_unlock_irqrestore(&mdp->lock, flags);
+
+       return ret;
+}
+
+static int sh_eth_set_settings(struct net_device *ndev,
+               struct ethtool_cmd *ecmd)
+{
+       struct sh_eth_private *mdp = netdev_priv(ndev);
+       unsigned long flags;
+       int ret;
+
+       spin_lock_irqsave(&mdp->lock, flags);
+
+       /* disable tx and rx */
+       sh_eth_rcv_snd_disable(ndev);
+
+       ret = phy_ethtool_sset(mdp->phydev, ecmd);
+       if (ret)
+               goto error_exit;
+
+       if (ecmd->duplex == DUPLEX_FULL)
+               mdp->duplex = 1;
+       else
+               mdp->duplex = 0;
+
+       if (mdp->cd->set_duplex)
+               mdp->cd->set_duplex(ndev);
+
+error_exit:
+       mdelay(1);
+
+       /* enable tx and rx */
+       sh_eth_rcv_snd_enable(ndev);
+
+       spin_unlock_irqrestore(&mdp->lock, flags);
+
+       return ret;
+}
+
+static int sh_eth_nway_reset(struct net_device *ndev)
+{
+       struct sh_eth_private *mdp = netdev_priv(ndev);
+       unsigned long flags;
+       int ret;
+
+       spin_lock_irqsave(&mdp->lock, flags);
+       ret = phy_start_aneg(mdp->phydev);
+       spin_unlock_irqrestore(&mdp->lock, flags);
+
+       return ret;
+}
+
+static u32 sh_eth_get_msglevel(struct net_device *ndev)
+{
+       struct sh_eth_private *mdp = netdev_priv(ndev);
+       return mdp->msg_enable;
+}
+
+static void sh_eth_set_msglevel(struct net_device *ndev, u32 value)
+{
+       struct sh_eth_private *mdp = netdev_priv(ndev);
+       mdp->msg_enable = value;
+}
+
+static const char sh_eth_gstrings_stats[][ETH_GSTRING_LEN] = {
+       "rx_current", "tx_current",
+       "rx_dirty", "tx_dirty",
+};
+#define SH_ETH_STATS_LEN  ARRAY_SIZE(sh_eth_gstrings_stats)
+
+static int sh_eth_get_sset_count(struct net_device *netdev, int sset)
+{
+       switch (sset) {
+       case ETH_SS_STATS:
+               return SH_ETH_STATS_LEN;
+       default:
+               return -EOPNOTSUPP;
+       }
+}
+
+static void sh_eth_get_ethtool_stats(struct net_device *ndev,
+                       struct ethtool_stats *stats, u64 *data)
+{
+       struct sh_eth_private *mdp = netdev_priv(ndev);
+       int i = 0;
+
+       /* device-specific stats */
+       data[i++] = mdp->cur_rx;
+       data[i++] = mdp->cur_tx;
+       data[i++] = mdp->dirty_rx;
+       data[i++] = mdp->dirty_tx;
+}
+
+static void sh_eth_get_strings(struct net_device *ndev, u32 stringset, u8 *data)
+{
+       switch (stringset) {
+       case ETH_SS_STATS:
+               memcpy(data, *sh_eth_gstrings_stats,
+                                       sizeof(sh_eth_gstrings_stats));
+               break;
+       }
+}
+
+static struct ethtool_ops sh_eth_ethtool_ops = {
+       .get_settings   = sh_eth_get_settings,
+       .set_settings   = sh_eth_set_settings,
+       .nway_reset             = sh_eth_nway_reset,
+       .get_msglevel   = sh_eth_get_msglevel,
+       .set_msglevel   = sh_eth_set_msglevel,
+       .get_link               = ethtool_op_get_link,
+       .get_strings    = sh_eth_get_strings,
+       .get_ethtool_stats  = sh_eth_get_ethtool_stats,
+       .get_sset_count     = sh_eth_get_sset_count,
+};
+
+/* network device open function */
+static int sh_eth_open(struct net_device *ndev)
+{
+       int ret = 0;
+       struct sh_eth_private *mdp = netdev_priv(ndev);
+
+       pm_runtime_get_sync(&mdp->pdev->dev);
+
+       ret = request_irq(ndev->irq, sh_eth_interrupt,
+#if defined(CONFIG_CPU_SUBTYPE_SH7763) || \
+       defined(CONFIG_CPU_SUBTYPE_SH7764) || \
+       defined(CONFIG_CPU_SUBTYPE_SH7757)
+                               IRQF_SHARED,
+#else
+                               0,
+#endif
+                               ndev->name, ndev);
+       if (ret) {
+               dev_err(&ndev->dev, "Can not assign IRQ number\n");
+               return ret;
+       }
+
+       /* Descriptor set */
+       ret = sh_eth_ring_init(ndev);
+       if (ret)
+               goto out_free_irq;
+
+       /* device init */
+       ret = sh_eth_dev_init(ndev);
+       if (ret)
+               goto out_free_irq;
+
+       /* PHY control start*/
+       ret = sh_eth_phy_start(ndev);
+       if (ret)
+               goto out_free_irq;
+
+       /* Set the timer to check for link beat. */
+       init_timer(&mdp->timer);
+       mdp->timer.expires = (jiffies + (24 * HZ)) / 10;/* 2.4 sec. */
+       setup_timer(&mdp->timer, sh_eth_timer, (unsigned long)ndev);
+
+       return ret;
+
+out_free_irq:
+       free_irq(ndev->irq, ndev);
+       pm_runtime_put_sync(&mdp->pdev->dev);
+       return ret;
+}
+
+/* Timeout function */
+static void sh_eth_tx_timeout(struct net_device *ndev)
+{
+       struct sh_eth_private *mdp = netdev_priv(ndev);
+       struct sh_eth_rxdesc *rxdesc;
+       int i;
+
+       netif_stop_queue(ndev);
+
+       if (netif_msg_timer(mdp))
+               dev_err(&ndev->dev, "%s: transmit timed out, status %8.8x,"
+              " resetting...\n", ndev->name, (int)sh_eth_read(ndev, EESR));
+
+       /* tx_errors count up */
+       mdp->stats.tx_errors++;
+
+       /* timer off */
+       del_timer_sync(&mdp->timer);
+
+       /* Free all the skbuffs in the Rx queue. */
+       for (i = 0; i < RX_RING_SIZE; i++) {
+               rxdesc = &mdp->rx_ring[i];
+               rxdesc->status = 0;
+               rxdesc->addr = 0xBADF00D0;
+               if (mdp->rx_skbuff[i])
+                       dev_kfree_skb(mdp->rx_skbuff[i]);
+               mdp->rx_skbuff[i] = NULL;
+       }
+       for (i = 0; i < TX_RING_SIZE; i++) {
+               if (mdp->tx_skbuff[i])
+                       dev_kfree_skb(mdp->tx_skbuff[i]);
+               mdp->tx_skbuff[i] = NULL;
+       }
+
+       /* device init */
+       sh_eth_dev_init(ndev);
+
+       /* timer on */
+       mdp->timer.expires = (jiffies + (24 * HZ)) / 10;/* 2.4 sec. */
+       add_timer(&mdp->timer);
+}
+
+/* Packet transmit function */
+static int sh_eth_start_xmit(struct sk_buff *skb, struct net_device *ndev)
+{
+       struct sh_eth_private *mdp = netdev_priv(ndev);
+       struct sh_eth_txdesc *txdesc;
+       u32 entry;
+       unsigned long flags;
+
+       spin_lock_irqsave(&mdp->lock, flags);
+       if ((mdp->cur_tx - mdp->dirty_tx) >= (TX_RING_SIZE - 4)) {
+               if (!sh_eth_txfree(ndev)) {
+                       if (netif_msg_tx_queued(mdp))
+                               dev_warn(&ndev->dev, "TxFD exhausted.\n");
+                       netif_stop_queue(ndev);
+                       spin_unlock_irqrestore(&mdp->lock, flags);
+                       return NETDEV_TX_BUSY;
+               }
+       }
+       spin_unlock_irqrestore(&mdp->lock, flags);
+
+       entry = mdp->cur_tx % TX_RING_SIZE;
+       mdp->tx_skbuff[entry] = skb;
+       txdesc = &mdp->tx_ring[entry];
+       /* soft swap. */
+       if (!mdp->cd->hw_swap)
+               sh_eth_soft_swap(phys_to_virt(ALIGN(txdesc->addr, 4)),
+                                skb->len + 2);
+       txdesc->addr = dma_map_single(&ndev->dev, skb->data, skb->len,
+                                     DMA_TO_DEVICE);
+       if (skb->len < ETHERSMALL)
+               txdesc->buffer_length = ETHERSMALL;
+       else
+               txdesc->buffer_length = skb->len;
+
+       if (entry >= TX_RING_SIZE - 1)
+               txdesc->status |= cpu_to_edmac(mdp, TD_TACT | TD_TDLE);
+       else
+               txdesc->status |= cpu_to_edmac(mdp, TD_TACT);
+
+       mdp->cur_tx++;
+
+       if (!(sh_eth_read(ndev, EDTRR) & sh_eth_get_edtrr_trns(mdp)))
+               sh_eth_write(ndev, sh_eth_get_edtrr_trns(mdp), EDTRR);
+
+       return NETDEV_TX_OK;
+}
+
+/* device close function */
+static int sh_eth_close(struct net_device *ndev)
+{
+       struct sh_eth_private *mdp = netdev_priv(ndev);
+       int ringsize;
+
+       netif_stop_queue(ndev);
+
+       /* Disable interrupts by clearing the interrupt mask. */
+       sh_eth_write(ndev, 0x0000, EESIPR);
+
+       /* Stop the chip's Tx and Rx processes. */
+       sh_eth_write(ndev, 0, EDTRR);
+       sh_eth_write(ndev, 0, EDRRR);
+
+       /* PHY Disconnect */
+       if (mdp->phydev) {
+               phy_stop(mdp->phydev);
+               phy_disconnect(mdp->phydev);
+       }
+
+       free_irq(ndev->irq, ndev);
+
+       del_timer_sync(&mdp->timer);
+
+       /* Free all the skbuffs in the Rx queue. */
+       sh_eth_ring_free(ndev);
+
+       /* free DMA buffer */
+       ringsize = sizeof(struct sh_eth_rxdesc) * RX_RING_SIZE;
+       dma_free_coherent(NULL, ringsize, mdp->rx_ring, mdp->rx_desc_dma);
+
+       /* free DMA buffer */
+       ringsize = sizeof(struct sh_eth_txdesc) * TX_RING_SIZE;
+       dma_free_coherent(NULL, ringsize, mdp->tx_ring, mdp->tx_desc_dma);
+
+       pm_runtime_put_sync(&mdp->pdev->dev);
+
+       return 0;
+}
+
+static struct net_device_stats *sh_eth_get_stats(struct net_device *ndev)
+{
+       struct sh_eth_private *mdp = netdev_priv(ndev);
+
+       pm_runtime_get_sync(&mdp->pdev->dev);
+
+       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 (sh_eth_is_gether(mdp)) {
+               mdp->stats.tx_carrier_errors += sh_eth_read(ndev, CERCR);
+               sh_eth_write(ndev, 0, CERCR);   /* (write clear) */
+               mdp->stats.tx_carrier_errors += sh_eth_read(ndev, CEECR);
+               sh_eth_write(ndev, 0, CEECR);   /* (write clear) */
+       } else {
+               mdp->stats.tx_carrier_errors += sh_eth_read(ndev, CNDCR);
+               sh_eth_write(ndev, 0, CNDCR);   /* (write clear) */
+       }
+       pm_runtime_put_sync(&mdp->pdev->dev);
+
+       return &mdp->stats;
+}
+
+/* ioctl to device funciotn*/
+static int sh_eth_do_ioctl(struct net_device *ndev, struct ifreq *rq,
+                               int cmd)
+{
+       struct sh_eth_private *mdp = netdev_priv(ndev);
+       struct phy_device *phydev = mdp->phydev;
+
+       if (!netif_running(ndev))
+               return -EINVAL;
+
+       if (!phydev)
+               return -ENODEV;
+
+       return phy_mii_ioctl(phydev, rq, cmd);
+}
+
+#if defined(SH_ETH_HAS_TSU)
+/* Multicast reception directions set */
+static void sh_eth_set_multicast_list(struct net_device *ndev)
+{
+       if (ndev->flags & IFF_PROMISC) {
+               /* Set promiscuous. */
+               sh_eth_write(ndev, (sh_eth_read(ndev, ECMR) & ~ECMR_MCT) |
+                               ECMR_PRM, ECMR);
+       } else {
+               /* Normal, unicast/broadcast-only mode. */
+               sh_eth_write(ndev, (sh_eth_read(ndev, ECMR) & ~ECMR_PRM) |
+                               ECMR_MCT, ECMR);
+       }
+}
+#endif /* SH_ETH_HAS_TSU */
+
+/* SuperH's TSU register init function */
+static void sh_eth_tsu_init(struct sh_eth_private *mdp)
+{
+       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 (sh_eth_is_gether(mdp)) {
+               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 {
+               sh_eth_tsu_write(mdp, 0, TSU_QTAGM0);   /* Disable QTAG(0->1) */
+               sh_eth_tsu_write(mdp, 0, TSU_QTAGM1);   /* Disable QTAG(1->0) */
+       }
+       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] */
+}
+
+/* MDIO bus release function */
+static int sh_mdio_release(struct net_device *ndev)
+{
+       struct mii_bus *bus = dev_get_drvdata(&ndev->dev);
+
+       /* unregister mdio bus */
+       mdiobus_unregister(bus);
+
+       /* remove mdio bus info from net_device */
+       dev_set_drvdata(&ndev->dev, NULL);
+
+       /* free interrupts memory */
+       kfree(bus->irq);
+
+       /* free bitbang info */
+       free_mdio_bitbang(bus);
+
+       return 0;
+}
+
+/* MDIO bus init function */
+static int sh_mdio_init(struct net_device *ndev, int id,
+                       struct sh_eth_plat_data *pd)
+{
+       int ret, i;
+       struct bb_info *bitbang;
+       struct sh_eth_private *mdp = netdev_priv(ndev);
+
+       /* create bit control struct for PHY */
+       bitbang = kzalloc(sizeof(struct bb_info), GFP_KERNEL);
+       if (!bitbang) {
+               ret = -ENOMEM;
+               goto out;
+       }
+
+       /* bitbang init */
+       bitbang->addr = ndev->base_addr + mdp->reg_offset[PIR];
+       bitbang->set_gate = pd->set_mdio_gate;
+       bitbang->mdi_msk = 0x08;
+       bitbang->mdo_msk = 0x04;
+       bitbang->mmd_msk = 0x02;/* MMD */
+       bitbang->mdc_msk = 0x01;
+       bitbang->ctrl.ops = &bb_ops;
+
+       /* MII controller setting */
+       mdp->mii_bus = alloc_mdio_bitbang(&bitbang->ctrl);
+       if (!mdp->mii_bus) {
+               ret = -ENOMEM;
+               goto out_free_bitbang;
+       }
+
+       /* Hook up MII support for ethtool */
+       mdp->mii_bus->name = "sh_mii";
+       mdp->mii_bus->parent = &ndev->dev;
+       snprintf(mdp->mii_bus->id, MII_BUS_ID_SIZE, "%x", id);
+
+       /* PHY IRQ */
+       mdp->mii_bus->irq = kmalloc(sizeof(int)*PHY_MAX_ADDR, GFP_KERNEL);
+       if (!mdp->mii_bus->irq) {
+               ret = -ENOMEM;
+               goto out_free_bus;
+       }
+
+       for (i = 0; i < PHY_MAX_ADDR; i++)
+               mdp->mii_bus->irq[i] = PHY_POLL;
+
+       /* regist mdio bus */
+       ret = mdiobus_register(mdp->mii_bus);
+       if (ret)
+               goto out_free_irq;
+
+       dev_set_drvdata(&ndev->dev, mdp->mii_bus);
+
+       return 0;
+
+out_free_irq:
+       kfree(mdp->mii_bus->irq);
+
+out_free_bus:
+       free_mdio_bitbang(mdp->mii_bus);
+
+out_free_bitbang:
+       kfree(bitbang);
+
+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,
+       .ndo_start_xmit         = sh_eth_start_xmit,
+       .ndo_get_stats          = sh_eth_get_stats,
+#if defined(SH_ETH_HAS_TSU)
+       .ndo_set_multicast_list = sh_eth_set_multicast_list,
+#endif
+       .ndo_tx_timeout         = sh_eth_tx_timeout,
+       .ndo_do_ioctl           = sh_eth_do_ioctl,
+       .ndo_validate_addr      = eth_validate_addr,
+       .ndo_set_mac_address    = eth_mac_addr,
+       .ndo_change_mtu         = eth_change_mtu,
+};
+
+static int sh_eth_drv_probe(struct platform_device *pdev)
+{
+       int ret, devno = 0;
+       struct resource *res;
+       struct net_device *ndev = NULL;
+       struct sh_eth_private *mdp = NULL;
+       struct sh_eth_plat_data *pd;
+
+       /* get base addr */
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       if (unlikely(res == NULL)) {
+               dev_err(&pdev->dev, "invalid resource\n");
+               ret = -EINVAL;
+               goto out;
+       }
+
+       ndev = alloc_etherdev(sizeof(struct sh_eth_private));
+       if (!ndev) {
+               dev_err(&pdev->dev, "Could not allocate device.\n");
+               ret = -ENOMEM;
+               goto out;
+       }
+
+       /* The sh Ether-specific entries in the device structure. */
+       ndev->base_addr = res->start;
+       devno = pdev->id;
+       if (devno < 0)
+               devno = 0;
+
+       ndev->dma = -1;
+       ret = platform_get_irq(pdev, 0);
+       if (ret < 0) {
+               ret = -ENODEV;
+               goto out_release;
+       }
+       ndev->irq = ret;
+
+       SET_NETDEV_DEV(ndev, &pdev->dev);
+
+       /* Fill in the fields of the device structure with ethernet values. */
+       ether_setup(ndev);
+
+       mdp = netdev_priv(ndev);
+       spin_lock_init(&mdp->lock);
+       mdp->pdev = pdev;
+       pm_runtime_enable(&pdev->dev);
+       pm_runtime_resume(&pdev->dev);
+
+       pd = (struct sh_eth_plat_data *)(pdev->dev.platform_data);
+       /* get PHY ID */
+       mdp->phy_id = pd->phy;
+       mdp->phy_interface = pd->phy_interface;
+       /* EDMAC endian */
+       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 */
+#if defined(SH_ETH_HAS_BOTH_MODULES)
+       mdp->cd = sh_eth_get_cpu_data(mdp);
+#else
+       mdp->cd = &sh_eth_my_cpu_data;
+#endif
+       sh_eth_set_default_cpu_data(mdp->cd);
+
+       /* set function */
+       ndev->netdev_ops = &sh_eth_netdev_ops;
+       SET_ETHTOOL_OPS(ndev, &sh_eth_ethtool_ops);
+       ndev->watchdog_timeo = TX_TIMEOUT;
+
+       /* debug message level */
+       mdp->msg_enable = SH_ETH_DEF_MSG_ENABLE;
+       mdp->post_rx = POST_RX >> (devno << 1);
+       mdp->post_fw = POST_FW >> (devno << 1);
+
+       /* read and set MAC address */
+       read_mac_address(ndev, pd->mac_addr);
+
+       /* First device only init */
+       if (!devno) {
+               if (mdp->cd->tsu) {
+                       struct resource *rtsu;
+                       rtsu = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+                       if (!rtsu) {
+                               dev_err(&pdev->dev, "Not found TSU resource\n");
+                               goto out_release;
+                       }
+                       mdp->tsu_addr = ioremap(rtsu->start,
+                                               resource_size(rtsu));
+               }
+               if (mdp->cd->chip_reset)
+                       mdp->cd->chip_reset(ndev);
+
+               if (mdp->cd->tsu) {
+                       /* TSU init (Init only)*/
+                       sh_eth_tsu_init(mdp);
+               }
+       }
+
+       /* network device register */
+       ret = register_netdev(ndev);
+       if (ret)
+               goto out_release;
+
+       /* mdio bus init */
+       ret = sh_mdio_init(ndev, pdev->id, pd);
+       if (ret)
+               goto out_unregister;
+
+       /* print device information */
+       pr_info("Base address at 0x%x, %pM, IRQ %d.\n",
+              (u32)ndev->base_addr, ndev->dev_addr, ndev->irq);
+
+       platform_set_drvdata(pdev, ndev);
+
+       return ret;
+
+out_unregister:
+       unregister_netdev(ndev);
+
+out_release:
+       /* net_dev free */
+       if (mdp && mdp->tsu_addr)
+               iounmap(mdp->tsu_addr);
+       if (ndev)
+               free_netdev(ndev);
+
+out:
+       return ret;
+}
+
+static int sh_eth_drv_remove(struct platform_device *pdev)
+{
+       struct net_device *ndev = platform_get_drvdata(pdev);
+       struct sh_eth_private *mdp = netdev_priv(ndev);
+
+       iounmap(mdp->tsu_addr);
+       sh_mdio_release(ndev);
+       unregister_netdev(ndev);
+       pm_runtime_disable(&pdev->dev);
+       free_netdev(ndev);
+       platform_set_drvdata(pdev, NULL);
+
+       return 0;
+}
+
+static int sh_eth_runtime_nop(struct device *dev)
+{
+       /*
+        * Runtime PM callback shared between ->runtime_suspend()
+        * and ->runtime_resume(). Simply returns success.
+        *
+        * This driver re-initializes all registers after
+        * pm_runtime_get_sync() anyway so there is no need
+        * to save and restore registers here.
+        */
+       return 0;
+}
+
+static struct dev_pm_ops sh_eth_dev_pm_ops = {
+       .runtime_suspend = sh_eth_runtime_nop,
+       .runtime_resume = sh_eth_runtime_nop,
+};
+
+static struct platform_driver sh_eth_driver = {
+       .probe = sh_eth_drv_probe,
+       .remove = sh_eth_drv_remove,
+       .driver = {
+                  .name = CARDNAME,
+                  .pm = &sh_eth_dev_pm_ops,
+       },
+};
+
+static int __init sh_eth_init(void)
+{
+       return platform_driver_register(&sh_eth_driver);
+}
+
+static void __exit sh_eth_cleanup(void)
+{
+       platform_driver_unregister(&sh_eth_driver);
+}
+
+module_init(sh_eth_init);
+module_exit(sh_eth_cleanup);
+
+MODULE_AUTHOR("Nobuhiro Iwamatsu, Yoshihiro Shimoda");
+MODULE_DESCRIPTION("Renesas SuperH Ethernet driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/net/ethernet/renesas/sh_eth.h b/drivers/net/ethernet/renesas/sh_eth.h
new file mode 100644 (file)
index 0000000..c3048a6
--- /dev/null
@@ -0,0 +1,837 @@
+/*
+ *  SuperH Ethernet device driver
+ *
+ *  Copyright (C) 2006-2008 Nobuhiro Iwamatsu
+ *  Copyright (C) 2008-2011 Renesas Solutions Corp.
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms and conditions of the GNU General Public License,
+ *  version 2, as published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ *  more details.
+ *  You should have received a copy of the GNU General Public License along with
+ *  this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *  The full GNU General Public License is included in this distribution in
+ *  the file called "COPYING".
+ */
+
+#ifndef __SH_ETH_H__
+#define __SH_ETH_H__
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/spinlock.h>
+#include <linux/netdevice.h>
+#include <linux/phy.h>
+
+#include <asm/sh_eth.h>
+
+#define CARDNAME       "sh-eth"
+#define TX_TIMEOUT     (5*HZ)
+#define TX_RING_SIZE   64      /* Tx ring size */
+#define RX_RING_SIZE   64      /* Rx ring size */
+#define ETHERSMALL             60
+#define PKT_BUF_SZ             1538
+
+enum {
+       /* E-DMAC registers */
+       EDSR = 0,
+       EDMR,
+       EDTRR,
+       EDRRR,
+       EESR,
+       EESIPR,
+       TDLAR,
+       TDFAR,
+       TDFXR,
+       TDFFR,
+       RDLAR,
+       RDFAR,
+       RDFXR,
+       RDFFR,
+       TRSCER,
+       RMFCR,
+       TFTR,
+       FDR,
+       RMCR,
+       EDOCR,
+       TFUCR,
+       RFOCR,
+       FCFTR,
+       RPADIR,
+       TRIMD,
+       RBWAR,
+       TBRAR,
+
+       /* Ether registers */
+       ECMR,
+       ECSR,
+       ECSIPR,
+       PIR,
+       PSR,
+       RDMLR,
+       PIPR,
+       RFLR,
+       IPGR,
+       APR,
+       MPR,
+       PFTCR,
+       PFRCR,
+       RFCR,
+       RFCF,
+       TPAUSER,
+       TPAUSECR,
+       BCFR,
+       BCFRR,
+       GECMR,
+       BCULR,
+       MAHR,
+       MALR,
+       TROCR,
+       CDCR,
+       LCCR,
+       CNDCR,
+       CEFCR,
+       FRECR,
+       TSFRCR,
+       TLFRCR,
+       CERCR,
+       CEECR,
+       MAFCR,
+       RTRATE,
+
+       /* TSU Absolute address */
+       ARSTR,
+       TSU_CTRST,
+       TSU_FWEN0,
+       TSU_FWEN1,
+       TSU_FCM,
+       TSU_BSYSL0,
+       TSU_BSYSL1,
+       TSU_PRISL0,
+       TSU_PRISL1,
+       TSU_FWSL0,
+       TSU_FWSL1,
+       TSU_FWSLC,
+       TSU_QTAG0,
+       TSU_QTAG1,
+       TSU_QTAGM0,
+       TSU_QTAGM1,
+       TSU_FWSR,
+       TSU_FWINMK,
+       TSU_ADQT0,
+       TSU_ADQT1,
+       TSU_VTAG0,
+       TSU_VTAG1,
+       TSU_ADSBSY,
+       TSU_TEN,
+       TSU_POST1,
+       TSU_POST2,
+       TSU_POST3,
+       TSU_POST4,
+       TSU_ADRH0,
+       TSU_ADRL0,
+       TSU_ADRH31,
+       TSU_ADRL31,
+
+       TXNLCR0,
+       TXALCR0,
+       RXNLCR0,
+       RXALCR0,
+       FWNLCR0,
+       FWALCR0,
+       TXNLCR1,
+       TXALCR1,
+       RXNLCR1,
+       RXALCR1,
+       FWNLCR1,
+       FWALCR1,
+
+       /* This value must be written at last. */
+       SH_ETH_MAX_REGISTER_OFFSET,
+};
+
+static const u16 sh_eth_offset_gigabit[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,
+
+       [ECMR]  = 0x0500,
+       [ECSR]  = 0x0510,
+       [ECSIPR]        = 0x0518,
+       [PIR]   = 0x0520,
+       [PSR]   = 0x0528,
+       [PIPR]  = 0x052c,
+       [RFLR]  = 0x0508,
+       [APR]   = 0x0554,
+       [MPR]   = 0x0558,
+       [PFTCR] = 0x055c,
+       [PFRCR] = 0x0560,
+       [TPAUSER]       = 0x0564,
+       [GECMR] = 0x05b0,
+       [BCULR] = 0x05b4,
+       [MAHR]  = 0x05c0,
+       [MALR]  = 0x05c8,
+       [TROCR] = 0x0700,
+       [CDCR]  = 0x0708,
+       [LCCR]  = 0x0710,
+       [CEFCR] = 0x0740,
+       [FRECR] = 0x0748,
+       [TSFRCR]        = 0x0750,
+       [TLFRCR]        = 0x0758,
+       [RFCR]  = 0x0760,
+       [CERCR] = 0x0768,
+       [CEECR] = 0x0770,
+       [MAFCR] = 0x0778,
+
+       [ARSTR] = 0x0000,
+       [TSU_CTRST]     = 0x0004,
+       [TSU_FWEN0]     = 0x0010,
+       [TSU_FWEN1]     = 0x0014,
+       [TSU_FCM]       = 0x0018,
+       [TSU_BSYSL0]    = 0x0020,
+       [TSU_BSYSL1]    = 0x0024,
+       [TSU_PRISL0]    = 0x0028,
+       [TSU_PRISL1]    = 0x002c,
+       [TSU_FWSL0]     = 0x0030,
+       [TSU_FWSL1]     = 0x0034,
+       [TSU_FWSLC]     = 0x0038,
+       [TSU_QTAG0]     = 0x0040,
+       [TSU_QTAG1]     = 0x0044,
+       [TSU_FWSR]      = 0x0050,
+       [TSU_FWINMK]    = 0x0054,
+       [TSU_ADQT0]     = 0x0048,
+       [TSU_ADQT1]     = 0x004c,
+       [TSU_VTAG0]     = 0x0058,
+       [TSU_VTAG1]     = 0x005c,
+       [TSU_ADSBSY]    = 0x0060,
+       [TSU_TEN]       = 0x0064,
+       [TSU_POST1]     = 0x0070,
+       [TSU_POST2]     = 0x0074,
+       [TSU_POST3]     = 0x0078,
+       [TSU_POST4]     = 0x007c,
+       [TSU_ADRH0]     = 0x0100,
+       [TSU_ADRL0]     = 0x0104,
+       [TSU_ADRH31]    = 0x01f8,
+       [TSU_ADRL31]    = 0x01fc,
+
+       [TXNLCR0]       = 0x0080,
+       [TXALCR0]       = 0x0084,
+       [RXNLCR0]       = 0x0088,
+       [RXALCR0]       = 0x008c,
+       [FWNLCR0]       = 0x0090,
+       [FWALCR0]       = 0x0094,
+       [TXNLCR1]       = 0x00a0,
+       [TXALCR1]       = 0x00a0,
+       [RXNLCR1]       = 0x00a8,
+       [RXALCR1]       = 0x00ac,
+       [FWNLCR1]       = 0x00b0,
+       [FWALCR1]       = 0x00b4,
+};
+
+static const u16 sh_eth_offset_fast_sh4[SH_ETH_MAX_REGISTER_OFFSET] = {
+       [ECMR]  = 0x0100,
+       [RFLR]  = 0x0108,
+       [ECSR]  = 0x0110,
+       [ECSIPR]        = 0x0118,
+       [PIR]   = 0x0120,
+       [PSR]   = 0x0128,
+       [RDMLR] = 0x0140,
+       [IPGR]  = 0x0150,
+       [APR]   = 0x0154,
+       [MPR]   = 0x0158,
+       [TPAUSER]       = 0x0164,
+       [RFCF]  = 0x0160,
+       [TPAUSECR]      = 0x0168,
+       [BCFRR] = 0x016c,
+       [MAHR]  = 0x01c0,
+       [MALR]  = 0x01c8,
+       [TROCR] = 0x01d0,
+       [CDCR]  = 0x01d4,
+       [LCCR]  = 0x01d8,
+       [CNDCR] = 0x01dc,
+       [CEFCR] = 0x01e4,
+       [FRECR] = 0x01e8,
+       [TSFRCR]        = 0x01ec,
+       [TLFRCR]        = 0x01f0,
+       [RFCR]  = 0x01f4,
+       [MAFCR] = 0x01f8,
+       [RTRATE]        = 0x01fc,
+
+       [EDMR]  = 0x0000,
+       [EDTRR] = 0x0008,
+       [EDRRR] = 0x0010,
+       [TDLAR] = 0x0018,
+       [RDLAR] = 0x0020,
+       [EESR]  = 0x0028,
+       [EESIPR]        = 0x0030,
+       [TRSCER]        = 0x0038,
+       [RMFCR] = 0x0040,
+       [TFTR]  = 0x0048,
+       [FDR]   = 0x0050,
+       [RMCR]  = 0x0058,
+       [TFUCR] = 0x0064,
+       [RFOCR] = 0x0068,
+       [FCFTR] = 0x0070,
+       [RPADIR]        = 0x0078,
+       [TRIMD] = 0x007c,
+       [RBWAR] = 0x00c8,
+       [RDFAR] = 0x00cc,
+       [TBRAR] = 0x00d4,
+       [TDFAR] = 0x00d8,
+};
+
+static const u16 sh_eth_offset_fast_sh3_sh2[SH_ETH_MAX_REGISTER_OFFSET] = {
+       [ECMR]  = 0x0160,
+       [ECSR]  = 0x0164,
+       [ECSIPR]        = 0x0168,
+       [PIR]   = 0x016c,
+       [MAHR]  = 0x0170,
+       [MALR]  = 0x0174,
+       [RFLR]  = 0x0178,
+       [PSR]   = 0x017c,
+       [TROCR] = 0x0180,
+       [CDCR]  = 0x0184,
+       [LCCR]  = 0x0188,
+       [CNDCR] = 0x018c,
+       [CEFCR] = 0x0194,
+       [FRECR] = 0x0198,
+       [TSFRCR]        = 0x019c,
+       [TLFRCR]        = 0x01a0,
+       [RFCR]  = 0x01a4,
+       [MAFCR] = 0x01a8,
+       [IPGR]  = 0x01b4,
+       [APR]   = 0x01b8,
+       [MPR]   = 0x01bc,
+       [TPAUSER]       = 0x01c4,
+       [BCFR]  = 0x01cc,
+
+       [ARSTR] = 0x0000,
+       [TSU_CTRST]     = 0x0004,
+       [TSU_FWEN0]     = 0x0010,
+       [TSU_FWEN1]     = 0x0014,
+       [TSU_FCM]       = 0x0018,
+       [TSU_BSYSL0]    = 0x0020,
+       [TSU_BSYSL1]    = 0x0024,
+       [TSU_PRISL0]    = 0x0028,
+       [TSU_PRISL1]    = 0x002c,
+       [TSU_FWSL0]     = 0x0030,
+       [TSU_FWSL1]     = 0x0034,
+       [TSU_FWSLC]     = 0x0038,
+       [TSU_QTAGM0]    = 0x0040,
+       [TSU_QTAGM1]    = 0x0044,
+       [TSU_ADQT0]     = 0x0048,
+       [TSU_ADQT1]     = 0x004c,
+       [TSU_FWSR]      = 0x0050,
+       [TSU_FWINMK]    = 0x0054,
+       [TSU_ADSBSY]    = 0x0060,
+       [TSU_TEN]       = 0x0064,
+       [TSU_POST1]     = 0x0070,
+       [TSU_POST2]     = 0x0074,
+       [TSU_POST3]     = 0x0078,
+       [TSU_POST4]     = 0x007c,
+
+       [TXNLCR0]       = 0x0080,
+       [TXALCR0]       = 0x0084,
+       [RXNLCR0]       = 0x0088,
+       [RXALCR0]       = 0x008c,
+       [FWNLCR0]       = 0x0090,
+       [FWALCR0]       = 0x0094,
+       [TXNLCR1]       = 0x00a0,
+       [TXALCR1]       = 0x00a0,
+       [RXNLCR1]       = 0x00a8,
+       [RXALCR1]       = 0x00ac,
+       [FWNLCR1]       = 0x00b0,
+       [FWALCR1]       = 0x00b4,
+
+       [TSU_ADRH0]     = 0x0100,
+       [TSU_ADRL0]     = 0x0104,
+       [TSU_ADRL31]    = 0x01fc,
+
+};
+
+/* 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
+ */
+#ifdef CONFIG_CPU_SUBTYPE_SH7763
+/* EDSR */
+enum EDSR_BIT {
+       EDSR_ENT = 0x01, EDSR_ENR = 0x02,
+};
+#define EDSR_ENALL (EDSR_ENT|EDSR_ENR)
+
+/* GECMR */
+enum GECMR_BIT {
+       GECMR_10 = 0x0, GECMR_100 = 0x04, GECMR_1000 = 0x01,
+};
+#endif
+
+/* EDMR */
+enum DMAC_M_BIT {
+       EDMR_EL = 0x40, /* Litte endian */
+       EDMR_DL1 = 0x20, EDMR_DL0 = 0x10,
+       EDMR_SRST_GETHER = 0x03,
+       EDMR_SRST_ETHER = 0x01,
+};
+
+/* EDTRR */
+enum DMAC_T_BIT {
+       EDTRR_TRNS_GETHER = 0x03,
+       EDTRR_TRNS_ETHER = 0x01,
+};
+
+/* EDRRR*/
+enum EDRRR_R_BIT {
+       EDRRR_R = 0x01,
+};
+
+/* TPAUSER */
+enum TPAUSER_BIT {
+       TPAUSER_TPAUSE = 0x0000ffff,
+       TPAUSER_UNLIMITED = 0,
+};
+
+/* BCFR */
+enum BCFR_BIT {
+       BCFR_RPAUSE = 0x0000ffff,
+       BCFR_UNLIMITED = 0,
+};
+
+/* PIR */
+enum PIR_BIT {
+       PIR_MDI = 0x08, PIR_MDO = 0x04, PIR_MMD = 0x02, PIR_MDC = 0x01,
+};
+
+/* PSR */
+enum PHY_STATUS_BIT { PHY_ST_LINK = 0x01, };
+
+/* EESR */
+enum EESR_BIT {
+       EESR_TWB1       = 0x80000000,
+       EESR_TWB        = 0x40000000,   /* same as TWB0 */
+       EESR_TC1        = 0x20000000,
+       EESR_TUC        = 0x10000000,
+       EESR_ROC        = 0x08000000,
+       EESR_TABT       = 0x04000000,
+       EESR_RABT       = 0x02000000,
+       EESR_RFRMER     = 0x01000000,   /* same as RFCOF */
+       EESR_ADE        = 0x00800000,
+       EESR_ECI        = 0x00400000,
+       EESR_FTC        = 0x00200000,   /* same as TC or TC0 */
+       EESR_TDE        = 0x00100000,
+       EESR_TFE        = 0x00080000,   /* same as TFUF */
+       EESR_FRC        = 0x00040000,   /* same as FR */
+       EESR_RDE        = 0x00020000,
+       EESR_RFE        = 0x00010000,
+       EESR_CND        = 0x00000800,
+       EESR_DLC        = 0x00000400,
+       EESR_CD         = 0x00000200,
+       EESR_RTO        = 0x00000100,
+       EESR_RMAF       = 0x00000080,
+       EESR_CEEF       = 0x00000040,
+       EESR_CELF       = 0x00000020,
+       EESR_RRF        = 0x00000010,
+       EESR_RTLF       = 0x00000008,
+       EESR_RTSF       = 0x00000004,
+       EESR_PRE        = 0x00000002,
+       EESR_CERF       = 0x00000001,
+};
+
+#define DEFAULT_TX_CHECK       (EESR_FTC | EESR_CND | EESR_DLC | EESR_CD | \
+                                EESR_RTO)
+#define DEFAULT_EESR_ERR_CHECK (EESR_TWB | EESR_TABT | EESR_RABT | \
+                                EESR_RDE | EESR_RFRMER | EESR_ADE | \
+                                EESR_TFE | EESR_TDE | EESR_ECI)
+#define DEFAULT_TX_ERROR_CHECK (EESR_TWB | EESR_TABT | EESR_ADE | EESR_TDE | \
+                                EESR_TFE)
+
+/* EESIPR */
+enum DMAC_IM_BIT {
+       DMAC_M_TWB = 0x40000000, DMAC_M_TABT = 0x04000000,
+       DMAC_M_RABT = 0x02000000,
+       DMAC_M_RFRMER = 0x01000000, DMAC_M_ADF = 0x00800000,
+       DMAC_M_ECI = 0x00400000, DMAC_M_FTC = 0x00200000,
+       DMAC_M_TDE = 0x00100000, DMAC_M_TFE = 0x00080000,
+       DMAC_M_FRC = 0x00040000, DMAC_M_RDE = 0x00020000,
+       DMAC_M_RFE = 0x00010000, DMAC_M_TINT4 = 0x00000800,
+       DMAC_M_TINT3 = 0x00000400, DMAC_M_TINT2 = 0x00000200,
+       DMAC_M_TINT1 = 0x00000100, DMAC_M_RINT8 = 0x00000080,
+       DMAC_M_RINT5 = 0x00000010, DMAC_M_RINT4 = 0x00000008,
+       DMAC_M_RINT3 = 0x00000004, DMAC_M_RINT2 = 0x00000002,
+       DMAC_M_RINT1 = 0x00000001,
+};
+
+/* Receive descriptor bit */
+enum RD_STS_BIT {
+       RD_RACT = 0x80000000, RD_RDEL = 0x40000000,
+       RD_RFP1 = 0x20000000, RD_RFP0 = 0x10000000,
+       RD_RFE = 0x08000000, RD_RFS10 = 0x00000200,
+       RD_RFS9 = 0x00000100, RD_RFS8 = 0x00000080,
+       RD_RFS7 = 0x00000040, RD_RFS6 = 0x00000020,
+       RD_RFS5 = 0x00000010, RD_RFS4 = 0x00000008,
+       RD_RFS3 = 0x00000004, RD_RFS2 = 0x00000002,
+       RD_RFS1 = 0x00000001,
+};
+#define RDF1ST RD_RFP1
+#define RDFEND RD_RFP0
+#define RD_RFP (RD_RFP1|RD_RFP0)
+
+/* FCFTR */
+enum FCFTR_BIT {
+       FCFTR_RFF2 = 0x00040000, FCFTR_RFF1 = 0x00020000,
+       FCFTR_RFF0 = 0x00010000, FCFTR_RFD2 = 0x00000004,
+       FCFTR_RFD1 = 0x00000002, FCFTR_RFD0 = 0x00000001,
+};
+#define DEFAULT_FIFO_F_D_RFF   (FCFTR_RFF2 | FCFTR_RFF1 | FCFTR_RFF0)
+#define DEFAULT_FIFO_F_D_RFD   (FCFTR_RFD2 | FCFTR_RFD1 | FCFTR_RFD0)
+
+/* Transfer descriptor bit */
+enum TD_STS_BIT {
+       TD_TACT = 0x80000000,
+       TD_TDLE = 0x40000000, TD_TFP1 = 0x20000000,
+       TD_TFP0 = 0x10000000,
+};
+#define TDF1ST TD_TFP1
+#define TDFEND TD_TFP0
+#define TD_TFP (TD_TFP1|TD_TFP0)
+
+/* RMCR */
+#define DEFAULT_RMCR_VALUE     0x00000000
+
+/* ECMR */
+enum FELIC_MODE_BIT {
+       ECMR_TRCCM = 0x04000000, ECMR_RCSC = 0x00800000,
+       ECMR_DPAD = 0x00200000, ECMR_RZPF = 0x00100000,
+       ECMR_ZPF = 0x00080000, ECMR_PFR = 0x00040000, ECMR_RXF = 0x00020000,
+       ECMR_TXF = 0x00010000, ECMR_MCT = 0x00002000, ECMR_PRCEF = 0x00001000,
+       ECMR_PMDE = 0x00000200, ECMR_RE = 0x00000040, ECMR_TE = 0x00000020,
+       ECMR_RTM = 0x00000010, ECMR_ILB = 0x00000008, ECMR_ELB = 0x00000004,
+       ECMR_DM = 0x00000002, ECMR_PRM = 0x00000001,
+};
+
+/* ECSR */
+enum ECSR_STATUS_BIT {
+       ECSR_BRCRX = 0x20, ECSR_PSRTO = 0x10,
+       ECSR_LCHNG = 0x04,
+       ECSR_MPD = 0x02, ECSR_ICD = 0x01,
+};
+
+#define DEFAULT_ECSR_INIT      (ECSR_BRCRX | ECSR_PSRTO | ECSR_LCHNG | \
+                                ECSR_ICD | ECSIPR_MPDIP)
+
+/* ECSIPR */
+enum ECSIPR_STATUS_MASK_BIT {
+       ECSIPR_BRCRXIP = 0x20, ECSIPR_PSRTOIP = 0x10,
+       ECSIPR_LCHNGIP = 0x04,
+       ECSIPR_MPDIP = 0x02, ECSIPR_ICDIP = 0x01,
+};
+
+#define DEFAULT_ECSIPR_INIT    (ECSIPR_BRCRXIP | ECSIPR_PSRTOIP | \
+                                ECSIPR_LCHNGIP | ECSIPR_ICDIP | ECSIPR_MPDIP)
+
+/* APR */
+enum APR_BIT {
+       APR_AP = 0x00000001,
+};
+
+/* MPR */
+enum MPR_BIT {
+       MPR_MP = 0x00000001,
+};
+
+/* TRSCER */
+enum DESC_I_BIT {
+       DESC_I_TINT4 = 0x0800, DESC_I_TINT3 = 0x0400, DESC_I_TINT2 = 0x0200,
+       DESC_I_TINT1 = 0x0100, DESC_I_RINT8 = 0x0080, DESC_I_RINT5 = 0x0010,
+       DESC_I_RINT4 = 0x0008, DESC_I_RINT3 = 0x0004, DESC_I_RINT2 = 0x0002,
+       DESC_I_RINT1 = 0x0001,
+};
+
+/* RPADIR */
+enum RPADIR_BIT {
+       RPADIR_PADS1 = 0x20000, RPADIR_PADS0 = 0x10000,
+       RPADIR_PADR = 0x0003f,
+};
+
+/* RFLR */
+#define RFLR_VALUE 0x1000
+
+/* FDR */
+#define DEFAULT_FDR_INIT       0x00000707
+
+enum phy_offsets {
+       PHY_CTRL = 0, PHY_STAT = 1, PHY_IDT1 = 2, PHY_IDT2 = 3,
+       PHY_ANA = 4, PHY_ANL = 5, PHY_ANE = 6,
+       PHY_16 = 16,
+};
+
+/* PHY_CTRL */
+enum PHY_CTRL_BIT {
+       PHY_C_RESET = 0x8000, PHY_C_LOOPBK = 0x4000, PHY_C_SPEEDSL = 0x2000,
+       PHY_C_ANEGEN = 0x1000, PHY_C_PWRDN = 0x0800, PHY_C_ISO = 0x0400,
+       PHY_C_RANEG = 0x0200, PHY_C_DUPLEX = 0x0100, PHY_C_COLT = 0x0080,
+};
+#define DM9161_PHY_C_ANEGEN 0  /* auto nego special */
+
+/* PHY_STAT */
+enum PHY_STAT_BIT {
+       PHY_S_100T4 = 0x8000, PHY_S_100X_F = 0x4000, PHY_S_100X_H = 0x2000,
+       PHY_S_10T_F = 0x1000, PHY_S_10T_H = 0x0800, PHY_S_ANEGC = 0x0020,
+       PHY_S_RFAULT = 0x0010, PHY_S_ANEGA = 0x0008, PHY_S_LINK = 0x0004,
+       PHY_S_JAB = 0x0002, PHY_S_EXTD = 0x0001,
+};
+
+/* PHY_ANA */
+enum PHY_ANA_BIT {
+       PHY_A_NP = 0x8000, PHY_A_ACK = 0x4000, PHY_A_RF = 0x2000,
+       PHY_A_FCS = 0x0400, PHY_A_T4 = 0x0200, PHY_A_FDX = 0x0100,
+       PHY_A_HDX = 0x0080, PHY_A_10FDX = 0x0040, PHY_A_10HDX = 0x0020,
+       PHY_A_SEL = 0x001e,
+};
+/* PHY_ANL */
+enum PHY_ANL_BIT {
+       PHY_L_NP = 0x8000, PHY_L_ACK = 0x4000, PHY_L_RF = 0x2000,
+       PHY_L_FCS = 0x0400, PHY_L_T4 = 0x0200, PHY_L_FDX = 0x0100,
+       PHY_L_HDX = 0x0080, PHY_L_10FDX = 0x0040, PHY_L_10HDX = 0x0020,
+       PHY_L_SEL = 0x001f,
+};
+
+/* PHY_ANE */
+enum PHY_ANE_BIT {
+       PHY_E_PDF = 0x0010, PHY_E_LPNPA = 0x0008, PHY_E_NPA = 0x0004,
+       PHY_E_PRX = 0x0002, PHY_E_LPANEGA = 0x0001,
+};
+
+/* DM9161 */
+enum PHY_16_BIT {
+       PHY_16_BP4B45 = 0x8000, PHY_16_BPSCR = 0x4000, PHY_16_BPALIGN = 0x2000,
+       PHY_16_BP_ADPOK = 0x1000, PHY_16_Repeatmode = 0x0800,
+       PHY_16_TXselect = 0x0400,
+       PHY_16_Rsvd = 0x0200, PHY_16_RMIIEnable = 0x0100,
+       PHY_16_Force100LNK = 0x0080,
+       PHY_16_APDLED_CTL = 0x0040, PHY_16_COLLED_CTL = 0x0020,
+       PHY_16_RPDCTR_EN = 0x0010,
+       PHY_16_ResetStMch = 0x0008, PHY_16_PreamSupr = 0x0004,
+       PHY_16_Sleepmode = 0x0002,
+       PHY_16_RemoteLoopOut = 0x0001,
+};
+
+#define POST_RX                0x08
+#define POST_FW                0x04
+#define POST0_RX       (POST_RX)
+#define POST0_FW       (POST_FW)
+#define POST1_RX       (POST_RX >> 2)
+#define POST1_FW       (POST_FW >> 2)
+#define POST_ALL       (POST0_RX | POST0_FW | POST1_RX | POST1_FW)
+
+/* ARSTR */
+enum ARSTR_BIT { ARSTR_ARSTR = 0x00000001, };
+
+/* TSU_FWEN0 */
+enum TSU_FWEN0_BIT {
+       TSU_FWEN0_0 = 0x00000001,
+};
+
+/* TSU_ADSBSY */
+enum TSU_ADSBSY_BIT {
+       TSU_ADSBSY_0 = 0x00000001,
+};
+
+/* TSU_TEN */
+enum TSU_TEN_BIT {
+       TSU_TEN_0 = 0x80000000,
+};
+
+/* TSU_FWSL0 */
+enum TSU_FWSL0_BIT {
+       TSU_FWSL0_FW50 = 0x1000, TSU_FWSL0_FW40 = 0x0800,
+       TSU_FWSL0_FW30 = 0x0400, TSU_FWSL0_FW20 = 0x0200,
+       TSU_FWSL0_FW10 = 0x0100, TSU_FWSL0_RMSA0 = 0x0010,
+};
+
+/* TSU_FWSLC */
+enum TSU_FWSLC_BIT {
+       TSU_FWSLC_POSTENU = 0x2000, TSU_FWSLC_POSTENL = 0x1000,
+       TSU_FWSLC_CAMSEL03 = 0x0080, TSU_FWSLC_CAMSEL02 = 0x0040,
+       TSU_FWSLC_CAMSEL01 = 0x0020, TSU_FWSLC_CAMSEL00 = 0x0010,
+       TSU_FWSLC_CAMSEL13 = 0x0008, TSU_FWSLC_CAMSEL12 = 0x0004,
+       TSU_FWSLC_CAMSEL11 = 0x0002, TSU_FWSLC_CAMSEL10 = 0x0001,
+};
+
+/*
+ * The sh ether Tx buffer descriptors.
+ * This structure should be 20 bytes.
+ */
+struct sh_eth_txdesc {
+       u32 status;             /* TD0 */
+#if defined(CONFIG_CPU_LITTLE_ENDIAN)
+       u16 pad0;               /* TD1 */
+       u16 buffer_length;      /* TD1 */
+#else
+       u16 buffer_length;      /* TD1 */
+       u16 pad0;               /* TD1 */
+#endif
+       u32 addr;               /* TD2 */
+       u32 pad1;               /* padding data */
+} __attribute__((aligned(2), packed));
+
+/*
+ * The sh ether Rx buffer descriptors.
+ * This structure should be 20 bytes.
+ */
+struct sh_eth_rxdesc {
+       u32 status;             /* RD0 */
+#if defined(CONFIG_CPU_LITTLE_ENDIAN)
+       u16 frame_length;       /* RD1 */
+       u16 buffer_length;      /* RD1 */
+#else
+       u16 buffer_length;      /* RD1 */
+       u16 frame_length;       /* RD1 */
+#endif
+       u32 addr;               /* RD2 */
+       u32 pad0;               /* padding data */
+} __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 tsu:1;                 /* EtherC have TSU */
+       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 platform_device *pdev;
+       struct sh_eth_cpu_data *cd;
+       const u16 *reg_offset;
+       void __iomem *tsu_addr;
+       dma_addr_t rx_desc_dma;
+       dma_addr_t tx_desc_dma;
+       struct sh_eth_rxdesc *rx_ring;
+       struct sh_eth_txdesc *tx_ring;
+       struct sk_buff **rx_skbuff;
+       struct sk_buff **tx_skbuff;
+       struct net_device_stats stats;
+       struct timer_list timer;
+       spinlock_t lock;
+       u32 cur_rx, dirty_rx;   /* Producer/consumer ring indices */
+       u32 cur_tx, dirty_tx;
+       u32 rx_buf_sz;          /* Based on MTU+slack. */
+       int edmac_endian;
+       /* MII transceiver section. */
+       u32 phy_id;                                     /* PHY ID */
+       struct mii_bus *mii_bus;        /* MDIO bus control */
+       struct phy_device *phydev;      /* PHY device control */
+       enum phy_state link;
+       phy_interface_t phy_interface;
+       int msg_enable;
+       int speed;
+       int duplex;
+       u32 rx_int_var, tx_int_var;     /* interrupt control variables */
+       char post_rx;           /* POST receive */
+       char post_fw;           /* POST forward */
+       struct net_device_stats tsu_stats;      /* TSU forward status */
+
+       unsigned no_ether_link:1;
+       unsigned ether_link_active_low:1;
+};
+
+static inline void sh_eth_soft_swap(char *src, int len)
+{
+#ifdef __LITTLE_ENDIAN__
+       u32 *p = (u32 *)src;
+       u32 *maxp;
+       maxp = p + ((len + sizeof(u32) - 1) / sizeof(u32));
+
+       for (; p < maxp; p++)
+               *p = swab32(*p);
+#endif
+}
+
+static inline void sh_eth_write(struct net_device *ndev, unsigned long data,
+                               int enum_index)
+{
+       struct sh_eth_private *mdp = netdev_priv(ndev);
+
+       writel(data, ndev->base_addr + mdp->reg_offset[enum_index]);
+}
+
+static inline unsigned long sh_eth_read(struct net_device *ndev,
+                                       int enum_index)
+{
+       struct sh_eth_private *mdp = netdev_priv(ndev);
+
+       return readl(ndev->base_addr + mdp->reg_offset[enum_index]);
+}
+
+static inline void sh_eth_tsu_write(struct sh_eth_private *mdp,
+                               unsigned long data, int enum_index)
+{
+       writel(data, mdp->tsu_addr + mdp->reg_offset[enum_index]);
+}
+
+static inline unsigned long sh_eth_tsu_read(struct sh_eth_private *mdp,
+                                       int enum_index)
+{
+       return readl(mdp->tsu_addr + mdp->reg_offset[enum_index]);
+}
+
+#endif /* #ifndef __SH_ETH_H__ */
diff --git a/drivers/net/sh_eth.c b/drivers/net/sh_eth.c
deleted file mode 100644 (file)
index ad35c21..0000000
+++ /dev/null
@@ -1,1959 +0,0 @@
-/*
- *  SuperH Ethernet device driver
- *
- *  Copyright (C) 2006-2008 Nobuhiro Iwamatsu
- *  Copyright (C) 2008-2009 Renesas Solutions Corp.
- *
- *  This program is free software; you can redistribute it and/or modify it
- *  under the terms and conditions of the GNU General Public License,
- *  version 2, as published by the Free Software Foundation.
- *
- *  This program is distributed in the hope it will be useful, but WITHOUT
- *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- *  more details.
- *  You should have received a copy of the GNU General Public License along with
- *  this program; if not, write to the Free Software Foundation, Inc.,
- *  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- *  The full GNU General Public License is included in this distribution in
- *  the file called "COPYING".
- */
-
-#include <linux/init.h>
-#include <linux/dma-mapping.h>
-#include <linux/etherdevice.h>
-#include <linux/delay.h>
-#include <linux/platform_device.h>
-#include <linux/mdio-bitbang.h>
-#include <linux/netdevice.h>
-#include <linux/phy.h>
-#include <linux/cache.h>
-#include <linux/io.h>
-#include <linux/pm_runtime.h>
-#include <linux/slab.h>
-#include <linux/ethtool.h>
-
-#include "sh_eth.h"
-
-#define SH_ETH_DEF_MSG_ENABLE \
-               (NETIF_MSG_LINK | \
-               NETIF_MSG_TIMER | \
-               NETIF_MSG_RX_ERR| \
-               NETIF_MSG_TX_ERR)
-
-/* There is CPU dependent code */
-#if defined(CONFIG_CPU_SUBTYPE_SH7724)
-#define SH_ETH_RESET_DEFAULT   1
-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, sh_eth_read(ndev, ECMR) & ~ECMR_RTM, ECMR);
-               break;
-       case 100:/* 100BASE */
-               sh_eth_write(ndev, sh_eth_read(ndev, ECMR) | ECMR_RTM, ECMR);
-               break;
-       default:
-               break;
-       }
-}
-
-/* SH7724 */
-static struct sh_eth_cpu_data sh_eth_my_cpu_data = {
-       .set_duplex     = sh_eth_set_duplex,
-       .set_rate       = sh_eth_set_rate,
-
-       .ecsr_value     = ECSR_PSRTO | ECSR_LCHNG | ECSR_ICD,
-       .ecsipr_value   = ECSIPR_PSRTOIP | ECSIPR_LCHNGIP | ECSIPR_ICDIP,
-       .eesipr_value   = DMAC_M_RFRMER | DMAC_M_ECI | 0x01ff009f,
-
-       .tx_check       = EESR_FTC | EESR_CND | EESR_DLC | EESR_CD | EESR_RTO,
-       .eesr_err_check = EESR_TWB | EESR_TABT | EESR_RABT | EESR_RDE |
-                         EESR_RFRMER | EESR_TFE | EESR_TDE | EESR_ECI,
-       .tx_error_check = EESR_TWB | EESR_TABT | EESR_TDE | EESR_TFE,
-
-       .apr            = 1,
-       .mpr            = 1,
-       .tpauser        = 1,
-       .hw_swap        = 1,
-       .rpadir         = 1,
-       .rpadir_value   = 0x00020000, /* NET_IP_ALIGN assumed to be 2 */
-};
-#elif defined(CONFIG_CPU_SUBTYPE_SH7757)
-#define SH_ETH_HAS_BOTH_MODULES        1
-#define SH_ETH_HAS_TSU 1
-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, 0, RTRATE);
-               break;
-       case 100:/* 100BASE */
-               sh_eth_write(ndev, 1, RTRATE);
-               break;
-       default:
-               break;
-       }
-}
-
-/* SH7757 */
-static struct sh_eth_cpu_data sh_eth_my_cpu_data = {
-       .set_duplex             = sh_eth_set_duplex,
-       .set_rate               = sh_eth_set_rate,
-
-       .eesipr_value   = DMAC_M_RFRMER | DMAC_M_ECI | 0x003fffff,
-       .rmcr_value     = 0x00000001,
-
-       .tx_check       = EESR_FTC | EESR_CND | EESR_DLC | EESR_CD | EESR_RTO,
-       .eesr_err_check = EESR_TWB | EESR_TABT | EESR_RABT | EESR_RDE |
-                         EESR_RFRMER | EESR_TFE | EESR_TDE | EESR_ECI,
-       .tx_error_check = EESR_TWB | EESR_TABT | EESR_TDE | EESR_TFE,
-
-       .apr            = 1,
-       .mpr            = 1,
-       .tpauser        = 1,
-       .hw_swap        = 1,
-       .no_ade         = 1,
-       .rpadir         = 1,
-       .rpadir_value   = 2 << 16,
-};
-
-#define SH_GIGA_ETH_BASE       0xfee00000
-#define GIGA_MALR(port)                (SH_GIGA_ETH_BASE + 0x800 * (port) + 0x05c8)
-#define GIGA_MAHR(port)                (SH_GIGA_ETH_BASE + 0x800 * (port) + 0x05c0)
-static void sh_eth_chip_reset_giga(struct net_device *ndev)
-{
-       int i;
-       unsigned long mahr[2], malr[2];
-
-       /* save MAHR and MALR */
-       for (i = 0; i < 2; i++) {
-               malr[i] = readl(GIGA_MALR(i));
-               mahr[i] = readl(GIGA_MAHR(i));
-       }
-
-       /* reset device */
-       writel(ARSTR_ARSTR, SH_GIGA_ETH_BASE + 0x1800);
-       mdelay(1);
-
-       /* restore MAHR and MALR */
-       for (i = 0; i < 2; i++) {
-               writel(malr[i], GIGA_MALR(i));
-               writel(mahr[i], GIGA_MAHR(i));
-       }
-}
-
-static int sh_eth_is_gether(struct sh_eth_private *mdp);
-static void sh_eth_reset(struct net_device *ndev)
-{
-       struct sh_eth_private *mdp = netdev_priv(ndev);
-       int cnt = 100;
-
-       if (sh_eth_is_gether(mdp)) {
-               sh_eth_write(ndev, 0x03, 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);
-       } else {
-               sh_eth_write(ndev, sh_eth_read(ndev, EDMR) | EDMR_SRST_ETHER,
-                               EDMR);
-               mdelay(3);
-               sh_eth_write(ndev, sh_eth_read(ndev, EDMR) & ~EDMR_SRST_ETHER,
-                               EDMR);
-       }
-}
-
-static void sh_eth_set_duplex_giga(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_giga(struct net_device *ndev)
-{
-       struct sh_eth_private *mdp = netdev_priv(ndev);
-
-       switch (mdp->speed) {
-       case 10: /* 10BASE */
-               sh_eth_write(ndev, 0x00000000, GECMR);
-               break;
-       case 100:/* 100BASE */
-               sh_eth_write(ndev, 0x00000010, GECMR);
-               break;
-       case 1000: /* 1000BASE */
-               sh_eth_write(ndev, 0x00000020, GECMR);
-               break;
-       default:
-               break;
-       }
-}
-
-/* SH7757(GETHERC) */
-static struct sh_eth_cpu_data sh_eth_my_cpu_data_giga = {
-       .chip_reset     = sh_eth_chip_reset_giga,
-       .set_duplex     = sh_eth_set_duplex_giga,
-       .set_rate       = sh_eth_set_rate_giga,
-
-       .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,
-       .fdr_value      = 0x0000072f,
-       .rmcr_value     = 0x00000001,
-
-       .apr            = 1,
-       .mpr            = 1,
-       .tpauser        = 1,
-       .bculr          = 1,
-       .hw_swap        = 1,
-       .rpadir         = 1,
-       .rpadir_value   = 2 << 16,
-       .no_trimd       = 1,
-       .no_ade         = 1,
-};
-
-static struct sh_eth_cpu_data *sh_eth_get_cpu_data(struct sh_eth_private *mdp)
-{
-       if (sh_eth_is_gether(mdp))
-               return &sh_eth_my_cpu_data_giga;
-       else
-               return &sh_eth_my_cpu_data;
-}
-
-#elif defined(CONFIG_CPU_SUBTYPE_SH7763)
-#define SH_ETH_HAS_TSU 1
-static void sh_eth_chip_reset(struct net_device *ndev)
-{
-       struct sh_eth_private *mdp = netdev_priv(ndev);
-
-       /* reset device */
-       sh_eth_tsu_write(mdp, ARSTR_ARSTR, ARSTR);
-       mdelay(1);
-}
-
-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;
-       }
-}
-
-/* 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,
-       .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 = {
-       .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,
-       .tsu            = 1,
-};
-#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)
-{
-       sh_eth_write(ndev, sh_eth_read(ndev, EDMR) | EDMR_SRST_ETHER, EDMR);
-       mdelay(3);
-       sh_eth_write(ndev, sh_eth_read(ndev, EDMR) & ~EDMR_SRST_ETHER, 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 */
-static inline __u32 cpu_to_edmac(struct sh_eth_private *mdp, u32 x)
-{
-       switch (mdp->edmac_endian) {
-       case EDMAC_LITTLE_ENDIAN:
-               return cpu_to_le32(x);
-       case EDMAC_BIG_ENDIAN:
-               return cpu_to_be32(x);
-       }
-       return x;
-}
-
-static inline __u32 edmac_to_cpu(struct sh_eth_private *mdp, u32 x)
-{
-       switch (mdp->edmac_endian) {
-       case EDMAC_LITTLE_ENDIAN:
-               return le32_to_cpu(x);
-       case EDMAC_BIG_ENDIAN:
-               return be32_to_cpu(x);
-       }
-       return x;
-}
-
-/*
- * Program the hardware MAC address from dev->dev_addr.
- */
-static void update_mac_address(struct net_device *ndev)
-{
-       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);
-}
-
-/*
- * Get MAC address from SuperH MAC address register
- *
- * SuperH's Ethernet device doesn't have 'ROM' to MAC address.
- * This driver get MAC address that use by bootloader(U-boot or sh-ipl+g).
- * When you want use this device, you must set MAC address in bootloader.
- *
- */
-static void read_mac_address(struct net_device *ndev, unsigned char *mac)
-{
-       if (mac[0] || mac[1] || mac[2] || mac[3] || mac[4] || mac[5]) {
-               memcpy(ndev->dev_addr, mac, 6);
-       } else {
-               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);
-       }
-}
-
-static int sh_eth_is_gether(struct sh_eth_private *mdp)
-{
-       if (mdp->reg_offset == sh_eth_offset_gigabit)
-               return 1;
-       else
-               return 0;
-}
-
-static unsigned long sh_eth_get_edtrr_trns(struct sh_eth_private *mdp)
-{
-       if (sh_eth_is_gether(mdp))
-               return EDTRR_TRNS_GETHER;
-       else
-               return EDTRR_TRNS_ETHER;
-}
-
-struct bb_info {
-       void (*set_gate)(unsigned long addr);
-       struct mdiobb_ctrl ctrl;
-       u32 addr;
-       u32 mmd_msk;/* MMD */
-       u32 mdo_msk;
-       u32 mdi_msk;
-       u32 mdc_msk;
-};
-
-/* PHY bit set */
-static void bb_set(u32 addr, u32 msk)
-{
-       writel(readl(addr) | msk, addr);
-}
-
-/* PHY bit clear */
-static void bb_clr(u32 addr, u32 msk)
-{
-       writel((readl(addr) & ~msk), addr);
-}
-
-/* PHY bit read */
-static int bb_read(u32 addr, u32 msk)
-{
-       return (readl(addr) & msk) != 0;
-}
-
-/* Data I/O pin control */
-static void sh_mmd_ctrl(struct mdiobb_ctrl *ctrl, int bit)
-{
-       struct bb_info *bitbang = container_of(ctrl, struct bb_info, ctrl);
-
-       if (bitbang->set_gate)
-               bitbang->set_gate(bitbang->addr);
-
-       if (bit)
-               bb_set(bitbang->addr, bitbang->mmd_msk);
-       else
-               bb_clr(bitbang->addr, bitbang->mmd_msk);
-}
-
-/* Set bit data*/
-static void sh_set_mdio(struct mdiobb_ctrl *ctrl, int bit)
-{
-       struct bb_info *bitbang = container_of(ctrl, struct bb_info, ctrl);
-
-       if (bitbang->set_gate)
-               bitbang->set_gate(bitbang->addr);
-
-       if (bit)
-               bb_set(bitbang->addr, bitbang->mdo_msk);
-       else
-               bb_clr(bitbang->addr, bitbang->mdo_msk);
-}
-
-/* Get bit data*/
-static int sh_get_mdio(struct mdiobb_ctrl *ctrl)
-{
-       struct bb_info *bitbang = container_of(ctrl, struct bb_info, ctrl);
-
-       if (bitbang->set_gate)
-               bitbang->set_gate(bitbang->addr);
-
-       return bb_read(bitbang->addr, bitbang->mdi_msk);
-}
-
-/* MDC pin control */
-static void sh_mdc_ctrl(struct mdiobb_ctrl *ctrl, int bit)
-{
-       struct bb_info *bitbang = container_of(ctrl, struct bb_info, ctrl);
-
-       if (bitbang->set_gate)
-               bitbang->set_gate(bitbang->addr);
-
-       if (bit)
-               bb_set(bitbang->addr, bitbang->mdc_msk);
-       else
-               bb_clr(bitbang->addr, bitbang->mdc_msk);
-}
-
-/* mdio bus control struct */
-static struct mdiobb_ops bb_ops = {
-       .owner = THIS_MODULE,
-       .set_mdc = sh_mdc_ctrl,
-       .set_mdio_dir = sh_mmd_ctrl,
-       .set_mdio_data = sh_set_mdio,
-       .get_mdio_data = sh_get_mdio,
-};
-
-/* free skb and descriptor buffer */
-static void sh_eth_ring_free(struct net_device *ndev)
-{
-       struct sh_eth_private *mdp = netdev_priv(ndev);
-       int i;
-
-       /* Free Rx skb ringbuffer */
-       if (mdp->rx_skbuff) {
-               for (i = 0; i < RX_RING_SIZE; i++) {
-                       if (mdp->rx_skbuff[i])
-                               dev_kfree_skb(mdp->rx_skbuff[i]);
-               }
-       }
-       kfree(mdp->rx_skbuff);
-
-       /* Free Tx skb ringbuffer */
-       if (mdp->tx_skbuff) {
-               for (i = 0; i < TX_RING_SIZE; i++) {
-                       if (mdp->tx_skbuff[i])
-                               dev_kfree_skb(mdp->tx_skbuff[i]);
-               }
-       }
-       kfree(mdp->tx_skbuff);
-}
-
-/* format skb and descriptor buffer */
-static void sh_eth_ring_format(struct net_device *ndev)
-{
-       struct sh_eth_private *mdp = netdev_priv(ndev);
-       int i;
-       struct sk_buff *skb;
-       struct sh_eth_rxdesc *rxdesc = NULL;
-       struct sh_eth_txdesc *txdesc = NULL;
-       int rx_ringsize = sizeof(*rxdesc) * RX_RING_SIZE;
-       int tx_ringsize = sizeof(*txdesc) * TX_RING_SIZE;
-
-       mdp->cur_rx = mdp->cur_tx = 0;
-       mdp->dirty_rx = mdp->dirty_tx = 0;
-
-       memset(mdp->rx_ring, 0, rx_ringsize);
-
-       /* build Rx ring buffer */
-       for (i = 0; i < RX_RING_SIZE; i++) {
-               /* skb */
-               mdp->rx_skbuff[i] = NULL;
-               skb = dev_alloc_skb(mdp->rx_buf_sz);
-               mdp->rx_skbuff[i] = skb;
-               if (skb == NULL)
-                       break;
-               dma_map_single(&ndev->dev, skb->tail, mdp->rx_buf_sz,
-                               DMA_FROM_DEVICE);
-               skb->dev = ndev; /* Mark as being used by this device. */
-               sh_eth_set_receive_align(skb);
-
-               /* RX descriptor */
-               rxdesc = &mdp->rx_ring[i];
-               rxdesc->addr = virt_to_phys(PTR_ALIGN(skb->data, 4));
-               rxdesc->status = cpu_to_edmac(mdp, RD_RACT | RD_RFP);
-
-               /* The size of the buffer is 16 byte boundary. */
-               rxdesc->buffer_length = ALIGN(mdp->rx_buf_sz, 16);
-               /* Rx descriptor address set */
-               if (i == 0) {
-                       sh_eth_write(ndev, mdp->rx_desc_dma, RDLAR);
-                       if (sh_eth_is_gether(mdp))
-                               sh_eth_write(ndev, mdp->rx_desc_dma, RDFAR);
-               }
-       }
-
-       mdp->dirty_rx = (u32) (i - RX_RING_SIZE);
-
-       /* Mark the last entry as wrapping the ring. */
-       rxdesc->status |= cpu_to_edmac(mdp, RD_RDEL);
-
-       memset(mdp->tx_ring, 0, tx_ringsize);
-
-       /* build Tx ring buffer */
-       for (i = 0; i < TX_RING_SIZE; i++) {
-               mdp->tx_skbuff[i] = NULL;
-               txdesc = &mdp->tx_ring[i];
-               txdesc->status = cpu_to_edmac(mdp, TD_TFP);
-               txdesc->buffer_length = 0;
-               if (i == 0) {
-                       /* Tx descriptor address set */
-                       sh_eth_write(ndev, mdp->tx_desc_dma, TDLAR);
-                       if (sh_eth_is_gether(mdp))
-                               sh_eth_write(ndev, mdp->tx_desc_dma, TDFAR);
-               }
-       }
-
-       txdesc->status |= cpu_to_edmac(mdp, TD_TDLE);
-}
-
-/* Get skb and descriptor buffer */
-static int sh_eth_ring_init(struct net_device *ndev)
-{
-       struct sh_eth_private *mdp = netdev_priv(ndev);
-       int rx_ringsize, tx_ringsize, ret = 0;
-
-       /*
-        * +26 gets the maximum ethernet encapsulation, +7 & ~7 because the
-        * card needs room to do 8 byte alignment, +2 so we can reserve
-        * the first 2 bytes, and +16 gets room for the status word from the
-        * card.
-        */
-       mdp->rx_buf_sz = (ndev->mtu <= 1492 ? PKT_BUF_SZ :
-                         (((ndev->mtu + 26 + 7) & ~7) + 2 + 16));
-       if (mdp->cd->rpadir)
-               mdp->rx_buf_sz += NET_IP_ALIGN;
-
-       /* Allocate RX and TX skb rings */
-       mdp->rx_skbuff = kmalloc(sizeof(*mdp->rx_skbuff) * RX_RING_SIZE,
-                               GFP_KERNEL);
-       if (!mdp->rx_skbuff) {
-               dev_err(&ndev->dev, "Cannot allocate Rx skb\n");
-               ret = -ENOMEM;
-               return ret;
-       }
-
-       mdp->tx_skbuff = kmalloc(sizeof(*mdp->tx_skbuff) * TX_RING_SIZE,
-                               GFP_KERNEL);
-       if (!mdp->tx_skbuff) {
-               dev_err(&ndev->dev, "Cannot allocate Tx skb\n");
-               ret = -ENOMEM;
-               goto skb_ring_free;
-       }
-
-       /* Allocate all Rx descriptors. */
-       rx_ringsize = sizeof(struct sh_eth_rxdesc) * RX_RING_SIZE;
-       mdp->rx_ring = dma_alloc_coherent(NULL, rx_ringsize, &mdp->rx_desc_dma,
-                       GFP_KERNEL);
-
-       if (!mdp->rx_ring) {
-               dev_err(&ndev->dev, "Cannot allocate Rx Ring (size %d bytes)\n",
-                       rx_ringsize);
-               ret = -ENOMEM;
-               goto desc_ring_free;
-       }
-
-       mdp->dirty_rx = 0;
-
-       /* Allocate all Tx descriptors. */
-       tx_ringsize = sizeof(struct sh_eth_txdesc) * TX_RING_SIZE;
-       mdp->tx_ring = dma_alloc_coherent(NULL, tx_ringsize, &mdp->tx_desc_dma,
-                       GFP_KERNEL);
-       if (!mdp->tx_ring) {
-               dev_err(&ndev->dev, "Cannot allocate Tx Ring (size %d bytes)\n",
-                       tx_ringsize);
-               ret = -ENOMEM;
-               goto desc_ring_free;
-       }
-       return ret;
-
-desc_ring_free:
-       /* free DMA buffer */
-       dma_free_coherent(NULL, rx_ringsize, mdp->rx_ring, mdp->rx_desc_dma);
-
-skb_ring_free:
-       /* Free Rx and Tx skb ring buffer */
-       sh_eth_ring_free(ndev);
-
-       return ret;
-}
-
-static int sh_eth_dev_init(struct net_device *ndev)
-{
-       int ret = 0;
-       struct sh_eth_private *mdp = netdev_priv(ndev);
-       u_int32_t rx_int_var, tx_int_var;
-       u32 val;
-
-       /* Soft Reset */
-       sh_eth_reset(ndev);
-
-       /* Descriptor format */
-       sh_eth_ring_format(ndev);
-       if (mdp->cd->rpadir)
-               sh_eth_write(ndev, mdp->cd->rpadir_value, RPADIR);
-
-       /* all sh_eth int mask */
-       sh_eth_write(ndev, 0, EESIPR);
-
-#if defined(__LITTLE_ENDIAN__)
-       if (mdp->cd->hw_swap)
-               sh_eth_write(ndev, EDMR_EL, EDMR);
-       else
-#endif
-               sh_eth_write(ndev, 0, EDMR);
-
-       /* FIFO size set */
-       sh_eth_write(ndev, mdp->cd->fdr_value, FDR);
-       sh_eth_write(ndev, 0, TFTR);
-
-       /* Frame recv control */
-       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;
-       sh_eth_write(ndev, rx_int_var | tx_int_var, TRSCER);
-
-       if (mdp->cd->bculr)
-               sh_eth_write(ndev, 0x800, BCULR);       /* Burst sycle set */
-
-       sh_eth_write(ndev, mdp->cd->fcftr_value, FCFTR);
-
-       if (!mdp->cd->no_trimd)
-               sh_eth_write(ndev, 0, TRIMD);
-
-       /* Recv frame limit set register */
-       sh_eth_write(ndev, RFLR_VALUE, RFLR);
-
-       sh_eth_write(ndev, sh_eth_read(ndev, EESR), EESR);
-       sh_eth_write(ndev, mdp->cd->eesipr_value, EESIPR);
-
-       /* PAUSE Prohibition */
-       val = (sh_eth_read(ndev, ECMR) & ECMR_DM) |
-               ECMR_ZPF | (mdp->duplex ? ECMR_DM : 0) | ECMR_TE | ECMR_RE;
-
-       sh_eth_write(ndev, val, ECMR);
-
-       if (mdp->cd->set_rate)
-               mdp->cd->set_rate(ndev);
-
-       /* E-MAC Status Register clear */
-       sh_eth_write(ndev, mdp->cd->ecsr_value, ECSR);
-
-       /* E-MAC Interrupt Enable register */
-       sh_eth_write(ndev, mdp->cd->ecsipr_value, ECSIPR);
-
-       /* Set MAC address */
-       update_mac_address(ndev);
-
-       /* mask reset */
-       if (mdp->cd->apr)
-               sh_eth_write(ndev, APR_AP, APR);
-       if (mdp->cd->mpr)
-               sh_eth_write(ndev, MPR_MP, MPR);
-       if (mdp->cd->tpauser)
-               sh_eth_write(ndev, TPAUSER_UNLIMITED, TPAUSER);
-
-       /* Setting the Rx mode will start the Rx process. */
-       sh_eth_write(ndev, EDRRR_R, EDRRR);
-
-       netif_start_queue(ndev);
-
-       return ret;
-}
-
-/* free Tx skb function */
-static int sh_eth_txfree(struct net_device *ndev)
-{
-       struct sh_eth_private *mdp = netdev_priv(ndev);
-       struct sh_eth_txdesc *txdesc;
-       int freeNum = 0;
-       int entry = 0;
-
-       for (; mdp->cur_tx - mdp->dirty_tx > 0; mdp->dirty_tx++) {
-               entry = mdp->dirty_tx % TX_RING_SIZE;
-               txdesc = &mdp->tx_ring[entry];
-               if (txdesc->status & cpu_to_edmac(mdp, TD_TACT))
-                       break;
-               /* Free the original skb. */
-               if (mdp->tx_skbuff[entry]) {
-                       dma_unmap_single(&ndev->dev, txdesc->addr,
-                                        txdesc->buffer_length, DMA_TO_DEVICE);
-                       dev_kfree_skb_irq(mdp->tx_skbuff[entry]);
-                       mdp->tx_skbuff[entry] = NULL;
-                       freeNum++;
-               }
-               txdesc->status = cpu_to_edmac(mdp, TD_TFP);
-               if (entry >= TX_RING_SIZE - 1)
-                       txdesc->status |= cpu_to_edmac(mdp, TD_TDLE);
-
-               mdp->stats.tx_packets++;
-               mdp->stats.tx_bytes += txdesc->buffer_length;
-       }
-       return freeNum;
-}
-
-/* Packet receive function */
-static int sh_eth_rx(struct net_device *ndev)
-{
-       struct sh_eth_private *mdp = netdev_priv(ndev);
-       struct sh_eth_rxdesc *rxdesc;
-
-       int entry = mdp->cur_rx % RX_RING_SIZE;
-       int boguscnt = (mdp->dirty_rx + RX_RING_SIZE) - mdp->cur_rx;
-       struct sk_buff *skb;
-       u16 pkt_len = 0;
-       u32 desc_status;
-
-       rxdesc = &mdp->rx_ring[entry];
-       while (!(rxdesc->status & cpu_to_edmac(mdp, RD_RACT))) {
-               desc_status = edmac_to_cpu(mdp, rxdesc->status);
-               pkt_len = rxdesc->frame_length;
-
-               if (--boguscnt < 0)
-                       break;
-
-               if (!(desc_status & RDFEND))
-                       mdp->stats.rx_length_errors++;
-
-               if (desc_status & (RD_RFS1 | RD_RFS2 | RD_RFS3 | RD_RFS4 |
-                                  RD_RFS5 | RD_RFS6 | RD_RFS10)) {
-                       mdp->stats.rx_errors++;
-                       if (desc_status & RD_RFS1)
-                               mdp->stats.rx_crc_errors++;
-                       if (desc_status & RD_RFS2)
-                               mdp->stats.rx_frame_errors++;
-                       if (desc_status & RD_RFS3)
-                               mdp->stats.rx_length_errors++;
-                       if (desc_status & RD_RFS4)
-                               mdp->stats.rx_length_errors++;
-                       if (desc_status & RD_RFS6)
-                               mdp->stats.rx_missed_errors++;
-                       if (desc_status & RD_RFS10)
-                               mdp->stats.rx_over_errors++;
-               } else {
-                       if (!mdp->cd->hw_swap)
-                               sh_eth_soft_swap(
-                                       phys_to_virt(ALIGN(rxdesc->addr, 4)),
-                                       pkt_len + 2);
-                       skb = mdp->rx_skbuff[entry];
-                       mdp->rx_skbuff[entry] = NULL;
-                       if (mdp->cd->rpadir)
-                               skb_reserve(skb, NET_IP_ALIGN);
-                       skb_put(skb, pkt_len);
-                       skb->protocol = eth_type_trans(skb, ndev);
-                       netif_rx(skb);
-                       mdp->stats.rx_packets++;
-                       mdp->stats.rx_bytes += pkt_len;
-               }
-               rxdesc->status |= cpu_to_edmac(mdp, RD_RACT);
-               entry = (++mdp->cur_rx) % RX_RING_SIZE;
-               rxdesc = &mdp->rx_ring[entry];
-       }
-
-       /* Refill the Rx ring buffers. */
-       for (; mdp->cur_rx - mdp->dirty_rx > 0; mdp->dirty_rx++) {
-               entry = mdp->dirty_rx % RX_RING_SIZE;
-               rxdesc = &mdp->rx_ring[entry];
-               /* The size of the buffer is 16 byte boundary. */
-               rxdesc->buffer_length = ALIGN(mdp->rx_buf_sz, 16);
-
-               if (mdp->rx_skbuff[entry] == NULL) {
-                       skb = dev_alloc_skb(mdp->rx_buf_sz);
-                       mdp->rx_skbuff[entry] = skb;
-                       if (skb == NULL)
-                               break;  /* Better luck next round. */
-                       dma_map_single(&ndev->dev, skb->tail, mdp->rx_buf_sz,
-                                       DMA_FROM_DEVICE);
-                       skb->dev = ndev;
-                       sh_eth_set_receive_align(skb);
-
-                       skb_checksum_none_assert(skb);
-                       rxdesc->addr = virt_to_phys(PTR_ALIGN(skb->data, 4));
-               }
-               if (entry >= RX_RING_SIZE - 1)
-                       rxdesc->status |=
-                               cpu_to_edmac(mdp, RD_RACT | RD_RFP | RD_RDEL);
-               else
-                       rxdesc->status |=
-                               cpu_to_edmac(mdp, RD_RACT | RD_RFP);
-       }
-
-       /* Restart Rx engine if stopped. */
-       /* If we don't need to check status, don't. -KDU */
-       if (!(sh_eth_read(ndev, EDRRR) & EDRRR_R))
-               sh_eth_write(ndev, EDRRR_R, EDRRR);
-
-       return 0;
-}
-
-static void sh_eth_rcv_snd_disable(struct net_device *ndev)
-{
-       /* disable tx and rx */
-       sh_eth_write(ndev, sh_eth_read(ndev, ECMR) &
-               ~(ECMR_RE | ECMR_TE), ECMR);
-}
-
-static void sh_eth_rcv_snd_enable(struct net_device *ndev)
-{
-       /* enable tx and rx */
-       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 felic_stat;
-       u32 link_stat;
-       u32 mask;
-
-       if (intr_status & EESR_ECI) {
-               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) {
-                       /* Link Changed */
-                       if (mdp->cd->no_psr || mdp->no_ether_link) {
-                               if (mdp->link == PHY_DOWN)
-                                       link_stat = 0;
-                               else
-                                       link_stat = PHY_ST_LINK;
-                       } else {
-                               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(ndev);
-                       else {
-                               /* Link Up */
-                               sh_eth_write(ndev, sh_eth_read(ndev, EESIPR) &
-                                         ~DMAC_M_ECI, EESIPR);
-                               /*clear int */
-                               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(ndev);
-                       }
-               }
-       }
-
-       if (intr_status & EESR_TWB) {
-               /* Write buck end. unused write back interrupt */
-               if (intr_status & EESR_TABT)    /* Transmit Abort int */
-                       mdp->stats.tx_aborted_errors++;
-                       if (netif_msg_tx_err(mdp))
-                               dev_err(&ndev->dev, "Transmit Abort\n");
-       }
-
-       if (intr_status & EESR_RABT) {
-               /* Receive Abort int */
-               if (intr_status & EESR_RFRMER) {
-                       /* Receive Frame Overflow int */
-                       mdp->stats.rx_frame_errors++;
-                       if (netif_msg_rx_err(mdp))
-                               dev_err(&ndev->dev, "Receive Abort\n");
-               }
-       }
-
-       if (intr_status & EESR_TDE) {
-               /* Transmit Descriptor Empty int */
-               mdp->stats.tx_fifo_errors++;
-               if (netif_msg_tx_err(mdp))
-                       dev_err(&ndev->dev, "Transmit Descriptor Empty\n");
-       }
-
-       if (intr_status & EESR_TFE) {
-               /* FIFO under flow */
-               mdp->stats.tx_fifo_errors++;
-               if (netif_msg_tx_err(mdp))
-                       dev_err(&ndev->dev, "Transmit FIFO Under flow\n");
-       }
-
-       if (intr_status & EESR_RDE) {
-               /* Receive Descriptor Empty int */
-               mdp->stats.rx_over_errors++;
-
-               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");
-       }
-
-       if (intr_status & EESR_RFE) {
-               /* Receive FIFO Overflow int */
-               mdp->stats.rx_fifo_errors++;
-               if (netif_msg_rx_err(mdp))
-                       dev_err(&ndev->dev, "Receive FIFO Overflow\n");
-       }
-
-       if (!mdp->cd->no_ade && (intr_status & EESR_ADE)) {
-               /* Address Error */
-               mdp->stats.tx_fifo_errors++;
-               if (netif_msg_tx_err(mdp))
-                       dev_err(&ndev->dev, "Address Error\n");
-       }
-
-       mask = EESR_TWB | EESR_TABT | EESR_ADE | EESR_TDE | EESR_TFE;
-       if (mdp->cd->no_ade)
-               mask &= ~EESR_ADE;
-       if (intr_status & mask) {
-               /* Tx error */
-               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);
-               dev_err(&ndev->dev, "dirty_tx=%8.8x state=%8.8x EDTRR=%8.8x.\n",
-                               mdp->dirty_tx, (u32) ndev->state, edtrr);
-               /* dirty buffer free */
-               sh_eth_txfree(ndev);
-
-               /* SH7712 BUG */
-               if (edtrr ^ sh_eth_get_edtrr_trns(mdp)) {
-                       /* tx dma start */
-                       sh_eth_write(ndev, sh_eth_get_edtrr_trns(mdp), EDTRR);
-               }
-               /* wakeup */
-               netif_wake_queue(ndev);
-       }
-}
-
-static irqreturn_t sh_eth_interrupt(int irq, void *netdev)
-{
-       struct net_device *ndev = netdev;
-       struct sh_eth_private *mdp = netdev_priv(ndev);
-       struct sh_eth_cpu_data *cd = mdp->cd;
-       irqreturn_t ret = IRQ_NONE;
-       u32 intr_status = 0;
-
-       spin_lock(&mdp->lock);
-
-       /* Get interrpt stat */
-       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)) {
-               sh_eth_write(ndev, intr_status, EESR);
-               ret = IRQ_HANDLED;
-       } else
-               goto other_irq;
-
-       if (intr_status & (EESR_FRC | /* Frame recv*/
-                       EESR_RMAF | /* Multi cast address recv*/
-                       EESR_RRF  | /* Bit frame recv */
-                       EESR_RTLF | /* Long frame recv*/
-                       EESR_RTSF | /* short frame recv */
-                       EESR_PRE  | /* PHY-LSI recv error */
-                       EESR_CERF)){ /* recv frame CRC error */
-               sh_eth_rx(ndev);
-       }
-
-       /* Tx Check */
-       if (intr_status & cd->tx_check) {
-               sh_eth_txfree(ndev);
-               netif_wake_queue(ndev);
-       }
-
-       if (intr_status & cd->eesr_err_check)
-               sh_eth_error(ndev, intr_status);
-
-other_irq:
-       spin_unlock(&mdp->lock);
-
-       return ret;
-}
-
-static void sh_eth_timer(unsigned long data)
-{
-       struct net_device *ndev = (struct net_device *)data;
-       struct sh_eth_private *mdp = netdev_priv(ndev);
-
-       mod_timer(&mdp->timer, jiffies + (10 * HZ));
-}
-
-/* PHY state control function */
-static void sh_eth_adjust_link(struct net_device *ndev)
-{
-       struct sh_eth_private *mdp = netdev_priv(ndev);
-       struct phy_device *phydev = mdp->phydev;
-       int new_state = 0;
-
-       if (phydev->link != PHY_DOWN) {
-               if (phydev->duplex != mdp->duplex) {
-                       new_state = 1;
-                       mdp->duplex = phydev->duplex;
-                       if (mdp->cd->set_duplex)
-                               mdp->cd->set_duplex(ndev);
-               }
-
-               if (phydev->speed != mdp->speed) {
-                       new_state = 1;
-                       mdp->speed = phydev->speed;
-                       if (mdp->cd->set_rate)
-                               mdp->cd->set_rate(ndev);
-               }
-               if (mdp->link == PHY_DOWN) {
-                       sh_eth_write(ndev,
-                               (sh_eth_read(ndev, ECMR) & ~ECMR_TXF), ECMR);
-                       new_state = 1;
-                       mdp->link = phydev->link;
-               }
-       } else if (mdp->link) {
-               new_state = 1;
-               mdp->link = PHY_DOWN;
-               mdp->speed = 0;
-               mdp->duplex = -1;
-       }
-
-       if (new_state && netif_msg_link(mdp))
-               phy_print_status(phydev);
-}
-
-/* PHY init function */
-static int sh_eth_phy_init(struct net_device *ndev)
-{
-       struct sh_eth_private *mdp = netdev_priv(ndev);
-       char phy_id[MII_BUS_ID_SIZE + 3];
-       struct phy_device *phydev = NULL;
-
-       snprintf(phy_id, sizeof(phy_id), PHY_ID_FMT,
-               mdp->mii_bus->id , mdp->phy_id);
-
-       mdp->link = PHY_DOWN;
-       mdp->speed = 0;
-       mdp->duplex = -1;
-
-       /* Try connect to PHY */
-       phydev = phy_connect(ndev, phy_id, sh_eth_adjust_link,
-                               0, mdp->phy_interface);
-       if (IS_ERR(phydev)) {
-               dev_err(&ndev->dev, "phy_connect failed\n");
-               return PTR_ERR(phydev);
-       }
-
-       dev_info(&ndev->dev, "attached phy %i to driver %s\n",
-               phydev->addr, phydev->drv->name);
-
-       mdp->phydev = phydev;
-
-       return 0;
-}
-
-/* PHY control start function */
-static int sh_eth_phy_start(struct net_device *ndev)
-{
-       struct sh_eth_private *mdp = netdev_priv(ndev);
-       int ret;
-
-       ret = sh_eth_phy_init(ndev);
-       if (ret)
-               return ret;
-
-       /* reset phy - this also wakes it from PDOWN */
-       phy_write(mdp->phydev, MII_BMCR, BMCR_RESET);
-       phy_start(mdp->phydev);
-
-       return 0;
-}
-
-static int sh_eth_get_settings(struct net_device *ndev,
-                       struct ethtool_cmd *ecmd)
-{
-       struct sh_eth_private *mdp = netdev_priv(ndev);
-       unsigned long flags;
-       int ret;
-
-       spin_lock_irqsave(&mdp->lock, flags);
-       ret = phy_ethtool_gset(mdp->phydev, ecmd);
-       spin_unlock_irqrestore(&mdp->lock, flags);
-
-       return ret;
-}
-
-static int sh_eth_set_settings(struct net_device *ndev,
-               struct ethtool_cmd *ecmd)
-{
-       struct sh_eth_private *mdp = netdev_priv(ndev);
-       unsigned long flags;
-       int ret;
-
-       spin_lock_irqsave(&mdp->lock, flags);
-
-       /* disable tx and rx */
-       sh_eth_rcv_snd_disable(ndev);
-
-       ret = phy_ethtool_sset(mdp->phydev, ecmd);
-       if (ret)
-               goto error_exit;
-
-       if (ecmd->duplex == DUPLEX_FULL)
-               mdp->duplex = 1;
-       else
-               mdp->duplex = 0;
-
-       if (mdp->cd->set_duplex)
-               mdp->cd->set_duplex(ndev);
-
-error_exit:
-       mdelay(1);
-
-       /* enable tx and rx */
-       sh_eth_rcv_snd_enable(ndev);
-
-       spin_unlock_irqrestore(&mdp->lock, flags);
-
-       return ret;
-}
-
-static int sh_eth_nway_reset(struct net_device *ndev)
-{
-       struct sh_eth_private *mdp = netdev_priv(ndev);
-       unsigned long flags;
-       int ret;
-
-       spin_lock_irqsave(&mdp->lock, flags);
-       ret = phy_start_aneg(mdp->phydev);
-       spin_unlock_irqrestore(&mdp->lock, flags);
-
-       return ret;
-}
-
-static u32 sh_eth_get_msglevel(struct net_device *ndev)
-{
-       struct sh_eth_private *mdp = netdev_priv(ndev);
-       return mdp->msg_enable;
-}
-
-static void sh_eth_set_msglevel(struct net_device *ndev, u32 value)
-{
-       struct sh_eth_private *mdp = netdev_priv(ndev);
-       mdp->msg_enable = value;
-}
-
-static const char sh_eth_gstrings_stats[][ETH_GSTRING_LEN] = {
-       "rx_current", "tx_current",
-       "rx_dirty", "tx_dirty",
-};
-#define SH_ETH_STATS_LEN  ARRAY_SIZE(sh_eth_gstrings_stats)
-
-static int sh_eth_get_sset_count(struct net_device *netdev, int sset)
-{
-       switch (sset) {
-       case ETH_SS_STATS:
-               return SH_ETH_STATS_LEN;
-       default:
-               return -EOPNOTSUPP;
-       }
-}
-
-static void sh_eth_get_ethtool_stats(struct net_device *ndev,
-                       struct ethtool_stats *stats, u64 *data)
-{
-       struct sh_eth_private *mdp = netdev_priv(ndev);
-       int i = 0;
-
-       /* device-specific stats */
-       data[i++] = mdp->cur_rx;
-       data[i++] = mdp->cur_tx;
-       data[i++] = mdp->dirty_rx;
-       data[i++] = mdp->dirty_tx;
-}
-
-static void sh_eth_get_strings(struct net_device *ndev, u32 stringset, u8 *data)
-{
-       switch (stringset) {
-       case ETH_SS_STATS:
-               memcpy(data, *sh_eth_gstrings_stats,
-                                       sizeof(sh_eth_gstrings_stats));
-               break;
-       }
-}
-
-static struct ethtool_ops sh_eth_ethtool_ops = {
-       .get_settings   = sh_eth_get_settings,
-       .set_settings   = sh_eth_set_settings,
-       .nway_reset             = sh_eth_nway_reset,
-       .get_msglevel   = sh_eth_get_msglevel,
-       .set_msglevel   = sh_eth_set_msglevel,
-       .get_link               = ethtool_op_get_link,
-       .get_strings    = sh_eth_get_strings,
-       .get_ethtool_stats  = sh_eth_get_ethtool_stats,
-       .get_sset_count     = sh_eth_get_sset_count,
-};
-
-/* network device open function */
-static int sh_eth_open(struct net_device *ndev)
-{
-       int ret = 0;
-       struct sh_eth_private *mdp = netdev_priv(ndev);
-
-       pm_runtime_get_sync(&mdp->pdev->dev);
-
-       ret = request_irq(ndev->irq, sh_eth_interrupt,
-#if defined(CONFIG_CPU_SUBTYPE_SH7763) || \
-       defined(CONFIG_CPU_SUBTYPE_SH7764) || \
-       defined(CONFIG_CPU_SUBTYPE_SH7757)
-                               IRQF_SHARED,
-#else
-                               0,
-#endif
-                               ndev->name, ndev);
-       if (ret) {
-               dev_err(&ndev->dev, "Can not assign IRQ number\n");
-               return ret;
-       }
-
-       /* Descriptor set */
-       ret = sh_eth_ring_init(ndev);
-       if (ret)
-               goto out_free_irq;
-
-       /* device init */
-       ret = sh_eth_dev_init(ndev);
-       if (ret)
-               goto out_free_irq;
-
-       /* PHY control start*/
-       ret = sh_eth_phy_start(ndev);
-       if (ret)
-               goto out_free_irq;
-
-       /* Set the timer to check for link beat. */
-       init_timer(&mdp->timer);
-       mdp->timer.expires = (jiffies + (24 * HZ)) / 10;/* 2.4 sec. */
-       setup_timer(&mdp->timer, sh_eth_timer, (unsigned long)ndev);
-
-       return ret;
-
-out_free_irq:
-       free_irq(ndev->irq, ndev);
-       pm_runtime_put_sync(&mdp->pdev->dev);
-       return ret;
-}
-
-/* Timeout function */
-static void sh_eth_tx_timeout(struct net_device *ndev)
-{
-       struct sh_eth_private *mdp = netdev_priv(ndev);
-       struct sh_eth_rxdesc *rxdesc;
-       int i;
-
-       netif_stop_queue(ndev);
-
-       if (netif_msg_timer(mdp))
-               dev_err(&ndev->dev, "%s: transmit timed out, status %8.8x,"
-              " resetting...\n", ndev->name, (int)sh_eth_read(ndev, EESR));
-
-       /* tx_errors count up */
-       mdp->stats.tx_errors++;
-
-       /* timer off */
-       del_timer_sync(&mdp->timer);
-
-       /* Free all the skbuffs in the Rx queue. */
-       for (i = 0; i < RX_RING_SIZE; i++) {
-               rxdesc = &mdp->rx_ring[i];
-               rxdesc->status = 0;
-               rxdesc->addr = 0xBADF00D0;
-               if (mdp->rx_skbuff[i])
-                       dev_kfree_skb(mdp->rx_skbuff[i]);
-               mdp->rx_skbuff[i] = NULL;
-       }
-       for (i = 0; i < TX_RING_SIZE; i++) {
-               if (mdp->tx_skbuff[i])
-                       dev_kfree_skb(mdp->tx_skbuff[i]);
-               mdp->tx_skbuff[i] = NULL;
-       }
-
-       /* device init */
-       sh_eth_dev_init(ndev);
-
-       /* timer on */
-       mdp->timer.expires = (jiffies + (24 * HZ)) / 10;/* 2.4 sec. */
-       add_timer(&mdp->timer);
-}
-
-/* Packet transmit function */
-static int sh_eth_start_xmit(struct sk_buff *skb, struct net_device *ndev)
-{
-       struct sh_eth_private *mdp = netdev_priv(ndev);
-       struct sh_eth_txdesc *txdesc;
-       u32 entry;
-       unsigned long flags;
-
-       spin_lock_irqsave(&mdp->lock, flags);
-       if ((mdp->cur_tx - mdp->dirty_tx) >= (TX_RING_SIZE - 4)) {
-               if (!sh_eth_txfree(ndev)) {
-                       if (netif_msg_tx_queued(mdp))
-                               dev_warn(&ndev->dev, "TxFD exhausted.\n");
-                       netif_stop_queue(ndev);
-                       spin_unlock_irqrestore(&mdp->lock, flags);
-                       return NETDEV_TX_BUSY;
-               }
-       }
-       spin_unlock_irqrestore(&mdp->lock, flags);
-
-       entry = mdp->cur_tx % TX_RING_SIZE;
-       mdp->tx_skbuff[entry] = skb;
-       txdesc = &mdp->tx_ring[entry];
-       /* soft swap. */
-       if (!mdp->cd->hw_swap)
-               sh_eth_soft_swap(phys_to_virt(ALIGN(txdesc->addr, 4)),
-                                skb->len + 2);
-       txdesc->addr = dma_map_single(&ndev->dev, skb->data, skb->len,
-                                     DMA_TO_DEVICE);
-       if (skb->len < ETHERSMALL)
-               txdesc->buffer_length = ETHERSMALL;
-       else
-               txdesc->buffer_length = skb->len;
-
-       if (entry >= TX_RING_SIZE - 1)
-               txdesc->status |= cpu_to_edmac(mdp, TD_TACT | TD_TDLE);
-       else
-               txdesc->status |= cpu_to_edmac(mdp, TD_TACT);
-
-       mdp->cur_tx++;
-
-       if (!(sh_eth_read(ndev, EDTRR) & sh_eth_get_edtrr_trns(mdp)))
-               sh_eth_write(ndev, sh_eth_get_edtrr_trns(mdp), EDTRR);
-
-       return NETDEV_TX_OK;
-}
-
-/* device close function */
-static int sh_eth_close(struct net_device *ndev)
-{
-       struct sh_eth_private *mdp = netdev_priv(ndev);
-       int ringsize;
-
-       netif_stop_queue(ndev);
-
-       /* Disable interrupts by clearing the interrupt mask. */
-       sh_eth_write(ndev, 0x0000, EESIPR);
-
-       /* Stop the chip's Tx and Rx processes. */
-       sh_eth_write(ndev, 0, EDTRR);
-       sh_eth_write(ndev, 0, EDRRR);
-
-       /* PHY Disconnect */
-       if (mdp->phydev) {
-               phy_stop(mdp->phydev);
-               phy_disconnect(mdp->phydev);
-       }
-
-       free_irq(ndev->irq, ndev);
-
-       del_timer_sync(&mdp->timer);
-
-       /* Free all the skbuffs in the Rx queue. */
-       sh_eth_ring_free(ndev);
-
-       /* free DMA buffer */
-       ringsize = sizeof(struct sh_eth_rxdesc) * RX_RING_SIZE;
-       dma_free_coherent(NULL, ringsize, mdp->rx_ring, mdp->rx_desc_dma);
-
-       /* free DMA buffer */
-       ringsize = sizeof(struct sh_eth_txdesc) * TX_RING_SIZE;
-       dma_free_coherent(NULL, ringsize, mdp->tx_ring, mdp->tx_desc_dma);
-
-       pm_runtime_put_sync(&mdp->pdev->dev);
-
-       return 0;
-}
-
-static struct net_device_stats *sh_eth_get_stats(struct net_device *ndev)
-{
-       struct sh_eth_private *mdp = netdev_priv(ndev);
-
-       pm_runtime_get_sync(&mdp->pdev->dev);
-
-       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 (sh_eth_is_gether(mdp)) {
-               mdp->stats.tx_carrier_errors += sh_eth_read(ndev, CERCR);
-               sh_eth_write(ndev, 0, CERCR);   /* (write clear) */
-               mdp->stats.tx_carrier_errors += sh_eth_read(ndev, CEECR);
-               sh_eth_write(ndev, 0, CEECR);   /* (write clear) */
-       } else {
-               mdp->stats.tx_carrier_errors += sh_eth_read(ndev, CNDCR);
-               sh_eth_write(ndev, 0, CNDCR);   /* (write clear) */
-       }
-       pm_runtime_put_sync(&mdp->pdev->dev);
-
-       return &mdp->stats;
-}
-
-/* ioctl to device funciotn*/
-static int sh_eth_do_ioctl(struct net_device *ndev, struct ifreq *rq,
-                               int cmd)
-{
-       struct sh_eth_private *mdp = netdev_priv(ndev);
-       struct phy_device *phydev = mdp->phydev;
-
-       if (!netif_running(ndev))
-               return -EINVAL;
-
-       if (!phydev)
-               return -ENODEV;
-
-       return phy_mii_ioctl(phydev, rq, cmd);
-}
-
-#if defined(SH_ETH_HAS_TSU)
-/* Multicast reception directions set */
-static void sh_eth_set_multicast_list(struct net_device *ndev)
-{
-       if (ndev->flags & IFF_PROMISC) {
-               /* Set promiscuous. */
-               sh_eth_write(ndev, (sh_eth_read(ndev, ECMR) & ~ECMR_MCT) |
-                               ECMR_PRM, ECMR);
-       } else {
-               /* Normal, unicast/broadcast-only mode. */
-               sh_eth_write(ndev, (sh_eth_read(ndev, ECMR) & ~ECMR_PRM) |
-                               ECMR_MCT, ECMR);
-       }
-}
-#endif /* SH_ETH_HAS_TSU */
-
-/* SuperH's TSU register init function */
-static void sh_eth_tsu_init(struct sh_eth_private *mdp)
-{
-       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 (sh_eth_is_gether(mdp)) {
-               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 {
-               sh_eth_tsu_write(mdp, 0, TSU_QTAGM0);   /* Disable QTAG(0->1) */
-               sh_eth_tsu_write(mdp, 0, TSU_QTAGM1);   /* Disable QTAG(1->0) */
-       }
-       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] */
-}
-
-/* MDIO bus release function */
-static int sh_mdio_release(struct net_device *ndev)
-{
-       struct mii_bus *bus = dev_get_drvdata(&ndev->dev);
-
-       /* unregister mdio bus */
-       mdiobus_unregister(bus);
-
-       /* remove mdio bus info from net_device */
-       dev_set_drvdata(&ndev->dev, NULL);
-
-       /* free interrupts memory */
-       kfree(bus->irq);
-
-       /* free bitbang info */
-       free_mdio_bitbang(bus);
-
-       return 0;
-}
-
-/* MDIO bus init function */
-static int sh_mdio_init(struct net_device *ndev, int id,
-                       struct sh_eth_plat_data *pd)
-{
-       int ret, i;
-       struct bb_info *bitbang;
-       struct sh_eth_private *mdp = netdev_priv(ndev);
-
-       /* create bit control struct for PHY */
-       bitbang = kzalloc(sizeof(struct bb_info), GFP_KERNEL);
-       if (!bitbang) {
-               ret = -ENOMEM;
-               goto out;
-       }
-
-       /* bitbang init */
-       bitbang->addr = ndev->base_addr + mdp->reg_offset[PIR];
-       bitbang->set_gate = pd->set_mdio_gate;
-       bitbang->mdi_msk = 0x08;
-       bitbang->mdo_msk = 0x04;
-       bitbang->mmd_msk = 0x02;/* MMD */
-       bitbang->mdc_msk = 0x01;
-       bitbang->ctrl.ops = &bb_ops;
-
-       /* MII controller setting */
-       mdp->mii_bus = alloc_mdio_bitbang(&bitbang->ctrl);
-       if (!mdp->mii_bus) {
-               ret = -ENOMEM;
-               goto out_free_bitbang;
-       }
-
-       /* Hook up MII support for ethtool */
-       mdp->mii_bus->name = "sh_mii";
-       mdp->mii_bus->parent = &ndev->dev;
-       snprintf(mdp->mii_bus->id, MII_BUS_ID_SIZE, "%x", id);
-
-       /* PHY IRQ */
-       mdp->mii_bus->irq = kmalloc(sizeof(int)*PHY_MAX_ADDR, GFP_KERNEL);
-       if (!mdp->mii_bus->irq) {
-               ret = -ENOMEM;
-               goto out_free_bus;
-       }
-
-       for (i = 0; i < PHY_MAX_ADDR; i++)
-               mdp->mii_bus->irq[i] = PHY_POLL;
-
-       /* regist mdio bus */
-       ret = mdiobus_register(mdp->mii_bus);
-       if (ret)
-               goto out_free_irq;
-
-       dev_set_drvdata(&ndev->dev, mdp->mii_bus);
-
-       return 0;
-
-out_free_irq:
-       kfree(mdp->mii_bus->irq);
-
-out_free_bus:
-       free_mdio_bitbang(mdp->mii_bus);
-
-out_free_bitbang:
-       kfree(bitbang);
-
-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,
-       .ndo_start_xmit         = sh_eth_start_xmit,
-       .ndo_get_stats          = sh_eth_get_stats,
-#if defined(SH_ETH_HAS_TSU)
-       .ndo_set_multicast_list = sh_eth_set_multicast_list,
-#endif
-       .ndo_tx_timeout         = sh_eth_tx_timeout,
-       .ndo_do_ioctl           = sh_eth_do_ioctl,
-       .ndo_validate_addr      = eth_validate_addr,
-       .ndo_set_mac_address    = eth_mac_addr,
-       .ndo_change_mtu         = eth_change_mtu,
-};
-
-static int sh_eth_drv_probe(struct platform_device *pdev)
-{
-       int ret, devno = 0;
-       struct resource *res;
-       struct net_device *ndev = NULL;
-       struct sh_eth_private *mdp = NULL;
-       struct sh_eth_plat_data *pd;
-
-       /* get base addr */
-       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (unlikely(res == NULL)) {
-               dev_err(&pdev->dev, "invalid resource\n");
-               ret = -EINVAL;
-               goto out;
-       }
-
-       ndev = alloc_etherdev(sizeof(struct sh_eth_private));
-       if (!ndev) {
-               dev_err(&pdev->dev, "Could not allocate device.\n");
-               ret = -ENOMEM;
-               goto out;
-       }
-
-       /* The sh Ether-specific entries in the device structure. */
-       ndev->base_addr = res->start;
-       devno = pdev->id;
-       if (devno < 0)
-               devno = 0;
-
-       ndev->dma = -1;
-       ret = platform_get_irq(pdev, 0);
-       if (ret < 0) {
-               ret = -ENODEV;
-               goto out_release;
-       }
-       ndev->irq = ret;
-
-       SET_NETDEV_DEV(ndev, &pdev->dev);
-
-       /* Fill in the fields of the device structure with ethernet values. */
-       ether_setup(ndev);
-
-       mdp = netdev_priv(ndev);
-       spin_lock_init(&mdp->lock);
-       mdp->pdev = pdev;
-       pm_runtime_enable(&pdev->dev);
-       pm_runtime_resume(&pdev->dev);
-
-       pd = (struct sh_eth_plat_data *)(pdev->dev.platform_data);
-       /* get PHY ID */
-       mdp->phy_id = pd->phy;
-       mdp->phy_interface = pd->phy_interface;
-       /* EDMAC endian */
-       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 */
-#if defined(SH_ETH_HAS_BOTH_MODULES)
-       mdp->cd = sh_eth_get_cpu_data(mdp);
-#else
-       mdp->cd = &sh_eth_my_cpu_data;
-#endif
-       sh_eth_set_default_cpu_data(mdp->cd);
-
-       /* set function */
-       ndev->netdev_ops = &sh_eth_netdev_ops;
-       SET_ETHTOOL_OPS(ndev, &sh_eth_ethtool_ops);
-       ndev->watchdog_timeo = TX_TIMEOUT;
-
-       /* debug message level */
-       mdp->msg_enable = SH_ETH_DEF_MSG_ENABLE;
-       mdp->post_rx = POST_RX >> (devno << 1);
-       mdp->post_fw = POST_FW >> (devno << 1);
-
-       /* read and set MAC address */
-       read_mac_address(ndev, pd->mac_addr);
-
-       /* First device only init */
-       if (!devno) {
-               if (mdp->cd->tsu) {
-                       struct resource *rtsu;
-                       rtsu = platform_get_resource(pdev, IORESOURCE_MEM, 1);
-                       if (!rtsu) {
-                               dev_err(&pdev->dev, "Not found TSU resource\n");
-                               goto out_release;
-                       }
-                       mdp->tsu_addr = ioremap(rtsu->start,
-                                               resource_size(rtsu));
-               }
-               if (mdp->cd->chip_reset)
-                       mdp->cd->chip_reset(ndev);
-
-               if (mdp->cd->tsu) {
-                       /* TSU init (Init only)*/
-                       sh_eth_tsu_init(mdp);
-               }
-       }
-
-       /* network device register */
-       ret = register_netdev(ndev);
-       if (ret)
-               goto out_release;
-
-       /* mdio bus init */
-       ret = sh_mdio_init(ndev, pdev->id, pd);
-       if (ret)
-               goto out_unregister;
-
-       /* print device information */
-       pr_info("Base address at 0x%x, %pM, IRQ %d.\n",
-              (u32)ndev->base_addr, ndev->dev_addr, ndev->irq);
-
-       platform_set_drvdata(pdev, ndev);
-
-       return ret;
-
-out_unregister:
-       unregister_netdev(ndev);
-
-out_release:
-       /* net_dev free */
-       if (mdp && mdp->tsu_addr)
-               iounmap(mdp->tsu_addr);
-       if (ndev)
-               free_netdev(ndev);
-
-out:
-       return ret;
-}
-
-static int sh_eth_drv_remove(struct platform_device *pdev)
-{
-       struct net_device *ndev = platform_get_drvdata(pdev);
-       struct sh_eth_private *mdp = netdev_priv(ndev);
-
-       iounmap(mdp->tsu_addr);
-       sh_mdio_release(ndev);
-       unregister_netdev(ndev);
-       pm_runtime_disable(&pdev->dev);
-       free_netdev(ndev);
-       platform_set_drvdata(pdev, NULL);
-
-       return 0;
-}
-
-static int sh_eth_runtime_nop(struct device *dev)
-{
-       /*
-        * Runtime PM callback shared between ->runtime_suspend()
-        * and ->runtime_resume(). Simply returns success.
-        *
-        * This driver re-initializes all registers after
-        * pm_runtime_get_sync() anyway so there is no need
-        * to save and restore registers here.
-        */
-       return 0;
-}
-
-static struct dev_pm_ops sh_eth_dev_pm_ops = {
-       .runtime_suspend = sh_eth_runtime_nop,
-       .runtime_resume = sh_eth_runtime_nop,
-};
-
-static struct platform_driver sh_eth_driver = {
-       .probe = sh_eth_drv_probe,
-       .remove = sh_eth_drv_remove,
-       .driver = {
-                  .name = CARDNAME,
-                  .pm = &sh_eth_dev_pm_ops,
-       },
-};
-
-static int __init sh_eth_init(void)
-{
-       return platform_driver_register(&sh_eth_driver);
-}
-
-static void __exit sh_eth_cleanup(void)
-{
-       platform_driver_unregister(&sh_eth_driver);
-}
-
-module_init(sh_eth_init);
-module_exit(sh_eth_cleanup);
-
-MODULE_AUTHOR("Nobuhiro Iwamatsu, Yoshihiro Shimoda");
-MODULE_DESCRIPTION("Renesas SuperH Ethernet driver");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/net/sh_eth.h b/drivers/net/sh_eth.h
deleted file mode 100644 (file)
index c3048a6..0000000
+++ /dev/null
@@ -1,837 +0,0 @@
-/*
- *  SuperH Ethernet device driver
- *
- *  Copyright (C) 2006-2008 Nobuhiro Iwamatsu
- *  Copyright (C) 2008-2011 Renesas Solutions Corp.
- *
- *  This program is free software; you can redistribute it and/or modify it
- *  under the terms and conditions of the GNU General Public License,
- *  version 2, as published by the Free Software Foundation.
- *
- *  This program is distributed in the hope it will be useful, but WITHOUT
- *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- *  more details.
- *  You should have received a copy of the GNU General Public License along with
- *  this program; if not, write to the Free Software Foundation, Inc.,
- *  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- *  The full GNU General Public License is included in this distribution in
- *  the file called "COPYING".
- */
-
-#ifndef __SH_ETH_H__
-#define __SH_ETH_H__
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/spinlock.h>
-#include <linux/netdevice.h>
-#include <linux/phy.h>
-
-#include <asm/sh_eth.h>
-
-#define CARDNAME       "sh-eth"
-#define TX_TIMEOUT     (5*HZ)
-#define TX_RING_SIZE   64      /* Tx ring size */
-#define RX_RING_SIZE   64      /* Rx ring size */
-#define ETHERSMALL             60
-#define PKT_BUF_SZ             1538
-
-enum {
-       /* E-DMAC registers */
-       EDSR = 0,
-       EDMR,
-       EDTRR,
-       EDRRR,
-       EESR,
-       EESIPR,
-       TDLAR,
-       TDFAR,
-       TDFXR,
-       TDFFR,
-       RDLAR,
-       RDFAR,
-       RDFXR,
-       RDFFR,
-       TRSCER,
-       RMFCR,
-       TFTR,
-       FDR,
-       RMCR,
-       EDOCR,
-       TFUCR,
-       RFOCR,
-       FCFTR,
-       RPADIR,
-       TRIMD,
-       RBWAR,
-       TBRAR,
-
-       /* Ether registers */
-       ECMR,
-       ECSR,
-       ECSIPR,
-       PIR,
-       PSR,
-       RDMLR,
-       PIPR,
-       RFLR,
-       IPGR,
-       APR,
-       MPR,
-       PFTCR,
-       PFRCR,
-       RFCR,
-       RFCF,
-       TPAUSER,
-       TPAUSECR,
-       BCFR,
-       BCFRR,
-       GECMR,
-       BCULR,
-       MAHR,
-       MALR,
-       TROCR,
-       CDCR,
-       LCCR,
-       CNDCR,
-       CEFCR,
-       FRECR,
-       TSFRCR,
-       TLFRCR,
-       CERCR,
-       CEECR,
-       MAFCR,
-       RTRATE,
-
-       /* TSU Absolute address */
-       ARSTR,
-       TSU_CTRST,
-       TSU_FWEN0,
-       TSU_FWEN1,
-       TSU_FCM,
-       TSU_BSYSL0,
-       TSU_BSYSL1,
-       TSU_PRISL0,
-       TSU_PRISL1,
-       TSU_FWSL0,
-       TSU_FWSL1,
-       TSU_FWSLC,
-       TSU_QTAG0,
-       TSU_QTAG1,
-       TSU_QTAGM0,
-       TSU_QTAGM1,
-       TSU_FWSR,
-       TSU_FWINMK,
-       TSU_ADQT0,
-       TSU_ADQT1,
-       TSU_VTAG0,
-       TSU_VTAG1,
-       TSU_ADSBSY,
-       TSU_TEN,
-       TSU_POST1,
-       TSU_POST2,
-       TSU_POST3,
-       TSU_POST4,
-       TSU_ADRH0,
-       TSU_ADRL0,
-       TSU_ADRH31,
-       TSU_ADRL31,
-
-       TXNLCR0,
-       TXALCR0,
-       RXNLCR0,
-       RXALCR0,
-       FWNLCR0,
-       FWALCR0,
-       TXNLCR1,
-       TXALCR1,
-       RXNLCR1,
-       RXALCR1,
-       FWNLCR1,
-       FWALCR1,
-
-       /* This value must be written at last. */
-       SH_ETH_MAX_REGISTER_OFFSET,
-};
-
-static const u16 sh_eth_offset_gigabit[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,
-
-       [ECMR]  = 0x0500,
-       [ECSR]  = 0x0510,
-       [ECSIPR]        = 0x0518,
-       [PIR]   = 0x0520,
-       [PSR]   = 0x0528,
-       [PIPR]  = 0x052c,
-       [RFLR]  = 0x0508,
-       [APR]   = 0x0554,
-       [MPR]   = 0x0558,
-       [PFTCR] = 0x055c,
-       [PFRCR] = 0x0560,
-       [TPAUSER]       = 0x0564,
-       [GECMR] = 0x05b0,
-       [BCULR] = 0x05b4,
-       [MAHR]  = 0x05c0,
-       [MALR]  = 0x05c8,
-       [TROCR] = 0x0700,
-       [CDCR]  = 0x0708,
-       [LCCR]  = 0x0710,
-       [CEFCR] = 0x0740,
-       [FRECR] = 0x0748,
-       [TSFRCR]        = 0x0750,
-       [TLFRCR]        = 0x0758,
-       [RFCR]  = 0x0760,
-       [CERCR] = 0x0768,
-       [CEECR] = 0x0770,
-       [MAFCR] = 0x0778,
-
-       [ARSTR] = 0x0000,
-       [TSU_CTRST]     = 0x0004,
-       [TSU_FWEN0]     = 0x0010,
-       [TSU_FWEN1]     = 0x0014,
-       [TSU_FCM]       = 0x0018,
-       [TSU_BSYSL0]    = 0x0020,
-       [TSU_BSYSL1]    = 0x0024,
-       [TSU_PRISL0]    = 0x0028,
-       [TSU_PRISL1]    = 0x002c,
-       [TSU_FWSL0]     = 0x0030,
-       [TSU_FWSL1]     = 0x0034,
-       [TSU_FWSLC]     = 0x0038,
-       [TSU_QTAG0]     = 0x0040,
-       [TSU_QTAG1]     = 0x0044,
-       [TSU_FWSR]      = 0x0050,
-       [TSU_FWINMK]    = 0x0054,
-       [TSU_ADQT0]     = 0x0048,
-       [TSU_ADQT1]     = 0x004c,
-       [TSU_VTAG0]     = 0x0058,
-       [TSU_VTAG1]     = 0x005c,
-       [TSU_ADSBSY]    = 0x0060,
-       [TSU_TEN]       = 0x0064,
-       [TSU_POST1]     = 0x0070,
-       [TSU_POST2]     = 0x0074,
-       [TSU_POST3]     = 0x0078,
-       [TSU_POST4]     = 0x007c,
-       [TSU_ADRH0]     = 0x0100,
-       [TSU_ADRL0]     = 0x0104,
-       [TSU_ADRH31]    = 0x01f8,
-       [TSU_ADRL31]    = 0x01fc,
-
-       [TXNLCR0]       = 0x0080,
-       [TXALCR0]       = 0x0084,
-       [RXNLCR0]       = 0x0088,
-       [RXALCR0]       = 0x008c,
-       [FWNLCR0]       = 0x0090,
-       [FWALCR0]       = 0x0094,
-       [TXNLCR1]       = 0x00a0,
-       [TXALCR1]       = 0x00a0,
-       [RXNLCR1]       = 0x00a8,
-       [RXALCR1]       = 0x00ac,
-       [FWNLCR1]       = 0x00b0,
-       [FWALCR1]       = 0x00b4,
-};
-
-static const u16 sh_eth_offset_fast_sh4[SH_ETH_MAX_REGISTER_OFFSET] = {
-       [ECMR]  = 0x0100,
-       [RFLR]  = 0x0108,
-       [ECSR]  = 0x0110,
-       [ECSIPR]        = 0x0118,
-       [PIR]   = 0x0120,
-       [PSR]   = 0x0128,
-       [RDMLR] = 0x0140,
-       [IPGR]  = 0x0150,
-       [APR]   = 0x0154,
-       [MPR]   = 0x0158,
-       [TPAUSER]       = 0x0164,
-       [RFCF]  = 0x0160,
-       [TPAUSECR]      = 0x0168,
-       [BCFRR] = 0x016c,
-       [MAHR]  = 0x01c0,
-       [MALR]  = 0x01c8,
-       [TROCR] = 0x01d0,
-       [CDCR]  = 0x01d4,
-       [LCCR]  = 0x01d8,
-       [CNDCR] = 0x01dc,
-       [CEFCR] = 0x01e4,
-       [FRECR] = 0x01e8,
-       [TSFRCR]        = 0x01ec,
-       [TLFRCR]        = 0x01f0,
-       [RFCR]  = 0x01f4,
-       [MAFCR] = 0x01f8,
-       [RTRATE]        = 0x01fc,
-
-       [EDMR]  = 0x0000,
-       [EDTRR] = 0x0008,
-       [EDRRR] = 0x0010,
-       [TDLAR] = 0x0018,
-       [RDLAR] = 0x0020,
-       [EESR]  = 0x0028,
-       [EESIPR]        = 0x0030,
-       [TRSCER]        = 0x0038,
-       [RMFCR] = 0x0040,
-       [TFTR]  = 0x0048,
-       [FDR]   = 0x0050,
-       [RMCR]  = 0x0058,
-       [TFUCR] = 0x0064,
-       [RFOCR] = 0x0068,
-       [FCFTR] = 0x0070,
-       [RPADIR]        = 0x0078,
-       [TRIMD] = 0x007c,
-       [RBWAR] = 0x00c8,
-       [RDFAR] = 0x00cc,
-       [TBRAR] = 0x00d4,
-       [TDFAR] = 0x00d8,
-};
-
-static const u16 sh_eth_offset_fast_sh3_sh2[SH_ETH_MAX_REGISTER_OFFSET] = {
-       [ECMR]  = 0x0160,
-       [ECSR]  = 0x0164,
-       [ECSIPR]        = 0x0168,
-       [PIR]   = 0x016c,
-       [MAHR]  = 0x0170,
-       [MALR]  = 0x0174,
-       [RFLR]  = 0x0178,
-       [PSR]   = 0x017c,
-       [TROCR] = 0x0180,
-       [CDCR]  = 0x0184,
-       [LCCR]  = 0x0188,
-       [CNDCR] = 0x018c,
-       [CEFCR] = 0x0194,
-       [FRECR] = 0x0198,
-       [TSFRCR]        = 0x019c,
-       [TLFRCR]        = 0x01a0,
-       [RFCR]  = 0x01a4,
-       [MAFCR] = 0x01a8,
-       [IPGR]  = 0x01b4,
-       [APR]   = 0x01b8,
-       [MPR]   = 0x01bc,
-       [TPAUSER]       = 0x01c4,
-       [BCFR]  = 0x01cc,
-
-       [ARSTR] = 0x0000,
-       [TSU_CTRST]     = 0x0004,
-       [TSU_FWEN0]     = 0x0010,
-       [TSU_FWEN1]     = 0x0014,
-       [TSU_FCM]       = 0x0018,
-       [TSU_BSYSL0]    = 0x0020,
-       [TSU_BSYSL1]    = 0x0024,
-       [TSU_PRISL0]    = 0x0028,
-       [TSU_PRISL1]    = 0x002c,
-       [TSU_FWSL0]     = 0x0030,
-       [TSU_FWSL1]     = 0x0034,
-       [TSU_FWSLC]     = 0x0038,
-       [TSU_QTAGM0]    = 0x0040,
-       [TSU_QTAGM1]    = 0x0044,
-       [TSU_ADQT0]     = 0x0048,
-       [TSU_ADQT1]     = 0x004c,
-       [TSU_FWSR]      = 0x0050,
-       [TSU_FWINMK]    = 0x0054,
-       [TSU_ADSBSY]    = 0x0060,
-       [TSU_TEN]       = 0x0064,
-       [TSU_POST1]     = 0x0070,
-       [TSU_POST2]     = 0x0074,
-       [TSU_POST3]     = 0x0078,
-       [TSU_POST4]     = 0x007c,
-
-       [TXNLCR0]       = 0x0080,
-       [TXALCR0]       = 0x0084,
-       [RXNLCR0]       = 0x0088,
-       [RXALCR0]       = 0x008c,
-       [FWNLCR0]       = 0x0090,
-       [FWALCR0]       = 0x0094,
-       [TXNLCR1]       = 0x00a0,
-       [TXALCR1]       = 0x00a0,
-       [RXNLCR1]       = 0x00a8,
-       [RXALCR1]       = 0x00ac,
-       [FWNLCR1]       = 0x00b0,
-       [FWALCR1]       = 0x00b4,
-
-       [TSU_ADRH0]     = 0x0100,
-       [TSU_ADRL0]     = 0x0104,
-       [TSU_ADRL31]    = 0x01fc,
-
-};
-
-/* 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
- */
-#ifdef CONFIG_CPU_SUBTYPE_SH7763
-/* EDSR */
-enum EDSR_BIT {
-       EDSR_ENT = 0x01, EDSR_ENR = 0x02,
-};
-#define EDSR_ENALL (EDSR_ENT|EDSR_ENR)
-
-/* GECMR */
-enum GECMR_BIT {
-       GECMR_10 = 0x0, GECMR_100 = 0x04, GECMR_1000 = 0x01,
-};
-#endif
-
-/* EDMR */
-enum DMAC_M_BIT {
-       EDMR_EL = 0x40, /* Litte endian */
-       EDMR_DL1 = 0x20, EDMR_DL0 = 0x10,
-       EDMR_SRST_GETHER = 0x03,
-       EDMR_SRST_ETHER = 0x01,
-};
-
-/* EDTRR */
-enum DMAC_T_BIT {
-       EDTRR_TRNS_GETHER = 0x03,
-       EDTRR_TRNS_ETHER = 0x01,
-};
-
-/* EDRRR*/
-enum EDRRR_R_BIT {
-       EDRRR_R = 0x01,
-};
-
-/* TPAUSER */
-enum TPAUSER_BIT {
-       TPAUSER_TPAUSE = 0x0000ffff,
-       TPAUSER_UNLIMITED = 0,
-};
-
-/* BCFR */
-enum BCFR_BIT {
-       BCFR_RPAUSE = 0x0000ffff,
-       BCFR_UNLIMITED = 0,
-};
-
-/* PIR */
-enum PIR_BIT {
-       PIR_MDI = 0x08, PIR_MDO = 0x04, PIR_MMD = 0x02, PIR_MDC = 0x01,
-};
-
-/* PSR */
-enum PHY_STATUS_BIT { PHY_ST_LINK = 0x01, };
-
-/* EESR */
-enum EESR_BIT {
-       EESR_TWB1       = 0x80000000,
-       EESR_TWB        = 0x40000000,   /* same as TWB0 */
-       EESR_TC1        = 0x20000000,
-       EESR_TUC        = 0x10000000,
-       EESR_ROC        = 0x08000000,
-       EESR_TABT       = 0x04000000,
-       EESR_RABT       = 0x02000000,
-       EESR_RFRMER     = 0x01000000,   /* same as RFCOF */
-       EESR_ADE        = 0x00800000,
-       EESR_ECI        = 0x00400000,
-       EESR_FTC        = 0x00200000,   /* same as TC or TC0 */
-       EESR_TDE        = 0x00100000,
-       EESR_TFE        = 0x00080000,   /* same as TFUF */
-       EESR_FRC        = 0x00040000,   /* same as FR */
-       EESR_RDE        = 0x00020000,
-       EESR_RFE        = 0x00010000,
-       EESR_CND        = 0x00000800,
-       EESR_DLC        = 0x00000400,
-       EESR_CD         = 0x00000200,
-       EESR_RTO        = 0x00000100,
-       EESR_RMAF       = 0x00000080,
-       EESR_CEEF       = 0x00000040,
-       EESR_CELF       = 0x00000020,
-       EESR_RRF        = 0x00000010,
-       EESR_RTLF       = 0x00000008,
-       EESR_RTSF       = 0x00000004,
-       EESR_PRE        = 0x00000002,
-       EESR_CERF       = 0x00000001,
-};
-
-#define DEFAULT_TX_CHECK       (EESR_FTC | EESR_CND | EESR_DLC | EESR_CD | \
-                                EESR_RTO)
-#define DEFAULT_EESR_ERR_CHECK (EESR_TWB | EESR_TABT | EESR_RABT | \
-                                EESR_RDE | EESR_RFRMER | EESR_ADE | \
-                                EESR_TFE | EESR_TDE | EESR_ECI)
-#define DEFAULT_TX_ERROR_CHECK (EESR_TWB | EESR_TABT | EESR_ADE | EESR_TDE | \
-                                EESR_TFE)
-
-/* EESIPR */
-enum DMAC_IM_BIT {
-       DMAC_M_TWB = 0x40000000, DMAC_M_TABT = 0x04000000,
-       DMAC_M_RABT = 0x02000000,
-       DMAC_M_RFRMER = 0x01000000, DMAC_M_ADF = 0x00800000,
-       DMAC_M_ECI = 0x00400000, DMAC_M_FTC = 0x00200000,
-       DMAC_M_TDE = 0x00100000, DMAC_M_TFE = 0x00080000,
-       DMAC_M_FRC = 0x00040000, DMAC_M_RDE = 0x00020000,
-       DMAC_M_RFE = 0x00010000, DMAC_M_TINT4 = 0x00000800,
-       DMAC_M_TINT3 = 0x00000400, DMAC_M_TINT2 = 0x00000200,
-       DMAC_M_TINT1 = 0x00000100, DMAC_M_RINT8 = 0x00000080,
-       DMAC_M_RINT5 = 0x00000010, DMAC_M_RINT4 = 0x00000008,
-       DMAC_M_RINT3 = 0x00000004, DMAC_M_RINT2 = 0x00000002,
-       DMAC_M_RINT1 = 0x00000001,
-};
-
-/* Receive descriptor bit */
-enum RD_STS_BIT {
-       RD_RACT = 0x80000000, RD_RDEL = 0x40000000,
-       RD_RFP1 = 0x20000000, RD_RFP0 = 0x10000000,
-       RD_RFE = 0x08000000, RD_RFS10 = 0x00000200,
-       RD_RFS9 = 0x00000100, RD_RFS8 = 0x00000080,
-       RD_RFS7 = 0x00000040, RD_RFS6 = 0x00000020,
-       RD_RFS5 = 0x00000010, RD_RFS4 = 0x00000008,
-       RD_RFS3 = 0x00000004, RD_RFS2 = 0x00000002,
-       RD_RFS1 = 0x00000001,
-};
-#define RDF1ST RD_RFP1
-#define RDFEND RD_RFP0
-#define RD_RFP (RD_RFP1|RD_RFP0)
-
-/* FCFTR */
-enum FCFTR_BIT {
-       FCFTR_RFF2 = 0x00040000, FCFTR_RFF1 = 0x00020000,
-       FCFTR_RFF0 = 0x00010000, FCFTR_RFD2 = 0x00000004,
-       FCFTR_RFD1 = 0x00000002, FCFTR_RFD0 = 0x00000001,
-};
-#define DEFAULT_FIFO_F_D_RFF   (FCFTR_RFF2 | FCFTR_RFF1 | FCFTR_RFF0)
-#define DEFAULT_FIFO_F_D_RFD   (FCFTR_RFD2 | FCFTR_RFD1 | FCFTR_RFD0)
-
-/* Transfer descriptor bit */
-enum TD_STS_BIT {
-       TD_TACT = 0x80000000,
-       TD_TDLE = 0x40000000, TD_TFP1 = 0x20000000,
-       TD_TFP0 = 0x10000000,
-};
-#define TDF1ST TD_TFP1
-#define TDFEND TD_TFP0
-#define TD_TFP (TD_TFP1|TD_TFP0)
-
-/* RMCR */
-#define DEFAULT_RMCR_VALUE     0x00000000
-
-/* ECMR */
-enum FELIC_MODE_BIT {
-       ECMR_TRCCM = 0x04000000, ECMR_RCSC = 0x00800000,
-       ECMR_DPAD = 0x00200000, ECMR_RZPF = 0x00100000,
-       ECMR_ZPF = 0x00080000, ECMR_PFR = 0x00040000, ECMR_RXF = 0x00020000,
-       ECMR_TXF = 0x00010000, ECMR_MCT = 0x00002000, ECMR_PRCEF = 0x00001000,
-       ECMR_PMDE = 0x00000200, ECMR_RE = 0x00000040, ECMR_TE = 0x00000020,
-       ECMR_RTM = 0x00000010, ECMR_ILB = 0x00000008, ECMR_ELB = 0x00000004,
-       ECMR_DM = 0x00000002, ECMR_PRM = 0x00000001,
-};
-
-/* ECSR */
-enum ECSR_STATUS_BIT {
-       ECSR_BRCRX = 0x20, ECSR_PSRTO = 0x10,
-       ECSR_LCHNG = 0x04,
-       ECSR_MPD = 0x02, ECSR_ICD = 0x01,
-};
-
-#define DEFAULT_ECSR_INIT      (ECSR_BRCRX | ECSR_PSRTO | ECSR_LCHNG | \
-                                ECSR_ICD | ECSIPR_MPDIP)
-
-/* ECSIPR */
-enum ECSIPR_STATUS_MASK_BIT {
-       ECSIPR_BRCRXIP = 0x20, ECSIPR_PSRTOIP = 0x10,
-       ECSIPR_LCHNGIP = 0x04,
-       ECSIPR_MPDIP = 0x02, ECSIPR_ICDIP = 0x01,
-};
-
-#define DEFAULT_ECSIPR_INIT    (ECSIPR_BRCRXIP | ECSIPR_PSRTOIP | \
-                                ECSIPR_LCHNGIP | ECSIPR_ICDIP | ECSIPR_MPDIP)
-
-/* APR */
-enum APR_BIT {
-       APR_AP = 0x00000001,
-};
-
-/* MPR */
-enum MPR_BIT {
-       MPR_MP = 0x00000001,
-};
-
-/* TRSCER */
-enum DESC_I_BIT {
-       DESC_I_TINT4 = 0x0800, DESC_I_TINT3 = 0x0400, DESC_I_TINT2 = 0x0200,
-       DESC_I_TINT1 = 0x0100, DESC_I_RINT8 = 0x0080, DESC_I_RINT5 = 0x0010,
-       DESC_I_RINT4 = 0x0008, DESC_I_RINT3 = 0x0004, DESC_I_RINT2 = 0x0002,
-       DESC_I_RINT1 = 0x0001,
-};
-
-/* RPADIR */
-enum RPADIR_BIT {
-       RPADIR_PADS1 = 0x20000, RPADIR_PADS0 = 0x10000,
-       RPADIR_PADR = 0x0003f,
-};
-
-/* RFLR */
-#define RFLR_VALUE 0x1000
-
-/* FDR */
-#define DEFAULT_FDR_INIT       0x00000707
-
-enum phy_offsets {
-       PHY_CTRL = 0, PHY_STAT = 1, PHY_IDT1 = 2, PHY_IDT2 = 3,
-       PHY_ANA = 4, PHY_ANL = 5, PHY_ANE = 6,
-       PHY_16 = 16,
-};
-
-/* PHY_CTRL */
-enum PHY_CTRL_BIT {
-       PHY_C_RESET = 0x8000, PHY_C_LOOPBK = 0x4000, PHY_C_SPEEDSL = 0x2000,
-       PHY_C_ANEGEN = 0x1000, PHY_C_PWRDN = 0x0800, PHY_C_ISO = 0x0400,
-       PHY_C_RANEG = 0x0200, PHY_C_DUPLEX = 0x0100, PHY_C_COLT = 0x0080,
-};
-#define DM9161_PHY_C_ANEGEN 0  /* auto nego special */
-
-/* PHY_STAT */
-enum PHY_STAT_BIT {
-       PHY_S_100T4 = 0x8000, PHY_S_100X_F = 0x4000, PHY_S_100X_H = 0x2000,
-       PHY_S_10T_F = 0x1000, PHY_S_10T_H = 0x0800, PHY_S_ANEGC = 0x0020,
-       PHY_S_RFAULT = 0x0010, PHY_S_ANEGA = 0x0008, PHY_S_LINK = 0x0004,
-       PHY_S_JAB = 0x0002, PHY_S_EXTD = 0x0001,
-};
-
-/* PHY_ANA */
-enum PHY_ANA_BIT {
-       PHY_A_NP = 0x8000, PHY_A_ACK = 0x4000, PHY_A_RF = 0x2000,
-       PHY_A_FCS = 0x0400, PHY_A_T4 = 0x0200, PHY_A_FDX = 0x0100,
-       PHY_A_HDX = 0x0080, PHY_A_10FDX = 0x0040, PHY_A_10HDX = 0x0020,
-       PHY_A_SEL = 0x001e,
-};
-/* PHY_ANL */
-enum PHY_ANL_BIT {
-       PHY_L_NP = 0x8000, PHY_L_ACK = 0x4000, PHY_L_RF = 0x2000,
-       PHY_L_FCS = 0x0400, PHY_L_T4 = 0x0200, PHY_L_FDX = 0x0100,
-       PHY_L_HDX = 0x0080, PHY_L_10FDX = 0x0040, PHY_L_10HDX = 0x0020,
-       PHY_L_SEL = 0x001f,
-};
-
-/* PHY_ANE */
-enum PHY_ANE_BIT {
-       PHY_E_PDF = 0x0010, PHY_E_LPNPA = 0x0008, PHY_E_NPA = 0x0004,
-       PHY_E_PRX = 0x0002, PHY_E_LPANEGA = 0x0001,
-};
-
-/* DM9161 */
-enum PHY_16_BIT {
-       PHY_16_BP4B45 = 0x8000, PHY_16_BPSCR = 0x4000, PHY_16_BPALIGN = 0x2000,
-       PHY_16_BP_ADPOK = 0x1000, PHY_16_Repeatmode = 0x0800,
-       PHY_16_TXselect = 0x0400,
-       PHY_16_Rsvd = 0x0200, PHY_16_RMIIEnable = 0x0100,
-       PHY_16_Force100LNK = 0x0080,
-       PHY_16_APDLED_CTL = 0x0040, PHY_16_COLLED_CTL = 0x0020,
-       PHY_16_RPDCTR_EN = 0x0010,
-       PHY_16_ResetStMch = 0x0008, PHY_16_PreamSupr = 0x0004,
-       PHY_16_Sleepmode = 0x0002,
-       PHY_16_RemoteLoopOut = 0x0001,
-};
-
-#define POST_RX                0x08
-#define POST_FW                0x04
-#define POST0_RX       (POST_RX)
-#define POST0_FW       (POST_FW)
-#define POST1_RX       (POST_RX >> 2)
-#define POST1_FW       (POST_FW >> 2)
-#define POST_ALL       (POST0_RX | POST0_FW | POST1_RX | POST1_FW)
-
-/* ARSTR */
-enum ARSTR_BIT { ARSTR_ARSTR = 0x00000001, };
-
-/* TSU_FWEN0 */
-enum TSU_FWEN0_BIT {
-       TSU_FWEN0_0 = 0x00000001,
-};
-
-/* TSU_ADSBSY */
-enum TSU_ADSBSY_BIT {
-       TSU_ADSBSY_0 = 0x00000001,
-};
-
-/* TSU_TEN */
-enum TSU_TEN_BIT {
-       TSU_TEN_0 = 0x80000000,
-};
-
-/* TSU_FWSL0 */
-enum TSU_FWSL0_BIT {
-       TSU_FWSL0_FW50 = 0x1000, TSU_FWSL0_FW40 = 0x0800,
-       TSU_FWSL0_FW30 = 0x0400, TSU_FWSL0_FW20 = 0x0200,
-       TSU_FWSL0_FW10 = 0x0100, TSU_FWSL0_RMSA0 = 0x0010,
-};
-
-/* TSU_FWSLC */
-enum TSU_FWSLC_BIT {
-       TSU_FWSLC_POSTENU = 0x2000, TSU_FWSLC_POSTENL = 0x1000,
-       TSU_FWSLC_CAMSEL03 = 0x0080, TSU_FWSLC_CAMSEL02 = 0x0040,
-       TSU_FWSLC_CAMSEL01 = 0x0020, TSU_FWSLC_CAMSEL00 = 0x0010,
-       TSU_FWSLC_CAMSEL13 = 0x0008, TSU_FWSLC_CAMSEL12 = 0x0004,
-       TSU_FWSLC_CAMSEL11 = 0x0002, TSU_FWSLC_CAMSEL10 = 0x0001,
-};
-
-/*
- * The sh ether Tx buffer descriptors.
- * This structure should be 20 bytes.
- */
-struct sh_eth_txdesc {
-       u32 status;             /* TD0 */
-#if defined(CONFIG_CPU_LITTLE_ENDIAN)
-       u16 pad0;               /* TD1 */
-       u16 buffer_length;      /* TD1 */
-#else
-       u16 buffer_length;      /* TD1 */
-       u16 pad0;               /* TD1 */
-#endif
-       u32 addr;               /* TD2 */
-       u32 pad1;               /* padding data */
-} __attribute__((aligned(2), packed));
-
-/*
- * The sh ether Rx buffer descriptors.
- * This structure should be 20 bytes.
- */
-struct sh_eth_rxdesc {
-       u32 status;             /* RD0 */
-#if defined(CONFIG_CPU_LITTLE_ENDIAN)
-       u16 frame_length;       /* RD1 */
-       u16 buffer_length;      /* RD1 */
-#else
-       u16 buffer_length;      /* RD1 */
-       u16 frame_length;       /* RD1 */
-#endif
-       u32 addr;               /* RD2 */
-       u32 pad0;               /* padding data */
-} __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 tsu:1;                 /* EtherC have TSU */
-       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 platform_device *pdev;
-       struct sh_eth_cpu_data *cd;
-       const u16 *reg_offset;
-       void __iomem *tsu_addr;
-       dma_addr_t rx_desc_dma;
-       dma_addr_t tx_desc_dma;
-       struct sh_eth_rxdesc *rx_ring;
-       struct sh_eth_txdesc *tx_ring;
-       struct sk_buff **rx_skbuff;
-       struct sk_buff **tx_skbuff;
-       struct net_device_stats stats;
-       struct timer_list timer;
-       spinlock_t lock;
-       u32 cur_rx, dirty_rx;   /* Producer/consumer ring indices */
-       u32 cur_tx, dirty_tx;
-       u32 rx_buf_sz;          /* Based on MTU+slack. */
-       int edmac_endian;
-       /* MII transceiver section. */
-       u32 phy_id;                                     /* PHY ID */
-       struct mii_bus *mii_bus;        /* MDIO bus control */
-       struct phy_device *phydev;      /* PHY device control */
-       enum phy_state link;
-       phy_interface_t phy_interface;
-       int msg_enable;
-       int speed;
-       int duplex;
-       u32 rx_int_var, tx_int_var;     /* interrupt control variables */
-       char post_rx;           /* POST receive */
-       char post_fw;           /* POST forward */
-       struct net_device_stats tsu_stats;      /* TSU forward status */
-
-       unsigned no_ether_link:1;
-       unsigned ether_link_active_low:1;
-};
-
-static inline void sh_eth_soft_swap(char *src, int len)
-{
-#ifdef __LITTLE_ENDIAN__
-       u32 *p = (u32 *)src;
-       u32 *maxp;
-       maxp = p + ((len + sizeof(u32) - 1) / sizeof(u32));
-
-       for (; p < maxp; p++)
-               *p = swab32(*p);
-#endif
-}
-
-static inline void sh_eth_write(struct net_device *ndev, unsigned long data,
-                               int enum_index)
-{
-       struct sh_eth_private *mdp = netdev_priv(ndev);
-
-       writel(data, ndev->base_addr + mdp->reg_offset[enum_index]);
-}
-
-static inline unsigned long sh_eth_read(struct net_device *ndev,
-                                       int enum_index)
-{
-       struct sh_eth_private *mdp = netdev_priv(ndev);
-
-       return readl(ndev->base_addr + mdp->reg_offset[enum_index]);
-}
-
-static inline void sh_eth_tsu_write(struct sh_eth_private *mdp,
-                               unsigned long data, int enum_index)
-{
-       writel(data, mdp->tsu_addr + mdp->reg_offset[enum_index]);
-}
-
-static inline unsigned long sh_eth_tsu_read(struct sh_eth_private *mdp,
-                                       int enum_index)
-{
-       return readl(mdp->tsu_addr + mdp->reg_offset[enum_index]);
-}
-
-#endif /* #ifndef __SH_ETH_H__ */