#define CAN_TERMINATION_OHM_VALUE 120
int can_set_netlink_message(Link *link, sd_netlink_message *m) {
- struct can_ctrlmode cm = {};
int r;
assert(link);
return log_link_debug_errno(link, r, "Could not append IFLA_CAN_RESTART_MS attribute: %m");
}
- if (link->network->can_fd_mode >= 0) {
- cm.mask |= CAN_CTRLMODE_FD;
- SET_FLAG(cm.flags, CAN_CTRLMODE_FD, link->network->can_fd_mode);
- log_link_debug(link, "Setting FD mode to '%s'.", yes_no(link->network->can_fd_mode));
- }
-
- if (link->network->can_non_iso >= 0) {
- cm.mask |= CAN_CTRLMODE_FD_NON_ISO;
- SET_FLAG(cm.flags, CAN_CTRLMODE_FD_NON_ISO, link->network->can_non_iso);
- log_link_debug(link, "Setting FD non-ISO mode to '%s'.", yes_no(link->network->can_non_iso));
- }
-
- if (link->network->can_triple_sampling >= 0) {
- cm.mask |= CAN_CTRLMODE_3_SAMPLES;
- SET_FLAG(cm.flags, CAN_CTRLMODE_3_SAMPLES, link->network->can_triple_sampling);
- log_link_debug(link, "Setting triple-sampling to '%s'.", yes_no(link->network->can_triple_sampling));
- }
-
- if (link->network->can_berr_reporting >= 0) {
- cm.mask |= CAN_CTRLMODE_BERR_REPORTING;
- SET_FLAG(cm.flags, CAN_CTRLMODE_BERR_REPORTING, link->network->can_berr_reporting);
- log_link_debug(link, "Setting bus error reporting to '%s'.", yes_no(link->network->can_berr_reporting));
- }
-
- if (link->network->can_listen_only >= 0) {
- cm.mask |= CAN_CTRLMODE_LISTENONLY;
- SET_FLAG(cm.flags, CAN_CTRLMODE_LISTENONLY, link->network->can_listen_only);
- log_link_debug(link, "Setting listen-only mode to '%s'.", yes_no(link->network->can_listen_only));
- }
+ if (link->network->can_control_mode_mask != 0) {
+ struct can_ctrlmode cm = {
+ .mask = link->network->can_control_mode_mask,
+ .flags = link->network->can_control_mode_flags,
+ };
- if (cm.mask != 0) {
r = sd_netlink_message_append_data(m, IFLA_CAN_CTRLMODE, &cm, sizeof(cm));
if (r < 0)
return log_link_debug_errno(link, r, "Could not append IFLA_CAN_CTRLMODE attribute: %m");
*restart_usec = usec;
return 0;
}
+
+int config_parse_can_control_mode(
+ 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) {
+
+ Network *network = userdata;
+ uint32_t mask = ltype;
+ int r;
+
+ assert(filename);
+ assert(lvalue);
+ assert(rvalue);
+ assert(userdata);
+ assert(mask != 0);
+
+ if (isempty(rvalue)) {
+ network->can_control_mode_mask &= ~mask;
+ network->can_control_mode_flags &= ~mask;
+ return 0;
+ }
+
+ r = parse_boolean(rvalue);
+ if (r < 0) {
+ log_syntax(unit, LOG_WARNING, filename, line, r,
+ "Failed to parse CAN control mode '%s', ignoring: %s", lvalue, rvalue);
+ return 0;
+ }
+
+ network->can_control_mode_mask |= mask;
+ SET_FLAG(network->can_control_mode_flags, mask, r);
+ return 0;
+}
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
+#include <linux/can/netlink.h>
+
#include "sd-netlink.h"
#include "conf-parser.h"
CONFIG_PARSER_PROTOTYPE(config_parse_can_bitrate);
CONFIG_PARSER_PROTOTYPE(config_parse_can_restart_usec);
+CONFIG_PARSER_PROTOTYPE(config_parse_can_control_mode);
CAN.SamplePoint, config_parse_permille, 0, offsetof(Network, can_sample_point)
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.FDMode, config_parse_tristate, 0, offsetof(Network, can_fd_mode)
-CAN.FDNonISO, config_parse_tristate, 0, offsetof(Network, can_non_iso)
CAN.RestartSec, config_parse_can_restart_usec, 0, offsetof(Network, can_restart_us)
-CAN.TripleSampling, config_parse_tristate, 0, offsetof(Network, can_triple_sampling)
-CAN.BusErrorReporting, config_parse_tristate, 0, offsetof(Network, can_berr_reporting)
+CAN.ListenOnly, config_parse_can_control_mode, CAN_CTRLMODE_LISTENONLY, 0
+CAN.TripleSampling, config_parse_can_control_mode, CAN_CTRLMODE_3_SAMPLES, 0
+CAN.BusErrorReporting, config_parse_can_control_mode, CAN_CTRLMODE_BERR_REPORTING, 0
+CAN.FDMode, config_parse_can_control_mode, CAN_CTRLMODE_FD, 0
+CAN.FDNonISO, config_parse_can_control_mode, CAN_CTRLMODE_FD_NON_ISO, 0
CAN.Termination, config_parse_tristate, 0, offsetof(Network, can_termination)
-CAN.ListenOnly, config_parse_tristate, 0, offsetof(Network, can_listen_only)
QDisc.Parent, config_parse_qdisc_parent, _QDISC_KIND_INVALID, 0
QDisc.Handle, config_parse_qdisc_handle, _QDISC_KIND_INVALID, 0
BFIFO.Parent, config_parse_qdisc_parent, QDISC_KIND_BFIFO, 0
.ipv6_accept_ra_route_metric = DHCP_ROUTE_METRIC,
.ipv6_accept_ra_start_dhcp6_client = IPV6_ACCEPT_RA_START_DHCP6_CLIENT_YES,
- .can_triple_sampling = -1,
- .can_berr_reporting = -1,
.can_termination = -1,
- .can_listen_only = -1,
- .can_fd_mode = -1,
- .can_non_iso = -1,
};
r = config_parse_many(
uint32_t can_data_bitrate;
unsigned can_data_sample_point;
usec_t can_restart_us;
- int can_triple_sampling;
- int can_berr_reporting;
+ uint32_t can_control_mode_mask;
+ uint32_t can_control_mode_flags;
int can_termination;
- int can_listen_only;
- int can_fd_mode;
- int can_non_iso;
/* sysctl settings */
AddressFamily ip_forward;