122-phy-separate-swphy-state-validation-from-register-ge.patch 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. From e07630ad84c7dc145863f079f108154fb7c975e7 Mon Sep 17 00:00:00 2001
  2. From: Russell King <rmk+kernel@arm.linux.org.uk>
  3. Date: Sun, 20 Sep 2015 11:12:15 +0100
  4. Subject: [PATCH 711/744] phy: separate swphy state validation from register
  5. generation
  6. Separate out the generation of MII registers from the state validation.
  7. This allows us to simplify the error handing in fixed_phy() by allowing
  8. earlier error detection.
  9. Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
  10. Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
  11. ---
  12. drivers/net/phy/fixed_phy.c | 15 +++++++--------
  13. drivers/net/phy/swphy.c | 33 ++++++++++++++++++++++++++-------
  14. drivers/net/phy/swphy.h | 3 ++-
  15. 3 files changed, 35 insertions(+), 16 deletions(-)
  16. --- a/drivers/net/phy/fixed_phy.c
  17. +++ b/drivers/net/phy/fixed_phy.c
  18. @@ -49,12 +49,12 @@ static struct fixed_mdio_bus platform_fm
  19. .phys = LIST_HEAD_INIT(platform_fmb.phys),
  20. };
  21. -static int fixed_phy_update_regs(struct fixed_phy *fp)
  22. +static void fixed_phy_update_regs(struct fixed_phy *fp)
  23. {
  24. if (gpio_is_valid(fp->link_gpio))
  25. fp->status.link = !!gpio_get_value_cansleep(fp->link_gpio);
  26. - return swphy_update_regs(fp->regs, &fp->status);
  27. + swphy_update_regs(fp->regs, &fp->status);
  28. }
  29. static int fixed_mdio_read(struct mii_bus *bus, int phy_addr, int reg_num)
  30. @@ -161,6 +161,10 @@ int fixed_phy_add(unsigned int irq, int
  31. struct fixed_mdio_bus *fmb = &platform_fmb;
  32. struct fixed_phy *fp;
  33. + ret = swphy_validate_state(status);
  34. + if (ret < 0)
  35. + return ret;
  36. +
  37. fp = kzalloc(sizeof(*fp), GFP_KERNEL);
  38. if (!fp)
  39. return -ENOMEM;
  40. @@ -180,17 +184,12 @@ int fixed_phy_add(unsigned int irq, int
  41. goto err_regs;
  42. }
  43. - ret = fixed_phy_update_regs(fp);
  44. - if (ret)
  45. - goto err_gpio;
  46. + fixed_phy_update_regs(fp);
  47. list_add_tail(&fp->node, &fmb->phys);
  48. return 0;
  49. -err_gpio:
  50. - if (gpio_is_valid(fp->link_gpio))
  51. - gpio_free(fp->link_gpio);
  52. err_regs:
  53. kfree(fp);
  54. return ret;
  55. --- a/drivers/net/phy/swphy.c
  56. +++ b/drivers/net/phy/swphy.c
  57. @@ -87,6 +87,29 @@ static int swphy_decode_speed(int speed)
  58. }
  59. /**
  60. + * swphy_validate_state - validate the software phy status
  61. + * @state: software phy status
  62. + *
  63. + * This checks that we can represent the state stored in @state can be
  64. + * represented in the emulated MII registers. Returns 0 if it can,
  65. + * otherwise returns -EINVAL.
  66. + */
  67. +int swphy_validate_state(const struct fixed_phy_status *state)
  68. +{
  69. + int err;
  70. +
  71. + if (state->link) {
  72. + err = swphy_decode_speed(state->speed);
  73. + if (err < 0) {
  74. + pr_warn("swphy: unknown speed\n");
  75. + return -EINVAL;
  76. + }
  77. + }
  78. + return 0;
  79. +}
  80. +EXPORT_SYMBOL_GPL(swphy_validate_state);
  81. +
  82. +/**
  83. * swphy_update_regs - update MII register array with fixed phy state
  84. * @regs: array of 32 registers to update
  85. * @state: fixed phy status
  86. @@ -94,7 +117,7 @@ static int swphy_decode_speed(int speed)
  87. * Update the array of MII registers with the fixed phy link, speed,
  88. * duplex and pause mode settings.
  89. */
  90. -int swphy_update_regs(u16 *regs, const struct fixed_phy_status *state)
  91. +void swphy_update_regs(u16 *regs, const struct fixed_phy_status *state)
  92. {
  93. int speed_index, duplex_index;
  94. u16 bmsr = BMSR_ANEGCAPABLE;
  95. @@ -103,10 +126,8 @@ int swphy_update_regs(u16 *regs, const s
  96. u16 lpa = 0;
  97. speed_index = swphy_decode_speed(state->speed);
  98. - if (speed_index < 0) {
  99. - pr_warn("swphy: unknown speed\n");
  100. - return -EINVAL;
  101. - }
  102. + if (WARN_ON(speed_index < 0))
  103. + return;
  104. duplex_index = state->duplex ? SWMII_DUPLEX_FULL : SWMII_DUPLEX_HALF;
  105. @@ -133,7 +154,5 @@ int swphy_update_regs(u16 *regs, const s
  106. regs[MII_BMCR] = bmcr;
  107. regs[MII_LPA] = lpa;
  108. regs[MII_STAT1000] = lpagb;
  109. -
  110. - return 0;
  111. }
  112. EXPORT_SYMBOL_GPL(swphy_update_regs);
  113. --- a/drivers/net/phy/swphy.h
  114. +++ b/drivers/net/phy/swphy.h
  115. @@ -3,6 +3,7 @@
  116. struct fixed_phy_status;
  117. -int swphy_update_regs(u16 *regs, const struct fixed_phy_status *state);
  118. +int swphy_validate_state(const struct fixed_phy_status *state);
  119. +void swphy_update_regs(u16 *regs, const struct fixed_phy_status *state);
  120. #endif