Lines Matching +full:tx +full:- +full:ts +full:- +full:mask
1 // SPDX-License-Identifier: GPL-2.0
3 // Copyright (C) 2018 MOSER-BAER AG
103 #define ines_read32(s, r) __raw_readl((void __iomem *)&s->regs->r)
104 #define ines_write32(s, v, r) __raw_writel(v, (void __iomem *)&s->regs->r)
171 struct ines_timestamp *ts, struct device *dev);
174 static bool ines_timestamp_expired(struct ines_timestamp *ts);
186 port = &clock->port[i]; in ines_clock_cleanup()
187 cancel_delayed_work_sync(&port->ts_work); in ines_clock_cleanup()
194 struct device_node *node = device->of_node; in ines_clock_init()
199 INIT_LIST_HEAD(&clock->list); in ines_clock_init()
200 clock->node = node; in ines_clock_init()
201 clock->dev = device; in ines_clock_init()
202 clock->base = addr; in ines_clock_init()
203 clock->regs = clock->base; in ines_clock_init()
206 port = &clock->port[i]; in ines_clock_init()
207 port_addr = (unsigned long) clock->base + in ines_clock_init()
209 port->regs = (struct ines_port_registers *) port_addr; in ines_clock_init()
210 port->clock = clock; in ines_clock_init()
211 port->index = i; in ines_clock_init()
212 INIT_DELAYED_WORK(&port->ts_work, ines_txtstamp_work); in ines_clock_init()
213 spin_lock_init(&port->lock); in ines_clock_init()
214 INIT_LIST_HEAD(&port->events); in ines_clock_init()
215 INIT_LIST_HEAD(&port->pool); in ines_clock_init()
217 list_add(&port->pool_data[j].list, &port->pool); in ines_clock_init()
229 port = &clock->port[i]; in ines_clock_init()
245 if (clock->node == node) { in ines_find_port()
246 port = &clock->port[index]; in ines_find_port()
257 struct ines_timestamp *ts; in ines_find_rxts() local
264 spin_lock_irqsave(&port->lock, flags); in ines_find_rxts()
266 list_for_each_safe(this, next, &port->events) { in ines_find_rxts()
267 ts = list_entry(this, struct ines_timestamp, list); in ines_find_rxts()
268 if (ines_timestamp_expired(ts)) { in ines_find_rxts()
269 list_del_init(&ts->list); in ines_find_rxts()
270 list_add(&ts->list, &port->pool); in ines_find_rxts()
273 if (ines_match(skb, type, ts, port->clock->dev)) { in ines_find_rxts()
274 ns = ts->sec * 1000000000ULL + ts->nsec; in ines_find_rxts()
275 list_del_init(&ts->list); in ines_find_rxts()
276 list_add(&ts->list, &port->pool); in ines_find_rxts()
280 spin_unlock_irqrestore(&port->lock, flags); in ines_find_rxts()
288 u32 data_rd_pos, buf_stat, mask, ts_stat_tx; in ines_find_txts() local
289 struct ines_timestamp ts; in ines_find_txts() local
293 mask = TX_FIFO_NE_1 << port->index; in ines_find_txts()
295 spin_lock_irqsave(&port->lock, flags); in ines_find_txts()
299 buf_stat = ines_read32(port->clock, buf_stat); in ines_find_txts()
300 if (!(buf_stat & mask)) { in ines_find_txts()
301 dev_dbg(port->clock->dev, in ines_find_txts()
302 "Tx timestamp FIFO unexpectedly empty\n"); in ines_find_txts()
309 dev_err(port->clock->dev, in ines_find_txts()
310 "unexpected Tx read pos %u\n", data_rd_pos); in ines_find_txts()
314 ts.tag = ines_read32(port, ts_tx); in ines_find_txts()
315 ts.sec = ines_txts64(port, 3); in ines_find_txts()
316 ts.nsec = ines_txts64(port, 2); in ines_find_txts()
317 ts.clkid = ines_txts64(port, 4); in ines_find_txts()
318 ts.portnum = ines_read32(port, ts_tx); in ines_find_txts()
319 ts.seqid = ines_read32(port, ts_tx); in ines_find_txts()
321 if (ines_match(skb, class, &ts, port->clock->dev)) { in ines_find_txts()
322 ns = ts.sec * 1000000000ULL + ts.nsec; in ines_find_txts()
327 spin_unlock_irqrestore(&port->lock, flags); in ines_find_txts()
339 switch (cfg->tx_type) { in ines_hwtstamp()
351 return -ERANGE; in ines_hwtstamp()
354 switch (cfg->rx_filter) { in ines_hwtstamp()
362 return -ERANGE; in ines_hwtstamp()
373 cfg->rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT; in ines_hwtstamp()
376 return -ERANGE; in ines_hwtstamp()
379 spin_lock_irqsave(&port->lock, flags); in ines_hwtstamp()
389 port->rxts_enabled = ts_stat_rx == TS_ENABLE; in ines_hwtstamp()
390 port->txts_enabled = ts_stat_tx == TS_ENABLE; in ines_hwtstamp()
392 spin_unlock_irqrestore(&port->lock, flags); in ines_hwtstamp()
404 switch (phydev->speed) { in ines_link_state()
415 dev_err(port->clock->dev, "bad speed: %d\n", phydev->speed); in ines_link_state()
418 spin_lock_irqsave(&port->lock, flags); in ines_link_state()
426 spin_unlock_irqrestore(&port->lock, flags); in ines_link_state()
430 struct ines_timestamp *ts, struct device *dev) in ines_match() argument
445 clkid = be64_to_cpup((__be64 *)&hdr->source_port_identity.clock_identity.id[0]); in ines_match()
446 portn = be16_to_cpu(hdr->source_port_identity.port_number); in ines_match()
447 seqid = be16_to_cpu(hdr->sequence_id); in ines_match()
449 if (tag_to_msgtype(ts->tag & 0x7) != msgtype) { in ines_match()
450 dev_dbg(dev, "msgtype mismatch ts %hhu != skb %hhu\n", in ines_match()
451 tag_to_msgtype(ts->tag & 0x7), msgtype); in ines_match()
454 if (ts->clkid != clkid) { in ines_match()
455 dev_dbg(dev, "clkid mismatch ts %llx != skb %llx\n", in ines_match()
456 ts->clkid, clkid); in ines_match()
459 if (ts->portnum != portn) { in ines_match()
460 dev_dbg(dev, "portn mismatch ts %hu != skb %hu\n", in ines_match()
461 ts->portnum, portn); in ines_match()
464 if (ts->seqid != seqid) { in ines_match()
465 dev_dbg(dev, "seqid mismatch ts %hu != skb %hu\n", in ines_match()
466 ts->seqid, seqid); in ines_match()
480 if (!port->rxts_enabled) in ines_rxtstamp()
488 ssh->hwtstamp = ns_to_ktime(ns); in ines_rxtstamp()
496 u32 data_rd_pos, buf_stat, mask, ts_stat_rx; in ines_rxfifo_read() local
497 struct ines_timestamp *ts; in ines_rxfifo_read() local
500 mask = RX_FIFO_NE_1 << port->index; in ines_rxfifo_read()
503 if (list_empty(&port->pool)) { in ines_rxfifo_read()
504 dev_err(port->clock->dev, "event pool is empty\n"); in ines_rxfifo_read()
505 return -1; in ines_rxfifo_read()
507 buf_stat = ines_read32(port->clock, buf_stat); in ines_rxfifo_read()
508 if (!(buf_stat & mask)) in ines_rxfifo_read()
515 dev_err(port->clock->dev, "unexpected Rx read pos %u\n", in ines_rxfifo_read()
520 ts = list_first_entry(&port->pool, struct ines_timestamp, list); in ines_rxfifo_read()
521 ts->tmo = jiffies + HZ; in ines_rxfifo_read()
522 ts->tag = ines_read32(port, ts_rx); in ines_rxfifo_read()
523 ts->sec = ines_rxts64(port, 3); in ines_rxfifo_read()
524 ts->nsec = ines_rxts64(port, 2); in ines_rxfifo_read()
525 ts->clkid = ines_rxts64(port, 4); in ines_rxfifo_read()
526 ts->portnum = ines_read32(port, ts_rx); in ines_rxfifo_read()
527 ts->seqid = ines_read32(port, ts_rx); in ines_rxfifo_read()
529 list_del_init(&ts->list); in ines_rxfifo_read()
530 list_add_tail(&ts->list, &port->events); in ines_rxfifo_read()
544 words--; in ines_rxts64()
553 static bool ines_timestamp_expired(struct ines_timestamp *ts) in ines_timestamp_expired() argument
555 return time_after(jiffies, ts->tmo); in ines_timestamp_expired()
561 info->so_timestamping = in ines_ts_info()
567 info->tx_types = in ines_ts_info()
572 info->rx_filters = in ines_ts_info()
587 words--; in ines_txts64()
601 spin_lock_irqsave(&port->lock, flags); in ines_txts_onestep()
603 spin_unlock_irqrestore(&port->lock, flags); in ines_txts_onestep()
618 if (!port->txts_enabled || ines_txts_onestep(port, skb, type)) { in ines_txtstamp()
623 spin_lock_irqsave(&port->lock, flags); in ines_txtstamp()
625 if (port->tx_skb) in ines_txtstamp()
626 old_skb = port->tx_skb; in ines_txtstamp()
628 port->tx_skb = skb; in ines_txtstamp()
630 spin_unlock_irqrestore(&port->lock, flags); in ines_txtstamp()
634 schedule_delayed_work(&port->ts_work, 1); in ines_txtstamp()
646 spin_lock_irqsave(&port->lock, flags); in ines_txtstamp_work()
647 skb = port->tx_skb; in ines_txtstamp_work()
648 port->tx_skb = NULL; in ines_txtstamp_work()
649 spin_unlock_irqrestore(&port->lock, flags); in ines_txtstamp_work()
698 struct device_node *node = device->of_node; in ines_ptp_probe_channel()
701 if (index > INES_N_PORTS - 1) { in ines_ptp_probe_channel()
703 return ERR_PTR(-EINVAL); in ines_ptp_probe_channel()
708 return ERR_PTR(-ENODEV); in ines_ptp_probe_channel()
710 port->mii_ts.rxtstamp = ines_rxtstamp; in ines_ptp_probe_channel()
711 port->mii_ts.txtstamp = ines_txtstamp; in ines_ptp_probe_channel()
712 port->mii_ts.hwtstamp = ines_hwtstamp; in ines_ptp_probe_channel()
713 port->mii_ts.link_state = ines_link_state; in ines_ptp_probe_channel()
714 port->mii_ts.ts_info = ines_ts_info; in ines_ptp_probe_channel()
716 return &port->mii_ts; in ines_ptp_probe_channel()
742 err = -ENOMEM; in ines_ptp_ctrl_probe()
745 if (ines_clock_init(clock, &pld->dev, addr)) { in ines_ptp_ctrl_probe()
747 err = -ENOMEM; in ines_ptp_ctrl_probe()
750 err = register_mii_tstamp_controller(&pld->dev, &ines_ctrl); in ines_ptp_ctrl_probe()
756 list_add_tail(&ines_clocks, &clock->list); in ines_ptp_ctrl_probe()
759 dev_set_drvdata(&pld->dev, clock); in ines_ptp_ctrl_probe()
766 struct ines_clock *clock = dev_get_drvdata(&pld->dev); in ines_ptp_ctrl_remove()
768 unregister_mii_tstamp_controller(&pld->dev); in ines_ptp_ctrl_remove()
770 list_del(&clock->list); in ines_ptp_ctrl_remove()
777 { .compatible = "ines,ptp-ctrl" },