Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * Marvell 88E6xxx Switch hardware timestamping support
0004  *
0005  * Copyright (c) 2008 Marvell Semiconductor
0006  *
0007  * Copyright (c) 2017 National Instruments
0008  *      Erik Hons <erik.hons@ni.com>
0009  *      Brandon Streiff <brandon.streiff@ni.com>
0010  *      Dane Wagner <dane.wagner@ni.com>
0011  */
0012 
0013 #include "chip.h"
0014 #include "global2.h"
0015 #include "hwtstamp.h"
0016 #include "ptp.h"
0017 #include <linux/ptp_classify.h>
0018 
0019 #define SKB_PTP_TYPE(__skb) (*(unsigned int *)((__skb)->cb))
0020 
0021 static int mv88e6xxx_port_ptp_read(struct mv88e6xxx_chip *chip, int port,
0022                    int addr, u16 *data, int len)
0023 {
0024     if (!chip->info->ops->avb_ops->port_ptp_read)
0025         return -EOPNOTSUPP;
0026 
0027     return chip->info->ops->avb_ops->port_ptp_read(chip, port, addr,
0028                                data, len);
0029 }
0030 
0031 static int mv88e6xxx_port_ptp_write(struct mv88e6xxx_chip *chip, int port,
0032                     int addr, u16 data)
0033 {
0034     if (!chip->info->ops->avb_ops->port_ptp_write)
0035         return -EOPNOTSUPP;
0036 
0037     return chip->info->ops->avb_ops->port_ptp_write(chip, port, addr,
0038                             data);
0039 }
0040 
0041 static int mv88e6xxx_ptp_write(struct mv88e6xxx_chip *chip, int addr,
0042                    u16 data)
0043 {
0044     if (!chip->info->ops->avb_ops->ptp_write)
0045         return -EOPNOTSUPP;
0046 
0047     return chip->info->ops->avb_ops->ptp_write(chip, addr, data);
0048 }
0049 
0050 static int mv88e6xxx_ptp_read(struct mv88e6xxx_chip *chip, int addr,
0051                   u16 *data)
0052 {
0053     if (!chip->info->ops->avb_ops->ptp_read)
0054         return -EOPNOTSUPP;
0055 
0056     return chip->info->ops->avb_ops->ptp_read(chip, addr, data, 1);
0057 }
0058 
0059 /* TX_TSTAMP_TIMEOUT: This limits the time spent polling for a TX
0060  * timestamp. When working properly, hardware will produce a timestamp
0061  * within 1ms. Software may enounter delays due to MDIO contention, so
0062  * the timeout is set accordingly.
0063  */
0064 #define TX_TSTAMP_TIMEOUT   msecs_to_jiffies(40)
0065 
0066 int mv88e6xxx_get_ts_info(struct dsa_switch *ds, int port,
0067               struct ethtool_ts_info *info)
0068 {
0069     const struct mv88e6xxx_ptp_ops *ptp_ops;
0070     struct mv88e6xxx_chip *chip;
0071 
0072     chip = ds->priv;
0073     ptp_ops = chip->info->ops->ptp_ops;
0074 
0075     if (!chip->info->ptp_support)
0076         return -EOPNOTSUPP;
0077 
0078     info->so_timestamping =
0079         SOF_TIMESTAMPING_TX_HARDWARE |
0080         SOF_TIMESTAMPING_RX_HARDWARE |
0081         SOF_TIMESTAMPING_RAW_HARDWARE;
0082     info->phc_index = ptp_clock_index(chip->ptp_clock);
0083     info->tx_types =
0084         (1 << HWTSTAMP_TX_OFF) |
0085         (1 << HWTSTAMP_TX_ON);
0086     info->rx_filters = ptp_ops->rx_filters;
0087 
0088     return 0;
0089 }
0090 
0091 static int mv88e6xxx_set_hwtstamp_config(struct mv88e6xxx_chip *chip, int port,
0092                      struct hwtstamp_config *config)
0093 {
0094     const struct mv88e6xxx_ptp_ops *ptp_ops = chip->info->ops->ptp_ops;
0095     struct mv88e6xxx_port_hwtstamp *ps = &chip->port_hwtstamp[port];
0096     bool tstamp_enable = false;
0097 
0098     /* Prevent the TX/RX paths from trying to interact with the
0099      * timestamp hardware while we reconfigure it.
0100      */
0101     clear_bit_unlock(MV88E6XXX_HWTSTAMP_ENABLED, &ps->state);
0102 
0103     switch (config->tx_type) {
0104     case HWTSTAMP_TX_OFF:
0105         tstamp_enable = false;
0106         break;
0107     case HWTSTAMP_TX_ON:
0108         tstamp_enable = true;
0109         break;
0110     default:
0111         return -ERANGE;
0112     }
0113 
0114     /* The switch supports timestamping both L2 and L4; one cannot be
0115      * disabled independently of the other.
0116      */
0117 
0118     if (!(BIT(config->rx_filter) & ptp_ops->rx_filters)) {
0119         config->rx_filter = HWTSTAMP_FILTER_NONE;
0120         dev_dbg(chip->dev, "Unsupported rx_filter %d\n",
0121             config->rx_filter);
0122         return -ERANGE;
0123     }
0124 
0125     switch (config->rx_filter) {
0126     case HWTSTAMP_FILTER_NONE:
0127         tstamp_enable = false;
0128         break;
0129     case HWTSTAMP_FILTER_PTP_V2_L4_EVENT:
0130     case HWTSTAMP_FILTER_PTP_V2_L4_SYNC:
0131     case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ:
0132     case HWTSTAMP_FILTER_PTP_V2_L2_EVENT:
0133     case HWTSTAMP_FILTER_PTP_V2_L2_SYNC:
0134     case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ:
0135     case HWTSTAMP_FILTER_PTP_V2_EVENT:
0136     case HWTSTAMP_FILTER_PTP_V2_SYNC:
0137     case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ:
0138         config->rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT;
0139         break;
0140     case HWTSTAMP_FILTER_ALL:
0141     default:
0142         config->rx_filter = HWTSTAMP_FILTER_NONE;
0143         return -ERANGE;
0144     }
0145 
0146     mv88e6xxx_reg_lock(chip);
0147     if (tstamp_enable) {
0148         chip->enable_count += 1;
0149         if (chip->enable_count == 1 && ptp_ops->global_enable)
0150             ptp_ops->global_enable(chip);
0151         if (ptp_ops->port_enable)
0152             ptp_ops->port_enable(chip, port);
0153     } else {
0154         if (ptp_ops->port_disable)
0155             ptp_ops->port_disable(chip, port);
0156         chip->enable_count -= 1;
0157         if (chip->enable_count == 0 && ptp_ops->global_disable)
0158             ptp_ops->global_disable(chip);
0159     }
0160     mv88e6xxx_reg_unlock(chip);
0161 
0162     /* Once hardware has been configured, enable timestamp checks
0163      * in the RX/TX paths.
0164      */
0165     if (tstamp_enable)
0166         set_bit(MV88E6XXX_HWTSTAMP_ENABLED, &ps->state);
0167 
0168     return 0;
0169 }
0170 
0171 int mv88e6xxx_port_hwtstamp_set(struct dsa_switch *ds, int port,
0172                 struct ifreq *ifr)
0173 {
0174     struct mv88e6xxx_chip *chip = ds->priv;
0175     struct mv88e6xxx_port_hwtstamp *ps = &chip->port_hwtstamp[port];
0176     struct hwtstamp_config config;
0177     int err;
0178 
0179     if (!chip->info->ptp_support)
0180         return -EOPNOTSUPP;
0181 
0182     if (copy_from_user(&config, ifr->ifr_data, sizeof(config)))
0183         return -EFAULT;
0184 
0185     err = mv88e6xxx_set_hwtstamp_config(chip, port, &config);
0186     if (err)
0187         return err;
0188 
0189     /* Save the chosen configuration to be returned later. */
0190     memcpy(&ps->tstamp_config, &config, sizeof(config));
0191 
0192     return copy_to_user(ifr->ifr_data, &config, sizeof(config)) ?
0193         -EFAULT : 0;
0194 }
0195 
0196 int mv88e6xxx_port_hwtstamp_get(struct dsa_switch *ds, int port,
0197                 struct ifreq *ifr)
0198 {
0199     struct mv88e6xxx_chip *chip = ds->priv;
0200     struct mv88e6xxx_port_hwtstamp *ps = &chip->port_hwtstamp[port];
0201     struct hwtstamp_config *config = &ps->tstamp_config;
0202 
0203     if (!chip->info->ptp_support)
0204         return -EOPNOTSUPP;
0205 
0206     return copy_to_user(ifr->ifr_data, config, sizeof(*config)) ?
0207         -EFAULT : 0;
0208 }
0209 
0210 /* Returns a pointer to the PTP header if the caller should time stamp,
0211  * or NULL if the caller should not.
0212  */
0213 static struct ptp_header *mv88e6xxx_should_tstamp(struct mv88e6xxx_chip *chip,
0214                           int port, struct sk_buff *skb,
0215                           unsigned int type)
0216 {
0217     struct mv88e6xxx_port_hwtstamp *ps = &chip->port_hwtstamp[port];
0218     struct ptp_header *hdr;
0219 
0220     if (!chip->info->ptp_support)
0221         return NULL;
0222 
0223     hdr = ptp_parse_header(skb, type);
0224     if (!hdr)
0225         return NULL;
0226 
0227     if (!test_bit(MV88E6XXX_HWTSTAMP_ENABLED, &ps->state))
0228         return NULL;
0229 
0230     return hdr;
0231 }
0232 
0233 static int mv88e6xxx_ts_valid(u16 status)
0234 {
0235     if (!(status & MV88E6XXX_PTP_TS_VALID))
0236         return 0;
0237     if (status & MV88E6XXX_PTP_TS_STATUS_MASK)
0238         return 0;
0239     return 1;
0240 }
0241 
0242 static int seq_match(struct sk_buff *skb, u16 ts_seqid)
0243 {
0244     unsigned int type = SKB_PTP_TYPE(skb);
0245     struct ptp_header *hdr;
0246 
0247     hdr = ptp_parse_header(skb, type);
0248 
0249     return ts_seqid == ntohs(hdr->sequence_id);
0250 }
0251 
0252 static void mv88e6xxx_get_rxts(struct mv88e6xxx_chip *chip,
0253                    struct mv88e6xxx_port_hwtstamp *ps,
0254                    struct sk_buff *skb, u16 reg,
0255                    struct sk_buff_head *rxq)
0256 {
0257     u16 buf[4] = { 0 }, status, seq_id;
0258     struct skb_shared_hwtstamps *shwt;
0259     struct sk_buff_head received;
0260     u64 ns, timelo, timehi;
0261     unsigned long flags;
0262     int err;
0263 
0264     /* The latched timestamp belongs to one of the received frames. */
0265     __skb_queue_head_init(&received);
0266     spin_lock_irqsave(&rxq->lock, flags);
0267     skb_queue_splice_tail_init(rxq, &received);
0268     spin_unlock_irqrestore(&rxq->lock, flags);
0269 
0270     mv88e6xxx_reg_lock(chip);
0271     err = mv88e6xxx_port_ptp_read(chip, ps->port_id,
0272                       reg, buf, ARRAY_SIZE(buf));
0273     mv88e6xxx_reg_unlock(chip);
0274     if (err)
0275         pr_err("failed to get the receive time stamp\n");
0276 
0277     status = buf[0];
0278     timelo = buf[1];
0279     timehi = buf[2];
0280     seq_id = buf[3];
0281 
0282     if (status & MV88E6XXX_PTP_TS_VALID) {
0283         mv88e6xxx_reg_lock(chip);
0284         err = mv88e6xxx_port_ptp_write(chip, ps->port_id, reg, 0);
0285         mv88e6xxx_reg_unlock(chip);
0286         if (err)
0287             pr_err("failed to clear the receive status\n");
0288     }
0289     /* Since the device can only handle one time stamp at a time,
0290      * we purge any extra frames from the queue.
0291      */
0292     for ( ; skb; skb = __skb_dequeue(&received)) {
0293         if (mv88e6xxx_ts_valid(status) && seq_match(skb, seq_id)) {
0294             ns = timehi << 16 | timelo;
0295 
0296             mv88e6xxx_reg_lock(chip);
0297             ns = timecounter_cyc2time(&chip->tstamp_tc, ns);
0298             mv88e6xxx_reg_unlock(chip);
0299             shwt = skb_hwtstamps(skb);
0300             memset(shwt, 0, sizeof(*shwt));
0301             shwt->hwtstamp = ns_to_ktime(ns);
0302             status &= ~MV88E6XXX_PTP_TS_VALID;
0303         }
0304         netif_rx(skb);
0305     }
0306 }
0307 
0308 static void mv88e6xxx_rxtstamp_work(struct mv88e6xxx_chip *chip,
0309                     struct mv88e6xxx_port_hwtstamp *ps)
0310 {
0311     const struct mv88e6xxx_ptp_ops *ptp_ops = chip->info->ops->ptp_ops;
0312     struct sk_buff *skb;
0313 
0314     skb = skb_dequeue(&ps->rx_queue);
0315 
0316     if (skb)
0317         mv88e6xxx_get_rxts(chip, ps, skb, ptp_ops->arr0_sts_reg,
0318                    &ps->rx_queue);
0319 
0320     skb = skb_dequeue(&ps->rx_queue2);
0321     if (skb)
0322         mv88e6xxx_get_rxts(chip, ps, skb, ptp_ops->arr1_sts_reg,
0323                    &ps->rx_queue2);
0324 }
0325 
0326 static int is_pdelay_resp(const struct ptp_header *hdr)
0327 {
0328     return (hdr->tsmt & 0xf) == 3;
0329 }
0330 
0331 bool mv88e6xxx_port_rxtstamp(struct dsa_switch *ds, int port,
0332                  struct sk_buff *skb, unsigned int type)
0333 {
0334     struct mv88e6xxx_port_hwtstamp *ps;
0335     struct mv88e6xxx_chip *chip;
0336     struct ptp_header *hdr;
0337 
0338     chip = ds->priv;
0339     ps = &chip->port_hwtstamp[port];
0340 
0341     if (ps->tstamp_config.rx_filter != HWTSTAMP_FILTER_PTP_V2_EVENT)
0342         return false;
0343 
0344     hdr = mv88e6xxx_should_tstamp(chip, port, skb, type);
0345     if (!hdr)
0346         return false;
0347 
0348     SKB_PTP_TYPE(skb) = type;
0349 
0350     if (is_pdelay_resp(hdr))
0351         skb_queue_tail(&ps->rx_queue2, skb);
0352     else
0353         skb_queue_tail(&ps->rx_queue, skb);
0354 
0355     ptp_schedule_worker(chip->ptp_clock, 0);
0356 
0357     return true;
0358 }
0359 
0360 static int mv88e6xxx_txtstamp_work(struct mv88e6xxx_chip *chip,
0361                    struct mv88e6xxx_port_hwtstamp *ps)
0362 {
0363     const struct mv88e6xxx_ptp_ops *ptp_ops = chip->info->ops->ptp_ops;
0364     struct skb_shared_hwtstamps shhwtstamps;
0365     u16 departure_block[4], status;
0366     struct sk_buff *tmp_skb;
0367     u32 time_raw;
0368     int err;
0369     u64 ns;
0370 
0371     if (!ps->tx_skb)
0372         return 0;
0373 
0374     mv88e6xxx_reg_lock(chip);
0375     err = mv88e6xxx_port_ptp_read(chip, ps->port_id,
0376                       ptp_ops->dep_sts_reg,
0377                       departure_block,
0378                       ARRAY_SIZE(departure_block));
0379     mv88e6xxx_reg_unlock(chip);
0380 
0381     if (err)
0382         goto free_and_clear_skb;
0383 
0384     if (!(departure_block[0] & MV88E6XXX_PTP_TS_VALID)) {
0385         if (time_is_before_jiffies(ps->tx_tstamp_start +
0386                        TX_TSTAMP_TIMEOUT)) {
0387             dev_warn(chip->dev, "p%d: clearing tx timestamp hang\n",
0388                  ps->port_id);
0389             goto free_and_clear_skb;
0390         }
0391         /* The timestamp should be available quickly, while getting it
0392          * is high priority and time bounded to only 10ms. A poll is
0393          * warranted so restart the work.
0394          */
0395         return 1;
0396     }
0397 
0398     /* We have the timestamp; go ahead and clear valid now */
0399     mv88e6xxx_reg_lock(chip);
0400     mv88e6xxx_port_ptp_write(chip, ps->port_id, ptp_ops->dep_sts_reg, 0);
0401     mv88e6xxx_reg_unlock(chip);
0402 
0403     status = departure_block[0] & MV88E6XXX_PTP_TS_STATUS_MASK;
0404     if (status != MV88E6XXX_PTP_TS_STATUS_NORMAL) {
0405         dev_warn(chip->dev, "p%d: tx timestamp overrun\n", ps->port_id);
0406         goto free_and_clear_skb;
0407     }
0408 
0409     if (departure_block[3] != ps->tx_seq_id) {
0410         dev_warn(chip->dev, "p%d: unexpected seq. id\n", ps->port_id);
0411         goto free_and_clear_skb;
0412     }
0413 
0414     memset(&shhwtstamps, 0, sizeof(shhwtstamps));
0415     time_raw = ((u32)departure_block[2] << 16) | departure_block[1];
0416     mv88e6xxx_reg_lock(chip);
0417     ns = timecounter_cyc2time(&chip->tstamp_tc, time_raw);
0418     mv88e6xxx_reg_unlock(chip);
0419     shhwtstamps.hwtstamp = ns_to_ktime(ns);
0420 
0421     dev_dbg(chip->dev,
0422         "p%d: txtstamp %llx status 0x%04x skb ID 0x%04x hw ID 0x%04x\n",
0423         ps->port_id, ktime_to_ns(shhwtstamps.hwtstamp),
0424         departure_block[0], ps->tx_seq_id, departure_block[3]);
0425 
0426     /* skb_complete_tx_timestamp() will free up the client to make
0427      * another timestamp-able transmit. We have to be ready for it
0428      * -- by clearing the ps->tx_skb "flag" -- beforehand.
0429      */
0430 
0431     tmp_skb = ps->tx_skb;
0432     ps->tx_skb = NULL;
0433     clear_bit_unlock(MV88E6XXX_HWTSTAMP_TX_IN_PROGRESS, &ps->state);
0434     skb_complete_tx_timestamp(tmp_skb, &shhwtstamps);
0435 
0436     return 0;
0437 
0438 free_and_clear_skb:
0439     dev_kfree_skb_any(ps->tx_skb);
0440     ps->tx_skb = NULL;
0441     clear_bit_unlock(MV88E6XXX_HWTSTAMP_TX_IN_PROGRESS, &ps->state);
0442 
0443     return 0;
0444 }
0445 
0446 long mv88e6xxx_hwtstamp_work(struct ptp_clock_info *ptp)
0447 {
0448     struct mv88e6xxx_chip *chip = ptp_to_chip(ptp);
0449     struct dsa_switch *ds = chip->ds;
0450     struct mv88e6xxx_port_hwtstamp *ps;
0451     int i, restart = 0;
0452 
0453     for (i = 0; i < ds->num_ports; i++) {
0454         if (!dsa_is_user_port(ds, i))
0455             continue;
0456 
0457         ps = &chip->port_hwtstamp[i];
0458         if (test_bit(MV88E6XXX_HWTSTAMP_TX_IN_PROGRESS, &ps->state))
0459             restart |= mv88e6xxx_txtstamp_work(chip, ps);
0460 
0461         mv88e6xxx_rxtstamp_work(chip, ps);
0462     }
0463 
0464     return restart ? 1 : -1;
0465 }
0466 
0467 void mv88e6xxx_port_txtstamp(struct dsa_switch *ds, int port,
0468                  struct sk_buff *skb)
0469 {
0470     struct mv88e6xxx_chip *chip = ds->priv;
0471     struct mv88e6xxx_port_hwtstamp *ps = &chip->port_hwtstamp[port];
0472     struct ptp_header *hdr;
0473     struct sk_buff *clone;
0474     unsigned int type;
0475 
0476     type = ptp_classify_raw(skb);
0477     if (type == PTP_CLASS_NONE)
0478         return;
0479 
0480     hdr = mv88e6xxx_should_tstamp(chip, port, skb, type);
0481     if (!hdr)
0482         return;
0483 
0484     clone = skb_clone_sk(skb);
0485     if (!clone)
0486         return;
0487 
0488     if (test_and_set_bit_lock(MV88E6XXX_HWTSTAMP_TX_IN_PROGRESS,
0489                   &ps->state)) {
0490         kfree_skb(clone);
0491         return;
0492     }
0493 
0494     ps->tx_skb = clone;
0495     ps->tx_tstamp_start = jiffies;
0496     ps->tx_seq_id = be16_to_cpu(hdr->sequence_id);
0497 
0498     ptp_schedule_worker(chip->ptp_clock, 0);
0499 }
0500 
0501 int mv88e6165_global_disable(struct mv88e6xxx_chip *chip)
0502 {
0503     u16 val;
0504     int err;
0505 
0506     err = mv88e6xxx_ptp_read(chip, MV88E6165_PTP_CFG, &val);
0507     if (err)
0508         return err;
0509     val |= MV88E6165_PTP_CFG_DISABLE_PTP;
0510 
0511     return mv88e6xxx_ptp_write(chip, MV88E6165_PTP_CFG, val);
0512 }
0513 
0514 int mv88e6165_global_enable(struct mv88e6xxx_chip *chip)
0515 {
0516     u16 val;
0517     int err;
0518 
0519     err = mv88e6xxx_ptp_read(chip, MV88E6165_PTP_CFG, &val);
0520     if (err)
0521         return err;
0522 
0523     val &= ~(MV88E6165_PTP_CFG_DISABLE_PTP | MV88E6165_PTP_CFG_TSPEC_MASK);
0524 
0525     return mv88e6xxx_ptp_write(chip, MV88E6165_PTP_CFG, val);
0526 }
0527 
0528 int mv88e6352_hwtstamp_port_disable(struct mv88e6xxx_chip *chip, int port)
0529 {
0530     return mv88e6xxx_port_ptp_write(chip, port, MV88E6XXX_PORT_PTP_CFG0,
0531                     MV88E6XXX_PORT_PTP_CFG0_DISABLE_PTP);
0532 }
0533 
0534 int mv88e6352_hwtstamp_port_enable(struct mv88e6xxx_chip *chip, int port)
0535 {
0536     return mv88e6xxx_port_ptp_write(chip, port, MV88E6XXX_PORT_PTP_CFG0,
0537                     MV88E6XXX_PORT_PTP_CFG0_DISABLE_TSPEC_MATCH);
0538 }
0539 
0540 static int mv88e6xxx_hwtstamp_port_setup(struct mv88e6xxx_chip *chip, int port)
0541 {
0542     const struct mv88e6xxx_ptp_ops *ptp_ops = chip->info->ops->ptp_ops;
0543     struct mv88e6xxx_port_hwtstamp *ps = &chip->port_hwtstamp[port];
0544 
0545     ps->port_id = port;
0546 
0547     skb_queue_head_init(&ps->rx_queue);
0548     skb_queue_head_init(&ps->rx_queue2);
0549 
0550     if (ptp_ops->port_disable)
0551         return ptp_ops->port_disable(chip, port);
0552 
0553     return 0;
0554 }
0555 
0556 int mv88e6xxx_hwtstamp_setup(struct mv88e6xxx_chip *chip)
0557 {
0558     const struct mv88e6xxx_ptp_ops *ptp_ops = chip->info->ops->ptp_ops;
0559     int err;
0560     int i;
0561 
0562     /* Disable timestamping on all ports. */
0563     for (i = 0; i < mv88e6xxx_num_ports(chip); ++i) {
0564         err = mv88e6xxx_hwtstamp_port_setup(chip, i);
0565         if (err)
0566             return err;
0567     }
0568 
0569     /* Disable PTP globally */
0570     if (ptp_ops->global_disable) {
0571         err = ptp_ops->global_disable(chip);
0572         if (err)
0573             return err;
0574     }
0575 
0576     /* Set the ethertype of L2 PTP messages */
0577     err = mv88e6xxx_ptp_write(chip, MV88E6XXX_PTP_GC_ETYPE, ETH_P_1588);
0578     if (err)
0579         return err;
0580 
0581     /* MV88E6XXX_PTP_MSG_TYPE is a mask of PTP message types to
0582      * timestamp. This affects all ports that have timestamping enabled,
0583      * but the timestamp config is per-port; thus we configure all events
0584      * here and only support the HWTSTAMP_FILTER_*_EVENT filter types.
0585      */
0586     err = mv88e6xxx_ptp_write(chip, MV88E6XXX_PTP_MSGTYPE,
0587                   MV88E6XXX_PTP_MSGTYPE_ALL_EVENT);
0588     if (err)
0589         return err;
0590 
0591     /* Use ARRIVAL1 for peer delay response messages. */
0592     err = mv88e6xxx_ptp_write(chip, MV88E6XXX_PTP_TS_ARRIVAL_PTR,
0593                   MV88E6XXX_PTP_MSGTYPE_PDLAY_RES);
0594     if (err)
0595         return err;
0596 
0597     /* 88E6341 devices default to timestamping at the PHY, but this has
0598      * a hardware issue that results in unreliable timestamps. Force
0599      * these devices to timestamp at the MAC.
0600      */
0601     if (chip->info->family == MV88E6XXX_FAMILY_6341) {
0602         u16 val = MV88E6341_PTP_CFG_UPDATE |
0603               MV88E6341_PTP_CFG_MODE_IDX |
0604               MV88E6341_PTP_CFG_MODE_TS_AT_MAC;
0605         err = mv88e6xxx_ptp_write(chip, MV88E6341_PTP_CFG, val);
0606         if (err)
0607             return err;
0608     }
0609 
0610     return 0;
0611 }
0612 
0613 void mv88e6xxx_hwtstamp_free(struct mv88e6xxx_chip *chip)
0614 {
0615 }