libnl  3.2.24-rc1
can.c
1 /*
2  * lib/route/link/can.c CAN Link Info
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation version 2.1
7  * of the License.
8  *
9  * Copyright (c) 2012 Benedikt Spranger <b.spranger@linutronix.de>
10  */
11 
12 /**
13  * @ingroup link
14  * @defgroup can CAN
15  * Controller Area Network link module
16  *
17  * @details
18  * \b Link Type Name: "can"
19  *
20  * @route_doc{link_can, CAN Documentation}
21  *
22  * @{
23  */
24 
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>
33 
34 #include <linux/can/netlink.h>
35 
36 /** @cond SKIP */
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)
45 
46 struct can_info {
47  uint32_t ci_state;
48  uint32_t ci_restart;
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;
55  uint32_t ci_mask;
56 };
57 
58 /** @endcond */
59 
60 static struct nla_policy can_policy[IFLA_CAN_MAX + 1] = {
61  [IFLA_CAN_STATE] = { .type = NLA_U32 },
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) },
70 };
71 
72 static int can_alloc(struct rtnl_link *link)
73 {
74  struct can_info *ci;
75 
76  ci = calloc(1, sizeof(*ci));
77  if (!ci)
78  return -NLE_NOMEM;
79 
80  link->l_info = ci;
81 
82  return 0;
83 }
84 
85 static int can_parse(struct rtnl_link *link, struct nlattr *data,
86  struct nlattr *xstats)
87 {
88  struct nlattr *tb[IFLA_CAN_MAX+1];
89  struct can_info *ci;
90  int err;
91 
92  NL_DBG(3, "Parsing CAN link info");
93 
94  if ((err = nla_parse_nested(tb, IFLA_CAN_MAX, data, can_policy)) < 0)
95  goto errout;
96 
97  if ((err = can_alloc(link)) < 0)
98  goto errout;
99 
100  ci = link->l_info;
101 
102  if (tb[IFLA_CAN_STATE]) {
103  ci->ci_state = nla_get_u32(tb[IFLA_CAN_STATE]);
104  ci->ci_mask |= CAN_HAS_STATE;
105  }
106 
107  if (tb[IFLA_CAN_RESTART]) {
108  ci->ci_restart = nla_get_u32(tb[IFLA_CAN_RESTART]);
109  ci->ci_mask |= CAN_HAS_RESTART;
110  }
111 
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;
115  }
116 
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;
121  }
122 
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;
127  }
128 
129  if (tb[IFLA_CAN_BITTIMING_CONST]) {
130  nla_memcpy(&ci->ci_bittiming_const,
131  tb[IFLA_CAN_BITTIMING_CONST],
132  sizeof(ci->ci_bittiming_const));
133  ci->ci_mask |= CAN_HAS_BITTIMING_CONST;
134  }
135 
136  if (tb[IFLA_CAN_CLOCK]) {
137  nla_memcpy(&ci->ci_clock, tb[IFLA_CAN_CLOCK],
138  sizeof(ci->ci_clock));
139  ci->ci_mask |= CAN_HAS_CLOCK;
140  }
141 
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;
146  }
147 
148  err = 0;
149 errout:
150  return err;
151 }
152 
153 static void can_free(struct rtnl_link *link)
154 {
155  struct can_info *ci = link->l_info;
156 
157  free(ci);
158  link->l_info = NULL;
159 }
160 
161 static char *print_can_state (uint32_t state)
162 {
163  char *text;
164 
165  switch (state)
166  {
167  case CAN_STATE_ERROR_ACTIVE:
168  text = "error active";
169  break;
170  case CAN_STATE_ERROR_WARNING:
171  text = "error warning";
172  break;
173  case CAN_STATE_ERROR_PASSIVE:
174  text = "error passive";
175  break;
176  case CAN_STATE_BUS_OFF:
177  text = "bus off";
178  break;
179  case CAN_STATE_STOPPED:
180  text = "stopped";
181  break;
182  case CAN_STATE_SLEEPING:
183  text = "sleeping";
184  break;
185  default:
186  text = "unknown state";
187  }
188 
189  return text;
190 }
191 
192 static void can_dump_line(struct rtnl_link *link, struct nl_dump_params *p)
193 {
194  struct can_info *ci = link->l_info;
195  char buf [64];
196 
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);
200 }
201 
202 static void can_dump_details(struct rtnl_link *link, struct nl_dump_params *p)
203 {
204  struct can_info *ci = link->l_info;
205  char buf [64];
206 
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);
210 
211  if (ci->ci_mask & CAN_HAS_RESTART) {
212  if (ci->ci_restart)
213  nl_dump_line(p," restarting\n");
214  }
215 
216  if (ci->ci_mask & CAN_HAS_RESTART_MS) {
217  nl_dump_line(p," restart interval %d ms\n",
218  ci->ci_restart_ms);
219  }
220 
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);
236  }
237 
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);
255  }
256 
257  if (ci->ci_mask & CAN_HAS_CLOCK) {
258  nl_dump_line(p," base freq %d Hz\n", ci->ci_clock);
259 
260  }
261 
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);
267  }
268 
269  return;
270 }
271 
272 static int can_clone(struct rtnl_link *dst, struct rtnl_link *src)
273 {
274  struct can_info *cdst, *csrc = src->l_info;
275  int ret;
276 
277  dst->l_info = NULL;
278  ret = rtnl_link_set_type(dst, "can");
279  if (ret < 0)
280  return ret;
281 
282  cdst = malloc(sizeof(*cdst));
283  if (!cdst)
284  return -NLE_NOMEM;
285 
286  *cdst = *csrc;
287  dst->l_info = cdst;
288 
289  return 0;
290 }
291 
292 static int can_put_attrs(struct nl_msg *msg, struct rtnl_link *link)
293 {
294  struct can_info *ci = link->l_info;
295  struct nlattr *data;
296 
297  data = nla_nest_start(msg, IFLA_INFO_DATA);
298  if (!data)
299  return -NLE_MSGSIZE;
300 
301  if (ci->ci_mask & CAN_HAS_RESTART)
302  NLA_PUT_U32(msg, CAN_HAS_RESTART, ci->ci_restart);
303 
304  if (ci->ci_mask & CAN_HAS_RESTART_MS)
305  NLA_PUT_U32(msg, CAN_HAS_RESTART_MS, ci->ci_restart_ms);
306 
307  if (ci->ci_mask & CAN_HAS_CTRLMODE)
308  NLA_PUT(msg, CAN_HAS_CTRLMODE, sizeof(ci->ci_ctrlmode),
309  &ci->ci_ctrlmode);
310 
311  if (ci->ci_mask & CAN_HAS_BITTIMING)
312  NLA_PUT(msg, CAN_HAS_BITTIMING, sizeof(ci->ci_bittiming),
313  &ci->ci_bittiming);
314 
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);
319 
320  if (ci->ci_mask & CAN_HAS_CLOCK)
321  NLA_PUT(msg, CAN_HAS_CLOCK, sizeof(ci->ci_clock),
322  &ci->ci_clock);
323 
324  nla_nest_end(msg, data);
325 
326 nla_put_failure:
327 
328  return 0;
329 }
330 
331 static struct rtnl_link_info_ops can_info_ops = {
332  .io_name = "can",
333  .io_alloc = can_alloc,
334  .io_parse = can_parse,
335  .io_dump = {
336  [NL_DUMP_LINE] = can_dump_line,
337  [NL_DUMP_DETAILS] = can_dump_details,
338  },
339  .io_clone = can_clone,
340  .io_put_attrs = can_put_attrs,
341  .io_free = can_free,
342 };
343 
344 /** @cond SKIP */
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; \
349  }
350 /** @endcond */
351 
352 /**
353  * @name CAN Object
354  * @{
355  */
356 
357 /**
358  * Check if link is a CAN link
359  * @arg link Link object
360  *
361  * @return True if link is a CAN link, otherwise false is returned.
362  */
363 int rtnl_link_is_can(struct rtnl_link *link)
364 {
365  return link->l_info_ops && !strcmp(link->l_info_ops->io_name, "can");
366 }
367 
368 /**
369  * Restart CAN device
370  * @arg link Link object
371  *
372  * @return 0 on success or a negative error code
373  */
375 {
376  struct can_info *ci = link->l_info;
377 
378  IS_CAN_LINK_ASSERT(link);
379 
380  ci->ci_restart = 1;
381  ci->ci_restart |= CAN_HAS_RESTART;
382 
383  return 0;
384 }
385 
386 /**
387  * Get CAN base frequency
388  * @arg link Link object
389  * @arg freq frequency in Hz
390  *
391  * @return 0 on success or a negative error code
392  */
393 int rtnl_link_can_freq(struct rtnl_link *link, uint32_t *freq)
394 {
395  struct can_info *ci = link->l_info;
396 
397  IS_CAN_LINK_ASSERT(link);
398  if (!freq)
399  return -NLE_INVAL;
400 
401  if (ci->ci_mask & CAN_HAS_CLOCK)
402  *freq = ci->ci_clock.freq;
403  else
404  return -NLE_AGAIN;
405 
406  return 0;
407 }
408 
409 /**
410  * Get CAN state
411  * @arg link Link object
412  * @arg state CAN bus state
413  * @return 0 on success or a negative error code
414  */
415 int rtnl_link_can_state(struct rtnl_link *link, uint32_t *state)
416 {
417  struct can_info *ci = link->l_info;
418 
419  IS_CAN_LINK_ASSERT(link);
420  if (!state)
421  return -NLE_INVAL;
422 
423  *state = ci->ci_state;
424 
425  return 0;
426 }
427 
428 /**
429  * Get CAN RX bus error count
430  * @arg link Link object
431  *
432  * @return RX bus error count on success or a negative error code
433  */
435 {
436  struct can_info *ci = link->l_info;
437 
438  IS_CAN_LINK_ASSERT(link);
439 
440  if (ci->ci_mask & CAN_HAS_BERR_COUNTER)
441  return ci->ci_berr_counter.rxerr;
442  else
443  return -NLE_AGAIN;
444 }
445 
446 /**
447  * Get CAN TX bus error count
448  * @arg link Link object
449  *
450  * @return TX bus error count on success or a negative error code
451  */
453 {
454  struct can_info *ci = link->l_info;
455 
456  IS_CAN_LINK_ASSERT(link);
457 
458  if (ci->ci_mask & CAN_HAS_BERR_COUNTER)
459  return ci->ci_berr_counter.txerr;
460  else
461  return -NLE_AGAIN;
462 }
463 
464 /**
465  * Get CAN bus error count
466  * @arg link Link object
467  * @arg berr Bus error count
468  *
469  * @return 0 on success or a negative error code
470  */
471 int rtnl_link_can_berr(struct rtnl_link *link, struct can_berr_counter *berr)
472 {
473  struct can_info *ci = link->l_info;
474 
475  IS_CAN_LINK_ASSERT(link);
476  if (!berr)
477  return -NLE_INVAL;
478 
479  if (ci->ci_mask & CAN_HAS_BERR_COUNTER)
480  *berr = ci->ci_berr_counter;
481  else
482  return -NLE_AGAIN;
483 
484  return 0;
485 }
486 
487 /**
488  * Get CAN harware-dependent bit-timing constant
489  * @arg link Link object
490  * @arg bt_const Bit-timing constant
491  *
492  * @return 0 on success or a negative error code
493  */
495  struct can_bittiming_const *bt_const)
496 {
497  struct can_info *ci = link->l_info;
498 
499  IS_CAN_LINK_ASSERT(link);
500  if (!bt_const)
501  return -NLE_INVAL;
502 
503  if (ci->ci_mask & CAN_HAS_BITTIMING_CONST)
504  *bt_const = ci->ci_bittiming_const;
505  else
506  return -NLE_AGAIN;
507 
508  return 0;
509 }
510 
511 /**
512  * Get CAN device bit-timing
513  * @arg link Link object
514  * @arg bit_timing CAN bit-timing
515  *
516  * @return 0 on success or a negative error code
517  */
519  struct can_bittiming *bit_timing)
520 {
521  struct can_info *ci = link->l_info;
522 
523  IS_CAN_LINK_ASSERT(link);
524  if (!bit_timing)
525  return -NLE_INVAL;
526 
527  if (ci->ci_mask & CAN_HAS_BITTIMING)
528  *bit_timing = ci->ci_bittiming;
529  else
530  return -NLE_AGAIN;
531 
532  return 0;
533 }
534 
535 /**
536  * Set CAN device bit-timing
537  * @arg link Link object
538  * @arg bit_timing CAN bit-timing
539  *
540  * @return 0 on success or a negative error code
541  */
543  struct can_bittiming *bit_timing)
544 {
545  struct can_info *ci = link->l_info;
546 
547  IS_CAN_LINK_ASSERT(link);
548  if (!bit_timing)
549  return -NLE_INVAL;
550 
551  ci->ci_bittiming = *bit_timing;
552  ci->ci_mask |= CAN_HAS_BITTIMING;
553 
554  return 0;
555 }
556 
557 /**
558  * Get CAN device bit-timing
559  * @arg link Link object
560  * @arg bitrate CAN bitrate
561  *
562  * @return 0 on success or a negative error code
563  */
564 int rtnl_link_can_get_bitrate(struct rtnl_link *link, uint32_t *bitrate)
565 {
566  struct can_info *ci = link->l_info;
567 
568  IS_CAN_LINK_ASSERT(link);
569  if (!bitrate)
570  return -NLE_INVAL;
571 
572  if (ci->ci_mask & CAN_HAS_BITTIMING)
573  *bitrate = ci->ci_bittiming.bitrate;
574  else
575  return -NLE_AGAIN;
576 
577  return 0;
578 }
579 
580 /**
581  * Set CAN device bit-rate
582  * @arg link Link object
583  * @arg bitrate CAN bitrate
584  *
585  * @return 0 on success or a negative error code
586  */
587 int rtnl_link_can_set_bitrate(struct rtnl_link *link, uint32_t bitrate)
588 {
589  struct can_info *ci = link->l_info;
590 
591  IS_CAN_LINK_ASSERT(link);
592 
593  ci->ci_bittiming.bitrate = bitrate;
594  ci->ci_mask |= CAN_HAS_BITTIMING;
595 
596  return 0;
597 }
598 
599 /**
600  * Get CAN device sample point
601  * @arg link Link object
602  * @arg sp CAN sample point
603  *
604  * @return 0 on success or a negative error code
605  */
606 int rtnl_link_can_get_sample_point(struct rtnl_link *link, uint32_t *sp)
607 {
608  struct can_info *ci = link->l_info;
609 
610  IS_CAN_LINK_ASSERT(link);
611  if (!sp)
612  return -NLE_INVAL;
613 
614  if (ci->ci_mask & CAN_HAS_BITTIMING)
615  *sp = ci->ci_bittiming.sample_point;
616  else
617  return -NLE_AGAIN;
618 
619  return 0;
620 }
621 
622 /**
623  * Set CAN device sample point
624  * @arg link Link object
625  * @arg sp CAN sample point
626  *
627  * @return 0 on success or a negative error code
628  */
629 int rtnl_link_can_set_sample_point(struct rtnl_link *link, uint32_t sp)
630 {
631  struct can_info *ci = link->l_info;
632 
633  IS_CAN_LINK_ASSERT(link);
634 
635  ci->ci_bittiming.sample_point = sp;
636  ci->ci_mask |= CAN_HAS_BITTIMING;
637 
638  return 0;
639 }
640 
641 /**
642  * Get CAN device restart intervall
643  * @arg link Link object
644  * @arg interval Restart intervall in ms
645  *
646  * @return 0 on success or a negative error code
647  */
648 int rtnl_link_can_get_restart_ms(struct rtnl_link *link, uint32_t *interval)
649 {
650  struct can_info *ci = link->l_info;
651 
652  IS_CAN_LINK_ASSERT(link);
653  if (!interval)
654  return -NLE_INVAL;
655 
656  if (ci->ci_mask & CAN_HAS_RESTART_MS)
657  *interval = ci->ci_restart_ms;
658  else
659  return -NLE_AGAIN;
660 
661  return 0;
662 }
663 
664 /**
665  * Set CAN device restart intervall
666  * @arg link Link object
667  * @arg interval Restart intervall in ms
668  *
669  * @return 0 on success or a negative error code
670  */
671 int rtnl_link_can_set_restart_ms(struct rtnl_link *link, uint32_t interval)
672 {
673  struct can_info *ci = link->l_info;
674 
675  IS_CAN_LINK_ASSERT(link);
676 
677  ci->ci_restart_ms = interval;
678  ci->ci_mask |= CAN_HAS_RESTART_MS;
679 
680  return 0;
681 }
682 
683 /**
684  * Get CAN control mode
685  * @arg link Link object
686  * @arg ctrlmode CAN control mode
687  *
688  * @return 0 on success or a negative error code
689  */
690 int rtnl_link_can_get_ctrlmode(struct rtnl_link *link, uint32_t *ctrlmode)
691 {
692  struct can_info *ci = link->l_info;
693 
694  IS_CAN_LINK_ASSERT(link);
695  if (!ctrlmode)
696  return -NLE_INVAL;
697 
698  if (ci->ci_mask & CAN_HAS_CTRLMODE)
699  *ctrlmode = ci->ci_ctrlmode.flags;
700  else
701  return -NLE_AGAIN;
702 
703  return 0;
704 }
705 
706 /**
707  * Set a CAN Control Mode
708  * @arg link Link object
709  * @arg ctrlmode CAN control mode
710  *
711  * @return 0 on success or a negative error code
712  */
713 int rtnl_link_can_set_ctrlmode(struct rtnl_link *link, uint32_t ctrlmode)
714 {
715  struct can_info *ci = link->l_info;
716 
717  IS_CAN_LINK_ASSERT(link);
718 
719  ci->ci_ctrlmode.flags |= ctrlmode;
720  ci->ci_ctrlmode.mask |= ctrlmode;
721  ci->ci_mask |= CAN_HAS_CTRLMODE;
722 
723  return 0;
724 }
725 
726 /**
727  * Unset a CAN Control Mode
728  * @arg link Link object
729  * @arg ctrlmode CAN control mode
730  *
731  * @return 0 on success or a negative error code
732  */
733 int rtnl_link_can_unset_ctrlmode(struct rtnl_link *link, uint32_t ctrlmode)
734 {
735  struct can_info *ci = link->l_info;
736 
737  IS_CAN_LINK_ASSERT(link);
738 
739  ci->ci_ctrlmode.flags &= ~ctrlmode;
740  ci->ci_ctrlmode.mask |= ctrlmode;
741  ci->ci_mask |= CAN_HAS_CTRLMODE;
742 
743  return 0;
744 }
745 
746 /** @} */
747 
748 /**
749  * @name Control Mode Translation
750  * @{
751  */
752 
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)
759 };
760 
761 char *rtnl_link_can_ctrlmode2str(int ctrlmode, char *buf, size_t len)
762 {
763  return __flags2str(ctrlmode, buf, len, can_ctrlmode,
764  ARRAY_SIZE(can_ctrlmode));
765 }
766 
767 int rtnl_link_can_str2ctrlmode(const char *name)
768 {
769  return __str2flags(name, can_ctrlmode, ARRAY_SIZE(can_ctrlmode));
770 }
771 
772 /** @} */
773 
774 static void __init can_init(void)
775 {
776  rtnl_link_register_info(&can_info_ops);
777 }
778 
779 static void __exit can_exit(void)
780 {
781  rtnl_link_unregister_info(&can_info_ops);
782 }
783 
784 /** @} */