libnl: /data/src/libnl3/lib/route/link/can.c Source File

libnl 3.10.0

can.c
1/* SPDX-License-Identifier: LGPL-2.1-only */
2/*
3 * Copyright (c) 2012 Benedikt Spranger <b.spranger@linutronix.de>
4 */
5
6/**
7 * @ingroup link
8 * @defgroup can CAN
9 * Controller Area Network link module
10 *
11 * @details
12 * \b Link Type Name: "can"
13 *
14 * @route_doc{link_can, CAN Documentation}
15 *
16 * @{
17 */
18
19#include "nl-default.h"
20
21#include <linux/can/netlink.h>
22
23#include <netlink/netlink.h>
24#include <netlink/attr.h>
25#include <netlink/utils.h>
26#include <netlink/object.h>
27#include <netlink/route/rtnl.h>
28#include <netlink/route/link/can.h>
29
30#include "nl-route.h"
31#include "link-api.h"
32
33/** @cond SKIP */
34#define CAN_HAS_BITTIMING (1<<0)
35#define CAN_HAS_BITTIMING_CONST (1<<1)
36#define CAN_HAS_CLOCK (1<<2)
37#define CAN_HAS_STATE (1<<3)
38#define CAN_HAS_CTRLMODE (1<<4)
39#define CAN_HAS_RESTART_MS (1<<5)
40#define CAN_HAS_RESTART (1<<6)
41#define CAN_HAS_BERR_COUNTER (1<<7)
42#define CAN_HAS_DATA_BITTIMING (1<<8)
43#define CAN_HAS_DATA_BITTIMING_CONST (1<<9)
44#define CAN_HAS_DEVICE_STATS (1<<10)
45
46struct 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 struct can_bittiming ci_data_bittiming;
57 struct can_bittiming_const ci_data_bittiming_const;
58 struct can_device_stats ci_device_stats;
59};
60
61/** @endcond */
62
63static struct nla_policy can_policy[IFLA_CAN_MAX + 1] = {
64 [IFLA_CAN_STATE] = { .type = NLA_U32 },
65 [IFLA_CAN_CTRLMODE] = { .minlen = sizeof(struct can_ctrlmode) },
66 [IFLA_CAN_RESTART_MS] = { .type = NLA_U32 },
67 [IFLA_CAN_RESTART] = { .type = NLA_U32 },
68 [IFLA_CAN_BITTIMING] = { .minlen = sizeof(struct can_bittiming) },
69 [IFLA_CAN_BITTIMING_CONST]
70 = { .minlen = sizeof(struct can_bittiming_const) },
71 [IFLA_CAN_CLOCK] = { .minlen = sizeof(struct can_clock) },
72 [IFLA_CAN_BERR_COUNTER] = { .minlen = sizeof(struct can_berr_counter) },
73 [IFLA_CAN_DATA_BITTIMING]
74 = { .minlen = sizeof(struct can_bittiming) },
75 [IFLA_CAN_DATA_BITTIMING_CONST]
76 = { .minlen = sizeof(struct can_bittiming_const) },
77};
78
79static int can_alloc(struct rtnl_link *link)
80{
81 struct can_info *ci;
82
83 if (link->l_info)
84 memset(link->l_info, 0, sizeof(*ci));
85 else {
86 ci = calloc(1, sizeof(*ci));
87 if (!ci)
88 return -NLE_NOMEM;
89
90 link->l_info = ci;
91 }
92
93 return 0;
94}
95
96static int can_parse(struct rtnl_link *link, struct nlattr *data,
97 struct nlattr *xstats)
98{
99 struct nlattr *tb[IFLA_CAN_MAX+1];
100 struct can_info *ci;
101 int err;
102
103 NL_DBG(3, "Parsing CAN link info\n");
104
105 if ((err = nla_parse_nested(tb, IFLA_CAN_MAX, data, can_policy)) < 0)
106 goto errout;
107
108 if ((err = can_alloc(link)) < 0)
109 goto errout;
110
111 ci = link->l_info;
112
113 if (tb[IFLA_CAN_STATE]) {
114 ci->ci_state = nla_get_u32(tb[IFLA_CAN_STATE]);
115 ci->ci_mask |= CAN_HAS_STATE;
116 }
117
118 if (tb[IFLA_CAN_RESTART]) {
119 ci->ci_restart = nla_get_u32(tb[IFLA_CAN_RESTART]);
120 ci->ci_mask |= CAN_HAS_RESTART;
121 }
122
123 if (tb[IFLA_CAN_RESTART_MS]) {
124 ci->ci_restart_ms = nla_get_u32(tb[IFLA_CAN_RESTART_MS]);
125 ci->ci_mask |= CAN_HAS_RESTART_MS;
126 }
127
128 if (tb[IFLA_CAN_CTRLMODE]) {
129 nla_memcpy(&ci->ci_ctrlmode, tb[IFLA_CAN_CTRLMODE],
130 sizeof(ci->ci_ctrlmode));
131 ci->ci_mask |= CAN_HAS_CTRLMODE;
132 }
133
134 if (tb[IFLA_CAN_BITTIMING]) {
135 nla_memcpy(&ci->ci_bittiming, tb[IFLA_CAN_BITTIMING],
136 sizeof(ci->ci_bittiming));
137 ci->ci_mask |= CAN_HAS_BITTIMING;
138 }
139
140 if (tb[IFLA_CAN_BITTIMING_CONST]) {
141 nla_memcpy(&ci->ci_bittiming_const,
142 tb[IFLA_CAN_BITTIMING_CONST],
143 sizeof(ci->ci_bittiming_const));
144 ci->ci_mask |= CAN_HAS_BITTIMING_CONST;
145 }
146
147 if (tb[IFLA_CAN_CLOCK]) {
148 nla_memcpy(&ci->ci_clock, tb[IFLA_CAN_CLOCK],
149 sizeof(ci->ci_clock));
150 ci->ci_mask |= CAN_HAS_CLOCK;
151 }
152
153 if (tb[IFLA_CAN_BERR_COUNTER]) {
154 nla_memcpy(&ci->ci_berr_counter, tb[IFLA_CAN_BERR_COUNTER],
155 sizeof(ci->ci_berr_counter));
156 ci->ci_mask |= CAN_HAS_BERR_COUNTER;
157 }
158
159 if (tb[IFLA_CAN_DATA_BITTIMING]) {
160 nla_memcpy(&ci->ci_data_bittiming, tb[IFLA_CAN_DATA_BITTIMING],
161 sizeof(ci->ci_data_bittiming));
162 ci->ci_mask |= CAN_HAS_DATA_BITTIMING;
163 }
164
165 if (tb[IFLA_CAN_DATA_BITTIMING_CONST]) {
166 nla_memcpy(&ci->ci_data_bittiming_const, tb[IFLA_CAN_DATA_BITTIMING_CONST],
167 sizeof(ci->ci_data_bittiming_const));
168 ci->ci_mask |= CAN_HAS_DATA_BITTIMING_CONST;
169 }
170
171 if (xstats && _nla_len(xstats) >= sizeof(ci->ci_device_stats)) {
172 nla_memcpy(&ci->ci_device_stats, xstats, sizeof(ci->ci_device_stats));
173 ci->ci_mask |= CAN_HAS_DEVICE_STATS;
174 }
175
176 err = 0;
177errout:
178 return err;
179}
180
181static void can_free(struct rtnl_link *link)
182{
183 struct can_info *ci = link->l_info;
184
185 free(ci);
186 link->l_info = NULL;
187}
188
189static char *print_can_state (uint32_t state)
190{
191 char *text;
192
193 switch (state)
194 {
195 case CAN_STATE_ERROR_ACTIVE:
196 text = "error active";
197 break;
198 case CAN_STATE_ERROR_WARNING:
199 text = "error warning";
200 break;
201 case CAN_STATE_ERROR_PASSIVE:
202 text = "error passive";
203 break;
204 case CAN_STATE_BUS_OFF:
205 text = "bus off";
206 break;
207 case CAN_STATE_STOPPED:
208 text = "stopped";
209 break;
210 case CAN_STATE_SLEEPING:
211 text = "sleeping";
212 break;
213 default:
214 text = "unknown state";
215 }
216
217 return text;
218}
219
220static void can_dump_line(struct rtnl_link *link, struct nl_dump_params *p)
221{
222 struct can_info *ci = link->l_info;
223 char buf [64];
224
225 rtnl_link_can_ctrlmode2str(ci->ci_ctrlmode.flags, buf, sizeof(buf));
226 nl_dump(p, "bitrate %d %s <%s>",
227 ci->ci_bittiming.bitrate, print_can_state(ci->ci_state), buf);
228}
229
230static void can_dump_details(struct rtnl_link *link, struct nl_dump_params *p)
231{
232 struct can_info *ci = link->l_info;
233
234 can_dump_line(link, p);
235
236 if (ci->ci_mask & CAN_HAS_RESTART) {
237 if (ci->ci_restart)
238 nl_dump_line(p," restarting\n");
239 }
240
241 if (ci->ci_mask & CAN_HAS_RESTART_MS) {
242 nl_dump_line(p," restart interval %d ms\n",
243 ci->ci_restart_ms);
244 }
245
246 if (ci->ci_mask & CAN_HAS_BITTIMING) {
247 nl_dump_line(p," sample point %f %%\n",
248 ((float) ci->ci_bittiming.sample_point)/10);
249 nl_dump_line(p," time quanta %d ns\n",
250 ci->ci_bittiming.tq);
251 nl_dump_line(p," propagation segment %d tq\n",
252 ci->ci_bittiming.prop_seg);
253 nl_dump_line(p," phase buffer segment1 %d tq\n",
254 ci->ci_bittiming.phase_seg1);
255 nl_dump_line(p," phase buffer segment2 %d tq\n",
256 ci->ci_bittiming.phase_seg2);
257 nl_dump_line(p," synchronisation jump width %d tq\n",
258 ci->ci_bittiming.sjw);
259 nl_dump_line(p," bitrate prescaler %d\n",
260 ci->ci_bittiming.brp);
261 }
262
263 if (ci->ci_mask & CAN_HAS_BITTIMING_CONST) {
264 nl_dump_line(p," minimum tsig1 %d tq\n",
265 ci->ci_bittiming_const.tseg1_min);
266 nl_dump_line(p," maximum tsig1 %d tq\n",
267 ci->ci_bittiming_const.tseg1_max);
268 nl_dump_line(p," minimum tsig2 %d tq\n",
269 ci->ci_bittiming_const.tseg2_min);
270 nl_dump_line(p," maximum tsig2 %d tq\n",
271 ci->ci_bittiming_const.tseg2_max);
272 nl_dump_line(p," maximum sjw %d tq\n",
273 ci->ci_bittiming_const.sjw_max);
274 nl_dump_line(p," minimum brp %d\n",
275 ci->ci_bittiming_const.brp_min);
276 nl_dump_line(p," maximum brp %d\n",
277 ci->ci_bittiming_const.brp_max);
278 nl_dump_line(p," brp increment %d\n",
279 ci->ci_bittiming_const.brp_inc);
280 }
281
282 if (ci->ci_mask & CAN_HAS_CLOCK) {
283 nl_dump_line(p," base freq %u Hz\n", ci->ci_clock.freq);
284
285 }
286
287 if (ci->ci_mask & CAN_HAS_BERR_COUNTER) {
288 nl_dump_line(p," bus error RX %d\n",
289 ci->ci_berr_counter.rxerr);
290 nl_dump_line(p," bus error TX %d\n",
291 ci->ci_berr_counter.txerr);
292 }
293}
294
295static void can_dump_stats(struct rtnl_link *link, struct nl_dump_params *p)
296{
297 struct can_info *ci = link->l_info;
298
299 can_dump_details(link, p);
300
301 if (ci->ci_mask & CAN_HAS_DEVICE_STATS) {
302 nl_dump_line(p," bus errors %d\n",
303 ci->ci_device_stats.bus_error);
304 nl_dump_line(p," error warning state changes %d\n",
305 ci->ci_device_stats.error_warning);
306 nl_dump_line(p," error passive state changes %d\n",
307 ci->ci_device_stats.error_passive);
308 nl_dump_line(p," bus off state changes %d\n",
309 ci->ci_device_stats.bus_off);
310 nl_dump_line(p," arbitration lost errors %d\n",
311 ci->ci_device_stats.arbitration_lost);
312 nl_dump_line(p," restarts %d\n",
313 ci->ci_device_stats.restarts);
314 }
315}
316
317static int can_clone(struct rtnl_link *dst, struct rtnl_link *src)
318{
319 struct can_info *cdst, *csrc = src->l_info;
320 int ret;
321
322 dst->l_info = NULL;
323 ret = rtnl_link_set_type(dst, "can");
324 if (ret < 0)
325 return ret;
326
327 cdst = malloc(sizeof(*cdst));
328 if (!cdst)
329 return -NLE_NOMEM;
330
331 *cdst = *csrc;
332 dst->l_info = cdst;
333
334 return 0;
335}
336
337static int can_put_attrs(struct nl_msg *msg, struct rtnl_link *link)
338{
339 struct can_info *ci = link->l_info;
340 struct nlattr *data;
341
342 data = nla_nest_start(msg, IFLA_INFO_DATA);
343 if (!data)
344 return -NLE_MSGSIZE;
345
346 if (ci->ci_mask & CAN_HAS_RESTART)
347 NLA_PUT_U32(msg, IFLA_CAN_RESTART, ci->ci_restart);
348
349 if (ci->ci_mask & CAN_HAS_RESTART_MS)
350 NLA_PUT_U32(msg, IFLA_CAN_RESTART_MS, ci->ci_restart_ms);
351
352 if (ci->ci_mask & CAN_HAS_CTRLMODE)
353 NLA_PUT(msg, IFLA_CAN_CTRLMODE, sizeof(ci->ci_ctrlmode),
354 &ci->ci_ctrlmode);
355
356 if (ci->ci_mask & CAN_HAS_BITTIMING)
357 NLA_PUT(msg, IFLA_CAN_BITTIMING, sizeof(ci->ci_bittiming),
358 &ci->ci_bittiming);
359
360 if (ci->ci_mask & CAN_HAS_BITTIMING_CONST)
361 NLA_PUT(msg, IFLA_CAN_BITTIMING_CONST,
362 sizeof(ci->ci_bittiming_const),
363 &ci->ci_bittiming_const);
364
365 if (ci->ci_mask & CAN_HAS_CLOCK)
366 NLA_PUT(msg, IFLA_CAN_CLOCK, sizeof(ci->ci_clock),
367 &ci->ci_clock);
368
369 if (ci->ci_mask & CAN_HAS_DATA_BITTIMING)
370 NLA_PUT(msg, IFLA_CAN_DATA_BITTIMING, sizeof(ci->ci_data_bittiming),
371 &ci->ci_data_bittiming);
372
373 if (ci->ci_mask & CAN_HAS_DATA_BITTIMING_CONST)
374 NLA_PUT(msg, IFLA_CAN_DATA_BITTIMING_CONST, sizeof(ci->ci_data_bittiming_const),
375 &ci->ci_data_bittiming_const);
376
377 nla_nest_end(msg, data);
378
379nla_put_failure:
380
381 return 0;
382}
383
384static struct rtnl_link_info_ops can_info_ops = {
385 .io_name = "can",
386 .io_alloc = can_alloc,
387 .io_parse = can_parse,
388 .io_dump = {
389 [NL_DUMP_LINE] = can_dump_line,
390 [NL_DUMP_DETAILS] = can_dump_details,
391 [NL_DUMP_STATS] = can_dump_stats,
392 },
393 .io_clone = can_clone,
394 .io_put_attrs = can_put_attrs,
395 .io_free = can_free,
396};
397
398/** @cond SKIP */
399#define IS_CAN_LINK_ASSERT(link) \
400 if ((link)->l_info_ops != &can_info_ops) { \
401 APPBUG("Link is not a CAN link. set type \"can\" first."); \
402 return -NLE_OPNOTSUPP; \
403 }
404/** @endcond */
405
406/**
407 * @name CAN Object
408 * @{
409 */
410
411/**
412 * Check if link is a CAN link
413 * @arg link Link object
414 *
415 * @return True if link is a CAN link, otherwise false is returned.
416 */
417 int rtnl_link_is_can(struct rtnl_link *link)
418{
419 return link->l_info_ops && !strcmp(link->l_info_ops->io_name, "can");
420}
421
422/**
423 * Restart CAN device
424 * @arg link Link object
425 *
426 * @return 0 on success or a negative error code
427 */
428 int rtnl_link_can_restart(struct rtnl_link *link)
429{
430 struct can_info *ci = link->l_info;
431
432 IS_CAN_LINK_ASSERT(link);
433
434 ci->ci_restart = 1;
435 ci->ci_restart |= CAN_HAS_RESTART;
436
437 return 0;
438}
439
440/**
441 * Get CAN base frequency
442 * @arg link Link object
443 * @arg freq frequency in Hz
444 *
445 * @return 0 on success or a negative error code
446 */
447 int rtnl_link_can_freq(struct rtnl_link *link, uint32_t *freq)
448{
449 struct can_info *ci = link->l_info;
450
451 IS_CAN_LINK_ASSERT(link);
452 if (!freq)
453 return -NLE_INVAL;
454
455 if (ci->ci_mask & CAN_HAS_CLOCK)
456 *freq = ci->ci_clock.freq;
457 else
458 return -NLE_AGAIN;
459
460 return 0;
461}
462
463/**
464 * Get CAN state
465 * @arg link Link object
466 * @arg state CAN bus state
467 * @return 0 on success or a negative error code
468 */
469 int rtnl_link_can_state(struct rtnl_link *link, uint32_t *state)
470{
471 struct can_info *ci = link->l_info;
472
473 IS_CAN_LINK_ASSERT(link);
474 if (!state)
475 return -NLE_INVAL;
476
477 *state = ci->ci_state;
478
479 return 0;
480}
481
482/**
483 * Get CAN RX bus error count
484 * @arg link Link object
485 *
486 * @return RX bus error count on success or a negative error code
487 */
488 int rtnl_link_can_berr_rx(struct rtnl_link *link)
489{
490 struct can_info *ci = link->l_info;
491
492 IS_CAN_LINK_ASSERT(link);
493
494 if (ci->ci_mask & CAN_HAS_BERR_COUNTER)
495 return ci->ci_berr_counter.rxerr;
496 else
497 return -NLE_AGAIN;
498}
499
500/**
501 * Get CAN TX bus error count
502 * @arg link Link object
503 *
504 * @return TX bus error count on success or a negative error code
505 */
506 int rtnl_link_can_berr_tx(struct rtnl_link *link)
507{
508 struct can_info *ci = link->l_info;
509
510 IS_CAN_LINK_ASSERT(link);
511
512 if (ci->ci_mask & CAN_HAS_BERR_COUNTER)
513 return ci->ci_berr_counter.txerr;
514 else
515 return -NLE_AGAIN;
516}
517
518/**
519 * Get CAN bus error count
520 * @arg link Link object
521 * @arg berr Bus error count
522 *
523 * @return 0 on success or a negative error code
524 */
525 int rtnl_link_can_berr(struct rtnl_link *link, struct can_berr_counter *berr)
526{
527 struct can_info *ci = link->l_info;
528
529 IS_CAN_LINK_ASSERT(link);
530 if (!berr)
531 return -NLE_INVAL;
532
533 if (ci->ci_mask & CAN_HAS_BERR_COUNTER)
534 *berr = ci->ci_berr_counter;
535 else
536 return -NLE_AGAIN;
537
538 return 0;
539}
540
541/**
542 * Get CAN hardware-dependent bit-timing constant
543 * @arg link Link object
544 * @arg bt_const Bit-timing constant
545 *
546 * @return 0 on success or a negative error code
547 */
548 int rtnl_link_can_get_bt_const(struct rtnl_link *link,
549 struct can_bittiming_const *bt_const)
550{
551 struct can_info *ci = link->l_info;
552
553 IS_CAN_LINK_ASSERT(link);
554 if (!bt_const)
555 return -NLE_INVAL;
556
557 if (ci->ci_mask & CAN_HAS_BITTIMING_CONST)
558 *bt_const = ci->ci_bittiming_const;
559 else
560 return -NLE_AGAIN;
561
562 return 0;
563}
564
565/**
566 * Get CAN device bit-timing
567 * @arg link Link object
568 * @arg bit_timing CAN bit-timing
569 *
570 * @return 0 on success or a negative error code
571 */
572 int rtnl_link_can_get_bittiming(struct rtnl_link *link,
573 struct can_bittiming *bit_timing)
574{
575 struct can_info *ci = link->l_info;
576
577 IS_CAN_LINK_ASSERT(link);
578 if (!bit_timing)
579 return -NLE_INVAL;
580
581 if (ci->ci_mask & CAN_HAS_BITTIMING)
582 *bit_timing = ci->ci_bittiming;
583 else
584 return -NLE_AGAIN;
585
586 return 0;
587}
588
589/**
590 * Set CAN device bit-timing
591 * @arg link Link object
592 * @arg bit_timing CAN bit-timing
593 *
594 * @return 0 on success or a negative error code
595 */
596 int rtnl_link_can_set_bittiming(struct rtnl_link *link,
597 const struct can_bittiming *bit_timing)
598{
599 struct can_info *ci = link->l_info;
600
601 IS_CAN_LINK_ASSERT(link);
602 if (!bit_timing)
603 return -NLE_INVAL;
604
605 ci->ci_bittiming = *bit_timing;
606 ci->ci_mask |= CAN_HAS_BITTIMING;
607
608 return 0;
609}
610
611/**
612 * Get CAN device bit-timing
613 * @arg link Link object
614 * @arg bitrate CAN bitrate
615 *
616 * @return 0 on success or a negative error code
617 */
618 int rtnl_link_can_get_bitrate(struct rtnl_link *link, uint32_t *bitrate)
619{
620 struct can_info *ci = link->l_info;
621
622 IS_CAN_LINK_ASSERT(link);
623 if (!bitrate)
624 return -NLE_INVAL;
625
626 if (ci->ci_mask & CAN_HAS_BITTIMING)
627 *bitrate = ci->ci_bittiming.bitrate;
628 else
629 return -NLE_AGAIN;
630
631 return 0;
632}
633
634/**
635 * Set CAN device bit-rate
636 * @arg link Link object
637 * @arg bitrate CAN bitrate
638 *
639 * @return 0 on success or a negative error code
640 */
641 int rtnl_link_can_set_bitrate(struct rtnl_link *link, uint32_t bitrate)
642{
643 struct can_info *ci = link->l_info;
644
645 IS_CAN_LINK_ASSERT(link);
646
647 ci->ci_bittiming.bitrate = bitrate;
648 ci->ci_mask |= CAN_HAS_BITTIMING;
649
650 return 0;
651}
652
653/**
654 * Get CAN device sample point
655 * @arg link Link object
656 * @arg sp CAN sample point
657 *
658 * @return 0 on success or a negative error code
659 */
660 int rtnl_link_can_get_sample_point(struct rtnl_link *link, uint32_t *sp)
661{
662 struct can_info *ci = link->l_info;
663
664 IS_CAN_LINK_ASSERT(link);
665 if (!sp)
666 return -NLE_INVAL;
667
668 if (ci->ci_mask & CAN_HAS_BITTIMING)
669 *sp = ci->ci_bittiming.sample_point;
670 else
671 return -NLE_AGAIN;
672
673 return 0;
674}
675
676/**
677 * Set CAN device sample point
678 * @arg link Link object
679 * @arg sp CAN sample point
680 *
681 * @return 0 on success or a negative error code
682 */
683 int rtnl_link_can_set_sample_point(struct rtnl_link *link, uint32_t sp)
684{
685 struct can_info *ci = link->l_info;
686
687 IS_CAN_LINK_ASSERT(link);
688
689 ci->ci_bittiming.sample_point = sp;
690 ci->ci_mask |= CAN_HAS_BITTIMING;
691
692 return 0;
693}
694
695/**
696 * Get CAN device restart intervall
697 * @arg link Link object
698 * @arg interval Restart intervall in ms
699 *
700 * @return 0 on success or a negative error code
701 */
702 int rtnl_link_can_get_restart_ms(struct rtnl_link *link, uint32_t *interval)
703{
704 struct can_info *ci = link->l_info;
705
706 IS_CAN_LINK_ASSERT(link);
707 if (!interval)
708 return -NLE_INVAL;
709
710 if (ci->ci_mask & CAN_HAS_RESTART_MS)
711 *interval = ci->ci_restart_ms;
712 else
713 return -NLE_AGAIN;
714
715 return 0;
716}
717
718/**
719 * Set CAN device restart intervall
720 * @arg link Link object
721 * @arg interval Restart intervall in ms
722 *
723 * @return 0 on success or a negative error code
724 */
725 int rtnl_link_can_set_restart_ms(struct rtnl_link *link, uint32_t interval)
726{
727 struct can_info *ci = link->l_info;
728
729 IS_CAN_LINK_ASSERT(link);
730
731 ci->ci_restart_ms = interval;
732 ci->ci_mask |= CAN_HAS_RESTART_MS;
733
734 return 0;
735}
736
737/**
738 * Get CAN control mode
739 * @arg link Link object
740 * @arg ctrlmode CAN control mode
741 *
742 * @return 0 on success or a negative error code
743 */
744 int rtnl_link_can_get_ctrlmode(struct rtnl_link *link, uint32_t *ctrlmode)
745{
746 struct can_info *ci = link->l_info;
747
748 IS_CAN_LINK_ASSERT(link);
749 if (!ctrlmode)
750 return -NLE_INVAL;
751
752 if (ci->ci_mask & CAN_HAS_CTRLMODE)
753 *ctrlmode = ci->ci_ctrlmode.flags;
754 else
755 return -NLE_AGAIN;
756
757 return 0;
758}
759
760/**
761 * Set a CAN Control Mode
762 * @arg link Link object
763 * @arg ctrlmode CAN control mode
764 *
765 * @return 0 on success or a negative error code
766 */
767 int rtnl_link_can_set_ctrlmode(struct rtnl_link *link, uint32_t ctrlmode)
768{
769 struct can_info *ci = link->l_info;
770
771 IS_CAN_LINK_ASSERT(link);
772
773 ci->ci_ctrlmode.flags |= ctrlmode;
774 ci->ci_ctrlmode.mask |= ctrlmode;
775 ci->ci_mask |= CAN_HAS_CTRLMODE;
776
777 return 0;
778}
779
780/**
781 * Unset a CAN Control Mode
782 * @arg link Link object
783 * @arg ctrlmode CAN control mode
784 *
785 * @return 0 on success or a negative error code
786 */
787 int rtnl_link_can_unset_ctrlmode(struct rtnl_link *link, uint32_t ctrlmode)
788{
789 struct can_info *ci = link->l_info;
790
791 IS_CAN_LINK_ASSERT(link);
792
793 ci->ci_ctrlmode.flags &= ~ctrlmode;
794 ci->ci_ctrlmode.mask |= ctrlmode;
795 ci->ci_mask |= CAN_HAS_CTRLMODE;
796
797 return 0;
798}
799
800/**
801 * Get CAN FD hardware-dependent data bit-timing constant
802 * @arg link Link object
803 * @arg data_bt_const CAN FD data bit-timing constant
804 *
805 * @return 0 on success or a negative error code
806 */
807 int rtnl_link_can_get_data_bittiming_const(struct rtnl_link *link,
808 struct can_bittiming_const *data_bt_const)
809{
810 struct can_info *ci = link->l_info;
811
812 IS_CAN_LINK_ASSERT(link);
813 if (!data_bt_const)
814 return -NLE_INVAL;
815
816 if (ci->ci_mask & CAN_HAS_DATA_BITTIMING_CONST)
817 *data_bt_const = ci->ci_data_bittiming_const;
818 else
819 return -NLE_AGAIN;
820
821 return 0;
822}
823
824/**
825 * Set CAN FD device data bit-timing-const
826 * @arg link Link object
827 * @arg data_bit_timing CAN FD data bit-timing
828 *
829 * @return 0 on success or a negative error code
830 */
831 int rtnl_link_can_set_data_bittiming_const(struct rtnl_link *link,
832 const struct can_bittiming_const *data_bt_const)
833{
834 struct can_info *ci = link->l_info;
835
836 IS_CAN_LINK_ASSERT(link);
837 if (!data_bt_const)
838 return -NLE_INVAL;
839
840 ci->ci_data_bittiming_const = *data_bt_const;
841 ci->ci_mask |= CAN_HAS_DATA_BITTIMING_CONST;
842
843 return 0;
844}
845
846/**
847 * Get CAN FD device data bit-timing
848 * @arg link Link object
849 * @arg data_bit_timing CAN FD data bit-timing
850 *
851 * @return 0 on success or a negative error code
852 */
853 int rtnl_link_can_get_data_bittiming(struct rtnl_link *link,
854 struct can_bittiming *data_bit_timing)
855{
856 struct can_info *ci = link->l_info;
857
858 IS_CAN_LINK_ASSERT(link);
859 if (!data_bit_timing)
860 return -NLE_INVAL;
861
862 if (ci->ci_mask & CAN_HAS_DATA_BITTIMING)
863 *data_bit_timing = ci->ci_data_bittiming;
864 else
865 return -NLE_AGAIN;
866
867 return 0;
868}
869
870/**
871 * Set CAN FD device data bit-timing
872 * @arg link Link object
873 * @arg data_bit_timing CAN FD data bit-timing
874 *
875 * @return 0 on success or a negative error code
876 */
877 int rtnl_link_can_set_data_bittiming(struct rtnl_link *link,
878 const struct can_bittiming *data_bit_timing)
879{
880 struct can_info *ci = link->l_info;
881
882 IS_CAN_LINK_ASSERT(link);
883 if (!data_bit_timing)
884 return -NLE_INVAL;
885
886 ci->ci_data_bittiming = *data_bit_timing;
887 ci->ci_mask |= CAN_HAS_DATA_BITTIMING;
888
889 return 0;
890}
891
892/**
893 * Get CAN device stats
894 * @arg link Link object
895 * @arg device_stats CAN device stats
896 *
897 * @return 0 on success or a negative error code
898 */
899 int rtnl_link_can_get_device_stats(struct rtnl_link* link,
900 struct can_device_stats *device_stats)
901{
902 struct can_info *ci = link->l_info;
903
904 IS_CAN_LINK_ASSERT(link);
905 if (!device_stats)
906 return -NLE_INVAL;
907
908 if (ci->ci_mask & CAN_HAS_DEVICE_STATS)
909 *device_stats = ci->ci_device_stats;
910 else
911 return -NLE_MISSING_ATTR;
912
913 return 0;
914}
915
916/** @} */
917
918/**
919 * @name Control Mode Translation
920 * @{
921 */
922
923static const struct trans_tbl can_ctrlmode[] = {
924 __ADD(CAN_CTRLMODE_LOOPBACK, loopback),
925 __ADD(CAN_CTRLMODE_LISTENONLY, listen-only),
926 __ADD(CAN_CTRLMODE_3_SAMPLES, triple-sampling),
927 __ADD(CAN_CTRLMODE_ONE_SHOT, one-shot),
928 __ADD(CAN_CTRLMODE_BERR_REPORTING, berr-reporting),
929 __ADD(CAN_CTRLMODE_FD, fd),
930 __ADD(CAN_CTRLMODE_PRESUME_ACK, presume-ack),
931 __ADD(CAN_CTRLMODE_FD_NON_ISO, fd-non-iso),
932};
933
934char *rtnl_link_can_ctrlmode2str(int ctrlmode, char *buf, size_t len)
935{
936 return __flags2str(ctrlmode, buf, len, can_ctrlmode,
937 ARRAY_SIZE(can_ctrlmode));
938}
939
940int rtnl_link_can_str2ctrlmode(const char *name)
941{
942 return __str2flags(name, can_ctrlmode, ARRAY_SIZE(can_ctrlmode));
943}
944
945/** @} */
946
947static void _nl_init can_init(void)
948{
949 rtnl_link_register_info(&can_info_ops);
950}
951
952static void _nl_exit can_exit(void)
953{
954 rtnl_link_unregister_info(&can_info_ops);
955}
956
957/** @} */
nla_get_u32
uint32_t nla_get_u32(const struct nlattr *nla)
Return payload of 32 bit integer attribute.
Definition attr.c:712
NLA_PUT
#define NLA_PUT(msg, attrtype, attrlen, data)
Add unspecific attribute to netlink message.
Definition attr.h:159
NLA_PUT_U32
#define NLA_PUT_U32(msg, attrtype, value)
Add 32 bit integer attribute to netlink message.
Definition attr.h:230
nla_memcpy
int nla_memcpy(void *dest, const struct nlattr *src, int count)
Copy attribute payload to another memory area.
Definition attr.c:353
nla_nest_start
struct nlattr * nla_nest_start(struct nl_msg *msg, int attrtype)
Start a new level of nested attributes.
Definition attr.c:908
nla_parse_nested
int nla_parse_nested(struct nlattr *tb[], int maxtype, struct nlattr *nla, const struct nla_policy *policy)
Create attribute index based on nested attribute.
Definition attr.c:1035
nla_nest_end
int nla_nest_end(struct nl_msg *msg, struct nlattr *start)
Finalize nesting of attributes.
Definition attr.c:971
NLA_U32
@ NLA_U32
32 bit integer
Definition attr.h:37
rtnl_link_can_berr_rx
int rtnl_link_can_berr_rx(struct rtnl_link *link)
Get CAN RX bus error count.
Definition can.c:488
rtnl_link_can_set_restart_ms
int rtnl_link_can_set_restart_ms(struct rtnl_link *link, uint32_t interval)
Set CAN device restart intervall.
Definition can.c:725
rtnl_link_can_get_restart_ms
int rtnl_link_can_get_restart_ms(struct rtnl_link *link, uint32_t *interval)
Get CAN device restart intervall.
Definition can.c:702
rtnl_link_can_get_ctrlmode
int rtnl_link_can_get_ctrlmode(struct rtnl_link *link, uint32_t *ctrlmode)
Get CAN control mode.
Definition can.c:744
rtnl_link_can_freq
int rtnl_link_can_freq(struct rtnl_link *link, uint32_t *freq)
Get CAN base frequency.
Definition can.c:447
rtnl_link_can_get_bittiming
int rtnl_link_can_get_bittiming(struct rtnl_link *link, struct can_bittiming *bit_timing)
Get CAN device bit-timing.
Definition can.c:572
rtnl_link_can_unset_ctrlmode
int rtnl_link_can_unset_ctrlmode(struct rtnl_link *link, uint32_t ctrlmode)
Unset a CAN Control Mode.
Definition can.c:787
rtnl_link_can_set_data_bittiming_const
int rtnl_link_can_set_data_bittiming_const(struct rtnl_link *link, const struct can_bittiming_const *data_bt_const)
Set CAN FD device data bit-timing-const.
Definition can.c:831
rtnl_link_is_can
int rtnl_link_is_can(struct rtnl_link *link)
Check if link is a CAN link.
Definition can.c:417
rtnl_link_can_get_data_bittiming
int rtnl_link_can_get_data_bittiming(struct rtnl_link *link, struct can_bittiming *data_bit_timing)
Get CAN FD device data bit-timing.
Definition can.c:853
rtnl_link_can_restart
int rtnl_link_can_restart(struct rtnl_link *link)
Restart CAN device.
Definition can.c:428
rtnl_link_can_set_sample_point
int rtnl_link_can_set_sample_point(struct rtnl_link *link, uint32_t sp)
Set CAN device sample point.
Definition can.c:683
rtnl_link_can_set_data_bittiming
int rtnl_link_can_set_data_bittiming(struct rtnl_link *link, const struct can_bittiming *data_bit_timing)
Set CAN FD device data bit-timing.
Definition can.c:877
rtnl_link_can_get_sample_point
int rtnl_link_can_get_sample_point(struct rtnl_link *link, uint32_t *sp)
Get CAN device sample point.
Definition can.c:660
rtnl_link_can_set_bittiming
int rtnl_link_can_set_bittiming(struct rtnl_link *link, const struct can_bittiming *bit_timing)
Set CAN device bit-timing.
Definition can.c:596
rtnl_link_can_set_bitrate
int rtnl_link_can_set_bitrate(struct rtnl_link *link, uint32_t bitrate)
Set CAN device bit-rate.
Definition can.c:641
rtnl_link_can_get_device_stats
int rtnl_link_can_get_device_stats(struct rtnl_link *link, struct can_device_stats *device_stats)
Get CAN device stats.
Definition can.c:899
rtnl_link_can_get_data_bittiming_const
int rtnl_link_can_get_data_bittiming_const(struct rtnl_link *link, struct can_bittiming_const *data_bt_const)
Get CAN FD hardware-dependent data bit-timing constant.
Definition can.c:807
rtnl_link_can_get_bitrate
int rtnl_link_can_get_bitrate(struct rtnl_link *link, uint32_t *bitrate)
Get CAN device bit-timing.
Definition can.c:618
rtnl_link_can_berr_tx
int rtnl_link_can_berr_tx(struct rtnl_link *link)
Get CAN TX bus error count.
Definition can.c:506
rtnl_link_can_state
int rtnl_link_can_state(struct rtnl_link *link, uint32_t *state)
Get CAN state.
Definition can.c:469
rtnl_link_can_get_bt_const
int rtnl_link_can_get_bt_const(struct rtnl_link *link, struct can_bittiming_const *bt_const)
Get CAN hardware-dependent bit-timing constant.
Definition can.c:548
rtnl_link_can_set_ctrlmode
int rtnl_link_can_set_ctrlmode(struct rtnl_link *link, uint32_t ctrlmode)
Set a CAN Control Mode.
Definition can.c:767
rtnl_link_can_berr
int rtnl_link_can_berr(struct rtnl_link *link, struct can_berr_counter *berr)
Get CAN bus error count.
Definition can.c:525
rtnl_link_register_info
int rtnl_link_register_info(struct rtnl_link_info_ops *ops)
Register operations for a link info type.
Definition api.c:127
rtnl_link_unregister_info
int rtnl_link_unregister_info(struct rtnl_link_info_ops *ops)
Unregister operations for a link info type.
Definition api.c:162
rtnl_link_set_type
int rtnl_link_set_type(struct rtnl_link *link, const char *type)
Set type of link object.
Definition link.c:2558
nl_dump
void nl_dump(struct nl_dump_params *params, const char *fmt,...)
Dump a formatted character string.
Definition utils.c:1015
NL_DUMP_STATS
@ NL_DUMP_STATS
Dump all attributes including statistics.
Definition types.h:22
NL_DUMP_LINE
@ NL_DUMP_LINE
Dump object briefly on one line.
Definition types.h:20
NL_DUMP_DETAILS
@ NL_DUMP_DETAILS
Dump all attributes but no statistics.
Definition types.h:21
nl_dump_params
Dumping parameters.
Definition types.h:32
nla_policy
Attribute validation policy.
Definition attr.h:63
nla_policy::type
uint16_t type
Type of attribute or NLA_UNSPEC.
Definition attr.h:65
rtnl_link_info_ops
Available operations to modules implementing a link info type.
Definition link-api.h:20
rtnl_link_info_ops::io_name
char * io_name
Name of link info type, must match name on kernel side.
Definition link-api.h:22
rtnl_link
Link object.
Definition nl-route.h:29