net: stmmac: clean up / fix synopsys IP version checks
Subsystems (5)
cover net: stmmac: clean up / fix synopsys IP version checks
Oh lookie, another relatively large stmmac patch series as a result of reviewing Jitendra Vegiraju's patch series! Yay! :(
This series cleans up and in some cases fixes the Synopsys IP version checks, which is a per-core numberspace.
For example, for dwmac1000 and dwmac4, we have versions such as v3.4 to up v5.2, which are represented by two BCD digits. For XGMAC, we have versions v2.1 and v2.2 represented by 0x21 and 0x22 respectively. For XLGMAC, we have v2.0, which is 0x20.
Note that hwif.c supports GMAC4 core type with the IP version in the range 0..0x40, which overlaps with the GMAC core type.
Thus, testing the Synopsys IP version for <= v4.0 will match dwmac1000, potentially some dwmac4, and all xgmac and xlgmac cores. In some cases, the latter two are provably incorrect.
The Synopsys IP version is named "synopsys_id" in the driver - as stated, it is the Synopsys IP version, and the register field is called snpsver. Use this name throughout the driver to avoid confusion. Also, dev_id seems to actually be userver.
The first decision making change is for dche, which is only looked at by the dwmac4 DMA code which requires core_type == DWMAC_CORE_GMAC4. Thus, it makes no sense to merely look at the IP version. Since setting this to true makes no sense for non-GMAC4 cores, force it to false for non-DWMAC_CORE_GMAC4 cores.
The MAC .debug() method is only populated by the dwmac1000 and dwmac4 cores, yet the test checks only for the IP version >= v3.5. While this works today, it may not work in the future given the different version numberspaces. Make this conditional on DWMAC_CORE_GMAC or GMAC4 core types to limit the version check. Ideally, it would be better to move the version check inside the .dwbug() method implementation, but that would require the method signature to change.
As getting to that point involved quite a bit of research, add comments into stmmac_get_ethtool_stats() so others don't have to re-analyse the code.
Clean up the resulting code in stmmac_get_ethtool_stats() given the complexity, adding documentation for each test.
Address the rx_coe handling, which checks for IP version >= v4.0 or the XGMAC core type. However, the members being printed are only present in the GMAC4 and XGMAC core type in one path, and GMAC in the other. There is an odd-ball which is sun8i, but we preserve its current behaviour. Also, given the research, add documentation in appropriate places. Note that priv->plat->rx_coe (and also priv->hw->rx_csum) has different value spaces depending on the core type - which is not nice.
Lastly, make the printing of the COE type, which as identified above, depend on the GMAC core type.
This leaves four locations unaddressed:
1) PTP filter code:
case HWTSTAMP_FILTER_PTP_V2_EVENT:
/* PTP v2/802.AS1 any layer, any kind of event packet */
config->rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT;
ptp_v2 = PTP_TCR_TSVER2ENA;
snap_type_sel = PTP_TCR_SNAPTYPSEL_1;
if (priv->snpsver < DWMAC_CORE_4_10)
ts_event_en = PTP_TCR_TSEVNTENA;I don't yet have an answer for this one, but it does mean that PTP_TCR_TSEVNTENA will be set for XGMAC cores for HWTSTAMP_FILTER_PTP_V2_EVENT... if they have PTP support.
2) riwt watchdog:
/* Rx Watchdog is available in the COREs newer than the 3.40.
* In some case, for example on bugged HW this feature
* has to be disable and this can be done by passing the
* riwt_off field from the platform.
*/
if ((priv->snpsver >= DWMAC_CORE_3_50 ||
priv->plat->core_type == DWMAC_CORE_XGMAC) &&
!priv->plat->riwt_off) {
priv->use_riwt = 1;This to me looks like the version check is only really applicable for the DWMAC_CORE_GMAC core type. So, I'm thinking that:
if (priv->plat->core_type >= DWMAC_CORE_GMAC4 ||
(priv->plat->core_type == DWMAC_CORE_GMAC &&
priv->snpsver >= DWMAC_CORE_3_50)) {
if (!priv->plat->rwit_off) {
...would be clearer (note the splitting of the if() conditions which seems to me would be more readable than trying to munge it all into one expression.)
3) max_mtu setup:
/* Set the maximum MTU.
* For XGMAC cores, 16KiB.
* For cores using enhanced descriptors or GMAC cores >= v4.00, 9kB.
* For everything else, PAGE_SIZE - NET_SKB_PAD - NET_IP_ALIGN -
* aligned skb_shared_info.
*/
if (priv->plat->core_type == DWMAC_CORE_XGMAC)
ndev->max_mtu = XGMAC_JUMBO_LEN;
else if (priv->plat->enh_desc || priv->snpsver >= DWMAC_CORE_4_00)
ndev->max_mtu = JUMBO_LEN;
else
ndev->max_mtu = SKB_MAX_HEAD(NET_SKB_PAD + NET_IP_ALIGN);which I've previously identified is very buggy, and I'm not sure what the real tests here should be. I'm quite certain that the max_mtu values are basically completely wrong, especially in the last case. This needs a lot of analysis and comparing with documentation to get to the bottom of what the tests and resulting max_mtu values should actually be.
.../net/ethernet/stmicro/stmmac/dwmac-loongson.c | 2 +- drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c | 2 +- drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c | 2 +- drivers/net/ethernet/stmicro/stmmac/hwif.c | 54 +++++++++++----------- drivers/net/ethernet/stmicro/stmmac/stmmac.h | 2 +- .../net/ethernet/stmicro/stmmac/stmmac_ethtool.c | 51 +++++++++++--------- drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 24 ++++++---- drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c | 8 ++-- include/linux/stmmac.h | 7 +++ 9 files changed, 85 insertions(+), 67 deletions(-)
Signature · 2 lines
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/ FTTP is here! 80Mbps down 10Mbps up. Decent connectivity at last!
RFC PATCH 1/10 net: stmmac: rename min_id to min_snpsver
min_id is the minimum Synopsys IP version that the hwif entry will match. Name it min_snpsver so that it's clear which part of the version ID it is related to.
--- drivers/net/ethernet/stmicro/stmmac/hwif.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-)
drivers/net/ethernet/stmicro/stmmac/hwif.c +10 -10
@@ -110,7 +110,7 @@ int stmmac_reset(struct stmmac_priv *priv) static const struct stmmac_hwif_entry { enum dwmac_core_type core_type; - u32 min_id; + u32 min_snpsver; u32 dev_id; const struct stmmac_regs_off regs; const void *desc;
@@ -129,7 +129,7 @@ static const struct stmmac_hwif_entry {/* NOTE: New HW versions shall go to the end of this table */ { .core_type = DWMAC_CORE_MAC100, - .min_id = 0, + .min_snpsver = 0, .regs = { .ptp_off = PTP_GMAC3_X_OFFSET, .mmc_off = MMC_GMAC3_X_OFFSET,
@@ -146,7 +146,7 @@ static const struct stmmac_hwif_entry { .quirks = stmmac_dwmac1_quirks, }, { .core_type = DWMAC_CORE_GMAC, - .min_id = 0, + .min_snpsver = 0, .regs = { .ptp_off = PTP_GMAC3_X_OFFSET, .mmc_off = MMC_GMAC3_X_OFFSET,
@@ -163,7 +163,7 @@ static const struct stmmac_hwif_entry { .quirks = stmmac_dwmac1_quirks, }, { .core_type = DWMAC_CORE_GMAC4, - .min_id = 0, + .min_snpsver = 0, .regs = { .ptp_off = PTP_GMAC4_OFFSET, .mmc_off = MMC_GMAC4_OFFSET,
@@ -183,7 +183,7 @@ static const struct stmmac_hwif_entry { .quirks = stmmac_dwmac4_quirks, }, { .core_type = DWMAC_CORE_GMAC4, - .min_id = DWMAC_CORE_4_00, + .min_snpsver = DWMAC_CORE_4_00, .regs = { .ptp_off = PTP_GMAC4_OFFSET, .mmc_off = MMC_GMAC4_OFFSET,
@@ -204,7 +204,7 @@ static const struct stmmac_hwif_entry { .quirks = NULL, }, { .core_type = DWMAC_CORE_GMAC4, - .min_id = DWMAC_CORE_4_10, + .min_snpsver = DWMAC_CORE_4_10, .regs = { .ptp_off = PTP_GMAC4_OFFSET, .mmc_off = MMC_GMAC4_OFFSET,
@@ -225,7 +225,7 @@ static const struct stmmac_hwif_entry { .quirks = NULL, }, { .core_type = DWMAC_CORE_GMAC4, - .min_id = DWMAC_CORE_5_10, + .min_snpsver = DWMAC_CORE_5_10, .regs = { .ptp_off = PTP_GMAC4_OFFSET, .mmc_off = MMC_GMAC4_OFFSET,
@@ -246,7 +246,7 @@ static const struct stmmac_hwif_entry { .quirks = NULL, }, { .core_type = DWMAC_CORE_XGMAC, - .min_id = DWXGMAC_CORE_2_10, + .min_snpsver = DWXGMAC_CORE_2_10, .dev_id = DWXGMAC_ID, .regs = { .ptp_off = PTP_XGMAC_OFFSET,
@@ -268,7 +268,7 @@ static const struct stmmac_hwif_entry { .quirks = NULL, }, { .core_type = DWMAC_CORE_XGMAC, - .min_id = DWXLGMAC_CORE_2_00, + .min_snpsver = DWXLGMAC_CORE_2_00, .dev_id = DWXLGMAC_ID, .regs = { .ptp_off = PTP_XGMAC_OFFSET,
@@ -302,7 +302,7 @@ stmmac_hwif_find(enum dwmac_core_type core_type, u8 snpsver, u8 dev_id)if (core_type != entry->core_type)continue ;/* Use synopsys_id var because some setups can override this */ -if (snpsver < entry->min_id) +if (snpsver < entry->min_snpsver)continue ;if (core_type ==DWMAC_CORE_XGMAC && dev_id != entry->dev_id)
Signature · 1 line
2.47.3
RFC PATCH 2/10 net: stmmac: rename dev_id to userver
In reply to Russell King (Oracle)The Synopsys Databook and several implementation TRMs identify bits 15:8 of the version register in dwmac v3.xx and v4.xx as "userver". We even print its value with "User ID". Rather than using "dev_id", use "userver" instead.
--- drivers/net/ethernet/stmicro/stmmac/hwif.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-)
drivers/net/ethernet/stmicro/stmmac/hwif.c +9 -9
@@ -15,7 +15,7 @@struct stmmac_version {u8 snpsver; -u8 dev_id; +u8 userver; }; static void stmmac_get_version(struct stmmac_priv *priv,
@@ -26,7 +26,7 @@ static void stmmac_get_version(struct stmmac_priv *priv,u32 version; ver->snpsver =0 ; - ver->dev_id =0 ; + ver->userver =0 ;if (core_type ==DWMAC_CORE_MAC100 )return ;
@@ -48,7 +48,7 @@ static void stmmac_get_version(struct stmmac_priv *priv, ver->snpsver =FIELD_GET (DWMAC_SNPSVER , version);if (core_type ==DWMAC_CORE_XGMAC ) - ver->dev_id =FIELD_GET (DWMAC_USERVER , version); + ver->userver =FIELD_GET (DWMAC_USERVER , version); }static void stmmac_dwmac_mode_quirk (struct stmmac_priv *priv)
@@ -111,7 +111,7 @@ int stmmac_reset(struct stmmac_priv *priv) static const struct stmmac_hwif_entry { enum dwmac_core_type core_type; u32 min_snpsver; - u32 dev_id; + u32 userver; const struct stmmac_regs_off regs; const void *desc; const void *dma;
@@ -247,7 +247,7 @@ static const struct stmmac_hwif_entry { }, { .core_type = DWMAC_CORE_XGMAC, .min_snpsver = DWXGMAC_CORE_2_10, - .dev_id = DWXGMAC_ID, + .userver = DWXGMAC_ID, .regs = { .ptp_off = PTP_XGMAC_OFFSET, .mmc_off = MMC_XGMAC_OFFSET,
@@ -269,7 +269,7 @@ static const struct stmmac_hwif_entry { }, { .core_type = DWMAC_CORE_XGMAC, .min_snpsver = DWXLGMAC_CORE_2_00, - .dev_id = DWXLGMAC_ID, + .userver = DWXLGMAC_ID, .regs = { .ptp_off = PTP_XGMAC_OFFSET, .mmc_off = MMC_XGMAC_OFFSET,
@@ -291,7 +291,7 @@ 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) +stmmac_hwif_find (enum dwmac_core_type core_type,u8 snpsver,u8 userver) {const struct stmmac_hwif_entry *entry;int i;
@@ -305,7 +305,7 @@ stmmac_hwif_find(enum dwmac_core_type core_type, u8 snpsver, u8 dev_id)if (snpsver < entry->min_snpsver)continue ;if (core_type ==DWMAC_CORE_XGMAC && - dev_id != entry->dev_id) + userver != entry->userver)continue ;return entry;
@@ -358,7 +358,7 @@ int stmmac_hwif_init(struct stmmac_priv *priv)/* Fallback to generic HW */ /* Use synopsys_id var because some setups can override this */ - entry =stmmac_hwif_find (core_type, priv->synopsys_id, version.dev_id); + entry =stmmac_hwif_find (core_type, priv->synopsys_id, version.userver);if (!entry) { dev_err(priv->device, "Failed to find HW IF (id=0x%x, gmac=%d/%d)\n",
Signature · 1 line
2.47.3
Re: [PATCH RFC net-next 02/10] net: stmmac: rename dev_id to userver
Hi Russell,
Quoted 16 lines · Russell King (Oracle)
The Synopsys Databook and several implementation TRMs identify bits 15:8 of the version register in dwmac v3.xx and v4.xx as "userver". We even print its value with "User ID". Rather than using "
dev_id", use "userver" instead.Signed-off-by Russell King (Oracle) <[email protected]>--- drivers/net/ethernet/stmicro/stmmac/hwif.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-)drivers/net/ethernet/stmicro/stmmac/hwif.c +0
-0
drivers/net/ethernet/stmicro/stmmac/hwif.c line 19
Quoted 6 lines
drivers/net/ethernet/stmicro/stmmac/hwif.c +1
-1@@ -15,7 +15,7 @@struct stmmac_version {u8 snpsver; -u8 dev_id; +u8 userver; };
From the XGMAC databook that I have access to bits(15:8) identify the DEVID field of MAC_version register.
The userver field is from bits(23:16) of the same register. This is a customer defined field (configured with coreConsultant). Currently stmmac doesn't care about bits(23:16).
I think the confusion is coming from macro name in common.h
#define DWMAC_USERVER GENMASK_U32(15, 8)
This should be named
#define DWMAC_DEVID GENMASK_U32(15, 8)
Hope someone with access to another databook can confirm this.
Quoted 77 lines
drivers/net/ethernet/stmicro/stmmac/hwif.c +8
-9static void stmmac_get_version(struct stmmac_priv *priv,@@ -26,7 +26,7 @@ static void stmmac_get_version(struct stmmac_priv *priv,u32 version; ver->snpsver =0 ; - ver->dev_id =0 ; + ver->userver =0 ;if (core_type ==DWMAC_CORE_MAC100 )return ;@@ -48,7 +48,7 @@ static void stmmac_get_version(struct stmmac_priv *priv, ver->snpsver =FIELD_GET (DWMAC_SNPSVER , version);if (core_type ==DWMAC_CORE_XGMAC ) - ver->dev_id =FIELD_GET (DWMAC_USERVER , version); + ver->userver =FIELD_GET (DWMAC_USERVER , version); }static void stmmac_dwmac_mode_quirk (struct stmmac_priv *priv)@@ -111,7 +111,7 @@ int stmmac_reset(struct stmmac_priv *priv) static const struct stmmac_hwif_entry { enum dwmac_core_type core_type; u32 min_snpsver; - u32 dev_id; + u32 userver; const struct stmmac_regs_off regs; const void *desc; const void *dma;@@ -247,7 +247,7 @@ static const struct stmmac_hwif_entry { }, { .core_type = DWMAC_CORE_XGMAC, .min_snpsver = DWXGMAC_CORE_2_10, - .dev_id = DWXGMAC_ID, + .userver = DWXGMAC_ID, .regs = { .ptp_off = PTP_XGMAC_OFFSET, .mmc_off = MMC_XGMAC_OFFSET,@@ -269,7 +269,7 @@ static const struct stmmac_hwif_entry { }, { .core_type = DWMAC_CORE_XGMAC, .min_snpsver = DWXLGMAC_CORE_2_00, - .dev_id = DWXLGMAC_ID, + .userver = DWXLGMAC_ID, .regs = { .ptp_off = PTP_XGMAC_OFFSET, .mmc_off = MMC_XGMAC_OFFSET,@@ -291,7 +291,7 @@ 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) +stmmac_hwif_find (enum dwmac_core_type core_type,u8 snpsver,u8 userver) {const struct stmmac_hwif_entry *entry;int i;@@ -305,7 +305,7 @@ stmmac_hwif_find(enum dwmac_core_type core_type, u8 snpsver, u8 dev_id)if (snpsver < entry->min_snpsver)continue ;if (core_type ==DWMAC_CORE_XGMAC && - dev_id != entry->dev_id) + userver != entry->userver)continue ;return entry;@@ -358,7 +358,7 @@ int stmmac_hwif_init(struct stmmac_priv *priv)/* Fallback to generic HW */ /* Use synopsys_id var because some setups can override this */ - entry =stmmac_hwif_find (core_type, priv->synopsys_id, version.dev_id); + entry =stmmac_hwif_find (core_type, priv->synopsys_id, version.userver);if (!entry) { dev_err(priv->device, "Failed to find HW IF (id=0x%x, gmac=%d/%d)\n", --2.47.3
Re: [PATCH RFC net-next 02/10] net: stmmac: rename dev_id to userver
Quoted 21 lines · Jitendra Vegiraju
Hi Russell,
Quoted 17 lines · Russell King (Oracle)
The Synopsys Databook and several implementation TRMs identify bits 15:8 of the version register in dwmac v3.xx and v4.xx as "userver". We even print its value with "User ID". Rather than using "
dev_id", use "userver" instead.Signed-off-by Russell King (Oracle) <[email protected]>--- drivers/net/ethernet/stmicro/stmmac/hwif.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-)drivers/net/ethernet/stmicro/stmmac/hwif.c +0
-0@@ -15,7 +15,7 @@
Quoted 10 lines
drivers/net/ethernet/stmicro/stmmac/hwif.c line 19
Quoted 5 lines
drivers/net/ethernet/stmicro/stmmac/hwif.c +1
-1struct stmmac_version {u8 snpsver; -u8 dev_id; +u8 userver; };From the XGMAC databook that I have access to bits(15:8) identify the DEVID field of
MAC_versionregister.
The userver field is from bits(23:16) of the same register. This is a customer defined field (configured with coreConsultant). Currently stmmac doesn't care about bits(23:16).
Thanks for the additional information.
I don't have any XGMAC documentation, but this indicates that it differs between XGMAC and previous cores - GMAC and GMAC4 cores, 15:8 are documented as userver, and 31:16 are marked as reserved.
Note that the dev_info() also prints 15:8 as "User ID" not "Device ID".
To confirm, is the XGMAC version register at offset 0x20 ? Later GMAC cores moved it to 0x110.
Signature · 2 lines
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/ FTTP is here! 80Mbps down 10Mbps up. Decent connectivity at last!
Re: [PATCH RFC net-next 02/10] net: stmmac: rename dev_id to userver
Quoted 36 lines · Russell King (Oracle)
Quoted 21 lines · Jitendra Vegiraju
Hi Russell,
Quoted 17 lines · Russell King (Oracle)
The Synopsys Databook and several implementation TRMs identify bits 15:8 of the version register in dwmac v3.xx and v4.xx as "userver". We even print its value with "User ID". Rather than using "
dev_id", use "userver" instead.Signed-off-by Russell King (Oracle) <[email protected]>--- drivers/net/ethernet/stmicro/stmmac/hwif.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-)drivers/net/ethernet/stmicro/stmmac/hwif.c +0
-0@@ -15,7 +15,7 @@Quoted 10 lines
drivers/net/ethernet/stmicro/stmmac/hwif.c line 19
Quoted 5 lines
drivers/net/ethernet/stmicro/stmmac/hwif.c +1
-1struct stmmac_version {u8 snpsver; -u8 dev_id; +u8 userver; };From the XGMAC databook that I have access to bits(15:8) identify the DEVID field of
MAC_versionregister.
The userver field is from bits(23:16) of the same register. This is a customer defined field (configured with coreConsultant). Currently stmmac doesn't care about bits(23:16).Thanks for the additional information.
Quoted 8 lines
I don't have any XGMAC documentation, but this indicates that it differs between XGMAC and previous cores - GMAC and GMAC4 cores, 15:8 are documented as userver, and 31:16 are marked as reserved.
Note that the
dev_info()also prints 15:8 as "User ID" not "Device ID".To confirm, is the XGMAC version register at offset
0x20? Later GMAC cores moved it to0x110.
The XGMAC version register is at offset 0x110.
Quoted 4 lines
--
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 80Mbps down 10Mbps up. Decent connectivity at last!
RFC PATCH 3/10 net: stmmac: always fill in ver->userver
In reply to Russell King (Oracle)Always fill in ver->userver irrespective of the core type. This has no functional impact but tidies up the code by removing an unnecessary conditional.
--- drivers/net/ethernet/stmicro/stmmac/hwif.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
drivers/net/ethernet/stmicro/stmmac/hwif.c +1 -2
@@ -47,8 +47,7 @@ static void stmmac_get_version(struct stmmac_priv *priv, FIELD_GET(DWMAC_SNPSVER, version)); ver->snpsver =FIELD_GET (DWMAC_SNPSVER , version); -if (core_type ==DWMAC_CORE_XGMAC ) - ver->userver =FIELD_GET (DWMAC_USERVER , version); + ver->userver =FIELD_GET (DWMAC_USERVER , version); }static void stmmac_dwmac_mode_quirk (struct stmmac_priv *priv)
Signature · 1 line
2.47.3
RFC PATCH 4/10 net: stmmac: use ver->userver and ver->snpsver to print version
In reply to Russell King (Oracle)Rather than using FIELD_GET() twice, reorder the code to extract the version fields into struct stmmac_version, and then print them.
--- drivers/net/ethernet/stmicro/stmmac/hwif.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-)
drivers/net/ethernet/stmicro/stmmac/hwif.c +3 -4
@@ -42,12 +42,11 @@ static void stmmac_get_version(struct stmmac_priv *priv,return ; } -dev_info (priv->device,"User ID: 0x%x, Synopsys ID: 0x%x\n" , -FIELD_GET (DWMAC_USERVER , version), -FIELD_GET (DWMAC_SNPSVER , version)); - ver->snpsver =FIELD_GET (DWMAC_SNPSVER , version); ver->userver =FIELD_GET (DWMAC_USERVER , version); + +dev_info (priv->device,"User ID: 0x%x, Synopsys ID: 0x%x\n" , + ver->userver, ver->snpsver); }static void stmmac_dwmac_mode_quirk (struct stmmac_priv *priv)
Signature · 1 line
2.47.3
RFC PATCH 5/10 net: stmmac: rename confusing synopsys_id
In reply to Russell King (Oracle)priv->synopsys_id is the Synopsys IP version, defined by snpsver in the databook. This is made up of the major version in bits 7:4 and the first digit of the minor version in bits 3:0. Change the type for synopsys_id to be a u8 and rename to snpsver.
For reference, the values for snpsver:
GMAC100 cores do not have a readable snpsver number.
GMAC cores generally have a snpsver number less than 0x40.
GMAC4 cores may have a version number that overlaps GMAC cores (see first entry for DWMAC_CORE_GMAC4).
XGMAC and XLGMAC cores each have an entirely separate IP version number space from GMAC and GMAC4, which are distinguished by their respective userver.
--- drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c | 2 +- drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c | 2 +- drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c | 2 +- drivers/net/ethernet/stmicro/stmmac/hwif.c | 10 +++++----- drivers/net/ethernet/stmicro/stmmac/stmmac.h | 2 +- drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c | 2 +- drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 12 ++++++------ drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c | 8 ++++---- 8 files changed, 20 insertions(+), 20 deletions(-)
drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c +1 -1
@@ -326,7 +326,7 @@ static int loongson_dwmac_setup(void *apriv, struct mac_device_info *mac)* original value so the correct HW-interface would be selected. */ if (ld->multichan) { - priv->synopsys_id =DWMAC_CORE_3_70 ; + priv->snpsver =DWMAC_CORE_3_70 ; *dma = dwmac1000_dma_ops; dma->init_chan = loongson_dwmac_dma_init_channel; dma->dma_interrupt = loongson_dwmac_dma_interrupt;
drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c +1 -1
@@ -1069,7 +1069,7 @@ static int sun8i_dwmac_setup(void *ppriv, struct mac_device_info *mac) mac->unicast_filter_entries =8 ;/* Synopsys Id is not available */ - priv->synopsys_id =0 ; + priv->snpsver =0 ;return 0 ; }
drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c +1 -1
@@ -380,7 +380,7 @@ static int dwxgmac2_get_hw_feature(void __iomem *ioaddr, dma_cap->vlhash = (hw_cap &XGMAC_HWFEAT_VLHASH ) >>4 ; dma_cap->half_duplex = (hw_cap &XGMAC_HWFEAT_HDSEL ) >>3 ; dma_cap->mbps_1000 = (hw_cap &XGMAC_HWFEAT_GMIISEL ) >>1 ; -if (dma_cap->mbps_1000 && priv->synopsys_id >=DWXGMAC_CORE_2_20 ) +if (dma_cap->mbps_1000 && priv->snpsver >=DWXGMAC_CORE_2_20 ) dma_cap->mbps_10_100 =1 ;/* MAC HW feature 1 */
drivers/net/ethernet/stmicro/stmmac/hwif.c +5 -5
@@ -72,7 +72,7 @@ static int stmmac_dwmac1_quirks(struct stmmac_priv *priv)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 ) { +if (priv->snpsver >=DWMAC_CORE_3_50 ) {dev_info (priv->device,"Enabled extended descriptors\n" ); priv->extend_desc = true; }else {
@@ -299,7 +299,7 @@ stmmac_hwif_find(enum dwmac_core_type core_type, u8 snpsver, u8 userver)if (core_type != entry->core_type)continue ; -/* Use synopsys_id var because some setups can override this */ +/* Use snpsver var because some setups can override this */ if (snpsver < entry->min_snpsver)continue ; if (core_type == DWMAC_CORE_XGMAC &&
@@ -324,7 +324,7 @@ int stmmac_hwif_init(struct stmmac_priv *priv)stmmac_get_version (priv, &version);/* Save ID for later use */ - priv->synopsys_id = version.snpsver; + priv->snpsver = version.snpsver;/* Lets assume some safe values first */ if (core_type ==DWMAC_CORE_GMAC4 ) {
@@ -355,8 +355,8 @@ int stmmac_hwif_init(struct stmmac_priv *priv)/* Fallback to generic HW */ -/* Use synopsys_id var because some setups can override this */ - entry =stmmac_hwif_find (core_type, priv->synopsys_id, version.userver); +/* Use snpsver var because some setups can override this */ + entry =stmmac_hwif_find (core_type, priv->snpsver, version.userver);if (!entry) { dev_err(priv->device, "Failed to find HW IF (id=0x%x, gmac=%d/%d)\n",
drivers/net/ethernet/stmicro/stmmac/stmmac.h +1 -1
@@ -304,7 +304,7 @@ struct stmmac_priv {struct dma_features dma_cap;struct stmmac_counters mmc;int hw_cap_support; -int synopsys_id; +u8 snpsver;u32 msg_enable;/* Our MAC Wake-on-Lan options */ int wolopts;
drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c +1 -1
@@ -553,7 +553,7 @@ static void stmmac_get_ethtool_stats(struct net_device *dev, priv->xstats.phy_eee_wakeup_error_n = val; } -if (priv->synopsys_id >=DWMAC_CORE_3_50 ) +if (priv->snpsver >=DWMAC_CORE_3_50 )stmmac_mac_debug (priv, priv->ioaddr, (void *)&priv->xstats, rx_queues_count, tx_queues_count);
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +6 -6
@@ -755,7 +755,7 @@ static int stmmac_hwtstamp_set(struct net_device *dev, config->rx_filter =HWTSTAMP_FILTER_PTP_V2_EVENT ; ptp_v2 =PTP_TCR_TSVER2ENA ; snap_type_sel =PTP_TCR_SNAPTYPSEL_1 ; -if (priv->synopsys_id <DWMAC_CORE_4_10 ) +if (priv->snpsver <DWMAC_CORE_4_10 ) ts_event_en =PTP_TCR_TSEVNTENA ; ptp_over_ipv4_udp =PTP_TCR_TSIPV4ENA ; ptp_over_ipv6_udp =PTP_TCR_TSIPV6ENA ;
@@ -6624,7 +6624,7 @@ static int stmmac_dma_cap_show(struct seq_file *seq, void *v)seq_printf (seq,"\tAV features: %s\n" , (priv->dma_cap.av) ?"Y" :"N" );seq_printf (seq,"\tChecksum Offload in TX: %s\n" , (priv->dma_cap.tx_coe) ?"Y" :"N" ); -if (priv->synopsys_id >=DWMAC_CORE_4_00 || +if (priv->snpsver >=DWMAC_CORE_4_00 || priv->plat->core_type ==DWMAC_CORE_XGMAC ) {seq_printf (seq,"\tIP Checksum Offload in RX: %s\n" , (priv->dma_cap.rx_coe) ?"Y" :"N" );
@@ -7454,7 +7454,7 @@ static int stmmac_hw_init(struct stmmac_priv *priv)if (priv->plat->rx_coe) { priv->hw->rx_csum = priv->plat->rx_coe;dev_info (priv->device,"RX Checksum Offload Engine supported\n" ); -if (priv->synopsys_id <DWMAC_CORE_4_00 ) +if (priv->snpsver <DWMAC_CORE_4_00 )dev_info (priv->device,"COE Type %d\n" , priv->hw->rx_csum); }if (priv->plat->tx_coe)
@@ -7520,7 +7520,7 @@ static int stmmac_hw_init(struct stmmac_priv *priv)* has to be disable and this can be done by passing the * riwt_off field from the platform. */ -if ((priv->synopsys_id >=DWMAC_CORE_3_50 || +if ((priv->snpsver >=DWMAC_CORE_3_50 || priv->plat->core_type ==DWMAC_CORE_XGMAC ) && !priv->plat->riwt_off) { priv->use_riwt =1 ;
@@ -7897,7 +7897,7 @@ static int __stmmac_dvr_probe(struct device *device,/* Only DWMAC core version 5.20 onwards supports HW descriptor prefetch. */ -if (priv->synopsys_id <DWMAC_CORE_5_20 ) +if (priv->snpsver <DWMAC_CORE_5_20 ) priv->plat->dma_cfg->dche = false;stmmac_check_ether_addr (priv);
@@ -7997,7 +7997,7 @@ static int __stmmac_dvr_probe(struct device *device,if (priv->plat->core_type ==DWMAC_CORE_XGMAC ) ndev->max_mtu =XGMAC_JUMBO_LEN ; -else if (priv->plat->enh_desc || priv->synopsys_id >=DWMAC_CORE_4_00 ) +else if (priv->plat->enh_desc || priv->snpsver >=DWMAC_CORE_4_00 ) ndev->max_mtu =JUMBO_LEN ;else ndev->max_mtu =SKB_MAX_HEAD (NET_SKB_PAD +NET_IP_ALIGN );
drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c +4 -4
@@ -74,7 +74,7 @@ static void stmmac_xgmac2_c22_format(struct stmmac_priv *priv, int phyaddr, {u32 tmp =0 ; -if (priv->synopsys_id <DWXGMAC_CORE_2_20 ) { +if (priv->snpsver <DWXGMAC_CORE_2_20 ) {/* Until ver 2.20 XGMAC does not support C22 addr >= 4. Those * bits above bit 3 of XGMAC_MDIO_C22P register are reserved. */
@@ -136,7 +136,7 @@ static int stmmac_xgmac2_mdio_read_c22(struct mii_bus *bus, int phyaddr,u32 addr;/* Until ver 2.20 XGMAC does not support C22 addr >= 4 */ -if (priv->synopsys_id <DWXGMAC_CORE_2_20 && +if (priv->snpsver <DWXGMAC_CORE_2_20 && phyaddr >MII_XGMAC_MAX_C22ADDR )return -ENODEV ;
@@ -199,7 +199,7 @@ static int stmmac_xgmac2_mdio_write_c22(struct mii_bus *bus, int phyaddr,u32 addr;/* Until ver 2.20 XGMAC does not support C22 addr >= 4 */ -if (priv->synopsys_id <DWXGMAC_CORE_2_20 && +if (priv->snpsver <DWXGMAC_CORE_2_20 && phyaddr >MII_XGMAC_MAX_C22ADDR )return -ENODEV ;
@@ -625,7 +625,7 @@ int stmmac_mdio_register(struct net_device *ndev) new_bus->read_c45 = &stmmac_xgmac2_mdio_read_c45; new_bus->write_c45 = &stmmac_xgmac2_mdio_write_c45; -if (priv->synopsys_id <DWXGMAC_CORE_2_20 ) { +if (priv->snpsver <DWXGMAC_CORE_2_20 ) {/* Right now only C22 phys are supported */ max_addr =MII_XGMAC_MAX_C22ADDR ;
Signature · 1 line
2.47.3
RFC PATCH 6/10 net: stmmac: dche is only for GMAC4 cores
In reply to Russell King (Oracle)dma_cfg->dche is only read by dwmac4_dma_init(), which is only called for the DWMAC_CORE_GMAC4 core type. Rather than having a bare IP version check that can match any core type, make this conditional on DWMAC_CORE_GMAC4 to make it clear that it's a GMAC4 feature.
--- drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +3 -2
@@ -7895,9 +7895,10 @@ static int __stmmac_dvr_probe(struct device *device,if (ret) goto error_hw_init; -/* Only DWMAC core version 5.20 onwards supports HW descriptor prefetch. +/* Only DWMAC4 core version 5.20 onwards support HW descriptor prefetch. */ -if (priv->snpsver <DWMAC_CORE_5_20 ) +if (priv->plat->core_type !=DWMAC_CORE_GMAC4 || + priv->snpsver <DWMAC_CORE_5_20 ) priv->plat->dma_cfg->dche = false;stmmac_check_ether_addr (priv);
Signature · 1 line
2.47.3
RFC PATCH 7/10 net: stmmac: limit MAC .debug() to dwmac1000 and dwmac4
In reply to Russell King (Oracle)Avoid a bare test against snpsver which has multiple different number spaces depending on the core type by testing for core types that implement the .debug() method. This documents that these statistics are only available on dwmac1000 and dwmac4 cores.
--- .../net/ethernet/stmicro/stmmac/stmmac_ethtool.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-)
drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c +11 -2
@@ -531,7 +531,10 @@ static void stmmac_get_ethtool_stats(struct net_device *dev, } } -/* Update the DMA HW counters for dwmac10/100 */ +/* Update the DMA HW counters for dwmac10/100 (DWMAC_CORE_MAC100), +* where this will return zero. Other core types will have a non-zero +* return value. +*/ ret =stmmac_dma_diagnostic_fr (priv, &priv->xstats, priv->ioaddr);if (ret) {/* If supported, for new GMAC chips expose the MMC counters */
@@ -553,7 +556,13 @@ static void stmmac_get_ethtool_stats(struct net_device *dev, priv->xstats.phy_eee_wakeup_error_n = val; } -if (priv->snpsver >=DWMAC_CORE_3_50 ) +/* Only dwmac1000 and dwmac4 implements the MAC .debug() method. +* As there are different version spaces depending on core_type, +* make this conditional on the appropriate core type. +*/ +if ((priv->plat->core_type ==DWMAC_CORE_GMAC || + priv->plat->core_type ==DWMAC_CORE_GMAC4 ) && + priv->snpsver >=DWMAC_CORE_3_50 )stmmac_mac_debug (priv, priv->ioaddr, (void *)&priv->xstats, rx_queues_count, tx_queues_count);
Signature · 1 line
2.47.3
RFC PATCH 8/10 net: stmmac: simplify stmmac_get_ethtool_stats()
In reply to Russell King (Oracle)As documented, stmmac_dma_diagnostic_fr() will return non-zero for all non-DWMAC_CORE_MAC100 core types.
However, as DWMAC_CORE_MAC100 core types do not have DMA capabilities, priv->dma_cap.rmon and priv->dma_cap.eee will be zero, and thus there is no need to make this also conditional on the stmmac_dma_diagnostic_fr() return value.
Remove this test and unindent the code, and remove unnecessary parens.
--- .../ethernet/stmicro/stmmac/stmmac_ethtool.c | 60 +++++++++---------- 1 file changed, 28 insertions(+), 32 deletions(-)
drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c +28 -32
@@ -519,9 +519,9 @@ static void stmmac_get_ethtool_stats(struct net_device *dev,u32 rx_queues_count = priv->plat->rx_queues_to_use;u32 tx_queues_count = priv->plat->tx_queues_to_use;u64 napi_poll =0 , normal_irq_n =0 ; -int i, j =0 , pos, ret;unsigned long count;unsigned int start; +int i, j =0 , pos;if (priv->dma_cap.asp) {for (i =0 ; i <STMMAC_SAFETY_FEAT_SIZE ; i++) {
@@ -531,42 +531,38 @@ static void stmmac_get_ethtool_stats(struct net_device *dev, } } -/* Update the DMA HW counters for dwmac10/100 (DWMAC_CORE_MAC100), -* where this will return zero. Other core types will have a non-zero -* return value. -*/ - ret =stmmac_dma_diagnostic_fr (priv, &priv->xstats, priv->ioaddr); -if (ret) { -/* If supported, for new GMAC chips expose the MMC counters */ -if (priv->dma_cap.rmon) { -stmmac_mmc_read (priv, priv->mmcaddr, &priv->mmc); +/* Update the DMA HW counters for dwmac10/100 (DWMAC_CORE_MAC100). */ +stmmac_dma_diagnostic_fr (priv, &priv->xstats, priv->ioaddr); -for (i =0 ; i <STMMAC_MMC_STATS_LEN ; i++) { -char *p; - p = (char *)priv + stmmac_mmc[i].stat_offset; +/* If supported, for new GMAC chips expose the MMC counters */ +if (priv->dma_cap.rmon) { +stmmac_mmc_read (priv, priv->mmcaddr, &priv->mmc); - data[j++] = (stmmac_mmc[i].sizeof_stat == -sizeof (u64)) ? (*(u64 *)p) : - (*(u32 *)p); - } - } -if (priv->dma_cap.eee) { -int val =phylink_get_eee_err (priv->phylink); -if (val) - priv->xstats.phy_eee_wakeup_error_n = val; +for (i =0 ; i <STMMAC_MMC_STATS_LEN ; i++) { +char *p = (char *)priv + stmmac_mmc[i].stat_offset; + + data[j++] = stmmac_mmc[i].sizeof_stat ==sizeof (u64) ? + *(u64 *)p : *(u32 *)p; } + } -/* Only dwmac1000 and dwmac4 implements the MAC .debug() method. -* As there are different version spaces depending on core_type, -* make this conditional on the appropriate core type. -*/ -if ((priv->plat->core_type ==DWMAC_CORE_GMAC || - priv->plat->core_type ==DWMAC_CORE_GMAC4 ) && - priv->snpsver >=DWMAC_CORE_3_50 ) -stmmac_mac_debug (priv, priv->ioaddr, - (void *)&priv->xstats, - rx_queues_count, tx_queues_count); +if (priv->dma_cap.eee) { +int val =phylink_get_eee_err (priv->phylink); +if (val) + priv->xstats.phy_eee_wakeup_error_n = val; } + +/* Only dwmac1000 and dwmac4 implements the MAC .debug() method. +* As there are different version spaces depending on core_type, +* make this conditional on the appropriate core type. +*/ +if ((priv->plat->core_type ==DWMAC_CORE_GMAC || + priv->plat->core_type ==DWMAC_CORE_GMAC4 ) && + priv->snpsver >=DWMAC_CORE_3_50 ) +stmmac_mac_debug (priv, priv->ioaddr, + (void *)&priv->xstats, + rx_queues_count, tx_queues_count); +for (i =0 ; i <STMMAC_STATS_LEN ; i++) {char *p = (char *)priv + stmmac_gstrings_stats[i].stat_offset; data[j++] = (stmmac_gstrings_stats[i].sizeof_stat ==
Signature · 1 line
2.47.3
RFC PATCH 9/10 net: stmmac: clean up test for rx_coe debug printing
In reply to Russell King (Oracle)The test for printing rx_coe as opposed to rx_coe_type[12] and rxfifo_over_2048 has checked for an XGMAC core or the Synopssys IP version (snpsver) >= v4.0.
Since the Synopsys IP version depends on the core type, avoid using it.
The GMAC4 core type uses dwmac4_get_hw_feature(), which populates rx_coe but not rx_coe_type[12] or rxfifo_over_2048. XGMAC is the same but via dwxgmac2_get_hw_feature().
dwmac-motorcomm populates rx_coe but not the others, and sets the core type to GMAC4. The Synopsys IP version is likely >= 4, but in any case printing rx_coe is clearly more correct.
Lastly, dwmac-sun8i is an oddball - it sets rx_coe, but does not set core_type, leaving it as the defeault DWMAC_CORE_MAC100 since as far as I can see, none of the .dtsi files for this platform use any of the versioned snps,gmac-* compatibles. Moreover, sun8i_dwmac_setup() sets snpsver to zero (which stmmac_get_version() will have already done) so this has always used the rx_coe_type[12] path.
Change the test to check for GMAC4 or XGMAC which covers the cases where rx_coe is set from the core hardware features.
Also add a comment for the GMAC to GMAC4+ rx_coe feature translation in stmmac_hw_init(), and document rx_coe in struct plat_stmmacenet_data.
--- drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 11 +++++++++-- include/linux/stmmac.h | 7 +++++++ 2 files changed, 16 insertions(+), 2 deletions(-)
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +9 -2
@@ -6624,11 +6624,15 @@ static int stmmac_dma_cap_show(struct seq_file *seq, void *v)seq_printf (seq,"\tAV features: %s\n" , (priv->dma_cap.av) ?"Y" :"N" );seq_printf (seq,"\tChecksum Offload in TX: %s\n" , (priv->dma_cap.tx_coe) ?"Y" :"N" ); -if (priv->snpsver >=DWMAC_CORE_4_00 || - priv->plat->core_type ==DWMAC_CORE_XGMAC ) { +if (dwmac_is_xmac (priv->plat->core_type)) { +/* gmac4, xgmac, and motorcomm populate this. */ seq_printf (seq,"\tIP Checksum Offload in RX: %s\n" , (priv->dma_cap.rx_coe) ?"Y" :"N" ); }else { +/* only dwmac1000 has these three. sun8i sets rx_coe, but +* sets snpsver to zero and leaves core_Type as MAC100, so +* uses this path. +*/ seq_printf (seq,"\tIP Checksum Offload (type1) in RX: %s\n" , (priv->dma_cap.rx_coe_type1) ?"Y" :"N" ); seq_printf(seq, "\tIP Checksum Offload (type2) in RX: %s\n",
@@ -7441,6 +7445,9 @@ static int stmmac_hw_init(struct stmmac_priv *priv)/* In case of GMAC4 rx_coe is from HW cap register. */ priv->plat->rx_coe = priv->dma_cap.rx_coe; +/* GMAC (dwmac1000) has separate bits for the Rx COE type. +* Translate to the GMAC4/XGMAC rx_coe feature code. +*/ if (priv->dma_cap.rx_coe_type2) priv->plat->rx_coe =STMMAC_RX_COE_TYPE2 ;else if (priv->dma_cap.rx_coe_type1)
include/linux/stmmac.h +7 -0
@@ -256,6 +256,13 @@ struct plat_stmmacenet_data {bool force_sf_dma_mode;bool force_thresh_dma_mode;bool riwt_off; +/* rx_coe: +* for dwmac100, rx_coe does not appear to be defined. +* for dwmac1000, rx_coe takes one of the STMMAC_RX_COE_* constants, +* which will be derived from the RXTYP[12]COE hardware feature bits. +* for dwmac4 and xgmac, rx_coe is a boolean from the RXCOESEL hardware +* feature bit. +*/ int rx_coe;int max_speed;int maxmtu;
Signature · 1 line
2.47.3
RFC PATCH 10/10 net: stmmac: only print receive COE type for GMAC cores
In reply to Russell King (Oracle)As identified in the previous commit, only GMAC cores have a COE type, but priv->snpsver's numberspace is core specific. Change the test for printing this to check the core type instead of checking for the Synopssys IP version being < v4.0, which will incorrectly match XGMAC cores.
--- drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +1 -1
@@ -7461,7 +7461,7 @@ static int stmmac_hw_init(struct stmmac_priv *priv)if (priv->plat->rx_coe) { priv->hw->rx_csum = priv->plat->rx_coe;dev_info (priv->device,"RX Checksum Offload Engine supported\n" ); -if (priv->snpsver <DWMAC_CORE_4_00 ) +if (priv->plat->core_type ==DWMAC_CORE_GMAC )dev_info (priv->device,"COE Type %d\n" , priv->hw->rx_csum); }if (priv->plat->tx_coe)
Signature · 1 line
2.47.3