Skip to content

Commit

Permalink
mlxsw: spectrum_ptp: Use 'struct mlxsw_sp_ptp_clock' per ASIC
Browse files Browse the repository at this point in the history
Currently, there is one shared structure that holds the required
structures for PTP clock. Most of the existing fields are relevant only
for Spectrum-1 (cycles, timecounter, and more). Rename the structure to
be specific for Spectrum-1 and align the existing code. Add a common
structure which includes the structures which will be used also for
Spectrum-2. This structure will be returned from clock_init() operation,
as the definition is shared between all ASICs' operations.

Signed-off-by: Amit Cohen <amcohen@nvidia.com>
Reviewed-by: Petr Machata <petrm@nvidia.com>
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Amit Cohen authored and David S. Miller committed Jul 25, 2022
1 parent e8fea34 commit 9bfe3c1
Showing 1 changed file with 44 additions and 31 deletions.
75 changes: 44 additions & 31 deletions drivers/net/ethernet/mellanox/mlxsw/spectrum_ptp.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,12 +64,16 @@ static const struct rhashtable_params mlxsw_sp1_ptp_unmatched_ht_params = {

struct mlxsw_sp_ptp_clock {
struct mlxsw_core *core;
struct ptp_clock *ptp;
struct ptp_clock_info ptp_info;
};

struct mlxsw_sp1_ptp_clock {
struct mlxsw_sp_ptp_clock common;
spinlock_t lock; /* protect this structure */
struct cyclecounter cycles;
struct timecounter tc;
u32 nominal_c_mult;
struct ptp_clock *ptp;
struct ptp_clock_info ptp_info;
unsigned long overflow_period;
struct delayed_work overflow_work;
};
Expand All @@ -81,10 +85,16 @@ mlxsw_sp1_ptp_state(struct mlxsw_sp *mlxsw_sp)
common);
}

