Dear All,
I'm experiencing lost frames and id 0, 8 byte all zero packets now that we have 
equipment sending back to back packets on a 250Kb network.
I have plenty of hardware attached to Gumstix Overos so I'll test your patch 
once the kernel is rebuilt.

Cheers Mike.

-----Original Message-----
From: [email protected] 
[mailto:[email protected]] On Behalf Of christian 
pellegrin
Sent: Thursday, 2 September 2010 02:36
To: Benny B. Simonsen
Cc: [email protected]
Subject: Re: [Socketcan-users] MCP 2515 RX problems

Hi, first of all sorry for the late response. Just now I managed to put 
together the needed hardware (you know, in Italy it's near impossible to do 
anything not related to holidays in august ;-) )

I had a quick look at your patch and it's similar to the one I prepared and I'm 
attaching below. I think both of them solve the problem with out of order 
frame. What is worrying me is that packet with all zeros. I never saw something 
similar. I'll put my system on test during the next night to see if I can 
reproduce it. I guess you put the code to reset RX flags in case of error to 
try to solve this glitch, didn't you?

Anyway I will try your patch tomorrow.

diff --git a/drivers/net/can/mcp251x.c b/drivers/net/can/mcp251x.c index 
177f2e1..e8c5e37 100644
--- a/drivers/net/can/mcp251x.c
+++ b/drivers/net/can/mcp251x.c
@@ -773,8 +773,9 @@ static irqreturn_t mcp251x_can_ist(int irq, void *dev_id)
        struct mcp251x_priv *priv = dev_id;
        struct spi_device *spi = priv->spi;
        struct net_device *net = priv->net;
+       u8 intf;
 #ifdef STATS
-       static int irqs, runs, ov0, ov1, rx0, rx1;
+       static int irqs, runs;
        static int ee[8], ii[8];
        static unsigned long last;
        unsigned long now;
@@ -788,7 +789,7 @@ static irqreturn_t mcp251x_can_ist(int irq, void *dev_id)
                now = jiffies;
                if (now >= last + HZ) {
                        last = now;
-                       printk("%lu: i %d r %d r0 %d r1 %d o0 %d o1 %d err", 
now, irqs,
runs, rx0, rx1, ov0, ov1);
+                       printk("%lu: i %d r %d err", now, irqs, runs);
                        for(i = 0; i < 8; i++) {
                                printk(",%d", ee[i]);
                                ee[i] = 0;
@@ -799,24 +800,20 @@ static irqreturn_t mcp251x_can_ist(int irq, void *dev_id)
                                ii[i] = 0;
                        }
                        printk("\n");
-                       irqs = runs = rx0 = rx1 = ov0 = ov1 = 0;
+                       irqs = runs = 0;
                }
        }
        irqs += 1;
 #endif

        mutex_lock(&priv->mcp_lock);
-       while (!priv->force_quit) {
+       intf = mcp251x_read_reg(spi, CANINTF);
+       do {
                enum can_state new_state;
-               u8 intf = mcp251x_read_reg(spi, CANINTF);
-               u8 eflag;
+               u8 eflag = 0;
                int can_id = 0, data1 = 0;
 #ifdef STATS
                runs += 1;
-               if (intf & CANINTF_RX0IF)
-                       rx0 += 1;
-               if (intf & CANINTF_RX1IF)
-                       rx1 += 1;
                {
                        int i;
                        for(i = 0; i < 8; i++) {
@@ -828,25 +825,31 @@ static irqreturn_t mcp251x_can_ist(int irq, void *dev_id)

                if (intf & CANINTF_RX0IF) {
                        mcp251x_hw_rx(spi, 0);
-                       /* Free one buffer ASAP */
-                       mcp251x_write_bits(spi, CANINTF, intf & CANINTF_RX0IF,
-                                          0x00);
+
+                       /* check that a packet didn't come while emptying RX0 */
+                       if ((intf & CANINTF_RX1IF) == 0)
+                               intf |= mcp251x_read_reg(spi, CANINTF);
                }

                if (intf & CANINTF_RX1IF)
                        mcp251x_hw_rx(spi, 1);

+               /* This is needed to close a race condition that causes
+                * packet reordening: we must assure that we never empty
+                * RX0 but not RX1. If this happens the next packet will
+                * land in RX0. As a conseuqence on the next do { } while
+                * spin we will have packets out of order.
+                */
+               intf |= CANINTF_RX1IF;
+
                mcp251x_write_bits(spi, CANINTF, intf, 0x00);

-               eflag = mcp251x_read_reg(spi, EFLG);
-               mcp251x_write_reg(spi, EFLG, 0x00);
+               if (intf && CANINTF_ERRIF) {
+                       eflag = mcp251x_read_reg(spi, EFLG);
+                       mcp251x_write_reg(spi, EFLG, 0x00);
+               }

 #ifdef STATS
-               if (eflag & EFLG_RX0OVR)
-                       ov0 += 1;
-
-               if (eflag & EFLG_RX1OVR)
-                       ov1 += 1;
                {
                        int i;
                        for(i = 0; i < 8; i++) {
@@ -924,9 +927,6 @@ static irqreturn_t mcp251x_can_ist(int irq, void *dev_id)
                        }
                }

-               if (intf == 0)
-                       break;
-
                if (intf & (CANINTF_TX2IF | CANINTF_TX1IF | CANINTF_TX0IF)) {
                        net->stats.tx_packets++;
                        net->stats.tx_bytes += priv->tx_len - 1; @@ -936,7 
+936,8 @@ static irqreturn_t mcp251x_can_ist(int irq, void *dev_id)
                        }
                        netif_wake_queue(net);
                }
-       }
+               intf = mcp251x_read_reg(spi, CANINTF);
+       } while (!priv->force_quit && intf);
        mutex_unlock(&priv->mcp_lock);
        return IRQ_HANDLED;
 }



