Message ID | 20240227093945.21525-5-bastien.curutchet@bootlin.com (mailing list archive) |
---|---|
State | Changes Requested |
Delegated to: | Netdev Maintainers |
Headers | show |
Series | net: phy: Add TI's DP83640 device tree binding | expand |
Hello Bastien, On Tue, 27 Feb 2024 10:39:43 +0100 Bastien Curutchet <bastien.curutchet@bootlin.com> wrote: > The driver does not support enabling/disabling Energy Detect Power Down > (EDPD). > The PHY itself support EDPD. > > Add missing part in the driver in order to have this support based on > ethtool {set,get}_phy_tunable functions. > > Signed-off-by: Bastien Curutchet <bastien.curutchet@bootlin.com> > --- > drivers/net/phy/dp83640.c | 62 +++++++++++++++++++++++++++++++++++ > drivers/net/phy/dp83640_reg.h | 4 +++ > 2 files changed, 66 insertions(+) > > diff --git a/drivers/net/phy/dp83640.c b/drivers/net/phy/dp83640.c > index c46c81ef0ad0..16c9fda50b19 100644 > --- a/drivers/net/phy/dp83640.c > +++ b/drivers/net/phy/dp83640.c > @@ -1531,6 +1531,66 @@ static void dp83640_remove(struct phy_device *phydev) > kfree(dp83640); > } > > +static int dp83640_get_edpd(struct phy_device *phydev, u16 *edpd) > +{ > + int val; > + > + phy_write(phydev, PAGESEL, 0); Same comment as the previous patch on paged accesses > + val = phy_read(phydev, EDCR); > + if (val & ED_EN) > + *edpd = 2000; /* 2 seconds */ > + else > + *edpd = ETHTOOL_PHY_EDPD_DISABLE; > + > + return 0; > +} > + > +static int dp83640_set_edpd(struct phy_device *phydev, u16 edpd) > +{ > + int val; > + > + phy_write(phydev, PAGESEL, 0); ditto > + val = phy_read(phydev, EDCR); > + > + switch (edpd) { > + case ETHTOOL_PHY_EDPD_DFLT_TX_MSECS: > + case 2000: /* 2 seconds */ > + val |= ED_EN; > + break; > + case ETHTOOL_PHY_EDPD_DISABLE: > + val &= ~ED_EN; > + break; > + default: > + return -EINVAL; > + } > + > + phy_write(phydev, EDCR, val); Here you could use phy_clear_bits / phy_set_bits, which are flavors of the phy_modify accessors. > + > + return 0; > +} > + > +static int dp83640_get_tunable(struct phy_device *phydev, > + struct ethtool_tunable *tuna, void *data) > +{ > + switch (tuna->id) { > + case ETHTOOL_PHY_EDPD: > + return dp83640_get_edpd(phydev, data); > + default: > + return -EOPNOTSUPP; > + } > +} > + > +static int dp83640_set_tunable(struct phy_device *phydev, > + struct ethtool_tunable *tuna, const void *data) > +{ > + switch (tuna->id) { > + case ETHTOOL_PHY_EDPD: > + return dp83640_set_edpd(phydev, *(u16 *)data); > + default: > + return -EOPNOTSUPP; > + } > +} > + > static int dp83640_led_brightness_set(struct phy_device *phydev, u8 index, > enum led_brightness brightness) > { > @@ -1692,6 +1752,8 @@ static struct phy_driver dp83640_driver = { > .name = "NatSemi DP83640", > /* PHY_BASIC_FEATURES */ > .probe = dp83640_probe, > + .get_tunable = dp83640_get_tunable, > + .set_tunable = dp83640_set_tunable, > .remove = dp83640_remove, > .soft_reset = dp83640_soft_reset, > .config_init = dp83640_config_init, > diff --git a/drivers/net/phy/dp83640_reg.h b/drivers/net/phy/dp83640_reg.h > index 09dd2d2527c7..bf34d422d91e 100644 > --- a/drivers/net/phy/dp83640_reg.h > +++ b/drivers/net/phy/dp83640_reg.h > @@ -9,6 +9,7 @@ > #define LEDCR 0x0018 /* PHY Control Register */ > #define PHYCR 0x0019 /* PHY Control Register */ > #define PHYCR2 0x001c /* PHY Control Register 2 */ > +#define EDCR 0x001D /* Energy Detect Control Register */ > > #define PAGE4 0x0004 > #define PTP_CTL 0x0014 /* PTP Control Register */ > @@ -64,6 +65,9 @@ > /* Bit definitions for the PHYCR2 register */ > #define BC_WRITE (1<<11) /* Broadcast Write Enable */ > > +/* Bit definitions for the EDCR register */ > +#define ED_EN BIT(15) /* Enable Energy Detect Mode */ > + > /* Bit definitions for the PTP_CTL register */ > #define TRIG_SEL_SHIFT (10) /* PTP Trigger Select */ > #define TRIG_SEL_MASK (0x7) Thanks, Maxime
diff --git a/drivers/net/phy/dp83640.c b/drivers/net/phy/dp83640.c index c46c81ef0ad0..16c9fda50b19 100644 --- a/drivers/net/phy/dp83640.c +++ b/drivers/net/phy/dp83640.c @@ -1531,6 +1531,66 @@ static void dp83640_remove(struct phy_device *phydev) kfree(dp83640); } +static int dp83640_get_edpd(struct phy_device *phydev, u16 *edpd) +{ + int val; + + phy_write(phydev, PAGESEL, 0); + val = phy_read(phydev, EDCR); + if (val & ED_EN) + *edpd = 2000; /* 2 seconds */ + else + *edpd = ETHTOOL_PHY_EDPD_DISABLE; + + return 0; +} + +static int dp83640_set_edpd(struct phy_device *phydev, u16 edpd) +{ + int val; + + phy_write(phydev, PAGESEL, 0); + val = phy_read(phydev, EDCR); + + switch (edpd) { + case ETHTOOL_PHY_EDPD_DFLT_TX_MSECS: + case 2000: /* 2 seconds */ + val |= ED_EN; + break; + case ETHTOOL_PHY_EDPD_DISABLE: + val &= ~ED_EN; + break; + default: + return -EINVAL; + } + + phy_write(phydev, EDCR, val); + + return 0; +} + +static int dp83640_get_tunable(struct phy_device *phydev, + struct ethtool_tunable *tuna, void *data) +{ + switch (tuna->id) { + case ETHTOOL_PHY_EDPD: + return dp83640_get_edpd(phydev, data); + default: + return -EOPNOTSUPP; + } +} + +static int dp83640_set_tunable(struct phy_device *phydev, + struct ethtool_tunable *tuna, const void *data) +{ + switch (tuna->id) { + case ETHTOOL_PHY_EDPD: + return dp83640_set_edpd(phydev, *(u16 *)data); + default: + return -EOPNOTSUPP; + } +} + static int dp83640_led_brightness_set(struct phy_device *phydev, u8 index, enum led_brightness brightness) { @@ -1692,6 +1752,8 @@ static struct phy_driver dp83640_driver = { .name = "NatSemi DP83640", /* PHY_BASIC_FEATURES */ .probe = dp83640_probe, + .get_tunable = dp83640_get_tunable, + .set_tunable = dp83640_set_tunable, .remove = dp83640_remove, .soft_reset = dp83640_soft_reset, .config_init = dp83640_config_init, diff --git a/drivers/net/phy/dp83640_reg.h b/drivers/net/phy/dp83640_reg.h index 09dd2d2527c7..bf34d422d91e 100644 --- a/drivers/net/phy/dp83640_reg.h +++ b/drivers/net/phy/dp83640_reg.h @@ -9,6 +9,7 @@ #define LEDCR 0x0018 /* PHY Control Register */ #define PHYCR 0x0019 /* PHY Control Register */ #define PHYCR2 0x001c /* PHY Control Register 2 */ +#define EDCR 0x001D /* Energy Detect Control Register */ #define PAGE4 0x0004 #define PTP_CTL 0x0014 /* PTP Control Register */ @@ -64,6 +65,9 @@ /* Bit definitions for the PHYCR2 register */ #define BC_WRITE (1<<11) /* Broadcast Write Enable */ +/* Bit definitions for the EDCR register */ +#define ED_EN BIT(15) /* Enable Energy Detect Mode */ + /* Bit definitions for the PTP_CTL register */ #define TRIG_SEL_SHIFT (10) /* PTP Trigger Select */ #define TRIG_SEL_MASK (0x7)
The driver does not support enabling/disabling Energy Detect Power Down (EDPD). The PHY itself support EDPD. Add missing part in the driver in order to have this support based on ethtool {set,get}_phy_tunable functions. Signed-off-by: Bastien Curutchet <bastien.curutchet@bootlin.com> --- drivers/net/phy/dp83640.c | 62 +++++++++++++++++++++++++++++++++++ drivers/net/phy/dp83640_reg.h | 4 +++ 2 files changed, 66 insertions(+)