Skip to content

Commit a585c03

Browse files
Russell Kingdavem330
authored andcommitted
net: phy: marvell10g: add energy detect power down tunable
Add support for the energy detect power down tunable, which saves around 600mW when the link is down. The 88x3310 supports off, rx-only and NLP every second. Enable EDPD by default for 88x3310. Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> Reviewed-by: Andrew Lunn <andrew@lunn.ch> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 8d8963c commit a585c03

File tree

1 file changed

+85
-1
lines changed

1 file changed

+85
-1
lines changed

drivers/net/phy/marvell10g.c

Lines changed: 85 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,10 @@ enum {
4141
MV_PCS_1000BASEX = 0x2000,
4242

4343
MV_PCS_CSCR1 = 0x8000,
44+
MV_PCS_CSCR1_ED_MASK = 0x0300,
45+
MV_PCS_CSCR1_ED_OFF = 0x0000,
46+
MV_PCS_CSCR1_ED_RX = 0x0200,
47+
MV_PCS_CSCR1_ED_NLP = 0x0300,
4448
MV_PCS_CSCR1_MDIX_MASK = 0x0060,
4549
MV_PCS_CSCR1_MDIX_MDI = 0x0000,
4650
MV_PCS_CSCR1_MDIX_MDIX = 0x0020,
@@ -243,6 +247,59 @@ static int mv3310_reset(struct phy_device *phydev, u32 unit)
243247
return val & MDIO_CTRL1_RESET ? -ETIMEDOUT : 0;
244248
}
245249

250+
static int mv3310_get_edpd(struct phy_device *phydev, u16 *edpd)
251+
{
252+
int val;
253+
254+
val = phy_read_mmd(phydev, MDIO_MMD_PCS, MV_PCS_CSCR1);
255+
if (val < 0)
256+
return val;
257+
258+
switch (val & MV_PCS_CSCR1_ED_MASK) {
259+
case MV_PCS_CSCR1_ED_NLP:
260+
*edpd = 1000;
261+
break;
262+
case MV_PCS_CSCR1_ED_RX:
263+
*edpd = ETHTOOL_PHY_EDPD_NO_TX;
264+
break;
265+
default:
266+
*edpd = ETHTOOL_PHY_EDPD_DISABLE;
267+
break;
268+
}
269+
return 0;
270+
}
271+
272+
static int mv3310_set_edpd(struct phy_device *phydev, u16 edpd)
273+
{
274+
u16 val;
275+
int err;
276+
277+
switch (edpd) {
278+
case 1000:
279+
case ETHTOOL_PHY_EDPD_DFLT_TX_MSECS:
280+
val = MV_PCS_CSCR1_ED_NLP;
281+
break;
282+
283+
case ETHTOOL_PHY_EDPD_NO_TX:
284+
val = MV_PCS_CSCR1_ED_RX;
285+
break;
286+
287+
case ETHTOOL_PHY_EDPD_DISABLE:
288+
val = MV_PCS_CSCR1_ED_OFF;
289+
break;
290+
291+
default:
292+
return -EINVAL;
293+
}
294+
295+
err = phy_modify_mmd_changed(phydev, MDIO_MMD_PCS, MV_PCS_CSCR1,
296+
MV_PCS_CSCR1_ED_MASK, val);
297+
if (err > 0)
298+
err = mv3310_reset(phydev, MV_PCS_BASE_T);
299+
300+
return err;
301+
}
302+
246303
static int mv3310_sfp_insert(void *upstream, const struct sfp_eeprom_id *id)
247304
{
248305
struct phy_device *phydev = upstream;
@@ -345,7 +402,8 @@ static int mv3310_config_init(struct phy_device *phydev)
345402

346403
phydev->mdix_ctrl = ETH_TP_MDI_AUTO;
347404

348-
return 0;
405+
/* Enable EDPD mode - saving 600mW */
406+
return mv3310_set_edpd(phydev, ETHTOOL_PHY_EDPD_DFLT_TX_MSECS);
349407
}
350408

351409
static int mv3310_get_features(struct phy_device *phydev)
@@ -594,6 +652,28 @@ static int mv3310_read_status(struct phy_device *phydev)
594652
return 0;
595653
}
596654

655+
static int mv3310_get_tunable(struct phy_device *phydev,
656+
struct ethtool_tunable *tuna, void *data)
657+
{
658+
switch (tuna->id) {
659+
case ETHTOOL_PHY_EDPD:
660+
return mv3310_get_edpd(phydev, data);
661+
default:
662+
return -EOPNOTSUPP;
663+
}
664+
}
665+
666+
static int mv3310_set_tunable(struct phy_device *phydev,
667+
struct ethtool_tunable *tuna, const void *data)
668+
{
669+
switch (tuna->id) {
670+
case ETHTOOL_PHY_EDPD:
671+
return mv3310_set_edpd(phydev, *(u16 *)data);
672+
default:
673+
return -EOPNOTSUPP;
674+
}
675+
}
676+
597677
static struct phy_driver mv3310_drivers[] = {
598678
{
599679
.phy_id = MARVELL_PHY_ID_88X3310,
@@ -608,6 +688,8 @@ static struct phy_driver mv3310_drivers[] = {
608688
.config_aneg = mv3310_config_aneg,
609689
.aneg_done = mv3310_aneg_done,
610690
.read_status = mv3310_read_status,
691+
.get_tunable = mv3310_get_tunable,
692+
.set_tunable = mv3310_set_tunable,
611693
},
612694
{
613695
.phy_id = MARVELL_PHY_ID_88E2110,
@@ -621,6 +703,8 @@ static struct phy_driver mv3310_drivers[] = {
621703
.config_aneg = mv3310_config_aneg,
622704
.aneg_done = mv3310_aneg_done,
623705
.read_status = mv3310_read_status,
706+
.get_tunable = mv3310_get_tunable,
707+
.set_tunable = mv3310_set_tunable,
624708
},
625709
};
626710

0 commit comments

Comments
 (0)