imx6: fix USB for 4.9 kernel
[oweals/openwrt.git] / target / linux / mvebu / patches-4.4 / 134-net-mvneta-convert-to-phylink.patch
1 From e268be0ddc666f4a98db462cbed2a97637e82b5c Mon Sep 17 00:00:00 2001
2 From: Russell King <rmk+kernel@arm.linux.org.uk>
3 Date: Wed, 16 Sep 2015 21:27:10 +0100
4 Subject: [PATCH 722/744] net: mvneta: convert to phylink
5
6 Convert mvneta to use phylink, which models the MAC to PHY link in
7 a generic, reusable form.
8
9 Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
10 ---
11  drivers/net/ethernet/marvell/Kconfig  |   2 +-
12  drivers/net/ethernet/marvell/mvneta.c | 451 +++++++++++++++++-----------------
13  2 files changed, 227 insertions(+), 226 deletions(-)
14
15 --- a/drivers/net/ethernet/marvell/Kconfig
16 +++ b/drivers/net/ethernet/marvell/Kconfig
17 @@ -58,7 +58,7 @@ config MVNETA
18         tristate "Marvell Armada 370/38x/XP network interface support"
19         depends on PLAT_ORION
20         select MVMDIO
21 -       select FIXED_PHY
22 +       select PHYLINK
23         ---help---
24           This driver supports the network interface units in the
25           Marvell ARMADA XP, ARMADA 370 and ARMADA 38x SoC family.
26 --- a/drivers/net/ethernet/marvell/mvneta.c
27 +++ b/drivers/net/ethernet/marvell/mvneta.c
28 @@ -28,6 +28,7 @@
29  #include <linux/of_mdio.h>
30  #include <linux/of_net.h>
31  #include <linux/phy.h>
32 +#include <linux/phylink.h>
33  #include <linux/platform_device.h>
34  #include <linux/skbuff.h>
35  #include <net/hwbm.h>
36 @@ -188,6 +189,7 @@
37  #define MVNETA_GMAC_CTRL_0                       0x2c00
38  #define      MVNETA_GMAC_MAX_RX_SIZE_SHIFT       2
39  #define      MVNETA_GMAC_MAX_RX_SIZE_MASK        0x7ffc
40 +#define      MVNETA_GMAC0_PORT_1000BASE_X        BIT(1)
41  #define      MVNETA_GMAC0_PORT_ENABLE            BIT(0)
42  #define MVNETA_GMAC_CTRL_2                       0x2c08
43  #define      MVNETA_GMAC2_INBAND_AN_ENABLE       BIT(0)
44 @@ -203,13 +205,19 @@
45  #define      MVNETA_GMAC_TX_FLOW_CTRL_ENABLE     BIT(5)
46  #define      MVNETA_GMAC_RX_FLOW_CTRL_ACTIVE     BIT(6)
47  #define      MVNETA_GMAC_TX_FLOW_CTRL_ACTIVE     BIT(7)
48 +#define      MVNETA_GMAC_AN_COMPLETE             BIT(11)
49 +#define      MVNETA_GMAC_SYNC_OK                 BIT(14)
50  #define MVNETA_GMAC_AUTONEG_CONFIG               0x2c0c
51  #define      MVNETA_GMAC_FORCE_LINK_DOWN         BIT(0)
52  #define      MVNETA_GMAC_FORCE_LINK_PASS         BIT(1)
53  #define      MVNETA_GMAC_INBAND_AN_ENABLE        BIT(2)
54 +#define      MVNETA_GMAC_AN_BYPASS_ENABLE        BIT(3)
55 +#define      MVNETA_GMAC_INBAND_RESTART_AN       BIT(4)
56  #define      MVNETA_GMAC_CONFIG_MII_SPEED        BIT(5)
57  #define      MVNETA_GMAC_CONFIG_GMII_SPEED       BIT(6)
58  #define      MVNETA_GMAC_AN_SPEED_EN             BIT(7)
59 +#define      MVNETA_GMAC_CONFIG_FLOW_CTRL        BIT(8)
60 +#define      MVNETA_GMAC_ADVERT_SYM_FLOW_CTRL    BIT(9)
61  #define      MVNETA_GMAC_AN_FLOW_CTRL_EN         BIT(11)
62  #define      MVNETA_GMAC_CONFIG_FULL_DUPLEX      BIT(12)
63  #define      MVNETA_GMAC_AN_DUPLEX_EN            BIT(13)
64 @@ -396,15 +404,9 @@ struct mvneta_port {
65         u16 tx_ring_size;
66         u16 rx_ring_size;
67  
68 -       struct mii_bus *mii_bus;
69 -       struct phy_device *phy_dev;
70 -       phy_interface_t phy_interface;
71 -       struct device_node *phy_node;
72 -       unsigned int link;
73 -       unsigned int duplex;
74 -       unsigned int speed;
75 +       struct device_node *dn;
76         unsigned int tx_csum_limit;
77 -       unsigned int use_inband_status:1;
78 +       struct phylink *phylink;
79  
80         struct mvneta_bm *bm_priv;
81         struct mvneta_bm_pool *pool_long;
82 @@ -1236,44 +1238,6 @@ static void mvneta_set_other_mcast_table
83                 mvreg_write(pp, MVNETA_DA_FILT_OTH_MCAST + offset, val);
84  }
85  
86 -static void mvneta_set_autoneg(struct mvneta_port *pp, int enable)
87 -{
88 -       u32 val;
89 -
90 -       if (enable) {
91 -               val = mvreg_read(pp, MVNETA_GMAC_AUTONEG_CONFIG);
92 -               val &= ~(MVNETA_GMAC_FORCE_LINK_PASS |
93 -                        MVNETA_GMAC_FORCE_LINK_DOWN |
94 -                        MVNETA_GMAC_AN_FLOW_CTRL_EN);
95 -               val |= MVNETA_GMAC_INBAND_AN_ENABLE |
96 -                      MVNETA_GMAC_AN_SPEED_EN |
97 -                      MVNETA_GMAC_AN_DUPLEX_EN;
98 -               mvreg_write(pp, MVNETA_GMAC_AUTONEG_CONFIG, val);
99 -
100 -               val = mvreg_read(pp, MVNETA_GMAC_CLOCK_DIVIDER);
101 -               val |= MVNETA_GMAC_1MS_CLOCK_ENABLE;
102 -               mvreg_write(pp, MVNETA_GMAC_CLOCK_DIVIDER, val);
103 -
104 -               val = mvreg_read(pp, MVNETA_GMAC_CTRL_2);
105 -               val |= MVNETA_GMAC2_INBAND_AN_ENABLE;
106 -               mvreg_write(pp, MVNETA_GMAC_CTRL_2, val);
107 -       } else {
108 -               val = mvreg_read(pp, MVNETA_GMAC_AUTONEG_CONFIG);
109 -               val &= ~(MVNETA_GMAC_INBAND_AN_ENABLE |
110 -                      MVNETA_GMAC_AN_SPEED_EN |
111 -                      MVNETA_GMAC_AN_DUPLEX_EN);
112 -               mvreg_write(pp, MVNETA_GMAC_AUTONEG_CONFIG, val);
113 -
114 -               val = mvreg_read(pp, MVNETA_GMAC_CLOCK_DIVIDER);
115 -               val &= ~MVNETA_GMAC_1MS_CLOCK_ENABLE;
116 -               mvreg_write(pp, MVNETA_GMAC_CLOCK_DIVIDER, val);
117 -
118 -               val = mvreg_read(pp, MVNETA_GMAC_CTRL_2);
119 -               val &= ~MVNETA_GMAC2_INBAND_AN_ENABLE;
120 -               mvreg_write(pp, MVNETA_GMAC_CTRL_2, val);
121 -       }
122 -}
123 -
124  static void mvneta_percpu_unmask_interrupt(void *arg)
125  {
126         struct mvneta_port *pp = arg;
127 @@ -1421,7 +1385,6 @@ static void mvneta_defaults_set(struct m
128         val &= ~MVNETA_PHY_POLLING_ENABLE;
129         mvreg_write(pp, MVNETA_UNIT_CONTROL, val);
130  
131 -       mvneta_set_autoneg(pp, pp->use_inband_status);
132         mvneta_set_ucast_table(pp, -1);
133         mvneta_set_special_mcast_table(pp, -1);
134         mvneta_set_other_mcast_table(pp, -1);
135 @@ -2614,26 +2577,11 @@ static irqreturn_t mvneta_isr(int irq, v
136         return IRQ_HANDLED;
137  }
138  
139 -static int mvneta_fixed_link_update(struct mvneta_port *pp,
140 -                                   struct phy_device *phy)
141 +static void mvneta_link_change(struct mvneta_port *pp)
142  {
143 -       struct fixed_phy_status status;
144 -       struct fixed_phy_status changed = {};
145         u32 gmac_stat = mvreg_read(pp, MVNETA_GMAC_STATUS);
146  
147 -       status.link = !!(gmac_stat & MVNETA_GMAC_LINK_UP);
148 -       if (gmac_stat & MVNETA_GMAC_SPEED_1000)
149 -               status.speed = SPEED_1000;
150 -       else if (gmac_stat & MVNETA_GMAC_SPEED_100)
151 -               status.speed = SPEED_100;
152 -       else
153 -               status.speed = SPEED_10;
154 -       status.duplex = !!(gmac_stat & MVNETA_GMAC_FULL_DUPLEX);
155 -       changed.link = 1;
156 -       changed.speed = 1;
157 -       changed.duplex = 1;
158 -       fixed_phy_update_state(phy, &status, &changed);
159 -       return 0;
160 +       phylink_mac_change(pp->phylink, !!(gmac_stat & MVNETA_GMAC_LINK_UP));
161  }
162  
163  /* NAPI handler
164 @@ -2662,12 +2610,11 @@ static int mvneta_poll(struct napi_struc
165                 u32 cause_misc = mvreg_read(pp, MVNETA_INTR_MISC_CAUSE);
166  
167                 mvreg_write(pp, MVNETA_INTR_MISC_CAUSE, 0);
168 -               if (pp->use_inband_status && (cause_misc &
169 -                               (MVNETA_CAUSE_PHY_STATUS_CHANGE |
170 -                                MVNETA_CAUSE_LINK_CHANGE |
171 -                                MVNETA_CAUSE_PSC_SYNC_CHANGE))) {
172 -                       mvneta_fixed_link_update(pp, pp->phy_dev);
173 -               }
174 +
175 +               if (cause_misc & (MVNETA_CAUSE_PHY_STATUS_CHANGE |
176 +                                 MVNETA_CAUSE_LINK_CHANGE |
177 +                                 MVNETA_CAUSE_PSC_SYNC_CHANGE))
178 +                       mvneta_link_change(pp);
179         }
180  
181         /* Release Tx descriptors */
182 @@ -2983,7 +2930,7 @@ static void mvneta_start_dev(struct mvne
183                     MVNETA_CAUSE_LINK_CHANGE |
184                     MVNETA_CAUSE_PSC_SYNC_CHANGE);
185  
186 -       phy_start(pp->phy_dev);
187 +       phylink_start(pp->phylink);
188         netif_tx_start_all_queues(pp->dev);
189  }
190  
191 @@ -2991,7 +2938,7 @@ static void mvneta_stop_dev(struct mvnet
192  {
193         unsigned int cpu;
194  
195 -       phy_stop(pp->phy_dev);
196 +       phylink_stop(pp->phylink);
197  
198         for_each_online_cpu(cpu) {
199                 struct mvneta_pcpu_port *port = per_cpu_ptr(pp->ports, cpu);
200 @@ -3161,99 +3108,219 @@ static int mvneta_set_mac_addr(struct ne
201         return 0;
202  }
203  
204 -static void mvneta_adjust_link(struct net_device *ndev)
205 +static int mvneta_mac_support(struct net_device *ndev, unsigned int mode,
206 +                             struct phylink_link_state *state)
207 +{
208 +       switch (mode) {
209 +       case MLO_AN_8023Z:
210 +               state->supported = SUPPORTED_1000baseT_Full |
211 +                                  SUPPORTED_Autoneg | SUPPORTED_Pause;
212 +               state->advertising = ADVERTISED_1000baseT_Full |
213 +                                    ADVERTISED_Autoneg | ADVERTISED_Pause;
214 +               state->an_enabled = 1;
215 +               break;
216 +
217 +       case MLO_AN_FIXED:
218 +               break;
219 +
220 +       default:
221 +               state->supported = PHY_10BT_FEATURES |
222 +                                  PHY_100BT_FEATURES |
223 +                                  SUPPORTED_1000baseT_Full |
224 +                                  SUPPORTED_Autoneg;
225 +               state->advertising = ADVERTISED_10baseT_Half |
226 +                                    ADVERTISED_10baseT_Full |
227 +                                    ADVERTISED_100baseT_Half |
228 +                                    ADVERTISED_100baseT_Full |
229 +                                    ADVERTISED_1000baseT_Full |
230 +                                    ADVERTISED_Autoneg;
231 +               state->an_enabled = 1;
232 +               break;
233 +       }
234 +       return 0;
235 +}
236 +
237 +static int mvneta_mac_link_state(struct net_device *ndev,
238 +                                struct phylink_link_state *state)
239  {
240         struct mvneta_port *pp = netdev_priv(ndev);
241 -       struct phy_device *phydev = pp->phy_dev;
242 -       int status_change = 0;
243 +       u32 gmac_stat;
244  
245 -       if (phydev->link) {
246 -               if ((pp->speed != phydev->speed) ||
247 -                   (pp->duplex != phydev->duplex)) {
248 -                       u32 val;
249 -
250 -                       val = mvreg_read(pp, MVNETA_GMAC_AUTONEG_CONFIG);
251 -                       val &= ~(MVNETA_GMAC_CONFIG_MII_SPEED |
252 -                                MVNETA_GMAC_CONFIG_GMII_SPEED |
253 -                                MVNETA_GMAC_CONFIG_FULL_DUPLEX);
254 -
255 -                       if (phydev->duplex)
256 -                               val |= MVNETA_GMAC_CONFIG_FULL_DUPLEX;
257 -
258 -                       if (phydev->speed == SPEED_1000)
259 -                               val |= MVNETA_GMAC_CONFIG_GMII_SPEED;
260 -                       else if (phydev->speed == SPEED_100)
261 -                               val |= MVNETA_GMAC_CONFIG_MII_SPEED;
262 +       gmac_stat = mvreg_read(pp, MVNETA_GMAC_STATUS);
263  
264 -                       mvreg_write(pp, MVNETA_GMAC_AUTONEG_CONFIG, val);
265 +       if (gmac_stat & MVNETA_GMAC_SPEED_1000)
266 +               state->speed = SPEED_1000;
267 +       else if (gmac_stat & MVNETA_GMAC_SPEED_100)
268 +               state->speed = SPEED_100;
269 +       else
270 +               state->speed = SPEED_10;
271  
272 -                       pp->duplex = phydev->duplex;
273 -                       pp->speed  = phydev->speed;
274 -               }
275 +       state->an_complete = !!(gmac_stat & MVNETA_GMAC_AN_COMPLETE);
276 +       state->sync = !!(gmac_stat & MVNETA_GMAC_SYNC_OK);
277 +       state->link = !!(gmac_stat & MVNETA_GMAC_LINK_UP);
278 +       state->duplex = !!(gmac_stat & MVNETA_GMAC_FULL_DUPLEX);
279 +
280 +       state->pause = 0;
281 +       if (gmac_stat & MVNETA_GMAC_RX_FLOW_CTRL_ENABLE)
282 +               state->pause |= MLO_PAUSE_RX;
283 +       if (gmac_stat & MVNETA_GMAC_TX_FLOW_CTRL_ENABLE)
284 +               state->pause |= MLO_PAUSE_TX;
285 +
286 +       return 1;
287 +}
288 +
289 +static void mvneta_mac_an_restart(struct net_device *ndev, unsigned int mode)
290 +{
291 +       struct mvneta_port *pp = netdev_priv(ndev);
292 +
293 +       if (mode == MLO_AN_8023Z) {
294 +               u32 gmac_an = mvreg_read(pp, MVNETA_GMAC_AUTONEG_CONFIG);
295 +
296 +               mvreg_write(pp, MVNETA_GMAC_AUTONEG_CONFIG,
297 +                           gmac_an | MVNETA_GMAC_INBAND_RESTART_AN);
298 +               mvreg_write(pp, MVNETA_GMAC_AUTONEG_CONFIG,
299 +                           gmac_an & ~MVNETA_GMAC_INBAND_RESTART_AN);
300         }
301 +}
302  
303 -       if (phydev->link != pp->link) {
304 -               if (!phydev->link) {
305 -                       pp->duplex = -1;
306 -                       pp->speed = 0;
307 -               }
308 +static void mvneta_mac_config(struct net_device *ndev, unsigned int mode,
309 +       const struct phylink_link_state *state)
310 +{
311 +       struct mvneta_port *pp = netdev_priv(ndev);
312 +       u32 new_ctrl0, gmac_ctrl0 = mvreg_read(pp, MVNETA_GMAC_CTRL_0);
313 +       u32 new_ctrl2, gmac_ctrl2 = mvreg_read(pp, MVNETA_GMAC_CTRL_2);
314 +       u32 new_clk, gmac_clk = mvreg_read(pp, MVNETA_GMAC_CLOCK_DIVIDER);
315 +       u32 new_an, gmac_an = mvreg_read(pp, MVNETA_GMAC_AUTONEG_CONFIG);
316 +
317 +       new_ctrl0 = gmac_ctrl0 & ~MVNETA_GMAC0_PORT_1000BASE_X;
318 +       new_ctrl2 = gmac_ctrl2 & ~MVNETA_GMAC2_INBAND_AN_ENABLE;
319 +       new_clk = gmac_clk & ~MVNETA_GMAC_1MS_CLOCK_ENABLE;
320 +       new_an = gmac_an & ~(MVNETA_GMAC_INBAND_AN_ENABLE |
321 +                            MVNETA_GMAC_INBAND_RESTART_AN |
322 +                            MVNETA_GMAC_CONFIG_MII_SPEED |
323 +                            MVNETA_GMAC_CONFIG_GMII_SPEED |
324 +                            MVNETA_GMAC_AN_SPEED_EN |
325 +                            MVNETA_GMAC_ADVERT_SYM_FLOW_CTRL |
326 +                            MVNETA_GMAC_CONFIG_FLOW_CTRL |
327 +                            MVNETA_GMAC_AN_FLOW_CTRL_EN |
328 +                            MVNETA_GMAC_CONFIG_FULL_DUPLEX |
329 +                            MVNETA_GMAC_AN_DUPLEX_EN);
330 +
331 +       if (state->advertising & ADVERTISED_Pause)
332 +               new_an |= MVNETA_GMAC_ADVERT_SYM_FLOW_CTRL;
333 +
334 +       switch (mode) {
335 +       case MLO_AN_SGMII:
336 +               /* SGMII mode receives the state from the PHY */
337 +               new_ctrl2 |= MVNETA_GMAC2_INBAND_AN_ENABLE;
338 +               new_clk |= MVNETA_GMAC_1MS_CLOCK_ENABLE;
339 +               new_an = (new_an & ~(MVNETA_GMAC_FORCE_LINK_DOWN |
340 +                                    MVNETA_GMAC_FORCE_LINK_PASS)) |
341 +                        MVNETA_GMAC_INBAND_AN_ENABLE |
342 +                        MVNETA_GMAC_AN_SPEED_EN |
343 +                        MVNETA_GMAC_AN_DUPLEX_EN;
344 +               break;
345 +
346 +       case MLO_AN_8023Z:
347 +               /* 802.3z negotiation - only 1000base-X */
348 +               new_ctrl0 |= MVNETA_GMAC0_PORT_1000BASE_X;
349 +               new_clk |= MVNETA_GMAC_1MS_CLOCK_ENABLE;
350 +               new_an = (new_an & ~(MVNETA_GMAC_FORCE_LINK_DOWN |
351 +                                    MVNETA_GMAC_FORCE_LINK_PASS)) |
352 +                        MVNETA_GMAC_INBAND_AN_ENABLE |
353 +                        MVNETA_GMAC_CONFIG_GMII_SPEED |
354 +                        /* The MAC only supports FD mode */
355 +                        MVNETA_GMAC_CONFIG_FULL_DUPLEX;
356 +
357 +               if (state->an_enabled)
358 +                       new_an |= MVNETA_GMAC_AN_FLOW_CTRL_EN;
359 +               break;
360  
361 -               pp->link = phydev->link;
362 -               status_change = 1;
363 +       default:
364 +               /* Phy or fixed speed */
365 +               if (state->duplex)
366 +                       new_an |= MVNETA_GMAC_CONFIG_FULL_DUPLEX;
367 +
368 +               if (state->speed == SPEED_1000)
369 +                       new_an |= MVNETA_GMAC_CONFIG_GMII_SPEED;
370 +               else if (state->speed == SPEED_100)
371 +                       new_an |= MVNETA_GMAC_CONFIG_MII_SPEED;
372 +               break;
373         }
374  
375 -       if (status_change) {
376 -               if (phydev->link) {
377 -                       if (!pp->use_inband_status) {
378 -                               u32 val = mvreg_read(pp,
379 -                                                 MVNETA_GMAC_AUTONEG_CONFIG);
380 -                               val &= ~MVNETA_GMAC_FORCE_LINK_DOWN;
381 -                               val |= MVNETA_GMAC_FORCE_LINK_PASS;
382 -                               mvreg_write(pp, MVNETA_GMAC_AUTONEG_CONFIG,
383 -                                           val);
384 -                       }
385 -                       mvneta_port_up(pp);
386 -               } else {
387 -                       if (!pp->use_inband_status) {
388 -                               u32 val = mvreg_read(pp,
389 -                                                 MVNETA_GMAC_AUTONEG_CONFIG);
390 -                               val &= ~MVNETA_GMAC_FORCE_LINK_PASS;
391 -                               val |= MVNETA_GMAC_FORCE_LINK_DOWN;
392 -                               mvreg_write(pp, MVNETA_GMAC_AUTONEG_CONFIG,
393 -                                           val);
394 -                       }
395 -                       mvneta_port_down(pp);
396 -               }
397 -               phy_print_status(phydev);
398 +       /* Armada 370 documentation says we can only change the port mode
399 +        * and in-band enable when the link is down, so force it down
400 +        * while making these changes. We also do this for GMAC_CTRL2 */
401 +       if ((new_ctrl0 ^ gmac_ctrl0) & MVNETA_GMAC0_PORT_1000BASE_X ||
402 +           (new_ctrl2 ^ gmac_ctrl2) & MVNETA_GMAC2_INBAND_AN_ENABLE ||
403 +           (new_an  ^ gmac_an) & MVNETA_GMAC_INBAND_AN_ENABLE) {
404 +               mvreg_write(pp, MVNETA_GMAC_AUTONEG_CONFIG,
405 +                           (gmac_an & ~MVNETA_GMAC_FORCE_LINK_PASS) |
406 +                           MVNETA_GMAC_FORCE_LINK_DOWN);
407 +       }
408 +
409 +       if (new_ctrl0 != gmac_ctrl0)
410 +               mvreg_write(pp, MVNETA_GMAC_CTRL_0, new_ctrl0);
411 +       if (new_ctrl2 != gmac_ctrl2)
412 +               mvreg_write(pp, MVNETA_GMAC_CTRL_2, new_ctrl2);
413 +       if (new_clk != gmac_clk)
414 +               mvreg_write(pp, MVNETA_GMAC_CLOCK_DIVIDER, new_clk);
415 +       if (new_an != gmac_an)
416 +               mvreg_write(pp, MVNETA_GMAC_AUTONEG_CONFIG, new_an);
417 +}
418 +
419 +static void mvneta_mac_link_down(struct net_device *ndev, unsigned int mode)
420 +{
421 +       struct mvneta_port *pp = netdev_priv(ndev);
422 +       u32 val;
423 +
424 +       mvneta_port_down(pp);
425 +
426 +       if (mode == MLO_AN_PHY || mode == MLO_AN_FIXED) {
427 +               val = mvreg_read(pp, MVNETA_GMAC_AUTONEG_CONFIG);
428 +               val &= ~MVNETA_GMAC_FORCE_LINK_PASS;
429 +               val |= MVNETA_GMAC_FORCE_LINK_DOWN;
430 +               mvreg_write(pp, MVNETA_GMAC_AUTONEG_CONFIG, val);
431         }
432  }
433  
434 -static int mvneta_mdio_probe(struct mvneta_port *pp)
435 +static void mvneta_mac_link_up(struct net_device *ndev, unsigned int mode,
436 +                              struct phy_device *phy)
437  {
438 -       struct phy_device *phy_dev;
439 +       struct mvneta_port *pp = netdev_priv(ndev);
440 +       u32 val;
441 +
442 +       if (mode == MLO_AN_PHY || mode == MLO_AN_FIXED) {
443 +               val = mvreg_read(pp, MVNETA_GMAC_AUTONEG_CONFIG);
444 +               val &= ~MVNETA_GMAC_FORCE_LINK_DOWN;
445 +               val |= MVNETA_GMAC_FORCE_LINK_PASS;
446 +               mvreg_write(pp, MVNETA_GMAC_AUTONEG_CONFIG, val);
447 +       }
448  
449 -       phy_dev = of_phy_connect(pp->dev, pp->phy_node, mvneta_adjust_link, 0,
450 -                                pp->phy_interface);
451 -       if (!phy_dev) {
452 -               netdev_err(pp->dev, "could not find the PHY\n");
453 -               return -ENODEV;
454 -       }
455 -
456 -       phy_dev->supported &= PHY_GBIT_FEATURES;
457 -       phy_dev->advertising = phy_dev->supported;
458 -
459 -       pp->phy_dev = phy_dev;
460 -       pp->link    = 0;
461 -       pp->duplex  = 0;
462 -       pp->speed   = 0;
463 +       mvneta_port_up(pp);
464 +}
465  
466 -       return 0;
467 +static const struct phylink_mac_ops mvneta_phylink_ops = {
468 +       .mac_get_support = mvneta_mac_support,
469 +       .mac_link_state = mvneta_mac_link_state,
470 +       .mac_an_restart = mvneta_mac_an_restart,
471 +       .mac_config = mvneta_mac_config,
472 +       .mac_link_down = mvneta_mac_link_down,
473 +       .mac_link_up = mvneta_mac_link_up,
474 +};
475 +
476 +static int mvneta_mdio_probe(struct mvneta_port *pp)
477 +{
478 +       int err = phylink_of_phy_connect(pp->phylink, pp->dn);
479 +       if (err)
480 +               netdev_err(pp->dev, "could not attach PHY\n");
481 +
482 +       return err;
483  }
484  
485  static void mvneta_mdio_remove(struct mvneta_port *pp)
486  {
487 -       phy_disconnect(pp->phy_dev);
488 -       pp->phy_dev = NULL;
489 +       phylink_disconnect_phy(pp->phylink);
490  }
491  
492  /* Electing a CPU must be done in an atomic way: it should be done
493 @@ -3501,10 +3568,7 @@ static int mvneta_ioctl(struct net_devic
494  {
495         struct mvneta_port *pp = netdev_priv(dev);
496  
497 -       if (!pp->phy_dev)
498 -               return -ENOTSUPP;
499 -
500 -       return phy_mii_ioctl(pp->phy_dev, ifr, cmd);
501 +       return phylink_mii_ioctl(pp->phylink, ifr, cmd);
502  }
503  
504  /* Ethtool methods */
505 @@ -3514,54 +3578,15 @@ int mvneta_ethtool_get_settings(struct n
506  {
507         struct mvneta_port *pp = netdev_priv(dev);
508  
509 -       if (!pp->phy_dev)
510 -               return -ENODEV;
511 -
512 -       return phy_ethtool_gset(pp->phy_dev, cmd);
513 +       return phylink_ethtool_get_settings(pp->phylink, cmd);
514  }
515  
516  /* Set settings (phy address, speed) for ethtools */
517  int mvneta_ethtool_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
518  {
519         struct mvneta_port *pp = netdev_priv(dev);
520 -       struct phy_device *phydev = pp->phy_dev;
521 -
522 -       if (!phydev)
523 -               return -ENODEV;
524  
525 -       if ((cmd->autoneg == AUTONEG_ENABLE) != pp->use_inband_status) {
526 -               u32 val;
527 -
528 -               mvneta_set_autoneg(pp, cmd->autoneg == AUTONEG_ENABLE);
529 -
530 -               if (cmd->autoneg == AUTONEG_DISABLE) {
531 -                       val = mvreg_read(pp, MVNETA_GMAC_AUTONEG_CONFIG);
532 -                       val &= ~(MVNETA_GMAC_CONFIG_MII_SPEED |
533 -                                MVNETA_GMAC_CONFIG_GMII_SPEED |
534 -                                MVNETA_GMAC_CONFIG_FULL_DUPLEX);
535 -
536 -                       if (phydev->duplex)
537 -                               val |= MVNETA_GMAC_CONFIG_FULL_DUPLEX;
538 -
539 -                       if (phydev->speed == SPEED_1000)
540 -                               val |= MVNETA_GMAC_CONFIG_GMII_SPEED;
541 -                       else if (phydev->speed == SPEED_100)
542 -                               val |= MVNETA_GMAC_CONFIG_MII_SPEED;
543 -
544 -                       mvreg_write(pp, MVNETA_GMAC_AUTONEG_CONFIG, val);
545 -               }
546 -
547 -               pp->use_inband_status = (cmd->autoneg == AUTONEG_ENABLE);
548 -               netdev_info(pp->dev, "autoneg status set to %i\n",
549 -                           pp->use_inband_status);
550 -
551 -               if (netif_running(dev)) {
552 -                       mvneta_port_down(pp);
553 -                       mvneta_port_up(pp);
554 -               }
555 -       }
556 -
557 -       return phy_ethtool_sset(pp->phy_dev, cmd);
558 +       return phylink_ethtool_set_settings(pp->phylink, cmd);
559  }
560  
561  /* Set interrupt coalescing for ethtools */
562 @@ -3669,7 +3694,8 @@ static void mvneta_ethtool_update_stats(
563  {
564         const struct mvneta_statistic *s;
565         void __iomem *base = pp->base;
566 -       u32 high, low, val;
567 +       u32 high, low;
568 +       u64 val;
569         u64 val64;
570         int i;
571  
572 @@ -3964,14 +3990,13 @@ static int mvneta_probe(struct platform_
573         const struct mbus_dram_target_info *dram_target_info;
574         struct resource *res;
575         struct device_node *dn = pdev->dev.of_node;
576 -       struct device_node *phy_node;
577         struct device_node *bm_node;
578         struct mvneta_port *pp;
579         struct net_device *dev;
580 +       struct phylink *phylink;
581         const char *dt_mac_addr;
582         char hw_mac_addr[ETH_ALEN];
583         const char *mac_from;
584 -       const char *managed;
585         int tx_csum_limit;
586         int phy_mode;
587         int err;
588 @@ -3987,31 +4012,11 @@ static int mvneta_probe(struct platform_
589                 goto err_free_netdev;
590         }
591  
592 -       phy_node = of_parse_phandle(dn, "phy", 0);
593 -       if (!phy_node) {
594 -               if (!of_phy_is_fixed_link(dn)) {
595 -                       dev_err(&pdev->dev, "no PHY specified\n");
596 -                       err = -ENODEV;
597 -                       goto err_free_irq;
598 -               }
599 -
600 -               err = of_phy_register_fixed_link(dn);
601 -               if (err < 0) {
602 -                       dev_err(&pdev->dev, "cannot register fixed PHY\n");
603 -                       goto err_free_irq;
604 -               }
605 -
606 -               /* In the case of a fixed PHY, the DT node associated
607 -                * to the PHY is the Ethernet MAC DT node.
608 -                */
609 -               phy_node = of_node_get(dn);
610 -       }
611 -
612         phy_mode = of_get_phy_mode(dn);
613         if (phy_mode < 0) {
614                 dev_err(&pdev->dev, "incorrect phy-mode\n");
615                 err = -EINVAL;
616 -               goto err_put_phy_node;
617 +               goto err_free_irq;
618         }
619  
620         dev->tx_queue_len = MVNETA_MAX_TXD;
621 @@ -4022,12 +4027,7 @@ static int mvneta_probe(struct platform_
622  
623         pp = netdev_priv(dev);
624         spin_lock_init(&pp->lock);
625 -       pp->phy_node = phy_node;
626 -       pp->phy_interface = phy_mode;
627 -
628 -       err = of_property_read_string(dn, "managed", &managed);
629 -       pp->use_inband_status = (err == 0 &&
630 -                                strcmp(managed, "in-band-status") == 0);
631 +       pp->dn = dn;
632         pp->cpu_notifier.notifier_call = mvneta_percpu_notifier;
633  
634         pp->rxq_def = rxq_def;
635 @@ -4037,7 +4037,7 @@ static int mvneta_probe(struct platform_
636         pp->clk = devm_clk_get(&pdev->dev, NULL);
637         if (IS_ERR(pp->clk)) {
638                 err = PTR_ERR(pp->clk);
639 -               goto err_put_phy_node;
640 +               goto err_free_irq;
641         }
642  
643         clk_prepare_enable(pp->clk);
644 @@ -4140,6 +4140,14 @@ static int mvneta_probe(struct platform_
645         dev->priv_flags |= IFF_UNICAST_FLT | IFF_LIVE_ADDR_CHANGE;
646         dev->gso_max_segs = MVNETA_MAX_TSO_SEGS;
647  
648 +       phylink = phylink_create(dev, dn, phy_mode, &mvneta_phylink_ops);
649 +       if (IS_ERR(phylink)) {
650 +               err = PTR_ERR(phylink);
651 +               goto err_free_stats;
652 +       }
653 +
654 +       pp->phylink = phylink;
655 +
656         err = register_netdev(dev);
657         if (err < 0) {
658                 dev_err(&pdev->dev, "failed to register\n");
659 @@ -4151,13 +4159,6 @@ static int mvneta_probe(struct platform_
660  
661         platform_set_drvdata(pdev, pp->dev);
662  
663 -       if (pp->use_inband_status) {
664 -               struct phy_device *phy = of_phy_find_device(dn);
665 -
666 -               mvneta_fixed_link_update(pp, phy);
667 -
668 -               put_device(&phy->dev);
669 -       }
670  
671         return 0;
672  
673 @@ -4169,13 +4170,13 @@ err_netdev:
674                                        1 << pp->id);
675         }
676  err_free_stats:
677 +       if (pp->phylink)
678 +               phylink_destroy(pp->phylink);
679         free_percpu(pp->stats);
680  err_free_ports:
681         free_percpu(pp->ports);
682  err_clk:
683         clk_disable_unprepare(pp->clk);
684 -err_put_phy_node:
685 -       of_node_put(phy_node);
686  err_free_irq:
687         irq_dispose_mapping(dev->irq);
688  err_free_netdev:
689 @@ -4194,7 +4195,7 @@ static int mvneta_remove(struct platform
690         free_percpu(pp->ports);
691         free_percpu(pp->stats);
692         irq_dispose_mapping(dev->irq);
693 -       of_node_put(pp->phy_node);
694 +       phylink_destroy(pp->phylink);
695         free_netdev(dev);
696  
697         if (pp->bm_priv) {