]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
tg3: Fix APE mutex init and use
authorMatt Carlson <mcarlson@broadcom.com>
Fri, 4 Nov 2011 09:14:58 +0000 (09:14 +0000)
committerJoe Jin <joe.jin@oracle.com>
Wed, 16 May 2012 02:27:03 +0000 (10:27 +0800)
APE mutex register blocks are shared by all ports of multiport devices.
For some mutexing purposes, each function is assigned their own
register.  For other cases, each function is assigned its own request
and grant bits of a single register.  For the latter cases, the tg3
driver is incorrectly allowing each function to use the same set of
grant / request bits.  This patch fixes the code so that each function
uses the appropriate bitset.

(cherry picked from commit 78f94dc7b10d98cf4cf8498d98581500d910c6b7)
Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
Signed-off-by: Michael Chan <mchan@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Joe Jin <joe.jin@oracle.com>
drivers/net/tg3.c
drivers/net/tg3.h

index 88c819dd8cf218877f885982b723845d5901755f..cfbfe5a7166def695bf7852846cd073c48f68926 100644 (file)
@@ -627,19 +627,23 @@ static void tg3_ape_lock_init(struct tg3 *tp)
                regbase = TG3_APE_PER_LOCK_GRANT;
 
        /* Make sure the driver hasn't any stale locks. */
-       for (i = 0; i < 8; i++) {
-               if (i == TG3_APE_LOCK_GPIO)
-                       continue;
-               tg3_ape_write32(tp, regbase + 4 * i, APE_LOCK_GRANT_DRIVER);
+       for (i = TG3_APE_LOCK_PHY0; i <= TG3_APE_LOCK_GPIO; i++) {
+               switch (i) {
+               case TG3_APE_LOCK_PHY0:
+               case TG3_APE_LOCK_PHY1:
+               case TG3_APE_LOCK_PHY2:
+               case TG3_APE_LOCK_PHY3:
+                       bit = APE_LOCK_GRANT_DRIVER;
+                       break;
+               default:
+                       if (!tp->pci_fn)
+                               bit = APE_LOCK_GRANT_DRIVER;
+                       else
+                               bit = 1 << tp->pci_fn;
+               }
+               tg3_ape_write32(tp, regbase + 4 * i, bit);
        }
 
-       /* Clear the correct bit of the GPIO lock too. */
-       if (!tp->pci_fn)
-               bit = APE_LOCK_GRANT_DRIVER;
-       else
-               bit = 1 << tp->pci_fn;
-
-       tg3_ape_write32(tp, regbase + 4 * TG3_APE_LOCK_GPIO, bit);
 }
 
 static int tg3_ape_lock(struct tg3 *tp, int locknum)
@@ -657,6 +661,10 @@ static int tg3_ape_lock(struct tg3 *tp, int locknum)
                        return 0;
        case TG3_APE_LOCK_GRC:
        case TG3_APE_LOCK_MEM:
+               if (!tp->pci_fn)
+                       bit = APE_LOCK_REQ_DRIVER;
+               else
+                       bit = 1 << tp->pci_fn;
                break;
        default:
                return -EINVAL;
@@ -672,11 +680,6 @@ static int tg3_ape_lock(struct tg3 *tp, int locknum)
 
        off = 4 * locknum;
 
-       if (locknum != TG3_APE_LOCK_GPIO || !tp->pci_fn)
-               bit = APE_LOCK_REQ_DRIVER;
-       else
-               bit = 1 << tp->pci_fn;
-
        tg3_ape_write32(tp, req + off, bit);
 
        /* Wait for up to 1 millisecond to acquire lock. */
@@ -709,6 +712,10 @@ static void tg3_ape_unlock(struct tg3 *tp, int locknum)
                        return;
        case TG3_APE_LOCK_GRC:
        case TG3_APE_LOCK_MEM:
+               if (!tp->pci_fn)
+                       bit = APE_LOCK_GRANT_DRIVER;
+               else
+                       bit = 1 << tp->pci_fn;
                break;
        default:
                return;
@@ -719,11 +726,6 @@ static void tg3_ape_unlock(struct tg3 *tp, int locknum)
        else
                gnt = TG3_APE_PER_LOCK_GRANT;
 
-       if (locknum != TG3_APE_LOCK_GPIO || !tp->pci_fn)
-               bit = APE_LOCK_GRANT_DRIVER;
-       else
-               bit = 1 << tp->pci_fn;
-
        tg3_ape_write32(tp, gnt + 4 * locknum, bit);
 }
 
index 3923531743a9ecdea765042e831a4cb570d5cff3..1e02e436ac39cf4d91f00f7bacd85bab03956b34 100644 (file)
 #define  APE_PER_LOCK_GRANT_DRIVER      0x00001000
 
 /* APE convenience enumerations. */
-#define TG3_APE_LOCK_GRC                1
-#define TG3_APE_LOCK_MEM                4
-#define TG3_APE_LOCK_GPIO               7
+#define TG3_APE_LOCK_PHY0              0
+#define TG3_APE_LOCK_GRC               1
+#define TG3_APE_LOCK_PHY1              2
+#define TG3_APE_LOCK_PHY2              3
+#define TG3_APE_LOCK_MEM               4
+#define TG3_APE_LOCK_PHY3              5
+#define TG3_APE_LOCK_GPIO              7
 
 #define TG3_EEPROM_SB_F1R2_MBA_OFF     0x10