Move the version handling out of stmmac_hwif_init() and into its own function, returning the version information through a structure. Signed-off-by: Russell King (Oracle) --- drivers/net/ethernet/stmicro/stmmac/hwif.c | 42 +++++++++++++++------- 1 file changed, 29 insertions(+), 13 deletions(-) diff --git a/drivers/net/ethernet/stmicro/stmmac/hwif.c b/drivers/net/ethernet/stmicro/stmmac/hwif.c index 00083ce52549..44e34b6ab90a 100644 --- a/drivers/net/ethernet/stmicro/stmmac/hwif.c +++ b/drivers/net/ethernet/stmicro/stmmac/hwif.c @@ -13,6 +13,11 @@ #include "dwmac4_descs.h" #include "dwxgmac2.h" +struct stmmac_version { + u8 snpsver; + u8 dev_id; +}; + static u32 stmmac_get_id(struct stmmac_priv *priv, u32 id_reg) { u32 reg = readl(priv->ioaddr + id_reg); @@ -40,6 +45,24 @@ static u32 stmmac_get_dev_id(struct stmmac_priv *priv, u32 id_reg) return (reg & GENMASK(15, 8)) >> 8; } +static void stmmac_get_version(struct stmmac_priv *priv, + struct stmmac_version *ver) +{ + enum dwmac_core_type core_type = priv->plat->core_type; + + ver->dev_id = 0; + + if (core_type == DWMAC_CORE_GMAC) { + ver->snpsver = stmmac_get_id(priv, GMAC_VERSION); + } else if (dwmac_is_xmac(core_type)) { + ver->snpsver = stmmac_get_id(priv, GMAC4_VERSION); + if (core_type == DWMAC_CORE_XGMAC) + ver->dev_id = stmmac_get_dev_id(priv, GMAC4_VERSION); + } else { + ver->snpsver = 0; + } +} + static void stmmac_dwmac_mode_quirk(struct stmmac_priv *priv) { struct mac_device_info *mac = priv->hw; @@ -292,23 +315,15 @@ int stmmac_hwif_init(struct stmmac_priv *priv) { enum dwmac_core_type core_type = priv->plat->core_type; const struct stmmac_hwif_entry *entry; + struct stmmac_version version; struct mac_device_info *mac; bool needs_setup = true; - u32 id, dev_id = 0; int i, ret; - if (core_type == DWMAC_CORE_GMAC) { - id = stmmac_get_id(priv, GMAC_VERSION); - } else if (dwmac_is_xmac(core_type)) { - id = stmmac_get_id(priv, GMAC4_VERSION); - if (core_type == DWMAC_CORE_XGMAC) - dev_id = stmmac_get_dev_id(priv, GMAC4_VERSION); - } else { - id = 0; - } + stmmac_get_version(priv, &version); /* Save ID for later use */ - priv->synopsys_id = id; + priv->synopsys_id = version.snpsver; /* Lets assume some safe values first */ if (core_type == DWMAC_CORE_GMAC4) { @@ -342,7 +357,8 @@ int stmmac_hwif_init(struct stmmac_priv *priv) /* Use synopsys_id var because some setups can override this */ if (priv->synopsys_id < entry->min_id) continue; - if (core_type == DWMAC_CORE_XGMAC && (dev_id ^ entry->dev_id)) + if (core_type == DWMAC_CORE_XGMAC && + (version.dev_id ^ entry->dev_id)) continue; /* Only use generic HW helpers if needed */ @@ -378,7 +394,7 @@ int stmmac_hwif_init(struct stmmac_priv *priv) } dev_err(priv->device, "Failed to find HW IF (id=0x%x, gmac=%d/%d)\n", - id, core_type == DWMAC_CORE_GMAC, + version.snpsver, core_type == DWMAC_CORE_GMAC, core_type == DWMAC_CORE_GMAC4); return -EINVAL; } -- 2.47.3 We can simplify stmmac_get_version() by pre-initialising the version members to zero, detecting the MAC100 core and returning, otherwise determining the version register offset separately from calling stmmac_get_id() and stmmac_get_dev_id(). Do this. Signed-off-by: Russell King (Oracle) --- drivers/net/ethernet/stmicro/stmmac/hwif.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/drivers/net/ethernet/stmicro/stmmac/hwif.c b/drivers/net/ethernet/stmicro/stmmac/hwif.c index 44e34b6ab90a..7ee304e3599a 100644 --- a/drivers/net/ethernet/stmicro/stmmac/hwif.c +++ b/drivers/net/ethernet/stmicro/stmmac/hwif.c @@ -49,18 +49,22 @@ static void stmmac_get_version(struct stmmac_priv *priv, struct stmmac_version *ver) { enum dwmac_core_type core_type = priv->plat->core_type; + unsigned int version_offset; + ver->snpsver = 0; ver->dev_id = 0; - if (core_type == DWMAC_CORE_GMAC) { - ver->snpsver = stmmac_get_id(priv, GMAC_VERSION); - } else if (dwmac_is_xmac(core_type)) { - ver->snpsver = stmmac_get_id(priv, GMAC4_VERSION); - if (core_type == DWMAC_CORE_XGMAC) - ver->dev_id = stmmac_get_dev_id(priv, GMAC4_VERSION); - } else { - ver->snpsver = 0; - } + if (core_type == DWMAC_CORE_MAC100) + return; + + if (core_type == DWMAC_CORE_GMAC) + version_offset = GMAC_VERSION; + else + version_offset = GMAC4_VERSION; + + ver->snpsver = stmmac_get_id(priv, version_offset); + if (core_type == DWMAC_CORE_XGMAC) + ver->dev_id = stmmac_get_dev_id(priv, verison_offset); } static void stmmac_dwmac_mode_quirk(struct stmmac_priv *priv) -- 2.47.3 There is no need to read the version register twice, once in stmmac_get_id() and then again in stmmac_get_dev_id(). Consolidate this into stmmac_get_version() and pass each of these this value. As both functions unnecessarily issue the same warning for a zero register value, also move this into stmmac_get_version(). Signed-off-by: Russell King (Oracle) --- drivers/net/ethernet/stmicro/stmmac/hwif.c | 29 ++++++++-------------- 1 file changed, 11 insertions(+), 18 deletions(-) diff --git a/drivers/net/ethernet/stmicro/stmmac/hwif.c b/drivers/net/ethernet/stmicro/stmmac/hwif.c index 7ee304e3599a..c446fafdd804 100644 --- a/drivers/net/ethernet/stmicro/stmmac/hwif.c +++ b/drivers/net/ethernet/stmicro/stmmac/hwif.c @@ -18,30 +18,16 @@ struct stmmac_version { u8 dev_id; }; -static u32 stmmac_get_id(struct stmmac_priv *priv, u32 id_reg) +static u32 stmmac_get_id(struct stmmac_priv *priv, u32 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 u32 stmmac_get_dev_id(struct stmmac_priv *priv, u32 id_reg) +static u32 stmmac_get_dev_id(struct stmmac_priv *priv, u32 reg) { - u32 reg = readl(priv->ioaddr + id_reg); - - if (!reg) { - dev_info(priv->device, "Version ID not available\n"); - return 0x0; - } - return (reg & GENMASK(15, 8)) >> 8; } @@ -50,6 +36,7 @@ static void stmmac_get_version(struct stmmac_priv *priv, { enum dwmac_core_type core_type = priv->plat->core_type; unsigned int version_offset; + u32 version; ver->snpsver = 0; ver->dev_id = 0; @@ -62,9 +49,15 @@ static void stmmac_get_version(struct stmmac_priv *priv, else version_offset = GMAC4_VERSION; - ver->snpsver = stmmac_get_id(priv, version_offset); + version = readl(priv->ioaddr + version_offset); + if (version == 0) { + dev_info(priv->device, "Version ID not available\n"); + return; + } + + ver->snpsver = stmmac_get_id(priv, version); if (core_type == DWMAC_CORE_XGMAC) - ver->dev_id = stmmac_get_dev_id(priv, verison_offset); + ver->dev_id = stmmac_get_dev_id(priv, verison); } static void stmmac_dwmac_mode_quirk(struct stmmac_priv *priv) -- 2.47.3 Move the contents of both stmmac_get_id() and stmmac_get_dev_id() into stmmac_get_version() as it no longer makes sense for these to be separate functions. Signed-off-by: Russell King (Oracle) --- drivers/net/ethernet/stmicro/stmmac/hwif.c | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/drivers/net/ethernet/stmicro/stmmac/hwif.c b/drivers/net/ethernet/stmicro/stmmac/hwif.c index c446fafdd804..c156edb54ae6 100644 --- a/drivers/net/ethernet/stmicro/stmmac/hwif.c +++ b/drivers/net/ethernet/stmicro/stmmac/hwif.c @@ -18,19 +18,6 @@ struct stmmac_version { u8 dev_id; }; -static u32 stmmac_get_id(struct stmmac_priv *priv, u32 reg) -{ - 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 u32 stmmac_get_dev_id(struct stmmac_priv *priv, u32 reg) -{ - return (reg & GENMASK(15, 8)) >> 8; -} - static void stmmac_get_version(struct stmmac_priv *priv, struct stmmac_version *ver) { @@ -55,9 +42,13 @@ static void stmmac_get_version(struct stmmac_priv *priv, return; } - ver->snpsver = stmmac_get_id(priv, version); + dev_info(priv->device, "User ID: 0x%x, Synopsys ID: 0x%x\n", + (unsigned int)(version & GENMASK(15, 8)) >> 8, + (unsigned int)(version & GENMASK(7, 0))); + + ver->snpsver = version & GENMASK(7, 0); if (core_type == DWMAC_CORE_XGMAC) - ver->dev_id = stmmac_get_dev_id(priv, verison); + ver->dev_id = (version & GENMASK(15, 8)) >> 8; } static void stmmac_dwmac_mode_quirk(struct stmmac_priv *priv) -- 2.47.3 Provide field definitions in common.h, and use these with FIELD_GET() to extract the fields from the version register. Signed-off-by: Russell King (Oracle) --- drivers/net/ethernet/stmicro/stmmac/common.h | 3 +++ drivers/net/ethernet/stmicro/stmmac/hwif.c | 8 ++++---- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h index 31254ba525d5..a89fe25f1837 100644 --- a/drivers/net/ethernet/stmicro/stmmac/common.h +++ b/drivers/net/ethernet/stmicro/stmmac/common.h @@ -26,6 +26,9 @@ #include "hwif.h" #include "mmc.h" +#define DWMAC_SNPSVER GENMASK_U32(7, 0) +#define DWMAC_USERVER GENMASK_U32(15, 8) + /* Synopsys Core versions */ #define DWMAC_CORE_3_40 0x34 #define DWMAC_CORE_3_50 0x35 diff --git a/drivers/net/ethernet/stmicro/stmmac/hwif.c b/drivers/net/ethernet/stmicro/stmmac/hwif.c index c156edb54ae6..78362cf656f2 100644 --- a/drivers/net/ethernet/stmicro/stmmac/hwif.c +++ b/drivers/net/ethernet/stmicro/stmmac/hwif.c @@ -43,12 +43,12 @@ static void stmmac_get_version(struct stmmac_priv *priv, } dev_info(priv->device, "User ID: 0x%x, Synopsys ID: 0x%x\n", - (unsigned int)(version & GENMASK(15, 8)) >> 8, - (unsigned int)(version & GENMASK(7, 0))); + FIELD_GET(DWMAC_USERVER, version), + FIELD_GET(DWMAC_SNPSVER, version)); - ver->snpsver = version & GENMASK(7, 0); + ver->snpsver = FIELD_GET(DWMAC_SNPSVER, version); if (core_type == DWMAC_CORE_XGMAC) - ver->dev_id = (version & GENMASK(15, 8)) >> 8; + ver->dev_id = FIELD_GET(DWMAC_USERVER, version); } static void stmmac_dwmac_mode_quirk(struct stmmac_priv *priv) -- 2.47.3 Provide a function to lookup the hwif entry given the core type, Synopsys version, and device ID (used for XGMAC cores). Signed-off-by: Russell King (Oracle) --- drivers/net/ethernet/stmicro/stmmac/hwif.c | 40 +++++++++++++++------- 1 file changed, 28 insertions(+), 12 deletions(-) diff --git a/drivers/net/ethernet/stmicro/stmmac/hwif.c b/drivers/net/ethernet/stmicro/stmmac/hwif.c index 78362cf656f2..6c5429f37cae 100644 --- a/drivers/net/ethernet/stmicro/stmmac/hwif.c +++ b/drivers/net/ethernet/stmicro/stmmac/hwif.c @@ -299,6 +299,30 @@ static const struct stmmac_hwif_entry { }, }; +static const struct stmmac_hwif_entry * +stmmac_hwif_find(enum dwmac_core_type core_type, u8 snpsver, u8 dev_id) +{ + const struct stmmac_hwif_entry *entry; + int i; + + for (i = ARRAY_SIZE(stmmac_hw) - 1; i >= 0; i--) { + entry = &stmmac_hw[i]; + + if (core_type != entry->core_type) + continue; + /* Use synopsys_id var because some setups can override this */ + if (snpsver < entry->min_id) + continue; + if (core_type == DWMAC_CORE_XGMAC && + (dev_id ^ entry->dev_id)) + continue; + + return entry; + } + + return NULL; +} + int stmmac_hwif_init(struct stmmac_priv *priv) { enum dwmac_core_type core_type = priv->plat->core_type; @@ -306,7 +330,7 @@ int stmmac_hwif_init(struct stmmac_priv *priv) struct stmmac_version version; struct mac_device_info *mac; bool needs_setup = true; - int i, ret; + int ret; stmmac_get_version(priv, &version); @@ -337,18 +361,10 @@ int stmmac_hwif_init(struct stmmac_priv *priv) return -ENOMEM; /* Fallback to generic HW */ - for (i = ARRAY_SIZE(stmmac_hw) - 1; i >= 0; i--) { - entry = &stmmac_hw[i]; - - if (core_type != entry->core_type) - continue; - /* Use synopsys_id var because some setups can override this */ - if (priv->synopsys_id < entry->min_id) - continue; - if (core_type == DWMAC_CORE_XGMAC && - (version.dev_id ^ entry->dev_id)) - continue; + /* Use synopsys_id var because some setups can override this */ + entry = stmmac_hwif_find(core_type, priv->synopsys_id, version.dev_id); + if (entry) { /* Only use generic HW helpers if needed */ mac->desc = mac->desc ? : entry->desc; mac->dma = mac->dma ? : entry->dma; -- 2.47.3 Use the more usual not-equals rather than exclusive-or operator when comparing the dev_id in stmmac_hwif_find(). Signed-off-by: Russell King (Oracle) --- drivers/net/ethernet/stmicro/stmmac/hwif.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/stmicro/stmmac/hwif.c b/drivers/net/ethernet/stmicro/stmmac/hwif.c index 6c5429f37cae..187ae582a933 100644 --- a/drivers/net/ethernet/stmicro/stmmac/hwif.c +++ b/drivers/net/ethernet/stmicro/stmmac/hwif.c @@ -314,7 +314,7 @@ stmmac_hwif_find(enum dwmac_core_type core_type, u8 snpsver, u8 dev_id) if (snpsver < entry->min_id) continue; if (core_type == DWMAC_CORE_XGMAC && - (dev_id ^ entry->dev_id)) + dev_id != entry->dev_id) continue; return entry; -- 2.47.3 Reorganise stmmac_hwif_init() to handle the error case of stmmac_hwif_find() in the indented block, which follows normal programming pattern. Signed-off-by: Russell King (Oracle) --- drivers/net/ethernet/stmicro/stmmac/hwif.c | 72 ++++++++++++---------- 1 file changed, 38 insertions(+), 34 deletions(-) diff --git a/drivers/net/ethernet/stmicro/stmmac/hwif.c b/drivers/net/ethernet/stmicro/stmmac/hwif.c index 187ae582a933..0c187f8175b6 100644 --- a/drivers/net/ethernet/stmicro/stmmac/hwif.c +++ b/drivers/net/ethernet/stmicro/stmmac/hwif.c @@ -364,41 +364,45 @@ int stmmac_hwif_init(struct stmmac_priv *priv) /* Use synopsys_id var because some setups can override this */ entry = stmmac_hwif_find(core_type, priv->synopsys_id, version.dev_id); - if (entry) { - /* Only use generic HW helpers if needed */ - mac->desc = mac->desc ? : entry->desc; - mac->dma = mac->dma ? : entry->dma; - mac->mac = mac->mac ? : entry->mac; - mac->ptp = mac->ptp ? : entry->hwtimestamp; - mac->mode = mac->mode ? : entry->mode; - mac->tc = mac->tc ? : entry->tc; - mac->mmc = mac->mmc ? : entry->mmc; - mac->est = mac->est ? : entry->est; - mac->vlan = mac->vlan ? : entry->vlan; - - priv->hw = mac; - priv->fpe_cfg.reg = entry->regs.fpe_reg; - priv->ptpaddr = priv->ioaddr + entry->regs.ptp_off; - priv->mmcaddr = priv->ioaddr + entry->regs.mmc_off; - memcpy(&priv->ptp_clock_ops, entry->ptp, - sizeof(struct ptp_clock_info)); - if (entry->est) - priv->estaddr = priv->ioaddr + entry->regs.est_off; - - /* Entry found */ - if (needs_setup) { - ret = entry->setup(priv); - if (ret) - return ret; - } + if (!entry) { + dev_err(priv->device, + "Failed to find HW IF (id=0x%x, gmac=%d/%d)\n", + version.snpsver, core_type == DWMAC_CORE_GMAC, + core_type == DWMAC_CORE_GMAC4); + + return -EINVAL; + } - /* Save quirks, if needed for posterior use */ - priv->hwif_quirks = entry->quirks; - return 0; + /* Only use generic HW helpers if needed */ + mac->desc = mac->desc ? : entry->desc; + mac->dma = mac->dma ? : entry->dma; + mac->mac = mac->mac ? : entry->mac; + mac->ptp = mac->ptp ? : entry->hwtimestamp; + mac->mode = mac->mode ? : entry->mode; + mac->tc = mac->tc ? : entry->tc; + mac->mmc = mac->mmc ? : entry->mmc; + mac->est = mac->est ? : entry->est; + mac->vlan = mac->vlan ? : entry->vlan; + + priv->hw = mac; + priv->fpe_cfg.reg = entry->regs.fpe_reg; + priv->ptpaddr = priv->ioaddr + entry->regs.ptp_off; + priv->mmcaddr = priv->ioaddr + entry->regs.mmc_off; + memcpy(&priv->ptp_clock_ops, entry->ptp, + sizeof(struct ptp_clock_info)); + + if (entry->est) + priv->estaddr = priv->ioaddr + entry->regs.est_off; + + /* Entry found */ + if (needs_setup) { + ret = entry->setup(priv); + if (ret) + return ret; } - dev_err(priv->device, "Failed to find HW IF (id=0x%x, gmac=%d/%d)\n", - version.snpsver, core_type == DWMAC_CORE_GMAC, - core_type == DWMAC_CORE_GMAC4); - return -EINVAL; + /* Save quirks, if needed for posterior use */ + priv->hwif_quirks = entry->quirks; + + return 0; } -- 2.47.3