Skip to content

Commit

Permalink
Merge tag 'linux-can-fixes-for-6.0-20220928' of git://git.kernel.org/…
Browse files Browse the repository at this point in the history
…pub/scm/linux/kernel/git/mkl/linux-can

Marc Kleine-Budde says:

====================
pull-request: can 2022-09-28

The patch is by me and targets the c_can driver. It disables an
optimization in the TX path of C_CAN cores which causes problems.

* tag 'linux-can-fixes-for-6.0-20220928' of git://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can:
  can: c_can: don't cache TX messages for C_CAN cores
====================

Link: https://lore.kernel.org/r/20220928090629.1124190-1-mkl@pengutronix.de
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
  • Loading branch information
Jakub Kicinski committed Sep 28, 2022
2 parents 44d70bb + 81d192c commit af2faee
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 8 deletions.
17 changes: 15 additions & 2 deletions drivers/net/can/c_can/c_can.h
Original file line number Diff line number Diff line change
Expand Up @@ -235,9 +235,22 @@ static inline u8 c_can_get_tx_tail(const struct c_can_tx_ring *ring)
return ring->tail & (ring->obj_num - 1);
}

static inline u8 c_can_get_tx_free(const struct c_can_tx_ring *ring)
static inline u8 c_can_get_tx_free(const struct c_can_priv *priv,
const struct c_can_tx_ring *ring)
{
return ring->obj_num - (ring->head - ring->tail);
u8 head = c_can_get_tx_head(ring);
u8 tail = c_can_get_tx_tail(ring);

if (priv->type == BOSCH_D_CAN)
return ring->obj_num - (ring->head - ring->tail);

/* This is not a FIFO. C/D_CAN sends out the buffers
* prioritized. The lowest buffer number wins.
*/
if (head < tail)
return 0;

return ring->obj_num - head;
}

#endif /* C_CAN_H */
11 changes: 5 additions & 6 deletions drivers/net/can/c_can/c_can_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -429,15 +429,15 @@ static void c_can_setup_receive_object(struct net_device *dev, int iface,
static bool c_can_tx_busy(const struct c_can_priv *priv,
const struct c_can_tx_ring *tx_ring)
{
if (c_can_get_tx_free(tx_ring) > 0)
if (c_can_get_tx_free(priv, tx_ring) > 0)
return false;

netif_stop_queue(priv->dev);

/* Memory barrier before checking tx_free (head and tail) */
smp_mb();

if (c_can_get_tx_free(tx_ring) == 0) {
if (c_can_get_tx_free(priv, tx_ring) == 0) {
netdev_dbg(priv->dev,
"Stopping tx-queue (tx_head=0x%08x, tx_tail=0x%08x, len=%d).\n",
tx_ring->head, tx_ring->tail,
Expand Down Expand Up @@ -465,7 +465,7 @@ static netdev_tx_t c_can_start_xmit(struct sk_buff *skb,

idx = c_can_get_tx_head(tx_ring);
tx_ring->head++;
if (c_can_get_tx_free(tx_ring) == 0)
if (c_can_get_tx_free(priv, tx_ring) == 0)
netif_stop_queue(dev);

if (idx < c_can_get_tx_tail(tx_ring))
Expand Down Expand Up @@ -748,7 +748,7 @@ static void c_can_do_tx(struct net_device *dev)
return;

tx_ring->tail += pkts;
if (c_can_get_tx_free(tx_ring)) {
if (c_can_get_tx_free(priv, tx_ring)) {
/* Make sure that anybody stopping the queue after
* this sees the new tx_ring->tail.
*/
Expand All @@ -760,8 +760,7 @@ static void c_can_do_tx(struct net_device *dev)
stats->tx_packets += pkts;

tail = c_can_get_tx_tail(tx_ring);

if (tail == 0) {
if (priv->type == BOSCH_D_CAN && tail == 0) {
u8 head = c_can_get_tx_head(tx_ring);

/* Start transmission for all cached messages */
Expand Down

0 comments on commit af2faee

Please sign in to comment.