can: dev: can_free_echo_skb(): extend to return can frame length
authorMarc Kleine-Budde <mkl@pengutronix.de>
Fri, 19 Mar 2021 14:21:32 +0000 (15:21 +0100)
committerMarc Kleine-Budde <mkl@pengutronix.de>
Tue, 30 Mar 2021 09:14:28 +0000 (11:14 +0200)
In order to implement byte queue limits (bql) in CAN drivers, the
length of the CAN frame needs to be passed into the networking stack
even if the transmission failed for some reason.

To avoid to calculate this length twice, extend can_free_echo_skb() to
return that value. Convert all users of this function, too.

This patch is the natural extension of commit:

9420e1d495e2 ("can: dev: can_get_echo_skb(): extend to return can
|                frame length")

Link: https://lore.kernel.org/r/20210319142700.305648-3-mkl@pengutronix.de
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
17 files changed:
drivers/net/can/dev/skb.c
drivers/net/can/grcan.c
drivers/net/can/m_can/m_can.c
drivers/net/can/rcar/rcar_can.c
drivers/net/can/rcar/rcar_canfd.c
drivers/net/can/sja1000/sja1000.c
drivers/net/can/spi/hi311x.c
drivers/net/can/spi/mcp251x.c
drivers/net/can/usb/ems_usb.c
drivers/net/can/usb/esd_usb2.c
drivers/net/can/usb/gs_usb.c
drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c
drivers/net/can/usb/mcba_usb.c
drivers/net/can/usb/peak_usb/pcan_usb_core.c
drivers/net/can/usb/ucan.c
drivers/net/can/usb/usb_8dev.c
include/linux/can/skb.h

index 2256391ddbb3e19a069f3657d7dadee8c7047873..387c0bc0fb9c4fdabf5fc2d1b5476a2c61378d22 100644 (file)
@@ -153,7 +153,8 @@ EXPORT_SYMBOL_GPL(can_get_echo_skb);
  *
  * The function is typically called when TX failed.
  */
-void can_free_echo_skb(struct net_device *dev, unsigned int idx)
+void can_free_echo_skb(struct net_device *dev, unsigned int idx,
+                      unsigned int *frame_len_ptr)
 {
        struct can_priv *priv = netdev_priv(dev);
 
@@ -164,7 +165,13 @@ void can_free_echo_skb(struct net_device *dev, unsigned int idx)
        }
 
        if (priv->echo_skb[idx]) {
-               dev_kfree_skb_any(priv->echo_skb[idx]);
+               struct sk_buff *skb = priv->echo_skb[idx];
+               struct can_skb_priv *can_skb_priv = can_skb_prv(skb);
+
+               if (frame_len_ptr)
+                       *frame_len_ptr = can_skb_priv->frame_len;
+
+               dev_kfree_skb_any(skb);
                priv->echo_skb[idx] = NULL;
        }
 }
index 4a8453290530921a8cb265355edfb54c3abf2905..78e27940b2affe44f9999f1cbaef4b0b875bd306 100644 (file)
@@ -520,7 +520,7 @@ static int catch_up_echo_skb(struct net_device *dev, int budget, bool echo)
                        can_get_echo_skb(dev, i, NULL);
                } else {
                        /* For cleanup of untransmitted messages */
-                       can_free_echo_skb(dev, i);
+                       can_free_echo_skb(dev, i, NULL);
                }
 
                priv->eskbp = grcan_ring_add(priv->eskbp, GRCAN_MSG_SIZE,
index 0c8d36bc668c8219ce134a7b7736bda771f5fcd1..2ae3da16cbfe84ec08b6b662c2ae0823e1625856 100644 (file)
@@ -425,7 +425,7 @@ static void m_can_clean(struct net_device *net)
                        putidx = ((m_can_read(cdev, M_CAN_TXFQS) &
                                   TXFQS_TFQPI_MASK) >> TXFQS_TFQPI_SHIFT);
 
-               can_free_echo_skb(cdev->net, putidx);
+               can_free_echo_skb(cdev->net, putidx, NULL);
                cdev->tx_skb = NULL;
        }
 }
index 4870c4ea190a9b32bc6b2fcbd69209347f09d2c2..00e4533c8bddcdb89606aa8d588e89965e2a86af 100644 (file)
@@ -217,7 +217,7 @@ static void tx_failure_cleanup(struct net_device *ndev)
        int i;
 
        for (i = 0; i < RCAR_CAN_FIFO_DEPTH; i++)
-               can_free_echo_skb(ndev, i);
+               can_free_echo_skb(ndev, i, NULL);
 }
 
 static void rcar_can_error(struct net_device *ndev)
