Commit b7a5b0843812b7bd4a225951ce11e7d14398395c

Authored by Philippe De Muyter
Committed by Joe Hershberger
1 parent e9efe16da8

net: phy: micrel: add support for KSZ8895 switch in SMI mode

This patch adds a phy driver for the Micrel KSZ8895 switch.  As the SoC MAC
is directly connected to the switch MAC the link to the switch is always up.

But the KSZ8895 switch can be hardwired in three configuration modes :
- not configurable with eventually an eeprom-stored configuration
- configurable by the mdio/mdc connection (SMI protocol)
- configurable by a SPI connection.

In not configurable mode, the switch starts automatically, but in the
other modes, it must be started programmatically, by writing 1 in
configuration register 1.
We only support the not configurable and mdio/mdc (aka SMI) modes here.

Signed-off-by: Philippe De Muyter <phdm@macqel.be>
Cc: Christian Gmeiner <christian.gmeiner@gmail.com>
Signed-off-by: Joe Hershberger <joe.hershberger@ni.com>

Showing 1 changed file with 58 additions and 0 deletions Side-by-side Diff

drivers/net/phy/micrel.c
... ... @@ -22,6 +22,63 @@
22 22 .shutdown = &genphy_shutdown,
23 23 };
24 24  
  25 +/**
  26 + * KSZ8895
  27 + */
  28 +
  29 +static unsigned short smireg_to_phy(unsigned short reg)
  30 +{
  31 + return ((reg & 0xc0) >> 3) + 0x06 + ((reg & 0x20) >> 5);
  32 +}
  33 +
  34 +static unsigned short smireg_to_reg(unsigned short reg)
  35 +{
  36 + return reg & 0x1F;
  37 +}
  38 +
  39 +static void ksz8895_write_smireg(struct phy_device *phydev, int smireg, int val)
  40 +{
  41 + phydev->bus->write(phydev->bus, smireg_to_phy(smireg), MDIO_DEVAD_NONE,
  42 + smireg_to_reg(smireg), val);
  43 +}
  44 +
  45 +#if 0
  46 +static int ksz8895_read_smireg(struct phy_device *phydev, int smireg)
  47 +{
  48 + return phydev->bus->read(phydev->bus, smireg_to_phy(smireg),
  49 + MDIO_DEVAD_NONE, smireg_to_reg(smireg));
  50 +}
  51 +#endif
  52 +
  53 +int ksz8895_config(struct phy_device *phydev)
  54 +{
  55 + /* we are connected directly to the switch without
  56 + * dedicated PHY. SCONF1 == 001 */
  57 + phydev->link = 1;
  58 + phydev->duplex = DUPLEX_FULL;
  59 + phydev->speed = SPEED_100;
  60 +
  61 + /* Force the switch to start */
  62 + ksz8895_write_smireg(phydev, 1, 1);
  63 +
  64 + return 0;
  65 +}
  66 +
  67 +static int ksz8895_startup(struct phy_device *phydev)
  68 +{
  69 + return 0;
  70 +}
  71 +
  72 +static struct phy_driver ksz8895_driver = {
  73 + .name = "Micrel KSZ8895/KSZ8864",
  74 + .uid = 0x221450,
  75 + .mask = 0xffffe1,
  76 + .features = PHY_BASIC_FEATURES,
  77 + .config = &ksz8895_config,
  78 + .startup = &ksz8895_startup,
  79 + .shutdown = &genphy_shutdown,
  80 +};
  81 +
25 82 #ifndef CONFIG_PHY_MICREL_KSZ9021
26 83 /*
27 84 * I can't believe Micrel used the exact same part number
... ... @@ -221,6 +278,7 @@
221 278 phy_register(&KS8721_driver);
222 279 #endif
223 280 phy_register(&ksz9031_driver);
  281 + phy_register(&ksz8895_driver);
224 282 return 0;
225 283 }