Commit fa288a42 authored by David S. Miller's avatar David S. Miller

Merge branch 'genphy_read_abilities'

Heiner Kallweit says:

====================
net: phy: add and use new function genphy_read_abilities

Similar to genphy_c45_pma_read_abilities() add a function to dynamically
detect the abilities of a Clause 22 PHY. This is mainly copied from
genphy_config_init(). Main benefit is that PHY drivers no longer have
to specify whether they support GBit or not (provided they keep to
the C22 standard).
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 6d670497 48e4adf9
......@@ -1880,6 +1880,54 @@ int genphy_config_init(struct phy_device *phydev)
}
EXPORT_SYMBOL(genphy_config_init);
/**
* genphy_read_abilities - read PHY abilities from Clause 22 registers
* @phydev: target phy_device struct
*
* Description: Reads the PHY's abilities and populates
* phydev->supported accordingly.
*
* Returns: 0 on success, < 0 on failure
*/
int genphy_read_abilities(struct phy_device *phydev)
{
int val;
linkmode_set_bit_array(phy_basic_ports_array,
ARRAY_SIZE(phy_basic_ports_array),
phydev->supported);
val = phy_read(phydev, MII_BMSR);
if (val < 0)
return val;
linkmode_mod_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, phydev->supported,
val & BMSR_ANEGCAPABLE);
linkmode_mod_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT, phydev->supported,
val & BMSR_100FULL);
linkmode_mod_bit(ETHTOOL_LINK_MODE_100baseT_Half_BIT, phydev->supported,
val & BMSR_100HALF);
linkmode_mod_bit(ETHTOOL_LINK_MODE_10baseT_Full_BIT, phydev->supported,
val & BMSR_10FULL);
linkmode_mod_bit(ETHTOOL_LINK_MODE_10baseT_Half_BIT, phydev->supported,
val & BMSR_10HALF);
if (val & BMSR_ESTATEN) {
val = phy_read(phydev, MII_ESTATUS);
if (val < 0)
return val;
linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
phydev->supported, val & ESTATUS_1000_TFULL);
linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT,
phydev->supported, val & ESTATUS_1000_THALF);
}
return 0;
}
EXPORT_SYMBOL(genphy_read_abilities);
/* This is used for the phy device which doesn't support the MMD extended
* register access, but it does have side effect when we are trying to access
* the MMD register via indirect method.
......@@ -2236,8 +2284,7 @@ static struct phy_driver genphy_driver = {
.phy_id_mask = 0xffffffff,
.name = "Generic PHY",
.soft_reset = genphy_no_soft_reset,
.config_init = genphy_config_init,
.features = PHY_GBIT_ALL_PORTS_FEATURES,
.get_features = genphy_read_abilities,
.aneg_done = genphy_aneg_done,
.suspend = genphy_suspend,
.resume = genphy_resume,
......
......@@ -151,21 +151,14 @@ static int rtl8211_config_aneg(struct phy_device *phydev)
static int rtl8211c_config_init(struct phy_device *phydev)
{
/* RTL8211C has an issue when operating in Gigabit slave mode */
phy_set_bits(phydev, MII_CTRL1000,
CTL1000_ENABLE_MASTER | CTL1000_AS_MASTER);
return genphy_config_init(phydev);
return phy_set_bits(phydev, MII_CTRL1000,
CTL1000_ENABLE_MASTER | CTL1000_AS_MASTER);
}
static int rtl8211f_config_init(struct phy_device *phydev)
{
int ret;
u16 val = 0;
ret = genphy_config_init(phydev);
if (ret < 0)
return ret;
/* enable TX-delay for rgmii-id and rgmii-txid, otherwise disable it */
if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID ||
phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID)
......@@ -192,10 +185,6 @@ static int rtl8366rb_config_init(struct phy_device *phydev)
{
int ret;
ret = genphy_config_init(phydev);
if (ret < 0)
return ret;
ret = phy_set_bits(phydev, RTL8366RB_POWER_SAVE,
RTL8366RB_POWER_SAVE_ON);
if (ret) {
......@@ -210,11 +199,11 @@ static struct phy_driver realtek_drvs[] = {
{
PHY_ID_MATCH_EXACT(0x00008201),
.name = "RTL8201CP Ethernet",
.features = PHY_BASIC_FEATURES,
.get_features = genphy_read_abilities,
}, {
PHY_ID_MATCH_EXACT(0x001cc816),
.name = "RTL8201F Fast Ethernet",
.features = PHY_BASIC_FEATURES,
.get_features = genphy_read_abilities,
.ack_interrupt = &rtl8201_ack_interrupt,
.config_intr = &rtl8201_config_intr,
.suspend = genphy_suspend,
......@@ -224,14 +213,14 @@ static struct phy_driver realtek_drvs[] = {
}, {
PHY_ID_MATCH_EXACT(0x001cc910),
.name = "RTL8211 Gigabit Ethernet",
.features = PHY_GBIT_FEATURES,
.get_features = genphy_read_abilities,
.config_aneg = rtl8211_config_aneg,
.read_mmd = &genphy_read_mmd_unsupported,
.write_mmd = &genphy_write_mmd_unsupported,
}, {
PHY_ID_MATCH_EXACT(0x001cc912),
.name = "RTL8211B Gigabit Ethernet",
.features = PHY_GBIT_FEATURES,
.get_features = genphy_read_abilities,
.ack_interrupt = &rtl821x_ack_interrupt,
.config_intr = &rtl8211b_config_intr,
.read_mmd = &genphy_read_mmd_unsupported,
......@@ -241,14 +230,14 @@ static struct phy_driver realtek_drvs[] = {
}, {
PHY_ID_MATCH_EXACT(0x001cc913),
.name = "RTL8211C Gigabit Ethernet",
.features = PHY_GBIT_FEATURES,
.get_features = genphy_read_abilities,
.config_init = rtl8211c_config_init,
.read_mmd = &genphy_read_mmd_unsupported,
.write_mmd = &genphy_write_mmd_unsupported,
}, {
PHY_ID_MATCH_EXACT(0x001cc914),
.name = "RTL8211DN Gigabit Ethernet",
.features = PHY_GBIT_FEATURES,
.get_features = genphy_read_abilities,
.ack_interrupt = rtl821x_ack_interrupt,
.config_intr = rtl8211e_config_intr,
.suspend = genphy_suspend,
......@@ -256,7 +245,7 @@ static struct phy_driver realtek_drvs[] = {
}, {
PHY_ID_MATCH_EXACT(0x001cc915),
.name = "RTL8211E Gigabit Ethernet",
.features = PHY_GBIT_FEATURES,
.get_features = genphy_read_abilities,
.ack_interrupt = &rtl821x_ack_interrupt,
.config_intr = &rtl8211e_config_intr,
.suspend = genphy_suspend,
......@@ -264,7 +253,7 @@ static struct phy_driver realtek_drvs[] = {
}, {
PHY_ID_MATCH_EXACT(0x001cc916),
.name = "RTL8211F Gigabit Ethernet",
.features = PHY_GBIT_FEATURES,
.get_features = genphy_read_abilities,
.config_init = &rtl8211f_config_init,
.ack_interrupt = &rtl8211f_ack_interrupt,
.config_intr = &rtl8211f_config_intr,
......@@ -275,8 +264,7 @@ static struct phy_driver realtek_drvs[] = {
}, {
PHY_ID_MATCH_EXACT(0x001cc800),
.name = "Generic Realtek PHY",
.features = PHY_GBIT_FEATURES,
.config_init = genphy_config_init,
.get_features = genphy_read_abilities,
.suspend = genphy_suspend,
.resume = genphy_resume,
.read_page = rtl821x_read_page,
......@@ -284,7 +272,7 @@ static struct phy_driver realtek_drvs[] = {
}, {
PHY_ID_MATCH_EXACT(0x001cc961),
.name = "RTL8366RB Gigabit Ethernet",
.features = PHY_GBIT_FEATURES,
.get_features = genphy_read_abilities,
.config_init = &rtl8366rb_config_init,
/* These interrupts are handled by the irq controller
* embedded inside the RTL8366RB, they get unmasked when the
......
......@@ -1075,6 +1075,7 @@ void phy_attached_info(struct phy_device *phydev);
/* Clause 22 PHY */
int genphy_config_init(struct phy_device *phydev);
int genphy_read_abilities(struct phy_device *phydev);
int genphy_setup_forced(struct phy_device *phydev);
int genphy_restart_aneg(struct phy_device *phydev);
int genphy_config_eee_advert(struct phy_device *phydev);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment