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