summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--man/systemd.network.xml34
-rw-r--r--src/network/networkd-can.c66
-rw-r--r--src/network/networkd-can.h1
-rw-r--r--src/network/networkd-network-gperf.gperf10
-rw-r--r--src/network/networkd-network.h10
-rw-r--r--test/fuzz/fuzz-network-parser/directives.network10
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=