-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Wolfgang Grandegger wrote:
>>> Very nice. Do you really need to stop the NAPI in case of bus-off? You
>>> stopped the device and no more message will come in anyhow.
>> hmmm...I'll try
works
> It would be nice if we could get rid of the work queue. For the MSCAN on
> the MPC5200, NAPI is also not disabled on bus-off and the controller
> behaves similar (doing automatic bus-off recovery).
[..]
>>>> The driver with NAPI receiving messages with a length of 1 on a 1 Mbit
>>>> link without swapping the messages (tested with pengutronix cansequence).
>>> Please use Vladislavs' canecho_gen/duts at 125kB/sec, which is more
>>> sensitive. Don't forget to fix the unhanded errno ENOBUFS of the write
>>> functions.
>> using select/poll would be better than calling sched_yield
>
> Well, yes, could this easily be achieved? Oliver?
Poll/select/... works already even for sending. No work needed.
BTW: I have a hack that puts sending in blocking mode by default, but
that's a different story.
Vladislavs test program found a bug, which is fixed and now it works
with all of the three tested bitrates 125K, 250K and 1Mbit.
>>>> However if I add some "ping -f" load the driver keeps working (tested
>>>> with looking at the data bytes in the driver), but the userspace doesn't
>>>> get enough cpu cycles so AFAICS the pacakges must be dropped in the
>>>> network layer.
>>>>
>>>> Even on the 1 Mbit link the total number IRQs isn't reduced by NAPI
>>>> (less than 1%). But with NAPI I can enable the Acknowledgement Error
>>>> even on 1 Mbit, and the system doesn't lock up. It generated ~15K Int/s.
>>> With NAPI, message processing is moved from the interrupt to the process
>>> context, which efficiently avoids lockups. As longs as CPU resources are
>>> available, no messages will be dropped.
>>>> Adding again "ping -f" load, the CAN interrupts drop to ~11K Int/s,
>>>> the Ethernet causes only ~7K Int/s.
>>>>
>>>> Maybe we can think of some really "slow" polling for such interrupts.
>>>> IIRC the SJA1000 has the same problem.
>>> I remember some discussion on this topic a long time ago and there it
>>> was regarded important to get and inspect all bus errors. Throttling was
>>> not accepted.
>> As we see with the above numbers, we lose about 4000 errors per second
>> if ethernet traffic hits the box. I was just thinking about polling this
>> particular error if it hits the chip.
>
> This is a general issue and I think we should re-discuss it sooner than
> later.
ACK,
First let's get some drivers into mainline ;)
>>>> Here's the driver, comments welcome. There are some functions, that
>>>> might be moved out of the driver into can/dev.c (alloc_can*frame).
>>> There are various general coding style issues:
> [snip]
>>>> +/* Common registers */
>>>> +enum at91_reg {
>>>> + AT91_MR = 0x000,
>>>> + AT91_IER = 0x004,
>>>> + AT91_IDR = 0x008,
>>>> + AT91_IMR = 0x00C,
>>>> + AT91_SR = 0x010,
>>>> + AT91_BR = 0x014,
>>>> + AT91_TIM = 0x018,
>>>> + AT91_TIMESTP = 0x01C,
>>>> + AT91_ECR = 0x020,
>>>> + AT91_TCR = 0x024,
>>>> + AT91_ACR = 0x028,
>>>> +};
>>>> +
>>>> +/* Mailbox registers (0 <= i <= 15) */
>>>> +#define AT91_MMR(i) (enum at91_reg)(0x200 + ((i) * 0x20))
>>>> +#define AT91_MAM(i) (enum at91_reg)(0x204 + ((i) * 0x20))
>>>> +#define AT91_MID(i) (enum at91_reg)(0x208 + ((i) * 0x20))
>>>> +#define AT91_MFID(i) (enum at91_reg)(0x20C + ((i) * 0x20))
>>>> +#define AT91_MSR(i) (enum at91_reg)(0x210 + ((i) * 0x20))
>>>> +#define AT91_MDL(i) (enum at91_reg)(0x214 + ((i) * 0x20))
>>>> +#define AT91_MDH(i) (enum at91_reg)(0x218 + ((i) * 0x20))
>>>> +#define AT91_MCR(i) (enum at91_reg)(0x21C + ((i) * 0x20))
>>>> +
>>>> +/* Register bits */
>>>> +#define AT91_MR_AT91EN BIT(0)
>>>> +#define AT91_MR_LPM BIT(1)
>>>> +#define AT91_MR_ABM BIT(2)
>>>> +#define AT91_MR_OVL BIT(3)
>>>> +#define AT91_MR_TEOF BIT(4)
>>>> +#define AT91_MR_TTM BIT(5)
>>>> +#define AT91_MR_TIMFRZ BIT(6)
>>>> +#define AT91_MR_DRPT BIT(7)
>>>> +
>>>> +#define AT91_SR_RBSY BIT(29)
>>>> +
>>>> +#define AT91_MMR_PRIO_SHIFT (16)
>>>> +
>>>> +#define AT91_MID_MIDE BIT(29)
>>>> +
>>>> +#define AT91_MSR_MRTR BIT(20)
>>>> +#define AT91_MSR_MABT BIT(22)
>>>> +#define AT91_MSR_MRDY BIT(23)
>>>> +#define AT91_MSR_MMI BIT(24)
>>>> +
>>>> +#define AT91_MCR_MRTR BIT(20)
>>>> +#define AT91_MCR_MTCR BIT(23)
>>>> +
>>>> +/* Mailbox Modes */
>>>> +enum at91_mb_mode {
>>>> + AT91_MB_MODE_DISABLED = 0,
>>>> + AT91_MB_MODE_RX = 1,
>>>> + AT91_MB_MODE_RX_OVRWR = 2,
>>>> + AT91_MB_MODE_TX = 3,
>>>> + AT91_MB_MODE_CONSUMER = 4,
>>>> + AT91_MB_MODE_PRODUCER = 5,
>>>> +};
>>>> +
>>>> +/* Interrupt mask bits */
>>>> +#define AT91_IRQ_MB_RX ((1 << (AT91_MB_RX_LAST + 1)) \
>>>> + - (1 << AT91_MB_RX_FIRST))
>>>> +#define AT91_IRQ_MB_TX ((1 << (AT91_MB_TX_LAST + 1)) \
>>>> + - (1 << AT91_MB_TX_FIRST))
>>>> +#define AT91_IRQ_MB_AL (AT91_IRQ_MB_RX | AT91_IRQ_MB_TX)
>>>> +
>>>> +#define AT91_IRQ_ERRA (1 << 16)
>>>> +#define AT91_IRQ_WARN (1 << 17)
>>>> +#define AT91_IRQ_ERRP (1 << 18)
>>>> +#define AT91_IRQ_BOFF (1 << 19)
>>>> +#define AT91_IRQ_SLEEP (1 << 20)
>>>> +#define AT91_IRQ_WAKEUP (1 << 21)
>>>> +#define AT91_IRQ_TOVF (1 << 22)
>>>> +#define AT91_IRQ_TSTP (1 << 23)
>>>> +#define AT91_IRQ_CERR (1 << 24)
>>>> +#define AT91_IRQ_SERR (1 << 25)
>>>> +#define AT91_IRQ_AERR (1 << 26)
>>>> +#define AT91_IRQ_FERR (1 << 27)
>>>> +#define AT91_IRQ_BERR (1 << 28)
>>>> +
>>>> +#define AT91_IRQ_ERR_ALL (0x1fff0000)
>>>> +#define AT91_IRQ_ERR_FRAME (AT91_IRQ_CERR | AT91_IRQ_SERR | \
>>>> + AT91_IRQ_AERR | AT91_IRQ_FERR | AT91_IRQ_BERR)
>>>> +#define AT91_IRQ_ERR_LINE (AT91_IRQ_ERRA | AT91_IRQ_WARN | \
>>>> + AT91_IRQ_ERRP | AT91_IRQ_BOFF)
>>>> +
>>>> +#define AT91_IRQ_ALL (0x1fffffff)
>>>> +
>>>> +struct at91_priv {
>>>> + struct can_priv can; /* must be the first member! */
>>>> + struct net_device *dev;
>>>> + struct napi_struct napi;
>>>> +
>>>> + void __iomem *reg_base;
>>>> +
>>>> + u32 reg_sr;
>>>> + unsigned int tx_next;
>>>> + unsigned int tx_echo;
>>>> + unsigned int rx_next;
>>>> +
>>>> + struct work_struct bus_off_task;
>>>> +
>>>> + struct clk *clk;
>>>> + struct at91_can_data *pdata;
>>>> +};
>>>> +
>>>> +
>>>> +static struct can_bittiming_const at91_bittiming_const = {
>>>> + .tseg1_min = 4,
>>>> + .tseg1_max = 16,
>>>> + .tseg2_min = 2,
>>>> + .tseg2_max = 8,
>>>> + .sjw_max = 4,
>>>> + .brp_min = 2,
>>>> + .brp_max = 128,
>>>> + .brp_inc = 1,
>>>> +};
>>> Why do you don't use tab here fore aligment of the numbers?
>> As Wolfram pointed out:
>>
>>> There are a few of those. Such kind of indentation is ususally
>>> rejected upstream, too. If one of the member names ever changes, "="
>>> will get misaligned again (or you'd need to alter lines just for
>>> beautification which would make git blame less useful). So, one space
>>> after the names should do.
>
> I know, but then you probably also want to fix the enums above. In the
> file header, I'm more relaxed, especially because defines are usually
> aligned as well.
okay, realligned
>>>> +
>>>> +static inline int get_tx_next_mb(struct at91_priv *priv)
>>>> +{
>>>> + return (priv->tx_next & AT91_NEXT_MB_MASK) + AT91_MB_TX_FIRST;
>>>> +}
>>>> +
>>>> +static inline int get_tx_next_prio(struct at91_priv *priv)
>>>> +{
>>>> + return (priv->tx_next >> AT91_NEXT_PRIO_SHIFT) & 0xf;
>>>> +}
>>>> +
>>>> +static inline int get_tx_echo_mb(struct at91_priv *priv)
>>>> +{
>>>> + return (priv->tx_echo & AT91_NEXT_MB_MASK) + AT91_MB_TX_FIRST;
>>>> +}
>>>> +
>>>> +
>>>> +static inline u32 at91_read(struct net_device *dev, enum at91_reg reg)
>>>> +{
>>>> + struct at91_priv *priv = netdev_priv(dev);
>>>> + return readl(priv->reg_base + reg);
>>>> +}
>>>> +
>>>> +static inline void
>>>> +at91_write(struct net_device *dev, enum at91_reg reg, u32 value)
>>>> +{
>>>> + struct at91_priv *priv = netdev_priv(dev);
>>>> + writel(value, priv->reg_base + reg);
>>>> +}
>>>> +
>>>> +
>>>> +static inline void
>>>> +set_mb_mode_prio(struct net_device *dev, unsigned int mb,
>>>> + enum at91_mb_mode mode, int prio)
>>>> +{
>>>> + at91_write(dev, AT91_MMR(mb),
>>>> + (mode << 24) | (prio << 16));
>>> Fits on one line?
>> it does, fixed
>>
>>>> +}
>>>> +
>>>> +static inline void
>>>> +set_mb_mode(struct net_device *dev, unsigned int mb, enum at91_mb_mode
>>>> mode)
>>>> +{
>>>> + set_mb_mode_prio(dev, mb, mode, 0);
>>>> +}
>>>> +
>>>> +
>>>> +static struct sk_buff *
>>>> +alloc_can_frame(struct net_device *dev, struct can_frame **cf)
>>>> +{
>>>> + struct sk_buff *skb;
>>>> +
>>>> + skb = netdev_alloc_skb(dev, sizeof(struct can_frame));
>>>> + if (unlikely(!skb))
>
> A (rate limited) dev_err would be nice here as well.
If we make this a library function or inline, IMHO the user of this
function should care about error handling and/or messaging. I increase
rx_dropped when it happens in the normal rx-path.
>>>> + return NULL;
>>>> +
>>>> + skb->protocol = htons(ETH_P_CAN);
>>>> + skb->ip_summed = CHECKSUM_UNNECESSARY;
>>>> + *cf = (struct can_frame *)skb_put(skb, sizeof(struct can_frame));
>>>> +
>>>> + return skb;
>>>> +}
>>>> +
>>>> +
>>>> +static struct sk_buff *
>>>> +alloc_can_err_frame(struct net_device *dev, struct can_frame **cf)
>>>> +{
>>>> + struct sk_buff *skb;
>>>> +
>>>> + skb = alloc_can_frame(dev, cf);
>>>> + if (unlikely(!skb))
>>>> + return NULL;
>>>> +
>>>> + memset(*cf, 0, sizeof(struct can_frame));
>>>> + (*cf)->can_id = CAN_ERR_FLAG;
>>>> + (*cf)->can_dlc = CAN_ERR_DLC;
>>>> +
>>>> + return skb;
>>>> +}
>>> Yes, we should put similar functions into dev.[ch]. But I would use the
>>> suffix "skb" instead of "frame" because the return value is of type
>>> "static struct sk_buff *". Patches are welcome.
>> fixed. patches against which tree?
>
> First again SVN trunk.
What about a git tree? The whole svn situation suxs.
cheers, Marc
- --
Pengutronix e.K. | Marc Kleine-Budde |
Linux Solutions for Science and Industry | Phone: +49-231-2826-924 |
Vertretung West/Dortmund | Fax: +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686 | http://www.pengutronix.de |
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org
iEYEARECAAYFAkquRtkACgkQjTAFq1RaXHPGDwCgk0+WNHkcG2JXK6swVcmCC0Rp
xHYAoI+pl6cyplwJ4s2yBf6WeBkHIjf/
=x7nn
-----END PGP SIGNATURE-----
_______________________________________________
Socketcan-core mailing list
[email protected]
https://lists.berlios.de/mailman/listinfo/socketcan-core