Skip to content

Commit 36d7478

Browse files
author
Paolo Abeni
committed
Merge branch 'net-fec-fix-some-ptp-related-issues'
Wei Fang says: ==================== net: fec: fix some PTP related issues There are some issues which were introduced by the commit 350749b ("net: fec: Add support for periodic output signal of PPS"). See each patch for more details. ==================== Link: https://patch.msgid.link/20251125085210.1094306-1-wei.fang@nxp.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>
2 parents b3e528a + 9a060d0 commit 36d7478

2 files changed

Lines changed: 53 additions & 12 deletions

File tree

drivers/net/ethernet/freescale/fec.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -687,6 +687,7 @@ struct fec_enet_private {
687687
unsigned int reload_period;
688688
int pps_enable;
689689
unsigned int next_counter;
690+
bool perout_enable;
690691
struct hrtimer perout_timer;
691692
u64 perout_stime;
692693

drivers/net/ethernet/freescale/fec_ptp.c

Lines changed: 52 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,12 @@ static int fec_ptp_enable_pps(struct fec_enet_private *fep, uint enable)
128128

129129
spin_lock_irqsave(&fep->tmreg_lock, flags);
130130

131+
if (fep->perout_enable) {
132+
spin_unlock_irqrestore(&fep->tmreg_lock, flags);
133+
dev_err(&fep->pdev->dev, "PEROUT is running");
134+
return -EBUSY;
135+
}
136+
131137
if (fep->pps_enable == enable) {
132138
spin_unlock_irqrestore(&fep->tmreg_lock, flags);
133139
return 0;
@@ -243,6 +249,7 @@ static int fec_ptp_pps_perout(struct fec_enet_private *fep)
243249
* the FEC_TCCR register in time and missed the start time.
244250
*/
245251
if (fep->perout_stime < curr_time + 100 * NSEC_PER_MSEC) {
252+
fep->perout_enable = false;
246253
dev_err(&fep->pdev->dev, "Current time is too close to the start time!\n");
247254
spin_unlock_irqrestore(&fep->tmreg_lock, flags);
248255
return -1;
@@ -497,7 +504,10 @@ static int fec_ptp_pps_disable(struct fec_enet_private *fep, uint channel)
497504
{
498505
unsigned long flags;
499506

507+
hrtimer_cancel(&fep->perout_timer);
508+
500509
spin_lock_irqsave(&fep->tmreg_lock, flags);
510+
fep->perout_enable = false;
501511
writel(0, fep->hwp + FEC_TCSR(channel));
502512
spin_unlock_irqrestore(&fep->tmreg_lock, flags);
503513

@@ -529,6 +539,8 @@ static int fec_ptp_enable(struct ptp_clock_info *ptp,
529539

530540
return ret;
531541
} else if (rq->type == PTP_CLK_REQ_PEROUT) {
542+
u32 reload_period;
543+
532544
/* Reject requests with unsupported flags */
533545
if (rq->perout.flags)
534546
return -EOPNOTSUPP;
@@ -548,12 +560,14 @@ static int fec_ptp_enable(struct ptp_clock_info *ptp,
548560
return -EOPNOTSUPP;
549561
}
550562

551-
fep->reload_period = div_u64(period_ns, 2);
552-
if (on && fep->reload_period) {
563+
reload_period = div_u64(period_ns, 2);
564+
if (on && reload_period) {
565+
u64 perout_stime;
566+
553567
/* Convert 1588 timestamp to ns*/
554568
start_time.tv_sec = rq->perout.start.sec;
555569
start_time.tv_nsec = rq->perout.start.nsec;
556-
fep->perout_stime = timespec64_to_ns(&start_time);
570+
perout_stime = timespec64_to_ns(&start_time);
557571

558572
mutex_lock(&fep->ptp_clk_mutex);
559573
if (!fep->ptp_clk_on) {
@@ -562,18 +576,41 @@ static int fec_ptp_enable(struct ptp_clock_info *ptp,
562576
return -EOPNOTSUPP;
563577
}
564578
spin_lock_irqsave(&fep->tmreg_lock, flags);
579+
580+
if (fep->pps_enable) {
581+
dev_err(&fep->pdev->dev, "PPS is running");
582+
ret = -EBUSY;
583+
goto unlock;
584+
}
585+
586+
if (fep->perout_enable) {
587+
dev_err(&fep->pdev->dev,
588+
"PEROUT has been enabled\n");
589+
ret = -EBUSY;
590+
goto unlock;
591+
}
592+
565593
/* Read current timestamp */
566594
curr_time = timecounter_read(&fep->tc);
567-
spin_unlock_irqrestore(&fep->tmreg_lock, flags);
568-
mutex_unlock(&fep->ptp_clk_mutex);
595+
if (perout_stime <= curr_time) {
596+
dev_err(&fep->pdev->dev,
597+
"Start time must be greater than current time\n");
598+
ret = -EINVAL;
599+
goto unlock;
600+
}
569601

570602
/* Calculate time difference */
571-
delta = fep->perout_stime - curr_time;
603+
delta = perout_stime - curr_time;
604+
fep->reload_period = reload_period;
605+
fep->perout_stime = perout_stime;
606+
fep->perout_enable = true;
572607

573-
if (fep->perout_stime <= curr_time) {
574-
dev_err(&fep->pdev->dev, "Start time must larger than current time!\n");
575-
return -EINVAL;
576-
}
608+
unlock:
609+
spin_unlock_irqrestore(&fep->tmreg_lock, flags);
610+
mutex_unlock(&fep->ptp_clk_mutex);
611+
612+
if (ret)
613+
return ret;
577614

578615
/* Because the timer counter of FEC only has 31-bits, correspondingly,
579616
* the time comparison register FEC_TCCR also only low 31 bits can be
@@ -681,8 +718,11 @@ static irqreturn_t fec_pps_interrupt(int irq, void *dev_id)
681718
fep->next_counter = (fep->next_counter + fep->reload_period) &
682719
fep->cc.mask;
683720

684-
event.type = PTP_CLOCK_PPS;
685-
ptp_clock_event(fep->ptp_clock, &event);
721+
if (fep->pps_enable) {
722+
event.type = PTP_CLOCK_PPS;
723+
ptp_clock_event(fep->ptp_clock, &event);
724+
}
725+
686726
return IRQ_HANDLED;
687727
}
688728

0 commit comments

Comments
 (0)