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)
76 ci = calloc(1,
sizeof(*ci));
85 static int can_parse(
struct rtnl_link *link,
struct nlattr *data,
86 struct nlattr *xstats)
88 struct nlattr *tb[IFLA_CAN_MAX+1];
92 NL_DBG(3,
"Parsing CAN link info");
97 if ((err = can_alloc(link)) < 0)
102 if (tb[IFLA_CAN_STATE]) {
104 ci->ci_mask |= CAN_HAS_STATE;
107 if (tb[IFLA_CAN_RESTART]) {
108 ci->ci_restart =
nla_get_u32(tb[IFLA_CAN_RESTART]);
109 ci->ci_mask |= CAN_HAS_RESTART;
112 if (tb[IFLA_CAN_RESTART_MS]) {
113 ci->ci_restart_ms =
nla_get_u32(tb[IFLA_CAN_RESTART_MS]);
114 ci->ci_mask |= CAN_HAS_RESTART_MS;
117 if (tb[IFLA_CAN_CTRLMODE]) {
118 nla_memcpy(&ci->ci_ctrlmode, tb[IFLA_CAN_CTRLMODE],
119 sizeof(ci->ci_ctrlmode));
120 ci->ci_mask |= CAN_HAS_CTRLMODE;
123 if (tb[IFLA_CAN_BITTIMING]) {
124 nla_memcpy(&ci->ci_bittiming, tb[IFLA_CAN_BITTIMING],
125 sizeof(ci->ci_bittiming));
126 ci->ci_mask |= CAN_HAS_BITTIMING;
129 if (tb[IFLA_CAN_BITTIMING_CONST]) {
131 tb[IFLA_CAN_BITTIMING_CONST],
132 sizeof(ci->ci_bittiming_const));
133 ci->ci_mask |= CAN_HAS_BITTIMING_CONST;
136 if (tb[IFLA_CAN_CLOCK]) {
138 sizeof(ci->ci_clock));
139 ci->ci_mask |= CAN_HAS_CLOCK;
142 if (tb[IFLA_CAN_BERR_COUNTER]) {
143 nla_memcpy(&ci->ci_berr_counter, tb[IFLA_CAN_BERR_COUNTER],
144 sizeof(ci->ci_berr_counter));
145 ci->ci_mask |= CAN_HAS_BERR_COUNTER;
153 static void can_free(
struct rtnl_link *link)
155 struct can_info *ci = link->l_info;
161 static char *print_can_state (uint32_t state)
167 case CAN_STATE_ERROR_ACTIVE:
168 text =
"error active";
170 case CAN_STATE_ERROR_WARNING:
171 text =
"error warning";
173 case CAN_STATE_ERROR_PASSIVE:
174 text =
"error passive";
176 case CAN_STATE_BUS_OFF:
179 case CAN_STATE_STOPPED:
182 case CAN_STATE_SLEEPING:
186 text =
"unknown state";
194 struct can_info *ci = link->l_info;
197 rtnl_link_can_ctrlmode2str(ci->ci_ctrlmode.flags, buf,
sizeof(buf));
198 nl_dump(p,
"bitrate %d %s <%s>",
199 ci->ci_bittiming.bitrate, print_can_state(ci->ci_state), buf);
204 struct can_info *ci = link->l_info;
207 rtnl_link_can_ctrlmode2str(ci->ci_ctrlmode.flags, buf,
sizeof(buf));
208 nl_dump(p,
" bitrate %d %s <%s>",
209 ci->ci_bittiming.bitrate, print_can_state(ci->ci_state), buf);
211 if (ci->ci_mask & CAN_HAS_RESTART) {
213 nl_dump_line(p,
" restarting\n");
216 if (ci->ci_mask & CAN_HAS_RESTART_MS) {
217 nl_dump_line(p,
" restart interval %d ms\n",
221 if (ci->ci_mask & CAN_HAS_BITTIMING) {
222 nl_dump_line(p,
" sample point %f %%\n",
223 ((
float) ci->ci_bittiming.sample_point)/10);
224 nl_dump_line(p,
" time quanta %d ns\n",
225 ci->ci_bittiming.tq);
226 nl_dump_line(p,
" propagation segment %d tq\n",
227 ci->ci_bittiming.prop_seg);
228 nl_dump_line(p,
" phase buffer segment1 %d tq\n",
229 ci->ci_bittiming.phase_seg1);
230 nl_dump_line(p,
" phase buffer segment2 %d tq\n",
231 ci->ci_bittiming.phase_seg2);
232 nl_dump_line(p,
" synchronisation jump width %d tq\n",
233 ci->ci_bittiming.sjw);
234 nl_dump_line(p,
" bitrate prescaler %d\n",
235 ci->ci_bittiming.brp);
238 if (ci->ci_mask & CAN_HAS_BITTIMING_CONST) {
239 nl_dump_line(p,
" minimum tsig1 %d tq\n",
240 ci->ci_bittiming_const.tseg1_min);
241 nl_dump_line(p,
" maximum tsig1 %d tq\n",
242 ci->ci_bittiming_const.tseg1_max);
243 nl_dump_line(p,
" minimum tsig2 %d tq\n",
244 ci->ci_bittiming_const.tseg2_min);
245 nl_dump_line(p,
" maximum tsig2 %d tq\n",
246 ci->ci_bittiming_const.tseg2_max);
247 nl_dump_line(p,
" maximum sjw %d tq\n",
248 ci->ci_bittiming_const.sjw_max);
249 nl_dump_line(p,
" minimum brp %d\n",
250 ci->ci_bittiming_const.brp_min);
251 nl_dump_line(p,
" maximum brp %d\n",
252 ci->ci_bittiming_const.brp_max);
253 nl_dump_line(p,
" brp increment %d\n",
254 ci->ci_bittiming_const.brp_inc);
257 if (ci->ci_mask & CAN_HAS_CLOCK) {
258 nl_dump_line(p,
" base freq %d Hz\n", ci->ci_clock);
262 if (ci->ci_mask & CAN_HAS_BERR_COUNTER) {
263 nl_dump_line(p,
" bus error RX %d\n",
264 ci->ci_berr_counter.rxerr);
265 nl_dump_line(p,
" bus error TX %d\n",
266 ci->ci_berr_counter.txerr);
274 struct can_info *cdst, *csrc = src->l_info;
282 cdst = malloc(
sizeof(*cdst));
292 static int can_put_attrs(
struct nl_msg *msg,
struct rtnl_link *link)
294 struct can_info *ci = link->l_info;
301 if (ci->ci_mask & CAN_HAS_RESTART)
304 if (ci->ci_mask & CAN_HAS_RESTART_MS)
305 NLA_PUT_U32(msg, CAN_HAS_RESTART_MS, ci->ci_restart_ms);
307 if (ci->ci_mask & CAN_HAS_CTRLMODE)
308 NLA_PUT(msg, CAN_HAS_CTRLMODE,
sizeof(ci->ci_ctrlmode),
311 if (ci->ci_mask & CAN_HAS_BITTIMING)
312 NLA_PUT(msg, CAN_HAS_BITTIMING,
sizeof(ci->ci_bittiming),
315 if (ci->ci_mask & CAN_HAS_BITTIMING_CONST)
316 NLA_PUT(msg, CAN_HAS_BITTIMING_CONST,
317 sizeof(ci->ci_bittiming_const),
318 &ci->ci_bittiming_const);
320 if (ci->ci_mask & CAN_HAS_CLOCK)
321 NLA_PUT(msg, CAN_HAS_CLOCK,
sizeof(ci->ci_clock),
331 static struct rtnl_link_info_ops can_info_ops = {
333 .io_alloc = can_alloc,
334 .io_parse = can_parse,
339 .io_clone = can_clone,
340 .io_put_attrs = can_put_attrs,
345 #define IS_CAN_LINK_ASSERT(link) \
346 if ((link)->l_info_ops != &can_info_ops) { \
347 APPBUG("Link is not a CAN link. set type \"can\" first."); \
348 return -NLE_OPNOTSUPP; \
365 return link->l_info_ops && !strcmp(link->l_info_ops->io_name,
"can");
376 struct can_info *ci = link->l_info;
378 IS_CAN_LINK_ASSERT(link);
381 ci->ci_restart |= CAN_HAS_RESTART;
395 struct can_info *ci = link->l_info;
397 IS_CAN_LINK_ASSERT(link);
401 if (ci->ci_mask & CAN_HAS_CLOCK)
402 *freq = ci->ci_clock.freq;
417 struct can_info *ci = link->l_info;
419 IS_CAN_LINK_ASSERT(link);
423 *state = ci->ci_state;
436 struct can_info *ci = link->l_info;
438 IS_CAN_LINK_ASSERT(link);
440 if (ci->ci_mask & CAN_HAS_BERR_COUNTER)
441 return ci->ci_berr_counter.rxerr;
454 struct can_info *ci = link->l_info;
456 IS_CAN_LINK_ASSERT(link);
458 if (ci->ci_mask & CAN_HAS_BERR_COUNTER)
459 return ci->ci_berr_counter.txerr;
473 struct can_info *ci = link->l_info;
475 IS_CAN_LINK_ASSERT(link);
479 if (ci->ci_mask & CAN_HAS_BERR_COUNTER)
480 *berr = ci->ci_berr_counter;
495 struct can_bittiming_const *bt_const)
497 struct can_info *ci = link->l_info;
499 IS_CAN_LINK_ASSERT(link);
503 if (ci->ci_mask & CAN_HAS_BITTIMING_CONST)
504 *bt_const = ci->ci_bittiming_const;
519 struct can_bittiming *bit_timing)
521 struct can_info *ci = link->l_info;
523 IS_CAN_LINK_ASSERT(link);
527 if (ci->ci_mask & CAN_HAS_BITTIMING)
528 *bit_timing = ci->ci_bittiming;
543 struct can_bittiming *bit_timing)
545 struct can_info *ci = link->l_info;
547 IS_CAN_LINK_ASSERT(link);
551 ci->ci_bittiming = *bit_timing;
552 ci->ci_mask |= CAN_HAS_BITTIMING;
566 struct can_info *ci = link->l_info;
568 IS_CAN_LINK_ASSERT(link);
572 if (ci->ci_mask & CAN_HAS_BITTIMING)
573 *bitrate = ci->ci_bittiming.bitrate;
589 struct can_info *ci = link->l_info;
591 IS_CAN_LINK_ASSERT(link);
593 ci->ci_bittiming.bitrate = bitrate;
594 ci->ci_mask |= CAN_HAS_BITTIMING;
608 struct can_info *ci = link->l_info;
610 IS_CAN_LINK_ASSERT(link);
614 if (ci->ci_mask & CAN_HAS_BITTIMING)
615 *sp = ci->ci_bittiming.sample_point;
631 struct can_info *ci = link->l_info;
633 IS_CAN_LINK_ASSERT(link);
635 ci->ci_bittiming.sample_point = sp;
636 ci->ci_mask |= CAN_HAS_BITTIMING;
650 struct can_info *ci = link->l_info;
652 IS_CAN_LINK_ASSERT(link);
656 if (ci->ci_mask & CAN_HAS_RESTART_MS)
657 *interval = ci->ci_restart_ms;
673 struct can_info *ci = link->l_info;
675 IS_CAN_LINK_ASSERT(link);
677 ci->ci_restart_ms = interval;
678 ci->ci_mask |= CAN_HAS_RESTART_MS;
692 struct can_info *ci = link->l_info;
694 IS_CAN_LINK_ASSERT(link);
698 if (ci->ci_mask & CAN_HAS_CTRLMODE)
699 *ctrlmode = ci->ci_ctrlmode.flags;
715 struct can_info *ci = link->l_info;
717 IS_CAN_LINK_ASSERT(link);
719 ci->ci_ctrlmode.flags |= ctrlmode;
720 ci->ci_ctrlmode.mask |= ctrlmode;
721 ci->ci_mask |= CAN_HAS_CTRLMODE;
735 struct can_info *ci = link->l_info;
737 IS_CAN_LINK_ASSERT(link);
739 ci->ci_ctrlmode.flags &= ~ctrlmode;
740 ci->ci_ctrlmode.mask |= ctrlmode;
741 ci->ci_mask |= CAN_HAS_CTRLMODE;
753 static const struct trans_tbl can_ctrlmode[] = {
754 __ADD(CAN_CTRLMODE_LOOPBACK, loopback)
755 __ADD(CAN_CTRLMODE_LISTENONLY, listen-only)
756 __ADD(CAN_CTRLMODE_3_SAMPLES, triple-sampling)
757 __ADD(CAN_CTRLMODE_ONE_SHOT, one-shot)
758 __ADD(CAN_CTRLMODE_BERR_REPORTING, berr-reporting)
761 char *rtnl_link_can_ctrlmode2str(
int ctrlmode,
char *buf,
size_t len)
763 return __flags2str(ctrlmode, buf, len, can_ctrlmode,
764 ARRAY_SIZE(can_ctrlmode));
767 int rtnl_link_can_str2ctrlmode(
const char *name)
769 return __str2flags(name, can_ctrlmode, ARRAY_SIZE(can_ctrlmode));
774 static void __init can_init(
void)
779 static void __exit can_exit(
void)