@@ -25,6 +25,7 @@ static const char *instance_type_to_clock_type(const char *type)
2525 return "P2P_TC" ;
2626 if (!strcmp (type , "e2e-tc" ))
2727 return "E2E_TC" ;
28+
2829 return NULL ;
2930}
3031
@@ -101,32 +102,34 @@ static bool iface_has_hw_timestamp(json_t *root, const char *ifname)
101102 return false;
102103}
103104
105+ static uint16_t instance (struct lyd_node * inst )
106+ {
107+ return (uint16_t )atoi (lydx_get_cattr (inst , "instance-index" ));
108+ }
109+
104110/*
105111 * Scan all ports of inst and determine whether to use hardware or software
106112 * timestamping. Emits a syslog WARNING when falling back to software due
107113 * to a mixed or software-only set of port interfaces.
108114 */
109- static const char * instance_time_stamping (struct lyd_node * inst , json_t * root )
115+ static const char * instance_time_stamping (uint16_t idx , struct lyd_node * inst , json_t * root )
110116{
117+ const char * ifname = NULL ;
111118 struct lyd_node * port ;
112- bool any_sw = false;
113119
114120 LYX_LIST_FOR_EACH (lyd_child (lydx_get_child (inst , "ports" )), port , "port" ) {
115121 const char * iface = lydx_get_cattr (port , "underlying-interface" );
116122
117- if (!iface )
118- continue ;
119123 if (iface_has_hw_timestamp (root , iface ))
120124 continue ;
121125
122- any_sw = true ;
126+ ifname = iface ;
123127 break ;
124128 }
125129
126- if (any_sw ) {
127- WARN ("PTP instance has software-only timestamping port(s), "
128- "falling back to time_stamping software" );
129-
130+ if (ifname ) {
131+ WARN ("PTP instance %u will use software based timestamping due to "
132+ "missing hardware support on %s" , idx , ifname );
130133 return "software" ;
131134 }
132135
@@ -151,10 +154,7 @@ static int write_instance_conf(struct lyd_node *inst, json_t *root)
151154 uint16_t idx ;
152155 FILE * fp ;
153156
154- v = lydx_get_cattr (inst , "instance-index" );
155- if (!v )
156- return SR_ERR_INVAL_ARG ;
157- idx = (uint16_t )atoi (v );
157+ idx = instance (inst );
158158
159159 snprintf (path , sizeof (path ), PTP_CONF_DIR "/ptp4l-%u.conf+" , idx );
160160 fp = fopen (path , "w" );
@@ -178,7 +178,7 @@ static int write_instance_conf(struct lyd_node *inst, json_t *root)
178178 fprintf (fp , "uds_address /var/run/ptp4l-%u\n" , idx );
179179
180180 /* Timestamping mode: hardware if all ports support it, software otherwise */
181- ts = instance_time_stamping (inst , root );
181+ ts = instance_time_stamping (idx , inst , root );
182182 fprintf (fp , "time_stamping %s\n" , ts );
183183
184184 /* Profile — sets transportSpecific and all protocol-mandatory options */
@@ -200,10 +200,8 @@ static int write_instance_conf(struct lyd_node *inst, json_t *root)
200200 * boundary_clock_jbod silences ptp4l's startup PHC-mismatch check and
201201 * lets each port use its own PHC. It is a no-op when all ports share
202202 * the same PHC (single-chip board or software timestamping).
203- *
204- * NOTE: for BC on multi-chip hardware, ptp4l only disciplines the PHC
205- * of the active slave port; the other chips' PHCs will drift unless
206- * phc2sys(8) -a is also run. That is a separate service (TODO).
203+ * On multi-chip hardware, phc2sys -a disciplines the secondary PHCs;
204+ * see needs_phc2sys() / activate_phc2sys().
207205 */
208206 if (tc || bc )
209207 fprintf (fp , "boundary_clock_jbod 1\n" );
@@ -333,7 +331,7 @@ static bool needs_phc2sys(struct lyd_node *inst, json_t *root)
333331 if (strcmp (type , "bc" ) && strcmp (type , "p2p-tc" ) && strcmp (type , "e2e-tc" ))
334332 return false;
335333
336- return !strcmp (instance_time_stamping (inst , root ), "hardware" );
334+ return !strcmp (instance_time_stamping (instance ( inst ), inst , root ), "hardware" );
337335}
338336
339337/*
@@ -359,24 +357,23 @@ static void deactivate_phc2sys(uint16_t idx)
359357static void cleanup_stale_phc2sys (struct lyd_node * config )
360358{
361359 const struct dirent * ent ;
362- struct lyd_node * inst ;
363360 DIR * d ;
364- int idx ;
365361
366362 d = opendir (FINIT_RCSD "/enabled" );
367363 if (!d )
368364 return ;
369365
370366 while ((ent = readdir (d ))) {
367+ struct lyd_node * inst , * instances ;
371368 bool found = false;
369+ int idx ;
372370
373371 if (sscanf (ent -> d_name , "phc2sys@%d.conf" , & idx ) != 1 )
374372 continue ;
375373
376- LYX_LIST_FOR_EACH (lydx_get_descendant (config , "ptp" , "instances" , "instance" , NULL ),
377- inst , "instance" ) {
378- const char * v = lydx_get_cattr (inst , "instance-index" );
379- if (v && atoi (v ) == idx ) {
374+ instances = lydx_get_descendant (config , "ptp" , "instances" , "instance" , NULL );
375+ LYX_LIST_FOR_EACH (instances , inst , "instance" ) {
376+ if (instance (inst ) == idx ) {
380377 found = true;
381378 break ;
382379 }
@@ -445,25 +442,24 @@ static void deactivate_instance(uint16_t idx)
445442static void cleanup_stale_instances (struct lyd_node * config )
446443{
447444 const struct dirent * ent ;
448- struct lyd_node * inst ;
449- int idx ;
450445 DIR * d ;
451446
452447 d = opendir (FINIT_RCSD "/enabled" );
453448 if (!d )
454449 return ;
455450
456451 while ((ent = readdir (d ))) {
452+ struct lyd_node * inst , * instances ;
457453 bool found = false;
454+ int idx ;
458455
459456 if (sscanf (ent -> d_name , "ptp4l@%d.conf" , & idx ) != 1 )
460457 continue ;
461458
462459 /* Is this index still configured? */
463- LYX_LIST_FOR_EACH (lydx_get_descendant (config , "ptp" , "instances" , "instance" , NULL ),
464- inst , "instance" ) {
465- const char * v = lydx_get_cattr (inst , "instance-index" );
466- if (v && atoi (v ) == idx ) {
460+ instances = lydx_get_descendant (config , "ptp" , "instances" , "instance" , NULL );
461+ LYX_LIST_FOR_EACH (instances , inst , "instance" ) {
462+ if (instance (inst ) == idx ) {
467463 found = true;
468464 break ;
469465 }
@@ -493,23 +489,19 @@ static int change(sr_session_ctx_t *session, struct lyd_node *config,
493489 case SR_EV_ABORT :
494490 /* Remove any staging files */
495491 instances = lydx_get_descendant (config , "ptp" , "instances" , "instance" , NULL );
496- LYX_LIST_FOR_EACH (instances , inst , "instance" ) {
497- const char * v = lydx_get_cattr (inst , "instance-index" );
498- if (v )
499- remove_staging ((uint16_t )atoi (v ));
500- }
492+ LYX_LIST_FOR_EACH (instances , inst , "instance" )
493+ remove_staging (instance (inst ));
501494 return SR_ERR_OK ;
502495
503496 case SR_EV_DONE :
504497 /* Activate all configured instances */
505498 instances = lydx_get_descendant (config , "ptp" , "instances" , "instance" , NULL );
506499 LYX_LIST_FOR_EACH (instances , inst , "instance" ) {
507- const char * v = lydx_get_cattr (inst , "instance-index" );
508- if (!v )
509- continue ;
510- uint16_t idx = (uint16_t )atoi (v );
500+ uint16_t idx = instance (inst );
501+
511502 if ((rc = activate_instance (idx )))
512503 return rc ;
504+
513505 if (needs_phc2sys (inst , confd -> root ))
514506 activate_phc2sys (idx );
515507 else
@@ -519,10 +511,6 @@ static int change(sr_session_ctx_t *session, struct lyd_node *config,
519511 /* Disable stale services not in current config */
520512 cleanup_stale_instances (config );
521513 cleanup_stale_phc2sys (config );
522-
523- if (!instances )
524- return SR_ERR_OK ;
525-
526514 return SR_ERR_OK ;
527515
528516 default :
0 commit comments