X Tutup
Skip to content

Commit b164b57

Browse files
committed
network: can: allow to specify bit-timing with TimeQuantaNSec= and friends
Closes systemd#19424 and systemd#20435.
1 parent 817561c commit b164b57

File tree

6 files changed

+130
-1
lines changed

6 files changed

+130
-1
lines changed

man/systemd.network.xml

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2961,6 +2961,25 @@ IPv6Token=prefixstable:2002:da8:1::</programlisting></para>
29612961
<varname>BitRate=</varname> is unspecified.</para>
29622962
</listitem>
29632963
</varlistentry>
2964+
<varlistentry>
2965+
<term><varname>TimeQuantaNSec=</varname></term>
2966+
<term><varname>PropagationSegment=</varname></term>
2967+
<term><varname>PhaseBufferSegment1=</varname></term>
2968+
<term><varname>PhaseBufferSegment2=</varname></term>
2969+
<term><varname>SyncJumpWidth=</varname></term>
2970+
<listitem>
2971+
<para>Specifies the time quanta, propagation segment, phase buffer segment 1 and 2, and the
2972+
synchronization jump width, which allow to define the CAN bit-timing in a hardware
2973+
independent format as proposed by the Bosch CAN 2.0 Specification.
2974+
<varname>TimeQuantaNSec=</varname> takes a timespan in nanoseconds.
2975+
<varname>PropagationSegment=</varname>, <varname>PhaseBufferSegment1=</varname>,
2976+
<varname>PhaseBufferSegment2=</varname>, and <varname>SyncJumpWidth=</varname> take number
2977+
of time quantum specified in <varname>TimeQuantaNSec=</varname> and must be an unsigned
2978+
integer in the range 0…4294967295. These settings except for
2979+
<varname>SyncJumpWidth=</varname> will be ignored when <varname>BitRate=</varname> is
2980+
specified.</para>
2981+
</listitem>
2982+
</varlistentry>
29642983
<varlistentry>
29652984
<term><varname>DataBitRate=</varname></term>
29662985
<term><varname>DataSamplePoint=</varname></term>
@@ -2969,12 +2988,25 @@ IPv6Token=prefixstable:2002:da8:1::</programlisting></para>
29692988
analogous to the <varname>BitRate=</varname> and <varname>SamplePoint=</varname> keys.</para>
29702989
</listitem>
29712990
</varlistentry>
2991+
<varlistentry>
2992+
<term><varname>DataTimeQuantaNSec=</varname></term>
2993+
<term><varname>DataPropagationSegment=</varname></term>
2994+
<term><varname>DataPhaseBufferSegment1=</varname></term>
2995+
<term><varname>DataPhaseBufferSegment2=</varname></term>
2996+
<term><varname>DataSyncJumpWidth=</varname></term>
2997+
<listitem>
2998+
<para>Specifies the time quanta, propagation segment, phase buffer segment 1 and 2, and the
2999+
synchronization jump width for the data phase, if CAN-FD is used. These settings are
3000+
analogous to the <varname>TimeQuantaNSec=</varname> or related settings.</para>
3001+
</listitem>
3002+
</varlistentry>
29723003
<varlistentry>
29733004
<term><varname>FDMode=</varname></term>
29743005
<listitem>
29753006
<para>Takes a boolean. When <literal>yes</literal>, CAN-FD mode is enabled for the interface.
29763007
Note, that a bitrate and optional sample point should also be set for the CAN-FD data phase using
2977-
the <varname>DataBitRate=</varname> and <varname>DataSamplePoint=</varname> keys.</para>
3008+
the <varname>DataBitRate=</varname> and <varname>DataSamplePoint=</varname> keys, or
3009+
<varname>DataTimeQuanta=</varname> and related settings.</para>
29783010
</listitem>
29793011
</varlistentry>
29803012
<varlistentry>

