Lines Matching +full:phy +full:- +full:wrapper
1 // SPDX-License-Identifier: GPL-2.0+
14 * PHY driver for mv88e61xx ethernet switches.
16 * This driver configures the mv88e61xx for basic use as a PHY. The switch
19 * traffic from each PHY port only to the CPU port, and from the CPU port to
20 * any PHY port.
22 * The configuration determines which PHY ports to activate using the
25 * connected to unless it is connected over a PHY interface (not MII).
43 #define PORT_MASK ((1 << PORT_COUNT) - 1)
73 /* Phy registers */
81 /* Phy page numbers */
138 /* PHY Status Register */
149 * for both the indirect multichip addressing mode and the PHY indirection
150 * required for the writes to any PHY register.
228 val = bus->read(bus, smi_addr, MDIO_DEVAD_NONE, SMI_CMD_REG); in mv88e61xx_smi_wait()
233 } while (--timeout); in mv88e61xx_smi_wait()
236 return -ETIMEDOUT; in mv88e61xx_smi_wait()
243 * which on-chip register set you are reading/writing (the various PHYs, their
248 * single-chip addressing mode, where it responds to all SMI addresses, using
252 * non-zero address, it only responds to that SMI address and requires indirect
257 struct mv88e61xx_phy_priv *priv = phydev->priv; in mv88e61xx_reg_read()
258 struct mii_dev *mdio_bus = priv->mdio_bus; in mv88e61xx_reg_read()
259 int smi_addr = priv->smi_addr; in mv88e61xx_reg_read()
262 /* In single-chip mode, the device can be addressed directly */ in mv88e61xx_reg_read()
264 return mdio_bus->read(mdio_bus, dev, MDIO_DEVAD_NONE, reg); in mv88e61xx_reg_read()
272 res = mdio_bus->write(mdio_bus, smi_addr, MDIO_DEVAD_NONE, SMI_CMD_REG, in mv88e61xx_reg_read()
283 res = mdio_bus->read(mdio_bus, smi_addr, MDIO_DEVAD_NONE, SMI_DATA_REG); in mv88e61xx_reg_read()
294 struct mv88e61xx_phy_priv *priv = phydev->priv; in mv88e61xx_reg_write()
295 struct mii_dev *mdio_bus = priv->mdio_bus; in mv88e61xx_reg_write()
296 int smi_addr = priv->smi_addr; in mv88e61xx_reg_write()
299 /* In single-chip mode, the device can be addressed directly */ in mv88e61xx_reg_write()
301 return mdio_bus->write(mdio_bus, dev, MDIO_DEVAD_NONE, reg, in mv88e61xx_reg_write()
311 res = mdio_bus->write(mdio_bus, smi_addr, MDIO_DEVAD_NONE, in mv88e61xx_reg_write()
317 res = mdio_bus->write(mdio_bus, smi_addr, MDIO_DEVAD_NONE, SMI_CMD_REG, in mv88e61xx_reg_write()
342 } while (--timeout); in mv88e61xx_phy_wait()
344 return -ETIMEDOUT; in mv88e61xx_phy_wait()
353 phydev = (struct phy_device *)smi_wrapper->priv; in mv88e61xx_phy_read_indirect()
376 phydev = (struct phy_device *)smi_wrapper->priv; in mv88e61xx_phy_write_indirect()
394 /* Wrapper function to make calls to phy_read_indirect simpler */
395 static int mv88e61xx_phy_read(struct phy_device *phydev, int phy, int reg) in mv88e61xx_phy_read() argument
397 return mv88e61xx_phy_read_indirect(phydev->bus, DEVADDR_PHY(phy), in mv88e61xx_phy_read()
401 /* Wrapper function to make calls to phy_read_indirect simpler */
402 static int mv88e61xx_phy_write(struct phy_device *phydev, int phy, in mv88e61xx_phy_write() argument
405 return mv88e61xx_phy_write_indirect(phydev->bus, DEVADDR_PHY(phy), in mv88e61xx_phy_write()
420 static int mv88e61xx_set_page(struct phy_device *phydev, u8 phy, u8 page) in mv88e61xx_set_page() argument
422 return mv88e61xx_phy_write(phydev, phy, PHY_REG_PAGE, page); in mv88e61xx_set_page()
437 struct mv88e61xx_phy_priv *priv = phydev->priv; in mv88e61xx_6352_family()
439 switch (priv->id) { in mv88e61xx_6352_family()
470 puts("Waiting for PHY realtime link"); in mv88e61xx_parse_status()
475 phydev->link = 0; in mv88e61xx_parse_status()
489 phydev->link = 1; in mv88e61xx_parse_status()
491 phydev->link = 0; in mv88e61xx_parse_status()
495 phydev->duplex = DUPLEX_FULL; in mv88e61xx_parse_status()
497 phydev->duplex = DUPLEX_HALF; in mv88e61xx_parse_status()
503 phydev->speed = SPEED_1000; in mv88e61xx_parse_status()
506 phydev->speed = SPEED_100; in mv88e61xx_parse_status()
509 phydev->speed = SPEED_10; in mv88e61xx_parse_status()
549 for (time = 1000; time; time--) { in mv88e61xx_switch_reset()
557 return -ETIMEDOUT; in mv88e61xx_switch_reset()
658 res = -EIO; in mv88e61xx_read_port_config()
663 } while (--timeout); in mv88e61xx_read_port_config()
666 res = -ETIMEDOUT; in mv88e61xx_read_port_config()
672 phydev->duplex = DUPLEX_FULL; in mv88e61xx_read_port_config()
674 phydev->duplex = DUPLEX_HALF; in mv88e61xx_read_port_config()
680 phydev->speed = SPEED_1000; in mv88e61xx_read_port_config()
683 phydev->speed = SPEED_100; in mv88e61xx_read_port_config()
686 phydev->speed = SPEED_10; in mv88e61xx_read_port_config()
807 static int mv88e61xx_phy_enable(struct phy_device *phydev, u8 phy) in mv88e61xx_phy_enable() argument
811 val = mv88e61xx_phy_read(phydev, phy, MII_BMCR); in mv88e61xx_phy_enable()
815 val = mv88e61xx_phy_write(phydev, phy, MII_BMCR, val); in mv88e61xx_phy_enable()
822 static int mv88e61xx_phy_setup(struct phy_device *phydev, u8 phy) in mv88e61xx_phy_setup() argument
827 * Enable energy-detect sensing on PHY, used to determine when a PHY in mv88e61xx_phy_setup()
830 val = mv88e61xx_phy_read(phydev, phy, PHY_REG_CTRL1); in mv88e61xx_phy_setup()
836 val = mv88e61xx_phy_write(phydev, phy, PHY_REG_CTRL1, val); in mv88e61xx_phy_setup()
843 static int mv88e61xx_phy_config_port(struct phy_device *phydev, u8 phy) in mv88e61xx_phy_config_port() argument
847 val = mv88e61xx_port_enable(phydev, phy); in mv88e61xx_phy_config_port()
851 val = mv88e61xx_port_set_vlan(phydev, phy, in mv88e61xx_phy_config_port()
871 return -ENOMEM; in mv88e61xx_probe()
876 * This device requires indirect reads/writes to the PHY registers in mv88e61xx_probe()
877 * which the generic PHY code can't handle. Make a wrapper MII device in mv88e61xx_probe()
883 return -ENOMEM; in mv88e61xx_probe()
888 * the bus with the wrapper bus in mv88e61xx_probe()
890 priv->mdio_bus = phydev->bus; in mv88e61xx_probe()
897 priv->smi_addr = phydev->addr; in mv88e61xx_probe()
900 * Store the phy_device in the wrapper mii device. This lets us get it in mv88e61xx_probe()
903 smi_wrapper->priv = phydev; in mv88e61xx_probe()
904 strncpy(smi_wrapper->name, "indirect mii", sizeof(smi_wrapper->name)); in mv88e61xx_probe()
905 smi_wrapper->read = mv88e61xx_phy_read_indirect; in mv88e61xx_probe()
906 smi_wrapper->write = mv88e61xx_phy_write_indirect; in mv88e61xx_probe()
908 /* Replace the bus with the wrapper device */ in mv88e61xx_probe()
909 phydev->bus = smi_wrapper; in mv88e61xx_probe()
911 phydev->priv = priv; in mv88e61xx_probe()
913 priv->id = mv88e61xx_get_switch_id(phydev); in mv88e61xx_probe()
922 int ret = -1; in mv88e61xx_phy_config()
930 phydev->addr = i; in mv88e61xx_phy_config()
934 printf("Error enabling PHY %i\n", i); in mv88e61xx_phy_config()
939 printf("Error setting up PHY %i\n", i); in mv88e61xx_phy_config()
944 printf("Error configuring PHY %i\n", i); in mv88e61xx_phy_config()
950 printf("Error resetting PHY %i\n", i); in mv88e61xx_phy_config()
955 printf("Error setting PHY %i autoneg\n", i); in mv88e61xx_phy_config()
959 /* Return success if any PHY succeeds */ in mv88e61xx_phy_config()
977 val = mv88e61xx_phy_read(phydev, phydev->addr, PHY_REG_STATUS1); in mv88e61xx_phy_is_connected()
994 int speed = phydev->speed; in mv88e61xx_phy_startup()
995 int duplex = phydev->duplex; in mv88e61xx_phy_startup()
999 phydev->addr = i; in mv88e61xx_phy_startup()
1008 link = (link || phydev->link); in mv88e61xx_phy_startup()
1011 phydev->link = link; in mv88e61xx_phy_startup()
1015 phydev->speed = speed; in mv88e61xx_phy_startup()
1016 phydev->duplex = duplex; in mv88e61xx_phy_startup()
1052 * Overload weak get_phy_id definition since we need non-standard functions
1053 * to read PHY registers
1073 return -EIO; in get_phy_id()
1079 return -EIO; in get_phy_id()