net: stmmac: Implement logic to automatically select HW Interface
authorJose Abreu <Jose.Abreu@synopsys.com>
Mon, 23 Apr 2018 08:05:15 +0000 (09:05 +0100)
committerDavid S. Miller <davem@davemloft.net>
Mon, 23 Apr 2018 16:03:50 +0000 (12:03 -0400)
Move all the core version detection to a common place ("hwif.c") and
implement a table which can be used to lookup the correct callbacks for
each IP version.

This simplifies the initialization flow of each IP version and eases
future implementation of new IP versions.

Signed-off-by: Jose Abreu <joabreu@synopsys.com>
Cc: David S. Miller <davem@davemloft.net>
Cc: Joao Pinto <jpinto@synopsys.com>
Cc: Vitor Soares <soares@synopsys.com>
Cc: Giuseppe Cavallaro <peppe.cavallaro@st.com>
Cc: Alexandre Torgue <alexandre.torgue@st.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/stmicro/stmmac/Makefile
drivers/net/ethernet/stmicro/stmmac/common.h
drivers/net/ethernet/stmicro/stmmac/dwmac1000.h
drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c
drivers/net/ethernet/stmicro/stmmac/dwmac100_core.c
drivers/net/ethernet/stmicro/stmmac/dwmac4.h
drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
drivers/net/ethernet/stmicro/stmmac/hwif.c [new file with mode: 0644]
drivers/net/ethernet/stmicro/stmmac/hwif.h
drivers/net/ethernet/stmicro/stmmac/stmmac.h
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c

index 972e4ef6d4148ea75f9a10ccc533ba366ef6e559..e3b578b4f7cb73685e9a5cfe3a8ed4ed5e777f55 100644 (file)
@@ -4,7 +4,8 @@ stmmac-objs:= stmmac_main.o stmmac_ethtool.o stmmac_mdio.o ring_mode.o  \
              chain_mode.o dwmac_lib.o dwmac1000_core.o dwmac1000_dma.o \
              dwmac100_core.o dwmac100_dma.o enh_desc.o norm_desc.o     \
              mmc_core.o stmmac_hwtstamp.o stmmac_ptp.o dwmac4_descs.o  \
-             dwmac4_dma.o dwmac4_lib.o dwmac4_core.o dwmac5.o $(stmmac-y)
+             dwmac4_dma.o dwmac4_lib.o dwmac4_core.o dwmac5.o hwif.o \
+             $(stmmac-y)
 
 # Ordering matters. Generic driver must be last.
 obj-$(CONFIG_STMMAC_PLATFORM)  += stmmac-platform.o
index 59673c6d2e52dc19b3584f28f4aa492319e19cb4..627e905b6d76b1f36042ac9c9bb63bd79e017093 100644 (file)
@@ -39,6 +39,7 @@
 #define        DWMAC_CORE_3_40 0x34
 #define        DWMAC_CORE_3_50 0x35
 #define        DWMAC_CORE_4_00 0x40
+#define DWMAC_CORE_4_10        0x41
 #define DWMAC_CORE_5_00 0x50
 #define DWMAC_CORE_5_10 0x51
 #define STMMAC_CHAN0   0       /* Always supported and default for all chips */
@@ -428,12 +429,9 @@ struct stmmac_rx_routing {
        u32 reg_shift;
 };
 
-struct mac_device_info *dwmac1000_setup(void __iomem *ioaddr, int mcbins,
-                                       int perfect_uc_entries,
-                                       int *synopsys_id);
-struct mac_device_info *dwmac100_setup(void __iomem *ioaddr, int *synopsys_id);
-struct mac_device_info *dwmac4_setup(void __iomem *ioaddr, int mcbins,
-                                    int perfect_uc_entries, int *synopsys_id);
+int dwmac100_setup(struct stmmac_priv *priv);
+int dwmac1000_setup(struct stmmac_priv *priv);
+int dwmac4_setup(struct stmmac_priv *priv);
 
 void stmmac_set_mac_addr(void __iomem *ioaddr, u8 addr[6],
                         unsigned int high, unsigned int low);
@@ -453,24 +451,4 @@ extern const struct stmmac_mode_ops ring_mode_ops;
 extern const struct stmmac_mode_ops chain_mode_ops;
 extern const struct stmmac_desc_ops dwmac4_desc_ops;
 