src/network/networkd-can.c

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ int can_set_netlink_message(Link *link, sd_netlink_message *m) {
3535
struct can_bittiming bt = {
3636
.bitrate = link->network->can_bitrate,
3737
.sample_point = link->network->can_sample_point,
38+
.sjw = link->network->can_sync_jump_width,
3839
};
3940

4041
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) {
4647
r = sd_netlink_message_append_data(m, IFLA_CAN_BITTIMING, &bt, sizeof(bt));
4748
if (r < 0)
4849
return log_link_debug_errno(link, r, "Could not append IFLA_CAN_BITTIMING attribute: %m");
50+
} else if (link->network->can_time_quanta_ns > 0) {
51+
struct can_bittiming bt = {
52+
.tq = link->network->can_time_quanta_ns,
53+
.prop_seg = link->network->can_propagation_segment,
54+
.phase_seg1 = link->network->can_phase_buffer_segment_1,
55+
.phase_seg2 = link->network->can_phase_buffer_segment_2,
56+
.sjw = link->network->can_sync_jump_width,
57+
};
58+
59+
log_link_debug(link, "Setting time quanta = %"PRIu32" nsec", bt.tq);
60+
r = sd_netlink_message_append_data(m, IFLA_CAN_BITTIMING, &bt, sizeof(bt));
61+
if (r < 0)
62+
return log_link_debug_errno(link, r, "Could not append IFLA_CAN_BITTIMING attribute: %m");
4963
}
5064

5165
if (link->network->can_data_bitrate > 0) {
5266
struct can_bittiming bt = {
5367
.bitrate = link->network->can_data_bitrate,
5468
.sample_point = link->network->can_data_sample_point,
69+
.sjw = link->network->can_data_sync_jump_width,
5570
};
5671

5772
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) {
6378
r = sd_netlink_message_append_data(m, IFLA_CAN_DATA_BITTIMING, &bt, sizeof(bt));
6479
if (r < 0)
6580
return log_link_debug_errno(link, r, "Could not append IFLA_CAN_DATA_BITTIMING attribute: %m");
81+
} else if (link->network->can_data_time_quanta_ns > 0) {
82+
struct can_bittiming bt = {
83+
.tq = link->network->can_data_time_quanta_ns,
84+
.prop_seg = link->network->can_data_propagation_segment,
85+
.phase_seg1 = link->network->can_data_phase_buffer_segment_1,
86+
.phase_seg2 = link->network->can_data_phase_buffer_segment_2,
87+
.sjw = link->network->can_data_sync_jump_width,
88+
};
89+
90+
log_link_debug(link, "Setting data time quanta = %"PRIu32" nsec", bt.tq);
91+
r = sd_netlink_message_append_data(m, IFLA_CAN_DATA_BITTIMING, &bt, sizeof(bt));
92+
if (r < 0)
93+
return log_link_debug_errno(link, r, "Could not append IFLA_CAN_DATA_BITTIMING attribute: %m");
6694
}
6795

