Skip to content

Commit

Permalink
phy: unmask link partner capabilities
Browse files Browse the repository at this point in the history
Masking the link partner's capabilities with local capabilities can be
misleading in autonegotiation scenarios such as PAUSE frame
autonegotiation.
This patch calculates the join between the local capabilities and the
link parner capabilities, when it determines the speed and duplex
settings, but does not mask any of the link partner capabilities when
it calculates PAUSE frame settings.

Signed-off-by: Cristian Bercaru <cristian.bercaru@freescale.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Cristian Bercaru authored and David S. Miller committed Feb 25, 2014
1 parent 46833a8 commit a4572e0
Showing 1 changed file with 9 additions and 7 deletions.
16 changes: 9 additions & 7 deletions drivers/net/phy/phy_device.c
Original file line number Diff line number Diff line change
Expand Up @@ -916,6 +916,8 @@ int genphy_read_status(struct phy_device *phydev)
int err;
int lpa;
int lpagb = 0;
int common_adv;
int common_adv_gb = 0;

/* Update the link, but return if there was an error */
err = genphy_update_link(phydev);
Expand All @@ -937,7 +939,7 @@ int genphy_read_status(struct phy_device *phydev)

phydev->lp_advertising =
mii_stat1000_to_ethtool_lpa_t(lpagb);
lpagb &= adv << 2;
common_adv_gb = lpagb & adv << 2;
}

lpa = phy_read(phydev, MII_LPA);
Expand All @@ -950,25 +952,25 @@ int genphy_read_status(struct phy_device *phydev)
if (adv < 0)
return adv;

lpa &= adv;
common_adv = lpa & adv;

phydev->speed = SPEED_10;
phydev->duplex = DUPLEX_HALF;
phydev->pause = 0;
phydev->asym_pause = 0;

if (lpagb & (LPA_1000FULL | LPA_1000HALF)) {
if (common_adv_gb & (LPA_1000FULL | LPA_1000HALF)) {
phydev->speed = SPEED_1000;

if (lpagb & LPA_1000FULL)
if (common_adv_gb & LPA_1000FULL)
phydev->duplex = DUPLEX_FULL;
} else if (lpa & (LPA_100FULL | LPA_100HALF)) {
} else if (common_adv & (LPA_100FULL | LPA_100HALF)) {
phydev->speed = SPEED_100;

if (lpa & LPA_100FULL)
if (common_adv & LPA_100FULL)
phydev->duplex = DUPLEX_FULL;
} else
if (lpa & LPA_10FULL)
if (common_adv & LPA_10FULL)
phydev->duplex = DUPLEX_FULL;

if (phydev->duplex == DUPLEX_FULL) {
Expand Down

0 comments on commit a4572e0

Please sign in to comment.