index d8d233e629904ddfbba5689c99a5430e8cf1b2ec..311e6ca3bdc41aedfe3722b32e8fc099e05602e6 100644 (file)
@@ -617,7 +617,7 @@ static void rcar_canfd_tx_failure_cleanup(struct net_device *ndev)
        u32 i;
 
        for (i = 0; i < RCANFD_FIFO_DEPTH; i++)
-               can_free_echo_skb(ndev, i);
+               can_free_echo_skb(ndev, i, NULL);
 }
 
 static int rcar_canfd_reset_controller(struct rcar_canfd_global *gpriv)
index 9e86488ba55f17cb674d0482be9397611c5819a4..3fad546467461df5ed0ddfa9588c55c5e2576d07 100644 (file)
@@ -525,7 +525,7 @@ irqreturn_t sja1000_interrupt(int irq, void *dev_id)
                        if (priv->can.ctrlmode & CAN_CTRLMODE_ONE_SHOT &&
                            !(status & SR_TCS)) {
                                stats->tx_errors++;
-                               can_free_echo_skb(dev, 0);
+                               can_free_echo_skb(dev, 0, NULL);
                        } else {
                                /* transmission complete */
                                stats->tx_bytes +=
index c3e020c901116634f50b50cdf29f199128686b72..6f5d6d04a8b969835e7151fc883d30e98c2a2a52 100644 (file)
@@ -179,7 +179,7 @@ static void hi3110_clean(struct net_device *net)
                net->stats.tx_errors++;
        dev_kfree_skb(priv->tx_skb);
        if (priv->tx_len)
-               can_free_echo_skb(priv->net, 0);
+               can_free_echo_skb(priv->net, 0, NULL);
        priv->tx_skb = NULL;
        priv->tx_len = 0;
 }
index f69fb4238a654cb31c70ed2bcda663dc072abced..80ab1593ca31d12d025bf755940fe76b011e5b0e 100644 (file)
@@ -276,7 +276,7 @@ static void mcp251x_clean(struct net_device *net)
                net->stats.tx_errors++;
        dev_kfree_skb(priv->tx_skb);
        if (priv->tx_len)
-               can_free_echo_skb(priv->net, 0);
+               can_free_echo_skb(priv->net, 0, NULL);
        priv->tx_skb = NULL;
        priv->tx_len = 0;
 }
