Skip to content

Commit 431af77

Browse files
can: dev: add CAN interface API for fixed bitrates
Some CAN interfaces only support fixed fixed bitrates. This patch adds a netlink interface to get the list of the CAN interface's fixed bitrates and data bitrates. Inside the driver arrays of supported data- bitrate values are defined. const u32 drvname_bitrate[] = { 20000, 50000, 100000 }; const u32 drvname_data_bitrate[] = { 200000, 500000, 1000000 }; struct drvname_priv *priv; priv = netdev_priv(dev); priv->bitrate_const = drvname_bitrate; priv->bitrate_const_cnt = ARRAY_SIZE(drvname_bitrate); priv->data_bitrate_const = drvname_data_bitrate; priv->data_bitrate_const_cnt = ARRAY_SIZE(drvname_data_bitrate); Signed-off-by: Marc Kleine-Budde <[email protected]>
1 parent c3606d4 commit 431af77

File tree

3 files changed

+71
-16
lines changed

3 files changed

+71
-16
lines changed

drivers/net/can/dev.c

Lines changed: 65 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -279,8 +279,29 @@ static int can_fixup_bittiming(struct net_device *dev, struct can_bittiming *bt,
279279
return 0;
280280
}
281281

282+
/* Checks the validity of predefined bitrate settings */
283+
static int can_validate_bitrate(struct net_device *dev, struct can_bittiming *bt,
284+
const u32 *bitrate_const,
285+
const unsigned int bitrate_const_cnt)
286+
{
287+
struct can_priv *priv = netdev_priv(dev);
288+
unsigned int i;
289+
290+
for (i = 0; i < bitrate_const_cnt; i++) {
291+
if (bt->bitrate == bitrate_const[i])
292+
break;
293+
}
294+
295+
if (i >= priv->bitrate_const_cnt)
296+
return -EINVAL;
297+
298+
return 0;
299+
}
300+
282301
static int can_get_bittiming(struct net_device *dev, struct can_bittiming *bt,
283-
const struct can_bittiming_const *btc)
302+
const struct can_bittiming_const *btc,
303+
const u32 *bitrate_const,
304+
const unsigned int bitrate_const_cnt)
284305
{
285306
int err;
286307

@@ -290,10 +311,13 @@ static int can_get_bittiming(struct net_device *dev, struct can_bittiming *bt,
290311
* alternatively the CAN timing parameters (tq, prop_seg, etc.) are
291312
* provided directly which are then checked and fixed up.
292313
*/
293-
if (!bt->tq && bt->bitrate)
314+
if (!bt->tq && bt->bitrate && btc)
294315
err = can_calc_bittiming(dev, bt, btc);
295-
else if (bt->tq && !bt->bitrate)
316+
else if (bt->tq && !bt->bitrate && btc)
296317
err = can_fixup_bittiming(dev, bt, btc);
318+
else if (!bt->tq && bt->bitrate && bitrate_const)
319+
err = can_validate_bitrate(dev, bt, bitrate_const,
320+
bitrate_const_cnt);
297321
else
298322
err = -EINVAL;
299323

@@ -878,12 +902,12 @@ static int can_changelink(struct net_device *dev,
878902
return -EOPNOTSUPP;
879903

880904
memcpy(&bt, nla_data(data[IFLA_CAN_BITTIMING]), sizeof(bt));
881-
if (priv->bittiming_const) {
882-
err = can_get_bittiming(dev, &bt,
883-
priv->bittiming_const);
884-
if (err)
885-
return err;
886-
}
905+
err = can_get_bittiming(dev, &bt,
906+
priv->bittiming_const,
907+
priv->bitrate_const,
908+
priv->bitrate_const_cnt);
909+
if (err)
910+
return err;
887911
memcpy(&priv->bittiming, &bt, sizeof(bt));
888912

889913
if (priv->do_set_bittiming) {
@@ -962,12 +986,12 @@ static int can_changelink(struct net_device *dev,
962986

963987
memcpy(&dbt, nla_data(data[IFLA_CAN_DATA_BITTIMING]),
964988
sizeof(dbt));
965-
if (priv->data_bittiming_const) {
966-
err = can_get_bittiming(dev, &dbt,
967-
priv->data_bittiming_const);
968-
if (err)
969-
return err;
970-
}
989+
err = can_get_bittiming(dev, &dbt,
990+
priv->data_bittiming_const,
991+
priv->data_bitrate_const,
992+
priv->data_bitrate_const_cnt);
993+
if (err)
994+
return err;
971995
memcpy(&priv->data_bittiming, &dbt, sizeof(dbt));
972996

973997
if (priv->do_set_data_bittiming) {
@@ -1029,6 +1053,12 @@ static size_t can_get_size(const struct net_device *dev)
10291053
size += nla_total_size(sizeof(*priv->termination_const) * /* IFLA_CAN_TERMINATION_CONST */
10301054
priv->termination_const_cnt);
10311055
}
1056+
if (priv->bitrate_const) /* IFLA_CAN_BITRATE_CONST */
1057+
size += nla_total_size(sizeof(*priv->bitrate_const) *
1058+
priv->bitrate_const_cnt);
1059+
if (priv->data_bitrate_const) /* IFLA_CAN_DATA_BITRATE_CONST */
1060+
size += nla_total_size(sizeof(*priv->data_bitrate_const) *
1061+
priv->data_bitrate_const_cnt);
10321062

10331063
return size;
10341064
}
@@ -1074,7 +1104,20 @@ static int can_fill_info(struct sk_buff *skb, const struct net_device *dev)
10741104
nla_put(skb, IFLA_CAN_TERMINATION_CONST,
10751105
sizeof(*priv->termination_const) *
10761106
priv->termination_const_cnt,
1077-
priv->termination_const))))
1107+
priv->termination_const))) ||
1108+
1109+
(priv->bitrate_const &&
1110+
nla_put(skb, IFLA_CAN_BITRATE_CONST,
1111+
sizeof(*priv->bitrate_const) *
1112+
priv->bitrate_const_cnt,
1113+
priv->bitrate_const)) ||
1114+
1115+
(priv->data_bitrate_const &&
1116+
nla_put(skb, IFLA_CAN_DATA_BITRATE_CONST,
1117+
sizeof(*priv->data_bitrate_const) *
1118+
priv->data_bitrate_const_cnt,
1119+
priv->data_bitrate_const))
1120+
)
10781121

