Skip to content

Commit 12a6075

Browse files
hartkoppmarckleinebudde
authored andcommitted
can: dev: add CAN interface termination API
This patch adds a netlink interface to configure the CAN bus termination of CAN interfaces. Inside the driver an array of supported termination values is defined: const u16 drvname_termination[] = { 60, 120, CAN_TERMINATION_DISABLED }; struct drvname_priv *priv; priv = netdev_priv(dev); priv->termination_const = drvname_termination; priv->termination_const_cnt = ARRAY_SIZE(drvname_termination); priv->termination = CAN_TERMINATION_DISABLED; And the funtion to set the value has to be defined: priv->do_set_termination = drvname_set_termination; Signed-off-by: Oliver Hartkopp <socketcan@hartkopp.net> Reviewed-by: Ramesh Shanmugasundaram <Ramesh.shanmugasundaram@bp.renesas.com> Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
1 parent d140199 commit 12a6075

3 files changed

Lines changed: 57 additions & 1 deletion

File tree

drivers/net/can/dev.c

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -958,6 +958,30 @@ static int can_changelink(struct net_device *dev,
958958
}
959959
}
960960

961+
if (data[IFLA_CAN_TERMINATION]) {
962+
const u16 termval = nla_get_u16(data[IFLA_CAN_TERMINATION]);
963+
const unsigned int num_term = priv->termination_const_cnt;
964+
unsigned int i;
965+
966+
if (!priv->do_set_termination)
967+
return -EOPNOTSUPP;
968+
969+
/* check whether given value is supported by the interface */
970+
for (i = 0; i < num_term; i++) {
971+
if (termval == priv->termination_const[i])
972+
break;
973+
}
974+
if (i >= num_term)
975+
return -EINVAL;
976+
977+
/* Finally, set the termination value */
978+
err = priv->do_set_termination(dev, termval);
979+
if (err)
980+
return err;
981+
982+
priv->termination = termval;
983+
}
984+
961985
return 0;
962986
}
963987

@@ -980,6 +1004,11 @@ static size_t can_get_size(const struct net_device *dev)
9801004
size += nla_total_size(sizeof(struct can_bittiming));
9811005
if (priv->data_bittiming_const) /* IFLA_CAN_DATA_BITTIMING_CONST */
9821006
size += nla_total_size(sizeof(struct can_bittiming_const));
1007+
if (priv->termination_const) {
1008+
size += nla_total_size(sizeof(priv->termination)); /* IFLA_CAN_TERMINATION */
1009+
size += nla_total_size(sizeof(*priv->termination_const) * /* IFLA_CAN_TERMINATION_CONST */
1010+
priv->termination_const_cnt);
1011+
}
9831012

9841013
return size;
9851014
}
@@ -1018,7 +1047,15 @@ static int can_fill_info(struct sk_buff *skb, const struct net_device *dev)
10181047
(priv->data_bittiming_const &&
10191048
nla_put(skb, IFLA_CAN_DATA_BITTIMING_CONST,
10201049
sizeof(*priv->data_bittiming_const),
1021-
priv->data_bittiming_const)))
1050+
priv->data_bittiming_const)) ||
1051+
1052+
(priv->termination_const &&
1053+
(nla_put_u16(skb, IFLA_CAN_TERMINATION, priv->termination) ||
1054+
nla_put(skb, IFLA_CAN_TERMINATION_CONST,
1055+
sizeof(*priv->termination_const) *
1056+
priv->termination_const_cnt,
1057+
priv->termination_const))))
1058+
10221059
return -EMSGSIZE;
10231060

10241061
return 0;
@@ -1073,6 +1110,16 @@ static struct rtnl_link_ops can_link_ops __read_mostly = {
10731110
*/
10741111
int register_candev(struct net_device *dev)
10751112
{
1113+
struct can_priv *priv = netdev_priv(dev);
1114+
1115+
/* Ensure termination_const, termination_const_cnt and
1116+
* do_set_termination consistency. All must be either set or
1117+
* unset.
1118+
*/
1119+
if ((!priv->termination_const != !priv->termination_const_cnt) ||
1120+
(!priv->termination_const != !priv->do_set_termination))
1121+
return -EINVAL;
1122+
10761123
dev->rtnl_link_ops = &can_link_ops;
10771124
return register_netdev(dev);
10781125
}

include/linux/can/dev.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,9 @@ struct can_priv {
3838
struct can_bittiming bittiming, data_bittiming;
3939
const struct can_bittiming_const *bittiming_const,
4040
*data_bittiming_const;
41+
const u16 *termination_const;
42+
unsigned int termination_const_cnt;
43+
u16 termination;
4144
struct can_clock clock;
4245

4346
enum can_state state;
@@ -53,6 +56,7 @@ struct can_priv {
5356
int (*do_set_bittiming)(struct net_device *dev);
5457
int (*do_set_data_bittiming)(struct net_device *dev);
5558
int (*do_set_mode)(struct net_device *dev, enum can_mode mode);
59+
int (*do_set_termination)(struct net_device *dev, u16 term);
5660
int (*do_get_state)(const struct net_device *dev,
5761
enum can_state *state);
5862
int (*do_get_berr_counter)(const struct net_device *dev,

include/uapi/linux/can/netlink.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,9 +127,14 @@ enum {
127127
IFLA_CAN_BERR_COUNTER,
128128
IFLA_CAN_DATA_BITTIMING,
129129
IFLA_CAN_DATA_BITTIMING_CONST,
130+
IFLA_CAN_TERMINATION,
131+
IFLA_CAN_TERMINATION_CONST,
130132
__IFLA_CAN_MAX
131133
};
132134

133135
#define IFLA_CAN_MAX (__IFLA_CAN_MAX - 1)
134136

137+
/* u16 termination range: 1..65535 Ohms */
138+
#define CAN_TERMINATION_DISABLED 0
139+
135140
#endif /* !_UAPI_CAN_NETLINK_H */

0 commit comments

Comments
 (0)