Merge branch 'net-macb-eyeq5-support'

says:

====================
net: macb: EyeQ5 support

This series' goal is adding support to the MACB driver for EyeQ5 GEM.
The specifics for this compatible are:

 - HW cannot add dummy bytes at the start of IP packets for alignment
   purposes. The behavior can be detected using DCFG6 so it isn't
   attached to compatible data.

 - The hardware LSO/TSO is known to be buggy: add a compatible
   capability flag to force disable it.

 - At init, we have to wiggle two syscon registers that configure the
   PHY integration.

   In past attempts [0] we did it in macb_config->init() using a syscon
   regmap. That was far from ideal so now a generic PHY driver
   abstracts that away. We reuse the bp->sgmii_phy field used by some
   compatibles.

   We have to add a phy_set_mode() call as the PHY power on sequence
   depends on whether we do RGMII or SGMII.

[0]: https://lore.kernel.org/lkml/20250627-macb-v2-15-ff8207d0bb77@bootlin.com/

Signed-off-by: Théo Lebrun <theo.lebrun@bootlin.com>
---
Changes in v3:
- Drop Fixes: trailer on [2/5]. We don't fix any platform using the
  driver currently.
- Improve [5/5] commit message; add info about how an unconditional
  phy_set_mode_ext() won't break existing platforms.
- Hardbreak 82 characters line in [2/5]; warning by patchwork.
- Trailers:
  - 1x Acked-by: Conor Dooley on [1/5].
  - 2x Reviewed-by: Andrew Lunn on [1/5] and [4/5].
  - 2x Reviewed-by: Maxime Chevallier on [4/5] and [5/5].
- Link to v2: https://lore.kernel.org/r/20251022-macb-eyeq5-v2-0-7c140abb0581@bootlin.com

Changes in v2:
- Drop non net-next patches.
- Re-run get_maintainers.pl to shorten the To/Cc list.
- Rebase upon latest net-next; no changes. Tested on HW.
- Link to v1: https://lore.kernel.org/r/20251021-macb-eyeq5-v1-0-3b0b5a9d2f85@bootlin.com

Past versions of the MACB EyeQ5 patches:
 - March 2025: [PATCH net-next 00/13] Support the Cadence MACB/GEM
   instances on Mobileye EyeQ5 SoCs
   https://lore.kernel.org/lkml/20250321-macb-v1-0-537b7e37971d@bootlin.com/
 - June 2025: [PATCH net-next v2 00/18] Support the Cadence MACB/GEM
   instances on Mobileye EyeQ5 SoCs
   https://lore.kernel.org/lkml/20250627-macb-v2-0-ff8207d0bb77@bootlin.com/
 - August 2025: [PATCH net v3 00/16] net: macb: various fixes & cleanup
   https://lore.kernel.org/lkml/20250808-macb-fixes-v3-0-08f1fcb5179f@bootlin.com/

---
Théo Lebrun (5):
      dt-bindings: net: cdns,macb: add Mobileye EyeQ5 ethernet interface
      net: macb: match skb_reserve(skb, NET_IP_ALIGN) with HW alignment
      net: macb: add no LSO capability (MACB_CAPS_NO_LSO)
      net: macb: rename bp->sgmii_phy field to bp->phy
      net: macb: Add "mobileye,eyeq5-gem" compatible

 .../devicetree/bindings/net/cdns,macb.yaml         | 10 +++
 drivers/net/ethernet/cadence/macb.h                |  6 +-
 drivers/net/ethernet/cadence/macb_main.c           | 94 +++++++++++++++++-----
 3 files changed, 91 insertions(+), 19 deletions(-)
---
base-commit: 61b7ade9ba
change-id: 20251020-macb-eyeq5-fe2c0d1edc75

Best regards,
====================

Link: https://patch.msgid.link/20251023-macb-eyeq5-v3-0-af509422c204@bootlin.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
This commit is contained in:
Paolo Abeni
2025-10-28 15:17:55 +01:00
3 changed files with 91 additions and 19 deletions

View File

@@ -57,6 +57,7 @@ properties:
- cdns,np4-macb # NP4 SoC devices
- microchip,sama7g5-emac # Microchip SAMA7G5 ethernet interface
- microchip,sama7g5-gem # Microchip SAMA7G5 gigabit ethernet interface
- mobileye,eyeq5-gem # Mobileye EyeQ5 SoCs
- raspberrypi,rp1-gem # Raspberry Pi RP1 gigabit ethernet interface
- sifive,fu540-c000-gem # SiFive FU540-C000 SoC
@@ -183,6 +184,15 @@ allOf:
reg:
maxItems: 1
- if:
properties:
compatible:
contains:
const: mobileye,eyeq5-gem
then:
required:
- phys
unevaluatedProperties: false
examples:

View File

