Commit 77501a79 authored by Philipp Zabel's avatar Philipp Zabel Committed by David S. Miller

net: phy: micrel: Add KSZ8041FTL fiber mode support

We can't detect the FXEN (fiber mode) bootstrap pin, so configure
it via a boolean device tree property "micrel,fiber-mode".
If it is enabled, auto-negotiation is not supported.
The only available modes are 100base-fx (full duplex and half duplex).
Signed-off-by: default avatarPhilipp Zabel <p.zabel@pengutronix.de>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 2f43b9be
...@@ -35,3 +35,13 @@ Optional properties: ...@@ -35,3 +35,13 @@ Optional properties:
supported clocks: supported clocks:
- KSZ8021, KSZ8031, KSZ8081, KSZ8091: "rmii-ref": The RMII reference - KSZ8021, KSZ8031, KSZ8081, KSZ8091: "rmii-ref": The RMII reference
input clock. Used to determine the XI input clock. input clock. Used to determine the XI input clock.
- micrel,fiber-mode: If present the PHY is configured to operate in fiber mode
Some PHYs, such as the KSZ8041FTL variant, support fiber mode, enabled
by the FXEN boot strapping pin. It can't be determined from the PHY
registers whether the PHY is in fiber mode, so this boolean device tree
property can be used to describe it.
In fiber mode, auto-negotiation is disabled and the PHY can only work in
100base-fx (full and half duplex) modes.
...@@ -311,6 +311,36 @@ static int kszphy_config_init(struct phy_device *phydev) ...@@ -311,6 +311,36 @@ static int kszphy_config_init(struct phy_device *phydev)
return 0; 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, static int ksz9021_load_values_from_of(struct phy_device *phydev,
const struct device_node *of_node, const struct device_node *of_node,
u16 reg, u16 reg,
...@@ -788,8 +818,8 @@ static struct phy_driver ksphy_driver[] = { ...@@ -788,8 +818,8 @@ static struct phy_driver ksphy_driver[] = {
.flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT, .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
.driver_data = &ksz8041_type, .driver_data = &ksz8041_type,
.probe = kszphy_probe, .probe = kszphy_probe,
.config_init = kszphy_config_init, .config_init = ksz8041_config_init,
.config_aneg = genphy_config_aneg, .config_aneg = ksz8041_config_aneg,
.read_status = genphy_read_status, .read_status = genphy_read_status,
.ack_interrupt = kszphy_ack_interrupt, .ack_interrupt = kszphy_ack_interrupt,
.config_intr = kszphy_config_intr, .config_intr = kszphy_config_intr,
......
...@@ -37,6 +37,7 @@ ...@@ -37,6 +37,7 @@
/* struct phy_device dev_flags definitions */ /* struct phy_device dev_flags definitions */
#define MICREL_PHY_50MHZ_CLK 0x00000001 #define MICREL_PHY_50MHZ_CLK 0x00000001
#define MICREL_PHY_FXEN 0x00000002
#define MICREL_KSZ9021_EXTREG_CTRL 0xB #define MICREL_KSZ9021_EXTREG_CTRL 0xB
#define MICREL_KSZ9021_EXTREG_DATA_WRITE 0xC #define MICREL_KSZ9021_EXTREG_DATA_WRITE 0xC
......
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