Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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: Philipp Zabel <p.zabel@pengutronix.de>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Philipp Zabel and committed by
David S. Miller
77501a79 2f43b9be

+43 -2
+10
Documentation/devicetree/bindings/net/micrel.txt
··· 35 35 supported clocks: 36 36 - KSZ8021, KSZ8031, KSZ8081, KSZ8091: "rmii-ref": The RMII reference 37 37 input clock. Used to determine the XI input clock. 38 + 39 + - micrel,fiber-mode: If present the PHY is configured to operate in fiber mode 40 + 41 + Some PHYs, such as the KSZ8041FTL variant, support fiber mode, enabled 42 + by the FXEN boot strapping pin. It can't be determined from the PHY 43 + registers whether the PHY is in fiber mode, so this boolean device tree 44 + property can be used to describe it. 45 + 46 + In fiber mode, auto-negotiation is disabled and the PHY can only work in 47 + 100base-fx (full and half duplex) modes.
+32 -2
drivers/net/phy/micrel.c
··· 311 311 return 0; 312 312 } 313 313 314 + static int ksz8041_config_init(struct phy_device *phydev) 315 + { 316 + struct device_node *of_node = phydev->mdio.dev.of_node; 317 + 318 + /* Limit supported and advertised modes in fiber mode */ 319 + if (of_property_read_bool(of_node, "micrel,fiber-mode")) { 320 + phydev->dev_flags |= MICREL_PHY_FXEN; 321 + phydev->supported &= SUPPORTED_FIBRE | 322 + SUPPORTED_100baseT_Full | 323 + SUPPORTED_100baseT_Half; 324 + phydev->advertising &= ADVERTISED_FIBRE | 325 + ADVERTISED_100baseT_Full | 326 + ADVERTISED_100baseT_Half; 327 + phydev->autoneg = AUTONEG_DISABLE; 328 + } 329 + 330 + return kszphy_config_init(phydev); 331 + } 332 + 333 + static int ksz8041_config_aneg(struct phy_device *phydev) 334 + { 335 + /* Skip auto-negotiation in fiber mode */ 336 + if (phydev->dev_flags & MICREL_PHY_FXEN) { 337 + phydev->speed = SPEED_100; 338 + return 0; 339 + } 340 + 341 + return genphy_config_aneg(phydev); 342 + } 343 + 314 344 static int ksz9021_load_values_from_of(struct phy_device *phydev, 315 345 const struct device_node *of_node, 316 346 u16 reg, ··· 818 788 .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT, 819 789 .driver_data = &ksz8041_type, 820 790 .probe = kszphy_probe, 821 - .config_init = kszphy_config_init, 822 - .config_aneg = genphy_config_aneg, 791 + .config_init = ksz8041_config_init, 792 + .config_aneg = ksz8041_config_aneg, 823 793 .read_status = genphy_read_status, 824 794 .ack_interrupt = kszphy_ack_interrupt, 825 795 .config_intr = kszphy_config_intr,
+1
include/linux/micrel_phy.h
··· 37 37 38 38 /* struct phy_device dev_flags definitions */ 39 39 #define MICREL_PHY_50MHZ_CLK 0x00000001 40 + #define MICREL_PHY_FXEN 0x00000002 40 41 41 42 #define MICREL_KSZ9021_EXTREG_CTRL 0xB 42 43 #define MICREL_KSZ9021_EXTREG_DATA_WRITE 0xC