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