Thomas Körper wrote:
> Hello Wolfgang,
> 
> 
>>> This patch fixes sending erroneous frames when loopback is disabled.
>>> Also stats->txBytes is now only increased in TX-done interrupt and
>>> not earlier.
>>>
>>>     Thomas
>>>
>>>
>>> Signed-off-by: thomas.koerper <[email protected]>
>>> ---
>>> Index: kernel/2.6/drivers/net/can/esd_pci331.c
>>> ===================================================================
>>> --- kernel/2.6/drivers/net/can/esd_pci331.c    (revision 1103)
>>> +++ kernel/2.6/drivers/net/can/esd_pci331.c    (working copy)
>>> @@ -318,32 +318,6 @@
>>>       return err;
>>>   }
>>>
>>> -static int esd331_send(struct esd331_pci *board, u8 pci331net,
>>> unsigned long id,
>>> -            int eff, int rtr, u16 dlc, u8 *data)
>>> -{
>>> -    struct esd331_can_msg msg;
>>> -    int i;
>>> -
>>> -    memset(&msg, 0, sizeof(msg));
>>> -
>>> -    if (eff) {
>>> -        msg.cmmd = ESD331_I20_EX_BCAN;
>>> -        msg.id = cpu_to_be16((id >> 16) & 0x1fff);
>>> -        msg.x2 = cpu_to_be16(id);
>>> -    } else {
>>> -        msg.cmmd = ESD331_I20_BCAN;
>>> -        msg.id = cpu_to_be16(id);
>>> -    }
>>> -    msg.net = pci331net;
>>> -    msg.len = cpu_to_be16(rtr ? dlc | ESD331_RTR_FLAG : dlc);
>>> -
>>> -    i = (dlc < 8) ? dlc : 8;
>>> -    while (i--)
>>> -        msg.data[i] = data[i];
>>> -
>>> -    return esd331_write(&msg, board);
>>> -}
>>> -
>>>   static int esd331_write_allid(u8 net, struct esd331_pci *board)
>>>   {
>>>       struct esd331_can_msg mesg;
>>> @@ -583,6 +557,7 @@
>>>           case ESD331_I20_TXDONE:
>>>           case ESD331_I20_EX_TXDONE:
>>>               stats->tx_packets++;
>>> +            stats->tx_bytes += msg.x1;
>>>               can_get_echo_skb(dev, 0);
>>>               netif_wake_queue(dev);
>>>               break;
>>> @@ -693,24 +668,36 @@
>>>       struct net_device_stats *stats = &dev->stats;
>>>   #endif
>>>       struct can_frame *cf = (struct can_frame *)skb->data;
>>> -    int err;
>>> +    struct esd331_can_msg msg;
>>> +    int err = NETDEV_TX_OK;
>>
>> As "err" does not hold an error code, "ret" seems more appropriate.
>> Maybe you do not even need that variable.
> Well, of course I could avoid the variable and just call "return
> NETDEV_TX..." anywhere
> in the function. But I think I was told not to do that and use "goto"
> instead.

Well, "goto" should be used if there is a step by step cleanup to be
done, but that's not the case here.

> Just tell me how it should look like, will put the complete function at
> the end of this post.

I would remove err completely also to save some lines.

>>> +    int i;
>>>
>>> -    can_put_echo_skb(skb, dev, 0);
>>> -
>>>       if ((cf->can_id & CAN_EFF_FLAG) && (priv->board->eff_supp == 0)) {
>>>           stats->tx_errors++;
>>>           stats->tx_dropped++;
>>> -        can_free_echo_skb(dev, 0);
>>> -        err = -EOPNOTSUPP;
>>>           goto out;
>>>       }
>>>
>>> -    err = esd331_send(priv->board, priv->boards_net,
>>> -                cf->can_id & CAN_EFF_MASK,
>>> -                cf->can_id & CAN_EFF_FLAG,
>>> -                cf->can_id & CAN_RTR_FLAG,
>>> -                cf->can_dlc, cf->data);
>>> -    if (err) {
>>> +    memset(&msg, 0, sizeof(msg));
>>> +    if (cf->can_id & CAN_EFF_FLAG) {
>>> +        msg.cmmd = ESD331_I20_EX_BCAN;
>>> +        msg.id = cpu_to_be16((cf->can_id & CAN_EFF_MASK) >> 16);
>>> +        msg.x2 = cpu_to_be16(cf->can_id & CAN_EFF_MASK);
>>> +    } else {
>>> +        msg.cmmd = ESD331_I20_BCAN;
>>> +        msg.id = cpu_to_be16(cf->can_id & CAN_EFF_MASK);
>>> +    }
>>> +    msg.x1 = cpu_to_be16(cf->can_dlc);
>>> +    msg.net = priv->boards_net;
>>> +    msg.len = cpu_to_be16((cf->can_id & CAN_RTR_FLAG) ?
>>> +                cf->can_dlc | ESD331_RTR_FLAG : cf->can_dlc);
>>> +
>>> +    for (i = 0; i < cf->can_dlc; i++)
>>> +        msg.data[i] = cf->data[i];
>>> +
>>> +    can_put_echo_skb(skb, dev, 0);
>>> +    if (esd331_write(&msg, priv->board)) {
>>> +        err = NETDEV_TX_BUSY;
>>>           stats->tx_fifo_errors++;
>>>           stats->tx_errors++;
>>>           stats->tx_dropped++;
>>> @@ -719,8 +706,8 @@
>>>       }
>>
>> You dropped the packet and you should therefore call can_free_echo_skb()
>> and return with NETDEV_TX_OK.
> Just missing in the patch cause that line's already there.
> 
>> Can esd331_write() fail? Will it succeed the next time it is called?
>> The NETDEV_TX_BUSY might be more appropriate.
> Fails when card's fifo is full, therefore likely to succeed next time.
> But as NETDEV_TX_BUSY is also already returned then, I don't get what
> you mean.

If you return with NETDEV_TX_BUSY, you should *not* free the skb and
therefore *not* increment "stats->tx_dropped". In contrast, if you
return with NETDEV_TX_OK, the *driver* must take care of the skb. Do you
realized the difference and problem now?

Wolfgang.
_______________________________________________
Socketcan-core mailing list
[email protected]
https://lists.berlios.de/mailman/listinfo/socketcan-core

Reply via email to