Skip to content

Commit 997edb4

Browse files
yangbolu1991nashif
authored andcommitted
net: dsa: add PTP solution in core driver
Added PTP solution in core driver. Now only gPTP was supported. - ethernet_api like get_capabilities and get_ptp_clock were supported in port driver. - For TX timestamp, added new dsa_api port_txtstamp for device to handle. Device driver might put pkt in queue, and reported timestamp after completing transmitting on hardware. - For RX timestamp, the timestamp could be given to pkt in tag driver or device driver. Signed-off-by: Yangbo Lu <[email protected]>
1 parent 17f4d34 commit 997edb4

File tree

3 files changed

+72
-2
lines changed

3 files changed

+72
-2
lines changed

include/zephyr/net/dsa_core.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,13 @@ struct dsa_api {
117117
/** Port generates random mac address */
118118
void (*port_generate_random_mac)(uint8_t *mac_addr);
119119

120+
#if defined(CONFIG_NET_L2_PTP) || defined(__DOXYGEN__)
121+
/**
122+
* Port TX timestamp handling
123+
* @kconfig_dep{CONFIG_NET_L2_PTP}
124+
*/
125+
int (*port_txtstamp)(const struct device *dev, struct net_pkt *pkt);
126+
#endif
120127
/** Switch setup */
121128
int (*switch_setup)(const struct dsa_switch_context *dsa_switch_ctx);
122129

@@ -142,6 +149,13 @@ struct dsa_port_config {
142149
const int tag_proto;
143150
/** Ethernet device connected to the port */
144151
const struct device *ethernet_connection;
152+
#if defined(CONFIG_NET_L2_PTP) || defined(__DOXYGEN__)
153+
/**
154+
* PTP clock used on the port
155+
* @kconfig_dep{CONFIG_NET_L2_PTP}
156+
*/
157+
const struct device *ptp_clock;
158+
#endif
145159
/** Instance specific config */
146160
void *prv_config;
147161
};

subsys/net/l2/ethernet/dsa/dsa_core.c

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,42 @@ int dsa_xmit(const struct device *dev, struct net_pkt *pkt)
2929
struct net_if *iface_conduit = dsa_switch_ctx->iface_conduit;
3030
const struct device *dev_conduit = net_if_get_device(iface_conduit);
3131
const struct ethernet_api *eth_api_conduit = dev_conduit->api;
32+
struct net_pkt *dsa_pkt;
33+
struct net_pkt *clone;
34+
int ret;
35+
36+
#ifdef CONFIG_NET_L2_PTP
37+
/* Handle TX timestamp if defines */
38+
if (ntohs(NET_ETH_HDR(pkt)->type) == NET_ETH_PTYPE_PTP &&
39+
dsa_switch_ctx->dapi->port_txtstamp != NULL) {
40+
ret = dsa_switch_ctx->dapi->port_txtstamp(dev, pkt);
41+
if (ret != 0) {
42+
return ret;
43+
}
44+
}
45+
#endif
46+
/*
47+
* In case of using TX pkt in other places, pkt should not be changed.
48+
* Here just clone pkt to use for tagging and sending.
49+
* It could be optimized here for performance in the future if some mechanism
50+
* implemented marks whether the pkt data will be accessed or not in other
51+
* places after sending.
52+
*/
53+
clone = net_pkt_clone(pkt, K_NO_WAIT);
54+
if (clone == NULL) {
55+
return -ENOBUFS;
56+
}
57+
3258
/* Tag protocol handles pkt first */
33-
struct net_pkt *dsa_pkt = dsa_tag_xmit(iface, pkt);
59+
dsa_pkt = dsa_tag_xmit(iface, clone);
3460

3561
/* Transmit from conduit port */
36-
return eth_api_conduit->send(dev_conduit, dsa_pkt);
62+
ret = eth_api_conduit->send(dev_conduit, dsa_pkt);
63+
64+
/* Release the cloned pkt */
65+
net_pkt_unref(clone);
66+
67+
return ret;
3768
}
3869

3970
int dsa_eth_init(struct net_if *iface)

subsys/net/l2/ethernet/dsa/dsa_port.c

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,8 +122,33 @@ static const struct device *dsa_port_get_phy(const struct device *dev)
122122
return cfg->phy_dev;
123123
}
124124

125+
#ifdef CONFIG_NET_L2_PTP
126+
const struct device *dsa_port_get_ptp_clock(const struct device *dev)
127+
{
128+
const struct dsa_port_config *cfg = dev->config;
129+
130+
return cfg->ptp_clock;
131+
}
132+
#endif
133+
134+
enum ethernet_hw_caps dsa_port_get_capabilities(const struct device *dev)
135+
{
136+
uint32_t caps = 0;
137+
138+
#ifdef CONFIG_NET_L2_PTP
139+
if (dsa_port_get_ptp_clock(dev) != NULL) {
140+
caps |= ETHERNET_PTP;
141+
}
142+
#endif
143+
return caps;
144+
}
145+
125146
const struct ethernet_api dsa_eth_api = {
126147
.iface_api.init = dsa_port_iface_init,
127148
.get_phy = dsa_port_get_phy,
128149
.send = dsa_xmit,
150+
#ifdef CONFIG_NET_L2_PTP
151+
.get_ptp_clock = dsa_port_get_ptp_clock,
152+
#endif
153+
.get_capabilities = dsa_port_get_capabilities,
129154
};

0 commit comments

Comments
 (0)