From fc18b6e98cce2380e8f31b0e5089b11ceecb541d Mon Sep 17 00:00:00 2001 From: "Russell King (Oracle)" Date: Wed, 29 Oct 2025 00:03:10 +0000 Subject: [PATCH 1/8] net: stmmac: move version handling into own function Move the version handling out of stmmac_hwif_init() and into its own function, returning the version information through a structure. Reviewed-by: Andrew Lunn Tested-by: Maxime Chevallier Tested-by: Mohd Ayaan Anwar Signed-off-by: Russell King (Oracle) Link: https://patch.msgid.link/E1vDteg-0000000CCBr-2m7q@rmk-PC.armlinux.org.uk Signed-off-by: Jakub Kicinski --- 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 41a7e1841227..4924e74997e4 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) { @@ -344,7 +359,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 */ @@ -380,7 +396,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; } From f49838f77cf6c50961afa33a5bc1ea95e061d7f0 Mon Sep 17 00:00:00 2001 From: "Russell King (Oracle)" Date: Wed, 29 Oct 2025 00:03:15 +0000 Subject: [PATCH 2/8] net: stmmac: simplify stmmac_get_version() 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. Reviewed-by: Andrew Lunn Tested-by: Maxime Chevallier Tested-by: Mohd Ayaan Anwar Signed-off-by: Russell King (Oracle) Link: https://patch.msgid.link/E1vDtel-0000000CCBx-3Lpf@rmk-PC.armlinux.org.uk Signed-off-by: Jakub Kicinski --- 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 4924e74997e4..f6ada5a905fe 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, version_offset); } static void stmmac_dwmac_mode_quirk(struct stmmac_priv *priv) From c36b97e4ca773f20ff20db34ed97e35cc36ad97c Mon Sep 17 00:00:00 2001 From: "Russell King (Oracle)" Date: Wed, 29 Oct 2025 00:03:20 +0000 Subject: [PATCH 3/8] net: stmmac: consolidate version reading and validation 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(). Reviewed-by: Andrew Lunn Tested-by: Maxime Chevallier Tested-by: Mohd Ayaan Anwar Signed-off-by: Russell King (Oracle) Link: https://patch.msgid.link/E1vDteq-0000000CCC3-3zbJ@rmk-PC.armlinux.org.uk Signed-off-by: Jakub Kicinski --- 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 f6ada5a905fe..ffdc101ce3ce 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, version_offset); + ver->dev_id = stmmac_get_dev_id(priv, version); } static void stmmac_dwmac_mode_quirk(struct stmmac_priv *priv) From 7b2e41fff76f53b53e7e00222674e3d87cbd4a67 Mon Sep 17 00:00:00 2001 From: "Russell King (Oracle)" Date: Wed, 29 Oct 2025 00:03:26 +0000 Subject: [PATCH 4/8] net: stmmac: move stmmac_get_*id() into stmmac_get_version() 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. Reviewed-by: Andrew Lunn Tested-by: Maxime Chevallier Tested-by: Mohd Ayaan Anwar Signed-off-by: Russell King (Oracle) Link: https://patch.msgid.link/E1vDtew-0000000CCC9-0KeM@rmk-PC.armlinux.org.uk Signed-off-by: Jakub Kicinski --- 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 ffdc101ce3ce..a4df51a7aef1 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, version); + ver->dev_id = (version & GENMASK(15, 8)) >> 8; } static void stmmac_dwmac_mode_quirk(struct stmmac_priv *priv) From b2fe9e29b5f65aa5ad87e859966871061eb37303 Mon Sep 17 00:00:00 2001 From: "Russell King (Oracle)" Date: Wed, 29 Oct 2025 00:03:31 +0000 Subject: [PATCH 5/8] net: stmmac: use FIELD_GET() for version register Provide field definitions in common.h, and use these with FIELD_GET() to extract the fields from the version register. Reviewed-by: Andrew Lunn Tested-by: Maxime Chevallier Tested-by: Mohd Ayaan Anwar Signed-off-by: Russell King (Oracle) Link: https://patch.msgid.link/E1vDtf1-0000000CCCF-0uUV@rmk-PC.armlinux.org.uk Signed-off-by: Jakub Kicinski --- 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 553a8897b005..27083af54568 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 a4df51a7aef1..26cc1bc758bf 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) From 7b510ea8e58eb0ead6bc41fd0f15ec064312dcbf Mon Sep 17 00:00:00 2001 From: "Russell King (Oracle)" Date: Wed, 29 Oct 2025 00:03:36 +0000 Subject: [PATCH 6/8] net: stmmac: provide function to lookup hwif Provide a function to lookup the hwif entry given the core type, Synopsys version, and device ID (used for XGMAC cores). Reviewed-by: Andrew Lunn Tested-by: Maxime Chevallier Tested-by: Mohd Ayaan Anwar Signed-off-by: Russell King (Oracle) Link: https://patch.msgid.link/E1vDtf6-0000000CCCL-1cQA@rmk-PC.armlinux.org.uk Signed-off-by: Jakub Kicinski --- 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 26cc1bc758bf..892cef79c4d1 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); @@ -339,18 +363,10 @@ int stmmac_hwif_init(struct stmmac_priv *priv) spin_lock_init(&mac->irq_ctrl_lock); /* 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; From f9326b139b4c77128564574ea2d7b83c8a758114 Mon Sep 17 00:00:00 2001 From: "Russell King (Oracle)" Date: Wed, 29 Oct 2025 00:03:41 +0000 Subject: [PATCH 7/8] net: stmmac: use != rather than ^ for comparing dev_id Use the more usual not-equals rather than exclusive-or operator when comparing the dev_id in stmmac_hwif_find(). Reviewed-by: Andrew Lunn Tested-by: Maxime Chevallier Tested-by: Mohd Ayaan Anwar Signed-off-by: Russell King (Oracle) Link: https://patch.msgid.link/E1vDtfB-0000000CCCR-25rr@rmk-PC.armlinux.org.uk Signed-off-by: Jakub Kicinski --- 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 892cef79c4d1..e1f99b9d9d7f 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; From 6436f408eb214bce9c5c308d51372a1611940dff Mon Sep 17 00:00:00 2001 From: "Russell King (Oracle)" Date: Wed, 29 Oct 2025 00:03:46 +0000 Subject: [PATCH 8/8] net: stmmac: reorganise stmmac_hwif_init() Reorganise stmmac_hwif_init() to handle the error case of stmmac_hwif_find() in the indented block, which follows normal programming pattern. Reviewed-by: Andrew Lunn Tested-by: Maxime Chevallier Tested-by: Mohd Ayaan Anwar Signed-off-by: Russell King (Oracle) Link: https://patch.msgid.link/E1vDtfG-0000000CCCX-2YwQ@rmk-PC.armlinux.org.uk Signed-off-by: Jakub Kicinski --- 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 e1f99b9d9d7f..8212441f9826 100644 --- a/drivers/net/ethernet/stmicro/stmmac/hwif.c +++ b/drivers/net/ethernet/stmicro/stmmac/hwif.c @@ -366,41 +366,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; + 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); - 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; - } - - /* Save quirks, if needed for posterior use */ - priv->hwif_quirks = entry->quirks; - return 0; + return -EINVAL; } - 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; + /* 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; + } + + /* Save quirks, if needed for posterior use */ + priv->hwif_quirks = entry->quirks; + + return 0; }