net: ethernet: ravb: Replace gPTP flags with callbacks

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 <sergei.shtylyov@gmail.com>
Link: https://patch.msgid.link/20260921175037.4084310-7-niklas.soderlund+renesas@ragnatech.se
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Niklas Söderlund 2026-09-21 19:50:33 +02:00 committed by Jakub Kicinski
parent 121cc8a3ac
commit 14bf0091dd
2 changed files with 78 additions and 33 deletions

View File

@ -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 */

View File

@ -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 (priv->ptp.clock && (hw_info->gptp || hw_info->ccc_gac)) {
if (priv->ptp.clock && 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);
@ -1981,8 +1974,8 @@ static int ravb_open(struct net_device *ndev)
out_ptp_stop:
/* Stop PTP Clock driver */
if (info->ccc_gac)
ravb_ptp_stop(ndev);
if (info->ptp && info->ptp->ndev_close)
info->ptp->ndev_close(ndev);
ravb_stop_dma(ndev);
out_set_reset:
ravb_set_opmode(ndev, CCC_OPC_RESET);
@ -2190,7 +2183,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) {
@ -2372,8 +2365,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)
@ -2381,7 +2374,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);
@ -2663,6 +2656,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,
@ -2681,12 +2694,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,
@ -2705,11 +2730,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,
};
@ -2736,7 +2761,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,
};
@ -2761,7 +2786,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,