6896
if (link->network->can_restart_us > 0) {
@@ -149,6 +177,44 @@ int config_parse_can_bitrate(
149177
return 0;
150178
}
151179

180+
int config_parse_can_time_quanta(
181+
const char* unit,
182+
const char *filename,
183+
unsigned line,
184+
const char *section,
185+
unsigned section_line,
186+
const char *lvalue,
187+
int ltype,
188+
const char *rvalue,
189+
void *data,
190+
void *userdata) {
191+
192+
nsec_t val, *tq = data;
193+
int r;
194+
195+
assert(filename);
196+
assert(lvalue);
197+
assert(rvalue);
198+
assert(data);
199+
200+
r = parse_nsec(rvalue, &val);
201+
if (r < 0) {
202+
log_syntax(unit, LOG_WARNING, filename, line, r,
203+
"Failed to parse can time quanta '%s', ignoring: %m", rvalue);
204+
return 0;
205+
}
206+
207+
/* Linux uses __u32 for bitrates, so the value should not exceed that. */
208+
if (val <= 0 || val > UINT32_MAX) {
209+
log_syntax(unit, LOG_WARNING, filename, line, 0,
210+
"Time quanta out of permitted range 1...4294967295");
211+
return 0;
212+
}
213+
214+
*tq = val;
215+
return 0;
216+
}
217+
152218
int config_parse_can_restart_usec(
153219
const char* unit,
154220
const char *filename,

src/network/networkd-can.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ typedef struct Link Link;
1212
int can_set_netlink_message(Link *link, sd_netlink_message *m);
1313

1414
CONFIG_PARSER_PROTOTYPE(config_parse_can_bitrate);
15+
CONFIG_PARSER_PROTOTYPE(config_parse_can_time_quanta);
1516
CONFIG_PARSER_PROTOTYPE(config_parse_can_restart_usec);
1617
CONFIG_PARSER_PROTOTYPE(config_parse_can_control_mode);
1718
CONFIG_PARSER_PROTOTYPE(config_parse_can_termination);

src/network/networkd-network-gperf.gperf

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -346,8 +346,18 @@ IPv6RoutePrefix.LifetimeSec, config_parse_route_prefix_lifetime,
346346
LLDP.MUDURL, config_parse_mud_url, 0, offsetof(Network, lldp_mud)
347347
CAN.BitRate, config_parse_can_bitrate, 0, offsetof(Network, can_bitrate)
348348
CAN.SamplePoint, config_parse_permille, 0, offsetof(Network, can_sample_point)
349+
CAN.TimeQuantaNSec, config_parse_can_time_quanta, 0, offsetof(Network, can_time_quanta_ns)
350+
CAN.PropagationSegment, config_parse_uint32, 0, offsetof(Network, can_propagation_segment)
351+
CAN.PhaseBufferSegment1, config_parse_uint32, 0, offsetof(Network, can_phase_buffer_segment_1)
352+
CAN.PhaseBufferSegment2, config_parse_uint32, 0, offsetof(Network, can_phase_buffer_segment_2)
353+
CAN.SyncJumpWidth, config_parse_uint32, 0, offsetof(Network, can_sync_jump_width)
349354
CAN.DataBitRate, config_parse_can_bitrate, 0, offsetof(Network, can_data_bitrate)
350355
CAN.DataSamplePoint, config_parse_permille, 0, offsetof(Network, can_data_sample_point)
356+
CAN.DataTimeQuantaNSec, config_parse_can_time_quanta, 0, offsetof(Network, can_data_time_quanta_ns)
357+
CAN.DataPropagationSegment, config_parse_uint32, 0, offsetof(Network, can_data_propagation_segment)
358+
CAN.DataPhaseBufferSegment1, config_parse_uint32, 0, offsetof(Network, can_data_phase_buffer_segment_1)
359+
CAN.DataPhaseBufferSegment2, config_parse_uint32, 0, offsetof(Network, can_data_phase_buffer_segment_2)
360+
CAN.DataSyncJumpWidth, config_parse_uint32, 0, offsetof(Network, can_data_sync_jump_width)
351361
CAN.RestartSec, config_parse_can_restart_usec, 0, offsetof(Network, can_restart_us)
352362
CAN.Loopback, config_parse_can_control_mode, CAN_CTRLMODE_LOOPBACK, 0
353363
CAN.ListenOnly, config_parse_can_control_mode, CAN_CTRLMODE_LISTENONLY, 0

src/network/networkd-network.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,8 +265,18 @@ struct Network {
265265
/* CAN support */
266266
uint32_t can_bitrate;
267267
unsigned can_sample_point;
268+
nsec_t can_time_quanta_ns;
269+
uint32_t can_propagation_segment;
270+
uint32_t can_phase_buffer_segment_1;
271+
uint32_t can_phase_buffer_segment_2;
272+
uint32_t can_sync_jump_width;
268273
uint32_t can_data_bitrate;
269274
unsigned can_data_sample_point;
275+
nsec_t can_data_time_quanta_ns;
276+
uint32_t can_data_propagation_segment;
277+
uint32_t can_data_phase_buffer_segment_1;
278+
uint32_t can_data_phase_buffer_segment_2;
279+
uint32_t can_data_sync_jump_width;
270280
usec_t can_restart_us;
271281
uint32_t can_control_mode_mask;
272282
uint32_t can_control_mode_flags;

test/fuzz/fuzz-network-parser/directives.network

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,8 +257,18 @@ MUDURL=
257257
[CAN]
258258
SamplePoint=
259259
BitRate=
260+
TimeQuantaNSec=
261+
PropagationSegment=
262+
PhaseBufferSegment1=
263+
PhaseBufferSegment2=
264+
SyncJumpWidth=
260265
DataSamplePoint=
261266
DataBitRate=
267+
DataTimeQuantaNSec=
268+
DataPropagationSegment=
269+
DataPhaseBufferSegment1=
270+
DataPhaseBufferSegment2=
271+
DataSyncJumpWidth=
262272
FDMode=
263273
FDNonISO=
264274
RestartSec=

0 commit comments

Comments
 (0)
X Tutup