@@ -537,6 +537,8 @@
/* Bitfields in DCFG6. */
#define GEM_PBUF_LSO_OFFSET 27
#define GEM_PBUF_LSO_SIZE 1
#define GEM_PBUF_RSC_OFFSET 26
#define GEM_PBUF_RSC_SIZE 1
#define GEM_PBUF_CUTTHRU_OFFSET 25
#define GEM_PBUF_CUTTHRU_SIZE 1
#define GEM_DAW64_OFFSET 23
@@ -775,6 +777,8 @@
#define MACB_CAPS_MACB_IS_GEM BIT(20)
#define MACB_CAPS_DMA_64B BIT(21)
#define MACB_CAPS_DMA_PTP BIT(22)
#define MACB_CAPS_RSC BIT(23)
#define MACB_CAPS_NO_LSO BIT(24)
/* LSO settings */
#define MACB_LSO_UFO_ENABLE 0x01
@@ -1337,7 +1341,7 @@ struct macb {
struct macb_ptp_info *ptp_info; /* macb-ptp interface */
struct phy *sgmii_phy; /* for ZynqMP SGMII mode */
struct phy *phy;
spinlock_t tsu_clk_lock; /* gem tsu clock locking */
unsigned int tsu_rate;

View File

@@ -1300,8 +1300,19 @@ static void gem_rx_refill(struct macb_queue *queue)
dma_wmb();
macb_set_addr(bp, desc, paddr);
/* properly align Ethernet header */
skb_reserve(skb, NET_IP_ALIGN);
/* Properly align Ethernet header.
*
* Hardware can add dummy bytes if asked using the RBOF
* field inside the NCFGR register. That feature isn't
* available if hardware is RSC capable.
*
* We cannot fallback to doing the 2-byte shift before
* DMA mapping because the address field does not allow
* setting the low 2/3 bits.
* It is 3 bits if HW_DMA_CAP_PTP, else 2 bits.
*/
if (!(bp->caps & MACB_CAPS_RSC))
skb_reserve(skb, NET_IP_ALIGN);
} else {
desc->ctrl = 0;
dma_wmb();
@@ -2773,7 +2784,11 @@ static void macb_init_hw(struct macb *bp)
macb_set_hwaddr(bp);
config = macb_mdc_clk_div(bp);
config |= MACB_BF(RBOF, NET_IP_ALIGN); /* Make eth data aligned */
/* Make eth data aligned.
* If RSC capable, that offset is ignored by HW.
*/
if (!(bp->caps & MACB_CAPS_RSC))
config |= MACB_BF(RBOF, NET_IP_ALIGN);
config |= MACB_BIT(DRFCS); /* Discard Rx FCS */
if (bp->caps & MACB_CAPS_JUMBO)
config |= MACB_BIT(JFRAME); /* Enable jumbo frames */
@@ -2950,7 +2965,11 @@ static int macb_open(struct net_device *dev)
macb_init_hw(bp);
err = phy_power_on(bp->sgmii_phy);
err = phy_set_mode_ext(bp->phy, PHY_MODE_ETHERNET, bp->phy_interface);
if (err)
goto reset_hw;
err = phy_power_on(bp->phy);
if (err)
goto reset_hw;
@@ -2966,7 +2985,7 @@ static int macb_open(struct net_device *dev)
return 0;
phy_off:
phy_power_off(bp->sgmii_phy);
phy_power_off(bp->phy);
reset_hw:
macb_reset_hw(bp);
@@ -2998,7 +3017,7 @@ static int macb_close(struct net_device *dev)
phylink_stop(bp->phylink);
phylink_disconnect_phy(bp->phylink);
phy_power_off(bp->sgmii_phy);
phy_power_off(bp->phy);
spin_lock_irqsave(&bp->lock, flags);
macb_reset_hw(bp);
@@ -4321,6 +4340,8 @@ static void macb_configure_caps(struct macb *bp,
dcfg = gem_readl(bp, DCFG2);
if ((dcfg & (GEM_BIT(RX_PKT_BUFF) | GEM_BIT(TX_PKT_BUFF))) == 0)
bp->caps |= MACB_CAPS_FIFO_MODE;
if (GEM_BFEXT(PBUF_RSC, gem_readl(bp, DCFG6)))
bp->caps |= MACB_CAPS_RSC;
if (gem_has_ptp(bp)) {
if (!GEM_BFEXT(TSU, gem_readl(bp, DCFG5)))
dev_err(&bp->pdev->dev,
@@ -4547,8 +4568,11 @@ static int macb_init(struct platform_device *pdev)
/* Set features */
dev->hw_features = NETIF_F_SG;
/* Check LSO capability */
if (GEM_BFEXT(PBUF_LSO, gem_readl(bp, DCFG6)))
/* Check LSO capability; runtime detection can be overridden by a cap
* flag if the hardware is known to be buggy
*/
if (!(bp->caps & MACB_CAPS_NO_LSO) &&
GEM_BFEXT(PBUF_LSO, gem_readl(bp, DCFG6)))
dev->hw_features |= MACB_NETIF_LSO;
/* Checksum offload is only available on gem with packet buffer */
@@ -5121,13 +5145,13 @@ static int init_reset_optional(struct platform_device *pdev)
if (bp->phy_interface == PHY_INTERFACE_MODE_SGMII) {
/* Ensure PHY device used in SGMII mode is ready */
bp->sgmii_phy = devm_phy_optional_get(&pdev->dev, NULL);
bp->phy = devm_phy_optional_get(&pdev->dev, NULL);
if (IS_ERR(bp->sgmii_phy))
return dev_err_probe(&pdev->dev, PTR_ERR(bp->sgmii_phy),
if (IS_ERR(bp->phy))
return dev_err_probe(&pdev->dev, PTR_ERR(bp->phy),
"failed to get SGMII PHY\n");
ret = phy_init(bp->sgmii_phy);
ret = phy_init(bp->phy);
if (ret)
return dev_err_probe(&pdev->dev, ret,
"failed to init SGMII PHY\n");
@@ -5156,7 +5180,7 @@ static int init_reset_optional(struct platform_device *pdev)
/* Fully reset controller at hardware level if mapped in device tree */
ret = device_reset_optional(&pdev->dev);
if (ret) {
phy_exit(bp->sgmii_phy);
phy_exit(bp->phy);
return dev_err_probe(&pdev->dev, ret, "failed to reset controller");
}
@@ -5164,11 +5188,33 @@ static int init_reset_optional(struct platform_device *pdev)
err_out_phy_exit:
if (ret)
phy_exit(bp->sgmii_phy);
phy_exit(bp->phy);
return ret;
}
static int eyeq5_init(struct platform_device *pdev)
{
struct net_device *netdev = platform_get_drvdata(pdev);
struct macb *bp = netdev_priv(netdev);
struct device *dev = &pdev->dev;
int ret;
bp->phy = devm_phy_get(dev, NULL);
if (IS_ERR(bp->phy))
return dev_err_probe(dev, PTR_ERR(bp->phy),
"failed to get PHY\n");
ret = phy_init(bp->phy);
if (ret)
return dev_err_probe(dev, ret, "failed to init PHY\n");
ret = macb_init(pdev);
if (ret)
phy_exit(bp->phy);
return ret;
}
static const struct macb_usrio_config sama7g5_usrio = {
.mii = 0,
.rmii = 1,
@@ -5323,6 +5369,17 @@ static const struct macb_config versal_config = {
.usrio = &macb_default_usrio,
};
static const struct macb_config eyeq5_config = {
.caps = MACB_CAPS_GIGABIT_MODE_AVAILABLE | MACB_CAPS_JUMBO |
MACB_CAPS_GEM_HAS_PTP | MACB_CAPS_QUEUE_DISABLE |
MACB_CAPS_NO_LSO,
.dma_burst_length = 16,
.clk_init = macb_clk_init,
.init = eyeq5_init,
.jumbo_max_len = 10240,
.usrio = &macb_default_usrio,
};
static const struct macb_config raspberrypi_rp1_config = {
.caps = MACB_CAPS_GIGABIT_MODE_AVAILABLE | MACB_CAPS_CLK_HW_CHG |
MACB_CAPS_JUMBO |
@@ -5354,6 +5411,7 @@ static const struct of_device_id macb_dt_ids[] = {
{ .compatible = "microchip,mpfs-macb", .data = &mpfs_config },
{ .compatible = "microchip,sama7g5-gem", .data = &sama7g5_gem_config },
{ .compatible = "microchip,sama7g5-emac", .data = &sama7g5_emac_config },
{ .compatible = "mobileye,eyeq5-gem", .data = &eyeq5_config },
{ .compatible = "raspberrypi,rp1-gem", .data = &raspberrypi_rp1_config },
{ .compatible = "xlnx,zynqmp-gem", .data = &zynqmp_config},
{ .compatible = "xlnx,zynq-gem", .data = &zynq_config },
@@ -5574,7 +5632,7 @@ static int macb_probe(struct platform_device *pdev)
mdiobus_free(bp->mii_bus);
err_out_phy_exit:
phy_exit(bp->sgmii_phy);
phy_exit(bp->phy);
err_out_free_netdev:
free_netdev(dev);
@@ -5598,7 +5656,7 @@ static void macb_remove(struct platform_device *pdev)
if (dev) {
bp = netdev_priv(dev);
unregister_netdev(dev);
phy_exit(bp->sgmii_phy);
phy_exit(bp->phy);
mdiobus_unregister(bp->mii_bus);
mdiobus_free(bp->mii_bus);
@@ -5625,7 +5683,7 @@ static int __maybe_unused macb_suspend(struct device *dev)
u32 tmp;
if (!device_may_wakeup(&bp->dev->dev))
phy_exit(bp->sgmii_phy);
phy_exit(bp->phy);
if (!netif_running(netdev))
return 0;
@@ -5754,7 +5812,7 @@ static int __maybe_unused macb_resume(struct device *dev)
int err;
if (!device_may_wakeup(&bp->dev->dev))
phy_init(bp->sgmii_phy);
phy_init(bp->phy);
if (!netif_running(netdev))
return 0;