125-phy-provide-a-hook-for-link-up-link-down-events.patch 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. From d8b4e728f598d3c8a9b219d4679d5de350caa082 Mon Sep 17 00:00:00 2001
  2. From: Russell King <rmk+kernel@arm.linux.org.uk>
  3. Date: Fri, 18 Sep 2015 14:42:16 +0100
  4. Subject: [PATCH 714/744] phy: provide a hook for link up/link down events
  5. Sometimes, we need to do additional work between the PHY coming up and
  6. marking the carrier present - for example, we may need to wait for the
  7. PHY to MAC link to finish negotiation. This changes phylib to provide
  8. a notification function pointer which avoids the built-in
  9. netif_carrier_on() and netif_carrier_off() functions.
  10. Standard ->adjust_link functionality is provided by hooking a helper
  11. into the new ->phy_link_change method.
  12. Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
  13. Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
  14. ---
  15. drivers/net/phy/phy.c | 42 ++++++++++++++++++++++--------------------
  16. drivers/net/phy/phy_device.c | 14 ++++++++++++++
  17. include/linux/phy.h | 1 +
  18. 3 files changed, 37 insertions(+), 20 deletions(-)
  19. --- a/drivers/net/phy/phy.c
  20. +++ b/drivers/net/phy/phy.c
  21. @@ -855,6 +855,16 @@ void phy_start(struct phy_device *phydev
  22. }
  23. EXPORT_SYMBOL(phy_start);
  24. +static void phy_link_up(struct phy_device *phydev)
  25. +{
  26. + phydev->phy_link_change(phydev, true, true);
  27. +}
  28. +
  29. +static void phy_link_down(struct phy_device *phydev, bool do_carrier)
  30. +{
  31. + phydev->phy_link_change(phydev, false, do_carrier);
  32. +}
  33. +
  34. /**
  35. * phy_state_machine - Handle the state machine
  36. * @work: work_struct that describes the work to be done
  37. @@ -896,8 +906,7 @@ void phy_state_machine(struct work_struc
  38. /* If the link is down, give up on negotiation for now */
  39. if (!phydev->link) {
  40. phydev->state = PHY_NOLINK;
  41. - netif_carrier_off(phydev->attached_dev);
  42. - phydev->adjust_link(phydev->attached_dev);
  43. + phy_link_down(phydev, true);
  44. break;
  45. }
  46. @@ -909,9 +918,7 @@ void phy_state_machine(struct work_struc
  47. /* If AN is done, we're running */
  48. if (err > 0) {
  49. phydev->state = PHY_RUNNING;
  50. - netif_carrier_on(phydev->attached_dev);
  51. - phydev->adjust_link(phydev->attached_dev);
  52. -
  53. + phy_link_up(phydev);
  54. } else if (0 == phydev->link_timeout--)
  55. needs_aneg = true;
  56. break;
  57. @@ -936,8 +943,7 @@ void phy_state_machine(struct work_struc
  58. }
  59. }
  60. phydev->state = PHY_RUNNING;
  61. - netif_carrier_on(phydev->attached_dev);
  62. - phydev->adjust_link(phydev->attached_dev);
  63. + phy_link_up(phydev);
  64. }
  65. break;
  66. case PHY_FORCING:
  67. @@ -947,13 +953,12 @@ void phy_state_machine(struct work_struc
  68. if (phydev->link) {
  69. phydev->state = PHY_RUNNING;
  70. - netif_carrier_on(phydev->attached_dev);
  71. + phy_link_up(phydev);
  72. } else {
  73. if (0 == phydev->link_timeout--)
  74. needs_aneg = true;
  75. + phy_link_down(phydev, false);
  76. }
  77. -
  78. - phydev->adjust_link(phydev->attached_dev);
  79. break;
  80. case PHY_RUNNING:
  81. /* Only register a CHANGE if we are polling or ignoring
  82. @@ -985,14 +990,12 @@ void phy_state_machine(struct work_struc
  83. if (phydev->link) {
  84. phydev->state = PHY_RUNNING;
  85. - netif_carrier_on(phydev->attached_dev);
  86. + phy_link_up(phydev);
  87. } else {
  88. phydev->state = PHY_NOLINK;
  89. - netif_carrier_off(phydev->attached_dev);
  90. + phy_link_down(phydev, true);
  91. }
  92. - phydev->adjust_link(phydev->attached_dev);
  93. -
  94. if (phy_interrupt_is_valid(phydev))
  95. err = phy_config_interrupt(phydev,
  96. PHY_INTERRUPT_ENABLED);
  97. @@ -1000,8 +1003,7 @@ void phy_state_machine(struct work_struc
  98. case PHY_HALTED:
  99. if (phydev->link) {
  100. phydev->link = 0;
  101. - netif_carrier_off(phydev->attached_dev);
  102. - phydev->adjust_link(phydev->attached_dev);
  103. + phy_link_down(phydev, true);
  104. do_suspend = true;
  105. }
  106. break;
  107. @@ -1021,11 +1023,11 @@ void phy_state_machine(struct work_struc
  108. if (phydev->link) {
  109. phydev->state = PHY_RUNNING;
  110. - netif_carrier_on(phydev->attached_dev);
  111. + phy_link_up(phydev);
  112. } else {
  113. phydev->state = PHY_NOLINK;
  114. + phy_link_down(phydev, false);
  115. }
  116. - phydev->adjust_link(phydev->attached_dev);
  117. } else {
  118. phydev->state = PHY_AN;
  119. phydev->link_timeout = PHY_AN_TIMEOUT;
  120. @@ -1037,11 +1039,11 @@ void phy_state_machine(struct work_struc
  121. if (phydev->link) {
  122. phydev->state = PHY_RUNNING;
  123. - netif_carrier_on(phydev->attached_dev);
  124. + phy_link_up(phydev);
  125. } else {
  126. phydev->state = PHY_NOLINK;
  127. + phy_link_down(phydev, false);
  128. }
  129. - phydev->adjust_link(phydev->attached_dev);
  130. }
  131. break;
  132. }
  133. --- a/drivers/net/phy/phy_device.c
  134. +++ b/drivers/net/phy/phy_device.c
  135. @@ -441,6 +441,19 @@ struct phy_device *phy_find_first(struct
  136. }
  137. EXPORT_SYMBOL(phy_find_first);
  138. +static void phy_link_change(struct phy_device *phydev, bool up, bool do_carrier)
  139. +{
  140. + struct net_device *netdev = phydev->attached_dev;
  141. +
  142. + if (do_carrier) {
  143. + if (up)
  144. + netif_carrier_on(netdev);
  145. + else
  146. + netif_carrier_off(netdev);
  147. + }
  148. + phydev->adjust_link(netdev);
  149. +}
  150. +
  151. /**
  152. * phy_prepare_link - prepares the PHY layer to monitor link status
  153. * @phydev: target phy_device struct
  154. @@ -662,6 +675,7 @@ int phy_attach_direct(struct net_device
  155. goto error;
  156. }
  157. + phydev->phy_link_change = phy_link_change;
  158. phydev->attached_dev = dev;
  159. dev->phydev = phydev;
  160. --- a/include/linux/phy.h
  161. +++ b/include/linux/phy.h
  162. @@ -429,6 +429,7 @@ struct phy_device {
  163. u8 mdix;
  164. + void (*phy_link_change)(struct phy_device *, bool up, bool do_carrier);
  165. void (*adjust_link)(struct net_device *dev);
  166. };
  167. #define to_phy_device(d) container_of(d, struct phy_device, dev)