Messages in this thread Patch in this message | | | From | Shmuel Hazan <> | Subject | [PATCH 1/3] net: mvpp2: tai: add refcount for ptp worker | Date | Mon, 17 Apr 2023 19:01:49 +0300 |
| |
In some configurations, a single TAI can be responsible for multiple mvpp2 interfaces. However, the mvpp2 driver will call mvpp22_tai_stop and mvpp22_tai_start per interface RX timestamp disable/enable.
As a result, disabling timestamping for one interface would stop the worker and corrupt the other interface's RX timestamps.
This commit solves the issue by introducing a simpler ref count for each TAI instance.
Fixes: ce3497e2072e ("net: mvpp2: ptp: add support for receive timestamping") Signed-off-by: Shmuel Hazan <shmuel.h@siklu.com> --- .../net/ethernet/marvell/mvpp2/mvpp2_tai.c | 30 +++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_tai.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_tai.c index 95862aff49f1..9c0d50a924d9 100644 --- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_tai.c +++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_tai.c @@ -61,6 +61,7 @@ struct mvpp2_tai { u64 period; // nanosecond period in 32.32 fixed point /* This timestamp is updated every two seconds */ struct timespec64 stamp; + u16 poll_worker_refcount; }; static void mvpp2_tai_modify(void __iomem *reg, u32 mask, u32 set) @@ -368,20 +369,45 @@ void mvpp22_tai_tstamp(struct mvpp2_tai *tai, u32 tstamp, hwtstamp->hwtstamp = timespec64_to_ktime(ts); } -void mvpp22_tai_start(struct mvpp2_tai *tai) +static void mvpp22_tai_start_unlocked(struct mvpp2_tai *tai) { long delay; + tai->poll_worker_refcount++; + if (tai->poll_worker_refcount > 1) + return; + delay = mvpp22_tai_aux_work(&tai->caps); ptp_schedule_worker(tai->ptp_clock, delay); } -void mvpp22_tai_stop(struct mvpp2_tai *tai) +void mvpp22_tai_start(struct mvpp2_tai *tai) { + unsigned long flags; + + spin_lock_irqsave(&tai->lock, flags); + mvpp22_tai_start_unlocked(tai); + spin_unlock_irqrestore(&tai->lock, flags); +} + +static void mvpp22_tai_stop_unlocked(struct mvpp2_tai *tai) +{ + tai->poll_worker_refcount--; + if (tai->poll_worker_refcount) + return; ptp_cancel_worker_sync(tai->ptp_clock); } +void mvpp22_tai_stop(struct mvpp2_tai *tai) +{ + unsigned long flags; + + spin_lock_irqsave(&tai->lock, flags); + mvpp22_tai_stop_unlocked(tai); + spin_unlock_irqrestore(&tai->lock, flags); +} + static void mvpp22_tai_remove(void *priv) { struct mvpp2_tai *tai = priv; -- 2.40.0
| |