Re: AW: [PATCH RFC can v2] can: mcp251xfd: mcp251xfd_get_tef_len(): fix length calculation

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 05.11.2024 18:53:49, Renjaya Raga Zenta wrote:
> > Please add this patch, compile, reproduce the issue, send me the
> > devcoredump and the log output.
> 
> > >
> > --- a/drivers/net/can/spi/mcp251xfd/mcp251xfd-tef.c
> > +++ b/drivers/net/can/spi/mcp251xfd/mcp251xfd-tef.c
> > @@ -149,6 +149,10 @@ mcp251xfd_get_tef_len(struct mcp251xfd_priv *priv, u8 *len_p)
> >          len = (chip_tx_tail << shift) - (tail << shift);
> >          *len_p = len >> shift;
> >
> > +        if (*len_p == 0)
> > +                netdev_err(priv->ndev, "%s: fifo_sta=0x%08x head=0x%08x tail=0x%08x\n", __func__,
> > +                           fifo_sta, tx_ring->head, tx_ring->tail);
> > +
> >          return 0;
> >  }
> 
> I applied this patch manually because it couldn't be applied after your
> "mcp251xfd_get_tef_len(): fix length calculation" patch.
> 
> The log (dmesg | grep spi)
> [  125.501493] mcp251xfd spi0.0 can1: mcp251xfd_get_tef_len: fifo_sta=0x00000103 head=0x00004a95 tail=0x00004a91
> [  125.511420] mcp251xfd spi0.0 can1: IRQ handler mcp251xfd_handle_tefif() returned -22.
> [  125.519250] mcp251xfd spi0.0 can1: IRQ handler returned -22 (intf=0xbf1a0010).
> 
> The devcoredump file is attached.

To me it seems the TX-FIFO STA register is not consistent at this point,
this is likely another manifestation of the mcp2518fd erratum
DS80000789E 6.

The TX-FIFO and the Transmit Event FIFO (TEF) are implemented as ring
buffers in hardware. They work on a buffer in the chip's memory, with a
head and tail index.

From the driver's point of view the TX-queue is full, the TX-FIFO with
depth 4 is completely filled, the head and tail indexes have a
difference of 4 (head=0x00004a95 tail=0x00004a91). The driver is waiting
for TX complete events.

Here, the chip has successfully send at least 1 CAN frame, puts that
information in the Transmit Event FIFO (TEF) and rises a TX Event FIFO
not empty interrupt.

The driver handles this interrupt in the mcp251xfd_handle_tefif()
function. It reads the TX-FIFO STA register (sic! TX-FIFO) and tries to
figure out the fill level of the TEF. (Note: The RX-FIFO has head
index in the STA register, the TEF, doesn't.)

The trick to figure out the fill level of the TEF, is to look at the
tail index of the TX FIFO. The tail index is the next CAN frame that
the chip will send. The driver assumes that all CAN frames before that
have been send. This means the TX-tail index should equal the TEF-head
index. The difference between the TEF-head and TEF-tail would be the
fill level of the TEF.

According to the debug message, the TX-FIFO STA register shows a TX tail
index of 1 and the other bits show that the TX FIFO is _not_ empty.

Looking at the driver's version of the TX indexes:

| head=0x00004a95
| tail=0x00004a91

With the here configured FIFO depth of 4, both indexes would be "1" in
hardware. This means the TX-FIFO could either be full or empty. "TX-FIFO
full" makes no sense, as the driver is right now handling the "TEF not
empty" interrupt. (In order to have an event in the TEF, a CAN frame
must have been send, so the TX-FIFO cannot be full.)

But the bits in the TX-FIFO STA also tell us the TX-FIFO is not empty
either (TFERFFIF is not set).

From the debug message:

|          fifosta      =0x00000103 
|           FIFOCI =   1		FIFO Message Index
|         TFERFFIF    		Transmit/Receive FIFO Empty/Full Interrupt Flag
|         TFHRFHIF   x		Transmit/Receive FIFO Half Empty/Half Full Interrupt Flag
|         TFNRFNIF   x		Transmit/Receive FIFO Not Full/Not Empty Interrupt Flag

This is inconsistent and the driver bails out. Then it creates a dump of
the registers:

| FIFOSTA: fifosta(0x078)=0x00000107
|           FIFOCI =   1		FIFO Message Index
|         TFERFFIF   x		Transmit/Receive FIFO Empty/Full Interrupt Flag
|         TFHRFHIF   x		Transmit/Receive FIFO Half Empty/Half Full Interrupt Flag
|         TFNRFNIF   x		Transmit/Receive FIFO Not Full/Not Empty Interrupt Flag

We see that the TFERFFIF _is_ set. Note: It takes some time between the
initial read of the TX-FIFO STA and the reading of the TX-FIFO STA
register for the dump.

I've just send a patch [1] to work around this issue. However not
tested, as I cannot reproduce the problem here.

[1] https://patch.msgid.link/20241125-mcp251xfd-fix-length-calculation-v1-1-974445b5f893@xxxxxxxxxxxxxx

regards,
Marc

-- 
Pengutronix e.K.                 | Marc Kleine-Budde          |
Embedded Linux                   | https://www.pengutronix.de |
Vertretung Nürnberg              | Phone: +49-5121-206917-129 |
Amtsgericht Hildesheim, HRA 2686 | Fax:   +49-5121-206917-9   |

Attachment: signature.asc
Description: PGP signature


[Index of Archives]     [Automotive Discussions]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Security]     [Bugtraq]     [Linux]     [Linux OMAP]     [Linux MIPS]     [eCos]     [Asterisk Internet PBX]     [Linux API]     [CAN Bus]

  Powered by Linux