@@ -12,39 +12,82 @@ LOG_MODULE_REGISTER(net_dsa_tag_netc, CONFIG_NET_DSA_LOG_LEVEL);
1212#include <zephyr/net/dsa_tag_netc.h>
1313#include "fsl_netc_tag.h"
1414
15- /* tag is inserted after DMAC/SMAC fields */
16- struct dsa_tag_netc_to_host_header {
17- uint8_t dmac [NET_ETH_ADDR_LEN ];
18- uint8_t smac [NET_ETH_ADDR_LEN ];
19- netc_swt_tag_host_t tag ;
20- };
21-
22- struct dsa_tag_netc_to_port_header {
23- uint8_t dmac [NET_ETH_ADDR_LEN ];
24- uint8_t smac [NET_ETH_ADDR_LEN ];
25- netc_swt_tag_port_no_ts_t tag ;
26- };
27-
2815struct net_if * dsa_tag_netc_recv (struct net_if * iface , struct net_pkt * pkt )
2916{
3017 struct ethernet_context * eth_ctx = net_if_l2_data (iface );
31- struct dsa_switch_context * dsa_switch_ctx = eth_ctx -> dsa_switch_ctx ;
32- uint16_t header_len = sizeof (struct dsa_tag_netc_to_host_header );
33- struct dsa_tag_netc_to_host_header * header ;
18+ const struct dsa_switch_context * dsa_switch_ctx = eth_ctx -> dsa_switch_ctx ;
19+ #ifdef CONFIG_NET_L2_PTP
20+ struct dsa_tag_netc_data * tagger_data =
21+ (struct dsa_tag_netc_data * )(dsa_switch_ctx -> tagger_data );
22+ #endif
23+ void * header = pkt -> frags -> data ;
24+ uint16_t tag_len = sizeof (netc_swt_tag_host_t );
25+ netc_swt_tag_common_t * tag_common ;
3426 struct net_if * iface_dst = iface ;
3527 uint8_t * ptr ;
3628
37- if (pkt -> frags -> len < header_len ) {
29+ /* Tag is inserted after DMAC/SMAC fields. Check the smallest tag type header size. */
30+ if (pkt -> frags -> len < NET_ETH_ADDR_LEN * 2 + tag_len ) {
3831 LOG_ERR ("tag len error" );
3932 return iface_dst ;
4033 }
4134
35+ /* Handle tag type */
36+ tag_common = (netc_swt_tag_common_t * )((uintptr_t )pkt -> frags -> data + NET_ETH_ADDR_LEN * 2 );
37+ if (tag_common -> type == kNETC_TagForward ) {
38+
39+ /* Update tag length per tag type */
40+ tag_len = sizeof (netc_swt_tag_forward_t );
41+
42+ } else if (tag_common -> type == kNETC_TagToHost ) {
43+ #ifdef CONFIG_NET_L2_PTP
44+ netc_swt_tag_host_rx_ts_t * tag_rx_ts ;
45+ netc_swt_tag_host_tx_ts_t * tag_tx_ts ;
46+ uint64_t ts ;
47+ #endif
48+ /* Handle tag sub-type */
49+ switch (tag_common -> subType ) {
50+ case kNETC_TagToHostNoTs :
51+ /* Normal case */
52+ break ;
53+ case kNETC_TagToHostRxTs :
54+ #ifdef CONFIG_NET_L2_PTP
55+ tag_rx_ts = (netc_swt_tag_host_rx_ts_t * )tag_common ;
56+ ts = ntohll (tag_rx_ts -> timestamp );
57+
58+ /* Fill timestamp */
59+ pkt -> timestamp .nanosecond = ts % NSEC_PER_SEC ;
60+ pkt -> timestamp .second = ts / NSEC_PER_SEC ;
61+ #endif
62+ /* Update tag length per tag type */
63+ tag_len = sizeof (netc_swt_tag_host_rx_ts_t );
64+ break ;
65+ case kNETC_TagToHostTxTs :
66+ #ifdef CONFIG_NET_L2_PTP
67+ tag_tx_ts = (netc_swt_tag_host_tx_ts_t * )tag_common ;
68+ ts = ntohll (tag_tx_ts -> timestamp );
69+
70+ if (tagger_data -> twostep_timestamp_handler != NULL ) {
71+ tagger_data -> twostep_timestamp_handler (dsa_switch_ctx ,
72+ tag_tx_ts -> tsReqId , ts );
73+ }
74+ #endif
75+ /* Update tag length per tag type */
76+ tag_len = sizeof (netc_swt_tag_host_tx_ts_t );
77+ break ;
78+ default :
79+ LOG_ERR ("tag sub-type error" );
80+ break ;
81+ }
82+ } else {
83+ LOG_ERR ("tag type error" );
84+ }
85+
4286 /* redirect to user port */
43- header = (struct dsa_tag_netc_to_host_header * )pkt -> frags -> data ;
44- iface_dst = dsa_switch_ctx -> iface_user [header -> tag .comTag .port ];
87+ iface_dst = dsa_switch_ctx -> iface_user [tag_common -> port ];
4588
4689 /* drop tag */
47- ptr = net_buf_pull (pkt -> frags , sizeof ( netc_swt_tag_host_t ) );
90+ ptr = net_buf_pull (pkt -> frags , tag_len );
4891 for (int i = 0 ; i < (NET_ETH_ADDR_LEN * 2 ); i ++ ) {
4992 ptr [i ] = * (uint8_t * )((uintptr_t )header + i );
5093 }
@@ -56,27 +99,53 @@ struct net_pkt *dsa_tag_netc_xmit(struct net_if *iface, struct net_pkt *pkt)
5699{
57100 const struct device * dev = net_if_get_device (iface );
58101 struct dsa_port_config * cfg = (struct dsa_port_config * )dev -> config ;
59- struct dsa_tag_netc_to_port_header * header ;
60102 struct net_buf * header_buf ;
103+ size_t header_len = NET_ETH_ADDR_LEN * 2 ;
104+ netc_swt_tag_common_t * tag_common ;
105+ void * tag ;
106+
107+ /* Tag is inserted after DMAC/SMAC fields. Decide header size per tag type. */
108+ if (ntohs (NET_ETH_HDR (pkt )-> type ) == NET_ETH_PTYPE_PTP ) {
109+ header_len += sizeof (netc_swt_tag_port_two_step_ts_t );
110+ } else {
111+ header_len += sizeof (netc_swt_tag_port_no_ts_t );
112+ }
61113
62114 /* Allocate net_buf for header */
63115 header_buf = net_buf_alloc_len (net_buf_pool_get (pkt -> buffer -> pool_id ),
64- sizeof ( * header ) , K_NO_WAIT );
116+ header_len , K_NO_WAIT );
65117 if (!header_buf ) {
66118 LOG_ERR ("Cannot allocate header buffer" );
67119 return NULL ;
68120 }
69121
70- header_buf -> len = sizeof ( * header ) ;
122+ header_buf -> len = header_len ;
71123
72124 /* Fill the header */
73- header = (struct dsa_tag_netc_to_port_header * )header_buf -> data ;
74- memcpy (header , pkt -> frags -> data , NET_ETH_ADDR_LEN * 2 );
75- header -> tag .comTag .tpid = NETC_SWITCH_DEFAULT_ETHER_TYPE ;
76- header -> tag .comTag .subType = kNETC_TagToPortNoTs ;
77- header -> tag .comTag .type = kNETC_TagToPort ;
78- header -> tag .comTag .swtId = 1 ;
79- header -> tag .comTag .port = cfg -> port_idx ;
125+ memcpy (header_buf -> data , pkt -> frags -> data , NET_ETH_ADDR_LEN * 2 );
126+ tag = (void * )((uintptr_t )header_buf -> data + NET_ETH_ADDR_LEN * 2 );
127+
128+ #ifdef CONFIG_NET_L2_PTP
129+ /* Enable two-step timestamping for gPTP. */
130+ if (ntohs (NET_ETH_HDR (pkt )-> type ) == NET_ETH_PTYPE_PTP ) {
131+
132+ /* Utilize control block for timestamp request ID */
133+ ((netc_swt_tag_port_two_step_ts_t * )tag )-> tsReqId = pkt -> cb .cb [0 ] & 0xf ;
134+
135+ tag_common = & ((netc_swt_tag_port_two_step_ts_t * )tag )-> comTag ;
136+ tag_common -> subType = kNETC_TagToPortTwoStepTs ;
137+ } else {
138+ tag_common = & ((netc_swt_tag_port_no_ts_t * )tag )-> comTag ;
139+ tag_common -> subType = kNETC_TagToPortNoTs ;
140+ }
141+ #else
142+ tag_common = & ((netc_swt_tag_port_no_ts_t * )tag )-> comTag ;
143+ tag_common -> subType = kNETC_TagToPortNoTs ;
144+ #endif
145+ tag_common -> tpid = NETC_SWITCH_DEFAULT_ETHER_TYPE ;
146+ tag_common -> type = kNETC_TagToPort ;
147+ tag_common -> swtId = 1 ;
148+ tag_common -> port = cfg -> port_idx ;
80149
81150 /* Drop DMAC/SMAC on original frag */
82151 net_buf_pull (pkt -> frags , NET_ETH_ADDR_LEN * 2 );
0 commit comments