• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * phylink models the MAC to optional PHY connection, supporting
3  * technologies such as SFP cages where the PHY is hot-pluggable.
4  *
5  * Copyright (C) 2015 Russell King
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License version 2 as
9  * published by the Free Software Foundation.
10  */
11 #include <linux/ethtool.h>
12 #include <linux/export.h>
13 #include <linux/gpio/consumer.h>
14 #include <linux/netdevice.h>
15 #include <linux/of.h>
16 #include <linux/of_mdio.h>
17 #include <linux/phy.h>
18 #include <linux/phy_fixed.h>
19 #include <linux/phylink.h>
20 #include <linux/rtnetlink.h>
21 #include <linux/spinlock.h>
22 #include <linux/workqueue.h>
23 
24 #include "sfp.h"
25 #include "swphy.h"
26 
27 #define SUPPORTED_INTERFACES \
28 	(SUPPORTED_TP | SUPPORTED_MII | SUPPORTED_FIBRE | \
29 	 SUPPORTED_BNC | SUPPORTED_AUI | SUPPORTED_Backplane)
30 #define ADVERTISED_INTERFACES \
31 	(ADVERTISED_TP | ADVERTISED_MII | ADVERTISED_FIBRE | \
32 	 ADVERTISED_BNC | ADVERTISED_AUI | ADVERTISED_Backplane)
33 
34 enum {
35 	PHYLINK_DISABLE_STOPPED,
36 	PHYLINK_DISABLE_LINK,
37 };
38 
39 struct phylink {
40 	struct net_device *netdev;
41 	const struct phylink_mac_ops *ops;
42 
43 	unsigned long phylink_disable_state; /* bitmask of disables */
44 	struct phy_device *phydev;
45 	phy_interface_t link_interface;	/* PHY_INTERFACE_xxx */
46 	u8 link_an_mode;		/* MLO_AN_xxx */
47 	u8 link_port;			/* The current non-phy ethtool port */
48 	__ETHTOOL_DECLARE_LINK_MODE_MASK(supported);
49 
50 	/* The link configuration settings */
51 	struct phylink_link_state link_config;
52 	struct gpio_desc *link_gpio;
53 
54 	struct mutex state_mutex;
55 	struct phylink_link_state phy_state;
56 	struct work_struct resolve;
57 
58 	bool mac_link_dropped;
59 
60 	struct sfp_bus *sfp_bus;
61 };
62 
linkmode_zero(unsigned long * dst)63 static inline void linkmode_zero(unsigned long *dst)
64 {
65 	bitmap_zero(dst, __ETHTOOL_LINK_MODE_MASK_NBITS);
66 }
67 
linkmode_copy(unsigned long * dst,const unsigned long * src)68 static inline void linkmode_copy(unsigned long *dst, const unsigned long *src)
69 {
70 	bitmap_copy(dst, src, __ETHTOOL_LINK_MODE_MASK_NBITS);
71 }
72 
linkmode_and(unsigned long * dst,const unsigned long * a,const unsigned long * b)73 static inline void linkmode_and(unsigned long *dst, const unsigned long *a,
74 				const unsigned long *b)
75 {
76 	bitmap_and(dst, a, b, __ETHTOOL_LINK_MODE_MASK_NBITS);
77 }
78 
linkmode_or(unsigned long * dst,const unsigned long * a,const unsigned long * b)79 static inline void linkmode_or(unsigned long *dst, const unsigned long *a,
80 				const unsigned long *b)
81 {
82 	bitmap_or(dst, a, b, __ETHTOOL_LINK_MODE_MASK_NBITS);
83 }
84 
linkmode_empty(const unsigned long * src)85 static inline bool linkmode_empty(const unsigned long *src)
86 {
87 	return bitmap_empty(src, __ETHTOOL_LINK_MODE_MASK_NBITS);
88 }
89 
phylink_set_port_modes(unsigned long * mask)90 void phylink_set_port_modes(unsigned long *mask)
91 {
92 	phylink_set(mask, TP);
93 	phylink_set(mask, AUI);
94 	phylink_set(mask, MII);
95 	phylink_set(mask, FIBRE);
96 	phylink_set(mask, BNC);
97 	phylink_set(mask, Backplane);
98 }
99 EXPORT_SYMBOL_GPL(phylink_set_port_modes);
100 
phylink_is_empty_linkmode(const unsigned long * linkmode)101 static int phylink_is_empty_linkmode(const unsigned long *linkmode)
102 {
103 	__ETHTOOL_DECLARE_LINK_MODE_MASK(tmp) = { 0, };
104 
105 	phylink_set_port_modes(tmp);
106 	phylink_set(tmp, Autoneg);
107 	phylink_set(tmp, Pause);
108 	phylink_set(tmp, Asym_Pause);
109 
110 	bitmap_andnot(tmp, linkmode, tmp, __ETHTOOL_LINK_MODE_MASK_NBITS);
111 
112 	return linkmode_empty(tmp);
113 }
114 
phylink_an_mode_str(unsigned int mode)115 static const char *phylink_an_mode_str(unsigned int mode)
116 {
117 	static const char *modestr[] = {
118 		[MLO_AN_PHY] = "phy",
119 		[MLO_AN_FIXED] = "fixed",
120 		[MLO_AN_SGMII] = "SGMII",
121 		[MLO_AN_8023Z] = "802.3z",
122 	};
123 
124 	return mode < ARRAY_SIZE(modestr) ? modestr[mode] : "unknown";
125 }
126 
phylink_validate(struct phylink * pl,unsigned long * supported,struct phylink_link_state * state)127 static int phylink_validate(struct phylink *pl, unsigned long *supported,
128 			    struct phylink_link_state *state)
129 {
130 	pl->ops->validate(pl->netdev, supported, state);
131 
132 	return phylink_is_empty_linkmode(supported) ? -EINVAL : 0;
133 }
134 
phylink_parse_fixedlink(struct phylink * pl,struct device_node * np)135 static int phylink_parse_fixedlink(struct phylink *pl, struct device_node *np)
136 {
137 	struct device_node *fixed_node;
138 	const struct phy_setting *s;
139 	struct gpio_desc *desc;
140 	const __be32 *fixed_prop;
141 	u32 speed;
142 	int ret, len;
143 
144 	fixed_node = of_get_child_by_name(np, "fixed-link");
145 	if (fixed_node) {
146 		ret = of_property_read_u32(fixed_node, "speed", &speed);
147 
148 		pl->link_config.speed = speed;
149 		pl->link_config.duplex = DUPLEX_HALF;
150 
151 		if (of_property_read_bool(fixed_node, "full-duplex"))
152 			pl->link_config.duplex = DUPLEX_FULL;
153 
154 		/* We treat the "pause" and "asym-pause" terminology as
155 		 * defining the link partner's ability. */
156 		if (of_property_read_bool(fixed_node, "pause"))
157 			pl->link_config.pause |= MLO_PAUSE_SYM;
158 		if (of_property_read_bool(fixed_node, "asym-pause"))
159 			pl->link_config.pause |= MLO_PAUSE_ASYM;
160 
161 		if (ret == 0) {
162 			desc = fwnode_get_named_gpiod(&fixed_node->fwnode,
163 						      "link-gpios", 0,
164 						      GPIOD_IN, "?");
165 
166 			if (!IS_ERR(desc))
167 				pl->link_gpio = desc;
168 			else if (desc == ERR_PTR(-EPROBE_DEFER))
169 				ret = -EPROBE_DEFER;
170 		}
171 		of_node_put(fixed_node);
172 
173 		if (ret)
174 			return ret;
175 	} else {
176 		fixed_prop = of_get_property(np, "fixed-link", &len);
177 		if (!fixed_prop) {
178 			netdev_err(pl->netdev, "broken fixed-link?\n");
179 			return -EINVAL;
180 		}
181 		if (len == 5 * sizeof(*fixed_prop)) {
182 			pl->link_config.duplex = be32_to_cpu(fixed_prop[1]) ?
183 						DUPLEX_FULL : DUPLEX_HALF;
184 			pl->link_config.speed = be32_to_cpu(fixed_prop[2]);
185 			if (be32_to_cpu(fixed_prop[3]))
186 				pl->link_config.pause |= MLO_PAUSE_SYM;
187 			if (be32_to_cpu(fixed_prop[4]))
188 				pl->link_config.pause |= MLO_PAUSE_ASYM;
189 		}
190 	}
191 
192 	if (pl->link_config.speed > SPEED_1000 &&
193 	    pl->link_config.duplex != DUPLEX_FULL)
194 		netdev_warn(pl->netdev, "fixed link specifies half duplex for %dMbps link?\n",
195 			    pl->link_config.speed);
196 
197 	bitmap_fill(pl->supported, __ETHTOOL_LINK_MODE_MASK_NBITS);
198 	linkmode_copy(pl->link_config.advertising, pl->supported);
199 	phylink_validate(pl, pl->supported, &pl->link_config);
200 
201 	s = phy_lookup_setting(pl->link_config.speed, pl->link_config.duplex,
202 			       pl->supported,
203 			       __ETHTOOL_LINK_MODE_MASK_NBITS, true);
204 	linkmode_zero(pl->supported);
205 	phylink_set(pl->supported, MII);
206 	phylink_set(pl->supported, Pause);
207 	phylink_set(pl->supported, Asym_Pause);
208 	if (s) {
209 		__set_bit(s->bit, pl->supported);
210 	} else {
211 		netdev_warn(pl->netdev, "fixed link %s duplex %dMbps not recognised\n",
212 			    pl->link_config.duplex == DUPLEX_FULL ? "full" : "half",
213 			    pl->link_config.speed);
214 	}
215 
216 	linkmode_and(pl->link_config.advertising, pl->link_config.advertising,
217 		     pl->supported);
218 
219 	pl->link_config.link = 1;
220 	pl->link_config.an_complete = 1;
221 
222 	return 0;
223 }
224 
phylink_parse_mode(struct phylink * pl,struct device_node * np)225 static int phylink_parse_mode(struct phylink *pl, struct device_node *np)
226 {
227 	struct device_node *dn;
228 	const char *managed;
229 
230 	dn = of_get_child_by_name(np, "fixed-link");
231 	if (dn || of_find_property(np, "fixed-link", NULL))
232 		pl->link_an_mode = MLO_AN_FIXED;
233 	of_node_put(dn);
234 
235 	if (of_property_read_string(np, "managed", &managed) == 0 &&
236 	    strcmp(managed, "in-band-status") == 0) {
237 		if (pl->link_an_mode == MLO_AN_FIXED) {
238 			netdev_err(pl->netdev,
239 				   "can't use both fixed-link and in-band-status\n");
240 			return -EINVAL;
241 		}
242 
243 		linkmode_zero(pl->supported);
244 		phylink_set(pl->supported, MII);
245 		phylink_set(pl->supported, Autoneg);
246 		phylink_set(pl->supported, Asym_Pause);
247 		phylink_set(pl->supported, Pause);
248 		pl->link_config.an_enabled = true;
249 
250 		switch (pl->link_config.interface) {
251 		case PHY_INTERFACE_MODE_SGMII:
252 			phylink_set(pl->supported, 10baseT_Half);
253 			phylink_set(pl->supported, 10baseT_Full);
254 			phylink_set(pl->supported, 100baseT_Half);
255 			phylink_set(pl->supported, 100baseT_Full);
256 			phylink_set(pl->supported, 1000baseT_Half);
257 			phylink_set(pl->supported, 1000baseT_Full);
258 			pl->link_an_mode = MLO_AN_SGMII;
259 			break;
260 
261 		case PHY_INTERFACE_MODE_1000BASEX:
262 			phylink_set(pl->supported, 1000baseX_Full);
263 			pl->link_an_mode = MLO_AN_8023Z;
264 			break;
265 
266 		case PHY_INTERFACE_MODE_2500BASEX:
267 			phylink_set(pl->supported, 2500baseX_Full);
268 			pl->link_an_mode = MLO_AN_8023Z;
269 			break;
270 
271 		case PHY_INTERFACE_MODE_10GKR:
272 			phylink_set(pl->supported, 10baseT_Half);
273 			phylink_set(pl->supported, 10baseT_Full);
274 			phylink_set(pl->supported, 100baseT_Half);
275 			phylink_set(pl->supported, 100baseT_Full);
276 			phylink_set(pl->supported, 1000baseT_Half);
277 			phylink_set(pl->supported, 1000baseT_Full);
278 			phylink_set(pl->supported, 1000baseX_Full);
279 			phylink_set(pl->supported, 10000baseKR_Full);
280 			phylink_set(pl->supported, 10000baseCR_Full);
281 			phylink_set(pl->supported, 10000baseSR_Full);
282 			phylink_set(pl->supported, 10000baseLR_Full);
283 			phylink_set(pl->supported, 10000baseLRM_Full);
284 			phylink_set(pl->supported, 10000baseER_Full);
285 			pl->link_an_mode = MLO_AN_SGMII;
286 			break;
287 
288 		default:
289 			netdev_err(pl->netdev,
290 				   "incorrect link mode %s for in-band status\n",
291 				   phy_modes(pl->link_config.interface));
292 			return -EINVAL;
293 		}
294 
295 		linkmode_copy(pl->link_config.advertising, pl->supported);
296 
297 		if (phylink_validate(pl, pl->supported, &pl->link_config)) {
298 			netdev_err(pl->netdev,
299 				   "failed to validate link configuration for in-band status\n");
300 			return -EINVAL;
301 		}
302 	}
303 
304 	return 0;
305 }
306 
phylink_mac_config(struct phylink * pl,const struct phylink_link_state * state)307 static void phylink_mac_config(struct phylink *pl,
308 			       const struct phylink_link_state *state)
309 {
310 	netdev_dbg(pl->netdev,
311 		   "%s: mode=%s/%s/%s/%s adv=%*pb pause=%02x link=%u an=%u\n",
312 		   __func__, phylink_an_mode_str(pl->link_an_mode),
313 		   phy_modes(state->interface),
314 		   phy_speed_to_str(state->speed),
315 		   phy_duplex_to_str(state->duplex),
316 		   __ETHTOOL_LINK_MODE_MASK_NBITS, state->advertising,
317 		   state->pause, state->link, state->an_enabled);
318 
319 	pl->ops->mac_config(pl->netdev, pl->link_an_mode, state);
320 }
321 
phylink_mac_an_restart(struct phylink * pl)322 static void phylink_mac_an_restart(struct phylink *pl)
323 {
324 	if (pl->link_config.an_enabled &&
325 	    (pl->link_config.interface == PHY_INTERFACE_MODE_1000BASEX ||
326 	     pl->link_config.interface == PHY_INTERFACE_MODE_2500BASEX))
327 		pl->ops->mac_an_restart(pl->netdev);
328 }
329 
phylink_get_mac_state(struct phylink * pl,struct phylink_link_state * state)330 static int phylink_get_mac_state(struct phylink *pl, struct phylink_link_state *state)
331 {
332 	struct net_device *ndev = pl->netdev;
333 
334 	linkmode_copy(state->advertising, pl->link_config.advertising);
335 	linkmode_zero(state->lp_advertising);
336 	state->interface = pl->link_config.interface;
337 	state->an_enabled = pl->link_config.an_enabled;
338 	state->speed = SPEED_UNKNOWN;
339 	state->duplex = DUPLEX_UNKNOWN;
340 	state->pause = MLO_PAUSE_NONE;
341 	state->an_complete = 0;
342 	state->link = 1;
343 
344 	return pl->ops->mac_link_state(ndev, state);
345 }
346 
347 /* The fixed state is... fixed except for the link state,
348  * which may be determined by a GPIO.
349  */
phylink_get_fixed_state(struct phylink * pl,struct phylink_link_state * state)350 static void phylink_get_fixed_state(struct phylink *pl, struct phylink_link_state *state)
351 {
352 	*state = pl->link_config;
353 	if (pl->link_gpio)
354 		state->link = !!gpiod_get_value(pl->link_gpio);
355 }
356 
357 /* Flow control is resolved according to our and the link partners
358  * advertisments using the following drawn from the 802.3 specs:
359  *  Local device  Link partner
360  *  Pause AsymDir Pause AsymDir Result
361  *    1     X       1     X     TX+RX
362  *    0     1       1     1     TX
363  *    1     1       0     1     RX
364  */
phylink_resolve_flow(struct phylink * pl,struct phylink_link_state * state)365 static void phylink_resolve_flow(struct phylink *pl,
366 	struct phylink_link_state *state)
367 {
368 	int new_pause = 0;
369 
370 	if (pl->link_config.pause & MLO_PAUSE_AN) {
371 		int pause = 0;
372 
373 		if (phylink_test(pl->link_config.advertising, Pause))
374 			pause |= MLO_PAUSE_SYM;
375 		if (phylink_test(pl->link_config.advertising, Asym_Pause))
376 			pause |= MLO_PAUSE_ASYM;
377 
378 		pause &= state->pause;
379 
380 		if (pause & MLO_PAUSE_SYM)
381 			new_pause = MLO_PAUSE_TX | MLO_PAUSE_RX;
382 		else if (pause & MLO_PAUSE_ASYM)
383 			new_pause = state->pause & MLO_PAUSE_SYM ?
384 				 MLO_PAUSE_TX : MLO_PAUSE_RX;
385 	} else {
386 		new_pause = pl->link_config.pause & MLO_PAUSE_TXRX_MASK;
387 	}
388 
389 	state->pause &= ~MLO_PAUSE_TXRX_MASK;
390 	state->pause |= new_pause;
391 }
392 
phylink_pause_to_str(int pause)393 static const char *phylink_pause_to_str(int pause)
394 {
395 	switch (pause & MLO_PAUSE_TXRX_MASK) {
396 	case MLO_PAUSE_TX | MLO_PAUSE_RX:
397 		return "rx/tx";
398 	case MLO_PAUSE_TX:
399 		return "tx";
400 	case MLO_PAUSE_RX:
401 		return "rx";
402 	default:
403 		return "off";
404 	}
405 }
406 
phylink_resolve(struct work_struct * w)407 static void phylink_resolve(struct work_struct *w)
408 {
409 	struct phylink *pl = container_of(w, struct phylink, resolve);
410 	struct phylink_link_state link_state;
411 	struct net_device *ndev = pl->netdev;
412 
413 	mutex_lock(&pl->state_mutex);
414 	if (pl->phylink_disable_state) {
415 		pl->mac_link_dropped = false;
416 		link_state.link = false;
417 	} else if (pl->mac_link_dropped) {
418 		link_state.link = false;
419 	} else {
420 		switch (pl->link_an_mode) {
421 		case MLO_AN_PHY:
422 			link_state = pl->phy_state;
423 			phylink_resolve_flow(pl, &link_state);
424 			phylink_mac_config(pl, &link_state);
425 			break;
426 
427 		case MLO_AN_FIXED:
428 			phylink_get_fixed_state(pl, &link_state);
429 			phylink_mac_config(pl, &link_state);
430 			break;
431 
432 		case MLO_AN_SGMII:
433 			phylink_get_mac_state(pl, &link_state);
434 			if (pl->phydev) {
435 				bool changed = false;
436 
437 				link_state.link = link_state.link &&
438 						  pl->phy_state.link;
439 
440 				if (pl->phy_state.interface !=
441 				    link_state.interface) {
442 					link_state.interface = pl->phy_state.interface;
443 					changed = true;
444 				}
445 
446 				/* Propagate the flow control from the PHY
447 				 * to the MAC. Also propagate the interface
448 				 * if changed.
449 				 */
450 				if (pl->phy_state.link || changed) {
451 					link_state.pause |= pl->phy_state.pause;
452 					phylink_resolve_flow(pl, &link_state);
453 
454 					phylink_mac_config(pl, &link_state);
455 				}
456 			}
457 			break;
458 
459 		case MLO_AN_8023Z:
460 			phylink_get_mac_state(pl, &link_state);
461 			break;
462 		}
463 	}
464 
465 	if (link_state.link != netif_carrier_ok(ndev)) {
466 		if (!link_state.link) {
467 			netif_carrier_off(ndev);
468 			pl->ops->mac_link_down(ndev, pl->link_an_mode);
469 			netdev_info(ndev, "Link is Down\n");
470 		} else {
471 			pl->ops->mac_link_up(ndev, pl->link_an_mode,
472 					     pl->phydev);
473 
474 			netif_carrier_on(ndev);
475 
476 			netdev_info(ndev,
477 				    "Link is Up - %s/%s - flow control %s\n",
478 				    phy_speed_to_str(link_state.speed),
479 				    phy_duplex_to_str(link_state.duplex),
480 				    phylink_pause_to_str(link_state.pause));
481 		}
482 	}
483 	if (!link_state.link && pl->mac_link_dropped) {
484 		pl->mac_link_dropped = false;
485 		queue_work(system_power_efficient_wq, &pl->resolve);
486 	}
487 	mutex_unlock(&pl->state_mutex);
488 }
489 
phylink_run_resolve(struct phylink * pl)490 static void phylink_run_resolve(struct phylink *pl)
491 {
492 	if (!pl->phylink_disable_state)
493 		queue_work(system_power_efficient_wq, &pl->resolve);
494 }
495 
phylink_run_resolve_and_disable(struct phylink * pl,int bit)496 static void phylink_run_resolve_and_disable(struct phylink *pl, int bit)
497 {
498 	unsigned long state = pl->phylink_disable_state;
499 
500 	set_bit(bit, &pl->phylink_disable_state);
501 	if (state == 0) {
502 		queue_work(system_power_efficient_wq, &pl->resolve);
503 		flush_work(&pl->resolve);
504 	}
505 }
506 
507 static const struct sfp_upstream_ops sfp_phylink_ops;
508 
phylink_register_sfp(struct phylink * pl,struct device_node * np)509 static int phylink_register_sfp(struct phylink *pl, struct device_node *np)
510 {
511 	struct device_node *sfp_np;
512 
513 	sfp_np = of_parse_phandle(np, "sfp", 0);
514 	if (!sfp_np)
515 		return 0;
516 
517 	pl->sfp_bus = sfp_register_upstream(sfp_np, pl->netdev, pl,
518 					    &sfp_phylink_ops);
519 	if (!pl->sfp_bus)
520 		return -ENOMEM;
521 
522 	return 0;
523 }
524 
phylink_create(struct net_device * ndev,struct device_node * np,phy_interface_t iface,const struct phylink_mac_ops * ops)525 struct phylink *phylink_create(struct net_device *ndev, struct device_node *np,
526 	phy_interface_t iface, const struct phylink_mac_ops *ops)
527 {
528 	struct phylink *pl;
529 	int ret;
530 
531 	pl = kzalloc(sizeof(*pl), GFP_KERNEL);
532 	if (!pl)
533 		return ERR_PTR(-ENOMEM);
534 
535 	mutex_init(&pl->state_mutex);
536 	INIT_WORK(&pl->resolve, phylink_resolve);
537 	pl->netdev = ndev;
538 	pl->phy_state.interface = iface;
539 	pl->link_interface = iface;
540 	pl->link_port = PORT_MII;
541 	pl->link_config.interface = iface;
542 	pl->link_config.pause = MLO_PAUSE_AN;
543 	pl->link_config.speed = SPEED_UNKNOWN;
544 	pl->link_config.duplex = DUPLEX_UNKNOWN;
545 	pl->link_config.an_enabled = true;
546 	pl->ops = ops;
547 	__set_bit(PHYLINK_DISABLE_STOPPED, &pl->phylink_disable_state);
548 
549 	bitmap_fill(pl->supported, __ETHTOOL_LINK_MODE_MASK_NBITS);
550 	linkmode_copy(pl->link_config.advertising, pl->supported);
551 	phylink_validate(pl, pl->supported, &pl->link_config);
552 
553 	ret = phylink_parse_mode(pl, np);
554 	if (ret < 0) {
555 		kfree(pl);
556 		return ERR_PTR(ret);
557 	}
558 
559 	if (pl->link_an_mode == MLO_AN_FIXED) {
560 		ret = phylink_parse_fixedlink(pl, np);
561 		if (ret < 0) {
562 			kfree(pl);
563 			return ERR_PTR(ret);
564 		}
565 	}
566 
567 	ret = phylink_register_sfp(pl, np);
568 	if (ret < 0) {
569 		kfree(pl);
570 		return ERR_PTR(ret);
571 	}
572 
573 	return pl;
574 }
575 EXPORT_SYMBOL_GPL(phylink_create);
576 
phylink_destroy(struct phylink * pl)577 void phylink_destroy(struct phylink *pl)
578 {
579 	if (pl->sfp_bus)
580 		sfp_unregister_upstream(pl->sfp_bus);
581 	if (!IS_ERR_OR_NULL(pl->link_gpio))
582 		gpiod_put(pl->link_gpio);
583 
584 	cancel_work_sync(&pl->resolve);
585 	kfree(pl);
586 }
587 EXPORT_SYMBOL_GPL(phylink_destroy);
588 
phylink_phy_change(struct phy_device * phydev,bool up,bool do_carrier)589 void phylink_phy_change(struct phy_device *phydev, bool up, bool do_carrier)
590 {
591 	struct phylink *pl = phydev->phylink;
592 
593 	mutex_lock(&pl->state_mutex);
594 	pl->phy_state.speed = phydev->speed;
595 	pl->phy_state.duplex = phydev->duplex;
596 	pl->phy_state.pause = MLO_PAUSE_NONE;
597 	if (phydev->pause)
598 		pl->phy_state.pause |= MLO_PAUSE_SYM;
599 	if (phydev->asym_pause)
600 		pl->phy_state.pause |= MLO_PAUSE_ASYM;
601 	pl->phy_state.interface = phydev->interface;
602 	pl->phy_state.link = up;
603 	mutex_unlock(&pl->state_mutex);
604 
605 	phylink_run_resolve(pl);
606 
607 	netdev_dbg(pl->netdev, "phy link %s %s/%s/%s\n", up ? "up" : "down",
608 	           phy_modes(phydev->interface),
609 		   phy_speed_to_str(phydev->speed),
610 		   phy_duplex_to_str(phydev->duplex));
611 }
612 
phylink_bringup_phy(struct phylink * pl,struct phy_device * phy)613 static int phylink_bringup_phy(struct phylink *pl, struct phy_device *phy)
614 {
615 	struct phylink_link_state config;
616 	__ETHTOOL_DECLARE_LINK_MODE_MASK(supported);
617 	u32 advertising;
618 	int ret;
619 
620 	memset(&config, 0, sizeof(config));
621 	ethtool_convert_legacy_u32_to_link_mode(supported, phy->supported);
622 	ethtool_convert_legacy_u32_to_link_mode(config.advertising,
623 						phy->advertising);
624 	config.interface = pl->link_config.interface;
625 
626 	/*
627 	 * This is the new way of dealing with flow control for PHYs,
628 	 * as described by Timur Tabi in commit 529ed1275263 ("net: phy:
629 	 * phy drivers should not set SUPPORTED_[Asym_]Pause") except
630 	 * using our validate call to the MAC, we rely upon the MAC
631 	 * clearing the bits from both supported and advertising fields.
632 	 */
633 	if (phylink_test(supported, Pause))
634 		phylink_set(config.advertising, Pause);
635 	if (phylink_test(supported, Asym_Pause))
636 		phylink_set(config.advertising, Asym_Pause);
637 
638 	ret = phylink_validate(pl, supported, &config);
639 	if (ret)
640 		return ret;
641 
642 	phy->phylink = pl;
643 	phy->phy_link_change = phylink_phy_change;
644 
645 	netdev_info(pl->netdev,
646 		    "PHY [%s] driver [%s]\n", dev_name(&phy->mdio.dev),
647 		    phy->drv->name);
648 
649 	mutex_lock(&phy->lock);
650 	mutex_lock(&pl->state_mutex);
651 	pl->netdev->phydev = phy;
652 	pl->phydev = phy;
653 	linkmode_copy(pl->supported, supported);
654 	linkmode_copy(pl->link_config.advertising, config.advertising);
655 
656 	/* Restrict the phy advertisment according to the MAC support. */
657 	ethtool_convert_link_mode_to_legacy_u32(&advertising, config.advertising);
658 	phy->advertising = advertising;
659 	mutex_unlock(&pl->state_mutex);
660 	mutex_unlock(&phy->lock);
661 
662 	netdev_dbg(pl->netdev,
663 		   "phy: setting supported %*pb advertising 0x%08x\n",
664 		   __ETHTOOL_LINK_MODE_MASK_NBITS, pl->supported,
665 		   phy->advertising);
666 
667 	phy_start_machine(phy);
668 	if (phy->irq > 0)
669 		phy_start_interrupts(phy);
670 
671 	return 0;
672 }
673 
phylink_connect_phy(struct phylink * pl,struct phy_device * phy)674 int phylink_connect_phy(struct phylink *pl, struct phy_device *phy)
675 {
676 	int ret;
677 
678 	ret = phy_attach_direct(pl->netdev, phy, 0, pl->link_interface);
679 	if (ret)
680 		return ret;
681 
682 	ret = phylink_bringup_phy(pl, phy);
683 	if (ret)
684 		phy_detach(phy);
685 
686 	return ret;
687 }
688 EXPORT_SYMBOL_GPL(phylink_connect_phy);
689 
phylink_of_phy_connect(struct phylink * pl,struct device_node * dn)690 int phylink_of_phy_connect(struct phylink *pl, struct device_node *dn)
691 {
692 	struct device_node *phy_node;
693 	struct phy_device *phy_dev;
694 	int ret;
695 
696 	/* Fixed links are handled without needing a PHY */
697 	if (pl->link_an_mode == MLO_AN_FIXED)
698 		return 0;
699 
700 	phy_node = of_parse_phandle(dn, "phy-handle", 0);
701 	if (!phy_node)
702 		phy_node = of_parse_phandle(dn, "phy", 0);
703 	if (!phy_node)
704 		phy_node = of_parse_phandle(dn, "phy-device", 0);
705 
706 	if (!phy_node) {
707 		if (pl->link_an_mode == MLO_AN_PHY) {
708 			netdev_err(pl->netdev, "unable to find PHY node\n");
709 			return -ENODEV;
710 		}
711 		return 0;
712 	}
713 
714 	phy_dev = of_phy_attach(pl->netdev, phy_node, 0, pl->link_interface);
715 	/* We're done with the phy_node handle */
716 	of_node_put(phy_node);
717 
718 	if (!phy_dev)
719 		return -ENODEV;
720 
721 	ret = phylink_bringup_phy(pl, phy_dev);
722 	if (ret)
723 		phy_detach(phy_dev);
724 
725 	return ret;
726 }
727 EXPORT_SYMBOL_GPL(phylink_of_phy_connect);
728 
phylink_disconnect_phy(struct phylink * pl)729 void phylink_disconnect_phy(struct phylink *pl)
730 {
731 	struct phy_device *phy;
732 
733 	WARN_ON(!lockdep_rtnl_is_held());
734 
735 	phy = pl->phydev;
736 	if (phy) {
737 		mutex_lock(&phy->lock);
738 		mutex_lock(&pl->state_mutex);
739 		pl->netdev->phydev = NULL;
740 		pl->phydev = NULL;
741 		mutex_unlock(&pl->state_mutex);
742 		mutex_unlock(&phy->lock);
743 		flush_work(&pl->resolve);
744 
745 		phy_disconnect(phy);
746 	}
747 }
748 EXPORT_SYMBOL_GPL(phylink_disconnect_phy);
749 
phylink_mac_change(struct phylink * pl,bool up)750 void phylink_mac_change(struct phylink *pl, bool up)
751 {
752 	if (!up)
753 		pl->mac_link_dropped = true;
754 	phylink_run_resolve(pl);
755 	netdev_dbg(pl->netdev, "mac link %s\n", up ? "up" : "down");
756 }
757 EXPORT_SYMBOL_GPL(phylink_mac_change);
758 
phylink_start(struct phylink * pl)759 void phylink_start(struct phylink *pl)
760 {
761 	WARN_ON(!lockdep_rtnl_is_held());
762 
763 	netdev_info(pl->netdev, "configuring for %s/%s link mode\n",
764 		    phylink_an_mode_str(pl->link_an_mode),
765 		    phy_modes(pl->link_config.interface));
766 
767 	/* Always set the carrier off */
768 	netif_carrier_off(pl->netdev);
769 
770 	/* Apply the link configuration to the MAC when starting. This allows
771 	 * a fixed-link to start with the correct parameters, and also
772 	 * ensures that we set the appropriate advertisment for Serdes links.
773 	 */
774 	phylink_resolve_flow(pl, &pl->link_config);
775 	phylink_mac_config(pl, &pl->link_config);
776 
777 	clear_bit(PHYLINK_DISABLE_STOPPED, &pl->phylink_disable_state);
778 	phylink_run_resolve(pl);
779 
780 	if (pl->sfp_bus)
781 		sfp_upstream_start(pl->sfp_bus);
782 	if (pl->phydev)
783 		phy_start(pl->phydev);
784 }
785 EXPORT_SYMBOL_GPL(phylink_start);
786 
phylink_stop(struct phylink * pl)787 void phylink_stop(struct phylink *pl)
788 {
789 	WARN_ON(!lockdep_rtnl_is_held());
790 
791 	if (pl->phydev)
792 		phy_stop(pl->phydev);
793 	if (pl->sfp_bus)
794 		sfp_upstream_stop(pl->sfp_bus);
795 
796 	phylink_run_resolve_and_disable(pl, PHYLINK_DISABLE_STOPPED);
797 }
798 EXPORT_SYMBOL_GPL(phylink_stop);
799 
phylink_ethtool_get_wol(struct phylink * pl,struct ethtool_wolinfo * wol)800 void phylink_ethtool_get_wol(struct phylink *pl, struct ethtool_wolinfo *wol)
801 {
802 	WARN_ON(!lockdep_rtnl_is_held());
803 
804 	wol->supported = 0;
805 	wol->wolopts = 0;
806 
807 	if (pl->phydev)
808 		phy_ethtool_get_wol(pl->phydev, wol);
809 }
810 EXPORT_SYMBOL_GPL(phylink_ethtool_get_wol);
811 
phylink_ethtool_set_wol(struct phylink * pl,struct ethtool_wolinfo * wol)812 int phylink_ethtool_set_wol(struct phylink *pl, struct ethtool_wolinfo *wol)
813 {
814 	int ret = -EOPNOTSUPP;
815 
816 	WARN_ON(!lockdep_rtnl_is_held());
817 
818 	if (pl->phydev)
819 		ret = phy_ethtool_set_wol(pl->phydev, wol);
820 
821 	return ret;
822 }
823 EXPORT_SYMBOL_GPL(phylink_ethtool_set_wol);
824 
phylink_merge_link_mode(unsigned long * dst,const unsigned long * b)825 static void phylink_merge_link_mode(unsigned long *dst, const unsigned long *b)
826 {
827 	__ETHTOOL_DECLARE_LINK_MODE_MASK(mask);
828 
829 	linkmode_zero(mask);
830 	phylink_set_port_modes(mask);
831 
832 	linkmode_and(dst, dst, mask);
833 	linkmode_or(dst, dst, b);
834 }
835 
phylink_get_ksettings(const struct phylink_link_state * state,struct ethtool_link_ksettings * kset)836 static void phylink_get_ksettings(const struct phylink_link_state *state,
837 				  struct ethtool_link_ksettings *kset)
838 {
839 	phylink_merge_link_mode(kset->link_modes.advertising, state->advertising);
840 	linkmode_copy(kset->link_modes.lp_advertising, state->lp_advertising);
841 	kset->base.speed = state->speed;
842 	kset->base.duplex = state->duplex;
843 	kset->base.autoneg = state->an_enabled ? AUTONEG_ENABLE :
844 				AUTONEG_DISABLE;
845 }
846 
phylink_ethtool_ksettings_get(struct phylink * pl,struct ethtool_link_ksettings * kset)847 int phylink_ethtool_ksettings_get(struct phylink *pl,
848 	struct ethtool_link_ksettings *kset)
849 {
850 	struct phylink_link_state link_state;
851 
852 	WARN_ON(!lockdep_rtnl_is_held());
853 
854 	if (pl->phydev) {
855 		phy_ethtool_ksettings_get(pl->phydev, kset);
856 	} else {
857 		kset->base.port = pl->link_port;
858 	}
859 
860 	linkmode_copy(kset->link_modes.supported, pl->supported);
861 
862 	switch (pl->link_an_mode) {
863 	case MLO_AN_FIXED:
864 		/* We are using fixed settings. Report these as the
865 		 * current link settings - and note that these also
866 		 * represent the supported speeds/duplex/pause modes.
867 		 */
868 		phylink_get_fixed_state(pl, &link_state);
869 		phylink_get_ksettings(&link_state, kset);
870 		break;
871 
872 	case MLO_AN_SGMII:
873 		/* If there is a phy attached, then use the reported
874 		 * settings from the phy with no modification.
875 		 */
876 		if (pl->phydev)
877 			break;
878 
879 	case MLO_AN_8023Z:
880 		phylink_get_mac_state(pl, &link_state);
881 
882 		/* The MAC is reporting the link results from its own PCS
883 		 * layer via in-band status. Report these as the current
884 		 * link settings.
885 		 */
886 		phylink_get_ksettings(&link_state, kset);
887 		break;
888 	}
889 
890 	return 0;
891 }
892 EXPORT_SYMBOL_GPL(phylink_ethtool_ksettings_get);
893 
phylink_ethtool_ksettings_set(struct phylink * pl,const struct ethtool_link_ksettings * kset)894 int phylink_ethtool_ksettings_set(struct phylink *pl,
895 	const struct ethtool_link_ksettings *kset)
896 {
897 	struct ethtool_link_ksettings our_kset;
898 	struct phylink_link_state config;
899 	int ret;
900 
901 	WARN_ON(!lockdep_rtnl_is_held());
902 
903 	if (kset->base.autoneg != AUTONEG_DISABLE &&
904 	    kset->base.autoneg != AUTONEG_ENABLE)
905 		return -EINVAL;
906 
907 	config = pl->link_config;
908 
909 	/* Mask out unsupported advertisments */
910 	linkmode_and(config.advertising, kset->link_modes.advertising,
911 		     pl->supported);
912 
913 	/* FIXME: should we reject autoneg if phy/mac does not support it? */
914 	if (kset->base.autoneg == AUTONEG_DISABLE) {
915 		const struct phy_setting *s;
916 
917 		/* Autonegotiation disabled, select a suitable speed and
918 		 * duplex.
919 		 */
920 		s = phy_lookup_setting(kset->base.speed, kset->base.duplex,
921 				       pl->supported,
922 				       __ETHTOOL_LINK_MODE_MASK_NBITS, false);
923 		if (!s)
924 			return -EINVAL;
925 
926 		/* If we have a fixed link (as specified by firmware), refuse
927 		 * to change link parameters.
928 		 */
929 		if (pl->link_an_mode == MLO_AN_FIXED &&
930 		    (s->speed != pl->link_config.speed ||
931 		     s->duplex != pl->link_config.duplex))
932 			return -EINVAL;
933 
934 		config.speed = s->speed;
935 		config.duplex = s->duplex;
936 		config.an_enabled = false;
937 
938 		__clear_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, config.advertising);
939 	} else {
940 		/* If we have a fixed link, refuse to enable autonegotiation */
941 		if (pl->link_an_mode == MLO_AN_FIXED)
942 			return -EINVAL;
943 
944 		config.speed = SPEED_UNKNOWN;
945 		config.duplex = DUPLEX_UNKNOWN;
946 		config.an_enabled = true;
947 
948 		__set_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, config.advertising);
949 	}
950 
951 	if (phylink_validate(pl, pl->supported, &config))
952 		return -EINVAL;
953 
954 	/* If autonegotiation is enabled, we must have an advertisment */
955 	if (config.an_enabled && phylink_is_empty_linkmode(config.advertising))
956 		return -EINVAL;
957 
958 	our_kset = *kset;
959 	linkmode_copy(our_kset.link_modes.advertising, config.advertising);
960 	our_kset.base.speed = config.speed;
961 	our_kset.base.duplex = config.duplex;
962 
963 	/* If we have a PHY, configure the phy */
964 	if (pl->phydev) {
965 		ret = phy_ethtool_ksettings_set(pl->phydev, &our_kset);
966 		if (ret)
967 			return ret;
968 	}
969 
970 	mutex_lock(&pl->state_mutex);
971 	/* Configure the MAC to match the new settings */
972 	linkmode_copy(pl->link_config.advertising, our_kset.link_modes.advertising);
973 	pl->link_config.interface = config.interface;
974 	pl->link_config.speed = our_kset.base.speed;
975 	pl->link_config.duplex = our_kset.base.duplex;
976 	pl->link_config.an_enabled = our_kset.base.autoneg != AUTONEG_DISABLE;
977 
978 	if (!test_bit(PHYLINK_DISABLE_STOPPED, &pl->phylink_disable_state)) {
979 		phylink_mac_config(pl, &pl->link_config);
980 		phylink_mac_an_restart(pl);
981 	}
982 	mutex_unlock(&pl->state_mutex);
983 
984 	return 0;
985 }
986 EXPORT_SYMBOL_GPL(phylink_ethtool_ksettings_set);
987 
phylink_ethtool_nway_reset(struct phylink * pl)988 int phylink_ethtool_nway_reset(struct phylink *pl)
989 {
990 	int ret = 0;
991 
992 	WARN_ON(!lockdep_rtnl_is_held());
993 
994 	if (pl->phydev)
995 		ret = phy_restart_aneg(pl->phydev);
996 	phylink_mac_an_restart(pl);
997 
998 	return ret;
999 }
1000 EXPORT_SYMBOL_GPL(phylink_ethtool_nway_reset);
1001 
phylink_ethtool_get_pauseparam(struct phylink * pl,struct ethtool_pauseparam * pause)1002 void phylink_ethtool_get_pauseparam(struct phylink *pl,
1003 				    struct ethtool_pauseparam *pause)
1004 {
1005 	WARN_ON(!lockdep_rtnl_is_held());
1006 
1007 	pause->autoneg = !!(pl->link_config.pause & MLO_PAUSE_AN);
1008 	pause->rx_pause = !!(pl->link_config.pause & MLO_PAUSE_RX);
1009 	pause->tx_pause = !!(pl->link_config.pause & MLO_PAUSE_TX);
1010 }
1011 EXPORT_SYMBOL_GPL(phylink_ethtool_get_pauseparam);
1012 
phylink_ethtool_set_pauseparam(struct phylink * pl,struct ethtool_pauseparam * pause)1013 int phylink_ethtool_set_pauseparam(struct phylink *pl,
1014 				   struct ethtool_pauseparam *pause)
1015 {
1016 	struct phylink_link_state *config = &pl->link_config;
1017 
1018 	WARN_ON(!lockdep_rtnl_is_held());
1019 
1020 	if (!phylink_test(pl->supported, Pause) &&
1021 	    !phylink_test(pl->supported, Asym_Pause))
1022 		return -EOPNOTSUPP;
1023 
1024 	if (!phylink_test(pl->supported, Asym_Pause) &&
1025 	    !pause->autoneg && pause->rx_pause != pause->tx_pause)
1026 		return -EINVAL;
1027 
1028 	config->pause &= ~(MLO_PAUSE_AN | MLO_PAUSE_TXRX_MASK);
1029 
1030 	if (pause->autoneg)
1031 		config->pause |= MLO_PAUSE_AN;
1032 	if (pause->rx_pause)
1033 		config->pause |= MLO_PAUSE_RX;
1034 	if (pause->tx_pause)
1035 		config->pause |= MLO_PAUSE_TX;
1036 
1037 	if (!test_bit(PHYLINK_DISABLE_STOPPED, &pl->phylink_disable_state)) {
1038 		switch (pl->link_an_mode) {
1039 		case MLO_AN_PHY:
1040 			/* Silently mark the carrier down, and then trigger a resolve */
1041 			netif_carrier_off(pl->netdev);
1042 			phylink_run_resolve(pl);
1043 			break;
1044 
1045 		case MLO_AN_FIXED:
1046 			/* Should we allow fixed links to change against the config? */
1047 			phylink_resolve_flow(pl, config);
1048 			phylink_mac_config(pl, config);
1049 			break;
1050 
1051 		case MLO_AN_SGMII:
1052 		case MLO_AN_8023Z:
1053 			phylink_mac_config(pl, config);
1054 			phylink_mac_an_restart(pl);
1055 			break;
1056 		}
1057 	}
1058 
1059 	return 0;
1060 }
1061 EXPORT_SYMBOL_GPL(phylink_ethtool_set_pauseparam);
1062 
phylink_ethtool_get_module_info(struct phylink * pl,struct ethtool_modinfo * modinfo)1063 int phylink_ethtool_get_module_info(struct phylink *pl,
1064 				    struct ethtool_modinfo *modinfo)
1065 {
1066 	int ret = -EOPNOTSUPP;
1067 
1068 	WARN_ON(!lockdep_rtnl_is_held());
1069 
1070 	if (pl->sfp_bus)
1071 		ret = sfp_get_module_info(pl->sfp_bus, modinfo);
1072 
1073 	return ret;
1074 }
1075 EXPORT_SYMBOL_GPL(phylink_ethtool_get_module_info);
1076 
phylink_ethtool_get_module_eeprom(struct phylink * pl,struct ethtool_eeprom * ee,u8 * buf)1077 int phylink_ethtool_get_module_eeprom(struct phylink *pl,
1078 				      struct ethtool_eeprom *ee, u8 *buf)
1079 {
1080 	int ret = -EOPNOTSUPP;
1081 
1082 	WARN_ON(!lockdep_rtnl_is_held());
1083 
1084 	if (pl->sfp_bus)
1085 		ret = sfp_get_module_eeprom(pl->sfp_bus, ee, buf);
1086 
1087 	return ret;
1088 }
1089 EXPORT_SYMBOL_GPL(phylink_ethtool_get_module_eeprom);
1090 
phylink_init_eee(struct phylink * pl,bool clk_stop_enable)1091 int phylink_init_eee(struct phylink *pl, bool clk_stop_enable)
1092 {
1093 	int ret = -EPROTONOSUPPORT;
1094 
1095 	WARN_ON(!lockdep_rtnl_is_held());
1096 
1097 	if (pl->phydev)
1098 		ret = phy_init_eee(pl->phydev, clk_stop_enable);
1099 
1100 	return ret;
1101 }
1102 EXPORT_SYMBOL_GPL(phylink_init_eee);
1103 
phylink_get_eee_err(struct phylink * pl)1104 int phylink_get_eee_err(struct phylink *pl)
1105 {
1106 	int ret = 0;
1107 
1108 	WARN_ON(!lockdep_rtnl_is_held());
1109 
1110 	if (pl->phydev)
1111 		ret = phy_get_eee_err(pl->phydev);
1112 
1113 	return ret;
1114 }
1115 EXPORT_SYMBOL_GPL(phylink_get_eee_err);
1116 
phylink_ethtool_get_eee(struct phylink * pl,struct ethtool_eee * eee)1117 int phylink_ethtool_get_eee(struct phylink *pl, struct ethtool_eee *eee)
1118 {
1119 	int ret = -EOPNOTSUPP;
1120 
1121 	WARN_ON(!lockdep_rtnl_is_held());
1122 
1123 	if (pl->phydev)
1124 		ret = phy_ethtool_get_eee(pl->phydev, eee);
1125 
1126 	return ret;
1127 }
1128 EXPORT_SYMBOL_GPL(phylink_ethtool_get_eee);
1129 
phylink_ethtool_set_eee(struct phylink * pl,struct ethtool_eee * eee)1130 int phylink_ethtool_set_eee(struct phylink *pl, struct ethtool_eee *eee)
1131 {
1132 	int ret = -EOPNOTSUPP;
1133 
1134 	WARN_ON(!lockdep_rtnl_is_held());
1135 
1136 	if (pl->phydev)
1137 		ret = phy_ethtool_set_eee(pl->phydev, eee);
1138 
1139 	return ret;
1140 }
1141 EXPORT_SYMBOL_GPL(phylink_ethtool_set_eee);
1142 
1143 /* This emulates MII registers for a fixed-mode phy operating as per the
1144  * passed in state. "aneg" defines if we report negotiation is possible.
1145  *
1146  * FIXME: should deal with negotiation state too.
1147  */
phylink_mii_emul_read(struct net_device * ndev,unsigned int reg,struct phylink_link_state * state,bool aneg)1148 static int phylink_mii_emul_read(struct net_device *ndev, unsigned int reg,
1149 				 struct phylink_link_state *state, bool aneg)
1150 {
1151 	struct fixed_phy_status fs;
1152 	int val;
1153 
1154 	fs.link = state->link;
1155 	fs.speed = state->speed;
1156 	fs.duplex = state->duplex;
1157 	fs.pause = state->pause & MLO_PAUSE_SYM;
1158 	fs.asym_pause = state->pause & MLO_PAUSE_ASYM;
1159 
1160 	val = swphy_read_reg(reg, &fs);
1161 	if (reg == MII_BMSR) {
1162 		if (!state->an_complete)
1163 			val &= ~BMSR_ANEGCOMPLETE;
1164 		if (!aneg)
1165 			val &= ~BMSR_ANEGCAPABLE;
1166 	}
1167 	return val;
1168 }
1169 
phylink_phy_read(struct phylink * pl,unsigned int phy_id,unsigned int reg)1170 static int phylink_phy_read(struct phylink *pl, unsigned int phy_id,
1171 			    unsigned int reg)
1172 {
1173 	struct phy_device *phydev = pl->phydev;
1174 	int prtad, devad;
1175 
1176 	if (mdio_phy_id_is_c45(phy_id)) {
1177 		prtad = mdio_phy_id_prtad(phy_id);
1178 		devad = mdio_phy_id_devad(phy_id);
1179 		devad = MII_ADDR_C45 | devad << 16 | reg;
1180 	} else if (phydev->is_c45) {
1181 		switch (reg) {
1182 		case MII_BMCR:
1183 		case MII_BMSR:
1184 		case MII_PHYSID1:
1185 		case MII_PHYSID2:
1186 			devad = __ffs(phydev->c45_ids.devices_in_package);
1187 			break;
1188 		case MII_ADVERTISE:
1189 		case MII_LPA:
1190 			if (!(phydev->c45_ids.devices_in_package & MDIO_DEVS_AN))
1191 				return -EINVAL;
1192 			devad = MDIO_MMD_AN;
1193 			if (reg == MII_ADVERTISE)
1194 				reg = MDIO_AN_ADVERTISE;
1195 			else
1196 				reg = MDIO_AN_LPA;
1197 			break;
1198 		default:
1199 			return -EINVAL;
1200 		}
1201 		prtad = phy_id;
1202 		devad = MII_ADDR_C45 | devad << 16 | reg;
1203 	} else {
1204 		prtad = phy_id;
1205 		devad = reg;
1206 	}
1207 	return mdiobus_read(pl->phydev->mdio.bus, prtad, devad);
1208 }
1209 
phylink_phy_write(struct phylink * pl,unsigned int phy_id,unsigned int reg,unsigned int val)1210 static int phylink_phy_write(struct phylink *pl, unsigned int phy_id,
1211 			     unsigned int reg, unsigned int val)
1212 {
1213 	struct phy_device *phydev = pl->phydev;
1214 	int prtad, devad;
1215 
1216 	if (mdio_phy_id_is_c45(phy_id)) {
1217 		prtad = mdio_phy_id_prtad(phy_id);
1218 		devad = mdio_phy_id_devad(phy_id);
1219 		devad = MII_ADDR_C45 | devad << 16 | reg;
1220 	} else if (phydev->is_c45) {
1221 		switch (reg) {
1222 		case MII_BMCR:
1223 		case MII_BMSR:
1224 		case MII_PHYSID1:
1225 		case MII_PHYSID2:
1226 			devad = __ffs(phydev->c45_ids.devices_in_package);
1227 			break;
1228 		case MII_ADVERTISE:
1229 		case MII_LPA:
1230 			if (!(phydev->c45_ids.devices_in_package & MDIO_DEVS_AN))
1231 				return -EINVAL;
1232 			devad = MDIO_MMD_AN;
1233 			if (reg == MII_ADVERTISE)
1234 				reg = MDIO_AN_ADVERTISE;
1235 			else
1236 				reg = MDIO_AN_LPA;
1237 			break;
1238 		default:
1239 			return -EINVAL;
1240 		}
1241 		prtad = phy_id;
1242 		devad = MII_ADDR_C45 | devad << 16 | reg;
1243 	} else {
1244 		prtad = phy_id;
1245 		devad = reg;
1246 	}
1247 
1248 	return mdiobus_write(phydev->mdio.bus, prtad, devad, val);
1249 }
1250 
phylink_mii_read(struct phylink * pl,unsigned int phy_id,unsigned int reg)1251 static int phylink_mii_read(struct phylink *pl, unsigned int phy_id,
1252 			    unsigned int reg)
1253 {
1254 	struct phylink_link_state state;
1255 	int val = 0xffff;
1256 
1257 	switch (pl->link_an_mode) {
1258 	case MLO_AN_FIXED:
1259 		if (phy_id == 0) {
1260 			phylink_get_fixed_state(pl, &state);
1261 			val = phylink_mii_emul_read(pl->netdev, reg, &state,
1262 						    true);
1263 		}
1264 		break;
1265 
1266 	case MLO_AN_PHY:
1267 		return -EOPNOTSUPP;
1268 
1269 	case MLO_AN_SGMII:
1270 		/* No phy, fall through to 8023z method */
1271 	case MLO_AN_8023Z:
1272 		if (phy_id == 0) {
1273 			val = phylink_get_mac_state(pl, &state);
1274 			if (val < 0)
1275 				return val;
1276 
1277 			val = phylink_mii_emul_read(pl->netdev, reg, &state,
1278 						    true);
1279 		}
1280 		break;
1281 	}
1282 
1283 	return val & 0xffff;
1284 }
1285 
phylink_mii_write(struct phylink * pl,unsigned int phy_id,unsigned int reg,unsigned int val)1286 static int phylink_mii_write(struct phylink *pl, unsigned int phy_id,
1287 			     unsigned int reg, unsigned int val)
1288 {
1289 	switch (pl->link_an_mode) {
1290 	case MLO_AN_FIXED:
1291 		break;
1292 
1293 	case MLO_AN_PHY:
1294 		return -EOPNOTSUPP;
1295 
1296 	case MLO_AN_SGMII:
1297 		/* No phy, fall through to 8023z method */
1298 	case MLO_AN_8023Z:
1299 		break;
1300 	}
1301 
1302 	return 0;
1303 }
1304 
phylink_mii_ioctl(struct phylink * pl,struct ifreq * ifr,int cmd)1305 int phylink_mii_ioctl(struct phylink *pl, struct ifreq *ifr, int cmd)
1306 {
1307 	struct mii_ioctl_data *mii = if_mii(ifr);
1308 	int  ret;
1309 
1310 	WARN_ON(!lockdep_rtnl_is_held());
1311 
1312 	if (pl->phydev) {
1313 		/* PHYs only exist for MLO_AN_PHY and MLO_AN_SGMII */
1314 		switch (cmd) {
1315 		case SIOCGMIIPHY:
1316 			mii->phy_id = pl->phydev->mdio.addr;
1317 
1318 		case SIOCGMIIREG:
1319 			ret = phylink_phy_read(pl, mii->phy_id, mii->reg_num);
1320 			if (ret >= 0) {
1321 				mii->val_out = ret;
1322 				ret = 0;
1323 			}
1324 			break;
1325 
1326 		case SIOCSMIIREG:
1327 			ret = phylink_phy_write(pl, mii->phy_id, mii->reg_num,
1328 						mii->val_in);
1329 			break;
1330 
1331 		default:
1332 			ret = phy_mii_ioctl(pl->phydev, ifr, cmd);
1333 			break;
1334 		}
1335 	} else {
1336 		switch (cmd) {
1337 		case SIOCGMIIPHY:
1338 			mii->phy_id = 0;
1339 
1340 		case SIOCGMIIREG:
1341 			ret = phylink_mii_read(pl, mii->phy_id, mii->reg_num);
1342 			if (ret >= 0) {
1343 				mii->val_out = ret;
1344 				ret = 0;
1345 			}
1346 			break;
1347 
1348 		case SIOCSMIIREG:
1349 			ret = phylink_mii_write(pl, mii->phy_id, mii->reg_num,
1350 						mii->val_in);
1351 			break;
1352 
1353 		default:
1354 			ret = -EOPNOTSUPP;
1355 			break;
1356 		}
1357 	}
1358 
1359 	return ret;
1360 }
1361 EXPORT_SYMBOL_GPL(phylink_mii_ioctl);
1362 
1363 
1364 
phylink_sfp_module_insert(void * upstream,const struct sfp_eeprom_id * id)1365 static int phylink_sfp_module_insert(void *upstream,
1366 				     const struct sfp_eeprom_id *id)
1367 {
1368 	struct phylink *pl = upstream;
1369 	__ETHTOOL_DECLARE_LINK_MODE_MASK(support) = { 0, };
1370 	struct phylink_link_state config;
1371 	phy_interface_t iface;
1372 	int mode, ret = 0;
1373 	bool changed;
1374 	u8 port;
1375 
1376 	sfp_parse_support(pl->sfp_bus, id, support);
1377 	port = sfp_parse_port(pl->sfp_bus, id, support);
1378 	iface = sfp_parse_interface(pl->sfp_bus, id);
1379 
1380 	WARN_ON(!lockdep_rtnl_is_held());
1381 
1382 	switch (iface) {
1383 	case PHY_INTERFACE_MODE_SGMII:
1384 		mode = MLO_AN_SGMII;
1385 		break;
1386 	case PHY_INTERFACE_MODE_1000BASEX:
1387 		mode = MLO_AN_8023Z;
1388 		break;
1389 	default:
1390 		return -EINVAL;
1391 	}
1392 
1393 	memset(&config, 0, sizeof(config));
1394 	linkmode_copy(config.advertising, support);
1395 	config.interface = iface;
1396 	config.speed = SPEED_UNKNOWN;
1397 	config.duplex = DUPLEX_UNKNOWN;
1398 	config.pause = MLO_PAUSE_AN;
1399 	config.an_enabled = pl->link_config.an_enabled;
1400 
1401 	/* Ignore errors if we're expecting a PHY to attach later */
1402 	ret = phylink_validate(pl, support, &config);
1403 	if (ret) {
1404 		netdev_err(pl->netdev, "validation of %s/%s with support %*pb failed: %d\n",
1405 			   phylink_an_mode_str(mode), phy_modes(config.interface),
1406 			   __ETHTOOL_LINK_MODE_MASK_NBITS, support, ret);
1407 		return ret;
1408 	}
1409 
1410 	netdev_dbg(pl->netdev, "requesting link mode %s/%s with support %*pb\n",
1411 		   phylink_an_mode_str(mode), phy_modes(config.interface),
1412 		   __ETHTOOL_LINK_MODE_MASK_NBITS, support);
1413 
1414 	if (mode == MLO_AN_8023Z && pl->phydev)
1415 		return -EINVAL;
1416 
1417 	changed = !bitmap_equal(pl->supported, support,
1418 				__ETHTOOL_LINK_MODE_MASK_NBITS);
1419 	if (changed) {
1420 		linkmode_copy(pl->supported, support);
1421 		linkmode_copy(pl->link_config.advertising, config.advertising);
1422 	}
1423 
1424 	if (pl->link_an_mode != mode ||
1425 	    pl->link_config.interface != config.interface) {
1426 		pl->link_config.interface = config.interface;
1427 		pl->link_an_mode = mode;
1428 
1429 		changed = true;
1430 
1431 		netdev_info(pl->netdev, "switched to %s/%s link mode\n",
1432 			    phylink_an_mode_str(mode),
1433 			    phy_modes(config.interface));
1434 	}
1435 
1436 	pl->link_port = port;
1437 
1438 	if (changed && !test_bit(PHYLINK_DISABLE_STOPPED,
1439 				 &pl->phylink_disable_state))
1440 		phylink_mac_config(pl, &pl->link_config);
1441 
1442 	return ret;
1443 }
1444 
phylink_sfp_link_down(void * upstream)1445 static void phylink_sfp_link_down(void *upstream)
1446 {
1447 	struct phylink *pl = upstream;
1448 
1449 	WARN_ON(!lockdep_rtnl_is_held());
1450 
1451 	phylink_run_resolve_and_disable(pl, PHYLINK_DISABLE_LINK);
1452 }
1453 
phylink_sfp_link_up(void * upstream)1454 static void phylink_sfp_link_up(void *upstream)
1455 {
1456 	struct phylink *pl = upstream;
1457 
1458 	WARN_ON(!lockdep_rtnl_is_held());
1459 
1460 	clear_bit(PHYLINK_DISABLE_LINK, &pl->phylink_disable_state);
1461 	phylink_run_resolve(pl);
1462 }
1463 
phylink_sfp_connect_phy(void * upstream,struct phy_device * phy)1464 static int phylink_sfp_connect_phy(void *upstream, struct phy_device *phy)
1465 {
1466 	return phylink_connect_phy(upstream, phy);
1467 }
1468 
phylink_sfp_disconnect_phy(void * upstream)1469 static void phylink_sfp_disconnect_phy(void *upstream)
1470 {
1471 	phylink_disconnect_phy(upstream);
1472 }
1473 
1474 static const struct sfp_upstream_ops sfp_phylink_ops = {
1475 	.module_insert = phylink_sfp_module_insert,
1476 	.link_up = phylink_sfp_link_up,
1477 	.link_down = phylink_sfp_link_down,
1478 	.connect_phy = phylink_sfp_connect_phy,
1479 	.disconnect_phy = phylink_sfp_disconnect_phy,
1480 };
1481 
1482 MODULE_LICENSE("GPL");
1483