711-net-phy-add-an-MDIO-SMBus-library.patch 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. From d585c55b9f70cf9e8c66820d7efe7130c683f19e Mon Sep 17 00:00:00 2001
  2. From: Antoine Tenart <[email protected]>
  3. Date: Fri, 21 Feb 2020 11:51:27 +0100
  4. Subject: [PATCH 2/3] net: phy: add an MDIO SMBus library
  5. Signed-off-by: Antoine Tenart <[email protected]>
  6. ---
  7. drivers/net/mdio/Kconfig | 11 +++++++
  8. drivers/net/mdio/Makefile | 1 +
  9. drivers/net/mdio/mdio-smbus.c | 62 +++++++++++++++++++++++++++++++++++
  10. drivers/net/phy/Kconfig | 1 +
  11. include/linux/mdio/mdio-i2c.h | 16 +++++++++
  12. 5 files changed, 91 insertions(+)
  13. create mode 100644 drivers/net/mdio/mdio-smbus.c
  14. --- a/drivers/net/mdio/Kconfig
  15. +++ b/drivers/net/mdio/Kconfig
  16. @@ -54,6 +54,17 @@ config MDIO_SUN4I
  17. interface units of the Allwinner SoC that have an EMAC (A10,
  18. A12, A10s, etc.)
  19. +config MDIO_SMBUS
  20. + tristate
  21. + depends on I2C_SMBUS
  22. + help
  23. + Support SMBus based PHYs. This provides a MDIO bus bridged
  24. + to SMBus to allow PHYs connected in SMBus mode to be accessed
  25. + using the existing infrastructure.
  26. +
  27. + This is library mode.
  28. +
  29. +
  30. config MDIO_XGENE
  31. tristate "APM X-Gene SoC MDIO bus controller"
  32. depends on ARCH_XGENE || COMPILE_TEST
  33. --- a/drivers/net/mdio/Makefile
  34. +++ b/drivers/net/mdio/Makefile
  35. @@ -19,6 +19,7 @@ obj-$(CONFIG_MDIO_MOXART) += mdio-moxar
  36. obj-$(CONFIG_MDIO_MSCC_MIIM) += mdio-mscc-miim.o
  37. obj-$(CONFIG_MDIO_MVUSB) += mdio-mvusb.o
  38. obj-$(CONFIG_MDIO_OCTEON) += mdio-octeon.o
  39. +obj-$(CONFIG_MDIO_SMBUS) += mdio-smbus.o
  40. obj-$(CONFIG_MDIO_SUN4I) += mdio-sun4i.o
  41. obj-$(CONFIG_MDIO_THUNDER) += mdio-thunder.o
  42. obj-$(CONFIG_MDIO_XGENE) += mdio-xgene.o
  43. --- /dev/null
  44. +++ b/drivers/net/mdio/mdio-smbus.c
  45. @@ -0,0 +1,62 @@
  46. +// SPDX-License-Identifier: GPL-2.0-or-later
  47. +/*
  48. + * MDIO SMBus bridge
  49. + *
  50. + * Copyright (C) 2020 Antoine Tenart
  51. + *
  52. + * Network PHYs can appear on SMBus when they are part of SFP modules.
  53. + */
  54. +#include <linux/i2c.h>
  55. +#include <linux/phy.h>
  56. +#include <linux/mdio/mdio-i2c.h>
  57. +
  58. +static int smbus_mii_read(struct mii_bus *mii, int phy_id, int reg)
  59. +{
  60. + struct i2c_adapter *i2c = mii->priv;
  61. + union i2c_smbus_data data;
  62. + int ret;
  63. +
  64. + ret = i2c_smbus_xfer(i2c, i2c_mii_phy_addr(phy_id), 0, I2C_SMBUS_READ,
  65. + reg, I2C_SMBUS_BYTE_DATA, &data);
  66. + if (ret < 0)
  67. + return 0xff;
  68. +
  69. + return data.byte;
  70. +}
  71. +
  72. +static int smbus_mii_write(struct mii_bus *mii, int phy_id, int reg, u16 val)
  73. +{
  74. + struct i2c_adapter *i2c = mii->priv;
  75. + union i2c_smbus_data data;
  76. + int ret;
  77. +
  78. + data.byte = val;
  79. +
  80. + ret = i2c_smbus_xfer(i2c, i2c_mii_phy_addr(phy_id), 0, I2C_SMBUS_WRITE,
  81. + reg, I2C_SMBUS_BYTE_DATA, &data);
  82. + return ret < 0 ? ret : 0;
  83. +}
  84. +
  85. +struct mii_bus *mdio_smbus_alloc(struct device *parent, struct i2c_adapter *i2c)
  86. +{
  87. + struct mii_bus *mii;
  88. +
  89. + if (!i2c_check_functionality(i2c, I2C_FUNC_SMBUS_BYTE_DATA))
  90. + return ERR_PTR(-EINVAL);
  91. +
  92. + mii = mdiobus_alloc();
  93. + if (!mii)
  94. + return ERR_PTR(-ENOMEM);
  95. +
  96. + snprintf(mii->id, MII_BUS_ID_SIZE, "smbus:%s", dev_name(parent));
  97. + mii->parent = parent;
  98. + mii->read = smbus_mii_read;
  99. + mii->write = smbus_mii_write;
  100. + mii->priv = i2c;
  101. +
  102. + return mii;
  103. +}
  104. +
  105. +MODULE_AUTHOR("Antoine Tenart");
  106. +MODULE_DESCRIPTION("MDIO SMBus bridge library");
  107. +MODULE_LICENSE("GPL");
  108. --- a/drivers/net/phy/Kconfig
  109. +++ b/drivers/net/phy/Kconfig
  110. @@ -61,6 +61,7 @@ config SFP
  111. depends on I2C && PHYLINK
  112. depends on HWMON || HWMON=n
  113. select MDIO_I2C
  114. + select MDIO_SMBUS
  115. comment "Switch configuration API + drivers"
  116. --- a/include/linux/mdio/mdio-i2c.h
  117. +++ b/include/linux/mdio/mdio-i2c.h
  118. @@ -12,5 +12,8 @@ struct i2c_adapter;
  119. struct mii_bus;
  120. struct mii_bus *mdio_i2c_alloc(struct device *parent, struct i2c_adapter *i2c);
  121. +struct mii_bus *mdio_smbus_alloc(struct device *parent, struct i2c_adapter *i2c);
  122. +bool i2c_mii_valid_phy_id(int phy_id);
  123. +unsigned int i2c_mii_phy_addr(int phy_id);
  124. #endif
  125. --- a/drivers/net/mdio/mdio-i2c.c
  126. +++ b/drivers/net/mdio/mdio-i2c.c
  127. @@ -18,12 +18,12 @@
  128. * specified to be present in SFP modules. These correspond with PHY
  129. * addresses 16 and 17. Disallow access to these "phy" addresses.
  130. */
  131. -static bool i2c_mii_valid_phy_id(int phy_id)
  132. +bool i2c_mii_valid_phy_id(int phy_id)
  133. {
  134. return phy_id != 0x10 && phy_id != 0x11;
  135. }
  136. -static unsigned int i2c_mii_phy_addr(int phy_id)
  137. +unsigned int i2c_mii_phy_addr(int phy_id)
  138. {
  139. return phy_id + 0x40;
  140. }