Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
[cascardo/linux.git] / drivers / net / ethernet / renesas / sh_eth.c
index 42e9dd0..8cb600c 100644 (file)
@@ -313,9 +313,14 @@ static const u16 sh_eth_offset_fast_sh3_sh2[SH_ETH_MAX_REGISTER_OFFSET] = {
        [TSU_ADRL31]    = 0x01fc,
 };
 
-#if defined(CONFIG_CPU_SUBTYPE_SH7734) || \
-       defined(CONFIG_CPU_SUBTYPE_SH7763) || \
-       defined(CONFIG_ARCH_R8A7740)
+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 void sh_eth_select_mii(struct net_device *ndev)
 {
        u32 value = 0x0;
@@ -339,11 +344,7 @@ static void sh_eth_select_mii(struct net_device *ndev)
 
        sh_eth_write(ndev, value, RMII_MII);
 }
-#endif
 
-/* There is CPU dependent code */
-#if defined(CONFIG_ARCH_R8A7778) || defined(CONFIG_ARCH_R8A7779)
-#define SH_ETH_RESET_DEFAULT   1
 static void sh_eth_set_duplex(struct net_device *ndev)
 {
        struct sh_eth_private *mdp = netdev_priv(ndev);
@@ -354,7 +355,8 @@ static void sh_eth_set_duplex(struct net_device *ndev)
                sh_eth_write(ndev, sh_eth_read(ndev, ECMR) & ~ECMR_DM, ECMR);
 }
 
-static void sh_eth_set_rate(struct net_device *ndev)
+/* There is CPU dependent code */
+static void sh_eth_set_rate_r8a777x(struct net_device *ndev)
 {
        struct sh_eth_private *mdp = netdev_priv(ndev);
 
@@ -371,9 +373,9 @@ static void sh_eth_set_rate(struct net_device *ndev)
 }
 
 /* R8A7778/9 */
