Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
0002 /* Copyright (c) 2019 Mellanox Technologies. All rights reserved */
0003 
0004 #include <linux/ptp_clock_kernel.h>
0005 #include <linux/clocksource.h>
0006 #include <linux/timecounter.h>
0007 #include <linux/spinlock.h>
0008 #include <linux/device.h>
0009 #include <linux/rhashtable.h>
0010 #include <linux/ptp_classify.h>
0011 #include <linux/if_ether.h>
0012 #include <linux/if_vlan.h>
0013 #include <linux/net_tstamp.h>
0014 #include <linux/refcount.h>
0015 
0016 #include "spectrum.h"
0017 #include "spectrum_ptp.h"
0018 #include "core.h"
0019 
0020 #define MLXSW_SP1_PTP_CLOCK_CYCLES_SHIFT    29
0021 #define MLXSW_SP1_PTP_CLOCK_FREQ_KHZ        156257 /* 6.4nSec */
0022 #define MLXSW_SP1_PTP_CLOCK_MASK        64
0023 
0024 #define MLXSW_SP1_PTP_HT_GC_INTERVAL        500 /* ms */
0025 
0026 /* How long, approximately, should the unmatched entries stay in the hash table
0027  * before they are collected. Should be evenly divisible by the GC interval.
0028  */
0029 #define MLXSW_SP1_PTP_HT_GC_TIMEOUT     1000 /* ms */
0030 
0031 struct mlxsw_sp_ptp_state {
0032     struct mlxsw_sp *mlxsw_sp;
0033 };
0034 
0035 struct mlxsw_sp1_ptp_state {
0036     struct mlxsw_sp_ptp_state common;
0037     struct rhltable unmatched_ht;
0038     spinlock_t unmatched_lock; /* protects the HT */
0039     struct delayed_work ht_gc_dw;
0040     u32 gc_cycle;
0041 };
0042 
0043 struct mlxsw_sp2_ptp_state {
0044     struct mlxsw_sp_ptp_state common;
0045     refcount_t ptp_port_enabled_ref; /* Number of ports with time stamping
0046                       * enabled.
0047                       */
0048     struct hwtstamp_config config;
0049     struct mutex lock; /* Protects 'config' and HW configuration. */
0050 };
0051 
0052 struct mlxsw_sp1_ptp_key {
0053     u16 local_port;
0054     u8 message_type;
0055     u16 sequence_id;
0056     u8 domain_number;
0057     bool ingress;
0058 };
0059 
0060 struct mlxsw_sp1_ptp_unmatched {
0061     struct mlxsw_sp1_ptp_key key;
0062     struct rhlist_head ht_node;
0063     struct rcu_head rcu;
0064     struct sk_buff *skb;
0065     u64 timestamp;
0066     u32 gc_cycle;
0067 };
0068 
0069 static const struct rhashtable_params mlxsw_sp1_ptp_unmatched_ht_params = {
0070     .key_len = sizeof_field(struct mlxsw_sp1_ptp_unmatched, key),
0071     .key_offset = offsetof(struct mlxsw_sp1_ptp_unmatched, key),
0072     .head_offset = offsetof(struct mlxsw_sp1_ptp_unmatched, ht_node),
0073 };
0074 
0075 struct mlxsw_sp_ptp_clock {
0076     struct mlxsw_core *core;
0077     struct ptp_clock *ptp;
0078     struct ptp_clock_info ptp_info;
0079 };
0080 
0081 struct mlxsw_sp1_ptp_clock {
0082     struct mlxsw_sp_ptp_clock common;
0083     spinlock_t lock; /* protect this structure */
0084     struct cyclecounter cycles;
0085     struct timecounter tc;
0086     u32 nominal_c_mult;
0087     unsigned long overflow_period;
0088     struct delayed_work overflow_work;
0089 };
0090 
0091 static struct mlxsw_sp1_ptp_state *
0092 mlxsw_sp1_ptp_state(struct mlxsw_sp *mlxsw_sp)
0093 {
0094     return container_of(mlxsw_sp->ptp_state, struct mlxsw_sp1_ptp_state,
0095                 common);
0096 }
0097 
0098 static struct mlxsw_sp2_ptp_state *
0099 mlxsw_sp2_ptp_state(struct mlxsw_sp *mlxsw_sp)
0100 {
0101     return container_of(mlxsw_sp->ptp_state, struct mlxsw_sp2_ptp_state,
0102                 common);
0103 }
0104 
0105 static struct mlxsw_sp1_ptp_clock *
0106 mlxsw_sp1_ptp_clock(struct ptp_clock_info *ptp)
0107 {
0108     return container_of(ptp, struct mlxsw_sp1_ptp_clock, common.ptp_info);
0109 }
0110 
0111 static u64 __mlxsw_sp1_ptp_read_frc(struct mlxsw_sp1_ptp_clock *clock,
0112                     struct ptp_system_timestamp *sts)
0113 {
0114     struct mlxsw_core *mlxsw_core = clock->common.core;
0115     u32 frc_h1, frc_h2, frc_l;
0116 
0117     frc_h1 = mlxsw_core_read_frc_h(mlxsw_core);
0118     ptp_read_system_prets(sts);
0119     frc_l = mlxsw_core_read_frc_l(mlxsw_core);
0120     ptp_read_system_postts(sts);
0121     frc_h2 = mlxsw_core_read_frc_h(mlxsw_core);
0122 
0123     if (frc_h1 != frc_h2) {
0124         /* wrap around */
0125         ptp_read_system_prets(sts);
0126         frc_l = mlxsw_core_read_frc_l(mlxsw_core);
0127         ptp_read_system_postts(sts);
0128     }
0129 
0130     return (u64) frc_l | (u64) frc_h2 << 32;
0131 }
0132 
0133 static u64 mlxsw_sp1_ptp_read_frc(const struct cyclecounter *cc)
0134 {
0135     struct mlxsw_sp1_ptp_clock *clock =
0136         container_of(cc, struct mlxsw_sp1_ptp_clock, cycles);
0137 
0138     return __mlxsw_sp1_ptp_read_frc(clock, NULL) & cc->mask;
0139 }
0140 
0141 static int
0142 mlxsw_sp_ptp_phc_adjfreq(struct mlxsw_sp_ptp_clock *clock, int freq_adj)
0143 {
0144     struct mlxsw_core *mlxsw_core = clock->core;
0145     char mtutc_pl[MLXSW_REG_MTUTC_LEN];
0146 
0147     mlxsw_reg_mtutc_pack(mtutc_pl, MLXSW_REG_MTUTC_OPERATION_ADJUST_FREQ,
0148                  freq_adj, 0, 0, 0);
0149     return mlxsw_reg_write(mlxsw_core, MLXSW_REG(mtutc), mtutc_pl);
0150 }
0151 
0152 static u64 mlxsw_sp1_ptp_ns2cycles(const struct timecounter *tc, u64 nsec)
0153 {
0154     u64 cycles = (u64) nsec;
0155 
0156     cycles <<= tc->cc->shift;
0157     cycles = div_u64(cycles, tc->cc->mult);
0158 
0159     return cycles;
0160 }
0161 
0162 static int
0163 mlxsw_sp1_ptp_phc_settime(struct mlxsw_sp1_ptp_clock *clock, u64 nsec)
0164 {
0165     struct mlxsw_core *mlxsw_core = clock->common.core;
0166     u64 next_sec, next_sec_in_nsec, cycles;
0167     char mtutc_pl[MLXSW_REG_MTUTC_LEN];
0168     char mtpps_pl[MLXSW_REG_MTPPS_LEN];
0169     int err;
0170 
0171     next_sec = div_u64(nsec, NSEC_PER_SEC) + 1;
0172     next_sec_in_nsec = next_sec * NSEC_PER_SEC;
0173 
0174     spin_lock_bh(&clock->lock);
0175     cycles = mlxsw_sp1_ptp_ns2cycles(&clock->tc, next_sec_in_nsec);
0176     spin_unlock_bh(&clock->lock);
0177 
0178     mlxsw_reg_mtpps_vpin_pack(mtpps_pl, cycles);
0179     err = mlxsw_reg_write(mlxsw_core, MLXSW_REG(mtpps), mtpps_pl);
0180     if (err)
0181         return err;
0182 
0183     mlxsw_reg_mtutc_pack(mtutc_pl,
0184                  MLXSW_REG_MTUTC_OPERATION_SET_TIME_AT_NEXT_SEC,
0185                  0, next_sec, 0, 0);
0186     return mlxsw_reg_write(mlxsw_core, MLXSW_REG(mtutc), mtutc_pl);
0187 }
0188 
0189 static int mlxsw_sp1_ptp_adjfine(struct ptp_clock_info *ptp, long scaled_ppm)
0190 {
0191     struct mlxsw_sp1_ptp_clock *clock = mlxsw_sp1_ptp_clock(ptp);
0192     int neg_adj = 0;
0193     u32 diff;
0194     u64 adj;
0195     s32 ppb;
0196 
0197     ppb = scaled_ppm_to_ppb(scaled_ppm);
0198 
0199     if (ppb < 0) {
0200         neg_adj = 1;
0201         ppb = -ppb;
0202     }
0203 
0204     adj = clock->nominal_c_mult;
0205     adj *= ppb;
0206     diff = div_u64(adj, NSEC_PER_SEC);
0207 
0208     spin_lock_bh(&clock->lock);
0209     timecounter_read(&clock->tc);
0210     clock->cycles.mult = neg_adj ? clock->nominal_c_mult - diff :
0211                        clock->nominal_c_mult + diff;
0212     spin_unlock_bh(&clock->lock);
0213 
0214     return mlxsw_sp_ptp_phc_adjfreq(&clock->common, neg_adj ? -ppb : ppb);
0215 }
0216 
0217 static int mlxsw_sp1_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta)
0218 {
0219     struct mlxsw_sp1_ptp_clock *clock = mlxsw_sp1_ptp_clock(ptp);
0220     u64 nsec;
0221 
0222     spin_lock_bh(&clock->lock);
0223     timecounter_adjtime(&clock->tc, delta);
0224     nsec = timecounter_read(&clock->tc);
0225     spin_unlock_bh(&clock->lock);
0226 
0227     return mlxsw_sp1_ptp_phc_settime(clock, nsec);
0228 }
0229 
0230 static int mlxsw_sp1_ptp_gettimex(struct ptp_clock_info *ptp,
0231                   struct timespec64 *ts,
0232                   struct ptp_system_timestamp *sts)
0233 {
0234     struct mlxsw_sp1_ptp_clock *clock = mlxsw_sp1_ptp_clock(ptp);
0235     u64 cycles, nsec;
0236 
0237     spin_lock_bh(&clock->lock);
0238     cycles = __mlxsw_sp1_ptp_read_frc(clock, sts);
0239     nsec = timecounter_cyc2time(&clock->tc, cycles);
0240     spin_unlock_bh(&clock->lock);
0241 
0242     *ts = ns_to_timespec64(nsec);
0243 
0244     return 0;
0245 }
0246 
0247 static int mlxsw_sp1_ptp_settime(struct ptp_clock_info *ptp,
0248                  const struct timespec64 *ts)
0249 {
0250     struct mlxsw_sp1_ptp_clock *clock = mlxsw_sp1_ptp_clock(ptp);
0251     u64 nsec = timespec64_to_ns(ts);
0252 
0253     spin_lock_bh(&clock->lock);
0254     timecounter_init(&clock->tc, &clock->cycles, nsec);
0255     nsec = timecounter_read(&clock->tc);
0256     spin_unlock_bh(&clock->lock);
0257 
0258     return mlxsw_sp1_ptp_phc_settime(clock, nsec);
0259 }
0260 
0261 static const struct ptp_clock_info mlxsw_sp1_ptp_clock_info = {
0262     .owner      = THIS_MODULE,
0263     .name       = "mlxsw_sp_clock",
0264     .max_adj    = 100000000,
0265     .adjfine    = mlxsw_sp1_ptp_adjfine,
0266     .adjtime    = mlxsw_sp1_ptp_adjtime,
0267     .gettimex64 = mlxsw_sp1_ptp_gettimex,
0268     .settime64  = mlxsw_sp1_ptp_settime,
0269 };
0270 
0271 static void mlxsw_sp1_ptp_clock_overflow(struct work_struct *work)
0272 {
0273     struct delayed_work *dwork = to_delayed_work(work);
0274     struct mlxsw_sp1_ptp_clock *clock;
0275 
0276     clock = container_of(dwork, struct mlxsw_sp1_ptp_clock, overflow_work);
0277 
0278     spin_lock_bh(&clock->lock);
0279     timecounter_read(&clock->tc);
0280     spin_unlock_bh(&clock->lock);
0281     mlxsw_core_schedule_dw(&clock->overflow_work, clock->overflow_period);
0282 }
0283 
0284 struct mlxsw_sp_ptp_clock *
0285 mlxsw_sp1_ptp_clock_init(struct mlxsw_sp *mlxsw_sp, struct device *dev)
0286 {
0287     u64 overflow_cycles, nsec, frac = 0;
0288     struct mlxsw_sp1_ptp_clock *clock;
0289     int err;
0290 
0291     clock = kzalloc(sizeof(*clock), GFP_KERNEL);
0292     if (!clock)
0293         return ERR_PTR(-ENOMEM);
0294 
0295     spin_lock_init(&clock->lock);
0296     clock->cycles.read = mlxsw_sp1_ptp_read_frc;
0297     clock->cycles.shift = MLXSW_SP1_PTP_CLOCK_CYCLES_SHIFT;
0298     clock->cycles.mult = clocksource_khz2mult(MLXSW_SP1_PTP_CLOCK_FREQ_KHZ,
0299                           clock->cycles.shift);
0300     clock->nominal_c_mult = clock->cycles.mult;
0301     clock->cycles.mask = CLOCKSOURCE_MASK(MLXSW_SP1_PTP_CLOCK_MASK);
0302     clock->common.core = mlxsw_sp->core;
0303 
0304     timecounter_init(&clock->tc, &clock->cycles, 0);
0305 
0306     /* Calculate period in seconds to call the overflow watchdog - to make
0307      * sure counter is checked at least twice every wrap around.
0308      * The period is calculated as the minimum between max HW cycles count
0309      * (The clock source mask) and max amount of cycles that can be
0310      * multiplied by clock multiplier where the result doesn't exceed
0311      * 64bits.
0312      */
0313     overflow_cycles = div64_u64(~0ULL >> 1, clock->cycles.mult);
0314     overflow_cycles = min(overflow_cycles, div_u64(clock->cycles.mask, 3));
0315 
0316     nsec = cyclecounter_cyc2ns(&clock->cycles, overflow_cycles, 0, &frac);
0317     clock->overflow_period = nsecs_to_jiffies(nsec);
0318 
0319     INIT_DELAYED_WORK(&clock->overflow_work, mlxsw_sp1_ptp_clock_overflow);
0320     mlxsw_core_schedule_dw(&clock->overflow_work, 0);
0321 
0322     clock->common.ptp_info = mlxsw_sp1_ptp_clock_info;
0323     clock->common.ptp = ptp_clock_register(&clock->common.ptp_info, dev);
0324     if (IS_ERR(clock->common.ptp)) {
0325         err = PTR_ERR(clock->common.ptp);
0326         dev_err(dev, "ptp_clock_register failed %d\n", err);
0327         goto err_ptp_clock_register;
0328     }
0329 
0330     return &clock->common;
0331 
0332 err_ptp_clock_register:
0333     cancel_delayed_work_sync(&clock->overflow_work);
0334     kfree(clock);
0335     return ERR_PTR(err);
0336 }
0337 
0338 void mlxsw_sp1_ptp_clock_fini(struct mlxsw_sp_ptp_clock *clock_common)
0339 {
0340     struct mlxsw_sp1_ptp_clock *clock =
0341         container_of(clock_common, struct mlxsw_sp1_ptp_clock, common);
0342 
0343     ptp_clock_unregister(clock_common->ptp);
0344     cancel_delayed_work_sync(&clock->overflow_work);
0345     kfree(clock);
0346 }
0347 
0348 static u64 mlxsw_sp2_ptp_read_utc(struct mlxsw_sp_ptp_clock *clock,
0349                   struct ptp_system_timestamp *sts)
0350 {
0351     struct mlxsw_core *mlxsw_core = clock->core;
0352     u32 utc_sec1, utc_sec2, utc_nsec;
0353 
0354     utc_sec1 = mlxsw_core_read_utc_sec(mlxsw_core);
0355     ptp_read_system_prets(sts);
0356     utc_nsec = mlxsw_core_read_utc_nsec(mlxsw_core);
0357     ptp_read_system_postts(sts);
0358     utc_sec2 = mlxsw_core_read_utc_sec(mlxsw_core);
0359 
0360     if (utc_sec1 != utc_sec2) {
0361         /* Wrap around. */
0362         ptp_read_system_prets(sts);
0363         utc_nsec = mlxsw_core_read_utc_nsec(mlxsw_core);
0364         ptp_read_system_postts(sts);
0365     }
0366 
0367     return (u64)utc_sec2 * NSEC_PER_SEC + utc_nsec;
0368 }
0369 
0370 static int
0371 mlxsw_sp2_ptp_phc_settime(struct mlxsw_sp_ptp_clock *clock, u64 nsec)
0372 {
0373     struct mlxsw_core *mlxsw_core = clock->core;
0374     char mtutc_pl[MLXSW_REG_MTUTC_LEN];
0375     u32 sec, nsec_rem;
0376 
0377     sec = div_u64_rem(nsec, NSEC_PER_SEC, &nsec_rem);
0378     mlxsw_reg_mtutc_pack(mtutc_pl,
0379                  MLXSW_REG_MTUTC_OPERATION_SET_TIME_IMMEDIATE,
0380                  0, sec, nsec_rem, 0);
0381     return mlxsw_reg_write(mlxsw_core, MLXSW_REG(mtutc), mtutc_pl);
0382 }
0383 
0384 static int mlxsw_sp2_ptp_adjfine(struct ptp_clock_info *ptp, long scaled_ppm)
0385 {
0386     struct mlxsw_sp_ptp_clock *clock =
0387         container_of(ptp, struct mlxsw_sp_ptp_clock, ptp_info);
0388     s32 ppb = scaled_ppm_to_ppb(scaled_ppm);
0389 
0390     /* In Spectrum-2 and newer ASICs, the frequency adjustment in MTUTC is
0391      * reversed, positive values mean to decrease the frequency. Adjust the
0392      * sign of PPB to this behavior.
0393      */
0394     return mlxsw_sp_ptp_phc_adjfreq(clock, -ppb);
0395 }
0396 
0397 static int mlxsw_sp2_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta)
0398 {
0399     struct mlxsw_sp_ptp_clock *clock =
0400         container_of(ptp, struct mlxsw_sp_ptp_clock, ptp_info);
0401     struct mlxsw_core *mlxsw_core = clock->core;
0402     char mtutc_pl[MLXSW_REG_MTUTC_LEN];
0403 
0404     /* HW time adjustment range is s16. If out of range, set time instead. */
0405     if (delta < S16_MIN || delta > S16_MAX) {
0406         u64 nsec;
0407 
0408         nsec = mlxsw_sp2_ptp_read_utc(clock, NULL);
0409         nsec += delta;
0410 
0411         return mlxsw_sp2_ptp_phc_settime(clock, nsec);
0412     }
0413 
0414     mlxsw_reg_mtutc_pack(mtutc_pl,
0415                  MLXSW_REG_MTUTC_OPERATION_ADJUST_TIME,
0416                  0, 0, 0, delta);
0417     return mlxsw_reg_write(mlxsw_core, MLXSW_REG(mtutc), mtutc_pl);
0418 }
0419 
0420 static int mlxsw_sp2_ptp_gettimex(struct ptp_clock_info *ptp,
0421                   struct timespec64 *ts,
0422                   struct ptp_system_timestamp *sts)
0423 {
0424     struct mlxsw_sp_ptp_clock *clock =
0425         container_of(ptp, struct mlxsw_sp_ptp_clock, ptp_info);
0426     u64 nsec;
0427 
0428     nsec = mlxsw_sp2_ptp_read_utc(clock, sts);
0429     *ts = ns_to_timespec64(nsec);
0430 
0431     return 0;
0432 }
0433 
0434 static int mlxsw_sp2_ptp_settime(struct ptp_clock_info *ptp,
0435                  const struct timespec64 *ts)
0436 {
0437     struct mlxsw_sp_ptp_clock *clock =
0438         container_of(ptp, struct mlxsw_sp_ptp_clock, ptp_info);
0439     u64 nsec = timespec64_to_ns(ts);
0440 
0441     return mlxsw_sp2_ptp_phc_settime(clock, nsec);
0442 }
0443 
0444 static const struct ptp_clock_info mlxsw_sp2_ptp_clock_info = {
0445     .owner      = THIS_MODULE,
0446     .name       = "mlxsw_sp_clock",
0447     .max_adj    = MLXSW_REG_MTUTC_MAX_FREQ_ADJ,
0448     .adjfine    = mlxsw_sp2_ptp_adjfine,
0449     .adjtime    = mlxsw_sp2_ptp_adjtime,
0450     .gettimex64 = mlxsw_sp2_ptp_gettimex,
0451     .settime64  = mlxsw_sp2_ptp_settime,
0452 };
0453 
0454 struct mlxsw_sp_ptp_clock *
0455 mlxsw_sp2_ptp_clock_init(struct mlxsw_sp *mlxsw_sp, struct device *dev)
0456 {
0457     struct mlxsw_sp_ptp_clock *clock;
0458     int err;
0459 
0460     clock = kzalloc(sizeof(*clock), GFP_KERNEL);
0461     if (!clock)
0462         return ERR_PTR(-ENOMEM);
0463 
0464     clock->core = mlxsw_sp->core;
0465 
0466     clock->ptp_info = mlxsw_sp2_ptp_clock_info;
0467 
0468     err = mlxsw_sp2_ptp_phc_settime(clock, 0);
0469     if (err) {
0470         dev_err(dev, "setting UTC time failed %d\n", err);
0471         goto err_ptp_phc_settime;
0472     }
0473 
0474     clock->ptp = ptp_clock_register(&clock->ptp_info, dev);
0475     if (IS_ERR(clock->ptp)) {
0476         err = PTR_ERR(clock->ptp);
0477         dev_err(dev, "ptp_clock_register failed %d\n", err);
0478         goto err_ptp_clock_register;
0479     }
0480 
0481     return clock;
0482 
0483 err_ptp_clock_register:
0484 err_ptp_phc_settime:
0485     kfree(clock);
0486     return ERR_PTR(err);
0487 }
0488 
0489 void mlxsw_sp2_ptp_clock_fini(struct mlxsw_sp_ptp_clock *clock)
0490 {
0491     ptp_clock_unregister(clock->ptp);
0492     kfree(clock);
0493 }
0494 
0495 static int mlxsw_sp_ptp_parse(struct sk_buff *skb,
0496                   u8 *p_domain_number,
0497                   u8 *p_message_type,
0498                   u16 *p_sequence_id)
0499 {
0500     unsigned int ptp_class;
0501     struct ptp_header *hdr;
0502 
0503     ptp_class = ptp_classify_raw(skb);
0504 
0505     switch (ptp_class & PTP_CLASS_VMASK) {
0506     case PTP_CLASS_V1:
0507     case PTP_CLASS_V2:
0508         break;
0509     default:
0510         return -ERANGE;
0511     }
0512 
0513     hdr = ptp_parse_header(skb, ptp_class);
0514     if (!hdr)
0515         return -EINVAL;
0516 
0517     *p_message_type  = ptp_get_msgtype(hdr, ptp_class);
0518     *p_domain_number = hdr->domain_number;
0519     *p_sequence_id   = be16_to_cpu(hdr->sequence_id);
0520 
0521     return 0;
0522 }
0523 
0524 /* Returns NULL on successful insertion, a pointer on conflict, or an ERR_PTR on
0525  * error.
0526  */
0527 static int
0528 mlxsw_sp1_ptp_unmatched_save(struct mlxsw_sp *mlxsw_sp,
0529                  struct mlxsw_sp1_ptp_key key,
0530                  struct sk_buff *skb,
0531                  u64 timestamp)
0532 {
0533     int cycles = MLXSW_SP1_PTP_HT_GC_TIMEOUT / MLXSW_SP1_PTP_HT_GC_INTERVAL;
0534     struct mlxsw_sp1_ptp_state *ptp_state = mlxsw_sp1_ptp_state(mlxsw_sp);
0535     struct mlxsw_sp1_ptp_unmatched *unmatched;
0536     int err;
0537 
0538     unmatched = kzalloc(sizeof(*unmatched), GFP_ATOMIC);
0539     if (!unmatched)
0540         return -ENOMEM;
0541 
0542     unmatched->key = key;
0543     unmatched->skb = skb;
0544     unmatched->timestamp = timestamp;
0545     unmatched->gc_cycle = ptp_state->gc_cycle + cycles;
0546 
0547     err = rhltable_insert(&ptp_state->unmatched_ht, &unmatched->ht_node,
0548                   mlxsw_sp1_ptp_unmatched_ht_params);
0549     if (err)
0550         kfree(unmatched);
0551 
0552     return err;
0553 }
0554 
0555 static struct mlxsw_sp1_ptp_unmatched *
0556 mlxsw_sp1_ptp_unmatched_lookup(struct mlxsw_sp *mlxsw_sp,
0557                    struct mlxsw_sp1_ptp_key key, int *p_length)
0558 {
0559     struct mlxsw_sp1_ptp_state *ptp_state = mlxsw_sp1_ptp_state(mlxsw_sp);
0560     struct mlxsw_sp1_ptp_unmatched *unmatched, *last = NULL;
0561     struct rhlist_head *tmp, *list;
0562     int length = 0;
0563 
0564     list = rhltable_lookup(&ptp_state->unmatched_ht, &key,
0565                    mlxsw_sp1_ptp_unmatched_ht_params);
0566     rhl_for_each_entry_rcu(unmatched, tmp, list, ht_node) {
0567         last = unmatched;
0568         length++;
0569     }
0570 
0571     *p_length = length;
0572     return last;
0573 }
0574 
0575 static int
0576 mlxsw_sp1_ptp_unmatched_remove(struct mlxsw_sp *mlxsw_sp,
0577                    struct mlxsw_sp1_ptp_unmatched *unmatched)
0578 {
0579     struct mlxsw_sp1_ptp_state *ptp_state = mlxsw_sp1_ptp_state(mlxsw_sp);
0580 
0581     return rhltable_remove(&ptp_state->unmatched_ht,
0582                    &unmatched->ht_node,
0583                    mlxsw_sp1_ptp_unmatched_ht_params);
0584 }
0585 
0586 /* This function is called in the following scenarios:
0587  *
0588  * 1) When a packet is matched with its timestamp.
0589  * 2) In several situation when it is necessary to immediately pass on
0590  *    an SKB without a timestamp.
0591  * 3) From GC indirectly through mlxsw_sp1_ptp_unmatched_finish().
0592  *    This case is similar to 2) above.
0593  */
0594 static void mlxsw_sp1_ptp_packet_finish(struct mlxsw_sp *mlxsw_sp,
0595                     struct sk_buff *skb, u16 local_port,
0596                     bool ingress,
0597                     struct skb_shared_hwtstamps *hwtstamps)
0598 {
0599     struct mlxsw_sp_port *mlxsw_sp_port;
0600 
0601     /* Between capturing the packet and finishing it, there is a window of
0602      * opportunity for the originating port to go away (e.g. due to a
0603      * split). Also make sure the SKB device reference is still valid.
0604      */
0605     mlxsw_sp_port = mlxsw_sp->ports[local_port];
0606     if (!(mlxsw_sp_port && (!skb->dev || skb->dev == mlxsw_sp_port->dev))) {
0607         dev_kfree_skb_any(skb);
0608         return;
0609     }
0610 
0611     if (ingress) {
0612         if (hwtstamps)
0613             *skb_hwtstamps(skb) = *hwtstamps;
0614         mlxsw_sp_rx_listener_no_mark_func(skb, local_port, mlxsw_sp);
0615     } else {
0616         /* skb_tstamp_tx() allows hwtstamps to be NULL. */
0617         skb_tstamp_tx(skb, hwtstamps);
0618         dev_kfree_skb_any(skb);
0619     }
0620 }
0621 
0622 static void mlxsw_sp1_packet_timestamp(struct mlxsw_sp *mlxsw_sp,
0623                        struct mlxsw_sp1_ptp_key key,
0624                        struct sk_buff *skb,
0625                        u64 timestamp)
0626 {
0627     struct mlxsw_sp_ptp_clock *clock_common = mlxsw_sp->clock;
0628     struct mlxsw_sp1_ptp_clock *clock =
0629         container_of(clock_common, struct mlxsw_sp1_ptp_clock, common);
0630 
0631     struct skb_shared_hwtstamps hwtstamps;
0632     u64 nsec;
0633 
0634     spin_lock_bh(&clock->lock);
0635     nsec = timecounter_cyc2time(&clock->tc, timestamp);
0636     spin_unlock_bh(&clock->lock);
0637 
0638     hwtstamps.hwtstamp = ns_to_ktime(nsec);
0639     mlxsw_sp1_ptp_packet_finish(mlxsw_sp, skb,
0640                     key.local_port, key.ingress, &hwtstamps);
0641 }
0642 
0643 static void
0644 mlxsw_sp1_ptp_unmatched_finish(struct mlxsw_sp *mlxsw_sp,
0645                    struct mlxsw_sp1_ptp_unmatched *unmatched)
0646 {
0647     if (unmatched->skb && unmatched->timestamp)
0648         mlxsw_sp1_packet_timestamp(mlxsw_sp, unmatched->key,
0649                        unmatched->skb,
0650                        unmatched->timestamp);
0651     else if (unmatched->skb)
0652         mlxsw_sp1_ptp_packet_finish(mlxsw_sp, unmatched->skb,
0653                         unmatched->key.local_port,
0654                         unmatched->key.ingress, NULL);
0655     kfree_rcu(unmatched, rcu);
0656 }
0657 
0658 static void mlxsw_sp1_ptp_unmatched_free_fn(void *ptr, void *arg)
0659 {
0660     struct mlxsw_sp1_ptp_unmatched *unmatched = ptr;
0661 
0662     /* This is invoked at a point where the ports are gone already. Nothing
0663      * to do with whatever is left in the HT but to free it.
0664      */
0665     if (unmatched->skb)
0666         dev_kfree_skb_any(unmatched->skb);
0667     kfree_rcu(unmatched, rcu);
0668 }
0669 
0670 static void mlxsw_sp1_ptp_got_piece(struct mlxsw_sp *mlxsw_sp,
0671                     struct mlxsw_sp1_ptp_key key,
0672                     struct sk_buff *skb, u64 timestamp)
0673 {
0674     struct mlxsw_sp1_ptp_state *ptp_state = mlxsw_sp1_ptp_state(mlxsw_sp);
0675     struct mlxsw_sp1_ptp_unmatched *unmatched;
0676     int length;
0677     int err;
0678 
0679     rcu_read_lock();
0680 
0681     spin_lock(&ptp_state->unmatched_lock);
0682 
0683     unmatched = mlxsw_sp1_ptp_unmatched_lookup(mlxsw_sp, key, &length);
0684     if (skb && unmatched && unmatched->timestamp) {
0685         unmatched->skb = skb;
0686     } else if (timestamp && unmatched && unmatched->skb) {
0687         unmatched->timestamp = timestamp;
0688     } else {
0689         /* Either there is no entry to match, or one that is there is
0690          * incompatible.
0691          */
0692         if (length < 100)
0693             err = mlxsw_sp1_ptp_unmatched_save(mlxsw_sp, key,
0694                                skb, timestamp);
0695         else
0696             err = -E2BIG;
0697         if (err && skb)
0698             mlxsw_sp1_ptp_packet_finish(mlxsw_sp, skb,
0699                             key.local_port,
0700                             key.ingress, NULL);
0701         unmatched = NULL;
0702     }
0703 
0704     if (unmatched) {
0705         err = mlxsw_sp1_ptp_unmatched_remove(mlxsw_sp, unmatched);
0706         WARN_ON_ONCE(err);
0707     }
0708 
0709     spin_unlock(&ptp_state->unmatched_lock);
0710 
0711     if (unmatched)
0712         mlxsw_sp1_ptp_unmatched_finish(mlxsw_sp, unmatched);
0713 
0714     rcu_read_unlock();
0715 }
0716 
0717 static void mlxsw_sp1_ptp_got_packet(struct mlxsw_sp *mlxsw_sp,
0718                      struct sk_buff *skb, u16 local_port,
0719                      bool ingress)
0720 {
0721     struct mlxsw_sp_port *mlxsw_sp_port;
0722     struct mlxsw_sp1_ptp_key key;
0723     u8 types;
0724     int err;
0725 
0726     mlxsw_sp_port = mlxsw_sp->ports[local_port];
0727     if (!mlxsw_sp_port)
0728         goto immediate;
0729 
0730     types = ingress ? mlxsw_sp_port->ptp.ing_types :
0731               mlxsw_sp_port->ptp.egr_types;
0732     if (!types)
0733         goto immediate;
0734 
0735     memset(&key, 0, sizeof(key));
0736     key.local_port = local_port;
0737     key.ingress = ingress;
0738 
0739     err = mlxsw_sp_ptp_parse(skb, &key.domain_number, &key.message_type,
0740                  &key.sequence_id);
0741     if (err)
0742         goto immediate;
0743 
0744     /* For packets whose timestamping was not enabled on this port, don't
0745      * bother trying to match the timestamp.
0746      */
0747     if (!((1 << key.message_type) & types))
0748         goto immediate;
0749 
0750     mlxsw_sp1_ptp_got_piece(mlxsw_sp, key, skb, 0);
0751     return;
0752 
0753 immediate:
0754     mlxsw_sp1_ptp_packet_finish(mlxsw_sp, skb, local_port, ingress, NULL);
0755 }
0756 
0757 void mlxsw_sp1_ptp_got_timestamp(struct mlxsw_sp *mlxsw_sp, bool ingress,
0758                  u16 local_port, u8 message_type,
0759                  u8 domain_number, u16 sequence_id,
0760                  u64 timestamp)
0761 {
0762     struct mlxsw_sp_port *mlxsw_sp_port;
0763     struct mlxsw_sp1_ptp_key key;
0764     u8 types;
0765 
0766     if (WARN_ON_ONCE(!mlxsw_sp_local_port_is_valid(mlxsw_sp, local_port)))
0767         return;
0768     mlxsw_sp_port = mlxsw_sp->ports[local_port];
0769     if (!mlxsw_sp_port)
0770         return;
0771 
0772     types = ingress ? mlxsw_sp_port->ptp.ing_types :
0773               mlxsw_sp_port->ptp.egr_types;
0774 
0775     /* For message types whose timestamping was not enabled on this port,
0776      * don't bother with the timestamp.
0777      */
0778     if (!((1 << message_type) & types))
0779         return;
0780 
0781     memset(&key, 0, sizeof(key));
0782     key.local_port = local_port;
0783     key.domain_number = domain_number;
0784     key.message_type = message_type;
0785     key.sequence_id = sequence_id;
0786     key.ingress = ingress;
0787 
0788     mlxsw_sp1_ptp_got_piece(mlxsw_sp, key, NULL, timestamp);
0789 }
0790 
0791 void mlxsw_sp1_ptp_receive(struct mlxsw_sp *mlxsw_sp, struct sk_buff *skb,
0792                u16 local_port)
0793 {
0794     skb_reset_mac_header(skb);
0795     mlxsw_sp1_ptp_got_packet(mlxsw_sp, skb, local_port, true);
0796 }
0797 
0798 void mlxsw_sp1_ptp_transmitted(struct mlxsw_sp *mlxsw_sp,
0799                    struct sk_buff *skb, u16 local_port)
0800 {
0801     mlxsw_sp1_ptp_got_packet(mlxsw_sp, skb, local_port, false);
0802 }
0803 
0804 static void
0805 mlxsw_sp1_ptp_ht_gc_collect(struct mlxsw_sp1_ptp_state *ptp_state,
0806                 struct mlxsw_sp1_ptp_unmatched *unmatched)
0807 {
0808     struct mlxsw_sp *mlxsw_sp = ptp_state->common.mlxsw_sp;
0809     struct mlxsw_sp_ptp_port_dir_stats *stats;
0810     struct mlxsw_sp_port *mlxsw_sp_port;
0811     int err;
0812 
0813     /* If an unmatched entry has an SKB, it has to be handed over to the
0814      * networking stack. This is usually done from a trap handler, which is
0815      * invoked in a softirq context. Here we are going to do it in process
0816      * context. If that were to be interrupted by a softirq, it could cause
0817      * a deadlock when an attempt is made to take an already-taken lock
0818      * somewhere along the sending path. Disable softirqs to prevent this.
0819      */
0820     local_bh_disable();
0821 
0822     spin_lock(&ptp_state->unmatched_lock);
0823     err = rhltable_remove(&ptp_state->unmatched_ht, &unmatched->ht_node,
0824                   mlxsw_sp1_ptp_unmatched_ht_params);
0825     spin_unlock(&ptp_state->unmatched_lock);
0826 
0827     if (err)
0828         /* The packet was matched with timestamp during the walk. */
0829         goto out;
0830 
0831     mlxsw_sp_port = mlxsw_sp->ports[unmatched->key.local_port];
0832     if (mlxsw_sp_port) {
0833         stats = unmatched->key.ingress ?
0834             &mlxsw_sp_port->ptp.stats.rx_gcd :
0835             &mlxsw_sp_port->ptp.stats.tx_gcd;
0836         if (unmatched->skb)
0837             stats->packets++;
0838         else
0839             stats->timestamps++;
0840     }
0841 
0842     /* mlxsw_sp1_ptp_unmatched_finish() invokes netif_receive_skb(). While
0843      * the comment at that function states that it can only be called in
0844      * soft IRQ context, this pattern of local_bh_disable() +
0845      * netif_receive_skb(), in process context, is seen elsewhere in the
0846      * kernel, notably in pktgen.
0847      */
0848     mlxsw_sp1_ptp_unmatched_finish(mlxsw_sp, unmatched);
0849 
0850 out:
0851     local_bh_enable();
0852 }
0853 
0854 static void mlxsw_sp1_ptp_ht_gc(struct work_struct *work)
0855 {
0856     struct delayed_work *dwork = to_delayed_work(work);
0857     struct mlxsw_sp1_ptp_unmatched *unmatched;
0858     struct mlxsw_sp1_ptp_state *ptp_state;
0859     struct rhashtable_iter iter;
0860     u32 gc_cycle;
0861     void *obj;
0862 
0863     ptp_state = container_of(dwork, struct mlxsw_sp1_ptp_state, ht_gc_dw);
0864     gc_cycle = ptp_state->gc_cycle++;
0865 
0866     rhltable_walk_enter(&ptp_state->unmatched_ht, &iter);
0867     rhashtable_walk_start(&iter);
0868     while ((obj = rhashtable_walk_next(&iter))) {
0869         if (IS_ERR(obj))
0870             continue;
0871 
0872         unmatched = obj;
0873         if (unmatched->gc_cycle <= gc_cycle)
0874             mlxsw_sp1_ptp_ht_gc_collect(ptp_state, unmatched);
0875     }
0876     rhashtable_walk_stop(&iter);
0877     rhashtable_walk_exit(&iter);
0878 
0879     mlxsw_core_schedule_dw(&ptp_state->ht_gc_dw,
0880                    MLXSW_SP1_PTP_HT_GC_INTERVAL);
0881 }
0882 
0883 static int mlxsw_sp_ptp_mtptpt_set(struct mlxsw_sp *mlxsw_sp,
0884                    enum mlxsw_reg_mtptpt_trap_id trap_id,
0885                    u16 message_type)
0886 {
0887     char mtptpt_pl[MLXSW_REG_MTPTPT_LEN];
0888 
0889     mlxsw_reg_mtptpt_pack(mtptpt_pl, trap_id, message_type);
0890     return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(mtptpt), mtptpt_pl);
0891 }
0892 
0893 static int mlxsw_sp1_ptp_set_fifo_clr_on_trap(struct mlxsw_sp *mlxsw_sp,
0894                           bool clr)
0895 {
0896     char mogcr_pl[MLXSW_REG_MOGCR_LEN] = {0};
0897     int err;
0898 
0899     err = mlxsw_reg_query(mlxsw_sp->core, MLXSW_REG(mogcr), mogcr_pl);
0900     if (err)
0901         return err;
0902 
0903     mlxsw_reg_mogcr_ptp_iftc_set(mogcr_pl, clr);
0904     mlxsw_reg_mogcr_ptp_eftc_set(mogcr_pl, clr);
0905     return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(mogcr), mogcr_pl);
0906 }
0907 
0908 static int mlxsw_sp1_ptp_mtpppc_set(struct mlxsw_sp *mlxsw_sp,
0909                     u16 ing_types, u16 egr_types)
0910 {
0911     char mtpppc_pl[MLXSW_REG_MTPPPC_LEN];
0912 
0913     mlxsw_reg_mtpppc_pack(mtpppc_pl, ing_types, egr_types);
0914     return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(mtpppc), mtpppc_pl);
0915 }
0916 
0917 struct mlxsw_sp1_ptp_shaper_params {
0918     u32 ethtool_speed;
0919     enum mlxsw_reg_qpsc_port_speed port_speed;
0920     u8 shaper_time_exp;
0921     u8 shaper_time_mantissa;
0922     u8 shaper_inc;
0923     u8 shaper_bs;
0924     u8 port_to_shaper_credits;
0925     int ing_timestamp_inc;
0926     int egr_timestamp_inc;
0927 };
0928 
0929 static const struct mlxsw_sp1_ptp_shaper_params
0930 mlxsw_sp1_ptp_shaper_params[] = {
0931     {
0932         .ethtool_speed      = SPEED_100,
0933         .port_speed     = MLXSW_REG_QPSC_PORT_SPEED_100M,
0934         .shaper_time_exp    = 4,
0935         .shaper_time_mantissa   = 12,
0936         .shaper_inc     = 9,
0937         .shaper_bs      = 1,
0938         .port_to_shaper_credits = 1,
0939         .ing_timestamp_inc  = -313,
0940         .egr_timestamp_inc  = 313,
0941     },
0942     {
0943         .ethtool_speed      = SPEED_1000,
0944         .port_speed     = MLXSW_REG_QPSC_PORT_SPEED_1G,
0945         .shaper_time_exp    = 0,
0946         .shaper_time_mantissa   = 12,
0947         .shaper_inc     = 6,
0948         .shaper_bs      = 0,
0949         .port_to_shaper_credits = 1,
0950         .ing_timestamp_inc  = -35,
0951         .egr_timestamp_inc  = 35,
0952     },
0953     {
0954         .ethtool_speed      = SPEED_10000,
0955         .port_speed     = MLXSW_REG_QPSC_PORT_SPEED_10G,
0956         .shaper_time_exp    = 0,
0957         .shaper_time_mantissa   = 2,
0958         .shaper_inc     = 14,
0959         .shaper_bs      = 1,
0960         .port_to_shaper_credits = 1,
0961         .ing_timestamp_inc  = -11,
0962         .egr_timestamp_inc  = 11,
0963     },
0964     {
0965         .ethtool_speed      = SPEED_25000,
0966         .port_speed     = MLXSW_REG_QPSC_PORT_SPEED_25G,
0967         .shaper_time_exp    = 0,
0968         .shaper_time_mantissa   = 0,
0969         .shaper_inc     = 11,
0970         .shaper_bs      = 1,
0971         .port_to_shaper_credits = 1,
0972         .ing_timestamp_inc  = -14,
0973         .egr_timestamp_inc  = 14,
0974     },
0975 };
0976 
0977 #define MLXSW_SP1_PTP_SHAPER_PARAMS_LEN ARRAY_SIZE(mlxsw_sp1_ptp_shaper_params)
0978 
0979 static int mlxsw_sp1_ptp_shaper_params_set(struct mlxsw_sp *mlxsw_sp)
0980 {
0981     const struct mlxsw_sp1_ptp_shaper_params *params;
0982     char qpsc_pl[MLXSW_REG_QPSC_LEN];
0983     int i, err;
0984 
0985     for (i = 0; i < MLXSW_SP1_PTP_SHAPER_PARAMS_LEN; i++) {
0986         params = &mlxsw_sp1_ptp_shaper_params[i];
0987         mlxsw_reg_qpsc_pack(qpsc_pl, params->port_speed,
0988                     params->shaper_time_exp,
0989                     params->shaper_time_mantissa,
0990                     params->shaper_inc, params->shaper_bs,
0991                     params->port_to_shaper_credits,
0992                     params->ing_timestamp_inc,
0993                     params->egr_timestamp_inc);
0994         err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(qpsc), qpsc_pl);
0995         if (err)
0996             return err;
0997     }
0998 
0999     return 0;
1000 }
1001 
1002 static int mlxsw_sp_ptp_traps_set(struct mlxsw_sp *mlxsw_sp)
1003 {
1004     u16 event_message_type;
1005     int err;
1006 
1007     /* Deliver these message types as PTP0. */
1008     event_message_type = BIT(PTP_MSGTYPE_SYNC) |
1009                  BIT(PTP_MSGTYPE_DELAY_REQ) |
1010                  BIT(PTP_MSGTYPE_PDELAY_REQ) |
1011                  BIT(PTP_MSGTYPE_PDELAY_RESP);
1012 
1013     err = mlxsw_sp_ptp_mtptpt_set(mlxsw_sp, MLXSW_REG_MTPTPT_TRAP_ID_PTP0,
1014                       event_message_type);
1015     if (err)
1016         return err;
1017 
1018     /* Everything else is PTP1. */
1019     err = mlxsw_sp_ptp_mtptpt_set(mlxsw_sp, MLXSW_REG_MTPTPT_TRAP_ID_PTP1,
1020                       ~event_message_type);
1021     if (err)
1022         goto err_mtptpt1_set;
1023 
1024     return 0;
1025 
1026 err_mtptpt1_set:
1027     mlxsw_sp_ptp_mtptpt_set(mlxsw_sp, MLXSW_REG_MTPTPT_TRAP_ID_PTP0, 0);
1028     return err;
1029 }
1030 
1031 static void mlxsw_sp_ptp_traps_unset(struct mlxsw_sp *mlxsw_sp)
1032 {
1033     mlxsw_sp_ptp_mtptpt_set(mlxsw_sp, MLXSW_REG_MTPTPT_TRAP_ID_PTP1, 0);
1034     mlxsw_sp_ptp_mtptpt_set(mlxsw_sp, MLXSW_REG_MTPTPT_TRAP_ID_PTP0, 0);
1035 }
1036 
1037 struct mlxsw_sp_ptp_state *mlxsw_sp1_ptp_init(struct mlxsw_sp *mlxsw_sp)
1038 {
1039     struct mlxsw_sp1_ptp_state *ptp_state;
1040     int err;
1041 
1042     err = mlxsw_sp1_ptp_shaper_params_set(mlxsw_sp);
1043     if (err)
1044         return ERR_PTR(err);
1045 
1046     ptp_state = kzalloc(sizeof(*ptp_state), GFP_KERNEL);
1047     if (!ptp_state)
1048         return ERR_PTR(-ENOMEM);
1049     ptp_state->common.mlxsw_sp = mlxsw_sp;
1050 
1051     spin_lock_init(&ptp_state->unmatched_lock);
1052 
1053     err = rhltable_init(&ptp_state->unmatched_ht,
1054                 &mlxsw_sp1_ptp_unmatched_ht_params);
1055     if (err)
1056         goto err_hashtable_init;
1057 
1058     err = mlxsw_sp_ptp_traps_set(mlxsw_sp);
1059     if (err)
1060         goto err_ptp_traps_set;
1061 
1062     err = mlxsw_sp1_ptp_set_fifo_clr_on_trap(mlxsw_sp, true);
1063     if (err)
1064         goto err_fifo_clr;
1065 
1066     INIT_DELAYED_WORK(&ptp_state->ht_gc_dw, mlxsw_sp1_ptp_ht_gc);
1067     mlxsw_core_schedule_dw(&ptp_state->ht_gc_dw,
1068                    MLXSW_SP1_PTP_HT_GC_INTERVAL);
1069     return &ptp_state->common;
1070 
1071 err_fifo_clr:
1072     mlxsw_sp_ptp_traps_unset(mlxsw_sp);
1073 err_ptp_traps_set:
1074     rhltable_destroy(&ptp_state->unmatched_ht);
1075 err_hashtable_init:
1076     kfree(ptp_state);
1077     return ERR_PTR(err);
1078 }
1079 
1080 void mlxsw_sp1_ptp_fini(struct mlxsw_sp_ptp_state *ptp_state_common)
1081 {
1082     struct mlxsw_sp *mlxsw_sp = ptp_state_common->mlxsw_sp;
1083     struct mlxsw_sp1_ptp_state *ptp_state;
1084 
1085     ptp_state = mlxsw_sp1_ptp_state(mlxsw_sp);
1086 
1087     cancel_delayed_work_sync(&ptp_state->ht_gc_dw);
1088     mlxsw_sp1_ptp_mtpppc_set(mlxsw_sp, 0, 0);
1089     mlxsw_sp1_ptp_set_fifo_clr_on_trap(mlxsw_sp, false);
1090     mlxsw_sp_ptp_traps_unset(mlxsw_sp);
1091     rhltable_free_and_destroy(&ptp_state->unmatched_ht,
1092                   &mlxsw_sp1_ptp_unmatched_free_fn, NULL);
1093     kfree(ptp_state);
1094 }
1095 
1096 int mlxsw_sp1_ptp_hwtstamp_get(struct mlxsw_sp_port *mlxsw_sp_port,
1097                    struct hwtstamp_config *config)
1098 {
1099     *config = mlxsw_sp_port->ptp.hwtstamp_config;
1100     return 0;
1101 }
1102 
1103 static int
1104 mlxsw_sp1_ptp_get_message_types(const struct hwtstamp_config *config,
1105                 u16 *p_ing_types, u16 *p_egr_types,
1106                 enum hwtstamp_rx_filters *p_rx_filter)
1107 {
1108     enum hwtstamp_rx_filters rx_filter = config->rx_filter;
1109     enum hwtstamp_tx_types tx_type = config->tx_type;
1110     u16 ing_types = 0x00;
1111     u16 egr_types = 0x00;
1112 
1113     switch (tx_type) {
1114     case HWTSTAMP_TX_OFF:
1115         egr_types = 0x00;
1116         break;
1117     case HWTSTAMP_TX_ON:
1118         egr_types = 0xff;
1119         break;
1120     case HWTSTAMP_TX_ONESTEP_SYNC:
1121     case HWTSTAMP_TX_ONESTEP_P2P:
1122         return -ERANGE;
1123     default:
1124         return -EINVAL;
1125     }
1126 
1127     switch (rx_filter) {
1128     case HWTSTAMP_FILTER_NONE:
1129         ing_types = 0x00;
1130         break;
1131     case HWTSTAMP_FILTER_PTP_V1_L4_SYNC:
1132     case HWTSTAMP_FILTER_PTP_V2_L4_SYNC:
1133     case HWTSTAMP_FILTER_PTP_V2_L2_SYNC:
1134     case HWTSTAMP_FILTER_PTP_V2_SYNC:
1135         ing_types = 0x01;
1136         break;
1137     case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ:
1138     case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ:
1139     case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ:
1140     case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ:
1141         ing_types = 0x02;
1142         break;
1143     case HWTSTAMP_FILTER_PTP_V1_L4_EVENT:
1144     case HWTSTAMP_FILTER_PTP_V2_L4_EVENT:
1145     case HWTSTAMP_FILTER_PTP_V2_L2_EVENT:
1146     case HWTSTAMP_FILTER_PTP_V2_EVENT:
1147         ing_types = 0x0f;
1148         break;
1149     case HWTSTAMP_FILTER_ALL:
1150         ing_types = 0xff;
1151         break;
1152     case HWTSTAMP_FILTER_SOME:
1153     case HWTSTAMP_FILTER_NTP_ALL:
1154         return -ERANGE;
1155     default:
1156         return -EINVAL;
1157     }
1158 
1159     *p_ing_types = ing_types;
1160     *p_egr_types = egr_types;
1161     *p_rx_filter = rx_filter;
1162     return 0;
1163 }
1164 
1165 static int mlxsw_sp1_ptp_mtpppc_update(struct mlxsw_sp_port *mlxsw_sp_port,
1166                        u16 ing_types, u16 egr_types)
1167 {
1168     struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
1169     struct mlxsw_sp_port *tmp;
1170     u16 orig_ing_types = 0;
1171     u16 orig_egr_types = 0;
1172     int err;
1173     int i;
1174 
1175     /* MTPPPC configures timestamping globally, not per port. Find the
1176      * configuration that contains all configured timestamping requests.
1177      */
1178     for (i = 1; i < mlxsw_core_max_ports(mlxsw_sp->core); i++) {
1179         tmp = mlxsw_sp->ports[i];
1180         if (tmp) {
1181             orig_ing_types |= tmp->ptp.ing_types;
1182             orig_egr_types |= tmp->ptp.egr_types;
1183         }
1184         if (tmp && tmp != mlxsw_sp_port) {
1185             ing_types |= tmp->ptp.ing_types;
1186             egr_types |= tmp->ptp.egr_types;
1187         }
1188     }
1189 
1190     if ((ing_types || egr_types) && !(orig_ing_types || orig_egr_types)) {
1191         err = mlxsw_sp_parsing_depth_inc(mlxsw_sp);
1192         if (err) {
1193             netdev_err(mlxsw_sp_port->dev, "Failed to increase parsing depth");
1194             return err;
1195         }
1196     }
1197     if (!(ing_types || egr_types) && (orig_ing_types || orig_egr_types))
1198         mlxsw_sp_parsing_depth_dec(mlxsw_sp);
1199 
1200     return mlxsw_sp1_ptp_mtpppc_set(mlxsw_sp_port->mlxsw_sp,
1201                        ing_types, egr_types);
1202 }
1203 
1204 static bool mlxsw_sp1_ptp_hwtstamp_enabled(struct mlxsw_sp_port *mlxsw_sp_port)
1205 {
1206     return mlxsw_sp_port->ptp.ing_types || mlxsw_sp_port->ptp.egr_types;
1207 }
1208 
1209 static int
1210 mlxsw_sp1_ptp_port_shaper_set(struct mlxsw_sp_port *mlxsw_sp_port, bool enable)
1211 {
1212     struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
1213     char qeec_pl[MLXSW_REG_QEEC_LEN];
1214 
1215     mlxsw_reg_qeec_ptps_pack(qeec_pl, mlxsw_sp_port->local_port, enable);
1216     return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(qeec), qeec_pl);
1217 }
1218 
1219 static int mlxsw_sp1_ptp_port_shaper_check(struct mlxsw_sp_port *mlxsw_sp_port)
1220 {
1221     bool ptps = false;
1222     int err, i;
1223     u32 speed;
1224 
1225     if (!mlxsw_sp1_ptp_hwtstamp_enabled(mlxsw_sp_port))
1226         return mlxsw_sp1_ptp_port_shaper_set(mlxsw_sp_port, false);
1227 
1228     err = mlxsw_sp_port_speed_get(mlxsw_sp_port, &speed);
1229     if (err)
1230         return err;
1231 
1232     for (i = 0; i < MLXSW_SP1_PTP_SHAPER_PARAMS_LEN; i++) {
1233         if (mlxsw_sp1_ptp_shaper_params[i].ethtool_speed == speed) {
1234             ptps = true;
1235             break;
1236         }
1237     }
1238 
1239     return mlxsw_sp1_ptp_port_shaper_set(mlxsw_sp_port, ptps);
1240 }
1241 
1242 void mlxsw_sp1_ptp_shaper_work(struct work_struct *work)
1243 {
1244     struct delayed_work *dwork = to_delayed_work(work);
1245     struct mlxsw_sp_port *mlxsw_sp_port;
1246     int err;
1247 
1248     mlxsw_sp_port = container_of(dwork, struct mlxsw_sp_port,
1249                      ptp.shaper_dw);
1250 
1251     if (!mlxsw_sp1_ptp_hwtstamp_enabled(mlxsw_sp_port))
1252         return;
1253 
1254     err = mlxsw_sp1_ptp_port_shaper_check(mlxsw_sp_port);
1255     if (err)
1256         netdev_err(mlxsw_sp_port->dev, "Failed to set up PTP shaper\n");
1257 }
1258 
1259 int mlxsw_sp1_ptp_hwtstamp_set(struct mlxsw_sp_port *mlxsw_sp_port,
1260                    struct hwtstamp_config *config)
1261 {
1262     enum hwtstamp_rx_filters rx_filter;
1263     u16 ing_types;
1264     u16 egr_types;
1265     int err;
1266 
1267     err = mlxsw_sp1_ptp_get_message_types(config, &ing_types, &egr_types,
1268                           &rx_filter);
1269     if (err)
1270         return err;
1271 
1272     err = mlxsw_sp1_ptp_mtpppc_update(mlxsw_sp_port, ing_types, egr_types);
1273     if (err)
1274         return err;
1275 
1276     mlxsw_sp_port->ptp.hwtstamp_config = *config;
1277     mlxsw_sp_port->ptp.ing_types = ing_types;
1278     mlxsw_sp_port->ptp.egr_types = egr_types;
1279 
1280     err = mlxsw_sp1_ptp_port_shaper_check(mlxsw_sp_port);
1281     if (err)
1282         return err;
1283 
1284     /* Notify the ioctl caller what we are actually timestamping. */
1285     config->rx_filter = rx_filter;
1286 
1287     return 0;
1288 }
1289 
1290 int mlxsw_sp1_ptp_get_ts_info(struct mlxsw_sp *mlxsw_sp,
1291                   struct ethtool_ts_info *info)
1292 {
1293     info->phc_index = ptp_clock_index(mlxsw_sp->clock->ptp);
1294 
1295     info->so_timestamping = SOF_TIMESTAMPING_TX_HARDWARE |
1296                 SOF_TIMESTAMPING_RX_HARDWARE |
1297                 SOF_TIMESTAMPING_RAW_HARDWARE;
1298 
1299     info->tx_types = BIT(HWTSTAMP_TX_OFF) |
1300              BIT(HWTSTAMP_TX_ON);
1301 
1302     info->rx_filters = BIT(HWTSTAMP_FILTER_NONE) |
1303                BIT(HWTSTAMP_FILTER_ALL);
1304 
1305     return 0;
1306 }
1307 
1308 struct mlxsw_sp_ptp_port_stat {
1309     char str[ETH_GSTRING_LEN];
1310     ptrdiff_t offset;
1311 };
1312 
1313 #define MLXSW_SP_PTP_PORT_STAT(NAME, FIELD)             \
1314     {                               \
1315         .str = NAME,                        \
1316         .offset = offsetof(struct mlxsw_sp_ptp_port_stats,  \
1317                     FIELD),             \
1318     }
1319 
1320 static const struct mlxsw_sp_ptp_port_stat mlxsw_sp_ptp_port_stats[] = {
1321     MLXSW_SP_PTP_PORT_STAT("ptp_rx_gcd_packets",    rx_gcd.packets),
1322     MLXSW_SP_PTP_PORT_STAT("ptp_rx_gcd_timestamps", rx_gcd.timestamps),
1323     MLXSW_SP_PTP_PORT_STAT("ptp_tx_gcd_packets",    tx_gcd.packets),
1324     MLXSW_SP_PTP_PORT_STAT("ptp_tx_gcd_timestamps", tx_gcd.timestamps),
1325 };
1326 
1327 #undef MLXSW_SP_PTP_PORT_STAT
1328 
1329 #define MLXSW_SP_PTP_PORT_STATS_LEN \
1330     ARRAY_SIZE(mlxsw_sp_ptp_port_stats)
1331 
1332 int mlxsw_sp1_get_stats_count(void)
1333 {
1334     return MLXSW_SP_PTP_PORT_STATS_LEN;
1335 }
1336 
1337 void mlxsw_sp1_get_stats_strings(u8 **p)
1338 {
1339     int i;
1340 
1341     for (i = 0; i < MLXSW_SP_PTP_PORT_STATS_LEN; i++) {
1342         memcpy(*p, mlxsw_sp_ptp_port_stats[i].str,
1343                ETH_GSTRING_LEN);
1344         *p += ETH_GSTRING_LEN;
1345     }
1346 }
1347 
1348 void mlxsw_sp1_get_stats(struct mlxsw_sp_port *mlxsw_sp_port,
1349              u64 *data, int data_index)
1350 {
1351     void *stats = &mlxsw_sp_port->ptp.stats;
1352     ptrdiff_t offset;
1353     int i;
1354 
1355     data += data_index;
1356     for (i = 0; i < MLXSW_SP_PTP_PORT_STATS_LEN; i++) {
1357         offset = mlxsw_sp_ptp_port_stats[i].offset;
1358         *data++ = *(u64 *)(stats + offset);
1359     }
1360 }
1361 
1362 struct mlxsw_sp_ptp_state *mlxsw_sp2_ptp_init(struct mlxsw_sp *mlxsw_sp)
1363 {
1364     struct mlxsw_sp2_ptp_state *ptp_state;
1365     int err;
1366 
1367     ptp_state = kzalloc(sizeof(*ptp_state), GFP_KERNEL);
1368     if (!ptp_state)
1369         return ERR_PTR(-ENOMEM);
1370 
1371     ptp_state->common.mlxsw_sp = mlxsw_sp;
1372 
1373     err = mlxsw_sp_ptp_traps_set(mlxsw_sp);
1374     if (err)
1375         goto err_ptp_traps_set;
1376 
1377     refcount_set(&ptp_state->ptp_port_enabled_ref, 0);
1378     mutex_init(&ptp_state->lock);
1379     return &ptp_state->common;
1380 
1381 err_ptp_traps_set:
1382     kfree(ptp_state);
1383     return ERR_PTR(err);
1384 }
1385 
1386 void mlxsw_sp2_ptp_fini(struct mlxsw_sp_ptp_state *ptp_state_common)
1387 {
1388     struct mlxsw_sp *mlxsw_sp = ptp_state_common->mlxsw_sp;
1389     struct mlxsw_sp2_ptp_state *ptp_state;
1390 
1391     ptp_state = mlxsw_sp2_ptp_state(mlxsw_sp);
1392 
1393     mutex_destroy(&ptp_state->lock);
1394     mlxsw_sp_ptp_traps_unset(mlxsw_sp);
1395     kfree(ptp_state);
1396 }
1397 
1398 static u32 mlxsw_ptp_utc_time_stamp_sec_get(struct mlxsw_core *mlxsw_core,
1399                         u8 cqe_ts_sec)
1400 {
1401     u32 utc_sec = mlxsw_core_read_utc_sec(mlxsw_core);
1402 
1403     if (cqe_ts_sec > (utc_sec & 0xff))
1404         /* Time stamp above the last bits of UTC (UTC & 0xff) means the
1405          * latter has wrapped after the time stamp was collected.
1406          */
1407         utc_sec -= 256;
1408 
1409     utc_sec &= ~0xff;
1410     utc_sec |= cqe_ts_sec;
1411 
1412     return utc_sec;
1413 }
1414 
1415 static void mlxsw_sp2_ptp_hwtstamp_fill(struct mlxsw_core *mlxsw_core,
1416                     const struct mlxsw_skb_cb *cb,
1417                     struct skb_shared_hwtstamps *hwtstamps)
1418 {
1419     u64 ts_sec, ts_nsec, nsec;
1420 
1421     WARN_ON_ONCE(!cb->cqe_ts.sec && !cb->cqe_ts.nsec);
1422 
1423     /* The time stamp in the CQE is represented by 38 bits, which is a short
1424      * representation of UTC time. Software should create the full time
1425      * stamp using the global UTC clock. The seconds have only 8 bits in the
1426      * CQE, to create the full time stamp, use the current UTC time and fix
1427      * the seconds according to the relation between UTC seconds and CQE
1428      * seconds.
1429      */
1430     ts_sec = mlxsw_ptp_utc_time_stamp_sec_get(mlxsw_core, cb->cqe_ts.sec);
1431     ts_nsec = cb->cqe_ts.nsec;
1432 
1433     nsec = ts_sec * NSEC_PER_SEC + ts_nsec;
1434 
1435     hwtstamps->hwtstamp = ns_to_ktime(nsec);
1436 }
1437 
1438 void mlxsw_sp2_ptp_receive(struct mlxsw_sp *mlxsw_sp, struct sk_buff *skb,
1439                u16 local_port)
1440 {
1441     struct skb_shared_hwtstamps hwtstamps;
1442 
1443     mlxsw_sp2_ptp_hwtstamp_fill(mlxsw_sp->core, mlxsw_skb_cb(skb),
1444                     &hwtstamps);
1445     *skb_hwtstamps(skb) = hwtstamps;
1446     mlxsw_sp_rx_listener_no_mark_func(skb, local_port, mlxsw_sp);
1447 }
1448 
1449 void mlxsw_sp2_ptp_transmitted(struct mlxsw_sp *mlxsw_sp,
1450                    struct sk_buff *skb, u16 local_port)
1451 {
1452     struct skb_shared_hwtstamps hwtstamps;
1453 
1454     mlxsw_sp2_ptp_hwtstamp_fill(mlxsw_sp->core, mlxsw_skb_cb(skb),
1455                     &hwtstamps);
1456     skb_tstamp_tx(skb, &hwtstamps);
1457     dev_kfree_skb_any(skb);
1458 }
1459 
1460 int mlxsw_sp2_ptp_hwtstamp_get(struct mlxsw_sp_port *mlxsw_sp_port,
1461                    struct hwtstamp_config *config)
1462 {
1463     struct mlxsw_sp2_ptp_state *ptp_state;
1464 
1465     ptp_state = mlxsw_sp2_ptp_state(mlxsw_sp_port->mlxsw_sp);
1466 
1467     mutex_lock(&ptp_state->lock);
1468     *config = ptp_state->config;
1469     mutex_unlock(&ptp_state->lock);
1470 
1471     return 0;
1472 }
1473 
1474 static int
1475 mlxsw_sp2_ptp_get_message_types(const struct hwtstamp_config *config,
1476                 u16 *p_ing_types, u16 *p_egr_types,
1477                 enum hwtstamp_rx_filters *p_rx_filter)
1478 {
1479     enum hwtstamp_rx_filters rx_filter = config->rx_filter;
1480     enum hwtstamp_tx_types tx_type = config->tx_type;
1481     u16 ing_types = 0x00;
1482     u16 egr_types = 0x00;
1483 
1484     *p_rx_filter = rx_filter;
1485 
1486     switch (rx_filter) {
1487     case HWTSTAMP_FILTER_NONE:
1488         ing_types = 0x00;
1489         break;
1490     case HWTSTAMP_FILTER_PTP_V1_L4_SYNC:
1491     case HWTSTAMP_FILTER_PTP_V2_L4_SYNC:
1492     case HWTSTAMP_FILTER_PTP_V2_L2_SYNC:
1493     case HWTSTAMP_FILTER_PTP_V2_SYNC:
1494     case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ:
1495     case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ:
1496     case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ:
1497     case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ:
1498     case HWTSTAMP_FILTER_PTP_V1_L4_EVENT:
1499     case HWTSTAMP_FILTER_PTP_V2_L4_EVENT:
1500     case HWTSTAMP_FILTER_PTP_V2_L2_EVENT:
1501     case HWTSTAMP_FILTER_PTP_V2_EVENT:
1502         /* In Spectrum-2 and above, all packets get time stamp by
1503          * default and the driver fill the time stamp only for event
1504          * packets. Return all event types even if only specific types
1505          * were required.
1506          */
1507         ing_types = 0x0f;
1508         *p_rx_filter = HWTSTAMP_FILTER_SOME;
1509         break;
1510     case HWTSTAMP_FILTER_ALL:
1511     case HWTSTAMP_FILTER_SOME:
1512     case HWTSTAMP_FILTER_NTP_ALL:
1513         return -ERANGE;
1514     default:
1515         return -EINVAL;
1516     }
1517 
1518     switch (tx_type) {
1519     case HWTSTAMP_TX_OFF:
1520         egr_types = 0x00;
1521         break;
1522     case HWTSTAMP_TX_ON:
1523         egr_types = 0x0f;
1524         break;
1525     case HWTSTAMP_TX_ONESTEP_SYNC:
1526     case HWTSTAMP_TX_ONESTEP_P2P:
1527         return -ERANGE;
1528     default:
1529         return -EINVAL;
1530     }
1531 
1532     if ((ing_types && !egr_types) || (!ing_types && egr_types))
1533         return -EINVAL;
1534 
1535     *p_ing_types = ing_types;
1536     *p_egr_types = egr_types;
1537     return 0;
1538 }
1539 
1540 static int mlxsw_sp2_ptp_mtpcpc_set(struct mlxsw_sp *mlxsw_sp, bool ptp_trap_en,
1541                     u16 ing_types, u16 egr_types)
1542 {
1543     char mtpcpc_pl[MLXSW_REG_MTPCPC_LEN];
1544 
1545     mlxsw_reg_mtpcpc_pack(mtpcpc_pl, false, 0, ptp_trap_en, ing_types,
1546                   egr_types);
1547     return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(mtpcpc), mtpcpc_pl);
1548 }
1549 
1550 static int mlxsw_sp2_ptp_enable(struct mlxsw_sp *mlxsw_sp, u16 ing_types,
1551                 u16 egr_types,
1552                 struct hwtstamp_config new_config)
1553 {
1554     struct mlxsw_sp2_ptp_state *ptp_state = mlxsw_sp2_ptp_state(mlxsw_sp);
1555     int err;
1556 
1557     err = mlxsw_sp2_ptp_mtpcpc_set(mlxsw_sp, true, ing_types, egr_types);
1558     if (err)
1559         return err;
1560 
1561     ptp_state->config = new_config;
1562     return 0;
1563 }
1564 
1565 static int mlxsw_sp2_ptp_disable(struct mlxsw_sp *mlxsw_sp,
1566                  struct hwtstamp_config new_config)
1567 {
1568     struct mlxsw_sp2_ptp_state *ptp_state = mlxsw_sp2_ptp_state(mlxsw_sp);
1569     int err;
1570 
1571     err = mlxsw_sp2_ptp_mtpcpc_set(mlxsw_sp, false, 0, 0);
1572     if (err)
1573         return err;
1574 
1575     ptp_state->config = new_config;
1576     return 0;
1577 }
1578 
1579 static int mlxsw_sp2_ptp_configure_port(struct mlxsw_sp_port *mlxsw_sp_port,
1580                     u16 ing_types, u16 egr_types,
1581                     struct hwtstamp_config new_config)
1582 {
1583     struct mlxsw_sp2_ptp_state *ptp_state;
1584     int err;
1585 
1586     ptp_state = mlxsw_sp2_ptp_state(mlxsw_sp_port->mlxsw_sp);
1587 
1588     if (refcount_inc_not_zero(&ptp_state->ptp_port_enabled_ref))
1589         return 0;
1590 
1591     err = mlxsw_sp2_ptp_enable(mlxsw_sp_port->mlxsw_sp, ing_types,
1592                    egr_types, new_config);
1593     if (err)
1594         return err;
1595 
1596     refcount_set(&ptp_state->ptp_port_enabled_ref, 1);
1597 
1598     return 0;
1599 }
1600 
1601 static int mlxsw_sp2_ptp_deconfigure_port(struct mlxsw_sp_port *mlxsw_sp_port,
1602                       struct hwtstamp_config new_config)
1603 {
1604     struct mlxsw_sp2_ptp_state *ptp_state;
1605     int err;
1606 
1607     ptp_state = mlxsw_sp2_ptp_state(mlxsw_sp_port->mlxsw_sp);
1608 
1609     if (!refcount_dec_and_test(&ptp_state->ptp_port_enabled_ref))
1610         return 0;
1611 
1612     err = mlxsw_sp2_ptp_disable(mlxsw_sp_port->mlxsw_sp, new_config);
1613     if (err)
1614         goto err_ptp_disable;
1615 
1616     return 0;
1617 
1618 err_ptp_disable:
1619     refcount_set(&ptp_state->ptp_port_enabled_ref, 1);
1620     return err;
1621 }
1622 
1623 int mlxsw_sp2_ptp_hwtstamp_set(struct mlxsw_sp_port *mlxsw_sp_port,
1624                    struct hwtstamp_config *config)
1625 {
1626     struct mlxsw_sp2_ptp_state *ptp_state;
1627     enum hwtstamp_rx_filters rx_filter;
1628     struct hwtstamp_config new_config;
1629     u16 new_ing_types, new_egr_types;
1630     bool ptp_enabled;
1631     int err;
1632 
1633     ptp_state = mlxsw_sp2_ptp_state(mlxsw_sp_port->mlxsw_sp);
1634     mutex_lock(&ptp_state->lock);
1635 
1636     err = mlxsw_sp2_ptp_get_message_types(config, &new_ing_types,
1637                           &new_egr_types, &rx_filter);
1638     if (err)
1639         goto err_get_message_types;
1640 
1641     new_config.flags = config->flags;
1642     new_config.tx_type = config->tx_type;
1643     new_config.rx_filter = rx_filter;
1644 
1645     ptp_enabled = mlxsw_sp_port->ptp.ing_types ||
1646               mlxsw_sp_port->ptp.egr_types;
1647 
1648     if ((new_ing_types || new_egr_types) && !ptp_enabled) {
1649         err = mlxsw_sp2_ptp_configure_port(mlxsw_sp_port, new_ing_types,
1650                            new_egr_types, new_config);
1651         if (err)
1652             goto err_configure_port;
1653     } else if (!new_ing_types && !new_egr_types && ptp_enabled) {
1654         err = mlxsw_sp2_ptp_deconfigure_port(mlxsw_sp_port, new_config);
1655         if (err)
1656             goto err_deconfigure_port;
1657     }
1658 
1659     mlxsw_sp_port->ptp.ing_types = new_ing_types;
1660     mlxsw_sp_port->ptp.egr_types = new_egr_types;
1661 
1662     /* Notify the ioctl caller what we are actually timestamping. */
1663     config->rx_filter = rx_filter;
1664     mutex_unlock(&ptp_state->lock);
1665 
1666     return 0;
1667 
1668 err_deconfigure_port:
1669 err_configure_port:
1670 err_get_message_types:
1671     mutex_unlock(&ptp_state->lock);
1672     return err;
1673 }
1674 
1675 int mlxsw_sp2_ptp_get_ts_info(struct mlxsw_sp *mlxsw_sp,
1676                   struct ethtool_ts_info *info)
1677 {
1678     info->phc_index = ptp_clock_index(mlxsw_sp->clock->ptp);
1679 
1680     info->so_timestamping = SOF_TIMESTAMPING_TX_HARDWARE |
1681                 SOF_TIMESTAMPING_RX_HARDWARE |
1682                 SOF_TIMESTAMPING_RAW_HARDWARE;
1683 
1684     info->tx_types = BIT(HWTSTAMP_TX_OFF) |
1685              BIT(HWTSTAMP_TX_ON);
1686 
1687     info->rx_filters = BIT(HWTSTAMP_FILTER_NONE) |
1688                BIT(HWTSTAMP_FILTER_PTP_V1_L4_EVENT) |
1689                BIT(HWTSTAMP_FILTER_PTP_V2_EVENT);
1690 
1691     return 0;
1692 }
1693 
1694 int mlxsw_sp_ptp_txhdr_construct(struct mlxsw_core *mlxsw_core,
1695                  struct mlxsw_sp_port *mlxsw_sp_port,
1696                  struct sk_buff *skb,
1697                  const struct mlxsw_tx_info *tx_info)
1698 {
1699     mlxsw_sp_txhdr_construct(skb, tx_info);
1700     return 0;
1701 }
1702 
1703 int mlxsw_sp2_ptp_txhdr_construct(struct mlxsw_core *mlxsw_core,
1704                   struct mlxsw_sp_port *mlxsw_sp_port,
1705                   struct sk_buff *skb,
1706                   const struct mlxsw_tx_info *tx_info)
1707 {
1708     /* In Spectrum-2 and Spectrum-3, in order for PTP event packets to have
1709      * their correction field correctly set on the egress port they must be
1710      * transmitted as data packets. Such packets ingress the ASIC via the
1711      * CPU port and must have a VLAN tag, as the CPU port is not configured
1712      * with a PVID. Push the default VLAN (4095), which is configured as
1713      * egress untagged on all the ports.
1714      */
1715     if (!skb_vlan_tagged(skb)) {
1716         skb = vlan_insert_tag_set_proto(skb, htons(ETH_P_8021Q),
1717                         MLXSW_SP_DEFAULT_VID);
1718         if (!skb) {
1719             this_cpu_inc(mlxsw_sp_port->pcpu_stats->tx_dropped);
1720             return -ENOMEM;
1721         }
1722     }
1723 
1724     return mlxsw_sp_txhdr_ptp_data_construct(mlxsw_core, mlxsw_sp_port, skb,
1725                          tx_info);
1726 }