-/**
- * stmmac_get_synopsys_id - return the SYINID.
- * @priv: driver private structure
- * Description: this simple function is to decode and return the SYINID
- * starting from the HW core register.
- */
-static inline u32 stmmac_get_synopsys_id(u32 hwid)
-{
-       /* Check Synopsys Id (not available on old chips) */
-       if (likely(hwid)) {
-               u32 uid = ((hwid & 0x0000ff00) >> 8);
-               u32 synid = (hwid & 0x000000ff);
-
-               pr_info("stmmac - user ID: 0x%x, Synopsys ID: 0x%x\n",
-                       uid, synid);
-
-               return synid;
-       }
-       return 0;
-}
 #endif /* __COMMON_H__ */
index c02d36629c5284993afe7c6604af11d9c1923abb..184ca13c8f7903c4e1c3c33b86b8b3193b631081 100644 (file)
@@ -29,7 +29,6 @@
 #define GMAC_MII_DATA          0x00000014      /* MII Data */
 #define GMAC_FLOW_CTRL         0x00000018      /* Flow Control */
 #define GMAC_VLAN_TAG          0x0000001c      /* VLAN Tag */
-#define GMAC_VERSION           0x00000020      /* GMAC CORE Version */
 #define GMAC_DEBUG             0x00000024      /* GMAC debug register */
 #define GMAC_WAKEUP_FILTER     0x00000028      /* Wake-up Frame Filter */
 
index ef10baf14186267a4c7cd11602258f3ec893b77d..0877bde6e860b24a4f6003e817ee82a0726f0f11 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/ethtool.h>
 #include <net/dsa.h>
 #include <asm/io.h>
+#include "stmmac.h"
 #include "stmmac_pcs.h"
 #include "dwmac1000.h"
 
@@ -498,7 +499,7 @@ static void dwmac1000_debug(void __iomem *ioaddr, struct stmmac_extra_stats *x,
                x->mac_gmii_rx_proto_engine++;
 }
 
