aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/sky2.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/sky2.c')
-rw-r--r--drivers/net/sky2.c42
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);