diff options
author | Marc Kleine-Budde <mkl@pengutronix.de> | 2011-01-09 16:46:25 -0500 |
---|---|---|
committer | Marc Kleine-Budde <mkl@pengutronix.de> | 2011-01-24 07:24:30 -0500 |
commit | 9e0a2d1ca3de6e284e99ad5cae1ae33ecb74c479 (patch) | |
tree | 2055519c8e9459d2f7c09f98440d6f243038fa60 /drivers/net | |
parent | 0909c1ec6f016b3f580fa2f4630659a5874a8ef8 (diff) |
can: at91_can: don't use mailbox 0
Due to a chip bug (errata 50.2.6.3 & 50.3.5.3 in
"AT91SAM9263 Preliminary 6249H-ATARM-27-Jul-09") the contents of mailbox
0 may be send under certain conditions (even if disabled or in rx mode).
The workaround in the errata suggests not to use the mailbox and load it
with a unused identifier.
This patch implements the first part of the workaround, it updates
AT91_MB_RX_NUM and AT91_MB_RX_FIRST (and the inline documentation)
so that mailbox 0 stays unused.
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
Acked-by: Wolfgang Grandegger <wg@grandegger.com>
Acked-by: Kurt Van Dijck <kurt.van.dijck@eia.be>
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/can/at91_can.c | 32 |
1 files changed, 20 insertions, 12 deletions
diff --git a/drivers/net/can/at91_can.c b/drivers/net/can/at91_can.c index 892c3d8c64a2..16e45a51cbb3 100644 --- a/drivers/net/can/at91_can.c +++ b/drivers/net/can/at91_can.c | |||
@@ -40,16 +40,16 @@ | |||
40 | 40 | ||
41 | #include <mach/board.h> | 41 | #include <mach/board.h> |
42 | 42 | ||
43 | #define AT91_NAPI_WEIGHT 12 | 43 | #define AT91_NAPI_WEIGHT 11 |
44 | 44 | ||
45 | /* | 45 | /* |
46 | * RX/TX Mailbox split | 46 | * RX/TX Mailbox split |
47 | * don't dare to touch | 47 | * don't dare to touch |
48 | */ | 48 | */ |
49 | #define AT91_MB_RX_NUM 12 | 49 | #define AT91_MB_RX_NUM 11 |
50 | #define AT91_MB_TX_SHIFT 2 | 50 | #define AT91_MB_TX_SHIFT 2 |
51 | 51 | ||
52 | #define AT91_MB_RX_FIRST 0 | 52 | #define AT91_MB_RX_FIRST 1 |
53 | #define AT91_MB_RX_LAST (AT91_MB_RX_FIRST + AT91_MB_RX_NUM - 1) | 53 | #define AT91_MB_RX_LAST (AT91_MB_RX_FIRST + AT91_MB_RX_NUM - 1) |
54 | 54 | ||
55 | #define AT91_MB_RX_MASK(i) ((1 << (i)) - 1) | 55 | #define AT91_MB_RX_MASK(i) ((1 << (i)) - 1) |
@@ -236,10 +236,14 @@ static void at91_setup_mailboxes(struct net_device *dev) | |||
236 | unsigned int i; | 236 | unsigned int i; |
237 | 237 | ||
238 | /* | 238 | /* |
239 | * The first 12 mailboxes are used as a reception FIFO. The | 239 | * Due to a chip bug (errata 50.2.6.3 & 50.3.5.3) the first |
240 | * last mailbox is configured with overwrite option. The | 240 | * mailbox is disabled. The next 11 mailboxes are used as a |
241 | * overwrite flag indicates a FIFO overflow. | 241 | * reception FIFO. The last mailbox is configured with |
242 | * overwrite option. The overwrite flag indicates a FIFO | ||
243 | * overflow. | ||
242 | */ | 244 | */ |
245 | for (i = 0; i < AT91_MB_RX_FIRST; i++) | ||
246 | set_mb_mode(priv, i, AT91_MB_MODE_DISABLED); | ||
243 | for (i = AT91_MB_RX_FIRST; i < AT91_MB_RX_LAST; i++) | 247 | for (i = AT91_MB_RX_FIRST; i < AT91_MB_RX_LAST; i++) |
244 | set_mb_mode(priv, i, AT91_MB_MODE_RX); | 248 | set_mb_mode(priv, i, AT91_MB_MODE_RX); |
245 | set_mb_mode(priv, AT91_MB_RX_LAST, AT91_MB_MODE_RX_OVRWR); | 249 | set_mb_mode(priv, AT91_MB_RX_LAST, AT91_MB_MODE_RX_OVRWR); |
@@ -541,27 +545,31 @@ static void at91_read_msg(struct net_device *dev, unsigned int mb) | |||
541 | * | 545 | * |
542 | * Theory of Operation: | 546 | * Theory of Operation: |
543 | * | 547 | * |
544 | * 12 of the 16 mailboxes on the chip are reserved for RX. we split | 548 | * 11 of the 16 mailboxes on the chip are reserved for RX. we split |
545 | * them into 2 groups. The lower group holds 8 and upper 4 mailboxes. | 549 | * them into 2 groups. The lower group holds 7 and upper 4 mailboxes. |
546 | * | 550 | * |
547 | * Like it or not, but the chip always saves a received CAN message | 551 | * Like it or not, but the chip always saves a received CAN message |
548 | * into the first free mailbox it finds (starting with the | 552 | * into the first free mailbox it finds (starting with the |
549 | * lowest). This makes it very difficult to read the messages in the | 553 | * lowest). This makes it very difficult to read the messages in the |
550 | * right order from the chip. This is how we work around that problem: | 554 | * right order from the chip. This is how we work around that problem: |
551 | * | 555 | * |
552 | * The first message goes into mb nr. 0 and issues an interrupt. All | 556 | * The first message goes into mb nr. 1 and issues an interrupt. All |
553 | * rx ints are disabled in the interrupt handler and a napi poll is | 557 | * rx ints are disabled in the interrupt handler and a napi poll is |
554 | * scheduled. We read the mailbox, but do _not_ reenable the mb (to | 558 | * scheduled. We read the mailbox, but do _not_ reenable the mb (to |
555 | * receive another message). | 559 | * receive another message). |
556 | * | 560 | * |
557 | * lower mbxs upper | 561 | * lower mbxs upper |
558 | * ______^______ __^__ | 562 | * ____^______ __^__ |
559 | * / \ / \ | 563 | * / \ / \ |
560 | * +-+-+-+-+-+-+-+-++-+-+-+-+ | 564 | * +-+-+-+-+-+-+-+-++-+-+-+-+ |
561 | * |x|x|x|x|x|x|x|x|| | | | | | 565 | * | |x|x|x|x|x|x|x|| | | | | |
562 | * +-+-+-+-+-+-+-+-++-+-+-+-+ | 566 | * +-+-+-+-+-+-+-+-++-+-+-+-+ |
563 | * 0 0 0 0 0 0 0 0 0 0 1 1 \ mail | 567 | * 0 0 0 0 0 0 0 0 0 0 1 1 \ mail |
564 | * 0 1 2 3 4 5 6 7 8 9 0 1 / box | 568 | * 0 1 2 3 4 5 6 7 8 9 0 1 / box |
569 | * ^ | ||
570 | * | | ||
571 | * \ | ||
572 | * unused, due to chip bug | ||
565 | * | 573 | * |
566 | * The variable priv->rx_next points to the next mailbox to read a | 574 | * The variable priv->rx_next points to the next mailbox to read a |
567 | * message from. As long we're in the lower mailboxes we just read the | 575 | * message from. As long we're in the lower mailboxes we just read the |