-static const struct stmmac_ops dwmac1000_ops = {
+const struct stmmac_ops dwmac1000_ops = {
        .core_init = dwmac1000_core_init,
        .set_mac = stmmac_set_mac,
        .rx_ipc = dwmac1000_rx_ipc_enable,
@@ -519,28 +520,21 @@ static const struct stmmac_ops dwmac1000_ops = {
        .pcs_get_adv_lp = dwmac1000_get_adv_lp,
 };
 
-struct mac_device_info *dwmac1000_setup(void __iomem *ioaddr, int mcbins,
-                                       int perfect_uc_entries,
-                                       int *synopsys_id)
+int dwmac1000_setup(struct stmmac_priv *priv)
 {
-       struct mac_device_info *mac;
-       u32 hwid = readl(ioaddr + GMAC_VERSION);
+       struct mac_device_info *mac = priv->hw;
 
-       mac = kzalloc(sizeof(const struct mac_device_info), GFP_KERNEL);
-       if (!mac)
-               return NULL;
+       dev_info(priv->device, "\tDWMAC1000\n");
 
-       mac->pcsr = ioaddr;
-       mac->multicast_filter_bins = mcbins;
-       mac->unicast_filter_entries = perfect_uc_entries;
+       priv->dev->priv_flags |= IFF_UNICAST_FLT;
+       mac->pcsr = priv->ioaddr;
+       mac->multicast_filter_bins = priv->plat->multicast_filter_bins;
+       mac->unicast_filter_entries = priv->plat->unicast_filter_entries;
        mac->mcast_bits_log2 = 0;
 
        if (mac->multicast_filter_bins)
                mac->mcast_bits_log2 = ilog2(mac->multicast_filter_bins);
 
-       mac->mac = &dwmac1000_ops;
-       mac->dma = &dwmac1000_dma_ops;
-
        mac->link.duplex = GMAC_CONTROL_DM;
        mac->link.speed10 = GMAC_CONTROL_PS;
        mac->link.speed100 = GMAC_CONTROL_PS | GMAC_CONTROL_FES;
@@ -555,8 +549,5 @@ struct mac_device_info *dwmac1000_setup(void __iomem *ioaddr, int mcbins,
        mac->mii.clk_csr_shift = 2;
        mac->mii.clk_csr_mask = GENMASK(5, 2);
 
-       /* Get and dump the chip ID */
-       *synopsys_id = stmmac_get_synopsys_id(hwid);
-
-       return mac;
+       return 0;
 }
index 91b23f9db31ade76c05a6a7a638d41506ed9c93d..b735143987e143cc636ce06488d46423b0200bdb 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/crc32.h>
 #include <net/dsa.h>
 #include <asm/io.h>
+#include "stmmac.h"
 #include "dwmac100.h"
 
 static void dwmac100_core_init(struct mac_device_info *hw,
@@ -159,7 +160,7 @@ static void dwmac100_pmt(struct mac_device_info *hw, unsigned long mode)
        return;
 }
 
-static const struct stmmac_ops dwmac100_ops = {
+const struct stmmac_ops dwmac100_ops = {
        .core_init = dwmac100_core_init,
        .set_mac = stmmac_set_mac,
        .rx_ipc = dwmac100_rx_ipc_enable,
@@ -172,20 +173,13 @@ static const struct stmmac_ops dwmac100_ops = {
        .get_umac_addr = dwmac100_get_umac_addr,
 };
 
-struct mac_device_info *dwmac100_setup(void __iomem *ioaddr, int *synopsys_id)
+int dwmac100_setup(struct stmmac_priv *priv)
 {
-       struct mac_device_info *mac;
+       struct mac_device_info *mac = priv->hw;
 
-       mac = kzalloc(sizeof(const struct mac_device_info), GFP_KERNEL);
-       if (!mac)
-               return NULL;
-
-       pr_info("\tDWMAC100\n");
-
-       mac->pcsr = ioaddr;
-       mac->mac = &dwmac100_ops;
-       mac->dma = &dwmac100_dma_ops;
+       dev_info(priv->device, "\tDWMAC100\n");
 
+       mac->pcsr = priv->ioaddr;
        mac->link.duplex = MAC_CONTROL_F;
        mac->link.speed10 = 0;
        mac->link.speed100 = 0;
@@ -200,8 +194,5 @@ struct mac_device_info *dwmac100_setup(void __iomem *ioaddr, int *synopsys_id)
        mac->mii.clk_csr_shift = 2;
        mac->mii.clk_csr_mask = GENMASK(5, 2);
 
-       /* Synopsys Id is not available on old chips */
-       *synopsys_id = 0;
-
-       return mac;
+       return 0;
 }
index dedd40613090d19daef8837ff3bc938055c87fcc..03eab9077c1c98a16527c5cec80fc20ea27be827 100644 (file)
@@ -34,7 +34,6 @@
 #define GMAC_PCS_BASE                  0x000000e0
 #define GMAC_PHYIF_CONTROL_STATUS      0x000000f8
 #define GMAC_PMT                       0x000000c0
-#define GMAC_VERSION                   0x00000110
 #define GMAC_DEBUG                     0x00000114
 #define GMAC_HW_FEATURE0               0x0000011c
 #define GMAC_HW_FEATURE1               0x00000120
index 517b1f6736a8357b1631fa4308349b29e242caff..7289b3b47d8e69305b2fb9653f9fe61e269fad8f 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/ethtool.h>
 #include <linux/io.h>
 #include <net/dsa.h>
+#include "stmmac.h"
 #include "stmmac_pcs.h"
 #include "dwmac4.h"
 #include "dwmac5.h"
@@ -700,7 +701,7 @@ static void dwmac4_debug(void __iomem *ioaddr, struct stmmac_extra_stats *x,
                x->mac_gmii_rx_proto_engine++;
 }
 
-static const struct stmmac_ops dwmac4_ops = {
+const struct stmmac_ops dwmac4_ops = {
        .core_init = dwmac4_core_init,
        .set_mac = stmmac_set_mac,
        .rx_ipc = dwmac4_rx_ipc_enable,
@@ -731,7 +732,7 @@ static const struct stmmac_ops dwmac4_ops = {
        .set_filter = dwmac4_set_filter,
 };
 
-static const struct stmmac_ops dwmac410_ops = {
+const struct stmmac_ops dwmac410_ops = {
        .core_init = dwmac4_core_init,
        .set_mac = stmmac_dwmac4_set_mac,
        .rx_ipc = dwmac4_rx_ipc_enable,
@@ -762,7 +763,7 @@ static const struct stmmac_ops dwmac410_ops = {
        .set_filter = dwmac4_set_filter,
 };
 
-static const struct stmmac_ops dwmac510_ops = {
+const struct stmmac_ops dwmac510_ops = {
        .core_init = dwmac4_core_init,
        .set_mac = stmmac_dwmac4_set_mac,
        .rx_ipc = dwmac4_rx_ipc_enable,
@@ -796,19 +797,16 @@ static const struct stmmac_ops dwmac510_ops = {
        .safety_feat_dump = dwmac5_safety_feat_dump,
 };
 
-struct mac_device_info *dwmac4_setup(void __iomem *ioaddr, int mcbins,
-                                    int perfect_uc_entries, int *synopsys_id)
+int dwmac4_setup(struct stmmac_priv *priv)
 {
-       struct mac_device_info *mac;
-       u32 hwid = readl(ioaddr + GMAC_VERSION);
+       struct mac_device_info *mac = priv->hw;
 
-       mac = kzalloc(sizeof(const struct mac_device_info), GFP_KERNEL);
-       if (!mac)
-               return NULL;
+       dev_info(priv->device, "\tDWMAC4/5\n");
 
-       mac->pcsr = ioaddr;
-       mac->multicast_filter_bins = mcbins;
-       mac->unicast_filter_entries = perfect_uc_entries;
+       priv->dev->priv_flags |= IFF_UNICAST_FLT;
+       mac->pcsr = priv->ioaddr;
+       mac->multicast_filter_bins = priv->plat->multicast_filter_bins;
+       mac->unicast_filter_entries = priv->plat->unicast_filter_entries;
        mac->mcast_bits_log2 = 0;
 
        if (mac->multicast_filter_bins)
@@ -828,20 +826,5 @@ struct mac_device_info *dwmac4_setup(void __iomem *ioaddr, int mcbins,
        mac->mii.clk_csr_shift = 8;
        mac->mii.clk_csr_mask = GENMASK(11, 8);
 
-       /* Get and dump the chip ID */
-       *synopsys_id = stmmac_get_synopsys_id(hwid);
-
-       if (*synopsys_id > DWMAC_CORE_4_00)
-               mac->dma = &dwmac410_dma_ops;
-       else
-               mac->dma = &dwmac4_dma_ops;
-
-       if (*synopsys_id >= DWMAC_CORE_5_10)
-               mac->mac = &dwmac510_ops;
-       else if (*synopsys_id >= DWMAC_CORE_4_00)
-               mac->mac = &dwmac410_ops;
-       else
-               mac->mac = &dwmac4_ops;
-
-       return mac;
+       return 0;
 }
diff --git a/drivers/net/ethernet/stmicro/stmmac/hwif.c b/drivers/net/ethernet/stmicro/stmmac/hwif.c
new file mode 100644 (file)
index 0000000..2b0a7e7
--- /dev/null
@@ -0,0 +1,220 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright (c) 2018 Synopsys, Inc. and/or its affiliates.
+ * stmmac HW Interface Handling
+ */
+
+#include "common.h"
+#include "stmmac.h"
+
+static u32 stmmac_get_id(struct stmmac_priv *priv, u32 id_reg)
+{
+       u32 reg = readl(priv->ioaddr + id_reg);
+
+       if (!reg) {
+               dev_info(priv->device, "Version ID not available\n");
+               return 0x0;
+       }
+
+       dev_info(priv->device, "User ID: 0x%x, Synopsys ID: 0x%x\n",
+                       (unsigned int)(reg & GENMASK(15, 8)) >> 8,
+                       (unsigned int)(reg & GENMASK(7, 0)));
+       return reg & GENMASK(7, 0);
+}
+
+static void stmmac_dwmac_mode_quirk(struct stmmac_priv *priv)
+{
+       struct mac_device_info *mac = priv->hw;
+
+       if (priv->chain_mode) {
+               dev_info(priv->device, "Chain mode enabled\n");
+               priv->mode = STMMAC_CHAIN_MODE;
+               mac->mode = &chain_mode_ops;
+       } else {
+               dev_info(priv->device, "Ring mode enabled\n");
+               priv->mode = STMMAC_RING_MODE;
+               mac->mode = &ring_mode_ops;
+       }
+}
+
+static int stmmac_dwmac1_quirks(struct stmmac_priv *priv)
+{
+       struct mac_device_info *mac = priv->hw;
+
+       if (priv->plat->enh_desc) {
+               dev_info(priv->device, "Enhanced/Alternate descriptors\n");
+
+               /* GMAC older than 3.50 has no extended descriptors */
+               if (priv->synopsys_id >= DWMAC_CORE_3_50) {
+                       dev_info(priv->device, "Enabled extended descriptors\n");
+                       priv->extend_desc = 1;
+               } else {
+                       dev_warn(priv->device, "Extended descriptors not supported\n");
+               }
+
+               mac->desc = &enh_desc_ops;
+       } else {
+               dev_info(priv->device, "Normal descriptors\n");
+               mac->desc = &ndesc_ops;
+       }
+
+       stmmac_dwmac_mode_quirk(priv);
+       return 0;
+}
+
+static int stmmac_dwmac4_quirks(struct stmmac_priv *priv)
+{
+       stmmac_dwmac_mode_quirk(priv);
+       return 0;
+}
+
+static const struct stmmac_hwif_entry {
+       bool gmac;
+       bool gmac4;
+       u32 min_id;
+       const void *desc;
+       const void *dma;
+       const void *mac;
+       const void *hwtimestamp;
+       const void *mode;
+       int (*setup)(struct stmmac_priv *priv);
+       int (*quirks)(struct stmmac_priv *priv);
+} stmmac_hw[] = {
+       /* NOTE: New HW versions shall go to the end of this table */
+       {
+               .gmac = false,
+               .gmac4 = false,
+               .min_id = 0,
+               .desc = NULL,
+               .dma = &dwmac100_dma_ops,
+               .mac = &dwmac100_ops,
+               .hwtimestamp = &stmmac_ptp,
+               .mode = NULL,
+               .setup = dwmac100_setup,
+               .quirks = stmmac_dwmac1_quirks,
+       }, {
+               .gmac = true,
+               .gmac4 = false,
+               .min_id = 0,
+               .desc = NULL,
+               .dma = &dwmac1000_dma_ops,
+               .mac = &dwmac1000_ops,
+               .hwtimestamp = &stmmac_ptp,
+               .mode = NULL,
+               .setup = dwmac1000_setup,
+               .quirks = stmmac_dwmac1_quirks,
+       }, {
+               .gmac = false,
+               .gmac4 = true,
+               .min_id = 0,
+               .desc = &dwmac4_desc_ops,
+               .dma = &dwmac4_dma_ops,
+               .mac = &dwmac4_ops,
+               .hwtimestamp = &stmmac_ptp,
+               .mode = NULL,
+               .setup = dwmac4_setup,
+               .quirks = stmmac_dwmac4_quirks,
+       }, {
+               .gmac = false,
+               .gmac4 = true,
+               .min_id = DWMAC_CORE_4_00,
+               .desc = &dwmac4_desc_ops,
+               .dma = &dwmac4_dma_ops,
+               .mac = &dwmac410_ops,
+               .hwtimestamp = &stmmac_ptp,
+               .mode = &dwmac4_ring_mode_ops,
+               .setup = dwmac4_setup,
+               .quirks = NULL,
+       }, {
+               .gmac = false,
+               .gmac4 = true,
+               .min_id = DWMAC_CORE_4_10,
+               .desc = &dwmac4_desc_ops,
+               .dma = &dwmac410_dma_ops,
+               .mac = &dwmac410_ops,
+               .hwtimestamp = &stmmac_ptp,
+               .mode = &dwmac4_ring_mode_ops,
+               .setup = dwmac4_setup,
+               .quirks = NULL,
+       }, {
+               .gmac = false,
+               .gmac4 = true,
+               .min_id = DWMAC_CORE_5_10,
+               .desc = &dwmac4_desc_ops,
+               .dma = &dwmac410_dma_ops,
+               .mac = &dwmac510_ops,
+               .hwtimestamp = &stmmac_ptp,
+               .mode = &dwmac4_ring_mode_ops,
+               .setup = dwmac4_setup,
+               .quirks = NULL,
+       }
+};
+
+int stmmac_hwif_init(struct stmmac_priv *priv)
+{
+       bool needs_gmac4 = priv->plat->has_gmac4;
+       bool needs_gmac = priv->plat->has_gmac;
+       const struct stmmac_hwif_entry *entry;
+       struct mac_device_info *mac;
+       int i, ret;
+       u32 id;
+
+       if (needs_gmac) {
+               id = stmmac_get_id(priv, GMAC_VERSION);
+       } else {
+               id = stmmac_get_id(priv, GMAC4_VERSION);
+       }
+
+       /* Save ID for later use */
+       priv->synopsys_id = id;
+
+       /* Check for HW specific setup first */
+       if (priv->plat->setup) {
+               priv->hw = priv->plat->setup(priv);
+               if (!priv->hw)
+                       return -ENOMEM;
+               return 0;
+       }
+
+       mac = devm_kzalloc(priv->device, sizeof(*mac), GFP_KERNEL);
+       if (!mac)
+               return -ENOMEM;
+
+       /* Fallback to generic HW */
+       for (i = ARRAY_SIZE(stmmac_hw) - 1; i >= 0; i--) {
+               entry = &stmmac_hw[i];
+
+               if (needs_gmac ^ entry->gmac)
+                       continue;
+               if (needs_gmac4 ^ entry->gmac4)
+                       continue;
+               if (id < entry->min_id)
+                       continue;
+
+               mac->desc = entry->desc;
+               mac->dma = entry->dma;
+               mac->mac = entry->mac;
+               mac->ptp = entry->hwtimestamp;
+               mac->mode = entry->mode;
+
+               priv->hw = mac;
+
+               /* Entry found */
+               ret = entry->setup(priv);
+               if (ret)
+                       return ret;
+
+               /* Run quirks, if needed */
+               if (entry->quirks) {
+                       ret = entry->quirks(priv);
+                       if (ret)
+                               return ret;
+               }
+
+               return 0;
+       }
+
+       dev_err(priv->device, "Failed to find HW IF (id=0x%x, gmac=%d/%d)\n",
+                       id, needs_gmac, needs_gmac4);
+       return -EINVAL;
+}
index f81ded4a9946cf33dca4dfde15304652cb94aa34..bfad61607f07fa1925a22663d978a4d16b3554c0 100644 (file)
@@ -418,4 +418,21 @@ struct stmmac_mode_ops {
 #define stmmac_clean_desc3(__priv, __args...) \
        stmmac_do_void_callback(__priv, mode, clean_desc3, __args)
 
+struct stmmac_priv;
+
+extern const struct stmmac_ops dwmac100_ops;
+extern const struct stmmac_dma_ops dwmac100_dma_ops;
+extern const struct stmmac_ops dwmac1000_ops;
+extern const struct stmmac_dma_ops dwmac1000_dma_ops;
+extern const struct stmmac_ops dwmac4_ops;
+extern const struct stmmac_dma_ops dwmac4_dma_ops;
+extern const struct stmmac_ops dwmac410_ops;
+extern const struct stmmac_dma_ops dwmac410_dma_ops;
+extern const struct stmmac_ops dwmac510_ops;
+
+#define GMAC_VERSION           0x00000020      /* GMAC CORE Version */
+#define GMAC4_VERSION          0x00000110      /* GMAC4+ CORE Version */
+
+int stmmac_hwif_init(struct stmmac_priv *priv);
+
 #endif /* __STMMAC_HWIF_H__ */
index da50451f8999aa9d417f0eb2277da8d49d215a27..2443f20e07bff02527021a7404f060f70b1bd296 100644 (file)
@@ -130,6 +130,7 @@ struct stmmac_priv {
        int eee_active;
        int tx_lpi_timer;
        unsigned int mode;
+       unsigned int chain_mode;
        int extend_desc;
        struct ptp_clock *ptp_clock;
        struct ptp_clock_info ptp_clock_ops;
index 48b55407a953d3fa1dd6868953b2d62734bd235d..0135fd3aa6efd6a7c33991c631602c4e1316bc35 100644 (file)
@@ -769,7 +769,6 @@ static int stmmac_init_ptp(struct stmmac_priv *priv)
                netdev_info(priv->dev,
                            "IEEE 1588-2008 Advanced Timestamp supported\n");
 
-       priv->hw->ptp = &stmmac_ptp;
        priv->hwts_tx_en = 0;
        priv->hwts_rx_en = 0;
 
@@ -2121,32 +2120,6 @@ static void stmmac_mmc_setup(struct stmmac_priv *priv)
                netdev_info(priv->dev, "No MAC Management Counters available\n");
 }
 
-/**
- * stmmac_selec_desc_mode - to select among: normal/alternate/extend descriptors
- * @priv: driver private structure
- * Description: select the Enhanced/Alternate or Normal descriptors.
- * In case of Enhanced/Alternate, it checks if the extended descriptors are
- * supported by the HW capability register.
- */
-static void stmmac_selec_desc_mode(struct stmmac_priv *priv)
-{
-       if (priv->plat->enh_desc) {
-               dev_info(priv->device, "Enhanced/Alternate descriptors\n");
-
-               /* GMAC older than 3.50 has no extended descriptors */
-               if (priv->synopsys_id >= DWMAC_CORE_3_50) {
-                       dev_info(priv->device, "Enabled extended descriptors\n");
-                       priv->extend_desc = 1;
-               } else
-                       dev_warn(priv->device, "Extended descriptors not supported\n");
-
-               priv->hw->desc = &enh_desc_ops;
-       } else {
-               dev_info(priv->device, "Normal descriptors\n");
-               priv->hw->desc = &ndesc_ops;
-       }
-}
-
 /**
  * stmmac_get_hw_features - get MAC capabilities from the HW cap. register.
  * @priv: driver private structure
@@ -4098,49 +4071,17 @@ static void stmmac_service_task(struct work_struct *work)
  */
 static int stmmac_hw_init(struct stmmac_priv *priv)
 {
-       struct mac_device_info *mac;
-
-       /* Identify the MAC HW device */
-       if (priv->plat->setup) {
-               mac = priv->plat->setup(priv);
-       } else if (priv->plat->has_gmac) {
-               priv->dev->priv_flags |= IFF_UNICAST_FLT;
-               mac = dwmac1000_setup(priv->ioaddr,
-                                     priv->plat->multicast_filter_bins,
-                                     priv->plat->unicast_filter_entries,
-                                     &priv->synopsys_id);
-       } else if (priv->plat->has_gmac4) {
-               priv->dev->priv_flags |= IFF_UNICAST_FLT;
-               mac = dwmac4_setup(priv->ioaddr,
-                                  priv->plat->multicast_filter_bins,
-                                  priv->plat->unicast_filter_entries,
-                                  &priv->synopsys_id);
-       } else {
-               mac = dwmac100_setup(priv->ioaddr, &priv->synopsys_id);
-       }
-       if (!mac)
-               return -ENOMEM;
-
-       priv->hw = mac;
+       int ret;
 
        /* dwmac-sun8i only work in chain mode */
        if (priv->plat->has_sun8i)
                chain_mode = 1;
+       priv->chain_mode = chain_mode;
 
-       /* To use the chained or ring mode */
-       if (priv->synopsys_id >= DWMAC_CORE_4_00) {
-               priv->hw->mode = &dwmac4_ring_mode_ops;
-       } else {
-               if (chain_mode) {
-                       priv->hw->mode = &chain_mode_ops;
-                       dev_info(priv->device, "Chain mode enabled\n");
-                       priv->mode = STMMAC_CHAIN_MODE;
-               } else {
-                       priv->hw->mode = &ring_mode_ops;
-                       dev_info(priv->device, "Ring mode enabled\n");
-                       priv->mode = STMMAC_RING_MODE;
-               }
-       }
+       /* Initialize HW Interface */
+       ret = stmmac_hwif_init(priv);
+       if (ret)
+               return ret;
 
        /* Get the HW capability (new GMAC newer than 3.50a) */
        priv->hw_cap_support = stmmac_get_hw_features(priv);
@@ -4174,12 +4115,6 @@ static int stmmac_hw_init(struct stmmac_priv *priv)
                dev_info(priv->device, "No HW DMA feature register supported\n");
        }
 
-       /* To use alternate (extended), normal or GMAC4 descriptor structures */
-       if (priv->synopsys_id >= DWMAC_CORE_4_00)
-               priv->hw->desc = &dwmac4_desc_ops;
-       else
-               stmmac_selec_desc_mode(priv);
-
        if (priv->plat->rx_coe) {
                priv->hw->rx_csum = priv->plat->rx_coe;
                dev_info(priv->device, "RX Checksum Offload Engine supported\n");