net: phy: micrel: Add KSZ8041FTL fiber mode support
authorPhilipp Zabel <p.zabel@pengutronix.de>
Thu, 14 Jul 2016 14:29:43 +0000 (16:29 +0200)
committerDavid S. Miller <davem@davemloft.net>
Fri, 15 Jul 2016 18:53:02 +0000 (11:53 -0700)
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>
Documentation/devicetree/bindings/net/micrel.txt
drivers/net/phy/micrel.c
include/linux/micrel_phy.h

index 87496a8c64ab5d8d3f84497454653f0cfb395c16..8d157f0295a502fd326eab4e2196f17654d8b484 100644 (file)
@@ -35,3 +35,13 @@ Optional properties:
        supported clocks:
        - KSZ8021, KSZ8031, KSZ8081, KSZ8091: "rmii-ref": The RMII reference
          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.
index 5a8fefc25157b73202e4139a50b79bf43fa16858..059f13b60fe02f1eb4b51294b01d736acd58665e 100644 (file)
@@ -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,
@@ -788,8 +818,8 @@ static struct phy_driver ksphy_driver[] = {
        .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,
index 2e5b194b9b1900b9d5304cbdb52f14aac576b85e..257173e0095ebdb22e1684fbd56ce05a8971ee1d 100644 (file)
@@ -37,6 +37,7 @@
 
 /* struct phy_device dev_flags definitions */
 #define MICREL_PHY_50MHZ_CLK   0x00000001
+#define MICREL_PHY_FXEN                0x00000002
 
 #define MICREL_KSZ9021_EXTREG_CTRL     0xB
 #define MICREL_KSZ9021_EXTREG_DATA_WRITE       0xC