index 18f40eb203605a55620f08f3e43f609271549fbe..5af69787d9d5d4ac54e3a0b67ec17f516fbeeb16 100644 (file)
@@ -807,7 +807,7 @@ static netdev_tx_t ems_usb_start_xmit(struct sk_buff *skb, struct net_device *ne
 
        err = usb_submit_urb(urb, GFP_ATOMIC);
        if (unlikely(err)) {
-               can_free_echo_skb(netdev, context->echo_index);
+               can_free_echo_skb(netdev, context->echo_index, NULL);
 
                usb_unanchor_urb(urb);
                usb_free_coherent(dev->udev, size, buf, urb->transfer_dma);
index 562acbf454fd63d490963c4477a2f8476276a149..65b58f8fc3287cd046629dd18cc0a964d558a63e 100644 (file)
@@ -360,7 +360,7 @@ static void esd_usb2_tx_done_msg(struct esd_usb2_net_priv *priv,
                can_get_echo_skb(netdev, context->echo_index, NULL);
        } else {
                stats->tx_errors++;
-               can_free_echo_skb(netdev, context->echo_index);
+               can_free_echo_skb(netdev, context->echo_index, NULL);
        }
 
        /* Release context */
@@ -793,7 +793,7 @@ static netdev_tx_t esd_usb2_start_xmit(struct sk_buff *skb,
 
        err = usb_submit_urb(urb, GFP_ATOMIC);
        if (err) {
-               can_free_echo_skb(netdev, context->echo_index);
+               can_free_echo_skb(netdev, context->echo_index, NULL);
 
                atomic_dec(&priv->active_tx_jobs);
                usb_unanchor_urb(urb);
index a00dc19044151f342fa13d77f30804a6303c66ea..5e892bef46b0067908c444ad8960c63532b0faaa 100644 (file)
@@ -533,7 +533,7 @@ static netdev_tx_t gs_can_start_xmit(struct sk_buff *skb,
        if (unlikely(rc)) {                     /* usb send failed */
                atomic_dec(&dev->active_tx_urbs);
 
-               can_free_echo_skb(netdev, idx);
+               can_free_echo_skb(netdev, idx, NULL);
                gs_free_tx_context(txc);
 
                usb_unanchor_urb(urb);
index 4e97da8434ab5bf815ad96b07c5da60eb78d0781..90ebcae13409b93310401777b5b3b5c381489b26 100644 (file)
@@ -593,7 +593,7 @@ static netdev_tx_t kvaser_usb_start_xmit(struct sk_buff *skb,
        if (unlikely(err)) {
                spin_lock_irqsave(&priv->tx_contexts_lock, flags);
 
-               can_free_echo_skb(netdev, context->echo_index);
+               can_free_echo_skb(netdev, context->echo_index, NULL);
                context->echo_index = dev->max_tx_urbs;
                --priv->active_tx_contexts;
                netif_wake_queue(netdev);
index 1f649d17801074873b82c73be89818b982f1e484..029e77dfa773b6c91e2bdf6b0afd61012ddcba37 100644 (file)
@@ -364,7 +364,7 @@ static netdev_tx_t mcba_usb_start_xmit(struct sk_buff *skb,
        return NETDEV_TX_OK;
 
 xmit_failed:
-       can_free_echo_skb(priv->netdev, ctx->ndx);
+       can_free_echo_skb(priv->netdev, ctx->ndx, NULL);
        mcba_usb_free_ctx(ctx);
        dev_kfree_skb(skb);
        stats->tx_dropped++;
index 573b11559d733fc5328130fced5f910b8b81334e..29227b5851fea4b0d7679b4232434f8c1df6f7fa 100644 (file)
@@ -371,7 +371,7 @@ static netdev_tx_t peak_usb_ndo_start_xmit(struct sk_buff *skb,
 
        err = usb_submit_urb(urb, GFP_ATOMIC);
        if (err) {
-               can_free_echo_skb(netdev, context->echo_index);
+               can_free_echo_skb(netdev, context->echo_index, NULL);
 
                usb_unanchor_urb(urb);
 
index fa403c080871e16355fd71187b0b32f2e444dbe0..11fddedc36d4892478ff17a63d3dbc70b047535d 100644 (file)
@@ -675,7 +675,7 @@ static void ucan_tx_complete_msg(struct ucan_priv *up,
                        can_get_echo_skb(up->netdev, echo_index, NULL);
                } else {
                        up->netdev->stats.tx_dropped++;
-                       can_free_echo_skb(up->netdev, echo_index);
+                       can_free_echo_skb(up->netdev, echo_index, NULL);
                }
                spin_unlock_irqrestore(&up->echo_skb_lock, flags);
        }
@@ -843,7 +843,7 @@ static void ucan_write_bulk_callback(struct urb *urb)
 
                /* update counters an cleanup */
                spin_lock_irqsave(&up->echo_skb_lock, flags);
-               can_free_echo_skb(up->netdev, context - up->context_array);
+               can_free_echo_skb(up->netdev, context - up->context_array, NULL);
                spin_unlock_irqrestore(&up->echo_skb_lock, flags);
 
                up->netdev->stats.tx_dropped++;
@@ -1157,7 +1157,7 @@ static netdev_tx_t ucan_start_xmit(struct sk_buff *skb,
                 * frees the skb
                 */
                spin_lock_irqsave(&up->echo_skb_lock, flags);
-               can_free_echo_skb(up->netdev, echo_index);
+               can_free_echo_skb(up->netdev, echo_index, NULL);
                spin_unlock_irqrestore(&up->echo_skb_lock, flags);
 
                if (ret == -ENODEV) {
index e8c42430a4fcd3bc52add08c0b762db69dd113dd..b6e7ef0d5bc69249ad548fe47e0980a822b22afe 100644 (file)
@@ -691,7 +691,7 @@ nofreecontext:
        return NETDEV_TX_BUSY;
 
 failed:
-       can_free_echo_skb(netdev, context->echo_index);
+       can_free_echo_skb(netdev, context->echo_index, NULL);
 
        usb_unanchor_urb(urb);
        usb_free_coherent(priv->udev, size, buf, urb->transfer_dma);
index d438eb058069b1c420473cb2cedee5d0b78eed4a..d311bc369a3968f7faf80763feb1628a285db22f 100644 (file)
@@ -23,7 +23,8 @@ struct sk_buff *__can_get_echo_skb(struct net_device *dev, unsigned int idx,
                                   u8 *len_ptr, unsigned int *frame_len_ptr);
 unsigned int can_get_echo_skb(struct net_device *dev, unsigned int idx,
                              unsigned int *frame_len_ptr);
-void can_free_echo_skb(struct net_device *dev, unsigned int idx);
+void can_free_echo_skb(struct net_device *dev, unsigned int idx,
+                      unsigned int *frame_len_ptr);
 struct sk_buff *alloc_can_skb(struct net_device *dev, struct can_frame **cf);
 struct sk_buff *alloc_canfd_skb(struct net_device *dev,
                                struct canfd_frame **cfd);