Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

net: dsa: microchip: ptp: add packet transmission timestamping

This patch adds the routines for transmission of ptp packets. When the
ptp pdelay_req packet to be transmitted, it uses the deferred xmit
worker to schedule the packets.
During irq_setup, interrupt for Sync, Pdelay_req and Pdelay_rsp are
enabled. So interrupt is triggered for all three packets. But for
p2p1step, we require only time stamp of Pdelay_req packet. Hence to
avoid posting of the completion from ISR routine for Sync and
Pdelay_resp packets, ts_en flag is introduced. This controls which
packets need to processed for timestamp.
After the packet is transmitted, ISR is triggered. The time at which
packet transmitted is recorded to separate register.
This value is reconstructed to absolute time and posted to the user
application through socket error queue.

Signed-off-by: Christian Eggers <ceggers@arri.de>
Co-developed-by: Arun Ramadoss <arun.ramadoss@microchip.com>
Signed-off-by: Arun Ramadoss <arun.ramadoss@microchip.com>
Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Christian Eggers and committed by
David S. Miller
ab32f56a 90188fff

+196 -4
+14
drivers/net/dsa/microchip/ksz_common.c
··· 6 6 */ 7 7 8 8 #include <linux/delay.h> 9 + #include <linux/dsa/ksz_common.h> 9 10 #include <linux/export.h> 10 11 #include <linux/gpio/consumer.h> 11 12 #include <linux/kernel.h> ··· 2540 2539 return proto; 2541 2540 } 2542 2541 2542 + static int ksz_connect_tag_protocol(struct dsa_switch *ds, 2543 + enum dsa_tag_protocol proto) 2544 + { 2545 + struct ksz_tagger_data *tagger_data; 2546 + 2547 + tagger_data = ksz_tagger_data(ds); 2548 + tagger_data->xmit_work_fn = ksz_port_deferred_xmit; 2549 + 2550 + return 0; 2551 + } 2552 + 2543 2553 static int ksz_port_vlan_filtering(struct dsa_switch *ds, int port, 2544 2554 bool flag, struct netlink_ext_ack *extack) 2545 2555 { ··· 2966 2954 2967 2955 static const struct dsa_switch_ops ksz_switch_ops = { 2968 2956 .get_tag_protocol = ksz_get_tag_protocol, 2957 + .connect_tag_protocol = ksz_connect_tag_protocol, 2969 2958 .get_phy_flags = ksz_get_phy_flags, 2970 2959 .setup = ksz_setup, 2971 2960 .teardown = ksz_teardown, ··· 3004 2991 .get_ts_info = ksz_get_ts_info, 3005 2992 .port_hwtstamp_get = ksz_hwtstamp_get, 3006 2993 .port_hwtstamp_set = ksz_hwtstamp_set, 2994 + .port_txtstamp = ksz_port_txtstamp, 3007 2995 .port_rxtstamp = ksz_port_rxtstamp, 3008 2996 }; 3009 2997
+3
drivers/net/dsa/microchip/ksz_common.h
··· 87 87 struct ksz_ptp_irq { 88 88 struct ksz_port *port; 89 89 u16 ts_reg; 90 + bool ts_en; 90 91 char name[16]; 91 92 int num; 92 93 }; ··· 117 116 bool hwts_rx_en; 118 117 struct ksz_irq ptpirq; 119 118 struct ksz_ptp_irq ptpmsg_irq[3]; 119 + ktime_t tstamp_msg; 120 + struct completion tstamp_msg_comp; 120 121 #endif 121 122 }; 122 123
+114 -1
drivers/net/dsa/microchip/ksz_ptp.c
··· 18 18 19 19 #define ptp_caps_to_data(d) container_of((d), struct ksz_ptp_data, caps) 20 20 #define ptp_data_to_ksz_dev(d) container_of((d), struct ksz_device, ptp_data) 21 + #define work_to_xmit_work(w) \ 22 + container_of((w), struct ksz_deferred_xmit_work, work) 21 23 22 24 /* Sub-nanoseconds-adj,max * sub-nanoseconds / 40ns * 1ns 23 25 * = (2^30-1) * (2 ^ 32) / 40 ns * 1 ns = 6249999 ··· 113 111 114 112 switch (config->tx_type) { 115 113 case HWTSTAMP_TX_OFF: 114 + prt->ptpmsg_irq[KSZ_SYNC_MSG].ts_en = false; 115 + prt->ptpmsg_irq[KSZ_XDREQ_MSG].ts_en = false; 116 + prt->ptpmsg_irq[KSZ_PDRES_MSG].ts_en = false; 116 117 prt->hwts_tx_en = false; 117 118 break; 118 119 case HWTSTAMP_TX_ONESTEP_P2P: 120 + prt->ptpmsg_irq[KSZ_SYNC_MSG].ts_en = false; 121 + prt->ptpmsg_irq[KSZ_XDREQ_MSG].ts_en = true; 122 + prt->ptpmsg_irq[KSZ_PDRES_MSG].ts_en = false; 119 123 prt->hwts_tx_en = true; 120 124 break; 121 125 default: ··· 238 230 239 231 out: 240 232 return false; 233 + } 234 + 235 + void ksz_port_txtstamp(struct dsa_switch *ds, int port, struct sk_buff *skb) 236 + { 237 + struct ksz_device *dev = ds->priv; 238 + struct ptp_header *hdr; 239 + struct sk_buff *clone; 240 + struct ksz_port *prt; 241 + unsigned int type; 242 + u8 ptp_msg_type; 243 + 244 + prt = &dev->ports[port]; 245 + 246 + if (!prt->hwts_tx_en) 247 + return; 248 + 249 + type = ptp_classify_raw(skb); 250 + if (type == PTP_CLASS_NONE) 251 + return; 252 + 253 + hdr = ptp_parse_header(skb, type); 254 + if (!hdr) 255 + return; 256 + 257 + ptp_msg_type = ptp_get_msgtype(hdr, type); 258 + 259 + switch (ptp_msg_type) { 260 + case PTP_MSGTYPE_PDELAY_REQ: 261 + break; 262 + 263 + default: 264 + return; 265 + } 266 + 267 + clone = skb_clone_sk(skb); 268 + if (!clone) 269 + return; 270 + 271 + /* caching the value to be used in tag_ksz.c */ 272 + KSZ_SKB_CB(skb)->clone = clone; 273 + } 274 + 275 + static void ksz_ptp_txtstamp_skb(struct ksz_device *dev, 276 + struct ksz_port *prt, struct sk_buff *skb) 277 + { 278 + struct skb_shared_hwtstamps hwtstamps = {}; 279 + int ret; 280 + 281 + /* timeout must include DSA master to transmit data, tstamp latency, 282 + * IRQ latency and time for reading the time stamp. 283 + */ 284 + ret = wait_for_completion_timeout(&prt->tstamp_msg_comp, 285 + msecs_to_jiffies(100)); 286 + if (!ret) 287 + return; 288 + 289 + hwtstamps.hwtstamp = prt->tstamp_msg; 290 + skb_complete_tx_timestamp(skb, &hwtstamps); 291 + } 292 + 293 + void ksz_port_deferred_xmit(struct kthread_work *work) 294 + { 295 + struct ksz_deferred_xmit_work *xmit_work = work_to_xmit_work(work); 296 + struct sk_buff *clone, *skb = xmit_work->skb; 297 + struct dsa_switch *ds = xmit_work->dp->ds; 298 + struct ksz_device *dev = ds->priv; 299 + struct ksz_port *prt; 300 + 301 + prt = &dev->ports[xmit_work->dp->index]; 302 + 303 + clone = KSZ_SKB_CB(skb)->clone; 304 + 305 + skb_shinfo(clone)->tx_flags |= SKBTX_IN_PROGRESS; 306 + 307 + reinit_completion(&prt->tstamp_msg_comp); 308 + 309 + dsa_enqueue_skb(skb, skb->dev); 310 + 311 + ksz_ptp_txtstamp_skb(dev, prt, clone); 312 + 313 + kfree(xmit_work); 241 314 } 242 315 243 316 static int _ksz_ptp_gettime(struct ksz_device *dev, struct timespec64 *ts) ··· 577 488 578 489 static irqreturn_t ksz_ptp_msg_thread_fn(int irq, void *dev_id) 579 490 { 580 - return IRQ_NONE; 491 + struct ksz_ptp_irq *ptpmsg_irq = dev_id; 492 + struct ksz_device *dev; 493 + struct ksz_port *port; 494 + u32 tstamp_raw; 495 + ktime_t tstamp; 496 + int ret; 497 + 498 + port = ptpmsg_irq->port; 499 + dev = port->ksz_dev; 500 + 501 + if (ptpmsg_irq->ts_en) { 502 + ret = ksz_read32(dev, ptpmsg_irq->ts_reg, &tstamp_raw); 503 + if (ret) 504 + return IRQ_NONE; 505 + 506 + tstamp = ksz_decode_tstamp(tstamp_raw); 507 + 508 + port->tstamp_msg = ksz_tstamp_reconstruct(dev, tstamp); 509 + 510 + complete(&port->tstamp_msg_comp); 511 + } 512 + 513 + return IRQ_HANDLED; 581 514 } 582 515 583 516 static irqreturn_t ksz_ptp_irq_thread_fn(int irq, void *dev_id) ··· 743 632 ptpirq->reg_status = ops->get_port_addr(p, 744 633 REG_PTP_PORT_TX_INT_STATUS__2); 745 634 snprintf(ptpirq->name, sizeof(ptpirq->name), "ptp-irq-%d", p); 635 + 636 + init_completion(&port->tstamp_msg_comp); 746 637 747 638 ptpirq->domain = irq_domain_add_linear(dev->dev->of_node, ptpirq->nirqs, 748 639 &ksz_ptp_irq_domain_ops, ptpirq);
+6
drivers/net/dsa/microchip/ksz_ptp.h
··· 30 30 struct ethtool_ts_info *ts); 31 31 int ksz_hwtstamp_get(struct dsa_switch *ds, int port, struct ifreq *ifr); 32 32 int ksz_hwtstamp_set(struct dsa_switch *ds, int port, struct ifreq *ifr); 33 + void ksz_port_txtstamp(struct dsa_switch *ds, int port, struct sk_buff *skb); 34 + void ksz_port_deferred_xmit(struct kthread_work *work); 33 35 bool ksz_port_rxtstamp(struct dsa_switch *ds, int port, struct sk_buff *skb, 34 36 unsigned int type); 35 37 int ksz_ptp_irq_setup(struct dsa_switch *ds, u8 p); ··· 65 63 #define ksz_hwtstamp_set NULL 66 64 67 65 #define ksz_port_rxtstamp NULL 66 + 67 + #define ksz_port_txtstamp NULL 68 + 69 + #define ksz_port_deferred_xmit NULL 68 70 69 71 #endif /* End of CONFIG_NET_DSA_MICROCHIP_KSZ_PTP */ 70 72
+8
include/linux/dsa/ksz_common.h
··· 23 23 return ns_to_ktime(ns); 24 24 } 25 25 26 + struct ksz_deferred_xmit_work { 27 + struct dsa_port *dp; 28 + struct sk_buff *skb; 29 + struct kthread_work work; 30 + }; 31 + 26 32 struct ksz_tagger_data { 33 + void (*xmit_work_fn)(struct kthread_work *work); 27 34 void (*hwtstamp_set_state)(struct dsa_switch *ds, bool on); 28 35 }; 29 36 30 37 struct ksz_skb_cb { 38 + struct sk_buff *clone; 31 39 u32 tstamp; 32 40 }; 33 41
+51 -3
net/dsa/tag_ksz.c
··· 26 26 struct ksz_tagger_private { 27 27 struct ksz_tagger_data data; /* Must be first */ 28 28 unsigned long state; 29 + struct kthread_worker *xmit_worker; 29 30 }; 30 31 31 32 static struct ksz_tagger_private * ··· 49 48 { 50 49 struct ksz_tagger_private *priv = ds->tagger_data; 51 50 51 + kthread_destroy_worker(priv->xmit_worker); 52 52 kfree(priv); 53 53 ds->tagger_data = NULL; 54 54 } ··· 57 55 static int ksz_connect(struct dsa_switch *ds) 58 56 { 59 57 struct ksz_tagger_data *tagger_data; 58 + struct kthread_worker *xmit_worker; 60 59 struct ksz_tagger_private *priv; 60 + int ret; 61 61 62 62 priv = kzalloc(sizeof(*priv), GFP_KERNEL); 63 63 if (!priv) 64 64 return -ENOMEM; 65 65 66 + xmit_worker = kthread_create_worker(0, "dsa%d:%d_xmit", 67 + ds->dst->index, ds->index); 68 + if (IS_ERR(xmit_worker)) { 69 + ret = PTR_ERR(xmit_worker); 70 + kfree(priv); 71 + return ret; 72 + } 73 + 74 + priv->xmit_worker = xmit_worker; 66 75 /* Export functions for switch driver use */ 67 76 tagger_data = &priv->data; 68 77 tagger_data->hwtstamp_set_state = ksz_hwtstamp_set_state; ··· 204 191 put_unaligned_be32(0, skb_put(skb, KSZ_PTP_TAG_LEN)); 205 192 } 206 193 194 + /* Defer transmit if waiting for egress time stamp is required. */ 195 + static struct sk_buff *ksz_defer_xmit(struct dsa_port *dp, struct sk_buff *skb) 196 + { 197 + struct ksz_tagger_data *tagger_data = ksz_tagger_data(dp->ds); 198 + struct ksz_tagger_private *priv = ksz_tagger_private(dp->ds); 199 + void (*xmit_work_fn)(struct kthread_work *work); 200 + struct sk_buff *clone = KSZ_SKB_CB(skb)->clone; 201 + struct ksz_deferred_xmit_work *xmit_work; 202 + struct kthread_worker *xmit_worker; 203 + 204 + if (!clone) 205 + return skb; /* no deferred xmit for this packet */ 206 + 207 + xmit_work_fn = tagger_data->xmit_work_fn; 208 + xmit_worker = priv->xmit_worker; 209 + 210 + if (!xmit_work_fn || !xmit_worker) 211 + return NULL; 212 + 213 + xmit_work = kzalloc(sizeof(*xmit_work), GFP_ATOMIC); 214 + if (!xmit_work) 215 + return NULL; 216 + 217 + kthread_init_work(&xmit_work->work, xmit_work_fn); 218 + /* Increase refcount so the kfree_skb in dsa_slave_xmit 219 + * won't really free the packet. 220 + */ 221 + xmit_work->dp = dp; 222 + xmit_work->skb = skb_get(skb); 223 + 224 + kthread_queue_work(xmit_worker, &xmit_work->work); 225 + 226 + return NULL; 227 + } 228 + 207 229 static struct sk_buff *ksz9477_xmit(struct sk_buff *skb, 208 230 struct net_device *dev) 209 231 { ··· 263 215 264 216 *tag = cpu_to_be16(val); 265 217 266 - return skb; 218 + return ksz_defer_xmit(dp, skb); 267 219 } 268 220 269 221 static struct sk_buff *ksz9477_rcv(struct sk_buff *skb, struct net_device *dev) ··· 319 271 if (is_link_local_ether_addr(addr)) 320 272 *tag |= KSZ9893_TAIL_TAG_OVERRIDE; 321 273 322 - return skb; 274 + return ksz_defer_xmit(dp, skb); 323 275 } 324 276 325 277 static const struct dsa_device_ops ksz9893_netdev_ops = { ··· 384 336 385 337 put_unaligned_be16(val, tag); 386 338 387 - return skb; 339 + return ksz_defer_xmit(dp, skb); 388 340 } 389 341 390 342 static const struct dsa_device_ops lan937x_netdev_ops = {