Skip to content

Commit

Permalink
net: stmmac: Implement logic to automatically select HW Interface
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Jose Abreu authored and David S. Miller committed Apr 23, 2018
1 parent 22148df commit 5f0456b
Show file tree
Hide file tree
Showing 11 changed files with 279 additions and 164 deletions.
3 changes: 2 additions & 1 deletion drivers/net/ethernet/stmicro/stmmac/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
30 changes: 4 additions & 26 deletions drivers/net/ethernet/stmicro/stmmac/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down Expand Up @@ -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);
Expand All @@ -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__ */
1 change: 0 additions & 1 deletion drivers/net/ethernet/stmicro/stmmac/dwmac1000.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */

Expand Down
29 changes: 10 additions & 19 deletions drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand Down Expand Up @@ -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,
Expand All @@ -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;
Expand All @@ -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;
}
23 changes: 7 additions & 16 deletions drivers/net/ethernet/stmicro/stmmac/dwmac100_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand All @@ -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;
Expand All @@ -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;
}
1 change: 0 additions & 1 deletion drivers/net/ethernet/stmicro/stmmac/dwmac4.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
41 changes: 12 additions & 29 deletions drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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)
Expand All @@ -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;
}
Loading

0 comments on commit 5f0456b

Please sign in to comment.