phy-core.c 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. /*
  2. * Core PHY library, taken from phy.c
  3. *
  4. * This program is free software; you can redistribute it and/or modify it
  5. * under the terms of the GNU General Public License as published by the
  6. * Free Software Foundation; either version 2 of the License, or (at your
  7. * option) any later version.
  8. */
  9. #include <linux/export.h>
  10. #include <linux/phy.h>
  11. static void mmd_phy_indirect(struct mii_bus *bus, int phy_addr, int devad,
  12. u16 regnum)
  13. {
  14. /* Write the desired MMD Devad */
  15. bus->write(bus, phy_addr, MII_MMD_CTRL, devad);
  16. /* Write the desired MMD register address */
  17. bus->write(bus, phy_addr, MII_MMD_DATA, regnum);
  18. /* Select the Function : DATA with no post increment */
  19. bus->write(bus, phy_addr, MII_MMD_CTRL, devad | MII_MMD_CTRL_NOINCR);
  20. }
  21. /**
  22. * phy_read_mmd - Convenience function for reading a register
  23. * from an MMD on a given PHY.
  24. * @phydev: The phy_device struct
  25. * @devad: The MMD to read from (0..31)
  26. * @regnum: The register on the MMD to read (0..65535)
  27. *
  28. * Same rules as for phy_read();
  29. */
  30. int phy_read_mmd(struct phy_device *phydev, int devad, u32 regnum)
  31. {
  32. int val;
  33. if (regnum > (u16)~0 || devad > 32)
  34. return -EINVAL;
  35. if (phydev->drv->read_mmd) {
  36. val = phydev->drv->read_mmd(phydev, devad, regnum);
  37. } else if (phydev->is_c45) {
  38. u32 addr = MII_ADDR_C45 | (devad << 16) | (regnum & 0xffff);
  39. val = mdiobus_read(phydev->mdio.bus, phydev->mdio.addr, addr);
  40. } else {
  41. struct mii_bus *bus = phydev->mdio.bus;
  42. int phy_addr = phydev->mdio.addr;
  43. mutex_lock(&bus->mdio_lock);
  44. mmd_phy_indirect(bus, phy_addr, devad, regnum);
  45. /* Read the content of the MMD's selected register */
  46. val = bus->read(bus, phy_addr, MII_MMD_DATA);
  47. mutex_unlock(&bus->mdio_lock);
  48. }
  49. return val;
  50. }
  51. EXPORT_SYMBOL(phy_read_mmd);
  52. /**
  53. * phy_write_mmd - Convenience function for writing a register
  54. * on an MMD on a given PHY.
  55. * @phydev: The phy_device struct
  56. * @devad: The MMD to read from
  57. * @regnum: The register on the MMD to read
  58. * @val: value to write to @regnum
  59. *
  60. * Same rules as for phy_write();
  61. */
  62. int phy_write_mmd(struct phy_device *phydev, int devad, u32 regnum, u16 val)
  63. {
  64. int ret;
  65. if (regnum > (u16)~0 || devad > 32)
  66. return -EINVAL;
  67. if (phydev->drv->write_mmd) {
  68. ret = phydev->drv->write_mmd(phydev, devad, regnum, val);
  69. } else if (phydev->is_c45) {
  70. u32 addr = MII_ADDR_C45 | (devad << 16) | (regnum & 0xffff);
  71. ret = mdiobus_write(phydev->mdio.bus, phydev->mdio.addr,
  72. addr, val);
  73. } else {
  74. struct mii_bus *bus = phydev->mdio.bus;
  75. int phy_addr = phydev->mdio.addr;
  76. mutex_lock(&bus->mdio_lock);
  77. mmd_phy_indirect(bus, phy_addr, devad, regnum);
  78. /* Write the data into MMD's selected register */
  79. bus->write(bus, phy_addr, MII_MMD_DATA, val);
  80. mutex_unlock(&bus->mdio_lock);
  81. ret = 0;
  82. }
  83. return ret;
  84. }
  85. EXPORT_SYMBOL(phy_write_mmd);