diff options
-rw-r--r-- | man/systemd.network.xml | 34 | ||||
-rw-r--r-- | src/network/networkd-can.c | 66 | ||||
-rw-r--r-- | src/network/networkd-can.h | 1 | ||||
-rw-r--r-- | src/network/networkd-network-gperf.gperf | 10 | ||||
-rw-r--r-- | src/network/networkd-network.h | 10 | ||||
-rw-r--r-- | test/fuzz/fuzz-network-parser/directives.network | 10 |
6 files changed, 130 insertions, 1 deletions
diff --git a/man/systemd.network.xml b/man/systemd.network.xml index c28cbed74f..fc127b1dba 100644 --- a/man/systemd.network.xml +++ b/man/systemd.network.xml @@ -2962,6 +2962,25 @@ IPv6Token=prefixstable:2002:da8:1::</programlisting></para> </listitem> </varlistentry> <varlistentry> + <term><varname>TimeQuantaNSec=</varname></term> + <term><varname>PropagationSegment=</varname></term> + <term><varname>PhaseBufferSegment1=</varname></term> + <term><varname>PhaseBufferSegment2=</varname></term> + <term><varname>SyncJumpWidth=</varname></term> + <listitem> + <para>Specifies the time quanta, propagation segment, phase buffer segment 1 and 2, and the + synchronization jump width, which allow to define the CAN bit-timing in a hardware + independent format as proposed by the Bosch CAN 2.0 Specification. + <varname>TimeQuantaNSec=</varname> takes a timespan in nanoseconds. + <varname>PropagationSegment=</varname>, <varname>PhaseBufferSegment1=</varname>, + <varname>PhaseBufferSegment2=</varname>, and <varname>SyncJumpWidth=</varname> take number + of time quantum specified in <varname>TimeQuantaNSec=</varname> and must be an unsigned + integer in the range 0…4294967295. These settings except for + <varname>SyncJumpWidth=</varname> will be ignored when <varname>BitRate=</varname> is + specified.</para> + </listitem> + </varlistentry> + <varlistentry> <term><varname>DataBitRate=</varname></term> <term><varname>DataSamplePoint=</varname></term> <listitem> @@ -2970,11 +2989,24 @@ IPv6Token=prefixstable:2002:da8:1::</programlisting></para> </listitem> </varlistentry> <varlistentry> + <term><varname>DataTimeQuantaNSec=</varname></term> + <term><varname>DataPropagationSegment=</varname></term> + <term><varname>DataPhaseBufferSegment1=</varname></term> + <term><varname>DataPhaseBufferSegment2=</varname></term> + <term><varname>DataSyncJumpWidth=</varname></term> + <listitem> + <para>Specifies the time quanta, propagation segment, phase buffer segment 1 and 2, and the + synchronization jump width for the data phase, if CAN-FD is used. These settings are + analogous to the <varname>TimeQuantaNSec=</varname> or related settings.</para> + </listitem> + </varlistentry> + <varlistentry> <term><varname>FDMode=</varname></term> <listitem> <para>Takes a boolean. When <literal>yes</literal>, CAN-FD mode is enabled for the interface. Note, that a bitrate and optional sample point should also be set for the CAN-FD data phase using - the <varname>DataBitRate=</varname> and <varname>DataSamplePoint=</varname> keys.</para> + the <varname>DataBitRate=</varname> and <varname>DataSamplePoint=</varname> keys, or + <varname>DataTimeQuanta=</varname> and related settings.</para> </listitem> </varlistentry> <varlistentry> diff --git a/src/network/networkd-can.c b/src/network/networkd-can.c index c4c71b8285..7a0a6e5522 100644 --- a/src/network/networkd-can.c +++ b/src/network/networkd-can.c @@ -35,6 +35,7 @@ int can_set_netlink_message(Link *link, sd_netlink_message *m) { struct can_bittiming bt = { .bitrate = link->network->can_bitrate, .sample_point = link->network->can_sample_point, + .sjw = link->network->can_sync_jump_width, }; log_link_debug(link, "Setting bitrate = %d bit/s", bt.bitrate); @@ -46,12 +47,26 @@ int can_set_netlink_message(Link *link, sd_netlink_message *m) { r = sd_netlink_message_append_data(m, IFLA_CAN_BITTIMING, &bt, sizeof(bt)); if (r < 0) return log_link_debug_errno(link, r, "Could not append IFLA_CAN_BITTIMING attribute: %m"); + } else if (link->network->can_time_quanta_ns > 0) { + struct can_bittiming bt = { + .tq = link->network->can_time_quanta_ns, + .prop_seg = link->network->can_propagation_segment, + .phase_seg1 = link->network->can_phase_buffer_segment_1, + .phase_seg2 = link->network->can_phase_buffer_segment_2, + .sjw = link->network->can_sync_jump_width, + }; + + log_link_debug(link, "Setting time quanta = %"PRIu32" nsec", bt.tq); + r = sd_netlink_message_append_data(m, IFLA_CAN_BITTIMING, &bt, sizeof(bt)); + if (r < 0) + return log_link_debug_errno(link, r, "Could not append IFLA_CAN_BITTIMING attribute: %m"); } if (link->network->can_data_bitrate > 0) { struct can_bittiming bt = { .bitrate = link->network->can_data_bitrate, .sample_point = link->network->can_data_sample_point, + .sjw = link->network->can_data_sync_jump_width, }; log_link_debug(link, "Setting data bitrate = %d bit/s", bt.bitrate); @@ -63,6 +78,19 @@ int can_set_netlink_message(Link *link, sd_netlink_message *m) { r = sd_netlink_message_append_data(m, IFLA_CAN_DATA_BITTIMING, &bt, sizeof(bt)); if (r < 0) return log_link_debug_errno(link, r, "Could not append IFLA_CAN_DATA_BITTIMING attribute: %m"); + } else if (link->network->can_data_time_quanta_ns > 0) { + struct can_bittiming bt = { + .tq = link->network->can_data_time_quanta_ns, + .prop_seg = link->network->can_data_propagation_segment, + .phase_seg1 = link->network->can_data_phase_buffer_segment_1, + .phase_seg2 = link->network->can_data_phase_buffer_segment_2, + .sjw = link->network->can_data_sync_jump_width, + }; + + log_link_debug(link, "Setting data time quanta = %"PRIu32" nsec", bt.tq); + r = sd_netlink_message_append_data(m, IFLA_CAN_DATA_BITTIMING, &bt, sizeof(bt)); + if (r < 0) + return log_link_debug_errno(link, r, "Could not append IFLA_CAN_DATA_BITTIMING attribute: %m"); } if (link->network->can_restart_us > 0) { @@ -149,6 +177,44 @@ int config_parse_can_bitrate( return 0; } +int config_parse_can_time_quanta( + const char* unit, + const char *filename, + unsigned line, + const char *section, + unsigned section_line, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + nsec_t val, *tq = data; + int r; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + r = parse_nsec(rvalue, &val); + if (r < 0) { + log_syntax(unit, LOG_WARNING, filename, line, r, + "Failed to parse can time quanta '%s', ignoring: %m", rvalue); + return 0; + } + + /* Linux uses __u32 for bitrates, so the value should not exceed that. */ + if (val <= 0 || val > UINT32_MAX) { + log_syntax(unit, LOG_WARNING, filename, line, 0, + "Time quanta out of permitted range 1...4294967295"); + return 0; + } + + *tq = val; + return 0; +} + int config_parse_can_restart_usec( const char* unit, const char *filename, diff --git a/src/network/networkd-can.h b/src/network/networkd-can.h index ff1a014a15..3945082498 100644 --- a/src/network/networkd-can.h +++ b/src/network/networkd-can.h @@ -12,6 +12,7 @@ typedef struct Link Link; int can_set_netlink_message(Link *link, sd_netlink_message *m); CONFIG_PARSER_PROTOTYPE(config_parse_can_bitrate); +CONFIG_PARSER_PROTOTYPE(config_parse_can_time_quanta); CONFIG_PARSER_PROTOTYPE(config_parse_can_restart_usec); CONFIG_PARSER_PROTOTYPE(config_parse_can_control_mode); CONFIG_PARSER_PROTOTYPE(config_parse_can_termination); diff --git a/src/network/networkd-network-gperf.gperf b/src/network/networkd-network-gperf.gperf index 077779cc6b..580347363d 100644 --- a/src/network/networkd-network-gperf.gperf +++ b/src/network/networkd-network-gperf.gperf @@ -346,8 +346,18 @@ IPv6RoutePrefix.LifetimeSec, config_parse_route_prefix_lifetime, LLDP.MUDURL, config_parse_mud_url, 0, offsetof(Network, lldp_mud) CAN.BitRate, config_parse_can_bitrate, 0, offsetof(Network, can_bitrate) CAN.SamplePoint, config_parse_permille, 0, offsetof(Network, can_sample_point) +CAN.TimeQuantaNSec, config_parse_can_time_quanta, 0, offsetof(Network, can_time_quanta_ns) +CAN.PropagationSegment, config_parse_uint32, 0, offsetof(Network, can_propagation_segment) +CAN.PhaseBufferSegment1, config_parse_uint32, 0, offsetof(Network, can_phase_buffer_segment_1) +CAN.PhaseBufferSegment2, config_parse_uint32, 0, offsetof(Network, can_phase_buffer_segment_2) +CAN.SyncJumpWidth, config_parse_uint32, 0, offsetof(Network, can_sync_jump_width) CAN.DataBitRate, config_parse_can_bitrate, 0, offsetof(Network, can_data_bitrate) CAN.DataSamplePoint, config_parse_permille, 0, offsetof(Network, can_data_sample_point) +CAN.DataTimeQuantaNSec, config_parse_can_time_quanta, 0, offsetof(Network, can_data_time_quanta_ns) +CAN.DataPropagationSegment, config_parse_uint32, 0, offsetof(Network, can_data_propagation_segment) +CAN.DataPhaseBufferSegment1, config_parse_uint32, 0, offsetof(Network, can_data_phase_buffer_segment_1) +CAN.DataPhaseBufferSegment2, config_parse_uint32, 0, offsetof(Network, can_data_phase_buffer_segment_2) +CAN.DataSyncJumpWidth, config_parse_uint32, 0, offsetof(Network, can_data_sync_jump_width) CAN.RestartSec, config_parse_can_restart_usec, 0, offsetof(Network, can_restart_us) CAN.Loopback, config_parse_can_control_mode, CAN_CTRLMODE_LOOPBACK, 0 CAN.ListenOnly, config_parse_can_control_mode, CAN_CTRLMODE_LISTENONLY, 0 diff --git a/src/network/networkd-network.h b/src/network/networkd-network.h index 488d49e3ac..4410683b4a 100644 --- a/src/network/networkd-network.h +++ b/src/network/networkd-network.h @@ -265,8 +265,18 @@ struct Network { /* CAN support */ uint32_t can_bitrate; unsigned can_sample_point; + nsec_t can_time_quanta_ns; + uint32_t can_propagation_segment; + uint32_t can_phase_buffer_segment_1; + uint32_t can_phase_buffer_segment_2; + uint32_t can_sync_jump_width; uint32_t can_data_bitrate; unsigned can_data_sample_point; + nsec_t can_data_time_quanta_ns; + uint32_t can_data_propagation_segment; + uint32_t can_data_phase_buffer_segment_1; + uint32_t can_data_phase_buffer_segment_2; + uint32_t can_data_sync_jump_width; usec_t can_restart_us; uint32_t can_control_mode_mask; uint32_t can_control_mode_flags; diff --git a/test/fuzz/fuzz-network-parser/directives.network b/test/fuzz/fuzz-network-parser/directives.network index 2f96bb8db9..eb7e699bd3 100644 --- a/test/fuzz/fuzz-network-parser/directives.network +++ b/test/fuzz/fuzz-network-parser/directives.network @@ -257,8 +257,18 @@ MUDURL= [CAN] SamplePoint= BitRate= +TimeQuantaNSec= +PropagationSegment= +PhaseBufferSegment1= +PhaseBufferSegment2= +SyncJumpWidth= DataSamplePoint= DataBitRate= +DataTimeQuantaNSec= +DataPropagationSegment= +DataPhaseBufferSegment1= +DataPhaseBufferSegment2= +DataSyncJumpWidth= FDMode= FDNonISO= RestartSec= |