Lines Matching +full:ocelot +full:- +full:1
1 // SPDX-License-Identifier: (GPL-2.0 OR MIT)
2 /* Microsemi Ocelot PTP clock driver
9 #include <linux/dsa/ocelot.h>
14 #include <soc/mscc/ocelot.h>
15 #include "ocelot.h"
19 struct ocelot *ocelot = container_of(ptp, struct ocelot, ptp_info); in ocelot_ptp_gettime64() local
25 spin_lock_irqsave(&ocelot->ptp_clock_lock, flags); in ocelot_ptp_gettime64()
27 val = ocelot_read_rix(ocelot, PTP_PIN_CFG, TOD_ACC_PIN); in ocelot_ptp_gettime64()
30 ocelot_write_rix(ocelot, val, PTP_PIN_CFG, TOD_ACC_PIN); in ocelot_ptp_gettime64()
32 s = ocelot_read_rix(ocelot, PTP_PIN_TOD_SEC_MSB, TOD_ACC_PIN) & 0xffff; in ocelot_ptp_gettime64()
34 s += ocelot_read_rix(ocelot, PTP_PIN_TOD_SEC_LSB, TOD_ACC_PIN); in ocelot_ptp_gettime64()
35 ns = ocelot_read_rix(ocelot, PTP_PIN_TOD_NSEC, TOD_ACC_PIN); in ocelot_ptp_gettime64()
37 spin_unlock_irqrestore(&ocelot->ptp_clock_lock, flags); in ocelot_ptp_gettime64()
41 s--; in ocelot_ptp_gettime64()
54 struct ocelot *ocelot = container_of(ptp, struct ocelot, ptp_info); in ocelot_ptp_settime64() local
58 spin_lock_irqsave(&ocelot->ptp_clock_lock, flags); in ocelot_ptp_settime64()
60 val = ocelot_read_rix(ocelot, PTP_PIN_CFG, TOD_ACC_PIN); in ocelot_ptp_settime64()
64 ocelot_write_rix(ocelot, val, PTP_PIN_CFG, TOD_ACC_PIN); in ocelot_ptp_settime64()
66 ocelot_write_rix(ocelot, lower_32_bits(ts->tv_sec), PTP_PIN_TOD_SEC_LSB, in ocelot_ptp_settime64()
68 ocelot_write_rix(ocelot, upper_32_bits(ts->tv_sec), PTP_PIN_TOD_SEC_MSB, in ocelot_ptp_settime64()
70 ocelot_write_rix(ocelot, ts->tv_nsec, PTP_PIN_TOD_NSEC, TOD_ACC_PIN); in ocelot_ptp_settime64()
72 val = ocelot_read_rix(ocelot, PTP_PIN_CFG, TOD_ACC_PIN); in ocelot_ptp_settime64()
76 ocelot_write_rix(ocelot, val, PTP_PIN_CFG, TOD_ACC_PIN); in ocelot_ptp_settime64()
78 spin_unlock_irqrestore(&ocelot->ptp_clock_lock, flags); in ocelot_ptp_settime64()
80 if (ocelot->ops->tas_clock_adjust) in ocelot_ptp_settime64()
81 ocelot->ops->tas_clock_adjust(ocelot); in ocelot_ptp_settime64()
89 if (delta > -(NSEC_PER_SEC / 2) && delta < (NSEC_PER_SEC / 2)) { in ocelot_ptp_adjtime()
90 struct ocelot *ocelot = container_of(ptp, struct ocelot, in ocelot_ptp_adjtime() local
95 spin_lock_irqsave(&ocelot->ptp_clock_lock, flags); in ocelot_ptp_adjtime()
97 val = ocelot_read_rix(ocelot, PTP_PIN_CFG, TOD_ACC_PIN); in ocelot_ptp_adjtime()
102 ocelot_write_rix(ocelot, val, PTP_PIN_CFG, TOD_ACC_PIN); in ocelot_ptp_adjtime()
104 ocelot_write_rix(ocelot, 0, PTP_PIN_TOD_SEC_LSB, TOD_ACC_PIN); in ocelot_ptp_adjtime()
105 ocelot_write_rix(ocelot, 0, PTP_PIN_TOD_SEC_MSB, TOD_ACC_PIN); in ocelot_ptp_adjtime()
106 ocelot_write_rix(ocelot, delta, PTP_PIN_TOD_NSEC, TOD_ACC_PIN); in ocelot_ptp_adjtime()
108 val = ocelot_read_rix(ocelot, PTP_PIN_CFG, TOD_ACC_PIN); in ocelot_ptp_adjtime()
113 ocelot_write_rix(ocelot, val, PTP_PIN_CFG, TOD_ACC_PIN); in ocelot_ptp_adjtime()
115 spin_unlock_irqrestore(&ocelot->ptp_clock_lock, flags); in ocelot_ptp_adjtime()
117 if (ocelot->ops->tas_clock_adjust) in ocelot_ptp_adjtime()
118 ocelot->ops->tas_clock_adjust(ocelot); in ocelot_ptp_adjtime()
138 struct ocelot *ocelot = container_of(ptp, struct ocelot, ptp_info); in ocelot_ptp_adjfine() local
143 spin_lock_irqsave(&ocelot->ptp_clock_lock, flags); in ocelot_ptp_adjfine()
150 scaled_ppm = -scaled_ppm; in ocelot_ptp_adjfine()
158 if (adj >= (1L << 30)) { in ocelot_ptp_adjfine()
164 if (adj >= (1L << 30)) in ocelot_ptp_adjfine()
167 ocelot_write(ocelot, unit | adj, PTP_CLK_CFG_ADJ_FREQ); in ocelot_ptp_adjfine()
168 ocelot_write(ocelot, PTP_CFG_CLK_ADJ_CFG_ENA | direction, in ocelot_ptp_adjfine()
171 spin_unlock_irqrestore(&ocelot->ptp_clock_lock, flags); in ocelot_ptp_adjfine()
175 ocelot_write(ocelot, 0, PTP_CLK_CFG_ADJ_CFG); in ocelot_ptp_adjfine()
177 spin_unlock_irqrestore(&ocelot->ptp_clock_lock, flags); in ocelot_ptp_adjfine()
191 return -1; in ocelot_ptp_verify()
200 struct ocelot *ocelot = container_of(ptp, struct ocelot, ptp_info); in ocelot_ptp_enable() local
205 int pin = -1; in ocelot_ptp_enable()
210 switch (rq->type) { in ocelot_ptp_enable()
213 if (rq->perout.flags & ~(PTP_PEROUT_DUTY_CYCLE | in ocelot_ptp_enable()
215 return -EOPNOTSUPP; in ocelot_ptp_enable()
217 pin = ptp_find_pin(ocelot->ptp_clock, PTP_PF_PEROUT, in ocelot_ptp_enable()
218 rq->perout.index); in ocelot_ptp_enable()
221 else if (pin == 1) in ocelot_ptp_enable()
228 return -EBUSY; in ocelot_ptp_enable()
230 ts_period.tv_sec = rq->perout.period.sec; in ocelot_ptp_enable()
231 ts_period.tv_nsec = rq->perout.period.nsec; in ocelot_ptp_enable()
233 if (ts_period.tv_sec == 1 && ts_period.tv_nsec == 0) in ocelot_ptp_enable()
238 spin_lock_irqsave(&ocelot->ptp_clock_lock, flags); in ocelot_ptp_enable()
240 ocelot_write_rix(ocelot, val, PTP_PIN_CFG, ptp_pin); in ocelot_ptp_enable()
241 spin_unlock_irqrestore(&ocelot->ptp_clock_lock, flags); in ocelot_ptp_enable()
245 if (rq->perout.flags & PTP_PEROUT_PHASE) { in ocelot_ptp_enable()
246 ts_phase.tv_sec = rq->perout.phase.sec; in ocelot_ptp_enable()
247 ts_phase.tv_nsec = rq->perout.phase.nsec; in ocelot_ptp_enable()
250 ts_phase.tv_sec = rq->perout.start.sec; in ocelot_ptp_enable()
251 ts_phase.tv_nsec = rq->perout.start.nsec; in ocelot_ptp_enable()
254 dev_warn(ocelot->dev, in ocelot_ptp_enable()
256 dev_warn(ocelot->dev, in ocelot_ptp_enable()
258 return -EINVAL; in ocelot_ptp_enable()
262 if (rq->perout.flags & PTP_PEROUT_DUTY_CYCLE) { in ocelot_ptp_enable()
265 ts_on.tv_sec = rq->perout.on.sec; in ocelot_ptp_enable()
266 ts_on.tv_nsec = rq->perout.on.nsec; in ocelot_ptp_enable()
279 wf_low -= wf_high; in ocelot_ptp_enable()
283 spin_lock_irqsave(&ocelot->ptp_clock_lock, flags); in ocelot_ptp_enable()
284 ocelot_write_rix(ocelot, ts_phase.tv_nsec, in ocelot_ptp_enable()
286 ocelot_write_rix(ocelot, wf_high, in ocelot_ptp_enable()
290 ocelot_write_rix(ocelot, val, PTP_PIN_CFG, ptp_pin); in ocelot_ptp_enable()
291 spin_unlock_irqrestore(&ocelot->ptp_clock_lock, flags); in ocelot_ptp_enable()
297 return -EINVAL; in ocelot_ptp_enable()
299 return -EINVAL; in ocelot_ptp_enable()
301 spin_lock_irqsave(&ocelot->ptp_clock_lock, flags); in ocelot_ptp_enable()
302 ocelot_write_rix(ocelot, wf_low, PTP_PIN_WF_LOW_PERIOD, in ocelot_ptp_enable()
304 ocelot_write_rix(ocelot, wf_high, PTP_PIN_WF_HIGH_PERIOD, in ocelot_ptp_enable()
307 ocelot_write_rix(ocelot, val, PTP_PIN_CFG, ptp_pin); in ocelot_ptp_enable()
308 spin_unlock_irqrestore(&ocelot->ptp_clock_lock, flags); in ocelot_ptp_enable()
311 return -EOPNOTSUPP; in ocelot_ptp_enable()
319 trap->key_type = OCELOT_VCAP_KEY_ETYPE; in ocelot_populate_l2_ptp_trap_key()
320 *(__be16 *)trap->key.etype.etype.value = htons(ETH_P_1588); in ocelot_populate_l2_ptp_trap_key()
321 *(__be16 *)trap->key.etype.etype.mask = htons(0xffff); in ocelot_populate_l2_ptp_trap_key()
327 trap->key_type = OCELOT_VCAP_KEY_IPV4; in ocelot_populate_ipv4_ptp_event_trap_key()
328 trap->key.ipv4.proto.value[0] = IPPROTO_UDP; in ocelot_populate_ipv4_ptp_event_trap_key()
329 trap->key.ipv4.proto.mask[0] = 0xff; in ocelot_populate_ipv4_ptp_event_trap_key()
330 trap->key.ipv4.dport.value = PTP_EV_PORT; in ocelot_populate_ipv4_ptp_event_trap_key()
331 trap->key.ipv4.dport.mask = 0xffff; in ocelot_populate_ipv4_ptp_event_trap_key()
337 trap->key_type = OCELOT_VCAP_KEY_IPV6; in ocelot_populate_ipv6_ptp_event_trap_key()
338 trap->key.ipv6.proto.value[0] = IPPROTO_UDP; in ocelot_populate_ipv6_ptp_event_trap_key()
339 trap->key.ipv6.proto.mask[0] = 0xff; in ocelot_populate_ipv6_ptp_event_trap_key()
340 trap->key.ipv6.dport.value = PTP_EV_PORT; in ocelot_populate_ipv6_ptp_event_trap_key()
341 trap->key.ipv6.dport.mask = 0xffff; in ocelot_populate_ipv6_ptp_event_trap_key()
347 trap->key_type = OCELOT_VCAP_KEY_IPV4; in ocelot_populate_ipv4_ptp_general_trap_key()
348 trap->key.ipv4.proto.value[0] = IPPROTO_UDP; in ocelot_populate_ipv4_ptp_general_trap_key()
349 trap->key.ipv4.proto.mask[0] = 0xff; in ocelot_populate_ipv4_ptp_general_trap_key()
350 trap->key.ipv4.dport.value = PTP_GEN_PORT; in ocelot_populate_ipv4_ptp_general_trap_key()
351 trap->key.ipv4.dport.mask = 0xffff; in ocelot_populate_ipv4_ptp_general_trap_key()
357 trap->key_type = OCELOT_VCAP_KEY_IPV6; in ocelot_populate_ipv6_ptp_general_trap_key()
358 trap->key.ipv6.proto.value[0] = IPPROTO_UDP; in ocelot_populate_ipv6_ptp_general_trap_key()
359 trap->key.ipv6.proto.mask[0] = 0xff; in ocelot_populate_ipv6_ptp_general_trap_key()
360 trap->key.ipv6.dport.value = PTP_GEN_PORT; in ocelot_populate_ipv6_ptp_general_trap_key()
361 trap->key.ipv6.dport.mask = 0xffff; in ocelot_populate_ipv6_ptp_general_trap_key()
364 static int ocelot_l2_ptp_trap_add(struct ocelot *ocelot, int port) in ocelot_l2_ptp_trap_add() argument
366 unsigned long l2_cookie = OCELOT_VCAP_IS2_L2_PTP_TRAP(ocelot); in ocelot_l2_ptp_trap_add()
368 return ocelot_trap_add(ocelot, port, l2_cookie, true, in ocelot_l2_ptp_trap_add()
372 static int ocelot_l2_ptp_trap_del(struct ocelot *ocelot, int port) in ocelot_l2_ptp_trap_del() argument
374 unsigned long l2_cookie = OCELOT_VCAP_IS2_L2_PTP_TRAP(ocelot); in ocelot_l2_ptp_trap_del()
376 return ocelot_trap_del(ocelot, port, l2_cookie); in ocelot_l2_ptp_trap_del()
379 static int ocelot_ipv4_ptp_trap_add(struct ocelot *ocelot, int port) in ocelot_ipv4_ptp_trap_add() argument
381 unsigned long ipv4_gen_cookie = OCELOT_VCAP_IS2_IPV4_GEN_PTP_TRAP(ocelot); in ocelot_ipv4_ptp_trap_add()
382 unsigned long ipv4_ev_cookie = OCELOT_VCAP_IS2_IPV4_EV_PTP_TRAP(ocelot); in ocelot_ipv4_ptp_trap_add()
385 err = ocelot_trap_add(ocelot, port, ipv4_ev_cookie, true, in ocelot_ipv4_ptp_trap_add()
390 err = ocelot_trap_add(ocelot, port, ipv4_gen_cookie, false, in ocelot_ipv4_ptp_trap_add()
393 ocelot_trap_del(ocelot, port, ipv4_ev_cookie); in ocelot_ipv4_ptp_trap_add()
398 static int ocelot_ipv4_ptp_trap_del(struct ocelot *ocelot, int port) in ocelot_ipv4_ptp_trap_del() argument
400 unsigned long ipv4_gen_cookie = OCELOT_VCAP_IS2_IPV4_GEN_PTP_TRAP(ocelot); in ocelot_ipv4_ptp_trap_del()
401 unsigned long ipv4_ev_cookie = OCELOT_VCAP_IS2_IPV4_EV_PTP_TRAP(ocelot); in ocelot_ipv4_ptp_trap_del()
404 err = ocelot_trap_del(ocelot, port, ipv4_ev_cookie); in ocelot_ipv4_ptp_trap_del()
405 err |= ocelot_trap_del(ocelot, port, ipv4_gen_cookie); in ocelot_ipv4_ptp_trap_del()
409 static int ocelot_ipv6_ptp_trap_add(struct ocelot *ocelot, int port) in ocelot_ipv6_ptp_trap_add() argument
411 unsigned long ipv6_gen_cookie = OCELOT_VCAP_IS2_IPV6_GEN_PTP_TRAP(ocelot); in ocelot_ipv6_ptp_trap_add()
412 unsigned long ipv6_ev_cookie = OCELOT_VCAP_IS2_IPV6_EV_PTP_TRAP(ocelot); in ocelot_ipv6_ptp_trap_add()
415 err = ocelot_trap_add(ocelot, port, ipv6_ev_cookie, true, in ocelot_ipv6_ptp_trap_add()
420 err = ocelot_trap_add(ocelot, port, ipv6_gen_cookie, false, in ocelot_ipv6_ptp_trap_add()
423 ocelot_trap_del(ocelot, port, ipv6_ev_cookie); in ocelot_ipv6_ptp_trap_add()
428 static int ocelot_ipv6_ptp_trap_del(struct ocelot *ocelot, int port) in ocelot_ipv6_ptp_trap_del() argument
430 unsigned long ipv6_gen_cookie = OCELOT_VCAP_IS2_IPV6_GEN_PTP_TRAP(ocelot); in ocelot_ipv6_ptp_trap_del()
431 unsigned long ipv6_ev_cookie = OCELOT_VCAP_IS2_IPV6_EV_PTP_TRAP(ocelot); in ocelot_ipv6_ptp_trap_del()
434 err = ocelot_trap_del(ocelot, port, ipv6_ev_cookie); in ocelot_ipv6_ptp_trap_del()
435 err |= ocelot_trap_del(ocelot, port, ipv6_gen_cookie); in ocelot_ipv6_ptp_trap_del()
439 static int ocelot_setup_ptp_traps(struct ocelot *ocelot, int port, in ocelot_setup_ptp_traps() argument
442 struct ocelot_port *ocelot_port = ocelot->ports[port]; in ocelot_setup_ptp_traps()
445 ocelot_port->trap_proto &= ~(OCELOT_PROTO_PTP_L2 | in ocelot_setup_ptp_traps()
449 err = ocelot_l2_ptp_trap_add(ocelot, port); in ocelot_setup_ptp_traps()
451 err = ocelot_l2_ptp_trap_del(ocelot, port); in ocelot_setup_ptp_traps()
456 err = ocelot_ipv4_ptp_trap_add(ocelot, port); in ocelot_setup_ptp_traps()
460 err = ocelot_ipv6_ptp_trap_add(ocelot, port); in ocelot_setup_ptp_traps()
464 err = ocelot_ipv4_ptp_trap_del(ocelot, port); in ocelot_setup_ptp_traps()
466 err |= ocelot_ipv6_ptp_trap_del(ocelot, port); in ocelot_setup_ptp_traps()
472 ocelot_port->trap_proto |= OCELOT_PROTO_PTP_L2; in ocelot_setup_ptp_traps()
474 ocelot_port->trap_proto |= OCELOT_PROTO_PTP_L4; in ocelot_setup_ptp_traps()
479 ocelot_ipv4_ptp_trap_del(ocelot, port); in ocelot_setup_ptp_traps()
482 ocelot_l2_ptp_trap_del(ocelot, port); in ocelot_setup_ptp_traps()
498 int ocelot_hwstamp_get(struct ocelot *ocelot, int port, struct ifreq *ifr) in ocelot_hwstamp_get() argument
500 struct ocelot_port *ocelot_port = ocelot->ports[port]; in ocelot_hwstamp_get()
503 switch (ocelot_port->ptp_cmd) { in ocelot_hwstamp_get()
515 cfg.rx_filter = ocelot_traps_to_ptp_rx_filter(ocelot_port->trap_proto); in ocelot_hwstamp_get()
517 return copy_to_user(ifr->ifr_data, &cfg, sizeof(cfg)) ? -EFAULT : 0; in ocelot_hwstamp_get()
521 int ocelot_hwstamp_set(struct ocelot *ocelot, int port, struct ifreq *ifr) in ocelot_hwstamp_set() argument
523 struct ocelot_port *ocelot_port = ocelot->ports[port]; in ocelot_hwstamp_set()
528 if (copy_from_user(&cfg, ifr->ifr_data, sizeof(cfg))) in ocelot_hwstamp_set()
529 return -EFAULT; in ocelot_hwstamp_set()
534 ocelot_port->ptp_cmd = IFH_REW_OP_TWO_STEP_PTP; in ocelot_hwstamp_set()
540 ocelot_port->ptp_cmd = IFH_REW_OP_ORIGIN_PTP; in ocelot_hwstamp_set()
543 ocelot_port->ptp_cmd = 0; in ocelot_hwstamp_set()
546 return -ERANGE; in ocelot_hwstamp_set()
569 return -ERANGE; in ocelot_hwstamp_set()
572 err = ocelot_setup_ptp_traps(ocelot, port, l2, l4); in ocelot_hwstamp_set()
576 cfg.rx_filter = ocelot_traps_to_ptp_rx_filter(ocelot_port->trap_proto); in ocelot_hwstamp_set()
578 return copy_to_user(ifr->ifr_data, &cfg, sizeof(cfg)) ? -EFAULT : 0; in ocelot_hwstamp_set()
582 int ocelot_get_ts_info(struct ocelot *ocelot, int port, in ocelot_get_ts_info() argument
585 info->phc_index = ocelot->ptp_clock ? in ocelot_get_ts_info()
586 ptp_clock_index(ocelot->ptp_clock) : -1; in ocelot_get_ts_info()
587 if (info->phc_index == -1) { in ocelot_get_ts_info()
588 info->so_timestamping |= SOF_TIMESTAMPING_TX_SOFTWARE | in ocelot_get_ts_info()
593 info->so_timestamping |= SOF_TIMESTAMPING_TX_SOFTWARE | in ocelot_get_ts_info()
599 info->tx_types = BIT(HWTSTAMP_TX_OFF) | BIT(HWTSTAMP_TX_ON) | in ocelot_get_ts_info()
601 info->rx_filters = BIT(HWTSTAMP_FILTER_NONE) | in ocelot_get_ts_info()
610 static int ocelot_port_add_txtstamp_skb(struct ocelot *ocelot, int port, in ocelot_port_add_txtstamp_skb() argument
613 struct ocelot_port *ocelot_port = ocelot->ports[port]; in ocelot_port_add_txtstamp_skb()
616 spin_lock_irqsave(&ocelot->ts_id_lock, flags); in ocelot_port_add_txtstamp_skb()
618 if (ocelot_port->ptp_skbs_in_flight == OCELOT_MAX_PTP_ID || in ocelot_port_add_txtstamp_skb()
619 ocelot->ptp_skbs_in_flight == OCELOT_PTP_FIFO_SIZE) { in ocelot_port_add_txtstamp_skb()
620 spin_unlock_irqrestore(&ocelot->ts_id_lock, flags); in ocelot_port_add_txtstamp_skb()
621 return -EBUSY; in ocelot_port_add_txtstamp_skb()
624 skb_shinfo(clone)->tx_flags |= SKBTX_IN_PROGRESS; in ocelot_port_add_txtstamp_skb()
625 /* Store timestamp ID in OCELOT_SKB_CB(clone)->ts_id */ in ocelot_port_add_txtstamp_skb()
626 OCELOT_SKB_CB(clone)->ts_id = ocelot_port->ts_id; in ocelot_port_add_txtstamp_skb()
628 ocelot_port->ts_id++; in ocelot_port_add_txtstamp_skb()
629 if (ocelot_port->ts_id == OCELOT_MAX_PTP_ID) in ocelot_port_add_txtstamp_skb()
630 ocelot_port->ts_id = 0; in ocelot_port_add_txtstamp_skb()
632 ocelot_port->ptp_skbs_in_flight++; in ocelot_port_add_txtstamp_skb()
633 ocelot->ptp_skbs_in_flight++; in ocelot_port_add_txtstamp_skb()
635 skb_queue_tail(&ocelot_port->tx_skbs, clone); in ocelot_port_add_txtstamp_skb()
637 spin_unlock_irqrestore(&ocelot->ts_id_lock, flags); in ocelot_port_add_txtstamp_skb()
653 twostep = hdr->flag_field[0] & 0x2; in ocelot_ptp_is_onestep_sync()
661 int ocelot_port_txtstamp_request(struct ocelot *ocelot, int port, in ocelot_port_txtstamp_request() argument
665 struct ocelot_port *ocelot_port = ocelot->ports[port]; in ocelot_port_txtstamp_request()
666 u8 ptp_cmd = ocelot_port->ptp_cmd; in ocelot_port_txtstamp_request()
676 return -EINVAL; in ocelot_port_txtstamp_request()
678 /* Store ptp_cmd in OCELOT_SKB_CB(skb)->ptp_cmd */ in ocelot_port_txtstamp_request()
681 OCELOT_SKB_CB(skb)->ptp_cmd = ptp_cmd; in ocelot_port_txtstamp_request()
685 /* Fall back to two-step timestamping */ in ocelot_port_txtstamp_request()
692 return -ENOMEM; in ocelot_port_txtstamp_request()
694 err = ocelot_port_add_txtstamp_skb(ocelot, port, *clone); in ocelot_port_txtstamp_request()
698 OCELOT_SKB_CB(skb)->ptp_cmd = ptp_cmd; in ocelot_port_txtstamp_request()
699 OCELOT_SKB_CB(*clone)->ptp_class = ptp_class; in ocelot_port_txtstamp_request()
706 static void ocelot_get_hwtimestamp(struct ocelot *ocelot, in ocelot_get_hwtimestamp() argument
712 spin_lock_irqsave(&ocelot->ptp_clock_lock, flags); in ocelot_get_hwtimestamp()
715 val = ocelot_read_rix(ocelot, PTP_PIN_CFG, TOD_ACC_PIN); in ocelot_get_hwtimestamp()
719 ocelot_write_rix(ocelot, val, PTP_PIN_CFG, TOD_ACC_PIN); in ocelot_get_hwtimestamp()
720 ts->tv_sec = ocelot_read_rix(ocelot, PTP_PIN_TOD_SEC_LSB, TOD_ACC_PIN); in ocelot_get_hwtimestamp()
723 val = ocelot_read(ocelot, SYS_PTP_TXSTAMP); in ocelot_get_hwtimestamp()
724 ts->tv_nsec = SYS_PTP_TXSTAMP_PTP_TXSTAMP(val); in ocelot_get_hwtimestamp()
727 if ((ts->tv_sec & 0x1) != !!(val & SYS_PTP_TXSTAMP_PTP_TXSTAMP_SEC)) in ocelot_get_hwtimestamp()
728 ts->tv_sec--; in ocelot_get_hwtimestamp()
730 spin_unlock_irqrestore(&ocelot->ptp_clock_lock, flags); in ocelot_get_hwtimestamp()
737 hdr = ptp_parse_header(clone, OCELOT_SKB_CB(clone)->ptp_class); in ocelot_validate_ptp_skb()
741 return seqid == ntohs(hdr->sequence_id); in ocelot_validate_ptp_skb()
744 void ocelot_get_txtstamp(struct ocelot *ocelot) in ocelot_get_txtstamp() argument
748 while (budget--) { in ocelot_get_txtstamp()
756 val = ocelot_read(ocelot, SYS_PTP_STATUS); in ocelot_get_txtstamp()
769 port = ocelot->ports[txport]; in ocelot_get_txtstamp()
771 spin_lock(&ocelot->ts_id_lock); in ocelot_get_txtstamp()
772 port->ptp_skbs_in_flight--; in ocelot_get_txtstamp()
773 ocelot->ptp_skbs_in_flight--; in ocelot_get_txtstamp()
774 spin_unlock(&ocelot->ts_id_lock); in ocelot_get_txtstamp()
778 spin_lock_irqsave(&port->tx_skbs.lock, flags); in ocelot_get_txtstamp()
780 skb_queue_walk_safe(&port->tx_skbs, skb, skb_tmp) { in ocelot_get_txtstamp()
781 if (OCELOT_SKB_CB(skb)->ts_id != id) in ocelot_get_txtstamp()
783 __skb_unlink(skb, &port->tx_skbs); in ocelot_get_txtstamp()
788 spin_unlock_irqrestore(&port->tx_skbs.lock, flags); in ocelot_get_txtstamp()
794 dev_err_ratelimited(ocelot->dev, in ocelot_get_txtstamp()
802 ocelot_get_hwtimestamp(ocelot, &ts); in ocelot_get_txtstamp()
810 ocelot_write(ocelot, SYS_PTP_NXT_PTP_NXT, SYS_PTP_NXT); in ocelot_get_txtstamp()
815 int ocelot_init_timestamp(struct ocelot *ocelot, in ocelot_init_timestamp() argument
821 ocelot->ptp_info = *info; in ocelot_init_timestamp()
824 struct ptp_pin_desc *p = &ocelot->ptp_pins[i]; in ocelot_init_timestamp()
826 snprintf(p->name, sizeof(p->name), "switch_1588_dat%d", i); in ocelot_init_timestamp()
827 p->index = i; in ocelot_init_timestamp()
828 p->func = PTP_PF_NONE; in ocelot_init_timestamp()
831 ocelot->ptp_info.pin_config = &ocelot->ptp_pins[0]; in ocelot_init_timestamp()
833 ptp_clock = ptp_clock_register(&ocelot->ptp_info, ocelot->dev); in ocelot_init_timestamp()
840 ocelot->ptp_clock = ptp_clock; in ocelot_init_timestamp()
842 ocelot_write(ocelot, SYS_PTP_CFG_PTP_STAMP_WID(30), SYS_PTP_CFG); in ocelot_init_timestamp()
843 ocelot_write(ocelot, 0xffffffff, ANA_TABLES_PTP_ID_LOW); in ocelot_init_timestamp()
844 ocelot_write(ocelot, 0xffffffff, ANA_TABLES_PTP_ID_HIGH); in ocelot_init_timestamp()
846 ocelot_write(ocelot, PTP_CFG_MISC_PTP_EN, PTP_CFG_MISC); in ocelot_init_timestamp()
852 int ocelot_deinit_timestamp(struct ocelot *ocelot) in ocelot_deinit_timestamp() argument
854 if (ocelot->ptp_clock) in ocelot_deinit_timestamp()
855 ptp_clock_unregister(ocelot->ptp_clock); in ocelot_deinit_timestamp()