static u64 __mlxsw_sp1_ptp_read_frc(struct mlxsw_sp_ptp_clock *clock,
static struct mlxsw_sp1_ptp_clock *
mlxsw_sp1_ptp_clock(struct ptp_clock_info *ptp)
{
return container_of(ptp, struct mlxsw_sp1_ptp_clock, common.ptp_info);
}

static u64 __mlxsw_sp1_ptp_read_frc(struct mlxsw_sp1_ptp_clock *clock,
struct ptp_system_timestamp *sts)
{
struct mlxsw_core *mlxsw_core = clock->core;
struct mlxsw_core *mlxsw_core = clock->common.core;
u32 frc_h1, frc_h2, frc_l;

frc_h1 = mlxsw_core_read_frc_h(mlxsw_core);
Expand All @@ -105,8 +115,8 @@ static u64 __mlxsw_sp1_ptp_read_frc(struct mlxsw_sp_ptp_clock *clock,

static u64 mlxsw_sp1_ptp_read_frc(const struct cyclecounter *cc)
{
struct mlxsw_sp_ptp_clock *clock =
container_of(cc, struct mlxsw_sp_ptp_clock, cycles);
struct mlxsw_sp1_ptp_clock *clock =
container_of(cc, struct mlxsw_sp1_ptp_clock, cycles);

return __mlxsw_sp1_ptp_read_frc(clock, NULL) & cc->mask;
}
Expand All @@ -133,9 +143,9 @@ static u64 mlxsw_sp1_ptp_ns2cycles(const struct timecounter *tc, u64 nsec)
}

static int
mlxsw_sp1_ptp_phc_settime(struct mlxsw_sp_ptp_clock *clock, u64 nsec)
mlxsw_sp1_ptp_phc_settime(struct mlxsw_sp1_ptp_clock *clock, u64 nsec)
{
struct mlxsw_core *mlxsw_core = clock->core;
struct mlxsw_core *mlxsw_core = clock->common.core;
u64 next_sec, next_sec_in_nsec, cycles;
char mtutc_pl[MLXSW_REG_MTUTC_LEN];
char mtpps_pl[MLXSW_REG_MTPPS_LEN];
Expand All @@ -161,8 +171,7 @@ mlxsw_sp1_ptp_phc_settime(struct mlxsw_sp_ptp_clock *clock, u64 nsec)

static int mlxsw_sp1_ptp_adjfine(struct ptp_clock_info *ptp, long scaled_ppm)
{
struct mlxsw_sp_ptp_clock *clock =
container_of(ptp, struct mlxsw_sp_ptp_clock, ptp_info);
struct mlxsw_sp1_ptp_clock *clock = mlxsw_sp1_ptp_clock(ptp);
int neg_adj = 0;
u32 diff;
u64 adj;
Expand All @@ -185,13 +194,12 @@ static int mlxsw_sp1_ptp_adjfine(struct ptp_clock_info *ptp, long scaled_ppm)
clock->nominal_c_mult + diff;
spin_unlock_bh(&clock->lock);

return mlxsw_sp1_ptp_phc_adjfreq(clock, neg_adj ? -ppb : ppb);
return mlxsw_sp1_ptp_phc_adjfreq(&clock->common, neg_adj ? -ppb : ppb);
}

static int mlxsw_sp1_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta)
{
struct mlxsw_sp_ptp_clock *clock =
container_of(ptp, struct mlxsw_sp_ptp_clock, ptp_info);
struct mlxsw_sp1_ptp_clock *clock = mlxsw_sp1_ptp_clock(ptp);
u64 nsec;

spin_lock_bh(&clock->lock);
Expand All @@ -206,8 +214,7 @@ static int mlxsw_sp1_ptp_gettimex(struct ptp_clock_info *ptp,
struct timespec64 *ts,
struct ptp_system_timestamp *sts)
{
struct mlxsw_sp_ptp_clock *clock =
container_of(ptp, struct mlxsw_sp_ptp_clock, ptp_info);
struct mlxsw_sp1_ptp_clock *clock = mlxsw_sp1_ptp_clock(ptp);
u64 cycles, nsec;

spin_lock_bh(&clock->lock);
Expand All @@ -223,8 +230,7 @@ static int mlxsw_sp1_ptp_gettimex(struct ptp_clock_info *ptp,
static int mlxsw_sp1_ptp_settime(struct ptp_clock_info *ptp,
const struct timespec64 *ts)
{
struct mlxsw_sp_ptp_clock *clock =
container_of(ptp, struct mlxsw_sp_ptp_clock, ptp_info);
struct mlxsw_sp1_ptp_clock *clock = mlxsw_sp1_ptp_clock(ptp);
u64 nsec = timespec64_to_ns(ts);

spin_lock_bh(&clock->lock);
Expand All @@ -248,9 +254,9 @@ static const struct ptp_clock_info mlxsw_sp1_ptp_clock_info = {
static void mlxsw_sp1_ptp_clock_overflow(struct work_struct *work)
{
struct delayed_work *dwork = to_delayed_work(work);
struct mlxsw_sp_ptp_clock *clock;
struct mlxsw_sp1_ptp_clock *clock;

clock = container_of(dwork, struct mlxsw_sp_ptp_clock, overflow_work);
clock = container_of(dwork, struct mlxsw_sp1_ptp_clock, overflow_work);

spin_lock_bh(&clock->lock);
timecounter_read(&clock->tc);
Expand All @@ -262,7 +268,7 @@ struct mlxsw_sp_ptp_clock *
mlxsw_sp1_ptp_clock_init(struct mlxsw_sp *mlxsw_sp, struct device *dev)
{
u64 overflow_cycles, nsec, frac = 0;
struct mlxsw_sp_ptp_clock *clock;
struct mlxsw_sp1_ptp_clock *clock;
int err;

clock = kzalloc(sizeof(*clock), GFP_KERNEL);
Expand All @@ -276,7 +282,7 @@ mlxsw_sp1_ptp_clock_init(struct mlxsw_sp *mlxsw_sp, struct device *dev)
clock->cycles.shift);
clock->nominal_c_mult = clock->cycles.mult;
clock->cycles.mask = CLOCKSOURCE_MASK(MLXSW_SP1_PTP_CLOCK_MASK);
clock->core = mlxsw_sp->core;
clock->common.core = mlxsw_sp->core;

timecounter_init(&clock->tc, &clock->cycles, 0);

Expand All @@ -296,25 +302,28 @@ mlxsw_sp1_ptp_clock_init(struct mlxsw_sp *mlxsw_sp, struct device *dev)
INIT_DELAYED_WORK(&clock->overflow_work, mlxsw_sp1_ptp_clock_overflow);
mlxsw_core_schedule_dw(&clock->overflow_work, 0);

clock->ptp_info = mlxsw_sp1_ptp_clock_info;
clock->ptp = ptp_clock_register(&clock->ptp_info, dev);
if (IS_ERR(clock->ptp)) {
err = PTR_ERR(clock->ptp);
clock->common.ptp_info = mlxsw_sp1_ptp_clock_info;
clock->common.ptp = ptp_clock_register(&clock->common.ptp_info, dev);
if (IS_ERR(clock->common.ptp)) {
err = PTR_ERR(clock->common.ptp);
dev_err(dev, "ptp_clock_register failed %d\n", err);
goto err_ptp_clock_register;
}

return clock;
return &clock->common;

err_ptp_clock_register:
cancel_delayed_work_sync(&clock->overflow_work);
kfree(clock);
return ERR_PTR(err);
}

void mlxsw_sp1_ptp_clock_fini(struct mlxsw_sp_ptp_clock *clock)
void mlxsw_sp1_ptp_clock_fini(struct mlxsw_sp_ptp_clock *clock_common)
{
ptp_clock_unregister(clock->ptp);
struct mlxsw_sp1_ptp_clock *clock =
container_of(clock_common, struct mlxsw_sp1_ptp_clock, common);

ptp_clock_unregister(clock_common->ptp);
cancel_delayed_work_sync(&clock->overflow_work);
kfree(clock);
}
Expand Down Expand Up @@ -451,12 +460,16 @@ static void mlxsw_sp1_packet_timestamp(struct mlxsw_sp *mlxsw_sp,
struct sk_buff *skb,
u64 timestamp)
{
struct mlxsw_sp_ptp_clock *clock_common = mlxsw_sp->clock;
struct mlxsw_sp1_ptp_clock *clock =
container_of(clock_common, struct mlxsw_sp1_ptp_clock, common);

struct skb_shared_hwtstamps hwtstamps;
u64 nsec;

spin_lock_bh(&mlxsw_sp->clock->lock);
nsec = timecounter_cyc2time(&mlxsw_sp->clock->tc, timestamp);
spin_unlock_bh(&mlxsw_sp->clock->lock);
spin_lock_bh(&clock->lock);
nsec = timecounter_cyc2time(&clock->tc, timestamp);
spin_unlock_bh(&clock->lock);

hwtstamps.hwtstamp = ns_to_ktime(nsec);
mlxsw_sp1_ptp_packet_finish(mlxsw_sp, skb,
Expand Down

0 comments on commit 9bfe3c1

Please sign in to comment.