diff options
author | Brandon Philips <brandon@ifup.org> | 2010-06-16 12:21:58 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-06-23 17:37:04 -0400 |
commit | 38000a94a902e94ca8b5498f7871c6316de8957a (patch) | |
tree | 3f749a720a341e8598017f5ab1f417d7a3625c87 /drivers/net/sky2.c | |
parent | 6b2a541db58dba5860ccbcfaf36caee064b8a9fd (diff) |
sky2: enable rx/tx in sky2_phy_reinit()
sky2_phy_reinit is called by the ethtool helpers sky2_set_settings,
sky2_nway_reset and sky2_set_pauseparam when netif_running.
However, at the end of sky2_phy_init GM_GP_CTRL has GM_GPCR_RX_ENA and
GM_GPCR_TX_ENA cleared. So, doing these commands causes the device to
stop working:
$ ethtool -r eth0
$ ethtool -A eth0 autoneg off
Fix this issue by enabling Rx/Tx after running sky2_phy_init in
sky2_phy_reinit.
Signed-off-by: Brandon Philips <bphilips@suse.de>
Tested-by: Brandon Philips <bphilips@suse.de>
Cc: stable@kernel.org
Tested-by: Mike McCormack <mikem@ring3k.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/sky2.c')
-rw-r--r-- | drivers/net/sky2.c | 19 |
1 files changed, 14 insertions, 5 deletions
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index 2111c7bbf578..7985165e84fc 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c | |||
@@ -717,11 +717,24 @@ static void sky2_phy_power_down(struct sky2_hw *hw, unsigned port) | |||
717 | sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF); | 717 | sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF); |
718 | } | 718 | } |
719 | 719 | ||
720 | /* Enable Rx/Tx */ | ||
721 | static void sky2_enable_rx_tx(struct sky2_port *sky2) | ||
722 | { | ||
723 | struct sky2_hw *hw = sky2->hw; | ||
724 | unsigned port = sky2->port; | ||
725 | u16 reg; | ||
726 | |||
727 | reg = gma_read16(hw, port, GM_GP_CTRL); | ||
728 | reg |= GM_GPCR_RX_ENA | GM_GPCR_TX_ENA; | ||
729 | gma_write16(hw, port, GM_GP_CTRL, reg); | ||
730 | } | ||
731 | |||
720 | /* Force a renegotiation */ | 732 | /* Force a renegotiation */ |
721 | static void sky2_phy_reinit(struct sky2_port *sky2) | 733 | static void sky2_phy_reinit(struct sky2_port *sky2) |
722 | { | 734 | { |
723 | spin_lock_bh(&sky2->phy_lock); | 735 | spin_lock_bh(&sky2->phy_lock); |
724 | sky2_phy_init(sky2->hw, sky2->port); | 736 | sky2_phy_init(sky2->hw, sky2->port); |
737 | sky2_enable_rx_tx(sky2); | ||
725 | spin_unlock_bh(&sky2->phy_lock); | 738 | spin_unlock_bh(&sky2->phy_lock); |
726 | } | 739 | } |
727 | 740 | ||
@@ -2040,7 +2053,6 @@ static void sky2_link_up(struct sky2_port *sky2) | |||
2040 | { | 2053 | { |
2041 | struct sky2_hw *hw = sky2->hw; | 2054 | struct sky2_hw *hw = sky2->hw; |
2042 | unsigned port = sky2->port; | 2055 | unsigned port = sky2->port; |
2043 | u16 reg; | ||
2044 | static const char *fc_name[] = { | 2056 | static const char *fc_name[] = { |
2045 | [FC_NONE] = "none", | 2057 | [FC_NONE] = "none", |
2046 | [FC_TX] = "tx", | 2058 | [FC_TX] = "tx", |
@@ -2048,10 +2060,7 @@ static void sky2_link_up(struct sky2_port *sky2) | |||
2048 | [FC_BOTH] = "both", | 2060 | [FC_BOTH] = "both", |
2049 | }; | 2061 | }; |
2050 | 2062 | ||
2051 | /* enable Rx/Tx */ | 2063 | sky2_enable_rx_tx(sky2); |
2052 | reg = gma_read16(hw, port, GM_GP_CTRL); | ||
2053 | reg |= GM_GPCR_RX_ENA | GM_GPCR_TX_ENA; | ||
2054 | gma_write16(hw, port, GM_GP_CTRL, reg); | ||
2055 | 2064 | ||
2056 | gm_phy_write(hw, port, PHY_MARV_INT_MASK, PHY_M_DEF_MSK); | 2065 | gm_phy_write(hw, port, PHY_MARV_INT_MASK, PHY_M_DEF_MSK); |
2057 | 2066 | ||