Lines Matching +full:tx +full:- +full:delay +full:- +full:ps
1 // SPDX-License-Identifier: GPL-2.0-or-later
19 #define SKB_PTP_TYPE(__skb) (*(unsigned int *)((__skb)->cb))
24 if (!chip->info->ops->avb_ops->port_ptp_read) in mv88e6xxx_port_ptp_read()
25 return -EOPNOTSUPP; in mv88e6xxx_port_ptp_read()
27 return chip->info->ops->avb_ops->port_ptp_read(chip, port, addr, in mv88e6xxx_port_ptp_read()
34 if (!chip->info->ops->avb_ops->port_ptp_write) in mv88e6xxx_port_ptp_write()
35 return -EOPNOTSUPP; in mv88e6xxx_port_ptp_write()
37 return chip->info->ops->avb_ops->port_ptp_write(chip, port, addr, in mv88e6xxx_port_ptp_write()
44 if (!chip->info->ops->avb_ops->ptp_write) in mv88e6xxx_ptp_write()
45 return -EOPNOTSUPP; in mv88e6xxx_ptp_write()
47 return chip->info->ops->avb_ops->ptp_write(chip, addr, data); in mv88e6xxx_ptp_write()
53 if (!chip->info->ops->avb_ops->ptp_read) in mv88e6xxx_ptp_read()
54 return -EOPNOTSUPP; in mv88e6xxx_ptp_read()
56 return chip->info->ops->avb_ops->ptp_read(chip, addr, data, 1); in mv88e6xxx_ptp_read()
59 /* TX_TSTAMP_TIMEOUT: This limits the time spent polling for a TX
72 chip = ds->priv; in mv88e6xxx_get_ts_info()
73 ptp_ops = chip->info->ops->ptp_ops; in mv88e6xxx_get_ts_info()
75 if (!chip->info->ptp_support) in mv88e6xxx_get_ts_info()
76 return -EOPNOTSUPP; in mv88e6xxx_get_ts_info()
78 info->so_timestamping = in mv88e6xxx_get_ts_info()
82 info->phc_index = ptp_clock_index(chip->ptp_clock); in mv88e6xxx_get_ts_info()
83 info->tx_types = in mv88e6xxx_get_ts_info()
86 info->rx_filters = ptp_ops->rx_filters; in mv88e6xxx_get_ts_info()
94 const struct mv88e6xxx_ptp_ops *ptp_ops = chip->info->ops->ptp_ops; in mv88e6xxx_set_hwtstamp_config()
95 struct mv88e6xxx_port_hwtstamp *ps = &chip->port_hwtstamp[port]; in mv88e6xxx_set_hwtstamp_config() local
98 /* Prevent the TX/RX paths from trying to interact with the in mv88e6xxx_set_hwtstamp_config()
101 clear_bit_unlock(MV88E6XXX_HWTSTAMP_ENABLED, &ps->state); in mv88e6xxx_set_hwtstamp_config()
103 switch (config->tx_type) { in mv88e6xxx_set_hwtstamp_config()
111 return -ERANGE; in mv88e6xxx_set_hwtstamp_config()
118 if (!(BIT(config->rx_filter) & ptp_ops->rx_filters)) { in mv88e6xxx_set_hwtstamp_config()
119 config->rx_filter = HWTSTAMP_FILTER_NONE; in mv88e6xxx_set_hwtstamp_config()
120 dev_dbg(chip->dev, "Unsupported rx_filter %d\n", in mv88e6xxx_set_hwtstamp_config()
121 config->rx_filter); in mv88e6xxx_set_hwtstamp_config()
122 return -ERANGE; in mv88e6xxx_set_hwtstamp_config()
125 switch (config->rx_filter) { in mv88e6xxx_set_hwtstamp_config()
138 config->rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT; in mv88e6xxx_set_hwtstamp_config()
142 config->rx_filter = HWTSTAMP_FILTER_NONE; in mv88e6xxx_set_hwtstamp_config()
143 return -ERANGE; in mv88e6xxx_set_hwtstamp_config()
148 chip->enable_count += 1; in mv88e6xxx_set_hwtstamp_config()
149 if (chip->enable_count == 1 && ptp_ops->global_enable) in mv88e6xxx_set_hwtstamp_config()
150 ptp_ops->global_enable(chip); in mv88e6xxx_set_hwtstamp_config()
151 if (ptp_ops->port_enable) in mv88e6xxx_set_hwtstamp_config()
152 ptp_ops->port_enable(chip, port); in mv88e6xxx_set_hwtstamp_config()
154 if (ptp_ops->port_disable) in mv88e6xxx_set_hwtstamp_config()
155 ptp_ops->port_disable(chip, port); in mv88e6xxx_set_hwtstamp_config()
156 chip->enable_count -= 1; in mv88e6xxx_set_hwtstamp_config()
157 if (chip->enable_count == 0 && ptp_ops->global_disable) in mv88e6xxx_set_hwtstamp_config()
158 ptp_ops->global_disable(chip); in mv88e6xxx_set_hwtstamp_config()
163 * in the RX/TX paths. in mv88e6xxx_set_hwtstamp_config()
166 set_bit(MV88E6XXX_HWTSTAMP_ENABLED, &ps->state); in mv88e6xxx_set_hwtstamp_config()
174 struct mv88e6xxx_chip *chip = ds->priv; in mv88e6xxx_port_hwtstamp_set()
175 struct mv88e6xxx_port_hwtstamp *ps = &chip->port_hwtstamp[port]; in mv88e6xxx_port_hwtstamp_set() local
179 if (!chip->info->ptp_support) in mv88e6xxx_port_hwtstamp_set()
180 return -EOPNOTSUPP; in mv88e6xxx_port_hwtstamp_set()
182 if (copy_from_user(&config, ifr->ifr_data, sizeof(config))) in mv88e6xxx_port_hwtstamp_set()
183 return -EFAULT; in mv88e6xxx_port_hwtstamp_set()
190 memcpy(&ps->tstamp_config, &config, sizeof(config)); in mv88e6xxx_port_hwtstamp_set()
192 return copy_to_user(ifr->ifr_data, &config, sizeof(config)) ? in mv88e6xxx_port_hwtstamp_set()
193 -EFAULT : 0; in mv88e6xxx_port_hwtstamp_set()
199 struct mv88e6xxx_chip *chip = ds->priv; in mv88e6xxx_port_hwtstamp_get()
200 struct mv88e6xxx_port_hwtstamp *ps = &chip->port_hwtstamp[port]; in mv88e6xxx_port_hwtstamp_get() local
201 struct hwtstamp_config *config = &ps->tstamp_config; in mv88e6xxx_port_hwtstamp_get()
203 if (!chip->info->ptp_support) in mv88e6xxx_port_hwtstamp_get()
204 return -EOPNOTSUPP; in mv88e6xxx_port_hwtstamp_get()
206 return copy_to_user(ifr->ifr_data, config, sizeof(*config)) ? in mv88e6xxx_port_hwtstamp_get()
207 -EFAULT : 0; in mv88e6xxx_port_hwtstamp_get()
217 struct mv88e6xxx_port_hwtstamp *ps = &chip->port_hwtstamp[port]; in mv88e6xxx_should_tstamp() local
220 if (!chip->info->ptp_support) in mv88e6xxx_should_tstamp()
227 if (!test_bit(MV88E6XXX_HWTSTAMP_ENABLED, &ps->state)) in mv88e6xxx_should_tstamp()
249 return ts_seqid == ntohs(hdr->sequence_id); in seq_match()
253 struct mv88e6xxx_port_hwtstamp *ps, in mv88e6xxx_get_rxts() argument
266 spin_lock_irqsave(&rxq->lock, flags); in mv88e6xxx_get_rxts()
268 spin_unlock_irqrestore(&rxq->lock, flags); in mv88e6xxx_get_rxts()
271 err = mv88e6xxx_port_ptp_read(chip, ps->port_id, in mv88e6xxx_get_rxts()
284 err = mv88e6xxx_port_ptp_write(chip, ps->port_id, reg, 0); in mv88e6xxx_get_rxts()
297 ns = timecounter_cyc2time(&chip->tstamp_tc, ns); in mv88e6xxx_get_rxts()
301 shwt->hwtstamp = ns_to_ktime(ns); in mv88e6xxx_get_rxts()
309 struct mv88e6xxx_port_hwtstamp *ps) in mv88e6xxx_rxtstamp_work() argument
311 const struct mv88e6xxx_ptp_ops *ptp_ops = chip->info->ops->ptp_ops; in mv88e6xxx_rxtstamp_work()
314 skb = skb_dequeue(&ps->rx_queue); in mv88e6xxx_rxtstamp_work()
317 mv88e6xxx_get_rxts(chip, ps, skb, ptp_ops->arr0_sts_reg, in mv88e6xxx_rxtstamp_work()
318 &ps->rx_queue); in mv88e6xxx_rxtstamp_work()
320 skb = skb_dequeue(&ps->rx_queue2); in mv88e6xxx_rxtstamp_work()
322 mv88e6xxx_get_rxts(chip, ps, skb, ptp_ops->arr1_sts_reg, in mv88e6xxx_rxtstamp_work()
323 &ps->rx_queue2); in mv88e6xxx_rxtstamp_work()
328 return (hdr->tsmt & 0xf) == 3; in is_pdelay_resp()
334 struct mv88e6xxx_port_hwtstamp *ps; in mv88e6xxx_port_rxtstamp() local
338 chip = ds->priv; in mv88e6xxx_port_rxtstamp()
339 ps = &chip->port_hwtstamp[port]; in mv88e6xxx_port_rxtstamp()
341 if (ps->tstamp_config.rx_filter != HWTSTAMP_FILTER_PTP_V2_EVENT) in mv88e6xxx_port_rxtstamp()
351 skb_queue_tail(&ps->rx_queue2, skb); in mv88e6xxx_port_rxtstamp()
353 skb_queue_tail(&ps->rx_queue, skb); in mv88e6xxx_port_rxtstamp()
355 ptp_schedule_worker(chip->ptp_clock, 0); in mv88e6xxx_port_rxtstamp()
361 struct mv88e6xxx_port_hwtstamp *ps) in mv88e6xxx_txtstamp_work() argument
363 const struct mv88e6xxx_ptp_ops *ptp_ops = chip->info->ops->ptp_ops; in mv88e6xxx_txtstamp_work()
371 if (!ps->tx_skb) in mv88e6xxx_txtstamp_work()
375 err = mv88e6xxx_port_ptp_read(chip, ps->port_id, in mv88e6xxx_txtstamp_work()
376 ptp_ops->dep_sts_reg, in mv88e6xxx_txtstamp_work()
385 if (time_is_before_jiffies(ps->tx_tstamp_start + in mv88e6xxx_txtstamp_work()
387 dev_warn(chip->dev, "p%d: clearing tx timestamp hang\n", in mv88e6xxx_txtstamp_work()
388 ps->port_id); in mv88e6xxx_txtstamp_work()
400 mv88e6xxx_port_ptp_write(chip, ps->port_id, ptp_ops->dep_sts_reg, 0); in mv88e6xxx_txtstamp_work()
405 dev_warn(chip->dev, "p%d: tx timestamp overrun\n", ps->port_id); in mv88e6xxx_txtstamp_work()
409 if (departure_block[3] != ps->tx_seq_id) { in mv88e6xxx_txtstamp_work()
410 dev_warn(chip->dev, "p%d: unexpected seq. id\n", ps->port_id); in mv88e6xxx_txtstamp_work()
417 ns = timecounter_cyc2time(&chip->tstamp_tc, time_raw); in mv88e6xxx_txtstamp_work()
421 dev_dbg(chip->dev, in mv88e6xxx_txtstamp_work()
423 ps->port_id, ktime_to_ns(shhwtstamps.hwtstamp), in mv88e6xxx_txtstamp_work()
424 departure_block[0], ps->tx_seq_id, departure_block[3]); in mv88e6xxx_txtstamp_work()
427 * another timestamp-able transmit. We have to be ready for it in mv88e6xxx_txtstamp_work()
428 * -- by clearing the ps->tx_skb "flag" -- beforehand. in mv88e6xxx_txtstamp_work()
431 tmp_skb = ps->tx_skb; in mv88e6xxx_txtstamp_work()
432 ps->tx_skb = NULL; in mv88e6xxx_txtstamp_work()
433 clear_bit_unlock(MV88E6XXX_HWTSTAMP_TX_IN_PROGRESS, &ps->state); in mv88e6xxx_txtstamp_work()
439 dev_kfree_skb_any(ps->tx_skb); in mv88e6xxx_txtstamp_work()
440 ps->tx_skb = NULL; in mv88e6xxx_txtstamp_work()
441 clear_bit_unlock(MV88E6XXX_HWTSTAMP_TX_IN_PROGRESS, &ps->state); in mv88e6xxx_txtstamp_work()
449 struct dsa_switch *ds = chip->ds; in mv88e6xxx_hwtstamp_work()
450 struct mv88e6xxx_port_hwtstamp *ps; in mv88e6xxx_hwtstamp_work() local
453 for (i = 0; i < ds->num_ports; i++) { in mv88e6xxx_hwtstamp_work()
457 ps = &chip->port_hwtstamp[i]; in mv88e6xxx_hwtstamp_work()
458 if (test_bit(MV88E6XXX_HWTSTAMP_TX_IN_PROGRESS, &ps->state)) in mv88e6xxx_hwtstamp_work()
459 restart |= mv88e6xxx_txtstamp_work(chip, ps); in mv88e6xxx_hwtstamp_work()
461 mv88e6xxx_rxtstamp_work(chip, ps); in mv88e6xxx_hwtstamp_work()
464 return restart ? 1 : -1; in mv88e6xxx_hwtstamp_work()
470 struct mv88e6xxx_chip *chip = ds->priv; in mv88e6xxx_port_txtstamp()
471 struct mv88e6xxx_port_hwtstamp *ps = &chip->port_hwtstamp[port]; in mv88e6xxx_port_txtstamp() local
489 &ps->state)) { in mv88e6xxx_port_txtstamp()
494 ps->tx_skb = clone; in mv88e6xxx_port_txtstamp()
495 ps->tx_tstamp_start = jiffies; in mv88e6xxx_port_txtstamp()
496 ps->tx_seq_id = be16_to_cpu(hdr->sequence_id); in mv88e6xxx_port_txtstamp()
498 ptp_schedule_worker(chip->ptp_clock, 0); in mv88e6xxx_port_txtstamp()
542 const struct mv88e6xxx_ptp_ops *ptp_ops = chip->info->ops->ptp_ops; in mv88e6xxx_hwtstamp_port_setup()
543 struct mv88e6xxx_port_hwtstamp *ps = &chip->port_hwtstamp[port]; in mv88e6xxx_hwtstamp_port_setup() local
545 ps->port_id = port; in mv88e6xxx_hwtstamp_port_setup()
547 skb_queue_head_init(&ps->rx_queue); in mv88e6xxx_hwtstamp_port_setup()
548 skb_queue_head_init(&ps->rx_queue2); in mv88e6xxx_hwtstamp_port_setup()
550 if (ptp_ops->port_disable) in mv88e6xxx_hwtstamp_port_setup()
551 return ptp_ops->port_disable(chip, port); in mv88e6xxx_hwtstamp_port_setup()
558 const struct mv88e6xxx_ptp_ops *ptp_ops = chip->info->ops->ptp_ops; in mv88e6xxx_hwtstamp_setup()
570 if (ptp_ops->global_disable) { in mv88e6xxx_hwtstamp_setup()
571 err = ptp_ops->global_disable(chip); in mv88e6xxx_hwtstamp_setup()
583 * but the timestamp config is per-port; thus we configure all events in mv88e6xxx_hwtstamp_setup()
591 /* Use ARRIVAL1 for peer delay response messages. */ in mv88e6xxx_hwtstamp_setup()
601 if (chip->info->family == MV88E6XXX_FAMILY_6341) { in mv88e6xxx_hwtstamp_setup()