2828#include <net/net_if.h>
2929#include <net/ethernet.h>
3030
31+ #if defined(CONFIG_ETH_NATIVE_POSIX_PTP_CLOCK )
32+ #include <ptp_clock.h>
33+ #include <net/gptp_messages.h>
34+ #endif
35+
3136#include "eth_native_posix_priv.h"
3237#include "eth_stats.h"
3338
@@ -77,6 +82,107 @@ static struct eth_context *get_context(struct net_if *iface)
7782 return net_if_get_device (iface )-> driver_data ;
7883}
7984
85+ #if defined(CONFIG_NET_GPTP )
86+ static bool need_timestamping (struct gptp_hdr * hdr )
87+ {
88+ switch (hdr -> message_type ) {
89+ case GPTP_SYNC_MESSAGE :
90+ case GPTP_PATH_DELAY_RESP_MESSAGE :
91+ return true;
92+ default :
93+ return false;
94+ }
95+ }
96+
97+ static struct gptp_hdr * check_gptp_msg (struct net_if * iface ,
98+ struct net_pkt * pkt )
99+ {
100+ struct ethernet_context * eth_ctx ;
101+ struct gptp_hdr * gptp_hdr ;
102+ u8_t * msg_start ;
103+
104+ if (net_pkt_ll_reserve (pkt )) {
105+ msg_start = net_pkt_ll (pkt );
106+ } else {
107+ msg_start = net_pkt_ip_data (pkt );
108+ }
109+
110+ #if defined(CONFIG_NET_VLAN )
111+ eth_ctx = net_if_l2_data (iface );
112+ if (net_eth_is_vlan_enabled (eth_ctx , iface )) {
113+ struct net_eth_vlan_hdr * hdr_vlan ;
114+
115+ hdr_vlan = (struct net_eth_vlan_hdr * )msg_start ;
116+ if (ntohs (hdr_vlan -> type ) != NET_ETH_PTYPE_PTP ) {
117+ return NULL ;
118+ }
119+
120+ gptp_hdr = (struct gptp_hdr * )(msg_start +
121+ sizeof (struct net_eth_vlan_hdr ));
122+ } else
123+ #endif
124+ {
125+ struct net_eth_hdr * hdr ;
126+
127+ hdr = (struct net_eth_hdr * )msg_start ;
128+ if (ntohs (hdr -> type ) != NET_ETH_PTYPE_PTP ) {
129+ return NULL ;
130+ }
131+
132+ gptp_hdr = (struct gptp_hdr * )(msg_start +
133+ sizeof (struct net_eth_hdr ));
134+ }
135+
136+ return gptp_hdr ;
137+ }
138+
139+ static void update_pkt_priority (struct gptp_hdr * hdr , struct net_pkt * pkt )
140+ {
141+ switch (hdr -> message_type ) {
142+ case GPTP_SYNC_MESSAGE :
143+ case GPTP_DELAY_REQ_MESSAGE :
144+ case GPTP_PATH_DELAY_REQ_MESSAGE :
145+ case GPTP_PATH_DELAY_RESP_MESSAGE :
146+ net_pkt_set_priority (pkt , NET_PRIORITY_CA );
147+ break ;
148+ default :
149+ net_pkt_set_priority (pkt , NET_PRIORITY_IC );
150+ break ;
151+ }
152+ }
153+
154+ static void update_gptp (struct net_if * iface , struct net_pkt * pkt ,
155+ bool send )
156+ {
157+ struct net_ptp_time timestamp ;
158+ struct gptp_hdr * hdr ;
159+ int ret ;
160+
161+ ret = eth_clock_gettime (& timestamp );
162+ if (ret < 0 ) {
163+ return ;
164+ }
165+
166+ net_pkt_set_timestamp (pkt , & timestamp );
167+
168+ hdr = check_gptp_msg (iface , pkt );
169+ if (!hdr ) {
170+ return ;
171+ }
172+
173+ if (send ) {
174+ ret = need_timestamping (hdr );
175+ if (ret ) {
176+ net_if_add_tx_timestamp (pkt );
177+ }
178+ } else {
179+ update_pkt_priority (hdr , pkt );
180+ }
181+ }
182+ #else
183+ #define update_gptp (iface , pkt , send )
184+ #endif /* CONFIG_NET_GPTP */
185+
80186static int eth_send (struct net_if * iface , struct net_pkt * pkt )
81187{
82188 struct eth_context * ctx = get_context (iface );
@@ -110,6 +216,8 @@ static int eth_send(struct net_if *iface, struct net_pkt *pkt)
110216 }
111217 }
112218
219+ update_gptp (iface , pkt , true);
220+
113221 SYS_LOG_DBG ("Send pkt %p len %d" , pkt , count );
114222
115223 eth_write_data (ctx -> dev_fd , ctx -> send , count );
@@ -200,6 +308,15 @@ static int read_data(struct eth_context *ctx, int fd)
200308 net_pkt_set_vlan_tci (pkt , ntohs (hdr_vlan -> vlan .tci ));
201309 vlan_tag = net_pkt_vlan_tag (pkt );
202310 }
311+
312+ #if CONFIG_NET_TC_RX_COUNT > 1
313+ {
314+ enum net_priority prio ;
315+
316+ prio = net_vlan2priority (net_pkt_vlan_priority (pkt ));
317+ net_pkt_set_priority (pkt , prio );
318+ }
319+ #endif
203320 }
204321#endif
205322
@@ -222,6 +339,8 @@ static int read_data(struct eth_context *ctx, int fd)
222339
223340 SYS_LOG_DBG ("Recv pkt %p len %d" , pkt , pkt_len );
224341
342+ update_gptp (iface , pkt , false);
343+
225344 if (net_recv_data (iface , pkt ) < 0 ) {
226345 net_pkt_unref (pkt );
227346 }
@@ -365,3 +484,60 @@ ETH_NET_DEVICE_INIT(eth_native_posix, CONFIG_ETH_NATIVE_POSIX_DRV_NAME,
365484 eth_init , & eth_context_data , NULL ,
366485 CONFIG_KERNEL_INIT_PRIORITY_DEFAULT , & eth_if_api ,
367486 _ETH_MTU );
487+
488+ #if defined(CONFIG_ETH_NATIVE_POSIX_PTP_CLOCK )
489+ static int ptp_clock_set_native_posix (struct ptp_clock * clk ,
490+ struct net_ptp_time * tm )
491+ {
492+ ARG_UNUSED (clk );
493+ ARG_UNUSED (tm );
494+
495+ /* We cannot set the host device time so this function
496+ * does nothing.
497+ */
498+
499+ return 0 ;
500+ }
501+
502+ static int ptp_clock_get_native_posix (struct ptp_clock * clk ,
503+ struct net_ptp_time * tm )
504+ {
505+ return eth_clock_gettime (tm );
506+ }
507+
508+ static int ptp_clock_adjust_native_posix (struct ptp_clock * clk ,
509+ int increment )
510+ {
511+ ARG_UNUSED (clk );
512+ ARG_UNUSED (increment );
513+
514+ /* We cannot adjust the host device time so this function
515+ * does nothing.
516+ */
517+
518+ return 0 ;
519+ }
520+
521+ static int ptp_clock_rate_adjust_native_posix (struct ptp_clock * clk ,
522+ float ratio )
523+ {
524+ ARG_UNUSED (clk );
525+ ARG_UNUSED (ratio );
526+
527+ /* We cannot adjust the host device time so this function
528+ * does nothing.
529+ */
530+
531+ return 0 ;
532+ }
533+
534+ static const struct ptp_clock_driver_api api = {
535+ .set = ptp_clock_set_native_posix ,
536+ .get = ptp_clock_get_native_posix ,
537+ .adjust = ptp_clock_adjust_native_posix ,
538+ .rate_adjust = ptp_clock_rate_adjust_native_posix ,
539+ };
540+
541+ PTP_CLOCK_DEVICE_INIT (eth_native_posix , api );
542+
543+ #endif /* CONFIG_ETH_NATIVE_POSIX_PTP_CLOCK */
0 commit comments