aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/can/dev.c45
-rw-r--r--include/linux/can/dev.h6
-rw-r--r--include/uapi/linux/can/netlink.h2
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
652static int can_changelink(struct net_device *dev, 656static 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 {
33struct can_priv { 33struct 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