[PATCH 2/2] link: socket-CAN helper functions

Benedikt Spranger b.spranger at linutronix.de
Thu Nov 29 13:48:46 EST 2012


Add helper functions to make socket-CAN configuration easy.

Signed-off-by: Benedikt Spranger <b.spranger at linutronix.de>
---
 include/netlink/route/link/can.h |   27 +++
 lib/route/link/can.c             |  359 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 386 insertions(+)

diff --git a/include/netlink/route/link/can.h b/include/netlink/route/link/can.h
index 0a99dfd..90296f1 100644
--- a/include/netlink/route/link/can.h
+++ b/include/netlink/route/link/can.h
@@ -25,6 +25,33 @@ extern int rtnl_link_is_can(struct rtnl_link *link);
 extern char *rtnl_link_can_ctrlmode2str(int, char *, size_t);
 extern int rtnl_link_can_str2ctrlmode(const char *);
 
+extern int rtnl_link_can_restart(struct rtnl_link *);
+extern int rtnl_link_can_freq(struct rtnl_link *, uint32_t *);
+
+extern int rtnl_link_can_berr_rx(struct rtnl_link *);
+extern int rtnl_link_can_berr_tx(struct rtnl_link *);
+extern int rtnl_link_can_berr(struct rtnl_link *, struct can_berr_counter *);
+
+extern int rtnl_link_can_get_bt_const(struct rtnl_link *,
+				      struct can_bittiming_const *);
+extern int rtnl_link_can_get_bittiming(struct rtnl_link *,
+				       struct can_bittiming *);
+extern int rtnl_link_can_set_bittiming(struct rtnl_link *,
+				       struct can_bittiming *);
+
+extern int rtnl_link_can_get_bitrate(struct rtnl_link *, uint32_t *);
+extern int rtnl_link_can_set_bitrate(struct rtnl_link *, uint32_t);
+
+extern int rtnl_link_can_get_sample_point(struct rtnl_link *, uint32_t *);
+extern int rtnl_link_can_set_sample_point(struct rtnl_link *, uint32_t);
+
+extern int rtnl_link_can_get_restart_ms(struct rtnl_link *, uint32_t *);
+extern int rtnl_link_can_set_restart_ms(struct rtnl_link *, uint32_t);
+
+extern int rtnl_link_can_get_ctrlmode(struct rtnl_link *, uint32_t *);
+extern int rtnl_link_can_set_ctrlmode(struct rtnl_link *, uint32_t);
+extern int rtnl_link_can_unset_ctrlmode(struct rtnl_link *, uint32_t);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/lib/route/link/can.c b/lib/route/link/can.c
index a987ca3..4b80d94 100644
--- a/lib/route/link/can.c
+++ b/lib/route/link/can.c
@@ -363,6 +363,365 @@ int rtnl_link_is_can(struct rtnl_link *link)
 	return link->l_info_ops && !strcmp(link->l_info_ops->io_name, "can");
 }
 
