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