summaryrefslogtreecommitdiff
path: root/drivers/net/phy/micrel.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/phy/micrel.c')
-rw-r--r--drivers/net/phy/micrel.c101
1 files changed, 71 insertions, 30 deletions
diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c
index 4516c8a4f..885ac9cba 100644
--- a/drivers/net/phy/micrel.c
+++ b/drivers/net/phy/micrel.c
@@ -311,6 +311,36 @@ static int kszphy_config_init(struct phy_device *phydev)
return 0;
}
+static int ksz8041_config_init(struct phy_device *phydev)
+{
+ struct device_node *of_node = phydev->mdio.dev.of_node;
+
+ /* Limit supported and advertised modes in fiber mode */
+ if (of_property_read_bool(of_node, "micrel,fiber-mode")) {
+ phydev->dev_flags |= MICREL_PHY_FXEN;
+ phydev->supported &= SUPPORTED_FIBRE |
+ SUPPORTED_100baseT_Full |
+ SUPPORTED_100baseT_Half;
+ phydev->advertising &= ADVERTISED_FIBRE |
+ ADVERTISED_100baseT_Full |
+ ADVERTISED_100baseT_Half;
+ phydev->autoneg = AUTONEG_DISABLE;
+ }
+
+ return kszphy_config_init(phydev);
+}
+
+static int ksz8041_config_aneg(struct phy_device *phydev)
+{
+ /* Skip auto-negotiation in fiber mode */
+ if (phydev->dev_flags & MICREL_PHY_FXEN) {
+ phydev->speed = SPEED_100;
+ return 0;
+ }
+
+ return genphy_config_aneg(phydev);
+}
+
static int ksz9021_load_values_from_of(struct phy_device *phydev,
const struct device_node *of_node,
u16 reg,
@@ -647,17 +677,28 @@ static void kszphy_get_stats(struct phy_device *phydev,
data[i] = kszphy_get_stat(phydev, i);
}
-static int kszphy_resume(struct phy_device *phydev)
+static int kszphy_suspend(struct phy_device *phydev)
{
- int value;
+ /* Disable PHY Interrupts */
+ if (phy_interrupt_is_valid(phydev)) {
+ phydev->interrupts = PHY_INTERRUPT_DISABLED;
+ if (phydev->drv->config_intr)
+ phydev->drv->config_intr(phydev);
+ }
- mutex_lock(&phydev->lock);
+ return genphy_suspend(phydev);
+}
- value = phy_read(phydev, MII_BMCR);
- phy_write(phydev, MII_BMCR, value & ~BMCR_PDOWN);
+static int kszphy_resume(struct phy_device *phydev)
+{
+ genphy_resume(phydev);
- kszphy_config_intr(phydev);
- mutex_unlock(&phydev->lock);
+ /* Enable PHY Interrupts */
+ if (phy_interrupt_is_valid(phydev)) {
+ phydev->interrupts = PHY_INTERRUPT_ENABLED;
+ if (phydev->drv->config_intr)
+ phydev->drv->config_intr(phydev);
+ }
return 0;
}
@@ -726,7 +767,7 @@ static int kszphy_probe(struct phy_device *phydev)
static struct phy_driver ksphy_driver[] = {
{
.phy_id = PHY_ID_KS8737,
- .phy_id_mask = 0x00fffff0,
+ .phy_id_mask = MICREL_PHY_ID_MASK,
.name = "Micrel KS8737",
.features = (PHY_BASIC_FEATURES | SUPPORTED_Pause),
.flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
@@ -781,15 +822,15 @@ static struct phy_driver ksphy_driver[] = {
.resume = genphy_resume,
}, {
.phy_id = PHY_ID_KSZ8041,
- .phy_id_mask = 0x00fffff0,
+ .phy_id_mask = MICREL_PHY_ID_MASK,
.name = "Micrel KSZ8041",
.features = (PHY_BASIC_FEATURES | SUPPORTED_Pause
| SUPPORTED_Asym_Pause),
.flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
.driver_data = &ksz8041_type,
.probe = kszphy_probe,
- .config_init = kszphy_config_init,
- .config_aneg = genphy_config_aneg,
+ .config_init = ksz8041_config_init,
+ .config_aneg = ksz8041_config_aneg,
.read_status = genphy_read_status,
.ack_interrupt = kszphy_ack_interrupt,
.config_intr = kszphy_config_intr,
@@ -800,7 +841,7 @@ static struct phy_driver ksphy_driver[] = {
.resume = genphy_resume,
}, {
.phy_id = PHY_ID_KSZ8041RNLI,
- .phy_id_mask = 0x00fffff0,
+ .phy_id_mask = MICREL_PHY_ID_MASK,
.name = "Micrel KSZ8041RNLI",
.features = PHY_BASIC_FEATURES |
SUPPORTED_Pause | SUPPORTED_Asym_Pause,
@@ -819,7 +860,7 @@ static struct phy_driver ksphy_driver[] = {
.resume = genphy_resume,
}, {
.phy_id = PHY_ID_KSZ8051,
- .phy_id_mask = 0x00fffff0,
+ .phy_id_mask = MICREL_PHY_ID_MASK,
.name = "Micrel KSZ8051",
.features = (PHY_BASIC_FEATURES | SUPPORTED_Pause
| SUPPORTED_Asym_Pause),
@@ -839,7 +880,7 @@ static struct phy_driver ksphy_driver[] = {
}, {
.phy_id = PHY_ID_KSZ8001,
.name = "Micrel KSZ8001 or KS8721",
- .phy_id_mask = 0x00ffffff,
+ .phy_id_mask = 0x00fffffc,
.features = (PHY_BASIC_FEATURES | SUPPORTED_Pause),
.flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
.driver_data = &ksz8041_type,
@@ -857,7 +898,7 @@ static struct phy_driver ksphy_driver[] = {
}, {
.phy_id = PHY_ID_KSZ8081,
.name = "Micrel KSZ8081 or KSZ8091",
- .phy_id_mask = 0x00fffff0,
+ .phy_id_mask = MICREL_PHY_ID_MASK,
.features = (PHY_BASIC_FEATURES | SUPPORTED_Pause),
.flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
.driver_data = &ksz8081_type,
@@ -870,12 +911,12 @@ static struct phy_driver ksphy_driver[] = {
.get_sset_count = kszphy_get_sset_count,
.get_strings = kszphy_get_strings,
.get_stats = kszphy_get_stats,
- .suspend = genphy_suspend,
+ .suspend = kszphy_suspend,
.resume = kszphy_resume,
}, {
.phy_id = PHY_ID_KSZ8061,
.name = "Micrel KSZ8061",
- .phy_id_mask = 0x00fffff0,
+ .phy_id_mask = MICREL_PHY_ID_MASK,
.features = (PHY_BASIC_FEATURES | SUPPORTED_Pause),
.flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
.config_init = kszphy_config_init,
@@ -909,7 +950,7 @@ static struct phy_driver ksphy_driver[] = {
.write_mmd_indirect = ksz9021_wr_mmd_phyreg,
}, {
.phy_id = PHY_ID_KSZ9031,
- .phy_id_mask = 0x00fffff0,
+ .phy_id_mask = MICREL_PHY_ID_MASK,
.name = "Micrel KSZ9031 Gigabit PHY",
.features = (PHY_GBIT_FEATURES | SUPPORTED_Pause),
.flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
@@ -923,10 +964,10 @@ static struct phy_driver ksphy_driver[] = {
.get_strings = kszphy_get_strings,
.get_stats = kszphy_get_stats,
.suspend = genphy_suspend,
- .resume = genphy_resume,
+ .resume = kszphy_resume,
}, {
.phy_id = PHY_ID_KSZ8873MLL,
- .phy_id_mask = 0x00fffff0,
+ .phy_id_mask = MICREL_PHY_ID_MASK,
.name = "Micrel KSZ8873MLL Switch",
.features = (SUPPORTED_Pause | SUPPORTED_Asym_Pause),
.flags = PHY_HAS_MAGICANEG,
@@ -940,7 +981,7 @@ static struct phy_driver ksphy_driver[] = {
.resume = genphy_resume,
}, {
.phy_id = PHY_ID_KSZ886X,
- .phy_id_mask = 0x00fffff0,
+ .phy_id_mask = MICREL_PHY_ID_MASK,
.name = "Micrel KSZ886X Switch",
.features = (PHY_BASIC_FEATURES | SUPPORTED_Pause),
.flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
@@ -962,17 +1003,17 @@ MODULE_LICENSE("GPL");
static struct mdio_device_id __maybe_unused micrel_tbl[] = {
{ PHY_ID_KSZ9021, 0x000ffffe },
- { PHY_ID_KSZ9031, 0x00fffff0 },
- { PHY_ID_KSZ8001, 0x00ffffff },
- { PHY_ID_KS8737, 0x00fffff0 },
+ { PHY_ID_KSZ9031, MICREL_PHY_ID_MASK },
+ { PHY_ID_KSZ8001, 0x00fffffc },
+ { PHY_ID_KS8737, MICREL_PHY_ID_MASK },
{ PHY_ID_KSZ8021, 0x00ffffff },
{ PHY_ID_KSZ8031, 0x00ffffff },
- { PHY_ID_KSZ8041, 0x00fffff0 },
- { PHY_ID_KSZ8051, 0x00fffff0 },
- { PHY_ID_KSZ8061, 0x00fffff0 },
- { PHY_ID_KSZ8081, 0x00fffff0 },
- { PHY_ID_KSZ8873MLL, 0x00fffff0 },
- { PHY_ID_KSZ886X, 0x00fffff0 },
+ { PHY_ID_KSZ8041, MICREL_PHY_ID_MASK },
+ { PHY_ID_KSZ8051, MICREL_PHY_ID_MASK },
+ { PHY_ID_KSZ8061, MICREL_PHY_ID_MASK },
+ { PHY_ID_KSZ8081, MICREL_PHY_ID_MASK },
+ { PHY_ID_KSZ8873MLL, MICREL_PHY_ID_MASK },
+ { PHY_ID_KSZ886X, MICREL_PHY_ID_MASK },
{ }
};