|
@@ -647,6 +647,10 @@ static const struct nla_policy can_policy[IFLA_CAN_MAX + 1] = {
|
|
= { .len = sizeof(struct can_bittiming_const) },
|
|
= { .len = sizeof(struct can_bittiming_const) },
|
|
[IFLA_CAN_CLOCK] = { .len = sizeof(struct can_clock) },
|
|
[IFLA_CAN_CLOCK] = { .len = sizeof(struct can_clock) },
|
|
[IFLA_CAN_BERR_COUNTER] = { .len = sizeof(struct can_berr_counter) },
|
|
[IFLA_CAN_BERR_COUNTER] = { .len = sizeof(struct can_berr_counter) },
|
|
|
|
+ [IFLA_CAN_DATA_BITTIMING]
|
|
|
|
+ = { .len = sizeof(struct can_bittiming) },
|
|
|
|
+ [IFLA_CAN_DATA_BITTIMING_CONST]
|
|
|
|
+ = { .len = sizeof(struct can_bittiming_const) },
|
|
};
|
|
};
|
|
|
|
|
|
static int can_changelink(struct net_device *dev,
|
|
static int can_changelink(struct net_device *dev,
|
|
@@ -707,6 +711,27 @@ static int can_changelink(struct net_device *dev,
|
|
return err;
|
|
return err;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ if (data[IFLA_CAN_DATA_BITTIMING]) {
|
|
|
|
+ struct can_bittiming dbt;
|
|
|
|
+
|
|
|
|
+ /* Do not allow changing bittiming while running */
|
|
|
|
+ if (dev->flags & IFF_UP)
|
|
|
|
+ return -EBUSY;
|
|
|
|
+ memcpy(&dbt, nla_data(data[IFLA_CAN_DATA_BITTIMING]),
|
|
|
|
+ sizeof(dbt));
|
|
|
|
+ err = can_get_bittiming(dev, &dbt, priv->data_bittiming_const);
|
|
|
|
+ if (err)
|
|
|
|
+ return err;
|
|
|
|
+ memcpy(&priv->data_bittiming, &dbt, sizeof(dbt));
|
|
|
|
+
|
|
|
|
+ if (priv->do_set_data_bittiming) {
|
|
|
|
+ /* Finally, set the bit-timing registers */
|
|
|
|
+ err = priv->do_set_data_bittiming(dev);
|
|
|
|
+ if (err)
|
|
|
|
+ return err;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -725,6 +750,10 @@ static size_t can_get_size(const struct net_device *dev)
|
|
size += nla_total_size(sizeof(u32)); /* IFLA_CAN_RESTART_MS */
|
|
size += nla_total_size(sizeof(u32)); /* IFLA_CAN_RESTART_MS */
|
|
if (priv->do_get_berr_counter) /* IFLA_CAN_BERR_COUNTER */
|
|
if (priv->do_get_berr_counter) /* IFLA_CAN_BERR_COUNTER */
|
|
size += nla_total_size(sizeof(struct can_berr_counter));
|
|
size += nla_total_size(sizeof(struct can_berr_counter));
|
|
|
|
+ if (priv->data_bittiming.bitrate) /* IFLA_CAN_DATA_BITTIMING */
|
|
|
|
+ size += nla_total_size(sizeof(struct can_bittiming));
|
|
|
|
+ if (priv->data_bittiming_const) /* IFLA_CAN_DATA_BITTIMING_CONST */
|
|
|
|
+ size += nla_total_size(sizeof(struct can_bittiming_const));
|
|
|
|
|
|
return size;
|
|
return size;
|
|
}
|
|
}
|
|
@@ -738,20 +767,34 @@ static int can_fill_info(struct sk_buff *skb, const struct net_device *dev)
|
|
|
|
|
|
if (priv->do_get_state)
|
|
if (priv->do_get_state)
|
|
priv->do_get_state(dev, &state);
|
|
priv->do_get_state(dev, &state);
|
|
|
|
+
|
|
if ((priv->bittiming.bitrate &&
|
|
if ((priv->bittiming.bitrate &&
|
|
nla_put(skb, IFLA_CAN_BITTIMING,
|
|
nla_put(skb, IFLA_CAN_BITTIMING,
|
|
sizeof(priv->bittiming), &priv->bittiming)) ||
|
|
sizeof(priv->bittiming), &priv->bittiming)) ||
|
|
|
|
+
|
|
(priv->bittiming_const &&
|
|
(priv->bittiming_const &&
|
|
nla_put(skb, IFLA_CAN_BITTIMING_CONST,
|
|
nla_put(skb, IFLA_CAN_BITTIMING_CONST,
|
|
sizeof(*priv->bittiming_const), priv->bittiming_const)) ||
|
|
sizeof(*priv->bittiming_const), priv->bittiming_const)) ||
|
|
|
|
+
|
|
nla_put(skb, IFLA_CAN_CLOCK, sizeof(cm), &priv->clock) ||
|
|
nla_put(skb, IFLA_CAN_CLOCK, sizeof(cm), &priv->clock) ||
|
|
nla_put_u32(skb, IFLA_CAN_STATE, state) ||
|
|
nla_put_u32(skb, IFLA_CAN_STATE, state) ||
|
|
nla_put(skb, IFLA_CAN_CTRLMODE, sizeof(cm), &cm) ||
|
|
nla_put(skb, IFLA_CAN_CTRLMODE, sizeof(cm), &cm) ||
|
|
nla_put_u32(skb, IFLA_CAN_RESTART_MS, priv->restart_ms) ||
|
|
nla_put_u32(skb, IFLA_CAN_RESTART_MS, priv->restart_ms) ||
|
|
|
|
+
|
|
(priv->do_get_berr_counter &&
|
|
(priv->do_get_berr_counter &&
|
|
!priv->do_get_berr_counter(dev, &bec) &&
|
|
!priv->do_get_berr_counter(dev, &bec) &&
|
|
- nla_put(skb, IFLA_CAN_BERR_COUNTER, sizeof(bec), &bec)))
|
|
|
|
|
|
+ nla_put(skb, IFLA_CAN_BERR_COUNTER, sizeof(bec), &bec)) ||
|
|
|
|
+
|
|
|
|
+ (priv->data_bittiming.bitrate &&
|
|
|
|
+ nla_put(skb, IFLA_CAN_DATA_BITTIMING,
|
|
|
|
+ sizeof(priv->data_bittiming), &priv->data_bittiming)) ||
|
|
|
|
+
|
|
|
|
+ (priv->data_bittiming_const &&
|
|
|
|
+ nla_put(skb, IFLA_CAN_DATA_BITTIMING_CONST,
|
|
|
|
+ sizeof(*priv->data_bittiming_const),
|
|
|
|
+ priv->data_bittiming_const)))
|
|
return -EMSGSIZE;
|
|
return -EMSGSIZE;
|
|
|
|
+
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|