File Index
Files and directories
Sign in
FILE

spectrum_ptp.c

File preview with syntax highlighting.

linux-6.19.14/drivers/net/ethernet/mellanox/mlxsw/spectrum_ptp.c C
   1// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
   2/* Copyright (c) 2019 Mellanox Technologies. All rights reserved */
   3
   4#include <linux/ptp_clock_kernel.h>
   5#include <linux/clocksource.h>
   6#include <linux/timecounter.h>
   7#include <linux/spinlock.h>
   8#include <linux/device.h>
   9#include <linux/rhashtable.h>
  10#include <linux/ptp_classify.h>
  11#include <linux/if_ether.h>
  12#include <linux/if_vlan.h>
  13#include <linux/net_tstamp.h>
  14#include <linux/refcount.h>
  15
  16#include "spectrum.h"
  17#include "spectrum_ptp.h"
  18#include "core.h"
  19#include "txheader.h"
  20
  21#define MLXSW_SP1_PTP_CLOCK_CYCLES_SHIFT	29
  22#define MLXSW_SP1_PTP_CLOCK_FREQ_KHZ		156257 /* 6.4nSec */
  23#define MLXSW_SP1_PTP_CLOCK_MASK		64
  24
  25#define MLXSW_SP1_PTP_HT_GC_INTERVAL		500 /* ms */
  26
  27/* How long, approximately, should the unmatched entries stay in the hash table
  28 * before they are collected. Should be evenly divisible by the GC interval.
  29 */
  30#define MLXSW_SP1_PTP_HT_GC_TIMEOUT		1000 /* ms */
  31
  32struct mlxsw_sp_ptp_state {
  33	struct mlxsw_sp *mlxsw_sp;
  34};
  35
  36struct mlxsw_sp1_ptp_state {
  37	struct mlxsw_sp_ptp_state common;
  38	struct rhltable unmatched_ht;
  39	spinlock_t unmatched_lock; /* protects the HT */
  40	struct delayed_work ht_gc_dw;
  41	u32 gc_cycle;
  42};
  43
  44struct mlxsw_sp2_ptp_state {
  45	struct mlxsw_sp_ptp_state common;
  46	refcount_t ptp_port_enabled_ref; /* Number of ports with time stamping
  47					  * enabled.
  48					  */
  49	struct kernel_hwtstamp_config config;
  50	struct mutex lock; /* Protects 'config' and HW configuration. */
  51};
  52
  53struct mlxsw_sp1_ptp_key {
  54	u16 local_port;
  55	u8 message_type;
  56	u16 sequence_id;
  57	u8 domain_number;
  58	bool ingress;
  59};
  60
  61struct mlxsw_sp1_ptp_unmatched {
  62	struct mlxsw_sp1_ptp_key key;
  63	struct rhlist_head ht_node;
  64	struct rcu_head rcu;
  65	struct sk_buff *skb;
  66	u64 timestamp;
  67	u32 gc_cycle;
  68};
  69
  70static const struct rhashtable_params mlxsw_sp1_ptp_unmatched_ht_params = {
  71	.key_len = sizeof_field(struct mlxsw_sp1_ptp_unmatched, key),
  72	.key_offset = offsetof(struct mlxsw_sp1_ptp_unmatched, key),
  73	.head_offset = offsetof(struct mlxsw_sp1_ptp_unmatched, ht_node),
  74};
  75
  76struct mlxsw_sp_ptp_clock {
  77	struct mlxsw_core *core;
  78	struct ptp_clock *ptp;
  79	struct ptp_clock_info ptp_info;
  80};
  81
  82struct mlxsw_sp1_ptp_clock {
  83	struct mlxsw_sp_ptp_clock common;
  84	spinlock_t lock; /* protect this structure */
  85	struct cyclecounter cycles;
  86	struct timecounter tc;
  87	u32 nominal_c_mult;
  88	unsigned long overflow_period;
  89	struct delayed_work overflow_work;
  90};
  91
  92static struct mlxsw_sp1_ptp_state *
  93mlxsw_sp1_ptp_state(struct mlxsw_sp *mlxsw_sp)
  94{
  95	return container_of(mlxsw_sp->ptp_state, struct mlxsw_sp1_ptp_state,
  96			    common);
  97}
  98
  99static struct mlxsw_sp2_ptp_state *
 100mlxsw_sp2_ptp_state(struct mlxsw_sp *mlxsw_sp)
 101{
 102	return container_of(mlxsw_sp->ptp_state, struct mlxsw_sp2_ptp_state,
 103			    common);
 104}
 105
 106static struct mlxsw_sp1_ptp_clock *
 107mlxsw_sp1_ptp_clock(struct ptp_clock_info *ptp)
 108{
 109	return container_of(ptp, struct mlxsw_sp1_ptp_clock, common.ptp_info);
 110}
 111
 112static u64 __mlxsw_sp1_ptp_read_frc(struct mlxsw_sp1_ptp_clock *clock,
 113				    struct ptp_system_timestamp *sts)
 114{
 115	struct mlxsw_core *mlxsw_core = clock->common.core;
 116	u32 frc_h1, frc_h2, frc_l;
 117
 118	frc_h1 = mlxsw_core_read_frc_h(mlxsw_core);
 119	ptp_read_system_prets(sts);
 120	frc_l = mlxsw_core_read_frc_l(mlxsw_core);
 121	ptp_read_system_postts(sts);
 122	frc_h2 = mlxsw_core_read_frc_h(mlxsw_core);
 123
 124	if (frc_h1 != frc_h2) {
 125		/* wrap around */
 126		ptp_read_system_prets(sts);
 127		frc_l = mlxsw_core_read_frc_l(mlxsw_core);
 128		ptp_read_system_postts(sts);
 129	}
 130
 131	return (u64) frc_l | (u64) frc_h2 << 32;
 132}
 133
 134static u64 mlxsw_sp1_ptp_read_frc(struct cyclecounter *cc)
 135{
 136	struct mlxsw_sp1_ptp_clock *clock =
 137		container_of(cc, struct mlxsw_sp1_ptp_clock, cycles);
 138
 139	return __mlxsw_sp1_ptp_read_frc(clock, NULL) & cc->mask;
 140}
 141
 142static int
 143mlxsw_sp_ptp_phc_adjfreq(struct mlxsw_sp_ptp_clock *clock, int freq_adj)
 144{
 145	struct mlxsw_core *mlxsw_core = clock->core;
 146	char mtutc_pl[MLXSW_REG_MTUTC_LEN];
 147
 148	mlxsw_reg_mtutc_pack(mtutc_pl, MLXSW_REG_MTUTC_OPERATION_ADJUST_FREQ,
 149			     freq_adj, 0, 0, 0);
 150	return mlxsw_reg_write(mlxsw_core, MLXSW_REG(mtutc), mtutc_pl);
 151}
 152
 153static u64 mlxsw_sp1_ptp_ns2cycles(const struct timecounter *tc, u64 nsec)
 154{
 155	u64 cycles = (u64) nsec;
 156
 157	cycles <<= tc->cc->shift;
 158	cycles = div_u64(cycles, tc->cc->mult);
 159
 160	return cycles;
 161}
 162
 163static int
 164mlxsw_sp1_ptp_phc_settime(struct mlxsw_sp1_ptp_clock *clock, u64 nsec)
 165{
 166	struct mlxsw_core *mlxsw_core = clock->common.core;
 167	u64 next_sec, next_sec_in_nsec, cycles;
 168	char mtutc_pl[MLXSW_REG_MTUTC_LEN];
 169	char mtpps_pl[MLXSW_REG_MTPPS_LEN];
 170	int err;
 171
 172	next_sec = div_u64(nsec, NSEC_PER_SEC) + 1;
 173	next_sec_in_nsec = next_sec * NSEC_PER_SEC;
 174
 175	spin_lock_bh(&clock->lock);
 176	cycles = mlxsw_sp1_ptp_ns2cycles(&clock->tc, next_sec_in_nsec);
 177	spin_unlock_bh(&clock->lock);
 178
 179	mlxsw_reg_mtpps_vpin_pack(mtpps_pl, cycles);
 180	err = mlxsw_reg_write(mlxsw_core, MLXSW_REG(mtpps), mtpps_pl);
 181	if (err)
 182		return err;
 183
 184	mlxsw_reg_mtutc_pack(mtutc_pl,
 185			     MLXSW_REG_MTUTC_OPERATION_SET_TIME_AT_NEXT_SEC,
 186			     0, next_sec, 0, 0);
 187	return mlxsw_reg_write(mlxsw_core, MLXSW_REG(mtutc), mtutc_pl);
 188}
 189
 190static int mlxsw_sp1_ptp_adjfine(struct ptp_clock_info *ptp, long scaled_ppm)
 191{
 192	struct mlxsw_sp1_ptp_clock *clock = mlxsw_sp1_ptp_clock(ptp);
 193	s32 ppb;
 194
 195	ppb = scaled_ppm_to_ppb(scaled_ppm);
 196
 197	spin_lock_bh(&clock->lock);
 198	timecounter_read(&clock->tc);
 199	clock->cycles.mult = adjust_by_scaled_ppm(clock->nominal_c_mult,
 200						  scaled_ppm);
 201	spin_unlock_bh(&clock->lock);
 202
 203	return mlxsw_sp_ptp_phc_adjfreq(&clock->common, ppb);
 204}
 205
 206static int mlxsw_sp1_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta)
 207{
 208	struct mlxsw_sp1_ptp_clock *clock = mlxsw_sp1_ptp_clock(ptp);
 209	u64 nsec;
 210
 211	spin_lock_bh(&clock->lock);
 212	timecounter_adjtime(&clock->tc, delta);
 213	nsec = timecounter_read(&clock->tc);
 214	spin_unlock_bh(&clock->lock);
 215
 216	return mlxsw_sp1_ptp_phc_settime(clock, nsec);
 217}
 218
 219static int mlxsw_sp1_ptp_gettimex(struct ptp_clock_info *ptp,
 220				  struct timespec64 *ts,
 221				  struct ptp_system_timestamp *sts)
 222{
 223	struct mlxsw_sp1_ptp_clock *clock = mlxsw_sp1_ptp_clock(ptp);
 224	u64 cycles, nsec;
 225
 226	spin_lock_bh(&clock->lock);
 227	cycles = __mlxsw_sp1_ptp_read_frc(clock, sts);
 228	nsec = timecounter_cyc2time(&clock->tc, cycles);
 229	spin_unlock_bh(&clock->lock);
 230
 231	*ts = ns_to_timespec64(nsec);
 232
 233	return 0;
 234}
 235
 236static int mlxsw_sp1_ptp_settime(struct ptp_clock_info *ptp,
 237				 const struct timespec64 *ts)
 238{
 239	struct mlxsw_sp1_ptp_clock *clock = mlxsw_sp1_ptp_clock(ptp);
 240	u64 nsec = timespec64_to_ns(ts);
 241
 242	spin_lock_bh(&clock->lock);
 243	timecounter_init(&clock->tc, &clock->cycles, nsec);
 244	nsec = timecounter_read(&clock->tc);
 245	spin_unlock_bh(&clock->lock);
 246
 247	return mlxsw_sp1_ptp_phc_settime(clock, nsec);
 248}
 249
 250static const struct ptp_clock_info mlxsw_sp1_ptp_clock_info = {
 251	.owner		= THIS_MODULE,
 252	.name		= "mlxsw_sp_clock",
 253	.max_adj	= 100000000,
 254	.adjfine	= mlxsw_sp1_ptp_adjfine,
 255	.adjtime	= mlxsw_sp1_ptp_adjtime,
 256	.gettimex64	= mlxsw_sp1_ptp_gettimex,
 257	.settime64	= mlxsw_sp1_ptp_settime,
 258};
 259
 260static void mlxsw_sp1_ptp_clock_overflow(struct work_struct *work)
 261{
 262	struct delayed_work *dwork = to_delayed_work(work);
 263	struct mlxsw_sp1_ptp_clock *clock;
 264
 265	clock = container_of(dwork, struct mlxsw_sp1_ptp_clock, overflow_work);
 266
 267	spin_lock_bh(&clock->lock);
 268	timecounter_read(&clock->tc);
 269	spin_unlock_bh(&clock->lock);
 270	mlxsw_core_schedule_dw(&clock->overflow_work, clock->overflow_period);
 271}
 272
 273struct mlxsw_sp_ptp_clock *
 274mlxsw_sp1_ptp_clock_init(struct mlxsw_sp *mlxsw_sp, struct device *dev)
 275{
 276	u64 overflow_cycles, nsec, frac = 0;
 277	struct mlxsw_sp1_ptp_clock *clock;
 278	int err;
 279
 280	clock = kzalloc(sizeof(*clock), GFP_KERNEL);
 281	if (!clock)
 282		return ERR_PTR(-ENOMEM);
 283
 284	spin_lock_init(&clock->lock);
 285	clock->cycles.read = mlxsw_sp1_ptp_read_frc;
 286	clock->cycles.shift = MLXSW_SP1_PTP_CLOCK_CYCLES_SHIFT;
 287	clock->cycles.mult = clocksource_khz2mult(MLXSW_SP1_PTP_CLOCK_FREQ_KHZ,
 288						  clock->cycles.shift);
 289	clock->nominal_c_mult = clock->cycles.mult;
 290	clock->cycles.mask = CLOCKSOURCE_MASK(MLXSW_SP1_PTP_CLOCK_MASK);
 291	clock->common.core = mlxsw_sp->core;
 292
 293	timecounter_init(&clock->tc, &clock->cycles, 0);
 294
 295	/* Calculate period in seconds to call the overflow watchdog - to make
 296	 * sure counter is checked at least twice every wrap around.
 297	 * The period is calculated as the minimum between max HW cycles count
 298	 * (The clock source mask) and max amount of cycles that can be
 299	 * multiplied by clock multiplier where the result doesn't exceed
 300	 * 64bits.
 301	 */
 302	overflow_cycles = div64_u64(~0ULL >> 1, clock->cycles.mult);
 303	overflow_cycles = min(overflow_cycles, div_u64(clock->cycles.mask, 3));
 304
 305	nsec = cyclecounter_cyc2ns(&clock->cycles, overflow_cycles, 0, &frac);
 306	clock->overflow_period = nsecs_to_jiffies(nsec);
 307
 308	INIT_DELAYED_WORK(&clock->overflow_work, mlxsw_sp1_ptp_clock_overflow);
 309	mlxsw_core_schedule_dw(&clock->overflow_work, 0);
 310
 311	clock->common.ptp_info = mlxsw_sp1_ptp_clock_info;
 312	clock->common.ptp = ptp_clock_register(&clock->common.ptp_info, dev);
 313	if (IS_ERR(clock->common.ptp)) {
 314		err = PTR_ERR(clock->common.ptp);
 315		dev_err(dev, "ptp_clock_register failed %d\n", err);
 316		goto err_ptp_clock_register;
 317	}
 318
 319	return &clock->common;
 320
 321err_ptp_clock_register:
 322	cancel_delayed_work_sync(&clock->overflow_work);
 323	kfree(clock);
 324	return ERR_PTR(err);
 325}
 326
 327void mlxsw_sp1_ptp_clock_fini(struct mlxsw_sp_ptp_clock *clock_common)
 328{
 329	struct mlxsw_sp1_ptp_clock *clock =
 330		container_of(clock_common, struct mlxsw_sp1_ptp_clock, common);
 331
 332	ptp_clock_unregister(clock_common->ptp);
 333	cancel_delayed_work_sync(&clock->overflow_work);
 334	kfree(clock);
 335}
 336
 337static u64 mlxsw_sp2_ptp_read_utc(struct mlxsw_sp_ptp_clock *clock,
 338				  struct ptp_system_timestamp *sts)
 339{
 340	struct mlxsw_core *mlxsw_core = clock->core;
 341	u32 utc_sec1, utc_sec2, utc_nsec;
 342
 343	utc_sec1 = mlxsw_core_read_utc_sec(mlxsw_core);
 344	ptp_read_system_prets(sts);
 345	utc_nsec = mlxsw_core_read_utc_nsec(mlxsw_core);
 346	ptp_read_system_postts(sts);
 347	utc_sec2 = mlxsw_core_read_utc_sec(mlxsw_core);
 348
 349	if (utc_sec1 != utc_sec2) {
 350		/* Wrap around. */
 351		ptp_read_system_prets(sts);
 352		utc_nsec = mlxsw_core_read_utc_nsec(mlxsw_core);
 353		ptp_read_system_postts(sts);
 354	}
 355
 356	return (u64)utc_sec2 * NSEC_PER_SEC + utc_nsec;
 357}
 358
 359static int
 360mlxsw_sp2_ptp_phc_settime(struct mlxsw_sp_ptp_clock *clock, u64 nsec)
 361{
 362	struct mlxsw_core *mlxsw_core = clock->core;
 363	char mtutc_pl[MLXSW_REG_MTUTC_LEN];
 364	u32 sec, nsec_rem;
 365
 366	sec = div_u64_rem(nsec, NSEC_PER_SEC, &nsec_rem);
 367	mlxsw_reg_mtutc_pack(mtutc_pl,
 368			     MLXSW_REG_MTUTC_OPERATION_SET_TIME_IMMEDIATE,
 369			     0, sec, nsec_rem, 0);
 370	return mlxsw_reg_write(mlxsw_core, MLXSW_REG(mtutc), mtutc_pl);
 371}
 372
 373static int mlxsw_sp2_ptp_adjfine(struct ptp_clock_info *ptp, long scaled_ppm)
 374{
 375	struct mlxsw_sp_ptp_clock *clock =
 376		container_of(ptp, struct mlxsw_sp_ptp_clock, ptp_info);
 377	s32 ppb = scaled_ppm_to_ppb(scaled_ppm);
 378
 379	/* In Spectrum-2 and newer ASICs, the frequency adjustment in MTUTC is
 380	 * reversed, positive values mean to decrease the frequency. Adjust the
 381	 * sign of PPB to this behavior.
 382	 */
 383	return mlxsw_sp_ptp_phc_adjfreq(clock, -ppb);
 384}
 385
 386static int mlxsw_sp2_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta)
 387{
 388	struct mlxsw_sp_ptp_clock *clock =
 389		container_of(ptp, struct mlxsw_sp_ptp_clock, ptp_info);
 390	struct mlxsw_core *mlxsw_core = clock->core;
 391	char mtutc_pl[MLXSW_REG_MTUTC_LEN];
 392
 393	/* HW time adjustment range is s16. If out of range, set time instead. */
 394	if (delta < S16_MIN || delta > S16_MAX) {
 395		u64 nsec;
 396
 397		nsec = mlxsw_sp2_ptp_read_utc(clock, NULL);
 398		nsec += delta;
 399
 400		return mlxsw_sp2_ptp_phc_settime(clock, nsec);
 401	}
 402
 403	mlxsw_reg_mtutc_pack(mtutc_pl,
 404			     MLXSW_REG_MTUTC_OPERATION_ADJUST_TIME,
 405			     0, 0, 0, delta);
 406	return mlxsw_reg_write(mlxsw_core, MLXSW_REG(mtutc), mtutc_pl);
 407}
 408
 409static int mlxsw_sp2_ptp_gettimex(struct ptp_clock_info *ptp,
 410				  struct timespec64 *ts,
 411				  struct ptp_system_timestamp *sts)
 412{
 413	struct mlxsw_sp_ptp_clock *clock =
 414		container_of(ptp, struct mlxsw_sp_ptp_clock, ptp_info);
 415	u64 nsec;
 416
 417	nsec = mlxsw_sp2_ptp_read_utc(clock, sts);
 418	*ts = ns_to_timespec64(nsec);
 419
 420	return 0;
 421}
 422
 423static int mlxsw_sp2_ptp_settime(struct ptp_clock_info *ptp,
 424				 const struct timespec64 *ts)
 425{
 426	struct mlxsw_sp_ptp_clock *clock =
 427		container_of(ptp, struct mlxsw_sp_ptp_clock, ptp_info);
 428	u64 nsec = timespec64_to_ns(ts);
 429
 430	return mlxsw_sp2_ptp_phc_settime(clock, nsec);
 431}
 432
 433static const struct ptp_clock_info mlxsw_sp2_ptp_clock_info = {
 434	.owner		= THIS_MODULE,
 435	.name		= "mlxsw_sp_clock",
 436	.max_adj	= MLXSW_REG_MTUTC_MAX_FREQ_ADJ,
 437	.adjfine	= mlxsw_sp2_ptp_adjfine,
 438	.adjtime	= mlxsw_sp2_ptp_adjtime,
 439	.gettimex64	= mlxsw_sp2_ptp_gettimex,
 440	.settime64	= mlxsw_sp2_ptp_settime,
 441};
 442
 443struct mlxsw_sp_ptp_clock *
 444mlxsw_sp2_ptp_clock_init(struct mlxsw_sp *mlxsw_sp, struct device *dev)
 445{
 446	struct mlxsw_sp_ptp_clock *clock;
 447	int err;
 448
 449	clock = kzalloc(sizeof(*clock), GFP_KERNEL);
 450	if (!clock)
 451		return ERR_PTR(-ENOMEM);
 452
 453	clock->core = mlxsw_sp->core;
 454
 455	clock->ptp_info = mlxsw_sp2_ptp_clock_info;
 456
 457	err = mlxsw_sp2_ptp_phc_settime(clock, 0);
 458	if (err) {
 459		dev_err(dev, "setting UTC time failed %d\n", err);
 460		goto err_ptp_phc_settime;
 461	}
 462
 463	clock->ptp = ptp_clock_register(&clock->ptp_info, dev);
 464	if (IS_ERR(clock->ptp)) {
 465		err = PTR_ERR(clock->ptp);
 466		dev_err(dev, "ptp_clock_register failed %d\n", err);
 467		goto err_ptp_clock_register;
 468	}
 469
 470	return clock;
 471
 472err_ptp_clock_register:
 473err_ptp_phc_settime:
 474	kfree(clock);
 475	return ERR_PTR(err);
 476}
 477
 478void mlxsw_sp2_ptp_clock_fini(struct mlxsw_sp_ptp_clock *clock)
 479{
 480	ptp_clock_unregister(clock->ptp);
 481	kfree(clock);
 482}
 483
 484static int mlxsw_sp_ptp_parse(struct sk_buff *skb,
 485			      u8 *p_domain_number,
 486			      u8 *p_message_type,
 487			      u16 *p_sequence_id)
 488{
 489	unsigned int ptp_class;
 490	struct ptp_header *hdr;
 491
 492	ptp_class = ptp_classify_raw(skb);
 493
 494	switch (ptp_class & PTP_CLASS_VMASK) {
 495	case PTP_CLASS_V1:
 496	case PTP_CLASS_V2:
 497		break;
 498	default:
 499		return -ERANGE;
 500	}
 501
 502	hdr = ptp_parse_header(skb, ptp_class);
 503	if (!hdr)
 504		return -EINVAL;
 505
 506	*p_message_type	 = ptp_get_msgtype(hdr, ptp_class);
 507	*p_domain_number = hdr->domain_number;
 508	*p_sequence_id	 = be16_to_cpu(hdr->sequence_id);
 509
 510	return 0;
 511}
 512
 513/* Returns NULL on successful insertion, a pointer on conflict, or an ERR_PTR on
 514 * error.
 515 */
 516static int
 517mlxsw_sp1_ptp_unmatched_save(struct mlxsw_sp *mlxsw_sp,
 518			     struct mlxsw_sp1_ptp_key key,
 519			     struct sk_buff *skb,
 520			     u64 timestamp)
 521{
 522	int cycles = MLXSW_SP1_PTP_HT_GC_TIMEOUT / MLXSW_SP1_PTP_HT_GC_INTERVAL;
 523	struct mlxsw_sp1_ptp_state *ptp_state = mlxsw_sp1_ptp_state(mlxsw_sp);
 524	struct mlxsw_sp1_ptp_unmatched *unmatched;
 525	int err;
 526
 527	unmatched = kzalloc(sizeof(*unmatched), GFP_ATOMIC);
 528	if (!unmatched)
 529		return -ENOMEM;
 530
 531	unmatched->key = key;
 532	unmatched->skb = skb;
 533	unmatched->timestamp = timestamp;
 534	unmatched->gc_cycle = ptp_state->gc_cycle + cycles;
 535
 536	err = rhltable_insert(&ptp_state->unmatched_ht, &unmatched->ht_node,
 537			      mlxsw_sp1_ptp_unmatched_ht_params);
 538	if (err)
 539		kfree(unmatched);
 540
 541	return err;
 542}
 543
 544static struct mlxsw_sp1_ptp_unmatched *
 545mlxsw_sp1_ptp_unmatched_lookup(struct mlxsw_sp *mlxsw_sp,
 546			       struct mlxsw_sp1_ptp_key key, int *p_length)
 547{
 548	struct mlxsw_sp1_ptp_state *ptp_state = mlxsw_sp1_ptp_state(mlxsw_sp);
 549	struct mlxsw_sp1_ptp_unmatched *unmatched, *last = NULL;
 550	struct rhlist_head *tmp, *list;
 551	int length = 0;
 552
 553	list = rhltable_lookup(&ptp_state->unmatched_ht, &key,
 554			       mlxsw_sp1_ptp_unmatched_ht_params);
 555	rhl_for_each_entry_rcu(unmatched, tmp, list, ht_node) {
 556		last = unmatched;
 557		length++;
 558	}
 559
 560	*p_length = length;
 561	return last;
 562}
 563
 564static int
 565mlxsw_sp1_ptp_unmatched_remove(struct mlxsw_sp *mlxsw_sp,
 566			       struct mlxsw_sp1_ptp_unmatched *unmatched)
 567{
 568	struct mlxsw_sp1_ptp_state *ptp_state = mlxsw_sp1_ptp_state(mlxsw_sp);
 569
 570	return rhltable_remove(&ptp_state->unmatched_ht,
 571			       &unmatched->ht_node,
 572			       mlxsw_sp1_ptp_unmatched_ht_params);
 573}
 574
 575/* This function is called in the following scenarios:
 576 *
 577 * 1) When a packet is matched with its timestamp.
 578 * 2) In several situation when it is necessary to immediately pass on
 579 *    an SKB without a timestamp.
 580 * 3) From GC indirectly through mlxsw_sp1_ptp_unmatched_finish().
 581 *    This case is similar to 2) above.
 582 */
 583static void mlxsw_sp1_ptp_packet_finish(struct mlxsw_sp *mlxsw_sp,
 584					struct sk_buff *skb, u16 local_port,
 585					bool ingress,
 586					struct skb_shared_hwtstamps *hwtstamps)
 587{
 588	struct mlxsw_sp_port *mlxsw_sp_port;
 589
 590	/* Between capturing the packet and finishing it, there is a window of
 591	 * opportunity for the originating port to go away (e.g. due to a
 592	 * split). Also make sure the SKB device reference is still valid.
 593	 */
 594	mlxsw_sp_port = mlxsw_sp->ports[local_port];
 595	if (!(mlxsw_sp_port && (!skb->dev || skb->dev == mlxsw_sp_port->dev))) {
 596		dev_kfree_skb_any(skb);
 597		return;
 598	}
 599
 600	if (ingress) {
 601		if (hwtstamps)
 602			*skb_hwtstamps(skb) = *hwtstamps;
 603		mlxsw_sp_rx_listener_no_mark_func(skb, local_port, mlxsw_sp);
 604	} else {
 605		/* skb_tstamp_tx() allows hwtstamps to be NULL. */
 606		skb_tstamp_tx(skb, hwtstamps);
 607		dev_kfree_skb_any(skb);
 608	}
 609}
 610
 611static void mlxsw_sp1_packet_timestamp(struct mlxsw_sp *mlxsw_sp,
 612				       struct mlxsw_sp1_ptp_key key,
 613				       struct sk_buff *skb,
 614				       u64 timestamp)
 615{
 616	struct mlxsw_sp_ptp_clock *clock_common = mlxsw_sp->clock;
 617	struct mlxsw_sp1_ptp_clock *clock =
 618		container_of(clock_common, struct mlxsw_sp1_ptp_clock, common);
 619
 620	struct skb_shared_hwtstamps hwtstamps;
 621	u64 nsec;
 622
 623	spin_lock_bh(&clock->lock);
 624	nsec = timecounter_cyc2time(&clock->tc, timestamp);
 625	spin_unlock_bh(&clock->lock);
 626
 627	hwtstamps.hwtstamp = ns_to_ktime(nsec);
 628	mlxsw_sp1_ptp_packet_finish(mlxsw_sp, skb,
 629				    key.local_port, key.ingress, &hwtstamps);
 630}
 631
 632static void
 633mlxsw_sp1_ptp_unmatched_finish(struct mlxsw_sp *mlxsw_sp,
 634			       struct mlxsw_sp1_ptp_unmatched *unmatched)
 635{
 636	if (unmatched->skb && unmatched->timestamp)
 637		mlxsw_sp1_packet_timestamp(mlxsw_sp, unmatched->key,
 638					   unmatched->skb,
 639					   unmatched->timestamp);
 640	else if (unmatched->skb)
 641		mlxsw_sp1_ptp_packet_finish(mlxsw_sp, unmatched->skb,
 642					    unmatched->key.local_port,
 643					    unmatched->key.ingress, NULL);
 644	kfree_rcu(unmatched, rcu);
 645}
 646
 647static void mlxsw_sp1_ptp_unmatched_free_fn(void *ptr, void *arg)
 648{
 649	struct mlxsw_sp1_ptp_unmatched *unmatched = ptr;
 650
 651	/* This is invoked at a point where the ports are gone already. Nothing
 652	 * to do with whatever is left in the HT but to free it.
 653	 */
 654	if (unmatched->skb)
 655		dev_kfree_skb_any(unmatched->skb);
 656	kfree_rcu(unmatched, rcu);
 657}
 658
 659static void mlxsw_sp1_ptp_got_piece(struct mlxsw_sp *mlxsw_sp,
 660				    struct mlxsw_sp1_ptp_key key,
 661				    struct sk_buff *skb, u64 timestamp)
 662{
 663	struct mlxsw_sp1_ptp_state *ptp_state = mlxsw_sp1_ptp_state(mlxsw_sp);
 664	struct mlxsw_sp1_ptp_unmatched *unmatched;
 665	int length;
 666	int err;
 667
 668	rcu_read_lock();
 669
 670	spin_lock(&ptp_state->unmatched_lock);
 671
 672	unmatched = mlxsw_sp1_ptp_unmatched_lookup(mlxsw_sp, key, &length);
 673	if (skb && unmatched && unmatched->timestamp) {
 674		unmatched->skb = skb;
 675	} else if (timestamp && unmatched && unmatched->skb) {
 676		unmatched->timestamp = timestamp;
 677	} else {
 678		/* Either there is no entry to match, or one that is there is
 679		 * incompatible.
 680		 */
 681		if (length < 100)
 682			err = mlxsw_sp1_ptp_unmatched_save(mlxsw_sp, key,
 683							   skb, timestamp);
 684		else
 685			err = -E2BIG;
 686		if (err && skb)
 687			mlxsw_sp1_ptp_packet_finish(mlxsw_sp, skb,
 688						    key.local_port,
 689						    key.ingress, NULL);
 690		unmatched = NULL;
 691	}
 692
 693	if (unmatched) {
 694		err = mlxsw_sp1_ptp_unmatched_remove(mlxsw_sp, unmatched);
 695		WARN_ON_ONCE(err);
 696	}
 697
 698	spin_unlock(&ptp_state->unmatched_lock);
 699
 700	if (unmatched)
 701		mlxsw_sp1_ptp_unmatched_finish(mlxsw_sp, unmatched);
 702
 703	rcu_read_unlock();
 704}
 705
 706static void mlxsw_sp1_ptp_got_packet(struct mlxsw_sp *mlxsw_sp,
 707				     struct sk_buff *skb, u16 local_port,
 708				     bool ingress)
 709{
 710	struct mlxsw_sp_port *mlxsw_sp_port;
 711	struct mlxsw_sp1_ptp_key key;
 712	u8 types;
 713	int err;
 714
 715	mlxsw_sp_port = mlxsw_sp->ports[local_port];
 716	if (!mlxsw_sp_port)
 717		goto immediate;
 718
 719	types = ingress ? mlxsw_sp_port->ptp.ing_types :
 720			  mlxsw_sp_port->ptp.egr_types;
 721	if (!types)
 722		goto immediate;
 723
 724	memset(&key, 0, sizeof(key));
 725	key.local_port = local_port;
 726	key.ingress = ingress;
 727
 728	err = mlxsw_sp_ptp_parse(skb, &key.domain_number, &key.message_type,
 729				 &key.sequence_id);
 730	if (err)
 731		goto immediate;
 732
 733	/* For packets whose timestamping was not enabled on this port, don't
 734	 * bother trying to match the timestamp.
 735	 */
 736	if (!((1 << key.message_type) & types))
 737		goto immediate;
 738
 739	mlxsw_sp1_ptp_got_piece(mlxsw_sp, key, skb, 0);
 740	return;
 741
 742immediate:
 743	mlxsw_sp1_ptp_packet_finish(mlxsw_sp, skb, local_port, ingress, NULL);
 744}
 745
 746void mlxsw_sp1_ptp_got_timestamp(struct mlxsw_sp *mlxsw_sp, bool ingress,
 747				 u16 local_port, u8 message_type,
 748				 u8 domain_number, u16 sequence_id,
 749				 u64 timestamp)
 750{
 751	struct mlxsw_sp_port *mlxsw_sp_port;
 752	struct mlxsw_sp1_ptp_key key;
 753	u8 types;
 754
 755	if (WARN_ON_ONCE(!mlxsw_sp_local_port_is_valid(mlxsw_sp, local_port)))
 756		return;
 757	mlxsw_sp_port = mlxsw_sp->ports[local_port];
 758	if (!mlxsw_sp_port)
 759		return;
 760
 761	types = ingress ? mlxsw_sp_port->ptp.ing_types :
 762			  mlxsw_sp_port->ptp.egr_types;
 763
 764	/* For message types whose timestamping was not enabled on this port,
 765	 * don't bother with the timestamp.
 766	 */
 767	if (!((1 << message_type) & types))
 768		return;
 769
 770	memset(&key, 0, sizeof(key));
 771	key.local_port = local_port;
 772	key.domain_number = domain_number;
 773	key.message_type = message_type;
 774	key.sequence_id = sequence_id;
 775	key.ingress = ingress;
 776
 777	mlxsw_sp1_ptp_got_piece(mlxsw_sp, key, NULL, timestamp);
 778}
 779
 780void mlxsw_sp1_ptp_receive(struct mlxsw_sp *mlxsw_sp, struct sk_buff *skb,
 781			   u16 local_port)
 782{
 783	skb_reset_mac_header(skb);
 784	mlxsw_sp1_ptp_got_packet(mlxsw_sp, skb, local_port, true);
 785}
 786
 787void mlxsw_sp1_ptp_transmitted(struct mlxsw_sp *mlxsw_sp,
 788			       struct sk_buff *skb, u16 local_port)
 789{
 790	mlxsw_sp1_ptp_got_packet(mlxsw_sp, skb, local_port, false);
 791}
 792
 793static void
 794mlxsw_sp1_ptp_ht_gc_collect(struct mlxsw_sp1_ptp_state *ptp_state,
 795			    struct mlxsw_sp1_ptp_unmatched *unmatched)
 796{
 797	struct mlxsw_sp *mlxsw_sp = ptp_state->common.mlxsw_sp;
 798	struct mlxsw_sp_ptp_port_dir_stats *stats;
 799	struct mlxsw_sp_port *mlxsw_sp_port;
 800	int err;
 801
 802	/* If an unmatched entry has an SKB, it has to be handed over to the
 803	 * networking stack. This is usually done from a trap handler, which is
 804	 * invoked in a softirq context. Here we are going to do it in process
 805	 * context. If that were to be interrupted by a softirq, it could cause
 806	 * a deadlock when an attempt is made to take an already-taken lock
 807	 * somewhere along the sending path. Disable softirqs to prevent this.
 808	 */
 809	local_bh_disable();
 810
 811	spin_lock(&ptp_state->unmatched_lock);
 812	err = rhltable_remove(&ptp_state->unmatched_ht, &unmatched->ht_node,
 813			      mlxsw_sp1_ptp_unmatched_ht_params);
 814	spin_unlock(&ptp_state->unmatched_lock);
 815
 816	if (err)
 817		/* The packet was matched with timestamp during the walk. */
 818		goto out;
 819
 820	mlxsw_sp_port = mlxsw_sp->ports[unmatched->key.local_port];
 821	if (mlxsw_sp_port) {
 822		stats = unmatched->key.ingress ?
 823			&mlxsw_sp_port->ptp.stats.rx_gcd :
 824			&mlxsw_sp_port->ptp.stats.tx_gcd;
 825		if (unmatched->skb)
 826			stats->packets++;
 827		else
 828			stats->timestamps++;
 829	}
 830
 831	/* mlxsw_sp1_ptp_unmatched_finish() invokes netif_receive_skb(). While
 832	 * the comment at that function states that it can only be called in
 833	 * soft IRQ context, this pattern of local_bh_disable() +
 834	 * netif_receive_skb(), in process context, is seen elsewhere in the
 835	 * kernel, notably in pktgen.
 836	 */
 837	mlxsw_sp1_ptp_unmatched_finish(mlxsw_sp, unmatched);
 838
 839out:
 840	local_bh_enable();
 841}
 842
 843static void mlxsw_sp1_ptp_ht_gc(struct work_struct *work)
 844{
 845	struct delayed_work *dwork = to_delayed_work(work);
 846	struct mlxsw_sp1_ptp_unmatched *unmatched;
 847	struct mlxsw_sp1_ptp_state *ptp_state;
 848	struct rhashtable_iter iter;
 849	u32 gc_cycle;
 850	void *obj;
 851
 852	ptp_state = container_of(dwork, struct mlxsw_sp1_ptp_state, ht_gc_dw);
 853	gc_cycle = ptp_state->gc_cycle++;
 854
 855	rhltable_walk_enter(&ptp_state->unmatched_ht, &iter);
 856	rhashtable_walk_start(&iter);
 857	while ((obj = rhashtable_walk_next(&iter))) {
 858		if (IS_ERR(obj))
 859			continue;
 860
 861		unmatched = obj;
 862		if (unmatched->gc_cycle <= gc_cycle)
 863			mlxsw_sp1_ptp_ht_gc_collect(ptp_state, unmatched);
 864	}
 865	rhashtable_walk_stop(&iter);
 866	rhashtable_walk_exit(&iter);
 867
 868	mlxsw_core_schedule_dw(&ptp_state->ht_gc_dw,
 869			       MLXSW_SP1_PTP_HT_GC_INTERVAL);
 870}
 871
 872static int mlxsw_sp_ptp_mtptpt_set(struct mlxsw_sp *mlxsw_sp,
 873				   enum mlxsw_reg_mtptpt_trap_id trap_id,
 874				   u16 message_type)
 875{
 876	char mtptpt_pl[MLXSW_REG_MTPTPT_LEN];
 877
 878	mlxsw_reg_mtptpt_pack(mtptpt_pl, trap_id, message_type);
 879	return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(mtptpt), mtptpt_pl);
 880}
 881
 882static int mlxsw_sp1_ptp_set_fifo_clr_on_trap(struct mlxsw_sp *mlxsw_sp,
 883					      bool clr)
 884{
 885	char mogcr_pl[MLXSW_REG_MOGCR_LEN] = {0};
 886	int err;
 887
 888	err = mlxsw_reg_query(mlxsw_sp->core, MLXSW_REG(mogcr), mogcr_pl);
 889	if (err)
 890		return err;
 891
 892	mlxsw_reg_mogcr_ptp_iftc_set(mogcr_pl, clr);
 893	mlxsw_reg_mogcr_ptp_eftc_set(mogcr_pl, clr);
 894	return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(mogcr), mogcr_pl);
 895}
 896
 897static int mlxsw_sp1_ptp_mtpppc_set(struct mlxsw_sp *mlxsw_sp,
 898				    u16 ing_types, u16 egr_types)
 899{
 900	char mtpppc_pl[MLXSW_REG_MTPPPC_LEN];
 901
 902	mlxsw_reg_mtpppc_pack(mtpppc_pl, ing_types, egr_types);
 903	return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(mtpppc), mtpppc_pl);
 904}
 905
 906struct mlxsw_sp1_ptp_shaper_params {
 907	u32 ethtool_speed;
 908	enum mlxsw_reg_qpsc_port_speed port_speed;
 909	u8 shaper_time_exp;
 910	u8 shaper_time_mantissa;
 911	u8 shaper_inc;
 912	u8 shaper_bs;
 913	u8 port_to_shaper_credits;
 914	int ing_timestamp_inc;
 915	int egr_timestamp_inc;
 916};
 917
 918static const struct mlxsw_sp1_ptp_shaper_params
 919mlxsw_sp1_ptp_shaper_params[] = {
 920	{
 921		.ethtool_speed		= SPEED_100,
 922		.port_speed		= MLXSW_REG_QPSC_PORT_SPEED_100M,
 923		.shaper_time_exp	= 4,
 924		.shaper_time_mantissa	= 12,
 925		.shaper_inc		= 9,
 926		.shaper_bs		= 1,
 927		.port_to_shaper_credits	= 1,
 928		.ing_timestamp_inc	= -313,
 929		.egr_timestamp_inc	= 313,
 930	},
 931	{
 932		.ethtool_speed		= SPEED_1000,
 933		.port_speed		= MLXSW_REG_QPSC_PORT_SPEED_1G,
 934		.shaper_time_exp	= 0,
 935		.shaper_time_mantissa	= 12,
 936		.shaper_inc		= 6,
 937		.shaper_bs		= 0,
 938		.port_to_shaper_credits	= 1,
 939		.ing_timestamp_inc	= -35,
 940		.egr_timestamp_inc	= 35,
 941	},
 942	{
 943		.ethtool_speed		= SPEED_10000,
 944		.port_speed		= MLXSW_REG_QPSC_PORT_SPEED_10G,
 945		.shaper_time_exp	= 0,
 946		.shaper_time_mantissa	= 2,
 947		.shaper_inc		= 14,
 948		.shaper_bs		= 1,
 949		.port_to_shaper_credits	= 1,
 950		.ing_timestamp_inc	= -11,
 951		.egr_timestamp_inc	= 11,
 952	},
 953	{
 954		.ethtool_speed		= SPEED_25000,
 955		.port_speed		= MLXSW_REG_QPSC_PORT_SPEED_25G,
 956		.shaper_time_exp	= 0,
 957		.shaper_time_mantissa	= 0,
 958		.shaper_inc		= 11,
 959		.shaper_bs		= 1,
 960		.port_to_shaper_credits	= 1,
 961		.ing_timestamp_inc	= -14,
 962		.egr_timestamp_inc	= 14,
 963	},
 964};
 965
 966#define MLXSW_SP1_PTP_SHAPER_PARAMS_LEN ARRAY_SIZE(mlxsw_sp1_ptp_shaper_params)
 967
 968static int mlxsw_sp1_ptp_shaper_params_set(struct mlxsw_sp *mlxsw_sp)
 969{
 970	const struct mlxsw_sp1_ptp_shaper_params *params;
 971	char qpsc_pl[MLXSW_REG_QPSC_LEN];
 972	int i, err;
 973
 974	for (i = 0; i < MLXSW_SP1_PTP_SHAPER_PARAMS_LEN; i++) {
 975		params = &mlxsw_sp1_ptp_shaper_params[i];
 976		mlxsw_reg_qpsc_pack(qpsc_pl, params->port_speed,
 977				    params->shaper_time_exp,
 978				    params->shaper_time_mantissa,
 979				    params->shaper_inc, params->shaper_bs,
 980				    params->port_to_shaper_credits,
 981				    params->ing_timestamp_inc,
 982				    params->egr_timestamp_inc);
 983		err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(qpsc), qpsc_pl);
 984		if (err)
 985			return err;
 986	}
 987
 988	return 0;
 989}
 990
 991static int mlxsw_sp_ptp_traps_set(struct mlxsw_sp *mlxsw_sp)
 992{
 993	u16 event_message_type;
 994	int err;
 995
 996	/* Deliver these message types as PTP0. */
 997	event_message_type = BIT(PTP_MSGTYPE_SYNC) |
 998			     BIT(PTP_MSGTYPE_DELAY_REQ) |
 999			     BIT(PTP_MSGTYPE_PDELAY_REQ) |
1000			     BIT(PTP_MSGTYPE_PDELAY_RESP);
1001
1002	err = mlxsw_sp_ptp_mtptpt_set(mlxsw_sp, MLXSW_REG_MTPTPT_TRAP_ID_PTP0,
1003				      event_message_type);
1004	if (err)
1005		return err;
1006
1007	/* Everything else is PTP1. */
1008	err = mlxsw_sp_ptp_mtptpt_set(mlxsw_sp, MLXSW_REG_MTPTPT_TRAP_ID_PTP1,
1009				      ~event_message_type);
1010	if (err)
1011		goto err_mtptpt1_set;
1012
1013	return 0;
1014
1015err_mtptpt1_set:
1016	mlxsw_sp_ptp_mtptpt_set(mlxsw_sp, MLXSW_REG_MTPTPT_TRAP_ID_PTP0, 0);
1017	return err;
1018}
1019
1020static void mlxsw_sp_ptp_traps_unset(struct mlxsw_sp *mlxsw_sp)
1021{
1022	mlxsw_sp_ptp_mtptpt_set(mlxsw_sp, MLXSW_REG_MTPTPT_TRAP_ID_PTP1, 0);
1023	mlxsw_sp_ptp_mtptpt_set(mlxsw_sp, MLXSW_REG_MTPTPT_TRAP_ID_PTP0, 0);
1024}
1025
1026struct mlxsw_sp_ptp_state *mlxsw_sp1_ptp_init(struct mlxsw_sp *mlxsw_sp)
1027{
1028	struct mlxsw_sp1_ptp_state *ptp_state;
1029	int err;
1030
1031	err = mlxsw_sp1_ptp_shaper_params_set(mlxsw_sp);
1032	if (err)
1033		return ERR_PTR(err);
1034
1035	ptp_state = kzalloc(sizeof(*ptp_state), GFP_KERNEL);
1036	if (!ptp_state)
1037		return ERR_PTR(-ENOMEM);
1038	ptp_state->common.mlxsw_sp = mlxsw_sp;
1039
1040	spin_lock_init(&ptp_state->unmatched_lock);
1041
1042	err = rhltable_init(&ptp_state->unmatched_ht,
1043			    &mlxsw_sp1_ptp_unmatched_ht_params);
1044	if (err)
1045		goto err_hashtable_init;
1046
1047	err = mlxsw_sp_ptp_traps_set(mlxsw_sp);
1048	if (err)
1049		goto err_ptp_traps_set;
1050
1051	err = mlxsw_sp1_ptp_set_fifo_clr_on_trap(mlxsw_sp, true);
1052	if (err)
1053		goto err_fifo_clr;
1054
1055	INIT_DELAYED_WORK(&ptp_state->ht_gc_dw, mlxsw_sp1_ptp_ht_gc);
1056	mlxsw_core_schedule_dw(&ptp_state->ht_gc_dw,
1057			       MLXSW_SP1_PTP_HT_GC_INTERVAL);
1058	return &ptp_state->common;
1059
1060err_fifo_clr:
1061	mlxsw_sp_ptp_traps_unset(mlxsw_sp);
1062err_ptp_traps_set:
1063	rhltable_destroy(&ptp_state->unmatched_ht);
1064err_hashtable_init:
1065	kfree(ptp_state);
1066	return ERR_PTR(err);
1067}
1068
1069void mlxsw_sp1_ptp_fini(struct mlxsw_sp_ptp_state *ptp_state_common)
1070{
1071	struct mlxsw_sp *mlxsw_sp = ptp_state_common->mlxsw_sp;
1072	struct mlxsw_sp1_ptp_state *ptp_state;
1073
1074	ptp_state = mlxsw_sp1_ptp_state(mlxsw_sp);
1075
1076	cancel_delayed_work_sync(&ptp_state->ht_gc_dw);
1077	mlxsw_sp1_ptp_mtpppc_set(mlxsw_sp, 0, 0);
1078	mlxsw_sp1_ptp_set_fifo_clr_on_trap(mlxsw_sp, false);
1079	mlxsw_sp_ptp_traps_unset(mlxsw_sp);
1080	rhltable_free_and_destroy(&ptp_state->unmatched_ht,
1081				  &mlxsw_sp1_ptp_unmatched_free_fn, NULL);
1082	kfree(ptp_state);
1083}
1084
1085int mlxsw_sp1_ptp_hwtstamp_get(struct mlxsw_sp_port *mlxsw_sp_port,
1086			       struct kernel_hwtstamp_config *config)
1087{
1088	*config = mlxsw_sp_port->ptp.hwtstamp_config;
1089	return 0;
1090}
1091
1092static int
1093mlxsw_sp1_ptp_get_message_types(const struct kernel_hwtstamp_config *config,
1094				u16 *p_ing_types, u16 *p_egr_types,
1095				enum hwtstamp_rx_filters *p_rx_filter)
1096{
1097	enum hwtstamp_rx_filters rx_filter = config->rx_filter;
1098	enum hwtstamp_tx_types tx_type = config->tx_type;
1099	u16 ing_types = 0x00;
1100	u16 egr_types = 0x00;
1101
1102	switch (tx_type) {
1103	case HWTSTAMP_TX_OFF:
1104		egr_types = 0x00;
1105		break;
1106	case HWTSTAMP_TX_ON:
1107		egr_types = 0xff;
1108		break;
1109	case HWTSTAMP_TX_ONESTEP_SYNC:
1110	case HWTSTAMP_TX_ONESTEP_P2P:
1111		return -ERANGE;
1112	default:
1113		return -EINVAL;
1114	}
1115
1116	switch (rx_filter) {
1117	case HWTSTAMP_FILTER_NONE:
1118		ing_types = 0x00;
1119		break;
1120	case HWTSTAMP_FILTER_PTP_V1_L4_SYNC:
1121	case HWTSTAMP_FILTER_PTP_V2_L4_SYNC:
1122	case HWTSTAMP_FILTER_PTP_V2_L2_SYNC:
1123	case HWTSTAMP_FILTER_PTP_V2_SYNC:
1124		ing_types = 0x01;
1125		break;
1126	case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ:
1127	case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ:
1128	case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ:
1129	case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ:
1130		ing_types = 0x02;
1131		break;
1132	case HWTSTAMP_FILTER_PTP_V1_L4_EVENT:
1133	case HWTSTAMP_FILTER_PTP_V2_L4_EVENT:
1134	case HWTSTAMP_FILTER_PTP_V2_L2_EVENT:
1135	case HWTSTAMP_FILTER_PTP_V2_EVENT:
1136		ing_types = 0x0f;
1137		break;
1138	case HWTSTAMP_FILTER_ALL:
1139		ing_types = 0xff;
1140		break;
1141	case HWTSTAMP_FILTER_SOME:
1142	case HWTSTAMP_FILTER_NTP_ALL:
1143		return -ERANGE;
1144	default:
1145		return -EINVAL;
1146	}
1147
1148	*p_ing_types = ing_types;
1149	*p_egr_types = egr_types;
1150	*p_rx_filter = rx_filter;
1151	return 0;
1152}
1153
1154static int mlxsw_sp1_ptp_mtpppc_update(struct mlxsw_sp_port *mlxsw_sp_port,
1155				       u16 ing_types, u16 egr_types)
1156{
1157	struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
1158	struct mlxsw_sp_port *tmp;
1159	u16 orig_ing_types = 0;
1160	u16 orig_egr_types = 0;
1161	int err;
1162	int i;
1163
1164	/* MTPPPC configures timestamping globally, not per port. Find the
1165	 * configuration that contains all configured timestamping requests.
1166	 */
1167	for (i = 1; i < mlxsw_core_max_ports(mlxsw_sp->core); i++) {
1168		tmp = mlxsw_sp->ports[i];
1169		if (tmp) {
1170			orig_ing_types |= tmp->ptp.ing_types;
1171			orig_egr_types |= tmp->ptp.egr_types;
1172		}
1173		if (tmp && tmp != mlxsw_sp_port) {
1174			ing_types |= tmp->ptp.ing_types;
1175			egr_types |= tmp->ptp.egr_types;
1176		}
1177	}
1178
1179	if ((ing_types || egr_types) && !(orig_ing_types || orig_egr_types)) {
1180		err = mlxsw_sp_parsing_depth_inc(mlxsw_sp);
1181		if (err) {
1182			netdev_err(mlxsw_sp_port->dev, "Failed to increase parsing depth");
1183			return err;
1184		}
1185	}
1186	if (!(ing_types || egr_types) && (orig_ing_types || orig_egr_types))
1187		mlxsw_sp_parsing_depth_dec(mlxsw_sp);
1188
1189	return mlxsw_sp1_ptp_mtpppc_set(mlxsw_sp_port->mlxsw_sp,
1190				       ing_types, egr_types);
1191}
1192
1193static bool mlxsw_sp1_ptp_hwtstamp_enabled(struct mlxsw_sp_port *mlxsw_sp_port)
1194{
1195	return mlxsw_sp_port->ptp.ing_types || mlxsw_sp_port->ptp.egr_types;
1196}
1197
1198static int
1199mlxsw_sp1_ptp_port_shaper_set(struct mlxsw_sp_port *mlxsw_sp_port, bool enable)
1200{
1201	struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
1202	char qeec_pl[MLXSW_REG_QEEC_LEN];
1203
1204	mlxsw_reg_qeec_ptps_pack(qeec_pl, mlxsw_sp_port->local_port, enable);
1205	return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(qeec), qeec_pl);
1206}
1207
1208static int mlxsw_sp1_ptp_port_shaper_check(struct mlxsw_sp_port *mlxsw_sp_port)
1209{
1210	bool ptps = false;
1211	int err, i;
1212	u32 speed;
1213
1214	if (!mlxsw_sp1_ptp_hwtstamp_enabled(mlxsw_sp_port))
1215		return mlxsw_sp1_ptp_port_shaper_set(mlxsw_sp_port, false);
1216
1217	err = mlxsw_sp_port_speed_get(mlxsw_sp_port, &speed);
1218	if (err)
1219		return err;
1220
1221	for (i = 0; i < MLXSW_SP1_PTP_SHAPER_PARAMS_LEN; i++) {
1222		if (mlxsw_sp1_ptp_shaper_params[i].ethtool_speed == speed) {
1223			ptps = true;
1224			break;
1225		}
1226	}
1227
1228	return mlxsw_sp1_ptp_port_shaper_set(mlxsw_sp_port, ptps);
1229}
1230
1231void mlxsw_sp1_ptp_shaper_work(struct work_struct *work)
1232{
1233	struct delayed_work *dwork = to_delayed_work(work);
1234	struct mlxsw_sp_port *mlxsw_sp_port;
1235	int err;
1236
1237	mlxsw_sp_port = container_of(dwork, struct mlxsw_sp_port,
1238				     ptp.shaper_dw);
1239
1240	if (!mlxsw_sp1_ptp_hwtstamp_enabled(mlxsw_sp_port))
1241		return;
1242
1243	err = mlxsw_sp1_ptp_port_shaper_check(mlxsw_sp_port);
1244	if (err)
1245		netdev_err(mlxsw_sp_port->dev, "Failed to set up PTP shaper\n");
1246}
1247
1248int mlxsw_sp1_ptp_hwtstamp_set(struct mlxsw_sp_port *mlxsw_sp_port,
1249			       struct kernel_hwtstamp_config *config,
1250			       struct netlink_ext_ack *extack)
1251{
1252	enum hwtstamp_rx_filters rx_filter;
1253	u16 ing_types;
1254	u16 egr_types;
1255	int err;
1256
1257	err = mlxsw_sp1_ptp_get_message_types(config, &ing_types, &egr_types,
1258					      &rx_filter);
1259	if (err)
1260		return err;
1261
1262	err = mlxsw_sp1_ptp_mtpppc_update(mlxsw_sp_port, ing_types, egr_types);
1263	if (err)
1264		return err;
1265
1266	mlxsw_sp_port->ptp.hwtstamp_config = *config;
1267	mlxsw_sp_port->ptp.ing_types = ing_types;
1268	mlxsw_sp_port->ptp.egr_types = egr_types;
1269
1270	err = mlxsw_sp1_ptp_port_shaper_check(mlxsw_sp_port);
1271	if (err)
1272		return err;
1273
1274	/* Notify the caller what we are actually timestamping. */
1275	config->rx_filter = rx_filter;
1276
1277	return 0;
1278}
1279
1280int mlxsw_sp1_ptp_get_ts_info(struct mlxsw_sp *mlxsw_sp,
1281			      struct kernel_ethtool_ts_info *info)
1282{
1283	info->phc_index = ptp_clock_index(mlxsw_sp->clock->ptp);
1284
1285	info->so_timestamping = SOF_TIMESTAMPING_TX_HARDWARE |
1286				SOF_TIMESTAMPING_RX_HARDWARE |
1287				SOF_TIMESTAMPING_RAW_HARDWARE;
1288
1289	info->tx_types = BIT(HWTSTAMP_TX_OFF) |
1290			 BIT(HWTSTAMP_TX_ON);
1291
1292	info->rx_filters = BIT(HWTSTAMP_FILTER_NONE) |
1293			   BIT(HWTSTAMP_FILTER_ALL);
1294
1295	return 0;
1296}
1297
1298struct mlxsw_sp_ptp_port_stat {
1299	char str[ETH_GSTRING_LEN];
1300	ptrdiff_t offset;
1301};
1302
1303#define MLXSW_SP_PTP_PORT_STAT(NAME, FIELD)				\
1304	{								\
1305		.str = NAME,						\
1306		.offset = offsetof(struct mlxsw_sp_ptp_port_stats,	\
1307				    FIELD),				\
1308	}
1309
1310static const struct mlxsw_sp_ptp_port_stat mlxsw_sp_ptp_port_stats[] = {
1311	MLXSW_SP_PTP_PORT_STAT("ptp_rx_gcd_packets",    rx_gcd.packets),
1312	MLXSW_SP_PTP_PORT_STAT("ptp_rx_gcd_timestamps", rx_gcd.timestamps),
1313	MLXSW_SP_PTP_PORT_STAT("ptp_tx_gcd_packets",    tx_gcd.packets),
1314	MLXSW_SP_PTP_PORT_STAT("ptp_tx_gcd_timestamps", tx_gcd.timestamps),
1315};
1316
1317#undef MLXSW_SP_PTP_PORT_STAT
1318
1319#define MLXSW_SP_PTP_PORT_STATS_LEN \
1320	ARRAY_SIZE(mlxsw_sp_ptp_port_stats)
1321
1322int mlxsw_sp1_get_stats_count(void)
1323{
1324	return MLXSW_SP_PTP_PORT_STATS_LEN;
1325}
1326
1327void mlxsw_sp1_get_stats_strings(u8 **p)
1328{
1329	int i;
1330
1331	for (i = 0; i < MLXSW_SP_PTP_PORT_STATS_LEN; i++) {
1332		memcpy(*p, mlxsw_sp_ptp_port_stats[i].str,
1333		       ETH_GSTRING_LEN);
1334		*p += ETH_GSTRING_LEN;
1335	}
1336}
1337
1338void mlxsw_sp1_get_stats(struct mlxsw_sp_port *mlxsw_sp_port,
1339			 u64 *data, int data_index)
1340{
1341	void *stats = &mlxsw_sp_port->ptp.stats;
1342	ptrdiff_t offset;
1343	int i;
1344
1345	data += data_index;
1346	for (i = 0; i < MLXSW_SP_PTP_PORT_STATS_LEN; i++) {
1347		offset = mlxsw_sp_ptp_port_stats[i].offset;
1348		*data++ = *(u64 *)(stats + offset);
1349	}
1350}
1351
1352struct mlxsw_sp_ptp_state *mlxsw_sp2_ptp_init(struct mlxsw_sp *mlxsw_sp)
1353{
1354	struct mlxsw_sp2_ptp_state *ptp_state;
1355	int err;
1356
1357	/* Max FID will be used in data path, check validity as part of init. */
1358	if (!MLXSW_CORE_RES_VALID(mlxsw_sp->core, FID))
1359		return ERR_PTR(-EIO);
1360
1361	ptp_state = kzalloc(sizeof(*ptp_state), GFP_KERNEL);
1362	if (!ptp_state)
1363		return ERR_PTR(-ENOMEM);
1364
1365	ptp_state->common.mlxsw_sp = mlxsw_sp;
1366
1367	err = mlxsw_sp_ptp_traps_set(mlxsw_sp);
1368	if (err)
1369		goto err_ptp_traps_set;
1370
1371	refcount_set(&ptp_state->ptp_port_enabled_ref, 0);
1372	mutex_init(&ptp_state->lock);
1373	return &ptp_state->common;
1374
1375err_ptp_traps_set:
1376	kfree(ptp_state);
1377	return ERR_PTR(err);
1378}
1379
1380void mlxsw_sp2_ptp_fini(struct mlxsw_sp_ptp_state *ptp_state_common)
1381{
1382	struct mlxsw_sp *mlxsw_sp = ptp_state_common->mlxsw_sp;
1383	struct mlxsw_sp2_ptp_state *ptp_state;
1384
1385	ptp_state = mlxsw_sp2_ptp_state(mlxsw_sp);
1386
1387	mutex_destroy(&ptp_state->lock);
1388	mlxsw_sp_ptp_traps_unset(mlxsw_sp);
1389	kfree(ptp_state);
1390}
1391
1392static u32 mlxsw_ptp_utc_time_stamp_sec_get(struct mlxsw_core *mlxsw_core,
1393					    u8 cqe_ts_sec)
1394{
1395	u32 utc_sec = mlxsw_core_read_utc_sec(mlxsw_core);
1396
1397	if (cqe_ts_sec > (utc_sec & 0xff))
1398		/* Time stamp above the last bits of UTC (UTC & 0xff) means the
1399		 * latter has wrapped after the time stamp was collected.
1400		 */
1401		utc_sec -= 256;
1402
1403	utc_sec &= ~0xff;
1404	utc_sec |= cqe_ts_sec;
1405
1406	return utc_sec;
1407}
1408
1409static void mlxsw_sp2_ptp_hwtstamp_fill(struct mlxsw_core *mlxsw_core,
1410					const struct mlxsw_skb_cb *cb,
1411					struct skb_shared_hwtstamps *hwtstamps)
1412{
1413	u64 ts_sec, ts_nsec, nsec;
1414
1415	WARN_ON_ONCE(!cb->cqe_ts.sec && !cb->cqe_ts.nsec);
1416
1417	/* The time stamp in the CQE is represented by 38 bits, which is a short
1418	 * representation of UTC time. Software should create the full time
1419	 * stamp using the global UTC clock. The seconds have only 8 bits in the
1420	 * CQE, to create the full time stamp, use the current UTC time and fix
1421	 * the seconds according to the relation between UTC seconds and CQE
1422	 * seconds.
1423	 */
1424	ts_sec = mlxsw_ptp_utc_time_stamp_sec_get(mlxsw_core, cb->cqe_ts.sec);
1425	ts_nsec = cb->cqe_ts.nsec;
1426
1427	nsec = ts_sec * NSEC_PER_SEC + ts_nsec;
1428
1429	hwtstamps->hwtstamp = ns_to_ktime(nsec);
1430}
1431
1432void mlxsw_sp2_ptp_receive(struct mlxsw_sp *mlxsw_sp, struct sk_buff *skb,
1433			   u16 local_port)
1434{
1435	struct skb_shared_hwtstamps hwtstamps;
1436
1437	mlxsw_sp2_ptp_hwtstamp_fill(mlxsw_sp->core, mlxsw_skb_cb(skb),
1438				    &hwtstamps);
1439	*skb_hwtstamps(skb) = hwtstamps;
1440	mlxsw_sp_rx_listener_no_mark_func(skb, local_port, mlxsw_sp);
1441}
1442
1443void mlxsw_sp2_ptp_transmitted(struct mlxsw_sp *mlxsw_sp,
1444			       struct sk_buff *skb, u16 local_port)
1445{
1446	struct skb_shared_hwtstamps hwtstamps;
1447
1448	mlxsw_sp2_ptp_hwtstamp_fill(mlxsw_sp->core, mlxsw_skb_cb(skb),
1449				    &hwtstamps);
1450	skb_tstamp_tx(skb, &hwtstamps);
1451	dev_kfree_skb_any(skb);
1452}
1453
1454int mlxsw_sp2_ptp_hwtstamp_get(struct mlxsw_sp_port *mlxsw_sp_port,
1455			       struct kernel_hwtstamp_config *config)
1456{
1457	struct mlxsw_sp2_ptp_state *ptp_state;
1458
1459	ptp_state = mlxsw_sp2_ptp_state(mlxsw_sp_port->mlxsw_sp);
1460
1461	mutex_lock(&ptp_state->lock);
1462	*config = ptp_state->config;
1463	mutex_unlock(&ptp_state->lock);
1464
1465	return 0;
1466}
1467
1468static int
1469mlxsw_sp2_ptp_get_message_types(const struct kernel_hwtstamp_config *config,
1470				u16 *p_ing_types, u16 *p_egr_types,
1471				enum hwtstamp_rx_filters *p_rx_filter)
1472{
1473	enum hwtstamp_rx_filters rx_filter = config->rx_filter;
1474	enum hwtstamp_tx_types tx_type = config->tx_type;
1475	u16 ing_types = 0x00;
1476	u16 egr_types = 0x00;
1477
1478	*p_rx_filter = rx_filter;
1479
1480	switch (rx_filter) {
1481	case HWTSTAMP_FILTER_NONE:
1482		ing_types = 0x00;
1483		break;
1484	case HWTSTAMP_FILTER_PTP_V1_L4_SYNC:
1485	case HWTSTAMP_FILTER_PTP_V2_L4_SYNC:
1486	case HWTSTAMP_FILTER_PTP_V2_L2_SYNC:
1487	case HWTSTAMP_FILTER_PTP_V2_SYNC:
1488	case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ:
1489	case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ:
1490	case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ:
1491	case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ:
1492	case HWTSTAMP_FILTER_PTP_V1_L4_EVENT:
1493	case HWTSTAMP_FILTER_PTP_V2_L4_EVENT:
1494	case HWTSTAMP_FILTER_PTP_V2_L2_EVENT:
1495	case HWTSTAMP_FILTER_PTP_V2_EVENT:
1496		/* In Spectrum-2 and above, all packets get time stamp by
1497		 * default and the driver fill the time stamp only for event
1498		 * packets. Return all event types even if only specific types
1499		 * were required.
1500		 */
1501		ing_types = 0x0f;
1502		*p_rx_filter = HWTSTAMP_FILTER_SOME;
1503		break;
1504	case HWTSTAMP_FILTER_ALL:
1505	case HWTSTAMP_FILTER_SOME:
1506	case HWTSTAMP_FILTER_NTP_ALL:
1507		return -ERANGE;
1508	default:
1509		return -EINVAL;
1510	}
1511
1512	switch (tx_type) {
1513	case HWTSTAMP_TX_OFF:
1514		egr_types = 0x00;
1515		break;
1516	case HWTSTAMP_TX_ON:
1517		egr_types = 0x0f;
1518		break;
1519	case HWTSTAMP_TX_ONESTEP_SYNC:
1520	case HWTSTAMP_TX_ONESTEP_P2P:
1521		return -ERANGE;
1522	default:
1523		return -EINVAL;
1524	}
1525
1526	if ((ing_types && !egr_types) || (!ing_types && egr_types))
1527		return -EINVAL;
1528
1529	*p_ing_types = ing_types;
1530	*p_egr_types = egr_types;
1531	return 0;
1532}
1533
1534static int mlxsw_sp2_ptp_mtpcpc_set(struct mlxsw_sp *mlxsw_sp, bool ptp_trap_en,
1535				    u16 ing_types, u16 egr_types)
1536{
1537	char mtpcpc_pl[MLXSW_REG_MTPCPC_LEN];
1538
1539	mlxsw_reg_mtpcpc_pack(mtpcpc_pl, false, 0, ptp_trap_en, ing_types,
1540			      egr_types);
1541	return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(mtpcpc), mtpcpc_pl);
1542}
1543
1544static int mlxsw_sp2_ptp_enable(struct mlxsw_sp *mlxsw_sp, u16 ing_types,
1545				u16 egr_types,
1546				struct kernel_hwtstamp_config new_config)
1547{
1548	struct mlxsw_sp2_ptp_state *ptp_state = mlxsw_sp2_ptp_state(mlxsw_sp);
1549	int err;
1550
1551	err = mlxsw_sp2_ptp_mtpcpc_set(mlxsw_sp, true, ing_types, egr_types);
1552	if (err)
1553		return err;
1554
1555	ptp_state->config = new_config;
1556	return 0;
1557}
1558
1559static int mlxsw_sp2_ptp_disable(struct mlxsw_sp *mlxsw_sp,
1560				 struct kernel_hwtstamp_config new_config)
1561{
1562	struct mlxsw_sp2_ptp_state *ptp_state = mlxsw_sp2_ptp_state(mlxsw_sp);
1563	int err;
1564
1565	err = mlxsw_sp2_ptp_mtpcpc_set(mlxsw_sp, false, 0, 0);
1566	if (err)
1567		return err;
1568
1569	ptp_state->config = new_config;
1570	return 0;
1571}
1572
1573static int mlxsw_sp2_ptp_configure_port(struct mlxsw_sp_port *mlxsw_sp_port,
1574					u16 ing_types, u16 egr_types,
1575					struct kernel_hwtstamp_config new_config)
1576{
1577	struct mlxsw_sp2_ptp_state *ptp_state;
1578	int err;
1579
1580	ptp_state = mlxsw_sp2_ptp_state(mlxsw_sp_port->mlxsw_sp);
1581
1582	if (refcount_inc_not_zero(&ptp_state->ptp_port_enabled_ref))
1583		return 0;
1584
1585	err = mlxsw_sp2_ptp_enable(mlxsw_sp_port->mlxsw_sp, ing_types,
1586				   egr_types, new_config);
1587	if (err)
1588		return err;
1589
1590	refcount_set(&ptp_state->ptp_port_enabled_ref, 1);
1591
1592	return 0;
1593}
1594
1595static int mlxsw_sp2_ptp_deconfigure_port(struct mlxsw_sp_port *mlxsw_sp_port,
1596					  struct kernel_hwtstamp_config new_config)
1597{
1598	struct mlxsw_sp2_ptp_state *ptp_state;
1599	int err;
1600
1601	ptp_state = mlxsw_sp2_ptp_state(mlxsw_sp_port->mlxsw_sp);
1602
1603	if (!refcount_dec_and_test(&ptp_state->ptp_port_enabled_ref))
1604		return 0;
1605
1606	err = mlxsw_sp2_ptp_disable(mlxsw_sp_port->mlxsw_sp, new_config);
1607	if (err)
1608		goto err_ptp_disable;
1609
1610	return 0;
1611
1612err_ptp_disable:
1613	refcount_set(&ptp_state->ptp_port_enabled_ref, 1);
1614	return err;
1615}
1616
1617int mlxsw_sp2_ptp_hwtstamp_set(struct mlxsw_sp_port *mlxsw_sp_port,
1618			       struct kernel_hwtstamp_config *config,
1619			       struct netlink_ext_ack *extack)
1620{
1621	struct kernel_hwtstamp_config new_config;
1622	struct mlxsw_sp2_ptp_state *ptp_state;
1623	enum hwtstamp_rx_filters rx_filter;
1624	u16 new_ing_types, new_egr_types;
1625	bool ptp_enabled;
1626	int err;
1627
1628	ptp_state = mlxsw_sp2_ptp_state(mlxsw_sp_port->mlxsw_sp);
1629	mutex_lock(&ptp_state->lock);
1630
1631	err = mlxsw_sp2_ptp_get_message_types(config, &new_ing_types,
1632					      &new_egr_types, &rx_filter);
1633	if (err)
1634		goto err_get_message_types;
1635
1636	new_config.flags = config->flags;
1637	new_config.tx_type = config->tx_type;
1638	new_config.rx_filter = rx_filter;
1639
1640	ptp_enabled = mlxsw_sp_port->ptp.ing_types ||
1641		      mlxsw_sp_port->ptp.egr_types;
1642
1643	if ((new_ing_types || new_egr_types) && !ptp_enabled) {
1644		err = mlxsw_sp2_ptp_configure_port(mlxsw_sp_port, new_ing_types,
1645						   new_egr_types, new_config);
1646		if (err)
1647			goto err_configure_port;
1648	} else if (!new_ing_types && !new_egr_types && ptp_enabled) {
1649		err = mlxsw_sp2_ptp_deconfigure_port(mlxsw_sp_port, new_config);
1650		if (err)
1651			goto err_deconfigure_port;
1652	}
1653
1654	mlxsw_sp_port->ptp.ing_types = new_ing_types;
1655	mlxsw_sp_port->ptp.egr_types = new_egr_types;
1656
1657	/* Notify the caller what we are actually timestamping. */
1658	config->rx_filter = rx_filter;
1659	mutex_unlock(&ptp_state->lock);
1660
1661	return 0;
1662
1663err_deconfigure_port:
1664err_configure_port:
1665err_get_message_types:
1666	mutex_unlock(&ptp_state->lock);
1667	return err;
1668}
1669
1670int mlxsw_sp2_ptp_get_ts_info(struct mlxsw_sp *mlxsw_sp,
1671			      struct kernel_ethtool_ts_info *info)
1672{
1673	info->phc_index = ptp_clock_index(mlxsw_sp->clock->ptp);
1674
1675	info->so_timestamping = SOF_TIMESTAMPING_TX_HARDWARE |
1676				SOF_TIMESTAMPING_RX_HARDWARE |
1677				SOF_TIMESTAMPING_RAW_HARDWARE;
1678
1679	info->tx_types = BIT(HWTSTAMP_TX_OFF) |
1680			 BIT(HWTSTAMP_TX_ON);
1681
1682	info->rx_filters = BIT(HWTSTAMP_FILTER_NONE) |
1683			   BIT(HWTSTAMP_FILTER_PTP_V1_L4_EVENT) |
1684			   BIT(HWTSTAMP_FILTER_PTP_V2_EVENT);
1685
1686	return 0;
1687}
~/ Read-only file preview.