can: at91_can: don't use mailbox 0
[pandora-kernel.git] / drivers / net / can / at91_can.c
index 7ef83d0..16e45a5 100644 (file)
@@ -2,7 +2,7 @@
  * at91_can.c - CAN network driver for AT91 SoC CAN controller
  *
  * (C) 2007 by Hans J. Koch <hjk@hansjkoch.de>
- * (C) 2008, 2009, 2010 by Marc Kleine-Budde <kernel@pengutronix.de>
+ * (C) 2008, 2009, 2010, 2011 by Marc Kleine-Budde <kernel@pengutronix.de>
  *
  * This software may be distributed under the terms of the GNU General
  * Public License ("GPL") version 2 as distributed in the 'COPYING'
 
 #include <mach/board.h>
 
-#define AT91_NAPI_WEIGHT       12
+#define AT91_NAPI_WEIGHT       11
 
 /*
  * RX/TX Mailbox split
  * don't dare to touch
  */
-#define AT91_MB_RX_NUM         12
+#define AT91_MB_RX_NUM         11
 #define AT91_MB_TX_SHIFT       2
 
-#define AT91_MB_RX_FIRST       0
+#define AT91_MB_RX_FIRST       1
 #define AT91_MB_RX_LAST                (AT91_MB_RX_FIRST + AT91_MB_RX_NUM - 1)
 
 #define AT91_MB_RX_MASK(i)     ((1 << (i)) - 1)
 #define AT91_MB_RX_SPLIT       8
 #define AT91_MB_RX_LOW_LAST    (AT91_MB_RX_SPLIT - 1)
-#define AT91_MB_RX_LOW_MASK    (AT91_MB_RX_MASK(AT91_MB_RX_SPLIT))
+#define AT91_MB_RX_LOW_MASK    (AT91_MB_RX_MASK(AT91_MB_RX_SPLIT) & \
+                                ~AT91_MB_RX_MASK(AT91_MB_RX_FIRST))
 
 #define AT91_MB_TX_NUM         (1 << AT91_MB_TX_SHIFT)
 #define AT91_MB_TX_FIRST       (AT91_MB_RX_LAST + 1)
@@ -235,10 +236,14 @@ static void at91_setup_mailboxes(struct net_device *dev)
        unsigned int i;
 
        /*
-        * The first 12 mailboxes are used as a reception FIFO. The
-        * last mailbox is configured with overwrite option. The
-        * overwrite flag indicates a FIFO overflow.
+        * Due to a chip bug (errata 50.2.6.3 & 50.3.5.3) the first
+        * mailbox is disabled. The next 11 mailboxes are used as a
+        * reception FIFO. The last mailbox is configured with
+        * overwrite option. The overwrite flag indicates a FIFO
+        * overflow.
         */
+       for (i = 0; i < AT91_MB_RX_FIRST; i++)
+               set_mb_mode(priv, i, AT91_MB_MODE_DISABLED);
        for (i = AT91_MB_RX_FIRST; i < AT91_MB_RX_LAST; i++)
                set_mb_mode(priv, i, AT91_MB_MODE_RX);
        set_mb_mode(priv, AT91_MB_RX_LAST, AT91_MB_MODE_RX_OVRWR);
@@ -254,7 +259,8 @@ static void at91_setup_mailboxes(struct net_device *dev)
                set_mb_mode_prio(priv, i, AT91_MB_MODE_TX, 0);
 
        /* Reset tx and rx helper pointers */
-       priv->tx_next = priv->tx_echo = priv->rx_next = 0;
+       priv->tx_next = priv->tx_echo = 0;
+       priv->rx_next = AT91_MB_RX_FIRST;
 }
 
 static int at91_set_bittiming(struct net_device *dev)
@@ -539,27 +545,31 @@ static void at91_read_msg(struct net_device *dev, unsigned int mb)
  *
  * Theory of Operation:
  *
- * 12 of the 16 mailboxes on the chip are reserved for RX. we split
- * them into 2 groups. The lower group holds 8 and upper 4 mailboxes.
+ * 11 of the 16 mailboxes on the chip are reserved for RX. we split
+ * them into 2 groups. The lower group holds 7 and upper 4 mailboxes.
  *
  * Like it or not, but the chip always saves a received CAN message
  * into the first free mailbox it finds (starting with the
  * lowest). This makes it very difficult to read the messages in the
  * right order from the chip. This is how we work around that problem:
  *
- * The first message goes into mb nr. 0 and issues an interrupt. All
+ * The first message goes into mb nr. 1 and issues an interrupt. All
  * rx ints are disabled in the interrupt handler and a napi poll is
  * scheduled. We read the mailbox, but do _not_ reenable the mb (to
  * receive another message).
  *
  *    lower mbxs      upper
- *   ______^______    __^__
- *  /             \  /     \
+ *     ____^______    __^__
+ *    /           \  /     \
  * +-+-+-+-+-+-+-+-++-+-+-+-+
- * |x|x|x|x|x|x|x|x|| | | | |
+ * | |x|x|x|x|x|x|x|| | | | |
  * +-+-+-+-+-+-+-+-++-+-+-+-+
  *  0 0 0 0 0 0  0 0 0 0 1 1  \ mail
  *  0 1 2 3 4 5  6 7 8 9 0 1  / box
+ *  ^
+ *  |
+ *   \
+ *     unused, due to chip bug
  *
  * The variable priv->rx_next points to the next mailbox to read a
  * message from. As long we're in the lower mailboxes we just read the
@@ -590,10 +600,10 @@ static int at91_poll_rx(struct net_device *dev, int quota)
                        "order of incoming frames cannot be guaranteed\n");
 
  again:
-       for (mb = find_next_bit(addr, AT91_MB_RX_NUM, priv->rx_next);
-            mb < AT91_MB_RX_NUM && quota > 0;
+       for (mb = find_next_bit(addr, AT91_MB_RX_LAST + 1, priv->rx_next);
+            mb < AT91_MB_RX_LAST + 1 && quota > 0;
             reg_sr = at91_read(priv, AT91_SR),
-            mb = find_next_bit(addr, AT91_MB_RX_NUM, ++priv->rx_next)) {
+            mb = find_next_bit(addr, AT91_MB_RX_LAST + 1, ++priv->rx_next)) {
                at91_read_msg(dev, mb);
 
                /* reactivate mailboxes */
@@ -610,8 +620,8 @@ static int at91_poll_rx(struct net_device *dev, int quota)
 
        /* upper group completed, look again in lower */
        if (priv->rx_next > AT91_MB_RX_LOW_LAST &&
-           quota > 0 && mb >= AT91_MB_RX_NUM) {
-               priv->rx_next = 0;
+           quota > 0 && mb > AT91_MB_RX_LAST) {
+               priv->rx_next = AT91_MB_RX_FIRST;
                goto again;
        }