diff options
Diffstat (limited to 'drivers/net/can/dev/dev.c')
-rw-r--r-- | drivers/net/can/dev/dev.c | 31 |
1 files changed, 17 insertions, 14 deletions
diff --git a/drivers/net/can/dev/dev.c b/drivers/net/can/dev/dev.c index 43125ce96f1a..89f80d74f27e 100644 --- a/drivers/net/can/dev/dev.c +++ b/drivers/net/can/dev/dev.c @@ -125,13 +125,16 @@ void can_change_state(struct net_device *dev, struct can_frame *cf, EXPORT_SYMBOL_GPL(can_change_state); /* CAN device restart for bus-off recovery */ -static void can_restart(struct net_device *dev) +static int can_restart(struct net_device *dev) { struct can_priv *priv = netdev_priv(dev); struct sk_buff *skb; struct can_frame *cf; int err; + if (!priv->do_set_mode) + return -EOPNOTSUPP; + if (netif_carrier_ok(dev)) netdev_err(dev, "Attempt to restart for bus-off recovery, but carrier is OK?\n"); @@ -142,24 +145,25 @@ static void can_restart(struct net_device *dev) /* send restart message upstream */ skb = alloc_can_err_skb(dev, &cf); - if (!skb) - goto restart; - - cf->can_id |= CAN_ERR_RESTARTED; - - netif_rx(skb); - -restart: - netdev_dbg(dev, "restarted\n"); - priv->can_stats.restarts++; + if (skb) { + cf->can_id |= CAN_ERR_RESTARTED; + netif_rx(skb); + } /* Now restart the device */ netif_carrier_on(dev); err = priv->do_set_mode(dev, CAN_MODE_START); if (err) { - netdev_err(dev, "Error %d during restart", err); + netdev_err(dev, "Restart failed, error %pe\n", ERR_PTR(err)); netif_carrier_off(dev); + + return err; + } else { + netdev_dbg(dev, "Restarted\n"); + priv->can_stats.restarts++; } + + return 0; } static void can_restart_work(struct work_struct *work) @@ -184,9 +188,8 @@ int can_restart_now(struct net_device *dev) return -EBUSY; cancel_delayed_work_sync(&priv->restart_work); - can_restart(dev); - return 0; + return can_restart(dev); } /* CAN bus-off |