121-phy-convert-swphy-register-generation-to-tabular-for.patch 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. From cd834fe430f030a63bfa9277bba194e8eef4dbd0 Mon Sep 17 00:00:00 2001
  2. From: Russell King <rmk+kernel@arm.linux.org.uk>
  3. Date: Sun, 20 Sep 2015 10:18:59 +0100
  4. Subject: [PATCH 710/744] phy: convert swphy register generation to tabular
  5. form
  6. Convert the swphy register generation to tabular form which allows us
  7. to eliminate multiple switch() statements. This results in a smaller
  8. object code size, more efficient, and easier to add support for faster
  9. speeds.
  10. Before:
  11. Idx Name Size VMA LMA File off Algn
  12. 0 .text 00000164 00000000 00000000 00000034 2**2
  13. text data bss dec hex filename
  14. 388 0 0 388 184 swphy.o
  15. After:
  16. Idx Name Size VMA LMA File off Algn
  17. 0 .text 000000fc 00000000 00000000 00000034 2**2
  18. 5 .rodata 00000028 00000000 00000000 00000138 2**2
  19. text data bss dec hex filename
  20. 324 0 0 324 144 swphy.o
  21. Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
  22. Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
  23. ---
  24. drivers/net/phy/swphy.c | 143 ++++++++++++++++++++++++++----------------------
  25. 1 file changed, 78 insertions(+), 65 deletions(-)
  26. --- a/drivers/net/phy/swphy.c
  27. +++ b/drivers/net/phy/swphy.c
  28. @@ -20,6 +20,72 @@
  29. #include "swphy.h"
  30. +struct swmii_regs {
  31. + u16 bmcr;
  32. + u16 bmsr;
  33. + u16 lpa;
  34. + u16 lpagb;
  35. +};
  36. +
  37. +enum {
  38. + SWMII_SPEED_10 = 0,
  39. + SWMII_SPEED_100,
  40. + SWMII_SPEED_1000,
  41. + SWMII_DUPLEX_HALF = 0,
  42. + SWMII_DUPLEX_FULL,
  43. +};
  44. +
  45. +/*
  46. + * These two tables get bitwise-anded together to produce the final result.
  47. + * This means the speed table must contain both duplex settings, and the
  48. + * duplex table must contain all speed settings.
  49. + */
  50. +static const struct swmii_regs speed[] = {
  51. + [SWMII_SPEED_10] = {
  52. + .bmcr = BMCR_FULLDPLX,
  53. + .lpa = LPA_10FULL | LPA_10HALF,
  54. + },
  55. + [SWMII_SPEED_100] = {
  56. + .bmcr = BMCR_FULLDPLX | BMCR_SPEED100,
  57. + .bmsr = BMSR_100FULL | BMSR_100HALF,
  58. + .lpa = LPA_100FULL | LPA_100HALF,
  59. + },
  60. + [SWMII_SPEED_1000] = {
  61. + .bmcr = BMCR_FULLDPLX | BMCR_SPEED1000,
  62. + .bmsr = BMSR_ESTATEN,
  63. + .lpagb = LPA_1000FULL | LPA_1000HALF,
  64. + },
  65. +};
  66. +
  67. +static const struct swmii_regs duplex[] = {
  68. + [SWMII_DUPLEX_HALF] = {
  69. + .bmcr = ~BMCR_FULLDPLX,
  70. + .bmsr = BMSR_ESTATEN | BMSR_100HALF,
  71. + .lpa = LPA_10HALF | LPA_100HALF,
  72. + .lpagb = LPA_1000HALF,
  73. + },
  74. + [SWMII_DUPLEX_FULL] = {
  75. + .bmcr = ~0,
  76. + .bmsr = BMSR_ESTATEN | BMSR_100FULL,
  77. + .lpa = LPA_10FULL | LPA_100FULL,
  78. + .lpagb = LPA_1000FULL,
  79. + },
  80. +};
  81. +
  82. +static int swphy_decode_speed(int speed)
  83. +{
  84. + switch (speed) {
  85. + case 1000:
  86. + return SWMII_SPEED_1000;
  87. + case 100:
  88. + return SWMII_SPEED_100;
  89. + case 10:
  90. + return SWMII_SPEED_10;
  91. + default:
  92. + return -EINVAL;
  93. + }
  94. +}
  95. +
  96. /**
  97. * swphy_update_regs - update MII register array with fixed phy state
  98. * @regs: array of 32 registers to update
  99. @@ -30,81 +96,28 @@
  100. */
  101. int swphy_update_regs(u16 *regs, const struct fixed_phy_status *state)
  102. {
  103. + int speed_index, duplex_index;
  104. u16 bmsr = BMSR_ANEGCAPABLE;
  105. u16 bmcr = 0;
  106. u16 lpagb = 0;
  107. u16 lpa = 0;
  108. - if (state->duplex) {
  109. - switch (state->speed) {
  110. - case 1000:
  111. - bmsr |= BMSR_ESTATEN;
  112. - break;
  113. - case 100:
  114. - bmsr |= BMSR_100FULL;
  115. - break;
  116. - case 10:
  117. - bmsr |= BMSR_10FULL;
  118. - break;
  119. - default:
  120. - break;
  121. - }
  122. - } else {
  123. - switch (state->speed) {
  124. - case 1000:
  125. - bmsr |= BMSR_ESTATEN;
  126. - break;
  127. - case 100:
  128. - bmsr |= BMSR_100HALF;
  129. - break;
  130. - case 10:
  131. - bmsr |= BMSR_10HALF;
  132. - break;
  133. - default:
  134. - break;
  135. - }
  136. + speed_index = swphy_decode_speed(state->speed);
  137. + if (speed_index < 0) {
  138. + pr_warn("swphy: unknown speed\n");
  139. + return -EINVAL;
  140. }
  141. + duplex_index = state->duplex ? SWMII_DUPLEX_FULL : SWMII_DUPLEX_HALF;
  142. +
  143. + bmsr |= speed[speed_index].bmsr & duplex[duplex_index].bmsr;
  144. +
  145. if (state->link) {
  146. bmsr |= BMSR_LSTATUS | BMSR_ANEGCOMPLETE;
  147. - if (state->duplex) {
  148. - bmcr |= BMCR_FULLDPLX;
  149. -
  150. - switch (state->speed) {
  151. - case 1000:
  152. - bmcr |= BMCR_SPEED1000;
  153. - lpagb |= LPA_1000FULL;
  154. - break;
  155. - case 100:
  156. - bmcr |= BMCR_SPEED100;
  157. - lpa |= LPA_100FULL;
  158. - break;
  159. - case 10:
  160. - lpa |= LPA_10FULL;
  161. - break;
  162. - default:
  163. - pr_warn("swphy: unknown speed\n");
  164. - return -EINVAL;
  165. - }
  166. - } else {
  167. - switch (state->speed) {
  168. - case 1000:
  169. - bmcr |= BMCR_SPEED1000;
  170. - lpagb |= LPA_1000HALF;
  171. - break;
  172. - case 100:
  173. - bmcr |= BMCR_SPEED100;
  174. - lpa |= LPA_100HALF;
  175. - break;
  176. - case 10:
  177. - lpa |= LPA_10HALF;
  178. - break;
  179. - default:
  180. - pr_warn("swphy: unknown speed\n");
  181. - return -EINVAL;
  182. - }
  183. - }
  184. + bmcr |= speed[speed_index].bmcr & duplex[duplex_index].bmcr;
  185. + lpa |= speed[speed_index].lpa & duplex[duplex_index].lpa;
  186. + lpagb |= speed[speed_index].lpagb & duplex[duplex_index].lpagb;
  187. if (state->pause)
  188. lpa |= LPA_PAUSE_CAP;