712-net-phy-sfp-add-support-for-SMBus.patch 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. From 3cb0bde365d913c484d20224367a54a0eac780a7 Mon Sep 17 00:00:00 2001
  2. From: Antoine Tenart <[email protected]>
  3. Date: Fri, 21 Feb 2020 11:55:29 +0100
  4. Subject: [PATCH 3/3] net: phy: sfp: add support for SMBus
  5. Signed-off-by: Antoine Tenart <[email protected]>
  6. ---
  7. drivers/net/phy/sfp.c | 68 ++++++++++++++++++++++++++++++++++---------
  8. 1 file changed, 54 insertions(+), 14 deletions(-)
  9. --- a/drivers/net/phy/sfp.c
  10. +++ b/drivers/net/phy/sfp.c
  11. @@ -556,32 +556,72 @@ static int sfp_i2c_write(struct sfp *sfp
  12. return ret == ARRAY_SIZE(msgs) ? len : 0;
  13. }
  14. +static int sfp_smbus_read(struct sfp *sfp, bool a2, u8 dev_addr, void *buf,
  15. + size_t len)
  16. +{
  17. + u8 bus_addr = a2 ? 0x51 : 0x50, *val = buf;
  18. +
  19. + bus_addr -= 0x40;
  20. +
  21. + while (len > 0) {
  22. + *val = sfp->i2c_mii->read(sfp->i2c_mii, bus_addr, dev_addr);
  23. +
  24. + val++;
  25. + dev_addr++;
  26. + len--;
  27. + }
  28. +
  29. + return val - (u8 *)buf;
  30. +}
  31. +
  32. +static int sfp_smbus_write(struct sfp *sfp, bool a2, u8 dev_addr, void *buf,
  33. + size_t len)
  34. +{
  35. + u8 bus_addr = a2 ? 0x51 : 0x50;
  36. + u16 val;
  37. +
  38. + memcpy(&val, buf, len);
  39. +
  40. + return sfp->i2c_mii->write(sfp->i2c_mii, bus_addr, dev_addr, val);
  41. +}
  42. +
  43. static int sfp_i2c_configure(struct sfp *sfp, struct i2c_adapter *i2c)
  44. {
  45. - struct mii_bus *i2c_mii;
  46. + struct mii_bus *mii;
  47. int ret;
  48. - if (!i2c_check_functionality(i2c, I2C_FUNC_I2C))
  49. - return -EINVAL;
  50. -
  51. sfp->i2c = i2c;
  52. - sfp->read = sfp_i2c_read;
  53. - sfp->write = sfp_i2c_write;
  54. - i2c_mii = mdio_i2c_alloc(sfp->dev, i2c);
  55. - if (IS_ERR(i2c_mii))
  56. - return PTR_ERR(i2c_mii);
  57. + if (i2c_check_functionality(i2c, I2C_FUNC_I2C)) {
  58. + sfp->read = sfp_i2c_read;
  59. + sfp->write = sfp_i2c_write;
  60. +
  61. + mii = mdio_i2c_alloc(sfp->dev, i2c);
  62. + if (IS_ERR(mii))
  63. + return PTR_ERR(mii);
  64. +
  65. + mii->name = "SFP I2C Bus";
  66. + } else if (i2c_check_functionality(i2c, I2C_FUNC_SMBUS_BYTE_DATA)) {
  67. + sfp->read = sfp_smbus_read;
  68. + sfp->write = sfp_smbus_write;
  69. +
  70. + mii = mdio_smbus_alloc(sfp->dev, i2c);
  71. + if (IS_ERR(mii))
  72. + return PTR_ERR(mii);
  73. - i2c_mii->name = "SFP I2C Bus";
  74. - i2c_mii->phy_mask = ~0;
  75. + mii->name = "SFP SMBus";
  76. + } else {
  77. + return -EINVAL;
  78. + }
  79. - ret = mdiobus_register(i2c_mii);
  80. + mii->phy_mask = ~0;
  81. + ret = mdiobus_register(mii);
  82. if (ret < 0) {
  83. - mdiobus_free(i2c_mii);
  84. + mdiobus_free(mii);
  85. return ret;
  86. }
  87. - sfp->i2c_mii = i2c_mii;
  88. + sfp->i2c_mii = mii;
  89. return 0;
  90. }