10791122
return -EMSGSIZE;
10801123

@@ -1140,6 +1183,12 @@ int register_candev(struct net_device *dev)
11401183
(!priv->termination_const != !priv->do_set_termination))
11411184
return -EINVAL;
11421185

1186+
if (!priv->bitrate_const != !priv->bitrate_const_cnt)
1187+
return -EINVAL;
1188+
1189+
if (!priv->data_bitrate_const != !priv->data_bitrate_const_cnt)
1190+
return -EINVAL;
1191+
11431192
dev->rtnl_link_ops = &can_link_ops;
11441193
return register_netdev(dev);
11451194
}

include/linux/can/dev.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,10 @@ struct can_priv {
4141
const u16 *termination_const;
4242
unsigned int termination_const_cnt;
4343
u16 termination;
44+
const u32 *bitrate_const;
45+
unsigned int bitrate_const_cnt;
46+
const u32 *data_bitrate_const;
47+
unsigned int data_bitrate_const_cnt;
4448
struct can_clock clock;
4549

4650
enum can_state state;

include/uapi/linux/can/netlink.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,8 @@ enum {
129129
IFLA_CAN_DATA_BITTIMING_CONST,
130130
IFLA_CAN_TERMINATION,
131131
IFLA_CAN_TERMINATION_CONST,
132+
IFLA_CAN_BITRATE_CONST,
133+
IFLA_CAN_DATA_BITRATE_CONST,
132134
__IFLA_CAN_MAX
133135
};
134136

0 commit comments

Comments
 (0)