@@ -254,15 +254,10 @@ static int stmmac_getcrosststamp(struct ptp_clock_info *ptp,
}
/* structure describing a PTP hardware clock */
-static struct ptp_clock_info stmmac_ptp_clock_ops = {
+static const struct ptp_clock_info stmmac_ptp_clock_ops = {
.owner = THIS_MODULE,
.name = "stmmac ptp",
.max_adj = 62500000,
- .n_alarm = 0,
- .n_ext_ts = 0, /* will be overwritten in stmmac_ptp_register */
- .n_per_out = 0, /* will be overwritten in stmmac_ptp_register */
- .n_pins = 0,
- .pps = 0,
.adjfine = stmmac_adjust_freq,
.adjtime = stmmac_adjust_time,
.gettime64 = stmmac_get_time,
@@ -287,21 +282,21 @@ void stmmac_ptp_register(struct stmmac_priv *priv)
priv->pps[i].available = true;
}
- if (priv->plat->ptp_max_adj)
- stmmac_ptp_clock_ops.max_adj = priv->plat->ptp_max_adj;
-
/* Calculate the clock domain crossing (CDC) error if necessary */
priv->plat->cdc_error_adj = 0;
if (priv->plat->has_gmac4 && priv->plat->clk_ptp_rate)
priv->plat->cdc_error_adj = (2 * NSEC_PER_SEC) / priv->plat->clk_ptp_rate;
- stmmac_ptp_clock_ops.n_per_out = priv->dma_cap.pps_out_num;
- stmmac_ptp_clock_ops.n_ext_ts = priv->dma_cap.aux_snapshot_n;
-
rwlock_init(&priv->ptp_lock);
mutex_init(&priv->aux_ts_lock);
priv->ptp_clock_ops = stmmac_ptp_clock_ops;
+ if (priv->plat->ptp_max_adj)
+ priv->ptp_clock_ops.max_adj = priv->plat->ptp_max_adj;
+
+ priv->ptp_clock_ops.n_per_out = priv->dma_cap.pps_out_num;
+ priv->ptp_clock_ops.n_ext_ts = priv->dma_cap.aux_snapshot_n;
+
priv->ptp_clock = ptp_clock_register(&priv->ptp_clock_ops,
priv->device);
if (IS_ERR(priv->ptp_clock)) {
It had been defined as constant before commit 9a8a02c9d46d ("net: stmmac: Add Flexible PPS support"). But then it was converted to be just static, which fields may get to be modified on each stmmac_ptp_register() invocation. Since that method is called from the driver probe method, a concurrent DW *MAC NIC initialization causes the race condition for the updated stmmac_ptp_clock_ops fields. That also may lead to setting an inappropriate max_adj value, which was specific for one device, was written to the stmmac_ptp_clock_ops, but then copied to the private ptp_clock_info instance unmodified. So to speak let's leave the stmmac_ptp_clock_ops content untouched and just copy it to the device-specific instance of the ptp_clock_info structure, which fields could be then accordingly modified. After that we can get the const qualifier back to the stmmac_ptp_clock_ops instance definition. While at it remove pointless zero-initialization of the stmmac_ptp_clock_ops fields. It's redundant since the structure is static. Fixes: 9a8a02c9d46d ("net: stmmac: Add Flexible PPS support") Fixes: 190f73ab4c43 ("net: stmmac: setup higher frequency clk support for EHL & TGL") Fixes: f4da56529da6 ("net: stmmac: Add support for external trigger timestamping") Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> --- .../net/ethernet/stmicro/stmmac/stmmac_ptp.c | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-)