mirror of
https://github.com/Dasharo/systemd.git
synced 2026-03-06 15:02:31 -08:00
network: can: allow to specify bit-timing with TimeQuantaNSec= and friends
Closes #19424 and #20435.
This commit is contained in:
@@ -2961,6 +2961,25 @@ IPv6Token=prefixstable:2002:da8:1::</programlisting></para>
|
||||
<varname>BitRate=</varname> is unspecified.</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>
|
||||
@@ -2969,12 +2988,25 @@ IPv6Token=prefixstable:2002:da8:1::</programlisting></para>
|
||||
analogous to the <varname>BitRate=</varname> and <varname>SamplePoint=</varname> keys.</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>
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -257,8 +257,18 @@ MUDURL=
|
||||
[CAN]
|
||||
SamplePoint=
|
||||
BitRate=
|
||||
TimeQuantaNSec=
|
||||
PropagationSegment=
|
||||
PhaseBufferSegment1=
|
||||
PhaseBufferSegment2=
|
||||
SyncJumpWidth=
|
||||
DataSamplePoint=
|
||||
DataBitRate=
|
||||
DataTimeQuantaNSec=
|
||||
DataPropagationSegment=
|
||||
DataPhaseBufferSegment1=
|
||||
DataPhaseBufferSegment2=
|
||||
DataSyncJumpWidth=
|
||||
FDMode=
|
||||
FDNonISO=
|
||||
RestartSec=
|
||||
|
||||
Reference in New Issue
Block a user