1
0

450-reprobe_sfp_phy.patch 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. From 28baa5e2635285b178326b301f534ed95c65dd01 Mon Sep 17 00:00:00 2001
  2. From: Jonas Gorski <jonas.gorski@gmail.com>
  3. Date: Thu, 29 Sep 2016 11:44:39 +0200
  4. Subject: [PATCH] sfp: retry phy probe if unsuccessful
  5. Some phys seem to take longer than 50 ms to come out of reset, so retry
  6. until we find a phy.
  7. Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
  8. ---
  9. drivers/net/phy/sfp.c | 38 +++++++++++++++++++++++++-------------
  10. 1 file changed, 25 insertions(+), 13 deletions(-)
  11. --- a/drivers/net/phy/sfp.c
  12. +++ b/drivers/net/phy/sfp.c
  13. @@ -506,7 +506,7 @@ static void sfp_sm_phy_detach(struct sfp
  14. sfp->mod_phy = NULL;
  15. }
  16. -static void sfp_sm_probe_phy(struct sfp *sfp)
  17. +static int sfp_sm_probe_phy(struct sfp *sfp)
  18. {
  19. struct phy_device *phy;
  20. int err;
  21. @@ -516,11 +516,11 @@ static void sfp_sm_probe_phy(struct sfp
  22. phy = mdiobus_scan(sfp->i2c_mii, SFP_PHY_ADDR);
  23. if (phy == ERR_PTR(-ENODEV)) {
  24. dev_info(sfp->dev, "no PHY detected\n");
  25. - return;
  26. + return -EAGAIN;
  27. }
  28. if (IS_ERR(phy)) {
  29. dev_err(sfp->dev, "mdiobus scan returned %ld\n", PTR_ERR(phy));
  30. - return;
  31. + return PTR_ERR(phy);
  32. }
  33. err = sfp_add_phy(sfp->sfp_bus, phy);
  34. @@ -528,11 +528,13 @@ static void sfp_sm_probe_phy(struct sfp
  35. phy_device_remove(phy);
  36. phy_device_free(phy);
  37. dev_err(sfp->dev, "sfp_add_phy failed: %d\n", err);
  38. - return;
  39. + return err;
  40. }
  41. sfp->mod_phy = phy;
  42. phy_start(phy);
  43. +
  44. + return 0;
  45. }
  46. static void sfp_sm_link_up(struct sfp *sfp)
  47. @@ -578,14 +580,9 @@ static void sfp_sm_fault(struct sfp *sfp
  48. static void sfp_sm_mod_init(struct sfp *sfp)
  49. {
  50. - sfp_module_tx_enable(sfp);
  51. + int ret = 0;
  52. - /* Wait t_init before indicating that the link is up, provided the
  53. - * current state indicates no TX_FAULT. If TX_FAULT clears before
  54. - * this time, that's fine too.
  55. - */
  56. - sfp_sm_next(sfp, SFP_S_INIT, T_INIT_JIFFIES);
  57. - sfp->sm_retries = 5;
  58. + sfp_module_tx_enable(sfp);
  59. /* Setting the serdes link mode is guesswork: there's no
  60. * field in the EEPROM which indicates what mode should
  61. @@ -599,7 +596,22 @@ static void sfp_sm_mod_init(struct sfp *
  62. if (sfp->id.base.e1000_base_t ||
  63. sfp->id.base.e100_base_lx ||
  64. sfp->id.base.e100_base_fx)
  65. - sfp_sm_probe_phy(sfp);
  66. + ret = sfp_sm_probe_phy(sfp);
  67. +
  68. + if (!ret) {
  69. + /* Wait t_init before indicating that the link is up, provided
  70. + * the current state indicates no TX_FAULT. If TX_FAULT clears
  71. + * this time, that's fine too.
  72. + */
  73. + sfp_sm_next(sfp, SFP_S_INIT, T_INIT_JIFFIES);
  74. + sfp->sm_retries = 5;
  75. + return;
  76. + }
  77. +
  78. + if (ret == -EAGAIN)
  79. + sfp_sm_set_timer(sfp, T_PROBE_RETRY);
  80. + else
  81. + sfp_sm_next(sfp, SFP_S_TX_DISABLE, 0);
  82. }
  83. static int sfp_sm_mod_probe(struct sfp *sfp)