Skip to content

Commit

Permalink
tg3: Fix phylib locking strategy
Browse files Browse the repository at this point in the history
Felix Radensky noted that chip resets were generating stack trace dumps.
This is because the driver is attempting to acquire the mdio bus mutex
while holding the tp->lock spinlock.  The fix is to change the code such
that every phy access takes the tp->lock spinlock instead.

Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Matt Carlson authored and David S. Miller committed Oct 7, 2009
1 parent 083925d commit 24bb4fb
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 28 deletions.
41 changes: 14 additions & 27 deletions drivers/net/tg3.c
Original file line number Diff line number Diff line change
Expand Up @@ -902,26 +902,29 @@ static int tg3_mdio_read(struct mii_bus *bp, int mii_id, int reg)
struct tg3 *tp = bp->priv;
u32 val;

if (tp->tg3_flags3 & TG3_FLG3_MDIOBUS_PAUSED)
return -EAGAIN;
spin_lock_bh(&tp->lock);

if (tg3_readphy(tp, reg, &val))
return -EIO;
val = -EIO;

spin_unlock_bh(&tp->lock);

return val;
}

static int tg3_mdio_write(struct mii_bus *bp, int mii_id, int reg, u16 val)
{
struct tg3 *tp = bp->priv;
u32 ret = 0;

if (tp->tg3_flags3 & TG3_FLG3_MDIOBUS_PAUSED)
return -EAGAIN;
spin_lock_bh(&tp->lock);

if (tg3_writephy(tp, reg, val))
return -EIO;
ret = -EIO;

return 0;
spin_unlock_bh(&tp->lock);

return ret;
}

static int tg3_mdio_reset(struct mii_bus *bp)
Expand Down Expand Up @@ -1011,12 +1014,6 @@ static void tg3_mdio_config_5785(struct tg3 *tp)

static void tg3_mdio_start(struct tg3 *tp)
{
if (tp->tg3_flags3 & TG3_FLG3_MDIOBUS_INITED) {
mutex_lock(&tp->mdio_bus->mdio_lock);
tp->tg3_flags3 &= ~TG3_FLG3_MDIOBUS_PAUSED;
mutex_unlock(&tp->mdio_bus->mdio_lock);
}

tp->mi_mode &= ~MAC_MI_MODE_AUTO_POLL;
tw32_f(MAC_MI_MODE, tp->mi_mode);
udelay(80);
Expand All @@ -1041,15 +1038,6 @@ static void tg3_mdio_start(struct tg3 *tp)
tg3_mdio_config_5785(tp);
}

static void tg3_mdio_stop(struct tg3 *tp)
{
if (tp->tg3_flags3 & TG3_FLG3_MDIOBUS_INITED) {
mutex_lock(&tp->mdio_bus->mdio_lock);
tp->tg3_flags3 |= TG3_FLG3_MDIOBUS_PAUSED;
mutex_unlock(&tp->mdio_bus->mdio_lock);
}
}

static int tg3_mdio_init(struct tg3 *tp)
{
int i;
Expand Down Expand Up @@ -1141,7 +1129,6 @@ static void tg3_mdio_fini(struct tg3 *tp)
tp->tg3_flags3 &= ~TG3_FLG3_MDIOBUS_INITED;
mdiobus_unregister(tp->mdio_bus);
mdiobus_free(tp->mdio_bus);
tp->tg3_flags3 &= ~TG3_FLG3_MDIOBUS_PAUSED;
}
}

Expand Down Expand Up @@ -1363,7 +1350,7 @@ static void tg3_adjust_link(struct net_device *dev)
struct tg3 *tp = netdev_priv(dev);
struct phy_device *phydev = tp->mdio_bus->phy_map[PHY_ADDR];

spin_lock(&tp->lock);
spin_lock_bh(&tp->lock);

mac_mode = tp->mac_mode & ~(MAC_MODE_PORT_MODE_MASK |
MAC_MODE_HALF_DUPLEX);
Expand Down Expand Up @@ -1431,7 +1418,7 @@ static void tg3_adjust_link(struct net_device *dev)
tp->link_config.active_speed = phydev->speed;
tp->link_config.active_duplex = phydev->duplex;

spin_unlock(&tp->lock);
spin_unlock_bh(&tp->lock);

if (linkmesg)
tg3_link_report(tp);
Expand Down Expand Up @@ -6392,8 +6379,6 @@ static int tg3_chip_reset(struct tg3 *tp)

tg3_nvram_lock(tp);

tg3_mdio_stop(tp);

tg3_ape_lock(tp, TG3_APE_LOCK_GRC);

/* No matching tg3_nvram_unlock() after this because
Expand Down Expand Up @@ -8698,6 +8683,8 @@ static int tg3_close(struct net_device *dev)

del_timer_sync(&tp->timer);

tg3_phy_stop(tp);

tg3_full_lock(tp, 1);
#if 0
tg3_dump_state(tp);
Expand Down
1 change: 0 additions & 1 deletion drivers/net/tg3.h
Original file line number Diff line number Diff line change
Expand Up @@ -2748,7 +2748,6 @@ struct tg3 {
#define TG3_FLG3_5701_DMA_BUG 0x00000008
#define TG3_FLG3_USE_PHYLIB 0x00000010
#define TG3_FLG3_MDIOBUS_INITED 0x00000020
#define TG3_FLG3_MDIOBUS_PAUSED 0x00000040
#define TG3_FLG3_PHY_CONNECTED 0x00000080
#define TG3_FLG3_RGMII_STD_IBND_DISABLE 0x00000100
#define TG3_FLG3_RGMII_EXT_IBND_RX_EN 0x00000200
Expand Down

0 comments on commit 24bb4fb

Please sign in to comment.