Lines Matching +full:ptp +full:- +full:ref
1 // SPDX-License-Identifier: GPL-2.0+
12 * The value is calculated as following: (1/1000000)/((2^-59)/6.037735849)
23 /* This represents the base rule ID for the PTP rules that are added in the
57 struct lan966x *lan966x = port->lan966x; in lan966x_ptp_add_trap()
61 vrule = vcap_get_rule(lan966x->vcap_ctrl, rule_id); in lan966x_ptp_add_trap()
68 mask &= ~BIT(port->chip_port); in lan966x_ptp_add_trap()
76 vrule = vcap_alloc_rule(lan966x->vcap_ctrl, port->dev, in lan966x_ptp_add_trap()
103 struct lan966x *lan966x = port->lan966x; in lan966x_ptp_del_trap()
108 vrule = vcap_get_rule(lan966x->vcap_ctrl, rule_id); in lan966x_ptp_del_trap()
110 return -EEXIST; in lan966x_ptp_del_trap()
113 mask |= BIT(port->chip_port); in lan966x_ptp_del_trap()
116 if (mask == GENMASK(lan966x->num_phys_ports, 0)) { in lan966x_ptp_del_trap()
117 err = vcap_del_rule(lan966x->vcap_ctrl, port->dev, rule_id); in lan966x_ptp_del_trap()
254 if (cfg->rx_filter == HWTSTAMP_FILTER_NONE) in lan966x_ptp_setup_traps()
264 struct lan966x *lan966x = port->lan966x; in lan966x_ptp_hwtstamp_set()
267 switch (cfg->tx_type) { in lan966x_ptp_hwtstamp_set()
269 port->ptp_tx_cmd = IFH_REW_OP_TWO_STEP_PTP; in lan966x_ptp_hwtstamp_set()
272 port->ptp_tx_cmd = IFH_REW_OP_ONE_STEP_PTP; in lan966x_ptp_hwtstamp_set()
275 port->ptp_tx_cmd = IFH_REW_OP_NOOP; in lan966x_ptp_hwtstamp_set()
278 return -ERANGE; in lan966x_ptp_hwtstamp_set()
281 switch (cfg->rx_filter) { in lan966x_ptp_hwtstamp_set()
283 port->ptp_rx_cmd = false; in lan966x_ptp_hwtstamp_set()
299 port->ptp_rx_cmd = true; in lan966x_ptp_hwtstamp_set()
300 cfg->rx_filter = HWTSTAMP_FILTER_ALL; in lan966x_ptp_hwtstamp_set()
303 return -ERANGE; in lan966x_ptp_hwtstamp_set()
307 mutex_lock(&lan966x->ptp_lock); in lan966x_ptp_hwtstamp_set()
308 phc = &lan966x->phc[LAN966X_PHC_PORT]; in lan966x_ptp_hwtstamp_set()
309 phc->hwtstamp_config = *cfg; in lan966x_ptp_hwtstamp_set()
310 mutex_unlock(&lan966x->ptp_lock); in lan966x_ptp_hwtstamp_set()
318 struct lan966x *lan966x = port->lan966x; in lan966x_ptp_hwtstamp_get()
321 phc = &lan966x->phc[LAN966X_PHC_PORT]; in lan966x_ptp_hwtstamp_get()
322 *cfg = phc->hwtstamp_config; in lan966x_ptp_hwtstamp_get()
331 if (port->ptp_tx_cmd == IFH_REW_OP_NOOP) in lan966x_ptp_classify()
342 if (port->ptp_tx_cmd == IFH_REW_OP_TWO_STEP_PTP) in lan966x_ptp_classify()
360 spin_lock_irqsave(&port->tx_skbs.lock, flags); in lan966x_ptp_txtstamp_old_release()
361 skb_queue_walk_safe(&port->tx_skbs, skb, skb_tmp) { in lan966x_ptp_txtstamp_old_release()
362 if time_after(LAN966X_SKB_CB(skb)->jiffies + LAN966X_PTP_TIMEOUT, in lan966x_ptp_txtstamp_old_release()
366 __skb_unlink(skb, &port->tx_skbs); in lan966x_ptp_txtstamp_old_release()
369 spin_unlock_irqrestore(&port->tx_skbs.lock, flags); in lan966x_ptp_txtstamp_old_release()
375 struct lan966x *lan966x = port->lan966x; in lan966x_ptp_txtstamp_request()
380 LAN966X_SKB_CB(skb)->rew_op = rew_op; in lan966x_ptp_txtstamp_request()
387 spin_lock_irqsave(&lan966x->ptp_ts_id_lock, flags); in lan966x_ptp_txtstamp_request()
388 if (lan966x->ptp_skbs == LAN966X_MAX_PTP_ID) { in lan966x_ptp_txtstamp_request()
389 spin_unlock_irqrestore(&lan966x->ptp_ts_id_lock, flags); in lan966x_ptp_txtstamp_request()
390 return -EBUSY; in lan966x_ptp_txtstamp_request()
393 skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS; in lan966x_ptp_txtstamp_request()
395 skb_queue_tail(&port->tx_skbs, skb); in lan966x_ptp_txtstamp_request()
396 LAN966X_SKB_CB(skb)->ts_id = port->ts_id; in lan966x_ptp_txtstamp_request()
397 LAN966X_SKB_CB(skb)->jiffies = jiffies; in lan966x_ptp_txtstamp_request()
399 lan966x->ptp_skbs++; in lan966x_ptp_txtstamp_request()
400 port->ts_id++; in lan966x_ptp_txtstamp_request()
401 if (port->ts_id == LAN966X_MAX_PTP_ID) in lan966x_ptp_txtstamp_request()
402 port->ts_id = 0; in lan966x_ptp_txtstamp_request()
404 spin_unlock_irqrestore(&lan966x->ptp_ts_id_lock, flags); in lan966x_ptp_txtstamp_request()
412 struct lan966x *lan966x = port->lan966x; in lan966x_ptp_txtstamp_release()
415 spin_lock_irqsave(&lan966x->ptp_ts_id_lock, flags); in lan966x_ptp_txtstamp_release()
416 port->ts_id--; in lan966x_ptp_txtstamp_release()
417 lan966x->ptp_skbs--; in lan966x_ptp_txtstamp_release()
418 skb_unlink(skb, &port->tx_skbs); in lan966x_ptp_txtstamp_release()
419 spin_unlock_irqrestore(&lan966x->ptp_ts_id_lock, flags); in lan966x_ptp_txtstamp_release()
426 /* Read current PTP time to get seconds */ in lan966x_get_hwtimestamp()
430 spin_lock_irqsave(&lan966x->ptp_clock_lock, flags); in lan966x_get_hwtimestamp()
440 ts->tv_sec = lan_rd(lan966x, PTP_TOD_SEC_LSB(TOD_ACC_PIN)); in lan966x_get_hwtimestamp()
443 ts->tv_nsec = nsec; in lan966x_get_hwtimestamp()
447 ts->tv_sec--; in lan966x_get_hwtimestamp()
449 spin_unlock_irqrestore(&lan966x->ptp_clock_lock, flags); in lan966x_get_hwtimestamp()
457 while (budget--) { in lan966x_ptp_irq_handler()
481 port = lan966x->ports[txport]; in lan966x_ptp_irq_handler()
503 spin_lock_irqsave(&port->tx_skbs.lock, flags); in lan966x_ptp_irq_handler()
504 skb_queue_walk_safe(&port->tx_skbs, skb, skb_tmp) { in lan966x_ptp_irq_handler()
505 if (LAN966X_SKB_CB(skb)->ts_id != id) in lan966x_ptp_irq_handler()
508 __skb_unlink(skb, &port->tx_skbs); in lan966x_ptp_irq_handler()
512 spin_unlock_irqrestore(&port->tx_skbs.lock, flags); in lan966x_ptp_irq_handler()
522 spin_lock_irqsave(&lan966x->ptp_ts_id_lock, flags); in lan966x_ptp_irq_handler()
523 lan966x->ptp_skbs--; in lan966x_ptp_irq_handler()
524 spin_unlock_irqrestore(&lan966x->ptp_ts_id_lock, flags); in lan966x_ptp_irq_handler()
556 phc = &lan966x->phc[i]; in lan966x_ptp_ext_irq_handler()
557 pin = ptp_find_pin_unlocked(phc->clock, PTP_PF_EXTTS, 0); in lan966x_ptp_ext_irq_handler()
558 if (pin == -1) in lan966x_ptp_ext_irq_handler()
564 spin_lock_irqsave(&lan966x->ptp_clock_lock, flags); in lan966x_ptp_ext_irq_handler()
578 spin_unlock_irqrestore(&lan966x->ptp_clock_lock, flags); in lan966x_ptp_ext_irq_handler()
581 s--; in lan966x_ptp_ext_irq_handler()
590 ptp_clock_event(phc->clock, &ptp_event); in lan966x_ptp_ext_irq_handler()
596 static int lan966x_ptp_adjfine(struct ptp_clock_info *ptp, long scaled_ppm) in lan966x_ptp_adjfine() argument
598 struct lan966x_phc *phc = container_of(ptp, struct lan966x_phc, info); in lan966x_ptp_adjfine()
599 struct lan966x *lan966x = phc->lan966x; in lan966x_ptp_adjfine()
603 u64 ref; in lan966x_ptp_adjfine() local
610 scaled_ppm = -scaled_ppm; in lan966x_ptp_adjfine()
619 ref = LAN966X_1PPM_FORMAT * (scaled_ppm >> 16); in lan966x_ptp_adjfine()
620 ref += (LAN966X_1PPM_FORMAT * (0xffff & scaled_ppm)) >> 16; in lan966x_ptp_adjfine()
621 tod_inc = neg_adj ? tod_inc - ref : tod_inc + ref; in lan966x_ptp_adjfine()
623 spin_lock_irqsave(&lan966x->ptp_clock_lock, flags); in lan966x_ptp_adjfine()
625 lan_rmw(PTP_DOM_CFG_CLKCFG_DIS_SET(1 << BIT(phc->index)), in lan966x_ptp_adjfine()
630 PTP_CLK_PER_CFG(phc->index, 0)); in lan966x_ptp_adjfine()
632 PTP_CLK_PER_CFG(phc->index, 1)); in lan966x_ptp_adjfine()
638 spin_unlock_irqrestore(&lan966x->ptp_clock_lock, flags); in lan966x_ptp_adjfine()
643 static int lan966x_ptp_settime64(struct ptp_clock_info *ptp, in lan966x_ptp_settime64() argument
646 struct lan966x_phc *phc = container_of(ptp, struct lan966x_phc, info); in lan966x_ptp_settime64()
647 struct lan966x *lan966x = phc->lan966x; in lan966x_ptp_settime64()
650 spin_lock_irqsave(&lan966x->ptp_clock_lock, flags); in lan966x_ptp_settime64()
654 PTP_PIN_CFG_PIN_DOM_SET(phc->index) | in lan966x_ptp_settime64()
662 lan_wr(PTP_TOD_SEC_MSB_TOD_SEC_MSB_SET(upper_32_bits(ts->tv_sec)), in lan966x_ptp_settime64()
664 lan_wr(lower_32_bits(ts->tv_sec), in lan966x_ptp_settime64()
666 lan_wr(ts->tv_nsec, lan966x, PTP_TOD_NSEC(TOD_ACC_PIN)); in lan966x_ptp_settime64()
670 PTP_PIN_CFG_PIN_DOM_SET(phc->index) | in lan966x_ptp_settime64()
677 spin_unlock_irqrestore(&lan966x->ptp_clock_lock, flags); in lan966x_ptp_settime64()
682 int lan966x_ptp_gettime64(struct ptp_clock_info *ptp, struct timespec64 *ts) in lan966x_ptp_gettime64() argument
684 struct lan966x_phc *phc = container_of(ptp, struct lan966x_phc, info); in lan966x_ptp_gettime64()
685 struct lan966x *lan966x = phc->lan966x; in lan966x_ptp_gettime64()
690 spin_lock_irqsave(&lan966x->ptp_clock_lock, flags); in lan966x_ptp_gettime64()
693 PTP_PIN_CFG_PIN_DOM_SET(phc->index) | in lan966x_ptp_gettime64()
706 spin_unlock_irqrestore(&lan966x->ptp_clock_lock, flags); in lan966x_ptp_gettime64()
710 s--; in lan966x_ptp_gettime64()
719 static int lan966x_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta) in lan966x_ptp_adjtime() argument
721 struct lan966x_phc *phc = container_of(ptp, struct lan966x_phc, info); in lan966x_ptp_adjtime()
722 struct lan966x *lan966x = phc->lan966x; in lan966x_ptp_adjtime()
724 if (delta > -(NSEC_PER_SEC / 2) && delta < (NSEC_PER_SEC / 2)) { in lan966x_ptp_adjtime()
727 spin_lock_irqsave(&lan966x->ptp_clock_lock, flags); in lan966x_ptp_adjtime()
731 PTP_PIN_CFG_PIN_DOM_SET(phc->index) | in lan966x_ptp_adjtime()
743 PTP_PIN_CFG_PIN_DOM_SET(phc->index) | in lan966x_ptp_adjtime()
750 spin_unlock_irqrestore(&lan966x->ptp_clock_lock, flags); in lan966x_ptp_adjtime()
756 lan966x_ptp_gettime64(ptp, &ts); in lan966x_ptp_adjtime()
761 lan966x_ptp_settime64(ptp, &ts); in lan966x_ptp_adjtime()
767 static int lan966x_ptp_verify(struct ptp_clock_info *ptp, unsigned int pin, in lan966x_ptp_verify() argument
770 struct lan966x_phc *phc = container_of(ptp, struct lan966x_phc, info); in lan966x_ptp_verify()
771 struct lan966x *lan966x = phc->lan966x; in lan966x_ptp_verify()
777 return -1; in lan966x_ptp_verify()
785 return -1; in lan966x_ptp_verify()
788 /* The PTP pins are shared by all the PHC. So it is required to see if in lan966x_ptp_verify()
793 info = &lan966x->phc[i].info; in lan966x_ptp_verify()
796 if (ptp == info) in lan966x_ptp_verify()
799 if (info->pin_config[pin].func == PTP_PF_PEROUT || in lan966x_ptp_verify()
800 info->pin_config[pin].func == PTP_PF_EXTTS) in lan966x_ptp_verify()
801 return -1; in lan966x_ptp_verify()
807 static int lan966x_ptp_perout(struct ptp_clock_info *ptp, in lan966x_ptp_perout() argument
810 struct lan966x_phc *phc = container_of(ptp, struct lan966x_phc, info); in lan966x_ptp_perout()
811 struct lan966x *lan966x = phc->lan966x; in lan966x_ptp_perout()
818 if (rq->perout.flags & ~(PTP_PEROUT_DUTY_CYCLE | in lan966x_ptp_perout()
820 return -EOPNOTSUPP; in lan966x_ptp_perout()
822 pin = ptp_find_pin(phc->clock, PTP_PF_PEROUT, rq->perout.index); in lan966x_ptp_perout()
823 if (pin == -1 || pin >= LAN966X_PHC_PINS_NUM) in lan966x_ptp_perout()
824 return -EINVAL; in lan966x_ptp_perout()
827 spin_lock_irqsave(&lan966x->ptp_clock_lock, flags); in lan966x_ptp_perout()
829 PTP_PIN_CFG_PIN_DOM_SET(phc->index) | in lan966x_ptp_perout()
835 spin_unlock_irqrestore(&lan966x->ptp_clock_lock, flags); in lan966x_ptp_perout()
839 if (rq->perout.period.sec == 1 && in lan966x_ptp_perout()
840 rq->perout.period.nsec == 0) in lan966x_ptp_perout()
843 if (rq->perout.flags & PTP_PEROUT_PHASE) { in lan966x_ptp_perout()
844 ts_phase.tv_sec = rq->perout.phase.sec; in lan966x_ptp_perout()
845 ts_phase.tv_nsec = rq->perout.phase.nsec; in lan966x_ptp_perout()
847 ts_phase.tv_sec = rq->perout.start.sec; in lan966x_ptp_perout()
848 ts_phase.tv_nsec = rq->perout.start.nsec; in lan966x_ptp_perout()
852 dev_warn(lan966x->dev, in lan966x_ptp_perout()
854 return -EINVAL; in lan966x_ptp_perout()
857 if (rq->perout.flags & PTP_PEROUT_DUTY_CYCLE) { in lan966x_ptp_perout()
860 ts_on.tv_sec = rq->perout.on.sec; in lan966x_ptp_perout()
861 ts_on.tv_nsec = rq->perout.on.nsec; in lan966x_ptp_perout()
869 spin_lock_irqsave(&lan966x->ptp_clock_lock, flags); in lan966x_ptp_perout()
875 PTP_PIN_CFG_PIN_DOM_SET(phc->index) | in lan966x_ptp_perout()
881 spin_unlock_irqrestore(&lan966x->ptp_clock_lock, flags); in lan966x_ptp_perout()
885 ts_period.tv_sec = rq->perout.period.sec; in lan966x_ptp_perout()
886 ts_period.tv_nsec = rq->perout.period.nsec; in lan966x_ptp_perout()
889 wf_low -= wf_high; in lan966x_ptp_perout()
891 spin_lock_irqsave(&lan966x->ptp_clock_lock, flags); in lan966x_ptp_perout()
897 PTP_PIN_CFG_PIN_DOM_SET(phc->index) | in lan966x_ptp_perout()
903 spin_unlock_irqrestore(&lan966x->ptp_clock_lock, flags); in lan966x_ptp_perout()
908 static int lan966x_ptp_extts(struct ptp_clock_info *ptp, in lan966x_ptp_extts() argument
911 struct lan966x_phc *phc = container_of(ptp, struct lan966x_phc, info); in lan966x_ptp_extts()
912 struct lan966x *lan966x = phc->lan966x; in lan966x_ptp_extts()
917 if (lan966x->ptp_ext_irq <= 0) in lan966x_ptp_extts()
918 return -EOPNOTSUPP; in lan966x_ptp_extts()
921 if (rq->extts.flags & ~(PTP_ENABLE_FEATURE | in lan966x_ptp_extts()
924 return -EOPNOTSUPP; in lan966x_ptp_extts()
926 pin = ptp_find_pin(phc->clock, PTP_PF_EXTTS, rq->extts.index); in lan966x_ptp_extts()
927 if (pin == -1 || pin >= LAN966X_PHC_PINS_NUM) in lan966x_ptp_extts()
928 return -EINVAL; in lan966x_ptp_extts()
930 spin_lock_irqsave(&lan966x->ptp_clock_lock, flags); in lan966x_ptp_extts()
933 PTP_PIN_CFG_PIN_DOM_SET(phc->index) | in lan966x_ptp_extts()
948 spin_unlock_irqrestore(&lan966x->ptp_clock_lock, flags); in lan966x_ptp_extts()
953 static int lan966x_ptp_enable(struct ptp_clock_info *ptp, in lan966x_ptp_enable() argument
956 switch (rq->type) { in lan966x_ptp_enable()
958 return lan966x_ptp_perout(ptp, rq, on); in lan966x_ptp_enable()
960 return lan966x_ptp_extts(ptp, rq, on); in lan966x_ptp_enable()
962 return -EOPNOTSUPP; in lan966x_ptp_enable()
970 .name = "lan966x ptp",
987 struct lan966x_phc *phc = &lan966x->phc[index]; in lan966x_ptp_phc_init()
992 p = &phc->pins[i]; in lan966x_ptp_phc_init()
994 snprintf(p->name, sizeof(p->name), "pin%d", i); in lan966x_ptp_phc_init()
995 p->index = i; in lan966x_ptp_phc_init()
996 p->func = PTP_PF_NONE; in lan966x_ptp_phc_init()
999 phc->info = *clock_info; in lan966x_ptp_phc_init()
1000 phc->info.pin_config = &phc->pins[0]; in lan966x_ptp_phc_init()
1001 phc->clock = ptp_clock_register(&phc->info, lan966x->dev); in lan966x_ptp_phc_init()
1002 if (IS_ERR(phc->clock)) in lan966x_ptp_phc_init()
1003 return PTR_ERR(phc->clock); in lan966x_ptp_phc_init()
1005 phc->index = index; in lan966x_ptp_phc_init()
1006 phc->lan966x = lan966x; in lan966x_ptp_phc_init()
1017 if (!lan966x->ptp) in lan966x_ptp_init()
1026 spin_lock_init(&lan966x->ptp_clock_lock); in lan966x_ptp_init()
1027 spin_lock_init(&lan966x->ptp_ts_id_lock); in lan966x_ptp_init()
1028 mutex_init(&lan966x->ptp_lock); in lan966x_ptp_init()
1052 for (i = 0; i < lan966x->num_phys_ports; i++) { in lan966x_ptp_init()
1053 port = lan966x->ports[i]; in lan966x_ptp_init()
1057 skb_queue_head_init(&port->tx_skbs); in lan966x_ptp_init()
1068 if (!lan966x->ptp) in lan966x_ptp_deinit()
1071 for (i = 0; i < lan966x->num_phys_ports; i++) { in lan966x_ptp_deinit()
1072 port = lan966x->ports[i]; in lan966x_ptp_deinit()
1076 skb_queue_purge(&port->tx_skbs); in lan966x_ptp_deinit()
1080 ptp_clock_unregister(lan966x->phc[i].clock); in lan966x_ptp_deinit()
1091 if (!lan966x->ptp || in lan966x_ptp_rxtstamp()
1092 !lan966x->ports[src_port]->ptp_rx_cmd) in lan966x_ptp_rxtstamp()
1095 phc = &lan966x->phc[LAN966X_PHC_PORT]; in lan966x_ptp_rxtstamp()
1096 lan966x_ptp_gettime64(&phc->info, &ts); in lan966x_ptp_rxtstamp()
1098 /* Drop the sub-ns precision */ in lan966x_ptp_rxtstamp()
1101 ts.tv_sec--; in lan966x_ptp_rxtstamp()
1106 shhwtstamps->hwtstamp = full_ts_in_ns; in lan966x_ptp_rxtstamp()