Add support for XGMAC2 in stmmac
Subsystems (5)
v3 cover Add support for XGMAC2 in stmmac
This series adds support for 10Gigabit IP in stmmac. The IP is called XGMAC2 and has many similarities with GMAC4. Due to this, its relatively easy to incorporate this new IP into stmmac driver by adding a new block and filling the necessary callbacks.
The functionality added by this series is still reduced but its only a starting point which will later be expanded.
I splitted the patches into funcionality and to ease the review. Only the patch 8/9 really enables the XGMAC2 block by adding a new compatible string.
Version 3 addresses review comments of Andrew Lunn.
NOTE: Although the IP supports 10G, for now it was only possible to test it at 1G speed due to 10G PHY HW shipping problems. Here follows iperf3 results at 1G:
---
# iperf3 -c 192.168.0.10 Connecting to host 192.168.0.10, port 5201 [ 4] local 192.168.0.3 port 39178 connected to 192.168.0.10 port 5201 [ ID] Interval Transfer Bandwidth Retr Cwnd [ 4] 0.00-1.00 sec 110 MBytes 920 Mbits/sec 0 482 KBytes [ 4] 1.00-2.00 sec 113 MBytes 946 Mbits/sec 0 482 KBytes [ 4] 2.00-3.00 sec 112 MBytes 937 Mbits/sec 0 482 KBytes [ 4] 3.00-4.00 sec 113 MBytes 946 Mbits/sec 0 482 KBytes [ 4] 4.00-5.00 sec 112 MBytes 935 Mbits/sec 0 482 KBytes [ 4] 5.00-6.00 sec 113 MBytes 946 Mbits/sec 0 482 KBytes [ 4] 6.00-7.00 sec 112 MBytes 937 Mbits/sec 0 482 KBytes [ 4] 7.00-8.00 sec 113 MBytes 946 Mbits/sec 0 482 KBytes [ 4] 8.00-9.00 sec 112 MBytes 937 Mbits/sec 0 482 KBytes [ 4] 9.00-10.00 sec 113 MBytes 946 Mbits/sec 0 482 KBytes - - - - - - - - - - - - - - - - - - - - - - - - - [ ID] Interval Transfer Bandwidth Retr [ 4] 0.00-10.00 sec 1.09 GBytes 940 Mbits/sec 0 sender [ 4] 0.00-10.00 sec 1.09 GBytes 938 Mbits/sec receiver ---
Jose Abreu (9):
net: stmmac: Add XGMAC 2.10 HWIF entry
net: stmmac: Add MAC related callbacks for XGMAC2
net: stmmac: Add DMA related callbacks for XGMAC2
net: stmmac: Add descriptor related callbacks for XGMAC2
net: stmmac: Add MDIO related functions for XGMAC2
net: stmmac: Add PTP support for XGMAC2
net: stmmac: Integrate XGMAC into main driver flow
net: stmmac: Add the bindings parsing for XGMAC2
dt-bindings: net: stmmac: Add the bindings documentation for XGMAC2.
Documentation/devicetree/bindings/net/stmmac.txt | 5 +- drivers/net/ethernet/stmicro/stmmac/Makefile | 3 +- drivers/net/ethernet/stmicro/stmmac/common.h | 17 +- .../net/ethernet/stmicro/stmmac/dwmac-generic.c | 2 + drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h | 227 ++++++++++++ .../net/ethernet/stmicro/stmmac/dwxgmac2_core.c | 371 +++++++++++++++++++ .../net/ethernet/stmicro/stmmac/dwxgmac2_descs.c | 280 ++++++++++++++ drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c | 410 +++++++++++++++++++++ drivers/net/ethernet/stmicro/stmmac/hwif.c | 31 +- drivers/net/ethernet/stmicro/stmmac/hwif.h | 3 + drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 67 +++- drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c | 117 +++++- .../net/ethernet/stmicro/stmmac/stmmac_platform.c | 6 + drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c | 6 +- drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.h | 1 + include/linux/stmmac.h | 1 + 16 files changed, 1513 insertions(+), 34 deletions(-) create mode 100644 drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h create mode 100644 drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c create mode 100644 drivers/net/ethernet/stmicro/stmmac/dwxgmac2_descs.c create mode 100644 drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c
Signature · 1 line
2.7.4
PATCH v3 1/9 net: stmmac: Add XGMAC 2.10 HWIF entry
Add a new entry to HWIF table for XGMAC 2.10. For now we fill it with empty callbacks which will be added in posterior patches.
--- drivers/net/ethernet/stmicro/stmmac/common.h | 14 +++++++------ drivers/net/ethernet/stmicro/stmmac/hwif.c | 31 ++++++++++++++++++++++++++-- include/linux/stmmac.h | 1 + 3 files changed, 38 insertions(+), 8 deletions(-)
drivers/net/ethernet/stmicro/stmmac/common.h +8 -6
@@ -36,12 +36,14 @@#include "mmc.h" /* Synopsys Core versions */ -#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 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 DWXGMAC_CORE_2_10 0x21 +#define STMMAC_CHAN0 0/* Always supported and default for all chips */ /* These need to be power of two, and >= 4 */
drivers/net/ethernet/stmicro/stmmac/hwif.c +29 -2
@@ -72,6 +72,7 @@ static int stmmac_dwmac4_quirks(struct stmmac_priv *priv) static const struct stmmac_hwif_entry { bool gmac; bool gmac4; + bool xgmac; u32 min_id; const struct stmmac_regs_off regs; const void *desc;
@@ -87,6 +88,7 @@ static const struct stmmac_hwif_entry { { .gmac = false, .gmac4 = false, + .xgmac = false, .min_id = 0, .regs = { .ptp_off = PTP_GMAC3_X_OFFSET,
@@ -103,6 +105,7 @@ static const struct stmmac_hwif_entry { }, { .gmac = true, .gmac4 = false, + .xgmac = false, .min_id = 0, .regs = { .ptp_off = PTP_GMAC3_X_OFFSET,
@@ -119,6 +122,7 @@ static const struct stmmac_hwif_entry { }, { .gmac = false, .gmac4 = true, + .xgmac = false, .min_id = 0, .regs = { .ptp_off = PTP_GMAC4_OFFSET,
@@ -135,6 +139,7 @@ static const struct stmmac_hwif_entry { }, { .gmac = false, .gmac4 = true, + .xgmac = false, .min_id = DWMAC_CORE_4_00, .regs = { .ptp_off = PTP_GMAC4_OFFSET,
@@ -151,6 +156,7 @@ static const struct stmmac_hwif_entry { }, { .gmac = false, .gmac4 = true, + .xgmac = false, .min_id = DWMAC_CORE_4_10, .regs = { .ptp_off = PTP_GMAC4_OFFSET,
@@ -167,6 +173,7 @@ static const struct stmmac_hwif_entry { }, { .gmac = false, .gmac4 = true, + .xgmac = false, .min_id = DWMAC_CORE_5_10, .regs = { .ptp_off = PTP_GMAC4_OFFSET,
@@ -180,11 +187,29 @@ static const struct stmmac_hwif_entry { .tc = &dwmac510_tc_ops, .setup = dwmac4_setup, .quirks = NULL, - } + }, { + .gmac = false, + .gmac4 = false, + .xgmac = true, + .min_id = DWXGMAC_CORE_2_10, + .regs = { + .ptp_off = 0, + .mmc_off = 0, + }, + .desc = NULL, + .dma = NULL, + .mac = NULL, + .hwtimestamp = NULL, + .mode = NULL, + .tc = NULL, + .setup = NULL, + .quirks = NULL, + }, };int stmmac_hwif_init (struct stmmac_priv *priv) { +bool needs_xgmac = priv->plat->has_xgmac;bool needs_gmac4 = priv->plat->has_gmac4;bool needs_gmac = priv->plat->has_gmac;const struct stmmac_hwif_entry *entry;
@@ -195,7 +220,7 @@ int stmmac_hwif_init(struct stmmac_priv *priv)if (needs_gmac) { id =stmmac_get_id (priv,GMAC_VERSION ); - }else if (needs_gmac4) { + }else if (needs_gmac4 || needs_xgmac) { id =stmmac_get_id (priv,GMAC4_VERSION ); }else { id =0 ;
@@ -229,6 +254,8 @@ int stmmac_hwif_init(struct stmmac_priv *priv)continue ;if (needs_gmac4 ^ entry->gmac4)continue ; +if (needs_xgmac ^ entry->xgmac) +continue ;/* Use synopsys_id var because some setups can override this */ if (priv->synopsys_id < entry->min_id)continue ;
include/linux/stmmac.h +1 -0
@@ -190,5 +190,6 @@ struct plat_stmmacenet_data {bool tso_en;int mac_port_sel_speed;bool en_tx_lpi_clockgating; + int has_xgmac; };#endif
Signature · 1 line
2.7.4
Re: [PATCH v3 net-next 1/9] net: stmmac: Add XGMAC 2.10 HWIF entry
Quoted 52 lines · Jose Abreu
Add a new entry to HWIF table for XGMAC 2.10. For now we fill it with empty callbacks which will be added in posterior patches.
Signed-off-by Jose Abreu <[email protected]>Cc David S. Miller <[email protected]>Cc Joao Pinto <[email protected]>Cc Giuseppe Cavallaro <[email protected]>Cc Alexandre Torgue <[email protected]>--- drivers/net/ethernet/stmicro/stmmac/common.h | 14 +++++++------ drivers/net/ethernet/stmicro/stmmac/hwif.c | 31 ++++++++++++++++++++++++++-- include/linux/stmmac.h | 1 + 3 files changed, 38 insertions(+), 8 deletions(-)drivers/net/ethernet/stmicro/stmmac/common.h +8
-6@@ -36,12 +36,14 @@#include "mmc.h" /* Synopsys Core versions */ -#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 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 DWXGMAC_CORE_2_10 0x21 +#define STMMAC_CHAN0 0/* Always supported and default for all chips */ /* These need to be power of two, and >= 4 */ drivers/net/ethernet/stmicro/stmmac/hwif.c +1
-0@@ -72,6 +72,7 @@ static int stmmac_dwmac4_quirks(struct stmmac_priv *priv) static const struct stmmac_hwif_entry { bool gmac; bool gmac4; + bool xgmac; u32 min_id; const struct stmmac_regs_off regs; const void *desc;
drivers/net/ethernet/stmicro/stmmac/hwif.c static const struct stmmac_hwif_entry { · line 91
Quoted 4 lines
drivers/net/ethernet/stmicro/stmmac/hwif.c +1
-0@@ -87,6 +88,7 @@ static const struct stmmac_hwif_entry { { .gmac = false, .gmac4 = false, + .xgmac = false,
In a future clean-up you would like want to remove this and replace this an enumeration which is less error prone than having to define a boolean for each of these previous generations only to say "this is not an xgmac".
Signature · 1 line
Florian
Re: [PATCH v3 net-next 1/9] net: stmmac: Add XGMAC 2.10 HWIF entry
Hi Florian,
Quoted 9 lines · Florian Fainelli
drivers/net/ethernet/stmicro/stmmac/hwif.c static const struct stmmac_hwif_entry { · line 91
Quoted 5 lines · Jose Abreu
drivers/net/ethernet/stmicro/stmmac/hwif.c +1
-0@@ -87,6 +88,7 @@ static const struct stmmac_hwif_entry { { .gmac = false, .gmac4 = false, + .xgmac = false,In a future clean-up you would like want to remove this and replace this an enumeration which is less error prone than having to define a boolean for each of these previous generations only to say "this is not an xgmac".
Its a good idea! I really don't like the pattern of "if (priv->plat->has_something)" in the code. I will think about adding this but for now let's merge xgmac2 and I will try to refactor the code later because I will need to change many files and the patchset would be bigger.
Thanks and Best Regards,
Jose Miguel Abreu
PATCH v3 2/9 net: stmmac: Add MAC related callbacks for XGMAC2
In reply to Jose AbreuAdd the MAC related callbacks for the new IP block XGMAC2.
--- drivers/net/ethernet/stmicro/stmmac/Makefile | 2 +- drivers/net/ethernet/stmicro/stmmac/common.h | 3 + drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h | 141 ++++++++ .../net/ethernet/stmicro/stmmac/dwxgmac2_core.c | 371 +++++++++++++++++++++ drivers/net/ethernet/stmicro/stmmac/hwif.c | 4 +- drivers/net/ethernet/stmicro/stmmac/hwif.h | 1 + 6 files changed, 519 insertions(+), 3 deletions(-) create mode 100644 drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h create mode 100644 drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
drivers/net/ethernet/stmicro/stmmac/Makefile +1 -1
@@ -5,7 +5,7 @@ stmmac-objs:= stmmac_main.o stmmac_ethtool.o stmmac_mdio.o ring_mode.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 hwif.o \ - stmmac_tc.o $(stmmac-y) + stmmac_tc.o dwxgmac2_core.o $(stmmac-y) # Ordering matters. Generic driver must be last. obj-$(CONFIG_STMMAC_PLATFORM) += stmmac-platform.o
drivers/net/ethernet/stmicro/stmmac/common.h +3 -0
@@ -400,6 +400,8 @@ struct mac_link {u32 speed10;u32 speed100;u32 speed1000; +u32 speed2500; +u32 speed10000;u32 duplex; };
@@ -441,6 +443,7 @@ struct stmmac_rx_routing {int dwmac100_setup (struct stmmac_priv *priv);int dwmac1000_setup (struct stmmac_priv *priv);int dwmac4_setup (struct stmmac_priv *priv); +int dwxgmac2_setup (struct stmmac_priv *priv);void stmmac_set_mac_addr (void __iomem *ioaddr,u8 addr[6 ],unsigned int high,unsigned int low);
drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h new file +141 -0
141 lines not on this page · raw message
drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c new file +371 -0
371 lines not on this page · raw message
drivers/net/ethernet/stmicro/stmmac/hwif.c +2 -2
@@ -198,11 +198,11 @@ static const struct stmmac_hwif_entry { }, .desc = NULL, .dma = NULL, - .mac = NULL, + .mac = &dwxgmac210_ops, .hwtimestamp = NULL, .mode = NULL, .tc = NULL, - .setup = NULL, + .setup = dwxgmac2_setup, .quirks = NULL, }, };
drivers/net/ethernet/stmicro/stmmac/hwif.h +1 -0
@@ -479,6 +479,7 @@ extern const struct stmmac_ops dwmac410_ops;extern const struct stmmac_dma_ops dwmac410_dma_ops;extern const struct stmmac_ops dwmac510_ops;extern const struct stmmac_tc_ops dwmac510_tc_ops; +extern const struct stmmac_ops dwxgmac210_ops;#define GMAC_VERSION 0x00000020/* GMAC CORE Version */ #define GMAC4_VERSION 0x00000110/* GMAC4+ CORE Version */
Signature · 1 line
2.7.4
PATCH v3 3/9 net: stmmac: Add DMA related callbacks for XGMAC2
In reply to Jose AbreuAdd the DMA related callbacks for the new IP block XGMAC2.
--- drivers/net/ethernet/stmicro/stmmac/Makefile | 2 +- drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h | 56 +++ drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c | 410 +++++++++++++++++++++ drivers/net/ethernet/stmicro/stmmac/hwif.c | 2 +- drivers/net/ethernet/stmicro/stmmac/hwif.h | 1 + 5 files changed, 469 insertions(+), 2 deletions(-) create mode 100644 drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c
drivers/net/ethernet/stmicro/stmmac/Makefile +1 -1
@@ -5,7 +5,7 @@ stmmac-objs:= stmmac_main.o stmmac_ethtool.o stmmac_mdio.o ring_mode.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 hwif.o \ - stmmac_tc.o dwxgmac2_core.o $(stmmac-y) + stmmac_tc.o dwxgmac2_core.o dwxgmac2_dma.o $(stmmac-y) # Ordering matters. Generic driver must be last. obj-$(CONFIG_STMMAC_PLATFORM) += stmmac-platform.o
drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h +56 -0
60 lines not on this page · raw message
drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c new file +410 -0
410 lines not on this page · raw message
drivers/net/ethernet/stmicro/stmmac/hwif.c +1 -1
@@ -197,7 +197,7 @@ static const struct stmmac_hwif_entry { .mmc_off = 0, }, .desc = NULL, - .dma = NULL, + .dma = &dwxgmac210_dma_ops, .mac = &dwxgmac210_ops, .hwtimestamp = NULL, .mode = NULL,
drivers/net/ethernet/stmicro/stmmac/hwif.h +1 -0
@@ -480,6 +480,7 @@ extern const struct stmmac_dma_ops dwmac410_dma_ops;extern const struct stmmac_ops dwmac510_ops;extern const struct stmmac_tc_ops dwmac510_tc_ops;extern const struct stmmac_ops dwxgmac210_ops; +extern const struct stmmac_dma_ops dwxgmac210_dma_ops;#define GMAC_VERSION 0x00000020/* GMAC CORE Version */ #define GMAC4_VERSION 0x00000110/* GMAC4+ CORE Version */
Signature · 1 line
2.7.4
Re: [PATCH v3 net-next 3/9] net: stmmac: Add DMA related callbacks for XGMAC2
Quoted 9 lines · Jose Abreu
Add the DMA related callbacks for the new IP block XGMAC2.
Signed-off-by Jose Abreu <[email protected]>Cc David S. Miller <[email protected]>Cc Joao Pinto <[email protected]>Cc Giuseppe Cavallaro <[email protected]>Cc Alexandre Torgue <[email protected]>---
drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c line 96
Quoted 7 lines
drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c new file +7
-0+ value &= ~XGMAC_RD_OSR_LMT ; + value |= (axi->axi_rd_osr_lmt <<XGMAC_RD_OSR_LMT_SHIFT ) & +XGMAC_RD_OSR_LMT ; + +for (i =0 ; i <AXI_BLEN ; i++) { +if (axi->axi_blen[i]) + value &= ~XGMAC_UNDEF ;
Should not you be you clearing all XGMAC_BLEN* values since you do a logical or here? I am assuming this is not something that would likely change from one open/close but still?
Signature · 1 line
Florian
Re: [PATCH v3 net-next 3/9] net: stmmac: Add DMA related callbacks for XGMAC2
Quoted 19 lines · Florian Fainelli
Quoted 8 lines · Jose Abreu
Add the DMA related callbacks for the new IP block XGMAC2.
Signed-off-by Jose Abreu <[email protected]>Cc David S. Miller <[email protected]>Cc Joao Pinto <[email protected]>Cc Giuseppe Cavallaro <[email protected]>Cc Alexandre Torgue <[email protected]>---
drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c line 96
Quoted 7 lines
drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c new file +7
-0+ value &= ~XGMAC_RD_OSR_LMT ; + value |= (axi->axi_rd_osr_lmt <<XGMAC_RD_OSR_LMT_SHIFT ) & +XGMAC_RD_OSR_LMT ; + +for (i =0 ; i <AXI_BLEN ; i++) { +if (axi->axi_blen[i]) + value &= ~XGMAC_UNDEF ;Should not you be you clearing all XGMAC_BLEN* values since you do a logical or here? I am assuming this is not something that would likely change from one open/close but still?
Yeah, this won't change between open/close but I will add the mask anyway.
Thanks and Best Regards,
Jose Miguel Abreu
PATCH v3 4/9 net: stmmac: Add descriptor related callbacks for XGMAC2
In reply to Jose AbreuAdd the descriptor related callbacks for the new IP block XGMAC2.
--- drivers/net/ethernet/stmicro/stmmac/Makefile | 3 +- drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h | 30 +++ .../net/ethernet/stmicro/stmmac/dwxgmac2_descs.c | 280 +++++++++++++++++++++ drivers/net/ethernet/stmicro/stmmac/hwif.c | 2 +- drivers/net/ethernet/stmicro/stmmac/hwif.h | 1 + 5 files changed, 314 insertions(+), 2 deletions(-) create mode 100644 drivers/net/ethernet/stmicro/stmmac/dwxgmac2_descs.c
drivers/net/ethernet/stmicro/stmmac/Makefile +2 -1
@@ -5,7 +5,8 @@ stmmac-objs:= stmmac_main.o stmmac_ethtool.o stmmac_mdio.o ring_mode.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 hwif.o \ - stmmac_tc.o dwxgmac2_core.o dwxgmac2_dma.o $(stmmac-y) + stmmac_tc.o dwxgmac2_core.o dwxgmac2_dma.o dwxgmac2_descs.o \ + $(stmmac-y) # Ordering matters. Generic driver must be last. obj-$(CONFIG_STMMAC_PLATFORM) += stmmac-platform.o
drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h +30 -0
@@ -194,4 +194,34 @@#define XGMAC_TPS BIT(1)#define XGMAC_TI BIT(0) +/* Descriptors */ +#define XGMAC_TDES2_IOC BIT(31) +#define XGMAC_TDES2_TTSE BIT(30) +#define XGMAC_TDES2_B2L GENMASK(29, 16) +#define XGMAC_TDES2_B2L_SHIFT 16 +#define XGMAC_TDES2_B1L GENMASK(13, 0) +#define XGMAC_TDES3_OWN BIT(31) +#define XGMAC_TDES3_CTXT BIT(30) +#define XGMAC_TDES3_FD BIT(29) +#define XGMAC_TDES3_LD BIT(28) +#define XGMAC_TDES3_CPC GENMASK(27, 26) +#define XGMAC_TDES3_CPC_SHIFT 26 +#define XGMAC_TDES3_TCMSSV BIT(26) +#define XGMAC_TDES3_THL GENMASK(22, 19) +#define XGMAC_TDES3_THL_SHIFT 19 +#define XGMAC_TDES3_TSE BIT(18) +#define XGMAC_TDES3_CIC GENMASK(17, 16) +#define XGMAC_TDES3_CIC_SHIFT 16 +#define XGMAC_TDES3_TPL GENMASK(17, 0) +#define XGMAC_TDES3_FL GENMASK(14, 0) +#define XGMAC_RDES3_OWN BIT(31) +#define XGMAC_RDES3_CTXT BIT(30) +#define XGMAC_RDES3_IOC BIT(30) +#define XGMAC_RDES3_LD BIT(28) +#define XGMAC_RDES3_CDA BIT(27) +#define XGMAC_RDES3_ES BIT(15) +#define XGMAC_RDES3_PL GENMASK(13, 0) +#define XGMAC_RDES3_TSD BIT(6) +#define XGMAC_RDES3_TSA BIT(4) +#endif /* __STMMAC_DWXGMAC2_H__ */
drivers/net/ethernet/stmicro/stmmac/dwxgmac2_descs.c new file +280 -0
280 lines not on this page · raw message
drivers/net/ethernet/stmicro/stmmac/hwif.c +1 -1
@@ -196,7 +196,7 @@ static const struct stmmac_hwif_entry { .ptp_off = 0, .mmc_off = 0, }, - .desc = NULL, + .desc = &dwxgmac210_desc_ops, .dma = &dwxgmac210_dma_ops, .mac = &dwxgmac210_ops, .hwtimestamp = NULL,
drivers/net/ethernet/stmicro/stmmac/hwif.h +1 -0
@@ -481,6 +481,7 @@ extern const struct stmmac_ops dwmac510_ops;extern const struct stmmac_tc_ops dwmac510_tc_ops;extern const struct stmmac_ops dwxgmac210_ops;extern const struct stmmac_dma_ops dwxgmac210_dma_ops; +extern const struct stmmac_desc_ops dwxgmac210_desc_ops;#define GMAC_VERSION 0x00000020/* GMAC CORE Version */ #define GMAC4_VERSION 0x00000110/* GMAC4+ CORE Version */
Signature · 1 line
2.7.4
PATCH v3 5/9 net: stmmac: Add MDIO related functions for XGMAC2
In reply to Jose AbreuAdd the MDIO related funcionalities for the new IP block XGMAC2.
---
Changes from v2:
- Use helper to set C22 (Andrew)
- Wait for bus free before setting C22 reg (Andrew)
Changes from v1:
- Remove C45 support (Andrew)
- Add define for bits (Andrew)
- Remove uneeded cast (Andrew)
- Use different callbacks instead of if's (Andrew)
--- drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c | 117 +++++++++++++++++++++- 1 file changed, 115 insertions(+), 2 deletions(-)
drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c +115 -2
@@ -29,6 +29,7 @@#include <linux/phy.h> #include <linux/slab.h> +#include "dwxgmac2.h" #include "stmmac.h" #define MII_BUSY 0x00000001
@@ -39,6 +40,112 @@#define MII_GMAC4_WRITE (1 << MII_GMAC4_GOC_SHIFT)#define MII_GMAC4_READ (3 << MII_GMAC4_GOC_SHIFT) +/* XGMAC defines */ +#define MII_XGMAC_SADDR BIT(18) +#define MII_XGMAC_CMD_SHIFT 16 +#define MII_XGMAC_WRITE (1 << MII_XGMAC_CMD_SHIFT) +#define MII_XGMAC_READ (3 << MII_XGMAC_CMD_SHIFT) +#define MII_XGMAC_BUSY BIT(22) + +static int stmmac_xgmac2_c22_format (struct stmmac_priv *priv,int phyaddr, +int phyreg,u32 *hw_addr) +{ +unsigned int mii_data = priv->hw->mii.data; +u32 tmp; + +/* HW does not support C22 addr >= 4 */ +if (phyaddr >=4 ) +return -ENODEV ; +/* Wait until any existing MII operation is complete */ +if (readl_poll_timeout (priv->ioaddr + mii_data, tmp, + !(tmp &MII_XGMAC_BUSY ),100 ,10000 )) +return -EBUSY ; + +/* Set port as Clause 22 */ + tmp =readl (priv->ioaddr +XGMAC_MDIO_C22P ); + tmp |=BIT (phyaddr); +writel (tmp, priv->ioaddr +XGMAC_MDIO_C22P ); + + *hw_addr = (phyaddr <<16 ) | (phyreg &0x1f ); +return 0 ; +} + +static int stmmac_xgmac2_mdio_read (struct mii_bus *bus,int phyaddr,int phyreg) +{ +struct net_device *ndev = bus->priv; +struct stmmac_priv *priv =netdev_priv (ndev); +unsigned int mii_address = priv->hw->mii.addr; +unsigned int mii_data = priv->hw->mii.data; +u32 tmp, addr, value =MII_XGMAC_BUSY ; +int ret; + +if (phyreg &MII_ADDR_C45 ) { +return -EOPNOTSUPP ; + }else { + ret =stmmac_xgmac2_c22_format (priv, phyaddr, phyreg, &addr); +if (ret) +return ret; + } + + value |= (priv->clk_csr << priv->hw->mii.clk_csr_shift) + & priv->hw->mii.clk_csr_mask; + value |=MII_XGMAC_SADDR |MII_XGMAC_READ ; + +/* Wait until any existing MII operation is complete */ +if (readl_poll_timeout (priv->ioaddr + mii_data, tmp, + !(tmp &MII_XGMAC_BUSY ),100 ,10000 )) +return -EBUSY ; + +/* Set the MII address register to read */ +writel (addr, priv->ioaddr + mii_address); +writel (value, priv->ioaddr + mii_data); + +/* Wait until any existing MII operation is complete */ +if (readl_poll_timeout (priv->ioaddr + mii_data, tmp, + !(tmp &MII_XGMAC_BUSY ),100 ,10000 )) +return -EBUSY ; + +/* Read the data from the MII data register */ +return readl (priv->ioaddr + mii_data) &GENMASK (15 ,0 ); +} + +static int stmmac_xgmac2_mdio_write (struct mii_bus *bus,int phyaddr, +int phyreg,u16 phydata) +{ +struct net_device *ndev = bus->priv; +struct stmmac_priv *priv =netdev_priv (ndev); +unsigned int mii_address = priv->hw->mii.addr; +unsigned int mii_data = priv->hw->mii.data; +u32 addr, tmp, value =MII_XGMAC_BUSY ; +int ret; + +if (phyreg &MII_ADDR_C45 ) { +return -EOPNOTSUPP ; + }else { + ret =stmmac_xgmac2_c22_format (priv, phyaddr, phyreg, &addr); +if (ret) +return ret; + } + + value |= (priv->clk_csr << priv->hw->mii.clk_csr_shift) + & priv->hw->mii.clk_csr_mask; + value |= phydata |MII_XGMAC_SADDR ; + value |=MII_XGMAC_WRITE ; + +/* Wait until any existing MII operation is complete */ +if (readl_poll_timeout (priv->ioaddr + mii_data, tmp, + !(tmp &MII_XGMAC_BUSY ),100 ,10000 )) +return -EBUSY ; + +/* Set the MII address register to write */ +writel (addr, priv->ioaddr + mii_address); +writel (value, priv->ioaddr + mii_data); + +/* Wait until any existing MII operation is complete */ +return readl_poll_timeout (priv->ioaddr + mii_data, tmp, + !(tmp &MII_XGMAC_BUSY ),100 ,10000 ); +} +/** * stmmac_mdio_read * @bus: points to the mii_bus structure
@@ -223,8 +330,14 @@ int stmmac_mdio_register(struct net_device *ndev)#endif new_bus->name ="stmmac" ; - new_bus->read = &stmmac_mdio_read; - new_bus->write = &stmmac_mdio_write; + +if (priv->plat->has_xgmac) { + new_bus->read = &stmmac_xgmac2_mdio_read; + new_bus->write = &stmmac_xgmac2_mdio_write; + }else { + new_bus->read = &stmmac_mdio_read; + new_bus->write = &stmmac_mdio_write; + } new_bus->reset = &stmmac_mdio_reset; snprintf(new_bus->id, MII_BUS_ID_SIZE, "%s-%x",
Signature · 1 line
2.7.4
Re: [PATCH v3 net-next 5/9] net: stmmac: Add MDIO related functions for XGMAC2
Quoted 8 lines · Jose Abreu
Add the MDIO related funcionalities for the new IP block XGMAC2.
Signed-off-by Jose Abreu <[email protected]>Cc David S. Miller <[email protected]>Cc Joao Pinto <[email protected]>Cc Giuseppe Cavallaro <[email protected]>Cc Alexandre Torgue <[email protected]>Cc Andrew Lunn <[email protected]>
Andrew
Re: [PATCH v3 net-next 5/9] net: stmmac: Add MDIO related functions for XGMAC2
In reply to Jose AbreuQuoted 10 lines · Jose Abreu
Add the MDIO related funcionalities for the new IP block XGMAC2.
Signed-off-by Jose Abreu <[email protected]>Cc David S. Miller <[email protected]>Cc Joao Pinto <[email protected]>Cc Giuseppe Cavallaro <[email protected]>Cc Alexandre Torgue <[email protected]>Cc Andrew Lunn <[email protected]>---
drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c line 58
Quoted 9 lines
drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c +9
-0+satic int stmmac_xgmac2_c22_format(struct stmmac_priv *priv, int phyaddr, +int phyreg,u32 *hw_addr) +{ +unsigned int mii_data = priv->hw->mii.data; +u32 tmp; + +/* HW does not support C22 addr >= 4 */ +if (phyaddr >=4 ) +return -ENODEV ;
It would be nice if this could be moved at probe time so you don't have to wait until you connect to the PHY, read its PHY OUI and find out it has a MDIO address >= 4. Not a blocker, but something that could be improved further on.
In premise you could even scan the MDIO bus' device tree node, and find that out ahead of time.
drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c line 66
Quoted 8 lines
drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c +8
-0+/* Wait until any existing MII operation is complete */ +if (readl_poll_timeout (priv->ioaddr + mii_data, tmp, + !(tmp &MII_XGMAC_BUSY ),100 ,10000 )) +return -EBUSY ; + +/* Set port as Clause 22 */ + tmp =readl (priv->ioaddr +XGMAC_MDIO_C22P ); + tmp |=BIT (phyaddr);
Since the registers are being Read/Modify/Write here, don't you need to clear the previous address bits as well?
You probably did not encounter any problems in your testing if you had only one PHY on the MDIO bus, but this is not something that is necessarily true, e.g: if you have an Ethernet switch, several MDIO bus addresses are going to be responding.
Your MDIO bus implementation must be able to support one transaction with one PHY address and the next transaction with another PHY address , etc...
That is something that should be easy to fix and be resubmitted as part of v4.
Signature · 1 line
Florian
Re: [PATCH v3 net-next 5/9] net: stmmac: Add MDIO related functions for XGMAC2
Quoted 24 lines · Florian Fainelli
Quoted 9 lines · Jose Abreu
Add the MDIO related funcionalities for the new IP block XGMAC2.
Signed-off-by Jose Abreu <[email protected]>Cc David S. Miller <[email protected]>Cc Joao Pinto <[email protected]>Cc Giuseppe Cavallaro <[email protected]>Cc Alexandre Torgue <[email protected]>Cc Andrew Lunn <[email protected]>---
drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c line 58
Quoted 9 lines
drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c +9
-0+satic int stmmac_xgmac2_c22_format(struct stmmac_priv *priv, int phyaddr, +int phyreg,u32 *hw_addr) +{ +unsigned int mii_data = priv->hw->mii.data; +u32 tmp; + +/* HW does not support C22 addr >= 4 */ +if (phyaddr >=4 ) +return -ENODEV ;It would be nice if this could be moved at probe time so you don't have to wait until you connect to the PHY, read its PHY OUI and find out it has a MDIO address >= 4. Not a blocker, but something that could be improved further on.
Quoted 2 lines
In premise you could even scan the MDIO bus' device tree node, and find that out ahead of time.
Oh, but I use phylib ... I only provide the read/write callbacks so I think we should avoid duplicating the code that's already in the phylib ... No?
Quoted 17 lines
drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c line 66
Quoted 9 lines
drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c +8
-0+/* Wait until any existing MII operation is complete */ +if (readl_poll_timeout (priv->ioaddr + mii_data, tmp, + !(tmp &MII_XGMAC_BUSY ),100 ,10000 )) +return -EBUSY ; + +/* Set port as Clause 22 */ + tmp =readl (priv->ioaddr +XGMAC_MDIO_C22P ); + tmp |=BIT (phyaddr);Since the registers are being Read/Modify/Write here, don't you need to clear the previous address bits as well?
You probably did not encounter any problems in your testing if you had only one PHY on the MDIO bus, but this is not something that is necessarily true, e.g: if you have an Ethernet switch, several MDIO bus addresses are going to be responding.
Quoted 6 lines
Your MDIO bus implementation must be able to support one transaction with one PHY address and the next transaction with another PHY address , etc...
That is something that should be easy to fix and be resubmitted as part of v4.
I'm not following you here... I only set/unset the bit for the corresponding phyaddr that phylib wants to read/write. Why would I clear the remaining addresses?
Thanks and Best Regards,
Jose Miguel Abreu
Re: [PATCH v3 net-next 5/9] net: stmmac: Add MDIO related functions for XGMAC2
Quoted 28 lines · Jose Abreu
Quoted 11 lines · Florian Fainelli
Quoted 10 lines · Jose Abreu
Add the MDIO related funcionalities for the new IP block XGMAC2.
Signed-off-by Jose Abreu <[email protected]>Cc David S. Miller <[email protected]>Cc Joao Pinto <[email protected]>Cc Giuseppe Cavallaro <[email protected]>Cc Alexandre Torgue <[email protected]>Cc Andrew Lunn <[email protected]>---
+satic int stmmac_xgmac2_c22_format(structstmmac_priv*priv, intphyaddr,
Quoted 9 lines
drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c line 58
Quoted 8 lines
drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c +8
-0+ int phyreg, u32 *hw_addr) +{ +unsigned int mii_data = priv->hw->mii.data; +u32 tmp; + +/* HW does not support C22 addr >= 4 */ +if (phyaddr >=4 ) +return -ENODEV ;It would be nice if this could be moved at probe time so you don't
have
Quoted 1 line
to wait until you connect to the PHY, read its PHY OUI and find out
it
Quoted 3 lines
has a MDIO address >= 4. Not a blocker, but something that could be improved further on.
Quoted 7 lines
Quoted 1 line
In premise you could even scan the MDIO bus' device tree node, and
find
Quoted 1 line
that out ahead of time.
Oh, but I use phylib ... I only provide the read/write callbacks so I think we should avoid duplicating the code that's already in the phylib ... No?
You can always extract the code that scans a MDIO bus into a helper function and make it parametrized with a callback of some kind. In that case I would be fine with you open coding the MDIO bus scan to find out if there is an address >= 4.
Quoted 26 lines
Quoted 11 lines
drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c line 66
Quoted 10 lines
drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c +8
-0+/* Wait until any existing MII operation is complete */ +if (readl_poll_timeout (priv->ioaddr + mii_data, tmp, + !(tmp &MII_XGMAC_BUSY ),100 ,10000 )) +return -EBUSY ; + +/* Set port as Clause 22 */ + tmp =readl (priv->ioaddr +XGMAC_MDIO_C22P ); + tmp |=BIT (phyaddr);Since the registers are being Read/Modify/Write here, don't you need
to
Quoted 3 lines
clear the previous address bits as well?
You probably did not encounter any problems in your testing if you
had
Quoted 2 lines
only one PHY on the MDIO bus, but this is not something that is necessarily true, e.g: if you have an Ethernet switch, several MDIO
bus
Quoted 4 lines
addresses are going to be responding.
Your MDIO bus implementation must be able to support one transaction with one PHY address and the next transaction with another PHY
address ,
Quoted 2 lines
etc...
Quoted 7 lines
Quoted 1 line
That is something that should be easy to fix and be resubmitted as
part
Quoted 1 line
of v4.
I'm not following you here... I only set/unset the bit for the corresponding phyaddr that phylib wants to read/write. Why would I clear the remaining addresses?
Because this is all about transactions, the HW must be in a state that it will be able to perform that transaction correctly. So here for instance if you needed to support a C45 transaction you would have to clear that bit for that particular PHY address. Since you don't appear to support those yet then yes the code appears fine though it would not hurt if you did clear all other PHY's c22 bits to make it clear what this does.
Signature · 1 line
Florian
Re: [PATCH v3 net-next 5/9] net: stmmac: Add MDIO related functions for XGMAC2
Hi Florian,
Quoted 29 lines · Florian Fainelli
Quoted 28 lines · Jose Abreu
Quoted 11 lines · Florian Fainelli
Quoted 10 lines · Jose Abreu
Add the MDIO related funcionalities for the new IP block XGMAC2.
Signed-off-by Jose Abreu <[email protected]>Cc David S. Miller <[email protected]>Cc Joao Pinto <[email protected]>Cc Giuseppe Cavallaro <[email protected]>Cc Alexandre Torgue <[email protected]>Cc Andrew Lunn <[email protected]>---
+satic int stmmac_xgmac2_c22_format(structstmmac_priv*priv, intphyaddr,
Quoted 9 lines
drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c line 58
Quoted 8 lines
drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c +8
-0+ int phyreg, u32 *hw_addr) +{ +unsigned int mii_data = priv->hw->mii.data; +u32 tmp; + +/* HW does not support C22 addr >= 4 */ +if (phyaddr >=4 ) +return -ENODEV ;It would be nice if this could be moved at probe time so you don't
have
Quoted 1 line
to wait until you connect to the PHY, read its PHY OUI and find out
it
Quoted 3 lines
has a MDIO address >= 4. Not a blocker, but something that could be improved further on.
Quoted 7 lines
Quoted 6 lines
Quoted 1 line
In premise you could even scan the MDIO bus' device tree node, and
find
Quoted 1 line
that out ahead of time.
Oh, but I use phylib ... I only provide the read/write callbacks so I think we should avoid duplicating the code that's already in the phylib ... No?
You can always extract the code that scans a MDIO bus into a helper function and make it parametrized with a callback of some kind. In that case I would be fine with you open coding the MDIO bus scan to find out if there is an address >= 4.
Sorry but I dont' think thats the best solution because of_mdiobus_register() already scans the bus. Duplicating this should be avoided, no?
Note all of this is probably never needed because stmmac just picks the first phy it finds, if phy_addr is not specified ...
Quoted 25 lines
Quoted 25 lines
Quoted 10 lines
drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c line 66
Quoted 9 lines
drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c +8
-0+/* Wait until any existing MII operation is complete */ +if (readl_poll_timeout (priv->ioaddr + mii_data, tmp, + !(tmp &MII_XGMAC_BUSY ),100 ,10000 )) +return -EBUSY ; + +/* Set port as Clause 22 */ + tmp =readl (priv->ioaddr +XGMAC_MDIO_C22P ); + tmp |=BIT (phyaddr);Since the registers are being Read/Modify/Write here, don't you need
to
Quoted 3 lines
clear the previous address bits as well?
You probably did not encounter any problems in your testing if you
had
Quoted 2 lines
only one PHY on the MDIO bus, but this is not something that is necessarily true, e.g: if you have an Ethernet switch, several MDIO
bus
Quoted 4 lines
addresses are going to be responding.
Your MDIO bus implementation must be able to support one transaction with one PHY address and the next transaction with another PHY
address ,
Quoted 2 lines
etc...
Quoted 7 lines
Quoted 6 lines
Quoted 1 line
That is something that should be easy to fix and be resubmitted as
part
Quoted 1 line
of v4.
I'm not following you here... I only set/unset the bit for the corresponding phyaddr that phylib wants to read/write. Why would I clear the remaining addresses?
Because this is all about transactions, the HW must be in a state that it will be able to perform that transaction correctly. So here for instance if you needed to support a C45 transaction you would have to clear that bit for that particular PHY address. Since you don't appear to support those yet then yes the code appears fine though it would not hurt if you did clear all other PHY's c22 bits to make it clear what this does.
I can't test C45 right now but I will in a near future. In that case then we will need to support C22 and C45 so I may want to only set one bit for a specific phy that only supports c22.
Thanks and Best Regards,
Jose Miguel Abreu
Quoted 1 line
Re: [PATCH v3 net-next 5/9] net: stmmac: Add MDIO related functions for XGMAC2
Quoted 33 lines · Jose Abreu
Hi Florian,
Quoted 30 lines · Florian Fainelli
Quoted 29 lines · Jose Abreu
Quoted 11 lines · Florian Fainelli
Quoted 10 lines · Jose Abreu
Add the MDIO related funcionalities for the new IP block XGMAC2.
Signed-off-by Jose Abreu <[email protected]>Cc David S. Miller <[email protected]>Cc Joao Pinto <[email protected]>Cc Giuseppe Cavallaro <[email protected]>Cc Alexandre Torgue <[email protected]>Cc Andrew Lunn <[email protected]>---
+satic int stmmac_xgmac2_c22_format(structstmmac_priv*priv, intphyaddr,
Quoted 9 lines
drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c line 58
Quoted 8 lines
drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c +8
-0+ int phyreg, u32 *hw_addr) +{ +unsigned int mii_data = priv->hw->mii.data; +u32 tmp; + +/* HW does not support C22 addr >= 4 */ +if (phyaddr >=4 ) +return -ENODEV ;It would be nice if this could be moved at probe time so you don't
have
Quoted 1 line
to wait until you connect to the PHY, read its PHY OUI and find out
it
Quoted 4 lines
has a MDIO address >= 4. Not a blocker, but something that could be improved further on.
In premise you could even scan the MDIO bus' device tree node, and
Quoted 8 lines
Quoted 6 lines
Quoted 5 lines
find
Quoted 1 line
that out ahead of time.
Oh, but I use phylib ... I only provide the read/write callbacks so I think we should avoid duplicating the code that's already in the phylib ... No?
You can always extract the code that scans a MDIO bus into a helper function and make it parametrized with a callback of some kind. In that case I would be fine with you open coding the MDIO bus scan to find out if there is an address >= 4.
Sorry but I dont' think thats the best solution because
of_mdiobus_register()already scans the bus.
My mistake. Its stmmac thats scanning the bus. See this:
359 for (addr = 0; addr < PHY_MAX_ADDR; addr++)
{
360 struct phy_device *phydev =mdiobus_get_phy(new_bus, addr);
361
362 if
(!phydev)
363
continue;
So, its just cycling through all possible phys (0..31) ... Do you think it would be okay if I just limit the cycle max to 4 for this xgmac2 for now ? I would maintain the if in the stmmac_xgmac2_c22_format though, as safe-guard.
Thanks and Best Regards,
Jose Miguel Abreu
Quoted 44 lines
Duplicating this
should be avoided, no?Note all of this is probably never needed because stmmac just picks the first phy it finds, if
phy_addris not specified ...Quoted 24 lines
Quoted 24 lines
Quoted 9 lines
drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c line 66
Quoted 8 lines
drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c +8
-0+/* Wait until any existing MII operation is complete */ +if (readl_poll_timeout (priv->ioaddr + mii_data, tmp, + !(tmp &MII_XGMAC_BUSY ),100 ,10000 )) +return -EBUSY ; + +/* Set port as Clause 22 */ + tmp =readl (priv->ioaddr +XGMAC_MDIO_C22P ); + tmp |=BIT (phyaddr);Since the registers are being Read/Modify/Write here, don't you need
to
Quoted 3 lines
clear the previous address bits as well?
You probably did not encounter any problems in your testing if you
had
Quoted 2 lines
only one PHY on the MDIO bus, but this is not something that is necessarily true, e.g: if you have an Ethernet switch, several MDIO
bus
Quoted 4 lines
addresses are going to be responding.
Your MDIO bus implementation must be able to support one transaction with one PHY address and the next transaction with another PHY
address ,
Quoted 2 lines
etc...
Quoted 7 lines
Quoted 6 lines
Quoted 1 line
That is something that should be easy to fix and be resubmitted as
part
Quoted 1 line
of v4.
I'm not following you here... I only set/unset the bit for the corresponding phyaddr that phylib wants to read/write. Why would I clear the remaining addresses?
Because this is all about transactions, the HW must be in a state that it will be able to perform that transaction correctly. So here for instance if you needed to support a C45 transaction you would have to clear that bit for that particular PHY address. Since you don't appear to support those yet then yes the code appears fine though it would not hurt if you did clear all other PHY's c22 bits to make it clear what this does.
I can't test C45 right now but I will in a near future. In that case then we will need to support C22 and C45 so I may want to only set one bit for a specific phy that only supports c22.
Thanks and Best Regards,
Jose Miguel Abreu
Re: [PATCH v3 net-next 5/9] net: stmmac: Add MDIO related functions for XGMAC2
In reply to Jose AbreuQuoted 35 lines · Jose Abreu
Hi Florian,
Quoted 32 lines · Florian Fainelli
Quoted 31 lines · Jose Abreu
Quoted 11 lines · Florian Fainelli
Quoted 10 lines · Jose Abreu
Add the MDIO related funcionalities for the new IP block XGMAC2.
Signed-off-by Jose Abreu <[email protected]>Cc David S. Miller <[email protected]>Cc Joao Pinto <[email protected]>Cc Giuseppe Cavallaro <[email protected]>Cc Alexandre Torgue <[email protected]>Cc Andrew Lunn <[email protected]>---
+satic int stmmac_xgmac2_c22_format(structstmmac_priv*priv, intphyaddr,
Quoted 9 lines
drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c line 58
Quoted 8 lines
drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c +8
-0+ int phyreg, u32 *hw_addr) +{ +unsigned int mii_data = priv->hw->mii.data; +u32 tmp; + +/* HW does not support C22 addr >= 4 */ +if (phyaddr >=4 ) +return -ENODEV ;It would be nice if this could be moved at probe time so you don't
have
Quoted 1 line
to wait until you connect to the PHY, read its PHY OUI and find out
it
Quoted 4 lines
has a MDIO address >= 4. Not a blocker, but something that could be improved further on.
In premise you could even scan the MDIO bus' device tree node, and
find
Quoted 1 line
that out ahead of time.
Quoted 8 lines
Quoted 4 lines
Quoted 3 lines
Oh, but I use phylib ... I only provide the read/write callbacks so I think we should avoid duplicating the code that's already in the phylib ... No?
You can always extract the code that scans a MDIO bus into a helper function and make it parametrized with a callback of some kind. In that case I would be fine with you open coding the MDIO bus scan to find out if there is an address >= 4.
Sorry but I dont' think thats the best solution because
of_mdiobus_register()already scans the bus. Duplicating this should be avoided, no?
I suggested you extract the code into a helper to avoid the duplication.
Quoted 3 lines
Note all of this is probably never needed because stmmac just picks the first phy it finds, if
phy_addris not specified ...
No, it's much more involved than that, there are several modes in which MDIO on stmmac can be instantiated:
- platform data instantiation, which uses a loop and finds the first available address
- Device Tree which will scan the MDIO bus' node child nodes and create PHYs for valid nodes
It feels a bit late to check for PHY address >= 4 during the first read, because it won't be obvious to somehow why this fails, but if that fulfills your needs, keep it that way.
Quoted 29 lines
Quoted 29 lines
Quoted 29 lines
Quoted 11 lines
drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c line 66
Quoted 10 lines
drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c +8
-0+/* Wait until any existing MII operation is complete */ +if (readl_poll_timeout (priv->ioaddr + mii_data, tmp, + !(tmp &MII_XGMAC_BUSY ),100 ,10000 )) +return -EBUSY ; + +/* Set port as Clause 22 */ + tmp =readl (priv->ioaddr +XGMAC_MDIO_C22P ); + tmp |=BIT (phyaddr);Since the registers are being Read/Modify/Write here, don't you need
to
Quoted 3 lines
clear the previous address bits as well?
You probably did not encounter any problems in your testing if you
had
Quoted 2 lines
only one PHY on the MDIO bus, but this is not something that is necessarily true, e.g: if you have an Ethernet switch, several MDIO
bus
Quoted 4 lines
addresses are going to be responding.
Your MDIO bus implementation must be able to support one transaction with one PHY address and the next transaction with another PHY
address ,
Quoted 3 lines
etc...
That is something that should be easy to fix and be resubmitted as
part
Quoted 1 line
of v4.
Quoted 8 lines
Quoted 4 lines
Quoted 3 lines
I'm not following you here... I only set/unset the bit for the corresponding phyaddr that phylib wants to read/write. Why would I clear the remaining addresses?
Because this is all about transactions, the HW must be in a state that it will be able to perform that transaction correctly. So here for instance if you needed to support a C45 transaction you would have to clear that bit for that particular PHY address. Since you don't appear to support those yet then yes the code appears fine though it would not hurt if you did clear all other PHY's c22 bits to make it clear what this does.
I can't test C45 right now but I will in a near future. In that case then we will need to support C22 and C45 so I may want to only set one bit for a specific phy that only supports c22.
We are really talking about adding something like:
reg &= ~(MASK);
before setting the bit, anyhow, if you want to do that later on when you add C45 support, be my guest...
Signature · 1 line
Florian
PATCH v3 6/9 net: stmmac: Add PTP support for XGMAC2
In reply to Jose AbreuXGMAC2 uses the same engine of timestamping as GMAC4. Let's use the same callbacks.
--- drivers/net/ethernet/stmicro/stmmac/hwif.c | 4 ++-- drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c | 6 ++++-- drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.h | 1 + 3 files changed, 7 insertions(+), 4 deletions(-)
drivers/net/ethernet/stmicro/stmmac/hwif.c +2 -2
@@ -193,13 +193,13 @@ static const struct stmmac_hwif_entry { .xgmac = true, .min_id = DWXGMAC_CORE_2_10, .regs = { - .ptp_off = 0, + .ptp_off = PTP_XGMAC_OFFSET, .mmc_off = 0, }, .desc = &dwxgmac210_desc_ops, .dma = &dwxgmac210_dma_ops, .mac = &dwxgmac210_ops, - .hwtimestamp = NULL, + .hwtimestamp = &stmmac_ptp, .mode = NULL, .tc = NULL, .setup = dwxgmac2_setup,
drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c +4 -2
@@ -71,6 +71,9 @@ static int stmmac_adjust_time(struct ptp_clock_info *ptp, s64 delta)u32 sec, nsec;u32 quotient, reminder;int neg_adj =0 ; +bool xmac; + + xmac = priv->plat->has_gmac4 || priv->plat->has_xgmac;if (delta <0 ) { neg_adj =1 ;
@@ -82,8 +85,7 @@ static int stmmac_adjust_time(struct ptp_clock_info *ptp, s64 delta) nsec = reminder;spin_lock_irqsave (&priv->ptp_lock, flags); -stmmac_adjust_systime (priv, priv->ptpaddr, sec, nsec, neg_adj, - priv->plat->has_gmac4); +stmmac_adjust_systime (priv, priv->ptpaddr, sec, nsec, neg_adj, xmac);spin_unlock_irqrestore (&priv->ptp_lock, flags);return 0 ;
drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.h +1 -0
@@ -21,6 +21,7 @@#ifndef __STMMAC_PTP_H__#define __STMMAC_PTP_H__ +#define PTP_XGMAC_OFFSET 0xd00#define PTP_GMAC4_OFFSET 0xb00#define PTP_GMAC3_X_OFFSET 0x700
Signature · 1 line
2.7.4
PATCH v3 7/9 net: stmmac: Integrate XGMAC into main driver flow
In reply to Jose AbreuNow that we have all the XGMAC related callbacks, lets start integrating this IP block into main driver.
Also, we corrected the initialization flow to only start DMA after setting descriptors length.
---
Changes from v1:
- Correct flow of initialization
- Remove 2.5G/10G support (Andrew)
--- drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 67 ++++++++++++++++------- 1 file changed, 48 insertions(+), 19 deletions(-)
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +48 -19
@@ -51,6 +51,7 @@#include <linux/reset.h> #include <linux/of_mdio.h> #include "dwmac1000.h" +#include "dwxgmac2.h" #include "hwif.h" #define STMMAC_ALIGN (x) __ALIGN_KERNEL(x, SMP_CACHE_BYTES)
@@ -262,6 +263,21 @@ static void stmmac_clk_csr_set(struct stmmac_priv *priv)else priv->clk_csr =0 ; } + +if (priv->plat->has_xgmac) { +if (clk_rate >400000000 ) + priv->clk_csr =0x5 ; +else if (clk_rate >350000000 ) + priv->clk_csr =0x4 ; +else if (clk_rate >300000000 ) + priv->clk_csr =0x3 ; +else if (clk_rate >250000000 ) + priv->clk_csr =0x2 ; +else if (clk_rate >150000000 ) + priv->clk_csr =0x1 ; +else + priv->clk_csr =0x0 ; + } }static void print_pkt (unsigned char *buf,int len)
@@ -498,7 +514,7 @@ static void stmmac_get_rx_hwtstamp(struct stmmac_priv *priv, struct dma_desc *p,if (!priv->hwts_rx_en)return ;/* For GMAC4, the valid timestamp is from CTX next desc. */ -if (priv->plat->has_gmac4) +if (priv->plat->has_gmac4 || priv->plat->has_xgmac) desc = np;/* Check if timestamp is available */
@@ -540,6 +556,9 @@ static int stmmac_hwtstamp_ioctl(struct net_device *dev, struct ifreq *ifr)u32 ts_event_en =0 ;u32 value =0 ;u32 sec_inc; +bool xmac; + + xmac = priv->plat->has_gmac4 || priv->plat->has_xgmac;if (!(priv->dma_cap.time_stamp || priv->adv_ts)) {netdev_alert (priv->dev,"No support for HW time stamping\n" );
@@ -575,7 +594,7 @@ static int stmmac_hwtstamp_ioctl(struct net_device *dev, struct ifreq *ifr)/* PTP v1, UDP, any kind of event packet */ config.rx_filter =HWTSTAMP_FILTER_PTP_V1_L4_EVENT ;/* take time stamp for all event messages */ -if (priv->plat->has_gmac4) +if (xmac) snap_type_sel =PTP_GMAC4_TCR_SNAPTYPSEL_1 ;else snap_type_sel =PTP_TCR_SNAPTYPSEL_1 ;
@@ -610,7 +629,7 @@ static int stmmac_hwtstamp_ioctl(struct net_device *dev, struct ifreq *ifr) config.rx_filter =HWTSTAMP_FILTER_PTP_V2_L4_EVENT ; ptp_v2 =PTP_TCR_TSVER2ENA ;/* take time stamp for all event messages */ -if (priv->plat->has_gmac4) +if (xmac) snap_type_sel =PTP_GMAC4_TCR_SNAPTYPSEL_1 ;else snap_type_sel =PTP_TCR_SNAPTYPSEL_1 ;
@@ -647,7 +666,7 @@ static int stmmac_hwtstamp_ioctl(struct net_device *dev, struct ifreq *ifr) config.rx_filter =HWTSTAMP_FILTER_PTP_V2_EVENT ; ptp_v2 =PTP_TCR_TSVER2ENA ;/* take time stamp for all event messages */ -if (priv->plat->has_gmac4) +if (xmac) snap_type_sel =PTP_GMAC4_TCR_SNAPTYPSEL_1 ;else snap_type_sel =PTP_TCR_SNAPTYPSEL_1 ;
@@ -718,7 +737,7 @@ static int stmmac_hwtstamp_ioctl(struct net_device *dev, struct ifreq *ifr)/* program Sub Second Increment reg */ stmmac_config_sub_second_increment (priv, priv->ptpaddr, priv->plat->clk_ptp_rate, - priv->plat->has_gmac4, &sec_inc); + xmac, &sec_inc); temp =div_u64 (1000000000ULL , sec_inc);/* Store sub second increment and flags for later use */
@@ -755,12 +774,14 @@ static int stmmac_hwtstamp_ioctl(struct net_device *dev, struct ifreq *ifr)*/ static int stmmac_init_ptp (struct stmmac_priv *priv) { +bool xmac = priv->plat->has_gmac4 || priv->plat->has_xgmac; +if (!(priv->dma_cap.time_stamp || priv->dma_cap.atime_stamp))return -EOPNOTSUPP ; priv->adv_ts =0 ; -/* Check if adv_ts can be enabled for dwmac 4.x core */ -if (priv->plat->has_gmac4 && priv->dma_cap.atime_stamp) +/* Check if adv_ts can be enabled for dwmac 4.x / xgmac core */ +if (xmac && priv->dma_cap.atime_stamp) priv->adv_ts =1 ;/* Dwmac 3.x core with extend_desc can support adv_ts */ else if (priv->extend_desc && priv->dma_cap.atime_stamp)
@@ -2173,6 +2194,12 @@ static int stmmac_init_dma_engine(struct stmmac_priv *priv)return ret; } +/* DMA Configuration */ +stmmac_dma_init (priv, priv->ioaddr, priv->plat->dma_cfg, atds); + +if (priv->plat->axi) +stmmac_axi (priv, priv->ioaddr, priv->plat->axi); +/* DMA RX Channel Configuration */ for (chan =0 ; chan < rx_channels_count; chan++) { rx_q = &priv->rx_queue[chan];
@@ -2203,12 +2230,6 @@ static int stmmac_init_dma_engine(struct stmmac_priv *priv)for (chan =0 ; chan < dma_csr_ch; chan++)stmmac_init_chan (priv, priv->ioaddr, priv->plat->dma_cfg, chan); -/* DMA Configuration */ -stmmac_dma_init (priv, priv->ioaddr, priv->plat->dma_cfg, atds); - -if (priv->plat->axi) -stmmac_axi (priv, priv->ioaddr, priv->plat->axi); -return ret; }
@@ -2526,9 +2547,6 @@ static int stmmac_hw_setup(struct net_device *dev, bool init_ptp)netdev_warn (priv->dev,"%s: failed debugFS registration\n" , __func__);#endif -/* Start the ball rolling... */ -stmmac_start_all_dma (priv); - priv->tx_lpi_timer =STMMAC_DEFAULT_TWT_LS ;if (priv->use_riwt) {
@@ -2549,6 +2567,9 @@ static int stmmac_hw_setup(struct net_device *dev, bool init_ptp)stmmac_enable_tso (priv, priv->ioaddr,1 , chan); } +/* Start the ball rolling... */ +stmmac_start_all_dma (priv); +return 0 ; }
@@ -3305,6 +3326,9 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit, u32 queue)int coe = priv->hw->rx_csum;unsigned int next_entry;unsigned int count =0 ; +bool xmac; + + xmac = priv->plat->has_gmac4 || priv->plat->has_xgmac;if (netif_msg_rx_status (priv)) {void *rx_head;
@@ -3406,7 +3430,7 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit, u32 queue)* in case of GMAC4 because it needs * to refill the used descriptors, always. */ -if (unlikely (!priv->plat->has_gmac4 && +if (unlikely (!xmac && ((frame_len < priv->rx_copybreak) ||stmmac_rx_threshold_count (rx_q)))) { skb = netdev_alloc_skb_ip_align(priv->dev,
@@ -3642,7 +3666,9 @@ static irqreturn_t stmmac_interrupt(int irq, void *dev_id)u32 tx_cnt = priv->plat->tx_queues_to_use;u32 queues_count;u32 queue; +bool xmac; + xmac = priv->plat->has_gmac4 || priv->plat->has_xgmac; queues_count = (rx_cnt > tx_cnt) ? rx_cnt : tx_cnt;if (priv->irq_wake)
@@ -3661,7 +3687,7 @@ static irqreturn_t stmmac_interrupt(int irq, void *dev_id)return IRQ_HANDLED ;/* To handle GMAC own interrupts */ -if ((priv->plat->has_gmac) || (priv->plat->has_gmac4)) { +if ((priv->plat->has_gmac) || xmac) {int status =stmmac_host_irq_status (priv, priv->hw, &priv->xstats);int mtl_status;
@@ -4269,6 +4295,8 @@ int stmmac_dvr_probe(struct device *device, ndev->min_mtu =ETH_ZLEN -ETH_HLEN ;if ((priv->plat->enh_desc) || (priv->synopsys_id >=DWMAC_CORE_4_00 )) ndev->max_mtu =JUMBO_LEN ; +else if (priv->plat->has_xgmac) + ndev->max_mtu =XGMAC_JUMBO_LEN ;else ndev->max_mtu =SKB_MAX_HEAD (NET_SKB_PAD +NET_IP_ALIGN );/* Will not overwrite ndev->max_mtu if plat->maxmtu > ndev->max_mtu
@@ -4290,7 +4318,8 @@ int stmmac_dvr_probe(struct device *device,* 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 ) && (!priv->plat->riwt_off)) { +if (((priv->synopsys_id >=DWMAC_CORE_3_50 ) || + (priv->plat->has_xgmac)) && (!priv->plat->riwt_off)) { priv->use_riwt =1 ;dev_info (priv->device,"Enable RX Mitigation via HW Watchdog Timer\n" );
Signature · 1 line
2.7.4
PATCH v3 8/9 net: stmmac: Add the bindings parsing for XGMAC2
In reply to Jose AbreuAdd the bindings parsing for XGMAC2 IP block.
--- drivers/net/ethernet/stmicro/stmmac/dwmac-generic.c | 2 ++ drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c | 6 ++++++ 2 files changed, 8 insertions(+)
drivers/net/ethernet/stmicro/stmmac/dwmac-generic.c +2 -0
@@ -78,6 +78,8 @@ static const struct of_device_id dwmac_generic_match[] = { { .compatible = "snps,dwmac-4.00"}, { .compatible = "snps,dwmac-4.10a"}, { .compatible = "snps,dwmac"}, + { .compatible = "snps,dwxgmac-2.10"}, + { .compatible = "snps,dwxgmac"}, { } };MODULE_DEVICE_TABLE (of, dwmac_generic_match);
drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c +6 -0
@@ -486,6 +486,12 @@ stmmac_probe_config_dt(struct platform_device *pdev, const char **mac) plat->force_sf_dma_mode =1 ; } +if (of_device_is_compatible (np,"snps,dwxgmac" )) { + plat->has_xgmac =1 ; + plat->pmt =1 ; + plat->tso_en =of_property_read_bool (np,"snps,tso" ); + } + dma_cfg =devm_kzalloc (&pdev->dev,sizeof (*dma_cfg),GFP_KERNEL );if (!dma_cfg) {
Signature · 1 line
2.7.4
PATCH v3 9/9 dt-bindings: net: stmmac: Add the bindings documentation for XGMAC2.
In reply to Jose AbreuAdds the documentation for XGMAC2 DT bindings.
---
Changes from v1:
- Correct header, now we also support 2.5/10G.
- Add missing '>' (Sergei)
--- Documentation/devicetree/bindings/net/stmmac.txt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
Documentation/devicetree/bindings/net/stmmac.txt +3 -2
@@ -1,7 +1,8 @@ -* STMicroelectronics 10/100/1000 Ethernet driver (GMAC) +* STMicroelectronics 10/100/1000/2500/10000 Ethernet driver (GMAC/XGMAC) Required properties: -- compatible: Should be "snps,dwmac-<ip_version>", "snps,dwmac" +- compatible: Should be "snps,dwmac-<ip_version>", "snps,dwmac" or + "snps,dwxgmac-<ip_version>", "snps,dwxgmac". For backwards compatibility: "st,spear600-gmac" is also supported. - reg: Address and length of the register set for the device - interrupt-parent: Should be the phandle for the interrupt controller
Signature · 1 line
2.7.4
Rob Herring
maintainerRe: [PATCH v3 net-next 9/9] dt-bindings: net: stmmac: Add the bindings documentation for XGMAC2.
Quoted 23 lines · Jose Abreu
Adds the documentation for XGMAC2 DT bindings.
Signed-off-by Jose Abreu <[email protected]>Cc David S. Miller <[email protected]>Cc Joao Pinto <[email protected]>Cc Giuseppe Cavallaro <[email protected]>Cc Alexandre Torgue <[email protected]>Cc Sergei Shtylyov <[email protected]>Cc Rob Herring <[email protected]>---
Changes from v1:
- Correct header, now we also support 2.5/10G.
- Add missing '>' (Sergei)--- Documentation/devicetree/bindings/net/stmmac.txt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)Documentation/devicetree/bindings/net/stmmac.txt +0
-0
Documentation/devicetree/bindings/net/stmmac.txt line 1
Quoted 2 lines
Documentation/devicetree/bindings/net/stmmac.txt +1
-1@@ -1,7 +1,8 @@ -* STMicroelectronics 10/100/1000 Ethernet driver (GMAC) +* STMicroelectronics 10/100/1000/2500/10000 Ethernet driver (GMAC/XGMAC)
Bindings don't describe drivers.
Quoted 12 lines
Documentation/devicetree/bindings/net/stmmac.txt +2
-1Required properties: -- compatible: Should be "snps,dwmac-<ip_version>", "snps,dwmac" +- compatible: Should be "snps,dwmac-<ip_version>", "snps,dwmac" or + "snps,dwxgmac-<ip_version>", "snps,dwxgmac". For backwards compatibility: "st,spear600-gmac" is also supported. - reg: Address and length of the register set for the device - interrupt-parent: Should be the phandle for the interrupt controllerSignature · 1 line
2.7.4