Commit 4a0475d5 authored by Miroslav Lichvar's avatar Miroslav Lichvar Committed by Saeed Mahameed

mlx5: extend PTP gettime function to read system clock

Read the system time right before and immediately after reading the low
register of the internal timer. This adds support for the
PTP_SYS_OFFSET_EXTENDED ioctl.

Cc: Richard Cochran <richardcochran@gmail.com>
Cc: Saeed Mahameed <saeedm@mellanox.com>
Signed-off-by: default avatarMiroslav Lichvar <mlichvar@redhat.com>
Signed-off-by: default avatarSaeed Mahameed <saeedm@mellanox.com>
parent 5d867836
...@@ -72,7 +72,7 @@ static u64 read_internal_timer(const struct cyclecounter *cc) ...@@ -72,7 +72,7 @@ static u64 read_internal_timer(const struct cyclecounter *cc)
struct mlx5_core_dev *mdev = container_of(clock, struct mlx5_core_dev, struct mlx5_core_dev *mdev = container_of(clock, struct mlx5_core_dev,
clock); clock);
return mlx5_read_internal_timer(mdev) & cc->mask; return mlx5_read_internal_timer(mdev, NULL) & cc->mask;
} }
static void mlx5_update_clock_info_page(struct mlx5_core_dev *mdev) static void mlx5_update_clock_info_page(struct mlx5_core_dev *mdev)
...@@ -156,15 +156,19 @@ static int mlx5_ptp_settime(struct ptp_clock_info *ptp, ...@@ -156,15 +156,19 @@ static int mlx5_ptp_settime(struct ptp_clock_info *ptp,
return 0; return 0;
} }
static int mlx5_ptp_gettime(struct ptp_clock_info *ptp, struct timespec64 *ts) static int mlx5_ptp_gettimex(struct ptp_clock_info *ptp, struct timespec64 *ts,
struct ptp_system_timestamp *sts)
{ {
struct mlx5_clock *clock = container_of(ptp, struct mlx5_clock, struct mlx5_clock *clock = container_of(ptp, struct mlx5_clock,
ptp_info); ptp_info);
u64 ns; struct mlx5_core_dev *mdev = container_of(clock, struct mlx5_core_dev,
clock);
unsigned long flags; unsigned long flags;
u64 cycles, ns;
write_seqlock_irqsave(&clock->lock, flags); write_seqlock_irqsave(&clock->lock, flags);
ns = timecounter_read(&clock->tc); cycles = mlx5_read_internal_timer(mdev, sts);
ns = timecounter_cyc2time(&clock->tc, cycles);
write_sequnlock_irqrestore(&clock->lock, flags); write_sequnlock_irqrestore(&clock->lock, flags);
*ts = ns_to_timespec64(ns); *ts = ns_to_timespec64(ns);
...@@ -307,7 +311,7 @@ static int mlx5_perout_configure(struct ptp_clock_info *ptp, ...@@ -307,7 +311,7 @@ static int mlx5_perout_configure(struct ptp_clock_info *ptp,
ts.tv_sec = rq->perout.start.sec; ts.tv_sec = rq->perout.start.sec;
ts.tv_nsec = rq->perout.start.nsec; ts.tv_nsec = rq->perout.start.nsec;
ns = timespec64_to_ns(&ts); ns = timespec64_to_ns(&ts);
cycles_now = mlx5_read_internal_timer(mdev); cycles_now = mlx5_read_internal_timer(mdev, NULL);
write_seqlock_irqsave(&clock->lock, flags); write_seqlock_irqsave(&clock->lock, flags);
nsec_now = timecounter_cyc2time(&clock->tc, cycles_now); nsec_now = timecounter_cyc2time(&clock->tc, cycles_now);
nsec_delta = ns - nsec_now; nsec_delta = ns - nsec_now;
...@@ -384,7 +388,7 @@ static const struct ptp_clock_info mlx5_ptp_clock_info = { ...@@ -384,7 +388,7 @@ static const struct ptp_clock_info mlx5_ptp_clock_info = {
.pps = 0, .pps = 0,
.adjfreq = mlx5_ptp_adjfreq, .adjfreq = mlx5_ptp_adjfreq,
.adjtime = mlx5_ptp_adjtime, .adjtime = mlx5_ptp_adjtime,
.gettime64 = mlx5_ptp_gettime, .gettimex64 = mlx5_ptp_gettimex,
.settime64 = mlx5_ptp_settime, .settime64 = mlx5_ptp_settime,
.enable = NULL, .enable = NULL,
.verify = NULL, .verify = NULL,
...@@ -469,8 +473,8 @@ static int mlx5_pps_event(struct notifier_block *nb, ...@@ -469,8 +473,8 @@ static int mlx5_pps_event(struct notifier_block *nb,
ptp_clock_event(clock->ptp, &ptp_event); ptp_clock_event(clock->ptp, &ptp_event);
break; break;
case PTP_PF_PEROUT: case PTP_PF_PEROUT:
mlx5_ptp_gettime(&clock->ptp_info, &ts); mlx5_ptp_gettimex(&clock->ptp_info, &ts, NULL);
cycles_now = mlx5_read_internal_timer(mdev); cycles_now = mlx5_read_internal_timer(mdev, NULL);
ts.tv_sec += 1; ts.tv_sec += 1;
ts.tv_nsec = 0; ts.tv_nsec = 0;
ns = timespec64_to_ns(&ts); ns = timespec64_to_ns(&ts);
......
...@@ -580,15 +580,22 @@ int mlx5_core_disable_hca(struct mlx5_core_dev *dev, u16 func_id) ...@@ -580,15 +580,22 @@ int mlx5_core_disable_hca(struct mlx5_core_dev *dev, u16 func_id)
return mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out)); return mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out));
} }
u64 mlx5_read_internal_timer(struct mlx5_core_dev *dev) u64 mlx5_read_internal_timer(struct mlx5_core_dev *dev,
struct ptp_system_timestamp *sts)
{ {
u32 timer_h, timer_h1, timer_l; u32 timer_h, timer_h1, timer_l;
timer_h = ioread32be(&dev->iseg->internal_timer_h); timer_h = ioread32be(&dev->iseg->internal_timer_h);
ptp_read_system_prets(sts);
timer_l = ioread32be(&dev->iseg->internal_timer_l); timer_l = ioread32be(&dev->iseg->internal_timer_l);
ptp_read_system_postts(sts);
timer_h1 = ioread32be(&dev->iseg->internal_timer_h); timer_h1 = ioread32be(&dev->iseg->internal_timer_h);
if (timer_h != timer_h1) /* wrap around */ if (timer_h != timer_h1) {
/* wrap around */
ptp_read_system_prets(sts);
timer_l = ioread32be(&dev->iseg->internal_timer_l); timer_l = ioread32be(&dev->iseg->internal_timer_l);
ptp_read_system_postts(sts);
}
return (u64)timer_l | (u64)timer_h1 << 32; return (u64)timer_l | (u64)timer_h1 << 32;
} }
......
...@@ -38,6 +38,7 @@ ...@@ -38,6 +38,7 @@
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/if_link.h> #include <linux/if_link.h>
#include <linux/firmware.h> #include <linux/firmware.h>
#include <linux/ptp_clock_kernel.h>
#include <linux/mlx5/cq.h> #include <linux/mlx5/cq.h>
#include <linux/mlx5/fs.h> #include <linux/mlx5/fs.h>
...@@ -121,7 +122,8 @@ int mlx5_modify_scheduling_element_cmd(struct mlx5_core_dev *dev, u8 hierarchy, ...@@ -121,7 +122,8 @@ int mlx5_modify_scheduling_element_cmd(struct mlx5_core_dev *dev, u8 hierarchy,
int mlx5_destroy_scheduling_element_cmd(struct mlx5_core_dev *dev, u8 hierarchy, int mlx5_destroy_scheduling_element_cmd(struct mlx5_core_dev *dev, u8 hierarchy,
u32 element_id); u32 element_id);
int mlx5_wait_for_vf_pages(struct mlx5_core_dev *dev); int mlx5_wait_for_vf_pages(struct mlx5_core_dev *dev);
u64 mlx5_read_internal_timer(struct mlx5_core_dev *dev); u64 mlx5_read_internal_timer(struct mlx5_core_dev *dev,
struct ptp_system_timestamp *sts);
void mlx5_cmd_trigger_completions(struct mlx5_core_dev *dev); void mlx5_cmd_trigger_completions(struct mlx5_core_dev *dev);
int mlx5_cq_debugfs_init(struct mlx5_core_dev *dev); int mlx5_cq_debugfs_init(struct mlx5_core_dev *dev);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment