25 #include <netlink-private/netlink.h>
26 #include <netlink/netlink.h>
27 #include <netlink/attr.h>
28 #include <netlink/utils.h>
29 #include <netlink/object.h>
30 #include <netlink/route/rtnl.h>
31 #include <netlink-private/route/link/api.h>
32 #include <netlink/route/link/can.h>
34 #include <linux/can/netlink.h>
37 #define CAN_HAS_BITTIMING (1<<0)
38 #define CAN_HAS_BITTIMING_CONST (1<<1)
39 #define CAN_HAS_CLOCK (1<<2)
40 #define CAN_HAS_STATE (1<<3)
41 #define CAN_HAS_CTRLMODE (1<<4)
42 #define CAN_HAS_RESTART_MS (1<<5)
43 #define CAN_HAS_RESTART (1<<6)
44 #define CAN_HAS_BERR_COUNTER (1<<7)
49 uint32_t ci_restart_ms;
50 struct can_ctrlmode ci_ctrlmode;
51 struct can_bittiming ci_bittiming;
52 struct can_bittiming_const ci_bittiming_const;
53 struct can_clock ci_clock;
54 struct can_berr_counter ci_berr_counter;
60 static struct nla_policy can_policy[IFLA_CAN_MAX + 1] = {
62 [IFLA_CAN_CTRLMODE] = { .minlen =
sizeof(
struct can_ctrlmode) },
63 [IFLA_CAN_RESTART_MS] = { .type =
NLA_U32 },
64 [IFLA_CAN_RESTART] = { .type =
NLA_U32 },
65 [IFLA_CAN_BITTIMING] = { .minlen =
sizeof(
struct can_bittiming) },
66 [IFLA_CAN_BITTIMING_CONST]
67 = { .minlen =
sizeof(
struct can_bittiming_const) },
68 [IFLA_CAN_CLOCK] = { .minlen =
sizeof(
struct can_clock) },
69 [IFLA_CAN_BERR_COUNTER] = { .minlen =
sizeof(
struct can_berr_counter) },
72 static int can_alloc(
struct rtnl_link *link)
77 memset(link->l_info, 0,
sizeof(*ci));
79 ci = calloc(1,
sizeof(*ci));
89 static int can_parse(
struct rtnl_link *link,
struct nlattr *data,
90 struct nlattr *xstats)
92 struct nlattr *tb[IFLA_CAN_MAX+1];
96 NL_DBG(3,
"Parsing CAN link info\n");
101 if ((err = can_alloc(link)) < 0)
106 if (tb[IFLA_CAN_STATE]) {
108 ci->ci_mask |= CAN_HAS_STATE;
111 if (tb[IFLA_CAN_RESTART]) {
112 ci->ci_restart =
nla_get_u32(tb[IFLA_CAN_RESTART]);
113 ci->ci_mask |= CAN_HAS_RESTART;
116 if (tb[IFLA_CAN_RESTART_MS]) {
117 ci->ci_restart_ms =
nla_get_u32(tb[IFLA_CAN_RESTART_MS]);
118 ci->ci_mask |= CAN_HAS_RESTART_MS;
121 if (tb[IFLA_CAN_CTRLMODE]) {
122 nla_memcpy(&ci->ci_ctrlmode, tb[IFLA_CAN_CTRLMODE],
123 sizeof(ci->ci_ctrlmode));
124 ci->ci_mask |= CAN_HAS_CTRLMODE;
127 if (tb[IFLA_CAN_BITTIMING]) {
128 nla_memcpy(&ci->ci_bittiming, tb[IFLA_CAN_BITTIMING],
129 sizeof(ci->ci_bittiming));
130 ci->ci_mask |= CAN_HAS_BITTIMING;
133 if (tb[IFLA_CAN_BITTIMING_CONST]) {
135 tb[IFLA_CAN_BITTIMING_CONST],
136 sizeof(ci->ci_bittiming_const));
137 ci->ci_mask |= CAN_HAS_BITTIMING_CONST;
140 if (tb[IFLA_CAN_CLOCK]) {
142 sizeof(ci->ci_clock));
143 ci->ci_mask |= CAN_HAS_CLOCK;
146 if (tb[IFLA_CAN_BERR_COUNTER]) {
147 nla_memcpy(&ci->ci_berr_counter, tb[IFLA_CAN_BERR_COUNTER],
148 sizeof(ci->ci_berr_counter));
149 ci->ci_mask |= CAN_HAS_BERR_COUNTER;
157 static void can_free(
struct rtnl_link *link)
159 struct can_info *ci = link->l_info;
165 static char *print_can_state (uint32_t state)
171 case CAN_STATE_ERROR_ACTIVE:
172 text =
"error active";
174 case CAN_STATE_ERROR_WARNING:
175 text =
"error warning";
177 case CAN_STATE_ERROR_PASSIVE:
178 text =
"error passive";
180 case CAN_STATE_BUS_OFF:
183 case CAN_STATE_STOPPED:
186 case CAN_STATE_SLEEPING:
190 text =
"unknown state";
198 struct can_info *ci = link->l_info;
201 rtnl_link_can_ctrlmode2str(ci->ci_ctrlmode.flags, buf,
sizeof(buf));
202 nl_dump(p,
"bitrate %d %s <%s>",
203 ci->ci_bittiming.bitrate, print_can_state(ci->ci_state), buf);
208 struct can_info *ci = link->l_info;
211 rtnl_link_can_ctrlmode2str(ci->ci_ctrlmode.flags, buf,
sizeof(buf));
212 nl_dump(p,
" bitrate %d %s <%s>",
213 ci->ci_bittiming.bitrate, print_can_state(ci->ci_state), buf);
215 if (ci->ci_mask & CAN_HAS_RESTART) {
217 nl_dump_line(p,
" restarting\n");
220 if (ci->ci_mask & CAN_HAS_RESTART_MS) {
221 nl_dump_line(p,
" restart interval %d ms\n",
225 if (ci->ci_mask & CAN_HAS_BITTIMING) {
226 nl_dump_line(p,
" sample point %f %%\n",
227 ((
float) ci->ci_bittiming.sample_point)/10);
228 nl_dump_line(p,
" time quanta %d ns\n",
229 ci->ci_bittiming.tq);
230 nl_dump_line(p,
" propagation segment %d tq\n",
231 ci->ci_bittiming.prop_seg);
232 nl_dump_line(p,
" phase buffer segment1 %d tq\n",
233 ci->ci_bittiming.phase_seg1);
234 nl_dump_line(p,
" phase buffer segment2 %d tq\n",
235 ci->ci_bittiming.phase_seg2);
236 nl_dump_line(p,
" synchronisation jump width %d tq\n",
237 ci->ci_bittiming.sjw);
238 nl_dump_line(p,
" bitrate prescaler %d\n",
239 ci->ci_bittiming.brp);
242 if (ci->ci_mask & CAN_HAS_BITTIMING_CONST) {
243 nl_dump_line(p,
" minimum tsig1 %d tq\n",
244 ci->ci_bittiming_const.tseg1_min);
245 nl_dump_line(p,
" maximum tsig1 %d tq\n",
246 ci->ci_bittiming_const.tseg1_max);
247 nl_dump_line(p,
" minimum tsig2 %d tq\n",
248 ci->ci_bittiming_const.tseg2_min);
249 nl_dump_line(p,
" maximum tsig2 %d tq\n",
250 ci->ci_bittiming_const.tseg2_max);
251 nl_dump_line(p,
" maximum sjw %d tq\n",
252 ci->ci_bittiming_const.sjw_max);
253 nl_dump_line(p,
" minimum brp %d\n",
254 ci->ci_bittiming_const.brp_min);
255 nl_dump_line(p,
" maximum brp %d\n",
256 ci->ci_bittiming_const.brp_max);
257 nl_dump_line(p,
" brp increment %d\n",
258 ci->ci_bittiming_const.brp_inc);
261 if (ci->ci_mask & CAN_HAS_CLOCK) {
262 nl_dump_line(p,
" base freq %d Hz\n", ci->ci_clock);
266 if (ci->ci_mask & CAN_HAS_BERR_COUNTER) {
267 nl_dump_line(p,
" bus error RX %d\n",
268 ci->ci_berr_counter.rxerr);
269 nl_dump_line(p,
" bus error TX %d\n",
270 ci->ci_berr_counter.txerr);
278 struct can_info *cdst, *csrc = src->l_info;
286 cdst = malloc(
sizeof(*cdst));
296 static int can_put_attrs(
struct nl_msg *msg,
struct rtnl_link *link)
298 struct can_info *ci = link->l_info;
305 if (ci->ci_mask & CAN_HAS_RESTART)
308 if (ci->ci_mask & CAN_HAS_RESTART_MS)
309 NLA_PUT_U32(msg, CAN_HAS_RESTART_MS, ci->ci_restart_ms);
311 if (ci->ci_mask & CAN_HAS_CTRLMODE)
312 NLA_PUT(msg, CAN_HAS_CTRLMODE,
sizeof(ci->ci_ctrlmode),
315 if (ci->ci_mask & CAN_HAS_BITTIMING)
316 NLA_PUT(msg, CAN_HAS_BITTIMING,
sizeof(ci->ci_bittiming),
319 if (ci->ci_mask & CAN_HAS_BITTIMING_CONST)
320 NLA_PUT(msg, CAN_HAS_BITTIMING_CONST,
321 sizeof(ci->ci_bittiming_const),
322 &ci->ci_bittiming_const);
324 if (ci->ci_mask & CAN_HAS_CLOCK)
325 NLA_PUT(msg, CAN_HAS_CLOCK,
sizeof(ci->ci_clock),
335 static struct rtnl_link_info_ops can_info_ops = {
337 .io_alloc = can_alloc,
338 .io_parse = can_parse,
343 .io_clone = can_clone,
344 .io_put_attrs = can_put_attrs,
349 #define IS_CAN_LINK_ASSERT(link) \
350 if ((link)->l_info_ops != &can_info_ops) { \
351 APPBUG("Link is not a CAN link. set type \"can\" first."); \
352 return -NLE_OPNOTSUPP; \
369 return link->l_info_ops && !strcmp(link->l_info_ops->io_name,
"can");
380 struct can_info *ci = link->l_info;
382 IS_CAN_LINK_ASSERT(link);
385 ci->ci_restart |= CAN_HAS_RESTART;
399 struct can_info *ci = link->l_info;
401 IS_CAN_LINK_ASSERT(link);
405 if (ci->ci_mask & CAN_HAS_CLOCK)
406 *freq = ci->ci_clock.freq;
421 struct can_info *ci = link->l_info;
423 IS_CAN_LINK_ASSERT(link);
427 *state = ci->ci_state;
440 struct can_info *ci = link->l_info;
442 IS_CAN_LINK_ASSERT(link);
444 if (ci->ci_mask & CAN_HAS_BERR_COUNTER)
445 return ci->ci_berr_counter.rxerr;
458 struct can_info *ci = link->l_info;
460 IS_CAN_LINK_ASSERT(link);
462 if (ci->ci_mask & CAN_HAS_BERR_COUNTER)
463 return ci->ci_berr_counter.txerr;
477 struct can_info *ci = link->l_info;
479 IS_CAN_LINK_ASSERT(link);
483 if (ci->ci_mask & CAN_HAS_BERR_COUNTER)
484 *berr = ci->ci_berr_counter;
499 struct can_bittiming_const *bt_const)
501 struct can_info *ci = link->l_info;
503 IS_CAN_LINK_ASSERT(link);
507 if (ci->ci_mask & CAN_HAS_BITTIMING_CONST)
508 *bt_const = ci->ci_bittiming_const;
523 struct can_bittiming *bit_timing)
525 struct can_info *ci = link->l_info;
527 IS_CAN_LINK_ASSERT(link);
531 if (ci->ci_mask & CAN_HAS_BITTIMING)
532 *bit_timing = ci->ci_bittiming;
547 struct can_bittiming *bit_timing)
549 struct can_info *ci = link->l_info;
551 IS_CAN_LINK_ASSERT(link);
555 ci->ci_bittiming = *bit_timing;
556 ci->ci_mask |= CAN_HAS_BITTIMING;
570 struct can_info *ci = link->l_info;
572 IS_CAN_LINK_ASSERT(link);
576 if (ci->ci_mask & CAN_HAS_BITTIMING)
577 *bitrate = ci->ci_bittiming.bitrate;
593 struct can_info *ci = link->l_info;
595 IS_CAN_LINK_ASSERT(link);
597 ci->ci_bittiming.bitrate = bitrate;
598 ci->ci_mask |= CAN_HAS_BITTIMING;
612 struct can_info *ci = link->l_info;
614 IS_CAN_LINK_ASSERT(link);
618 if (ci->ci_mask & CAN_HAS_BITTIMING)
619 *sp = ci->ci_bittiming.sample_point;
635 struct can_info *ci = link->l_info;
637 IS_CAN_LINK_ASSERT(link);
639 ci->ci_bittiming.sample_point = sp;
640 ci->ci_mask |= CAN_HAS_BITTIMING;
654 struct can_info *ci = link->l_info;
656 IS_CAN_LINK_ASSERT(link);
660 if (ci->ci_mask & CAN_HAS_RESTART_MS)
661 *interval = ci->ci_restart_ms;
677 struct can_info *ci = link->l_info;
679 IS_CAN_LINK_ASSERT(link);
681 ci->ci_restart_ms = interval;
682 ci->ci_mask |= CAN_HAS_RESTART_MS;
696 struct can_info *ci = link->l_info;
698 IS_CAN_LINK_ASSERT(link);
702 if (ci->ci_mask & CAN_HAS_CTRLMODE)
703 *ctrlmode = ci->ci_ctrlmode.flags;
719 struct can_info *ci = link->l_info;
721 IS_CAN_LINK_ASSERT(link);
723 ci->ci_ctrlmode.flags |= ctrlmode;
724 ci->ci_ctrlmode.mask |= ctrlmode;
725 ci->ci_mask |= CAN_HAS_CTRLMODE;
739 struct can_info *ci = link->l_info;
741 IS_CAN_LINK_ASSERT(link);
743 ci->ci_ctrlmode.flags &= ~ctrlmode;
744 ci->ci_ctrlmode.mask |= ctrlmode;
745 ci->ci_mask |= CAN_HAS_CTRLMODE;
757 static const struct trans_tbl can_ctrlmode[] = {
758 __ADD(CAN_CTRLMODE_LOOPBACK, loopback),
759 __ADD(CAN_CTRLMODE_LISTENONLY, listen-only),
760 __ADD(CAN_CTRLMODE_3_SAMPLES, triple-sampling),
761 __ADD(CAN_CTRLMODE_ONE_SHOT, one-shot),
762 __ADD(CAN_CTRLMODE_BERR_REPORTING, berr-reporting),
765 char *rtnl_link_can_ctrlmode2str(
int ctrlmode,
char *buf,
size_t len)
767 return __flags2str(ctrlmode, buf, len, can_ctrlmode,
768 ARRAY_SIZE(can_ctrlmode));
771 int rtnl_link_can_str2ctrlmode(
const char *name)
773 return __str2flags(name, can_ctrlmode, ARRAY_SIZE(can_ctrlmode));
778 static void __init can_init(
void)
783 static void __exit can_exit(
void)
Dump object briefly on one line.
int rtnl_link_can_restart(struct rtnl_link *link)
Restart CAN device.
int rtnl_link_can_berr_rx(struct rtnl_link *link)
Get CAN RX bus error count.
int rtnl_link_can_set_ctrlmode(struct rtnl_link *link, uint32_t ctrlmode)
Set a CAN Control Mode.
int rtnl_link_register_info(struct rtnl_link_info_ops *ops)
Register operations for a link info type.
Attribute validation policy.
int rtnl_link_can_set_restart_ms(struct rtnl_link *link, uint32_t interval)
Set CAN device restart intervall.
int rtnl_link_is_can(struct rtnl_link *link)
Check if link is a CAN link.
uint32_t nla_get_u32(const struct nlattr *nla)
Return payload of 32 bit integer attribute.
int rtnl_link_can_unset_ctrlmode(struct rtnl_link *link, uint32_t ctrlmode)
Unset a CAN Control Mode.
int rtnl_link_can_berr(struct rtnl_link *link, struct can_berr_counter *berr)
Get CAN bus error count.
Dump all attributes but no statistics.
int rtnl_link_can_get_bitrate(struct rtnl_link *link, uint32_t *bitrate)
Get CAN device bit-timing.
int rtnl_link_can_state(struct rtnl_link *link, uint32_t *state)
Get CAN state.
int nla_nest_end(struct nl_msg *msg, struct nlattr *start)
Finalize nesting of attributes.
int nla_memcpy(void *dest, const struct nlattr *src, int count)
Copy attribute payload to another memory area.
int rtnl_link_can_get_bt_const(struct rtnl_link *link, struct can_bittiming_const *bt_const)
Get CAN harware-dependent bit-timing constant.
#define NLA_PUT(msg, attrtype, attrlen, data)
Add unspecific attribute to netlink message.
int nla_parse_nested(struct nlattr *tb[], int maxtype, struct nlattr *nla, struct nla_policy *policy)
Create attribute index based on nested attribute.
int rtnl_link_can_get_restart_ms(struct rtnl_link *link, uint32_t *interval)
Get CAN device restart intervall.
int rtnl_link_set_type(struct rtnl_link *link, const char *type)
Set type of link object.
#define NLA_PUT_U32(msg, attrtype, value)
Add 32 bit integer attribute to netlink message.
int rtnl_link_can_set_bitrate(struct rtnl_link *link, uint32_t bitrate)
Set CAN device bit-rate.
int rtnl_link_can_get_sample_point(struct rtnl_link *link, uint32_t *sp)
Get CAN device sample point.
int rtnl_link_unregister_info(struct rtnl_link_info_ops *ops)
Unregister operations for a link info type.
uint16_t type
Type of attribute or NLA_UNSPEC.
int rtnl_link_can_get_ctrlmode(struct rtnl_link *link, uint32_t *ctrlmode)
Get CAN control mode.
int rtnl_link_can_set_bittiming(struct rtnl_link *link, struct can_bittiming *bit_timing)
Set CAN device bit-timing.
int rtnl_link_can_set_sample_point(struct rtnl_link *link, uint32_t sp)
Set CAN device sample point.
int rtnl_link_can_freq(struct rtnl_link *link, uint32_t *freq)
Get CAN base frequency.
void nl_dump(struct nl_dump_params *params, const char *fmt,...)
Dump a formatted character string.
int rtnl_link_can_berr_tx(struct rtnl_link *link)
Get CAN TX bus error count.
int rtnl_link_can_get_bittiming(struct rtnl_link *link, struct can_bittiming *bit_timing)
Get CAN device bit-timing.
struct nlattr * nla_nest_start(struct nl_msg *msg, int attrtype)
Start a new level of nested attributes.