diff options
-rw-r--r-- | drivers/net/can/dev.c | 45 | ||||
-rw-r--r-- | include/linux/can/dev.h | 6 | ||||
-rw-r--r-- | include/uapi/linux/can/netlink.h | 2 |
3 files changed, 50 insertions, 3 deletions
diff --git a/drivers/net/can/dev.c b/drivers/net/can/dev.c index 8141290e4c18..8ebe112458c4 100644 --- a/drivers/net/can/dev.c +++ b/drivers/net/can/dev.c | |||
@@ -647,6 +647,10 @@ static const struct nla_policy can_policy[IFLA_CAN_MAX + 1] = { | |||
647 | = { .len = sizeof(struct can_bittiming_const) }, | 647 | = { .len = sizeof(struct can_bittiming_const) }, |
648 | [IFLA_CAN_CLOCK] = { .len = sizeof(struct can_clock) }, | 648 | [IFLA_CAN_CLOCK] = { .len = sizeof(struct can_clock) }, |
649 | [IFLA_CAN_BERR_COUNTER] = { .len = sizeof(struct can_berr_counter) }, | 649 | [IFLA_CAN_BERR_COUNTER] = { .len = sizeof(struct can_berr_counter) }, |
650 | [IFLA_CAN_DATA_BITTIMING] | ||
651 | = { .len = sizeof(struct can_bittiming) }, | ||
652 | [IFLA_CAN_DATA_BITTIMING_CONST] | ||
653 | = { .len = sizeof(struct can_bittiming_const) }, | ||
650 | }; | 654 | }; |
651 | 655 | ||
652 | static int can_changelink(struct net_device *dev, | 656 | static int can_changelink(struct net_device *dev, |
@@ -707,6 +711,27 @@ static int can_changelink(struct net_device *dev, | |||
707 | return err; | 711 | return err; |
708 | } | 712 | } |
709 | 713 | ||
714 | if (data[IFLA_CAN_DATA_BITTIMING]) { | ||
715 | struct can_bittiming dbt; | ||
716 | |||
717 | /* Do not allow changing bittiming while running */ | ||
718 | if (dev->flags & IFF_UP) | ||
719 | return -EBUSY; | ||
720 | memcpy(&dbt, nla_data(data[IFLA_CAN_DATA_BITTIMING]), | ||
721 | sizeof(dbt)); | ||
722 | err = can_get_bittiming(dev, &dbt, priv->data_bittiming_const); | ||
723 | if (err) | ||
724 | return err; | ||
725 | memcpy(&priv->data_bittiming, &dbt, sizeof(dbt)); | ||
726 | |||
727 | if (priv->do_set_data_bittiming) { | ||
728 | /* Finally, set the bit-timing registers */ | ||
729 | err = priv->do_set_data_bittiming(dev); | ||
730 | if (err) | ||
731 | return err; | ||
732 | } | ||
733 | } | ||
734 | |||
710 | return 0; | 735 | return 0; |
711 | } | 736 | } |
712 | 737 | ||
@@ -725,6 +750,10 @@ static size_t can_get_size(const struct net_device *dev) | |||
725 | size += nla_total_size(sizeof(u32)); /* IFLA_CAN_RESTART_MS */ | 750 | size += nla_total_size(sizeof(u32)); /* IFLA_CAN_RESTART_MS */ |
726 | if (priv->do_get_berr_counter) /* IFLA_CAN_BERR_COUNTER */ | 751 | if (priv->do_get_berr_counter) /* IFLA_CAN_BERR_COUNTER */ |
727 | size += nla_total_size(sizeof(struct can_berr_counter)); | 752 | size += nla_total_size(sizeof(struct can_berr_counter)); |
753 | if (priv->data_bittiming.bitrate) /* IFLA_CAN_DATA_BITTIMING */ | ||
754 | size += nla_total_size(sizeof(struct can_bittiming)); | ||
755 | if (priv->data_bittiming_const) /* IFLA_CAN_DATA_BITTIMING_CONST */ | ||
756 | size += nla_total_size(sizeof(struct can_bittiming_const)); | ||
728 | 757 | ||
729 | return size; | 758 | return size; |
730 | } | 759 | } |
@@ -738,20 +767,34 @@ static int can_fill_info(struct sk_buff *skb, const struct net_device *dev) | |||
738 | 767 | ||
739 | if (priv->do_get_state) | 768 | if (priv->do_get_state) |
740 | priv->do_get_state(dev, &state); | 769 | priv->do_get_state(dev, &state); |
770 | |||
741 | if ((priv->bittiming.bitrate && | 771 | if ((priv->bittiming.bitrate && |
742 | nla_put(skb, IFLA_CAN_BITTIMING, | 772 | nla_put(skb, IFLA_CAN_BITTIMING, |
743 | sizeof(priv->bittiming), &priv->bittiming)) || | 773 | sizeof(priv->bittiming), &priv->bittiming)) || |
774 | |||
744 | (priv->bittiming_const && | 775 | (priv->bittiming_const && |
745 | nla_put(skb, IFLA_CAN_BITTIMING_CONST, | 776 | nla_put(skb, IFLA_CAN_BITTIMING_CONST, |
746 | sizeof(*priv->bittiming_const), priv->bittiming_const)) || | 777 | sizeof(*priv->bittiming_const), priv->bittiming_const)) || |
778 | |||
747 | nla_put(skb, IFLA_CAN_CLOCK, sizeof(cm), &priv->clock) || | 779 | nla_put(skb, IFLA_CAN_CLOCK, sizeof(cm), &priv->clock) || |
748 | nla_put_u32(skb, IFLA_CAN_STATE, state) || | 780 | nla_put_u32(skb, IFLA_CAN_STATE, state) || |
749 | nla_put(skb, IFLA_CAN_CTRLMODE, sizeof(cm), &cm) || | 781 | nla_put(skb, IFLA_CAN_CTRLMODE, sizeof(cm), &cm) || |
750 | nla_put_u32(skb, IFLA_CAN_RESTART_MS, priv->restart_ms) || | 782 | nla_put_u32(skb, IFLA_CAN_RESTART_MS, priv->restart_ms) || |
783 | |||
751 | (priv->do_get_berr_counter && | 784 | (priv->do_get_berr_counter && |
752 | !priv->do_get_berr_counter(dev, &bec) && | 785 | !priv->do_get_berr_counter(dev, &bec) && |
753 | nla_put(skb, IFLA_CAN_BERR_COUNTER, sizeof(bec), &bec))) | 786 | nla_put(skb, IFLA_CAN_BERR_COUNTER, sizeof(bec), &bec)) || |
787 | |||
788 | (priv->data_bittiming.bitrate && | ||
789 | nla_put(skb, IFLA_CAN_DATA_BITTIMING, | ||
790 | sizeof(priv->data_bittiming), &priv->data_bittiming)) || | ||
791 | |||
792 | (priv->data_bittiming_const && | ||
793 | nla_put(skb, IFLA_CAN_DATA_BITTIMING_CONST, | ||
794 | sizeof(*priv->data_bittiming_const), | ||
795 | priv->data_bittiming_const))) | ||
754 | return -EMSGSIZE; | 796 | return -EMSGSIZE; |
797 | |||
755 | return 0; | 798 | return 0; |
756 | } | 799 | } |
757 | 800 | ||
diff --git a/include/linux/can/dev.h b/include/linux/can/dev.h index dc5f9026b67f..8adaee96f292 100644 --- a/include/linux/can/dev.h +++ b/include/linux/can/dev.h | |||
@@ -33,8 +33,9 @@ enum can_mode { | |||
33 | struct can_priv { | 33 | struct can_priv { |
34 | struct can_device_stats can_stats; | 34 | struct can_device_stats can_stats; |
35 | 35 | ||
36 | struct can_bittiming bittiming; | 36 | struct can_bittiming bittiming, data_bittiming; |
37 | const struct can_bittiming_const *bittiming_const; | 37 | const struct can_bittiming_const *bittiming_const, |
38 | *data_bittiming_const; | ||
38 | struct can_clock clock; | 39 | struct can_clock clock; |
39 | 40 | ||
40 | enum can_state state; | 41 | enum can_state state; |
@@ -45,6 +46,7 @@ struct can_priv { | |||
45 | struct timer_list restart_timer; | 46 | struct timer_list restart_timer; |
46 | 47 | ||
47 | int (*do_set_bittiming)(struct net_device *dev); | 48 | int (*do_set_bittiming)(struct net_device *dev); |
49 | int (*do_set_data_bittiming)(struct net_device *dev); | ||
48 | int (*do_set_mode)(struct net_device *dev, enum can_mode mode); | 50 | int (*do_set_mode)(struct net_device *dev, enum can_mode mode); |
49 | int (*do_get_state)(const struct net_device *dev, | 51 | int (*do_get_state)(const struct net_device *dev, |
50 | enum can_state *state); | 52 | enum can_state *state); |
diff --git a/include/uapi/linux/can/netlink.h b/include/uapi/linux/can/netlink.h index df944ed206a8..b41933d6bdcd 100644 --- a/include/uapi/linux/can/netlink.h +++ b/include/uapi/linux/can/netlink.h | |||
@@ -122,6 +122,8 @@ enum { | |||
122 | IFLA_CAN_RESTART_MS, | 122 | IFLA_CAN_RESTART_MS, |
123 | IFLA_CAN_RESTART, | 123 | IFLA_CAN_RESTART, |
124 | IFLA_CAN_BERR_COUNTER, | 124 | IFLA_CAN_BERR_COUNTER, |
125 | IFLA_CAN_DATA_BITTIMING, | ||
126 | IFLA_CAN_DATA_BITTIMING_CONST, | ||
125 | __IFLA_CAN_MAX | 127 | __IFLA_CAN_MAX |
126 | }; | 128 | }; |
127 | 129 | ||