summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/net/pcs/pcs-xpcs.c18
-rw-r--r--drivers/net/phy/marvell.c10
-rw-r--r--drivers/net/phy/phy_device.c18
-rw-r--r--include/linux/mii.h35
4 files changed, 41 insertions, 40 deletions
diff --git a/drivers/net/pcs/pcs-xpcs.c b/drivers/net/pcs/pcs-xpcs.c
index a5d520e34ea3..ab0af1d2531f 100644
--- a/drivers/net/pcs/pcs-xpcs.c
+++ b/drivers/net/pcs/pcs-xpcs.c
@@ -1081,23 +1081,7 @@ static void xpcs_link_up_sgmii(struct dw_xpcs *xpcs, unsigned int mode,
if (phylink_autoneg_inband(mode))
return;
- switch (speed) {
- case SPEED_1000:
- val = BMCR_SPEED1000;
- break;
- case SPEED_100:
- val = BMCR_SPEED100;
- break;
- case SPEED_10:
- val = BMCR_SPEED10;
- break;
- default:
- return;
- }
-
- if (duplex == DUPLEX_FULL)
- val |= BMCR_FULLDPLX;
-
+ val = mii_bmcr_encode_fixed(speed, duplex);
ret = xpcs_write(xpcs, MDIO_MMD_VEND2, MDIO_CTRL1, val);
if (ret)
pr_err("%s: xpcs_write returned %pe\n", __func__, ERR_PTR(ret));
diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c
index d777c8851ed6..a714150f5e8c 100644
--- a/drivers/net/phy/marvell.c
+++ b/drivers/net/phy/marvell.c
@@ -1991,15 +1991,9 @@ static int m88e1510_loopback(struct phy_device *phydev, bool enable)
int err;
if (enable) {
- u16 bmcr_ctl = 0, mscr2_ctl = 0;
+ u16 bmcr_ctl, mscr2_ctl = 0;
- if (phydev->speed == SPEED_1000)
- bmcr_ctl = BMCR_SPEED1000;
- else if (phydev->speed == SPEED_100)
- bmcr_ctl = BMCR_SPEED100;
-
- if (phydev->duplex == DUPLEX_FULL)
- bmcr_ctl |= BMCR_FULLDPLX;
+ bmcr_ctl = mii_bmcr_encode_fixed(phydev->speed, phydev->duplex);
err = phy_write(phydev, MII_BMCR, bmcr_ctl);
if (err < 0)
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index 431a8719c635..7885bceff773 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -2001,18 +2001,12 @@ EXPORT_SYMBOL(genphy_config_eee_advert);
*/
int genphy_setup_forced(struct phy_device *phydev)
{
- u16 ctl = 0;
+ u16 ctl;
phydev->pause = 0;
phydev->asym_pause = 0;
- if (SPEED_1000 == phydev->speed)
- ctl |= BMCR_SPEED1000;
- else if (SPEED_100 == phydev->speed)
- ctl |= BMCR_SPEED100;
-
- if (DUPLEX_FULL == phydev->duplex)
- ctl |= BMCR_FULLDPLX;
+ ctl = mii_bmcr_encode_fixed(phydev->speed, phydev->duplex);
return phy_modify(phydev, MII_BMCR,
~(BMCR_LOOPBACK | BMCR_ISOLATE | BMCR_PDOWN), ctl);
@@ -2614,13 +2608,7 @@ int genphy_loopback(struct phy_device *phydev, bool enable)
u16 val, ctl = BMCR_LOOPBACK;
int ret;
- if (phydev->speed == SPEED_1000)
- ctl |= BMCR_SPEED1000;
- else if (phydev->speed == SPEED_100)
- ctl |= BMCR_SPEED100;
-
- if (phydev->duplex == DUPLEX_FULL)
- ctl |= BMCR_FULLDPLX;
+ ctl |= mii_bmcr_encode_fixed(phydev->speed, phydev->duplex);
phy_modify(phydev, MII_BMCR, ~0, ctl);
diff --git a/include/linux/mii.h b/include/linux/mii.h
index 5ee13083cec7..d5a959ce4877 100644
--- a/include/linux/mii.h
+++ b/include/linux/mii.h
@@ -545,4 +545,39 @@ static inline u8 mii_resolve_flowctrl_fdx(u16 lcladv, u16 rmtadv)
return cap;
}
+/**
+ * mii_bmcr_encode_fixed - encode fixed speed/duplex settings to a BMCR value
+ * @speed: a SPEED_* value
+ * @duplex: a DUPLEX_* value
+ *
+ * Encode the speed and duplex to a BMCR value. 2500, 1000, 100 and 10 Mbps are
+ * supported. 2500Mbps is encoded to 1000Mbps. Other speeds are encoded as 10
+ * Mbps. Unknown duplex values are encoded to half-duplex.
+ */
+static inline u16 mii_bmcr_encode_fixed(int speed, int duplex)
+{
+ u16 bmcr;
+
+ switch (speed) {
+ case SPEED_2500:
+ case SPEED_1000:
+ bmcr = BMCR_SPEED1000;
+ break;
+
+ case SPEED_100:
+ bmcr = BMCR_SPEED100;
+ break;
+
+ case SPEED_10:
+ default:
+ bmcr = BMCR_SPEED10;
+ break;
+ }
+
+ if (duplex == DUPLEX_FULL)
+ bmcr |= BMCR_FULLDPLX;
+
+ return bmcr;
+}
+
#endif /* __LINUX_MII_H__ */