[PATCH v2 0/6] add support for sama7g5 ethernet interfaces

Hi,
This series add support for SAMA7G5 ethernet interfaces: one gigabit interface and one 10/100Mbps interface.
Thank you, Claudiu Beznea
Changes in v2: - fix compilation error on patch 6/6 for wb50n_defconfig
Claudiu Beznea (6): net: macb: use dummy descriptor for RBQP net: macb: add user io config data structure net: macb: check clk_set_rate return value to be negative net: macb: add support for sama7g5 gmac net: macb: add support for sama7g5 emac net: macb: take into account all RGMII interface types
drivers/net/macb.c | 101 +++++++++++++++++++++++++++++++++++++++++++++-------- drivers/net/macb.h | 2 ++ 2 files changed, 89 insertions(+), 14 deletions(-)

In case of multiple queues on RX side the queue scheduler will try to use all the available configured queues (with descriptors having TX_USED bit cleared). If at least one RBQP points to a descriptor with a valid used bit configuration then the reception may block as this may point to any memory. To avoid this scenario all the queues (except queue zero) were disabled by setting DMA descriptors with used bit set on proper RBQP. The driver anyway uses only queue 0 for TX/RX.
Signed-off-by: Claudiu Beznea claudiu.beznea@microchip.com --- drivers/net/macb.c | 4 +++- drivers/net/macb.h | 2 ++ 2 files changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/net/macb.c b/drivers/net/macb.c index b80a259ff757..836eb85ec96a 100644 --- a/drivers/net/macb.c +++ b/drivers/net/macb.c @@ -732,8 +732,10 @@ static int gmac_init_multi_queues(struct macb_device *macb) flush_dcache_range(macb->dummy_desc_dma, macb->dummy_desc_dma + ALIGN(MACB_TX_DUMMY_DMA_DESC_SIZE, PKTALIGN));
- for (i = 1; i < num_queues; i++) + for (i = 1; i < num_queues; i++) { gem_writel_queue_TBQP(macb, macb->dummy_desc_dma, i - 1); + gem_writel_queue_RBQP(macb, macb->dummy_desc_dma, i - 1); + }
return 0; } diff --git a/drivers/net/macb.h b/drivers/net/macb.h index 9b16383eba46..28c7fe306883 100644 --- a/drivers/net/macb.h +++ b/drivers/net/macb.h @@ -768,5 +768,7 @@ #define GEM_RX_CSUM_CHECKED_MASK 2 #define gem_writel_queue_TBQP(port, value, queue_num) \ writel((value), (port)->regs + GEM_TBQP(queue_num)) +#define gem_writel_queue_RBQP(port, value, queue_num) \ + writel((value), (port)->regs + GEM_RBQP(queue_num))
#endif /* __DRIVERS_MACB_H__ */

