]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
tg3: Request APE_LOCK_PHY before PHY access
authorMichael Chan <mchan@broadcom.com>
Sun, 29 Jul 2012 19:15:41 +0000 (19:15 +0000)
committerJoe Jin <joe.jin@oracle.com>
Tue, 28 Aug 2012 07:23:09 +0000 (15:23 +0800)
to prevent PHY access conflict with APE firmware.

(cherry picked from commit 8151ad576d34a5ec1f1068edf25f3b7c47f6edab)
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 9cc6e0c4f87fc0781cc094e471f20b23972947fc..b0d3c73811730775f0509e11b390e4ef56bc8170 100644 (file)
@@ -672,6 +672,12 @@ static int tg3_ape_lock(struct tg3 *tp, int locknum)
                else
                        bit = 1 << tp->pci_fn;
                break;
+       case TG3_APE_LOCK_PHY0:
+       case TG3_APE_LOCK_PHY1:
+       case TG3_APE_LOCK_PHY2:
+       case TG3_APE_LOCK_PHY3:
+               bit = APE_LOCK_REQ_DRIVER;
+               break;
        default:
                return -EINVAL;
        }
@@ -723,6 +729,12 @@ static void tg3_ape_unlock(struct tg3 *tp, int locknum)
                else
                        bit = 1 << tp->pci_fn;
                break;
+       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:
                return;
        }
@@ -1052,6 +1064,8 @@ static int tg3_readphy(struct tg3 *tp, int reg, u32 *val)
                udelay(80);
        }
 
+       tg3_ape_lock(tp, tp->phy_ape_lock);
+
        *val = 0x0;
 
        frame_val  = ((tp->phy_addr << MI_COM_PHY_ADDR_SHIFT) &
@@ -1086,6 +1100,8 @@ static int tg3_readphy(struct tg3 *tp, int reg, u32 *val)
                udelay(80);
        }
 
+       tg3_ape_unlock(tp, tp->phy_ape_lock);
+
        return ret;
 }
 
@@ -1105,6 +1121,8 @@ static int tg3_writephy(struct tg3 *tp, int reg, u32 val)
                udelay(80);
        }
 
+       tg3_ape_lock(tp, tp->phy_ape_lock);
+
        frame_val  = ((tp->phy_addr << MI_COM_PHY_ADDR_SHIFT) &
                      MI_COM_PHY_ADDR_MASK);
        frame_val |= ((reg << MI_COM_REG_ADDR_SHIFT) &
@@ -1135,6 +1153,8 @@ static int tg3_writephy(struct tg3 *tp, int reg, u32 val)
                udelay(80);
        }
 
+       tg3_ape_unlock(tp, tp->phy_ape_lock);
+
        return ret;
 }
 
@@ -13616,6 +13636,23 @@ static int __devinit tg3_phy_probe(struct tg3 *tp)
        tg3_flag_set(tp, PAUSE_AUTONEG);
        tp->link_config.flowctrl = FLOW_CTRL_TX | FLOW_CTRL_RX;
 
+       if (tg3_flag(tp, ENABLE_APE)) {
+               switch (tp->pci_fn) {
+               case 0:
+                       tp->phy_ape_lock = TG3_APE_LOCK_PHY0;
+                       break;
+               case 1:
+                       tp->phy_ape_lock = TG3_APE_LOCK_PHY1;
+                       break;
+               case 2:
+                       tp->phy_ape_lock = TG3_APE_LOCK_PHY2;
+                       break;
+               case 3:
+                       tp->phy_ape_lock = TG3_APE_LOCK_PHY3;
+                       break;
+               }
+       }
+
        if (tg3_flag(tp, USE_PHYLIB))
                return tg3_phy_init(tp);
 
index 501828bab6ff35a733a683cf8218d0c646d22a3b..67bfae4e331855fa8b0ce2770d8a1074da9669e0 100644 (file)
@@ -3103,6 +3103,7 @@ struct tg3 {
        int                             old_link;
 
        u8                              phy_addr;
+       u8                              phy_ape_lock;
 
        /* PHY info */
        u32                             phy_id;