[PATCH net-next v2 06/10] net: ethernet: ravb: Replace gPTP flags with callbacks
From: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
Date: 2026-08-11 16:05:13
Also in:
linux-devicetree, linux-renesas-soc, lkml
Subsystem:
networking drivers, renesas ethernet avb driver, the rest · Maintainers:
Andrew Lunn, "David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Niklas Söderlund, Linus Torvalds
Prepare for adding Gen4 support which will add a third and new way to interact with the gPTP clock by replacing the flags for Gen2 behavior (info->gptp) and Gen3 behavior (info->ccc_gac) with callbacks. This will make adding Gen4 support cleaner as the code will not have "if else if else" sprinkled all over to handle each generations special cases. Signed-off-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se> Reviewed-by: Sergey Shtylyov <redacted> --- * Changes since v1 - Handle error from starting the PTP clock. --- drivers/net/ethernet/renesas/ravb.h | 24 ++++++- drivers/net/ethernet/renesas/ravb_main.c | 83 +++++++++++++++--------- 2 files changed, 76 insertions(+), 31 deletions(-)
diff --git a/drivers/net/ethernet/renesas/ravb.h b/drivers/net/ethernet/renesas/ravb.h
index 39892f0f8e62..c98228cfdda9 100644
--- a/drivers/net/ethernet/renesas/ravb.h
+++ b/drivers/net/ethernet/renesas/ravb.h@@ -1034,6 +1034,27 @@ struct ravb_ptp { struct ravb_ptp_perout perout[N_PER_OUT]; }; +/** + * struct ravb_gptp_info - Platform specific gPTP behavior + * + * Each generation of RAVB have slightly different behaviors when interacting + * with the gPTP clock. This struct provides the callbacks to be called at + * critical points in the RAVB driver. + * + * @set_config_mode: Enter config mode + * @dmac_start: Called when the DMAC starts + * @dmac_stop: Called when the DMAC stops + * @ndev_open: Called when the ndev is opened + * @ndev_close: Called when the ndev is closed + */ +struct ravb_gptp_info { + int (*set_config_mode)(struct net_device *ndev); + int (*dmac_start)(struct net_device *ndev); + void (*dmac_stop)(struct net_device *ndev); + int (*ndev_open)(struct net_device *ndev); + void (*ndev_close)(struct net_device *ndev); +}; + struct ravb_hw_info { int (*receive)(struct net_device *ndev, int budget, int q); void (*set_rate)(struct net_device *ndev);
@@ -1052,6 +1073,7 @@ struct ravb_hw_info { u32 rx_buffer_size; u32 rx_desc_size; u32 dbat_entry_num; + const struct ravb_gptp_info *ptp; /* Callbacks to handle gPTP interactions. */ unsigned aligned_tx: 1; unsigned coalesce_irqs:1; /* Needs software IRQ coalescing */
@@ -1062,8 +1084,6 @@ struct ravb_hw_info { unsigned multi_irqs:1; /* AVB-DMAC and E-MAC has multiple irqs */ unsigned irq_en_dis:1; /* Has separate irq enable and disable regs */ unsigned err_mgmt_irqs:1; /* Line1 (Err) and Line2 (Mgmt) irqs are separate */ - unsigned gptp:1; /* AVB-DMAC has gPTP support */ - unsigned ccc_gac:1; /* AVB-DMAC has gPTP support active in config mode */ unsigned gptp_ref_clk:1; /* gPTP has separate reference clock */ unsigned nc_queues:1; /* AVB-DMAC has RX and TX NC queues */ unsigned magic_pkt:1; /* E-MAC supports magic packet detection */
diff --git a/drivers/net/ethernet/renesas/ravb_main.c b/drivers/net/ethernet/renesas/ravb_main.c
index b3cc4c79b29f..d4d03de381db 100644
--- a/drivers/net/ethernet/renesas/ravb_main.c
+++ b/drivers/net/ethernet/renesas/ravb_main.c@@ -712,8 +712,8 @@ static int ravb_dmac_init(struct net_device *ndev) return error; /* Initialise PTP Clock driver */ - if (info->gptp) - ravb_ptp_init(ndev); + if (info->ptp && info->ptp->dmac_start) + return info->ptp->dmac_start(ndev); return 0; }
@@ -1124,8 +1124,8 @@ static int ravb_stop_dma(struct net_device *ndev) } /* Stop PTP Clock driver */ - if (info->gptp) - ravb_ptp_stop(ndev); + if (info->ptp && info->ptp->dmac_stop) + info->ptp->dmac_stop(ndev); /* Stop AVB-DMAC process */ return ravb_set_opmode(ndev, CCC_OPC_CONFIG);
@@ -1774,7 +1774,7 @@ static int ravb_get_ts_info(struct net_device *ndev, struct ravb_private *priv = netdev_priv(ndev); const struct ravb_hw_info *hw_info = priv->info; - if (hw_info->gptp || hw_info->ccc_gac) { + if (hw_info->ptp) { info->so_timestamping = SOF_TIMESTAMPING_TX_SOFTWARE | SOF_TIMESTAMPING_TX_HARDWARE |
@@ -1835,21 +1835,11 @@ static int ravb_set_config_mode(struct net_device *ndev) { struct ravb_private *priv = netdev_priv(ndev); const struct ravb_hw_info *info = priv->info; - int error; - if (info->gptp) { - error = ravb_set_opmode(ndev, CCC_OPC_CONFIG); - if (error) - return error; - /* Set CSEL value */ - ravb_modify(ndev, CCC, CCC_CSEL, CCC_CSEL_HPB); - } else if (info->ccc_gac) { - error = ravb_set_opmode(ndev, CCC_OPC_CONFIG | CCC_GAC | CCC_CSEL_HPB); - } else { - error = ravb_set_opmode(ndev, CCC_OPC_CONFIG); - } + if (info->ptp && info->ptp->set_config_mode) + return info->ptp->set_config_mode(ndev); - return error; + return ravb_set_opmode(ndev, CCC_OPC_CONFIG); } static int ravb_compute_gti(struct net_device *ndev)
@@ -1860,7 +1850,7 @@ static int ravb_compute_gti(struct net_device *ndev) unsigned long rate; u64 inc; - if (!(info->gptp || info->ccc_gac)) + if (!info->ptp) return 0; if (info->gptp_ref_clk)
@@ -1967,8 +1957,11 @@ static int ravb_open(struct net_device *ndev) ravb_emac_init(ndev); /* Initialise PTP Clock driver */ - if (info->ccc_gac) - ravb_ptp_init(ndev); + if (info->ptp && info->ptp->ndev_open) { + error = info->ptp->ndev_open(ndev); + if (error) + goto out_ptp_stop; + } /* PHY control start */ error = ravb_phy_start(ndev);
@@ -2187,7 +2180,7 @@ static netdev_tx_t ravb_start_xmit(struct sk_buff *skb, struct net_device *ndev) desc->dptr = cpu_to_le32(dma_addr); /* TX timestamp required */ - if (info->gptp || info->ccc_gac) { + if (info->ptp) { if (q == RAVB_NC) { ts_skb = kmalloc_obj(*ts_skb, GFP_ATOMIC); if (!ts_skb) {
@@ -2369,8 +2362,8 @@ static int ravb_close(struct net_device *ndev) } /* Stop PTP Clock driver */ - if (info->ccc_gac) - ravb_ptp_stop(ndev); + if (info->ptp && info->ptp->ndev_close) + info->ptp->ndev_close(ndev); /* Set the config mode to stop the AVB-DMAC's processes */ if (ravb_stop_dma(ndev) < 0)
@@ -2378,7 +2371,7 @@ static int ravb_close(struct net_device *ndev) "device will be stopped after h/w processes are done.\n"); /* Clear the timestamp list */ - if (info->gptp || info->ccc_gac) { + if (info->ptp) { list_for_each_entry_safe(ts_skb, ts_skb2, &priv->ts_skb_list, list) { list_del(&ts_skb->list); kfree_skb(ts_skb->skb);
@@ -2660,6 +2653,26 @@ static int ravb_mdio_release(struct ravb_private *priv) return 0; } +static int ravb_gen2_ptp_set_config_mode(struct net_device *ndev) +{ + int ret; + + ret = ravb_set_opmode(ndev, CCC_OPC_CONFIG); + if (ret) + return ret; + + /* gPTP Clock Select High-speed peripheral bus clock. */ + ravb_modify(ndev, CCC, CCC_CSEL, CCC_CSEL_HPB); + + return 0; +} + +static const struct ravb_gptp_info ravb_gen2_ptp_info = { + .set_config_mode = ravb_gen2_ptp_set_config_mode, + .dmac_start = ravb_ptp_init, + .dmac_stop = ravb_ptp_stop, +}; + static const struct ravb_hw_info ravb_gen2_hw_info = { .receive = ravb_rx_rcar, .set_rate = ravb_set_rate_rcar,
@@ -2678,12 +2691,24 @@ static const struct ravb_hw_info ravb_gen2_hw_info = { SKB_DATA_ALIGN(sizeof(struct skb_shared_info)), .rx_desc_size = sizeof(struct ravb_ex_rx_desc), .dbat_entry_num = 22, + .ptp = &ravb_gen2_ptp_info, .aligned_tx = 1, - .gptp = 1, .nc_queues = 1, .magic_pkt = 1, }; +static int ravb_gen3_ptp_set_config_mode(struct net_device *ndev) +{ + /* Enable gPTP Clock and Select High-speed peripheral bus clock. */ + return ravb_set_opmode(ndev, CCC_OPC_CONFIG | CCC_GAC | CCC_CSEL_HPB); +} + +static const struct ravb_gptp_info ravb_gen3_ptp_info = { + .set_config_mode = ravb_gen3_ptp_set_config_mode, + .ndev_open = ravb_ptp_init, + .ndev_close = ravb_ptp_stop, +}; + static const struct ravb_hw_info ravb_gen3_hw_info = { .receive = ravb_rx_rcar, .set_rate = ravb_set_rate_rcar,
@@ -2702,11 +2727,11 @@ static const struct ravb_hw_info ravb_gen3_hw_info = { SKB_DATA_ALIGN(sizeof(struct skb_shared_info)), .rx_desc_size = sizeof(struct ravb_ex_rx_desc), .dbat_entry_num = 22, + .ptp = &ravb_gen3_ptp_info, .internal_delay = 1, .tx_counters = 1, .multi_irqs = 1, .irq_en_dis = 1, - .ccc_gac = 1, .nc_queues = 1, .magic_pkt = 1, };
@@ -2733,7 +2758,7 @@ static const struct ravb_hw_info ravb_gen4_hw_info = { .tx_counters = 1, .multi_irqs = 1, .irq_en_dis = 1, - .ccc_gac = 1, + .ptp = &ravb_gen3_ptp_info, .nc_queues = 1, .magic_pkt = 1, };
@@ -2758,7 +2783,7 @@ static const struct ravb_hw_info ravb_rzv2m_hw_info = { .dbat_entry_num = 22, .multi_irqs = 1, .err_mgmt_irqs = 1, - .gptp = 1, + .ptp = &ravb_gen2_ptp_info, .gptp_ref_clk = 1, .nc_queues = 1, .magic_pkt = 1,
--
2.55.0