summaryrefslogtreecommitdiff
path: root/drivers/net/phy/phy-core.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2018-01-02 15:00:50 -0500
committerDavid S. Miller <davem@davemloft.net>2018-01-02 15:00:50 -0500
commitdc917aec77c0255ba20d582a72a0137f7321f17c (patch)
tree87d806a67ec3ecf3b84d9af0c70ca69b33265745 /drivers/net/phy/phy-core.c
parent3abbcccc6f318f858ffbd4e3d82839b66ff1b960 (diff)
parent6798d03cfa5ed2f20a4cf33da1d31eba80b4714f (diff)
Merge branch 'marvell10g-phy-updates'
Russell King says: ==================== marvell10g updates This series: - adds MDI/MDIX reporting - adds support for 10/100Mbps half-duplex link modes - adds a comment describing the setup on VF610 ZII boards (where the phy interface mode doesn't change.) - cleans up the phy interace mode switching ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/phy/phy-core.c')
-rw-r--r--drivers/net/phy/phy-core.c43
1 files changed, 43 insertions, 0 deletions
diff --git a/drivers/net/phy/phy-core.c b/drivers/net/phy/phy-core.c
index 21f75ae244b3..c0ad08fa9d2c 100644
--- a/drivers/net/phy/phy-core.c
+++ b/drivers/net/phy/phy-core.c
@@ -189,6 +189,49 @@ size_t phy_speeds(unsigned int *speeds, size_t size,
return count;
}
+/**
+ * phy_resolve_aneg_linkmode - resolve the advertisments into phy settings
+ * @phydev: The phy_device struct
+ *
+ * Resolve our and the link partner advertisments into their corresponding
+ * speed and duplex. If full duplex was negotiated, extract the pause mode
+ * from the link partner mask.
+ */
+void phy_resolve_aneg_linkmode(struct phy_device *phydev)
+{
+ u32 common = phydev->lp_advertising & phydev->advertising;
+
+ if (common & ADVERTISED_10000baseT_Full) {
+ phydev->speed = SPEED_10000;
+ phydev->duplex = DUPLEX_FULL;
+ } else if (common & ADVERTISED_1000baseT_Full) {
+ phydev->speed = SPEED_1000;
+ phydev->duplex = DUPLEX_FULL;
+ } else if (common & ADVERTISED_1000baseT_Half) {
+ phydev->speed = SPEED_1000;
+ phydev->duplex = DUPLEX_HALF;
+ } else if (common & ADVERTISED_100baseT_Full) {
+ phydev->speed = SPEED_100;
+ phydev->duplex = DUPLEX_FULL;
+ } else if (common & ADVERTISED_100baseT_Half) {
+ phydev->speed = SPEED_100;
+ phydev->duplex = DUPLEX_HALF;
+ } else if (common & ADVERTISED_10baseT_Full) {
+ phydev->speed = SPEED_10;
+ phydev->duplex = DUPLEX_FULL;
+ } else if (common & ADVERTISED_10baseT_Half) {
+ phydev->speed = SPEED_10;
+ phydev->duplex = DUPLEX_HALF;
+ }
+
+ if (phydev->duplex == DUPLEX_FULL) {
+ phydev->pause = !!(phydev->lp_advertising & ADVERTISED_Pause);
+ phydev->asym_pause = !!(phydev->lp_advertising &
+ ADVERTISED_Asym_Pause);
+ }
+}
+EXPORT_SYMBOL_GPL(phy_resolve_aneg_linkmode);
+
static void mmd_phy_indirect(struct mii_bus *bus, int phy_addr, int devad,
u16 regnum)
{