Different implementation of USER IO register needs different mapping for bit fields of this register. Add implementation for this and, since clken is part of USER IO and it needs to be activated based on per SoC capabilities, add caps in macb_config where clken specific information needs to be filled.
Signed-off-by: Claudiu Beznea claudiu.beznea@microchip.com --- drivers/net/macb.c | 52 ++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 40 insertions(+), 12 deletions(-)
diff --git a/drivers/net/macb.c b/drivers/net/macb.c index 836eb85ec96a..049ade6a7470 100644 --- a/drivers/net/macb.c +++ b/drivers/net/macb.c @@ -135,10 +135,19 @@ struct macb_device { #endif };
+struct macb_usrio_cfg { + unsigned int mii; + unsigned int rmii; + unsigned int rgmii; + unsigned int clken; +}; + struct macb_config { unsigned int dma_burst_length; + unsigned int caps;
int (*clk_init)(struct udevice *dev, ulong rate); + const struct macb_usrio_cfg *usrio; };
#ifndef CONFIG_DM_ETH @@ -773,6 +782,7 @@ static int _macb_init(struct macb_device *macb, const char *name) { #ifdef CONFIG_DM_ETH struct macb_device *macb = dev_get_priv(dev); + unsigned int val = 0; #endif unsigned long paddr; int ret; @@ -830,11 +840,17 @@ static int _macb_init(struct macb_device *macb, const char *name) * to select interface between RMII and MII. */ #ifdef CONFIG_DM_ETH - if ((macb->phy_interface == PHY_INTERFACE_MODE_RMII) || - (macb->phy_interface == PHY_INTERFACE_MODE_RGMII)) - gem_writel(macb, USRIO, GEM_BIT(RGMII)); - else - gem_writel(macb, USRIO, 0); + if (macb->phy_interface == PHY_INTERFACE_MODE_RGMII) + val = macb->config->usrio->rgmii; + else if (macb->phy_interface == PHY_INTERFACE_MODE_RMII) + val = macb->config->usrio->rmii; + else if (macb->phy_interface == PHY_INTERFACE_MODE_MII) + val = macb->config->usrio->mii; + + if (macb->config->caps & MACB_CAPS_USRIO_HAS_CLKEN) + val |= macb->config->usrio->clken; + + gem_writel(macb, USRIO, val);
if (macb->phy_interface == PHY_INTERFACE_MODE_SGMII) { unsigned int ncfgr = macb_readl(macb, NCFGR); @@ -844,7 +860,7 @@ static int _macb_init(struct macb_device *macb, const char *name) } #else #if defined(CONFIG_RGMII) || defined(CONFIG_RMII) - gem_writel(macb, USRIO, GEM_BIT(RGMII)); + gem_writel(macb, USRIO, macb->config->usrio->rgmii); #else gem_writel(macb, USRIO, 0); #endif @@ -855,28 +871,30 @@ static int _macb_init(struct macb_device *macb, const char *name) #ifdef CONFIG_AT91FAMILY if (macb->phy_interface == PHY_INTERFACE_MODE_RMII) { macb_writel(macb, USRIO, - MACB_BIT(RMII) | MACB_BIT(CLKEN)); + macb->config->usrio->rmii | + macb->config->usrio->clken); } else { - macb_writel(macb, USRIO, MACB_BIT(CLKEN)); + macb_writel(macb, USRIO, macb->config->usrio->clken); } #else if (macb->phy_interface == PHY_INTERFACE_MODE_RMII) macb_writel(macb, USRIO, 0); else - macb_writel(macb, USRIO, MACB_BIT(MII)); + macb_writel(macb, USRIO, macb->config->usrio->mii); #endif #else #ifdef CONFIG_RMII #ifdef CONFIG_AT91FAMILY - macb_writel(macb, USRIO, MACB_BIT(RMII) | MACB_BIT(CLKEN)); + macb_writel(macb, USRIO, macb->config->usrio->rmii | + macb->config->usrio->clken); #else macb_writel(macb, USRIO, 0); #endif #else #ifdef CONFIG_AT91FAMILY - macb_writel(macb, USRIO, MACB_BIT(CLKEN)); + macb_writel(macb, USRIO, macb->config->usrio->clken); #else - macb_writel(macb, USRIO, MACB_BIT(MII)); + macb_writel(macb, USRIO, macb->config->usrio->mii); #endif #endif /* CONFIG_RMII */ #endif @@ -1217,9 +1235,17 @@ static int macb_enable_clk(struct udevice *dev) } #endif
+static const struct macb_usrio_cfg macb_default_usrio = { + .mii = MACB_BIT(MII), + .rmii = MACB_BIT(RMII), + .rgmii = GEM_BIT(RGMII), + .clken = MACB_BIT(CLKEN), +}; + static const struct macb_config default_gem_config = { .dma_burst_length = 16, .clk_init = NULL, + .usrio = &macb_default_usrio, };
static int macb_eth_probe(struct udevice *dev) @@ -1309,11 +1335,13 @@ static int macb_eth_ofdata_to_platdata(struct udevice *dev) static const struct macb_config sama5d4_config = { .dma_burst_length = 4, .clk_init = NULL, + .usrio = &macb_default_usrio, };
static const struct macb_config sifive_config = { .dma_burst_length = 16, .clk_init = macb_sifive_clk_init, + .usrio = &macb_default_usrio, };
static const struct udevice_id macb_eth_ids[] = {

clk_set_rate() returns the set rate in case of success and a negative number in case of failure. Consider failure only the negative numbers.
Fixes: 3ef64444de157 ("dm: net: macb: Implement link speed change callback") Signed-off-by: Claudiu Beznea claudiu.beznea@microchip.com --- drivers/net/macb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/macb.c b/drivers/net/macb.c index 049ade6a7470..241b42a6e9d3 100644 --- a/drivers/net/macb.c +++ b/drivers/net/macb.c @@ -564,7 +564,7 @@ int __weak macb_linkspd_cb(struct udevice *dev, unsigned int speed)
if (tx_clk.dev) { ret = clk_set_rate(&tx_clk, rate); - if (ret) + if (ret < 0) return ret; } #endif

Add support for SAMA7G5 GMAC.
Signed-off-by: Claudiu Beznea claudiu.beznea@microchip.com --- drivers/net/macb.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+)
diff --git a/drivers/net/macb.c b/drivers/net/macb.c index 241b42a6e9d3..234d85a94d34 100644 --- a/drivers/net/macb.c +++ b/drivers/net/macb.c @@ -528,6 +528,23 @@ static int macb_sifive_clk_init(struct udevice *dev, ulong rate) return 0; }
+static int macb_sama7g5_clk_init(struct udevice *dev, ulong rate) +{ + struct clk clk; + int ret; + + ret = clk_get_by_name(dev, "tx_clk", &clk); + if (ret) + return ret; + + /* + * This is for using GCK. Clock rate is addressed via assigned-clock + * property, so only clock enable is needed here. The switching to + * proper clock rate depending on link speed is managed by IP logic. + */ + return clk_enable(&clk); +} + int __weak macb_linkspd_cb(struct udevice *dev, unsigned int speed) { #ifdef CONFIG_CLK @@ -1332,6 +1349,13 @@ static int macb_eth_ofdata_to_platdata(struct udevice *dev) return macb_late_eth_ofdata_to_platdata(dev); }
+static const struct macb_usrio_cfg sama7g5_usrio = { + .mii = 0, + .rmii = 1, + .rgmii = 2, + .clken = BIT(2), +}; + static const struct macb_config sama5d4_config = { .dma_burst_length = 4, .clk_init = NULL, @@ -1344,10 +1368,18 @@ static const struct macb_config sifive_config = { .usrio = &macb_default_usrio, };
+static const struct macb_config sama7g5_gmac_config = { + .dma_burst_length = 16, + .clk_init = macb_sama7g5_clk_init, + .usrio = &sama7g5_usrio, +}; + static const struct udevice_id macb_eth_ids[] = { { .compatible = "cdns,macb" }, { .compatible = "cdns,at91sam9260-macb" }, { .compatible = "cdns,sam9x60-macb" }, + { .compatible = "cdns,sama7g5-gem", + .data = (ulong)&sama7g5_gmac_config }, { .compatible = "atmel,sama5d2-gem" }, { .compatible = "atmel,sama5d3-gem" }, { .compatible = "atmel,sama5d4-gem", .data = (ulong)&sama5d4_config },

Add support for SAMA7G5 EMAC.
Signed-off-by: Claudiu Beznea claudiu.beznea@microchip.com --- drivers/net/macb.c | 8 ++++++++ 1 file changed, 8 insertions(+)
diff --git a/drivers/net/macb.c b/drivers/net/macb.c index 234d85a94d34..827f34bb172d 100644 --- a/drivers/net/macb.c +++ b/drivers/net/macb.c @@ -1374,12 +1374,20 @@ static const struct macb_config sama7g5_gmac_config = { .usrio = &sama7g5_usrio, };
+static const struct macb_config sama7g5_emac_config = { + .caps = MACB_CAPS_USRIO_HAS_CLKEN, + .dma_burst_length = 16, + .usrio = &sama7g5_usrio, +}; + static const struct udevice_id macb_eth_ids[] = { { .compatible = "cdns,macb" }, { .compatible = "cdns,at91sam9260-macb" }, { .compatible = "cdns,sam9x60-macb" }, { .compatible = "cdns,sama7g5-gem", .data = (ulong)&sama7g5_gmac_config }, + { .compatible = "cdns,sama7g5-emac", + .data = (ulong)&sama7g5_emac_config }, { .compatible = "atmel,sama5d2-gem" }, { .compatible = "atmel,sama5d3-gem" }, { .compatible = "atmel,sama5d4-gem", .data = (ulong)&sama5d4_config },

Take into account all RGMII interface types. Depending on it the RGMII PHY's timings are setup.
Signed-off-by: Claudiu Beznea claudiu.beznea@microchip.com --- drivers/net/macb.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/net/macb.c b/drivers/net/macb.c index 827f34bb172d..fe299af4d5d3 100644 --- a/drivers/net/macb.c +++ b/drivers/net/macb.c @@ -857,7 +857,10 @@ static int _macb_init(struct macb_device *macb, const char *name) * to select interface between RMII and MII. */ #ifdef CONFIG_DM_ETH - if (macb->phy_interface == PHY_INTERFACE_MODE_RGMII) + if (macb->phy_interface == PHY_INTERFACE_MODE_RGMII || + macb->phy_interface == PHY_INTERFACE_MODE_RGMII_ID || + macb->phy_interface == PHY_INTERFACE_MODE_RGMII_RXID || + macb->phy_interface == PHY_INTERFACE_MODE_RGMII_TXID) val = macb->config->usrio->rgmii; else if (macb->phy_interface == PHY_INTERFACE_MODE_RMII) val = macb->config->usrio->rmii;

On 03.12.2020 15:59, Claudiu Beznea wrote:
Hi,
This series add support for SAMA7G5 ethernet interfaces: one gigabit interface and one 10/100Mbps interface.
Thank you, Claudiu Beznea
Changes in v2:
- fix compilation error on patch 6/6 for wb50n_defconfig
Claudiu Beznea (6): net: macb: use dummy descriptor for RBQP net: macb: add user io config data structure net: macb: check clk_set_rate return value to be negative net: macb: add support for sama7g5 gmac net: macb: add support for sama7g5 emac net: macb: take into account all RGMII interface types
drivers/net/macb.c | 101 +++++++++++++++++++++++++++++++++++++++++++++-------- drivers/net/macb.h | 2 ++ 2 files changed, 89 insertions(+), 14 deletions(-)
Hi Claudiu,
Can you please rebase this series on u-boot/master ? The series for macb by Padmarao was applied yesterday.
Thanks ! Eugen
participants (2)
-
Claudiu Beznea
-
Eugen.Hristev@microchip.com