-static struct sh_eth_cpu_data sh_eth_my_cpu_data = {
+static struct sh_eth_cpu_data r8a777x_data = {
        .set_duplex     = sh_eth_set_duplex,
-       .set_rate       = sh_eth_set_rate,
+       .set_rate       = sh_eth_set_rate_r8a777x,
 
        .ecsr_value     = ECSR_PSRTO | ECSR_LCHNG | ECSR_ICD,
        .ecsipr_value   = ECSIPR_PSRTOIP | ECSIPR_LCHNGIP | ECSIPR_ICDIP,
@@ -389,19 +391,8 @@ static struct sh_eth_cpu_data sh_eth_my_cpu_data = {
        .tpauser        = 1,
        .hw_swap        = 1,
 };
-#elif 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)
+static void sh_eth_set_rate_sh7724(struct net_device *ndev)
 {
        struct sh_eth_private *mdp = netdev_priv(ndev);
 
@@ -418,9 +409,9 @@ static void sh_eth_set_rate(struct net_device *ndev)
 }
 
 /* SH7724 */
-static struct sh_eth_cpu_data sh_eth_my_cpu_data = {
+static struct sh_eth_cpu_data sh7724_data = {
        .set_duplex     = sh_eth_set_duplex,
-       .set_rate       = sh_eth_set_rate,
+       .set_rate       = sh_eth_set_rate_sh7724,
 
        .ecsr_value     = ECSR_PSRTO | ECSR_LCHNG | ECSR_ICD,
        .ecsipr_value   = ECSIPR_PSRTOIP | ECSIPR_LCHNGIP | ECSIPR_ICDIP,
@@ -438,22 +429,8 @@ static struct sh_eth_cpu_data sh_eth_my_cpu_data = {
        .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 int sh_eth_check_reset(struct net_device *ndev);
 
-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)
+static void sh_eth_set_rate_sh7757(struct net_device *ndev)
 {
        struct sh_eth_private *mdp = netdev_priv(ndev);
 
@@ -470,9 +447,9 @@ static void sh_eth_set_rate(struct net_device *ndev)
 }
 
 /* SH7757 */
-static struct sh_eth_cpu_data sh_eth_my_cpu_data = {
-       .set_duplex             = sh_eth_set_duplex,
-       .set_rate               = sh_eth_set_rate,
+static struct sh_eth_cpu_data sh7757_data = {
+       .set_duplex     = sh_eth_set_duplex,
+       .set_rate       = sh_eth_set_rate_sh7757,
 
        .eesipr_value   = DMAC_M_RFRMER | DMAC_M_ECI | 0x003fffff,
        .rmcr_value     = 0x00000001,
@@ -482,6 +459,7 @@ static struct sh_eth_cpu_data sh_eth_my_cpu_data = {
                          EESR_RFRMER | EESR_TFE | EESR_TDE | EESR_ECI,
        .tx_error_check = EESR_TWB | EESR_TABT | EESR_TDE | EESR_TFE,
 
+       .irq_flags      = IRQF_SHARED,
        .apr            = 1,
        .mpr            = 1,
        .tpauser        = 1,
@@ -491,7 +469,7 @@ static struct sh_eth_cpu_data sh_eth_my_cpu_data = {
        .rpadir_value   = 2 << 16,
 };
 
-#define SH_GIGA_ETH_BASE       0xfee00000
+#define SH_GIGA_ETH_BASE       0xfee00000UL
 #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)
@@ -516,52 +494,6 @@ static void sh_eth_chip_reset_giga(struct net_device *ndev)
        }
 }
 
-static int sh_eth_is_gether(struct sh_eth_private *mdp);
-static int sh_eth_reset(struct net_device *ndev)
-{
-       struct sh_eth_private *mdp = netdev_priv(ndev);
-       int ret = 0;
-
-       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);
-
-               ret = sh_eth_check_reset(ndev);
-               if (ret)
-                       goto out;
-
-               /* 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);
-       }
-
-out:
-       return ret;
-}
-
-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);
@@ -582,9 +514,9 @@ static void sh_eth_set_rate_giga(struct net_device *ndev)
 }
 
 /* SH7757(GETHERC) */
-static struct sh_eth_cpu_data sh_eth_my_cpu_data_giga = {
+static struct sh_eth_cpu_data sh7757_data_giga = {
        .chip_reset     = sh_eth_chip_reset_giga,
-       .set_duplex     = sh_eth_set_duplex_giga,
+       .set_duplex     = sh_eth_set_duplex,
        .set_rate       = sh_eth_set_rate_giga,
 
        .ecsr_value     = ECSR_ICD | ECSR_MPD,
@@ -600,6 +532,7 @@ static struct sh_eth_cpu_data sh_eth_my_cpu_data_giga = {
        .fdr_value      = 0x0000072f,
        .rmcr_value     = 0x00000001,
 
+       .irq_flags      = IRQF_SHARED,
        .apr            = 1,
        .mpr            = 1,
        .tpauser        = 1,
@@ -612,19 +545,6 @@ static struct sh_eth_cpu_data sh_eth_my_cpu_data_giga = {
        .tsu            = 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_SH7734) || defined(CONFIG_CPU_SUBTYPE_SH7763)
-#define SH_ETH_HAS_TSU 1
-static int sh_eth_check_reset(struct net_device *ndev);
-static void sh_eth_reset_hw_crc(struct net_device *ndev);
-
 static void sh_eth_chip_reset(struct net_device *ndev)
 {
        struct sh_eth_private *mdp = netdev_priv(ndev);
@@ -634,17 +554,7 @@ static void sh_eth_chip_reset(struct net_device *ndev)
        mdelay(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)
+static void sh_eth_set_rate_gether(struct net_device *ndev)
 {
        struct sh_eth_private *mdp = netdev_priv(ndev);
 
@@ -663,11 +573,11 @@ static void sh_eth_set_rate(struct net_device *ndev)
        }
 }
 
-/* sh7763 */
-static struct sh_eth_cpu_data sh_eth_my_cpu_data = {
+/* SH7734 */
+static struct sh_eth_cpu_data sh7734_data = {
        .chip_reset     = sh_eth_chip_reset,
        .set_duplex     = sh_eth_set_duplex,
-       .set_rate       = sh_eth_set_rate,
+       .set_rate       = sh_eth_set_rate_gether,
 
        .ecsr_value     = ECSR_ICD | ECSR_MPD,
        .ecsipr_value   = ECSIPR_LCHNGIP | ECSIPR_ICDIP | ECSIPR_MPDIP,
@@ -688,54 +598,39 @@ static struct sh_eth_cpu_data sh_eth_my_cpu_data = {
        .no_trimd       = 1,
        .no_ade         = 1,
        .tsu            = 1,
-#if defined(CONFIG_CPU_SUBTYPE_SH7734)
-       .hw_crc     = 1,
-       .select_mii = 1,
-#endif
+       .hw_crc         = 1,
+       .select_mii     = 1,
 };
 
-static int sh_eth_reset(struct net_device *ndev)
-{
-       int ret = 0;
+/* SH7763 */
+static struct sh_eth_cpu_data sh7763_data = {
+       .chip_reset     = sh_eth_chip_reset,
+       .set_duplex     = sh_eth_set_duplex,
+       .set_rate       = sh_eth_set_rate_gether,
 
-       sh_eth_write(ndev, EDSR_ENALL, EDSR);
-       sh_eth_write(ndev, sh_eth_read(ndev, EDMR) | EDMR_SRST_GETHER, EDMR);
+       .ecsr_value     = ECSR_ICD | ECSR_MPD,
+       .ecsipr_value   = ECSIPR_LCHNGIP | ECSIPR_ICDIP | ECSIPR_MPDIP,
+       .eesipr_value   = DMAC_M_RFRMER | DMAC_M_ECI | 0x003fffff,
 
-       ret = sh_eth_check_reset(ndev);
-       if (ret)
-               goto out;
+       .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,
 
-       /* 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);
-
-       /* Reset HW CRC register */
-       sh_eth_reset_hw_crc(ndev);
-
-       /* Select MII mode */
-       if (sh_eth_my_cpu_data.select_mii)
-               sh_eth_select_mii(ndev);
-out:
-       return ret;
-}
+       .apr            = 1,
+       .mpr            = 1,
+       .tpauser        = 1,
+       .bculr          = 1,
+       .hw_swap        = 1,
+       .no_trimd       = 1,
+       .no_ade         = 1,
+       .tsu            = 1,
+       .irq_flags      = IRQF_SHARED,
+};
 
-static void sh_eth_reset_hw_crc(struct net_device *ndev)
-{
-       if (sh_eth_my_cpu_data.hw_crc)
-               sh_eth_write(ndev, 0x0, CSMR);
-}
-
-#elif defined(CONFIG_ARCH_R8A7740)
-#define SH_ETH_HAS_TSU 1
-static int sh_eth_check_reset(struct net_device *ndev);
-
-static void sh_eth_chip_reset(struct net_device *ndev)
+static void sh_eth_chip_reset_r8a7740(struct net_device *ndev)
 {
        struct sh_eth_private *mdp = netdev_priv(ndev);
 
@@ -746,65 +641,11 @@ static void sh_eth_chip_reset(struct net_device *ndev)
        sh_eth_select_mii(ndev);
 }
 
-static int sh_eth_reset(struct net_device *ndev)
-{
-       int ret = 0;
-
-       sh_eth_write(ndev, EDSR_ENALL, EDSR);
-       sh_eth_write(ndev, sh_eth_read(ndev, EDMR) | EDMR_SRST_GETHER, EDMR);
-
-       ret = sh_eth_check_reset(ndev);
-       if (ret)
-               goto out;
-
-       /* 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);
-
-out:
-       return ret;
-}
-
-static void sh_eth_set_duplex(struct net_device *ndev)
-{
-       struct sh_eth_private *mdp = netdev_priv(ndev);
-
-       if (mdp->duplex) /* Full */
-               sh_eth_write(ndev, sh_eth_read(ndev, ECMR) | ECMR_DM, ECMR);
-       else            /* Half */
-               sh_eth_write(ndev, sh_eth_read(ndev, ECMR) & ~ECMR_DM, ECMR);
-}
-
-static void sh_eth_set_rate(struct net_device *ndev)
-{
-       struct sh_eth_private *mdp = netdev_priv(ndev);
-
-       switch (mdp->speed) {
-       case 10: /* 10BASE */
-               sh_eth_write(ndev, GECMR_10, GECMR);
-               break;
-       case 100:/* 100BASE */
-               sh_eth_write(ndev, GECMR_100, GECMR);
-               break;
-       case 1000: /* 1000BASE */
-               sh_eth_write(ndev, GECMR_1000, GECMR);
-               break;
-       default:
-               break;
-       }
-}
-
 /* R8A7740 */
-static struct sh_eth_cpu_data sh_eth_my_cpu_data = {
-       .chip_reset     = sh_eth_chip_reset,
+static struct sh_eth_cpu_data r8a7740_data = {
+       .chip_reset     = sh_eth_chip_reset_r8a7740,
        .set_duplex     = sh_eth_set_duplex,
-       .set_rate       = sh_eth_set_rate,
+       .set_rate       = sh_eth_set_rate_gether,
 
        .ecsr_value     = ECSR_ICD | ECSR_MPD,
        .ecsipr_value   = ECSIPR_LCHNGIP | ECSIPR_ICDIP | ECSIPR_MPDIP,
@@ -828,9 +669,7 @@ static struct sh_eth_cpu_data sh_eth_my_cpu_data = {
        .select_mii     = 1,
 };
 
-#elif defined(CONFIG_CPU_SUBTYPE_SH7619)
-#define SH_ETH_RESET_DEFAULT   1
-static struct sh_eth_cpu_data sh_eth_my_cpu_data = {
+static struct sh_eth_cpu_data sh7619_data = {
        .eesipr_value   = DMAC_M_RFRMER | DMAC_M_ECI | 0x003fffff,
 
        .apr            = 1,
@@ -838,14 +677,11 @@ static struct sh_eth_cpu_data sh_eth_my_cpu_data = {
        .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 = {
+
+static struct sh_eth_cpu_data sh771x_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)
 {
@@ -875,17 +711,6 @@ static void sh_eth_set_default_cpu_data(struct sh_eth_cpu_data *cd)
                cd->tx_error_check = DEFAULT_TX_ERROR_CHECK;
 }
 
-#if defined(SH_ETH_RESET_DEFAULT)
-/* Chip Reset */
-static int  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);
-
-       return 0;
-}
-#else
 static int sh_eth_check_reset(struct net_device *ndev)
 {
        int ret = 0;
@@ -897,13 +722,55 @@ static int sh_eth_check_reset(struct net_device *ndev)
                mdelay(1);
                cnt--;
        }
-       if (cnt < 0) {
-               pr_err("Device reset fail\n");
+       if (cnt <= 0) {
+               pr_err("Device reset failed\n");
                ret = -ETIMEDOUT;
        }
        return ret;
 }
-#endif
+
+static int sh_eth_reset(struct net_device *ndev)
+{
+       struct sh_eth_private *mdp = netdev_priv(ndev);
+       int ret = 0;
+
+       if (sh_eth_is_gether(mdp)) {
+               sh_eth_write(ndev, EDSR_ENALL, EDSR);
+               sh_eth_write(ndev, sh_eth_read(ndev, EDMR) | EDMR_SRST_GETHER,
+                            EDMR);
+
+               ret = sh_eth_check_reset(ndev);
+               if (ret)
+                       goto out;
+
+               /* 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);
+
+               /* Reset HW CRC register */
+               if (mdp->cd->hw_crc)
+                       sh_eth_write(ndev, 0x0, CSMR);
+
+               /* Select MII mode */
+               if (mdp->cd->select_mii)
+                       sh_eth_select_mii(ndev);
+       } 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);
+       }
+
+out:
+       return ret;
+}
 
 #if defined(CONFIG_CPU_SH4) || defined(CONFIG_ARCH_SHMOBILE)
 static void sh_eth_set_receive_align(struct sk_buff *skb)
@@ -979,14 +846,6 @@ static void read_mac_address(struct net_device *ndev, unsigned char *mac)
        }
 }
 
-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))
@@ -1401,16 +1260,23 @@ static int sh_eth_rx(struct net_device *ndev, u32 intr_status)
                desc_status = edmac_to_cpu(mdp, rxdesc->status);
                pkt_len = rxdesc->frame_length;
 
-#if defined(CONFIG_ARCH_R8A7740)
-               desc_status >>= 16;
-#endif
-
                if (--boguscnt < 0)
                        break;
 
                if (!(desc_status & RDFEND))
                        ndev->stats.rx_length_errors++;
 
+#if defined(CONFIG_ARCH_R8A7740)
+               /*
+                * In case of almost all GETHER/ETHERs, the Receive Frame State
+                * (RFS) bits in the Receive Descriptor 0 are from bit 9 to
+                * bit 0. However, in case of the R8A7740's GETHER, the RFS
+                * bits are from bit 25 to bit 16. So, the driver needs right
+                * shifting by 16.
+                */
+               desc_status >>= 16;
+#endif
+
                if (desc_status & (RD_RFS1 | RD_RFS2 | RD_RFS3 | RD_RFS4 |
                                   RD_RFS5 | RD_RFS6 | RD_RFS10)) {
                        ndev->stats.rx_errors++;
@@ -1961,14 +1827,7 @@ static int sh_eth_open(struct net_device *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);
+                         mdp->cd->irq_flags, ndev->name, ndev);
        if (ret) {
                dev_err(&ndev->dev, "Can not assign IRQ number\n");
                return ret;
@@ -2154,7 +2013,6 @@ static int sh_eth_do_ioctl(struct net_device *ndev, struct ifreq *rq,
        return phy_mii_ioctl(phydev, rq, cmd);
 }
 
-#if defined(SH_ETH_HAS_TSU)
 /* For TSU_POSTn. Please refer to the manual about this (strange) bitfields */
 static void *sh_eth_tsu_get_post_reg_offset(struct sh_eth_private *mdp,
                                            int entry)
@@ -2497,7 +2355,6 @@ static int sh_eth_vlan_rx_kill_vid(struct net_device *ndev,
 
        return 0;
 }
-#endif /* SH_ETH_HAS_TSU */
 
 /* SuperH's TSU register init function */
 static void sh_eth_tsu_init(struct sh_eth_private *mdp)
@@ -2641,11 +2498,21 @@ static const struct net_device_ops sh_eth_netdev_ops = {
        .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_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 const struct net_device_ops sh_eth_netdev_ops_tsu = {
+       .ndo_open               = sh_eth_open,
+       .ndo_stop               = sh_eth_close,
+       .ndo_start_xmit         = sh_eth_start_xmit,
+       .ndo_get_stats          = sh_eth_get_stats,
        .ndo_set_rx_mode        = sh_eth_set_multicast_list,
        .ndo_vlan_rx_add_vid    = sh_eth_vlan_rx_add_vid,
        .ndo_vlan_rx_kill_vid   = sh_eth_vlan_rx_kill_vid,
-#endif
        .ndo_tx_timeout         = sh_eth_tx_timeout,
        .ndo_do_ioctl           = sh_eth_do_ioctl,
        .ndo_validate_addr      = eth_validate_addr,
@@ -2660,6 +2527,7 @@ static int sh_eth_drv_probe(struct platform_device *pdev)
        struct net_device *ndev = NULL;
        struct sh_eth_private *mdp = NULL;
        struct sh_eth_plat_data *pd = pdev->dev.platform_data;
+       const struct platform_device_id *id = platform_get_device_id(pdev);
 
        /* get base addr */
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -2718,15 +2586,14 @@ static int sh_eth_drv_probe(struct platform_device *pdev)
        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
+       mdp->cd = (struct sh_eth_cpu_data *)id->driver_data;
        sh_eth_set_default_cpu_data(mdp->cd);
 
        /* set function */
-       ndev->netdev_ops = &sh_eth_netdev_ops;
+       if (mdp->cd->tsu)
+               ndev->netdev_ops = &sh_eth_netdev_ops_tsu;
+       else
+               ndev->netdev_ops = &sh_eth_netdev_ops;
        SET_ETHTOOL_OPS(ndev, &sh_eth_ethtool_ops);
        ndev->watchdog_timeo = TX_TIMEOUT;
 
@@ -2803,11 +2670,11 @@ static int sh_eth_drv_remove(struct platform_device *pdev)
        unregister_netdev(ndev);
        pm_runtime_disable(&pdev->dev);
        free_netdev(ndev);
-       platform_set_drvdata(pdev, NULL);
 
        return 0;
 }
 
+#ifdef CONFIG_PM
 static int sh_eth_runtime_nop(struct device *dev)
 {
        /*
@@ -2821,17 +2688,36 @@ static int sh_eth_runtime_nop(struct device *dev)
        return 0;
 }
 
-static struct dev_pm_ops sh_eth_dev_pm_ops = {
+static const struct dev_pm_ops sh_eth_dev_pm_ops = {
        .runtime_suspend = sh_eth_runtime_nop,
        .runtime_resume = sh_eth_runtime_nop,
 };
+#define SH_ETH_PM_OPS (&sh_eth_dev_pm_ops)
+#else
+#define SH_ETH_PM_OPS NULL
+#endif
+
+static struct platform_device_id sh_eth_id_table[] = {
+       { "sh7619-ether", (kernel_ulong_t)&sh7619_data },
+       { "sh771x-ether", (kernel_ulong_t)&sh771x_data },
+       { "sh7724-ether", (kernel_ulong_t)&sh7724_data },
+       { "sh7734-gether", (kernel_ulong_t)&sh7734_data },
+       { "sh7757-ether", (kernel_ulong_t)&sh7757_data },
+       { "sh7757-gether", (kernel_ulong_t)&sh7757_data_giga },
+       { "sh7763-gether", (kernel_ulong_t)&sh7763_data },
+       { "r8a7740-gether", (kernel_ulong_t)&r8a7740_data },
+       { "r8a777x-ether", (kernel_ulong_t)&r8a777x_data },
+       { }
+};
+MODULE_DEVICE_TABLE(platform, sh_eth_id_table);
 
 static struct platform_driver sh_eth_driver = {
        .probe = sh_eth_drv_probe,
        .remove = sh_eth_drv_remove,
+       .id_table = sh_eth_id_table,
        .driver = {
                   .name = CARDNAME,
-                  .pm = &sh_eth_dev_pm_ops,
+                  .pm = SH_ETH_PM_OPS,
        },
 };