diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/sky2.c | 42 |
1 files changed, 31 insertions, 11 deletions
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index e5679965501c..2c9118125b5e 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c | |||
@@ -1766,10 +1766,10 @@ static int sky2_autoneg_done(struct sky2_port *sky2, u16 aux) | |||
1766 | { | 1766 | { |
1767 | struct sky2_hw *hw = sky2->hw; | 1767 | struct sky2_hw *hw = sky2->hw; |
1768 | unsigned port = sky2->port; | 1768 | unsigned port = sky2->port; |
1769 | u16 lpa; | 1769 | u16 advert, lpa; |
1770 | 1770 | ||
1771 | advert = gm_phy_read(hw, port, PHY_MARV_AUNE_ADV); | ||
1771 | lpa = gm_phy_read(hw, port, PHY_MARV_AUNE_LP); | 1772 | lpa = gm_phy_read(hw, port, PHY_MARV_AUNE_LP); |
1772 | |||
1773 | if (lpa & PHY_M_AN_RF) { | 1773 | if (lpa & PHY_M_AN_RF) { |
1774 | printk(KERN_ERR PFX "%s: remote fault", sky2->netdev->name); | 1774 | printk(KERN_ERR PFX "%s: remote fault", sky2->netdev->name); |
1775 | return -1; | 1775 | return -1; |
@@ -1784,20 +1784,40 @@ static int sky2_autoneg_done(struct sky2_port *sky2, u16 aux) | |||
1784 | sky2->speed = sky2_phy_speed(hw, aux); | 1784 | sky2->speed = sky2_phy_speed(hw, aux); |
1785 | sky2->duplex = (aux & PHY_M_PS_FULL_DUP) ? DUPLEX_FULL : DUPLEX_HALF; | 1785 | sky2->duplex = (aux & PHY_M_PS_FULL_DUP) ? DUPLEX_FULL : DUPLEX_HALF; |
1786 | 1786 | ||
1787 | /* Pause bits are offset (9..8) */ | 1787 | /* Since the pause result bits seem to in different positions on |
1788 | if (hw->chip_id == CHIP_ID_YUKON_XL | 1788 | * different chips. look at registers. |
1789 | || hw->chip_id == CHIP_ID_YUKON_EC_U | 1789 | */ |
1790 | || hw->chip_id == CHIP_ID_YUKON_EX) | 1790 | if (!sky2_is_copper(hw)) { |
1791 | aux >>= 6; | 1791 | /* Shift for bits in fiber PHY */ |
1792 | 1792 | advert &= ~(ADVERTISE_PAUSE_CAP|ADVERTISE_PAUSE_ASYM); | |
1793 | sky2->flow_status = sky2_flow(aux & PHY_M_PS_RX_P_EN, | 1793 | lpa &= ~(LPA_PAUSE_CAP|LPA_PAUSE_ASYM); |
1794 | aux & PHY_M_PS_TX_P_EN); | 1794 | |
1795 | if (advert & ADVERTISE_1000XPAUSE) | ||
1796 | advert |= ADVERTISE_PAUSE_CAP; | ||
1797 | if (advert & ADVERTISE_1000XPSE_ASYM) | ||
1798 | advert |= ADVERTISE_PAUSE_ASYM; | ||
1799 | if (lpa & LPA_1000XPAUSE) | ||
1800 | lpa |= LPA_PAUSE_CAP; | ||
1801 | if (lpa & LPA_1000XPAUSE_ASYM) | ||
1802 | lpa |= LPA_PAUSE_ASYM; | ||
1803 | } | ||
1804 | |||
1805 | sky2->flow_status = FC_NONE; | ||
1806 | if (advert & ADVERTISE_PAUSE_CAP) { | ||
1807 | if (lpa & LPA_PAUSE_CAP) | ||
1808 | sky2->flow_status = FC_BOTH; | ||
1809 | else if (advert & ADVERTISE_PAUSE_ASYM) | ||
1810 | sky2->flow_status = FC_RX; | ||
1811 | } else if (advert & ADVERTISE_PAUSE_ASYM) { | ||
1812 | if ((lpa & LPA_PAUSE_CAP) && (lpa & LPA_PAUSE_ASYM)) | ||
1813 | sky2->flow_status = FC_TX; | ||
1814 | } | ||
1795 | 1815 | ||
1796 | if (sky2->duplex == DUPLEX_HALF && sky2->speed < SPEED_1000 | 1816 | if (sky2->duplex == DUPLEX_HALF && sky2->speed < SPEED_1000 |
1797 | && !(hw->chip_id == CHIP_ID_YUKON_EC_U || hw->chip_id == CHIP_ID_YUKON_EX)) | 1817 | && !(hw->chip_id == CHIP_ID_YUKON_EC_U || hw->chip_id == CHIP_ID_YUKON_EX)) |
1798 | sky2->flow_status = FC_NONE; | 1818 | sky2->flow_status = FC_NONE; |
1799 | 1819 | ||
1800 | if (aux & PHY_M_PS_RX_P_EN) | 1820 | if (sky2->flow_status & FC_TX) |
1801 | sky2_write8(hw, SK_REG(port, GMAC_CTRL), GMC_PAUSE_ON); | 1821 | sky2_write8(hw, SK_REG(port, GMAC_CTRL), GMC_PAUSE_ON); |
1802 | else | 1822 | else |
1803 | sky2_write8(hw, SK_REG(port, GMAC_CTRL), GMC_PAUSE_OFF); | 1823 | sky2_write8(hw, SK_REG(port, GMAC_CTRL), GMC_PAUSE_OFF); |