+/**
+ * Restart CAN device
+ * @arg link            Link object
+ *
+ * @return 0 on success or a negative error code
+ */
+int rtnl_link_can_restart(struct rtnl_link *link)
+{
+	struct can_info *ci = link->l_info;
+
+	IS_CAN_LINK_ASSERT(link);
+
+	ci->ci_restart = 1;
+	ci->ci_restart |= CAN_HAS_RESTART;
+
+	return 0;
+}
+
+/**
+ * Get CAN base frequency
+ * @arg link            Link object
+ * @arg freq		frequency in Hz
+ *
+ * @return 0 on success or a negative error code
+ */
+int rtnl_link_can_freq(struct rtnl_link *link, uint32_t *freq)
+{
+	struct can_info *ci = link->l_info;
+
+	IS_CAN_LINK_ASSERT(link);
+	if (!freq)
+		return -NLE_INVAL;
+
+	if (ci->ci_mask & CAN_HAS_CLOCK)
+		*freq = ci->ci_clock.freq;
+	else
+		return -NLE_AGAIN;
+
+	return 0;
+}
+
+/**
+ * Get CAN RX bus error count
+ * @arg link            Link object
+ *
+ * @return RX bus error count on success or a negative error code
+ */
+int rtnl_link_can_berr_rx(struct rtnl_link *link)
+{
+	struct can_info *ci = link->l_info;
+
+	IS_CAN_LINK_ASSERT(link);
+
+	if (ci->ci_mask & CAN_HAS_BERR_COUNTER)
+		return ci->ci_berr_counter.rxerr;
+	else
+		return -NLE_AGAIN;
+}
+
+/**
+ * Get CAN TX bus error count
+ * @arg link            Link object
+ *
+ * @return TX bus error count on success or a negative error code
+ */
+int rtnl_link_can_berr_tx(struct rtnl_link *link)
+{
+	struct can_info *ci = link->l_info;
+
+	IS_CAN_LINK_ASSERT(link);
+
+	if (ci->ci_mask & CAN_HAS_BERR_COUNTER)
+		return ci->ci_berr_counter.txerr;
+	else
+		return -NLE_AGAIN;
+}
+
+/**
+ * Get CAN bus error count
+ * @arg link            Link object
+ * @arg berr		Bus error count
+ *
+ * @return 0 on success or a negative error code
+ */
+int rtnl_link_can_berr(struct rtnl_link *link, struct can_berr_counter *berr)
+{
+	struct can_info *ci = link->l_info;
+
+	IS_CAN_LINK_ASSERT(link);
+	if (!berr)
+		return -NLE_INVAL;
+
+	if (ci->ci_mask & CAN_HAS_BERR_COUNTER)
+		*berr = ci->ci_berr_counter;
+	else
+		return -NLE_AGAIN;
+
+	return 0;
+}
+
+/**
+ * Get CAN harware-dependent bit-timing constant
+ * @arg link            Link object
+ * @arg bt_const	Bit-timing constant
+ *
+ * @return 0 on success or a negative error code
+ */
+int rtnl_link_can_get_bt_const(struct rtnl_link *link,
+			       struct can_bittiming_const *bt_const)
+{
+	struct can_info *ci = link->l_info;
+
+	IS_CAN_LINK_ASSERT(link);
+	if (!bt_const)
+		return -NLE_INVAL;
+
+	if (ci->ci_mask & CAN_HAS_BITTIMING_CONST)
+		*bt_const = ci->ci_bittiming_const;
+	else
+		return -NLE_AGAIN;
+
+	return 0;
+}
+
+/**
+ * Get CAN device bit-timing
+ * @arg link            Link object
+ * @arg bit_timing	CAN bit-timing
+ *
+ * @return 0 on success or a negative error code
+ */
+int rtnl_link_can_get_bittiming(struct rtnl_link *link,
+				struct can_bittiming *bit_timing)
+{
+	struct can_info *ci = link->l_info;
+
+	IS_CAN_LINK_ASSERT(link);
+	if (!bit_timing)
+		return -NLE_INVAL;
+
+	if (ci->ci_mask & CAN_HAS_BITTIMING)
+		*bit_timing = ci->ci_bittiming;
+	else
+		return -NLE_AGAIN;
+
+	return 0;
+}
+
+/**
+ * Set CAN device bit-timing
+ * @arg link            Link object
+ * @arg bit_timing	CAN bit-timing
+ *
+ * @return 0 on success or a negative error code
+ */
+int rtnl_link_can_set_bittiming(struct rtnl_link *link,
+				struct can_bittiming *bit_timing)
+{
+	struct can_info *ci = link->l_info;
+
+	IS_CAN_LINK_ASSERT(link);
+	if (!bit_timing)
+		return -NLE_INVAL;
+
+	ci->ci_bittiming = *bit_timing;
+	ci->ci_mask |= CAN_HAS_BITTIMING;
+
+	return 0;
+}
+
+/**
+ * Get CAN device bit-timing
+ * @arg link            Link object
+ * @arg bitrate		CAN bitrate
+ *
+ * @return 0 on success or a negative error code
+ */
+int rtnl_link_can_get_bitrate(struct rtnl_link *link, uint32_t *bitrate)
+{
+	struct can_info *ci = link->l_info;
+
+	IS_CAN_LINK_ASSERT(link);
+	if (!bitrate)
+		return -NLE_INVAL;
+
+	if (ci->ci_mask & CAN_HAS_BITTIMING)
+		*bitrate = ci->ci_bittiming.bitrate;
+	else
+		return -NLE_AGAIN;
+
+	return 0;
+}
+
+/**
+ * Set CAN device bit-rate
+ * @arg link            Link object
+ * @arg bitrate		CAN bitrate
+ *
+ * @return 0 on success or a negative error code
+ */
+int rtnl_link_can_set_bitrate(struct rtnl_link *link, uint32_t bitrate)
+{
+	struct can_info *ci = link->l_info;
+
+	IS_CAN_LINK_ASSERT(link);
+
+	ci->ci_bittiming.bitrate = bitrate;
+	ci->ci_mask |= CAN_HAS_BITTIMING;
+
+	return 0;
+}
+
+/**
+ * Get CAN device sample point
+ * @arg link            Link object
+ * @arg sp		CAN sample point
+ *
+ * @return 0 on success or a negative error code
+ */
+int rtnl_link_can_get_sample_point(struct rtnl_link *link, uint32_t *sp)
+{
+	struct can_info *ci = link->l_info;
+
+	IS_CAN_LINK_ASSERT(link);
+	if (!sp)
+		return -NLE_INVAL;
+
+	if (ci->ci_mask & CAN_HAS_BITTIMING)
+		*sp = ci->ci_bittiming.sample_point;
+	else
+		return -NLE_AGAIN;
+
+	return 0;
+}
+
+/**
+ * Set CAN device sample point
+ * @arg link            Link object
+ * @arg sp		CAN sample point
+ *
+ * @return 0 on success or a negative error code
+ */
+int rtnl_link_can_set_sample_point(struct rtnl_link *link, uint32_t sp)
+{
+	struct can_info *ci = link->l_info;
+
+	IS_CAN_LINK_ASSERT(link);
+
+	ci->ci_bittiming.sample_point = sp;
+	ci->ci_mask |= CAN_HAS_BITTIMING;
+
+	return 0;
+}
+
+/**
+ * Get CAN device restart intervall
+ * @arg link            Link object
+ * @arg interval	Restart intervall in ms
+ *
+ * @return 0 on success or a negative error code
+ */
+int rtnl_link_can_get_restart_ms(struct rtnl_link *link, uint32_t *interval)
+{
+	struct can_info *ci = link->l_info;
+
+	IS_CAN_LINK_ASSERT(link);
+	if (!interval)
+		return -NLE_INVAL;
+
+	if (ci->ci_mask & CAN_HAS_RESTART_MS)
+		*interval = ci->ci_restart_ms;
+	else
+		return -NLE_AGAIN;
+
+	return 0;
+}
+
+/**
+ * Set CAN device restart intervall
+ * @arg link            Link object
+ * @arg interval	Restart intervall in ms
+ *
+ * @return 0 on success or a negative error code
+ */
+int rtnl_link_can_set_restart_ms(struct rtnl_link *link, uint32_t interval)
+{
+	struct can_info *ci = link->l_info;
+
+	IS_CAN_LINK_ASSERT(link);
+
+	ci->ci_restart_ms = interval;
+	ci->ci_mask |= CAN_HAS_RESTART_MS;
+
+	return 0;
+}
+
+/**
+ * Get CAN control mode
+ * @arg link            Link object
+ * @arg ctrlmode	CAN control mode
+ *
+ * @return 0 on success or a negative error code
+ */
+int rtnl_link_can_get_ctrlmode(struct rtnl_link *link, uint32_t *ctrlmode)
+{
+	struct can_info *ci = link->l_info;
+
+	IS_CAN_LINK_ASSERT(link);
+	if (!ctrlmode)
+		return -NLE_INVAL;
+
+	if (ci->ci_mask & CAN_HAS_CTRLMODE)
+		*ctrlmode = ci->ci_ctrlmode.flags;
+	else
+		return -NLE_AGAIN;
+
+	return 0;
+}
+
+/**
+ * Set a CAN Control Mode
+ * @arg link            Link object
+ * @arg ctrlmode	CAN control mode
+ *
+ * @return 0 on success or a negative error code
+ */
+int rtnl_link_can_set_ctrlmode(struct rtnl_link *link, uint32_t ctrlmode)
+{
+	struct can_info *ci = link->l_info;
+
+	IS_CAN_LINK_ASSERT(link);
+
+	ci->ci_ctrlmode.flags |= ctrlmode;
+	ci->ci_ctrlmode.mask |= ctrlmode;
+	ci->ci_mask |= CAN_HAS_CTRLMODE;
+
+	return 0;
+}
+
+/**
+ * Unset a CAN Control Mode
+ * @arg link            Link object
+ * @arg ctrlmode	CAN control mode
+ *
+ * @return 0 on success or a negative error code
+ */
+int rtnl_link_can_unset_ctrlmode(struct rtnl_link *link, uint32_t ctrlmode)
+{
+	struct can_info *ci = link->l_info;
+
+	IS_CAN_LINK_ASSERT(link);
+
+	ci->ci_ctrlmode.flags &= ~ctrlmode;
+	ci->ci_ctrlmode.mask |= ctrlmode;
+	ci->ci_mask |= CAN_HAS_CTRLMODE;
+
+	return 0;
+}
+
 /** @} */
 
 /**
-- 
1.7.10.4




More information about the libnl mailing list