summaryrefslogtreecommitdiffstats
path: root/drivers/net/can/dev.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/can/dev.c')
-rw-r--r--drivers/net/can/dev.c42
1 files changed, 40 insertions, 2 deletions
diff --git a/drivers/net/can/dev.c b/drivers/net/can/dev.c
index e1a4f821423..2868fe842a4 100644
--- a/drivers/net/can/dev.c
+++ b/drivers/net/can/dev.c
@@ -315,7 +315,7 @@ void can_get_echo_skb(struct net_device *dev, int idx)
{
struct can_priv *priv = netdev_priv(dev);
- if ((dev->flags & IFF_ECHO) && priv->echo_skb[idx]) {
+ if (priv->echo_skb[idx]) {
netif_rx(priv->echo_skb[idx]);
priv->echo_skb[idx] = NULL;
}
@@ -323,6 +323,22 @@ void can_get_echo_skb(struct net_device *dev, int idx)
EXPORT_SYMBOL_GPL(can_get_echo_skb);
/*
+ * Remove the skb from the stack and free it.
+ *
+ * The function is typically called when TX failed.
+ */
+void can_free_echo_skb(struct net_device *dev, int idx)
+{
+ struct can_priv *priv = netdev_priv(dev);
+
+ if (priv->echo_skb[idx]) {
+ kfree_skb(priv->echo_skb[idx]);
+ priv->echo_skb[idx] = NULL;
+ }
+}
+EXPORT_SYMBOL_GPL(can_free_echo_skb);
+
+/*
* CAN device restart for bus-off recovery
*/
void can_restart(unsigned long data)
@@ -357,7 +373,6 @@ void can_restart(unsigned long data)
netif_rx(skb);
- dev->last_rx = jiffies;
stats->rx_packets++;
stats->rx_bytes += cf->can_dlc;
@@ -574,6 +589,22 @@ static int can_changelink(struct net_device *dev,
return 0;
}
+static size_t can_get_size(const struct net_device *dev)
+{
+ struct can_priv *priv = netdev_priv(dev);
+ size_t size;
+
+ size = nla_total_size(sizeof(u32)); /* IFLA_CAN_STATE */
+ size += sizeof(struct can_ctrlmode); /* IFLA_CAN_CTRLMODE */
+ size += nla_total_size(sizeof(u32)); /* IFLA_CAN_RESTART_MS */
+ size += sizeof(struct can_bittiming); /* IFLA_CAN_BITTIMING */
+ size += sizeof(struct can_clock); /* IFLA_CAN_CLOCK */
+ if (priv->bittiming_const) /* IFLA_CAN_BITTIMING_CONST */
+ size += sizeof(struct can_bittiming_const);
+
+ return size;
+}
+
static int can_fill_info(struct sk_buff *skb, const struct net_device *dev)
{
struct can_priv *priv = netdev_priv(dev);
@@ -598,6 +629,11 @@ nla_put_failure:
return -EMSGSIZE;
}
+static size_t can_get_xstats_size(const struct net_device *dev)
+{
+ return sizeof(struct can_device_stats);
+}
+
static int can_fill_xstats(struct sk_buff *skb, const struct net_device *dev)
{
struct can_priv *priv = netdev_priv(dev);
@@ -624,7 +660,9 @@ static struct rtnl_link_ops can_link_ops __read_mostly = {
.setup = can_setup,
.newlink = can_newlink,
.changelink = can_changelink,
+ .get_size = can_get_size,
.fill_info = can_fill_info,
+ .get_xstats_size = can_get_xstats_size,
.fill_xstats = can_fill_xstats,
};