libnl  3.2.21
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_put_failure:
325 
326  return 0;
327 }
328 
329 static struct rtnl_link_info_ops can_info_ops = {
330  .io_name = "can",
331  .io_alloc = can_alloc,
332  .io_parse = can_parse,
333  .io_dump = {
334  [NL_DUMP_LINE] = can_dump_line,
335  [NL_DUMP_DETAILS] = can_dump_details,
336  },
337  .io_clone = can_clone,
338  .io_put_attrs = can_put_attrs,
339  .io_free = can_free,
340 };
341 
342 /** @cond SKIP */
343 #define IS_CAN_LINK_ASSERT(link) \
344  if ((link)->l_info_ops != &can_info_ops) { \
345  APPBUG("Link is not a CAN link. set type \"can\" first."); \
346  return -NLE_OPNOTSUPP; \
347  }
348 /** @endcond */
349 
350 /**
351  * @name CAN Object
352  * @{
353  */
354 
355 /**
356  * Check if link is a CAN link
357  * @arg link Link object
358  *
359  * @return True if link is a CAN link, otherwise false is returned.
360  */
361 int rtnl_link_is_can(struct rtnl_link *link)
362 {
363  return link->l_info_ops && !strcmp(link->l_info_ops->io_name, "can");
364 }
365 
366 /**
367  * Restart CAN device
368  * @arg link Link object
369  *
370  * @return 0 on success or a negative error code
371  */
373 {
374  struct can_info *ci = link->l_info;
375 
376  IS_CAN_LINK_ASSERT(link);
377 
378  ci->ci_restart = 1;
379  ci->ci_restart |= CAN_HAS_RESTART;
380 
381  return 0;
382 }
383 
384 /**
385  * Get CAN base frequency
386  * @arg link Link object
387  * @arg freq frequency in Hz
388  *
389  * @return 0 on success or a negative error code
390  */
391 int rtnl_link_can_freq(struct rtnl_link *link, uint32_t *freq)
392 {
393  struct can_info *ci = link->l_info;
394 
395  IS_CAN_LINK_ASSERT(link);
396  if (!freq)
397  return -NLE_INVAL;
398 
399  if (ci->ci_mask & CAN_HAS_CLOCK)
400  *freq = ci->ci_clock.freq;
401  else
402  return -NLE_AGAIN;
403 
404  return 0;
405 }
406 
407 /**
408  * Get CAN RX bus error count
409  * @arg link Link object
410  *
411  * @return RX bus error count on success or a negative error code
412  */
414 {
415  struct can_info *ci = link->l_info;
416 
417  IS_CAN_LINK_ASSERT(link);
418 
419  if (ci->ci_mask & CAN_HAS_BERR_COUNTER)
420  return ci->ci_berr_counter.rxerr;
421  else
422  return -NLE_AGAIN;
423 }
424 
425 /**
426  * Get CAN TX bus error count
427  * @arg link Link object
428  *
429  * @return TX bus error count on success or a negative error code
430  */
432 {
433  struct can_info *ci = link->l_info;
434 
435  IS_CAN_LINK_ASSERT(link);
436 
437  if (ci->ci_mask & CAN_HAS_BERR_COUNTER)
438  return ci->ci_berr_counter.txerr;
439  else
440  return -NLE_AGAIN;
441 }
442 
443 /**
444  * Get CAN bus error count
445  * @arg link Link object
446  * @arg berr Bus error count
447  *
448  * @return 0 on success or a negative error code
449  */
450 int rtnl_link_can_berr(struct rtnl_link *link, struct can_berr_counter *berr)
451 {
452  struct can_info *ci = link->l_info;
453 
454  IS_CAN_LINK_ASSERT(link);
455  if (!berr)
456  return -NLE_INVAL;
457 
458  if (ci->ci_mask & CAN_HAS_BERR_COUNTER)
459  *berr = ci->ci_berr_counter;
460  else
461  return -NLE_AGAIN;
462 
463  return 0;
464 }
465 
466 /**
467  * Get CAN harware-dependent bit-timing constant
468  * @arg link Link object
469  * @arg bt_const Bit-timing constant
470  *
471  * @return 0 on success or a negative error code
472  */
474  struct can_bittiming_const *bt_const)
475 {
476  struct can_info *ci = link->l_info;
477 
478  IS_CAN_LINK_ASSERT(link);
479  if (!bt_const)
480  return -NLE_INVAL;
481 
482  if (ci->ci_mask & CAN_HAS_BITTIMING_CONST)
483  *bt_const = ci->ci_bittiming_const;
484  else
485  return -NLE_AGAIN;
486 
487  return 0;
488 }
489 
490 /**
491  * Get CAN device bit-timing
492  * @arg link Link object
493  * @arg bit_timing CAN bit-timing
494  *
495  * @return 0 on success or a negative error code
496  */
498  struct can_bittiming *bit_timing)
499 {
500  struct can_info *ci = link->l_info;
501 
502  IS_CAN_LINK_ASSERT(link);
503  if (!bit_timing)
504  return -NLE_INVAL;
505 
506  if (ci->ci_mask & CAN_HAS_BITTIMING)
507  *bit_timing = ci->ci_bittiming;
508  else
509  return -NLE_AGAIN;
510 
511  return 0;
512 }
513 
514 /**
515  * Set CAN device bit-timing
516  * @arg link Link object
517  * @arg bit_timing CAN bit-timing
518  *
519  * @return 0 on success or a negative error code
520  */
522  struct can_bittiming *bit_timing)
523 {
524  struct can_info *ci = link->l_info;
525 
526  IS_CAN_LINK_ASSERT(link);
527  if (!bit_timing)
528  return -NLE_INVAL;
529 
530  ci->ci_bittiming = *bit_timing;
531  ci->ci_mask |= CAN_HAS_BITTIMING;
532 
533  return 0;
534 }
535 
536 /**
537  * Get CAN device bit-timing
538  * @arg link Link object
539  * @arg bitrate CAN bitrate
540  *
541  * @return 0 on success or a negative error code
542  */
543 int rtnl_link_can_get_bitrate(struct rtnl_link *link, uint32_t *bitrate)
544 {
545  struct can_info *ci = link->l_info;
546 
547  IS_CAN_LINK_ASSERT(link);
548  if (!bitrate)
549  return -NLE_INVAL;
550 
551  if (ci->ci_mask & CAN_HAS_BITTIMING)
552  *bitrate = ci->ci_bittiming.bitrate;
553  else
554  return -NLE_AGAIN;
555 
556  return 0;
557 }
558 
559 /**
560  * Set CAN device bit-rate
561  * @arg link Link object
562  * @arg bitrate CAN bitrate
563  *
564  * @return 0 on success or a negative error code
565  */
566 int rtnl_link_can_set_bitrate(struct rtnl_link *link, uint32_t bitrate)
567 {
568  struct can_info *ci = link->l_info;
569 
570  IS_CAN_LINK_ASSERT(link);
571 
572  ci->ci_bittiming.bitrate = bitrate;
573  ci->ci_mask |= CAN_HAS_BITTIMING;
574 
575  return 0;
576 }
577 
578 /**
579  * Get CAN device sample point
580  * @arg link Link object
581  * @arg sp CAN sample point
582  *
583  * @return 0 on success or a negative error code
584  */
585 int rtnl_link_can_get_sample_point(struct rtnl_link *link, uint32_t *sp)
586 {
587  struct can_info *ci = link->l_info;
588 
589  IS_CAN_LINK_ASSERT(link);
590  if (!sp)
591  return -NLE_INVAL;
592 
593  if (ci->ci_mask & CAN_HAS_BITTIMING)
594  *sp = ci->ci_bittiming.sample_point;
595  else
596  return -NLE_AGAIN;
597 
598  return 0;
599 }
600 
601 /**
602  * Set CAN device sample point
603  * @arg link Link object
604  * @arg sp CAN sample point
605  *
606  * @return 0 on success or a negative error code
607  */
608 int rtnl_link_can_set_sample_point(struct rtnl_link *link, uint32_t sp)
609 {
610  struct can_info *ci = link->l_info;
611 
612  IS_CAN_LINK_ASSERT(link);
613 
614  ci->ci_bittiming.sample_point = sp;
615  ci->ci_mask |= CAN_HAS_BITTIMING;
616 
617  return 0;
618 }
619 
620 /**
621  * Get CAN device restart intervall
622  * @arg link Link object
623  * @arg interval Restart intervall in ms
624  *
625  * @return 0 on success or a negative error code
626  */
627 int rtnl_link_can_get_restart_ms(struct rtnl_link *link, uint32_t *interval)
628 {
629  struct can_info *ci = link->l_info;
630 
631  IS_CAN_LINK_ASSERT(link);
632  if (!interval)
633  return -NLE_INVAL;
634 
635  if (ci->ci_mask & CAN_HAS_RESTART_MS)
636  *interval = ci->ci_restart_ms;
637  else
638  return -NLE_AGAIN;
639 
640  return 0;
641 }
642 
643 /**
644  * Set CAN device restart intervall
645  * @arg link Link object
646  * @arg interval Restart intervall in ms
647  *
648  * @return 0 on success or a negative error code
649  */
650 int rtnl_link_can_set_restart_ms(struct rtnl_link *link, uint32_t interval)
651 {
652  struct can_info *ci = link->l_info;
653 
654  IS_CAN_LINK_ASSERT(link);
655 
656  ci->ci_restart_ms = interval;
657  ci->ci_mask |= CAN_HAS_RESTART_MS;
658 
659  return 0;
660 }
661 
662 /**
663  * Get CAN control mode
664  * @arg link Link object
665  * @arg ctrlmode CAN control mode
666  *
667  * @return 0 on success or a negative error code
668  */
669 int rtnl_link_can_get_ctrlmode(struct rtnl_link *link, uint32_t *ctrlmode)
670 {
671  struct can_info *ci = link->l_info;
672 
673  IS_CAN_LINK_ASSERT(link);
674  if (!ctrlmode)
675  return -NLE_INVAL;
676 
677  if (ci->ci_mask & CAN_HAS_CTRLMODE)
678  *ctrlmode = ci->ci_ctrlmode.flags;
679  else
680  return -NLE_AGAIN;
681 
682  return 0;
683 }
684 
685 /**
686  * Set a CAN Control Mode
687  * @arg link Link object
688  * @arg ctrlmode CAN control mode
689  *
690  * @return 0 on success or a negative error code
691  */
692 int rtnl_link_can_set_ctrlmode(struct rtnl_link *link, uint32_t ctrlmode)
693 {
694  struct can_info *ci = link->l_info;
695 
696  IS_CAN_LINK_ASSERT(link);
697 
698  ci->ci_ctrlmode.flags |= ctrlmode;
699  ci->ci_ctrlmode.mask |= ctrlmode;
700  ci->ci_mask |= CAN_HAS_CTRLMODE;
701 
702  return 0;
703 }
704 
705 /**
706  * Unset a CAN Control Mode
707  * @arg link Link object
708  * @arg ctrlmode CAN control mode
709  *
710  * @return 0 on success or a negative error code
711  */
712 int rtnl_link_can_unset_ctrlmode(struct rtnl_link *link, uint32_t ctrlmode)
713 {
714  struct can_info *ci = link->l_info;
715 
716  IS_CAN_LINK_ASSERT(link);
717 
718  ci->ci_ctrlmode.flags &= ~ctrlmode;
719  ci->ci_ctrlmode.mask |= ctrlmode;
720  ci->ci_mask |= CAN_HAS_CTRLMODE;
721 
722  return 0;
723 }
724 
725 /** @} */
726 
727 /**
728  * @name Control Mode Translation
729  * @{
730  */
731 
732 static const struct trans_tbl can_ctrlmode[] = {
733  __ADD(CAN_CTRLMODE_LOOPBACK, loopback)
734  __ADD(CAN_CTRLMODE_LISTENONLY, listen-only)
735  __ADD(CAN_CTRLMODE_3_SAMPLES, triple-sampling)
736  __ADD(CAN_CTRLMODE_ONE_SHOT, one-shot)
737  __ADD(CAN_CTRLMODE_BERR_REPORTING, berr-reporting)
738 };
739 
740 char *rtnl_link_can_ctrlmode2str(int ctrlmode, char *buf, size_t len)
741 {
742  return __flags2str(ctrlmode, buf, len, can_ctrlmode,
743  ARRAY_SIZE(can_ctrlmode));
744 }
745 
746 int rtnl_link_can_str2ctrlmode(const char *name)
747 {
748  return __str2flags(name, can_ctrlmode, ARRAY_SIZE(can_ctrlmode));
749 }
750 
751 /** @} */
752 
753 static void __init can_init(void)
754 {
755  rtnl_link_register_info(&can_info_ops);
756 }
757 
758 static void __exit can_exit(void)
759 {
760  rtnl_link_unregister_info(&can_info_ops);
761 }
762 
763 /** @} */