aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/can/at91_can.c
diff options
context:
space:
mode:
authorMarc Kleine-Budde <mkl@pengutronix.de>2010-10-20 21:01:14 -0400
committerDavid S. Miller <davem@davemloft.net>2010-10-24 17:47:48 -0400
commit8a0e0a49b0a917c8c8dce6f7121ec73a5c8e3932 (patch)
tree36478aa3ed999ef60fea8d728d28b55bf3c2825b /drivers/net/can/at91_can.c
parentdbe91325c2d6ad34c1ce4f2aeae4bbd11b7a3fff (diff)
can: at91_can: fix reception of extended frames
The AT91_MID_MIDE bit must be set in order to receive extended frames. The reception of an extended frame sets this bit, while reception of standard frames resets it. This results in some lost extended frames in an extended ID only environment. But leads to unpredictable lost extended ID frames in a mixed environment. The problem is fixed by setting the AT91_MID_MIDE after reception of a CAN frame. Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/can/at91_can.c')
-rw-r--r--drivers/net/can/at91_can.c9
1 files changed, 9 insertions, 0 deletions
diff --git a/drivers/net/can/at91_can.c b/drivers/net/can/at91_can.c
index b2a4599eb1d7..3b66c6736832 100644
--- a/drivers/net/can/at91_can.c
+++ b/drivers/net/can/at91_can.c
@@ -243,6 +243,12 @@ static void at91_setup_mailboxes(struct net_device *dev)
243 set_mb_mode(priv, i, AT91_MB_MODE_RX); 243 set_mb_mode(priv, i, AT91_MB_MODE_RX);
244 set_mb_mode(priv, AT91_MB_RX_LAST, AT91_MB_MODE_RX_OVRWR); 244 set_mb_mode(priv, AT91_MB_RX_LAST, AT91_MB_MODE_RX_OVRWR);
245 245
246 /* reset acceptance mask and id register */
247 for (i = AT91_MB_RX_FIRST; i <= AT91_MB_RX_LAST; i++) {
248 at91_write(priv, AT91_MAM(i), 0x0 );
249 at91_write(priv, AT91_MID(i), AT91_MID_MIDE);
250 }
251
246 /* The last 4 mailboxes are used for transmitting. */ 252 /* The last 4 mailboxes are used for transmitting. */
247 for (i = AT91_MB_TX_FIRST; i <= AT91_MB_TX_LAST; i++) 253 for (i = AT91_MB_TX_FIRST; i <= AT91_MB_TX_LAST; i++)
248 set_mb_mode_prio(priv, i, AT91_MB_MODE_TX, 0); 254 set_mb_mode_prio(priv, i, AT91_MB_MODE_TX, 0);
@@ -480,6 +486,9 @@ static void at91_read_mb(struct net_device *dev, unsigned int mb,
480 *(u32 *)(cf->data + 0) = at91_read(priv, AT91_MDL(mb)); 486 *(u32 *)(cf->data + 0) = at91_read(priv, AT91_MDL(mb));
481 *(u32 *)(cf->data + 4) = at91_read(priv, AT91_MDH(mb)); 487 *(u32 *)(cf->data + 4) = at91_read(priv, AT91_MDH(mb));
482 488
489 /* allow RX of extended frames */
490 at91_write(priv, AT91_MID(mb), AT91_MID_MIDE);
491
483 if (unlikely(mb == AT91_MB_RX_LAST && reg_msr & AT91_MSR_MMI)) 492 if (unlikely(mb == AT91_MB_RX_LAST && reg_msr & AT91_MSR_MMI))
484 at91_rx_overflow_err(dev); 493 at91_rx_overflow_err(dev);
485} 494}