@@ -414,8 +414,17 @@ static int can_tdc_fill_info(struct sk_buff *skb, const struct net_device *dev)
goto err_cancel;
if (can_tdc_is_enabled(priv)) {
- if (priv->ctrlmode & CAN_CTRLMODE_TDC_MANUAL &&
- nla_put_u32(skb, IFLA_CAN_TDC_TDCV, tdc->tdcv))
+ u32 tdcv;
+ int err = -EINVAL;
+
+ if (priv->ctrlmode & CAN_CTRLMODE_TDC_MANUAL) {
+ tdcv = tdc->tdcv;
+ err = 0;
+ } else if (priv->ctrlmode & CAN_CTRLMODE_TDC_AUTO &&
+ priv->do_get_auto_tdcv) {
+ err = priv->do_get_auto_tdcv(dev, &tdcv);
+ }
+ if (!err && nla_put_u32(skb, IFLA_CAN_TDC_TDCV, tdcv))
goto err_cancel;
if (nla_put_u32(skb, IFLA_CAN_TDC_TDCO, tdc->tdco))
goto err_cancel;
@@ -74,6 +74,7 @@ struct can_priv {
enum can_state *state);
int (*do_get_berr_counter)(const struct net_device *dev,
struct can_berr_counter *bec);
+ int (*do_get_auto_tdcv)(const struct net_device *dev, u32 *tdcv);
unsigned int echo_skb_max;
struct sk_buff **echo_skb;
Some CAN device can measure the TDCV (Transmission Delay Compensation Value) automatically for each transmitted CAN frames. A callback function do_get_auto_tdcv() is added to retrieve that value. This function is used only if CAN_CTRLMODE_TDC_AUTO is enabled (if CAN_CTRLMODE_TDC_MANUAL is selected, the TDCV value is provided by the user). If the device does not support reporting of TDCV, do_get_auto_tdcv() should be set to NULL and TDCV will not be reported by the netlink interface. On success, do_get_auto_tdcv() shall return 0. If the value can not be measured by the device, for example because network is down or because no frames were transmitted yet, can_priv::do_get_auto_tdcv() shall return a negative error code (e.g. -EINVAL) to signify that the value is not yet available. In such cases, TDCV is not reported by the netlink interface. CC: Stefan Mätje <stefan.maetje@esd.eu> Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr> --- drivers/net/can/dev/netlink.c | 13 +++++++++++-- include/linux/can/dev.h | 1 + 2 files changed, 12 insertions(+), 2 deletions(-)