On Sat, Aug 28, 2010 at 2:20 PM, Benny B. Simonsen <[email protected]> wrote:
>
>
> 2010/8/6 christian pellegrin <[email protected]>
>>
>> On Fri, Aug 6, 2010 at 3:56 PM, Wolfgang Grandegger 
>> <[email protected]>
>> wrote:
>> > To be clear, out-of-order messages are also not OK.
>>
>> Yes I was looking at this with some interleave analysis. I think the 
>> problem lies in the following race:
>>
>> // suppose we come here with RXB0 filled with packet X
>>                u8 intf = mcp251x_read_reg(spi, CANINTF);
>>                u8 eflag;
>>                int can_id = 0, data1 = 0;
>>
>> // packet X+1 arrives and lands in RXB1
>>
>>                if (intf & CANINTF_RX0IF) {
>>                        mcp251x_hw_rx(spi, 0);
>>                        /* Free one buffer ASAP */
>>                        mcp251x_write_bits(spi, CANINTF, intf & 
>> CANINTF_RX0IF,
>>                                           0x00);
>>                }
>>
>> // packet X+2 arrives and lands in RXB0 // unfortunately variable 
>> intf is old and doesn't show that we have something in RXB1 // (*1)
>>                if (intf & CANINTF_RX1IF)
>>                        mcp251x_hw_rx(spi, 1);
>>
>> now on the next turn we will have packet X+2 in RXB0 and X+1 in RXB1 
>> so we read them out-of-order. The easiest way to solve the problem is 
>> to take out the line:
>>
>>                        /* Free one buffer ASAP */
>>                        mcp251x_write_bits(spi, CANINTF, intf & 
>> CANINTF_RX0IF,
>>                                           0x00);
>>
>> but we risk to lose more packets. Perhaps also rereading intf in (*1) 
>> could work but we must be careful when we reset CANINTF register to 
>> not lose an interrupt for RXB0. I will do some tests but after next 
>> week because I don't have the access to the hardware until then.
>>
>> --
>> Christian Pellegrin, see http://www.evolware.org/chri/ "Real 
>> Programmers don't play tennis, or any other sport which requires you 
>> to change clothes. Mountain climbing is OK, and Real Programmers wear 
>> their climbing boots to work in case a mountain should suddenly 
>> spring up in the middle of the computer room."
>
>
> Hi Christian,
> Did you have a chance to look on the problem and / or the patch I send 
> to the list?
> BR
> Benny



--
Christian Pellegrin, see http://www.evolware.org/chri/ "Real Programmers don't 
play tennis, or any other sport which requires you to change clothes. Mountain 
climbing is OK, and Real Programmers wear their climbing boots to work in case 
a mountain should suddenly spring up in the middle of the computer room."
_______________________________________________
Socketcan-users mailing list
[email protected]
https://lists.berlios.de/mailman/listinfo/socketcan-users
_______________________________________________
Socketcan-users mailing list
[email protected]
https://lists.berlios.de/mailman/listinfo/socketcan-users

Reply via email to