300-reprobe_sfp_phy.patch 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  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. @@ -488,7 +488,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. @@ -498,11 +498,11 @@ static void sfp_sm_probe_phy(struct sfp
  22. phy = mdiobus_scan(sfp->i2c_mii, SFP_PHY_ADDR);
  23. if (IS_ERR(phy)) {
  24. dev_err(sfp->dev, "mdiobus scan returned %ld\n", PTR_ERR(phy));
  25. - return;
  26. + return PTR_ERR(phy);
  27. }
  28. if (!phy) {
  29. - dev_info(sfp->dev, "no PHY detected\n");
  30. - return;
  31. + dev_dbg(sfp->dev, "no PHY detected\n");
  32. + return -EAGAIN;
  33. }
  34. err = phylink_connect_phy(sfp->phylink, phy);
  35. @@ -510,11 +510,13 @@ static void sfp_sm_probe_phy(struct sfp
  36. phy_device_remove(phy);
  37. phy_device_free(phy);
  38. dev_err(sfp->dev, "phylink_connect_phy failed: %d\n", err);
  39. - return;
  40. + return err;
  41. }
  42. sfp->mod_phy = phy;
  43. phy_start(phy);
  44. +
  45. + return 0;
  46. }
  47. static void sfp_sm_link_up(struct sfp *sfp)
  48. @@ -565,13 +567,6 @@ static void sfp_sm_mod_init(struct sfp *
  49. {
  50. sfp_module_tx_enable(sfp);
  51. - /* Wait t_init before indicating that the link is up, provided the
  52. - * current state indicates no TX_FAULT. If TX_FAULT clears before
  53. - * this time, that's fine too.
  54. - */
  55. - sfp_sm_next(sfp, SFP_S_INIT, T_INIT_JIFFIES);
  56. - sfp->sm_retries = 5;
  57. -
  58. if (sfp->phylink) {
  59. /* Setting the serdes link mode is guesswork: there's no
  60. * field in the EEPROM which indicates what mode should
  61. @@ -587,9 +582,26 @@ static void sfp_sm_mod_init(struct sfp *
  62. !sfp->id.base.e100_base_fx) {
  63. phylink_set_link_an_mode(sfp->phylink, MLO_AN_8023Z);
  64. } else {
  65. + int ret;
  66. +
  67. phylink_set_link_an_mode(sfp->phylink, MLO_AN_SGMII);
  68. - sfp_sm_probe_phy(sfp);
  69. +
  70. + ret = sfp_sm_probe_phy(sfp);
  71. + if (ret) {
  72. + if (ret == -EAGAIN)
  73. + sfp_sm_set_timer(sfp, T_PROBE_RETRY);
  74. + else
  75. + sfp_sm_next(sfp, SFP_S_TX_DISABLE, 0);
  76. + return;
  77. + }
  78. }
  79. +
  80. + /* Wait t_init before indicating that the link is up, provided the
  81. + * current state indicates no TX_FAULT. If TX_FAULT clears before
  82. + * this time, that's fine too.
  83. + */
  84. + sfp_sm_next(sfp, SFP_S_INIT, T_INIT_JIFFIES);
  85. + sfp->sm_retries = 5;
  86. }
  87. }