0001
0002
0003
0004
0005
0006
0007 #include <asm/unaligned.h>
0008 #include <linux/mii.h>
0009 #include <linux/phy.h>
0010 #include <linux/ptp_classify.h>
0011 #include <linux/ptp_clock_kernel.h>
0012 #include <linux/net_tstamp.h>
0013 #include <linux/netdevice.h>
0014 #include <linux/workqueue.h>
0015
0016 #include "bcm-phy-lib.h"
0017
0018
0019 #define SLICE_CTRL 0x0810
0020 #define SLICE_TX_EN BIT(0)
0021 #define SLICE_RX_EN BIT(8)
0022 #define TX_EVENT_MODE 0x0811
0023 #define MODE_TX_UPDATE_CF BIT(0)
0024 #define MODE_TX_REPLACE_TS_CF BIT(1)
0025 #define MODE_TX_REPLACE_TS GENMASK(1, 0)
0026 #define RX_EVENT_MODE 0x0819
0027 #define MODE_RX_UPDATE_CF BIT(0)
0028 #define MODE_RX_INSERT_TS_48 BIT(1)
0029 #define MODE_RX_INSERT_TS_64 GENMASK(1, 0)
0030
0031 #define MODE_EVT_SHIFT_SYNC 0
0032 #define MODE_EVT_SHIFT_DELAY_REQ 2
0033 #define MODE_EVT_SHIFT_PDELAY_REQ 4
0034 #define MODE_EVT_SHIFT_PDELAY_RESP 6
0035
0036 #define MODE_SEL_SHIFT_PORT 0
0037 #define MODE_SEL_SHIFT_CPU 8
0038
0039 #define RX_MODE_SEL(sel, evt, act) \
0040 (((MODE_RX_##act) << (MODE_EVT_SHIFT_##evt)) << (MODE_SEL_SHIFT_##sel))
0041
0042 #define TX_MODE_SEL(sel, evt, act) \
0043 (((MODE_TX_##act) << (MODE_EVT_SHIFT_##evt)) << (MODE_SEL_SHIFT_##sel))
0044
0045
0046 #define TX_TS_CAPTURE 0x0821
0047 #define TX_TS_CAP_EN BIT(0)
0048 #define RX_TS_CAPTURE 0x0822
0049 #define RX_TS_CAP_EN BIT(0)
0050
0051 #define TIME_CODE_0 0x0854
0052 #define TIME_CODE_1 0x0855
0053 #define TIME_CODE_2 0x0856
0054 #define TIME_CODE_3 0x0857
0055 #define TIME_CODE_4 0x0858
0056
0057 #define DPLL_SELECT 0x085b
0058 #define DPLL_HB_MODE2 BIT(6)
0059
0060 #define SHADOW_CTRL 0x085c
0061 #define SHADOW_LOAD 0x085d
0062 #define TIME_CODE_LOAD BIT(10)
0063 #define SYNC_OUT_LOAD BIT(9)
0064 #define NCO_TIME_LOAD BIT(7)
0065 #define FREQ_LOAD BIT(6)
0066 #define INTR_MASK 0x085e
0067 #define INTR_STATUS 0x085f
0068 #define INTC_FSYNC BIT(0)
0069 #define INTC_SOP BIT(1)
0070
0071 #define NCO_FREQ_LSB 0x0873
0072 #define NCO_FREQ_MSB 0x0874
0073
0074 #define NCO_TIME_0 0x0875
0075 #define NCO_TIME_1 0x0876
0076 #define NCO_TIME_2_CTRL 0x0877
0077 #define FREQ_MDIO_SEL BIT(14)
0078
0079 #define SYNC_OUT_0 0x0878
0080 #define SYNC_OUT_1 0x0879
0081 #define SYNC_OUT_2 0x087a
0082
0083 #define SYNC_IN_DIVIDER 0x087b
0084
0085 #define SYNOUT_TS_0 0x087c
0086 #define SYNOUT_TS_1 0x087d
0087 #define SYNOUT_TS_2 0x087e
0088
0089 #define NSE_CTRL 0x087f
0090 #define NSE_GMODE_EN GENMASK(15, 14)
0091 #define NSE_CAPTURE_EN BIT(13)
0092 #define NSE_INIT BIT(12)
0093 #define NSE_CPU_FRAMESYNC BIT(5)
0094 #define NSE_SYNC1_FRAMESYNC BIT(3)
0095 #define NSE_FRAMESYNC_MASK GENMASK(5, 2)
0096 #define NSE_PEROUT_EN BIT(1)
0097 #define NSE_ONESHOT_EN BIT(0)
0098 #define NSE_SYNC_OUT_MASK GENMASK(1, 0)
0099
0100 #define TS_READ_CTRL 0x0885
0101 #define TS_READ_START BIT(0)
0102 #define TS_READ_END BIT(1)
0103
0104 #define HB_REG_0 0x0886
0105 #define HB_REG_1 0x0887
0106 #define HB_REG_2 0x0888
0107 #define HB_REG_3 0x08ec
0108 #define HB_REG_4 0x08ed
0109 #define HB_STAT_CTRL 0x088e
0110 #define HB_READ_START BIT(10)
0111 #define HB_READ_END BIT(11)
0112 #define HB_READ_MASK GENMASK(11, 10)
0113
0114 #define TS_REG_0 0x0889
0115 #define TS_REG_1 0x088a
0116 #define TS_REG_2 0x088b
0117 #define TS_REG_3 0x08c4
0118
0119 #define TS_INFO_0 0x088c
0120 #define TS_INFO_1 0x088d
0121
0122 #define TIMECODE_CTRL 0x08c3
0123 #define TX_TIMECODE_SEL GENMASK(7, 0)
0124 #define RX_TIMECODE_SEL GENMASK(15, 8)
0125
0126 #define TIME_SYNC 0x0ff5
0127 #define TIME_SYNC_EN BIT(0)
0128
0129 struct bcm_ptp_private {
0130 struct phy_device *phydev;
0131 struct mii_timestamper mii_ts;
0132 struct ptp_clock *ptp_clock;
0133 struct ptp_clock_info ptp_info;
0134 struct ptp_pin_desc pin;
0135 struct mutex mutex;
0136 struct sk_buff_head tx_queue;
0137 int tx_type;
0138 bool hwts_rx;
0139 u16 nse_ctrl;
0140 bool pin_active;
0141 struct delayed_work pin_work;
0142 };
0143
0144 struct bcm_ptp_skb_cb {
0145 unsigned long timeout;
0146 u16 seq_id;
0147 u8 msgtype;
0148 bool discard;
0149 };
0150
0151 struct bcm_ptp_capture {
0152 ktime_t hwtstamp;
0153 u16 seq_id;
0154 u8 msgtype;
0155 bool tx_dir;
0156 };
0157
0158 #define BCM_SKB_CB(skb) ((struct bcm_ptp_skb_cb *)(skb)->cb)
0159 #define SKB_TS_TIMEOUT 10
0160
0161 #define BCM_MAX_PULSE_8NS ((1U << 9) - 1)
0162 #define BCM_MAX_PERIOD_8NS ((1U << 30) - 1)
0163
0164 #define BRCM_PHY_MODEL(phydev) \
0165 ((phydev)->drv->phy_id & (phydev)->drv->phy_id_mask)
0166
0167 static struct bcm_ptp_private *mii2priv(struct mii_timestamper *mii_ts)
0168 {
0169 return container_of(mii_ts, struct bcm_ptp_private, mii_ts);
0170 }
0171
0172 static struct bcm_ptp_private *ptp2priv(struct ptp_clock_info *info)
0173 {
0174 return container_of(info, struct bcm_ptp_private, ptp_info);
0175 }
0176
0177 static void bcm_ptp_get_framesync_ts(struct phy_device *phydev,
0178 struct timespec64 *ts)
0179 {
0180 u16 hb[4];
0181
0182 bcm_phy_write_exp(phydev, HB_STAT_CTRL, HB_READ_START);
0183
0184 hb[0] = bcm_phy_read_exp(phydev, HB_REG_0);
0185 hb[1] = bcm_phy_read_exp(phydev, HB_REG_1);
0186 hb[2] = bcm_phy_read_exp(phydev, HB_REG_2);
0187 hb[3] = bcm_phy_read_exp(phydev, HB_REG_3);
0188
0189 bcm_phy_write_exp(phydev, HB_STAT_CTRL, HB_READ_END);
0190 bcm_phy_write_exp(phydev, HB_STAT_CTRL, 0);
0191
0192 ts->tv_sec = (hb[3] << 16) | hb[2];
0193 ts->tv_nsec = (hb[1] << 16) | hb[0];
0194 }
0195
0196 static u16 bcm_ptp_framesync_disable(struct phy_device *phydev, u16 orig_ctrl)
0197 {
0198 u16 ctrl = orig_ctrl & ~(NSE_FRAMESYNC_MASK | NSE_CAPTURE_EN);
0199
0200 bcm_phy_write_exp(phydev, NSE_CTRL, ctrl);
0201
0202 return ctrl;
0203 }
0204
0205 static void bcm_ptp_framesync_restore(struct phy_device *phydev, u16 orig_ctrl)
0206 {
0207 if (orig_ctrl & NSE_FRAMESYNC_MASK)
0208 bcm_phy_write_exp(phydev, NSE_CTRL, orig_ctrl);
0209 }
0210
0211 static void bcm_ptp_framesync(struct phy_device *phydev, u16 ctrl)
0212 {
0213
0214 bcm_phy_write_exp(phydev, NSE_CTRL, ctrl | NSE_CPU_FRAMESYNC);
0215 }
0216
0217 static int bcm_ptp_framesync_ts(struct phy_device *phydev,
0218 struct ptp_system_timestamp *sts,
0219 struct timespec64 *ts,
0220 u16 orig_ctrl)
0221 {
0222 u16 ctrl, reg;
0223 int i;
0224
0225 ctrl = bcm_ptp_framesync_disable(phydev, orig_ctrl);
0226
0227 ptp_read_system_prets(sts);
0228
0229
0230 bcm_ptp_framesync(phydev, ctrl | NSE_CAPTURE_EN);
0231
0232 ptp_read_system_postts(sts);
0233
0234
0235 for (i = 0; i < 10; i++) {
0236 reg = bcm_phy_read_exp(phydev, INTR_STATUS);
0237 if (reg & INTC_FSYNC) {
0238 bcm_ptp_get_framesync_ts(phydev, ts);
0239 break;
0240 }
0241 }
0242
0243 bcm_ptp_framesync_restore(phydev, orig_ctrl);
0244
0245 return reg & INTC_FSYNC ? 0 : -ETIMEDOUT;
0246 }
0247
0248 static int bcm_ptp_gettimex(struct ptp_clock_info *info,
0249 struct timespec64 *ts,
0250 struct ptp_system_timestamp *sts)
0251 {
0252 struct bcm_ptp_private *priv = ptp2priv(info);
0253 int err;
0254
0255 mutex_lock(&priv->mutex);
0256 err = bcm_ptp_framesync_ts(priv->phydev, sts, ts, priv->nse_ctrl);
0257 mutex_unlock(&priv->mutex);
0258
0259 return err;
0260 }
0261
0262 static int bcm_ptp_settime_locked(struct bcm_ptp_private *priv,
0263 const struct timespec64 *ts)
0264 {
0265 struct phy_device *phydev = priv->phydev;
0266 u16 ctrl;
0267 u64 ns;
0268
0269 ctrl = bcm_ptp_framesync_disable(phydev, priv->nse_ctrl);
0270
0271
0272 bcm_phy_write_exp(phydev, TIME_CODE_0, ts->tv_nsec);
0273 bcm_phy_write_exp(phydev, TIME_CODE_1, ts->tv_nsec >> 16);
0274 bcm_phy_write_exp(phydev, TIME_CODE_2, ts->tv_sec);
0275 bcm_phy_write_exp(phydev, TIME_CODE_3, ts->tv_sec >> 16);
0276 bcm_phy_write_exp(phydev, TIME_CODE_4, ts->tv_sec >> 32);
0277
0278
0279 ns = timespec64_to_ns(ts);
0280 bcm_phy_write_exp(phydev, NCO_TIME_0, ns >> 4);
0281 bcm_phy_write_exp(phydev, NCO_TIME_1, ns >> 20);
0282 bcm_phy_write_exp(phydev, NCO_TIME_2_CTRL, (ns >> 36) & 0xfff);
0283
0284
0285 bcm_phy_write_exp(phydev, SHADOW_LOAD, TIME_CODE_LOAD | NCO_TIME_LOAD);
0286
0287
0288 bcm_ptp_framesync(phydev, ctrl | NSE_INIT);
0289
0290 bcm_ptp_framesync_restore(phydev, priv->nse_ctrl);
0291
0292 return 0;
0293 }
0294
0295 static int bcm_ptp_settime(struct ptp_clock_info *info,
0296 const struct timespec64 *ts)
0297 {
0298 struct bcm_ptp_private *priv = ptp2priv(info);
0299 int err;
0300
0301 mutex_lock(&priv->mutex);
0302 err = bcm_ptp_settime_locked(priv, ts);
0303 mutex_unlock(&priv->mutex);
0304
0305 return err;
0306 }
0307
0308 static int bcm_ptp_adjtime_locked(struct bcm_ptp_private *priv,
0309 s64 delta_ns)
0310 {
0311 struct timespec64 ts;
0312 int err;
0313 s64 ns;
0314
0315 err = bcm_ptp_framesync_ts(priv->phydev, NULL, &ts, priv->nse_ctrl);
0316 if (!err) {
0317 ns = timespec64_to_ns(&ts) + delta_ns;
0318 ts = ns_to_timespec64(ns);
0319 err = bcm_ptp_settime_locked(priv, &ts);
0320 }
0321 return err;
0322 }
0323
0324 static int bcm_ptp_adjtime(struct ptp_clock_info *info, s64 delta_ns)
0325 {
0326 struct bcm_ptp_private *priv = ptp2priv(info);
0327 int err;
0328
0329 mutex_lock(&priv->mutex);
0330 err = bcm_ptp_adjtime_locked(priv, delta_ns);
0331 mutex_unlock(&priv->mutex);
0332
0333 return err;
0334 }
0335
0336
0337
0338
0339
0340
0341
0342
0343
0344 static int bcm_ptp_adjfine(struct ptp_clock_info *info, long scaled_ppm)
0345 {
0346 struct bcm_ptp_private *priv = ptp2priv(info);
0347 int neg_adj = 0;
0348 u32 diff, freq;
0349 u16 ctrl;
0350 u64 adj;
0351
0352 if (scaled_ppm < 0) {
0353 neg_adj = 1;
0354 scaled_ppm = -scaled_ppm;
0355 }
0356
0357 adj = scaled_ppm << 9;
0358 diff = div_u64(adj, 15625);
0359 freq = (8 << 28) + (neg_adj ? -diff : diff);
0360
0361 mutex_lock(&priv->mutex);
0362
0363 ctrl = bcm_ptp_framesync_disable(priv->phydev, priv->nse_ctrl);
0364
0365 bcm_phy_write_exp(priv->phydev, NCO_FREQ_LSB, freq);
0366 bcm_phy_write_exp(priv->phydev, NCO_FREQ_MSB, freq >> 16);
0367
0368 bcm_phy_write_exp(priv->phydev, NCO_TIME_2_CTRL, FREQ_MDIO_SEL);
0369
0370
0371 bcm_phy_write_exp(priv->phydev, SHADOW_LOAD, FREQ_LOAD);
0372
0373 bcm_ptp_framesync(priv->phydev, ctrl);
0374
0375
0376 bcm_phy_write_exp(priv->phydev, SHADOW_LOAD, 0);
0377
0378 bcm_ptp_framesync_restore(priv->phydev, priv->nse_ctrl);
0379
0380 mutex_unlock(&priv->mutex);
0381
0382 return 0;
0383 }
0384
0385 static bool bcm_ptp_rxtstamp(struct mii_timestamper *mii_ts,
0386 struct sk_buff *skb, int type)
0387 {
0388 struct bcm_ptp_private *priv = mii2priv(mii_ts);
0389 struct skb_shared_hwtstamps *hwts;
0390 struct ptp_header *header;
0391 u32 sec, nsec;
0392 u8 *data;
0393 int off;
0394
0395 if (!priv->hwts_rx)
0396 return false;
0397
0398 header = ptp_parse_header(skb, type);
0399 if (!header)
0400 return false;
0401
0402 data = (u8 *)(header + 1);
0403 sec = get_unaligned_be32(data);
0404 nsec = get_unaligned_be32(data + 4);
0405
0406 hwts = skb_hwtstamps(skb);
0407 hwts->hwtstamp = ktime_set(sec, nsec);
0408
0409 off = data - skb->data + 8;
0410 if (off < skb->len) {
0411 memmove(data, data + 8, skb->len - off);
0412 __pskb_trim(skb, skb->len - 8);
0413 }
0414
0415 return false;
0416 }
0417
0418 static bool bcm_ptp_get_tstamp(struct bcm_ptp_private *priv,
0419 struct bcm_ptp_capture *capts)
0420 {
0421 struct phy_device *phydev = priv->phydev;
0422 u16 ts[4], reg;
0423 u32 sec, nsec;
0424
0425 mutex_lock(&priv->mutex);
0426
0427 reg = bcm_phy_read_exp(phydev, INTR_STATUS);
0428 if ((reg & INTC_SOP) == 0) {
0429 mutex_unlock(&priv->mutex);
0430 return false;
0431 }
0432
0433 bcm_phy_write_exp(phydev, TS_READ_CTRL, TS_READ_START);
0434
0435 ts[0] = bcm_phy_read_exp(phydev, TS_REG_0);
0436 ts[1] = bcm_phy_read_exp(phydev, TS_REG_1);
0437 ts[2] = bcm_phy_read_exp(phydev, TS_REG_2);
0438 ts[3] = bcm_phy_read_exp(phydev, TS_REG_3);
0439
0440
0441 capts->seq_id = bcm_phy_read_exp(priv->phydev, TS_INFO_0);
0442
0443 reg = bcm_phy_read_exp(phydev, TS_INFO_1);
0444 capts->msgtype = reg >> 12;
0445 capts->tx_dir = !!(reg & BIT(11));
0446
0447 bcm_phy_write_exp(phydev, TS_READ_CTRL, TS_READ_END);
0448 bcm_phy_write_exp(phydev, TS_READ_CTRL, 0);
0449
0450 mutex_unlock(&priv->mutex);
0451
0452 sec = (ts[3] << 16) | ts[2];
0453 nsec = (ts[1] << 16) | ts[0];
0454 capts->hwtstamp = ktime_set(sec, nsec);
0455
0456 return true;
0457 }
0458
0459 static void bcm_ptp_match_tstamp(struct bcm_ptp_private *priv,
0460 struct bcm_ptp_capture *capts)
0461 {
0462 struct skb_shared_hwtstamps hwts;
0463 struct sk_buff *skb, *ts_skb;
0464 unsigned long flags;
0465 bool first = false;
0466
0467 ts_skb = NULL;
0468 spin_lock_irqsave(&priv->tx_queue.lock, flags);
0469 skb_queue_walk(&priv->tx_queue, skb) {
0470 if (BCM_SKB_CB(skb)->seq_id == capts->seq_id &&
0471 BCM_SKB_CB(skb)->msgtype == capts->msgtype) {
0472 first = skb_queue_is_first(&priv->tx_queue, skb);
0473 __skb_unlink(skb, &priv->tx_queue);
0474 ts_skb = skb;
0475 break;
0476 }
0477 }
0478 spin_unlock_irqrestore(&priv->tx_queue.lock, flags);
0479
0480
0481 if (ts_skb) {
0482 if (BCM_SKB_CB(ts_skb)->discard) {
0483 kfree_skb(ts_skb);
0484 } else {
0485 memset(&hwts, 0, sizeof(hwts));
0486 hwts.hwtstamp = capts->hwtstamp;
0487 skb_complete_tx_timestamp(ts_skb, &hwts);
0488 }
0489 }
0490
0491
0492 if (!first) {
0493 while ((skb = skb_dequeue(&priv->tx_queue))) {
0494 if (!time_after(jiffies, BCM_SKB_CB(skb)->timeout)) {
0495 skb_queue_head(&priv->tx_queue, skb);
0496 break;
0497 }
0498 kfree_skb(skb);
0499 }
0500 }
0501 }
0502
0503 static long bcm_ptp_do_aux_work(struct ptp_clock_info *info)
0504 {
0505 struct bcm_ptp_private *priv = ptp2priv(info);
0506 struct bcm_ptp_capture capts;
0507 bool reschedule = false;
0508
0509 while (!skb_queue_empty_lockless(&priv->tx_queue)) {
0510 if (!bcm_ptp_get_tstamp(priv, &capts)) {
0511 reschedule = true;
0512 break;
0513 }
0514 bcm_ptp_match_tstamp(priv, &capts);
0515 }
0516
0517 return reschedule ? 1 : -1;
0518 }
0519
0520 static int bcm_ptp_cancel_func(struct bcm_ptp_private *priv)
0521 {
0522 if (!priv->pin_active)
0523 return 0;
0524
0525 priv->pin_active = false;
0526
0527 priv->nse_ctrl &= ~(NSE_SYNC_OUT_MASK | NSE_SYNC1_FRAMESYNC |
0528 NSE_CAPTURE_EN);
0529 bcm_phy_write_exp(priv->phydev, NSE_CTRL, priv->nse_ctrl);
0530
0531 cancel_delayed_work_sync(&priv->pin_work);
0532
0533 return 0;
0534 }
0535
0536 static void bcm_ptp_perout_work(struct work_struct *pin_work)
0537 {
0538 struct bcm_ptp_private *priv =
0539 container_of(pin_work, struct bcm_ptp_private, pin_work.work);
0540 struct phy_device *phydev = priv->phydev;
0541 struct timespec64 ts;
0542 u64 ns, next;
0543 u16 ctrl;
0544
0545 mutex_lock(&priv->mutex);
0546
0547
0548 if (!priv->pin_active) {
0549 mutex_unlock(&priv->mutex);
0550 return;
0551 }
0552
0553 bcm_ptp_framesync_ts(phydev, NULL, &ts, priv->nse_ctrl);
0554
0555
0556 next = NSEC_PER_SEC - ts.tv_nsec;
0557 ts.tv_sec += next < NSEC_PER_MSEC ? 2 : 1;
0558 ts.tv_nsec = 0;
0559
0560 ns = timespec64_to_ns(&ts);
0561
0562
0563 ctrl = bcm_ptp_framesync_disable(phydev,
0564 priv->nse_ctrl & ~NSE_ONESHOT_EN);
0565
0566 bcm_phy_write_exp(phydev, SYNOUT_TS_0, ns & 0xfff0);
0567 bcm_phy_write_exp(phydev, SYNOUT_TS_1, ns >> 16);
0568 bcm_phy_write_exp(phydev, SYNOUT_TS_2, ns >> 32);
0569
0570
0571 bcm_phy_write_exp(phydev, SHADOW_LOAD, SYNC_OUT_LOAD);
0572
0573 bcm_ptp_framesync(phydev, ctrl | NSE_ONESHOT_EN | NSE_INIT);
0574
0575 priv->nse_ctrl |= NSE_ONESHOT_EN;
0576 bcm_ptp_framesync_restore(phydev, priv->nse_ctrl);
0577
0578 mutex_unlock(&priv->mutex);
0579
0580 next = next + NSEC_PER_MSEC;
0581 schedule_delayed_work(&priv->pin_work, nsecs_to_jiffies(next));
0582 }
0583
0584 static int bcm_ptp_perout_locked(struct bcm_ptp_private *priv,
0585 struct ptp_perout_request *req, int on)
0586 {
0587 struct phy_device *phydev = priv->phydev;
0588 u64 period, pulse;
0589 u16 val;
0590
0591 if (!on)
0592 return bcm_ptp_cancel_func(priv);
0593
0594
0595 if (req->period.sec != 1 || req->period.nsec != 0)
0596 return -EINVAL;
0597
0598 period = BCM_MAX_PERIOD_8NS;
0599
0600 if (req->flags & PTP_PEROUT_PHASE)
0601 return -EOPNOTSUPP;
0602
0603 if (req->flags & PTP_PEROUT_DUTY_CYCLE)
0604 pulse = ktime_to_ns(ktime_set(req->on.sec, req->on.nsec));
0605 else
0606 pulse = (u64)BCM_MAX_PULSE_8NS << 3;
0607
0608
0609 pulse >>= 3;
0610
0611 if (!pulse || pulse > period || pulse > BCM_MAX_PULSE_8NS)
0612 return -EINVAL;
0613
0614 bcm_phy_write_exp(phydev, SYNC_OUT_0, period);
0615
0616 val = ((pulse & 0x3) << 14) | ((period >> 16) & 0x3fff);
0617 bcm_phy_write_exp(phydev, SYNC_OUT_1, val);
0618
0619 val = ((pulse >> 2) & 0x7f) | (pulse << 7);
0620 bcm_phy_write_exp(phydev, SYNC_OUT_2, val);
0621
0622 if (priv->pin_active)
0623 cancel_delayed_work_sync(&priv->pin_work);
0624
0625 priv->pin_active = true;
0626 INIT_DELAYED_WORK(&priv->pin_work, bcm_ptp_perout_work);
0627 schedule_delayed_work(&priv->pin_work, 0);
0628
0629 return 0;
0630 }
0631
0632 static void bcm_ptp_extts_work(struct work_struct *pin_work)
0633 {
0634 struct bcm_ptp_private *priv =
0635 container_of(pin_work, struct bcm_ptp_private, pin_work.work);
0636 struct phy_device *phydev = priv->phydev;
0637 struct ptp_clock_event event;
0638 struct timespec64 ts;
0639 u16 reg;
0640
0641 mutex_lock(&priv->mutex);
0642
0643
0644 if (!priv->pin_active) {
0645 mutex_unlock(&priv->mutex);
0646 return;
0647 }
0648
0649 reg = bcm_phy_read_exp(phydev, INTR_STATUS);
0650 if ((reg & INTC_FSYNC) == 0)
0651 goto out;
0652
0653 bcm_ptp_get_framesync_ts(phydev, &ts);
0654
0655 event.index = 0;
0656 event.type = PTP_CLOCK_EXTTS;
0657 event.timestamp = timespec64_to_ns(&ts);
0658 ptp_clock_event(priv->ptp_clock, &event);
0659
0660 out:
0661 mutex_unlock(&priv->mutex);
0662 schedule_delayed_work(&priv->pin_work, HZ / 4);
0663 }
0664
0665 static int bcm_ptp_extts_locked(struct bcm_ptp_private *priv, int on)
0666 {
0667 struct phy_device *phydev = priv->phydev;
0668
0669 if (!on)
0670 return bcm_ptp_cancel_func(priv);
0671
0672 if (priv->pin_active)
0673 cancel_delayed_work_sync(&priv->pin_work);
0674
0675 bcm_ptp_framesync_disable(phydev, priv->nse_ctrl);
0676
0677 priv->nse_ctrl |= NSE_SYNC1_FRAMESYNC | NSE_CAPTURE_EN;
0678
0679 bcm_ptp_framesync_restore(phydev, priv->nse_ctrl);
0680
0681 priv->pin_active = true;
0682 INIT_DELAYED_WORK(&priv->pin_work, bcm_ptp_extts_work);
0683 schedule_delayed_work(&priv->pin_work, 0);
0684
0685 return 0;
0686 }
0687
0688 static int bcm_ptp_enable(struct ptp_clock_info *info,
0689 struct ptp_clock_request *rq, int on)
0690 {
0691 struct bcm_ptp_private *priv = ptp2priv(info);
0692 int err = -EBUSY;
0693
0694 mutex_lock(&priv->mutex);
0695
0696 switch (rq->type) {
0697 case PTP_CLK_REQ_PEROUT:
0698 if (priv->pin.func == PTP_PF_PEROUT)
0699 err = bcm_ptp_perout_locked(priv, &rq->perout, on);
0700 break;
0701 case PTP_CLK_REQ_EXTTS:
0702 if (priv->pin.func == PTP_PF_EXTTS)
0703 err = bcm_ptp_extts_locked(priv, on);
0704 break;
0705 default:
0706 err = -EOPNOTSUPP;
0707 break;
0708 }
0709
0710 mutex_unlock(&priv->mutex);
0711
0712 return err;
0713 }
0714
0715 static int bcm_ptp_verify(struct ptp_clock_info *info, unsigned int pin,
0716 enum ptp_pin_function func, unsigned int chan)
0717 {
0718 switch (func) {
0719 case PTP_PF_NONE:
0720 case PTP_PF_EXTTS:
0721 case PTP_PF_PEROUT:
0722 break;
0723 default:
0724 return -EOPNOTSUPP;
0725 }
0726 return 0;
0727 }
0728
0729 static const struct ptp_clock_info bcm_ptp_clock_info = {
0730 .owner = THIS_MODULE,
0731 .name = KBUILD_MODNAME,
0732 .max_adj = 100000000,
0733 .gettimex64 = bcm_ptp_gettimex,
0734 .settime64 = bcm_ptp_settime,
0735 .adjtime = bcm_ptp_adjtime,
0736 .adjfine = bcm_ptp_adjfine,
0737 .enable = bcm_ptp_enable,
0738 .verify = bcm_ptp_verify,
0739 .do_aux_work = bcm_ptp_do_aux_work,
0740 .n_pins = 1,
0741 .n_per_out = 1,
0742 .n_ext_ts = 1,
0743 };
0744
0745 static void bcm_ptp_txtstamp(struct mii_timestamper *mii_ts,
0746 struct sk_buff *skb, int type)
0747 {
0748 struct bcm_ptp_private *priv = mii2priv(mii_ts);
0749 struct ptp_header *hdr;
0750 bool discard = false;
0751 int msgtype;
0752
0753 hdr = ptp_parse_header(skb, type);
0754 if (!hdr)
0755 goto out;
0756 msgtype = ptp_get_msgtype(hdr, type);
0757
0758 switch (priv->tx_type) {
0759 case HWTSTAMP_TX_ONESTEP_P2P:
0760 if (msgtype == PTP_MSGTYPE_PDELAY_RESP)
0761 discard = true;
0762 fallthrough;
0763 case HWTSTAMP_TX_ONESTEP_SYNC:
0764 if (msgtype == PTP_MSGTYPE_SYNC)
0765 discard = true;
0766 fallthrough;
0767 case HWTSTAMP_TX_ON:
0768 BCM_SKB_CB(skb)->timeout = jiffies + SKB_TS_TIMEOUT;
0769 BCM_SKB_CB(skb)->seq_id = be16_to_cpu(hdr->sequence_id);
0770 BCM_SKB_CB(skb)->msgtype = msgtype;
0771 BCM_SKB_CB(skb)->discard = discard;
0772 skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
0773 skb_queue_tail(&priv->tx_queue, skb);
0774 ptp_schedule_worker(priv->ptp_clock, 0);
0775 return;
0776 default:
0777 break;
0778 }
0779
0780 out:
0781 kfree_skb(skb);
0782 }
0783
0784 static int bcm_ptp_hwtstamp(struct mii_timestamper *mii_ts,
0785 struct ifreq *ifr)
0786 {
0787 struct bcm_ptp_private *priv = mii2priv(mii_ts);
0788 struct hwtstamp_config cfg;
0789 u16 mode, ctrl;
0790
0791 if (copy_from_user(&cfg, ifr->ifr_data, sizeof(cfg)))
0792 return -EFAULT;
0793
0794 switch (cfg.rx_filter) {
0795 case HWTSTAMP_FILTER_NONE:
0796 priv->hwts_rx = false;
0797 break;
0798 case HWTSTAMP_FILTER_PTP_V2_L4_EVENT:
0799 case HWTSTAMP_FILTER_PTP_V2_L4_SYNC:
0800 case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ:
0801 case HWTSTAMP_FILTER_PTP_V2_L2_EVENT:
0802 case HWTSTAMP_FILTER_PTP_V2_L2_SYNC:
0803 case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ:
0804 case HWTSTAMP_FILTER_PTP_V2_EVENT:
0805 case HWTSTAMP_FILTER_PTP_V2_SYNC:
0806 case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ:
0807 cfg.rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT;
0808 priv->hwts_rx = true;
0809 break;
0810 default:
0811 return -ERANGE;
0812 }
0813
0814 priv->tx_type = cfg.tx_type;
0815
0816 ctrl = priv->hwts_rx ? SLICE_RX_EN : 0;
0817 ctrl |= priv->tx_type != HWTSTAMP_TX_OFF ? SLICE_TX_EN : 0;
0818
0819 mode = TX_MODE_SEL(PORT, SYNC, REPLACE_TS) |
0820 TX_MODE_SEL(PORT, DELAY_REQ, REPLACE_TS) |
0821 TX_MODE_SEL(PORT, PDELAY_REQ, REPLACE_TS) |
0822 TX_MODE_SEL(PORT, PDELAY_RESP, REPLACE_TS);
0823
0824 bcm_phy_write_exp(priv->phydev, TX_EVENT_MODE, mode);
0825
0826 mode = RX_MODE_SEL(PORT, SYNC, INSERT_TS_64) |
0827 RX_MODE_SEL(PORT, DELAY_REQ, INSERT_TS_64) |
0828 RX_MODE_SEL(PORT, PDELAY_REQ, INSERT_TS_64) |
0829 RX_MODE_SEL(PORT, PDELAY_RESP, INSERT_TS_64);
0830
0831 bcm_phy_write_exp(priv->phydev, RX_EVENT_MODE, mode);
0832
0833 bcm_phy_write_exp(priv->phydev, SLICE_CTRL, ctrl);
0834
0835 if (ctrl & SLICE_TX_EN)
0836 bcm_phy_write_exp(priv->phydev, TX_TS_CAPTURE, TX_TS_CAP_EN);
0837 else
0838 ptp_cancel_worker_sync(priv->ptp_clock);
0839
0840
0841 skb_queue_purge(&priv->tx_queue);
0842
0843 return copy_to_user(ifr->ifr_data, &cfg, sizeof(cfg)) ? -EFAULT : 0;
0844 }
0845
0846 static int bcm_ptp_ts_info(struct mii_timestamper *mii_ts,
0847 struct ethtool_ts_info *ts_info)
0848 {
0849 struct bcm_ptp_private *priv = mii2priv(mii_ts);
0850
0851 ts_info->phc_index = ptp_clock_index(priv->ptp_clock);
0852 ts_info->so_timestamping =
0853 SOF_TIMESTAMPING_TX_HARDWARE |
0854 SOF_TIMESTAMPING_RX_HARDWARE |
0855 SOF_TIMESTAMPING_RAW_HARDWARE;
0856 ts_info->tx_types =
0857 BIT(HWTSTAMP_TX_ON) |
0858 BIT(HWTSTAMP_TX_OFF) |
0859 BIT(HWTSTAMP_TX_ONESTEP_SYNC) |
0860 BIT(HWTSTAMP_TX_ONESTEP_P2P);
0861 ts_info->rx_filters =
0862 BIT(HWTSTAMP_FILTER_NONE) |
0863 BIT(HWTSTAMP_FILTER_PTP_V2_EVENT);
0864
0865 return 0;
0866 }
0867
0868 void bcm_ptp_stop(struct bcm_ptp_private *priv)
0869 {
0870 ptp_cancel_worker_sync(priv->ptp_clock);
0871 bcm_ptp_cancel_func(priv);
0872 }
0873 EXPORT_SYMBOL_GPL(bcm_ptp_stop);
0874
0875 void bcm_ptp_config_init(struct phy_device *phydev)
0876 {
0877
0878 bcm_phy_write_exp(phydev, NSE_CTRL, NSE_GMODE_EN | NSE_INIT);
0879
0880
0881 bcm_phy_write_exp(phydev, TIME_SYNC, TIME_SYNC_EN);
0882
0883
0884 bcm_phy_write_exp(phydev, DPLL_SELECT, DPLL_HB_MODE2);
0885
0886
0887 bcm_phy_write_exp(phydev, TIMECODE_CTRL, TX_TIMECODE_SEL);
0888
0889
0890 bcm_phy_write_exp(phydev, SHADOW_CTRL, FREQ_LOAD);
0891
0892 bcm_phy_write_exp(phydev, SYNC_IN_DIVIDER, 1);
0893 }
0894 EXPORT_SYMBOL_GPL(bcm_ptp_config_init);
0895
0896 static void bcm_ptp_init(struct bcm_ptp_private *priv)
0897 {
0898 priv->nse_ctrl = NSE_GMODE_EN;
0899
0900 mutex_init(&priv->mutex);
0901 skb_queue_head_init(&priv->tx_queue);
0902
0903 priv->mii_ts.rxtstamp = bcm_ptp_rxtstamp;
0904 priv->mii_ts.txtstamp = bcm_ptp_txtstamp;
0905 priv->mii_ts.hwtstamp = bcm_ptp_hwtstamp;
0906 priv->mii_ts.ts_info = bcm_ptp_ts_info;
0907
0908 priv->phydev->mii_ts = &priv->mii_ts;
0909 }
0910
0911 struct bcm_ptp_private *bcm_ptp_probe(struct phy_device *phydev)
0912 {
0913 struct bcm_ptp_private *priv;
0914 struct ptp_clock *clock;
0915
0916 switch (BRCM_PHY_MODEL(phydev)) {
0917 case PHY_ID_BCM54210E:
0918 break;
0919 default:
0920 return NULL;
0921 }
0922
0923 priv = devm_kzalloc(&phydev->mdio.dev, sizeof(*priv), GFP_KERNEL);
0924 if (!priv)
0925 return ERR_PTR(-ENOMEM);
0926
0927 priv->ptp_info = bcm_ptp_clock_info;
0928
0929 snprintf(priv->pin.name, sizeof(priv->pin.name), "SYNC_OUT");
0930 priv->ptp_info.pin_config = &priv->pin;
0931
0932 clock = ptp_clock_register(&priv->ptp_info, &phydev->mdio.dev);
0933 if (IS_ERR(clock))
0934 return ERR_CAST(clock);
0935 priv->ptp_clock = clock;
0936
0937 priv->phydev = phydev;
0938 bcm_ptp_init(priv);
0939
0940 return priv;
0941 }
0942 EXPORT_SYMBOL_GPL(bcm_ptp_probe);
0943
0944 MODULE_LICENSE("GPL");